archgraph-argo 0.26.2 → 0.27.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 +13 -4
- package/argo/.env.example +170 -163
- package/argo/plugins/argo-wakeup.js +29 -27
- package/argo/rules/archgraph.instructions.md +189 -187
- package/argo/schema/argob-rules.json +12229 -0
- package/argo/schema/argob.config.json +20 -0
- package/argo/scripts/argo-mcp-server.js +67 -1
- package/argo/scripts/argob-schema.js +574 -0
- package/argo/scripts/ensureArgoHarnessEnvironment.js +14 -0
- package/argo/scripts/external-graph-query.js +162 -0
- package/argo/scripts/graph-rag/defaultSemanticRetrieval.js +0 -13
- package/argo/scripts/graph-rag/liveEmbeddingProviderConfig.js +6 -61
- package/argo/scripts/graph-semantics.js +266 -227
- package/argo/scripts/runArchitectureTests.js +14 -6
- package/argo/scripts/systemarchitecture-mcp-server.js +87 -44
- package/argo/scripts/validateSystemArchitecture.js +260 -253
- package/argo/scripts/validator-mcp-server.js +1 -1
- package/argo/skills/argo-init/SKILL.md +7 -9
- package/argo/skills/ea-human-reconcile/SKILL.md +2 -1
- package/dsh-argo-wakeup/index.js +2 -2
- package/dsh-argo-workspace/index.js +3 -2
- package/install-argo.ps1 +215 -186
- package/package.json +5 -2
package/install-argo.ps1
CHANGED
|
@@ -25,6 +25,9 @@ param(
|
|
|
25
25
|
[string]$OpenClawWorkspace = "$env:USERPROFILE\.openclaw\workspace",
|
|
26
26
|
[string]$OpenClawRepoRoot = '',
|
|
27
27
|
[switch]$SkipOpenClaw,
|
|
28
|
+
[string]$DoubaoHome = "$env:USERPROFILE\Doubao",
|
|
29
|
+
[string]$DoubaoWorkspace = "$env:LOCALAPPDATA\Doubao\User Data\Default\.doubao\agent_mode\workspace",
|
|
30
|
+
[switch]$SkipDoubao,
|
|
28
31
|
[string]$McpPath,
|
|
29
32
|
[string]$GraphMcpUrl = 'https://argo.derekworkspacev5.com/mcp'
|
|
30
33
|
)
|
|
@@ -298,16 +301,6 @@ function Get-MarkdownBody {
|
|
|
298
301
|
return $m.Groups[2].Value
|
|
299
302
|
}
|
|
300
303
|
|
|
301
|
-
function Get-WakeupGuideline {
|
|
302
|
-
# Extract the <WakeupGuideline>...</WakeupGuideline> block from the rule
|
|
303
|
-
# text, so the DSH wakeup plugin is generated from the same source the
|
|
304
|
-
# Copilot / Cursor / OpenCode rules use.
|
|
305
|
-
param([string]$RuleText)
|
|
306
|
-
$m = [regex]::Match($RuleText, '(?s)<WakeupGuideline>(.*?)</WakeupGuideline>')
|
|
307
|
-
if (-not $m.Success) { return '' }
|
|
308
|
-
return $m.Groups[1].Value.Trim()
|
|
309
|
-
}
|
|
310
|
-
|
|
311
304
|
function Write-ArchGraphRuleBlock {
|
|
312
305
|
# Merge the frontmatter-stripped ArchGraph rule into a target AGENTS.md
|
|
313
306
|
# file (DSH home or OpenClaw workspace), replacing the previous ArchGraph
|
|
@@ -372,6 +365,149 @@ function Write-OpenClawAgentRule {
|
|
|
372
365
|
Write-ArchGraphRuleBlock -DestPath (Join-Path $OpenClawWorkspace 'AGENTS.md') -RuleText $RuleText -Label 'OpenClaw rule'
|
|
373
366
|
}
|
|
374
367
|
|
|
368
|
+
function Convert-SkillFile {
|
|
369
|
+
# Normalize an ArchGraph SKILL.md for the Doubao (desktop agent mode) skill
|
|
370
|
+
# system. Doubao follows the Anthropic Agent Skills spec: the YAML
|
|
371
|
+
# frontmatter may contain ONLY `name` and `description` (see the built-in
|
|
372
|
+
# skill-creator-for-work skill); any other field is rejected. The ArchGraph
|
|
373
|
+
# skills additionally carry VS Code / OpenCode-only fields (argument-hint,
|
|
374
|
+
# disable-model-invocation), so strip the frontmatter down to name +
|
|
375
|
+
# description while keeping the body verbatim and the values byte-intact.
|
|
376
|
+
param(
|
|
377
|
+
[string]$SourceFile,
|
|
378
|
+
[string]$DestinationFile
|
|
379
|
+
)
|
|
380
|
+
$content = Get-Content $SourceFile -Raw -Encoding UTF8
|
|
381
|
+
$m = [regex]::Match($content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
382
|
+
if (-not $m.Success) {
|
|
383
|
+
Copy-Item -Force -Path $SourceFile -Destination $DestinationFile
|
|
384
|
+
return
|
|
385
|
+
}
|
|
386
|
+
$front = $m.Groups[1].Value
|
|
387
|
+
$body = $m.Groups[2].Value
|
|
388
|
+
|
|
389
|
+
$name = ''
|
|
390
|
+
$desc = ''
|
|
391
|
+
$nm = [regex]::Match($front, '(?m)^name:\s*(.*)$')
|
|
392
|
+
if ($nm.Success) { $name = $nm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
393
|
+
# Keep the description value verbatim (including any surrounding quotes) so
|
|
394
|
+
# non-ASCII and internal punctuation survive the round-trip byte-for-byte.
|
|
395
|
+
$dm = [regex]::Match($front, '(?m)^description:\s*(.*)$')
|
|
396
|
+
if ($dm.Success) { $desc = $dm.Groups[1].Value.Trim() }
|
|
397
|
+
|
|
398
|
+
$newFront = "---`r`n"
|
|
399
|
+
if ($name) { $newFront += "name: $name`r`n" }
|
|
400
|
+
if ($desc) { $newFront += "description: $desc`r`n" }
|
|
401
|
+
$newFront += "---`r`n"
|
|
402
|
+
|
|
403
|
+
$result = $newFront + "`r`n" + $body
|
|
404
|
+
[System.IO.File]::WriteAllText($DestinationFile, $result, (New-Object System.Text.UTF8Encoding $false))
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function Copy-DoubaoSkills {
|
|
408
|
+
# Deploy the ArchGraph skills into a Doubao skill root. Doubao adopts the
|
|
409
|
+
# Anthropic Agent Skills layout: one folder per skill containing SKILL.md
|
|
410
|
+
# (plus optional scripts/references/assets). The metadata (name +
|
|
411
|
+
# description) is always in context; the body loads only when the skill
|
|
412
|
+
# triggers. SKILL.md is normalized via Convert-SkillFile; any bundled
|
|
413
|
+
# resources are copied verbatim so the skill folder is self-contained.
|
|
414
|
+
param(
|
|
415
|
+
[string]$Root,
|
|
416
|
+
[string]$SourceSkillsRoot,
|
|
417
|
+
[string[]]$SkillNames,
|
|
418
|
+
[string]$Label
|
|
419
|
+
)
|
|
420
|
+
foreach ($skill in $SkillNames) {
|
|
421
|
+
$src = Join-Path $SourceSkillsRoot $skill
|
|
422
|
+
if (-not (Test-Path (Join-Path $src 'SKILL.md'))) { continue }
|
|
423
|
+
$destDir = Join-Path $Root $skill
|
|
424
|
+
New-Item -ItemType Directory -Force -Path $destDir | Out-Null
|
|
425
|
+
Copy-Item -Recurse -Force -Path (Join-Path $src '*') -Destination $destDir
|
|
426
|
+
Convert-SkillFile -SourceFile (Join-Path $src 'SKILL.md') -DestinationFile (Join-Path $destDir 'SKILL.md')
|
|
427
|
+
}
|
|
428
|
+
Write-Host " argo skills -> $Root ($Label)"
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function Convert-RuleToSkill {
|
|
432
|
+
# Package the single-source ARGO rule file (argo/rules/archgraph.instructions.md)
|
|
433
|
+
# as a Doubao entry skill. Doubao keeps ONLY a skill's name + description in
|
|
434
|
+
# context permanently (the body loads when the skill triggers) and it
|
|
435
|
+
# forbids angle brackets in the description. So the frontmatter carries a
|
|
436
|
+
# mandatory trigger description (the STEP 0 gate + the "load before any
|
|
437
|
+
# intent-graph read/write" mandate) and the body is the rule text verbatim
|
|
438
|
+
# (frontmatter stripped). This is the closest Doubao allows to an always-on
|
|
439
|
+
# rule: Doubao has no system-prompt / AGENTS.md hook.
|
|
440
|
+
param(
|
|
441
|
+
[string]$RuleFile,
|
|
442
|
+
[string]$DestinationFile
|
|
443
|
+
)
|
|
444
|
+
$rule = Get-Content $RuleFile -Raw -Encoding UTF8
|
|
445
|
+
$body = Get-MarkdownBody -Content $rule
|
|
446
|
+
$description = 'MANDATORY entry skill for the ARGO / ArchGraph intent graph. Whenever the workspace is an ArchGraph workspace (contains design/KG/SystemArchitecture.json) or the argo MCP tools (mcp__argo__*) are available, you MUST load this skill BEFORE reading, querying or writing the architecture graph. STEP 0 gate: identify your Business Actor through the argo MCP and restore your working memory first, then follow this skill for KG-first retrieval, the ARGO red lines, acceptance-test-first work, deduplicated and lossless graph writes, and commit tracing.'
|
|
447
|
+
$front = "---`r`nname: archgraph-argo`r`ndescription: `"$description`"`r`n---`r`n"
|
|
448
|
+
[System.IO.File]::WriteAllText($DestinationFile, ($front + "`r`n" + $body), (New-Object System.Text.UTF8Encoding $false))
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function Write-DoubaoMcpRecipe {
|
|
452
|
+
# Doubao's desktop agent mode registers MCP servers through its in-app UI
|
|
453
|
+
# (自定义连接器: 传输类型 STDIO / 命令 / 参数 / 环境变量), NOT through a config
|
|
454
|
+
# file, so the installer cannot auto-register. This writes the exact
|
|
455
|
+
# connector values to a reference file and prints a copy-paste recipe.
|
|
456
|
+
#
|
|
457
|
+
# The argo server is a local stdio child with NO fixed workspace: Doubao's
|
|
458
|
+
# MCP client (rmcp) supports the MCP `roots` handshake and passes a
|
|
459
|
+
# `workingDirectory` when spawning a stdio connector, so argo follows the
|
|
460
|
+
# workspace the user selected in Doubao - exactly like the OpenCode (roots)
|
|
461
|
+
# and DeepSeek Harness (injected workspaceRoot) hosts. ARGO_REPO_ROOT is
|
|
462
|
+
# therefore NOT pinned; it remains available as an optional override.
|
|
463
|
+
# graph-mcp (remote Streamable HTTP) is exposed through the same stdio
|
|
464
|
+
# bridge the Cursor deployment uses.
|
|
465
|
+
param(
|
|
466
|
+
[string]$RecipePath,
|
|
467
|
+
[string]$ArgoServer,
|
|
468
|
+
[string]$BridgePath,
|
|
469
|
+
[string]$GraphMcpUrl
|
|
470
|
+
)
|
|
471
|
+
$argoServerSlash = ($ArgoServer -replace '\\', '/')
|
|
472
|
+
$connectors = @(
|
|
473
|
+
[ordered]@{
|
|
474
|
+
serverName = 'argo'
|
|
475
|
+
transport = 'STDIO'
|
|
476
|
+
command = 'node'
|
|
477
|
+
args = @($argoServerSlash)
|
|
478
|
+
}
|
|
479
|
+
)
|
|
480
|
+
if ($BridgePath) {
|
|
481
|
+
$connectors += [ordered]@{
|
|
482
|
+
serverName = 'graph-mcp'
|
|
483
|
+
transport = 'STDIO'
|
|
484
|
+
command = 'node'
|
|
485
|
+
args = @(($BridgePath -replace '\\', '/'))
|
|
486
|
+
env = [ordered]@{ GRAPH_MCP_URL = $GraphMcpUrl }
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
$recipe = [ordered]@{
|
|
490
|
+
host = 'Doubao desktop (agent mode) - custom connector (自定义连接器), manual in-app registration'
|
|
491
|
+
note = 'Open Doubao agent mode -> MCP/connector settings -> add a custom connector -> enter the values below (transport 传输类型 = STDIO). Requires Node.js on PATH. Doubao custom connectors run only on the local machine.'
|
|
492
|
+
workspace = 'The argo connector has no fixed workspace: it follows the workspace selected in Doubao (MCP roots / connector workingDirectory), the same way OpenCode (roots) and DeepSeek Harness (injected workspaceRoot) do. To pin a fixed workspace instead, add env ARGO_REPO_ROOT=<absolute project path>.'
|
|
493
|
+
connectors = $connectors
|
|
494
|
+
}
|
|
495
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $RecipePath) | Out-Null
|
|
496
|
+
[System.IO.File]::WriteAllText($RecipePath, ($recipe | ConvertTo-Json -Depth 8), (New-Object System.Text.UTF8Encoding $false))
|
|
497
|
+
Write-Host " Doubao MCP connector recipe -> $RecipePath"
|
|
498
|
+
Write-Host ' Register once in the Doubao app (自定义连接器, 传输类型 STDIO):'
|
|
499
|
+
Write-Host ' 服务器名称: argo'
|
|
500
|
+
Write-Host ' 命令: node'
|
|
501
|
+
Write-Host " 参数: $argoServerSlash"
|
|
502
|
+
Write-Host ' (workspace: follows the workspace selected in Doubao)'
|
|
503
|
+
if ($BridgePath) {
|
|
504
|
+
Write-Host ' 服务器名称: graph-mcp'
|
|
505
|
+
Write-Host ' 命令: node'
|
|
506
|
+
Write-Host " 参数: $($BridgePath -replace '\\', '/')"
|
|
507
|
+
Write-Host " 环境变量: GRAPH_MCP_URL=$GraphMcpUrl"
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
375
511
|
function Write-OpenClawMcpConfig {
|
|
376
512
|
# Register the argo MCP server under mcp.servers.argo in
|
|
377
513
|
# ~/.openclaw/openclaw.json. OpenClaw is a fixed-workspace host: its
|
|
@@ -491,200 +627,51 @@ function Write-DshManagedBlock {
|
|
|
491
627
|
}
|
|
492
628
|
|
|
493
629
|
function New-DshWakeupPlugin {
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
630
|
+
# Deploy the DSH wakeup-gate Cordis plugin under ~/.dsh/plugins by copying
|
|
631
|
+
# the single-source bundle artifact dsh-argo-wakeup/index.js (generated from
|
|
632
|
+
# the <WakeupGuideline> block of argo/rules/archgraph.instructions.md by
|
|
633
|
+
# scripts/gen-dsh-plugins.js). Copying - not regenerating a template here -
|
|
634
|
+
# keeps the deployed plugin and the shipped bundle byte-identical, so the
|
|
635
|
+
# gate text has exactly one source and cannot fork.
|
|
499
636
|
param(
|
|
500
|
-
[string]$DshHome
|
|
501
|
-
[string]$RuleText
|
|
637
|
+
[string]$DshHome
|
|
502
638
|
)
|
|
503
|
-
$
|
|
504
|
-
if (-not $
|
|
505
|
-
Write-Warning
|
|
639
|
+
$source = Join-Path (Join-Path $repoRoot 'dsh-argo-wakeup') 'index.js'
|
|
640
|
+
if (-not (Test-Path $source)) {
|
|
641
|
+
Write-Warning " $source not found; DSH wakeup plugin skipped."
|
|
506
642
|
return $null
|
|
507
643
|
}
|
|
508
644
|
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-wakeup'
|
|
509
645
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
510
|
-
$gateJson = $gate | ConvertTo-Json
|
|
511
|
-
$plugin = @"
|
|
512
|
-
// dsh-argo-wakeup - generated by install-argo.ps1 from
|
|
513
|
-
// argo/rules/archgraph.instructions.md (single source of truth: the rule file;
|
|
514
|
-
// this file is a deployment artifact, do not edit by hand).
|
|
515
|
-
// DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
|
|
516
|
-
// registers the unconditional wakeup gate as the first system-prompt section
|
|
517
|
-
// after the harness identity, so every session identifies its Business Actor
|
|
518
|
-
// through the argo MCP server before responding.
|
|
519
|
-
export const name = 'dsh-argo-wakeup'
|
|
520
|
-
export const inject = ['systemPrompt']
|
|
521
|
-
const WAKEUP_GATE = $gateJson
|
|
522
|
-
export function apply(ctx) {
|
|
523
|
-
ctx.effect(() => ctx.systemPrompt.section({
|
|
524
|
-
name: 'argo:wakeup',
|
|
525
|
-
order: -90,
|
|
526
|
-
text: WAKEUP_GATE,
|
|
527
|
-
}), 'argo:wakeup.section()')
|
|
528
|
-
}
|
|
529
|
-
"@
|
|
530
646
|
$indexPath = Join-Path $dir 'index.js'
|
|
531
|
-
|
|
532
|
-
Write-Host " DSH wakeup plugin
|
|
647
|
+
Copy-Item -Force -Path $source -Destination $indexPath
|
|
648
|
+
Write-Host " DSH wakeup plugin <- $source (single source)"
|
|
533
649
|
return $indexPath
|
|
534
650
|
}
|
|
535
651
|
|
|
536
652
|
function New-DshWorkspaceBridge {
|
|
537
|
-
#
|
|
538
|
-
#
|
|
539
|
-
#
|
|
653
|
+
# Deploy the DSH workspace bridge plugin under ~/.dsh/plugins by copying the
|
|
654
|
+
# single-source bundle artifact dsh-argo-workspace/index.js. It connects
|
|
655
|
+
# directly to the argo MCP server (no dsh-mcp-client row needed) with a
|
|
656
|
+
# zero-dependency minimal MCP stdio client, registers every tool as
|
|
540
657
|
# mcp__argo__* and injects the current session's workspace directory
|
|
541
658
|
# (SessionHeader.cwd) as the per-call `workspaceRoot`, so ONE dsh instance
|
|
542
659
|
# follows whichever workspace the user switched to - no model-visible
|
|
543
|
-
# parameters, no internal tool names, no restart.
|
|
544
|
-
# the
|
|
660
|
+
# parameters, no internal tool names, no restart. Copying (not embedding a
|
|
661
|
+
# template) keeps the deployed plugin and the shipped bundle identical.
|
|
545
662
|
param(
|
|
546
663
|
[string]$DshHome
|
|
547
664
|
)
|
|
665
|
+
$source = Join-Path (Join-Path $repoRoot 'dsh-argo-workspace') 'index.js'
|
|
666
|
+
if (-not (Test-Path $source)) {
|
|
667
|
+
Write-Warning " $source not found; DSH workspace bridge skipped."
|
|
668
|
+
return $null
|
|
669
|
+
}
|
|
548
670
|
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-workspace'
|
|
549
671
|
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
550
|
-
$plugin = @'
|
|
551
|
-
// dsh-argo-workspace - generated by install-argo.ps1 (single source of truth:
|
|
552
|
-
// the installer; this file is a deployment artifact, do not edit by hand).
|
|
553
|
-
//
|
|
554
|
-
// Direct MCP bridge to the argo server for DeepSeek Harness. Registers every
|
|
555
|
-
// argo tool as mcp__argo__* and injects the current session's workspace
|
|
556
|
-
// directory (SessionHeader.cwd) as the per-call `workspaceRoot` argument, so
|
|
557
|
-
// one dsh instance follows whichever workspace the user switched to - the
|
|
558
|
-
// model sees no extra parameters and no internal tool names. The argo server
|
|
559
|
-
// honors the injected workspaceRoot unconditionally.
|
|
560
|
-
//
|
|
561
|
-
// Zero dependencies on purpose: implements the minimal MCP stdio client
|
|
562
|
-
// (JSON-RPC 2.0, one JSON object per line) with Node built-ins only, so the
|
|
563
|
-
// plugin runs from any DSH layout without resolving @modelcontextprotocol/sdk.
|
|
564
|
-
import { spawn } from 'node:child_process'
|
|
565
|
-
import readline from 'node:readline'
|
|
566
|
-
|
|
567
|
-
export const name = 'dsh-argo-workspace'
|
|
568
|
-
export const inject = ['tools']
|
|
569
|
-
|
|
570
|
-
/** Minimal MCP stdio client over the argo server process. */
|
|
571
|
-
function createArgoClient(serverPath, env, cwd) {
|
|
572
|
-
const child = spawn('node', [serverPath], {
|
|
573
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
574
|
-
env,
|
|
575
|
-
...(cwd ? { cwd } : {}),
|
|
576
|
-
})
|
|
577
|
-
const pending = new Map()
|
|
578
|
-
let nextId = 1
|
|
579
|
-
readline.createInterface({ input: child.stdout }).on('line', (line) => {
|
|
580
|
-
let message
|
|
581
|
-
try { message = JSON.parse(line) } catch { return }
|
|
582
|
-
if (message && typeof message.id === 'number' && pending.has(message.id)) {
|
|
583
|
-
const { resolve, reject } = pending.get(message.id)
|
|
584
|
-
pending.delete(message.id)
|
|
585
|
-
if (message.error) reject(new Error(JSON.stringify(message.error)))
|
|
586
|
-
else resolve(message.result)
|
|
587
|
-
}
|
|
588
|
-
})
|
|
589
|
-
child.stderr.on('data', () => {}) // drain; the argo server logs to stderr
|
|
590
|
-
const request = (method, params) => new Promise((resolve, reject) => {
|
|
591
|
-
const id = nextId++
|
|
592
|
-
pending.set(id, { resolve, reject })
|
|
593
|
-
child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n')
|
|
594
|
-
})
|
|
595
|
-
return {
|
|
596
|
-
request,
|
|
597
|
-
notify: (method, params) => {
|
|
598
|
-
child.stdin.write(JSON.stringify({ jsonrpc: '2.0', method, params }) + '\n')
|
|
599
|
-
},
|
|
600
|
-
close: () => child.kill(),
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/** Connect, list tools, register them, and keep the client until disposal. */
|
|
605
|
-
export async function apply(ctx, config) {
|
|
606
|
-
const serverPath = config.serverPath
|
|
607
|
-
const workspaces = Array.isArray(config.workspaces) ? config.workspaces : []
|
|
608
|
-
const env = { ...process.env }
|
|
609
|
-
if (workspaces.length > 0) env.ARGO_WORKSPACE_ROOTS = workspaces.join(';')
|
|
610
|
-
const client = createArgoClient(serverPath, env, config.cwd)
|
|
611
|
-
ctx.effect(() => () => client.close(), 'dsh-argo-workspace.dispose()')
|
|
612
|
-
|
|
613
|
-
let tools = []
|
|
614
|
-
try {
|
|
615
|
-
await client.request('initialize', {
|
|
616
|
-
protocolVersion: '2024-11-05',
|
|
617
|
-
capabilities: {},
|
|
618
|
-
clientInfo: { name: 'dsh-argo-workspace', version: '0.1.0' },
|
|
619
|
-
})
|
|
620
|
-
client.notify('notifications/initialized', {})
|
|
621
|
-
const listed = await client.request('tools/list', {})
|
|
622
|
-
tools = (listed && Array.isArray(listed.tools)) ? listed.tools : []
|
|
623
|
-
} catch (error) {
|
|
624
|
-
console.warn(`[dsh-argo-workspace] failed to connect to the argo MCP server (${serverPath}): ${error && error.message ? error.message : error}`)
|
|
625
|
-
return
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
const disposers = []
|
|
629
|
-
for (const tool of tools) {
|
|
630
|
-
const publicName = 'mcp__argo__' + tool.name
|
|
631
|
-
disposers.push(ctx.tools.register({
|
|
632
|
-
name: publicName,
|
|
633
|
-
description: tool.description ?? '',
|
|
634
|
-
parameters: tool.inputSchema,
|
|
635
|
-
output: {
|
|
636
|
-
schema: {
|
|
637
|
-
type: 'object',
|
|
638
|
-
properties: {
|
|
639
|
-
content: { type: 'array', items: {} },
|
|
640
|
-
structuredContent: {},
|
|
641
|
-
},
|
|
642
|
-
required: ['content'],
|
|
643
|
-
additionalProperties: false,
|
|
644
|
-
},
|
|
645
|
-
render: (_args, value) => value.content,
|
|
646
|
-
},
|
|
647
|
-
execute: async (args, exec) => {
|
|
648
|
-
// SessionHeader.cwd (the durable session workspace), NOT
|
|
649
|
-
// requestHeader() — that returns the request EpochHeader
|
|
650
|
-
// (config/system/tools) which has no cwd field.
|
|
651
|
-
const sessionCwd = exec && exec.agent && exec.agent.session
|
|
652
|
-
? exec.agent.session.header?.cwd
|
|
653
|
-
: undefined
|
|
654
|
-
const injected = { ...(args && typeof args === 'object' ? args : {}) }
|
|
655
|
-
if (typeof sessionCwd === 'string' && sessionCwd !== '') {
|
|
656
|
-
injected.workspaceRoot = sessionCwd
|
|
657
|
-
}
|
|
658
|
-
if (exec && exec.signal && exec.signal.aborted) {
|
|
659
|
-
throw new Error('aborted')
|
|
660
|
-
}
|
|
661
|
-
const result = await client.request('tools/call', {
|
|
662
|
-
name: tool.name,
|
|
663
|
-
arguments: injected,
|
|
664
|
-
})
|
|
665
|
-
const text = Array.isArray(result.content)
|
|
666
|
-
? result.content
|
|
667
|
-
.map((block) => block && block.type === 'text' && typeof block.text === 'string'
|
|
668
|
-
? block.text
|
|
669
|
-
: JSON.stringify(block))
|
|
670
|
-
.join('\n')
|
|
671
|
-
: (result.toolResult !== undefined ? JSON.stringify(result.toolResult) : '(no output)')
|
|
672
|
-
if (result.isError === true) throw new Error(text)
|
|
673
|
-
return {
|
|
674
|
-
content: [{ type: 'text', text }],
|
|
675
|
-
...(result.structuredContent !== undefined ? { structuredContent: result.structuredContent } : {}),
|
|
676
|
-
}
|
|
677
|
-
},
|
|
678
|
-
}))
|
|
679
|
-
}
|
|
680
|
-
ctx.effect(() => () => {
|
|
681
|
-
for (const dispose of disposers) dispose()
|
|
682
|
-
}, 'dsh-argo-workspace.tools')
|
|
683
|
-
}
|
|
684
|
-
'@
|
|
685
672
|
$indexPath = Join-Path $dir 'index.js'
|
|
686
|
-
|
|
687
|
-
Write-Host " DSH workspace bridge
|
|
673
|
+
Copy-Item -Force -Path $source -Destination $indexPath
|
|
674
|
+
Write-Host " DSH workspace bridge <- $source (single source)"
|
|
688
675
|
return $indexPath
|
|
689
676
|
}
|
|
690
677
|
|
|
@@ -867,8 +854,8 @@ if ($SkipDsh) {
|
|
|
867
854
|
Write-Host ' argo\skills\agent-search-diagnosis -> $DshHome\skills\agent-search-diagnosis (DeepSeek Harness skill)'
|
|
868
855
|
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path (Join-Path $DshHome 'skills') 'agent-search-diagnosis')
|
|
869
856
|
|
|
870
|
-
Write-Host "[17/22] argo\rules
|
|
871
|
-
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome
|
|
857
|
+
Write-Host "[17/22] dsh-argo-wakeup\index.js (single source; gate from argo\rules\archgraph.instructions.md <WakeupGuideline>) -> $DshHome\plugins\dsh-argo-wakeup\index.js (DeepSeek Harness wakeup plugin)"
|
|
858
|
+
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome
|
|
872
859
|
|
|
873
860
|
Write-Host "[18/22] argo-workspace + argo-wakeup rows -> $patchPath (DeepSeek Harness MCP bridge + wakeup plugin)"
|
|
874
861
|
# The generated dsh-argo-workspace bridge connects directly to the argo
|
|
@@ -937,6 +924,48 @@ Copy-Tree -Source $diagSkillSrc -Destination (Join-Path (Join-Path $OpenClawHome
|
|
|
937
924
|
Write-Host ' the OpenClaw gateway (openclaw gateway restart) if it is already running.'
|
|
938
925
|
}
|
|
939
926
|
|
|
927
|
+
if ($SkipDoubao) {
|
|
928
|
+
Write-Host 'Skipped Doubao integration (-SkipDoubao).'
|
|
929
|
+
} else {
|
|
930
|
+
# Doubao (desktop agent mode) skill discovery. Doubao adopts the Anthropic
|
|
931
|
+
# Agent Skills spec and loads user skills from
|
|
932
|
+
# <workspace>/.user_skills/<name>/SKILL.md (per-session workspace root)
|
|
933
|
+
# plus a global user root
|
|
934
|
+
# ~/Doubao/skills/<name>/SKILL.md
|
|
935
|
+
# Doubao exposes no AGENTS.md-equivalent always-on instruction file, so the
|
|
936
|
+
# WakeupGuideline / unconditional startup gate has no hook (skills are the
|
|
937
|
+
# fully ported surface). MCP servers are registered through Doubao's in-app
|
|
938
|
+
# custom connector UI (STDIO), not a config file, so the installer emits a
|
|
939
|
+
# copy-paste connector recipe instead of writing a config.
|
|
940
|
+
$doubaoSkills = @('argo-init', 'ea-human-reconcile', 'agent-search-diagnosis')
|
|
941
|
+
$doubaoSkillsSrc = Join-Path $argoDir 'skills'
|
|
942
|
+
Write-Host '==> Deploying Doubao (desktop agent mode) integration'
|
|
943
|
+
Copy-DoubaoSkills -Root (Join-Path $DoubaoWorkspace '.user_skills') -SourceSkillsRoot $doubaoSkillsSrc -SkillNames $doubaoSkills -Label 'workspace .user_skills'
|
|
944
|
+
Copy-DoubaoSkills -Root (Join-Path $DoubaoHome 'skills') -SourceSkillsRoot $doubaoSkillsSrc -SkillNames $doubaoSkills -Label 'global ~/Doubao/skills'
|
|
945
|
+
# Entry skill: the single-source ARGO rules packaged as a Doubao skill whose
|
|
946
|
+
# always-in-context description states the STEP 0 gate and the mandate to
|
|
947
|
+
# load it before any intent-graph read/write. This is the closest Doubao
|
|
948
|
+
# allows to an always-on rule (skills have no system-prompt hook).
|
|
949
|
+
$doubaoRule = Join-Path $argoDir 'rules\archgraph.instructions.md'
|
|
950
|
+
foreach ($doubaoRoot in @((Join-Path $DoubaoWorkspace '.user_skills'), (Join-Path $DoubaoHome 'skills'))) {
|
|
951
|
+
$entryDir = Join-Path $doubaoRoot 'archgraph-argo'
|
|
952
|
+
New-Item -ItemType Directory -Force -Path $entryDir | Out-Null
|
|
953
|
+
Convert-RuleToSkill -RuleFile $doubaoRule -DestinationFile (Join-Path $entryDir 'SKILL.md')
|
|
954
|
+
Write-Host " entry skill (ARGO rules) -> $(Join-Path $entryDir 'SKILL.md')"
|
|
955
|
+
}
|
|
956
|
+
Write-Host ' Doubao injects each skill''s name + description into context and loads the'
|
|
957
|
+
Write-Host ' body on trigger; new skills are picked up on the next agent session.'
|
|
958
|
+
$doubaoBridgeDir = Join-Path $ArgoRoot 'mcp-bridges'
|
|
959
|
+
Copy-Tree -Source (Join-Path $argoDir 'mcp-bridges') -Destination $doubaoBridgeDir
|
|
960
|
+
$doubaoBridgePath = Join-Path $doubaoBridgeDir 'graph-mcp-stdio.js'
|
|
961
|
+
if (-not (Test-Path $doubaoBridgePath)) { $doubaoBridgePath = '' }
|
|
962
|
+
Write-DoubaoMcpRecipe -RecipePath (Join-Path $ArgoRoot 'doubao-mcp.json') -ArgoServer (Join-Path $ArgoRoot 'scripts\argo-mcp-server.js') -BridgePath $doubaoBridgePath -GraphMcpUrl $GraphMcpUrl
|
|
963
|
+
Write-Host ' the argo connector has no fixed workspace: it follows the workspace you'
|
|
964
|
+
Write-Host ' select in Doubao (MCP roots / connector workingDirectory), like OpenCode/DSH.'
|
|
965
|
+
Write-Host ' note: Doubao has no AGENTS.md-equivalent always-on rule file, so the ARGO'
|
|
966
|
+
Write-Host ' WakeupGuideline / unconditional startup gate is not deployed (no hook).'
|
|
967
|
+
}
|
|
968
|
+
|
|
940
969
|
if ($SkipDeps) {
|
|
941
970
|
Write-Host 'Skipped dependency install (-SkipDeps).'
|
|
942
971
|
} elseif (Get-Command npm -ErrorAction SilentlyContinue) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "archgraph-argo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -45,7 +45,10 @@
|
|
|
45
45
|
"playwright": "1.61.1"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
|
-
"test": "node --test \"tests/*.test.js\""
|
|
48
|
+
"test": "node --test \"tests/*.test.js\"",
|
|
49
|
+
"acceptance": "node scripts/mcp-acceptance.js",
|
|
50
|
+
"gen:dsh-plugins": "node scripts/gen-dsh-plugins.js",
|
|
51
|
+
"prepack": "node scripts/gen-dsh-plugins.js"
|
|
49
52
|
},
|
|
50
53
|
"engines": {
|
|
51
54
|
"node": ">=18"
|