mirror of
https://github.com/hansjone/netxops.git
synced 2026-10-16 09:10:45 +08:00
Sync Netx Ops declarative preset into web profile on DSH 0.2.
0.2 web no longer lists ~/.dsh/.agent-presets; without a cordis.patch.yml insert the preset never appears in Settings. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6bf5268dfb
commit
a313dd0eae
4 changed files with 36 additions and 145 deletions
|
|
@ -9,7 +9,7 @@ One install wires **all of**:
|
||||||
| Host tools | Capability groups **ops / topology** (one group ↔ one skill). Default ops in Ops preset; topology and all public off. Other agents may mount `dsh-netxops/tools-ops|topology` |
|
| Host tools | Capability groups **ops / topology** (one group ↔ one skill). Default ops in Ops preset; topology and all public off. Other agents may mount `dsh-netxops/tools-ops|topology` |
|
||||||
| Companion plugins | **dsh-im-ops** + **dsh-ops-cron** — add as **direct** profile deps in the same command (DSH/pnpm blocks `github:` as transitive deps) |
|
| Companion plugins | **dsh-im-ops** + **dsh-ops-cron** — add as **direct** profile deps in the same command (DSH/pnpm blocks `github:` as transitive deps) |
|
||||||
| Plugins card | Settings → Plugins → **Netx Ops** (URL / API lang / thinking+reply language / token / capability groups) |
|
| Plugins card | Settings → Plugins → **Netx Ops** (URL / API lang / thinking+reply language / token / capability groups) |
|
||||||
| Agent preset + skills | Settings → Agent presets → **Netx Ops**. Host composes from **this host's** shipped **standard** + Netx Ops overlays (no preset inheritance): Desktop 0.2 prefers `@deepseek-ai/dsh-web-app/presets/standard.patch.yml` (`workflow-ptc`); web/CLI use `dsh-agent-presets` directory standard. Web installs land in `~/.dsh/.agent-presets/netxops`; Desktop also syncs a declarative `@deepseek-ai/dsh-agent-preset` row into the profile patch. Restart Desktop once after upgrade. Playbooks follow the same group toggles |
|
| Agent preset + skills | Settings → Agent presets → **Netx Ops**. Host composes from **this host's** shipped **standard** + Netx Ops overlays (no preset inheritance). DSH ≥0.2 (Desktop **and** web) uses declarative `@deepseek-ai/dsh-agent-preset` rows synced into that profile's `cordis.patch.yml` (from `@deepseek-ai/dsh-web-app/presets/standard.patch.yml`). A directory under `~/.dsh/.agent-presets/netxops` is still written for older hosts, but 0.2 no longer lists it. Restart Desktop / `dsh web` once after upgrade. Playbooks follow the same group toggles |
|
||||||
|
|
||||||
You do **not** run `link-preset.ps1` for normal use. That script is only a manual fallback.
|
You do **not** run `link-preset.ps1` for normal use. That script is only a manual fallback.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -437,7 +437,7 @@ function installDirectoryPreset(artifacts, logger) {
|
||||||
logger.info("netxops: directory preset composed from %s → %s", artifacts.standardSource, dest);
|
logger.info("netxops: directory preset composed from %s → %s", artifacts.standardSource, dest);
|
||||||
}
|
}
|
||||||
function syncDeclarativeIntoProfilePatch(profileName, declarativePatch, logger) {
|
function syncDeclarativeIntoProfilePatch(profileName, declarativePatch, logger) {
|
||||||
if (profileName !== "desktop")
|
if (profileName !== "desktop" && profileName !== "web")
|
||||||
return;
|
return;
|
||||||
const profileDir = join(resolveDshHome(), "profiles", profileName);
|
const profileDir = join(resolveDshHome(), "profiles", profileName);
|
||||||
const patchPath = join(profileDir, "cordis.patch.yml");
|
const patchPath = join(profileDir, "cordis.patch.yml");
|
||||||
|
|
@ -458,7 +458,11 @@ ${declarativePatch.trimEnd()}
|
||||||
${DESKTOP_PATCH_END}
|
${DESKTOP_PATCH_END}
|
||||||
`;
|
`;
|
||||||
writeFileSync(patchPath, `${patch}${managed}`, "utf8");
|
writeFileSync(patchPath, `${patch}${managed}`, "utf8");
|
||||||
logger.info("netxops: declarative preset synced into profiles/%s/cordis.patch.yml (restart Desktop to load)", profileName);
|
logger.info(
|
||||||
|
"netxops: declarative preset synced into profiles/%s/cordis.patch.yml (restart %s to load)",
|
||||||
|
profileName,
|
||||||
|
profileName === "desktop" ? "Desktop" : "dsh web"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
function stripManagedPresetBlocks(patch) {
|
function stripManagedPresetBlocks(patch) {
|
||||||
let out = patch;
|
let out = patch;
|
||||||
|
|
|
||||||
|
|
@ -11,29 +11,6 @@
|
||||||
name: "Netx Ops"
|
name: "Netx Ops"
|
||||||
description: "运维专家(含标准模式全套工作区能力 + netx 工具)。"
|
description: "运维专家(含标准模式全套工作区能力 + netx 工具)。"
|
||||||
plugins:
|
plugins:
|
||||||
# The `standard` agent preset: the full coding agent, mounted once per process.
|
|
||||||
#
|
|
||||||
# This file is an AGENT-PLANE composition. The roster mounts it ONCE under a
|
|
||||||
# standing scope; every session naming it joins by scope parentage, so the
|
|
||||||
# tools and prompt sections registered here cover each joined agent while a
|
|
||||||
# session's own state stays keyed per Session/Agent inside the plugins. The
|
|
||||||
# host composition (`base.cordis.yml` + `web.cordis.yml`) keeps everything a
|
|
||||||
# preset must not own: the registries themselves, the sandbox and approval
|
|
||||||
# stack, persistence, and the model route.
|
|
||||||
#
|
|
||||||
# A service row here MUST sit inside a group carrying an `isolate` realm.
|
|
||||||
# Without one it publishes into the root realm, where it is process-global —
|
|
||||||
# another preset publishing the same name collides, and a host reader would
|
|
||||||
# resolve one preset's instance for every session; `dsh-agent-presets` rejects
|
|
||||||
# that at mount. `true` means an entry-local realm: this standing mount's own
|
|
||||||
# private instance, apart from every other preset's. (A shared label does NOT
|
|
||||||
# pool instances — `provide()` throws on the second registration under the
|
|
||||||
# same realm symbol; labels join REALMS, and are not what this file needs.)
|
|
||||||
|
|
||||||
# ── identity ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# The preset's own persona, shadowing the deployment default for this agent.
|
|
||||||
# `{{model}}` and `{{cwd}}` resolve from the agent's own route and workspace.
|
|
||||||
- id: persona
|
- id: persona
|
||||||
name: '@deepseek-ai/dsh-persona'
|
name: '@deepseek-ai/dsh-persona'
|
||||||
config:
|
config:
|
||||||
|
|
@ -123,80 +100,32 @@
|
||||||
name: '@deepseek-ai/dsh-agent-instructions'
|
name: '@deepseek-ai/dsh-agent-instructions'
|
||||||
config:
|
config:
|
||||||
maxBytes: 65536
|
maxBytes: 65536
|
||||||
|
|
||||||
# ── shell ───────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# `shell-env` stays in the HOST composition: `apps/cli/src/web.ts` injects it to
|
|
||||||
# publish `DSH_WEB_URL`/`DSH_WEB_MODE`, and a host row that injects a service is
|
|
||||||
# the criterion for host-plane ownership — injection resolves before any session
|
|
||||||
# exists, so there is no agent to key by. Behind a preset realm those variables
|
|
||||||
# never reached the model's shell at all. Both shell tools consume the host
|
|
||||||
# registry from here; their executors (`bash-sandbox`/`pwsh-sandbox`) are
|
|
||||||
# host-plane too.
|
|
||||||
- id: tool-bash
|
- id: tool-bash
|
||||||
name: '@deepseek-ai/dsh-tool-bash'
|
name: '@deepseek-ai/dsh-tool-bash'
|
||||||
disabled: !!js process.platform === 'win32'
|
disabled: !!js process.platform === 'win32'
|
||||||
|
|
||||||
- id: tool-pwsh
|
- id: tool-pwsh
|
||||||
name: '@deepseek-ai/dsh-tool-pwsh'
|
name: '@deepseek-ai/dsh-tool-pwsh'
|
||||||
disabled: !!js process.platform !== 'win32'
|
disabled: !!js process.platform !== 'win32'
|
||||||
|
|
||||||
# ── filesystem ──────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Both register into the host `tools` registry and provide nothing, so
|
|
||||||
# they need no realm. The `fs` service and its policy stay in the host.
|
|
||||||
- id: tool-fs
|
- id: tool-fs
|
||||||
name: '@deepseek-ai/dsh-tool-fs'
|
name: '@deepseek-ai/dsh-tool-fs'
|
||||||
|
|
||||||
- id: tool-fs-search
|
- id: tool-fs-search
|
||||||
name: '@deepseek-ai/dsh-tool-fs-search'
|
name: '@deepseek-ai/dsh-tool-fs-search'
|
||||||
config:
|
config:
|
||||||
sampleOverCapGlobResults: false
|
sampleOverCapGlobResults: false
|
||||||
|
|
||||||
# ── background jobs ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Only the model-facing controls. The task REGISTRY stays on the host plane:
|
|
||||||
# its producers sit outside any realm this file could put it in — `tool-bash`
|
|
||||||
# above resolves it with `ctx.get`, and an entry-local realm here is invisible
|
|
||||||
# to every sibling row, so `run_in_background` would answer "background jobs
|
|
||||||
# unavailable" while these controls sat in the catalog. The registry is keyed by
|
|
||||||
# owning agent anyway, so one host instance serves every session. What a preset
|
|
||||||
# chooses is whether its agent can collect and stop background work at all.
|
|
||||||
- id: tool-jobs
|
- id: tool-jobs
|
||||||
name: '@deepseek-ai/dsh-tool-jobs'
|
name: '@deepseek-ai/dsh-tool-jobs'
|
||||||
|
|
||||||
# ── skills ──────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# The skill REGISTRY lives in the host composition and is layered per scope:
|
|
||||||
# these rows register into THIS preset's layer of it, so they need no realm.
|
|
||||||
# `skill-filesystem` contributes local-root discovery for agents on this preset, and
|
|
||||||
# `tool-skill` gives them the catalog and loader; the merged catalog also
|
|
||||||
# carries whatever the deployment registered globally (repository plugins).
|
|
||||||
- id: skill-filesystem
|
- id: skill-filesystem
|
||||||
name: '@deepseek-ai/dsh-skill-filesystem'
|
name: '@deepseek-ai/dsh-skill-filesystem'
|
||||||
|
|
||||||
- id: tool-skill
|
- id: tool-skill
|
||||||
name: '@deepseek-ai/dsh-tool-skill'
|
name: '@deepseek-ai/dsh-tool-skill'
|
||||||
|
|
||||||
# ── goals ───────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# The goal service and session driver stay on the host plane, where the Gateway
|
|
||||||
# can resolve them. The human command and model-facing tool register into this
|
|
||||||
# preset's scoped layers.
|
|
||||||
|
|
||||||
- id: netxops-tools
|
- id: netxops-tools
|
||||||
name: dsh-netxops/tools
|
name: dsh-netxops/tools
|
||||||
|
|
||||||
- id: command-goal
|
- id: command-goal
|
||||||
name: '@deepseek-ai/dsh-command-goal'
|
name: '@deepseek-ai/dsh-command-goal'
|
||||||
|
|
||||||
- id: tool-goal
|
- id: tool-goal
|
||||||
name: '@deepseek-ai/dsh-tool-goal'
|
name: '@deepseek-ai/dsh-tool-goal'
|
||||||
|
|
||||||
# ── plan mode ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# Plan state is per-agent by nature, so an entry-local realm is not a
|
|
||||||
# workaround here — it is the correct lifetime.
|
|
||||||
- id: planning
|
- id: planning
|
||||||
name: cordis:group
|
name: cordis:group
|
||||||
group: true
|
group: true
|
||||||
|
|
@ -218,18 +147,6 @@
|
||||||
Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
|
Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
|
||||||
|
|
||||||
When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
|
When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
|
||||||
|
|
||||||
# ── compaction ──────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# `compaction-basic` reads `toolResultPrune` through `ctx.get`, so the pruner must
|
|
||||||
# share this realm rather than sit outside it.
|
|
||||||
#
|
|
||||||
# `tokenMeter` is deliberately NOT in this realm: the meter stays on the HOST
|
|
||||||
# plane, and the rows here resolve that one instance. It takes no configuration,
|
|
||||||
# keys every fold by Session, and owns the context-meter projection units the
|
|
||||||
# browser reads for every session — behind a realm those units would come and go
|
|
||||||
# with whichever presets happen to be mounted. What a preset chooses is whether
|
|
||||||
# its agent compacts at all, which is `compaction-basic` below.
|
|
||||||
- id: compaction
|
- id: compaction
|
||||||
name: cordis:group
|
name: cordis:group
|
||||||
group: true
|
group: true
|
||||||
|
|
@ -239,28 +156,14 @@
|
||||||
config:
|
config:
|
||||||
- id: compaction-basic
|
- id: compaction-basic
|
||||||
name: '@deepseek-ai/dsh-compaction-basic'
|
name: '@deepseek-ai/dsh-compaction-basic'
|
||||||
|
|
||||||
- id: command-compact
|
- id: command-compact
|
||||||
name: '@deepseek-ai/dsh-command-compact'
|
name: '@deepseek-ai/dsh-command-compact'
|
||||||
|
|
||||||
- id: tool-result-pruner
|
- id: tool-result-pruner
|
||||||
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
||||||
config:
|
config:
|
||||||
thresholdChars: 8192
|
thresholdChars: 8192
|
||||||
headChars: 4096
|
headChars: 4096
|
||||||
tailChars: 1024
|
tailChars: 1024
|
||||||
|
|
||||||
# ── delegation and workflows ────────────────────────────────────────────────
|
|
||||||
|
|
||||||
# The `subagents` registry and its spawn/fork backends live in the HOST
|
|
||||||
# composition: the registry is a process singleton whose cross-session queries
|
|
||||||
# the api-proxy serves to the browser, and a provider name may only be
|
|
||||||
# registered once. This preset contributes the delegation TOOLS, which resolve
|
|
||||||
# that host registry.
|
|
||||||
#
|
|
||||||
# `workflows` is different — nothing outside an agent reads it — so every row
|
|
||||||
# that reaches it shares one entry-local realm here, and a consumer left
|
|
||||||
# outside would resolve a host registry this preset does not populate.
|
|
||||||
- id: delegation
|
- id: delegation
|
||||||
name: cordis:group
|
name: cordis:group
|
||||||
group: true
|
group: true
|
||||||
|
|
@ -269,10 +172,8 @@
|
||||||
config:
|
config:
|
||||||
- id: tool-subagent-control
|
- id: tool-subagent-control
|
||||||
name: '@deepseek-ai/dsh-tool-subagent-control'
|
name: '@deepseek-ai/dsh-tool-subagent-control'
|
||||||
|
|
||||||
- id: tool-subagent-list-agents
|
- id: tool-subagent-list-agents
|
||||||
name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
|
name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
|
||||||
|
|
||||||
- id: tool-subagent
|
- id: tool-subagent
|
||||||
name: '@deepseek-ai/dsh-tool-subagent'
|
name: '@deepseek-ai/dsh-tool-subagent'
|
||||||
config:
|
config:
|
||||||
|
|
@ -280,22 +181,12 @@
|
||||||
toolName: subagent
|
toolName: subagent
|
||||||
modelSelectionSettings: true
|
modelSelectionSettings: true
|
||||||
backgroundMode: continuable
|
backgroundMode: continuable
|
||||||
|
|
||||||
# Fork omits model selection so provider/model stay equal to the parent and
|
|
||||||
# the inherited history remains eligible for KV Cache reuse. This preset
|
|
||||||
# keeps fork continuable; parent and child inherit the same messaging tool,
|
|
||||||
# while the parent id and return guidance follow the inherited history.
|
|
||||||
- id: tool-subagent-fork
|
- id: tool-subagent-fork
|
||||||
name: '@deepseek-ai/dsh-tool-subagent'
|
name: '@deepseek-ai/dsh-tool-subagent'
|
||||||
config:
|
config:
|
||||||
provider: fork
|
provider: fork
|
||||||
toolName: subagent_fork
|
toolName: subagent_fork
|
||||||
backgroundMode: continuable
|
backgroundMode: continuable
|
||||||
|
|
||||||
# Production dsh does not install these optional providers. Install the
|
|
||||||
# matching Bundle in this Profile and restart the Host, then copy this
|
|
||||||
# preset and remove `disabled` from the matching tool row. Host availability
|
|
||||||
# alone grants no tool.
|
|
||||||
- id: tool-subagent-codex
|
- id: tool-subagent-codex
|
||||||
name: '@deepseek-ai/dsh-tool-subagent'
|
name: '@deepseek-ai/dsh-tool-subagent'
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|
@ -304,7 +195,6 @@
|
||||||
toolName: subagent_codex
|
toolName: subagent_codex
|
||||||
backgroundMode: one-shot
|
backgroundMode: one-shot
|
||||||
maxDepth: provider-managed
|
maxDepth: provider-managed
|
||||||
|
|
||||||
- id: tool-subagent-claude-code
|
- id: tool-subagent-claude-code
|
||||||
name: '@deepseek-ai/dsh-tool-subagent'
|
name: '@deepseek-ai/dsh-tool-subagent'
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|
@ -313,39 +203,32 @@
|
||||||
toolName: subagent_claude_code
|
toolName: subagent_claude_code
|
||||||
backgroundMode: one-shot
|
backgroundMode: one-shot
|
||||||
maxDepth: provider-managed
|
maxDepth: provider-managed
|
||||||
|
|
||||||
- id: workflow-ptc
|
- id: workflow-ptc
|
||||||
name: '@deepseek-ai/dsh-workflow-ptc'
|
name: '@deepseek-ai/dsh-workflow-ptc'
|
||||||
config:
|
config:
|
||||||
provider: spawn
|
provider: spawn
|
||||||
|
|
||||||
- id: tool-workflow
|
- id: tool-workflow
|
||||||
name: '@deepseek-ai/dsh-tool-workflow'
|
name: '@deepseek-ai/dsh-tool-workflow'
|
||||||
|
|
||||||
- id: tool-ralph
|
- id: tool-ralph
|
||||||
name: '@deepseek-ai/dsh-tool-ralph'
|
name: '@deepseek-ai/dsh-tool-ralph'
|
||||||
|
disabled: true
|
||||||
config:
|
config:
|
||||||
subagentProvider: spawn
|
subagentProvider: spawn
|
||||||
maxRounds: 64
|
maxRounds: 64
|
||||||
|
|
||||||
# ── remaining model-facing rows ─────────────────────────────────────────────
|
|
||||||
|
|
||||||
- id: tool-ask-user
|
- id: tool-ask-user
|
||||||
name: '@deepseek-ai/dsh-tool-ask-user'
|
name: '@deepseek-ai/dsh-tool-ask-user'
|
||||||
|
|
||||||
- id: tool-todo
|
- id: tool-todo
|
||||||
name: '@deepseek-ai/dsh-tool-todo'
|
name: '@deepseek-ai/dsh-tool-todo'
|
||||||
config:
|
config:
|
||||||
allowParallelInProgress: true
|
allowParallelInProgress: true
|
||||||
|
|
||||||
# The `web` service and its search provider stay in the host composition; only
|
|
||||||
# the model-facing tool is per-session.
|
|
||||||
- id: tool-web
|
- id: tool-web
|
||||||
name: '@deepseek-ai/dsh-tool-web'
|
name: '@deepseek-ai/dsh-tool-web'
|
||||||
config:
|
config:
|
||||||
fetch: true
|
fetch: true
|
||||||
searchTimeoutMs: 60000
|
searchTimeoutMs: 60000
|
||||||
|
|
||||||
- id: present
|
- id: present
|
||||||
name: '@deepseek-ai/dsh-tool-present'
|
name: '@deepseek-ai/dsh-tool-present'
|
||||||
|
- id: tool-plugin-manager
|
||||||
|
name: '@deepseek-ai/dsh-plugin-manager/tools'
|
||||||
|
disabled: true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
/**
|
/**
|
||||||
* Install Netx Ops agent preset for both DSH host styles:
|
* Install Netx Ops agent preset for both DSH host styles:
|
||||||
*
|
*
|
||||||
* - Web / source CLI (`@deepseek-ai/dsh-agent-presets`): directory under
|
* - DSH ≥0.2 (`@deepseek-ai/dsh-agent-preset` + registry): declarative insert
|
||||||
* `$DSH_HOME/.agent-presets/netxops`.
|
* row synced into **desktop and web** profile `cordis.patch.yml` on apply.
|
||||||
* - Desktop 0.2 (`@deepseek-ai/dsh-agent-preset` + registry): declarative
|
* Directory `$DSH_HOME/.agent-presets/netxops` is still written for older
|
||||||
* insert row synced into the desktop profile `cordis.patch.yml` on apply.
|
* hosts that scan `@deepseek-ai/dsh-agent-presets`, but 0.2 web/desktop no
|
||||||
|
* longer load that roster — without the patch row, Settings → Agent presets
|
||||||
|
* shows no Netx Ops entry.
|
||||||
*
|
*
|
||||||
* Both are composed from the **host's** shipped `standard` + Netx Ops overlays
|
* Composed from the **host's** shipped `standard` + Netx Ops overlays (DSH has
|
||||||
* (DSH has no preset `extends`). Desktop 0.2 ships standard as
|
* no preset `extends`). Prefer `@deepseek-ai/dsh-web-app/presets/standard.patch.yml`
|
||||||
* `@deepseek-ai/dsh-web-app/presets/standard.patch.yml` (`workflow-ptc`); the
|
* (`workflow-ptc`) when present; refuse to write a composition whose package
|
||||||
* CLI heal tree under `$DSH_HOME/profiles/node_modules` may still carry an
|
|
||||||
* older `dsh-agent-presets` standard (`workflow-worker-thread`). Prefer the
|
|
||||||
* Desktop patch when present, and refuse to write a composition whose package
|
|
||||||
* names cannot resolve from the host anchors.
|
* names cannot resolve from the host anchors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -531,16 +530,17 @@ function installDirectoryPreset(artifacts: NetxopsPresetArtifacts, logger: Conte
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync declarative preset into Desktop's cordis.patch.yml.
|
* Sync declarative preset into a profile's cordis.patch.yml.
|
||||||
* Desktop 0.2 profile roots are empty `[]` (bundles + patch compose the tree),
|
* DSH ≥0.2 profile roots are empty `[]` (bundles + patch compose the tree).
|
||||||
* so we key off the profile name — never web's directory roster.
|
* Both `desktop` and `web` need the `@deepseek-ai/dsh-agent-preset` insert;
|
||||||
|
* directory `.agent-presets` alone is invisible on 0.2.
|
||||||
*/
|
*/
|
||||||
function syncDeclarativeIntoProfilePatch(
|
function syncDeclarativeIntoProfilePatch(
|
||||||
profileName: string,
|
profileName: string,
|
||||||
declarativePatch: string,
|
declarativePatch: string,
|
||||||
logger: Context['logger'],
|
logger: Context['logger'],
|
||||||
): void {
|
): void {
|
||||||
if (profileName !== 'desktop') return
|
if (profileName !== 'desktop' && profileName !== 'web') return
|
||||||
const profileDir = join(resolveDshHome(), 'profiles', profileName)
|
const profileDir = join(resolveDshHome(), 'profiles', profileName)
|
||||||
const patchPath = join(profileDir, 'cordis.patch.yml')
|
const patchPath = join(profileDir, 'cordis.patch.yml')
|
||||||
if (!existsSync(profileDir)) return
|
if (!existsSync(profileDir)) return
|
||||||
|
|
@ -555,7 +555,11 @@ function syncDeclarativeIntoProfilePatch(
|
||||||
|
|
||||||
const managed = `${DESKTOP_PATCH_BEGIN}\n${declarativePatch.trimEnd()}\n${DESKTOP_PATCH_END}\n`
|
const managed = `${DESKTOP_PATCH_BEGIN}\n${declarativePatch.trimEnd()}\n${DESKTOP_PATCH_END}\n`
|
||||||
writeFileSync(patchPath, `${patch}${managed}`, 'utf8')
|
writeFileSync(patchPath, `${patch}${managed}`, 'utf8')
|
||||||
logger.info('netxops: declarative preset synced into profiles/%s/cordis.patch.yml (restart Desktop to load)', profileName)
|
logger.info(
|
||||||
|
'netxops: declarative preset synced into profiles/%s/cordis.patch.yml (restart %s to load)',
|
||||||
|
profileName,
|
||||||
|
profileName === 'desktop' ? 'Desktop' : 'dsh web',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove every BEGIN…END managed block using literal index search (markers contain `()`). */
|
/** Remove every BEGIN…END managed block using literal index search (markers contain `()`). */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue