@wrongstack/core 0.297.0 → 0.298.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/dist/chronicle/index.js +126 -22
- package/dist/chronicle/project-server-client.d.ts +12 -0
- package/dist/chronicle/project-server-protocol.d.ts +22 -0
- package/dist/chronicle/project-server.js +238 -157
- package/dist/coordination/agents/index.js +136 -1
- package/dist/coordination/agents/role-skills.d.ts +3 -2
- package/dist/coordination/brain-trace.d.ts +2 -1
- package/dist/coordination/director/director-task-registry.d.ts +12 -0
- package/dist/coordination/fleet-supervisor.d.ts +21 -0
- package/dist/coordination/index.d.ts +23 -21
- package/dist/coordination/index.js +16493 -16068
- package/dist/coordination/mail-tools.d.ts +3 -3
- package/dist/coordination/mailbox-credential-store.d.ts +22 -2
- package/dist/coordination/mailbox-credential-throttle.d.ts +63 -0
- package/dist/coordination/mailbox-project-server-client.d.ts +16 -0
- package/dist/coordination/mailbox-project-server-protocol.d.ts +43 -5
- package/dist/coordination/mailbox-project-server.js +508 -253
- package/dist/coordination/provider-status-tracker.d.ts +2 -0
- package/dist/coordination/remote-mailbox-credential-store.d.ts +5 -5
- package/dist/coordination/remote-mailbox.d.ts +8 -4
- package/dist/coordination/sqlite-mailbox-credentials.d.ts +11 -0
- package/dist/core/fallback-profile-manager.d.ts +14 -0
- package/dist/core/index.js +451 -137
- package/dist/core/instruction-bundle.d.ts +12 -0
- package/dist/core/system-prompt-builder.d.ts +14 -0
- package/dist/core/system-prompt-skill-bodies.d.ts +1 -1
- package/dist/core/system-prompt-skill-text.d.ts +1 -2
- package/dist/defaults/index.js +2191 -1208
- package/dist/design/index.js +47 -8
- package/dist/execution/design-materialize.d.ts +22 -0
- package/dist/execution/index.js +495 -248
- package/dist/execution/skill-loader.d.ts +10 -1
- package/dist/execution/tool-error-taxonomy.d.ts +31 -0
- package/dist/execution/tool-executor.d.ts +1 -0
- package/dist/goal/index.js +3 -1
- package/dist/hooks/index.js +5 -0
- package/dist/hq/auth-audit.d.ts +6 -0
- package/dist/hq/auth-store.d.ts +59 -3
- package/dist/hq/index.js +401 -101
- package/dist/hq/kanban-store.d.ts +3 -0
- package/dist/hq/protocol/core.d.ts +3 -15
- package/dist/hq/protocol/envelope.d.ts +29 -0
- package/dist/hq/protocol/governance.d.ts +34 -0
- package/dist/hq/protocol/project.d.ts +3 -0
- package/dist/hq/protocol/resume.d.ts +1 -1
- package/dist/hq/protocol.d.ts +9 -8
- package/dist/hq/protocol.js +675 -0
- package/dist/index.js +9012 -6916
- package/dist/infrastructure/index.js +199 -102
- package/dist/kernel/events/session-events.d.ts +3 -0
- package/dist/kernel/events/tool-events.d.ts +3 -1
- package/dist/models/index.js +1 -1
- package/dist/observability/index.js +27 -0
- package/dist/observability/prometheus.d.ts +11 -0
- package/dist/plugin/index.d.ts +5 -1
- package/dist/plugin/index.js +988 -558
- package/dist/plugins/auto-review-plugin.d.ts +1 -11
- package/dist/plugins/review-store-maintenance.d.ts +26 -0
- package/dist/plugins/review-types.d.ts +6 -0
- package/dist/security/auto-approve-policy.d.ts +37 -0
- package/dist/security/capabilities.d.ts +45 -1
- package/dist/security/error-sanitize.d.ts +49 -0
- package/dist/security/file-permissions.d.ts +41 -0
- package/dist/security/index.d.ts +9 -6
- package/dist/security/index.js +3008 -2029
- package/dist/security/permission-helpers.d.ts +93 -0
- package/dist/security/permission-policy.d.ts +37 -35
- package/dist/security/secret-vault.d.ts +17 -0
- package/dist/security/totp.d.ts +86 -0
- package/dist/skills/frontmatter.d.ts +12 -1
- package/dist/skills/github-fetcher.d.ts +48 -0
- package/dist/skills/index.js +137 -26
- package/dist/skills/limits.d.ts +19 -0
- package/dist/skills/skill-installer.d.ts +13 -0
- package/dist/storage/index.js +929 -733
- package/dist/storage/provider-config-watcher.d.ts +1 -0
- package/dist/storage/session-helpers.d.ts +1 -0
- package/dist/storage/session-store.d.ts +9 -2
- package/dist/storage/session-workspace-checkpoints.d.ts +5 -0
- package/dist/tools/fallback-manage-tools.d.ts +6 -0
- package/dist/tools/index.js +287 -131
- package/dist/tools/mcp-use.d.ts +1 -1
- package/dist/types/blocks.d.ts +7 -0
- package/dist/types/config/autonomy.d.ts +15 -7
- package/dist/types/config/mcp-features.d.ts +9 -1
- package/dist/types/config/root.d.ts +10 -4
- package/dist/types/context-window.d.ts +15 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/secret-vault.d.ts +8 -0
- package/dist/types/session.d.ts +2 -0
- package/dist/types/skill.d.ts +56 -0
- package/dist/types/tool-executor.d.ts +2 -0
- package/dist/utils/env-typed.d.ts +64 -0
- package/dist/utils/glob-match.d.ts +21 -1
- package/dist/utils/heap-watchdog.js +1 -1
- package/dist/utils/incoming-images.d.ts +19 -0
- package/dist/utils/index.d.ts +16 -12
- package/dist/utils/index.js +3128 -2800
- package/dist/utils/path-segment.d.ts +29 -0
- package/dist/utils/sage-output-block.js +48 -0
- package/dist/utils/win32-cmd.d.ts +25 -0
- package/dist/worktree/index.js +5 -0
- package/instructions/llm/chimera-review.md +4 -6
- package/package.json +13 -4
- package/skills/auto-review/SKILL.md +11 -76
- package/skills/chimera/SKILL.md +31 -49
- package/skills/data-governance/SKILL.md +92 -0
- package/skills/wrongstack-kanban/SKILL.md +125 -64
- package/dist/agent-status-helpers.d.ts.map +0 -1
- package/dist/agent-status-tracker.d.ts.map +0 -1
- package/dist/boot.d.ts.map +0 -1
- package/dist/chronicle/context.d.ts.map +0 -1
- package/dist/chronicle/decision-adapter.d.ts.map +0 -1
- package/dist/chronicle/domain-adapter.d.ts.map +0 -1
- package/dist/chronicle/event-hash.d.ts.map +0 -1
- package/dist/chronicle/file-observer.d.ts.map +0 -1
- package/dist/chronicle/health-monitor.d.ts.map +0 -1
- package/dist/chronicle/identity.d.ts.map +0 -1
- package/dist/chronicle/index.d.ts.map +0 -1
- package/dist/chronicle/index.js.map +0 -7
- package/dist/chronicle/journal.d.ts.map +0 -1
- package/dist/chronicle/legacy-journal-import.d.ts.map +0 -1
- package/dist/chronicle/metrics-store.d.ts.map +0 -1
- package/dist/chronicle/partition-filename.d.ts.map +0 -1
- package/dist/chronicle/partition-range-cache.d.ts.map +0 -1
- package/dist/chronicle/process-adapter.d.ts.map +0 -1
- package/dist/chronicle/project-access.d.ts.map +0 -1
- package/dist/chronicle/project-server-client.d.ts.map +0 -1
- package/dist/chronicle/project-server-endpoint.d.ts.map +0 -1
- package/dist/chronicle/project-server-protocol.d.ts.map +0 -1
- package/dist/chronicle/project-server.d.ts.map +0 -1
- package/dist/chronicle/project-server.js.map +0 -7
- package/dist/chronicle/prompt-manifest.d.ts.map +0 -1
- package/dist/chronicle/provider-adapter.d.ts.map +0 -1
- package/dist/chronicle/query.d.ts.map +0 -1
- package/dist/chronicle/review-adapter.d.ts.map +0 -1
- package/dist/chronicle/rollup-adapter.d.ts.map +0 -1
- package/dist/chronicle/sink.d.ts.map +0 -1
- package/dist/chronicle/sqlite-journal.d.ts.map +0 -1
- package/dist/chronicle/sqlite-query.d.ts.map +0 -1
- package/dist/chronicle/stream-adapter.d.ts.map +0 -1
- package/dist/chronicle/tool-adapter.d.ts.map +0 -1
- package/dist/chronicle/types.d.ts.map +0 -1
- package/dist/coordination/adaptive-concurrency.d.ts.map +0 -1
- package/dist/coordination/agent-bridge.d.ts.map +0 -1
- package/dist/coordination/agent-monitor.d.ts.map +0 -1
- package/dist/coordination/agent-subagent-runner.d.ts.map +0 -1
- package/dist/coordination/agents/agent-prompts.d.ts.map +0 -1
- package/dist/coordination/agents/index.d.ts.map +0 -1
- package/dist/coordination/agents/index.js.map +0 -7
- package/dist/coordination/agents/phase1-discovery.d.ts.map +0 -1
- package/dist/coordination/agents/phase2-planning.d.ts.map +0 -1
- package/dist/coordination/agents/phase3-build.d.ts.map +0 -1
- package/dist/coordination/agents/phase3-techstack.d.ts.map +0 -1
- package/dist/coordination/agents/phase3-wave1-platform.d.ts.map +0 -1
- package/dist/coordination/agents/phase3-wave2-meta.d.ts.map +0 -1
- package/dist/coordination/agents/phase4-verify.d.ts.map +0 -1
- package/dist/coordination/agents/phase5-review.d.ts.map +0 -1
- package/dist/coordination/agents/phase6-domain.d.ts.map +0 -1
- package/dist/coordination/agents/phase7-knowledge.d.ts.map +0 -1
- package/dist/coordination/agents/phase8-delivery.d.ts.map +0 -1
- package/dist/coordination/agents/phase8-wave3-products.d.ts.map +0 -1
- package/dist/coordination/agents/phase9-meta.d.ts.map +0 -1
- package/dist/coordination/agents/phase9-wave4-platform-meta.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-config-validation.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-consolidation.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-files.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-identity-types.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-identity.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-knowledge-manifests.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-learning-entries.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-learning-normalize.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-learning-policy.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-learning-structured.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-paths.d.ts.map +0 -1
- package/dist/coordination/agents/project-agent-profile.d.ts.map +0 -1
- package/dist/coordination/agents/role-skills.d.ts.map +0 -1
- package/dist/coordination/agents/types.d.ts.map +0 -1
- package/dist/coordination/agents.d.ts.map +0 -1
- package/dist/coordination/auto-extend.d.ts.map +0 -1
- package/dist/coordination/autonomous-brain.d.ts.map +0 -1
- package/dist/coordination/autonomous-coordinator.d.ts.map +0 -1
- package/dist/coordination/brain-cache.d.ts.map +0 -1
- package/dist/coordination/brain-heuristics.d.ts.map +0 -1
- package/dist/coordination/brain-ledger.d.ts.map +0 -1
- package/dist/coordination/brain-monitor.d.ts.map +0 -1
- package/dist/coordination/brain-rules.d.ts.map +0 -1
- package/dist/coordination/brain-telemetry.d.ts.map +0 -1
- package/dist/coordination/brain-trace.d.ts.map +0 -1
- package/dist/coordination/brain.d.ts.map +0 -1
- package/dist/coordination/change-manager.d.ts.map +0 -1
- package/dist/coordination/checkpoint-wiring.d.ts.map +0 -1
- package/dist/coordination/collab-bus.d.ts.map +0 -1
- package/dist/coordination/collab-debug-types.d.ts.map +0 -1
- package/dist/coordination/collab-debug.d.ts.map +0 -1
- package/dist/coordination/collab-director-host.d.ts.map +0 -1
- package/dist/coordination/commit-safety.d.ts.map +0 -1
- package/dist/coordination/consensus-protocol.d.ts.map +0 -1
- package/dist/coordination/coordinator/error-classifier.d.ts.map +0 -1
- package/dist/coordination/delegate-tool.d.ts.map +0 -1
- package/dist/coordination/dep-watcher-bridge.d.ts.map +0 -1
- package/dist/coordination/dep-watcher.d.ts.map +0 -1
- package/dist/coordination/director/director-btw-notes.d.ts.map +0 -1
- package/dist/coordination/director/director-budget-policy.d.ts.map +0 -1
- package/dist/coordination/director/director-collab.d.ts.map +0 -1
- package/dist/coordination/director/director-errors.d.ts.map +0 -1
- package/dist/coordination/director/director-task-registry.d.ts.map +0 -1
- package/dist/coordination/director/director-toolset.d.ts.map +0 -1
- package/dist/coordination/director-basic-tools.d.ts.map +0 -1
- package/dist/coordination/director-collab-tools.d.ts.map +0 -1
- package/dist/coordination/director-host-contracts.d.ts.map +0 -1
- package/dist/coordination/director-input-helpers.d.ts.map +0 -1
- package/dist/coordination/director-kanban-queue-helpers.d.ts.map +0 -1
- package/dist/coordination/director-options.d.ts.map +0 -1
- package/dist/coordination/director-prompts.d.ts.map +0 -1
- package/dist/coordination/director-quality-gate-tool.d.ts.map +0 -1
- package/dist/coordination/director-session.d.ts.map +0 -1
- package/dist/coordination/director-spawn-model.d.ts.map +0 -1
- package/dist/coordination/director-tools.d.ts.map +0 -1
- package/dist/coordination/director.d.ts.map +0 -1
- package/dist/coordination/dispatcher.d.ts.map +0 -1
- package/dist/coordination/file-author-tracker.d.ts.map +0 -1
- package/dist/coordination/fleet-bus.d.ts.map +0 -1
- package/dist/coordination/fleet-event-validation.d.ts.map +0 -1
- package/dist/coordination/fleet-manager.d.ts.map +0 -1
- package/dist/coordination/fleet-spawn.d.ts.map +0 -1
- package/dist/coordination/fleet-status-tool.d.ts.map +0 -1
- package/dist/coordination/fleet-supervisor.d.ts.map +0 -1
- package/dist/coordination/fleet.d.ts.map +0 -1
- package/dist/coordination/global-mailbox-completion.d.ts.map +0 -1
- package/dist/coordination/global-mailbox-paths.d.ts.map +0 -1
- package/dist/coordination/icoordinator.d.ts.map +0 -1
- package/dist/coordination/ifleet-manager.d.ts.map +0 -1
- package/dist/coordination/in-memory-transport.d.ts.map +0 -1
- package/dist/coordination/index.d.ts.map +0 -1
- package/dist/coordination/index.js.map +0 -7
- package/dist/coordination/knowledge-graph.d.ts.map +0 -1
- package/dist/coordination/large-answer-store.d.ts.map +0 -1
- package/dist/coordination/mail-tools.d.ts.map +0 -1
- package/dist/coordination/mailbox-actions.d.ts.map +0 -1
- package/dist/coordination/mailbox-auth-types.d.ts.map +0 -1
- package/dist/coordination/mailbox-codecs.d.ts.map +0 -1
- package/dist/coordination/mailbox-constants.d.ts.map +0 -1
- package/dist/coordination/mailbox-credential-store.d.ts.map +0 -1
- package/dist/coordination/mailbox-events.d.ts.map +0 -1
- package/dist/coordination/mailbox-health.d.ts.map +0 -1
- package/dist/coordination/mailbox-hooks.d.ts.map +0 -1
- package/dist/coordination/mailbox-http-auth.d.ts.map +0 -1
- package/dist/coordination/mailbox-http-rate-limit.d.ts.map +0 -1
- package/dist/coordination/mailbox-http-router.d.ts.map +0 -1
- package/dist/coordination/mailbox-http-validation.d.ts.map +0 -1
- package/dist/coordination/mailbox-message-codec.d.ts.map +0 -1
- package/dist/coordination/mailbox-parse-state.d.ts.map +0 -1
- package/dist/coordination/mailbox-project-server-client.d.ts.map +0 -1
- package/dist/coordination/mailbox-project-server-endpoint.d.ts.map +0 -1
- package/dist/coordination/mailbox-project-server-protocol.d.ts.map +0 -1
- package/dist/coordination/mailbox-project-server.d.ts.map +0 -1
- package/dist/coordination/mailbox-project-server.js.map +0 -7
- package/dist/coordination/mailbox-receipt-folding.d.ts.map +0 -1
- package/dist/coordination/mailbox-registry-codec.d.ts.map +0 -1
- package/dist/coordination/mailbox-retention-state.d.ts.map +0 -1
- package/dist/coordination/mailbox-status-mappers.d.ts.map +0 -1
- package/dist/coordination/mailbox-tool.d.ts.map +0 -1
- package/dist/coordination/mailbox-type-properties.d.ts.map +0 -1
- package/dist/coordination/mailbox-types.d.ts.map +0 -1
- package/dist/coordination/model-matrix.d.ts.map +0 -1
- package/dist/coordination/multi-agent-coordinator.d.ts.map +0 -1
- package/dist/coordination/multi-agent-timeout.d.ts.map +0 -1
- package/dist/coordination/null-fleet-bus.d.ts.map +0 -1
- package/dist/coordination/package-author-tracker.d.ts.map +0 -1
- package/dist/coordination/package-outdated-watcher.d.ts.map +0 -1
- package/dist/coordination/provider-status-tracker.d.ts.map +0 -1
- package/dist/coordination/remote-mailbox-credential-store.d.ts.map +0 -1
- package/dist/coordination/remote-mailbox.d.ts.map +0 -1
- package/dist/coordination/single-instance-mailbox.d.ts.map +0 -1
- package/dist/coordination/spawn-budget.d.ts.map +0 -1
- package/dist/coordination/sqlite-mailbox-compaction.d.ts.map +0 -1
- package/dist/coordination/sqlite-mailbox-credentials.d.ts.map +0 -1
- package/dist/coordination/sqlite-mailbox-rows.d.ts.map +0 -1
- package/dist/coordination/sqlite-mailbox-schema.d.ts.map +0 -1
- package/dist/coordination/sqlite-mailbox.d.ts.map +0 -1
- package/dist/coordination/subagent-budget.d.ts.map +0 -1
- package/dist/coordination/subagent-nicknames.d.ts.map +0 -1
- package/dist/coordination/subagent-result-tool.d.ts.map +0 -1
- package/dist/coordination/task-auctioneer.d.ts.map +0 -1
- package/dist/coordination/task-dag.d.ts.map +0 -1
- package/dist/coordination/techstack-mailbox-consumer.d.ts.map +0 -1
- package/dist/coordination/transport.d.ts.map +0 -1
- package/dist/coordination/worktree-task-runner.d.ts.map +0 -1
- package/dist/core/agent-internals.d.ts.map +0 -1
- package/dist/core/agent-loop.d.ts.map +0 -1
- package/dist/core/agent-response.d.ts.map +0 -1
- package/dist/core/agent-tools.d.ts.map +0 -1
- package/dist/core/agent-types.d.ts.map +0 -1
- package/dist/core/agent.d.ts.map +0 -1
- package/dist/core/btw.d.ts.map +0 -1
- package/dist/core/context.d.ts.map +0 -1
- package/dist/core/continue-intent.d.ts.map +0 -1
- package/dist/core/continue-to-next-iteration.d.ts.map +0 -1
- package/dist/core/conversation-state.d.ts.map +0 -1
- package/dist/core/fallback-model.d.ts.map +0 -1
- package/dist/core/fallback-profile-manager.d.ts.map +0 -1
- package/dist/core/fleet-pulse.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -7
- package/dist/core/input-builder.d.ts.map +0 -1
- package/dist/core/instruction-bundle.d.ts.map +0 -1
- package/dist/core/iteration-limit.d.ts.map +0 -1
- package/dist/core/mailbox-loop.d.ts.map +0 -1
- package/dist/core/model-availability-calendar.d.ts.map +0 -1
- package/dist/core/model-ref.d.ts.map +0 -1
- package/dist/core/model-ref.js.map +0 -7
- package/dist/core/modes/brief.d.ts.map +0 -1
- package/dist/core/modes/default.d.ts.map +0 -1
- package/dist/core/modes/teach.d.ts.map +0 -1
- package/dist/core/provider-runner.d.ts.map +0 -1
- package/dist/core/queued-messages.d.ts.map +0 -1
- package/dist/core/request-provider-binding.d.ts.map +0 -1
- package/dist/core/run-env.d.ts.map +0 -1
- package/dist/core/streaming-response-builder.d.ts.map +0 -1
- package/dist/core/system-prompt-blocks.d.ts.map +0 -1
- package/dist/core/system-prompt-builder.d.ts.map +0 -1
- package/dist/core/system-prompt-environment-probes.d.ts.map +0 -1
- package/dist/core/system-prompt-environment.d.ts.map +0 -1
- package/dist/core/system-prompt-memory-skills.d.ts.map +0 -1
- package/dist/core/system-prompt-plan.d.ts.map +0 -1
- package/dist/core/system-prompt-shell.d.ts.map +0 -1
- package/dist/core/system-prompt-skill-bodies.d.ts.map +0 -1
- package/dist/core/system-prompt-skill-text.d.ts.map +0 -1
- package/dist/defaults/index.d.ts.map +0 -1
- package/dist/defaults/index.js.map +0 -7
- package/dist/design/index.d.ts.map +0 -1
- package/dist/design/index.js.map +0 -7
- package/dist/execution/auto-compaction-middleware.d.ts.map +0 -1
- package/dist/execution/autonomous-runner.d.ts.map +0 -1
- package/dist/execution/autonomy-brain.d.ts.map +0 -1
- package/dist/execution/autonomy-prompt-contributor.d.ts.map +0 -1
- package/dist/execution/brain-chain.d.ts.map +0 -1
- package/dist/execution/brain-circuit.d.ts.map +0 -1
- package/dist/execution/brain-evaluation.d.ts.map +0 -1
- package/dist/execution/brain-runtime-constants.d.ts.map +0 -1
- package/dist/execution/brain-runtime.d.ts.map +0 -1
- package/dist/execution/compaction-core.d.ts.map +0 -1
- package/dist/execution/compaction-scoring.d.ts.map +0 -1
- package/dist/execution/compaction-summary-cache.d.ts.map +0 -1
- package/dist/execution/compactor.d.ts.map +0 -1
- package/dist/execution/council-brain.d.ts.map +0 -1
- package/dist/execution/council-orchestrator.d.ts.map +0 -1
- package/dist/execution/council-personas.d.ts.map +0 -1
- package/dist/execution/council-profiles.d.ts.map +0 -1
- package/dist/execution/council-prompts.d.ts.map +0 -1
- package/dist/execution/council-resolution.d.ts.map +0 -1
- package/dist/execution/design-color.d.ts.map +0 -1
- package/dist/execution/design-detect.d.ts.map +0 -1
- package/dist/execution/design-kit-loader.d.ts.map +0 -1
- package/dist/execution/design-materialize.d.ts.map +0 -1
- package/dist/execution/design-project-store.d.ts.map +0 -1
- package/dist/execution/design-tune.d.ts.map +0 -1
- package/dist/execution/design-verify.d.ts.map +0 -1
- package/dist/execution/enhance-recovery.d.ts.map +0 -1
- package/dist/execution/error-handler.d.ts.map +0 -1
- package/dist/execution/eternal-autonomy-types.d.ts.map +0 -1
- package/dist/execution/eternal-autonomy.d.ts.map +0 -1
- package/dist/execution/goal-preamble.d.ts.map +0 -1
- package/dist/execution/index.d.ts.map +0 -1
- package/dist/execution/index.js.map +0 -7
- package/dist/execution/intelligent-compactor.d.ts.map +0 -1
- package/dist/execution/model-runtime.d.ts.map +0 -1
- package/dist/execution/one-shot-llm.d.ts.map +0 -1
- package/dist/execution/parallel-eternal-engine.d.ts.map +0 -1
- package/dist/execution/prompt-enhancer.d.ts.map +0 -1
- package/dist/execution/prompt-enhancer.js.map +0 -7
- package/dist/execution/prompt-loader.d.ts.map +0 -1
- package/dist/execution/provider-runner-impl.d.ts.map +0 -1
- package/dist/execution/regex-patterns.d.ts.map +0 -1
- package/dist/execution/retry-policy.d.ts.map +0 -1
- package/dist/execution/selective-compactor.d.ts.map +0 -1
- package/dist/execution/skill-loader.d.ts.map +0 -1
- package/dist/execution/strategy-compactor.d.ts.map +0 -1
- package/dist/execution/subagent-compaction.d.ts.map +0 -1
- package/dist/execution/tool-executor-logging.d.ts.map +0 -1
- package/dist/execution/tool-executor-results.d.ts.map +0 -1
- package/dist/execution/tool-executor-stream.d.ts.map +0 -1
- package/dist/execution/tool-executor-support.d.ts.map +0 -1
- package/dist/execution/tool-executor.d.ts.map +0 -1
- package/dist/extension/extension-points.d.ts.map +0 -1
- package/dist/extension/index.d.ts.map +0 -1
- package/dist/extension/index.js.map +0 -7
- package/dist/extension/registry.d.ts.map +0 -1
- package/dist/fleet-notifier.d.ts.map +0 -1
- package/dist/goal/checkpoint.d.ts.map +0 -1
- package/dist/goal/goal-assessor.d.ts.map +0 -1
- package/dist/goal/goal-planner.d.ts.map +0 -1
- package/dist/goal/goal-runner.d.ts.map +0 -1
- package/dist/goal/index.d.ts.map +0 -1
- package/dist/goal/index.js.map +0 -7
- package/dist/goal/phase-board-mutations.d.ts.map +0 -1
- package/dist/goal/phase-graph-builder.d.ts.map +0 -1
- package/dist/goal/phase-orchestrator-integration.d.ts.map +0 -1
- package/dist/goal/phase-orchestrator-queries.d.ts.map +0 -1
- package/dist/goal/phase-orchestrator-runtime.d.ts.map +0 -1
- package/dist/goal/phase-orchestrator-types.d.ts.map +0 -1
- package/dist/goal/phase-orchestrator.d.ts.map +0 -1
- package/dist/goal/phase-store.d.ts.map +0 -1
- package/dist/goal/types.d.ts.map +0 -1
- package/dist/hooks/http-executor.d.ts.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -7
- package/dist/hooks/registry.d.ts.map +0 -1
- package/dist/hooks/runner.d.ts.map +0 -1
- package/dist/hooks/shell-executor.d.ts.map +0 -1
- package/dist/hooks/shell-hooks-equal.d.ts.map +0 -1
- package/dist/hq/alerts.d.ts.map +0 -1
- package/dist/hq/auth-audit.d.ts.map +0 -1
- package/dist/hq/auth-store.d.ts.map +0 -1
- package/dist/hq/bootstrap-store.d.ts.map +0 -1
- package/dist/hq/brain-bridge.d.ts.map +0 -1
- package/dist/hq/bridge-context.d.ts.map +0 -1
- package/dist/hq/commands.d.ts.map +0 -1
- package/dist/hq/cost-bridge.d.ts.map +0 -1
- package/dist/hq/exposure.d.ts.map +0 -1
- package/dist/hq/factory.d.ts.map +0 -1
- package/dist/hq/fleet-bridge.d.ts.map +0 -1
- package/dist/hq/index.d.ts.map +0 -1
- package/dist/hq/index.js.map +0 -7
- package/dist/hq/kanban-store.d.ts.map +0 -1
- package/dist/hq/mailbox-mapper.d.ts.map +0 -1
- package/dist/hq/persistence/event-log.d.ts.map +0 -1
- package/dist/hq/persistence/jsonl-io.d.ts.map +0 -1
- package/dist/hq/persistence/simple-log.d.ts.map +0 -1
- package/dist/hq/persistence/snapshot-store.d.ts.map +0 -1
- package/dist/hq/persistence/timeseries-store.d.ts.map +0 -1
- package/dist/hq/persistence.d.ts.map +0 -1
- package/dist/hq/protocol/brain.d.ts.map +0 -1
- package/dist/hq/protocol/browser.d.ts.map +0 -1
- package/dist/hq/protocol/client.d.ts.map +0 -1
- package/dist/hq/protocol/core.d.ts.map +0 -1
- package/dist/hq/protocol/fleet.d.ts.map +0 -1
- package/dist/hq/protocol/kanban.d.ts.map +0 -1
- package/dist/hq/protocol/mailbox.d.ts.map +0 -1
- package/dist/hq/protocol/mcp.d.ts.map +0 -1
- package/dist/hq/protocol/peer.d.ts.map +0 -1
- package/dist/hq/protocol/project.d.ts.map +0 -1
- package/dist/hq/protocol/resume.d.ts.map +0 -1
- package/dist/hq/protocol/session.d.ts.map +0 -1
- package/dist/hq/protocol/tool.d.ts.map +0 -1
- package/dist/hq/protocol.d.ts.map +0 -1
- package/dist/hq/publisher.d.ts.map +0 -1
- package/dist/hq/redaction.d.ts.map +0 -1
- package/dist/hq/session-bridge.d.ts.map +0 -1
- package/dist/hq/tool-bridge.d.ts.map +0 -1
- package/dist/hq/transcript-mapper.d.ts.map +0 -1
- package/dist/hq/worktree-bridge.d.ts.map +0 -1
- package/dist/hq/write-queues.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -7
- package/dist/infrastructure/context-manager.d.ts.map +0 -1
- package/dist/infrastructure/index.d.ts.map +0 -1
- package/dist/infrastructure/index.js.map +0 -7
- package/dist/infrastructure/logger.d.ts.map +0 -1
- package/dist/infrastructure/mcp-servers.d.ts.map +0 -1
- package/dist/infrastructure/path-resolver.d.ts.map +0 -1
- package/dist/infrastructure/provider-cache-ledger.d.ts.map +0 -1
- package/dist/infrastructure/token-counter.d.ts.map +0 -1
- package/dist/kernel/container.d.ts.map +0 -1
- package/dist/kernel/events/agent-events.d.ts.map +0 -1
- package/dist/kernel/events/brain-events.d.ts.map +0 -1
- package/dist/kernel/events/file-events.d.ts.map +0 -1
- package/dist/kernel/events/fleet-events.d.ts.map +0 -1
- package/dist/kernel/events/memory-events.d.ts.map +0 -1
- package/dist/kernel/events/network-events.d.ts.map +0 -1
- package/dist/kernel/events/process-events.d.ts.map +0 -1
- package/dist/kernel/events/provider-events.d.ts.map +0 -1
- package/dist/kernel/events/sdd-events.d.ts.map +0 -1
- package/dist/kernel/events/session-events.d.ts.map +0 -1
- package/dist/kernel/events/tool-events.d.ts.map +0 -1
- package/dist/kernel/events/worktree-events.d.ts.map +0 -1
- package/dist/kernel/events.d.ts.map +0 -1
- package/dist/kernel/index.d.ts.map +0 -1
- package/dist/kernel/index.js.map +0 -7
- package/dist/kernel/pipeline.d.ts.map +0 -1
- package/dist/kernel/run-controller.d.ts.map +0 -1
- package/dist/kernel/tokens.d.ts.map +0 -1
- package/dist/mailbox-attach.d.ts.map +0 -1
- package/dist/middleware/collab-pause.d.ts.map +0 -1
- package/dist/models/alibaba-token-plan-catalog.d.ts.map +0 -1
- package/dist/models/codex-catalog.d.ts.map +0 -1
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js.map +0 -7
- package/dist/models/llm-selector.d.ts.map +0 -1
- package/dist/models/mode-store.d.ts.map +0 -1
- package/dist/models/model-intelligence.d.ts.map +0 -1
- package/dist/models/model-router.d.ts.map +0 -1
- package/dist/models/models-registry.d.ts.map +0 -1
- package/dist/models/provider-model-resolve.d.ts.map +0 -1
- package/dist/notifications/index.d.ts.map +0 -1
- package/dist/notifications/index.js.map +0 -7
- package/dist/notifications/notifier-impl.d.ts.map +0 -1
- package/dist/notifications/notifier.d.ts.map +0 -1
- package/dist/notifications/types.d.ts.map +0 -1
- package/dist/observability/event-bridge.d.ts.map +0 -1
- package/dist/observability/health.d.ts.map +0 -1
- package/dist/observability/index.d.ts.map +0 -1
- package/dist/observability/index.js.map +0 -7
- package/dist/observability/metrics.d.ts.map +0 -1
- package/dist/observability/network-telemetry.d.ts.map +0 -1
- package/dist/observability/otel-tracer.d.ts.map +0 -1
- package/dist/observability/otlp-metrics.d.ts.map +0 -1
- package/dist/observability/otlp-traces.d.ts.map +0 -1
- package/dist/observability/process-telemetry.d.ts.map +0 -1
- package/dist/observability/prometheus.d.ts.map +0 -1
- package/dist/observability/redact-command.d.ts.map +0 -1
- package/dist/observability/tracer.d.ts.map +0 -1
- package/dist/plugin/api.d.ts.map +0 -1
- package/dist/plugin/config.d.ts.map +0 -1
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js.map +0 -7
- package/dist/plugin/loader.d.ts.map +0 -1
- package/dist/plugins/auto-review-plugin.d.ts.map +0 -1
- package/dist/plugins/chimera-plugin.d.ts.map +0 -1
- package/dist/plugins/prompts-plugin.d.ts.map +0 -1
- package/dist/plugins/review-claim-registry.d.ts.map +0 -1
- package/dist/plugins/review-context-builder.d.ts.map +0 -1
- package/dist/plugins/review-finding-commands.d.ts.map +0 -1
- package/dist/plugins/review-finding-integration.d.ts.map +0 -1
- package/dist/plugins/review-finding-parser.d.ts.map +0 -1
- package/dist/plugins/review-finding-store.d.ts.map +0 -1
- package/dist/plugins/review-finding-types.d.ts.map +0 -1
- package/dist/plugins/review-report-integration.d.ts.map +0 -1
- package/dist/plugins/review-report-store.d.ts.map +0 -1
- package/dist/plugins/review-report-types.d.ts.map +0 -1
- package/dist/plugins/review-types.d.ts.map +0 -1
- package/dist/plugins/skills-plugin.d.ts.map +0 -1
- package/dist/plugins/sync-plugin.d.ts.map +0 -1
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/prompt-installer.d.ts.map +0 -1
- package/dist/prompts/prompt-manifest-store.d.ts.map +0 -1
- package/dist/registry/index.d.ts.map +0 -1
- package/dist/registry/index.js.map +0 -7
- package/dist/registry/provider-registry.d.ts.map +0 -1
- package/dist/registry/slash-command-registry.d.ts.map +0 -1
- package/dist/registry/tool-registry.d.ts.map +0 -1
- package/dist/replay/hash.d.ts.map +0 -1
- package/dist/replay/index.d.ts.map +0 -1
- package/dist/replay/index.js.map +0 -7
- package/dist/replay/replay-provider-runner.d.ts.map +0 -1
- package/dist/security/capabilities.d.ts.map +0 -1
- package/dist/security/config-secrets.d.ts.map +0 -1
- package/dist/security/directory-permission-policy.d.ts.map +0 -1
- package/dist/security/directory-policy-schema.d.ts.map +0 -1
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js.map +0 -7
- package/dist/security/kanban-boundary.d.ts.map +0 -1
- package/dist/security/permission-policy-schema.d.ts.map +0 -1
- package/dist/security/permission-policy.d.ts.map +0 -1
- package/dist/security/readonly-permission-policy.d.ts.map +0 -1
- package/dist/security/secret-scrubber.d.ts.map +0 -1
- package/dist/security/secret-vault.d.ts.map +0 -1
- package/dist/security/trust-boundary.d.ts.map +0 -1
- package/dist/security/yolo-risk.d.ts.map +0 -1
- package/dist/session-registry-atomic-file.d.ts.map +0 -1
- package/dist/session-registry-types.d.ts.map +0 -1
- package/dist/session-registry.d.ts.map +0 -1
- package/dist/skills/foreign-sources.d.ts.map +0 -1
- package/dist/skills/frontmatter.d.ts.map +0 -1
- package/dist/skills/github-fetcher.d.ts.map +0 -1
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js.map +0 -7
- package/dist/skills/limits.d.ts.map +0 -1
- package/dist/skills/manifest-store.d.ts.map +0 -1
- package/dist/skills/registry/github-direct-adapter.d.ts.map +0 -1
- package/dist/skills/registry/registry-adapter.d.ts.map +0 -1
- package/dist/skills/registry/skills-sh-adapter.d.ts.map +0 -1
- package/dist/skills/skill-generator.d.ts.map +0 -1
- package/dist/skills/skill-installer.d.ts.map +0 -1
- package/dist/storage/annotations-store.d.ts.map +0 -1
- package/dist/storage/attachment-store.d.ts.map +0 -1
- package/dist/storage/cloud-sync.d.ts.map +0 -1
- package/dist/storage/completed-work-checkpoint.d.ts.map +0 -1
- package/dist/storage/config-loader/bootstrap.d.ts.map +0 -1
- package/dist/storage/config-loader/default-repair.d.ts.map +0 -1
- package/dist/storage/config-loader/defaults.d.ts.map +0 -1
- package/dist/storage/config-loader/diagnostics.d.ts.map +0 -1
- package/dist/storage/config-loader/env-overrides.d.ts.map +0 -1
- package/dist/storage/config-loader/in-project-policy.d.ts.map +0 -1
- package/dist/storage/config-loader/inline-provider-models.d.ts.map +0 -1
- package/dist/storage/config-loader/legacy-sage-migration.d.ts.map +0 -1
- package/dist/storage/config-loader/path-identity.d.ts.map +0 -1
- package/dist/storage/config-loader/types.d.ts.map +0 -1
- package/dist/storage/config-loader/validation.d.ts.map +0 -1
- package/dist/storage/config-loader.d.ts.map +0 -1
- package/dist/storage/config-migration.d.ts.map +0 -1
- package/dist/storage/config-store.d.ts.map +0 -1
- package/dist/storage/director-state.d.ts.map +0 -1
- package/dist/storage/file-session-writer.d.ts.map +0 -1
- package/dist/storage/goal-coordination.d.ts.map +0 -1
- package/dist/storage/goal-kanban.d.ts.map +0 -1
- package/dist/storage/goal-store.d.ts.map +0 -1
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js.map +0 -7
- package/dist/storage/input-history-store.d.ts.map +0 -1
- package/dist/storage/memory-backend.d.ts.map +0 -1
- package/dist/storage/memory-consolidator.d.ts.map +0 -1
- package/dist/storage/memory-graph-backend.d.ts.map +0 -1
- package/dist/storage/plan-store.d.ts.map +0 -1
- package/dist/storage/plan-templates.d.ts.map +0 -1
- package/dist/storage/prompt-store.d.ts.map +0 -1
- package/dist/storage/prompt-usage-store.d.ts.map +0 -1
- package/dist/storage/provider-config-watcher.d.ts.map +0 -1
- package/dist/storage/queue-store.d.ts.map +0 -1
- package/dist/storage/recovery-lock.d.ts.map +0 -1
- package/dist/storage/replay-log-store.d.ts.map +0 -1
- package/dist/storage/session-analyzer.d.ts.map +0 -1
- package/dist/storage/session-checkpoint-cas.d.ts.map +0 -1
- package/dist/storage/session-event-bridge.d.ts.map +0 -1
- package/dist/storage/session-helpers.d.ts.map +0 -1
- package/dist/storage/session-id-resolver.d.ts.map +0 -1
- package/dist/storage/session-id.d.ts.map +0 -1
- package/dist/storage/session-read-scrubber.d.ts.map +0 -1
- package/dist/storage/session-reader.d.ts.map +0 -1
- package/dist/storage/session-recovery.d.ts.map +0 -1
- package/dist/storage/session-resume-validation.d.ts.map +0 -1
- package/dist/storage/session-rewind-apply.d.ts.map +0 -1
- package/dist/storage/session-rewinder.d.ts.map +0 -1
- package/dist/storage/session-store/delete-session-artifacts.d.ts.map +0 -1
- package/dist/storage/session-store/delete-session-guards.d.ts.map +0 -1
- package/dist/storage/session-store/directory-scan.d.ts.map +0 -1
- package/dist/storage/session-store/directory-session-files.d.ts.map +0 -1
- package/dist/storage/session-store/events.d.ts.map +0 -1
- package/dist/storage/session-store/fork-session.d.ts.map +0 -1
- package/dist/storage/session-store/index-reader.d.ts.map +0 -1
- package/dist/storage/session-store/load-cache.d.ts.map +0 -1
- package/dist/storage/session-store/load-session-data.d.ts.map +0 -1
- package/dist/storage/session-store/paths.d.ts.map +0 -1
- package/dist/storage/session-store/prune-helpers.d.ts.map +0 -1
- package/dist/storage/session-store/replay.d.ts.map +0 -1
- package/dist/storage/session-store/search-events.d.ts.map +0 -1
- package/dist/storage/session-store/shard-manifest.d.ts.map +0 -1
- package/dist/storage/session-store/summary-builder.d.ts.map +0 -1
- package/dist/storage/session-store/summary-header.d.ts.map +0 -1
- package/dist/storage/session-store/types.d.ts.map +0 -1
- package/dist/storage/session-store.d.ts.map +0 -1
- package/dist/storage/session-summary.d.ts.map +0 -1
- package/dist/storage/session-tool-call-ends.d.ts.map +0 -1
- package/dist/storage/session-writer-scrubber.d.ts.map +0 -1
- package/dist/storage/session-writer-truncate.d.ts.map +0 -1
- package/dist/storage/storage-concurrency.d.ts.map +0 -1
- package/dist/storage/task-store.d.ts.map +0 -1
- package/dist/storage/todos-checkpoint.d.ts.map +0 -1
- package/dist/storage/tool-audit-log.d.ts.map +0 -1
- package/dist/tasking/index.d.ts.map +0 -1
- package/dist/tasking/index.js.map +0 -7
- package/dist/tasking/task-store.d.ts.map +0 -1
- package/dist/tasking/task-tracker.d.ts.map +0 -1
- package/dist/tools/council-tool.d.ts.map +0 -1
- package/dist/tools/fallback-chain-manage-tool.d.ts.map +0 -1
- package/dist/tools/fallback-favorite-manage-tool.d.ts.map +0 -1
- package/dist/tools/fallback-manage-helpers.d.ts.map +0 -1
- package/dist/tools/fallback-manage-tool-options.d.ts.map +0 -1
- package/dist/tools/fallback-manage-tools.d.ts.map +0 -1
- package/dist/tools/fallback-model-ref-parse.d.ts.map +0 -1
- package/dist/tools/fallback-provider-key-store.d.ts.map +0 -1
- package/dist/tools/fallback-system-config-view-tool.d.ts.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js.map +0 -7
- package/dist/tools/mcp-control.d.ts.map +0 -1
- package/dist/tools/mcp-use.d.ts.map +0 -1
- package/dist/tools/one-shot-llm-tool.d.ts.map +0 -1
- package/dist/tools/plugin-manager.d.ts.map +0 -1
- package/dist/types/agent-bridge.d.ts.map +0 -1
- package/dist/types/attachment.d.ts.map +0 -1
- package/dist/types/autonomy.d.ts.map +0 -1
- package/dist/types/blocks.d.ts.map +0 -1
- package/dist/types/compactor.d.ts.map +0 -1
- package/dist/types/config/autonomy.d.ts.map +0 -1
- package/dist/types/config/context.d.ts.map +0 -1
- package/dist/types/config/fleet-chat.d.ts.map +0 -1
- package/dist/types/config/mcp-features.d.ts.map +0 -1
- package/dist/types/config/providers.d.ts.map +0 -1
- package/dist/types/config/root.d.ts.map +0 -1
- package/dist/types/config/runtime.d.ts.map +0 -1
- package/dist/types/config/skills-fleet-brain.d.ts.map +0 -1
- package/dist/types/config/tools.d.ts.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/context-evidence.d.ts.map +0 -1
- package/dist/types/context-window.d.ts.map +0 -1
- package/dist/types/council.d.ts.map +0 -1
- package/dist/types/default-config.d.ts.map +0 -1
- package/dist/types/design-kit.d.ts.map +0 -1
- package/dist/types/error-handler.d.ts.map +0 -1
- package/dist/types/errors.d.ts.map +0 -1
- package/dist/types/file-event-record.d.ts.map +0 -1
- package/dist/types/hooks.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -7
- package/dist/types/input-reader.d.ts.map +0 -1
- package/dist/types/logger.d.ts.map +0 -1
- package/dist/types/memory.d.ts.map +0 -1
- package/dist/types/messages.d.ts.map +0 -1
- package/dist/types/mode-prompts.d.ts.map +0 -1
- package/dist/types/mode.d.ts.map +0 -1
- package/dist/types/models-registry.d.ts.map +0 -1
- package/dist/types/multi-agent.d.ts.map +0 -1
- package/dist/types/observability.d.ts.map +0 -1
- package/dist/types/one-shot-llm.d.ts.map +0 -1
- package/dist/types/path-resolver.d.ts.map +0 -1
- package/dist/types/permission.d.ts.map +0 -1
- package/dist/types/plugin.d.ts.map +0 -1
- package/dist/types/prompt-registry.d.ts.map +0 -1
- package/dist/types/prompt.d.ts.map +0 -1
- package/dist/types/provider-runner.d.ts.map +0 -1
- package/dist/types/provider.d.ts.map +0 -1
- package/dist/types/quota-regex.d.ts.map +0 -1
- package/dist/types/renderer.d.ts.map +0 -1
- package/dist/types/retry-policy.d.ts.map +0 -1
- package/dist/types/secret-scrubber.d.ts.map +0 -1
- package/dist/types/secret-vault.d.ts.map +0 -1
- package/dist/types/selector.d.ts.map +0 -1
- package/dist/types/session-markers.d.ts.map +0 -1
- package/dist/types/session-markers.js.map +0 -7
- package/dist/types/session-reader.d.ts.map +0 -1
- package/dist/types/session-rewinder.d.ts.map +0 -1
- package/dist/types/session.d.ts.map +0 -1
- package/dist/types/side-effect.d.ts.map +0 -1
- package/dist/types/skill.d.ts.map +0 -1
- package/dist/types/slash-command.d.ts.map +0 -1
- package/dist/types/spec.d.ts.map +0 -1
- package/dist/types/system-prompt-contributor.d.ts.map +0 -1
- package/dist/types/system-prompt.d.ts.map +0 -1
- package/dist/types/task-graph.d.ts.map +0 -1
- package/dist/types/token-counter.d.ts.map +0 -1
- package/dist/types/tool-executor.d.ts.map +0 -1
- package/dist/types/tool-markers.d.ts.map +0 -1
- package/dist/types/tool.d.ts.map +0 -1
- package/dist/types/utility-types.d.ts.map +0 -1
- package/dist/utils/assert-never.d.ts.map +0 -1
- package/dist/utils/atomic-write.d.ts.map +0 -1
- package/dist/utils/cache-key.d.ts.map +0 -1
- package/dist/utils/child-env.d.ts.map +0 -1
- package/dist/utils/color.d.ts.map +0 -1
- package/dist/utils/compaction-preview.d.ts.map +0 -1
- package/dist/utils/config-backup.d.ts.map +0 -1
- package/dist/utils/config-json.d.ts.map +0 -1
- package/dist/utils/connectivity.d.ts.map +0 -1
- package/dist/utils/context-breakdown.d.ts.map +0 -1
- package/dist/utils/context-evidence.d.ts.map +0 -1
- package/dist/utils/continuous-memory-profiler.d.ts.map +0 -1
- package/dist/utils/crash-shield.d.ts.map +0 -1
- package/dist/utils/deep-merge.d.ts.map +0 -1
- package/dist/utils/diff.d.ts.map +0 -1
- package/dist/utils/error.d.ts.map +0 -1
- package/dist/utils/error.js.map +0 -7
- package/dist/utils/expect-defined.d.ts.map +0 -1
- package/dist/utils/expect-defined.js.map +0 -7
- package/dist/utils/glob-expand.d.ts.map +0 -1
- package/dist/utils/glob-match.d.ts.map +0 -1
- package/dist/utils/heap-watchdog-types.d.ts.map +0 -1
- package/dist/utils/heap-watchdog.d.ts.map +0 -1
- package/dist/utils/heap-watchdog.js.map +0 -7
- package/dist/utils/incoming-images.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -7
- package/dist/utils/instruction-file.d.ts.map +0 -1
- package/dist/utils/ip-guard.d.ts.map +0 -1
- package/dist/utils/json-repair.d.ts.map +0 -1
- package/dist/utils/json-schema-validate.d.ts.map +0 -1
- package/dist/utils/lru-cache.d.ts.map +0 -1
- package/dist/utils/memory-flight-recorder.d.ts.map +0 -1
- package/dist/utils/merge-custom-models.d.ts.map +0 -1
- package/dist/utils/merge-models-payload.d.ts.map +0 -1
- package/dist/utils/message-invariants.d.ts.map +0 -1
- package/dist/utils/newline-normalize.d.ts.map +0 -1
- package/dist/utils/perf-profile.d.ts.map +0 -1
- package/dist/utils/pid.d.ts.map +0 -1
- package/dist/utils/project-identity.d.ts.map +0 -1
- package/dist/utils/project-watch.d.ts.map +0 -1
- package/dist/utils/regex-guard.d.ts.map +0 -1
- package/dist/utils/safe-json.d.ts.map +0 -1
- package/dist/utils/sage-output-block.d.ts.map +0 -1
- package/dist/utils/session-scoped-path.d.ts.map +0 -1
- package/dist/utils/sleep.d.ts.map +0 -1
- package/dist/utils/slug.d.ts.map +0 -1
- package/dist/utils/socket-path.d.ts.map +0 -1
- package/dist/utils/sqlite-warning.d.ts.map +0 -1
- package/dist/utils/string.d.ts.map +0 -1
- package/dist/utils/task-format.d.ts.map +0 -1
- package/dist/utils/term.d.ts.map +0 -1
- package/dist/utils/todos-format.d.ts.map +0 -1
- package/dist/utils/token-estimate.d.ts.map +0 -1
- package/dist/utils/tool-description-mode.d.ts.map +0 -1
- package/dist/utils/tool-name.d.ts.map +0 -1
- package/dist/utils/tool-output-serializer.d.ts.map +0 -1
- package/dist/utils/tool-result-render-mode.d.ts.map +0 -1
- package/dist/utils/tool-subject.d.ts.map +0 -1
- package/dist/utils/tool-wire-compact.d.ts.map +0 -1
- package/dist/utils/tree-kill.d.ts.map +0 -1
- package/dist/utils/tree-kill.js.map +0 -7
- package/dist/utils/ulid.d.ts.map +0 -1
- package/dist/utils/walk-ignore.d.ts.map +0 -1
- package/dist/utils/wstack-paths.d.ts.map +0 -1
- package/dist/worktree/index.d.ts.map +0 -1
- package/dist/worktree/index.js.map +0 -7
- package/dist/worktree/worktree-git.d.ts.map +0 -1
- package/dist/worktree/worktree-managed-ops.d.ts.map +0 -1
- package/dist/worktree/worktree-manager.d.ts.map +0 -1
- package/dist/worktree/worktree-types.d.ts.map +0 -1
package/dist/storage/index.js
CHANGED
|
@@ -2,67 +2,80 @@
|
|
|
2
2
|
import * as fsp12 from "node:fs/promises";
|
|
3
3
|
import * as path13 from "node:path";
|
|
4
4
|
|
|
5
|
+
// src/security/file-permissions.ts
|
|
6
|
+
var SECRET_FILE_MODE = 384;
|
|
7
|
+
|
|
5
8
|
// src/security/secret-scrubber.ts
|
|
6
9
|
var PATTERNS = [
|
|
7
10
|
// Anchored at the start where possible so partial matches inside larger
|
|
8
11
|
// strings don't trigger false positives.
|
|
9
12
|
{
|
|
10
13
|
type: "anthropic_key",
|
|
11
|
-
regex: /(?<![A-Za-z0-9])sk-ant-api\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g
|
|
14
|
+
regex: /(?<![A-Za-z0-9])sk-ant-api\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g,
|
|
15
|
+
anchor: "sk-ant-"
|
|
12
16
|
},
|
|
13
|
-
{ type: "openai_key", regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },
|
|
14
|
-
{ type: "github_pat", regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },
|
|
15
|
-
{ type: "github_pat_v2", regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },
|
|
16
|
-
{ type: "aws_access_key", regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },
|
|
17
|
-
{ type: "gcp_key", regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },
|
|
18
|
-
{ type: "slack_token", regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },
|
|
17
|
+
{ type: "openai_key", regex: /(?<![A-Za-z0-9])sk-(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g, anchor: "sk-" },
|
|
18
|
+
{ type: "github_pat", regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g, anchor: "ghp_" },
|
|
19
|
+
{ type: "github_pat_v2", regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g, anchor: "github_pat_" },
|
|
20
|
+
{ type: "aws_access_key", regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g, anchor: "AKIA" },
|
|
21
|
+
{ type: "gcp_key", regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g, anchor: "AIza" },
|
|
22
|
+
{ type: "slack_token", regex: /(?<![A-Za-z0-9-])xox[abpos]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g, anchor: "xox" },
|
|
19
23
|
{
|
|
20
24
|
type: "stripe_key",
|
|
21
|
-
regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g
|
|
25
|
+
regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g,
|
|
26
|
+
anchor: "sk_"
|
|
22
27
|
},
|
|
23
28
|
{
|
|
24
29
|
type: "twilio_sid",
|
|
25
|
-
regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g
|
|
30
|
+
regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g,
|
|
31
|
+
anchor: "AC"
|
|
26
32
|
},
|
|
27
33
|
{
|
|
28
34
|
type: "telegram_bot_token",
|
|
29
35
|
// Telegram tokens are of the form bot<digits>:<alphanum> in URL paths
|
|
30
|
-
regex: /\/bot\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
|
|
36
|
+
regex: /\/bot\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
37
|
+
anchor: "/bot"
|
|
31
38
|
},
|
|
32
39
|
{
|
|
33
40
|
type: "jwt",
|
|
34
41
|
// Anchored: look for literal "eyJ" which is unambiguous for JWT header
|
|
35
|
-
regex: /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g
|
|
42
|
+
regex: /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g,
|
|
43
|
+
anchor: "eyJ"
|
|
36
44
|
},
|
|
37
45
|
{
|
|
38
46
|
type: "private_key",
|
|
39
47
|
// Anchored: start must be BEGIN, end must be END with no extra dashes after END
|
|
40
|
-
regex: /(?:^|\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\s\S]*?-----END[^-]*-----(?:\n|$)/g
|
|
48
|
+
regex: /(?:^|\n)-----BEGIN (?:RSA|EC|OPENSSH|DSA|PGP)? ?PRIVATE KEY-----[\s\S]*?-----END[^-]*-----(?:\n|$)/g,
|
|
49
|
+
anchor: "-----BEGIN"
|
|
41
50
|
},
|
|
42
|
-
{ type: "mongodb_uri", regex: /mongodb(?:\+srv)?:\/\/[^\s"'`]+/g },
|
|
43
|
-
{ type: "postgres_uri", regex: /postgres(?:ql)?:\/\/[^\s"'`]+/g },
|
|
44
|
-
{ type: "mysql_uri", regex: /mysql:\/\/[^\s"'`]+/g },
|
|
45
|
-
{ type: "redis_uri", regex: /redis:\/\/[^\s"'`]+/g },
|
|
51
|
+
{ type: "mongodb_uri", regex: /mongodb(?:\+srv)?:\/\/[^\s"'`]+/g, anchor: "mongodb" },
|
|
52
|
+
{ type: "postgres_uri", regex: /postgres(?:ql)?:\/\/[^\s"'`]+/g, anchor: "postgres" },
|
|
53
|
+
{ type: "mysql_uri", regex: /mysql:\/\/[^\s"'`]+/g, anchor: "mysql://" },
|
|
54
|
+
{ type: "redis_uri", regex: /redis:\/\/[^\s"'`]+/g, anchor: "redis://" },
|
|
46
55
|
// AI/ML provider keys — modern LLM services with well-known prefixes
|
|
47
56
|
{
|
|
48
57
|
type: "huggingface_token",
|
|
49
58
|
// HuggingFace tokens: hf_ followed by 34 alphanumeric chars
|
|
50
|
-
regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g
|
|
59
|
+
regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g,
|
|
60
|
+
anchor: "hf_"
|
|
51
61
|
},
|
|
52
62
|
{
|
|
53
63
|
type: "replicate_token",
|
|
54
64
|
// Replicate tokens: r8_ followed by 40+ alphanumeric chars
|
|
55
|
-
regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g
|
|
65
|
+
regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,
|
|
66
|
+
anchor: "r8_"
|
|
56
67
|
},
|
|
57
68
|
{
|
|
58
69
|
type: "perplexity_key",
|
|
59
70
|
// Perplexity API keys: pplx- followed by 40+ alphanumeric chars
|
|
60
|
-
regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g
|
|
71
|
+
regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,
|
|
72
|
+
anchor: "pplx-"
|
|
61
73
|
},
|
|
62
74
|
{
|
|
63
75
|
type: "groq_key",
|
|
64
76
|
// Groq API keys: gsk_ followed by 40+ alphanumeric chars
|
|
65
|
-
regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g
|
|
77
|
+
regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,
|
|
78
|
+
anchor: "gsk_"
|
|
66
79
|
},
|
|
67
80
|
{
|
|
68
81
|
type: "bearer_token",
|
|
@@ -75,7 +88,8 @@ var PATTERNS = [
|
|
|
75
88
|
// tokens sharing a single delimiter (`Bearer a… Bearer b…`) must both be
|
|
76
89
|
// redacted. A consuming trailing delimiter would eat the separator the
|
|
77
90
|
// next match needs for its leading anchor, leaking the second token.
|
|
78
|
-
regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{12,512}=*(?=$|[^A-Za-z0-9_.~+/-])/g
|
|
91
|
+
regex: /(?:^|[^A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{12,512}=*(?=$|[^A-Za-z0-9_.~+/-])/g,
|
|
92
|
+
anchor: "Bearer"
|
|
79
93
|
},
|
|
80
94
|
{
|
|
81
95
|
type: "high_entropy_env",
|
|
@@ -91,7 +105,89 @@ var PATTERNS = [
|
|
|
91
105
|
// replacement so the separator between adjacent secrets is preserved
|
|
92
106
|
// rather than collapsed. Capture groups are therefore: 1=leading
|
|
93
107
|
// delimiter, 2=key name, 3=value.
|
|
94
|
-
regex: /(^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?=\s|$)/g
|
|
108
|
+
regex: /(^|\s)([A-Z_]{4,}(?:KEY|TOKEN|SECRET|PASSWORD|PWD))\s*[:=]\s*['"]?([A-Za-z0-9_/+=-]{20,512})['"]?(?=\s|$)/g,
|
|
109
|
+
anchor: ["KEY", "TOKEN", "SECRET", "PASSWORD", "PWD"]
|
|
110
|
+
},
|
|
111
|
+
// ── Ported from packages/plugins credential-patterns.ts (WS-034) ─────────
|
|
112
|
+
// The plugin runtime carried 37 patterns while this scrubber — the one that
|
|
113
|
+
// guards session JSONL, chronicle, HQ broadcast, WebUI events and the auth
|
|
114
|
+
// audit — carried 22. The plugin side already had a parity test; it just did
|
|
115
|
+
// not cover core. Most consequential: WrongStack mints `gho_` tokens itself
|
|
116
|
+
// in the Copilot OAuth flow, and `gh[ousr]_` was absent here.
|
|
117
|
+
{
|
|
118
|
+
type: "github_oauth_token",
|
|
119
|
+
regex: /(?<![A-Za-z0-9])gh[ousr]_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g,
|
|
120
|
+
anchor: ["gho_", "ghu_", "ghs_", "ghr_"]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
type: "gitlab_pat",
|
|
124
|
+
regex: /(?<![A-Za-z0-9])glpat-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
125
|
+
anchor: "glpat-"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: "gitlab_runner_token",
|
|
129
|
+
regex: /(?<![A-Za-z0-9])glrt-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
130
|
+
anchor: "glrt-"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
type: "npm_token",
|
|
134
|
+
regex: /(?<![A-Za-z0-9])npm_[A-Za-z0-9]{36}(?![A-Za-z0-9])/g,
|
|
135
|
+
anchor: "npm_"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: "slack_app_token",
|
|
139
|
+
regex: /(?<![A-Za-z0-9-])xapp-\d-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g,
|
|
140
|
+
anchor: "xapp-"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: "slack_webhook",
|
|
144
|
+
regex: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9_-]+\/B[A-Za-z0-9_-]+\/[A-Za-z0-9]{16,}/g,
|
|
145
|
+
anchor: "hooks.slack.com"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: "sendgrid_key",
|
|
149
|
+
regex: /(?<![A-Za-z0-9])SG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
150
|
+
anchor: "SG."
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
type: "digitalocean_token",
|
|
154
|
+
regex: /(?<![A-Za-z0-9])dop_v1_[a-f0-9]{64}(?![A-Za-z0-9])/g,
|
|
155
|
+
anchor: "dop_v1_"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: "doppler_token",
|
|
159
|
+
regex: /(?<![A-Za-z0-9])dp\.(?:pt|st|sa|scim|audit)\.[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,
|
|
160
|
+
anchor: "dp."
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: "shopify_token",
|
|
164
|
+
regex: /(?<![A-Za-z0-9])shp(?:at|ca|pa|ss)_[a-fA-F0-9]{32}(?![A-Za-z0-9])/g,
|
|
165
|
+
anchor: "shp"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: "docker_pat",
|
|
169
|
+
regex: /(?<![A-Za-z0-9])dckr_pat_[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
170
|
+
anchor: "dckr_pat_"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
type: "linear_key",
|
|
174
|
+
regex: /(?<![A-Za-z0-9])lin_api_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g,
|
|
175
|
+
anchor: "lin_api_"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: "atlassian_token",
|
|
179
|
+
regex: /(?<![A-Za-z0-9])ATATT3[A-Za-z0-9_\-=]{40,}(?![A-Za-z0-9_\-=])/g,
|
|
180
|
+
anchor: "ATATT3"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: "square_token",
|
|
184
|
+
regex: /(?<![A-Za-z0-9])(?:sq0(?:atp|csp)-|EAAA)[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
185
|
+
anchor: ["sq0atp-", "sq0csp-", "EAAA"]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
type: "google_oauth_client_secret",
|
|
189
|
+
regex: /(?<![A-Za-z0-9_-])GOCSPX-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g,
|
|
190
|
+
anchor: "GOCSPX-"
|
|
95
191
|
}
|
|
96
192
|
];
|
|
97
193
|
var SIMPLE_PATTERNS = PATTERNS.filter((p) => p.type !== "high_entropy_env");
|
|
@@ -100,32 +196,32 @@ var HIGH_ENTROPY_REGEX = PATTERNS.find((p) => p.type === "high_entropy_env").reg
|
|
|
100
196
|
var COMBINED_REPLACEMENTS = SIMPLE_PATTERNS.map((p) => `[REDACTED:${p.type}]`);
|
|
101
197
|
var SCRUB_CHUNK_BYTES = 64 * 1024;
|
|
102
198
|
var SCRUB_OVERLAP_BYTES = 1024;
|
|
199
|
+
var PATTERN_ANCHORS = [
|
|
200
|
+
...new Set(
|
|
201
|
+
PATTERNS.flatMap(
|
|
202
|
+
(pattern) => typeof pattern.anchor === "string" ? [pattern.anchor] : [...pattern.anchor]
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
];
|
|
206
|
+
var JSON_KEY_ANCHORS = [
|
|
207
|
+
'"apiKey"',
|
|
208
|
+
'"api_key"',
|
|
209
|
+
'"token"',
|
|
210
|
+
'"secret"',
|
|
211
|
+
'"password"',
|
|
212
|
+
'"authorization"',
|
|
213
|
+
'"bearer"',
|
|
214
|
+
'"private_key"',
|
|
215
|
+
'"access_token"',
|
|
216
|
+
'"refresh_token"',
|
|
217
|
+
'"client_secret"'
|
|
218
|
+
];
|
|
219
|
+
var ALL_ANCHORS = [...PATTERN_ANCHORS, ...JSON_KEY_ANCHORS];
|
|
103
220
|
function hasCredentialAnchors(text) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
text.includes("github_pat_") || // GitHub PAT v2
|
|
109
|
-
text.includes("eyJ") || // JWT
|
|
110
|
-
text.includes("AKIA") || // AWS access key
|
|
111
|
-
text.includes("AIza") || // GCP service key
|
|
112
|
-
text.includes("xox") || // Slack token (xoxa/xoxb/xoxp/xoxo/xoxs)
|
|
113
|
-
text.includes("Bearer ") || // Bearer token (space suffix reduces false positives)
|
|
114
|
-
text.includes("/bot") || // Telegram bot token (URL path pattern)
|
|
115
|
-
text.includes("hf_") || // HuggingFace token
|
|
116
|
-
text.includes("r8_") || // Replicate token
|
|
117
|
-
text.includes("pplx-") || // Perplexity API key
|
|
118
|
-
text.includes("gsk_") || // Groq API key
|
|
119
|
-
text.includes("_KEY=") || // High-entropy env vars: API_KEY=, SECRET_KEY=, ...
|
|
120
|
-
text.includes("_TOKEN=") || // ACCESS_TOKEN=, AUTH_TOKEN=, ...
|
|
121
|
-
text.includes("_SECRET=") || // API_SECRET=, CLIENT_SECRET=, ...
|
|
122
|
-
text.includes("_PASSWORD=") || // DB_PASSWORD=, ROOT_PASSWORD=, ...
|
|
123
|
-
text.includes("mongodb://") || text.includes("mongodb+srv://") || text.includes("postgres://") || text.includes("postgresql://") || text.includes("mysql://") || text.includes("redis://") || // JSON-style credential keys: tool outputs often serialise objects as
|
|
124
|
-
// raw JSON strings rather than parsed objects. The value may not start
|
|
125
|
-
// with a recognisable prefix (sk-, ghp_, etc.), so we anchor on common
|
|
126
|
-
// key names. The `"` prefix avoids matching prose that happens to mention
|
|
127
|
-
// these words — JSON serialisation always quotes string keys.
|
|
128
|
-
text.includes('"apiKey"') || text.includes('"api_key"') || text.includes('"token"') || text.includes('"secret"') || text.includes('"password"') || text.includes('"authorization"') || text.includes('"bearer"') || text.includes('"private_key"') || text.includes('"access_token"') || text.includes('"refresh_token"') || text.includes('"client_secret"');
|
|
221
|
+
for (const anchor of ALL_ANCHORS) {
|
|
222
|
+
if (text.includes(anchor)) return true;
|
|
223
|
+
}
|
|
224
|
+
return false;
|
|
129
225
|
}
|
|
130
226
|
var DefaultSecretScrubber = class {
|
|
131
227
|
scrub(text) {
|
|
@@ -388,6 +484,11 @@ var SECRET_NAME_PARTS = [
|
|
|
388
484
|
"SECRET",
|
|
389
485
|
"PASSWORD",
|
|
390
486
|
"PASSWD",
|
|
487
|
+
// WRONGSTACK_VAULT_PASSPHRASE is the vault KEK. Without this entry it matched
|
|
488
|
+
// no rule here and fell through to the `WRONGSTACK_` prefix allow-rule, so the
|
|
489
|
+
// key that protects the credential vault was forwarded to every child process
|
|
490
|
+
// — including the agent's own exec/bash tools and MCP stdio servers (WS-033).
|
|
491
|
+
"PASSPHRASE",
|
|
391
492
|
"AUTH",
|
|
392
493
|
"CRED",
|
|
393
494
|
"BEARER",
|
|
@@ -558,6 +659,65 @@ async function backupConfigFile(filePath, paths) {
|
|
|
558
659
|
}
|
|
559
660
|
}
|
|
560
661
|
|
|
662
|
+
// src/utils/deep-merge.ts
|
|
663
|
+
var FORBIDDEN_PROTO_KEYS = /* @__PURE__ */ new Set([
|
|
664
|
+
"__proto__",
|
|
665
|
+
"constructor",
|
|
666
|
+
"prototype",
|
|
667
|
+
"__defineGetter__",
|
|
668
|
+
"__defineSetter__",
|
|
669
|
+
"__lookupGetter__",
|
|
670
|
+
"__lookupSetter__"
|
|
671
|
+
]);
|
|
672
|
+
function isPrimitiveArray(a) {
|
|
673
|
+
return a.every((v) => v === null || typeof v !== "object" && typeof v !== "function");
|
|
674
|
+
}
|
|
675
|
+
function deepMerge(base, patch, options = {}) {
|
|
676
|
+
const {
|
|
677
|
+
conflictResolution = "prefer-patch",
|
|
678
|
+
arrayMode = "replace",
|
|
679
|
+
protectProto = true,
|
|
680
|
+
onNonPrimitiveArrayReplace
|
|
681
|
+
} = options;
|
|
682
|
+
if (typeof base !== "object" || base === null) {
|
|
683
|
+
return conflictResolution === "prefer-patch" ? patch : base;
|
|
684
|
+
}
|
|
685
|
+
if (typeof patch !== "object" || patch === null) {
|
|
686
|
+
return conflictResolution === "prefer-patch" ? patch : base;
|
|
687
|
+
}
|
|
688
|
+
if (Array.isArray(base) && Array.isArray(patch)) {
|
|
689
|
+
if (arrayMode === "concat-primitives" && isPrimitiveArray(base) && isPrimitiveArray(patch)) {
|
|
690
|
+
return [.../* @__PURE__ */ new Set([...base, ...patch])];
|
|
691
|
+
}
|
|
692
|
+
return conflictResolution === "prefer-patch" ? patch : base;
|
|
693
|
+
}
|
|
694
|
+
if (Array.isArray(base) || Array.isArray(patch)) {
|
|
695
|
+
return conflictResolution === "prefer-patch" ? patch : base;
|
|
696
|
+
}
|
|
697
|
+
const baseObj = base;
|
|
698
|
+
const patchObj = patch;
|
|
699
|
+
const out = { ...baseObj };
|
|
700
|
+
for (const [k, v] of Object.entries(patchObj)) {
|
|
701
|
+
if (protectProto && FORBIDDEN_PROTO_KEYS.has(k)) continue;
|
|
702
|
+
const existing = out[k];
|
|
703
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v) && existing !== null && typeof existing === "object" && !Array.isArray(existing)) {
|
|
704
|
+
out[k] = deepMerge(existing, v, options);
|
|
705
|
+
} else if (Array.isArray(v) && Array.isArray(existing)) {
|
|
706
|
+
if (onNonPrimitiveArrayReplace && !isPrimitiveArray(v)) {
|
|
707
|
+
onNonPrimitiveArrayReplace(k, existing.length, v.length);
|
|
708
|
+
}
|
|
709
|
+
out[k] = deepMerge(existing, v, options);
|
|
710
|
+
} else if (v !== void 0) {
|
|
711
|
+
if (onNonPrimitiveArrayReplace && Array.isArray(v) && !isPrimitiveArray(v)) {
|
|
712
|
+
const existingLen = Array.isArray(existing) ? existing.length : 0;
|
|
713
|
+
onNonPrimitiveArrayReplace(k, existingLen, v.length);
|
|
714
|
+
}
|
|
715
|
+
out[k] = v;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return out;
|
|
719
|
+
}
|
|
720
|
+
|
|
561
721
|
// src/utils/expect-defined.ts
|
|
562
722
|
function expectDefined(value, label) {
|
|
563
723
|
if (value === null || value === void 0) {
|
|
@@ -677,68 +837,137 @@ function isEmptyMessage(msg) {
|
|
|
677
837
|
// src/types/config/runtime.ts
|
|
678
838
|
var DEFAULT_TUI_THINKING_WORD = "thinking";
|
|
679
839
|
|
|
680
|
-
// src/utils/
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
"
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
return conflictResolution === "prefer-patch" ? patch : base;
|
|
702
|
-
}
|
|
703
|
-
if (typeof patch !== "object" || patch === null) {
|
|
704
|
-
return conflictResolution === "prefer-patch" ? patch : base;
|
|
705
|
-
}
|
|
706
|
-
if (Array.isArray(base) && Array.isArray(patch)) {
|
|
707
|
-
if (arrayMode === "concat-primitives" && isPrimitiveArray(base) && isPrimitiveArray(patch)) {
|
|
708
|
-
return [.../* @__PURE__ */ new Set([...base, ...patch])];
|
|
709
|
-
}
|
|
710
|
-
return conflictResolution === "prefer-patch" ? patch : base;
|
|
711
|
-
}
|
|
712
|
-
if (Array.isArray(base) || Array.isArray(patch)) {
|
|
713
|
-
return conflictResolution === "prefer-patch" ? patch : base;
|
|
840
|
+
// src/utils/wstack-paths.ts
|
|
841
|
+
import { createHash } from "node:crypto";
|
|
842
|
+
import * as fs2 from "node:fs";
|
|
843
|
+
import * as os from "node:os";
|
|
844
|
+
import * as path2 from "node:path";
|
|
845
|
+
function canonicalProjectRoot(absRoot) {
|
|
846
|
+
const checkoutRoot = path2.resolve(absRoot);
|
|
847
|
+
const dotGit = path2.join(checkoutRoot, ".git");
|
|
848
|
+
try {
|
|
849
|
+
if (!fs2.statSync(dotGit).isFile()) return checkoutRoot;
|
|
850
|
+
const gitDirLine = fs2.readFileSync(dotGit, "utf8").trim();
|
|
851
|
+
const match = /^gitdir:\s*(.+)$/i.exec(gitDirLine);
|
|
852
|
+
if (!match?.[1]) return checkoutRoot;
|
|
853
|
+
const gitDir = path2.resolve(checkoutRoot, match[1].trim());
|
|
854
|
+
const commonDirFile = path2.join(gitDir, "commondir");
|
|
855
|
+
if (!fs2.statSync(commonDirFile).isFile()) return checkoutRoot;
|
|
856
|
+
const commonDir = path2.resolve(gitDir, fs2.readFileSync(commonDirFile, "utf8").trim());
|
|
857
|
+
if (path2.basename(commonDir).toLowerCase() !== ".git") return checkoutRoot;
|
|
858
|
+
return path2.dirname(commonDir);
|
|
859
|
+
} catch {
|
|
860
|
+
return checkoutRoot;
|
|
714
861
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
862
|
+
}
|
|
863
|
+
function projectHash(absRoot) {
|
|
864
|
+
return createHash("sha256").update(canonicalProjectRoot(absRoot)).digest("hex").slice(0, 12);
|
|
865
|
+
}
|
|
866
|
+
function projectSlug(absRoot) {
|
|
867
|
+
const identityRoot = canonicalProjectRoot(absRoot);
|
|
868
|
+
const base = slugify(path2.basename(identityRoot));
|
|
869
|
+
const hash = createHash("sha256").update(identityRoot).digest("hex").slice(0, 6);
|
|
870
|
+
return `${base}-${hash}`;
|
|
871
|
+
}
|
|
872
|
+
function slugify(name) {
|
|
873
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
|
|
874
|
+
}
|
|
875
|
+
function safeProfileName(name) {
|
|
876
|
+
const safe = (name ?? "").replace(/[/\\:]/g, "_").replace(/\.\./g, "_").trim();
|
|
877
|
+
return safe || "default";
|
|
878
|
+
}
|
|
879
|
+
function activeProfileName(globalRoot) {
|
|
880
|
+
try {
|
|
881
|
+
const parsed = JSON.parse(fs2.readFileSync(path2.join(globalRoot, "config.json"), "utf8"));
|
|
882
|
+
return safeProfileName(typeof parsed.activeProfile === "string" ? parsed.activeProfile : void 0);
|
|
883
|
+
} catch {
|
|
884
|
+
return "default";
|
|
735
885
|
}
|
|
736
|
-
|
|
886
|
+
}
|
|
887
|
+
function wstackGlobalRoot() {
|
|
888
|
+
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
889
|
+
if (fromEnv && fromEnv.trim().length > 0) return path2.resolve(fromEnv);
|
|
890
|
+
return path2.join(os.homedir(), ".wrongstack");
|
|
891
|
+
}
|
|
892
|
+
function resolveWstackPaths(opts) {
|
|
893
|
+
const globalRoot = opts.globalRoot ?? (opts.userHome ? path2.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
894
|
+
const homeDir = opts.userHome ?? os.homedir();
|
|
895
|
+
const profileName = safeProfileName(opts.profileName ?? activeProfileName(globalRoot));
|
|
896
|
+
const profileDir = path2.join(globalRoot, "profiles", profileName);
|
|
897
|
+
const hash = projectHash(opts.projectRoot);
|
|
898
|
+
const slug = projectSlug(opts.projectRoot);
|
|
899
|
+
const projectDir = path2.join(globalRoot, "projects", slug);
|
|
900
|
+
return {
|
|
901
|
+
globalRoot,
|
|
902
|
+
profileName,
|
|
903
|
+
profileDir,
|
|
904
|
+
projectRoot: opts.projectRoot,
|
|
905
|
+
homeDir,
|
|
906
|
+
configDir: profileDir,
|
|
907
|
+
globalConfig: path2.join(globalRoot, "config.json"),
|
|
908
|
+
profilesDir: path2.join(globalRoot, "profiles"),
|
|
909
|
+
profileConfig: (name) => {
|
|
910
|
+
return path2.join(globalRoot, "profiles", safeProfileName(name), "config.json");
|
|
911
|
+
},
|
|
912
|
+
profileStatuslineConfig: (name) => {
|
|
913
|
+
return path2.join(globalRoot, "profiles", safeProfileName(name), "statusline.json");
|
|
914
|
+
},
|
|
915
|
+
profileModeConfig: (name) => {
|
|
916
|
+
return path2.join(globalRoot, "profiles", safeProfileName(name), "mode.json");
|
|
917
|
+
},
|
|
918
|
+
profileProviderStatus: (name) => {
|
|
919
|
+
return path2.join(globalRoot, "profiles", safeProfileName(name), "provider-status.json");
|
|
920
|
+
},
|
|
921
|
+
profileUpdateCache: (name) => {
|
|
922
|
+
return path2.join(globalRoot, "profiles", safeProfileName(name), "update-cache.json");
|
|
923
|
+
},
|
|
924
|
+
secretsKey: path2.join(globalRoot, ".key"),
|
|
925
|
+
globalMemory: path2.join(profileDir, "memory.md"),
|
|
926
|
+
globalSkills: path2.join(profileDir, "skills"),
|
|
927
|
+
globalClaudeSkills: path2.join(homeDir, ".claude", "skills"),
|
|
928
|
+
globalDesignKits: path2.join(profileDir, "design-kits"),
|
|
929
|
+
globalPrompts: path2.join(profileDir, "prompts"),
|
|
930
|
+
globalInstructions: path2.join(profileDir, "instructions"),
|
|
931
|
+
promptUsage: path2.join(profileDir, "prompt-usage.json"),
|
|
932
|
+
cacheDir: path2.join(globalRoot, "cache"),
|
|
933
|
+
modelsCache: path2.join(globalRoot, "cache", "models.dev.json"),
|
|
934
|
+
modelsOverlayCache: path2.join(globalRoot, "cache", "models-overlay.json"),
|
|
935
|
+
historyFile: path2.join(profileDir, "history"),
|
|
936
|
+
logFile: path2.join(globalRoot, "logs", "wrongstack.log"),
|
|
937
|
+
projectDir,
|
|
938
|
+
projectCodebaseIndex: path2.join(projectDir, "codebase-index"),
|
|
939
|
+
projectMemory: path2.join(projectDir, "memory.md"),
|
|
940
|
+
projectSessions: path2.join(projectDir, "sessions"),
|
|
941
|
+
projectTrust: path2.join(projectDir, "trust.json"),
|
|
942
|
+
projectMeta: path2.join(projectDir, "meta.json"),
|
|
943
|
+
projectLocalConfig: path2.join(projectDir, "config.local.json"),
|
|
944
|
+
inProjectConfig: path2.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
945
|
+
inProjectAgentsFile: path2.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
946
|
+
inProjectSkills: path2.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
947
|
+
inProjectClaudeSkills: path2.join(opts.projectRoot, ".claude", "skills"),
|
|
948
|
+
inProjectPrompts: path2.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
949
|
+
inProjectInstructions: path2.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
950
|
+
inProjectDesignKits: path2.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
951
|
+
inProjectWorktrees: path2.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
952
|
+
projectHash: hash,
|
|
953
|
+
projectSlug: slug,
|
|
954
|
+
projectGoal: path2.join(projectDir, "goal.json"),
|
|
955
|
+
projectInputHistory: path2.join(projectDir, "input-history.json"),
|
|
956
|
+
projectSpecs: path2.join(projectDir, "specs"),
|
|
957
|
+
projectTaskGraphs: path2.join(projectDir, "task-graphs"),
|
|
958
|
+
projectSddSession: path2.join(projectDir, "sdd-session.json"),
|
|
959
|
+
projectPlan: path2.join(projectDir, "plan.json"),
|
|
960
|
+
projectAutophase: path2.join(projectDir, "autophase"),
|
|
961
|
+
projectSddBoards: path2.join(projectDir, "sdd-boards"),
|
|
962
|
+
syncConfig: path2.join(profileDir, "sync.json"),
|
|
963
|
+
configHistoryDir: path2.join(globalRoot, "config-history"),
|
|
964
|
+
projectStatus: (projectHash2) => path2.join(globalRoot, "projects", projectHash2, "status.json")
|
|
965
|
+
};
|
|
737
966
|
}
|
|
738
967
|
|
|
739
968
|
// src/utils/instruction-file.ts
|
|
740
|
-
import { readFileSync, statSync } from "node:fs";
|
|
741
|
-
import * as
|
|
969
|
+
import { readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
|
|
970
|
+
import * as path3 from "node:path";
|
|
742
971
|
import { fileURLToPath } from "node:url";
|
|
743
972
|
var textCache = /* @__PURE__ */ new Map();
|
|
744
973
|
var rootCandidates;
|
|
@@ -748,7 +977,7 @@ function readBundledInstructionText(relativePath) {
|
|
|
748
977
|
let resolved = "";
|
|
749
978
|
for (const root of instructionRootCandidates()) {
|
|
750
979
|
try {
|
|
751
|
-
resolved =
|
|
980
|
+
resolved = readFileSync2(path3.join(root, relativePath), "utf8").trimEnd();
|
|
752
981
|
break;
|
|
753
982
|
} catch {
|
|
754
983
|
}
|
|
@@ -764,18 +993,18 @@ function renderInstructionTemplate(template, values) {
|
|
|
764
993
|
}
|
|
765
994
|
function instructionRootCandidates() {
|
|
766
995
|
if (rootCandidates !== void 0) return rootCandidates;
|
|
767
|
-
const here =
|
|
996
|
+
const here = path3.dirname(fileURLToPath(import.meta.url));
|
|
768
997
|
const candidates = [
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
998
|
+
path3.resolve(here, "../../instructions"),
|
|
999
|
+
path3.resolve(here, "../instructions"),
|
|
1000
|
+
path3.resolve(here, "instructions")
|
|
772
1001
|
];
|
|
773
1002
|
rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
|
|
774
1003
|
return rootCandidates;
|
|
775
1004
|
}
|
|
776
1005
|
function isDirectory(candidate) {
|
|
777
1006
|
try {
|
|
778
|
-
return
|
|
1007
|
+
return statSync2(candidate).isDirectory();
|
|
779
1008
|
} catch {
|
|
780
1009
|
return false;
|
|
781
1010
|
}
|
|
@@ -875,14 +1104,14 @@ function safeParse(input, maxBytes = 5e6) {
|
|
|
875
1104
|
}
|
|
876
1105
|
|
|
877
1106
|
// src/utils/session-scoped-path.ts
|
|
878
|
-
import * as
|
|
1107
|
+
import * as path4 from "node:path";
|
|
879
1108
|
function sessionScopedPath(dir, sessionId, suffix) {
|
|
880
1109
|
if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
|
|
881
1110
|
throw invalid(sessionId);
|
|
882
1111
|
}
|
|
883
|
-
const resolved =
|
|
884
|
-
const rel =
|
|
885
|
-
if (rel.startsWith("..") ||
|
|
1112
|
+
const resolved = path4.resolve(dir, `${sessionId}${suffix}`);
|
|
1113
|
+
const rel = path4.relative(path4.resolve(dir), resolved);
|
|
1114
|
+
if (rel.startsWith("..") || path4.isAbsolute(rel)) {
|
|
886
1115
|
throw invalid(sessionId);
|
|
887
1116
|
}
|
|
888
1117
|
return resolved;
|
|
@@ -897,144 +1126,33 @@ function invalid(sessionId) {
|
|
|
897
1126
|
}
|
|
898
1127
|
|
|
899
1128
|
// src/utils/slug.ts
|
|
900
|
-
function
|
|
1129
|
+
function slugify2(name, fallback = "prompt", maxLen = 64) {
|
|
901
1130
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLen).replace(/-+$/g, "") || fallback;
|
|
902
1131
|
}
|
|
903
1132
|
|
|
904
|
-
// src/
|
|
905
|
-
import {
|
|
906
|
-
import * as
|
|
907
|
-
import * as
|
|
908
|
-
import
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
const gitDirLine = fs2.readFileSync(dotGit, "utf8").trim();
|
|
915
|
-
const match = /^gitdir:\s*(.+)$/i.exec(gitDirLine);
|
|
916
|
-
if (!match?.[1]) return checkoutRoot;
|
|
917
|
-
const gitDir = path4.resolve(checkoutRoot, match[1].trim());
|
|
918
|
-
const commonDirFile = path4.join(gitDir, "commondir");
|
|
919
|
-
if (!fs2.statSync(commonDirFile).isFile()) return checkoutRoot;
|
|
920
|
-
const commonDir = path4.resolve(gitDir, fs2.readFileSync(commonDirFile, "utf8").trim());
|
|
921
|
-
if (path4.basename(commonDir).toLowerCase() !== ".git") return checkoutRoot;
|
|
922
|
-
return path4.dirname(commonDir);
|
|
923
|
-
} catch {
|
|
924
|
-
return checkoutRoot;
|
|
1133
|
+
// src/storage/file-session-writer.ts
|
|
1134
|
+
import { closeSync, createReadStream, fsyncSync, openSync, writeSync } from "node:fs";
|
|
1135
|
+
import * as fsp2 from "node:fs/promises";
|
|
1136
|
+
import * as path5 from "node:path";
|
|
1137
|
+
import { createInterface } from "node:readline";
|
|
1138
|
+
|
|
1139
|
+
// src/storage/session-workspace-checkpoints.ts
|
|
1140
|
+
function requiredCheckpointCas(checkpointCas, operation) {
|
|
1141
|
+
if (!checkpointCas) {
|
|
1142
|
+
throw new Error(`Workspace checkpoint ${operation} requires a projectRoot-aware session store`);
|
|
925
1143
|
}
|
|
1144
|
+
return checkpointCas;
|
|
926
1145
|
}
|
|
927
|
-
function
|
|
928
|
-
return
|
|
929
|
-
}
|
|
930
|
-
function projectSlug(absRoot) {
|
|
931
|
-
const identityRoot = canonicalProjectRoot(absRoot);
|
|
932
|
-
const base = slugify2(path4.basename(identityRoot));
|
|
933
|
-
const hash = createHash("sha256").update(identityRoot).digest("hex").slice(0, 6);
|
|
934
|
-
return `${base}-${hash}`;
|
|
935
|
-
}
|
|
936
|
-
function slugify2(name) {
|
|
937
|
-
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40) || "project";
|
|
1146
|
+
function captureCheckpoint(checkpointCas, sessionId, promptIndex) {
|
|
1147
|
+
return requiredCheckpointCas(checkpointCas, "capture").capture(sessionId, promptIndex);
|
|
938
1148
|
}
|
|
939
|
-
function
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
try {
|
|
945
|
-
const parsed = JSON.parse(fs2.readFileSync(path4.join(globalRoot, "config.json"), "utf8"));
|
|
946
|
-
return safeProfileName(typeof parsed.activeProfile === "string" ? parsed.activeProfile : void 0);
|
|
947
|
-
} catch {
|
|
948
|
-
return "default";
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
function wstackGlobalRoot() {
|
|
952
|
-
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
953
|
-
if (fromEnv && fromEnv.trim().length > 0) return path4.resolve(fromEnv);
|
|
954
|
-
return path4.join(os.homedir(), ".wrongstack");
|
|
955
|
-
}
|
|
956
|
-
function resolveWstackPaths(opts) {
|
|
957
|
-
const globalRoot = opts.globalRoot ?? (opts.userHome ? path4.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
|
|
958
|
-
const homeDir = opts.userHome ?? os.homedir();
|
|
959
|
-
const profileName = safeProfileName(opts.profileName ?? activeProfileName(globalRoot));
|
|
960
|
-
const profileDir = path4.join(globalRoot, "profiles", profileName);
|
|
961
|
-
const hash = projectHash(opts.projectRoot);
|
|
962
|
-
const slug = projectSlug(opts.projectRoot);
|
|
963
|
-
const projectDir = path4.join(globalRoot, "projects", slug);
|
|
964
|
-
return {
|
|
965
|
-
globalRoot,
|
|
966
|
-
profileName,
|
|
967
|
-
profileDir,
|
|
968
|
-
projectRoot: opts.projectRoot,
|
|
969
|
-
homeDir,
|
|
970
|
-
configDir: profileDir,
|
|
971
|
-
globalConfig: path4.join(globalRoot, "config.json"),
|
|
972
|
-
profilesDir: path4.join(globalRoot, "profiles"),
|
|
973
|
-
profileConfig: (name) => {
|
|
974
|
-
return path4.join(globalRoot, "profiles", safeProfileName(name), "config.json");
|
|
975
|
-
},
|
|
976
|
-
profileStatuslineConfig: (name) => {
|
|
977
|
-
return path4.join(globalRoot, "profiles", safeProfileName(name), "statusline.json");
|
|
978
|
-
},
|
|
979
|
-
profileModeConfig: (name) => {
|
|
980
|
-
return path4.join(globalRoot, "profiles", safeProfileName(name), "mode.json");
|
|
981
|
-
},
|
|
982
|
-
profileProviderStatus: (name) => {
|
|
983
|
-
return path4.join(globalRoot, "profiles", safeProfileName(name), "provider-status.json");
|
|
984
|
-
},
|
|
985
|
-
profileUpdateCache: (name) => {
|
|
986
|
-
return path4.join(globalRoot, "profiles", safeProfileName(name), "update-cache.json");
|
|
987
|
-
},
|
|
988
|
-
secretsKey: path4.join(globalRoot, ".key"),
|
|
989
|
-
globalMemory: path4.join(profileDir, "memory.md"),
|
|
990
|
-
globalSkills: path4.join(profileDir, "skills"),
|
|
991
|
-
globalClaudeSkills: path4.join(homeDir, ".claude", "skills"),
|
|
992
|
-
globalDesignKits: path4.join(profileDir, "design-kits"),
|
|
993
|
-
globalPrompts: path4.join(profileDir, "prompts"),
|
|
994
|
-
globalInstructions: path4.join(profileDir, "instructions"),
|
|
995
|
-
promptUsage: path4.join(profileDir, "prompt-usage.json"),
|
|
996
|
-
cacheDir: path4.join(globalRoot, "cache"),
|
|
997
|
-
modelsCache: path4.join(globalRoot, "cache", "models.dev.json"),
|
|
998
|
-
modelsOverlayCache: path4.join(globalRoot, "cache", "models-overlay.json"),
|
|
999
|
-
historyFile: path4.join(profileDir, "history"),
|
|
1000
|
-
logFile: path4.join(globalRoot, "logs", "wrongstack.log"),
|
|
1001
|
-
projectDir,
|
|
1002
|
-
projectCodebaseIndex: path4.join(projectDir, "codebase-index"),
|
|
1003
|
-
projectMemory: path4.join(projectDir, "memory.md"),
|
|
1004
|
-
projectSessions: path4.join(projectDir, "sessions"),
|
|
1005
|
-
projectTrust: path4.join(projectDir, "trust.json"),
|
|
1006
|
-
projectMeta: path4.join(projectDir, "meta.json"),
|
|
1007
|
-
projectLocalConfig: path4.join(projectDir, "config.local.json"),
|
|
1008
|
-
inProjectConfig: path4.join(opts.projectRoot, ".wrongstack", "config.json"),
|
|
1009
|
-
inProjectAgentsFile: path4.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
|
|
1010
|
-
inProjectSkills: path4.join(opts.projectRoot, ".wrongstack", "skills"),
|
|
1011
|
-
inProjectClaudeSkills: path4.join(opts.projectRoot, ".claude", "skills"),
|
|
1012
|
-
inProjectPrompts: path4.join(opts.projectRoot, ".wrongstack", "prompts"),
|
|
1013
|
-
inProjectInstructions: path4.join(opts.projectRoot, ".wrongstack", "instructions"),
|
|
1014
|
-
inProjectDesignKits: path4.join(opts.projectRoot, ".wrongstack", "design-kits"),
|
|
1015
|
-
inProjectWorktrees: path4.join(opts.projectRoot, ".wrongstack", "worktrees"),
|
|
1016
|
-
projectHash: hash,
|
|
1017
|
-
projectSlug: slug,
|
|
1018
|
-
projectGoal: path4.join(projectDir, "goal.json"),
|
|
1019
|
-
projectInputHistory: path4.join(projectDir, "input-history.json"),
|
|
1020
|
-
projectSpecs: path4.join(projectDir, "specs"),
|
|
1021
|
-
projectTaskGraphs: path4.join(projectDir, "task-graphs"),
|
|
1022
|
-
projectSddSession: path4.join(projectDir, "sdd-session.json"),
|
|
1023
|
-
projectPlan: path4.join(projectDir, "plan.json"),
|
|
1024
|
-
projectAutophase: path4.join(projectDir, "autophase"),
|
|
1025
|
-
projectSddBoards: path4.join(projectDir, "sdd-boards"),
|
|
1026
|
-
syncConfig: path4.join(profileDir, "sync.json"),
|
|
1027
|
-
configHistoryDir: path4.join(globalRoot, "config-history"),
|
|
1028
|
-
projectStatus: (projectHash2) => path4.join(globalRoot, "projects", projectHash2, "status.json")
|
|
1029
|
-
};
|
|
1149
|
+
function materializeCheckpoint(checkpointCas, checkpoint, targetRoot) {
|
|
1150
|
+
return requiredCheckpointCas(checkpointCas, "materialization").materialize(
|
|
1151
|
+
checkpoint,
|
|
1152
|
+
targetRoot
|
|
1153
|
+
);
|
|
1030
1154
|
}
|
|
1031
1155
|
|
|
1032
|
-
// src/storage/file-session-writer.ts
|
|
1033
|
-
import { closeSync, createReadStream, fsyncSync, openSync, writeSync } from "node:fs";
|
|
1034
|
-
import * as fsp2 from "node:fs/promises";
|
|
1035
|
-
import * as path5 from "node:path";
|
|
1036
|
-
import { createInterface } from "node:readline";
|
|
1037
|
-
|
|
1038
1156
|
// src/storage/session-helpers.ts
|
|
1039
1157
|
function consumeControlString(value, start) {
|
|
1040
1158
|
let index = start;
|
|
@@ -2010,7 +2128,8 @@ var FileSessionWriter = class _FileSessionWriter {
|
|
|
2010
2128
|
promptIndex,
|
|
2011
2129
|
promptPreview,
|
|
2012
2130
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2013
|
-
fileCount
|
|
2131
|
+
fileCount,
|
|
2132
|
+
...workspaceCheckpoint ? { workspaceCheckpoint } : {}
|
|
2014
2133
|
});
|
|
2015
2134
|
}
|
|
2016
2135
|
async writeFileSnapshot(promptIndex, files) {
|
|
@@ -2742,57 +2861,82 @@ function formatInterruptedToolNotice(pendingToolUseCount) {
|
|
|
2742
2861
|
].join("\n");
|
|
2743
2862
|
}
|
|
2744
2863
|
|
|
2745
|
-
// src/storage/session-store/
|
|
2864
|
+
// src/storage/session-store/delete-session-artifacts.ts
|
|
2746
2865
|
import * as fsp5 from "node:fs/promises";
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2866
|
+
import * as path10 from "node:path";
|
|
2867
|
+
|
|
2868
|
+
// src/storage/session-store/paths.ts
|
|
2869
|
+
import * as path9 from "node:path";
|
|
2870
|
+
function sessionPath(storeDir, id, ext) {
|
|
2871
|
+
return sessionScopedPath(storeDir, id, ext);
|
|
2872
|
+
}
|
|
2873
|
+
function shardManifestPath(storeDir, shardKey) {
|
|
2874
|
+
return shardKey ? path9.join(storeDir, shardKey, "_manifest.json") : path9.join(storeDir, "_manifest.json");
|
|
2875
|
+
}
|
|
2876
|
+
function shardKeyForSessionId(id) {
|
|
2877
|
+
const dirName = path9.dirname(id);
|
|
2878
|
+
return dirName === "." ? "" : dirName;
|
|
2879
|
+
}
|
|
2880
|
+
async function ensureShardDir(storeDir, id) {
|
|
2881
|
+
const dirPath = path9.dirname(sessionScopedPath(storeDir, id, ""));
|
|
2882
|
+
await ensureDir(dirPath);
|
|
2883
|
+
return dirPath;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
// src/storage/session-store/delete-session-artifacts.ts
|
|
2887
|
+
async function deleteSessionArtifacts({
|
|
2888
|
+
rootDir,
|
|
2889
|
+
id,
|
|
2890
|
+
jsonlPath
|
|
2891
|
+
}) {
|
|
2892
|
+
const shardDir = path10.dirname(jsonlPath);
|
|
2893
|
+
const base = path10.basename(id);
|
|
2894
|
+
const sessDir = path10.join(shardDir, base);
|
|
2895
|
+
const deletions = [
|
|
2896
|
+
fsp5.unlink(jsonlPath),
|
|
2897
|
+
fsp5.unlink(sessionPath(rootDir, id, ".summary.json")),
|
|
2898
|
+
fsp5.unlink(sessionPath(rootDir, id, ".plan.json")),
|
|
2899
|
+
fsp5.unlink(sessionPath(rootDir, id, ".tasks.json")),
|
|
2900
|
+
fsp5.unlink(sessionPath(rootDir, id, ".todos.json"))
|
|
2901
|
+
];
|
|
2902
|
+
const results = await Promise.allSettled(deletions);
|
|
2903
|
+
for (const result of results) {
|
|
2904
|
+
if (result.status === "rejected") {
|
|
2905
|
+
warnDeleteFailure(id, result.reason);
|
|
2761
2906
|
}
|
|
2762
2907
|
}
|
|
2908
|
+
await fsp5.rm(sessDir, { recursive: true, force: true }).catch((err) => {
|
|
2909
|
+
console.warn(
|
|
2910
|
+
JSON.stringify({
|
|
2911
|
+
level: "warn",
|
|
2912
|
+
event: "session_store.rmdir_failed",
|
|
2913
|
+
sessionId: id,
|
|
2914
|
+
message: toErrorMessage(err),
|
|
2915
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2916
|
+
})
|
|
2917
|
+
);
|
|
2918
|
+
});
|
|
2763
2919
|
}
|
|
2764
|
-
|
|
2765
|
-
const
|
|
2766
|
-
if (
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
} catch {
|
|
2785
|
-
completeLength = lastNewline + 1;
|
|
2786
|
-
}
|
|
2787
|
-
}
|
|
2788
|
-
return {
|
|
2789
|
-
raw: buffer.subarray(0, completeLength).toString("utf8"),
|
|
2790
|
-
end: start + completeLength
|
|
2791
|
-
};
|
|
2792
|
-
} catch {
|
|
2793
|
-
return null;
|
|
2794
|
-
} finally {
|
|
2795
|
-
await handle?.close().catch(() => void 0);
|
|
2920
|
+
function warnDeleteFailure(id, reason) {
|
|
2921
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
2922
|
+
if (reason?.code === "ENOENT") return;
|
|
2923
|
+
console.warn(
|
|
2924
|
+
JSON.stringify({
|
|
2925
|
+
level: "warn",
|
|
2926
|
+
event: "session_store.delete_failed",
|
|
2927
|
+
sessionId: id,
|
|
2928
|
+
message: msg,
|
|
2929
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2930
|
+
})
|
|
2931
|
+
);
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
// src/storage/session-store/delete-session-guards.ts
|
|
2935
|
+
async function assertSessionCanBeDeleted(sessionId, isSessionInUse) {
|
|
2936
|
+
if (!isSessionInUse) return;
|
|
2937
|
+
const reason = await isSessionInUse(sessionId);
|
|
2938
|
+
if (reason) {
|
|
2939
|
+
throw new Error(`Session ${sessionId} is in use (${reason}) and cannot be deleted.`);
|
|
2796
2940
|
}
|
|
2797
2941
|
}
|
|
2798
2942
|
|
|
@@ -2806,7 +2950,7 @@ function isSessionJsonlFileName(name) {
|
|
|
2806
2950
|
|
|
2807
2951
|
// src/storage/session-store/directory-session-files.ts
|
|
2808
2952
|
import * as fsp6 from "node:fs/promises";
|
|
2809
|
-
import * as
|
|
2953
|
+
import * as path11 from "node:path";
|
|
2810
2954
|
function sessionIdForFile(prefix, name) {
|
|
2811
2955
|
const base = name.replace(/\.jsonl$/, "");
|
|
2812
2956
|
return prefix ? `${prefix}/${base}` : base;
|
|
@@ -2828,12 +2972,12 @@ async function collectSessionFiles(dir, prefix = "", depth = 0) {
|
|
|
2828
2972
|
if (entry.isDirectory()) {
|
|
2829
2973
|
dirEntries.push(entry);
|
|
2830
2974
|
} else if (entry.isFile() && isSessionJsonlFileName(entry.name)) {
|
|
2831
|
-
files.push({ id: sessionIdForFile(prefix, entry.name), filePath:
|
|
2975
|
+
files.push({ id: sessionIdForFile(prefix, entry.name), filePath: path11.join(dir, entry.name) });
|
|
2832
2976
|
}
|
|
2833
2977
|
}
|
|
2834
2978
|
const childFileArrays = await Promise.all(
|
|
2835
2979
|
dirEntries.map(
|
|
2836
|
-
(entry) => collectSessionFiles(
|
|
2980
|
+
(entry) => collectSessionFiles(path11.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
|
|
2837
2981
|
)
|
|
2838
2982
|
);
|
|
2839
2983
|
return [...childFileArrays.flat(), ...files];
|
|
@@ -2857,236 +3001,61 @@ async function collectSessionIds(dir, prefix = "", depth = 0) {
|
|
|
2857
3001
|
}
|
|
2858
3002
|
const childIdArrays = await Promise.all(
|
|
2859
3003
|
dirEntries.map(
|
|
2860
|
-
(entry) => collectSessionIds(
|
|
3004
|
+
(entry) => collectSessionIds(path11.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
|
|
2861
3005
|
)
|
|
2862
3006
|
);
|
|
2863
3007
|
return [...childIdArrays.flat(), ...fileIds];
|
|
2864
3008
|
}
|
|
2865
3009
|
|
|
2866
|
-
// src/storage/session-store/
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
}
|
|
2878
|
-
function shardKeyForSessionId(id) {
|
|
2879
|
-
const dirName = path10.dirname(id);
|
|
2880
|
-
return dirName === "." ? "" : dirName;
|
|
2881
|
-
}
|
|
2882
|
-
async function ensureShardDir(storeDir, id) {
|
|
2883
|
-
const dirPath = path10.dirname(sessionScopedPath(storeDir, id, ""));
|
|
2884
|
-
await ensureDir(dirPath);
|
|
2885
|
-
return dirPath;
|
|
3010
|
+
// src/storage/session-store/events.ts
|
|
3011
|
+
function emitSessionStoreRead(events, sessionId, filePath, operation, outcome, durationMs, error) {
|
|
3012
|
+
events?.emit("storage.read", {
|
|
3013
|
+
sessionId,
|
|
3014
|
+
store: "session",
|
|
3015
|
+
filePath,
|
|
3016
|
+
operation,
|
|
3017
|
+
outcome,
|
|
3018
|
+
durationMs,
|
|
3019
|
+
...error !== void 0 ? { error } : {}
|
|
3020
|
+
});
|
|
2886
3021
|
}
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
const deletions = [
|
|
2898
|
-
fsp7.unlink(jsonlPath),
|
|
2899
|
-
fsp7.unlink(sessionPath(rootDir, id, ".summary.json")),
|
|
2900
|
-
fsp7.unlink(sessionPath(rootDir, id, ".plan.json")),
|
|
2901
|
-
fsp7.unlink(sessionPath(rootDir, id, ".tasks.json")),
|
|
2902
|
-
fsp7.unlink(sessionPath(rootDir, id, ".todos.json"))
|
|
2903
|
-
];
|
|
2904
|
-
const results = await Promise.allSettled(deletions);
|
|
2905
|
-
for (const result of results) {
|
|
2906
|
-
if (result.status === "rejected") {
|
|
2907
|
-
warnDeleteFailure(id, result.reason);
|
|
2908
|
-
}
|
|
2909
|
-
}
|
|
2910
|
-
await fsp7.rm(sessDir, { recursive: true, force: true }).catch((err) => {
|
|
2911
|
-
console.warn(
|
|
2912
|
-
JSON.stringify({
|
|
2913
|
-
level: "warn",
|
|
2914
|
-
event: "session_store.rmdir_failed",
|
|
2915
|
-
sessionId: id,
|
|
2916
|
-
message: toErrorMessage(err),
|
|
2917
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2918
|
-
})
|
|
2919
|
-
);
|
|
3022
|
+
function emitSessionStoreWrite(events, sessionId, filePath, operation, outcome, durationMs, eventCount, error) {
|
|
3023
|
+
events?.emit("storage.write", {
|
|
3024
|
+
sessionId,
|
|
3025
|
+
store: "session",
|
|
3026
|
+
filePath,
|
|
3027
|
+
operation,
|
|
3028
|
+
outcome,
|
|
3029
|
+
durationMs,
|
|
3030
|
+
...eventCount !== void 0 ? { eventCount } : {},
|
|
3031
|
+
...error !== void 0 ? { error } : {}
|
|
2920
3032
|
});
|
|
2921
3033
|
}
|
|
2922
|
-
function
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2932
|
-
})
|
|
2933
|
-
);
|
|
3034
|
+
function emitSessionStoreError(events, sessionId, filePath, operation, error, recoverable) {
|
|
3035
|
+
events?.emit("storage.error", {
|
|
3036
|
+
sessionId,
|
|
3037
|
+
store: "session",
|
|
3038
|
+
filePath,
|
|
3039
|
+
operation,
|
|
3040
|
+
error,
|
|
3041
|
+
recoverable
|
|
3042
|
+
});
|
|
2934
3043
|
}
|
|
2935
3044
|
|
|
2936
|
-
// src/storage/session-store/
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
this.entries = entries;
|
|
2951
|
-
}
|
|
2952
|
-
entries;
|
|
2953
|
-
bytes = 0;
|
|
2954
|
-
clear(sessionId) {
|
|
2955
|
-
if (sessionId !== void 0) {
|
|
2956
|
-
this.delete(sessionId);
|
|
2957
|
-
return;
|
|
2958
|
-
}
|
|
2959
|
-
this.entries.clear();
|
|
2960
|
-
this.bytes = 0;
|
|
2961
|
-
}
|
|
2962
|
-
getFresh(id, stat15, full) {
|
|
2963
|
-
const cached = this.entries.get(id);
|
|
2964
|
-
if (!cached || cached.mtimeMs !== stat15.mtimeMs || cached.size !== stat15.size) {
|
|
2965
|
-
return null;
|
|
2966
|
-
}
|
|
2967
|
-
this.entries.delete(id);
|
|
2968
|
-
this.entries.set(id, cached);
|
|
2969
|
-
if (full) return cached.data;
|
|
2970
|
-
return { ...cached.data, messages: [] };
|
|
2971
|
-
}
|
|
2972
|
-
set(id, stat15, data) {
|
|
2973
|
-
this.delete(id);
|
|
2974
|
-
while (stat15.size <= LOAD_CACHE_MAX_BYTES && (this.entries.size >= LOAD_CACHE_MAX_ENTRIES || this.bytes + stat15.size > LOAD_CACHE_MAX_BYTES)) {
|
|
2975
|
-
const oldest = this.entries.keys().next().value;
|
|
2976
|
-
if (oldest === void 0) break;
|
|
2977
|
-
this.delete(oldest);
|
|
2978
|
-
}
|
|
2979
|
-
if (stat15.size <= LOAD_CACHE_MAX_BYTES) {
|
|
2980
|
-
this.entries.set(id, { mtimeMs: stat15.mtimeMs, size: stat15.size, data });
|
|
2981
|
-
this.bytes += stat15.size;
|
|
2982
|
-
}
|
|
2983
|
-
}
|
|
2984
|
-
delete(sessionId) {
|
|
2985
|
-
const cached = this.entries.get(sessionId);
|
|
2986
|
-
if (cached) this.bytes = Math.max(0, this.bytes - cached.size);
|
|
2987
|
-
this.entries.delete(sessionId);
|
|
2988
|
-
}
|
|
2989
|
-
};
|
|
2990
|
-
|
|
2991
|
-
// src/storage/session-store/prune-helpers.ts
|
|
2992
|
-
import * as fsp8 from "node:fs/promises";
|
|
2993
|
-
import * as path12 from "node:path";
|
|
2994
|
-
function isPrunableSessionJsonl(name) {
|
|
2995
|
-
return name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
|
|
2996
|
-
}
|
|
2997
|
-
async function pruneSessionFiles(storeDir, maxAgeDays, deleteSession) {
|
|
2998
|
-
const cutoff = Date.now() - maxAgeDays * 864e5;
|
|
2999
|
-
let deleted = 0;
|
|
3000
|
-
const pruneFile = async (dir, name, prefix) => {
|
|
3001
|
-
const jsonlPath = path12.join(dir, name);
|
|
3002
|
-
try {
|
|
3003
|
-
const stat15 = await fsp8.stat(jsonlPath);
|
|
3004
|
-
if (stat15.mtimeMs >= cutoff) return;
|
|
3005
|
-
} catch {
|
|
3006
|
-
return;
|
|
3007
|
-
}
|
|
3008
|
-
const base = name.replace(/\.jsonl$/, "");
|
|
3009
|
-
const id = prefix ? `${prefix}/${base}` : base;
|
|
3010
|
-
await deleteSession(id);
|
|
3011
|
-
deleted++;
|
|
3012
|
-
};
|
|
3013
|
-
const entries = await fsp8.readdir(storeDir, { withFileTypes: true }).catch(() => []);
|
|
3014
|
-
for (const entry of entries) {
|
|
3015
|
-
if (entry.isFile()) {
|
|
3016
|
-
if (isPrunableSessionJsonl(entry.name)) await pruneFile(storeDir, entry.name, "");
|
|
3017
|
-
continue;
|
|
3018
|
-
}
|
|
3019
|
-
if (!entry.isDirectory()) continue;
|
|
3020
|
-
const dateDir = path12.join(storeDir, entry.name);
|
|
3021
|
-
const files = await fsp8.readdir(dateDir, { withFileTypes: true }).catch(() => []);
|
|
3022
|
-
for (const file of files) {
|
|
3023
|
-
if (!file.isFile() || !isPrunableSessionJsonl(file.name)) continue;
|
|
3024
|
-
await pruneFile(dateDir, file.name, entry.name);
|
|
3025
|
-
}
|
|
3026
|
-
}
|
|
3027
|
-
for (const entry of entries) {
|
|
3028
|
-
if (!entry.isDirectory()) continue;
|
|
3029
|
-
const dateDir = path12.join(storeDir, entry.name);
|
|
3030
|
-
try {
|
|
3031
|
-
const remaining = await fsp8.readdir(dateDir);
|
|
3032
|
-
if (remaining.length === 0) {
|
|
3033
|
-
await fsp8.rmdir(dateDir).catch(() => void 0);
|
|
3034
|
-
}
|
|
3035
|
-
} catch {
|
|
3036
|
-
}
|
|
3037
|
-
}
|
|
3038
|
-
return deleted;
|
|
3039
|
-
}
|
|
3040
|
-
|
|
3041
|
-
// src/storage/session-store/events.ts
|
|
3042
|
-
function emitSessionStoreRead(events, sessionId, filePath, operation, outcome, durationMs, error) {
|
|
3043
|
-
events?.emit("storage.read", {
|
|
3044
|
-
sessionId,
|
|
3045
|
-
store: "session",
|
|
3046
|
-
filePath,
|
|
3047
|
-
operation,
|
|
3048
|
-
outcome,
|
|
3049
|
-
durationMs,
|
|
3050
|
-
...error !== void 0 ? { error } : {}
|
|
3051
|
-
});
|
|
3052
|
-
}
|
|
3053
|
-
function emitSessionStoreWrite(events, sessionId, filePath, operation, outcome, durationMs, eventCount, error) {
|
|
3054
|
-
events?.emit("storage.write", {
|
|
3055
|
-
sessionId,
|
|
3056
|
-
store: "session",
|
|
3057
|
-
filePath,
|
|
3058
|
-
operation,
|
|
3059
|
-
outcome,
|
|
3060
|
-
durationMs,
|
|
3061
|
-
...eventCount !== void 0 ? { eventCount } : {},
|
|
3062
|
-
...error !== void 0 ? { error } : {}
|
|
3063
|
-
});
|
|
3064
|
-
}
|
|
3065
|
-
function emitSessionStoreError(events, sessionId, filePath, operation, error, recoverable) {
|
|
3066
|
-
events?.emit("storage.error", {
|
|
3067
|
-
sessionId,
|
|
3068
|
-
store: "session",
|
|
3069
|
-
filePath,
|
|
3070
|
-
operation,
|
|
3071
|
-
error,
|
|
3072
|
-
recoverable
|
|
3073
|
-
});
|
|
3074
|
-
}
|
|
3075
|
-
|
|
3076
|
-
// src/storage/session-store/fork-session.ts
|
|
3077
|
-
import { createHash as createHash4 } from "node:crypto";
|
|
3078
|
-
|
|
3079
|
-
// src/storage/session-store/replay.ts
|
|
3080
|
-
function isReplayableMessage(value) {
|
|
3081
|
-
if (!value || typeof value !== "object") return false;
|
|
3082
|
-
const candidate = value;
|
|
3083
|
-
return (candidate.role === "user" || candidate.role === "assistant" || candidate.role === "system") && (typeof candidate.content === "string" || Array.isArray(candidate.content));
|
|
3084
|
-
}
|
|
3085
|
-
function trackMessageToolState(message, openToolUses) {
|
|
3086
|
-
if (!Array.isArray(message.content)) return;
|
|
3087
|
-
for (const block of message.content) {
|
|
3088
|
-
if (block.type === "tool_use") openToolUses.add(block.id);
|
|
3089
|
-
else if (block.type === "tool_result") openToolUses.delete(block.tool_use_id);
|
|
3045
|
+
// src/storage/session-store/fork-session.ts
|
|
3046
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
3047
|
+
|
|
3048
|
+
// src/storage/session-store/replay.ts
|
|
3049
|
+
function isReplayableMessage(value) {
|
|
3050
|
+
if (!value || typeof value !== "object") return false;
|
|
3051
|
+
const candidate = value;
|
|
3052
|
+
return (candidate.role === "user" || candidate.role === "assistant" || candidate.role === "system") && (typeof candidate.content === "string" || Array.isArray(candidate.content));
|
|
3053
|
+
}
|
|
3054
|
+
function trackMessageToolState(message, openToolUses) {
|
|
3055
|
+
if (!Array.isArray(message.content)) return;
|
|
3056
|
+
for (const block of message.content) {
|
|
3057
|
+
if (block.type === "tool_use") openToolUses.add(block.id);
|
|
3058
|
+
else if (block.type === "tool_result") openToolUses.delete(block.tool_use_id);
|
|
3090
3059
|
}
|
|
3091
3060
|
}
|
|
3092
3061
|
function replayableMessage(value, fallbackTs) {
|
|
@@ -3187,6 +3156,106 @@ async function forkSession(host, id, opts = {}) {
|
|
|
3187
3156
|
}
|
|
3188
3157
|
}
|
|
3189
3158
|
|
|
3159
|
+
// src/storage/session-store/index-reader.ts
|
|
3160
|
+
import * as fsp7 from "node:fs/promises";
|
|
3161
|
+
function applySessionIndexLines(raw, byId, deleted) {
|
|
3162
|
+
for (const line of raw.split("\n")) {
|
|
3163
|
+
if (!line.trim()) continue;
|
|
3164
|
+
try {
|
|
3165
|
+
const entry = JSON.parse(line);
|
|
3166
|
+
if (entry.action === "delete" && entry.id) {
|
|
3167
|
+
deleted.add(entry.id);
|
|
3168
|
+
byId.delete(entry.id);
|
|
3169
|
+
continue;
|
|
3170
|
+
}
|
|
3171
|
+
if (entry.id && !deleted.has(entry.id)) {
|
|
3172
|
+
byId.set(entry.id, entry);
|
|
3173
|
+
}
|
|
3174
|
+
} catch {
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
async function readFileRange(file, start, end) {
|
|
3179
|
+
const length = end - start;
|
|
3180
|
+
if (length <= 0) return { raw: "", end: start };
|
|
3181
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
3182
|
+
let offset = 0;
|
|
3183
|
+
let handle;
|
|
3184
|
+
try {
|
|
3185
|
+
handle = await fsp7.open(file, "r");
|
|
3186
|
+
while (offset < length) {
|
|
3187
|
+
const { bytesRead } = await handle.read(buffer, offset, length - offset, start + offset);
|
|
3188
|
+
if (bytesRead === 0) return null;
|
|
3189
|
+
offset += bytesRead;
|
|
3190
|
+
}
|
|
3191
|
+
let completeLength = buffer.length;
|
|
3192
|
+
if (buffer.at(-1) !== 10) {
|
|
3193
|
+
const lastNewline = buffer.lastIndexOf(10);
|
|
3194
|
+
const trailing = buffer.subarray(lastNewline + 1).toString("utf8").trim();
|
|
3195
|
+
try {
|
|
3196
|
+
if (trailing) JSON.parse(trailing);
|
|
3197
|
+
else completeLength = lastNewline + 1;
|
|
3198
|
+
} catch {
|
|
3199
|
+
completeLength = lastNewline + 1;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
return {
|
|
3203
|
+
raw: buffer.subarray(0, completeLength).toString("utf8"),
|
|
3204
|
+
end: start + completeLength
|
|
3205
|
+
};
|
|
3206
|
+
} catch {
|
|
3207
|
+
return null;
|
|
3208
|
+
} finally {
|
|
3209
|
+
await handle?.close().catch(() => void 0);
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
// src/storage/session-store/load-cache.ts
|
|
3214
|
+
var LOAD_CACHE_MAX_ENTRIES = 50;
|
|
3215
|
+
var LOAD_CACHE_MAX_BYTES = 64 * 1024 * 1024;
|
|
3216
|
+
var SessionLoadCache = class {
|
|
3217
|
+
constructor(entries = /* @__PURE__ */ new Map()) {
|
|
3218
|
+
this.entries = entries;
|
|
3219
|
+
}
|
|
3220
|
+
entries;
|
|
3221
|
+
bytes = 0;
|
|
3222
|
+
clear(sessionId) {
|
|
3223
|
+
if (sessionId !== void 0) {
|
|
3224
|
+
this.delete(sessionId);
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
this.entries.clear();
|
|
3228
|
+
this.bytes = 0;
|
|
3229
|
+
}
|
|
3230
|
+
getFresh(id, stat15, full) {
|
|
3231
|
+
const cached = this.entries.get(id);
|
|
3232
|
+
if (!cached || cached.mtimeMs !== stat15.mtimeMs || cached.size !== stat15.size) {
|
|
3233
|
+
return null;
|
|
3234
|
+
}
|
|
3235
|
+
this.entries.delete(id);
|
|
3236
|
+
this.entries.set(id, cached);
|
|
3237
|
+
if (full) return cached.data;
|
|
3238
|
+
return { ...cached.data, messages: [] };
|
|
3239
|
+
}
|
|
3240
|
+
set(id, stat15, data) {
|
|
3241
|
+
this.delete(id);
|
|
3242
|
+
while (stat15.size <= LOAD_CACHE_MAX_BYTES && (this.entries.size >= LOAD_CACHE_MAX_ENTRIES || this.bytes + stat15.size > LOAD_CACHE_MAX_BYTES)) {
|
|
3243
|
+
const oldest = this.entries.keys().next().value;
|
|
3244
|
+
if (oldest === void 0) break;
|
|
3245
|
+
this.delete(oldest);
|
|
3246
|
+
}
|
|
3247
|
+
if (stat15.size <= LOAD_CACHE_MAX_BYTES) {
|
|
3248
|
+
this.entries.set(id, { mtimeMs: stat15.mtimeMs, size: stat15.size, data });
|
|
3249
|
+
this.bytes += stat15.size;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
delete(sessionId) {
|
|
3253
|
+
const cached = this.entries.get(sessionId);
|
|
3254
|
+
if (cached) this.bytes = Math.max(0, this.bytes - cached.size);
|
|
3255
|
+
this.entries.delete(sessionId);
|
|
3256
|
+
}
|
|
3257
|
+
};
|
|
3258
|
+
|
|
3190
3259
|
// src/storage/session-store/load-session-data.ts
|
|
3191
3260
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
3192
3261
|
import { createInterface as createInterface2 } from "node:readline";
|
|
@@ -3426,19 +3495,191 @@ function replaySessionEvent(params) {
|
|
|
3426
3495
|
}
|
|
3427
3496
|
return { exactJournalActive };
|
|
3428
3497
|
}
|
|
3429
|
-
function accumulateUsage(usage, ev) {
|
|
3430
|
-
return {
|
|
3431
|
-
input: usage.input + (ev.usage.input ?? 0),
|
|
3432
|
-
output: usage.output + (ev.usage.output ?? 0),
|
|
3433
|
-
cacheRead: (usage.cacheRead ?? 0) + (ev.usage.cacheRead ?? 0),
|
|
3434
|
-
cacheWrite: (usage.cacheWrite ?? 0) + (ev.usage.cacheWrite ?? 0)
|
|
3435
|
-
};
|
|
3498
|
+
function accumulateUsage(usage, ev) {
|
|
3499
|
+
return {
|
|
3500
|
+
input: usage.input + (ev.usage.input ?? 0),
|
|
3501
|
+
output: usage.output + (ev.usage.output ?? 0),
|
|
3502
|
+
cacheRead: (usage.cacheRead ?? 0) + (ev.usage.cacheRead ?? 0),
|
|
3503
|
+
cacheWrite: (usage.cacheWrite ?? 0) + (ev.usage.cacheWrite ?? 0)
|
|
3504
|
+
};
|
|
3505
|
+
}
|
|
3506
|
+
function emitDamaged(params, detail) {
|
|
3507
|
+
params.events?.emit("session.damaged", {
|
|
3508
|
+
sessionId: params.id,
|
|
3509
|
+
detail
|
|
3510
|
+
});
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
// src/storage/session-store/prune-helpers.ts
|
|
3514
|
+
import * as fsp8 from "node:fs/promises";
|
|
3515
|
+
import * as path12 from "node:path";
|
|
3516
|
+
function isPrunableSessionJsonl(name) {
|
|
3517
|
+
return name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
|
|
3518
|
+
}
|
|
3519
|
+
async function pruneSessionFiles(storeDir, maxAgeDays, deleteSession) {
|
|
3520
|
+
const cutoff = Date.now() - maxAgeDays * 864e5;
|
|
3521
|
+
let deleted = 0;
|
|
3522
|
+
const pruneFile = async (dir, name, prefix) => {
|
|
3523
|
+
const jsonlPath = path12.join(dir, name);
|
|
3524
|
+
try {
|
|
3525
|
+
const stat15 = await fsp8.stat(jsonlPath);
|
|
3526
|
+
if (stat15.mtimeMs >= cutoff) return;
|
|
3527
|
+
} catch {
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3530
|
+
const base = name.replace(/\.jsonl$/, "");
|
|
3531
|
+
const id = prefix ? `${prefix}/${base}` : base;
|
|
3532
|
+
await deleteSession(id);
|
|
3533
|
+
deleted++;
|
|
3534
|
+
};
|
|
3535
|
+
const entries = await fsp8.readdir(storeDir, { withFileTypes: true }).catch(() => []);
|
|
3536
|
+
for (const entry of entries) {
|
|
3537
|
+
if (entry.isFile()) {
|
|
3538
|
+
if (isPrunableSessionJsonl(entry.name)) await pruneFile(storeDir, entry.name, "");
|
|
3539
|
+
continue;
|
|
3540
|
+
}
|
|
3541
|
+
if (!entry.isDirectory()) continue;
|
|
3542
|
+
const dateDir = path12.join(storeDir, entry.name);
|
|
3543
|
+
const files = await fsp8.readdir(dateDir, { withFileTypes: true }).catch(() => []);
|
|
3544
|
+
for (const file of files) {
|
|
3545
|
+
if (!file.isFile() || !isPrunableSessionJsonl(file.name)) continue;
|
|
3546
|
+
await pruneFile(dateDir, file.name, entry.name);
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
for (const entry of entries) {
|
|
3550
|
+
if (!entry.isDirectory()) continue;
|
|
3551
|
+
const dateDir = path12.join(storeDir, entry.name);
|
|
3552
|
+
try {
|
|
3553
|
+
const remaining = await fsp8.readdir(dateDir);
|
|
3554
|
+
if (remaining.length === 0) {
|
|
3555
|
+
await fsp8.rmdir(dateDir).catch(() => void 0);
|
|
3556
|
+
}
|
|
3557
|
+
} catch {
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
return deleted;
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3563
|
+
// src/storage/session-store/search-events.ts
|
|
3564
|
+
import * as fsp9 from "node:fs/promises";
|
|
3565
|
+
async function searchSessionEvents(args) {
|
|
3566
|
+
const { file, secretScrubber, predicate, limit, signal } = args;
|
|
3567
|
+
const out = [];
|
|
3568
|
+
let stat15;
|
|
3569
|
+
try {
|
|
3570
|
+
stat15 = await fsp9.stat(file);
|
|
3571
|
+
} catch (err) {
|
|
3572
|
+
if (err.code === "ENOENT") return [];
|
|
3573
|
+
throw err;
|
|
3574
|
+
}
|
|
3575
|
+
if (stat15.size === 0) return [];
|
|
3576
|
+
let fh;
|
|
3577
|
+
try {
|
|
3578
|
+
fh = await fsp9.open(file, "r");
|
|
3579
|
+
const CHUNK = 64 * 1024;
|
|
3580
|
+
const buf = Buffer.alloc(CHUNK);
|
|
3581
|
+
let leftover = "";
|
|
3582
|
+
let eventIndex = 0;
|
|
3583
|
+
for (let position = 0; ; position += buf.byteLength) {
|
|
3584
|
+
if (signal?.aborted) {
|
|
3585
|
+
const reason = signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
3586
|
+
throw reason;
|
|
3587
|
+
}
|
|
3588
|
+
const { bytesRead } = await fh.read(buf, 0, CHUNK, position);
|
|
3589
|
+
if (bytesRead === 0) break;
|
|
3590
|
+
const text = leftover + buf.subarray(0, bytesRead).toString("utf8");
|
|
3591
|
+
const parts = text.split("\n");
|
|
3592
|
+
leftover = parts.pop() ?? "";
|
|
3593
|
+
for (const line of parts) {
|
|
3594
|
+
if (!line) continue;
|
|
3595
|
+
const ev = parseSessionEventLine(line, secretScrubber);
|
|
3596
|
+
if (!ev) continue;
|
|
3597
|
+
if (predicate(ev, eventIndex, ev.ts)) {
|
|
3598
|
+
out.push({ event: ev, eventIndex, ts: ev.ts });
|
|
3599
|
+
if (limit !== void 0 && out.length >= limit) return out;
|
|
3600
|
+
}
|
|
3601
|
+
eventIndex++;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
const trailing = parseSessionEventLine(leftover.trim() ? leftover : "", secretScrubber);
|
|
3605
|
+
if (trailing && predicate(trailing, eventIndex, trailing.ts)) {
|
|
3606
|
+
out.push({ event: trailing, eventIndex, ts: trailing.ts });
|
|
3607
|
+
}
|
|
3608
|
+
return out;
|
|
3609
|
+
} finally {
|
|
3610
|
+
if (fh) await fh.close().catch(() => void 0);
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
function parseSessionEventLine(line, secretScrubber) {
|
|
3614
|
+
if (!line) return null;
|
|
3615
|
+
try {
|
|
3616
|
+
const parsed = JSON.parse(line);
|
|
3617
|
+
if (parsed === null || typeof parsed !== "object" || typeof parsed.type !== "string" || typeof parsed.ts !== "string") {
|
|
3618
|
+
return null;
|
|
3619
|
+
}
|
|
3620
|
+
return scrubPersistedSessionEvent(parsed, secretScrubber);
|
|
3621
|
+
} catch {
|
|
3622
|
+
return null;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
// src/storage/session-store/shard-manifest.ts
|
|
3627
|
+
import * as fsp10 from "node:fs/promises";
|
|
3628
|
+
|
|
3629
|
+
// src/storage/session-summary.ts
|
|
3630
|
+
function compareSessionSummaries(a, b) {
|
|
3631
|
+
const aActivity = a.lastActivityAt ?? a.endedAt ?? a.startedAt;
|
|
3632
|
+
const bActivity = b.lastActivityAt ?? b.endedAt ?? b.startedAt;
|
|
3633
|
+
if (aActivity < bActivity) return 1;
|
|
3634
|
+
if (aActivity > bActivity) return -1;
|
|
3635
|
+
if (a.startedAt < b.startedAt) return 1;
|
|
3636
|
+
if (a.startedAt > b.startedAt) return -1;
|
|
3637
|
+
return a.id.localeCompare(b.id);
|
|
3638
|
+
}
|
|
3639
|
+
function matchesSessionFilter(summary, criteria) {
|
|
3640
|
+
if (criteria.since && summary.startedAt < criteria.since) return false;
|
|
3641
|
+
if (criteria.until && summary.startedAt > criteria.until) return false;
|
|
3642
|
+
if (criteria.provider && summary.provider !== criteria.provider) return false;
|
|
3643
|
+
if (criteria.model && summary.model !== criteria.model) return false;
|
|
3644
|
+
if (criteria.minTokens !== void 0 && summary.tokenTotal < criteria.minTokens) return false;
|
|
3645
|
+
if (criteria.titleContains) {
|
|
3646
|
+
const needle = criteria.titleContains.toLocaleLowerCase();
|
|
3647
|
+
if (!summary.title.toLocaleLowerCase().includes(needle)) return false;
|
|
3648
|
+
}
|
|
3649
|
+
return true;
|
|
3436
3650
|
}
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3651
|
+
|
|
3652
|
+
// src/storage/session-store/shard-manifest.ts
|
|
3653
|
+
async function readOrBuildShardManifestEntry(opts) {
|
|
3654
|
+
try {
|
|
3655
|
+
const raw = await fsp10.readFile(opts.manifestPath, "utf8");
|
|
3656
|
+
const parsed = JSON.parse(raw);
|
|
3657
|
+
return {
|
|
3658
|
+
summaries: Array.isArray(parsed.summaries) ? parsed.summaries : [],
|
|
3659
|
+
ids: Array.isArray(parsed.ids) ? parsed.ids : []
|
|
3660
|
+
};
|
|
3661
|
+
} catch {
|
|
3662
|
+
}
|
|
3663
|
+
const refs = await opts.collectSessionFilesInShard(opts.shardKey);
|
|
3664
|
+
const candidates = await mapWithConcurrency(
|
|
3665
|
+
refs,
|
|
3666
|
+
opts.concurrency,
|
|
3667
|
+
async (ref) => {
|
|
3668
|
+
const manifest = await opts.readSummaryManifest(ref.id);
|
|
3669
|
+
if (manifest) return { summary: manifest, needsBackfill: false };
|
|
3670
|
+
const summary = await opts.summaryHeaderFor(ref);
|
|
3671
|
+
if (!summary) return null;
|
|
3672
|
+
const hydrated = await opts.summaryFor(summary.id).catch(() => summary);
|
|
3673
|
+
return { summary: hydrated, needsBackfill: false };
|
|
3674
|
+
}
|
|
3675
|
+
);
|
|
3676
|
+
const summaries = candidates.filter((candidate) => candidate !== null).map((candidate) => candidate.summary);
|
|
3677
|
+
summaries.sort(compareSessionSummaries);
|
|
3678
|
+
const entry = { summaries, ids: summaries.map((summary) => summary.id) };
|
|
3679
|
+
await atomicWrite(opts.manifestPath, JSON.stringify(entry), { mode: 384 }).catch(
|
|
3680
|
+
() => void 0
|
|
3681
|
+
);
|
|
3682
|
+
return entry;
|
|
3442
3683
|
}
|
|
3443
3684
|
|
|
3444
3685
|
// src/storage/session-store/summary-builder.ts
|
|
@@ -3580,11 +3821,11 @@ async function* iterateSessionEvents(file, secretScrubber) {
|
|
|
3580
3821
|
}
|
|
3581
3822
|
|
|
3582
3823
|
// src/storage/session-store/summary-header.ts
|
|
3583
|
-
import * as
|
|
3824
|
+
import * as fsp11 from "node:fs/promises";
|
|
3584
3825
|
async function readSessionSummaryHeader(ref, secretScrubber) {
|
|
3585
3826
|
let mtime = (/* @__PURE__ */ new Date(0)).toISOString();
|
|
3586
3827
|
try {
|
|
3587
|
-
const stat15 = await
|
|
3828
|
+
const stat15 = await fsp11.stat(ref.filePath);
|
|
3588
3829
|
if (!stat15.isFile()) return damagedSummary(ref.id, stat15.mtime.toISOString());
|
|
3589
3830
|
mtime = stat15.mtime.toISOString();
|
|
3590
3831
|
} catch {
|
|
@@ -3629,128 +3870,6 @@ function damagedSummary(id, startedAt) {
|
|
|
3629
3870
|
};
|
|
3630
3871
|
}
|
|
3631
3872
|
|
|
3632
|
-
// src/storage/session-store/shard-manifest.ts
|
|
3633
|
-
import * as fsp10 from "node:fs/promises";
|
|
3634
|
-
|
|
3635
|
-
// src/storage/session-summary.ts
|
|
3636
|
-
function compareSessionSummaries(a, b) {
|
|
3637
|
-
const aActivity = a.lastActivityAt ?? a.endedAt ?? a.startedAt;
|
|
3638
|
-
const bActivity = b.lastActivityAt ?? b.endedAt ?? b.startedAt;
|
|
3639
|
-
if (aActivity < bActivity) return 1;
|
|
3640
|
-
if (aActivity > bActivity) return -1;
|
|
3641
|
-
if (a.startedAt < b.startedAt) return 1;
|
|
3642
|
-
if (a.startedAt > b.startedAt) return -1;
|
|
3643
|
-
return a.id.localeCompare(b.id);
|
|
3644
|
-
}
|
|
3645
|
-
function matchesSessionFilter(summary, criteria) {
|
|
3646
|
-
if (criteria.since && summary.startedAt < criteria.since) return false;
|
|
3647
|
-
if (criteria.until && summary.startedAt > criteria.until) return false;
|
|
3648
|
-
if (criteria.provider && summary.provider !== criteria.provider) return false;
|
|
3649
|
-
if (criteria.model && summary.model !== criteria.model) return false;
|
|
3650
|
-
if (criteria.minTokens !== void 0 && summary.tokenTotal < criteria.minTokens) return false;
|
|
3651
|
-
if (criteria.titleContains) {
|
|
3652
|
-
const needle = criteria.titleContains.toLocaleLowerCase();
|
|
3653
|
-
if (!summary.title.toLocaleLowerCase().includes(needle)) return false;
|
|
3654
|
-
}
|
|
3655
|
-
return true;
|
|
3656
|
-
}
|
|
3657
|
-
|
|
3658
|
-
// src/storage/session-store/shard-manifest.ts
|
|
3659
|
-
async function readOrBuildShardManifestEntry(opts) {
|
|
3660
|
-
try {
|
|
3661
|
-
const raw = await fsp10.readFile(opts.manifestPath, "utf8");
|
|
3662
|
-
const parsed = JSON.parse(raw);
|
|
3663
|
-
return {
|
|
3664
|
-
summaries: Array.isArray(parsed.summaries) ? parsed.summaries : [],
|
|
3665
|
-
ids: Array.isArray(parsed.ids) ? parsed.ids : []
|
|
3666
|
-
};
|
|
3667
|
-
} catch {
|
|
3668
|
-
}
|
|
3669
|
-
const refs = await opts.collectSessionFilesInShard(opts.shardKey);
|
|
3670
|
-
const candidates = await mapWithConcurrency(
|
|
3671
|
-
refs,
|
|
3672
|
-
opts.concurrency,
|
|
3673
|
-
async (ref) => {
|
|
3674
|
-
const manifest = await opts.readSummaryManifest(ref.id);
|
|
3675
|
-
if (manifest) return { summary: manifest, needsBackfill: false };
|
|
3676
|
-
const summary = await opts.summaryHeaderFor(ref);
|
|
3677
|
-
if (!summary) return null;
|
|
3678
|
-
const hydrated = await opts.summaryFor(summary.id).catch(() => summary);
|
|
3679
|
-
return { summary: hydrated, needsBackfill: false };
|
|
3680
|
-
}
|
|
3681
|
-
);
|
|
3682
|
-
const summaries = candidates.filter((candidate) => candidate !== null).map((candidate) => candidate.summary);
|
|
3683
|
-
summaries.sort(compareSessionSummaries);
|
|
3684
|
-
const entry = { summaries, ids: summaries.map((summary) => summary.id) };
|
|
3685
|
-
await atomicWrite(opts.manifestPath, JSON.stringify(entry), { mode: 384 }).catch(
|
|
3686
|
-
() => void 0
|
|
3687
|
-
);
|
|
3688
|
-
return entry;
|
|
3689
|
-
}
|
|
3690
|
-
|
|
3691
|
-
// src/storage/session-store/search-events.ts
|
|
3692
|
-
import * as fsp11 from "node:fs/promises";
|
|
3693
|
-
async function searchSessionEvents(args) {
|
|
3694
|
-
const { file, secretScrubber, predicate, limit, signal } = args;
|
|
3695
|
-
const out = [];
|
|
3696
|
-
let stat15;
|
|
3697
|
-
try {
|
|
3698
|
-
stat15 = await fsp11.stat(file);
|
|
3699
|
-
} catch (err) {
|
|
3700
|
-
if (err.code === "ENOENT") return [];
|
|
3701
|
-
throw err;
|
|
3702
|
-
}
|
|
3703
|
-
if (stat15.size === 0) return [];
|
|
3704
|
-
let fh;
|
|
3705
|
-
try {
|
|
3706
|
-
fh = await fsp11.open(file, "r");
|
|
3707
|
-
const CHUNK = 64 * 1024;
|
|
3708
|
-
const buf = Buffer.alloc(CHUNK);
|
|
3709
|
-
let leftover = "";
|
|
3710
|
-
let eventIndex = 0;
|
|
3711
|
-
for (let position = 0; ; position += buf.byteLength) {
|
|
3712
|
-
if (signal?.aborted) {
|
|
3713
|
-
const reason = signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
3714
|
-
throw reason;
|
|
3715
|
-
}
|
|
3716
|
-
const { bytesRead } = await fh.read(buf, 0, CHUNK, position);
|
|
3717
|
-
if (bytesRead === 0) break;
|
|
3718
|
-
const text = leftover + buf.subarray(0, bytesRead).toString("utf8");
|
|
3719
|
-
const parts = text.split("\n");
|
|
3720
|
-
leftover = parts.pop() ?? "";
|
|
3721
|
-
for (const line of parts) {
|
|
3722
|
-
if (!line) continue;
|
|
3723
|
-
const ev = parseSessionEventLine(line, secretScrubber);
|
|
3724
|
-
if (!ev) continue;
|
|
3725
|
-
if (predicate(ev, eventIndex, ev.ts)) {
|
|
3726
|
-
out.push({ event: ev, eventIndex, ts: ev.ts });
|
|
3727
|
-
if (limit !== void 0 && out.length >= limit) return out;
|
|
3728
|
-
}
|
|
3729
|
-
eventIndex++;
|
|
3730
|
-
}
|
|
3731
|
-
}
|
|
3732
|
-
const trailing = parseSessionEventLine(leftover.trim() ? leftover : "", secretScrubber);
|
|
3733
|
-
if (trailing && predicate(trailing, eventIndex, trailing.ts)) {
|
|
3734
|
-
out.push({ event: trailing, eventIndex, ts: trailing.ts });
|
|
3735
|
-
}
|
|
3736
|
-
return out;
|
|
3737
|
-
} finally {
|
|
3738
|
-
if (fh) await fh.close().catch(() => void 0);
|
|
3739
|
-
}
|
|
3740
|
-
}
|
|
3741
|
-
function parseSessionEventLine(line, secretScrubber) {
|
|
3742
|
-
if (!line) return null;
|
|
3743
|
-
try {
|
|
3744
|
-
const parsed = JSON.parse(line);
|
|
3745
|
-
if (parsed === null || typeof parsed !== "object" || typeof parsed.type !== "string" || typeof parsed.ts !== "string") {
|
|
3746
|
-
return null;
|
|
3747
|
-
}
|
|
3748
|
-
return scrubPersistedSessionEvent(parsed, secretScrubber);
|
|
3749
|
-
} catch {
|
|
3750
|
-
return null;
|
|
3751
|
-
}
|
|
3752
|
-
}
|
|
3753
|
-
|
|
3754
3873
|
// src/storage/session-store.ts
|
|
3755
3874
|
var DefaultSessionStore = class _DefaultSessionStore {
|
|
3756
3875
|
dir;
|
|
@@ -3891,13 +4010,17 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3891
4010
|
async fork(id, opts = {}) {
|
|
3892
4011
|
return forkSession(this, id, opts);
|
|
3893
4012
|
}
|
|
4013
|
+
/**
|
|
4014
|
+
* Capture the deterministic post-tool workspace identity through the store-owned CAS.
|
|
4015
|
+
*/
|
|
4016
|
+
async captureWorkspaceCheckpoint(sessionId, promptIndex) {
|
|
4017
|
+
return captureCheckpoint(this.checkpointCas, sessionId, promptIndex);
|
|
4018
|
+
}
|
|
4019
|
+
/**
|
|
4020
|
+
* Materialize a store-owned checkpoint into an already isolated workspace.
|
|
4021
|
+
*/
|
|
3894
4022
|
async materializeWorkspaceCheckpoint(checkpoint, targetRoot) {
|
|
3895
|
-
|
|
3896
|
-
throw new Error(
|
|
3897
|
-
"Workspace checkpoint materialization requires a projectRoot-aware session store"
|
|
3898
|
-
);
|
|
3899
|
-
}
|
|
3900
|
-
return this.checkpointCas.materialize(checkpoint, targetRoot);
|
|
4023
|
+
return materializeCheckpoint(this.checkpointCas, checkpoint, targetRoot);
|
|
3901
4024
|
}
|
|
3902
4025
|
async resolveId(query) {
|
|
3903
4026
|
const normalized = query.trim();
|
|
@@ -3982,9 +4105,12 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
3982
4105
|
handle = await fsp12.open(file, "a", 384);
|
|
3983
4106
|
} catch (err) {
|
|
3984
4107
|
emitSessionStoreError(this.events, canonicalId, file, "resume", toErrorMessage(err), false);
|
|
3985
|
-
throw new Error(
|
|
3986
|
-
|
|
3987
|
-
|
|
4108
|
+
throw new Error(
|
|
4109
|
+
`Failed to open session "${canonicalId}" for append: ${toErrorMessage(err)}`,
|
|
4110
|
+
{
|
|
4111
|
+
cause: err
|
|
4112
|
+
}
|
|
4113
|
+
);
|
|
3988
4114
|
}
|
|
3989
4115
|
try {
|
|
3990
4116
|
const writer = new FileSessionWriter(
|
|
@@ -4181,7 +4307,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
4181
4307
|
await withFileLock(this.indexFile, async () => {
|
|
4182
4308
|
await this.invalidateShardManifestBySessionId(summary.id);
|
|
4183
4309
|
const line = JSON.stringify(summary) + "\n";
|
|
4184
|
-
await fsp12.appendFile(this.indexFile, line, "utf8");
|
|
4310
|
+
await fsp12.appendFile(this.indexFile, line, { encoding: "utf8", mode: SECRET_FILE_MODE });
|
|
4185
4311
|
this._indexCache = null;
|
|
4186
4312
|
this.indexAppendCount++;
|
|
4187
4313
|
if (this.indexAppendCount >= _DefaultSessionStore.COMPACT_EVERY) {
|
|
@@ -4204,7 +4330,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
4204
4330
|
await ensureDir(this.dir);
|
|
4205
4331
|
await withFileLock(this.indexFile, async () => {
|
|
4206
4332
|
const line = JSON.stringify({ action: "delete", id }) + "\n";
|
|
4207
|
-
await fsp12.appendFile(this.indexFile, line, "utf8");
|
|
4333
|
+
await fsp12.appendFile(this.indexFile, line, { encoding: "utf8", mode: SECRET_FILE_MODE });
|
|
4208
4334
|
this._indexCache = null;
|
|
4209
4335
|
await this.invalidateShardManifestBySessionId(id);
|
|
4210
4336
|
this.indexAppendCount++;
|
|
@@ -4412,12 +4538,28 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
4412
4538
|
});
|
|
4413
4539
|
outcome = "failure";
|
|
4414
4540
|
errorMsg = "summary fallback \xE2\u20AC\u201D manifest rebuilt";
|
|
4415
|
-
emitSessionStoreRead(
|
|
4541
|
+
emitSessionStoreRead(
|
|
4542
|
+
this.events,
|
|
4543
|
+
id,
|
|
4544
|
+
manifest,
|
|
4545
|
+
"summary",
|
|
4546
|
+
outcome,
|
|
4547
|
+
Date.now() - t0,
|
|
4548
|
+
errorMsg
|
|
4549
|
+
);
|
|
4416
4550
|
return summary;
|
|
4417
4551
|
} catch (err) {
|
|
4418
4552
|
outcome = "failure";
|
|
4419
4553
|
errorMsg = toErrorMessage(err);
|
|
4420
|
-
emitSessionStoreRead(
|
|
4554
|
+
emitSessionStoreRead(
|
|
4555
|
+
this.events,
|
|
4556
|
+
id,
|
|
4557
|
+
manifest,
|
|
4558
|
+
"summary",
|
|
4559
|
+
outcome,
|
|
4560
|
+
Date.now() - t0,
|
|
4561
|
+
errorMsg
|
|
4562
|
+
);
|
|
4421
4563
|
return {
|
|
4422
4564
|
id,
|
|
4423
4565
|
title: "(damaged)",
|
|
@@ -4432,14 +4574,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
|
|
|
4432
4574
|
const manifest = this.sessionPath(id, ".summary.json");
|
|
4433
4575
|
try {
|
|
4434
4576
|
const raw = await fsp12.readFile(manifest, "utf8");
|
|
4435
|
-
emitSessionStoreRead(
|
|
4436
|
-
this.events,
|
|
4437
|
-
id,
|
|
4438
|
-
manifest,
|
|
4439
|
-
"summary",
|
|
4440
|
-
"success",
|
|
4441
|
-
Date.now() - startTime
|
|
4442
|
-
);
|
|
4577
|
+
emitSessionStoreRead(this.events, id, manifest, "summary", "success", Date.now() - startTime);
|
|
4443
4578
|
return JSON.parse(raw);
|
|
4444
4579
|
} catch {
|
|
4445
4580
|
return null;
|
|
@@ -5162,7 +5297,7 @@ var FileMemoryBackend = class {
|
|
|
5162
5297
|
const line = `- [${entry.ts}] ${id}${meta} ${entry.text.replace(/\n/g, " ")}
|
|
5163
5298
|
`;
|
|
5164
5299
|
await withFileLock(file, async () => {
|
|
5165
|
-
const handle = await fs3.open(file, "a+");
|
|
5300
|
+
const handle = await fs3.open(file, "a+", SECRET_FILE_MODE);
|
|
5166
5301
|
try {
|
|
5167
5302
|
const stat15 = await handle.stat();
|
|
5168
5303
|
let prefix = "";
|
|
@@ -6171,6 +6306,9 @@ async function readProviderSnapshot(configPath, vault, warn) {
|
|
|
6171
6306
|
if (typeof decrypted.uiLocale === "string" && decrypted.uiLocale)
|
|
6172
6307
|
snapshot.uiLocale = decrypted.uiLocale;
|
|
6173
6308
|
if (Array.isArray(decrypted.fallbackModels)) snapshot.fallbackModels = decrypted.fallbackModels;
|
|
6309
|
+
if (typeof decrypted.fallbackBridge === "string" && decrypted.fallbackBridge.trim()) {
|
|
6310
|
+
snapshot.fallbackBridge = decrypted.fallbackBridge.trim();
|
|
6311
|
+
}
|
|
6174
6312
|
if (decrypted.fallbackProfiles) snapshot.fallbackProfiles = decrypted.fallbackProfiles;
|
|
6175
6313
|
if (Array.isArray(decrypted.favoriteModels)) snapshot.favoriteModels = decrypted.favoriteModels;
|
|
6176
6314
|
if (typeof decrypted.favoriteModelsOnly === "boolean")
|
|
@@ -6188,6 +6326,7 @@ function serializeSnapshot(s) {
|
|
|
6188
6326
|
baseUrl: s.baseUrl ?? null,
|
|
6189
6327
|
uiLocale: s.uiLocale ?? null,
|
|
6190
6328
|
fallbackModels: s.fallbackModels ?? null,
|
|
6329
|
+
fallbackBridge: s.fallbackBridge ?? null,
|
|
6191
6330
|
fallbackProfiles: s.fallbackProfiles ?? null,
|
|
6192
6331
|
favoriteModels: s.favoriteModels ?? null,
|
|
6193
6332
|
favoriteModelsOnly: s.favoriteModelsOnly ?? null,
|
|
@@ -6402,7 +6541,13 @@ var CONFIG_BEHAVIOR_DEFAULTS = {
|
|
|
6402
6541
|
// models still get cost savings without capability loss. Explicit tiers
|
|
6403
6542
|
// are respected verbatim.
|
|
6404
6543
|
tokenSavingMode: "auto",
|
|
6405
|
-
|
|
6544
|
+
// Derived, never written by hand: this and `tools.restrictToProjectRoot`
|
|
6545
|
+
// (line 41) are the two halves of one switch, and they used to be declared
|
|
6546
|
+
// independently in this same object — one `true`, one `true` — with
|
|
6547
|
+
// session.ts resolving the contradiction via `??` in favour of the
|
|
6548
|
+
// permissive half. The confinement guard therefore shipped disabled on a
|
|
6549
|
+
// fresh install even though the other half asked for it (WS-075).
|
|
6550
|
+
allowOutsideProjectRoot: !DEFAULT_TOOLS_CONFIG.restrictToProjectRoot
|
|
6406
6551
|
},
|
|
6407
6552
|
Sage: {
|
|
6408
6553
|
enabled: true,
|
|
@@ -6481,9 +6626,11 @@ var CONFIG_BEHAVIOR_DEFAULTS = {
|
|
|
6481
6626
|
enhance: true,
|
|
6482
6627
|
enhanceDelayMs: 6e4,
|
|
6483
6628
|
enhanceLanguage: "original",
|
|
6484
|
-
|
|
6629
|
+
// Product-wide statusline density default. Mirrored by the TUI's
|
|
6630
|
+
// DEFAULT_STATUSLINE_MODE (packages/tui/src/components/settings-picker-model.ts).
|
|
6631
|
+
statuslineMode: "minimum",
|
|
6485
6632
|
thinkingWord: DEFAULT_TUI_THINKING_WORD,
|
|
6486
|
-
showAgentSwarmPanel:
|
|
6633
|
+
showAgentSwarmPanel: "bottom"
|
|
6487
6634
|
},
|
|
6488
6635
|
circuitBreaker: { ...DEFAULT_CIRCUIT_BREAKER_CONFIG },
|
|
6489
6636
|
modelRuntime: {
|
|
@@ -6650,6 +6797,7 @@ var IN_PROJECT_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
6650
6797
|
"maxConcurrent",
|
|
6651
6798
|
"uiLocale",
|
|
6652
6799
|
"fallbackModels",
|
|
6800
|
+
"fallbackBridge",
|
|
6653
6801
|
"fallbackProfiles",
|
|
6654
6802
|
"favoriteModels",
|
|
6655
6803
|
"favoriteModelsOnly",
|
|
@@ -6712,6 +6860,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
6712
6860
|
"tools",
|
|
6713
6861
|
"mcpServers",
|
|
6714
6862
|
"fallbackModels",
|
|
6863
|
+
"fallbackBridge",
|
|
6715
6864
|
"fallbackProfiles",
|
|
6716
6865
|
"favoriteModels",
|
|
6717
6866
|
"favoriteModelsOnly",
|
|
@@ -6746,6 +6895,75 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
6746
6895
|
"brain",
|
|
6747
6896
|
"git"
|
|
6748
6897
|
]);
|
|
6898
|
+
var IN_PROJECT_DENIED_PATHS = [
|
|
6899
|
+
{
|
|
6900
|
+
path: "tools.exec.allow",
|
|
6901
|
+
reason: "Extends the exec allow-list; a repo could authorise its own binaries."
|
|
6902
|
+
},
|
|
6903
|
+
{ path: "tools.exec.danger", reason: "Weakens the destructive-command banner." },
|
|
6904
|
+
{ path: "skills.extraDirs", reason: "Loads skill definitions from repo-chosen directories." },
|
|
6905
|
+
{ path: "skills.registryUrl", reason: "Redirects skill installs to a repo-chosen host." },
|
|
6906
|
+
// Deliberately NOT denied: skills.mode and skills.eagerMaxChars. The audit
|
|
6907
|
+
// suggested stripping both, but config-loader-extra.test.ts classifies `mode`
|
|
6908
|
+
// as a safe preference with a stated rationale, and a repo can only use these
|
|
6909
|
+
// to move injection volume in either direction — the trust problem was that
|
|
6910
|
+
// repo-supplied skill bodies were indistinguishable from the user's own, which
|
|
6911
|
+
// the provenance tag in system-prompt-skill-bodies.ts now fixes. Re-classifying
|
|
6912
|
+
// them is a product call.
|
|
6913
|
+
{ path: "Sage.storage.directory", reason: "Redirects memory storage outside the profile." },
|
|
6914
|
+
{
|
|
6915
|
+
path: "autonomy.yolo",
|
|
6916
|
+
reason: "Alias for the denied top-level `yolo`, and it wins over the user setting \u2014 a repo-committed config could disable every permission prompt."
|
|
6917
|
+
},
|
|
6918
|
+
{
|
|
6919
|
+
path: "autonomy.defaultMode",
|
|
6920
|
+
reason: "Sets the startup autonomy mode; autonomy is user-owned, never repo-owned."
|
|
6921
|
+
},
|
|
6922
|
+
// Deliberately NOT denied: autonomy.autoProceedDelayMs and
|
|
6923
|
+
// autoProceedMaxIterations. They tune a mode the user has already switched on
|
|
6924
|
+
// rather than granting it, and config-loader-extra.test.ts classifies the
|
|
6925
|
+
// delay as a benign project preference. Re-classifying them is a product call.
|
|
6926
|
+
{
|
|
6927
|
+
path: "launch.autonomy",
|
|
6928
|
+
reason: "Launch-time autonomy mode; same user-owned boundary as autonomy.defaultMode."
|
|
6929
|
+
},
|
|
6930
|
+
{
|
|
6931
|
+
path: "features.allowOutsideProjectRoot",
|
|
6932
|
+
reason: "Short-circuits both the project-root containment check and the symlink realpath check in the file tools."
|
|
6933
|
+
},
|
|
6934
|
+
{
|
|
6935
|
+
path: "tools.restrictToProjectRoot",
|
|
6936
|
+
reason: "The other half of the filesystem confinement switch."
|
|
6937
|
+
}
|
|
6938
|
+
];
|
|
6939
|
+
function deleteNestedPath(target, path30) {
|
|
6940
|
+
const segments = path30.split(".");
|
|
6941
|
+
const last = segments[segments.length - 1];
|
|
6942
|
+
if (last === void 0) return false;
|
|
6943
|
+
let cursor = target;
|
|
6944
|
+
const chain = [];
|
|
6945
|
+
for (const segment of segments.slice(0, -1)) {
|
|
6946
|
+
const next = cursor[segment];
|
|
6947
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) return false;
|
|
6948
|
+
chain.push({ parent: cursor, key: segment });
|
|
6949
|
+
cursor = next;
|
|
6950
|
+
}
|
|
6951
|
+
if (!(last in cursor)) return false;
|
|
6952
|
+
const clonedLeaf = { ...cursor };
|
|
6953
|
+
delete clonedLeaf[last];
|
|
6954
|
+
let replacement = clonedLeaf;
|
|
6955
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
6956
|
+
const link2 = chain[i];
|
|
6957
|
+
if (!link2) continue;
|
|
6958
|
+
replacement = { ...link2.parent, [link2.key]: replacement };
|
|
6959
|
+
if (i === 0) {
|
|
6960
|
+
for (const [k, v] of Object.entries(replacement)) target[k] = v;
|
|
6961
|
+
return true;
|
|
6962
|
+
}
|
|
6963
|
+
}
|
|
6964
|
+
for (const [k, v] of Object.entries(replacement)) target[k] = v;
|
|
6965
|
+
return true;
|
|
6966
|
+
}
|
|
6749
6967
|
function assertInProjectAllowListComplete() {
|
|
6750
6968
|
const missingFromBoth = [];
|
|
6751
6969
|
for (const key of KNOWN_CONFIG_TOP_LEVEL_KEYS) {
|
|
@@ -6775,6 +6993,22 @@ function assertInProjectAllowListComplete() {
|
|
|
6775
6993
|
`field(s) appear in BOTH IN_PROJECT_ALLOWED_KEYS and KNOWN_DENIED_IN_PROJECT: ` + duplicate.join(", ") + ". The allow-list wins at runtime; remove from one of the two."
|
|
6776
6994
|
);
|
|
6777
6995
|
}
|
|
6996
|
+
const orphanedPaths = IN_PROJECT_DENIED_PATHS.filter(
|
|
6997
|
+
({ path: path30 }) => !IN_PROJECT_ALLOWED_KEYS.has(path30.split(".")[0] ?? "")
|
|
6998
|
+
).map(({ path: path30 }) => path30);
|
|
6999
|
+
if (orphanedPaths.length > 0) {
|
|
7000
|
+
problems.push(
|
|
7001
|
+
`IN_PROJECT_DENIED_PATHS entr(ies) whose top-level parent is not allowed: ` + orphanedPaths.join(", ") + ". The parent is already stripped wholesale, so the nested denial is dead \u2014 remove it."
|
|
7002
|
+
);
|
|
7003
|
+
}
|
|
7004
|
+
const malformedPaths = IN_PROJECT_DENIED_PATHS.filter(
|
|
7005
|
+
({ path: path30 }) => path30.split(".").length < 2 || path30.split(".").some((s) => s.length === 0)
|
|
7006
|
+
).map(({ path: path30 }) => path30);
|
|
7007
|
+
if (malformedPaths.length > 0) {
|
|
7008
|
+
problems.push(
|
|
7009
|
+
`IN_PROJECT_DENIED_PATHS entr(ies) are not dotted nested paths: ` + malformedPaths.join(", ") + ". Top-level keys belong in KNOWN_DENIED_IN_PROJECT instead."
|
|
7010
|
+
);
|
|
7011
|
+
}
|
|
6778
7012
|
if (problems.length > 0) {
|
|
6779
7013
|
throw new Error(
|
|
6780
7014
|
`stripUnsafeInProjectFields drift check failed:
|
|
@@ -6797,58 +7031,8 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
|
|
|
6797
7031
|
}
|
|
6798
7032
|
stripped.push(k);
|
|
6799
7033
|
}
|
|
6800
|
-
const
|
|
6801
|
-
|
|
6802
|
-
const execCfg = outTools["exec"];
|
|
6803
|
-
if (execCfg && typeof execCfg === "object") {
|
|
6804
|
-
const hasAllow = "allow" in execCfg;
|
|
6805
|
-
const hasDanger = "danger" in execCfg;
|
|
6806
|
-
if (hasAllow || hasDanger) {
|
|
6807
|
-
const clonedExec = { ...execCfg };
|
|
6808
|
-
if (hasAllow) {
|
|
6809
|
-
delete clonedExec["allow"];
|
|
6810
|
-
stripped.push("tools.exec.allow");
|
|
6811
|
-
}
|
|
6812
|
-
if (hasDanger) {
|
|
6813
|
-
delete clonedExec["danger"];
|
|
6814
|
-
stripped.push("tools.exec.danger");
|
|
6815
|
-
}
|
|
6816
|
-
out["tools"] = {
|
|
6817
|
-
...outTools,
|
|
6818
|
-
exec: clonedExec
|
|
6819
|
-
};
|
|
6820
|
-
}
|
|
6821
|
-
}
|
|
6822
|
-
}
|
|
6823
|
-
const outSkills = out["skills"];
|
|
6824
|
-
if (outSkills && typeof outSkills === "object") {
|
|
6825
|
-
const skillsRec = outSkills;
|
|
6826
|
-
const needsClone = "extraDirs" in skillsRec || "registryUrl" in skillsRec;
|
|
6827
|
-
if (needsClone) {
|
|
6828
|
-
const clonedSkills = { ...skillsRec };
|
|
6829
|
-
if ("extraDirs" in clonedSkills) {
|
|
6830
|
-
delete clonedSkills["extraDirs"];
|
|
6831
|
-
stripped.push("skills.extraDirs");
|
|
6832
|
-
}
|
|
6833
|
-
if ("registryUrl" in clonedSkills) {
|
|
6834
|
-
delete clonedSkills["registryUrl"];
|
|
6835
|
-
stripped.push("skills.registryUrl");
|
|
6836
|
-
}
|
|
6837
|
-
out["skills"] = clonedSkills;
|
|
6838
|
-
}
|
|
6839
|
-
}
|
|
6840
|
-
const outSage = out["Sage"];
|
|
6841
|
-
if (outSage && typeof outSage === "object") {
|
|
6842
|
-
const storage = outSage["storage"];
|
|
6843
|
-
if (storage && typeof storage === "object" && "directory" in storage) {
|
|
6844
|
-
const clonedStorage = { ...storage };
|
|
6845
|
-
delete clonedStorage["directory"];
|
|
6846
|
-
out["Sage"] = {
|
|
6847
|
-
...outSage,
|
|
6848
|
-
storage: clonedStorage
|
|
6849
|
-
};
|
|
6850
|
-
stripped.push("Sage.storage.directory");
|
|
6851
|
-
}
|
|
7034
|
+
for (const { path: path30 } of IN_PROJECT_DENIED_PATHS) {
|
|
7035
|
+
if (deleteNestedPath(out, path30)) stripped.push(path30);
|
|
6852
7036
|
}
|
|
6853
7037
|
if (stripped.length > 0) {
|
|
6854
7038
|
warn(
|
|
@@ -8360,7 +8544,7 @@ var ReplayLogStore = class _ReplayLogStore {
|
|
|
8360
8544
|
} catch (err) {
|
|
8361
8545
|
if (err.code !== "ENOENT") throw err;
|
|
8362
8546
|
}
|
|
8363
|
-
await fs8.appendFile(fp, line, "utf8");
|
|
8547
|
+
await fs8.appendFile(fp, line, { encoding: "utf8", mode: SECRET_FILE_MODE });
|
|
8364
8548
|
cache.set(hash, { entry, offset: offset2, length: Buffer.byteLength(line, "utf8") });
|
|
8365
8549
|
this.diskCount.set(input.sessionId, currentCount + 1);
|
|
8366
8550
|
this.events?.emit("storage.write", {
|
|
@@ -9023,7 +9207,13 @@ var ToolAuditLog = class {
|
|
|
9023
9207
|
isError: input.isError,
|
|
9024
9208
|
index
|
|
9025
9209
|
};
|
|
9026
|
-
await fs10.appendFile(fp, JSON.stringify(entry) + "\n",
|
|
9210
|
+
await fs10.appendFile(fp, JSON.stringify(entry) + "\n", {
|
|
9211
|
+
encoding: "utf8",
|
|
9212
|
+
// WS-035: this file records raw tool INPUT and OUTPUT. Created
|
|
9213
|
+
// without a mode it lands 0644 — world-readable — while its
|
|
9214
|
+
// siblings under the same directory correctly use 0600.
|
|
9215
|
+
mode: SECRET_FILE_MODE
|
|
9216
|
+
});
|
|
9027
9217
|
try {
|
|
9028
9218
|
const st = await fs10.stat(fp);
|
|
9029
9219
|
this.tailStat.set(input.sessionId, { mtimeMs: st.mtimeMs, size: st.size });
|
|
@@ -9260,7 +9450,7 @@ var ToolAuditLog = class {
|
|
|
9260
9450
|
}
|
|
9261
9451
|
} catch {
|
|
9262
9452
|
} finally {
|
|
9263
|
-
this.unSyncedWrites.
|
|
9453
|
+
this.unSyncedWrites.delete(sessionId);
|
|
9264
9454
|
}
|
|
9265
9455
|
}
|
|
9266
9456
|
enqueue(sessionId, fn) {
|
|
@@ -12511,7 +12701,7 @@ function migratePromptEntry(raw) {
|
|
|
12511
12701
|
const tags = Array.isArray(r["tags"]) ? r["tags"].filter((t) => typeof t === "string") : [];
|
|
12512
12702
|
return {
|
|
12513
12703
|
id: r["id"],
|
|
12514
|
-
slug: typeof r["slug"] === "string" && r["slug"].length > 0 ? r["slug"] :
|
|
12704
|
+
slug: typeof r["slug"] === "string" && r["slug"].length > 0 ? r["slug"] : slugify2(title),
|
|
12515
12705
|
title,
|
|
12516
12706
|
description: typeof r["description"] === "string" ? r["description"] : "",
|
|
12517
12707
|
content,
|
|
@@ -12614,7 +12804,7 @@ var DefaultPromptStore = class {
|
|
|
12614
12804
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12615
12805
|
return {
|
|
12616
12806
|
id: ulid(),
|
|
12617
|
-
slug: extra.slug && extra.slug.length > 0 ? extra.slug :
|
|
12807
|
+
slug: extra.slug && extra.slug.length > 0 ? extra.slug : slugify2(title),
|
|
12618
12808
|
title,
|
|
12619
12809
|
description: extra.description ?? "",
|
|
12620
12810
|
content,
|
|
@@ -13374,6 +13564,9 @@ function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
|
13374
13564
|
async append(event) {
|
|
13375
13565
|
const target = resolveWriter();
|
|
13376
13566
|
if (!target) return;
|
|
13567
|
+
if (event.type === "tool_call_end") {
|
|
13568
|
+
progressCounters.delete(event.id);
|
|
13569
|
+
}
|
|
13377
13570
|
if (!isAllowed(event.type, currentLevel)) return;
|
|
13378
13571
|
if (!shouldSample(event)) return;
|
|
13379
13572
|
try {
|
|
@@ -13384,6 +13577,9 @@ function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
|
13384
13577
|
async appendBatch(events) {
|
|
13385
13578
|
const target = resolveWriter();
|
|
13386
13579
|
if (!target || events.length === 0) return;
|
|
13580
|
+
for (const e of events) {
|
|
13581
|
+
if (e.type === "tool_call_end") progressCounters.delete(e.id);
|
|
13582
|
+
}
|
|
13387
13583
|
const allowed = events.filter((e) => isAllowed(e.type, currentLevel) && shouldSample(e));
|
|
13388
13584
|
if (allowed.length === 0) return;
|
|
13389
13585
|
try {
|