@haposoft/cafekit 0.16.0-rc.7 → 0.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 +116 -27
- package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
- package/bin/__tests__/codex-hooks.test.js +295 -0
- package/bin/__tests__/codex-native.test.js +2289 -34
- package/bin/__tests__/develop-contract.test.js +400 -23
- package/bin/__tests__/installer-safety.test.js +3 -3
- package/bin/__tests__/optional-skill-inventory.test.js +249 -0
- package/bin/__tests__/output-styles.test.js +214 -0
- package/bin/__tests__/package-inventory.test.js +2131 -16
- package/bin/__tests__/runtime-schema.test.js +111 -0
- package/bin/__tests__/secret-output-guardrail.test.js +122 -0
- package/bin/__tests__/skill-routing-source.test.js +172 -0
- package/bin/__tests__/specs-v2-execution-closeout.test.js +1 -1
- package/bin/install.js +10 -0
- package/bin/lib/codex-install.js +170 -5
- package/bin/lib/context.js +14 -0
- package/bin/lib/i18n.js +12 -6
- package/bin/lib/skill-deps.js +5 -5
- package/bin/phases/claude-runtime.js +23 -0
- package/bin/phases/claude-settings.js +8 -0
- package/bin/phases/codex-hooks.js +156 -0
- package/bin/phases/codex-runtime.js +29 -38
- package/bin/phases/copy-payload.js +8 -2
- package/bin/phases/select-skill-bundles.js +96 -0
- package/bin/phases/skill-inventory.js +71 -0
- package/bin/phases/skills-setup.js +9 -2
- package/bin/phases/write-metadata.js +8 -5
- package/package.json +8 -2
- package/src/claude/CLAUDE.md +3 -3
- package/src/claude/agents/brainstormer.md +52 -69
- package/src/claude/agents/code-auditor.md +32 -14
- package/src/claude/agents/debugger.md +35 -20
- package/src/claude/agents/deployer.md +12 -5
- package/src/claude/agents/docs-keeper.md +11 -1
- package/src/claude/agents/implementer.md +25 -13
- package/src/claude/agents/inspector.md +6 -3
- package/src/claude/agents/project-manager.md +1 -1
- package/src/claude/agents/researcher.md +26 -55
- package/src/claude/agents/spec-maker.md +24 -13
- package/src/claude/agents/strategist.md +52 -0
- package/src/claude/agents/test-runner.md +117 -132
- package/src/claude/agents/ui-ux-designer.md +1 -1
- package/src/claude/hooks/__tests__/fixtures/statusline-default.golden +1 -0
- package/src/claude/hooks/__tests__/precompact.test.js +158 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +87 -4
- package/src/claude/hooks/__tests__/state.test.js +254 -3
- package/src/claude/hooks/__tests__/statusline.test.js +196 -0
- package/src/claude/hooks/agent.cjs +1 -1
- package/src/claude/hooks/docs-sync.cjs +12 -10
- package/src/claude/hooks/inspect-block.cjs +1 -1
- package/src/claude/hooks/lib/config.cjs +3 -0
- package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
- package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
- package/src/claude/hooks/precompact.cjs +105 -0
- package/src/claude/hooks/rules.cjs +1 -1
- package/src/claude/hooks/secret-output-guardrail.cjs +43 -0
- package/src/claude/hooks/session.cjs +27 -1
- package/src/claude/hooks/spec-gate.cjs +3 -3
- package/src/claude/hooks/spec-state.cjs +32 -5
- package/src/claude/hooks/state.cjs +1 -1
- package/src/claude/hooks/task-scaffold-guard.cjs +1 -1
- package/src/claude/hooks/usage.cjs +1 -1
- package/src/claude/migration-manifest.json +29 -15
- package/src/claude/output-styles/coding-level-0-eli5.md +103 -0
- package/src/claude/output-styles/coding-level-1-junior.md +124 -0
- package/src/claude/output-styles/coding-level-2-mid.md +146 -0
- package/src/claude/output-styles/coding-level-3-senior.md +148 -0
- package/src/claude/output-styles/coding-level-4-lead.md +159 -0
- package/src/claude/output-styles/coding-level-5-god.md +91 -0
- package/src/claude/references/debugger/core-philosophy.md +5 -3
- package/src/claude/references/debugger/frontend-verification.md +2 -2
- package/src/claude/references/debugger/log-ci-analysis.md +13 -1
- package/src/claude/references/debugger/parallel-agent-hydration.md +19 -34
- package/src/claude/references/debugger/performance-diagnostics.md +2 -2
- package/src/claude/references/debugger/root-cause-tracing.md +37 -6
- package/src/claude/references/debugger/side-effect-gate.md +3 -1
- package/src/claude/references/debugger/verification-protocol.md +13 -12
- package/src/claude/rules/orchestrator.md +7 -1
- package/src/claude/rules/process-management.md +39 -0
- package/src/claude/rules/review-audit-self-decision.md +48 -0
- package/src/claude/rules/skill-domain-routing.md +26 -24
- package/src/claude/rules/skill-workflow-routing.md +22 -14
- package/src/claude/rules/workflow.md +3 -3
- package/src/claude/runtime.json +1 -0
- package/src/claude/runtime.schema.json +205 -0
- package/src/claude/scripts/generate-skill-catalog.cjs +156 -122
- package/src/claude/scripts/provenance.cjs +18 -5
- package/src/claude/scripts/spec-receipt.cjs +76 -21
- package/src/claude/scripts/spec-resolver.cjs +144 -4
- package/src/claude/scripts/workflow-policy.cjs +1 -1
- package/src/claude/settings/settings.json +16 -0
- package/src/claude/skills/agent-browser/SKILL.md +1 -1
- package/src/claude/skills/ai-multimodal/SKILL.md +1 -1
- package/src/claude/skills/brainstorm/SKILL.md +193 -172
- package/src/claude/skills/brainstorm/references/question-framework.md +105 -167
- package/src/claude/skills/chrome-devtools/SKILL.md +1 -1
- package/src/claude/skills/code-review/SKILL.md +43 -25
- package/src/claude/skills/code-review/references/spec-compliance-review.md +3 -4
- package/src/claude/skills/code-review/references/verification-gate.md +1 -1
- package/src/claude/skills/debug/SKILL.md +48 -19
- package/src/claude/skills/delegate/SKILL.md +1 -1
- package/src/claude/skills/develop/SKILL.md +92 -65
- package/src/claude/skills/develop/references/parallel-waves.md +36 -63
- package/src/claude/skills/develop/references/quality-gate.md +31 -4
- package/src/claude/skills/develop/references/subagent-patterns.md +21 -7
- package/src/claude/skills/docs/SKILL.md +42 -23
- package/src/claude/skills/docs/references/init-workflow.md +4 -4
- package/src/claude/skills/docs/references/reconstruct-workflow.md +6 -6
- package/src/claude/skills/docs/references/standard-docs-workflow.md +6 -2
- package/src/claude/skills/docs/references/summarize-workflow.md +2 -2
- package/src/claude/skills/docs/references/update-workflow.md +9 -7
- package/src/claude/skills/docs/templates/requirements-as-is.md +1 -1
- package/src/claude/skills/docx/SKILL.md +1 -1
- package/src/claude/skills/git/SKILL.md +1 -1
- package/src/claude/skills/git/references/commit-protocols.md +1 -1
- package/src/claude/skills/git/references/finish-branch.md +1 -1
- package/src/claude/skills/hotfix/SKILL.md +159 -170
- package/src/claude/skills/hotfix/references/diagnosis-protocol.md +14 -9
- package/src/claude/skills/hotfix/references/parallel-patterns.md +27 -13
- package/src/claude/skills/hotfix/references/prevention-gate.md +5 -0
- package/src/claude/skills/hotfix/references/review-cycle.md +21 -15
- package/src/claude/skills/hotfix/references/workflow-specialized.md +53 -21
- package/src/claude/skills/inspect/SKILL.md +55 -46
- package/src/claude/skills/inspect/references/internal-inspection.md +21 -5
- package/src/claude/skills/loop/SKILL.md +114 -0
- package/src/claude/skills/loop/references/bounded-loop-protocol.md +104 -0
- package/src/claude/skills/loop/references/metric-and-guard-contract.md +76 -0
- package/src/claude/skills/pdf/SKILL.md +1 -1
- package/src/claude/skills/pptx/SKILL.md +1 -1
- package/src/claude/skills/question/SKILL.md +16 -13
- package/src/claude/skills/research/SKILL.md +70 -43
- package/src/claude/skills/route/SKILL.md +94 -0
- package/src/claude/skills/route/references/agent-timing.md +46 -0
- package/src/claude/skills/route/references/chaining-patterns.md +53 -0
- package/src/claude/skills/route/references/task-taxonomy.md +48 -0
- package/src/claude/skills/specs/SKILL.md +48 -57
- package/src/claude/skills/specs/references/review.md +26 -8
- package/src/claude/skills/specs/references/templates.md +76 -31
- package/src/claude/skills/specs/templates/requirements-init.md +1 -1
- package/src/claude/skills/specs/templates/research.md +2 -2
- package/src/claude/skills/sync/SKILL.md +6 -6
- package/src/claude/skills/sync/references/sync-protocols.md +1 -1
- package/src/claude/skills/test/SKILL.md +120 -120
- package/src/claude/skills/test/references/execution-strategy.md +208 -361
- package/src/claude/skills/test/references/failure-triage.md +55 -121
- package/src/claude/skills/test/references/test-memory.md +20 -34
- package/src/claude/skills/ui-ux-pro-max/SKILL.md +1 -1
- package/src/claude/skills/web-testing/SKILL.md +1 -1
- package/src/claude/skills/xlsx/SKILL.md +1 -1
- package/src/claude/status.cjs +135 -33
- package/src/codex/AGENTS.md +14 -4
- package/src/codex/hooks/docs-sync.cjs +8 -3
- package/src/codex/hooks/lib/hook-context.cjs +18 -4
- package/src/codex/hooks/rules.cjs +29 -1
- package/src/codex/hooks/secret-output-guardrail.cjs +30 -0
- package/src/codex/hooks/spec-gate.cjs +3 -8
- package/src/codex/hooks/spec-state.cjs +34 -5
- package/src/codex/hooks.json +5 -0
- package/src/codex/runtime.json +2 -0
- package/src/common/.env.example +1 -1
- package/src/claude/skills/backend-development/SKILL.md +0 -101
- package/src/claude/skills/backend-development/references/backend-api-design.md +0 -495
- package/src/claude/skills/backend-development/references/backend-architecture.md +0 -454
- package/src/claude/skills/backend-development/references/backend-authentication.md +0 -338
- package/src/claude/skills/backend-development/references/backend-code-quality.md +0 -659
- package/src/claude/skills/backend-development/references/backend-debugging.md +0 -904
- package/src/claude/skills/backend-development/references/backend-devops.md +0 -491
- package/src/claude/skills/backend-development/references/backend-mindset.md +0 -387
- package/src/claude/skills/backend-development/references/backend-performance.md +0 -397
- package/src/claude/skills/backend-development/references/backend-security.md +0 -342
- package/src/claude/skills/backend-development/references/backend-technologies.md +0 -256
- package/src/claude/skills/backend-development/references/backend-testing.md +0 -429
- package/src/claude/skills/devops/.env.example +0 -76
- package/src/claude/skills/devops/SKILL.md +0 -102
- package/src/claude/skills/devops/references/browser-rendering.md +0 -305
- package/src/claude/skills/devops/references/cloudflare-d1-kv.md +0 -123
- package/src/claude/skills/devops/references/cloudflare-platform.md +0 -271
- package/src/claude/skills/devops/references/cloudflare-r2-storage.md +0 -280
- package/src/claude/skills/devops/references/cloudflare-workers-advanced.md +0 -312
- package/src/claude/skills/devops/references/cloudflare-workers-apis.md +0 -309
- package/src/claude/skills/devops/references/cloudflare-workers-basics.md +0 -418
- package/src/claude/skills/devops/references/docker-basics.md +0 -297
- package/src/claude/skills/devops/references/docker-compose.md +0 -292
- package/src/claude/skills/devops/references/gcloud-platform.md +0 -297
- package/src/claude/skills/devops/references/gcloud-services.md +0 -304
- package/src/claude/skills/devops/references/kubernetes-basics.md +0 -95
- package/src/claude/skills/devops/references/kubernetes-helm-advanced.md +0 -70
- package/src/claude/skills/devops/references/kubernetes-helm.md +0 -81
- package/src/claude/skills/devops/references/kubernetes-kubectl.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-security-advanced.md +0 -94
- package/src/claude/skills/devops/references/kubernetes-security.md +0 -89
- package/src/claude/skills/devops/references/kubernetes-troubleshooting-advanced.md +0 -74
- package/src/claude/skills/devops/references/kubernetes-troubleshooting.md +0 -49
- package/src/claude/skills/devops/references/kubernetes-workflows-advanced.md +0 -75
- package/src/claude/skills/devops/references/kubernetes-workflows.md +0 -76
- package/src/claude/skills/devops/scripts/cloudflare_deploy.py +0 -269
- package/src/claude/skills/devops/scripts/docker_optimize.py +0 -332
- package/src/claude/skills/devops/scripts/requirements.txt +0 -20
- package/src/claude/skills/devops/scripts/tests/requirements.txt +0 -3
- package/src/claude/skills/devops/scripts/tests/test_cloudflare_deploy.py +0 -285
- package/src/claude/skills/devops/scripts/tests/test_docker_optimize.py +0 -436
- package/src/claude/skills/frontend-design/SKILL.md +0 -135
- package/src/claude/skills/frontend-design/references/ai-multimodal-overview.md +0 -165
- package/src/claude/skills/frontend-design/references/analysis-best-practices.md +0 -80
- package/src/claude/skills/frontend-design/references/analysis-prompts.md +0 -141
- package/src/claude/skills/frontend-design/references/analysis-techniques.md +0 -118
- package/src/claude/skills/frontend-design/references/animejs.md +0 -396
- package/src/claude/skills/frontend-design/references/anti-slop-rules.md +0 -103
- package/src/claude/skills/frontend-design/references/asset-generation.md +0 -337
- package/src/claude/skills/frontend-design/references/bento-motion-engine.md +0 -142
- package/src/claude/skills/frontend-design/references/design-extraction-overview.md +0 -71
- package/src/claude/skills/frontend-design/references/extraction-best-practices.md +0 -141
- package/src/claude/skills/frontend-design/references/extraction-output-templates.md +0 -162
- package/src/claude/skills/frontend-design/references/extraction-prompts.md +0 -127
- package/src/claude/skills/frontend-design/references/magicui-components.md +0 -129
- package/src/claude/skills/frontend-design/references/performance-guardrails.md +0 -169
- package/src/claude/skills/frontend-design/references/premium-design-patterns.md +0 -93
- package/src/claude/skills/frontend-design/references/redesign-audit-checklist.md +0 -114
- package/src/claude/skills/frontend-design/references/technical-accessibility.md +0 -119
- package/src/claude/skills/frontend-design/references/technical-best-practices.md +0 -97
- package/src/claude/skills/frontend-design/references/technical-optimization.md +0 -44
- package/src/claude/skills/frontend-design/references/technical-overview.md +0 -90
- package/src/claude/skills/frontend-design/references/technical-workflows.md +0 -150
- package/src/claude/skills/frontend-design/references/visual-analysis-overview.md +0 -95
- package/src/claude/skills/frontend-design/references/workflow-3d.md +0 -102
- package/src/claude/skills/frontend-design/references/workflow-describe.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-immersive.md +0 -87
- package/src/claude/skills/frontend-design/references/workflow-quick.md +0 -57
- package/src/claude/skills/frontend-design/references/workflow-screenshot.md +0 -63
- package/src/claude/skills/frontend-design/references/workflow-video.md +0 -74
- package/src/claude/skills/frontend-development/SKILL.md +0 -406
- package/src/claude/skills/frontend-development/resources/common-patterns.md +0 -331
- package/src/claude/skills/frontend-development/resources/complete-examples.md +0 -872
- package/src/claude/skills/frontend-development/resources/component-patterns.md +0 -502
- package/src/claude/skills/frontend-development/resources/data-fetching.md +0 -767
- package/src/claude/skills/frontend-development/resources/file-organization.md +0 -502
- package/src/claude/skills/frontend-development/resources/loading-and-error-states.md +0 -501
- package/src/claude/skills/frontend-development/resources/performance.md +0 -406
- package/src/claude/skills/frontend-development/resources/routing-guide.md +0 -364
- package/src/claude/skills/frontend-development/resources/styling-guide.md +0 -428
- package/src/claude/skills/frontend-development/resources/typescript-standards.md +0 -418
- package/src/claude/skills/mobile-development/SKILL.md +0 -218
- package/src/claude/skills/mobile-development/references/mobile-android.md +0 -604
- package/src/claude/skills/mobile-development/references/mobile-best-practices.md +0 -544
- package/src/claude/skills/mobile-development/references/mobile-debugging.md +0 -1089
- package/src/claude/skills/mobile-development/references/mobile-frameworks.md +0 -465
- package/src/claude/skills/mobile-development/references/mobile-ios.md +0 -496
- package/src/claude/skills/mobile-development/references/mobile-mindset.md +0 -542
- package/src/claude/skills/react-best-practices/AGENTS.md +0 -2249
- package/src/claude/skills/react-best-practices/README.md +0 -123
- package/src/claude/skills/react-best-practices/SKILL.md +0 -128
- package/src/claude/skills/react-best-practices/metadata.json +0 -15
- package/src/claude/skills/react-best-practices/rules/_sections.md +0 -46
- package/src/claude/skills/react-best-practices/rules/_template.md +0 -28
- package/src/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/src/claude/skills/react-best-practices/rules/advanced-use-latest.md +0 -49
- package/src/claude/skills/react-best-practices/rules/async-api-routes.md +0 -38
- package/src/claude/skills/react-best-practices/rules/async-defer-await.md +0 -80
- package/src/claude/skills/react-best-practices/rules/async-dependencies.md +0 -36
- package/src/claude/skills/react-best-practices/rules/async-parallel.md +0 -28
- package/src/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/src/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/src/claude/skills/react-best-practices/rules/bundle-conditional.md +0 -31
- package/src/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/src/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/src/claude/skills/react-best-practices/rules/bundle-preload.md +0 -50
- package/src/claude/skills/react-best-practices/rules/client-event-listeners.md +0 -74
- package/src/claude/skills/react-best-practices/rules/client-swr-dedup.md +0 -56
- package/src/claude/skills/react-best-practices/rules/js-batch-dom-css.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-cache-function-results.md +0 -80
- package/src/claude/skills/react-best-practices/rules/js-cache-property-access.md +0 -28
- package/src/claude/skills/react-best-practices/rules/js-cache-storage.md +0 -70
- package/src/claude/skills/react-best-practices/rules/js-combine-iterations.md +0 -32
- package/src/claude/skills/react-best-practices/rules/js-early-exit.md +0 -50
- package/src/claude/skills/react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/src/claude/skills/react-best-practices/rules/js-index-maps.md +0 -37
- package/src/claude/skills/react-best-practices/rules/js-length-check-first.md +0 -49
- package/src/claude/skills/react-best-practices/rules/js-min-max-loop.md +0 -82
- package/src/claude/skills/react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/src/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/src/claude/skills/react-best-practices/rules/rendering-activity.md +0 -26
- package/src/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/src/claude/skills/react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/src/claude/skills/react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/src/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/src/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/src/claude/skills/react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/src/claude/skills/react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/src/claude/skills/react-best-practices/rules/rerender-dependencies.md +0 -45
- package/src/claude/skills/react-best-practices/rules/rerender-derived-state.md +0 -29
- package/src/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/src/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/src/claude/skills/react-best-practices/rules/rerender-memo.md +0 -44
- package/src/claude/skills/react-best-practices/rules/rerender-transitions.md +0 -40
- package/src/claude/skills/react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/src/claude/skills/react-best-practices/rules/server-cache-lru.md +0 -41
- package/src/claude/skills/react-best-practices/rules/server-cache-react.md +0 -26
- package/src/claude/skills/react-best-practices/rules/server-parallel-fetching.md +0 -79
- package/src/claude/skills/react-best-practices/rules/server-serialization.md +0 -38
|
@@ -70,16 +70,138 @@ function candidateError(reason, code = 'malformed') {
|
|
|
70
70
|
|
|
71
71
|
const WORKFLOW_STATUSES = new Set(['pending', 'in_progress', 'paused', 'blocked', 'done']);
|
|
72
72
|
const WORKFLOW_TASK_NAME = /^task-[A-Za-z0-9][A-Za-z0-9._-]*\.md$/;
|
|
73
|
+
const WORKFLOW_CONTRACT = 'process-first-ready-v1';
|
|
74
|
+
|
|
75
|
+
function annotatedMarkdownLines(content) {
|
|
76
|
+
let fence = null;
|
|
77
|
+
return String(content || '').split(/\r?\n/).map((line, index) => {
|
|
78
|
+
const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
|
|
79
|
+
const outsideFence = fence === null && !fenceMatch;
|
|
80
|
+
let fenceEvent = null;
|
|
81
|
+
if (fenceMatch) {
|
|
82
|
+
const marker = fenceMatch[1];
|
|
83
|
+
if (!fence) {
|
|
84
|
+
fence = { char: marker[0], length: marker.length };
|
|
85
|
+
fenceEvent = 'open';
|
|
86
|
+
} else if (marker[0] === fence.char && marker.length >= fence.length && fenceMatch[2].trim() === '') {
|
|
87
|
+
fence = null;
|
|
88
|
+
fenceEvent = 'close';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { index, line, outsideFence, fenceEvent };
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function workflowPlanContract(content) {
|
|
96
|
+
const markers = annotatedMarkdownLines(content)
|
|
97
|
+
.filter(({ line, outsideFence }) => outsideFence && /^\s*Specs-Contract\s*:/i.test(line))
|
|
98
|
+
.map(({ line }) => line);
|
|
99
|
+
if (markers.length === 0) return { workflowContract: null, queueReady: false };
|
|
100
|
+
if (markers.length !== 1 || markers[0] !== `Specs-Contract: ${WORKFLOW_CONTRACT}`) {
|
|
101
|
+
throw candidateError(`plan.md must contain exactly one Specs-Contract: ${WORKFLOW_CONTRACT} marker`);
|
|
102
|
+
}
|
|
103
|
+
return { workflowContract: WORKFLOW_CONTRACT, queueReady: true };
|
|
104
|
+
}
|
|
73
105
|
|
|
74
106
|
function workflowTaskStatus(content, taskName) {
|
|
75
|
-
const
|
|
76
|
-
|
|
107
|
+
const values = annotatedMarkdownLines(content)
|
|
108
|
+
.filter(({ outsideFence }) => outsideFence)
|
|
109
|
+
.map(({ line }) => line.match(/^\s*(?:\*\*)?Status(?:\*\*)?\s*:\s*(?:\*\*)?\s*([A-Za-z_-]+)(?:\*\*)?\s*$/i))
|
|
110
|
+
.filter(Boolean)
|
|
111
|
+
.map((match) => match[1].toLowerCase().replaceAll('-', '_'));
|
|
77
112
|
if (values.length !== 1 || !WORKFLOW_STATUSES.has(values[0])) {
|
|
78
113
|
throw candidateError(`${taskName} must contain exactly one supported Status field`);
|
|
79
114
|
}
|
|
80
115
|
return values[0];
|
|
81
116
|
}
|
|
82
117
|
|
|
118
|
+
function workflowTaskNumericPrefix(taskName) {
|
|
119
|
+
const match = taskName.match(/^task-(\d+)(?:-|\.md$)/);
|
|
120
|
+
return match ? match[1].replace(/^0+(?=\d)/, '') : null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function workflowTaskDependencies(content, taskName, taskNames, queueReady) {
|
|
124
|
+
const lines = annotatedMarkdownLines(content);
|
|
125
|
+
let sectionStart = -1;
|
|
126
|
+
let sectionEnd = lines.length;
|
|
127
|
+
let sectionCount = 0;
|
|
128
|
+
|
|
129
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
130
|
+
if (!lines[index].outsideFence) continue;
|
|
131
|
+
|
|
132
|
+
const heading = lines[index].line.match(/^(#{1,6})\s+(.+?)\s*$/);
|
|
133
|
+
if (!heading || heading[1].length > 2) continue;
|
|
134
|
+
const title = heading[2].trim().toLowerCase();
|
|
135
|
+
if (heading[1].length === 2 && title === 'dependencies') {
|
|
136
|
+
sectionCount += 1;
|
|
137
|
+
if (sectionStart < 0) sectionStart = index + 1;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (sectionStart >= 0 && sectionEnd === lines.length) sectionEnd = index;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!queueReady && sectionCount === 0) return [];
|
|
144
|
+
if (sectionCount !== 1 || sectionStart < 0) {
|
|
145
|
+
throw candidateError(`${taskName} must contain exactly one ## Dependencies section`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const entries = lines.slice(sectionStart, sectionEnd)
|
|
149
|
+
.filter(({ outsideFence }) => outsideFence)
|
|
150
|
+
.map(({ line }) => line.trim())
|
|
151
|
+
.filter(Boolean)
|
|
152
|
+
.map((line) => {
|
|
153
|
+
const bullet = line.match(/^-\s+(.+?)\s*$/);
|
|
154
|
+
if (!bullet) throw candidateError(`${taskName} Dependencies must contain only bullet entries`);
|
|
155
|
+
const value = bullet[1].replace(/^`([^`]+)`$/, '$1').trim();
|
|
156
|
+
if (!value) throw candidateError(`${taskName} contains an empty dependency`);
|
|
157
|
+
return value;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (entries.length === 1 && entries[0].toLowerCase() === 'none') return [];
|
|
161
|
+
if (entries.length === 0 || entries.some((entry) => entry.toLowerCase() === 'none')) {
|
|
162
|
+
throw candidateError(`${taskName} must use either - none or exact task basenames`);
|
|
163
|
+
}
|
|
164
|
+
const resolved = entries.map((entry) => {
|
|
165
|
+
if (WORKFLOW_TASK_NAME.test(entry)) return entry;
|
|
166
|
+
const legacy = !queueReady && entry.match(/^(?:Task\s+)?(\d+)$/i);
|
|
167
|
+
if (!legacy) throw candidateError(`${taskName} dependencies must be exact flat task basenames`);
|
|
168
|
+
const numericId = legacy[1].replace(/^0+(?=\d)/, '');
|
|
169
|
+
const matches = taskNames.filter((candidate) => workflowTaskNumericPrefix(candidate) === numericId);
|
|
170
|
+
if (matches.length !== 1) {
|
|
171
|
+
throw candidateError(`${taskName} legacy dependency ${entry} maps to ${matches.length} task basenames`);
|
|
172
|
+
}
|
|
173
|
+
return matches[0];
|
|
174
|
+
});
|
|
175
|
+
if (new Set(resolved).size !== resolved.length) {
|
|
176
|
+
throw candidateError(`${taskName} contains duplicate dependencies`);
|
|
177
|
+
}
|
|
178
|
+
return resolved;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function assertAcyclicWorkflow(tasks) {
|
|
182
|
+
const dependencies = new Map(tasks.map((task) => [task.path, [...task.dependencies].sort()]));
|
|
183
|
+
const state = new Map();
|
|
184
|
+
const stack = [];
|
|
185
|
+
|
|
186
|
+
function visit(taskPath) {
|
|
187
|
+
state.set(taskPath, 'visiting');
|
|
188
|
+
stack.push(taskPath);
|
|
189
|
+
for (const dependency of dependencies.get(taskPath) || []) {
|
|
190
|
+
if (state.get(dependency) === 'visiting') {
|
|
191
|
+
const start = stack.indexOf(dependency);
|
|
192
|
+
throw candidateError(`dependency cycle detected: ${[...stack.slice(start), dependency].join(' -> ')}`);
|
|
193
|
+
}
|
|
194
|
+
if (state.get(dependency) !== 'visited') visit(dependency);
|
|
195
|
+
}
|
|
196
|
+
stack.pop();
|
|
197
|
+
state.set(taskPath, 'visited');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for (const taskPath of [...dependencies.keys()].sort()) {
|
|
201
|
+
if (!state.has(taskPath)) visit(taskPath);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
83
205
|
function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
|
|
84
206
|
const featureDir = path.join(specsDir, requestedName);
|
|
85
207
|
let featureLstat;
|
|
@@ -114,6 +236,7 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
|
|
|
114
236
|
if (planLstat.isSymbolicLink() || !planLstat.isFile() || fs.realpathSync(planFile) !== planFile) {
|
|
115
237
|
throw candidateError('plan.md must be a regular non-symlink file in the workflow feature directory');
|
|
116
238
|
}
|
|
239
|
+
const { workflowContract, queueReady } = workflowPlanContract(fs.readFileSync(planFile, 'utf8'));
|
|
117
240
|
|
|
118
241
|
const taskNames = fs.readdirSync(canonicalFeature, { withFileTypes: true })
|
|
119
242
|
.filter((entry) => WORKFLOW_TASK_NAME.test(entry.name))
|
|
@@ -129,12 +252,26 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
|
|
|
129
252
|
if (taskLstat.isSymbolicLink() || !taskLstat.isFile() || fs.realpathSync(taskFile) !== taskFile) {
|
|
130
253
|
throw candidateError(`${taskName} must be a regular non-symlink file in the workflow feature directory`);
|
|
131
254
|
}
|
|
255
|
+
const taskContent = fs.readFileSync(taskFile, 'utf8');
|
|
132
256
|
return {
|
|
133
257
|
path: taskName,
|
|
134
|
-
status: workflowTaskStatus(
|
|
258
|
+
status: workflowTaskStatus(taskContent, taskName),
|
|
259
|
+
dependencies: workflowTaskDependencies(taskContent, taskName, taskNames, queueReady),
|
|
135
260
|
};
|
|
136
261
|
});
|
|
137
|
-
const
|
|
262
|
+
const taskNameSet = new Set(taskNames);
|
|
263
|
+
for (const task of tasks) {
|
|
264
|
+
if (task.dependencies.includes(task.path)) {
|
|
265
|
+
throw candidateError(`${task.path} cannot depend on itself`);
|
|
266
|
+
}
|
|
267
|
+
const missing = task.dependencies.find((dependency) => !taskNameSet.has(dependency));
|
|
268
|
+
if (missing) throw candidateError(`${task.path} references missing dependency ${missing}`);
|
|
269
|
+
}
|
|
270
|
+
assertAcyclicWorkflow(tasks);
|
|
271
|
+
const taskRegistry = Object.fromEntries(tasks.map((task) => [task.path, {
|
|
272
|
+
status: task.status,
|
|
273
|
+
dependencies: task.dependencies,
|
|
274
|
+
}]));
|
|
138
275
|
const allTasksDone = tasks.every((task) => task.status === 'done');
|
|
139
276
|
return {
|
|
140
277
|
layoutKind: 'process-v3',
|
|
@@ -147,6 +284,8 @@ function inspectWorkflowFeature(specsDir, canonicalSpecs, requestedName) {
|
|
|
147
284
|
taskRegistry,
|
|
148
285
|
tasks,
|
|
149
286
|
allTasksDone,
|
|
287
|
+
workflowContract,
|
|
288
|
+
queueReady,
|
|
150
289
|
};
|
|
151
290
|
}
|
|
152
291
|
|
|
@@ -778,6 +917,7 @@ function refineWorkflowGateResolution(resolved) {
|
|
|
778
917
|
}
|
|
779
918
|
|
|
780
919
|
module.exports = {
|
|
920
|
+
annotatedMarkdownLines,
|
|
781
921
|
specsDirectory,
|
|
782
922
|
findAllActiveSpecs,
|
|
783
923
|
findAllSpecCandidates,
|
|
@@ -1733,7 +1733,7 @@ function evaluateFlashPromotion(task, verdict, proof = 'Verification: PASS', cap
|
|
|
1733
1733
|
status: 'in_progress',
|
|
1734
1734
|
receipt: 'FLASH_UNVERIFIED',
|
|
1735
1735
|
blocker: normalized.diagnostic === 'NO_TESTS'
|
|
1736
|
-
? 'awaiting test proof from /
|
|
1736
|
+
? 'awaiting test proof from /cf:test <feature>'
|
|
1737
1737
|
: normalized.diagnostic === 'PARTIAL'
|
|
1738
1738
|
? 'verification is partial; awaiting complete test proof'
|
|
1739
1739
|
: `verification returned ${normalized.verdict}`,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/status.cjs\"",
|
|
5
5
|
"padding": 0
|
|
6
6
|
},
|
|
7
|
+
"outputStyle": "Junior Developer Mode (Level 1)",
|
|
7
8
|
"hooks": {
|
|
8
9
|
"SessionStart": [
|
|
9
10
|
{
|
|
@@ -35,9 +36,24 @@
|
|
|
35
36
|
]
|
|
36
37
|
}
|
|
37
38
|
],
|
|
39
|
+
"PreCompact": [
|
|
40
|
+
{
|
|
41
|
+
"matcher": "*",
|
|
42
|
+
"hooks": [
|
|
43
|
+
{
|
|
44
|
+
"type": "command",
|
|
45
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/precompact.cjs\""
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
],
|
|
38
50
|
"UserPromptSubmit": [
|
|
39
51
|
{
|
|
40
52
|
"hooks": [
|
|
53
|
+
{
|
|
54
|
+
"type": "command",
|
|
55
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/secret-output-guardrail.cjs\""
|
|
56
|
+
},
|
|
41
57
|
{
|
|
42
58
|
"type": "command",
|
|
43
59
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/rules.cjs\""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: cf:agent-browser
|
|
3
3
|
description: AI-optimized browser automation CLI with context-efficient snapshots. Use for long autonomous sessions, self-verifying workflows, video recording, and cloud browser testing (Browserbase).
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
user-invocable: true
|