@haposoft/cafekit 0.16.0-rc.1 → 0.16.0-rc.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/bin/__tests__/codex-hooks.test.js +355 -12
- package/bin/__tests__/codex-native.test.js +1 -1
- package/bin/__tests__/develop-contract.test.js +1374 -78
- package/bin/__tests__/installer-safety.test.js +43 -29
- package/bin/__tests__/opencode-spec-gate.test.js +791 -0
- package/bin/__tests__/package-inventory.test.js +157 -0
- package/bin/__tests__/validator-grounding.test.js +707 -2
- package/package.json +1 -1
- package/src/claude/agents/code-auditor.md +8 -1
- package/src/claude/agents/spec-maker.md +107 -200
- package/src/claude/hooks/__tests__/completion-authority.test.js +720 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +511 -38
- package/src/claude/hooks/completion-authority-check.cjs +307 -0
- package/src/claude/hooks/completion-authority-state.cjs +525 -0
- package/src/claude/hooks/completion-authority.cjs +148 -0
- package/src/claude/hooks/session.cjs +33 -19
- package/src/claude/hooks/spec-gate.cjs +173 -61
- package/src/claude/hooks/spec-state.cjs +104 -45
- package/src/claude/migration-manifest.json +6 -1
- package/src/claude/scripts/provenance.cjs +315 -0
- package/src/claude/scripts/spec-resolver.cjs +450 -0
- package/src/claude/scripts/spec-scaffold.cjs +716 -41
- package/src/claude/scripts/validate-spec-output.cjs +355 -53
- package/src/claude/scripts/workflow-policy.cjs +1529 -162
- package/src/claude/settings/settings.json +8 -0
- package/src/claude/skills/backend-development/references/backend-security.md +52 -0
- package/src/claude/skills/code-review/SKILL.md +85 -66
- package/src/claude/skills/develop/SKILL.md +153 -285
- package/src/claude/skills/develop/references/quality-gate.md +112 -124
- package/src/claude/skills/develop/references/subagent-patterns.md +42 -37
- package/src/claude/skills/specs/SKILL.md +170 -381
- package/src/claude/skills/specs/rules/task-scoring-rubric.md +45 -46
- package/src/claude/skills/specs/rules/tasks-generation.md +49 -20
- package/src/claude/skills/specs/templates/spec-state.json +23 -2
- package/src/claude/skills/specs/templates/task.md +20 -0
- package/src/claude/skills/sync/SKILL.md +15 -8
- package/src/claude/skills/sync/references/sync-protocols.md +4 -4
- package/src/claude/skills/test/SKILL.md +141 -167
- package/src/codex/hooks/completion-authority-check.cjs +260 -0
- package/src/codex/hooks/completion-authority-state.cjs +525 -0
- package/src/codex/hooks/completion-authority.cjs +100 -0
- package/src/codex/hooks/lib/hook-context.cjs +42 -2
- package/src/codex/hooks/lib/spec-receipt.cjs +76 -43
- package/src/codex/hooks/lib/spec-utils.cjs +53 -27
- package/src/codex/hooks/session.cjs +2 -0
- package/src/codex/hooks/spec-gate.cjs +132 -20
- package/src/codex/hooks/spec-state.cjs +56 -10
- package/src/codex/hooks.json +10 -0
- package/src/opencode/AGENTS.md +4 -2
- package/src/opencode/plugins/spec-gate.ts +296 -122
- package/src/opencode/plugins/spec-state.ts +183 -116
|
@@ -761,50 +761,64 @@ test('copyRecursive skips generated artifacts while copying normal files', () =>
|
|
|
761
761
|
});
|
|
762
762
|
});
|
|
763
763
|
|
|
764
|
-
test('OpenCode
|
|
764
|
+
test('OpenCode gate uses a real before-hook block and documents the host boundary', () => {
|
|
765
765
|
const opencodeAgents = fs.readFileSync(path.join(__dirname, '../../src/opencode/AGENTS.md'), 'utf8');
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
766
|
+
const assertOpenCodeBoundary = (content) => {
|
|
767
|
+
assert.match(content, /tool\.execute\.before/);
|
|
768
|
+
assert.match(content, /hard-block supported completion\/state tools/);
|
|
769
|
+
assert.match(content, /`task`, `taskupdate`, and `todowrite`/);
|
|
770
|
+
assert.match(content, /CAFEKIT_SPEC_GATE_BLOCKED/);
|
|
771
|
+
assert.match(content, /`session\.idle`\/Stop/);
|
|
772
|
+
assert.match(content, /final assistant-turn cancellation boundary/);
|
|
773
|
+
assert.match(content, /observational only/);
|
|
774
|
+
assert.match(content, /full-turn parity with Claude\/Codex/);
|
|
775
|
+
assert.doesNotMatch(content, /tool\.execute\.after/);
|
|
776
|
+
assert.doesNotMatch(content, /best-effort/);
|
|
777
|
+
assert.doesNotMatch(content, /tier-2/);
|
|
778
|
+
assert.doesNotMatch(content, /\badvisory\b/i);
|
|
779
|
+
};
|
|
780
|
+
assertOpenCodeBoundary(opencodeAgents);
|
|
781
|
+
|
|
777
782
|
const pluginPath = path.join(__dirname, '../../src/opencode/plugins/spec-gate.ts');
|
|
778
|
-
assert.equal(fs.existsSync(pluginPath), true, 'OpenCode spec-gate plugin must exist
|
|
783
|
+
assert.equal(fs.existsSync(pluginPath), true, 'OpenCode spec-gate plugin must exist');
|
|
779
784
|
const plugin = fs.readFileSync(pluginPath, 'utf8');
|
|
780
|
-
assert.match(plugin, /advisory/i);
|
|
781
785
|
assert.match(plugin, /completion_gate/);
|
|
782
|
-
assert.match(plugin, /
|
|
783
|
-
assert.match(plugin, /
|
|
786
|
+
assert.match(plugin, /tool\.execute\.before/);
|
|
787
|
+
assert.match(plugin, /CAFEKIT_SPEC_GATE_BLOCKED/);
|
|
788
|
+
assert.match(plugin, /throw createBlockError/);
|
|
789
|
+
assert.match(plugin, /session\.idle/);
|
|
790
|
+
assert.match(plugin, /final assistant message[\s\S]*outside this adapter's boundary/);
|
|
791
|
+
assert.doesNotMatch(plugin, /advisory/i);
|
|
792
|
+
assert.doesNotMatch(plugin, /fail-open/i);
|
|
784
793
|
// JSDoc-safe wording: must not contain block-comment-closing pattern specs/*/spec.json
|
|
785
794
|
assert.doesNotMatch(plugin, /specs\/\*\/spec\.json/);
|
|
786
|
-
|
|
787
|
-
// traversal check must be sibling-prefix safe (resolve + relative, not simple startsWith)
|
|
795
|
+
// Traversal check must be sibling-prefix safe (resolve + relative, not simple startsWith).
|
|
788
796
|
assert.match(plugin, /relative\s*\(\s*resolvedFeatureDir/);
|
|
789
797
|
assert.match(plugin, /isAbsolute/);
|
|
790
798
|
assert.doesNotMatch(plugin, /if \(!abs\.startsWith\(featureDir\)\)/);
|
|
791
|
-
//
|
|
792
|
-
assert.match(plugin, /
|
|
793
|
-
assert.match(plugin, /
|
|
794
|
-
assert.match(plugin, /
|
|
795
|
-
|
|
796
|
-
assert.
|
|
797
|
-
|
|
798
|
-
assert.match(plugin, /head_sha\\s\*:\[ \\t\]\*\\S/);
|
|
799
|
-
// shipped docs must not claim OpenCode parity for hard completion gate
|
|
799
|
+
// Single executable authorities: OpenCode delegates both validation and resolution.
|
|
800
|
+
assert.match(plugin, /workflow-policy\.cjs/);
|
|
801
|
+
assert.match(plugin, /spec-resolver\.cjs/);
|
|
802
|
+
assert.match(plugin, /getSharedValidate|validateCanonicalReceipt/);
|
|
803
|
+
assert.doesNotMatch(plugin, /const hasBase\s*&&\s*hasHead/);
|
|
804
|
+
assert.doesNotMatch(plugin, /PLACEHOLDER_TOKENS/);
|
|
805
|
+
|
|
800
806
|
const installerDocs = fs.readFileSync(path.join(__dirname, '../../../../docs/installer-architecture.md'), 'utf8');
|
|
801
807
|
assert.doesNotMatch(installerDocs, /OpenCode.*hard.*completion gate/i);
|
|
802
|
-
|
|
808
|
+
|
|
809
|
+
// Combined install must copy the plugin and both shared authorities.
|
|
803
810
|
inTempProject((root) => {
|
|
804
811
|
const result = spawnSync(process.execPath, [INSTALLER, '--platform', 'opencode', '--yes'], { cwd: root, encoding: 'utf8', env: { ...process.env, PATH: '/usr/bin:/bin' } });
|
|
805
812
|
assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}`);
|
|
806
813
|
assert.equal(fs.existsSync(path.join(root, '.opencode/plugins/spec-gate.ts')), true);
|
|
814
|
+
assert.equal(fs.existsSync(path.join(root, '.opencode/scripts/workflow-policy.cjs')), true);
|
|
815
|
+
assert.equal(fs.existsSync(path.join(root, '.opencode/scripts/spec-resolver.cjs')), true);
|
|
816
|
+
const installedAgents = fs.readFileSync(path.join(root, 'AGENTS.md'), 'utf8');
|
|
817
|
+
assertOpenCodeBoundary(managedBody(installedAgents, OPENCODE_START, OPENCODE_END));
|
|
807
818
|
const installed = fs.readFileSync(path.join(root, '.opencode/plugins/spec-gate.ts'), 'utf8');
|
|
808
|
-
assert.match(installed, /
|
|
819
|
+
assert.match(installed, /tool\.execute\.before/);
|
|
820
|
+
assert.match(installed, /CAFEKIT_SPEC_GATE_BLOCKED/);
|
|
821
|
+
assert.match(installed, /workflow-policy\.cjs/);
|
|
822
|
+
assert.match(installed, /spec-resolver\.cjs/);
|
|
809
823
|
});
|
|
810
824
|
});
|