eai-cli 0.0.0-bootstrap.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/LICENSE +183 -0
- package/NOTICE +4 -0
- package/README.md +14 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +69 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/blocks.d.ts +3 -0
- package/dist/commands/blocks.d.ts.map +1 -0
- package/dist/commands/blocks.js +249 -0
- package/dist/commands/blocks.js.map +1 -0
- package/dist/commands/chat.d.ts +6 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +105 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/deploy.d.ts +36 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +712 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +133 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/docs.d.ts +6 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +118 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/env.d.ts +10 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +200 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/errors.d.ts +3 -0
- package/dist/commands/errors.d.ts.map +1 -0
- package/dist/commands/errors.js +72 -0
- package/dist/commands/errors.js.map +1 -0
- package/dist/commands/gofer.d.ts +3 -0
- package/dist/commands/gofer.d.ts.map +1 -0
- package/dist/commands/gofer.js +134 -0
- package/dist/commands/gofer.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1437 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +117 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/provision.d.ts +6 -0
- package/dist/commands/provision.d.ts.map +1 -0
- package/dist/commands/provision.js +855 -0
- package/dist/commands/provision.js.map +1 -0
- package/dist/commands/publicapi.d.ts +6 -0
- package/dist/commands/publicapi.d.ts.map +1 -0
- package/dist/commands/publicapi.js +184 -0
- package/dist/commands/publicapi.js.map +1 -0
- package/dist/commands/resources.d.ts +38 -0
- package/dist/commands/resources.d.ts.map +1 -0
- package/dist/commands/resources.js +1010 -0
- package/dist/commands/resources.js.map +1 -0
- package/dist/commands/runtime.d.ts +3 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +78 -0
- package/dist/commands/runtime.js.map +1 -0
- package/dist/commands/template.d.ts +3 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +365 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/tenant.d.ts +45 -0
- package/dist/commands/tenant.d.ts.map +1 -0
- package/dist/commands/tenant.js +1036 -0
- package/dist/commands/tenant.js.map +1 -0
- package/dist/commands/types.d.ts +130 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +1636 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +163 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/user.d.ts +6 -0
- package/dist/commands/user.d.ts.map +1 -0
- package/dist/commands/user.js +359 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/verify.d.ts +40 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +1442 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/vertical.d.ts +24 -0
- package/dist/commands/vertical.d.ts.map +1 -0
- package/dist/commands/vertical.js +301 -0
- package/dist/commands/vertical.js.map +1 -0
- package/dist/commands/whoami.d.ts +6 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +73 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/commands/workflow.d.ts +6 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +400 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +272 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agent-guide.d.ts +24 -0
- package/dist/lib/agent-guide.d.ts.map +1 -0
- package/dist/lib/agent-guide.js +155 -0
- package/dist/lib/agent-guide.js.map +1 -0
- package/dist/lib/api.d.ts +338 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +991 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +65 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +592 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/azure-cli.d.ts +6 -0
- package/dist/lib/azure-cli.d.ts.map +1 -0
- package/dist/lib/azure-cli.js +13 -0
- package/dist/lib/azure-cli.js.map +1 -0
- package/dist/lib/block-catalog-normalize.d.ts +47 -0
- package/dist/lib/block-catalog-normalize.d.ts.map +1 -0
- package/dist/lib/block-catalog-normalize.js +355 -0
- package/dist/lib/block-catalog-normalize.js.map +1 -0
- package/dist/lib/block-catalog-types.d.ts +111 -0
- package/dist/lib/block-catalog-types.d.ts.map +1 -0
- package/dist/lib/block-catalog-types.js +41 -0
- package/dist/lib/block-catalog-types.js.map +1 -0
- package/dist/lib/block-catalog-utils.d.ts +7 -0
- package/dist/lib/block-catalog-utils.d.ts.map +1 -0
- package/dist/lib/block-catalog-utils.js +47 -0
- package/dist/lib/block-catalog-utils.js.map +1 -0
- package/dist/lib/block-catalog-validation.d.ts +5 -0
- package/dist/lib/block-catalog-validation.d.ts.map +1 -0
- package/dist/lib/block-catalog-validation.js +112 -0
- package/dist/lib/block-catalog-validation.js.map +1 -0
- package/dist/lib/block-catalog.d.ts +3 -0
- package/dist/lib/block-catalog.d.ts.map +1 -0
- package/dist/lib/block-catalog.js +284 -0
- package/dist/lib/block-catalog.js.map +1 -0
- package/dist/lib/cloud-env.d.ts +25 -0
- package/dist/lib/cloud-env.d.ts.map +1 -0
- package/dist/lib/cloud-env.js +79 -0
- package/dist/lib/cloud-env.js.map +1 -0
- package/dist/lib/config.d.ts +116 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +195 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/context.d.ts +43 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/context.js +68 -0
- package/dist/lib/context.js.map +1 -0
- package/dist/lib/error-codes.d.ts +56 -0
- package/dist/lib/error-codes.d.ts.map +1 -0
- package/dist/lib/error-codes.js +211 -0
- package/dist/lib/error-codes.js.map +1 -0
- package/dist/lib/error-guidance/catalog.d.ts +648 -0
- package/dist/lib/error-guidance/catalog.d.ts.map +1 -0
- package/dist/lib/error-guidance/catalog.js +940 -0
- package/dist/lib/error-guidance/catalog.js.map +1 -0
- package/dist/lib/error-guidance/match.d.ts +3 -0
- package/dist/lib/error-guidance/match.d.ts.map +1 -0
- package/dist/lib/error-guidance/match.js +46 -0
- package/dist/lib/error-guidance/match.js.map +1 -0
- package/dist/lib/error-guidance/render.d.ts +5 -0
- package/dist/lib/error-guidance/render.d.ts.map +1 -0
- package/dist/lib/error-guidance/render.js +92 -0
- package/dist/lib/error-guidance/render.js.map +1 -0
- package/dist/lib/error-guidance/types.d.ts +76 -0
- package/dist/lib/error-guidance/types.d.ts.map +1 -0
- package/dist/lib/error-guidance/types.js +2 -0
- package/dist/lib/error-guidance/types.js.map +1 -0
- package/dist/lib/error-guidance/validate.d.ts +3 -0
- package/dist/lib/error-guidance/validate.d.ts.map +1 -0
- package/dist/lib/error-guidance/validate.js +59 -0
- package/dist/lib/error-guidance/validate.js.map +1 -0
- package/dist/lib/gofer-installer.d.ts +32 -0
- package/dist/lib/gofer-installer.d.ts.map +1 -0
- package/dist/lib/gofer-installer.js +589 -0
- package/dist/lib/gofer-installer.js.map +1 -0
- package/dist/lib/gofer-refresh.d.ts +46 -0
- package/dist/lib/gofer-refresh.d.ts.map +1 -0
- package/dist/lib/gofer-refresh.js +536 -0
- package/dist/lib/gofer-refresh.js.map +1 -0
- package/dist/lib/next-route-exports.d.ts +6 -0
- package/dist/lib/next-route-exports.d.ts.map +1 -0
- package/dist/lib/next-route-exports.js +127 -0
- package/dist/lib/next-route-exports.js.map +1 -0
- package/dist/lib/npm.d.ts +2 -0
- package/dist/lib/npm.d.ts.map +1 -0
- package/dist/lib/npm.js +4 -0
- package/dist/lib/npm.js.map +1 -0
- package/dist/lib/object-type-defaults.d.ts +4 -0
- package/dist/lib/object-type-defaults.d.ts.map +1 -0
- package/dist/lib/object-type-defaults.js +72 -0
- package/dist/lib/object-type-defaults.js.map +1 -0
- package/dist/lib/output.d.ts +35 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +166 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/profile.d.ts +52 -0
- package/dist/lib/profile.d.ts.map +1 -0
- package/dist/lib/profile.js +116 -0
- package/dist/lib/profile.js.map +1 -0
- package/dist/lib/project-manifest.d.ts +42 -0
- package/dist/lib/project-manifest.d.ts.map +1 -0
- package/dist/lib/project-manifest.js +191 -0
- package/dist/lib/project-manifest.js.map +1 -0
- package/dist/lib/resourceapi-bundle.d.ts +33 -0
- package/dist/lib/resourceapi-bundle.d.ts.map +1 -0
- package/dist/lib/resourceapi-bundle.js +79 -0
- package/dist/lib/resourceapi-bundle.js.map +1 -0
- package/dist/lib/runtime-contract.d.ts +84 -0
- package/dist/lib/runtime-contract.d.ts.map +1 -0
- package/dist/lib/runtime-contract.js +318 -0
- package/dist/lib/runtime-contract.js.map +1 -0
- package/dist/lib/schema-builder.d.ts +28 -0
- package/dist/lib/schema-builder.d.ts.map +1 -0
- package/dist/lib/schema-builder.js +69 -0
- package/dist/lib/schema-builder.js.map +1 -0
- package/dist/lib/tenant-context.d.ts +127 -0
- package/dist/lib/tenant-context.d.ts.map +1 -0
- package/dist/lib/tenant-context.js +573 -0
- package/dist/lib/tenant-context.js.map +1 -0
- package/dist/lib/update-check.d.ts +52 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +271 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/update-maintenance.d.ts +15 -0
- package/dist/lib/update-maintenance.d.ts.map +1 -0
- package/dist/lib/update-maintenance.js +187 -0
- package/dist/lib/update-maintenance.js.map +1 -0
- package/dist/lib/utils.d.ts +23 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +48 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/workflow-provisioning.d.ts +54 -0
- package/dist/lib/workflow-provisioning.d.ts.map +1 -0
- package/dist/lib/workflow-provisioning.js +281 -0
- package/dist/lib/workflow-provisioning.js.map +1 -0
- package/package.json +51 -0
- package/resources/gofer/.gofer-version +7 -0
- package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +1287 -0
- package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +429 -0
- package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +635 -0
- package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +1159 -0
- package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +860 -0
- package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +886 -0
- package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +748 -0
- package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +924 -0
- package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +2269 -0
- package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +423 -0
- package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +508 -0
- package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +315 -0
- package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +558 -0
- package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +148 -0
- package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +119 -0
- package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +612 -0
- package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +114 -0
- package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +397 -0
- package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +561 -0
- package/resources/gofer/agents-skills/gofer_personality/SKILL.md +44 -0
- package/resources/gofer/agents-skills/gofer_plan/SKILL.md +40 -0
- package/resources/gofer/agents-skills/gofer_side/SKILL.md +45 -0
- package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +112 -0
- package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +112 -0
- package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +112 -0
- package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +112 -0
- package/resources/gofer/bash-scripts/check-context-health.sh +365 -0
- package/resources/gofer/bash-scripts/check-persona-pack.sh +81 -0
- package/resources/gofer/bash-scripts/check-prerequisites.sh +168 -0
- package/resources/gofer/bash-scripts/common.sh +192 -0
- package/resources/gofer/bash-scripts/create-new-feature.sh +260 -0
- package/resources/gofer/bash-scripts/install-optional-tools.sh +270 -0
- package/resources/gofer/bash-scripts/log-stage.sh +224 -0
- package/resources/gofer/bash-scripts/mark-task-complete.sh +74 -0
- package/resources/gofer/bash-scripts/pipeline-state.sh +306 -0
- package/resources/gofer/bash-scripts/read-failed-approaches.sh +114 -0
- package/resources/gofer/bash-scripts/read-session-memories.sh +96 -0
- package/resources/gofer/bash-scripts/save-checkpoint.sh +407 -0
- package/resources/gofer/bash-scripts/setup-plan.sh +62 -0
- package/resources/gofer/bash-scripts/sync-implementation-status.sh +47 -0
- package/resources/gofer/bash-scripts/update-agent-context.sh +772 -0
- package/resources/gofer/bash-scripts/validate-artifact.sh +335 -0
- package/resources/gofer/bash-scripts/verify-task.sh +384 -0
- package/resources/gofer/bash-scripts/write-failed-approach.sh +110 -0
- package/resources/gofer/bash-scripts/write-periodic-checkpoint.sh +128 -0
- package/resources/gofer/bash-scripts/write-session-memory.sh +118 -0
- package/resources/gofer/claude-agents/assumption-tracker.md +168 -0
- package/resources/gofer/claude-agents/business-metrics-analyzer.md +169 -0
- package/resources/gofer/claude-agents/business-problem-validator.md +168 -0
- package/resources/gofer/claude-agents/codebase-analyzer.md +124 -0
- package/resources/gofer/claude-agents/codebase-locator.md +95 -0
- package/resources/gofer/claude-agents/codebase-pattern-finder.md +180 -0
- package/resources/gofer/claude-agents/comms-writer.md +158 -0
- package/resources/gofer/claude-agents/engineer-review.md +169 -0
- package/resources/gofer/claude-agents/implement-bug-triangulator.md +94 -0
- package/resources/gofer/claude-agents/implement-code-review-council.md +89 -0
- package/resources/gofer/claude-agents/implement-doc-writer.md +89 -0
- package/resources/gofer/claude-agents/implement-error-hardener.md +84 -0
- package/resources/gofer/claude-agents/implement-performance-explorer.md +95 -0
- package/resources/gofer/claude-agents/implement-test-diversifier.md +82 -0
- package/resources/gofer/claude-agents/implement-variant-generator.md +80 -0
- package/resources/gofer/claude-agents/multi-perspective-judge.md +114 -0
- package/resources/gofer/claude-agents/plan-api-comparator.md +90 -0
- package/resources/gofer/claude-agents/plan-architecture-diverger.md +100 -0
- package/resources/gofer/claude-agents/plan-data-model-stress-tester.md +95 -0
- package/resources/gofer/claude-agents/plan-migration-path-finder.md +95 -0
- package/resources/gofer/claude-agents/plan-refactor-rewrite-advisor.md +97 -0
- package/resources/gofer/claude-agents/research-dependency-evaluator.md +106 -0
- package/resources/gofer/claude-agents/research-horizon-scanner.md +100 -0
- package/resources/gofer/claude-agents/research-market-scanner.md +137 -0
- package/resources/gofer/claude-agents/research-perspective-multiplier.md +102 -0
- package/resources/gofer/claude-agents/scope-creep-detector.md +152 -0
- package/resources/gofer/claude-agents/specify-ambiguity-detector.md +95 -0
- package/resources/gofer/claude-agents/specify-journey-stress-tester.md +92 -0
- package/resources/gofer/claude-agents/tasks-cross-cutting-scanner.md +91 -0
- package/resources/gofer/claude-agents/tasks-rollback-planner.md +89 -0
- package/resources/gofer/claude-agents/validate-security-red-team.md +102 -0
- package/resources/gofer/claude-agents/validation-correctness.md +103 -0
- package/resources/gofer/claude-agents/validation-integration.md +129 -0
- package/resources/gofer/claude-agents/validation-performance.md +120 -0
- package/resources/gofer/claude-agents/validation-security.md +115 -0
- package/resources/gofer/claude-agents/validation-standards.md +151 -0
- package/resources/gofer/claude-agents/validation-test-quality.md +146 -0
- package/resources/gofer/claude-agents/visual-bounded-context-writer.md +40 -0
- package/resources/gofer/claude-agents/visual-c4-writer.md +45 -0
- package/resources/gofer/claude-agents/visual-erd-writer.md +34 -0
- package/resources/gofer/claude-agents/visual-heatmap-writer.md +63 -0
- package/resources/gofer/claude-agents/visual-risk-writer.md +64 -0
- package/resources/gofer/claude-commands/0_gofer_start.md +1282 -0
- package/resources/gofer/claude-commands/0a_problem_validation.md +424 -0
- package/resources/gofer/claude-commands/10_gofer_cloud.md +630 -0
- package/resources/gofer/claude-commands/1_gofer_research.md +1154 -0
- package/resources/gofer/claude-commands/2_gofer_specify.md +855 -0
- package/resources/gofer/claude-commands/3_gofer_plan.md +881 -0
- package/resources/gofer/claude-commands/4_gofer_tasks.md +743 -0
- package/resources/gofer/claude-commands/5_gofer_implement.md +919 -0
- package/resources/gofer/claude-commands/6_gofer_validate.md +2264 -0
- package/resources/gofer/claude-commands/7_gofer_save.md +418 -0
- package/resources/gofer/claude-commands/7a_stakeholder_comms.md +503 -0
- package/resources/gofer/claude-commands/8_gofer_branding.md +310 -0
- package/resources/gofer/claude-commands/9_gofer_tests.md +553 -0
- package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +143 -0
- package/resources/gofer/claude-commands/gofer_check_workspace.md +114 -0
- package/resources/gofer/claude-commands/gofer_constitution.md +607 -0
- package/resources/gofer/claude-commands/gofer_diagnose.md +109 -0
- package/resources/gofer/claude-commands/gofer_eai_first_run.md +392 -0
- package/resources/gofer/claude-commands/gofer_hydrate.md +556 -0
- package/resources/gofer/claude-commands/gofer_personality.md +39 -0
- package/resources/gofer/claude-commands/gofer_plan.md +35 -0
- package/resources/gofer/claude-commands/gofer_side.md +40 -0
- package/resources/gofer/claude-commands/gofer_spec_summary.md +107 -0
- package/resources/gofer/claude-commands/gofer_tdd.md +107 -0
- package/resources/gofer/claude-commands/gofer_vocabulary.md +107 -0
- package/resources/gofer/claude-commands/gofer_zoom_out.md +107 -0
- package/resources/gofer/claude-skills/eai-gofer/SKILL.md +56 -0
- package/resources/gofer/commands/.gitkeep +0 -0
- package/resources/gofer/commands/0_gofer_start.md +1299 -0
- package/resources/gofer/commands/0a_problem_validation.md +405 -0
- package/resources/gofer/commands/10_gofer_cloud.md +611 -0
- package/resources/gofer/commands/1_gofer_research.md +1135 -0
- package/resources/gofer/commands/2_gofer_specify.md +836 -0
- package/resources/gofer/commands/3_gofer_plan.md +862 -0
- package/resources/gofer/commands/4_gofer_tasks.md +724 -0
- package/resources/gofer/commands/5_gofer_implement.md +900 -0
- package/resources/gofer/commands/6_gofer_validate.md +2245 -0
- package/resources/gofer/commands/7_gofer_save.md +399 -0
- package/resources/gofer/commands/7a_stakeholder_comms.md +484 -0
- package/resources/gofer/commands/8_gofer_branding.md +291 -0
- package/resources/gofer/commands/9_gofer_tests.md +534 -0
- package/resources/gofer/commands/gofer_bootstrap_workspace.md +159 -0
- package/resources/gofer/commands/gofer_check_workspace.md +130 -0
- package/resources/gofer/commands/gofer_constitution.md +588 -0
- package/resources/gofer/commands/gofer_diagnose.md +89 -0
- package/resources/gofer/commands/gofer_eai_first_run.md +392 -0
- package/resources/gofer/commands/gofer_hydrate.md +537 -0
- package/resources/gofer/commands/gofer_personality.md +61 -0
- package/resources/gofer/commands/gofer_plan.md +51 -0
- package/resources/gofer/commands/gofer_side.md +56 -0
- package/resources/gofer/commands/gofer_spec_summary.md +87 -0
- package/resources/gofer/commands/gofer_tdd.md +87 -0
- package/resources/gofer/commands/gofer_vocabulary.md +87 -0
- package/resources/gofer/commands/gofer_zoom_out.md +87 -0
- package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +13 -0
- package/resources/gofer/copilot-instructions/language-server.instructions.md +49 -0
- package/resources/gofer/copilot-instructions/typescript.instructions.md +47 -0
- package/resources/gofer/copilot-instructions/vscode-extension.instructions.md +46 -0
- package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +1308 -0
- package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +429 -0
- package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +644 -0
- package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +1177 -0
- package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +878 -0
- package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +904 -0
- package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +766 -0
- package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +942 -0
- package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +2277 -0
- package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +433 -0
- package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +516 -0
- package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +323 -0
- package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +566 -0
- package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +161 -0
- package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +132 -0
- package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +621 -0
- package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +127 -0
- package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +410 -0
- package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +571 -0
- package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +57 -0
- package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +53 -0
- package/resources/gofer/copilot-prompts/gofer_side.prompt.md +58 -0
- package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +125 -0
- package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +125 -0
- package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +125 -0
- package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +125 -0
- package/resources/gofer/gemini/agents/assumption-tracker.md +171 -0
- package/resources/gofer/gemini/agents/business-metrics-analyzer.md +172 -0
- package/resources/gofer/gemini/agents/business-problem-validator.md +171 -0
- package/resources/gofer/gemini/agents/codebase-analyzer.md +127 -0
- package/resources/gofer/gemini/agents/codebase-locator.md +98 -0
- package/resources/gofer/gemini/agents/codebase-pattern-finder.md +183 -0
- package/resources/gofer/gemini/agents/comms-writer.md +161 -0
- package/resources/gofer/gemini/agents/engineer-review.md +172 -0
- package/resources/gofer/gemini/agents/implement-bug-triangulator.md +97 -0
- package/resources/gofer/gemini/agents/implement-code-review-council.md +92 -0
- package/resources/gofer/gemini/agents/implement-doc-writer.md +92 -0
- package/resources/gofer/gemini/agents/implement-error-hardener.md +87 -0
- package/resources/gofer/gemini/agents/implement-performance-explorer.md +98 -0
- package/resources/gofer/gemini/agents/implement-test-diversifier.md +85 -0
- package/resources/gofer/gemini/agents/implement-variant-generator.md +83 -0
- package/resources/gofer/gemini/agents/multi-perspective-judge.md +117 -0
- package/resources/gofer/gemini/agents/plan-api-comparator.md +93 -0
- package/resources/gofer/gemini/agents/plan-architecture-diverger.md +103 -0
- package/resources/gofer/gemini/agents/plan-data-model-stress-tester.md +98 -0
- package/resources/gofer/gemini/agents/plan-migration-path-finder.md +98 -0
- package/resources/gofer/gemini/agents/plan-refactor-rewrite-advisor.md +100 -0
- package/resources/gofer/gemini/agents/research-dependency-evaluator.md +109 -0
- package/resources/gofer/gemini/agents/research-horizon-scanner.md +103 -0
- package/resources/gofer/gemini/agents/research-market-scanner.md +140 -0
- package/resources/gofer/gemini/agents/research-perspective-multiplier.md +105 -0
- package/resources/gofer/gemini/agents/scope-creep-detector.md +155 -0
- package/resources/gofer/gemini/agents/specify-ambiguity-detector.md +98 -0
- package/resources/gofer/gemini/agents/specify-journey-stress-tester.md +95 -0
- package/resources/gofer/gemini/agents/tasks-cross-cutting-scanner.md +94 -0
- package/resources/gofer/gemini/agents/tasks-rollback-planner.md +92 -0
- package/resources/gofer/gemini/agents/validate-security-red-team.md +105 -0
- package/resources/gofer/gemini/agents/validation-correctness.md +106 -0
- package/resources/gofer/gemini/agents/validation-integration.md +132 -0
- package/resources/gofer/gemini/agents/validation-performance.md +123 -0
- package/resources/gofer/gemini/agents/validation-security.md +118 -0
- package/resources/gofer/gemini/agents/validation-standards.md +154 -0
- package/resources/gofer/gemini/agents/validation-test-quality.md +149 -0
- package/resources/gofer/gemini/agents/visual-bounded-context-writer.md +40 -0
- package/resources/gofer/gemini/agents/visual-c4-writer.md +44 -0
- package/resources/gofer/gemini/agents/visual-erd-writer.md +36 -0
- package/resources/gofer/gemini/agents/visual-heatmap-writer.md +63 -0
- package/resources/gofer/gemini/agents/visual-risk-writer.md +64 -0
- package/resources/gofer/gemini/commands/gofer/.gitkeep +0 -0
- package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +1282 -0
- package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +424 -0
- package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +630 -0
- package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +1154 -0
- package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +855 -0
- package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +881 -0
- package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +743 -0
- package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +919 -0
- package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +2264 -0
- package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +418 -0
- package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +503 -0
- package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +310 -0
- package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +553 -0
- package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +143 -0
- package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +114 -0
- package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +607 -0
- package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +109 -0
- package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +392 -0
- package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +556 -0
- package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_personality.md +39 -0
- package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_plan.md +35 -0
- package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_side.md +40 -0
- package/resources/gofer/gemini/commands/gofer/gofer_side.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +107 -0
- package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +107 -0
- package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +107 -0
- package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +107 -0
- package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/manifest.json +32 -0
- package/resources/gofer/gemini/extension.json +16 -0
- package/resources/gofer/github-agents/gofer-business.agent.md +20 -0
- package/resources/gofer/github-agents/gofer-implement.agent.md +15 -0
- package/resources/gofer/github-agents/gofer-plan.agent.md +15 -0
- package/resources/gofer/github-agents/gofer-research.agent.md +15 -0
- package/resources/gofer/github-agents/gofer-validate.agent.md +10 -0
- package/resources/gofer/github-skills/eai-gofer/SKILL.md +56 -0
- package/resources/gofer/hook-scripts/agent-stop.mjs +655 -0
- package/resources/gofer/hook-scripts/log-stage-launch-time.mjs +77 -0
- package/resources/gofer/hook-scripts/post-tool-use.mjs +333 -0
- package/resources/gofer/hook-scripts/queued-input.mjs +188 -0
- package/resources/gofer/hook-scripts/session-lifecycle.mjs +93 -0
- package/resources/gofer/hook-scripts/user-prompt-submit.mjs +228 -0
- package/resources/gofer/instruction-templates/base/agents-base.md +37 -0
- package/resources/gofer/instruction-templates/base/claude-base.md +7 -0
- package/resources/gofer/instruction-templates/base/copilot-base.md +26 -0
- package/resources/gofer/instruction-templates/gofer/gofer-claude.md +5 -0
- package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +9 -0
- package/resources/gofer/instruction-templates/languages/generic.md +7 -0
- package/resources/gofer/instruction-templates/languages/go.md +8 -0
- package/resources/gofer/instruction-templates/languages/java.md +8 -0
- package/resources/gofer/instruction-templates/languages/python.md +9 -0
- package/resources/gofer/instruction-templates/languages/rust.md +9 -0
- package/resources/gofer/instruction-templates/languages/typescript.md +19 -0
- package/resources/gofer/instruction-templates/workflow/principles.md +52 -0
- package/resources/gofer/memory/constitution.md +391 -0
- package/resources/gofer/memory/context-profiles.yaml +74 -0
- package/resources/gofer/memory/decisions/000-use-adr-for-decisions.md +67 -0
- package/resources/gofer/memory/decisions/001-di-framework.md +190 -0
- package/resources/gofer/memory/decisions/002-module-extraction.md +305 -0
- package/resources/gofer/memory/decisions/003-error-handling.md +368 -0
- package/resources/gofer/memory/decisions/004-cache-eviction.md +436 -0
- package/resources/gofer/memory/decisions/005-constants-management.md +520 -0
- package/resources/gofer/memory/decisions/README.md +129 -0
- package/resources/gofer/memory/diagrams/di-container.mmd +321 -0
- package/resources/gofer/memory/diagrams/extension-activation.mmd +184 -0
- package/resources/gofer/memory/diagrams/module-dependencies.mmd +264 -0
- package/resources/gofer/memory/gofer-model-policy.yaml +97 -0
- package/resources/gofer/memory/lessons.md +46 -0
- package/resources/gofer/node-scripts/canonical-descriptions.mjs +86 -0
- package/resources/gofer/node-scripts/check-version-alignment.mjs +131 -0
- package/resources/gofer/node-scripts/codex-doctor.mjs +425 -0
- package/resources/gofer/node-scripts/generate-commands.mjs +1366 -0
- package/resources/gofer/node-scripts/generate-issues.js +563 -0
- package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +893 -0
- package/resources/gofer/node-scripts/gofer-loop-audit.mjs +541 -0
- package/resources/gofer/node-scripts/gofer-performance-report.mjs +306 -0
- package/resources/gofer/node-scripts/gofer-workspace-bootstrap.mjs +56 -0
- package/resources/gofer/node-scripts/gofer-workspace-check.mjs +56 -0
- package/resources/gofer/node-scripts/lib/ai-leverage-tagger.mjs +103 -0
- package/resources/gofer/node-scripts/lib/assemble-stakeholder-pack.mjs +114 -0
- package/resources/gofer/node-scripts/lib/marp-deck.mjs +87 -0
- package/resources/gofer/node-scripts/lib/mermaid-tabular-fallback.mjs +264 -0
- package/resources/gofer/node-scripts/lib/render-visual.mjs +54 -0
- package/resources/gofer/node-scripts/lib/validate-aliases.mjs +85 -0
- package/resources/gofer/node-scripts/lib/visual-counts.mjs +44 -0
- package/resources/gofer/node-scripts/lib/visual-pass-pipeline.mjs +134 -0
- package/resources/gofer/node-scripts/mermaid-export.mjs +72 -0
- package/resources/gofer/node-scripts/package-agent-plugin.mjs +940 -0
- package/resources/gofer/node-scripts/parse-stage-command.mjs +211 -0
- package/resources/gofer/node-scripts/schemas/.gitkeep +0 -0
- package/resources/gofer/node-scripts/schemas/stage-command.schema.json +72 -0
- package/resources/gofer/node-scripts/sync-extension-resources.mjs +110 -0
- package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +1166 -0
- package/resources/gofer/powershell-scripts/install-optional-tools.ps1 +214 -0
- package/resources/gofer/references/platform/README.md +17 -0
- package/resources/gofer/references/platform/deployment-repo.md +9 -0
- package/resources/gofer/references/platform/eai-app-template.md +45 -0
- package/resources/gofer/references/platform/eai-config-driven-ui.md +156 -0
- package/resources/gofer/references/platform/eai-error-catalog.yaml +197 -0
- package/resources/gofer/references/platform/eai-repo-contract.md +134 -0
- package/resources/gofer/references/platform/eai-service-patterns.md +56 -0
- package/resources/gofer/references/platform/eai.md +85 -0
- package/resources/gofer/references/platform/vertical-template.md +49 -0
- package/resources/gofer/specify-commands/.gitkeep +0 -0
- package/resources/gofer/specify-commands/0_gofer_start.md +1299 -0
- package/resources/gofer/specify-commands/0a_problem_validation.md +405 -0
- package/resources/gofer/specify-commands/10_gofer_cloud.md +611 -0
- package/resources/gofer/specify-commands/1_gofer_research.md +1135 -0
- package/resources/gofer/specify-commands/2_gofer_specify.md +836 -0
- package/resources/gofer/specify-commands/3_gofer_plan.md +862 -0
- package/resources/gofer/specify-commands/4_gofer_tasks.md +724 -0
- package/resources/gofer/specify-commands/5_gofer_implement.md +900 -0
- package/resources/gofer/specify-commands/6_gofer_validate.md +2245 -0
- package/resources/gofer/specify-commands/7_gofer_save.md +399 -0
- package/resources/gofer/specify-commands/7a_stakeholder_comms.md +484 -0
- package/resources/gofer/specify-commands/8_gofer_branding.md +291 -0
- package/resources/gofer/specify-commands/9_gofer_tests.md +534 -0
- package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +159 -0
- package/resources/gofer/specify-commands/gofer_check_workspace.md +130 -0
- package/resources/gofer/specify-commands/gofer_constitution.md +588 -0
- package/resources/gofer/specify-commands/gofer_diagnose.md +89 -0
- package/resources/gofer/specify-commands/gofer_eai_first_run.md +392 -0
- package/resources/gofer/specify-commands/gofer_hydrate.md +537 -0
- package/resources/gofer/specify-commands/gofer_personality.md +61 -0
- package/resources/gofer/specify-commands/gofer_plan.md +51 -0
- package/resources/gofer/specify-commands/gofer_side.md +56 -0
- package/resources/gofer/specify-commands/gofer_spec_summary.md +87 -0
- package/resources/gofer/specify-commands/gofer_tdd.md +87 -0
- package/resources/gofer/specify-commands/gofer_vocabulary.md +87 -0
- package/resources/gofer/specify-commands/gofer_zoom_out.md +87 -0
- package/resources/gofer/system-skills/0_gofer_start/SKILL.md +1287 -0
- package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +429 -0
- package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +635 -0
- package/resources/gofer/system-skills/1_gofer_research/SKILL.md +1159 -0
- package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +860 -0
- package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +886 -0
- package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +748 -0
- package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +924 -0
- package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +2269 -0
- package/resources/gofer/system-skills/7_gofer_save/SKILL.md +423 -0
- package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +508 -0
- package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +315 -0
- package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +558 -0
- package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +148 -0
- package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +119 -0
- package/resources/gofer/system-skills/gofer_constitution/SKILL.md +612 -0
- package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +114 -0
- package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +397 -0
- package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +561 -0
- package/resources/gofer/system-skills/gofer_personality/SKILL.md +44 -0
- package/resources/gofer/system-skills/gofer_plan/SKILL.md +40 -0
- package/resources/gofer/system-skills/gofer_side/SKILL.md +45 -0
- package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +112 -0
- package/resources/gofer/system-skills/gofer_tdd/SKILL.md +112 -0
- package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +112 -0
- package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +112 -0
- package/resources/gofer/templates/agent-file-template.md +28 -0
- package/resources/gofer/templates/assumptions-template.md +94 -0
- package/resources/gofer/templates/audit-history-template.md +35 -0
- package/resources/gofer/templates/brand/brand-profile-template.json +45 -0
- package/resources/gofer/templates/brand/document-style-template.md +50 -0
- package/resources/gofer/templates/brand/marp-theme-template.css +58 -0
- package/resources/gofer/templates/brownfield-analysis.md +44 -0
- package/resources/gofer/templates/business-metrics-template.md +120 -0
- package/resources/gofer/templates/business-owner-summary-template.md +83 -0
- package/resources/gofer/templates/checklist-template.md +40 -0
- package/resources/gofer/templates/ciso-security-summary-template.md +70 -0
- package/resources/gofer/templates/context-bundle-template.md +76 -0
- package/resources/gofer/templates/contract-pack-template.md +109 -0
- package/resources/gofer/templates/cto-architecture-summary-template.md +83 -0
- package/resources/gofer/templates/discovery-template.md +92 -0
- package/resources/gofer/templates/eai-preflight-template.md +144 -0
- package/resources/gofer/templates/goal-ledger-template.json +69 -0
- package/resources/gofer/templates/gofer-model-policy.yaml +97 -0
- package/resources/gofer/templates/issues-template.md +106 -0
- package/resources/gofer/templates/journey/base-journey.md +95 -0
- package/resources/gofer/templates/journey/industry-variants.yaml +277 -0
- package/resources/gofer/templates/loop-contract-template.json +68 -0
- package/resources/gofer/templates/plan-template.md +215 -0
- package/resources/gofer/templates/problem-brief-template.md +85 -0
- package/resources/gofer/templates/proposal-review-template.md +79 -0
- package/resources/gofer/templates/research-template.md +222 -0
- package/resources/gofer/templates/reuse-scan-template.md +43 -0
- package/resources/gofer/templates/sequence-diagrams/option-spectrum.yaml +178 -0
- package/resources/gofer/templates/service-fit-matrix-template.md +29 -0
- package/resources/gofer/templates/session-handoff-template.md +172 -0
- package/resources/gofer/templates/spec-summary-template.md +118 -0
- package/resources/gofer/templates/spec-template.md +196 -0
- package/resources/gofer/templates/stakeholder-comms-template.md +330 -0
- package/resources/gofer/templates/stakeholder-review-index-template.md +54 -0
- package/resources/gofer/templates/tasks-template.md +323 -0
- package/resources/gofer/templates/ui-approval-template.md +32 -0
- package/resources/gofer/templates/ui-preview-brief-template.md +65 -0
- package/resources/gofer/templates/ui-review-log-template.md +11 -0
- package/resources/gofer/templates/visuals/.gitkeep +0 -0
- package/resources/gofer/templates/visuals/bounded-context-map.md +19 -0
- package/resources/gofer/templates/visuals/bounded-context-template.md +47 -0
- package/resources/gofer/templates/visuals/c4-container-template.md +38 -0
- package/resources/gofer/templates/visuals/c4-container.md +20 -0
- package/resources/gofer/templates/visuals/c4-context-template.md +46 -0
- package/resources/gofer/templates/visuals/capability-heatmap-template.md +54 -0
- package/resources/gofer/templates/visuals/data-model-erd-template.md +41 -0
- package/resources/gofer/templates/visuals/erd.md +19 -0
- package/resources/gofer/templates/visuals/impact-canvas.md +40 -0
- package/resources/gofer/templates/visuals/risk-heatmap-template.md +51 -0
- package/resources/gofer/templates/visuals/roi-projection.md +17 -0
- package/resources/gofer/templates/visuals/value-stream-asis.md +16 -0
- package/resources/gofer/templates/visuals/value-stream-tobe.md +18 -0
- package/resources/gofer/templates/working-backwards-prfaq-template.md +165 -0
- package/resources/linked-sources.json +25 -0
|
@@ -0,0 +1,1166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { promises as fs } from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { parseStageCommand } from './parse-stage-command.mjs';
|
|
7
|
+
|
|
8
|
+
export const GOFER_VERSION_FILE = path.join('.specify', '.gofer-version');
|
|
9
|
+
export const CORE_SENTINELS = [
|
|
10
|
+
GOFER_VERSION_FILE,
|
|
11
|
+
path.join('.specify', 'commands', '0_gofer_start.md'),
|
|
12
|
+
path.join('.specify', 'templates', 'spec-template.md'),
|
|
13
|
+
path.join('.specify', 'templates', 'loop-contract-template.json'),
|
|
14
|
+
path.join('.specify', 'templates', 'working-backwards-prfaq-template.md'),
|
|
15
|
+
path.join('.specify', 'templates', 'business-owner-summary-template.md'),
|
|
16
|
+
path.join('.specify', 'templates', 'cto-architecture-summary-template.md'),
|
|
17
|
+
path.join('.specify', 'templates', 'ciso-security-summary-template.md'),
|
|
18
|
+
path.join('.specify', 'templates', 'stakeholder-review-index-template.md'),
|
|
19
|
+
path.join('.specify', 'templates', 'brand', 'brand-profile-template.json'),
|
|
20
|
+
path.join('.specify', 'templates', 'brand', 'document-style-template.md'),
|
|
21
|
+
path.join('.specify', 'templates', 'brand', 'marp-theme-template.css'),
|
|
22
|
+
path.join('.specify', 'scripts', 'bash', 'create-new-feature.sh'),
|
|
23
|
+
path.join('.specify', 'scripts', 'node', 'parse-stage-command.mjs'),
|
|
24
|
+
path.join('.specify', 'scripts', 'node', 'gofer-loop-audit.mjs'),
|
|
25
|
+
path.join('.specify', 'scripts', 'hooks', 'post-tool-use.mjs'),
|
|
26
|
+
path.join('.specify', 'scripts', 'powershell', 'install-optional-tools.ps1'),
|
|
27
|
+
path.join('.specify', 'references', 'platform', 'README.md'),
|
|
28
|
+
path.join('.specify', 'references', 'platform', 'eai.md'),
|
|
29
|
+
path.join('.specify', 'references', 'platform', 'eai-repo-contract.md'),
|
|
30
|
+
path.join('.specify', 'references', 'platform', 'eai-error-catalog.yaml'),
|
|
31
|
+
path.join('.specify', 'templates', 'gofer-model-policy.yaml'),
|
|
32
|
+
path.join('.specify', 'memory', 'gofer-model-policy.yaml'),
|
|
33
|
+
path.join('.specify', 'specs'),
|
|
34
|
+
path.join('.specify', 'memory'),
|
|
35
|
+
];
|
|
36
|
+
const LEGACY_MANAGED_PATHS = [
|
|
37
|
+
path.join('.specify', 'commands', '0_business_scenario.md'),
|
|
38
|
+
path.join('.claude', 'commands', '0_business_scenario.md'),
|
|
39
|
+
path.join('.github', 'prompts', '0_business_scenario.prompt.md'),
|
|
40
|
+
path.join('.agents', 'skills', '0_business_scenario'),
|
|
41
|
+
path.join('.system', 'skills', '0_business_scenario'),
|
|
42
|
+
path.join('.gemini', 'commands', 'gofer', '0_business_scenario.md'),
|
|
43
|
+
path.join('.gemini', 'commands', 'gofer', '0_business_scenario.toml'),
|
|
44
|
+
];
|
|
45
|
+
const LEGACY_MANAGED_ARCHIVE_ROOT = path.join('.specify', 'logs', 'legacy-command-backups');
|
|
46
|
+
|
|
47
|
+
export const HOST_POLICIES = {
|
|
48
|
+
auto: { required: [] },
|
|
49
|
+
claude: {
|
|
50
|
+
required: ['AGENTS.md', 'CLAUDE.md', path.join('.claude', 'settings.json')],
|
|
51
|
+
},
|
|
52
|
+
codex: {
|
|
53
|
+
required: ['AGENTS.md'],
|
|
54
|
+
},
|
|
55
|
+
copilot: {
|
|
56
|
+
required: [path.join('.github', 'copilot-instructions.md')],
|
|
57
|
+
},
|
|
58
|
+
gemini: {
|
|
59
|
+
required: [],
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const WORKSPACE_MARKERS = [
|
|
64
|
+
'.git',
|
|
65
|
+
'package.json',
|
|
66
|
+
'pyproject.toml',
|
|
67
|
+
'go.mod',
|
|
68
|
+
'Cargo.toml',
|
|
69
|
+
'.specify',
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const EAI_CONFIG_DIR = path.join('src', 'eai.config');
|
|
73
|
+
const EAI_OBJECT_TYPES_MARKER = path.join(EAI_CONFIG_DIR, 'object-types.ts');
|
|
74
|
+
const EAI_REGISTER_MARKER = path.join(EAI_CONFIG_DIR, 'register.ts');
|
|
75
|
+
const EAI_MANIFEST_MARKER = 'manifest.yml';
|
|
76
|
+
const EAI_RUNTIME_CONTRACT_MARKER = 'eai.runtime.json';
|
|
77
|
+
|
|
78
|
+
const EXTENSION_RESOURCE_PATHS = new Map([
|
|
79
|
+
[path.join('.specify', 'commands'), path.join('resources', 'specify-commands')],
|
|
80
|
+
[path.join('.specify', 'references'), path.join('resources', 'references')],
|
|
81
|
+
[path.join('.specify', 'templates'), path.join('resources', 'templates')],
|
|
82
|
+
[path.join('.specify', 'scripts', 'bash'), path.join('resources', 'bash-scripts')],
|
|
83
|
+
[path.join('.specify', 'scripts', 'node'), path.join('resources', 'node-scripts')],
|
|
84
|
+
[path.join('.specify', 'scripts', 'hooks'), path.join('resources', 'hook-scripts')],
|
|
85
|
+
[
|
|
86
|
+
path.join('.specify', 'scripts', 'powershell'),
|
|
87
|
+
path.join('resources', 'powershell-scripts'),
|
|
88
|
+
],
|
|
89
|
+
['commands', path.join('resources', 'claude-commands')],
|
|
90
|
+
['agents', path.join('resources', 'claude-agents')],
|
|
91
|
+
[path.join('.claude', 'skills'), path.join('resources', 'claude-skills')],
|
|
92
|
+
[path.join('.github', 'agents'), path.join('resources', 'github-agents')],
|
|
93
|
+
[path.join('.github', 'prompts'), path.join('resources', 'copilot-prompts')],
|
|
94
|
+
[path.join('.github', 'instructions'), path.join('resources', 'copilot-instructions')],
|
|
95
|
+
[path.join('.github', 'skills'), path.join('resources', 'github-skills')],
|
|
96
|
+
[path.join('.gemini'), path.join('resources', 'gemini')],
|
|
97
|
+
[path.join('.agents', 'skills'), 'skills'],
|
|
98
|
+
[path.join('.system', 'skills'), 'skills'],
|
|
99
|
+
]);
|
|
100
|
+
|
|
101
|
+
const GOFER_GITIGNORE_ENTRIES = [
|
|
102
|
+
'.specify/hooks/',
|
|
103
|
+
'.specify/memory/local.json',
|
|
104
|
+
'.specify/memory/dependency-graph.json',
|
|
105
|
+
'.specify/specs/*/.branch-info.json',
|
|
106
|
+
'.specify/logs/',
|
|
107
|
+
'.specify/memory/checkpoints/',
|
|
108
|
+
'.specify/memory/context-health-state.json',
|
|
109
|
+
'.specify/memory/observation-cache/',
|
|
110
|
+
'.specify/specs/*/research-index.json',
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
const CLAUDE_HOOKS_CONFIG = {
|
|
114
|
+
UserPromptSubmit: [
|
|
115
|
+
{
|
|
116
|
+
hooks: [
|
|
117
|
+
{
|
|
118
|
+
type: 'command',
|
|
119
|
+
command: 'node "$CLAUDE_PROJECT_DIR/.specify/scripts/hooks/user-prompt-submit.mjs"',
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
PostToolUse: [
|
|
125
|
+
{
|
|
126
|
+
matcher: '',
|
|
127
|
+
hooks: [
|
|
128
|
+
{
|
|
129
|
+
type: 'command',
|
|
130
|
+
command: 'node "$CLAUDE_PROJECT_DIR/.specify/scripts/hooks/post-tool-use.mjs"',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
Stop: [
|
|
136
|
+
{
|
|
137
|
+
hooks: [
|
|
138
|
+
{
|
|
139
|
+
type: 'command',
|
|
140
|
+
command: 'node "$CLAUDE_PROJECT_DIR/.specify/scripts/hooks/agent-stop.mjs"',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
function createEmptyProjectInfo(workspaceRoot) {
|
|
148
|
+
return {
|
|
149
|
+
name: path.basename(workspaceRoot),
|
|
150
|
+
language: 'unknown',
|
|
151
|
+
framework: null,
|
|
152
|
+
testRunner: null,
|
|
153
|
+
testCommand: null,
|
|
154
|
+
buildCommand: null,
|
|
155
|
+
lintCommand: null,
|
|
156
|
+
formatCommand: null,
|
|
157
|
+
packageManager: null,
|
|
158
|
+
eaiInitialized: false,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function normalizeHost(host = 'auto') {
|
|
163
|
+
const normalized = String(host || 'auto').trim().toLowerCase();
|
|
164
|
+
return Object.prototype.hasOwnProperty.call(HOST_POLICIES, normalized) ? normalized : 'auto';
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function scriptRootFromUrl(scriptUrl) {
|
|
168
|
+
const filePath = fileURLToPath(scriptUrl);
|
|
169
|
+
const dirPath = path.dirname(filePath);
|
|
170
|
+
if (path.basename(path.dirname(dirPath)) === 'resources') {
|
|
171
|
+
return path.resolve(dirPath, '..', '..');
|
|
172
|
+
}
|
|
173
|
+
return path.resolve(dirPath, '..', '..', '..');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export async function pathExists(targetPath) {
|
|
177
|
+
try {
|
|
178
|
+
await fs.access(targetPath);
|
|
179
|
+
return true;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (error?.code === 'ENOENT') {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function buildArchiveStamp() {
|
|
189
|
+
return `${new Date().toISOString().replace(/[:.]/g, '-')}-${process.pid}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function movePathPreservingAcrossDevices(sourcePath, targetPath) {
|
|
193
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
194
|
+
try {
|
|
195
|
+
await fs.rename(sourcePath, targetPath);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
if (error?.code !== 'EXDEV') {
|
|
198
|
+
throw error;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await fs.cp(sourcePath, targetPath, {
|
|
202
|
+
recursive: true,
|
|
203
|
+
force: true,
|
|
204
|
+
dereference: false,
|
|
205
|
+
});
|
|
206
|
+
await fs.rm(sourcePath, { recursive: true, force: true });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function archiveLegacyManagedPath(workspaceRoot, relativePath, archiveStamp, dryRun) {
|
|
211
|
+
const archiveRelativePath = path.join(LEGACY_MANAGED_ARCHIVE_ROOT, archiveStamp, relativePath);
|
|
212
|
+
if (!dryRun) {
|
|
213
|
+
await movePathPreservingAcrossDevices(
|
|
214
|
+
path.join(workspaceRoot, relativePath),
|
|
215
|
+
path.join(workspaceRoot, archiveRelativePath)
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return archiveRelativePath;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function removeLegacyManagedPaths(workspaceRoot, dryRun) {
|
|
223
|
+
const archived = [];
|
|
224
|
+
const archiveStamp = buildArchiveStamp();
|
|
225
|
+
for (const relativePath of LEGACY_MANAGED_PATHS) {
|
|
226
|
+
const targetPath = path.join(workspaceRoot, relativePath);
|
|
227
|
+
if (!(await pathExists(targetPath))) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
archived.push({
|
|
232
|
+
relativePath,
|
|
233
|
+
archivePath: await archiveLegacyManagedPath(workspaceRoot, relativePath, archiveStamp, dryRun),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return archived;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function resolveSourcePath(sourceRoot, relativePath) {
|
|
240
|
+
const directPath = path.join(sourceRoot, relativePath);
|
|
241
|
+
if (await pathExists(directPath)) {
|
|
242
|
+
return directPath;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const resourceRelativePath = EXTENSION_RESOURCE_PATHS.get(path.normalize(relativePath));
|
|
246
|
+
if (resourceRelativePath) {
|
|
247
|
+
const resourcePath = path.join(sourceRoot, resourceRelativePath);
|
|
248
|
+
if (await pathExists(resourcePath)) {
|
|
249
|
+
return resourcePath;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return directPath;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function readSourceFile(sourceRoot, relativePath, encoding = 'utf8') {
|
|
257
|
+
return fs.readFile(await resolveSourcePath(sourceRoot, relativePath), encoding);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function readJsonIfExists(filePath) {
|
|
261
|
+
try {
|
|
262
|
+
return JSON.parse(await fs.readFile(filePath, 'utf8'));
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (error?.code === 'ENOENT') {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export async function detectGoferVersion(sourceRoot) {
|
|
272
|
+
const candidates = [
|
|
273
|
+
{
|
|
274
|
+
path: path.join(sourceRoot, '.eai-gofer-plugin-version'),
|
|
275
|
+
type: 'marker',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
path: path.join(sourceRoot, 'plugin.json'),
|
|
279
|
+
type: 'manifest',
|
|
280
|
+
validName: (name) => name === 'eai-gofer',
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
path: path.join(sourceRoot, 'package.json'),
|
|
284
|
+
type: 'manifest',
|
|
285
|
+
validName: (name) => name === 'eai-gofer' || name === 'gofer',
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
path: path.join(sourceRoot, 'extension', 'package.json'),
|
|
289
|
+
type: 'manifest',
|
|
290
|
+
validName: (name) => name === 'gofer',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
path: path.join(sourceRoot, GOFER_VERSION_FILE),
|
|
294
|
+
type: 'marker',
|
|
295
|
+
},
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
for (const candidate of candidates) {
|
|
299
|
+
try {
|
|
300
|
+
const content = await fs.readFile(candidate.path, 'utf8');
|
|
301
|
+
if (candidate.type === 'marker') {
|
|
302
|
+
const firstLine = content.split('\n')[0]?.trim();
|
|
303
|
+
if (firstLine) {
|
|
304
|
+
return firstLine;
|
|
305
|
+
}
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const parsed = JSON.parse(content);
|
|
310
|
+
const name = typeof parsed.name === 'string' ? parsed.name.trim() : '';
|
|
311
|
+
if (
|
|
312
|
+
candidate.validName?.(name) &&
|
|
313
|
+
typeof parsed.version === 'string' &&
|
|
314
|
+
parsed.version.trim().length > 0
|
|
315
|
+
) {
|
|
316
|
+
return parsed.version.trim();
|
|
317
|
+
}
|
|
318
|
+
} catch (error) {
|
|
319
|
+
if (error?.code !== 'ENOENT') {
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return '0.0.0';
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export async function findWorkspaceRoot(startDir = process.cwd()) {
|
|
329
|
+
let current = path.resolve(startDir);
|
|
330
|
+
const fallbackRoot = current;
|
|
331
|
+
|
|
332
|
+
while (true) {
|
|
333
|
+
for (const marker of WORKSPACE_MARKERS) {
|
|
334
|
+
if (await pathExists(path.join(current, marker))) {
|
|
335
|
+
return current;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const parent = path.dirname(current);
|
|
340
|
+
if (parent === current) {
|
|
341
|
+
return fallbackRoot;
|
|
342
|
+
}
|
|
343
|
+
current = parent;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export async function loadStageMetadata(sourceRoot) {
|
|
348
|
+
const commandsDir = await resolveSourcePath(sourceRoot, path.join('.specify', 'commands'));
|
|
349
|
+
const entries = (await fs.readdir(commandsDir))
|
|
350
|
+
.filter((entry) => entry.endsWith('.md') && entry !== '.gitkeep')
|
|
351
|
+
.sort((left, right) => left.localeCompare(right, undefined, { numeric: true }));
|
|
352
|
+
|
|
353
|
+
const stages = [];
|
|
354
|
+
for (const entry of entries) {
|
|
355
|
+
const filePath = path.join(commandsDir, entry);
|
|
356
|
+
const parsed = await parseStageCommand(filePath);
|
|
357
|
+
stages.push({
|
|
358
|
+
stem: path.basename(entry, '.md'),
|
|
359
|
+
...parsed,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return stages;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async function detectPackageManager(workspaceRoot) {
|
|
367
|
+
if (await pathExists(path.join(workspaceRoot, 'bun.lockb'))) {
|
|
368
|
+
return 'bun';
|
|
369
|
+
}
|
|
370
|
+
if (await pathExists(path.join(workspaceRoot, 'pnpm-lock.yaml'))) {
|
|
371
|
+
return 'pnpm';
|
|
372
|
+
}
|
|
373
|
+
if (await pathExists(path.join(workspaceRoot, 'yarn.lock'))) {
|
|
374
|
+
return 'yarn';
|
|
375
|
+
}
|
|
376
|
+
if (await pathExists(path.join(workspaceRoot, 'package-lock.json'))) {
|
|
377
|
+
return 'npm';
|
|
378
|
+
}
|
|
379
|
+
if (await pathExists(path.join(workspaceRoot, 'pyproject.toml'))) {
|
|
380
|
+
return 'poetry';
|
|
381
|
+
}
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export async function detectProjectInfo(workspaceRoot) {
|
|
386
|
+
const info = createEmptyProjectInfo(workspaceRoot);
|
|
387
|
+
info.packageManager = await detectPackageManager(workspaceRoot);
|
|
388
|
+
info.eaiInitialized = await detectEaiInitialized(workspaceRoot);
|
|
389
|
+
|
|
390
|
+
if (await pathExists(path.join(workspaceRoot, 'tsconfig.json'))) {
|
|
391
|
+
info.language = 'typescript';
|
|
392
|
+
} else if (await pathExists(path.join(workspaceRoot, 'package.json'))) {
|
|
393
|
+
info.language = 'javascript';
|
|
394
|
+
} else if (
|
|
395
|
+
(await pathExists(path.join(workspaceRoot, 'pyproject.toml'))) ||
|
|
396
|
+
(await pathExists(path.join(workspaceRoot, 'requirements.txt')))
|
|
397
|
+
) {
|
|
398
|
+
info.language = 'python';
|
|
399
|
+
} else if (await pathExists(path.join(workspaceRoot, 'go.mod'))) {
|
|
400
|
+
info.language = 'go';
|
|
401
|
+
} else if (await pathExists(path.join(workspaceRoot, 'Cargo.toml'))) {
|
|
402
|
+
info.language = 'rust';
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const packageJson = await readJsonIfExists(path.join(workspaceRoot, 'package.json'));
|
|
406
|
+
if (packageJson) {
|
|
407
|
+
const scripts = packageJson.scripts || {};
|
|
408
|
+
const deps = {
|
|
409
|
+
...(packageJson.dependencies || {}),
|
|
410
|
+
...(packageJson.devDependencies || {}),
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
if (scripts.test) {
|
|
414
|
+
info.testCommand = 'npm test';
|
|
415
|
+
if (!info.testRunner) {
|
|
416
|
+
info.testRunner = 'test';
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (scripts.build) {
|
|
420
|
+
info.buildCommand = 'npm run build';
|
|
421
|
+
}
|
|
422
|
+
if (scripts.lint) {
|
|
423
|
+
info.lintCommand = 'npm run lint';
|
|
424
|
+
}
|
|
425
|
+
if (scripts.format) {
|
|
426
|
+
info.formatCommand = 'npm run format';
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const frameworkMatchers = [
|
|
430
|
+
['next', 'Next.js'],
|
|
431
|
+
['react', 'React'],
|
|
432
|
+
['vue', 'Vue'],
|
|
433
|
+
['express', 'Express'],
|
|
434
|
+
['@angular/core', 'Angular'],
|
|
435
|
+
['svelte', 'Svelte'],
|
|
436
|
+
];
|
|
437
|
+
for (const [dep, name] of frameworkMatchers) {
|
|
438
|
+
if (deps[dep]) {
|
|
439
|
+
info.framework = name;
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (deps.vitest || (await pathExists(path.join(workspaceRoot, 'vitest.config.ts')))) {
|
|
445
|
+
info.testRunner = 'vitest';
|
|
446
|
+
} else if (deps.jest || (await pathExists(path.join(workspaceRoot, 'jest.config.js')))) {
|
|
447
|
+
info.testRunner = 'jest';
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (
|
|
452
|
+
info.language === 'python' &&
|
|
453
|
+
(await pathExists(path.join(workspaceRoot, 'pytest.ini')))
|
|
454
|
+
) {
|
|
455
|
+
info.testRunner = 'pytest';
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return info;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
async function detectEaiInitialized(workspaceRoot) {
|
|
462
|
+
const [hasEaiConfigDir, hasObjectTypes, hasRegister, hasManifest, hasRuntimeContract] =
|
|
463
|
+
await Promise.all([
|
|
464
|
+
pathExists(path.join(workspaceRoot, EAI_CONFIG_DIR)),
|
|
465
|
+
pathExists(path.join(workspaceRoot, EAI_OBJECT_TYPES_MARKER)),
|
|
466
|
+
pathExists(path.join(workspaceRoot, EAI_REGISTER_MARKER)),
|
|
467
|
+
pathExists(path.join(workspaceRoot, EAI_MANIFEST_MARKER)),
|
|
468
|
+
pathExists(path.join(workspaceRoot, EAI_RUNTIME_CONTRACT_MARKER)),
|
|
469
|
+
]);
|
|
470
|
+
|
|
471
|
+
return hasRuntimeContract || (hasObjectTypes && hasRegister) || (hasEaiConfigDir && hasManifest);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function formatLanguage(language) {
|
|
475
|
+
const names = {
|
|
476
|
+
typescript: 'TypeScript',
|
|
477
|
+
javascript: 'JavaScript',
|
|
478
|
+
python: 'Python',
|
|
479
|
+
go: 'Go',
|
|
480
|
+
rust: 'Rust',
|
|
481
|
+
unknown: 'Unknown',
|
|
482
|
+
};
|
|
483
|
+
return names[language] || language;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function buildCommandsSection(projectInfo) {
|
|
487
|
+
const lines = [];
|
|
488
|
+
if (projectInfo.buildCommand) {
|
|
489
|
+
lines.push(`- **Build**: \`${projectInfo.buildCommand}\``);
|
|
490
|
+
}
|
|
491
|
+
if (projectInfo.testCommand) {
|
|
492
|
+
lines.push(`- **Test**: \`${projectInfo.testCommand}\``);
|
|
493
|
+
}
|
|
494
|
+
if (projectInfo.lintCommand) {
|
|
495
|
+
lines.push(`- **Lint**: \`${projectInfo.lintCommand}\``);
|
|
496
|
+
}
|
|
497
|
+
if (projectInfo.formatCommand) {
|
|
498
|
+
lines.push(`- **Format**: \`${projectInfo.formatCommand}\``);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return lines.length > 0
|
|
502
|
+
? lines.join('\n')
|
|
503
|
+
: 'No commands detected. Add build/test/lint scripts to your project.';
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function buildCodeStyleSection(projectInfo) {
|
|
507
|
+
const languageSpecific = {
|
|
508
|
+
typescript: [
|
|
509
|
+
'- Prefer explicit types at boundaries and strict TypeScript defaults',
|
|
510
|
+
'- Keep modules small and use ESM imports consistently',
|
|
511
|
+
],
|
|
512
|
+
javascript: [
|
|
513
|
+
'- Prefer explicit runtime validation at boundaries',
|
|
514
|
+
'- Keep modules small and use ESM imports consistently',
|
|
515
|
+
],
|
|
516
|
+
python: [
|
|
517
|
+
'- Prefer type hints for public functions and clear module boundaries',
|
|
518
|
+
'- Keep scripts deterministic and avoid hidden side effects',
|
|
519
|
+
],
|
|
520
|
+
go: [
|
|
521
|
+
'- Keep packages small and favor explicit error handling',
|
|
522
|
+
'- Prefer table-driven tests for behavior coverage',
|
|
523
|
+
],
|
|
524
|
+
rust: [
|
|
525
|
+
'- Prefer clear ownership boundaries and small modules',
|
|
526
|
+
'- Use Result-based error handling instead of panics for expected failures',
|
|
527
|
+
],
|
|
528
|
+
unknown: [],
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
const lines = [
|
|
532
|
+
'### Code Conventions',
|
|
533
|
+
'',
|
|
534
|
+
'- Follow existing code style and naming conventions in this project',
|
|
535
|
+
'- Write clear, self-documenting code with descriptive names',
|
|
536
|
+
'- Keep functions focused and small',
|
|
537
|
+
'- Add comments only where the logic is not self-evident',
|
|
538
|
+
'- Handle errors at appropriate boundaries',
|
|
539
|
+
...languageSpecific[projectInfo.language],
|
|
540
|
+
];
|
|
541
|
+
|
|
542
|
+
return lines.join('\n');
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function buildEaiRepoContractSection(projectInfo) {
|
|
546
|
+
if (!projectInfo.eaiInitialized) {
|
|
547
|
+
return `## EAI Platform Readiness
|
|
548
|
+
|
|
549
|
+
- This repo is not confirmed as EAI-initialized yet. Before any Gofer pipeline work, run \`eai whoami\`.
|
|
550
|
+
- If \`eai\` is missing, login fails, the token is expired, or no active tenant is visible, run \`/gofer:eai-first-run\` before building.
|
|
551
|
+
- Build on EAI Platform first and Azure second. Treat non-EAI runtimes as explicit exceptions only.
|
|
552
|
+
- Do not write tokens, secrets, private tenant IDs, or local \`.env\` values into Gofer artifacts.`;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return `## EAI Repo Contract
|
|
556
|
+
|
|
557
|
+
- This repo appears to be initialized from the EAI app template. Before app-delivery work, read \`.specify/references/platform/eai-repo-contract.md\` and \`.specify/references/platform/eai-error-catalog.yaml\`.
|
|
558
|
+
- Before any Gofer pipeline work, run \`eai whoami\`. If \`eai\` is missing, login fails, the token is expired, or no active tenant is visible, run \`/gofer:eai-first-run\` before building.
|
|
559
|
+
- If CLI, login, tenant, template, or Gofer readiness is missing or stale, run \`/gofer:eai-first-run\` before building.
|
|
560
|
+
- Use \`eai update --check\`, \`eai --describe\`, \`eai agent guide --format json\`, \`eai template check --format json\`, \`eai gofer refresh --check --format json\`, and \`eai workflow readiness --format json\` when the CLI advertises them before assuming the repo is current.
|
|
561
|
+
- After any \`eai\` command error, use \`eai errors explain <code-or-reason> --format json\` before guessing remediation.
|
|
562
|
+
- If \`eai errors explain\` is unavailable, match \`.specify/references/platform/eai-error-catalog.yaml\`, run read-only diagnostics before mutating fixes, and stop at the retry or escalation condition.
|
|
563
|
+
- For \`eai user invite\` 5xx or \`EXTERNAL_SERVICE_ERROR\`, check existing members with \`eai user list --tenant <tenant-id> --search <email> --format json\`; use \`eai user role set --tenant <tenant-id> --member-id <member-id> --role tenant-admin --format json\` only after verification and user approval, then tell the app user to sign out and sign back in.
|
|
564
|
+
- Build on EAI Platform first and Azure second. Treat non-EAI runtimes as explicit exceptions only.
|
|
565
|
+
- Keep provisioning, types seed, schema/storage health, workflow readiness, and preview as separate gates.`;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export function buildAgentsMd(projectInfo, stages) {
|
|
569
|
+
const corePipelineOrder = [
|
|
570
|
+
'0_gofer_start',
|
|
571
|
+
'1_gofer_research',
|
|
572
|
+
'2_gofer_specify',
|
|
573
|
+
'3_gofer_plan',
|
|
574
|
+
'4_gofer_tasks',
|
|
575
|
+
'5_gofer_implement',
|
|
576
|
+
'6_gofer_validate',
|
|
577
|
+
];
|
|
578
|
+
const corePipelineSet = new Set(corePipelineOrder);
|
|
579
|
+
const helperStages = [];
|
|
580
|
+
const pipelineStages = [];
|
|
581
|
+
|
|
582
|
+
for (const stage of stages) {
|
|
583
|
+
if (corePipelineSet.has(String(stage.frontmatter.name))) {
|
|
584
|
+
pipelineStages.push(stage);
|
|
585
|
+
} else {
|
|
586
|
+
helperStages.push(stage);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
pipelineStages.sort(
|
|
591
|
+
(a, b) =>
|
|
592
|
+
corePipelineOrder.indexOf(String(a.frontmatter.name)) -
|
|
593
|
+
corePipelineOrder.indexOf(String(b.frontmatter.name))
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
const pipelineSections = pipelineStages
|
|
597
|
+
.map(
|
|
598
|
+
(stage) =>
|
|
599
|
+
`### ${stage.frontmatter.name}\n\n${String(stage.frontmatter.description).trim()}`
|
|
600
|
+
)
|
|
601
|
+
.join('\n\n');
|
|
602
|
+
const helperSections = helperStages
|
|
603
|
+
.map(
|
|
604
|
+
(stage) =>
|
|
605
|
+
`### ${stage.frontmatter.name}\n\n${String(stage.frontmatter.description).trim()}`
|
|
606
|
+
)
|
|
607
|
+
.join('\n\n');
|
|
608
|
+
|
|
609
|
+
const frameworkLine = projectInfo.framework ? ` | **Framework**: ${projectInfo.framework}` : '';
|
|
610
|
+
|
|
611
|
+
return `# AGENTS.md
|
|
612
|
+
|
|
613
|
+
**Project**: ${projectInfo.name} | **Language**: ${formatLanguage(projectInfo.language)}${frameworkLine} | **Package Manager**: ${projectInfo.packageManager || 'Not detected'}
|
|
614
|
+
|
|
615
|
+
## Core Pipeline Stages
|
|
616
|
+
|
|
617
|
+
${pipelineSections}
|
|
618
|
+
|
|
619
|
+
## Optional Helper Commands
|
|
620
|
+
|
|
621
|
+
${helperSections}
|
|
622
|
+
|
|
623
|
+
## Commands
|
|
624
|
+
|
|
625
|
+
${buildCommandsSection(projectInfo)}
|
|
626
|
+
|
|
627
|
+
## Code Style
|
|
628
|
+
|
|
629
|
+
${buildCodeStyleSection(projectInfo)}
|
|
630
|
+
|
|
631
|
+
## Testing
|
|
632
|
+
|
|
633
|
+
- **Test Runner**: ${projectInfo.testRunner || 'Not detected'}
|
|
634
|
+
- Write tests for new functionality before marking tasks complete
|
|
635
|
+
- Run the full test suite before committing
|
|
636
|
+
|
|
637
|
+
## Git Workflow
|
|
638
|
+
|
|
639
|
+
- Use conventional commit messages (feat:, fix:, chore:, docs:)
|
|
640
|
+
- Create feature branches for new work
|
|
641
|
+
- Run tests and linting before committing
|
|
642
|
+
|
|
643
|
+
## Gofer Pipeline
|
|
644
|
+
|
|
645
|
+
This project uses Gofer for spec-driven development. Run \`/0_gofer_start\` to start the core pipeline (Gofer Start -> research -> specify -> plan -> tasks -> implement -> validate). \`/6_gofer_validate\` is the terminal quality gate and includes the final engineering review loop. Artifacts in \`.specify/specs/{feature}/\`.
|
|
646
|
+
|
|
647
|
+
Each feature should carry a bounded loop contract:
|
|
648
|
+
|
|
649
|
+
- \`loop-contract.json\` defines the objective, evaluation commands, maximum
|
|
650
|
+
loop count, stop conditions, and escalation rules.
|
|
651
|
+
- \`loop-ledger.jsonl\` records each implementation/validation check-repair
|
|
652
|
+
iteration.
|
|
653
|
+
- \`loop-audit-report.md\` is produced by
|
|
654
|
+
\`node .specify/scripts/node/gofer-loop-audit.mjs --feature-dir .specify/specs/{feature} --stage 6_validate --strict\`.
|
|
655
|
+
|
|
656
|
+
Implementation and validation must not finish if the loop audit reports
|
|
657
|
+
blocking findings.
|
|
658
|
+
|
|
659
|
+
${buildEaiRepoContractSection(projectInfo)}
|
|
660
|
+
|
|
661
|
+
## Core Principles
|
|
662
|
+
|
|
663
|
+
- **Simplicity First**: Make every change as simple as possible. Impact minimal code.
|
|
664
|
+
- **No Laziness**: Find root causes. No temporary fixes. Senior developer standards.
|
|
665
|
+
- **Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.
|
|
666
|
+
`;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export function buildClaudeMd(projectInfo) {
|
|
670
|
+
const eaiSection = buildEaiRepoContractSection(projectInfo);
|
|
671
|
+
|
|
672
|
+
return `# CLAUDE.md
|
|
673
|
+
|
|
674
|
+
See @AGENTS.md for project conventions, commands, and code style.
|
|
675
|
+
|
|
676
|
+
## Workflow Orchestration
|
|
677
|
+
|
|
678
|
+
### 1. Plan Node Default
|
|
679
|
+
- Enter plan mode for any non-trivial task (3+ steps or architectural decisions)
|
|
680
|
+
- If something goes sideways, stop and re-plan immediately instead of pushing through
|
|
681
|
+
- Use plan mode for verification steps, not just building
|
|
682
|
+
|
|
683
|
+
### 2. Verification Before Done
|
|
684
|
+
- Never mark a task complete without proving it works
|
|
685
|
+
- Diff behavior between main and your changes when relevant
|
|
686
|
+
- Run tests, check logs, and demonstrate correctness
|
|
687
|
+
|
|
688
|
+
### 3. Demand Elegance (Balanced)
|
|
689
|
+
- For non-trivial changes, pause and ask whether there is a cleaner solution
|
|
690
|
+
- Skip over-engineering for simple fixes
|
|
691
|
+
|
|
692
|
+
## Task Management
|
|
693
|
+
|
|
694
|
+
1. **Plan First**: Write a plan with checkable items before implementation
|
|
695
|
+
2. **Track Progress**: Mark items complete as you go
|
|
696
|
+
3. **Explain Changes**: Give high-level summaries at meaningful checkpoints
|
|
697
|
+
4. **Verify**: Run tests before calling the work done
|
|
698
|
+
|
|
699
|
+
## Core Principles
|
|
700
|
+
|
|
701
|
+
- **Simplicity First**: Make every change as simple as possible. Impact minimal code.
|
|
702
|
+
- **No Laziness**: Find root causes. No temporary fixes. Senior developer standards.
|
|
703
|
+
- **Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.
|
|
704
|
+
|
|
705
|
+
## Gofer Pipeline
|
|
706
|
+
|
|
707
|
+
Run \`/0_gofer_start\` to start the core pipeline: Gofer Start -> research -> specify -> plan -> tasks -> implement -> validate. \`/6_gofer_validate\` is the terminal quality gate and includes the final engineering review loop. Use \`/7_gofer_save\` for checkpoints and \`/8_gofer_branding\` to apply company, client, or consulting-firm presentation style. Artifacts go to \`.specify/specs/{feature}/\`.
|
|
708
|
+
|
|
709
|
+
For each active feature, keep \`loop-contract.json\`, \`loop-ledger.jsonl\`, and
|
|
710
|
+
\`loop-audit-report.md\` in the feature directory. The loop contract bounds
|
|
711
|
+
check-repair iterations, and validation must run
|
|
712
|
+
\`node .specify/scripts/node/gofer-loop-audit.mjs --feature-dir .specify/specs/{feature} --stage 6_validate --strict\`
|
|
713
|
+
before declaring the work complete.
|
|
714
|
+
|
|
715
|
+
${eaiSection}
|
|
716
|
+
`;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
export function buildCopilotInstructions(projectInfo) {
|
|
720
|
+
const frameworkBit = projectInfo.framework ? ` using ${projectInfo.framework}` : '';
|
|
721
|
+
const eaiSection = buildEaiRepoContractSection(projectInfo);
|
|
722
|
+
return `# Copilot Instructions
|
|
723
|
+
|
|
724
|
+
## Project Overview
|
|
725
|
+
|
|
726
|
+
**${projectInfo.name}** is a ${formatLanguage(projectInfo.language)} project${frameworkBit}.
|
|
727
|
+
|
|
728
|
+
## Gofer Pipeline
|
|
729
|
+
|
|
730
|
+
This project uses Gofer for spec-driven development. Run \`/0_gofer_start\` to start the core pipeline: Gofer Start -> research -> specify -> plan -> tasks -> implement -> validate.
|
|
731
|
+
|
|
732
|
+
Key commands: \`/1_gofer_research\`, \`/2_gofer_specify\`, \`/3_gofer_plan\`, \`/4_gofer_tasks\`, \`/5_gofer_implement\`, \`/6_gofer_validate\`. \`/6_gofer_validate\` is the terminal quality gate and includes the final engineering review loop. Use \`/7_gofer_save\` for checkpoints and \`/8_gofer_branding\` for branded document/deck templates. Artifacts in \`.specify/specs/{feature}/\`.
|
|
733
|
+
|
|
734
|
+
${eaiSection}
|
|
735
|
+
|
|
736
|
+
## Code Quality
|
|
737
|
+
|
|
738
|
+
${buildCodeStyleSection(projectInfo)}
|
|
739
|
+
|
|
740
|
+
## Task Management
|
|
741
|
+
|
|
742
|
+
1. **Plan First**: Write a plan with checkable items before starting
|
|
743
|
+
2. **Track Progress**: Mark items complete as you go
|
|
744
|
+
3. **Verify**: Run tests and demonstrate correctness before marking done
|
|
745
|
+
4. **Capture Lessons**: Update lessons after meaningful corrections
|
|
746
|
+
|
|
747
|
+
## Core Principles
|
|
748
|
+
|
|
749
|
+
- **Simplicity First**: Make every change as simple as possible. Impact minimal code.
|
|
750
|
+
- **No Laziness**: Find root causes. No temporary fixes. Senior developer standards.
|
|
751
|
+
- **Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs.
|
|
752
|
+
`;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
export async function readManagedVersion(workspaceRoot) {
|
|
756
|
+
try {
|
|
757
|
+
const content = await fs.readFile(path.join(workspaceRoot, GOFER_VERSION_FILE), 'utf8');
|
|
758
|
+
return content.split('\n')[0]?.trim() || null;
|
|
759
|
+
} catch (error) {
|
|
760
|
+
if (error?.code === 'ENOENT') {
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
throw error;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
async function collectMissingPaths(workspaceRoot, relativePaths) {
|
|
768
|
+
const missing = [];
|
|
769
|
+
for (const relativePath of relativePaths) {
|
|
770
|
+
if (!(await pathExists(path.join(workspaceRoot, relativePath)))) {
|
|
771
|
+
missing.push(relativePath);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return missing;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export async function checkWorkspaceState({
|
|
778
|
+
workspaceRoot,
|
|
779
|
+
host = 'auto',
|
|
780
|
+
sourceRoot,
|
|
781
|
+
}) {
|
|
782
|
+
const normalizedHost = normalizeHost(host);
|
|
783
|
+
const expectedVersion = await detectGoferVersion(sourceRoot);
|
|
784
|
+
const actualVersion = await readManagedVersion(workspaceRoot);
|
|
785
|
+
const missingCore = await collectMissingPaths(workspaceRoot, CORE_SENTINELS);
|
|
786
|
+
const requiredHostPaths = HOST_POLICIES[normalizedHost]?.required || [];
|
|
787
|
+
const missingHost = await collectMissingPaths(workspaceRoot, requiredHostPaths);
|
|
788
|
+
|
|
789
|
+
let status = 'healthy';
|
|
790
|
+
const reasons = [];
|
|
791
|
+
|
|
792
|
+
if (missingCore.length > 0 || missingHost.length > 0) {
|
|
793
|
+
status = 'missing';
|
|
794
|
+
if (missingCore.length > 0) {
|
|
795
|
+
reasons.push('core scaffold missing');
|
|
796
|
+
}
|
|
797
|
+
if (missingHost.length > 0) {
|
|
798
|
+
reasons.push(`${normalizedHost} host files missing`);
|
|
799
|
+
}
|
|
800
|
+
} else if (actualVersion !== expectedVersion) {
|
|
801
|
+
status = 'stale';
|
|
802
|
+
reasons.push(`workspace version ${actualVersion ?? 'missing'} != plugin version ${expectedVersion}`);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
return {
|
|
806
|
+
workspaceRoot,
|
|
807
|
+
host: normalizedHost,
|
|
808
|
+
status,
|
|
809
|
+
expectedVersion,
|
|
810
|
+
actualVersion,
|
|
811
|
+
missingCore,
|
|
812
|
+
missingHost,
|
|
813
|
+
shouldPromptInitialize: status !== 'healthy',
|
|
814
|
+
prompt:
|
|
815
|
+
status === 'healthy'
|
|
816
|
+
? null
|
|
817
|
+
: 'This repo is missing or stale for Gofer. Initialize/update it now?',
|
|
818
|
+
summary:
|
|
819
|
+
status === 'healthy'
|
|
820
|
+
? `Gofer workspace is healthy for ${normalizedHost}.`
|
|
821
|
+
: `Gofer workspace is ${status}: ${reasons.join('; ')}`,
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
async function ensureDir(targetPath, dryRun) {
|
|
826
|
+
if (!dryRun) {
|
|
827
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
async function copyDirectory(sourcePath, targetPath, dryRun) {
|
|
832
|
+
if (!(await pathExists(sourcePath))) {
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
if (dryRun) {
|
|
836
|
+
return true;
|
|
837
|
+
}
|
|
838
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
839
|
+
await fs.cp(sourcePath, targetPath, { recursive: true, force: true, dereference: false });
|
|
840
|
+
return true;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
async function writeFileIfMissing(filePath, content, dryRun) {
|
|
844
|
+
if (await pathExists(filePath)) {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
if (!dryRun) {
|
|
848
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
849
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
850
|
+
}
|
|
851
|
+
return true;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
async function writeTextFile(filePath, content, dryRun) {
|
|
855
|
+
if (!dryRun) {
|
|
856
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
857
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
async function writeModelPolicyIfMissing(workspaceRoot, sourceRoot, dryRun) {
|
|
862
|
+
const targetPath = path.join(workspaceRoot, '.specify', 'memory', 'gofer-model-policy.yaml');
|
|
863
|
+
|
|
864
|
+
let template = '';
|
|
865
|
+
try {
|
|
866
|
+
template = await readSourceFile(
|
|
867
|
+
sourceRoot,
|
|
868
|
+
path.join('.specify', 'templates', 'gofer-model-policy.yaml')
|
|
869
|
+
);
|
|
870
|
+
} catch (error) {
|
|
871
|
+
if (error?.code === 'ENOENT') {
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
throw error;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
return writeFileIfMissing(targetPath, template, dryRun);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
async function mergeGitignore(workspaceRoot, dryRun) {
|
|
881
|
+
const gitignorePath = path.join(workspaceRoot, '.gitignore');
|
|
882
|
+
let existing = '';
|
|
883
|
+
try {
|
|
884
|
+
existing = await fs.readFile(gitignorePath, 'utf8');
|
|
885
|
+
} catch (error) {
|
|
886
|
+
if (error?.code !== 'ENOENT') {
|
|
887
|
+
throw error;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
const missingEntries = GOFER_GITIGNORE_ENTRIES.filter((entry) => !existing.includes(entry));
|
|
892
|
+
if (missingEntries.length === 0) {
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
let updated = existing;
|
|
897
|
+
if (updated.length > 0 && !updated.endsWith('\n')) {
|
|
898
|
+
updated += '\n';
|
|
899
|
+
}
|
|
900
|
+
if (!updated.includes('# Gofer runtime files')) {
|
|
901
|
+
updated += '\n# Gofer runtime files (auto-generated, should not be committed)\n';
|
|
902
|
+
}
|
|
903
|
+
for (const entry of missingEntries) {
|
|
904
|
+
updated += `${entry}\n`;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
await writeTextFile(gitignorePath, updated, dryRun);
|
|
908
|
+
return true;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
function buildSpecifyReadme() {
|
|
912
|
+
return `# Gofer - Specification Directory
|
|
913
|
+
|
|
914
|
+
This folder contains all project specifications for AI-driven feature development.
|
|
915
|
+
|
|
916
|
+
## Structure
|
|
917
|
+
|
|
918
|
+
- **memory/** - Constitution, decisions, and project principles
|
|
919
|
+
- **specs/** - Feature specifications (numbered: 001-feature-name/)
|
|
920
|
+
- **templates/** - Templates for specs, plans, and tasks
|
|
921
|
+
- **references/** - Public-safe EAI fallback references and recovery guides
|
|
922
|
+
- **scripts/** - Helper scripts for workflow automation
|
|
923
|
+
- **logs/** - Execution logs and support artifacts
|
|
924
|
+
|
|
925
|
+
## Quick Start
|
|
926
|
+
|
|
927
|
+
Run the unified Gofer pipeline with:
|
|
928
|
+
|
|
929
|
+
\`\`\`
|
|
930
|
+
/0_gofer_start Add user authentication with OAuth2 and JWT
|
|
931
|
+
\`\`\`
|
|
932
|
+
|
|
933
|
+
Artifacts are stored in \`.specify/specs/{feature}/\`.
|
|
934
|
+
|
|
935
|
+
Each feature should include a bounded loop contract:
|
|
936
|
+
|
|
937
|
+
- \`loop-contract.json\` - objective, maximum iterations, stop conditions, and
|
|
938
|
+
evaluation commands.
|
|
939
|
+
- \`loop-ledger.jsonl\` - append-only check-repair evidence written during
|
|
940
|
+
implementation and validation.
|
|
941
|
+
- \`loop-audit-report.md\` - generated by
|
|
942
|
+
\`node .specify/scripts/node/gofer-loop-audit.mjs --feature-dir .specify/specs/{feature} --stage 6_validate --strict\`.
|
|
943
|
+
|
|
944
|
+
Each feature should also keep a running stakeholder review pack:
|
|
945
|
+
|
|
946
|
+
- \`working-backwards-prfaq.md\` - product release PR/FAQ that starts as a
|
|
947
|
+
launch-day fiction and becomes evidence-backed across stages.
|
|
948
|
+
- \`prfaq-history/\` - immutable stage snapshots of the PR/FAQ.
|
|
949
|
+
- \`business-owner-summary.md\` - business scenario, process, value case,
|
|
950
|
+
success metrics, and assumptions.
|
|
951
|
+
- \`cto-architecture-summary.md\` - EAI Platform/Azure architecture, auth,
|
|
952
|
+
tenancy, data, integration, and platform-fit evidence.
|
|
953
|
+
- \`ciso-security-summary.md\` - security posture, controls, residual risks,
|
|
954
|
+
and validation evidence.
|
|
955
|
+
- \`stakeholder-review-index.md\` - what is ready for review and who must
|
|
956
|
+
approve, revise, or defer.
|
|
957
|
+
|
|
958
|
+
## Model Policy
|
|
959
|
+
|
|
960
|
+
Edit \`.specify/memory/gofer-model-policy.yaml\` to tune simple, medium, hard,
|
|
961
|
+
and arbiter model routes for Claude, Codex/OpenAI, Gemini, and Copilot. The
|
|
962
|
+
file is copied from \`.specify/templates/gofer-model-policy.yaml\` when missing
|
|
963
|
+
and is not overwritten by bootstrap.
|
|
964
|
+
`;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
function getMirrorCopyCandidates() {
|
|
968
|
+
return [
|
|
969
|
+
{ sourceRelativePath: 'commands', target: path.join('.claude', 'commands') },
|
|
970
|
+
{ sourceRelativePath: 'agents', target: path.join('.claude', 'agents') },
|
|
971
|
+
{
|
|
972
|
+
sourceRelativePath: path.join('.claude', 'skills'),
|
|
973
|
+
target: path.join('.claude', 'skills'),
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
sourceRelativePath: path.join('.github', 'agents'),
|
|
977
|
+
target: path.join('.github', 'agents'),
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
sourceRelativePath: path.join('.github', 'prompts'),
|
|
981
|
+
target: path.join('.github', 'prompts'),
|
|
982
|
+
},
|
|
983
|
+
{
|
|
984
|
+
sourceRelativePath: path.join('.github', 'instructions'),
|
|
985
|
+
target: path.join('.github', 'instructions'),
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
sourceRelativePath: path.join('.github', 'skills'),
|
|
989
|
+
target: path.join('.github', 'skills'),
|
|
990
|
+
},
|
|
991
|
+
{ sourceRelativePath: '.gemini', target: '.gemini' },
|
|
992
|
+
{ sourceRelativePath: path.join('.agents', 'skills'), target: path.join('.agents', 'skills') },
|
|
993
|
+
{ sourceRelativePath: path.join('.system', 'skills'), target: path.join('.system', 'skills') },
|
|
994
|
+
];
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
async function installClaudeHooksSettings(workspaceRoot, dryRun) {
|
|
998
|
+
const settingsPath = path.join(workspaceRoot, '.claude', 'settings.json');
|
|
999
|
+
let settings = {};
|
|
1000
|
+
try {
|
|
1001
|
+
settings = JSON.parse(await fs.readFile(settingsPath, 'utf8'));
|
|
1002
|
+
} catch (error) {
|
|
1003
|
+
if (error?.code !== 'ENOENT' && !(error instanceof SyntaxError)) {
|
|
1004
|
+
throw error;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
settings.hooks = {
|
|
1009
|
+
...(settings.hooks || {}),
|
|
1010
|
+
...CLAUDE_HOOKS_CONFIG,
|
|
1011
|
+
};
|
|
1012
|
+
|
|
1013
|
+
await writeTextFile(settingsPath, `${JSON.stringify(settings, null, 2)}\n`, dryRun);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
export async function bootstrapWorkspace({
|
|
1017
|
+
workspaceRoot,
|
|
1018
|
+
host = 'auto',
|
|
1019
|
+
sourceRoot,
|
|
1020
|
+
dryRun = false,
|
|
1021
|
+
includeMirrors = false,
|
|
1022
|
+
}) {
|
|
1023
|
+
const normalizedHost = normalizeHost(host);
|
|
1024
|
+
const projectInfo = await detectProjectInfo(workspaceRoot);
|
|
1025
|
+
const stages = await loadStageMetadata(sourceRoot);
|
|
1026
|
+
const version = await detectGoferVersion(sourceRoot);
|
|
1027
|
+
const changed = [];
|
|
1028
|
+
|
|
1029
|
+
const coreDirs = [
|
|
1030
|
+
path.join('.specify', 'specs'),
|
|
1031
|
+
path.join('.specify', 'memory'),
|
|
1032
|
+
path.join('.specify', 'logs'),
|
|
1033
|
+
];
|
|
1034
|
+
for (const relativeDir of coreDirs) {
|
|
1035
|
+
await ensureDir(path.join(workspaceRoot, relativeDir), dryRun);
|
|
1036
|
+
changed.push(relativeDir);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
const coreCopies = [
|
|
1040
|
+
path.join('.specify', 'commands'),
|
|
1041
|
+
path.join('.specify', 'references'),
|
|
1042
|
+
path.join('.specify', 'templates'),
|
|
1043
|
+
path.join('.specify', 'scripts', 'bash'),
|
|
1044
|
+
path.join('.specify', 'scripts', 'node'),
|
|
1045
|
+
path.join('.specify', 'scripts', 'hooks'),
|
|
1046
|
+
path.join('.specify', 'scripts', 'powershell'),
|
|
1047
|
+
];
|
|
1048
|
+
for (const relativePath of coreCopies) {
|
|
1049
|
+
const copied = await copyDirectory(
|
|
1050
|
+
await resolveSourcePath(sourceRoot, relativePath),
|
|
1051
|
+
path.join(workspaceRoot, relativePath),
|
|
1052
|
+
dryRun
|
|
1053
|
+
);
|
|
1054
|
+
if (copied) {
|
|
1055
|
+
changed.push(relativePath);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (await writeModelPolicyIfMissing(workspaceRoot, sourceRoot, dryRun)) {
|
|
1060
|
+
changed.push(path.join('.specify', 'memory', 'gofer-model-policy.yaml'));
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
await writeTextFile(
|
|
1064
|
+
path.join(workspaceRoot, GOFER_VERSION_FILE),
|
|
1065
|
+
`${version}\n`,
|
|
1066
|
+
dryRun
|
|
1067
|
+
);
|
|
1068
|
+
changed.push(GOFER_VERSION_FILE);
|
|
1069
|
+
|
|
1070
|
+
if (await writeFileIfMissing(path.join(workspaceRoot, '.specify', 'README.md'), buildSpecifyReadme(), dryRun)) {
|
|
1071
|
+
changed.push(path.join('.specify', 'README.md'));
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (await writeFileIfMissing(path.join(workspaceRoot, 'AGENTS.md'), buildAgentsMd(projectInfo, stages), dryRun)) {
|
|
1075
|
+
changed.push('AGENTS.md');
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
if (normalizedHost === 'claude') {
|
|
1079
|
+
if (
|
|
1080
|
+
await writeFileIfMissing(
|
|
1081
|
+
path.join(workspaceRoot, 'CLAUDE.md'),
|
|
1082
|
+
buildClaudeMd(projectInfo),
|
|
1083
|
+
dryRun
|
|
1084
|
+
)
|
|
1085
|
+
) {
|
|
1086
|
+
changed.push('CLAUDE.md');
|
|
1087
|
+
}
|
|
1088
|
+
await installClaudeHooksSettings(workspaceRoot, dryRun);
|
|
1089
|
+
changed.push(path.join('.claude', 'settings.json'));
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
if (normalizedHost === 'copilot') {
|
|
1093
|
+
if (
|
|
1094
|
+
await writeFileIfMissing(
|
|
1095
|
+
path.join(workspaceRoot, '.github', 'copilot-instructions.md'),
|
|
1096
|
+
buildCopilotInstructions(projectInfo),
|
|
1097
|
+
dryRun
|
|
1098
|
+
)
|
|
1099
|
+
) {
|
|
1100
|
+
changed.push(path.join('.github', 'copilot-instructions.md'));
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
if (includeMirrors) {
|
|
1105
|
+
for (const candidate of getMirrorCopyCandidates(sourceRoot)) {
|
|
1106
|
+
const copied = await copyDirectory(
|
|
1107
|
+
await resolveSourcePath(sourceRoot, candidate.sourceRelativePath),
|
|
1108
|
+
path.join(workspaceRoot, candidate.target),
|
|
1109
|
+
dryRun
|
|
1110
|
+
);
|
|
1111
|
+
if (copied) {
|
|
1112
|
+
changed.push(candidate.target);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
const archivedLegacyPaths = await removeLegacyManagedPaths(workspaceRoot, dryRun);
|
|
1118
|
+
changed.push(
|
|
1119
|
+
...archivedLegacyPaths.map(
|
|
1120
|
+
({ relativePath, archivePath }) => `${relativePath} (archived legacy to ${archivePath})`
|
|
1121
|
+
)
|
|
1122
|
+
);
|
|
1123
|
+
|
|
1124
|
+
if (await mergeGitignore(workspaceRoot, dryRun)) {
|
|
1125
|
+
changed.push('.gitignore');
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
const postCheck = await checkWorkspaceState({
|
|
1129
|
+
workspaceRoot,
|
|
1130
|
+
host: normalizedHost,
|
|
1131
|
+
sourceRoot,
|
|
1132
|
+
});
|
|
1133
|
+
|
|
1134
|
+
return {
|
|
1135
|
+
workspaceRoot,
|
|
1136
|
+
host: normalizedHost,
|
|
1137
|
+
version,
|
|
1138
|
+
dryRun,
|
|
1139
|
+
includeMirrors,
|
|
1140
|
+
changed,
|
|
1141
|
+
status: postCheck.status,
|
|
1142
|
+
check: postCheck,
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
export function formatWorkspaceCheckReport(report) {
|
|
1147
|
+
const lines = [
|
|
1148
|
+
`Workspace: ${report.workspaceRoot}`,
|
|
1149
|
+
`Host: ${report.host}`,
|
|
1150
|
+
`Status: ${report.status}`,
|
|
1151
|
+
`Expected version: ${report.expectedVersion}`,
|
|
1152
|
+
`Workspace version: ${report.actualVersion ?? 'missing'}`,
|
|
1153
|
+
];
|
|
1154
|
+
|
|
1155
|
+
if (report.missingCore.length > 0) {
|
|
1156
|
+
lines.push(`Missing core: ${report.missingCore.join(', ')}`);
|
|
1157
|
+
}
|
|
1158
|
+
if (report.missingHost.length > 0) {
|
|
1159
|
+
lines.push(`Missing host files: ${report.missingHost.join(', ')}`);
|
|
1160
|
+
}
|
|
1161
|
+
if (report.prompt) {
|
|
1162
|
+
lines.push(`Prompt: ${report.prompt}`);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
return lines.join('\n');
|
|
1166
|
+
}
|