@enterpriseai/cli 3.19.0 → 3.19.2
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/package.json +3 -3
- package/resources/deploy/eai-app-template/producer-pin.json +5 -5
- package/resources/deploy/eai-app-template/tests/source-unknown-deployment-evidence.test.mjs +2141 -1
- package/resources/gofer/.gofer-version +4 -357
- package/resources/gofer/agents-skills/eai/SKILL.md +365 -0
- package/resources/gofer/agents-skills/eai-update/SKILL.md +56 -0
- package/resources/gofer/agents-skills/gofer-documentation/SKILL.md +93 -0
- package/resources/gofer/bash-scripts/create-new-feature.sh +3 -1
- package/resources/gofer/bash-scripts/sync-implementation-status.sh +4 -3
- package/resources/gofer/bash-scripts/update-agent-context.sh +7 -8
- package/resources/gofer/bash-scripts/validate-artifact.sh +10 -6
- package/resources/gofer/bash-scripts/verify-object-type-routing-workspace.sh +184 -0
- package/resources/gofer/claude-commands/eai-update.md +46 -0
- package/resources/gofer/claude-commands/eai.md +355 -0
- package/resources/gofer/claude-skills/eai/SKILL.md +365 -0
- package/resources/gofer/claude-skills/eai-update/SKILL.md +56 -0
- package/resources/gofer/claude-skills/gofer-documentation/SKILL.md +93 -0
- package/resources/gofer/commands/0_gofer_start.md +440 -99
- package/resources/gofer/commands/0a_problem_validation.md +187 -27
- package/resources/gofer/commands/10_gofer_cloud.md +183 -23
- package/resources/gofer/commands/1_gofer_research.md +239 -30
- package/resources/gofer/commands/2_gofer_specify.md +239 -35
- package/resources/gofer/commands/3_gofer_plan.md +259 -43
- package/resources/gofer/commands/4_gofer_tasks.md +401 -81
- package/resources/gofer/commands/5_gofer_implement.md +375 -84
- package/resources/gofer/commands/6_gofer_validate.md +284 -53
- package/resources/gofer/commands/7_gofer_save.md +187 -26
- package/resources/gofer/commands/7a_stakeholder_comms.md +183 -23
- package/resources/gofer/commands/8_gofer_branding.md +183 -23
- package/resources/gofer/commands/9_gofer_tests.md +212 -23
- package/resources/gofer/commands/gofer_bootstrap_workspace.md +121 -8
- package/resources/gofer/commands/gofer_check_workspace.md +123 -8
- package/resources/gofer/commands/gofer_constitution.md +183 -23
- package/resources/gofer/commands/gofer_diagnose.md +183 -23
- package/resources/gofer/commands/gofer_eai_first_run.md +254 -25
- package/resources/gofer/commands/gofer_hydrate.md +183 -23
- package/resources/gofer/commands/gofer_personality.md +117 -6
- package/resources/gofer/commands/gofer_plan.md +117 -6
- package/resources/gofer/commands/gofer_side.md +117 -6
- package/resources/gofer/commands/gofer_spec_summary.md +183 -23
- package/resources/gofer/commands/gofer_tdd.md +183 -23
- package/resources/gofer/commands/gofer_vocabulary.md +185 -25
- package/resources/gofer/commands/gofer_zoom_out.md +183 -23
- package/resources/gofer/config/typesafe-learning-review.json +16 -0
- package/resources/gofer/config/typesafe-semantic-review.json +9 -0
- package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +15 -6
- package/resources/gofer/copilot-instructions/typescript.instructions.md +1 -1
- package/resources/gofer/copilot-prompts/eai-update.prompt.md +58 -0
- package/resources/gofer/copilot-prompts/eai.prompt.md +367 -0
- package/resources/gofer/gemini/commands/gofer/eai-update.md +22 -0
- package/resources/gofer/gemini/commands/gofer/eai-update.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/eai.md +357 -0
- package/resources/gofer/gemini/commands/gofer/eai.toml +2 -0
- package/resources/gofer/gemini/commands/gofer/manifest.json +3 -27
- package/resources/gofer/gemini/extension.json +4 -4
- package/resources/gofer/github-agents/eai.agent.md +83 -0
- package/resources/gofer/github-agents/gofer-business.agent.md +73 -4
- package/resources/gofer/github-agents/gofer-implement.agent.md +71 -2
- package/resources/gofer/github-agents/gofer-plan.agent.md +72 -2
- package/resources/gofer/github-agents/gofer-research.agent.md +72 -2
- package/resources/gofer/github-agents/gofer-validate.agent.md +72 -2
- package/resources/gofer/github-skills/eai/SKILL.md +365 -0
- package/resources/gofer/github-skills/eai-update/SKILL.md +56 -0
- package/resources/gofer/github-skills/gofer-documentation/SKILL.md +93 -0
- package/resources/gofer/grok-skills/eai/SKILL.md +267 -14
- package/resources/gofer/grok-skills/eai-update/SKILL.md +56 -0
- package/resources/gofer/hook-scripts/user-prompt-submit.mjs +58 -13
- package/resources/gofer/instruction-templates/base/agents-base.md +8 -4
- package/resources/gofer/instruction-templates/gofer/gofer-claude.md +7 -5
- package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +10 -8
- package/resources/gofer/memory/constitution.md +9 -7
- package/resources/gofer/memory/gofer-model-policy.yaml +23 -1
- package/resources/gofer/memory/lessons.md +0 -31
- package/resources/gofer/node-scripts/canonical-descriptions.mjs +1 -1
- package/resources/gofer/node-scripts/check-version-alignment.mjs +4 -7
- package/resources/gofer/node-scripts/delivery-lineage-corpus.mjs +156 -0
- package/resources/gofer/node-scripts/generate-commands.mjs +1073 -265
- package/resources/gofer/node-scripts/gofer-acceptance-check.mjs +143 -0
- package/resources/gofer/node-scripts/gofer-agent-catalog.mjs +271 -0
- package/resources/gofer/node-scripts/gofer-benchmark-executor.mjs +123 -0
- package/resources/gofer/node-scripts/gofer-benchmark-sign.mjs +62 -0
- package/resources/gofer/node-scripts/gofer-benchmark-signer.mjs +89 -0
- package/resources/gofer/node-scripts/gofer-benchmark.mjs +76 -0
- package/resources/gofer/node-scripts/gofer-blocker-control.mjs +274 -0
- package/resources/gofer/node-scripts/gofer-claude-adapter.mjs +154 -0
- package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +19 -2
- package/resources/gofer/node-scripts/gofer-delivery-check.mjs +121 -0
- package/resources/gofer/node-scripts/gofer-encrypted-key.mjs +58 -0
- package/resources/gofer/node-scripts/gofer-execution-metrics.mjs +477 -0
- package/resources/gofer/node-scripts/gofer-execution-recovery.mjs +334 -0
- package/resources/gofer/node-scripts/gofer-grok-adapter.mjs +184 -0
- package/resources/gofer/node-scripts/gofer-heldout-corpus.mjs +73 -0
- package/resources/gofer/node-scripts/gofer-heldout-snapshot.mjs +286 -0
- package/resources/gofer/node-scripts/gofer-heldout-verifier.mjs +211 -0
- package/resources/gofer/node-scripts/gofer-host-capability.mjs +335 -0
- package/resources/gofer/node-scripts/gofer-independent-reviewer.mjs +130 -0
- package/resources/gofer/node-scripts/gofer-live-routing.mjs +109 -0
- package/resources/gofer/node-scripts/gofer-local-capability-issuer.mjs +71 -0
- package/resources/gofer/node-scripts/gofer-local-isolation.mjs +175 -0
- package/resources/gofer/node-scripts/gofer-local-settings-cleanup.mjs +388 -0
- package/resources/gofer/node-scripts/gofer-loop-audit.mjs +54 -3
- package/resources/gofer/node-scripts/gofer-native-adapter.mjs +567 -0
- package/resources/gofer/node-scripts/gofer-native-benchmark-dispatch.mjs +145 -0
- package/resources/gofer/node-scripts/gofer-native-runtime.mjs +169 -0
- package/resources/gofer/node-scripts/gofer-pre-edit-check.mjs +204 -0
- package/resources/gofer/node-scripts/gofer-priority-check.mjs +214 -0
- package/resources/gofer/node-scripts/gofer-response-check.mjs +56 -0
- package/resources/gofer/node-scripts/gofer-reviewed-learning.mjs +1232 -0
- package/resources/gofer/node-scripts/gofer-run-verified-task.mjs +330 -0
- package/resources/gofer/node-scripts/gofer-runtime-ledger.mjs +289 -0
- package/resources/gofer/node-scripts/gofer-semantic-drift.mjs +584 -0
- package/resources/gofer/node-scripts/gofer-surface-update.mjs +1178 -0
- package/resources/gofer/node-scripts/gofer-trust-bootstrap.mjs +77 -0
- package/resources/gofer/node-scripts/gofer-trusted-benchmark.mjs +102 -0
- package/resources/gofer/node-scripts/gofer-trusted-evaluator.mjs +274 -0
- package/resources/gofer/node-scripts/gofer-tty-prompt.mjs +34 -0
- package/resources/gofer/node-scripts/gofer-typesafe-credentials.mjs +435 -0
- package/resources/gofer/node-scripts/gofer-ui-preview.mjs +1212 -0
- package/resources/gofer/node-scripts/gofer-verified-execution.mjs +484 -0
- package/resources/gofer/node-scripts/gofer-verifier-key-ceremony.mjs +101 -0
- package/resources/gofer/node-scripts/gofer-worktree-layout.mjs +32 -0
- package/resources/gofer/node-scripts/object-type-routing-phase-bundle.mjs +360 -0
- package/resources/gofer/node-scripts/package-agent-plugin.mjs +574 -82
- package/resources/gofer/node-scripts/parse-stage-command.mjs +1 -1
- package/resources/gofer/node-scripts/render-delivery-lineage.mjs +178 -0
- package/resources/gofer/node-scripts/sync-extension-resources.mjs +78 -2
- package/resources/gofer/node-scripts/validate-object-type-identifiers.mjs +767 -0
- package/resources/gofer/node-scripts/validate-object-type-routing-workspace.mjs +1325 -0
- package/resources/gofer/node-scripts/validate-v4-resource-contract.d.mts +44 -0
- package/resources/gofer/node-scripts/validate-v4-resource-contract.mjs +957 -0
- package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +685 -116
- package/resources/gofer/references/agent-catalog.json +126 -0
- package/resources/gofer/references/blocker-mediation.md +156 -0
- package/resources/gofer/references/business-updates-and-goal-checks.md +109 -0
- package/resources/gofer/references/delivery-lineage.md +48 -0
- package/resources/gofer/references/mvp-capability-validation.md +102 -0
- package/resources/gofer/references/platform/README.md +1 -1
- package/resources/gofer/references/platform/eai-app-template.md +15 -13
- package/resources/gofer/references/platform/eai-auth-access.md +104 -0
- package/resources/gofer/references/platform/eai-config-driven-ui.md +5 -5
- package/resources/gofer/references/platform/eai-error-catalog.yaml +77 -19
- package/resources/gofer/references/platform/eai-repo-contract.md +61 -23
- package/resources/gofer/references/platform/eai-service-patterns.md +102 -105
- package/resources/gofer/references/platform/eai.md +44 -8
- package/resources/gofer/references/platform/vertical-template.md +10 -9
- package/resources/gofer/references/priority-outcome-protection.md +152 -0
- package/resources/gofer/references/verified-agent-execution.md +179 -0
- package/resources/gofer/schemas/gofer-learning-trace-v1.json +70 -0
- package/resources/gofer/specify-commands/0_gofer_start.md +440 -99
- package/resources/gofer/specify-commands/0a_problem_validation.md +187 -27
- package/resources/gofer/specify-commands/10_gofer_cloud.md +183 -23
- package/resources/gofer/specify-commands/1_gofer_research.md +239 -30
- package/resources/gofer/specify-commands/2_gofer_specify.md +239 -35
- package/resources/gofer/specify-commands/3_gofer_plan.md +259 -43
- package/resources/gofer/specify-commands/4_gofer_tasks.md +401 -81
- package/resources/gofer/specify-commands/5_gofer_implement.md +375 -84
- package/resources/gofer/specify-commands/6_gofer_validate.md +284 -53
- package/resources/gofer/specify-commands/7_gofer_save.md +187 -26
- package/resources/gofer/specify-commands/7a_stakeholder_comms.md +183 -23
- package/resources/gofer/specify-commands/8_gofer_branding.md +183 -23
- package/resources/gofer/specify-commands/9_gofer_tests.md +212 -23
- package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +121 -8
- package/resources/gofer/specify-commands/gofer_check_workspace.md +123 -8
- package/resources/gofer/specify-commands/gofer_constitution.md +183 -23
- package/resources/gofer/specify-commands/gofer_diagnose.md +183 -23
- package/resources/gofer/specify-commands/gofer_eai_first_run.md +254 -25
- package/resources/gofer/specify-commands/gofer_hydrate.md +183 -23
- package/resources/gofer/specify-commands/gofer_personality.md +117 -6
- package/resources/gofer/specify-commands/gofer_plan.md +117 -6
- package/resources/gofer/specify-commands/gofer_side.md +117 -6
- package/resources/gofer/specify-commands/gofer_spec_summary.md +183 -23
- package/resources/gofer/specify-commands/gofer_tdd.md +183 -23
- package/resources/gofer/specify-commands/gofer_vocabulary.md +185 -25
- package/resources/gofer/specify-commands/gofer_zoom_out.md +183 -23
- package/resources/gofer/specify-config/object-type-routing.json +24 -0
- package/resources/gofer/specify-config/typesafe-learning-review.json +16 -0
- package/resources/gofer/specify-config/typesafe-semantic-review.json +9 -0
- package/resources/gofer/system-skills/eai/SKILL.md +365 -0
- package/resources/gofer/system-skills/eai-update/SKILL.md +56 -0
- package/resources/gofer/system-skills/gofer-documentation/SKILL.md +93 -0
- package/resources/gofer/templates/build-map-template.md +64 -0
- package/resources/gofer/templates/business-scenarios-template.json +14 -0
- package/resources/gofer/templates/ciso-security-summary-template.md +3 -3
- package/resources/gofer/templates/context-bundle-template.md +4 -3
- package/resources/gofer/templates/contract-pack-template.md +8 -8
- package/resources/gofer/templates/cto-architecture-summary-template.md +3 -3
- package/resources/gofer/templates/delivery-lineage-template.json +8 -0
- package/resources/gofer/templates/eai-preflight-template.md +109 -68
- package/resources/gofer/templates/goal-ledger-template.json +1 -1
- package/resources/gofer/templates/gofer-model-policy.yaml +28 -6
- package/resources/gofer/templates/loop-contract-template.json +3 -1
- package/resources/gofer/templates/plan-template.md +8 -7
- package/resources/gofer/templates/priority-plan-template.json +29 -0
- package/resources/gofer/templates/proposal-review-template.md +6 -3
- package/resources/gofer/templates/release-capability-ledger-template.md +24 -0
- package/resources/gofer/templates/research-template.md +7 -6
- package/resources/gofer/templates/spec-summary-template.md +1 -1
- package/resources/gofer/templates/spec-template.md +45 -6
- package/resources/gofer/templates/tasks-template.md +12 -3
- package/resources/gofer/templates/ui-preview-brief-template.md +55 -5
- package/resources/gofer/templates/ui-review-log-template.md +21 -3
- package/resources/gofer/templates/ui-show-and-tell-template.md +46 -0
- package/resources/gofer/templates/visuals/capability-heatmap-template.md +2 -2
- package/resources/gofer/templates/working-backwards-prfaq-template.md +9 -8
- package/resources/linked-sources.json +4 -4
- package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +0 -1287
- package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +0 -429
- package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +0 -635
- package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +0 -1159
- package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +0 -860
- package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +0 -899
- package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +0 -760
- package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +0 -944
- package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +0 -2302
- package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +0 -423
- package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +0 -508
- package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +0 -315
- package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +0 -558
- package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
- package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +0 -119
- package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +0 -612
- package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +0 -114
- package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +0 -397
- package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +0 -561
- package/resources/gofer/agents-skills/gofer_personality/SKILL.md +0 -44
- package/resources/gofer/agents-skills/gofer_plan/SKILL.md +0 -40
- package/resources/gofer/agents-skills/gofer_side/SKILL.md +0 -45
- package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +0 -112
- package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +0 -112
- package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +0 -112
- package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +0 -112
- package/resources/gofer/claude-commands/0_gofer_start.md +0 -1282
- package/resources/gofer/claude-commands/0a_problem_validation.md +0 -424
- package/resources/gofer/claude-commands/10_gofer_cloud.md +0 -630
- package/resources/gofer/claude-commands/1_gofer_research.md +0 -1154
- package/resources/gofer/claude-commands/2_gofer_specify.md +0 -855
- package/resources/gofer/claude-commands/3_gofer_plan.md +0 -894
- package/resources/gofer/claude-commands/4_gofer_tasks.md +0 -755
- package/resources/gofer/claude-commands/5_gofer_implement.md +0 -939
- package/resources/gofer/claude-commands/6_gofer_validate.md +0 -2297
- package/resources/gofer/claude-commands/7_gofer_save.md +0 -418
- package/resources/gofer/claude-commands/7a_stakeholder_comms.md +0 -503
- package/resources/gofer/claude-commands/8_gofer_branding.md +0 -310
- package/resources/gofer/claude-commands/9_gofer_tests.md +0 -553
- package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +0 -143
- package/resources/gofer/claude-commands/gofer_check_workspace.md +0 -114
- package/resources/gofer/claude-commands/gofer_constitution.md +0 -607
- package/resources/gofer/claude-commands/gofer_diagnose.md +0 -109
- package/resources/gofer/claude-commands/gofer_eai_first_run.md +0 -392
- package/resources/gofer/claude-commands/gofer_hydrate.md +0 -556
- package/resources/gofer/claude-commands/gofer_personality.md +0 -39
- package/resources/gofer/claude-commands/gofer_plan.md +0 -35
- package/resources/gofer/claude-commands/gofer_side.md +0 -40
- package/resources/gofer/claude-commands/gofer_spec_summary.md +0 -107
- package/resources/gofer/claude-commands/gofer_tdd.md +0 -107
- package/resources/gofer/claude-commands/gofer_vocabulary.md +0 -107
- package/resources/gofer/claude-commands/gofer_zoom_out.md +0 -107
- package/resources/gofer/claude-skills/eai-gofer/SKILL.md +0 -56
- package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +0 -1308
- package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +0 -429
- package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +0 -644
- package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +0 -1177
- package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +0 -878
- package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +0 -917
- package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +0 -778
- package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +0 -962
- package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +0 -2310
- package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +0 -433
- package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +0 -516
- package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +0 -323
- package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +0 -566
- package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +0 -161
- package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +0 -132
- package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +0 -621
- package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +0 -127
- package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +0 -410
- package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +0 -571
- package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +0 -57
- package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +0 -53
- package/resources/gofer/copilot-prompts/gofer_side.prompt.md +0 -58
- package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +0 -125
- package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +0 -125
- package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +0 -125
- package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +0 -125
- package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +0 -1282
- package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +0 -424
- package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +0 -630
- package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +0 -1154
- package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +0 -855
- package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +0 -894
- package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +0 -755
- package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +0 -939
- package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +0 -2297
- package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +0 -418
- package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +0 -503
- package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +0 -310
- package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +0 -553
- package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +0 -143
- package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +0 -114
- package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +0 -607
- package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +0 -109
- package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +0 -392
- package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +0 -556
- package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_personality.md +0 -39
- package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_plan.md +0 -35
- package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_side.md +0 -40
- package/resources/gofer/gemini/commands/gofer/gofer_side.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +0 -107
- package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +0 -107
- package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +0 -107
- package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +0 -2
- package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +0 -107
- package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +0 -2
- package/resources/gofer/github-skills/eai-gofer/SKILL.md +0 -56
- package/resources/gofer/system-skills/0_gofer_start/SKILL.md +0 -1287
- package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +0 -429
- package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +0 -635
- package/resources/gofer/system-skills/1_gofer_research/SKILL.md +0 -1159
- package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +0 -860
- package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +0 -899
- package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +0 -760
- package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +0 -944
- package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +0 -2302
- package/resources/gofer/system-skills/7_gofer_save/SKILL.md +0 -423
- package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +0 -508
- package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +0 -315
- package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +0 -558
- package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +0 -148
- package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +0 -119
- package/resources/gofer/system-skills/gofer_constitution/SKILL.md +0 -612
- package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +0 -114
- package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +0 -397
- package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +0 -561
- package/resources/gofer/system-skills/gofer_personality/SKILL.md +0 -44
- package/resources/gofer/system-skills/gofer_plan/SKILL.md +0 -40
- package/resources/gofer/system-skills/gofer_side/SKILL.md +0 -45
- package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +0 -112
- package/resources/gofer/system-skills/gofer_tdd/SKILL.md +0 -112
- package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +0 -112
- package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +0 -112
- package/resources/gofer/templates/ui-approval-template.md +0 -32
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/** Validate the EAI local-isolation contract for Gofer's new task worktree.
|
|
2
|
+
* This is preflight evidence only. Native host invocation must still prove
|
|
3
|
+
* that the effective sandbox remained enabled for the task. */
|
|
4
|
+
import { execFile, spawnSync } from 'node:child_process';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { accessSync, constants, existsSync, mkdtempSync, realpathSync, rmSync, rmdirSync, statSync } from 'node:fs';
|
|
7
|
+
import { delimiter, dirname, isAbsolute, join, relative, sep } from 'node:path';
|
|
8
|
+
import { promisify } from 'node:util';
|
|
9
|
+
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
const text = value => typeof value === 'string' && value.trim().length > 0;
|
|
12
|
+
// Observed on the local Codex CLI 0.154.0. A changed signing identity fails
|
|
13
|
+
// closed until the host contract is reviewed.
|
|
14
|
+
const CODEX_MACOS_SIGNATURE_REQUIREMENT =
|
|
15
|
+
'=anchor apple generic and certificate leaf[subject.OU] = "2DC432GLL2"';
|
|
16
|
+
const CODEX_PROFILE = 'gofer-isolated';
|
|
17
|
+
|
|
18
|
+
/** Build one policy for both the no-model probe and the native invocation. */
|
|
19
|
+
export function codexIsolatedPermissionArgs(workspaceRoot) {
|
|
20
|
+
if (!text(workspaceRoot)) return null;
|
|
21
|
+
const git = spawnSync('/usr/bin/git', ['-C', workspaceRoot, 'rev-parse',
|
|
22
|
+
'--path-format=absolute', '--show-toplevel', '--git-dir', '--git-common-dir'],
|
|
23
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000,
|
|
24
|
+
env: Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.startsWith('GIT_'))) });
|
|
25
|
+
if (git.status !== 0 || !git.stdout?.trim()) return null;
|
|
26
|
+
const [topLevel, gitDirectory, commonDirectory] = git.stdout.trim().split('\n');
|
|
27
|
+
if (!topLevel || !gitDirectory || !commonDirectory) return null;
|
|
28
|
+
let common;
|
|
29
|
+
let workspace;
|
|
30
|
+
let gitDir;
|
|
31
|
+
let top;
|
|
32
|
+
try {
|
|
33
|
+
common = realpathSync(commonDirectory);
|
|
34
|
+
workspace = realpathSync(workspaceRoot);
|
|
35
|
+
gitDir = realpathSync(gitDirectory);
|
|
36
|
+
top = realpathSync(topLevel);
|
|
37
|
+
} catch { return null; }
|
|
38
|
+
const commonRelative = relative(workspace, common);
|
|
39
|
+
if (top !== workspace || gitDir === common || commonRelative === '' ||
|
|
40
|
+
(!commonRelative.startsWith(`..${sep}`) && commonRelative !== '..' && !isAbsolute(commonRelative))) return null;
|
|
41
|
+
return Object.freeze({ common,
|
|
42
|
+
config: Object.freeze([
|
|
43
|
+
`permissions.${CODEX_PROFILE}.extends=":workspace"`,
|
|
44
|
+
`permissions.${CODEX_PROFILE}.filesystem={ ":tmpdir" = "read", ":slash_tmp" = "read", ${JSON.stringify(common)} = "read" }`,
|
|
45
|
+
`default_permissions="${CODEX_PROFILE}"`,
|
|
46
|
+
]) });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function signedCodexExecutable() {
|
|
50
|
+
if (process.platform !== 'darwin') return null;
|
|
51
|
+
for (const entry of (process.env.PATH ?? '').split(delimiter)) {
|
|
52
|
+
if (!entry || !isAbsolute(entry)) continue;
|
|
53
|
+
const candidate = join(entry, 'codex');
|
|
54
|
+
try {
|
|
55
|
+
accessSync(candidate, constants.X_OK);
|
|
56
|
+
const executable = realpathSync(candidate);
|
|
57
|
+
if (!statSync(executable).isFile()) return null;
|
|
58
|
+
const signature = spawnSync('/usr/bin/codesign', ['--verify', '--strict', '--requirement',
|
|
59
|
+
CODEX_MACOS_SIGNATURE_REQUIREMENT, executable], { stdio: 'ignore', timeout: 10000 });
|
|
60
|
+
const identity = spawnSync('/usr/bin/codesign', ['-dv', '--verbose=2', executable], {
|
|
61
|
+
encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10000,
|
|
62
|
+
});
|
|
63
|
+
if (signature.status !== 0 || signature.error || identity.status !== 0 ||
|
|
64
|
+
!/\bTeamIdentifier=2DC432GLL2\b/.test(identity.stderr)) return null;
|
|
65
|
+
return executable;
|
|
66
|
+
} catch { /* Try the next PATH entry only when this one has no executable. */ }
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A no-model boundary probe. A worker must not write the shared Git store. */
|
|
72
|
+
export function probeMacCodexSandboxBoundary({ workspaceRoot, executable, runSandbox = spawnSync } = {}) {
|
|
73
|
+
if (!workspaceRoot || !executable || !existsSync('/usr/bin/touch') ||
|
|
74
|
+
typeof runSandbox !== 'function') return null;
|
|
75
|
+
const policy = codexIsolatedPermissionArgs(workspaceRoot);
|
|
76
|
+
if (!policy) return null;
|
|
77
|
+
let sibling;
|
|
78
|
+
try { sibling = mkdtempSync(join(dirname(workspaceRoot), '.gofer-isolation-probe-')); }
|
|
79
|
+
catch { return null; }
|
|
80
|
+
const inside = join(workspaceRoot, `.gofer-isolation-probe-${randomUUID()}`);
|
|
81
|
+
const outside = join(sibling, 'outside');
|
|
82
|
+
const sharedGit = join(policy.common, `.gofer-isolation-probe-${randomUUID()}`);
|
|
83
|
+
const probe = target => runSandbox(executable,
|
|
84
|
+
['sandbox', '-P', CODEX_PROFILE, ...policy.config.flatMap(value => ['-c', value]),
|
|
85
|
+
'-C', workspaceRoot, '--', '/usr/bin/touch', target],
|
|
86
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 15000, maxBuffer: 16384 });
|
|
87
|
+
const denied = result => result.status !== 0 && !result.error &&
|
|
88
|
+
/Operation not permitted|Permission denied/i.test(`${result.stderr}\n${result.stdout}`);
|
|
89
|
+
try {
|
|
90
|
+
for (const target of [outside, sharedGit]) {
|
|
91
|
+
const baseline = spawnSync('/usr/bin/touch', [target], { stdio: 'ignore', timeout: 5000 });
|
|
92
|
+
if (baseline.status !== 0 || !existsSync(target)) return null;
|
|
93
|
+
rmSync(target);
|
|
94
|
+
}
|
|
95
|
+
const allowed = probe(inside);
|
|
96
|
+
if (allowed.status !== 0 || !existsSync(inside)) return null;
|
|
97
|
+
const siblingResult = probe(outside);
|
|
98
|
+
if (!denied(siblingResult) || existsSync(outside)) return null;
|
|
99
|
+
const gitResult = probe(sharedGit);
|
|
100
|
+
return denied(gitResult) && !existsSync(sharedGit) ? executable : null;
|
|
101
|
+
} catch { return null; }
|
|
102
|
+
finally {
|
|
103
|
+
rmSync(inside, { force: true });
|
|
104
|
+
rmSync(outside, { force: true });
|
|
105
|
+
rmSync(sharedGit, { force: true });
|
|
106
|
+
try { rmdirSync(sibling); } catch { /* Preserve unexpected contents. */ }
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** An independent check of the signed executable Gofer will launch. */
|
|
111
|
+
export function probeNativeCodexSandbox(workspaceRoot) {
|
|
112
|
+
const executable = signedCodexExecutable();
|
|
113
|
+
return executable ? probeMacCodexSandboxBoundary({ workspaceRoot, executable }) : null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const LOCAL_ISOLATION_CONTRACT = 'eai.local-isolation/v2';
|
|
117
|
+
|
|
118
|
+
const HOST_SURFACES = Object.freeze({
|
|
119
|
+
codex: 'codex-cli',
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
function hasQualifiedHostArguments(host, workspaceRoot, args) {
|
|
123
|
+
if (host !== 'codex' || !Array.isArray(args)) return false;
|
|
124
|
+
const policy = codexIsolatedPermissionArgs(workspaceRoot);
|
|
125
|
+
if (!policy) return false;
|
|
126
|
+
const expected = ['--ask-for-approval', 'never', 'exec', '--ignore-user-config',
|
|
127
|
+
...policy.config.flatMap(value => ['-c', value])];
|
|
128
|
+
return args.length === expected.length && args.every((value, index) => value === expected[index]);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function verifyLocalIsolationReport(report, { host, workspaceRoot } = {}) {
|
|
132
|
+
const surfaceId = HOST_SURFACES[host];
|
|
133
|
+
if (!surfaceId || !text(workspaceRoot) || !report || report.contractVersion !== LOCAL_ISOLATION_CONTRACT ||
|
|
134
|
+
report.cloudExecution !== 'prohibited' || report.gitRepository !== true || !text(report.projectDirectory) ||
|
|
135
|
+
!Array.isArray(report.assessments)) return false;
|
|
136
|
+
const matchingAssessments = report.assessments.filter(item => item?.surfaceId === surfaceId);
|
|
137
|
+
if (matchingAssessments.length !== 1) return false;
|
|
138
|
+
const assessment = matchingAssessments[0];
|
|
139
|
+
if (!assessment || assessment.status !== 'ready' || assessment.localOnly !== true ||
|
|
140
|
+
assessment.requiresGitWorktree !== true || assessment.requiresOsSandbox !== true ||
|
|
141
|
+
!hasQualifiedHostArguments(host, workspaceRoot, assessment.hostArguments) ||
|
|
142
|
+
!Array.isArray(assessment.missing) || assessment.missing.length !== 0) return false;
|
|
143
|
+
const normalizedReportRoot = report.projectDirectory.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
144
|
+
const normalizedWorkspace = workspaceRoot.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
145
|
+
return normalizedReportRoot === normalizedWorkspace;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Query the installed local EAI CLI for the worktree Gofer actually created. */
|
|
149
|
+
export async function inspectEaiLocalIsolation({ host, workspaceRoot, command = 'eai',
|
|
150
|
+
run = execFileAsync, verifyNativeSandbox = probeNativeCodexSandbox } = {}) {
|
|
151
|
+
const surfaceId = HOST_SURFACES[host];
|
|
152
|
+
if (!surfaceId || !text(workspaceRoot) || !text(command) ||
|
|
153
|
+
typeof run !== 'function' || typeof verifyNativeSandbox !== 'function') {
|
|
154
|
+
throw new Error('LOCAL_SANDBOX_REQUIRED');
|
|
155
|
+
}
|
|
156
|
+
let stdout;
|
|
157
|
+
try {
|
|
158
|
+
({ stdout } = await run(command,
|
|
159
|
+
['start', workspaceRoot, '--isolation-check', '--surface', surfaceId, '--format', 'json'],
|
|
160
|
+
{ encoding: 'utf8', timeout: 15000, maxBuffer: 1024 * 1024, windowsHide: true }));
|
|
161
|
+
} catch {
|
|
162
|
+
throw new Error('LOCAL_SANDBOX_REQUIRED');
|
|
163
|
+
}
|
|
164
|
+
let report;
|
|
165
|
+
try { report = JSON.parse(stdout); }
|
|
166
|
+
catch { throw new Error('LOCAL_SANDBOX_REQUIRED'); }
|
|
167
|
+
if (!verifyLocalIsolationReport(report, { host, workspaceRoot })) {
|
|
168
|
+
throw new Error('LOCAL_SANDBOX_REQUIRED');
|
|
169
|
+
}
|
|
170
|
+
let nativeExecutable;
|
|
171
|
+
try { nativeExecutable = verifyNativeSandbox(workspaceRoot); }
|
|
172
|
+
catch { throw new Error('LOCAL_SANDBOX_REQUIRED'); }
|
|
173
|
+
if (!text(nativeExecutable) || !isAbsolute(nativeExecutable)) throw new Error('LOCAL_SANDBOX_REQUIRED');
|
|
174
|
+
return Object.freeze({ ...report, nativeExecutable });
|
|
175
|
+
}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { promises as fs } from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
export const STALE_GOFER_STEMS = [
|
|
9
|
+
'0_business_scenario',
|
|
10
|
+
'0a_problem_validation',
|
|
11
|
+
'0_gofer_start',
|
|
12
|
+
'1_gofer_research',
|
|
13
|
+
'2_gofer_specify',
|
|
14
|
+
'3_gofer_plan',
|
|
15
|
+
'4_gofer_tasks',
|
|
16
|
+
'5_gofer_implement',
|
|
17
|
+
'6_gofer_validate',
|
|
18
|
+
'6a_gofer_engineering_review',
|
|
19
|
+
'7_gofer_save',
|
|
20
|
+
'7a_stakeholder_comms',
|
|
21
|
+
'8_gofer_branding',
|
|
22
|
+
'8_gofer_resume',
|
|
23
|
+
'9_gofer_tests',
|
|
24
|
+
'10_gofer_cloud',
|
|
25
|
+
'gofer',
|
|
26
|
+
'gofer_bootstrap_workspace',
|
|
27
|
+
'gofer_check_workspace',
|
|
28
|
+
'gofer_constitution',
|
|
29
|
+
'gofer_diagnose',
|
|
30
|
+
'gofer_eai_first_run',
|
|
31
|
+
'gofer_hydrate',
|
|
32
|
+
'gofer_personality',
|
|
33
|
+
'gofer_plan',
|
|
34
|
+
'gofer_side',
|
|
35
|
+
'gofer_spec_summary',
|
|
36
|
+
'gofer_tdd',
|
|
37
|
+
'gofer_vocabulary',
|
|
38
|
+
'gofer_zoom_out',
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const GOFER_CONTENT_MARKER =
|
|
42
|
+
/\b(Gofer|gofer|eai-gofer|EAI delivery pipeline|\.specify\/commands|gofer-workspace-check)\b/;
|
|
43
|
+
|
|
44
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
45
|
+
|
|
46
|
+
function toPortablePath(value) {
|
|
47
|
+
return value.split(path.sep).join('/');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function buildArchiveStamp(now = new Date()) {
|
|
51
|
+
return now.toISOString().replace(/[:.]/g, '-');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildVisibleSurfaceRelatives(stem) {
|
|
55
|
+
return [
|
|
56
|
+
path.join('.claude', 'commands', `${stem}.md`),
|
|
57
|
+
path.join('.claude', 'skills', stem),
|
|
58
|
+
path.join('.github', 'prompts', `${stem}.prompt.md`),
|
|
59
|
+
path.join('.github', 'skills', stem),
|
|
60
|
+
path.join('.agents', 'skills', stem),
|
|
61
|
+
path.join('.system', 'skills', stem),
|
|
62
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.md`),
|
|
63
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.toml`),
|
|
64
|
+
path.join('.grok', 'skills', stem),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildHomeRelatives(stem) {
|
|
69
|
+
return [
|
|
70
|
+
path.join('.claude', 'commands', `${stem}.md`),
|
|
71
|
+
path.join('.claude', 'skills', stem),
|
|
72
|
+
path.join('.codex', 'skills', stem),
|
|
73
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.md`),
|
|
74
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.toml`),
|
|
75
|
+
path.join('.grok', 'skills', stem),
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function buildBundleRelatives(stem) {
|
|
80
|
+
return [
|
|
81
|
+
path.join('commands', `${stem}.md`),
|
|
82
|
+
path.join('skills', stem),
|
|
83
|
+
path.join('plugin-skills', stem),
|
|
84
|
+
path.join('.claude', 'commands', `${stem}.md`),
|
|
85
|
+
path.join('.claude', 'skills', stem),
|
|
86
|
+
path.join('.github', 'prompts', `${stem}.prompt.md`),
|
|
87
|
+
path.join('.github', 'skills', stem),
|
|
88
|
+
path.join('.agents', 'skills', stem),
|
|
89
|
+
path.join('.system', 'skills', stem),
|
|
90
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.md`),
|
|
91
|
+
path.join('.gemini', 'commands', 'gofer', `${stem}.toml`),
|
|
92
|
+
path.join('.grok', 'skills', stem),
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function pathExists(targetPath) {
|
|
97
|
+
try {
|
|
98
|
+
await fs.access(targetPath);
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function readTextIfFile(targetPath) {
|
|
106
|
+
try {
|
|
107
|
+
return await fs.readFile(targetPath, 'utf8');
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function directoryHasGoferMarker(targetPath, limit = 40) {
|
|
114
|
+
let checked = 0;
|
|
115
|
+
|
|
116
|
+
async function visit(current) {
|
|
117
|
+
if (checked >= limit) return false;
|
|
118
|
+
let entries;
|
|
119
|
+
try {
|
|
120
|
+
entries = await fs.readdir(current, { withFileTypes: true });
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (const entry of entries) {
|
|
126
|
+
const fullPath = path.join(current, entry.name);
|
|
127
|
+
if (entry.isDirectory()) {
|
|
128
|
+
if (await visit(fullPath)) return true;
|
|
129
|
+
} else if (entry.isFile()) {
|
|
130
|
+
checked += 1;
|
|
131
|
+
const content = await readTextIfFile(fullPath);
|
|
132
|
+
if (content && GOFER_CONTENT_MARKER.test(content)) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return await visit(targetPath);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function isGoferManagedTarget(targetPath) {
|
|
145
|
+
const content = await readTextIfFile(targetPath);
|
|
146
|
+
if (content !== null) {
|
|
147
|
+
return GOFER_CONTENT_MARKER.test(content);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const stat = await fs.stat(targetPath);
|
|
152
|
+
if (!stat.isDirectory()) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return await directoryHasGoferMarker(targetPath);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function sanitizeArchivePart(value) {
|
|
163
|
+
return toPortablePath(value)
|
|
164
|
+
.replace(/^[A-Za-z]:/, (match) => match.replace(':', ''))
|
|
165
|
+
.replace(/[^A-Za-z0-9._/-]+/g, '_')
|
|
166
|
+
.replace(/^\/+/, '')
|
|
167
|
+
.replace(/\/+/g, '/');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function moveToArchive(targetPath, archivePath) {
|
|
171
|
+
await fs.mkdir(path.dirname(archivePath), { recursive: true });
|
|
172
|
+
try {
|
|
173
|
+
await fs.rename(targetPath, archivePath);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (error?.code !== 'EXDEV') {
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
await fs.cp(targetPath, archivePath, { recursive: true, force: true });
|
|
179
|
+
await fs.rm(targetPath, { recursive: true, force: true });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function uniqueCandidates(candidates) {
|
|
184
|
+
const seen = new Set();
|
|
185
|
+
return candidates.filter((candidate) => {
|
|
186
|
+
const key = path.resolve(candidate.root, candidate.relativePath);
|
|
187
|
+
if (seen.has(key)) return false;
|
|
188
|
+
seen.add(key);
|
|
189
|
+
return true;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function discoverCodexCacheBundleRoots(home) {
|
|
194
|
+
const roots = [];
|
|
195
|
+
const base = path.join(home, '.codex', 'plugins', 'cache', 'eai-gofer', 'eai-gofer');
|
|
196
|
+
let entries;
|
|
197
|
+
try {
|
|
198
|
+
entries = await fs.readdir(base, { withFileTypes: true });
|
|
199
|
+
} catch {
|
|
200
|
+
return roots;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
for (const entry of entries) {
|
|
204
|
+
if (entry.isDirectory()) {
|
|
205
|
+
roots.push(path.join(base, entry.name));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return roots;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async function buildCleanupCandidates({ home, workspaces = [], bundleRoots = [] }) {
|
|
213
|
+
const candidates = [];
|
|
214
|
+
|
|
215
|
+
for (const stem of STALE_GOFER_STEMS) {
|
|
216
|
+
for (const relativePath of buildHomeRelatives(stem)) {
|
|
217
|
+
candidates.push({ scope: 'home', root: home, relativePath });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const defaultBundleRoots = [
|
|
222
|
+
path.join(home, 'plugins', 'eai-gofer'),
|
|
223
|
+
path.join(home, '.claude', 'plugins', 'marketplaces', 'eai-gofer', 'plugins', 'eai-gofer'),
|
|
224
|
+
path.join(home, '.gemini', 'extensions', 'eai-gofer'),
|
|
225
|
+
...(await discoverCodexCacheBundleRoots(home)),
|
|
226
|
+
...bundleRoots,
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
for (const bundleRoot of defaultBundleRoots) {
|
|
230
|
+
for (const stem of STALE_GOFER_STEMS) {
|
|
231
|
+
for (const relativePath of buildBundleRelatives(stem)) {
|
|
232
|
+
candidates.push({ scope: 'bundle', root: bundleRoot, relativePath });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
candidates.push({
|
|
236
|
+
scope: 'bundle',
|
|
237
|
+
root: bundleRoot,
|
|
238
|
+
relativePath: path.join('.specify', 'commands', '0_business_scenario.md'),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for (const workspaceRoot of workspaces) {
|
|
243
|
+
for (const stem of STALE_GOFER_STEMS) {
|
|
244
|
+
for (const relativePath of buildVisibleSurfaceRelatives(stem)) {
|
|
245
|
+
candidates.push({ scope: 'workspace', root: workspaceRoot, relativePath });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
candidates.push({
|
|
249
|
+
scope: 'workspace',
|
|
250
|
+
root: workspaceRoot,
|
|
251
|
+
relativePath: path.join('.specify', 'commands', '0_business_scenario.md'),
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return uniqueCandidates(candidates);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function cleanupLocalSettings({
|
|
259
|
+
home = os.homedir(),
|
|
260
|
+
workspaces = [],
|
|
261
|
+
bundleRoots = [],
|
|
262
|
+
apply = false,
|
|
263
|
+
now = new Date(),
|
|
264
|
+
} = {}) {
|
|
265
|
+
const archiveStamp = buildArchiveStamp(now);
|
|
266
|
+
const archiveRoot = path.join(home, '.eai-gofer', 'legacy-settings-backups', archiveStamp);
|
|
267
|
+
const report = {
|
|
268
|
+
status: apply ? 'applied' : 'planned',
|
|
269
|
+
archiveRoot,
|
|
270
|
+
removed: [],
|
|
271
|
+
skipped: [],
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
for (const candidate of await buildCleanupCandidates({ home, workspaces, bundleRoots })) {
|
|
275
|
+
const targetPath = path.join(candidate.root, candidate.relativePath);
|
|
276
|
+
if (!(await pathExists(targetPath))) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!(await isGoferManagedTarget(targetPath))) {
|
|
281
|
+
report.skipped.push({
|
|
282
|
+
scope: candidate.scope,
|
|
283
|
+
path: targetPath,
|
|
284
|
+
reason: 'no-gofer-marker',
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const archivePath = path.join(
|
|
290
|
+
archiveRoot,
|
|
291
|
+
candidate.scope,
|
|
292
|
+
sanitizeArchivePart(candidate.root),
|
|
293
|
+
sanitizeArchivePart(candidate.relativePath)
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
report.removed.push({
|
|
297
|
+
scope: candidate.scope,
|
|
298
|
+
path: targetPath,
|
|
299
|
+
archivePath,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
if (apply) {
|
|
303
|
+
await moveToArchive(targetPath, archivePath);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return report;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function parseArgs(argv) {
|
|
311
|
+
const options = {
|
|
312
|
+
home: os.homedir(),
|
|
313
|
+
workspaces: [],
|
|
314
|
+
bundleRoots: [],
|
|
315
|
+
apply: false,
|
|
316
|
+
json: false,
|
|
317
|
+
help: false,
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
321
|
+
const arg = argv[index];
|
|
322
|
+
const next = () => argv[++index];
|
|
323
|
+
|
|
324
|
+
if (arg === '--home') options.home = path.resolve(next());
|
|
325
|
+
else if (arg === '--workspace') options.workspaces.push(path.resolve(next()));
|
|
326
|
+
else if (arg === '--bundle') options.bundleRoots.push(path.resolve(next()));
|
|
327
|
+
else if (arg === '--apply') options.apply = true;
|
|
328
|
+
else if (arg === '--dry-run') options.apply = false;
|
|
329
|
+
else if (arg === '--json') options.json = true;
|
|
330
|
+
else if (arg === '--help' || arg === '-h') options.help = true;
|
|
331
|
+
else throw new Error(`Unknown option: ${arg}`);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return options;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function helpText() {
|
|
338
|
+
return `Gofer Local Settings Cleanup
|
|
339
|
+
|
|
340
|
+
Archives stale Gofer command and skill entries from known Claude, Codex,
|
|
341
|
+
Copilot, Gemini, Grok, VS Code, desktop, and CLI surface paths.
|
|
342
|
+
|
|
343
|
+
Usage:
|
|
344
|
+
node .specify/scripts/node/gofer-local-settings-cleanup.mjs [options]
|
|
345
|
+
|
|
346
|
+
Options:
|
|
347
|
+
--workspace <path> Also clean repo-local visible command surfaces.
|
|
348
|
+
--bundle <path> Also clean a downloaded eai-gofer plugin bundle.
|
|
349
|
+
--home <path> Home directory to inspect. Defaults to current user.
|
|
350
|
+
--apply Move stale entries to an archive. Default is dry-run.
|
|
351
|
+
--dry-run Report planned cleanup only.
|
|
352
|
+
--json Print machine-readable output.
|
|
353
|
+
--help Show this help.
|
|
354
|
+
`;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async function main() {
|
|
358
|
+
const options = parseArgs(process.argv.slice(2));
|
|
359
|
+
if (options.help) {
|
|
360
|
+
console.log(helpText());
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const report = await cleanupLocalSettings(options);
|
|
365
|
+
if (options.json) {
|
|
366
|
+
console.log(JSON.stringify(report, null, 2));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const verb = options.apply ? 'archived' : 'would archive';
|
|
371
|
+
console.log(`Gofer cleanup ${report.status}. ${report.removed.length} stale entries ${verb}.`);
|
|
372
|
+
if (report.removed.length > 0) {
|
|
373
|
+
console.log(`Archive root: ${report.archiveRoot}`);
|
|
374
|
+
}
|
|
375
|
+
for (const item of report.removed) {
|
|
376
|
+
console.log(`- ${item.path}`);
|
|
377
|
+
}
|
|
378
|
+
if (report.skipped.length > 0) {
|
|
379
|
+
console.log(`Skipped ${report.skipped.length} candidate(s) without Gofer markers.`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (path.resolve(process.argv[1] ?? '') === path.resolve(__filename)) {
|
|
384
|
+
main().catch((error) => {
|
|
385
|
+
console.error(error?.message ?? String(error));
|
|
386
|
+
process.exit(1);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { promises as fs } from 'fs';
|
|
4
4
|
import path from 'path';
|
|
5
|
+
import { reviewDelivery } from './gofer-delivery-check.mjs';
|
|
6
|
+
import { inspectBlockers } from './gofer-blocker-control.mjs';
|
|
7
|
+
import { reviewPriority } from './gofer-priority-check.mjs';
|
|
5
8
|
|
|
6
9
|
const STAGE_ORDER = {
|
|
7
10
|
'0_gofer_start': 0,
|
|
@@ -62,7 +65,10 @@ function parseArgs(argv) {
|
|
|
62
65
|
args.featureDir = argv[++index] || '';
|
|
63
66
|
break;
|
|
64
67
|
case '--stage':
|
|
65
|
-
|
|
68
|
+
if (argv[index + 1] === undefined || argv[index + 1].startsWith('--')) {
|
|
69
|
+
throw new Error('--stage requires a value before the next option.');
|
|
70
|
+
}
|
|
71
|
+
args.stage = argv[++index];
|
|
66
72
|
break;
|
|
67
73
|
case '--init':
|
|
68
74
|
args.init = true;
|
|
@@ -112,7 +118,11 @@ function parseArgs(argv) {
|
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
function normalizeStage(stage) {
|
|
115
|
-
|
|
121
|
+
const normalized = String(stage).trim();
|
|
122
|
+
if (!Object.hasOwn(STAGE_ORDER, normalized)) {
|
|
123
|
+
throw new Error(`Unknown stage: ${normalized}. Supported stages: ${Object.keys(STAGE_ORDER).join(', ')}`);
|
|
124
|
+
}
|
|
125
|
+
return normalized;
|
|
116
126
|
}
|
|
117
127
|
|
|
118
128
|
async function pathExists(targetPath) {
|
|
@@ -158,6 +168,8 @@ function createDefaultContract(featureDir) {
|
|
|
158
168
|
const featureId = path.basename(featureDir);
|
|
159
169
|
return {
|
|
160
170
|
schemaVersion: 1,
|
|
171
|
+
requireDeliveryCheckpoint: true,
|
|
172
|
+
requirePriorityPlan: true,
|
|
161
173
|
loopId: featureId,
|
|
162
174
|
profile: 'standard',
|
|
163
175
|
objective:
|
|
@@ -189,7 +201,7 @@ function createDefaultContract(featureDir) {
|
|
|
189
201
|
id: 'closed-loop-audit',
|
|
190
202
|
stage: '6_validate',
|
|
191
203
|
command:
|
|
192
|
-
'node .specify/scripts/node/gofer-closed-loop-audit.mjs --feature-dir {FEATURE_DIR} --json --strict',
|
|
204
|
+
'node .specify/scripts/node/gofer-closed-loop-audit.mjs --feature-dir {FEATURE_DIR} --json --strict --completion',
|
|
193
205
|
purpose: 'Verify goal, traceability, drift, and validation freshness before final scoring.',
|
|
194
206
|
runWhen: 'before validation scoring',
|
|
195
207
|
},
|
|
@@ -251,6 +263,12 @@ function validateContract(contract) {
|
|
|
251
263
|
if (contract.schemaVersion !== 1) {
|
|
252
264
|
findings.push('schemaVersion must be 1');
|
|
253
265
|
}
|
|
266
|
+
if (contract.requireDeliveryCheckpoint !== undefined && typeof contract.requireDeliveryCheckpoint !== 'boolean') {
|
|
267
|
+
findings.push('requireDeliveryCheckpoint must be a boolean');
|
|
268
|
+
}
|
|
269
|
+
if (contract.requirePriorityPlan !== undefined && typeof contract.requirePriorityPlan !== 'boolean') {
|
|
270
|
+
findings.push('requirePriorityPlan must be a boolean');
|
|
271
|
+
}
|
|
254
272
|
for (const field of ['loopId', 'profile', 'objective', 'entryStage']) {
|
|
255
273
|
if (!hasMaterialText(contract[field])) {
|
|
256
274
|
findings.push(`${field} must be material text`);
|
|
@@ -441,6 +459,10 @@ ${formatList(result.blockingFindings)}
|
|
|
441
459
|
|
|
442
460
|
${formatList(result.warnings)}
|
|
443
461
|
|
|
462
|
+
## Coverage Notes
|
|
463
|
+
|
|
464
|
+
${formatList(result.coverageNotes)}
|
|
465
|
+
|
|
444
466
|
## Last Ledger Entry
|
|
445
467
|
|
|
446
468
|
\`\`\`json
|
|
@@ -462,6 +484,7 @@ async function analyze(args) {
|
|
|
462
484
|
contractCreated: false,
|
|
463
485
|
blockingFindings: [],
|
|
464
486
|
warnings: [],
|
|
487
|
+
coverageNotes: [],
|
|
465
488
|
ledgerEntries: 0,
|
|
466
489
|
maxIterations: null,
|
|
467
490
|
lastLedgerEntry: null,
|
|
@@ -506,6 +529,34 @@ async function analyze(args) {
|
|
|
506
529
|
result.warnings.push(...validation.warnings);
|
|
507
530
|
}
|
|
508
531
|
|
|
532
|
+
try {
|
|
533
|
+
result.blockerReview = await inspectBlockers(args.featureDir);
|
|
534
|
+
if (result.blockerReview.status === 'blocked') result.blockingFindings.push('Recorded blockers remain unresolved; inspect blocker-register.json before continuing affected work');
|
|
535
|
+
result.coverageNotes.push(result.blockerReview.coverage);
|
|
536
|
+
} catch {
|
|
537
|
+
result.blockingFindings.push('Blocker register or its evidence is invalid; stop affected work and review the local record');
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (STAGE_ORDER[args.stage] >= 4) {
|
|
541
|
+
if (contract?.requirePriorityPlan === true || await pathExists(path.join(args.featureDir, 'priority-plan.json'))) {
|
|
542
|
+
result.priorityReview = await reviewPriority(args.featureDir, { finish: STAGE_ORDER[args.stage] >= 6 });
|
|
543
|
+
result.blockingFindings.push(...result.priorityReview.findings);
|
|
544
|
+
} else {
|
|
545
|
+
result.coverageNotes.push('Legacy feature has no priority plan; priority and outcome receipts are unverified');
|
|
546
|
+
}
|
|
547
|
+
if (contract?.requireDeliveryCheckpoint === true || await pathExists(path.join(args.featureDir, 'delivery-checkpoint.json'))) {
|
|
548
|
+
try {
|
|
549
|
+
const delivery = await reviewDelivery(args.featureDir);
|
|
550
|
+
result.deliveryReview = delivery;
|
|
551
|
+
result.blockingFindings.push(...delivery.findings.map(item => `Delivery review: ${item}`));
|
|
552
|
+
} catch {
|
|
553
|
+
result.blockingFindings.push('Delivery review could not read the feature checkpoint');
|
|
554
|
+
}
|
|
555
|
+
} else {
|
|
556
|
+
result.coverageNotes.push('Delivery checkpoint not enabled for this legacy feature; task freshness is unverified');
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
509
560
|
if (result.blockingFindings.length > 0) {
|
|
510
561
|
result.status = 'fail';
|
|
511
562
|
} else if (result.warnings.length > 0) {
|