xcoder-dna 0.0.0-stage → 1.3.1
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 +87 -2
- package/dist/agents/ai-chat-debate.d.ts +36 -0
- package/dist/agents/ai-chat-debate.js +300 -0
- package/dist/agents/ai-chat-report-writer.d.ts +7 -0
- package/dist/agents/ai-chat-report-writer.js +100 -0
- package/dist/agents/duplicate-detector.d.ts +41 -0
- package/dist/agents/duplicate-detector.js +65 -0
- package/dist/agents/genesis-agent.d.ts +61 -0
- package/dist/agents/genesis-agent.js +340 -0
- package/dist/agents/samurai-agent.d.ts +53 -0
- package/dist/agents/samurai-agent.js +279 -0
- package/dist/agents/sub-agent.d.ts +56 -0
- package/dist/agents/sub-agent.js +353 -0
- package/dist/backlog/backlog-requirement-validator.d.ts +10 -0
- package/dist/backlog/backlog-requirement-validator.js +60 -0
- package/dist/backlog/backlog-store.d.ts +29 -0
- package/dist/backlog/backlog-store.js +148 -0
- package/dist/backlog/po-agent.d.ts +16 -0
- package/dist/backlog/po-agent.js +121 -0
- package/dist/backlog/types.d.ts +25 -0
- package/dist/backlog/types.js +4 -0
- package/dist/bench/run.d.ts +11 -0
- package/dist/bench/run.js +185 -0
- package/dist/bench/types.d.ts +50 -0
- package/dist/bench/types.js +1 -0
- package/dist/cli/swarm.d.ts +10 -0
- package/dist/cli/swarm.js +100 -0
- package/dist/cli/task.d.ts +14 -0
- package/dist/cli/task.js +121 -0
- package/dist/cli/wbc-arg.d.ts +6 -0
- package/dist/cli/wbc-arg.js +40 -0
- package/dist/cli/wbc.d.ts +45 -0
- package/dist/cli/wbc.js +98 -0
- package/dist/commands/license.d.ts +9 -0
- package/dist/commands/license.js +140 -0
- package/dist/commands/release.d.ts +44 -0
- package/dist/commands/release.js +180 -0
- package/dist/commands/test.d.ts +50 -0
- package/dist/commands/test.js +385 -0
- package/dist/config/loadConfig.d.ts +82 -0
- package/dist/config/loadConfig.js +240 -0
- package/dist/config/secure-mode.d.ts +29 -0
- package/dist/config/secure-mode.js +63 -0
- package/dist/config/user-config.d.ts +39 -0
- package/dist/config/user-config.js +202 -0
- package/dist/engine/reasoning-engine.d.ts +21 -0
- package/dist/engine/reasoning-engine.js +59 -0
- package/dist/events/bus.d.ts +22 -0
- package/dist/events/bus.js +18 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +77 -0
- package/dist/indexing/ignoreRules.d.ts +1 -0
- package/dist/indexing/ignoreRules.js +53 -0
- package/dist/instance-swarm/instance-swarm-orchestrator.d.ts +57 -0
- package/dist/instance-swarm/instance-swarm-orchestrator.js +204 -0
- package/dist/instance-swarm/protocol-name-resolver.d.ts +23 -0
- package/dist/instance-swarm/protocol-name-resolver.js +64 -0
- package/dist/license/gate.d.ts +31 -0
- package/dist/license/gate.js +188 -0
- package/dist/license/http-client.d.ts +43 -0
- package/dist/license/http-client.js +195 -0
- package/dist/license/manager.d.ts +39 -0
- package/dist/license/manager.js +175 -0
- package/dist/license/receipt.d.ts +27 -0
- package/dist/license/receipt.js +108 -0
- package/dist/license/state-codec.d.ts +72 -0
- package/dist/license/state-codec.js +218 -0
- package/dist/license/state-paths.d.ts +17 -0
- package/dist/license/state-paths.js +64 -0
- package/dist/license/store.d.ts +44 -0
- package/dist/license/store.js +223 -0
- package/dist/license/trust-anchor.d.ts +24 -0
- package/dist/license/trust-anchor.js +74 -0
- package/dist/license/types.d.ts +34 -0
- package/dist/license/types.js +19 -0
- package/dist/llm/budget.d.ts +23 -0
- package/dist/llm/budget.js +58 -0
- package/dist/llm/client.d.ts +53 -0
- package/dist/llm/client.js +122 -0
- package/dist/llm/factory.d.ts +14 -0
- package/dist/llm/factory.js +32 -0
- package/dist/orchestrator/defect-logger.d.ts +31 -0
- package/dist/orchestrator/defect-logger.js +101 -0
- package/dist/orchestrator/defect-manager.d.ts +118 -0
- package/dist/orchestrator/defect-manager.js +338 -0
- package/dist/orchestrator/defect-migration.d.ts +14 -0
- package/dist/orchestrator/defect-migration.js +174 -0
- package/dist/orchestrator/defect-store.d.ts +48 -0
- package/dist/orchestrator/defect-store.js +76 -0
- package/dist/orchestrator/healing.d.ts +14 -0
- package/dist/orchestrator/healing.js +11 -0
- package/dist/orchestrator/interactive-steering.d.ts +64 -0
- package/dist/orchestrator/interactive-steering.js +107 -0
- package/dist/orchestrator/interrupt-handler.d.ts +30 -0
- package/dist/orchestrator/interrupt-handler.js +70 -0
- package/dist/orchestrator/lesson-manager.d.ts +25 -0
- package/dist/orchestrator/lesson-manager.js +122 -0
- package/dist/orchestrator/progress-summary.d.ts +15 -0
- package/dist/orchestrator/progress-summary.js +106 -0
- package/dist/orchestrator/reasoning-score.d.ts +49 -0
- package/dist/orchestrator/reasoning-score.js +117 -0
- package/dist/orchestrator/swarm.d.ts +36 -0
- package/dist/orchestrator/swarm.js +77 -0
- package/dist/orchestrator/task-factory.d.ts +15 -0
- package/dist/orchestrator/task-factory.js +176 -0
- package/dist/orchestrator/validation-gate.d.ts +23 -0
- package/dist/orchestrator/validation-gate.js +155 -0
- package/dist/protocol/react-contract.d.ts +136 -0
- package/dist/protocol/react-contract.js +698 -0
- package/dist/protocol/wks-protocol-manager.d.ts +22 -0
- package/dist/protocol/wks-protocol-manager.js +72 -0
- package/dist/sdlc-runtime/conversation-runner.d.ts +8 -0
- package/dist/sdlc-runtime/conversation-runner.js +64 -0
- package/dist/sdlc-runtime/dag-utils.d.ts +15 -0
- package/dist/sdlc-runtime/dag-utils.js +67 -0
- package/dist/sdlc-runtime/defect-integration.d.ts +7 -0
- package/dist/sdlc-runtime/defect-integration.js +99 -0
- package/dist/sdlc-runtime/execution-loop.d.ts +38 -0
- package/dist/sdlc-runtime/execution-loop.js +274 -0
- package/dist/sdlc-runtime/lesson-recorder.d.ts +9 -0
- package/dist/sdlc-runtime/lesson-recorder.js +27 -0
- package/dist/sdlc-runtime/plan-initializer.d.ts +47 -0
- package/dist/sdlc-runtime/plan-initializer.js +135 -0
- package/dist/sdlc-runtime/progress-persister.d.ts +10 -0
- package/dist/sdlc-runtime/progress-persister.js +34 -0
- package/dist/sdlc-runtime/protocol-loader.d.ts +10 -0
- package/dist/sdlc-runtime/protocol-loader.js +21 -0
- package/dist/sdlc-runtime/reporting.d.ts +24 -0
- package/dist/sdlc-runtime/reporting.js +68 -0
- package/dist/sdlc-runtime/sdlc-orchestrator.d.ts +59 -0
- package/dist/sdlc-runtime/sdlc-orchestrator.js +170 -0
- package/dist/sdlc-runtime/sdlc-skill.d.ts +44 -0
- package/dist/sdlc-runtime/sdlc-skill.js +148 -0
- package/dist/sdlc-runtime/steering-handler.d.ts +14 -0
- package/dist/sdlc-runtime/steering-handler.js +51 -0
- package/dist/sdlc-runtime/trace-recorder.d.ts +10 -0
- package/dist/sdlc-runtime/trace-recorder.js +7 -0
- package/dist/security/index.d.ts +16 -0
- package/dist/security/index.js +12 -0
- package/dist/security/input-screen.d.ts +30 -0
- package/dist/security/input-screen.js +75 -0
- package/dist/security/tool-call-guard.d.ts +16 -0
- package/dist/security/tool-call-guard.js +163 -0
- package/dist/security/untrusted-content.d.ts +34 -0
- package/dist/security/untrusted-content.js +63 -0
- package/dist/skills/advanced-dfir/SKILL.md +85 -0
- package/dist/skills/advanced-pentest-lab/SKILL.md +88 -0
- package/dist/skills/analyst/SKILL.md +55 -0
- package/dist/skills/architect/SKILL.md +54 -0
- package/dist/skills/aws/SKILL.md +92 -0
- package/dist/skills/azure/SKILL.md +90 -0
- package/dist/skills/bylaw-context.d.ts +45 -0
- package/dist/skills/bylaw-context.js +61 -0
- package/dist/skills/bylaw-review.d.ts +20 -0
- package/dist/skills/bylaw-review.js +101 -0
- package/dist/skills/conversation/SKILL.md +29 -0
- package/dist/skills/design-patterns/SKILL.md +190 -0
- package/dist/skills/devops/SKILL.md +55 -0
- package/dist/skills/directives.d.ts +20 -0
- package/dist/skills/directives.js +313 -0
- package/dist/skills/docker/SKILL.md +76 -0
- package/dist/skills/docker-expert/SKILL.md +56 -0
- package/dist/skills/enterprise-systems-analyst/SKILL.md +83 -0
- package/dist/skills/enterprise-systems-analyst/references/crm.md +41 -0
- package/dist/skills/enterprise-systems-analyst/references/erp.md +40 -0
- package/dist/skills/enterprise-systems-analyst/references/financial-systems.md +35 -0
- package/dist/skills/enterprise-systems-analyst/references/hcm.md +38 -0
- package/dist/skills/enterprise-systems-analyst/references/mrp.md +37 -0
- package/dist/skills/enterprise-systems-analyst/references/scm.md +32 -0
- package/dist/skills/ethical-hacking-methodology/SKILL.md +119 -0
- package/dist/skills/externalSkillLoader.d.ts +25 -0
- package/dist/skills/externalSkillLoader.js +65 -0
- package/dist/skills/externalSkillRegistry.d.ts +33 -0
- package/dist/skills/externalSkillRegistry.js +94 -0
- package/dist/skills/filesystem-management/SKILL.md +61 -0
- package/dist/skills/first-run-seed.d.ts +26 -0
- package/dist/skills/first-run-seed.js +75 -0
- package/dist/skills/git-vcs/SKILL.md +84 -0
- package/dist/skills/kafka/SKILL.md +89 -0
- package/dist/skills/kubernetes/SKILL.md +93 -0
- package/dist/skills/kubernetes-expert/SKILL.md +54 -0
- package/dist/skills/openshift/SKILL.md +93 -0
- package/dist/skills/pentester/SKILL.md +59 -0
- package/dist/skills/performance-tester/SKILL.md +57 -0
- package/dist/skills/playwright-ui-tester/SKILL.md +67 -0
- package/dist/skills/programmer/SKILL.md +58 -0
- package/dist/skills/project-scaffolding/SKILL.md +133 -0
- package/dist/skills/qa-engineer/SKILL.md +91 -0
- package/dist/skills/rca/SKILL.md +58 -0
- package/dist/skills/redhat/SKILL.md +92 -0
- package/dist/skills/rosa/SKILL.md +80 -0
- package/dist/skills/scrum-framework/SKILL.md +74 -0
- package/dist/skills/scrum-framework/references/artifacts_and_quality.md +79 -0
- package/dist/skills/scrum-framework/references/roles_and_events.md +105 -0
- package/dist/skills/scrum-master-agent/SKILL.md +74 -0
- package/dist/skills/scrum-master-agent/references/behaviors.md +56 -0
- package/dist/skills/sdlc-skill.d.ts +1 -0
- package/dist/skills/sdlc-skill.js +4 -0
- package/dist/skills/secops/SKILL.md +52 -0
- package/dist/skills/secure-architect.bylaws.d.ts +68 -0
- package/dist/skills/secure-architect.bylaws.js +525 -0
- package/dist/skills/seed-skills.d.ts +48 -0
- package/dist/skills/seed-skills.js +213 -0
- package/dist/skills/skill-authoring/SKILL.md +123 -0
- package/dist/skills/skill-header.d.ts +51 -0
- package/dist/skills/skill-header.js +163 -0
- package/dist/skills/skill-path-guard.d.ts +41 -0
- package/dist/skills/skill-path-guard.js +95 -0
- package/dist/skills/skillRouter.d.ts +51 -0
- package/dist/skills/skillRouter.js +90 -0
- package/dist/skills/skills-root.d.ts +64 -0
- package/dist/skills/skills-root.js +168 -0
- package/dist/skills/software-architect/SKILL.md +77 -0
- package/dist/skills/software-engineer/SKILL.md +74 -0
- package/dist/skills/solid-principles/SKILL.md +94 -0
- package/dist/skills/task-planning/SKILL.md +115 -0
- package/dist/skills/tester/SKILL.md +54 -0
- package/dist/skills/ubuntu/SKILL.md +87 -0
- package/dist/skills/ui-ux-design/SKILL.md +114 -0
- package/dist/skills/workspace-context/SKILL.md +103 -0
- package/dist/sprint/controller.d.ts +37 -0
- package/dist/sprint/controller.js +220 -0
- package/dist/sprint/dag-builder.d.ts +14 -0
- package/dist/sprint/dag-builder.js +105 -0
- package/dist/sprint/reporter.d.ts +11 -0
- package/dist/sprint/reporter.js +97 -0
- package/dist/sprint/state-store.d.ts +10 -0
- package/dist/sprint/state-store.js +71 -0
- package/dist/sprint/types.d.ts +24 -0
- package/dist/sprint/types.js +4 -0
- package/dist/store/file-version-store.d.ts +24 -0
- package/dist/store/file-version-store.js +73 -0
- package/dist/store/task-store.d.ts +90 -0
- package/dist/store/task-store.js +166 -0
- package/dist/task-ingest/architect-detailer.d.ts +43 -0
- package/dist/task-ingest/architect-detailer.js +141 -0
- package/dist/task-ingest/detail-schema.d.ts +9 -0
- package/dist/task-ingest/detail-schema.js +195 -0
- package/dist/task-ingest/detailed-run.d.ts +36 -0
- package/dist/task-ingest/detailed-run.js +108 -0
- package/dist/task-ingest/extract-id.d.ts +9 -0
- package/dist/task-ingest/extract-id.js +24 -0
- package/dist/task-ingest/index.d.ts +23 -0
- package/dist/task-ingest/index.js +14 -0
- package/dist/task-ingest/ingest.d.ts +45 -0
- package/dist/task-ingest/ingest.js +163 -0
- package/dist/task-ingest/list-ingested.d.ts +13 -0
- package/dist/task-ingest/list-ingested.js +30 -0
- package/dist/task-ingest/pending-filter.d.ts +30 -0
- package/dist/task-ingest/pending-filter.js +59 -0
- package/dist/task-ingest/scanner.d.ts +56 -0
- package/dist/task-ingest/scanner.js +216 -0
- package/dist/task-ingest/source-reader.d.ts +25 -0
- package/dist/task-ingest/source-reader.js +93 -0
- package/dist/task-ingest/spec-builder.d.ts +34 -0
- package/dist/task-ingest/spec-builder.js +89 -0
- package/dist/task-ingest/wbs-extract.d.ts +50 -0
- package/dist/task-ingest/wbs-extract.js +226 -0
- package/dist/task-ingest/wbs-parser.d.ts +36 -0
- package/dist/task-ingest/wbs-parser.js +170 -0
- package/dist/tools/apiTestTool.d.ts +37 -0
- package/dist/tools/apiTestTool.js +128 -0
- package/dist/tools/ast-tools.d.ts +183 -0
- package/dist/tools/ast-tools.js +853 -0
- package/dist/tools/browse-tool.d.ts +105 -0
- package/dist/tools/browse-tool.js +394 -0
- package/dist/tools/credential.d.ts +17 -0
- package/dist/tools/credential.js +32 -0
- package/dist/tools/dependency-graph.d.ts +23 -0
- package/dist/tools/dependency-graph.js +164 -0
- package/dist/tools/edit-tool.d.ts +34 -0
- package/dist/tools/edit-tool.js +95 -0
- package/dist/tools/file-header-manager.d.ts +27 -0
- package/dist/tools/file-header-manager.js +153 -0
- package/dist/tools/fs-tools.d.ts +154 -0
- package/dist/tools/fs-tools.js +337 -0
- package/dist/tools/git-tools.d.ts +79 -0
- package/dist/tools/git-tools.js +348 -0
- package/dist/tools/github-tool.d.ts +48 -0
- package/dist/tools/github-tool.js +147 -0
- package/dist/tools/globTool.d.ts +20 -0
- package/dist/tools/globTool.js +34 -0
- package/dist/tools/grepTool.d.ts +19 -0
- package/dist/tools/grepTool.js +44 -0
- package/dist/tools/index-freshness.d.ts +58 -0
- package/dist/tools/index-freshness.js +190 -0
- package/dist/tools/index-glob.d.ts +48 -0
- package/dist/tools/index-glob.js +175 -0
- package/dist/tools/load-skill-tool.d.ts +15 -0
- package/dist/tools/load-skill-tool.js +114 -0
- package/dist/tools/patch-tools.d.ts +58 -0
- package/dist/tools/patch-tools.js +153 -0
- package/dist/tools/playwright-tool.d.ts +66 -0
- package/dist/tools/playwright-tool.js +121 -0
- package/dist/tools/project-detect.d.ts +20 -0
- package/dist/tools/project-detect.js +87 -0
- package/dist/tools/prompt-guidance.d.ts +22 -0
- package/dist/tools/prompt-guidance.js +23 -0
- package/dist/tools/scheduleTool.d.ts +19 -0
- package/dist/tools/scheduleTool.js +181 -0
- package/dist/tools/search-tools.d.ts +27 -0
- package/dist/tools/search-tools.js +78 -0
- package/dist/tools/sed-tool.d.ts +66 -0
- package/dist/tools/sed-tool.js +402 -0
- package/dist/tools/shell-result.d.ts +11 -0
- package/dist/tools/shell-result.js +1 -0
- package/dist/tools/shell-tool.d.ts +45 -0
- package/dist/tools/shell-tool.js +141 -0
- package/dist/tools/siteCrawlerTool.d.ts +32 -0
- package/dist/tools/siteCrawlerTool.js +205 -0
- package/dist/tools/tool-registry.d.ts +67 -0
- package/dist/tools/tool-registry.js +596 -0
- package/dist/tools/validate-tool.d.ts +23 -0
- package/dist/tools/validate-tool.js +201 -0
- package/dist/tools/workspace-index.d.ts +46 -0
- package/dist/tools/workspace-index.js +173 -0
- package/dist/types.d.ts +222 -0
- package/dist/types.js +7 -0
- package/dist/updater/index.d.ts +14 -0
- package/dist/updater/index.js +120 -0
- package/dist/util/banner.d.ts +25 -0
- package/dist/util/banner.js +140 -0
- package/dist/util/command-suggester.d.ts +6 -0
- package/dist/util/command-suggester.js +25 -0
- package/dist/util/confirm-interrupt.d.ts +10 -0
- package/dist/util/confirm-interrupt.js +31 -0
- package/dist/util/continue-trigger.d.ts +11 -0
- package/dist/util/continue-trigger.js +20 -0
- package/dist/util/env-info.d.ts +18 -0
- package/dist/util/env-info.js +37 -0
- package/dist/util/file-access-log.d.ts +35 -0
- package/dist/util/file-access-log.js +140 -0
- package/dist/util/footer-manager.d.ts +124 -0
- package/dist/util/footer-manager.js +195 -0
- package/dist/util/footer-renderer.d.ts +67 -0
- package/dist/util/footer-renderer.js +319 -0
- package/dist/util/footer-state.d.ts +34 -0
- package/dist/util/footer-state.js +18 -0
- package/dist/util/footer-text.d.ts +51 -0
- package/dist/util/footer-text.js +74 -0
- package/dist/util/ids.d.ts +1 -0
- package/dist/util/ids.js +4 -0
- package/dist/util/levenshtein.d.ts +6 -0
- package/dist/util/levenshtein.js +34 -0
- package/dist/util/logger.d.ts +10 -0
- package/dist/util/logger.js +41 -0
- package/dist/util/logs.d.ts +26 -0
- package/dist/util/logs.js +88 -0
- package/dist/util/output-handler.d.ts +89 -0
- package/dist/util/output-handler.js +193 -0
- package/dist/util/output-interceptor.d.ts +18 -0
- package/dist/util/output-interceptor.js +49 -0
- package/dist/util/output-paths.d.ts +43 -0
- package/dist/util/output-paths.js +121 -0
- package/dist/util/package-json.d.ts +6 -0
- package/dist/util/package-json.js +36 -0
- package/dist/util/process-kill.d.ts +27 -0
- package/dist/util/process-kill.js +148 -0
- package/dist/util/protocol-error-logger.d.ts +33 -0
- package/dist/util/protocol-error-logger.js +73 -0
- package/dist/util/redact.d.ts +25 -0
- package/dist/util/redact.js +103 -0
- package/dist/util/scroll-region-guard.d.ts +33 -0
- package/dist/util/scroll-region-guard.js +63 -0
- package/dist/util/spinner.d.ts +15 -0
- package/dist/util/spinner.js +49 -0
- package/dist/util/terminal-output.d.ts +34 -0
- package/dist/util/terminal-output.js +1 -0
- package/dist/util/terminal-silent.d.ts +6 -0
- package/dist/util/terminal-silent.js +20 -0
- package/dist/util/terminal.d.ts +56 -0
- package/dist/util/terminal.js +124 -0
- package/dist/util/text-sanitize.d.ts +8 -0
- package/dist/util/text-sanitize.js +45 -0
- package/dist/util/thinking-spinner.d.ts +27 -0
- package/dist/util/thinking-spinner.js +189 -0
- package/dist/util/tool-error-logger.d.ts +33 -0
- package/dist/util/tool-error-logger.js +77 -0
- package/dist/util/tty.d.ts +13 -0
- package/dist/util/tty.js +16 -0
- package/dist/util/xcoder-paths.d.ts +56 -0
- package/dist/util/xcoder-paths.js +63 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/worker-agent/to-subtask-node.d.ts +35 -0
- package/dist/worker-agent/to-subtask-node.js +41 -0
- package/dist/worker-agent/worker-orchestrator.d.ts +104 -0
- package/dist/worker-agent/worker-orchestrator.js +201 -0
- package/package.json +38 -3
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// xcoder:version 4 | xcoder:task task-c4a64f | xcoder:updated 2026-10-17T03:03:13.222Z | xcoder:subtask test-st-3a3927
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveInWorkspace } from "./patch-tools.js";
|
|
5
|
+
import { runCommandTool } from "./shell-tool.js";
|
|
6
|
+
import { detectProjectCommands } from "./project-detect.js";
|
|
7
|
+
import { getOrBuildIndex } from "./workspace-index.js";
|
|
8
|
+
const EXT_LANG = {
|
|
9
|
+
".ts": "typescript",
|
|
10
|
+
".tsx": "typescript",
|
|
11
|
+
".mts": "typescript",
|
|
12
|
+
".cts": "typescript",
|
|
13
|
+
".js": "javascript",
|
|
14
|
+
".jsx": "javascript",
|
|
15
|
+
".mjs": "javascript",
|
|
16
|
+
".cjs": "javascript",
|
|
17
|
+
".py": "python",
|
|
18
|
+
".json": "json",
|
|
19
|
+
};
|
|
20
|
+
function guessLanguage(relPath) {
|
|
21
|
+
return EXT_LANG[path.extname(relPath).toLowerCase()] ?? "text";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Last-resort in-process TypeScript syntax check, used only when no external
|
|
25
|
+
* checker could be executed. Node's type stripper is the same parser that
|
|
26
|
+
* runs TS files natively, so it accepts every construct `node --check`
|
|
27
|
+
* rejects while still catching genuinely broken syntax (`const x = ;`).
|
|
28
|
+
*/
|
|
29
|
+
async function checkTypeScriptSyntax(full) {
|
|
30
|
+
let stripTypeScriptTypes;
|
|
31
|
+
try {
|
|
32
|
+
const mod = (await import("node:module"));
|
|
33
|
+
stripTypeScriptTypes = mod.stripTypeScriptTypes;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
stripTypeScriptTypes = undefined;
|
|
37
|
+
}
|
|
38
|
+
// Older Node without the helper is not a validation failure.
|
|
39
|
+
if (typeof stripTypeScriptTypes !== "function")
|
|
40
|
+
return { passed: true, errors: [] };
|
|
41
|
+
try {
|
|
42
|
+
const src = await fs.readFile(full, "utf8");
|
|
43
|
+
stripTypeScriptTypes(src);
|
|
44
|
+
return { passed: true, errors: [] };
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
const message = e?.message ?? String(e);
|
|
48
|
+
return { passed: false, errors: [`TypeScript syntax error: ${message.split("\n")[0]}`] };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* validate_file (AC-17): post-edit syntax/type check on JUST the patched
|
|
53
|
+
* file. Prefers the workspace's own detected `typecheck`/`lint` commands,
|
|
54
|
+
* then fast per-language syntax fallbacks (node --check, py_compile, JSON
|
|
55
|
+
* parse). Returns ONLY error lines — never the file body. Like every tool,
|
|
56
|
+
* it never throws; uncheckable languages return `no_checker_available` with
|
|
57
|
+
* a fallback suggestion.
|
|
58
|
+
*/
|
|
59
|
+
export async function validateFileTool(root, relPath, lang) {
|
|
60
|
+
let full;
|
|
61
|
+
try {
|
|
62
|
+
full = resolveInWorkspace(root, relPath);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return { ok: false, code: "workspace_escape", error: e.message };
|
|
66
|
+
}
|
|
67
|
+
// Fail fast on a missing file before any checker runs.
|
|
68
|
+
try {
|
|
69
|
+
await fs.access(full);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
code: "file_not_found",
|
|
75
|
+
error: `"${relPath}" doesn't exist. Use write_file to create it before validating.`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const language = (lang ?? guessLanguage(relPath)).toLowerCase();
|
|
79
|
+
const started = Date.now();
|
|
80
|
+
// 1) Try the project's own typecheck/lint first — it's already computed
|
|
81
|
+
// per workspace and is the most accurate signal.
|
|
82
|
+
try {
|
|
83
|
+
const index = await getOrBuildIndex(root);
|
|
84
|
+
const cmds = await detectProjectCommands(root, index);
|
|
85
|
+
const candidates = [cmds.typecheck, cmds.lint].filter((c) => !!c);
|
|
86
|
+
for (const candidate of candidates) {
|
|
87
|
+
const res = await runCommandTool(candidate, root, 120_000);
|
|
88
|
+
const errors = extractErrorLines(res.stdout + "\n" + res.stderr);
|
|
89
|
+
return {
|
|
90
|
+
ok: true,
|
|
91
|
+
result: {
|
|
92
|
+
passed: res.ok && errors.length === 0,
|
|
93
|
+
command: candidate,
|
|
94
|
+
tool: "project-command",
|
|
95
|
+
errors: errors.length > 0 ? errors.slice(0, 40) : undefined,
|
|
96
|
+
tookMs: Date.now() - started,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// fall through to language-specific syntax checks
|
|
103
|
+
}
|
|
104
|
+
// 2) Fast per-language syntax fallbacks.
|
|
105
|
+
//
|
|
106
|
+
// TypeScript MUST NOT go through `node --check`: that parser rejects
|
|
107
|
+
// TS-only syntax (annotations, interfaces, generics), so every valid .ts
|
|
108
|
+
// file was reported as failing. Use a TS-aware checker instead, and only
|
|
109
|
+
// count diagnostics that point at this file so project/include-level noise
|
|
110
|
+
// can never mark a good edit as broken.
|
|
111
|
+
if (language === "typescript") {
|
|
112
|
+
const res = await runCommandTool(`npx tsc --noEmit --skipLibCheck --target esnext --module esnext "${full}"`, root, 120_000);
|
|
113
|
+
const raw = extractErrorLines(res.stdout + "\n" + res.stderr);
|
|
114
|
+
const relevant = raw.filter((line) => line.includes(full) || line.includes(relPath));
|
|
115
|
+
// A checker that never ran (npx missing / tsc unavailable) must not be
|
|
116
|
+
// reported as a passing validation.
|
|
117
|
+
if (!res.ok && raw.length === 0) {
|
|
118
|
+
const fallback = await checkTypeScriptSyntax(full);
|
|
119
|
+
return {
|
|
120
|
+
ok: true,
|
|
121
|
+
result: {
|
|
122
|
+
passed: fallback.passed,
|
|
123
|
+
command: "stripTypeScriptTypes",
|
|
124
|
+
tool: "in-process",
|
|
125
|
+
errors: fallback.errors.length > 0 ? fallback.errors.slice(0, 40) : undefined,
|
|
126
|
+
tookMs: Date.now() - started,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
ok: true,
|
|
132
|
+
result: {
|
|
133
|
+
passed: res.ok && relevant.length === 0,
|
|
134
|
+
command: "tsc --noEmit",
|
|
135
|
+
tool: "typecheck",
|
|
136
|
+
errors: relevant.length > 0 ? relevant.slice(0, 40) : undefined,
|
|
137
|
+
tookMs: Date.now() - started,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (language === "javascript") {
|
|
142
|
+
const res = await runCommandTool(`node --check "${full}"`, root, 60_000);
|
|
143
|
+
const errors = extractErrorLines(res.stderr);
|
|
144
|
+
return {
|
|
145
|
+
ok: true,
|
|
146
|
+
result: {
|
|
147
|
+
passed: res.ok && errors.length === 0,
|
|
148
|
+
command: "node --check",
|
|
149
|
+
tool: "syntax",
|
|
150
|
+
errors: errors.length > 0 ? errors.slice(0, 40) : undefined,
|
|
151
|
+
tookMs: Date.now() - started,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (language === "python") {
|
|
156
|
+
const res = await runCommandTool(`python -m py_compile "${full}"`, root, 60_000);
|
|
157
|
+
const errors = extractErrorLines(res.stderr);
|
|
158
|
+
return {
|
|
159
|
+
ok: true,
|
|
160
|
+
result: {
|
|
161
|
+
passed: res.ok && errors.length === 0,
|
|
162
|
+
command: "python -m py_compile",
|
|
163
|
+
tool: "syntax",
|
|
164
|
+
errors: errors.length > 0 ? errors.slice(0, 40) : undefined,
|
|
165
|
+
tookMs: Date.now() - started,
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (language === "json") {
|
|
170
|
+
try {
|
|
171
|
+
const raw = await fs.readFile(full, "utf8");
|
|
172
|
+
JSON.parse(raw);
|
|
173
|
+
return { ok: true, result: { passed: true, command: "JSON.parse", tool: "in-process", tookMs: Date.now() - started } };
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
return {
|
|
177
|
+
ok: true,
|
|
178
|
+
result: {
|
|
179
|
+
passed: false,
|
|
180
|
+
command: "JSON.parse",
|
|
181
|
+
tool: "in-process",
|
|
182
|
+
errors: [`JSON parse error: ${e.message}`],
|
|
183
|
+
tookMs: Date.now() - started,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
ok: false,
|
|
190
|
+
code: "no_checker_available",
|
|
191
|
+
error: `no syntax/type checker found for "${language}" ("${relPath}"). Use run_command to run an appropriate compiler/linter for this language.`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** Pulls only error/warning lines out of mixed output — never file bodies. */
|
|
195
|
+
function extractErrorLines(output) {
|
|
196
|
+
return output
|
|
197
|
+
.split("\n")
|
|
198
|
+
.map((l) => l.trim())
|
|
199
|
+
.filter((l) => l !== "" && /(?:error|Error|❌|✖|failed|Cannot find|TS\d+|SyntaxError|ModuleNotFound)/.test(l))
|
|
200
|
+
.slice(0, 40);
|
|
201
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface IndexEntry {
|
|
2
|
+
relPath: string;
|
|
3
|
+
sizeBytes: number;
|
|
4
|
+
mtimeMs: number;
|
|
5
|
+
sha1: string;
|
|
6
|
+
language: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WorkspaceIndex {
|
|
9
|
+
root: string;
|
|
10
|
+
builtAt: string;
|
|
11
|
+
entries: IndexEntry[];
|
|
12
|
+
}
|
|
13
|
+
export declare const IGNORE_DIRS: Set<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Files above this size are never hashed or indexed.
|
|
16
|
+
*
|
|
17
|
+
* Exported because the freshness probe must apply the same threshold as the
|
|
18
|
+
* builder. If it did not, every file above the cap would look like a missing
|
|
19
|
+
* index entry on every probe and the index would be rebuilt forever.
|
|
20
|
+
*/
|
|
21
|
+
export declare const MAX_INDEXED_FILE_BYTES = 5000000;
|
|
22
|
+
/**
|
|
23
|
+
* Every path this module stores or compares goes through this first.
|
|
24
|
+
*
|
|
25
|
+
* `path.relative()` uses the OS-native separator — backslashes on Windows.
|
|
26
|
+
* The model, quite reasonably, tends to write and request paths with
|
|
27
|
+
* forward slashes regardless of platform (it's the universal convention
|
|
28
|
+
* in code, docs, and every other tool's examples). Without normalization,
|
|
29
|
+
* a Windows index stores `requirements\design.md` while the model asks
|
|
30
|
+
* for `requirements/design.md`, the exact-string lookup in `findInIndex`
|
|
31
|
+
* fails, and `read_file` reports a false `file_not_found` for a file that
|
|
32
|
+
* genuinely exists — burning iterations on rediscovery instead of actual
|
|
33
|
+
* work. Storing (and comparing against) forward-slash-normalized paths
|
|
34
|
+
* everywhere makes every lookup, glob, and grep work identically
|
|
35
|
+
* regardless of which slash style either side happens to use.
|
|
36
|
+
*/
|
|
37
|
+
export declare function toPosixPath(p: string): string;
|
|
38
|
+
/** Full rebuild. This is the expensive path — call it, don't call it often. */
|
|
39
|
+
export declare function buildIndex(root: string): Promise<WorkspaceIndex>;
|
|
40
|
+
export declare function loadIndex(root: string): Promise<WorkspaceIndex | null>;
|
|
41
|
+
export declare function getOrBuildIndex(root: string): Promise<WorkspaceIndex>;
|
|
42
|
+
/** Cheap incremental update after a single write — avoids a full rescan per file. */
|
|
43
|
+
export declare function upsertEntry(root: string, relPath: string): Promise<void>;
|
|
44
|
+
/** Normalizes the lookup path the same way stored paths are normalized, so a lookup succeeds regardless of which slash style the caller used. */
|
|
45
|
+
export declare function findInIndex(index: WorkspaceIndex, relPath: string): IndexEntry | undefined;
|
|
46
|
+
export declare function searchIndex(index: WorkspaceIndex, query: string, limit?: number): IndexEntry[];
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// xcoder:version 3 | xcoder:task task-e16f85 | xcoder:updated 2026-10-30T18:13:45.828Z | xcoder:subtask code-st-791be4
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import crypto from "node:crypto";
|
|
5
|
+
export const IGNORE_DIRS = new Set([
|
|
6
|
+
"node_modules",
|
|
7
|
+
".git",
|
|
8
|
+
"dist",
|
|
9
|
+
"build",
|
|
10
|
+
".xcoder",
|
|
11
|
+
".next",
|
|
12
|
+
".venv",
|
|
13
|
+
"__pycache__",
|
|
14
|
+
"coverage",
|
|
15
|
+
".turbo",
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Files above this size are never hashed or indexed.
|
|
19
|
+
*
|
|
20
|
+
* Exported because the freshness probe must apply the same threshold as the
|
|
21
|
+
* builder. If it did not, every file above the cap would look like a missing
|
|
22
|
+
* index entry on every probe and the index would be rebuilt forever.
|
|
23
|
+
*/
|
|
24
|
+
export const MAX_INDEXED_FILE_BYTES = 5_000_000;
|
|
25
|
+
const LANGUAGE_BY_EXT = {
|
|
26
|
+
".ts": "typescript",
|
|
27
|
+
".tsx": "typescript",
|
|
28
|
+
".js": "javascript",
|
|
29
|
+
".jsx": "javascript",
|
|
30
|
+
".py": "python",
|
|
31
|
+
".go": "go",
|
|
32
|
+
".java": "java",
|
|
33
|
+
".rb": "ruby",
|
|
34
|
+
".rs": "rust",
|
|
35
|
+
".json": "json",
|
|
36
|
+
".md": "markdown",
|
|
37
|
+
".yaml": "yaml",
|
|
38
|
+
".yml": "yaml",
|
|
39
|
+
".sql": "sql",
|
|
40
|
+
".sh": "shell",
|
|
41
|
+
};
|
|
42
|
+
function indexPath(root) {
|
|
43
|
+
return path.join(root, ".xcoder", "workspace-index.json");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Every path this module stores or compares goes through this first.
|
|
47
|
+
*
|
|
48
|
+
* `path.relative()` uses the OS-native separator — backslashes on Windows.
|
|
49
|
+
* The model, quite reasonably, tends to write and request paths with
|
|
50
|
+
* forward slashes regardless of platform (it's the universal convention
|
|
51
|
+
* in code, docs, and every other tool's examples). Without normalization,
|
|
52
|
+
* a Windows index stores `requirements\design.md` while the model asks
|
|
53
|
+
* for `requirements/design.md`, the exact-string lookup in `findInIndex`
|
|
54
|
+
* fails, and `read_file` reports a false `file_not_found` for a file that
|
|
55
|
+
* genuinely exists — burning iterations on rediscovery instead of actual
|
|
56
|
+
* work. Storing (and comparing against) forward-slash-normalized paths
|
|
57
|
+
* everywhere makes every lookup, glob, and grep work identically
|
|
58
|
+
* regardless of which slash style either side happens to use.
|
|
59
|
+
*/
|
|
60
|
+
export function toPosixPath(p) {
|
|
61
|
+
return p.split(path.sep).join("/").replace(/\\/g, "/");
|
|
62
|
+
}
|
|
63
|
+
function guessLanguage(p) {
|
|
64
|
+
return LANGUAGE_BY_EXT[path.extname(p)] ?? "text";
|
|
65
|
+
}
|
|
66
|
+
async function hashFile(fullPath) {
|
|
67
|
+
const buf = await fs.readFile(fullPath);
|
|
68
|
+
return crypto.createHash("sha1").update(buf).digest("hex");
|
|
69
|
+
}
|
|
70
|
+
async function walk(dir, root, acc) {
|
|
71
|
+
let entries;
|
|
72
|
+
try {
|
|
73
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
if (entry.name.startsWith(".") && entry.name !== ".env.example") {
|
|
80
|
+
if (entry.isDirectory() && !IGNORE_DIRS.has(entry.name)) {
|
|
81
|
+
// allow hidden dirs the user explicitly wants scanned in the future;
|
|
82
|
+
// for now, skip all dotfiles/dotdirs except the explicit allowlist above.
|
|
83
|
+
}
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const full = path.join(dir, entry.name);
|
|
87
|
+
if (entry.isDirectory()) {
|
|
88
|
+
if (IGNORE_DIRS.has(entry.name))
|
|
89
|
+
continue;
|
|
90
|
+
await walk(full, root, acc);
|
|
91
|
+
}
|
|
92
|
+
else if (entry.isFile()) {
|
|
93
|
+
try {
|
|
94
|
+
const stat = await fs.stat(full);
|
|
95
|
+
// Skip anything absurdly large — it has no business being hashed
|
|
96
|
+
// wholesale and inlined-by-reference is the right pattern anyway.
|
|
97
|
+
if (stat.size > MAX_INDEXED_FILE_BYTES)
|
|
98
|
+
continue;
|
|
99
|
+
const sha1 = await hashFile(full);
|
|
100
|
+
acc.push({
|
|
101
|
+
relPath: toPosixPath(path.relative(root, full)),
|
|
102
|
+
sizeBytes: stat.size,
|
|
103
|
+
mtimeMs: stat.mtimeMs,
|
|
104
|
+
sha1,
|
|
105
|
+
language: guessLanguage(full),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// unreadable file (permissions, race with a concurrent delete) — skip it
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Full rebuild. This is the expensive path — call it, don't call it often. */
|
|
115
|
+
export async function buildIndex(root) {
|
|
116
|
+
const entries = [];
|
|
117
|
+
await walk(root, root, entries);
|
|
118
|
+
const index = { root, builtAt: new Date().toISOString(), entries };
|
|
119
|
+
await fs.mkdir(path.join(root, ".xcoder"), { recursive: true });
|
|
120
|
+
await fs.writeFile(indexPath(root), JSON.stringify(index, null, 2), "utf8");
|
|
121
|
+
return index;
|
|
122
|
+
}
|
|
123
|
+
export async function loadIndex(root) {
|
|
124
|
+
try {
|
|
125
|
+
const raw = await fs.readFile(indexPath(root), "utf8");
|
|
126
|
+
return JSON.parse(raw);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export async function getOrBuildIndex(root) {
|
|
133
|
+
const existing = await loadIndex(root);
|
|
134
|
+
if (existing)
|
|
135
|
+
return existing;
|
|
136
|
+
return buildIndex(root);
|
|
137
|
+
}
|
|
138
|
+
/** Cheap incremental update after a single write — avoids a full rescan per file. */
|
|
139
|
+
export async function upsertEntry(root, relPath) {
|
|
140
|
+
const index = (await loadIndex(root)) ?? { root, builtAt: new Date().toISOString(), entries: [] };
|
|
141
|
+
const normalizedRelPath = toPosixPath(relPath);
|
|
142
|
+
const full = path.join(root, relPath); // path.join/resolve handle forward slashes fine on every OS, including Windows
|
|
143
|
+
try {
|
|
144
|
+
const stat = await fs.stat(full);
|
|
145
|
+
const sha1 = await hashFile(full);
|
|
146
|
+
const next = {
|
|
147
|
+
relPath: normalizedRelPath,
|
|
148
|
+
sizeBytes: stat.size,
|
|
149
|
+
mtimeMs: stat.mtimeMs,
|
|
150
|
+
sha1,
|
|
151
|
+
language: guessLanguage(full),
|
|
152
|
+
};
|
|
153
|
+
const idx = index.entries.findIndex((e) => e.relPath === normalizedRelPath);
|
|
154
|
+
if (idx >= 0)
|
|
155
|
+
index.entries[idx] = next;
|
|
156
|
+
else
|
|
157
|
+
index.entries.push(next);
|
|
158
|
+
await fs.writeFile(indexPath(root), JSON.stringify(index, null, 2), "utf8");
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// file vanished between write and index update — ignore, next full
|
|
162
|
+
// reindex will reconcile it.
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Normalizes the lookup path the same way stored paths are normalized, so a lookup succeeds regardless of which slash style the caller used. */
|
|
166
|
+
export function findInIndex(index, relPath) {
|
|
167
|
+
const normalized = toPosixPath(relPath).replace(/^\.\//, "");
|
|
168
|
+
return index.entries.find((e) => e.relPath === normalized);
|
|
169
|
+
}
|
|
170
|
+
export function searchIndex(index, query, limit = 30) {
|
|
171
|
+
const q = toPosixPath(query).toLowerCase();
|
|
172
|
+
return index.entries.filter((e) => e.relPath.toLowerCase().includes(q)).slice(0, limit);
|
|
173
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core contracts. Everything else in this codebase is built around these
|
|
3
|
+
* shapes — the same principle Agent Factory's `af-shared-contracts` repo
|
|
4
|
+
* follows: one definition, imported everywhere, never hand-copied.
|
|
5
|
+
*/
|
|
6
|
+
import type { BylawLayer } from "./skills/secure-architect.bylaws.js";
|
|
7
|
+
export type SdlcStage = "requirements" | "design" | "code" | "refactor" | "test" | "ui_api_test" | "fix_defect" | "document" | "deploy" | "conversation" | "quality_gate";
|
|
8
|
+
export type Role = "requirements-analyst" | "architect" | "programmer" | "refactorer" | "tester" | "ui-api-tester" | "technical-writer" | "devops" | "conversation" | "business-analyst" | "defect-manager" | "scrum-master" | "system-architect" | "security-lead";
|
|
9
|
+
export type EngineName = "react-v1" | "rewoo-v1" | "plan-execute-v1" | "reflexion-v1";
|
|
10
|
+
/** Raw inputs as described in the brief: code / design / defect / url / credential. */
|
|
11
|
+
export interface TaskInputs {
|
|
12
|
+
code?: string;
|
|
13
|
+
design?: string;
|
|
14
|
+
defectDetail?: string;
|
|
15
|
+
url?: string;
|
|
16
|
+
credentialRef?: string;
|
|
17
|
+
freeText?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Workspace-relative POSIX path of the markdown/WBS source this task was
|
|
20
|
+
* ingested from (`xcoder task add --from <path>`). This is the idempotency
|
|
21
|
+
* key, readable back off the record. Inert data — it is NEVER re-interpreted
|
|
22
|
+
* as a path, command, URL or model directive at read time.
|
|
23
|
+
*/
|
|
24
|
+
sourcePath?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Workspace-relative POSIX path to the author-supplied requirements document
|
|
27
|
+
* that drives the QA workflow (requirement -> plan -> Playwright specs ->
|
|
28
|
+
* run -> report). Additive: its presence is what opts a task into that
|
|
29
|
+
* route, and no pre-existing intake rule changes behaviour without it.
|
|
30
|
+
*/
|
|
31
|
+
requirementsPath?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Minimum fraction (0<t<=1) of requirements whose tests must actually run
|
|
34
|
+
* and pass before the QA workflow may report a pass. Defaults to 1.0 - the
|
|
35
|
+
* brief asks for coverage of every requirement (design T1).
|
|
36
|
+
*/
|
|
37
|
+
coverageThreshold?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface TaskSpec {
|
|
40
|
+
taskId: string;
|
|
41
|
+
goal: string;
|
|
42
|
+
inputs: TaskInputs;
|
|
43
|
+
constraints: {
|
|
44
|
+
budgetUsd?: number;
|
|
45
|
+
maxHealingAttempts: number;
|
|
46
|
+
concurrency: number;
|
|
47
|
+
};
|
|
48
|
+
createdAt: string;
|
|
49
|
+
/**
|
|
50
|
+
* Audit trail for `xcoder task add --from <path>` ingestion. Absent on
|
|
51
|
+
* free-text tasks, which keeps every existing record byte-compatible.
|
|
52
|
+
* Recorded for provenance only — nothing downstream acts on it.
|
|
53
|
+
*/
|
|
54
|
+
provenance?: {
|
|
55
|
+
sourcePath: string;
|
|
56
|
+
sourceSha256: string;
|
|
57
|
+
ingestedAt: string;
|
|
58
|
+
ingestVersion: 1;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export type SubtaskStatus = "pending" | "ready" | "in_progress" | "validating" | "healing" | "escalated" | "blocked" | "done" | "failed";
|
|
62
|
+
export interface AcceptanceCriterion {
|
|
63
|
+
id: string;
|
|
64
|
+
type: "schema" | "command" | "rubric" | "file-exists" | "bylaw-review";
|
|
65
|
+
description: string;
|
|
66
|
+
/** For `command` type: a shell command run from the workspace root; exit code 0 = pass. */
|
|
67
|
+
command?: string;
|
|
68
|
+
/** For `file-exists` type: a glob pattern relative to the workspace root. At least one matching file must exist. */
|
|
69
|
+
pathGlob?: string;
|
|
70
|
+
/** For `bylaw-review` type: restrict the review scope to these layers.
|
|
71
|
+
* Omitted => inferLayers(goal) at validation time. */
|
|
72
|
+
bylawLayers?: BylawLayer[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A fully self-contained work order. A Sub Agent must be able to execute
|
|
76
|
+
* this in isolation, with its own memory loop, using nothing beyond this
|
|
77
|
+
* node, the tool registry, and its role's directive/skills.
|
|
78
|
+
*/
|
|
79
|
+
export interface SubtaskNode {
|
|
80
|
+
id: string;
|
|
81
|
+
stage: SdlcStage;
|
|
82
|
+
role: Role;
|
|
83
|
+
engine: EngineName;
|
|
84
|
+
dependsOn: string[];
|
|
85
|
+
goal: string;
|
|
86
|
+
/** Inlined outputs from upstream nodes — never a lookup id. */
|
|
87
|
+
upstreamContext: Record<string, unknown>;
|
|
88
|
+
/** What this subtask must hand back to the Master Orchestrator. */
|
|
89
|
+
deliverableSpec: string;
|
|
90
|
+
acceptanceCriteria: AcceptanceCriterion[];
|
|
91
|
+
status: SubtaskStatus;
|
|
92
|
+
healing: {
|
|
93
|
+
attempts: number;
|
|
94
|
+
maxAttempts: number;
|
|
95
|
+
log: string[];
|
|
96
|
+
};
|
|
97
|
+
result?: SubtaskResult;
|
|
98
|
+
/** Computed once per attempt by orchestrator/reasoning-score.ts, after validation. Not a pass/fail gate — see that file's doc comment for what this is and isn't for. */
|
|
99
|
+
reasoningScore?: {
|
|
100
|
+
score: number;
|
|
101
|
+
breakdown: string[];
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export interface TokenUsage {
|
|
105
|
+
inputTokens: number;
|
|
106
|
+
outputTokens: number;
|
|
107
|
+
}
|
|
108
|
+
/** Tracks the operation type for each file touched by a subtask. */
|
|
109
|
+
export type FileTouchOperation = "created" | "modified" | "touched";
|
|
110
|
+
export interface FileTouchEntry {
|
|
111
|
+
path: string;
|
|
112
|
+
operation: FileTouchOperation;
|
|
113
|
+
}
|
|
114
|
+
export interface SubtaskResult {
|
|
115
|
+
summary: string;
|
|
116
|
+
deliverable: unknown;
|
|
117
|
+
filesTouched: string[];
|
|
118
|
+
/**
|
|
119
|
+
* Optional additive field carrying operation type per file.
|
|
120
|
+
* Populated alongside filesTouched when context is available.
|
|
121
|
+
* When absent, consumers fall back to `filesTouched: string[]` with a
|
|
122
|
+
* generic `[touched]` label.
|
|
123
|
+
*/
|
|
124
|
+
_filesTouchedMeta?: FileTouchEntry[];
|
|
125
|
+
selfCheck?: {
|
|
126
|
+
ran: boolean;
|
|
127
|
+
passed: boolean;
|
|
128
|
+
detail: string;
|
|
129
|
+
};
|
|
130
|
+
raoTrace: RaoStep[];
|
|
131
|
+
tokenUsage: TokenUsage;
|
|
132
|
+
/** Number of ReAct loop turns taken to reach this result — the "iteration count" the benchmark harness and reasoning score both key off. */
|
|
133
|
+
iterations: number;
|
|
134
|
+
/** True if this result is a synthetic stand-in produced after the Sub Agent's
|
|
135
|
+
* process crashed — the Master Orchestrator never crashes with it (see
|
|
136
|
+
* `orchestrator/swarm.ts`); it treats a crash as a failed subtask that can
|
|
137
|
+
* still go through the normal bounded healing/escalation path. */
|
|
138
|
+
crashed?: boolean;
|
|
139
|
+
/** True if the attempt was aborted early because DuplicateActionDetector flagged it as a stuck loop rather than running to the full iteration cap. */
|
|
140
|
+
stuckLoop?: boolean;
|
|
141
|
+
/** True when the sub-agent exhausted its maxIterations without producing a final_answer. Set ONLY by SubAgent.run() in that case; never set in crashResult or stuckLoop returns. */
|
|
142
|
+
iterationsExhausted?: boolean;
|
|
143
|
+
}
|
|
144
|
+
export interface RaoStep {
|
|
145
|
+
thought: string;
|
|
146
|
+
action: {
|
|
147
|
+
tool: string;
|
|
148
|
+
input: unknown;
|
|
149
|
+
} | null;
|
|
150
|
+
observation: string;
|
|
151
|
+
}
|
|
152
|
+
export interface TaskRun {
|
|
153
|
+
spec: TaskSpec;
|
|
154
|
+
dag: SubtaskNode[];
|
|
155
|
+
status: "planning" | "running" | "done" | "halted" | "escalated";
|
|
156
|
+
escalations: {
|
|
157
|
+
subtaskId: string;
|
|
158
|
+
reason: string;
|
|
159
|
+
}[];
|
|
160
|
+
orchestratorTrace: RaoStep[];
|
|
161
|
+
finalDeliverable?: string;
|
|
162
|
+
totalTokenUsage: TokenUsage;
|
|
163
|
+
/** Interactive steering injections captured during this run, in order. */
|
|
164
|
+
steeringLog?: import("./orchestrator/interactive-steering.js").SteeringInjection[];
|
|
165
|
+
}
|
|
166
|
+
export type OrchestratorAction = {
|
|
167
|
+
type: "dispatch";
|
|
168
|
+
subtaskIds: string[];
|
|
169
|
+
} | {
|
|
170
|
+
type: "retry";
|
|
171
|
+
subtaskId: string;
|
|
172
|
+
hint: string;
|
|
173
|
+
} | {
|
|
174
|
+
type: "replan";
|
|
175
|
+
patch: {
|
|
176
|
+
addNodes?: SubtaskNode[];
|
|
177
|
+
removeNodeIds?: string[];
|
|
178
|
+
};
|
|
179
|
+
} | {
|
|
180
|
+
type: "escalate";
|
|
181
|
+
subtaskId: string;
|
|
182
|
+
reason: string;
|
|
183
|
+
} | {
|
|
184
|
+
type: "halt";
|
|
185
|
+
reason: string;
|
|
186
|
+
};
|
|
187
|
+
export interface DecisionContext {
|
|
188
|
+
dag: SubtaskNode[];
|
|
189
|
+
triggeringEvent: "subtask_failed" | "subtask_done" | "budget_warning" | "stuck_timeout";
|
|
190
|
+
subtask?: SubtaskNode;
|
|
191
|
+
}
|
|
192
|
+
export interface ReasoningEngine {
|
|
193
|
+
name: EngineName;
|
|
194
|
+
decide(context: DecisionContext): Promise<OrchestratorAction>;
|
|
195
|
+
}
|
|
196
|
+
export interface LoadedSkill {
|
|
197
|
+
header: SkillHeader;
|
|
198
|
+
body: string;
|
|
199
|
+
path: string;
|
|
200
|
+
}
|
|
201
|
+
export interface SkillHeader {
|
|
202
|
+
name: string;
|
|
203
|
+
role: string;
|
|
204
|
+
description: string;
|
|
205
|
+
triggers: string[];
|
|
206
|
+
version: string;
|
|
207
|
+
requires_tools: string[];
|
|
208
|
+
composes_with: string[];
|
|
209
|
+
}
|
|
210
|
+
/** A single lesson recorded into .xcoder/lesson.md. */
|
|
211
|
+
export interface LessonEntry {
|
|
212
|
+
/** Who recorded this — "orchestrator" | "sub-agent:<role>" | "samurai" */
|
|
213
|
+
source: string;
|
|
214
|
+
/** The task ID this was learned under, or "N/A" for standalone samurai. */
|
|
215
|
+
taskId: string;
|
|
216
|
+
/** Free-form tags for later categorisation (e.g. ["build-failure", "npm"]). */
|
|
217
|
+
tags: string[];
|
|
218
|
+
/** Brief description of what was happening when the lesson was recorded. */
|
|
219
|
+
context: string;
|
|
220
|
+
/** The actual insight — what was hard, why, and what was figured out. */
|
|
221
|
+
lesson: string;
|
|
222
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// xcoder:version 4 | xcoder:task task-a91099 | xcoder:updated 2026-10-23T10:52:21.073Z | xcoder:subtask code-st-03748c
|
|
2
|
+
/**
|
|
3
|
+
* Core contracts. Everything else in this codebase is built around these
|
|
4
|
+
* shapes — the same principle Agent Factory's `af-shared-contracts` repo
|
|
5
|
+
* follows: one definition, imported everywhere, never hand-copied.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Auto-Update Module — §3.5 of design-desktop-installer.md */
|
|
2
|
+
export interface UpdaterOptions {
|
|
3
|
+
currentVersion: string;
|
|
4
|
+
repo: string;
|
|
5
|
+
checkIntervalMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface UpdateCheckResult {
|
|
8
|
+
updateAvailable: boolean;
|
|
9
|
+
latestVersion: string | null;
|
|
10
|
+
downloadUrl: string | null;
|
|
11
|
+
releaseNotes: string | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkForUpdate(opts: UpdaterOptions): Promise<UpdateCheckResult>;
|
|
14
|
+
export declare function downloadAndApplyUpdate(downloadUrl: string, sha256Url: string): Promise<void>;
|