@khoavu882/doflow 0.0.0-stage → 2.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +132 -2
- package/bin/doflow.js +44 -0
- package/core/.antigravity-plugin/hooks.json +39 -0
- package/core/.antigravity-plugin/mcp_config.json +18 -0
- package/core/.antigravity-plugin/plugin.json +31 -0
- package/core/.claude-plugin/marketplace.json +20 -0
- package/core/.claude-plugin/plugin.json +21 -0
- package/core/.codex-plugin/marketplace.json +20 -0
- package/core/.codex-plugin/plugin.json +35 -0
- package/core/.plugin/plugin.json +19 -0
- package/core/harnesses/antigravity/hooks/pre-implementation-gate.sh +9 -0
- package/core/harnesses/antigravity/hooks/stop-check.sh +10 -0
- package/core/harnesses/claude/hooks/lib.sh +304 -0
- package/core/harnesses/claude/hooks/mcp-tool-guard.sh +20 -0
- package/core/harnesses/claude/hooks/permission-audit.sh +47 -0
- package/core/harnesses/claude/hooks/post-compact.sh +74 -0
- package/core/harnesses/claude/hooks/post-edit-lint.sh +36 -0
- package/core/harnesses/claude/hooks/post-tool-failure.sh +47 -0
- package/core/harnesses/claude/hooks/pre-bash-guard.sh +20 -0
- package/core/harnesses/claude/hooks/pre-compact.sh +43 -0
- package/core/harnesses/claude/hooks/pre-implement-gate.sh +21 -0
- package/core/harnesses/claude/hooks/session-end.sh +89 -0
- package/core/harnesses/claude/hooks/session-start.sh +5 -0
- package/core/harnesses/claude/hooks/skill-config-audit.sh +39 -0
- package/core/harnesses/claude/hooks/stop-check.sh +5 -0
- package/core/harnesses/claude/hooks/subagent-audit.sh +7 -0
- package/core/harnesses/claude/hooks/user-prompt-submit.sh +5 -0
- package/core/harnesses/claude/settings/keybindings.json +20 -0
- package/core/harnesses/claude/settings/settings.json +201 -0
- package/core/harnesses/claude/statusline/doflow-statusline.sh +49 -0
- package/core/harnesses/codex/agents/core-implementer.toml +7 -0
- package/core/harnesses/codex/agents/quality-guardian.toml +8 -0
- package/core/harnesses/codex/agents/research-writer.toml +8 -0
- package/core/harnesses/codex/agents/spec-analyst.toml +8 -0
- package/core/harnesses/codex/agents/system-architect.toml +9 -0
- package/core/harnesses/codex/config/config.toml +10 -0
- package/core/harnesses/codex/hooks/hooks.json +122 -0
- package/core/harnesses/codex/hooks/lib.sh +335 -0
- package/core/harnesses/codex/hooks/mcp-tool-guard.sh +18 -0
- package/core/harnesses/codex/hooks/post-edit-lint.impl.sh +52 -0
- package/core/harnesses/codex/hooks/post-edit-lint.sh +6 -0
- package/core/harnesses/codex/hooks/pre-bash-guard.sh +18 -0
- package/core/harnesses/codex/hooks/pre-compact.impl.sh +46 -0
- package/core/harnesses/codex/hooks/pre-compact.sh +9 -0
- package/core/harnesses/codex/hooks/pre-implement-gate.sh +19 -0
- package/core/harnesses/codex/hooks/session-end.impl.sh +92 -0
- package/core/harnesses/codex/hooks/session-end.sh +5 -0
- package/core/harnesses/codex/hooks/session-start.sh +5 -0
- package/core/harnesses/codex/hooks/stop-check.sh +8 -0
- package/core/harnesses/codex/hooks/subagent-audit.sh +8 -0
- package/core/harnesses/codex/hooks/user-prompt-submit.sh +6 -0
- package/core/harnesses/gemini/hooks/hooks.json +77 -0
- package/core/harnesses/gemini/hooks/lib.sh +302 -0
- package/core/harnesses/gemini/hooks/mcp-tool-guard.sh +21 -0
- package/core/harnesses/gemini/hooks/post-edit-lint.sh +39 -0
- package/core/harnesses/gemini/hooks/pre-bash-guard.sh +21 -0
- package/core/harnesses/gemini/hooks/pre-compact.sh +38 -0
- package/core/harnesses/gemini/hooks/pre-implement-gate.sh +22 -0
- package/core/harnesses/gemini/hooks/session-end.impl.sh +89 -0
- package/core/harnesses/gemini/hooks/session-end.sh +5 -0
- package/core/harnesses/gemini/hooks/session-start.sh +5 -0
- package/core/harnesses/gemini/settings/adapter-defaults.json +4 -0
- package/core/harnesses/kiro/agents/doflow.json +58 -0
- package/core/harnesses/kiro/hooks/doflow.json +53 -0
- package/core/harnesses/kiro/hooks/lib.sh +324 -0
- package/core/harnesses/kiro/hooks/mcp-tool-guard.sh +9 -0
- package/core/harnesses/kiro/hooks/pre-bash-guard.sh +9 -0
- package/core/harnesses/kiro/hooks/pre-implement-gate.sh +9 -0
- package/core/harnesses/kiro/hooks/session-start.sh +9 -0
- package/core/harnesses/kiro/hooks/stop-check.sh +43 -0
- package/core/harnesses/shared/hooks/ENVELOPE_MIGRATION.md +39 -0
- package/core/harnesses/shared/hooks/adapters/antigravity.js +111 -0
- package/core/harnesses/shared/hooks/adapters/arg-fields.js +19 -0
- package/core/harnesses/shared/hooks/adapters/gemini.js +114 -0
- package/core/harnesses/shared/hooks/hooks.json +47 -0
- package/core/harnesses/shared/hooks/policies/blocked-patterns.conf +91 -0
- package/core/harnesses/shared/hooks/policies/capture-failure.sh +97 -0
- package/core/harnesses/shared/hooks/policies/deny-json.sh +29 -0
- package/core/harnesses/shared/hooks/policies/lib.sh +501 -0
- package/core/harnesses/shared/hooks/policies/mcp-policy.conf +21 -0
- package/core/harnesses/shared/hooks/policies/mcp-tool-guard.sh +91 -0
- package/core/harnesses/shared/hooks/policies/pre-bash-guard.sh +328 -0
- package/core/harnesses/shared/hooks/policies/pre-implementation-gate.sh +496 -0
- package/core/harnesses/shared/hooks/policies/prompt-nudge.jq +131 -0
- package/core/harnesses/shared/hooks/policies/session-context.sh +141 -0
- package/core/harnesses/shared/hooks/policies/stop-check.sh +264 -0
- package/core/harnesses/shared/hooks/policies/subagent-audit.sh +46 -0
- package/core/harnesses/shared/hooks/policies/user-prompt-submit.sh +235 -0
- package/core/harnesses/shared/hooks/stream-hook-runner.js +590 -0
- package/core/harnesses/shared/locator/doflow-run +87 -0
- package/core/registry/advice.json +101 -0
- package/core/registry/assets.json +792 -0
- package/core/registry/capabilities.json +120 -0
- package/core/registry/contracts.json +189 -0
- package/core/registry/external-tools.json +191 -0
- package/core/registry/harnesses.json +2062 -0
- package/core/registry/lifecycle.json +231 -0
- package/core/registry/mcp.json +18 -0
- package/core/registry/models.json +79 -0
- package/core/registry/readiness-templates.json +118 -0
- package/core/registry/routes.json +47 -0
- package/core/registry/storage.json +1061 -0
- package/core/registry/verification.json +258 -0
- package/core/registry/workflows.json +790 -0
- package/core/shared/agent-specs/core-implementer.md +73 -0
- package/core/shared/agent-specs/quality-guardian.md +28 -0
- package/core/shared/agent-specs/research-writer.md +31 -0
- package/core/shared/agent-specs/spec-analyst.md +33 -0
- package/core/shared/agent-specs/system-architect.md +29 -0
- package/core/shared/guidance/DOFLOW_CORE.md +8 -0
- package/core/shared/guidance/FLAGS.md +25 -0
- package/core/shared/guidance/PRINCIPLES.md +61 -0
- package/core/shared/guidance/VERSION +1 -0
- package/core/shared/guidance/mcp/MCP_Context7.md +18 -0
- package/core/shared/guidance/mcp/MCP_Sequential.md +17 -0
- package/core/shared/guidance/modes/MODE_Brainstorming.md +46 -0
- package/core/shared/guidance/modes/MODE_DeepResearch.md +69 -0
- package/core/shared/guidance/modes/MODE_Introspection.md +33 -0
- package/core/shared/guidance/modes/MODE_Orchestration.md +57 -0
- package/core/shared/guidance/modes/MODE_Task_Management.md +74 -0
- package/core/shared/guidance/pointers/claude-gemini.md +2 -0
- package/core/shared/guidance/pointers/codex.md +6 -0
- package/core/shared/guidance/references/ARTIFACT_FORMAT.md +373 -0
- package/core/shared/guidance/references/ARTIFACT_VOICE.md +104 -0
- package/core/shared/guidance/references/CONSTITUTION_BASE.md +47 -0
- package/core/shared/guidance/references/DIAGRAM_GUIDE.md +161 -0
- package/core/shared/guidance/references/DOFLOW_CHAIN.md +87 -0
- package/core/shared/guidance/references/EVIDENCE_LEDGER.md +93 -0
- package/core/shared/guidance/references/MODEL_SELECTION.md +74 -0
- package/core/shared/guidance/references/ORCHESTRATION.md +36 -0
- package/core/shared/guidance/references/RESEARCH_CONFIG.md +21 -0
- package/core/shared/guidance/references/WORKFLOW_HANDOFF.md +81 -0
- package/core/shared/guidance/rules/RULE_01_SAFETY.md +25 -0
- package/core/shared/guidance/rules/RULE_02_WORKFLOW.md +23 -0
- package/core/shared/guidance/rules/RULE_03_QUALITY.md +14 -0
- package/core/shared/guidance/rules/RULE_04_QUESTIONS.md +46 -0
- package/core/shared/scripts/doflow/assets/mermaid-theme.json +46 -0
- package/core/shared/scripts/doflow/bash/do-exec-paths.sh +167 -0
- package/core/shared/scripts/doflow/bash/do-git-state.sh +546 -0
- package/core/shared/scripts/doflow/bash/do-parallel-check.sh +208 -0
- package/core/shared/scripts/doflow/bash/do-paths.sh +347 -0
- package/core/shared/scripts/doflow/bash/do-prereqs.sh +66 -0
- package/core/shared/scripts/doflow/bash/do-review-package.sh +127 -0
- package/core/shared/scripts/doflow/bash/do-task-brief.sh +698 -0
- package/core/shared/scripts/doflow/bash/render-audit.sh +224 -0
- package/core/shared/scripts/doflow/bash/render-diagrams.sh +177 -0
- package/core/shared/scripts/doflow/bash/render-puml.sh +223 -0
- package/core/shared/scripts/doflow/bash/sync-context.sh +66 -0
- package/core/shared/scripts/doflow/bash/validate-artifacts.sh +526 -0
- package/core/shared/scripts/doflow/bin/doflow-run +592 -0
- package/core/shared/skills/do/SKILL.md +128 -0
- package/core/shared/skills/do/references/estimation.md +13 -0
- package/core/shared/skills/do/references/pm_routing.md +25 -0
- package/core/shared/skills/do/references/tool_matrix.md +52 -0
- package/core/shared/skills/do-brainstorm/SKILL.md +252 -0
- package/core/shared/skills/do-code-review/README.md +49 -0
- package/core/shared/skills/do-code-review/SKILL.md +333 -0
- package/core/shared/skills/do-code-review/assets/sample_c_clean.c +71 -0
- package/core/shared/skills/do-code-review/assets/sample_c_smells.c +66 -0
- package/core/shared/skills/do-code-review/assets/sample_cpp_shift.cpp +19 -0
- package/core/shared/skills/do-code-review/assets/sample_csharp_clean.cs +100 -0
- package/core/shared/skills/do-code-review/assets/sample_csharp_smells.cs +78 -0
- package/core/shared/skills/do-code-review/assets/sample_java_clean.java +55 -0
- package/core/shared/skills/do-code-review/assets/sample_java_smells.java +56 -0
- package/core/shared/skills/do-code-review/assets/sample_json_clean.json +7 -0
- package/core/shared/skills/do-code-review/assets/sample_markdown_clean.md +30 -0
- package/core/shared/skills/do-code-review/assets/sample_markdown_smells.md +29 -0
- package/core/shared/skills/do-code-review/assets/sample_shell_heredoc.sh +38 -0
- package/core/shared/skills/do-code-review/assets/sample_shell_smells.sh +15 -0
- package/core/shared/skills/do-code-review/assets/sample_typescript_strings.ts +36 -0
- package/core/shared/skills/do-code-review/assets/sample_yaml_smells.yaml +6 -0
- package/core/shared/skills/do-code-review/content-types/config.md +83 -0
- package/core/shared/skills/do-code-review/content-types/markdown.md +132 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_c_clean_quality.json +79 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_c_smells_quality.json +169 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_cpp_shift_quality.json +49 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_clean_quality.json +149 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_csharp_smells_quality.json +157 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_java_clean_quality.json +67 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_java_smells_quality.json +97 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_json_clean_quality.json +33 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_clean_quality.json +1 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_markdown_smells_quality.json +16 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_shell_heredoc_quality.json +54 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_shell_smells_quality.json +91 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_typescript_strings_quality.json +60 -0
- package/core/shared/skills/do-code-review/expected_outputs/sample_yaml_smells_quality.json +46 -0
- package/core/shared/skills/do-code-review/languages/c.md +103 -0
- package/core/shared/skills/do-code-review/languages/cpp.md +103 -0
- package/core/shared/skills/do-code-review/languages/csharp.md +97 -0
- package/core/shared/skills/do-code-review/languages/dart.md +108 -0
- package/core/shared/skills/do-code-review/languages/go.md +92 -0
- package/core/shared/skills/do-code-review/languages/java.md +103 -0
- package/core/shared/skills/do-code-review/languages/kotlin.md +88 -0
- package/core/shared/skills/do-code-review/languages/php.md +109 -0
- package/core/shared/skills/do-code-review/languages/python.md +94 -0
- package/core/shared/skills/do-code-review/languages/ruby.md +105 -0
- package/core/shared/skills/do-code-review/languages/rust.md +99 -0
- package/core/shared/skills/do-code-review/languages/shell.md +90 -0
- package/core/shared/skills/do-code-review/languages/swift.md +88 -0
- package/core/shared/skills/do-code-review/languages/typescript.md +97 -0
- package/core/shared/skills/do-code-review/review-policy.json +47 -0
- package/core/shared/skills/do-code-review/rules/universal.md +49 -0
- package/core/shared/skills/do-code-review/scripts/code_quality_checker.py +1696 -0
- package/core/shared/skills/do-code-review/scripts/doc_quality_checker.py +532 -0
- package/core/shared/skills/do-code-review/scripts/pr_analyzer.py +620 -0
- package/core/shared/skills/do-code-review/scripts/review_report_generator.py +505 -0
- package/core/shared/skills/do-constitution/SKILL.md +72 -0
- package/core/shared/skills/do-design/SKILL.md +212 -0
- package/core/shared/skills/do-diagnose/SKILL.md +156 -0
- package/core/shared/skills/do-diagnose/references/code_audit.md +15 -0
- package/core/shared/skills/do-diagnose/references/refactoring.md +12 -0
- package/core/shared/skills/do-diagnose/references/root_cause.md +17 -0
- package/core/shared/skills/do-document/SKILL.md +81 -0
- package/core/shared/skills/do-document/references/api-reference.md +42 -0
- package/core/shared/skills/do-document/references/deep_research.md +18 -0
- package/core/shared/skills/do-document/references/embedded-research.md +11 -0
- package/core/shared/skills/do-document/references/implementation-flow.md +105 -0
- package/core/shared/skills/do-document/references/index_generator.md +9 -0
- package/core/shared/skills/do-document/references/user-guide.md +22 -0
- package/core/shared/skills/do-execute-plan/SKILL.md +261 -0
- package/core/shared/skills/do-execute-plan/references/handoff_record.md +57 -0
- package/core/shared/skills/do-execute-plan/references/parallel_dispatch.md +92 -0
- package/core/shared/skills/do-execute-plan/references/readiness_gate.md +155 -0
- package/core/shared/skills/do-execute-plan/references/run_position.md +63 -0
- package/core/shared/skills/do-execute-plan/references/scaffold.md +441 -0
- package/core/shared/skills/do-execute-plan/references/task_attempts.md +41 -0
- package/core/shared/skills/do-flow/SKILL.md +186 -0
- package/core/shared/skills/do-flow/references/task_classes.md +134 -0
- package/core/shared/skills/do-git/SKILL.md +115 -0
- package/core/shared/skills/do-git/references/hotfix-ritual.md +44 -0
- package/core/shared/skills/do-git/references/lifecycle-policy.md +54 -0
- package/core/shared/skills/do-git/references/release-ritual.md +64 -0
- package/core/shared/skills/do-implement/SKILL.md +222 -0
- package/core/shared/skills/do-plan/SKILL.md +219 -0
- package/core/shared/skills/do-test/SKILL.md +113 -0
- package/core/shared/templates/doflow/constitution-template.md +28 -0
- package/core/shared/templates/doflow/data-model-template.md +169 -0
- package/core/shared/templates/doflow/design-template.md +193 -0
- package/core/shared/templates/doflow/external-contract-template.md +35 -0
- package/core/shared/templates/doflow/intent-template.md +45 -0
- package/core/shared/templates/doflow/plan-template.md +151 -0
- package/core/shared/templates/doflow/question-log-template.md +51 -0
- package/core/shared/templates/doflow/requirement-template.md +126 -0
- package/core/shared/templates/doflow/specs-template.md +55 -0
- package/core/shared/templates/doflow/state-template.md +59 -0
- package/core/shared/workflows/do-flow-chain.md +17 -0
- package/package.json +48 -4
- package/src/adapters/antigravity/index.js +631 -0
- package/src/adapters/claude/index.js +548 -0
- package/src/adapters/claude/mcp.js +94 -0
- package/src/adapters/codex/agents.js +208 -0
- package/src/adapters/codex/config.js +272 -0
- package/src/adapters/codex/hooks.js +203 -0
- package/src/adapters/codex/index.js +707 -0
- package/src/adapters/codex/mcp.js +271 -0
- package/src/adapters/codex/native-projection.js +34 -0
- package/src/adapters/copilot/index.js +413 -0
- package/src/adapters/copy-tree.js +620 -0
- package/src/adapters/gemini/hooks.js +210 -0
- package/src/adapters/gemini/index.js +390 -0
- package/src/adapters/hook-commands.js +60 -0
- package/src/adapters/index.js +106 -0
- package/src/adapters/kiro/index.js +310 -0
- package/src/adapters/mcp-entries.js +331 -0
- package/src/adapters/opencode/index.js +466 -0
- package/src/adapters/pi/index.js +279 -0
- package/src/adapters/pi/json-members.js +185 -0
- package/src/adapters/pi/mcp.js +373 -0
- package/src/adapters/resolve-source.js +19 -0
- package/src/cli/commands/install.js +218 -0
- package/src/cli/commands/list-backups.js +21 -0
- package/src/cli/commands/reconcile.js +120 -0
- package/src/cli/commands/remove.js +82 -0
- package/src/cli/commands/rollback.js +172 -0
- package/src/cli/commands/self-update.js +33 -0
- package/src/cli/commands/status.js +138 -0
- package/src/cli/commands/tools.js +92 -0
- package/src/cli/commands/update.js +162 -0
- package/src/cli/index.js +568 -0
- package/src/cli/runtime-commands.js +281 -0
- package/src/cli/shared.js +218 -0
- package/src/helper/bash-helper.js +34 -0
- package/src/helper/git.js +24 -0
- package/src/helper/guardrails.js +49 -0
- package/src/helper/harness-paths.js +140 -0
- package/src/helper/marker-merge.js +116 -0
- package/src/helper/prompt.js +61 -0
- package/src/helper/repo-root.js +29 -0
- package/src/helper/settings-merge.js +151 -0
- package/src/helper/settings-scope.js +33 -0
- package/src/helper/toml.js +244 -0
- package/src/install/backup-set.js +149 -0
- package/src/install/backup.js +724 -0
- package/src/install/context.js +58 -0
- package/src/install/manifest.js +145 -0
- package/src/install/mcp.js +254 -0
- package/src/install/paths.js +84 -0
- package/src/install/targets.js +90 -0
- package/src/install/tool-lifecycle.js +151 -0
- package/src/lifecycle/bash-availability.js +25 -0
- package/src/lifecycle/index.js +812 -0
- package/src/lifecycle/mcp-index.js +28 -0
- package/src/lifecycle/policies.js +73 -0
- package/src/lifecycle/view.js +175 -0
- package/src/registry/index.js +611 -0
- package/src/release/build-package.js +91 -0
- package/src/release/changelog-section.js +70 -0
- package/src/release/sync-plugin-versions.js +66 -0
- package/src/runtime/advice/cli.js +283 -0
- package/src/runtime/advice/client.js +324 -0
- package/src/runtime/advice/config.js +189 -0
- package/src/runtime/advice/doctor.js +169 -0
- package/src/runtime/advice/endpoint-guard.js +134 -0
- package/src/runtime/advice/kinds.js +154 -0
- package/src/runtime/advice/providers/ollama-systemone.js +209 -0
- package/src/runtime/advice/record.js +166 -0
- package/src/runtime/advice/registry.js +170 -0
- package/src/runtime/advice/strength.js +66 -0
- package/src/runtime/brief-tools.js +342 -0
- package/src/runtime/c4-project.js +371 -0
- package/src/runtime/capability-router.js +484 -0
- package/src/runtime/checkouts.js +170 -0
- package/src/runtime/claims.js +468 -0
- package/src/runtime/cli-result.js +55 -0
- package/src/runtime/cli.js +678 -0
- package/src/runtime/command-detect.js +516 -0
- package/src/runtime/context-pack.js +492 -0
- package/src/runtime/decision-register.js +493 -0
- package/src/runtime/evidence-ledger.js +338 -0
- package/src/runtime/failure/capture.js +272 -0
- package/src/runtime/failure/classifier.js +68 -0
- package/src/runtime/failure/cli.js +178 -0
- package/src/runtime/failure/home.js +64 -0
- package/src/runtime/failure/store.js +226 -0
- package/src/runtime/feature-resolve.js +79 -0
- package/src/runtime/freshness.js +177 -0
- package/src/runtime/health.js +863 -0
- package/src/runtime/history-compactor.js +237 -0
- package/src/runtime/implementation-gate.js +321 -0
- package/src/runtime/inventory/coverage.js +218 -0
- package/src/runtime/inventory/identity.js +65 -0
- package/src/runtime/inventory/index.js +705 -0
- package/src/runtime/inventory/precedence.js +134 -0
- package/src/runtime/inventory/read-scopes.js +131 -0
- package/src/runtime/inventory/siblings.js +192 -0
- package/src/runtime/knowledge/chunker.js +124 -0
- package/src/runtime/knowledge/hybrid.js +149 -0
- package/src/runtime/knowledge/index-store.js +145 -0
- package/src/runtime/knowledge/retrieval.js +194 -0
- package/src/runtime/leak-scan.js +185 -0
- package/src/runtime/lifecycle/cli.js +276 -0
- package/src/runtime/lifecycle/event-store.js +340 -0
- package/src/runtime/lifecycle/fold.js +353 -0
- package/src/runtime/lifecycle/followup.js +432 -0
- package/src/runtime/lifecycle/goal.js +249 -0
- package/src/runtime/lifecycle/intent-writer.js +86 -0
- package/src/runtime/lifecycle/overview.js +292 -0
- package/src/runtime/lifecycle/release.js +241 -0
- package/src/runtime/lifecycle/report-store.js +221 -0
- package/src/runtime/lifecycle/retention.js +212 -0
- package/src/runtime/lifecycle/root.js +71 -0
- package/src/runtime/lifecycle/status.js +353 -0
- package/src/runtime/lifecycle/store-upkeep.js +393 -0
- package/src/runtime/locator-resolve.js +158 -0
- package/src/runtime/mask.js +210 -0
- package/src/runtime/mcp-consultations.js +412 -0
- package/src/runtime/mcp-reach.js +157 -0
- package/src/runtime/model-router.js +153 -0
- package/src/runtime/outcome.js +467 -0
- package/src/runtime/reach.js +148 -0
- package/src/runtime/readiness-record.js +150 -0
- package/src/runtime/readiness.js +435 -0
- package/src/runtime/recovery.js +282 -0
- package/src/runtime/research-request.js +231 -0
- package/src/runtime/retrieval-plan.js +578 -0
- package/src/runtime/scaffold/artifacts.js +217 -0
- package/src/runtime/scaffold/fingerprint.js +56 -0
- package/src/runtime/scaffold/generate.js +911 -0
- package/src/runtime/scaffold/languages.js +245 -0
- package/src/runtime/storage/cli.js +64 -0
- package/src/runtime/storage/engine.js +249 -0
- package/src/runtime/storage/registry.js +130 -0
- package/src/runtime/storage/roots.js +63 -0
- package/src/runtime/storage/rules.js +282 -0
- package/src/runtime/storage/upkeep.js +243 -0
- package/src/runtime/storage/work-status.js +326 -0
- package/src/runtime/task-attempts.js +415 -0
- package/src/runtime/task-classifier.js +550 -0
- package/src/runtime/task-scope.js +130 -0
- package/src/runtime/task-state.js +176 -0
- package/src/runtime/trace/indicators.js +235 -0
- package/src/runtime/trace/ledger.js +626 -0
- package/src/runtime/trace/render.js +76 -0
- package/src/runtime/trace/views.js +459 -0
- package/src/runtime/verification/contract-runner.js +341 -0
- package/src/runtime/verification/engine.js +1461 -0
- package/src/runtime/verification/registry.js +130 -0
- package/src/runtime/verification/scope-bound.js +418 -0
- package/src/runtime/verification/test-selection.js +172 -0
- package/src/runtime/workflow-engine.js +588 -0
- package/src/runtime/workflow-orchestrator.js +953 -0
- package/src/runtime/worktree.js +340 -0
- package/src/state/index.js +193 -0
- package/src/state/lockfile.js +136 -0
- package/src/state/run-lock.js +408 -0
- package/types/node-commonjs.d.ts +68 -0
- package/types/runtime.d.ts +91 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MCP reach: for each harness the ledgers say is installed, which MCP servers does that harness
|
|
7
|
+
* have — selected from DoFlow's catalog, configured by hand, absent, or out of the catalog's reach.
|
|
8
|
+
* Read-only: it reads the same ledgers `evaluateReach` reads and asks each adapter's `discover()`
|
|
9
|
+
* for the server names it can see (`mcpConfigured`) and whether that view is complete
|
|
10
|
+
* (`mcpComplete`). A server is reported absent only from a complete view; otherwise its state is
|
|
11
|
+
* unknown. It never starts a server and opens no connection, so the same inputs give the same answer.
|
|
12
|
+
*
|
|
13
|
+
* Server names come from the registries only (`mcp.json`, and the `mcp.server` of capability
|
|
14
|
+
* providers); nothing here names one.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('node:fs');
|
|
18
|
+
const os = require('node:os');
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
const { readLedger } = require('../state/index.js');
|
|
21
|
+
const { resolveAdapter } = require('../adapters/index.js');
|
|
22
|
+
const { evaluateReach } = require('./reach.js');
|
|
23
|
+
|
|
24
|
+
const SCOPE_ORDER = { project: 0, global: 1 };
|
|
25
|
+
|
|
26
|
+
/** Every server id the answer covers: the MCP catalog, then each provider's own MCP server. */
|
|
27
|
+
function serverIdsOf(registry ) {
|
|
28
|
+
const ids = (registry.mcp || []).map((server ) => server.id);
|
|
29
|
+
for (const capability of (Object.values(registry.capabilities || {}) )) {
|
|
30
|
+
for (const provider of capability.providers || []) if (provider.mcp?.server) ids.push(provider.mcp.server);
|
|
31
|
+
}
|
|
32
|
+
return [...new Set(ids)];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The MCP file an adapter's discovery could not read and the fixed reason it gives, or null.
|
|
36
|
+
* Reasons come from the adapters (invalid JSON, wrong shape), never from file content. */
|
|
37
|
+
function unreadableDetail(discovery ) {
|
|
38
|
+
for (const [file, read] of (Object.entries(discovery.mcpSnapshot || {}) )) if (read?.ok === false) return { detail: read.reason, file };
|
|
39
|
+
for (const [file, read] of (Object.entries(discovery.mcp || {}) )) if (read?.doc?.ok === false) return { detail: read.doc.reason, file };
|
|
40
|
+
if (discovery.settings?.error) return { detail: 'invalid JSON', ...(discovery.paths?.settings ? { file: discovery.paths.settings } : {}) };
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A server is absent (`not-taken`, `not-selected`) only where the adapter read every source its
|
|
45
|
+
* harness merges (`mcpComplete: true`); anywhere else absence is no proof and the state is unknown. */
|
|
46
|
+
function stateOf(row , id ) {
|
|
47
|
+
if (row.selected.has(id)) return 'selected';
|
|
48
|
+
if (row.configured?.includes(id)) return 'configured';
|
|
49
|
+
if (row.unreadable || row.configured === null || !row.complete) return 'unknown';
|
|
50
|
+
return row.catalog === 'not-taken' ? 'not-taken' : 'not-selected';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {Object} options
|
|
55
|
+
* @param {Object} options.registry loaded registry
|
|
56
|
+
* @param {string} options.projectRoot
|
|
57
|
+
* @param {string} [options.homeDir]
|
|
58
|
+
* @param {Object} [options.fsImpl]
|
|
59
|
+
* @param {Object} options.adapters adapter registry (`buildAdapterRegistry()`)
|
|
60
|
+
* @returns {{harnesses: Object[], unreadable: Object[]}} plain data; `anyHarnessHas` and `addCommand` ride along unenumerated
|
|
61
|
+
*/
|
|
62
|
+
function mcpReach({ registry, projectRoot, homeDir = os.homedir(), fsImpl = fs, adapters } ) {
|
|
63
|
+
const serverIds = serverIdsOf(registry);
|
|
64
|
+
const catalogIds = (registry.mcp || []).map((server ) => server.id);
|
|
65
|
+
const harnessOrder = registry.harnesses.map((harness ) => harness.id);
|
|
66
|
+
const { rows: reached } = evaluateReach({ registry, projectRoot, homeDir, fsImpl });
|
|
67
|
+
|
|
68
|
+
const ledgers = new Map();
|
|
69
|
+
const ledgerOf = ({ scope, installRoot } ) => {
|
|
70
|
+
const key = `${scope}\0${installRoot}`;
|
|
71
|
+
if (!ledgers.has(key)) {
|
|
72
|
+
let ledger = null;
|
|
73
|
+
try { ledger = readLedger(path.join(installRoot, '.doflow', 'state'), { fsImpl }); } catch { /* evaluateReach reports it */ }
|
|
74
|
+
ledgers.set(key, ledger);
|
|
75
|
+
}
|
|
76
|
+
return ledgers.get(key);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const unreadable = [];
|
|
80
|
+
const seen = new Set();
|
|
81
|
+
const rows = [];
|
|
82
|
+
for (const { harness: id, scope, installRoot } of reached) {
|
|
83
|
+
const key = `${id}\0${scope}\0${installRoot}`;
|
|
84
|
+
if (seen.has(key)) continue;
|
|
85
|
+
seen.add(key);
|
|
86
|
+
const harness = registry.harnesses.find((item ) => item.id === id);
|
|
87
|
+
const ledger = ledgerOf({ scope, installRoot });
|
|
88
|
+
const mcp = harness.capabilities?.mcp;
|
|
89
|
+
const row = {
|
|
90
|
+
id, scope, installRoot, displayName: harness.displayName || id,
|
|
91
|
+
catalog: mcp?.status === 'supported' ? 'taken' : 'not-taken',
|
|
92
|
+
note: mcp?.note ?? mcp?.verification,
|
|
93
|
+
selected: new Set((ledger?.resources || [])
|
|
94
|
+
.filter((resource ) => resource.harness === id && resource.kind === 'mcp-server').map((resource ) => resource.identity)),
|
|
95
|
+
configured: null,
|
|
96
|
+
complete: false,
|
|
97
|
+
unreadable: false,
|
|
98
|
+
};
|
|
99
|
+
try {
|
|
100
|
+
const discovery = resolveAdapter(adapters, harness).discover({
|
|
101
|
+
scope, scopeRoot: installRoot, homeDir, mcp: [], mcpAdoptable: [], ledger, registry, context: { homeDir },
|
|
102
|
+
});
|
|
103
|
+
row.configured = Array.isArray(discovery.mcpConfigured) ? discovery.mcpConfigured : null;
|
|
104
|
+
row.complete = discovery.mcpComplete === true;
|
|
105
|
+
const found = unreadableDetail(discovery);
|
|
106
|
+
if (found) { row.unreadable = true; unreadable.push({ harness: id, scope, ...found }); }
|
|
107
|
+
} catch (error ) {
|
|
108
|
+
row.unreadable = true;
|
|
109
|
+
unreadable.push({ harness: id, scope, detail: error.message });
|
|
110
|
+
}
|
|
111
|
+
rows.push(row);
|
|
112
|
+
}
|
|
113
|
+
rows.sort((a, b) => harnessOrder.indexOf(a.id) - harnessOrder.indexOf(b.id)
|
|
114
|
+
|| SCOPE_ORDER[a.scope] - SCOPE_ORDER[b.scope] || a.installRoot.localeCompare(b.installRoot));
|
|
115
|
+
|
|
116
|
+
const result = {
|
|
117
|
+
harnesses: rows.map((row) => {
|
|
118
|
+
const entry = { id: row.id, scope: row.scope, catalog: row.catalog };
|
|
119
|
+
if (row.catalog === 'not-taken' && row.note) entry.note = row.note;
|
|
120
|
+
entry.servers = Object.fromEntries(serverIds.map((server) => [server, stateOf(row, server)]));
|
|
121
|
+
return entry;
|
|
122
|
+
}),
|
|
123
|
+
unreadable,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** `true` when a server is selected or configured on some installed harness, `false` only when
|
|
127
|
+
* every installed harness read every source it merges and says it is absent, `null` (unknown)
|
|
128
|
+
* otherwise, including when none is installed. */
|
|
129
|
+
const anyHarnessHas = (server ) => {
|
|
130
|
+
const states = rows.map((row) => stateOf(row, server));
|
|
131
|
+
if (states.some((state) => state === 'selected' || state === 'configured')) return true;
|
|
132
|
+
return states.length > 0 && states.every((state) => state === 'not-selected' || state === 'not-taken') ? false : null;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** The command that adds `serverId` for a harness at a scope, or where to configure it by hand. */
|
|
136
|
+
const addCommand = (harnessId , scope , serverId ) => {
|
|
137
|
+
const harness = registry.harnesses.find((item ) => item.id === harnessId);
|
|
138
|
+
const name = harness?.displayName || harnessId;
|
|
139
|
+
if (harness?.capabilities?.mcp?.status !== 'supported') {
|
|
140
|
+
return `configure it in ${name}'s own MCP settings; DoFlow's catalog does not reach it`;
|
|
141
|
+
}
|
|
142
|
+
if (!catalogIds.includes(serverId)) {
|
|
143
|
+
return `configure it in ${name}'s own MCP settings; DoFlow's catalog does not carry ${serverId}`;
|
|
144
|
+
}
|
|
145
|
+
const chosen = new Set([serverId]);
|
|
146
|
+
for (const row of rows) if (row.id === harnessId && row.scope === scope) for (const id of row.selected) chosen.add(id);
|
|
147
|
+
return `doflow install${scope === 'global' ? ' -g' : ''} --target ${harnessId} --mcp ${catalogIds.filter((id ) => chosen.has(id)).join(',')}`;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
Object.defineProperties(result, {
|
|
151
|
+
anyHarnessHas: { value: anyHarnessHas },
|
|
152
|
+
addCommand: { value: addCommand },
|
|
153
|
+
});
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
module.exports = { mcpReach };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
4
|
+
|
|
5
|
+
// Model role router. DoFlow binds no model for the harness's own work; the runtime calls a
|
|
6
|
+
// configured local decision model only for advisory picks. This resolves an abstract role from
|
|
7
|
+
// core/registry/models.json into availability-annotated provider candidates that skills,
|
|
8
|
+
// orchestration snapshots, or operators act on through each harness's native model selection.
|
|
9
|
+
// Policy strings (prefer/fallback/require) pass through verbatim — the registry owns them; this
|
|
10
|
+
// module owns matching them against providers' declared tiers and what is installed right now.
|
|
11
|
+
|
|
12
|
+
const fs = require('node:fs');
|
|
13
|
+
const path = require('node:path');
|
|
14
|
+
const { loadRegistry } = require('../registry/index.js');
|
|
15
|
+
const { finishRuntime, usageError, captureCaught } = require('./cli-result.js');
|
|
16
|
+
const { REPO_ROOT } = require('../helper/repo-root.js');
|
|
17
|
+
|
|
18
|
+
/** The machine-level command each provider's backend answers to. A provider without a local CLI
|
|
19
|
+
* (hosted-only access through another harness) reports backendCli null and is never "available". */
|
|
20
|
+
const BACKEND_CLI = Object.freeze({ claude: 'claude', codex: 'codex', copilot: 'copilot', ollama: 'ollama' });
|
|
21
|
+
|
|
22
|
+
function whichLike(command , { fsImpl = fs, pathEnv = process.env.PATH } = {}) {
|
|
23
|
+
if (!command) return false;
|
|
24
|
+
for (const dir of String(pathEnv ?? '').split(path.delimiter)) {
|
|
25
|
+
if (!dir) continue;
|
|
26
|
+
try {
|
|
27
|
+
const candidate = path.join(dir, command);
|
|
28
|
+
fsImpl.accessSync(candidate, fs.constants.X_OK);
|
|
29
|
+
return true;
|
|
30
|
+
} catch { /* keep scanning */ }
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Providers whose backend CLI resolves on PATH. Injectable in tests; never guessed otherwise. */
|
|
36
|
+
function availableProviderIds({ fsImpl = fs } = {}) {
|
|
37
|
+
return Object.entries(BACKEND_CLI)
|
|
38
|
+
.filter(([, cli]) => whichLike(cli, { fsImpl }))
|
|
39
|
+
.map(([id]) => id);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Resolve one role to ranked candidates.
|
|
44
|
+
* Ordering: available first, then preferred-tier match, then fallback-tier match, registry order
|
|
45
|
+
* breaking ties. `exclude` drops provider ids entirely (e.g. the implementer when the role is
|
|
46
|
+
* review with require:different-family) and is reported back rather than hidden.
|
|
47
|
+
* Availability unknown stays null — absence of evidence is not reported as absent.
|
|
48
|
+
*/
|
|
49
|
+
function resolveModelRole({ registry, roleId, isAvailable = null, exclude = [] } = {}) {
|
|
50
|
+
const role = (registry.modelRoles || []).find((entry ) => entry.id === roleId);
|
|
51
|
+
if (!role) {
|
|
52
|
+
throw new Error(`Unknown model role '${roleId}'; valid: ${(registry.modelRoles || []).map((r ) => r.id).join(', ')}`);
|
|
53
|
+
}
|
|
54
|
+
const excluded = new Set(exclude);
|
|
55
|
+
const candidates = [];
|
|
56
|
+
for (const [index, provider] of (registry.modelProviders || []).entries()) {
|
|
57
|
+
if (excluded.has(provider.id)) continue;
|
|
58
|
+
const tiers = provider.tiers ?? [];
|
|
59
|
+
candidates.push({
|
|
60
|
+
id: provider.id,
|
|
61
|
+
kind: provider.kind,
|
|
62
|
+
displayName: provider.displayName,
|
|
63
|
+
backendCli: BACKEND_CLI[provider.id] ?? null,
|
|
64
|
+
available: isAvailable ? Boolean(isAvailable(provider.id)) : null,
|
|
65
|
+
servesPreferredTier: role.prefer ? tiers.includes(role.prefer) : null,
|
|
66
|
+
servesFallbackTier: role.fallback ? tiers.includes(role.fallback) : null,
|
|
67
|
+
_index: index,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const rank = (candidate ) => [
|
|
71
|
+
candidate.available === true ? 0 : candidate.available === false ? 1 : 2,
|
|
72
|
+
candidate.servesPreferredTier ? 0 : 1,
|
|
73
|
+
candidate.servesFallbackTier ? 0 : 1,
|
|
74
|
+
candidate._index,
|
|
75
|
+
];
|
|
76
|
+
candidates.sort((a , b ) => {
|
|
77
|
+
const ra = rank(a); const rb = rank(b);
|
|
78
|
+
for (let i = 0; i < ra.length; i += 1) if (ra[i] !== rb[i]) return ra[i] - rb[i];
|
|
79
|
+
return 0;
|
|
80
|
+
});
|
|
81
|
+
for (const candidate of candidates) delete candidate._index;
|
|
82
|
+
return {
|
|
83
|
+
roleId,
|
|
84
|
+
policy: { prefer: role.prefer ?? null, fallback: role.fallback ?? null, require: role.require ?? null },
|
|
85
|
+
candidates,
|
|
86
|
+
excluded: [...excluded],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolve one optional dense/rerank retrieval slot from core/registry/models.json. A slot binds a
|
|
92
|
+
* retrieval stage (`dense` embedding lookup, `rerank` cross-encoder pass) to one declared provider
|
|
93
|
+
* and the concrete model that provider serves; it takes effect only while `enabled`. Absent or
|
|
94
|
+
* disabled slots resolve to `{active:false}` and every caller stays on its existing lexical/graph
|
|
95
|
+
* path unchanged — this function never routes anywhere on its own. An enabled slot resolves to the
|
|
96
|
+
* bound provider with availability probed through the same injected seam resolveModelRole uses
|
|
97
|
+
* (PATH scan for the provider's backend CLI); `available:false` or `null` tells the caller to stay
|
|
98
|
+
* lexical rather than guess. Unknown slot ids also resolve to `{active:false}` rather than
|
|
99
|
+
* throwing: absence of a slot is every install's normal state, unlike an unknown role.
|
|
100
|
+
*/
|
|
101
|
+
function resolveRetrievalSlot({ registry, slotId, isAvailable = null } = {}) {
|
|
102
|
+
const slot = (registry.retrievalSlots || []).find((entry ) => entry.id === slotId);
|
|
103
|
+
if (!slot || !slot.enabled) return { slotId, active: false, reason: slot ? 'disabled' : 'undeclared' };
|
|
104
|
+
const provider = (registry.modelProviders || []).find((entry ) => entry.id === slot.provider);
|
|
105
|
+
if (!provider) return { slotId, active: false, reason: 'provider-missing' };
|
|
106
|
+
return {
|
|
107
|
+
slotId,
|
|
108
|
+
active: true,
|
|
109
|
+
reason: null,
|
|
110
|
+
provider: provider.id,
|
|
111
|
+
displayName: provider.displayName,
|
|
112
|
+
kind: provider.kind,
|
|
113
|
+
backendCli: BACKEND_CLI[provider.id] ?? null,
|
|
114
|
+
model: slot.model,
|
|
115
|
+
available: isAvailable ? Boolean(isAvailable(provider.id)) : null,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** CLI handler for `doflow model-role`. Read-only advisory routing; exits 1 on an unknown role
|
|
120
|
+
* because a silently-empty candidate list would read as "no providers" rather than "bad input". */
|
|
121
|
+
function handleModelRoleCommand({ role, exclude, json = false, repoRoot } = {}) {
|
|
122
|
+
if (!role) return usageError('model-role', '--role is required (one of the roles in core/registry/models.json)', json);
|
|
123
|
+
const registry = (() => {
|
|
124
|
+
try { return loadRegistry({ repoRoot: repoRoot || REPO_ROOT }); }
|
|
125
|
+
catch (error ) { captureCaught(error, 'model-role', 1); console.error(`[ERROR] model-role: ${error.message}`); return finishRuntime(1); }
|
|
126
|
+
})();
|
|
127
|
+
if (!registry) return undefined;
|
|
128
|
+
const available = new Set(availableProviderIds());
|
|
129
|
+
try {
|
|
130
|
+
const resolution = resolveModelRole({
|
|
131
|
+
registry,
|
|
132
|
+
roleId: role,
|
|
133
|
+
isAvailable: (providerId ) => available.has(providerId),
|
|
134
|
+
exclude: Array.isArray(exclude) ? exclude : String(exclude ?? '').split(',').map((s ) => s.trim()).filter(Boolean),
|
|
135
|
+
});
|
|
136
|
+
if (json) console.log(JSON.stringify(resolution, null, 2));
|
|
137
|
+
else {
|
|
138
|
+
console.log(`Role '${resolution.roleId}' — prefer:${resolution.policy.prefer ?? '—'} fallback:${resolution.policy.fallback ?? '—'} require:${resolution.policy.require ?? '—'}`);
|
|
139
|
+
for (const candidate of resolution.candidates) {
|
|
140
|
+
const availability = candidate.available === null ? '?' : candidate.available ? 'yes' : 'no';
|
|
141
|
+
console.log(` ${candidate.available ? '*' : ' '} ${candidate.id} (${candidate.kind}, via ${candidate.backendCli ?? 'hosted'}) available=${availability}${resolution.policy.prefer && candidate.servesPreferredTier ? ` serves ${resolution.policy.prefer}` : ''}`);
|
|
142
|
+
}
|
|
143
|
+
if (resolution.excluded.length) console.log(`Excluded: ${resolution.excluded.join(', ')}`);
|
|
144
|
+
}
|
|
145
|
+
return finishRuntime(0);
|
|
146
|
+
} catch (error ) {
|
|
147
|
+
captureCaught(error, 'model-role', 1);
|
|
148
|
+
console.error(`[ERROR] model-role: ${error.message}`);
|
|
149
|
+
return finishRuntime(1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = { resolveModelRole, resolveRetrievalSlot, handleModelRoleCommand, availableProviderIds, BACKEND_CLI };
|