archgraph-argo 0.9.2 → 0.9.4
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**, and **
|
|
29
|
+
Done — the ARGO toolchain, skills, and rules are deployed, and the `argo` MCP server is registered automatically in **GitHub Copilot**, **Cursor**, **OpenCode**, and **DeepSeek Harness** (dsh).
|
|
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.
|
|
@@ -28,5 +28,16 @@ argument-hint: "要发布的文章主题或源文档路径"
|
|
|
28
28
|
node "d:\Projects\_tools\wechat-cli-src\obsidian-wechat-public-platform-master\dist\wechat-public-cli.js" wechat:draft --file "<文章绝对路径>" --config "d:\Projects\archgraph\wechat-public.config.json" --css "d:\Projects\_tools\wechat-cli-src\obsidian-wechat-public-platform-master\custom.css"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## 文风要求(人味优先,去 AI 味)
|
|
32
|
+
|
|
33
|
+
发布公众号文章前,必须按以下要求降低「AI 味」、增加「人味」,否则读者不会看:
|
|
34
|
+
|
|
35
|
+
- 禁止 AI 套话与八股:删掉「首先/其次/最后」「综上所述」「总而言之」「值得注意的是」「赋能」「抓手」「闭环」「底层逻辑」等空洞词,去掉「本文将从以下 N 个方面展开」式开场。
|
|
36
|
+
- 去掉机械排比与对仗堆砌;段落要短,句子长短交错,像人说话,不像机器列清单。
|
|
37
|
+
- 多点人味:加入真实场景、具体例子、第一人称视角、设问、适度的口语与幽默;用具体数字和细节代替抽象概括。
|
|
38
|
+
- 开门见山直给观点与结论,少绕弯子;结尾给出可行动的判断,而非泛泛展望。
|
|
39
|
+
- 标题与摘要(digest)同样要有人味,避免口号式、震惊体式标题。
|
|
40
|
+
- 每篇至少通读一遍,找出并改写任何读起来像机器生成的句子。
|
|
41
|
+
|
|
31
42
|
## 输出格式
|
|
32
43
|
返回:文章路径、草稿 media_id(或确切失败原因)、状态(草稿已创建 / BLOCKED)。并提醒:API 发布不可用,需在公众号后台「草稿箱」手动发布。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Argo wakeup gate plugin for opencode.
|
|
2
|
+
//
|
|
3
|
+
// Injects an unconditional "wakeup gate" as the FIRST system instruction of
|
|
4
|
+
// every session, so the agent identifies its Business Actor and restores its
|
|
5
|
+
// long-term memory before responding to anything (including greetings and
|
|
6
|
+
// casual questions). The rule also lives in argo/rules/archgraph.instructions.md,
|
|
7
|
+
// but that file is long and can be skimmed; this hook guarantees a short,
|
|
8
|
+
// high-salience gate sits at the top of the system prompt on session start.
|
|
9
|
+
|
|
10
|
+
const WAKEUP_GATE = [
|
|
11
|
+
"WAKEUP GATE (unconditional; applies to the very first message of every session, including greetings, casual chat, and questions; never skip or defer).",
|
|
12
|
+
"1. Your very FIRST tool call must be an ARGO MCP query listing all Business Actors (getSystemArchitecture, purpose \"audit\", subject \"Business Actor\") to identify which Business Actor you are.",
|
|
13
|
+
"2. Restore that Actor's long-term memory (the SUBVIEW hierarchy mounted under it) before responding.",
|
|
14
|
+
"3. If the ARGO MCP is unavailable or errors, say so explicitly first. Only after this gate may you respond or act.",
|
|
15
|
+
].join("\n");
|
|
16
|
+
|
|
17
|
+
export default async function argoWakeupPlugin() {
|
|
18
|
+
return {
|
|
19
|
+
"experimental.chat.system.transform": async (_input, output) => {
|
|
20
|
+
const system = Array.isArray(output.system) ? output.system : [];
|
|
21
|
+
if (system.some((entry) => entry.includes("WAKEUP GATE"))) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
output.system = [WAKEUP_GATE, ...system];
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -4,6 +4,14 @@ name: "ArchGraph ARGO Workflow Rules"
|
|
|
4
4
|
applyTo: "**"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
<WakeupGuideline>
|
|
8
|
+
STEP 0 — UNCONDITIONAL STARTUP GATE. This applies to the very first message of every session, including greetings, casual chat, and questions; it may never be skipped, deferred, or treated as optional.
|
|
9
|
+
1. Your very FIRST tool call in the session MUST be an ARGO MCP query that lists all `Business Actor`s (getSystemArchitecture with purpose "audit" and subject "Business Actor"). Identify which `Business Actor` you are. If you are not sure, consult your human partner to confirm your role before doing anything else.
|
|
10
|
+
2. Restore your long-term memory: the SUBVIEW hierarchy mounted under that `Business Actor` element — the Views whose `parent_element_id` points to this Actor, plus the elements, relationships, and further nested sub-views inside them (NOT the View that merely includes the Actor in its `included_elements`) — and load it into session memory.
|
|
11
|
+
3. If the `agent` attribute of the confirmed Actor differs from your current Agent type, switch to that Agent type, or delegate to an Agent of that type per `<CoperationGuideline>` item 2.
|
|
12
|
+
4. If the ARGO MCP is unavailable or errors, state that explicitly to the user before doing anything else. Only after completing this gate may you respond to the user or take any other action.
|
|
13
|
+
</WakeupGuideline>
|
|
14
|
+
|
|
7
15
|
<CoreRules>
|
|
8
16
|
The following are non-negotiable red lines (MUST) for this Agent and must never be skipped at any time; details are expanded in the corresponding `<...>` sections.
|
|
9
17
|
1. Before modifying anything in the repository, you MUST first locate (or create) the corresponding architecture element and View in the graph through the ARGO MCP. See `<IntentArchitectureFirst>`.
|
|
@@ -20,11 +28,6 @@ Your cognitive architecture is composed of ArchiMate 3.2 elements and their exte
|
|
|
20
28
|
2. For the definitions of element or relationship types, see: ~/.argo/schema/archimate3.2.md
|
|
21
29
|
</Ontology>
|
|
22
30
|
|
|
23
|
-
<WakeupGuideline>
|
|
24
|
-
1. When you are started, first identify which `Business Actor` you are, then find your long-term memory — the SUBVIEW hierarchy mounted under that `Business Actor` element (the Views whose `parent_element_id` points to this Actor, plus the elements, relationships, and further nested sub-views inside them; NOT the View that merely includes the Actor in its `included_elements`) — and restore it into your session memory.
|
|
25
|
-
2. If you are not sure, query all existing `Business Actor`s, then consult your human partner to confirm your role. If the Agent type (the `agent` attribute) corresponding to the confirmed role differs from the current Agent type, switch to that Agent type, or delegate to an Agent of that type per `<CoperationGuideline>` item 2.
|
|
26
|
-
</WakeupGuideline>
|
|
27
|
-
|
|
28
31
|
<ExplorationGuideline>
|
|
29
32
|
1. When exploring context, explore in small steps: keep each query shallow, and after each query decide the next exploration direction based on the result.
|
|
30
33
|
2. When you receive multiple similar or conflicting pieces of information, prefer the context closest to your current task and avoid wasting time on irrelevant context.
|
package/install-argo.ps1
CHANGED
|
@@ -10,10 +10,14 @@ param(
|
|
|
10
10
|
[string]$OpenCodeConfigPath = "$env:USERPROFILE\.config\opencode\opencode.json",
|
|
11
11
|
[string]$CopilotAgentsRoot = "$env:USERPROFILE\.copilot\agents",
|
|
12
12
|
[string]$CursorAgentsRoot = "$env:USERPROFILE\.cursor\agents",
|
|
13
|
+
[string]$CursorRulesRoot = "$env:USERPROFILE\.cursor\rules",
|
|
13
14
|
[string]$OpenCodeAgentsRoot = "$env:USERPROFILE\.config\opencode\agents",
|
|
15
|
+
[string]$PluginsRoot = "$env:USERPROFILE\.argo\plugins",
|
|
14
16
|
[switch]$SkipEnv,
|
|
15
17
|
[switch]$SkipDeps,
|
|
16
18
|
[switch]$SkipMcp,
|
|
19
|
+
[switch]$SkipDsh,
|
|
20
|
+
[string]$DshHome = "$env:USERPROFILE\.dsh",
|
|
17
21
|
[string]$McpPath
|
|
18
22
|
)
|
|
19
23
|
|
|
@@ -93,6 +97,34 @@ function Convert-AgentFile {
|
|
|
93
97
|
[System.IO.File]::WriteAllText($DestinationFile, $result, (New-Object System.Text.UTF8Encoding $false))
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
function Convert-RuleFile {
|
|
101
|
+
param(
|
|
102
|
+
[string]$SourceFile,
|
|
103
|
+
[string]$DestinationFile
|
|
104
|
+
)
|
|
105
|
+
$content = Get-Content $SourceFile -Raw -Encoding UTF8
|
|
106
|
+
$m = [regex]::Match($content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
107
|
+
if (-not $m.Success) {
|
|
108
|
+
Copy-Item -Force -Path $SourceFile -Destination $DestinationFile
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
$front = $m.Groups[1].Value
|
|
112
|
+
$body = $m.Groups[2].Value
|
|
113
|
+
|
|
114
|
+
$desc = ''
|
|
115
|
+
$dm = [regex]::Match($front, '(?m)^description:\s*(.*)$')
|
|
116
|
+
if ($dm.Success) { $desc = $dm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
117
|
+
|
|
118
|
+
# Cursor .mdc rule: description + alwaysApply so it is injected into every
|
|
119
|
+
# request. The rule body (WakeupGuideline + CoreRules + ...) is kept verbatim.
|
|
120
|
+
$newFront = "---`r`n"
|
|
121
|
+
if ($desc) { $newFront += "description: `"$($desc -replace '"','\"')`"`r`n" }
|
|
122
|
+
$newFront += "alwaysApply: true`r`n---`r`n"
|
|
123
|
+
|
|
124
|
+
$result = $newFront + "`r`n" + $body
|
|
125
|
+
[System.IO.File]::WriteAllText($DestinationFile, $result, (New-Object System.Text.UTF8Encoding $false))
|
|
126
|
+
}
|
|
127
|
+
|
|
96
128
|
function Write-McpConfig {
|
|
97
129
|
param(
|
|
98
130
|
[string]$Path,
|
|
@@ -129,6 +161,39 @@ function Write-McpConfig {
|
|
|
129
161
|
[System.IO.File]::WriteAllText($Path, $json, (New-Object System.Text.UTF8Encoding $false))
|
|
130
162
|
}
|
|
131
163
|
|
|
164
|
+
function Register-OpenCodePlugin {
|
|
165
|
+
param(
|
|
166
|
+
[string]$ConfigPath,
|
|
167
|
+
[string]$PluginFilePath
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
$root = [ordered]@{}
|
|
171
|
+
if (Test-Path $ConfigPath) {
|
|
172
|
+
try {
|
|
173
|
+
$existing = Get-Content $ConfigPath -Raw | ConvertFrom-Json
|
|
174
|
+
foreach ($p in $existing.PSObject.Properties) {
|
|
175
|
+
$root[$p.Name] = $p.Value
|
|
176
|
+
}
|
|
177
|
+
} catch {
|
|
178
|
+
# Ignore an unparseable existing file and start fresh.
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
$url = 'file:///' + (($PluginFilePath -replace '\\', '/').TrimStart('/'))
|
|
183
|
+
$plugins = @()
|
|
184
|
+
if ($root.Contains('plugin') -and $null -ne $root['plugin']) {
|
|
185
|
+
$plugins = @($root['plugin'])
|
|
186
|
+
}
|
|
187
|
+
if ($plugins -notcontains $url) {
|
|
188
|
+
$plugins += $url
|
|
189
|
+
}
|
|
190
|
+
$root['plugin'] = $plugins
|
|
191
|
+
|
|
192
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $ConfigPath) | Out-Null
|
|
193
|
+
$json = $root | ConvertTo-Json -Depth 10
|
|
194
|
+
[System.IO.File]::WriteAllText($ConfigPath, $json, (New-Object System.Text.UTF8Encoding $false))
|
|
195
|
+
}
|
|
196
|
+
|
|
132
197
|
function Add-AgentsRule {
|
|
133
198
|
param(
|
|
134
199
|
[string]$AgentsPath,
|
|
@@ -172,60 +237,309 @@ function Add-AgentsRule {
|
|
|
172
237
|
}
|
|
173
238
|
}
|
|
174
239
|
|
|
240
|
+
# ---- DeepSeek Harness (dsh) conversion helpers ----
|
|
241
|
+
# The ArchGraph repository keeps ONE source file per artifact (rule / skill /
|
|
242
|
+
# mcp / plugin / agent). The targets below convert that single source into the
|
|
243
|
+
# DeepSeek Harness shape at deploy time, exactly like Convert-AgentFile and
|
|
244
|
+
# Convert-RuleFile do for Cursor / OpenCode.
|
|
245
|
+
|
|
246
|
+
function Get-MarkdownBody {
|
|
247
|
+
# Strip a leading YAML frontmatter block (--- ... ---) from markdown text.
|
|
248
|
+
# DeepSeek Harness injects AGENTS.md-style instruction files verbatim, so
|
|
249
|
+
# the frontmatter must not reach the model prompt.
|
|
250
|
+
param([string]$Content)
|
|
251
|
+
$m = [regex]::Match($Content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
252
|
+
if (-not $m.Success) { return $Content }
|
|
253
|
+
return $m.Groups[2].Value
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function Get-WakeupGuideline {
|
|
257
|
+
# Extract the <WakeupGuideline>...</WakeupGuideline> block from the rule
|
|
258
|
+
# text, so the DSH wakeup plugin is generated from the same source the
|
|
259
|
+
# Copilot / Cursor / OpenCode rules use.
|
|
260
|
+
param([string]$RuleText)
|
|
261
|
+
$m = [regex]::Match($RuleText, '(?s)<WakeupGuideline>(.*?)</WakeupGuideline>')
|
|
262
|
+
if (-not $m.Success) { return '' }
|
|
263
|
+
return $m.Groups[1].Value.Trim()
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function Write-DshAgentRule {
|
|
267
|
+
# Merge the frontmatter-stripped ArchGraph rule (plus a DSH adapter note
|
|
268
|
+
# explaining the mcp__argo__ tool prefix) into ~/.dsh/AGENTS.md, replacing
|
|
269
|
+
# the previous ArchGraph block while preserving surrounding user content.
|
|
270
|
+
param(
|
|
271
|
+
[string]$DshHome,
|
|
272
|
+
[string]$RuleText
|
|
273
|
+
)
|
|
274
|
+
$adapterNote = @'
|
|
275
|
+
# ArchGraph ARGO Workflow Rules (DeepSeek Harness edition)
|
|
276
|
+
|
|
277
|
+
> Deployed by install-argo.ps1 from argo/rules/archgraph.instructions.md
|
|
278
|
+
> (single source of truth; this file is a deployment artifact).
|
|
279
|
+
> DeepSeek Harness injects ~/.dsh/AGENTS.md through dsh-agent-instructions as
|
|
280
|
+
> user-global instructions; the file is injected verbatim, so the YAML
|
|
281
|
+
> frontmatter of the source rule is stripped here.
|
|
282
|
+
|
|
283
|
+
## DSH adapter note
|
|
284
|
+
- The ARGO MCP server is registered under serverName "argo" through the
|
|
285
|
+
@deepseek-ai/dsh-mcp-client plugin; its tools are exposed to the model with
|
|
286
|
+
the mcp__argo__ prefix (e.g. mcp__argo__getSystemArchitecture). When a rule
|
|
287
|
+
below names a tool like getSystemArchitecture, call the mcp__argo__* form.
|
|
288
|
+
- The argo-init skill is installed at ~/.dsh/skills/argo-init/SKILL.md and is
|
|
289
|
+
loadable through the harness skill tool.
|
|
290
|
+
'@
|
|
291
|
+
$body = Get-MarkdownBody -Content $RuleText
|
|
292
|
+
$ruleContent = $adapterNote + "`n`n" + $body
|
|
293
|
+
$dest = Join-Path $DshHome 'AGENTS.md'
|
|
294
|
+
$marker = 'ArchGraph ARGO Workflow Rules'
|
|
295
|
+
New-Item -ItemType Directory -Force -Path $DshHome | Out-Null
|
|
296
|
+
if (Test-Path $dest) {
|
|
297
|
+
$existing = Get-Content $dest -Raw -Encoding UTF8
|
|
298
|
+
if ($existing -like "*$marker*") {
|
|
299
|
+
$endTag = '</ToolsGuideline>'
|
|
300
|
+
$markerIdx = $existing.IndexOf($marker)
|
|
301
|
+
if ($markerIdx -lt 0) { $markerIdx = 0 }
|
|
302
|
+
$startIdx = $existing.LastIndexOf('# ArchGraph', $markerIdx)
|
|
303
|
+
if ($startIdx -lt 0) { $startIdx = 0 }
|
|
304
|
+
$endIdx = $existing.IndexOf($endTag, $markerIdx)
|
|
305
|
+
$before = $existing.Substring(0, $startIdx).TrimEnd()
|
|
306
|
+
if ($endIdx -lt 0) {
|
|
307
|
+
$combined = $before
|
|
308
|
+
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
309
|
+
$combined += $ruleContent
|
|
310
|
+
} else {
|
|
311
|
+
$after = $existing.Substring($endIdx + $endTag.Length)
|
|
312
|
+
$combined = $before
|
|
313
|
+
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
314
|
+
$combined += $ruleContent
|
|
315
|
+
if ($after.Length -gt 0) { $combined += $after }
|
|
316
|
+
}
|
|
317
|
+
[System.IO.File]::WriteAllText($dest, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
318
|
+
} else {
|
|
319
|
+
$combined = $existing.TrimEnd() + "`n`n" + $ruleContent
|
|
320
|
+
[System.IO.File]::WriteAllText($dest, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
[System.IO.File]::WriteAllText($dest, $ruleContent, (New-Object System.Text.UTF8Encoding $false))
|
|
324
|
+
}
|
|
325
|
+
Write-Host " DSH rule installed -> $dest"
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function Write-DshManagedBlock {
|
|
329
|
+
# Text-level upsert of a marker-delimited block into a file (used for the
|
|
330
|
+
# managed rows in ~/.dsh/cordis.patch.yml): replaces the previous managed
|
|
331
|
+
# block and preserves surrounding content. No YAML dependency needed.
|
|
332
|
+
param(
|
|
333
|
+
[string]$Path,
|
|
334
|
+
[string]$Block,
|
|
335
|
+
[string]$MarkerStart,
|
|
336
|
+
[string]$MarkerEnd
|
|
337
|
+
)
|
|
338
|
+
New-Item -ItemType Directory -Force -Path (Split-Path $Path) | Out-Null
|
|
339
|
+
$existing = if (Test-Path $Path) { Get-Content $Path -Raw -Encoding UTF8 } else { '' }
|
|
340
|
+
$startIdx = $existing.IndexOf($MarkerStart)
|
|
341
|
+
$endIdx = if ($startIdx -ge 0) { $existing.IndexOf($MarkerEnd, $startIdx) } else { -1 }
|
|
342
|
+
if ($startIdx -ge 0 -and $endIdx -ge 0) {
|
|
343
|
+
$endIdx += $MarkerEnd.Length
|
|
344
|
+
$combined = $existing.Substring(0, $startIdx).TrimEnd()
|
|
345
|
+
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
346
|
+
$combined += $Block
|
|
347
|
+
$after = $existing.Substring($endIdx).TrimStart()
|
|
348
|
+
if ($after.Length -gt 0) { $combined += "`n`n" + $after }
|
|
349
|
+
[System.IO.File]::WriteAllText($Path, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
350
|
+
} else {
|
|
351
|
+
$combined = $existing.TrimEnd()
|
|
352
|
+
if ($combined.Length -gt 0) { $combined += "`n`n" }
|
|
353
|
+
$combined += $Block + "`n"
|
|
354
|
+
[System.IO.File]::WriteAllText($Path, $combined, (New-Object System.Text.UTF8Encoding $false))
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function New-DshWakeupPlugin {
|
|
359
|
+
# Generate the DSH wakeup-gate Cordis plugin under ~/.dsh/plugins from the
|
|
360
|
+
# <WakeupGuideline> block of the rule file. This is the DeepSeek Harness
|
|
361
|
+
# equivalent of the OpenCode hook plugin argo/plugins/argo-wakeup.js: it
|
|
362
|
+
# registers the gate as the first system-prompt section after the harness
|
|
363
|
+
# identity (order -100), before the deployment persona (order 0).
|
|
364
|
+
param(
|
|
365
|
+
[string]$DshHome,
|
|
366
|
+
[string]$RuleText
|
|
367
|
+
)
|
|
368
|
+
$gate = Get-WakeupGuideline -RuleText $RuleText
|
|
369
|
+
if (-not $gate) {
|
|
370
|
+
Write-Warning ' <WakeupGuideline> not found in the rule file; DSH wakeup plugin skipped.'
|
|
371
|
+
return $null
|
|
372
|
+
}
|
|
373
|
+
$dir = Join-Path (Join-Path $DshHome 'plugins') 'dsh-argo-wakeup'
|
|
374
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
375
|
+
$gateJson = $gate | ConvertTo-Json
|
|
376
|
+
$plugin = @"
|
|
377
|
+
// dsh-argo-wakeup - generated by install-argo.ps1 from
|
|
378
|
+
// argo/rules/archgraph.instructions.md (single source of truth: the rule file;
|
|
379
|
+
// this file is a deployment artifact, do not edit by hand).
|
|
380
|
+
// DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
|
|
381
|
+
// registers the unconditional wakeup gate as the first system-prompt section
|
|
382
|
+
// after the harness identity, so every session identifies its Business Actor
|
|
383
|
+
// through the argo MCP server before responding.
|
|
384
|
+
export const name = 'dsh-argo-wakeup'
|
|
385
|
+
export const inject = ['systemPrompt']
|
|
386
|
+
const WAKEUP_GATE = $gateJson
|
|
387
|
+
export function apply(ctx) {
|
|
388
|
+
ctx.effect(() => ctx.systemPrompt.section({
|
|
389
|
+
name: 'argo:wakeup',
|
|
390
|
+
order: -90,
|
|
391
|
+
text: WAKEUP_GATE,
|
|
392
|
+
}), 'argo:wakeup.section()')
|
|
393
|
+
}
|
|
394
|
+
"@
|
|
395
|
+
$indexPath = Join-Path $dir 'index.js'
|
|
396
|
+
[System.IO.File]::WriteAllText($indexPath, $plugin, (New-Object System.Text.UTF8Encoding $false))
|
|
397
|
+
Write-Host " DSH wakeup plugin generated -> $indexPath"
|
|
398
|
+
return $indexPath
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function New-DshAgentPresets {
|
|
402
|
+
# Generate DSH agent presets under ~/.dsh/.agent-presets/<id>/ from
|
|
403
|
+
# argo/agents/*.agent.md (the same single source the Copilot / Cursor /
|
|
404
|
+
# OpenCode agent files are converted from). persona.md is a
|
|
405
|
+
# frontmatter-stripped copy of the agent body; persona.js is a fixed
|
|
406
|
+
# self-contained row that mounts it as the session persona
|
|
407
|
+
# (deployment:persona section, order 0).
|
|
408
|
+
param(
|
|
409
|
+
[string]$DshHome,
|
|
410
|
+
[string]$AgentsSrc
|
|
411
|
+
)
|
|
412
|
+
$files = @(Get-ChildItem -Path (Join-Path $AgentsSrc '*.agent.md') -ErrorAction SilentlyContinue)
|
|
413
|
+
if ($files.Count -eq 0) {
|
|
414
|
+
Write-Warning ' no *.agent.md files found; DSH agent presets skipped.'
|
|
415
|
+
return
|
|
416
|
+
}
|
|
417
|
+
foreach ($file in $files) {
|
|
418
|
+
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
|
419
|
+
$m = [regex]::Match($content, '(?s)^---\s*\r?\n(.*?)\r?\n---\s*\r?\n(.*)$')
|
|
420
|
+
$name = ''
|
|
421
|
+
$desc = ''
|
|
422
|
+
$body = $content
|
|
423
|
+
if ($m.Success) {
|
|
424
|
+
$front = $m.Groups[1].Value
|
|
425
|
+
$body = $m.Groups[2].Value.TrimStart("`r", "`n")
|
|
426
|
+
$nm = [regex]::Match($front, '(?m)^name:\s*(.*)$')
|
|
427
|
+
if ($nm.Success) { $name = $nm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
428
|
+
$dm = [regex]::Match($front, '(?m)^description:\s*(.*)$')
|
|
429
|
+
if ($dm.Success) { $desc = $dm.Groups[1].Value.Trim().Trim('"').Trim("'") }
|
|
430
|
+
}
|
|
431
|
+
$id = $file.BaseName -replace '\.agent$', ''
|
|
432
|
+
if (-not $name) { $name = $id }
|
|
433
|
+
$dir = Join-Path (Join-Path $DshHome '.agent-presets') $id
|
|
434
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
435
|
+
|
|
436
|
+
# preset.yml: display metadata (name + description).
|
|
437
|
+
$presetYml = "name: $name`n"
|
|
438
|
+
if ($desc) { $presetYml += "description: `"$($desc -replace '"', '\"')`"`n" }
|
|
439
|
+
[System.IO.File]::WriteAllText((Join-Path $dir 'preset.yml'), $presetYml, (New-Object System.Text.UTF8Encoding $false))
|
|
440
|
+
|
|
441
|
+
# persona.md: the agent body verbatim (single source: the .agent.md file).
|
|
442
|
+
[System.IO.File]::WriteAllText((Join-Path $dir 'persona.md'), $body, (New-Object System.Text.UTF8Encoding $false))
|
|
443
|
+
|
|
444
|
+
# agent.cordis.yml: mount the local persona row.
|
|
445
|
+
$cordisYml = @"
|
|
446
|
+
# ArchGraph agent preset "$name" - generated by install-argo.ps1 from
|
|
447
|
+
# argo/agents/$($file.Name) (single source of truth; this file is a deployment
|
|
448
|
+
# artifact, do not edit by hand). The persona is the frontmatter-stripped agent
|
|
449
|
+
# body (persona.md), mounted as the session's deployment:persona section.
|
|
450
|
+
- id: persona
|
|
451
|
+
name: './persona.js'
|
|
452
|
+
"@
|
|
453
|
+
[System.IO.File]::WriteAllText((Join-Path $dir 'agent.cordis.yml'), $cordisYml, (New-Object System.Text.UTF8Encoding $false))
|
|
454
|
+
|
|
455
|
+
# persona.js: fixed row implementation.
|
|
456
|
+
$personaJs = @'
|
|
457
|
+
// persona row for an ArchGraph agent preset (generated by install-argo.ps1).
|
|
458
|
+
// Loads persona.md next to this file and registers it as the
|
|
459
|
+
// deployment:persona system-prompt section (order 0), shadowing the
|
|
460
|
+
// deployment persona for the session that mounts this preset.
|
|
461
|
+
import { readFileSync } from 'node:fs'
|
|
462
|
+
import { fileURLToPath } from 'node:url'
|
|
463
|
+
export const name = 'persona'
|
|
464
|
+
export const inject = ['systemPrompt']
|
|
465
|
+
export function apply(ctx) {
|
|
466
|
+
const text = readFileSync(fileURLToPath(new URL('./persona.md', import.meta.url)), 'utf8')
|
|
467
|
+
ctx.effect(() => ctx.systemPrompt.section({
|
|
468
|
+
name: 'deployment:persona',
|
|
469
|
+
order: 0,
|
|
470
|
+
text,
|
|
471
|
+
}), 'persona.section()')
|
|
472
|
+
}
|
|
473
|
+
'@
|
|
474
|
+
[System.IO.File]::WriteAllText((Join-Path $dir 'persona.js'), $personaJs, (New-Object System.Text.UTF8Encoding $false))
|
|
475
|
+
Write-Host " DSH agent preset generated -> $dir"
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
175
479
|
Write-Host '==> Deploying Argo toolchain'
|
|
176
480
|
|
|
177
481
|
$schemaSrc = Join-Path $argoDir 'schema'
|
|
178
482
|
$schemaDest = Join-Path $ArgoRoot 'schema'
|
|
179
|
-
Write-Host "[1/
|
|
483
|
+
Write-Host "[1/14] argo\schema -> $schemaDest"
|
|
180
484
|
Copy-Tree -Source $schemaSrc -Destination $schemaDest
|
|
181
485
|
|
|
182
486
|
$scriptsSrc = Join-Path $argoDir 'scripts'
|
|
183
487
|
$scriptsDest = Join-Path $ArgoRoot 'scripts'
|
|
184
|
-
Write-Host "[2/
|
|
488
|
+
Write-Host "[2/14] argo\scripts -> $scriptsDest"
|
|
185
489
|
Copy-Tree -Source $scriptsSrc -Destination $scriptsDest
|
|
186
490
|
|
|
187
491
|
$defaultsSrc = Join-Path $argoDir 'defaults'
|
|
188
492
|
$defaultsDest = Join-Path $ArgoRoot 'defaults'
|
|
189
|
-
Write-Host "[3/
|
|
493
|
+
Write-Host "[3/14] argo\defaults -> $defaultsDest"
|
|
190
494
|
Copy-Tree -Source $defaultsSrc -Destination $defaultsDest
|
|
191
495
|
|
|
192
496
|
$skillSrc = Join-Path (Join-Path $argoDir 'skills') 'argo-init'
|
|
193
497
|
$skillDest = Join-Path $SkillsRoot 'argo-init'
|
|
194
|
-
Write-Host "[4/
|
|
498
|
+
Write-Host "[4/14] argo\skills\argo-init -> $skillDest"
|
|
195
499
|
Copy-Tree -Source $skillSrc -Destination $skillDest
|
|
196
500
|
|
|
197
501
|
$ruleSrc = Join-Path (Join-Path $argoDir 'rules') 'archgraph.instructions.md'
|
|
198
502
|
$ruleDest = Join-Path $PromptsRoot 'archgraph.instructions.md'
|
|
199
|
-
Write-Host "[5/
|
|
503
|
+
Write-Host "[5/14] argo\rules\archgraph.instructions.md -> $ruleDest"
|
|
200
504
|
New-Item -ItemType Directory -Force -Path $PromptsRoot | Out-Null
|
|
201
505
|
Copy-Item -Force -Path $ruleSrc -Destination $ruleDest
|
|
202
506
|
|
|
203
507
|
$depsSrc = Join-Path $argoDir 'package.json'
|
|
204
508
|
$depsDest = Join-Path $ArgoRoot 'package.json'
|
|
205
|
-
Write-Host "[6/
|
|
509
|
+
Write-Host "[6/14] argo\package.json -> $depsDest"
|
|
206
510
|
Copy-Item -Force -Path $depsSrc -Destination $depsDest
|
|
207
511
|
|
|
208
512
|
$cursorSkillDest = Join-Path $CursorSkillsRoot 'argo-init'
|
|
209
|
-
Write-Host "[7/
|
|
513
|
+
Write-Host "[7/14] argo\skills\argo-init -> $cursorSkillDest (Cursor)"
|
|
210
514
|
Copy-Tree -Source $skillSrc -Destination $cursorSkillDest
|
|
211
515
|
|
|
212
516
|
$openCodeSkillDest = Join-Path $OpenCodeSkillsRoot 'argo-init'
|
|
213
|
-
Write-Host "[8/
|
|
517
|
+
Write-Host "[8/14] argo\skills\argo-init -> $openCodeSkillDest (OpenCode)"
|
|
214
518
|
Copy-Tree -Source $skillSrc -Destination $openCodeSkillDest
|
|
215
519
|
|
|
216
|
-
Write-Host "[9/
|
|
520
|
+
Write-Host "[9/14] argo\rules\archgraph.instructions.md -> $OpenCodeAgentsPath (OpenCode global AGENTS.md)"
|
|
217
521
|
Add-AgentsRule -AgentsPath $OpenCodeAgentsPath -RulePath $ruleSrc
|
|
218
522
|
|
|
219
523
|
$agentsSrc = Join-Path $argoDir 'agents'
|
|
220
|
-
Write-Host "[10/
|
|
524
|
+
Write-Host "[10/14] argo\agents -> $CopilotAgentsRoot (Copilot user-level)"
|
|
221
525
|
Copy-Agents -Source $agentsSrc -Destination $CopilotAgentsRoot
|
|
222
526
|
|
|
223
|
-
Write-Host "[11/
|
|
527
|
+
Write-Host "[11/14] argo\agents -> $CursorAgentsRoot (Cursor user-level, converted to .md)"
|
|
224
528
|
Copy-Agents -Source $agentsSrc -Destination $CursorAgentsRoot -Target cursor
|
|
225
529
|
|
|
226
|
-
Write-Host "[12/
|
|
530
|
+
Write-Host "[12/14] argo\agents -> $OpenCodeAgentsRoot (OpenCode user-level, converted to .md)"
|
|
227
531
|
Copy-Agents -Source $agentsSrc -Destination $OpenCodeAgentsRoot -Target opencode
|
|
228
532
|
|
|
533
|
+
$pluginsSrc = Join-Path $argoDir 'plugins'
|
|
534
|
+
Write-Host "[13/14] argo\plugins -> $PluginsRoot (Argo opencode plugins)"
|
|
535
|
+
Copy-Tree -Source $pluginsSrc -Destination $PluginsRoot
|
|
536
|
+
|
|
537
|
+
$cursorRuleSrc = Join-Path (Join-Path $argoDir 'rules') 'archgraph.instructions.md'
|
|
538
|
+
$cursorRuleDest = Join-Path $CursorRulesRoot 'archgraph.mdc'
|
|
539
|
+
Write-Host "[14/14] argo\rules\archgraph.instructions.md -> $cursorRuleDest (Cursor global rule, alwaysApply)"
|
|
540
|
+
New-Item -ItemType Directory -Force -Path $CursorRulesRoot | Out-Null
|
|
541
|
+
Convert-RuleFile -SourceFile $cursorRuleSrc -DestinationFile $cursorRuleDest
|
|
542
|
+
|
|
229
543
|
if ($SkipDeps) {
|
|
230
544
|
Write-Host 'Skipped dependency install (-SkipDeps).'
|
|
231
545
|
} elseif (Get-Command npm -ErrorAction SilentlyContinue) {
|
|
@@ -347,5 +661,51 @@ if ($SkipMcp) {
|
|
|
347
661
|
Write-Host "argo MCP config written -> $OpenCodeConfigPath"
|
|
348
662
|
}
|
|
349
663
|
|
|
664
|
+
$wakeupPluginPath = Join-Path $PluginsRoot 'argo-wakeup.js'
|
|
665
|
+
if (Test-Path $wakeupPluginPath) {
|
|
666
|
+
Write-Host '==> Registering argo-wakeup plugin in OpenCode'
|
|
667
|
+
Register-OpenCodePlugin -ConfigPath $OpenCodeConfigPath -PluginFilePath $wakeupPluginPath
|
|
668
|
+
Write-Host "argo-wakeup plugin registered -> $OpenCodeConfigPath"
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if ($SkipDsh) {
|
|
672
|
+
Write-Host 'Skipped DeepSeek Harness integration (-SkipDsh).'
|
|
673
|
+
} else {
|
|
674
|
+
Write-Host '==> Deploying DeepSeek Harness integration (rule / skill / mcp / plugin / agent)'
|
|
675
|
+
|
|
676
|
+
$ruleSrcContent = Get-Content $ruleSrc -Raw -Encoding UTF8
|
|
677
|
+
|
|
678
|
+
# 1. rule -> ~/.dsh/AGENTS.md (frontmatter stripped; DSH injects verbatim)
|
|
679
|
+
Write-DshAgentRule -DshHome $DshHome -RuleText $ruleSrcContent
|
|
680
|
+
|
|
681
|
+
# 2. skill -> ~/.dsh/skills/argo-init (frontmatter is already DSH-compatible:
|
|
682
|
+
# name / description / disable-model-invocation are parsed by dsh-skill-filesystem)
|
|
683
|
+
$dshSkillDest = Join-Path (Join-Path $DshHome 'skills') 'argo-init'
|
|
684
|
+
Copy-Tree -Source (Join-Path $argoDir 'skills\argo-init') -Destination $dshSkillDest
|
|
685
|
+
Write-Host " argo-init skill installed -> $dshSkillDest"
|
|
686
|
+
|
|
687
|
+
# 3. plugin -> ~/.dsh/plugins/dsh-argo-wakeup/index.js generated from the
|
|
688
|
+
# rule's <WakeupGuideline> block (single source: the rule file)
|
|
689
|
+
$wakeupDshPath = New-DshWakeupPlugin -DshHome $DshHome -RuleText $ruleSrcContent
|
|
690
|
+
|
|
691
|
+
# 4. mcp + plugin rows -> ~/.dsh/cordis.patch.yml (marker-delimited managed block)
|
|
692
|
+
$argoServer = (Join-Path $ArgoRoot 'scripts\argo-mcp-server.js').Replace('\', '/')
|
|
693
|
+
$rows = " - id: mcp-argo`n name: '@deepseek-ai/dsh-mcp-client'`n config:`n serverName: argo`n transport: stdio`n command: node`n args:`n - $argoServer`n"
|
|
694
|
+
if ($wakeupDshPath) {
|
|
695
|
+
$pluginUrl = 'file:///' + (($wakeupDshPath -replace '\\', '/').TrimStart('/'))
|
|
696
|
+
$rows += " - id: argo-wakeup`n name: '$pluginUrl'`n"
|
|
697
|
+
}
|
|
698
|
+
$block = "# BEGIN ArchGraph ARGO deployment (managed by install-argo.ps1)`n- insert:`n" + $rows + "# END ArchGraph ARGO deployment"
|
|
699
|
+
$patchPath = Join-Path $DshHome 'cordis.patch.yml'
|
|
700
|
+
Write-DshManagedBlock -Path $patchPath -Block $block -MarkerStart '# BEGIN ArchGraph ARGO deployment' -MarkerEnd '# END ArchGraph ARGO deployment'
|
|
701
|
+
Write-Host " DSH MCP + wakeup rows written -> $patchPath"
|
|
702
|
+
|
|
703
|
+
# 5. agents -> ~/.dsh/.agent-presets/<id>/ generated from argo/agents/*.agent.md
|
|
704
|
+
New-DshAgentPresets -DshHome $DshHome -AgentsSrc (Join-Path $argoDir 'agents')
|
|
705
|
+
|
|
706
|
+
Write-Host ' Restart `dsh web` to activate the MCP server and the wakeup plugin;'
|
|
707
|
+
Write-Host ' new sessions pick up the global rule and the argo-init skill automatically.'
|
|
708
|
+
}
|
|
709
|
+
|
|
350
710
|
Write-Host ''
|
|
351
711
|
Write-Host 'Argo deployment complete.'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "archgraph-argo",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
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": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"argo/schema",
|
|
12
12
|
"argo/defaults",
|
|
13
13
|
"argo/agents",
|
|
14
|
+
"argo/plugins",
|
|
14
15
|
"argo/skills/argo-init",
|
|
15
16
|
"argo/rules",
|
|
16
17
|
"argo/package.json",
|