@haposoft/cafekit 0.16.0-rc.3 → 0.16.0-rc.5
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/bin/__tests__/change-firewall.semantic-firewall.test.js +2134 -0
- package/bin/__tests__/codex-hooks.test.js +531 -29
- package/bin/__tests__/codex-native.test.js +228 -7
- package/bin/__tests__/develop-contract.test.js +653 -185
- package/bin/__tests__/finalizer-pass-gate.semantic-firewall.test.js +342 -0
- package/bin/__tests__/installer-safety.test.js +39 -0
- package/bin/__tests__/opencode-spec-gate.test.js +24 -16
- package/bin/__tests__/package-inventory.test.js +705 -13
- package/bin/__tests__/release-preflight.semantic-firewall.test.js +578 -0
- package/bin/__tests__/review-receipt-c2.semantic-firewall.test.js +378 -0
- package/bin/__tests__/specs-v2-execution-closeout.test.js +468 -0
- package/bin/__tests__/specs-v2-policy-and-scaffold.test.js +665 -0
- package/bin/__tests__/specs-v2-validator-grounder-contract.test.js +1132 -0
- package/bin/__tests__/test-runtime-dependency-closure.cjs +182 -0
- package/bin/__tests__/validator-grounding.test.js +2013 -221
- package/bin/lib/managed-writer.js +12 -3
- package/bin/phases/codex-runtime.js +17 -1
- package/package.json +5 -2
- package/src/claude/CLAUDE.md +6 -0
- package/src/claude/agents/code-auditor.md +20 -0
- package/src/claude/agents/spec-maker.md +143 -99
- package/src/claude/hooks/__tests__/completion-authority.test.js +321 -58
- package/src/claude/hooks/__tests__/privacy-block.test.js +254 -0
- package/src/claude/hooks/__tests__/semantic-review-authority.test.js +257 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +115 -40
- package/src/claude/hooks/completion-authority-check.cjs +37 -288
- package/src/claude/hooks/completion-authority-state.cjs +10 -8
- package/src/claude/hooks/completion-authority.cjs +13 -7
- package/src/claude/hooks/docs-sync.cjs +5 -2
- package/src/claude/hooks/lib/privacy-command-analysis.cjs +393 -0
- package/src/claude/hooks/lib/runtime-path-safety.cjs +119 -0
- package/src/claude/hooks/privacy-block.cjs +99 -28
- package/src/claude/hooks/semantic-review-authority.cjs +152 -0
- package/src/claude/hooks/spec-gate.cjs +47 -117
- package/src/claude/hooks/spec-state.cjs +8 -2
- package/src/claude/migration-manifest.json +9 -1
- package/src/claude/rules/state-sync.md +52 -21
- package/src/claude/rules/workflow.md +17 -9
- package/src/claude/scripts/change-firewall.cjs +1748 -0
- package/src/claude/scripts/spec-authoring-digest.cjs +151 -0
- package/src/claude/scripts/spec-authoring-validation.cjs +126 -0
- package/src/claude/scripts/spec-final-state.cjs +290 -0
- package/src/claude/scripts/spec-ground.cjs +571 -173
- package/src/claude/scripts/spec-readiness.cjs +425 -0
- package/src/claude/scripts/spec-receipt.cjs +162 -0
- package/src/claude/scripts/spec-resolver.cjs +67 -16
- package/src/claude/scripts/spec-scaffold.cjs +1594 -139
- package/src/claude/scripts/spec-semantic-model.cjs +396 -0
- package/src/claude/scripts/validate-spec-output.cjs +3110 -218
- package/src/claude/scripts/workflow-policy.cjs +501 -183
- package/src/claude/settings/settings.json +4 -0
- package/src/claude/skills/code-review/SKILL.md +12 -3
- package/src/claude/skills/code-review/references/spec-compliance-review.md +10 -2
- package/src/claude/skills/code-review/references/verification-gate.md +13 -0
- package/src/claude/skills/develop/SKILL.md +47 -60
- package/src/claude/skills/develop/references/parallel-waves.md +9 -6
- package/src/claude/skills/develop/references/quality-gate.md +19 -12
- package/src/claude/skills/specs/SKILL.md +183 -177
- package/src/claude/skills/specs/references/ask-user-question-gates.md +27 -18
- package/src/claude/skills/specs/references/cross-spec-dependency.md +8 -4
- package/src/claude/skills/specs/references/research-strategy.md +4 -1
- package/src/claude/skills/specs/references/review.md +214 -262
- package/src/claude/skills/specs/references/scope-inquiry.md +18 -5
- package/src/claude/skills/specs/rules/design-discovery-full.md +33 -81
- package/src/claude/skills/specs/rules/design-discovery-light.md +21 -42
- package/src/claude/skills/specs/rules/design-principles.md +136 -180
- package/src/claude/skills/specs/rules/design-review.md +42 -97
- package/src/claude/skills/specs/rules/ears-format.md +42 -50
- package/src/claude/skills/specs/rules/phase-decision-matrix.md +42 -41
- package/src/claude/skills/specs/rules/task-scoring-rubric.md +2 -1
- package/src/claude/skills/specs/rules/tasks-generation.md +189 -300
- package/src/claude/skills/specs/templates/design.md +49 -263
- package/src/claude/skills/specs/templates/requirements.md +26 -36
- package/src/claude/skills/specs/templates/research.md +9 -98
- package/src/claude/skills/specs/templates/spec-state.json +35 -85
- package/src/claude/skills/specs/templates/task.md +30 -102
- package/src/claude/skills/sync/SKILL.md +33 -10
- package/src/claude/skills/sync/references/sync-protocols.md +31 -13
- package/src/claude/skills/test/SKILL.md +17 -7
- package/src/codex/AGENTS.md +6 -0
- package/src/codex/hooks/completion-authority-check.cjs +43 -240
- package/src/codex/hooks/completion-authority-state.cjs +10 -8
- package/src/codex/hooks/completion-authority.cjs +13 -7
- package/src/codex/hooks/lib/hook-context.cjs +16 -2
- package/src/codex/hooks/lib/privacy-command-analysis.cjs +3 -0
- package/src/codex/hooks/lib/privacy-state.cjs +61 -38
- package/src/codex/hooks/lib/runtime-path-safety.cjs +3 -0
- package/src/codex/hooks/lib/spec-receipt.cjs +72 -134
- package/src/codex/hooks/lib/spec-utils.cjs +56 -5
- package/src/codex/hooks/privacy-approval.cjs +6 -2
- package/src/codex/hooks/privacy-block.cjs +94 -15
- package/src/codex/hooks/semantic-review-authority.cjs +130 -0
- package/src/codex/hooks/spec-gate.cjs +49 -34
- package/src/codex/hooks/spec-state.cjs +10 -3
- package/src/codex/hooks/state.cjs +2 -0
- package/src/codex/hooks.json +6 -1
- package/src/codex/rules/state-sync.md +47 -27
- package/src/common/AGENTS.md +1 -1
|
@@ -250,9 +250,7 @@ function isPathInsideLegacy(parent, child) {
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
function explicitTargetValue(value) {
|
|
253
|
-
|
|
254
|
-
const trimmed = value.trim();
|
|
255
|
-
return trimmed ? trimmed : null;
|
|
253
|
+
return typeof value === 'string' ? value.trim() : value;
|
|
256
254
|
}
|
|
257
255
|
|
|
258
256
|
/**
|
|
@@ -265,12 +263,14 @@ function extractExplicitTarget(...sources) {
|
|
|
265
263
|
if (!source || typeof source !== 'object') continue;
|
|
266
264
|
|
|
267
265
|
for (const key of ['explicitFeature', 'featureName', 'feature']) {
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
267
|
+
return { explicitFeature: explicitTargetValue(source[key]) };
|
|
268
|
+
}
|
|
270
269
|
}
|
|
271
270
|
for (const key of ['explicitPath', 'specPath', 'spec_path', 'featurePath']) {
|
|
272
|
-
|
|
273
|
-
|
|
271
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
272
|
+
return { explicitPath: explicitTargetValue(source[key]) };
|
|
273
|
+
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
const target = source.target;
|
|
@@ -278,8 +278,8 @@ function extractExplicitTarget(...sources) {
|
|
|
278
278
|
const nested = extractExplicitTarget(target);
|
|
279
279
|
if (nested) return nested;
|
|
280
280
|
}
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
if (Object.prototype.hasOwnProperty.call(source, 'target')) {
|
|
282
|
+
const targetValue = explicitTargetValue(target);
|
|
283
283
|
return /[\\/]/.test(targetValue) || /(?:^|[\\/])spec\.json$/.test(targetValue)
|
|
284
284
|
? { explicitPath: targetValue }
|
|
285
285
|
: { explicitFeature: targetValue };
|
|
@@ -302,14 +302,23 @@ function resolveActiveSpec({ projectRoot, runtime, explicitFeature, explicitPath
|
|
|
302
302
|
if (!projectRoot) throw new TypeError('projectRoot required');
|
|
303
303
|
const rt = runtime || {};
|
|
304
304
|
const normalizedTarget = extractExplicitTarget(target);
|
|
305
|
-
explicitFeature
|
|
306
|
-
|
|
305
|
+
if (explicitFeature === undefined && normalizedTarget
|
|
306
|
+
&& Object.prototype.hasOwnProperty.call(normalizedTarget, 'explicitFeature')) {
|
|
307
|
+
explicitFeature = normalizedTarget.explicitFeature;
|
|
308
|
+
}
|
|
309
|
+
if (explicitPath === undefined && normalizedTarget
|
|
310
|
+
&& Object.prototype.hasOwnProperty.call(normalizedTarget, 'explicitPath')) {
|
|
311
|
+
explicitPath = normalizedTarget.explicitPath;
|
|
312
|
+
}
|
|
313
|
+
const hasExplicitFeature = explicitFeature !== undefined && explicitFeature !== null;
|
|
314
|
+
const hasExplicitPath = explicitPath !== undefined && explicitPath !== null;
|
|
315
|
+
const hasExplicitTarget = hasExplicitFeature || hasExplicitPath;
|
|
307
316
|
let specsDir;
|
|
308
317
|
try {
|
|
309
318
|
specsDir = specsDirectory(projectRoot, rt);
|
|
310
319
|
} catch (error) {
|
|
311
320
|
return {
|
|
312
|
-
error:
|
|
321
|
+
error: hasExplicitTarget ? 'explicit_malformed' : 'invalid_specs',
|
|
313
322
|
candidates: ['<specs>'],
|
|
314
323
|
explicitFeature,
|
|
315
324
|
explicitPath,
|
|
@@ -319,7 +328,7 @@ function resolveActiveSpec({ projectRoot, runtime, explicitFeature, explicitPath
|
|
|
319
328
|
let canonicalSpecs;
|
|
320
329
|
const specsLstat = lstatOptional(specsDir);
|
|
321
330
|
if (specsLstat.error) {
|
|
322
|
-
if (
|
|
331
|
+
if (hasExplicitTarget) {
|
|
323
332
|
return { error: 'explicit_malformed', explicitFeature, explicitPath, reason: `specs lstat error: ${specsLstat.error.message}` };
|
|
324
333
|
}
|
|
325
334
|
return { error: 'invalid_specs', candidates: ['<specs>'], invalid: [{ featureName: '<specs>', reason: `specs lstat error: ${specsLstat.error.message}`, specFile: specsDir }], reason: `Invalid spec JSON: <specs>: specs lstat error: ${specsLstat.error.message}` };
|
|
@@ -330,14 +339,14 @@ function resolveActiveSpec({ projectRoot, runtime, explicitFeature, explicitPath
|
|
|
330
339
|
try {
|
|
331
340
|
canonicalSpecs = fs.realpathSync(specsDir);
|
|
332
341
|
} catch (e) {
|
|
333
|
-
if (
|
|
342
|
+
if (hasExplicitTarget) {
|
|
334
343
|
return { error: 'explicit_malformed', explicitFeature, explicitPath, reason: `specs root canonicalization error: ${e.message}` };
|
|
335
344
|
}
|
|
336
345
|
return { error: 'invalid_specs', candidates: ['<specs>'], invalid: [{ featureName: '<specs>', reason: `specs root canonicalization error: ${e.message}`, specFile: specsDir }], reason: `Invalid spec JSON: <specs>: specs root canonicalization error: ${e.message}` };
|
|
337
346
|
}
|
|
338
347
|
}
|
|
339
348
|
|
|
340
|
-
if (
|
|
349
|
+
if (hasExplicitFeature) {
|
|
341
350
|
if (typeof explicitFeature !== 'string' || explicitFeature.trim() === '' || explicitFeature.includes('/') || explicitFeature.includes('\\') || explicitFeature.includes('..')) {
|
|
342
351
|
return { error: 'explicit_malformed', explicitFeature, reason: `malformed feature name: ${explicitFeature}` };
|
|
343
352
|
}
|
|
@@ -367,7 +376,7 @@ function resolveActiveSpec({ projectRoot, runtime, explicitFeature, explicitPath
|
|
|
367
376
|
}
|
|
368
377
|
}
|
|
369
378
|
|
|
370
|
-
if (
|
|
379
|
+
if (hasExplicitPath) {
|
|
371
380
|
if (typeof explicitPath !== 'string' || explicitPath.trim() === '') {
|
|
372
381
|
return { error: 'explicit_malformed', explicitPath, reason: 'empty explicit path' };
|
|
373
382
|
}
|
|
@@ -441,10 +450,52 @@ function resolveActiveSpec({ projectRoot, runtime, explicitFeature, explicitPath
|
|
|
441
450
|
};
|
|
442
451
|
}
|
|
443
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Resolve one persisted feature identity. Explicit host targets are inspected
|
|
455
|
+
* directly and never scan siblings; only the no-target path performs a global
|
|
456
|
+
* persisted-candidate scan and therefore owns ambiguity/invalid-sibling errors.
|
|
457
|
+
*/
|
|
458
|
+
function resolvePersistedSpec({ projectRoot, runtime, explicitFeature, explicitPath, target } = {}) {
|
|
459
|
+
const normalized = extractExplicitTarget(
|
|
460
|
+
target,
|
|
461
|
+
explicitFeature !== undefined ? { explicitFeature } : null,
|
|
462
|
+
explicitPath !== undefined ? { explicitPath } : null,
|
|
463
|
+
);
|
|
464
|
+
if (normalized) {
|
|
465
|
+
const value = Object.prototype.hasOwnProperty.call(normalized, 'explicitFeature')
|
|
466
|
+
? normalized.explicitFeature
|
|
467
|
+
: normalized.explicitPath;
|
|
468
|
+
if (value === null || value === undefined) {
|
|
469
|
+
return { error: 'explicit_malformed', ...normalized, reason: 'explicit target must be a non-empty string' };
|
|
470
|
+
}
|
|
471
|
+
return resolveActiveSpec({ projectRoot, runtime, ...normalized });
|
|
472
|
+
}
|
|
473
|
+
try {
|
|
474
|
+
const candidates = findAllSpecCandidates(projectRoot, runtime);
|
|
475
|
+
if (candidates.length === 0) return null;
|
|
476
|
+
if (candidates.length === 1) return candidates[0];
|
|
477
|
+
return {
|
|
478
|
+
error: 'multiple_persisted',
|
|
479
|
+
candidates: candidates.map((candidate) => candidate.featureName),
|
|
480
|
+
reason: `Multiple persisted specs found: ${candidates.map((candidate) => candidate.featureName).join(', ')}. Provide explicit feature.`,
|
|
481
|
+
};
|
|
482
|
+
} catch (error) {
|
|
483
|
+
return {
|
|
484
|
+
error: 'invalid_specs',
|
|
485
|
+
candidates: Array.isArray(error.invalid)
|
|
486
|
+
? error.invalid.map((entry) => entry.featureName)
|
|
487
|
+
: ['<specs>'],
|
|
488
|
+
invalid: error.invalid || [],
|
|
489
|
+
reason: error.message,
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
444
494
|
module.exports = {
|
|
445
495
|
specsDirectory,
|
|
446
496
|
findAllActiveSpecs,
|
|
447
497
|
findAllSpecCandidates,
|
|
448
498
|
extractExplicitTarget,
|
|
449
499
|
resolveActiveSpec,
|
|
500
|
+
resolvePersistedSpec,
|
|
450
501
|
};
|