@magic-spells/constellation 0.2.1 → 0.2.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.
Files changed (103) hide show
  1. package/dist/core/code.d.ts +46 -0
  2. package/dist/core/code.js +169 -0
  3. package/dist/core/code.js.map +1 -0
  4. package/dist/core/git.d.ts +8 -0
  5. package/dist/core/git.js +36 -4
  6. package/dist/core/git.js.map +1 -1
  7. package/dist/core/sync.d.ts +1 -0
  8. package/dist/core/sync.js +18 -8
  9. package/dist/core/sync.js.map +1 -1
  10. package/dist/core/validate.js +13 -2
  11. package/dist/core/validate.js.map +1 -1
  12. package/dist/core/writer.d.ts +25 -0
  13. package/dist/core/writer.js +65 -1
  14. package/dist/core/writer.js.map +1 -1
  15. package/dist/mcp/server.js +478 -16
  16. package/dist/mcp/server.js.map +1 -1
  17. package/docs/001-file-format.md +22 -4
  18. package/docs/002-mcp.md +29 -1
  19. package/docs/003-mcp-upgrade-plan.md +138 -0
  20. package/examples/constellation/datatype/DATATYPE-TICKET.md +5 -0
  21. package/package.json +4 -2
  22. package/schemas/card.json +46 -2
  23. package/skill/SKILL.md +34 -7
  24. package/skill/methodology.md +5 -2
  25. package/viewer/dist/assets/{arc-CMMRgIq9.js → arc-YuzGWkw8.js} +1 -1
  26. package/viewer/dist/assets/architecture-7EHR7CIX-BAboPvK1.js +1 -0
  27. package/viewer/dist/assets/{architectureDiagram-3BPJPVTR-CB5p_qlN.js → architectureDiagram-3BPJPVTR-BgksqMlF.js} +1 -1
  28. package/viewer/dist/assets/{blockDiagram-GPEHLZMM-DpnMj_e6.js → blockDiagram-GPEHLZMM-Bc6JILFK.js} +1 -1
  29. package/viewer/dist/assets/{c4Diagram-AAUBKEIU-f91ngVN8.js → c4Diagram-AAUBKEIU-CRVt42df.js} +1 -1
  30. package/viewer/dist/assets/channel-D8YnBgqu.js +1 -0
  31. package/viewer/dist/assets/{chunk-2J33WTMH-y7Pz5tMO.js → chunk-2J33WTMH-CpuwKeX6.js} +1 -1
  32. package/viewer/dist/assets/{chunk-3OPIFGDE-Ir_ghIUQ.js → chunk-3OPIFGDE-BG_ijJhE.js} +1 -1
  33. package/viewer/dist/assets/{chunk-4BX2VUAB-BTPyM1ux.js → chunk-4BX2VUAB-Bgz1tnDP.js} +1 -1
  34. package/viewer/dist/assets/{chunk-55IACEB6-CtNd8e4Y.js → chunk-55IACEB6-NdWURd2K.js} +1 -1
  35. package/viewer/dist/assets/{chunk-5ZQYHXKU-Dd3yz721.js → chunk-5ZQYHXKU-wzW5x_7z.js} +1 -1
  36. package/viewer/dist/assets/{chunk-727SXJPM-CAM8mGbv.js → chunk-727SXJPM-BxKeJXYf.js} +1 -1
  37. package/viewer/dist/assets/{chunk-AQP2D5EJ-C3nW9Uve.js → chunk-AQP2D5EJ-gPm6xhPX.js} +1 -1
  38. package/viewer/dist/assets/{chunk-BSJP7CBP-r6MRPvAH.js → chunk-BSJP7CBP-C30ZXEUD.js} +1 -1
  39. package/viewer/dist/assets/{chunk-CSCIHK7Q-Cn-ZTxsS.js → chunk-CSCIHK7Q-C9h7yfl1.js} +1 -1
  40. package/viewer/dist/assets/{chunk-FMBD7UC4-5axXeZJa.js → chunk-FMBD7UC4-BcSnkYc3.js} +1 -1
  41. package/viewer/dist/assets/{chunk-KSCS5N6A-BwmNx0l0.js → chunk-KSCS5N6A-rxSD5-MD.js} +1 -1
  42. package/viewer/dist/assets/{chunk-L5ZTLDWV-C2YNkUjB.js → chunk-L5ZTLDWV-DGwFsVWy.js} +1 -1
  43. package/viewer/dist/assets/{chunk-LZXEDZCA-CznuDgQD.js → chunk-LZXEDZCA-BY3sTuvt.js} +2 -2
  44. package/viewer/dist/assets/{chunk-ND2GUHAM-CokDnghi.js → chunk-ND2GUHAM-PqmKwdzq.js} +1 -1
  45. package/viewer/dist/assets/{chunk-NZK2D7GU-aaU0v4QE.js → chunk-NZK2D7GU-BAZbzxhl.js} +1 -1
  46. package/viewer/dist/assets/{chunk-O5CBEL6O-ByfKhkZf.js → chunk-O5CBEL6O-SvZfZ-0j.js} +1 -1
  47. package/viewer/dist/assets/chunk-QZHKN3VN-ClYnv9g5.js +1 -0
  48. package/viewer/dist/assets/chunk-WU5MYG2G-CvL2Yleq.js +1 -0
  49. package/viewer/dist/assets/{chunk-XPW4576I-Amo3awtq.js → chunk-XPW4576I-1OXPbRQX.js} +1 -1
  50. package/viewer/dist/assets/classDiagram-4FO5ZUOK-B8YUd1jx.js +1 -0
  51. package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-B8YUd1jx.js +1 -0
  52. package/viewer/dist/assets/{cose-bilkent-S5V4N54A-CO8yESCW.js → cose-bilkent-S5V4N54A-DtCvLpah.js} +1 -1
  53. package/viewer/dist/assets/{dagre-BM42HDAG-BnmNVNI2.js → dagre-BM42HDAG-B55Ilz10.js} +1 -1
  54. package/viewer/dist/assets/{diagram-2AECGRRQ-lcGXcbei.js → diagram-2AECGRRQ-ClqSMarp.js} +1 -1
  55. package/viewer/dist/assets/{diagram-5GNKFQAL-Cj3-lPUt.js → diagram-5GNKFQAL-Dx74UdxY.js} +1 -1
  56. package/viewer/dist/assets/{diagram-KO2AKTUF-CtXdRI4M.js → diagram-KO2AKTUF-Vj0buH8e.js} +1 -1
  57. package/viewer/dist/assets/{diagram-LMA3HP47-CIyLAzX7.js → diagram-LMA3HP47-DpEm8RZd.js} +1 -1
  58. package/viewer/dist/assets/{diagram-OG6HWLK6-BwF4bQCv.js → diagram-OG6HWLK6-Crl3BdwC.js} +1 -1
  59. package/viewer/dist/assets/{dist-DzXuQd4N.js → dist-C2uHOEFB.js} +1 -1
  60. package/viewer/dist/assets/{erDiagram-TEJ5UH35-DjwFw9yq.js → erDiagram-TEJ5UH35-B-Mf-EHP.js} +1 -1
  61. package/viewer/dist/assets/eventmodeling-FCH6USID-CZ5gxAxG.js +1 -0
  62. package/viewer/dist/assets/{flowDiagram-I6XJVG4X-CzXbf7vQ.js → flowDiagram-I6XJVG4X-B9stChWN.js} +1 -1
  63. package/viewer/dist/assets/{ganttDiagram-6RSMTGT7-BYcIhfmm.js → ganttDiagram-6RSMTGT7-DzWlclwM.js} +1 -1
  64. package/viewer/dist/assets/{gitGraph-WXDBUCRP-H8XeJ9QB.js → gitGraph-WXDBUCRP-CdVI3GTp.js} +1 -1
  65. package/viewer/dist/assets/{gitGraphDiagram-PVQCEYII-DtAPXKFK.js → gitGraphDiagram-PVQCEYII-Dn9yRc1N.js} +1 -1
  66. package/viewer/dist/assets/{index-DLPCG_Or.js → index-BsGRgBOD.js} +4 -4
  67. package/viewer/dist/assets/{info-J43DQDTF-BQScorZ0.js → info-J43DQDTF-CXV3Mm9T.js} +1 -1
  68. package/viewer/dist/assets/{infoDiagram-5YYISTIA-Udl1omvH.js → infoDiagram-5YYISTIA-zIUka_J2.js} +1 -1
  69. package/viewer/dist/assets/{ishikawaDiagram-YF4QCWOH-VnfzT_hk.js → ishikawaDiagram-YF4QCWOH-DsZwNuE3.js} +1 -1
  70. package/viewer/dist/assets/{journeyDiagram-JHISSGLW-Btn4EVoD.js → journeyDiagram-JHISSGLW-BhSTSB2s.js} +1 -1
  71. package/viewer/dist/assets/{kanban-definition-UN3LZRKU-flOzWhPe.js → kanban-definition-UN3LZRKU-sCAldj86.js} +1 -1
  72. package/viewer/dist/assets/{line-DJJ9BLuY.js → line-D7b3fopb.js} +1 -1
  73. package/viewer/dist/assets/{linear-C2SUy5ns.js → linear-BWlvVc_d.js} +1 -1
  74. package/viewer/dist/assets/{mermaid-parser.core-xhSeYiZo.js → mermaid-parser.core-BdEYBvaj.js} +2 -2
  75. package/viewer/dist/assets/{mermaid.core-DmeSIitY.js → mermaid.core-C9bGWeJU.js} +3 -3
  76. package/viewer/dist/assets/{mindmap-definition-RKZ34NQL-CCJcMKx1.js → mindmap-definition-RKZ34NQL-DbTvvku-.js} +1 -1
  77. package/viewer/dist/assets/{packet-YPE3B663-DS8RscAk.js → packet-YPE3B663-DRfLruyq.js} +1 -1
  78. package/viewer/dist/assets/{pie-LRSECV5Y-I2ZQhrNJ.js → pie-LRSECV5Y-47xXMkK-.js} +1 -1
  79. package/viewer/dist/assets/{pieDiagram-4H26LBE5-BS5HMs4j.js → pieDiagram-4H26LBE5-Ckno9E1M.js} +1 -1
  80. package/viewer/dist/assets/{quadrantDiagram-W4KKPZXB-W4H8cw2_.js → quadrantDiagram-W4KKPZXB-XB5kJ_2c.js} +1 -1
  81. package/viewer/dist/assets/{radar-GUYGQ44K-kf6QvSne.js → radar-GUYGQ44K-CLwIH5Zr.js} +1 -1
  82. package/viewer/dist/assets/{requirementDiagram-4Y6WPE33-DSbuDQGQ.js → requirementDiagram-4Y6WPE33-D3fApL0X.js} +1 -1
  83. package/viewer/dist/assets/{sankeyDiagram-5OEKKPKP-CH8Qr2vL.js → sankeyDiagram-5OEKKPKP-6UdaRhuZ.js} +1 -1
  84. package/viewer/dist/assets/{sequenceDiagram-3UESZ5HK-EugVcdad.js → sequenceDiagram-3UESZ5HK-ClIrrs0w.js} +1 -1
  85. package/viewer/dist/assets/{src-CM_9kdrU.js → src-BPb55SrS.js} +1 -1
  86. package/viewer/dist/assets/{stateDiagram-AJRCARHV-DiFl94Qy.js → stateDiagram-AJRCARHV-CCsrcv5R.js} +1 -1
  87. package/viewer/dist/assets/stateDiagram-v2-BHNVJYJU-C1phrPNi.js +1 -0
  88. package/viewer/dist/assets/{timeline-definition-PNZ67QCA-B0KW9GUN.js → timeline-definition-PNZ67QCA-BkiWQlVI.js} +1 -1
  89. package/viewer/dist/assets/{treeView-BLDUP644-CAEY4mxq.js → treeView-BLDUP644-m1mGpAE8.js} +1 -1
  90. package/viewer/dist/assets/{treemap-LRROVOQU-VVaEaTlU.js → treemap-LRROVOQU-Bapvwi0Q.js} +1 -1
  91. package/viewer/dist/assets/{vennDiagram-CIIHVFJN-BSLGNfJd.js → vennDiagram-CIIHVFJN-BlH71Nmx.js} +1 -1
  92. package/viewer/dist/assets/{wardley-L42UT6IY-C-5cXbAU.js → wardley-L42UT6IY-CPRSoKgV.js} +1 -1
  93. package/viewer/dist/assets/{wardleyDiagram-YWT4CUSO-COk4TVnQ.js → wardleyDiagram-YWT4CUSO-C-ptFJ9t.js} +1 -1
  94. package/viewer/dist/assets/{xychartDiagram-2RQKCTM6-CClGJLJp.js → xychartDiagram-2RQKCTM6-C4rfeH4W.js} +1 -1
  95. package/viewer/dist/index.html +1 -1
  96. package/viewer/dist/assets/architecture-7EHR7CIX-Cbb-syEI.js +0 -1
  97. package/viewer/dist/assets/channel-C2bkEQHQ.js +0 -1
  98. package/viewer/dist/assets/chunk-QZHKN3VN-DJRjGeIo.js +0 -1
  99. package/viewer/dist/assets/chunk-WU5MYG2G-C63BVvr_.js +0 -1
  100. package/viewer/dist/assets/classDiagram-4FO5ZUOK-z_bO1V-j.js +0 -1
  101. package/viewer/dist/assets/classDiagram-v2-Q7XG4LA2-z_bO1V-j.js +0 -1
  102. package/viewer/dist/assets/eventmodeling-FCH6USID-BlKFmSzA.js +0 -1
  103. package/viewer/dist/assets/stateDiagram-v2-BHNVJYJU-BlJV8F13.js +0 -1
@@ -0,0 +1,46 @@
1
+ import type { Card, PlanIndex } from './types.js';
2
+ /**
3
+ * Code binding + attach. A card points at code two ways: a directly-connected
4
+ * FILE card (its `path:`, the primary binding) or the card's own `code_refs`
5
+ * (optional precision binding, `path` or `path:symbol`). Both resolve here.
6
+ *
7
+ * Cards never connect across repos (a Constellation invariant), so bound code is
8
+ * always in the card's OWN repo — resolved against the git repo root. To read a
9
+ * sibling repo's code, target that repo's plan with the `repo` selector.
10
+ */
11
+ export interface BoundPath {
12
+ /** Repo-relative path. */
13
+ path: string;
14
+ via: 'file-card' | 'code_ref';
15
+ /** FILE card handle, when bound via a connected FILE card. */
16
+ handle?: string;
17
+ /** Symbol hint, when a code_ref was written `path:symbol`. Informational. */
18
+ symbol?: string;
19
+ }
20
+ /** Every distinct file a card is bound to (connected FILE paths + own code_refs). */
21
+ export declare function boundPathsForCard(index: PlanIndex, card: Card): BoundPath[];
22
+ export interface CodeFile extends BoundPath {
23
+ exists: boolean;
24
+ bytes?: number;
25
+ /** Attached file contents (mode "direct" only, when not skipped). */
26
+ content?: string;
27
+ truncated?: boolean;
28
+ /** Why contents were not attached (missing, binary, lockfile, too large, budget). */
29
+ skipped?: string;
30
+ }
31
+ export interface CodeResolution {
32
+ /** Git repo root the paths resolve against, or null when not in a git repo. */
33
+ repo_root: string | null;
34
+ files: CodeFile[];
35
+ total_bytes: number;
36
+ budget_exhausted: boolean;
37
+ /** Bound files whose path no longer exists on disk — a drift signal. */
38
+ missing: string[];
39
+ }
40
+ /**
41
+ * Resolve a card's bound code. mode "paths" returns existence-checked paths
42
+ * (cheap; the agent Reads what it wants); mode "direct" also attaches file
43
+ * contents under per-file and total size caps, skipping binaries, lockfiles,
44
+ * and generated output, with truncation noted.
45
+ */
46
+ export declare function resolveCodeForCard(planRoot: string, index: PlanIndex, card: Card, mode: 'paths' | 'direct'): Promise<CodeResolution>;
@@ -0,0 +1,169 @@
1
+ import { readFile, realpath, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { repoRootFor } from './git.js';
4
+ /** Every distinct file a card is bound to (connected FILE paths + own code_refs). */
5
+ export function boundPathsForCard(index, card) {
6
+ const out = [];
7
+ const seen = new Set();
8
+ const add = (p, b) => {
9
+ if (!p || seen.has(p))
10
+ return;
11
+ seen.add(p);
12
+ out.push({ path: p, ...b });
13
+ };
14
+ // A FILE card is bound to its own path:.
15
+ if (card.type === 'FILE' && typeof card.frontmatter.path === 'string') {
16
+ add(card.frontmatter.path, { via: 'file-card', handle: card.handle });
17
+ }
18
+ for (const handle of [...(index.connectedHandles.get(card.handle) ?? [])].sort()) {
19
+ const neighbor = index.cards.get(handle);
20
+ if (!neighbor || neighbor.type !== 'FILE')
21
+ continue;
22
+ const p = neighbor.frontmatter.path;
23
+ if (typeof p === 'string')
24
+ add(p, { via: 'file-card', handle });
25
+ }
26
+ const refs = Array.isArray(card.frontmatter.code_refs) ? card.frontmatter.code_refs : [];
27
+ for (const ref of refs) {
28
+ if (typeof ref !== 'string')
29
+ continue;
30
+ const colon = ref.indexOf(':');
31
+ const p = colon > 0 ? ref.slice(0, colon) : ref;
32
+ const symbol = colon > 0 ? ref.slice(colon + 1) : undefined;
33
+ add(p, { via: 'code_ref', symbol });
34
+ }
35
+ return out;
36
+ }
37
+ const PER_FILE_MAX = 64 * 1024;
38
+ const TOTAL_MAX = 256 * 1024;
39
+ const SKIP_BASENAMES = new Set([
40
+ 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'npm-shrinkwrap.json',
41
+ 'composer.lock', 'cargo.lock', 'poetry.lock', 'gemfile.lock', 'go.sum',
42
+ ]);
43
+ const SKIP_DIR_RE = /(^|\/)(node_modules|dist|build|out|coverage|\.next|\.git|vendor)\//;
44
+ const BINARY_EXT = new Set([
45
+ '.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.svg', '.pdf', '.zip', '.gz',
46
+ '.tar', '.tgz', '.wasm', '.woff', '.woff2', '.ttf', '.eot', '.mp4', '.mov', '.mp3',
47
+ '.bin', '.exe', '.dll', '.so', '.dylib', '.class', '.jar', '.db', '.sqlite',
48
+ ]);
49
+ const GENERATED_RE = /\.min\.(js|css)$|\.map$|\.lock$/;
50
+ /** Why a path should not have its contents attached, or null to attach it. */
51
+ function skipReason(p) {
52
+ const base = path.basename(p).toLowerCase();
53
+ const ext = path.extname(p).toLowerCase();
54
+ if (SKIP_BASENAMES.has(base))
55
+ return 'lockfile';
56
+ if (base === '.env' || base.startsWith('.env.') || ext === '.pem' || ext === '.key') {
57
+ return 'secrets';
58
+ }
59
+ if (SKIP_DIR_RE.test(p))
60
+ return 'generated/vendored';
61
+ if (BINARY_EXT.has(ext))
62
+ return 'binary';
63
+ if (ext === '.snap' || ext === '.tsbuildinfo')
64
+ return 'generated';
65
+ if (GENERATED_RE.test(p))
66
+ return 'generated';
67
+ return null;
68
+ }
69
+ /**
70
+ * Resolve a card's bound code. mode "paths" returns existence-checked paths
71
+ * (cheap; the agent Reads what it wants); mode "direct" also attaches file
72
+ * contents under per-file and total size caps, skipping binaries, lockfiles,
73
+ * and generated output, with truncation noted.
74
+ */
75
+ export async function resolveCodeForCard(planRoot, index, card, mode) {
76
+ const bound = boundPathsForCard(index, card);
77
+ let repoRoot = null;
78
+ try {
79
+ repoRoot = await repoRootFor(await realpath(planRoot));
80
+ }
81
+ catch {
82
+ repoRoot = null;
83
+ }
84
+ // Canonical repo root for the symlink-escape check below.
85
+ const realRepoRoot = repoRoot ? await realpath(repoRoot).catch(() => repoRoot) : null;
86
+ const escapes = (real) => realRepoRoot !== null && real !== realRepoRoot && !real.startsWith(realRepoRoot + path.sep);
87
+ const files = [];
88
+ const missing = [];
89
+ let total = 0;
90
+ let budgetExhausted = false;
91
+ for (const b of bound) {
92
+ const abs = repoRoot ? path.resolve(repoRoot, b.path) : null;
93
+ // Containment: a bound path with `..` must not escape the repo root and read
94
+ // arbitrary files. Reject anything resolving outside, in every mode.
95
+ const inside = abs !== null && repoRoot !== null
96
+ ? abs === repoRoot || abs.startsWith(repoRoot + path.sep)
97
+ : false;
98
+ if (abs !== null && !inside) {
99
+ files.push({ ...b, exists: false, skipped: 'outside repo root' });
100
+ continue;
101
+ }
102
+ let exists = false;
103
+ let bytes;
104
+ if (abs) {
105
+ try {
106
+ const s = await stat(abs);
107
+ exists = s.isFile();
108
+ bytes = s.size;
109
+ }
110
+ catch {
111
+ exists = false;
112
+ }
113
+ }
114
+ // Symlink containment: a file inside the repo may itself be a symlink pointing
115
+ // OUT of it; lexical containment can't catch that. Resolve the real path and
116
+ // refuse anything that leaves the tree (in both modes — the path is reported either way).
117
+ if (exists && abs) {
118
+ try {
119
+ if (escapes(await realpath(abs))) {
120
+ files.push({ ...b, exists: false, skipped: 'symlink escapes repo root' });
121
+ continue;
122
+ }
123
+ }
124
+ catch {
125
+ files.push({ ...b, exists: false, skipped: 'unresolvable' });
126
+ continue;
127
+ }
128
+ }
129
+ if (!exists)
130
+ missing.push(b.path);
131
+ const file = { ...b, exists, bytes };
132
+ if (mode === 'direct') {
133
+ if (!exists) {
134
+ file.skipped = 'missing';
135
+ }
136
+ else {
137
+ const reason = skipReason(b.path);
138
+ if (reason) {
139
+ file.skipped = reason;
140
+ }
141
+ else if ((bytes ?? 0) > PER_FILE_MAX) {
142
+ file.skipped = `too large (${bytes} > ${PER_FILE_MAX} bytes)`;
143
+ }
144
+ else if (total + (bytes ?? 0) > TOTAL_MAX) {
145
+ file.skipped = 'total budget exhausted';
146
+ budgetExhausted = true;
147
+ }
148
+ else {
149
+ try {
150
+ const buf = await readFile(abs);
151
+ if (buf.includes(0)) {
152
+ file.skipped = 'binary';
153
+ }
154
+ else {
155
+ file.content = buf.toString('utf8');
156
+ total += buf.length;
157
+ }
158
+ }
159
+ catch {
160
+ file.skipped = 'unreadable';
161
+ }
162
+ }
163
+ }
164
+ }
165
+ files.push(file);
166
+ }
167
+ return { repo_root: repoRoot, files, total_bytes: total, budget_exhausted: budgetExhausted, missing };
168
+ }
169
+ //# sourceMappingURL=code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/core/code.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,14 @@ export declare function writeSyncPoint(planRoot: string, sha?: string): Promise<
11
11
  * the plan being dirty).
12
12
  */
13
13
  export declare function planDirty(planRoot: string): Promise<boolean>;
14
+ /** The current HEAD sha of the repo the plan lives in. */
15
+ export declare function headSha(planRoot: string): Promise<string>;
16
+ /**
17
+ * Of the given repo-relative paths, the subset that changed between `sinceSha`
18
+ * and the working tree — one git call. A path absent from the result is
19
+ * unchanged since that sha (file existence is checked separately, on disk).
20
+ */
21
+ export declare function changedFilesSince(planRoot: string, sinceSha: string, paths: string[]): Promise<Set<string>>;
14
22
  export type ChangeKind = 'added' | 'modified' | 'removed' | 'renamed';
15
23
  export interface PlanChange {
16
24
  handle: string;
package/dist/core/git.js CHANGED
@@ -12,6 +12,19 @@ async function git(cwd, ...args) {
12
12
  });
13
13
  return stdout;
14
14
  }
15
+ /**
16
+ * Guard a caller-supplied git revision. A value starting with `-` would be
17
+ * parsed by git as an option, not a revision — e.g. `--output=/path` makes
18
+ * `git diff` write an arbitrary file. We both reject leading-dash revisions here
19
+ * and pass `--end-of-options` before every revision below, so no caller string
20
+ * is ever interpreted as a flag.
21
+ */
22
+ function safeRev(rev) {
23
+ if (rev.startsWith('-')) {
24
+ throw new Error(`Refusing git revision that looks like an option: ${rev}`);
25
+ }
26
+ return rev;
27
+ }
15
28
  export async function repoRootFor(planRoot) {
16
29
  return (await git(planRoot, 'rev-parse', '--show-toplevel')).trim();
17
30
  }
@@ -28,7 +41,7 @@ export async function readSyncPoint(planRoot) {
28
41
  }
29
42
  export async function writeSyncPoint(planRoot, sha) {
30
43
  const resolved = sha
31
- ? (await git(planRoot, 'rev-parse', sha)).trim()
44
+ ? (await git(planRoot, 'rev-parse', '--end-of-options', safeRev(sha))).trim()
32
45
  : (await git(planRoot, 'rev-parse', 'HEAD')).trim();
33
46
  const point = {
34
47
  synced_sha: resolved,
@@ -49,6 +62,25 @@ export async function planDirty(planRoot) {
49
62
  const out = await git(repoRoot, 'status', '--porcelain', '--', planRel, `:(exclude)${path.join(planRel, SYNC_FILE)}`);
50
63
  return out.trim().length > 0;
51
64
  }
65
+ /** The current HEAD sha of the repo the plan lives in. */
66
+ export async function headSha(planRoot) {
67
+ const realRoot = await realpath(planRoot);
68
+ const repoRoot = await repoRootFor(realRoot);
69
+ return (await git(repoRoot, 'rev-parse', 'HEAD')).trim();
70
+ }
71
+ /**
72
+ * Of the given repo-relative paths, the subset that changed between `sinceSha`
73
+ * and the working tree — one git call. A path absent from the result is
74
+ * unchanged since that sha (file existence is checked separately, on disk).
75
+ */
76
+ export async function changedFilesSince(planRoot, sinceSha, paths) {
77
+ if (paths.length === 0)
78
+ return new Set();
79
+ const realRoot = await realpath(planRoot);
80
+ const repoRoot = await repoRootFor(realRoot);
81
+ const out = await git(repoRoot, 'diff', '--name-only', '--end-of-options', safeRev(sinceSha), '--', ...paths);
82
+ return new Set(out.split('\n').map((l) => l.trim()).filter(Boolean));
83
+ }
52
84
  export async function diffPlan(planRoot, base, head) {
53
85
  // realpath: git reports the canonical repo root, which may differ from the
54
86
  // caller's path through symlinks (e.g. /var vs /private/var on macOS).
@@ -68,9 +100,9 @@ export async function diffPlan(planRoot, base, head) {
68
100
  baseSource = 'HEAD';
69
101
  }
70
102
  }
71
- const args = ['diff', '--name-status', '-M', resolvedBase];
103
+ const args = ['diff', '--name-status', '-M', '--end-of-options', safeRev(resolvedBase)];
72
104
  if (head)
73
- args.push(head);
105
+ args.push(safeRev(head));
74
106
  args.push('--', planRel);
75
107
  const output = await git(repoRoot, ...args);
76
108
  const changes = [];
@@ -223,7 +255,7 @@ export async function countCodeCommitsSince(planRoot, sinceSha) {
223
255
  const realRoot = await realpath(planRoot);
224
256
  const repoRoot = await repoRootFor(realRoot);
225
257
  const planRel = path.relative(repoRoot, realRoot) || '.';
226
- const out = await git(repoRoot, 'rev-list', '--count', `${sinceSha}..HEAD`, '--', '.', `:(exclude)${planRel}`);
258
+ const out = await git(repoRoot, 'rev-list', '--count', `${safeRev(sinceSha)}..HEAD`, '--', '.', `:(exclude)${planRel}`);
227
259
  return Number.parseInt(out.trim(), 10) || 0;
228
260
  }
229
261
  //# sourceMappingURL=git.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export type SyncState = 'in-sync' | 'drifted' | 'dirty' | 'never-synced' | 'no-g
3
3
  export interface SyncStatus {
4
4
  state: SyncState;
5
5
  marker: SyncPoint | null;
6
+ marker_error: string | null;
6
7
  plan_dirty: boolean;
7
8
  plan_changes_since_marker: number;
8
9
  code_commits_since_marker: number;
package/dist/core/sync.js CHANGED
@@ -32,6 +32,7 @@ export async function computeSyncStatus(planRoot, options = {}) {
32
32
  let plan_dirty = false;
33
33
  let plan_changes_since_marker = 0;
34
34
  let code_commits_since_marker = 0;
35
+ let marker_error = null;
35
36
  let activity = [];
36
37
  try {
37
38
  marker = await readSyncPoint(planRoot);
@@ -42,14 +43,14 @@ export async function computeSyncStatus(planRoot, options = {}) {
42
43
  const diff = await diffPlan(planRoot, marker.synced_sha, 'HEAD');
43
44
  plan_changes_since_marker = diff.changes.length;
44
45
  }
45
- catch {
46
- // marker sha unreachable (e.g. rebased history) — leave 0
46
+ catch (err) {
47
+ marker_error = markerError(marker.synced_sha, err);
47
48
  }
48
49
  try {
49
50
  code_commits_since_marker = await countCodeCommitsSince(planRoot, marker.synced_sha);
50
51
  }
51
- catch {
52
- // ignore drift count is best-effort
52
+ catch (err) {
53
+ marker_error ??= markerError(marker.synced_sha, err);
53
54
  }
54
55
  }
55
56
  }
@@ -58,6 +59,7 @@ export async function computeSyncStatus(planRoot, options = {}) {
58
59
  return {
59
60
  state: 'no-git',
60
61
  marker: null,
62
+ marker_error: null,
61
63
  plan_dirty: false,
62
64
  plan_changes_since_marker: 0,
63
65
  code_commits_since_marker: 0,
@@ -67,14 +69,17 @@ export async function computeSyncStatus(planRoot, options = {}) {
67
69
  }
68
70
  const state = !marker
69
71
  ? 'never-synced'
70
- : plan_changes_since_marker > 0 || code_commits_since_marker > 0
72
+ : marker_error
71
73
  ? 'drifted'
72
- : plan_dirty
73
- ? 'dirty'
74
- : 'in-sync';
74
+ : plan_changes_since_marker > 0 || code_commits_since_marker > 0
75
+ ? 'drifted'
76
+ : plan_dirty
77
+ ? 'dirty'
78
+ : 'in-sync';
75
79
  return {
76
80
  state,
77
81
  marker,
82
+ marker_error,
78
83
  plan_dirty,
79
84
  plan_changes_since_marker,
80
85
  code_commits_since_marker,
@@ -82,4 +87,9 @@ export async function computeSyncStatus(planRoot, options = {}) {
82
87
  ...base,
83
88
  };
84
89
  }
90
+ function markerError(sha, err) {
91
+ const reason = err instanceof Error ? err.message : String(err);
92
+ return (`Sync marker ${sha.slice(0, 12)} is not reachable in git history; ` +
93
+ `reconcile the plan and run set_sync_point again. ${reason}`);
94
+ }
85
95
  //# sourceMappingURL=sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/core/sync.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,17 @@ import { TYPE_FOLDERS } from './handles.js';
7
7
  const require = createRequire(import.meta.url);
8
8
  const ajvModule = require('ajv/dist/2020.js');
9
9
  const Ajv2020 = ajvModule.default ?? ajvModule;
10
+ // The four reserved keys, plus any cross-type metadata fields card.json defines
11
+ // (code_refs, verified_sha, verified_at, notes). Deriving the base allow-list
12
+ // from card.json — rather than a hardcoded list — means a new optional metadata
13
+ // field is blessed on every type the moment it is added to the schema, and AJV
14
+ // validates its shape (W002) on every card via cardValidator.
10
15
  const RESERVED_KEYS = ['name', 'kind', 'status', 'connections'];
16
+ function baseKeysFrom(cardSchema) {
17
+ const props = cardSchema?.properties ?? {};
18
+ const keys = Object.keys(props);
19
+ return keys.length > 0 ? keys : RESERVED_KEYS;
20
+ }
11
21
  export async function loadSchemas(schemasDir) {
12
22
  const dir = schemasDir ?? path.join(fileURLToPath(new URL('../..', import.meta.url)), 'schemas');
13
23
  const ajv = new Ajv2020({ allErrors: true, allowUnionTypes: true });
@@ -19,6 +29,7 @@ export async function loadSchemas(schemasDir) {
19
29
  ajv.addSchema(schema, file);
20
30
  }
21
31
  const cardValidator = ajv.getSchema('card.json');
32
+ const baseKeys = baseKeysFrom(raw.get('card.json'));
22
33
  const typeValidators = new Map();
23
34
  const knownKeys = new Map();
24
35
  for (const [type, folder] of Object.entries(TYPE_FOLDERS)) {
@@ -28,7 +39,7 @@ export async function loadSchemas(schemasDir) {
28
39
  continue;
29
40
  typeValidators.set(type, ajv.getSchema(file));
30
41
  const props = Object.keys(schema.properties ?? {});
31
- knownKeys.set(type, new Set([...RESERVED_KEYS, ...props]));
42
+ knownKeys.set(type, new Set([...baseKeys, ...props]));
32
43
  }
33
44
  return {
34
45
  validateCard(card) {
@@ -46,7 +57,7 @@ export async function loadSchemas(schemasDir) {
46
57
  }
47
58
  }
48
59
  }
49
- const known = knownKeys.get(card.type) ?? new Set(RESERVED_KEYS);
60
+ const known = knownKeys.get(card.type) ?? new Set(baseKeys);
50
61
  for (const key of Object.keys(card.frontmatter)) {
51
62
  if (!known.has(key)) {
52
63
  issues.push({
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,4EAA4E;AAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC;AAW/C,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEhE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAmB;IACnD,MAAM,GAAG,GACP,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAEvF,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAmC,CAAC;IACvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtB,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,CAAC,SAAS,CAAC,WAAW,CAAe,CAAC;IAC/D,MAAM,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEnD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,GAAG,MAAM,OAAO,CAAC;QAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,cAAc,CAAC,GAAG,CAAC,IAAgB,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAe,CAAC,CAAC;QACxE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACtB,MAAM,CAAC,UAAkD,IAAI,EAAE,CACjE,CAAC;QACF,SAAS,CAAC,GAAG,CAAC,IAAgB,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,OAAO;QACL,YAAY,CAAC,IAAU;YACrB,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CACtE,OAAO,CACQ,CAAC;YAElB,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;gBAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;oBAChC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;wBACxC,MAAM,CAAC,IAAI,CAAC;4BACV,QAAQ,EAAE,SAAS;4BACnB,IAAI,EAAE,MAAM;4BACZ,OAAO,EAAE,cAAc,GAAG,CAAC,YAAY,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,IAAI,YAAY,EAAE;4BAC9E,IAAI,EAAE,IAAI,CAAC,OAAO;yBACnB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;YACjE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;gBAChD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpB,MAAM,CAAC,IAAI,CAAC;wBACV,QAAQ,EAAE,SAAS;wBACnB,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,iCAAiC,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE;wBAC7D,IAAI,EAAE,IAAI,CAAC,OAAO;qBACnB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,31 @@ export interface CardPatch {
16
16
  }
17
17
  /** Shared patch semantics for MCP update_card and the viewer's PATCH endpoint. */
18
18
  export declare function applyCardPatch(frontmatter: Record<string, unknown>, patch: CardPatch): Record<string, unknown>;
19
+ export type NoteKind = 'decision' | 'gotcha' | 'state' | 'deviation' | 'verified';
20
+ export interface CardNote {
21
+ kind: NoteKind;
22
+ text: string;
23
+ sha?: string;
24
+ }
25
+ /**
26
+ * Append a typed note to a card's `notes` array (append-only memory). Preserves
27
+ * frontmatter key order — when `notes` already exists it is updated in place, so
28
+ * updateCardFile re-serializes only that one key and leaves the rest byte-for-byte.
29
+ */
30
+ export declare function withAppendedNote(frontmatter: Record<string, unknown>, note: CardNote): Record<string, unknown>;
31
+ /** Heading texts of a body (fence-aware) — for surfacing the available sections. */
32
+ export declare function bodyHeadingTexts(body: string): string[];
33
+ /**
34
+ * Replace the content under a markdown heading (matched by heading text,
35
+ * case-insensitively) with `newContent`, keeping the heading line and every
36
+ * other section byte-for-byte. The replaced span runs from just after the
37
+ * heading to the next heading of the same or higher level (or end of body).
38
+ * Headings inside fenced code blocks are ignored, so a `#`-line in a ```sh block
39
+ * is never mistaken for a section. Returns null when the heading is absent OR
40
+ * ambiguous (more than one match) — the caller tells the two apart via
41
+ * bodyHeadingTexts and reports accordingly.
42
+ */
43
+ export declare function replaceBodySection(body: string, heading: string, newContent: string): string | null;
19
44
  export declare function composeCard(fm: Record<string, unknown>, body: string): string;
20
45
  /** Path a handle's card file belongs at, relative to the plan root. */
21
46
  export declare function relPathForHandle(handle: string): string;
@@ -2,7 +2,9 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import yaml from 'js-yaml';
4
4
  import { TYPE_FOLDERS, typeForHandle } from './handles.js';
5
- const FM_BLOCK = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
5
+ // The `(?:\r?\n)?` before the closing fence keeps a truly-empty block (`---\n---`)
6
+ // matchable, so a frontmatter-only write doesn't mistake it for body and duplicate it.
7
+ const FM_BLOCK = /^---\r?\n([\s\S]*?)(?:\r?\n)?---\r?\n?/;
6
8
  const RESERVED_FRONTMATTER_KEYS = new Set(['name', 'kind', 'status', 'connections']);
7
9
  export function reservedFieldKeys(fields) {
8
10
  return Object.keys(fields ?? {}).filter((key) => RESERVED_FRONTMATTER_KEYS.has(key));
@@ -54,6 +56,68 @@ function isPlainObject(value) {
54
56
  !Array.isArray(value) &&
55
57
  Object.getPrototypeOf(value) === Object.prototype);
56
58
  }
59
+ /**
60
+ * Append a typed note to a card's `notes` array (append-only memory). Preserves
61
+ * frontmatter key order — when `notes` already exists it is updated in place, so
62
+ * updateCardFile re-serializes only that one key and leaves the rest byte-for-byte.
63
+ */
64
+ export function withAppendedNote(frontmatter, note) {
65
+ const existing = Array.isArray(frontmatter.notes) ? frontmatter.notes : [];
66
+ const entry = { kind: note.kind, text: note.text };
67
+ if (note.sha)
68
+ entry.sha = note.sha;
69
+ return { ...frontmatter, notes: [...existing, entry] };
70
+ }
71
+ const HEADING_RE = /^(#{1,6})\s+(.*?)\s*$/;
72
+ const FENCE_RE = /^\s*(```|~~~)/;
73
+ /** Markdown headings in a body, skipping any inside fenced code blocks. */
74
+ function scanHeadings(lines) {
75
+ const out = [];
76
+ let inFence = false;
77
+ for (let i = 0; i < lines.length; i++) {
78
+ if (FENCE_RE.test(lines[i])) {
79
+ inFence = !inFence;
80
+ continue;
81
+ }
82
+ if (inFence)
83
+ continue;
84
+ const m = HEADING_RE.exec(lines[i]);
85
+ if (m)
86
+ out.push({ line: i, level: m[1].length, text: m[2].trim() });
87
+ }
88
+ return out;
89
+ }
90
+ /** Heading texts of a body (fence-aware) — for surfacing the available sections. */
91
+ export function bodyHeadingTexts(body) {
92
+ return scanHeadings(body.split('\n')).map((h) => h.text);
93
+ }
94
+ /**
95
+ * Replace the content under a markdown heading (matched by heading text,
96
+ * case-insensitively) with `newContent`, keeping the heading line and every
97
+ * other section byte-for-byte. The replaced span runs from just after the
98
+ * heading to the next heading of the same or higher level (or end of body).
99
+ * Headings inside fenced code blocks are ignored, so a `#`-line in a ```sh block
100
+ * is never mistaken for a section. Returns null when the heading is absent OR
101
+ * ambiguous (more than one match) — the caller tells the two apart via
102
+ * bodyHeadingTexts and reports accordingly.
103
+ */
104
+ export function replaceBodySection(body, heading, newContent) {
105
+ const target = heading.trim().replace(/^#+\s*/, '').toLowerCase();
106
+ const lines = body.split('\n');
107
+ const headings = scanHeadings(lines);
108
+ const matches = headings.filter((h) => h.text.toLowerCase() === target);
109
+ if (matches.length !== 1)
110
+ return null; // absent or ambiguous
111
+ const { line: startIdx, level } = matches[0];
112
+ const next = headings.find((h) => h.line > startIdx && h.level <= level);
113
+ const endIdx = next ? next.line : lines.length;
114
+ const before = lines.slice(0, startIdx + 1).join('\n');
115
+ const after = lines.slice(endIdx).join('\n');
116
+ const content = newContent.replace(/\s+$/, '');
117
+ return after.trim().length > 0
118
+ ? `${before}\n\n${content}\n\n${after}`
119
+ : `${before}\n\n${content}\n`;
120
+ }
57
121
  function dumpFrontmatter(fm) {
58
122
  // js-yaml dumps in insertion order; deepMerge preserves it, so existing key
59
123
  // order survives a rewrite. Style normalizes (flow maps may become block).