@khoavu882/doflow 0.0.0-stage → 2.0.0-beta.3
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 +1057 -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 +46 -4
- package/src/adapters/antigravity/index.ts +631 -0
- package/src/adapters/claude/index.ts +548 -0
- package/src/adapters/claude/mcp.ts +94 -0
- package/src/adapters/codex/agents.ts +208 -0
- package/src/adapters/codex/config.ts +272 -0
- package/src/adapters/codex/hooks.ts +203 -0
- package/src/adapters/codex/index.ts +707 -0
- package/src/adapters/codex/mcp.ts +271 -0
- package/src/adapters/codex/native-projection.ts +34 -0
- package/src/adapters/copilot/index.ts +413 -0
- package/src/adapters/copy-tree.ts +620 -0
- package/src/adapters/gemini/hooks.ts +210 -0
- package/src/adapters/gemini/index.ts +390 -0
- package/src/adapters/hook-commands.ts +60 -0
- package/src/adapters/index.ts +106 -0
- package/src/adapters/kiro/index.ts +310 -0
- package/src/adapters/mcp-entries.ts +331 -0
- package/src/adapters/opencode/index.ts +466 -0
- package/src/adapters/pi/index.ts +279 -0
- package/src/adapters/pi/json-members.ts +185 -0
- package/src/adapters/pi/mcp.ts +373 -0
- package/src/adapters/resolve-source.ts +19 -0
- package/src/cli/commands/install.ts +218 -0
- package/src/cli/commands/list-backups.ts +21 -0
- package/src/cli/commands/reconcile.ts +120 -0
- package/src/cli/commands/remove.ts +82 -0
- package/src/cli/commands/rollback.ts +172 -0
- package/src/cli/commands/self-update.ts +33 -0
- package/src/cli/commands/status.ts +138 -0
- package/src/cli/commands/tools.ts +92 -0
- package/src/cli/commands/update.ts +162 -0
- package/src/cli/index.ts +568 -0
- package/src/cli/runtime-commands.ts +281 -0
- package/src/cli/shared.ts +218 -0
- package/src/helper/bash-helper.ts +34 -0
- package/src/helper/git.ts +24 -0
- package/src/helper/guardrails.ts +49 -0
- package/src/helper/harness-paths.ts +140 -0
- package/src/helper/marker-merge.ts +116 -0
- package/src/helper/prompt.ts +61 -0
- package/src/helper/repo-root.ts +29 -0
- package/src/helper/settings-merge.ts +151 -0
- package/src/helper/settings-scope.ts +33 -0
- package/src/helper/toml.ts +244 -0
- package/src/install/backup-set.ts +149 -0
- package/src/install/backup.ts +724 -0
- package/src/install/context.ts +58 -0
- package/src/install/manifest.ts +145 -0
- package/src/install/mcp.ts +254 -0
- package/src/install/paths.ts +84 -0
- package/src/install/targets.ts +90 -0
- package/src/install/tool-lifecycle.ts +151 -0
- package/src/lifecycle/bash-availability.ts +25 -0
- package/src/lifecycle/index.ts +812 -0
- package/src/lifecycle/mcp-index.ts +28 -0
- package/src/lifecycle/policies.ts +73 -0
- package/src/lifecycle/view.ts +175 -0
- package/src/registry/index.ts +611 -0
- package/src/release/sync-plugin-versions.ts +66 -0
- package/src/runtime/advice/cli.ts +283 -0
- package/src/runtime/advice/client.ts +324 -0
- package/src/runtime/advice/config.ts +189 -0
- package/src/runtime/advice/doctor.ts +169 -0
- package/src/runtime/advice/endpoint-guard.ts +134 -0
- package/src/runtime/advice/kinds.ts +154 -0
- package/src/runtime/advice/providers/ollama-systemone.ts +209 -0
- package/src/runtime/advice/record.ts +166 -0
- package/src/runtime/advice/registry.ts +170 -0
- package/src/runtime/advice/strength.ts +66 -0
- package/src/runtime/brief-tools.ts +342 -0
- package/src/runtime/c4-project.ts +371 -0
- package/src/runtime/capability-router.ts +484 -0
- package/src/runtime/checkouts.ts +170 -0
- package/src/runtime/claims.ts +468 -0
- package/src/runtime/cli-result.ts +55 -0
- package/src/runtime/cli.ts +678 -0
- package/src/runtime/command-detect.ts +516 -0
- package/src/runtime/context-pack.ts +492 -0
- package/src/runtime/decision-register.ts +493 -0
- package/src/runtime/evidence-ledger.ts +338 -0
- package/src/runtime/failure/capture.ts +272 -0
- package/src/runtime/failure/classifier.ts +68 -0
- package/src/runtime/failure/cli.ts +178 -0
- package/src/runtime/failure/home.ts +64 -0
- package/src/runtime/failure/store.ts +226 -0
- package/src/runtime/feature-resolve.ts +79 -0
- package/src/runtime/freshness.ts +177 -0
- package/src/runtime/health.ts +863 -0
- package/src/runtime/history-compactor.ts +237 -0
- package/src/runtime/implementation-gate.ts +321 -0
- package/src/runtime/inventory/coverage.ts +218 -0
- package/src/runtime/inventory/identity.ts +65 -0
- package/src/runtime/inventory/index.ts +705 -0
- package/src/runtime/inventory/precedence.ts +134 -0
- package/src/runtime/inventory/read-scopes.ts +131 -0
- package/src/runtime/inventory/siblings.ts +192 -0
- package/src/runtime/knowledge/chunker.ts +124 -0
- package/src/runtime/knowledge/hybrid.ts +149 -0
- package/src/runtime/knowledge/index-store.ts +145 -0
- package/src/runtime/knowledge/retrieval.ts +194 -0
- package/src/runtime/leak-scan.ts +185 -0
- package/src/runtime/lifecycle/cli.ts +276 -0
- package/src/runtime/lifecycle/event-store.ts +340 -0
- package/src/runtime/lifecycle/fold.ts +353 -0
- package/src/runtime/lifecycle/followup.ts +432 -0
- package/src/runtime/lifecycle/goal.ts +249 -0
- package/src/runtime/lifecycle/intent-writer.ts +86 -0
- package/src/runtime/lifecycle/overview.ts +292 -0
- package/src/runtime/lifecycle/release.ts +241 -0
- package/src/runtime/lifecycle/report-store.ts +221 -0
- package/src/runtime/lifecycle/retention.ts +212 -0
- package/src/runtime/lifecycle/root.ts +71 -0
- package/src/runtime/lifecycle/status.ts +353 -0
- package/src/runtime/lifecycle/store-upkeep.ts +393 -0
- package/src/runtime/locator-resolve.ts +158 -0
- package/src/runtime/mask.ts +210 -0
- package/src/runtime/mcp-consultations.ts +412 -0
- package/src/runtime/mcp-reach.ts +157 -0
- package/src/runtime/model-router.ts +153 -0
- package/src/runtime/outcome.ts +467 -0
- package/src/runtime/reach.ts +148 -0
- package/src/runtime/readiness-record.ts +150 -0
- package/src/runtime/readiness.ts +435 -0
- package/src/runtime/recovery.ts +282 -0
- package/src/runtime/research-request.ts +231 -0
- package/src/runtime/retrieval-plan.ts +578 -0
- package/src/runtime/scaffold/artifacts.ts +217 -0
- package/src/runtime/scaffold/fingerprint.ts +56 -0
- package/src/runtime/scaffold/generate.ts +911 -0
- package/src/runtime/scaffold/languages.ts +245 -0
- package/src/runtime/storage/cli.ts +64 -0
- package/src/runtime/storage/engine.ts +249 -0
- package/src/runtime/storage/registry.ts +130 -0
- package/src/runtime/storage/roots.ts +63 -0
- package/src/runtime/storage/rules.ts +282 -0
- package/src/runtime/storage/upkeep.ts +243 -0
- package/src/runtime/storage/work-status.ts +326 -0
- package/src/runtime/task-attempts.ts +415 -0
- package/src/runtime/task-classifier.ts +550 -0
- package/src/runtime/task-scope.ts +130 -0
- package/src/runtime/task-state.ts +176 -0
- package/src/runtime/trace/indicators.ts +235 -0
- package/src/runtime/trace/ledger.ts +626 -0
- package/src/runtime/trace/render.ts +76 -0
- package/src/runtime/trace/views.ts +459 -0
- package/src/runtime/verification/contract-runner.ts +341 -0
- package/src/runtime/verification/engine.ts +1461 -0
- package/src/runtime/verification/registry.ts +130 -0
- package/src/runtime/verification/scope-bound.ts +418 -0
- package/src/runtime/verification/test-selection.ts +172 -0
- package/src/runtime/workflow-engine.ts +588 -0
- package/src/runtime/workflow-orchestrator.ts +953 -0
- package/src/runtime/worktree.ts +340 -0
- package/src/state/index.ts +193 -0
- package/src/state/lockfile.ts +136 -0
- package/src/state/run-lock.ts +408 -0
- package/types/node-commonjs.d.ts +68 -0
- package/types/runtime.d.ts +91 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// TypeScript migration (agent-docs/BRIEF_GOAL_DOFLOW.md): run directly by Node native type-stripping.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Deterministic check execution — the JavaScript port of
|
|
7
|
+
* `core/shared/scripts/doflow/verification/contract_runner.py` (plan task B.3, component C7).
|
|
8
|
+
*
|
|
9
|
+
* Runs an ordered list of shell checks, cheapest and most deterministic first
|
|
10
|
+
* (syntax → compile → types → lint → unit → integration → architecture → scope), and compiles a
|
|
11
|
+
* report. Ported from observed behaviour (plan decision D3): the check record shape, the PASS/FAIL
|
|
12
|
+
* vocabulary, the 2,000-character output cap, exit code 124 for a timeout and the short-circuit on
|
|
13
|
+
* a failing syntax/compile/build check are all reproduced exactly.
|
|
14
|
+
*
|
|
15
|
+
* Three defects are fixed rather than reproduced, each explained at its site:
|
|
16
|
+
* 1. A check entry with no `command` silently ran `true` and reported PASS — a malformed
|
|
17
|
+
* contract produced a green check that verified nothing.
|
|
18
|
+
* 2. A timed-out check threw away the output captured before the kill, which is the only
|
|
19
|
+
* diagnostic a hung check ever produces.
|
|
20
|
+
* 3. A contract with no checks reported `status: "PASS"` — a verification verdict asserted over
|
|
21
|
+
* zero evidence.
|
|
22
|
+
*
|
|
23
|
+
* `verification.js`'s `VerificationEngine` (plan task C.2, design C7) is the registry-driven layer
|
|
24
|
+
* built on top of this runner — it owns tier selection, risk scaling and recovery, and calls
|
|
25
|
+
* `runCheck` for every check a resolved tier produces.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const { spawnSync } = require('node:child_process');
|
|
29
|
+
const fs = require('node:fs');
|
|
30
|
+
const path = require('node:path');
|
|
31
|
+
|
|
32
|
+
/** A failing check whose name contains one of these aborts the remaining checks: once the build is
|
|
33
|
+
* broken, every later result describes the broken build rather than the change. */
|
|
34
|
+
const FATAL_CHECK_MARKERS = Object.freeze(['syntax', 'compile', 'build']);
|
|
35
|
+
|
|
36
|
+
const DEFAULT_TIMEOUT_MS = 60000;
|
|
37
|
+
const MAX_STREAM_CHARS = 2000;
|
|
38
|
+
/** Enough head to catch a startup error; the rest of the budget goes to the tail. */
|
|
39
|
+
const HEAD_KEEP_CHARS = 400;
|
|
40
|
+
|
|
41
|
+
/** The exit code a shell reports for a command killed by a timeout; kept so callers that already
|
|
42
|
+
* special-case 124 from the Python keep working. */
|
|
43
|
+
const TIMEOUT_EXIT_CODE = 124;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {*} value
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
function truncate(value: any): string {
|
|
50
|
+
if (typeof value !== 'string') return '';
|
|
51
|
+
if (value.length <= MAX_STREAM_CHARS) return value;
|
|
52
|
+
// Keep the TAIL, not the head, and say so.
|
|
53
|
+
//
|
|
54
|
+
// Every runner worth verifying streams progress first and summarises last: `node --test` puts
|
|
55
|
+
// the failure diagnostics and the `# fail N` line at the end, as do pytest, jest and `go test`.
|
|
56
|
+
// Slicing from the front therefore kept ~10 passing subtests out of 572 and discarded the only
|
|
57
|
+
// part of the stream that shows a failure — a verification report that structurally could not
|
|
58
|
+
// report one. A little head is retained because a hard startup error (missing binary, bad
|
|
59
|
+
// config) appears there and nowhere else.
|
|
60
|
+
const head = value.slice(0, HEAD_KEEP_CHARS);
|
|
61
|
+
const tail = value.slice(-(MAX_STREAM_CHARS - HEAD_KEEP_CHARS));
|
|
62
|
+
const dropped = value.length - head.length - tail.length;
|
|
63
|
+
return `${head}\n… [${dropped} characters elided by the verification report] …\n${tail}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Cap on extracted failing-test identifiers — a bounded diagnostic, not a second log. */
|
|
67
|
+
const MAX_FAILED_TESTS = 50;
|
|
68
|
+
|
|
69
|
+
/** `not ok` lines in TAP output (node --test, pytest-tap, prove …): the failing test identifiers.
|
|
70
|
+
* Directive lines (`# SKIP`, `# TODO`) are not failures and are excluded. */
|
|
71
|
+
const TAP_NOT_OK = /^\s*not ok\b(?:\s+\d+)?(?:\s*-\s*)?(.*)$/gm;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Pulls failing test identifiers out of the FULL output, before any truncation — the middle of a
|
|
75
|
+
* TAP stream is exactly what the 2,000-character excerpt drops (review A2: a separate raw-log run
|
|
76
|
+
* was needed to recover which tests failed).
|
|
77
|
+
* @param {string} text
|
|
78
|
+
* @returns {Array<string>} unique identifiers, bounded by MAX_FAILED_TESTS
|
|
79
|
+
*/
|
|
80
|
+
function extractFailedTests(text: string): string[] {
|
|
81
|
+
const seen = new Set<string>();
|
|
82
|
+
for (const match of text.matchAll(TAP_NOT_OK)) {
|
|
83
|
+
const name = match[1].trim();
|
|
84
|
+
if (name === '' || /#\s*(?:SKIP|TODO)\b/i.test(name)) continue;
|
|
85
|
+
seen.add(name);
|
|
86
|
+
if (seen.size >= MAX_FAILED_TESTS) break;
|
|
87
|
+
}
|
|
88
|
+
return [...seen];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
class VerificationContractRunner {
|
|
92
|
+
cwd: string;
|
|
93
|
+
defaultTimeoutMs: number;
|
|
94
|
+
exec: any;
|
|
95
|
+
fsImpl: any;
|
|
96
|
+
logDir: string;
|
|
97
|
+
logWriteWarned?: boolean;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {Object|string} [options] a string is accepted for parity with the Python's positional
|
|
101
|
+
* `cwd` argument
|
|
102
|
+
* @param {string} [options.cwd] directory the checks run in; defaults to the current one
|
|
103
|
+
* @param {number} [options.defaultTimeoutMs=60000]
|
|
104
|
+
* @param {Function} [options.exec] injection seam for tests; same contract as `spawnSync`
|
|
105
|
+
*/
|
|
106
|
+
constructor(options: any = {}) {
|
|
107
|
+
const opts = typeof options === 'string' ? { cwd: options } : options;
|
|
108
|
+
this.cwd = opts.cwd || process.cwd();
|
|
109
|
+
this.defaultTimeoutMs = opts.defaultTimeoutMs || DEFAULT_TIMEOUT_MS;
|
|
110
|
+
this.exec = opts.exec || spawnSync;
|
|
111
|
+
this.fsImpl = opts.fsImpl || fs;
|
|
112
|
+
this.logDir = opts.logDir || path.join(this.cwd, '.doflow', 'state', 'verification', 'logs');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Persists one check's full output beside the state the run already keeps, so the 2,000-character
|
|
117
|
+
* excerpt is a pointer into a complete record rather than the only record (review A2: the
|
|
118
|
+
* truncation kept the failure count but dropped the failing test names from mid-stream, and
|
|
119
|
+
* recovering them took a second full run of the same command).
|
|
120
|
+
* @param {string} name
|
|
121
|
+
* @param {string} command
|
|
122
|
+
* @param {string} stdout
|
|
123
|
+
* @param {string} stderr
|
|
124
|
+
* @returns {string|null} the log path, or null when the log could not be written
|
|
125
|
+
*/
|
|
126
|
+
persistLog(name: string, command: string, stdout: string, stderr: string): string | null {
|
|
127
|
+
try {
|
|
128
|
+
this.fsImpl.mkdirSync(this.logDir, { recursive: true });
|
|
129
|
+
const safe = name.replace(/[^A-Za-z0-9._-]+/g, '_');
|
|
130
|
+
const file = path.join(this.logDir, `${Date.now()}-${safe}.log`);
|
|
131
|
+
this.fsImpl.writeFileSync(file,
|
|
132
|
+
`# check: ${name}\n# command: ${command}\n--- stdout ---\n${stdout || ''}\n--- stderr ---\n${stderr || ''}\n`,
|
|
133
|
+
'utf8');
|
|
134
|
+
return file;
|
|
135
|
+
} catch (error: any) {
|
|
136
|
+
// An unwritable log directory must not turn a completed check into an error — the check's
|
|
137
|
+
// verdict stands; only the pointer is missing, and its null says so. But a chronic
|
|
138
|
+
// permissions problem should not be invisible either: say so once per runner, on stderr so
|
|
139
|
+
// a caller capturing stdout never absorbs it as data (review suggestion, 026).
|
|
140
|
+
if (!this.logWriteWarned) {
|
|
141
|
+
this.logWriteWarned = true;
|
|
142
|
+
process.stderr.write(`doflow verification: could not persist check log under '${this.logDir}' (${error.message}); verdicts are unaffected, logPath will be null\n`);
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Adds the A2 diagnostics to a completed check record, from the FULL streams: failing test
|
|
150
|
+
* identifiers (extracted before truncation) and, for a failure or a truncated stream, the path
|
|
151
|
+
* of the persisted full log.
|
|
152
|
+
* @param {Object} result mutated in place
|
|
153
|
+
* @param {string} command
|
|
154
|
+
* @param {string} [stdout]
|
|
155
|
+
* @param {string} [stderr]
|
|
156
|
+
*/
|
|
157
|
+
decorate(result: any, command: string, stdout?: string, stderr?: string): void {
|
|
158
|
+
const full = `${stdout || ''}\n${stderr || ''}`;
|
|
159
|
+
if (result.status === 'FAIL') {
|
|
160
|
+
const failedTests = extractFailedTests(full);
|
|
161
|
+
if (failedTests.length > 0) result.failedTests = failedTests;
|
|
162
|
+
}
|
|
163
|
+
const truncated = (stdout || '').length > MAX_STREAM_CHARS || (stderr || '').length > MAX_STREAM_CHARS;
|
|
164
|
+
if ((result.status === 'FAIL' || truncated) && full.trim() !== '') {
|
|
165
|
+
result.logPath = this.persistLog(result.name, command, stdout as string, stderr as string);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Executes a single deterministic shell check.
|
|
171
|
+
* @param {string} name
|
|
172
|
+
* @param {string} command
|
|
173
|
+
* @param {number} [timeoutMs]
|
|
174
|
+
* @param {Map} [dedupeCache] scoped to ONE contract evaluation: a second check declaring the
|
|
175
|
+
* same command and timeout reuses the first result instead of re-running it (review A2: the
|
|
176
|
+
* contract ran the same `npm test` twice after the first failure). Never held across
|
|
177
|
+
* evaluations — a recovery retry must observe live behaviour, so each pass passes a fresh map.
|
|
178
|
+
* @returns {Object} check result
|
|
179
|
+
*/
|
|
180
|
+
runCheck(name: string, command: any, timeoutMs: number = this.defaultTimeoutMs, dedupeCache: Map<string, any> | null = null): any {
|
|
181
|
+
const checkName = name || 'unnamed_check';
|
|
182
|
+
|
|
183
|
+
// Defect fix (1): the Python defaulted a missing command to `true`, so a typo in a contract
|
|
184
|
+
// entry produced a check that always passed. A check that cannot be run has not passed.
|
|
185
|
+
if (typeof command !== 'string' || command.trim() === '') {
|
|
186
|
+
return {
|
|
187
|
+
name: checkName,
|
|
188
|
+
command: null,
|
|
189
|
+
status: 'FAIL',
|
|
190
|
+
exitCode: 1,
|
|
191
|
+
error: `Check '${checkName}' declares no command`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const dedupeKey = `${timeoutMs}\0${command}`;
|
|
196
|
+
if (dedupeCache && dedupeCache.has(dedupeKey)) {
|
|
197
|
+
return { ...dedupeCache.get(dedupeKey), name: checkName, deduplicated: true };
|
|
198
|
+
}
|
|
199
|
+
const remember = (result: any) => {
|
|
200
|
+
if (dedupeCache) dedupeCache.set(dedupeKey, result);
|
|
201
|
+
return result;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
let res: any;
|
|
205
|
+
try {
|
|
206
|
+
res = this.exec(command, {
|
|
207
|
+
shell: true,
|
|
208
|
+
cwd: this.cwd,
|
|
209
|
+
encoding: 'utf8',
|
|
210
|
+
timeout: timeoutMs,
|
|
211
|
+
killSignal: 'SIGKILL',
|
|
212
|
+
// The Python buffered without limit and truncated afterwards. Node's 1 MB default would
|
|
213
|
+
// kill a chatty-but-passing check and report it as a failure, so raise the ceiling well
|
|
214
|
+
// past anything a check legitimately prints. Only the first 2,000 chars are ever kept.
|
|
215
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
216
|
+
});
|
|
217
|
+
} catch (error: any) {
|
|
218
|
+
// Mirrors the Python's bare `except Exception` arm: an unspawnable command is a FAIL, not a
|
|
219
|
+
// thrown error that aborts the whole contract.
|
|
220
|
+
return remember({
|
|
221
|
+
name: checkName,
|
|
222
|
+
command,
|
|
223
|
+
status: 'FAIL',
|
|
224
|
+
exitCode: 1,
|
|
225
|
+
error: error.message,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Defect fix (2): the Python's TimeoutExpired arm returned neither stdout nor stderr, so a
|
|
230
|
+
// check that hung after printing its first failure told you only that it hung. Whatever the
|
|
231
|
+
// process produced before the kill is exactly what a reader needs.
|
|
232
|
+
if (res.error && res.error.code === 'ETIMEDOUT') {
|
|
233
|
+
const result = {
|
|
234
|
+
name: checkName,
|
|
235
|
+
command,
|
|
236
|
+
status: 'FAIL',
|
|
237
|
+
exitCode: TIMEOUT_EXIT_CODE,
|
|
238
|
+
error: 'TimeoutExpired',
|
|
239
|
+
stdout: truncate(res.stdout),
|
|
240
|
+
stderr: truncate(res.stderr),
|
|
241
|
+
};
|
|
242
|
+
this.decorate(result, command, res.stdout, res.stderr);
|
|
243
|
+
return remember(result);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (res.error) {
|
|
247
|
+
const result = {
|
|
248
|
+
name: checkName,
|
|
249
|
+
command,
|
|
250
|
+
status: 'FAIL',
|
|
251
|
+
exitCode: 1,
|
|
252
|
+
error: res.error.message,
|
|
253
|
+
stdout: truncate(res.stdout),
|
|
254
|
+
stderr: truncate(res.stderr),
|
|
255
|
+
};
|
|
256
|
+
this.decorate(result, command, res.stdout, res.stderr);
|
|
257
|
+
return remember(result);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// A process killed by a signal reports `status: null`. Python surfaced this as a negative
|
|
261
|
+
// return code; either way it is a non-zero outcome, so record the signal rather than let a
|
|
262
|
+
// null exit code read as success.
|
|
263
|
+
const exitCode = res.status === null || res.status === undefined ? 1 : res.status;
|
|
264
|
+
const passed = res.status === 0;
|
|
265
|
+
|
|
266
|
+
const result: any = {
|
|
267
|
+
name: checkName,
|
|
268
|
+
command,
|
|
269
|
+
status: passed ? 'PASS' : 'FAIL',
|
|
270
|
+
exitCode,
|
|
271
|
+
stdout: truncate(res.stdout),
|
|
272
|
+
stderr: truncate(res.stderr),
|
|
273
|
+
};
|
|
274
|
+
if (res.signal) {
|
|
275
|
+
result.error = `Terminated by signal ${res.signal}`;
|
|
276
|
+
}
|
|
277
|
+
this.decorate(result, command, res.stdout, res.stderr);
|
|
278
|
+
return remember(result);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Runs ordered checks and compiles a VerificationReport.
|
|
283
|
+
* @param {Array<{name?: string, command?: string, timeoutMs?: number}>} checks
|
|
284
|
+
* @returns {{ status: string, checks: Array<Object>, failedChecks: Array<string>, timestamp: string, reason?: string }}
|
|
285
|
+
*/
|
|
286
|
+
evaluateContract(checks: any[]): any {
|
|
287
|
+
if (!Array.isArray(checks)) {
|
|
288
|
+
throw new Error('evaluateContract expects an array of checks');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Defect fix (3): an empty contract reported PASS, which is a verdict over no evidence — the
|
|
292
|
+
// single failure mode a verification gate exists to prevent, and the same fail-closed reasoning
|
|
293
|
+
// `readiness.ts` already applies to a requirement with no evaluator. It is not FAIL either,
|
|
294
|
+
// since nothing failed; the caller (task C.2 owns tier selection) decides what an empty
|
|
295
|
+
// contract means for its risk level.
|
|
296
|
+
if (checks.length === 0) {
|
|
297
|
+
return {
|
|
298
|
+
status: 'INCONCLUSIVE',
|
|
299
|
+
checks: [],
|
|
300
|
+
failedChecks: [],
|
|
301
|
+
reason: 'Contract declared no checks; nothing was verified',
|
|
302
|
+
timestamp: new Date().toISOString(),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const results: any[] = [];
|
|
307
|
+
const failedChecks: string[] = [];
|
|
308
|
+
let overallStatus = 'PASS';
|
|
309
|
+
const dedupeCache = new Map<string, any>(); // one evaluation, one cache — a retry pass starts fresh
|
|
310
|
+
|
|
311
|
+
for (const chk of checks) {
|
|
312
|
+
const name = (chk && chk.name) || 'unnamed_check';
|
|
313
|
+
const res = this.runCheck(name, chk && chk.command, chk && chk.timeoutMs, dedupeCache);
|
|
314
|
+
results.push(res);
|
|
315
|
+
|
|
316
|
+
if (res.status === 'FAIL') {
|
|
317
|
+
overallStatus = 'FAIL';
|
|
318
|
+
failedChecks.push(name);
|
|
319
|
+
if (FATAL_CHECK_MARKERS.some((marker) => name.toLowerCase().includes(marker))) {
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
status: overallStatus,
|
|
327
|
+
checks: results,
|
|
328
|
+
failedChecks,
|
|
329
|
+
timestamp: new Date().toISOString(),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
module.exports = {
|
|
335
|
+
VerificationContractRunner,
|
|
336
|
+
FATAL_CHECK_MARKERS,
|
|
337
|
+
TIMEOUT_EXIT_CODE,
|
|
338
|
+
MAX_STREAM_CHARS,
|
|
339
|
+
MAX_FAILED_TESTS,
|
|
340
|
+
extractFailedTests,
|
|
341
|
+
};
|