@mono-labs/tracker 0.1.274 → 0.1.280

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 (114) hide show
  1. package/dist/dashboard/cli.js +42 -0
  2. package/dist/dashboard/server.d.ts.map +1 -1
  3. package/dist/dashboard/server.js +466 -3
  4. package/dist/dashboard/watcher.d.ts +1 -1
  5. package/dist/dashboard/watcher.d.ts.map +1 -1
  6. package/dist/dashboard/watcher.js +1 -1
  7. package/dist/executor/action-executor.d.ts +3 -3
  8. package/dist/executor/action-executor.d.ts.map +1 -1
  9. package/dist/executor/action-executor.js +2 -2
  10. package/dist/executor/actions/extract-action.d.ts +4 -0
  11. package/dist/executor/actions/extract-action.d.ts.map +1 -0
  12. package/dist/executor/actions/extract-action.js +85 -0
  13. package/dist/executor/actions/index.d.ts +4 -0
  14. package/dist/executor/actions/index.d.ts.map +1 -1
  15. package/dist/executor/actions/index.js +9 -1
  16. package/dist/executor/actions/insert-action.d.ts +4 -0
  17. package/dist/executor/actions/insert-action.d.ts.map +1 -0
  18. package/dist/executor/actions/insert-action.js +74 -0
  19. package/dist/executor/actions/move-action.d.ts +4 -0
  20. package/dist/executor/actions/move-action.d.ts.map +1 -0
  21. package/dist/executor/actions/move-action.js +83 -0
  22. package/dist/executor/actions/remove-action.d.ts +2 -2
  23. package/dist/executor/actions/remove-action.d.ts.map +1 -1
  24. package/dist/executor/actions/remove-action.js +70 -6
  25. package/dist/executor/actions/rename-action.d.ts +2 -2
  26. package/dist/executor/actions/rename-action.d.ts.map +1 -1
  27. package/dist/executor/actions/rename-action.js +69 -6
  28. package/dist/executor/actions/replace-action.d.ts +2 -2
  29. package/dist/executor/actions/replace-action.d.ts.map +1 -1
  30. package/dist/executor/actions/replace-action.js +65 -6
  31. package/dist/executor/actions/wrap-action.d.ts +4 -0
  32. package/dist/executor/actions/wrap-action.d.ts.map +1 -0
  33. package/dist/executor/actions/wrap-action.js +97 -0
  34. package/dist/executor/index.d.ts +1 -1
  35. package/dist/executor/index.d.ts.map +1 -1
  36. package/dist/executor/index.js +21 -1
  37. package/dist/governance/deprecation-tracker.d.ts +21 -0
  38. package/dist/governance/deprecation-tracker.d.ts.map +1 -0
  39. package/dist/governance/deprecation-tracker.js +55 -0
  40. package/dist/governance/index.d.ts +5 -0
  41. package/dist/governance/index.d.ts.map +1 -0
  42. package/dist/governance/index.js +7 -0
  43. package/dist/governance/security-gate.d.ts +15 -0
  44. package/dist/governance/security-gate.d.ts.map +1 -0
  45. package/dist/governance/security-gate.js +40 -0
  46. package/dist/governance/security-gate.test.d.ts +2 -0
  47. package/dist/governance/security-gate.test.d.ts.map +1 -0
  48. package/dist/governance/security-gate.test.js +67 -0
  49. package/dist/index.d.ts +13 -6
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +20 -1
  52. package/dist/integrations/ai-suggest.d.ts +8 -0
  53. package/dist/integrations/ai-suggest.d.ts.map +1 -0
  54. package/dist/integrations/ai-suggest.js +106 -0
  55. package/dist/integrations/github-issues.d.ts +8 -0
  56. package/dist/integrations/github-issues.d.ts.map +1 -0
  57. package/dist/integrations/github-issues.js +84 -0
  58. package/dist/integrations/index.d.ts +5 -0
  59. package/dist/integrations/index.d.ts.map +1 -0
  60. package/dist/integrations/index.js +9 -0
  61. package/dist/integrations/jira-issues.d.ts +8 -0
  62. package/dist/integrations/jira-issues.d.ts.map +1 -0
  63. package/dist/integrations/jira-issues.js +93 -0
  64. package/dist/manager/health-score.d.ts +3 -0
  65. package/dist/manager/health-score.d.ts.map +1 -0
  66. package/dist/manager/health-score.js +32 -0
  67. package/dist/manager/index.d.ts +3 -0
  68. package/dist/manager/index.d.ts.map +1 -1
  69. package/dist/manager/index.js +5 -1
  70. package/dist/manager/notation-manager.test.js +5 -1
  71. package/dist/manager/projection.d.ts +15 -0
  72. package/dist/manager/projection.d.ts.map +1 -0
  73. package/dist/manager/projection.js +56 -0
  74. package/dist/scanner/action-serializer.d.ts +4 -0
  75. package/dist/scanner/action-serializer.d.ts.map +1 -0
  76. package/dist/scanner/action-serializer.js +54 -0
  77. package/dist/scanner/attribute-parser.d.ts +2 -0
  78. package/dist/scanner/attribute-parser.d.ts.map +1 -1
  79. package/dist/scanner/attribute-parser.js +11 -0
  80. package/dist/scanner/git-blame.d.ts +3 -0
  81. package/dist/scanner/git-blame.d.ts.map +1 -0
  82. package/dist/scanner/git-blame.js +81 -0
  83. package/dist/scanner/index.d.ts +1 -0
  84. package/dist/scanner/index.d.ts.map +1 -1
  85. package/dist/scanner/index.js +4 -1
  86. package/dist/scanner/notation-parser.d.ts.map +1 -1
  87. package/dist/scanner/notation-parser.js +3 -1
  88. package/dist/storage/config-loader.d.ts +6 -0
  89. package/dist/storage/config-loader.d.ts.map +1 -1
  90. package/dist/storage/config-loader.js +10 -0
  91. package/dist/storage/index.d.ts +4 -1
  92. package/dist/storage/index.d.ts.map +1 -1
  93. package/dist/storage/index.js +4 -1
  94. package/dist/storage/snapshot-storage.d.ts +16 -0
  95. package/dist/storage/snapshot-storage.d.ts.map +1 -0
  96. package/dist/storage/snapshot-storage.js +106 -0
  97. package/dist/storage/snapshot-storage.test.d.ts +2 -0
  98. package/dist/storage/snapshot-storage.test.d.ts.map +1 -0
  99. package/dist/storage/snapshot-storage.test.js +117 -0
  100. package/dist/types/config.d.ts +22 -0
  101. package/dist/types/config.d.ts.map +1 -1
  102. package/dist/types/config.js +5 -1
  103. package/dist/types/enums.d.ts +1 -0
  104. package/dist/types/enums.d.ts.map +1 -1
  105. package/dist/types/enums.js +1 -0
  106. package/dist/types/index.d.ts +1 -1
  107. package/dist/types/index.d.ts.map +1 -1
  108. package/dist/types/notation.d.ts +9 -0
  109. package/dist/types/notation.d.ts.map +1 -1
  110. package/dist-dashboard/assets/index-CzsCRhkp.js +197 -0
  111. package/dist-dashboard/assets/index-DUqAN9SG.css +1 -0
  112. package/dist-dashboard/index.html +12 -1
  113. package/package.json +33 -8
  114. package/dist-dashboard/assets/index-Bi4tCz8P.js +0 -62
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createGitHubIssue = createGitHubIssue;
7
+ const https_1 = __importDefault(require("https"));
8
+ async function createGitHubIssue(config, token, notation) {
9
+ const title = `[${notation.type}] ${notation.description}`;
10
+ const body = buildIssueBody(notation);
11
+ const data = JSON.stringify({
12
+ title,
13
+ body,
14
+ labels: [notation.type.toLowerCase(), notation.priority || 'medium'].filter(Boolean),
15
+ });
16
+ return new Promise((resolve, reject) => {
17
+ const req = https_1.default.request({
18
+ hostname: 'api.github.com',
19
+ path: `/repos/${config.owner}/${config.repo}/issues`,
20
+ method: 'POST',
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ 'Authorization': `Bearer ${token}`,
24
+ 'User-Agent': 'mono-labs-tracker',
25
+ 'Accept': 'application/vnd.github.v3+json',
26
+ 'Content-Length': Buffer.byteLength(data),
27
+ },
28
+ timeout: 15000,
29
+ }, (res) => {
30
+ let body = '';
31
+ res.on('data', (chunk) => { body += chunk; });
32
+ res.on('end', () => {
33
+ try {
34
+ const parsed = JSON.parse(body);
35
+ if (res.statusCode === 201 && parsed.html_url) {
36
+ resolve(parsed.html_url);
37
+ }
38
+ else {
39
+ reject(new Error(`GitHub API error: ${res.statusCode} ${parsed.message || body}`));
40
+ }
41
+ }
42
+ catch {
43
+ reject(new Error(`GitHub API error: ${res.statusCode}`));
44
+ }
45
+ });
46
+ });
47
+ req.on('error', reject);
48
+ req.on('timeout', () => {
49
+ req.destroy();
50
+ reject(new Error('GitHub API timeout'));
51
+ });
52
+ req.write(data);
53
+ req.end();
54
+ });
55
+ }
56
+ function buildIssueBody(notation) {
57
+ const lines = [];
58
+ lines.push(`**Type:** ${notation.type}`);
59
+ lines.push(`**File:** \`${notation.location.file}:${notation.location.line}\``);
60
+ if (notation.priority)
61
+ lines.push(`**Priority:** ${notation.priority}`);
62
+ if (notation.assignee)
63
+ lines.push(`**Assignee:** ${notation.assignee}`);
64
+ if (notation.dueDate)
65
+ lines.push(`**Due Date:** ${notation.dueDate}`);
66
+ lines.push('');
67
+ lines.push('## Description');
68
+ lines.push(notation.description);
69
+ if (notation.body.length > 0) {
70
+ lines.push('');
71
+ lines.push(notation.body.join('\n'));
72
+ }
73
+ if (notation.codeContext.length > 0) {
74
+ lines.push('');
75
+ lines.push('## Code Context');
76
+ lines.push('```');
77
+ lines.push(notation.codeContext.join('\n'));
78
+ lines.push('```');
79
+ }
80
+ lines.push('');
81
+ lines.push('---');
82
+ lines.push('*Created by [@mono-labs/tracker](https://github.com/mono-labs/tracker)*');
83
+ return lines.join('\n');
84
+ }
@@ -0,0 +1,5 @@
1
+ export { createGitHubIssue } from './github-issues';
2
+ export { createJiraIssue } from './jira-issues';
3
+ export { suggestFix } from './ai-suggest';
4
+ export type { SuggestedFix } from './ai-suggest';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.suggestFix = exports.createJiraIssue = exports.createGitHubIssue = void 0;
4
+ var github_issues_1 = require("./github-issues");
5
+ Object.defineProperty(exports, "createGitHubIssue", { enumerable: true, get: function () { return github_issues_1.createGitHubIssue; } });
6
+ var jira_issues_1 = require("./jira-issues");
7
+ Object.defineProperty(exports, "createJiraIssue", { enumerable: true, get: function () { return jira_issues_1.createJiraIssue; } });
8
+ var ai_suggest_1 = require("./ai-suggest");
9
+ Object.defineProperty(exports, "suggestFix", { enumerable: true, get: function () { return ai_suggest_1.suggestFix; } });
@@ -0,0 +1,8 @@
1
+ import type { Notation } from '../types';
2
+ interface JiraConfig {
3
+ baseUrl: string;
4
+ project: string;
5
+ }
6
+ export declare function createJiraIssue(config: JiraConfig, token: string, notation: Notation): Promise<string>;
7
+ export {};
8
+ //# sourceMappingURL=jira-issues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-issues.d.ts","sourceRoot":"","sources":["../../src/integrations/jira-issues.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,UAAU,UAAU;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CACf;AAUD,wBAAsB,eAAe,CACpC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,MAAM,CAAC,CA2DjB"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createJiraIssue = createJiraIssue;
7
+ const https_1 = __importDefault(require("https"));
8
+ const PRIORITY_MAP = {
9
+ critical: 'Highest',
10
+ high: 'High',
11
+ medium: 'Medium',
12
+ low: 'Low',
13
+ minimal: 'Lowest',
14
+ };
15
+ async function createJiraIssue(config, token, notation) {
16
+ const summary = `[${notation.type}] ${notation.description}`.slice(0, 255);
17
+ const description = buildJiraDescription(notation);
18
+ const data = JSON.stringify({
19
+ fields: {
20
+ project: { key: config.project },
21
+ summary,
22
+ description,
23
+ issuetype: { name: notation.type === 'BUG' ? 'Bug' : 'Task' },
24
+ ...(notation.priority && PRIORITY_MAP[notation.priority]
25
+ ? { priority: { name: PRIORITY_MAP[notation.priority] } }
26
+ : {}),
27
+ },
28
+ });
29
+ const url = new URL(config.baseUrl);
30
+ return new Promise((resolve, reject) => {
31
+ const req = https_1.default.request({
32
+ hostname: url.hostname,
33
+ path: '/rest/api/3/issue',
34
+ method: 'POST',
35
+ headers: {
36
+ 'Content-Type': 'application/json',
37
+ 'Authorization': `Basic ${token}`,
38
+ 'Accept': 'application/json',
39
+ 'Content-Length': Buffer.byteLength(data),
40
+ },
41
+ timeout: 15000,
42
+ }, (res) => {
43
+ let body = '';
44
+ res.on('data', (chunk) => { body += chunk; });
45
+ res.on('end', () => {
46
+ try {
47
+ const parsed = JSON.parse(body);
48
+ if (res.statusCode === 201 && parsed.key) {
49
+ const issueUrl = `${config.baseUrl}/browse/${parsed.key}`;
50
+ resolve(issueUrl);
51
+ }
52
+ else {
53
+ reject(new Error(`Jira API error: ${res.statusCode} ${JSON.stringify(parsed.errors || parsed)}`));
54
+ }
55
+ }
56
+ catch {
57
+ reject(new Error(`Jira API error: ${res.statusCode}`));
58
+ }
59
+ });
60
+ });
61
+ req.on('error', reject);
62
+ req.on('timeout', () => {
63
+ req.destroy();
64
+ reject(new Error('Jira API timeout'));
65
+ });
66
+ req.write(data);
67
+ req.end();
68
+ });
69
+ }
70
+ function buildJiraDescription(notation) {
71
+ const lines = [];
72
+ lines.push(`*Type:* ${notation.type}`);
73
+ lines.push(`*File:* {{${notation.location.file}:${notation.location.line}}}`);
74
+ if (notation.priority)
75
+ lines.push(`*Priority:* ${notation.priority}`);
76
+ if (notation.assignee)
77
+ lines.push(`*Assignee:* ${notation.assignee}`);
78
+ lines.push('');
79
+ lines.push(`h3. Description`);
80
+ lines.push(notation.description);
81
+ if (notation.body.length > 0) {
82
+ lines.push('');
83
+ lines.push(notation.body.join('\n'));
84
+ }
85
+ if (notation.codeContext.length > 0) {
86
+ lines.push('');
87
+ lines.push(`h3. Code Context`);
88
+ lines.push('{code}');
89
+ lines.push(notation.codeContext.join('\n'));
90
+ lines.push('{code}');
91
+ }
92
+ return lines.join('\n');
93
+ }
@@ -0,0 +1,3 @@
1
+ import type { Notation } from '../types';
2
+ export declare function computeHealthScore(notations: Notation[]): number;
3
+ //# sourceMappingURL=health-score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-score.d.ts","sourceRoot":"","sources":["../../src/manager/health-score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAyBhE"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeHealthScore = computeHealthScore;
4
+ function computeHealthScore(notations) {
5
+ let score = 100;
6
+ for (const n of notations) {
7
+ if (n.status === 'resolved')
8
+ continue;
9
+ if (n.type === 'HACK')
10
+ score -= 3;
11
+ if (n.type === 'BUG')
12
+ score -= 4;
13
+ if (n.type === 'SECURITY' && n.priority === 'critical')
14
+ score -= 10;
15
+ if (n.type === 'SECURITY' && n.priority === 'high')
16
+ score -= 5;
17
+ if (n.dueDate && new Date(n.dueDate + 'T23:59:59') < new Date())
18
+ score -= 2;
19
+ if (n.relationships.length > 0)
20
+ score -= 1;
21
+ if (n.type === 'DEPRECATION' && n.eolDate && new Date(n.eolDate) < new Date())
22
+ score -= 3;
23
+ }
24
+ // Debt hours deduction
25
+ const totalDebt = notations
26
+ .filter((n) => n.status !== 'resolved' && n.debt)
27
+ .reduce((sum, n) => sum + (n.debt?.hours ?? 0), 0);
28
+ if (totalDebt > 40) {
29
+ score -= Math.floor((totalDebt - 40) / 10);
30
+ }
31
+ return Math.max(0, score);
32
+ }
@@ -4,4 +4,7 @@ export { updateStatus, addTag, removeTag, setAssignee } from './notation-updater
4
4
  export { validateNotation, validateAll } from './validator';
5
5
  export type { ValidationError } from './validator';
6
6
  export { computeStats } from './stats';
7
+ export { computeHealthScore } from './health-score';
8
+ export { computeBurnDown } from './projection';
9
+ export type { BurnDownData, BurnDownPoint } from './projection';
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACjF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.computeStats = exports.validateAll = exports.validateNotation = exports.setAssignee = exports.removeTag = exports.addTag = exports.updateStatus = exports.detectCircularDependencies = exports.isBlocked = exports.getBlockers = exports.NotationManager = void 0;
3
+ exports.computeBurnDown = exports.computeHealthScore = exports.computeStats = exports.validateAll = exports.validateNotation = exports.setAssignee = exports.removeTag = exports.addTag = exports.updateStatus = exports.detectCircularDependencies = exports.isBlocked = exports.getBlockers = exports.NotationManager = void 0;
4
4
  var notation_manager_1 = require("./notation-manager");
5
5
  Object.defineProperty(exports, "NotationManager", { enumerable: true, get: function () { return notation_manager_1.NotationManager; } });
6
6
  var relationship_manager_1 = require("./relationship-manager");
@@ -17,3 +17,7 @@ Object.defineProperty(exports, "validateNotation", { enumerable: true, get: func
17
17
  Object.defineProperty(exports, "validateAll", { enumerable: true, get: function () { return validator_1.validateAll; } });
18
18
  var stats_1 = require("./stats");
19
19
  Object.defineProperty(exports, "computeStats", { enumerable: true, get: function () { return stats_1.computeStats; } });
20
+ var health_score_1 = require("./health-score");
21
+ Object.defineProperty(exports, "computeHealthScore", { enumerable: true, get: function () { return health_score_1.computeHealthScore; } });
22
+ var projection_1 = require("./projection");
23
+ Object.defineProperty(exports, "computeBurnDown", { enumerable: true, get: function () { return projection_1.computeBurnDown; } });
@@ -27,9 +27,13 @@ const testConfig = {
27
27
  rootDir: '/tmp/test-project',
28
28
  include: ['**/*.ts'],
29
29
  exclude: ['**/node_modules/**'],
30
- markers: ['TODO', 'FIXME', 'BUG', 'HACK', 'NOTE', 'OPTIMIZE', 'SECURITY'],
30
+ markers: ['TODO', 'FIXME', 'BUG', 'HACK', 'NOTE', 'OPTIMIZE', 'SECURITY', 'DEPRECATION'],
31
31
  storagePath: '/tmp/test-tracker/notations.jsonl',
32
+ snapshotPath: '/tmp/test-tracker/snapshots.jsonl',
32
33
  idPrefix: 'N',
34
+ gitBlame: false,
35
+ securityGate: { enabled: false, blockOnCritical: true, blockOnHigh: false },
36
+ integrations: {},
33
37
  };
34
38
  (0, vitest_1.describe)('NotationManager', () => {
35
39
  let manager;
@@ -0,0 +1,15 @@
1
+ import type { Snapshot } from '../storage/snapshot-storage';
2
+ import type { Notation } from '../types';
3
+ export interface BurnDownPoint {
4
+ date: string;
5
+ total: number;
6
+ projected?: boolean;
7
+ }
8
+ export interface BurnDownData {
9
+ historical: BurnDownPoint[];
10
+ projection: BurnDownPoint[];
11
+ weeklyResolutionRate: number;
12
+ estimatedZeroDate: string | null;
13
+ }
14
+ export declare function computeBurnDown(snapshots: Snapshot[], currentNotations: Notation[]): BurnDownData;
15
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../src/manager/projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,YAAY,CA6CjG"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeBurnDown = computeBurnDown;
4
+ function computeBurnDown(snapshots, currentNotations) {
5
+ const historical = snapshots.map((s) => ({
6
+ date: s.date,
7
+ total: s.stats.total,
8
+ }));
9
+ // Add current state
10
+ const today = new Date().toISOString().slice(0, 10);
11
+ const currentTotal = currentNotations.filter((n) => n.status !== 'resolved').length;
12
+ if (!historical.find((h) => h.date === today)) {
13
+ historical.push({ date: today, total: currentTotal });
14
+ }
15
+ // Calculate weekly resolution rate from historical data
16
+ const weeklyResolutionRate = computeWeeklyRate(historical);
17
+ // Project forward
18
+ const projection = [];
19
+ let estimatedZeroDate = null;
20
+ if (weeklyResolutionRate > 0 && historical.length >= 2) {
21
+ let remaining = currentTotal;
22
+ const startDate = new Date(today);
23
+ for (let week = 1; week <= 26; week++) { // Project up to 26 weeks
24
+ remaining = Math.max(0, remaining - weeklyResolutionRate);
25
+ const projDate = new Date(startDate);
26
+ projDate.setDate(projDate.getDate() + week * 7);
27
+ const dateStr = projDate.toISOString().slice(0, 10);
28
+ projection.push({ date: dateStr, total: Math.round(remaining), projected: true });
29
+ if (remaining <= 0 && !estimatedZeroDate) {
30
+ estimatedZeroDate = dateStr;
31
+ break;
32
+ }
33
+ }
34
+ }
35
+ return {
36
+ historical,
37
+ projection,
38
+ weeklyResolutionRate,
39
+ estimatedZeroDate,
40
+ };
41
+ }
42
+ function computeWeeklyRate(points) {
43
+ if (points.length < 2)
44
+ return 0;
45
+ const first = points[0];
46
+ const last = points[points.length - 1];
47
+ const daysDiff = (new Date(last.date).getTime() - new Date(first.date).getTime()) / (1000 * 60 * 60 * 24);
48
+ if (daysDiff <= 0)
49
+ return 0;
50
+ const totalReduction = first.total - last.total;
51
+ if (totalReduction <= 0)
52
+ return 0;
53
+ // Convert daily rate to weekly rate
54
+ const dailyRate = totalReduction / daysDiff;
55
+ return Math.round(dailyRate * 7 * 100) / 100;
56
+ }
@@ -0,0 +1,4 @@
1
+ import type { NotationAction } from '../types';
2
+ export declare function serializeAction(action: NotationAction): string;
3
+ export declare function serializeActions(actions: NotationAction[]): string[];
4
+ //# sourceMappingURL=action-serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-serializer.d.ts","sourceRoot":"","sources":["../../src/scanner/action-serializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,UAAU,CAAA;AAgD1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAEpE"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeAction = serializeAction;
4
+ exports.serializeActions = serializeActions;
5
+ const action_1 = require("../types/action");
6
+ function serializeArgs(args) {
7
+ switch (args.verb) {
8
+ case action_1.ActionVerb.REPLACE:
9
+ return `replace(${quote(args.target)}, ${quote(args.replacement)})`;
10
+ case action_1.ActionVerb.REMOVE:
11
+ return `remove(${quote(args.target)})`;
12
+ case action_1.ActionVerb.RENAME:
13
+ return `rename(${quote(args.from)}, ${quote(args.to)})`;
14
+ case action_1.ActionVerb.INSERT: {
15
+ const base = `insert(${quote(args.content)})`;
16
+ if (args.anchor) {
17
+ return `${base}.${args.position}(${quote(args.anchor)})`;
18
+ }
19
+ return base;
20
+ }
21
+ case action_1.ActionVerb.EXTRACT: {
22
+ const base = `extract(${quote(args.target)})`;
23
+ if (args.destination) {
24
+ return `${base}.to(${quote(args.destination)})`;
25
+ }
26
+ return base;
27
+ }
28
+ case action_1.ActionVerb.MOVE: {
29
+ const base = `move(${quote(args.target)})`;
30
+ if (args.destination) {
31
+ return `${base}.to(${quote(args.destination)})`;
32
+ }
33
+ return base;
34
+ }
35
+ case action_1.ActionVerb.WRAP_IN:
36
+ return `wrapIn(${quote(args.target)}, ${quote(args.wrapper)})`;
37
+ case action_1.ActionVerb.GENERIC:
38
+ return args.description;
39
+ default:
40
+ return '';
41
+ }
42
+ }
43
+ function quote(s) {
44
+ if (s.includes("'")) {
45
+ return `"${s}"`;
46
+ }
47
+ return `'${s}'`;
48
+ }
49
+ function serializeAction(action) {
50
+ return `Action: ${serializeArgs(action.args)}`;
51
+ }
52
+ function serializeActions(actions) {
53
+ return actions.map((a) => `// ${serializeAction(a)}`);
54
+ }
@@ -10,6 +10,8 @@ export interface ParsedAttributes {
10
10
  performance?: PerformanceImpact;
11
11
  debt?: TechnicalDebt;
12
12
  relationships: string[];
13
+ eolDate?: string;
14
+ replacement?: string;
13
15
  }
14
16
  export declare function parseAttributes(bodyLines: string[]): ParsedAttributes;
15
17
  //# sourceMappingURL=attribute-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attribute-parser.d.ts","sourceRoot":"","sources":["../../src/scanner/attribute-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAmB,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGtG,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;CACvB;AAoKD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAiBrE"}
1
+ {"version":3,"file":"attribute-parser.d.ts","sourceRoot":"","sources":["../../src/scanner/attribute-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAmB,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGtG,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AA8KD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAiBrE"}
@@ -102,6 +102,17 @@ function applyKeyValue(key, value, attrs) {
102
102
  case 'related':
103
103
  attrs.relationships.push(...value.split(',').map((r) => r.trim()).filter(Boolean));
104
104
  break;
105
+ case 'eol':
106
+ case 'eoldate':
107
+ case 'eol date': {
108
+ const parsed = (0, utils_1.parseDate)(value);
109
+ if (parsed)
110
+ attrs.eolDate = parsed;
111
+ break;
112
+ }
113
+ case 'replacement':
114
+ attrs.replacement = value;
115
+ break;
105
116
  }
106
117
  }
107
118
  function parseAtPrefix(line, attrs) {
@@ -0,0 +1,3 @@
1
+ import type { Notation } from '../types';
2
+ export declare function batchBlame(projectRoot: string, notations: Notation[]): Promise<Notation[]>;
3
+ //# sourceMappingURL=git-blame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-blame.d.ts","sourceRoot":"","sources":["../../src/scanner/git-blame.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsExC,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAsBhG"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.batchBlame = batchBlame;
4
+ const child_process_1 = require("child_process");
5
+ // In-memory cache with TTL
6
+ const blameCache = new Map();
7
+ const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
8
+ function getCached(key) {
9
+ const entry = blameCache.get(key);
10
+ if (!entry)
11
+ return null;
12
+ if (Date.now() > entry.expires) {
13
+ blameCache.delete(key);
14
+ return null;
15
+ }
16
+ return entry.data;
17
+ }
18
+ function setCached(key, data) {
19
+ blameCache.set(key, { data, expires: Date.now() + CACHE_TTL });
20
+ }
21
+ function blameFile(projectRoot, file, line) {
22
+ return new Promise((resolve) => {
23
+ const args = ['blame', '-p', `-L${line},${line}`, '--', file];
24
+ (0, child_process_1.execFile)('git', args, { cwd: projectRoot, timeout: 10000 }, (err, stdout) => {
25
+ if (err) {
26
+ resolve(null);
27
+ return;
28
+ }
29
+ try {
30
+ const lines = stdout.split('\n');
31
+ let author = '';
32
+ let email = '';
33
+ let date = '';
34
+ let commitHash = '';
35
+ // First line starts with the commit hash
36
+ if (lines[0]) {
37
+ commitHash = lines[0].split(' ')[0];
38
+ }
39
+ for (const l of lines) {
40
+ if (l.startsWith('author '))
41
+ author = l.slice(7);
42
+ if (l.startsWith('author-mail '))
43
+ email = l.slice(12).replace(/[<>]/g, '');
44
+ if (l.startsWith('author-time ')) {
45
+ const timestamp = parseInt(l.slice(12), 10);
46
+ date = new Date(timestamp * 1000).toISOString();
47
+ }
48
+ }
49
+ if (author && commitHash) {
50
+ resolve({ author, email, date, commitHash });
51
+ }
52
+ else {
53
+ resolve(null);
54
+ }
55
+ }
56
+ catch {
57
+ resolve(null);
58
+ }
59
+ });
60
+ });
61
+ }
62
+ async function batchBlame(projectRoot, notations) {
63
+ const results = [];
64
+ for (const n of notations) {
65
+ const cacheKey = `${n.location.file}:${n.location.line}`;
66
+ const cached = getCached(cacheKey);
67
+ if (cached) {
68
+ results.push({ ...n, blame: cached });
69
+ continue;
70
+ }
71
+ const blame = await blameFile(projectRoot, n.location.file, n.location.line);
72
+ if (blame) {
73
+ setCached(cacheKey, blame);
74
+ results.push({ ...n, blame });
75
+ }
76
+ else {
77
+ results.push(n);
78
+ }
79
+ }
80
+ return results;
81
+ }
@@ -1,6 +1,7 @@
1
1
  export { parseAttributes } from './attribute-parser';
2
2
  export type { ParsedAttributes } from './attribute-parser';
3
3
  export { parseActions } from './action-parser';
4
+ export { serializeAction, serializeActions } from './action-serializer';
4
5
  export { parseFileContent } from './notation-parser';
5
6
  export { scanFiles } from './file-scanner';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.scanFiles = exports.parseFileContent = exports.parseActions = exports.parseAttributes = void 0;
3
+ exports.scanFiles = exports.parseFileContent = exports.serializeActions = exports.serializeAction = exports.parseActions = exports.parseAttributes = void 0;
4
4
  var attribute_parser_1 = require("./attribute-parser");
5
5
  Object.defineProperty(exports, "parseAttributes", { enumerable: true, get: function () { return attribute_parser_1.parseAttributes; } });
6
6
  var action_parser_1 = require("./action-parser");
7
7
  Object.defineProperty(exports, "parseActions", { enumerable: true, get: function () { return action_parser_1.parseActions; } });
8
+ var action_serializer_1 = require("./action-serializer");
9
+ Object.defineProperty(exports, "serializeAction", { enumerable: true, get: function () { return action_serializer_1.serializeAction; } });
10
+ Object.defineProperty(exports, "serializeActions", { enumerable: true, get: function () { return action_serializer_1.serializeActions; } });
8
11
  var notation_parser_1 = require("./notation-parser");
9
12
  Object.defineProperty(exports, "parseFileContent", { enumerable: true, get: function () { return notation_parser_1.parseFileContent; } });
10
13
  var file_scanner_1 = require("./file-scanner");
@@ -1 +1 @@
1
- {"version":3,"file":"notation-parser.d.ts","sourceRoot":"","sources":["../../src/scanner/notation-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,UAAU,CAAA;AAQpD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAY,GAAG,QAAQ,EAAE,CAoFtG"}
1
+ {"version":3,"file":"notation-parser.d.ts","sourceRoot":"","sources":["../../src/scanner/notation-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,UAAU,CAAA;AAQpD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAY,GAAG,QAAQ,EAAE,CAsFtG"}
@@ -5,7 +5,7 @@ const enums_1 = require("../types/enums");
5
5
  const utils_1 = require("../utils");
6
6
  const attribute_parser_1 = require("./attribute-parser");
7
7
  const action_parser_1 = require("./action-parser");
8
- const MARKER_REGEX = /^(\s*)\/\/\s*(FIXME|TODO|BUG|HACK|NOTE|OPTIMIZE|SECURITY):?\s*(?:\[([^\]]*)\])?\s*(.*)/;
8
+ const MARKER_REGEX = /^(\s*)\/\/\s*(FIXME|TODO|BUG|HACK|NOTE|OPTIMIZE|SECURITY|DEPRECATION):?\s*(?:\[([^\]]*)\])?\s*(.*)/;
9
9
  function parseFileContent(filePath, content, idPrefix = 'N') {
10
10
  const lines = content.split('\n');
11
11
  const notations = [];
@@ -77,6 +77,8 @@ function parseFileContent(filePath, content, idPrefix = 'N') {
77
77
  createdDate: attrs.createdDate,
78
78
  performance: attrs.performance,
79
79
  debt: attrs.debt,
80
+ eolDate: attrs.eolDate,
81
+ replacement: attrs.replacement,
80
82
  actions,
81
83
  relationships: attrs.relationships,
82
84
  rawBlock: rawLines.join('\n'),
@@ -1,3 +1,9 @@
1
1
  import type { TrackerConfig } from '../types';
2
+ export interface ResolvedSecrets {
3
+ githubToken?: string;
4
+ jiraToken?: string;
5
+ aiKey?: string;
6
+ }
7
+ export declare function loadSecrets(): ResolvedSecrets;
2
8
  export declare function loadConfig(projectRoot: string): TrackerConfig;
3
9
  //# sourceMappingURL=config-loader.d.ts.map
@@ -1 +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"}
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,MAAM,WAAW,eAAe;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,WAAW,IAAI,eAAe,CAM7C;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAkB7D"}