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.
Files changed (54) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +115 -0
  3. package/argo/package.json +8 -0
  4. package/argo/rules/intent-architecture-global-rule.md +45 -0
  5. package/argo/schema/ImplementationToCodingHandoff.schema.json +252 -0
  6. package/argo/schema/ImplementationToIntentTraceProposal.schema.json +180 -0
  7. package/argo/schema/IntentToImplementationHandoff.schema.json +75 -0
  8. package/argo/schema/SystemArchitecture.schema.json +378 -0
  9. package/argo/schema/archimate3.2.pdf +0 -0
  10. package/argo/scripts/ARCHITECTURE.md +57 -0
  11. package/argo/scripts/archimate32-rules.js +12301 -0
  12. package/argo/scripts/argo-mcp-server.js +629 -0
  13. package/argo/scripts/argo-paths.js +77 -0
  14. package/argo/scripts/ensureArgoHarnessEnvironment.js +340 -0
  15. package/argo/scripts/generateArchitectureDiffPlantuml.js +466 -0
  16. package/argo/scripts/graph-rag/ARCHITECTURE.md +192 -0
  17. package/argo/scripts/graph-rag/canonicalProjectionAuthority.js +45 -0
  18. package/argo/scripts/graph-rag/defaultSemanticRetrieval.js +969 -0
  19. package/argo/scripts/graph-rag/embeddingQualificationGate.js +59 -0
  20. package/argo/scripts/graph-rag/externalProductionConfig.js +74 -0
  21. package/argo/scripts/graph-rag/liveEmbeddingIndexGate.js +129 -0
  22. package/argo/scripts/graph-rag/liveEmbeddingNeo4jBoundary.js +137 -0
  23. package/argo/scripts/graph-rag/liveEmbeddingProviderClient.js +49 -0
  24. package/argo/scripts/graph-rag/liveEmbeddingProviderConfig.js +481 -0
  25. package/argo/scripts/graph-rag/mutationEmbeddingVectorLifecycle.js +1261 -0
  26. package/argo/scripts/graph-rag/neo4jNativeRetrieval.js +37 -0
  27. package/argo/scripts/graph-rag/productionGraphRagRuntime.js +1624 -0
  28. package/argo/scripts/graph-rag/semantic-persistence/ARCHITECTURE.md +51 -0
  29. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticBackfill.js +241 -0
  30. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticCheckpointStore.js +99 -0
  31. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticNeo4jAdapter.js +149 -0
  32. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticProjectionStore.js +171 -0
  33. package/argo/scripts/graph-rag/semanticOperatorError.js +38 -0
  34. package/argo/scripts/graph-rag/semanticOperatorJourney.js +459 -0
  35. package/argo/scripts/graph-rag/semanticReadinessAttestationStore.js +398 -0
  36. package/argo/scripts/graph-rag/systemMetadataCommandAdapter.js +269 -0
  37. package/argo/scripts/graph-semantics.js +220 -0
  38. package/argo/scripts/neo4j-system-architecture-store.js +777 -0
  39. package/argo/scripts/repositoryArgoEnvironment.js +101 -0
  40. package/argo/scripts/runArchitectureTests.js +583 -0
  41. package/argo/scripts/semanticOperatorJourneyCli.js +91 -0
  42. package/argo/scripts/syncSystemArchitectureToNeo4j.js +67 -0
  43. package/argo/scripts/systemarchitecture-mcp-server.js +2965 -0
  44. package/argo/scripts/test-executors/_template.js +58 -0
  45. package/argo/scripts/test-executors/default.js +199 -0
  46. package/argo/scripts/validateStageHandoff.js +459 -0
  47. package/argo/scripts/validateSystemArchitecture.js +254 -0
  48. package/argo/scripts/validateTraceProposal.js +181 -0
  49. package/argo/scripts/validator-mcp-server.js +377 -0
  50. package/argo/skills/argo-init/SKILL.md +110 -0
  51. package/bin/argo-deploy.js +12 -0
  52. package/install-argo.ps1 +112 -0
  53. package/package.json +28 -0
  54. package/vendor/neo4j-driver-6.2.0.tgz +0 -0
@@ -0,0 +1,340 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+ const { spawnSync } = require('node:child_process');
4
+
5
+ const argoMcp = require('./argo-mcp-server.js');
6
+ const systemArchitectureMcp = require('./systemarchitecture-mcp-server.js');
7
+ const {
8
+ runCanonicalSemanticInit,
9
+ } = require('./graph-rag/semanticOperatorJourney.js');
10
+ const {
11
+ DEFAULT_GRAPH_PATH,
12
+ createDriver,
13
+ ensureDatabaseExists,
14
+ getNeo4jConfig,
15
+ getNeo4jGraphSyncState,
16
+ syncArchitectureToNeo4j,
17
+ verifyArchitectureSync,
18
+ } = require('./neo4j-system-architecture-store.js');
19
+ const {
20
+ loadRepositoryArgoEnvironment,
21
+ } = require('./repositoryArgoEnvironment.js');
22
+ const {
23
+ getWorkspaceRoot,
24
+ resolveArgoPath,
25
+ } = require('./argo-paths.js');
26
+
27
+ const REQUIRED_TOOL_NAMES = [
28
+ 'getSystemArchitecture',
29
+ 'applySystemArchitectureMutation',
30
+ 'validateSystemArchitecture',
31
+ ];
32
+
33
+ async function main() {
34
+ const options = parseArgs(process.argv.slice(2));
35
+ const workspaceRoot = resolveWorkspaceRoot();
36
+ const reportPath = path.join(workspaceRoot, '.argo', 'temp', 'argo-harness-init-report.json');
37
+ const harnessEnvironment = loadRepositoryArgoEnvironment(workspaceRoot);
38
+ const report = {
39
+ status: 'ok',
40
+ workspaceRoot,
41
+ generatedAt: new Date().toISOString(),
42
+ mode: options.checkOnly ? 'check-only' : 'prepare-and-check',
43
+ reportPath: normalizeRelativePath(path.relative(workspaceRoot, reportPath)),
44
+ harnessEnvironment,
45
+ };
46
+
47
+ try {
48
+ report.mcp = verifyArgoMcpServer({ workspaceRoot });
49
+ report.systemArchitecture = await verifyCanonicalSystemArchitecture();
50
+ report.neo4j = await ensureNeo4jProjection({ checkOnly: options.checkOnly });
51
+ report.semanticLifecycle = await ensureCanonicalSemanticLifecycle({
52
+ checkOnly: options.checkOnly,
53
+ workspaceRoot,
54
+ neo4j: report.neo4j,
55
+ });
56
+ } catch (error) {
57
+ report.status = 'failed';
58
+ report.error = formatErrorForReport(error);
59
+ }
60
+
61
+ if (report.mcp && report.mcp.status === 'failed') {
62
+ report.status = 'failed';
63
+ }
64
+ if (report.systemArchitecture && report.systemArchitecture.status === 'failed') {
65
+ report.status = 'failed';
66
+ }
67
+ if (report.neo4j && report.neo4j.status === 'failed') {
68
+ report.status = 'failed';
69
+ }
70
+ if (report.semanticLifecycle && report.semanticLifecycle.status === 'failed') {
71
+ report.status = 'failed';
72
+ }
73
+
74
+ writeJson(reportPath, report);
75
+ console.log(JSON.stringify(report, null, 2));
76
+
77
+ if (report.status !== 'ok') {
78
+ process.exit(1);
79
+ }
80
+ }
81
+
82
+ function parseArgs(argv) {
83
+ const options = {
84
+ checkOnly: false,
85
+ };
86
+
87
+ for (const token of argv) {
88
+ if (token === '--check-only') {
89
+ options.checkOnly = true;
90
+ continue;
91
+ }
92
+ throw new Error(`Unsupported argument: ${token}`);
93
+ }
94
+
95
+ return options;
96
+ }
97
+
98
+ function resolveWorkspaceRoot() {
99
+ return getWorkspaceRoot();
100
+ }
101
+
102
+ async function ensureCanonicalSemanticLifecycle({ checkOnly, workspaceRoot, neo4j }) {
103
+ if (checkOnly) {
104
+ return {
105
+ status: 'skipped',
106
+ reason: 'check-only',
107
+ fullSnapshotFallback: false,
108
+ };
109
+ }
110
+
111
+ try {
112
+ const semanticLifecycle = await runCanonicalSemanticInit(
113
+ systemArchitectureMcp.createDefaultCanonicalSemanticInitComposition(),
114
+ {
115
+ repositoryRoot: workspaceRoot,
116
+ neo4j,
117
+ },
118
+ );
119
+ return {
120
+ status: 'ok',
121
+ state: semanticLifecycle.state,
122
+ alignment: semanticLifecycle.alignment,
123
+ readiness: semanticLifecycle.readiness,
124
+ fullSnapshotFallback: semanticLifecycle.fullSnapshotFallback === true,
125
+ };
126
+ } catch (error) {
127
+ return {
128
+ status: 'failed',
129
+ ...formatSemanticLifecycleError(error),
130
+ };
131
+ }
132
+ }
133
+
134
+ function verifyArgoMcpServer({ workspaceRoot }) {
135
+ const serverPath = resolveArgoPath('scripts', 'argo-mcp-server.js');
136
+ const requests = [
137
+ { jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'argo-init-skill', version: '1' } } },
138
+ { jsonrpc: '2.0', method: 'notifications/initialized', params: {} },
139
+ { jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} },
140
+ { jsonrpc: '2.0', id: 3, method: 'ping', params: {} },
141
+ ];
142
+ const input = `${requests.map(entry => JSON.stringify(entry)).join('\n')}\n`;
143
+ const result = spawnSync(process.execPath, [serverPath], {
144
+ cwd: workspaceRoot,
145
+ input,
146
+ encoding: 'utf8',
147
+ });
148
+
149
+ if (result.error) {
150
+ return {
151
+ status: 'failed',
152
+ error: String(result.error),
153
+ };
154
+ }
155
+ if (result.status !== 0) {
156
+ return {
157
+ status: 'failed',
158
+ error: result.stderr || `argo MCP exited with code ${result.status}`,
159
+ };
160
+ }
161
+
162
+ const responses = String(result.stdout || '')
163
+ .split(/\r?\n/)
164
+ .filter(line => line.trim())
165
+ .map(line => JSON.parse(line));
166
+ const initializeResponse = responses.find(entry => entry.id === 1);
167
+ const toolsListResponse = responses.find(entry => entry.id === 2);
168
+ const pingResponse = responses.find(entry => entry.id === 3);
169
+
170
+ if (!initializeResponse || !toolsListResponse || !pingResponse) {
171
+ return {
172
+ status: 'failed',
173
+ error: 'argo MCP did not return initialize/tools-list/ping responses as expected.',
174
+ };
175
+ }
176
+
177
+ const toolNames = (toolsListResponse.result && toolsListResponse.result.tools ? toolsListResponse.result.tools : [])
178
+ .map(tool => tool.name)
179
+ .sort();
180
+ const missingTools = REQUIRED_TOOL_NAMES.filter(name => !toolNames.includes(name));
181
+ if (missingTools.length > 0) {
182
+ return {
183
+ status: 'failed',
184
+ error: `argo MCP is missing required tools: ${missingTools.join(', ')}`,
185
+ toolCount: toolNames.length,
186
+ };
187
+ }
188
+
189
+ return {
190
+ status: 'ok',
191
+ protocolVersion: initializeResponse.result && initializeResponse.result.protocolVersion,
192
+ serverName: initializeResponse.result && initializeResponse.result.serverInfo && initializeResponse.result.serverInfo.name,
193
+ toolCount: toolNames.length,
194
+ checkedTools: REQUIRED_TOOL_NAMES,
195
+ ping: 'ok',
196
+ };
197
+ }
198
+
199
+ async function verifyCanonicalSystemArchitecture() {
200
+ const getResponse = await argoMcp.callTool('getSystemArchitecture', {
201
+ architecturePath: DEFAULT_GRAPH_PATH,
202
+ });
203
+ const getPayload = parseToolPayload(getResponse);
204
+ if (getPayload.status !== 'passed') {
205
+ return {
206
+ status: 'failed',
207
+ error: `getSystemArchitecture failed for ${DEFAULT_GRAPH_PATH}`,
208
+ payload: getPayload,
209
+ };
210
+ }
211
+
212
+ const validateResponse = await argoMcp.callTool('validateSystemArchitecture', {});
213
+ const validatePayload = parseToolPayload(validateResponse);
214
+ if (validatePayload.status !== 'passed') {
215
+ return {
216
+ status: 'failed',
217
+ graphPath: getPayload.graphPath,
218
+ error: 'validateSystemArchitecture reported errors.',
219
+ errors: validatePayload.errors || [],
220
+ };
221
+ }
222
+
223
+ return {
224
+ status: 'ok',
225
+ graphPath: getPayload.graphPath,
226
+ elementCount: Array.isArray(getPayload.document && getPayload.document.elements) ? getPayload.document.elements.length : 0,
227
+ relationshipCount: Array.isArray(getPayload.document && getPayload.document.relationships) ? getPayload.document.relationships.length : 0,
228
+ viewCount: Array.isArray(getPayload.document && getPayload.document.views) ? getPayload.document.views.length : 0,
229
+ neo4jRecovery: getPayload.neo4jRecovery || null,
230
+ };
231
+ }
232
+
233
+ async function ensureNeo4jProjection({ checkOnly }) {
234
+ const config = getNeo4jConfig();
235
+ const dirtyBefore = getNeo4jGraphSyncState(DEFAULT_GRAPH_PATH);
236
+ const driver = createDriver(config);
237
+ let databaseProvision = null;
238
+ try {
239
+ await driver.verifyConnectivity();
240
+ if (!checkOnly) {
241
+ databaseProvision = await ensureDatabaseExists(driver, config.database);
242
+ }
243
+ } catch (error) {
244
+ await driver.close();
245
+ return {
246
+ status: 'failed',
247
+ uri: config.uri,
248
+ database: config.database,
249
+ dirtyBefore,
250
+ error: String(error && error.message ? error.message : error),
251
+ };
252
+ }
253
+
254
+ await driver.close();
255
+
256
+ let syncResult = null;
257
+ if (!checkOnly) {
258
+ syncResult = await syncArchitectureToNeo4j({ architecturePath: DEFAULT_GRAPH_PATH, ...config });
259
+ databaseProvision = syncResult.databaseProvision;
260
+ }
261
+
262
+ const verification = await verifyArchitectureSync({ architecturePath: DEFAULT_GRAPH_PATH, ...config });
263
+ if (!verification.matches) {
264
+ return {
265
+ status: 'failed',
266
+ uri: config.uri,
267
+ database: config.database,
268
+ databaseProvision: verification.databaseProvision || databaseProvision,
269
+ dirtyBefore,
270
+ initialSync: syncResult ? syncResult.counts : null,
271
+ verification,
272
+ };
273
+ }
274
+
275
+ return {
276
+ status: 'ok',
277
+ uri: config.uri,
278
+ database: config.database,
279
+ databaseProvision: verification.databaseProvision || databaseProvision,
280
+ dirtyBefore,
281
+ initialSync: syncResult ? {
282
+ graphKey: syncResult.graphKey,
283
+ counts: syncResult.counts,
284
+ } : null,
285
+ verification,
286
+ };
287
+ }
288
+
289
+ function formatSemanticLifecycleError(error) {
290
+ const payload = error && typeof error === 'object' ? error : {};
291
+ const category = typeof payload.category === 'string'
292
+ ? payload.category
293
+ : 'SEMANTIC_LIFECYCLE_INIT_FAILED';
294
+ const action = typeof payload.action === 'string'
295
+ ? payload.action
296
+ : 'Repair semantic lifecycle initialization, then run argo init again.';
297
+ const message = payload.safeSemanticLifecycleMessage === true && typeof payload.message === 'string'
298
+ ? payload.message
299
+ : (typeof payload.publicMessage === 'string'
300
+ ? payload.publicMessage
301
+ : 'Semantic lifecycle initialization failed.');
302
+ return {
303
+ category,
304
+ action,
305
+ message,
306
+ ...(typeof payload.field === 'string' ? { field: payload.field } : {}),
307
+ };
308
+ }
309
+
310
+ function parseToolPayload(result) {
311
+ if (!result || !Array.isArray(result.content) || result.content.length === 0) {
312
+ throw new Error('Unexpected MCP tool result shape.');
313
+ }
314
+ return JSON.parse(result.content[0].text);
315
+ }
316
+
317
+ function normalizeRelativePath(value) {
318
+ return String(value).replace(/\\/g, '/');
319
+ }
320
+
321
+ function writeJson(filePath, payload) {
322
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
323
+ fs.writeFileSync(filePath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
324
+ }
325
+
326
+ function formatErrorForReport(error) {
327
+ let message = String(error && error.stack ? error.stack : error);
328
+ for (const key of ['QWEN_KEY', 'ARGO_NEO4J_DATABASE_PASSWORD']) {
329
+ const value = process.env[key];
330
+ if (typeof value === 'string' && value.length > 0) {
331
+ message = message.split(value).join(`[REDACTED:${key}]`);
332
+ }
333
+ }
334
+ return message;
335
+ }
336
+
337
+ main().catch(error => {
338
+ console.error(formatErrorForReport(error));
339
+ process.exit(1);
340
+ });