@qlingzzy/qling 1.0.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/CHANGELOG.md +122 -0
- package/LICENSE +21 -0
- package/README.en.md +129 -0
- package/README.md +416 -0
- package/dist/agent/subtask.d.ts +21 -0
- package/dist/agent/subtask.d.ts.map +1 -0
- package/dist/agent/subtask.js +55 -0
- package/dist/agent-loop.d.ts +151 -0
- package/dist/agent-loop.d.ts.map +1 -0
- package/dist/agent-loop.js +1498 -0
- package/dist/agents/isolation-policy.d.ts +14 -0
- package/dist/agents/isolation-policy.d.ts.map +1 -0
- package/dist/agents/isolation-policy.js +52 -0
- package/dist/channels/console-channel.d.ts +15 -0
- package/dist/channels/console-channel.d.ts.map +1 -0
- package/dist/channels/console-channel.js +66 -0
- package/dist/channels/registry.d.ts +10 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +25 -0
- package/dist/channels/slack-channel.d.ts +35 -0
- package/dist/channels/slack-channel.d.ts.map +1 -0
- package/dist/channels/slack-channel.js +232 -0
- package/dist/channels/telegram-channel.d.ts +32 -0
- package/dist/channels/telegram-channel.d.ts.map +1 -0
- package/dist/channels/telegram-channel.js +167 -0
- package/dist/channels/types.d.ts +31 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +4 -0
- package/dist/cli/bootstrap.d.ts +39 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +138 -0
- package/dist/cli/channel-bootstrap.d.ts +23 -0
- package/dist/cli/channel-bootstrap.d.ts.map +1 -0
- package/dist/cli/channel-bootstrap.js +46 -0
- package/dist/cli/daemon-control.d.ts +31 -0
- package/dist/cli/daemon-control.d.ts.map +1 -0
- package/dist/cli/daemon-control.js +177 -0
- package/dist/cli/guidance-panel.d.ts +11 -0
- package/dist/cli/guidance-panel.d.ts.map +1 -0
- package/dist/cli/guidance-panel.js +16 -0
- package/dist/cli/mcp-control.d.ts +7 -0
- package/dist/cli/mcp-control.d.ts.map +1 -0
- package/dist/cli/mcp-control.js +119 -0
- package/dist/cli/mission-views.d.ts +13 -0
- package/dist/cli/mission-views.d.ts.map +1 -0
- package/dist/cli/mission-views.js +82 -0
- package/dist/cli/setup.d.ts +9 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +140 -0
- package/dist/cli/startup-contract.d.ts +23 -0
- package/dist/cli/startup-contract.d.ts.map +1 -0
- package/dist/cli/startup-contract.js +694 -0
- package/dist/commands/agents.d.ts +3 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +44 -0
- package/dist/commands/checkpoint.d.ts +3 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +52 -0
- package/dist/commands/claude-style.d.ts +12 -0
- package/dist/commands/claude-style.d.ts.map +1 -0
- package/dist/commands/claude-style.js +560 -0
- package/dist/commands/clear.d.ts +3 -0
- package/dist/commands/clear.d.ts.map +1 -0
- package/dist/commands/clear.js +20 -0
- package/dist/commands/compact.d.ts +3 -0
- package/dist/commands/compact.d.ts.map +1 -0
- package/dist/commands/compact.js +23 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +22 -0
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +102 -0
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +13 -0
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +22 -0
- package/dist/commands/detach.d.ts +3 -0
- package/dist/commands/detach.d.ts.map +1 -0
- package/dist/commands/detach.js +44 -0
- package/dist/commands/distill.d.ts +3 -0
- package/dist/commands/distill.d.ts.map +1 -0
- package/dist/commands/distill.js +23 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +13 -0
- package/dist/commands/dream.d.ts +3 -0
- package/dist/commands/dream.d.ts.map +1 -0
- package/dist/commands/dream.js +59 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +18 -0
- package/dist/commands/exports.d.ts +3 -0
- package/dist/commands/exports.d.ts.map +1 -0
- package/dist/commands/exports.js +15 -0
- package/dist/commands/goal.d.ts +3 -0
- package/dist/commands/goal.d.ts.map +1 -0
- package/dist/commands/goal.js +147 -0
- package/dist/commands/help.d.ts +4 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +75 -0
- package/dist/commands/hooks.d.ts +3 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +14 -0
- package/dist/commands/index.d.ts +29 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +417 -0
- package/dist/commands/knowledge.d.ts +8 -0
- package/dist/commands/knowledge.d.ts.map +1 -0
- package/dist/commands/knowledge.js +191 -0
- package/dist/commands/loop.d.ts +3 -0
- package/dist/commands/loop.d.ts.map +1 -0
- package/dist/commands/loop.js +138 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +57 -0
- package/dist/commands/memory.d.ts +3 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +215 -0
- package/dist/commands/mission.d.ts +3 -0
- package/dist/commands/mission.d.ts.map +1 -0
- package/dist/commands/mission.js +129 -0
- package/dist/commands/permissions.d.ts +3 -0
- package/dist/commands/permissions.d.ts.map +1 -0
- package/dist/commands/permissions.js +82 -0
- package/dist/commands/privacy.d.ts +3 -0
- package/dist/commands/privacy.d.ts.map +1 -0
- package/dist/commands/privacy.js +13 -0
- package/dist/commands/recap.d.ts +3 -0
- package/dist/commands/recap.d.ts.map +1 -0
- package/dist/commands/recap.js +11 -0
- package/dist/commands/repomap.d.ts +3 -0
- package/dist/commands/repomap.d.ts.map +1 -0
- package/dist/commands/repomap.js +146 -0
- package/dist/commands/resume.d.ts +3 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +42 -0
- package/dist/commands/runtime.d.ts +61 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +20 -0
- package/dist/commands/sessions.d.ts +3 -0
- package/dist/commands/sessions.d.ts.map +1 -0
- package/dist/commands/sessions.js +34 -0
- package/dist/commands/shortcuts.d.ts +3 -0
- package/dist/commands/shortcuts.d.ts.map +1 -0
- package/dist/commands/shortcuts.js +12 -0
- package/dist/commands/skill.d.ts +3 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +20 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +31 -0
- package/dist/commands/statusline.d.ts +3 -0
- package/dist/commands/statusline.d.ts.map +1 -0
- package/dist/commands/statusline.js +40 -0
- package/dist/commands/storage.d.ts +3 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +122 -0
- package/dist/commands/tasks.d.ts +3 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +117 -0
- package/dist/commands/types.d.ts +14 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +1 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +86 -0
- package/dist/config-report.d.ts +35 -0
- package/dist/config-report.d.ts.map +1 -0
- package/dist/config-report.js +100 -0
- package/dist/config.d.ts +217 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +690 -0
- package/dist/context-compactor.d.ts +27 -0
- package/dist/context-compactor.d.ts.map +1 -0
- package/dist/context-compactor.js +489 -0
- package/dist/context-report.d.ts +35 -0
- package/dist/context-report.d.ts.map +1 -0
- package/dist/context-report.js +172 -0
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +316 -0
- package/dist/dashboard-server.d.ts +18 -0
- package/dist/dashboard-server.d.ts.map +1 -0
- package/dist/dashboard-server.js +325 -0
- package/dist/discovery-registry.d.ts +28 -0
- package/dist/discovery-registry.d.ts.map +1 -0
- package/dist/discovery-registry.js +106 -0
- package/dist/discovery-types.d.ts +54 -0
- package/dist/discovery-types.d.ts.map +1 -0
- package/dist/discovery-types.js +5 -0
- package/dist/doctor.d.ts +31 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +343 -0
- package/dist/eval/runner.d.ts +10 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +78 -0
- package/dist/eval/tasks.d.ts +3 -0
- package/dist/eval/tasks.d.ts.map +1 -0
- package/dist/eval/tasks.js +179 -0
- package/dist/eval/types.d.ts +31 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +4 -0
- package/dist/git/auto-commit.d.ts +28 -0
- package/dist/git/auto-commit.d.ts.map +1 -0
- package/dist/git/auto-commit.js +112 -0
- package/dist/guard/approval.d.ts +16 -0
- package/dist/guard/approval.d.ts.map +1 -0
- package/dist/guard/approval.js +68 -0
- package/dist/guard/content-filter.d.ts +15 -0
- package/dist/guard/content-filter.d.ts.map +1 -0
- package/dist/guard/content-filter.js +102 -0
- package/dist/guard/permissions.d.ts +17 -0
- package/dist/guard/permissions.d.ts.map +1 -0
- package/dist/guard/permissions.js +54 -0
- package/dist/guard/rate-limit.d.ts +14 -0
- package/dist/guard/rate-limit.d.ts.map +1 -0
- package/dist/guard/rate-limit.js +47 -0
- package/dist/guard.d.ts +21 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +144 -0
- package/dist/help-topics.d.ts +19 -0
- package/dist/help-topics.d.ts.map +1 -0
- package/dist/help-topics.js +391 -0
- package/dist/hooks-report.d.ts +23 -0
- package/dist/hooks-report.d.ts.map +1 -0
- package/dist/hooks-report.js +44 -0
- package/dist/i18n/index.d.ts +5 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +4 -0
- package/dist/i18n/zh-cn.d.ts +180 -0
- package/dist/i18n/zh-cn.d.ts.map +1 -0
- package/dist/i18n/zh-cn.js +184 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1157 -0
- package/dist/knowledge-agent.d.ts +47 -0
- package/dist/knowledge-agent.d.ts.map +1 -0
- package/dist/knowledge-agent.js +320 -0
- package/dist/local-status-report.d.ts +23 -0
- package/dist/local-status-report.d.ts.map +1 -0
- package/dist/local-status-report.js +63 -0
- package/dist/local-storage-report.d.ts +32 -0
- package/dist/local-storage-report.d.ts.map +1 -0
- package/dist/local-storage-report.js +171 -0
- package/dist/mcp/bridge.d.ts +11 -0
- package/dist/mcp/bridge.d.ts.map +1 -0
- package/dist/mcp/bridge.js +37 -0
- package/dist/mcp/client.d.ts +26 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +209 -0
- package/dist/mcp/http-transport.d.ts +21 -0
- package/dist/mcp/http-transport.d.ts.map +1 -0
- package/dist/mcp/http-transport.js +126 -0
- package/dist/mcp/presets.d.ts +22 -0
- package/dist/mcp/presets.d.ts.map +1 -0
- package/dist/mcp/presets.js +80 -0
- package/dist/mcp/registry.d.ts +23 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +85 -0
- package/dist/mcp/stdio-transport.d.ts +25 -0
- package/dist/mcp/stdio-transport.d.ts.map +1 -0
- package/dist/mcp/stdio-transport.js +92 -0
- package/dist/mcp/store.d.ts +41 -0
- package/dist/mcp/store.d.ts.map +1 -0
- package/dist/mcp/store.js +100 -0
- package/dist/mcp/types.d.ts +40 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +4 -0
- package/dist/mcp-report.d.ts +30 -0
- package/dist/mcp-report.d.ts.map +1 -0
- package/dist/mcp-report.js +104 -0
- package/dist/memory/cognitive-index.d.ts +56 -0
- package/dist/memory/cognitive-index.d.ts.map +1 -0
- package/dist/memory/cognitive-index.js +265 -0
- package/dist/memory/compactor.d.ts +28 -0
- package/dist/memory/compactor.d.ts.map +1 -0
- package/dist/memory/compactor.js +92 -0
- package/dist/memory/consolidation.d.ts +13 -0
- package/dist/memory/consolidation.d.ts.map +1 -0
- package/dist/memory/consolidation.js +77 -0
- package/dist/memory/embedding.d.ts +15 -0
- package/dist/memory/embedding.d.ts.map +1 -0
- package/dist/memory/embedding.js +59 -0
- package/dist/memory/memory-llm-dream.d.ts +3 -0
- package/dist/memory/memory-llm-dream.d.ts.map +1 -0
- package/dist/memory/memory-llm-dream.js +59 -0
- package/dist/memory/projection-worker.d.ts +30 -0
- package/dist/memory/projection-worker.d.ts.map +1 -0
- package/dist/memory/projection-worker.js +92 -0
- package/dist/memory/semantic-index.d.ts +18 -0
- package/dist/memory/semantic-index.d.ts.map +1 -0
- package/dist/memory/semantic-index.js +86 -0
- package/dist/memory/wal.d.ts +33 -0
- package/dist/memory/wal.d.ts.map +1 -0
- package/dist/memory/wal.js +131 -0
- package/dist/memory-report.d.ts +120 -0
- package/dist/memory-report.d.ts.map +1 -0
- package/dist/memory-report.js +726 -0
- package/dist/memory.d.ts +149 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +632 -0
- package/dist/metrics/agent-telemetry.d.ts +14 -0
- package/dist/metrics/agent-telemetry.d.ts.map +1 -0
- package/dist/metrics/agent-telemetry.js +44 -0
- package/dist/metrics/collector.d.ts +17 -0
- package/dist/metrics/collector.d.ts.map +1 -0
- package/dist/metrics/collector.js +137 -0
- package/dist/metrics/types.d.ts +14 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +4 -0
- package/dist/mission/manager.d.ts +28 -0
- package/dist/mission/manager.d.ts.map +1 -0
- package/dist/mission/manager.js +208 -0
- package/dist/mission/types.d.ts +37 -0
- package/dist/mission/types.d.ts.map +1 -0
- package/dist/mission/types.js +5 -0
- package/dist/onboarding/tutorial.d.ts +33 -0
- package/dist/onboarding/tutorial.d.ts.map +1 -0
- package/dist/onboarding/tutorial.js +96 -0
- package/dist/output-style.d.ts +14 -0
- package/dist/output-style.d.ts.map +1 -0
- package/dist/output-style.js +29 -0
- package/dist/package-version.d.ts +12 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +42 -0
- package/dist/permissions-report.d.ts +42 -0
- package/dist/permissions-report.d.ts.map +1 -0
- package/dist/permissions-report.js +120 -0
- package/dist/pipeline/consistency-checker.d.ts +8 -0
- package/dist/pipeline/consistency-checker.d.ts.map +1 -0
- package/dist/pipeline/consistency-checker.js +40 -0
- package/dist/pipeline/example-generator.d.ts +4 -0
- package/dist/pipeline/example-generator.d.ts.map +1 -0
- package/dist/pipeline/example-generator.js +64 -0
- package/dist/pipeline/hooks.d.ts +68 -0
- package/dist/pipeline/hooks.d.ts.map +1 -0
- package/dist/pipeline/hooks.js +377 -0
- package/dist/pipeline/sections.d.ts +41 -0
- package/dist/pipeline/sections.d.ts.map +1 -0
- package/dist/pipeline/sections.js +244 -0
- package/dist/pipeline/verification.d.ts +12 -0
- package/dist/pipeline/verification.d.ts.map +1 -0
- package/dist/pipeline/verification.js +138 -0
- package/dist/privacy-report.d.ts +24 -0
- package/dist/privacy-report.d.ts.map +1 -0
- package/dist/privacy-report.js +78 -0
- package/dist/providers/presets.d.ts +25 -0
- package/dist/providers/presets.d.ts.map +1 -0
- package/dist/providers/presets.js +205 -0
- package/dist/recap.d.ts +38 -0
- package/dist/recap.d.ts.map +1 -0
- package/dist/recap.js +154 -0
- package/dist/repl.d.ts +41 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +396 -0
- package/dist/runtime-paths.d.ts +32 -0
- package/dist/runtime-paths.d.ts.map +1 -0
- package/dist/runtime-paths.js +134 -0
- package/dist/sdk.d.ts +12 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +18 -0
- package/dist/session/daemon-session-api.d.ts +22 -0
- package/dist/session/daemon-session-api.d.ts.map +1 -0
- package/dist/session/daemon-session-api.js +48 -0
- package/dist/session/durable-session-supervisor.d.ts +24 -0
- package/dist/session/durable-session-supervisor.d.ts.map +1 -0
- package/dist/session/durable-session-supervisor.js +195 -0
- package/dist/session/goal-controller.d.ts +43 -0
- package/dist/session/goal-controller.d.ts.map +1 -0
- package/dist/session/goal-controller.js +77 -0
- package/dist/session/goal-evaluator.d.ts +29 -0
- package/dist/session/goal-evaluator.d.ts.map +1 -0
- package/dist/session/goal-evaluator.js +100 -0
- package/dist/session/loop-prompt.d.ts +14 -0
- package/dist/session/loop-prompt.d.ts.map +1 -0
- package/dist/session/loop-prompt.js +49 -0
- package/dist/session/session-goal-manager.d.ts +51 -0
- package/dist/session/session-goal-manager.d.ts.map +1 -0
- package/dist/session/session-goal-manager.js +118 -0
- package/dist/session/session-registry.d.ts +40 -0
- package/dist/session/session-registry.d.ts.map +1 -0
- package/dist/session/session-registry.js +124 -0
- package/dist/session/session-scheduler.d.ts +59 -0
- package/dist/session/session-scheduler.d.ts.map +1 -0
- package/dist/session/session-scheduler.js +170 -0
- package/dist/session-checkpoint-report.d.ts +22 -0
- package/dist/session-checkpoint-report.d.ts.map +1 -0
- package/dist/session-checkpoint-report.js +99 -0
- package/dist/session-export-index.d.ts +23 -0
- package/dist/session-export-index.d.ts.map +1 -0
- package/dist/session-export-index.js +96 -0
- package/dist/session-export.d.ts +28 -0
- package/dist/session-export.d.ts.map +1 -0
- package/dist/session-export.js +99 -0
- package/dist/session-goal-report.d.ts +37 -0
- package/dist/session-goal-report.d.ts.map +1 -0
- package/dist/session-goal-report.js +219 -0
- package/dist/session-list-report.d.ts +16 -0
- package/dist/session-list-report.d.ts.map +1 -0
- package/dist/session-list-report.js +60 -0
- package/dist/session-task-report.d.ts +23 -0
- package/dist/session-task-report.d.ts.map +1 -0
- package/dist/session-task-report.js +183 -0
- package/dist/shortcuts.d.ts +2 -0
- package/dist/shortcuts.d.ts.map +1 -0
- package/dist/shortcuts.js +32 -0
- package/dist/skills/registry.d.ts +8 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +119 -0
- package/dist/skills/types.d.ts +7 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +4 -0
- package/dist/statusline.d.ts +37 -0
- package/dist/statusline.d.ts.map +1 -0
- package/dist/statusline.js +207 -0
- package/dist/tools/bash.d.ts +10 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +278 -0
- package/dist/tools/browser-fetch.d.ts +7 -0
- package/dist/tools/browser-fetch.d.ts.map +1 -0
- package/dist/tools/browser-fetch.js +133 -0
- package/dist/tools/error-utils.d.ts +9 -0
- package/dist/tools/error-utils.d.ts.map +1 -0
- package/dist/tools/error-utils.js +35 -0
- package/dist/tools/index.d.ts +27 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +86 -0
- package/dist/tools/patch.d.ts +22 -0
- package/dist/tools/patch.d.ts.map +1 -0
- package/dist/tools/patch.js +458 -0
- package/dist/tools/planner.d.ts +7 -0
- package/dist/tools/planner.d.ts.map +1 -0
- package/dist/tools/planner.js +148 -0
- package/dist/tools/read.d.ts +8 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +114 -0
- package/dist/tools/search.d.ts +11 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +636 -0
- package/dist/tools/skill.d.ts +8 -0
- package/dist/tools/skill.d.ts.map +1 -0
- package/dist/tools/skill.js +181 -0
- package/dist/tools/subtask.d.ts +9 -0
- package/dist/tools/subtask.d.ts.map +1 -0
- package/dist/tools/subtask.js +120 -0
- package/dist/tools/todo.d.ts +8 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +170 -0
- package/dist/tools/url-fetch.d.ts +11 -0
- package/dist/tools/url-fetch.d.ts.map +1 -0
- package/dist/tools/url-fetch.js +208 -0
- package/dist/tools/vision-analyze.d.ts +9 -0
- package/dist/tools/vision-analyze.d.ts.map +1 -0
- package/dist/tools/vision-analyze.js +179 -0
- package/dist/tools/write.d.ts +7 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +128 -0
- package/dist/tui/chrome.d.ts +7 -0
- package/dist/tui/chrome.d.ts.map +1 -0
- package/dist/tui/chrome.js +22 -0
- package/dist/tui/input-buffer.d.ts +37 -0
- package/dist/tui/input-buffer.d.ts.map +1 -0
- package/dist/tui/input-buffer.js +228 -0
- package/dist/tui/input-history.d.ts +11 -0
- package/dist/tui/input-history.d.ts.map +1 -0
- package/dist/tui/input-history.js +69 -0
- package/dist/tui/input-queue.d.ts +27 -0
- package/dist/tui/input-queue.d.ts.map +1 -0
- package/dist/tui/input-queue.js +85 -0
- package/dist/tui/markdown.d.ts +10 -0
- package/dist/tui/markdown.d.ts.map +1 -0
- package/dist/tui/markdown.js +396 -0
- package/dist/tui/progress.d.ts +3 -0
- package/dist/tui/progress.d.ts.map +1 -0
- package/dist/tui/progress.js +13 -0
- package/dist/tui/shell.d.ts +67 -0
- package/dist/tui/shell.d.ts.map +1 -0
- package/dist/tui/shell.js +271 -0
- package/dist/tui/streaming-repl.d.ts +39 -0
- package/dist/tui/streaming-repl.d.ts.map +1 -0
- package/dist/tui/streaming-repl.js +460 -0
- package/dist/tui/streaming-tui.d.ts +174 -0
- package/dist/tui/streaming-tui.d.ts.map +1 -0
- package/dist/tui/streaming-tui.js +1049 -0
- package/dist/types.d.ts +221 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +37 -0
- package/dist/utils/symbol-extractor.d.ts +8 -0
- package/dist/utils/symbol-extractor.d.ts.map +1 -0
- package/dist/utils/symbol-extractor.js +190 -0
- package/dist/workflow-runtime.d.ts +45 -0
- package/dist/workflow-runtime.d.ts.map +1 -0
- package/dist/workflow-runtime.js +146 -0
- package/dist/workflow-types.d.ts +73 -0
- package/dist/workflow-types.d.ts.map +1 -0
- package/dist/workflow-types.js +34 -0
- package/docs/docker.md +66 -0
- package/docs/install.md +159 -0
- package/docs/sdk.md +67 -0
- package/docs/skills.md +51 -0
- package/package.json +102 -0
- package/scripts/bootstrap.mjs +63 -0
- package/scripts/check_image.ps1 +18 -0
- package/scripts/clean-dist.mjs +18 -0
- package/scripts/copy_image.ps1 +5 -0
- package/scripts/eval-smoke.mjs +17 -0
- package/skills/examples/repo-triage/SKILL.md +50 -0
- package/skills/qling.md +42 -0
- package/skills/templates/SKILL.md +37 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import { readFile, writeFile } from "fs/promises";
|
|
2
|
+
import { relative } from "path";
|
|
3
|
+
import { getErrorMessage, toolError, toolSuccess } from "./error-utils.js";
|
|
4
|
+
import { checkSensitiveWriteTarget, getRuntimeRootsFromEnv, isPathAllowedForWrite, resolveToolPath, } from "../runtime-paths.js";
|
|
5
|
+
/** 超过该字节数拒绝做 LCS diff / 写入,防止超大文件 OOM */
|
|
6
|
+
export const PATCH_MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
7
|
+
export const patchTool = {
|
|
8
|
+
name: "patch",
|
|
9
|
+
description: "Apply precise search-and-replace edits (chunks) to an existing file. Only writes if all chunks uniquely match. Supports dry_run. Prefer larger unique context blocks.",
|
|
10
|
+
longDescription: `精准局部替换文件内容(补丁)。默认会修改磁盘文件;dry_run=true 时只校验并返回 diff。
|
|
11
|
+
|
|
12
|
+
**使用场景**:
|
|
13
|
+
- 修改文件中的一个或多个函数、变量定义、导入声明等
|
|
14
|
+
- 避免重写大文件以节省 Token 资源并提高修改准确率
|
|
15
|
+
|
|
16
|
+
**工作逻辑**:
|
|
17
|
+
- 必须精确匹配 search 字段中的代码段(包括空格、缩进与换行)
|
|
18
|
+
- 只有当所有指定的 chunks 在文件中**有且仅有唯一匹配**时,才会将替换内容写入文件(dry_run 除外)
|
|
19
|
+
- 任意 chunk 失败则**整次事务不写盘**,并返回诊断上下文 + 建议 search 块
|
|
20
|
+
- search 为空、结果无变化(noop)、文件过大均会拒绝
|
|
21
|
+
|
|
22
|
+
**最佳实践(强烈推荐给 LLM)**:
|
|
23
|
+
- 使用包含周围几行的较大唯一块作为 search,而不是孤立的一行。
|
|
24
|
+
- 复制时务必 100% 精确,包括所有空白和换行。
|
|
25
|
+
- 不确定时,先调用 read 工具获取文件精确内容片段再构造 patch。
|
|
26
|
+
- 可用 dry_run=true 先预览 unified diff。`,
|
|
27
|
+
parameters: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
path: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Absolute or relative path to the target file",
|
|
33
|
+
},
|
|
34
|
+
chunks: {
|
|
35
|
+
type: "array",
|
|
36
|
+
items: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
search: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "The exact block of code to search for, including leading indent and whitespace",
|
|
42
|
+
},
|
|
43
|
+
replace: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "The code to replace it with",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ["search", "replace"],
|
|
49
|
+
},
|
|
50
|
+
description: "List of replacement chunks to apply in sequence",
|
|
51
|
+
},
|
|
52
|
+
dry_run: {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
description: "If true, validate and return unified diff without writing the file",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ["path", "chunks"],
|
|
58
|
+
},
|
|
59
|
+
paramSchema: {
|
|
60
|
+
path: {
|
|
61
|
+
type: "string",
|
|
62
|
+
description: "目标文件路径。相对路径以工作区为基准。",
|
|
63
|
+
minLength: 1,
|
|
64
|
+
},
|
|
65
|
+
chunks: {
|
|
66
|
+
type: "array",
|
|
67
|
+
description: "需要依次执行的精准替换块列表。",
|
|
68
|
+
},
|
|
69
|
+
dry_run: {
|
|
70
|
+
type: "boolean",
|
|
71
|
+
description: "为 true 时只预览 diff,不写盘。",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
examples: [
|
|
75
|
+
'patch path="src/utils.ts" chunks=[{"search":"export const foo = 1;","replace":"export const foo = 2;"}]',
|
|
76
|
+
'patch path="src/utils.ts" dry_run=true chunks=[{"search":"a","replace":"b"}]',
|
|
77
|
+
],
|
|
78
|
+
seeAlso: ["read", "write"],
|
|
79
|
+
scenes: ["coding"],
|
|
80
|
+
priority: 10,
|
|
81
|
+
readOnly: false,
|
|
82
|
+
destructive: false,
|
|
83
|
+
concurrencySafe: false,
|
|
84
|
+
effortHint: "medium",
|
|
85
|
+
};
|
|
86
|
+
export function computeLineStats(originalContent, newContent) {
|
|
87
|
+
const originalLines = originalContent.split(/\r?\n/);
|
|
88
|
+
const newLines = newContent.split(/\r?\n/);
|
|
89
|
+
// 简化:按行集合差估算;用于摘要(非完美 LCS 统计)
|
|
90
|
+
let oi = 0;
|
|
91
|
+
let ni = 0;
|
|
92
|
+
let added = 0;
|
|
93
|
+
let removed = 0;
|
|
94
|
+
let unchanged = 0;
|
|
95
|
+
while (oi < originalLines.length && ni < newLines.length) {
|
|
96
|
+
if (originalLines[oi] === newLines[ni]) {
|
|
97
|
+
unchanged++;
|
|
98
|
+
oi++;
|
|
99
|
+
ni++;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// 贪心:优先认为是替换
|
|
103
|
+
const lookAhead = originalLines.indexOf(newLines[ni], oi + 1);
|
|
104
|
+
const lookBack = newLines.indexOf(originalLines[oi], ni + 1);
|
|
105
|
+
if (lookAhead !== -1 && (lookBack === -1 || lookAhead - oi <= lookBack - ni)) {
|
|
106
|
+
removed += lookAhead - oi;
|
|
107
|
+
oi = lookAhead;
|
|
108
|
+
}
|
|
109
|
+
else if (lookBack !== -1) {
|
|
110
|
+
added += lookBack - ni;
|
|
111
|
+
ni = lookBack;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
removed++;
|
|
115
|
+
added++;
|
|
116
|
+
oi++;
|
|
117
|
+
ni++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
removed += originalLines.length - oi;
|
|
121
|
+
added += newLines.length - ni;
|
|
122
|
+
return { added, removed, unchanged };
|
|
123
|
+
}
|
|
124
|
+
export async function runPatch(args) {
|
|
125
|
+
const inputPath = String(args.path ?? "").trim();
|
|
126
|
+
if (!inputPath) {
|
|
127
|
+
return toolError("PATCH_INVALID_PATH", "path is required");
|
|
128
|
+
}
|
|
129
|
+
const chunks = args.chunks;
|
|
130
|
+
if (!Array.isArray(chunks) || chunks.length === 0) {
|
|
131
|
+
return toolError("PATCH_INVALID_CHUNKS", "chunks must be a non-empty array");
|
|
132
|
+
}
|
|
133
|
+
const dryRun = args.dry_run === true || String(args.dryRun) === "true";
|
|
134
|
+
const roots = getRuntimeRootsFromEnv();
|
|
135
|
+
const resolvedPath = resolveToolPath(inputPath, roots, "workspace");
|
|
136
|
+
if (!isPathAllowedForWrite(resolvedPath, roots)) {
|
|
137
|
+
return toolError("PATCH_OUTSIDE_ALLOWED_ROOT", `${resolvedPath} is outside write sandbox (default: workspace only; set QLING_WRITE_SANDBOX=roots|off to relax)`);
|
|
138
|
+
}
|
|
139
|
+
const sensitive = checkSensitiveWriteTarget(resolvedPath);
|
|
140
|
+
if (sensitive?.blocked) {
|
|
141
|
+
return toolError(sensitive.code, sensitive.reason, { category: "permission" });
|
|
142
|
+
}
|
|
143
|
+
let originalContent;
|
|
144
|
+
try {
|
|
145
|
+
originalContent = await readFile(resolvedPath, "utf-8");
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
return toolError("PATCH_READ_FAILED", `failed to read file: ${getErrorMessage(err)}`);
|
|
149
|
+
}
|
|
150
|
+
const byteLength = Buffer.byteLength(originalContent, "utf-8");
|
|
151
|
+
if (byteLength > PATCH_MAX_FILE_BYTES) {
|
|
152
|
+
return toolError("PATCH_FILE_TOO_LARGE", `file is ${byteLength} bytes; max supported is ${PATCH_MAX_FILE_BYTES} bytes. Use write for large rewrites or split the file.`);
|
|
153
|
+
}
|
|
154
|
+
// Work with a copy/simulation to check all matches before writing
|
|
155
|
+
let currentContent = originalContent;
|
|
156
|
+
for (let idx = 0; idx < chunks.length; idx++) {
|
|
157
|
+
const chunk = chunks[idx];
|
|
158
|
+
const searchStr = chunk.search;
|
|
159
|
+
const replaceStr = chunk.replace;
|
|
160
|
+
if (searchStr === undefined || replaceStr === undefined) {
|
|
161
|
+
return toolError("PATCH_INVALID_CHUNK", `chunk at index ${idx} is missing search or replace field`);
|
|
162
|
+
}
|
|
163
|
+
if (searchStr === "") {
|
|
164
|
+
return toolError("PATCH_EMPTY_SEARCH", `chunk at index ${idx} has empty search; refusing ambiguous full-file match.`);
|
|
165
|
+
}
|
|
166
|
+
// Split content to search for occurrences
|
|
167
|
+
const occurrences = countOccurrences(currentContent, searchStr);
|
|
168
|
+
if (occurrences === 0) {
|
|
169
|
+
const ctx = getDiagnosticContext(currentContent, searchStr);
|
|
170
|
+
const suggestion = getSuggestedSearchBlock(currentContent, searchStr);
|
|
171
|
+
let msg = `Chunk index ${idx} search block was not found in the file. Please verify exact spelling, whitespace and indents.\n` +
|
|
172
|
+
`Tip: Use the "read" tool first to get exact text, then copy a unique block.\n` +
|
|
173
|
+
`Search block tried:\n"""\n${searchStr}\n"""\n\n` +
|
|
174
|
+
`Relevant context from file (line numbers):\n"""\n${ctx}\n"""`;
|
|
175
|
+
if (suggestion) {
|
|
176
|
+
msg += `\n\nSuggested exact block from file (copy/adapt this as your search):\n"""\n${suggestion}\n"""`;
|
|
177
|
+
}
|
|
178
|
+
return toolError("PATCH_SEARCH_NOT_FOUND", msg);
|
|
179
|
+
}
|
|
180
|
+
if (occurrences > 1) {
|
|
181
|
+
const ctx = getDiagnosticContext(currentContent, searchStr);
|
|
182
|
+
const suggestion = getSuggestedSearchBlock(currentContent, searchStr);
|
|
183
|
+
let msg = `Chunk index ${idx} search block matches ${occurrences} locations. Please provide more context lines to ensure uniqueness.\n` +
|
|
184
|
+
`Tip: Enlarge the search block with surrounding code until unique.\n` +
|
|
185
|
+
`Search block:\n"""\n${searchStr}\n"""\n\n` +
|
|
186
|
+
`Relevant context from file (line numbers):\n"""\n${ctx}\n"""`;
|
|
187
|
+
if (suggestion) {
|
|
188
|
+
msg += `\n\nSuggested unique block from file (use more context like this):\n"""\n${suggestion}\n"""`;
|
|
189
|
+
}
|
|
190
|
+
return toolError("PATCH_SEARCH_AMBIGUOUS", msg);
|
|
191
|
+
}
|
|
192
|
+
// Uniquely found, execute replacement in simulation
|
|
193
|
+
currentContent = currentContent.replace(searchStr, replaceStr);
|
|
194
|
+
}
|
|
195
|
+
if (currentContent === originalContent) {
|
|
196
|
+
return toolError("PATCH_NOOP", "all chunks applied but file content is unchanged (no-op). Refine search/replace or skip this patch.");
|
|
197
|
+
}
|
|
198
|
+
const workspaceDir = roots.workspaceDir ?? process.cwd();
|
|
199
|
+
const relFile = relative(workspaceDir, resolvedPath).replace(/\\/g, "/");
|
|
200
|
+
const stats = computeLineStats(originalContent, currentContent);
|
|
201
|
+
const diffText = generateUnifiedDiff(relFile, originalContent, currentContent);
|
|
202
|
+
const summary = `summary: chunks=${chunks.length} +${stats.added}/-${stats.removed} lines ` +
|
|
203
|
+
`(unchanged≈${stats.unchanged}) path=${relFile}`;
|
|
204
|
+
if (dryRun) {
|
|
205
|
+
return toolSuccess(`🔎 dry_run OK — would apply ${chunks.length} patch chunk(s) to ${resolvedPath}\n` +
|
|
206
|
+
`${summary}\n\n${diffText}\n\n(no file written)`);
|
|
207
|
+
}
|
|
208
|
+
// Write changes after all validations pass
|
|
209
|
+
try {
|
|
210
|
+
await writeFile(resolvedPath, currentContent, "utf-8");
|
|
211
|
+
return toolSuccess(`✅ Successfully applied ${chunks.length} patch chunk(s) to ${resolvedPath}\n` +
|
|
212
|
+
`${summary}\n\n${diffText}`);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
return toolError("PATCH_WRITE_FAILED", `failed to write file: ${getErrorMessage(err)}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function countOccurrences(text, searchStr) {
|
|
219
|
+
if (!searchStr)
|
|
220
|
+
return 0;
|
|
221
|
+
let count = 0;
|
|
222
|
+
let pos = text.indexOf(searchStr);
|
|
223
|
+
while (pos !== -1) {
|
|
224
|
+
count++;
|
|
225
|
+
pos = text.indexOf(searchStr, pos + searchStr.length);
|
|
226
|
+
}
|
|
227
|
+
return count;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* On failure, return a line-numbered snippet around likely matching areas.
|
|
231
|
+
* Helps the LLM construct a better exact search block (Aider-like experience).
|
|
232
|
+
*/
|
|
233
|
+
function getDiagnosticContext(content, searchStr, contextLines = 4) {
|
|
234
|
+
const lines = content.split(/\r?\n/);
|
|
235
|
+
if (lines.length === 0)
|
|
236
|
+
return '';
|
|
237
|
+
const searchLines = searchStr.split(/\r?\n/).filter(l => l.trim().length > 0);
|
|
238
|
+
const keyPhrase = searchLines[0]?.trim().slice(0, 40) || '';
|
|
239
|
+
const candidateIdxs = [];
|
|
240
|
+
// Try direct partial match on first significant line
|
|
241
|
+
if (keyPhrase) {
|
|
242
|
+
for (let i = 0; i < lines.length; i++) {
|
|
243
|
+
if (lines[i].includes(keyPhrase) || lines[i].trim() === keyPhrase) {
|
|
244
|
+
candidateIdxs.push(i);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Fallback: word based match for short unique words
|
|
249
|
+
if (candidateIdxs.length === 0) {
|
|
250
|
+
const words = keyPhrase.split(/\s+/).filter(w => w.length > 4);
|
|
251
|
+
for (let i = 0; i < lines.length; i++) {
|
|
252
|
+
if (words.some(w => lines[i].includes(w))) {
|
|
253
|
+
candidateIdxs.push(i);
|
|
254
|
+
if (candidateIdxs.length >= 3)
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (candidateIdxs.length === 0) {
|
|
260
|
+
// Last resort: head of file
|
|
261
|
+
const preview = lines.slice(0, 12).map((l, i) => `${i + 1}: ${l}`).join('\n');
|
|
262
|
+
return `File head preview:\n${preview}`;
|
|
263
|
+
}
|
|
264
|
+
const idx = candidateIdxs[0];
|
|
265
|
+
const start = Math.max(0, idx - contextLines);
|
|
266
|
+
const end = Math.min(lines.length, idx + contextLines + Math.max(1, searchLines.length));
|
|
267
|
+
let snippet = lines
|
|
268
|
+
.slice(start, end)
|
|
269
|
+
.map((l, j) => `${start + j + 1}: ${l}`)
|
|
270
|
+
.join('\n');
|
|
271
|
+
if (candidateIdxs.length > 1) {
|
|
272
|
+
snippet += `\n... (similar content also near lines: ${candidateIdxs.slice(1, 5).map(n => n + 1).join(', ')})`;
|
|
273
|
+
}
|
|
274
|
+
return snippet;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* 当搜索失败时,尝试找到文件中与 search 最接近的实际代码块,
|
|
278
|
+
* 并返回建议的精确 search 文本(带上下文)。
|
|
279
|
+
* 这能显著帮助 LLM 构造可工作的 patch(类似 Aider 的反馈)。
|
|
280
|
+
*/
|
|
281
|
+
function getSuggestedSearchBlock(content, searchStr, contextLines = 2) {
|
|
282
|
+
const lines = content.split(/\r?\n/);
|
|
283
|
+
if (lines.length === 0)
|
|
284
|
+
return null;
|
|
285
|
+
const searchTrimmed = searchStr.trim();
|
|
286
|
+
if (!searchTrimmed)
|
|
287
|
+
return null;
|
|
288
|
+
let bestScore = 0;
|
|
289
|
+
let bestIdx = -1;
|
|
290
|
+
const searchLines = searchStr.split(/\r?\n/).filter(l => l.trim().length > 0);
|
|
291
|
+
const searchWords = searchTrimmed.split(/\s+/).filter(w => w.length > 2);
|
|
292
|
+
const firstSearchLine = searchStr.split(/\r?\n/)[0]?.trim() || '';
|
|
293
|
+
for (let i = 0; i < lines.length; i++) {
|
|
294
|
+
const line = lines[i];
|
|
295
|
+
let score = 0;
|
|
296
|
+
if (firstSearchLine && line.includes(firstSearchLine.slice(0, 30))) {
|
|
297
|
+
score += 20;
|
|
298
|
+
}
|
|
299
|
+
score += searchWords.filter(w => line.includes(w)).length * 3;
|
|
300
|
+
// Bonus for multi-line searches if nearby lines match
|
|
301
|
+
if (searchStr.includes('\n')) {
|
|
302
|
+
const nextSearch = searchStr.split('\n')[1]?.trim();
|
|
303
|
+
if (nextSearch && i + 1 < lines.length && lines[i + 1].includes(nextSearch.slice(0, 20))) {
|
|
304
|
+
score += 15;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Deeper: consecutive line overlap score for better multi-line suggestion (Aider style)
|
|
308
|
+
let consecutive = 0;
|
|
309
|
+
for (let k = 0; k < searchLines.length && (i + k) < lines.length; k++) {
|
|
310
|
+
const sline = searchLines[k].trim().toLowerCase();
|
|
311
|
+
const aline = lines[i + k].trim().toLowerCase();
|
|
312
|
+
if (sline && (aline.includes(sline.slice(0, 20)) || sline.includes(aline.slice(0, 20)))) {
|
|
313
|
+
consecutive += 10;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
score += consecutive;
|
|
317
|
+
if (score > bestScore) {
|
|
318
|
+
bestScore = score;
|
|
319
|
+
bestIdx = i;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (bestIdx < 0 || bestScore < 4)
|
|
323
|
+
return null; // threshold to avoid bad suggestions
|
|
324
|
+
const start = Math.max(0, bestIdx - contextLines);
|
|
325
|
+
const end = Math.min(lines.length, bestIdx + contextLines + 2);
|
|
326
|
+
const block = lines.slice(start, end).join('\n');
|
|
327
|
+
return block;
|
|
328
|
+
}
|
|
329
|
+
export function generateUnifiedDiff(filePath, originalContent, newContent) {
|
|
330
|
+
const originalLines = originalContent.split(/\r?\n/);
|
|
331
|
+
const newLines = newContent.split(/\r?\n/);
|
|
332
|
+
const m = originalLines.length;
|
|
333
|
+
const n = newLines.length;
|
|
334
|
+
// Simple LCS DP table
|
|
335
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
336
|
+
for (let i = 1; i <= m; i++) {
|
|
337
|
+
for (let j = 1; j <= n; j++) {
|
|
338
|
+
if (originalLines[i - 1] === newLines[j - 1]) {
|
|
339
|
+
dp[i][j] = dp[i - 1][j - 1] + 1;
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const diff = [];
|
|
347
|
+
let i = m, j = n;
|
|
348
|
+
while (i > 0 || j > 0) {
|
|
349
|
+
if (i > 0 && j > 0 && originalLines[i - 1] === newLines[j - 1]) {
|
|
350
|
+
diff.push({
|
|
351
|
+
type: "same",
|
|
352
|
+
line: originalLines[i - 1],
|
|
353
|
+
originalLineNum: i,
|
|
354
|
+
newLineNum: j
|
|
355
|
+
});
|
|
356
|
+
i--;
|
|
357
|
+
j--;
|
|
358
|
+
}
|
|
359
|
+
else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
360
|
+
diff.push({
|
|
361
|
+
type: "add",
|
|
362
|
+
line: newLines[j - 1],
|
|
363
|
+
originalLineNum: -1,
|
|
364
|
+
newLineNum: j
|
|
365
|
+
});
|
|
366
|
+
j--;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
diff.push({
|
|
370
|
+
type: "delete",
|
|
371
|
+
line: originalLines[i - 1],
|
|
372
|
+
originalLineNum: i,
|
|
373
|
+
newLineNum: -1
|
|
374
|
+
});
|
|
375
|
+
i--;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
diff.reverse();
|
|
379
|
+
// Group diff items into hunks with context
|
|
380
|
+
const contextLines = 3;
|
|
381
|
+
const hunks = [];
|
|
382
|
+
let inHunk = false;
|
|
383
|
+
let hunkStart = -1;
|
|
384
|
+
let lastModifiedIdx = -1;
|
|
385
|
+
for (let idx = 0; idx < diff.length; idx++) {
|
|
386
|
+
const isMod = diff[idx].type !== "same";
|
|
387
|
+
if (isMod) {
|
|
388
|
+
if (!inHunk) {
|
|
389
|
+
inHunk = true;
|
|
390
|
+
hunkStart = Math.max(0, idx - contextLines);
|
|
391
|
+
}
|
|
392
|
+
lastModifiedIdx = idx;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
if (inHunk && idx - lastModifiedIdx > contextLines * 2) {
|
|
396
|
+
hunks.push({ start: hunkStart, end: lastModifiedIdx + contextLines });
|
|
397
|
+
inHunk = false;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (inHunk) {
|
|
402
|
+
hunks.push({ start: hunkStart, end: Math.min(diff.length - 1, lastModifiedIdx + contextLines) });
|
|
403
|
+
}
|
|
404
|
+
// Merge overlapping hunks
|
|
405
|
+
const mergedHunks = [];
|
|
406
|
+
for (const hunk of hunks) {
|
|
407
|
+
if (mergedHunks.length === 0) {
|
|
408
|
+
mergedHunks.push(hunk);
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
const prev = mergedHunks[mergedHunks.length - 1];
|
|
412
|
+
if (hunk.start <= prev.end) {
|
|
413
|
+
prev.end = Math.max(prev.end, hunk.end);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
mergedHunks.push(hunk);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// Format hunks into standard unified diff format
|
|
421
|
+
const result = [];
|
|
422
|
+
result.push(`--- ${filePath}`);
|
|
423
|
+
result.push(`+++ ${filePath}`);
|
|
424
|
+
for (const hunk of mergedHunks) {
|
|
425
|
+
const hunkSlice = diff.slice(hunk.start, hunk.end + 1);
|
|
426
|
+
const originalSlice = hunkSlice.filter(x => x.type !== "add");
|
|
427
|
+
const newSlice = hunkSlice.filter(x => x.type !== "delete");
|
|
428
|
+
const originalCount = originalSlice.length;
|
|
429
|
+
const newCount = newSlice.length;
|
|
430
|
+
let originalStart = 0;
|
|
431
|
+
if (originalCount > 0) {
|
|
432
|
+
originalStart = originalSlice[0].originalLineNum;
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
originalStart = hunk.start > 0 ? diff[hunk.start - 1].originalLineNum : 0;
|
|
436
|
+
}
|
|
437
|
+
let newStart = 0;
|
|
438
|
+
if (newCount > 0) {
|
|
439
|
+
newStart = newSlice[0].newLineNum;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
newStart = hunk.start > 0 ? diff[hunk.start - 1].newLineNum : 0;
|
|
443
|
+
}
|
|
444
|
+
result.push(`@@ -${originalStart},${originalCount} +${newStart},${newCount} @@`);
|
|
445
|
+
for (const item of hunkSlice) {
|
|
446
|
+
if (item.type === "same") {
|
|
447
|
+
result.push(` ${item.line}`);
|
|
448
|
+
}
|
|
449
|
+
else if (item.type === "add") {
|
|
450
|
+
result.push(`+${item.line}`);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
result.push(`-${item.line}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return result.join("\n");
|
|
458
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/tools/planner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,eAAO,MAAM,WAAW,EAAE,cA8DzB,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiCtB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// 轻灵 - planner 工具
|
|
3
|
+
// 任务规划与分解,生成结构化执行计划
|
|
4
|
+
// ============================================================
|
|
5
|
+
export const plannerTool = {
|
|
6
|
+
name: "planner",
|
|
7
|
+
description: "Create a structured execution plan for complex tasks. Breaks down a goal into ordered steps with status tracking. Does not execute anything — only plans.",
|
|
8
|
+
longDescription: `任务规划工具,将复杂目标分解为有序步骤。**不会执行任何操作**。
|
|
9
|
+
|
|
10
|
+
**使用场景**:
|
|
11
|
+
- 收到复杂任务时,先规划再执行
|
|
12
|
+
- 需要拆分子任务的场景(如多文件重构)
|
|
13
|
+
- 生成执行清单后逐步执行
|
|
14
|
+
|
|
15
|
+
**参数说明**:
|
|
16
|
+
- goal: 总体目标(一句话描述)
|
|
17
|
+
- steps: 步骤数组,每个步骤包含 description 和 priority
|
|
18
|
+
- 若不传 steps,则根据 goal 自动生成建议步骤
|
|
19
|
+
|
|
20
|
+
**输出**:
|
|
21
|
+
- 结构化计划,包含步骤编号、描述、优先级
|
|
22
|
+
- 可配合 todo 工具逐步跟踪执行`,
|
|
23
|
+
parameters: {
|
|
24
|
+
type: "object",
|
|
25
|
+
properties: {
|
|
26
|
+
goal: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Overall goal or task description",
|
|
29
|
+
},
|
|
30
|
+
steps: {
|
|
31
|
+
type: "array",
|
|
32
|
+
description: "Optional: array of step descriptions to organize into a plan",
|
|
33
|
+
items: {
|
|
34
|
+
type: "string",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ["goal"],
|
|
39
|
+
},
|
|
40
|
+
paramSchema: {
|
|
41
|
+
goal: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "总体目标描述。简洁说明要完成什么。",
|
|
44
|
+
minLength: 5,
|
|
45
|
+
},
|
|
46
|
+
steps: {
|
|
47
|
+
type: "array",
|
|
48
|
+
description: "可选:步骤描述数组。若不提供,会根据 goal 自动生成建议步骤。",
|
|
49
|
+
items: {
|
|
50
|
+
type: "string",
|
|
51
|
+
description: "单个步骤描述",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
examples: [
|
|
56
|
+
'planner goal="重构认证模块为 JWT"',
|
|
57
|
+
'planner goal="部署应用到生产环境" steps=["构建项目","运行测试","推送镜像","更新服务"]',
|
|
58
|
+
],
|
|
59
|
+
seeAlso: ["todo", "bash"],
|
|
60
|
+
scenes: ["planning"],
|
|
61
|
+
priority: 6,
|
|
62
|
+
readOnly: true,
|
|
63
|
+
destructive: false,
|
|
64
|
+
concurrencySafe: true,
|
|
65
|
+
effortHint: "minimal",
|
|
66
|
+
};
|
|
67
|
+
export async function runPlanner(args) {
|
|
68
|
+
const steps = args.steps;
|
|
69
|
+
if (steps && steps.length > 0) {
|
|
70
|
+
// User provided steps — organize them
|
|
71
|
+
const lines = steps.map((s, i) => {
|
|
72
|
+
const num = String(i + 1).padStart(2, " ");
|
|
73
|
+
return ` ${num}. ⬜ ${s}`;
|
|
74
|
+
});
|
|
75
|
+
const plan = [
|
|
76
|
+
`📋 执行计划: ${args.goal}`,
|
|
77
|
+
`─────────────────────────────`,
|
|
78
|
+
...lines,
|
|
79
|
+
`─────────────────────────────`,
|
|
80
|
+
`共 ${steps.length} 步。建议用 todo add 逐个添加后执行。`,
|
|
81
|
+
];
|
|
82
|
+
return { tool_call_id: "", output: plan.join("\n") };
|
|
83
|
+
}
|
|
84
|
+
// Auto-generate suggested steps based on goal analysis
|
|
85
|
+
const suggestions = generateSuggestions(args.goal);
|
|
86
|
+
const plan = [
|
|
87
|
+
`📋 执行计划: ${args.goal}`,
|
|
88
|
+
`─────────────────────────────`,
|
|
89
|
+
...suggestions.map((s, i) => {
|
|
90
|
+
const num = String(i + 1).padStart(2, " ");
|
|
91
|
+
return ` ${num}. ⬜ ${s}`;
|
|
92
|
+
}),
|
|
93
|
+
`─────────────────────────────`,
|
|
94
|
+
`建议: 用 todo add 将上述步骤添加到任务列表,然后逐步执行。`,
|
|
95
|
+
`也可直接补充步骤: planner goal="${args.goal}" steps=["步骤1","步骤2",...]`,
|
|
96
|
+
];
|
|
97
|
+
return { tool_call_id: "", output: plan.join("\n") };
|
|
98
|
+
}
|
|
99
|
+
function generateSuggestions(goal) {
|
|
100
|
+
const g = goal.toLowerCase();
|
|
101
|
+
const steps = [];
|
|
102
|
+
// Detect common task patterns
|
|
103
|
+
if (/重构|refactor|重写|rewrite/i.test(g)) {
|
|
104
|
+
steps.push("分析现有代码结构(read + search)");
|
|
105
|
+
steps.push("确定重构范围和影响面");
|
|
106
|
+
steps.push("编写重构方案(DESIGN.md)");
|
|
107
|
+
steps.push("逐步实施重构");
|
|
108
|
+
steps.push("运行测试验证");
|
|
109
|
+
steps.push("清理无用代码");
|
|
110
|
+
}
|
|
111
|
+
else if (/部署|deploy|发布|release/i.test(g)) {
|
|
112
|
+
steps.push("检查构建配置和环境变量");
|
|
113
|
+
steps.push("运行完整测试套件");
|
|
114
|
+
steps.push("构建生产版本");
|
|
115
|
+
steps.push("部署到目标环境");
|
|
116
|
+
steps.push("验证部署结果");
|
|
117
|
+
}
|
|
118
|
+
else if (/修复|fix|bug|错误/i.test(g)) {
|
|
119
|
+
steps.push("定位问题(read 相关文件 + 搜索错误信息)");
|
|
120
|
+
steps.push("分析根因");
|
|
121
|
+
steps.push("实施修复");
|
|
122
|
+
steps.push("编写或更新测试");
|
|
123
|
+
steps.push("验证修复");
|
|
124
|
+
}
|
|
125
|
+
else if (/添加|add|新增|feature|功能/i.test(g)) {
|
|
126
|
+
steps.push("理解需求和技术约束");
|
|
127
|
+
steps.push("设计实现方案");
|
|
128
|
+
steps.push("编写代码");
|
|
129
|
+
steps.push("编写测试");
|
|
130
|
+
steps.push("集成验证");
|
|
131
|
+
}
|
|
132
|
+
else if (/迁移|migrate|升级|upgrade/i.test(g)) {
|
|
133
|
+
steps.push("评估迁移范围和风险");
|
|
134
|
+
steps.push("制定迁移计划");
|
|
135
|
+
steps.push("执行迁移(分批)");
|
|
136
|
+
steps.push("测试兼容性");
|
|
137
|
+
steps.push("清理旧版本依赖");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// Generic fallback
|
|
141
|
+
steps.push("明确任务需求和约束");
|
|
142
|
+
steps.push("搜索和阅读相关文件");
|
|
143
|
+
steps.push("制定执行步骤");
|
|
144
|
+
steps.push("逐步实施");
|
|
145
|
+
steps.push("验证结果");
|
|
146
|
+
}
|
|
147
|
+
return steps;
|
|
148
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQzD,eAAO,MAAM,QAAQ,EAAE,cA+DtB,CAAC;AAEF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,UAAU,CAAC,CA+CtB"}
|