@refrakt-md/plan 0.9.5 → 0.9.7

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/cards.d.ts +23 -0
  2. package/dist/cards.d.ts.map +1 -0
  3. package/dist/cards.js +150 -0
  4. package/dist/cards.js.map +1 -0
  5. package/dist/cli-plugin.d.ts.map +1 -1
  6. package/dist/cli-plugin.js +68 -5
  7. package/dist/cli-plugin.js.map +1 -1
  8. package/dist/commands/build.d.ts.map +1 -1
  9. package/dist/commands/build.js +13 -0
  10. package/dist/commands/build.js.map +1 -1
  11. package/dist/commands/create.js +3 -3
  12. package/dist/commands/create.js.map +1 -1
  13. package/dist/commands/history.d.ts +21 -0
  14. package/dist/commands/history.d.ts.map +1 -0
  15. package/dist/commands/history.js +261 -0
  16. package/dist/commands/history.js.map +1 -0
  17. package/dist/commands/init.d.ts +7 -2
  18. package/dist/commands/init.d.ts.map +1 -1
  19. package/dist/commands/init.js +149 -26
  20. package/dist/commands/init.js.map +1 -1
  21. package/dist/commands/next.d.ts.map +1 -1
  22. package/dist/commands/next.js +22 -6
  23. package/dist/commands/next.js.map +1 -1
  24. package/dist/commands/plan-behaviors.js +2 -1
  25. package/dist/commands/plan-behaviors.js.map +1 -1
  26. package/dist/commands/render-pipeline.d.ts.map +1 -1
  27. package/dist/commands/render-pipeline.js +148 -128
  28. package/dist/commands/render-pipeline.js.map +1 -1
  29. package/dist/commands/serve.d.ts.map +1 -1
  30. package/dist/commands/serve.js +54 -0
  31. package/dist/commands/serve.js.map +1 -1
  32. package/dist/commands/templates.js +13 -13
  33. package/dist/commands/templates.js.map +1 -1
  34. package/dist/commands/update.d.ts.map +1 -1
  35. package/dist/commands/update.js +39 -11
  36. package/dist/commands/update.js.map +1 -1
  37. package/dist/commands/validate.d.ts.map +1 -1
  38. package/dist/commands/validate.js +119 -1
  39. package/dist/commands/validate.js.map +1 -1
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js +86 -23
  42. package/dist/config.js.map +1 -1
  43. package/dist/diff.d.ts +35 -0
  44. package/dist/diff.d.ts.map +1 -0
  45. package/dist/diff.js +88 -0
  46. package/dist/diff.js.map +1 -0
  47. package/dist/entity-tabs-behavior.d.ts +13 -0
  48. package/dist/entity-tabs-behavior.d.ts.map +1 -0
  49. package/dist/entity-tabs-behavior.js +94 -0
  50. package/dist/entity-tabs-behavior.js.map +1 -0
  51. package/dist/history.d.ts +89 -0
  52. package/dist/history.d.ts.map +1 -0
  53. package/dist/history.js +336 -0
  54. package/dist/history.js.map +1 -0
  55. package/dist/index.d.ts +2 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +11 -1
  58. package/dist/index.js.map +1 -1
  59. package/dist/pipeline.d.ts +11 -11
  60. package/dist/pipeline.d.ts.map +1 -1
  61. package/dist/pipeline.js +468 -202
  62. package/dist/pipeline.js.map +1 -1
  63. package/dist/relationships.d.ts +36 -0
  64. package/dist/relationships.d.ts.map +1 -0
  65. package/dist/relationships.js +128 -0
  66. package/dist/relationships.js.map +1 -0
  67. package/dist/scanner-core.d.ts +10 -0
  68. package/dist/scanner-core.d.ts.map +1 -0
  69. package/dist/scanner-core.js +230 -0
  70. package/dist/scanner-core.js.map +1 -0
  71. package/dist/scanner.d.ts +2 -1
  72. package/dist/scanner.d.ts.map +1 -1
  73. package/dist/scanner.js +7 -124
  74. package/dist/scanner.js.map +1 -1
  75. package/dist/tags/bug.d.ts.map +1 -1
  76. package/dist/tags/bug.js +22 -1
  77. package/dist/tags/bug.js.map +1 -1
  78. package/dist/tags/decision.d.ts.map +1 -1
  79. package/dist/tags/decision.js +23 -1
  80. package/dist/tags/decision.js.map +1 -1
  81. package/dist/tags/milestone.d.ts.map +1 -1
  82. package/dist/tags/milestone.js +7 -4
  83. package/dist/tags/milestone.js.map +1 -1
  84. package/dist/tags/plan-history.d.ts +4 -0
  85. package/dist/tags/plan-history.d.ts.map +1 -0
  86. package/dist/tags/plan-history.js +46 -0
  87. package/dist/tags/plan-history.js.map +1 -0
  88. package/dist/tags/spec.d.ts.map +1 -1
  89. package/dist/tags/spec.js +4 -5
  90. package/dist/tags/spec.js.map +1 -1
  91. package/dist/tags/work.d.ts.map +1 -1
  92. package/dist/tags/work.js +28 -7
  93. package/dist/tags/work.js.map +1 -1
  94. package/dist/types.d.ts +20 -0
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/util.d.ts +2 -0
  97. package/dist/util.d.ts.map +1 -1
  98. package/dist/util.js +10 -0
  99. package/dist/util.js.map +1 -1
  100. package/package.json +26 -9
  101. package/styles/default.css +0 -586
  102. package/styles/minimal.css +0 -386
  103. package/styles/tokens.css +0 -13
@@ -0,0 +1,89 @@
1
+ import { type AttributeChange, type CriteriaChange } from './diff.js';
2
+ export { diffAttributes, diffCriteria, parseTagAttributes, parseCheckboxes, hasResolutionSection, } from './diff.js';
3
+ export type { AttributeChange, CriteriaChange, ParsedCheckbox } from './diff.js';
4
+ export interface HistoryEvent {
5
+ kind: 'created' | 'attributes' | 'criteria' | 'resolution' | 'content';
6
+ hash: string;
7
+ shortHash: string;
8
+ date: string;
9
+ author: string;
10
+ message: string;
11
+ /** Attribute changes (only for kind === 'attributes') */
12
+ attributeChanges?: AttributeChange[];
13
+ /** Criteria changes (only for kind === 'criteria') */
14
+ criteriaChanges?: CriteriaChange[];
15
+ /** Present when kind === 'created' — initial attribute snapshot */
16
+ initialAttributes?: Record<string, string>;
17
+ }
18
+ interface CommitInfo {
19
+ hash: string;
20
+ date: string;
21
+ author: string;
22
+ message: string;
23
+ }
24
+ /**
25
+ * Get the ordered list of commits that touched a file (oldest first).
26
+ * Uses --follow to track renames.
27
+ */
28
+ export declare function getFileCommits(filePath: string, cwd: string): CommitInfo[];
29
+ /**
30
+ * Get file contents at a specific commit.
31
+ */
32
+ export declare function getFileAtCommit(hash: string, filePath: string, cwd: string): string | null;
33
+ /**
34
+ * Detect whether the current repository is a shallow clone.
35
+ */
36
+ export declare function isShallowClone(cwd: string): boolean;
37
+ /**
38
+ * Extract the history timeline for a single plan entity file.
39
+ *
40
+ * @param filePath - Path to the entity file, relative to cwd
41
+ * @param cwd - Working directory (typically the repo root or plan directory)
42
+ * @returns Array of HistoryEvent objects, oldest first
43
+ */
44
+ export declare function extractEntityHistory(filePath: string, cwd: string): HistoryEvent[];
45
+ interface BatchCommitInfo {
46
+ hash: string;
47
+ date: string;
48
+ author: string;
49
+ message: string;
50
+ files: string[];
51
+ }
52
+ /**
53
+ * Get all commits affecting a directory, with their affected file lists.
54
+ * Returns newest-first (git default).
55
+ */
56
+ export declare function getBatchCommits(planDir: string, cwd: string, since?: string): BatchCommitInfo[];
57
+ /**
58
+ * Extract history for all plan entities in a directory.
59
+ * Groups commits by file path and runs per-entity extraction for files
60
+ * with more than one commit. Single-commit files get a created event.
61
+ *
62
+ * @returns Map of file path → HistoryEvent[]
63
+ */
64
+ export declare function extractBatchHistory(planDir: string, cwd: string, options?: {
65
+ since?: string;
66
+ cache?: HistoryCache;
67
+ }): Map<string, HistoryEvent[]>;
68
+ export interface HistoryCacheEntry {
69
+ latestCommit: string;
70
+ events: HistoryEvent[];
71
+ }
72
+ export interface HistoryCache {
73
+ entries: Record<string, HistoryCacheEntry>;
74
+ }
75
+ /**
76
+ * Read the history cache from disk.
77
+ */
78
+ export declare function readHistoryCache(planDir: string): HistoryCache;
79
+ /**
80
+ * Write the history cache to disk.
81
+ * Silently skips if the directory doesn't exist or writing fails.
82
+ */
83
+ export declare function writeHistoryCache(planDir: string, cache: HistoryCache): void;
84
+ /**
85
+ * Build a unified global timeline from batch history results.
86
+ * Returns events sorted by date descending (newest first), with commit hash grouping info.
87
+ */
88
+ export declare function buildGlobalTimeline(batchHistory: Map<string, HistoryEvent[]>): HistoryEvent[];
89
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAMA,OAAO,EAMN,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACN,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,oBAAoB,GACpB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjF,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,sDAAsD;IACtD,eAAe,CAAC,EAAE,cAAc,EAAE,CAAC;IACnC,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAID,UAAU,UAAU;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAiC1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW1F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWnD;AAqBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CA8GlF;AAID,UAAU,eAAe;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CA2C/F;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAO,GACpD,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CA2D7B;AAID,MAAM,WAAW,iBAAiB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC3C;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAQ9D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAM5E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,GACvC,YAAY,EAAE,CAQhB"}
@@ -0,0 +1,336 @@
1
+ // ─── Git-Native Entity History ───
2
+ // Derives structured lifecycle events from git commits for plan entities.
3
+ import { execSync } from 'node:child_process';
4
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { diffAttributes, diffCriteria, parseTagAttributes, parseCheckboxes, hasResolutionSection, } from './diff.js';
7
+ // Re-export pure diffing functions and types for backwards compatibility
8
+ export { diffAttributes, diffCriteria, parseTagAttributes, parseCheckboxes, hasResolutionSection, } from './diff.js';
9
+ /**
10
+ * Get the ordered list of commits that touched a file (oldest first).
11
+ * Uses --follow to track renames.
12
+ */
13
+ export function getFileCommits(filePath, cwd) {
14
+ try {
15
+ const output = execSync(`git log --follow --format="%H %aI %aN%n%s" -- "${filePath}"`, { cwd, encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'] });
16
+ const commits = [];
17
+ const lines = output.trim().split('\n');
18
+ for (let i = 0; i < lines.length; i += 2) {
19
+ const metaLine = lines[i]?.trim();
20
+ const messageLine = lines[i + 1]?.trim();
21
+ if (!metaLine)
22
+ continue;
23
+ // Parse: HASH ISO_DATE AUTHOR_NAME
24
+ const spaceIdx1 = metaLine.indexOf(' ');
25
+ const spaceIdx2 = metaLine.indexOf(' ', spaceIdx1 + 1);
26
+ if (spaceIdx1 === -1 || spaceIdx2 === -1)
27
+ continue;
28
+ const hash = metaLine.slice(0, spaceIdx1);
29
+ const date = metaLine.slice(spaceIdx1 + 1, spaceIdx2);
30
+ const author = metaLine.slice(spaceIdx2 + 1);
31
+ commits.push({ hash, date, author, message: messageLine ?? '' });
32
+ }
33
+ // Reverse to oldest-first for diffing
34
+ commits.reverse();
35
+ return commits;
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ }
41
+ /**
42
+ * Get file contents at a specific commit.
43
+ */
44
+ export function getFileAtCommit(hash, filePath, cwd) {
45
+ try {
46
+ return execSync(`git show "${hash}:${filePath}"`, { cwd, encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024, stdio: ['pipe', 'pipe', 'pipe'] });
47
+ }
48
+ catch {
49
+ // File may not exist at this commit (pre-rename)
50
+ // Try to find the file via diff-tree to handle renames
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Detect whether the current repository is a shallow clone.
56
+ */
57
+ export function isShallowClone(cwd) {
58
+ try {
59
+ const result = execSync('git rev-parse --is-shallow-repository', {
60
+ cwd,
61
+ encoding: 'utf-8',
62
+ stdio: ['pipe', 'pipe', 'pipe'],
63
+ }).trim();
64
+ return result === 'true';
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ }
70
+ function snapshotFromContent(content) {
71
+ const firstLine = content.split('\n')[0] ?? '';
72
+ return {
73
+ attributes: parseTagAttributes(firstLine),
74
+ checkboxes: parseCheckboxes(content),
75
+ hasResolution: hasResolutionSection(content),
76
+ rawContent: content,
77
+ };
78
+ }
79
+ /**
80
+ * Extract the history timeline for a single plan entity file.
81
+ *
82
+ * @param filePath - Path to the entity file, relative to cwd
83
+ * @param cwd - Working directory (typically the repo root or plan directory)
84
+ * @returns Array of HistoryEvent objects, oldest first
85
+ */
86
+ export function extractEntityHistory(filePath, cwd) {
87
+ const commits = getFileCommits(filePath, cwd);
88
+ if (commits.length === 0)
89
+ return [];
90
+ const events = [];
91
+ let prevSnapshot = null;
92
+ for (let i = 0; i < commits.length; i++) {
93
+ const commit = commits[i];
94
+ const content = getFileAtCommit(commit.hash, filePath, cwd);
95
+ // If we can't get the file content (e.g. pre-rename), try the old name
96
+ if (content === null) {
97
+ // For renamed files, the first commits may fail to resolve.
98
+ // Record a content event since we know the file was touched.
99
+ if (i === 0) {
100
+ events.push({
101
+ kind: 'created',
102
+ hash: commit.hash,
103
+ shortHash: commit.hash.slice(0, 7),
104
+ date: commit.date,
105
+ author: commit.author,
106
+ message: commit.message,
107
+ initialAttributes: {},
108
+ });
109
+ }
110
+ continue;
111
+ }
112
+ const snapshot = snapshotFromContent(content);
113
+ const shortHash = commit.hash.slice(0, 7);
114
+ if (i === 0) {
115
+ // First commit — this is the creation event
116
+ events.push({
117
+ kind: 'created',
118
+ hash: commit.hash,
119
+ shortHash,
120
+ date: commit.date,
121
+ author: commit.author,
122
+ message: commit.message,
123
+ initialAttributes: { ...snapshot.attributes },
124
+ });
125
+ }
126
+ else {
127
+ // Subsequent commits — diff against previous snapshot
128
+ const attrChanges = prevSnapshot ? diffAttributes(prevSnapshot.attributes, snapshot.attributes) : [];
129
+ const criteriaChanges = prevSnapshot ? diffCriteria(prevSnapshot.checkboxes, snapshot.checkboxes) : [];
130
+ const resolutionAdded = prevSnapshot ? (!prevSnapshot.hasResolution && snapshot.hasResolution) : false;
131
+ const resolutionModified = prevSnapshot?.hasResolution && snapshot.hasResolution && prevSnapshot.rawContent !== snapshot.rawContent;
132
+ if (attrChanges.length > 0 && criteriaChanges.length > 0) {
133
+ // Both attributes and criteria changed — emit a combined event
134
+ // Attribute changes take priority for the event kind
135
+ events.push({
136
+ kind: 'attributes',
137
+ hash: commit.hash,
138
+ shortHash,
139
+ date: commit.date,
140
+ author: commit.author,
141
+ message: commit.message,
142
+ attributeChanges: attrChanges,
143
+ criteriaChanges,
144
+ });
145
+ }
146
+ else if (attrChanges.length > 0) {
147
+ events.push({
148
+ kind: 'attributes',
149
+ hash: commit.hash,
150
+ shortHash,
151
+ date: commit.date,
152
+ author: commit.author,
153
+ message: commit.message,
154
+ attributeChanges: attrChanges,
155
+ });
156
+ }
157
+ else if (criteriaChanges.length > 0) {
158
+ events.push({
159
+ kind: 'criteria',
160
+ hash: commit.hash,
161
+ shortHash,
162
+ date: commit.date,
163
+ author: commit.author,
164
+ message: commit.message,
165
+ criteriaChanges,
166
+ });
167
+ }
168
+ else if (resolutionAdded || resolutionModified) {
169
+ events.push({
170
+ kind: 'resolution',
171
+ hash: commit.hash,
172
+ shortHash,
173
+ date: commit.date,
174
+ author: commit.author,
175
+ message: commit.message,
176
+ });
177
+ }
178
+ else {
179
+ // File changed but no structured diff detected — content edit
180
+ events.push({
181
+ kind: 'content',
182
+ hash: commit.hash,
183
+ shortHash,
184
+ date: commit.date,
185
+ author: commit.author,
186
+ message: commit.message,
187
+ });
188
+ }
189
+ }
190
+ prevSnapshot = snapshot;
191
+ }
192
+ return events;
193
+ }
194
+ /**
195
+ * Get all commits affecting a directory, with their affected file lists.
196
+ * Returns newest-first (git default).
197
+ */
198
+ export function getBatchCommits(planDir, cwd, since) {
199
+ try {
200
+ // Use %x00 as record separator to avoid ambiguity with blank lines in output
201
+ let cmd = `git log --format="%x00%H %aI %aN%n%s" --name-only -- "${planDir}"`;
202
+ if (since) {
203
+ cmd = `git log --since="${since}" --format="%x00%H %aI %aN%n%s" --name-only -- "${planDir}"`;
204
+ }
205
+ const output = execSync(cmd, {
206
+ cwd,
207
+ encoding: 'utf-8',
208
+ maxBuffer: 10 * 1024 * 1024,
209
+ stdio: ['pipe', 'pipe', 'pipe'],
210
+ });
211
+ const commits = [];
212
+ // Split on the NUL byte record separator we injected
213
+ const blocks = output.split('\x00').filter(b => b.trim() !== '');
214
+ for (const block of blocks) {
215
+ const lines = block.split('\n').filter(l => l.trim() !== '');
216
+ if (lines.length < 2)
217
+ continue;
218
+ const metaLine = lines[0].trim();
219
+ const messageLine = lines[1].trim();
220
+ const spaceIdx1 = metaLine.indexOf(' ');
221
+ const spaceIdx2 = metaLine.indexOf(' ', spaceIdx1 + 1);
222
+ if (spaceIdx1 === -1 || spaceIdx2 === -1)
223
+ continue;
224
+ const hash = metaLine.slice(0, spaceIdx1);
225
+ const date = metaLine.slice(spaceIdx1 + 1, spaceIdx2);
226
+ const author = metaLine.slice(spaceIdx2 + 1);
227
+ const files = lines.slice(2).map(l => l.trim()).filter(l => l.length > 0);
228
+ commits.push({ hash, date, author, message: messageLine, files });
229
+ }
230
+ return commits;
231
+ }
232
+ catch {
233
+ return [];
234
+ }
235
+ }
236
+ /**
237
+ * Extract history for all plan entities in a directory.
238
+ * Groups commits by file path and runs per-entity extraction for files
239
+ * with more than one commit. Single-commit files get a created event.
240
+ *
241
+ * @returns Map of file path → HistoryEvent[]
242
+ */
243
+ export function extractBatchHistory(planDir, cwd, options = {}) {
244
+ const batchCommits = getBatchCommits(planDir, cwd, options.since);
245
+ // Group by file: track which commits touch each file + latest hash
246
+ const fileCommitCounts = new Map();
247
+ const fileLatestHash = new Map();
248
+ for (const commit of batchCommits) {
249
+ for (const file of commit.files) {
250
+ fileCommitCounts.set(file, (fileCommitCounts.get(file) ?? 0) + 1);
251
+ // First occurrence (newest commit) sets the latest hash
252
+ if (!fileLatestHash.has(file)) {
253
+ fileLatestHash.set(file, commit.hash);
254
+ }
255
+ }
256
+ }
257
+ const cache = options.cache;
258
+ const result = new Map();
259
+ for (const [file, count] of fileCommitCounts) {
260
+ // Check cache
261
+ const latestHash = fileLatestHash.get(file);
262
+ if (cache) {
263
+ const cached = cache.entries[file];
264
+ if (cached && cached.latestCommit === latestHash) {
265
+ result.set(file, cached.events);
266
+ continue;
267
+ }
268
+ }
269
+ let events;
270
+ if (count === 1) {
271
+ // Single commit — emit a created event directly from batch data
272
+ const commit = batchCommits.find(c => c.files.includes(file));
273
+ const content = getFileAtCommit(commit.hash, file, cwd);
274
+ const attrs = content ? parseTagAttributes(content.split('\n')[0] ?? '') : {};
275
+ events = [{
276
+ kind: 'created',
277
+ hash: commit.hash,
278
+ shortHash: commit.hash.slice(0, 7),
279
+ date: commit.date,
280
+ author: commit.author,
281
+ message: commit.message,
282
+ initialAttributes: attrs,
283
+ }];
284
+ }
285
+ else {
286
+ events = extractEntityHistory(file, cwd);
287
+ }
288
+ result.set(file, events);
289
+ // Update cache
290
+ if (cache) {
291
+ cache.entries[file] = { latestCommit: latestHash, events };
292
+ }
293
+ }
294
+ return result;
295
+ }
296
+ const HISTORY_CACHE_FILENAME = '.plan-history-cache.json';
297
+ /**
298
+ * Read the history cache from disk.
299
+ */
300
+ export function readHistoryCache(planDir) {
301
+ const cachePath = join(planDir, HISTORY_CACHE_FILENAME);
302
+ if (!existsSync(cachePath))
303
+ return { entries: {} };
304
+ try {
305
+ return JSON.parse(readFileSync(cachePath, 'utf8'));
306
+ }
307
+ catch {
308
+ return { entries: {} };
309
+ }
310
+ }
311
+ /**
312
+ * Write the history cache to disk.
313
+ * Silently skips if the directory doesn't exist or writing fails.
314
+ */
315
+ export function writeHistoryCache(planDir, cache) {
316
+ try {
317
+ writeFileSync(join(planDir, HISTORY_CACHE_FILENAME), JSON.stringify(cache, null, '\t') + '\n');
318
+ }
319
+ catch {
320
+ // Non-critical — cache will be rebuilt next time
321
+ }
322
+ }
323
+ /**
324
+ * Build a unified global timeline from batch history results.
325
+ * Returns events sorted by date descending (newest first), with commit hash grouping info.
326
+ */
327
+ export function buildGlobalTimeline(batchHistory) {
328
+ const allEvents = [];
329
+ for (const events of batchHistory.values()) {
330
+ allEvents.push(...events);
331
+ }
332
+ // Sort newest first
333
+ allEvents.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
334
+ return allEvents;
335
+ }
336
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,5 +2,6 @@ import type { RunePackage } from '@refrakt-md/types';
2
2
  export declare const plan: RunePackage;
3
3
  export default plan;
4
4
  export { planPipelineHooks } from './pipeline.js';
5
- export type { PlanEntity, PlanRuneType, Criterion, ScanCache, ScanCacheEntry, ScanOptions } from './types.js';
5
+ export { parseFileContent, scanPlanSources } from './scanner.js';
6
+ export type { PlanEntity, PlanRuneType, Criterion, FileSource, ScanCache, ScanCacheEntry, ScanOptions } from './types.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAcrD,eAAO,MAAM,IAAI,EAAE,WA+HlB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAgBrD,eAAO,MAAM,IAAI,EAAE,WAsIlB,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { tabsBehavior } from '@refrakt-md/behaviors';
2
+ import { entityTabsBehavior } from './entity-tabs-behavior.js';
2
3
  import { spec } from './tags/spec.js';
3
4
  import { work } from './tags/work.js';
4
5
  import { bug } from './tags/bug.js';
@@ -8,12 +9,13 @@ import { backlog } from './tags/backlog.js';
8
9
  import { decisionLog } from './tags/decision-log.js';
9
10
  import { planProgress } from './tags/plan-progress.js';
10
11
  import { planActivity } from './tags/plan-activity.js';
12
+ import { planHistory } from './tags/plan-history.js';
11
13
  import { config } from './config.js';
12
14
  import { planPipelineHooks } from './pipeline.js';
13
15
  export const plan = {
14
16
  name: 'plan',
15
17
  displayName: 'Plan',
16
- version: '0.9.5',
18
+ version: '0.9.7',
17
19
  runes: {
18
20
  'spec': {
19
21
  transform: spec,
@@ -129,15 +131,23 @@ Custom properties cascade naturally without JavaScript.
129
131
  reinterprets: {},
130
132
  fixture: `{% plan-activity limit="10" /%}`,
131
133
  },
134
+ 'plan-history': {
135
+ transform: planHistory,
136
+ description: 'Git-native entity history timeline showing attribute transitions, criteria progress, and lifecycle events',
137
+ reinterprets: {},
138
+ fixture: `{% plan-history limit="20" /%}`,
139
+ },
132
140
  },
133
141
  theme: {
134
142
  runes: config,
135
143
  },
136
144
  behaviors: {
137
145
  'milestone-backlog': tabsBehavior,
146
+ 'plan-entity-tabs': entityTabsBehavior,
138
147
  },
139
148
  pipeline: planPipelineHooks,
140
149
  };
141
150
  export default plan;
142
151
  export { planPipelineHooks } from './pipeline.js';
152
+ export { parseFileContent, scanPlanSources } from './scanner.js';
143
153
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,11 @@
1
1
  import type { PackagePipelineHooks, EntityRegistration } from '@refrakt-md/types';
2
- /** A directed reference from one entity to another */
3
- export interface EntityRelationship {
4
- /** The entity that contains the reference */
5
- fromId: string;
6
- fromType: string;
7
- /** The entity being referenced */
8
- toId: string;
9
- toType: string;
10
- /** Relationship kind */
11
- kind: 'blocks' | 'blocked-by' | 'related';
12
- }
2
+ import { type HistoryEvent } from './history.js';
3
+ import { type EntityRelationship } from './relationships.js';
4
+ export type { EntityRelationship } from './relationships.js';
5
+ /** Set scanner dependency data for the pipeline's aggregate() hook to consume */
6
+ export declare function setScannerDependencies(deps: Map<string, string[]>): void;
7
+ /** Set the plan directory path for the pipeline's aggregate() hook to consume */
8
+ export declare function setPlanDir(dir: string): void;
13
9
  export interface PlanAggregatedData {
14
10
  workEntities: EntityRegistration[];
15
11
  bugEntities: EntityRegistration[];
@@ -18,6 +14,10 @@ export interface PlanAggregatedData {
18
14
  milestoneEntities: EntityRegistration[];
19
15
  /** Bidirectional relationship index: entityId → relationships */
20
16
  relationships: Map<string, EntityRelationship[]>;
17
+ /** Git-derived history events per entity file path */
18
+ history: Map<string, HistoryEvent[]>;
19
+ /** Repository URL for commit links (parsed from git remote or config) */
20
+ repositoryUrl?: string;
21
21
  }
22
22
  export declare const planPipelineHooks: PackagePipelineHooks;
23
23
  //# sourceMappingURL=pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAiQlF,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IAClC,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,IAAI,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IAClC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;IACvC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;IACxC,iEAAiE;IACjE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;CACjD;AASD,eAAO,MAAM,iBAAiB,EAAE,oBA0L/B,CAAC"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQlF,OAAO,EAIN,KAAK,YAAY,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAwHjF,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAS7D,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAGxE;AAQD,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,MAAM,WAAW,kBAAkB;IAClC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;IACvC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;IACxC,iEAAiE;IACjE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACjD,sDAAsD;IACtD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IACrC,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAgCD,eAAO,MAAM,iBAAiB,EAAE,oBAyN/B,CAAC"}