projscan 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +24 -7
  2. package/dist/cli/commands/applyFix.d.ts +7 -0
  3. package/dist/cli/commands/applyFix.js +113 -0
  4. package/dist/cli/commands/applyFix.js.map +1 -0
  5. package/dist/cli/commands/coverage.js +13 -0
  6. package/dist/cli/commands/coverage.js.map +1 -1
  7. package/dist/cli/commands/doctor.js +18 -2
  8. package/dist/cli/commands/doctor.js.map +1 -1
  9. package/dist/cli/commands/explain.js +1 -0
  10. package/dist/cli/commands/explain.js.map +1 -1
  11. package/dist/cli/commands/impact.js +25 -1
  12. package/dist/cli/commands/impact.js.map +1 -1
  13. package/dist/cli/commands/init.d.ts +6 -0
  14. package/dist/cli/commands/init.js +70 -0
  15. package/dist/cli/commands/init.js.map +1 -0
  16. package/dist/cli/commands/installHook.d.ts +9 -0
  17. package/dist/cli/commands/installHook.js +90 -0
  18. package/dist/cli/commands/installHook.js.map +1 -0
  19. package/dist/cli/commands/memory.d.ts +11 -0
  20. package/dist/cli/commands/memory.js +175 -0
  21. package/dist/cli/commands/memory.js.map +1 -0
  22. package/dist/cli/commands/taint.d.ts +6 -0
  23. package/dist/cli/commands/taint.js +74 -0
  24. package/dist/cli/commands/taint.js.map +1 -0
  25. package/dist/cli/commands/workspace.d.ts +11 -0
  26. package/dist/cli/commands/workspace.js +115 -0
  27. package/dist/cli/commands/workspace.js.map +1 -0
  28. package/dist/cli/index.js +12 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/core/applyFix.d.ts +52 -0
  31. package/dist/core/applyFix.js +220 -0
  32. package/dist/core/applyFix.js.map +1 -0
  33. package/dist/core/ast.d.ts +9 -0
  34. package/dist/core/ast.js +35 -4
  35. package/dist/core/ast.js.map +1 -1
  36. package/dist/core/codeGraph.js +190 -241
  37. package/dist/core/codeGraph.js.map +1 -1
  38. package/dist/core/fileInspector.js +40 -44
  39. package/dist/core/fileInspector.js.map +1 -1
  40. package/dist/core/fixSuggest.d.ts +6 -0
  41. package/dist/core/fixSuggest.js +195 -0
  42. package/dist/core/fixSuggest.js.map +1 -1
  43. package/dist/core/hotspotAnalyzer.js +65 -19
  44. package/dist/core/hotspotAnalyzer.js.map +1 -1
  45. package/dist/core/impact.d.ts +8 -0
  46. package/dist/core/impact.js +41 -3
  47. package/dist/core/impact.js.map +1 -1
  48. package/dist/core/indexCache.js +4 -1
  49. package/dist/core/indexCache.js.map +1 -1
  50. package/dist/core/issueEngine.js +24 -0
  51. package/dist/core/issueEngine.js.map +1 -1
  52. package/dist/core/languages/csharpImports.js +6 -4
  53. package/dist/core/languages/csharpImports.js.map +1 -1
  54. package/dist/core/memory.d.ts +154 -0
  55. package/dist/core/memory.js +277 -0
  56. package/dist/core/memory.js.map +1 -0
  57. package/dist/core/review.d.ts +25 -1
  58. package/dist/core/review.js +133 -2
  59. package/dist/core/review.js.map +1 -1
  60. package/dist/core/taint.d.ts +91 -0
  61. package/dist/core/taint.js +185 -0
  62. package/dist/core/taint.js.map +1 -0
  63. package/dist/core/workspace.d.ts +62 -0
  64. package/dist/core/workspace.js +127 -0
  65. package/dist/core/workspace.js.map +1 -0
  66. package/dist/mcp/prompts.js +274 -0
  67. package/dist/mcp/prompts.js.map +1 -1
  68. package/dist/mcp/server.js +162 -146
  69. package/dist/mcp/server.js.map +1 -1
  70. package/dist/mcp/tokenBudget.d.ts +22 -0
  71. package/dist/mcp/tokenBudget.js +26 -0
  72. package/dist/mcp/tokenBudget.js.map +1 -1
  73. package/dist/mcp/tools/applyFix.d.ts +16 -0
  74. package/dist/mcp/tools/applyFix.js +91 -0
  75. package/dist/mcp/tools/applyFix.js.map +1 -0
  76. package/dist/mcp/tools/doctor.js +65 -2
  77. package/dist/mcp/tools/doctor.js.map +1 -1
  78. package/dist/mcp/tools/explain.js +4 -3
  79. package/dist/mcp/tools/explain.js.map +1 -1
  80. package/dist/mcp/tools/explainIssue.js +3 -2
  81. package/dist/mcp/tools/explainIssue.js.map +1 -1
  82. package/dist/mcp/tools/file.js +3 -2
  83. package/dist/mcp/tools/file.js.map +1 -1
  84. package/dist/mcp/tools/graph.js +16 -11
  85. package/dist/mcp/tools/graph.js.map +1 -1
  86. package/dist/mcp/tools/impact.js +36 -3
  87. package/dist/mcp/tools/impact.js.map +1 -1
  88. package/dist/mcp/tools/memory.d.ts +19 -0
  89. package/dist/mcp/tools/memory.js +134 -0
  90. package/dist/mcp/tools/memory.js.map +1 -0
  91. package/dist/mcp/tools/review.js +25 -4
  92. package/dist/mcp/tools/review.js.map +1 -1
  93. package/dist/mcp/tools/taint.d.ts +15 -0
  94. package/dist/mcp/tools/taint.js +67 -0
  95. package/dist/mcp/tools/taint.js.map +1 -0
  96. package/dist/mcp/tools/upgrade.js +3 -2
  97. package/dist/mcp/tools/upgrade.js.map +1 -1
  98. package/dist/mcp/tools/workspaceGraph.d.ts +18 -0
  99. package/dist/mcp/tools/workspaceGraph.js +188 -0
  100. package/dist/mcp/tools/workspaceGraph.js.map +1 -0
  101. package/dist/mcp/tools.js +8 -0
  102. package/dist/mcp/tools.js.map +1 -1
  103. package/dist/reporters/consoleReporter.d.ts +12 -1
  104. package/dist/reporters/consoleReporter.js +289 -179
  105. package/dist/reporters/consoleReporter.js.map +1 -1
  106. package/dist/reporters/markdownReporter.js +185 -128
  107. package/dist/reporters/markdownReporter.js.map +1 -1
  108. package/dist/tool-manifest.json +129 -6
  109. package/dist/types.d.ts +67 -0
  110. package/dist/utils/config.js +93 -53
  111. package/dist/utils/config.js.map +1 -1
  112. package/package.json +9 -2
@@ -0,0 +1,175 @@
1
+ import chalk from 'chalk';
2
+ import { program, getRootPath, getFormat, setupLogLevel, maybeCompactBanner } from '../_shared.js';
3
+ import { findStableRules, forgetRule, loadMemory, saveMemory, } from '../../core/memory.js';
4
+ /**
5
+ * `projscan memory` — inspect or prune the local Project Memory store
6
+ * that learns which analyzer rules this repo has been carrying across
7
+ * many runs.
8
+ *
9
+ * projscan memory — aggregate summary (default)
10
+ * projscan memory stable — long-running rules + .projscanrc snippet
11
+ * projscan memory runs — every tracked rule with full history
12
+ * projscan memory forget <rule> — drop a single rule's history
13
+ */
14
+ export function registerMemory() {
15
+ const memory = program
16
+ .command('memory')
17
+ .description('Inspect or prune the local Project Memory (1.5+)')
18
+ .action(async () => {
19
+ await runSummary();
20
+ });
21
+ memory
22
+ .command('stable')
23
+ .description('Show rules that have been surfacing across enough runs to count as accepted')
24
+ .action(async () => {
25
+ await runStable();
26
+ });
27
+ memory
28
+ .command('runs')
29
+ .description('Show every tracked rule with its observation history')
30
+ .action(async () => {
31
+ await runRuns();
32
+ });
33
+ memory
34
+ .command('forget <rule>')
35
+ .description("Drop a single rule's history from memory")
36
+ .action(async (rule) => {
37
+ await runForget(rule);
38
+ });
39
+ }
40
+ async function runSummary() {
41
+ setupLogLevel();
42
+ maybeCompactBanner();
43
+ const rootPath = getRootPath();
44
+ const format = getFormat();
45
+ try {
46
+ const m = await loadMemory(rootPath);
47
+ if (format === 'json') {
48
+ console.log(JSON.stringify(summarize(m), null, 2));
49
+ return;
50
+ }
51
+ printSummary(m);
52
+ }
53
+ catch (error) {
54
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
55
+ process.exit(1);
56
+ }
57
+ }
58
+ async function runStable() {
59
+ setupLogLevel();
60
+ maybeCompactBanner();
61
+ const rootPath = getRootPath();
62
+ const format = getFormat();
63
+ try {
64
+ const m = await loadMemory(rootPath);
65
+ const stable = findStableRules(m);
66
+ if (format === 'json') {
67
+ console.log(JSON.stringify({ totalRuns: m.totalRuns, stable }, null, 2));
68
+ return;
69
+ }
70
+ printStable(m, stable);
71
+ }
72
+ catch (error) {
73
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
74
+ process.exit(1);
75
+ }
76
+ }
77
+ async function runRuns() {
78
+ setupLogLevel();
79
+ maybeCompactBanner();
80
+ const rootPath = getRootPath();
81
+ const format = getFormat();
82
+ try {
83
+ const m = await loadMemory(rootPath);
84
+ const all = Object.values(m.rules).sort((a, b) => b.runCount - a.runCount);
85
+ if (format === 'json') {
86
+ console.log(JSON.stringify({ totalRuns: m.totalRuns, rules: all }, null, 2));
87
+ return;
88
+ }
89
+ printRuns(m, all);
90
+ }
91
+ catch (error) {
92
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
93
+ process.exit(1);
94
+ }
95
+ }
96
+ async function runForget(rule) {
97
+ setupLogLevel();
98
+ maybeCompactBanner();
99
+ const rootPath = getRootPath();
100
+ try {
101
+ const m = await loadMemory(rootPath);
102
+ const existed = forgetRule(m, rule);
103
+ if (existed) {
104
+ await saveMemory(rootPath, m);
105
+ console.log(chalk.green(`✓ Dropped "${rule}" from memory.`));
106
+ }
107
+ else {
108
+ console.log(chalk.dim(`No memory entry for "${rule}".`));
109
+ }
110
+ }
111
+ catch (error) {
112
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
113
+ process.exit(1);
114
+ }
115
+ }
116
+ function summarize(m) {
117
+ return {
118
+ totalRuns: m.totalRuns,
119
+ rulesTracked: Object.keys(m.rules).length,
120
+ stableRuleCount: findStableRules(m).length,
121
+ lastUpdatedAt: m.lastUpdatedAt,
122
+ };
123
+ }
124
+ function printSummary(m) {
125
+ const stableCount = findStableRules(m).length;
126
+ console.log('');
127
+ console.log(chalk.bold('Project Memory'));
128
+ console.log(chalk.dim('────────────────────────────────────────'));
129
+ console.log(` total runs: ${m.totalRuns}`);
130
+ console.log(` rules tracked: ${Object.keys(m.rules).length}`);
131
+ console.log(` stable rules: ${stableCount > 0 ? chalk.yellow(stableCount) : '0'} ${chalk.dim('(unfixed across many runs)')}`);
132
+ console.log(` last updated: ${m.lastUpdatedAt}`);
133
+ if (stableCount > 0) {
134
+ console.log('');
135
+ console.log(chalk.dim(' Tip: run `projscan memory stable` to see which rules to consider disabling in .projscanrc.'));
136
+ }
137
+ }
138
+ function printStable(m, stable) {
139
+ console.log('');
140
+ console.log(chalk.bold('Stable rules (effectively accepted)'));
141
+ console.log(chalk.dim('────────────────────────────────────────'));
142
+ if (stable.length === 0) {
143
+ console.log(chalk.dim(' No stable rules yet — they appear after a rule has surfaced across'));
144
+ console.log(chalk.dim(' ≥ 3 runs over ≥ 7 days without ever being fixed.'));
145
+ return;
146
+ }
147
+ for (const r of stable) {
148
+ console.log(` ${chalk.yellow('▲')} ${chalk.bold(r.ruleId)} ${chalk.dim(`(seen in ${r.runCount} runs since ${r.firstSeenAt.slice(0, 10)})`)}`);
149
+ }
150
+ console.log('');
151
+ console.log(chalk.bold(' Suggested .projscanrc.json:'));
152
+ console.log('');
153
+ console.log(' ' + JSON.stringify({ disableRules: stable.map((r) => r.ruleId) }, null, 2).split('\n').join('\n '));
154
+ }
155
+ function printRuns(m, all) {
156
+ console.log('');
157
+ console.log(chalk.bold(`Tracked rules (${all.length})`));
158
+ console.log(chalk.dim('────────────────────────────────────────'));
159
+ if (all.length === 0) {
160
+ console.log(chalk.dim(' No rules tracked yet. Memory begins recording on `projscan doctor` runs.'));
161
+ return;
162
+ }
163
+ for (const r of all.slice(0, 30)) {
164
+ const status = r.suppressedInConfig
165
+ ? chalk.dim('[suppressed]')
166
+ : r.fixedCount > 0
167
+ ? chalk.green(`[fixed ×${r.fixedCount}]`)
168
+ : chalk.dim('[active]');
169
+ console.log(` runs ${String(r.runCount).padStart(3)} ${status} ${r.ruleId}`);
170
+ }
171
+ if (all.length > 30) {
172
+ console.log(chalk.dim(` ... and ${all.length - 30} more`));
173
+ }
174
+ }
175
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/cli/commands/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * `projscan taint` (1.6+) — surface source-to-sink reachability flows.
3
+ * Mirrors `projscan_taint` MCP tool. Default output is human-readable;
4
+ * `--format json` returns the raw TaintReport.
5
+ */
6
+ export declare function registerTaint(): void;
@@ -0,0 +1,74 @@
1
+ import chalk from 'chalk';
2
+ import { program, getFormat, getRootPath, loadProjectConfig, setupLogLevel, maybeCompactBanner, } from '../_shared.js';
3
+ import { scanRepository } from '../../core/repositoryScanner.js';
4
+ import { buildCodeGraph } from '../../core/codeGraph.js';
5
+ import { computeTaint } from '../../core/taint.js';
6
+ /**
7
+ * `projscan taint` (1.6+) — surface source-to-sink reachability flows.
8
+ * Mirrors `projscan_taint` MCP tool. Default output is human-readable;
9
+ * `--format json` returns the raw TaintReport.
10
+ */
11
+ export function registerTaint() {
12
+ program
13
+ .command('taint')
14
+ .description('Source-to-sink reachability over the call graph (1.6+)')
15
+ .option('--source <name...>', 'add a custom source name (repeatable)')
16
+ .option('--sink <name...>', 'add a custom sink name (repeatable)')
17
+ .option('--limit <n>', 'cap flows shown', '50')
18
+ .action(async (opts) => {
19
+ setupLogLevel();
20
+ maybeCompactBanner();
21
+ const rootPath = getRootPath();
22
+ const format = getFormat();
23
+ try {
24
+ const config = await loadProjectConfig();
25
+ const scan = await scanRepository(rootPath, { ignore: config.ignore });
26
+ const graph = await buildCodeGraph(rootPath, scan.files);
27
+ const sources = [...(config.taint?.sources ?? []), ...(opts.source ?? [])];
28
+ const sinks = [...(config.taint?.sinks ?? []), ...(opts.sink ?? [])];
29
+ const limit = Math.max(1, Math.min(500, parseInt(opts.limit ?? '50', 10) || 50));
30
+ const report = computeTaint(graph, { sources, sinks });
31
+ if (format === 'json') {
32
+ console.log(JSON.stringify({
33
+ ...report,
34
+ flows: report.flows.slice(0, limit),
35
+ truncated: report.flows.length > limit,
36
+ }, null, 2));
37
+ return;
38
+ }
39
+ renderTaint(report, limit);
40
+ }
41
+ catch (error) {
42
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
43
+ process.exit(1);
44
+ }
45
+ });
46
+ }
47
+ function renderTaint(report, limit) {
48
+ console.log('');
49
+ console.log(chalk.bold('Taint flows'));
50
+ console.log(chalk.dim('────────────────────────────────────────'));
51
+ if (!report.available) {
52
+ console.log(` ${chalk.yellow('!')} ${report.reason ?? 'unavailable'}`);
53
+ return;
54
+ }
55
+ if (report.flowCount === 0) {
56
+ console.log(' No source-to-sink flows detected.');
57
+ console.log(chalk.dim(` Effective sources: ${report.effectiveSources.length}; sinks: ${report.effectiveSinks.length}.`));
58
+ return;
59
+ }
60
+ console.log(` ${chalk.bold(report.flowCount)} flow(s) detected:`);
61
+ console.log('');
62
+ const shown = report.flows.slice(0, limit);
63
+ for (const flow of shown) {
64
+ const arrow = flow.path.length === 1 ? '(direct)' : flow.path.join(' → ');
65
+ console.log(` ${chalk.red('●')} ${chalk.bold(flow.source)} → ${chalk.bold(flow.sink)}`);
66
+ console.log(` ${chalk.dim('path:')} ${arrow}`);
67
+ console.log(` ${chalk.dim('files:')} ${flow.files.join(', ')}`);
68
+ console.log('');
69
+ }
70
+ if (report.flowCount > limit) {
71
+ console.log(chalk.dim(` …and ${report.flowCount - limit} more (raise --limit to see them).`));
72
+ }
73
+ }
74
+ //# sourceMappingURL=taint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taint.js","sourceRoot":"","sources":["../../../src/cli/commands/taint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,OAAO,EACP,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAErE;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,wDAAwD,CAAC;SACrE,MAAM,CAAC,oBAAoB,EAAE,uCAAuC,CAAC;SACrE,MAAM,CAAC,kBAAkB,EAAE,qCAAqC,CAAC;SACjE,MAAM,CAAC,aAAa,EAAE,iBAAiB,EAAE,IAAI,CAAC;SAC9C,MAAM,CAAC,KAAK,EAAE,IAA4D,EAAE,EAAE;QAC7E,aAAa,EAAE,CAAC;QAChB,kBAAkB,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACvE,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3E,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACjF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAEvD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;oBACE,GAAG,MAAM;oBACT,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;oBACnC,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK;iBACvC,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;gBACF,OAAO;YACT,CAAC;YAED,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,WAAW,CAAC,MAAmB,EAAE,KAAa;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,wBAAwB,MAAM,CAAC,gBAAgB,CAAC,MAAM,YAAY,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAClG,CACF,CAAC;QACF,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzF,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,GAAG,KAAK,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,SAAS,GAAG,KAAK,oCAAoC,CAAC,CAAC,CAAC;IACjG,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `projscan workspace` (1.6+) — register and inspect cross-repo
3
+ * sibling repos. Distinct from `projscan workspaces` (plural) which
4
+ * lists intra-repo monorepo packages (npm/yarn/pnpm/Lerna/Nx).
5
+ *
6
+ * projscan workspace — list registered repos (default)
7
+ * projscan workspace add <path> [--name <n>]
8
+ * projscan workspace remove <path|name>
9
+ * projscan workspace list
10
+ */
11
+ export declare function registerWorkspace(): void;
@@ -0,0 +1,115 @@
1
+ import chalk from 'chalk';
2
+ import { program, getRootPath, getFormat, setupLogLevel, maybeCompactBanner } from '../_shared.js';
3
+ import { addRepo, loadOrCreateWorkspace, loadWorkspace, removeRepo, saveWorkspace, } from '../../core/workspace.js';
4
+ /**
5
+ * `projscan workspace` (1.6+) — register and inspect cross-repo
6
+ * sibling repos. Distinct from `projscan workspaces` (plural) which
7
+ * lists intra-repo monorepo packages (npm/yarn/pnpm/Lerna/Nx).
8
+ *
9
+ * projscan workspace — list registered repos (default)
10
+ * projscan workspace add <path> [--name <n>]
11
+ * projscan workspace remove <path|name>
12
+ * projscan workspace list
13
+ */
14
+ export function registerWorkspace() {
15
+ const cmd = program
16
+ .command('workspace')
17
+ .description('Register cross-repo sibling repos for multi-repo intelligence (1.6+)')
18
+ .action(async () => {
19
+ await runList();
20
+ });
21
+ cmd
22
+ .command('add <path>')
23
+ .description('Register a sibling repo at the given path')
24
+ .option('--name <name>', 'human-readable name (defaults to basename of path)')
25
+ .action(async (repoPath, opts) => {
26
+ await runAdd(repoPath, opts.name);
27
+ });
28
+ cmd
29
+ .command('remove <pathOrName>')
30
+ .description('Unregister a sibling repo by path or name')
31
+ .action(async (pathOrName) => {
32
+ await runRemove(pathOrName);
33
+ });
34
+ cmd
35
+ .command('list')
36
+ .description('List registered sibling repos')
37
+ .action(async () => {
38
+ await runList();
39
+ });
40
+ }
41
+ async function runList() {
42
+ setupLogLevel();
43
+ maybeCompactBanner();
44
+ const rootPath = getRootPath();
45
+ const format = getFormat();
46
+ try {
47
+ const w = await loadWorkspace(rootPath);
48
+ if (format === 'json') {
49
+ console.log(JSON.stringify({ workspace: w }, null, 2));
50
+ return;
51
+ }
52
+ printList(w);
53
+ }
54
+ catch (error) {
55
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
56
+ process.exit(1);
57
+ }
58
+ }
59
+ async function runAdd(repoPath, name) {
60
+ setupLogLevel();
61
+ maybeCompactBanner();
62
+ const rootPath = getRootPath();
63
+ try {
64
+ const w = await loadOrCreateWorkspace(rootPath);
65
+ const entry = addRepo(w, repoPath, name);
66
+ await saveWorkspace(rootPath, w);
67
+ console.log(chalk.green(`✓ Registered "${entry.name}" at ${entry.path}`));
68
+ console.log(chalk.dim(` ${w.repos.length} repo${w.repos.length === 1 ? '' : 's'} in workspace.`));
69
+ }
70
+ catch (error) {
71
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
72
+ process.exit(1);
73
+ }
74
+ }
75
+ async function runRemove(pathOrName) {
76
+ setupLogLevel();
77
+ maybeCompactBanner();
78
+ const rootPath = getRootPath();
79
+ try {
80
+ const w = await loadWorkspace(rootPath);
81
+ if (!w) {
82
+ console.log(chalk.dim('No workspace registered yet.'));
83
+ return;
84
+ }
85
+ const removed = removeRepo(w, pathOrName);
86
+ if (!removed) {
87
+ console.log(chalk.dim(`No repo matching "${pathOrName}" — nothing to remove.`));
88
+ return;
89
+ }
90
+ await saveWorkspace(rootPath, w);
91
+ console.log(chalk.green(`✓ Unregistered "${removed.name}" (${removed.path})`));
92
+ console.log(chalk.dim(` ${w.repos.length} repo${w.repos.length === 1 ? '' : 's'} remaining.`));
93
+ }
94
+ catch (error) {
95
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
96
+ process.exit(1);
97
+ }
98
+ }
99
+ function printList(w) {
100
+ console.log('');
101
+ console.log(chalk.bold('Cross-repo workspace'));
102
+ console.log(chalk.dim('────────────────────────────────────────'));
103
+ if (!w || w.repos.length === 0) {
104
+ console.log(chalk.dim(' No sibling repos registered yet.'));
105
+ console.log('');
106
+ console.log(chalk.dim(' Tip: run `projscan workspace add <path>` to register a sibling repo.'));
107
+ return;
108
+ }
109
+ for (const r of w.repos) {
110
+ console.log(` ${chalk.cyan('◆')} ${chalk.bold(r.name)} ${chalk.dim(r.path)}`);
111
+ }
112
+ console.log('');
113
+ console.log(chalk.dim(` ${w.repos.length} repo${w.repos.length === 1 ? '' : 's'} registered. Use cross-repo tools: projscan_workspace_graph, projscan impact --cross-repo.`));
114
+ }
115
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../src/cli/commands/workspace.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -26,6 +26,12 @@ import { registerSearch } from './commands/search.js';
26
26
  import { registerCoverage } from './commands/coverage.js';
27
27
  import { registerMcp } from './commands/mcp.js';
28
28
  import { registerSession } from './commands/session.js';
29
+ import { registerMemory } from './commands/memory.js';
30
+ import { registerWorkspace } from './commands/workspace.js';
31
+ import { registerApplyFix } from './commands/applyFix.js';
32
+ import { registerInit } from './commands/init.js';
33
+ import { registerInstallHook } from './commands/installHook.js';
34
+ import { registerTaint } from './commands/taint.js';
29
35
  import { registerBadge } from './commands/badge.js';
30
36
  import { registerHelp } from './commands/help.js';
31
37
  registerAnalyze();
@@ -54,6 +60,12 @@ registerSearch();
54
60
  registerCoverage();
55
61
  registerMcp();
56
62
  registerSession();
63
+ registerMemory();
64
+ registerWorkspace();
65
+ registerApplyFix();
66
+ registerInit();
67
+ registerInstallHook();
68
+ registerTaint();
57
69
  registerBadge();
58
70
  registerHelp();
59
71
  program.parse();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,eAAe,EAAE,CAAC;AAClB,cAAc,EAAE,CAAC;AACjB,UAAU,EAAE,CAAC;AACb,YAAY,EAAE,CAAC;AACf,WAAW,EAAE,CAAC;AACd,YAAY,EAAE,CAAC;AACf,eAAe,EAAE,CAAC;AAClB,eAAe,EAAE,CAAC;AAClB,iBAAiB,EAAE,CAAC;AACpB,oBAAoB,EAAE,CAAC;AACvB,gBAAgB,EAAE,CAAC;AACnB,gBAAgB,EAAE,CAAC;AACnB,cAAc,EAAE,CAAC;AACjB,cAAc,EAAE,CAAC;AACjB,kBAAkB,EAAE,CAAC;AACrB,oBAAoB,EAAE,CAAC;AACvB,cAAc,EAAE,CAAC;AACjB,aAAa,EAAE,CAAC;AAChB,kBAAkB,EAAE,CAAC;AACrB,gBAAgB,EAAE,CAAC;AACnB,aAAa,EAAE,CAAC;AAChB,eAAe,EAAE,CAAC;AAClB,cAAc,EAAE,CAAC;AACjB,gBAAgB,EAAE,CAAC;AACnB,WAAW,EAAE,CAAC;AACd,eAAe,EAAE,CAAC;AAClB,aAAa,EAAE,CAAC;AAChB,YAAY,EAAE,CAAC;AAEf,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ export type ApplyOp = 'create' | 'modify' | 'delete';
2
+ export interface ApplyChange {
3
+ /** Repo-relative target path (POSIX-separator). */
4
+ path: string;
5
+ op: ApplyOp;
6
+ /** SHA-256 of file content before the change. null when op='create'. */
7
+ beforeHash: string | null;
8
+ /** SHA-256 of file content after the change. null when op='delete'. */
9
+ afterHash: string | null;
10
+ /**
11
+ * Snapshot of the before-content. Stored in the rollback record so
12
+ * the original can be restored even after the file has been further
13
+ * edited. null when op='create'.
14
+ */
15
+ beforeContent?: string | null;
16
+ }
17
+ export interface ApplyResult {
18
+ ok: boolean;
19
+ /** Set when ok=false. */
20
+ reason?: string;
21
+ /** Whether disk was actually written. False for dry runs. */
22
+ applied: boolean;
23
+ /** Rollback id (uuid). Present only when applied=true. */
24
+ rollbackId?: string;
25
+ changes: ApplyChange[];
26
+ }
27
+ /** A planned mutation: one or more file edits the template proposes. */
28
+ export interface ApplyPlan {
29
+ changes: Array<{
30
+ path: string;
31
+ op: ApplyOp;
32
+ /** New content. Required for 'create' / 'modify'; ignored for 'delete'. */
33
+ content?: string;
34
+ }>;
35
+ /** Human-readable summary, surfaced in dry-run + confirmation UX. */
36
+ summary: string;
37
+ }
38
+ export interface ApplyOptions {
39
+ /** When true, never write to disk; return the would-be ApplyResult. */
40
+ dryRun?: boolean;
41
+ }
42
+ /**
43
+ * Execute an ApplyPlan against `rootPath`. Validates each path, hashes
44
+ * before+after, performs atomic writes (tmp + rename), and records a
45
+ * rollback file when applied=true.
46
+ */
47
+ export declare function executePlan(rootPath: string, plan: ApplyPlan, options?: ApplyOptions): Promise<ApplyResult>;
48
+ /**
49
+ * Reverse a previously-applied ApplyResult. Reads the rollback record,
50
+ * restores each file's beforeContent (or deletes the file if op='create').
51
+ */
52
+ export declare function rollback(rootPath: string, rollbackId: string): Promise<ApplyResult>;