@dawipong/opcflow 0.4.0 → 0.5.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 (98) hide show
  1. package/README.en.md +3 -1
  2. package/README.md +3 -2
  3. package/dist/cli.mjs +199 -20
  4. package/package.json +3 -1
  5. package/web/dist/assets/{abnfDiagram-VRR7QNED-DAx6EpGI.js → abnfDiagram-VRR7QNED-Cwj4KBKb.js} +1 -1
  6. package/web/dist/assets/{arc-DPoWLLje.js → arc-Ci--dbFA.js} +1 -1
  7. package/web/dist/assets/architecture-TIHT7OUA-Dx_ZsFnL.js +1 -0
  8. package/web/dist/assets/{architectureDiagram-ZJ3FMSHR-Dvr2nr59.js → architectureDiagram-ZJ3FMSHR-B83QZuM-.js} +2 -2
  9. package/web/dist/assets/{blockDiagram-677ZJIJ3-CUYUzMZC.js → blockDiagram-677ZJIJ3-C5lnvD0j.js} +1 -1
  10. package/web/dist/assets/{c4Diagram-LMCZKHZV-DhT2uxnj.js → c4Diagram-LMCZKHZV-Di1TmZQy.js} +1 -1
  11. package/web/dist/assets/channel-Bk0jbqCs.js +1 -0
  12. package/web/dist/assets/{chunk-32BRIVSS-CztnJRkA.js → chunk-32BRIVSS-BWSjcFoD.js} +1 -1
  13. package/web/dist/assets/{chunk-C7G6YPKG-jsbUGVSb.js → chunk-C7G6YPKG-DSkQqM00.js} +1 -1
  14. package/web/dist/assets/{chunk-EX3LRPZG-M3QhKBUG.js → chunk-EX3LRPZG-DOdm7LPI.js} +1 -1
  15. package/web/dist/assets/{chunk-HOUHSVGY-DDAtZMtg.js → chunk-HOUHSVGY-D1LueKb6.js} +1 -1
  16. package/web/dist/assets/{chunk-ICXQ74PX-C2h9d1ob.js → chunk-ICXQ74PX-CFh6Ch4J.js} +1 -1
  17. package/web/dist/assets/{chunk-MOJQB5TN-DXlFl9Jv.js → chunk-MOJQB5TN-BrFLYoih.js} +1 -1
  18. package/web/dist/assets/{chunk-OGEWGWER-B5mrusUD.js → chunk-OGEWGWER-C1n7EcC_.js} +1 -1
  19. package/web/dist/assets/{chunk-PUDLZKDR-BTWHaeTZ.js → chunk-PUDLZKDR-D4rKEnrx.js} +1 -1
  20. package/web/dist/assets/{chunk-Q4XR5HBZ-Cfw3UWMb.js → chunk-Q4XR5HBZ-DVm0yUET.js} +1 -1
  21. package/web/dist/assets/{chunk-RYQCIY6F-CCUojmgb.js → chunk-RYQCIY6F-BlZZOayN.js} +1 -1
  22. package/web/dist/assets/{chunk-V7JOEXUC-Cbgml1c1.js → chunk-V7JOEXUC-Bb-id9Vk.js} +1 -1
  23. package/web/dist/assets/{chunk-VR4S4FIN-CUMv178C.js → chunk-VR4S4FIN-DbbNoX70.js} +1 -1
  24. package/web/dist/assets/{chunk-WYO6CB5R-BaRUDpDl.js → chunk-WYO6CB5R-C0vPAP7X.js} +1 -1
  25. package/web/dist/assets/{chunk-XXDRQBXY-tmq33VNh.js → chunk-XXDRQBXY-BS9H__hw.js} +1 -1
  26. package/web/dist/assets/{chunk-ZGVPDNZ5-DK9a-Iwy.js → chunk-ZGVPDNZ5-BiBGMdZe.js} +1 -1
  27. package/web/dist/assets/classDiagram-OUVF2IWQ-XODf2seK.js +1 -0
  28. package/web/dist/assets/classDiagram-v2-EOCWNBFH-XODf2seK.js +1 -0
  29. package/web/dist/assets/{cose-bilkent-JH36ORCC-BV8ttTSE.js → cose-bilkent-JH36ORCC-TcTcCWyr.js} +1 -1
  30. package/web/dist/assets/{cynefin-VYW2F7L2-BncvlU8s.js → cynefin-VYW2F7L2-D6vfZhRU.js} +1 -1
  31. package/web/dist/assets/{cynefinDiagram-TSTJHNR4-DrrKaXmw.js → cynefinDiagram-TSTJHNR4-BQ_p-vVW.js} +1 -1
  32. package/web/dist/assets/{dagre-VKFMJZFB-BxDsa977.js → dagre-VKFMJZFB-sC49sUfv.js} +1 -1
  33. package/web/dist/assets/{diagram-FQU43EPY-DkeAFpQM.js → diagram-FQU43EPY-znBmjqaC.js} +1 -1
  34. package/web/dist/assets/{diagram-G47NLZAW-BxVnT5Li.js → diagram-G47NLZAW-BFZHUq5q.js} +1 -1
  35. package/web/dist/assets/{diagram-NH7WQ7WH-BT56mGuK.js → diagram-NH7WQ7WH-CnF3KhFt.js} +1 -1
  36. package/web/dist/assets/{diagram-OA4YK3LP-CezybdJA.js → diagram-OA4YK3LP-DyxQbSTl.js} +1 -1
  37. package/web/dist/assets/{diagram-WEI45ONY-CO8JNWNf.js → diagram-WEI45ONY-u45fnoLo.js} +1 -1
  38. package/web/dist/assets/{dist-zlHGdC4Y.js → dist-DeM6hNwF.js} +1 -1
  39. package/web/dist/assets/{ebnfDiagram-CCIWWBDH-B-OkdWz4.js → ebnfDiagram-CCIWWBDH-CRWFKre6.js} +1 -1
  40. package/web/dist/assets/{erDiagram-Q63AITRT-DQNn2L0y.js → erDiagram-Q63AITRT-BWW0EF63.js} +1 -1
  41. package/web/dist/assets/eventmodeling-45OFAUF4-C8O_2_YB.js +1 -0
  42. package/web/dist/assets/flowDiagram-23GEKE2U-ADg31f6W.js +1 -0
  43. package/web/dist/assets/{ganttDiagram-NO4QXBWP-CFmDEUpW.js → ganttDiagram-NO4QXBWP-Cs24RF6t.js} +2 -2
  44. package/web/dist/assets/{gitGraph-TEB2WS4Q-BiEBwxQy.js → gitGraph-TEB2WS4Q-CWN94LWl.js} +1 -1
  45. package/web/dist/assets/{gitGraphDiagram-IHSO6WYX--62v4OfD.js → gitGraphDiagram-IHSO6WYX-B_EZLwDH.js} +1 -1
  46. package/web/dist/assets/index-C58B02oD.css +1 -0
  47. package/web/dist/assets/index-Cf-76g9P.js +420 -0
  48. package/web/dist/assets/{info-DKCQHKI2-BLKxCcH7.js → info-DKCQHKI2-_3TeAGLT.js} +1 -1
  49. package/web/dist/assets/{infoDiagram-FWYZ7A6U-DM429PMt.js → infoDiagram-FWYZ7A6U-C2mnh_tb.js} +1 -1
  50. package/web/dist/assets/{ishikawaDiagram-FXEZZL3T-D-nr9wXb.js → ishikawaDiagram-FXEZZL3T-B_eQA-ns.js} +1 -1
  51. package/web/dist/assets/{journeyDiagram-5HDEW3XC-CsPvawEB.js → journeyDiagram-5HDEW3XC-pWgngszB.js} +1 -1
  52. package/web/dist/assets/{kanban-definition-HUTT4EX6-Cq6fbJBF.js → kanban-definition-HUTT4EX6-ov2PISLL.js} +1 -1
  53. package/web/dist/assets/{line-CE9BvxIa.js → line-DdBTKf-T.js} +1 -1
  54. package/web/dist/assets/linear-BcjVZ8a_.js +1 -0
  55. package/web/dist/assets/{mermaid-parser.core-CAAH_OSq.js → mermaid-parser.core-CICKlqAN.js} +3 -3
  56. package/web/dist/assets/{mindmap-definition-LN4V7U3C-zZ5w-lPU.js → mindmap-definition-LN4V7U3C-0NmEERgv.js} +1 -1
  57. package/web/dist/assets/{packet-7NZHBO7P-ap_XD9pB.js → packet-7NZHBO7P-TpNRNd61.js} +1 -1
  58. package/web/dist/assets/{pegDiagram-2B236MQR-BL13lL1j.js → pegDiagram-2B236MQR-CiAlAiVi.js} +1 -1
  59. package/web/dist/assets/{pie-RZYD4A2V-C7RWGzoe.js → pie-RZYD4A2V-x4UQuGC2.js} +1 -1
  60. package/web/dist/assets/{pieDiagram-ENE6RG2P-B1mmu34A.js → pieDiagram-ENE6RG2P-inbfmWLn.js} +1 -1
  61. package/web/dist/assets/{quadrantDiagram-ABIIQ3AL-CotpR7ZY.js → quadrantDiagram-ABIIQ3AL-BG-L4IlR.js} +1 -1
  62. package/web/dist/assets/{radar-I7S5WNFK-D8ICPnt1.js → radar-I7S5WNFK-ifrr9rf8.js} +1 -1
  63. package/web/dist/assets/{railroad-3IZDKUUU-B7ZJ3IRr.js → railroad-3IZDKUUU-3WK9FStR.js} +1 -1
  64. package/web/dist/assets/railroad-abnf-AHOZXSZD-DI7lfwbp.js +1 -0
  65. package/web/dist/assets/railroad-ebnf-EBAXGLYW-COZaOyR2.js +1 -0
  66. package/web/dist/assets/railroad-peg-LSFZ7HO6-BE8vI_mk.js +1 -0
  67. package/web/dist/assets/{railroadDiagram-RFXS5EU6-BUbf08v3.js → railroadDiagram-RFXS5EU6-zGdHxvjI.js} +1 -1
  68. package/web/dist/assets/{requirementDiagram-TGXJPOKE-CgepHMpy.js → requirementDiagram-TGXJPOKE-DYBqltr1.js} +1 -1
  69. package/web/dist/assets/{sankeyDiagram-HTMAVEWB-9CV0aY5J.js → sankeyDiagram-HTMAVEWB-Cwthl6yk.js} +1 -1
  70. package/web/dist/assets/{sequenceDiagram-DBY2YBRQ-CkIJuJ5O.js → sequenceDiagram-DBY2YBRQ-yoZvzY4D.js} +1 -1
  71. package/web/dist/assets/src-Bp5IDfvJ.js +1 -0
  72. package/web/dist/assets/{stateDiagram-2N3HPSRC-wX6zU3Hv.js → stateDiagram-2N3HPSRC-UXu_N6p7.js} +1 -1
  73. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-K2x-LOU8.js +1 -0
  74. package/web/dist/assets/{swimlanes-5IMT3BWC-YXgGP77C.js → swimlanes-5IMT3BWC-CJml4vNZ.js} +1 -1
  75. package/web/dist/assets/swimlanesDiagram-G3AALYLV-BJTq-tR6.js +8 -0
  76. package/web/dist/assets/{timeline-definition-FHXFAJF6-CtMf684d.js → timeline-definition-FHXFAJF6-DmHx8Bri.js} +1 -1
  77. package/web/dist/assets/{treeView-QDETBFTQ-lUySd_Pd.js → treeView-QDETBFTQ-CW1zfcRK.js} +1 -1
  78. package/web/dist/assets/{treemap-6X3UGDF4-BewRw9PG.js → treemap-6X3UGDF4-ReFheQXq.js} +1 -1
  79. package/web/dist/assets/{vennDiagram-L72KCM5P-DbFoFgBM.js → vennDiagram-L72KCM5P-jIe_jCw3.js} +1 -1
  80. package/web/dist/assets/{wardley-OPB4EBWU-BCrrgDHP.js → wardley-OPB4EBWU-DqwQFz9-.js} +1 -1
  81. package/web/dist/assets/{wardleyDiagram-EHGQE667-C3J4of-x.js → wardleyDiagram-EHGQE667-DEJFp47s.js} +1 -1
  82. package/web/dist/assets/{xychartDiagram-FW5EYKEG-Fbzeb84K.js → xychartDiagram-FW5EYKEG-DBBG2OXr.js} +1 -1
  83. package/web/dist/index.html +12 -12
  84. package/web/dist/assets/architecture-TIHT7OUA-Bgyz4pDY.js +0 -1
  85. package/web/dist/assets/channel-vHKEEV51.js +0 -1
  86. package/web/dist/assets/classDiagram-OUVF2IWQ-Blusw6t4.js +0 -1
  87. package/web/dist/assets/classDiagram-v2-EOCWNBFH-Blusw6t4.js +0 -1
  88. package/web/dist/assets/eventmodeling-45OFAUF4-CA5_fuzk.js +0 -1
  89. package/web/dist/assets/flowDiagram-23GEKE2U-CPO1BGjg.js +0 -1
  90. package/web/dist/assets/index-BUs4sN1r.css +0 -1
  91. package/web/dist/assets/index-HsPwY2CU.js +0 -414
  92. package/web/dist/assets/linear-B8yeZliB.js +0 -1
  93. package/web/dist/assets/railroad-abnf-AHOZXSZD-uSXjMlP2.js +0 -1
  94. package/web/dist/assets/railroad-ebnf-EBAXGLYW-9im8bOEZ.js +0 -1
  95. package/web/dist/assets/railroad-peg-LSFZ7HO6-62Yk_rP2.js +0 -1
  96. package/web/dist/assets/src-W4W9ly-y.js +0 -1
  97. package/web/dist/assets/stateDiagram-v2-6OUMAXLB-CAdDNary.js +0 -1
  98. package/web/dist/assets/swimlanesDiagram-G3AALYLV--Ha4WrTi.js +0 -8
package/README.en.md CHANGED
@@ -172,7 +172,9 @@ Generated by `init`, hand-edited afterwards — each project's coordinate system
172
172
 
173
173
  `opcflow serve` serves at `http://127.0.0.1:5620`: the artifact tree (colors update live), markdown /
174
174
  mermaid / HTML-prototype iframe / code rendering, the **review-queue diff** (approved version vs.
175
- current), an event timeline, and live SSE refresh. Approve, reject, and thumbs-up/down prototypes right
175
+ current), the **artifact relation graph** (derived edges + manually declared edges: drag to connect,
176
+ manual edges unbindable, derived edges reconciled by scan; manual edges join invalidation propagation),
177
+ an event timeline, and live SSE refresh. Approve, reject, and thumbs-up/down prototypes right
176
178
  here.
177
179
 
178
180
  ## Scripts
package/README.md CHANGED
@@ -159,8 +159,9 @@ flowchart LR
159
159
  ## 可视化工作台
160
160
 
161
161
  `opcflow serve` 起在 `http://127.0.0.1:5620`:artifact 树(状态实时变色)、markdown / mermaid / HTML 原型
162
- iframe / 代码渲染、**待审队列 diff**(approved 版本 vs 当前)、事件时间线、SSE 实时刷新。审批、打回、
163
- 给原型 👍👎 都在这里点。
162
+ iframe / 代码渲染、**待审队列 diff**(approved 版本 vs 当前)、**产出物关系图**(自动推导边 + 手动声明边:
163
+ 画布上拖线即声明、手动边可解绑、推导边由 scan 对账维护;手动边同样参与失效传播)、事件时间线、
164
+ SSE 实时刷新。审批、打回、给原型 👍👎 都在这里点。
164
165
 
165
166
  ## 脚本
166
167
 
package/dist/cli.mjs CHANGED
@@ -279,7 +279,14 @@ CREATE INDEX IF NOT EXISTS idx_events_event ON events(event);
279
279
  }
280
280
  },
281
281
  // 迁移 3:claim 时记录 git HEAD,供 hotfix 契约触碰检测与 trailer 交叉验证
282
- { version: 3, up: (db) => db.exec("ALTER TABLE tasks ADD COLUMN claim_commit TEXT") }
282
+ { version: 3, up: (db) => db.exec("ALTER TABLE tasks ADD COLUMN claim_commit TEXT") },
283
+ // 迁移 4:边来源(derived=scan 按 parents×坐标推导,对账维护;manual=用户手动声明,可解绑、scan 永不动)
284
+ {
285
+ version: 4,
286
+ up: (db) => db.exec(
287
+ "ALTER TABLE artifact_edges ADD COLUMN source TEXT NOT NULL DEFAULT 'derived' CHECK (source IN ('derived','manual'))"
288
+ )
289
+ }
283
290
  ];
284
291
  CURRENT_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
285
292
  }
@@ -2512,30 +2519,42 @@ function deriveEdges(ctx) {
2512
2519
  list.push(a);
2513
2520
  byKind.set(a.kind, list);
2514
2521
  }
2515
- const insert = ctx.db.prepare("INSERT OR IGNORE INTO artifact_edges (from_id, to_id) VALUES (?, ?)");
2522
+ const expected = /* @__PURE__ */ new Set();
2523
+ for (const child of nonMeta) {
2524
+ const parents = registry[child.kind]?.parents ?? [];
2525
+ for (const parentKind of parents) {
2526
+ const level = registry[parentKind]?.level ?? "module";
2527
+ const candidates = (byKind.get(parentKind) ?? []).filter((p) => {
2528
+ if ((level === "module" || level === "page") && child.module && p.module !== child.module) return false;
2529
+ if ((level === "endpoint" || level === "page") && child.endpoint && p.endpoint !== child.endpoint) return false;
2530
+ if (level === "page" && child.page && p.page !== child.page) return false;
2531
+ return true;
2532
+ });
2533
+ for (const parent of candidates) expected.add(`${parent.id}|${child.id}`);
2534
+ }
2535
+ }
2536
+ const existing = ctx.db.prepare("SELECT id, from_id, to_id, source FROM artifact_edges").all();
2537
+ const have = new Set(existing.map((e) => `${e.from_id}|${e.to_id}`));
2538
+ const insert = ctx.db.prepare("INSERT OR IGNORE INTO artifact_edges (from_id, to_id, source) VALUES (?, ?, 'derived')");
2539
+ const del = ctx.db.prepare("DELETE FROM artifact_edges WHERE id = ?");
2516
2540
  let created = 0;
2541
+ let pruned = 0;
2517
2542
  const tx = ctx.db.transaction(() => {
2518
- for (const child of nonMeta) {
2519
- const parents = registry[child.kind]?.parents ?? [];
2520
- for (const parentKind of parents) {
2521
- const level = registry[parentKind]?.level ?? "module";
2522
- const candidates = (byKind.get(parentKind) ?? []).filter((p) => {
2523
- if ((level === "module" || level === "page") && child.module && p.module !== child.module) return false;
2524
- if ((level === "endpoint" || level === "page") && child.endpoint && p.endpoint !== child.endpoint) return false;
2525
- if (level === "page" && child.page && p.page !== child.page) return false;
2526
- return true;
2527
- });
2528
- for (const parent of candidates) {
2529
- created += insert.run(parent.id, child.id).changes;
2530
- }
2531
- }
2543
+ for (const key of expected) {
2544
+ if (have.has(key)) continue;
2545
+ const [from, to] = key.split("|");
2546
+ created += insert.run(Number(from), Number(to)).changes;
2547
+ }
2548
+ for (const e of existing) {
2549
+ if (e.source !== "derived") continue;
2550
+ if (!expected.has(`${e.from_id}|${e.to_id}`)) pruned += del.run(e.id).changes;
2532
2551
  }
2533
2552
  });
2534
2553
  tx();
2535
- return created;
2554
+ return { created, pruned };
2536
2555
  }
2537
2556
  function scanArtifacts(ctx, actor = "system") {
2538
- const summary = { registered: 0, refreshed: 0, remapped: 0, edges: 0, skipped: [], unresolved: [] };
2557
+ const summary = { registered: 0, refreshed: 0, remapped: 0, edges: 0, edgesPruned: 0, moved: 0, skipped: [], unresolved: [] };
2539
2558
  const files = [];
2540
2559
  for (const dir of Object.values(ctx.config.docs)) {
2541
2560
  const abs = join10(ctx.root, dir);
@@ -2588,6 +2607,26 @@ function scanArtifacts(ctx, actor = "system") {
2588
2607
  }
2589
2608
  const hash = hashPath(join10(ctx.root, relPath));
2590
2609
  if (hash === null) return;
2610
+ const movedFrom = ctx.db.prepare("SELECT * FROM artifacts WHERE content_hash = ? AND kind = ?").all(hash, kind).filter((a) => !existsSync9(join10(ctx.root, a.path)));
2611
+ if (movedFrom.length === 1) {
2612
+ const old = movedFrom[0];
2613
+ const tx2 = ctx.db.transaction(() => {
2614
+ ctx.db.prepare("UPDATE artifacts SET path = ?, module = ?, endpoint = ?, page = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?").run(relPath, coords.module, coords.endpoint, coords.page, old.id);
2615
+ logEvent(ctx.db, {
2616
+ entityType: "artifact",
2617
+ entityId: old.id,
2618
+ event: "auto_moved",
2619
+ actor,
2620
+ payload: { from: old.path, to: relPath },
2621
+ module: coords.module,
2622
+ endpoint: coords.endpoint,
2623
+ page: coords.page
2624
+ });
2625
+ });
2626
+ tx2();
2627
+ summary.moved++;
2628
+ return;
2629
+ }
2591
2630
  const tx = ctx.db.transaction(() => {
2592
2631
  const result = insert.run(kind, coords.module, coords.endpoint, coords.page, relPath, hash);
2593
2632
  logEvent(ctx.db, {
@@ -2615,9 +2654,35 @@ function scanArtifacts(ctx, actor = "system") {
2615
2654
  for (const code of expandCodeRoots(ctx)) {
2616
2655
  registerOne(code.dir, "code", { module: code.module, endpoint: code.endpoint, page: null });
2617
2656
  }
2618
- summary.edges = deriveEdges(ctx);
2657
+ const edgeResult = deriveEdges(ctx);
2658
+ summary.edges = edgeResult.created;
2659
+ summary.edgesPruned = edgeResult.pruned;
2619
2660
  return summary;
2620
2661
  }
2662
+ function registerAdHocArtifact(ctx, relPathRaw, actor) {
2663
+ const relPath = normalizeRelPath(ctx, relPathRaw);
2664
+ const existing = ctx.db.prepare("SELECT * FROM artifacts WHERE path = ?").get(relPath);
2665
+ if (existing) return existing;
2666
+ const hash = hashPath(join10(ctx.root, relPath));
2667
+ if (hash === null) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${relPath}`);
2668
+ const kind = inferKind(relPath, ctx.config);
2669
+ const coords = parseCoords(ctx, kind, relPath) ?? { module: null, endpoint: null, page: null };
2670
+ const tx = ctx.db.transaction(() => {
2671
+ const r = ctx.db.prepare("INSERT INTO artifacts (kind, module, endpoint, page, path, content_hash) VALUES (?, ?, ?, ?, ?, ?)").run(kind, coords.module, coords.endpoint, coords.page, relPath, hash);
2672
+ logEvent(ctx.db, {
2673
+ entityType: "artifact",
2674
+ entityId: r.lastInsertRowid,
2675
+ event: "scan_registered",
2676
+ actor,
2677
+ payload: { path: relPath, kind, adHoc: true },
2678
+ module: coords.module,
2679
+ endpoint: coords.endpoint,
2680
+ page: coords.page
2681
+ });
2682
+ });
2683
+ tx();
2684
+ return ctx.db.prepare("SELECT * FROM artifacts WHERE path = ?").get(relPath);
2685
+ }
2621
2686
  var stripExt;
2622
2687
  var init_scan_command = __esm({
2623
2688
  "core/commands/scan.command.ts"() {
@@ -3487,6 +3552,7 @@ __export(core_exports, {
3487
3552
  recordNote: () => recordNote,
3488
3553
  recordQaResult: () => recordQaResult,
3489
3554
  refreshArtifact: () => refreshArtifact,
3555
+ registerAdHocArtifact: () => registerAdHocArtifact,
3490
3556
  registerMetaArtifacts: () => registerMetaArtifacts,
3491
3557
  registerOutput: () => registerOutput,
3492
3558
  rejectArtifact: () => rejectArtifact,
@@ -3825,6 +3891,117 @@ data: {"cursor":${cursor2}}
3825
3891
  }, 500);
3826
3892
  req.raw.on("close", () => clearInterval(timer));
3827
3893
  });
3894
+ app.get("/api/graph", async () => {
3895
+ const registry = getKindRegistry(ctx.config);
3896
+ const rows = ctx.db.prepare("SELECT * FROM artifacts ORDER BY id").all().filter(
3897
+ (a) => !registry[a.kind]?.meta
3898
+ );
3899
+ const ids = new Set(rows.map((a) => a.id));
3900
+ const nodes = rows.map((a) => ({
3901
+ id: a.id,
3902
+ kind: a.kind,
3903
+ path: a.path,
3904
+ module: a.module,
3905
+ endpoint: a.endpoint,
3906
+ page: a.page,
3907
+ review_status: reviewStatus(a),
3908
+ missing: !existsSync14(join16(ctx.root, a.path))
3909
+ }));
3910
+ const edges = ctx.db.prepare("SELECT id, from_id, to_id, source FROM artifact_edges").all().filter((e) => ids.has(e.from_id) && ids.has(e.to_id));
3911
+ return { nodes, edges };
3912
+ });
3913
+ app.get("/api/search", async (req) => {
3914
+ const q = (req.query.q ?? "").trim().toLowerCase();
3915
+ if (!q) return { artifacts: [], files: [] };
3916
+ const like = `%${q.replace(/[%_\\]/g, (c) => "\\" + c)}%`;
3917
+ const artifacts = ctx.db.prepare("SELECT * FROM artifacts WHERE path LIKE ? ESCAPE '\\' ORDER BY path LIMIT 30").all(like).map((a) => ({ id: a.id, kind: a.kind, path: a.path, module: a.module, endpoint: a.endpoint, review_status: reviewStatus(a) }));
3918
+ const registered = new Set(ctx.db.prepare("SELECT path FROM artifacts").all().map((r) => r.path));
3919
+ const files = [];
3920
+ const walk = (dir, rel) => {
3921
+ if (files.length >= 30) return;
3922
+ for (const name of readdirSync7(dir).sort()) {
3923
+ if (files.length >= 30) return;
3924
+ if (name.startsWith(".") || name === "node_modules" || name === "dist" || name === "build") continue;
3925
+ const full = join16(dir, name);
3926
+ const relPath = rel ? `${rel}/${name}` : name;
3927
+ if (statSync6(full).isDirectory()) walk(full, relPath);
3928
+ else if (relPath.toLowerCase().includes(q) && !registered.has(relPath)) files.push(relPath);
3929
+ }
3930
+ };
3931
+ walk(ctx.root, "");
3932
+ return { artifacts, files };
3933
+ });
3934
+ app.post("/api/artifact/register", async (req) => {
3935
+ return registerAdHocArtifact(ctx, req.body.path, req.body.actor || "user");
3936
+ });
3937
+ app.post("/api/edge", async (req, reply) => {
3938
+ const { fromId, toId } = req.body;
3939
+ const actor = req.body.actor || "user";
3940
+ if (!fromId || !toId || fromId === toId) {
3941
+ return reply.code(400).send({ error: "\u65E0\u6548\u7684\u8FB9:\u9700\u8981\u4E24\u4E2A\u4E0D\u540C\u7684\u4EA7\u7269" });
3942
+ }
3943
+ const has = (id) => ctx.db.prepare("SELECT COUNT(*) c FROM artifacts WHERE id = ?").get(id).c > 0;
3944
+ if (!has(fromId) || !has(toId)) return reply.code(404).send({ error: "\u4EA7\u7269\u4E0D\u5B58\u5728" });
3945
+ const seen = /* @__PURE__ */ new Set([toId]);
3946
+ const queue = [toId];
3947
+ const next = ctx.db.prepare("SELECT to_id FROM artifact_edges WHERE from_id = ?");
3948
+ while (queue.length) {
3949
+ const cur = queue.pop();
3950
+ for (const row of next.all(cur)) {
3951
+ if (row.to_id === fromId) return reply.code(400).send({ error: "\u4F1A\u5F62\u6210\u73AF,\u5DF2\u62D2\u7EDD" });
3952
+ if (!seen.has(row.to_id)) {
3953
+ seen.add(row.to_id);
3954
+ queue.push(row.to_id);
3955
+ }
3956
+ }
3957
+ }
3958
+ const r = ctx.db.prepare("INSERT OR IGNORE INTO artifact_edges (from_id, to_id, source) VALUES (?, ?, 'manual')").run(fromId, toId);
3959
+ if (r.changes === 0) return reply.code(409).send({ error: "\u8BE5\u5173\u7CFB\u5DF2\u5B58\u5728" });
3960
+ logEvent(ctx.db, { entityType: "artifact", entityId: toId, event: "edge_added", actor, payload: { fromId, toId, source: "manual" } });
3961
+ return { id: r.lastInsertRowid, fromId, toId, source: "manual" };
3962
+ });
3963
+ app.delete("/api/artifact/:id", async (req, reply) => {
3964
+ const id = parseInt(req.params.id);
3965
+ const row = ctx.db.prepare("SELECT * FROM artifacts WHERE id = ?").get(id);
3966
+ if (!row) return reply.code(404).send({ error: "\u4EA7\u7269\u4E0D\u5B58\u5728" });
3967
+ if (row.approved_hash !== null) return reply.code(403).send({ error: "\u8BE5\u4EA7\u7269\u6709\u5BA1\u6279\u5386\u53F2,\u4E0D\u53EF\u53D6\u6D88\u767B\u8BB0" });
3968
+ const refs = ctx.db.prepare(
3969
+ `SELECT (SELECT COUNT(*) FROM task_inputs WHERE artifact_id = ?) +
3970
+ (SELECT COUNT(*) FROM task_outputs WHERE artifact_id = ?) +
3971
+ (SELECT COUNT(*) FROM artifact_feedback WHERE artifact_id = ?) AS c`
3972
+ ).get(id, id, id);
3973
+ if (refs.c > 0) return reply.code(403).send({ error: "\u8BE5\u4EA7\u7269\u5DF2\u88AB\u4EFB\u52A1/\u53CD\u9988\u5F15\u7528,\u4E0D\u53EF\u53D6\u6D88\u767B\u8BB0" });
3974
+ const tx = ctx.db.transaction(() => {
3975
+ logEvent(ctx.db, {
3976
+ entityType: "artifact",
3977
+ entityId: id,
3978
+ event: "unregistered",
3979
+ actor: req.body?.actor || "user",
3980
+ payload: { path: row.path, kind: row.kind },
3981
+ module: row.module,
3982
+ endpoint: row.endpoint,
3983
+ page: row.page
3984
+ });
3985
+ ctx.db.prepare("DELETE FROM artifacts WHERE id = ?").run(id);
3986
+ });
3987
+ tx();
3988
+ return { ok: true };
3989
+ });
3990
+ app.delete("/api/edge/:id", async (req, reply) => {
3991
+ const id = parseInt(req.params.id);
3992
+ const edge = ctx.db.prepare("SELECT * FROM artifact_edges WHERE id = ?").get(id);
3993
+ if (!edge) return reply.code(404).send({ error: "\u8FB9\u4E0D\u5B58\u5728" });
3994
+ if (edge.source !== "manual") return reply.code(403).send({ error: "\u81EA\u52A8\u63A8\u5BFC\u7684\u5173\u7CFB\u4E0D\u53EF\u89E3\u7ED1(\u7531 scan \u6309\u5750\u6807\u4E8B\u5B9E\u7EF4\u62A4)" });
3995
+ ctx.db.prepare("DELETE FROM artifact_edges WHERE id = ?").run(id);
3996
+ logEvent(ctx.db, {
3997
+ entityType: "artifact",
3998
+ entityId: edge.to_id,
3999
+ event: "edge_removed",
4000
+ actor: req.body?.actor || "user",
4001
+ payload: { fromId: edge.from_id, toId: edge.to_id }
4002
+ });
4003
+ return { ok: true };
4004
+ });
3828
4005
  app.get("/api/review-queue", async () => {
3829
4006
  return listArtifacts(ctx, {}).filter((r) => r.review_status === "pending" || r.review_status === "invalidated").map((r) => ({
3830
4007
  ...r,
@@ -3894,11 +4071,13 @@ var init_app = __esm({
3894
4071
  "use strict";
3895
4072
  init_artifact_commands();
3896
4073
  init_retro_command();
4074
+ init_scan_command();
3897
4075
  init_sync_command();
3898
4076
  init_config();
3899
4077
  init_task_commands();
3900
4078
  init_derive();
3901
4079
  init_events();
4080
+ init_kind();
3902
4081
  init_tree();
3903
4082
  MAX_INLINE_SIZE = 1024 * 1024;
3904
4083
  }
@@ -4447,7 +4626,7 @@ async function runCommand(ctx, command, a) {
4447
4626
  }
4448
4627
  case "scan": {
4449
4628
  const s = scanArtifacts(ctx, a.actor || "system");
4450
- console.log(chalk.green(`\u2705 \u626B\u63CF\u5B8C\u6210:\u65B0\u767B\u8BB0 ${s.registered},\u5185\u5BB9\u5237\u65B0 ${s.refreshed},\u91CD\u6302\u5750\u6807 ${s.remapped},\u65B0\u589E\u8FB9 ${s.edges},\u6392\u9664\u5143\u4EA7\u7269 ${s.skipped.length}`));
4629
+ console.log(chalk.green(`\u2705 \u626B\u63CF\u5B8C\u6210:\u65B0\u767B\u8BB0 ${s.registered},\u5185\u5BB9\u5237\u65B0 ${s.refreshed},\u91CD\u6302\u5750\u6807 ${s.remapped},\u81EA\u52A8\u8DDF\u968F\u79FB\u52A8 ${s.moved},\u65B0\u589E\u8FB9 ${s.edges},\u6E05\u7406\u6B8B\u7559\u8FB9 ${s.edgesPruned},\u6392\u9664\u5143\u4EA7\u7269 ${s.skipped.length}`));
4451
4630
  if (s.unresolved.length > 0) {
4452
4631
  console.log(chalk.yellow(`\u26A0 ${s.unresolved.length} \u4E2A\u6587\u4EF6\u547D\u4E2D kind \u4F46\u8DEF\u5F84\u4E0D\u7B26 coords \u6587\u6CD5,\u672A\u767B\u8BB0(\u975E\u89C4\u8303/\u5E9F\u5F03\u7AEF?):`));
4453
4632
  for (const p of s.unresolved) console.log(chalk.yellow(` - ${p}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dawipong/opcflow",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Spec-anchored, drift-enforced execution layer for AI coding agents — artifact DAG, trust gates, multi-role pipeline; generates agents/MCP/hooks for Claude Code, Codex, OpenCode & Cursor.",
5
5
  "license": "MIT",
6
6
  "author": "Dawi",
@@ -59,6 +59,7 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@ant-design/icons": "^6",
62
+ "@dagrejs/dagre": "^3.0.0",
62
63
  "@monaco-editor/react": "^4.7.0",
63
64
  "@semantic-release/changelog": "^6.0.3",
64
65
  "@semantic-release/git": "^10.0.1",
@@ -67,6 +68,7 @@
67
68
  "@types/react": "^18",
68
69
  "@types/react-dom": "^18",
69
70
  "@vitejs/plugin-react": "^6",
71
+ "@xyflow/react": "^12.11.2",
70
72
  "antd": "^6",
71
73
  "esbuild": "^0.28.1",
72
74
  "mermaid": "^11",
@@ -1 +1 @@
1
- import{m as e}from"./src-W4W9ly-y.js";import{n as t}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./chunk-WYO6CB5R-BaRUDpDl.js";import"./index-HsPwY2CU.js";import{m as n,t as r}from"./mermaid-parser.core-CAAH_OSq.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-DXlFl9Jv.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";var c=n().RailroadAbnf.parser.LangiumParser,l=t(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=t(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=t(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=t(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=t(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=t(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=t(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:t(t=>{o.clear(),e.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(t);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new r(n);let i=n.value;e.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),e.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{E as e}from"./src-Bp5IDfvJ.js";import{n as t}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./chunk-WYO6CB5R-C0vPAP7X.js";import"./index-Cf-76g9P.js";import{m as n,t as r}from"./mermaid-parser.core-CICKlqAN.js";import{n as i,r as a,t as o}from"./chunk-MOJQB5TN-BrFLYoih.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";var c=n().RailroadAbnf.parser.LangiumParser,l=t(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=t(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=t(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=t(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=t(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=t(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=t(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:t(t=>{o.clear(),e.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(t);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new r(n);let i=n.value;e.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),e.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -1 +1 @@
1
- import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-zlHGdC4Y.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-BWPyau1x.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-DeM6hNwF.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i)if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-KEIR6QF5-BfrZ3jm6.js";import{M as e}from"./mermaid-parser.core-CICKlqAN.js";export{e as createArchitectureServices};