archgraph-argo 0.1.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/LICENSE +201 -0
- package/README.md +115 -0
- package/argo/package.json +8 -0
- package/argo/rules/intent-architecture-global-rule.md +45 -0
- package/argo/schema/ImplementationToCodingHandoff.schema.json +252 -0
- package/argo/schema/ImplementationToIntentTraceProposal.schema.json +180 -0
- package/argo/schema/IntentToImplementationHandoff.schema.json +75 -0
- package/argo/schema/SystemArchitecture.schema.json +378 -0
- package/argo/schema/archimate3.2.pdf +0 -0
- package/argo/scripts/ARCHITECTURE.md +57 -0
- package/argo/scripts/archimate32-rules.js +12301 -0
- package/argo/scripts/argo-mcp-server.js +629 -0
- package/argo/scripts/argo-paths.js +77 -0
- package/argo/scripts/ensureArgoHarnessEnvironment.js +340 -0
- package/argo/scripts/generateArchitectureDiffPlantuml.js +466 -0
- package/argo/scripts/graph-rag/ARCHITECTURE.md +192 -0
- package/argo/scripts/graph-rag/canonicalProjectionAuthority.js +45 -0
- package/argo/scripts/graph-rag/defaultSemanticRetrieval.js +969 -0
- package/argo/scripts/graph-rag/embeddingQualificationGate.js +59 -0
- package/argo/scripts/graph-rag/externalProductionConfig.js +74 -0
- package/argo/scripts/graph-rag/liveEmbeddingIndexGate.js +129 -0
- package/argo/scripts/graph-rag/liveEmbeddingNeo4jBoundary.js +137 -0
- package/argo/scripts/graph-rag/liveEmbeddingProviderClient.js +49 -0
- package/argo/scripts/graph-rag/liveEmbeddingProviderConfig.js +481 -0
- package/argo/scripts/graph-rag/mutationEmbeddingVectorLifecycle.js +1261 -0
- package/argo/scripts/graph-rag/neo4jNativeRetrieval.js +37 -0
- package/argo/scripts/graph-rag/productionGraphRagRuntime.js +1624 -0
- package/argo/scripts/graph-rag/semantic-persistence/ARCHITECTURE.md +51 -0
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticBackfill.js +241 -0
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticCheckpointStore.js +99 -0
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticNeo4jAdapter.js +149 -0
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticProjectionStore.js +171 -0
- package/argo/scripts/graph-rag/semanticOperatorError.js +38 -0
- package/argo/scripts/graph-rag/semanticOperatorJourney.js +459 -0
- package/argo/scripts/graph-rag/semanticReadinessAttestationStore.js +398 -0
- package/argo/scripts/graph-rag/systemMetadataCommandAdapter.js +269 -0
- package/argo/scripts/graph-semantics.js +220 -0
- package/argo/scripts/neo4j-system-architecture-store.js +777 -0
- package/argo/scripts/repositoryArgoEnvironment.js +101 -0
- package/argo/scripts/runArchitectureTests.js +583 -0
- package/argo/scripts/semanticOperatorJourneyCli.js +91 -0
- package/argo/scripts/syncSystemArchitectureToNeo4j.js +67 -0
- package/argo/scripts/systemarchitecture-mcp-server.js +2965 -0
- package/argo/scripts/test-executors/_template.js +58 -0
- package/argo/scripts/test-executors/default.js +199 -0
- package/argo/scripts/validateStageHandoff.js +459 -0
- package/argo/scripts/validateSystemArchitecture.js +254 -0
- package/argo/scripts/validateTraceProposal.js +181 -0
- package/argo/scripts/validator-mcp-server.js +377 -0
- package/argo/skills/argo-init/SKILL.md +110 -0
- package/bin/argo-deploy.js +12 -0
- package/install-argo.ps1 +112 -0
- package/package.json +28 -0
- package/vendor/neo4j-driver-6.2.0.tgz +0 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
const { execFile, spawn } = require('node:child_process');
|
|
2
|
+
const fs = require('node:fs');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const readline = require('node:readline');
|
|
5
|
+
const { promisify } = require('node:util');
|
|
6
|
+
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
getArgoRoot,
|
|
11
|
+
getWorkspaceRoot,
|
|
12
|
+
} = require('./argo-paths.js');
|
|
13
|
+
|
|
14
|
+
const HANDOFF_STAGES = ['intent-to-implementation', 'implementation-to-coding'];
|
|
15
|
+
const DEFAULT_TRACE_PROPOSAL_PATH = 'design/KG/ImplementationToIntentTraceProposal.json';
|
|
16
|
+
const DEFAULT_ARCHITECTURE_GRAPH_PATH = 'design/KG/SystemArchitecture.json';
|
|
17
|
+
|
|
18
|
+
const SCRIPT_CANDIDATES = {
|
|
19
|
+
validateSystemArchitecture: [
|
|
20
|
+
'scripts/validateSystemArchitecture.js',
|
|
21
|
+
],
|
|
22
|
+
validateStageHandoff: [
|
|
23
|
+
'scripts/validateStageHandoff.js',
|
|
24
|
+
],
|
|
25
|
+
validateTraceProposal: [
|
|
26
|
+
'scripts/validateTraceProposal.js',
|
|
27
|
+
],
|
|
28
|
+
runArchitectureTests: [
|
|
29
|
+
'scripts/runArchitectureTests.js',
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const TOOLS = [
|
|
34
|
+
{
|
|
35
|
+
name: 'validateSystemArchitecture',
|
|
36
|
+
description: 'Validate design/KG/SystemArchitecture.json against .argo/schema/SystemArchitecture.schema.json and Argo graph rules.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {},
|
|
40
|
+
additionalProperties: false,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'validateStageHandoff',
|
|
45
|
+
description: 'Validate Argo stage handoff JSON. Use stage intent-to-implementation or implementation-to-coding, or omit to validate all supported stages.',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
stage: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
enum: HANDOFF_STAGES,
|
|
52
|
+
description: 'Optional handoff stage to validate.',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
additionalProperties: false,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'validateTraceProposal',
|
|
60
|
+
description: 'Validate ImplementationToIntentTraceProposal JSON against .argo/schema/ImplementationToIntentTraceProposal.schema.json and repository path references.',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
proposalPath: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: `Optional proposal path relative to workspace root. Default: ${DEFAULT_TRACE_PROPOSAL_PATH}`,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
additionalProperties: false,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'runArchitectureTests',
|
|
74
|
+
description: 'Execute explicit architecture testcases from the intent graph and refresh design/KG/test-failure-records.json. This MCP call can exceed client timeouts; if it times out, run the same test runner directly with: node .argo/scripts/runArchitectureTests.js',
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
architecturePath: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
description: `Optional architecture graph path relative to workspace root. Default: ${DEFAULT_ARCHITECTURE_GRAPH_PATH}`,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
additionalProperties: false,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
function resolveWorkspaceRoot() {
|
|
89
|
+
return getWorkspaceRoot();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function resolveScriptPath(workspaceRoot, candidates) {
|
|
93
|
+
const argoRoot = getArgoRoot();
|
|
94
|
+
for (const relativePath of candidates) {
|
|
95
|
+
const absolutePath = path.join(argoRoot, relativePath);
|
|
96
|
+
if (fs.existsSync(absolutePath)) {
|
|
97
|
+
return { absolutePath, relativePath };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const relativePath of candidates) {
|
|
102
|
+
const absolutePath = path.join(workspaceRoot, '.argo', relativePath);
|
|
103
|
+
if (fs.existsSync(absolutePath)) {
|
|
104
|
+
return { absolutePath, relativePath };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
throw new Error(`Unable to locate validator script. Checked: ${candidates.join(', ')}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function runValidatorScriptStreaming(workspaceRoot, scriptKey, args, progressToken) {
|
|
112
|
+
const { absolutePath, relativePath } = resolveScriptPath(workspaceRoot, SCRIPT_CANDIDATES[scriptKey]);
|
|
113
|
+
const command = process.execPath;
|
|
114
|
+
const commandArgs = [absolutePath, ...args];
|
|
115
|
+
|
|
116
|
+
return new Promise((resolve, reject) => {
|
|
117
|
+
const child = spawn(command, commandArgs, {
|
|
118
|
+
cwd: workspaceRoot,
|
|
119
|
+
env: {
|
|
120
|
+
...process.env,
|
|
121
|
+
ARGO_REPO_ROOT: workspaceRoot,
|
|
122
|
+
},
|
|
123
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
let stdout = '';
|
|
127
|
+
let stderr = '';
|
|
128
|
+
|
|
129
|
+
const stdoutLines = readline.createInterface({ input: child.stdout, crlfDelay: Infinity });
|
|
130
|
+
|
|
131
|
+
stdoutLines.on('line', (line) => {
|
|
132
|
+
stdout += line + '\n';
|
|
133
|
+
|
|
134
|
+
const progressMatch = line.match(/^\[PROGRESS\]\s*(.+)$/);
|
|
135
|
+
if (progressMatch) {
|
|
136
|
+
try {
|
|
137
|
+
const payload = JSON.parse(progressMatch[1]);
|
|
138
|
+
send({
|
|
139
|
+
jsonrpc: '2.0',
|
|
140
|
+
method: 'notifications/progress',
|
|
141
|
+
params: {
|
|
142
|
+
progressToken,
|
|
143
|
+
progress: payload.passedCount !== undefined
|
|
144
|
+
? payload.passedCount
|
|
145
|
+
: payload.index + 1,
|
|
146
|
+
total: payload.total,
|
|
147
|
+
message: `${payload.testcaseName || '(unnamed)'}: ${payload.status}`,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
} catch (_) {
|
|
151
|
+
// ignore malformed progress lines
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
child.stderr.on('data', (data) => {
|
|
157
|
+
stderr += data.toString();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
child.on('error', (error) => {
|
|
161
|
+
reject(error);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
child.on('close', (exitCode) => {
|
|
165
|
+
const code = exitCode === null ? 1 : exitCode;
|
|
166
|
+
const passed = code === 0;
|
|
167
|
+
resolve({
|
|
168
|
+
status: passed ? 'passed' : 'failed',
|
|
169
|
+
exitCode: code,
|
|
170
|
+
workspaceRoot,
|
|
171
|
+
scriptPath: relativePath,
|
|
172
|
+
command: [command, ...commandArgs],
|
|
173
|
+
stdout: stdout.trim(),
|
|
174
|
+
stderr: stderr.trim(),
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function runValidatorScript(workspaceRoot, scriptKey, args = []) {
|
|
181
|
+
const { absolutePath, relativePath } = resolveScriptPath(workspaceRoot, SCRIPT_CANDIDATES[scriptKey]);
|
|
182
|
+
const command = process.execPath;
|
|
183
|
+
const commandArgs = [absolutePath, ...args];
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const { stdout, stderr } = await execFileAsync(command, commandArgs, {
|
|
187
|
+
cwd: workspaceRoot,
|
|
188
|
+
env: {
|
|
189
|
+
...process.env,
|
|
190
|
+
ARGO_REPO_ROOT: workspaceRoot,
|
|
191
|
+
},
|
|
192
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
status: 'passed',
|
|
197
|
+
exitCode: 0,
|
|
198
|
+
workspaceRoot,
|
|
199
|
+
scriptPath: relativePath,
|
|
200
|
+
command: [command, ...commandArgs],
|
|
201
|
+
stdout: stdout.trim(),
|
|
202
|
+
stderr: stderr.trim(),
|
|
203
|
+
};
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return {
|
|
206
|
+
status: 'failed',
|
|
207
|
+
exitCode: typeof error.code === 'number' ? error.code : 1,
|
|
208
|
+
workspaceRoot,
|
|
209
|
+
scriptPath: relativePath,
|
|
210
|
+
command: [command, ...commandArgs],
|
|
211
|
+
stdout: String(error.stdout || '').trim(),
|
|
212
|
+
stderr: String(error.stderr || error.message || error).trim(),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function send(message) {
|
|
218
|
+
process.stdout.write(`${JSON.stringify(message)}\n`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function toolResult(payload) {
|
|
222
|
+
return {
|
|
223
|
+
content: [
|
|
224
|
+
{
|
|
225
|
+
type: 'text',
|
|
226
|
+
text: JSON.stringify(payload, null, 2),
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
isError: payload.status === 'failed',
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function callTool(name, args, progressToken = null) {
|
|
234
|
+
const workspaceRoot = resolveWorkspaceRoot();
|
|
235
|
+
|
|
236
|
+
if (name === 'validateSystemArchitecture') {
|
|
237
|
+
return toolResult(await runValidatorScript(workspaceRoot, 'validateSystemArchitecture'));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (name === 'validateStageHandoff') {
|
|
241
|
+
const stage = args && args.stage;
|
|
242
|
+
if (stage && !HANDOFF_STAGES.includes(stage)) {
|
|
243
|
+
throw new Error(`Unsupported handoff stage '${stage}'. Expected one of: ${HANDOFF_STAGES.join(', ')}`);
|
|
244
|
+
}
|
|
245
|
+
return toolResult(await runValidatorScript(workspaceRoot, 'validateStageHandoff', stage ? [stage] : []));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (name === 'validateTraceProposal') {
|
|
249
|
+
const proposalPath = (args && args.proposalPath) || DEFAULT_TRACE_PROPOSAL_PATH;
|
|
250
|
+
return toolResult(await runValidatorScript(workspaceRoot, 'validateTraceProposal', [proposalPath]));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (name === 'runArchitectureTests') {
|
|
254
|
+
const architecturePath = (args && args.architecturePath) || DEFAULT_ARCHITECTURE_GRAPH_PATH;
|
|
255
|
+
if (progressToken) {
|
|
256
|
+
return toolResult(await runValidatorScriptStreaming(workspaceRoot, 'runArchitectureTests', [architecturePath], progressToken));
|
|
257
|
+
}
|
|
258
|
+
return toolResult(await runValidatorScript(workspaceRoot, 'runArchitectureTests', [architecturePath]));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async function handleRequest(request) {
|
|
265
|
+
const { id, method, params } = request;
|
|
266
|
+
|
|
267
|
+
if (method === 'initialize') {
|
|
268
|
+
return {
|
|
269
|
+
jsonrpc: '2.0',
|
|
270
|
+
id,
|
|
271
|
+
result: {
|
|
272
|
+
protocolVersion: '2024-11-05',
|
|
273
|
+
capabilities: {
|
|
274
|
+
tools: {},
|
|
275
|
+
},
|
|
276
|
+
serverInfo: {
|
|
277
|
+
name: 'argo',
|
|
278
|
+
version: '1.0.0',
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (method === 'notifications/initialized') {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (method === 'tools/list') {
|
|
289
|
+
return {
|
|
290
|
+
jsonrpc: '2.0',
|
|
291
|
+
id,
|
|
292
|
+
result: {
|
|
293
|
+
tools: TOOLS,
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (method === 'tools/call') {
|
|
299
|
+
try {
|
|
300
|
+
const result = await callTool(params.name, params.arguments || {});
|
|
301
|
+
return {
|
|
302
|
+
jsonrpc: '2.0',
|
|
303
|
+
id,
|
|
304
|
+
result,
|
|
305
|
+
};
|
|
306
|
+
} catch (error) {
|
|
307
|
+
return {
|
|
308
|
+
jsonrpc: '2.0',
|
|
309
|
+
id,
|
|
310
|
+
result: {
|
|
311
|
+
content: [
|
|
312
|
+
{
|
|
313
|
+
type: 'text',
|
|
314
|
+
text: String(error && error.stack ? error.stack : error),
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
isError: true,
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (method === 'ping') {
|
|
324
|
+
return {
|
|
325
|
+
jsonrpc: '2.0',
|
|
326
|
+
id,
|
|
327
|
+
result: {},
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
jsonrpc: '2.0',
|
|
333
|
+
id,
|
|
334
|
+
error: {
|
|
335
|
+
code: -32601,
|
|
336
|
+
message: `Method not found: ${method}`,
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async function main() {
|
|
342
|
+
const rl = readline.createInterface({
|
|
343
|
+
input: process.stdin,
|
|
344
|
+
crlfDelay: Infinity,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
for await (const line of rl) {
|
|
348
|
+
if (!line.trim()) {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let request;
|
|
353
|
+
try {
|
|
354
|
+
request = JSON.parse(line);
|
|
355
|
+
} catch {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const response = await handleRequest(request);
|
|
360
|
+
if (response) {
|
|
361
|
+
send(response);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (require.main === module) {
|
|
367
|
+
main().catch((error) => {
|
|
368
|
+
console.error(error);
|
|
369
|
+
process.exit(1);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
module.exports = {
|
|
374
|
+
TOOLS,
|
|
375
|
+
callTool,
|
|
376
|
+
main,
|
|
377
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: argo-init
|
|
3
|
+
description: "检查全局 ARGO MCP 是否正常,并完成 NEO4J 初始同步与语义生命周期初始化。Use when the user asks to verify Argo MCP readiness and perform or verify the canonical JSON-to-Neo4j initial sync plus semantic lifecycle init. Keywords: ARGO INIT, harness init, MCP health check, Neo4j initial sync, semantic lifecycle."
|
|
4
|
+
argument-hint: scope-or-mode
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ARGO INIT
|
|
9
|
+
|
|
10
|
+
`argo-init` 负责检查全局安装的 `argo` MCP 是否正常、完成或验证 canonical intent graph 的 Neo4j 初始同步,并在非 `--check-only` 模式下执行 canonical semantic lifecycle init。它不再负责调用旧的工作区 bootstrap / `initializeWorkspace` 工具。
|
|
11
|
+
|
|
12
|
+
- `argo` MCP 服务器(全局 `.argo` 安装)能正常初始化、列出关键工具并响应 `ping`。
|
|
13
|
+
- `design/KG/SystemArchitecture.json` 可通过 `argo` MCP 正常读取和校验。
|
|
14
|
+
- 本机 Neo4j 连接可用。
|
|
15
|
+
- canonical intent graph 至少完成一次 JSON -> Neo4j 初始同步,并通过一致性校验。
|
|
16
|
+
- 非 `--check-only` 模式会在结构同步后执行语义生命周期:双 gate 未开启时记录 pending/disabled;双 gate 开启时执行全量 embedding backfill 与 readiness 对齐。
|
|
17
|
+
|
|
18
|
+
## Rules
|
|
19
|
+
|
|
20
|
+
- **MUST** 优先运行全局 harness 原生命令(当前工作目录须为目标仓库根):`node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js"`。
|
|
21
|
+
- **MUST** 将该命令返回的 JSON 结果作为最终判断依据,而不是凭主观描述报告环境状态。
|
|
22
|
+
- **MUST** 报告 `argo` MCP 是否通过、Neo4j 是否通过、初始同步是否完成、以及 `semanticLifecycle` 当前状态。
|
|
23
|
+
- **MUST** 在脚本失败时直接转述失败阶段、错误摘要和报告路径,不要改用含糊描述。
|
|
24
|
+
- **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在、文件是否位于 git 仓库内、以及 ACL 主体。
|
|
25
|
+
- **MUST NOT** 绕开脚本分别手工执行一堆无关命令来替代初始化工作流,除非你是在排查脚本自身失败。
|
|
26
|
+
|
|
27
|
+
## Workflow
|
|
28
|
+
|
|
29
|
+
### 1. Run ARGO HARNESS Init
|
|
30
|
+
|
|
31
|
+
在目标仓库根目录执行(harness 通过 `ARGO_REPO_ROOT` / `WORKSPACE_FOLDER` / `cwd` 解析工作区):
|
|
32
|
+
|
|
33
|
+
```powershell
|
|
34
|
+
$env:ARGO_REPO_ROOT = (Get-Location).Path
|
|
35
|
+
node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
只读检查(不修改工作区、不执行初始同步):
|
|
39
|
+
|
|
40
|
+
```powershell
|
|
41
|
+
$env:ARGO_REPO_ROOT = (Get-Location).Path
|
|
42
|
+
node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js" --check-only
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
若通过 `ARGO_ENV_FILE` 指定了秘密文件,请先设置该变量再运行。
|
|
46
|
+
|
|
47
|
+
### 2. Interpret The Report
|
|
48
|
+
|
|
49
|
+
读取脚本输出的 JSON,并关注 `mcp`、`systemArchitecture`、`neo4j`、`semanticLifecycle`、`reportPath`。
|
|
50
|
+
|
|
51
|
+
- `status=ok`:环境已就绪或已确认健康。
|
|
52
|
+
- `status=failed`:指出失败阶段:
|
|
53
|
+
- Argo MCP protocol health
|
|
54
|
+
- canonical SystemArchitecture validation
|
|
55
|
+
- Neo4j connectivity
|
|
56
|
+
- Neo4j initial sync / verification
|
|
57
|
+
- semantic lifecycle init / readiness alignment
|
|
58
|
+
|
|
59
|
+
### 3. Handle Secret File Blockers
|
|
60
|
+
|
|
61
|
+
全局 `.env` 默认位于 `$env:USERPROFILE\.argo\.env`(可用 `ARGO_ENV_FILE` 覆盖)。安全诊断(不打印 secret 值):
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
icacls "$env:USERPROFILE\.argo\.env"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
处理规则:
|
|
68
|
+
|
|
69
|
+
- `SECRET_FILE_ACL_UNSAFE`: 收紧 Windows ACL,只保留当前用户、Administrators、SYSTEM。
|
|
70
|
+
- `SECRET_FILE_REPARSE_PROHIBITED`: 将 `.env` 替换为普通文件(去掉符号链接/重解析点)。
|
|
71
|
+
- `SECRET_FILE_PATH_PROHIBITED`: 修正 `ARGO_ENV_FILE` 与安装根 `.env` 不一致的路径。
|
|
72
|
+
- git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`)只在 `.env` 位于 git 仓库内时出现;全局 `.env` 位于仓库外时天然不适用。
|
|
73
|
+
|
|
74
|
+
Windows ACL 修复:
|
|
75
|
+
|
|
76
|
+
```powershell
|
|
77
|
+
$identity = whoami
|
|
78
|
+
icacls "$env:USERPROFILE\.argo\.env" /inheritance:r /grant:r "${identity}:F" "BUILTIN\Administrators:F" "NT AUTHORITY\SYSTEM:F" /remove:g "BUILTIN\Users" "Everyone" "Authenticated Users" "NT AUTHORITY\Authenticated Users"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
修复后必须重跑 init。
|
|
82
|
+
|
|
83
|
+
### 4. Report Concisely
|
|
84
|
+
|
|
85
|
+
输出应直接说明:
|
|
86
|
+
|
|
87
|
+
- `argo` MCP 是否正常
|
|
88
|
+
- `SystemArchitecture.json` 是否正常
|
|
89
|
+
- Neo4j 是否连通
|
|
90
|
+
- 是否完成了一次初始同步
|
|
91
|
+
- 语义生命周期状态、alignment、是否因 `--check-only` 跳过
|
|
92
|
+
- 报告文件位置
|
|
93
|
+
|
|
94
|
+
## Output
|
|
95
|
+
|
|
96
|
+
输出必须包含:
|
|
97
|
+
|
|
98
|
+
### 1. Environment Status
|
|
99
|
+
- overall status: ok / failed
|
|
100
|
+
- whether Argo MCP health passed
|
|
101
|
+
- whether Neo4j health passed
|
|
102
|
+
|
|
103
|
+
### 2. Sync Status
|
|
104
|
+
- whether initial sync was executed
|
|
105
|
+
- whether verification matched JSON and Neo4j
|
|
106
|
+
- current counts summary when available
|
|
107
|
+
|
|
108
|
+
### 3. Semantic Lifecycle Status
|
|
109
|
+
- whether semantic lifecycle init ran, skipped, or failed
|
|
110
|
+
- state/alignment/readiness summary when available
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { spawnSync } = require('node:child_process');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const script = path.join(__dirname, '..', 'install-argo.ps1');
|
|
8
|
+
const shell = process.platform === 'win32' ? 'powershell' : 'pwsh';
|
|
9
|
+
const args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script, ...process.argv.slice(2)];
|
|
10
|
+
|
|
11
|
+
const result = spawnSync(shell, args, { stdio: 'inherit' });
|
|
12
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install-argo.ps1
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#Requires -Version 5.1
|
|
2
|
+
param(
|
|
3
|
+
[string]$ArgoRoot = "$env:USERPROFILE\.argo",
|
|
4
|
+
[string]$SkillsRoot = "$env:USERPROFILE\.copilot\skills",
|
|
5
|
+
[string]$PromptsRoot = "$env:APPDATA\Code\User\prompts",
|
|
6
|
+
[switch]$SkipEnv,
|
|
7
|
+
[switch]$SkipDeps
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
$ErrorActionPreference = 'Stop'
|
|
11
|
+
$repoRoot = $PSScriptRoot
|
|
12
|
+
$argoDir = Join-Path $repoRoot 'argo'
|
|
13
|
+
|
|
14
|
+
function Copy-Tree {
|
|
15
|
+
param([string]$Source, [string]$Destination)
|
|
16
|
+
New-Item -ItemType Directory -Force -Path $Destination | Out-Null
|
|
17
|
+
Copy-Item -Recurse -Force -Path (Join-Path $Source '*') -Destination $Destination
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Write-Host '==> Deploying Argo toolchain'
|
|
21
|
+
|
|
22
|
+
$schemaSrc = Join-Path $argoDir 'schema'
|
|
23
|
+
$schemaDest = Join-Path $ArgoRoot 'schema'
|
|
24
|
+
Write-Host "[1/4] argo\schema -> $schemaDest"
|
|
25
|
+
Copy-Tree -Source $schemaSrc -Destination $schemaDest
|
|
26
|
+
|
|
27
|
+
$scriptsSrc = Join-Path $argoDir 'scripts'
|
|
28
|
+
$scriptsDest = Join-Path $ArgoRoot 'scripts'
|
|
29
|
+
Write-Host "[2/4] argo\scripts -> $scriptsDest"
|
|
30
|
+
Copy-Tree -Source $scriptsSrc -Destination $scriptsDest
|
|
31
|
+
|
|
32
|
+
$skillSrc = Join-Path (Join-Path $argoDir 'skills') 'argo-init'
|
|
33
|
+
$skillDest = Join-Path $SkillsRoot 'argo-init'
|
|
34
|
+
Write-Host "[3/4] argo\skills\argo-init -> $skillDest"
|
|
35
|
+
Copy-Tree -Source $skillSrc -Destination $skillDest
|
|
36
|
+
|
|
37
|
+
$ruleSrc = Join-Path (Join-Path $argoDir 'rules') 'intent-architecture-global-rule.md'
|
|
38
|
+
$ruleDest = Join-Path $PromptsRoot 'intent-architecture-global-rule.md'
|
|
39
|
+
Write-Host "[4/4] argo\rules\intent-architecture-global-rule.md -> $ruleDest"
|
|
40
|
+
New-Item -ItemType Directory -Force -Path $PromptsRoot | Out-Null
|
|
41
|
+
Copy-Item -Force -Path $ruleSrc -Destination $ruleDest
|
|
42
|
+
|
|
43
|
+
$depsSrc = Join-Path $argoDir 'package.json'
|
|
44
|
+
$depsDest = Join-Path $ArgoRoot 'package.json'
|
|
45
|
+
Write-Host "[5/5] argo\package.json -> $depsDest"
|
|
46
|
+
Copy-Item -Force -Path $depsSrc -Destination $depsDest
|
|
47
|
+
|
|
48
|
+
if ($SkipDeps) {
|
|
49
|
+
Write-Host 'Skipped dependency install (-SkipDeps).'
|
|
50
|
+
} elseif (Get-Command npm -ErrorAction SilentlyContinue) {
|
|
51
|
+
Write-Host "==> Installing Node dependencies in $ArgoRoot"
|
|
52
|
+
$vendorDir = Join-Path $PSScriptRoot 'vendor'
|
|
53
|
+
Push-Location $ArgoRoot
|
|
54
|
+
try {
|
|
55
|
+
$vendorTgzs = @(Get-ChildItem -Path $vendorDir -Filter '*.tgz' -ErrorAction SilentlyContinue)
|
|
56
|
+
if ($vendorTgzs.Count -gt 0) {
|
|
57
|
+
foreach ($tgz in $vendorTgzs) {
|
|
58
|
+
Write-Host " installing bundled $($tgz.Name)"
|
|
59
|
+
npm install --no-save --omit=dev --no-audit --no-fund $tgz.FullName
|
|
60
|
+
if ($LASTEXITCODE -ne 0) {
|
|
61
|
+
throw "npm install $($tgz.Name) failed with exit code $LASTEXITCODE"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
npm install --omit=dev --no-audit --no-fund
|
|
66
|
+
if ($LASTEXITCODE -ne 0) {
|
|
67
|
+
throw "npm install failed with exit code $LASTEXITCODE"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} finally {
|
|
71
|
+
Pop-Location
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
Write-Warning 'npm was not found on PATH; skipped dependency install.'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if ($SkipEnv) {
|
|
78
|
+
Write-Host 'Skipped .env generation (-SkipEnv).'
|
|
79
|
+
} else {
|
|
80
|
+
Write-Host ''
|
|
81
|
+
Write-Host '==> Configure .env (press Enter to leave a value empty and fill it later)'
|
|
82
|
+
$envKeys = @(
|
|
83
|
+
'ARGO_EMBEDDING_BASE_URL',
|
|
84
|
+
'ARGO_EMBEDDING_MODEL',
|
|
85
|
+
'ARGO_EMBEDDING_PROVIDER',
|
|
86
|
+
'ARGO_EMBEDDING_MODEL_VERSION',
|
|
87
|
+
'ARGO_EMBEDDING_DIMENSIONS',
|
|
88
|
+
'ARGO_NEO4J_DATABASE_URL',
|
|
89
|
+
'ARGO_NEO4J_DATABASE_USERNAME',
|
|
90
|
+
'ARGO_NEO4J_DATABASE_PASSWORD',
|
|
91
|
+
'QWEN_KEY',
|
|
92
|
+
'ARGO_LIVE_PROVIDER_E2E',
|
|
93
|
+
'ARGO_W31_LIVE_MUTATION_VECTOR_E2E'
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
$lines = @('# Argo live-provider and Neo4j configuration.')
|
|
97
|
+
foreach ($key in $envKeys) {
|
|
98
|
+
$value = Read-Host $key
|
|
99
|
+
$lines += "$key=$value"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
$envPath = Join-Path $ArgoRoot '.env'
|
|
103
|
+
[System.IO.File]::WriteAllLines(
|
|
104
|
+
$envPath,
|
|
105
|
+
$lines,
|
|
106
|
+
(New-Object System.Text.UTF8Encoding $false)
|
|
107
|
+
)
|
|
108
|
+
Write-Host "Wrote $envPath"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
Write-Host ''
|
|
112
|
+
Write-Host 'Argo deployment complete.'
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "archgraph-argo",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"argo-deploy": "bin/argo-deploy.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"argo/scripts",
|
|
11
|
+
"argo/schema",
|
|
12
|
+
"argo/skills/argo-init",
|
|
13
|
+
"argo/rules",
|
|
14
|
+
"argo/package.json",
|
|
15
|
+
"vendor",
|
|
16
|
+
"install-argo.ps1",
|
|
17
|
+
"bin"
|
|
18
|
+
],
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"neo4j-driver": "^6.2.0"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "node --test \"tests/*.test.js\""
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
Binary file
|