hyacinth-ai 0.9.6
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 +205 -0
- package/commands.json +25 -0
- package/dist/agents/builtins.d.ts +8 -0
- package/dist/agents/builtins.js +50 -0
- package/dist/agents/config-loader.d.ts +15 -0
- package/dist/agents/config-loader.js +75 -0
- package/dist/agents/delegate-tool.d.ts +109 -0
- package/dist/agents/delegate-tool.js +407 -0
- package/dist/agents/index.d.ts +5 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/registry.d.ts +2 -0
- package/dist/agents/registry.js +2 -0
- package/dist/bypass/agents/companion/index.d.ts +57 -0
- package/dist/bypass/agents/companion/index.js +487 -0
- package/dist/bypass/agents/orchestrator/index.d.ts +17 -0
- package/dist/bypass/agents/orchestrator/index.js +414 -0
- package/dist/bypass/agents/orchestrator.d.ts +16 -0
- package/dist/bypass/agents/orchestrator.js +377 -0
- package/dist/bypass/agents/world-engine/agent.d.ts +41 -0
- package/dist/bypass/agents/world-engine/agent.js +385 -0
- package/dist/bypass/agents/world-engine/index.d.ts +52 -0
- package/dist/bypass/agents/world-engine/index.js +198 -0
- package/dist/bypass/agents/world-engine/sim.d.ts +14 -0
- package/dist/bypass/agents/world-engine/sim.js +120 -0
- package/dist/bypass/agents/world-engine/store.d.ts +110 -0
- package/dist/bypass/agents/world-engine/store.js +519 -0
- package/dist/bypass/agents/world-engine/ticker.d.ts +37 -0
- package/dist/bypass/agents/world-engine/ticker.js +214 -0
- package/dist/bypass/agents/world-engine/tools.d.ts +6 -0
- package/dist/bypass/agents/world-engine/tools.js +380 -0
- package/dist/bypass/agents/world-engine/types.d.ts +202 -0
- package/dist/bypass/agents/world-engine/types.js +56 -0
- package/dist/bypass/agents/world-engine.d.ts +20 -0
- package/dist/bypass/agents/world-engine.js +63 -0
- package/dist/bypass/base.d.ts +48 -0
- package/dist/bypass/base.js +126 -0
- package/dist/bypass/index.d.ts +5 -0
- package/dist/bypass/index.js +6 -0
- package/dist/bypass/manager.d.ts +41 -0
- package/dist/bypass/manager.js +179 -0
- package/dist/bypass/types.d.ts +63 -0
- package/dist/bypass/types.js +14 -0
- package/dist/channels/auto-detect.d.ts +25 -0
- package/dist/channels/auto-detect.js +77 -0
- package/dist/channels/builtin/http-webhook.d.ts +25 -0
- package/dist/channels/builtin/http-webhook.js +287 -0
- package/dist/channels/builtin/tui-channel.d.ts +33 -0
- package/dist/channels/builtin/tui-channel.js +61 -0
- package/dist/channels/builtin/tui-ws-session.d.ts +16 -0
- package/dist/channels/builtin/tui-ws-session.js +90 -0
- package/dist/channels/builtin/webui-output-handler.d.ts +30 -0
- package/dist/channels/builtin/webui-output-handler.js +93 -0
- package/dist/channels/index.d.ts +5 -0
- package/dist/channels/index.js +3 -0
- package/dist/channels/interface.d.ts +148 -0
- package/dist/channels/interface.js +15 -0
- package/dist/channels/manager.d.ts +43 -0
- package/dist/channels/manager.js +156 -0
- package/dist/channels/message-queue.d.ts +36 -0
- package/dist/channels/message-queue.js +91 -0
- package/dist/channels/plugins/clawbot/clawbot-auth.d.ts +50 -0
- package/dist/channels/plugins/clawbot/clawbot-auth.js +235 -0
- package/dist/channels/plugins/clawbot/clawbot-channel.d.ts +76 -0
- package/dist/channels/plugins/clawbot/clawbot-channel.js +566 -0
- package/dist/channels/plugins/clawbot/clawbot-client.d.ts +180 -0
- package/dist/channels/plugins/clawbot/clawbot-client.js +312 -0
- package/dist/channels/plugins/clawbot/clawbot-config.d.ts +30 -0
- package/dist/channels/plugins/clawbot/clawbot-config.js +28 -0
- package/dist/channels/plugins/clawbot/clawbot-message-queue.d.ts +27 -0
- package/dist/channels/plugins/clawbot/clawbot-message-queue.js +114 -0
- package/dist/channels/plugins/clawbot/clawbot-session.d.ts +10 -0
- package/dist/channels/plugins/clawbot/clawbot-session.js +26 -0
- package/dist/channels/plugins/clawbot/index.d.ts +17 -0
- package/dist/channels/plugins/clawbot/index.js +58 -0
- package/dist/channels/plugins/feishu/feishu-channel.d.ts +57 -0
- package/dist/channels/plugins/feishu/feishu-channel.js +602 -0
- package/dist/channels/plugins/feishu/feishu-client.d.ts +23 -0
- package/dist/channels/plugins/feishu/feishu-client.js +86 -0
- package/dist/channels/plugins/feishu/feishu-config.d.ts +53 -0
- package/dist/channels/plugins/feishu/feishu-config.js +35 -0
- package/dist/channels/plugins/feishu/feishu-event.d.ts +102 -0
- package/dist/channels/plugins/feishu/feishu-event.js +257 -0
- package/dist/channels/plugins/feishu/feishu-log-suppressor.d.ts +7 -0
- package/dist/channels/plugins/feishu/feishu-log-suppressor.js +34 -0
- package/dist/channels/plugins/feishu/feishu-message-queue.d.ts +27 -0
- package/dist/channels/plugins/feishu/feishu-message-queue.js +112 -0
- package/dist/channels/plugins/feishu/feishu-send.d.ts +44 -0
- package/dist/channels/plugins/feishu/feishu-send.js +232 -0
- package/dist/channels/plugins/feishu/feishu-session.d.ts +44 -0
- package/dist/channels/plugins/feishu/feishu-session.js +84 -0
- package/dist/channels/plugins/feishu/feishu-streaming.d.ts +49 -0
- package/dist/channels/plugins/feishu/feishu-streaming.js +185 -0
- package/dist/channels/plugins/feishu/feishu-transport.d.ts +29 -0
- package/dist/channels/plugins/feishu/feishu-transport.js +99 -0
- package/dist/channels/plugins/feishu/index.d.ts +22 -0
- package/dist/channels/plugins/feishu/index.js +68 -0
- package/dist/cli/doctor.d.ts +20 -0
- package/dist/cli/doctor.js +317 -0
- package/dist/context/cache-strategy.d.ts +76 -0
- package/dist/context/cache-strategy.js +123 -0
- package/dist/context/composer.d.ts +77 -0
- package/dist/context/composer.js +318 -0
- package/dist/context/compressor.d.ts +218 -0
- package/dist/context/compressor.js +909 -0
- package/dist/context/index.d.ts +14 -0
- package/dist/context/index.js +8 -0
- package/dist/context/interface.d.ts +33 -0
- package/dist/context/interface.js +2 -0
- package/dist/context/manifest-defaults.d.ts +51 -0
- package/dist/context/manifest-defaults.js +133 -0
- package/dist/context/manifest-loader.d.ts +16 -0
- package/dist/context/manifest-loader.js +103 -0
- package/dist/context/manifest-types.d.ts +26 -0
- package/dist/context/manifest-types.js +2 -0
- package/dist/context/precision/analyzer.d.ts +31 -0
- package/dist/context/precision/analyzer.js +131 -0
- package/dist/context/precision/companion.d.ts +27 -0
- package/dist/context/precision/companion.js +144 -0
- package/dist/context/precision/default.d.ts +14 -0
- package/dist/context/precision/default.js +17 -0
- package/dist/context/precision/index.d.ts +9 -0
- package/dist/context/precision/index.js +7 -0
- package/dist/context/precision/keyword-pool.d.ts +27 -0
- package/dist/context/precision/keyword-pool.js +66 -0
- package/dist/context/precision/strategy.d.ts +18 -0
- package/dist/context/precision/strategy.js +51 -0
- package/dist/context/precision/summary-store.d.ts +18 -0
- package/dist/context/precision/summary-store.js +67 -0
- package/dist/context/precision/types.d.ts +23 -0
- package/dist/context/precision/types.js +2 -0
- package/dist/context/profiles.d.ts +45 -0
- package/dist/context/profiles.js +92 -0
- package/dist/context/prompt-builder.d.ts +76 -0
- package/dist/context/prompt-builder.js +133 -0
- package/dist/context/retriever.d.ts +44 -0
- package/dist/context/retriever.js +203 -0
- package/dist/context/router.d.ts +122 -0
- package/dist/context/router.js +291 -0
- package/dist/context/section-resolver.d.ts +38 -0
- package/dist/context/section-resolver.js +398 -0
- package/dist/context/tokenizer.d.ts +23 -0
- package/dist/context/tokenizer.js +78 -0
- package/dist/dependency/analyzer.d.ts +33 -0
- package/dist/dependency/analyzer.js +242 -0
- package/dist/dependency/data-flow-tracker.d.ts +12 -0
- package/dist/dependency/data-flow-tracker.js +97 -0
- package/dist/dependency/function-parser.d.ts +34 -0
- package/dist/dependency/function-parser.js +295 -0
- package/dist/dependency/index.d.ts +14 -0
- package/dist/dependency/index.js +20 -0
- package/dist/dependency/parser.d.ts +10 -0
- package/dist/dependency/parser.js +93 -0
- package/dist/dependency/types.d.ts +57 -0
- package/dist/dependency/types.js +2 -0
- package/dist/env/env-collector.d.ts +45 -0
- package/dist/env/env-collector.js +221 -0
- package/dist/env/index.d.ts +3 -0
- package/dist/env/index.js +2 -0
- package/dist/event-store.d.ts +27 -0
- package/dist/event-store.js +71 -0
- package/dist/evolution/git-manager.d.ts +46 -0
- package/dist/evolution/git-manager.js +276 -0
- package/dist/evolution/index.d.ts +3 -0
- package/dist/evolution/index.js +2 -0
- package/dist/flow/bootstrap-flow.d.ts +19 -0
- package/dist/flow/bootstrap-flow.js +72 -0
- package/dist/flow/flow-registry.d.ts +12 -0
- package/dist/flow/flow-registry.js +74 -0
- package/dist/flow/flow-tools.d.ts +8 -0
- package/dist/flow/flow-tools.js +106 -0
- package/dist/flow/index.d.ts +6 -0
- package/dist/flow/index.js +8 -0
- package/dist/flow/todo-flow.d.ts +25 -0
- package/dist/flow/todo-flow.js +107 -0
- package/dist/flow/types.d.ts +78 -0
- package/dist/flow/types.js +12 -0
- package/dist/flows/bootstrap.d.ts +18 -0
- package/dist/flows/bootstrap.js +119 -0
- package/dist/flows/index.d.ts +6 -0
- package/dist/flows/index.js +11 -0
- package/dist/flows/todo.d.ts +26 -0
- package/dist/flows/todo.js +174 -0
- package/dist/flows/tools.d.ts +8 -0
- package/dist/flows/tools.js +119 -0
- package/dist/flows/types.d.ts +27 -0
- package/dist/flows/types.js +10 -0
- package/dist/gateway/cli.d.ts +5 -0
- package/dist/gateway/cli.js +1027 -0
- package/dist/gateway/factory.d.ts +80 -0
- package/dist/gateway/factory.js +832 -0
- package/dist/gateway/guardian.d.ts +8 -0
- package/dist/gateway/guardian.js +30 -0
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.js +3 -0
- package/dist/gateway/server.d.ts +17 -0
- package/dist/gateway/server.js +96 -0
- package/dist/gateway/tui.d.ts +16 -0
- package/dist/gateway/tui.js +3273 -0
- package/dist/hot-reload/agent-watcher.d.ts +24 -0
- package/dist/hot-reload/agent-watcher.js +175 -0
- package/dist/hot-reload/bundle-watcher.d.ts +12 -0
- package/dist/hot-reload/bundle-watcher.js +35 -0
- package/dist/hot-reload/channel-watcher.d.ts +19 -0
- package/dist/hot-reload/channel-watcher.js +54 -0
- package/dist/hot-reload/command-watcher.d.ts +14 -0
- package/dist/hot-reload/command-watcher.js +54 -0
- package/dist/hot-reload/config-watcher.d.ts +20 -0
- package/dist/hot-reload/config-watcher.js +58 -0
- package/dist/hot-reload/index.d.ts +12 -0
- package/dist/hot-reload/index.js +12 -0
- package/dist/hot-reload/manager.d.ts +58 -0
- package/dist/hot-reload/manager.js +243 -0
- package/dist/hot-reload/manifest-watcher.d.ts +9 -0
- package/dist/hot-reload/manifest-watcher.js +42 -0
- package/dist/hot-reload/mcp-watcher.d.ts +18 -0
- package/dist/hot-reload/mcp-watcher.js +64 -0
- package/dist/hot-reload/model-catalog-watcher.d.ts +18 -0
- package/dist/hot-reload/model-catalog-watcher.js +62 -0
- package/dist/hot-reload/plugin-watcher.d.ts +20 -0
- package/dist/hot-reload/plugin-watcher.js +56 -0
- package/dist/hot-reload/prompt-watcher.d.ts +6 -0
- package/dist/hot-reload/prompt-watcher.js +38 -0
- package/dist/hot-reload/provider-watcher.d.ts +16 -0
- package/dist/hot-reload/provider-watcher.js +45 -0
- package/dist/hot-reload/skill-watcher.d.ts +19 -0
- package/dist/hot-reload/skill-watcher.js +82 -0
- package/dist/hot-reload/tool-watcher.d.ts +16 -0
- package/dist/hot-reload/tool-watcher.js +168 -0
- package/dist/hot-reload/workflow-watcher.d.ts +19 -0
- package/dist/hot-reload/workflow-watcher.js +84 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/knowledge/fts5-retriever.d.ts +30 -0
- package/dist/knowledge/fts5-retriever.js +223 -0
- package/dist/knowledge/index.d.ts +11 -0
- package/dist/knowledge/index.js +14 -0
- package/dist/knowledge/indexer.d.ts +41 -0
- package/dist/knowledge/indexer.js +186 -0
- package/dist/knowledge/query-preprocessor.d.ts +13 -0
- package/dist/knowledge/query-preprocessor.js +63 -0
- package/dist/knowledge/retriever.d.ts +45 -0
- package/dist/knowledge/retriever.js +9 -0
- package/dist/knowledge/store.d.ts +27 -0
- package/dist/knowledge/store.js +61 -0
- package/dist/knowledge/structured-store.d.ts +78 -0
- package/dist/knowledge/structured-store.js +280 -0
- package/dist/knowledge/structured-tools.d.ts +12 -0
- package/dist/knowledge/structured-tools.js +151 -0
- package/dist/knowledge/tools.d.ts +20 -0
- package/dist/knowledge/tools.js +238 -0
- package/dist/knowledge/watcher.d.ts +28 -0
- package/dist/knowledge/watcher.js +113 -0
- package/dist/lifecycle/index.d.ts +12 -0
- package/dist/lifecycle/index.js +14 -0
- package/dist/lifecycle/interface.d.ts +94 -0
- package/dist/lifecycle/interface.js +2 -0
- package/dist/lifecycle/local-model.d.ts +62 -0
- package/dist/lifecycle/local-model.js +331 -0
- package/dist/lifecycle/manager.d.ts +70 -0
- package/dist/lifecycle/manager.js +374 -0
- package/dist/lifecycle/supervisor.d.ts +89 -0
- package/dist/lifecycle/supervisor.js +277 -0
- package/dist/lifecycle-integration-test.d.ts +2 -0
- package/dist/lifecycle-integration-test.js +72 -0
- package/dist/local-model/download-manager.d.ts +59 -0
- package/dist/local-model/download-manager.js +517 -0
- package/dist/local-model/index.d.ts +109 -0
- package/dist/local-model/index.js +233 -0
- package/dist/local-model/llamacpp-provider.d.ts +95 -0
- package/dist/local-model/llamacpp-provider.js +379 -0
- package/dist/local-model/model-bridge.d.ts +48 -0
- package/dist/local-model/model-bridge.js +256 -0
- package/dist/local-model/model-registry.d.ts +47 -0
- package/dist/local-model/model-registry.js +188 -0
- package/dist/local-model/types.d.ts +49 -0
- package/dist/local-model/types.js +2 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/logger.d.ts +56 -0
- package/dist/logging/logger.js +94 -0
- package/dist/machine/flows/bootstrap.d.ts +18 -0
- package/dist/machine/flows/bootstrap.js +119 -0
- package/dist/machine/flows/index.d.ts +6 -0
- package/dist/machine/flows/index.js +11 -0
- package/dist/machine/flows/spec.d.ts +17 -0
- package/dist/machine/flows/spec.js +176 -0
- package/dist/machine/flows/todo.d.ts +26 -0
- package/dist/machine/flows/todo.js +175 -0
- package/dist/machine/flows/tools.d.ts +8 -0
- package/dist/machine/flows/tools.js +119 -0
- package/dist/machine/flows/types.d.ts +33 -0
- package/dist/machine/flows/types.js +10 -0
- package/dist/machine/index.d.ts +8 -0
- package/dist/machine/index.js +9 -0
- package/dist/machine/registry.d.ts +34 -0
- package/dist/machine/registry.js +98 -0
- package/dist/machine/runner.d.ts +41 -0
- package/dist/machine/runner.js +177 -0
- package/dist/machine/types.d.ts +121 -0
- package/dist/machine/types.js +9 -0
- package/dist/mcp/bridge.d.ts +33 -0
- package/dist/mcp/bridge.js +99 -0
- package/dist/mcp/client.d.ts +37 -0
- package/dist/mcp/client.js +161 -0
- package/dist/mcp/config.d.ts +15 -0
- package/dist/mcp/config.js +85 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/install-manager.d.ts +31 -0
- package/dist/mcp/install-manager.js +158 -0
- package/dist/mcp/lifecycle.d.ts +41 -0
- package/dist/mcp/lifecycle.js +175 -0
- package/dist/mcp/process-transport.d.ts +21 -0
- package/dist/mcp/process-transport.js +59 -0
- package/dist/mcp/side-effect.d.ts +5 -0
- package/dist/mcp/side-effect.js +21 -0
- package/dist/mcp/system.d.ts +95 -0
- package/dist/mcp/system.js +279 -0
- package/dist/memory/companion-session.d.ts +22 -0
- package/dist/memory/companion-session.js +77 -0
- package/dist/memory/compression-boundary.d.ts +20 -0
- package/dist/memory/compression-boundary.js +40 -0
- package/dist/memory/conversation.d.ts +34 -0
- package/dist/memory/conversation.js +107 -0
- package/dist/memory/events.d.ts +42 -0
- package/dist/memory/events.js +56 -0
- package/dist/memory/index.d.ts +7 -0
- package/dist/memory/index.js +6 -0
- package/dist/memory/memory-store.d.ts +11 -0
- package/dist/memory/memory-store.js +51 -0
- package/dist/memory/session-allowlist.d.ts +11 -0
- package/dist/memory/session-allowlist.js +50 -0
- package/dist/memory/session.d.ts +48 -0
- package/dist/memory/session.js +275 -0
- package/dist/memory/stats.d.ts +23 -0
- package/dist/memory/stats.js +59 -0
- package/dist/memory/summary.d.ts +7 -0
- package/dist/memory/summary.js +23 -0
- package/dist/multimodal/index.d.ts +66 -0
- package/dist/multimodal/index.js +210 -0
- package/dist/orchestrator/index.d.ts +5 -0
- package/dist/orchestrator/index.js +4 -0
- package/dist/orchestrator/loop.d.ts +331 -0
- package/dist/orchestrator/loop.js +2443 -0
- package/dist/orchestrator/plan-store.d.ts +81 -0
- package/dist/orchestrator/plan-store.js +167 -0
- package/dist/orchestrator/planner.d.ts +20 -0
- package/dist/orchestrator/planner.js +34 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.js +2 -0
- package/dist/parser/router.d.ts +30 -0
- package/dist/parser/router.js +61 -0
- package/dist/plugins/api.d.ts +39 -0
- package/dist/plugins/api.js +85 -0
- package/dist/plugins/define.d.ts +27 -0
- package/dist/plugins/define.js +32 -0
- package/dist/plugins/index.d.ts +9 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/loader.d.ts +39 -0
- package/dist/plugins/loader.js +128 -0
- package/dist/plugins/manager.d.ts +61 -0
- package/dist/plugins/manager.js +257 -0
- package/dist/plugins/types.d.ts +82 -0
- package/dist/plugins/types.js +2 -0
- package/dist/prompts/agents/code-reviewer.md +16 -0
- package/dist/prompts/agents/security-auditor.md +17 -0
- package/dist/prompts/agents/test-writer.md +15 -0
- package/dist/prompts/attention/attention.md +12 -0
- package/dist/prompts/environment/environment.md +18 -0
- package/dist/prompts/environment/feishu.md +107 -0
- package/dist/prompts/flows/bootstrap-confirm.md +14 -0
- package/dist/prompts/flows/bootstrap-identity.md +11 -0
- package/dist/prompts/flows/bootstrap-soul.md +19 -0
- package/dist/prompts/flows/bootstrap-user.md +11 -0
- package/dist/prompts/flows/spec-checklist.md +27 -0
- package/dist/prompts/flows/spec-define.md +64 -0
- package/dist/prompts/flows/spec-executing-checklist.md +15 -0
- package/dist/prompts/flows/spec-executing-tasks.md +15 -0
- package/dist/prompts/flows/spec-spec.md +51 -0
- package/dist/prompts/flows/spec-tasks.md +32 -0
- package/dist/prompts/flows/todo-execution.md +7 -0
- package/dist/prompts/flows/todo-planning.md +18 -0
- package/dist/prompts/framework/architecture.md +131 -0
- package/dist/prompts/identity/identity.md +2 -0
- package/dist/prompts/loader.d.ts +24 -0
- package/dist/prompts/loader.js +102 -0
- package/dist/prompts/loader.ts +119 -0
- package/dist/prompts/orchestration/summary.md +14 -0
- package/dist/prompts/persona/BOOTSTRAP.md +5 -0
- package/dist/prompts/persona/IDENTITY.md +16 -0
- package/dist/prompts/persona/PartnerMemory.md +5 -0
- package/dist/prompts/persona/PartnerSoul.md +7 -0
- package/dist/prompts/persona/SOUL.md +30 -0
- package/dist/prompts/persona/USER.md +16 -0
- package/dist/prompts/precise/analyze.md +23 -0
- package/dist/prompts/precise/persona.md +18 -0
- package/dist/prompts/safety/coding-standards.md +5 -0
- package/dist/prompts/safety/safety.md +4 -0
- package/dist/prompts/skills/code-review.md +4 -0
- package/dist/prompts/skills/debug.md +7 -0
- package/dist/prompts/skills/framework-reference.md +131 -0
- package/dist/prompts/skills/refactor.md +6 -0
- package/dist/prompts/summary.md +22 -0
- package/dist/prompts/tools/framework-capabilities.md +241 -0
- package/dist/prompts/tools/tool-rules.md +15 -0
- package/dist/provider/anthropic.d.ts +62 -0
- package/dist/provider/anthropic.js +361 -0
- package/dist/provider/catalog.d.ts +58 -0
- package/dist/provider/catalog.js +97 -0
- package/dist/provider/compatible.d.ts +89 -0
- package/dist/provider/compatible.js +328 -0
- package/dist/provider/config.d.ts +23 -0
- package/dist/provider/config.js +158 -0
- package/dist/provider/deepseek.d.ts +25 -0
- package/dist/provider/deepseek.js +37 -0
- package/dist/provider/fallback.d.ts +51 -0
- package/dist/provider/fallback.js +113 -0
- package/dist/provider/gemini.d.ts +27 -0
- package/dist/provider/gemini.js +170 -0
- package/dist/provider/index.d.ts +36 -0
- package/dist/provider/index.js +42 -0
- package/dist/provider/interface.d.ts +62 -0
- package/dist/provider/interface.js +2 -0
- package/dist/provider/local-config.d.ts +37 -0
- package/dist/provider/local-config.js +146 -0
- package/dist/provider/local.d.ts +45 -0
- package/dist/provider/local.js +248 -0
- package/dist/provider/manager.d.ts +67 -0
- package/dist/provider/manager.js +355 -0
- package/dist/provider/mimo.d.ts +19 -0
- package/dist/provider/mimo.js +30 -0
- package/dist/provider/minimax.d.ts +22 -0
- package/dist/provider/minimax.js +33 -0
- package/dist/provider/model-catalog-loader.d.ts +42 -0
- package/dist/provider/model-catalog-loader.js +89 -0
- package/dist/provider/model-channel-registry.d.ts +130 -0
- package/dist/provider/model-channel-registry.js +488 -0
- package/dist/provider/model-router.d.ts +60 -0
- package/dist/provider/model-router.js +87 -0
- package/dist/provider/openai.d.ts +54 -0
- package/dist/provider/openai.js +274 -0
- package/dist/provider/qwen.d.ts +19 -0
- package/dist/provider/qwen.js +30 -0
- package/dist/provider/resilient.d.ts +46 -0
- package/dist/provider/resilient.js +181 -0
- package/dist/provider/retry.d.ts +16 -0
- package/dist/provider/retry.js +78 -0
- package/dist/provider/router.d.ts +68 -0
- package/dist/provider/router.js +145 -0
- package/dist/provider/tool-args-recovery.d.ts +36 -0
- package/dist/provider/tool-args-recovery.js +91 -0
- package/dist/provider/user-id.d.ts +13 -0
- package/dist/provider/user-id.js +53 -0
- package/dist/provider/zhipu.d.ts +19 -0
- package/dist/provider/zhipu.js +32 -0
- package/dist/registry/agent.registry.d.ts +57 -0
- package/dist/registry/agent.registry.js +224 -0
- package/dist/registry/base.d.ts +54 -0
- package/dist/registry/base.js +99 -0
- package/dist/registry/channel.registry.d.ts +53 -0
- package/dist/registry/channel.registry.js +87 -0
- package/dist/registry/index.d.ts +9 -0
- package/dist/registry/index.js +10 -0
- package/dist/registry/mcp.registry.d.ts +2 -0
- package/dist/registry/mcp.registry.js +2 -0
- package/dist/registry/plugin.registry.d.ts +33 -0
- package/dist/registry/plugin.registry.js +66 -0
- package/dist/registry/provider.registry.d.ts +51 -0
- package/dist/registry/provider.registry.js +104 -0
- package/dist/registry/skill.registry.d.ts +33 -0
- package/dist/registry/skill.registry.js +95 -0
- package/dist/registry/tool.registry.d.ts +68 -0
- package/dist/registry/tool.registry.js +185 -0
- package/dist/repair/loop-guard.d.ts +98 -0
- package/dist/repair/loop-guard.js +217 -0
- package/dist/repair/scavenge.d.ts +19 -0
- package/dist/repair/scavenge.js +81 -0
- package/dist/repair/storm.d.ts +7 -0
- package/dist/repair/storm.js +7 -0
- package/dist/rollback/index.d.ts +5 -0
- package/dist/rollback/index.js +4 -0
- package/dist/rollback/rollback-tool.d.ts +13 -0
- package/dist/rollback/rollback-tool.js +167 -0
- package/dist/rollback/turn-recorder.d.ts +37 -0
- package/dist/rollback/turn-recorder.js +183 -0
- package/dist/rollback/turn-store.d.ts +29 -0
- package/dist/rollback/turn-store.js +114 -0
- package/dist/rollback/types.d.ts +51 -0
- package/dist/rollback/types.js +9 -0
- package/dist/runtime/config-center.d.ts +92 -0
- package/dist/runtime/config-center.js +467 -0
- package/dist/runtime/config-schema.d.ts +201 -0
- package/dist/runtime/config-schema.js +2 -0
- package/dist/runtime/defaults.d.ts +3 -0
- package/dist/runtime/defaults.js +146 -0
- package/dist/schedule/cron.d.ts +24 -0
- package/dist/schedule/cron.js +145 -0
- package/dist/schedule/index.d.ts +6 -0
- package/dist/schedule/index.js +4 -0
- package/dist/schedule/persistence.d.ts +33 -0
- package/dist/schedule/persistence.js +106 -0
- package/dist/schedule/scheduler.d.ts +85 -0
- package/dist/schedule/scheduler.js +630 -0
- package/dist/schedule/types.d.ts +185 -0
- package/dist/schedule/types.js +2 -0
- package/dist/setup/config.d.ts +189 -0
- package/dist/setup/config.js +253 -0
- package/dist/setup/index.d.ts +3 -0
- package/dist/setup/index.js +3 -0
- package/dist/setup/model-defaults.d.ts +13 -0
- package/dist/setup/model-defaults.js +87 -0
- package/dist/setup/persona-bootstrap.d.ts +42 -0
- package/dist/setup/persona-bootstrap.js +379 -0
- package/dist/setup/wizard.d.ts +32 -0
- package/dist/setup/wizard.js +384 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.js +4 -0
- package/dist/skills/loader.d.ts +12 -0
- package/dist/skills/loader.js +83 -0
- package/dist/skills/registry.d.ts +2 -0
- package/dist/skills/registry.js +2 -0
- package/dist/skills/skill-tool.d.ts +20 -0
- package/dist/skills/skill-tool.js +49 -0
- package/dist/tools/archive.d.ts +17 -0
- package/dist/tools/archive.js +131 -0
- package/dist/tools/ask-user.d.ts +9 -0
- package/dist/tools/ask-user.js +62 -0
- package/dist/tools/background-registry.d.ts +45 -0
- package/dist/tools/background-registry.js +164 -0
- package/dist/tools/bash.d.ts +56 -0
- package/dist/tools/bash.js +391 -0
- package/dist/tools/bundle-registry.d.ts +42 -0
- package/dist/tools/bundle-registry.js +239 -0
- package/dist/tools/bundle-tools.d.ts +11 -0
- package/dist/tools/bundle-tools.js +168 -0
- package/dist/tools/channel-info.d.ts +5 -0
- package/dist/tools/channel-info.js +38 -0
- package/dist/tools/compression.d.ts +7 -0
- package/dist/tools/compression.js +21 -0
- package/dist/tools/config.d.ts +23 -0
- package/dist/tools/config.js +255 -0
- package/dist/tools/db-query.d.ts +12 -0
- package/dist/tools/db-query.js +107 -0
- package/dist/tools/diagnostics.d.ts +30 -0
- package/dist/tools/diagnostics.js +111 -0
- package/dist/tools/diff-channel.d.ts +9 -0
- package/dist/tools/diff-channel.js +17 -0
- package/dist/tools/diff-files.d.ts +17 -0
- package/dist/tools/diff-files.js +88 -0
- package/dist/tools/disk-usage.d.ts +34 -0
- package/dist/tools/disk-usage.js +258 -0
- package/dist/tools/edit.d.ts +30 -0
- package/dist/tools/edit.js +235 -0
- package/dist/tools/executor.d.ts +32 -0
- package/dist/tools/executor.js +66 -0
- package/dist/tools/file-tracker.d.ts +20 -0
- package/dist/tools/file-tracker.js +44 -0
- package/dist/tools/filtered-registry.d.ts +29 -0
- package/dist/tools/filtered-registry.js +50 -0
- package/dist/tools/flow.d.ts +10 -0
- package/dist/tools/flow.js +180 -0
- package/dist/tools/git-tool.d.ts +24 -0
- package/dist/tools/git-tool.js +113 -0
- package/dist/tools/glob.d.ts +29 -0
- package/dist/tools/glob.js +152 -0
- package/dist/tools/grep.d.ts +14 -0
- package/dist/tools/grep.js +325 -0
- package/dist/tools/http-request.d.ts +14 -0
- package/dist/tools/http-request.js +126 -0
- package/dist/tools/index.d.ts +43 -0
- package/dist/tools/index.js +76 -0
- package/dist/tools/injection-filter.d.ts +6 -0
- package/dist/tools/injection-filter.js +71 -0
- package/dist/tools/insert.d.ts +13 -0
- package/dist/tools/insert.js +61 -0
- package/dist/tools/interface.d.ts +30 -0
- package/dist/tools/interface.js +2 -0
- package/dist/tools/json-edit.d.ts +15 -0
- package/dist/tools/json-edit.js +122 -0
- package/dist/tools/multi-edit.d.ts +9 -0
- package/dist/tools/multi-edit.js +146 -0
- package/dist/tools/path-sandbox.d.ts +14 -0
- package/dist/tools/path-sandbox.js +60 -0
- package/dist/tools/process-tools.d.ts +15 -0
- package/dist/tools/process-tools.js +95 -0
- package/dist/tools/python-bridge/bridge.d.ts +24 -0
- package/dist/tools/python-bridge/bridge.js +39 -0
- package/dist/tools/python-bridge/executor.d.ts +6 -0
- package/dist/tools/python-bridge/executor.js +69 -0
- package/dist/tools/python-bridge/index.d.ts +5 -0
- package/dist/tools/python-bridge/index.js +4 -0
- package/dist/tools/python-bridge/parser.d.ts +21 -0
- package/dist/tools/python-bridge/parser.js +258 -0
- package/dist/tools/read.d.ts +16 -0
- package/dist/tools/read.js +276 -0
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +2 -0
- package/dist/tools/restart.d.ts +10 -0
- package/dist/tools/restart.js +46 -0
- package/dist/tools/result-buffer.d.ts +66 -0
- package/dist/tools/result-buffer.js +146 -0
- package/dist/tools/runtime-control.d.ts +163 -0
- package/dist/tools/runtime-control.js +1780 -0
- package/dist/tools/symbol-references.d.ts +5 -0
- package/dist/tools/symbol-references.js +331 -0
- package/dist/tools/system-info.d.ts +3 -0
- package/dist/tools/system-info.js +55 -0
- package/dist/tools/write.d.ts +18 -0
- package/dist/tools/write.js +118 -0
- package/dist/tools/xref/index.d.ts +25 -0
- package/dist/tools/xref/index.js +25 -0
- package/dist/tools/xref/manager.d.ts +85 -0
- package/dist/tools/xref/manager.js +948 -0
- package/dist/tools/xref/parser.d.ts +34 -0
- package/dist/tools/xref/parser.js +64 -0
- package/dist/tools/xref/regex-parser.d.ts +26 -0
- package/dist/tools/xref/regex-parser.js +446 -0
- package/dist/tools/xref/schema.d.ts +104 -0
- package/dist/tools/xref/schema.js +68 -0
- package/dist/tools/xref/ts-parser.d.ts +20 -0
- package/dist/tools/xref/ts-parser.js +403 -0
- package/dist/tools/xref/xref-build.d.ts +20 -0
- package/dist/tools/xref/xref-build.js +128 -0
- package/dist/tools/xref/xref-graph.d.ts +24 -0
- package/dist/tools/xref/xref-graph.js +88 -0
- package/dist/tools/xref/xref-query.d.ts +30 -0
- package/dist/tools/xref/xref-query.js +123 -0
- package/dist/types.d.ts +217 -0
- package/dist/types.js +2 -0
- package/dist/ui/assistant-message.d.ts +7 -0
- package/dist/ui/assistant-message.js +18 -0
- package/dist/ui/chat-log.d.ts +52 -0
- package/dist/ui/chat-log.js +246 -0
- package/dist/ui/command-registry.d.ts +73 -0
- package/dist/ui/command-registry.js +838 -0
- package/dist/ui/diff-component.d.ts +14 -0
- package/dist/ui/diff-component.js +42 -0
- package/dist/ui/hyperlink-markdown.d.ts +10 -0
- package/dist/ui/hyperlink-markdown.js +21 -0
- package/dist/ui/markdown-message.d.ts +10 -0
- package/dist/ui/markdown-message.js +16 -0
- package/dist/ui/osc8-hyperlinks.d.ts +4 -0
- package/dist/ui/osc8-hyperlinks.js +142 -0
- package/dist/ui/pi-tui-editor.d.ts +35 -0
- package/dist/ui/pi-tui-editor.js +79 -0
- package/dist/ui/slash-commands.d.ts +16 -0
- package/dist/ui/slash-commands.js +29 -0
- package/dist/ui/slash-panel.d.ts +54 -0
- package/dist/ui/slash-panel.js +199 -0
- package/dist/ui/theme.d.ts +120 -0
- package/dist/ui/theme.js +154 -0
- package/dist/ui/tool-display.d.ts +13 -0
- package/dist/ui/tool-display.js +85 -0
- package/dist/ui/tool-execution.d.ts +22 -0
- package/dist/ui/tool-execution.js +87 -0
- package/dist/ui/tui-formatters.d.ts +2 -0
- package/dist/ui/tui-formatters.js +145 -0
- package/dist/ui/user-message.d.ts +5 -0
- package/dist/ui/user-message.js +11 -0
- package/dist/update/check.d.ts +8 -0
- package/dist/update/check.js +28 -0
- package/dist/update/config.d.ts +6 -0
- package/dist/update/config.js +18 -0
- package/dist/update/download.d.ts +3 -0
- package/dist/update/download.js +27 -0
- package/dist/update/index.d.ts +6 -0
- package/dist/update/index.js +5 -0
- package/dist/update/install.d.ts +3 -0
- package/dist/update/install.js +33 -0
- package/dist/update/types.d.ts +16 -0
- package/dist/update/types.js +2 -0
- package/dist/utils/diff.d.ts +9 -0
- package/dist/utils/diff.js +45 -0
- package/dist/utils/misc.d.ts +12 -0
- package/dist/utils/misc.js +34 -0
- package/dist/world-engine/agent.d.ts +41 -0
- package/dist/world-engine/agent.js +385 -0
- package/dist/world-engine/index.d.ts +45 -0
- package/dist/world-engine/index.js +160 -0
- package/dist/world-engine/sim.d.ts +14 -0
- package/dist/world-engine/sim.js +120 -0
- package/dist/world-engine/store.d.ts +110 -0
- package/dist/world-engine/store.js +519 -0
- package/dist/world-engine/ticker.d.ts +37 -0
- package/dist/world-engine/ticker.js +214 -0
- package/dist/world-engine/tools.d.ts +6 -0
- package/dist/world-engine/tools.js +380 -0
- package/dist/world-engine/types.d.ts +202 -0
- package/dist/world-engine/types.js +56 -0
- package/docs/api.md +180 -0
- package/docs/architecture.md +206 -0
- package/docs/diagnostics/2026-06-08-config-prompt-guidance.md +67 -0
- package/docs/superpowers/plans/2026-06-08-global-bootstrap-mode.md +89 -0
- package/docs/superpowers/specs/2026-06-08-global-bootstrap-mode-design.md +174 -0
- package/docs/user-guide.md +226 -0
- package/package.json +63 -0
- package/plugins/example-greeter/index.js +55 -0
- package/plugins/example-greeter/plugin.json +8 -0
- package/pnpm-workspace.yaml +5 -0
- package/provider_arch.md +179 -0
- package/start-webui.sh +27 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/webui-channel-design.md +789 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { computeDiff } from '../utils/diff.js';
|
|
3
|
+
import { pushDiff } from './diff-channel.js';
|
|
4
|
+
import { getLastReadTime, recordFileWrite } from './file-tracker.js';
|
|
5
|
+
import { runDiagnostics } from './diagnostics.js';
|
|
6
|
+
import { autoReferenceCheck } from './symbol-references.js';
|
|
7
|
+
/**
|
|
8
|
+
* EditTool — 在文件中精确替换匹配的字符串 或 按行号替换
|
|
9
|
+
*
|
|
10
|
+
* 支持两种模式(互斥):
|
|
11
|
+
*
|
|
12
|
+
* 模式一:字符串替换(原有逻辑)
|
|
13
|
+
* - old_string (必需): 要被替换的字符串
|
|
14
|
+
* - new_string (必需): 替换后的字符串
|
|
15
|
+
* - replace_all (可选): 是否替换所有匹配,默认 false
|
|
16
|
+
*
|
|
17
|
+
* 模式二:行号替换(新增)
|
|
18
|
+
* - line_start (必需): 替换起始行号 (1-based)
|
|
19
|
+
* - line_count (可选): 替换行数,默认 1
|
|
20
|
+
* - new_string (必需): 替换后的内容
|
|
21
|
+
*/
|
|
22
|
+
export class EditTool {
|
|
23
|
+
name = 'edit';
|
|
24
|
+
description = 'Performs exact string replacements in a file (' +
|
|
25
|
+
'old_string must uniquely match unless replace_all=true), ' +
|
|
26
|
+
'or replaces lines by line number using line_start/line_count. ' +
|
|
27
|
+
'line_start and old_string are mutually exclusive.';
|
|
28
|
+
companionDescription = '得改一下了。';
|
|
29
|
+
inputSchema = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
file_path: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'The absolute path to the file to edit',
|
|
35
|
+
},
|
|
36
|
+
old_string: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'The text to replace (must match exactly). Mutually exclusive with line_start.',
|
|
39
|
+
},
|
|
40
|
+
new_string: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'The text to replace it with',
|
|
43
|
+
},
|
|
44
|
+
replace_all: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
description: 'Replace all occurrences of old_string. Defaults to false.',
|
|
47
|
+
},
|
|
48
|
+
line_start: {
|
|
49
|
+
type: 'number',
|
|
50
|
+
description: 'Starting line number for replacement (1-based). Mutually exclusive with old_string.',
|
|
51
|
+
},
|
|
52
|
+
line_count: {
|
|
53
|
+
type: 'number',
|
|
54
|
+
description: 'Number of lines to replace. Defaults to 1.',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['file_path', 'new_string'],
|
|
58
|
+
};
|
|
59
|
+
async execute(args) {
|
|
60
|
+
const filePath = args.file_path;
|
|
61
|
+
const newString = args.new_string;
|
|
62
|
+
const lineStart = args.line_start;
|
|
63
|
+
const oldString = args.old_string;
|
|
64
|
+
if (!filePath)
|
|
65
|
+
return '错误:缺少 file_path 参数。请提供文件的绝对路径。';
|
|
66
|
+
if (newString === undefined || newString === null)
|
|
67
|
+
return '错误:缺少 new_string 参数。请提供替换后的内容。';
|
|
68
|
+
if (lineStart === undefined && oldString === undefined)
|
|
69
|
+
return '错误:请提供 line_start(按行编辑)或 old_string(字符串替换)。';
|
|
70
|
+
if (lineStart !== undefined && lineStart < 1)
|
|
71
|
+
return '错误:line_start 必须 >= 1。';
|
|
72
|
+
if (lineStart !== undefined && oldString !== undefined) {
|
|
73
|
+
throw new Error('line_start and old_string are mutually exclusive. Use one mode or the other.');
|
|
74
|
+
}
|
|
75
|
+
// 拒绝编辑图片文件
|
|
76
|
+
const IMG_SIGS = [
|
|
77
|
+
[0xFF, 0xD8], // JPEG
|
|
78
|
+
[0x89, 0x50, 0x4E, 0x47], // PNG
|
|
79
|
+
[0x47, 0x49, 0x46], // GIF
|
|
80
|
+
[0x42, 0x4D], // BMP
|
|
81
|
+
[0x52, 0x49, 0x46, 0x46], // WEBP (RIFF)
|
|
82
|
+
];
|
|
83
|
+
try {
|
|
84
|
+
const fh = await fs.open(filePath, 'r');
|
|
85
|
+
const sniff = Buffer.alloc(12);
|
|
86
|
+
await fh.read(sniff, 0, 12, 0);
|
|
87
|
+
await fh.close();
|
|
88
|
+
for (const sig of IMG_SIGS) {
|
|
89
|
+
if (sig.every((b, i) => sniff[i] === b)) {
|
|
90
|
+
return `Error: Cannot edit image files (${filePath}). Use specialized image tools instead.`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
throw new Error(`File not found: ${filePath}`);
|
|
96
|
+
}
|
|
97
|
+
let content;
|
|
98
|
+
try {
|
|
99
|
+
content = await fs.readFile(filePath, 'utf-8');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new Error(`File not found: ${filePath}`);
|
|
103
|
+
}
|
|
104
|
+
// ── Read-before-write 门控 ──
|
|
105
|
+
const lastRead = getLastReadTime(filePath);
|
|
106
|
+
if (lastRead === null) {
|
|
107
|
+
return 'Error: You must read the file before editing it. Use the read tool first.';
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
const stat = await fs.stat(filePath);
|
|
111
|
+
if (stat.mtimeMs > lastRead) {
|
|
112
|
+
return 'Error: File has been modified on disk since it was last read. Please re-read it first.';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch { }
|
|
116
|
+
let result;
|
|
117
|
+
if (lineStart !== undefined) {
|
|
118
|
+
result = await this.executeLineReplace(filePath, content, newString, lineStart, args);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
result = await this.executeStringReplace(filePath, content, oldString, newString, args);
|
|
122
|
+
}
|
|
123
|
+
// 记录写入
|
|
124
|
+
recordFileWrite(filePath);
|
|
125
|
+
// ── 自动诊断:修改后运行类型检查/编译检查 ──
|
|
126
|
+
try {
|
|
127
|
+
const diag = await runDiagnostics(process.cwd(), 15000);
|
|
128
|
+
if (diag)
|
|
129
|
+
result += '\n\n' + diag;
|
|
130
|
+
}
|
|
131
|
+
catch { /* 诊断失败不影响工具返回值 */ }
|
|
132
|
+
// ── 自动引用搜索:提取变更符号 → 项目内搜索引用 ──
|
|
133
|
+
try {
|
|
134
|
+
const effectiveOld = oldString ?? (() => {
|
|
135
|
+
const ls = args.line_start ?? 1;
|
|
136
|
+
const lc = args.line_count ?? 1;
|
|
137
|
+
return content.split('\n').slice(ls - 1, ls - 1 + lc).join('\n');
|
|
138
|
+
})();
|
|
139
|
+
const ref = autoReferenceCheck(filePath, content, effectiveOld, newString);
|
|
140
|
+
if (ref.text)
|
|
141
|
+
result += '\n\n' + ref.text;
|
|
142
|
+
}
|
|
143
|
+
catch { /* 引用搜索失败不影响工具返回值 */ }
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
async executeLineReplace(filePath, content, newString, lineStart, args) {
|
|
147
|
+
const lineCount = args.line_count ?? 1;
|
|
148
|
+
const lines = content.split('\n');
|
|
149
|
+
const start = lineStart - 1;
|
|
150
|
+
if (start < 0 || start >= lines.length) {
|
|
151
|
+
throw new Error(`line_start ${lineStart} is out of range. File has ${lines.length} lines.`);
|
|
152
|
+
}
|
|
153
|
+
if (lineCount < 1) {
|
|
154
|
+
throw new Error('line_count must be at least 1.');
|
|
155
|
+
}
|
|
156
|
+
const end = Math.min(start + lineCount, lines.length);
|
|
157
|
+
const before = lines.slice(0, start);
|
|
158
|
+
const after = lines.slice(end);
|
|
159
|
+
const newContent = [...before, newString, ...after].join('\n');
|
|
160
|
+
await fs.writeFile(filePath, newContent, 'utf-8');
|
|
161
|
+
try {
|
|
162
|
+
pushDiff(filePath, computeDiff(content, newContent, filePath));
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
const replaced = end - start;
|
|
166
|
+
// 生成变更摘要:显示替换后的内容
|
|
167
|
+
const newLines = newString.split('\n');
|
|
168
|
+
const previewLines = newLines.slice(0, 5);
|
|
169
|
+
const preview = previewLines.join('\n');
|
|
170
|
+
const truncated = newLines.length > 5;
|
|
171
|
+
let result = `Successfully edited ${filePath} (replaced ${replaced} line${replaced > 1 ? 's' : ''} starting at line ${lineStart})`;
|
|
172
|
+
result += `\n--- New content preview ---\n${preview}`;
|
|
173
|
+
if (truncated) {
|
|
174
|
+
result += `\n... (${newLines.length - 5} more lines)`;
|
|
175
|
+
}
|
|
176
|
+
result += `\n--- End preview ---`;
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
async executeStringReplace(filePath, content, oldString, newString, args) {
|
|
180
|
+
const replaceAll = args.replace_all ?? false;
|
|
181
|
+
const matchCount = this.countOccurrences(content, oldString);
|
|
182
|
+
if (matchCount === 0) {
|
|
183
|
+
throw new Error(`String not found in file: ${filePath}\n` +
|
|
184
|
+
`The old_string was not found. Make sure the string matches exactly, including whitespace and indentation.`);
|
|
185
|
+
}
|
|
186
|
+
if (matchCount > 1 && !replaceAll) {
|
|
187
|
+
throw new Error(`Multiple matches found (${matchCount} occurrences) in file: ${filePath}\n` +
|
|
188
|
+
`Use replace_all=true to replace all occurrences, or provide a larger old_string that uniquely identifies the target.`);
|
|
189
|
+
}
|
|
190
|
+
let newContent;
|
|
191
|
+
if (replaceAll) {
|
|
192
|
+
newContent = content.split(oldString).join(newString);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const index = content.indexOf(oldString);
|
|
196
|
+
newContent =
|
|
197
|
+
content.slice(0, index) + newString + content.slice(index + oldString.length);
|
|
198
|
+
}
|
|
199
|
+
await fs.writeFile(filePath, newContent, 'utf-8');
|
|
200
|
+
try {
|
|
201
|
+
pushDiff(filePath, computeDiff(content, newContent, filePath));
|
|
202
|
+
}
|
|
203
|
+
catch { }
|
|
204
|
+
const replacementCount = replaceAll ? matchCount : 1;
|
|
205
|
+
// 生成变更摘要:显示 old_string 和 new_string 的对比
|
|
206
|
+
const oldPreview = oldString.split('\n').slice(0, 3).join('\n');
|
|
207
|
+
const newPreview = newString.split('\n').slice(0, 3).join('\n');
|
|
208
|
+
const oldTruncated = oldString.split('\n').length > 3;
|
|
209
|
+
const newTruncated = newString.split('\n').length > 3;
|
|
210
|
+
let result = `Successfully edited ${filePath} (${replacementCount} replacement${replacementCount > 1 ? 's' : ''})`;
|
|
211
|
+
result += `\n--- Replaced ---\n${oldPreview}`;
|
|
212
|
+
if (oldTruncated)
|
|
213
|
+
result += '\n...';
|
|
214
|
+
result += `\n--- With ---\n${newPreview}`;
|
|
215
|
+
if (newTruncated)
|
|
216
|
+
result += '\n...';
|
|
217
|
+
result += '\n--- End diff ---';
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 统计字符串在文本中出现的次数
|
|
222
|
+
*/
|
|
223
|
+
countOccurrences(text, search) {
|
|
224
|
+
if (search.length === 0)
|
|
225
|
+
return 0;
|
|
226
|
+
let count = 0;
|
|
227
|
+
let pos = 0;
|
|
228
|
+
while ((pos = text.indexOf(search, pos)) !== -1) {
|
|
229
|
+
count++;
|
|
230
|
+
pos += search.length;
|
|
231
|
+
}
|
|
232
|
+
return count;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ToolCall, ToolResult } from '../types.js';
|
|
2
|
+
import type { ToolRegistry } from './registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* ToolExecutor — 调度工具执行
|
|
5
|
+
*
|
|
6
|
+
* 职责:
|
|
7
|
+
* - 根据工具调用请求查找并执行对应工具
|
|
8
|
+
* - 处理超时和错误
|
|
9
|
+
* - 返回结构化结果(ToolResult)
|
|
10
|
+
*/
|
|
11
|
+
export declare class ToolExecutor {
|
|
12
|
+
private registry;
|
|
13
|
+
private defaultTimeout;
|
|
14
|
+
/**
|
|
15
|
+
* @param registry 工具注册表
|
|
16
|
+
* @param defaultTimeout 默认超时时间(毫秒),默认 300000 (5 分钟)
|
|
17
|
+
*/
|
|
18
|
+
constructor(registry: ToolRegistry, defaultTimeout?: number);
|
|
19
|
+
/**
|
|
20
|
+
* 执行单个工具调用
|
|
21
|
+
*/
|
|
22
|
+
execute(toolCall: ToolCall): Promise<ToolResult>;
|
|
23
|
+
/**
|
|
24
|
+
* 并行执行多个工具调用
|
|
25
|
+
*/
|
|
26
|
+
executeParallel(toolCalls: ToolCall[]): Promise<ToolResult[]>;
|
|
27
|
+
/**
|
|
28
|
+
* 为 Promise 添加超时控制
|
|
29
|
+
*/
|
|
30
|
+
private withTimeout;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToolExecutor — 调度工具执行
|
|
3
|
+
*
|
|
4
|
+
* 职责:
|
|
5
|
+
* - 根据工具调用请求查找并执行对应工具
|
|
6
|
+
* - 处理超时和错误
|
|
7
|
+
* - 返回结构化结果(ToolResult)
|
|
8
|
+
*/
|
|
9
|
+
export class ToolExecutor {
|
|
10
|
+
registry;
|
|
11
|
+
defaultTimeout;
|
|
12
|
+
/**
|
|
13
|
+
* @param registry 工具注册表
|
|
14
|
+
* @param defaultTimeout 默认超时时间(毫秒),默认 300000 (5 分钟)
|
|
15
|
+
*/
|
|
16
|
+
constructor(registry, defaultTimeout) {
|
|
17
|
+
this.registry = registry;
|
|
18
|
+
this.defaultTimeout = defaultTimeout ?? 300_000;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 执行单个工具调用
|
|
22
|
+
*/
|
|
23
|
+
async execute(toolCall) {
|
|
24
|
+
// 查找工具
|
|
25
|
+
const tool = this.registry.get(toolCall.name);
|
|
26
|
+
if (!tool) {
|
|
27
|
+
return {
|
|
28
|
+
tool_use_id: toolCall.id,
|
|
29
|
+
content: `Unknown tool: ${toolCall.name}`,
|
|
30
|
+
is_error: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
// 带超时执行
|
|
35
|
+
const result = await this.withTimeout(tool.execute(toolCall.input), this.defaultTimeout);
|
|
36
|
+
return {
|
|
37
|
+
tool_use_id: toolCall.id,
|
|
38
|
+
content: result,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
return {
|
|
44
|
+
tool_use_id: toolCall.id,
|
|
45
|
+
content: message,
|
|
46
|
+
is_error: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 并行执行多个工具调用
|
|
52
|
+
*/
|
|
53
|
+
async executeParallel(toolCalls) {
|
|
54
|
+
return Promise.all(toolCalls.map((tc) => this.execute(tc)));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 为 Promise 添加超时控制
|
|
58
|
+
*/
|
|
59
|
+
withTimeout(promise, ms) {
|
|
60
|
+
return Promise.race([
|
|
61
|
+
promise,
|
|
62
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Tool execution timed out after ${ms / 1000} seconds`)), ms)),
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* file-tracker — 追踪文件读写时间,支撑 read-before-write 门控。
|
|
3
|
+
*
|
|
4
|
+
* 全局 in-memory 记录表:
|
|
5
|
+
* - recordFileRead(path) — read 工具读取文件后调用
|
|
6
|
+
* - recordFileWrite(path) — write/edit 修改文件后调用
|
|
7
|
+
* - getLastReadTime(path) — 获取上次读取时间,null = 从未读取
|
|
8
|
+
*
|
|
9
|
+
* write/edit/multi_edit 在修改文件前检查:
|
|
10
|
+
* 1. 文件存在但从未被 read → 拒绝(幻觉编辑)
|
|
11
|
+
* 2. 文件在读取后被外部修改过 → 拒绝(过期数据编辑)
|
|
12
|
+
* 3. 文件不存在 → 放行(新建文件无需读取)
|
|
13
|
+
*/
|
|
14
|
+
/** 记录文件被读取 */
|
|
15
|
+
export declare function recordFileRead(filePath: string): void;
|
|
16
|
+
/** 获取文件上次被本进程读取的时间。null = 从未读取 */
|
|
17
|
+
export declare function getLastReadTime(filePath: string): number | null;
|
|
18
|
+
/** 记录文件被写入(写入后自动更新 readTime,等同于 read 过) */
|
|
19
|
+
export declare function recordFileWrite(filePath: string): void;
|
|
20
|
+
//# sourceMappingURL=file-tracker.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* file-tracker — 追踪文件读写时间,支撑 read-before-write 门控。
|
|
3
|
+
*
|
|
4
|
+
* 全局 in-memory 记录表:
|
|
5
|
+
* - recordFileRead(path) — read 工具读取文件后调用
|
|
6
|
+
* - recordFileWrite(path) — write/edit 修改文件后调用
|
|
7
|
+
* - getLastReadTime(path) — 获取上次读取时间,null = 从未读取
|
|
8
|
+
*
|
|
9
|
+
* write/edit/multi_edit 在修改文件前检查:
|
|
10
|
+
* 1. 文件存在但从未被 read → 拒绝(幻觉编辑)
|
|
11
|
+
* 2. 文件在读取后被外部修改过 → 拒绝(过期数据编辑)
|
|
12
|
+
* 3. 文件不存在 → 放行(新建文件无需读取)
|
|
13
|
+
*/
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
const records = new Map();
|
|
16
|
+
/** 规范化路径为绝对路径,Windows 上统一盘符大小写 */
|
|
17
|
+
function normalize(p) {
|
|
18
|
+
const resolved = path.resolve(p);
|
|
19
|
+
// Windows: 盘符统一大写,避免 c:\foo 和 C:\foo 被当成两个 key
|
|
20
|
+
if (process.platform === 'win32' && resolved.length >= 2 && resolved[1] === ':') {
|
|
21
|
+
return resolved[0].toUpperCase() + resolved.slice(1);
|
|
22
|
+
}
|
|
23
|
+
return resolved;
|
|
24
|
+
}
|
|
25
|
+
/** 记录文件被读取 */
|
|
26
|
+
export function recordFileRead(filePath) {
|
|
27
|
+
const key = normalize(filePath);
|
|
28
|
+
const existing = records.get(key);
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
records.set(key, { readTime: now, writeTime: existing?.writeTime ?? 0 });
|
|
31
|
+
}
|
|
32
|
+
/** 获取文件上次被本进程读取的时间。null = 从未读取 */
|
|
33
|
+
export function getLastReadTime(filePath) {
|
|
34
|
+
const key = normalize(filePath);
|
|
35
|
+
const record = records.get(key);
|
|
36
|
+
return record ? record.readTime : null;
|
|
37
|
+
}
|
|
38
|
+
/** 记录文件被写入(写入后自动更新 readTime,等同于 read 过) */
|
|
39
|
+
export function recordFileWrite(filePath) {
|
|
40
|
+
const key = normalize(filePath);
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
records.set(key, { readTime: now, writeTime: now });
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=file-tracker.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ToolDefinition } from '../types.js';
|
|
2
|
+
import type { Tool } from './interface.js';
|
|
3
|
+
import { ToolRegistry } from './registry.js';
|
|
4
|
+
/**
|
|
5
|
+
* FilteredToolRegistry — 包装 ToolRegistry,基于白名单过滤工具
|
|
6
|
+
* 用于子 Agent 的工具隔离:子 Agent 只能使用白名单中的工具
|
|
7
|
+
*/
|
|
8
|
+
export declare class FilteredToolRegistry extends ToolRegistry {
|
|
9
|
+
private parentRegistry;
|
|
10
|
+
private allowedTools;
|
|
11
|
+
constructor(parentRegistry: ToolRegistry, allowedTools: string[]);
|
|
12
|
+
/**
|
|
13
|
+
* 根据名称获取工具(仅在白名单中时返回)
|
|
14
|
+
*/
|
|
15
|
+
get(name: string): Tool | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* 获取所有允许的工具
|
|
18
|
+
*/
|
|
19
|
+
getAll(): Tool[];
|
|
20
|
+
/**
|
|
21
|
+
* 生成 LLM 格式的工具定义数组(仅包含白名单中的工具)
|
|
22
|
+
*/
|
|
23
|
+
getToolDefinitions(): ToolDefinition[];
|
|
24
|
+
/**
|
|
25
|
+
* 检查指定名称的工具是否可用
|
|
26
|
+
*/
|
|
27
|
+
has(name: string): boolean;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=filtered-registry.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ToolRegistry } from './registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* FilteredToolRegistry — 包装 ToolRegistry,基于白名单过滤工具
|
|
4
|
+
* 用于子 Agent 的工具隔离:子 Agent 只能使用白名单中的工具
|
|
5
|
+
*/
|
|
6
|
+
export class FilteredToolRegistry extends ToolRegistry {
|
|
7
|
+
parentRegistry;
|
|
8
|
+
allowedTools;
|
|
9
|
+
constructor(parentRegistry, allowedTools) {
|
|
10
|
+
super(); // 父类的 Map 为空,我们不使用它
|
|
11
|
+
this.parentRegistry = parentRegistry;
|
|
12
|
+
this.allowedTools = new Set(allowedTools);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 根据名称获取工具(仅在白名单中时返回)
|
|
16
|
+
*/
|
|
17
|
+
get(name) {
|
|
18
|
+
if (this.allowedTools.size > 0 && !this.allowedTools.has(name))
|
|
19
|
+
return undefined;
|
|
20
|
+
return this.parentRegistry.get(name);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 获取所有允许的工具
|
|
24
|
+
*/
|
|
25
|
+
getAll() {
|
|
26
|
+
const all = this.parentRegistry.getAll();
|
|
27
|
+
if (this.allowedTools.size === 0)
|
|
28
|
+
return all;
|
|
29
|
+
return all.filter(t => this.allowedTools.has(t.name));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 生成 LLM 格式的工具定义数组(仅包含白名单中的工具)
|
|
33
|
+
*/
|
|
34
|
+
getToolDefinitions() {
|
|
35
|
+
return this.getAll().map((tool) => ({
|
|
36
|
+
name: tool.name,
|
|
37
|
+
description: tool.description,
|
|
38
|
+
input_schema: tool.inputSchema,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 检查指定名称的工具是否可用
|
|
43
|
+
*/
|
|
44
|
+
has(name) {
|
|
45
|
+
if (this.allowedTools.size > 0 && !this.allowedTools.has(name))
|
|
46
|
+
return false;
|
|
47
|
+
return this.parentRegistry.has(name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=filtered-registry.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Tool } from './interface.js';
|
|
2
|
+
import type { MachineRegistry } from '../machine/registry.js';
|
|
3
|
+
/** Flow 框架工具名称集合 — 这些工具不记入对话历史 */
|
|
4
|
+
export declare const FLOW_TOOL_NAMES: Set<string>;
|
|
5
|
+
/** 判断给定工具名是否为 Flow 框架工具 */
|
|
6
|
+
export declare function isFlowTool(name: string): boolean;
|
|
7
|
+
export declare function createFlowStartTool(registry: MachineRegistry): Tool;
|
|
8
|
+
export declare function createFlowAddTool(registry: MachineRegistry): Tool;
|
|
9
|
+
export declare function createFlowCompleteTool(registry: MachineRegistry): Tool;
|
|
10
|
+
//# sourceMappingURL=flow.d.ts.map
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Flow Tools — 通用流程控制工具
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// flow_start — 激活指定模式(todo / plan / spec / ...)
|
|
6
|
+
// flow_add — 向当前活跃 Flow 追加定义项(仅 definition 阶段有效)
|
|
7
|
+
// flow_complete — 完成当前步骤/阶段,触发 guard → 状态转移
|
|
8
|
+
//
|
|
9
|
+
// 这三个工具以 flow_ 为前缀,自成体系。新增模式时只需扩展
|
|
10
|
+
// flow_start 的 mode 枚举,不新增工具。
|
|
11
|
+
//
|
|
12
|
+
// Flow 工具不记入对话历史——状态由 Zone 5 注入体现。
|
|
13
|
+
// ============================================================
|
|
14
|
+
// ── 元数据 ──────────────────────────────────────────────────
|
|
15
|
+
/** Flow 框架工具名称集合 — 这些工具不记入对话历史 */
|
|
16
|
+
export const FLOW_TOOL_NAMES = new Set([
|
|
17
|
+
'flow_start',
|
|
18
|
+
'flow_add',
|
|
19
|
+
'flow_complete',
|
|
20
|
+
]);
|
|
21
|
+
/** 已注册的 Flow mode → 描述映射 */
|
|
22
|
+
const MODE_DESCRIPTIONS = {
|
|
23
|
+
todo: '任务拆分与逐步执行 — 分析任务 → 拆解步骤 → 逐个执行',
|
|
24
|
+
spec: '需求规格撰写 — spec.md → tasks.md → checklist.md 三阶段推进',
|
|
25
|
+
};
|
|
26
|
+
/** 判断给定工具名是否为 Flow 框架工具 */
|
|
27
|
+
export function isFlowTool(name) {
|
|
28
|
+
return FLOW_TOOL_NAMES.has(name);
|
|
29
|
+
}
|
|
30
|
+
// ── flow_start ──────────────────────────────────────────────
|
|
31
|
+
export function createFlowStartTool(registry) {
|
|
32
|
+
return {
|
|
33
|
+
name: 'flow_start',
|
|
34
|
+
description: 'Activate a guided workflow mode. Available modes:\n' +
|
|
35
|
+
Object.entries(MODE_DESCRIPTIONS)
|
|
36
|
+
.map(([k, v]) => ` - "${k}": ${v}`)
|
|
37
|
+
.join('\n') +
|
|
38
|
+
'\n\nAfter activation, use flow_add to define items and flow_complete to advance.',
|
|
39
|
+
inputSchema: {
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
mode: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
description: `The workflow mode to activate. One of: ${Object.keys(MODE_DESCRIPTIONS).join(', ')}.`,
|
|
45
|
+
enum: Object.keys(MODE_DESCRIPTIONS),
|
|
46
|
+
},
|
|
47
|
+
task: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'A concise description of the overall task (for todo mode).',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ['mode'],
|
|
53
|
+
},
|
|
54
|
+
async execute(args) {
|
|
55
|
+
const mode = args.mode ?? '';
|
|
56
|
+
const task = args.task ?? '';
|
|
57
|
+
if (!MODE_DESCRIPTIONS[mode]) {
|
|
58
|
+
return `Unknown mode "${mode}". Available: ${Object.keys(MODE_DESCRIPTIONS).join(', ')}.`;
|
|
59
|
+
}
|
|
60
|
+
const flow = registry.get(mode);
|
|
61
|
+
if (!flow) {
|
|
62
|
+
return `Flow for mode "${mode}" is not registered.`;
|
|
63
|
+
}
|
|
64
|
+
// 检查是否同一 Flow 已经处于活跃状态
|
|
65
|
+
const currentActive = registry.getActive();
|
|
66
|
+
if (currentActive?.id === mode) {
|
|
67
|
+
const snap = currentActive.getSnapshot();
|
|
68
|
+
const steps = snap.context.steps ?? [];
|
|
69
|
+
if (steps.length > 0) {
|
|
70
|
+
return `Flow "${mode}" is already active with ${steps.length} step(s). Use flow_add to add more steps, or flow_complete to advance. To restart with a fresh plan, destroy the current flow first (wait for it to complete or be deactivated).`;
|
|
71
|
+
}
|
|
72
|
+
return `Flow "${mode}" is already active (no steps yet). Add steps with flow_add, then call flow_complete.`;
|
|
73
|
+
}
|
|
74
|
+
// 激活 Flow(自动停用当前活跃 Flow)
|
|
75
|
+
registry.activate(mode, { task });
|
|
76
|
+
return `Flow "${mode}" activated${task ? ` for task: "${task}"` : ''}. Follow the instructions in context, then call flow_complete to advance.`;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ── flow_add ────────────────────────────────────────────────
|
|
81
|
+
export function createFlowAddTool(registry) {
|
|
82
|
+
return {
|
|
83
|
+
name: 'flow_add',
|
|
84
|
+
description: 'Add steps to the current active flow. In todo mode, each step is an execution state. Submit ALL steps at once — do not add them one by one. Steps will be executed in order.',
|
|
85
|
+
inputSchema: {
|
|
86
|
+
type: 'object',
|
|
87
|
+
properties: {
|
|
88
|
+
steps: {
|
|
89
|
+
type: 'array',
|
|
90
|
+
items: { type: 'string' },
|
|
91
|
+
description: 'ALL step descriptions at once. Each string is one step — a clear, actionable description of what to do and what success looks like. Submit the COMPLETE list in one call.',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ['steps'],
|
|
95
|
+
},
|
|
96
|
+
async execute(args) {
|
|
97
|
+
const active = registry.getActive();
|
|
98
|
+
if (!active) {
|
|
99
|
+
return 'No active flow. Use flow_start first.';
|
|
100
|
+
}
|
|
101
|
+
const stepDescs = args.steps ?? [];
|
|
102
|
+
if (!active.addItem) {
|
|
103
|
+
return `Flow "${active.id}" does not support adding items.`;
|
|
104
|
+
}
|
|
105
|
+
if (stepDescs.length === 0) {
|
|
106
|
+
return 'No steps provided. Pass at least one step description in the steps array.';
|
|
107
|
+
}
|
|
108
|
+
const added = [];
|
|
109
|
+
for (const desc of stepDescs) {
|
|
110
|
+
const item = active.addItem(desc);
|
|
111
|
+
added.push(`${item.id}: ${item.label}`);
|
|
112
|
+
}
|
|
113
|
+
// 规划阶段:写入步骤后自动转移到执行阶段
|
|
114
|
+
// 模型只需提交步骤,状态机自己推进,无需模型额外调 flow_complete
|
|
115
|
+
const snapAfter = active.getSnapshot();
|
|
116
|
+
if (snapAfter.currentState === 'planning') {
|
|
117
|
+
const advanceResult = active.advance('flow_complete');
|
|
118
|
+
if (advanceResult.ok) {
|
|
119
|
+
registry.onAdvanceSucceeded(active.id, advanceResult.isTerminal ?? false);
|
|
120
|
+
const newSnap = active.getSnapshot();
|
|
121
|
+
const newSteps = newSnap.context.steps ?? [];
|
|
122
|
+
const newIdx = newSnap.context.stepIndex ?? 0;
|
|
123
|
+
const firstStep = newSteps[newIdx];
|
|
124
|
+
if (firstStep) {
|
|
125
|
+
return `${added.length} step(s) added. Auto-advanced to execution.\n\n${'-'.repeat(40)}\n${added.map((a, i) => ` ${i + 1}. ${a}`).join('\n')}\n${'-'.repeat(40)}\n\nNow executing step ${newIdx + 1}/${newSteps.length}: "${firstStep.label}"`;
|
|
126
|
+
}
|
|
127
|
+
return `${added.length} step(s) added:\n${added.map((a, i) => ` ${i + 1}. ${a}`).join('\n')}\n\nAuto-advanced to execution.`;
|
|
128
|
+
}
|
|
129
|
+
// guard 失败(比如步骤数为0),不自动转移,让模型知道
|
|
130
|
+
return `${added.length} step(s) added:\n${added.map((a, i) => ` ${i + 1}. ${a}`).join('\n')}\n\nWarning: could not auto-advance — ${advanceResult.reason ?? 'unknown guard failure'}. Call flow_complete manually.`;
|
|
131
|
+
}
|
|
132
|
+
return `${added.length} step(s) added:\n${added.map((a, i) => ` ${i + 1}. ${a}`).join('\n')}\n\nAll steps defined. Call flow_complete to begin execution.`;
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// ── flow_complete ───────────────────────────────────────────
|
|
137
|
+
export function createFlowCompleteTool(registry) {
|
|
138
|
+
return {
|
|
139
|
+
name: 'flow_complete',
|
|
140
|
+
description: 'Complete the current flow step or phase and advance. In definition phase (todo planning), this finishes defining and starts execution. In execution phase, this advances to the next step. On the final step, the flow ends.',
|
|
141
|
+
inputSchema: {
|
|
142
|
+
type: 'object',
|
|
143
|
+
properties: {},
|
|
144
|
+
required: [],
|
|
145
|
+
},
|
|
146
|
+
async execute(_args) {
|
|
147
|
+
const active = registry.getActive();
|
|
148
|
+
if (!active) {
|
|
149
|
+
return 'No active flow. Nothing to complete.';
|
|
150
|
+
}
|
|
151
|
+
const snap = active.getSnapshot();
|
|
152
|
+
const steps = snap.context.steps ?? [];
|
|
153
|
+
const idx = snap.context.stepIndex ?? 0;
|
|
154
|
+
// 执行实际的状态转移(guard 检查在此发生)
|
|
155
|
+
const result = active.advance('flow_complete');
|
|
156
|
+
if (!result.ok) {
|
|
157
|
+
// Guard 失败:返回失败原因给模型
|
|
158
|
+
return `Cannot advance: ${result.reason ?? 'unknown guard failure'}`;
|
|
159
|
+
}
|
|
160
|
+
// 转移成功:更新 registry(terminal 则清理)
|
|
161
|
+
registry.onAdvanceSucceeded(active.id, result.isTerminal ?? false);
|
|
162
|
+
if (result.isTerminal) {
|
|
163
|
+
return 'All steps completed. Flow finished.';
|
|
164
|
+
}
|
|
165
|
+
// 查找下一步
|
|
166
|
+
const newSnap = active.getSnapshot();
|
|
167
|
+
const newSteps = newSnap.context.steps ?? [];
|
|
168
|
+
const newIdx = newSnap.context.stepIndex ?? 0;
|
|
169
|
+
const nextStep = newSteps[newIdx];
|
|
170
|
+
if (newSnap.currentState === 'executing' && nextStep) {
|
|
171
|
+
return `Planning complete (${newSteps.length} steps). Now executing step ${newIdx + 1}/${newSteps.length}: "${nextStep.label}"`;
|
|
172
|
+
}
|
|
173
|
+
if (nextStep) {
|
|
174
|
+
return `Step "${nextStep.id}" (${newIdx + 1}/${newSteps.length}) acknowledged. Advancing to: "${nextStep.label}"`;
|
|
175
|
+
}
|
|
176
|
+
return `${newSteps.length} items defined — transitioning to execution.`;
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=flow.js.map
|