@khoavu882/doflow 2.0.0-beta.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -11
- package/bin/doflow.js +21 -11
- package/core/.antigravity-plugin/plugin.json +1 -3
- package/core/.claude-plugin/plugin.json +1 -1
- package/core/.codex-plugin/plugin.json +1 -1
- package/core/.plugin/plugin.json +1 -1
- package/core/harnesses/claude/hooks/lib.sh +43 -24
- package/core/harnesses/claude/hooks/mcp-tool-guard.sh +7 -17
- package/core/harnesses/claude/hooks/permission-audit.sh +3 -0
- package/core/harnesses/claude/hooks/post-compact.sh +35 -32
- package/core/harnesses/claude/hooks/post-edit-lint.sh +2 -0
- package/core/harnesses/claude/hooks/post-shell-observe.sh +48 -0
- package/core/harnesses/claude/hooks/post-tool-failure.sh +3 -0
- package/core/harnesses/claude/hooks/pre-bash-guard.sh +7 -17
- package/core/harnesses/claude/hooks/pre-compact.sh +23 -27
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +7 -18
- package/core/harnesses/claude/hooks/session-end.sh +23 -10
- package/core/harnesses/claude/hooks/session-start.sh +5 -3
- package/core/harnesses/claude/hooks/skill-config-audit.sh +3 -0
- package/core/harnesses/claude/hooks/stop-check.sh +5 -3
- package/core/harnesses/claude/hooks/subagent-audit.sh +5 -5
- package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -3
- package/core/harnesses/claude/settings/settings.json +18 -0
- package/core/harnesses/claude/statusline/doflow-statusline.sh +1 -0
- package/core/harnesses/codex/agents/core-implementer.toml +1 -0
- package/core/harnesses/codex/agents/delivery-lead.toml +10 -0
- package/core/harnesses/codex/agents/quality-guardian.toml +1 -1
- package/core/harnesses/codex/agents/research-writer.toml +1 -1
- package/core/harnesses/codex/agents/reviewer.toml +10 -0
- package/core/harnesses/codex/agents/spec-analyst.toml +1 -1
- package/core/harnesses/codex/agents/system-architect.toml +1 -1
- package/core/harnesses/codex/hooks/lib.sh +44 -25
- package/core/harnesses/codex/hooks/mcp-tool-guard.sh +7 -15
- package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +3 -1
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +7 -15
- package/core/harnesses/codex/hooks/pre-compact.impl.sh +29 -26
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +7 -16
- package/core/harnesses/codex/hooks/session-end.impl.sh +23 -10
- package/core/harnesses/codex/hooks/session-start.sh +5 -3
- package/core/harnesses/codex/hooks/stop-check.sh +6 -5
- package/core/harnesses/codex/hooks/subagent-audit.sh +18 -6
- package/core/harnesses/codex/hooks/user-prompt-submit.sh +5 -4
- package/core/harnesses/copilot/hooks/doflow-lib.sh +93 -0
- package/core/harnesses/copilot/hooks/doflow-mcp-tool-guard.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-pre-bash-guard.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-pre-implement-gate.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-session-start.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-stop-check.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-subagent-start.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow-subagent-stop.sh +9 -0
- package/core/harnesses/copilot/hooks/doflow.json +57 -0
- package/core/harnesses/kiro/agents/doflow.json +1 -1
- package/core/harnesses/kiro/hooks/lib.sh +26 -6
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +21 -5
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +21 -5
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +21 -5
- package/core/harnesses/kiro/hooks/session-start.sh +12 -5
- package/core/harnesses/kiro/hooks/stop-check.sh +22 -30
- package/core/harnesses/pi/extensions/doflow-guard.js +167 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +27 -12
- package/core/harnesses/shared/hooks/adapters/antigravity.js +14 -57
- package/core/harnesses/shared/hooks/bridge/bridge.sh +277 -0
- package/core/harnesses/shared/hooks/bridge/envelope.jq +129 -0
- package/core/harnesses/shared/hooks/bridge/observe-model.sh +75 -0
- package/core/harnesses/shared/hooks/bridge/respond.sh +70 -0
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +28 -14
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +51 -16
- package/core/harnesses/shared/hooks/policies/compact-text.sh +46 -0
- package/core/harnesses/shared/hooks/policies/contract.sh +78 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +35 -9
- package/core/harnesses/shared/hooks/policies/emission-rules.sh +37 -0
- package/core/harnesses/shared/hooks/policies/emission.jq +209 -0
- package/core/harnesses/shared/hooks/policies/emission.sh +383 -0
- package/core/harnesses/shared/hooks/policies/identity.sh +177 -0
- package/core/harnesses/shared/hooks/policies/lib.sh +65 -40
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +48 -35
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +284 -33
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +180 -110
- package/core/harnesses/shared/hooks/policies/session-context.sh +66 -7
- package/core/harnesses/shared/hooks/policies/stop-check.sh +61 -23
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +39 -6
- package/core/harnesses/shared/hooks/policies/summary-store.sh +347 -0
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +97 -159
- package/core/harnesses/shared/hooks/stream-hook-runner.js +114 -187
- package/core/harnesses/shared/locator/doflow-run +2 -3
- package/core/registry/advice.json +3 -3
- package/core/registry/assets.json +72 -80
- package/core/registry/capabilities.json +12 -0
- package/core/registry/contracts.json +60 -33
- package/core/registry/contribution-points.json +32 -0
- package/core/registry/gates.json +32 -0
- package/core/registry/guidance-caps.json +40 -0
- package/core/registry/harnesses.json +1542 -277
- package/core/registry/lifecycle.json +2837 -37
- package/core/registry/mcp.json +5 -1
- package/core/registry/models.json +7 -1
- package/core/registry/package-templates/README.md +19 -0
- package/core/registry/package-templates/agent/files/agent.md +9 -0
- package/core/registry/package-templates/agent/template.json +4 -0
- package/core/registry/package-templates/capability-provider/files/provider.json +9 -0
- package/core/registry/package-templates/capability-provider/template.json +11 -0
- package/core/registry/package-templates/debate-preset/files/preset.json +26 -0
- package/core/registry/package-templates/debate-preset/template.json +4 -0
- package/core/registry/package-templates/review-preset/files/preset.json +30 -0
- package/core/registry/package-templates/review-preset/template.json +4 -0
- package/core/registry/package-templates/skill/files/SKILL.md +8 -0
- package/core/registry/package-templates/skill/template.json +4 -0
- package/core/registry/package-templates/worker/files/worker.json +92 -0
- package/core/registry/package-templates/worker/template.json +11 -0
- package/core/registry/packages/doflow/doflow-package.json +15 -0
- package/core/registry/packages/doflow/presets/debate-3.json +26 -0
- package/core/registry/protocols.json +61 -0
- package/core/registry/routes.json +17 -0
- package/core/registry/rules.json +431 -0
- package/core/registry/settings.json +276 -0
- package/core/registry/storage.json +701 -30
- package/core/registry/telemetry.json +236 -0
- package/core/registry/transcripts.json +142 -0
- package/core/registry/verification.json +76 -1
- package/core/registry/workflows.json +55 -0
- package/core/shared/agent-specs/core-implementer.md +3 -0
- package/core/shared/agent-specs/delivery-lead.md +68 -0
- package/core/shared/agent-specs/quality-guardian.md +5 -1
- package/core/shared/agent-specs/research-writer.md +10 -3
- package/core/shared/agent-specs/reviewer.md +53 -0
- package/core/shared/agent-specs/spec-analyst.md +5 -6
- package/core/shared/agent-specs/system-architect.md +5 -1
- package/core/shared/guidance/DOFLOW_CORE.md +1 -5
- package/core/shared/guidance/modes/MODE_DeepResearch.md +1 -1
- package/core/shared/guidance/modes/MODE_Orchestration.md +4 -3
- package/core/shared/guidance/modes/MODE_Task_Management.md +14 -14
- package/core/shared/guidance/pointers/codex.md +1 -4
- package/core/shared/guidance/references/ARTIFACT_FORMAT.md +30 -16
- package/core/shared/guidance/references/ARTIFACT_VOICE.md +3 -2
- package/core/shared/guidance/references/CONSTITUTION_BASE.md +17 -15
- package/core/shared/guidance/references/DIAGRAM_GUIDE.md +1 -1
- package/core/shared/guidance/references/DOFLOW_CHAIN.md +17 -19
- package/core/shared/guidance/references/EVIDENCE_LEDGER.md +7 -8
- package/core/shared/guidance/references/MODEL_SELECTION.md +5 -3
- package/core/shared/guidance/references/ORCHESTRATION.md +1 -2
- package/core/shared/guidance/rules/RULES.md +45 -0
- package/core/shared/scripts/doflow/bash/do-args.sh +37 -0
- package/core/shared/scripts/doflow/bash/do-exec-paths.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-git-state.sh +15 -4
- package/core/shared/scripts/doflow/bash/do-parallel-check.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-paths.sh +40 -2
- package/core/shared/scripts/doflow/bash/do-prereqs.sh +2 -1
- package/core/shared/scripts/doflow/bash/do-review-package.sh +4 -0
- package/core/shared/scripts/doflow/bash/do-task-brief.sh +58 -16
- package/core/shared/scripts/doflow/bash/render-audit.sh +26 -2
- package/core/shared/scripts/doflow/bash/render-diagrams.sh +1 -0
- package/core/shared/scripts/doflow/bash/render-puml.sh +2 -1
- package/core/shared/scripts/doflow/bash/validate-artifacts.sh +48 -4
- package/core/shared/scripts/doflow/bin/doflow-run +154 -35
- package/core/shared/skills/do/SKILL.md +12 -10
- package/core/shared/skills/do/references/advice_calls.md +26 -0
- package/core/shared/skills/do/references/pm_routing.md +1 -2
- package/core/shared/skills/do/references/program_mode.md +31 -0
- package/core/shared/skills/do-brainstorm/SKILL.md +20 -74
- package/core/shared/skills/do-brainstorm/references/handoff_branches.md +35 -0
- package/core/shared/skills/do-brainstorm/references/intent_seed.md +21 -0
- package/core/shared/skills/do-brainstorm/references/round_log.md +17 -0
- package/core/shared/skills/do-code-review/SKILL.md +41 -144
- package/core/shared/skills/do-code-review/content-types/markdown.md +24 -2
- package/core/shared/skills/do-code-review/references/tools.md +90 -0
- package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +549 -7
- package/core/shared/skills/do-design/SKILL.md +24 -23
- package/core/shared/skills/do-diagnose/SKILL.md +14 -4
- package/core/shared/skills/do-document/SKILL.md +11 -1
- package/core/shared/skills/do-document/references/deep_research.md +1 -2
- package/core/shared/skills/do-document/references/embedded-research.md +18 -6
- package/core/shared/skills/do-document/references/implementation-flow.md +5 -6
- package/core/shared/skills/do-execute-plan/SKILL.md +17 -59
- package/core/shared/skills/do-execute-plan/references/handoff_record.md +7 -2
- package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +13 -0
- package/core/shared/skills/do-execute-plan/references/readiness_gate.md +28 -1
- package/core/shared/skills/do-execute-plan/references/run_position.md +13 -1
- package/core/shared/skills/do-execute-plan/references/scaffold.md +17 -9
- package/core/shared/skills/do-execute-plan/references/state_checkpoint.md +11 -0
- package/core/shared/skills/do-execute-plan/references/task_attempts.md +78 -24
- package/core/shared/skills/do-flow/SKILL.md +8 -9
- package/core/shared/skills/do-flow/references/task_classes.md +2 -2
- package/core/shared/skills/do-git/SKILL.md +4 -0
- package/core/shared/skills/do-implement/SKILL.md +7 -9
- package/core/shared/skills/do-plan/SKILL.md +29 -19
- package/core/shared/skills/do-test/SKILL.md +7 -4
- package/core/shared/templates/doflow/constitution-template.md +9 -3
- package/core/shared/templates/doflow/data-model-template.md +1 -1
- package/core/shared/templates/doflow/design-template.md +113 -16
- package/core/shared/templates/doflow/plan-template.md +11 -10
- package/core/shared/templates/doflow/question-log-template.md +14 -2
- package/core/shared/templates/doflow/requirement-template.md +1 -1
- package/core/worker-evidence/antigravity/checks.json +14 -0
- package/core/worker-evidence/codex/2026-10-18-cli-check.json +107 -0
- package/core/worker-evidence/codex/2026-10-18-live-run-edit.json +73 -0
- package/core/worker-evidence/codex/2026-10-18-live-run-read-only.json +62 -0
- package/core/worker-evidence/codex/2026-10-24-cli-check.json +126 -0
- package/core/worker-evidence/codex/checks.json +38 -0
- package/package.json +10 -6
- package/src/adapters/antigravity/index.js +226 -113
- package/src/adapters/claude/index.js +39 -5
- package/src/adapters/codex/agents.js +25 -15
- package/src/adapters/codex/hooks.js +40 -5
- package/src/adapters/codex/index.js +100 -22
- package/src/adapters/codex/native-projection.js +6 -2
- package/src/adapters/copilot/index.js +58 -23
- package/src/adapters/copy-tree.js +294 -48
- package/src/adapters/guidance-manifest.js +71 -0
- package/src/adapters/guidance-pointer.js +19 -0
- package/src/adapters/hook-commands.js +6 -10
- package/src/adapters/index.js +1 -0
- package/src/adapters/kiro/index.js +38 -13
- package/src/adapters/opencode/index.js +8 -8
- package/src/adapters/pi/hooks.js +120 -0
- package/src/adapters/pi/index.js +48 -16
- package/src/adapters/resolve-source.js +26 -2
- package/src/cli/commands/install.js +3 -2
- package/src/cli/commands/reconcile.js +53 -9
- package/src/cli/commands/remove.js +2 -2
- package/src/cli/commands/rollback.js +6 -3
- package/src/cli/commands/self-update.js +18 -9
- package/src/cli/commands/status.js +21 -2
- package/src/cli/commands/ui.js +99 -0
- package/src/cli/commands/update.js +3 -2
- package/src/cli/index.js +338 -33
- package/src/cli/runtime-commands.js +243 -52
- package/src/cli/shared.js +0 -2
- package/src/helper/git.js +1 -1
- package/src/helper/guardrails.js +1 -1
- package/src/helper/marker-merge.js +31 -13
- package/src/helper/package-ids.js +37 -0
- package/src/helper/semver.js +94 -0
- package/src/install/backup.js +105 -15
- package/src/install/context.js +1 -1
- package/src/install/targets.js +31 -16
- package/src/lifecycle/coverage.js +74 -0
- package/src/lifecycle/hook-step.js +61 -0
- package/src/lifecycle/hook-tier.js +160 -0
- package/src/lifecycle/index.js +434 -86
- package/src/lifecycle/retired-harnesses.js +318 -0
- package/src/lifecycle/view.js +35 -15
- package/src/registry/index.js +686 -32
- package/src/registry/worker-ids.js +45 -0
- package/src/release/build-package.js +0 -3
- package/src/release/docs-blocks.js +492 -0
- package/src/release/preflight.js +425 -0
- package/src/release/rehearse.js +401 -0
- package/src/release/release-workflow.js +733 -0
- package/src/release/sync-plugin-versions.js +43 -7
- package/src/runtime/advice/bench-gate.js +25 -0
- package/src/runtime/advice/cli.js +59 -16
- package/src/runtime/advice/client.js +32 -9
- package/src/runtime/advice/config.js +98 -133
- package/src/runtime/advice/doctor.js +1 -1
- package/src/runtime/advice/elevation.js +97 -0
- package/src/runtime/advice/endpoint-guard.js +9 -3
- package/src/runtime/advice/mode.js +37 -0
- package/src/runtime/advice/record.js +18 -5
- package/src/runtime/advice/registry.js +4 -1
- package/src/runtime/advice/shadow-config.js +229 -0
- package/src/runtime/advice/shadow-dispatcher.js +276 -0
- package/src/runtime/brief-rules.js +81 -0
- package/src/runtime/brief-tools.js +111 -34
- package/src/runtime/candidate.js +514 -0
- package/src/runtime/capabilities/executor.js +450 -0
- package/src/runtime/capabilities/loopback.js +41 -0
- package/src/runtime/capabilities/sanitizer.js +88 -0
- package/src/runtime/capability-router.js +135 -3
- package/src/runtime/checkouts.js +73 -11
- package/src/runtime/claims.js +27 -12
- package/src/runtime/cli-result.js +11 -4
- package/src/runtime/cli.js +221 -277
- package/src/runtime/config-home.js +42 -0
- package/src/runtime/context/arbitrate.js +767 -0
- package/src/runtime/context/budget.js +203 -0
- package/src/runtime/context/compose.js +1367 -0
- package/src/runtime/context/delivery-store.js +100 -0
- package/src/runtime/context/emission-rules.js +118 -0
- package/src/runtime/context/identity.js +227 -0
- package/src/runtime/context/mandatory.js +594 -0
- package/src/runtime/context/pointer.js +142 -0
- package/src/runtime/context/primary-command.js +117 -0
- package/src/runtime/context/primary.js +344 -0
- package/src/runtime/context/summary-store.js +655 -0
- package/src/runtime/context-pack.js +1106 -245
- package/src/runtime/decision-register.js +13 -4
- package/src/runtime/dispatch/admission.js +392 -0
- package/src/runtime/dispatch/attempt-end.js +274 -0
- package/src/runtime/dispatch/command.js +628 -0
- package/src/runtime/dispatch/controls.js +904 -0
- package/src/runtime/dispatch/envelope.js +276 -0
- package/src/runtime/dispatch/grants.js +310 -0
- package/src/runtime/dispatch/integrate.js +617 -0
- package/src/runtime/dispatch/loop.js +1835 -0
- package/src/runtime/dispatch/store.js +352 -0
- package/src/runtime/dispatch/verify-run.js +201 -0
- package/src/runtime/evidence-fields.js +39 -0
- package/src/runtime/evidence-ledger.js +41 -7
- package/src/runtime/failure/capture.js +3 -1
- package/src/runtime/failure/cli.js +25 -9
- package/src/runtime/failure/home.js +57 -30
- package/src/runtime/failure/store.js +7 -2
- package/src/runtime/feature-pointer.js +174 -0
- package/src/runtime/feature-resolve.js +13 -2
- package/src/runtime/fleet/command.js +77 -0
- package/src/runtime/fleet/projects.js +178 -0
- package/src/runtime/fleet/tree.js +383 -0
- package/src/runtime/freshness.js +77 -10
- package/src/runtime/git-memo.js +46 -0
- package/src/runtime/guidance/ablation.js +427 -0
- package/src/runtime/health.js +565 -17
- package/src/runtime/history-compactor.js +13 -3
- package/src/runtime/implementation-gate.js +277 -22
- package/src/runtime/inventory/coverage.js +1 -1
- package/src/runtime/inventory/index.js +1 -1
- package/src/runtime/inventory/precedence.js +2 -2
- package/src/runtime/inventory/siblings.js +6 -4
- package/src/runtime/knowledge/code-corpus.js +277 -0
- package/src/runtime/knowledge/code-lexical.js +130 -0
- package/src/runtime/knowledge/code-retrieval.js +307 -0
- package/src/runtime/knowledge/code-validation.js +106 -0
- package/src/runtime/knowledge/gp3-gate.js +74 -0
- package/src/runtime/knowledge/graph-adapter.js +288 -0
- package/src/runtime/knowledge/graph-fallback.js +394 -0
- package/src/runtime/knowledge/hybrid.js +136 -8
- package/src/runtime/knowledge/retrieval.js +34 -1
- package/src/runtime/knowledge/rtk-compress.js +77 -0
- package/src/runtime/knowledge/semble-bridge.py +106 -0
- package/src/runtime/knowledge/semble-lifecycle.js +114 -0
- package/src/runtime/knowledge/semble-provider.js +365 -0
- package/src/runtime/lifecycle/cli.js +16 -6
- package/src/runtime/lifecycle/event-store.js +8 -6
- package/src/runtime/lifecycle/followup.js +6 -1
- package/src/runtime/lifecycle/overview.js +24 -1
- package/src/runtime/lifecycle/report-store.js +8 -10
- package/src/runtime/lifecycle/retention.js +95 -31
- package/src/runtime/lifecycle/root.js +9 -1
- package/src/runtime/lifecycle/status.js +34 -17
- package/src/runtime/lifecycle/store-upkeep.js +56 -7
- package/src/runtime/mask.js +134 -7
- package/src/runtime/mcp-consultations.js +40 -6
- package/src/runtime/model-router.js +79 -7
- package/src/runtime/models/catalogue.js +191 -0
- package/src/runtime/models/command.js +153 -0
- package/src/runtime/off-words.js +12 -0
- package/src/runtime/outcome.js +3 -3
- package/src/runtime/packages/command.js +1009 -0
- package/src/runtime/packages/contributions.js +116 -0
- package/src/runtime/packages/digest.js +132 -0
- package/src/runtime/packages/fetch.js +182 -0
- package/src/runtime/packages/grants.js +192 -0
- package/src/runtime/packages/index-file.js +134 -0
- package/src/runtime/packages/instruction.js +90 -0
- package/src/runtime/packages/manifest.js +331 -0
- package/src/runtime/packages/points.js +477 -0
- package/src/runtime/packages/programs.js +216 -0
- package/src/runtime/packages/scaffold.js +277 -0
- package/src/runtime/packages/source.js +90 -0
- package/src/runtime/packages/state.js +164 -0
- package/src/runtime/packages/store.js +449 -0
- package/src/runtime/packages/tar.js +106 -0
- package/src/runtime/packages/view.js +406 -0
- package/src/runtime/plan-check.js +59 -0
- package/src/runtime/plan-content.js +324 -0
- package/src/runtime/policy-init.js +118 -0
- package/src/runtime/profiles/doctor.js +96 -0
- package/src/runtime/profiles/resolve.js +244 -0
- package/src/runtime/profiles/rollback.js +254 -0
- package/src/runtime/profiles/sampler.js +41 -0
- package/src/runtime/readiness-record.js +16 -11
- package/src/runtime/readiness.js +127 -16
- package/src/runtime/research-request.js +50 -25
- package/src/runtime/retrieval-plan.js +402 -73
- package/src/runtime/retrieval-record.js +293 -0
- package/src/runtime/review/command.js +246 -0
- package/src/runtime/review/dominance.js +68 -0
- package/src/runtime/review/findings.js +434 -0
- package/src/runtime/review/identity.js +255 -0
- package/src/runtime/review/protocol-command.js +109 -0
- package/src/runtime/review/protocols.js +405 -0
- package/src/runtime/review/resolve-protocol.js +302 -0
- package/src/runtime/review/start.js +530 -0
- package/src/runtime/roadmap/facts.js +479 -0
- package/src/runtime/roadmap/gates.js +270 -0
- package/src/runtime/roadmap/loop.js +1636 -0
- package/src/runtime/roadmap/merge.js +381 -0
- package/src/runtime/roadmap/rows.js +1113 -0
- package/src/runtime/roadmap/seed.js +951 -0
- package/src/runtime/rules-report.js +336 -0
- package/src/runtime/scaffold/artifacts.js +63 -9
- package/src/runtime/scaffold/generate.js +21 -9
- package/src/runtime/settings/autopilot.js +106 -0
- package/src/runtime/settings/cli.js +280 -0
- package/src/runtime/settings/config-write.js +314 -0
- package/src/runtime/settings/files.js +271 -0
- package/src/runtime/settings/legacy.js +154 -0
- package/src/runtime/settings/lexical.js +56 -0
- package/src/runtime/settings/prepared-run.js +269 -0
- package/src/runtime/settings/project-layers.js +118 -0
- package/src/runtime/settings/refs.js +288 -0
- package/src/runtime/settings/registry.js +553 -0
- package/src/runtime/settings/resolve.js +713 -0
- package/src/runtime/settings/shared.js +37 -0
- package/src/runtime/settings/worker-billing.js +107 -0
- package/src/runtime/settings/write.js +269 -0
- package/src/runtime/slot-command.js +78 -0
- package/src/runtime/slots.js +671 -0
- package/src/runtime/source-version.js +290 -0
- package/src/runtime/state-root.js +217 -0
- package/src/runtime/storage/cli.js +12 -5
- package/src/runtime/storage/engine.js +9 -2
- package/src/runtime/storage/registry.js +14 -1
- package/src/runtime/storage/roots.js +66 -16
- package/src/runtime/storage/rules.js +82 -10
- package/src/runtime/storage/upkeep.js +10 -2
- package/src/runtime/storage/work-status.js +245 -26
- package/src/runtime/task-attempts.js +589 -69
- package/src/runtime/task-classifier.js +47 -11
- package/src/runtime/task-graph.js +373 -0
- package/src/runtime/task-run.js +778 -0
- package/src/runtime/task-scope.js +202 -56
- package/src/runtime/task-sources.js +147 -0
- package/src/runtime/task-state.js +440 -65
- package/src/runtime/team/admission.js +301 -0
- package/src/runtime/team/envelope.js +324 -0
- package/src/runtime/team/review-guard.js +156 -0
- package/src/runtime/trace/analyze.js +427 -0
- package/src/runtime/trace/baseline.js +770 -0
- package/src/runtime/trace/ledger.js +63 -140
- package/src/runtime/trace/otlp-export.js +568 -0
- package/src/runtime/trace/otlp-map.js +481 -0
- package/src/runtime/trace/spans.js +745 -0
- package/src/runtime/trace/telemetry.js +225 -0
- package/src/runtime/trace/views.js +1 -0
- package/src/runtime/transcripts/command.js +98 -0
- package/src/runtime/transcripts/cursor.js +326 -0
- package/src/runtime/transcripts/read.js +126 -0
- package/src/runtime/transcripts/readers/claude-jsonl.js +74 -0
- package/src/runtime/transcripts/readers/codex-rollout.js +70 -0
- package/src/runtime/transcripts/readers/copilot-events.js +90 -0
- package/src/runtime/transcripts/readers/kiro-jsonl.js +77 -0
- package/src/runtime/transcripts/readers/pi-jsonl.js +59 -0
- package/src/runtime/transcripts/registry.js +161 -0
- package/src/runtime/transcripts/stats.js +161 -0
- package/src/runtime/verification/check-key.js +628 -0
- package/src/runtime/verification/contract-runner.js +546 -11
- package/src/runtime/verification/engine.js +499 -9
- package/src/runtime/verification/impact.js +617 -0
- package/src/runtime/verification/inflight.js +205 -0
- package/src/runtime/verification/registry.js +176 -0
- package/src/runtime/verification/reuse.js +184 -0
- package/src/runtime/verification/telemetry-emit.js +254 -0
- package/src/runtime/verification/test-selection.js +67 -7
- package/src/runtime/worker/active.js +90 -0
- package/src/runtime/worker/cancel.js +222 -0
- package/src/runtime/worker/catalogue.js +122 -0
- package/src/runtime/worker/command.js +677 -0
- package/src/runtime/worker/evidence.js +288 -0
- package/src/runtime/worker/launch.js +288 -0
- package/src/runtime/worker/models.js +137 -0
- package/src/runtime/worker/parsers.js +218 -0
- package/src/runtime/worker/probes/index.js +706 -0
- package/src/runtime/worker/process-tree.js +415 -0
- package/src/runtime/worker/quota.js +43 -0
- package/src/runtime/worker/readiness.js +713 -0
- package/src/runtime/worker/run-store.js +166 -0
- package/src/runtime/worker/supervisor.js +541 -0
- package/src/runtime/worker/worktree-check.js +252 -0
- package/src/runtime/workflow-engine.js +5 -1
- package/src/runtime/workflow-orchestrator.js +578 -63
- package/src/runtime/worktree.js +149 -22
- package/src/state/index.js +1 -1
- package/src/state/lockfile.js +64 -10
- package/src/state/run-lock.js +1 -1
- package/types/node-commonjs.d.ts +106 -7
- package/core/.antigravity-plugin/hooks.json +0 -39
- package/core/harnesses/gemini/hooks/hooks.json +0 -77
- package/core/harnesses/gemini/hooks/lib.sh +0 -302
- package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +0 -21
- package/core/harnesses/gemini/hooks/post-edit-lint.sh +0 -39
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +0 -21
- package/core/harnesses/gemini/hooks/pre-compact.sh +0 -38
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +0 -22
- package/core/harnesses/gemini/hooks/session-end.impl.sh +0 -89
- package/core/harnesses/gemini/hooks/session-end.sh +0 -5
- package/core/harnesses/gemini/hooks/session-start.sh +0 -5
- package/core/harnesses/gemini/settings/adapter-defaults.json +0 -4
- package/core/harnesses/shared/hooks/adapters/arg-fields.js +0 -19
- package/core/harnesses/shared/hooks/adapters/gemini.js +0 -114
- package/core/harnesses/shared/hooks/hooks.json +0 -47
- package/core/shared/guidance/FLAGS.md +0 -25
- package/core/shared/guidance/rules/RULE_01_SAFETY.md +0 -25
- package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +0 -23
- package/core/shared/guidance/rules/RULE_03_QUALITY.md +0 -14
- package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +0 -46
- package/src/adapters/gemini/hooks.js +0 -210
- package/src/adapters/gemini/index.js +0 -390
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
// `doflow reconcile` — converge observed state onto the doflow.lock pin: report drift, then heal
|
|
3
3
|
// it on confirmation. Never re-prompts for MCP; selections ride exactly as pinned.
|
|
4
4
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
5
|
+
const path = require('node:path');
|
|
5
6
|
const { toolDirs } = require('../../install/targets.js');
|
|
6
7
|
const { resolveContext, printContext } = require('../../install/context.js');
|
|
7
8
|
const { writeManifest } = require('../../install/manifest.js');
|
|
9
|
+
const { DEFAULT_BACKUP_RETENTION, createFileBackup } = require('../../install/backup.js');
|
|
10
|
+
const { backupSetFromPlan, backupSetFromPaths } = require('../../install/backup-set.js');
|
|
11
|
+
const { ledgerPath } = require('../../state/index.js');
|
|
12
|
+
const { backupStep, reportBackup, applyBackupRetention } = require('./install.js');
|
|
8
13
|
const { confirm } = require('../../helper/prompt.js');
|
|
9
14
|
const { sourceCommit } = require('../../helper/git.js');
|
|
10
|
-
const { loadRegistry } = require('../../registry/index.js');
|
|
15
|
+
const { loadRegistry, retiredFor } = require('../../registry/index.js');
|
|
11
16
|
const { applyLifecycle, recordMcpOwnership } = require('../../lifecycle/index.js');
|
|
17
|
+
const { formatRetiredPlans, retiredReleaseKeys } = require('../../lifecycle/retired-harnesses.js');
|
|
12
18
|
const {
|
|
13
19
|
registryLifecycleView, assertSafeRegistryPlan,
|
|
14
20
|
} = require('../../lifecycle/view.js');
|
|
@@ -33,6 +39,10 @@ function reconcileReport(view ) {
|
|
|
33
39
|
}
|
|
34
40
|
perHarness.set(target.harness, entry);
|
|
35
41
|
}
|
|
42
|
+
// A retired harness's rows (row 127 IC-003) are drift too: converging means releasing them.
|
|
43
|
+
for (const change of (view.plan.retiredHarnesses ?? []).flatMap((item ) => item.changes)) {
|
|
44
|
+
drifts.push({ harness: change.harness, operation: change.operation, assetId: change.assetId, target: change.target, retired: true });
|
|
45
|
+
}
|
|
36
46
|
return {
|
|
37
47
|
drifts,
|
|
38
48
|
conflicts: view.plan.conflicts,
|
|
@@ -42,17 +52,29 @@ function reconcileReport(view ) {
|
|
|
42
52
|
};
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
function printReconcileReport(report , lock ) {
|
|
55
|
+
function printReconcileReport(report , lock , retiredLines = []) {
|
|
46
56
|
console.log(`[INFO] Reconciling against doflow.lock (sourceVersion ${lock.sourceVersion ?? 'unknown'})`);
|
|
47
57
|
for (const [harness, counts] of Object.entries (report.perHarness)) {
|
|
48
58
|
const total = counts.create + counts.update + counts.remove;
|
|
49
59
|
console.log(`[INFO] ${harness}: ${total === 0 ? 'clean' : `${total} drift(s) (${counts.create} create, ${counts.update} update, ${counts.remove} remove)`}`);
|
|
50
60
|
}
|
|
61
|
+
for (const line of retiredLines) console.log(line);
|
|
51
62
|
for (const conflict of report.conflicts) console.log(`[CONFLICT] ${conflict.harness}: ${conflict.reason}`);
|
|
52
63
|
for (const prerequisite of report.prerequisites) console.log(`[PENDING-TRUST] ${prerequisite.harness}: ${prerequisite.prerequisite}`);
|
|
53
64
|
if (report.clean) console.log('[OK] Observed state matches doflow.lock.');
|
|
54
65
|
}
|
|
55
66
|
|
|
67
|
+
/** The backup a retirement sweep takes (row 127 FR-4): the set install and update take, files and
|
|
68
|
+
* ledger. A sweep that only gives up rows (release, drop, keep) touches no file, so that set is empty;
|
|
69
|
+
* the ledger alone is then what a rollback needs to bring the rows and the target entry back. */
|
|
70
|
+
function retirementBackupSet(view , paths , scope ) {
|
|
71
|
+
const ledger = ledgerPath(view.stateRoot);
|
|
72
|
+
const args = { scope: scope.global ? 'global' : 'project', scopeRoot: paths.scopeRoot, records: [ledger],
|
|
73
|
+
exclude: [paths.backupRoot, view.stateRoot, paths.manifestPath, path.join(paths.doflowRoot, 'doflow.lock')] };
|
|
74
|
+
const set = backupSetFromPlan({ plan: view.plan, ...args });
|
|
75
|
+
return set.count ? set : backupSetFromPaths({ items: [{ path: ledger, harnesses: [] }], ...args });
|
|
76
|
+
}
|
|
77
|
+
|
|
56
78
|
function cmdReconcile(o ) {
|
|
57
79
|
refuseHomeRootedProject(o, 'reconcile');
|
|
58
80
|
const scope = scopeOf(o);
|
|
@@ -61,23 +83,33 @@ function cmdReconcile(o ) {
|
|
|
61
83
|
const dirs = toolDirs(scope);
|
|
62
84
|
const lifecyclePaths = installPaths(scope);
|
|
63
85
|
const { lock, ledger, manifestServers } = scopeSelectionState(scope);
|
|
86
|
+
// Read only when there is a pin or a row to classify, as before this check existed.
|
|
87
|
+
const registry = lock?.targets?.length || ledger?.resources?.length ? loadRegistry({ repoRoot: REPO_ROOT }) : null;
|
|
88
|
+
const retired = (harness ) => (registry ? retiredFor(registry, harness) : null);
|
|
89
|
+
// A retired pin (row 127 IC-004) names a harness with no adapter: dropped, said, and the rest
|
|
90
|
+
// converge. Its ledger rows are released by this run's plan, like install's and update's.
|
|
91
|
+
for (const entry of lock?.targets ?? []) {
|
|
92
|
+
const record = retired(entry.harness);
|
|
93
|
+
if (record) console.log(`[WARN] ${entry.harness}: retired (use ${record.replacement}); dropped from the pinned targets`);
|
|
94
|
+
}
|
|
95
|
+
const livePins = (lock?.targets ?? []).filter((entry ) => !retired(entry.harness));
|
|
64
96
|
// A harness the ledger holds but the lock does not pin is installed and outside reconcile's reach.
|
|
65
97
|
// Said, not converged: the lock records choices, and reconcile has no choice to record for it.
|
|
66
|
-
const pinned = new Set(
|
|
67
|
-
const unpinned = [...new Set((ledger?.resources ?? []).map((resource ) => resource.harness))]
|
|
98
|
+
const pinned = new Set(livePins.map((entry ) => entry.harness));
|
|
99
|
+
const unpinned = [...new Set((ledger?.resources ?? []).map((resource ) => resource.harness))]
|
|
100
|
+
.filter((harness ) => !pinned.has(harness) && !retired(harness)).sort();
|
|
68
101
|
for (const harness of unpinned) {
|
|
69
102
|
const count = ledger.resources.filter((resource ) => resource.harness === harness).length;
|
|
70
103
|
console.log(`[WARN] ${harness}: installed (ledger holds ${count} resource(s)) but absent from doflow.lock; reconcile does not converge it.`);
|
|
71
104
|
}
|
|
72
|
-
if (!lock || !
|
|
105
|
+
if (!lock || !livePins.length) {
|
|
73
106
|
// Reconcile converges onto what install pinned; with no pin there is no desired state to
|
|
74
107
|
// converge to, and guessing one from the registry would silently adopt targets the user
|
|
75
108
|
// never chose.
|
|
76
109
|
console.log('[INFO] No doflow.lock in this scope — nothing pinned to reconcile against. Run `doflow install` first.');
|
|
77
110
|
return;
|
|
78
111
|
}
|
|
79
|
-
const targets =
|
|
80
|
-
const registry = loadRegistry({ repoRoot: REPO_ROOT });
|
|
112
|
+
const targets = livePins.map((entry ) => entry.harness);
|
|
81
113
|
printContext(resolveContext({ repoRoot: REPO_ROOT, targets, dirs, sourceCommit: sourceCommit(SCRIPT_DIR), ...scope }));
|
|
82
114
|
// Each harness converges onto its own pinned selection — reconcile never re-prompts and never
|
|
83
115
|
// lends one harness's servers to another.
|
|
@@ -87,7 +119,7 @@ function cmdReconcile(o ) {
|
|
|
87
119
|
if (!lifecycleView.plan.safe) { assertSafeRegistryPlan(lifecycleView); return; }
|
|
88
120
|
|
|
89
121
|
const report = reconcileReport(lifecycleView);
|
|
90
|
-
printReconcileReport(report, lock);
|
|
122
|
+
printReconcileReport(report, lock, formatRetiredPlans(lifecycleView.plan.retiredHarnesses ?? []));
|
|
91
123
|
if (o.json) console.log(JSON.stringify({ scope: lock.scope, sourceVersion: lock.sourceVersion, targets, unpinned, ...report }, null, 2));
|
|
92
124
|
if (o.dryRun) {
|
|
93
125
|
console.log('[DRY] Reconcile plan complete — no changes written');
|
|
@@ -107,10 +139,22 @@ function cmdReconcile(o ) {
|
|
|
107
139
|
process.exit(1);
|
|
108
140
|
}
|
|
109
141
|
checkpointRunLock(hold);
|
|
142
|
+
// A run that changes a retired harness's rows backs the retirement up first, as install and
|
|
143
|
+
// update do, so `doflow rollback` restores it (row 127 FR-4). Any other reconcile takes none.
|
|
144
|
+
let bid = '';
|
|
145
|
+
const retiring = retiredReleaseKeys(lifecycleView.plan.retiredHarnesses ?? []).size > 0;
|
|
146
|
+
if (retiring && o.noBackup) {
|
|
147
|
+
console.error('[WARN] Skipping backup (--no-backup)');
|
|
148
|
+
} else if (retiring) {
|
|
149
|
+
const commit = sourceCommit(SCRIPT_DIR);
|
|
150
|
+
bid = reportBackup(backupStep(() => createFileBackup({ operation: 'reconcile', set: retirementBackupSet(lifecycleView, lifecyclePaths, scope),
|
|
151
|
+
backupRoot: lifecyclePaths.backupRoot, repoRoot: SCRIPT_DIR, sourceCommit: commit, version: pkg.version, date: new Date() })));
|
|
152
|
+
}
|
|
110
153
|
applyLifecycle({ plan: lifecycleView.plan, registry: lifecycleView.registry,
|
|
111
154
|
adapters: buildAdapterRegistry(),
|
|
112
155
|
stateRoot: lifecycleView.stateRoot, ledger: lifecycleView.ledger });
|
|
113
|
-
writeManifest({ scopeRoot: lifecyclePaths.scopeRoot, scriptVersion: pkg.version, operation: 'update', repoRoot: SCRIPT_DIR, sourceCommit: sourceCommit(SCRIPT_DIR), backupId:
|
|
156
|
+
writeManifest({ scopeRoot: lifecyclePaths.scopeRoot, scriptVersion: pkg.version, operation: 'update', repoRoot: SCRIPT_DIR, sourceCommit: sourceCommit(SCRIPT_DIR), backupId: bid, tools: targets, date: new Date() });
|
|
157
|
+
if (bid) applyBackupRetention({ backupRoot: lifecyclePaths.backupRoot, prune: o.prune, keep: o.prune ?? DEFAULT_BACKUP_RETENTION, bid });
|
|
114
158
|
console.log('[OK] Reconciliation complete — state converged onto doflow.lock.');
|
|
115
159
|
} finally {
|
|
116
160
|
hold?.release();
|
|
@@ -59,8 +59,8 @@ function cmdRemove(o ) {
|
|
|
59
59
|
scope: codexScope(scope), scopeRoot: scope.global ? os.homedir() : path.resolve(scope.projectRoot),
|
|
60
60
|
targets: lifecycleTargets, mcpAdoptable, retainedMcpIds, stateRoot: view.stateRoot, ledger: view.ledger,
|
|
61
61
|
context: view.plan.targets[0].adapterInput.context });
|
|
62
|
-
// Shared destinations (one .doflow/scripts tree for claude/codex
|
|
63
|
-
//
|
|
62
|
+
// Shared destinations (one .doflow/scripts tree for claude/codex, one .agents for
|
|
63
|
+
// antigravity/copilot) mean a removal can legitimately leave files standing. Saying only "removed"
|
|
64
64
|
// would be half the truth, so what was kept and who still claims it is printed, not implied.
|
|
65
65
|
for (const line of retentionSummary(result.retained)) console.log(`[INFO] ${line}`);
|
|
66
66
|
console.log(`[OK] Removed ${result.ledger.resources.length === 0 ? 'all' : 'eligible'} native resource(s) for ${lifecycleTargets.join(', ')}; ${result.ledger.resources.length} owned record(s) remain.`);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// restores per tool, as it always did.
|
|
7
7
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
8
8
|
const path = require('node:path');
|
|
9
|
-
const { resolveTargets, toolDirs } = require('../../install/targets.js');
|
|
9
|
+
const { VALID, resolveTargets, toolDirs } = require('../../install/targets.js');
|
|
10
10
|
const { resolveContext, printContext } = require('../../install/context.js');
|
|
11
11
|
const {
|
|
12
12
|
BackupError, createFileBackup, planRestore, executeRestore, listBackups, formatBytes,
|
|
@@ -59,9 +59,12 @@ function cmdRollback(o ) {
|
|
|
59
59
|
fail(error);
|
|
60
60
|
}
|
|
61
61
|
// A per-file backup restores the harnesses it holds (only those in --target when given), so the
|
|
62
|
-
// banner and the install manifest name those, not the default target.
|
|
62
|
+
// banner and the install manifest name those, not the default target. A backup taken by a run
|
|
63
|
+
// that swept a retired harness (127 IC-003) holds that harness's files and rows too: they are
|
|
64
|
+
// restored like any other, but a retired id is no target, so the banner and manifest skip it.
|
|
63
65
|
const restoredTools = plan.format === 2
|
|
64
|
-
? [...new Set(plan.restore.flatMap((item ) => item.harnesses))]
|
|
66
|
+
? [...new Set(plan.restore.flatMap((item ) => item.harnesses))]
|
|
67
|
+
.filter((h ) => VALID.includes(h) && (!explicitTargets || targets.includes(h))).sort()
|
|
65
68
|
: targets;
|
|
66
69
|
printContext(resolveContext({ repoRoot: REPO_ROOT, targets: restoredTools, dirs, sourceCommit: commit, global: o.global, projectRoot: '.' }));
|
|
67
70
|
|
|
@@ -2,32 +2,41 @@
|
|
|
2
2
|
// `doflow self-update` — git fetch/pull the checkout, then re-run the install path so the
|
|
3
3
|
// installed trees match the freshly pulled source.
|
|
4
4
|
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const path = require('node:path');
|
|
5
7
|
const { execFileSync } = require('node:child_process');
|
|
6
8
|
const { REPO_ROOT } = require('../shared.js');
|
|
7
9
|
const cmdInstall = require('./install.js');
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
/** The second argument is for tests: the checkout to update and the install it re-runs. */
|
|
12
|
+
function cmdSelfUpdate(o , { repoRoot = REPO_ROOT, install = cmdInstall } = {}) {
|
|
10
13
|
console.log('[INFO] Self-update: checking for upstream changes...');
|
|
11
14
|
let pulled = false;
|
|
12
15
|
let fetchOk = false;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// An npm install is not a git checkout: `git -C` there would act on whatever repository holds
|
|
17
|
+
// node_modules (or fail), never on DoFlow's source.
|
|
18
|
+
const isCheckout = fs.existsSync(path.join(repoRoot, '.git'));
|
|
19
|
+
if (!isCheckout) console.log('[INFO] This install is not a git checkout; to upgrade DoFlow run: npm install -g @khoavu882/doflow');
|
|
20
|
+
if (isCheckout) {
|
|
21
|
+
try {
|
|
22
|
+
execFileSync('git', ['-C', repoRoot, 'fetch', '--depth=1', 'origin'], { stdio: ['ignore', 'ignore', 'pipe'], timeout: 10000 });
|
|
23
|
+
fetchOk = true;
|
|
24
|
+
} catch {
|
|
25
|
+
console.error('[WARN] git fetch failed (offline or no remote configured) — installing from current HEAD');
|
|
26
|
+
}
|
|
18
27
|
}
|
|
19
28
|
if (fetchOk) {
|
|
20
29
|
try {
|
|
21
|
-
execFileSync('git', ['-C',
|
|
30
|
+
execFileSync('git', ['-C', repoRoot, 'pull', '--ff-only'], { stdio: ['ignore', 'ignore', 'pipe'], timeout: 10000 });
|
|
22
31
|
pulled = true;
|
|
23
|
-
const commit = execFileSync('git', ['-C',
|
|
32
|
+
const commit = execFileSync('git', ['-C', repoRoot, 'rev-parse', '--short', 'HEAD']).toString().trim();
|
|
24
33
|
console.log(`[INFO] Updated to commit: ${commit}`);
|
|
25
34
|
} catch {
|
|
26
35
|
console.error('[WARN] Fast-forward not possible — using current local state');
|
|
27
36
|
}
|
|
28
37
|
}
|
|
29
38
|
console.log(`[INFO] Running install (after ${pulled ? 'a git pull' : 'checking for updates'})...`);
|
|
30
|
-
|
|
39
|
+
install(o);
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
module.exports = cmdSelfUpdate;
|
|
@@ -42,6 +42,10 @@ function cmdStatus(o ) {
|
|
|
42
42
|
ledgerPresent: Boolean(readLedger(registryView.stateRoot)),
|
|
43
43
|
plan: { changes: registryView.plan.changes.length, conflicts: registryView.plan.conflicts, prerequisites: registryView.plan.prerequisites },
|
|
44
44
|
};
|
|
45
|
+
// Row 127: a retired harness the ledger still holds rows of, which the next install or update
|
|
46
|
+
// releases. Absent when there is none, so the report is unchanged for every other ledger.
|
|
47
|
+
const retired = (registryView.plan.retiredHarnesses ?? []).map((item ) => ({ harness: item.harness, replacement: item.replacement, rows: item.changes.length }));
|
|
48
|
+
if (retired.length) ctx.registry.retired = retired;
|
|
45
49
|
// Per-harness status must derive from that harness's own plan target, not the flattened
|
|
46
50
|
// registryView.plan.changes/conflicts across every target — otherwise, e.g., Codex having
|
|
47
51
|
// pending changes when it isn't installed yet would make Claude's line falsely report
|
|
@@ -50,7 +54,7 @@ function cmdStatus(o ) {
|
|
|
50
54
|
// Hook-wiring status needs the same general per-harness verification every install/update run
|
|
51
55
|
// already flows through (src/lifecycle's verifyLifecycle) rather than a Codex-only hardcode:
|
|
52
56
|
// it is the one place that can tell 'installed and active' apart from 'installed but pending a
|
|
53
|
-
// prerequisite' (Codex's unreviewed trust
|
|
57
|
+
// prerequisite' (Codex's unreviewed trust) from 'absent'.
|
|
54
58
|
const verification = verifyLifecycle({ plan: registryView.plan, adapters: registryView.adapters, context: { registry } });
|
|
55
59
|
const hooksFor = (harness ) => verification.verifications.find((item ) => item.harness === harness)?.hookWiring ?? null;
|
|
56
60
|
const harnessStatus = (harness ) => {
|
|
@@ -80,8 +84,19 @@ function cmdStatus(o ) {
|
|
|
80
84
|
ctx.registry = { status: 'invalid', error: error.message };
|
|
81
85
|
}
|
|
82
86
|
|
|
87
|
+
// The primary is read on use only (row 120 A.4): a fault in resolving it never breaks status.
|
|
88
|
+
let primary = null;
|
|
89
|
+
let primaryText ;
|
|
90
|
+
try {
|
|
91
|
+
const { primarySummary, resolveForReport } = require('../../runtime/context/primary-command.js');
|
|
92
|
+
primary = resolveForReport({ env: process.env, projectRoot: path.resolve(scope.projectRoot) }).primary;
|
|
93
|
+
primaryText = primarySummary(primary);
|
|
94
|
+
} catch (error ) {
|
|
95
|
+
primaryText = `unavailable (${error?.message || String(error)})`;
|
|
96
|
+
}
|
|
97
|
+
|
|
83
98
|
if (o.json) {
|
|
84
|
-
console.log(JSON.stringify({ context: ctx, manifest, codex: ctx.codex ?? null, mcpSelections }, null, 2));
|
|
99
|
+
console.log(JSON.stringify({ context: ctx, manifest, codex: ctx.codex ?? null, mcpSelections, primary }, null, 2));
|
|
85
100
|
return;
|
|
86
101
|
}
|
|
87
102
|
|
|
@@ -92,6 +107,7 @@ function cmdStatus(o ) {
|
|
|
92
107
|
};
|
|
93
108
|
|
|
94
109
|
printContext(ctx);
|
|
110
|
+
console.log(`primary: ${primaryText}`);
|
|
95
111
|
if (!manifest) {
|
|
96
112
|
console.log("[WARN] No install manifest found — run 'doflow install' to get started");
|
|
97
113
|
return;
|
|
@@ -126,6 +142,9 @@ function cmdStatus(o ) {
|
|
|
126
142
|
if (ctx.registry) {
|
|
127
143
|
console.log(` Registry lifecycle: ${ctx.registry.status === 'invalid' ? ctx.registry.error : `${ctx.registry.plan.changes} pending, ${ctx.registry.plan.conflicts.length} conflict(s)`}`);
|
|
128
144
|
if (ctx.registry.status !== 'invalid') console.log(` Neutral state: ${ctx.registry.stateRoot}${ctx.registry.ledgerPresent ? ' (ledger present)' : ' (not yet created)'}`);
|
|
145
|
+
for (const item of ctx.registry.retired ?? []) {
|
|
146
|
+
console.log(` Retired harness: ${item.harness} (use ${item.replacement}): ${item.rows} ledger row(s); the next 'doflow install' or 'doflow update' in this scope releases them`);
|
|
147
|
+
}
|
|
129
148
|
}
|
|
130
149
|
console.log('\n TOOL STATUS LAST UPDATED');
|
|
131
150
|
for (const tool of LIFECYCLE_HARNESSES) {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// `doflow ui [<project>] [--port N] [private TLS flags]` — run the DoFlow Console, a separately installed package
|
|
3
|
+
// (092 IC-008). The package is found by file existence and never loaded into the core: this module
|
|
4
|
+
// loads only node:fs, node:path and node:child_process (test/runtime/ui-launcher.test.ts). It never
|
|
5
|
+
// listens, reads DoFlow state, installs anything, or adds a variable to the Console's environment.
|
|
6
|
+
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
7
|
+
const fs = require('node:fs');
|
|
8
|
+
const path = require('node:path');
|
|
9
|
+
const { spawn } = require('node:child_process');
|
|
10
|
+
|
|
11
|
+
/** The package's entry, fixed by its own contract (093 IC-002). */
|
|
12
|
+
const CONSOLE_BIN = path.join('bin', 'doflow-ui.js');
|
|
13
|
+
const USAGE = 'doflow ui: usage: doflow ui [<project>] [--port N] [--listen-address <private IP> --tls-cert <absolute path> --tls-key <absolute path>]';
|
|
14
|
+
const NOT_INSTALLED = 'doflow ui: the Console is not installed. Install it with: npm install -g @khoavu882/doflow-ui';
|
|
15
|
+
|
|
16
|
+
/** The Console bin when `dir` holds both the package's package.json and its bin, else null. */
|
|
17
|
+
function consoleBinIn(dir ) {
|
|
18
|
+
const bin = path.join(dir, CONSOLE_BIN);
|
|
19
|
+
return fs.existsSync(path.join(dir, 'package.json')) && fs.existsSync(bin) ? bin : null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* IC-008 order. First the core's sibling: npm puts both packages in the same
|
|
24
|
+
* `node_modules/@khoavu882/`, global or project, so that copy was installed next to this very core.
|
|
25
|
+
* Then a walk up from the project for `node_modules/@khoavu882/doflow-ui`.
|
|
26
|
+
*/
|
|
27
|
+
function findConsole(coreRoot , project ) {
|
|
28
|
+
const sibling = consoleBinIn(path.join(coreRoot, '..', 'doflow-ui'));
|
|
29
|
+
if (sibling) return sibling;
|
|
30
|
+
for (let dir = project; ; dir = path.dirname(dir)) {
|
|
31
|
+
const bin = consoleBinIn(path.join(dir, 'node_modules', '@khoavu882', 'doflow-ui'));
|
|
32
|
+
if (bin) return bin;
|
|
33
|
+
if (path.dirname(dir) === dir) return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** `coreRoot` is this core's package root, passed in by the COMMANDS table (src/helper/repo-root.js owns it). */
|
|
38
|
+
function cmdUi(o , coreRoot ) {
|
|
39
|
+
const port = o.port;
|
|
40
|
+
const uiFlags = new Set(['--listen-address', '--tls-cert', '--tls-key']);
|
|
41
|
+
const otherFlags = o.flagsGiven.filter((flag ) => {
|
|
42
|
+
const name = flag.split('=', 1)[0];
|
|
43
|
+
return name !== '--port' && !uiFlags.has(name);
|
|
44
|
+
});
|
|
45
|
+
const remoteValues = [o.listenAddress, o.tlsCert, o.tlsKey];
|
|
46
|
+
const remoteCount = remoteValues.filter((value ) => value !== undefined).length;
|
|
47
|
+
if (o.positional.length > 1 || otherFlags.length > 0
|
|
48
|
+
|| (remoteCount !== 0 && remoteCount !== remoteValues.length)
|
|
49
|
+
|| (port !== undefined && !(/^[0-9]{1,5}$/.test(port) && Number(port) <= 65535))) {
|
|
50
|
+
console.error(USAGE);
|
|
51
|
+
process.exitCode = 2;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const project = path.resolve(o.positional[0] ?? '.');
|
|
55
|
+
const bin = findConsole(coreRoot, project);
|
|
56
|
+
if (!bin) {
|
|
57
|
+
console.error(NOT_INSTALLED);
|
|
58
|
+
process.exitCode = 2;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// stderr, so stdout carries only the Console's own one line (093 IC-002).
|
|
62
|
+
console.error(`doflow ui: using ${bin}`);
|
|
63
|
+
const args = [bin, '--core', path.join(coreRoot, 'bin', 'doflow.js')];
|
|
64
|
+
if (o.positional.length > 0) args.push('--project', project);
|
|
65
|
+
if (port !== undefined) args.push('--port', port);
|
|
66
|
+
if (o.listenAddress !== undefined) args.push('--listen-address', o.listenAddress);
|
|
67
|
+
if (o.tlsCert !== undefined) args.push('--tls-cert', o.tlsCert);
|
|
68
|
+
if (o.tlsKey !== undefined) args.push('--tls-key', o.tlsKey);
|
|
69
|
+
const child = spawn(process.execPath, args, { stdio: 'inherit' });
|
|
70
|
+
|
|
71
|
+
// Stay up until the Console exits, so its exit code is ours. A terminal Ctrl-C already reaches the
|
|
72
|
+
// Console through the process group; it is forwarded as SIGTERM, which the Console handles once
|
|
73
|
+
// separately from SIGINT, so the second delivery does not cut its 2 s shutdown short.
|
|
74
|
+
const forward = () => { child.kill('SIGTERM'); };
|
|
75
|
+
process.on('SIGINT', forward);
|
|
76
|
+
process.on('SIGTERM', forward);
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
let settled = false;
|
|
79
|
+
const settle = (finish ) => {
|
|
80
|
+
if (settled) return;
|
|
81
|
+
settled = true;
|
|
82
|
+
process.off('SIGINT', forward);
|
|
83
|
+
process.off('SIGTERM', forward);
|
|
84
|
+
finish();
|
|
85
|
+
resolve();
|
|
86
|
+
};
|
|
87
|
+
child.on('error', (error ) => settle(() => {
|
|
88
|
+
console.error(`doflow ui: cannot start ${bin}: ${error.message}`);
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
}));
|
|
91
|
+
// Killed by a signal: die by the same signal, the shell's own way of forwarding it.
|
|
92
|
+
child.on('exit', (code , signal ) => settle(() => {
|
|
93
|
+
if (signal) process.kill(process.pid, signal);
|
|
94
|
+
else process.exitCode = code ?? 1;
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = cmdUi;
|
|
@@ -19,7 +19,7 @@ const { loadRegistry } = require('../../registry/index.js');
|
|
|
19
19
|
const { storageAfterInstall } = require('../../runtime/storage/upkeep.js');
|
|
20
20
|
const { applyLifecycle, recordMcpOwnership, retentionSummary } = require('../../lifecycle/index.js');
|
|
21
21
|
const {
|
|
22
|
-
codexScope, registryLifecycleView, printRegistryLifecycle, printPlanNotices, assertSafeRegistryPlan,
|
|
22
|
+
codexScope, registryLifecycleView, printRegistryLifecycle, printRetiredPlans, printPlanNotices, assertSafeRegistryPlan,
|
|
23
23
|
lockDocument, lockDelta, recordLock,
|
|
24
24
|
} = require('../../lifecycle/view.js');
|
|
25
25
|
const {
|
|
@@ -51,7 +51,7 @@ function cmdUpdate(o ) {
|
|
|
51
51
|
// One lifecycle view across every requested target — computed unconditionally (not only under
|
|
52
52
|
// --dry-run) so its safety gate and its plan are the exact same object the real apply below uses.
|
|
53
53
|
const lifecycleView = registryLifecycleView({ registry, repoRoot: REPO_ROOT, scope, dirs, targets,
|
|
54
|
-
mcpSelections: selection.selections, mcpAdoptable: selection.adoptable, retainedMcpIds: selection.retainedMcpIds,
|
|
54
|
+
mcpSelections: selection.selections, mcpAdoptable: selection.adoptable, retainedMcpIds: selection.retainedMcpIds, operation: 'update',
|
|
55
55
|
force: o.force, permissions: o.permissions === true, statusline: o.statusline === true });
|
|
56
56
|
if (!lifecycleView.plan.safe) { assertSafeRegistryPlan(lifecycleView); return; }
|
|
57
57
|
printMcpSelection(lifecycleView, selection.sources, { requested: o.mcp, prefix: o.dryRun ? '[DRY]' : '[INFO]' });
|
|
@@ -139,6 +139,7 @@ function cmdUpdate(o ) {
|
|
|
139
139
|
const owned = result.ledger.resources.filter((resource ) => resource.harness === target.harness).length;
|
|
140
140
|
console.log(`[INFO] ${target.harness}: lifecycle verified (${owned} owned resource(s))`);
|
|
141
141
|
}
|
|
142
|
+
printRetiredPlans(lifecycleView);
|
|
142
143
|
printPlanNotices(lifecycleView);
|
|
143
144
|
// As remove does: a file this update leaves standing because a harness outside the run still
|
|
144
145
|
// claims it is said, not implied. The per-file prune and keep lines are the plan notices above.
|