xcoder-dna 0.0.0-stage → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +66 -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 +39 -4
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built directly from real evidence, not speculation: a production run's
|
|
3
|
+
* `code` subtask re-read the same design document 11 times across its
|
|
4
|
+
* attempts (multiple times WITHIN a single attempt, not just once per
|
|
5
|
+
* fresh retry) and repeatedly re-checked for files it hadn't created yet,
|
|
6
|
+
* leaving almost none of its 25-iteration budget for actual file writing.
|
|
7
|
+
* That pattern — the exact same (thought, action) pair recurring — is
|
|
8
|
+
* cheap to detect and, left unflagged, silently burns the entire
|
|
9
|
+
* iteration budget on zero net progress.
|
|
10
|
+
*
|
|
11
|
+
* Scope: per SubAgent.run() call (one attempt), not persisted across
|
|
12
|
+
* healing retries — a fresh attempt gets a fresh detector, since a brand
|
|
13
|
+
* new transcript legitimately has no memory of the previous attempt's
|
|
14
|
+
* actions anyway (that's `sdlc-orchestrator.ts`'s file-carryover
|
|
15
|
+
* healing hint's job, not this one's).
|
|
16
|
+
*/
|
|
17
|
+
/** Recursively sorts object keys before stringifying, so two structurally-identical inputs compare equal regardless of key order the model happened to emit them in. */
|
|
18
|
+
function stableStringify(value) {
|
|
19
|
+
if (value === null || typeof value !== "object")
|
|
20
|
+
return JSON.stringify(value);
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return `[${value.map(stableStringify).join(",")}]`;
|
|
23
|
+
const keys = Object.keys(value).sort();
|
|
24
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`;
|
|
25
|
+
}
|
|
26
|
+
function normalizeThought(thought) {
|
|
27
|
+
return thought.trim().toLowerCase().replace(/\s+/g, " ");
|
|
28
|
+
}
|
|
29
|
+
export function actionKey(tool, input) {
|
|
30
|
+
return `${tool}::${stableStringify(input)}`;
|
|
31
|
+
}
|
|
32
|
+
export class DuplicateActionDetector {
|
|
33
|
+
abortAfterTotalDuplicates;
|
|
34
|
+
seen = new Map(); // "thought|||tool::input" -> iteration numbers where it occurred
|
|
35
|
+
totalDuplicates = 0;
|
|
36
|
+
/**
|
|
37
|
+
* @param abortAfterTotalDuplicates total duplicate incidents (not
|
|
38
|
+
* necessarily of the same action — any repeats, summed) across the
|
|
39
|
+
* whole attempt before it's treated as a stuck loop. 5 is deliberately
|
|
40
|
+
* generous: a couple of legitimate re-checks shouldn't trip this, but
|
|
41
|
+
* the 11-repeat pattern that motivated this class would trip it early
|
|
42
|
+
* instead of running to the full 25-iteration cap.
|
|
43
|
+
*/
|
|
44
|
+
constructor(abortAfterTotalDuplicates = 5) {
|
|
45
|
+
this.abortAfterTotalDuplicates = abortAfterTotalDuplicates;
|
|
46
|
+
}
|
|
47
|
+
check(thought, tool, input, iteration) {
|
|
48
|
+
const key = `${normalizeThought(thought)}|||${actionKey(tool, input)}`;
|
|
49
|
+
const prior = this.seen.get(key) ?? [];
|
|
50
|
+
const isDuplicate = prior.length > 0;
|
|
51
|
+
if (isDuplicate)
|
|
52
|
+
this.totalDuplicates++;
|
|
53
|
+
this.seen.set(key, [...prior, iteration]);
|
|
54
|
+
const stuck = this.totalDuplicates >= this.abortAfterTotalDuplicates;
|
|
55
|
+
const warning = isDuplicate
|
|
56
|
+
? `duplicate detected: this exact reasoning + action ("${tool}") was already tried at iteration ${prior.at(-1)}` +
|
|
57
|
+
`${prior.length > 1 ? ` (and ${prior.length - 1} time(s) before that)` : ""} — it produced no new information ` +
|
|
58
|
+
`last time. Try a genuinely different approach instead of repeating it.`
|
|
59
|
+
: null;
|
|
60
|
+
return { isDuplicate, priorIterations: prior, stuck, warning };
|
|
61
|
+
}
|
|
62
|
+
get duplicateCount() {
|
|
63
|
+
return this.totalDuplicates;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface GenesisOrchestratorOptions {
|
|
3
|
+
/** One or more skill labels injected into the system prompt. */
|
|
4
|
+
skills?: string[];
|
|
5
|
+
/** Agent identity string — used as `agentName` in the prompt. */
|
|
6
|
+
agentName?: string;
|
|
7
|
+
/** The high-level directive / role description block. */
|
|
8
|
+
directive?: string;
|
|
9
|
+
/** LLM client configuration (unchanged semantics). */
|
|
10
|
+
llmOptions?: {
|
|
11
|
+
model?: string;
|
|
12
|
+
maxTokens?: number;
|
|
13
|
+
};
|
|
14
|
+
/** If true, enable record_lesson tool and inject .xcoder/lesson.md context. */
|
|
15
|
+
lessonLearned?: boolean;
|
|
16
|
+
/** Pre-loaded lesson content (avoids re-reading .xcoder/lesson.md). */
|
|
17
|
+
lessonContext?: string;
|
|
18
|
+
}
|
|
19
|
+
export type OrchestratorState = 'IDLE' | 'THINKING' | 'EXECUTING_TOOL' | 'PAUSED' | 'COMPLETED' | 'FAILED';
|
|
20
|
+
export declare class GenesisReActOrchestrator extends EventEmitter {
|
|
21
|
+
private llm;
|
|
22
|
+
private opts;
|
|
23
|
+
private state;
|
|
24
|
+
private transcript;
|
|
25
|
+
private workspaceRoot;
|
|
26
|
+
private currentAbortController;
|
|
27
|
+
private interruptPending;
|
|
28
|
+
private cachedSystemPrompt?;
|
|
29
|
+
constructor(opts?: GenesisOrchestratorOptions);
|
|
30
|
+
getState(): OrchestratorState;
|
|
31
|
+
/**
|
|
32
|
+
* Triggers a non-blocking interrupt request. Aborts running operations immediately.
|
|
33
|
+
*/
|
|
34
|
+
triggerInterrupt(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Injects manual user steering into the transcript and resumes execution.
|
|
37
|
+
*/
|
|
38
|
+
injectUserInput(userInput: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Builds the system prompt once, on first run call. Uses shared
|
|
41
|
+
* infrastructure: workspace index, project detection, environment info,
|
|
42
|
+
* tool manifest, and optionally external skills.
|
|
43
|
+
*/
|
|
44
|
+
private buildSystemPrompt;
|
|
45
|
+
/**
|
|
46
|
+
* Runs the ReAct Orchestration Loop
|
|
47
|
+
*/
|
|
48
|
+
run(initialTask: string): Promise<string>;
|
|
49
|
+
private performReasoningStep;
|
|
50
|
+
private handleInterruptPause;
|
|
51
|
+
private setState;
|
|
52
|
+
}
|
|
53
|
+
export declare class XcoderCLIController {
|
|
54
|
+
private orchestrator;
|
|
55
|
+
constructor(orchestrator: GenesisReActOrchestrator);
|
|
56
|
+
private setupEvents;
|
|
57
|
+
private setupKeypressHandler;
|
|
58
|
+
private disableRawMode;
|
|
59
|
+
private promptForInput;
|
|
60
|
+
start(task: string): Promise<void>;
|
|
61
|
+
}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
// xcoder:version 2 | xcoder:task task-c49600 | xcoder:updated 2026-08-13T13:52:23.536Z | xcoder:subtask code-st-6d79ef
|
|
2
|
+
import * as readline from 'readline';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import { createLlmClient } from "../llm/factory.js";
|
|
5
|
+
import { buildAgentSystemPrompt, parseReactMessage } from "../protocol/react-contract.js";
|
|
6
|
+
import { buildToolManifest, dispatchTool } from "../tools/tool-registry.js";
|
|
7
|
+
import { getOrBuildIndex } from "../tools/workspace-index.js";
|
|
8
|
+
import { detectProjectCommands } from "../tools/project-detect.js";
|
|
9
|
+
import { getEnvironmentInfo } from "../util/env-info.js";
|
|
10
|
+
import { isExternalSkillsEnabled, getExternalSkills } from "../skills/externalSkillLoader.js";
|
|
11
|
+
import { confirmInterrupt } from "../util/confirm-interrupt.js";
|
|
12
|
+
import { FooterManager } from "../util/footer-manager.js";
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// ReAct Orchestrator Engine using LlmClient
|
|
15
|
+
// ============================================================================
|
|
16
|
+
export class GenesisReActOrchestrator extends EventEmitter {
|
|
17
|
+
llm;
|
|
18
|
+
opts;
|
|
19
|
+
state = 'IDLE';
|
|
20
|
+
transcript = [];
|
|
21
|
+
workspaceRoot;
|
|
22
|
+
currentAbortController = null;
|
|
23
|
+
interruptPending = false;
|
|
24
|
+
cachedSystemPrompt;
|
|
25
|
+
constructor(opts = {}) {
|
|
26
|
+
super();
|
|
27
|
+
this.opts = {
|
|
28
|
+
skills: [],
|
|
29
|
+
agentName: 'repl-agent',
|
|
30
|
+
directive: '',
|
|
31
|
+
lessonLearned: false,
|
|
32
|
+
...opts,
|
|
33
|
+
llmOptions: opts.llmOptions ?? {},
|
|
34
|
+
};
|
|
35
|
+
this.llm = createLlmClient("orchestrator", this.opts.llmOptions);
|
|
36
|
+
this.workspaceRoot = process.cwd();
|
|
37
|
+
}
|
|
38
|
+
getState() {
|
|
39
|
+
return this.state;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Triggers a non-blocking interrupt request. Aborts running operations immediately.
|
|
43
|
+
*/
|
|
44
|
+
triggerInterrupt() {
|
|
45
|
+
if (this.state === 'IDLE' || this.state === 'COMPLETED' || this.state === 'PAUSED') {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.interruptPending = true;
|
|
49
|
+
this.emit('interrupt:requested');
|
|
50
|
+
if (this.currentAbortController) {
|
|
51
|
+
this.currentAbortController.abort();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Injects manual user steering into the transcript and resumes execution.
|
|
56
|
+
*/
|
|
57
|
+
injectUserInput(userInput) {
|
|
58
|
+
this.transcript.push({
|
|
59
|
+
role: 'user',
|
|
60
|
+
content: `[USER MANUAL INTERRUPT]: The user paused execution and provided this guidance: "${userInput}". Adjust your strategy accordingly.`,
|
|
61
|
+
});
|
|
62
|
+
this.interruptPending = false;
|
|
63
|
+
this.emit('input:injected', userInput);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds the system prompt once, on first run call. Uses shared
|
|
67
|
+
* infrastructure: workspace index, project detection, environment info,
|
|
68
|
+
* tool manifest, and optionally external skills.
|
|
69
|
+
*/
|
|
70
|
+
async buildSystemPrompt() {
|
|
71
|
+
if (this.cachedSystemPrompt)
|
|
72
|
+
return this.cachedSystemPrompt;
|
|
73
|
+
const index = await getOrBuildIndex(this.workspaceRoot);
|
|
74
|
+
const detectedCommands = await detectProjectCommands(this.workspaceRoot, index);
|
|
75
|
+
const environment = getEnvironmentInfo();
|
|
76
|
+
let skills = this.opts.skills ?? [];
|
|
77
|
+
if (isExternalSkillsEnabled()) {
|
|
78
|
+
skills = [...skills, ...getExternalSkills()];
|
|
79
|
+
}
|
|
80
|
+
this.cachedSystemPrompt = buildAgentSystemPrompt({
|
|
81
|
+
agentName: this.opts.agentName ?? 'repl-agent',
|
|
82
|
+
roleDescription: this.opts.directive ?? '',
|
|
83
|
+
directive: this.opts.directive ?? '',
|
|
84
|
+
skills,
|
|
85
|
+
tools: buildToolManifest({ lessonLearned: this.opts.lessonLearned ?? false }),
|
|
86
|
+
environment,
|
|
87
|
+
detectedCommands,
|
|
88
|
+
goal: '(ad-hoc interactive task)',
|
|
89
|
+
lessonContext: this.opts.lessonContext,
|
|
90
|
+
isStandalone: true,
|
|
91
|
+
});
|
|
92
|
+
return this.cachedSystemPrompt;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Runs the ReAct Orchestration Loop
|
|
96
|
+
*/
|
|
97
|
+
async run(initialTask) {
|
|
98
|
+
// Build system prompt before entering the loop.
|
|
99
|
+
try {
|
|
100
|
+
await this.buildSystemPrompt();
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
this.setState('FAILED');
|
|
104
|
+
throw new Error(`Failed to build system prompt: ${err.message}`);
|
|
105
|
+
}
|
|
106
|
+
this.transcript.push({ role: 'user', content: initialTask });
|
|
107
|
+
while (this.state !== 'COMPLETED' && this.state !== 'FAILED') {
|
|
108
|
+
// 1. Check for manual interrupt
|
|
109
|
+
if (this.interruptPending) {
|
|
110
|
+
await this.handleInterruptPause();
|
|
111
|
+
}
|
|
112
|
+
// 2. THINKING PHASE (LLM Completion Call)
|
|
113
|
+
this.setState('THINKING');
|
|
114
|
+
this.currentAbortController = new AbortController();
|
|
115
|
+
let step;
|
|
116
|
+
try {
|
|
117
|
+
step = await this.performReasoningStep(this.currentAbortController.signal);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
if (err.name === 'AbortError' || this.interruptPending) {
|
|
121
|
+
await this.handleInterruptPause();
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
this.setState('FAILED');
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
this.currentAbortController = null;
|
|
129
|
+
}
|
|
130
|
+
this.emit('thought', step.thought);
|
|
131
|
+
if (step.final_answer) {
|
|
132
|
+
this.setState('COMPLETED');
|
|
133
|
+
this.transcript.push({ role: 'assistant', content: step.final_answer.summary });
|
|
134
|
+
return step.final_answer.summary;
|
|
135
|
+
}
|
|
136
|
+
// 3. EXECUTING TOOL PHASE
|
|
137
|
+
if (step.action) {
|
|
138
|
+
const toolName = step.action.tool;
|
|
139
|
+
const toolInput = step.action.input;
|
|
140
|
+
// Append Assistant's intended action to transcript
|
|
141
|
+
this.transcript.push({
|
|
142
|
+
role: 'assistant',
|
|
143
|
+
content: `Thought: ${step.thought}\nAction: ${JSON.stringify(step.action)}`,
|
|
144
|
+
});
|
|
145
|
+
this.setState('EXECUTING_TOOL');
|
|
146
|
+
this.emit('action:start', step.action);
|
|
147
|
+
this.currentAbortController = new AbortController();
|
|
148
|
+
let observation;
|
|
149
|
+
try {
|
|
150
|
+
const result = await Promise.race([
|
|
151
|
+
dispatchTool(this.workspaceRoot, toolName, toolInput),
|
|
152
|
+
new Promise((_, reject) => {
|
|
153
|
+
this.currentAbortController.signal.addEventListener('abort', () => {
|
|
154
|
+
reject(new DOMException('Tool execution cancelled by user.', 'AbortError'));
|
|
155
|
+
});
|
|
156
|
+
}),
|
|
157
|
+
]);
|
|
158
|
+
observation = result.ok
|
|
159
|
+
? JSON.stringify(result.output)
|
|
160
|
+
: `Tool Error: ${typeof result.output === 'object' ? result.output?.error ?? 'unknown' : result.output}`;
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
if (err.name === 'AbortError' || this.interruptPending) {
|
|
164
|
+
await this.handleInterruptPause();
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
observation = `Tool Error: ${err.message}`;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
this.currentAbortController = null;
|
|
171
|
+
}
|
|
172
|
+
this.emit('action:end', toolName, observation);
|
|
173
|
+
// Append tool result as observation for the LLM's next turn
|
|
174
|
+
this.transcript.push({
|
|
175
|
+
role: 'user',
|
|
176
|
+
content: `Observation: ${observation}`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw new Error('ReAct orchestration loop terminated unexpectedly.');
|
|
181
|
+
}
|
|
182
|
+
async performReasoningStep(signal) {
|
|
183
|
+
const completionPromise = this.llm.complete(this.cachedSystemPrompt, this.transcript);
|
|
184
|
+
const completion = await Promise.race([
|
|
185
|
+
completionPromise,
|
|
186
|
+
new Promise((_, reject) => {
|
|
187
|
+
signal.addEventListener('abort', () => {
|
|
188
|
+
reject(new DOMException('LLM completion aborted by user interrupt.', 'AbortError'));
|
|
189
|
+
});
|
|
190
|
+
}),
|
|
191
|
+
]);
|
|
192
|
+
const parsed = parseReactMessage(completion.text);
|
|
193
|
+
if (!parsed.ok) {
|
|
194
|
+
this.transcript.push({
|
|
195
|
+
role: 'user',
|
|
196
|
+
content: `protocol_error: ${parsed.error}`,
|
|
197
|
+
});
|
|
198
|
+
return { thought: parsed.error, action: null, final_answer: null };
|
|
199
|
+
}
|
|
200
|
+
return parsed.message;
|
|
201
|
+
}
|
|
202
|
+
async handleInterruptPause() {
|
|
203
|
+
this.setState('PAUSED');
|
|
204
|
+
this.emit('paused');
|
|
205
|
+
await new Promise((resolve) => {
|
|
206
|
+
const onInjected = () => {
|
|
207
|
+
this.removeListener('input:injected', onInjected);
|
|
208
|
+
resolve();
|
|
209
|
+
};
|
|
210
|
+
this.on('input:injected', onInjected);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
setState(newState) {
|
|
214
|
+
this.state = newState;
|
|
215
|
+
this.emit('state:change', newState);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// ============================================================================
|
|
219
|
+
// Interactive CLI Controller
|
|
220
|
+
// ============================================================================
|
|
221
|
+
export class XcoderCLIController {
|
|
222
|
+
orchestrator;
|
|
223
|
+
constructor(orchestrator) {
|
|
224
|
+
this.orchestrator = orchestrator;
|
|
225
|
+
this.setupEvents();
|
|
226
|
+
}
|
|
227
|
+
setupEvents() {
|
|
228
|
+
this.orchestrator.on('thought', (thought) => {
|
|
229
|
+
console.log(`\n\x1b[35m[Thought]:\x1b[0m ${thought}`);
|
|
230
|
+
});
|
|
231
|
+
this.orchestrator.on('action:start', (action) => {
|
|
232
|
+
console.log(`\x1b[33m[Action]:\x1b[0m Running ${action.tool} with args: ${JSON.stringify(action.input)}`);
|
|
233
|
+
});
|
|
234
|
+
this.orchestrator.on('action:end', (_name, observation) => {
|
|
235
|
+
console.log(`\x1b[34m[Observation]:\x1b[0m ${observation}`);
|
|
236
|
+
});
|
|
237
|
+
this.orchestrator.on('interrupt:requested', () => {
|
|
238
|
+
console.log('\n\x1b[31m[!] Interrupt received. Halting operation...\x1b[0m');
|
|
239
|
+
});
|
|
240
|
+
this.orchestrator.on('paused', async () => {
|
|
241
|
+
await this.promptForInput();
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
setupKeypressHandler() {
|
|
245
|
+
// Non-TTY environments (piped stdin, CI, Docker, SEA binary) cannot
|
|
246
|
+
// support raw-mode keypress listeners. Return a no-op cleanup.
|
|
247
|
+
if (!process.stdin.isTTY) {
|
|
248
|
+
return () => { };
|
|
249
|
+
}
|
|
250
|
+
readline.emitKeypressEvents(process.stdin);
|
|
251
|
+
process.stdin.setRawMode(true);
|
|
252
|
+
const onKeypress = async (_str, key) => {
|
|
253
|
+
if (key.ctrl && key.name === 'c') {
|
|
254
|
+
this.disableRawMode();
|
|
255
|
+
console.log('\nProcess terminated.');
|
|
256
|
+
process.exit(0);
|
|
257
|
+
}
|
|
258
|
+
if (this.orchestrator.getState() !== 'PAUSED' &&
|
|
259
|
+
this.orchestrator.getState() !== 'COMPLETED' &&
|
|
260
|
+
(key.name === 'i' || key.name === 'return')) {
|
|
261
|
+
try {
|
|
262
|
+
// Disable raw mode so confirmInterrupt can read cooked input.
|
|
263
|
+
this.disableRawMode();
|
|
264
|
+
FooterManager.instance()?.hide();
|
|
265
|
+
const confirmed = await confirmInterrupt();
|
|
266
|
+
FooterManager.instance()?.show();
|
|
267
|
+
if (confirmed) {
|
|
268
|
+
this.orchestrator.triggerInterrupt();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
// If the confirmation prompt itself fails, default to not interrupting.
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
// Re-enable raw mode for subsequent keypresses.
|
|
276
|
+
if (process.stdin.isTTY) {
|
|
277
|
+
process.stdin.setRawMode(true);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
process.stdin.on('keypress', onKeypress);
|
|
283
|
+
return () => {
|
|
284
|
+
process.stdin.removeListener('keypress', onKeypress);
|
|
285
|
+
this.disableRawMode();
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
disableRawMode() {
|
|
289
|
+
if (process.stdin.isTTY) {
|
|
290
|
+
process.stdin.setRawMode(false);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async promptForInput() {
|
|
294
|
+
this.disableRawMode();
|
|
295
|
+
const rl = readline.createInterface({
|
|
296
|
+
input: process.stdin,
|
|
297
|
+
output: process.stdout,
|
|
298
|
+
});
|
|
299
|
+
return new Promise((resolve) => {
|
|
300
|
+
rl.question('\n\x1b[36m[XCODER INTERRUPT] Enter steering instructions:\x1b[0m ', (answer) => {
|
|
301
|
+
rl.close();
|
|
302
|
+
if (process.stdin.isTTY) {
|
|
303
|
+
process.stdin.setRawMode(true);
|
|
304
|
+
}
|
|
305
|
+
this.orchestrator.injectUserInput(answer.trim());
|
|
306
|
+
resolve();
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
async start(task) {
|
|
311
|
+
const cleanupKeyboard = this.setupKeypressHandler();
|
|
312
|
+
console.log(`\x1b[32m=== Xcoder SDLC Agent Orchestration Active ===\x1b[0m`);
|
|
313
|
+
console.log(`\x1b[90mPress \x1b[33m'i'\x1b[90m or \x1b[33m[Enter]\x1b[90m at any time to interrupt and send input.\x1b[0m\n`);
|
|
314
|
+
try {
|
|
315
|
+
const result = await this.orchestrator.run(task);
|
|
316
|
+
console.log(`\n\x1b[32m=== Result ===\x1b[0m\n${result}`);
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
console.error(`\n\x1b[31m[Orchestrator Execution Failed]:\x1b[0m`, err.message);
|
|
320
|
+
}
|
|
321
|
+
finally {
|
|
322
|
+
cleanupKeyboard();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// ============================================================================
|
|
327
|
+
// Execution Example
|
|
328
|
+
// ============================================================================
|
|
329
|
+
async function main() {
|
|
330
|
+
const orchestrator = new GenesisReActOrchestrator({
|
|
331
|
+
agentName: 'repl-agent',
|
|
332
|
+
directive: 'You are the Xcoder SDLC ReAct Agent. Follow the response contract exactly.',
|
|
333
|
+
skills: [
|
|
334
|
+
'Interactive problem-solving',
|
|
335
|
+
'Tool-based exploration and execution',
|
|
336
|
+
],
|
|
337
|
+
});
|
|
338
|
+
const cli = new XcoderCLIController(orchestrator);
|
|
339
|
+
await cli.start('Analyze repository structure and find bugs.');
|
|
340
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { RaoStep, TokenUsage } from "../types.js";
|
|
2
|
+
import { LlmClient } from "../llm/client.js";
|
|
3
|
+
export interface SamuraiAgentOptions {
|
|
4
|
+
workspaceRoot: string;
|
|
5
|
+
llm: LlmClient;
|
|
6
|
+
maxIterations?: number;
|
|
7
|
+
model?: string;
|
|
8
|
+
/** Optional additional context injected into the system prompt (e.g. package.json contents). */
|
|
9
|
+
packageJsonContext?: string | null;
|
|
10
|
+
/** When true, writes protocol_error parse failures to protocol_error.log via logProtocolError(). Mirrors SubAgentOptions.protocolErrorLog. */
|
|
11
|
+
protocolErrorLog?: boolean;
|
|
12
|
+
/** When true, register record_lesson tool and inject lesson context. */
|
|
13
|
+
lessonLearned?: boolean;
|
|
14
|
+
/** Pre-loaded lesson content (avoid re-reading per run). */
|
|
15
|
+
lessonContext?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SamuraiResult {
|
|
18
|
+
summary: string;
|
|
19
|
+
deliverable: unknown;
|
|
20
|
+
filesTouched: string[];
|
|
21
|
+
raoTrace: RaoStep[];
|
|
22
|
+
tokenUsage: TokenUsage;
|
|
23
|
+
iterations: number;
|
|
24
|
+
crashed?: boolean;
|
|
25
|
+
stuckLoop?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A standalone single-agent ReAct loop. Loads all registered tools, runs a
|
|
29
|
+
* conversation loop against the LLM, dispatches tool calls through the shared
|
|
30
|
+
* tool registry, and returns a result (or keeps looping in chat mode).
|
|
31
|
+
* Not coupled to SubtaskNode, TaskSpec, or the orchestrator.
|
|
32
|
+
*/
|
|
33
|
+
export declare class SamuraiAgent {
|
|
34
|
+
private opts;
|
|
35
|
+
constructor(opts: SamuraiAgentOptions);
|
|
36
|
+
private buildPrompt;
|
|
37
|
+
private loop;
|
|
38
|
+
/**
|
|
39
|
+
* Run a single agent invocation for a given goal. Returns when the agent
|
|
40
|
+
* calls final_answer or exhausts iterations.
|
|
41
|
+
*/
|
|
42
|
+
runOnce(goal: string, opts?: {
|
|
43
|
+
onStep?: (step: RaoStep) => void;
|
|
44
|
+
onTokens?: (cumulative: TokenUsage) => void;
|
|
45
|
+
}): Promise<SamuraiResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Start an interactive REPL session. Reads lines from stdin, runs the agent
|
|
48
|
+
* loop per turn, and prints the result. The system prompt is built once
|
|
49
|
+
* and reused across turns; the transcript accumulates the full conversation
|
|
50
|
+
* (not cleared between user lines).
|
|
51
|
+
*/
|
|
52
|
+
runChat(onChunk?: (text: string) => void): Promise<void>;
|
|
53
|
+
}
|