projscan 2.2.0 → 2.9.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.
- package/README.md +59 -21
- package/dist/cli/commands/agentBrief.d.ts +1 -0
- package/dist/cli/commands/agentBrief.js +68 -0
- package/dist/cli/commands/agentBrief.js.map +1 -0
- package/dist/cli/commands/bugHunt.d.ts +1 -0
- package/dist/cli/commands/bugHunt.js +59 -0
- package/dist/cli/commands/bugHunt.js.map +1 -0
- package/dist/cli/commands/evidencePack.d.ts +1 -0
- package/dist/cli/commands/evidencePack.js +70 -0
- package/dist/cli/commands/evidencePack.js.map +1 -0
- package/dist/cli/commands/init.js +46 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/preflight.js +16 -0
- package/dist/cli/commands/preflight.js.map +1 -1
- package/dist/cli/commands/qualityScorecard.d.ts +1 -0
- package/dist/cli/commands/qualityScorecard.js +61 -0
- package/dist/cli/commands/qualityScorecard.js.map +1 -0
- package/dist/cli/commands/recipes.d.ts +2 -0
- package/dist/cli/commands/recipes.js +94 -0
- package/dist/cli/commands/recipes.js.map +1 -0
- package/dist/cli/commands/regressionPlan.d.ts +1 -0
- package/dist/cli/commands/regressionPlan.js +77 -0
- package/dist/cli/commands/regressionPlan.js.map +1 -0
- package/dist/cli/commands/releaseTrain.d.ts +1 -0
- package/dist/cli/commands/releaseTrain.js +58 -0
- package/dist/cli/commands/releaseTrain.js.map +1 -0
- package/dist/cli/commands/workplan.d.ts +1 -0
- package/dist/cli/commands/workplan.js +136 -0
- package/dist/cli/commands/workplan.js.map +1 -0
- package/dist/cli/index.js +17 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adoption.d.ts +57 -0
- package/dist/core/adoption.js +392 -0
- package/dist/core/adoption.js.map +1 -0
- package/dist/core/agentBrief.d.ts +6 -0
- package/dist/core/agentBrief.js +192 -0
- package/dist/core/agentBrief.js.map +1 -0
- package/dist/core/bugHunt.d.ts +6 -0
- package/dist/core/bugHunt.js +278 -0
- package/dist/core/bugHunt.js.map +1 -0
- package/dist/core/qualityScorecard.d.ts +6 -0
- package/dist/core/qualityScorecard.js +220 -0
- package/dist/core/qualityScorecard.js.map +1 -0
- package/dist/core/regressionPlan.d.ts +7 -0
- package/dist/core/regressionPlan.js +226 -0
- package/dist/core/regressionPlan.js.map +1 -0
- package/dist/core/releaseEvidence.d.ts +7 -0
- package/dist/core/releaseEvidence.js +174 -0
- package/dist/core/releaseEvidence.js.map +1 -0
- package/dist/core/releaseTrain.d.ts +5 -0
- package/dist/core/releaseTrain.js +348 -0
- package/dist/core/releaseTrain.js.map +1 -0
- package/dist/core/workplan.d.ts +12 -0
- package/dist/core/workplan.js +440 -0
- package/dist/core/workplan.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/tools/adoption.d.ts +2 -0
- package/dist/mcp/tools/adoption.js +35 -0
- package/dist/mcp/tools/adoption.js.map +1 -0
- package/dist/mcp/tools/agentBrief.d.ts +2 -0
- package/dist/mcp/tools/agentBrief.js +39 -0
- package/dist/mcp/tools/agentBrief.js.map +1 -0
- package/dist/mcp/tools/bugHunt.d.ts +2 -0
- package/dist/mcp/tools/bugHunt.js +31 -0
- package/dist/mcp/tools/bugHunt.js.map +1 -0
- package/dist/mcp/tools/evidencePack.d.ts +2 -0
- package/dist/mcp/tools/evidencePack.js +39 -0
- package/dist/mcp/tools/evidencePack.js.map +1 -0
- package/dist/mcp/tools/qualityScorecard.d.ts +2 -0
- package/dist/mcp/tools/qualityScorecard.js +26 -0
- package/dist/mcp/tools/qualityScorecard.js.map +1 -0
- package/dist/mcp/tools/regressionPlan.d.ts +2 -0
- package/dist/mcp/tools/regressionPlan.js +47 -0
- package/dist/mcp/tools/regressionPlan.js.map +1 -0
- package/dist/mcp/tools/releaseTrain.d.ts +2 -0
- package/dist/mcp/tools/releaseTrain.js +27 -0
- package/dist/mcp/tools/releaseTrain.js.map +1 -0
- package/dist/mcp/tools/workplan.d.ts +2 -0
- package/dist/mcp/tools/workplan.js +70 -0
- package/dist/mcp/tools/workplan.js.map +1 -0
- package/dist/mcp/tools.js +16 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/reporters/consoleReporter.js +4 -0
- package/dist/reporters/consoleReporter.js.map +1 -1
- package/dist/tool-manifest.json +222 -3
- package/dist/types.d.ts +240 -0
- package/dist/utils/formatSupport.d.ts +11 -0
- package/dist/utils/formatSupport.js +11 -0
- package/dist/utils/formatSupport.js.map +1 -1
- package/docs/PLUGIN-AUTHORING.md +4 -0
- package/docs/PLUGIN-GALLERY.md +61 -0
- package/docs/examples/plugins/release-readiness.mjs +26 -0
- package/docs/examples/plugins/release-readiness.projscan-plugin.json +8 -0
- package/docs/examples/plugins/security-radar.mjs +50 -0
- package/docs/examples/plugins/security-radar.projscan-plugin.json +8 -0
- package/package.json +5 -4
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { PLUGIN_PREVIEW_FLAG, discoverPluginManifests } from './plugins.js';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export const MCP_CLIENT_IDS = [
|
|
8
|
+
'all',
|
|
9
|
+
'claude-desktop',
|
|
10
|
+
'claude-code',
|
|
11
|
+
'cursor',
|
|
12
|
+
'codex',
|
|
13
|
+
'continue',
|
|
14
|
+
'windsurf',
|
|
15
|
+
'cline',
|
|
16
|
+
'zed',
|
|
17
|
+
'gemini',
|
|
18
|
+
];
|
|
19
|
+
const INSTALL = {
|
|
20
|
+
command: 'npm install -g projscan',
|
|
21
|
+
runWithoutInstall: 'npx projscan',
|
|
22
|
+
mcpServerCommand: 'npx -y projscan mcp',
|
|
23
|
+
};
|
|
24
|
+
const SERVER = {
|
|
25
|
+
command: 'npx',
|
|
26
|
+
args: ['-y', 'projscan', 'mcp'],
|
|
27
|
+
};
|
|
28
|
+
const CLIENTS = {
|
|
29
|
+
'claude-desktop': {
|
|
30
|
+
client: 'claude-desktop',
|
|
31
|
+
displayName: 'Claude Desktop',
|
|
32
|
+
whereToPaste: 'Claude Desktop MCP settings JSON.',
|
|
33
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
34
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
35
|
+
notes: ['Restart Claude Desktop after saving the config.'],
|
|
36
|
+
},
|
|
37
|
+
'claude-code': {
|
|
38
|
+
client: 'claude-code',
|
|
39
|
+
displayName: 'Claude Code',
|
|
40
|
+
whereToPaste: 'Claude Code MCP server settings.',
|
|
41
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
42
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
43
|
+
notes: ['Keep projscan as a stdio server so code never leaves the repo.'],
|
|
44
|
+
},
|
|
45
|
+
cursor: {
|
|
46
|
+
client: 'cursor',
|
|
47
|
+
displayName: 'Cursor',
|
|
48
|
+
whereToPaste: 'Cursor MCP settings, usually `.cursor/mcp.json` or Settings > MCP.',
|
|
49
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
50
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
51
|
+
notes: ['Open a repo before invoking projscan tools so the server starts in the project root.'],
|
|
52
|
+
},
|
|
53
|
+
codex: {
|
|
54
|
+
client: 'codex',
|
|
55
|
+
displayName: 'Codex CLI',
|
|
56
|
+
whereToPaste: 'Codex MCP server configuration.',
|
|
57
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
58
|
+
configText: [
|
|
59
|
+
'[mcp_servers.projscan]',
|
|
60
|
+
'command = "npx"',
|
|
61
|
+
'args = ["-y", "projscan", "mcp"]',
|
|
62
|
+
].join('\n'),
|
|
63
|
+
notes: ['Use this as a local stdio MCP server config; no projscan API key is required.'],
|
|
64
|
+
},
|
|
65
|
+
continue: {
|
|
66
|
+
client: 'continue',
|
|
67
|
+
displayName: 'Continue',
|
|
68
|
+
whereToPaste: 'Continue MCP server config.',
|
|
69
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
70
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
71
|
+
notes: ['Use alongside Continue context providers when agents need structured repo evidence.'],
|
|
72
|
+
},
|
|
73
|
+
windsurf: {
|
|
74
|
+
client: 'windsurf',
|
|
75
|
+
displayName: 'Windsurf',
|
|
76
|
+
whereToPaste: 'Windsurf MCP settings.',
|
|
77
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
78
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
79
|
+
notes: ['Run `projscan first-run` in the target repo if tools fail to start.'],
|
|
80
|
+
},
|
|
81
|
+
cline: {
|
|
82
|
+
client: 'cline',
|
|
83
|
+
displayName: 'Cline',
|
|
84
|
+
whereToPaste: 'Cline MCP settings JSON.',
|
|
85
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
86
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
87
|
+
notes: ['Keep the command as `npx` so Cline can launch the published server directly.'],
|
|
88
|
+
},
|
|
89
|
+
zed: {
|
|
90
|
+
client: 'zed',
|
|
91
|
+
displayName: 'Zed',
|
|
92
|
+
whereToPaste: 'Zed assistant MCP/context server settings.',
|
|
93
|
+
config: { context_servers: { projscan: SERVER } },
|
|
94
|
+
configText: JSON.stringify({ context_servers: { projscan: SERVER } }, null, 2),
|
|
95
|
+
notes: ['If your Zed build expects `mcpServers`, use the generic MCP JSON from `--client all`.'],
|
|
96
|
+
},
|
|
97
|
+
gemini: {
|
|
98
|
+
client: 'gemini',
|
|
99
|
+
displayName: 'Gemini CLI',
|
|
100
|
+
whereToPaste: 'Gemini CLI MCP settings.',
|
|
101
|
+
config: { mcpServers: { projscan: SERVER } },
|
|
102
|
+
configText: JSON.stringify({ mcpServers: { projscan: SERVER } }, null, 2),
|
|
103
|
+
notes: ['Use `npx -y projscan mcp` as the stdio server command.'],
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
export function isMcpClientId(value) {
|
|
107
|
+
return typeof value === 'string' && MCP_CLIENT_IDS.includes(value);
|
|
108
|
+
}
|
|
109
|
+
export function getMcpConfigGuide(client = 'all') {
|
|
110
|
+
if (client === 'all') {
|
|
111
|
+
return {
|
|
112
|
+
schemaVersion: 1,
|
|
113
|
+
client: 'all',
|
|
114
|
+
install: INSTALL,
|
|
115
|
+
configs: MCP_CLIENT_IDS.filter((id) => id !== 'all').map((id) => buildGuide(id)),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return buildGuide(client);
|
|
119
|
+
}
|
|
120
|
+
export function getWorkflowRecipes() {
|
|
121
|
+
return {
|
|
122
|
+
schemaVersion: 1,
|
|
123
|
+
recipes: [
|
|
124
|
+
{
|
|
125
|
+
id: 'before_edit',
|
|
126
|
+
name: 'Before Edit',
|
|
127
|
+
useWhen: 'Start here before an agent changes code.',
|
|
128
|
+
outcome: 'A proceed/caution/block gate plus the next tool calls that explain any risk.',
|
|
129
|
+
commands: [
|
|
130
|
+
'projscan preflight --mode before_edit --format json',
|
|
131
|
+
'projscan workplan --mode before_edit --format json',
|
|
132
|
+
],
|
|
133
|
+
mcpTools: ['projscan_preflight', 'projscan_workplan'],
|
|
134
|
+
handoff: 'If preflight returns caution or block, follow suggestedNextActions before editing.',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: 'bug_hunt',
|
|
138
|
+
name: 'Bug Hunt',
|
|
139
|
+
useWhen: 'Run a focused polish or stabilization pass.',
|
|
140
|
+
outcome: 'A ranked fix queue with evidence and verification commands.',
|
|
141
|
+
commands: [
|
|
142
|
+
'projscan bug-hunt --format json',
|
|
143
|
+
'projscan quality-scorecard --format json',
|
|
144
|
+
'projscan regression-plan --level focused --format json',
|
|
145
|
+
],
|
|
146
|
+
mcpTools: ['projscan_bug_hunt', 'projscan_quality_scorecard', 'projscan_regression_plan'],
|
|
147
|
+
handoff: 'Fix top-ranked targets first, then rerun the regression plan.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: 'release_approval',
|
|
151
|
+
name: 'Release Approval',
|
|
152
|
+
useWhen: 'Prepare a maintainer or CI environment approval packet.',
|
|
153
|
+
outcome: 'Version readiness, risks, regression commands, and website update copy in one loop.',
|
|
154
|
+
commands: [
|
|
155
|
+
'projscan release-train --format json',
|
|
156
|
+
'projscan evidence-pack --website-prompt --format json',
|
|
157
|
+
'projscan regression-plan --level full --format json',
|
|
158
|
+
],
|
|
159
|
+
mcpTools: ['projscan_release_train', 'projscan_evidence_pack', 'projscan_regression_plan'],
|
|
160
|
+
handoff: 'Use the evidence pack as the approval artifact; do not skip the full release gate.',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'handoff',
|
|
164
|
+
name: 'Agent Handoff',
|
|
165
|
+
useWhen: 'Compress repo context for the next agent or a resumed session.',
|
|
166
|
+
outcome: 'A compact brief with focus items, guardrails, and suggested next actions.',
|
|
167
|
+
commands: [
|
|
168
|
+
'projscan agent-brief --intent handoff --format json',
|
|
169
|
+
'projscan handoff --format json',
|
|
170
|
+
],
|
|
171
|
+
mcpTools: ['projscan_agent_brief', 'projscan_workplan'],
|
|
172
|
+
handoff: 'Paste the brief into the next agent session before asking it to edit.',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: 'pre_merge',
|
|
176
|
+
name: 'Pre-Merge',
|
|
177
|
+
useWhen: 'Check a branch before merge or release tagging.',
|
|
178
|
+
outcome: 'Changed-file health, review verdict, taint flow evidence, and required checks.',
|
|
179
|
+
commands: [
|
|
180
|
+
'projscan preflight --mode before_merge --format json',
|
|
181
|
+
'projscan review --format json',
|
|
182
|
+
'projscan regression-plan --level smoke --format json',
|
|
183
|
+
],
|
|
184
|
+
mcpTools: ['projscan_preflight', 'projscan_review', 'projscan_regression_plan'],
|
|
185
|
+
handoff: 'Treat block as a hard stop and caution as a request for explicit review.',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
export async function computeFirstRunDiagnostics(rootPath) {
|
|
191
|
+
const diagnostics = [
|
|
192
|
+
checkNodeVersion(),
|
|
193
|
+
await checkPackageJson(rootPath),
|
|
194
|
+
await checkGit(rootPath),
|
|
195
|
+
await checkConfig(rootPath),
|
|
196
|
+
await checkTreeSitter(rootPath),
|
|
197
|
+
await checkPlugins(rootPath),
|
|
198
|
+
checkMcpStartup(),
|
|
199
|
+
];
|
|
200
|
+
const overall = summarizeDiagnostics(diagnostics);
|
|
201
|
+
return {
|
|
202
|
+
schemaVersion: 1,
|
|
203
|
+
rootPath,
|
|
204
|
+
overall,
|
|
205
|
+
diagnostics,
|
|
206
|
+
nextCommands: [
|
|
207
|
+
'projscan init mcp --client all',
|
|
208
|
+
'projscan recipes',
|
|
209
|
+
'projscan preflight --mode before_edit --format json',
|
|
210
|
+
'projscan doctor',
|
|
211
|
+
],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function buildGuide(client) {
|
|
215
|
+
return {
|
|
216
|
+
schemaVersion: 1,
|
|
217
|
+
install: INSTALL,
|
|
218
|
+
...CLIENTS[client],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function checkNodeVersion() {
|
|
222
|
+
const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10);
|
|
223
|
+
if (Number.isFinite(major) && major >= 18) {
|
|
224
|
+
return {
|
|
225
|
+
id: 'node',
|
|
226
|
+
label: 'Node.js',
|
|
227
|
+
status: 'pass',
|
|
228
|
+
summary: `Node ${process.versions.node} satisfies projscan's >=18 requirement.`,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
id: 'node',
|
|
233
|
+
label: 'Node.js',
|
|
234
|
+
status: 'fail',
|
|
235
|
+
summary: `Node ${process.versions.node} is below projscan's >=18 requirement.`,
|
|
236
|
+
command: 'node --version',
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
async function checkPackageJson(rootPath) {
|
|
240
|
+
const file = path.join(rootPath, 'package.json');
|
|
241
|
+
try {
|
|
242
|
+
const raw = await fs.readFile(file, 'utf-8');
|
|
243
|
+
const parsed = JSON.parse(raw);
|
|
244
|
+
const name = typeof parsed.name === 'string' ? parsed.name : path.basename(rootPath);
|
|
245
|
+
const scripts = parsed.scripts && typeof parsed.scripts === 'object' ? Object.keys(parsed.scripts).length : 0;
|
|
246
|
+
return {
|
|
247
|
+
id: 'package-json',
|
|
248
|
+
label: 'Package metadata',
|
|
249
|
+
status: 'pass',
|
|
250
|
+
summary: `Found package.json for ${name}.`,
|
|
251
|
+
detail: scripts > 0 ? `${scripts} npm script(s) detected for release/test recipes.` : 'No npm scripts detected.',
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
return {
|
|
256
|
+
id: 'package-json',
|
|
257
|
+
label: 'Package metadata',
|
|
258
|
+
status: 'warn',
|
|
259
|
+
summary: 'No readable package.json found; Node dependency and script checks will be limited.',
|
|
260
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function checkGit(rootPath) {
|
|
265
|
+
try {
|
|
266
|
+
const inside = await git(rootPath, ['rev-parse', '--is-inside-work-tree']);
|
|
267
|
+
if (inside.stdout.trim() !== 'true') {
|
|
268
|
+
return {
|
|
269
|
+
id: 'git',
|
|
270
|
+
label: 'Git',
|
|
271
|
+
status: 'warn',
|
|
272
|
+
summary: 'This directory is not inside a Git worktree.',
|
|
273
|
+
detail: 'Review, changed-file, and pre-merge recipes need Git history.',
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const status = await git(rootPath, ['status', '--short']);
|
|
277
|
+
const remote = await git(rootPath, ['remote']);
|
|
278
|
+
const dirty = status.stdout.trim().length > 0;
|
|
279
|
+
return {
|
|
280
|
+
id: 'git',
|
|
281
|
+
label: 'Git',
|
|
282
|
+
status: dirty ? 'warn' : 'pass',
|
|
283
|
+
summary: dirty ? 'Git worktree has local changes.' : 'Git worktree detected and clean.',
|
|
284
|
+
detail: remote.stdout.trim().length > 0 ? `Remotes: ${remote.stdout.trim().split(/\s+/).join(', ')}` : 'No git remote configured.',
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
return {
|
|
289
|
+
id: 'git',
|
|
290
|
+
label: 'Git',
|
|
291
|
+
status: 'warn',
|
|
292
|
+
summary: 'Git metadata is unavailable.',
|
|
293
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
294
|
+
command: 'git status --short',
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
async function checkConfig(rootPath) {
|
|
299
|
+
try {
|
|
300
|
+
await fs.access(path.join(rootPath, '.projscanrc.json'));
|
|
301
|
+
return {
|
|
302
|
+
id: 'projscan-config',
|
|
303
|
+
label: 'projscan config',
|
|
304
|
+
status: 'pass',
|
|
305
|
+
summary: 'Found .projscanrc.json.',
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
return {
|
|
310
|
+
id: 'projscan-config',
|
|
311
|
+
label: 'projscan config',
|
|
312
|
+
status: 'info',
|
|
313
|
+
summary: 'No .projscanrc.json yet; defaults are fine for first use.',
|
|
314
|
+
command: 'projscan init',
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function checkTreeSitter(rootPath) {
|
|
319
|
+
const candidates = [
|
|
320
|
+
path.join(rootPath, 'node_modules', 'web-tree-sitter', 'tree-sitter.wasm'),
|
|
321
|
+
path.join(rootPath, 'dist', 'grammars', 'web-tree-sitter.wasm'),
|
|
322
|
+
];
|
|
323
|
+
for (const candidate of candidates) {
|
|
324
|
+
try {
|
|
325
|
+
await fs.access(candidate);
|
|
326
|
+
return {
|
|
327
|
+
id: 'tree-sitter',
|
|
328
|
+
label: 'Tree-sitter runtime',
|
|
329
|
+
status: 'pass',
|
|
330
|
+
summary: 'Tree-sitter WASM runtime is present.',
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// try next
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
id: 'tree-sitter',
|
|
339
|
+
label: 'Tree-sitter runtime',
|
|
340
|
+
status: 'info',
|
|
341
|
+
summary: 'Tree-sitter runtime was not found in this project checkout.',
|
|
342
|
+
detail: 'This is normal when using npx; projscan ships its runtime with the package.',
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
async function checkPlugins(rootPath) {
|
|
346
|
+
const entries = await discoverPluginManifests(rootPath);
|
|
347
|
+
if (entries.length === 0) {
|
|
348
|
+
return {
|
|
349
|
+
id: 'plugins',
|
|
350
|
+
label: 'Local plugins',
|
|
351
|
+
status: 'info',
|
|
352
|
+
summary: 'No local plugin manifests found.',
|
|
353
|
+
detail: `Set ${PLUGIN_PREVIEW_FLAG}=1 only when you want projscan to execute trusted local plugins.`,
|
|
354
|
+
command: 'projscan plugin init --kind analyzer --name policy',
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
const broken = entries.filter((entry) => entry.manifest === null);
|
|
358
|
+
return {
|
|
359
|
+
id: 'plugins',
|
|
360
|
+
label: 'Local plugins',
|
|
361
|
+
status: broken.length > 0 ? 'warn' : 'pass',
|
|
362
|
+
summary: broken.length > 0
|
|
363
|
+
? `${broken.length} of ${entries.length} plugin manifest(s) need attention.`
|
|
364
|
+
: `${entries.length} plugin manifest(s) validate.`,
|
|
365
|
+
command: 'projscan plugin list',
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
function checkMcpStartup() {
|
|
369
|
+
return {
|
|
370
|
+
id: 'mcp-startup',
|
|
371
|
+
label: 'MCP startup',
|
|
372
|
+
status: 'pass',
|
|
373
|
+
summary: 'Use stdio startup for every MCP client.',
|
|
374
|
+
detail: INSTALL.mcpServerCommand,
|
|
375
|
+
command: 'npx -y projscan mcp',
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function summarizeDiagnostics(diagnostics) {
|
|
379
|
+
if (diagnostics.some((diagnostic) => diagnostic.status === 'fail'))
|
|
380
|
+
return 'fail';
|
|
381
|
+
if (diagnostics.some((diagnostic) => diagnostic.status === 'warn'))
|
|
382
|
+
return 'warn';
|
|
383
|
+
return 'pass';
|
|
384
|
+
}
|
|
385
|
+
async function git(rootPath, args) {
|
|
386
|
+
return execFileAsync('git', args, {
|
|
387
|
+
cwd: rootPath,
|
|
388
|
+
timeout: 5000,
|
|
389
|
+
maxBuffer: 1024 * 1024,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=adoption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adoption.js","sourceRoot":"","sources":["../../src/core/adoption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentBriefIntent, AgentBriefReport } from '../types.js';
|
|
2
|
+
export interface ComputeAgentBriefOptions {
|
|
3
|
+
intent?: AgentBriefIntent;
|
|
4
|
+
maxItems?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function computeAgentBrief(rootPath: string, options?: ComputeAgentBriefOptions): Promise<AgentBriefReport>;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { analyzeHotspots } from './hotspotAnalyzer.js';
|
|
2
|
+
import { collectIssues } from './issueEngine.js';
|
|
3
|
+
import { scanRepository } from './repositoryScanner.js';
|
|
4
|
+
import { buildRiskNow } from './sessionResources.js';
|
|
5
|
+
import { applyConfigToIssues, loadConfig } from '../utils/config.js';
|
|
6
|
+
import { calculateScore } from '../utils/scoreCalculator.js';
|
|
7
|
+
const DEFAULT_MAX_ITEMS = 6;
|
|
8
|
+
export async function computeAgentBrief(rootPath, options = {}) {
|
|
9
|
+
const intent = normalizeIntent(options.intent);
|
|
10
|
+
const maxItems = normalizeMax(options.maxItems);
|
|
11
|
+
const configResult = await loadConfig(rootPath).catch(() => ({ config: { ignore: [] } }));
|
|
12
|
+
const scan = await scanRepository(rootPath, { ignore: configResult.config.ignore });
|
|
13
|
+
const issues = applyConfigToIssues(await collectIssues(rootPath, scan.files), configResult.config);
|
|
14
|
+
const health = calculateScore(issues);
|
|
15
|
+
const [riskNow, hotspots] = await Promise.all([
|
|
16
|
+
safeRiskNow(rootPath),
|
|
17
|
+
safeHotspots(rootPath, scan.files, issues, maxItems),
|
|
18
|
+
]);
|
|
19
|
+
const allFocus = rankFocus([
|
|
20
|
+
...issues.slice(0, maxItems * 2).map(issueToFocus),
|
|
21
|
+
...riskNow.conflicts.map(conflictToFocus),
|
|
22
|
+
...(hotspots.available ? hotspots.hotspots.map(hotspotToFocus) : []),
|
|
23
|
+
]);
|
|
24
|
+
const focus = allFocus.length > 0 ? allFocus.slice(0, maxItems) : [baselineFocus(intent)];
|
|
25
|
+
const guardrails = buildGuardrails(intent);
|
|
26
|
+
return {
|
|
27
|
+
schemaVersion: 1,
|
|
28
|
+
intent,
|
|
29
|
+
summary: summarize(intent, focus, health),
|
|
30
|
+
health,
|
|
31
|
+
context: {
|
|
32
|
+
totalFiles: scan.totalFiles,
|
|
33
|
+
totalDirectories: scan.totalDirectories,
|
|
34
|
+
topDirectories: topDirectories(scan.files),
|
|
35
|
+
touchedFiles: riskNow.touchedFiles.slice(0, 12),
|
|
36
|
+
conflicts: riskNow.conflicts.length,
|
|
37
|
+
},
|
|
38
|
+
focus,
|
|
39
|
+
guardrails,
|
|
40
|
+
suggestedNextActions: suggestedActions(focus, guardrails),
|
|
41
|
+
...(allFocus.length > focus.length || riskNow.touchedFiles.length > 12 ? { truncated: true } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async function safeRiskNow(rootPath) {
|
|
45
|
+
try {
|
|
46
|
+
return await buildRiskNow(rootPath);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return { touchedFiles: [], conflicts: [] };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function safeHotspots(rootPath, files, issues, limit) {
|
|
53
|
+
try {
|
|
54
|
+
return await analyzeHotspots(rootPath, files, issues, { limit });
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
return {
|
|
58
|
+
available: false,
|
|
59
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
60
|
+
window: { since: null, commitsScanned: 0 },
|
|
61
|
+
hotspots: [],
|
|
62
|
+
totalFilesRanked: 0,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function issueToFocus(issue) {
|
|
67
|
+
const files = issueFiles(issue);
|
|
68
|
+
return {
|
|
69
|
+
id: `ab-issue-${issue.id}`,
|
|
70
|
+
priority: severityPriority(issue.severity),
|
|
71
|
+
title: issue.title,
|
|
72
|
+
why: issue.description,
|
|
73
|
+
files,
|
|
74
|
+
commands: ['projscan doctor --format json', `projscan explain-issue ${issue.id} --format json`],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function conflictToFocus(conflict, index) {
|
|
78
|
+
return {
|
|
79
|
+
id: `ab-conflict-${index + 1}`,
|
|
80
|
+
priority: conflict.severity === 'error' ? 'p0' : 'p1',
|
|
81
|
+
title: 'Resolve coordination conflict',
|
|
82
|
+
why: conflict.message,
|
|
83
|
+
files: conflict.files,
|
|
84
|
+
commands: ['projscan session touched --format json', 'projscan agent-brief --format json'],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function hotspotToFocus(hotspot) {
|
|
88
|
+
return {
|
|
89
|
+
id: `ab-hotspot-${slug(hotspot.relativePath)}`,
|
|
90
|
+
priority: hotspot.riskScore >= 70 ? 'p0' : hotspot.riskScore >= 30 ? 'p1' : 'p2',
|
|
91
|
+
title: `Inspect hotspot ${hotspot.relativePath}`,
|
|
92
|
+
why: hotspot.reasons[0] ?? `Risk score ${Math.round(hotspot.riskScore)}`,
|
|
93
|
+
files: [hotspot.relativePath],
|
|
94
|
+
commands: [`projscan file ${hotspot.relativePath} --format json`, 'projscan hotspots --format json'],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function baselineFocus(intent) {
|
|
98
|
+
return {
|
|
99
|
+
id: 'ab-baseline',
|
|
100
|
+
priority: 'p2',
|
|
101
|
+
title: 'Keep the clean baseline reproducible',
|
|
102
|
+
why: `No immediate focus targets were found for ${intent}. Preserve the baseline with repeatable checks before handoff.`,
|
|
103
|
+
files: [],
|
|
104
|
+
commands: ['projscan doctor --format json', 'projscan preflight --mode before_edit --format json'],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function buildGuardrails(intent) {
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
id: 'ab-guardrail-health',
|
|
111
|
+
label: 'Health check',
|
|
112
|
+
reason: 'Start with the fastest repo-wide signal before editing.',
|
|
113
|
+
command: 'projscan doctor --format json',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'ab-guardrail-preflight',
|
|
117
|
+
label: 'Preflight check',
|
|
118
|
+
reason: 'Confirm the current session is safe for the selected intent.',
|
|
119
|
+
command: intent === 'release'
|
|
120
|
+
? 'projscan preflight --mode before_merge --format json'
|
|
121
|
+
: 'projscan preflight --mode before_edit --format json',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'ab-guardrail-tests',
|
|
125
|
+
label: 'Regression check',
|
|
126
|
+
reason: 'Keep the brief tied to repeatable verification.',
|
|
127
|
+
command: intent === 'release' ? 'projscan regression-plan --level focused --format json' : 'npm test',
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
function rankFocus(items) {
|
|
132
|
+
const seen = new Set();
|
|
133
|
+
return items
|
|
134
|
+
.filter((item) => {
|
|
135
|
+
if (seen.has(item.id))
|
|
136
|
+
return false;
|
|
137
|
+
seen.add(item.id);
|
|
138
|
+
return true;
|
|
139
|
+
})
|
|
140
|
+
.sort((a, b) => priorityRank(a.priority) - priorityRank(b.priority) || a.id.localeCompare(b.id));
|
|
141
|
+
}
|
|
142
|
+
function suggestedActions(focus, guardrails) {
|
|
143
|
+
return [
|
|
144
|
+
...focus.slice(0, 5).map((item) => ({ label: item.title, command: item.commands[0] })),
|
|
145
|
+
...guardrails.map((guardrail) => ({ label: guardrail.label, command: guardrail.command })),
|
|
146
|
+
].slice(0, 10);
|
|
147
|
+
}
|
|
148
|
+
function summarize(intent, focus, health) {
|
|
149
|
+
return `agent brief: ${intent} has ${focus.length} focus item(s), health ${health.grade} (${health.score})`;
|
|
150
|
+
}
|
|
151
|
+
function topDirectories(files) {
|
|
152
|
+
const counts = new Map();
|
|
153
|
+
for (const file of files) {
|
|
154
|
+
const dir = file.directory || '.';
|
|
155
|
+
counts.set(dir, (counts.get(dir) ?? 0) + 1);
|
|
156
|
+
}
|
|
157
|
+
return [...counts.entries()]
|
|
158
|
+
.map(([directory, count]) => ({ directory, files: count }))
|
|
159
|
+
.sort((a, b) => b.files - a.files || a.directory.localeCompare(b.directory))
|
|
160
|
+
.slice(0, 8);
|
|
161
|
+
}
|
|
162
|
+
function issueFiles(issue) {
|
|
163
|
+
return [...new Set((issue.locations ?? []).map((location) => location.file).filter(Boolean))];
|
|
164
|
+
}
|
|
165
|
+
function normalizeIntent(value) {
|
|
166
|
+
if (value === 'bug_hunt' || value === 'release' || value === 'refactor' || value === 'hardening')
|
|
167
|
+
return value;
|
|
168
|
+
return 'next_agent';
|
|
169
|
+
}
|
|
170
|
+
function normalizeMax(value) {
|
|
171
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
172
|
+
return DEFAULT_MAX_ITEMS;
|
|
173
|
+
return Math.max(1, Math.min(20, Math.floor(value)));
|
|
174
|
+
}
|
|
175
|
+
function severityPriority(severity) {
|
|
176
|
+
if (severity === 'error')
|
|
177
|
+
return 'p0';
|
|
178
|
+
if (severity === 'warning')
|
|
179
|
+
return 'p1';
|
|
180
|
+
return 'p2';
|
|
181
|
+
}
|
|
182
|
+
function priorityRank(priority) {
|
|
183
|
+
if (priority === 'p0')
|
|
184
|
+
return 0;
|
|
185
|
+
if (priority === 'p1')
|
|
186
|
+
return 1;
|
|
187
|
+
return 2;
|
|
188
|
+
}
|
|
189
|
+
function slug(value) {
|
|
190
|
+
return value.replace(/[^a-zA-Z0-9]+/g, '-').replace(/^-+|-+$/g, '').toLowerCase() || 'root';
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=agentBrief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentBrief.js","sourceRoot":"","sources":["../../src/core/agentBrief.ts"],"names":[],"mappings":"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"}
|