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 --
|
|
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
|
|
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(' (--
|
|
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
|
-
|
|
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
|
|
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
|
|
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`
|
|
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`
|
|
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
|
-
|
|
31
|
+
仓库根执行(`--work` 默认 = 当前项目根唯一 `*.qea`,无需写死文件名;`--base` 省略 = git HEAD 版本):
|
|
32
32
|
```powershell
|
|
33
|
-
node argo/scripts/ea-human-diff.js --
|
|
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
|
-
|
|
40
|
+
若仓库根有多个 `*.qea` 或未自动发现,须显式 `--work <项目.qea>`;若 `--work` 不是 git 跟踪文件(如临时副本),须显式 `--base <committed.qea>`,不能用自动基线。
|
|
41
41
|
|
|
42
42
|
### 3 · 还原 .qea 到上次提交
|
|
43
43
|
```powershell
|
|
44
|
-
git restore
|
|
45
|
-
git status --short # 应只剩 results/human-draft.*
|
|
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
|
|
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 "
|
|
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