archgraph-argo 0.9.8 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ npm install -g archgraph-argo
|
|
|
26
26
|
argo-deploy
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Done — the ARGO toolchain, skills, and rules are deployed, and the `argo` MCP server is registered automatically in **GitHub Copilot**, **Cursor**,
|
|
29
|
+
Done — the ARGO toolchain, skills, and rules are deployed, and the `argo` MCP server is registered automatically in **GitHub Copilot**, **Cursor**, and **OpenCode**.
|
|
30
30
|
|
|
31
31
|
> Semantic (Graph RAG) queries also need **Neo4j** and a **vector engine** configured in
|
|
32
32
|
> `~/.argo/.env`; everything else works out of the box.
|
|
@@ -18,7 +18,6 @@ const {
|
|
|
18
18
|
getWorkspaceRoot,
|
|
19
19
|
hasStaticWorkspace,
|
|
20
20
|
resolveArgoPath,
|
|
21
|
-
resolveCallWorkspaceRoot,
|
|
22
21
|
setMcpWorkspaceRoots,
|
|
23
22
|
} = require('./argo-paths.js');
|
|
24
23
|
const canonicalSemanticInitStorage = new AsyncLocalStorage();
|
|
@@ -305,25 +304,6 @@ const TOOLS = [
|
|
|
305
304
|
},
|
|
306
305
|
];
|
|
307
306
|
|
|
308
|
-
// Every tool accepts an optional per-call `workspaceRoot` (absolute path,
|
|
309
|
-
// honored only when listed in ARGO_WORKSPACE_ROOTS). The DeepSeek Harness
|
|
310
|
-
// bridge injects the current session's workspace directory here automatically.
|
|
311
|
-
// (tools/list dedupes with systemArchitectureMcp/validatorMcp tools, which
|
|
312
|
-
// carry the same field; this covers the local-only rows like initializeWorkspace.)
|
|
313
|
-
const WORKSPACE_ROOT_PARAM = Object.freeze({
|
|
314
|
-
type: 'string',
|
|
315
|
-
description:
|
|
316
|
-
'Optional absolute workspace root for this call. Honored only when listed in ARGO_WORKSPACE_ROOTS; otherwise the server launch directory is used.',
|
|
317
|
-
});
|
|
318
|
-
for (const tool of TOOLS) {
|
|
319
|
-
const inputSchema = tool && tool.inputSchema;
|
|
320
|
-
if (inputSchema && inputSchema.type === 'object' && inputSchema.properties) {
|
|
321
|
-
if (!Object.prototype.hasOwnProperty.call(inputSchema.properties, 'workspaceRoot')) {
|
|
322
|
-
inputSchema.properties.workspaceRoot = WORKSPACE_ROOT_PARAM;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
307
|
function intentElementContextInputSchema() {
|
|
328
308
|
return {
|
|
329
309
|
type: 'object',
|
|
@@ -394,20 +374,14 @@ function resolveWorkspaceRoot() {
|
|
|
394
374
|
return getWorkspaceRoot();
|
|
395
375
|
}
|
|
396
376
|
|
|
397
|
-
function resolveWorkspaceRoot(args) {
|
|
398
|
-
// Per-call workspaceRoot override (honored only when in the
|
|
399
|
-
// ARGO_WORKSPACE_ROOTS allowlist); defaults to the launch-directory root.
|
|
400
|
-
return resolveCallWorkspaceRoot(args);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
377
|
async function callTool(name, args = {}, progressToken = null, dependencies = undefined) {
|
|
404
|
-
loadRepositoryArgoEnvironment(resolveWorkspaceRoot(
|
|
378
|
+
loadRepositoryArgoEnvironment(resolveWorkspaceRoot());
|
|
405
379
|
if (name === 'initializeWorkspace') {
|
|
406
|
-
const workspace = await initializeWorkspace(resolveWorkspaceRoot(
|
|
380
|
+
const workspace = await initializeWorkspace(resolveWorkspaceRoot());
|
|
407
381
|
const composition = canonicalSemanticInitStorage.getStore()
|
|
408
382
|
|| systemArchitectureMcp.createDefaultCanonicalSemanticInitComposition();
|
|
409
383
|
const semanticLifecycle = await runCanonicalSemanticInit(composition, {
|
|
410
|
-
repositoryRoot: resolveWorkspaceRoot(
|
|
384
|
+
repositoryRoot: resolveWorkspaceRoot(),
|
|
411
385
|
workspace,
|
|
412
386
|
});
|
|
413
387
|
return toolResult({
|
|
@@ -121,48 +121,6 @@ function normalizeRelativePath(value) {
|
|
|
121
121
|
return String(value == null ? '' : value).replace(/\\/g, '/').replace(/^\/+/, '');
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
/**
|
|
125
|
-
* Resolve the workspace root for one tool call.
|
|
126
|
-
*
|
|
127
|
-
* Defaults to the launch-directory root (`getWorkspaceRoot()`). A per-call
|
|
128
|
-
* `workspaceRoot` argument (absolute path) is honored only when it appears in
|
|
129
|
-
* the `ARGO_WORKSPACE_ROOTS` allowlist (semicolon or comma separated absolute
|
|
130
|
-
* paths). Without an allowlist the override is ignored, so existing
|
|
131
|
-
* deployments keep launch-directory resolution with zero behavior change.
|
|
132
|
-
* This powers the DeepSeek Harness bridge, which injects the current session's
|
|
133
|
-
* workspace directory into every call so one dsh instance can follow the
|
|
134
|
-
* workspace the user switched to.
|
|
135
|
-
*
|
|
136
|
-
* @param {object} [args] - tool call arguments (may carry `workspaceRoot`).
|
|
137
|
-
* @returns {string} resolved absolute workspace root.
|
|
138
|
-
* @throws when the requested root is not in the allowlist.
|
|
139
|
-
*/
|
|
140
|
-
function resolveCallWorkspaceRoot(args = {}) {
|
|
141
|
-
const requested =
|
|
142
|
-
typeof args === 'object' && args !== null && typeof args.workspaceRoot === 'string'
|
|
143
|
-
? String(args.workspaceRoot).trim()
|
|
144
|
-
: '';
|
|
145
|
-
if (requested === '') {
|
|
146
|
-
return getWorkspaceRoot();
|
|
147
|
-
}
|
|
148
|
-
const allowlist = (process.env.ARGO_WORKSPACE_ROOTS || '')
|
|
149
|
-
.split(/[;,]/)
|
|
150
|
-
.map((entry) => entry.trim())
|
|
151
|
-
.filter(Boolean)
|
|
152
|
-
.map((entry) => path.resolve(entry));
|
|
153
|
-
if (allowlist.length === 0) {
|
|
154
|
-
return getWorkspaceRoot();
|
|
155
|
-
}
|
|
156
|
-
const resolved = path.resolve(requested);
|
|
157
|
-
const allowed = allowlist.some(
|
|
158
|
-
(root) => resolved === root || resolved.startsWith(root + path.sep),
|
|
159
|
-
);
|
|
160
|
-
if (!allowed) {
|
|
161
|
-
throw new Error(`workspaceRoot not in ARGO_WORKSPACE_ROOTS allowlist: ${requested}`);
|
|
162
|
-
}
|
|
163
|
-
return resolved;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
124
|
module.exports = {
|
|
167
125
|
getArgoRoot,
|
|
168
126
|
getArgoEnvPath,
|
|
@@ -170,7 +128,6 @@ module.exports = {
|
|
|
170
128
|
hasStaticWorkspace,
|
|
171
129
|
normalizeRelativePath,
|
|
172
130
|
resolveArgoPath,
|
|
173
|
-
resolveCallWorkspaceRoot,
|
|
174
131
|
resolveWorkspacePath,
|
|
175
132
|
setMcpWorkspaceRoots,
|
|
176
133
|
};
|
|
@@ -5,7 +5,7 @@ const crypto = require('node:crypto');
|
|
|
5
5
|
|
|
6
6
|
const {
|
|
7
7
|
getArgoRoot,
|
|
8
|
-
|
|
8
|
+
getWorkspaceRoot,
|
|
9
9
|
} = require('./argo-paths.js');
|
|
10
10
|
|
|
11
11
|
const DEFAULT_GRAPH_PATH = 'design/KG/SystemArchitecture.json';
|
|
@@ -381,23 +381,6 @@ const TOOLS = [
|
|
|
381
381
|
},
|
|
382
382
|
];
|
|
383
383
|
|
|
384
|
-
// Every tool accepts an optional per-call `workspaceRoot` (absolute path,
|
|
385
|
-
// honored only when listed in ARGO_WORKSPACE_ROOTS). The DeepSeek Harness
|
|
386
|
-
// bridge injects the current session's workspace directory here automatically.
|
|
387
|
-
const WORKSPACE_ROOT_PARAM = Object.freeze({
|
|
388
|
-
type: 'string',
|
|
389
|
-
description:
|
|
390
|
-
'Optional absolute workspace root for this call. Honored only when listed in ARGO_WORKSPACE_ROOTS; otherwise the server launch directory is used.',
|
|
391
|
-
});
|
|
392
|
-
for (const tool of TOOLS) {
|
|
393
|
-
const inputSchema = tool && tool.inputSchema;
|
|
394
|
-
if (inputSchema && inputSchema.type === 'object' && inputSchema.properties) {
|
|
395
|
-
if (!Object.prototype.hasOwnProperty.call(inputSchema.properties, 'workspaceRoot')) {
|
|
396
|
-
inputSchema.properties.workspaceRoot = WORKSPACE_ROOT_PARAM;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
384
|
function intentElementContextInputSchema() {
|
|
402
385
|
return {
|
|
403
386
|
type: 'object',
|
|
@@ -465,15 +448,13 @@ function mutationInputSchema() {
|
|
|
465
448
|
};
|
|
466
449
|
}
|
|
467
450
|
|
|
468
|
-
function resolveWorkspaceRoot(
|
|
469
|
-
|
|
470
|
-
// ARGO_WORKSPACE_ROOTS allowlist); defaults to the launch-directory root.
|
|
471
|
-
return resolveCallWorkspaceRoot(args);
|
|
451
|
+
function resolveWorkspaceRoot() {
|
|
452
|
+
return getWorkspaceRoot();
|
|
472
453
|
}
|
|
473
454
|
|
|
474
455
|
function initializeWorkspace(request) {
|
|
475
456
|
return require('./argo-mcp-server.js').initializeWorkspace(
|
|
476
|
-
request && request.repositoryRoot ? request.repositoryRoot : resolveWorkspaceRoot(
|
|
457
|
+
request && request.repositoryRoot ? request.repositoryRoot : resolveWorkspaceRoot(),
|
|
477
458
|
);
|
|
478
459
|
}
|
|
479
460
|
|
|
@@ -527,7 +508,7 @@ function readJson(filePath, label) {
|
|
|
527
508
|
}
|
|
528
509
|
|
|
529
510
|
async function loadContext(args = {}) {
|
|
530
|
-
const workspaceRoot = resolveWorkspaceRoot(
|
|
511
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
531
512
|
const graphPath = resolveWorkspacePath(workspaceRoot, args.architecturePath || DEFAULT_GRAPH_PATH);
|
|
532
513
|
const schemaPath = resolveSchemaPath(workspaceRoot);
|
|
533
514
|
const context = {
|
|
@@ -9,7 +9,6 @@ const execFileAsync = promisify(execFile);
|
|
|
9
9
|
const {
|
|
10
10
|
getArgoRoot,
|
|
11
11
|
getWorkspaceRoot,
|
|
12
|
-
resolveCallWorkspaceRoot,
|
|
13
12
|
} = require('./argo-paths.js');
|
|
14
13
|
|
|
15
14
|
const HANDOFF_STAGES = ['intent-to-implementation', 'implementation-to-coding'];
|
|
@@ -86,27 +85,8 @@ const TOOLS = [
|
|
|
86
85
|
},
|
|
87
86
|
];
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// bridge injects the current session's workspace directory here automatically.
|
|
92
|
-
const WORKSPACE_ROOT_PARAM = Object.freeze({
|
|
93
|
-
type: 'string',
|
|
94
|
-
description:
|
|
95
|
-
'Optional absolute workspace root for this call. Honored only when listed in ARGO_WORKSPACE_ROOTS; otherwise the server launch directory is used.',
|
|
96
|
-
});
|
|
97
|
-
for (const tool of TOOLS) {
|
|
98
|
-
const inputSchema = tool && tool.inputSchema;
|
|
99
|
-
if (inputSchema && inputSchema.type === 'object' && inputSchema.properties) {
|
|
100
|
-
if (!Object.prototype.hasOwnProperty.call(inputSchema.properties, 'workspaceRoot')) {
|
|
101
|
-
inputSchema.properties.workspaceRoot = WORKSPACE_ROOT_PARAM;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function resolveWorkspaceRoot(args) {
|
|
107
|
-
// Per-call workspaceRoot override (honored only when in the
|
|
108
|
-
// ARGO_WORKSPACE_ROOTS allowlist); defaults to the launch-directory root.
|
|
109
|
-
return resolveCallWorkspaceRoot(args);
|
|
88
|
+
function resolveWorkspaceRoot() {
|
|
89
|
+
return getWorkspaceRoot();
|
|
110
90
|
}
|
|
111
91
|
|
|
112
92
|
function resolveScriptPath(workspaceRoot, candidates) {
|
|
@@ -251,7 +231,7 @@ function toolResult(payload) {
|
|
|
251
231
|
}
|
|
252
232
|
|
|
253
233
|
async function callTool(name, args, progressToken = null) {
|
|
254
|
-
const workspaceRoot = resolveWorkspaceRoot(
|
|
234
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
255
235
|
|
|
256
236
|
if (name === 'validateSystemArchitecture') {
|
|
257
237
|
return toolResult(await runValidatorScript(workspaceRoot, 'validateSystemArchitecture'));
|
package/install-argo.ps1
CHANGED
|
@@ -16,10 +16,6 @@ param(
|
|
|
16
16
|
[switch]$SkipEnv,
|
|
17
17
|
[switch]$SkipDeps,
|
|
18
18
|
[switch]$SkipMcp,
|
|
19
|
-
[switch]$SkipDsh,
|
|
20
|
-
[string]$DshHome = "$env:USERPROFILE\.dsh",
|
|
21
|
-
[string]$DshCwd = '',
|
|
22
|
-
[string]$DshWorkspaces = '',
|
|
23
19
|
[string]$McpPath
|
|
24
20
|
)
|
|
25
21
|
|
|
@@ -239,505 +235,70 @@ function Add-AgentsRule {
|
|
|
239
235
|
}
|
|
240
236
|
}
|
|
241
237
|
|
|
242
|
-
# ---- DeepSeek Harness (dsh) conversion helpers ----
|
|
243
|
-
# The ArchGraph repository keeps ONE source file per artifact (rule / skill /
|
|
244
|
-
# mcp / plugin / agent). The targets below convert that single source into the
|
|
245
|
-
# DeepSeek Harness shape at deploy time, exactly like Convert-AgentFile and
|
|
246
|
-
# Convert-RuleFile do for Cursor / OpenCode.
|
|
247
|
-
|
|
248
|
-
function Get-MarkdownBody {
|
|
249
|
-
# Strip a leading YAML frontmatter block (--- ... ---) from markdown text.
|
|
250
|
-
# DeepSeek Harness injects AGENTS.md-style instruction files verbatim, so
|
|
251
|
-
# the frontmatter must not reach the model prompt.
|
|
252
|
-
param([string]$Content)
|
|
253
|
-
$m = [regex]::Match($Content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
254
|
-
if (-not $m.Success) { return $Content }
|
|
255
|
-
return $m.Groups[2].Value
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function Get-WakeupGuideline {
|
|
259
|
-
# Extract the <WakeupGuideline>...</WakeupGuideline> block from the rule
|
|
260
|
-
# text, so the DSH wakeup plugin is generated from the same source the
|
|
261
|
-
# Copilot / Cursor / OpenCode rules use.
|
|
262
|
-
param([string]$RuleText)
|
|
263
|
-
$m = [regex]::Match($RuleText, '(?s)<WakeupGuideline>(.*?)</WakeupGuideline>')
|
|
264
|
-
if (-not $m.Success) { return '' }
|
|
265
|
-
return $m.Groups[1].Value.Trim()
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
function Write-DshAgentRule {
|
|
269
|
-
# Merge the frontmatter-stripped ArchGraph rule into ~/.dsh/AGENTS.md,
|
|
270
|
-
# replacing the previous ArchGraph block while preserving surrounding user
|
|
271
|
-
# content. The rule body is injected verbatim - no adapter prose, so the
|
|
272
|
-
# working prompt stays identical to the Copilot / Cursor / OpenCode rules.
|
|
273
|
-
param(
|
|
274
|
-
[string]$DshHome,
|
|
275
|
-
[string]$RuleText
|
|
276
|
-
)
|
|
277
|
-
$ruleContent = Get-MarkdownBody -Content $RuleText
|
|
278
|
-
$dest = Join-Path $DshHome 'AGENTS.md'
|
|
279
|
-
$marker = '<WakeupGuideline>'
|
|
280
|
-
New-Item -ItemType Directory -Force -Path $DshHome | Out-Null
|
|
281
|
-
if (Test-Path $dest) {
|
|
282
|
-
$existing = Get-Content $dest -Raw -Encoding UTF8
|
|
283
|
-
if ($existing -like "*$marker*") {
|
|
284
|
-
$endTag = '</ToolsGuideline>'
|
|
285
|
-
$startIdx = $existing.IndexOf($marker)
|
|
286
|
-
if ($startIdx -lt 0) { $startIdx = 0 }
|
|
287
|
-
$endIdx = $existing.IndexOf($endTag, $startIdx)
|
|
288
|
-
$before = $existing.Substring(0, $startIdx).TrimEnd()
|
|
289
|
-
if ($endIdx -lt 0) {
|
|
290
|
-
$combined = $before
|
|
291
|
-
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
292
|
-
$combined += $ruleContent
|
|
293
|
-
} else {
|
|
294
|
-
$after = $existing.Substring($endIdx + $endTag.Length)
|
|
295
|
-
$combined = $before
|
|
296
|
-
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
297
|
-
$combined += $ruleContent
|
|
298
|
-
if ($after.Length -gt 0) { $combined += $after }
|
|
299
|
-
}
|
|
300
|
-
[System.IO.File]::WriteAllText($dest, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
301
|
-
} else {
|
|
302
|
-
$combined = $existing.TrimEnd() + "`n`n" + $ruleContent
|
|
303
|
-
[System.IO.File]::WriteAllText($dest, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
[System.IO.File]::WriteAllText($dest, $ruleContent, (New-Object System.Text.UTF8Encoding $false))
|
|
307
|
-
}
|
|
308
|
-
Write-Host " DSH rule installed -> $dest"
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function Write-DshManagedBlock {
|
|
312
|
-
# Text-level upsert of a marker-delimited block into a file (used for the
|
|
313
|
-
# managed rows in ~/.dsh/cordis.patch.yml): replaces the previous managed
|
|
314
|
-
# block and preserves surrounding content. No YAML dependency needed.
|
|
315
|
-
param(
|
|
316
|
-
[string]$Path,
|
|
317
|
-
[string]$Block,
|
|
318
|
-
[string]$MarkerStart,
|
|
319
|
-
[string]$MarkerEnd
|
|
320
|
-
)
|
|
321
|
-
New-Item -ItemType Directory -Force -Path (Split-Path $Path) | Out-Null
|
|
322
|
-
$existing = if (Test-Path $Path) { Get-Content $Path -Raw -Encoding UTF8 } else { '' }
|
|
323
|
-
$startIdx = $existing.IndexOf($MarkerStart)
|
|
324
|
-
$endIdx = if ($startIdx -ge 0) { $existing.IndexOf($MarkerEnd, $startIdx) } else { -1 }
|
|
325
|
-
if ($startIdx -ge 0 -and $endIdx -ge 0) {
|
|
326
|
-
$endIdx += $MarkerEnd.Length
|
|
327
|
-
$combined = $existing.Substring(0, $startIdx).TrimEnd()
|
|
328
|
-
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
329
|
-
$combined += $Block
|
|
330
|
-
$after = $existing.Substring($endIdx).TrimStart()
|
|
331
|
-
if ($after.Length -gt 0) { $combined += "`n`n" + $after }
|
|
332
|
-
[System.IO.File]::WriteAllText($Path, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
333
|
-
} else {
|
|
334
|
-
$combined = $existing.TrimEnd()
|
|
335
|
-
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
336
|
-
$combined += $Block + "`n"
|
|
337
|
-
[System.IO.File]::WriteAllText($Path, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function New-DshWakeupPlugin {
|
|
342
|
-
# Generate the DSH wakeup-gate Cordis plugin under ~/.dsh/plugins from the
|
|
343
|
-
# <WakeupGuideline> block of the rule file. This is the DeepSeek Harness
|
|
344
|
-
# equivalent of the OpenCode hook plugin argo/plugins/argo-wakeup.js: it
|
|
345
|
-
# registers the gate as the first system-prompt section after the harness
|
|
346
|
-
# identity (order -100), before the deployment persona (order 0).
|
|
347
|
-
param(
|
|
348
|
-
[string]$DshHome,
|
|
349
|
-
[string]$RuleText
|
|
350
|
-
)
|
|
351
|
-
$gate = Get-WakeupGuideline -RuleText $RuleText
|
|
352
|
-
if (-not $gate) {
|
|
353
|
-
Write-Warning ' <WakeupGuideline> not found in the rule file; DSH wakeup plugin skipped.'
|
|
354
|
-
return $null
|
|
355
|
-
}
|
|
356
|
-
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-wakeup'
|
|
357
|
-
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
358
|
-
$gateJson = $gate | ConvertTo-Json
|
|
359
|
-
$plugin = @"
|
|
360
|
-
// dsh-argo-wakeup - generated by install-argo.ps1 from
|
|
361
|
-
// argo/rules/archgraph.instructions.md (single source of truth: the rule file;
|
|
362
|
-
// this file is a deployment artifact, do not edit by hand).
|
|
363
|
-
// DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
|
|
364
|
-
// registers the unconditional wakeup gate as the first system-prompt section
|
|
365
|
-
// after the harness identity, so every session identifies its Business Actor
|
|
366
|
-
// through the argo MCP server before responding.
|
|
367
|
-
export const name = 'dsh-argo-wakeup'
|
|
368
|
-
export const inject = ['systemPrompt']
|
|
369
|
-
const WAKEUP_GATE = $gateJson
|
|
370
|
-
export function apply(ctx) {
|
|
371
|
-
ctx.effect(() => ctx.systemPrompt.section({
|
|
372
|
-
name: 'argo:wakeup',
|
|
373
|
-
order: -90,
|
|
374
|
-
text: WAKEUP_GATE,
|
|
375
|
-
}), 'argo:wakeup.section()')
|
|
376
|
-
}
|
|
377
|
-
"@
|
|
378
|
-
$indexPath = Join-Path $dir 'index.js'
|
|
379
|
-
[System.IO.File]::WriteAllText($indexPath, $plugin, (New-Object System.Text.UTF8Encoding $false))
|
|
380
|
-
Write-Host " DSH wakeup plugin generated -> $indexPath"
|
|
381
|
-
return $indexPath
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
function New-DshWorkspaceBridge {
|
|
385
|
-
# Generate the DSH workspace bridge plugin under ~/.dsh/plugins. It
|
|
386
|
-
# connects directly to the argo MCP server (no dsh-mcp-client row needed)
|
|
387
|
-
# with a zero-dependency minimal MCP stdio client, registers every tool as
|
|
388
|
-
# mcp__argo__* and injects the current session's workspace directory
|
|
389
|
-
# (SessionHeader.cwd) as the per-call `workspaceRoot`, so ONE dsh instance
|
|
390
|
-
# follows whichever workspace the user switched to - no model-visible
|
|
391
|
-
# parameters, no internal tool names, no restart. The argo server honors
|
|
392
|
-
# workspaceRoot only when listed in ARGO_WORKSPACE_ROOTS (install-argo.ps1
|
|
393
|
-
# -DshWorkspaces).
|
|
394
|
-
param(
|
|
395
|
-
[string]$DshHome
|
|
396
|
-
)
|
|
397
|
-
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-workspace'
|
|
398
|
-
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
399
|
-
$plugin = @'
|
|
400
|
-
// dsh-argo-workspace - generated by install-argo.ps1 (single source of truth:
|
|
401
|
-
// the installer; this file is a deployment artifact, do not edit by hand).
|
|
402
|
-
//
|
|
403
|
-
// Direct MCP bridge to the argo server for DeepSeek Harness. Registers every
|
|
404
|
-
// argo tool as mcp__argo__* and injects the current session's workspace
|
|
405
|
-
// directory (SessionHeader.cwd) as the per-call `workspaceRoot` argument, so
|
|
406
|
-
// one dsh instance follows whichever workspace the user switched to - the
|
|
407
|
-
// model sees no extra parameters and no internal tool names. The argo server
|
|
408
|
-
// honors workspaceRoot only when the workspace is listed in its
|
|
409
|
-
// ARGO_WORKSPACE_ROOTS allowlist.
|
|
410
|
-
//
|
|
411
|
-
// Zero dependencies on purpose: implements the minimal MCP stdio client
|
|
412
|
-
// (JSON-RPC 2.0, one JSON object per line) with Node built-ins only, so the
|
|
413
|
-
// plugin runs from any DSH layout without resolving @modelcontextprotocol/sdk.
|
|
414
|
-
import { spawn } from 'node:child_process'
|
|
415
|
-
import readline from 'node:readline'
|
|
416
|
-
|
|
417
|
-
export const name = 'dsh-argo-workspace'
|
|
418
|
-
export const inject = ['tools']
|
|
419
|
-
|
|
420
|
-
/** Minimal MCP stdio client over the argo server process. */
|
|
421
|
-
function createArgoClient(serverPath, env, cwd) {
|
|
422
|
-
const child = spawn('node', [serverPath], {
|
|
423
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
424
|
-
env,
|
|
425
|
-
...(cwd ? { cwd } : {}),
|
|
426
|
-
})
|
|
427
|
-
const pending = new Map()
|
|
428
|
-
let nextId = 1
|
|
429
|
-
readline.createInterface({ input: child.stdout }).on('line', (line) => {
|
|
430
|
-
let message
|
|
431
|
-
try { message = JSON.parse(line) } catch { return }
|
|
432
|
-
if (message && typeof message.id === 'number' && pending.has(message.id)) {
|
|
433
|
-
const { resolve, reject } = pending.get(message.id)
|
|
434
|
-
pending.delete(message.id)
|
|
435
|
-
if (message.error) reject(new Error(JSON.stringify(message.error)))
|
|
436
|
-
else resolve(message.result)
|
|
437
|
-
}
|
|
438
|
-
})
|
|
439
|
-
child.stderr.on('data', () => {}) // drain; the argo server logs to stderr
|
|
440
|
-
const request = (method, params) => new Promise((resolve, reject) => {
|
|
441
|
-
const id = nextId++
|
|
442
|
-
pending.set(id, { resolve, reject })
|
|
443
|
-
child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n')
|
|
444
|
-
})
|
|
445
|
-
return {
|
|
446
|
-
request,
|
|
447
|
-
notify: (method, params) => {
|
|
448
|
-
child.stdin.write(JSON.stringify({ jsonrpc: '2.0', method, params }) + '\n')
|
|
449
|
-
},
|
|
450
|
-
close: () => child.kill(),
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/** Connect, list tools, register them, and keep the client until disposal. */
|
|
455
|
-
export async function apply(ctx, config) {
|
|
456
|
-
const serverPath = config.serverPath
|
|
457
|
-
const workspaces = Array.isArray(config.workspaces) ? config.workspaces : []
|
|
458
|
-
const env = { ...process.env }
|
|
459
|
-
if (workspaces.length > 0) env.ARGO_WORKSPACE_ROOTS = workspaces.join(';')
|
|
460
|
-
const client = createArgoClient(serverPath, env, config.cwd)
|
|
461
|
-
ctx.effect(() => () => client.close(), 'dsh-argo-workspace.dispose()')
|
|
462
|
-
|
|
463
|
-
let tools = []
|
|
464
|
-
try {
|
|
465
|
-
await client.request('initialize', {
|
|
466
|
-
protocolVersion: '2024-11-05',
|
|
467
|
-
capabilities: {},
|
|
468
|
-
clientInfo: { name: 'dsh-argo-workspace', version: '0.1.0' },
|
|
469
|
-
})
|
|
470
|
-
client.notify('notifications/initialized', {})
|
|
471
|
-
const listed = await client.request('tools/list', {})
|
|
472
|
-
tools = (listed && Array.isArray(listed.tools)) ? listed.tools : []
|
|
473
|
-
} catch (error) {
|
|
474
|
-
console.warn(`[dsh-argo-workspace] failed to connect to the argo MCP server (${serverPath}): ${error && error.message ? error.message : error}`)
|
|
475
|
-
return
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const disposers = []
|
|
479
|
-
for (const tool of tools) {
|
|
480
|
-
const publicName = 'mcp__argo__' + tool.name
|
|
481
|
-
disposers.push(ctx.tools.register({
|
|
482
|
-
name: publicName,
|
|
483
|
-
description: tool.description ?? '',
|
|
484
|
-
parameters: tool.inputSchema,
|
|
485
|
-
output: {
|
|
486
|
-
schema: {
|
|
487
|
-
type: 'object',
|
|
488
|
-
properties: { content: { type: 'array', items: {} } },
|
|
489
|
-
required: ['content'],
|
|
490
|
-
additionalProperties: false,
|
|
491
|
-
},
|
|
492
|
-
},
|
|
493
|
-
execute: async (args, exec) => {
|
|
494
|
-
const sessionCwd = exec && exec.agent && exec.agent.session
|
|
495
|
-
? exec.agent.session.requestHeader().cwd
|
|
496
|
-
: undefined
|
|
497
|
-
const injected = { ...(args && typeof args === 'object' ? args : {}) }
|
|
498
|
-
if (typeof sessionCwd === 'string' && sessionCwd !== '') {
|
|
499
|
-
injected.workspaceRoot = sessionCwd
|
|
500
|
-
}
|
|
501
|
-
if (exec && exec.signal && exec.signal.aborted) {
|
|
502
|
-
throw new Error('aborted')
|
|
503
|
-
}
|
|
504
|
-
const result = await client.request('tools/call', {
|
|
505
|
-
name: tool.name,
|
|
506
|
-
arguments: injected,
|
|
507
|
-
})
|
|
508
|
-
const text = Array.isArray(result.content)
|
|
509
|
-
? result.content
|
|
510
|
-
.map((block) => block && block.type === 'text' && typeof block.text === 'string'
|
|
511
|
-
? block.text
|
|
512
|
-
: JSON.stringify(block))
|
|
513
|
-
.join('\n')
|
|
514
|
-
: (result.toolResult !== undefined ? JSON.stringify(result.toolResult) : '(no output)')
|
|
515
|
-
if (result.isError === true) throw new Error(text)
|
|
516
|
-
return {
|
|
517
|
-
content: [{ type: 'text', text }],
|
|
518
|
-
...(result.structuredContent !== undefined ? { structuredContent: result.structuredContent } : {}),
|
|
519
|
-
}
|
|
520
|
-
},
|
|
521
|
-
}))
|
|
522
|
-
}
|
|
523
|
-
ctx.effect(() => () => {
|
|
524
|
-
for (const dispose of disposers) dispose()
|
|
525
|
-
}, 'dsh-argo-workspace.tools')
|
|
526
|
-
}
|
|
527
|
-
'@
|
|
528
|
-
$indexPath = Join-Path $dir 'index.js'
|
|
529
|
-
[System.IO.File]::WriteAllText($indexPath, $plugin, (New-Object System.Text.UTF8Encoding $false))
|
|
530
|
-
Write-Host " DSH workspace bridge generated -> $indexPath"
|
|
531
|
-
return $indexPath
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
function New-DshAgentPresets {
|
|
535
|
-
# Generate DSH agent presets under ~/.dsh/.agent-presets/<id>/ from
|
|
536
|
-
# argo/agents/*.agent.md (the same single source the Copilot / Cursor /
|
|
537
|
-
# OpenCode agent files are converted from). persona.md is a
|
|
538
|
-
# frontmatter-stripped copy of the agent body; persona.js is a fixed
|
|
539
|
-
# self-contained row that mounts it as the session persona
|
|
540
|
-
# (deployment:persona section, order 0).
|
|
541
|
-
param(
|
|
542
|
-
[string]$DshHome,
|
|
543
|
-
[string]$AgentsSrc
|
|
544
|
-
)
|
|
545
|
-
$files = @(Get-ChildItem -Path (Join-Path $AgentsSrc '*.agent.md') -ErrorAction SilentlyContinue)
|
|
546
|
-
if ($files.Count -eq 0) {
|
|
547
|
-
Write-Warning ' no *.agent.md files found; DSH agent presets skipped.'
|
|
548
|
-
return
|
|
549
|
-
}
|
|
550
|
-
foreach ($file in $files) {
|
|
551
|
-
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
|
552
|
-
$m = [regex]::Match($content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
553
|
-
$name = ''
|
|
554
|
-
$desc = ''
|
|
555
|
-
$body = $content
|
|
556
|
-
if ($m.Success) {
|
|
557
|
-
$front = $m.Groups[1].Value
|
|
558
|
-
$body = $m.Groups[2].Value.TrimStart("`r", "`n")
|
|
559
|
-
$nm = [regex]::Match($front, '(?m)^name:\s*(.*)$')
|
|
560
|
-
if ($nm.Success) { $name = $nm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
561
|
-
$dm = [regex]::Match($front, '(?m)^description:\s*(.*)$')
|
|
562
|
-
if ($dm.Success) { $desc = $dm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
563
|
-
}
|
|
564
|
-
$id = $file.BaseName -replace '\.agent$', ''
|
|
565
|
-
if (-not $name) { $name = $id }
|
|
566
|
-
$dir = Join-Path (Join-Path $DshHome '.agent-presets') $id
|
|
567
|
-
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
568
|
-
|
|
569
|
-
# preset.yml: display metadata (name + description).
|
|
570
|
-
$presetYml = "name: $name`n"
|
|
571
|
-
if ($desc) { $presetYml += "description: `"$($desc -replace '"', '\"')`"`n" }
|
|
572
|
-
[System.IO.File]::WriteAllText((Join-Path $dir 'preset.yml'), $presetYml, (New-Object System.Text.UTF8Encoding $false))
|
|
573
|
-
|
|
574
|
-
# persona.md: the agent body verbatim (single source: the .agent.md file).
|
|
575
|
-
[System.IO.File]::WriteAllText((Join-Path $dir 'persona.md'), $body, (New-Object System.Text.UTF8Encoding $false))
|
|
576
|
-
|
|
577
|
-
# agent.cordis.yml: mount the local persona row.
|
|
578
|
-
$cordisYml = @"
|
|
579
|
-
# ArchGraph agent preset "$name" - generated by install-argo.ps1 from
|
|
580
|
-
# argo/agents/$($file.Name) (single source of truth; this file is a deployment
|
|
581
|
-
# artifact, do not edit by hand). The persona is the frontmatter-stripped agent
|
|
582
|
-
# body (persona.md), mounted as the session's deployment:persona section.
|
|
583
|
-
- id: persona
|
|
584
|
-
name: './persona.js'
|
|
585
|
-
"@
|
|
586
|
-
[System.IO.File]::WriteAllText((Join-Path $dir 'agent.cordis.yml'), $cordisYml, (New-Object System.Text.UTF8Encoding $false))
|
|
587
|
-
|
|
588
|
-
# persona.js: fixed row implementation.
|
|
589
|
-
$personaJs = @'
|
|
590
|
-
// persona row for an ArchGraph agent preset (generated by install-argo.ps1).
|
|
591
|
-
// Loads persona.md next to this file and registers it as the
|
|
592
|
-
// deployment:persona system-prompt section (order 0), shadowing the
|
|
593
|
-
// deployment persona for the session that mounts this preset.
|
|
594
|
-
import { readFileSync } from 'node:fs'
|
|
595
|
-
import { fileURLToPath } from 'node:url'
|
|
596
|
-
export const name = 'persona'
|
|
597
|
-
export const inject = ['systemPrompt']
|
|
598
|
-
export function apply(ctx) {
|
|
599
|
-
const text = readFileSync(fileURLToPath(new URL('./persona.md', import.meta.url)), 'utf8')
|
|
600
|
-
ctx.effect(() => ctx.systemPrompt.section({
|
|
601
|
-
name: 'deployment:persona',
|
|
602
|
-
order: 0,
|
|
603
|
-
text,
|
|
604
|
-
}), 'persona.section()')
|
|
605
|
-
}
|
|
606
|
-
'@
|
|
607
|
-
[System.IO.File]::WriteAllText((Join-Path $dir 'persona.js'), $personaJs, (New-Object System.Text.UTF8Encoding $false))
|
|
608
|
-
Write-Host " DSH agent preset generated -> $dir"
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
|
|
612
238
|
Write-Host '==> Deploying Argo toolchain'
|
|
613
239
|
|
|
614
240
|
$schemaSrc = Join-Path $argoDir 'schema'
|
|
615
241
|
$schemaDest = Join-Path $ArgoRoot 'schema'
|
|
616
|
-
Write-Host "[1/
|
|
242
|
+
Write-Host "[1/14] argo\schema -> $schemaDest"
|
|
617
243
|
Copy-Tree -Source $schemaSrc -Destination $schemaDest
|
|
618
244
|
|
|
619
245
|
$scriptsSrc = Join-Path $argoDir 'scripts'
|
|
620
246
|
$scriptsDest = Join-Path $ArgoRoot 'scripts'
|
|
621
|
-
Write-Host "[2/
|
|
247
|
+
Write-Host "[2/14] argo\scripts -> $scriptsDest"
|
|
622
248
|
Copy-Tree -Source $scriptsSrc -Destination $scriptsDest
|
|
623
249
|
|
|
624
250
|
$defaultsSrc = Join-Path $argoDir 'defaults'
|
|
625
251
|
$defaultsDest = Join-Path $ArgoRoot 'defaults'
|
|
626
|
-
Write-Host "[3/
|
|
252
|
+
Write-Host "[3/14] argo\defaults -> $defaultsDest"
|
|
627
253
|
Copy-Tree -Source $defaultsSrc -Destination $defaultsDest
|
|
628
254
|
|
|
629
255
|
$skillSrc = Join-Path (Join-Path $argoDir 'skills') 'argo-init'
|
|
630
256
|
$skillDest = Join-Path $SkillsRoot 'argo-init'
|
|
631
|
-
Write-Host "[4/
|
|
257
|
+
Write-Host "[4/14] argo\skills\argo-init -> $skillDest"
|
|
632
258
|
Copy-Tree -Source $skillSrc -Destination $skillDest
|
|
633
259
|
|
|
634
260
|
$ruleSrc = Join-Path (Join-Path $argoDir 'rules') 'archgraph.instructions.md'
|
|
635
261
|
$ruleDest = Join-Path $PromptsRoot 'archgraph.instructions.md'
|
|
636
|
-
Write-Host "[5/
|
|
262
|
+
Write-Host "[5/14] argo\rules\archgraph.instructions.md -> $ruleDest"
|
|
637
263
|
New-Item -ItemType Directory -Force -Path $PromptsRoot | Out-Null
|
|
638
264
|
Copy-Item -Force -Path $ruleSrc -Destination $ruleDest
|
|
639
265
|
|
|
640
266
|
$depsSrc = Join-Path $argoDir 'package.json'
|
|
641
267
|
$depsDest = Join-Path $ArgoRoot 'package.json'
|
|
642
|
-
Write-Host "[6/
|
|
268
|
+
Write-Host "[6/14] argo\package.json -> $depsDest"
|
|
643
269
|
Copy-Item -Force -Path $depsSrc -Destination $depsDest
|
|
644
270
|
|
|
645
271
|
$cursorSkillDest = Join-Path $CursorSkillsRoot 'argo-init'
|
|
646
|
-
Write-Host "[7/
|
|
272
|
+
Write-Host "[7/14] argo\skills\argo-init -> $cursorSkillDest (Cursor)"
|
|
647
273
|
Copy-Tree -Source $skillSrc -Destination $cursorSkillDest
|
|
648
274
|
|
|
649
275
|
$openCodeSkillDest = Join-Path $OpenCodeSkillsRoot 'argo-init'
|
|
650
|
-
Write-Host "[8/
|
|
276
|
+
Write-Host "[8/14] argo\skills\argo-init -> $openCodeSkillDest (OpenCode)"
|
|
651
277
|
Copy-Tree -Source $skillSrc -Destination $openCodeSkillDest
|
|
652
278
|
|
|
653
|
-
Write-Host "[9/
|
|
279
|
+
Write-Host "[9/14] argo\rules\archgraph.instructions.md -> $OpenCodeAgentsPath (OpenCode global AGENTS.md)"
|
|
654
280
|
Add-AgentsRule -AgentsPath $OpenCodeAgentsPath -RulePath $ruleSrc
|
|
655
281
|
|
|
656
282
|
$agentsSrc = Join-Path $argoDir 'agents'
|
|
657
|
-
Write-Host "[10/
|
|
283
|
+
Write-Host "[10/14] argo\agents -> $CopilotAgentsRoot (Copilot user-level)"
|
|
658
284
|
Copy-Agents -Source $agentsSrc -Destination $CopilotAgentsRoot
|
|
659
285
|
|
|
660
|
-
Write-Host "[11/
|
|
286
|
+
Write-Host "[11/14] argo\agents -> $CursorAgentsRoot (Cursor user-level, converted to .md)"
|
|
661
287
|
Copy-Agents -Source $agentsSrc -Destination $CursorAgentsRoot -Target cursor
|
|
662
288
|
|
|
663
|
-
Write-Host "[12/
|
|
289
|
+
Write-Host "[12/14] argo\agents -> $OpenCodeAgentsRoot (OpenCode user-level, converted to .md)"
|
|
664
290
|
Copy-Agents -Source $agentsSrc -Destination $OpenCodeAgentsRoot -Target opencode
|
|
665
291
|
|
|
666
292
|
$pluginsSrc = Join-Path $argoDir 'plugins'
|
|
667
|
-
Write-Host "[13/
|
|
293
|
+
Write-Host "[13/14] argo\plugins -> $PluginsRoot (Argo opencode plugins)"
|
|
668
294
|
Copy-Tree -Source $pluginsSrc -Destination $PluginsRoot
|
|
669
295
|
|
|
670
296
|
$cursorRuleSrc = Join-Path (Join-Path $argoDir 'rules') 'archgraph.instructions.md'
|
|
671
297
|
$cursorRuleDest = Join-Path $CursorRulesRoot 'archgraph.mdc'
|
|
672
|
-
Write-Host "[14/
|
|
298
|
+
Write-Host "[14/14] argo\rules\archgraph.instructions.md -> $cursorRuleDest (Cursor global rule, alwaysApply)"
|
|
673
299
|
New-Item -ItemType Directory -Force -Path $CursorRulesRoot | Out-Null
|
|
674
300
|
Convert-RuleFile -SourceFile $cursorRuleSrc -DestinationFile $cursorRuleDest
|
|
675
301
|
|
|
676
|
-
if ($SkipDsh) {
|
|
677
|
-
Write-Host 'Skipped DeepSeek Harness integration (-SkipDsh).'
|
|
678
|
-
} else {
|
|
679
|
-
$ruleSrcContent = Get-Content $ruleSrc -Raw -Encoding UTF8
|
|
680
|
-
$dshSkillDest = Join-Path (Join-Path $DshHome 'skills') 'argo-init'
|
|
681
|
-
$patchPath = Join-Path $DshHome 'cordis.patch.yml'
|
|
682
|
-
$argoServer = (Join-Path $ArgoRoot 'scripts\argo-mcp-server.js').Replace('\', '/')
|
|
683
|
-
|
|
684
|
-
Write-Host "[15/19] argo\rules\archgraph.instructions.md -> $DshHome\AGENTS.md (DeepSeek Harness user-global rule, frontmatter stripped)"
|
|
685
|
-
Write-DshAgentRule -DshHome $DshHome -RuleText $ruleSrcContent
|
|
686
|
-
|
|
687
|
-
Write-Host "[16/19] argo\skills\argo-init -> $dshSkillDest (DeepSeek Harness skill)"
|
|
688
|
-
Copy-Tree -Source (Join-Path $argoDir 'skills\argo-init') -Destination $dshSkillDest
|
|
689
|
-
|
|
690
|
-
Write-Host "[17/19] argo\rules\<WakeupGuideline> -> $DshHome\plugins\dsh-argo-wakeup\index.js (DeepSeek Harness wakeup plugin)"
|
|
691
|
-
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome -RuleText $ruleSrcContent
|
|
692
|
-
|
|
693
|
-
Write-Host "[18/19] argo-workspace + argo-wakeup rows -> $patchPath (DeepSeek Harness MCP bridge + wakeup plugin)"
|
|
694
|
-
# The generated dsh-argo-workspace bridge connects directly to the argo
|
|
695
|
-
# server (no dsh-mcp-client row), registers every tool as mcp__argo__* and
|
|
696
|
-
# injects the current session's workspace (SessionHeader.cwd) as the
|
|
697
|
-
# per-call workspaceRoot, so one dsh instance follows the workspace the
|
|
698
|
-
# user switched to. The server honors workspaceRoot only when the workspace
|
|
699
|
-
# is listed in ARGO_WORKSPACE_ROOTS (pass -DshWorkspaces "D:/a;D:/b").
|
|
700
|
-
$bridgeDshPath = New-DshWorkspaceBridge -DshHome $DshHome
|
|
701
|
-
if ($bridgeDshPath) {
|
|
702
|
-
$bridgeUrl = 'file:///' + (($bridgeDshPath -replace '\\', '/').TrimStart('/'))
|
|
703
|
-
$bridgeConfig = " config:`n serverPath: '$argoServer'`n"
|
|
704
|
-
if ($DshWorkspaces) {
|
|
705
|
-
$wsList = @($DshWorkspaces.Replace('\', '/').Split(';') | ForEach-Object { " - $_" }) -join "`n"
|
|
706
|
-
$bridgeConfig += " workspaces:`n" + $wsList + "`n"
|
|
707
|
-
}
|
|
708
|
-
if ($DshCwd) {
|
|
709
|
-
$bridgeConfig += " cwd: $($DshCwd.Replace('\', '/'))`n"
|
|
710
|
-
}
|
|
711
|
-
$rows = " - id: argo-workspace`n name: '$bridgeUrl'`n" + $bridgeConfig
|
|
712
|
-
} else {
|
|
713
|
-
$rows = ''
|
|
714
|
-
}
|
|
715
|
-
if ($wakeupDshPath) {
|
|
716
|
-
$pluginUrl = 'file:///' + (($wakeupDshPath -replace '\\', '/').TrimStart('/'))
|
|
717
|
-
$rows += " - id: argo-wakeup`n name: '$pluginUrl'`n"
|
|
718
|
-
}
|
|
719
|
-
if ($rows) {
|
|
720
|
-
$block = "# BEGIN ArchGraph ARGO deployment (managed by install-argo.ps1)`n- insert:`n" + $rows + "# END ArchGraph ARGO deployment"
|
|
721
|
-
Write-DshManagedBlock -Path $patchPath -Block $block -MarkerStart '# BEGIN ArchGraph ARGO deployment' -MarkerEnd '# END ArchGraph ARGO deployment'
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
Write-Host "[19/19] argo\agents -> $DshHome\.agent-presets\<id> (DeepSeek Harness agent presets)"
|
|
725
|
-
New-DshAgentPresets -DshHome $DshHome -AgentsSrc (Join-Path $argoDir 'agents')
|
|
726
|
-
|
|
727
|
-
Write-Host ' Restart `dsh web` to activate the MCP bridge and the wakeup plugin;'
|
|
728
|
-
Write-Host ' new sessions pick up the global rule and the argo-init skill automatically.'
|
|
729
|
-
if ($DshWorkspaces) {
|
|
730
|
-
Write-Host " Workspace following enabled: ARGO_WORKSPACE_ROOTS=$DshWorkspaces"
|
|
731
|
-
Write-Host ' The argo tools (mcp__argo__*) now auto-follow the workspace the user switched to'
|
|
732
|
-
Write-Host ' in one dsh instance - no restart needed between workspaces.'
|
|
733
|
-
} else {
|
|
734
|
-
Write-Host ' Multi-workspace: to let one dsh instance follow whichever workspace the user'
|
|
735
|
-
Write-Host ' switches to, re-run with -DshWorkspaces "D:/proj-a;D:/proj-b" (the argo server'
|
|
736
|
-
Write-Host ' only honors workspaces listed in ARGO_WORKSPACE_ROOTS). Without it the server'
|
|
737
|
-
Write-Host ' keeps resolving from the directory dsh was launched from.'
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
|
|
741
302
|
if ($SkipDeps) {
|
|
742
303
|
Write-Host 'Skipped dependency install (-SkipDeps).'
|
|
743
304
|
} elseif (Get-Command npm -ErrorAction SilentlyContinue) {
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "archgraph-argo",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"bin": {
|
|
7
|
-
"argo-deploy": "bin/argo-deploy.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"argo/scripts",
|
|
11
|
-
"argo/schema",
|
|
12
|
-
"argo/defaults",
|
|
13
|
-
"argo/agents",
|
|
14
|
-
"argo/plugins",
|
|
15
|
-
"argo/skills/argo-init",
|
|
16
|
-
"argo/rules",
|
|
17
|
-
"argo/package.json",
|
|
18
|
-
"vendor",
|
|
19
|
-
"install-argo.ps1",
|
|
20
|
-
"bin"
|
|
21
|
-
],
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"neo4j-driver": "^6.2.0"
|
|
24
|
-
},
|
|
25
|
-
"scripts": {
|
|
26
|
-
"test": "node --test \"tests/*.test.js\""
|
|
27
|
-
},
|
|
28
|
-
"engines": {
|
|
29
|
-
"node": ">=18"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "archgraph-argo",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"argo-deploy": "bin/argo-deploy.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"argo/scripts",
|
|
11
|
+
"argo/schema",
|
|
12
|
+
"argo/defaults",
|
|
13
|
+
"argo/agents",
|
|
14
|
+
"argo/plugins",
|
|
15
|
+
"argo/skills/argo-init",
|
|
16
|
+
"argo/rules",
|
|
17
|
+
"argo/package.json",
|
|
18
|
+
"vendor",
|
|
19
|
+
"install-argo.ps1",
|
|
20
|
+
"bin"
|
|
21
|
+
],
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"neo4j-driver": "^6.2.0"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"test": "node --test \"tests/*.test.js\""
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
}
|
|
31
|
+
}
|