archgraph-argo 0.15.0 → 0.15.2

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.
@@ -18,11 +18,13 @@
18
18
  // canonical proposal — it is only counted (layoutOnly) and excluded.
19
19
  //
20
20
  // Zero third-party deps, no EA required: node:sqlite via the shared lib helper.
21
- // node argo/scripts/ea-human-diff.js --base <base.qea> --work <work.qea> [--graph <json>]
21
+ // node argo/scripts/ea-human-diff.js [--work <work.qea>] [--base <base.qea>] [--graph <json>]
22
22
  // [--out <stem>] [--no-md] [--baseline-commit <sha>]
23
+ // --work defaults to the CURRENT PROJECT's root single *.qea (ARGO_EA_QEA > 仓库根唯一 *.qea),
24
+ // never a hardcoded filename — the flow works in any ArchGraph workspace.
23
25
  // --base is optional: when omitted and --work is a tracked file inside the git repo,
24
26
  // the committed (HEAD) version of --work is extracted automatically as the baseline —
25
- // the day-to-day "human edited archgraph.qea" flow is then a single command.
27
+ // the day-to-day "human edited <project>.qea" flow is then a single command.
26
28
 
27
29
  const path = require('node:path');
28
30
  const fs = require('node:fs');
@@ -523,6 +525,24 @@ function gitShowHeadBlob(relPath) {
523
525
  const { execFileSync } = require('node:child_process');
524
526
  return execFileSync('git', ['cat-file', 'blob', 'HEAD:' + relPath], { maxBuffer: 512 * 1024 * 1024 });
525
527
  }
528
+ function gitToplevel() {
529
+ const { execFileSync } = require('node:child_process');
530
+ try {
531
+ return execFileSync('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
532
+ } catch { return ''; }
533
+ }
534
+ // Resolve the CURRENT PROJECT's .qea (same convention as the projection):
535
+ // ARGO_EA_QEA env > exactly one *.qea at the git top-level (else cwd).
536
+ // Called when --work is omitted so the day-to-day command never hardcodes a filename.
537
+ function resolveProjectQea() {
538
+ if (process.env.ARGO_EA_QEA) { return process.env.ARGO_EA_QEA; }
539
+ const root = gitToplevel() || process.cwd();
540
+ let qeas = [];
541
+ try { qeas = fs.readdirSync(root).filter((f) => f.toLowerCase().endsWith('.qea')); } catch { qeas = []; }
542
+ if (qeas.length === 1) { return path.join(root, qeas[0]); }
543
+ return '';
544
+ }
545
+
526
546
  function resolveAutoBase(workPath) {
527
547
  const { execFileSync } = require('node:child_process');
528
548
  const workAbs = path.resolve(process.cwd(), workPath);
@@ -551,9 +571,13 @@ function resolveAutoBase(workPath) {
551
571
 
552
572
  function main() {
553
573
  const args = parseArgs(process.argv.slice(2));
574
+ if (!args.work) {
575
+ const auto = resolveProjectQea();
576
+ if (auto) { args.work = auto; }
577
+ }
554
578
  if (!args.base && !args.work) {
555
- console.error('usage: node argo/scripts/ea-human-diff.js --base <base.qea> --work <work.qea> [--graph <json>] [--out <stem>] [--baseline-commit <sha>] [--no-md]');
556
- console.error(' (--base optional: when omitted the committed HEAD version of --work is used as baseline)');
579
+ console.error('usage: node argo/scripts/ea-human-diff.js [--base <base.qea>] [--work <work.qea>] [--graph <json>] [--out <stem>] [--baseline-commit <sha>] [--no-md]');
580
+ console.error(' (--work optional: defaults to the current project root single *.qea; --base optional: the committed HEAD version of --work is the baseline)');
557
581
  process.exit(2);
558
582
  }
559
583
  if (args.base === '' && args.work) {
@@ -22,6 +22,10 @@ const crypto = require('node:crypto');
22
22
 
23
23
  const SYNC_PACKAGE_NAME = 'ArchGraph Sync';
24
24
  const DIAGRAM_TYPE = 'Logical';
25
+ // Attributes/Operations "Show Compartments" (Elements tab) default unchecked: EA stores
26
+ // these in t_diagram.PDATA as HideAtts / HideOps (hide compartment = 1). Projected
27
+ // diagrams hide both compartments by default while preserving EA's other PDATA tokens.
28
+ const DIAGRAM_DISPLAY_DEFAULT = 'HideAtts=1;HideOps=1;';
25
29
  const META_TABLE = 'kg_sync_meta'; // {kind,key,sha,payload} — Node export/reconcile store
26
30
  const BUSY_TIMEOUT_MS = 15000;
27
31
  const CHUNK = 200;
@@ -538,7 +542,7 @@ function syncGraphToQea(graph, qeaPath, opts) {
538
542
  // it touches an open project and DROPS unknown tokens like schema_view_id — if we
539
543
  // only matched by the token we would re-INSERT the same deterministic ea_guid and
540
544
  // crash on t_diagram's UNIQUE(ea_guid) (projection failure: Neo4j ok, EA stale).
541
- const existingDiags = db.prepare('SELECT Diagram_ID, Package_ID, Name, StyleEx, ea_guid FROM t_diagram WHERE Package_ID=?').all(syncId);
545
+ const existingDiags = db.prepare('SELECT Diagram_ID, Package_ID, Name, StyleEx, PDATA, ea_guid FROM t_diagram WHERE Package_ID=?').all(syncId);
542
546
  const diagByView = new Map();
543
547
  const diagByGuid = new Map();
544
548
  for (const d of existingDiags) {
@@ -567,6 +571,7 @@ function syncGraphToQea(graph, qeaPath, opts) {
567
571
  ParentID: parentObjectId,
568
572
  Notes: '', // EA .qea 不保留多段 Notes;视图内容经 kg_sync_meta 保真
569
573
  StyleEx: styleEx,
574
+ PDATA: DIAGRAM_DISPLAY_DEFAULT,
570
575
  };
571
576
  if (existing) {
572
577
  diagViewRows.set(viewId, existing);
@@ -577,11 +582,17 @@ function syncGraphToQea(graph, qeaPath, opts) {
577
582
  setStyleToken(existing.StyleEx, 'DLKO', '1'),
578
583
  'schema_view_id=' + viewId
579
584
  );
580
- const changed = intended.Name !== (existing.Name || '') || (existing.StyleEx || '') !== anchoredStyleEx;
585
+ // Default Attributes/Operations compartments unchecked: force HideAtts=1 /
586
+ // HideOps=1 into PDATA while preserving EA's other display tokens.
587
+ const anchoredPdata = setStyleToken(
588
+ setStyleToken(existing.PDATA, 'HideAtts', '1'),
589
+ 'HideOps', '1'
590
+ );
591
+ const changed = intended.Name !== (existing.Name || '') || (existing.StyleEx || '') !== anchoredStyleEx || (existing.PDATA || '') !== anchoredPdata;
581
592
  if (DEBUG && changed) { console.error('DEBUG diagram chg', viewId, JSON.stringify({n:[intended.Name,(existing.Name||'')], style: !!parseStyleToken(existing.StyleEx,'schema_view_id')})); }
582
593
  if (changed && !o.dryRun) {
583
- db.prepare('UPDATE t_diagram SET Name=?, StyleEx=? WHERE Diagram_ID=?')
584
- .run(intended.Name, anchoredStyleEx, Number(existing.Diagram_ID));
594
+ db.prepare('UPDATE t_diagram SET Name=?, StyleEx=?, PDATA=? WHERE Diagram_ID=?')
595
+ .run(intended.Name, anchoredStyleEx, anchoredPdata, Number(existing.Diagram_ID));
585
596
  }
586
597
  stats[changed ? 'updated' : 'skipped'].diagrams++;
587
598
  } else {
@@ -592,7 +603,7 @@ function syncGraphToQea(graph, qeaPath, opts) {
592
603
  const diagAliasToId = new Map();
593
604
  if (!o.dryRun) {
594
605
  if (newDiags.length > 0) {
595
- insertMany(db, 't_diagram', ['Name', 'Diagram_Type', 'Package_ID', 'ParentID', 'StyleEx', 'ea_guid'], newDiags);
606
+ insertMany(db, 't_diagram', ['Name', 'Diagram_Type', 'Package_ID', 'ParentID', 'StyleEx', 'PDATA', 'ea_guid'], newDiags);
596
607
  }
597
608
  for (let i = 0; i < newDiags.length; i += 200) {
598
609
  const part = newDiags.slice(i, i + 200);
@@ -1,21 +1,21 @@
1
1
  ---
2
2
  name: ea-human-draft
3
- description: "把人类在 EA 里对 .qea 的草稿改动收敛进正式图谱(WP2792 draft-proposal 流程):① 断言前提(EA 已关闭 / .qea 可还原 / 工具存在)→ ② 用 ea-human-diff 提取语义 diff 提议(JSON+Markdown,读 EA 可见对象模型、不读 kg_sync_meta、纯几何不产出)→ ③ git restore 还原 .qea 到上次提交 → ④ 把提议交给 agent/人类伙伴,按其指引经 ARGO preview/apply 写回 canonical JSON(自动增量投影回 .qea 并 commit)。Use when 人类专家用 Sparx EA 直接改了 archgraph.qea 需要并入正式图谱、提取人类 EA 改动的语义 diff、把 .qea 还原回已提交状态、或按 draft-proposal 收敛人类草稿。Keywords: EA 人类草稿, human draft, semantic diff, ea-human-diff, draft-proposal, reverse-ea2kg, 人类参与建图."
3
+ description: "把人类在 EA 里对当前项目 .qea 的草稿改动收敛进正式图谱(WP2792 draft-proposal 流程):① 断言前提(EA 已关闭 / 项目根唯一 *.qea 可还原 / 工具存在)→ ② 用 ea-human-diff 提取语义 diff 提议(默认自动发现当前项目根唯一 *.qea,JSON+Markdown,读 EA 可见对象模型、不读 kg_sync_meta、纯几何不产出)→ ③ git restore 还原 .qea 到上次提交 → ④ 把提议交给 agent/人类伙伴,按其指引经 ARGO preview/apply 写回 canonical JSON(自动增量投影回 .qea 并 commit)。Use when 人类专家用 Sparx EA 直接改了当前项目的 .qea 需要并入正式图谱、提取人类 EA 改动的语义 diff、把 .qea 还原回已提交状态、或按 draft-proposal 收敛人类草稿。Keywords: EA 人类草稿, human draft, semantic diff, ea-human-diff, draft-proposal, reverse-ea2kg, 人类参与建图."
4
4
  argument-hint: 人类 EA 草稿收敛
5
5
  ---
6
6
 
7
7
  # EA HUMAN DRAFT(人类 EA 草稿 → 语义 diff → 写回图谱)
8
8
 
9
- 定位:**EA 只当草稿纸**,`design/KG/SystemArchitecture.json` 是唯一真源。人类在 agent 空闲间隙用 EA `archgraph.qea`;本技能负责把人类改动**安全地提取为提议**(断言 + diff + 还原),并把提议交给 agent/人类伙伴,按其指引经 ARGO 写回 canonical——不建立有损的全自动 EA→JSON 反向投影。
9
+ 定位:**EA 只当草稿纸**,`design/KG/SystemArchitecture.json` 是唯一真源。人类在 agent 空闲间隙用 EA 改**当前项目的 `.qea`**(即仓库根的唯一 `*.qea`,不限定文件名);本技能负责把人类改动**安全地提取为提议**(断言 + diff + 还原),并把提议交给 agent/人类伙伴,按其指引经 ARGO 写回 canonical——不建立有损的全自动 EA→JSON 反向投影。
10
10
 
11
- 依赖工具:`argo/scripts/ea-human-diff.js`(仓库内)或部署版 `~/.argo/scripts/ea-human-diff.js`(随 `archgraph-argo` npm 包发布)。`--base` 可省略:自动取 git HEAD 里 `--work` 的版本作基线。
11
+ 依赖工具:`argo/scripts/ea-human-diff.js`(仓库内)或部署版 `~/.argo/scripts/ea-human-diff.js`(随 `archgraph-argo` npm 包发布)。`--work` 默认指向**当前项目根唯一 `*.qea`**(自动发现,`ARGO_EA_QEA` > 仓库根唯一 `*.qea`),`--base` 可省略:自动取 git HEAD 里 `--work` 的版本作基线。
12
12
 
13
13
  ## 前置(Assert —— 全部满足才继续,任一失败即停下报告)
14
14
 
15
- - [ ] 工作区含 `design/KG/SystemArchitecture.json` `archgraph.qea` 被 git 跟踪(`git ls-files archgraph.qea` 有输出)。
15
+ - [ ] 工作区含 `design/KG/SystemArchitecture.json`,且存在仓库根唯一 `*.qea`(自动发现:`Get-ChildItem *.qea` 恰一个,或 `$env:ARGO_EA_QEA` 已设)。该 `.qea` 被 git 跟踪(`git ls-files <该qea>` 有输出)。
16
16
  - [ ] diff 工具存在:仓库 `argo/scripts/ea-human-diff.js` 或部署 `~/.argo/scripts/ea-human-diff.js`。
17
17
  - [ ] **EA 已完全关闭**(人类改动已保存落盘)——否则读到的不是最终状态,且 `git restore` 可能被文件锁破坏/EA 关盘重写。
18
- - [ ] git 可用;`HEAD` 中存在 `archgraph.qea`(自动基线依赖)。若人类还没开改(`git status --short archgraph.qea` 为空)→ 说明:需先在 EA 里改、保存、关闭后再回来。
18
+ - [ ] git 可用;`HEAD` 中存在该 `.qea`(自动基线依赖)。若人类还没开改(`git status --short <该qea>` 为空)→ 说明:需先在 EA 里改、保存、关闭后再回来。
19
19
 
20
20
  Windows 可选核实无进程持有:
21
21
  ```powershell
@@ -28,21 +28,21 @@ Get-Process EA -ErrorAction SilentlyContinue # 有输出则先关闭 EA
28
28
  逐条检查上方前置并报告结果。任一失败 → 停下,不做 diff、不做 revert。
29
29
 
30
30
  ### 2 · 提取语义 diff
31
- 仓库根执行(自动基线 = git HEAD 里的 `archgraph.qea`):
31
+ 仓库根执行(`--work` 默认 = 当前项目根唯一 `*.qea`,无需写死文件名;`--base` 省略 = git HEAD 版本):
32
32
  ```powershell
33
- node argo/scripts/ea-human-diff.js --work archgraph.qea --out results/human-draft
33
+ node argo/scripts/ea-human-diff.js --out results/human-draft
34
34
  ```
35
35
  产物:
36
36
  - `results/human-draft.json` —— 机器提议集(`proposals[]`:`op`/`kind`/`id`/`fields`/`proposed`/`sourceEa` 等 + `summary`)。
37
37
  - `results/human-draft.md` —— 人读摘要(分类表格 + 逐条明细 + EA guid 溯源)。
38
38
 
39
39
  先给人伙伴看 `human-draft.md`:确认是预期改动、无意外删除;留意 `layoutOnly` / `outOfScopeNew` / `removedUnanchored` 计数(这些不产出提议)。
40
- `--work` 不是 git 跟踪文件(如临时副本),须显式 `--base <committed.qea>`,不能用自动基线。
40
+ 若仓库根有多个 `*.qea` 或未自动发现,须显式 `--work <项目.qea>`;若 `--work` 不是 git 跟踪文件(如临时副本),须显式 `--base <committed.qea>`,不能用自动基线。
41
41
 
42
42
  ### 3 · 还原 .qea 到上次提交
43
43
  ```powershell
44
- git restore archgraph.qea
45
- git status --short # 应只剩 results/human-draft.* 等产物,archgraph.qea 不再 dirty
44
+ git restore <项目.qea>
45
+ git status --short # 应只剩 results/human-draft.* 等产物,<项目.qea> 不再 dirty
46
46
  ```
47
47
  目的:把 `.qea` 拉回与 HEAD 一致,杜绝残留分叉;人类草稿只以提议文件形式存在,避免后续 agent 写图触发投影时静默覆盖/合并混乱。
48
48
 
@@ -57,7 +57,7 @@ git status --short # 应只剩 results/human-draft.* 等产物,archgraph.q
57
57
 
58
58
  - **MUST** 只在 EA 关闭后运行;diff 前先做断言并报告。
59
59
  - **MUST** diff 以 EA **可见对象模型**(`schema_id` 锚 tag 对齐)为准;**绝不**用 `kg_sync_meta` 判定人类改动(人类改动不进镜像)。
60
- - **MUST** 提取 diff 后先 `git restore archgraph.qea` 再进入写回阶段,避免 qea 侧残留被后续投影覆盖/丢失。
60
+ - **MUST** 提取 diff 后先 `git restore <项目.qea>` 再进入写回阶段,避免 qea 侧残留被后续投影覆盖/丢失。
61
61
  - **MUST** 把每条**删除**提议(removeElement/removeRelationship)标记为需人类/负责 agent 确认后再 apply。
62
62
  - **MUST NOT** 把 `human-draft.json` 当 canonical 直接写——必须先 ARGO `preview` 校验,再 `apply`。
63
63
  - **MUST NOT** 在 `.qea` 上手工写 canonical 内容(唯一写回通道是 canonical JSON → 自动增量投影)。
@@ -73,7 +73,7 @@ git status --short # 应只剩 results/human-draft.* 等产物,archgraph.q
73
73
 
74
74
  ## 故障排查
75
75
 
76
- - `git HEAD has no tracked file "..."`:`--work` 未被 git 跟踪 → 显式 `--base <committed.qea>`。
76
+ - `git HEAD has no tracked file "<项目.qea>"`:`--work` 未被 git 跟踪 → 显式 `--base <committed.qea>`。
77
77
  - `git restore` 失败/文件锁:EA 还开着 → 关闭 EA 后重试。
78
78
  - diff 为空但人类确实改过:多半只做了纯几何或超出 canonical 作用域改动 → 看 `.md` 的 `layoutOnly` / `outOfScopeNew` 计数。
79
79
  - 关系侧提议异常(id 为 undefined):确认基线 .qea 由投影生成(`t_connectortag` 带 `schema_id`),手绘模型无锚时关系不参与。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archgraph-argo",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
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": {