@tienne/gestalt 0.95.0 → 0.97.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 (120) hide show
  1. package/CLAUDE.md +5 -3
  2. package/README.ko.md +1 -0
  3. package/README.md +1 -0
  4. package/dist/package.json +4 -3
  5. package/dist/plugin/skills/_shared/agent-model.md +5 -3
  6. package/dist/plugin/skills/_shared/proactive-routing.md +1 -0
  7. package/dist/plugin/skills/agent/SKILL.md +1 -1
  8. package/dist/plugin/skills/architecture/SKILL.md +31 -5
  9. package/dist/plugin/skills/architecture/references/domain-flow.md +1 -0
  10. package/dist/plugin/skills/architecture/references/projections.md +56 -0
  11. package/dist/plugin/skills/architecture/references/rerun.md +3 -1
  12. package/dist/plugin/skills/blast-radius/SKILL.md +1 -1
  13. package/dist/plugin/skills/build-graph/SKILL.md +1 -1
  14. package/dist/plugin/skills/doubt/SKILL.md +229 -0
  15. package/dist/plugin/skills/execute/SKILL.md +13 -1
  16. package/dist/plugin/skills/explain/SKILL.md +1 -1
  17. package/dist/plugin/skills/interview/SKILL.md +1 -1
  18. package/dist/plugin/skills/local-pr/SKILL.md +14 -1
  19. package/dist/plugin/skills/pr/SKILL.md +14 -1
  20. package/dist/plugin/skills/review/SKILL.md +14 -1
  21. package/dist/plugin/skills/review-loop/SKILL.md +13 -0
  22. package/dist/plugin/skills/review-reply/SKILL.md +13 -0
  23. package/dist/plugin/skills/ship/SKILL.md +14 -1
  24. package/dist/plugin/skills/solve/SKILL.md +1 -1
  25. package/dist/plugin/skills/spec/SKILL.md +1 -1
  26. package/dist/schemas/architecture-ir.schema.json +51 -3
  27. package/dist/schemas/gestalt.schema.json +12 -0
  28. package/dist/src/architecture/blueprint-layout.d.ts +105 -0
  29. package/dist/src/architecture/blueprint-layout.d.ts.map +1 -0
  30. package/dist/src/architecture/blueprint-layout.js +297 -0
  31. package/dist/src/architecture/blueprint-layout.js.map +1 -0
  32. package/dist/src/architecture/delta-renderer.d.ts +35 -0
  33. package/dist/src/architecture/delta-renderer.d.ts.map +1 -0
  34. package/dist/src/architecture/delta-renderer.js +329 -0
  35. package/dist/src/architecture/delta-renderer.js.map +1 -0
  36. package/dist/src/architecture/delta.d.ts +70 -0
  37. package/dist/src/architecture/delta.d.ts.map +1 -0
  38. package/dist/src/architecture/delta.js +342 -0
  39. package/dist/src/architecture/delta.js.map +1 -0
  40. package/dist/src/architecture/drilldown.d.ts +19 -1
  41. package/dist/src/architecture/drilldown.d.ts.map +1 -1
  42. package/dist/src/architecture/drilldown.js +5 -5
  43. package/dist/src/architecture/drilldown.js.map +1 -1
  44. package/dist/src/architecture/er-layout.d.ts +97 -0
  45. package/dist/src/architecture/er-layout.d.ts.map +1 -0
  46. package/dist/src/architecture/er-layout.js +344 -0
  47. package/dist/src/architecture/er-layout.js.map +1 -0
  48. package/dist/src/architecture/flow-layout.d.ts +22 -1
  49. package/dist/src/architecture/flow-layout.d.ts.map +1 -1
  50. package/dist/src/architecture/flow-layout.js +13 -9
  51. package/dist/src/architecture/flow-layout.js.map +1 -1
  52. package/dist/src/architecture/html-renderer.d.ts +4 -0
  53. package/dist/src/architecture/html-renderer.d.ts.map +1 -1
  54. package/dist/src/architecture/html-renderer.js +462 -20
  55. package/dist/src/architecture/html-renderer.js.map +1 -1
  56. package/dist/src/architecture/html-theme.d.ts +18 -0
  57. package/dist/src/architecture/html-theme.d.ts.map +1 -1
  58. package/dist/src/architecture/html-theme.js +101 -1
  59. package/dist/src/architecture/html-theme.js.map +1 -1
  60. package/dist/src/architecture/ir-schema.d.ts +358 -117
  61. package/dist/src/architecture/ir-schema.d.ts.map +1 -1
  62. package/dist/src/architecture/ir-schema.js +33 -1
  63. package/dist/src/architecture/ir-schema.js.map +1 -1
  64. package/dist/src/architecture/lifecycle-layout.d.ts +94 -0
  65. package/dist/src/architecture/lifecycle-layout.d.ts.map +1 -0
  66. package/dist/src/architecture/lifecycle-layout.js +471 -0
  67. package/dist/src/architecture/lifecycle-layout.js.map +1 -0
  68. package/dist/src/architecture/merge.d.ts.map +1 -1
  69. package/dist/src/architecture/merge.js +72 -2
  70. package/dist/src/architecture/merge.js.map +1 -1
  71. package/dist/src/architecture/store.d.ts +6 -1
  72. package/dist/src/architecture/store.d.ts.map +1 -1
  73. package/dist/src/architecture/store.js +75 -8
  74. package/dist/src/architecture/store.js.map +1 -1
  75. package/dist/src/architecture/types.d.ts +35 -3
  76. package/dist/src/architecture/types.d.ts.map +1 -1
  77. package/dist/src/architecture/types.js +13 -1
  78. package/dist/src/architecture/types.js.map +1 -1
  79. package/dist/src/architecture/validator.d.ts +27 -3
  80. package/dist/src/architecture/validator.d.ts.map +1 -1
  81. package/dist/src/architecture/validator.js +331 -8
  82. package/dist/src/architecture/validator.js.map +1 -1
  83. package/dist/src/core/config.d.ts +18 -0
  84. package/dist/src/core/config.d.ts.map +1 -1
  85. package/dist/src/core/config.js +14 -1
  86. package/dist/src/core/config.js.map +1 -1
  87. package/dist/src/core/hooks-env.d.ts +7 -2
  88. package/dist/src/core/hooks-env.d.ts.map +1 -1
  89. package/dist/src/core/hooks-env.js +7 -2
  90. package/dist/src/core/hooks-env.js.map +1 -1
  91. package/dist/src/mcp/tools/architecture-passthrough.d.ts.map +1 -1
  92. package/dist/src/mcp/tools/architecture-passthrough.js +91 -2
  93. package/dist/src/mcp/tools/architecture-passthrough.js.map +1 -1
  94. package/package.json +4 -3
  95. package/plugin/.codex-plugin/plugin.json +1 -1
  96. package/plugin/.mcp.json +1 -1
  97. package/plugin/mcp.json +1 -1
  98. package/plugin/skills/_shared/agent-model.md +5 -3
  99. package/plugin/skills/_shared/proactive-routing.md +1 -0
  100. package/plugin/skills/agent/SKILL.md +1 -1
  101. package/plugin/skills/architecture/SKILL.md +31 -5
  102. package/plugin/skills/architecture/references/domain-flow.md +1 -0
  103. package/plugin/skills/architecture/references/projections.md +56 -0
  104. package/plugin/skills/architecture/references/rerun.md +3 -1
  105. package/plugin/skills/blast-radius/SKILL.md +1 -1
  106. package/plugin/skills/build-graph/SKILL.md +1 -1
  107. package/plugin/skills/doubt/SKILL.md +229 -0
  108. package/plugin/skills/execute/SKILL.md +13 -1
  109. package/plugin/skills/explain/SKILL.md +1 -1
  110. package/plugin/skills/interview/SKILL.md +1 -1
  111. package/plugin/skills/local-pr/SKILL.md +14 -1
  112. package/plugin/skills/pr/SKILL.md +14 -1
  113. package/plugin/skills/review/SKILL.md +14 -1
  114. package/plugin/skills/review-loop/SKILL.md +13 -0
  115. package/plugin/skills/review-reply/SKILL.md +13 -0
  116. package/plugin/skills/ship/SKILL.md +14 -1
  117. package/plugin/skills/solve/SKILL.md +1 -1
  118. package/plugin/skills/spec/SKILL.md +1 -1
  119. package/schemas/architecture-ir.schema.json +51 -3
  120. package/schemas/gestalt.schema.json +12 -0
@@ -0,0 +1,342 @@
1
+ import { NODE_KIND_SHORT } from './kind-text.js';
2
+ import { assignStages } from './layout.js';
3
+ import { ALL_PACKS_VOCABULARY } from './packs/index.js';
4
+ import { displayKindOf } from './types.js';
5
+ /** 원장 정렬 순서. 대상 id보다 먼저 본다 */
6
+ export const DELTA_CHANGES = [
7
+ 'ADDED',
8
+ 'REMOVED',
9
+ 'CHANGED',
10
+ 'MOVED',
11
+ 'REWIRED',
12
+ ];
13
+ /** 참고 자료의 한 장 예산. 남는 id는 한 번만 센다 */
14
+ export const DELTA_BUDGET = { components: 8, relationships: 10, ledger: 8 };
15
+ const COUNT_TEXT = {
16
+ components: '구성 요소',
17
+ relationships: '관계',
18
+ ledger: '변경 목록',
19
+ };
20
+ // label은 병합 키라 바뀌면 다른 노드다. 여기 없는 필드는 그림의 구조를 바꾸지 않는다
21
+ const CHANGED_ATTRS = [
22
+ ['kind', '종류'],
23
+ ['displayName', '표시 이름'],
24
+ ['description', '설명'],
25
+ ['displayKind', '종류 표시'],
26
+ ['protocol', '프로토콜'],
27
+ ['mcpServer', 'MCP 서버'],
28
+ ['actions', '동작'],
29
+ ['environment', '환경'],
30
+ ['engine', '엔진'],
31
+ ['platforms', '플랫폼'],
32
+ ];
33
+ const VALUE_MAX = 28;
34
+ function cmp(a, b) {
35
+ return a < b ? -1 : a > b ? 1 : 0;
36
+ }
37
+ function nameOf(node) {
38
+ return node.displayName ?? node.label;
39
+ }
40
+ function clip(text) {
41
+ const chars = [...text];
42
+ return chars.length > VALUE_MAX ? `${chars.slice(0, VALUE_MAX - 1).join('')}…` : text;
43
+ }
44
+ function valueText(v) {
45
+ if (v === undefined || v === '')
46
+ return '없음';
47
+ if (Array.isArray(v))
48
+ return v.length === 0 ? '없음' : clip(v.join(', '));
49
+ return `"${clip(String(v))}"`;
50
+ }
51
+ function sameValue(a, b) {
52
+ return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
53
+ }
54
+ /**
55
+ * 컬럼은 이름으로 맞춘다. 원장 한 줄이 길어지지 않게 생긴 것과 빠진 것, 바뀐 것을 이름만 적는다.
56
+ * 근거만 달라진 건 그림의 구조가 아니라서 세지 않는다. 다만 외래 키 근거가 생기거나 사라지면 선이 바뀌니 센다
57
+ */
58
+ function columnDiffs(b, a) {
59
+ const shape = (c) => JSON.stringify([
60
+ c.type ?? null,
61
+ c.pk ?? null,
62
+ c.nullable ?? null,
63
+ c.unique ?? null,
64
+ c.references?.table ?? null,
65
+ c.references?.column ?? null,
66
+ c.references?.onDelete ?? null,
67
+ c.references !== undefined && (c.evidence ?? []).length > 0,
68
+ ]);
69
+ const before = new Map((b.columns ?? []).map((c) => [c.name, c]));
70
+ const after = new Map((a.columns ?? []).map((c) => [c.name, c]));
71
+ const added = [...after.keys()].filter((n) => !before.has(n));
72
+ const removed = [...before.keys()].filter((n) => !after.has(n));
73
+ const changed = [...after.keys()].filter((n) => before.has(n) && shape(before.get(n)) !== shape(after.get(n)));
74
+ const list = (names) => clip(names.join(', '));
75
+ return [
76
+ ...(added.length > 0 ? [`컬럼 ${list(added)} 생김`] : []),
77
+ ...(removed.length > 0 ? [`컬럼 ${list(removed)} 빠짐`] : []),
78
+ ...(changed.length > 0 ? [`컬럼 ${list(changed)} 바뀜`] : []),
79
+ ];
80
+ }
81
+ function kindShort(node) {
82
+ return node.kind === 'component' && node.displayKind !== undefined
83
+ ? node.displayKind
84
+ : NODE_KIND_SHORT[displayKindOf(node)];
85
+ }
86
+ function edgeKindText(kind) {
87
+ return ALL_PACKS_VOCABULARY.edgeKinds[kind]?.text ?? kind;
88
+ }
89
+ function drawnNodes(s) {
90
+ return new Map(s.ir.nodes.filter((n) => s.nodeIds.has(n.id)).map((n) => [n.id, n]));
91
+ }
92
+ function drawnEdges(s) {
93
+ return new Map(s.ir.edges.filter((e) => s.edgeIds.has(e.id)).map((e) => [e.id, e]));
94
+ }
95
+ /**
96
+ * 이전 그림과 이번 그림을 id로 맞춰 바뀐 것을 뽑는다.
97
+ * render가 병합으로 이전 id를 물려준 뒤라 같은 것은 같은 id다. label이 병합 키라 이름을 바꾸면 빠짐과 생김 두 건이 된다.
98
+ */
99
+ export function computeArchitectureDelta(before, after) {
100
+ const bNodes = drawnNodes(before);
101
+ const aNodes = drawnNodes(after);
102
+ const bEdges = drawnEdges(before);
103
+ const aEdges = drawnEdges(after);
104
+ const bStages = stageLabels(before.ir);
105
+ const aStages = stageLabels(after.ir);
106
+ const nameIn = (nodes, ir) => {
107
+ const all = new Map(ir.nodes.map((x) => [x.id, x]));
108
+ return (id) => {
109
+ if (id === undefined)
110
+ return '없음';
111
+ const n = nodes.get(id) ?? all.get(id);
112
+ return `"${clip(n !== undefined ? nameOf(n) : id)}"`;
113
+ };
114
+ };
115
+ const bName = nameIn(bNodes, before.ir);
116
+ const aName = nameIn(aNodes, after.ir);
117
+ const ledger = [];
118
+ const nodes = [];
119
+ for (const id of [...new Set([...bNodes.keys(), ...aNodes.keys()])].sort(cmp)) {
120
+ const b = bNodes.get(id);
121
+ const a = aNodes.get(id);
122
+ const changes = [];
123
+ if (b === undefined && a !== undefined) {
124
+ changes.push('ADDED');
125
+ ledger.push({
126
+ change: 'ADDED',
127
+ target: id,
128
+ object: 'node',
129
+ text: `${kindShort(a)} "${nameOf(a)}" 생김`,
130
+ });
131
+ }
132
+ else if (a === undefined && b !== undefined) {
133
+ changes.push('REMOVED');
134
+ ledger.push({
135
+ change: 'REMOVED',
136
+ target: id,
137
+ object: 'node',
138
+ text: `${kindShort(b)} "${nameOf(b)}" 빠짐`,
139
+ });
140
+ }
141
+ else if (a !== undefined && b !== undefined) {
142
+ const diffs = [
143
+ ...CHANGED_ATTRS.filter(([k]) => !sameValue(b[k], a[k])).map(([k, text]) => `${text} ${valueText(b[k])} → ${valueText(a[k])}`),
144
+ ...columnDiffs(b, a),
145
+ ];
146
+ if (diffs.length > 0) {
147
+ changes.push('CHANGED');
148
+ ledger.push({
149
+ change: 'CHANGED',
150
+ target: id,
151
+ object: 'node',
152
+ text: `"${nameOf(a)}" ${diffs.join(', ')}`,
153
+ });
154
+ }
155
+ const moves = [];
156
+ if (b.parent !== a.parent)
157
+ moves.push(`부모 ${bName(b.parent)} → ${aName(a.parent)}`);
158
+ if (b.account !== a.account)
159
+ moves.push(`계정 ${bName(b.account)} → ${aName(a.account)}`);
160
+ const bStage = bStages.get(id);
161
+ const aStage = aStages.get(id);
162
+ if (bStage !== undefined && aStage !== undefined && bStage !== aStage) {
163
+ moves.push(`구간 "${bStage}" → "${aStage}"`);
164
+ }
165
+ if (moves.length > 0) {
166
+ changes.push('MOVED');
167
+ ledger.push({
168
+ change: 'MOVED',
169
+ target: id,
170
+ object: 'node',
171
+ text: `"${nameOf(a)}" ${moves.join(', ')}`,
172
+ });
173
+ }
174
+ }
175
+ nodes.push({ id, ...(b ? { before: b } : {}), ...(a ? { after: a } : {}), changes });
176
+ }
177
+ const edges = diffEdges(bEdges, aEdges);
178
+ for (const e of edges) {
179
+ const b = e.before;
180
+ const a = e.after;
181
+ const kindText = edgeKindText((a ?? b).kind);
182
+ const span = (edge, name) => `${name(edge.from)} → ${name(edge.to)}`;
183
+ for (const change of e.changes) {
184
+ let text;
185
+ if (change === 'ADDED')
186
+ text = `${kindText} 연결 ${span(a, aName)} 생김`;
187
+ else if (change === 'REMOVED')
188
+ text = `${kindText} 연결 ${span(b, bName)} 빠짐`;
189
+ else if (change === 'REWIRED')
190
+ text = `${kindText} 연결 ${span(b, bName)} 대신 ${span(a, aName)}`;
191
+ else {
192
+ const diffs = [];
193
+ if (b.kind !== a.kind)
194
+ diffs.push(`종류 ${edgeKindText(b.kind)} → ${kindText}`);
195
+ if (!sameValue(b.actions, a.actions))
196
+ diffs.push(`동작 ${valueText(b.actions)} → ${valueText(a.actions)}`);
197
+ text = `연결 ${span(a, aName)} ${diffs.join(', ')}`;
198
+ }
199
+ ledger.push({ change, target: e.id, object: 'edge', text });
200
+ }
201
+ }
202
+ ledger.sort((x, y) => DELTA_CHANGES.indexOf(x.change) - DELTA_CHANGES.indexOf(y.change) ||
203
+ (x.object === y.object ? 0 : x.object === 'node' ? -1 : 1) ||
204
+ cmp(x.target, y.target));
205
+ return { before, after, nodes, edges, ledger };
206
+ }
207
+ function stageLabels(ir) {
208
+ const staged = assignStages(ir);
209
+ const out = new Map();
210
+ if (staged === undefined)
211
+ return out;
212
+ for (const [id, i] of staged.indexOf)
213
+ out.set(id, staged.labels[i]);
214
+ return out;
215
+ }
216
+ /**
217
+ * 엣지는 병합이 (from, to, kind)로 id를 물려주므로 끝점이 바뀐 엣지는 보통 id가 다르다.
218
+ * 같은 kind의 빠진 엣지와 생긴 엣지가 한쪽 끝을 같은 자리에서 공유하고 서로 하나씩만 맞으면 다시 이은 것으로 본다.
219
+ * 짝이 여럿이면 어느 선이 어디로 갔는지 단정할 수 없어 빠짐과 생김으로 둔다
220
+ */
221
+ function diffEdges(bEdges, aEdges) {
222
+ const out = [];
223
+ const removed = [];
224
+ const added = [];
225
+ for (const id of [...new Set([...bEdges.keys(), ...aEdges.keys()])].sort(cmp)) {
226
+ const b = bEdges.get(id);
227
+ const a = aEdges.get(id);
228
+ if (b === undefined) {
229
+ added.push(a);
230
+ continue;
231
+ }
232
+ if (a === undefined) {
233
+ removed.push(b);
234
+ continue;
235
+ }
236
+ const changes = [];
237
+ if (b.kind !== a.kind || !sameValue(b.actions, a.actions))
238
+ changes.push('CHANGED');
239
+ // 다음 실행이 우연히 같은 id를 다른 선에 매기면 id는 남고 끝점만 바뀐다
240
+ if (b.from !== a.from || b.to !== a.to)
241
+ changes.push('REWIRED');
242
+ out.push({ id, before: b, after: a, changes });
243
+ }
244
+ const removedIx = indexEnds(removed);
245
+ const addedIx = indexEnds(added);
246
+ const pairedRemoved = new Set();
247
+ const pairedAdded = new Set();
248
+ for (const a of added) {
249
+ const cands = sharingOne(removedIx, a);
250
+ if (cands.length !== 1)
251
+ continue;
252
+ const r = cands[0];
253
+ if (sharingOne(addedIx, r).length !== 1)
254
+ continue;
255
+ pairedRemoved.add(r.id);
256
+ pairedAdded.add(a.id);
257
+ const changes = sameValue(r.actions, a.actions)
258
+ ? ['REWIRED']
259
+ : ['CHANGED', 'REWIRED'];
260
+ out.push({ id: a.id, before: r, after: a, changes });
261
+ }
262
+ for (const r of removed) {
263
+ if (!pairedRemoved.has(r.id))
264
+ out.push({ id: r.id, before: r, changes: ['REMOVED'] });
265
+ }
266
+ for (const a of added) {
267
+ if (!pairedAdded.has(a.id))
268
+ out.push({ id: a.id, after: a, changes: ['ADDED'] });
269
+ }
270
+ return out.sort((x, y) => cmp(x.id, y.id));
271
+ }
272
+ function indexEnds(edges) {
273
+ const byFrom = new Map();
274
+ const byTo = new Map();
275
+ const put = (m, key, e) => {
276
+ const list = m.get(key);
277
+ if (list === undefined)
278
+ m.set(key, [e]);
279
+ else
280
+ list.push(e);
281
+ };
282
+ for (const e of edges) {
283
+ put(byFrom, `${e.kind}|${e.from}`, e);
284
+ put(byTo, `${e.kind}|${e.to}`, e);
285
+ }
286
+ return { byFrom, byTo };
287
+ }
288
+ /** 같은 kind에서 from과 to 중 정확히 한쪽 끝만 e와 같은 엣지 */
289
+ function sharingOne(ix, e) {
290
+ const sameFrom = (ix.byFrom.get(`${e.kind}|${e.from}`) ?? []).filter((x) => x.to !== e.to);
291
+ const sameTo = (ix.byTo.get(`${e.kind}|${e.to}`) ?? []).filter((x) => x.from !== e.from);
292
+ return [...sameFrom, ...sameTo];
293
+ }
294
+ /**
295
+ * 그릴 범위. 합집합이 예산 안이면 전부 그린다. 넘으면 바뀐 노드와 바뀐 엣지의 끝, 그 1홉 이웃만 남긴다.
296
+ * 바뀌지 않은 먼 노드까지 그리면 큰 그림에서 변경이 묻힌다
297
+ */
298
+ export function deltaScope(delta) {
299
+ const all = new Set(delta.nodes.map((n) => n.id));
300
+ const total = { components: all.size, relationships: delta.edges.length };
301
+ if (total.components <= DELTA_BUDGET.components &&
302
+ total.relationships <= DELTA_BUDGET.relationships) {
303
+ return { nodeIds: all, edgeIds: new Set(delta.edges.map((e) => e.id)), scoped: false, total };
304
+ }
305
+ const core = new Set(delta.nodes.filter((n) => n.changes.length > 0).map((n) => n.id));
306
+ for (const e of delta.edges) {
307
+ if (e.changes.length === 0)
308
+ continue;
309
+ for (const end of endsOf(e))
310
+ core.add(end);
311
+ }
312
+ const keep = new Set(core);
313
+ for (const e of delta.edges) {
314
+ const ends = endsOf(e);
315
+ if (ends.some((id) => core.has(id)))
316
+ for (const id of ends)
317
+ keep.add(id);
318
+ }
319
+ const edgeIds = new Set(delta.edges.filter((e) => endsOf(e).every((id) => keep.has(id))).map((e) => e.id));
320
+ return { nodeIds: keep, edgeIds, scoped: true, total };
321
+ }
322
+ function endsOf(e) {
323
+ return [
324
+ ...new Set([
325
+ ...(e.before ? [e.before.from, e.before.to] : []),
326
+ ...(e.after ? [e.after.from, e.after.to] : []),
327
+ ]),
328
+ ];
329
+ }
330
+ export function deltaCounts(delta, scope) {
331
+ return {
332
+ components: scope.nodeIds.size,
333
+ relationships: scope.edgeIds.size,
334
+ ledger: delta.ledger.length,
335
+ };
336
+ }
337
+ export function deltaOverBudget(counts) {
338
+ return Object.keys(DELTA_BUDGET)
339
+ .filter((k) => counts[k] > DELTA_BUDGET[k])
340
+ .map((k) => `${COUNT_TEXT[k]} ${counts[k]}개 (예산 ${DELTA_BUDGET[k]})`);
341
+ }
342
+ //# sourceMappingURL=delta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../src/architecture/delta.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type LayoutResult } from './layout.js';
2
2
  import { type FlowLevel } from './flow-layout.js';
3
- import type { EdgeKind, LineStyle } from './types.js';
3
+ import type { ArchitectureEdge, ArchitectureNode, EdgeKind, LineStyle } from './types.js';
4
4
  import type { ValidatedIr } from './validator.js';
5
5
  export type DrillLevelKind = 'root' | 'service' | 'app' | 'server' | 'feature' | 'group';
6
6
  /**
@@ -39,6 +39,24 @@ export interface Drilldown {
39
39
  flows: FlowLevel[];
40
40
  }
41
41
  export declare const ROOT_LEVEL_ID = "root";
42
+ export interface Graph {
43
+ nodeById: Map<string, ArchitectureNode>;
44
+ edgeById: Map<string, ArchitectureEdge>;
45
+ edges: ArchitectureEdge[];
46
+ parentOf: Map<string, string>;
47
+ }
48
+ export declare function buildGraph(validated: {
49
+ ir: Pick<ValidatedIr['ir'], 'nodes' | 'edges'>;
50
+ drawableNodeIds: ReadonlySet<string>;
51
+ drawableEdgeIds: ReadonlySet<string>;
52
+ }): Graph;
53
+ export declare function kindOf(g: Graph, id: string): string | undefined;
54
+ /** 화면 자리에 서는 카드. 하네스의 스킬은 사용자가 고르는 입구라 웹의 화면과 같은 자리에 둔다 */
55
+ export declare function isSurface(g: Graph, id: string): boolean;
56
+ export declare function handlersOf(g: Graph, endpointId: string): ArchitectureEdge[];
57
+ /** 서버가 읽고 쓰는 저장소. 테이블에 걸린 선은 그 테이블이 속한 저장소로 올려 묶는다 */
58
+ /** 핸들러 모듈이 같은 프로세스의 엔진 모듈을 쓰는 선. 하네스 MCP 서버에서 도구 핸들러가 엔진을 부르는 자리다 */
59
+ export declare function moduleUses(g: Graph): ArchitectureEdge[];
42
60
  /** service 노드가 하나라도 그려지면 드릴다운으로 그린다 */
43
61
  export declare function shouldDrillDown(validated: ValidatedIr): boolean;
44
62
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"drilldown.d.ts","sourceRoot":"","sources":["../../../src/architecture/drilldown.ts"],"names":[],"mappings":"AAAA,OAAO,EAiBL,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAIrE,OAAO,KAAK,EAAsC,QAAQ,EAAE,SAAS,EAAY,MAAM,YAAY,CAAC;AAEpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAEzF;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,sFAAsF;IACtF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,8BAA8B;IAC9B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,sDAAsD;IACtD,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,SAAS,CAAC;AA6kCpC,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAgB/D;AAED;;;GAGG;AACH,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAItF;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAwJjF"}
1
+ {"version":3,"file":"drilldown.d.ts","sourceRoot":"","sources":["../../../src/architecture/drilldown.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,7 @@ function compareStr(a, b) {
22
22
  function byId(a, b) {
23
23
  return compareStr(a.id, b.id);
24
24
  }
25
- function buildGraph(validated) {
25
+ export function buildGraph(validated) {
26
26
  const { ir, drawableNodeIds, drawableEdgeIds } = validated;
27
27
  const nodes = ir.nodes.filter((n) => drawableNodeIds.has(n.id));
28
28
  const nodeById = new Map(nodes.map((n) => [n.id, n]));
@@ -36,7 +36,7 @@ function buildGraph(validated) {
36
36
  }
37
37
  return { nodeById, edgeById, edges, parentOf };
38
38
  }
39
- function kindOf(g, id) {
39
+ export function kindOf(g, id) {
40
40
  return g.nodeById.get(id)?.kind;
41
41
  }
42
42
  /** 가장 가까운 micro_app이나 service 조상. 화면과 기능 영역이 어느 레벨 칸에 서는지 이걸로 정한다 */
@@ -68,7 +68,7 @@ function edgesOf(g, kind, fromKind, toKind) {
68
68
  return g.edges.filter((e) => e.kind === kind && kindOf(g, e.from) === fromKind && kindOf(g, e.to) === toKind);
69
69
  }
70
70
  /** 화면 자리에 서는 카드. 하네스의 스킬은 사용자가 고르는 입구라 웹의 화면과 같은 자리에 둔다 */
71
- function isSurface(g, id) {
71
+ export function isSurface(g, id) {
72
72
  const kind = kindOf(g, id);
73
73
  return kind === 'screen' || kind === 'skill';
74
74
  }
@@ -125,7 +125,7 @@ function spawnedFrom(g, starts) {
125
125
  function routesInto(g, endpointId) {
126
126
  return g.edges.filter((e) => e.kind === 'routes' && e.to === endpointId && kindOf(g, e.from) === 'gateway');
127
127
  }
128
- function handlersOf(g, endpointId) {
128
+ export function handlersOf(g, endpointId) {
129
129
  return g.edges.filter((e) => e.kind === 'handles' && e.from === endpointId && kindOf(g, e.to) === 'app_module');
130
130
  }
131
131
  function gatewayHops(g) {
@@ -364,7 +364,7 @@ function prodGraph(g) {
364
364
  }
365
365
  /** 서버가 읽고 쓰는 저장소. 테이블에 걸린 선은 그 테이블이 속한 저장소로 올려 묶는다 */
366
366
  /** 핸들러 모듈이 같은 프로세스의 엔진 모듈을 쓰는 선. 하네스 MCP 서버에서 도구 핸들러가 엔진을 부르는 자리다 */
367
- function moduleUses(g) {
367
+ export function moduleUses(g) {
368
368
  return edgesOf(g, 'uses', 'app_module', 'app_module');
369
369
  }
370
370
  /**