projscan 4.15.0 → 4.16.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 +34 -2
- package/dist/cli/commands/assess.js +36 -2
- package/dist/cli/commands/assess.js.map +1 -1
- package/dist/core/baseframeAssessment.d.ts +9 -0
- package/dist/core/baseframeAssessment.js +471 -0
- package/dist/core/baseframeAssessment.js.map +1 -0
- package/dist/projscan-sbom.cdx.json +6 -6
- package/dist/publicCore.d.ts +1 -0
- package/dist/publicCore.js +1 -0
- package/dist/publicCore.js.map +1 -1
- package/dist/tool-manifest.json +2 -2
- package/dist/types/baseframe.d.ts +75 -0
- package/dist/types/baseframe.js +2 -0
- package/dist/types/baseframe.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/docs/integrations/baseframe-suite-v1.md +163 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -164,6 +164,25 @@ Use the risk delta simulator before a refactor or extraction. It predicts likely
|
|
|
164
164
|
|
|
165
165
|
Success criteria: the team sees the one or two highest-value fixes, why they matter, how to prove them, and whether ship-readiness still needs caution or review.
|
|
166
166
|
|
|
167
|
+
### Baseframe Suite assessment artifact
|
|
168
|
+
|
|
169
|
+
ProjScan finds the risk.
|
|
170
|
+
AgentLoopKit controls the work.
|
|
171
|
+
AgentFlight proves the result.
|
|
172
|
+
|
|
173
|
+
When a Baseframe Suite task needs a stable local artifact, run:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
projscan assess \
|
|
177
|
+
--intent "Implement password reset" \
|
|
178
|
+
--task-id auth-password-reset-20260626-01 \
|
|
179
|
+
--emit-baseframe
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
ProjScan writes `.baseframe/evidence/<task-id>/projscan-assessment.json` and
|
|
183
|
+
updates `.baseframe/agent-workflow.json` without writing AgentLoopKit or
|
|
184
|
+
AgentFlight artifacts. See [Baseframe Suite Integration v1](docs/integrations/baseframe-suite-v1.md).
|
|
185
|
+
|
|
167
186
|
## Mission Control
|
|
168
187
|
|
|
169
188
|
`projscan start --intent "<goal>"` turns a plain-language goal into an execution plan:
|
|
@@ -203,6 +222,19 @@ npm run docs:screenshots
|
|
|
203
222
|
npm run docs:demos
|
|
204
223
|
```
|
|
205
224
|
|
|
225
|
+
## 4.16.0 Notes
|
|
226
|
+
|
|
227
|
+
4.16.0 ships Baseframe Suite assessment export:
|
|
228
|
+
|
|
229
|
+
- `projscan assess --intent "<task>" --task-id <id> --emit-baseframe` writes
|
|
230
|
+
`.baseframe/evidence/<task-id>/projscan-assessment.json`.
|
|
231
|
+
- ProjScan updates `.baseframe/agent-workflow.json` with its own status while
|
|
232
|
+
preserving AgentLoopKit, AgentFlight, and unknown manifest fields.
|
|
233
|
+
- The package exports `createBaseframeAssessment()` plus Baseframe v1
|
|
234
|
+
assessment and workflow manifest types.
|
|
235
|
+
- Artifact writes are local, atomic, task-ID validated, and protected against
|
|
236
|
+
traversal and symlink output paths.
|
|
237
|
+
|
|
206
238
|
## 4.15.0 Notes
|
|
207
239
|
|
|
208
240
|
4.15.0 strengthens the proof-first change loop:
|
|
@@ -572,7 +604,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
|
|
|
572
604
|
|
|
573
605
|
## Install Notes
|
|
574
606
|
|
|
575
|
-
`projscan@4.
|
|
607
|
+
`projscan@4.16.0` has seven direct runtime dependencies:
|
|
576
608
|
|
|
577
609
|
- `@babel/parser`
|
|
578
610
|
- `@babel/types`
|
|
@@ -582,7 +614,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
|
|
|
582
614
|
- `ora`
|
|
583
615
|
- `web-tree-sitter`
|
|
584
616
|
|
|
585
|
-
If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.
|
|
617
|
+
If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.16.0. Open an issue with the warning text if npm reports install scripts from `projscan@latest`, or run `projscan feedback intake --text "<warning text>" --format json` to turn it into a focused setup-trust task.
|
|
586
618
|
|
|
587
619
|
The grammar packages are build-time sources, not global-install dependencies. Published grammar assets include `tree-sitter-python.wasm` and `tree-sitter-c_sharp.wasm`.
|
|
588
620
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
4
|
import { assertFormatSupported, getRootPath, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
|
|
5
|
+
import { createBaseframeAssessment } from '../../core/baseframeAssessment.js';
|
|
4
6
|
import { computeAssess } from '../../core/assess.js';
|
|
5
7
|
const ASSESS_MODES = ['standard', 'fix-first', 'ship-readiness'];
|
|
6
8
|
export function registerAssess() {
|
|
@@ -12,11 +14,28 @@ export function registerAssess() {
|
|
|
12
14
|
.option('--max-cards <count>', 'maximum Proof Cards to return', parsePositiveInt)
|
|
13
15
|
.option('--baseline <path>', 'prior assess JSON file to compare risk delta against')
|
|
14
16
|
.option('--feedback <path>', 'local projscan feedback artifact to apply as trust memory')
|
|
17
|
+
.option('--intent <text>', 'Baseframe task intent to include in the assessment artifact')
|
|
18
|
+
.option('--task-id <id>', 'Baseframe task ID for the assessment artifact')
|
|
19
|
+
.option('--emit-baseframe', 'write the Baseframe ProjScan assessment artifact')
|
|
20
|
+
.option('--output <path>', 'explicit ProjScan-owned Baseframe assessment output path')
|
|
15
21
|
.action(async (cmdOpts) => {
|
|
16
22
|
setupLogLevel();
|
|
17
|
-
maybeCompactBanner();
|
|
18
|
-
const format = assertFormatSupported('assess');
|
|
19
23
|
try {
|
|
24
|
+
if (shouldEmitBaseframe(cmdOpts)) {
|
|
25
|
+
const root = getRootPath();
|
|
26
|
+
const intent = requireBaseframeOption(cmdOpts.intent, '--intent');
|
|
27
|
+
const taskId = requireBaseframeOption(cmdOpts.taskId, '--task-id');
|
|
28
|
+
await createBaseframeAssessment({
|
|
29
|
+
root,
|
|
30
|
+
intent,
|
|
31
|
+
taskId,
|
|
32
|
+
outputPath: cmdOpts.output,
|
|
33
|
+
});
|
|
34
|
+
console.log(baseframeAssessmentRelativePath(root, taskId, cmdOpts.output));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
maybeCompactBanner();
|
|
38
|
+
const format = assertFormatSupported('assess');
|
|
20
39
|
const report = await computeAssess(getRootPath(), {
|
|
21
40
|
goal: cmdOpts.goal,
|
|
22
41
|
mode: cmdOpts.mode,
|
|
@@ -153,6 +172,21 @@ function parsePositiveInt(value) {
|
|
|
153
172
|
}
|
|
154
173
|
return parsed;
|
|
155
174
|
}
|
|
175
|
+
function shouldEmitBaseframe(cmdOpts) {
|
|
176
|
+
return Boolean(cmdOpts.emitBaseframe || cmdOpts.output);
|
|
177
|
+
}
|
|
178
|
+
function requireBaseframeOption(value, name) {
|
|
179
|
+
const trimmed = typeof value === 'string' ? value.trim() : '';
|
|
180
|
+
if (!trimmed)
|
|
181
|
+
throw new Error(`projscan assess Baseframe export requires ${name}.`);
|
|
182
|
+
return trimmed;
|
|
183
|
+
}
|
|
184
|
+
function baseframeAssessmentRelativePath(root, taskId, outputPath) {
|
|
185
|
+
const absolutePath = outputPath
|
|
186
|
+
? path.resolve(root, outputPath)
|
|
187
|
+
: path.join(root, '.baseframe', 'evidence', taskId, 'projscan-assessment.json');
|
|
188
|
+
return path.relative(root, absolutePath).replace(/\\/g, '/');
|
|
189
|
+
}
|
|
156
190
|
async function readAssessBaseline(filePath) {
|
|
157
191
|
try {
|
|
158
192
|
const parsed = JSON.parse(await fs.readFile(filePath, 'utf-8'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assess.js","sourceRoot":"","sources":["../../../src/cli/commands/assess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,gBAAgB,CAAiC,CAAC;AAEjG,MAAM,UAAU,cAAc;IAC5B,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,eAAe,EAAE,gCAAgC,CAAC;SACzD,MAAM,CAAC,eAAe,EAAE,sDAAsD,EAAE,SAAS,CAAC;SAC1F,MAAM,CAAC,qBAAqB,EAAE,+BAA+B,EAAE,gBAAgB,CAAC;SAChF,MAAM,CAAC,mBAAmB,EAAE,sDAAsD,CAAC;SACnF,MAAM,CAAC,mBAAmB,EAAE,2DAA2D,CAAC;SACxF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"assess.js","sourceRoot":"","sources":["../../../src/cli/commands/assess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ProjScanAssessmentV1 } from '../types/baseframe.js';
|
|
2
|
+
export type { BaseframeAgentWorkflowV1, ProjScanAssessmentV1 } from '../types/baseframe.js';
|
|
3
|
+
export interface CreateBaseframeAssessmentOptions {
|
|
4
|
+
root: string;
|
|
5
|
+
taskId: string;
|
|
6
|
+
intent: string;
|
|
7
|
+
outputPath?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createBaseframeAssessment(options: CreateBaseframeAssessmentOptions): Promise<ProjScanAssessmentV1>;
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import { computeAssess } from './assess.js';
|
|
7
|
+
import { detectFrameworks } from './frameworkDetector.js';
|
|
8
|
+
import { detectLanguages } from './languageDetector.js';
|
|
9
|
+
import { scanRepository } from './repositoryScanner.js';
|
|
10
|
+
import { atomicWriteFile } from '../utils/atomicWrite.js';
|
|
11
|
+
const execFileAsync = promisify(execFile);
|
|
12
|
+
const TASK_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9_-]{0,126}[A-Za-z0-9])?$/;
|
|
13
|
+
const ASSESSMENT_FILE = 'projscan-assessment.json';
|
|
14
|
+
const BASEFRAME_DIR = '.baseframe';
|
|
15
|
+
const EVIDENCE_DIR = 'evidence';
|
|
16
|
+
let cachedProducerVersion;
|
|
17
|
+
export async function createBaseframeAssessment(options) {
|
|
18
|
+
const root = path.resolve(options.root);
|
|
19
|
+
validateTaskId(options.taskId);
|
|
20
|
+
const intent = normalizeIntent(options.intent);
|
|
21
|
+
const outputPath = resolveAssessmentOutputPath(root, options.taskId, options.outputPath);
|
|
22
|
+
const generatedAt = new Date().toISOString();
|
|
23
|
+
const version = await readProducerVersion();
|
|
24
|
+
const [signals, repository] = await Promise.all([
|
|
25
|
+
collectSignals(root, intent),
|
|
26
|
+
readRepositoryMetadata(root),
|
|
27
|
+
]);
|
|
28
|
+
const assessment = buildAssessment({
|
|
29
|
+
taskId: options.taskId,
|
|
30
|
+
intent,
|
|
31
|
+
generatedAt,
|
|
32
|
+
version,
|
|
33
|
+
repository,
|
|
34
|
+
signals,
|
|
35
|
+
});
|
|
36
|
+
await prepareAssessmentWrite(root, options.taskId, outputPath);
|
|
37
|
+
await assertWritableAssessmentOutput(outputPath, options.taskId);
|
|
38
|
+
await atomicWriteJson(outputPath, assessment);
|
|
39
|
+
await updateWorkflowManifest({
|
|
40
|
+
root,
|
|
41
|
+
taskId: options.taskId,
|
|
42
|
+
intent,
|
|
43
|
+
assessmentPath: relativeRepositoryPath(root, outputPath),
|
|
44
|
+
version,
|
|
45
|
+
updatedAt: generatedAt,
|
|
46
|
+
});
|
|
47
|
+
return assessment;
|
|
48
|
+
}
|
|
49
|
+
function buildAssessment(input) {
|
|
50
|
+
const verdict = mapVerdict(input.signals.assess);
|
|
51
|
+
const summary = summarizeAssessment(verdict, input.signals);
|
|
52
|
+
const repositoryType = describeRepositoryType(input.signals.languages, input.signals.frameworks);
|
|
53
|
+
const proofCards = input.signals.assess?.proofCards ?? [];
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: '1.0',
|
|
56
|
+
kind: 'projscan-assessment',
|
|
57
|
+
producer: {
|
|
58
|
+
name: 'projscan',
|
|
59
|
+
version: input.version,
|
|
60
|
+
},
|
|
61
|
+
taskId: input.taskId,
|
|
62
|
+
intent: input.intent,
|
|
63
|
+
generatedAt: input.generatedAt,
|
|
64
|
+
repository: input.repository,
|
|
65
|
+
verdict,
|
|
66
|
+
summary,
|
|
67
|
+
...(repositoryType ? { repositoryType } : {}),
|
|
68
|
+
impactedAreas: buildImpactedAreas(proofCards),
|
|
69
|
+
reviewFocus: buildReviewFocus(proofCards),
|
|
70
|
+
risks: buildRisks(proofCards, verdict),
|
|
71
|
+
suggestedChecks: buildSuggestedChecks(input.signals.assess, verdict),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function collectSignals(root, intent) {
|
|
75
|
+
const limitations = [];
|
|
76
|
+
const [assessResult, scanResult] = await Promise.allSettled([
|
|
77
|
+
computeAssess(root, { goal: intent }),
|
|
78
|
+
scanRepository(root),
|
|
79
|
+
]);
|
|
80
|
+
const assess = settledValue(assessResult);
|
|
81
|
+
if (!assess)
|
|
82
|
+
limitations.push('assess report unavailable');
|
|
83
|
+
const scan = settledValue(scanResult);
|
|
84
|
+
if (!scan)
|
|
85
|
+
limitations.push('repository scan unavailable');
|
|
86
|
+
let languages;
|
|
87
|
+
let frameworks;
|
|
88
|
+
if (scan) {
|
|
89
|
+
try {
|
|
90
|
+
languages = detectLanguages(scan.files);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
limitations.push('language detection unavailable');
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
frameworks = await detectFrameworks(root, scan.files);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
limitations.push('framework detection unavailable');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { assess, scan, languages, frameworks, limitations };
|
|
103
|
+
}
|
|
104
|
+
function settledValue(result) {
|
|
105
|
+
return result.status === 'fulfilled' ? result.value : undefined;
|
|
106
|
+
}
|
|
107
|
+
function mapVerdict(assess) {
|
|
108
|
+
if (!assess)
|
|
109
|
+
return 'unknown';
|
|
110
|
+
const preflight = assess.sourceVerdicts?.preflight;
|
|
111
|
+
if (preflight === 'block')
|
|
112
|
+
return 'block';
|
|
113
|
+
if (preflight === 'caution')
|
|
114
|
+
return 'caution';
|
|
115
|
+
if (preflight === 'proceed')
|
|
116
|
+
return 'proceed';
|
|
117
|
+
if (assess.proofCards.length === 0)
|
|
118
|
+
return 'unknown';
|
|
119
|
+
if (assess.verdict === 'blocked')
|
|
120
|
+
return 'block';
|
|
121
|
+
if (assess.verdict === 'watch')
|
|
122
|
+
return 'caution';
|
|
123
|
+
if (assess.verdict === 'ready')
|
|
124
|
+
return 'proceed';
|
|
125
|
+
return 'unknown';
|
|
126
|
+
}
|
|
127
|
+
function summarizeAssessment(verdict, signals) {
|
|
128
|
+
if (verdict === 'unknown') {
|
|
129
|
+
const reason = signals.limitations.length > 0
|
|
130
|
+
? signals.limitations.join('; ')
|
|
131
|
+
: 'no source verdicts or review-focus evidence were available';
|
|
132
|
+
return `unknown: ProjScan assessment is limited because ${reason}.`;
|
|
133
|
+
}
|
|
134
|
+
const baseSummary = signals.assess?.summary ?? 'local ProjScan signals were mapped to Baseframe';
|
|
135
|
+
return `${verdict}: ${baseSummary}`;
|
|
136
|
+
}
|
|
137
|
+
function describeRepositoryType(languages, frameworks) {
|
|
138
|
+
const primary = languages?.primary && languages.primary !== 'Unknown' ? languages.primary : '';
|
|
139
|
+
const frameworkNames = frameworks?.frameworks.map((framework) => framework.name).sort((a, b) => a.localeCompare(b)) ??
|
|
140
|
+
[];
|
|
141
|
+
const packageManager = frameworks?.packageManager && frameworks.packageManager !== 'unknown'
|
|
142
|
+
? frameworks.packageManager
|
|
143
|
+
: '';
|
|
144
|
+
const details = frameworkNames.length > 0 && packageManager
|
|
145
|
+
? `${frameworkNames.join(', ')}; ${packageManager}`
|
|
146
|
+
: [...frameworkNames, packageManager].filter(Boolean).join(', ');
|
|
147
|
+
if (!primary && !details)
|
|
148
|
+
return undefined;
|
|
149
|
+
if (!primary)
|
|
150
|
+
return `Repository (${details})`;
|
|
151
|
+
return details ? `${primary} repository (${details})` : `${primary} repository`;
|
|
152
|
+
}
|
|
153
|
+
function buildImpactedAreas(proofCards) {
|
|
154
|
+
const areas = new Map();
|
|
155
|
+
for (const card of proofCards) {
|
|
156
|
+
for (const file of normalizeFileList(card.files)) {
|
|
157
|
+
const areaName = file.split('/')[0] || file;
|
|
158
|
+
const area = areas.get(areaName) ?? { paths: new Set(), reasons: new Set() };
|
|
159
|
+
area.paths.add(file);
|
|
160
|
+
area.reasons.add(card.finding);
|
|
161
|
+
areas.set(areaName, area);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return [...areas.entries()]
|
|
165
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
166
|
+
.map(([name, area]) => ({
|
|
167
|
+
name,
|
|
168
|
+
paths: [...area.paths].sort((a, b) => a.localeCompare(b)),
|
|
169
|
+
reason: [...area.reasons].sort((a, b) => a.localeCompare(b)).join('; '),
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
function buildReviewFocus(proofCards) {
|
|
173
|
+
const focus = new Map();
|
|
174
|
+
for (const card of proofCards) {
|
|
175
|
+
for (const file of normalizeFileList(card.files)) {
|
|
176
|
+
const current = focus.get(file);
|
|
177
|
+
const priority = strongerPriority(current?.priority, mapPriority(card.priority));
|
|
178
|
+
const reasons = current?.reasons ?? new Set();
|
|
179
|
+
reasons.add(card.finding);
|
|
180
|
+
reasons.add(card.whyItMatters);
|
|
181
|
+
focus.set(file, { priority, reasons });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return [...focus.entries()]
|
|
185
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
186
|
+
.map(([file, entry]) => ({
|
|
187
|
+
path: file,
|
|
188
|
+
priority: entry.priority,
|
|
189
|
+
reasons: [...entry.reasons].filter(Boolean),
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
function buildRisks(proofCards, verdict) {
|
|
193
|
+
return proofCards.map((card) => {
|
|
194
|
+
const files = normalizeFileList(card.files);
|
|
195
|
+
return {
|
|
196
|
+
id: card.id,
|
|
197
|
+
severity: riskSeverity(verdict, card.priority),
|
|
198
|
+
category: card.source,
|
|
199
|
+
message: card.finding,
|
|
200
|
+
...(files.length > 0 ? { files } : {}),
|
|
201
|
+
...(card.recommendedFix.summary ? { suggestedAction: card.recommendedFix.summary } : {}),
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
function buildSuggestedChecks(assess, verdict) {
|
|
206
|
+
if (!assess)
|
|
207
|
+
return [];
|
|
208
|
+
if (verdict === 'unknown' && assess.proofCards.length === 0 && !assess.sourceVerdicts)
|
|
209
|
+
return [];
|
|
210
|
+
const checks = new Map();
|
|
211
|
+
const proofReasons = new Map();
|
|
212
|
+
for (const card of assess.proofCards) {
|
|
213
|
+
for (const command of card.verification.commands) {
|
|
214
|
+
proofReasons.set(command, `Proof-card verification for ${card.finding}.`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
for (const command of assess.answers.testsThatProveIt) {
|
|
218
|
+
checks.set(command, {
|
|
219
|
+
command,
|
|
220
|
+
reason: proofReasons.get(command) ?? reasonForAssessmentCommand(command),
|
|
221
|
+
required: true,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
for (const [command, reason] of proofReasons) {
|
|
225
|
+
if (!checks.has(command))
|
|
226
|
+
checks.set(command, { command, reason, required: true });
|
|
227
|
+
}
|
|
228
|
+
for (const command of assess.commands) {
|
|
229
|
+
if (!checks.has(command)) {
|
|
230
|
+
checks.set(command, {
|
|
231
|
+
command,
|
|
232
|
+
reason: 'ProjScan assessment follow-up.',
|
|
233
|
+
required: false,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return [...checks.values()];
|
|
238
|
+
}
|
|
239
|
+
function reasonForAssessmentCommand(command) {
|
|
240
|
+
if (command === 'projscan doctor --format json')
|
|
241
|
+
return 'Confirms the issue queue after fixes.';
|
|
242
|
+
if (command.startsWith('projscan preflight '))
|
|
243
|
+
return 'Confirms preflight readiness.';
|
|
244
|
+
return 'Assessment verification command.';
|
|
245
|
+
}
|
|
246
|
+
function normalizeFileList(files) {
|
|
247
|
+
return [...new Set(files.map(normalizeReportPath).filter((file) => file.length > 0))].sort((a, b) => a.localeCompare(b));
|
|
248
|
+
}
|
|
249
|
+
function normalizeReportPath(file) {
|
|
250
|
+
return file.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
251
|
+
}
|
|
252
|
+
function mapPriority(priority) {
|
|
253
|
+
if (priority === 'p0' || priority === 'p1')
|
|
254
|
+
return 'high';
|
|
255
|
+
if (priority === 'p2')
|
|
256
|
+
return 'medium';
|
|
257
|
+
return 'low';
|
|
258
|
+
}
|
|
259
|
+
function strongerPriority(left, right) {
|
|
260
|
+
if (!left)
|
|
261
|
+
return right;
|
|
262
|
+
const rank = { high: 0, medium: 1, low: 2 };
|
|
263
|
+
return rank[right] < rank[left] ? right : left;
|
|
264
|
+
}
|
|
265
|
+
function riskSeverity(verdict, priority) {
|
|
266
|
+
if (verdict === 'block' || priority === 'p0')
|
|
267
|
+
return 'blocking';
|
|
268
|
+
if (verdict === 'caution' || priority === 'p1')
|
|
269
|
+
return 'warning';
|
|
270
|
+
return 'info';
|
|
271
|
+
}
|
|
272
|
+
function validateTaskId(taskId) {
|
|
273
|
+
if (!TASK_ID_PATTERN.test(taskId)) {
|
|
274
|
+
throw new Error('Invalid task ID. Task ID must be 1-128 characters, start and end with a letter or number, and contain only letters, numbers, hyphen, or underscore.');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function normalizeIntent(intent) {
|
|
278
|
+
const trimmed = intent.trim();
|
|
279
|
+
if (!trimmed)
|
|
280
|
+
throw new Error('Baseframe assessment requires a non-empty intent.');
|
|
281
|
+
return trimmed;
|
|
282
|
+
}
|
|
283
|
+
function resolveAssessmentOutputPath(root, taskId, outputPath) {
|
|
284
|
+
if (outputPath && hasTraversalSegment(outputPath)) {
|
|
285
|
+
throw new Error('Invalid output path. Path traversal segments are not allowed.');
|
|
286
|
+
}
|
|
287
|
+
const expected = defaultAssessmentPath(root, taskId);
|
|
288
|
+
const resolved = outputPath ? path.resolve(root, outputPath) : expected;
|
|
289
|
+
if (resolved !== expected) {
|
|
290
|
+
throw new Error(`Invalid output path. ProjScan can only write ${relativeRepositoryPath(root, expected)} for task ${taskId}.`);
|
|
291
|
+
}
|
|
292
|
+
return resolved;
|
|
293
|
+
}
|
|
294
|
+
function defaultAssessmentPath(root, taskId) {
|
|
295
|
+
return path.join(root, BASEFRAME_DIR, EVIDENCE_DIR, taskId, ASSESSMENT_FILE);
|
|
296
|
+
}
|
|
297
|
+
function hasTraversalSegment(value) {
|
|
298
|
+
return value.split(/[\\/]+/).includes('..');
|
|
299
|
+
}
|
|
300
|
+
async function prepareAssessmentWrite(root, taskId, outputPath) {
|
|
301
|
+
await ensureSafeDirectoryPath(root, [BASEFRAME_DIR, EVIDENCE_DIR, taskId]);
|
|
302
|
+
if (path.dirname(outputPath) !== path.join(root, BASEFRAME_DIR, EVIDENCE_DIR, taskId)) {
|
|
303
|
+
throw new Error('Invalid output path. Output parent does not match the task evidence directory.');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function ensureSafeDirectoryPath(root, segments) {
|
|
307
|
+
const rootReal = await fs.realpath(root);
|
|
308
|
+
let current = root;
|
|
309
|
+
for (const segment of segments) {
|
|
310
|
+
current = path.join(current, segment);
|
|
311
|
+
await ensureDirectoryNoSymlink(current);
|
|
312
|
+
}
|
|
313
|
+
const currentReal = await fs.realpath(current);
|
|
314
|
+
if (!isPathInside(currentReal, rootReal)) {
|
|
315
|
+
throw new Error(`Refusing to write through symlinked Baseframe path: ${current}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async function ensureDirectoryNoSymlink(dirPath) {
|
|
319
|
+
let stat = await lstatOptional(dirPath);
|
|
320
|
+
if (!stat) {
|
|
321
|
+
try {
|
|
322
|
+
await fs.mkdir(dirPath);
|
|
323
|
+
}
|
|
324
|
+
catch (err) {
|
|
325
|
+
if (!isNodeErrorCode(err, 'EEXIST'))
|
|
326
|
+
throw err;
|
|
327
|
+
}
|
|
328
|
+
stat = await lstatOptional(dirPath);
|
|
329
|
+
}
|
|
330
|
+
if (!stat)
|
|
331
|
+
throw new Error(`Could not create output directory: ${dirPath}`);
|
|
332
|
+
if (stat.isSymbolicLink()) {
|
|
333
|
+
throw new Error(`Refusing to write through symlinked Baseframe directory: ${dirPath}`);
|
|
334
|
+
}
|
|
335
|
+
if (!stat.isDirectory())
|
|
336
|
+
throw new Error(`Output path component is not a directory: ${dirPath}`);
|
|
337
|
+
}
|
|
338
|
+
async function assertWritableAssessmentOutput(outputPath, taskId) {
|
|
339
|
+
const stat = await lstatOptional(outputPath);
|
|
340
|
+
if (!stat)
|
|
341
|
+
return;
|
|
342
|
+
if (stat.isSymbolicLink()) {
|
|
343
|
+
throw new Error(`Refusing to overwrite symlinked output path: ${outputPath}`);
|
|
344
|
+
}
|
|
345
|
+
if (!stat.isFile())
|
|
346
|
+
throw new Error(`Existing output path is not a file: ${outputPath}`);
|
|
347
|
+
let parsed;
|
|
348
|
+
try {
|
|
349
|
+
parsed = JSON.parse(await fs.readFile(outputPath, 'utf-8'));
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
throw new Error(`Refusing to overwrite existing output that is not a ProjScan assessment: ${outputPath}`);
|
|
353
|
+
}
|
|
354
|
+
if (!isMatchingAssessment(parsed, taskId)) {
|
|
355
|
+
throw new Error(`Refusing to overwrite existing output that is not this ProjScan assessment: ${outputPath}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
function isMatchingAssessment(value, taskId) {
|
|
359
|
+
return (isRecord(value) &&
|
|
360
|
+
value.schemaVersion === '1.0' &&
|
|
361
|
+
value.kind === 'projscan-assessment' &&
|
|
362
|
+
value.taskId === taskId);
|
|
363
|
+
}
|
|
364
|
+
async function updateWorkflowManifest(input) {
|
|
365
|
+
const manifestPath = path.join(input.root, BASEFRAME_DIR, 'agent-workflow.json');
|
|
366
|
+
const stat = await lstatOptional(manifestPath);
|
|
367
|
+
if (stat?.isSymbolicLink()) {
|
|
368
|
+
throw new Error(`Refusing to overwrite symlinked workflow manifest: ${manifestPath}`);
|
|
369
|
+
}
|
|
370
|
+
if (stat && !stat.isFile()) {
|
|
371
|
+
throw new Error(`Existing workflow manifest is not a file: ${manifestPath}`);
|
|
372
|
+
}
|
|
373
|
+
const existing = stat ? await readManifest(manifestPath) : {};
|
|
374
|
+
if (typeof existing.taskId === 'string' && existing.taskId !== input.taskId) {
|
|
375
|
+
throw new Error(`Workflow manifest already belongs to task ${existing.taskId}; refusing to mix task ${input.taskId}.`);
|
|
376
|
+
}
|
|
377
|
+
const existingTools = isRecord(existing.tools) ? existing.tools : {};
|
|
378
|
+
const manifest = {
|
|
379
|
+
...existing,
|
|
380
|
+
schemaVersion: '1.0',
|
|
381
|
+
taskId: input.taskId,
|
|
382
|
+
intent: input.intent,
|
|
383
|
+
createdAt: typeof existing.createdAt === 'string' ? existing.createdAt : input.updatedAt,
|
|
384
|
+
updatedAt: input.updatedAt,
|
|
385
|
+
tools: {
|
|
386
|
+
...existingTools,
|
|
387
|
+
projscan: {
|
|
388
|
+
status: 'completed',
|
|
389
|
+
assessmentPath: input.assessmentPath,
|
|
390
|
+
version: input.version,
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
await atomicWriteJson(manifestPath, manifest);
|
|
395
|
+
}
|
|
396
|
+
async function readManifest(manifestPath) {
|
|
397
|
+
try {
|
|
398
|
+
const parsed = JSON.parse(await fs.readFile(manifestPath, 'utf-8'));
|
|
399
|
+
if (!isRecord(parsed))
|
|
400
|
+
throw new Error('workflow manifest must be a JSON object');
|
|
401
|
+
return parsed;
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
throw new Error(`Could not read workflow manifest ${manifestPath}: ${err instanceof Error ? err.message : 'invalid JSON'}`, { cause: err });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async function atomicWriteJson(filePath, value) {
|
|
408
|
+
await atomicWriteFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
409
|
+
}
|
|
410
|
+
async function readRepositoryMetadata(root) {
|
|
411
|
+
const [branch, commit] = await Promise.all([
|
|
412
|
+
gitOutput(root, ['rev-parse', '--abbrev-ref', 'HEAD']),
|
|
413
|
+
gitOutput(root, ['rev-parse', 'HEAD']),
|
|
414
|
+
]);
|
|
415
|
+
return {
|
|
416
|
+
root,
|
|
417
|
+
...(branch && branch !== 'HEAD' ? { branch } : {}),
|
|
418
|
+
...(commit ? { commit } : {}),
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
async function gitOutput(root, args) {
|
|
422
|
+
try {
|
|
423
|
+
const { stdout } = await execFileAsync('git', args, { cwd: root, maxBuffer: 1024 * 1024 });
|
|
424
|
+
const trimmed = stdout.trim();
|
|
425
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
return undefined;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
async function readProducerVersion() {
|
|
432
|
+
if (cachedProducerVersion)
|
|
433
|
+
return cachedProducerVersion;
|
|
434
|
+
try {
|
|
435
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
436
|
+
const packagePath = path.resolve(moduleDir, '../../package.json');
|
|
437
|
+
const parsed = JSON.parse(await fs.readFile(packagePath, 'utf-8'));
|
|
438
|
+
cachedProducerVersion = typeof parsed.version === 'string' ? parsed.version : 'unknown';
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
cachedProducerVersion = 'unknown';
|
|
442
|
+
}
|
|
443
|
+
return cachedProducerVersion;
|
|
444
|
+
}
|
|
445
|
+
function relativeRepositoryPath(root, filePath) {
|
|
446
|
+
return path.relative(root, filePath).replace(/\\/g, '/');
|
|
447
|
+
}
|
|
448
|
+
function isPathInside(candidate, root) {
|
|
449
|
+
const relative = path.relative(root, candidate);
|
|
450
|
+
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
451
|
+
}
|
|
452
|
+
async function lstatOptional(filePath) {
|
|
453
|
+
try {
|
|
454
|
+
return await fs.lstat(filePath);
|
|
455
|
+
}
|
|
456
|
+
catch (err) {
|
|
457
|
+
if (isNodeErrorCode(err, 'ENOENT'))
|
|
458
|
+
return undefined;
|
|
459
|
+
throw err;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function isNodeErrorCode(error, code) {
|
|
463
|
+
return (typeof error === 'object' &&
|
|
464
|
+
error !== null &&
|
|
465
|
+
'code' in error &&
|
|
466
|
+
error.code === code);
|
|
467
|
+
}
|
|
468
|
+
function isRecord(value) {
|
|
469
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
470
|
+
}
|
|
471
|
+
//# sourceMappingURL=baseframeAssessment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseframeAssessment.js","sourceRoot":"","sources":["../../src/core/baseframeAssessment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.5",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:12b15eac-df3a-433e-8905-e162e6e28c3c",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2026-06-
|
|
7
|
+
"timestamp": "2026-06-26T21:00:43.477Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "projscan",
|
|
11
11
|
"name": "projscan-sbom-generator",
|
|
12
|
-
"version": "4.
|
|
12
|
+
"version": "4.16.0"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"component": {
|
|
16
16
|
"type": "application",
|
|
17
|
-
"bom-ref": "pkg:npm/projscan@4.
|
|
17
|
+
"bom-ref": "pkg:npm/projscan@4.16.0",
|
|
18
18
|
"name": "projscan",
|
|
19
|
-
"version": "4.
|
|
20
|
-
"purl": "pkg:npm/projscan@4.
|
|
19
|
+
"version": "4.16.0",
|
|
20
|
+
"purl": "pkg:npm/projscan@4.16.0"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"components": [
|
package/dist/publicCore.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { analyzeDependencies } from './core/dependencyAnalyzer.js';
|
|
|
5
5
|
export { collectIssues } from './core/issueEngine.js';
|
|
6
6
|
export { analyzeHotspots, computeRiskScore } from './core/hotspotAnalyzer.js';
|
|
7
7
|
export { computeAssess } from './core/assess.js';
|
|
8
|
+
export { createBaseframeAssessment, type CreateBaseframeAssessmentOptions, } from './core/baseframeAssessment.js';
|
|
8
9
|
export { computeSimulation } from './core/simulate.js';
|
|
9
10
|
export { computeProve } from './core/prove.js';
|
|
10
11
|
export { inspectFile } from './core/fileInspector.js';
|
package/dist/publicCore.js
CHANGED
|
@@ -5,6 +5,7 @@ export { analyzeDependencies } from './core/dependencyAnalyzer.js';
|
|
|
5
5
|
export { collectIssues } from './core/issueEngine.js';
|
|
6
6
|
export { analyzeHotspots, computeRiskScore } from './core/hotspotAnalyzer.js';
|
|
7
7
|
export { computeAssess } from './core/assess.js';
|
|
8
|
+
export { createBaseframeAssessment, } from './core/baseframeAssessment.js';
|
|
8
9
|
export { computeSimulation } from './core/simulate.js';
|
|
9
10
|
export { computeProve } from './core/prove.js';
|
|
10
11
|
export { inspectFile } from './core/fileInspector.js';
|
package/dist/publicCore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publicCore.js","sourceRoot":"","sources":["../src/publicCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAqB,MAAM,eAAe,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,EACT,SAAS,EACT,WAAW,GAGZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAwD,MAAM,mBAAmB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,WAAW,GAEZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EACL,KAAK,IAAI,WAAW,EACpB,OAAO,IAAI,aAAa,EACxB,KAAK,IAAI,WAAW,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"publicCore.js","sourceRoot":"","sources":["../src/publicCore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,yBAAyB,GAE1B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAqB,MAAM,eAAe,CAAC;AAC5E,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,SAAS,EACT,SAAS,EACT,WAAW,GAGZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAwD,MAAM,mBAAmB,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,WAAW,GAEZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EACL,KAAK,IAAI,WAAW,EACpB,OAAO,IAAI,aAAa,EACxB,KAAK,IAAI,WAAW,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/tool-manifest.json
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type ProjScanAssessmentVerdict = 'proceed' | 'caution' | 'block' | 'unknown';
|
|
2
|
+
export type ProjScanAssessmentPriority = 'high' | 'medium' | 'low';
|
|
3
|
+
export type ProjScanAssessmentRiskSeverity = 'info' | 'warning' | 'blocking';
|
|
4
|
+
export interface ProjScanAssessmentV1 {
|
|
5
|
+
schemaVersion: '1.0';
|
|
6
|
+
kind: 'projscan-assessment';
|
|
7
|
+
producer: {
|
|
8
|
+
name: 'projscan';
|
|
9
|
+
version: string;
|
|
10
|
+
};
|
|
11
|
+
taskId: string;
|
|
12
|
+
intent: string;
|
|
13
|
+
generatedAt: string;
|
|
14
|
+
repository: {
|
|
15
|
+
root: string;
|
|
16
|
+
branch?: string;
|
|
17
|
+
commit?: string;
|
|
18
|
+
};
|
|
19
|
+
verdict: ProjScanAssessmentVerdict;
|
|
20
|
+
summary: string;
|
|
21
|
+
repositoryType?: string;
|
|
22
|
+
impactedAreas: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
paths: string[];
|
|
25
|
+
reason: string;
|
|
26
|
+
}>;
|
|
27
|
+
reviewFocus: Array<{
|
|
28
|
+
path: string;
|
|
29
|
+
priority: ProjScanAssessmentPriority;
|
|
30
|
+
reasons: string[];
|
|
31
|
+
}>;
|
|
32
|
+
risks: Array<{
|
|
33
|
+
id: string;
|
|
34
|
+
severity: ProjScanAssessmentRiskSeverity;
|
|
35
|
+
category: string;
|
|
36
|
+
message: string;
|
|
37
|
+
files?: string[];
|
|
38
|
+
suggestedAction?: string;
|
|
39
|
+
}>;
|
|
40
|
+
suggestedChecks: Array<{
|
|
41
|
+
command: string;
|
|
42
|
+
reason: string;
|
|
43
|
+
required: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
artifacts?: Array<{
|
|
46
|
+
kind: 'report' | 'scan' | 'log';
|
|
47
|
+
path: string;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
export interface BaseframeAgentWorkflowV1 {
|
|
51
|
+
schemaVersion: '1.0';
|
|
52
|
+
taskId: string;
|
|
53
|
+
intent: string;
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
tools: {
|
|
57
|
+
projscan?: {
|
|
58
|
+
status: 'created' | 'completed' | 'failed';
|
|
59
|
+
assessmentPath: string;
|
|
60
|
+
version: string;
|
|
61
|
+
};
|
|
62
|
+
agentloopkit?: {
|
|
63
|
+
status: 'created' | 'completed' | 'failed';
|
|
64
|
+
taskPath?: string;
|
|
65
|
+
version?: string;
|
|
66
|
+
};
|
|
67
|
+
agentflight?: {
|
|
68
|
+
status: 'created' | 'completed' | 'failed';
|
|
69
|
+
resultPath?: string;
|
|
70
|
+
version?: string;
|
|
71
|
+
};
|
|
72
|
+
[toolName: string]: unknown;
|
|
73
|
+
};
|
|
74
|
+
[field: string]: unknown;
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseframe.js","sourceRoot":"","sources":["../../src/types/baseframe.ts"],"names":[],"mappings":""}
|
package/dist/types.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type * from './types/trial.js';
|
|
|
25
25
|
export type * from './types/understand.js';
|
|
26
26
|
export type * from './types/qualityScorecard.js';
|
|
27
27
|
export type * from './types/assess.js';
|
|
28
|
+
export type * from './types/baseframe.js';
|
|
28
29
|
export type * from './types/simulate.js';
|
|
29
30
|
export type * from './types/prove.js';
|
|
30
31
|
export type * from './types/proofLedger.js';
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Baseframe Suite Integration v1
|
|
2
|
+
|
|
3
|
+
ProjScan produces the repository-risk assessment for a specific task. AgentLoopKit
|
|
4
|
+
can consume that assessment to create a task contract, and AgentFlight can later
|
|
5
|
+
consume both artifacts for review readiness. The products stay separate:
|
|
6
|
+
ProjScan does not depend on AgentLoopKit or AgentFlight packages and does not
|
|
7
|
+
write their artifacts.
|
|
8
|
+
|
|
9
|
+
## Artifact Paths
|
|
10
|
+
|
|
11
|
+
All artifacts are local files inside the target repository:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
.baseframe/
|
|
15
|
+
agent-workflow.json
|
|
16
|
+
evidence/
|
|
17
|
+
<task-id>/
|
|
18
|
+
projscan-assessment.json
|
|
19
|
+
agentloopkit-task.json
|
|
20
|
+
agentflight-result.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
ProjScan owns only:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
.baseframe/evidence/<task-id>/projscan-assessment.json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
ProjScan may create or update `.baseframe/agent-workflow.json`. It preserves
|
|
30
|
+
unknown fields and existing AgentLoopKit or AgentFlight sections, and updates
|
|
31
|
+
only shared task timestamps plus `tools.projscan`.
|
|
32
|
+
|
|
33
|
+
## Command
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
projscan assess \
|
|
37
|
+
--intent "Implement password reset" \
|
|
38
|
+
--task-id auth-password-reset-20260626-01 \
|
|
39
|
+
--emit-baseframe
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The command prints the relative assessment path:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
.baseframe/evidence/auth-password-reset-20260626-01/projscan-assessment.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
An explicit ProjScan-owned output path is also supported:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
projscan assess \
|
|
52
|
+
--intent "Implement password reset" \
|
|
53
|
+
--task-id auth-password-reset-20260626-01 \
|
|
54
|
+
--output .baseframe/evidence/auth-password-reset-20260626-01/projscan-assessment.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Task IDs must be filesystem-safe: 1 to 128 characters, start and end with a
|
|
58
|
+
letter or number, and contain only letters, numbers, hyphen, or underscore.
|
|
59
|
+
|
|
60
|
+
## Assessment Schema
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
type ProjScanAssessmentV1 = {
|
|
64
|
+
schemaVersion: "1.0";
|
|
65
|
+
kind: "projscan-assessment";
|
|
66
|
+
producer: { name: "projscan"; version: string };
|
|
67
|
+
taskId: string;
|
|
68
|
+
intent: string;
|
|
69
|
+
generatedAt: string;
|
|
70
|
+
repository: { root: string; branch?: string; commit?: string };
|
|
71
|
+
verdict: "proceed" | "caution" | "block" | "unknown";
|
|
72
|
+
summary: string;
|
|
73
|
+
repositoryType?: string;
|
|
74
|
+
impactedAreas: Array<{ name: string; paths: string[]; reason: string }>;
|
|
75
|
+
reviewFocus: Array<{
|
|
76
|
+
path: string;
|
|
77
|
+
priority: "high" | "medium" | "low";
|
|
78
|
+
reasons: string[];
|
|
79
|
+
}>;
|
|
80
|
+
risks: Array<{
|
|
81
|
+
id: string;
|
|
82
|
+
severity: "info" | "warning" | "blocking";
|
|
83
|
+
category: string;
|
|
84
|
+
message: string;
|
|
85
|
+
files?: string[];
|
|
86
|
+
suggestedAction?: string;
|
|
87
|
+
}>;
|
|
88
|
+
suggestedChecks: Array<{
|
|
89
|
+
command: string;
|
|
90
|
+
reason: string;
|
|
91
|
+
required: boolean;
|
|
92
|
+
}>;
|
|
93
|
+
artifacts?: Array<{ kind: "report" | "scan" | "log"; path: string }>;
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
ProjScan maps local evidence from `assess`, quality scorecard, bug hunt,
|
|
98
|
+
preflight, language detection, and framework detection. When a signal is not
|
|
99
|
+
available, ProjScan emits `unknown`, omits optional fields, uses empty arrays,
|
|
100
|
+
and explains the limitation in `summary`.
|
|
101
|
+
|
|
102
|
+
## Workflow Manifest
|
|
103
|
+
|
|
104
|
+
ProjScan writes manifest paths relative to the repository root:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
type BaseframeAgentWorkflowV1 = {
|
|
108
|
+
schemaVersion: "1.0";
|
|
109
|
+
taskId: string;
|
|
110
|
+
intent: string;
|
|
111
|
+
createdAt: string;
|
|
112
|
+
updatedAt: string;
|
|
113
|
+
tools: {
|
|
114
|
+
projscan?: {
|
|
115
|
+
status: "created" | "completed" | "failed";
|
|
116
|
+
assessmentPath: string;
|
|
117
|
+
version: string;
|
|
118
|
+
};
|
|
119
|
+
agentloopkit?: {
|
|
120
|
+
status: "created" | "completed" | "failed";
|
|
121
|
+
taskPath?: string;
|
|
122
|
+
version?: string;
|
|
123
|
+
};
|
|
124
|
+
agentflight?: {
|
|
125
|
+
status: "created" | "completed" | "failed";
|
|
126
|
+
resultPath?: string;
|
|
127
|
+
version?: string;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Writes are local and atomic. ProjScan rejects malformed task IDs, traversal
|
|
134
|
+
paths, symlinked Baseframe directories, and existing output files that are not a
|
|
135
|
+
matching ProjScan assessment for the same task.
|
|
136
|
+
|
|
137
|
+
## AgentLoopKit Consumption
|
|
138
|
+
|
|
139
|
+
AgentLoopKit should read:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
.baseframe/evidence/<task-id>/projscan-assessment.json
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
It should use `taskId`, `intent`, `verdict`, `impactedAreas`, `reviewFocus`,
|
|
146
|
+
`risks`, and `suggestedChecks` to create its own task contract artifact at:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
.baseframe/evidence/<task-id>/agentloopkit-task.json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
ProjScan does not call AgentLoopKit and does not write that file.
|
|
153
|
+
|
|
154
|
+
## Independent Use
|
|
155
|
+
|
|
156
|
+
The existing assessment workflows remain unchanged:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
projscan assess --mode fix-first --format markdown
|
|
160
|
+
projscan assess --goal "make this repo safer to ship this week" --format json
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Use the Baseframe flags only when a stable suite artifact is needed.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projscan",
|
|
3
3
|
"mcpName": "io.github.abhiyoheswaran1/projscan",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.16.0",
|
|
5
5
|
"description": "Local code intelligence for agent-assisted engineering. Focused daily workflows for repo orientation before edits, proof before handoff or commit, and release-candidate review, with AST-backed evidence through an MCP server and CLI. Runs locally by default.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"README.md",
|
|
15
15
|
"docs/2.0-MIGRATION.md",
|
|
16
16
|
"docs/GUIDE.md",
|
|
17
|
+
"docs/integrations/baseframe-suite-v1.md",
|
|
17
18
|
"docs/PLUGIN-AUTHORING.md",
|
|
18
19
|
"docs/PLUGIN-GALLERY.md",
|
|
19
20
|
"docs/ROADMAP.md",
|