archgraph-argo 0.11.0 → 0.12.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.
@@ -1,7 +1,8 @@
1
1
  const fs = require('node:fs');
2
2
  const path = require('node:path');
3
3
  const readline = require('node:readline');
4
- const { AsyncLocalStorage } = require('node:async_hooks');
4
+ const { AsyncLocalStorage } = require('node:async_hooks');
5
+ const { spawnSync } = require('node:child_process');
5
6
 
6
7
  const validatorMcp = require('./validator-mcp-server.js');
7
8
  const systemArchitectureMcp = require('./systemarchitecture-mcp-server.js');
@@ -395,7 +396,8 @@ async function callTool(name, args = {}, progressToken = null, dependencies = un
395
396
  mcp: report.mcp,
396
397
  systemArchitecture: report.systemArchitecture,
397
398
  subdiagramViews: report.subdiagramViews,
398
- neo4j: report.neo4j,
399
+ neo4j: report.neo4j,
400
+ qeaFullProjection: workspace.qeaFullProjection,
399
401
  semanticLifecycle: report.semanticLifecycle,
400
402
  semanticState: report.semanticLifecycle && report.semanticLifecycle.state,
401
403
  alignment: report.semanticLifecycle && report.semanticLifecycle.alignment,
@@ -418,6 +420,48 @@ async function withCanonicalSemanticInitTestComposition(composition, callback) {
418
420
  return canonicalSemanticInitStorage.run(Object.freeze({ ...composition }), callback);
419
421
  }
420
422
 
423
+ function resolveQeaProjectionTarget(workspaceRoot) {
424
+ try {
425
+ if (!workspaceRoot || !fs.existsSync(workspaceRoot)) { return null; }
426
+ const pick = (p) => (p && fs.existsSync(p) ? path.resolve(p) : null);
427
+ const qeaPath = pick(process.env.ARGO_EA_QEA);
428
+ if (qeaPath) { return { qeaPath, workspaceRoot }; }
429
+ let qeas = [];
430
+ try { qeas = fs.readdirSync(workspaceRoot).filter((n) => n.toLowerCase().endsWith('.qea')); } catch { /* ignore */ }
431
+ if (qeas.length === 1) { return { qeaPath: path.resolve(workspaceRoot, qeas[0]), workspaceRoot }; }
432
+ console.log('[ea-qea] init projection target: none' + (qeas.length > 1 ? ' (' + qeas.length + ' *.qea found; expected exactly one or ARGO_EA_QEA)' : '') + ' in ' + workspaceRoot);
433
+ return null;
434
+ } catch (error) {
435
+ console.log('[ea-qea] init projection target resolution failed: ' + String(error && error.message ? error.message : error));
436
+ return null;
437
+ }
438
+ }
439
+
440
+ // argo init .qea FULL projection (mirrors Neo4j initial full sync): wipes the whole target
441
+ // .qea then rebuilds it purely from the canonical graph. Non-fatal by contract.
442
+ function runQeaFullProjection(workspaceRoot, graphTargetPath) {
443
+ const target = resolveQeaProjectionTarget(workspaceRoot);
444
+ const script = path.join(__dirname, 'ea-qea-sync.js');
445
+ if (!target || !fs.existsSync(script)) {
446
+ return { status: 'noop', reason: !target ? 'no .qea target (env ARGO_EA_QEA or exactly one root *.qea)' : 'argo/scripts/ea-qea-sync.js missing' };
447
+ }
448
+ const snapshotDir = path.join(workspaceRoot, '.argo', 'temp', 'qea-backups');
449
+ const args = [script, '--mode', 'full', '--graph', graphTargetPath, '--qea', target.qeaPath, '--snapshot-dir', snapshotDir];
450
+ const started = Date.now();
451
+ try {
452
+ const res = spawnSync(process.execPath, args, { cwd: workspaceRoot, encoding: 'utf8', windowsHide: true, timeout: 120000 });
453
+ const ok = res.status === 0;
454
+ return {
455
+ status: ok ? 'ok' : 'failed',
456
+ qea: target.qeaPath,
457
+ ms: Date.now() - started,
458
+ ...(ok ? {} : { error: String((res.stderr || '').slice(0, 600) || ('exit ' + res.status)) }),
459
+ };
460
+ } catch (error) {
461
+ return { status: 'failed', qea: target.qeaPath, ms: Date.now() - started, error: String(error && error.message ? error.message : error) };
462
+ }
463
+ }
464
+
421
465
  async function initializeWorkspace(workspaceRoot) {
422
466
  const workspaceName = path.basename(workspaceRoot);
423
467
  const createdFiles = [];
@@ -454,8 +498,17 @@ async function initializeWorkspace(workspaceRoot) {
454
498
  }
455
499
  }
456
500
 
501
+ // WP2791: init .qea FULL projection (parallel to Neo4j initial full sync in the harness
502
+ // report). Non-fatal: a qea failure must never fail workspace init.
503
+ let qeaFullProjection = null;
504
+ try {
505
+ qeaFullProjection = runQeaFullProjection(workspaceRoot, graphTargetPath);
506
+ } catch (error) {
507
+ qeaFullProjection = { status: 'failed', error: String(error && error.message ? error.message : error) };
508
+ }
457
509
  return {
458
- workspaceRoot,
510
+ workspaceRoot,
511
+ qeaFullProjection,
459
512
  targetFeapName,
460
513
  createdFiles,
461
514
  updatedFiles,