hardness 1.1.2 → 1.1.3
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/AGENTS.md +3 -0
- package/CHANGELOG.md +34 -2
- package/README.md +2 -0
- package/node_modules/@hardness/analyzers/dist/index.d.ts +16 -0
- package/node_modules/@hardness/analyzers/dist/index.js +29 -0
- package/node_modules/@hardness/analyzers/dist/index.js.map +1 -1
- package/node_modules/@hardness/analyzers/dist/typescript-node.js +15 -8
- package/node_modules/@hardness/analyzers/dist/typescript-node.js.map +1 -1
- package/node_modules/@hardness/analyzers/package.json +1 -1
- package/node_modules/@hardness/core/dist/agent/adapter.d.ts +17 -0
- package/node_modules/@hardness/core/dist/agent/adapter.js +17 -0
- package/node_modules/@hardness/core/dist/agent/adapter.js.map +1 -1
- package/node_modules/@hardness/core/dist/common/paths.js +1 -0
- package/node_modules/@hardness/core/dist/common/paths.js.map +1 -1
- package/node_modules/@hardness/core/dist/common/types.d.ts +2 -1
- package/node_modules/@hardness/core/dist/common/types.js +1 -1
- package/node_modules/@hardness/core/dist/common/types.js.map +1 -1
- package/node_modules/@hardness/core/dist/gates/analyzer-gate.d.ts +3 -0
- package/node_modules/@hardness/core/dist/gates/analyzer-gate.js +29 -4
- package/node_modules/@hardness/core/dist/gates/analyzer-gate.js.map +1 -1
- package/node_modules/@hardness/core/dist/gates/dependency.d.ts +6 -0
- package/node_modules/@hardness/core/dist/gates/dependency.js +17 -2
- package/node_modules/@hardness/core/dist/gates/dependency.js.map +1 -1
- package/node_modules/@hardness/core/dist/gates/generic.d.ts +7 -1
- package/node_modules/@hardness/core/dist/gates/generic.js +24 -14
- package/node_modules/@hardness/core/dist/gates/generic.js.map +1 -1
- package/node_modules/@hardness/core/dist/gates/import-resolver.d.ts +2 -0
- package/node_modules/@hardness/core/dist/gates/import-resolver.js +34 -36
- package/node_modules/@hardness/core/dist/gates/import-resolver.js.map +1 -1
- package/node_modules/@hardness/core/dist/locks/harness-guard.js +2 -1
- package/node_modules/@hardness/core/dist/locks/harness-guard.js.map +1 -1
- package/node_modules/@hardness/core/dist/locks/sprint-lock.js +2 -1
- package/node_modules/@hardness/core/dist/locks/sprint-lock.js.map +1 -1
- package/node_modules/@hardness/core/dist/orchestrator.d.ts +2 -0
- package/node_modules/@hardness/core/dist/orchestrator.js +7 -0
- package/node_modules/@hardness/core/dist/orchestrator.js.map +1 -1
- package/node_modules/@hardness/core/dist/sprint/status.js +3 -3
- package/node_modules/@hardness/core/dist/sprint/status.js.map +1 -1
- package/node_modules/@hardness/core/dist/sprint/validator.js +14 -2
- package/node_modules/@hardness/core/dist/sprint/validator.js.map +1 -1
- package/node_modules/@hardness/core/package.json +1 -1
- package/node_modules/@hardness/prompts/package.json +1 -1
- package/package.json +1 -1
- package/packages/analyzers/dist/index.d.ts +16 -0
- package/packages/analyzers/dist/index.js +29 -0
- package/packages/analyzers/dist/index.js.map +1 -1
- package/packages/analyzers/dist/typescript-node.js +15 -8
- package/packages/analyzers/dist/typescript-node.js.map +1 -1
- package/packages/analyzers/package.json +1 -1
- package/packages/cli/dist/commands/audit.js +1 -1
- package/packages/cli/dist/commands/audit.js.map +1 -1
- package/packages/cli/dist/commands/discover.js +7 -1
- package/packages/cli/dist/commands/discover.js.map +1 -1
- package/packages/cli/dist/commands/plan.js +3 -1
- package/packages/cli/dist/commands/plan.js.map +1 -1
- package/packages/cli/dist/commands/run.js +6 -1
- package/packages/cli/dist/commands/run.js.map +1 -1
- package/packages/cli/dist/commands/spec.js +3 -1
- package/packages/cli/dist/commands/spec.js.map +1 -1
- package/packages/cli/dist/commands/validate.js +2 -2
- package/packages/cli/dist/commands/validate.js.map +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/core/dist/agent/adapter.d.ts +17 -0
- package/packages/core/dist/agent/adapter.js +17 -0
- package/packages/core/dist/agent/adapter.js.map +1 -1
- package/packages/core/dist/common/paths.js +1 -0
- package/packages/core/dist/common/paths.js.map +1 -1
- package/packages/core/dist/common/types.d.ts +2 -1
- package/packages/core/dist/common/types.js +1 -1
- package/packages/core/dist/common/types.js.map +1 -1
- package/packages/core/dist/gates/analyzer-gate.d.ts +3 -0
- package/packages/core/dist/gates/analyzer-gate.js +29 -4
- package/packages/core/dist/gates/analyzer-gate.js.map +1 -1
- package/packages/core/dist/gates/dependency.d.ts +6 -0
- package/packages/core/dist/gates/dependency.js +17 -2
- package/packages/core/dist/gates/dependency.js.map +1 -1
- package/packages/core/dist/gates/generic.d.ts +7 -1
- package/packages/core/dist/gates/generic.js +24 -14
- package/packages/core/dist/gates/generic.js.map +1 -1
- package/packages/core/dist/gates/import-resolver.d.ts +2 -0
- package/packages/core/dist/gates/import-resolver.js +34 -36
- package/packages/core/dist/gates/import-resolver.js.map +1 -1
- package/packages/core/dist/locks/harness-guard.js +2 -1
- package/packages/core/dist/locks/harness-guard.js.map +1 -1
- package/packages/core/dist/locks/sprint-lock.js +2 -1
- package/packages/core/dist/locks/sprint-lock.js.map +1 -1
- package/packages/core/dist/orchestrator.d.ts +2 -0
- package/packages/core/dist/orchestrator.js +7 -0
- package/packages/core/dist/orchestrator.js.map +1 -1
- package/packages/core/dist/sprint/status.js +3 -3
- package/packages/core/dist/sprint/status.js.map +1 -1
- package/packages/core/dist/sprint/validator.js +14 -2
- package/packages/core/dist/sprint/validator.js.map +1 -1
- package/packages/core/package.json +1 -1
- package/packages/prompts/package.json +1 -1
- package/schemas/sprint.schema.json +1 -1
|
@@ -10,7 +10,9 @@ export function planCommand(program) {
|
|
|
10
10
|
.option('--spec <path>', 'Path to SPEC.md (defaults to <root>/SPEC.md)')
|
|
11
11
|
.action(async (opts) => {
|
|
12
12
|
const root = opts.root ?? getProjectRoot();
|
|
13
|
-
const specPath = opts.spec
|
|
13
|
+
const specPath = opts.spec
|
|
14
|
+
? (path.isAbsolute(opts.spec) ? opts.spec : path.resolve(root, opts.spec))
|
|
15
|
+
: path.join(root, 'SPEC.md');
|
|
14
16
|
const sprintsDir = path.join(root, '.hardness', 'sprints');
|
|
15
17
|
if (!fs.existsSync(specPath)) {
|
|
16
18
|
logger.error(`SPEC.md not found at: ${specPath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,eAAe,EAAE,2DAA2D,CAAC;SACpF,MAAM,CAAC,eAAe,EAAE,8CAA8C,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,IAAsC,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,12 @@ export function runCommand(program) {
|
|
|
12
12
|
const root = getProjectRoot();
|
|
13
13
|
logger.debug(`Starting hardness run (dryRun=${!!opts.dryRun}) at root "${root}"...`);
|
|
14
14
|
try {
|
|
15
|
-
await runOrchestrator({
|
|
15
|
+
await runOrchestrator({
|
|
16
|
+
dryRun: !!opts.dryRun,
|
|
17
|
+
featureId: opts.feature,
|
|
18
|
+
thinkingLevel: opts.thinking,
|
|
19
|
+
timeout: opts.timeout ? parseInt(opts.timeout, 10) : undefined,
|
|
20
|
+
}, root);
|
|
16
21
|
}
|
|
17
22
|
catch (err) {
|
|
18
23
|
logger.fatal(`Orchestrator failure: ${err.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEzE,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,2DAA2D,CAAC;SACxE,MAAM,CAAC,WAAW,EAAE,yDAAyD,EAAE,KAAK,CAAC;SACrF,MAAM,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAClE,MAAM,CAAC,oBAAoB,EAAE,qDAAqD,CAAC;SACnF,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;SACzD,MAAM,CAAC,kBAAkB,EAAE,2BAA2B,EAAE,KAAK,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,IAAI,CAAC,MAAM,cAAc,IAAI,MAAM,CAAC,CAAC;QACrF,IAAI,CAAC;YACH,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEzE,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,2DAA2D,CAAC;SACxE,MAAM,CAAC,WAAW,EAAE,yDAAyD,EAAE,KAAK,CAAC;SACrF,MAAM,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;SAClE,MAAM,CAAC,oBAAoB,EAAE,qDAAqD,CAAC;SACnF,MAAM,CAAC,qBAAqB,EAAE,0BAA0B,CAAC;SACzD,MAAM,CAAC,kBAAkB,EAAE,2BAA2B,EAAE,KAAK,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,IAAI,CAAC,MAAM,cAAc,IAAI,MAAM,CAAC,CAAC;QACrF,IAAI,CAAC;YACH,MAAM,eAAe,CACnB;gBACE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;gBACrB,SAAS,EAAE,IAAI,CAAC,OAAO;gBACvB,aAAa,EAAE,IAAI,CAAC,QAAoE;gBACxF,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;aAC/D,EACD,IAAI,CACL,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,yBAA0B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -10,7 +10,9 @@ export function specCommand(program) {
|
|
|
10
10
|
.option('--prd <path>', 'Path to PRD.md (defaults to <root>/PRD.md)')
|
|
11
11
|
.action(async (opts) => {
|
|
12
12
|
const root = opts.root ?? getProjectRoot();
|
|
13
|
-
const prdPath = opts.prd
|
|
13
|
+
const prdPath = opts.prd
|
|
14
|
+
? (path.isAbsolute(opts.prd) ? opts.prd : path.resolve(root, opts.prd))
|
|
15
|
+
: path.join(root, 'PRD.md');
|
|
14
16
|
const specPath = path.join(root, 'SPEC.md');
|
|
15
17
|
if (!fs.existsSync(prdPath)) {
|
|
16
18
|
logger.error(`PRD.md not found at: ${prdPath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,eAAe,EAAE,2DAA2D,CAAC;SACpF,MAAM,CAAC,cAAc,EAAE,4CAA4C,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,IAAqC,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,eAAe,EAAE,2DAA2D,CAAC;SACpF,MAAM,CAAC,cAAc,EAAE,4CAA4C,CAAC;SACpE,MAAM,CAAC,KAAK,EAAE,IAAqC,EAAE,EAAE;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG;YACtB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACvE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAErD,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAErC,IAAI,CAAC;YACH,YAAY,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,2BAA4B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -34,11 +34,11 @@ export function validateCommand(program) {
|
|
|
34
34
|
totalErrors += errors.filter(e => e.severity === 'error').length;
|
|
35
35
|
}
|
|
36
36
|
if (totalErrors === 0) {
|
|
37
|
-
logger.success('
|
|
37
|
+
logger.success('All sprints are valid.');
|
|
38
38
|
process.exit(0);
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
41
|
-
logger.error(
|
|
41
|
+
logger.error(`${totalErrors} error(s) found during validation.`);
|
|
42
42
|
process.exit(1);
|
|
43
43
|
}
|
|
44
44
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAmB,MAAM,gBAAgB,CAAC;AAEpH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAE3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,iCAAiC,UAAU,GAAG,EAAE,4BAA4B,CAAC,CAAC;YAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE7C,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBACjE,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBAClD,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC9B,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;gBACjE,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9D,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3B,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;QACnE,CAAC;QAED,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAmB,MAAM,gBAAgB,CAAC;AAEpH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAE3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,KAAK,CAAC,iCAAiC,UAAU,GAAG,EAAE,4BAA4B,CAAC,CAAC;YAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE7C,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBACjE,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBAClD,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC9B,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;gBACjE,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;YAC9D,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3B,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;QACnE,CAAC;QAED,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,oCAAoC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,MAAyB;IAC3D,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACzD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -8,5 +8,22 @@ export interface AgentRunResult {
|
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Invokes the external agent, substituting template variables and handling the shell process.
|
|
11
|
+
*
|
|
12
|
+
* Trust boundary: the `agentCommand` template and the project root path are
|
|
13
|
+
* configured by the project owner via `.hardness/config.json`. Hardness does
|
|
14
|
+
* not shell-escape the substituted `{cwd}`, `{context_file}` or `{timeout}`
|
|
15
|
+
* values because:
|
|
16
|
+
*
|
|
17
|
+
* 1. The project owner is the trusted author of `agentCommand` — they control
|
|
18
|
+
* both the command string and the location of the project on disk.
|
|
19
|
+
* 2. Escaping rules differ across shells (POSIX sh, bash, cmd.exe, PowerShell)
|
|
20
|
+
* and a naive escape implementation could introduce bugs more dangerous
|
|
21
|
+
* than the risk it mitigates.
|
|
22
|
+
* 3. The orchestrator only ever substitutes paths that originate from
|
|
23
|
+
* `getProjectRoot()` and the `.hardness/context.json` path it writes itself
|
|
24
|
+
* — never from agent-supplied or user-input strings at runtime.
|
|
25
|
+
*
|
|
26
|
+
* If an untrusted party can influence the project root path or the
|
|
27
|
+
* `agentCommand` value, that is the real vulnerability — not the substitution.
|
|
11
28
|
*/
|
|
12
29
|
export declare function runAgent(config: HardnessConfig, contextFilePath: string, projectRoot: string): Promise<AgentRunResult>;
|
|
@@ -2,6 +2,23 @@ import { runChecked } from '../common/subprocess.js';
|
|
|
2
2
|
import { logger } from '../common/logger.js';
|
|
3
3
|
/**
|
|
4
4
|
* Invokes the external agent, substituting template variables and handling the shell process.
|
|
5
|
+
*
|
|
6
|
+
* Trust boundary: the `agentCommand` template and the project root path are
|
|
7
|
+
* configured by the project owner via `.hardness/config.json`. Hardness does
|
|
8
|
+
* not shell-escape the substituted `{cwd}`, `{context_file}` or `{timeout}`
|
|
9
|
+
* values because:
|
|
10
|
+
*
|
|
11
|
+
* 1. The project owner is the trusted author of `agentCommand` — they control
|
|
12
|
+
* both the command string and the location of the project on disk.
|
|
13
|
+
* 2. Escaping rules differ across shells (POSIX sh, bash, cmd.exe, PowerShell)
|
|
14
|
+
* and a naive escape implementation could introduce bugs more dangerous
|
|
15
|
+
* than the risk it mitigates.
|
|
16
|
+
* 3. The orchestrator only ever substitutes paths that originate from
|
|
17
|
+
* `getProjectRoot()` and the `.hardness/context.json` path it writes itself
|
|
18
|
+
* — never from agent-supplied or user-input strings at runtime.
|
|
19
|
+
*
|
|
20
|
+
* If an untrusted party can influence the project root path or the
|
|
21
|
+
* `agentCommand` value, that is the real vulnerability — not the substitution.
|
|
5
22
|
*/
|
|
6
23
|
export async function runAgent(config, contextFilePath, projectRoot) {
|
|
7
24
|
const startTime = Date.now();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/agent/adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAU7C
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/agent/adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAU7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAsB,EACtB,eAAuB,EACvB,WAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;IAE9C,sFAAsF;IACtF,MAAM,qBAAqB,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAEpD,MAAM,OAAO,GAAG,WAAW;SACxB,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC;SACnD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;SAClC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAExC,MAAM,CAAC,KAAK,CAAC,4BAA4B,OAAO,GAAG,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE;QAC1C,GAAG,EAAE,WAAW;QAChB,SAAS,EAAE,SAAS;KACrB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAE1C,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,IAAI;QACpB,UAAU;QACV,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/common/paths.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/common/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export type SprintStatus = 'pending' | 'in-progress' | 'done';
|
|
2
2
|
export type FeatureStatus = 'pending' | 'in-progress' | 'done';
|
|
3
|
+
export declare const LOCK_SCHEMA_VERSION = 4;
|
|
3
4
|
export interface DependencyVerification {
|
|
4
5
|
name: string;
|
|
5
6
|
manifest?: string;
|
|
6
7
|
}
|
|
7
8
|
export interface SmokeVerification {
|
|
8
9
|
command: string;
|
|
9
|
-
executedBy: 'workflow'
|
|
10
|
+
executedBy: 'workflow';
|
|
10
11
|
timeoutSeconds?: number;
|
|
11
12
|
}
|
|
12
13
|
export interface AuditCategoryVerification {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const LOCK_SCHEMA_VERSION = 4;
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC"}
|
|
@@ -2,5 +2,8 @@ import { Gate } from './engine.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Static Analysis Gate: integrates the orchestrator's gate engine with the
|
|
4
4
|
* global analyzer registry, blocking approval of code with static errors.
|
|
5
|
+
*
|
|
6
|
+
* Honors optional `verification.auditCategory` and `verification.auditFinal`
|
|
7
|
+
* thresholds when present; defaults to failing on `error` severity otherwise.
|
|
5
8
|
*/
|
|
6
9
|
export declare const AnalyzerGate: Gate;
|
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { globalAnalyzerRegistry } from '@hardness/analyzers';
|
|
2
|
+
const SEVERITY_RANK = {
|
|
3
|
+
NONE: 0,
|
|
4
|
+
LOW: 1,
|
|
5
|
+
MED: 2,
|
|
6
|
+
HIGH: 3,
|
|
7
|
+
};
|
|
8
|
+
function shouldFail(diagSeverity, threshold) {
|
|
9
|
+
const diagRank = SEVERITY_RANK[diagSeverity.toUpperCase()] ?? 3;
|
|
10
|
+
const thresholdRank = SEVERITY_RANK[threshold] ?? 0;
|
|
11
|
+
return diagRank >= thresholdRank;
|
|
12
|
+
}
|
|
2
13
|
/**
|
|
3
14
|
* Static Analysis Gate: integrates the orchestrator's gate engine with the
|
|
4
15
|
* global analyzer registry, blocking approval of code with static errors.
|
|
16
|
+
*
|
|
17
|
+
* Honors optional `verification.auditCategory` and `verification.auditFinal`
|
|
18
|
+
* thresholds when present; defaults to failing on `error` severity otherwise.
|
|
5
19
|
*/
|
|
6
20
|
export const AnalyzerGate = {
|
|
7
21
|
name: 'analyzer',
|
|
@@ -9,9 +23,20 @@ export const AnalyzerGate = {
|
|
|
9
23
|
const profile = config.stack.stackProfile;
|
|
10
24
|
try {
|
|
11
25
|
const diagnostics = await globalAnalyzerRegistry.runAll(profile, projectRoot);
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
const auditCategory = feature.verification.auditCategory;
|
|
27
|
+
const auditFinal = feature.verification.auditFinal;
|
|
28
|
+
let failing;
|
|
29
|
+
if (auditCategory || auditFinal) {
|
|
30
|
+
const threshold = auditFinal?.failOnSeverityAtOrAbove
|
|
31
|
+
?? auditCategory.failOnSeverityAtOrAbove
|
|
32
|
+
?? 'LOW';
|
|
33
|
+
failing = diagnostics.filter((d) => shouldFail(d.severity, threshold));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
failing = diagnostics.filter((d) => d.severity === 'error');
|
|
37
|
+
}
|
|
38
|
+
if (failing.length > 0) {
|
|
39
|
+
const details = failing.map((e) => `[${e.file}${e.line ? `:${e.line}` : ''}] (${e.ruleId}): ${e.message}`);
|
|
15
40
|
return {
|
|
16
41
|
passed: false,
|
|
17
42
|
gate: 'analyzer',
|
|
@@ -22,7 +47,7 @@ export const AnalyzerGate = {
|
|
|
22
47
|
return {
|
|
23
48
|
passed: true,
|
|
24
49
|
gate: 'analyzer',
|
|
25
|
-
message: `Static analysis OK. (${diagnostics.length} diagnostics
|
|
50
|
+
message: `Static analysis OK. (${diagnostics.length} diagnostics reported)`
|
|
26
51
|
};
|
|
27
52
|
}
|
|
28
53
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer-gate.js","sourceRoot":"","sources":["../../src/gates/analyzer-gate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"analyzer-gate.js","sourceRoot":"","sources":["../../src/gates/analyzer-gate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAc,MAAM,qBAAqB,CAAC;AAEzE,MAAM,aAAa,GAA6B;IAC9C,IAAI,EAAE,CAAC;IACP,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC;CACR,CAAC;AAEF,SAAS,UAAU,CAAC,YAAoB,EAAE,SAAmB;IAC3D,MAAM,QAAQ,GAAG,aAAa,CAAE,YAAY,CAAC,WAAW,EAAe,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,QAAQ,IAAI,aAAa,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAS;IAChC,IAAI,EAAE,UAAU;IAChB,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAE,MAAsB,EAAE,WAAmB;QACrE,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,WAAW,GAAiB,MAAM,sBAAsB,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAE5F,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC;YACzD,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC;YAEnD,IAAI,OAAqB,CAAC;YAE1B,IAAI,aAAa,IAAI,UAAU,EAAE,CAAC;gBAChC,MAAM,SAAS,GAAa,UAAU,EAAE,uBAAuB;uBAC1D,aAAc,CAAC,uBAAuB;uBACtC,KAAK,CAAC;gBAEX,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;YAC9D,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3G,OAAO;oBACL,MAAM,EAAE,KAAK;oBACb,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,qDAAqD;oBAC9D,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;iBAC5B,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,wBAAwB,WAAW,CAAC,MAAM,wBAAwB;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,iCAAkC,GAAa,CAAC,OAAO,EAAE;aACnE,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Gate } from './engine.js';
|
|
2
2
|
/**
|
|
3
3
|
* Dependencies Gate: validates that libraries declared in the feature are present in the package manifest.
|
|
4
|
+
*
|
|
5
|
+
* - For `package.json` manifests, uses structured key lookup (exact match).
|
|
6
|
+
* - For other manifests, uses word-boundary regex matching to avoid false
|
|
7
|
+
* positives like `lodash` matching `lodash-es`.
|
|
8
|
+
* - Emits a warning (via logger) when a non-Node stack has no explicit manifest,
|
|
9
|
+
* instead of silently skipping.
|
|
4
10
|
*/
|
|
5
11
|
export declare const DependencyGate: Gate;
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { safeProjectPath } from '../common/paths.js';
|
|
3
|
+
import { logger } from '../common/logger.js';
|
|
4
|
+
function escapeRegex(s) {
|
|
5
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* Dependencies Gate: validates that libraries declared in the feature are present in the package manifest.
|
|
9
|
+
*
|
|
10
|
+
* - For `package.json` manifests, uses structured key lookup (exact match).
|
|
11
|
+
* - For other manifests, uses word-boundary regex matching to avoid false
|
|
12
|
+
* positives like `lodash` matching `lodash-es`.
|
|
13
|
+
* - Emits a warning (via logger) when a non-Node stack has no explicit manifest,
|
|
14
|
+
* instead of silently skipping.
|
|
5
15
|
*/
|
|
6
16
|
export const DependencyGate = {
|
|
7
17
|
name: 'dependencies',
|
|
@@ -19,7 +29,9 @@ export const DependencyGate = {
|
|
|
19
29
|
manifestFile = 'package.json';
|
|
20
30
|
}
|
|
21
31
|
else {
|
|
22
|
-
//
|
|
32
|
+
// Warn instead of silently skipping — the user declared a dependency
|
|
33
|
+
// expectation that we cannot verify without a manifest path.
|
|
34
|
+
logger.warn(`Dependency "${dep.name}" declared without a manifest path and stack profile "${stackProfile}" has no default manifest. Skipping (unverifiable).`);
|
|
23
35
|
continue;
|
|
24
36
|
}
|
|
25
37
|
}
|
|
@@ -48,7 +60,10 @@ export const DependencyGate = {
|
|
|
48
60
|
}
|
|
49
61
|
else {
|
|
50
62
|
// Textual fallback for other formats (e.g. Cargo.toml, requirements.txt)
|
|
51
|
-
|
|
63
|
+
// Use boundary matching that treats '-' as part of package names,
|
|
64
|
+
// so 'lodash' does not false-positive match 'lodash-es'.
|
|
65
|
+
const depRegex = new RegExp(`(?<![a-zA-Z0-9_-])${escapeRegex(dep.name)}(?![a-zA-Z0-9_-])`);
|
|
66
|
+
if (!depRegex.test(raw)) {
|
|
52
67
|
return {
|
|
53
68
|
passed: false,
|
|
54
69
|
gate: 'dependencies',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency.js","sourceRoot":"","sources":["../../src/gates/dependency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency.js","sourceRoot":"","sources":["../../src/gates/dependency.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,13 @@ export declare const AntiEmptyGate: Gate;
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const PathsGate: Gate;
|
|
14
14
|
/**
|
|
15
|
-
* Unicode Gate: rejects invalid typographic characters
|
|
15
|
+
* Unicode Gate: rejects invalid typographic characters and hidden Unicode in source code.
|
|
16
|
+
*
|
|
17
|
+
* Detects:
|
|
18
|
+
* - Em-dash (U+2014) and smart quotes (U+201C/D, U+2018/9) — typographic substitutions
|
|
19
|
+
* - Zero-width space (U+200B), zero-width non-joiner (U+200C), word joiner (U+2060)
|
|
20
|
+
* - BOM (U+FEFF)
|
|
21
|
+
* - RTL override (U+202E) and LTR override (U+202D)
|
|
16
22
|
*/
|
|
17
23
|
export declare const UnicodeGate: Gate;
|
|
18
24
|
/**
|
|
@@ -97,16 +97,30 @@ export const PathsGate = {
|
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
99
|
/**
|
|
100
|
-
* Unicode Gate: rejects invalid typographic characters
|
|
100
|
+
* Unicode Gate: rejects invalid typographic characters and hidden Unicode in source code.
|
|
101
|
+
*
|
|
102
|
+
* Detects:
|
|
103
|
+
* - Em-dash (U+2014) and smart quotes (U+201C/D, U+2018/9) — typographic substitutions
|
|
104
|
+
* - Zero-width space (U+200B), zero-width non-joiner (U+200C), word joiner (U+2060)
|
|
105
|
+
* - BOM (U+FEFF)
|
|
106
|
+
* - RTL override (U+202E) and LTR override (U+202D)
|
|
101
107
|
*/
|
|
102
108
|
export const UnicodeGate = {
|
|
103
109
|
name: 'unicode',
|
|
104
110
|
async run(feature, config, projectRoot) {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
const FORBIDDEN = [
|
|
112
|
+
{ cp: '\u2014', label: 'em-dash (—)' },
|
|
113
|
+
{ cp: '\u201c', label: 'left smart quote (“)' },
|
|
114
|
+
{ cp: '\u201d', label: 'right smart quote (”)' },
|
|
115
|
+
{ cp: '\u2018', label: 'single left smart quote (‘)' },
|
|
116
|
+
{ cp: '\u2019', label: 'single right smart quote (’)' },
|
|
117
|
+
{ cp: '\u200b', label: 'zero-width space (U+200B)' },
|
|
118
|
+
{ cp: '\u200c', label: 'zero-width non-joiner (U+200C)' },
|
|
119
|
+
{ cp: '\u2060', label: 'word joiner (U+2060)' },
|
|
120
|
+
{ cp: '\ufeff', label: 'BOM (U+FEFF)' },
|
|
121
|
+
{ cp: '\u202e', label: 'RTL override (U+202E)' },
|
|
122
|
+
{ cp: '\u202d', label: 'LTR override (U+202D)' },
|
|
123
|
+
];
|
|
110
124
|
for (const fileEntry of feature.files) {
|
|
111
125
|
const isObj = typeof fileEntry === 'object';
|
|
112
126
|
const fileRelPath = isObj ? fileEntry.file : fileEntry;
|
|
@@ -115,14 +129,10 @@ export const UnicodeGate = {
|
|
|
115
129
|
if (!fs.existsSync(absPath))
|
|
116
130
|
continue;
|
|
117
131
|
const content = fs.readFileSync(absPath, 'utf-8');
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return { passed: false, gate: 'unicode', message: `Invalid typographic character 'smart quote' (“ or ”) detected in file: ${fileRelPath}` };
|
|
123
|
-
}
|
|
124
|
-
if (content.includes(SINGLE_LEFT_SMART_QUOTE) || content.includes(SINGLE_RIGHT_SMART_QUOTE)) {
|
|
125
|
-
return { passed: false, gate: 'unicode', message: `Invalid typographic character 'smart quote' (‘ or ’) detected in file: ${fileRelPath}` };
|
|
132
|
+
for (const { cp, label } of FORBIDDEN) {
|
|
133
|
+
if (content.includes(cp)) {
|
|
134
|
+
return { passed: false, gate: 'unicode', message: `Invalid Unicode character '${label}' detected in file: ${fileRelPath}` };
|
|
135
|
+
}
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/gates/generic.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/gates/generic.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,5 +2,7 @@ import { Gate } from './engine.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Import Resolver Gate: validates that all relative imports declared in the
|
|
4
4
|
* feature's edited files actually resolve to existing files on disk.
|
|
5
|
+
*
|
|
6
|
+
* Supports multiline import/require statements via extractRelativeImports.
|
|
5
7
|
*/
|
|
6
8
|
export declare const ImportResolverGate: Gate;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { safeProjectPath } from '../common/paths.js';
|
|
4
|
+
import { extractRelativeImports } from '@hardness/analyzers';
|
|
4
5
|
/**
|
|
5
6
|
* Import Resolver Gate: validates that all relative imports declared in the
|
|
6
7
|
* feature's edited files actually resolve to existing files on disk.
|
|
8
|
+
*
|
|
9
|
+
* Supports multiline import/require statements via extractRelativeImports.
|
|
7
10
|
*/
|
|
8
11
|
export const ImportResolverGate = {
|
|
9
12
|
name: 'import-resolver',
|
|
@@ -12,7 +15,7 @@ export const ImportResolverGate = {
|
|
|
12
15
|
if (files.length === 0) {
|
|
13
16
|
return { passed: true, gate: 'import-resolver', message: 'No files modified in the feature to analyze.' };
|
|
14
17
|
}
|
|
15
|
-
const sourceExtensions = ['.ts', '.tsx', '.js', '.jsx'];
|
|
18
|
+
const sourceExtensions = ['.ts', '.tsx', '.js', '.jsx', '.cts', '.mts', '.cjs', '.mjs'];
|
|
16
19
|
for (const entry of files) {
|
|
17
20
|
const fileRel = typeof entry === 'string' ? entry : entry.file;
|
|
18
21
|
if (!sourceExtensions.some(ext => fileRel.endsWith(ext))) {
|
|
@@ -24,44 +27,39 @@ export const ImportResolverGate = {
|
|
|
24
27
|
continue; // Skip if the file no longer exists
|
|
25
28
|
}
|
|
26
29
|
const content = fs.readFileSync(absPath, 'utf-8');
|
|
27
|
-
const lines = content.split('\n');
|
|
28
30
|
const fileDir = path.dirname(absPath);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (fs.existsSync(cand) && fs.statSync(cand).isFile()) {
|
|
53
|
-
resolved = true;
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (!resolved) {
|
|
58
|
-
return {
|
|
59
|
-
passed: false,
|
|
60
|
-
gate: 'import-resolver',
|
|
61
|
-
message: `Unresolved relative import "${relativeImport}" in file "${fileRel}" at line ${lineNum}.`
|
|
62
|
-
};
|
|
31
|
+
const imports = extractRelativeImports(content);
|
|
32
|
+
for (const { path: relativeImport, line: lineNum } of imports) {
|
|
33
|
+
let resolved = false;
|
|
34
|
+
const basePath = path.resolve(fileDir, relativeImport);
|
|
35
|
+
const candidatePaths = [
|
|
36
|
+
basePath,
|
|
37
|
+
`${basePath}.ts`,
|
|
38
|
+
`${basePath}.tsx`,
|
|
39
|
+
`${basePath}.js`,
|
|
40
|
+
`${basePath}.jsx`,
|
|
41
|
+
`${basePath}.cts`,
|
|
42
|
+
`${basePath}.mts`,
|
|
43
|
+
`${basePath}.cjs`,
|
|
44
|
+
`${basePath}.mjs`,
|
|
45
|
+
path.join(basePath, 'index.ts'),
|
|
46
|
+
path.join(basePath, 'index.tsx'),
|
|
47
|
+
path.join(basePath, 'index.js'),
|
|
48
|
+
path.join(basePath, 'index.jsx')
|
|
49
|
+
];
|
|
50
|
+
for (const cand of candidatePaths) {
|
|
51
|
+
if (fs.existsSync(cand) && fs.statSync(cand).isFile()) {
|
|
52
|
+
resolved = true;
|
|
53
|
+
break;
|
|
63
54
|
}
|
|
64
55
|
}
|
|
56
|
+
if (!resolved) {
|
|
57
|
+
return {
|
|
58
|
+
passed: false,
|
|
59
|
+
gate: 'import-resolver',
|
|
60
|
+
message: `Unresolved relative import "${relativeImport}" in file "${fileRel}" at line ${lineNum}.`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../src/gates/import-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../src/gates/import-resolver.ts"],"names":[],"mappings":"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"}
|