@wrongstack/core 0.296.4 → 0.298.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +1076 -283
- package/dist/coordination/agents/index.js +136 -1
- package/dist/coordination/agents/role-skills.d.ts +3 -2
- package/dist/coordination/brain-cache.d.ts +14 -0
- 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 +16514 -15945
- 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-http-router.d.ts +6 -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 +1270 -289
- 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 +30 -4
- package/dist/coordination/sqlite-mailbox-credentials.d.ts +11 -0
- package/dist/core/context.d.ts +5 -5
- package/dist/core/fallback-profile-manager.d.ts +14 -0
- package/dist/core/index.js +624 -168
- 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 +2393 -1302
- package/dist/design/index.js +47 -8
- package/dist/execution/design-materialize.d.ts +22 -0
- package/dist/execution/index.js +582 -285
- 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 +71 -17
- package/dist/goal/phase-store.d.ts +7 -0
- 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 +680 -163
- package/dist/hq/kanban-store.d.ts +3 -0
- package/dist/hq/persistence/event-log.d.ts +25 -0
- package/dist/hq/persistence.d.ts +1 -1
- package/dist/hq/protocol/browser.d.ts +2 -1
- package/dist/hq/protocol/client.d.ts +18 -1
- package/dist/hq/protocol/core.d.ts +5 -16
- package/dist/hq/protocol/envelope.d.ts +29 -0
- package/dist/hq/protocol/governance.d.ts +34 -0
- package/dist/hq/protocol/peer.d.ts +55 -0
- package/dist/hq/protocol/project.d.ts +3 -0
- package/dist/hq/protocol/resume.d.ts +56 -0
- package/dist/hq/protocol.d.ts +11 -8
- package/dist/hq/protocol.js +675 -0
- package/dist/hq/publisher.d.ts +31 -2
- package/dist/hq/session-bridge.d.ts +8 -0
- package/dist/index.js +7197 -4006
- package/dist/infrastructure/index.js +198 -101
- 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.d.ts +1 -1
- package/dist/observability/index.js +103 -5
- package/dist/observability/metrics.d.ts +37 -0
- package/dist/observability/prometheus.d.ts +11 -0
- package/dist/plugin/index.d.ts +5 -1
- package/dist/plugin/index.js +965 -511
- package/dist/plugins/auto-review-plugin.d.ts +6 -0
- package/dist/plugins/review-store-maintenance.d.ts +26 -0
- package/dist/plugins/review-types.d.ts +6 -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 +3007 -2032
- package/dist/security/permission-policy.d.ts +55 -3
- 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/file-session-writer.d.ts +23 -0
- package/dist/storage/index.js +1140 -905
- package/dist/storage/provider-config-watcher.d.ts +1 -0
- package/dist/storage/session-helpers.d.ts +1 -0
- package/dist/storage/session-reader.d.ts +0 -7
- package/dist/storage/session-store/types.d.ts +12 -1
- package/dist/storage/session-store.d.ts +11 -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 +305 -133
- package/dist/tools/mcp-use.d.ts +1 -1
- package/dist/types/blocks.d.ts +7 -0
- package/dist/types/config/autonomy.d.ts +12 -3
- package/dist/types/config/mcp-features.d.ts +15 -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/observability.d.ts +13 -0
- package/dist/types/secret-vault.d.ts +8 -0
- package/dist/types/session.d.ts +42 -0
- package/dist/types/skill.d.ts +56 -0
- package/dist/types/tool-executor.d.ts +2 -0
- package/dist/utils/continuous-memory-profiler.d.ts +35 -0
- package/dist/utils/env-typed.d.ts +64 -0
- package/dist/utils/glob-match.d.ts +21 -1
- package/dist/utils/heap-watchdog-types.d.ts +62 -0
- package/dist/utils/heap-watchdog.d.ts +15 -34
- package/dist/utils/heap-watchdog.js +592 -18
- package/dist/utils/incoming-images.d.ts +19 -0
- package/dist/utils/index.d.ts +15 -11
- package/dist/utils/index.js +1425 -545
- package/dist/utils/memory-flight-recorder.d.ts +47 -0
- package/dist/utils/path-segment.d.ts +29 -0
- package/dist/utils/tool-name.d.ts +34 -0
- package/dist/utils/win32-cmd.d.ts +25 -0
- package/dist/worktree/index.js +5 -0
- package/package.json +11 -3
- package/skills/chimera/SKILL.md +16 -4
- package/skills/data-governance/SKILL.md +92 -0
- package/skills/wrongstack-kanban/SKILL.md +129 -0
- package/skills/wrongstack-kanban/agents/openai.yaml +4 -0
- package/skills/wrongstack-mailbox-mcp/SKILL.md +72 -0
- package/skills/wrongstack-mailbox-mcp/agents/openai.yaml +4 -0
- 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/project.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/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.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/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-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
|
@@ -1,10 +1,832 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/chronicle/project-server.ts
|
|
4
|
-
import
|
|
5
|
-
import * as
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
import * as fs9 from "node:fs";
|
|
6
|
+
import * as fsp4 from "node:fs/promises";
|
|
6
7
|
import * as net from "node:net";
|
|
7
|
-
import * as
|
|
8
|
+
import * as path15 from "node:path";
|
|
9
|
+
|
|
10
|
+
// src/utils/atomic-write.ts
|
|
11
|
+
import {
|
|
12
|
+
createPersistencePrimitives
|
|
13
|
+
} from "@wrongstack/persistence";
|
|
14
|
+
|
|
15
|
+
// src/types/errors.ts
|
|
16
|
+
var ERROR_CODES = {
|
|
17
|
+
// Provider
|
|
18
|
+
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
19
|
+
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
20
|
+
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
21
|
+
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
22
|
+
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
23
|
+
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
24
|
+
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
25
|
+
// Tool
|
|
26
|
+
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
27
|
+
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
28
|
+
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
29
|
+
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
30
|
+
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
31
|
+
// Config
|
|
32
|
+
CONFIG_INVALID: "CONFIG_INVALID",
|
|
33
|
+
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
34
|
+
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
35
|
+
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
36
|
+
// Plugin
|
|
37
|
+
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
38
|
+
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
39
|
+
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
40
|
+
// Agent
|
|
41
|
+
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
42
|
+
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
43
|
+
AGENT_ABORTED: "AGENT_ABORTED",
|
|
44
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
45
|
+
// Session
|
|
46
|
+
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
47
|
+
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
48
|
+
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
49
|
+
// Container / Registry
|
|
50
|
+
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
51
|
+
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
52
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
53
|
+
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
54
|
+
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
55
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
56
|
+
// File system
|
|
57
|
+
FS_READ_FAILED: "FS_READ_FAILED",
|
|
58
|
+
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
59
|
+
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
60
|
+
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
61
|
+
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
62
|
+
// SDD (Spec-Driven Development)
|
|
63
|
+
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
64
|
+
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
65
|
+
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
66
|
+
SDD_NOT_READY: "SDD_NOT_READY",
|
|
67
|
+
// General
|
|
68
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
69
|
+
PARSE_FAILED: "PARSE_FAILED",
|
|
70
|
+
UNKNOWN: "UNKNOWN"
|
|
71
|
+
};
|
|
72
|
+
var WrongStackError = class extends Error {
|
|
73
|
+
code;
|
|
74
|
+
subsystem;
|
|
75
|
+
severity;
|
|
76
|
+
recoverable;
|
|
77
|
+
context;
|
|
78
|
+
constructor(opts) {
|
|
79
|
+
super(opts.message, { cause: opts.cause });
|
|
80
|
+
this.name = "WrongStackError";
|
|
81
|
+
this.code = opts.code;
|
|
82
|
+
this.subsystem = opts.subsystem;
|
|
83
|
+
this.severity = opts.severity ?? "error";
|
|
84
|
+
this.recoverable = opts.recoverable ?? false;
|
|
85
|
+
this.context = opts.context;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Render a one-line user-facing description.
|
|
89
|
+
* Subclasses should override for domain-specific formatting.
|
|
90
|
+
*/
|
|
91
|
+
describe() {
|
|
92
|
+
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
93
|
+
return `${this.code}: ${this.message}${ctx}`;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
function formatContext(ctx) {
|
|
97
|
+
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
98
|
+
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
99
|
+
}
|
|
100
|
+
var FsError = class extends WrongStackError {
|
|
101
|
+
path;
|
|
102
|
+
constructor(opts) {
|
|
103
|
+
super({
|
|
104
|
+
message: opts.message,
|
|
105
|
+
code: opts.code,
|
|
106
|
+
subsystem: "fs",
|
|
107
|
+
severity: "error",
|
|
108
|
+
recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,
|
|
109
|
+
context: { path: opts.path, ...opts.context },
|
|
110
|
+
cause: opts.cause
|
|
111
|
+
});
|
|
112
|
+
this.name = "FsError";
|
|
113
|
+
this.path = opts.path;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/utils/atomic-write.ts
|
|
118
|
+
var primitives = createPersistencePrimitives({
|
|
119
|
+
createLockTimeoutError: ({ targetPath, timeoutMs }) => new FsError({
|
|
120
|
+
message: `Timed out waiting for file lock: ${targetPath}`,
|
|
121
|
+
code: "FS_ATOMIC_WRITE_FAILED",
|
|
122
|
+
path: targetPath,
|
|
123
|
+
context: { timeoutMs }
|
|
124
|
+
})
|
|
125
|
+
});
|
|
126
|
+
var atomicWrite = primitives.atomicWrite;
|
|
127
|
+
var atomicReplaceWithWriter = primitives.atomicReplaceWithWriter;
|
|
128
|
+
var ensureDir = primitives.ensureDir;
|
|
129
|
+
var withFileLock = primitives.withFileLock;
|
|
130
|
+
|
|
131
|
+
// src/utils/heap-watchdog.ts
|
|
132
|
+
import * as fs from "node:fs";
|
|
133
|
+
import * as fsp2 from "node:fs/promises";
|
|
134
|
+
import * as path3 from "node:path";
|
|
135
|
+
import { PerformanceObserver, constants as performanceConstants } from "node:perf_hooks";
|
|
136
|
+
import * as v8 from "node:v8";
|
|
137
|
+
|
|
138
|
+
// src/utils/memory-flight-recorder.ts
|
|
139
|
+
import * as fsp from "node:fs/promises";
|
|
140
|
+
import * as path2 from "node:path";
|
|
141
|
+
|
|
142
|
+
// src/utils/continuous-memory-profiler.ts
|
|
143
|
+
import { Session } from "node:inspector/promises";
|
|
144
|
+
var DEFAULT_SAMPLE_INTERVAL_BYTES = 512 * 1024;
|
|
145
|
+
var DEFAULT_STACK_DEPTH = 64;
|
|
146
|
+
var MAX_SUMMARY_STACKS = 20;
|
|
147
|
+
var MAX_FRAMES_PER_STACK = 12;
|
|
148
|
+
function errorMessage(error) {
|
|
149
|
+
return error instanceof Error ? error.message : String(error);
|
|
150
|
+
}
|
|
151
|
+
function numeric(value) {
|
|
152
|
+
if (typeof value === "bigint") return Number(value);
|
|
153
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
154
|
+
}
|
|
155
|
+
function summarizePprof(profile) {
|
|
156
|
+
const strings = profile.stringTable.strings;
|
|
157
|
+
const functions = new Map(profile.function.map((entry) => [numeric(entry.id), entry]));
|
|
158
|
+
const locations = new Map(profile.location.map((entry) => [numeric(entry.id), entry]));
|
|
159
|
+
const stacks = /* @__PURE__ */ new Map();
|
|
160
|
+
let sampledBytes = 0;
|
|
161
|
+
let sampledObjects = 0;
|
|
162
|
+
for (const sample of profile.sample) {
|
|
163
|
+
const objects = numeric(sample.value[0]);
|
|
164
|
+
const bytes = numeric(sample.value[1]);
|
|
165
|
+
sampledObjects += objects;
|
|
166
|
+
sampledBytes += bytes;
|
|
167
|
+
const frames = sample.locationId.slice(0, MAX_FRAMES_PER_STACK).flatMap((locationId) => {
|
|
168
|
+
const location = locations.get(numeric(locationId));
|
|
169
|
+
const line = location?.line[0];
|
|
170
|
+
const fn = line ? functions.get(numeric(line.functionId)) : void 0;
|
|
171
|
+
if (!fn) return [];
|
|
172
|
+
const name = strings[numeric(fn.name)] || "(anonymous)";
|
|
173
|
+
const filename = strings[numeric(fn.filename)] || "";
|
|
174
|
+
const lineNumber = numeric(line?.line);
|
|
175
|
+
return [filename ? `${name} (${filename}${lineNumber > 0 ? `:${lineNumber}` : ""})` : name];
|
|
176
|
+
});
|
|
177
|
+
if (frames.length === 0) frames.push("(unknown)");
|
|
178
|
+
const key = frames.join("\n");
|
|
179
|
+
const existing = stacks.get(key);
|
|
180
|
+
if (existing) {
|
|
181
|
+
existing.bytes += bytes;
|
|
182
|
+
existing.objects += objects;
|
|
183
|
+
} else {
|
|
184
|
+
stacks.set(key, { bytes, objects, frames });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
sampledBytes,
|
|
189
|
+
sampledObjects,
|
|
190
|
+
sampleCount: profile.sample.length,
|
|
191
|
+
topStacks: [...stacks.values()].sort((left, right) => right.bytes - left.bytes).slice(0, MAX_SUMMARY_STACKS)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function startDatadogProfiler() {
|
|
195
|
+
const pprof = await import("@datadog/pprof");
|
|
196
|
+
pprof.heap.start(DEFAULT_SAMPLE_INTERVAL_BYTES, DEFAULT_STACK_DEPTH);
|
|
197
|
+
let stopped = false;
|
|
198
|
+
return {
|
|
199
|
+
backend: "datadog-pprof",
|
|
200
|
+
capture: async () => {
|
|
201
|
+
if (stopped) throw new Error("Continuous memory profiler is stopped");
|
|
202
|
+
const profile = pprof.heap.profile();
|
|
203
|
+
return {
|
|
204
|
+
backend: "datadog-pprof",
|
|
205
|
+
data: await pprof.encode(profile),
|
|
206
|
+
extension: ".pb.gz",
|
|
207
|
+
summary: summarizePprof(profile)
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
stop: async () => {
|
|
211
|
+
if (stopped) return;
|
|
212
|
+
stopped = true;
|
|
213
|
+
pprof.heap.stop();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
async function startInspectorProfiler() {
|
|
218
|
+
const session = new Session();
|
|
219
|
+
session.connect();
|
|
220
|
+
try {
|
|
221
|
+
await session.post("HeapProfiler.enable");
|
|
222
|
+
await session.post("HeapProfiler.startSampling", {
|
|
223
|
+
samplingInterval: DEFAULT_SAMPLE_INTERVAL_BYTES,
|
|
224
|
+
includeObjectsCollectedByMajorGC: false,
|
|
225
|
+
includeObjectsCollectedByMinorGC: false
|
|
226
|
+
});
|
|
227
|
+
} catch (error) {
|
|
228
|
+
try {
|
|
229
|
+
session.disconnect();
|
|
230
|
+
} catch {
|
|
231
|
+
}
|
|
232
|
+
throw error;
|
|
233
|
+
}
|
|
234
|
+
let stopped = false;
|
|
235
|
+
return {
|
|
236
|
+
backend: "node-inspector",
|
|
237
|
+
capture: async () => {
|
|
238
|
+
if (stopped) throw new Error("Continuous memory profiler is stopped");
|
|
239
|
+
const result = await session.post("HeapProfiler.stopSampling");
|
|
240
|
+
await session.post("HeapProfiler.startSampling", {
|
|
241
|
+
samplingInterval: DEFAULT_SAMPLE_INTERVAL_BYTES,
|
|
242
|
+
includeObjectsCollectedByMajorGC: false,
|
|
243
|
+
includeObjectsCollectedByMinorGC: false
|
|
244
|
+
});
|
|
245
|
+
return {
|
|
246
|
+
backend: "node-inspector",
|
|
247
|
+
data: JSON.stringify(result.profile),
|
|
248
|
+
extension: ".heapprofile"
|
|
249
|
+
};
|
|
250
|
+
},
|
|
251
|
+
stop: async () => {
|
|
252
|
+
if (stopped) return;
|
|
253
|
+
stopped = true;
|
|
254
|
+
try {
|
|
255
|
+
await session.post("HeapProfiler.disable");
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
session.disconnect();
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
async function startContinuousMemoryProfiler() {
|
|
266
|
+
try {
|
|
267
|
+
return { profiler: await startDatadogProfiler() };
|
|
268
|
+
} catch (error) {
|
|
269
|
+
const fallbackReason = errorMessage(error);
|
|
270
|
+
return {
|
|
271
|
+
profiler: await startInspectorProfiler(),
|
|
272
|
+
fallbackReason
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// src/utils/wstack-paths.ts
|
|
278
|
+
import * as os from "node:os";
|
|
279
|
+
import * as path from "node:path";
|
|
280
|
+
function wstackGlobalRoot() {
|
|
281
|
+
const fromEnv = process.env["WRONGSTACK_HOME"];
|
|
282
|
+
if (fromEnv && fromEnv.trim().length > 0) return path.resolve(fromEnv);
|
|
283
|
+
return path.join(os.homedir(), ".wrongstack");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// src/utils/memory-flight-recorder.ts
|
|
287
|
+
var MB = 1024 * 1024;
|
|
288
|
+
var HOUR_MS = 60 * 60 * 1e3;
|
|
289
|
+
var DEFAULT_WINDOW_MS = 5 * 60 * 1e3;
|
|
290
|
+
var DEFAULT_MINIMUM_WINDOW_MS = 2 * 60 * 1e3;
|
|
291
|
+
var DEFAULT_COOLDOWN_MS = 15 * 60 * 1e3;
|
|
292
|
+
var DEFAULT_CONTINUOUS_CAPTURE_MS = 5 * 60 * 1e3;
|
|
293
|
+
var MAX_OBSERVATIONS = 24;
|
|
294
|
+
var MAX_CAPTURE_SESSIONS = 12;
|
|
295
|
+
var MAX_CAPTURES_PER_SESSION = 6;
|
|
296
|
+
var SESSION_MAX_AGE_MS = 7 * 24 * HOUR_MS;
|
|
297
|
+
function timestampSlug(date = /* @__PURE__ */ new Date()) {
|
|
298
|
+
return date.toISOString().replaceAll(":", "").replaceAll(".", "-");
|
|
299
|
+
}
|
|
300
|
+
async function pruneCaptureFiles(artifactDir) {
|
|
301
|
+
const entries = await fsp.readdir(artifactDir, { withFileTypes: true });
|
|
302
|
+
const captures = entries.filter(
|
|
303
|
+
(entry) => entry.isFile() && entry.name.startsWith("event-") && entry.name.endsWith(".json")
|
|
304
|
+
).map((entry) => entry.name).sort();
|
|
305
|
+
const remove = captures.slice(0, Math.max(0, captures.length - MAX_CAPTURES_PER_SESSION));
|
|
306
|
+
await Promise.all(
|
|
307
|
+
remove.flatMap((eventName) => {
|
|
308
|
+
const stem = eventName.slice("event-".length, -".json".length);
|
|
309
|
+
return [
|
|
310
|
+
fsp.rm(path2.join(artifactDir, eventName), { force: true }),
|
|
311
|
+
fsp.rm(path2.join(artifactDir, `allocations-${stem}.heapprofile`), { force: true }),
|
|
312
|
+
fsp.rm(path2.join(artifactDir, `allocations-${stem}.pb.gz`), { force: true })
|
|
313
|
+
];
|
|
314
|
+
})
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
async function pruneOldSessions(root, currentDir) {
|
|
318
|
+
const entries = await fsp.readdir(root, { withFileTypes: true });
|
|
319
|
+
const sessions = await Promise.all(
|
|
320
|
+
entries.filter((entry) => entry.isDirectory() && entry.name !== path2.basename(currentDir)).map(async (entry) => {
|
|
321
|
+
const fullPath = path2.join(root, entry.name);
|
|
322
|
+
const stat5 = await fsp.stat(fullPath);
|
|
323
|
+
return { fullPath, mtimeMs: stat5.mtimeMs };
|
|
324
|
+
})
|
|
325
|
+
);
|
|
326
|
+
sessions.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
327
|
+
const now = Date.now();
|
|
328
|
+
await Promise.all(
|
|
329
|
+
sessions.filter(
|
|
330
|
+
(session, index) => now - session.mtimeMs > SESSION_MAX_AGE_MS || index >= MAX_CAPTURE_SESSIONS && now - session.mtimeMs > 24 * HOUR_MS
|
|
331
|
+
).map((session) => fsp.rm(session.fullPath, { recursive: true, force: true }))
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
var ContinuousMemoryCaptureWriter = class {
|
|
335
|
+
artifactDir;
|
|
336
|
+
root;
|
|
337
|
+
ready;
|
|
338
|
+
profiler;
|
|
339
|
+
profilerBackend = "initializing";
|
|
340
|
+
fallbackReason;
|
|
341
|
+
startError;
|
|
342
|
+
lastSummary;
|
|
343
|
+
stopped = false;
|
|
344
|
+
constructor(root) {
|
|
345
|
+
this.root = root;
|
|
346
|
+
this.artifactDir = path2.join(root, `${timestampSlug()}-pid-${process.pid}`);
|
|
347
|
+
this.ready = this.start().catch((error) => {
|
|
348
|
+
this.startError = error instanceof Error ? error.message : String(error);
|
|
349
|
+
this.profilerBackend = "unavailable";
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
async start() {
|
|
353
|
+
const started = await startContinuousMemoryProfiler();
|
|
354
|
+
this.profiler = started.profiler;
|
|
355
|
+
this.profilerBackend = started.profiler.backend;
|
|
356
|
+
this.fallbackReason = started.fallbackReason;
|
|
357
|
+
}
|
|
358
|
+
diagnostics() {
|
|
359
|
+
return {
|
|
360
|
+
memoryProfilerBackend: this.profilerBackend,
|
|
361
|
+
...this.fallbackReason ? { memoryProfilerFallbackReason: this.fallbackReason } : {},
|
|
362
|
+
...this.startError ? { memoryProfilerStartError: this.startError } : {},
|
|
363
|
+
...this.lastSummary ? {
|
|
364
|
+
memoryProfileSampledBytes: this.lastSummary.sampledBytes,
|
|
365
|
+
memoryProfileSampledObjects: this.lastSummary.sampledObjects,
|
|
366
|
+
memoryProfileSampleCount: this.lastSummary.sampleCount,
|
|
367
|
+
memoryProfileTopStack: this.lastSummary.topStack,
|
|
368
|
+
memoryProfileTopStackBytes: this.lastSummary.topStackBytes
|
|
369
|
+
} : {}
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
async capture(event) {
|
|
373
|
+
await this.ready;
|
|
374
|
+
if (this.stopped) return;
|
|
375
|
+
let profile;
|
|
376
|
+
let captureError = this.startError;
|
|
377
|
+
if (!captureError && this.profiler) {
|
|
378
|
+
try {
|
|
379
|
+
profile = await this.profiler.capture();
|
|
380
|
+
const top = profile.summary?.topStacks[0];
|
|
381
|
+
if (profile.summary) {
|
|
382
|
+
this.lastSummary = {
|
|
383
|
+
sampledBytes: profile.summary.sampledBytes,
|
|
384
|
+
sampledObjects: profile.summary.sampledObjects,
|
|
385
|
+
sampleCount: profile.summary.sampleCount,
|
|
386
|
+
topStack: top?.frames.join(" <- "),
|
|
387
|
+
topStackBytes: top?.bytes
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
} catch (error) {
|
|
391
|
+
captureError = error instanceof Error ? error.message : String(error);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
await fsp.mkdir(this.artifactDir, { recursive: true });
|
|
395
|
+
const stem = `${timestampSlug(new Date(event.capturedAt))}-${event.reason}`;
|
|
396
|
+
await fsp.writeFile(
|
|
397
|
+
path2.join(this.artifactDir, `event-${stem}.json`),
|
|
398
|
+
`${JSON.stringify(
|
|
399
|
+
{
|
|
400
|
+
...event,
|
|
401
|
+
profilerBackend: profile?.backend ?? this.profilerBackend,
|
|
402
|
+
...profile?.summary ? { allocationSummary: profile.summary } : {},
|
|
403
|
+
...this.fallbackReason ? { profilerFallbackReason: this.fallbackReason } : {},
|
|
404
|
+
...captureError ? { captureError } : {}
|
|
405
|
+
},
|
|
406
|
+
null,
|
|
407
|
+
2
|
|
408
|
+
)}
|
|
409
|
+
`,
|
|
410
|
+
"utf8"
|
|
411
|
+
);
|
|
412
|
+
if (profile) {
|
|
413
|
+
await fsp.writeFile(
|
|
414
|
+
path2.join(this.artifactDir, `allocations-${stem}${profile.extension}`),
|
|
415
|
+
profile.data
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
await Promise.all([
|
|
419
|
+
pruneCaptureFiles(this.artifactDir),
|
|
420
|
+
fsp.mkdir(this.root, { recursive: true }).then(() => pruneOldSessions(this.root, this.artifactDir))
|
|
421
|
+
]);
|
|
422
|
+
}
|
|
423
|
+
async stop() {
|
|
424
|
+
if (this.stopped) return;
|
|
425
|
+
this.stopped = true;
|
|
426
|
+
await this.ready;
|
|
427
|
+
await this.profiler?.stop();
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function disabledWriter(artifactDir) {
|
|
431
|
+
return {
|
|
432
|
+
artifactDir,
|
|
433
|
+
capture: async () => void 0,
|
|
434
|
+
stop: async () => void 0
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
function createMemoryFlightRecorder(options = {}) {
|
|
438
|
+
const now = options.now ?? Date.now;
|
|
439
|
+
const startedAt2 = now();
|
|
440
|
+
const root = options.diagnosticsRoot ?? path2.join(wstackGlobalRoot(), "diagnostics", "memory");
|
|
441
|
+
const enabled = options.enabled ?? (process.env["WRONGSTACK_MEMORY_FLIGHT_RECORDER"] !== "0" && process.env["NODE_ENV"] !== "test");
|
|
442
|
+
const writer = options.captureWriter ?? (enabled ? new ContinuousMemoryCaptureWriter(root) : disabledWriter(path2.join(root, `${timestampSlug()}-pid-${process.pid}`)));
|
|
443
|
+
const observations = [];
|
|
444
|
+
const windowMs = options.windowMs ?? DEFAULT_WINDOW_MS;
|
|
445
|
+
const minimumWindowMs = options.minimumWindowMs ?? DEFAULT_MINIMUM_WINDOW_MS;
|
|
446
|
+
const cooldownMs = options.cooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
447
|
+
const continuousCaptureMs = options.continuousCaptureMs ?? DEFAULT_CONTINUOUS_CAPTURE_MS;
|
|
448
|
+
const warmupMs = options.warmupMs ?? 6e4;
|
|
449
|
+
let lastSignalCaptureAt = Number.NEGATIVE_INFINITY;
|
|
450
|
+
let lastContinuousCaptureAt = startedAt2;
|
|
451
|
+
let captureInFlight = false;
|
|
452
|
+
let capturePromise;
|
|
453
|
+
const observe = (sample, stats) => {
|
|
454
|
+
const at = now();
|
|
455
|
+
const postGcHeapUsed = typeof stats["postGcHeapUsed"] === "number" ? stats["postGcHeapUsed"] : 0;
|
|
456
|
+
const postMajorGcHeapUsed = typeof stats["postMajorGcHeapUsed"] === "number" ? stats["postMajorGcHeapUsed"] : 0;
|
|
457
|
+
const lastGcAgoMs = typeof stats["lastGcAgoMs"] === "number" ? stats["lastGcAgoMs"] : -1;
|
|
458
|
+
const lastMajorGcAgoMs = typeof stats["lastMajorGcAgoMs"] === "number" ? stats["lastMajorGcAgoMs"] : -1;
|
|
459
|
+
const retainedHeapUsed = postMajorGcHeapUsed > 0 && lastMajorGcAgoMs >= 0 && lastMajorGcAgoMs <= windowMs ? postMajorGcHeapUsed : postGcHeapUsed > 0 && lastGcAgoMs >= 0 && lastGcAgoMs <= minimumWindowMs ? postGcHeapUsed : sample.heapUsed;
|
|
460
|
+
observations.push({
|
|
461
|
+
at,
|
|
462
|
+
heapUsed: retainedHeapUsed,
|
|
463
|
+
rss: sample.rss,
|
|
464
|
+
nativeResidual: sample.nativeResidual ?? 0
|
|
465
|
+
});
|
|
466
|
+
while (observations.length > MAX_OBSERVATIONS || observations.length > 1 && at - (observations[0]?.at ?? at) > windowMs) {
|
|
467
|
+
observations.shift();
|
|
468
|
+
}
|
|
469
|
+
const first = observations[0] ?? observations.at(-1);
|
|
470
|
+
const elapsedMs = first ? Math.max(0, at - first.at) : 0;
|
|
471
|
+
const heapGrowthBytes = first ? retainedHeapUsed - first.heapUsed : 0;
|
|
472
|
+
const rssGrowthBytes = first ? sample.rss - first.rss : 0;
|
|
473
|
+
const nativeGrowthBytes = first ? (sample.nativeResidual ?? 0) - first.nativeResidual : 0;
|
|
474
|
+
const heapGrowthBytesPerHour = elapsedMs > 0 ? Math.round(heapGrowthBytes / elapsedMs * HOUR_MS) : 0;
|
|
475
|
+
const rssGrowthBytesPerHour = elapsedMs > 0 ? Math.round(rssGrowthBytes / elapsedMs * HOUR_MS) : 0;
|
|
476
|
+
const nativeGrowthBytesPerHour = elapsedMs > 0 ? Math.round(nativeGrowthBytes / elapsedMs * HOUR_MS) : 0;
|
|
477
|
+
let signal = "stable";
|
|
478
|
+
if ((sample.detachedContexts ?? 0) > 0) signal = "detached-contexts";
|
|
479
|
+
else if (heapGrowthBytes >= 32 * MB && heapGrowthBytesPerHour > 0) signal = "js-retention";
|
|
480
|
+
else if (nativeGrowthBytes >= 64 * MB && nativeGrowthBytesPerHour > 0) signal = "native-rss";
|
|
481
|
+
const diagnosis = {
|
|
482
|
+
memorySignal: signal,
|
|
483
|
+
memoryWindowMs: elapsedMs,
|
|
484
|
+
retainedHeapUsed,
|
|
485
|
+
transientHeapBytes: Math.max(0, sample.heapUsed - retainedHeapUsed),
|
|
486
|
+
heapGrowthBytes,
|
|
487
|
+
rssGrowthBytes,
|
|
488
|
+
nativeGrowthBytes,
|
|
489
|
+
heapGrowthBytesPerHour,
|
|
490
|
+
rssGrowthBytesPerHour,
|
|
491
|
+
nativeGrowthBytesPerHour,
|
|
492
|
+
memoryArtifactDir: writer.artifactDir,
|
|
493
|
+
...writer.diagnostics?.() ?? {}
|
|
494
|
+
};
|
|
495
|
+
let reason;
|
|
496
|
+
if (at - startedAt2 >= warmupMs) {
|
|
497
|
+
if ((sample.detachedContexts ?? 0) > 0) reason = "detached-contexts";
|
|
498
|
+
else if (sample.load >= 0.45) reason = "heap-load";
|
|
499
|
+
else if (sample.heapUsed >= (options.absoluteHeapBytes ?? 768 * MB)) {
|
|
500
|
+
reason = "absolute-heap";
|
|
501
|
+
} else if (elapsedMs >= minimumWindowMs && heapGrowthBytes >= (options.heapGrowthBytes ?? 32 * MB) && heapGrowthBytesPerHour >= (options.heapGrowthBytesPerHour ?? 192 * MB)) {
|
|
502
|
+
reason = "heap-growth";
|
|
503
|
+
} else if (elapsedMs >= minimumWindowMs && nativeGrowthBytes >= (options.nativeGrowthBytes ?? 128 * MB) && nativeGrowthBytesPerHour >= (options.nativeGrowthBytesPerHour ?? 256 * MB)) {
|
|
504
|
+
reason = "native-rss-growth";
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
const signalCaptureDue = reason !== void 0 && at - lastSignalCaptureAt >= cooldownMs;
|
|
508
|
+
const intervalCaptureDue = at - lastContinuousCaptureAt >= continuousCaptureMs;
|
|
509
|
+
const captureReason = signalCaptureDue ? reason : intervalCaptureDue ? "interval" : void 0;
|
|
510
|
+
if (enabled && captureReason && !captureInFlight) {
|
|
511
|
+
if (captureReason !== "interval") lastSignalCaptureAt = at;
|
|
512
|
+
lastContinuousCaptureAt = at;
|
|
513
|
+
captureInFlight = true;
|
|
514
|
+
diagnosis["memoryCaptureReason"] = captureReason;
|
|
515
|
+
capturePromise = writer.capture({
|
|
516
|
+
reason: captureReason,
|
|
517
|
+
capturedAt: new Date(at).toISOString(),
|
|
518
|
+
pid: process.pid,
|
|
519
|
+
sample,
|
|
520
|
+
stats,
|
|
521
|
+
diagnosis: { ...diagnosis },
|
|
522
|
+
observations: observations.map((observation) => ({ ...observation }))
|
|
523
|
+
}).catch(() => {
|
|
524
|
+
}).finally(() => {
|
|
525
|
+
captureInFlight = false;
|
|
526
|
+
capturePromise = void 0;
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
return diagnosis;
|
|
530
|
+
};
|
|
531
|
+
return {
|
|
532
|
+
artifactDir: writer.artifactDir,
|
|
533
|
+
observe,
|
|
534
|
+
stop: async () => {
|
|
535
|
+
await capturePromise;
|
|
536
|
+
await writer.stop();
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/utils/heap-watchdog.ts
|
|
542
|
+
var MB2 = 1024 * 1024;
|
|
543
|
+
function defaultHeapLogPath() {
|
|
544
|
+
const override = process.env["WRONGSTACK_HEAP_LOG_PATH"]?.trim();
|
|
545
|
+
if (override) return path3.resolve(override);
|
|
546
|
+
return path3.join(wstackGlobalRoot(), "logs", "heap.jsonl");
|
|
547
|
+
}
|
|
548
|
+
function takeHeapSample() {
|
|
549
|
+
const m = process.memoryUsage();
|
|
550
|
+
const heap = v8.getHeapStatistics();
|
|
551
|
+
const spaces = v8.getHeapSpaceStatistics();
|
|
552
|
+
const spaceUsed = (name) => spaces.find((space) => space.space_name === name)?.space_used_size ?? 0;
|
|
553
|
+
const limit = heap.heap_size_limit || 0;
|
|
554
|
+
let activeResources = 0;
|
|
555
|
+
let activeResourceTypes = "";
|
|
556
|
+
try {
|
|
557
|
+
const resources = process.getActiveResourcesInfo?.() ?? [];
|
|
558
|
+
activeResources = resources.length;
|
|
559
|
+
const counts = /* @__PURE__ */ new Map();
|
|
560
|
+
for (const resource of resources) counts.set(resource, (counts.get(resource) ?? 0) + 1);
|
|
561
|
+
activeResourceTypes = [...counts].sort(([left], [right]) => left.localeCompare(right)).map(([resource, count]) => `${resource}=${count}`).join(",");
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
566
|
+
rss: m.rss,
|
|
567
|
+
heapUsed: m.heapUsed,
|
|
568
|
+
heapTotal: m.heapTotal,
|
|
569
|
+
external: m.external,
|
|
570
|
+
arrayBuffers: m.arrayBuffers,
|
|
571
|
+
nativeResidual: Math.max(0, m.rss - m.heapTotal - m.external),
|
|
572
|
+
oldSpaceUsed: spaceUsed("old_space"),
|
|
573
|
+
newSpaceUsed: spaceUsed("new_space"),
|
|
574
|
+
largeObjectSpaceUsed: spaceUsed("large_object_space"),
|
|
575
|
+
codeSpaceUsed: spaceUsed("code_space"),
|
|
576
|
+
mallocedMemory: heap.malloced_memory,
|
|
577
|
+
peakMallocedMemory: heap.peak_malloced_memory,
|
|
578
|
+
nativeContexts: heap.number_of_native_contexts,
|
|
579
|
+
detachedContexts: heap.number_of_detached_contexts,
|
|
580
|
+
activeResources,
|
|
581
|
+
activeResourceTypes,
|
|
582
|
+
heapLimit: limit,
|
|
583
|
+
load: limit > 0 ? m.heapUsed / limit : 0
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function startHeapWatchdog(opts = {}) {
|
|
587
|
+
const profileMode = process.env["WRONGSTACK_MEMORY_PROFILE"] === "1";
|
|
588
|
+
const sampleEveryMs = opts.sampleEveryMs ?? (profileMode ? 5e3 : 3e4);
|
|
589
|
+
const logEveryMs = opts.logEveryMs ?? (profileMode ? 5e3 : 6e4);
|
|
590
|
+
const logPath = opts.logPath ?? defaultHeapLogPath();
|
|
591
|
+
const warnAt = opts.warnAt ?? 0.6;
|
|
592
|
+
const criticalAt = opts.criticalAt ?? 0.85;
|
|
593
|
+
const REARM_MARGIN = 0.05;
|
|
594
|
+
let warnArmed = true;
|
|
595
|
+
let criticalArmed = true;
|
|
596
|
+
let lastLogAt = 0;
|
|
597
|
+
let writeInFlight = false;
|
|
598
|
+
let pendingLine;
|
|
599
|
+
let drainPromise;
|
|
600
|
+
let stopped = false;
|
|
601
|
+
let dirReady = false;
|
|
602
|
+
const flightRecorder = createMemoryFlightRecorder();
|
|
603
|
+
let gcMajorCount = 0;
|
|
604
|
+
let gcMinorCount = 0;
|
|
605
|
+
let gcIncrementalCount = 0;
|
|
606
|
+
let gcWeakCallbackCount = 0;
|
|
607
|
+
let gcDurationMs = 0;
|
|
608
|
+
let postGcHeapUsed = 0;
|
|
609
|
+
let postMajorGcHeapUsed = 0;
|
|
610
|
+
let lastGcAt = 0;
|
|
611
|
+
let lastMajorGcAt = 0;
|
|
612
|
+
const gcObserver = new PerformanceObserver((list) => {
|
|
613
|
+
for (const entry of list.getEntries()) {
|
|
614
|
+
const kind = entry.detail?.kind ?? 0;
|
|
615
|
+
if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MAJOR) !== 0) gcMajorCount++;
|
|
616
|
+
if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MINOR) !== 0) gcMinorCount++;
|
|
617
|
+
if ((kind & performanceConstants.NODE_PERFORMANCE_GC_INCREMENTAL) !== 0) {
|
|
618
|
+
gcIncrementalCount++;
|
|
619
|
+
}
|
|
620
|
+
if ((kind & performanceConstants.NODE_PERFORMANCE_GC_WEAKCB) !== 0) gcWeakCallbackCount++;
|
|
621
|
+
gcDurationMs += entry.duration;
|
|
622
|
+
postGcHeapUsed = process.memoryUsage().heapUsed;
|
|
623
|
+
if ((kind & performanceConstants.NODE_PERFORMANCE_GC_MAJOR) !== 0) {
|
|
624
|
+
postMajorGcHeapUsed = postGcHeapUsed;
|
|
625
|
+
lastMajorGcAt = Date.now();
|
|
626
|
+
}
|
|
627
|
+
lastGcAt = Date.now();
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
try {
|
|
631
|
+
gcObserver.observe({ entryTypes: ["gc"] });
|
|
632
|
+
} catch {
|
|
633
|
+
}
|
|
634
|
+
const collectRuntimeStats = () => ({
|
|
635
|
+
gcMajorCount,
|
|
636
|
+
gcMinorCount,
|
|
637
|
+
gcIncrementalCount,
|
|
638
|
+
gcWeakCallbackCount,
|
|
639
|
+
gcDurationMs: Math.round(gcDurationMs),
|
|
640
|
+
postGcHeapUsed,
|
|
641
|
+
postMajorGcHeapUsed,
|
|
642
|
+
lastGcAgoMs: lastGcAt > 0 ? Date.now() - lastGcAt : -1,
|
|
643
|
+
lastMajorGcAgoMs: lastMajorGcAt > 0 ? Date.now() - lastMajorGcAt : -1
|
|
644
|
+
});
|
|
645
|
+
const writeDiagnosticLine = opts.writeDiagnosticLine ?? (async (targetPath, line) => {
|
|
646
|
+
if (!dirReady) {
|
|
647
|
+
await fsp2.mkdir(path3.dirname(targetPath), { recursive: true });
|
|
648
|
+
dirReady = true;
|
|
649
|
+
}
|
|
650
|
+
await fsp2.appendFile(targetPath, `${line}
|
|
651
|
+
`, { encoding: "utf8", mode: 384 });
|
|
652
|
+
});
|
|
653
|
+
const drainWrites = async (firstLine) => {
|
|
654
|
+
let line = firstLine;
|
|
655
|
+
while (line !== void 0) {
|
|
656
|
+
try {
|
|
657
|
+
await writeDiagnosticLine(logPath, line);
|
|
658
|
+
} catch {
|
|
659
|
+
}
|
|
660
|
+
line = pendingLine;
|
|
661
|
+
pendingLine = void 0;
|
|
662
|
+
}
|
|
663
|
+
writeInFlight = false;
|
|
664
|
+
};
|
|
665
|
+
const append = (line) => {
|
|
666
|
+
if (stopped) return;
|
|
667
|
+
if (writeInFlight) {
|
|
668
|
+
pendingLine = line;
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
writeInFlight = true;
|
|
672
|
+
drainPromise = drainWrites(line);
|
|
673
|
+
};
|
|
674
|
+
const appendTerminalSample = (event, error, origin) => {
|
|
675
|
+
if (stopped) return;
|
|
676
|
+
let extras = {};
|
|
677
|
+
try {
|
|
678
|
+
extras = opts.collectStats?.() ?? {};
|
|
679
|
+
} catch {
|
|
680
|
+
}
|
|
681
|
+
try {
|
|
682
|
+
const sample = takeHeapSample();
|
|
683
|
+
const runtimeStats = collectRuntimeStats();
|
|
684
|
+
fs.mkdirSync(path3.dirname(logPath), { recursive: true });
|
|
685
|
+
fs.appendFileSync(
|
|
686
|
+
logPath,
|
|
687
|
+
`${JSON.stringify({
|
|
688
|
+
...extras,
|
|
689
|
+
...runtimeStats,
|
|
690
|
+
event,
|
|
691
|
+
...origin ? { crashOrigin: origin } : {},
|
|
692
|
+
...error instanceof Error ? { errorName: error.name, errorMessage: error.message.slice(0, 1e3) } : {},
|
|
693
|
+
pid: process.pid,
|
|
694
|
+
...sample,
|
|
695
|
+
exitCode: process.exitCode
|
|
696
|
+
})}
|
|
697
|
+
`,
|
|
698
|
+
"utf8"
|
|
699
|
+
);
|
|
700
|
+
} catch {
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
const onUncaughtException = (error, origin) => {
|
|
704
|
+
appendTerminalSample("memory.flight_recorder.crash", error, origin);
|
|
705
|
+
};
|
|
706
|
+
const onProcessExit = () => {
|
|
707
|
+
appendTerminalSample("memory.flight_recorder.exit");
|
|
708
|
+
};
|
|
709
|
+
process.on("uncaughtExceptionMonitor", onUncaughtException);
|
|
710
|
+
process.on("exit", onProcessExit);
|
|
711
|
+
const tick = () => {
|
|
712
|
+
let userTimings = 0;
|
|
713
|
+
try {
|
|
714
|
+
userTimings = performance.getEntriesByType("mark").length + performance.getEntriesByType("measure").length;
|
|
715
|
+
if (userTimings > 0) {
|
|
716
|
+
performance.clearMarks();
|
|
717
|
+
performance.clearMeasures();
|
|
718
|
+
}
|
|
719
|
+
} catch {
|
|
720
|
+
}
|
|
721
|
+
const s = takeHeapSample();
|
|
722
|
+
let extras = {};
|
|
723
|
+
try {
|
|
724
|
+
extras = opts.collectStats?.() ?? {};
|
|
725
|
+
} catch {
|
|
726
|
+
}
|
|
727
|
+
const runtimeStats = collectRuntimeStats();
|
|
728
|
+
const diagnosticStats = { ...extras, ...runtimeStats };
|
|
729
|
+
const memoryDiagnosis = flightRecorder.observe(s, diagnosticStats);
|
|
730
|
+
if (s.load >= criticalAt && criticalArmed) {
|
|
731
|
+
criticalArmed = false;
|
|
732
|
+
warnArmed = false;
|
|
733
|
+
opts.onWarn?.(
|
|
734
|
+
"critical",
|
|
735
|
+
`Heap critical: ${Math.round(s.heapUsed / MB2)} MB of ~${Math.round(s.heapLimit / MB2)} MB V8 limit (${Math.round(s.load * 100)}%). An out-of-memory crash is likely soon \u2014 finish/checkpoint work and restart the session. Diagnostics: ${logPath}`,
|
|
736
|
+
s
|
|
737
|
+
);
|
|
738
|
+
} else if (s.load >= warnAt && warnArmed) {
|
|
739
|
+
warnArmed = false;
|
|
740
|
+
opts.onWarn?.(
|
|
741
|
+
"warn",
|
|
742
|
+
`Heap high: ${Math.round(s.heapUsed / MB2)} MB of ~${Math.round(s.heapLimit / MB2)} MB V8 limit (${Math.round(s.load * 100)}%). Memory diagnostics are being recorded to ${logPath}`,
|
|
743
|
+
s
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
if (!warnArmed && s.load < warnAt - REARM_MARGIN) warnArmed = true;
|
|
747
|
+
if (!criticalArmed && s.load < criticalAt - REARM_MARGIN) criticalArmed = true;
|
|
748
|
+
const due = Date.now() - lastLogAt >= logEveryMs;
|
|
749
|
+
const crossed = s.load >= warnAt;
|
|
750
|
+
const captured = typeof memoryDiagnosis["memoryCaptureReason"] === "string";
|
|
751
|
+
if (due || crossed || captured) {
|
|
752
|
+
lastLogAt = Date.now();
|
|
753
|
+
append(
|
|
754
|
+
JSON.stringify({
|
|
755
|
+
...extras,
|
|
756
|
+
...runtimeStats,
|
|
757
|
+
...memoryDiagnosis,
|
|
758
|
+
pid: process.pid,
|
|
759
|
+
...s,
|
|
760
|
+
userTimings
|
|
761
|
+
})
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
const timer = setInterval(tick, sampleEveryMs);
|
|
766
|
+
timer.unref?.();
|
|
767
|
+
tick();
|
|
768
|
+
return async () => {
|
|
769
|
+
stopped = true;
|
|
770
|
+
clearInterval(timer);
|
|
771
|
+
gcObserver.disconnect();
|
|
772
|
+
process.removeListener("uncaughtExceptionMonitor", onUncaughtException);
|
|
773
|
+
process.removeListener("exit", onProcessExit);
|
|
774
|
+
await drainPromise;
|
|
775
|
+
await flightRecorder.stop();
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
var sharedContributors = /* @__PURE__ */ new Map();
|
|
779
|
+
var nextSharedContributorId = 1;
|
|
780
|
+
var sharedSamplerActive = false;
|
|
781
|
+
var stopSharedSampler;
|
|
782
|
+
function collectSharedStats() {
|
|
783
|
+
const merged = {};
|
|
784
|
+
for (const contributor of sharedContributors.values()) {
|
|
785
|
+
try {
|
|
786
|
+
Object.assign(merged, contributor.collectStats?.() ?? {});
|
|
787
|
+
} catch {
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return merged;
|
|
791
|
+
}
|
|
792
|
+
function warnSharedContributors(level, message, sample) {
|
|
793
|
+
for (const contributor of sharedContributors.values()) {
|
|
794
|
+
try {
|
|
795
|
+
contributor.onWarn?.(level, message, sample);
|
|
796
|
+
} catch {
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
function startSharedHeapWatchdog(opts = {}) {
|
|
801
|
+
if (process.env["NODE_ENV"] === "test" && !sharedSamplerActive && opts.logPath === void 0 && opts.writeDiagnosticLine === void 0) {
|
|
802
|
+
return async () => void 0;
|
|
803
|
+
}
|
|
804
|
+
const id = nextSharedContributorId++;
|
|
805
|
+
sharedContributors.set(id, {
|
|
806
|
+
collectStats: opts.collectStats,
|
|
807
|
+
onWarn: opts.onWarn
|
|
808
|
+
});
|
|
809
|
+
if (!sharedSamplerActive) {
|
|
810
|
+
sharedSamplerActive = true;
|
|
811
|
+
stopSharedSampler = startHeapWatchdog({
|
|
812
|
+
...opts,
|
|
813
|
+
collectStats: collectSharedStats,
|
|
814
|
+
onWarn: warnSharedContributors
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
let stopped = false;
|
|
818
|
+
return async () => {
|
|
819
|
+
if (stopped) return;
|
|
820
|
+
stopped = true;
|
|
821
|
+
sharedContributors.delete(id);
|
|
822
|
+
if (sharedContributors.size > 0 || !sharedSamplerActive) return;
|
|
823
|
+
const stop2 = stopSharedSampler;
|
|
824
|
+
if (!stop2) return;
|
|
825
|
+
sharedSamplerActive = false;
|
|
826
|
+
stopSharedSampler = void 0;
|
|
827
|
+
await stop2();
|
|
828
|
+
};
|
|
829
|
+
}
|
|
8
830
|
|
|
9
831
|
// src/utils/perf-profile.ts
|
|
10
832
|
var daemonDefaults = false;
|
|
@@ -23,8 +845,8 @@ function createChronicleContext(scope, traceId = randomUUID()) {
|
|
|
23
845
|
|
|
24
846
|
// src/chronicle/file-observer.ts
|
|
25
847
|
import { createHash } from "node:crypto";
|
|
26
|
-
import * as
|
|
27
|
-
import * as
|
|
848
|
+
import * as fsp3 from "node:fs/promises";
|
|
849
|
+
import * as path5 from "node:path";
|
|
28
850
|
|
|
29
851
|
// src/storage/storage-concurrency.ts
|
|
30
852
|
async function mapWithConcurrency(items, concurrency, mapper) {
|
|
@@ -46,14 +868,14 @@ async function mapWithConcurrency(items, concurrency, mapper) {
|
|
|
46
868
|
}
|
|
47
869
|
|
|
48
870
|
// src/utils/project-watch.ts
|
|
49
|
-
import * as
|
|
50
|
-
import * as
|
|
871
|
+
import * as fs2 from "node:fs";
|
|
872
|
+
import * as path4 from "node:path";
|
|
51
873
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("wrongstack.projectWatchRegistry");
|
|
52
874
|
var globalScope = globalThis;
|
|
53
875
|
if (!globalScope[REGISTRY_KEY]) globalScope[REGISTRY_KEY] = /* @__PURE__ */ new Map();
|
|
54
876
|
var registry = globalScope[REGISTRY_KEY];
|
|
55
877
|
function registryKey(root) {
|
|
56
|
-
const resolved =
|
|
878
|
+
const resolved = path4.resolve(root);
|
|
57
879
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
58
880
|
}
|
|
59
881
|
function watchProjectTree(root, listener, opts) {
|
|
@@ -61,8 +883,8 @@ function watchProjectTree(root, listener, opts) {
|
|
|
61
883
|
let entry = registry.get(key);
|
|
62
884
|
if (!entry || entry.dead) {
|
|
63
885
|
const subscribers = /* @__PURE__ */ new Set();
|
|
64
|
-
const watcher2 =
|
|
65
|
-
|
|
886
|
+
const watcher2 = fs2.watch(
|
|
887
|
+
path4.resolve(root),
|
|
66
888
|
{ recursive: true, persistent: false },
|
|
67
889
|
(eventType, filename) => {
|
|
68
890
|
const event = {
|
|
@@ -146,7 +968,7 @@ var SCAN_HASH_CONCURRENCY = 32;
|
|
|
146
968
|
var DEFAULT_FULL_RESCAN_MIN_INTERVAL_MS = 3e4;
|
|
147
969
|
var MAX_RECENT_TOOL_MUTATIONS = 500;
|
|
148
970
|
async function startChronicleFileObserver(options) {
|
|
149
|
-
const root =
|
|
971
|
+
const root = path5.resolve(options.projectRoot);
|
|
150
972
|
const excluded = new Set(options.excludedDirectories ?? DEFAULT_EXCLUDED);
|
|
151
973
|
const excludedPaths = normalizeExcludedPaths(root, options.excludedPaths ?? []);
|
|
152
974
|
const debounceMs = options.debounceMs ?? 120;
|
|
@@ -154,8 +976,8 @@ async function startChronicleFileObserver(options) {
|
|
|
154
976
|
const known = (await scanProject(root, excluded, excludedPaths, maxHashBytes, options.onError)).files;
|
|
155
977
|
const recentToolMutations = /* @__PURE__ */ new Map();
|
|
156
978
|
const noteToolMutation = (hint) => {
|
|
157
|
-
const absolute =
|
|
158
|
-
const relative4 = normalizeRelative(
|
|
979
|
+
const absolute = path5.isAbsolute(hint.path) ? path5.normalize(hint.path) : path5.resolve(root, hint.path);
|
|
980
|
+
const relative4 = normalizeRelative(path5.relative(root, absolute));
|
|
159
981
|
if (relative4.startsWith("../") || isExcluded(relative4, excluded, excludedPaths)) return;
|
|
160
982
|
recentToolMutations.set(relative4, {
|
|
161
983
|
at: hint.at ?? Date.now(),
|
|
@@ -235,7 +1057,7 @@ async function startChronicleFileObserver(options) {
|
|
|
235
1057
|
for (const relative4 of candidates) {
|
|
236
1058
|
const before = known.get(relative4);
|
|
237
1059
|
const cached = fullScan?.files.get(relative4);
|
|
238
|
-
const after = cached ?? (fullScan?.complete ? void 0 : await fingerprint(
|
|
1060
|
+
const after = cached ?? (fullScan?.complete ? void 0 : await fingerprint(path5.join(root, relative4), maxHashBytes));
|
|
239
1061
|
if (sameFingerprint(before, after)) continue;
|
|
240
1062
|
changes.push({ relative: relative4, before, after });
|
|
241
1063
|
}
|
|
@@ -375,7 +1197,7 @@ async function recordMutation(options, eventType, relativePath, state, attribute
|
|
|
375
1197
|
const context = typeof options.context === "function" ? options.context() : options.context;
|
|
376
1198
|
const operation = attributes["operation"];
|
|
377
1199
|
options.events?.emit("file.activity", {
|
|
378
|
-
filePath:
|
|
1200
|
+
filePath: path5.join(options.projectRoot, relativePath),
|
|
379
1201
|
operation,
|
|
380
1202
|
phase: "changed",
|
|
381
1203
|
source: attribution ? "tool" : "external",
|
|
@@ -428,10 +1250,10 @@ async function scanProject(root, excluded, excludedPaths, maxHashBytes, onError,
|
|
|
428
1250
|
while (dirs.length > 0) {
|
|
429
1251
|
const relativeDir = dirs.pop();
|
|
430
1252
|
try {
|
|
431
|
-
const entries = await
|
|
1253
|
+
const entries = await fsp3.readdir(path5.join(root, relativeDir), { withFileTypes: true });
|
|
432
1254
|
const filePaths = [];
|
|
433
1255
|
for (const entry of entries) {
|
|
434
|
-
const relative4 = normalizeRelative(
|
|
1256
|
+
const relative4 = normalizeRelative(path5.join(relativeDir, entry.name));
|
|
435
1257
|
if (isExcluded(relative4, excluded, excludedPaths)) continue;
|
|
436
1258
|
if (entry.isDirectory()) {
|
|
437
1259
|
dirs.push(relative4);
|
|
@@ -445,7 +1267,7 @@ async function scanProject(root, excluded, excludedPaths, maxHashBytes, onError,
|
|
|
445
1267
|
async (relative4) => {
|
|
446
1268
|
try {
|
|
447
1269
|
const value = await fingerprint(
|
|
448
|
-
|
|
1270
|
+
path5.join(root, relative4),
|
|
449
1271
|
maxHashBytes,
|
|
450
1272
|
previous?.get(relative4)
|
|
451
1273
|
);
|
|
@@ -469,15 +1291,15 @@ async function scanProject(root, excluded, excludedPaths, maxHashBytes, onError,
|
|
|
469
1291
|
}
|
|
470
1292
|
async function fingerprint(filePath, maxHashBytes, previous) {
|
|
471
1293
|
try {
|
|
472
|
-
const
|
|
473
|
-
if (!
|
|
474
|
-
const base = { size:
|
|
475
|
-
if (previous?.hash !== void 0 && previous.size ===
|
|
1294
|
+
const stat5 = await fsp3.stat(filePath);
|
|
1295
|
+
if (!stat5.isFile()) return void 0;
|
|
1296
|
+
const base = { size: stat5.size, mtimeMs: stat5.mtimeMs };
|
|
1297
|
+
if (previous?.hash !== void 0 && previous.size === stat5.size && previous.mtimeMs === stat5.mtimeMs) {
|
|
476
1298
|
base.hash = previous.hash;
|
|
477
1299
|
return base;
|
|
478
1300
|
}
|
|
479
|
-
if (
|
|
480
|
-
base.hash = createHash("sha256").update(await
|
|
1301
|
+
if (stat5.size <= maxHashBytes) {
|
|
1302
|
+
base.hash = createHash("sha256").update(await fsp3.readFile(filePath)).digest("hex");
|
|
481
1303
|
}
|
|
482
1304
|
return base;
|
|
483
1305
|
} catch (error) {
|
|
@@ -502,7 +1324,7 @@ function isExcluded(relative4, excluded, excludedPaths) {
|
|
|
502
1324
|
function normalizeExcludedPaths(root, values) {
|
|
503
1325
|
const result = /* @__PURE__ */ new Set();
|
|
504
1326
|
for (const value of values) {
|
|
505
|
-
const relative4 =
|
|
1327
|
+
const relative4 = path5.isAbsolute(value) ? path5.relative(root, path5.resolve(value)) : value;
|
|
506
1328
|
const normalized = normalizeRelative(relative4).replace(/\/+$/u, "");
|
|
507
1329
|
if (!normalized || normalized === "." || normalized.startsWith("../")) continue;
|
|
508
1330
|
result.add(normalized);
|
|
@@ -521,15 +1343,15 @@ function unionKeys(a, b) {
|
|
|
521
1343
|
|
|
522
1344
|
// src/chronicle/identity.ts
|
|
523
1345
|
import { createHash as createHash2 } from "node:crypto";
|
|
524
|
-
import * as
|
|
525
|
-
import * as
|
|
1346
|
+
import * as os2 from "node:os";
|
|
1347
|
+
import * as path6 from "node:path";
|
|
526
1348
|
function resolveChronicleRuntimeLocation(input) {
|
|
527
1349
|
const day = (input.now ?? /* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
528
1350
|
return {
|
|
529
|
-
installationId: stableId("installation",
|
|
530
|
-
machineId: stableId("machine", `${
|
|
1351
|
+
installationId: stableId("installation", path6.resolve(input.globalRoot)),
|
|
1352
|
+
machineId: stableId("machine", `${os2.hostname()}\0${os2.platform()}\0${os2.arch()}`),
|
|
531
1353
|
projectId: input.projectId,
|
|
532
|
-
chronicleDirectory:
|
|
1354
|
+
chronicleDirectory: path6.join(input.projectDir, "chronicle"),
|
|
533
1355
|
day
|
|
534
1356
|
};
|
|
535
1357
|
}
|
|
@@ -540,130 +1362,12 @@ function stableId(prefix, value) {
|
|
|
540
1362
|
// src/chronicle/journal.ts
|
|
541
1363
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
542
1364
|
import { createReadStream } from "node:fs";
|
|
543
|
-
import * as
|
|
544
|
-
import * as
|
|
1365
|
+
import * as fs3 from "node:fs/promises";
|
|
1366
|
+
import * as path8 from "node:path";
|
|
545
1367
|
import { createInterface } from "node:readline";
|
|
546
1368
|
|
|
547
|
-
// src/
|
|
548
|
-
|
|
549
|
-
createPersistencePrimitives
|
|
550
|
-
} from "@wrongstack/persistence";
|
|
551
|
-
|
|
552
|
-
// src/types/errors.ts
|
|
553
|
-
var ERROR_CODES = {
|
|
554
|
-
// Provider
|
|
555
|
-
PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
|
|
556
|
-
PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
|
|
557
|
-
PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
|
|
558
|
-
PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
|
|
559
|
-
PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
|
|
560
|
-
PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
|
|
561
|
-
PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
|
|
562
|
-
// Tool
|
|
563
|
-
TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
|
|
564
|
-
TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
|
|
565
|
-
TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
|
|
566
|
-
TOOL_TIMEOUT: "TOOL_TIMEOUT",
|
|
567
|
-
TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
|
|
568
|
-
// Config
|
|
569
|
-
CONFIG_INVALID: "CONFIG_INVALID",
|
|
570
|
-
CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
|
|
571
|
-
CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
|
|
572
|
-
CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
|
|
573
|
-
// Plugin
|
|
574
|
-
PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
|
|
575
|
-
PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
|
|
576
|
-
PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
|
|
577
|
-
// Agent
|
|
578
|
-
AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
|
|
579
|
-
AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
|
|
580
|
-
AGENT_ABORTED: "AGENT_ABORTED",
|
|
581
|
-
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
582
|
-
// Session
|
|
583
|
-
SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
|
|
584
|
-
SESSION_CORRUPTED: "SESSION_CORRUPTED",
|
|
585
|
-
SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
|
|
586
|
-
// Container / Registry
|
|
587
|
-
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
588
|
-
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
589
|
-
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
590
|
-
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
591
|
-
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
592
|
-
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
593
|
-
// File system
|
|
594
|
-
FS_READ_FAILED: "FS_READ_FAILED",
|
|
595
|
-
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
596
|
-
FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
|
|
597
|
-
FS_DELETE_FAILED: "FS_DELETE_FAILED",
|
|
598
|
-
FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
|
|
599
|
-
// SDD (Spec-Driven Development)
|
|
600
|
-
SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
|
|
601
|
-
SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
|
|
602
|
-
SDD_INVALID_STATE: "SDD_INVALID_STATE",
|
|
603
|
-
SDD_NOT_READY: "SDD_NOT_READY",
|
|
604
|
-
// General
|
|
605
|
-
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
606
|
-
PARSE_FAILED: "PARSE_FAILED",
|
|
607
|
-
UNKNOWN: "UNKNOWN"
|
|
608
|
-
};
|
|
609
|
-
var WrongStackError = class extends Error {
|
|
610
|
-
code;
|
|
611
|
-
subsystem;
|
|
612
|
-
severity;
|
|
613
|
-
recoverable;
|
|
614
|
-
context;
|
|
615
|
-
constructor(opts) {
|
|
616
|
-
super(opts.message, { cause: opts.cause });
|
|
617
|
-
this.name = "WrongStackError";
|
|
618
|
-
this.code = opts.code;
|
|
619
|
-
this.subsystem = opts.subsystem;
|
|
620
|
-
this.severity = opts.severity ?? "error";
|
|
621
|
-
this.recoverable = opts.recoverable ?? false;
|
|
622
|
-
this.context = opts.context;
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Render a one-line user-facing description.
|
|
626
|
-
* Subclasses should override for domain-specific formatting.
|
|
627
|
-
*/
|
|
628
|
-
describe() {
|
|
629
|
-
const ctx = this.context ? ` ${formatContext(this.context)}` : "";
|
|
630
|
-
return `${this.code}: ${this.message}${ctx}`;
|
|
631
|
-
}
|
|
632
|
-
};
|
|
633
|
-
function formatContext(ctx) {
|
|
634
|
-
const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
|
|
635
|
-
return parts.length > 0 ? `[${parts.join(" ")}]` : "";
|
|
636
|
-
}
|
|
637
|
-
var FsError = class extends WrongStackError {
|
|
638
|
-
path;
|
|
639
|
-
constructor(opts) {
|
|
640
|
-
super({
|
|
641
|
-
message: opts.message,
|
|
642
|
-
code: opts.code,
|
|
643
|
-
subsystem: "fs",
|
|
644
|
-
severity: "error",
|
|
645
|
-
recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,
|
|
646
|
-
context: { path: opts.path, ...opts.context },
|
|
647
|
-
cause: opts.cause
|
|
648
|
-
});
|
|
649
|
-
this.name = "FsError";
|
|
650
|
-
this.path = opts.path;
|
|
651
|
-
}
|
|
652
|
-
};
|
|
653
|
-
|
|
654
|
-
// src/utils/atomic-write.ts
|
|
655
|
-
var primitives = createPersistencePrimitives({
|
|
656
|
-
createLockTimeoutError: ({ targetPath, timeoutMs }) => new FsError({
|
|
657
|
-
message: `Timed out waiting for file lock: ${targetPath}`,
|
|
658
|
-
code: "FS_ATOMIC_WRITE_FAILED",
|
|
659
|
-
path: targetPath,
|
|
660
|
-
context: { timeoutMs }
|
|
661
|
-
})
|
|
662
|
-
});
|
|
663
|
-
var atomicWrite = primitives.atomicWrite;
|
|
664
|
-
var atomicReplaceWithWriter = primitives.atomicReplaceWithWriter;
|
|
665
|
-
var ensureDir = primitives.ensureDir;
|
|
666
|
-
var withFileLock = primitives.withFileLock;
|
|
1369
|
+
// src/security/file-permissions.ts
|
|
1370
|
+
var SECRET_FILE_MODE = 384;
|
|
667
1371
|
|
|
668
1372
|
// src/chronicle/event-hash.ts
|
|
669
1373
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -685,14 +1389,14 @@ function chronicleEventHash(event) {
|
|
|
685
1389
|
}
|
|
686
1390
|
|
|
687
1391
|
// src/chronicle/partition-filename.ts
|
|
688
|
-
import * as
|
|
1392
|
+
import * as path7 from "node:path";
|
|
689
1393
|
var PARTITION_FILE_PATTERN = /^(.*\.events)(?:\.(\d{5}))?\.jsonl$/;
|
|
690
1394
|
function partitionFamily(filePath) {
|
|
691
|
-
const match = PARTITION_FILE_PATTERN.exec(
|
|
692
|
-
return
|
|
1395
|
+
const match = PARTITION_FILE_PATTERN.exec(path7.basename(filePath));
|
|
1396
|
+
return path7.join(path7.dirname(filePath), match?.[1] ?? path7.basename(filePath));
|
|
693
1397
|
}
|
|
694
1398
|
function partitionSequence(filePath) {
|
|
695
|
-
const match = PARTITION_FILE_PATTERN.exec(
|
|
1399
|
+
const match = PARTITION_FILE_PATTERN.exec(path7.basename(filePath));
|
|
696
1400
|
return Number(match?.[2] ?? 0);
|
|
697
1401
|
}
|
|
698
1402
|
function comparePartitionPaths(left, right) {
|
|
@@ -722,7 +1426,16 @@ var ChronicleJournal = class {
|
|
|
722
1426
|
drainPromise;
|
|
723
1427
|
drainScheduled = false;
|
|
724
1428
|
drainTimer;
|
|
725
|
-
counters = {
|
|
1429
|
+
counters = {
|
|
1430
|
+
acceptedEvents: 0,
|
|
1431
|
+
persistedEvents: 0,
|
|
1432
|
+
rejectedEvents: 0,
|
|
1433
|
+
failedEvents: 0,
|
|
1434
|
+
batches: 0,
|
|
1435
|
+
maxObservedPending: 0,
|
|
1436
|
+
largestBatch: 0,
|
|
1437
|
+
partitionRolls: 0
|
|
1438
|
+
};
|
|
726
1439
|
lastBatchDurationMs;
|
|
727
1440
|
partitionIndex = 0;
|
|
728
1441
|
partitionStartedAt;
|
|
@@ -732,7 +1445,7 @@ var ChronicleJournal = class {
|
|
|
732
1445
|
lastHash = GENESIS_HASH;
|
|
733
1446
|
lastAutoPurgeAt = 0;
|
|
734
1447
|
constructor(options) {
|
|
735
|
-
this.basePath =
|
|
1448
|
+
this.basePath = path8.resolve(options.filePath);
|
|
736
1449
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
737
1450
|
this.monotonicNow = options.monotonicNow ?? (() => process.hrtime.bigint());
|
|
738
1451
|
this.idFactory = options.idFactory ?? randomUUID2;
|
|
@@ -748,18 +1461,27 @@ var ChronicleJournal = class {
|
|
|
748
1461
|
return this.partitionIndex === 0 ? this.basePath : rotatedPath(this.basePath, this.partitionIndex);
|
|
749
1462
|
}
|
|
750
1463
|
stats() {
|
|
751
|
-
return {
|
|
1464
|
+
return {
|
|
1465
|
+
...this.counters,
|
|
1466
|
+
pendingEvents: this.pending.length,
|
|
1467
|
+
...this.lastBatchDurationMs !== void 0 ? { lastBatchDurationMs: this.lastBatchDurationMs } : {}
|
|
1468
|
+
};
|
|
752
1469
|
}
|
|
753
1470
|
append(input) {
|
|
754
1471
|
if (this.pending.length >= this.maxPending) {
|
|
755
1472
|
this.counters.rejectedEvents++;
|
|
756
|
-
return Promise.reject(
|
|
1473
|
+
return Promise.reject(
|
|
1474
|
+
new Error(`Chronicle backpressure limit reached (${this.maxPending} pending events)`)
|
|
1475
|
+
);
|
|
757
1476
|
}
|
|
758
|
-
const promise = new Promise((
|
|
759
|
-
this.pending.push({ input, resolve:
|
|
1477
|
+
const promise = new Promise((resolve12, reject) => {
|
|
1478
|
+
this.pending.push({ input, resolve: resolve12, reject });
|
|
760
1479
|
});
|
|
761
1480
|
this.counters.acceptedEvents++;
|
|
762
|
-
this.counters.maxObservedPending = Math.max(
|
|
1481
|
+
this.counters.maxObservedPending = Math.max(
|
|
1482
|
+
this.counters.maxObservedPending,
|
|
1483
|
+
this.pending.length
|
|
1484
|
+
);
|
|
763
1485
|
this.scheduleDrain();
|
|
764
1486
|
return promise;
|
|
765
1487
|
}
|
|
@@ -785,7 +1507,8 @@ var ChronicleJournal = class {
|
|
|
785
1507
|
await this.flush();
|
|
786
1508
|
const files = await collectPartitions(this.basePath);
|
|
787
1509
|
const checkpointResult = await readRetentionCheckpoint(this.basePath);
|
|
788
|
-
if (checkpointResult.error)
|
|
1510
|
+
if (checkpointResult.error)
|
|
1511
|
+
return { ok: false, entries: 0, brokenAt: 0, reason: checkpointResult.error };
|
|
789
1512
|
return verifyPartitionFiles(files, checkpointResult.checkpoint);
|
|
790
1513
|
}
|
|
791
1514
|
async purge(options) {
|
|
@@ -795,15 +1518,18 @@ var ChronicleJournal = class {
|
|
|
795
1518
|
}
|
|
796
1519
|
await this.refreshStateFromDisk();
|
|
797
1520
|
const cutoff = Date.now() - options.retentionDays * 864e5;
|
|
798
|
-
const activePath =
|
|
1521
|
+
const activePath = path8.resolve(this.path);
|
|
799
1522
|
const errors = [];
|
|
800
1523
|
let dc = 0, db = 0, sc = 0;
|
|
801
1524
|
const suppliedFiles = options.files === void 0 ? await collectJournalPartitions(this.basePath) : [...options.files];
|
|
802
1525
|
const eligible = /* @__PURE__ */ new Set();
|
|
803
1526
|
for (const suppliedPath of new Set(suppliedFiles)) {
|
|
804
|
-
const file =
|
|
805
|
-
if (!isJournalPartition(file,
|
|
806
|
-
errors.push({
|
|
1527
|
+
const file = path8.resolve(suppliedPath);
|
|
1528
|
+
if (!isJournalPartition(file, path8.dirname(this.basePath), this.basePath)) {
|
|
1529
|
+
errors.push({
|
|
1530
|
+
file: suppliedPath,
|
|
1531
|
+
reason: "not a Chronicle journal partition in this journal directory"
|
|
1532
|
+
});
|
|
807
1533
|
sc++;
|
|
808
1534
|
continue;
|
|
809
1535
|
}
|
|
@@ -813,7 +1539,7 @@ var ChronicleJournal = class {
|
|
|
813
1539
|
}
|
|
814
1540
|
let mtimeMs;
|
|
815
1541
|
try {
|
|
816
|
-
const fileStat = await
|
|
1542
|
+
const fileStat = await fs3.lstat(file);
|
|
817
1543
|
if (!fileStat.isFile()) {
|
|
818
1544
|
sc++;
|
|
819
1545
|
continue;
|
|
@@ -821,7 +1547,7 @@ var ChronicleJournal = class {
|
|
|
821
1547
|
mtimeMs = fileStat.mtimeMs;
|
|
822
1548
|
} catch (error) {
|
|
823
1549
|
if (isNotFound(error)) continue;
|
|
824
|
-
errors.push({ file, reason:
|
|
1550
|
+
errors.push({ file, reason: errorMessage2(error) });
|
|
825
1551
|
sc++;
|
|
826
1552
|
continue;
|
|
827
1553
|
}
|
|
@@ -847,18 +1573,22 @@ var ChronicleJournal = class {
|
|
|
847
1573
|
const familyBase = partitionFamilyBase(file);
|
|
848
1574
|
let deletedBytes;
|
|
849
1575
|
await withFileLock(familyBase, async () => {
|
|
850
|
-
const fileStat = await
|
|
1576
|
+
const fileStat = await fs3.lstat(file);
|
|
851
1577
|
if (!fileStat.isFile() || fileStat.mtimeMs > cutoff) return;
|
|
852
1578
|
const checkpointResult = await readRetentionCheckpoint(familyBase);
|
|
853
1579
|
if (checkpointResult.error) throw new Error(checkpointResult.error);
|
|
854
1580
|
const checkpoint = checkpointResult.checkpoint;
|
|
855
|
-
const nextCheckpoint = await verifyRetainedPrefix(
|
|
856
|
-
|
|
1581
|
+
const nextCheckpoint = await verifyRetainedPrefix(
|
|
1582
|
+
streamEntriesStrict(file),
|
|
1583
|
+
checkpoint
|
|
1584
|
+
);
|
|
1585
|
+
if (!nextCheckpoint)
|
|
1586
|
+
throw new Error("partition does not extend the trusted Chronicle chain");
|
|
857
1587
|
if (nextCheckpoint.sequence > (checkpoint?.sequence ?? 0)) {
|
|
858
1588
|
await writeRetentionCheckpoint(familyBase, nextCheckpoint);
|
|
859
1589
|
}
|
|
860
1590
|
deletedBytes = fileStat.size;
|
|
861
|
-
await
|
|
1591
|
+
await fs3.unlink(file);
|
|
862
1592
|
});
|
|
863
1593
|
if (deletedBytes === void 0) {
|
|
864
1594
|
sc++;
|
|
@@ -867,13 +1597,19 @@ var ChronicleJournal = class {
|
|
|
867
1597
|
db += deletedBytes;
|
|
868
1598
|
dc++;
|
|
869
1599
|
} catch (error) {
|
|
870
|
-
errors.push({ file, reason:
|
|
1600
|
+
errors.push({ file, reason: errorMessage2(error) });
|
|
871
1601
|
sc++;
|
|
872
1602
|
break;
|
|
873
1603
|
}
|
|
874
1604
|
}
|
|
875
1605
|
}
|
|
876
|
-
return {
|
|
1606
|
+
return {
|
|
1607
|
+
deletedCount: dc,
|
|
1608
|
+
deletedBytes: db,
|
|
1609
|
+
skippedCount: sc,
|
|
1610
|
+
errors,
|
|
1611
|
+
...options.dryRun ? { candidates } : {}
|
|
1612
|
+
};
|
|
877
1613
|
}
|
|
878
1614
|
async maybeAutoPurge() {
|
|
879
1615
|
if (this.retentionDays <= 0) return;
|
|
@@ -929,11 +1665,11 @@ var ChronicleJournal = class {
|
|
|
929
1665
|
if (!this.stateInitialized) return false;
|
|
930
1666
|
const nextPartition = rotatedPath(this.basePath, this.partitionIndex + 1);
|
|
931
1667
|
const [currentStat, nextExists] = await Promise.all([
|
|
932
|
-
|
|
1668
|
+
fs3.stat(this.path).catch((error) => {
|
|
933
1669
|
if (isNotFound(error)) return void 0;
|
|
934
1670
|
throw error;
|
|
935
1671
|
}),
|
|
936
|
-
|
|
1672
|
+
fs3.access(nextPartition).then(
|
|
937
1673
|
() => true,
|
|
938
1674
|
(error) => {
|
|
939
1675
|
if (isNotFound(error)) return false;
|
|
@@ -949,7 +1685,8 @@ var ChronicleJournal = class {
|
|
|
949
1685
|
this.rotate();
|
|
950
1686
|
return;
|
|
951
1687
|
}
|
|
952
|
-
if (Number.isFinite(this.maxPartitionSizeBytes) && this.partitionSizeBytes >= this.maxPartitionSizeBytes)
|
|
1688
|
+
if (Number.isFinite(this.maxPartitionSizeBytes) && this.partitionSizeBytes >= this.maxPartitionSizeBytes)
|
|
1689
|
+
this.rotate();
|
|
953
1690
|
}
|
|
954
1691
|
rotate() {
|
|
955
1692
|
this.partitionIndex++;
|
|
@@ -970,13 +1707,23 @@ var ChronicleJournal = class {
|
|
|
970
1707
|
let prev = this.lastSequence > 0 ? { sequence: this.lastSequence, hash: this.lastHash } : void 0;
|
|
971
1708
|
recorded = batch.map(({ input }) => {
|
|
972
1709
|
const instant = this.now().toISOString();
|
|
973
|
-
const uh = {
|
|
1710
|
+
const uh = {
|
|
1711
|
+
...input,
|
|
1712
|
+
occurredAt: input.occurredAt ?? instant,
|
|
1713
|
+
monotonicNs: input.monotonicNs ?? this.monotonicNow().toString(),
|
|
1714
|
+
schemaVersion: CHRONICLE_SCHEMA_VERSION,
|
|
1715
|
+
eventId: this.idFactory(),
|
|
1716
|
+
observedAt: instant,
|
|
1717
|
+
persistedAt: instant,
|
|
1718
|
+
sequence: (prev?.sequence ?? 0) + 1,
|
|
1719
|
+
previousHash: prev?.hash ?? GENESIS_HASH
|
|
1720
|
+
};
|
|
974
1721
|
const event = { ...uh, hash: hashValue(uh) };
|
|
975
1722
|
prev = event;
|
|
976
1723
|
return event;
|
|
977
1724
|
});
|
|
978
1725
|
const serialized = recorded.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
979
|
-
await
|
|
1726
|
+
await fs3.appendFile(cp, serialized, { encoding: "utf8", mode: SECRET_FILE_MODE });
|
|
980
1727
|
this.partitionSizeBytes += Buffer.byteLength(serialized);
|
|
981
1728
|
});
|
|
982
1729
|
const last = recorded[recorded.length - 1];
|
|
@@ -999,33 +1746,34 @@ var ChronicleJournal = class {
|
|
|
999
1746
|
}
|
|
1000
1747
|
};
|
|
1001
1748
|
function rotatedPath(basePath, index) {
|
|
1002
|
-
const dir =
|
|
1003
|
-
const ext =
|
|
1004
|
-
const base =
|
|
1005
|
-
return
|
|
1749
|
+
const dir = path8.dirname(basePath);
|
|
1750
|
+
const ext = path8.extname(basePath);
|
|
1751
|
+
const base = path8.basename(basePath, ext);
|
|
1752
|
+
return path8.join(dir, `${base}.${String(index).padStart(5, "0")}${ext}`);
|
|
1006
1753
|
}
|
|
1007
1754
|
async function collectPartitions(basePath) {
|
|
1008
|
-
const dir =
|
|
1009
|
-
const ext =
|
|
1010
|
-
const base =
|
|
1755
|
+
const dir = path8.dirname(basePath);
|
|
1756
|
+
const ext = path8.extname(basePath);
|
|
1757
|
+
const base = path8.basename(basePath, ext);
|
|
1011
1758
|
const pattern = new RegExp(`^${escapeRegex(base)}(?:\\.\\d{5})?${escapeRegex(ext)}$`);
|
|
1012
1759
|
const result = [];
|
|
1013
1760
|
try {
|
|
1014
|
-
const entries = await
|
|
1015
|
-
for (const entry of entries)
|
|
1761
|
+
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
1762
|
+
for (const entry of entries)
|
|
1763
|
+
if (entry.isFile() && pattern.test(entry.name)) result.push(path8.join(dir, entry.name));
|
|
1016
1764
|
} catch {
|
|
1017
1765
|
}
|
|
1018
|
-
const baseFile =
|
|
1766
|
+
const baseFile = path8.join(dir, base + ext);
|
|
1019
1767
|
const rotated = result.filter((file) => file !== baseFile).sort((left, right) => parseIndex(left, base, ext) - parseIndex(right, base, ext));
|
|
1020
1768
|
return [baseFile, ...rotated];
|
|
1021
1769
|
}
|
|
1022
1770
|
async function collectJournalPartitions(basePath) {
|
|
1023
|
-
const directory =
|
|
1771
|
+
const directory = path8.dirname(basePath);
|
|
1024
1772
|
const result = [];
|
|
1025
1773
|
try {
|
|
1026
|
-
const entries = await
|
|
1774
|
+
const entries = await fs3.readdir(directory, { withFileTypes: true });
|
|
1027
1775
|
for (const entry of entries) {
|
|
1028
|
-
const file =
|
|
1776
|
+
const file = path8.join(directory, entry.name);
|
|
1029
1777
|
if (entry.isFile() && isJournalPartition(file, directory, basePath)) result.push(file);
|
|
1030
1778
|
}
|
|
1031
1779
|
} catch {
|
|
@@ -1033,13 +1781,13 @@ async function collectJournalPartitions(basePath) {
|
|
|
1033
1781
|
return result.sort(comparePartitionPaths);
|
|
1034
1782
|
}
|
|
1035
1783
|
function isJournalPartition(filePath, directory, basePath) {
|
|
1036
|
-
if (
|
|
1037
|
-
const fileName =
|
|
1784
|
+
if (path8.dirname(path8.resolve(filePath)) !== path8.resolve(directory)) return false;
|
|
1785
|
+
const fileName = path8.basename(filePath);
|
|
1038
1786
|
if (!basePath) return false;
|
|
1039
|
-
const baseName =
|
|
1787
|
+
const baseName = path8.basename(basePath);
|
|
1040
1788
|
const dailyFamily = /^\d{4}-\d{2}-\d{2}\.events(?:\.\d{5})?\.jsonl$/;
|
|
1041
1789
|
if (/^\d{4}-\d{2}-\d{2}\.events\.jsonl$/.test(baseName)) return dailyFamily.test(fileName);
|
|
1042
|
-
return partitionFamilyBase(
|
|
1790
|
+
return partitionFamilyBase(path8.resolve(filePath)) === partitionFamilyBase(path8.resolve(basePath));
|
|
1043
1791
|
}
|
|
1044
1792
|
function groupPartitionsByFamily(files) {
|
|
1045
1793
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -1087,28 +1835,47 @@ async function verifyPartitionFiles(files, checkpoint) {
|
|
|
1087
1835
|
for await (const entry of streamEntriesStrict(file)) {
|
|
1088
1836
|
const { hash: recordedHash, ...content } = entry;
|
|
1089
1837
|
if (entry.sequence <= checkpointSequence) {
|
|
1090
|
-
if (hashValue(content) !== recordedHash)
|
|
1838
|
+
if (hashValue(content) !== recordedHash)
|
|
1839
|
+
return { ok: false, entries, brokenAt: entries, reason: "entry hash mismatch" };
|
|
1091
1840
|
if (coveredPrevious && entry.sequence !== coveredPrevious.sequence + 1) {
|
|
1092
|
-
return {
|
|
1841
|
+
return {
|
|
1842
|
+
ok: false,
|
|
1843
|
+
entries,
|
|
1844
|
+
brokenAt: entries,
|
|
1845
|
+
reason: `sequence ${entry.sequence} is not ${coveredPrevious.sequence + 1}`
|
|
1846
|
+
};
|
|
1093
1847
|
}
|
|
1094
1848
|
if (coveredPrevious && entry.previousHash !== coveredPrevious.hash) {
|
|
1095
1849
|
return { ok: false, entries, brokenAt: entries, reason: "previous hash mismatch" };
|
|
1096
1850
|
}
|
|
1097
1851
|
if (entry.sequence === checkpointSequence && recordedHash !== checkpoint?.hash) {
|
|
1098
|
-
return {
|
|
1852
|
+
return {
|
|
1853
|
+
ok: false,
|
|
1854
|
+
entries,
|
|
1855
|
+
brokenAt: entries,
|
|
1856
|
+
reason: "retention checkpoint hash mismatch"
|
|
1857
|
+
};
|
|
1099
1858
|
}
|
|
1100
1859
|
coveredPrevious = entry;
|
|
1101
1860
|
continue;
|
|
1102
1861
|
}
|
|
1103
1862
|
const index = entries++;
|
|
1104
|
-
if (entry.sequence !== lastSequence + 1)
|
|
1105
|
-
|
|
1106
|
-
|
|
1863
|
+
if (entry.sequence !== lastSequence + 1)
|
|
1864
|
+
return {
|
|
1865
|
+
ok: false,
|
|
1866
|
+
entries,
|
|
1867
|
+
brokenAt: index,
|
|
1868
|
+
reason: `sequence ${entry.sequence} is not ${lastSequence + 1}`
|
|
1869
|
+
};
|
|
1870
|
+
if (entry.previousHash !== previousHash)
|
|
1871
|
+
return { ok: false, entries, brokenAt: index, reason: "previous hash mismatch" };
|
|
1872
|
+
if (hashValue(content) !== recordedHash)
|
|
1873
|
+
return { ok: false, entries, brokenAt: index, reason: "entry hash mismatch" };
|
|
1107
1874
|
previousHash = recordedHash;
|
|
1108
1875
|
lastSequence = entry.sequence;
|
|
1109
1876
|
}
|
|
1110
1877
|
} catch (error) {
|
|
1111
|
-
return { ok: false, entries, brokenAt: entries, reason:
|
|
1878
|
+
return { ok: false, entries, brokenAt: entries, reason: errorMessage2(error) };
|
|
1112
1879
|
}
|
|
1113
1880
|
}
|
|
1114
1881
|
if (coveredPrevious && (coveredPrevious.sequence !== checkpointSequence || coveredPrevious.hash !== checkpoint?.hash)) {
|
|
@@ -1120,9 +1887,9 @@ async function readRetentionCheckpoint(basePath) {
|
|
|
1120
1887
|
const checkpointPath = retentionCheckpointPath(basePath);
|
|
1121
1888
|
let raw;
|
|
1122
1889
|
try {
|
|
1123
|
-
raw = await
|
|
1890
|
+
raw = await fs3.readFile(checkpointPath, "utf8");
|
|
1124
1891
|
} catch (error) {
|
|
1125
|
-
return isNotFound(error) ? {} : { error: `cannot read retention checkpoint: ${
|
|
1892
|
+
return isNotFound(error) ? {} : { error: `cannot read retention checkpoint: ${errorMessage2(error)}` };
|
|
1126
1893
|
}
|
|
1127
1894
|
try {
|
|
1128
1895
|
const parsed2 = JSON.parse(raw);
|
|
@@ -1136,18 +1903,20 @@ async function readRetentionCheckpoint(basePath) {
|
|
|
1136
1903
|
}
|
|
1137
1904
|
async function writeRetentionCheckpoint(basePath, checkpoint) {
|
|
1138
1905
|
await atomicWrite(retentionCheckpointPath(basePath), `${JSON.stringify(checkpoint)}
|
|
1139
|
-
`, {
|
|
1906
|
+
`, {
|
|
1907
|
+
mode: 384
|
|
1908
|
+
});
|
|
1140
1909
|
}
|
|
1141
1910
|
function isHash(value) {
|
|
1142
1911
|
return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
1143
1912
|
}
|
|
1144
1913
|
function parseIndex(filePath, base, ext) {
|
|
1145
|
-
const suffix =
|
|
1914
|
+
const suffix = path8.basename(filePath).slice(base.length + 1, -ext.length);
|
|
1146
1915
|
return suffix ? parseInt(suffix, 10) : 0;
|
|
1147
1916
|
}
|
|
1148
1917
|
function partitionIndex(filePath, basePath) {
|
|
1149
|
-
const ext =
|
|
1150
|
-
return parseIndex(filePath,
|
|
1918
|
+
const ext = path8.extname(basePath);
|
|
1919
|
+
return parseIndex(filePath, path8.basename(basePath, ext), ext);
|
|
1151
1920
|
}
|
|
1152
1921
|
function escapeRegex(text) {
|
|
1153
1922
|
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -1155,14 +1924,14 @@ function escapeRegex(text) {
|
|
|
1155
1924
|
async function readLastEntryState(filePath) {
|
|
1156
1925
|
let handle;
|
|
1157
1926
|
try {
|
|
1158
|
-
handle = await
|
|
1927
|
+
handle = await fs3.open(filePath, "r");
|
|
1159
1928
|
} catch (error) {
|
|
1160
1929
|
if (isNotFound(error)) return { size: 0 };
|
|
1161
1930
|
throw error;
|
|
1162
1931
|
}
|
|
1163
1932
|
try {
|
|
1164
|
-
const
|
|
1165
|
-
const size =
|
|
1933
|
+
const stat5 = await handle.stat();
|
|
1934
|
+
const size = stat5.size;
|
|
1166
1935
|
let position = size, suffix = "";
|
|
1167
1936
|
while (position > 0) {
|
|
1168
1937
|
const length = Math.min(65536, position);
|
|
@@ -1176,13 +1945,17 @@ async function readLastEntryState(filePath) {
|
|
|
1176
1945
|
const trimmed = lines[i].trim();
|
|
1177
1946
|
if (!trimmed) continue;
|
|
1178
1947
|
try {
|
|
1179
|
-
return {
|
|
1948
|
+
return {
|
|
1949
|
+
entry: JSON.parse(trimmed),
|
|
1950
|
+
size,
|
|
1951
|
+
birthtimeMs: stat5.birthtimeMs
|
|
1952
|
+
};
|
|
1180
1953
|
} catch {
|
|
1181
1954
|
}
|
|
1182
1955
|
}
|
|
1183
1956
|
suffix = lines[0] ?? "";
|
|
1184
1957
|
}
|
|
1185
|
-
return { size, birthtimeMs:
|
|
1958
|
+
return { size, birthtimeMs: stat5.birthtimeMs };
|
|
1186
1959
|
} finally {
|
|
1187
1960
|
await handle.close();
|
|
1188
1961
|
}
|
|
@@ -1200,7 +1973,7 @@ async function* streamEntriesStrict(filePath) {
|
|
|
1200
1973
|
try {
|
|
1201
1974
|
entry = JSON.parse(trimmed);
|
|
1202
1975
|
} catch {
|
|
1203
|
-
throw new Error(`invalid JSON at line ${lineNumber} in ${
|
|
1976
|
+
throw new Error(`invalid JSON at line ${lineNumber} in ${path8.basename(filePath)}`);
|
|
1204
1977
|
}
|
|
1205
1978
|
yield entry;
|
|
1206
1979
|
}
|
|
@@ -1217,13 +1990,13 @@ async function readEntriesStrict(filePath) {
|
|
|
1217
1990
|
function isNotFound(error) {
|
|
1218
1991
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
1219
1992
|
}
|
|
1220
|
-
function
|
|
1993
|
+
function errorMessage2(error) {
|
|
1221
1994
|
return error instanceof Error ? error.message : String(error);
|
|
1222
1995
|
}
|
|
1223
1996
|
|
|
1224
1997
|
// src/chronicle/legacy-journal-import.ts
|
|
1225
|
-
import * as
|
|
1226
|
-
import * as
|
|
1998
|
+
import * as fs4 from "node:fs/promises";
|
|
1999
|
+
import * as path9 from "node:path";
|
|
1227
2000
|
var ChronicleImportError = class extends Error {
|
|
1228
2001
|
constructor(message, day, sequence) {
|
|
1229
2002
|
super(message);
|
|
@@ -1237,7 +2010,7 @@ var ChronicleImportError = class extends Error {
|
|
|
1237
2010
|
async function discoverFamilies(directory) {
|
|
1238
2011
|
let entries;
|
|
1239
2012
|
try {
|
|
1240
|
-
entries = await
|
|
2013
|
+
entries = await fs4.readdir(directory);
|
|
1241
2014
|
} catch {
|
|
1242
2015
|
return [];
|
|
1243
2016
|
}
|
|
@@ -1266,7 +2039,7 @@ async function importLegacyChronicleJournal(journal, directory) {
|
|
|
1266
2039
|
let importedFamilies = 0;
|
|
1267
2040
|
for (const familyBase of families) {
|
|
1268
2041
|
const day = dayOfFamily(familyBase);
|
|
1269
|
-
const basePath =
|
|
2042
|
+
const basePath = path9.join(directory, `${familyBase}.jsonl`);
|
|
1270
2043
|
let familyEvents = 0;
|
|
1271
2044
|
if (journal.hasImportedDay(day)) continue;
|
|
1272
2045
|
try {
|
|
@@ -1329,9 +2102,9 @@ async function importLegacyChronicleJournal(journal, directory) {
|
|
|
1329
2102
|
}
|
|
1330
2103
|
|
|
1331
2104
|
// src/chronicle/metrics-store.ts
|
|
1332
|
-
import * as
|
|
2105
|
+
import * as fs7 from "node:fs/promises";
|
|
1333
2106
|
import { createRequire } from "node:module";
|
|
1334
|
-
import * as
|
|
2107
|
+
import * as path12 from "node:path";
|
|
1335
2108
|
|
|
1336
2109
|
// src/utils/sqlite-warning.ts
|
|
1337
2110
|
var SQLITE_EXPERIMENTAL_WARNING_RE = /sqlite is an experimental feature/i;
|
|
@@ -1359,13 +2132,13 @@ function withSqliteExperimentalWarningSuppressed(run) {
|
|
|
1359
2132
|
// src/chronicle/query.ts
|
|
1360
2133
|
import { createHash as createHash4 } from "node:crypto";
|
|
1361
2134
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
1362
|
-
import * as
|
|
1363
|
-
import * as
|
|
2135
|
+
import * as fs6 from "node:fs/promises";
|
|
2136
|
+
import * as path11 from "node:path";
|
|
1364
2137
|
import { createInterface as createInterface2 } from "node:readline";
|
|
1365
2138
|
|
|
1366
2139
|
// src/chronicle/partition-range-cache.ts
|
|
1367
|
-
import * as
|
|
1368
|
-
import * as
|
|
2140
|
+
import * as fs5 from "node:fs/promises";
|
|
2141
|
+
import * as path10 from "node:path";
|
|
1369
2142
|
var CACHE_VERSION = 1;
|
|
1370
2143
|
function isRange(value) {
|
|
1371
2144
|
if (!value || typeof value !== "object") return false;
|
|
@@ -1375,20 +2148,20 @@ function isRange(value) {
|
|
|
1375
2148
|
var ChroniclePartitionRangeCache = class {
|
|
1376
2149
|
constructor(directory) {
|
|
1377
2150
|
this.directory = directory;
|
|
1378
|
-
this.cachePath =
|
|
2151
|
+
this.cachePath = path10.join(directory, "range-cache.json");
|
|
1379
2152
|
}
|
|
1380
2153
|
directory;
|
|
1381
2154
|
cachePath;
|
|
1382
2155
|
entries;
|
|
1383
2156
|
dirty = false;
|
|
1384
2157
|
toKey(filePath) {
|
|
1385
|
-
return
|
|
2158
|
+
return path10.relative(this.directory, filePath).split(path10.sep).join("/");
|
|
1386
2159
|
}
|
|
1387
2160
|
async load() {
|
|
1388
2161
|
if (this.entries) return this.entries;
|
|
1389
2162
|
const entries = /* @__PURE__ */ new Map();
|
|
1390
2163
|
try {
|
|
1391
|
-
const raw = await
|
|
2164
|
+
const raw = await fs5.readFile(this.cachePath, "utf8");
|
|
1392
2165
|
const parsed2 = JSON.parse(raw);
|
|
1393
2166
|
if (parsed2.version === CACHE_VERSION && parsed2.entries && typeof parsed2.entries === "object") {
|
|
1394
2167
|
for (const [key, range] of Object.entries(parsed2.entries)) {
|
|
@@ -1483,7 +2256,7 @@ var ChronicleQueryEngine = class _ChronicleQueryEngine {
|
|
|
1483
2256
|
/** The one file (if any) that could still be actively appended to — never cache-checked or skipped. */
|
|
1484
2257
|
activeFile;
|
|
1485
2258
|
static async fromDirectory(directory, options) {
|
|
1486
|
-
const resolved =
|
|
2259
|
+
const resolved = path11.resolve(directory);
|
|
1487
2260
|
const files = await findPartitions(resolved);
|
|
1488
2261
|
const rangeCache2 = options?.rangeCache ?? new ChroniclePartitionRangeCache(resolved);
|
|
1489
2262
|
return new _ChronicleQueryEngine(
|
|
@@ -1701,7 +2474,7 @@ async function* reverseLines(filePath, maxBytes) {
|
|
|
1701
2474
|
const NEWLINE = 10;
|
|
1702
2475
|
let handle;
|
|
1703
2476
|
try {
|
|
1704
|
-
handle = await
|
|
2477
|
+
handle = await fs6.open(filePath, "r");
|
|
1705
2478
|
} catch {
|
|
1706
2479
|
return;
|
|
1707
2480
|
}
|
|
@@ -1875,12 +2648,12 @@ async function findPartitions(root) {
|
|
|
1875
2648
|
const visit = async (directory) => {
|
|
1876
2649
|
let entries;
|
|
1877
2650
|
try {
|
|
1878
|
-
entries = await
|
|
2651
|
+
entries = await fs6.readdir(directory, { withFileTypes: true });
|
|
1879
2652
|
} catch {
|
|
1880
2653
|
return;
|
|
1881
2654
|
}
|
|
1882
2655
|
for (const entry of entries) {
|
|
1883
|
-
const full =
|
|
2656
|
+
const full = path11.join(directory, entry.name);
|
|
1884
2657
|
if (entry.isDirectory()) await visit(full);
|
|
1885
2658
|
else if (entry.isFile() && PARTITION_FILE_PATTERN.test(entry.name)) result.push(full);
|
|
1886
2659
|
}
|
|
@@ -2045,7 +2818,7 @@ async function captureSnapshot(files) {
|
|
|
2045
2818
|
return Promise.all(files.map(async (file) => {
|
|
2046
2819
|
let size = 0;
|
|
2047
2820
|
try {
|
|
2048
|
-
size = (await
|
|
2821
|
+
size = (await fs6.stat(file)).size;
|
|
2049
2822
|
} catch {
|
|
2050
2823
|
}
|
|
2051
2824
|
return { file, id: fileId(file), size };
|
|
@@ -2058,7 +2831,7 @@ async function resolveSnapshotFiles(files, snapshot) {
|
|
|
2058
2831
|
if (!file) throw new Error("Chronicle cursor snapshot has expired");
|
|
2059
2832
|
let currentSize;
|
|
2060
2833
|
try {
|
|
2061
|
-
currentSize = (await
|
|
2834
|
+
currentSize = (await fs6.stat(file)).size;
|
|
2062
2835
|
} catch {
|
|
2063
2836
|
throw new Error("Chronicle cursor snapshot has expired");
|
|
2064
2837
|
}
|
|
@@ -2067,7 +2840,7 @@ async function resolveSnapshotFiles(files, snapshot) {
|
|
|
2067
2840
|
}));
|
|
2068
2841
|
}
|
|
2069
2842
|
function fileId(file) {
|
|
2070
|
-
return createHash4("sha256").update(
|
|
2843
|
+
return createHash4("sha256").update(path11.resolve(file), "utf8").digest("base64url");
|
|
2071
2844
|
}
|
|
2072
2845
|
function stableStringify2(value) {
|
|
2073
2846
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
@@ -2179,8 +2952,8 @@ var ChronicleMetricsStore = class _ChronicleMetricsStore {
|
|
|
2179
2952
|
directory;
|
|
2180
2953
|
dbPath;
|
|
2181
2954
|
constructor(directory) {
|
|
2182
|
-
this.directory =
|
|
2183
|
-
this.dbPath =
|
|
2955
|
+
this.directory = path12.resolve(directory);
|
|
2956
|
+
this.dbPath = path12.join(this.directory, "metrics.db");
|
|
2184
2957
|
const Database = loadDatabaseSync();
|
|
2185
2958
|
this.db = new Database(this.dbPath);
|
|
2186
2959
|
this.db.exec("PRAGMA journal_mode = WAL");
|
|
@@ -2205,7 +2978,7 @@ var ChronicleMetricsStore = class _ChronicleMetricsStore {
|
|
|
2205
2978
|
const files = await findChroniclePartitions(this.directory);
|
|
2206
2979
|
const offsets = this.loadOffsets();
|
|
2207
2980
|
for (const file of files) {
|
|
2208
|
-
const key = normalizeKey(
|
|
2981
|
+
const key = normalizeKey(path12.relative(this.directory, file));
|
|
2209
2982
|
const consumed = offsets.get(key) ?? 0;
|
|
2210
2983
|
const ingested = await this.ingestFile(file, key, consumed, result);
|
|
2211
2984
|
if (ingested) result.sourceFiles++;
|
|
@@ -2575,7 +3348,7 @@ var ChronicleMetricsStore = class _ChronicleMetricsStore {
|
|
|
2575
3348
|
}
|
|
2576
3349
|
pruneOffsets(existingFiles) {
|
|
2577
3350
|
const keep = new Set(
|
|
2578
|
-
existingFiles.map((file) => normalizeKey(
|
|
3351
|
+
existingFiles.map((file) => normalizeKey(path12.relative(this.directory, file)))
|
|
2579
3352
|
);
|
|
2580
3353
|
for (const row of this.db.prepare("SELECT file FROM ingest_state").all()) {
|
|
2581
3354
|
if (!keep.has(row.file))
|
|
@@ -2588,7 +3361,7 @@ var ChronicleMetricsStore = class _ChronicleMetricsStore {
|
|
|
2588
3361
|
async ingestFile(file, key, consumed, result) {
|
|
2589
3362
|
let handle;
|
|
2590
3363
|
try {
|
|
2591
|
-
handle = await
|
|
3364
|
+
handle = await fs7.open(file, "r");
|
|
2592
3365
|
} catch {
|
|
2593
3366
|
return false;
|
|
2594
3367
|
}
|
|
@@ -2872,9 +3645,9 @@ function normalizePathKey(value) {
|
|
|
2872
3645
|
|
|
2873
3646
|
// src/chronicle/project-server-endpoint.ts
|
|
2874
3647
|
import { createHash as createHash5 } from "node:crypto";
|
|
2875
|
-
import * as
|
|
2876
|
-
import * as
|
|
2877
|
-
import * as
|
|
3648
|
+
import * as fs8 from "node:fs";
|
|
3649
|
+
import * as os3 from "node:os";
|
|
3650
|
+
import * as path13 from "node:path";
|
|
2878
3651
|
|
|
2879
3652
|
// src/utils/socket-path.ts
|
|
2880
3653
|
import {
|
|
@@ -2894,37 +3667,37 @@ function encodeChronicleProjectServerMessage(message) {
|
|
|
2894
3667
|
// src/chronicle/project-server-endpoint.ts
|
|
2895
3668
|
var CHRONICLE_PROJECT_SERVER_METADATA_FILE = "server.json";
|
|
2896
3669
|
function normalizedPath(value) {
|
|
2897
|
-
const resolved =
|
|
3670
|
+
const resolved = path13.resolve(value);
|
|
2898
3671
|
return process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
2899
3672
|
}
|
|
2900
3673
|
function chronicleProjectServerKey(projectDir) {
|
|
2901
|
-
return createHash5("sha256").update(normalizedPath(
|
|
3674
|
+
return createHash5("sha256").update(normalizedPath(path13.join(projectDir, "chronicle"))).digest("hex").slice(0, 24);
|
|
2902
3675
|
}
|
|
2903
3676
|
function chronicleProjectServerEndpoint(projectDir) {
|
|
2904
3677
|
const key = chronicleProjectServerKey(projectDir);
|
|
2905
3678
|
if (process.platform === "win32") {
|
|
2906
3679
|
return `\\\\.\\pipe\\wrongstack-chronicle-v${CHRONICLE_PROJECT_SERVER_PROTOCOL_VERSION}-${key}`;
|
|
2907
3680
|
}
|
|
2908
|
-
return
|
|
2909
|
-
|
|
3681
|
+
return path13.join(
|
|
3682
|
+
os3.tmpdir(),
|
|
2910
3683
|
`wsch-v${CHRONICLE_PROJECT_SERVER_PROTOCOL_VERSION}`,
|
|
2911
3684
|
`${key}.sock`
|
|
2912
3685
|
);
|
|
2913
3686
|
}
|
|
2914
3687
|
function chronicleProjectServerMetadataPath(projectDir) {
|
|
2915
|
-
return
|
|
3688
|
+
return path13.join(projectDir, "chronicle", CHRONICLE_PROJECT_SERVER_METADATA_FILE);
|
|
2916
3689
|
}
|
|
2917
3690
|
function ensureChronicleProjectServerSocketDirectory(endpoint2) {
|
|
2918
3691
|
if (process.platform !== "win32") {
|
|
2919
3692
|
assertUnixSocketPathWithinLimit(endpoint2, "chronicle");
|
|
2920
|
-
|
|
3693
|
+
fs8.mkdirSync(path13.dirname(endpoint2), { recursive: true, mode: 448 });
|
|
2921
3694
|
}
|
|
2922
3695
|
}
|
|
2923
3696
|
|
|
2924
3697
|
// src/chronicle/sqlite-journal.ts
|
|
2925
3698
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
2926
3699
|
import { createRequire as createRequire2 } from "node:module";
|
|
2927
|
-
import * as
|
|
3700
|
+
import * as path14 from "node:path";
|
|
2928
3701
|
|
|
2929
3702
|
// src/chronicle/sqlite-query.ts
|
|
2930
3703
|
var MAX_LIMIT = 1e4;
|
|
@@ -3207,7 +3980,7 @@ var ChronicleSqliteJournal = class {
|
|
|
3207
3980
|
};
|
|
3208
3981
|
lastBatchDurationMs;
|
|
3209
3982
|
constructor(options) {
|
|
3210
|
-
this.dbPath =
|
|
3983
|
+
this.dbPath = path14.join(path14.resolve(options.directory), CHRONICLE_SQLITE_FILE);
|
|
3211
3984
|
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
3212
3985
|
this.monotonicNow = options.monotonicNow ?? (() => process.hrtime.bigint());
|
|
3213
3986
|
this.idFactory = options.idFactory ?? (() => randomUUID3());
|
|
@@ -3673,22 +4446,27 @@ function parseArgs(argv) {
|
|
|
3673
4446
|
}
|
|
3674
4447
|
const retentionInput = Number(values.get("--retention-days"));
|
|
3675
4448
|
return {
|
|
3676
|
-
projectRoot:
|
|
3677
|
-
globalRoot:
|
|
4449
|
+
projectRoot: path15.resolve(values.get("--project-root")),
|
|
4450
|
+
globalRoot: path15.resolve(values.get("--global-root")),
|
|
3678
4451
|
projectId: values.get("--project-id"),
|
|
3679
|
-
projectDir:
|
|
4452
|
+
projectDir: path15.resolve(values.get("--project-dir")),
|
|
3680
4453
|
workspaceId: values.get("--workspace-id"),
|
|
3681
4454
|
retentionDays: Number.isFinite(retentionInput) && retentionInput >= 0 ? retentionInput : 30
|
|
3682
4455
|
};
|
|
3683
4456
|
}
|
|
3684
4457
|
useDaemonPerfDefaults();
|
|
3685
4458
|
var parsed = parseArgs(process.argv.slice(2));
|
|
3686
|
-
var chronicleDirectory =
|
|
4459
|
+
var chronicleDirectory = path15.join(parsed.projectDir, "chronicle");
|
|
3687
4460
|
var endpoint = chronicleProjectServerEndpoint(parsed.projectDir);
|
|
3688
4461
|
var metadataPath = chronicleProjectServerMetadataPath(parsed.projectDir);
|
|
3689
4462
|
var idleInput = Number(process.env["WRONGSTACK_CHRONICLE_SERVER_IDLE_MS"]);
|
|
3690
4463
|
var idleMs = Number.isFinite(idleInput) && idleInput >= 100 ? idleInput : DEFAULT_IDLE_MS;
|
|
3691
4464
|
var startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4465
|
+
var authToken = randomBytes(16).toString("hex");
|
|
4466
|
+
var markMetadataWritten;
|
|
4467
|
+
var metadataWritten = new Promise((resolve12) => {
|
|
4468
|
+
markMetadataWritten = resolve12;
|
|
4469
|
+
});
|
|
3692
4470
|
var serverInfo = {
|
|
3693
4471
|
protocolVersion: CHRONICLE_PROJECT_SERVER_PROTOCOL_VERSION,
|
|
3694
4472
|
pid: process.pid,
|
|
@@ -3698,7 +4476,7 @@ var serverInfo = {
|
|
|
3698
4476
|
endpoint,
|
|
3699
4477
|
startedAt
|
|
3700
4478
|
};
|
|
3701
|
-
process.title = `wrongstack-chronicle:${
|
|
4479
|
+
process.title = `wrongstack-chronicle:${path15.basename(parsed.projectRoot)}`;
|
|
3702
4480
|
var clients = /* @__PURE__ */ new Set();
|
|
3703
4481
|
var journals = /* @__PURE__ */ new Map();
|
|
3704
4482
|
var activeRequests = 0;
|
|
@@ -3712,6 +4490,17 @@ var metricsStore;
|
|
|
3712
4490
|
var partitionRangeCache;
|
|
3713
4491
|
var metricsRefresh;
|
|
3714
4492
|
var pendingMutationHints = [];
|
|
4493
|
+
var stopMemoryWatchdog = startSharedHeapWatchdog({
|
|
4494
|
+
collectStats: () => ({
|
|
4495
|
+
surface: "chronicle-project-server",
|
|
4496
|
+
clients: clients.size,
|
|
4497
|
+
journals: journals.size,
|
|
4498
|
+
activeRequests,
|
|
4499
|
+
pendingMutationHints: pendingMutationHints.length,
|
|
4500
|
+
queryGeneration,
|
|
4501
|
+
cachedQuery: cachedQuery !== void 0
|
|
4502
|
+
})
|
|
4503
|
+
});
|
|
3715
4504
|
var MAX_OPEN_JOURNAL_DAYS = 2;
|
|
3716
4505
|
function pruneJournals(currentDay) {
|
|
3717
4506
|
if (journals.size <= MAX_OPEN_JOURNAL_DAYS) return;
|
|
@@ -3725,7 +4514,7 @@ function pruneJournals(currentDay) {
|
|
|
3725
4514
|
}
|
|
3726
4515
|
}
|
|
3727
4516
|
function legacyPartitionPath(location) {
|
|
3728
|
-
return
|
|
4517
|
+
return path15.join(location.chronicleDirectory, `${location.day}.events.jsonl`);
|
|
3729
4518
|
}
|
|
3730
4519
|
function useSqliteStore() {
|
|
3731
4520
|
return process.env["WRONGSTACK_CHRONICLE_STORE"] !== "jsonl";
|
|
@@ -3734,7 +4523,7 @@ var sqliteStore;
|
|
|
3734
4523
|
var quarantinedFamilies = [];
|
|
3735
4524
|
function store() {
|
|
3736
4525
|
sqliteStore ??= (async () => {
|
|
3737
|
-
await
|
|
4526
|
+
await fsp4.mkdir(chronicleDirectory, { recursive: true });
|
|
3738
4527
|
const journal = new ChronicleSqliteJournal({ directory: chronicleDirectory });
|
|
3739
4528
|
try {
|
|
3740
4529
|
const result = await importLegacyChronicleJournal(journal, chronicleDirectory);
|
|
@@ -3959,6 +4748,16 @@ function send(state, message) {
|
|
|
3959
4748
|
state.socket.write(encoded);
|
|
3960
4749
|
}
|
|
3961
4750
|
async function handleMessage(state, message) {
|
|
4751
|
+
if (message.authToken !== authToken) {
|
|
4752
|
+
send(state, {
|
|
4753
|
+
type: "response",
|
|
4754
|
+
id: message.id,
|
|
4755
|
+
ok: false,
|
|
4756
|
+
error: "Chronicle IPC request rejected: missing or invalid authToken. Reconnect to refresh metadata (server.json#authToken).",
|
|
4757
|
+
errorName: "UnauthorizedChronicleRequest"
|
|
4758
|
+
});
|
|
4759
|
+
return;
|
|
4760
|
+
}
|
|
3962
4761
|
if (message.type === "shutdown") {
|
|
3963
4762
|
send(state, { type: "response", id: message.id, ok: true, result: { stopped: true } });
|
|
3964
4763
|
await stop(message.reason ?? "client request");
|
|
@@ -4012,24 +4811,15 @@ function scheduleIdleStop() {
|
|
|
4012
4811
|
idleTimer.unref?.();
|
|
4013
4812
|
}
|
|
4014
4813
|
async function writeMetadata() {
|
|
4015
|
-
await
|
|
4016
|
-
const
|
|
4017
|
-
await
|
|
4018
|
-
`, {
|
|
4019
|
-
encoding: "utf8",
|
|
4020
|
-
mode: 384
|
|
4021
|
-
});
|
|
4022
|
-
try {
|
|
4023
|
-
await fsp2.rename(temporary, metadataPath);
|
|
4024
|
-
} catch {
|
|
4025
|
-
await fsp2.rm(metadataPath, { force: true });
|
|
4026
|
-
await fsp2.rename(temporary, metadataPath);
|
|
4027
|
-
}
|
|
4814
|
+
await fsp4.mkdir(path15.dirname(metadataPath), { recursive: true });
|
|
4815
|
+
const metadata = { ...serverInfo, authToken };
|
|
4816
|
+
await atomicWrite(metadataPath, `${JSON.stringify(metadata, null, 2)}
|
|
4817
|
+
`, { mode: 384 });
|
|
4028
4818
|
}
|
|
4029
4819
|
async function removeOwnedMetadata() {
|
|
4030
4820
|
try {
|
|
4031
|
-
const current = JSON.parse(await
|
|
4032
|
-
if (current.pid === process.pid) await
|
|
4821
|
+
const current = JSON.parse(await fsp4.readFile(metadataPath, "utf8"));
|
|
4822
|
+
if (current.pid === process.pid) await fsp4.rm(metadataPath, { force: true });
|
|
4033
4823
|
} catch {
|
|
4034
4824
|
}
|
|
4035
4825
|
}
|
|
@@ -4038,7 +4828,8 @@ async function stop(_reason) {
|
|
|
4038
4828
|
stopping = true;
|
|
4039
4829
|
if (idleTimer) clearTimeout(idleTimer);
|
|
4040
4830
|
idleTimer = void 0;
|
|
4041
|
-
await
|
|
4831
|
+
await removeOwnedMetadata();
|
|
4832
|
+
await new Promise((resolve12) => server.close(() => resolve12()));
|
|
4042
4833
|
for (const state of clients) state.socket.destroy();
|
|
4043
4834
|
clients.clear();
|
|
4044
4835
|
await watcher?.close().catch(() => {
|
|
@@ -4048,9 +4839,9 @@ async function stop(_reason) {
|
|
|
4048
4839
|
});
|
|
4049
4840
|
metricsStore?.close();
|
|
4050
4841
|
metricsStore = void 0;
|
|
4051
|
-
await
|
|
4052
|
-
if (process.platform !== "win32") await fsp2.rm(endpoint, { force: true }).catch(() => {
|
|
4842
|
+
if (process.platform !== "win32") await fsp4.rm(endpoint, { force: true }).catch(() => {
|
|
4053
4843
|
});
|
|
4844
|
+
await stopMemoryWatchdog();
|
|
4054
4845
|
}
|
|
4055
4846
|
ensureChronicleProjectServerSocketDirectory(endpoint);
|
|
4056
4847
|
var server = net.createServer((socket) => {
|
|
@@ -4063,7 +4854,9 @@ var server = net.createServer((socket) => {
|
|
|
4063
4854
|
socket.setEncoding("utf8");
|
|
4064
4855
|
const state = { socket, buffer: "" };
|
|
4065
4856
|
clients.add(state);
|
|
4066
|
-
|
|
4857
|
+
void metadataWritten.then(() => {
|
|
4858
|
+
if (!socket.destroyed) send(state, { type: "hello", ...serverInfo });
|
|
4859
|
+
});
|
|
4067
4860
|
socket.on("data", (chunk) => onData(state, chunk));
|
|
4068
4861
|
socket.on("close", () => {
|
|
4069
4862
|
clients.delete(state);
|
|
@@ -4089,7 +4882,7 @@ server.on("error", (error) => {
|
|
|
4089
4882
|
probe.once("error", () => {
|
|
4090
4883
|
probe.destroy();
|
|
4091
4884
|
try {
|
|
4092
|
-
|
|
4885
|
+
fs9.rmSync(endpoint, { force: true });
|
|
4093
4886
|
} catch {
|
|
4094
4887
|
}
|
|
4095
4888
|
probingExistingEndpoint = false;
|
|
@@ -4102,11 +4895,11 @@ server.on("error", (error) => {
|
|
|
4102
4895
|
server.on("listening", () => {
|
|
4103
4896
|
if (process.platform !== "win32") {
|
|
4104
4897
|
try {
|
|
4105
|
-
|
|
4898
|
+
fs9.chmodSync(endpoint, 384);
|
|
4106
4899
|
} catch {
|
|
4107
4900
|
}
|
|
4108
4901
|
}
|
|
4109
|
-
void writeMetadata();
|
|
4902
|
+
void writeMetadata().then(() => markMetadataWritten?.());
|
|
4110
4903
|
void startChronicleFileObserver({
|
|
4111
4904
|
projectRoot: parsed.projectRoot,
|
|
4112
4905
|
journal: watcherSink,
|