@lotagate/cli 0.1.22 → 0.1.24
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/package.json +7 -7
- package/scripts/install-native.mjs +11 -11
- package/dist/application/agent/agent-history.d.ts +0 -3
- package/dist/application/agent/agent-history.js +0 -81
- package/dist/application/agent/agent-input-context.d.ts +0 -9
- package/dist/application/agent/agent-input-context.js +0 -12
- package/dist/application/agent/agent-limit.d.ts +0 -3
- package/dist/application/agent/agent-limit.js +0 -12
- package/dist/application/agent/agent-run-tracker.d.ts +0 -30
- package/dist/application/agent/agent-run-tracker.js +0 -68
- package/dist/application/agent/agent-session-store.d.ts +0 -19
- package/dist/application/agent/agent-session-store.js +0 -74
- package/dist/application/agent/capability-profile.d.ts +0 -37
- package/dist/application/agent/capability-profile.js +0 -13
- package/dist/application/agent/cli-agent-execution-service.d.ts +0 -81
- package/dist/application/agent/cli-agent-execution-service.js +0 -279
- package/dist/application/agent/context-compaction-persistence.d.ts +0 -8
- package/dist/application/agent/context-compaction-persistence.js +0 -27
- package/dist/application/agent/context-compaction.d.ts +0 -20
- package/dist/application/agent/context-compaction.js +0 -114
- package/dist/application/agent/prompt-data-safety.d.ts +0 -14
- package/dist/application/agent/prompt-data-safety.js +0 -38
- package/dist/application/agent/safe-system-prompt.d.ts +0 -3
- package/dist/application/agent/safe-system-prompt.js +0 -19
- package/dist/application/agent/scoped-tool-executor.d.ts +0 -13
- package/dist/application/agent/scoped-tool-executor.js +0 -32
- package/dist/application/agent/system-prompt-builder.d.ts +0 -14
- package/dist/application/agent/system-prompt-builder.js +0 -199
- package/dist/application/agent/tool-catalog.d.ts +0 -14
- package/dist/application/agent/tool-catalog.js +0 -30
- package/dist/application/agent/tool-display.d.ts +0 -6
- package/dist/application/agent/tool-display.js +0 -59
- package/dist/application/agent/tool-hook-lifecycle.d.ts +0 -19
- package/dist/application/agent/tool-hook-lifecycle.js +0 -85
- package/dist/application/auth/authentication-service.d.ts +0 -20
- package/dist/application/auth/authentication-service.js +0 -44
- package/dist/application/chat/chat-service.d.ts +0 -12
- package/dist/application/chat/chat-service.js +0 -19
- package/dist/application/chat/pending-attachment-store.d.ts +0 -12
- package/dist/application/chat/pending-attachment-store.js +0 -28
- package/dist/application/commands/application-command-executor.d.ts +0 -20
- package/dist/application/commands/application-command-executor.js +0 -66
- package/dist/application/commands/cli-args.d.ts +0 -6
- package/dist/application/commands/cli-args.js +0 -43
- package/dist/application/commands/cli-command-services.d.ts +0 -16
- package/dist/application/commands/cli-command-services.js +0 -405
- package/dist/application/commands/command-catalog.d.ts +0 -6
- package/dist/application/commands/command-catalog.js +0 -159
- package/dist/application/commands/command-contract.d.ts +0 -58
- package/dist/application/commands/command-contract.js +0 -1
- package/dist/application/commands/command-hints.d.ts +0 -9
- package/dist/application/commands/command-hints.js +0 -17
- package/dist/application/commands/command-output.d.ts +0 -4
- package/dist/application/commands/command-output.js +0 -1
- package/dist/application/commands/command-parser.d.ts +0 -10
- package/dist/application/commands/command-parser.js +0 -155
- package/dist/application/commands/command-presentation.d.ts +0 -7
- package/dist/application/commands/command-presentation.js +0 -131
- package/dist/application/commands/command-registry.d.ts +0 -11
- package/dist/application/commands/command-registry.js +0 -64
- package/dist/application/commands/command-runtime.d.ts +0 -2
- package/dist/application/commands/command-runtime.js +0 -3
- package/dist/application/commands/goal-command-handlers.d.ts +0 -3
- package/dist/application/commands/goal-command-handlers.js +0 -120
- package/dist/application/commands/media-command-handlers.d.ts +0 -9
- package/dist/application/commands/media-command-handlers.js +0 -307
- package/dist/application/commands/media-command-output.d.ts +0 -11
- package/dist/application/commands/media-command-output.js +0 -8
- package/dist/application/commands/runtime-command-handlers.d.ts +0 -7
- package/dist/application/commands/runtime-command-handlers.js +0 -177
- package/dist/application/commands/stream-output.d.ts +0 -4
- package/dist/application/commands/stream-output.js +0 -10
- package/dist/application/commands/utility-commands.d.ts +0 -6
- package/dist/application/commands/utility-commands.js +0 -81
- package/dist/application/config/execution-config.d.ts +0 -4
- package/dist/application/config/execution-config.js +0 -6
- package/dist/application/extensions/extension-list-contract.d.ts +0 -13
- package/dist/application/extensions/extension-list-contract.js +0 -1
- package/dist/application/extensions/extension-list-formatters.d.ts +0 -31
- package/dist/application/extensions/extension-list-formatters.js +0 -98
- package/dist/application/extensions/extension-list-output.d.ts +0 -3
- package/dist/application/extensions/extension-list-output.js +0 -7
- package/dist/application/extensions/plugin-contribution-registry.d.ts +0 -15
- package/dist/application/extensions/plugin-contribution-registry.js +0 -80
- package/dist/application/extensions/skill-scope-store.d.ts +0 -23
- package/dist/application/extensions/skill-scope-store.js +0 -33
- package/dist/application/formatting/compact-number.d.ts +0 -2
- package/dist/application/formatting/compact-number.js +0 -18
- package/dist/application/formatting/compact-table.d.ts +0 -22
- package/dist/application/formatting/compact-table.js +0 -49
- package/dist/application/media/video-operation-poller.d.ts +0 -5
- package/dist/application/media/video-operation-poller.js +0 -42
- package/dist/application/model/cached-model-catalog.d.ts +0 -13
- package/dist/application/model/cached-model-catalog.js +0 -31
- package/dist/application/model/initial-model-selection.d.ts +0 -10
- package/dist/application/model/initial-model-selection.js +0 -11
- package/dist/application/model/model-catalog-service.d.ts +0 -6
- package/dist/application/model/model-catalog-service.js +0 -13
- package/dist/application/model/model-context-window.d.ts +0 -3
- package/dist/application/model/model-context-window.js +0 -23
- package/dist/application/orchestration/cli-subagent-service.d.ts +0 -70
- package/dist/application/orchestration/cli-subagent-service.js +0 -328
- package/dist/application/orchestration/cli-turn-event-projector.d.ts +0 -12
- package/dist/application/orchestration/cli-turn-event-projector.js +0 -81
- package/dist/application/orchestration/cli-turn-events.d.ts +0 -76
- package/dist/application/orchestration/cli-turn-events.js +0 -39
- package/dist/application/orchestration/cli-turn-persistence.d.ts +0 -6
- package/dist/application/orchestration/cli-turn-persistence.js +0 -14
- package/dist/application/orchestration/goal-evaluator.d.ts +0 -18
- package/dist/application/orchestration/goal-evaluator.js +0 -88
- package/dist/application/orchestration/goal-input.d.ts +0 -3
- package/dist/application/orchestration/goal-input.js +0 -19
- package/dist/application/orchestration/goal-output.d.ts +0 -2
- package/dist/application/orchestration/goal-output.js +0 -11
- package/dist/application/orchestration/goal-runner.d.ts +0 -22
- package/dist/application/orchestration/goal-runner.js +0 -153
- package/dist/application/orchestration/goal-usage.d.ts +0 -9
- package/dist/application/orchestration/goal-usage.js +0 -19
- package/dist/application/orchestration/headless-agent-turn.d.ts +0 -32
- package/dist/application/orchestration/headless-agent-turn.js +0 -82
- package/dist/application/orchestration/plan-generator.d.ts +0 -7
- package/dist/application/orchestration/plan-generator.js +0 -34
- package/dist/application/orchestration/subagent-coordinator.d.ts +0 -33
- package/dist/application/orchestration/subagent-coordinator.js +0 -28
- package/dist/application/orchestration/subagent-handoff.d.ts +0 -2
- package/dist/application/orchestration/subagent-handoff.js +0 -68
- package/dist/application/orchestration/subagent-tool-executor.d.ts +0 -12
- package/dist/application/orchestration/subagent-tool-executor.js +0 -93
- package/dist/application/orchestration/task-assessment.d.ts +0 -4
- package/dist/application/orchestration/task-assessment.js +0 -35
- package/dist/application/orchestration/task-graph.d.ts +0 -13
- package/dist/application/orchestration/task-graph.js +0 -56
- package/dist/application/orchestration/task-scheduler.d.ts +0 -18
- package/dist/application/orchestration/task-scheduler.js +0 -88
- package/dist/application/project/project-trust-service.d.ts +0 -13
- package/dist/application/project/project-trust-service.js +0 -74
- package/dist/application/protocol/browser-host-tool-executor.d.ts +0 -41
- package/dist/application/protocol/browser-host-tool-executor.js +0 -88
- package/dist/application/protocol/desktop-agent-command.d.ts +0 -9
- package/dist/application/protocol/desktop-agent-command.js +0 -663
- package/dist/application/protocol/desktop-attachment-store.d.ts +0 -16
- package/dist/application/protocol/desktop-attachment-store.js +0 -82
- package/dist/application/protocol/desktop-command-catalog.d.ts +0 -2
- package/dist/application/protocol/desktop-command-catalog.js +0 -19
- package/dist/application/protocol/desktop-command-contract.d.ts +0 -22
- package/dist/application/protocol/desktop-command-contract.js +0 -3
- package/dist/application/protocol/desktop-command-executor.d.ts +0 -16
- package/dist/application/protocol/desktop-command-executor.js +0 -47
- package/dist/application/protocol/desktop-command-output.d.ts +0 -15
- package/dist/application/protocol/desktop-command-output.js +0 -24
- package/dist/application/protocol/desktop-execution-policy.d.ts +0 -17
- package/dist/application/protocol/desktop-execution-policy.js +0 -49
- package/dist/application/protocol/desktop-host-tool-executor.d.ts +0 -57
- package/dist/application/protocol/desktop-host-tool-executor.js +0 -53
- package/dist/application/protocol/desktop-orchestration-events.d.ts +0 -5
- package/dist/application/protocol/desktop-orchestration-events.js +0 -37
- package/dist/application/protocol/json-line-writer.d.ts +0 -9
- package/dist/application/protocol/json-line-writer.js +0 -19
- package/dist/application/protocol/jsonl-agent-command.d.ts +0 -3
- package/dist/application/protocol/jsonl-agent-command.js +0 -97
- package/dist/application/protocol/jsonl-protocol.d.ts +0 -52
- package/dist/application/protocol/jsonl-protocol.js +0 -170
- package/dist/application/security/desktop-tool-scope-policy.d.ts +0 -3
- package/dist/application/security/desktop-tool-scope-policy.js +0 -52
- package/dist/application/security/tool-action-risk-analyzer.d.ts +0 -13
- package/dist/application/security/tool-action-risk-analyzer.js +0 -64
- package/dist/application/security/tool-approval-service.d.ts +0 -35
- package/dist/application/security/tool-approval-service.js +0 -97
- package/dist/application/security/tool-risk-classifier.d.ts +0 -11
- package/dist/application/security/tool-risk-classifier.js +0 -65
- package/dist/application/security/workspace-permission-policy.d.ts +0 -10
- package/dist/application/security/workspace-permission-policy.js +0 -50
- package/dist/application/session/project-session-access.d.ts +0 -8
- package/dist/application/session/project-session-access.js +0 -19
- package/dist/application/session/session-compaction-service.d.ts +0 -10
- package/dist/application/session/session-compaction-service.js +0 -43
- package/dist/application/session/session-turn-lifecycle.d.ts +0 -5
- package/dist/application/session/session-turn-lifecycle.js +0 -31
- package/dist/application/workspace/workspace-file-index.d.ts +0 -15
- package/dist/application/workspace/workspace-file-index.js +0 -60
- package/dist/application/workspace/workspace-file-reference-resolver.d.ts +0 -14
- package/dist/application/workspace/workspace-file-reference-resolver.js +0 -123
- package/dist/application/workspace/workspace-instruction-loader.d.ts +0 -8
- package/dist/application/workspace/workspace-instruction-loader.js +0 -55
- package/dist/bootstrap/composition-root.d.ts +0 -6
- package/dist/bootstrap/composition-root.js +0 -4
- package/dist/bootstrap/global-cli-options.d.ts +0 -6
- package/dist/bootstrap/global-cli-options.js +0 -29
- package/dist/bootstrap/native-devtools-stub.d.ts +0 -10
- package/dist/bootstrap/native-devtools-stub.js +0 -10
- package/dist/bootstrap/native-entry.d.ts +0 -1
- package/dist/bootstrap/native-entry.js +0 -6
- package/dist/bootstrap/native-tiktoken.d.ts +0 -4
- package/dist/bootstrap/native-tiktoken.js +0 -5
- package/dist/bootstrap/runtime-factory.d.ts +0 -35
- package/dist/bootstrap/runtime-factory.js +0 -44
- package/dist/bootstrap/shutdown-manager.d.ts +0 -10
- package/dist/bootstrap/shutdown-manager.js +0 -14
- package/dist/bootstrap/startup-sequence.d.ts +0 -5
- package/dist/bootstrap/startup-sequence.js +0 -10
- package/dist/domain/auth/auth-profile.d.ts +0 -14
- package/dist/domain/auth/auth-profile.js +0 -39
- package/dist/domain/config/config-schema.d.ts +0 -17
- package/dist/domain/config/config-schema.js +0 -105
- package/dist/domain/errors/cli-command-hint.d.ts +0 -5
- package/dist/domain/errors/cli-command-hint.js +0 -1
- package/dist/domain/errors/cli-error.d.ts +0 -35
- package/dist/domain/errors/cli-error.js +0 -129
- package/dist/domain/errors/error-codes.d.ts +0 -46
- package/dist/domain/errors/error-codes.js +0 -45
- package/dist/domain/extensions/extension-scope.d.ts +0 -3
- package/dist/domain/extensions/extension-scope.js +0 -23
- package/dist/domain/extensions/extension-state.d.ts +0 -5
- package/dist/domain/extensions/extension-state.js +0 -11
- package/dist/domain/extensions/hook-manifest.d.ts +0 -10
- package/dist/domain/extensions/hook-manifest.js +0 -23
- package/dist/domain/extensions/mcp-config.d.ts +0 -18
- package/dist/domain/extensions/mcp-config.js +0 -111
- package/dist/domain/extensions/plugin-manifest.d.ts +0 -11
- package/dist/domain/extensions/plugin-manifest.js +0 -43
- package/dist/domain/extensions/skill-manifest.d.ts +0 -10
- package/dist/domain/extensions/skill-manifest.js +0 -51
- package/dist/domain/filesystem/file-change-diff.d.ts +0 -21
- package/dist/domain/filesystem/file-change-diff.js +0 -60
- package/dist/domain/media/gateway-media-contract.d.ts +0 -23
- package/dist/domain/media/gateway-media-contract.js +0 -163
- package/dist/domain/media/media-contract.d.ts +0 -28
- package/dist/domain/media/media-contract.js +0 -1
- package/dist/domain/media/media-execution-policy.d.ts +0 -9
- package/dist/domain/media/media-execution-policy.js +0 -31
- package/dist/domain/orchestration/goal.d.ts +0 -58
- package/dist/domain/orchestration/goal.js +0 -113
- package/dist/domain/orchestration/subagent-identity.d.ts +0 -2
- package/dist/domain/orchestration/subagent-identity.js +0 -8
- package/dist/domain/orchestration/subagent.d.ts +0 -33
- package/dist/domain/orchestration/subagent.js +0 -1
- package/dist/domain/orchestration/task.d.ts +0 -31
- package/dist/domain/orchestration/task.js +0 -1
- package/dist/domain/project/project-identity.d.ts +0 -6
- package/dist/domain/project/project-identity.js +0 -4
- package/dist/domain/runtime/assistant-delta-normalizer.d.ts +0 -11
- package/dist/domain/runtime/assistant-delta-normalizer.js +0 -19
- package/dist/domain/runtime/resource-limits.d.ts +0 -60
- package/dist/domain/runtime/resource-limits.js +0 -60
- package/dist/domain/session/attachment.d.ts +0 -13
- package/dist/domain/session/attachment.js +0 -1
- package/dist/domain/session/session-schema.d.ts +0 -6
- package/dist/domain/session/session-schema.js +0 -28
- package/dist/domain/session/session.d.ts +0 -27
- package/dist/domain/session/session.js +0 -1
- package/dist/domain/settings/settings-document.d.ts +0 -8
- package/dist/domain/settings/settings-document.js +0 -36
- package/dist/domain/validation/record-schema.d.ts +0 -4
- package/dist/domain/validation/record-schema.js +0 -9
- package/dist/domain/workspace/workspace-settings.d.ts +0 -12
- package/dist/domain/workspace/workspace-settings.js +0 -44
- package/dist/infrastructure/agent-sdk/agent-instance-factory.d.ts +0 -22
- package/dist/infrastructure/agent-sdk/agent-instance-factory.js +0 -31
- package/dist/infrastructure/agent-sdk/tool-calling-model-client.d.ts +0 -11
- package/dist/infrastructure/agent-sdk/tool-calling-model-client.js +0 -447
- package/dist/infrastructure/cache/cache-policy.d.ts +0 -7
- package/dist/infrastructure/cache/cache-policy.js +0 -18
- package/dist/infrastructure/cache/file-cache-store.d.ts +0 -17
- package/dist/infrastructure/cache/file-cache-store.js +0 -121
- package/dist/infrastructure/clipboard/clipboard-adapter-factory.d.ts +0 -11
- package/dist/infrastructure/clipboard/clipboard-adapter-factory.js +0 -98
- package/dist/infrastructure/clipboard/clipboard-policy.d.ts +0 -8
- package/dist/infrastructure/clipboard/clipboard-policy.js +0 -19
- package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.d.ts +0 -10
- package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.js +0 -94
- package/dist/infrastructure/clipboard/image-normalizer.d.ts +0 -12
- package/dist/infrastructure/clipboard/image-normalizer.js +0 -78
- package/dist/infrastructure/clipboard/windows-clipboard-adapter.d.ts +0 -7
- package/dist/infrastructure/clipboard/windows-clipboard-adapter.js +0 -66
- package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.d.ts +0 -7
- package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.js +0 -70
- package/dist/infrastructure/config/config-loader.d.ts +0 -19
- package/dist/infrastructure/config/config-loader.js +0 -76
- package/dist/infrastructure/config/environment-values.d.ts +0 -2
- package/dist/infrastructure/config/environment-values.js +0 -7
- package/dist/infrastructure/credentials/composite-credential-store.d.ts +0 -11
- package/dist/infrastructure/credentials/composite-credential-store.js +0 -32
- package/dist/infrastructure/credentials/encrypted-file-credential-store.d.ts +0 -17
- package/dist/infrastructure/credentials/encrypted-file-credential-store.js +0 -181
- package/dist/infrastructure/credentials/environment-credential-store.d.ts +0 -11
- package/dist/infrastructure/credentials/environment-credential-store.js +0 -37
- package/dist/infrastructure/credentials/secret-input.d.ts +0 -7
- package/dist/infrastructure/credentials/secret-input.js +0 -44
- package/dist/infrastructure/extensions/composite-mcp-config-store.d.ts +0 -9
- package/dist/infrastructure/extensions/composite-mcp-config-store.js +0 -10
- package/dist/infrastructure/extensions/extension-directory-reader.d.ts +0 -2
- package/dist/infrastructure/extensions/extension-directory-reader.js +0 -15
- package/dist/infrastructure/extensions/extension-source-resolver.d.ts +0 -6
- package/dist/infrastructure/extensions/extension-source-resolver.js +0 -126
- package/dist/infrastructure/extensions/file-mcp-config-store.d.ts +0 -15
- package/dist/infrastructure/extensions/file-mcp-config-store.js +0 -66
- package/dist/infrastructure/extensions/hook-runtime.d.ts +0 -18
- package/dist/infrastructure/extensions/hook-runtime.js +0 -66
- package/dist/infrastructure/extensions/mcp-runtime.d.ts +0 -12
- package/dist/infrastructure/extensions/mcp-runtime.js +0 -52
- package/dist/infrastructure/extensions/plugin-discovery.d.ts +0 -5
- package/dist/infrastructure/extensions/plugin-discovery.js +0 -52
- package/dist/infrastructure/extensions/plugin-manager.d.ts +0 -26
- package/dist/infrastructure/extensions/plugin-manager.js +0 -139
- package/dist/infrastructure/extensions/skill-discovery.d.ts +0 -4
- package/dist/infrastructure/extensions/skill-discovery.js +0 -29
- package/dist/infrastructure/extensions/skill-installer.d.ts +0 -8
- package/dist/infrastructure/extensions/skill-installer.js +0 -88
- package/dist/infrastructure/extensions/skill-manager.d.ts +0 -22
- package/dist/infrastructure/extensions/skill-manager.js +0 -67
- package/dist/infrastructure/extensions/skill-roots.d.ts +0 -19
- package/dist/infrastructure/extensions/skill-roots.js +0 -25
- package/dist/infrastructure/extensions/skill-tool-executor.d.ts +0 -18
- package/dist/infrastructure/extensions/skill-tool-executor.js +0 -53
- package/dist/infrastructure/filesystem/atomic-file-store.d.ts +0 -12
- package/dist/infrastructure/filesystem/atomic-file-store.js +0 -106
- package/dist/infrastructure/filesystem/bounded-file-reader.d.ts +0 -6
- package/dist/infrastructure/filesystem/bounded-file-reader.js +0 -24
- package/dist/infrastructure/filesystem/bounded-json-reader.d.ts +0 -1
- package/dist/infrastructure/filesystem/bounded-json-reader.js +0 -7
- package/dist/infrastructure/filesystem/fs-errors.d.ts +0 -2
- package/dist/infrastructure/filesystem/fs-errors.js +0 -6
- package/dist/infrastructure/filesystem/gateway-media-input-reader.d.ts +0 -12
- package/dist/infrastructure/filesystem/gateway-media-input-reader.js +0 -49
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.d.ts +0 -21
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.js +0 -176
- package/dist/infrastructure/filesystem/path-resolver.d.ts +0 -20
- package/dist/infrastructure/filesystem/path-resolver.js +0 -119
- package/dist/infrastructure/filesystem/workspace-media-artifact-store.d.ts +0 -13
- package/dist/infrastructure/filesystem/workspace-media-artifact-store.js +0 -152
- package/dist/infrastructure/logging/daily-rotating-file-writer.d.ts +0 -20
- package/dist/infrastructure/logging/daily-rotating-file-writer.js +0 -75
- package/dist/infrastructure/logging/log-redactor.d.ts +0 -2
- package/dist/infrastructure/logging/log-redactor.js +0 -26
- package/dist/infrastructure/logging/logging-policy.d.ts +0 -6
- package/dist/infrastructure/logging/logging-policy.js +0 -6
- package/dist/infrastructure/logging/structured-logger.d.ts +0 -24
- package/dist/infrastructure/logging/structured-logger.js +0 -40
- package/dist/infrastructure/network/safe-media-downloader.d.ts +0 -23
- package/dist/infrastructure/network/safe-media-downloader.js +0 -239
- package/dist/infrastructure/platform/host-platform.d.ts +0 -14
- package/dist/infrastructure/platform/host-platform.js +0 -23
- package/dist/infrastructure/platform/host-process.d.ts +0 -17
- package/dist/infrastructure/platform/host-process.js +0 -116
- package/dist/infrastructure/platform/platform-paths.d.ts +0 -25
- package/dist/infrastructure/platform/platform-paths.js +0 -33
- package/dist/infrastructure/project/file-project-trust-store.d.ts +0 -12
- package/dist/infrastructure/project/file-project-trust-store.js +0 -59
- package/dist/infrastructure/sdk/chat-completion-adapter.d.ts +0 -8
- package/dist/infrastructure/sdk/chat-completion-adapter.js +0 -115
- package/dist/infrastructure/sdk/lotagate-client-factory.d.ts +0 -3
- package/dist/infrastructure/sdk/lotagate-client-factory.js +0 -8
- package/dist/infrastructure/sdk/model-catalog-adapter.d.ts +0 -19
- package/dist/infrastructure/sdk/model-catalog-adapter.js +0 -28
- package/dist/infrastructure/sdk/sdk-media-gateway-client.d.ts +0 -20
- package/dist/infrastructure/sdk/sdk-media-gateway-client.js +0 -97
- package/dist/infrastructure/sessions/file-goal-store.d.ts +0 -21
- package/dist/infrastructure/sessions/file-goal-store.js +0 -160
- package/dist/infrastructure/sessions/file-session-store.d.ts +0 -48
- package/dist/infrastructure/sessions/file-session-store.js +0 -525
- package/dist/infrastructure/sessions/project-session-paths.d.ts +0 -17
- package/dist/infrastructure/sessions/project-session-paths.js +0 -41
- package/dist/infrastructure/sessions/session-index.d.ts +0 -16
- package/dist/infrastructure/sessions/session-index.js +0 -84
- package/dist/infrastructure/sessions/session-journal.d.ts +0 -22
- package/dist/infrastructure/sessions/session-journal.js +0 -137
- package/dist/infrastructure/sessions/subagent-journal-store.d.ts +0 -28
- package/dist/infrastructure/sessions/subagent-journal-store.js +0 -30
- package/dist/infrastructure/shell/shell-tool-executor.d.ts +0 -17
- package/dist/infrastructure/shell/shell-tool-executor.js +0 -115
- package/dist/infrastructure/tokens/tiktoken-token-estimator.d.ts +0 -18
- package/dist/infrastructure/tokens/tiktoken-token-estimator.js +0 -48
- package/dist/infrastructure/workspace/workspace-settings-store.d.ts +0 -9
- package/dist/infrastructure/workspace/workspace-settings-store.js +0 -75
- package/dist/main.d.ts +0 -7
- package/dist/main.js +0 -66
- package/dist/ports/cache-store.d.ts +0 -10
- package/dist/ports/cache-store.js +0 -1
- package/dist/ports/chat-model.d.ts +0 -30
- package/dist/ports/chat-model.js +0 -1
- package/dist/ports/clipboard-adapter.d.ts +0 -7
- package/dist/ports/clipboard-adapter.js +0 -1
- package/dist/ports/clipboard-text-adapter.d.ts +0 -3
- package/dist/ports/clipboard-text-adapter.js +0 -1
- package/dist/ports/credential-store.d.ts +0 -7
- package/dist/ports/credential-store.js +0 -1
- package/dist/ports/goal-store.d.ts +0 -12
- package/dist/ports/goal-store.js +0 -1
- package/dist/ports/logger.d.ts +0 -8
- package/dist/ports/logger.js +0 -1
- package/dist/ports/media-gateway-client.d.ts +0 -54
- package/dist/ports/media-gateway-client.js +0 -1
- package/dist/ports/model-diagnostics.d.ts +0 -17
- package/dist/ports/model-diagnostics.js +0 -1
- package/dist/ports/project-trust-store.d.ts +0 -12
- package/dist/ports/project-trust-store.js +0 -1
- package/dist/ports/session-store.d.ts +0 -58
- package/dist/ports/session-store.js +0 -1
- package/dist/ports/subagent-lifecycle.d.ts +0 -31
- package/dist/ports/subagent-lifecycle.js +0 -1
- package/dist/ports/tool-activity.d.ts +0 -13
- package/dist/ports/tool-activity.js +0 -1
- package/dist/presentation/themes/theme.d.ts +0 -19
- package/dist/presentation/themes/theme.js +0 -8
- package/dist/presentation/tui/agent-initialization-renderer.d.ts +0 -4
- package/dist/presentation/tui/agent-initialization-renderer.js +0 -37
- package/dist/presentation/tui/context-display.d.ts +0 -21
- package/dist/presentation/tui/context-display.js +0 -33
- package/dist/presentation/tui/formatters.d.ts +0 -6
- package/dist/presentation/tui/formatters.js +0 -60
- package/dist/presentation/tui/ink/choice-window.d.ts +0 -5
- package/dist/presentation/tui/ink/choice-window.js +0 -5
- package/dist/presentation/tui/ink/components/activity-entry.d.ts +0 -6
- package/dist/presentation/tui/ink/components/activity-entry.js +0 -16
- package/dist/presentation/tui/ink/components/activity-status.d.ts +0 -10
- package/dist/presentation/tui/ink/components/activity-status.js +0 -21
- package/dist/presentation/tui/ink/components/choice-modal.d.ts +0 -11
- package/dist/presentation/tui/ink/components/choice-modal.js +0 -29
- package/dist/presentation/tui/ink/components/composer.d.ts +0 -40
- package/dist/presentation/tui/ink/components/composer.js +0 -271
- package/dist/presentation/tui/ink/components/file-diff.d.ts +0 -6
- package/dist/presentation/tui/ink/components/file-diff.js +0 -34
- package/dist/presentation/tui/ink/components/modal.d.ts +0 -8
- package/dist/presentation/tui/ink/components/modal.js +0 -110
- package/dist/presentation/tui/ink/components/shimmer-text.d.ts +0 -6
- package/dist/presentation/tui/ink/components/shimmer-text.js +0 -9
- package/dist/presentation/tui/ink/components/subagent-activity.d.ts +0 -11
- package/dist/presentation/tui/ink/components/subagent-activity.js +0 -61
- package/dist/presentation/tui/ink/components/transcript.d.ts +0 -39
- package/dist/presentation/tui/ink/components/transcript.js +0 -121
- package/dist/presentation/tui/ink/components/welcome-panel.d.ts +0 -6
- package/dist/presentation/tui/ink/components/welcome-panel.js +0 -20
- package/dist/presentation/tui/ink/lotagate-tui.d.ts +0 -6
- package/dist/presentation/tui/ink/lotagate-tui.js +0 -136
- package/dist/presentation/tui/ink/markdown-inline-renderer.d.ts +0 -4
- package/dist/presentation/tui/ink/markdown-inline-renderer.js +0 -20
- package/dist/presentation/tui/ink/markdown-inline.d.ts +0 -13
- package/dist/presentation/tui/ink/markdown-inline.js +0 -91
- package/dist/presentation/tui/ink/markdown-message.d.ts +0 -6
- package/dist/presentation/tui/ink/markdown-message.js +0 -66
- package/dist/presentation/tui/ink/markdown-table.d.ts +0 -16
- package/dist/presentation/tui/ink/markdown-table.js +0 -77
- package/dist/presentation/tui/ink/tui-bridge.d.ts +0 -195
- package/dist/presentation/tui/ink/tui-bridge.js +0 -289
- package/dist/presentation/tui/terminal-capabilities.d.ts +0 -15
- package/dist/presentation/tui/terminal-capabilities.js +0 -7
- package/dist/presentation/tui/terminal-mouse.d.ts +0 -5
- package/dist/presentation/tui/terminal-mouse.js +0 -19
- package/dist/presentation/tui/terminal-screen.d.ts +0 -10
- package/dist/presentation/tui/terminal-screen.js +0 -23
- package/dist/presentation/tui/tui-agent-event-runner.d.ts +0 -24
- package/dist/presentation/tui/tui-agent-event-runner.js +0 -69
- package/dist/presentation/tui/tui-application-contract.d.ts +0 -10
- package/dist/presentation/tui/tui-application-contract.js +0 -8
- package/dist/presentation/tui/tui-application.d.ts +0 -62
- package/dist/presentation/tui/tui-application.js +0 -675
- package/dist/presentation/tui/tui-attachment-input.d.ts +0 -2
- package/dist/presentation/tui/tui-attachment-input.js +0 -5
- package/dist/presentation/tui/tui-clipboard-paste-handlers.d.ts +0 -11
- package/dist/presentation/tui/tui-clipboard-paste-handlers.js +0 -25
- package/dist/presentation/tui/tui-command-context.d.ts +0 -3
- package/dist/presentation/tui/tui-command-context.js +0 -1
- package/dist/presentation/tui/tui-command-executor.d.ts +0 -38
- package/dist/presentation/tui/tui-command-executor.js +0 -214
- package/dist/presentation/tui/tui-command-host-factory.d.ts +0 -40
- package/dist/presentation/tui/tui-command-host-factory.js +0 -23
- package/dist/presentation/tui/tui-context-compaction.d.ts +0 -5
- package/dist/presentation/tui/tui-context-compaction.js +0 -22
- package/dist/presentation/tui/tui-context-service.d.ts +0 -34
- package/dist/presentation/tui/tui-context-service.js +0 -126
- package/dist/presentation/tui/tui-file-suggestions.d.ts +0 -3
- package/dist/presentation/tui/tui-file-suggestions.js +0 -8
- package/dist/presentation/tui/tui-goal-controller.d.ts +0 -14
- package/dist/presentation/tui/tui-goal-controller.js +0 -52
- package/dist/presentation/tui/tui-initial-model.d.ts +0 -3
- package/dist/presentation/tui/tui-initial-model.js +0 -28
- package/dist/presentation/tui/tui-lifecycle-actions.d.ts +0 -13
- package/dist/presentation/tui/tui-lifecycle-actions.js +0 -45
- package/dist/presentation/tui/tui-manual-compaction.d.ts +0 -18
- package/dist/presentation/tui/tui-manual-compaction.js +0 -31
- package/dist/presentation/tui/tui-media-model-selection.d.ts +0 -12
- package/dist/presentation/tui/tui-media-model-selection.js +0 -38
- package/dist/presentation/tui/tui-prompt-dispatcher.d.ts +0 -16
- package/dist/presentation/tui/tui-prompt-dispatcher.js +0 -38
- package/dist/presentation/tui/tui-skill-controller.d.ts +0 -11
- package/dist/presentation/tui/tui-skill-controller.js +0 -13
- package/dist/presentation/tui/tui-tool-approval.d.ts +0 -22
- package/dist/presentation/tui/tui-tool-approval.js +0 -73
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -1
|
@@ -1,525 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { CliError } from '../../domain/errors/cli-error.js';
|
|
5
|
-
import { CLI_ERROR_CODES } from '../../domain/errors/error-codes.js';
|
|
6
|
-
import { isRecord, isSessionEvent, isSessionMetadata, isTranscriptEntry } from '../../domain/session/session-schema.js';
|
|
7
|
-
import { isGoalEventType, isPersistedGoalEventData } from '../../domain/orchestration/goal.js';
|
|
8
|
-
import { isAlreadyExists, isFileNotFound } from '../filesystem/fs-errors.js';
|
|
9
|
-
import { acquireAdvisoryFileLock, atomicWriteFile, releaseAdvisoryFileLock } from '../filesystem/atomic-file-store.js';
|
|
10
|
-
import { isSafeProjectKey, resolveProjectSessionPaths, resolveProjectSessionPathsForKey } from './project-session-paths.js';
|
|
11
|
-
import { appendJournalRecord, appendJournalRecords, eventRecord, journalEvents, journalTranscript, latestMetadata, metadataRecord, readJournal, repairJournal, transcriptRecord } from './session-journal.js';
|
|
12
|
-
import { indexProjectSession, readProjectSessionIndex, readSessionLocator, removeIndexedSession } from './session-index.js';
|
|
13
|
-
import { RESOURCE_LIMITS } from '../../domain/runtime/resource-limits.js';
|
|
14
|
-
import { readJsonFileBounded } from '../filesystem/bounded-json-reader.js';
|
|
15
|
-
const SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
16
|
-
const ATTACHMENT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
17
|
-
const SESSION_LOCK_STALE_MS = 5 * 60 * 1000;
|
|
18
|
-
export class FileSessionStore {
|
|
19
|
-
paths;
|
|
20
|
-
constructor(paths) {
|
|
21
|
-
this.paths = paths;
|
|
22
|
-
}
|
|
23
|
-
async create(input) {
|
|
24
|
-
const now = new Date().toISOString();
|
|
25
|
-
const metadata = { ...input, id: crypto.randomUUID(), createdAt: now, updatedAt: now };
|
|
26
|
-
const sessionPaths = resolveProjectSessionPaths(this.paths, metadata.cwd, metadata.id);
|
|
27
|
-
await fs.mkdir(sessionPaths.attachmentsDirectory, { recursive: true });
|
|
28
|
-
await appendJournalRecord(sessionPaths.journalFile, metadataRecord(metadata));
|
|
29
|
-
await indexProjectSession(this.paths, metadata, sessionPaths.projectKey);
|
|
30
|
-
return metadata;
|
|
31
|
-
}
|
|
32
|
-
async get(sessionId) {
|
|
33
|
-
const sessionPaths = await this.locate(sessionId);
|
|
34
|
-
if (sessionPaths === undefined)
|
|
35
|
-
return undefined;
|
|
36
|
-
try {
|
|
37
|
-
const metadata = latestMetadata(await readJournal(sessionPaths.journalFile));
|
|
38
|
-
if (metadata === undefined)
|
|
39
|
-
throw new Error('Session metadata is missing.');
|
|
40
|
-
return metadata;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
throw this.corrupt(sessionId, error);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async list(projectFingerprint) {
|
|
47
|
-
const sessions = [];
|
|
48
|
-
for (const projectKey of await this.projectKeys()) {
|
|
49
|
-
const projectPaths = resolveProjectSessionPathsForKey(this.paths, projectKey, '00000000-0000-4000-8000-000000000000');
|
|
50
|
-
const index = await this.readOrRebuildIndex(projectPaths.projectIndexFile, projectKey);
|
|
51
|
-
for (const metadata of Object.values(index))
|
|
52
|
-
if (projectFingerprint === undefined || metadata.projectFingerprint === projectFingerprint)
|
|
53
|
-
sessions.push(metadata);
|
|
54
|
-
}
|
|
55
|
-
return sessions.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
56
|
-
}
|
|
57
|
-
async updateStatus(sessionId, status) {
|
|
58
|
-
return this.withLock(sessionId, async () => {
|
|
59
|
-
const metadata = await this.require(sessionId);
|
|
60
|
-
const updated = { ...metadata, status, updatedAt: new Date().toISOString() };
|
|
61
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
62
|
-
await appendJournalRecord(sessionPaths.journalFile, metadataRecord(updated));
|
|
63
|
-
await indexProjectSession(this.paths, updated, sessionPaths.projectKey);
|
|
64
|
-
return updated;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
async rename(sessionId, name) {
|
|
68
|
-
const normalized = name.trim().replace(/\s+/gu, ' ');
|
|
69
|
-
if (normalized.length === 0 || normalized.length > 120 || /[\r\n]/u.test(normalized) || normalized.includes('\0')) {
|
|
70
|
-
throw new CliError(CLI_ERROR_CODES.INVALID_ARGUMENT, 'Session name is invalid.', { category: 'session', userMessage: 'Session name must be between 1 and 120 printable characters.' });
|
|
71
|
-
}
|
|
72
|
-
return this.withLock(sessionId, async () => {
|
|
73
|
-
const metadata = await this.require(sessionId);
|
|
74
|
-
const updated = { ...metadata, name: normalized, updatedAt: new Date().toISOString() };
|
|
75
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
76
|
-
await appendJournalRecord(sessionPaths.journalFile, metadataRecord(updated));
|
|
77
|
-
await indexProjectSession(this.paths, updated, sessionPaths.projectKey);
|
|
78
|
-
return updated;
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
async appendEvent(event, options = {}) {
|
|
82
|
-
const records = [{ kind: 'event', event }];
|
|
83
|
-
if (options.locked === true)
|
|
84
|
-
await this.appendJournalLocked(event.sessionId, records);
|
|
85
|
-
else
|
|
86
|
-
await this.appendJournal(event.sessionId, records);
|
|
87
|
-
}
|
|
88
|
-
async appendTranscript(sessionId, entry) {
|
|
89
|
-
await this.appendJournal(sessionId, [{ kind: 'transcript', entry }]);
|
|
90
|
-
}
|
|
91
|
-
async appendJournal(sessionId, records) {
|
|
92
|
-
if (records.length === 0)
|
|
93
|
-
return;
|
|
94
|
-
await this.withLock(sessionId, () => this.appendJournalLocked(sessionId, records));
|
|
95
|
-
}
|
|
96
|
-
async readEvents(sessionId) {
|
|
97
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
98
|
-
await this.require(sessionId);
|
|
99
|
-
return journalEvents(await readJournal(sessionPaths.journalFile));
|
|
100
|
-
}
|
|
101
|
-
async readTranscript(sessionId) {
|
|
102
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
103
|
-
await this.require(sessionId);
|
|
104
|
-
return journalTranscript(await readJournal(sessionPaths.journalFile));
|
|
105
|
-
}
|
|
106
|
-
async readHistory(sessionId) {
|
|
107
|
-
return this.withLock(sessionId, async () => {
|
|
108
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
109
|
-
await this.require(sessionId);
|
|
110
|
-
const records = await readJournal(sessionPaths.journalFile);
|
|
111
|
-
return { events: journalEvents(records), transcript: journalTranscript(records) };
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
async delete(sessionId) {
|
|
115
|
-
const metadata = await this.get(sessionId);
|
|
116
|
-
if (metadata === undefined)
|
|
117
|
-
return false;
|
|
118
|
-
await this.withLock(sessionId, async () => {
|
|
119
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
120
|
-
await fs.rm(sessionPaths.journalFile, { force: true });
|
|
121
|
-
await fs.rm(sessionPaths.sessionDirectory, { recursive: true, force: true });
|
|
122
|
-
await removeIndexedSession(this.paths, metadata, sessionPaths.projectKey);
|
|
123
|
-
});
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
async fork(sessionId, overrides = {}) {
|
|
127
|
-
const snapshot = await this.readSnapshot(sessionId);
|
|
128
|
-
const source = snapshot.metadata;
|
|
129
|
-
const forked = await this.create({ projectFingerprint: source.projectFingerprint, cwd: source.cwd, model: overrides.model ?? source.model, profile: overrides.profile ?? source.profile, status: 'active' });
|
|
130
|
-
try {
|
|
131
|
-
await this.withLock(forked.id, async () => {
|
|
132
|
-
const sessionPaths = await this.requirePaths(forked.id);
|
|
133
|
-
for (const event of snapshot.events) {
|
|
134
|
-
const data = pauseForkedGoalEvent(event.data);
|
|
135
|
-
await appendJournalRecord(sessionPaths.journalFile, eventRecord({ ...event, sessionId: forked.id, ...(data === undefined ? {} : { data }) }));
|
|
136
|
-
}
|
|
137
|
-
for (const entry of snapshot.transcript)
|
|
138
|
-
await appendJournalRecord(sessionPaths.journalFile, transcriptRecord(entry));
|
|
139
|
-
for (const [attachmentId, item] of snapshot.attachments) {
|
|
140
|
-
if (item.attachment !== undefined)
|
|
141
|
-
await this.persistAttachment(forked.id, { ...item.attachment, id: attachmentId }, item.bytes);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
return forked;
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
try {
|
|
148
|
-
await this.delete(forked.id);
|
|
149
|
-
}
|
|
150
|
-
catch (cleanupError) {
|
|
151
|
-
throw new AggregateError([error, cleanupError], 'Session fork failed and cleanup was incomplete.');
|
|
152
|
-
}
|
|
153
|
-
throw error;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async compact(sessionId, summary, options = {}) {
|
|
157
|
-
const normalized = summary.trim();
|
|
158
|
-
if (normalized.length === 0)
|
|
159
|
-
throw new CliError(CLI_ERROR_CODES.SESSION_CORRUPTED, 'Compaction summary cannot be empty.', { category: 'session', userMessage: 'Compaction summary cannot be empty.' });
|
|
160
|
-
const timestamp = new Date().toISOString();
|
|
161
|
-
await this.appendJournal(sessionId, [
|
|
162
|
-
{ kind: 'transcript', entry: { type: 'system', timestamp, content: `[Compacted context]\n${normalized}`, ...(options.turnId === undefined ? {} : { turnId: options.turnId }) } },
|
|
163
|
-
{ kind: 'event', event: { type: 'context.compacted', timestamp, sessionId, ...(options.turnId === undefined ? {} : { turnId: options.turnId }), data: { summary: normalized } } },
|
|
164
|
-
]);
|
|
165
|
-
}
|
|
166
|
-
async export(sessionId) {
|
|
167
|
-
const snapshot = await this.readSnapshot(sessionId);
|
|
168
|
-
const attachments = [];
|
|
169
|
-
for (const entry of snapshot.transcript)
|
|
170
|
-
for (const attachmentId of entry.attachmentIds ?? []) {
|
|
171
|
-
if (attachments.some((item) => item.attachment.id === attachmentId))
|
|
172
|
-
continue;
|
|
173
|
-
const item = snapshot.attachments.get(attachmentId);
|
|
174
|
-
if (item === undefined)
|
|
175
|
-
continue;
|
|
176
|
-
const attachment = item.attachment ?? { id: attachmentId, name: attachmentId, mimeType: 'application/octet-stream', sizeBytes: item.bytes.byteLength, source: 'file' };
|
|
177
|
-
attachments.push({ attachment, dataBase64: Buffer.from(item.bytes).toString('base64') });
|
|
178
|
-
}
|
|
179
|
-
return { metadata: snapshot.metadata, events: snapshot.events, transcript: snapshot.transcript, attachments };
|
|
180
|
-
}
|
|
181
|
-
async import(bundle, projectFingerprint, cwd) {
|
|
182
|
-
validateBundle(bundle);
|
|
183
|
-
const metadata = await this.create({ projectFingerprint, cwd, model: bundle.metadata.model, profile: bundle.metadata.profile, status: 'active' });
|
|
184
|
-
try {
|
|
185
|
-
for (const event of bundle.events) {
|
|
186
|
-
const data = pauseImportedGoalEvent(event.data);
|
|
187
|
-
await this.appendEvent({ ...event, sessionId: metadata.id, ...(data === undefined ? {} : { data }) });
|
|
188
|
-
}
|
|
189
|
-
for (const entry of bundle.transcript)
|
|
190
|
-
await this.appendTranscript(metadata.id, entry);
|
|
191
|
-
for (const item of bundle.attachments)
|
|
192
|
-
await this.saveAttachment(metadata.id, item.attachment, Buffer.from(item.dataBase64, 'base64'));
|
|
193
|
-
return metadata;
|
|
194
|
-
}
|
|
195
|
-
catch (error) {
|
|
196
|
-
try {
|
|
197
|
-
await this.delete(metadata.id);
|
|
198
|
-
}
|
|
199
|
-
catch (cleanupError) {
|
|
200
|
-
throw new AggregateError([error, cleanupError], 'Session import failed and cleanup was incomplete.');
|
|
201
|
-
}
|
|
202
|
-
throw error;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
async saveAttachment(sessionId, attachment, bytes) {
|
|
206
|
-
if (!ATTACHMENT_ID_PATTERN.test(attachment.id))
|
|
207
|
-
throw new CliError(CLI_ERROR_CODES.ATTACHMENT_INVALID_IMAGE, 'Attachment id is invalid.', { category: 'attachment', userMessage: 'Attachment name is invalid.' });
|
|
208
|
-
if (attachment.sizeBytes < 0 || attachment.sizeBytes > RESOURCE_LIMITS.maxAttachmentBytes)
|
|
209
|
-
throw new CliError(CLI_ERROR_CODES.ATTACHMENT_TOO_LARGE, 'Attachment exceeds the allowed size.', { category: 'attachment', userMessage: 'Attachment exceeds the allowed size.' });
|
|
210
|
-
if (bytes.byteLength !== attachment.sizeBytes)
|
|
211
|
-
throw new CliError(CLI_ERROR_CODES.ATTACHMENT_INVALID_IMAGE, 'Attachment size does not match metadata.', { category: 'attachment', userMessage: 'Attachment size does not match its metadata.' });
|
|
212
|
-
return this.withLock(sessionId, () => this.persistAttachment(sessionId, attachment, bytes));
|
|
213
|
-
}
|
|
214
|
-
async persistAttachment(sessionId, attachment, bytes) {
|
|
215
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
216
|
-
await this.require(sessionId);
|
|
217
|
-
await fs.mkdir(sessionPaths.attachmentsDirectory, { recursive: true });
|
|
218
|
-
const filePath = path.join(sessionPaths.attachmentsDirectory, `${attachment.id}.bin`);
|
|
219
|
-
await fs.writeFile(filePath, bytes, { flag: 'wx', mode: 0o600 }).catch(async (error) => { if (!isAlreadyExists(error))
|
|
220
|
-
throw error; await fs.writeFile(filePath, bytes, { mode: 0o600 }); });
|
|
221
|
-
await atomicWriteFile(path.join(sessionPaths.attachmentsDirectory, `${attachment.id}.json`), `${JSON.stringify(attachment, null, 2)}\n`);
|
|
222
|
-
return { ...attachment, storagePath: path.posix.join('attachments', `${attachment.id}.bin`) };
|
|
223
|
-
}
|
|
224
|
-
async readAttachment(sessionId, attachmentId) {
|
|
225
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
226
|
-
await this.require(sessionId);
|
|
227
|
-
if (!ATTACHMENT_ID_PATTERN.test(attachmentId))
|
|
228
|
-
return undefined;
|
|
229
|
-
const filePath = path.join(sessionPaths.attachmentsDirectory, `${attachmentId}.bin`);
|
|
230
|
-
try {
|
|
231
|
-
const stat = await fs.stat(filePath);
|
|
232
|
-
if (stat.size > RESOURCE_LIMITS.maxAttachmentBytes) {
|
|
233
|
-
throw new CliError(CLI_ERROR_CODES.ATTACHMENT_TOO_LARGE, 'Stored attachment exceeds the allowed size.', { category: 'attachment', userMessage: 'Stored attachment exceeds the allowed size.' });
|
|
234
|
-
}
|
|
235
|
-
return await fs.readFile(filePath);
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
if (isFileNotFound(error))
|
|
239
|
-
return undefined;
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
async recoverStaleLock(sessionId) {
|
|
244
|
-
const sessionPaths = await this.locate(sessionId);
|
|
245
|
-
if (sessionPaths === undefined)
|
|
246
|
-
return false;
|
|
247
|
-
let stat;
|
|
248
|
-
try {
|
|
249
|
-
stat = await fs.stat(sessionPaths.lockFile);
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
if (isFileNotFound(error))
|
|
253
|
-
return false;
|
|
254
|
-
throw error;
|
|
255
|
-
}
|
|
256
|
-
if (Date.now() - stat.mtimeMs < SESSION_LOCK_STALE_MS)
|
|
257
|
-
return false;
|
|
258
|
-
let lock = {};
|
|
259
|
-
try {
|
|
260
|
-
lock = await readJsonFileBounded(sessionPaths.lockFile, 4 * 1024);
|
|
261
|
-
}
|
|
262
|
-
catch { /* stale malformed lock is recoverable after age threshold */ }
|
|
263
|
-
if (typeof lock.pid === 'number' && isProcessAlive(lock.pid))
|
|
264
|
-
return false;
|
|
265
|
-
await fs.rm(sessionPaths.lockFile, { force: true });
|
|
266
|
-
return true;
|
|
267
|
-
}
|
|
268
|
-
async repair(sessionId) {
|
|
269
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
270
|
-
const removed = await this.withLock(sessionId, () => repairJournal(sessionPaths.journalFile));
|
|
271
|
-
return { eventsRemoved: removed, transcriptRemoved: 0 };
|
|
272
|
-
}
|
|
273
|
-
async withLock(sessionId, action) {
|
|
274
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
275
|
-
await fs.mkdir(sessionPaths.sessionDirectory, { recursive: true });
|
|
276
|
-
let handle;
|
|
277
|
-
try {
|
|
278
|
-
handle = await acquireAdvisoryFileLock(sessionPaths.lockFile);
|
|
279
|
-
}
|
|
280
|
-
catch (error) {
|
|
281
|
-
if (isAlreadyExists(error) && await this.recoverStaleLock(sessionId))
|
|
282
|
-
return this.withLock(sessionId, action);
|
|
283
|
-
if (isAlreadyExists(error))
|
|
284
|
-
throw new CliError(CLI_ERROR_CODES.SESSION_LOCKED, `Session is locked: ${sessionId}`, { category: 'session', userMessage: 'The session is being used by another process. Try again later.', retryable: true });
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
try {
|
|
288
|
-
return await action();
|
|
289
|
-
}
|
|
290
|
-
finally {
|
|
291
|
-
await releaseAdvisoryFileLock(handle, sessionPaths.lockFile);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
async require(sessionId) {
|
|
295
|
-
const metadata = await this.get(sessionId);
|
|
296
|
-
if (metadata === undefined)
|
|
297
|
-
throw new CliError(CLI_ERROR_CODES.SESSION_NOT_FOUND, `Session not found: ${sessionId}`, { category: 'session', userMessage: `Session not found: ${sessionId}.` });
|
|
298
|
-
return metadata;
|
|
299
|
-
}
|
|
300
|
-
async requirePaths(sessionId) {
|
|
301
|
-
const sessionPaths = await this.locate(sessionId);
|
|
302
|
-
if (sessionPaths === undefined)
|
|
303
|
-
throw new CliError(CLI_ERROR_CODES.SESSION_NOT_FOUND, `Session not found: ${sessionId}`, { category: 'session', userMessage: `Session not found: ${sessionId}.` });
|
|
304
|
-
return sessionPaths;
|
|
305
|
-
}
|
|
306
|
-
async locate(sessionId) {
|
|
307
|
-
if (!SESSION_ID_PATTERN.test(sessionId))
|
|
308
|
-
return undefined;
|
|
309
|
-
const locator = await readSessionLocator(this.paths);
|
|
310
|
-
const projectKey = locator.sessions[sessionId];
|
|
311
|
-
if (typeof projectKey === 'string' && isSafeProjectKey(projectKey)) {
|
|
312
|
-
const located = resolveProjectSessionPathsForKey(this.paths, projectKey, sessionId);
|
|
313
|
-
if (await fileExists(located.journalFile))
|
|
314
|
-
return located;
|
|
315
|
-
}
|
|
316
|
-
return this.locateByScan(sessionId);
|
|
317
|
-
}
|
|
318
|
-
async locateByScan(sessionId) {
|
|
319
|
-
for (const projectKey of await this.projectKeys()) {
|
|
320
|
-
const candidate = resolveProjectSessionPathsForKey(this.paths, projectKey, sessionId);
|
|
321
|
-
if (await fileExists(candidate.journalFile))
|
|
322
|
-
return candidate;
|
|
323
|
-
}
|
|
324
|
-
return undefined;
|
|
325
|
-
}
|
|
326
|
-
async projectKeys() {
|
|
327
|
-
try {
|
|
328
|
-
return (await fs.readdir(this.paths.projectsDir, { withFileTypes: true })).filter((entry) => entry.isDirectory() && isSafeProjectKey(entry.name)).map((entry) => entry.name);
|
|
329
|
-
}
|
|
330
|
-
catch (error) {
|
|
331
|
-
if (isFileNotFound(error))
|
|
332
|
-
return [];
|
|
333
|
-
throw error;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
async readOrRebuildIndex(filePath, projectKey) {
|
|
337
|
-
try {
|
|
338
|
-
const sessions = (await readProjectSessionIndex(filePath, projectKey)).sessions;
|
|
339
|
-
if (await this.indexMatchesJournals(projectKey, sessions))
|
|
340
|
-
return sessions;
|
|
341
|
-
return this.rebuildProjectIndex(projectKey);
|
|
342
|
-
}
|
|
343
|
-
catch {
|
|
344
|
-
return this.rebuildProjectIndex(projectKey);
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
async indexMatchesJournals(projectKey, sessions) {
|
|
348
|
-
const journalIds = await this.projectJournalIds(projectKey);
|
|
349
|
-
const indexedIds = Object.keys(sessions);
|
|
350
|
-
return journalIds.length === indexedIds.length && journalIds.every((id) => sessions[id] !== undefined);
|
|
351
|
-
}
|
|
352
|
-
async projectJournalIds(projectKey) {
|
|
353
|
-
const directory = path.join(this.paths.projectsDir, projectKey);
|
|
354
|
-
try {
|
|
355
|
-
return (await fs.readdir(directory, { withFileTypes: true }))
|
|
356
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith('.jsonl'))
|
|
357
|
-
.map((entry) => entry.name.slice(0, -'.jsonl'.length))
|
|
358
|
-
.filter((id) => SESSION_ID_PATTERN.test(id));
|
|
359
|
-
}
|
|
360
|
-
catch (error) {
|
|
361
|
-
if (isFileNotFound(error))
|
|
362
|
-
return [];
|
|
363
|
-
throw error;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
async projectHasJournals(projectKey) {
|
|
367
|
-
const directory = path.join(this.paths.projectsDir, projectKey);
|
|
368
|
-
try {
|
|
369
|
-
return (await fs.readdir(directory, { withFileTypes: true })).some((entry) => entry.isFile() && entry.name.endsWith('.jsonl'));
|
|
370
|
-
}
|
|
371
|
-
catch (error) {
|
|
372
|
-
if (isFileNotFound(error))
|
|
373
|
-
return false;
|
|
374
|
-
throw error;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
async rebuildProjectIndex(projectKey) {
|
|
378
|
-
const sessions = {};
|
|
379
|
-
const projectDirectory = path.join(this.paths.projectsDir, projectKey);
|
|
380
|
-
for (const entry of await fs.readdir(projectDirectory, { withFileTypes: true })) {
|
|
381
|
-
if (!entry.isFile() || !entry.name.endsWith('.jsonl'))
|
|
382
|
-
continue;
|
|
383
|
-
try {
|
|
384
|
-
const metadata = latestMetadata(await readJournal(path.join(projectDirectory, entry.name)));
|
|
385
|
-
if (metadata !== undefined)
|
|
386
|
-
sessions[metadata.id] = metadata;
|
|
387
|
-
}
|
|
388
|
-
catch { /* A corrupted session remains inspectable through session show/repair. */ }
|
|
389
|
-
}
|
|
390
|
-
const indexFile = path.join(projectDirectory, 'index.json');
|
|
391
|
-
await fs.mkdir(projectDirectory, { recursive: true });
|
|
392
|
-
await atomicWriteFile(indexFile, `${JSON.stringify({ projectKey, sessions }, null, 2)}\n`);
|
|
393
|
-
for (const metadata of Object.values(sessions))
|
|
394
|
-
await indexProjectSession(this.paths, metadata, projectKey);
|
|
395
|
-
return sessions;
|
|
396
|
-
}
|
|
397
|
-
async readSnapshot(sessionId) {
|
|
398
|
-
return this.withLock(sessionId, async () => {
|
|
399
|
-
const metadata = await this.require(sessionId);
|
|
400
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
401
|
-
const records = await readJournal(sessionPaths.journalFile);
|
|
402
|
-
const events = journalEvents(records);
|
|
403
|
-
const transcript = journalTranscript(records);
|
|
404
|
-
const attachments = new Map();
|
|
405
|
-
for (const entry of transcript)
|
|
406
|
-
for (const attachmentId of entry.attachmentIds ?? []) {
|
|
407
|
-
if (attachments.has(attachmentId))
|
|
408
|
-
continue;
|
|
409
|
-
const bytes = await this.readAttachment(sessionId, attachmentId);
|
|
410
|
-
if (bytes !== undefined)
|
|
411
|
-
attachments.set(attachmentId, { bytes, attachment: await this.readAttachmentMetadata(sessionPaths, attachmentId) });
|
|
412
|
-
}
|
|
413
|
-
return { metadata, events, transcript, attachments };
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
async appendJournalLocked(sessionId, records) {
|
|
417
|
-
const sessionPaths = await this.requirePaths(sessionId);
|
|
418
|
-
await this.require(sessionId);
|
|
419
|
-
const journalRecords = records.map((record) => {
|
|
420
|
-
if (record.kind === 'event' && record.event.sessionId !== sessionId) {
|
|
421
|
-
throw new CliError(CLI_ERROR_CODES.SESSION_CORRUPTED, 'Cannot append an event to a different session.', {
|
|
422
|
-
category: 'session', userMessage: 'Session event data is invalid.',
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
return record.kind === 'event' ? eventRecord(record.event) : transcriptRecord(record.entry);
|
|
426
|
-
});
|
|
427
|
-
await appendJournalRecords(sessionPaths.journalFile, journalRecords);
|
|
428
|
-
}
|
|
429
|
-
async readAttachmentMetadata(sessionPaths, attachmentId) {
|
|
430
|
-
try {
|
|
431
|
-
return parseAttachment(await readJsonFileBounded(path.join(sessionPaths.attachmentsDirectory, `${attachmentId}.json`), RESOURCE_LIMITS.configFileBytes));
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
if (isFileNotFound(error))
|
|
435
|
-
return undefined;
|
|
436
|
-
throw error;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
corrupt(sessionId, cause) { return new CliError(CLI_ERROR_CODES.SESSION_CORRUPTED, `Session metadata is corrupted: ${sessionId}`, { category: 'session', userMessage: 'Session is corrupted and its metadata cannot be read.', cause }); }
|
|
440
|
-
}
|
|
441
|
-
function pauseForkedGoalEvent(data) {
|
|
442
|
-
return pauseGoalEventData(data);
|
|
443
|
-
}
|
|
444
|
-
function pauseImportedGoalEvent(data) {
|
|
445
|
-
return pauseGoalEventData(data);
|
|
446
|
-
}
|
|
447
|
-
function pauseGoalEventData(data) {
|
|
448
|
-
if (data === undefined || typeof data['goal'] !== 'object' || data['goal'] === null)
|
|
449
|
-
return data;
|
|
450
|
-
const goal = data['goal'];
|
|
451
|
-
if (goal['status'] !== 'active')
|
|
452
|
-
return data;
|
|
453
|
-
return { ...data, goal: { ...goal, status: 'paused', updatedAt: new Date().toISOString() }, reason: 'Explicit resume is required after fork or import.' };
|
|
454
|
-
}
|
|
455
|
-
async function fileExists(filePath) { try {
|
|
456
|
-
await fs.access(filePath);
|
|
457
|
-
return true;
|
|
458
|
-
}
|
|
459
|
-
catch (error) {
|
|
460
|
-
if (isFileNotFound(error))
|
|
461
|
-
return false;
|
|
462
|
-
throw error;
|
|
463
|
-
} }
|
|
464
|
-
function isProcessAlive(pid) { if (pid === process.pid)
|
|
465
|
-
return true; try {
|
|
466
|
-
process.kill(pid, 0);
|
|
467
|
-
return true;
|
|
468
|
-
}
|
|
469
|
-
catch {
|
|
470
|
-
return false;
|
|
471
|
-
} }
|
|
472
|
-
function validateBundle(bundle) {
|
|
473
|
-
if (!isSessionMetadata(bundle.metadata) || !Array.isArray(bundle.events) || !Array.isArray(bundle.transcript) || !Array.isArray(bundle.attachments))
|
|
474
|
-
throw invalidBundle('Session export file is invalid.');
|
|
475
|
-
if (bundle.events.length > RESOURCE_LIMITS.sessionEvents || bundle.transcript.length > RESOURCE_LIMITS.sessionTranscriptEntries || bundle.attachments.length > RESOURCE_LIMITS.sessionAttachments)
|
|
476
|
-
throw invalidBundle('Session export exceeds the supported entry limits.');
|
|
477
|
-
for (const event of bundle.events) {
|
|
478
|
-
if (!isSessionEvent(event))
|
|
479
|
-
throw invalidBundle('Session export contains an invalid event.');
|
|
480
|
-
if (isGoalEventType(event.type) && !isPersistedGoalEventData(event.data))
|
|
481
|
-
throw invalidBundle('Session export contains an invalid goal event.');
|
|
482
|
-
if (byteLength(event.type) > 256 || byteLength(event.timestamp) > 128 || byteLength(event.sessionId) > 128)
|
|
483
|
-
throw invalidBundle('Session event metadata is too large.');
|
|
484
|
-
}
|
|
485
|
-
const attachmentIds = new Set();
|
|
486
|
-
let totalAttachmentBytes = 0;
|
|
487
|
-
for (const entry of bundle.transcript) {
|
|
488
|
-
if (!isTranscriptEntry(entry) || byteLength(entry.content) > RESOURCE_LIMITS.sessionTextBytes)
|
|
489
|
-
throw invalidBundle('Session export contains an invalid transcript entry.');
|
|
490
|
-
if (entry.attachmentIds !== undefined && (!Array.isArray(entry.attachmentIds) || entry.attachmentIds.some((id) => typeof id !== 'string' || !ATTACHMENT_ID_PATTERN.test(id))))
|
|
491
|
-
throw invalidBundle('Session transcript contains invalid attachment references.');
|
|
492
|
-
}
|
|
493
|
-
for (const item of bundle.attachments) {
|
|
494
|
-
if (!isSessionAttachment(item))
|
|
495
|
-
throw invalidBundle('Session export contains an invalid attachment.');
|
|
496
|
-
const attachment = item.attachment;
|
|
497
|
-
if (typeof attachment.id !== 'string' || !ATTACHMENT_ID_PATTERN.test(attachment.id) || attachmentIds.has(attachment.id) || typeof attachment.name !== 'string' || typeof attachment.mimeType !== 'string' || typeof attachment.sizeBytes !== 'number' || !Number.isSafeInteger(attachment.sizeBytes) || attachment.sizeBytes < 0 || attachment.sizeBytes > RESOURCE_LIMITS.maxAttachmentBytes || (attachment.source !== 'clipboard' && attachment.source !== 'file'))
|
|
498
|
-
throw invalidBundle('Session export contains invalid attachment metadata.');
|
|
499
|
-
const bytes = Buffer.from(item.dataBase64, 'base64');
|
|
500
|
-
if (bytes.toString('base64') !== item.dataBase64 || bytes.byteLength !== attachment.sizeBytes)
|
|
501
|
-
throw invalidBundle('Session export contains an invalid attachment payload.');
|
|
502
|
-
totalAttachmentBytes += bytes.byteLength;
|
|
503
|
-
if (totalAttachmentBytes > RESOURCE_LIMITS.sessionAttachmentTotalBytes)
|
|
504
|
-
throw invalidBundle('Session export exceeds the total attachment limit.');
|
|
505
|
-
attachmentIds.add(attachment.id);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
function isSessionAttachment(value) {
|
|
509
|
-
if (!isRecord(value) || !isRecord(value['attachment']) || typeof value['dataBase64'] !== 'string')
|
|
510
|
-
return false;
|
|
511
|
-
const attachment = value['attachment'];
|
|
512
|
-
return typeof attachment['id'] === 'string' && typeof attachment['name'] === 'string' && typeof attachment['mimeType'] === 'string'
|
|
513
|
-
&& typeof attachment['sizeBytes'] === 'number' && Number.isSafeInteger(attachment['sizeBytes'])
|
|
514
|
-
&& (attachment['source'] === 'clipboard' || attachment['source'] === 'file');
|
|
515
|
-
}
|
|
516
|
-
function byteLength(value) { return Buffer.byteLength(value, 'utf8'); }
|
|
517
|
-
function invalidBundle(message) { return new CliError(CLI_ERROR_CODES.SESSION_CORRUPTED, message, { category: 'session', userMessage: message }); }
|
|
518
|
-
function parseAttachment(value) {
|
|
519
|
-
if (typeof value !== 'object' || value === null)
|
|
520
|
-
throw new Error('Invalid attachment metadata.');
|
|
521
|
-
const record = value;
|
|
522
|
-
if (typeof record['id'] !== 'string' || typeof record['name'] !== 'string' || typeof record['mimeType'] !== 'string' || typeof record['sizeBytes'] !== 'number' || (record['source'] !== 'clipboard' && record['source'] !== 'file'))
|
|
523
|
-
throw new Error('Invalid attachment metadata.');
|
|
524
|
-
return value;
|
|
525
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { PlatformPaths } from '../platform/platform-paths.js';
|
|
2
|
-
import { type HostPlatformContext } from '../platform/host-platform.js';
|
|
3
|
-
export interface ProjectSessionPaths {
|
|
4
|
-
projectKey: string;
|
|
5
|
-
projectDirectory: string;
|
|
6
|
-
projectIndexFile: string;
|
|
7
|
-
sessionId: string;
|
|
8
|
-
journalFile: string;
|
|
9
|
-
sessionDirectory: string;
|
|
10
|
-
attachmentsDirectory: string;
|
|
11
|
-
subagentsDirectory: string;
|
|
12
|
-
lockFile: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function isSafeProjectKey(value: string): boolean;
|
|
15
|
-
export declare function createProjectKey(cwd: string, platform?: HostPlatformContext): string;
|
|
16
|
-
export declare function resolveProjectSessionPaths(paths: PlatformPaths, cwd: string, sessionId: string): ProjectSessionPaths;
|
|
17
|
-
export declare function resolveProjectSessionPathsForKey(paths: PlatformPaths, projectKey: string, sessionId: string): ProjectSessionPaths;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { detectHostPlatform } from '../platform/host-platform.js';
|
|
4
|
-
export function isSafeProjectKey(value) {
|
|
5
|
-
return /^[A-Za-z0-9._-]+--[0-9a-f]{12}$/u.test(value);
|
|
6
|
-
}
|
|
7
|
-
export function createProjectKey(cwd, platform = detectHostPlatform()) {
|
|
8
|
-
const canonical = path.resolve(cwd);
|
|
9
|
-
const comparisonValue = platform.isWindows ? canonical.toLowerCase() : canonical;
|
|
10
|
-
const hash = crypto.createHash('sha256').update(comparisonValue, 'utf8').digest('hex').slice(0, 12);
|
|
11
|
-
const display = canonical
|
|
12
|
-
.replaceAll('\\', '-')
|
|
13
|
-
.replaceAll('/', '-')
|
|
14
|
-
.replaceAll(':', '-')
|
|
15
|
-
.replace(/[^A-Za-z0-9._-]+/gu, '-')
|
|
16
|
-
.replace(/-+/gu, '-')
|
|
17
|
-
.replace(/^-|-$/gu, '')
|
|
18
|
-
.slice(0, 120);
|
|
19
|
-
return `${display || 'project'}--${hash}`;
|
|
20
|
-
}
|
|
21
|
-
export function resolveProjectSessionPaths(paths, cwd, sessionId) {
|
|
22
|
-
const projectKey = createProjectKey(cwd, paths.platform);
|
|
23
|
-
return resolveProjectSessionPathsForKey(paths, projectKey, sessionId);
|
|
24
|
-
}
|
|
25
|
-
export function resolveProjectSessionPathsForKey(paths, projectKey, sessionId) {
|
|
26
|
-
if (!isSafeProjectKey(projectKey))
|
|
27
|
-
throw new Error('Invalid project session key.');
|
|
28
|
-
const projectDirectory = path.join(paths.projectsDir, projectKey);
|
|
29
|
-
const sessionDirectory = path.join(projectDirectory, sessionId);
|
|
30
|
-
return {
|
|
31
|
-
projectKey,
|
|
32
|
-
projectDirectory,
|
|
33
|
-
projectIndexFile: path.join(projectDirectory, 'index.json'),
|
|
34
|
-
sessionId,
|
|
35
|
-
journalFile: path.join(projectDirectory, `${sessionId}.jsonl`),
|
|
36
|
-
sessionDirectory,
|
|
37
|
-
attachmentsDirectory: path.join(sessionDirectory, 'attachments'),
|
|
38
|
-
subagentsDirectory: path.join(sessionDirectory, 'subagents'),
|
|
39
|
-
lockFile: path.join(sessionDirectory, 'lock'),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { SessionMetadata } from '../../domain/session/session.js';
|
|
2
|
-
import type { PlatformPaths } from '../platform/platform-paths.js';
|
|
3
|
-
interface ProjectSessionIndex {
|
|
4
|
-
projectKey: string;
|
|
5
|
-
sessions: Record<string, SessionMetadata>;
|
|
6
|
-
}
|
|
7
|
-
interface SessionLocatorIndex {
|
|
8
|
-
sessions: Record<string, string>;
|
|
9
|
-
}
|
|
10
|
-
export declare function readProjectSessionIndex(filePath: string, projectKey: string): Promise<ProjectSessionIndex>;
|
|
11
|
-
export declare function writeProjectSessionIndex(filePath: string, projectKey: string, sessions: Readonly<Record<string, SessionMetadata>>): Promise<void>;
|
|
12
|
-
export declare function readSessionLocator(paths: PlatformPaths): Promise<SessionLocatorIndex>;
|
|
13
|
-
export declare function writeSessionLocator(paths: PlatformPaths, sessions: Readonly<Record<string, string>>): Promise<void>;
|
|
14
|
-
export declare function indexProjectSession(paths: PlatformPaths, metadata: SessionMetadata, projectKey: string): Promise<void>;
|
|
15
|
-
export declare function removeIndexedSession(paths: PlatformPaths, metadata: SessionMetadata, projectKey: string): Promise<void>;
|
|
16
|
-
export {};
|