@rpamis/comet 0.4.0-beta.5 → 0.4.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -77
- package/assets/manifest.json +14 -5
- package/assets/skills/comet/SKILL.md +17 -282
- package/assets/skills/comet/reference/comet-yaml-fields.md +5 -3
- package/assets/skills/comet/reference/context-recovery.md +3 -3
- package/assets/skills/comet/reference/intent-frame.md +2 -2
- package/assets/skills/comet/reference/scripts.md +2 -2
- package/assets/skills/comet/rules/comet-workflow-guard.en.md +32 -0
- package/assets/skills/comet/rules/comet-workflow-guard.md +32 -0
- package/assets/skills/comet/scripts/comet-entry-runtime.mjs +7834 -0
- package/assets/skills/comet/scripts/comet-hook-router.mjs +10307 -0
- package/assets/skills/comet/scripts/comet-runtime.mjs +782 -425
- package/assets/skills/comet-any/SKILL.md +4 -4
- package/assets/skills/comet-any/reference/authoring-subagents.md +1 -1
- package/assets/skills/comet-any/reference/bundle-authoring.md +1 -1
- package/assets/skills/comet-any/reference/subagents/reference-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/script-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/skill-core-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/skill-reviewer.md +2 -2
- package/assets/skills/comet-any/reference/subagents/workflow-entry-author.md +3 -3
- package/assets/skills/comet-archive/SKILL.md +7 -9
- package/assets/skills/comet-build/SKILL.md +17 -11
- package/assets/skills/comet-classic/SKILL.md +293 -0
- package/assets/skills/comet-design/SKILL.md +1 -1
- package/assets/skills/comet-hotfix/SKILL.md +20 -6
- package/assets/skills/comet-native/SKILL.md +257 -0
- package/assets/skills/comet-native/reference/artifacts.md +204 -0
- package/assets/skills/comet-native/reference/commands.md +118 -0
- package/assets/skills/comet-native/reference/recovery.md +143 -0
- package/assets/skills/comet-native/scripts/comet-native-hook-guard.mjs +4 -0
- package/assets/skills/comet-native/scripts/comet-native-runtime.mjs +28898 -0
- package/assets/skills/comet-open/SKILL.md +4 -4
- package/assets/skills/comet-tweak/SKILL.md +22 -10
- package/assets/skills/comet-verify/SKILL.md +2 -0
- package/assets/skills-zh/comet/SKILL.md +17 -270
- package/assets/skills-zh/comet/reference/comet-yaml-fields.md +5 -3
- package/assets/skills-zh/comet/reference/context-recovery.md +3 -3
- package/assets/skills-zh/comet/reference/intent-frame.md +2 -2
- package/assets/skills-zh/comet/reference/scripts.md +2 -2
- package/assets/skills-zh/comet-any/SKILL.md +4 -4
- package/assets/skills-zh/comet-any/reference/authoring-subagents.md +1 -1
- package/assets/skills-zh/comet-any/reference/bundle-authoring.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/reference-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/script-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/skill-core-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/skill-reviewer.md +2 -2
- package/assets/skills-zh/comet-any/reference/subagents/workflow-entry-author.md +3 -3
- package/assets/skills-zh/comet-archive/SKILL.md +7 -9
- package/assets/skills-zh/comet-build/SKILL.md +17 -11
- package/assets/skills-zh/comet-classic/SKILL.md +281 -0
- package/assets/skills-zh/comet-design/SKILL.md +1 -1
- package/assets/skills-zh/comet-hotfix/SKILL.md +20 -6
- package/assets/skills-zh/comet-native/SKILL.md +257 -0
- package/assets/skills-zh/comet-native/reference/artifacts.md +206 -0
- package/assets/skills-zh/comet-native/reference/commands.md +118 -0
- package/assets/skills-zh/comet-native/reference/recovery.md +143 -0
- package/assets/skills-zh/comet-open/SKILL.md +4 -4
- package/assets/skills-zh/comet-tweak/SKILL.md +22 -10
- package/assets/skills-zh/comet-verify/SKILL.md +2 -0
- package/dist/app/cli/index.js +59 -13
- package/dist/app/cli/index.js.map +1 -1
- package/dist/app/commands/command-result.d.ts +6 -0
- package/dist/app/commands/command-result.d.ts.map +1 -0
- package/dist/app/commands/command-result.js +4 -0
- package/dist/app/commands/command-result.js.map +1 -0
- package/dist/app/commands/doctor.d.ts +1 -0
- package/dist/app/commands/doctor.d.ts.map +1 -1
- package/dist/app/commands/doctor.js +201 -26
- package/dist/app/commands/doctor.js.map +1 -1
- package/dist/app/commands/eval.d.ts +3 -1
- package/dist/app/commands/eval.d.ts.map +1 -1
- package/dist/app/commands/eval.js +17 -7
- package/dist/app/commands/eval.js.map +1 -1
- package/dist/app/commands/i18n.d.ts +1 -1
- package/dist/app/commands/i18n.d.ts.map +1 -1
- package/dist/app/commands/i18n.js +6 -2
- package/dist/app/commands/i18n.js.map +1 -1
- package/dist/app/commands/init.d.ts +10 -2
- package/dist/app/commands/init.d.ts.map +1 -1
- package/dist/app/commands/init.js +331 -50
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/native.d.ts +2 -0
- package/dist/app/commands/native.d.ts.map +1 -0
- package/dist/app/commands/native.js +10 -0
- package/dist/app/commands/native.js.map +1 -0
- package/dist/app/commands/project-scope-selection.d.ts.map +1 -1
- package/dist/app/commands/project-scope-selection.js +2 -0
- package/dist/app/commands/project-scope-selection.js.map +1 -1
- package/dist/app/commands/resume-probe.d.ts.map +1 -1
- package/dist/app/commands/resume-probe.js +8 -2
- package/dist/app/commands/resume-probe.js.map +1 -1
- package/dist/app/commands/status.d.ts +0 -31
- package/dist/app/commands/status.d.ts.map +1 -1
- package/dist/app/commands/status.js +49 -172
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/update.d.ts +20 -4
- package/dist/app/commands/update.d.ts.map +1 -1
- package/dist/app/commands/update.js +698 -90
- package/dist/app/commands/update.js.map +1 -1
- package/dist/app/commands/workflow.d.ts +6 -0
- package/dist/app/commands/workflow.d.ts.map +1 -0
- package/dist/app/commands/workflow.js +11 -0
- package/dist/app/commands/workflow.js.map +1 -0
- package/dist/config/repository-layout.json +21 -1
- package/dist/domains/comet-classic/classic-archive.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-archive.js +3 -0
- package/dist/domains/comet-classic/classic-archive.js.map +1 -1
- package/dist/domains/comet-classic/classic-branch-binding.d.ts +51 -0
- package/dist/domains/comet-classic/classic-branch-binding.d.ts.map +1 -0
- package/dist/domains/comet-classic/classic-branch-binding.js +107 -0
- package/dist/domains/comet-classic/classic-branch-binding.js.map +1 -0
- package/dist/domains/comet-classic/classic-current-change.d.ts +3 -5
- package/dist/domains/comet-classic/classic-current-change.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-current-change.js +59 -68
- package/dist/domains/comet-classic/classic-current-change.js.map +1 -1
- package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-guard.js +40 -10
- package/dist/domains/comet-classic/classic-guard.js.map +1 -1
- package/dist/domains/comet-classic/classic-hook-guard.d.ts +9 -0
- package/dist/domains/comet-classic/classic-hook-guard.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-hook-guard.js +109 -13
- package/dist/domains/comet-classic/classic-hook-guard.js.map +1 -1
- package/dist/domains/comet-classic/classic-project-config.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-project-config.js +12 -8
- package/dist/domains/comet-classic/classic-project-config.js.map +1 -1
- package/dist/domains/comet-classic/classic-runtime-run.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-runtime-run.js +9 -1
- package/dist/domains/comet-classic/classic-runtime-run.js.map +1 -1
- package/dist/domains/comet-classic/classic-state-command.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-state-command.js +94 -4
- package/dist/domains/comet-classic/classic-state-command.js.map +1 -1
- package/dist/domains/comet-classic/classic-state-events.d.ts +1 -1
- package/dist/domains/comet-classic/classic-state-events.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-state.d.ts +2 -1
- package/dist/domains/comet-classic/classic-state.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-state.js +3 -0
- package/dist/domains/comet-classic/classic-state.js.map +1 -1
- package/dist/domains/comet-classic/classic-transitions.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-transitions.js +1 -0
- package/dist/domains/comet-classic/classic-transitions.js.map +1 -1
- package/dist/domains/comet-classic/classic-validate-command.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-validate-command.js +6 -0
- package/dist/domains/comet-classic/classic-validate-command.js.map +1 -1
- package/dist/domains/comet-entry/current-selection-repair.d.ts +17 -0
- package/dist/domains/comet-entry/current-selection-repair.d.ts.map +1 -0
- package/dist/domains/comet-entry/current-selection-repair.js +19 -0
- package/dist/domains/comet-entry/current-selection-repair.js.map +1 -0
- package/dist/domains/comet-entry/current-selection.d.ts +28 -0
- package/dist/domains/comet-entry/current-selection.d.ts.map +1 -0
- package/dist/domains/comet-entry/current-selection.js +116 -0
- package/dist/domains/comet-entry/current-selection.js.map +1 -0
- package/dist/domains/comet-entry/entry-runtime-entry.d.ts +2 -0
- package/dist/domains/comet-entry/entry-runtime-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/entry-runtime-entry.js +3 -0
- package/dist/domains/comet-entry/entry-runtime-entry.js.map +1 -0
- package/dist/domains/comet-entry/entry-runtime.d.ts +7 -0
- package/dist/domains/comet-entry/entry-runtime.d.ts.map +1 -0
- package/dist/domains/comet-entry/entry-runtime.js +55 -0
- package/dist/domains/comet-entry/entry-runtime.js.map +1 -0
- package/dist/domains/comet-entry/hook-adapter.d.ts +6 -0
- package/dist/domains/comet-entry/hook-adapter.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-adapter.js +202 -0
- package/dist/domains/comet-entry/hook-adapter.js.map +1 -0
- package/dist/domains/comet-entry/hook-router-entry.d.ts +8 -0
- package/dist/domains/comet-entry/hook-router-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-router-entry.js +92 -0
- package/dist/domains/comet-entry/hook-router-entry.js.map +1 -0
- package/dist/domains/comet-entry/hook-router.d.ts +32 -0
- package/dist/domains/comet-entry/hook-router.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-router.js +133 -0
- package/dist/domains/comet-entry/hook-router.js.map +1 -0
- package/dist/domains/comet-entry/hook-types.d.ts +20 -0
- package/dist/domains/comet-entry/hook-types.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-types.js +2 -0
- package/dist/domains/comet-entry/hook-types.js.map +1 -0
- package/dist/domains/comet-entry/init-workflow.d.ts +16 -0
- package/dist/domains/comet-entry/init-workflow.d.ts.map +1 -0
- package/dist/domains/comet-entry/init-workflow.js +103 -0
- package/dist/domains/comet-entry/init-workflow.js.map +1 -0
- package/dist/domains/comet-entry/project-status.d.ts +3 -0
- package/dist/domains/comet-entry/project-status.d.ts.map +1 -0
- package/dist/domains/comet-entry/project-status.js +222 -0
- package/dist/domains/comet-entry/project-status.js.map +1 -0
- package/dist/domains/comet-entry/resolve-entry.d.ts +3 -0
- package/dist/domains/comet-entry/resolve-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/resolve-entry.js +22 -0
- package/dist/domains/comet-entry/resolve-entry.js.map +1 -0
- package/dist/domains/comet-entry/resume-probe.d.ts +34 -0
- package/dist/domains/comet-entry/resume-probe.d.ts.map +1 -0
- package/dist/domains/comet-entry/resume-probe.js +458 -0
- package/dist/domains/comet-entry/resume-probe.js.map +1 -0
- package/dist/domains/comet-entry/types.d.ts +59 -0
- package/dist/domains/comet-entry/types.d.ts.map +1 -0
- package/dist/domains/comet-entry/types.js +2 -0
- package/dist/domains/comet-entry/types.js.map +1 -0
- package/dist/domains/comet-entry/workflow-resolution.d.ts +8 -0
- package/dist/domains/comet-entry/workflow-resolution.d.ts.map +1 -0
- package/dist/domains/comet-entry/workflow-resolution.js +16 -0
- package/dist/domains/comet-entry/workflow-resolution.js.map +1 -0
- package/dist/domains/comet-native/index.d.ts +35 -0
- package/dist/domains/comet-native/index.d.ts.map +1 -0
- package/dist/domains/comet-native/index.js +35 -0
- package/dist/domains/comet-native/index.js.map +1 -0
- package/dist/domains/comet-native/native-acceptance.d.ts +42 -0
- package/dist/domains/comet-native/native-acceptance.d.ts.map +1 -0
- package/dist/domains/comet-native/native-acceptance.js +503 -0
- package/dist/domains/comet-native/native-acceptance.js.map +1 -0
- package/dist/domains/comet-native/native-archive-content.d.ts +26 -0
- package/dist/domains/comet-native/native-archive-content.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-content.js +159 -0
- package/dist/domains/comet-native/native-archive-content.js.map +1 -0
- package/dist/domains/comet-native/native-archive-inspection.d.ts +9 -0
- package/dist/domains/comet-native/native-archive-inspection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-inspection.js +94 -0
- package/dist/domains/comet-native/native-archive-inspection.js.map +1 -0
- package/dist/domains/comet-native/native-archive-preflight.d.ts +52 -0
- package/dist/domains/comet-native/native-archive-preflight.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-preflight.js +214 -0
- package/dist/domains/comet-native/native-archive-preflight.js.map +1 -0
- package/dist/domains/comet-native/native-archive-transaction.d.ts +19 -0
- package/dist/domains/comet-native/native-archive-transaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-transaction.js +1181 -0
- package/dist/domains/comet-native/native-archive-transaction.js.map +1 -0
- package/dist/domains/comet-native/native-archive.d.ts +36 -0
- package/dist/domains/comet-native/native-archive.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive.js +403 -0
- package/dist/domains/comet-native/native-archive.js.map +1 -0
- package/dist/domains/comet-native/native-artifacts.d.ts +10 -0
- package/dist/domains/comet-native/native-artifacts.d.ts.map +1 -0
- package/dist/domains/comet-native/native-artifacts.js +204 -0
- package/dist/domains/comet-native/native-artifacts.js.map +1 -0
- package/dist/domains/comet-native/native-atomic-file.d.ts +10 -0
- package/dist/domains/comet-native/native-atomic-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-atomic-file.js +175 -0
- package/dist/domains/comet-native/native-atomic-file.js.map +1 -0
- package/dist/domains/comet-native/native-bounded-file.d.ts +19 -0
- package/dist/domains/comet-native/native-bounded-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-bounded-file.js +180 -0
- package/dist/domains/comet-native/native-bounded-file.js.map +1 -0
- package/dist/domains/comet-native/native-build-evidence.d.ts +42 -0
- package/dist/domains/comet-native/native-build-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-build-evidence.js +257 -0
- package/dist/domains/comet-native/native-build-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-canonical-hash.d.ts +10 -0
- package/dist/domains/comet-native/native-canonical-hash.d.ts.map +1 -0
- package/dist/domains/comet-native/native-canonical-hash.js +100 -0
- package/dist/domains/comet-native/native-canonical-hash.js.map +1 -0
- package/dist/domains/comet-native/native-change-recovery.d.ts +11 -0
- package/dist/domains/comet-native/native-change-recovery.d.ts.map +1 -0
- package/dist/domains/comet-native/native-change-recovery.js +15 -0
- package/dist/domains/comet-native/native-change-recovery.js.map +1 -0
- package/dist/domains/comet-native/native-change.d.ts +61 -0
- package/dist/domains/comet-native/native-change.d.ts.map +1 -0
- package/dist/domains/comet-native/native-change.js +696 -0
- package/dist/domains/comet-native/native-change.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-model.d.ts +63 -0
- package/dist/domains/comet-native/native-check-receipt-model.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-model.js +347 -0
- package/dist/domains/comet-native/native-check-receipt-model.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-storage.d.ts +10 -0
- package/dist/domains/comet-native/native-check-receipt-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-storage.js +196 -0
- package/dist/domains/comet-native/native-check-receipt-storage.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt.d.ts +19 -0
- package/dist/domains/comet-native/native-check-receipt.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt.js +446 -0
- package/dist/domains/comet-native/native-check-receipt.js.map +1 -0
- package/dist/domains/comet-native/native-check.d.ts +18 -0
- package/dist/domains/comet-native/native-check.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check.js +29 -0
- package/dist/domains/comet-native/native-check.js.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-journal.d.ts +13 -0
- package/dist/domains/comet-native/native-checkpoint-journal.d.ts.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-journal.js +53 -0
- package/dist/domains/comet-native/native-checkpoint-journal.js.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-storage.d.ts +43 -0
- package/dist/domains/comet-native/native-checkpoint-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-storage.js +487 -0
- package/dist/domains/comet-native/native-checkpoint-storage.js.map +1 -0
- package/dist/domains/comet-native/native-cli-entry.d.ts +2 -0
- package/dist/domains/comet-native/native-cli-entry.d.ts.map +1 -0
- package/dist/domains/comet-native/native-cli-entry.js +18 -0
- package/dist/domains/comet-native/native-cli-entry.js.map +1 -0
- package/dist/domains/comet-native/native-cli.d.ts +7 -0
- package/dist/domains/comet-native/native-cli.d.ts.map +1 -0
- package/dist/domains/comet-native/native-cli.js +642 -0
- package/dist/domains/comet-native/native-cli.js.map +1 -0
- package/dist/domains/comet-native/native-config.d.ts +15 -0
- package/dist/domains/comet-native/native-config.d.ts.map +1 -0
- package/dist/domains/comet-native/native-config.js +281 -0
- package/dist/domains/comet-native/native-config.js.map +1 -0
- package/dist/domains/comet-native/native-conflict-inspection.d.ts +17 -0
- package/dist/domains/comet-native/native-conflict-inspection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-conflict-inspection.js +90 -0
- package/dist/domains/comet-native/native-conflict-inspection.js.map +1 -0
- package/dist/domains/comet-native/native-conflict-radar.d.ts +75 -0
- package/dist/domains/comet-native/native-conflict-radar.d.ts.map +1 -0
- package/dist/domains/comet-native/native-conflict-radar.js +326 -0
- package/dist/domains/comet-native/native-conflict-radar.js.map +1 -0
- package/dist/domains/comet-native/native-continuation.d.ts +9 -0
- package/dist/domains/comet-native/native-continuation.d.ts.map +1 -0
- package/dist/domains/comet-native/native-continuation.js +146 -0
- package/dist/domains/comet-native/native-continuation.js.map +1 -0
- package/dist/domains/comet-native/native-contract-files.d.ts +24 -0
- package/dist/domains/comet-native/native-contract-files.d.ts.map +1 -0
- package/dist/domains/comet-native/native-contract-files.js +66 -0
- package/dist/domains/comet-native/native-contract-files.js.map +1 -0
- package/dist/domains/comet-native/native-contract.d.ts +41 -0
- package/dist/domains/comet-native/native-contract.d.ts.map +1 -0
- package/dist/domains/comet-native/native-contract.js +141 -0
- package/dist/domains/comet-native/native-contract.js.map +1 -0
- package/dist/domains/comet-native/native-diagnostics.d.ts +18 -0
- package/dist/domains/comet-native/native-diagnostics.d.ts.map +1 -0
- package/dist/domains/comet-native/native-diagnostics.js +522 -0
- package/dist/domains/comet-native/native-diagnostics.js.map +1 -0
- package/dist/domains/comet-native/native-doctor.d.ts +12 -0
- package/dist/domains/comet-native/native-doctor.d.ts.map +1 -0
- package/dist/domains/comet-native/native-doctor.js +768 -0
- package/dist/domains/comet-native/native-doctor.js.map +1 -0
- package/dist/domains/comet-native/native-evidence-retention.d.ts +37 -0
- package/dist/domains/comet-native/native-evidence-retention.d.ts.map +1 -0
- package/dist/domains/comet-native/native-evidence-retention.js +885 -0
- package/dist/domains/comet-native/native-evidence-retention.js.map +1 -0
- package/dist/domains/comet-native/native-evidence-storage.d.ts +41 -0
- package/dist/domains/comet-native/native-evidence-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-evidence-storage.js +351 -0
- package/dist/domains/comet-native/native-evidence-storage.js.map +1 -0
- package/dist/domains/comet-native/native-findings.d.ts +8 -0
- package/dist/domains/comet-native/native-findings.d.ts.map +1 -0
- package/dist/domains/comet-native/native-findings.js +238 -0
- package/dist/domains/comet-native/native-findings.js.map +1 -0
- package/dist/domains/comet-native/native-guards.d.ts +7 -0
- package/dist/domains/comet-native/native-guards.d.ts.map +1 -0
- package/dist/domains/comet-native/native-guards.js +126 -0
- package/dist/domains/comet-native/native-guards.js.map +1 -0
- package/dist/domains/comet-native/native-hash.d.ts +3 -0
- package/dist/domains/comet-native/native-hash.d.ts.map +1 -0
- package/dist/domains/comet-native/native-hash.js +12 -0
- package/dist/domains/comet-native/native-hash.js.map +1 -0
- package/dist/domains/comet-native/native-hook-guard.d.ts +17 -0
- package/dist/domains/comet-native/native-hook-guard.d.ts.map +1 -0
- package/dist/domains/comet-native/native-hook-guard.js +154 -0
- package/dist/domains/comet-native/native-hook-guard.js.map +1 -0
- package/dist/domains/comet-native/native-lock.d.ts +47 -0
- package/dist/domains/comet-native/native-lock.d.ts.map +1 -0
- package/dist/domains/comet-native/native-lock.js +395 -0
- package/dist/domains/comet-native/native-lock.js.map +1 -0
- package/dist/domains/comet-native/native-mutation-lock.d.ts +5 -0
- package/dist/domains/comet-native/native-mutation-lock.d.ts.map +1 -0
- package/dist/domains/comet-native/native-mutation-lock.js +66 -0
- package/dist/domains/comet-native/native-mutation-lock.js.map +1 -0
- package/dist/domains/comet-native/native-paths.d.ts +10 -0
- package/dist/domains/comet-native/native-paths.d.ts.map +1 -0
- package/dist/domains/comet-native/native-paths.js +171 -0
- package/dist/domains/comet-native/native-paths.js.map +1 -0
- package/dist/domains/comet-native/native-progress-checkpoint.d.ts +13 -0
- package/dist/domains/comet-native/native-progress-checkpoint.d.ts.map +1 -0
- package/dist/domains/comet-native/native-progress-checkpoint.js +104 -0
- package/dist/domains/comet-native/native-progress-checkpoint.js.map +1 -0
- package/dist/domains/comet-native/native-protected-file.d.ts +113 -0
- package/dist/domains/comet-native/native-protected-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-protected-file.js +509 -0
- package/dist/domains/comet-native/native-protected-file.js.map +1 -0
- package/dist/domains/comet-native/native-redaction.d.ts +2 -0
- package/dist/domains/comet-native/native-redaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-redaction.js +18 -0
- package/dist/domains/comet-native/native-redaction.js.map +1 -0
- package/dist/domains/comet-native/native-repair-integration.d.ts +42 -0
- package/dist/domains/comet-native/native-repair-integration.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-integration.js +184 -0
- package/dist/domains/comet-native/native-repair-integration.js.map +1 -0
- package/dist/domains/comet-native/native-repair-runtime.d.ts +73 -0
- package/dist/domains/comet-native/native-repair-runtime.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-runtime.js +509 -0
- package/dist/domains/comet-native/native-repair-runtime.js.map +1 -0
- package/dist/domains/comet-native/native-repair-stagnation.d.ts +85 -0
- package/dist/domains/comet-native/native-repair-stagnation.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-stagnation.js +256 -0
- package/dist/domains/comet-native/native-repair-stagnation.js.map +1 -0
- package/dist/domains/comet-native/native-resume-view.d.ts +14 -0
- package/dist/domains/comet-native/native-resume-view.d.ts.map +1 -0
- package/dist/domains/comet-native/native-resume-view.js +105 -0
- package/dist/domains/comet-native/native-resume-view.js.map +1 -0
- package/dist/domains/comet-native/native-revision.d.ts +20 -0
- package/dist/domains/comet-native/native-revision.d.ts.map +1 -0
- package/dist/domains/comet-native/native-revision.js +32 -0
- package/dist/domains/comet-native/native-revision.js.map +1 -0
- package/dist/domains/comet-native/native-root-move.d.ts +20 -0
- package/dist/domains/comet-native/native-root-move.d.ts.map +1 -0
- package/dist/domains/comet-native/native-root-move.js +812 -0
- package/dist/domains/comet-native/native-root-move.js.map +1 -0
- package/dist/domains/comet-native/native-run-consistency.d.ts +3 -0
- package/dist/domains/comet-native/native-run-consistency.d.ts.map +1 -0
- package/dist/domains/comet-native/native-run-consistency.js +136 -0
- package/dist/domains/comet-native/native-run-consistency.js.map +1 -0
- package/dist/domains/comet-native/native-run-store.d.ts +41 -0
- package/dist/domains/comet-native/native-run-store.d.ts.map +1 -0
- package/dist/domains/comet-native/native-run-store.js +451 -0
- package/dist/domains/comet-native/native-run-store.js.map +1 -0
- package/dist/domains/comet-native/native-runtime-package.d.ts +16 -0
- package/dist/domains/comet-native/native-runtime-package.d.ts.map +1 -0
- package/dist/domains/comet-native/native-runtime-package.js +72 -0
- package/dist/domains/comet-native/native-runtime-package.js.map +1 -0
- package/dist/domains/comet-native/native-schema-migration.d.ts +11 -0
- package/dist/domains/comet-native/native-schema-migration.d.ts.map +1 -0
- package/dist/domains/comet-native/native-schema-migration.js +899 -0
- package/dist/domains/comet-native/native-schema-migration.js.map +1 -0
- package/dist/domains/comet-native/native-selection.d.ts +12 -0
- package/dist/domains/comet-native/native-selection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-selection.js +52 -0
- package/dist/domains/comet-native/native-selection.js.map +1 -0
- package/dist/domains/comet-native/native-sensitive-paths.d.ts +7 -0
- package/dist/domains/comet-native/native-sensitive-paths.d.ts.map +1 -0
- package/dist/domains/comet-native/native-sensitive-paths.js +69 -0
- package/dist/domains/comet-native/native-sensitive-paths.js.map +1 -0
- package/dist/domains/comet-native/native-snapshot.d.ts +74 -0
- package/dist/domains/comet-native/native-snapshot.d.ts.map +1 -0
- package/dist/domains/comet-native/native-snapshot.js +2308 -0
- package/dist/domains/comet-native/native-snapshot.js.map +1 -0
- package/dist/domains/comet-native/native-specs.d.ts +12 -0
- package/dist/domains/comet-native/native-specs.d.ts.map +1 -0
- package/dist/domains/comet-native/native-specs.js +270 -0
- package/dist/domains/comet-native/native-specs.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory-limits.d.ts +7 -0
- package/dist/domains/comet-native/native-trajectory-limits.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory-limits.js +13 -0
- package/dist/domains/comet-native/native-trajectory-limits.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory-recovery.d.ts +37 -0
- package/dist/domains/comet-native/native-trajectory-recovery.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory-recovery.js +133 -0
- package/dist/domains/comet-native/native-trajectory-recovery.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory.d.ts +16 -0
- package/dist/domains/comet-native/native-trajectory.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory.js +27 -0
- package/dist/domains/comet-native/native-trajectory.js.map +1 -0
- package/dist/domains/comet-native/native-transaction.d.ts +45 -0
- package/dist/domains/comet-native/native-transaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transaction.js +846 -0
- package/dist/domains/comet-native/native-transaction.js.map +1 -0
- package/dist/domains/comet-native/native-transition-evidence.d.ts +4 -0
- package/dist/domains/comet-native/native-transition-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transition-evidence.js +20 -0
- package/dist/domains/comet-native/native-transition-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-transition-journal.d.ts +30 -0
- package/dist/domains/comet-native/native-transition-journal.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transition-journal.js +819 -0
- package/dist/domains/comet-native/native-transition-journal.js.map +1 -0
- package/dist/domains/comet-native/native-transitions.d.ts +13 -0
- package/dist/domains/comet-native/native-transitions.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transitions.js +632 -0
- package/dist/domains/comet-native/native-transitions.js.map +1 -0
- package/dist/domains/comet-native/native-types.d.ts +547 -0
- package/dist/domains/comet-native/native-types.d.ts.map +1 -0
- package/dist/domains/comet-native/native-types.js +8 -0
- package/dist/domains/comet-native/native-types.js.map +1 -0
- package/dist/domains/comet-native/native-verification-evidence.d.ts +86 -0
- package/dist/domains/comet-native/native-verification-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-evidence.js +480 -0
- package/dist/domains/comet-native/native-verification-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-verification-runtime.d.ts +58 -0
- package/dist/domains/comet-native/native-verification-runtime.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-runtime.js +321 -0
- package/dist/domains/comet-native/native-verification-runtime.js.map +1 -0
- package/dist/domains/comet-native/native-verification-scope.d.ts +117 -0
- package/dist/domains/comet-native/native-verification-scope.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-scope.js +1040 -0
- package/dist/domains/comet-native/native-verification-scope.js.map +1 -0
- package/dist/domains/comet-native/native-workspace.d.ts +46 -0
- package/dist/domains/comet-native/native-workspace.d.ts.map +1 -0
- package/dist/domains/comet-native/native-workspace.js +276 -0
- package/dist/domains/comet-native/native-workspace.js.map +1 -0
- package/dist/domains/dashboard/collector.d.ts.map +1 -1
- package/dist/domains/dashboard/collector.js +9 -1
- package/dist/domains/dashboard/collector.js.map +1 -1
- package/dist/domains/dashboard/native-adapter.d.ts +157 -0
- package/dist/domains/dashboard/native-adapter.d.ts.map +1 -0
- package/dist/domains/dashboard/native-adapter.js +302 -0
- package/dist/domains/dashboard/native-adapter.js.map +1 -0
- package/dist/domains/dashboard/native-collector.d.ts +6 -0
- package/dist/domains/dashboard/native-collector.d.ts.map +1 -0
- package/dist/domains/dashboard/native-collector.js +285 -0
- package/dist/domains/dashboard/native-collector.js.map +1 -0
- package/dist/domains/dashboard/types.d.ts +5 -0
- package/dist/domains/dashboard/types.d.ts.map +1 -1
- package/dist/domains/dashboard/web/assets/{arc-TGVUG2WN.js → arc-CxdiLJ50.js} +1 -1
- package/dist/domains/dashboard/web/assets/{architectureDiagram-3BPJPVTR-ASHmiHoP.js → architectureDiagram-3BPJPVTR-D5YCQu4e.js} +1 -1
- package/dist/domains/dashboard/web/assets/{blockDiagram-GPEHLZMM-CwASxBKe.js → blockDiagram-GPEHLZMM-8NfdCOQ8.js} +1 -1
- package/dist/domains/dashboard/web/assets/{c4Diagram-AAUBKEIU-BU8z_WNk.js → c4Diagram-AAUBKEIU-B3cFnNT7.js} +1 -1
- package/dist/domains/dashboard/web/assets/channel-B6AFly29.js +1 -0
- package/dist/domains/dashboard/web/assets/{chunk-2J33WTMH-CBGlUx4_.js → chunk-2J33WTMH-CBNfW-Dr.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-4BX2VUAB-CS-iGcFz.js → chunk-4BX2VUAB-vWyemRBr.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-55IACEB6-BUtCVJat.js → chunk-55IACEB6-H6haOo2C.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-727SXJPM-C94tj_pf.js → chunk-727SXJPM-D02UjGND.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-AQP2D5EJ-BFOKcpdG.js → chunk-AQP2D5EJ-wKsbOw_T.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-FMBD7UC4-Dmx8B-st.js → chunk-FMBD7UC4-eYFEZimP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-ND2GUHAM-DYV00CNn.js → chunk-ND2GUHAM-fMaIDDI2.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-QZHKN3VN-DMJJyQnw.js → chunk-QZHKN3VN-C9rhF6Hm.js} +1 -1
- package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-BcnrxOTt.js +1 -0
- package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-BcnrxOTt.js +1 -0
- package/dist/domains/dashboard/web/assets/{cose-bilkent-S5V4N54A-P4nE2rea.js → cose-bilkent-S5V4N54A-CbaShPub.js} +1 -1
- package/dist/domains/dashboard/web/assets/{cynefin-VYW2F7L2-C-R1HXDv.js → cynefin-VYW2F7L2-DN4emAQv.js} +1 -1
- package/dist/domains/dashboard/web/assets/{dagre-BM42HDAG-BH8d-C9z.js → dagre-BM42HDAG-BpSzbk_V.js} +1 -1
- package/dist/domains/dashboard/web/assets/demo-BuVau32v.js +25 -0
- package/dist/domains/dashboard/web/assets/{diagram-2AECGRRQ-DpXTgQIH.js → diagram-2AECGRRQ-CfXwGGpQ.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-5GNKFQAL-DSiFJzSw.js → diagram-5GNKFQAL-DMp0Zmot.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-KO2AKTUF-DULMkben.js → diagram-KO2AKTUF-C7ZvofsM.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-LMA3HP47-Pi8m_NO9.js → diagram-LMA3HP47-BjmxFnap.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-OG6HWLK6-BSe6bCWm.js → diagram-OG6HWLK6-DFBG1Iqy.js} +1 -1
- package/dist/domains/dashboard/web/assets/{erDiagram-TEJ5UH35-zb-FEcbq.js → erDiagram-TEJ5UH35-MpNT7dzt.js} +1 -1
- package/dist/domains/dashboard/web/assets/{flowDiagram-I6XJVG4X-Dr-Gk0z2.js → flowDiagram-I6XJVG4X-_1wAR6c1.js} +1 -1
- package/dist/domains/dashboard/web/assets/{ganttDiagram-6RSMTGT7-qs6Zb2A6.js → ganttDiagram-6RSMTGT7-DJKjDeWl.js} +1 -1
- package/dist/domains/dashboard/web/assets/{gitGraphDiagram-PVQCEYII-BQ314orT.js → gitGraphDiagram-PVQCEYII-BL7yUEn-.js} +1 -1
- package/dist/domains/dashboard/web/assets/index-CjE9mHGb.js +24 -0
- package/dist/domains/dashboard/web/assets/index-D-AGxvI4.css +1 -0
- package/dist/domains/dashboard/web/assets/{infoDiagram-5YYISTIA-O0bQp98A.js → infoDiagram-5YYISTIA-Bt5fqrOd.js} +1 -1
- package/dist/domains/dashboard/web/assets/{ishikawaDiagram-YF4QCWOH-BPC7wbKh.js → ishikawaDiagram-YF4QCWOH-COCMcjBM.js} +1 -1
- package/dist/domains/dashboard/web/assets/{journeyDiagram-JHISSGLW-ohViOd4b.js → journeyDiagram-JHISSGLW-DGcpcWny.js} +1 -1
- package/dist/domains/dashboard/web/assets/{kanban-definition-UN3LZRKU-CHleNdbG.js → kanban-definition-UN3LZRKU-QSBNsWMP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{linear-CyqiW--Q.js → linear-9uyeeBZf.js} +1 -1
- package/dist/domains/dashboard/web/assets/{mermaid.core-qS9XvtaK.js → mermaid.core-CkNdB471.js} +4 -4
- package/dist/domains/dashboard/web/assets/{mindmap-definition-RKZ34NQL-oaGkqO9l.js → mindmap-definition-RKZ34NQL-CiNxI0gP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{pieDiagram-4H26LBE5-CPcB-AFh.js → pieDiagram-4H26LBE5-BLJ6QnRO.js} +1 -1
- package/dist/domains/dashboard/web/assets/{quadrantDiagram-W4KKPZXB-LFy52Qtj.js → quadrantDiagram-W4KKPZXB-CflW-eFH.js} +1 -1
- package/dist/domains/dashboard/web/assets/{requirementDiagram-4Y6WPE33-BdjeaYP_.js → requirementDiagram-4Y6WPE33-B9HLmRWH.js} +1 -1
- package/dist/domains/dashboard/web/assets/{sankeyDiagram-5OEKKPKP-DDJ4styL.js → sankeyDiagram-5OEKKPKP-6xnco5k5.js} +1 -1
- package/dist/domains/dashboard/web/assets/{sequenceDiagram-3UESZ5HK-BL5bFNoz.js → sequenceDiagram-3UESZ5HK-Dp1rujNZ.js} +1 -1
- package/dist/domains/dashboard/web/assets/{stateDiagram-AJRCARHV-BNUfikui.js → stateDiagram-AJRCARHV-C1Xc90ek.js} +1 -1
- package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-p-qmzXyE.js +1 -0
- package/dist/domains/dashboard/web/assets/{timeline-definition-PNZ67QCA--ps2uu6L.js → timeline-definition-PNZ67QCA-g9s-m5Z4.js} +1 -1
- package/dist/domains/dashboard/web/assets/{vennDiagram-CIIHVFJN-C2q8q26c.js → vennDiagram-CIIHVFJN-rkEyhyCc.js} +1 -1
- package/dist/domains/dashboard/web/assets/{wardleyDiagram-YWT4CUSO-BUH9gXqd.js → wardleyDiagram-YWT4CUSO-CJLrWGXc.js} +1 -1
- package/dist/domains/dashboard/web/assets/{xychartDiagram-2RQKCTM6-B-DielEy.js → xychartDiagram-2RQKCTM6-BxJvPNqo.js} +1 -1
- package/dist/domains/dashboard/web/index.html +2 -2
- package/dist/domains/engine/storage-layout.d.ts +14 -0
- package/dist/domains/engine/storage-layout.d.ts.map +1 -0
- package/dist/domains/engine/storage-layout.js +32 -0
- package/dist/domains/engine/storage-layout.js.map +1 -0
- package/dist/domains/engine/storage-run.d.ts +9 -0
- package/dist/domains/engine/storage-run.d.ts.map +1 -0
- package/dist/domains/engine/storage-run.js +116 -0
- package/dist/domains/engine/storage-run.js.map +1 -0
- package/dist/domains/factory/package.d.ts.map +1 -1
- package/dist/domains/factory/package.js +5 -3
- package/dist/domains/factory/package.js.map +1 -1
- package/dist/domains/integrations/openspec.d.ts.map +1 -1
- package/dist/domains/integrations/openspec.js +8 -6
- package/dist/domains/integrations/openspec.js.map +1 -1
- package/dist/domains/skill/find.d.ts.map +1 -1
- package/dist/domains/skill/find.js +7 -1
- package/dist/domains/skill/find.js.map +1 -1
- package/dist/domains/skill/platform-inspect.d.ts +6 -2
- package/dist/domains/skill/platform-inspect.d.ts.map +1 -1
- package/dist/domains/skill/platform-inspect.js +52 -8
- package/dist/domains/skill/platform-inspect.js.map +1 -1
- package/dist/domains/skill/platform-install.d.ts +18 -7
- package/dist/domains/skill/platform-install.d.ts.map +1 -1
- package/dist/domains/skill/platform-install.js +338 -71
- package/dist/domains/skill/platform-install.js.map +1 -1
- package/dist/domains/skill/project-instructions.d.ts.map +1 -1
- package/dist/domains/skill/project-instructions.js +12 -6
- package/dist/domains/skill/project-instructions.js.map +1 -1
- package/dist/domains/skill/uninstall.d.ts.map +1 -1
- package/dist/domains/skill/uninstall.js +15 -3
- package/dist/domains/skill/uninstall.js.map +1 -1
- package/dist/domains/workflow-contract/builtins.d.ts +6 -0
- package/dist/domains/workflow-contract/builtins.d.ts.map +1 -1
- package/dist/domains/workflow-contract/builtins.js +137 -0
- package/dist/domains/workflow-contract/builtins.js.map +1 -1
- package/dist/domains/workflow-contract/index.d.ts +3 -1
- package/dist/domains/workflow-contract/index.d.ts.map +1 -1
- package/dist/domains/workflow-contract/index.js +2 -1
- package/dist/domains/workflow-contract/index.js.map +1 -1
- package/dist/domains/workflow-contract/normalize.d.ts.map +1 -1
- package/dist/domains/workflow-contract/normalize.js +28 -10
- package/dist/domains/workflow-contract/normalize.js.map +1 -1
- package/dist/domains/workflow-contract/project-config.d.ts +7 -0
- package/dist/domains/workflow-contract/project-config.d.ts.map +1 -0
- package/dist/domains/workflow-contract/project-config.js +110 -0
- package/dist/domains/workflow-contract/project-config.js.map +1 -0
- package/dist/domains/workflow-contract/types.d.ts +4 -2
- package/dist/domains/workflow-contract/types.d.ts.map +1 -1
- package/dist/domains/workflow-contract/validation.d.ts.map +1 -1
- package/dist/domains/workflow-contract/validation.js +14 -5
- package/dist/domains/workflow-contract/validation.js.map +1 -1
- package/dist/platform/install/detect.d.ts +3 -1
- package/dist/platform/install/detect.d.ts.map +1 -1
- package/dist/platform/install/detect.js +4 -1
- package/dist/platform/install/detect.js.map +1 -1
- package/dist/platform/install/project-registry.js +2 -2
- package/dist/platform/install/project-registry.js.map +1 -1
- package/dist/platform/paths/repository-layout.d.ts +16 -0
- package/dist/platform/paths/repository-layout.d.ts.map +1 -1
- package/dist/platform/paths/repository-layout.js.map +1 -1
- package/eval/local/README.md +50 -0
- package/eval/local/scripts/compare_baselines.py +127 -1
- package/eval/local/scripts/regression_check.py +3 -4
- package/eval/local/tasks/comet-native-clarification/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-clarification/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-clarification/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-clarification/instruction.md +7 -0
- package/eval/local/tasks/comet-native-clarification/task.toml +40 -0
- package/eval/local/tasks/comet-native-clarification/validation/test_native_clarification.py +193 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-clarification-modes/instruction.md +13 -0
- package/eval/local/tasks/comet-native-clarification-modes/task.toml +39 -0
- package/eval/local/tasks/comet-native-clarification-modes/validation/test_native_clarification_modes.py +235 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/.comet/config.yaml +6 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/Dockerfile +28 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/brief.md +17 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/comet-state.yaml +12 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/runtime/transition.json +69 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/specs/character-counting/spec.md +3 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/test_wordcount.py +20 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/wordcount.py +27 -0
- package/eval/local/tasks/comet-native-interrupted-transition/instruction.md +7 -0
- package/eval/local/tasks/comet-native-interrupted-transition/task.toml +35 -0
- package/eval/local/tasks/comet-native-interrupted-transition/validation/test_native_interrupted_transition.py +63 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/Dockerfile +26 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/PRODUCT_RULES.md +3 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/test_wordcount.py +20 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/wordcount.py +27 -0
- package/eval/local/tasks/comet-native-repository-fact/instruction.md +7 -0
- package/eval/local/tasks/comet-native-repository-fact/task.toml +35 -0
- package/eval/local/tasks/comet-native-repository-fact/validation/test_native_repository_fact.py +53 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/instruction.md +9 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/task.toml +40 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/validation/test_native_wave_b_decision_resume.py +208 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/instruction.md +11 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/task.toml +36 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/validation/test_native_wave_c_verification_integrity.py +344 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/instruction.md +11 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/task.toml +37 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/validation/test_native_wave_d_stagnation_stop.py +284 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/.include-trusted-native-runtime +1 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/instruction.md +9 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/task.toml +37 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/validation/test_native_wave_e_parallel_safety.py +309 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/.include-current-comet-cli +1 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/Dockerfile +31 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet-package.json +18 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet.sh +14 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/instruction.md +7 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/task.toml +36 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/validation/test_native_wave_f_dashboard_readonly.py +469 -0
- package/eval/local/tasks/comet-native-workflow/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-workflow/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-workflow/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-workflow/instruction.md +14 -0
- package/eval/local/tasks/comet-native-workflow/task.toml +36 -0
- package/eval/local/tasks/comet-native-workflow/validation/test_native_workflow.py +149 -0
- package/eval/local/tasks/index.yaml +61 -0
- package/eval/local/tests/conftest.py +407 -22
- package/eval/local/tests/scaffold/test_aligned_comparison.py +1012 -0
- package/eval/local/tests/scaffold/test_conftest_helpers.py +187 -7
- package/eval/local/tests/scaffold/test_logging.py +135 -1
- package/eval/local/tests/scaffold/test_manifests.py +2 -0
- package/eval/local/tests/scaffold/test_native_aligned_eval.py +346 -0
- package/eval/local/tests/scaffold/test_native_wave_evaluations.py +1889 -0
- package/eval/local/tests/scaffold/test_profiles.py +33 -0
- package/eval/local/tests/scaffold/test_sample_quality.py +57 -0
- package/eval/local/tests/scaffold/test_tasks.py +377 -1
- package/eval/local/tests/scaffold/test_treatments.py +59 -13
- package/eval/local/tests/scaffold/test_utils.py +277 -4
- package/eval/local/tests/tasks/__init__.py +1 -0
- package/eval/local/tests/tasks/test_tasks.py +104 -78
- package/eval/local/tests/tasks/test_validation_scripts.py +37 -0
- package/eval/local/treatments/comet/comet_native_phase1.yaml +66 -0
- package/eval/scaffold/python/aligned_comparison.py +1631 -0
- package/eval/scaffold/python/generic_llm_judge.py +3 -1
- package/eval/scaffold/python/llm_judge.py +0 -3
- package/eval/scaffold/python/logging.py +115 -16
- package/eval/scaffold/python/manifests.py +2 -0
- package/eval/scaffold/python/native_eval.py +138 -0
- package/eval/scaffold/python/pass_at_k.py +0 -1
- package/eval/scaffold/python/report_outputs.py +226 -44
- package/eval/scaffold/python/sample_quality.py +45 -2
- package/eval/scaffold/python/tasks.py +11 -0
- package/eval/scaffold/python/utils.py +108 -20
- package/eval/scaffold/python/validation/__init__.py +15 -5
- package/eval/scaffold/python/validation/comet_workflow.py +10 -5
- package/eval/scaffold/python/validation/generic_rubric.py +1 -2
- package/eval/scaffold/python/validation/native_wave.py +2154 -0
- package/eval/scaffold/python/validation/native_workflow.py +252 -0
- package/eval/scaffold/python/validation/rubric.py +0 -2
- package/eval/scaffold/shell/completion-point.sh +18 -0
- package/eval/scaffold/shell/decision-point.sh +35 -0
- package/eval/scaffold/shell/docker.sh +150 -9
- package/eval/scaffold/shell/run-claude-loop.sh +57 -27
- package/package.json +19 -5
- package/dist/domains/dashboard/web/assets/channel-kp6Ng2JJ.js +0 -1
- package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-yBDjgMY_.js +0 -1
- package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-yBDjgMY_.js +0 -1
- package/dist/domains/dashboard/web/assets/demo-DQyfozbi.js +0 -1
- package/dist/domains/dashboard/web/assets/index-BLAfkNTu.css +0 -1
- package/dist/domains/dashboard/web/assets/index-DtLUOcAW.js +0 -24
- package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-DGrsmWts.js +0 -1
- package/eval/.env.example +0 -52
- package/eval/langsmith/.env.example +0 -16
|
@@ -126,17 +126,17 @@ var require_visit = __commonJS({
|
|
|
126
126
|
visit.BREAK = BREAK;
|
|
127
127
|
visit.SKIP = SKIP;
|
|
128
128
|
visit.REMOVE = REMOVE;
|
|
129
|
-
function visit_(key, node, visitor,
|
|
130
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
129
|
+
function visit_(key, node, visitor, path24) {
|
|
130
|
+
const ctrl = callVisitor(key, node, visitor, path24);
|
|
131
131
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
132
|
-
replaceNode(key,
|
|
133
|
-
return visit_(key, ctrl, visitor,
|
|
132
|
+
replaceNode(key, path24, ctrl);
|
|
133
|
+
return visit_(key, ctrl, visitor, path24);
|
|
134
134
|
}
|
|
135
135
|
if (typeof ctrl !== "symbol") {
|
|
136
136
|
if (identity.isCollection(node)) {
|
|
137
|
-
|
|
137
|
+
path24 = Object.freeze(path24.concat(node));
|
|
138
138
|
for (let i = 0; i < node.items.length; ++i) {
|
|
139
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
139
|
+
const ci = visit_(i, node.items[i], visitor, path24);
|
|
140
140
|
if (typeof ci === "number")
|
|
141
141
|
i = ci - 1;
|
|
142
142
|
else if (ci === BREAK)
|
|
@@ -147,13 +147,13 @@ var require_visit = __commonJS({
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
} else if (identity.isPair(node)) {
|
|
150
|
-
|
|
151
|
-
const ck = visit_("key", node.key, visitor,
|
|
150
|
+
path24 = Object.freeze(path24.concat(node));
|
|
151
|
+
const ck = visit_("key", node.key, visitor, path24);
|
|
152
152
|
if (ck === BREAK)
|
|
153
153
|
return BREAK;
|
|
154
154
|
else if (ck === REMOVE)
|
|
155
155
|
node.key = null;
|
|
156
|
-
const cv = visit_("value", node.value, visitor,
|
|
156
|
+
const cv = visit_("value", node.value, visitor, path24);
|
|
157
157
|
if (cv === BREAK)
|
|
158
158
|
return BREAK;
|
|
159
159
|
else if (cv === REMOVE)
|
|
@@ -174,17 +174,17 @@ var require_visit = __commonJS({
|
|
|
174
174
|
visitAsync.BREAK = BREAK;
|
|
175
175
|
visitAsync.SKIP = SKIP;
|
|
176
176
|
visitAsync.REMOVE = REMOVE;
|
|
177
|
-
async function visitAsync_(key, node, visitor,
|
|
178
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
177
|
+
async function visitAsync_(key, node, visitor, path24) {
|
|
178
|
+
const ctrl = await callVisitor(key, node, visitor, path24);
|
|
179
179
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
180
|
-
replaceNode(key,
|
|
181
|
-
return visitAsync_(key, ctrl, visitor,
|
|
180
|
+
replaceNode(key, path24, ctrl);
|
|
181
|
+
return visitAsync_(key, ctrl, visitor, path24);
|
|
182
182
|
}
|
|
183
183
|
if (typeof ctrl !== "symbol") {
|
|
184
184
|
if (identity.isCollection(node)) {
|
|
185
|
-
|
|
185
|
+
path24 = Object.freeze(path24.concat(node));
|
|
186
186
|
for (let i = 0; i < node.items.length; ++i) {
|
|
187
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
187
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path24);
|
|
188
188
|
if (typeof ci === "number")
|
|
189
189
|
i = ci - 1;
|
|
190
190
|
else if (ci === BREAK)
|
|
@@ -195,13 +195,13 @@ var require_visit = __commonJS({
|
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
} else if (identity.isPair(node)) {
|
|
198
|
-
|
|
199
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
198
|
+
path24 = Object.freeze(path24.concat(node));
|
|
199
|
+
const ck = await visitAsync_("key", node.key, visitor, path24);
|
|
200
200
|
if (ck === BREAK)
|
|
201
201
|
return BREAK;
|
|
202
202
|
else if (ck === REMOVE)
|
|
203
203
|
node.key = null;
|
|
204
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
204
|
+
const cv = await visitAsync_("value", node.value, visitor, path24);
|
|
205
205
|
if (cv === BREAK)
|
|
206
206
|
return BREAK;
|
|
207
207
|
else if (cv === REMOVE)
|
|
@@ -228,23 +228,23 @@ var require_visit = __commonJS({
|
|
|
228
228
|
}
|
|
229
229
|
return visitor;
|
|
230
230
|
}
|
|
231
|
-
function callVisitor(key, node, visitor,
|
|
231
|
+
function callVisitor(key, node, visitor, path24) {
|
|
232
232
|
if (typeof visitor === "function")
|
|
233
|
-
return visitor(key, node,
|
|
233
|
+
return visitor(key, node, path24);
|
|
234
234
|
if (identity.isMap(node))
|
|
235
|
-
return visitor.Map?.(key, node,
|
|
235
|
+
return visitor.Map?.(key, node, path24);
|
|
236
236
|
if (identity.isSeq(node))
|
|
237
|
-
return visitor.Seq?.(key, node,
|
|
237
|
+
return visitor.Seq?.(key, node, path24);
|
|
238
238
|
if (identity.isPair(node))
|
|
239
|
-
return visitor.Pair?.(key, node,
|
|
239
|
+
return visitor.Pair?.(key, node, path24);
|
|
240
240
|
if (identity.isScalar(node))
|
|
241
|
-
return visitor.Scalar?.(key, node,
|
|
241
|
+
return visitor.Scalar?.(key, node, path24);
|
|
242
242
|
if (identity.isAlias(node))
|
|
243
|
-
return visitor.Alias?.(key, node,
|
|
243
|
+
return visitor.Alias?.(key, node, path24);
|
|
244
244
|
return void 0;
|
|
245
245
|
}
|
|
246
|
-
function replaceNode(key,
|
|
247
|
-
const parent =
|
|
246
|
+
function replaceNode(key, path24, node) {
|
|
247
|
+
const parent = path24[path24.length - 1];
|
|
248
248
|
if (identity.isCollection(parent)) {
|
|
249
249
|
parent.items[key] = node;
|
|
250
250
|
} else if (identity.isPair(parent)) {
|
|
@@ -854,10 +854,10 @@ var require_Collection = __commonJS({
|
|
|
854
854
|
var createNode = require_createNode();
|
|
855
855
|
var identity = require_identity();
|
|
856
856
|
var Node = require_Node();
|
|
857
|
-
function collectionFromPath(schema,
|
|
857
|
+
function collectionFromPath(schema, path24, value) {
|
|
858
858
|
let v = value;
|
|
859
|
-
for (let i =
|
|
860
|
-
const k =
|
|
859
|
+
for (let i = path24.length - 1; i >= 0; --i) {
|
|
860
|
+
const k = path24[i];
|
|
861
861
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
862
862
|
const a = [];
|
|
863
863
|
a[k] = v;
|
|
@@ -876,7 +876,7 @@ var require_Collection = __commonJS({
|
|
|
876
876
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
877
877
|
});
|
|
878
878
|
}
|
|
879
|
-
var isEmptyPath = (
|
|
879
|
+
var isEmptyPath = (path24) => path24 == null || typeof path24 === "object" && !!path24[Symbol.iterator]().next().done;
|
|
880
880
|
var Collection = class extends Node.NodeBase {
|
|
881
881
|
constructor(type, schema) {
|
|
882
882
|
super(type);
|
|
@@ -906,11 +906,11 @@ var require_Collection = __commonJS({
|
|
|
906
906
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
907
907
|
* that already exists in the map.
|
|
908
908
|
*/
|
|
909
|
-
addIn(
|
|
910
|
-
if (isEmptyPath(
|
|
909
|
+
addIn(path24, value) {
|
|
910
|
+
if (isEmptyPath(path24))
|
|
911
911
|
this.add(value);
|
|
912
912
|
else {
|
|
913
|
-
const [key, ...rest] =
|
|
913
|
+
const [key, ...rest] = path24;
|
|
914
914
|
const node = this.get(key, true);
|
|
915
915
|
if (identity.isCollection(node))
|
|
916
916
|
node.addIn(rest, value);
|
|
@@ -924,8 +924,8 @@ var require_Collection = __commonJS({
|
|
|
924
924
|
* Removes a value from the collection.
|
|
925
925
|
* @returns `true` if the item was found and removed.
|
|
926
926
|
*/
|
|
927
|
-
deleteIn(
|
|
928
|
-
const [key, ...rest] =
|
|
927
|
+
deleteIn(path24) {
|
|
928
|
+
const [key, ...rest] = path24;
|
|
929
929
|
if (rest.length === 0)
|
|
930
930
|
return this.delete(key);
|
|
931
931
|
const node = this.get(key, true);
|
|
@@ -939,8 +939,8 @@ var require_Collection = __commonJS({
|
|
|
939
939
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
940
940
|
* `true` (collections are always returned intact).
|
|
941
941
|
*/
|
|
942
|
-
getIn(
|
|
943
|
-
const [key, ...rest] =
|
|
942
|
+
getIn(path24, keepScalar) {
|
|
943
|
+
const [key, ...rest] = path24;
|
|
944
944
|
const node = this.get(key, true);
|
|
945
945
|
if (rest.length === 0)
|
|
946
946
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -958,8 +958,8 @@ var require_Collection = __commonJS({
|
|
|
958
958
|
/**
|
|
959
959
|
* Checks if the collection includes a value with the key `key`.
|
|
960
960
|
*/
|
|
961
|
-
hasIn(
|
|
962
|
-
const [key, ...rest] =
|
|
961
|
+
hasIn(path24) {
|
|
962
|
+
const [key, ...rest] = path24;
|
|
963
963
|
if (rest.length === 0)
|
|
964
964
|
return this.has(key);
|
|
965
965
|
const node = this.get(key, true);
|
|
@@ -969,8 +969,8 @@ var require_Collection = __commonJS({
|
|
|
969
969
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
970
970
|
* boolean to add/remove the item from the set.
|
|
971
971
|
*/
|
|
972
|
-
setIn(
|
|
973
|
-
const [key, ...rest] =
|
|
972
|
+
setIn(path24, value) {
|
|
973
|
+
const [key, ...rest] = path24;
|
|
974
974
|
if (rest.length === 0) {
|
|
975
975
|
this.set(key, value);
|
|
976
976
|
} else {
|
|
@@ -3485,9 +3485,9 @@ var require_Document = __commonJS({
|
|
|
3485
3485
|
this.contents.add(value);
|
|
3486
3486
|
}
|
|
3487
3487
|
/** Adds a value to the document. */
|
|
3488
|
-
addIn(
|
|
3488
|
+
addIn(path24, value) {
|
|
3489
3489
|
if (assertCollection(this.contents))
|
|
3490
|
-
this.contents.addIn(
|
|
3490
|
+
this.contents.addIn(path24, value);
|
|
3491
3491
|
}
|
|
3492
3492
|
/**
|
|
3493
3493
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3562,14 +3562,14 @@ var require_Document = __commonJS({
|
|
|
3562
3562
|
* Removes a value from the document.
|
|
3563
3563
|
* @returns `true` if the item was found and removed.
|
|
3564
3564
|
*/
|
|
3565
|
-
deleteIn(
|
|
3566
|
-
if (Collection.isEmptyPath(
|
|
3565
|
+
deleteIn(path24) {
|
|
3566
|
+
if (Collection.isEmptyPath(path24)) {
|
|
3567
3567
|
if (this.contents == null)
|
|
3568
3568
|
return false;
|
|
3569
3569
|
this.contents = null;
|
|
3570
3570
|
return true;
|
|
3571
3571
|
}
|
|
3572
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3572
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path24) : false;
|
|
3573
3573
|
}
|
|
3574
3574
|
/**
|
|
3575
3575
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3584,10 +3584,10 @@ var require_Document = __commonJS({
|
|
|
3584
3584
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3585
3585
|
* `true` (collections are always returned intact).
|
|
3586
3586
|
*/
|
|
3587
|
-
getIn(
|
|
3588
|
-
if (Collection.isEmptyPath(
|
|
3587
|
+
getIn(path24, keepScalar) {
|
|
3588
|
+
if (Collection.isEmptyPath(path24))
|
|
3589
3589
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3590
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3590
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path24, keepScalar) : void 0;
|
|
3591
3591
|
}
|
|
3592
3592
|
/**
|
|
3593
3593
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3598,10 +3598,10 @@ var require_Document = __commonJS({
|
|
|
3598
3598
|
/**
|
|
3599
3599
|
* Checks if the document includes a value at `path`.
|
|
3600
3600
|
*/
|
|
3601
|
-
hasIn(
|
|
3602
|
-
if (Collection.isEmptyPath(
|
|
3601
|
+
hasIn(path24) {
|
|
3602
|
+
if (Collection.isEmptyPath(path24))
|
|
3603
3603
|
return this.contents !== void 0;
|
|
3604
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3604
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path24) : false;
|
|
3605
3605
|
}
|
|
3606
3606
|
/**
|
|
3607
3607
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3618,13 +3618,13 @@ var require_Document = __commonJS({
|
|
|
3618
3618
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3619
3619
|
* boolean to add/remove the item from the set.
|
|
3620
3620
|
*/
|
|
3621
|
-
setIn(
|
|
3622
|
-
if (Collection.isEmptyPath(
|
|
3621
|
+
setIn(path24, value) {
|
|
3622
|
+
if (Collection.isEmptyPath(path24)) {
|
|
3623
3623
|
this.contents = value;
|
|
3624
3624
|
} else if (this.contents == null) {
|
|
3625
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3625
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path24), value);
|
|
3626
3626
|
} else if (assertCollection(this.contents)) {
|
|
3627
|
-
this.contents.setIn(
|
|
3627
|
+
this.contents.setIn(path24, value);
|
|
3628
3628
|
}
|
|
3629
3629
|
}
|
|
3630
3630
|
/**
|
|
@@ -5584,9 +5584,9 @@ var require_cst_visit = __commonJS({
|
|
|
5584
5584
|
visit.BREAK = BREAK;
|
|
5585
5585
|
visit.SKIP = SKIP;
|
|
5586
5586
|
visit.REMOVE = REMOVE;
|
|
5587
|
-
visit.itemAtPath = (cst,
|
|
5587
|
+
visit.itemAtPath = (cst, path24) => {
|
|
5588
5588
|
let item = cst;
|
|
5589
|
-
for (const [field2, index] of
|
|
5589
|
+
for (const [field2, index] of path24) {
|
|
5590
5590
|
const tok = item?.[field2];
|
|
5591
5591
|
if (tok && "items" in tok) {
|
|
5592
5592
|
item = tok.items[index];
|
|
@@ -5595,23 +5595,23 @@ var require_cst_visit = __commonJS({
|
|
|
5595
5595
|
}
|
|
5596
5596
|
return item;
|
|
5597
5597
|
};
|
|
5598
|
-
visit.parentCollection = (cst,
|
|
5599
|
-
const parent = visit.itemAtPath(cst,
|
|
5600
|
-
const field2 =
|
|
5598
|
+
visit.parentCollection = (cst, path24) => {
|
|
5599
|
+
const parent = visit.itemAtPath(cst, path24.slice(0, -1));
|
|
5600
|
+
const field2 = path24[path24.length - 1][0];
|
|
5601
5601
|
const coll = parent?.[field2];
|
|
5602
5602
|
if (coll && "items" in coll)
|
|
5603
5603
|
return coll;
|
|
5604
5604
|
throw new Error("Parent collection not found");
|
|
5605
5605
|
};
|
|
5606
|
-
function _visit(
|
|
5607
|
-
let ctrl = visitor(item,
|
|
5606
|
+
function _visit(path24, item, visitor) {
|
|
5607
|
+
let ctrl = visitor(item, path24);
|
|
5608
5608
|
if (typeof ctrl === "symbol")
|
|
5609
5609
|
return ctrl;
|
|
5610
5610
|
for (const field2 of ["key", "value"]) {
|
|
5611
5611
|
const token = item[field2];
|
|
5612
5612
|
if (token && "items" in token) {
|
|
5613
5613
|
for (let i = 0; i < token.items.length; ++i) {
|
|
5614
|
-
const ci = _visit(Object.freeze(
|
|
5614
|
+
const ci = _visit(Object.freeze(path24.concat([[field2, i]])), token.items[i], visitor);
|
|
5615
5615
|
if (typeof ci === "number")
|
|
5616
5616
|
i = ci - 1;
|
|
5617
5617
|
else if (ci === BREAK)
|
|
@@ -5622,10 +5622,10 @@ var require_cst_visit = __commonJS({
|
|
|
5622
5622
|
}
|
|
5623
5623
|
}
|
|
5624
5624
|
if (typeof ctrl === "function" && field2 === "key")
|
|
5625
|
-
ctrl = ctrl(item,
|
|
5625
|
+
ctrl = ctrl(item, path24);
|
|
5626
5626
|
}
|
|
5627
5627
|
}
|
|
5628
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5628
|
+
return typeof ctrl === "function" ? ctrl(item, path24) : ctrl;
|
|
5629
5629
|
}
|
|
5630
5630
|
exports.visit = visit;
|
|
5631
5631
|
}
|
|
@@ -6927,14 +6927,14 @@ var require_parser = __commonJS({
|
|
|
6927
6927
|
case "scalar":
|
|
6928
6928
|
case "single-quoted-scalar":
|
|
6929
6929
|
case "double-quoted-scalar": {
|
|
6930
|
-
const
|
|
6930
|
+
const fs23 = this.flowScalar(this.type);
|
|
6931
6931
|
if (atNextItem || it.value) {
|
|
6932
|
-
map.items.push({ start, key:
|
|
6932
|
+
map.items.push({ start, key: fs23, sep: [] });
|
|
6933
6933
|
this.onKeyLine = true;
|
|
6934
6934
|
} else if (it.sep) {
|
|
6935
|
-
this.stack.push(
|
|
6935
|
+
this.stack.push(fs23);
|
|
6936
6936
|
} else {
|
|
6937
|
-
Object.assign(it, { key:
|
|
6937
|
+
Object.assign(it, { key: fs23, sep: [] });
|
|
6938
6938
|
this.onKeyLine = true;
|
|
6939
6939
|
}
|
|
6940
6940
|
return;
|
|
@@ -7062,13 +7062,13 @@ var require_parser = __commonJS({
|
|
|
7062
7062
|
case "scalar":
|
|
7063
7063
|
case "single-quoted-scalar":
|
|
7064
7064
|
case "double-quoted-scalar": {
|
|
7065
|
-
const
|
|
7065
|
+
const fs23 = this.flowScalar(this.type);
|
|
7066
7066
|
if (!it || it.value)
|
|
7067
|
-
fc.items.push({ start: [], key:
|
|
7067
|
+
fc.items.push({ start: [], key: fs23, sep: [] });
|
|
7068
7068
|
else if (it.sep)
|
|
7069
|
-
this.stack.push(
|
|
7069
|
+
this.stack.push(fs23);
|
|
7070
7070
|
else
|
|
7071
|
-
Object.assign(it, { key:
|
|
7071
|
+
Object.assign(it, { key: fs23, sep: [] });
|
|
7072
7072
|
return;
|
|
7073
7073
|
}
|
|
7074
7074
|
case "flow-map-end":
|
|
@@ -7257,7 +7257,7 @@ var require_public_api = __commonJS({
|
|
|
7257
7257
|
return docs;
|
|
7258
7258
|
return Object.assign([], { empty: true }, composer$1.streamInfo());
|
|
7259
7259
|
}
|
|
7260
|
-
function
|
|
7260
|
+
function parseDocument8(source, options = {}) {
|
|
7261
7261
|
const { lineCounter: lineCounter2, prettyErrors } = parseOptions(options);
|
|
7262
7262
|
const parser$1 = new parser.Parser(lineCounter2?.addNewLine);
|
|
7263
7263
|
const composer$1 = new composer.Composer(options);
|
|
@@ -7283,7 +7283,7 @@ var require_public_api = __commonJS({
|
|
|
7283
7283
|
} else if (options === void 0 && reviver && typeof reviver === "object") {
|
|
7284
7284
|
options = reviver;
|
|
7285
7285
|
}
|
|
7286
|
-
const doc =
|
|
7286
|
+
const doc = parseDocument8(src, options);
|
|
7287
7287
|
if (!doc)
|
|
7288
7288
|
return null;
|
|
7289
7289
|
doc.warnings.forEach((warning) => log.warn(doc.options.logLevel, warning));
|
|
@@ -7319,7 +7319,7 @@ var require_public_api = __commonJS({
|
|
|
7319
7319
|
}
|
|
7320
7320
|
exports.parse = parse2;
|
|
7321
7321
|
exports.parseAllDocuments = parseAllDocuments;
|
|
7322
|
-
exports.parseDocument =
|
|
7322
|
+
exports.parseDocument = parseDocument8;
|
|
7323
7323
|
exports.stringify = stringify;
|
|
7324
7324
|
}
|
|
7325
7325
|
});
|
|
@@ -7546,8 +7546,8 @@ import { pathToFileURL } from "url";
|
|
|
7546
7546
|
// domains/comet-classic/classic-archive.ts
|
|
7547
7547
|
import { createHash as createHash3 } from "crypto";
|
|
7548
7548
|
import { spawnSync } from "child_process";
|
|
7549
|
-
import { promises as
|
|
7550
|
-
import
|
|
7549
|
+
import { promises as fs14 } from "fs";
|
|
7550
|
+
import path15 from "path";
|
|
7551
7551
|
|
|
7552
7552
|
// domains/comet-classic/classic-paths.ts
|
|
7553
7553
|
import { promises as fs } from "fs";
|
|
@@ -7824,6 +7824,7 @@ var CLASSIC_WIRE_KEYS = [
|
|
|
7824
7824
|
"tdd_mode",
|
|
7825
7825
|
"review_mode",
|
|
7826
7826
|
"isolation",
|
|
7827
|
+
"bound_branch",
|
|
7827
7828
|
"verify_mode",
|
|
7828
7829
|
"auto_transition",
|
|
7829
7830
|
"base_ref",
|
|
@@ -7942,6 +7943,7 @@ function classicStateFromDocument(doc) {
|
|
|
7942
7943
|
tddMode: enumValue(doc, "tdd_mode", TDD_MODES),
|
|
7943
7944
|
reviewMode: enumValue(doc, "review_mode", REVIEW_MODES),
|
|
7944
7945
|
isolation: enumValue(doc, "isolation", ISOLATIONS),
|
|
7946
|
+
boundBranch: nullableString(doc, "bound_branch"),
|
|
7945
7947
|
verifyMode: enumValue(doc, "verify_mode", VERIFY_MODES),
|
|
7946
7948
|
autoTransition: booleanValue(doc, "auto_transition"),
|
|
7947
7949
|
baseRef: nullableString(doc, "base_ref"),
|
|
@@ -8007,6 +8009,7 @@ function classicStateToDocument(state) {
|
|
|
8007
8009
|
tdd_mode: state.tddMode,
|
|
8008
8010
|
review_mode: state.reviewMode,
|
|
8009
8011
|
isolation: state.isolation,
|
|
8012
|
+
bound_branch: state.boundBranch,
|
|
8010
8013
|
verify_mode: state.verifyMode,
|
|
8011
8014
|
auto_transition: state.autoTransition,
|
|
8012
8015
|
base_ref: state.baseRef,
|
|
@@ -9013,6 +9016,11 @@ async function fileExists2(file) {
|
|
|
9013
9016
|
throw error;
|
|
9014
9017
|
}
|
|
9015
9018
|
}
|
|
9019
|
+
async function isClassicRuntimePackageRoot(root) {
|
|
9020
|
+
if (!await directoryExists(root)) return false;
|
|
9021
|
+
if (await fileExists2(path10.join(root, "skill.yaml"))) return true;
|
|
9022
|
+
return await fileExists2(path10.join(root, "SKILL.md")) && await fileExists2(path10.join(root, "comet", "skill.yaml"));
|
|
9023
|
+
}
|
|
9016
9024
|
function embeddedClassicRuntimePackage(root) {
|
|
9017
9025
|
return {
|
|
9018
9026
|
root,
|
|
@@ -9251,7 +9259,7 @@ async function classicRuntimeRoot() {
|
|
|
9251
9259
|
path10.resolve("assets", "skills", "comet-classic")
|
|
9252
9260
|
].filter((candidate) => Boolean(candidate));
|
|
9253
9261
|
for (const candidate of candidates) {
|
|
9254
|
-
if (await
|
|
9262
|
+
if (await isClassicRuntimePackageRoot(candidate)) return candidate;
|
|
9255
9263
|
}
|
|
9256
9264
|
return null;
|
|
9257
9265
|
}
|
|
@@ -9493,6 +9501,7 @@ function applyClassicTransition(current, event, options = {}) {
|
|
|
9493
9501
|
setField(classic, effects, "tddMode", null);
|
|
9494
9502
|
setField(classic, effects, "reviewMode", null);
|
|
9495
9503
|
setField(classic, effects, "isolation", null);
|
|
9504
|
+
setField(classic, effects, "boundBranch", null);
|
|
9496
9505
|
setField(classic, effects, "verifyMode", null);
|
|
9497
9506
|
setField(classic, effects, "directOverride", null);
|
|
9498
9507
|
} else if (event === "archive-confirm") {
|
|
@@ -9521,6 +9530,324 @@ function applyClassicTransition(current, event, options = {}) {
|
|
|
9521
9530
|
return { classic, effects, definition };
|
|
9522
9531
|
}
|
|
9523
9532
|
|
|
9533
|
+
// domains/comet-classic/classic-current-change.ts
|
|
9534
|
+
import { promises as fs13 } from "fs";
|
|
9535
|
+
import path14 from "path";
|
|
9536
|
+
|
|
9537
|
+
// domains/comet-entry/current-selection.ts
|
|
9538
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
9539
|
+
import { promises as fs11 } from "fs";
|
|
9540
|
+
import path12 from "path";
|
|
9541
|
+
var COMET_CURRENT_SELECTION_SCHEMA = "comet.selection.v2";
|
|
9542
|
+
var COMET_CURRENT_SELECTION_MAX_BYTES = 16 * 1024;
|
|
9543
|
+
function cometCurrentSelectionFile(projectRoot2) {
|
|
9544
|
+
return path12.join(projectRoot2, ".comet", "current-change.json");
|
|
9545
|
+
}
|
|
9546
|
+
function isRecord(value) {
|
|
9547
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
9548
|
+
}
|
|
9549
|
+
function validBranch(value) {
|
|
9550
|
+
return value === null || typeof value === "string";
|
|
9551
|
+
}
|
|
9552
|
+
function parseSelection(source) {
|
|
9553
|
+
let value;
|
|
9554
|
+
try {
|
|
9555
|
+
value = JSON.parse(source);
|
|
9556
|
+
} catch (error) {
|
|
9557
|
+
throw new Error(
|
|
9558
|
+
`current change selection contains invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
9559
|
+
{ cause: error }
|
|
9560
|
+
);
|
|
9561
|
+
}
|
|
9562
|
+
if (!isRecord(value)) {
|
|
9563
|
+
throw new Error("current change selection must be a JSON object");
|
|
9564
|
+
}
|
|
9565
|
+
if (value.version === 1) {
|
|
9566
|
+
if (typeof value.change !== "string") {
|
|
9567
|
+
throw new Error("legacy current change selection change must be a string");
|
|
9568
|
+
}
|
|
9569
|
+
if (value.branch !== void 0 && !validBranch(value.branch)) {
|
|
9570
|
+
throw new Error("legacy current change selection branch must be a string or null");
|
|
9571
|
+
}
|
|
9572
|
+
return {
|
|
9573
|
+
selection: {
|
|
9574
|
+
schema: COMET_CURRENT_SELECTION_SCHEMA,
|
|
9575
|
+
workflow: "classic",
|
|
9576
|
+
change: value.change,
|
|
9577
|
+
branch: value.branch ?? null
|
|
9578
|
+
},
|
|
9579
|
+
legacy: true
|
|
9580
|
+
};
|
|
9581
|
+
}
|
|
9582
|
+
if (value.schema !== COMET_CURRENT_SELECTION_SCHEMA) {
|
|
9583
|
+
throw new Error(`current change selection schema must be ${COMET_CURRENT_SELECTION_SCHEMA}`);
|
|
9584
|
+
}
|
|
9585
|
+
if (value.workflow !== "native" && value.workflow !== "classic") {
|
|
9586
|
+
throw new Error("current change selection workflow must be native or classic");
|
|
9587
|
+
}
|
|
9588
|
+
if (typeof value.change !== "string") {
|
|
9589
|
+
throw new Error("current change selection change must be a string");
|
|
9590
|
+
}
|
|
9591
|
+
if (!validBranch(value.branch)) {
|
|
9592
|
+
throw new Error("current change selection branch must be a string or null");
|
|
9593
|
+
}
|
|
9594
|
+
if (value.workflow === "native" && value.branch !== null) {
|
|
9595
|
+
throw new Error("Native current change selection branch must be null");
|
|
9596
|
+
}
|
|
9597
|
+
return { selection: value, legacy: false };
|
|
9598
|
+
}
|
|
9599
|
+
async function readCometCurrentSelection(projectRoot2) {
|
|
9600
|
+
let source;
|
|
9601
|
+
try {
|
|
9602
|
+
const stat = await fs11.lstat(cometCurrentSelectionFile(projectRoot2));
|
|
9603
|
+
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
9604
|
+
throw new Error("current change selection must be a regular file");
|
|
9605
|
+
}
|
|
9606
|
+
if (stat.size > COMET_CURRENT_SELECTION_MAX_BYTES) {
|
|
9607
|
+
throw new Error(
|
|
9608
|
+
`current change selection exceeds ${COMET_CURRENT_SELECTION_MAX_BYTES} bytes`
|
|
9609
|
+
);
|
|
9610
|
+
}
|
|
9611
|
+
source = await fs11.readFile(cometCurrentSelectionFile(projectRoot2), "utf8");
|
|
9612
|
+
} catch (error) {
|
|
9613
|
+
if (error.code === "ENOENT") return { status: "missing" };
|
|
9614
|
+
throw new Error(
|
|
9615
|
+
`cannot read current change selection: ${error instanceof Error ? error.message : String(error)}`,
|
|
9616
|
+
{ cause: error }
|
|
9617
|
+
);
|
|
9618
|
+
}
|
|
9619
|
+
const parsed = parseSelection(source);
|
|
9620
|
+
return { status: "selected", ...parsed };
|
|
9621
|
+
}
|
|
9622
|
+
async function writeCometCurrentSelection(projectRoot2, selection) {
|
|
9623
|
+
const parsed = parseSelection(JSON.stringify(selection));
|
|
9624
|
+
if (parsed.legacy) throw new Error("cannot write a legacy current change selection");
|
|
9625
|
+
const file = cometCurrentSelectionFile(projectRoot2);
|
|
9626
|
+
const temporary = `${file}.${randomUUID6()}.tmp`;
|
|
9627
|
+
await fs11.mkdir(path12.dirname(file), { recursive: true });
|
|
9628
|
+
try {
|
|
9629
|
+
await fs11.writeFile(temporary, `${JSON.stringify(parsed.selection, null, 2)}
|
|
9630
|
+
`, "utf8");
|
|
9631
|
+
await fs11.rename(temporary, file);
|
|
9632
|
+
} catch (error) {
|
|
9633
|
+
await fs11.rm(temporary, { force: true });
|
|
9634
|
+
throw error;
|
|
9635
|
+
}
|
|
9636
|
+
}
|
|
9637
|
+
async function clearCometCurrentSelection(projectRoot2) {
|
|
9638
|
+
await fs11.rm(cometCurrentSelectionFile(projectRoot2), { force: true });
|
|
9639
|
+
}
|
|
9640
|
+
async function clearCometCurrentSelectionIf(projectRoot2, workflow, change) {
|
|
9641
|
+
const current = await readCometCurrentSelection(projectRoot2);
|
|
9642
|
+
if (current.status !== "selected" || current.selection.workflow !== workflow || current.selection.change !== change) {
|
|
9643
|
+
return false;
|
|
9644
|
+
}
|
|
9645
|
+
await clearCometCurrentSelection(projectRoot2);
|
|
9646
|
+
return true;
|
|
9647
|
+
}
|
|
9648
|
+
|
|
9649
|
+
// domains/comet-classic/classic-branch-binding.ts
|
|
9650
|
+
var import_yaml3 = __toESM(require_dist(), 1);
|
|
9651
|
+
import { execFileSync } from "child_process";
|
|
9652
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
9653
|
+
import { promises as fs12 } from "fs";
|
|
9654
|
+
import path13 from "path";
|
|
9655
|
+
function liveGitBranch(cwd) {
|
|
9656
|
+
try {
|
|
9657
|
+
const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
9658
|
+
cwd,
|
|
9659
|
+
encoding: "utf8",
|
|
9660
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
9661
|
+
}).trim();
|
|
9662
|
+
return branch && branch !== "HEAD" ? branch : null;
|
|
9663
|
+
} catch {
|
|
9664
|
+
return null;
|
|
9665
|
+
}
|
|
9666
|
+
}
|
|
9667
|
+
function isGitWorkTree(cwd) {
|
|
9668
|
+
try {
|
|
9669
|
+
return execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
9670
|
+
cwd,
|
|
9671
|
+
encoding: "utf8",
|
|
9672
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
9673
|
+
}).trim() === "true";
|
|
9674
|
+
} catch {
|
|
9675
|
+
return false;
|
|
9676
|
+
}
|
|
9677
|
+
}
|
|
9678
|
+
var BOUND_BRANCH_ISOLATIONS = ["current", "branch", "worktree"];
|
|
9679
|
+
function requiresBranchBinding(isolation) {
|
|
9680
|
+
return BOUND_BRANCH_ISOLATIONS.includes(isolation);
|
|
9681
|
+
}
|
|
9682
|
+
function evaluateBranchBinding(input) {
|
|
9683
|
+
if (!requiresBranchBinding(input.isolation)) return { status: "not-applicable" };
|
|
9684
|
+
if (input.boundBranch === null && input.currentBranch === null && input.gitWorkTree === false) {
|
|
9685
|
+
return { status: "not-applicable" };
|
|
9686
|
+
}
|
|
9687
|
+
if (input.boundBranch === null) {
|
|
9688
|
+
return input.currentBranch === null ? { status: "unbound-detached" } : { status: "needs-heal", branch: input.currentBranch };
|
|
9689
|
+
}
|
|
9690
|
+
if (input.currentBranch === input.boundBranch) return { status: "ok" };
|
|
9691
|
+
return { status: "drift", boundBranch: input.boundBranch, currentBranch: input.currentBranch };
|
|
9692
|
+
}
|
|
9693
|
+
async function resolveBranchBinding(changeDir, options) {
|
|
9694
|
+
const file = path13.join(changeDir, ".comet.yaml");
|
|
9695
|
+
const document = (0, import_yaml3.parseDocument)(await fs12.readFile(file, "utf8"), { uniqueKeys: false });
|
|
9696
|
+
if (document.errors.length > 0) {
|
|
9697
|
+
throw new Error(`Invalid .comet.yaml: ${document.errors[0].message}`);
|
|
9698
|
+
}
|
|
9699
|
+
const record = document.toJS() ?? {};
|
|
9700
|
+
const isolation = typeof record.isolation === "string" ? record.isolation : null;
|
|
9701
|
+
const boundBranch = typeof record.bound_branch === "string" && record.bound_branch !== "" ? record.bound_branch : null;
|
|
9702
|
+
const bindingRequired = requiresBranchBinding(isolation);
|
|
9703
|
+
const currentBranch = liveGitBranch(options.cwd);
|
|
9704
|
+
const gitWorkTree = bindingRequired && boundBranch === null && currentBranch === null ? isGitWorkTree(options.cwd) : true;
|
|
9705
|
+
const verdict = evaluateBranchBinding({ isolation, boundBranch, currentBranch, gitWorkTree });
|
|
9706
|
+
if (verdict.status === "needs-heal" && options.heal) {
|
|
9707
|
+
await healBoundBranch(changeDir, verdict.branch);
|
|
9708
|
+
return { status: "healed", branch: verdict.branch, bindingRequired, currentBranch };
|
|
9709
|
+
}
|
|
9710
|
+
return { ...verdict, bindingRequired, currentBranch };
|
|
9711
|
+
}
|
|
9712
|
+
async function healBoundBranch(changeDir, branch) {
|
|
9713
|
+
const file = path13.join(changeDir, ".comet.yaml");
|
|
9714
|
+
const document = (0, import_yaml3.parseDocument)(await fs12.readFile(file, "utf8"), { uniqueKeys: false });
|
|
9715
|
+
document.set("bound_branch", branch);
|
|
9716
|
+
const temporary = `${file}.${randomUUID7()}.tmp`;
|
|
9717
|
+
try {
|
|
9718
|
+
await fs12.writeFile(temporary, document.toString(), "utf8");
|
|
9719
|
+
await fs12.rename(temporary, file);
|
|
9720
|
+
} catch (error) {
|
|
9721
|
+
await fs12.rm(temporary, { force: true });
|
|
9722
|
+
throw error;
|
|
9723
|
+
}
|
|
9724
|
+
}
|
|
9725
|
+
function branchLabel(currentBranch) {
|
|
9726
|
+
return currentBranch ?? "detached HEAD";
|
|
9727
|
+
}
|
|
9728
|
+
function driftBlockedMessage(change, boundBranch, currentBranch) {
|
|
9729
|
+
return `change '${change}' is bound to branch '${boundBranch}', but current branch is '${branchLabel(currentBranch)}'.
|
|
9730
|
+
Next: ask the user to confirm — switch back to '${boundBranch}', or run \`comet state rebind ${change}\` after explicit confirmation.`;
|
|
9731
|
+
}
|
|
9732
|
+
function driftStaleReason(change, boundBranch, currentBranch) {
|
|
9733
|
+
return `change '${change}' is bound to branch '${boundBranch}', but current branch is '${branchLabel(currentBranch)}'`;
|
|
9734
|
+
}
|
|
9735
|
+
function unboundDetachedMessage(change) {
|
|
9736
|
+
return `change '${change}' uses a branch-bound workspace mode but has no bound branch and HEAD is detached; checkout a branch first before continuing.`;
|
|
9737
|
+
}
|
|
9738
|
+
|
|
9739
|
+
// domains/comet-classic/classic-current-change.ts
|
|
9740
|
+
function changeDirectory(projectRoot2, changeName) {
|
|
9741
|
+
return path14.join(projectRoot2, "openspec", "changes", changeName);
|
|
9742
|
+
}
|
|
9743
|
+
async function validateActiveChange(projectRoot2, changeName) {
|
|
9744
|
+
assertOpenSpecChangeName(changeName);
|
|
9745
|
+
const changeDir = changeDirectory(projectRoot2, changeName);
|
|
9746
|
+
try {
|
|
9747
|
+
await fs13.access(path14.join(changeDir, ".comet.yaml"));
|
|
9748
|
+
} catch (error) {
|
|
9749
|
+
if (error.code === "ENOENT") {
|
|
9750
|
+
throw new Error(
|
|
9751
|
+
`Cannot select current change '${changeName}': active change state not found`,
|
|
9752
|
+
{
|
|
9753
|
+
cause: error
|
|
9754
|
+
}
|
|
9755
|
+
);
|
|
9756
|
+
}
|
|
9757
|
+
throw error;
|
|
9758
|
+
}
|
|
9759
|
+
const projection = await readClassicState(changeDir, { migrate: false });
|
|
9760
|
+
if (!projection.classic) {
|
|
9761
|
+
throw new Error(`Cannot select current change '${changeName}': Classic state is incomplete`);
|
|
9762
|
+
}
|
|
9763
|
+
if (projection.classic.archived) {
|
|
9764
|
+
throw new Error(`Cannot select current change '${changeName}': change is archived`);
|
|
9765
|
+
}
|
|
9766
|
+
}
|
|
9767
|
+
async function selectCurrentChange(projectRoot2, changeName) {
|
|
9768
|
+
await validateActiveChange(projectRoot2, changeName);
|
|
9769
|
+
const outcome = await resolveBranchBinding(changeDirectory(projectRoot2, changeName), {
|
|
9770
|
+
heal: true,
|
|
9771
|
+
cwd: projectRoot2
|
|
9772
|
+
});
|
|
9773
|
+
if (outcome.status === "drift") {
|
|
9774
|
+
throw new Error(driftStaleReason(changeName, outcome.boundBranch, outcome.currentBranch));
|
|
9775
|
+
}
|
|
9776
|
+
if (outcome.status === "unbound-detached") {
|
|
9777
|
+
throw new Error(unboundDetachedMessage(changeName));
|
|
9778
|
+
}
|
|
9779
|
+
const selection = {
|
|
9780
|
+
schema: "comet.selection.v2",
|
|
9781
|
+
workflow: "classic",
|
|
9782
|
+
change: changeName,
|
|
9783
|
+
branch: outcome.currentBranch
|
|
9784
|
+
};
|
|
9785
|
+
await writeCometCurrentSelection(projectRoot2, selection);
|
|
9786
|
+
return selection;
|
|
9787
|
+
}
|
|
9788
|
+
async function resolveCurrentChange(projectRoot2) {
|
|
9789
|
+
let current;
|
|
9790
|
+
try {
|
|
9791
|
+
current = await readCometCurrentSelection(projectRoot2);
|
|
9792
|
+
} catch (error) {
|
|
9793
|
+
return {
|
|
9794
|
+
status: "stale",
|
|
9795
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
9796
|
+
};
|
|
9797
|
+
}
|
|
9798
|
+
if (current.status === "missing") return { status: "missing" };
|
|
9799
|
+
if (current.selection.workflow !== "classic") {
|
|
9800
|
+
return {
|
|
9801
|
+
status: "stale",
|
|
9802
|
+
reason: `current change '${current.selection.change}' belongs to Native, not Classic`
|
|
9803
|
+
};
|
|
9804
|
+
}
|
|
9805
|
+
const selection = current.selection;
|
|
9806
|
+
try {
|
|
9807
|
+
await validateActiveChange(projectRoot2, selection.change);
|
|
9808
|
+
} catch (error) {
|
|
9809
|
+
return {
|
|
9810
|
+
status: "stale",
|
|
9811
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
9812
|
+
};
|
|
9813
|
+
}
|
|
9814
|
+
const outcome = await resolveBranchBinding(changeDirectory(projectRoot2, selection.change), {
|
|
9815
|
+
heal: false,
|
|
9816
|
+
cwd: projectRoot2
|
|
9817
|
+
});
|
|
9818
|
+
if (outcome.status === "drift") {
|
|
9819
|
+
return {
|
|
9820
|
+
status: "stale",
|
|
9821
|
+
reason: driftStaleReason(selection.change, outcome.boundBranch, outcome.currentBranch)
|
|
9822
|
+
};
|
|
9823
|
+
}
|
|
9824
|
+
if (outcome.status === "unbound-detached") {
|
|
9825
|
+
return { status: "stale", reason: unboundDetachedMessage(selection.change) };
|
|
9826
|
+
}
|
|
9827
|
+
if (outcome.status === "ok") return { status: "selected", selection };
|
|
9828
|
+
if (selection.branch !== null && outcome.currentBranch !== selection.branch) {
|
|
9829
|
+
return {
|
|
9830
|
+
status: "stale",
|
|
9831
|
+
reason: `current change '${selection.change}' was selected on branch '${selection.branch}', current branch is '${outcome.currentBranch ?? "detached HEAD"}'`
|
|
9832
|
+
};
|
|
9833
|
+
}
|
|
9834
|
+
return { status: "selected", selection };
|
|
9835
|
+
}
|
|
9836
|
+
async function clearCurrentChange(projectRoot2) {
|
|
9837
|
+
let current;
|
|
9838
|
+
try {
|
|
9839
|
+
current = await readCometCurrentSelection(projectRoot2);
|
|
9840
|
+
} catch {
|
|
9841
|
+
return;
|
|
9842
|
+
}
|
|
9843
|
+
if (current.status === "selected" && current.selection.workflow === "classic") {
|
|
9844
|
+
await clearCometCurrentSelection(projectRoot2);
|
|
9845
|
+
}
|
|
9846
|
+
}
|
|
9847
|
+
async function clearCurrentChangeIf(projectRoot2, change) {
|
|
9848
|
+
return clearCometCurrentSelectionIf(projectRoot2, "classic", change);
|
|
9849
|
+
}
|
|
9850
|
+
|
|
9524
9851
|
// domains/comet-classic/classic-archive.ts
|
|
9525
9852
|
var GREEN = "\x1B[32m";
|
|
9526
9853
|
var RED = "\x1B[31m";
|
|
@@ -9555,7 +9882,7 @@ var ArchiveOutput = class {
|
|
|
9555
9882
|
};
|
|
9556
9883
|
async function exists2(file) {
|
|
9557
9884
|
try {
|
|
9558
|
-
await
|
|
9885
|
+
await fs14.access(file);
|
|
9559
9886
|
return true;
|
|
9560
9887
|
} catch (error) {
|
|
9561
9888
|
if (error.code === "ENOENT") return false;
|
|
@@ -9609,10 +9936,10 @@ async function findArchiveDir(change, preferred) {
|
|
|
9609
9936
|
if (await exists2(preferred)) return preferred;
|
|
9610
9937
|
const archiveRoot = "openspec/changes/archive";
|
|
9611
9938
|
if (!await exists2(archiveRoot)) return null;
|
|
9612
|
-
for (const entry2 of (await
|
|
9939
|
+
for (const entry2 of (await fs14.readdir(archiveRoot)).sort()) {
|
|
9613
9940
|
if (!entry2.endsWith(`-${change}`)) continue;
|
|
9614
9941
|
const candidate = `${archiveRoot}/${entry2}`;
|
|
9615
|
-
if ((await
|
|
9942
|
+
if ((await fs14.stat(candidate)).isDirectory()) return candidate;
|
|
9616
9943
|
}
|
|
9617
9944
|
return null;
|
|
9618
9945
|
}
|
|
@@ -9642,9 +9969,9 @@ async function annotateFrontmatter(output, file, archiveName, extraFields, dryRu
|
|
|
9642
9969
|
output.stepsTotal += 1;
|
|
9643
9970
|
return;
|
|
9644
9971
|
}
|
|
9645
|
-
const original = await
|
|
9972
|
+
const original = await fs14.readFile(file, "utf8");
|
|
9646
9973
|
const updated = annotatedMarkdown(original, archiveName, extraFields);
|
|
9647
|
-
await
|
|
9974
|
+
await fs14.writeFile(file, updated);
|
|
9648
9975
|
output.stderr.push(green(` [OK] Annotated: ${file}`));
|
|
9649
9976
|
output.stepsOk += 1;
|
|
9650
9977
|
output.stepsTotal += 1;
|
|
@@ -9653,10 +9980,10 @@ async function verifyMainSpecsClean() {
|
|
|
9653
9980
|
const specsRoot = "openspec/specs";
|
|
9654
9981
|
if (!await exists2(specsRoot)) return;
|
|
9655
9982
|
let found = false;
|
|
9656
|
-
for (const entry2 of await
|
|
9983
|
+
for (const entry2 of await fs14.readdir(specsRoot)) {
|
|
9657
9984
|
const specFile = `${specsRoot}/${entry2}/spec.md`;
|
|
9658
9985
|
if (!await exists2(specFile)) continue;
|
|
9659
|
-
const matches = (await
|
|
9986
|
+
const matches = (await fs14.readFile(specFile, "utf8")).split(/\r?\n/u).map((line, index) => ({ line, number: index + 1 })).filter((item) => /^## (ADDED|MODIFIED|REMOVED|RENAMED) Requirements$/u.test(item.line));
|
|
9660
9987
|
if (matches.length > 0) {
|
|
9661
9988
|
found = true;
|
|
9662
9989
|
process.stderr.write(
|
|
@@ -9688,7 +10015,7 @@ var classicArchiveCommand = async (args) => {
|
|
|
9688
10015
|
}
|
|
9689
10016
|
if (recoveredArchive) {
|
|
9690
10017
|
archiveDir = recoveredArchive;
|
|
9691
|
-
archiveName =
|
|
10018
|
+
archiveName = path15.basename(recoveredArchive);
|
|
9692
10019
|
}
|
|
9693
10020
|
const projection = await readClassicState(changeDir);
|
|
9694
10021
|
if (!projection.classic) {
|
|
@@ -9783,7 +10110,7 @@ var classicArchiveCommand = async (args) => {
|
|
|
9783
10110
|
return output.toResult(1);
|
|
9784
10111
|
}
|
|
9785
10112
|
archiveDir = resolvedArchive;
|
|
9786
|
-
archiveName =
|
|
10113
|
+
archiveName = path15.basename(resolvedArchive);
|
|
9787
10114
|
output.stderr.push(green(` [OK] OpenSpec archive completed: ${archiveDir}`));
|
|
9788
10115
|
output.stepsOk += 1;
|
|
9789
10116
|
output.stepsTotal += 1;
|
|
@@ -9890,6 +10217,7 @@ var classicArchiveCommand = async (args) => {
|
|
|
9890
10217
|
output.stepsOk += 1;
|
|
9891
10218
|
output.stepsTotal += 1;
|
|
9892
10219
|
}
|
|
10220
|
+
if (!dryRun) await clearCurrentChangeIf(process.cwd(), change);
|
|
9893
10221
|
output.stderr.push("");
|
|
9894
10222
|
output.stderr.push(
|
|
9895
10223
|
dryRun ? yellow(`Dry run complete. ${output.stepsOk}/${output.stepsTotal} steps would succeed.`) : green(`Archive complete. ${output.stepsOk}/${output.stepsTotal} steps succeeded.`)
|
|
@@ -9907,30 +10235,30 @@ var classicArchiveCommand = async (args) => {
|
|
|
9907
10235
|
};
|
|
9908
10236
|
|
|
9909
10237
|
// domains/comet-classic/classic-guard.ts
|
|
9910
|
-
var
|
|
10238
|
+
var import_yaml6 = __toESM(require_dist(), 1);
|
|
9911
10239
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
9912
10240
|
import { createHash as createHash4 } from "crypto";
|
|
9913
|
-
import { existsSync, promises as
|
|
9914
|
-
import
|
|
10241
|
+
import { existsSync, promises as fs18, readFileSync } from "fs";
|
|
10242
|
+
import path19 from "path";
|
|
9915
10243
|
|
|
9916
10244
|
// domains/comet-classic/classic-command-checks.ts
|
|
9917
|
-
import
|
|
10245
|
+
import path16 from "path";
|
|
9918
10246
|
function validateScope(scope) {
|
|
9919
10247
|
if (scope !== "build" && scope !== "verify") {
|
|
9920
10248
|
throw new Error(`Invalid command check scope: '${String(scope)}'`);
|
|
9921
10249
|
}
|
|
9922
10250
|
}
|
|
9923
10251
|
function projectRoot(changeDir) {
|
|
9924
|
-
return
|
|
10252
|
+
return path16.resolve(changeDir, "..", "..", "..");
|
|
9925
10253
|
}
|
|
9926
10254
|
function normalizedCwd(changeDir, cwd = ".") {
|
|
9927
10255
|
if (cwd.trim().length === 0) throw new Error("Command check cwd cannot be blank");
|
|
9928
10256
|
const root = projectRoot(changeDir);
|
|
9929
|
-
const target =
|
|
9930
|
-
if (target !== root && !target.startsWith(root +
|
|
10257
|
+
const target = path16.resolve(root, cwd);
|
|
10258
|
+
if (target !== root && !target.startsWith(root + path16.sep)) {
|
|
9931
10259
|
throw new Error(`Command check cwd must resolve within the project root: '${cwd}'`);
|
|
9932
10260
|
}
|
|
9933
|
-
return
|
|
10261
|
+
return path16.relative(root, target).replaceAll("\\", "/") || ".";
|
|
9934
10262
|
}
|
|
9935
10263
|
function validRecord(changeDir, event) {
|
|
9936
10264
|
if (event.type !== "command_check_recorded") return null;
|
|
@@ -10091,9 +10419,9 @@ async function inspectClassicChange(changeDir, name) {
|
|
|
10091
10419
|
}
|
|
10092
10420
|
|
|
10093
10421
|
// domains/comet-classic/classic-validate-command.ts
|
|
10094
|
-
var
|
|
10095
|
-
import { promises as
|
|
10096
|
-
import
|
|
10422
|
+
var import_yaml4 = __toESM(require_dist(), 1);
|
|
10423
|
+
import { promises as fs15 } from "fs";
|
|
10424
|
+
import path17 from "path";
|
|
10097
10425
|
var GREEN2 = "\x1B[32m";
|
|
10098
10426
|
var RED2 = "\x1B[31m";
|
|
10099
10427
|
var YELLOW2 = "\x1B[33m";
|
|
@@ -10143,7 +10471,7 @@ function color(code, message) {
|
|
|
10143
10471
|
}
|
|
10144
10472
|
async function exists3(file) {
|
|
10145
10473
|
try {
|
|
10146
|
-
await
|
|
10474
|
+
await fs15.access(file);
|
|
10147
10475
|
return true;
|
|
10148
10476
|
} catch (error) {
|
|
10149
10477
|
if (error.code === "ENOENT") return false;
|
|
@@ -10164,7 +10492,7 @@ var classicValidateCommand = async (args) => {
|
|
|
10164
10492
|
};
|
|
10165
10493
|
}
|
|
10166
10494
|
const { directory, label } = await resolveClassicChangeDirectory(name);
|
|
10167
|
-
const yamlFile =
|
|
10495
|
+
const yamlFile = path17.join(directory, ".comet.yaml");
|
|
10168
10496
|
const lines = [`[VALIDATE] ${label}/.comet.yaml`];
|
|
10169
10497
|
let errors = 0;
|
|
10170
10498
|
let warnings = 0;
|
|
@@ -10178,7 +10506,7 @@ var classicValidateCommand = async (args) => {
|
|
|
10178
10506
|
};
|
|
10179
10507
|
let source;
|
|
10180
10508
|
try {
|
|
10181
|
-
source = await
|
|
10509
|
+
source = await fs15.readFile(yamlFile, "utf8");
|
|
10182
10510
|
} catch (error) {
|
|
10183
10511
|
if (error.code === "ENOENT") {
|
|
10184
10512
|
fail3(".comet.yaml does not exist");
|
|
@@ -10187,10 +10515,10 @@ var classicValidateCommand = async (args) => {
|
|
|
10187
10515
|
}
|
|
10188
10516
|
throw error;
|
|
10189
10517
|
}
|
|
10190
|
-
const document = (0,
|
|
10191
|
-
if (document.errors.length > 0 || !(0,
|
|
10518
|
+
const document = (0, import_yaml4.parseDocument)(source);
|
|
10519
|
+
if (document.errors.length > 0 || !(0, import_yaml4.isMap)(document.contents)) {
|
|
10192
10520
|
for (const error of document.errors) fail3(error.message);
|
|
10193
|
-
if (!(0,
|
|
10521
|
+
if (!(0, import_yaml4.isMap)(document.contents)) fail3("document root must be a mapping");
|
|
10194
10522
|
lines.push("", color(RED2, `${errors} error(s), ${warnings} warning(s) — validation FAILED`));
|
|
10195
10523
|
return { exitCode: 1, stderr: lines.join("\n") };
|
|
10196
10524
|
}
|
|
@@ -10213,6 +10541,12 @@ var classicValidateCommand = async (args) => {
|
|
|
10213
10541
|
fail3(`${field2}='${value}' is not valid. Expected: ${values.join(" ")}`);
|
|
10214
10542
|
}
|
|
10215
10543
|
}
|
|
10544
|
+
if (Object.prototype.hasOwnProperty.call(record, "bound_branch")) {
|
|
10545
|
+
const value = record.bound_branch;
|
|
10546
|
+
if (value !== null && typeof value !== "string") {
|
|
10547
|
+
fail3(`bound_branch='${text(value)}' is not a string or null`);
|
|
10548
|
+
}
|
|
10549
|
+
}
|
|
10216
10550
|
if (Object.prototype.hasOwnProperty.call(record, "verify_failures")) {
|
|
10217
10551
|
const value = record.verify_failures;
|
|
10218
10552
|
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
@@ -10221,7 +10555,7 @@ var classicValidateCommand = async (args) => {
|
|
|
10221
10555
|
}
|
|
10222
10556
|
for (const field2 of ["design_doc", "plan", "handoff_context"]) {
|
|
10223
10557
|
const value = text(record[field2]);
|
|
10224
|
-
if (value && !await exists3(
|
|
10558
|
+
if (value && !await exists3(path17.resolve(value))) {
|
|
10225
10559
|
fail3(`${field2}='${value}' does not exist on disk`);
|
|
10226
10560
|
}
|
|
10227
10561
|
}
|
|
@@ -10244,16 +10578,16 @@ var classicValidateCommand = async (args) => {
|
|
|
10244
10578
|
};
|
|
10245
10579
|
|
|
10246
10580
|
// domains/comet-classic/classic-project-config.ts
|
|
10247
|
-
var
|
|
10581
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
10248
10582
|
import os from "os";
|
|
10249
|
-
import { promises as
|
|
10250
|
-
import
|
|
10583
|
+
import { promises as fs17 } from "fs";
|
|
10584
|
+
import path18 from "path";
|
|
10251
10585
|
|
|
10252
10586
|
// platform/fs/file-system.ts
|
|
10253
|
-
import { promises as
|
|
10587
|
+
import { promises as fs16 } from "fs";
|
|
10254
10588
|
async function fileExists3(filePath) {
|
|
10255
10589
|
try {
|
|
10256
|
-
await
|
|
10590
|
+
await fs16.access(filePath);
|
|
10257
10591
|
return true;
|
|
10258
10592
|
} catch (error) {
|
|
10259
10593
|
if (isNotFoundError(error)) return false;
|
|
@@ -10262,7 +10596,7 @@ async function fileExists3(filePath) {
|
|
|
10262
10596
|
}
|
|
10263
10597
|
async function readDir(dirPath) {
|
|
10264
10598
|
try {
|
|
10265
|
-
return await
|
|
10599
|
+
return await fs16.readdir(dirPath);
|
|
10266
10600
|
} catch (error) {
|
|
10267
10601
|
const code = error?.code;
|
|
10268
10602
|
if (code === "ENOENT" || code === "ENOTDIR") {
|
|
@@ -10280,9 +10614,9 @@ function configCandidates(options = {}) {
|
|
|
10280
10614
|
const cwd = options.cwd ?? process.cwd();
|
|
10281
10615
|
const homeDir = options.homeDir ?? os.homedir();
|
|
10282
10616
|
const candidates = [
|
|
10283
|
-
{ file:
|
|
10617
|
+
{ file: path18.resolve(cwd, ".comet", "config.yaml"), source: ".comet/config.yaml" },
|
|
10284
10618
|
{
|
|
10285
|
-
file:
|
|
10619
|
+
file: path18.resolve(homeDir, ".comet", "config.yaml"),
|
|
10286
10620
|
source: "~/.comet/config.yaml"
|
|
10287
10621
|
}
|
|
10288
10622
|
];
|
|
@@ -10293,10 +10627,14 @@ function configCandidates(options = {}) {
|
|
|
10293
10627
|
async function readClassicConfigValue(field2, options = {}) {
|
|
10294
10628
|
for (const candidate of configCandidates(options)) {
|
|
10295
10629
|
if (!await fileExists3(candidate.file)) continue;
|
|
10296
|
-
const document = (0,
|
|
10630
|
+
const document = (0, import_yaml5.parseDocument)(await fs17.readFile(candidate.file, "utf8"), {
|
|
10297
10631
|
uniqueKeys: false
|
|
10298
10632
|
});
|
|
10299
|
-
const
|
|
10633
|
+
const root = document.toJS();
|
|
10634
|
+
if (!root || typeof root !== "object" || Array.isArray(root)) continue;
|
|
10635
|
+
const classic = root.classic;
|
|
10636
|
+
if (!classic || typeof classic !== "object" || Array.isArray(classic)) continue;
|
|
10637
|
+
const value = classic[field2];
|
|
10300
10638
|
if (value === null || value === void 0) continue;
|
|
10301
10639
|
return { value: String(value), source: candidate.source };
|
|
10302
10640
|
}
|
|
@@ -10367,7 +10705,7 @@ var GuardOutput = class {
|
|
|
10367
10705
|
};
|
|
10368
10706
|
async function exists4(file) {
|
|
10369
10707
|
try {
|
|
10370
|
-
await
|
|
10708
|
+
await fs18.access(file);
|
|
10371
10709
|
return true;
|
|
10372
10710
|
} catch (error) {
|
|
10373
10711
|
if (error.code === "ENOENT") return false;
|
|
@@ -10376,7 +10714,7 @@ async function exists4(file) {
|
|
|
10376
10714
|
}
|
|
10377
10715
|
async function nonempty(file) {
|
|
10378
10716
|
try {
|
|
10379
|
-
return (await
|
|
10717
|
+
return (await fs18.stat(file)).size > 0;
|
|
10380
10718
|
} catch (error) {
|
|
10381
10719
|
if (error.code === "ENOENT") return false;
|
|
10382
10720
|
throw error;
|
|
@@ -10390,8 +10728,8 @@ async function resolveChangeDir(name) {
|
|
|
10390
10728
|
return (await resolveClassicChangeDirectory(name)).label;
|
|
10391
10729
|
}
|
|
10392
10730
|
async function readField(changeDir, field2) {
|
|
10393
|
-
const file =
|
|
10394
|
-
const document = (0,
|
|
10731
|
+
const file = path19.join(changeDir, ".comet.yaml");
|
|
10732
|
+
const document = (0, import_yaml6.parseDocument)(await fs18.readFile(file, "utf8"), { uniqueKeys: false });
|
|
10395
10733
|
if (document.errors.length > 0) {
|
|
10396
10734
|
throw new GuardFailure(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
|
|
10397
10735
|
}
|
|
@@ -10432,7 +10770,7 @@ function countEnglishWords(source) {
|
|
|
10432
10770
|
}
|
|
10433
10771
|
async function documentLanguageMatchesConfigured(changeDir, file) {
|
|
10434
10772
|
const language = await configuredLanguage(changeDir);
|
|
10435
|
-
const source = stripFencedCodeBlocks(await
|
|
10773
|
+
const source = stripFencedCodeBlocks(await fs18.readFile(file, "utf8"));
|
|
10436
10774
|
const cjk = countCjkChars(source);
|
|
10437
10775
|
const englishWords = countEnglishWords(source);
|
|
10438
10776
|
if (language === "zh-CN" && cjk < 20 && englishWords >= 20) {
|
|
@@ -10456,7 +10794,7 @@ async function handoffSourceFiles(changeDir) {
|
|
|
10456
10794
|
const files = [`${changeDir}/proposal.md`, `${changeDir}/design.md`, `${changeDir}/tasks.md`];
|
|
10457
10795
|
const specs = `${changeDir}/specs`;
|
|
10458
10796
|
if (await exists4(specs)) {
|
|
10459
|
-
for (const entry2 of (await
|
|
10797
|
+
for (const entry2 of (await fs18.readdir(specs)).sort()) {
|
|
10460
10798
|
const spec = `${specs}/${entry2}/spec.md`;
|
|
10461
10799
|
if (await exists4(spec)) files.push(spec);
|
|
10462
10800
|
}
|
|
@@ -10476,7 +10814,7 @@ async function preflight(changeDir, name) {
|
|
|
10476
10814
|
if (!await exists4(changeDir)) {
|
|
10477
10815
|
throw new GuardFailure(red2(`FATAL: change directory not found: ${changeDir}`));
|
|
10478
10816
|
}
|
|
10479
|
-
if (!await exists4(
|
|
10817
|
+
if (!await exists4(path19.join(changeDir, ".comet.yaml"))) {
|
|
10480
10818
|
throw new GuardFailure(red2(`FATAL: .comet.yaml not found in ${changeDir}`));
|
|
10481
10819
|
}
|
|
10482
10820
|
const result5 = await classicValidateCommand([name], { json: false });
|
|
@@ -10546,9 +10884,9 @@ var INFERRED_COMMAND_SOURCES = [
|
|
|
10546
10884
|
"Cargo.toml"
|
|
10547
10885
|
];
|
|
10548
10886
|
async function removedProjectCommandField(field2) {
|
|
10549
|
-
const config =
|
|
10887
|
+
const config = path19.join(".comet", "config.yaml");
|
|
10550
10888
|
if (!await exists4(config)) return false;
|
|
10551
|
-
const document = (0,
|
|
10889
|
+
const document = (0, import_yaml6.parseDocument)(await fs18.readFile(config, "utf8"));
|
|
10552
10890
|
if (document.errors.length > 0) {
|
|
10553
10891
|
throw new Error(
|
|
10554
10892
|
`.comet/config.yaml is invalid YAML (${document.errors[0].message}); cannot check for removed "${field2}" field. Fix the config and retry.`
|
|
@@ -10629,14 +10967,14 @@ ${recoveryCommand(change, scope, recorded.command)}`
|
|
|
10629
10967
|
return { status: 0, output: evidenceDetail(recorded) };
|
|
10630
10968
|
}
|
|
10631
10969
|
async function tasksAllDone(changeDir) {
|
|
10632
|
-
const tasks =
|
|
10970
|
+
const tasks = path19.join(changeDir, "tasks.md");
|
|
10633
10971
|
if (!await exists4(tasks)) {
|
|
10634
10972
|
return fail(
|
|
10635
10973
|
`tasks.md is missing at ${tasks}
|
|
10636
10974
|
Next: restore or create tasks.md for this change before leaving build.`
|
|
10637
10975
|
);
|
|
10638
10976
|
}
|
|
10639
|
-
const source = await
|
|
10977
|
+
const source = await fs18.readFile(tasks, "utf8");
|
|
10640
10978
|
if (!/- \[x\]/u.test(source)) {
|
|
10641
10979
|
return fail(
|
|
10642
10980
|
"tasks.md has no completed tasks.\nNext: complete implementation tasks and mark them with '- [x]'."
|
|
@@ -10653,9 +10991,9 @@ Next: complete or explicitly remove unfinished tasks, then mark tasks.md with '-
|
|
|
10653
10991
|
return pass();
|
|
10654
10992
|
}
|
|
10655
10993
|
async function tasksHasAny(changeDir) {
|
|
10656
|
-
const tasks =
|
|
10994
|
+
const tasks = path19.join(changeDir, "tasks.md");
|
|
10657
10995
|
if (!await exists4(tasks)) return false;
|
|
10658
|
-
return /- \[/u.test(await
|
|
10996
|
+
return /- \[/u.test(await fs18.readFile(tasks, "utf8"));
|
|
10659
10997
|
}
|
|
10660
10998
|
async function planTasksAllDone(changeDir) {
|
|
10661
10999
|
const plan = await readField(changeDir, "plan");
|
|
@@ -10666,7 +11004,7 @@ async function planTasksAllDone(changeDir) {
|
|
|
10666
11004
|
Next: restore the Superpowers plan file or update .comet.yaml plan before leaving build.`
|
|
10667
11005
|
);
|
|
10668
11006
|
}
|
|
10669
|
-
const source = await
|
|
11007
|
+
const source = await fs18.readFile(plan, "utf8");
|
|
10670
11008
|
const unfinished = source.split(/\r?\n/u).map((line, index) => ({ line, number: index + 1 })).filter((entry2) => /^\s*- \[ \]/u.test(entry2.line));
|
|
10671
11009
|
if (unfinished.length > 0) {
|
|
10672
11010
|
return fail(
|
|
@@ -10677,14 +11015,36 @@ Next: check off corresponding completed plan tasks, then commit the plan update.
|
|
|
10677
11015
|
}
|
|
10678
11016
|
return pass();
|
|
10679
11017
|
}
|
|
11018
|
+
async function boundBranchMatches(changeDir, change) {
|
|
11019
|
+
let outcome;
|
|
11020
|
+
try {
|
|
11021
|
+
outcome = await resolveBranchBinding(changeDir, { heal: true, cwd: process.cwd() });
|
|
11022
|
+
} catch (error) {
|
|
11023
|
+
throw new GuardFailure(`ERROR: ${error instanceof Error ? error.message : String(error)}`);
|
|
11024
|
+
}
|
|
11025
|
+
switch (outcome.status) {
|
|
11026
|
+
case "drift":
|
|
11027
|
+
return fail(driftBlockedMessage(change, outcome.boundBranch, outcome.currentBranch));
|
|
11028
|
+
case "unbound-detached":
|
|
11029
|
+
return fail(unboundDetachedMessage(change));
|
|
11030
|
+
case "healed":
|
|
11031
|
+
return pass(`bound_branch lazily set to ${outcome.branch}`);
|
|
11032
|
+
case "needs-heal":
|
|
11033
|
+
case "ok":
|
|
11034
|
+
case "not-applicable":
|
|
11035
|
+
return pass();
|
|
11036
|
+
default: {
|
|
11037
|
+
const exhaustive = outcome;
|
|
11038
|
+
throw new Error(`unhandled branch binding status: ${JSON.stringify(exhaustive)}`);
|
|
11039
|
+
}
|
|
11040
|
+
}
|
|
11041
|
+
}
|
|
10680
11042
|
async function isolationSelected(changeDir, change) {
|
|
10681
11043
|
const isolation = await readField(changeDir, "isolation");
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
if (isolation === "current" && (workflow === "hotfix" || workflow === "tweak")) return pass();
|
|
10685
|
-
const allowedValues = workflow === "full" ? "<branch|worktree>" : "<current|branch|worktree>";
|
|
11044
|
+
if (isolation === "current" || isolation === "branch" || isolation === "worktree") return pass();
|
|
11045
|
+
const allowedValues = "<current|branch|worktree>";
|
|
10686
11046
|
return fail(
|
|
10687
|
-
`isolation must be
|
|
11047
|
+
`isolation must be current, branch, or worktree, got '${isolation || "null"}'
|
|
10688
11048
|
Next: choose a valid workspace mode, prepare it when needed, then run:
|
|
10689
11049
|
comet state set ${change} isolation ${allowedValues}`
|
|
10690
11050
|
);
|
|
@@ -10758,7 +11118,7 @@ async function archivedIsTrue(changeDir) {
|
|
|
10758
11118
|
return await readField(changeDir, "archived") === "true";
|
|
10759
11119
|
}
|
|
10760
11120
|
async function designDocFrontmatterHas(designDoc, field2, expected) {
|
|
10761
|
-
const source = (await
|
|
11121
|
+
const source = (await fs18.readFile(designDoc, "utf8")).replace(/^\uFEFF/u, "");
|
|
10762
11122
|
let inFrontmatter = false;
|
|
10763
11123
|
for (const line of source.split(/\r?\n/u)) {
|
|
10764
11124
|
if (!inFrontmatter) {
|
|
@@ -10823,7 +11183,7 @@ async function designHandoffMarkdownTraceable(changeDir) {
|
|
|
10823
11183
|
const markdown = `${context.replace(/\.json$/u, "")}.md`;
|
|
10824
11184
|
if (!await nonempty(markdown))
|
|
10825
11185
|
return fail(`design handoff markdown is missing or empty: ${markdown}`);
|
|
10826
|
-
const source = await
|
|
11186
|
+
const source = await fs18.readFile(markdown, "utf8");
|
|
10827
11187
|
const problems = [];
|
|
10828
11188
|
if (!/^Generated-by: comet-handoff\.sh$/mu.test(source)) {
|
|
10829
11189
|
problems.push("handoff markdown is missing Generated-by marker");
|
|
@@ -10850,7 +11210,7 @@ async function betaSpecJsonStructurallyValid(changeDir) {
|
|
|
10850
11210
|
const context = await readField(changeDir, "handoff_context");
|
|
10851
11211
|
if (!context || context === "null") return fail("handoff_context is missing from .comet.yaml");
|
|
10852
11212
|
if (!await nonempty(context)) return fail(`spec-context.json is missing or empty: ${context}`);
|
|
10853
|
-
const source = await
|
|
11213
|
+
const source = await fs18.readFile(context, "utf8");
|
|
10854
11214
|
const problems = [];
|
|
10855
11215
|
let parsed;
|
|
10856
11216
|
try {
|
|
@@ -10887,19 +11247,19 @@ async function guardOpenChecks(output, changeDir) {
|
|
|
10887
11247
|
const checks = [
|
|
10888
11248
|
check(
|
|
10889
11249
|
"proposal.md exists and non-empty",
|
|
10890
|
-
async () => await nonempty(
|
|
11250
|
+
async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
|
|
10891
11251
|
),
|
|
10892
11252
|
check(
|
|
10893
11253
|
"proposal.md matches configured language",
|
|
10894
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11254
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
|
|
10895
11255
|
),
|
|
10896
11256
|
check(
|
|
10897
11257
|
"tasks.md exists and non-empty",
|
|
10898
|
-
async () => await nonempty(
|
|
11258
|
+
async () => await nonempty(path19.join(changeDir, "tasks.md")) ? pass() : fail("")
|
|
10899
11259
|
),
|
|
10900
11260
|
check(
|
|
10901
11261
|
"tasks.md matches configured language",
|
|
10902
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11262
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "tasks.md"))
|
|
10903
11263
|
),
|
|
10904
11264
|
check(
|
|
10905
11265
|
"tasks.md has at least one task",
|
|
@@ -10912,11 +11272,11 @@ async function guardOpenChecks(output, changeDir) {
|
|
|
10912
11272
|
0,
|
|
10913
11273
|
check(
|
|
10914
11274
|
"design.md exists and non-empty",
|
|
10915
|
-
async () => await nonempty(
|
|
11275
|
+
async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
|
|
10916
11276
|
),
|
|
10917
11277
|
check(
|
|
10918
11278
|
"design.md matches configured language",
|
|
10919
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11279
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "design.md"))
|
|
10920
11280
|
)
|
|
10921
11281
|
);
|
|
10922
11282
|
}
|
|
@@ -10928,27 +11288,27 @@ async function guardDesignChecks(output, changeDir, change) {
|
|
|
10928
11288
|
const builders = [
|
|
10929
11289
|
check(
|
|
10930
11290
|
"proposal.md exists",
|
|
10931
|
-
async () => await nonempty(
|
|
11291
|
+
async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
|
|
10932
11292
|
),
|
|
10933
11293
|
check(
|
|
10934
11294
|
"proposal.md matches configured language",
|
|
10935
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11295
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
|
|
10936
11296
|
),
|
|
10937
11297
|
check(
|
|
10938
11298
|
"design.md exists",
|
|
10939
|
-
async () => await nonempty(
|
|
11299
|
+
async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
|
|
10940
11300
|
),
|
|
10941
11301
|
check(
|
|
10942
11302
|
"design.md matches configured language",
|
|
10943
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11303
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "design.md"))
|
|
10944
11304
|
),
|
|
10945
11305
|
check(
|
|
10946
11306
|
"tasks.md exists",
|
|
10947
|
-
async () => await nonempty(
|
|
11307
|
+
async () => await nonempty(path19.join(changeDir, "tasks.md")) ? pass() : fail("")
|
|
10948
11308
|
),
|
|
10949
11309
|
check(
|
|
10950
11310
|
"tasks.md matches configured language",
|
|
10951
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11311
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "tasks.md"))
|
|
10952
11312
|
),
|
|
10953
11313
|
check("design handoff context exists", () => designHandoffContextValid(changeDir, change)),
|
|
10954
11314
|
check("design handoff markdown is traceable", () => designHandoffMarkdownTraceable(changeDir))
|
|
@@ -10999,6 +11359,7 @@ async function guardDesignChecks(output, changeDir, change) {
|
|
|
10999
11359
|
}
|
|
11000
11360
|
async function guardBuildChecks(output, changeDir, change, run) {
|
|
11001
11361
|
return runChecks(output, [
|
|
11362
|
+
check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
|
|
11002
11363
|
check("isolation selected", () => isolationSelected(changeDir, change)),
|
|
11003
11364
|
check("build_mode selected", () => buildModeSelected(changeDir, change)),
|
|
11004
11365
|
check("build_mode allowed for workflow", () => buildModeAllowedForWorkflow(changeDir)),
|
|
@@ -11009,11 +11370,11 @@ async function guardBuildChecks(output, changeDir, change, run) {
|
|
|
11009
11370
|
check("Superpowers plan all tasks checked", () => planTasksAllDone(changeDir)),
|
|
11010
11371
|
check(
|
|
11011
11372
|
"proposal.md exists",
|
|
11012
|
-
async () => await nonempty(
|
|
11373
|
+
async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
|
|
11013
11374
|
),
|
|
11014
11375
|
check(
|
|
11015
11376
|
"proposal.md matches configured language",
|
|
11016
|
-
() => documentLanguageMatchesConfigured(changeDir,
|
|
11377
|
+
() => documentLanguageMatchesConfigured(changeDir, path19.join(changeDir, "proposal.md"))
|
|
11017
11378
|
),
|
|
11018
11379
|
check("Superpowers plan matches configured language", async () => {
|
|
11019
11380
|
const plan = await readField(changeDir, "plan");
|
|
@@ -11030,6 +11391,7 @@ async function guardBuildChecks(output, changeDir, change, run) {
|
|
|
11030
11391
|
}
|
|
11031
11392
|
async function guardVerifyChecks(output, changeDir, change, run) {
|
|
11032
11393
|
return runChecks(output, [
|
|
11394
|
+
check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
|
|
11033
11395
|
check("tasks.md all tasks checked", () => tasksAllDone(changeDir)),
|
|
11034
11396
|
// Verification command runs after tasks check — no point running tests
|
|
11035
11397
|
// if tasks.md is incomplete.
|
|
@@ -11048,16 +11410,17 @@ async function guardVerifyChecks(output, changeDir, change, run) {
|
|
|
11048
11410
|
})
|
|
11049
11411
|
]);
|
|
11050
11412
|
}
|
|
11051
|
-
async function guardArchiveChecks(output, changeDir) {
|
|
11413
|
+
async function guardArchiveChecks(output, changeDir, change) {
|
|
11052
11414
|
return runChecks(output, [
|
|
11415
|
+
check("bound branch matches workspace mode", () => boundBranchMatches(changeDir, change)),
|
|
11053
11416
|
check("archived is true", async () => await archivedIsTrue(changeDir) ? pass() : fail("")),
|
|
11054
11417
|
check(
|
|
11055
11418
|
"proposal.md exists",
|
|
11056
|
-
async () => await nonempty(
|
|
11419
|
+
async () => await nonempty(path19.join(changeDir, "proposal.md")) ? pass() : fail("")
|
|
11057
11420
|
),
|
|
11058
11421
|
check(
|
|
11059
11422
|
"design.md exists",
|
|
11060
|
-
async () => await nonempty(
|
|
11423
|
+
async () => await nonempty(path19.join(changeDir, "design.md")) ? pass() : fail("")
|
|
11061
11424
|
),
|
|
11062
11425
|
check("tasks.md all tasks checked", () => tasksAllDone(changeDir)),
|
|
11063
11426
|
check(
|
|
@@ -11066,9 +11429,10 @@ async function guardArchiveChecks(output, changeDir) {
|
|
|
11066
11429
|
)
|
|
11067
11430
|
]);
|
|
11068
11431
|
}
|
|
11069
|
-
async function applyStateUpdate(output, change, changeDir, phase
|
|
11432
|
+
async function applyStateUpdate(output, change, changeDir, phase) {
|
|
11070
11433
|
const event = CLASSIC_GUARD_TRANSITION_EVENT[phase];
|
|
11071
11434
|
if (!event) return;
|
|
11435
|
+
const context = await ensureClassicRuntimeRun(changeDir);
|
|
11072
11436
|
const result5 = applyClassicTransition(context.classic, event);
|
|
11073
11437
|
await transitionClassicRuntimeRun(changeDir, result5.classic, context.run, {
|
|
11074
11438
|
event,
|
|
@@ -11122,7 +11486,7 @@ Valid phases: open, design, build, verify, archive`
|
|
|
11122
11486
|
blocked2 = await guardBuildChecks(output, changeDir, change, runContext.run);
|
|
11123
11487
|
else if (phase === "verify")
|
|
11124
11488
|
blocked2 = await guardVerifyChecks(output, changeDir, change, runContext.run);
|
|
11125
|
-
else blocked2 = await guardArchiveChecks(output, changeDir);
|
|
11489
|
+
else blocked2 = await guardArchiveChecks(output, changeDir, change);
|
|
11126
11490
|
if (blocked2) {
|
|
11127
11491
|
output.stderr.push("");
|
|
11128
11492
|
output.stderr.push(red2("BLOCKED — fix failing checks before proceeding to next phase"));
|
|
@@ -11131,7 +11495,7 @@ Valid phases: open, design, build, verify, archive`
|
|
|
11131
11495
|
output.stderr.push("");
|
|
11132
11496
|
output.stderr.push(green2("ALL CHECKS PASSED — ready for next phase"));
|
|
11133
11497
|
if (flag === "--apply") {
|
|
11134
|
-
await applyStateUpdate(output, change, changeDir, phase
|
|
11498
|
+
await applyStateUpdate(output, change, changeDir, phase);
|
|
11135
11499
|
}
|
|
11136
11500
|
return output.toResult(0);
|
|
11137
11501
|
} catch (error) {
|
|
@@ -11144,10 +11508,10 @@ Valid phases: open, design, build, verify, archive`
|
|
|
11144
11508
|
};
|
|
11145
11509
|
|
|
11146
11510
|
// domains/comet-classic/classic-handoff.ts
|
|
11147
|
-
var
|
|
11511
|
+
var import_yaml7 = __toESM(require_dist(), 1);
|
|
11148
11512
|
import { createHash as createHash5 } from "crypto";
|
|
11149
|
-
import { promises as
|
|
11150
|
-
import
|
|
11513
|
+
import { promises as fs19, readFileSync as readFileSync2 } from "fs";
|
|
11514
|
+
import path20 from "path";
|
|
11151
11515
|
var GREEN4 = "\x1B[32m";
|
|
11152
11516
|
var RED4 = "\x1B[31m";
|
|
11153
11517
|
var YELLOW4 = "\x1B[33m";
|
|
@@ -11181,7 +11545,7 @@ var HandoffOutput = class {
|
|
|
11181
11545
|
};
|
|
11182
11546
|
async function exists5(file) {
|
|
11183
11547
|
try {
|
|
11184
|
-
await
|
|
11548
|
+
await fs19.access(file);
|
|
11185
11549
|
return true;
|
|
11186
11550
|
} catch (error) {
|
|
11187
11551
|
if (error.code === "ENOENT") return false;
|
|
@@ -11190,7 +11554,7 @@ async function exists5(file) {
|
|
|
11190
11554
|
}
|
|
11191
11555
|
async function nonempty2(file) {
|
|
11192
11556
|
try {
|
|
11193
|
-
return (await
|
|
11557
|
+
return (await fs19.stat(file)).size > 0;
|
|
11194
11558
|
} catch (error) {
|
|
11195
11559
|
if (error.code === "ENOENT") return false;
|
|
11196
11560
|
throw error;
|
|
@@ -11219,7 +11583,7 @@ async function handoffSourceFiles2(changeDir) {
|
|
|
11219
11583
|
const files = [`${changeDir}/proposal.md`, `${changeDir}/design.md`, `${changeDir}/tasks.md`];
|
|
11220
11584
|
const specs = `${changeDir}/specs`;
|
|
11221
11585
|
if (await exists5(specs)) {
|
|
11222
|
-
for (const entry2 of (await
|
|
11586
|
+
for (const entry2 of (await fs19.readdir(specs)).sort()) {
|
|
11223
11587
|
const spec = `${specs}/${entry2}/spec.md`;
|
|
11224
11588
|
if (await exists5(spec)) files.push(spec);
|
|
11225
11589
|
}
|
|
@@ -11267,7 +11631,7 @@ async function writeMarkdownContext(changeDir, change, mode, contextHash, output
|
|
|
11267
11631
|
];
|
|
11268
11632
|
for (const file of await handoffSourceFiles2(changeDir)) {
|
|
11269
11633
|
if (!await exists5(file)) continue;
|
|
11270
|
-
const content = await
|
|
11634
|
+
const content = await fs19.readFile(file, "utf8");
|
|
11271
11635
|
const total = lineCount(content);
|
|
11272
11636
|
lines.push(
|
|
11273
11637
|
`## ${file}`,
|
|
@@ -11292,7 +11656,7 @@ async function writeMarkdownContext(changeDir, change, mode, contextHash, output
|
|
|
11292
11656
|
}
|
|
11293
11657
|
lines.push("");
|
|
11294
11658
|
}
|
|
11295
|
-
await
|
|
11659
|
+
await fs19.writeFile(output, lines.join("\n"));
|
|
11296
11660
|
}
|
|
11297
11661
|
async function writeJsonContext(changeDir, change, mode, contextHash, output) {
|
|
11298
11662
|
const entries = [];
|
|
@@ -11315,7 +11679,7 @@ async function writeJsonContext(changeDir, change, mode, contextHash, output) {
|
|
|
11315
11679
|
"}",
|
|
11316
11680
|
""
|
|
11317
11681
|
].join("\n");
|
|
11318
|
-
await
|
|
11682
|
+
await fs19.writeFile(output, document);
|
|
11319
11683
|
}
|
|
11320
11684
|
async function writeSpecProjectionForFile(file, content) {
|
|
11321
11685
|
return [
|
|
@@ -11355,11 +11719,11 @@ async function writeSpecMarkdownContext(changeDir, change, contextHash, output)
|
|
|
11355
11719
|
const specs = `${changeDir}/specs`;
|
|
11356
11720
|
let projected = false;
|
|
11357
11721
|
if (await exists5(specs)) {
|
|
11358
|
-
for (const entry2 of (await
|
|
11722
|
+
for (const entry2 of (await fs19.readdir(specs)).sort()) {
|
|
11359
11723
|
const spec = `${specs}/${entry2}/spec.md`;
|
|
11360
11724
|
if (!await exists5(spec)) continue;
|
|
11361
11725
|
projected = true;
|
|
11362
|
-
lines.push(...await writeSpecProjectionForFile(spec, await
|
|
11726
|
+
lines.push(...await writeSpecProjectionForFile(spec, await fs19.readFile(spec, "utf8")));
|
|
11363
11727
|
}
|
|
11364
11728
|
}
|
|
11365
11729
|
if (!projected) {
|
|
@@ -11368,7 +11732,7 @@ async function writeSpecMarkdownContext(changeDir, change, contextHash, output)
|
|
|
11368
11732
|
lines.push(
|
|
11369
11733
|
"Full source files remain canonical. If a required heading or scenario is missing here, regenerate the handoff or read the source spec directly. Supporting files (proposal, design, tasks) are referenced by hash only."
|
|
11370
11734
|
);
|
|
11371
|
-
await
|
|
11735
|
+
await fs19.writeFile(output, lines.join("\n"));
|
|
11372
11736
|
}
|
|
11373
11737
|
async function writeSpecJsonContext(changeDir, change, contextHash, output) {
|
|
11374
11738
|
const entries = [];
|
|
@@ -11377,7 +11741,7 @@ async function writeSpecJsonContext(changeDir, change, contextHash, output) {
|
|
|
11377
11741
|
const role = /\/specs\/[^/]+\/spec\.md$/u.test(file) ? "spec" : "supporting";
|
|
11378
11742
|
entries.push({ path: file, sha256: hashFile2(file), role });
|
|
11379
11743
|
}
|
|
11380
|
-
await
|
|
11744
|
+
await fs19.writeFile(
|
|
11381
11745
|
output,
|
|
11382
11746
|
`${JSON.stringify(
|
|
11383
11747
|
{
|
|
@@ -11396,8 +11760,8 @@ async function writeSpecJsonContext(changeDir, change, contextHash, output) {
|
|
|
11396
11760
|
);
|
|
11397
11761
|
}
|
|
11398
11762
|
async function readField2(changeDir, field2) {
|
|
11399
|
-
const file =
|
|
11400
|
-
const document = (0,
|
|
11763
|
+
const file = path20.join(changeDir, ".comet.yaml");
|
|
11764
|
+
const document = (0, import_yaml7.parseDocument)(await fs19.readFile(file, "utf8"), { uniqueKeys: false });
|
|
11401
11765
|
if (document.errors.length > 0) {
|
|
11402
11766
|
throw new HandoffFailure(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
|
|
11403
11767
|
}
|
|
@@ -11431,7 +11795,7 @@ async function completedHandoffIsCurrent(changeDir, run, contextHash, contextJso
|
|
|
11431
11795
|
readCheckpoint(changeDir, run.checkpointRef)
|
|
11432
11796
|
]);
|
|
11433
11797
|
if (!await exists5(contextJson) || !await exists5(contextMd)) return false;
|
|
11434
|
-
if (context !== await
|
|
11798
|
+
if (context !== await fs19.readFile(contextMd, "utf8")) return false;
|
|
11435
11799
|
if (artifacts.handoff_context !== contextJson || artifacts.handoff_markdown !== contextMd) {
|
|
11436
11800
|
return false;
|
|
11437
11801
|
}
|
|
@@ -11554,7 +11918,7 @@ var classicHandoffCommand = async (args) => {
|
|
|
11554
11918
|
run: pendingRun,
|
|
11555
11919
|
unknownKeys: (await readClassicState(changeDir)).unknownKeys
|
|
11556
11920
|
});
|
|
11557
|
-
await
|
|
11921
|
+
await fs19.mkdir(handoffDir, { recursive: true });
|
|
11558
11922
|
if (handoffMode === "beta") {
|
|
11559
11923
|
await writeSpecMarkdownContext(changeDir, change, contextHash, contextMd);
|
|
11560
11924
|
await writeSpecJsonContext(changeDir, change, contextHash, contextJson);
|
|
@@ -11562,7 +11926,7 @@ var classicHandoffCommand = async (args) => {
|
|
|
11562
11926
|
await writeMarkdownContext(changeDir, change, handoffMode, contextHash, contextMd);
|
|
11563
11927
|
await writeJsonContext(changeDir, change, handoffMode, contextHash, contextJson);
|
|
11564
11928
|
}
|
|
11565
|
-
const context = await
|
|
11929
|
+
const context = await fs19.readFile(contextMd, "utf8");
|
|
11566
11930
|
await writeContext(changeDir, pendingRun.contextRef, context);
|
|
11567
11931
|
const artifacts = {
|
|
11568
11932
|
...await readArtifacts(changeDir, pendingRun.artifactsRef),
|
|
@@ -11619,140 +11983,8 @@ var classicHandoffCommand = async (args) => {
|
|
|
11619
11983
|
};
|
|
11620
11984
|
|
|
11621
11985
|
// domains/comet-classic/classic-hook-guard.ts
|
|
11622
|
-
import { existsSync as existsSync2, promises as
|
|
11623
|
-
import
|
|
11624
|
-
|
|
11625
|
-
// domains/comet-classic/classic-current-change.ts
|
|
11626
|
-
import { execFileSync } from "child_process";
|
|
11627
|
-
import { randomUUID as randomUUID6 } from "crypto";
|
|
11628
|
-
import { promises as fs17 } from "fs";
|
|
11629
|
-
import path18 from "path";
|
|
11630
|
-
function currentChangeFile(projectRoot2) {
|
|
11631
|
-
return path18.join(projectRoot2, ".comet", "current-change.json");
|
|
11632
|
-
}
|
|
11633
|
-
function currentBranch(projectRoot2) {
|
|
11634
|
-
try {
|
|
11635
|
-
const branch = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
11636
|
-
cwd: projectRoot2,
|
|
11637
|
-
encoding: "utf8",
|
|
11638
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
11639
|
-
}).trim();
|
|
11640
|
-
return branch && branch !== "HEAD" ? branch : null;
|
|
11641
|
-
} catch {
|
|
11642
|
-
return null;
|
|
11643
|
-
}
|
|
11644
|
-
}
|
|
11645
|
-
function changeDirectory(projectRoot2, changeName) {
|
|
11646
|
-
return path18.join(projectRoot2, "openspec", "changes", changeName);
|
|
11647
|
-
}
|
|
11648
|
-
async function validateActiveChange(projectRoot2, changeName) {
|
|
11649
|
-
assertOpenSpecChangeName(changeName);
|
|
11650
|
-
const changeDir = changeDirectory(projectRoot2, changeName);
|
|
11651
|
-
try {
|
|
11652
|
-
await fs17.access(path18.join(changeDir, ".comet.yaml"));
|
|
11653
|
-
} catch (error) {
|
|
11654
|
-
if (error.code === "ENOENT") {
|
|
11655
|
-
throw new Error(
|
|
11656
|
-
`Cannot select current change '${changeName}': active change state not found`,
|
|
11657
|
-
{
|
|
11658
|
-
cause: error
|
|
11659
|
-
}
|
|
11660
|
-
);
|
|
11661
|
-
}
|
|
11662
|
-
throw error;
|
|
11663
|
-
}
|
|
11664
|
-
const projection = await readClassicState(changeDir, { migrate: false });
|
|
11665
|
-
if (!projection.classic) {
|
|
11666
|
-
throw new Error(`Cannot select current change '${changeName}': Classic state is incomplete`);
|
|
11667
|
-
}
|
|
11668
|
-
if (projection.classic.archived) {
|
|
11669
|
-
throw new Error(`Cannot select current change '${changeName}': change is archived`);
|
|
11670
|
-
}
|
|
11671
|
-
}
|
|
11672
|
-
function parseSelection(source) {
|
|
11673
|
-
let value;
|
|
11674
|
-
try {
|
|
11675
|
-
value = JSON.parse(source);
|
|
11676
|
-
} catch (error) {
|
|
11677
|
-
throw new Error(
|
|
11678
|
-
`current change selection contains invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
11679
|
-
{ cause: error }
|
|
11680
|
-
);
|
|
11681
|
-
}
|
|
11682
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
11683
|
-
throw new Error("current change selection must be a JSON object");
|
|
11684
|
-
}
|
|
11685
|
-
const record = value;
|
|
11686
|
-
if (record.version !== 1) {
|
|
11687
|
-
throw new Error("current change selection version must be 1");
|
|
11688
|
-
}
|
|
11689
|
-
if (typeof record.change !== "string") {
|
|
11690
|
-
throw new Error("current change selection change must be a string");
|
|
11691
|
-
}
|
|
11692
|
-
assertOpenSpecChangeName(record.change);
|
|
11693
|
-
if (record.branch !== null && typeof record.branch !== "string") {
|
|
11694
|
-
throw new Error("current change selection branch must be a string or null");
|
|
11695
|
-
}
|
|
11696
|
-
return {
|
|
11697
|
-
version: 1,
|
|
11698
|
-
change: record.change,
|
|
11699
|
-
branch: record.branch
|
|
11700
|
-
};
|
|
11701
|
-
}
|
|
11702
|
-
async function selectCurrentChange(projectRoot2, changeName) {
|
|
11703
|
-
await validateActiveChange(projectRoot2, changeName);
|
|
11704
|
-
const selection = {
|
|
11705
|
-
version: 1,
|
|
11706
|
-
change: changeName,
|
|
11707
|
-
branch: currentBranch(projectRoot2)
|
|
11708
|
-
};
|
|
11709
|
-
const file = currentChangeFile(projectRoot2);
|
|
11710
|
-
const temporary = `${file}.${randomUUID6()}.tmp`;
|
|
11711
|
-
await fs17.mkdir(path18.dirname(file), { recursive: true });
|
|
11712
|
-
try {
|
|
11713
|
-
await fs17.writeFile(temporary, JSON.stringify(selection, null, 2) + "\n", "utf8");
|
|
11714
|
-
await fs17.rename(temporary, file);
|
|
11715
|
-
} catch (error) {
|
|
11716
|
-
await fs17.rm(temporary, { force: true });
|
|
11717
|
-
throw error;
|
|
11718
|
-
}
|
|
11719
|
-
return selection;
|
|
11720
|
-
}
|
|
11721
|
-
async function resolveCurrentChange(projectRoot2) {
|
|
11722
|
-
let source;
|
|
11723
|
-
try {
|
|
11724
|
-
source = await fs17.readFile(currentChangeFile(projectRoot2), "utf8");
|
|
11725
|
-
} catch (error) {
|
|
11726
|
-
if (error.code === "ENOENT") return { status: "missing" };
|
|
11727
|
-
return {
|
|
11728
|
-
status: "stale",
|
|
11729
|
-
reason: `cannot read current change selection: ${error instanceof Error ? error.message : String(error)}`
|
|
11730
|
-
};
|
|
11731
|
-
}
|
|
11732
|
-
let selection;
|
|
11733
|
-
try {
|
|
11734
|
-
selection = parseSelection(source);
|
|
11735
|
-
await validateActiveChange(projectRoot2, selection.change);
|
|
11736
|
-
} catch (error) {
|
|
11737
|
-
return {
|
|
11738
|
-
status: "stale",
|
|
11739
|
-
reason: error instanceof Error ? error.message : String(error)
|
|
11740
|
-
};
|
|
11741
|
-
}
|
|
11742
|
-
const branch = currentBranch(projectRoot2);
|
|
11743
|
-
if (selection.branch !== null && branch !== selection.branch) {
|
|
11744
|
-
return {
|
|
11745
|
-
status: "stale",
|
|
11746
|
-
reason: `current change '${selection.change}' was selected on branch '${selection.branch}', current branch is '${branch ?? "detached HEAD"}'`
|
|
11747
|
-
};
|
|
11748
|
-
}
|
|
11749
|
-
return { status: "selected", selection };
|
|
11750
|
-
}
|
|
11751
|
-
async function clearCurrentChange(projectRoot2) {
|
|
11752
|
-
await fs17.rm(currentChangeFile(projectRoot2), { force: true });
|
|
11753
|
-
}
|
|
11754
|
-
|
|
11755
|
-
// domains/comet-classic/classic-hook-guard.ts
|
|
11986
|
+
import { existsSync as existsSync2, promises as fs20, readFileSync as readFileSync3 } from "fs";
|
|
11987
|
+
import path21 from "path";
|
|
11756
11988
|
function result(exitCode, message) {
|
|
11757
11989
|
return { exitCode, stderr: message + "\n" };
|
|
11758
11990
|
}
|
|
@@ -11781,52 +12013,52 @@ function comparisonKey(value) {
|
|
|
11781
12013
|
function parseProjectRoot(args) {
|
|
11782
12014
|
const index = args.indexOf("--project-root");
|
|
11783
12015
|
const value = index >= 0 ? args[index + 1] : void 0;
|
|
11784
|
-
return
|
|
12016
|
+
return path21.resolve(value && !value.startsWith("--") ? value : process.cwd());
|
|
11785
12017
|
}
|
|
11786
12018
|
function relativeToProjectRoot(target, projectRoot2) {
|
|
11787
|
-
const relative = normalized(
|
|
12019
|
+
const relative = normalized(path21.relative(projectRoot2, target));
|
|
11788
12020
|
if (relative === "") return "";
|
|
11789
|
-
if (relative.startsWith("../") || relative === ".." ||
|
|
12021
|
+
if (relative.startsWith("../") || relative === ".." || path21.isAbsolute(relative)) return null;
|
|
11790
12022
|
return relative;
|
|
11791
12023
|
}
|
|
11792
12024
|
async function physicalPathForPossiblyMissingTarget(target) {
|
|
11793
|
-
const resolved =
|
|
11794
|
-
const root =
|
|
12025
|
+
const resolved = path21.resolve(target);
|
|
12026
|
+
const root = path21.parse(resolved).root;
|
|
11795
12027
|
const missingSegments = [];
|
|
11796
12028
|
let cursor = resolved;
|
|
11797
12029
|
while (cursor && cursor !== root) {
|
|
11798
12030
|
try {
|
|
11799
|
-
const physicalBase = await
|
|
11800
|
-
return
|
|
12031
|
+
const physicalBase = await fs20.realpath(cursor);
|
|
12032
|
+
return path21.join(physicalBase, ...missingSegments.reverse());
|
|
11801
12033
|
} catch (error) {
|
|
11802
12034
|
const code = error.code;
|
|
11803
12035
|
if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
|
|
11804
|
-
missingSegments.push(
|
|
11805
|
-
cursor =
|
|
12036
|
+
missingSegments.push(path21.basename(cursor));
|
|
12037
|
+
cursor = path21.dirname(cursor);
|
|
11806
12038
|
}
|
|
11807
12039
|
}
|
|
11808
12040
|
try {
|
|
11809
|
-
const physicalRoot = await
|
|
11810
|
-
return
|
|
12041
|
+
const physicalRoot = await fs20.realpath(root);
|
|
12042
|
+
return path21.join(physicalRoot, ...missingSegments.reverse());
|
|
11811
12043
|
} catch {
|
|
11812
12044
|
return null;
|
|
11813
12045
|
}
|
|
11814
12046
|
}
|
|
11815
12047
|
async function projectRelative(target, projectRoot2) {
|
|
11816
|
-
const rawCandidate =
|
|
12048
|
+
const rawCandidate = path21.isAbsolute(target) ? target : path21.resolve(process.cwd(), target);
|
|
11817
12049
|
let candidate = normalized(rawCandidate);
|
|
11818
12050
|
const rootRelative = relativeToProjectRoot(rawCandidate, projectRoot2);
|
|
11819
12051
|
if (rootRelative !== null) return rootRelative;
|
|
11820
12052
|
try {
|
|
11821
12053
|
const physicalCandidate = await physicalPathForPossiblyMissingTarget(rawCandidate);
|
|
11822
|
-
const physicalRoot = await
|
|
12054
|
+
const physicalRoot = await fs20.realpath(projectRoot2);
|
|
11823
12055
|
if (physicalCandidate) {
|
|
11824
12056
|
const physicalRootRelative = relativeToProjectRoot(physicalCandidate, physicalRoot);
|
|
11825
12057
|
if (physicalRootRelative !== null) return physicalRootRelative;
|
|
11826
12058
|
candidate = normalized(physicalCandidate);
|
|
11827
12059
|
}
|
|
11828
12060
|
} catch {
|
|
11829
|
-
if (!
|
|
12061
|
+
if (!path21.isAbsolute(target)) return normalized(target).replace(/^\.\//u, "");
|
|
11830
12062
|
}
|
|
11831
12063
|
return candidate.replace(/^\.\//u, "");
|
|
11832
12064
|
}
|
|
@@ -11856,15 +12088,15 @@ async function loadGoverningChange(changeDir) {
|
|
|
11856
12088
|
}
|
|
11857
12089
|
}
|
|
11858
12090
|
async function activeChanges(projectRoot2) {
|
|
11859
|
-
const changesDir =
|
|
12091
|
+
const changesDir = path21.join(projectRoot2, "openspec", "changes");
|
|
11860
12092
|
const governingChanges = [];
|
|
11861
12093
|
if (!existsSync2(changesDir)) return governingChanges;
|
|
11862
|
-
for (const entry2 of (await
|
|
12094
|
+
for (const entry2 of (await fs20.readdir(changesDir, { withFileTypes: true })).sort(
|
|
11863
12095
|
(left, right) => left.name.localeCompare(right.name)
|
|
11864
12096
|
)) {
|
|
11865
12097
|
if (!entry2.isDirectory() || entry2.name === "archive") continue;
|
|
11866
|
-
const changeDir =
|
|
11867
|
-
if (!existsSync2(
|
|
12098
|
+
const changeDir = path21.join(changesDir, entry2.name);
|
|
12099
|
+
if (!existsSync2(path21.join(changeDir, ".comet.yaml"))) continue;
|
|
11868
12100
|
const governing = await loadGoverningChange(changeDir);
|
|
11869
12101
|
if (!governing || governing.archived) continue;
|
|
11870
12102
|
governingChanges.push(governing);
|
|
@@ -11912,7 +12144,7 @@ function allowsSuperpowersArtifacts(governing) {
|
|
|
11912
12144
|
return governing.phase === "design" || governing.phase === "build" || governing.phase === "verify";
|
|
11913
12145
|
}
|
|
11914
12146
|
function governingChangeName(governing) {
|
|
11915
|
-
return governing.changeDir ?
|
|
12147
|
+
return governing.changeDir ? path21.basename(governing.changeDir) : null;
|
|
11916
12148
|
}
|
|
11917
12149
|
var SUPERPOWERS_ARTIFACT_SUFFIXES = /* @__PURE__ */ new Set([
|
|
11918
12150
|
"design",
|
|
@@ -11959,9 +12191,20 @@ async function superpowersArtifactGoverningChange(relativePath2, projectRoot2) {
|
|
|
11959
12191
|
if (named) return { governing: named, match: "named" };
|
|
11960
12192
|
return null;
|
|
11961
12193
|
}
|
|
11962
|
-
async function repoSourceGoverningChange(projectRoot2, relativePath2) {
|
|
12194
|
+
async function repoSourceGoverningChange(projectRoot2, relativePath2, selectedChangeName) {
|
|
11963
12195
|
const active = await activeChanges(projectRoot2);
|
|
11964
12196
|
if (active.length === 0) return null;
|
|
12197
|
+
if (selectedChangeName) {
|
|
12198
|
+
const selected = active.find(
|
|
12199
|
+
(governing) => governingChangeName(governing) === selectedChangeName
|
|
12200
|
+
);
|
|
12201
|
+
return selected ?? {
|
|
12202
|
+
blockedResult: blockedStaleSelection(
|
|
12203
|
+
relativePath2,
|
|
12204
|
+
`selected change '${selectedChangeName}' is no longer active`
|
|
12205
|
+
)
|
|
12206
|
+
};
|
|
12207
|
+
}
|
|
11965
12208
|
const current = await resolveCurrentChange(projectRoot2);
|
|
11966
12209
|
if (current.status === "stale") {
|
|
11967
12210
|
return { blockedResult: blockedStaleSelection(relativePath2, current.reason) };
|
|
@@ -11978,7 +12221,30 @@ async function repoSourceGoverningChange(projectRoot2, relativePath2) {
|
|
|
11978
12221
|
)
|
|
11979
12222
|
};
|
|
11980
12223
|
}
|
|
11981
|
-
if (active.length === 1)
|
|
12224
|
+
if (active.length === 1) {
|
|
12225
|
+
const sole = active[0];
|
|
12226
|
+
if (sole.changeDir !== null) {
|
|
12227
|
+
const outcome = await resolveBranchBinding(sole.changeDir, {
|
|
12228
|
+
heal: false,
|
|
12229
|
+
cwd: projectRoot2
|
|
12230
|
+
});
|
|
12231
|
+
const name = governingChangeName(sole) ?? "unknown";
|
|
12232
|
+
if (outcome.status === "drift") {
|
|
12233
|
+
return {
|
|
12234
|
+
blockedResult: blockedStaleSelection(
|
|
12235
|
+
relativePath2,
|
|
12236
|
+
driftStaleReason(name, outcome.boundBranch, outcome.currentBranch)
|
|
12237
|
+
)
|
|
12238
|
+
};
|
|
12239
|
+
}
|
|
12240
|
+
if (outcome.status === "unbound-detached") {
|
|
12241
|
+
return {
|
|
12242
|
+
blockedResult: blockedStaleSelection(relativePath2, unboundDetachedMessage(name))
|
|
12243
|
+
};
|
|
12244
|
+
}
|
|
12245
|
+
}
|
|
12246
|
+
return sole;
|
|
12247
|
+
}
|
|
11982
12248
|
return {
|
|
11983
12249
|
blockedResult: blockedMultipleChanges(
|
|
11984
12250
|
relativePath2,
|
|
@@ -11986,14 +12252,14 @@ async function repoSourceGoverningChange(projectRoot2, relativePath2) {
|
|
|
11986
12252
|
)
|
|
11987
12253
|
};
|
|
11988
12254
|
}
|
|
11989
|
-
async function governingChange(relativePath2, projectRoot2) {
|
|
12255
|
+
async function governingChange(relativePath2, projectRoot2, selectedChangeName) {
|
|
11990
12256
|
const prefix = "openspec/changes/";
|
|
11991
12257
|
if (relativePath2.startsWith(prefix)) {
|
|
11992
12258
|
const rest = relativePath2.slice(prefix.length);
|
|
11993
12259
|
const [name] = rest.split("/");
|
|
11994
12260
|
if (name && name !== "archive") {
|
|
11995
|
-
const changeDir =
|
|
11996
|
-
const stateFile2 =
|
|
12261
|
+
const changeDir = path21.join(projectRoot2, "openspec", "changes", name);
|
|
12262
|
+
const stateFile2 = path21.join(changeDir, ".comet.yaml");
|
|
11997
12263
|
if (existsSync2(stateFile2)) {
|
|
11998
12264
|
const governing = await loadGoverningChange(changeDir);
|
|
11999
12265
|
if (governing) return governing;
|
|
@@ -12016,7 +12282,11 @@ async function governingChange(relativePath2, projectRoot2) {
|
|
|
12016
12282
|
} : { ...superpowers.governing, superpowersArtifact: "matched" };
|
|
12017
12283
|
}
|
|
12018
12284
|
if (slot) {
|
|
12019
|
-
const candidate = await repoSourceGoverningChange(
|
|
12285
|
+
const candidate = await repoSourceGoverningChange(
|
|
12286
|
+
projectRoot2,
|
|
12287
|
+
relativePath2,
|
|
12288
|
+
selectedChangeName
|
|
12289
|
+
);
|
|
12020
12290
|
if (!candidate || "blockedResult" in candidate) return candidate;
|
|
12021
12291
|
return {
|
|
12022
12292
|
...candidate,
|
|
@@ -12024,10 +12294,11 @@ async function governingChange(relativePath2, projectRoot2) {
|
|
|
12024
12294
|
superpowersSlot: slot
|
|
12025
12295
|
};
|
|
12026
12296
|
}
|
|
12027
|
-
const
|
|
12297
|
+
const active = await activeChanges(projectRoot2);
|
|
12298
|
+
const fallback = selectedChangeName ? active.find((candidate) => governingChangeName(candidate) === selectedChangeName) ?? null : active[0] ?? null;
|
|
12028
12299
|
return fallback ? { ...fallback, superpowersArtifact: "unmatched" } : null;
|
|
12029
12300
|
}
|
|
12030
|
-
return repoSourceGoverningChange(projectRoot2, relativePath2);
|
|
12301
|
+
return repoSourceGoverningChange(projectRoot2, relativePath2, selectedChangeName);
|
|
12031
12302
|
}
|
|
12032
12303
|
function isRootMarkdown(relativePath2) {
|
|
12033
12304
|
return !relativePath2.includes("/") && relativePath2.endsWith(".md");
|
|
@@ -12183,10 +12454,7 @@ function blockedStaleSelection(relativePath2, reason) {
|
|
|
12183
12454
|
].join("\n")
|
|
12184
12455
|
);
|
|
12185
12456
|
}
|
|
12186
|
-
|
|
12187
|
-
const projectRoot2 = parseProjectRoot(args);
|
|
12188
|
-
const target = inputTarget();
|
|
12189
|
-
if (!target) return allowed("no file path in tool input");
|
|
12457
|
+
async function inspectClassicHookTarget(projectRoot2, target, selectedChangeName) {
|
|
12190
12458
|
const relativePath2 = await projectRelative(target, projectRoot2);
|
|
12191
12459
|
if (isCometConfig(relativePath2)) {
|
|
12192
12460
|
return allowed(`${relativePath2} (whitelist: comet config)`);
|
|
@@ -12202,7 +12470,7 @@ var classicHookGuardCommand = async (args) => {
|
|
|
12202
12470
|
}
|
|
12203
12471
|
let governing;
|
|
12204
12472
|
try {
|
|
12205
|
-
governing = await governingChange(relativePath2, projectRoot2);
|
|
12473
|
+
governing = await governingChange(relativePath2, projectRoot2, selectedChangeName);
|
|
12206
12474
|
} catch (error) {
|
|
12207
12475
|
return result(
|
|
12208
12476
|
2,
|
|
@@ -12230,6 +12498,12 @@ var classicHookGuardCommand = async (args) => {
|
|
|
12230
12498
|
return allowed(`${relativePath2} (phase: ${phase})`);
|
|
12231
12499
|
}
|
|
12232
12500
|
return blocked(relativePath2, phase);
|
|
12501
|
+
}
|
|
12502
|
+
var classicHookGuardCommand = async (args) => {
|
|
12503
|
+
const projectRoot2 = parseProjectRoot(args);
|
|
12504
|
+
const target = inputTarget();
|
|
12505
|
+
if (!target) return allowed("no file path in tool input");
|
|
12506
|
+
return inspectClassicHookTarget(projectRoot2, target);
|
|
12233
12507
|
};
|
|
12234
12508
|
|
|
12235
12509
|
// domains/comet-classic/classic-intent.ts
|
|
@@ -12285,7 +12559,7 @@ ${issues.map((issue) => `- ${issue}`).join("\n")}`);
|
|
|
12285
12559
|
}
|
|
12286
12560
|
issues;
|
|
12287
12561
|
};
|
|
12288
|
-
function
|
|
12562
|
+
function isRecord2(value) {
|
|
12289
12563
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12290
12564
|
}
|
|
12291
12565
|
function enumValue2(value, allowed2, field2, issues) {
|
|
@@ -12338,15 +12612,15 @@ function nonNegativeIntegerValue(value, field2, issues) {
|
|
|
12338
12612
|
}
|
|
12339
12613
|
function validateFrame(input) {
|
|
12340
12614
|
const issues = [];
|
|
12341
|
-
if (!
|
|
12342
|
-
const intent =
|
|
12343
|
-
if (!
|
|
12344
|
-
const slots =
|
|
12345
|
-
if (!
|
|
12346
|
-
const context =
|
|
12347
|
-
if (!
|
|
12348
|
-
const proposedRouteInput =
|
|
12349
|
-
if (!
|
|
12615
|
+
if (!isRecord2(input)) throw new CometIntentValidationError(["frame must be an object"]);
|
|
12616
|
+
const intent = isRecord2(input.intent) ? input.intent : {};
|
|
12617
|
+
if (!isRecord2(input.intent)) issues.push("intent must be an object");
|
|
12618
|
+
const slots = isRecord2(input.slots) ? input.slots : {};
|
|
12619
|
+
if (!isRecord2(input.slots)) issues.push("slots must be an object");
|
|
12620
|
+
const context = isRecord2(input.context) ? input.context : {};
|
|
12621
|
+
if (!isRecord2(input.context)) issues.push("context must be an object");
|
|
12622
|
+
const proposedRouteInput = isRecord2(input.proposed_route) ? input.proposed_route : {};
|
|
12623
|
+
if (!isRecord2(input.proposed_route)) issues.push("proposed_route must be an object");
|
|
12350
12624
|
const entities = input.entities === void 0 ? [] : Array.isArray(input.entities) ? input.entities : [];
|
|
12351
12625
|
if (input.entities !== void 0 && !Array.isArray(input.entities)) {
|
|
12352
12626
|
issues.push("entities must be an array");
|
|
@@ -12367,8 +12641,8 @@ function validateFrame(input) {
|
|
|
12367
12641
|
confidence: confidenceValue(intent.confidence, "intent.confidence", issues)
|
|
12368
12642
|
},
|
|
12369
12643
|
entities: entities.map((entity, index) => {
|
|
12370
|
-
const record =
|
|
12371
|
-
if (!
|
|
12644
|
+
const record = isRecord2(entity) ? entity : {};
|
|
12645
|
+
if (!isRecord2(entity)) issues.push(`entities[${index}] must be an object`);
|
|
12372
12646
|
return {
|
|
12373
12647
|
type: enumValue2(record.type, ENTITY_TYPES, `entities[${index}].type`, issues) ?? "risk_signal",
|
|
12374
12648
|
value: stringValue(record.value, `entities[${index}].value`, issues),
|
|
@@ -12416,7 +12690,7 @@ function validateFrame(input) {
|
|
|
12416
12690
|
"context.active_changes_count",
|
|
12417
12691
|
issues
|
|
12418
12692
|
),
|
|
12419
|
-
active_change_names:
|
|
12693
|
+
active_change_names: isRecord2(context) ? (() => {
|
|
12420
12694
|
if (!Array.isArray(context.active_change_names)) {
|
|
12421
12695
|
issues.push("context.active_change_names must be an array");
|
|
12422
12696
|
return [];
|
|
@@ -12434,8 +12708,8 @@ function validateFrame(input) {
|
|
|
12434
12708
|
)
|
|
12435
12709
|
},
|
|
12436
12710
|
evidence: evidence.map((item, index) => {
|
|
12437
|
-
const record =
|
|
12438
|
-
if (!
|
|
12711
|
+
const record = isRecord2(item) ? item : {};
|
|
12712
|
+
if (!isRecord2(item)) issues.push(`evidence[${index}] must be an object`);
|
|
12439
12713
|
return {
|
|
12440
12714
|
field: stringValue(record.field, `evidence[${index}].field`, issues),
|
|
12441
12715
|
quote: stringValue(record.quote, `evidence[${index}].quote`, issues),
|
|
@@ -12601,15 +12875,15 @@ var classicIntentCommand = async (args, _options) => {
|
|
|
12601
12875
|
};
|
|
12602
12876
|
|
|
12603
12877
|
// domains/comet-classic/classic-resume-probe.ts
|
|
12604
|
-
import
|
|
12605
|
-
import { promises as
|
|
12878
|
+
import path22 from "path";
|
|
12879
|
+
import { promises as fs21 } from "fs";
|
|
12606
12880
|
import { spawn } from "child_process";
|
|
12607
12881
|
var COMET_RESUME_PROBE_SCHEMA_VERSION = "comet.resume_probe.v1";
|
|
12608
|
-
function
|
|
12882
|
+
function isRecord3(value) {
|
|
12609
12883
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12610
12884
|
}
|
|
12611
12885
|
function normalizeInput(input) {
|
|
12612
|
-
if (!
|
|
12886
|
+
if (!isRecord3(input)) {
|
|
12613
12887
|
throw new Error("Invalid CometResumeProbeInput: input must be an object");
|
|
12614
12888
|
}
|
|
12615
12889
|
if (input.schema_version !== COMET_RESUME_PROBE_SCHEMA_VERSION) {
|
|
@@ -12620,7 +12894,7 @@ function normalizeInput(input) {
|
|
|
12620
12894
|
if (typeof input.utterance !== "string") {
|
|
12621
12895
|
throw new Error("Invalid CometResumeProbeInput: utterance must be a string");
|
|
12622
12896
|
}
|
|
12623
|
-
const context =
|
|
12897
|
+
const context = isRecord3(input.agent_context) ? input.agent_context : {};
|
|
12624
12898
|
return {
|
|
12625
12899
|
schema_version: COMET_RESUME_PROBE_SCHEMA_VERSION,
|
|
12626
12900
|
utterance: input.utterance,
|
|
@@ -12645,13 +12919,13 @@ function result3(action, change, confidence, reason, evidence = []) {
|
|
|
12645
12919
|
}
|
|
12646
12920
|
async function readIfExists(filePath) {
|
|
12647
12921
|
if (!await fileExists3(filePath)) return "";
|
|
12648
|
-
return
|
|
12922
|
+
return fs21.readFile(filePath, "utf8");
|
|
12649
12923
|
}
|
|
12650
12924
|
async function changeSearchText(changeDir, classic) {
|
|
12651
12925
|
const files = ["proposal.md", "design.md", "tasks.md"];
|
|
12652
12926
|
const parts = [classic.name, classic.workflow, classic.phase];
|
|
12653
12927
|
for (const file of files) {
|
|
12654
|
-
parts.push(await readIfExists(
|
|
12928
|
+
parts.push(await readIfExists(path22.join(changeDir, file)));
|
|
12655
12929
|
}
|
|
12656
12930
|
return parts.join("\n").toLowerCase();
|
|
12657
12931
|
}
|
|
@@ -12715,19 +12989,19 @@ function diagnosticFromProjection(changeDir, name, projection) {
|
|
|
12715
12989
|
};
|
|
12716
12990
|
}
|
|
12717
12991
|
async function hasOpenSpecChangeFiles(changeDir) {
|
|
12718
|
-
return await fileExists3(
|
|
12992
|
+
return await fileExists3(path22.join(changeDir, "proposal.md")) || await fileExists3(path22.join(changeDir, "design.md")) || await fileExists3(path22.join(changeDir, "tasks.md"));
|
|
12719
12993
|
}
|
|
12720
12994
|
async function discoverActiveChanges(projectRoot2) {
|
|
12721
|
-
const changesDir =
|
|
12995
|
+
const changesDir = path22.join(projectRoot2, "openspec", "changes");
|
|
12722
12996
|
if (!await fileExists3(changesDir)) return [];
|
|
12723
12997
|
const entries = await readDir(changesDir);
|
|
12724
12998
|
const changes = [];
|
|
12725
12999
|
for (const entry2 of entries) {
|
|
12726
13000
|
if (entry2 === "archive") continue;
|
|
12727
|
-
const changeDir =
|
|
12728
|
-
const stat = await
|
|
13001
|
+
const changeDir = path22.join(changesDir, entry2);
|
|
13002
|
+
const stat = await fs21.stat(changeDir).catch(() => null);
|
|
12729
13003
|
if (!stat?.isDirectory()) continue;
|
|
12730
|
-
const hasCometState = await fileExists3(
|
|
13004
|
+
const hasCometState = await fileExists3(path22.join(changeDir, ".comet.yaml"));
|
|
12731
13005
|
if (!hasCometState) {
|
|
12732
13006
|
if (!await hasOpenSpecChangeFiles(changeDir)) continue;
|
|
12733
13007
|
const missingStateChange = {
|
|
@@ -13027,11 +13301,11 @@ var classicResumeProbeCommand = async (args) => {
|
|
|
13027
13301
|
};
|
|
13028
13302
|
|
|
13029
13303
|
// domains/comet-classic/classic-state-command.ts
|
|
13030
|
-
var
|
|
13304
|
+
var import_yaml8 = __toESM(require_dist(), 1);
|
|
13031
13305
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
13032
|
-
import { randomUUID as
|
|
13033
|
-
import { existsSync as existsSync3, promises as
|
|
13034
|
-
import
|
|
13306
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
13307
|
+
import { existsSync as existsSync3, promises as fs22 } from "fs";
|
|
13308
|
+
import path23 from "path";
|
|
13035
13309
|
init_state();
|
|
13036
13310
|
var GREEN5 = "\x1B[32m";
|
|
13037
13311
|
var RED5 = "\x1B[31m";
|
|
@@ -13046,7 +13320,8 @@ var MACHINE_OWNED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
13046
13320
|
"archive_confirmation",
|
|
13047
13321
|
"verify_failures",
|
|
13048
13322
|
"classic_profile",
|
|
13049
|
-
"classic_migration"
|
|
13323
|
+
"classic_migration",
|
|
13324
|
+
"bound_branch"
|
|
13050
13325
|
]);
|
|
13051
13326
|
var SETTABLE_FIELDS = new Set(
|
|
13052
13327
|
CLASSIC_WIRE_KEYS.filter((field2) => !MACHINE_OWNED_FIELDS.has(field2))
|
|
@@ -13144,7 +13419,7 @@ function validateRelativePath(value, field2) {
|
|
|
13144
13419
|
}
|
|
13145
13420
|
async function exists6(file) {
|
|
13146
13421
|
try {
|
|
13147
|
-
await
|
|
13422
|
+
await fs22.access(file);
|
|
13148
13423
|
return true;
|
|
13149
13424
|
} catch (error) {
|
|
13150
13425
|
if (error.code === "ENOENT") return false;
|
|
@@ -13153,7 +13428,7 @@ async function exists6(file) {
|
|
|
13153
13428
|
}
|
|
13154
13429
|
async function nonempty3(file) {
|
|
13155
13430
|
try {
|
|
13156
|
-
return (await
|
|
13431
|
+
return (await fs22.stat(file)).size > 0;
|
|
13157
13432
|
} catch (error) {
|
|
13158
13433
|
if (error.code === "ENOENT") return false;
|
|
13159
13434
|
throw error;
|
|
@@ -13165,27 +13440,27 @@ async function changeDirectory2(name) {
|
|
|
13165
13440
|
async function readDocument2(file) {
|
|
13166
13441
|
let source;
|
|
13167
13442
|
try {
|
|
13168
|
-
source = await
|
|
13443
|
+
source = await fs22.readFile(file, "utf8");
|
|
13169
13444
|
} catch (error) {
|
|
13170
13445
|
if (error.code === "ENOENT") {
|
|
13171
13446
|
fail2(
|
|
13172
|
-
`ERROR: .comet.yaml not found at ${
|
|
13447
|
+
`ERROR: .comet.yaml not found at ${path23.relative(process.cwd(), file).replaceAll("\\", "/")}`
|
|
13173
13448
|
);
|
|
13174
13449
|
}
|
|
13175
13450
|
throw error;
|
|
13176
13451
|
}
|
|
13177
|
-
const document = (0,
|
|
13452
|
+
const document = (0, import_yaml8.parseDocument)(source, { uniqueKeys: false });
|
|
13178
13453
|
if (document.errors.length > 0) fail2(`ERROR: Invalid .comet.yaml: ${document.errors[0].message}`);
|
|
13179
13454
|
return document;
|
|
13180
13455
|
}
|
|
13181
13456
|
async function atomicWrite2(file, content) {
|
|
13182
|
-
await
|
|
13183
|
-
const temporary = `${file}.${
|
|
13457
|
+
await fs22.mkdir(path23.dirname(file), { recursive: true });
|
|
13458
|
+
const temporary = `${file}.${randomUUID8()}.tmp`;
|
|
13184
13459
|
try {
|
|
13185
|
-
await
|
|
13186
|
-
await
|
|
13460
|
+
await fs22.writeFile(temporary, content, "utf8");
|
|
13461
|
+
await fs22.rename(temporary, file);
|
|
13187
13462
|
} catch (error) {
|
|
13188
|
-
await
|
|
13463
|
+
await fs22.rm(temporary, { force: true });
|
|
13189
13464
|
throw error;
|
|
13190
13465
|
}
|
|
13191
13466
|
}
|
|
@@ -13255,6 +13530,7 @@ function sparseClassicState(record) {
|
|
|
13255
13530
|
["current", "branch", "worktree"],
|
|
13256
13531
|
null
|
|
13257
13532
|
),
|
|
13533
|
+
boundBranch: nullableRecordString(record, "bound_branch"),
|
|
13258
13534
|
verifyMode: enumRecordValue(record, "verify_mode", ["light", "full"], null),
|
|
13259
13535
|
autoTransition: nullableRecordBoolean(record, "auto_transition"),
|
|
13260
13536
|
baseRef: nullableRecordString(record, "base_ref"),
|
|
@@ -13327,7 +13603,7 @@ async function stateFile(name) {
|
|
|
13327
13603
|
const change = await changeDirectory2(name);
|
|
13328
13604
|
return {
|
|
13329
13605
|
...change,
|
|
13330
|
-
file:
|
|
13606
|
+
file: path23.join(change.directory, ".comet.yaml")
|
|
13331
13607
|
};
|
|
13332
13608
|
}
|
|
13333
13609
|
async function readField3(name, field2) {
|
|
@@ -13345,7 +13621,7 @@ async function readField3(name, field2) {
|
|
|
13345
13621
|
return scalar(value);
|
|
13346
13622
|
}
|
|
13347
13623
|
function parsedValue(field2, value) {
|
|
13348
|
-
const document = (0,
|
|
13624
|
+
const document = (0, import_yaml8.parseDocument)(`${field2}: ${value}
|
|
13349
13625
|
`);
|
|
13350
13626
|
if (document.errors.length > 0) fail2(`ERROR: Invalid value: '${value}'`);
|
|
13351
13627
|
return document.get(field2);
|
|
@@ -13380,7 +13656,35 @@ async function setField2(output, name, field2, value, options = {}) {
|
|
|
13380
13656
|
validateSetValue(field2, value);
|
|
13381
13657
|
const { file, directory } = await stateFile(name);
|
|
13382
13658
|
const document = await readDocument2(file);
|
|
13659
|
+
const previousRecord = document.toJS() ?? {};
|
|
13383
13660
|
document.set(field2, parsedValue(field2, value));
|
|
13661
|
+
if (field2 === "isolation") {
|
|
13662
|
+
if (requiresBranchBinding(value)) {
|
|
13663
|
+
const previousIsolation = typeof previousRecord.isolation === "string" ? previousRecord.isolation : null;
|
|
13664
|
+
const existing = previousRecord.bound_branch;
|
|
13665
|
+
const alreadyBound = typeof existing === "string" && existing !== "";
|
|
13666
|
+
if (!alreadyBound || previousIsolation !== value) {
|
|
13667
|
+
const currentBranch = liveGitBranch(process.cwd());
|
|
13668
|
+
const verdict = evaluateBranchBinding({
|
|
13669
|
+
isolation: value,
|
|
13670
|
+
boundBranch: null,
|
|
13671
|
+
currentBranch,
|
|
13672
|
+
gitWorkTree: currentBranch === null ? isGitWorkTree(process.cwd()) : true
|
|
13673
|
+
});
|
|
13674
|
+
if (verdict.status === "needs-heal") {
|
|
13675
|
+
document.set("bound_branch", verdict.branch);
|
|
13676
|
+
} else if (verdict.status === "unbound-detached") {
|
|
13677
|
+
fail2(
|
|
13678
|
+
`ERROR: cannot bind isolation=${value} while HEAD is detached; checkout a branch first`
|
|
13679
|
+
);
|
|
13680
|
+
} else {
|
|
13681
|
+
document.set("bound_branch", null);
|
|
13682
|
+
}
|
|
13683
|
+
}
|
|
13684
|
+
} else {
|
|
13685
|
+
document.set("bound_branch", null);
|
|
13686
|
+
}
|
|
13687
|
+
}
|
|
13384
13688
|
const run = await readRunState(directory);
|
|
13385
13689
|
const projection = parseClassicStateDocument(document.toJS(), run);
|
|
13386
13690
|
if (projection.run) {
|
|
@@ -13430,10 +13734,10 @@ async function init(output, name, workflow) {
|
|
|
13430
13734
|
validateEnum(workflow, PROFILES);
|
|
13431
13735
|
const { file, label, directory } = await stateFile(name);
|
|
13432
13736
|
if (await exists6(file)) fail2(`ERROR: .comet.yaml already exists at ${label}/.comet.yaml`);
|
|
13433
|
-
await
|
|
13737
|
+
await fs22.mkdir(directory, { recursive: true });
|
|
13434
13738
|
const preset = workflow !== "full";
|
|
13435
13739
|
const reviewMode = preset ? "off" : await reviewModeDefault();
|
|
13436
|
-
const document = new
|
|
13740
|
+
const document = new import_yaml8.Document({
|
|
13437
13741
|
workflow,
|
|
13438
13742
|
language: await projectLanguageDefault(),
|
|
13439
13743
|
phase: "open",
|
|
@@ -13443,7 +13747,7 @@ async function init(output, name, workflow) {
|
|
|
13443
13747
|
subagent_dispatch: null,
|
|
13444
13748
|
tdd_mode: preset ? "direct" : null,
|
|
13445
13749
|
review_mode: reviewMode,
|
|
13446
|
-
isolation:
|
|
13750
|
+
isolation: null,
|
|
13447
13751
|
verify_mode: preset ? "light" : null,
|
|
13448
13752
|
auto_transition: await autoTransition() === "true",
|
|
13449
13753
|
base_ref: gitOutput(["rev-parse", "--verify", "HEAD"]),
|
|
@@ -13475,10 +13779,10 @@ async function requireBuildDecisions(name) {
|
|
|
13475
13779
|
const subagentDispatch = await readField3(name, "subagent_dispatch");
|
|
13476
13780
|
const tddMode = await readField3(name, "tdd_mode");
|
|
13477
13781
|
const reviewMode = await readField3(name, "review_mode");
|
|
13478
|
-
const allowedIsolation =
|
|
13782
|
+
const allowedIsolation = ["current", "branch", "worktree"];
|
|
13479
13783
|
if (!allowedIsolation.includes(isolation)) {
|
|
13480
13784
|
fail2(
|
|
13481
|
-
`ERROR: Cannot transition '${name}': isolation must be
|
|
13785
|
+
`ERROR: Cannot transition '${name}': isolation must be current, branch, or worktree, got '${isolation || "null"}'`
|
|
13482
13786
|
);
|
|
13483
13787
|
}
|
|
13484
13788
|
if (!["subagent-driven-development", "executing-plans", "direct"].includes(buildMode)) {
|
|
@@ -13511,13 +13815,13 @@ async function requireOpenArtifacts(name) {
|
|
|
13511
13815
|
const { directory } = await stateFile(name);
|
|
13512
13816
|
const workflow = await readField3(name, "workflow");
|
|
13513
13817
|
for (const artifact of ["proposal.md", "tasks.md"]) {
|
|
13514
|
-
if (!await nonempty3(
|
|
13818
|
+
if (!await nonempty3(path23.join(directory, artifact))) {
|
|
13515
13819
|
fail2(
|
|
13516
13820
|
`ERROR: Cannot transition '${name}': ${artifact} must exist and be non-empty before leaving open`
|
|
13517
13821
|
);
|
|
13518
13822
|
}
|
|
13519
13823
|
}
|
|
13520
|
-
if (workflow === "full" && !await nonempty3(
|
|
13824
|
+
if (workflow === "full" && !await nonempty3(path23.join(directory, "design.md"))) {
|
|
13521
13825
|
fail2(
|
|
13522
13826
|
`ERROR: Cannot transition '${name}': design.md must exist and be non-empty before leaving open`
|
|
13523
13827
|
);
|
|
@@ -13525,14 +13829,14 @@ async function requireOpenArtifacts(name) {
|
|
|
13525
13829
|
}
|
|
13526
13830
|
async function requireDesignEvidence(name) {
|
|
13527
13831
|
const designDoc = await readField3(name, "design_doc");
|
|
13528
|
-
if (!designDoc || designDoc === "null" || !await nonempty3(
|
|
13832
|
+
if (!designDoc || designDoc === "null" || !await nonempty3(path23.resolve(designDoc))) {
|
|
13529
13833
|
fail2(
|
|
13530
13834
|
`ERROR: Cannot transition '${name}': design_doc must point to an existing Design Doc before leaving design`
|
|
13531
13835
|
);
|
|
13532
13836
|
}
|
|
13533
13837
|
}
|
|
13534
13838
|
async function writeSparseTransitionEffects(directory, effects) {
|
|
13535
|
-
const file =
|
|
13839
|
+
const file = path23.join(directory, ".comet.yaml");
|
|
13536
13840
|
const document = await readDocument2(file);
|
|
13537
13841
|
for (const effect of effects) {
|
|
13538
13842
|
const field2 = wireField2(effect.field);
|
|
@@ -13547,7 +13851,7 @@ async function applyTransitionEvent(output, name, event) {
|
|
|
13547
13851
|
let sparse = false;
|
|
13548
13852
|
if (!classic) {
|
|
13549
13853
|
if (projection.run) fail2("ERROR: Classic state projection is missing");
|
|
13550
|
-
const document = await readDocument2(
|
|
13854
|
+
const document = await readDocument2(path23.join(directory, ".comet.yaml"));
|
|
13551
13855
|
classic = sparseClassicState(document.toJS());
|
|
13552
13856
|
sparse = true;
|
|
13553
13857
|
}
|
|
@@ -13594,7 +13898,7 @@ async function transition(output, name, event) {
|
|
|
13594
13898
|
} else if (event === "verify-pass") {
|
|
13595
13899
|
await requirePhase(name, "verify");
|
|
13596
13900
|
const report = await readField3(name, "verification_report");
|
|
13597
|
-
if (!report || !await exists6(
|
|
13901
|
+
if (!report || !await exists6(path23.resolve(report))) {
|
|
13598
13902
|
fail2(
|
|
13599
13903
|
`ERROR: Cannot transition '${name}': verification_report must point to an existing report file`
|
|
13600
13904
|
);
|
|
@@ -13658,9 +13962,9 @@ async function next(output, name) {
|
|
|
13658
13962
|
async function taskCheckoff(output, taskFile, taskText) {
|
|
13659
13963
|
validateRelativePath(taskFile, "task file");
|
|
13660
13964
|
if (!taskText) fail2("ERROR: Task text cannot be empty");
|
|
13661
|
-
const file =
|
|
13965
|
+
const file = path23.resolve(taskFile);
|
|
13662
13966
|
if (!await exists6(file)) fail2(`ERROR: Task file not found: ${taskFile}`);
|
|
13663
|
-
const lines = (await
|
|
13967
|
+
const lines = (await fs22.readFile(file, "utf8")).split(/\r?\n/u);
|
|
13664
13968
|
const matches = lines.filter(
|
|
13665
13969
|
(line) => [`- [ ] ${taskText}`, `- [x] ${taskText}`, `- [X] ${taskText}`].includes(line)
|
|
13666
13970
|
);
|
|
@@ -13698,21 +14002,21 @@ async function check2(output, name, phase) {
|
|
|
13698
14002
|
designDoc ? `design_doc=${designDoc} (expected: empty/null)` : "design_doc is empty/null"
|
|
13699
14003
|
);
|
|
13700
14004
|
for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
|
|
13701
|
-
(await nonempty3(
|
|
13702
|
-
`${artifact} ${await nonempty3(
|
|
14005
|
+
(await nonempty3(path23.join(directory, artifact)) ? pass2 : reject)(
|
|
14006
|
+
`${artifact} ${await nonempty3(path23.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
|
|
13703
14007
|
);
|
|
13704
14008
|
}
|
|
13705
14009
|
} else if (phase === "build") {
|
|
13706
14010
|
const workflow = await readField3(name, "workflow");
|
|
13707
14011
|
const designDoc = await readField3(name, "design_doc");
|
|
13708
14012
|
if (workflow === "full") {
|
|
13709
|
-
(designDoc && designDoc !== "null" && await exists6(
|
|
14013
|
+
(designDoc && designDoc !== "null" && await exists6(path23.resolve(designDoc)) ? pass2 : reject)(`design_doc=${designDoc} (expected: non-null and file exists)`);
|
|
13710
14014
|
} else {
|
|
13711
14015
|
pass2(`workflow=${workflow} (design_doc not required)`);
|
|
13712
14016
|
}
|
|
13713
14017
|
for (const artifact of ["proposal.md", "tasks.md"]) {
|
|
13714
|
-
(await nonempty3(
|
|
13715
|
-
`${artifact} ${await nonempty3(
|
|
14018
|
+
(await nonempty3(path23.join(directory, artifact)) ? pass2 : reject)(
|
|
14019
|
+
`${artifact} ${await nonempty3(path23.join(directory, artifact)) ? "non-empty" : "missing or empty"}`
|
|
13716
14020
|
);
|
|
13717
14021
|
}
|
|
13718
14022
|
} else if (phase === "verify") {
|
|
@@ -13725,6 +14029,29 @@ async function check2(output, name, phase) {
|
|
|
13725
14029
|
const archived = await readField3(name, "archived");
|
|
13726
14030
|
(archived !== "true" ? pass2 : reject)(`archived=${archived} (expected: not true)`);
|
|
13727
14031
|
}
|
|
14032
|
+
const binding = await resolveBranchBinding(directory, { heal: true, cwd: process.cwd() });
|
|
14033
|
+
if (binding.bindingRequired) {
|
|
14034
|
+
switch (binding.status) {
|
|
14035
|
+
case "drift":
|
|
14036
|
+
reject(driftBlockedMessage(name, binding.boundBranch, binding.currentBranch));
|
|
14037
|
+
break;
|
|
14038
|
+
case "unbound-detached":
|
|
14039
|
+
reject(unboundDetachedMessage(name));
|
|
14040
|
+
break;
|
|
14041
|
+
case "healed":
|
|
14042
|
+
pass2(`bound_branch lazily set to ${binding.branch}`);
|
|
14043
|
+
break;
|
|
14044
|
+
case "needs-heal":
|
|
14045
|
+
case "ok":
|
|
14046
|
+
case "not-applicable":
|
|
14047
|
+
pass2("bound_branch matches current branch");
|
|
14048
|
+
break;
|
|
14049
|
+
default: {
|
|
14050
|
+
const exhaustive = binding;
|
|
14051
|
+
throw new Error(`unhandled branch binding status: ${JSON.stringify(exhaustive)}`);
|
|
14052
|
+
}
|
|
14053
|
+
}
|
|
14054
|
+
}
|
|
13728
14055
|
output.stdout.push("");
|
|
13729
14056
|
if (blocked2) {
|
|
13730
14057
|
output.stderr.push(red4("BLOCKED — fix failing checks before proceeding"));
|
|
@@ -13734,7 +14061,7 @@ async function check2(output, name, phase) {
|
|
|
13734
14061
|
}
|
|
13735
14062
|
function fieldStatus(field2, value, file) {
|
|
13736
14063
|
if (!value || value === "null") return ` - ${field2}: PENDING`;
|
|
13737
|
-
if (file && !existsSync3(
|
|
14064
|
+
if (file && !existsSync3(path23.resolve(file))) {
|
|
13738
14065
|
return ` - ${field2}: BROKEN (path ${value} does not exist)`;
|
|
13739
14066
|
}
|
|
13740
14067
|
return ` - ${field2}: DONE (${value})`;
|
|
@@ -13743,7 +14070,7 @@ async function recoverOpen(output, directory) {
|
|
|
13743
14070
|
output.stdout.push(" Artifacts:");
|
|
13744
14071
|
let complete = 0;
|
|
13745
14072
|
for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
|
|
13746
|
-
const done = await nonempty3(
|
|
14073
|
+
const done = await nonempty3(path23.join(directory, artifact));
|
|
13747
14074
|
if (done) complete += 1;
|
|
13748
14075
|
output.stdout.push(` - ${artifact}: ${done ? "DONE" : "PENDING"}`);
|
|
13749
14076
|
}
|
|
@@ -13756,7 +14083,7 @@ async function recoverDesign(output, name, directory) {
|
|
|
13756
14083
|
output.stdout.push(" Artifacts:");
|
|
13757
14084
|
for (const artifact of ["proposal.md", "design.md", "tasks.md"]) {
|
|
13758
14085
|
output.stdout.push(
|
|
13759
|
-
` - ${artifact}: ${await nonempty3(
|
|
14086
|
+
` - ${artifact}: ${await nonempty3(path23.join(directory, artifact)) ? "DONE" : "MISSING (unexpected in design phase)"}`
|
|
13760
14087
|
);
|
|
13761
14088
|
}
|
|
13762
14089
|
const handoff = await readField3(name, "handoff_context");
|
|
@@ -13770,11 +14097,11 @@ async function recoverDesign(output, name, directory) {
|
|
|
13770
14097
|
fieldStatus("design_doc", design, design),
|
|
13771
14098
|
""
|
|
13772
14099
|
);
|
|
13773
|
-
if (design && design !== "null" && await exists6(
|
|
14100
|
+
if (design && design !== "null" && await exists6(path23.resolve(design))) {
|
|
13774
14101
|
output.stdout.push(
|
|
13775
14102
|
"Recovery action: Design Doc already created and linked. Run guard to transition to build."
|
|
13776
14103
|
);
|
|
13777
|
-
} else if (handoff && handoff !== "null" && await exists6(
|
|
14104
|
+
} else if (handoff && handoff !== "null" && await exists6(path23.resolve(handoff))) {
|
|
13778
14105
|
output.stdout.push(
|
|
13779
14106
|
"Recovery action: Handoff generated but Design Doc not yet created. Resume from brainstorming confirmation (Step 1c)."
|
|
13780
14107
|
);
|
|
@@ -13804,7 +14131,7 @@ async function recoverBuild(output, name, directory, workflow) {
|
|
|
13804
14131
|
decisions.push(fieldStatus("subagent_dispatch", subagentDispatch));
|
|
13805
14132
|
}
|
|
13806
14133
|
output.stdout.push(...decisions, "", " Plan:", fieldStatus("plan", plan, plan), "");
|
|
13807
|
-
const tasks =
|
|
14134
|
+
const tasks = path23.join(directory, "tasks.md");
|
|
13808
14135
|
if (!await exists6(tasks)) {
|
|
13809
14136
|
output.stdout.push(
|
|
13810
14137
|
" Tasks: tasks.md MISSING",
|
|
@@ -13813,14 +14140,14 @@ async function recoverBuild(output, name, directory, workflow) {
|
|
|
13813
14140
|
);
|
|
13814
14141
|
return;
|
|
13815
14142
|
}
|
|
13816
|
-
const lines = (await
|
|
14143
|
+
const lines = (await fs22.readFile(tasks, "utf8")).split(/\r?\n/u);
|
|
13817
14144
|
const total = lines.filter((line) => /^\s*- \[[ xX]\] /u.test(line)).length;
|
|
13818
14145
|
const done = lines.filter((line) => /^\s*- \[[xX]\] /u.test(line)).length;
|
|
13819
14146
|
const pending = total - done;
|
|
13820
14147
|
let planTotal = 0;
|
|
13821
14148
|
let planDone = 0;
|
|
13822
|
-
if (plan && plan !== "null" && await exists6(
|
|
13823
|
-
const planLines = (await
|
|
14149
|
+
if (plan && plan !== "null" && await exists6(path23.resolve(plan))) {
|
|
14150
|
+
const planLines = (await fs22.readFile(path23.resolve(plan), "utf8")).split(/\r?\n/u);
|
|
13824
14151
|
planTotal = planLines.filter((line) => /^\s*- \[[ xX]\] /u.test(line)).length;
|
|
13825
14152
|
planDone = planLines.filter((line) => /^\s*- \[[xX]\] /u.test(line)).length;
|
|
13826
14153
|
}
|
|
@@ -13951,19 +14278,19 @@ async function scale(output, name) {
|
|
|
13951
14278
|
validateChangeName4(name);
|
|
13952
14279
|
const { file, directory, label } = await stateFile(name);
|
|
13953
14280
|
if (!await exists6(file)) fail2(`ERROR: .comet.yaml not found at ${label}/.comet.yaml`);
|
|
13954
|
-
const tasksFile =
|
|
13955
|
-
const taskCount = await exists6(tasksFile) ? (await
|
|
13956
|
-
const specs =
|
|
14281
|
+
const tasksFile = path23.join(directory, "tasks.md");
|
|
14282
|
+
const taskCount = await exists6(tasksFile) ? (await fs22.readFile(tasksFile, "utf8")).split(/\r?\n/u).filter((line) => /^- \[/u.test(line)).length : 0;
|
|
14283
|
+
const specs = path23.join(directory, "specs");
|
|
13957
14284
|
let deltaSpecs = 0;
|
|
13958
14285
|
if (await exists6(specs)) {
|
|
13959
|
-
for (const entry2 of await
|
|
13960
|
-
if (await exists6(
|
|
14286
|
+
for (const entry2 of await fs22.readdir(specs)) {
|
|
14287
|
+
if (await exists6(path23.join(specs, entry2, "spec.md"))) deltaSpecs += 1;
|
|
13961
14288
|
}
|
|
13962
14289
|
}
|
|
13963
14290
|
const plan = await readField3(name, "plan");
|
|
13964
14291
|
let baseRef = "";
|
|
13965
|
-
if (plan && plan !== "null" && await exists6(
|
|
13966
|
-
const match = (await
|
|
14292
|
+
if (plan && plan !== "null" && await exists6(path23.resolve(plan))) {
|
|
14293
|
+
const match = (await fs22.readFile(path23.resolve(plan), "utf8")).match(/^base-ref:\s*(.+)$/mu);
|
|
13967
14294
|
baseRef = match?.[1].trim() ?? "";
|
|
13968
14295
|
}
|
|
13969
14296
|
if (!baseRef) baseRef = await readField3(name, "base_ref");
|
|
@@ -14043,15 +14370,42 @@ async function selectChange(output, name) {
|
|
|
14043
14370
|
validateChangeName4(name);
|
|
14044
14371
|
try {
|
|
14045
14372
|
const selection = await selectCurrentChange(process.cwd(), name);
|
|
14373
|
+
const boundBranch = await readField3(name, "bound_branch");
|
|
14374
|
+
const bound = boundBranch && boundBranch !== "null" ? boundBranch : null;
|
|
14046
14375
|
output.stderr.push(
|
|
14047
|
-
green4(
|
|
14048
|
-
`[SELECTED] current change: ${selection.change}${selection.branch ? ` (branch: ${selection.branch})` : ""}`
|
|
14049
|
-
)
|
|
14376
|
+
green4(`[SELECTED] current change: ${selection.change}${bound ? ` (branch: ${bound})` : ""}`)
|
|
14050
14377
|
);
|
|
14051
14378
|
} catch (error) {
|
|
14052
14379
|
fail2(`ERROR: ${error instanceof Error ? error.message : String(error)}`);
|
|
14053
14380
|
}
|
|
14054
14381
|
}
|
|
14382
|
+
async function rebind(output, name) {
|
|
14383
|
+
validateChangeName4(name);
|
|
14384
|
+
const { directory } = await stateFile(name);
|
|
14385
|
+
const boundBranch = await readField3(name, "bound_branch");
|
|
14386
|
+
if (!boundBranch || boundBranch === "null") {
|
|
14387
|
+
fail2(
|
|
14388
|
+
`ERROR: '${name}' is not yet bound; use 'comet state set ${name} isolation <current|branch|worktree>' to establish the first binding`
|
|
14389
|
+
);
|
|
14390
|
+
}
|
|
14391
|
+
const branch = liveGitBranch(process.cwd());
|
|
14392
|
+
if (branch === null) {
|
|
14393
|
+
fail2("ERROR: cannot rebind while HEAD is detached; checkout a branch first");
|
|
14394
|
+
}
|
|
14395
|
+
const before = await readClassicState(directory);
|
|
14396
|
+
if (!before.classic) fail2("ERROR: Classic state projection is missing");
|
|
14397
|
+
await healBoundBranch(directory, branch);
|
|
14398
|
+
const after = { ...before.classic, boundBranch: branch };
|
|
14399
|
+
await appendClassicStateEvent(directory, {
|
|
14400
|
+
change: name,
|
|
14401
|
+
event: "rebind",
|
|
14402
|
+
source: "comet-state",
|
|
14403
|
+
from: before.classic,
|
|
14404
|
+
to: after,
|
|
14405
|
+
effects: [{ field: "boundBranch", from: boundBranch, to: branch }]
|
|
14406
|
+
});
|
|
14407
|
+
output.stderr.push(green4(`[REBIND] bound_branch: ${boundBranch} → ${branch}`));
|
|
14408
|
+
}
|
|
14055
14409
|
async function currentChange(output) {
|
|
14056
14410
|
const resolution = await resolveCurrentChange(process.cwd());
|
|
14057
14411
|
if (resolution.status === "selected") {
|
|
@@ -14105,6 +14459,9 @@ var classicStateCommand = async (args) => {
|
|
|
14105
14459
|
} else if (subcommand === "task-checkoff") {
|
|
14106
14460
|
required(rest, 2, "Usage: comet-state.mjs task-checkoff <file> <task-text>");
|
|
14107
14461
|
await taskCheckoff(output, rest[0], rest[1]);
|
|
14462
|
+
} else if (subcommand === "rebind") {
|
|
14463
|
+
requiredExact(rest, 1, "Usage: comet-state.mjs rebind <change-name>");
|
|
14464
|
+
await rebind(output, rest[0]);
|
|
14108
14465
|
} else if (subcommand === "select") {
|
|
14109
14466
|
requiredExact(rest, 1, "Usage: comet-state.mjs select <change-name>");
|
|
14110
14467
|
await selectChange(output, rest[0]);
|