archgraph-argo 0.26.2 → 0.28.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 +127 -57
- package/argo/.env.example +181 -163
- package/argo/plugins/argo-wakeup.js +29 -27
- package/argo/rules/archgraph.instructions.md +189 -187
- package/argo/schema/schema-bundle.config.json +22 -0
- package/argo/schema/schema-bundle.rules.json +12229 -0
- package/argo/scripts/agentSearchDiagnose.js +410 -407
- package/argo/scripts/argo-mcp-server.js +122 -9
- 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 +9 -61
- package/argo/scripts/graph-semantics.js +363 -227
- package/argo/scripts/runArchitectureTests.js +591 -583
- package/argo/scripts/schema-bundle.js +932 -0
- package/argo/scripts/systemarchitecture-mcp-server.js +758 -110
- package/argo/scripts/validateSystemArchitecture.js +262 -253
- package/argo/scripts/validator-mcp-server.js +1 -1
- package/argo/scripts/workspace-write-guard.js +144 -0
- package/argo/skills/argo-init/SKILL.md +7 -9
- package/argo/skills/ea-human-reconcile/SKILL.md +40 -39
- package/cordis.patch.yml +15 -6
- package/dsh-argo-wakeup/index.js +17 -17
- package/dsh-argo-workspace/index.js +227 -141
- package/install-argo.ps1 +336 -206
- package/package.json +57 -53
package/install-argo.ps1
CHANGED
|
@@ -25,6 +25,12 @@ 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,
|
|
31
|
+
[string]$CodexHome = "$env:USERPROFILE\.codex",
|
|
32
|
+
[string]$CodexRepoRoot = '',
|
|
33
|
+
[switch]$SkipCodex,
|
|
28
34
|
[string]$McpPath,
|
|
29
35
|
[string]$GraphMcpUrl = 'https://argo.derekworkspacev5.com/mcp'
|
|
30
36
|
)
|
|
@@ -298,16 +304,6 @@ function Get-MarkdownBody {
|
|
|
298
304
|
return $m.Groups[2].Value
|
|
299
305
|
}
|
|
300
306
|
|
|
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
307
|
function Write-ArchGraphRuleBlock {
|
|
312
308
|
# Merge the frontmatter-stripped ArchGraph rule into a target AGENTS.md
|
|
313
309
|
# file (DSH home or OpenClaw workspace), replacing the previous ArchGraph
|
|
@@ -372,6 +368,149 @@ function Write-OpenClawAgentRule {
|
|
|
372
368
|
Write-ArchGraphRuleBlock -DestPath (Join-Path $OpenClawWorkspace 'AGENTS.md') -RuleText $RuleText -Label 'OpenClaw rule'
|
|
373
369
|
}
|
|
374
370
|
|
|
371
|
+
function Convert-SkillFile {
|
|
372
|
+
# Normalize an ArchGraph SKILL.md for the Doubao (desktop agent mode) skill
|
|
373
|
+
# system. Doubao follows the Anthropic Agent Skills spec: the YAML
|
|
374
|
+
# frontmatter may contain ONLY `name` and `description` (see the built-in
|
|
375
|
+
# skill-creator-for-work skill); any other field is rejected. The ArchGraph
|
|
376
|
+
# skills additionally carry VS Code / OpenCode-only fields (argument-hint,
|
|
377
|
+
# disable-model-invocation), so strip the frontmatter down to name +
|
|
378
|
+
# description while keeping the body verbatim and the values byte-intact.
|
|
379
|
+
param(
|
|
380
|
+
[string]$SourceFile,
|
|
381
|
+
[string]$DestinationFile
|
|
382
|
+
)
|
|
383
|
+
$content = Get-Content $SourceFile -Raw -Encoding UTF8
|
|
384
|
+
$m = [regex]::Match($content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
385
|
+
if (-not $m.Success) {
|
|
386
|
+
Copy-Item -Force -Path $SourceFile -Destination $DestinationFile
|
|
387
|
+
return
|
|
388
|
+
}
|
|
389
|
+
$front = $m.Groups[1].Value
|
|
390
|
+
$body = $m.Groups[2].Value
|
|
391
|
+
|
|
392
|
+
$name = ''
|
|
393
|
+
$desc = ''
|
|
394
|
+
$nm = [regex]::Match($front, '(?m)^name:\s*(.*)$')
|
|
395
|
+
if ($nm.Success) { $name = $nm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
396
|
+
# Keep the description value verbatim (including any surrounding quotes) so
|
|
397
|
+
# non-ASCII and internal punctuation survive the round-trip byte-for-byte.
|
|
398
|
+
$dm = [regex]::Match($front, '(?m)^description:\s*(.*)$')
|
|
399
|
+
if ($dm.Success) { $desc = $dm.Groups[1].Value.Trim() }
|
|
400
|
+
|
|
401
|
+
$newFront = "---`r`n"
|
|
402
|
+
if ($name) { $newFront += "name: $name`r`n" }
|
|
403
|
+
if ($desc) { $newFront += "description: $desc`r`n" }
|
|
404
|
+
$newFront += "---`r`n"
|
|
405
|
+
|
|
406
|
+
$result = $newFront + "`r`n" + $body
|
|
407
|
+
[System.IO.File]::WriteAllText($DestinationFile, $result, (New-Object System.Text.UTF8Encoding $false))
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function Copy-DoubaoSkills {
|
|
411
|
+
# Deploy the ArchGraph skills into a Doubao skill root. Doubao adopts the
|
|
412
|
+
# Anthropic Agent Skills layout: one folder per skill containing SKILL.md
|
|
413
|
+
# (plus optional scripts/references/assets). The metadata (name +
|
|
414
|
+
# description) is always in context; the body loads only when the skill
|
|
415
|
+
# triggers. SKILL.md is normalized via Convert-SkillFile; any bundled
|
|
416
|
+
# resources are copied verbatim so the skill folder is self-contained.
|
|
417
|
+
param(
|
|
418
|
+
[string]$Root,
|
|
419
|
+
[string]$SourceSkillsRoot,
|
|
420
|
+
[string[]]$SkillNames,
|
|
421
|
+
[string]$Label
|
|
422
|
+
)
|
|
423
|
+
foreach ($skill in $SkillNames) {
|
|
424
|
+
$src = Join-Path $SourceSkillsRoot $skill
|
|
425
|
+
if (-not (Test-Path (Join-Path $src 'SKILL.md'))) { continue }
|
|
426
|
+
$destDir = Join-Path $Root $skill
|
|
427
|
+
New-Item -ItemType Directory -Force -Path $destDir | Out-Null
|
|
428
|
+
Copy-Item -Recurse -Force -Path (Join-Path $src '*') -Destination $destDir
|
|
429
|
+
Convert-SkillFile -SourceFile (Join-Path $src 'SKILL.md') -DestinationFile (Join-Path $destDir 'SKILL.md')
|
|
430
|
+
}
|
|
431
|
+
Write-Host " argo skills -> $Root ($Label)"
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function Convert-RuleToSkill {
|
|
435
|
+
# Package the single-source ARGO rule file (argo/rules/archgraph.instructions.md)
|
|
436
|
+
# as a Doubao entry skill. Doubao keeps ONLY a skill's name + description in
|
|
437
|
+
# context permanently (the body loads when the skill triggers) and it
|
|
438
|
+
# forbids angle brackets in the description. So the frontmatter carries a
|
|
439
|
+
# mandatory trigger description (the STEP 0 gate + the "load before any
|
|
440
|
+
# intent-graph read/write" mandate) and the body is the rule text verbatim
|
|
441
|
+
# (frontmatter stripped). This is the closest Doubao allows to an always-on
|
|
442
|
+
# rule: Doubao has no system-prompt / AGENTS.md hook.
|
|
443
|
+
param(
|
|
444
|
+
[string]$RuleFile,
|
|
445
|
+
[string]$DestinationFile
|
|
446
|
+
)
|
|
447
|
+
$rule = Get-Content $RuleFile -Raw -Encoding UTF8
|
|
448
|
+
$body = Get-MarkdownBody -Content $rule
|
|
449
|
+
$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.'
|
|
450
|
+
$front = "---`r`nname: archgraph-argo`r`ndescription: `"$description`"`r`n---`r`n"
|
|
451
|
+
[System.IO.File]::WriteAllText($DestinationFile, ($front + "`r`n" + $body), (New-Object System.Text.UTF8Encoding $false))
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function Write-DoubaoMcpRecipe {
|
|
455
|
+
# Doubao's desktop agent mode registers MCP servers through its in-app UI
|
|
456
|
+
# (自定义连接器: 传输类型 STDIO / 命令 / 参数 / 环境变量), NOT through a config
|
|
457
|
+
# file, so the installer cannot auto-register. This writes the exact
|
|
458
|
+
# connector values to a reference file and prints a copy-paste recipe.
|
|
459
|
+
#
|
|
460
|
+
# The argo server is a local stdio child with NO fixed workspace: Doubao's
|
|
461
|
+
# MCP client (rmcp) supports the MCP `roots` handshake and passes a
|
|
462
|
+
# `workingDirectory` when spawning a stdio connector, so argo follows the
|
|
463
|
+
# workspace the user selected in Doubao - exactly like the OpenCode (roots)
|
|
464
|
+
# and DeepSeek Harness (injected workspaceRoot) hosts. ARGO_REPO_ROOT is
|
|
465
|
+
# therefore NOT pinned; it remains available as an optional override.
|
|
466
|
+
# graph-mcp (remote Streamable HTTP) is exposed through the same stdio
|
|
467
|
+
# bridge the Cursor deployment uses.
|
|
468
|
+
param(
|
|
469
|
+
[string]$RecipePath,
|
|
470
|
+
[string]$ArgoServer,
|
|
471
|
+
[string]$BridgePath,
|
|
472
|
+
[string]$GraphMcpUrl
|
|
473
|
+
)
|
|
474
|
+
$argoServerSlash = ($ArgoServer -replace '\\', '/')
|
|
475
|
+
$connectors = @(
|
|
476
|
+
[ordered]@{
|
|
477
|
+
serverName = 'argo'
|
|
478
|
+
transport = 'STDIO'
|
|
479
|
+
command = 'node'
|
|
480
|
+
args = @($argoServerSlash)
|
|
481
|
+
}
|
|
482
|
+
)
|
|
483
|
+
if ($BridgePath) {
|
|
484
|
+
$connectors += [ordered]@{
|
|
485
|
+
serverName = 'graph-mcp'
|
|
486
|
+
transport = 'STDIO'
|
|
487
|
+
command = 'node'
|
|
488
|
+
args = @(($BridgePath -replace '\\', '/'))
|
|
489
|
+
env = [ordered]@{ GRAPH_MCP_URL = $GraphMcpUrl }
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
$recipe = [ordered]@{
|
|
493
|
+
host = 'Doubao desktop (agent mode) - custom connector (自定义连接器), manual in-app registration'
|
|
494
|
+
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.'
|
|
495
|
+
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>.'
|
|
496
|
+
connectors = $connectors
|
|
497
|
+
}
|
|
498
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $RecipePath) | Out-Null
|
|
499
|
+
[System.IO.File]::WriteAllText($RecipePath, ($recipe | ConvertTo-Json -Depth 8), (New-Object System.Text.UTF8Encoding $false))
|
|
500
|
+
Write-Host " Doubao MCP connector recipe -> $RecipePath"
|
|
501
|
+
Write-Host ' Register once in the Doubao app (自定义连接器, 传输类型 STDIO):'
|
|
502
|
+
Write-Host ' 服务器名称: argo'
|
|
503
|
+
Write-Host ' 命令: node'
|
|
504
|
+
Write-Host " 参数: $argoServerSlash"
|
|
505
|
+
Write-Host ' (workspace: follows the workspace selected in Doubao)'
|
|
506
|
+
if ($BridgePath) {
|
|
507
|
+
Write-Host ' 服务器名称: graph-mcp'
|
|
508
|
+
Write-Host ' 命令: node'
|
|
509
|
+
Write-Host " 参数: $($BridgePath -replace '\\', '/')"
|
|
510
|
+
Write-Host " 环境变量: GRAPH_MCP_URL=$GraphMcpUrl"
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
375
514
|
function Write-OpenClawMcpConfig {
|
|
376
515
|
# Register the argo MCP server under mcp.servers.argo in
|
|
377
516
|
# ~/.openclaw/openclaw.json. OpenClaw is a fixed-workspace host: its
|
|
@@ -460,6 +599,71 @@ function Write-OpenClawMcpConfig {
|
|
|
460
599
|
[System.IO.File]::WriteAllText($configPath, $json, (New-Object System.Text.UTF8Encoding $false))
|
|
461
600
|
}
|
|
462
601
|
|
|
602
|
+
function ConvertTo-TomlString {
|
|
603
|
+
# Encode a value as a TOML basic string (escape backslash + double quote).
|
|
604
|
+
param([string]$Value)
|
|
605
|
+
return '"' + ($Value -replace '\\', '\\\\' -replace '"', '\"') + '"'
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
function Write-CodexMcpConfig {
|
|
609
|
+
# Register the argo and graph-mcp MCP servers in the Codex config file
|
|
610
|
+
# (~/.codex/config.toml). Codex stores MCP servers as standard TOML tables
|
|
611
|
+
# [mcp_servers.<name>] (NOT the JSON/YAML shapes the other hosts use), so
|
|
612
|
+
# this is a text-level table upsert:
|
|
613
|
+
# - the previous managed tables ([mcp_servers.argo], [mcp_servers.argo.env],
|
|
614
|
+
# [mcp_servers.graph-mcp]) are removed first, so a re-deploy replaces
|
|
615
|
+
# rather than duplicates them (duplicate TOML tables are a parse error);
|
|
616
|
+
# - every unrelated config.toml key (the desktop app's own settings, other
|
|
617
|
+
# MCP servers, plugins, marketplaces) is preserved verbatim;
|
|
618
|
+
# - the file is written without a BOM.
|
|
619
|
+
#
|
|
620
|
+
# Workspace: Codex spawns every stdio MCP server with the SESSION workspace
|
|
621
|
+
# as its process cwd and without ARGO_* env (verified), and argo-paths.js
|
|
622
|
+
# falls back to process.cwd() when ARGO_REPO_ROOT is unset. So, like
|
|
623
|
+
# OpenCode / DeepSeek Harness, the single global argo server FOLLOWS whichever
|
|
624
|
+
# workspace the user opened in Codex and ARGO_REPO_ROOT is NOT pinned by
|
|
625
|
+
# default. Pass -RepoRoot to pin a fixed workspace instead (opt-in).
|
|
626
|
+
param(
|
|
627
|
+
[string]$ConfigPath,
|
|
628
|
+
[string]$ArgoServer,
|
|
629
|
+
[string]$GraphMcpUrl,
|
|
630
|
+
[string]$RepoRoot
|
|
631
|
+
)
|
|
632
|
+
$targetHeaders = @('[mcp_servers.argo]', '[mcp_servers.argo.env]', '[mcp_servers.graph-mcp]')
|
|
633
|
+
$existing = if (Test-Path $ConfigPath) { [System.IO.File]::ReadAllText($ConfigPath) } else { '' }
|
|
634
|
+
$lines = if ($existing -eq '') { @() } else { $existing -split "\r?\n" }
|
|
635
|
+
|
|
636
|
+
$kept = New-Object System.Collections.Generic.List[string]
|
|
637
|
+
$i = 0
|
|
638
|
+
while ($i -lt $lines.Count) {
|
|
639
|
+
$trim = $lines[$i].Trim()
|
|
640
|
+
if ($targetHeaders -contains $trim) {
|
|
641
|
+
# Skip the header and its body up to the next top-level table header.
|
|
642
|
+
$i++
|
|
643
|
+
while ($i -lt $lines.Count -and -not $lines[$i].TrimStart().StartsWith('[')) { $i++ }
|
|
644
|
+
continue
|
|
645
|
+
}
|
|
646
|
+
$kept.Add($lines[$i])
|
|
647
|
+
$i++
|
|
648
|
+
}
|
|
649
|
+
while ($kept.Count -gt 0 -and $kept[$kept.Count - 1].Trim() -eq '') { $kept.RemoveAt($kept.Count - 1) }
|
|
650
|
+
|
|
651
|
+
$blocks = New-Object System.Collections.Generic.List[string]
|
|
652
|
+
$blocks.Add((@('[mcp_servers.argo]', 'command = "node"', "args = [$(ConvertTo-TomlString $ArgoServer)]") -join "`n"))
|
|
653
|
+
if (-not [string]::IsNullOrWhiteSpace($RepoRoot)) {
|
|
654
|
+
$blocks.Add(("[mcp_servers.argo.env]`nARGO_REPO_ROOT = $(ConvertTo-TomlString $RepoRoot)"))
|
|
655
|
+
}
|
|
656
|
+
$blocks.Add(("[mcp_servers.graph-mcp]`nurl = $(ConvertTo-TomlString $GraphMcpUrl)"))
|
|
657
|
+
|
|
658
|
+
$result = ($kept -join "`n")
|
|
659
|
+
if ($result.Trim() -ne '') { $result = $result.TrimEnd() + "`n`n" }
|
|
660
|
+
$result += ($blocks -join "`n`n") + "`n"
|
|
661
|
+
|
|
662
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $ConfigPath) | Out-Null
|
|
663
|
+
[System.IO.File]::WriteAllText($ConfigPath, $result, (New-Object System.Text.UTF8Encoding $false))
|
|
664
|
+
Write-Host " Codex MCP: argo (stdio) + graph-mcp (streamable http) -> $ConfigPath"
|
|
665
|
+
}
|
|
666
|
+
|
|
463
667
|
function Write-DshManagedBlock {
|
|
464
668
|
# Text-level upsert of a marker-delimited block into a file (used for the
|
|
465
669
|
# managed rows in ~/.dsh/cordis.patch.yml): replaces the previous managed
|
|
@@ -491,200 +695,51 @@ function Write-DshManagedBlock {
|
|
|
491
695
|
}
|
|
492
696
|
|
|
493
697
|
function New-DshWakeupPlugin {
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
698
|
+
# Deploy the DSH wakeup-gate Cordis plugin under ~/.dsh/plugins by copying
|
|
699
|
+
# the single-source bundle artifact dsh-argo-wakeup/index.js (generated from
|
|
700
|
+
# the <WakeupGuideline> block of argo/rules/archgraph.instructions.md by
|
|
701
|
+
# scripts/gen-dsh-plugins.js). Copying - not regenerating a template here -
|
|
702
|
+
# keeps the deployed plugin and the shipped bundle byte-identical, so the
|
|
703
|
+
# gate text has exactly one source and cannot fork.
|
|
499
704
|
param(
|
|
500
|
-
[string]$DshHome
|
|
501
|
-
[string]$RuleText
|
|
705
|
+
[string]$DshHome
|
|
502
706
|
)
|
|
503
|
-
$
|
|
504
|
-
if (-not $
|
|
505
|
-
Write-Warning
|
|
707
|
+
$source = Join-Path (Join-Path $repoRoot 'dsh-argo-wakeup') 'index.js'
|
|
708
|
+
if (-not (Test-Path $source)) {
|
|
709
|
+
Write-Warning " $source not found; DSH wakeup plugin skipped."
|
|
506
710
|
return $null
|
|
507
711
|
}
|
|
508
712
|
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-wakeup'
|
|
509
713
|
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
714
|
$indexPath = Join-Path $dir 'index.js'
|
|
531
|
-
|
|
532
|
-
Write-Host " DSH wakeup plugin
|
|
715
|
+
Copy-Item -Force -Path $source -Destination $indexPath
|
|
716
|
+
Write-Host " DSH wakeup plugin <- $source (single source)"
|
|
533
717
|
return $indexPath
|
|
534
718
|
}
|
|
535
719
|
|
|
536
720
|
function New-DshWorkspaceBridge {
|
|
537
|
-
#
|
|
538
|
-
#
|
|
539
|
-
#
|
|
721
|
+
# Deploy the DSH workspace bridge plugin under ~/.dsh/plugins by copying the
|
|
722
|
+
# single-source bundle artifact dsh-argo-workspace/index.js. It connects
|
|
723
|
+
# directly to the argo MCP server (no dsh-mcp-client row needed) with a
|
|
724
|
+
# zero-dependency minimal MCP stdio client, registers every tool as
|
|
540
725
|
# mcp__argo__* and injects the current session's workspace directory
|
|
541
726
|
# (SessionHeader.cwd) as the per-call `workspaceRoot`, so ONE dsh instance
|
|
542
727
|
# follows whichever workspace the user switched to - no model-visible
|
|
543
|
-
# parameters, no internal tool names, no restart.
|
|
544
|
-
# the
|
|
728
|
+
# parameters, no internal tool names, no restart. Copying (not embedding a
|
|
729
|
+
# template) keeps the deployed plugin and the shipped bundle identical.
|
|
545
730
|
param(
|
|
546
731
|
[string]$DshHome
|
|
547
732
|
)
|
|
733
|
+
$source = Join-Path (Join-Path $repoRoot 'dsh-argo-workspace') 'index.js'
|
|
734
|
+
if (-not (Test-Path $source)) {
|
|
735
|
+
Write-Warning " $source not found; DSH workspace bridge skipped."
|
|
736
|
+
return $null
|
|
737
|
+
}
|
|
548
738
|
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-workspace'
|
|
549
739
|
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
740
|
$indexPath = Join-Path $dir 'index.js'
|
|
686
|
-
|
|
687
|
-
Write-Host " DSH workspace bridge
|
|
741
|
+
Copy-Item -Force -Path $source -Destination $indexPath
|
|
742
|
+
Write-Host " DSH workspace bridge <- $source (single source)"
|
|
688
743
|
return $indexPath
|
|
689
744
|
}
|
|
690
745
|
|
|
@@ -789,10 +844,9 @@ Write-Host "[4/22] argo\skills\argo-init -> $skillDest"
|
|
|
789
844
|
Copy-Tree -Source $skillSrc -Destination $skillDest
|
|
790
845
|
$reconcileSkillSrc = Join-Path (Join-Path $argoDir 'skills') 'ea-human-reconcile'
|
|
791
846
|
$diagSkillSrc = Join-Path (Join-Path $argoDir 'skills') 'agent-search-diagnosis'
|
|
792
|
-
Write-Host
|
|
847
|
+
Write-Host " argo\skills\ea-human-reconcile -> $SkillsRoot\ea-human-reconcile (EA human draft reconcile skill)"
|
|
793
848
|
Copy-Tree -Source $reconcileSkillSrc -Destination (Join-Path $SkillsRoot 'ea-human-reconcile')
|
|
794
|
-
|
|
795
|
-
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path $SkillsRoot 'agent-search-diagnosis')
|
|
849
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to Copilot.
|
|
796
850
|
|
|
797
851
|
$ruleSrc = Join-Path (Join-Path $argoDir 'rules') 'archgraph.instructions.md'
|
|
798
852
|
$ruleDest = Join-Path $PromptsRoot 'archgraph.instructions.md'
|
|
@@ -808,10 +862,9 @@ Copy-Item -Force -Path $depsSrc -Destination $depsDest
|
|
|
808
862
|
$cursorSkillDest = Join-Path $CursorSkillsRoot 'argo-init'
|
|
809
863
|
Write-Host "[7/22] argo\skills\argo-init -> $cursorSkillDest (Cursor)"
|
|
810
864
|
Copy-Tree -Source $skillSrc -Destination $cursorSkillDest
|
|
811
|
-
Write-Host
|
|
865
|
+
Write-Host " argo\skills\ea-human-reconcile -> $CursorSkillsRoot\ea-human-reconcile (Cursor)"
|
|
812
866
|
Copy-Tree -Source $reconcileSkillSrc -Destination (Join-Path $CursorSkillsRoot 'ea-human-reconcile')
|
|
813
|
-
|
|
814
|
-
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path $CursorSkillsRoot 'agent-search-diagnosis')
|
|
867
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to Cursor.
|
|
815
868
|
|
|
816
869
|
$mcpBridgeSrc = Join-Path $argoDir 'mcp-bridges'
|
|
817
870
|
$mcpBridgeDest = Join-Path $CursorMcpBridgesRoot ''
|
|
@@ -821,9 +874,9 @@ Copy-Tree -Source $mcpBridgeSrc -Destination $mcpBridgeDest
|
|
|
821
874
|
$openCodeSkillDest = Join-Path $OpenCodeSkillsRoot 'argo-init'
|
|
822
875
|
Write-Host "[8/22] argo\skills\argo-init -> $openCodeSkillDest (OpenCode)"
|
|
823
876
|
Copy-Tree -Source $skillSrc -Destination $openCodeSkillDest
|
|
824
|
-
Write-Host
|
|
877
|
+
Write-Host " argo\skills\ea-human-reconcile -> $OpenCodeSkillsRoot\ea-human-reconcile (OpenCode)"
|
|
825
878
|
Copy-Tree -Source $reconcileSkillSrc -Destination (Join-Path $OpenCodeSkillsRoot 'ea-human-reconcile')
|
|
826
|
-
Write-Host
|
|
879
|
+
Write-Host " argo\skills\agent-search-diagnosis -> $OpenCodeSkillsRoot\agent-search-diagnosis (OpenCode-only: assumes opencode session export)"
|
|
827
880
|
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path $OpenCodeSkillsRoot 'agent-search-diagnosis')
|
|
828
881
|
|
|
829
882
|
Write-Host "[9/22] argo\rules\archgraph.instructions.md -> $OpenCodeAgentsPath (OpenCode global AGENTS.md)"
|
|
@@ -862,15 +915,14 @@ if ($SkipDsh) {
|
|
|
862
915
|
|
|
863
916
|
Write-Host "[16/22] argo\skills\argo-init -> $dshSkillDest (DeepSeek Harness skill)"
|
|
864
917
|
Copy-Tree -Source (Join-Path $argoDir 'skills\argo-init') -Destination $dshSkillDest
|
|
865
|
-
Write-Host
|
|
918
|
+
Write-Host " argo\skills\ea-human-reconcile -> $DshHome\skills\ea-human-reconcile (DeepSeek Harness skill)"
|
|
866
919
|
Copy-Tree -Source (Join-Path $argoDir 'skills\ea-human-reconcile') -Destination (Join-Path (Join-Path $DshHome 'skills') 'ea-human-reconcile')
|
|
867
|
-
|
|
868
|
-
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path (Join-Path $DshHome 'skills') 'agent-search-diagnosis')
|
|
920
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to DeepSeek Harness.
|
|
869
921
|
|
|
870
|
-
Write-Host "[17/22] argo\rules
|
|
871
|
-
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome
|
|
922
|
+
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)"
|
|
923
|
+
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome
|
|
872
924
|
|
|
873
|
-
Write-Host "[18/22] argo-workspace + argo-wakeup rows -> $patchPath (DeepSeek Harness MCP
|
|
925
|
+
Write-Host "[18/22] argo-workspace (argo + graph-mcp) + argo-wakeup rows -> $patchPath (DeepSeek Harness MCP bridges + wakeup plugin)"
|
|
874
926
|
# The generated dsh-argo-workspace bridge connects directly to the argo
|
|
875
927
|
# server (no dsh-mcp-client row), registers every tool as mcp__argo__* and
|
|
876
928
|
# injects the current session's workspace (SessionHeader.cwd) as the
|
|
@@ -878,9 +930,20 @@ if ($SkipDsh) {
|
|
|
878
930
|
# user switched to. The server honors the injected workspaceRoot
|
|
879
931
|
# unconditionally.
|
|
880
932
|
$bridgeDshPath = New-DshWorkspaceBridge -DshHome $DshHome
|
|
933
|
+
# Deploy the federation Graph MCP stdio bridge next to the DSH plugins, so the
|
|
934
|
+
# remote graph-mcp (registry_*/mirror_*/graph_*) mounts as an ordinary local
|
|
935
|
+
# stdio server - the same bridge Cursor/Doubao already use.
|
|
936
|
+
$dshBridgeDir = Join-Path $DshHome 'mcp-bridges'
|
|
937
|
+
Copy-Tree -Source (Join-Path $argoDir 'mcp-bridges') -Destination $dshBridgeDir
|
|
938
|
+
$dshGraphBridgePath = (Join-Path $dshBridgeDir 'graph-mcp-stdio.js').Replace('\', '/')
|
|
881
939
|
if ($bridgeDshPath) {
|
|
882
940
|
$bridgeUrl = 'file:///' + (($bridgeDshPath -replace '\\', '/').TrimStart('/'))
|
|
883
|
-
|
|
941
|
+
# One bridge plugin mounts every server; the argo server follows the session
|
|
942
|
+
# workspace (workspaceRoot), graph-mcp does not inject workspaceRoot.
|
|
943
|
+
$serversYaml = " servers:`n"
|
|
944
|
+
$serversYaml += " - id: argo`n serverPath: '$argoServer'`n injectWorkspaceRoot: true`n"
|
|
945
|
+
$serversYaml += " - id: graph-mcp`n command: node`n args:`n - '$dshGraphBridgePath'`n env:`n GRAPH_MCP_URL: '$GraphMcpUrl'`n injectWorkspaceRoot: false`n"
|
|
946
|
+
$bridgeConfig = " config:`n" + $serversYaml
|
|
884
947
|
if ($DshWorkspaces) {
|
|
885
948
|
$wsList = @($DshWorkspaces.Replace('\', '/').Split(';') | ForEach-Object { " - $_" }) -join "`n"
|
|
886
949
|
$bridgeConfig += " workspaces:`n" + $wsList + "`n"
|
|
@@ -904,10 +967,8 @@ if ($SkipDsh) {
|
|
|
904
967
|
Write-Host "[19/22] argo\agents -> $DshHome\.agent-presets\<id> (DeepSeek Harness agent presets)"
|
|
905
968
|
New-DshAgentPresets -DshHome $DshHome -AgentsSrc (Join-Path $argoDir 'agents')
|
|
906
969
|
|
|
907
|
-
Write-Host "
|
|
908
|
-
Write-Host "
|
|
909
|
-
Write-Host " the local argo server); an HTTP remote MCP server has no equivalent cordis row here."
|
|
910
|
-
Write-Host " Restart `dsh web` to activate the MCP bridge and the wakeup plugin;"
|
|
970
|
+
Write-Host " graph-mcp registered for DeepSeek Harness as a stdio bridge -> $dshGraphBridgePath (GRAPH_MCP_URL=$GraphMcpUrl)"
|
|
971
|
+
Write-Host " Restart `dsh web` to activate the MCP bridges and the wakeup plugin;"
|
|
911
972
|
Write-Host ' new sessions pick up the global rule and the argo-init skill automatically.'
|
|
912
973
|
Write-Host ' The argo tools (mcp__argo__*) auto-follow the workspace the user switched to'
|
|
913
974
|
Write-Host ' in one dsh instance - no restart needed between workspaces (the server honors'
|
|
@@ -927,16 +988,58 @@ if ($SkipOpenClaw) {
|
|
|
927
988
|
|
|
928
989
|
Write-Host "[21/22] argo\skills\argo-init -> $openClawSkillDest (OpenClaw managed skill, all agents)"
|
|
929
990
|
Copy-Tree -Source (Join-Path $argoDir 'skills\argo-init') -Destination $openClawSkillDest
|
|
930
|
-
Write-Host
|
|
991
|
+
Write-Host " argo\skills\ea-human-reconcile -> $OpenClawHome\skills\ea-human-reconcile (OpenClaw managed skill, all agents)"
|
|
931
992
|
Copy-Tree -Source (Join-Path $argoDir 'skills\ea-human-reconcile') -Destination (Join-Path (Join-Path $OpenClawHome 'skills') 'ea-human-reconcile')
|
|
932
|
-
|
|
933
|
-
Copy-Tree -Source $diagSkillSrc -Destination (Join-Path (Join-Path $OpenClawHome 'skills') 'agent-search-diagnosis')
|
|
993
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to OpenClaw.
|
|
934
994
|
|
|
935
995
|
Write-Host ' OpenClaw injects AGENTS.md into Project Context on every session, so the wakeup'
|
|
936
996
|
Write-Host ' gate (UNCONDITIONAL STARTUP GATE) is active on the next OpenClaw session; restart'
|
|
937
997
|
Write-Host ' the OpenClaw gateway (openclaw gateway restart) if it is already running.'
|
|
938
998
|
}
|
|
939
999
|
|
|
1000
|
+
if ($SkipDoubao) {
|
|
1001
|
+
Write-Host 'Skipped Doubao integration (-SkipDoubao).'
|
|
1002
|
+
} else {
|
|
1003
|
+
# Doubao (desktop agent mode) skill discovery. Doubao adopts the Anthropic
|
|
1004
|
+
# Agent Skills spec and loads user skills from
|
|
1005
|
+
# <workspace>/.user_skills/<name>/SKILL.md (per-session workspace root)
|
|
1006
|
+
# plus a global user root
|
|
1007
|
+
# ~/Doubao/skills/<name>/SKILL.md
|
|
1008
|
+
# Doubao exposes no AGENTS.md-equivalent always-on instruction file, so the
|
|
1009
|
+
# WakeupGuideline / unconditional startup gate has no hook (skills are the
|
|
1010
|
+
# fully ported surface). MCP servers are registered through Doubao's in-app
|
|
1011
|
+
# custom connector UI (STDIO), not a config file, so the installer emits a
|
|
1012
|
+
# copy-paste connector recipe instead of writing a config.
|
|
1013
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to Doubao.
|
|
1014
|
+
$doubaoSkills = @('argo-init', 'ea-human-reconcile')
|
|
1015
|
+
$doubaoSkillsSrc = Join-Path $argoDir 'skills'
|
|
1016
|
+
Write-Host '==> Deploying Doubao (desktop agent mode) integration'
|
|
1017
|
+
Copy-DoubaoSkills -Root (Join-Path $DoubaoWorkspace '.user_skills') -SourceSkillsRoot $doubaoSkillsSrc -SkillNames $doubaoSkills -Label 'workspace .user_skills'
|
|
1018
|
+
Copy-DoubaoSkills -Root (Join-Path $DoubaoHome 'skills') -SourceSkillsRoot $doubaoSkillsSrc -SkillNames $doubaoSkills -Label 'global ~/Doubao/skills'
|
|
1019
|
+
# Entry skill: the single-source ARGO rules packaged as a Doubao skill whose
|
|
1020
|
+
# always-in-context description states the STEP 0 gate and the mandate to
|
|
1021
|
+
# load it before any intent-graph read/write. This is the closest Doubao
|
|
1022
|
+
# allows to an always-on rule (skills have no system-prompt hook).
|
|
1023
|
+
$doubaoRule = Join-Path $argoDir 'rules\archgraph.instructions.md'
|
|
1024
|
+
foreach ($doubaoRoot in @((Join-Path $DoubaoWorkspace '.user_skills'), (Join-Path $DoubaoHome 'skills'))) {
|
|
1025
|
+
$entryDir = Join-Path $doubaoRoot 'archgraph-argo'
|
|
1026
|
+
New-Item -ItemType Directory -Force -Path $entryDir | Out-Null
|
|
1027
|
+
Convert-RuleToSkill -RuleFile $doubaoRule -DestinationFile (Join-Path $entryDir 'SKILL.md')
|
|
1028
|
+
Write-Host " entry skill (ARGO rules) -> $(Join-Path $entryDir 'SKILL.md')"
|
|
1029
|
+
}
|
|
1030
|
+
Write-Host ' Doubao injects each skill''s name + description into context and loads the'
|
|
1031
|
+
Write-Host ' body on trigger; new skills are picked up on the next agent session.'
|
|
1032
|
+
$doubaoBridgeDir = Join-Path $ArgoRoot 'mcp-bridges'
|
|
1033
|
+
Copy-Tree -Source (Join-Path $argoDir 'mcp-bridges') -Destination $doubaoBridgeDir
|
|
1034
|
+
$doubaoBridgePath = Join-Path $doubaoBridgeDir 'graph-mcp-stdio.js'
|
|
1035
|
+
if (-not (Test-Path $doubaoBridgePath)) { $doubaoBridgePath = '' }
|
|
1036
|
+
Write-DoubaoMcpRecipe -RecipePath (Join-Path $ArgoRoot 'doubao-mcp.json') -ArgoServer (Join-Path $ArgoRoot 'scripts\argo-mcp-server.js') -BridgePath $doubaoBridgePath -GraphMcpUrl $GraphMcpUrl
|
|
1037
|
+
Write-Host ' the argo connector has no fixed workspace: it follows the workspace you'
|
|
1038
|
+
Write-Host ' select in Doubao (MCP roots / connector workingDirectory), like OpenCode/DSH.'
|
|
1039
|
+
Write-Host ' note: Doubao has no AGENTS.md-equivalent always-on rule file, so the ARGO'
|
|
1040
|
+
Write-Host ' WakeupGuideline / unconditional startup gate is not deployed (no hook).'
|
|
1041
|
+
}
|
|
1042
|
+
|
|
940
1043
|
if ($SkipDeps) {
|
|
941
1044
|
Write-Host 'Skipped dependency install (-SkipDeps).'
|
|
942
1045
|
} elseif (Get-Command npm -ErrorAction SilentlyContinue) {
|
|
@@ -1113,6 +1216,33 @@ if ($SkipMcp) {
|
|
|
1113
1216
|
}
|
|
1114
1217
|
}
|
|
1115
1218
|
|
|
1219
|
+
if ($SkipCodex) {
|
|
1220
|
+
Write-Host 'Skipped Codex integration (-SkipCodex).'
|
|
1221
|
+
} else {
|
|
1222
|
+
$ruleSrcContent = Get-Content $ruleSrc -Raw -Encoding UTF8
|
|
1223
|
+
$codexAgentsPath = Join-Path $CodexHome 'AGENTS.md'
|
|
1224
|
+
$codexSkillsRoot = Join-Path $CodexHome 'skills'
|
|
1225
|
+
|
|
1226
|
+
Write-Host '==> Deploying Codex integration'
|
|
1227
|
+
Write-Host "[Codex 1/3] argo\rules\archgraph.instructions.md -> $codexAgentsPath (Codex global AGENTS.md, frontmatter stripped)"
|
|
1228
|
+
Write-ArchGraphRuleBlock -DestPath $codexAgentsPath -RuleText $ruleSrcContent -Label 'Codex rule'
|
|
1229
|
+
|
|
1230
|
+
Write-Host "[Codex 2/3] argo\skills -> $codexSkillsRoot (Codex user skills: argo-init, ea-human-reconcile)"
|
|
1231
|
+
Copy-DoubaoSkills -Root $codexSkillsRoot -SourceSkillsRoot (Join-Path $argoDir 'skills') -SkillNames @('argo-init', 'ea-human-reconcile') -Label 'Codex user skills'
|
|
1232
|
+
# agent-search-diagnosis is OpenCode-only (it assumes `opencode` session export); not deployed to Codex.
|
|
1233
|
+
|
|
1234
|
+
if ($SkipMcp) {
|
|
1235
|
+
Write-Host ' Skipped Codex MCP registration (-SkipMcp).'
|
|
1236
|
+
} else {
|
|
1237
|
+
$codexConfigPath = Join-Path $CodexHome 'config.toml'
|
|
1238
|
+
Write-Host "[Codex 3/3] argo MCP (stdio) + graph-mcp -> $codexConfigPath (Codex config.toml)"
|
|
1239
|
+
Write-CodexMcpConfig -ConfigPath $codexConfigPath -ArgoServer $argoServer -GraphMcpUrl $GraphMcpUrl -RepoRoot $CodexRepoRoot
|
|
1240
|
+
}
|
|
1241
|
+
Write-Host ' Codex injects the global AGENTS.md into every session, so the wakeup gate is'
|
|
1242
|
+
Write-Host ' active on the next Codex session; skills load on trigger. Restart Codex so it'
|
|
1243
|
+
Write-Host ' picks up config.toml and the new skills.'
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1116
1246
|
$wakeupPluginPath = Join-Path $PluginsRoot 'argo-wakeup.js'
|
|
1117
1247
|
if (Test-Path $wakeupPluginPath) {
|
|
1118
1248
|
Write-Host '==> Registering argo-wakeup plugin in OpenCode'
|