@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/dist/agent/agent-definition-registry.d.ts +21 -3
- package/dist/agent/agent-definition-registry.js +49 -18
- package/dist/agent/agent-definition.d.ts +32 -0
- package/dist/agent/agent-definition.js +49 -4
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +47 -6
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -51
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +41 -0
- package/dist/automation/cron-expr.js +169 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +84 -0
- package/dist/automation/runner.js +92 -0
- package/dist/automation/scheduler.d.ts +194 -0
- package/dist/automation/scheduler.js +623 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +122 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +64 -0
- package/dist/capability-control/overlay.js +116 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
- package/dist/cc-orchestrator/agent-adapter.js +133 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
- package/dist/cc-orchestrator/cc-capability.js +53 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
- package/dist/cc-orchestrator/codex-session-history.js +187 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +214 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
- package/dist/cc-orchestrator/external-agent-driver.js +69 -0
- package/dist/cc-orchestrator/index.d.ts +8 -0
- package/dist/cc-orchestrator/index.js +8 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
- package/dist/cc-orchestrator/relevance-judge.js +29 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
- package/dist/cc-orchestrator/session-discovery.js +125 -0
- package/dist/cc-orchestrator/session-history.d.ts +19 -0
- package/dist/cc-orchestrator/session-history.js +67 -0
- package/dist/cli/agent-server-stdio.d.ts +26 -1
- package/dist/cli/agent-server-stdio.js +221 -28
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +134 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.d.ts +56 -0
- package/dist/context/compaction.js +209 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +25 -41
- package/dist/cost-tracker.js +5 -61
- package/dist/credentials/cipher.d.ts +49 -0
- package/dist/credentials/cipher.js +45 -0
- package/dist/credentials/cookie-jar.d.ts +24 -0
- package/dist/credentials/cookie-jar.js +40 -0
- package/dist/credentials/index.d.ts +7 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/inject-credential-tool.d.ts +20 -0
- package/dist/credentials/inject-credential-tool.js +130 -0
- package/dist/credentials/store.d.ts +72 -0
- package/dist/credentials/store.js +184 -0
- package/dist/credentials/types.d.ts +56 -0
- package/dist/credentials/use-credential-tool.d.ts +29 -0
- package/dist/credentials/use-credential-tool.js +205 -0
- package/dist/credentials/use-gate.d.ts +56 -0
- package/dist/credentials/use-gate.js +52 -0
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/model-metadata.d.ts +77 -0
- package/dist/data/model-metadata.js +56 -0
- package/dist/data/model-metadata.json +216 -0
- package/dist/data/openrouter-models.d.ts +18 -7
- package/dist/data/openrouter-models.js +35 -8
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/aux-key.d.ts +10 -0
- package/dist/engine/aux-key.js +11 -0
- package/dist/engine/dynamic-tool-defs.d.ts +19 -0
- package/dist/engine/dynamic-tool-defs.js +36 -0
- package/dist/engine/engine.d.ts +431 -108
- package/dist/engine/engine.js +1630 -279
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +187 -0
- package/dist/engine/goal.js +196 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +165 -0
- package/dist/engine/image-policy.js +189 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +66 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +25 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.js +9 -1
- package/dist/engine/sandbox-cache-key.d.ts +10 -0
- package/dist/engine/sandbox-cache-key.js +9 -0
- package/dist/engine/sandbox-config.d.ts +31 -0
- package/dist/engine/sandbox-config.js +38 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/session-usage.d.ts +19 -0
- package/dist/engine/session-usage.js +25 -0
- package/dist/engine/steer-queue.d.ts +32 -0
- package/dist/engine/steer-queue.js +26 -0
- package/dist/engine/streaming-tool-queue.d.ts +12 -0
- package/dist/engine/streaming-tool-queue.js +50 -10
- package/dist/engine/turn-loop.d.ts +94 -9
- package/dist/engine/turn-loop.js +775 -342
- package/dist/engine/types.d.ts +175 -0
- package/dist/engine/types.js +13 -0
- package/dist/external-agents/config.d.ts +2 -0
- package/dist/external-agents/config.js +15 -0
- package/dist/external-agents/types.d.ts +31 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +62 -26
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +111 -20
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +58 -0
- package/dist/hooks/goal-stop-hook.js +279 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +57 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +48 -18
- package/dist/index.d.ts +79 -11
- package/dist/index.js +89 -6
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +37 -3
- package/dist/llm/capabilities/types.d.ts +32 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +69 -5
- package/dist/llm/client-base.js +185 -25
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +29 -11
- package/dist/llm/model-pool.js +36 -20
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +6 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +207 -18
- package/dist/llm/providers/openai.d.ts +47 -2
- package/dist/llm/providers/openai.js +478 -71
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +40 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +9 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +112 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +42 -11
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +407 -0
- package/dist/model-catalog/gen-connections.d.ts +20 -0
- package/dist/model-catalog/gen-connections.js +28 -0
- package/dist/model-catalog/index.d.ts +41 -0
- package/dist/model-catalog/index.js +90 -0
- package/dist/model-catalog/params.d.ts +20 -0
- package/dist/model-catalog/params.js +45 -0
- package/dist/model-catalog/resolve.d.ts +48 -0
- package/dist/model-catalog/resolve.js +33 -0
- package/dist/model-catalog/save-entry.d.ts +32 -0
- package/dist/model-catalog/save-entry.js +104 -0
- package/dist/model-catalog/types.d.ts +561 -0
- package/dist/model-catalog/types.js +93 -0
- package/dist/model-catalog/upsert.d.ts +9 -0
- package/dist/model-catalog/upsert.js +8 -0
- package/dist/onboarding.d.ts +12 -82
- package/dist/onboarding.js +75 -333
- package/dist/plugins/gitOps.d.ts +53 -0
- package/dist/plugins/gitOps.js +130 -5
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -0
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
- package/dist/plugins/installer/codex/convertCommands.js +46 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
- package/dist/plugins/installer/codex/convertMcp.js +85 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +123 -0
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +51 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +27 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
- package/dist/plugins/installer/loadPluginMcp.js +107 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +52 -0
- package/dist/plugins/installer/types.js +28 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +18 -0
- package/dist/plugins/installer/unzip.d.ts +14 -0
- package/dist/plugins/installer/unzip.js +82 -0
- package/dist/plugins/installer/update.d.ts +28 -0
- package/dist/plugins/installer/update.js +97 -0
- package/dist/plugins/loadPluginHooks.d.ts +54 -1
- package/dist/plugins/loadPluginHooks.js +83 -1
- package/dist/plugins/marketplaceManager.d.ts +15 -1
- package/dist/plugins/marketplaceManager.js +58 -4
- package/dist/plugins/pluginCommandHook.js +34 -14
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +34 -0
- package/dist/plugins/pluginInstaller.js +168 -35
- package/dist/plugins/schemas.js +41 -6
- package/dist/plugins/types.d.ts +10 -0
- package/dist/preset/index.d.ts +7 -1
- package/dist/preset/index.js +112 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +31 -0
- package/dist/prompt/composer.js +95 -25
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +1 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +15 -2
- package/dist/protocol/chat-session-manager.js +46 -0
- package/dist/protocol/chat-session.d.ts +82 -0
- package/dist/protocol/chat-session.js +121 -1
- package/dist/protocol/client.d.ts +27 -0
- package/dist/protocol/client.js +38 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +153 -2
- package/dist/protocol/server.js +807 -39
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +69 -0
- package/dist/protocol/types.js +22 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +155 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +40 -11
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +86 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +8 -1
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +495 -0
- package/dist/runtime/output-clean.d.ts +24 -0
- package/dist/runtime/output-clean.js +41 -0
- package/dist/runtime/ring-file.d.ts +64 -0
- package/dist/runtime/ring-file.js +174 -0
- package/dist/runtime/safe-spawn.js +15 -34
- package/dist/runtime/spawn-common.d.ts +148 -0
- package/dist/runtime/spawn-common.js +303 -0
- package/dist/runtime/truncate-output.d.ts +22 -0
- package/dist/runtime/truncate-output.js +49 -0
- package/dist/runtime/utf8-cut.d.ts +11 -0
- package/dist/runtime/utf8-cut.js +23 -0
- package/dist/services/auto-dream.d.ts +4 -0
- package/dist/services/auto-dream.js +26 -26
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/extract-memories.d.ts +14 -1
- package/dist/services/extract-memories.js +45 -6
- package/dist/services/memory-orchestrator.d.ts +21 -0
- package/dist/services/memory-orchestrator.js +125 -32
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +30 -19
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +232 -9
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +63 -1
- package/dist/session/session-manager.js +186 -5
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +25 -1
- package/dist/session/transcript.js +35 -2
- package/dist/session/undo-target.d.ts +67 -0
- package/dist/session/undo-target.js +144 -0
- package/dist/settings/disk-defaults.d.ts +42 -0
- package/dist/settings/disk-defaults.js +33 -0
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +101 -1
- package/dist/settings/manager.js +345 -15
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1827 -396
- package/dist/settings/schema.js +361 -81
- package/dist/skills/scanner.d.ts +9 -0
- package/dist/skills/scanner.js +30 -2
- package/dist/stt/resolve-transcribe.d.ts +31 -0
- package/dist/stt/resolve-transcribe.js +108 -0
- package/dist/stt/transcribe.d.ts +51 -0
- package/dist/stt/transcribe.js +65 -0
- package/dist/tool-system/browser-bridge.d.ts +226 -0
- package/dist/tool-system/browser-bridge.js +163 -0
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
- package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
- package/dist/tool-system/builtin/agent-notifications.js +9 -3
- package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
- package/dist/tool-system/builtin/agent-output-file.js +72 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
- package/dist/tool-system/builtin/agent-registry.js +16 -4
- package/dist/tool-system/builtin/agent.d.ts +50 -11
- package/dist/tool-system/builtin/agent.js +576 -73
- package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
- package/dist/tool-system/builtin/apply-patch/index.js +7 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
- package/dist/tool-system/builtin/background-jobs.js +124 -0
- package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
- package/dist/tool-system/builtin/background-shell-tools.js +108 -0
- package/dist/tool-system/builtin/background-work.d.ts +67 -0
- package/dist/tool-system/builtin/background-work.js +86 -0
- package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
- package/dist/tool-system/builtin/bash-output-style.js +40 -0
- package/dist/tool-system/builtin/bash.d.ts +5 -2
- package/dist/tool-system/builtin/bash.js +98 -62
- package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
- package/dist/tool-system/builtin/browser-tools.js +312 -0
- package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
- package/dist/tool-system/builtin/cancel-goal.js +64 -0
- package/dist/tool-system/builtin/check-quota.d.ts +15 -0
- package/dist/tool-system/builtin/check-quota.js +34 -0
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +105 -9
- package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
- package/dist/tool-system/builtin/drive-claude-code.js +157 -0
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +21 -12
- package/dist/tool-system/builtin/eol.d.ts +29 -0
- package/dist/tool-system/builtin/eol.js +37 -0
- package/dist/tool-system/builtin/file-cache.d.ts +6 -0
- package/dist/tool-system/builtin/file-cache.js +8 -0
- package/dist/tool-system/builtin/generate-image.d.ts +60 -0
- package/dist/tool-system/builtin/generate-image.js +374 -0
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +361 -0
- package/dist/tool-system/builtin/grep.js +6 -2
- package/dist/tool-system/builtin/image-providers.d.ts +86 -0
- package/dist/tool-system/builtin/image-providers.js +190 -0
- package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
- package/dist/tool-system/builtin/image-uploader.js +74 -0
- package/dist/tool-system/builtin/index.d.ts +24 -1
- package/dist/tool-system/builtin/index.js +310 -25
- package/dist/tool-system/builtin/mcp-tools.js +23 -3
- package/dist/tool-system/builtin/memory.js +45 -7
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +1 -1
- package/dist/tool-system/builtin/powershell.js +4 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +11 -3
- package/dist/tool-system/builtin/repl.js +4 -1
- package/dist/tool-system/builtin/skill.js +9 -0
- package/dist/tool-system/builtin/sleep.js +12 -5
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/tool-search.js +25 -7
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/video-providers.d.ts +154 -0
- package/dist/tool-system/builtin/video-providers.js +235 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +57 -10
- package/dist/tool-system/builtin/worktree.d.ts +2 -1
- package/dist/tool-system/builtin/worktree.js +31 -4
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +1 -1
- package/dist/tool-system/context.d.ts +166 -6
- package/dist/tool-system/executor.d.ts +3 -2
- package/dist/tool-system/executor.js +197 -119
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +20 -4
- package/dist/tool-system/mcp-manager.d.ts +78 -16
- package/dist/tool-system/mcp-manager.js +357 -28
- package/dist/tool-system/path-policy.d.ts +99 -0
- package/dist/tool-system/path-policy.js +578 -0
- package/dist/tool-system/permission.d.ts +36 -1
- package/dist/tool-system/permission.js +322 -117
- package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
- package/dist/tool-system/plan-mode-allowlist.js +65 -0
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +26 -1
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +301 -15
- package/dist/updater.js +20 -9
- package/dist/utils/envUtils.d.ts +0 -9
- package/dist/utils/envUtils.js +3 -28
- package/dist/utils/exec.d.ts +40 -0
- package/dist/utils/exec.js +144 -0
- package/dist/utils/format.js +4 -2
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +7 -1
- package/dist/utils/theme.js +5 -3
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +14 -7
- package/dist/agent/coordinator.d.ts +0 -49
- package/dist/agent/coordinator.js +0 -77
- package/dist/settings/manager.test.js +0 -73
- package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
- package/dist/tool-system/builtin/remote-trigger.js +0 -54
- package/dist/tool-system/builtin/send-message.d.ts +0 -6
- package/dist/tool-system/builtin/send-message.js +0 -47
- /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
|
@@ -6,21 +6,28 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import { userHome } from "../settings/manager.js";
|
|
10
|
+
import { sortSessionMemoriesByRecency } from "./session-memory-sort.js";
|
|
11
|
+
// Resolve per-call (NOT a module const): userHome() reads $HOME live, so a
|
|
12
|
+
// relocated/test HOME redirects writes instead of pinning the real ~/.code-shell
|
|
13
|
+
// at import time (bun freezes a module-level homedir() and never re-reads it).
|
|
14
|
+
function memoryDir() {
|
|
15
|
+
return join(userHome(), ".code-shell", "session-memories");
|
|
16
|
+
}
|
|
11
17
|
/**
|
|
12
18
|
* Save a session memory entry.
|
|
13
19
|
*/
|
|
14
20
|
export function saveSessionMemory(entry) {
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
const dir = memoryDir();
|
|
22
|
+
mkdirSync(dir, { recursive: true });
|
|
23
|
+
const file = join(dir, `${entry.sessionId}.json`);
|
|
17
24
|
writeFileSync(file, JSON.stringify(entry, null, 2), "utf-8");
|
|
18
25
|
}
|
|
19
26
|
/**
|
|
20
27
|
* Load a session memory by session ID.
|
|
21
28
|
*/
|
|
22
29
|
export function loadSessionMemory(sessionId) {
|
|
23
|
-
const file = join(
|
|
30
|
+
const file = join(memoryDir(), `${sessionId}.json`);
|
|
24
31
|
if (!existsSync(file))
|
|
25
32
|
return null;
|
|
26
33
|
try {
|
|
@@ -34,22 +41,24 @@ export function loadSessionMemory(sessionId) {
|
|
|
34
41
|
* List all session memories, most recent first.
|
|
35
42
|
*/
|
|
36
43
|
export function listSessionMemories(limit = 50) {
|
|
37
|
-
|
|
44
|
+
const dir = memoryDir();
|
|
45
|
+
if (!existsSync(dir))
|
|
38
46
|
return [];
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.sort()
|
|
42
|
-
.reverse()
|
|
43
|
-
.slice(0, limit);
|
|
47
|
+
// Read all entries, then order by createdAt (not by filename — the filename
|
|
48
|
+
// is the sessionId, which has no chronological meaning), then take `limit`.
|
|
44
49
|
const entries = [];
|
|
45
|
-
for (const file of
|
|
50
|
+
for (const file of readdirSync(dir)) {
|
|
51
|
+
if (!file.endsWith(".json"))
|
|
52
|
+
continue;
|
|
46
53
|
try {
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
entries.push(JSON.parse(readFileSync(join(dir, file), "utf-8")));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* intentional: skip a corrupt/torn memory file rather than failing the
|
|
58
|
+
whole listing — one bad entry must not hide all the others. */
|
|
49
59
|
}
|
|
50
|
-
catch { }
|
|
51
60
|
}
|
|
52
|
-
return entries;
|
|
61
|
+
return sortSessionMemoriesByRecency(entries).slice(0, limit);
|
|
53
62
|
}
|
|
54
63
|
/**
|
|
55
64
|
* Search session memories by keyword.
|
|
@@ -72,10 +81,12 @@ export function buildSessionMemoryPrompt(messages) {
|
|
|
72
81
|
|
|
73
82
|
${text.slice(0, 30000)}
|
|
74
83
|
|
|
75
|
-
Respond with JSON
|
|
84
|
+
Respond with ONLY a single JSON object — no markdown code fence, no text before
|
|
85
|
+
or after. Keep every value on one line (escape any newline as \\n) and escape
|
|
86
|
+
any double quote inside a string as \\". Shape:
|
|
76
87
|
{
|
|
77
88
|
"summary": "One paragraph summarizing what was discussed and accomplished",
|
|
78
|
-
"keyTopics": ["topic1", "topic2"
|
|
79
|
-
"decisions": ["decision1", "decision2"
|
|
89
|
+
"keyTopics": ["topic1", "topic2"],
|
|
90
|
+
"decisions": ["decision1", "decision2"]
|
|
80
91
|
}`;
|
|
81
92
|
}
|
|
@@ -10,16 +10,84 @@ export interface FileSnapshot {
|
|
|
10
10
|
backupPath: string;
|
|
11
11
|
hash: string;
|
|
12
12
|
size: number;
|
|
13
|
+
/**
|
|
14
|
+
* The conversation turn (one user message = one turn) this snapshot was taken
|
|
15
|
+
* in. Powers turn-level undo (`latestTurnUndoTargets`). Optional so snapshots
|
|
16
|
+
* written before this feature still load; absent ones share the "undefined"
|
|
17
|
+
* bucket and degrade to whole-session undo.
|
|
18
|
+
*/
|
|
19
|
+
turnSeq?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Set when this turn has been undone (by `undoLatestTurn`). Undone turns are
|
|
22
|
+
* SKIPPED by undo target selection (so the next undo peels the prior turn)
|
|
23
|
+
* but kept on disk so the turn can be re-applied via `redoLatestTurn`. Cleared
|
|
24
|
+
* on redo. Replaces the earlier "delete on undo" approach so redo has material.
|
|
25
|
+
*/
|
|
26
|
+
undone?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Redo material captured when a turn is undone: the file's content AT THE TIME
|
|
30
|
+
* OF UNDO (i.e. the turn's result), so `redoLatestTurn` can re-apply it.
|
|
31
|
+
* Stored separately from `snapshots` so it never pollutes undo selection
|
|
32
|
+
* (latestUndoTarget / earliestSnapshotsPerFile / latestTurnUndoTargets).
|
|
33
|
+
*/
|
|
34
|
+
export interface RedoRecord {
|
|
35
|
+
filePath: string;
|
|
36
|
+
/** The turn this redo restores (matches the undone snapshots' turnSeq). */
|
|
37
|
+
turnSeq: number;
|
|
38
|
+
/** Backup of the post-turn content to re-apply on redo. */
|
|
39
|
+
backupPath: string;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the file EXISTED before this turn (had a pre-turn snapshot). False
|
|
42
|
+
* means the turn CREATED it — undo deleted it, so redo must recreate it (and
|
|
43
|
+
* conversely undo of a created file means "remove", handled by the caller).
|
|
44
|
+
*/
|
|
45
|
+
existedBefore: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Marks that a file was CREATED in a given turn (it did not exist before the
|
|
49
|
+
* turn's first edit). Recorded by `recordCreated` from the engine hook when the
|
|
50
|
+
* pre-edit `saveSnapshot` returns null (file absent). Drives the "undo deletes a
|
|
51
|
+
* newly-created file / redo recreates it" behaviour. Like snapshots, a created
|
|
52
|
+
* marker is flipped `undone` on undo and cleared on redo rather than deleted, so
|
|
53
|
+
* the create/delete can round-trip.
|
|
54
|
+
*/
|
|
55
|
+
export interface CreatedMarker {
|
|
56
|
+
filePath: string;
|
|
57
|
+
turnSeq: number;
|
|
58
|
+
undone?: boolean;
|
|
13
59
|
}
|
|
14
60
|
export declare class FileHistory {
|
|
15
61
|
private readonly historyDir;
|
|
16
62
|
private snapshots;
|
|
63
|
+
/**
|
|
64
|
+
* Redo material for undone turns, kept SEPARATE from `snapshots` so it never
|
|
65
|
+
* pollutes undo selection (latestTurnUndoTargets / earliestSnapshotsPerFile).
|
|
66
|
+
*/
|
|
67
|
+
private redoRecords;
|
|
68
|
+
/** Per-turn "this file was created" markers (see CreatedMarker). */
|
|
69
|
+
private created;
|
|
17
70
|
constructor(sessionDir: string);
|
|
18
71
|
/**
|
|
19
72
|
* Save a snapshot of a file before it is modified.
|
|
20
73
|
* Returns the snapshot record, or null if the file doesn't exist.
|
|
74
|
+
*
|
|
75
|
+
* `turnSeq` tags the snapshot with the current conversation turn so a later
|
|
76
|
+
* `/undo` can revert exactly the files that turn changed (see
|
|
77
|
+
* latestTurnUndoTargets). Omit it for callers without turn context.
|
|
78
|
+
*/
|
|
79
|
+
saveSnapshot(filePath: string, turnSeq?: number): FileSnapshot | null;
|
|
80
|
+
/**
|
|
81
|
+
* Record that `filePath` was CREATED in `turnSeq` — called by the engine hook
|
|
82
|
+
* when the pre-edit saveSnapshot returns null (file did not exist yet). Idempotent
|
|
83
|
+
* per (path, turn): a file built then edited again in the same turn is recorded
|
|
84
|
+
* once, so undo deletes it (rather than restoring an intra-turn snapshot). A
|
|
85
|
+
* marker already flipped `undone` from a prior undo is reused as-is (not
|
|
86
|
+
* re-armed) — only fresh turns create new markers.
|
|
21
87
|
*/
|
|
22
|
-
|
|
88
|
+
recordCreated(filePath: string, turnSeq: number): void;
|
|
89
|
+
/** Redo material captured by past undos (see RedoRecord). Returns a copy. */
|
|
90
|
+
getRedoRecords(): RedoRecord[];
|
|
23
91
|
/**
|
|
24
92
|
* Get all snapshots for a specific file.
|
|
25
93
|
*/
|
|
@@ -36,6 +104,61 @@ export declare class FileHistory {
|
|
|
36
104
|
* Get all tracked files.
|
|
37
105
|
*/
|
|
38
106
|
getTrackedFiles(): string[];
|
|
107
|
+
/**
|
|
108
|
+
* Restore EVERY tracked file to its earliest snapshot — the state before the
|
|
109
|
+
* first AI edit this session. Powers `/undo all`. Targets are computed up
|
|
110
|
+
* front (restore() appends a new snapshot, so reading them lazily mid-loop
|
|
111
|
+
* would be unstable). Returns a per-file result so a partial failure doesn't
|
|
112
|
+
* hide which files reverted.
|
|
113
|
+
*/
|
|
114
|
+
restoreAllToEarliest(): Array<{
|
|
115
|
+
filePath: string;
|
|
116
|
+
ok: boolean;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Capture the file's CURRENT on-disk content into a fresh redo backup and
|
|
120
|
+
* append a RedoRecord. `existedBefore` distinguishes a modified file (true,
|
|
121
|
+
* redo re-applies content) from a turn-created file (false, redo recreates it).
|
|
122
|
+
* Returns false if the file can't be read (then no record is added).
|
|
123
|
+
*/
|
|
124
|
+
private captureRedoBackup;
|
|
125
|
+
/**
|
|
126
|
+
* Turn-level undo: revert every file the most recent conversation turn changed
|
|
127
|
+
* back to its pre-turn state. Unlike the earlier "delete on undo" approach this
|
|
128
|
+
* now (a) captures the turn's RESULT as redo material so `redoLatestTurn` can
|
|
129
|
+
* re-apply it, and (b) MARKS the turn's snapshots `undone` rather than deleting
|
|
130
|
+
* them — `latestTurnUndoTargets` skips undone turns, so a subsequent `/undo`
|
|
131
|
+
* still peels the previous turn ("onion"). Powers `/undo`.
|
|
132
|
+
*
|
|
133
|
+
* Files the turn CREATED (recorded via recordCreated) are DELETED on undo (with
|
|
134
|
+
* existedBefore:false redo material) instead of restored. `targets` come from
|
|
135
|
+
* latestTurnUndoTargets so preview and restore agree. Returns per-file results.
|
|
136
|
+
*/
|
|
137
|
+
undoLatestTurn(targets: FileSnapshot[]): Array<{
|
|
138
|
+
filePath: string;
|
|
139
|
+
ok: boolean;
|
|
140
|
+
}>;
|
|
141
|
+
/** Greatest turnSeq among not-yet-undone created markers, or undefined. */
|
|
142
|
+
private latestLiveCreatedTurn;
|
|
143
|
+
/**
|
|
144
|
+
* Turn-level redo: re-apply a previously undone turn. For each redo target,
|
|
145
|
+
* write the stashed post-turn content back to disk (existedBefore:false
|
|
146
|
+
* records RECREATE a turn-created file). Then clear the `undone` flags on that
|
|
147
|
+
* turn's snapshots and created markers, and drop the consumed redo records.
|
|
148
|
+
*
|
|
149
|
+
* `redoTargets` come from latestRedoTargets (which guarantees they are the
|
|
150
|
+
* latest still-undone turn). Returns per-file results.
|
|
151
|
+
*/
|
|
152
|
+
redoLatestTurn(redoTargets: RedoRecord[]): Array<{
|
|
153
|
+
filePath: string;
|
|
154
|
+
ok: boolean;
|
|
155
|
+
}>;
|
|
156
|
+
/**
|
|
157
|
+
* All snapshots in record (chronological) order. Used by undo to pick the
|
|
158
|
+
* single most-recent modification across every file (see latestUndoTarget).
|
|
159
|
+
* Returns a copy so callers can't mutate the internal list.
|
|
160
|
+
*/
|
|
161
|
+
getAllSnapshots(): FileSnapshot[];
|
|
39
162
|
private saveIndex;
|
|
40
163
|
static loadFromDir(sessionDir: string): FileHistory;
|
|
41
164
|
}
|
|
@@ -4,12 +4,20 @@
|
|
|
4
4
|
* Stores snapshots in the session directory under file-history/.
|
|
5
5
|
* Supports restoring files to a previous state.
|
|
6
6
|
*/
|
|
7
|
-
import { mkdirSync, existsSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
|
|
7
|
+
import { mkdirSync, existsSync, readFileSync, writeFileSync, copyFileSync, rmSync, } from "node:fs";
|
|
8
8
|
import { join, resolve } from "node:path";
|
|
9
9
|
import { createHash } from "node:crypto";
|
|
10
|
+
import { earliestSnapshotsPerFile } from "./undo-target.js";
|
|
10
11
|
export class FileHistory {
|
|
11
12
|
historyDir;
|
|
12
13
|
snapshots = [];
|
|
14
|
+
/**
|
|
15
|
+
* Redo material for undone turns, kept SEPARATE from `snapshots` so it never
|
|
16
|
+
* pollutes undo selection (latestTurnUndoTargets / earliestSnapshotsPerFile).
|
|
17
|
+
*/
|
|
18
|
+
redoRecords = [];
|
|
19
|
+
/** Per-turn "this file was created" markers (see CreatedMarker). */
|
|
20
|
+
created = [];
|
|
13
21
|
constructor(sessionDir) {
|
|
14
22
|
this.historyDir = join(sessionDir, "file-history");
|
|
15
23
|
mkdirSync(this.historyDir, { recursive: true });
|
|
@@ -17,22 +25,36 @@ export class FileHistory {
|
|
|
17
25
|
/**
|
|
18
26
|
* Save a snapshot of a file before it is modified.
|
|
19
27
|
* Returns the snapshot record, or null if the file doesn't exist.
|
|
28
|
+
*
|
|
29
|
+
* `turnSeq` tags the snapshot with the current conversation turn so a later
|
|
30
|
+
* `/undo` can revert exactly the files that turn changed (see
|
|
31
|
+
* latestTurnUndoTargets). Omit it for callers without turn context.
|
|
20
32
|
*/
|
|
21
|
-
saveSnapshot(filePath) {
|
|
33
|
+
saveSnapshot(filePath, turnSeq) {
|
|
22
34
|
const absPath = resolve(filePath);
|
|
23
35
|
if (!existsSync(absPath))
|
|
24
36
|
return null;
|
|
25
37
|
try {
|
|
26
38
|
const content = readFileSync(absPath);
|
|
27
39
|
const hash = createHash("md5").update(content).digest("hex");
|
|
28
|
-
// Check if we already have this exact
|
|
29
|
-
|
|
40
|
+
// Check if we already have this exact (path, content) for this turn. Dedup
|
|
41
|
+
// is per-turn: the same content re-snapshotted in a later turn is a real
|
|
42
|
+
// new pre-turn baseline and must be recorded, or turn-level undo would
|
|
43
|
+
// miss it. Within a turn, re-snapshotting unchanged content is a no-op.
|
|
44
|
+
const existing = this.snapshots.find((s) => s.filePath === absPath && s.hash === hash && s.turnSeq === turnSeq);
|
|
30
45
|
if (existing)
|
|
31
46
|
return existing;
|
|
32
|
-
// Create backup
|
|
47
|
+
// Create backup. The filename must uniquely identify (path, content): a
|
|
48
|
+
// bare 100-char tail of the path can collide for two different files
|
|
49
|
+
// whose tails coincide, and with the same ms timestamp the second
|
|
50
|
+
// copyFileSync would silently overwrite the first backup while both
|
|
51
|
+
// index entries point to it (restore would then return the wrong file's
|
|
52
|
+
// content). Fold a full-path hash and the content hash into the name so
|
|
53
|
+
// distinct (path, content) pairs never share a backup file.
|
|
33
54
|
const timestamp = Date.now();
|
|
34
|
-
const
|
|
35
|
-
const
|
|
55
|
+
const pathHash = createHash("md5").update(absPath).digest("hex").slice(0, 8);
|
|
56
|
+
const safeName = absPath.replace(/[/\\:]/g, "_").slice(-80);
|
|
57
|
+
const backupPath = join(this.historyDir, `${timestamp}_${pathHash}_${hash.slice(0, 8)}_${safeName}`);
|
|
36
58
|
copyFileSync(absPath, backupPath);
|
|
37
59
|
const snapshot = {
|
|
38
60
|
filePath: absPath,
|
|
@@ -40,6 +62,7 @@ export class FileHistory {
|
|
|
40
62
|
backupPath,
|
|
41
63
|
hash,
|
|
42
64
|
size: content.length,
|
|
65
|
+
...(turnSeq === undefined ? {} : { turnSeq }),
|
|
43
66
|
};
|
|
44
67
|
this.snapshots.push(snapshot);
|
|
45
68
|
// Write index
|
|
@@ -50,6 +73,26 @@ export class FileHistory {
|
|
|
50
73
|
return null;
|
|
51
74
|
}
|
|
52
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Record that `filePath` was CREATED in `turnSeq` — called by the engine hook
|
|
78
|
+
* when the pre-edit saveSnapshot returns null (file did not exist yet). Idempotent
|
|
79
|
+
* per (path, turn): a file built then edited again in the same turn is recorded
|
|
80
|
+
* once, so undo deletes it (rather than restoring an intra-turn snapshot). A
|
|
81
|
+
* marker already flipped `undone` from a prior undo is reused as-is (not
|
|
82
|
+
* re-armed) — only fresh turns create new markers.
|
|
83
|
+
*/
|
|
84
|
+
recordCreated(filePath, turnSeq) {
|
|
85
|
+
const absPath = resolve(filePath);
|
|
86
|
+
const existing = this.created.find((c) => c.filePath === absPath && c.turnSeq === turnSeq);
|
|
87
|
+
if (existing)
|
|
88
|
+
return;
|
|
89
|
+
this.created.push({ filePath: absPath, turnSeq });
|
|
90
|
+
this.saveIndex();
|
|
91
|
+
}
|
|
92
|
+
/** Redo material captured by past undos (see RedoRecord). Returns a copy. */
|
|
93
|
+
getRedoRecords() {
|
|
94
|
+
return [...this.redoRecords];
|
|
95
|
+
}
|
|
53
96
|
/**
|
|
54
97
|
* Get all snapshots for a specific file.
|
|
55
98
|
*/
|
|
@@ -90,10 +133,180 @@ export class FileHistory {
|
|
|
90
133
|
getTrackedFiles() {
|
|
91
134
|
return [...new Set(this.snapshots.map((s) => s.filePath))];
|
|
92
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Restore EVERY tracked file to its earliest snapshot — the state before the
|
|
138
|
+
* first AI edit this session. Powers `/undo all`. Targets are computed up
|
|
139
|
+
* front (restore() appends a new snapshot, so reading them lazily mid-loop
|
|
140
|
+
* would be unstable). Returns a per-file result so a partial failure doesn't
|
|
141
|
+
* hide which files reverted.
|
|
142
|
+
*/
|
|
143
|
+
restoreAllToEarliest() {
|
|
144
|
+
const targets = earliestSnapshotsPerFile(this.snapshots);
|
|
145
|
+
return targets.map((snap) => ({ filePath: snap.filePath, ok: this.restore(snap) }));
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Capture the file's CURRENT on-disk content into a fresh redo backup and
|
|
149
|
+
* append a RedoRecord. `existedBefore` distinguishes a modified file (true,
|
|
150
|
+
* redo re-applies content) from a turn-created file (false, redo recreates it).
|
|
151
|
+
* Returns false if the file can't be read (then no record is added).
|
|
152
|
+
*/
|
|
153
|
+
captureRedoBackup(filePath, turnSeq, existedBefore) {
|
|
154
|
+
try {
|
|
155
|
+
if (!existsSync(filePath))
|
|
156
|
+
return false;
|
|
157
|
+
const content = readFileSync(filePath);
|
|
158
|
+
const hash = createHash("md5").update(content).digest("hex");
|
|
159
|
+
const timestamp = Date.now();
|
|
160
|
+
const pathHash = createHash("md5").update(filePath).digest("hex").slice(0, 8);
|
|
161
|
+
const safeName = filePath.replace(/[/\\:]/g, "_").slice(-80);
|
|
162
|
+
const backupPath = join(this.historyDir, `redo_${timestamp}_${pathHash}_${hash.slice(0, 8)}_${safeName}`);
|
|
163
|
+
copyFileSync(filePath, backupPath);
|
|
164
|
+
this.redoRecords.push({ filePath, turnSeq, backupPath, existedBefore });
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Turn-level undo: revert every file the most recent conversation turn changed
|
|
173
|
+
* back to its pre-turn state. Unlike the earlier "delete on undo" approach this
|
|
174
|
+
* now (a) captures the turn's RESULT as redo material so `redoLatestTurn` can
|
|
175
|
+
* re-apply it, and (b) MARKS the turn's snapshots `undone` rather than deleting
|
|
176
|
+
* them — `latestTurnUndoTargets` skips undone turns, so a subsequent `/undo`
|
|
177
|
+
* still peels the previous turn ("onion"). Powers `/undo`.
|
|
178
|
+
*
|
|
179
|
+
* Files the turn CREATED (recorded via recordCreated) are DELETED on undo (with
|
|
180
|
+
* existedBefore:false redo material) instead of restored. `targets` come from
|
|
181
|
+
* latestTurnUndoTargets so preview and restore agree. Returns per-file results.
|
|
182
|
+
*/
|
|
183
|
+
undoLatestTurn(targets) {
|
|
184
|
+
// The turn being undone = the turnSeq shared by the targets (all from the
|
|
185
|
+
// same latest live turn). Created-only turns may have no snapshot targets, so
|
|
186
|
+
// fall back to the created markers' turn.
|
|
187
|
+
const undoneTurn = targets[0]?.turnSeq ?? this.latestLiveCreatedTurn();
|
|
188
|
+
if (undoneTurn === undefined)
|
|
189
|
+
return [];
|
|
190
|
+
const results = [];
|
|
191
|
+
// Files created this turn: delete them (after stashing redo material). Skip
|
|
192
|
+
// files that are also a restore target — created wins (the file didn't exist
|
|
193
|
+
// pre-turn, so its "pre-turn state" is "absent" → delete, not restore).
|
|
194
|
+
const createdThisTurn = this.created.filter((c) => !c.undone && c.turnSeq === undoneTurn);
|
|
195
|
+
const createdPaths = new Set(createdThisTurn.map((c) => c.filePath));
|
|
196
|
+
for (const c of createdThisTurn) {
|
|
197
|
+
this.captureRedoBackup(c.filePath, undoneTurn, false);
|
|
198
|
+
let ok = true;
|
|
199
|
+
try {
|
|
200
|
+
if (existsSync(c.filePath))
|
|
201
|
+
rmSync(c.filePath, { force: true });
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
ok = false;
|
|
205
|
+
}
|
|
206
|
+
results.push({ filePath: c.filePath, ok });
|
|
207
|
+
}
|
|
208
|
+
// Modified (pre-existing) files: stash the current result as redo material,
|
|
209
|
+
// then restore the pre-turn content.
|
|
210
|
+
for (const snap of targets) {
|
|
211
|
+
if (createdPaths.has(snap.filePath))
|
|
212
|
+
continue;
|
|
213
|
+
this.captureRedoBackup(snap.filePath, undoneTurn, true);
|
|
214
|
+
results.push({ filePath: snap.filePath, ok: this.restore(snap) });
|
|
215
|
+
}
|
|
216
|
+
// Mark the turn undone (snapshots + created markers) — keep them on disk so
|
|
217
|
+
// redo has material and the turn is re-applyable.
|
|
218
|
+
for (const s of this.snapshots) {
|
|
219
|
+
if (s.turnSeq === undoneTurn)
|
|
220
|
+
s.undone = true;
|
|
221
|
+
}
|
|
222
|
+
for (const c of this.created) {
|
|
223
|
+
if (c.turnSeq === undoneTurn)
|
|
224
|
+
c.undone = true;
|
|
225
|
+
}
|
|
226
|
+
this.saveIndex();
|
|
227
|
+
return results;
|
|
228
|
+
}
|
|
229
|
+
/** Greatest turnSeq among not-yet-undone created markers, or undefined. */
|
|
230
|
+
latestLiveCreatedTurn() {
|
|
231
|
+
let max;
|
|
232
|
+
for (const c of this.created) {
|
|
233
|
+
if (c.undone)
|
|
234
|
+
continue;
|
|
235
|
+
if (max === undefined || c.turnSeq > max)
|
|
236
|
+
max = c.turnSeq;
|
|
237
|
+
}
|
|
238
|
+
return max;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Turn-level redo: re-apply a previously undone turn. For each redo target,
|
|
242
|
+
* write the stashed post-turn content back to disk (existedBefore:false
|
|
243
|
+
* records RECREATE a turn-created file). Then clear the `undone` flags on that
|
|
244
|
+
* turn's snapshots and created markers, and drop the consumed redo records.
|
|
245
|
+
*
|
|
246
|
+
* `redoTargets` come from latestRedoTargets (which guarantees they are the
|
|
247
|
+
* latest still-undone turn). Returns per-file results.
|
|
248
|
+
*/
|
|
249
|
+
redoLatestTurn(redoTargets) {
|
|
250
|
+
if (redoTargets.length === 0)
|
|
251
|
+
return [];
|
|
252
|
+
const turn = redoTargets[0].turnSeq;
|
|
253
|
+
const results = redoTargets.map((rec) => {
|
|
254
|
+
let ok = false;
|
|
255
|
+
try {
|
|
256
|
+
if (existsSync(rec.backupPath)) {
|
|
257
|
+
copyFileSync(rec.backupPath, rec.filePath);
|
|
258
|
+
ok = true;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
ok = false;
|
|
263
|
+
}
|
|
264
|
+
return { filePath: rec.filePath, ok };
|
|
265
|
+
});
|
|
266
|
+
// Un-mark the turn: it is live again, so undo can re-target it.
|
|
267
|
+
for (const s of this.snapshots) {
|
|
268
|
+
if (s.turnSeq === turn)
|
|
269
|
+
s.undone = false;
|
|
270
|
+
}
|
|
271
|
+
for (const c of this.created) {
|
|
272
|
+
if (c.turnSeq === turn)
|
|
273
|
+
c.undone = false;
|
|
274
|
+
}
|
|
275
|
+
// Consume the redo records for this turn (and remove their backups).
|
|
276
|
+
const consumed = new Set(redoTargets);
|
|
277
|
+
this.redoRecords = this.redoRecords.filter((r) => {
|
|
278
|
+
if (consumed.has(r) || r.turnSeq === turn) {
|
|
279
|
+
try {
|
|
280
|
+
if (existsSync(r.backupPath))
|
|
281
|
+
rmSync(r.backupPath, { force: true });
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// best-effort cleanup
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
return true;
|
|
289
|
+
});
|
|
290
|
+
this.saveIndex();
|
|
291
|
+
return results;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* All snapshots in record (chronological) order. Used by undo to pick the
|
|
295
|
+
* single most-recent modification across every file (see latestUndoTarget).
|
|
296
|
+
* Returns a copy so callers can't mutate the internal list.
|
|
297
|
+
*/
|
|
298
|
+
getAllSnapshots() {
|
|
299
|
+
return [...this.snapshots];
|
|
300
|
+
}
|
|
93
301
|
saveIndex() {
|
|
94
302
|
try {
|
|
95
303
|
const indexPath = join(this.historyDir, "index.json");
|
|
96
|
-
|
|
304
|
+
const index = {
|
|
305
|
+
snapshots: this.snapshots,
|
|
306
|
+
redoRecords: this.redoRecords,
|
|
307
|
+
created: this.created,
|
|
308
|
+
};
|
|
309
|
+
writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
97
310
|
}
|
|
98
311
|
catch {
|
|
99
312
|
// Silent fail
|
|
@@ -104,7 +317,17 @@ export class FileHistory {
|
|
|
104
317
|
const indexPath = join(history.historyDir, "index.json");
|
|
105
318
|
if (existsSync(indexPath)) {
|
|
106
319
|
try {
|
|
107
|
-
|
|
320
|
+
const parsed = JSON.parse(readFileSync(indexPath, "utf-8"));
|
|
321
|
+
if (Array.isArray(parsed)) {
|
|
322
|
+
// Legacy v1: bare FileSnapshot[]. No redo/created material existed yet.
|
|
323
|
+
history.snapshots = parsed;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const index = parsed;
|
|
327
|
+
history.snapshots = index.snapshots ?? [];
|
|
328
|
+
history.redoRecords = index.redoRecords ?? [];
|
|
329
|
+
history.created = index.created ?? [];
|
|
330
|
+
}
|
|
108
331
|
}
|
|
109
332
|
catch {
|
|
110
333
|
// Start fresh
|