@mono-labs/tracker 0.1.269

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 (126) hide show
  1. package/README.md +1196 -0
  2. package/bin/tracker.js +2 -0
  3. package/dist/dashboard/cli.d.ts +2 -0
  4. package/dist/dashboard/cli.d.ts.map +1 -0
  5. package/dist/dashboard/cli.js +38 -0
  6. package/dist/dashboard/index.d.ts +3 -0
  7. package/dist/dashboard/index.d.ts.map +1 -0
  8. package/dist/dashboard/index.js +5 -0
  9. package/dist/dashboard/server.d.ts +3 -0
  10. package/dist/dashboard/server.d.ts.map +1 -0
  11. package/dist/dashboard/server.js +130 -0
  12. package/dist/dashboard/types.d.ts +13 -0
  13. package/dist/dashboard/types.d.ts.map +1 -0
  14. package/dist/dashboard/types.js +2 -0
  15. package/dist/dashboard/watcher.d.ts +7 -0
  16. package/dist/dashboard/watcher.d.ts.map +1 -0
  17. package/dist/dashboard/watcher.js +44 -0
  18. package/dist/executor/action-executor.d.ts +10 -0
  19. package/dist/executor/action-executor.d.ts.map +1 -0
  20. package/dist/executor/action-executor.js +19 -0
  21. package/dist/executor/actions/index.d.ts +4 -0
  22. package/dist/executor/actions/index.d.ts.map +1 -0
  23. package/dist/executor/actions/index.js +9 -0
  24. package/dist/executor/actions/remove-action.d.ts +4 -0
  25. package/dist/executor/actions/remove-action.d.ts.map +1 -0
  26. package/dist/executor/actions/remove-action.js +10 -0
  27. package/dist/executor/actions/rename-action.d.ts +4 -0
  28. package/dist/executor/actions/rename-action.d.ts.map +1 -0
  29. package/dist/executor/actions/rename-action.js +10 -0
  30. package/dist/executor/actions/replace-action.d.ts +4 -0
  31. package/dist/executor/actions/replace-action.d.ts.map +1 -0
  32. package/dist/executor/actions/replace-action.js +10 -0
  33. package/dist/executor/index.d.ts +4 -0
  34. package/dist/executor/index.d.ts.map +1 -0
  35. package/dist/executor/index.js +10 -0
  36. package/dist/index.d.ts +20 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +58 -0
  39. package/dist/manager/index.d.ts +7 -0
  40. package/dist/manager/index.d.ts.map +1 -0
  41. package/dist/manager/index.js +19 -0
  42. package/dist/manager/notation-manager.d.ts +18 -0
  43. package/dist/manager/notation-manager.d.ts.map +1 -0
  44. package/dist/manager/notation-manager.js +137 -0
  45. package/dist/manager/notation-manager.test.d.ts +2 -0
  46. package/dist/manager/notation-manager.test.d.ts.map +1 -0
  47. package/dist/manager/notation-manager.test.js +211 -0
  48. package/dist/manager/notation-updater.d.ts +6 -0
  49. package/dist/manager/notation-updater.d.ts.map +1 -0
  50. package/dist/manager/notation-updater.js +20 -0
  51. package/dist/manager/relationship-manager.d.ts +5 -0
  52. package/dist/manager/relationship-manager.d.ts.map +1 -0
  53. package/dist/manager/relationship-manager.js +46 -0
  54. package/dist/manager/stats.d.ts +3 -0
  55. package/dist/manager/stats.d.ts.map +1 -0
  56. package/dist/manager/stats.js +41 -0
  57. package/dist/manager/validator.d.ts +9 -0
  58. package/dist/manager/validator.d.ts.map +1 -0
  59. package/dist/manager/validator.js +62 -0
  60. package/dist/scanner/action-parser.d.ts +3 -0
  61. package/dist/scanner/action-parser.d.ts.map +1 -0
  62. package/dist/scanner/action-parser.js +97 -0
  63. package/dist/scanner/action-parser.test.d.ts +2 -0
  64. package/dist/scanner/action-parser.test.d.ts.map +1 -0
  65. package/dist/scanner/action-parser.test.js +94 -0
  66. package/dist/scanner/attribute-parser.d.ts +15 -0
  67. package/dist/scanner/attribute-parser.d.ts.map +1 -0
  68. package/dist/scanner/attribute-parser.js +183 -0
  69. package/dist/scanner/attribute-parser.test.d.ts +2 -0
  70. package/dist/scanner/attribute-parser.test.d.ts.map +1 -0
  71. package/dist/scanner/attribute-parser.test.js +93 -0
  72. package/dist/scanner/file-scanner.d.ts +3 -0
  73. package/dist/scanner/file-scanner.d.ts.map +1 -0
  74. package/dist/scanner/file-scanner.js +58 -0
  75. package/dist/scanner/index.d.ts +6 -0
  76. package/dist/scanner/index.d.ts.map +1 -0
  77. package/dist/scanner/index.js +11 -0
  78. package/dist/scanner/notation-parser.d.ts +3 -0
  79. package/dist/scanner/notation-parser.d.ts.map +1 -0
  80. package/dist/scanner/notation-parser.js +88 -0
  81. package/dist/scanner/notation-parser.test.d.ts +2 -0
  82. package/dist/scanner/notation-parser.test.d.ts.map +1 -0
  83. package/dist/scanner/notation-parser.test.js +153 -0
  84. package/dist/storage/config-loader.d.ts +3 -0
  85. package/dist/storage/config-loader.d.ts.map +1 -0
  86. package/dist/storage/config-loader.js +55 -0
  87. package/dist/storage/index.d.ts +3 -0
  88. package/dist/storage/index.d.ts.map +1 -0
  89. package/dist/storage/index.js +7 -0
  90. package/dist/storage/jsonl-storage.d.ts +11 -0
  91. package/dist/storage/jsonl-storage.d.ts.map +1 -0
  92. package/dist/storage/jsonl-storage.js +88 -0
  93. package/dist/storage/jsonl-storage.test.d.ts +2 -0
  94. package/dist/storage/jsonl-storage.test.d.ts.map +1 -0
  95. package/dist/storage/jsonl-storage.test.js +126 -0
  96. package/dist/types/action.d.ts +57 -0
  97. package/dist/types/action.d.ts.map +1 -0
  98. package/dist/types/action.js +13 -0
  99. package/dist/types/config.d.ts +11 -0
  100. package/dist/types/config.d.ts.map +1 -0
  101. package/dist/types/config.js +11 -0
  102. package/dist/types/enums.d.ts +40 -0
  103. package/dist/types/enums.d.ts.map +1 -0
  104. package/dist/types/enums.js +37 -0
  105. package/dist/types/index.d.ts +7 -0
  106. package/dist/types/index.d.ts.map +1 -0
  107. package/dist/types/index.js +13 -0
  108. package/dist/types/notation.d.ts +64 -0
  109. package/dist/types/notation.d.ts.map +1 -0
  110. package/dist/types/notation.js +2 -0
  111. package/dist/utils/date-parser.d.ts +3 -0
  112. package/dist/utils/date-parser.d.ts.map +1 -0
  113. package/dist/utils/date-parser.js +51 -0
  114. package/dist/utils/date-parser.test.d.ts +2 -0
  115. package/dist/utils/date-parser.test.d.ts.map +1 -0
  116. package/dist/utils/date-parser.test.js +34 -0
  117. package/dist/utils/id-generator.d.ts +3 -0
  118. package/dist/utils/id-generator.d.ts.map +1 -0
  119. package/dist/utils/id-generator.js +12 -0
  120. package/dist/utils/id-generator.test.d.ts +2 -0
  121. package/dist/utils/id-generator.test.d.ts.map +1 -0
  122. package/dist/utils/id-generator.test.js +30 -0
  123. package/dist/utils/index.d.ts +3 -0
  124. package/dist/utils/index.d.ts.map +1 -0
  125. package/dist/utils/index.js +9 -0
  126. package/package.json +60 -0
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFileContent = parseFileContent;
4
+ const enums_1 = require("../types/enums");
5
+ const utils_1 = require("../utils");
6
+ const attribute_parser_1 = require("./attribute-parser");
7
+ const action_parser_1 = require("./action-parser");
8
+ const MARKER_REGEX = /^(\s*)\/\/\s*(FIXME|TODO|BUG|HACK|NOTE|OPTIMIZE|SECURITY):?\s*(?:\[([^\]]*)\])?\s*(.*)/;
9
+ function parseFileContent(filePath, content, idPrefix = 'N') {
10
+ const lines = content.split('\n');
11
+ const notations = [];
12
+ let i = 0;
13
+ while (i < lines.length) {
14
+ const match = lines[i].match(MARKER_REGEX);
15
+ if (!match) {
16
+ i++;
17
+ continue;
18
+ }
19
+ const indent = match[1];
20
+ const markerType = match[2];
21
+ const inlineId = match[3] || undefined;
22
+ const description = match[4].trim();
23
+ const startLine = i + 1; // 1-indexed
24
+ const column = indent.length + 1;
25
+ // Collect continuation lines (// lines that aren't new markers)
26
+ const bodyLines = [];
27
+ const rawLines = [lines[i]];
28
+ i++;
29
+ while (i < lines.length) {
30
+ const nextLine = lines[i];
31
+ // Stop if it's a new marker
32
+ if (MARKER_REGEX.test(nextLine))
33
+ break;
34
+ // Stop if not a comment line
35
+ const commentMatch = nextLine.match(/^\s*\/\/\s?(.*)/);
36
+ if (!commentMatch)
37
+ break;
38
+ bodyLines.push(commentMatch[1]);
39
+ rawLines.push(nextLine);
40
+ i++;
41
+ }
42
+ // Collect code context lines (non-empty, non-comment lines until blank)
43
+ const codeContext = [];
44
+ while (i < lines.length) {
45
+ const codeLine = lines[i];
46
+ if (codeLine.trim() === '')
47
+ break;
48
+ if (/^\s*\/\//.test(codeLine))
49
+ break;
50
+ codeContext.push(codeLine);
51
+ rawLines.push(codeLine);
52
+ i++;
53
+ }
54
+ const endLine = startLine + rawLines.length - 1;
55
+ const id = inlineId || (0, utils_1.generateStableId)(idPrefix, filePath, startLine);
56
+ const attrs = (0, attribute_parser_1.parseAttributes)(bodyLines);
57
+ const actions = (0, action_parser_1.parseActions)(bodyLines);
58
+ const notation = {
59
+ id,
60
+ type: markerType,
61
+ description,
62
+ body: bodyLines,
63
+ codeContext,
64
+ location: {
65
+ file: filePath,
66
+ line: startLine,
67
+ column,
68
+ endLine,
69
+ },
70
+ author: attrs.author,
71
+ assignee: attrs.assignee,
72
+ priority: attrs.priority,
73
+ risk: attrs.risk,
74
+ status: enums_1.Status.OPEN,
75
+ tags: attrs.tags,
76
+ dueDate: attrs.dueDate,
77
+ createdDate: attrs.createdDate,
78
+ performance: attrs.performance,
79
+ debt: attrs.debt,
80
+ actions,
81
+ relationships: attrs.relationships,
82
+ rawBlock: rawLines.join('\n'),
83
+ scannedAt: new Date().toISOString(),
84
+ };
85
+ notations.push(notation);
86
+ }
87
+ return notations;
88
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=notation-parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notation-parser.test.d.ts","sourceRoot":"","sources":["../../src/scanner/notation-parser.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const notation_parser_1 = require("./notation-parser");
5
+ (0, vitest_1.describe)('parseFileContent', () => {
6
+ (0, vitest_1.it)('parses a simple TODO', () => {
7
+ const content = '// TODO: Fix this bug';
8
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
9
+ (0, vitest_1.expect)(result).toHaveLength(1);
10
+ (0, vitest_1.expect)(result[0].type).toBe('TODO');
11
+ (0, vitest_1.expect)(result[0].description).toBe('Fix this bug');
12
+ });
13
+ (0, vitest_1.it)('parses a FIXME marker', () => {
14
+ const content = '// FIXME: Memory leak in handler';
15
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
16
+ (0, vitest_1.expect)(result).toHaveLength(1);
17
+ (0, vitest_1.expect)(result[0].type).toBe('FIXME');
18
+ });
19
+ (0, vitest_1.it)('parses a BUG marker', () => {
20
+ const content = '// BUG: Null pointer exception';
21
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
22
+ (0, vitest_1.expect)(result[0].type).toBe('BUG');
23
+ });
24
+ (0, vitest_1.it)('parses a HACK marker', () => {
25
+ const content = '// HACK: Temporary workaround';
26
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
27
+ (0, vitest_1.expect)(result[0].type).toBe('HACK');
28
+ });
29
+ (0, vitest_1.it)('parses a NOTE marker', () => {
30
+ const content = '// NOTE: This is intentional';
31
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
32
+ (0, vitest_1.expect)(result[0].type).toBe('NOTE');
33
+ });
34
+ (0, vitest_1.it)('parses an OPTIMIZE marker', () => {
35
+ const content = '// OPTIMIZE: Use batch query';
36
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
37
+ (0, vitest_1.expect)(result[0].type).toBe('OPTIMIZE');
38
+ });
39
+ (0, vitest_1.it)('parses a SECURITY marker', () => {
40
+ const content = '// SECURITY: Validate input';
41
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
42
+ (0, vitest_1.expect)(result[0].type).toBe('SECURITY');
43
+ });
44
+ (0, vitest_1.it)('extracts inline id from brackets', () => {
45
+ const content = '// TODO [TASK-123] Implement feature';
46
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
47
+ (0, vitest_1.expect)(result[0].id).toBe('TASK-123');
48
+ });
49
+ (0, vitest_1.it)('collects continuation comment lines', () => {
50
+ const content = [
51
+ '// TODO: Main description',
52
+ '// @author: Cody Jones',
53
+ '// @priority: high',
54
+ ].join('\n');
55
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
56
+ (0, vitest_1.expect)(result).toHaveLength(1);
57
+ (0, vitest_1.expect)(result[0].body).toHaveLength(2);
58
+ (0, vitest_1.expect)(result[0].author).toBe('Cody Jones');
59
+ (0, vitest_1.expect)(result[0].priority).toBe('high');
60
+ });
61
+ (0, vitest_1.it)('collects code context lines', () => {
62
+ const content = [
63
+ '// TODO: Fix this function',
64
+ 'function broken() {',
65
+ ' return null',
66
+ '}',
67
+ ].join('\n');
68
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
69
+ (0, vitest_1.expect)(result[0].codeContext).toHaveLength(3);
70
+ (0, vitest_1.expect)(result[0].codeContext[0]).toBe('function broken() {');
71
+ });
72
+ (0, vitest_1.it)('stops code context at blank line', () => {
73
+ const content = [
74
+ '// TODO: Fix this',
75
+ 'const x = 1',
76
+ '',
77
+ 'const y = 2',
78
+ ].join('\n');
79
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
80
+ (0, vitest_1.expect)(result[0].codeContext).toHaveLength(1);
81
+ });
82
+ (0, vitest_1.it)('parses adjacent markers separately', () => {
83
+ const content = [
84
+ '// TODO: First task',
85
+ '// FIXME: Second task',
86
+ ].join('\n');
87
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
88
+ (0, vitest_1.expect)(result).toHaveLength(2);
89
+ (0, vitest_1.expect)(result[0].type).toBe('TODO');
90
+ (0, vitest_1.expect)(result[1].type).toBe('FIXME');
91
+ });
92
+ (0, vitest_1.it)('sets correct line numbers (1-indexed)', () => {
93
+ const content = [
94
+ 'const x = 1',
95
+ '// TODO: Found on line 2',
96
+ 'const y = 2',
97
+ ].join('\n');
98
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
99
+ (0, vitest_1.expect)(result[0].location.line).toBe(2);
100
+ });
101
+ (0, vitest_1.it)('sets correct file path', () => {
102
+ const content = '// TODO: Test';
103
+ const result = (0, notation_parser_1.parseFileContent)('src/app.ts', content);
104
+ (0, vitest_1.expect)(result[0].location.file).toBe('src/app.ts');
105
+ });
106
+ (0, vitest_1.it)('parses indented markers', () => {
107
+ const content = ' // TODO: Indented task';
108
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
109
+ (0, vitest_1.expect)(result).toHaveLength(1);
110
+ (0, vitest_1.expect)(result[0].location.column).toBe(5);
111
+ });
112
+ (0, vitest_1.it)('parses marker without colon', () => {
113
+ const content = '// TODO Fix without colon';
114
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
115
+ (0, vitest_1.expect)(result).toHaveLength(1);
116
+ (0, vitest_1.expect)(result[0].description).toBe('Fix without colon');
117
+ });
118
+ (0, vitest_1.it)('handles multi-line with actions', () => {
119
+ const content = [
120
+ '// TODO: Refactor handler',
121
+ '// Action: replace(oldFn, newFn)',
122
+ ].join('\n');
123
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
124
+ (0, vitest_1.expect)(result[0].actions).toHaveLength(1);
125
+ (0, vitest_1.expect)(result[0].actions[0].args.verb).toBe('replace');
126
+ });
127
+ (0, vitest_1.it)('generates stable ids when no inline id', () => {
128
+ const content = '// TODO: No id here';
129
+ const r1 = (0, notation_parser_1.parseFileContent)('test.ts', content, 'N');
130
+ const r2 = (0, notation_parser_1.parseFileContent)('test.ts', content, 'N');
131
+ (0, vitest_1.expect)(r1[0].id).toBe(r2[0].id);
132
+ });
133
+ (0, vitest_1.it)('handles empty content', () => {
134
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', '');
135
+ (0, vitest_1.expect)(result).toHaveLength(0);
136
+ });
137
+ (0, vitest_1.it)('handles content with no markers', () => {
138
+ const content = 'const x = 1\nconst y = 2';
139
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
140
+ (0, vitest_1.expect)(result).toHaveLength(0);
141
+ });
142
+ (0, vitest_1.it)('preserves raw block', () => {
143
+ const content = [
144
+ '// TODO: Raw block test',
145
+ '// with continuation',
146
+ 'const x = 1',
147
+ ].join('\n');
148
+ const result = (0, notation_parser_1.parseFileContent)('test.ts', content);
149
+ (0, vitest_1.expect)(result[0].rawBlock).toContain('TODO: Raw block test');
150
+ (0, vitest_1.expect)(result[0].rawBlock).toContain('with continuation');
151
+ (0, vitest_1.expect)(result[0].rawBlock).toContain('const x = 1');
152
+ });
153
+ });
@@ -0,0 +1,3 @@
1
+ import type { TrackerConfig } from '../types';
2
+ export declare function loadConfig(projectRoot: string): TrackerConfig;
3
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/storage/config-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAG7C,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAgB7D"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const types_1 = require("../types");
40
+ function loadConfig(projectRoot) {
41
+ const configPath = path.join(projectRoot, 'tracker.config.json');
42
+ let userConfig = {};
43
+ try {
44
+ const raw = fs.readFileSync(configPath, 'utf-8');
45
+ userConfig = JSON.parse(raw);
46
+ }
47
+ catch {
48
+ // No config file or invalid JSON — use defaults
49
+ }
50
+ return {
51
+ ...types_1.DEFAULT_CONFIG,
52
+ ...userConfig,
53
+ rootDir: projectRoot,
54
+ };
55
+ }
@@ -0,0 +1,3 @@
1
+ export { JsonlStorage } from './jsonl-storage';
2
+ export { loadConfig } from './config-loader';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfig = exports.JsonlStorage = void 0;
4
+ var jsonl_storage_1 = require("./jsonl-storage");
5
+ Object.defineProperty(exports, "JsonlStorage", { enumerable: true, get: function () { return jsonl_storage_1.JsonlStorage; } });
6
+ var config_loader_1 = require("./config-loader");
7
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_loader_1.loadConfig; } });
@@ -0,0 +1,11 @@
1
+ import type { Notation } from '../types';
2
+ export declare class JsonlStorage {
3
+ private filePath;
4
+ constructor(filePath: string);
5
+ ensureDirectory(): Promise<void>;
6
+ readAll(): Promise<Notation[]>;
7
+ writeAll(notations: Notation[]): Promise<void>;
8
+ append(notation: Notation): Promise<void>;
9
+ appendBatch(notations: Notation[]): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=jsonl-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-storage.d.ts","sourceRoot":"","sources":["../../src/storage/jsonl-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,QAAQ,EAAE,MAAM;IAItB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAmB9B,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAMvD"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.JsonlStorage = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class JsonlStorage {
40
+ filePath;
41
+ constructor(filePath) {
42
+ this.filePath = filePath;
43
+ }
44
+ async ensureDirectory() {
45
+ const dir = path.dirname(this.filePath);
46
+ await fs.promises.mkdir(dir, { recursive: true });
47
+ }
48
+ async readAll() {
49
+ try {
50
+ const content = await fs.promises.readFile(this.filePath, 'utf-8');
51
+ const lines = content.trim().split('\n').filter(Boolean);
52
+ const notations = [];
53
+ for (const line of lines) {
54
+ try {
55
+ notations.push(JSON.parse(line));
56
+ }
57
+ catch {
58
+ // Skip corrupt lines
59
+ }
60
+ }
61
+ return notations;
62
+ }
63
+ catch (err) {
64
+ if (err.code === 'ENOENT')
65
+ return [];
66
+ throw err;
67
+ }
68
+ }
69
+ async writeAll(notations) {
70
+ await this.ensureDirectory();
71
+ const tmpPath = this.filePath + '.tmp';
72
+ const content = notations.map((n) => JSON.stringify(n)).join('\n') + '\n';
73
+ await fs.promises.writeFile(tmpPath, content, 'utf-8');
74
+ await fs.promises.rename(tmpPath, this.filePath);
75
+ }
76
+ async append(notation) {
77
+ await this.ensureDirectory();
78
+ await fs.promises.appendFile(this.filePath, JSON.stringify(notation) + '\n', 'utf-8');
79
+ }
80
+ async appendBatch(notations) {
81
+ if (notations.length === 0)
82
+ return;
83
+ await this.ensureDirectory();
84
+ const content = notations.map((n) => JSON.stringify(n)).join('\n') + '\n';
85
+ await fs.promises.appendFile(this.filePath, content, 'utf-8');
86
+ }
87
+ }
88
+ exports.JsonlStorage = JsonlStorage;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsonl-storage.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-storage.test.d.ts","sourceRoot":"","sources":["../../src/storage/jsonl-storage.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const jsonl_storage_1 = require("./jsonl-storage");
41
+ function makeNotation(overrides = {}) {
42
+ return {
43
+ id: 'N-test001',
44
+ type: 'TODO',
45
+ description: 'Test notation',
46
+ body: [],
47
+ codeContext: [],
48
+ location: { file: 'test.ts', line: 1, column: 1 },
49
+ status: 'open',
50
+ tags: [],
51
+ actions: [],
52
+ relationships: [],
53
+ rawBlock: '// TODO: Test notation',
54
+ scannedAt: '2026-01-01T00:00:00.000Z',
55
+ ...overrides,
56
+ };
57
+ }
58
+ (0, vitest_1.describe)('JsonlStorage', () => {
59
+ let tmpDir;
60
+ let storage;
61
+ (0, vitest_1.beforeEach)(() => {
62
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tracker-test-'));
63
+ storage = new jsonl_storage_1.JsonlStorage(path.join(tmpDir, 'data', 'notations.jsonl'));
64
+ });
65
+ (0, vitest_1.afterEach)(() => {
66
+ fs.rmSync(tmpDir, { recursive: true, force: true });
67
+ });
68
+ (0, vitest_1.it)('returns empty array when file does not exist', async () => {
69
+ const result = await storage.readAll();
70
+ (0, vitest_1.expect)(result).toEqual([]);
71
+ });
72
+ (0, vitest_1.it)('round-trips notations through writeAll/readAll', async () => {
73
+ const notations = [makeNotation({ id: 'N-1' }), makeNotation({ id: 'N-2' })];
74
+ await storage.writeAll(notations);
75
+ const result = await storage.readAll();
76
+ (0, vitest_1.expect)(result).toHaveLength(2);
77
+ (0, vitest_1.expect)(result[0].id).toBe('N-1');
78
+ (0, vitest_1.expect)(result[1].id).toBe('N-2');
79
+ });
80
+ (0, vitest_1.it)('appends a single notation', async () => {
81
+ await storage.append(makeNotation({ id: 'N-1' }));
82
+ await storage.append(makeNotation({ id: 'N-2' }));
83
+ const result = await storage.readAll();
84
+ (0, vitest_1.expect)(result).toHaveLength(2);
85
+ });
86
+ (0, vitest_1.it)('appends a batch of notations', async () => {
87
+ await storage.appendBatch([
88
+ makeNotation({ id: 'N-1' }),
89
+ makeNotation({ id: 'N-2' }),
90
+ makeNotation({ id: 'N-3' }),
91
+ ]);
92
+ const result = await storage.readAll();
93
+ (0, vitest_1.expect)(result).toHaveLength(3);
94
+ });
95
+ (0, vitest_1.it)('skips corrupt lines gracefully', async () => {
96
+ const filePath = path.join(tmpDir, 'data', 'notations.jsonl');
97
+ await storage.ensureDirectory();
98
+ fs.writeFileSync(filePath, [
99
+ JSON.stringify(makeNotation({ id: 'N-1' })),
100
+ 'this is not valid json{{{',
101
+ JSON.stringify(makeNotation({ id: 'N-2' })),
102
+ ].join('\n') + '\n');
103
+ const result = await storage.readAll();
104
+ (0, vitest_1.expect)(result).toHaveLength(2);
105
+ (0, vitest_1.expect)(result[0].id).toBe('N-1');
106
+ (0, vitest_1.expect)(result[1].id).toBe('N-2');
107
+ });
108
+ (0, vitest_1.it)('creates directory on write', async () => {
109
+ const nested = new jsonl_storage_1.JsonlStorage(path.join(tmpDir, 'a', 'b', 'c', 'data.jsonl'));
110
+ await nested.writeAll([makeNotation()]);
111
+ const result = await nested.readAll();
112
+ (0, vitest_1.expect)(result).toHaveLength(1);
113
+ });
114
+ (0, vitest_1.it)('overwrites existing data on writeAll', async () => {
115
+ await storage.writeAll([makeNotation({ id: 'N-1' }), makeNotation({ id: 'N-2' })]);
116
+ await storage.writeAll([makeNotation({ id: 'N-3' })]);
117
+ const result = await storage.readAll();
118
+ (0, vitest_1.expect)(result).toHaveLength(1);
119
+ (0, vitest_1.expect)(result[0].id).toBe('N-3');
120
+ });
121
+ (0, vitest_1.it)('handles empty batch append', async () => {
122
+ await storage.appendBatch([]);
123
+ const result = await storage.readAll();
124
+ (0, vitest_1.expect)(result).toEqual([]);
125
+ });
126
+ });
@@ -0,0 +1,57 @@
1
+ export declare const ActionVerb: {
2
+ readonly REPLACE: "replace";
3
+ readonly REMOVE: "remove";
4
+ readonly RENAME: "rename";
5
+ readonly INSERT: "insert";
6
+ readonly EXTRACT: "extract";
7
+ readonly MOVE: "move";
8
+ readonly WRAP_IN: "wrapIn";
9
+ readonly GENERIC: "generic";
10
+ };
11
+ export type ActionVerb = (typeof ActionVerb)[keyof typeof ActionVerb];
12
+ export interface ReplaceArgs {
13
+ verb: typeof ActionVerb.REPLACE;
14
+ target: string;
15
+ replacement: string;
16
+ }
17
+ export interface RemoveArgs {
18
+ verb: typeof ActionVerb.REMOVE;
19
+ target: string;
20
+ }
21
+ export interface RenameArgs {
22
+ verb: typeof ActionVerb.RENAME;
23
+ from: string;
24
+ to: string;
25
+ }
26
+ export interface InsertArgs {
27
+ verb: typeof ActionVerb.INSERT;
28
+ content: string;
29
+ position: 'before' | 'after';
30
+ anchor: string;
31
+ }
32
+ export interface ExtractArgs {
33
+ verb: typeof ActionVerb.EXTRACT;
34
+ target: string;
35
+ destination: string;
36
+ }
37
+ export interface MoveArgs {
38
+ verb: typeof ActionVerb.MOVE;
39
+ target: string;
40
+ destination: string;
41
+ }
42
+ export interface WrapInArgs {
43
+ verb: typeof ActionVerb.WRAP_IN;
44
+ target: string;
45
+ wrapper: string;
46
+ }
47
+ export interface GenericArgs {
48
+ verb: typeof ActionVerb.GENERIC;
49
+ description: string;
50
+ }
51
+ export type ActionArgs = ReplaceArgs | RemoveArgs | RenameArgs | InsertArgs | ExtractArgs | MoveArgs | WrapInArgs | GenericArgs;
52
+ export interface NotationAction {
53
+ verb: ActionVerb;
54
+ raw: string;
55
+ args: ActionArgs;
56
+ }
57
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/types/action.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;;CASb,CAAA;AACV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAA;AAErE,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,OAAO,UAAU,CAAC,OAAO,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,UAAU,CAAC,MAAM,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,UAAU,CAAC,MAAM,CAAA;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,UAAU,CAAC,MAAM,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,OAAO,UAAU,CAAC,OAAO,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,OAAO,UAAU,CAAC,IAAI,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,UAAU,CAAC,OAAO,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,OAAO,UAAU,CAAC,OAAO,CAAA;IAC/B,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,UAAU,GACnB,WAAW,GACX,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,QAAQ,GACR,UAAU,GACV,WAAW,CAAA;AAEd,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,UAAU,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,UAAU,CAAA;CAChB"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionVerb = void 0;
4
+ exports.ActionVerb = {
5
+ REPLACE: 'replace',
6
+ REMOVE: 'remove',
7
+ RENAME: 'rename',
8
+ INSERT: 'insert',
9
+ EXTRACT: 'extract',
10
+ MOVE: 'move',
11
+ WRAP_IN: 'wrapIn',
12
+ GENERIC: 'generic',
13
+ };
@@ -0,0 +1,11 @@
1
+ import type { MarkerType } from './enums';
2
+ export interface TrackerConfig {
3
+ rootDir: string;
4
+ include: string[];
5
+ exclude: string[];
6
+ markers: MarkerType[];
7
+ storagePath: string;
8
+ idPrefix: string;
9
+ }
10
+ export declare const DEFAULT_CONFIG: TrackerConfig;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,cAAc,EAAE,aAO5B,CAAA"}