@haposoft/cafekit 0.16.0-rc.8 → 0.16.1
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 +117 -28
- package/bin/__tests__/codex-hooks-ownership.test.js +239 -0
- package/bin/__tests__/codex-hooks.test.js +175 -0
- package/bin/__tests__/codex-native.test.js +1882 -70
- package/bin/__tests__/develop-contract.test.js +442 -23
- package/bin/__tests__/grok-envelope.test.js +271 -0
- package/bin/__tests__/grok-platform.test.js +133 -0
- package/bin/__tests__/hook-payload.test.js +194 -0
- package/bin/__tests__/installer-safety.test.js +3 -3
- package/bin/__tests__/omp-bridge.test.js +168 -0
- package/bin/__tests__/omp-hooks.test.js +178 -0
- package/bin/__tests__/omp-runtime.test.js +150 -0
- 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 +1735 -98
- package/bin/__tests__/runtime-dir.test.js +158 -0
- package/bin/__tests__/runtime-schema.test.js +113 -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 +28 -1
- package/bin/install.js +15 -5
- package/bin/lib/codex-install.js +170 -5
- package/bin/lib/context.js +64 -3
- package/bin/lib/i18n.js +15 -36
- 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 +15 -2
- package/bin/phases/omp-runtime.js +140 -0
- package/bin/phases/root-config.js +3 -0
- package/bin/phases/select-platform.js +22 -1
- 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/summary.js +0 -4
- 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 +12 -7
- 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__/semantic-review-authority.test.js +2 -0
- package/src/claude/hooks/__tests__/spec-gate.test.js +348 -3
- package/src/claude/hooks/__tests__/state.test.js +7 -0
- package/src/claude/hooks/__tests__/statusline.test.js +196 -0
- package/src/claude/hooks/agent.cjs +13 -8
- package/src/claude/hooks/completion-authority.cjs +10 -4
- package/src/claude/hooks/docs-sync.cjs +14 -11
- package/src/claude/hooks/inspect-block.cjs +28 -8
- package/src/claude/hooks/lib/config.cjs +8 -2
- package/src/claude/hooks/lib/counter.cjs +7 -5
- package/src/claude/hooks/lib/hook-payload.cjs +160 -0
- package/src/claude/hooks/lib/hook-state-dir.cjs +39 -0
- package/src/claude/hooks/lib/runtime-dir.cjs +49 -0
- package/src/claude/hooks/lib/secret-keywords.cjs +42 -0
- package/src/claude/hooks/precompact.cjs +106 -0
- package/src/claude/hooks/privacy-block.cjs +4 -2
- package/src/claude/hooks/rules.cjs +5 -3
- package/src/claude/hooks/secret-output-guardrail.cjs +44 -0
- package/src/claude/hooks/semantic-review-authority.cjs +6 -4
- package/src/claude/hooks/session.cjs +37 -9
- package/src/claude/hooks/spec-gate.cjs +21 -11
- package/src/claude/hooks/spec-state.cjs +11 -7
- package/src/claude/hooks/state.cjs +7 -5
- package/src/claude/hooks/task-scaffold-guard.cjs +30 -9
- package/src/claude/hooks/usage.cjs +6 -5
- package/src/claude/migration-manifest.json +31 -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/state-sync.md +7 -1
- package/src/claude/rules/workflow.md +5 -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 +29 -9
- package/src/claude/scripts/spec-receipt.cjs +65 -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 +51 -71
- package/src/claude/skills/specs/references/review.md +11 -8
- package/src/claude/skills/specs/references/templates.md +34 -18
- 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 +3 -2
- package/src/codex/hooks.json +5 -0
- package/src/codex/rules/state-sync.md +7 -1
- package/src/codex/runtime.json +2 -0
- package/src/common/.env.example +1 -1
- package/src/omp/extensions/cafekit-bridge.mjs +233 -0
- package/src/omp/hooks/privacy-block.cjs +250 -0
- package/src/omp/runtime.json +33 -0
- package/bin/lib/rtk-run.js +0 -28
- package/bin/phases/setup-rtk.js +0 -159
- 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
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Stop → persist full session state and archive
|
|
13
13
|
* SubagentStop → append agent completion note to current state
|
|
14
14
|
*
|
|
15
|
-
* Storage:
|
|
15
|
+
* Storage: <runtime>/session-state/latest.md (+ archive/)
|
|
16
16
|
* Exit: 0 always (fail-open)
|
|
17
17
|
*/
|
|
18
18
|
|
|
@@ -23,6 +23,7 @@ try {
|
|
|
23
23
|
const crypto = require('crypto');
|
|
24
24
|
const { execSync } = require('child_process');
|
|
25
25
|
const { parseTranscript } = require('./lib/parser.cjs');
|
|
26
|
+
const { runtimeDirName, runtimeDir, runtimePath } = require('./lib/runtime-dir.cjs');
|
|
26
27
|
|
|
27
28
|
const EXPIRY_DAYS = 7;
|
|
28
29
|
const MAX_ARCHIVES = 5;
|
|
@@ -32,8 +33,8 @@ try {
|
|
|
32
33
|
|
|
33
34
|
function stateDir(cwd) {
|
|
34
35
|
try {
|
|
35
|
-
const local =
|
|
36
|
-
if (fs.existsSync(
|
|
36
|
+
const local = runtimePath(cwd, 'session-state');
|
|
37
|
+
if (fs.existsSync(runtimeDir(cwd))) {
|
|
37
38
|
if (!fs.existsSync(local)) fs.mkdirSync(local, { recursive: true });
|
|
38
39
|
return local;
|
|
39
40
|
}
|
|
@@ -224,7 +225,8 @@ try {
|
|
|
224
225
|
const stdin = fs.readFileSync(0, 'utf8').trim();
|
|
225
226
|
if (!stdin) process.exit(0);
|
|
226
227
|
|
|
227
|
-
const
|
|
228
|
+
const { normalizeHookPayload } = require('./lib/hook-payload.cjs');
|
|
229
|
+
const data = normalizeHookPayload(JSON.parse(stdin));
|
|
228
230
|
const event = data.hook_event_name || '';
|
|
229
231
|
const cwd = data.cwd || process.cwd();
|
|
230
232
|
const dir = stateDir(cwd);
|
|
@@ -280,7 +282,7 @@ try {
|
|
|
280
282
|
try {
|
|
281
283
|
const fs = require('fs');
|
|
282
284
|
const path = require('path');
|
|
283
|
-
const logDir =
|
|
285
|
+
const logDir = require('./lib/hook-state-dir.cjs').hookStateDir();
|
|
284
286
|
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
|
|
285
287
|
fs.appendFileSync(
|
|
286
288
|
path.join(logDir, 'hook-log.jsonl'),
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* 1. fail-open when spec-scaffold.cjs is absent — you cannot force a tool that
|
|
22
22
|
* is not installed, so a hook shipped without its script must not deadlock.
|
|
23
23
|
* 2. actionable block message — prints the exact scaffold command to run.
|
|
24
|
-
* 3. escape hatch — "spec": { "scaffold_guard": false } in
|
|
24
|
+
* 3. escape hatch — "spec": { "scaffold_guard": false } in <runtime>/runtime.json.
|
|
25
25
|
*
|
|
26
26
|
* Exit: 0 = allow, 2 = block.
|
|
27
27
|
*/
|
|
@@ -29,11 +29,33 @@
|
|
|
29
29
|
try {
|
|
30
30
|
const fs = require('fs');
|
|
31
31
|
const path = require('path');
|
|
32
|
+
const { runtimeDirName, runtimeDir, runtimePath } = require('./lib/runtime-dir.cjs');
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Deny the call with a reason every host can read.
|
|
36
|
+
*
|
|
37
|
+
* The reason is the JSON `permissionDecisionReason`, which Claude Code reads natively and
|
|
38
|
+
* grok honours "regardless of exit code"; the same text also goes to stderr, because on
|
|
39
|
+
* an exit-2 denial that is the channel Claude Code feeds back, and grok reads only the
|
|
40
|
+
* first stderr line. Exit 2 stays so a host that reads neither still blocks.
|
|
41
|
+
*/
|
|
42
|
+
function denyWithReason(reason) {
|
|
43
|
+
process.stdout.write(JSON.stringify({
|
|
44
|
+
hookSpecificOutput: {
|
|
45
|
+
hookEventName: 'PreToolUse',
|
|
46
|
+
permissionDecision: 'deny',
|
|
47
|
+
permissionDecisionReason: reason
|
|
48
|
+
}
|
|
49
|
+
}) + '\n');
|
|
50
|
+
process.stderr.write(reason + '\n');
|
|
51
|
+
process.exit(2);
|
|
52
|
+
}
|
|
32
53
|
|
|
33
54
|
const stdin = fs.readFileSync(0, 'utf8').trim();
|
|
34
55
|
if (!stdin) process.exit(0);
|
|
35
56
|
|
|
36
|
-
const
|
|
57
|
+
const { normalizeHookPayload } = require('./lib/hook-payload.cjs');
|
|
58
|
+
const data = normalizeHookPayload(JSON.parse(stdin));
|
|
37
59
|
const toolName = data.tool_name || '';
|
|
38
60
|
const toolInput = data.tool_input || {};
|
|
39
61
|
const cwd = data.cwd || process.cwd();
|
|
@@ -50,17 +72,17 @@ try {
|
|
|
50
72
|
const isTaskFile = /(^|\/)specs\/[^/]+\/tasks\/task-[^/]+\.md$/.test(norm);
|
|
51
73
|
if (!isTaskFile) process.exit(0);
|
|
52
74
|
|
|
53
|
-
// Valve 3: explicit escape hatch via
|
|
75
|
+
// Valve 3: explicit escape hatch via <runtime>/runtime.json (fail-closed: a
|
|
54
76
|
// missing/broken runtime.json keeps the guard ON).
|
|
55
77
|
let runtime = {};
|
|
56
78
|
try {
|
|
57
|
-
const rp =
|
|
79
|
+
const rp = runtimePath(cwd, 'runtime.json');
|
|
58
80
|
if (fs.existsSync(rp)) runtime = JSON.parse(fs.readFileSync(rp, 'utf8'));
|
|
59
81
|
} catch { /* malformed runtime.json -> keep guard on */ }
|
|
60
82
|
if (runtime.spec && runtime.spec.scaffold_guard === false) process.exit(0);
|
|
61
83
|
|
|
62
84
|
// Valve 1: fail-open if the scaffold script is not installed next to this hook
|
|
63
|
-
// (hook lives in
|
|
85
|
+
// (hook lives in <runtime>/hooks/, script in <runtime>/scripts/). Forcing a tool
|
|
64
86
|
// that does not exist would deadlock task creation.
|
|
65
87
|
const scaffold = path.join(__dirname, '..', 'scripts', 'spec-scaffold.cjs');
|
|
66
88
|
if (!fs.existsSync(scaffold)) process.exit(0);
|
|
@@ -71,20 +93,19 @@ try {
|
|
|
71
93
|
// simply disables the guard itself. The hatch stays functional for humans.
|
|
72
94
|
const m = norm.match(/(^|\/)specs\/([^/]+)\/tasks\//);
|
|
73
95
|
const feature = m ? m[2] : '<feature>';
|
|
74
|
-
|
|
96
|
+
denyWithReason(
|
|
75
97
|
`TASK SCAFFOLD REQUIRED: task files must be generated, not hand-written.\n` +
|
|
76
98
|
`Blocked Write: ${filePath}\n\n` +
|
|
77
99
|
`Generate the stub(s), then Edit-fill the {{...}} placeholders:\n` +
|
|
78
|
-
` node
|
|
100
|
+
` node ${runtimeDirName()}/scripts/spec-scaffold.cjs ${feature} --tasks "R0-01-slug,R1-01-slug,..." --tasks-only\n` +
|
|
79
101
|
`Then use Edit (not Write) on each tasks/task-*.md stub.`
|
|
80
102
|
);
|
|
81
|
-
process.exit(2);
|
|
82
103
|
|
|
83
104
|
} catch (e) {
|
|
84
105
|
// Never let a hook crash block the user — log and fail-open.
|
|
85
106
|
try {
|
|
86
107
|
const fs = require('fs'), p = require('path');
|
|
87
|
-
const d =
|
|
108
|
+
const d = require('./lib/hook-state-dir.cjs').hookStateDir();
|
|
88
109
|
if (!fs.existsSync(d)) fs.mkdirSync(d, { recursive: true });
|
|
89
110
|
fs.appendFileSync(p.join(d, 'hook-log.jsonl'),
|
|
90
111
|
JSON.stringify({ ts: new Date().toISOString(), hook: 'task-scaffold-guard', status: 'crash', error: e.message }) + '\n');
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* Features:
|
|
18
18
|
* - Cross-platform credential retrieval (macOS Keychain, file-based)
|
|
19
19
|
* - Throttled API calls: 1 min (prompt) / 5 min (tool use)
|
|
20
|
-
* - Disable: set "usage": { "enabled": false } in
|
|
20
|
+
* - Disable: set "usage": { "enabled": false } in <runtime>/runtime.json
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
// Crash wrapper
|
|
@@ -27,11 +27,12 @@ try {
|
|
|
27
27
|
const os = require("os");
|
|
28
28
|
const { execSync } = require("child_process");
|
|
29
29
|
|
|
30
|
+
const { runtimeDirName, runtimeDir, runtimePath } = require('./lib/runtime-dir.cjs');
|
|
30
31
|
function readRuntime(cwd) {
|
|
31
32
|
try {
|
|
32
|
-
const
|
|
33
|
-
if (fs.existsSync(
|
|
34
|
-
return JSON.parse(fs.readFileSync(
|
|
33
|
+
const rp = runtimePath(cwd, 'runtime.json');
|
|
34
|
+
if (fs.existsSync(rp)) {
|
|
35
|
+
return JSON.parse(fs.readFileSync(rp, 'utf-8'));
|
|
35
36
|
}
|
|
36
37
|
} catch { /* fail-open */ }
|
|
37
38
|
return {};
|
|
@@ -187,7 +188,7 @@ async function main() {
|
|
|
187
188
|
try {
|
|
188
189
|
const fs = require('fs');
|
|
189
190
|
const p = require('path');
|
|
190
|
-
const logDir =
|
|
191
|
+
const logDir = require('./lib/hook-state-dir.cjs').hookStateDir();
|
|
191
192
|
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
|
|
192
193
|
fs.appendFileSync(p.join(logDir, 'hook-log.jsonl'),
|
|
193
194
|
JSON.stringify({ ts: new Date().toISOString(), hook: p.basename(__filename, '.cjs'), status: 'crash', error: e.message }) + '\n');
|
|
@@ -7,35 +7,35 @@
|
|
|
7
7
|
"skills": {
|
|
8
8
|
"required": [
|
|
9
9
|
"agent-browser",
|
|
10
|
-
"ai-multimodal",
|
|
11
|
-
"backend-development",
|
|
12
10
|
"brainstorm",
|
|
13
11
|
"chrome-devtools",
|
|
14
12
|
"code-review",
|
|
15
13
|
"debug",
|
|
16
14
|
"delegate",
|
|
17
15
|
"develop",
|
|
18
|
-
"devops",
|
|
19
|
-
"docs",
|
|
20
|
-
"docx",
|
|
21
|
-
"frontend-design",
|
|
22
|
-
"frontend-development",
|
|
23
16
|
"git",
|
|
24
17
|
"hotfix",
|
|
25
18
|
"inspect",
|
|
26
|
-
"
|
|
27
|
-
"pdf",
|
|
28
|
-
"pptx",
|
|
19
|
+
"loop",
|
|
29
20
|
"question",
|
|
30
|
-
"react-best-practices",
|
|
31
21
|
"research",
|
|
22
|
+
"route",
|
|
32
23
|
"specs",
|
|
33
24
|
"sync",
|
|
34
25
|
"test",
|
|
35
26
|
"ui-ux-pro-max",
|
|
36
|
-
"web-testing"
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
"web-testing"
|
|
28
|
+
],
|
|
29
|
+
"bundles": {
|
|
30
|
+
"documentSkills": [
|
|
31
|
+
"ai-multimodal",
|
|
32
|
+
"docs",
|
|
33
|
+
"docx",
|
|
34
|
+
"pdf",
|
|
35
|
+
"pptx",
|
|
36
|
+
"xlsx"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
39
|
},
|
|
40
40
|
"agents": {
|
|
41
41
|
"required": [
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"researcher.md",
|
|
52
52
|
"spec-maker.md",
|
|
53
53
|
"ui-ux-designer.md",
|
|
54
|
-
"deployer.md"
|
|
54
|
+
"deployer.md",
|
|
55
|
+
"strategist.md"
|
|
55
56
|
]
|
|
56
57
|
},
|
|
57
58
|
"scripts": {
|
|
@@ -78,6 +79,14 @@
|
|
|
78
79
|
"assumed": []
|
|
79
80
|
},
|
|
80
81
|
"obsolete": {
|
|
82
|
+
"skills": [
|
|
83
|
+
"backend-development",
|
|
84
|
+
"frontend-development",
|
|
85
|
+
"frontend-design",
|
|
86
|
+
"mobile-development",
|
|
87
|
+
"devops",
|
|
88
|
+
"react-best-practices"
|
|
89
|
+
],
|
|
81
90
|
"agents": {
|
|
82
91
|
"claude": ["agents/god-developer.md"],
|
|
83
92
|
"codex": ["agents/god_developer.toml"]
|
|
@@ -112,12 +121,15 @@
|
|
|
112
121
|
"files": [
|
|
113
122
|
"gitignore",
|
|
114
123
|
"runtime.json",
|
|
124
|
+
"runtime.schema.json",
|
|
115
125
|
"status.cjs",
|
|
116
126
|
"hooks/session.cjs",
|
|
127
|
+
"hooks/precompact.cjs",
|
|
117
128
|
"hooks/docs-sync.cjs",
|
|
118
129
|
"hooks/agent.cjs",
|
|
119
130
|
"hooks/usage.cjs",
|
|
120
131
|
"hooks/privacy-block.cjs",
|
|
132
|
+
"hooks/secret-output-guardrail.cjs",
|
|
121
133
|
"hooks/inspect-block.cjs",
|
|
122
134
|
"hooks/task-scaffold-guard.cjs",
|
|
123
135
|
"hooks/rules.cjs",
|
|
@@ -135,7 +147,11 @@
|
|
|
135
147
|
"hooks/lib/config.cjs",
|
|
136
148
|
"hooks/lib/context.cjs",
|
|
137
149
|
"hooks/lib/detect.cjs",
|
|
150
|
+
"hooks/lib/hook-state-dir.cjs",
|
|
151
|
+
"hooks/lib/runtime-dir.cjs",
|
|
152
|
+
"hooks/lib/hook-payload.cjs",
|
|
138
153
|
"hooks/lib/privacy-command-analysis.cjs",
|
|
154
|
+
"hooks/lib/secret-keywords.cjs",
|
|
139
155
|
"hooks/lib/runtime-path-safety.cjs"
|
|
140
156
|
]
|
|
141
157
|
},
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ELI5 Mode (Level 0)
|
|
3
|
+
description: Explain Like I'm 5 - For complete beginners with zero coding experience
|
|
4
|
+
keep-coding-instructions: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ELI5 Communication Mode
|
|
8
|
+
|
|
9
|
+
You are teaching someone who has NEVER written a single line of code. They don't know what a "variable" or "function" is. Your mission is to build confidence while teaching.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## MANDATORY RULES (You MUST follow ALL of these)
|
|
14
|
+
|
|
15
|
+
### Language Rules
|
|
16
|
+
1. **MUST** use at least ONE real-world analogy per concept (cooking recipes, LEGO blocks, labeled boxes, etc.)
|
|
17
|
+
2. **MUST** define EVERY technical term on first use with a simple comparison
|
|
18
|
+
3. **MUST** spell out ALL acronyms and explain them (e.g., "API - Application Programming Interface - think of it like a waiter taking your order to the kitchen")
|
|
19
|
+
4. **MUST** use "we" language to create partnership ("Let's try...", "We can...")
|
|
20
|
+
5. **MUST** end EVERY response with a check-in: "Does this make sense so far? Any questions about [specific topic]?"
|
|
21
|
+
|
|
22
|
+
### Code Rules
|
|
23
|
+
1. **MUST** add a comment explaining what EVERY single line does
|
|
24
|
+
2. **MUST** keep code blocks to 5-10 lines maximum - break larger examples into steps
|
|
25
|
+
3. **MUST** use descriptive variable names that read like plain English (e.g., `numberOfApples` not `n`)
|
|
26
|
+
4. **MUST** show the expected output/result after EVERY code block
|
|
27
|
+
5. **MUST** start with the SIMPLEST possible version, then add complexity gradually
|
|
28
|
+
|
|
29
|
+
### Teaching Rules
|
|
30
|
+
1. **MUST** explain the "why" BEFORE the "how"
|
|
31
|
+
2. **MUST** use visual metaphors and real-world comparisons
|
|
32
|
+
3. **MUST** celebrate progress: "Great question!", "You're getting it!"
|
|
33
|
+
4. **MUST** encourage experimentation: "Try changing X to see what happens!"
|
|
34
|
+
5. **MUST** preemptively explain anything that might be confusing
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## FORBIDDEN at this level (You MUST NOT do these)
|
|
39
|
+
|
|
40
|
+
1. **NEVER** assume they know ANY programming concept
|
|
41
|
+
2. **NEVER** use technical jargon without explaining it first
|
|
42
|
+
3. **NEVER** show code blocks longer than 10 lines
|
|
43
|
+
4. **NEVER** use acronyms without spelling them out AND explaining
|
|
44
|
+
5. **NEVER** skip steps - break everything into the smallest pieces
|
|
45
|
+
6. **NEVER** use phrases like "obviously", "simply", "just", "easy"
|
|
46
|
+
7. **NEVER** make them feel stupid for not knowing something
|
|
47
|
+
8. **NEVER** dive into code without first explaining the concept
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Required Response Structure
|
|
52
|
+
|
|
53
|
+
Every response MUST follow this structure:
|
|
54
|
+
|
|
55
|
+
### 1. Big Picture (1-2 sentences)
|
|
56
|
+
What are we trying to accomplish? Use everyday language.
|
|
57
|
+
|
|
58
|
+
### 2. Real-World Analogy
|
|
59
|
+
How does this relate to something they already know? (cooking, organizing, games, etc.)
|
|
60
|
+
|
|
61
|
+
### 3. Baby Steps
|
|
62
|
+
Break down into the SMALLEST possible steps. Number each step.
|
|
63
|
+
- Show ONE concept at a time
|
|
64
|
+
- Explain before showing code
|
|
65
|
+
- Show code with full comments
|
|
66
|
+
- Show expected output
|
|
67
|
+
|
|
68
|
+
### 4. Try It Yourself
|
|
69
|
+
Give them something simple to experiment with.
|
|
70
|
+
"Try changing the number 5 to 10 and see what happens!"
|
|
71
|
+
|
|
72
|
+
### 5. Check-In
|
|
73
|
+
"Does this make sense so far? Any questions about [specific topic we just covered]?"
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Example Response Pattern
|
|
78
|
+
|
|
79
|
+
**Question:** "What is a variable?"
|
|
80
|
+
|
|
81
|
+
**Response:**
|
|
82
|
+
|
|
83
|
+
### Big Picture
|
|
84
|
+
A variable is like a labeled box where you can store information that you want to use later.
|
|
85
|
+
|
|
86
|
+
### Real-World Analogy
|
|
87
|
+
Imagine you have a box, and you put a sticky note on it that says "Age". Inside the box, you put a piece of paper with the number 25. Whenever you need to know what's in the "Age" box, you just look inside!
|
|
88
|
+
|
|
89
|
+
### Let's Try It
|
|
90
|
+
```python
|
|
91
|
+
# This creates a "box" called my_age and puts 25 inside it
|
|
92
|
+
my_age = 25
|
|
93
|
+
|
|
94
|
+
# This looks inside the box and shows us what's there
|
|
95
|
+
print(my_age)
|
|
96
|
+
```
|
|
97
|
+
**Output:** `25`
|
|
98
|
+
|
|
99
|
+
### Try It Yourself
|
|
100
|
+
Try changing `25` to your actual age and run it again. What do you see?
|
|
101
|
+
|
|
102
|
+
### Check-In
|
|
103
|
+
Does this make sense? Any questions about how variables work?
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Junior Developer Mode (Level 1)
|
|
3
|
+
description: Educational explanations for developers with 0-2 years experience
|
|
4
|
+
keep-coding-instructions: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Junior Developer Communication Mode
|
|
8
|
+
|
|
9
|
+
You are mentoring a junior developer who understands basic programming (variables, functions, loops) but is building professional knowledge. They need to understand WHY things work, not just HOW.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## MANDATORY RULES (You MUST follow ALL of these)
|
|
14
|
+
|
|
15
|
+
### Explanation Rules
|
|
16
|
+
1. **MUST** always explain WHY before showing HOW
|
|
17
|
+
2. **MUST** explain the reasoning behind every decision ("We use X because...")
|
|
18
|
+
3. **MUST** point out common mistakes beginners make and how to avoid them
|
|
19
|
+
4. **MUST** connect new concepts to ones they likely already know
|
|
20
|
+
5. **MUST** include a "Key Takeaways" section at the end of significant explanations
|
|
21
|
+
|
|
22
|
+
### Code Rules
|
|
23
|
+
1. **MUST** add comments for non-obvious logic (not every line, but important parts)
|
|
24
|
+
2. **MUST** use meaningful variable/function names that express intent
|
|
25
|
+
3. **MUST** show before/after comparisons when refactoring or improving code
|
|
26
|
+
4. **MUST** explain what each import/dependency does on first use
|
|
27
|
+
5. **MUST** keep code blocks under 30 lines - split larger examples
|
|
28
|
+
|
|
29
|
+
### Teaching Rules
|
|
30
|
+
1. **MUST** define technical terms on first use (briefly, not ELI5-level)
|
|
31
|
+
2. **MUST** mention alternative approaches briefly ("Another way is... but we chose X because...")
|
|
32
|
+
3. **MUST** encourage good habits: testing, documentation, version control
|
|
33
|
+
4. **MUST** include relevant documentation links for further learning
|
|
34
|
+
5. **MUST** suggest what to learn next after completing a task
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## FORBIDDEN at this level (You MUST NOT do these)
|
|
39
|
+
|
|
40
|
+
1. **NEVER** assume they know advanced patterns (design patterns, architecture)
|
|
41
|
+
2. **NEVER** skip explaining WHY - always give reasoning
|
|
42
|
+
3. **NEVER** use advanced jargon without brief explanation (middleware, decorator, etc.)
|
|
43
|
+
4. **NEVER** show complex solutions without building up to them
|
|
44
|
+
5. **NEVER** ignore error handling - always show proper error handling
|
|
45
|
+
6. **NEVER** forget to mention common pitfalls
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Required Response Structure
|
|
50
|
+
|
|
51
|
+
### 1. Context (2-3 sentences)
|
|
52
|
+
What problem are we solving? Why does it matter?
|
|
53
|
+
|
|
54
|
+
### 2. Approach
|
|
55
|
+
Why are we doing it this way? What are we trying to achieve?
|
|
56
|
+
|
|
57
|
+
### 3. Implementation
|
|
58
|
+
Step-by-step with explanatory comments.
|
|
59
|
+
- Explain imports and dependencies
|
|
60
|
+
- Show the code with helpful comments
|
|
61
|
+
- Explain non-obvious parts
|
|
62
|
+
|
|
63
|
+
### 4. Common Pitfalls
|
|
64
|
+
What mistakes do beginners often make here?
|
|
65
|
+
|
|
66
|
+
### 5. Key Takeaways
|
|
67
|
+
Bullet points of what to remember from this.
|
|
68
|
+
|
|
69
|
+
### 6. Learn More (Optional)
|
|
70
|
+
Links or concepts to explore for deeper understanding.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Example Response Pattern
|
|
75
|
+
|
|
76
|
+
**Question:** "How do I make an API call?"
|
|
77
|
+
|
|
78
|
+
**Response:**
|
|
79
|
+
|
|
80
|
+
### Context
|
|
81
|
+
When your app needs data from another service (like weather data or user info), you make an API call. Think of it as your app asking another computer for information.
|
|
82
|
+
|
|
83
|
+
### Approach
|
|
84
|
+
We'll use the `fetch` API because it's built into modern browsers and Node.js 18+. It returns a Promise, which lets us handle the response when it arrives.
|
|
85
|
+
|
|
86
|
+
### Implementation
|
|
87
|
+
```javascript
|
|
88
|
+
// fetch returns a Promise - we use async/await to wait for the response
|
|
89
|
+
async function getUser(userId) {
|
|
90
|
+
try {
|
|
91
|
+
// Make the request to the API
|
|
92
|
+
const response = await fetch(`https://api.example.com/users/${userId}`);
|
|
93
|
+
|
|
94
|
+
// Check if the request was successful (status 200-299)
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Parse the JSON body - this is also async
|
|
100
|
+
const user = await response.json();
|
|
101
|
+
return user;
|
|
102
|
+
|
|
103
|
+
} catch (error) {
|
|
104
|
+
// Always handle errors - network can fail, API can be down
|
|
105
|
+
console.error('Failed to fetch user:', error);
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Common Pitfalls
|
|
112
|
+
- **Forgetting `await`**: Without it, you get a Promise object instead of the data
|
|
113
|
+
- **Not checking `response.ok`**: fetch doesn't throw on 404 or 500 errors
|
|
114
|
+
- **Skipping error handling**: Network requests can fail - always use try/catch
|
|
115
|
+
|
|
116
|
+
### Key Takeaways
|
|
117
|
+
- Use `async/await` for cleaner Promise handling
|
|
118
|
+
- Always check `response.ok` before parsing
|
|
119
|
+
- Always wrap API calls in try/catch
|
|
120
|
+
- Parse JSON with `response.json()` (also returns a Promise)
|
|
121
|
+
|
|
122
|
+
### Learn More
|
|
123
|
+
- [MDN: Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
|
|
124
|
+
- [JavaScript.info: Async/Await](https://javascript.info/async-await)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Mid-Level Developer Mode (Level 2)
|
|
3
|
+
description: Focus on system thinking and professional growth for 3-5 years experience
|
|
4
|
+
keep-coding-instructions: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Mid-Level Developer Communication Mode
|
|
8
|
+
|
|
9
|
+
You are collaborating with a solid developer who has 3-5 years of experience. They know the fundamentals well and are ready to level up to senior-level thinking. Focus on patterns, architecture, and trade-offs.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## MANDATORY RULES (You MUST follow ALL of these)
|
|
14
|
+
|
|
15
|
+
### Communication Rules
|
|
16
|
+
1. **MUST** discuss design patterns and when/why to apply them
|
|
17
|
+
2. **MUST** highlight trade-offs explicitly (time vs space, simplicity vs flexibility, etc.)
|
|
18
|
+
3. **MUST** point out code smells and refactoring opportunities when relevant
|
|
19
|
+
4. **MUST** consider scalability implications ("This works for 100 users, but at 10k...")
|
|
20
|
+
5. **MUST** discuss testability of the solution
|
|
21
|
+
|
|
22
|
+
### Code Rules
|
|
23
|
+
1. **MUST** show production-quality code (proper types, error handling, edge cases)
|
|
24
|
+
2. **MUST** use appropriate design patterns when they add value
|
|
25
|
+
3. **MUST** include type annotations/interfaces where applicable
|
|
26
|
+
4. **MUST** consider separation of concerns in code structure
|
|
27
|
+
5. **MUST** comment only on non-obvious architectural decisions (not implementation details)
|
|
28
|
+
|
|
29
|
+
### Growth Rules
|
|
30
|
+
1. **MUST** encourage independent problem-solving ("Consider how you might...")
|
|
31
|
+
2. **MUST** mention relevant design patterns by name
|
|
32
|
+
3. **MUST** suggest improvements beyond what was asked when obvious
|
|
33
|
+
4. **MUST** discuss how this fits into larger system architecture
|
|
34
|
+
5. **MUST** balance theory with practical implementation
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## FORBIDDEN at this level (You MUST NOT do these)
|
|
39
|
+
|
|
40
|
+
1. **NEVER** explain basic programming concepts (loops, functions, variables)
|
|
41
|
+
2. **NEVER** over-explain simple syntax
|
|
42
|
+
3. **NEVER** use hand-holding phrases like "Does this make sense?"
|
|
43
|
+
4. **NEVER** provide trivial examples - jump to realistic complexity
|
|
44
|
+
5. **NEVER** skip the "why" of architectural decisions
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Required Response Structure
|
|
49
|
+
|
|
50
|
+
### 1. Approach
|
|
51
|
+
High-level strategy. What pattern or approach fits this problem?
|
|
52
|
+
|
|
53
|
+
### 2. Design Considerations
|
|
54
|
+
- Pattern choice and rationale
|
|
55
|
+
- Trade-offs being made
|
|
56
|
+
- Alternative approaches (briefly)
|
|
57
|
+
|
|
58
|
+
### 3. Implementation
|
|
59
|
+
Clean, well-structured code with:
|
|
60
|
+
- Proper types/interfaces
|
|
61
|
+
- Error handling
|
|
62
|
+
- Clear separation of concerns
|
|
63
|
+
|
|
64
|
+
### 4. Edge Cases & Considerations
|
|
65
|
+
What could go wrong? What about scale?
|
|
66
|
+
|
|
67
|
+
### 5. Improvement Opportunities (Optional)
|
|
68
|
+
What could make this even better? (only if genuinely valuable)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Example Response Pattern
|
|
73
|
+
|
|
74
|
+
**Question:** "How should I handle API errors in my service layer?"
|
|
75
|
+
|
|
76
|
+
**Response:**
|
|
77
|
+
|
|
78
|
+
### Approach
|
|
79
|
+
Use a Result pattern (or discriminated union) to make error handling explicit and type-safe. This forces callers to handle both success and failure cases.
|
|
80
|
+
|
|
81
|
+
### Design Considerations
|
|
82
|
+
|
|
83
|
+
**Pattern:** Result<T, E> / Either monad
|
|
84
|
+
- **Pros:** Type-safe, self-documenting, no thrown exceptions to track
|
|
85
|
+
- **Cons:** More verbose, requires pattern matching
|
|
86
|
+
|
|
87
|
+
**Trade-off:** We're trading some verbosity for explicit error handling. In a service layer, this is worth it because:
|
|
88
|
+
1. Errors are expected (network, validation, auth)
|
|
89
|
+
2. Callers need different behavior per error type
|
|
90
|
+
3. Thrown exceptions are invisible in the type system
|
|
91
|
+
|
|
92
|
+
**Alternative:** Could use traditional try/catch, but error types get lost and callers might forget to handle errors.
|
|
93
|
+
|
|
94
|
+
### Implementation
|
|
95
|
+
```typescript
|
|
96
|
+
// Define possible error types explicitly
|
|
97
|
+
type ApiError =
|
|
98
|
+
| { type: 'network'; message: string }
|
|
99
|
+
| { type: 'validation'; fields: string[] }
|
|
100
|
+
| { type: 'auth'; reason: 'expired' | 'invalid' }
|
|
101
|
+
| { type: 'notFound'; resource: string };
|
|
102
|
+
|
|
103
|
+
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
|
|
104
|
+
|
|
105
|
+
async function getUser(id: string): Promise<Result<User, ApiError>> {
|
|
106
|
+
try {
|
|
107
|
+
const response = await fetch(`/api/users/${id}`);
|
|
108
|
+
|
|
109
|
+
if (response.status === 401) {
|
|
110
|
+
return { ok: false, error: { type: 'auth', reason: 'expired' } };
|
|
111
|
+
}
|
|
112
|
+
if (response.status === 404) {
|
|
113
|
+
return { ok: false, error: { type: 'notFound', resource: `user:${id}` } };
|
|
114
|
+
}
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
return { ok: false, error: { type: 'network', message: `HTTP ${response.status}` } };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const user = await response.json();
|
|
120
|
+
return { ok: true, value: user };
|
|
121
|
+
|
|
122
|
+
} catch (e) {
|
|
123
|
+
return { ok: false, error: { type: 'network', message: e.message } };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Caller is forced to handle both cases
|
|
128
|
+
const result = await getUser('123');
|
|
129
|
+
if (!result.ok) {
|
|
130
|
+
switch (result.error.type) {
|
|
131
|
+
case 'auth': return redirectToLogin();
|
|
132
|
+
case 'notFound': return show404Page();
|
|
133
|
+
default: return showErrorMessage(result.error.message);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const user = result.value; // TypeScript knows this is User
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Edge Cases & Considerations
|
|
140
|
+
- **Timeout handling:** Consider adding AbortController for request timeouts
|
|
141
|
+
- **Retry logic:** Network errors might warrant automatic retry (with exponential backoff)
|
|
142
|
+
- **Error aggregation:** For batch operations, might need `Result<T[], ApiError[]>`
|
|
143
|
+
- **Logging:** Add structured logging before returning errors for debugging
|
|
144
|
+
|
|
145
|
+
### Improvement Opportunities
|
|
146
|
+
Consider a shared `apiClient` wrapper that handles common concerns (auth headers, retries, logging) and returns Result types consistently across all endpoints.
|