praxis-agent 0.1.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/LICENSE +21 -0
- package/README.md +534 -0
- package/dist/application/background-agent-manager.d.ts +66 -0
- package/dist/application/background-agent-manager.d.ts.map +1 -0
- package/dist/application/background-agent-manager.js +362 -0
- package/dist/application/background-agent-manager.js.map +1 -0
- package/dist/application/background-bash-manager.d.ts +54 -0
- package/dist/application/background-bash-manager.d.ts.map +1 -0
- package/dist/application/background-bash-manager.js +354 -0
- package/dist/application/background-bash-manager.js.map +1 -0
- package/dist/application/background-task-id.d.ts +5 -0
- package/dist/application/background-task-id.d.ts.map +1 -0
- package/dist/application/background-task-id.js +25 -0
- package/dist/application/background-task-id.js.map +1 -0
- package/dist/application/claude-project-purge.d.ts +50 -0
- package/dist/application/claude-project-purge.d.ts.map +1 -0
- package/dist/application/claude-project-purge.js +459 -0
- package/dist/application/claude-project-purge.js.map +1 -0
- package/dist/application/managed-worktree.d.ts +15 -0
- package/dist/application/managed-worktree.d.ts.map +1 -0
- package/dist/application/managed-worktree.js +127 -0
- package/dist/application/managed-worktree.js.map +1 -0
- package/dist/application/model-compactor.d.ts +8 -0
- package/dist/application/model-compactor.d.ts.map +1 -0
- package/dist/application/model-compactor.js +70 -0
- package/dist/application/model-compactor.js.map +1 -0
- package/dist/application/scheduled-prompt-manager.d.ts +69 -0
- package/dist/application/scheduled-prompt-manager.d.ts.map +1 -0
- package/dist/application/scheduled-prompt-manager.js +387 -0
- package/dist/application/scheduled-prompt-manager.js.map +1 -0
- package/dist/application/session-service.d.ts +142 -0
- package/dist/application/session-service.d.ts.map +1 -0
- package/dist/application/session-service.js +1690 -0
- package/dist/application/session-service.js.map +1 -0
- package/dist/application/session-worktree.d.ts +55 -0
- package/dist/application/session-worktree.d.ts.map +1 -0
- package/dist/application/session-worktree.js +311 -0
- package/dist/application/session-worktree.js.map +1 -0
- package/dist/application/subagent-service.d.ts +98 -0
- package/dist/application/subagent-service.d.ts.map +1 -0
- package/dist/application/subagent-service.js +1305 -0
- package/dist/application/subagent-service.js.map +1 -0
- package/dist/application/tool-use-summary.d.ts +8 -0
- package/dist/application/tool-use-summary.d.ts.map +1 -0
- package/dist/application/tool-use-summary.js +53 -0
- package/dist/application/tool-use-summary.js.map +1 -0
- package/dist/application/top-level-agent-manager.d.ts +58 -0
- package/dist/application/top-level-agent-manager.d.ts.map +1 -0
- package/dist/application/top-level-agent-manager.js +907 -0
- package/dist/application/top-level-agent-manager.js.map +1 -0
- package/dist/application/workflow-manager.d.ts +61 -0
- package/dist/application/workflow-manager.d.ts.map +1 -0
- package/dist/application/workflow-manager.js +582 -0
- package/dist/application/workflow-manager.js.map +1 -0
- package/dist/application/workflow-meta.d.ts +18 -0
- package/dist/application/workflow-meta.d.ts.map +1 -0
- package/dist/application/workflow-meta.js +146 -0
- package/dist/application/workflow-meta.js.map +1 -0
- package/dist/application/workflow-runtime.d.ts +29 -0
- package/dist/application/workflow-runtime.d.ts.map +1 -0
- package/dist/application/workflow-runtime.js +176 -0
- package/dist/application/workflow-runtime.js.map +1 -0
- package/dist/application/workflow-worktree.d.ts +9 -0
- package/dist/application/workflow-worktree.d.ts.map +1 -0
- package/dist/application/workflow-worktree.js +11 -0
- package/dist/application/workflow-worktree.js.map +1 -0
- package/dist/cli/agents-dashboard.d.ts +37 -0
- package/dist/cli/agents-dashboard.d.ts.map +1 -0
- package/dist/cli/agents-dashboard.js +408 -0
- package/dist/cli/agents-dashboard.js.map +1 -0
- package/dist/cli/controls.d.ts +15 -0
- package/dist/cli/controls.d.ts.map +1 -0
- package/dist/cli/controls.js +219 -0
- package/dist/cli/controls.js.map +1 -0
- package/dist/cli/debug.d.ts +13 -0
- package/dist/cli/debug.d.ts.map +1 -0
- package/dist/cli/debug.js +37 -0
- package/dist/cli/debug.js.map +1 -0
- package/dist/cli/interactive.d.ts +63 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +600 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/protocol.d.ts +251 -0
- package/dist/cli/protocol.d.ts.map +1 -0
- package/dist/cli/protocol.js +2146 -0
- package/dist/cli/protocol.js.map +1 -0
- package/dist/cli.d.ts +116 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3901 -0
- package/dist/cli.js.map +1 -0
- package/dist/compatibility/claude/compaction.d.ts +19 -0
- package/dist/compatibility/claude/compaction.d.ts.map +1 -0
- package/dist/compatibility/claude/compaction.js +82 -0
- package/dist/compatibility/claude/compaction.js.map +1 -0
- package/dist/compatibility/claude/context.d.ts +24 -0
- package/dist/compatibility/claude/context.d.ts.map +1 -0
- package/dist/compatibility/claude/context.js +92 -0
- package/dist/compatibility/claude/context.js.map +1 -0
- package/dist/compatibility/claude/dynamic-context.d.ts +20 -0
- package/dist/compatibility/claude/dynamic-context.d.ts.map +1 -0
- package/dist/compatibility/claude/dynamic-context.js +168 -0
- package/dist/compatibility/claude/dynamic-context.js.map +1 -0
- package/dist/compatibility/claude/file-history.d.ts +14 -0
- package/dist/compatibility/claude/file-history.d.ts.map +1 -0
- package/dist/compatibility/claude/file-history.js +340 -0
- package/dist/compatibility/claude/file-history.js.map +1 -0
- package/dist/compatibility/claude/file-resources.d.ts +28 -0
- package/dist/compatibility/claude/file-resources.d.ts.map +1 -0
- package/dist/compatibility/claude/file-resources.js +168 -0
- package/dist/compatibility/claude/file-resources.js.map +1 -0
- package/dist/compatibility/claude/fork.d.ts +9 -0
- package/dist/compatibility/claude/fork.d.ts.map +1 -0
- package/dist/compatibility/claude/fork.js +225 -0
- package/dist/compatibility/claude/fork.js.map +1 -0
- package/dist/compatibility/claude/history.d.ts +4 -0
- package/dist/compatibility/claude/history.d.ts.map +1 -0
- package/dist/compatibility/claude/history.js +86 -0
- package/dist/compatibility/claude/history.js.map +1 -0
- package/dist/compatibility/claude/ownership.d.ts +87 -0
- package/dist/compatibility/claude/ownership.d.ts.map +1 -0
- package/dist/compatibility/claude/ownership.js +100 -0
- package/dist/compatibility/claude/ownership.js.map +1 -0
- package/dist/compatibility/claude/paths.d.ts +17 -0
- package/dist/compatibility/claude/paths.d.ts.map +1 -0
- package/dist/compatibility/claude/paths.js +54 -0
- package/dist/compatibility/claude/paths.js.map +1 -0
- package/dist/compatibility/claude/pr-links.d.ts +25 -0
- package/dist/compatibility/claude/pr-links.d.ts.map +1 -0
- package/dist/compatibility/claude/pr-links.js +80 -0
- package/dist/compatibility/claude/pr-links.js.map +1 -0
- package/dist/compatibility/claude/projection.d.ts +11 -0
- package/dist/compatibility/claude/projection.d.ts.map +1 -0
- package/dist/compatibility/claude/projection.js +325 -0
- package/dist/compatibility/claude/projection.js.map +1 -0
- package/dist/compatibility/claude/schema.d.ts +18 -0
- package/dist/compatibility/claude/schema.d.ts.map +1 -0
- package/dist/compatibility/claude/schema.js +983 -0
- package/dist/compatibility/claude/schema.js.map +1 -0
- package/dist/compatibility/claude/shared-resources.d.ts +51 -0
- package/dist/compatibility/claude/shared-resources.d.ts.map +1 -0
- package/dist/compatibility/claude/shared-resources.js +382 -0
- package/dist/compatibility/claude/shared-resources.js.map +1 -0
- package/dist/compatibility/claude/sidechain.d.ts +50 -0
- package/dist/compatibility/claude/sidechain.d.ts.map +1 -0
- package/dist/compatibility/claude/sidechain.js +90 -0
- package/dist/compatibility/claude/sidechain.js.map +1 -0
- package/dist/compatibility/claude/tool-links.d.ts +13 -0
- package/dist/compatibility/claude/tool-links.d.ts.map +1 -0
- package/dist/compatibility/claude/tool-links.js +61 -0
- package/dist/compatibility/claude/tool-links.js.map +1 -0
- package/dist/compatibility/claude/translation.d.ts +71 -0
- package/dist/compatibility/claude/translation.d.ts.map +1 -0
- package/dist/compatibility/claude/translation.js +443 -0
- package/dist/compatibility/claude/translation.js.map +1 -0
- package/dist/compatibility/claude/workflow-replay.d.ts +10 -0
- package/dist/compatibility/claude/workflow-replay.d.ts.map +1 -0
- package/dist/compatibility/claude/workflow-replay.js +66 -0
- package/dist/compatibility/claude/workflow-replay.js.map +1 -0
- package/dist/compatibility/claude/workflow.d.ts +33 -0
- package/dist/compatibility/claude/workflow.d.ts.map +1 -0
- package/dist/compatibility/claude/workflow.js +76 -0
- package/dist/compatibility/claude/workflow.js.map +1 -0
- package/dist/core/compaction.d.ts +16 -0
- package/dist/core/compaction.d.ts.map +1 -0
- package/dist/core/compaction.js +2 -0
- package/dist/core/compaction.js.map +1 -0
- package/dist/core/context-budget.d.ts +28 -0
- package/dist/core/context-budget.d.ts.map +1 -0
- package/dist/core/context-budget.js +108 -0
- package/dist/core/context-budget.js.map +1 -0
- package/dist/core/context.d.ts +16 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +13 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/runtime.d.ts +394 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +507 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/core/usage.d.ts +26 -0
- package/dist/core/usage.d.ts.map +1 -0
- package/dist/core/usage.js +133 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/extensions/claude-extension-tools.d.ts +16 -0
- package/dist/extensions/claude-extension-tools.d.ts.map +1 -0
- package/dist/extensions/claude-extension-tools.js +78 -0
- package/dist/extensions/claude-extension-tools.js.map +1 -0
- package/dist/extensions/claude-extensions.d.ts +41 -0
- package/dist/extensions/claude-extensions.d.ts.map +1 -0
- package/dist/extensions/claude-extensions.js +270 -0
- package/dist/extensions/claude-extensions.js.map +1 -0
- package/dist/hooks/claude-hook-tools.d.ts +26 -0
- package/dist/hooks/claude-hook-tools.d.ts.map +1 -0
- package/dist/hooks/claude-hook-tools.js +129 -0
- package/dist/hooks/claude-hook-tools.js.map +1 -0
- package/dist/hooks/claude-hooks.d.ts +87 -0
- package/dist/hooks/claude-hooks.d.ts.map +1 -0
- package/dist/hooks/claude-hooks.js +411 -0
- package/dist/hooks/claude-hooks.js.map +1 -0
- package/dist/maintenance/doctor.d.ts +33 -0
- package/dist/maintenance/doctor.d.ts.map +1 -0
- package/dist/maintenance/doctor.js +391 -0
- package/dist/maintenance/doctor.js.map +1 -0
- package/dist/maintenance/self-update.d.ts +31 -0
- package/dist/maintenance/self-update.d.ts.map +1 -0
- package/dist/maintenance/self-update.js +81 -0
- package/dist/maintenance/self-update.js.map +1 -0
- package/dist/mcp/claude-mcp-management.d.ts +28 -0
- package/dist/mcp/claude-mcp-management.d.ts.map +1 -0
- package/dist/mcp/claude-mcp-management.js +169 -0
- package/dist/mcp/claude-mcp-management.js.map +1 -0
- package/dist/mcp/claude-mcp-oauth.d.ts +113 -0
- package/dist/mcp/claude-mcp-oauth.d.ts.map +1 -0
- package/dist/mcp/claude-mcp-oauth.js +1053 -0
- package/dist/mcp/claude-mcp-oauth.js.map +1 -0
- package/dist/mcp/claude-mcp-tools.d.ts +98 -0
- package/dist/mcp/claude-mcp-tools.d.ts.map +1 -0
- package/dist/mcp/claude-mcp-tools.js +1246 -0
- package/dist/mcp/claude-mcp-tools.js.map +1 -0
- package/dist/mcp/praxis-mcp-server.d.ts +35 -0
- package/dist/mcp/praxis-mcp-server.d.ts.map +1 -0
- package/dist/mcp/praxis-mcp-server.js +520 -0
- package/dist/mcp/praxis-mcp-server.js.map +1 -0
- package/dist/permissions/claude-auto-classifier.d.ts +20 -0
- package/dist/permissions/claude-auto-classifier.d.ts.map +1 -0
- package/dist/permissions/claude-auto-classifier.js +140 -0
- package/dist/permissions/claude-auto-classifier.js.map +1 -0
- package/dist/permissions/claude-permission-resolver.d.ts +30 -0
- package/dist/permissions/claude-permission-resolver.d.ts.map +1 -0
- package/dist/permissions/claude-permission-resolver.js +334 -0
- package/dist/permissions/claude-permission-resolver.js.map +1 -0
- package/dist/persistence/claude-job-store.d.ts +68 -0
- package/dist/persistence/claude-job-store.d.ts.map +1 -0
- package/dist/persistence/claude-job-store.js +311 -0
- package/dist/persistence/claude-job-store.js.map +1 -0
- package/dist/persistence/claude-scheduled-task-store.d.ts +29 -0
- package/dist/persistence/claude-scheduled-task-store.d.ts.map +1 -0
- package/dist/persistence/claude-scheduled-task-store.js +163 -0
- package/dist/persistence/claude-scheduled-task-store.js.map +1 -0
- package/dist/persistence/claude-sidechain-store.d.ts +18 -0
- package/dist/persistence/claude-sidechain-store.d.ts.map +1 -0
- package/dist/persistence/claude-sidechain-store.js +107 -0
- package/dist/persistence/claude-sidechain-store.js.map +1 -0
- package/dist/persistence/claude-task-store.d.ts +72 -0
- package/dist/persistence/claude-task-store.d.ts.map +1 -0
- package/dist/persistence/claude-task-store.js +440 -0
- package/dist/persistence/claude-task-store.js.map +1 -0
- package/dist/persistence/claude-transcript-store.d.ts +85 -0
- package/dist/persistence/claude-transcript-store.d.ts.map +1 -0
- package/dist/persistence/claude-transcript-store.js +385 -0
- package/dist/persistence/claude-transcript-store.js.map +1 -0
- package/dist/persistence/claude-workflow-store.d.ts +41 -0
- package/dist/persistence/claude-workflow-store.d.ts.map +1 -0
- package/dist/persistence/claude-workflow-store.js +263 -0
- package/dist/persistence/claude-workflow-store.js.map +1 -0
- package/dist/persistence/in-memory-sidechain-store.d.ts +12 -0
- package/dist/persistence/in-memory-sidechain-store.d.ts.map +1 -0
- package/dist/persistence/in-memory-sidechain-store.js +30 -0
- package/dist/persistence/in-memory-sidechain-store.js.map +1 -0
- package/dist/persistence/in-memory-transcript-store.d.ts +15 -0
- package/dist/persistence/in-memory-transcript-store.d.ts.map +1 -0
- package/dist/persistence/in-memory-transcript-store.js +95 -0
- package/dist/persistence/in-memory-transcript-store.js.map +1 -0
- package/dist/platform/atomic-write.d.ts +5 -0
- package/dist/platform/atomic-write.d.ts.map +1 -0
- package/dist/platform/atomic-write.js +25 -0
- package/dist/platform/atomic-write.js.map +1 -0
- package/dist/platform/bounded-process-runner.d.ts +28 -0
- package/dist/platform/bounded-process-runner.d.ts.map +1 -0
- package/dist/platform/bounded-process-runner.js +209 -0
- package/dist/platform/bounded-process-runner.js.map +1 -0
- package/dist/platform/claude-version.d.ts +5 -0
- package/dist/platform/claude-version.d.ts.map +1 -0
- package/dist/platform/claude-version.js +17 -0
- package/dist/platform/claude-version.js.map +1 -0
- package/dist/platform/command-shell.d.ts +3 -0
- package/dist/platform/command-shell.d.ts.map +1 -0
- package/dist/platform/command-shell.js +15 -0
- package/dist/platform/command-shell.js.map +1 -0
- package/dist/platform/exclusive-file-lease.d.ts +15 -0
- package/dist/platform/exclusive-file-lease.d.ts.map +1 -0
- package/dist/platform/exclusive-file-lease.js +265 -0
- package/dist/platform/exclusive-file-lease.js.map +1 -0
- package/dist/platform/sensitive-data.d.ts +8 -0
- package/dist/platform/sensitive-data.d.ts.map +1 -0
- package/dist/platform/sensitive-data.js +138 -0
- package/dist/platform/sensitive-data.js.map +1 -0
- package/dist/platform/tmux-worktree.d.ts +30 -0
- package/dist/platform/tmux-worktree.d.ts.map +1 -0
- package/dist/platform/tmux-worktree.js +138 -0
- package/dist/platform/tmux-worktree.js.map +1 -0
- package/dist/plugins/claude-plugin-eval-discovery.d.ts +20 -0
- package/dist/plugins/claude-plugin-eval-discovery.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-eval-discovery.js +128 -0
- package/dist/plugins/claude-plugin-eval-discovery.js.map +1 -0
- package/dist/plugins/claude-plugin-eval-graders.d.ts +49 -0
- package/dist/plugins/claude-plugin-eval-graders.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-eval-graders.js +137 -0
- package/dist/plugins/claude-plugin-eval-graders.js.map +1 -0
- package/dist/plugins/claude-plugin-eval-runner.d.ts +50 -0
- package/dist/plugins/claude-plugin-eval-runner.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-eval-runner.js +189 -0
- package/dist/plugins/claude-plugin-eval-runner.js.map +1 -0
- package/dist/plugins/claude-plugin-eval-schema.d.ts +80 -0
- package/dist/plugins/claude-plugin-eval-schema.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-eval-schema.js +436 -0
- package/dist/plugins/claude-plugin-eval-schema.js.map +1 -0
- package/dist/plugins/claude-plugin-eval.d.ts +66 -0
- package/dist/plugins/claude-plugin-eval.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-eval.js +438 -0
- package/dist/plugins/claude-plugin-eval.js.map +1 -0
- package/dist/plugins/claude-plugin-maintenance.d.ts +39 -0
- package/dist/plugins/claude-plugin-maintenance.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-maintenance.js +336 -0
- package/dist/plugins/claude-plugin-maintenance.js.map +1 -0
- package/dist/plugins/claude-plugin-marketplace.d.ts +97 -0
- package/dist/plugins/claude-plugin-marketplace.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-marketplace.js +1433 -0
- package/dist/plugins/claude-plugin-marketplace.js.map +1 -0
- package/dist/plugins/claude-plugin-mcpb.d.ts +71 -0
- package/dist/plugins/claude-plugin-mcpb.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-mcpb.js +885 -0
- package/dist/plugins/claude-plugin-mcpb.js.map +1 -0
- package/dist/plugins/claude-plugin-runtime.d.ts +120 -0
- package/dist/plugins/claude-plugin-runtime.d.ts.map +1 -0
- package/dist/plugins/claude-plugin-runtime.js +1263 -0
- package/dist/plugins/claude-plugin-runtime.js.map +1 -0
- package/dist/providers/anthropic-compatible.d.ts +35 -0
- package/dist/providers/anthropic-compatible.d.ts.map +1 -0
- package/dist/providers/anthropic-compatible.js +733 -0
- package/dist/providers/anthropic-compatible.js.map +1 -0
- package/dist/providers/environment.d.ts +14 -0
- package/dist/providers/environment.d.ts.map +1 -0
- package/dist/providers/environment.js +67 -0
- package/dist/providers/environment.js.map +1 -0
- package/dist/providers/fallback-provider.d.ts +17 -0
- package/dist/providers/fallback-provider.d.ts.map +1 -0
- package/dist/providers/fallback-provider.js +70 -0
- package/dist/providers/fallback-provider.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +30 -0
- package/dist/providers/openai-compatible.d.ts.map +1 -0
- package/dist/providers/openai-compatible.js +409 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/tools/claude-interactive-tools.d.ts +58 -0
- package/dist/tools/claude-interactive-tools.d.ts.map +1 -0
- package/dist/tools/claude-interactive-tools.js +390 -0
- package/dist/tools/claude-interactive-tools.js.map +1 -0
- package/dist/tools/claude-lsp-formatters.d.ts +2 -0
- package/dist/tools/claude-lsp-formatters.d.ts.map +1 -0
- package/dist/tools/claude-lsp-formatters.js +291 -0
- package/dist/tools/claude-lsp-formatters.js.map +1 -0
- package/dist/tools/claude-lsp-tool.d.ts +22 -0
- package/dist/tools/claude-lsp-tool.d.ts.map +1 -0
- package/dist/tools/claude-lsp-tool.js +744 -0
- package/dist/tools/claude-lsp-tool.js.map +1 -0
- package/dist/tools/claude-scheduled-tools.d.ts +20 -0
- package/dist/tools/claude-scheduled-tools.d.ts.map +1 -0
- package/dist/tools/claude-scheduled-tools.js +344 -0
- package/dist/tools/claude-scheduled-tools.js.map +1 -0
- package/dist/tools/claude-task-tools.d.ts +30 -0
- package/dist/tools/claude-task-tools.d.ts.map +1 -0
- package/dist/tools/claude-task-tools.js +503 -0
- package/dist/tools/claude-task-tools.js.map +1 -0
- package/dist/tools/claude-user-message.d.ts +16 -0
- package/dist/tools/claude-user-message.d.ts.map +1 -0
- package/dist/tools/claude-user-message.js +98 -0
- package/dist/tools/claude-user-message.js.map +1 -0
- package/dist/tools/claude-workflow-tools.d.ts +27 -0
- package/dist/tools/claude-workflow-tools.d.ts.map +1 -0
- package/dist/tools/claude-workflow-tools.js +257 -0
- package/dist/tools/claude-workflow-tools.js.map +1 -0
- package/dist/tools/claude-worktree-tools.d.ts +17 -0
- package/dist/tools/claude-worktree-tools.d.ts.map +1 -0
- package/dist/tools/claude-worktree-tools.js +135 -0
- package/dist/tools/claude-worktree-tools.js.map +1 -0
- package/dist/tools/filtered-tool-registry.d.ts +16 -0
- package/dist/tools/filtered-tool-registry.d.ts.map +1 -0
- package/dist/tools/filtered-tool-registry.js +51 -0
- package/dist/tools/filtered-tool-registry.js.map +1 -0
- package/dist/tools/glob.d.ts +9 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +88 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/local-tools.d.ts +47 -0
- package/dist/tools/local-tools.d.ts.map +1 -0
- package/dist/tools/local-tools.js +1082 -0
- package/dist/tools/local-tools.js.map +1 -0
- package/dist/tools/notebook.d.ts +22 -0
- package/dist/tools/notebook.d.ts.map +1 -0
- package/dist/tools/notebook.js +154 -0
- package/dist/tools/notebook.js.map +1 -0
- package/dist/tools/web.d.ts +48 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +726 -0
- package/dist/tools/web.js.map +1 -0
- package/package.json +145 -0
|
@@ -0,0 +1,983 @@
|
|
|
1
|
+
const SUPPORTED_VERSION = '2.1.208';
|
|
2
|
+
const APPENDABLE_ENTRY_TYPES = new Set([
|
|
3
|
+
'agent-name',
|
|
4
|
+
'agent-setting',
|
|
5
|
+
'assistant',
|
|
6
|
+
'attachment',
|
|
7
|
+
'custom-title',
|
|
8
|
+
'file-history-delta',
|
|
9
|
+
'file-history-snapshot',
|
|
10
|
+
'last-prompt',
|
|
11
|
+
'permission-mode',
|
|
12
|
+
'pr-link',
|
|
13
|
+
'system',
|
|
14
|
+
'user',
|
|
15
|
+
'worktree-state',
|
|
16
|
+
]);
|
|
17
|
+
const FORKABLE_ENTRY_TYPES = new Set([
|
|
18
|
+
'agent-name',
|
|
19
|
+
'agent-setting',
|
|
20
|
+
'ai-title',
|
|
21
|
+
'assistant',
|
|
22
|
+
'attachment',
|
|
23
|
+
'custom-title',
|
|
24
|
+
'last-prompt',
|
|
25
|
+
'mode',
|
|
26
|
+
'permission-mode',
|
|
27
|
+
'pr-link',
|
|
28
|
+
'system',
|
|
29
|
+
'user',
|
|
30
|
+
]);
|
|
31
|
+
export function isClaudeForkableEntryType(type) {
|
|
32
|
+
return FORKABLE_ENTRY_TYPES.has(type);
|
|
33
|
+
}
|
|
34
|
+
const FORKABLE_SYSTEM_SUBTYPES = new Set([
|
|
35
|
+
'api_error',
|
|
36
|
+
'away_summary',
|
|
37
|
+
'compact_boundary',
|
|
38
|
+
'local_command',
|
|
39
|
+
'stop_hook_summary',
|
|
40
|
+
'turn_duration',
|
|
41
|
+
]);
|
|
42
|
+
const FORKABLE_ATTACHMENT_TYPES = new Set([
|
|
43
|
+
'agent_listing_delta',
|
|
44
|
+
'command_permissions',
|
|
45
|
+
'date_change',
|
|
46
|
+
'directory',
|
|
47
|
+
'edited_text_file',
|
|
48
|
+
'file',
|
|
49
|
+
'goal_status',
|
|
50
|
+
'hook_additional_context',
|
|
51
|
+
'hook_blocking_error',
|
|
52
|
+
'hook_error',
|
|
53
|
+
'hook_success',
|
|
54
|
+
'mcp_instructions_delta',
|
|
55
|
+
'nested_memory',
|
|
56
|
+
'plan_mode_exit',
|
|
57
|
+
'queued_command',
|
|
58
|
+
'read_truncation_notice',
|
|
59
|
+
'skill_listing',
|
|
60
|
+
'task_reminder',
|
|
61
|
+
]);
|
|
62
|
+
const RAW_CLAUDE_ENTRY = Symbol('raw-claude-entry');
|
|
63
|
+
function parseEntry(line) {
|
|
64
|
+
let value;
|
|
65
|
+
try {
|
|
66
|
+
value = JSON.parse(line);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error('Invalid Claude transcript JSON', { cause: error });
|
|
70
|
+
}
|
|
71
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
72
|
+
throw new Error('Claude transcript entry must be an object');
|
|
73
|
+
}
|
|
74
|
+
const entry = value;
|
|
75
|
+
if (typeof entry.type !== 'string' || entry.type.length === 0) {
|
|
76
|
+
throw new Error('Claude transcript entry must have a type');
|
|
77
|
+
}
|
|
78
|
+
Object.defineProperty(entry, RAW_CLAUDE_ENTRY, { value: line });
|
|
79
|
+
return entry;
|
|
80
|
+
}
|
|
81
|
+
function serializeEntry(entry) {
|
|
82
|
+
return entry[RAW_CLAUDE_ENTRY] ?? JSON.stringify(entry);
|
|
83
|
+
}
|
|
84
|
+
function skipWhitespace(source, start) {
|
|
85
|
+
let index = start;
|
|
86
|
+
while (/\s/u.test(source[index] ?? ''))
|
|
87
|
+
index += 1;
|
|
88
|
+
return index;
|
|
89
|
+
}
|
|
90
|
+
function findStringEnd(source, start) {
|
|
91
|
+
if (source[start] !== '"')
|
|
92
|
+
throw new Error('Expected JSON string');
|
|
93
|
+
let escaped = false;
|
|
94
|
+
for (let index = start + 1; index < source.length; index += 1) {
|
|
95
|
+
const character = source[index];
|
|
96
|
+
if (escaped) {
|
|
97
|
+
escaped = false;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (character === '\\') {
|
|
101
|
+
escaped = true;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (character === '"')
|
|
105
|
+
return index + 1;
|
|
106
|
+
}
|
|
107
|
+
throw new Error('Unterminated JSON string');
|
|
108
|
+
}
|
|
109
|
+
function findValueEnd(source, start) {
|
|
110
|
+
if (source[start] === '"')
|
|
111
|
+
return findStringEnd(source, start);
|
|
112
|
+
if (source[start] !== '{' && source[start] !== '[') {
|
|
113
|
+
let index = start;
|
|
114
|
+
while (index < source.length &&
|
|
115
|
+
source[index] !== ',' &&
|
|
116
|
+
source[index] !== '}') {
|
|
117
|
+
index += 1;
|
|
118
|
+
}
|
|
119
|
+
return index;
|
|
120
|
+
}
|
|
121
|
+
const stack = [source[start]];
|
|
122
|
+
for (let index = start + 1; index < source.length; index += 1) {
|
|
123
|
+
const character = source[index];
|
|
124
|
+
if (character === '"') {
|
|
125
|
+
index = findStringEnd(source, index) - 1;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (character === '{' || character === '[')
|
|
129
|
+
stack.push(character);
|
|
130
|
+
else if (character === '}' || character === ']') {
|
|
131
|
+
const opener = stack.pop();
|
|
132
|
+
if ((opener === '{' && character !== '}') ||
|
|
133
|
+
(opener === '[' && character !== ']')) {
|
|
134
|
+
throw new Error('Mismatched JSON container');
|
|
135
|
+
}
|
|
136
|
+
if (stack.length === 0)
|
|
137
|
+
return index + 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw new Error('Unterminated JSON value');
|
|
141
|
+
}
|
|
142
|
+
function replaceRootStringProperty(source, property, value) {
|
|
143
|
+
let index = skipWhitespace(source, 0);
|
|
144
|
+
if (source[index] !== '{')
|
|
145
|
+
throw new Error('Claude entry must be an object');
|
|
146
|
+
index += 1;
|
|
147
|
+
let match;
|
|
148
|
+
while (true) {
|
|
149
|
+
index = skipWhitespace(source, index);
|
|
150
|
+
if (source[index] === '}')
|
|
151
|
+
break;
|
|
152
|
+
const keyStart = index;
|
|
153
|
+
const keyEnd = findStringEnd(source, keyStart);
|
|
154
|
+
const key = JSON.parse(source.slice(keyStart, keyEnd));
|
|
155
|
+
index = skipWhitespace(source, keyEnd);
|
|
156
|
+
if (source[index] !== ':')
|
|
157
|
+
throw new Error('Invalid Claude entry property');
|
|
158
|
+
index = skipWhitespace(source, index + 1);
|
|
159
|
+
const valueStart = index;
|
|
160
|
+
const valueEnd = findValueEnd(source, valueStart);
|
|
161
|
+
if (key === property) {
|
|
162
|
+
if (match)
|
|
163
|
+
throw new Error(`Claude entry has duplicate ${property}`);
|
|
164
|
+
if (source[valueStart] !== '"') {
|
|
165
|
+
throw new Error(`Claude entry ${property} must be a string`);
|
|
166
|
+
}
|
|
167
|
+
match = { start: valueStart, end: valueEnd };
|
|
168
|
+
}
|
|
169
|
+
index = skipWhitespace(source, valueEnd);
|
|
170
|
+
if (source[index] === '}')
|
|
171
|
+
break;
|
|
172
|
+
if (source[index] !== ',')
|
|
173
|
+
throw new Error('Invalid Claude entry object');
|
|
174
|
+
index += 1;
|
|
175
|
+
}
|
|
176
|
+
if (!match)
|
|
177
|
+
throw new Error(`Claude entry is missing ${property}`);
|
|
178
|
+
return `${source.slice(0, match.start)}${JSON.stringify(value)}${source.slice(match.end)}`;
|
|
179
|
+
}
|
|
180
|
+
export function copyClaudeEntryWithSessionId(entry, sessionId) {
|
|
181
|
+
const copy = { ...entry, sessionId };
|
|
182
|
+
const raw = entry[RAW_CLAUDE_ENTRY];
|
|
183
|
+
if (raw !== undefined) {
|
|
184
|
+
Object.defineProperty(copy, RAW_CLAUDE_ENTRY, { value: raw });
|
|
185
|
+
}
|
|
186
|
+
return copy;
|
|
187
|
+
}
|
|
188
|
+
function serializeForkEntry(entry) {
|
|
189
|
+
const raw = entry[RAW_CLAUDE_ENTRY];
|
|
190
|
+
return raw === undefined
|
|
191
|
+
? JSON.stringify(entry)
|
|
192
|
+
: replaceRootStringProperty(raw, 'sessionId', String(entry.sessionId));
|
|
193
|
+
}
|
|
194
|
+
function isRecord(value) {
|
|
195
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
196
|
+
}
|
|
197
|
+
function isNonEmptyString(value) {
|
|
198
|
+
return typeof value === 'string' && value.length > 0;
|
|
199
|
+
}
|
|
200
|
+
function validateMediaSource(value) {
|
|
201
|
+
if (!isRecord(value) ||
|
|
202
|
+
value.type !== 'base64' ||
|
|
203
|
+
!isNonEmptyString(value.media_type) ||
|
|
204
|
+
typeof value.data !== 'string') {
|
|
205
|
+
throw new Error('Claude transcript has invalid media source');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function validateForkUserContent(content) {
|
|
209
|
+
if (typeof content === 'string')
|
|
210
|
+
return;
|
|
211
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
212
|
+
throw new Error('Claude transcript user message has invalid content');
|
|
213
|
+
}
|
|
214
|
+
for (const block of content) {
|
|
215
|
+
if (!isRecord(block)) {
|
|
216
|
+
throw new Error('Claude transcript has invalid user content block');
|
|
217
|
+
}
|
|
218
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
219
|
+
continue;
|
|
220
|
+
if (block.type === 'image' || block.type === 'document') {
|
|
221
|
+
validateMediaSource(block.source);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (block.type !== 'tool_result' ||
|
|
225
|
+
!isNonEmptyString(block.tool_use_id) ||
|
|
226
|
+
(block.is_error !== undefined && typeof block.is_error !== 'boolean')) {
|
|
227
|
+
throw new Error('Claude transcript has invalid user content block');
|
|
228
|
+
}
|
|
229
|
+
if (typeof block.content === 'string')
|
|
230
|
+
continue;
|
|
231
|
+
if (!Array.isArray(block.content) || block.content.length === 0) {
|
|
232
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
233
|
+
}
|
|
234
|
+
for (const nested of block.content) {
|
|
235
|
+
if (!isRecord(nested)) {
|
|
236
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
237
|
+
}
|
|
238
|
+
if (nested.type === 'text' && typeof nested.text === 'string')
|
|
239
|
+
continue;
|
|
240
|
+
if (nested.type === 'image') {
|
|
241
|
+
validateMediaSource(nested.source);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function validateForkAssistantMessage(message) {
|
|
249
|
+
if (message.type !== 'message' ||
|
|
250
|
+
!isNonEmptyString(message.id) ||
|
|
251
|
+
!isNonEmptyString(message.model) ||
|
|
252
|
+
!Array.isArray(message.content) ||
|
|
253
|
+
message.content.length === 0) {
|
|
254
|
+
throw new Error('Claude transcript has invalid assistant message');
|
|
255
|
+
}
|
|
256
|
+
for (const block of message.content) {
|
|
257
|
+
if (!isRecord(block)) {
|
|
258
|
+
throw new Error('Claude transcript has invalid assistant content block');
|
|
259
|
+
}
|
|
260
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
261
|
+
continue;
|
|
262
|
+
if (block.type === 'image' || block.type === 'document') {
|
|
263
|
+
validateMediaSource(block.source);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (block.type === 'thinking' &&
|
|
267
|
+
typeof block.thinking === 'string' &&
|
|
268
|
+
typeof block.signature === 'string') {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (block.type === 'redacted_thinking' && typeof block.data === 'string') {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (block.type === 'tool_use' &&
|
|
275
|
+
isNonEmptyString(block.id) &&
|
|
276
|
+
isNonEmptyString(block.name) &&
|
|
277
|
+
isRecord(block.input)) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
throw new Error('Claude transcript has invalid assistant content block');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function validateUserContent(content) {
|
|
284
|
+
if (typeof content === 'string')
|
|
285
|
+
return;
|
|
286
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
287
|
+
throw new Error('Claude transcript user message has invalid content');
|
|
288
|
+
}
|
|
289
|
+
for (const block of content) {
|
|
290
|
+
if (!isRecord(block)) {
|
|
291
|
+
throw new Error('Claude transcript has invalid user content block');
|
|
292
|
+
}
|
|
293
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
294
|
+
continue;
|
|
295
|
+
if (block.type === 'image' || block.type === 'document') {
|
|
296
|
+
validateMediaSource(block.source);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (block.type !== 'tool_result' ||
|
|
300
|
+
!isNonEmptyString(block.tool_use_id) ||
|
|
301
|
+
(block.is_error !== undefined && typeof block.is_error !== 'boolean')) {
|
|
302
|
+
throw new Error('Claude transcript has invalid user content block');
|
|
303
|
+
}
|
|
304
|
+
if (typeof block.content === 'string')
|
|
305
|
+
continue;
|
|
306
|
+
if (!Array.isArray(block.content) || block.content.length === 0) {
|
|
307
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
308
|
+
}
|
|
309
|
+
for (const nested of block.content) {
|
|
310
|
+
if (!isRecord(nested)) {
|
|
311
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
312
|
+
}
|
|
313
|
+
if (nested.type === 'text' && typeof nested.text === 'string')
|
|
314
|
+
continue;
|
|
315
|
+
if (nested.type === 'image' || nested.type === 'document') {
|
|
316
|
+
validateMediaSource(nested.source);
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
throw new Error('Claude transcript has invalid tool result content');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function validateAssistantMessage(message) {
|
|
324
|
+
if (message.type !== 'message' ||
|
|
325
|
+
!isNonEmptyString(message.id) ||
|
|
326
|
+
!isNonEmptyString(message.model) ||
|
|
327
|
+
!Array.isArray(message.content) ||
|
|
328
|
+
message.content.length === 0) {
|
|
329
|
+
throw new Error('Claude transcript has invalid assistant message');
|
|
330
|
+
}
|
|
331
|
+
for (const block of message.content) {
|
|
332
|
+
if (!isRecord(block)) {
|
|
333
|
+
throw new Error('Claude transcript has invalid assistant content block');
|
|
334
|
+
}
|
|
335
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
336
|
+
continue;
|
|
337
|
+
if (block.type === 'thinking' &&
|
|
338
|
+
typeof block.thinking === 'string' &&
|
|
339
|
+
isNonEmptyString(block.signature)) {
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (block.type === 'redacted_thinking' && isNonEmptyString(block.data)) {
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (block.type === 'tool_use') {
|
|
346
|
+
if (!isNonEmptyString(block.id) ||
|
|
347
|
+
!isNonEmptyString(block.name) ||
|
|
348
|
+
!isRecord(block.input)) {
|
|
349
|
+
throw new Error('Claude transcript has invalid assistant tool_use block');
|
|
350
|
+
}
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
throw new Error('Claude transcript has invalid assistant content block');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const APPENDABLE_IMAGE_MEDIA_TYPES = new Set([
|
|
357
|
+
'image/png',
|
|
358
|
+
'image/jpeg',
|
|
359
|
+
'image/gif',
|
|
360
|
+
'image/webp',
|
|
361
|
+
]);
|
|
362
|
+
const APPENDABLE_DOCUMENT_MEDIA_TYPES = new Set([
|
|
363
|
+
'application/pdf',
|
|
364
|
+
'text/plain',
|
|
365
|
+
'text/markdown',
|
|
366
|
+
'application/json',
|
|
367
|
+
]);
|
|
368
|
+
function decodedBase64Size(data) {
|
|
369
|
+
if (data.length === 0 ||
|
|
370
|
+
data.length % 4 !== 0 ||
|
|
371
|
+
!/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
const decoded = Buffer.from(data, 'base64');
|
|
375
|
+
return decoded.toString('base64') === data ? decoded.length : null;
|
|
376
|
+
}
|
|
377
|
+
function validateMcpToolResultMetadata(entry, message) {
|
|
378
|
+
if (!Array.isArray(entry.toolUseResult)) {
|
|
379
|
+
if (entry.mcpMeta !== undefined) {
|
|
380
|
+
throw new Error('Claude MCP tool result metadata is invalid');
|
|
381
|
+
}
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
if (entry.type !== 'user' ||
|
|
385
|
+
!Array.isArray(message.content) ||
|
|
386
|
+
message.content.length !== 1 ||
|
|
387
|
+
!isRecord(message.content[0]) ||
|
|
388
|
+
message.content[0].type !== 'tool_result' ||
|
|
389
|
+
!Array.isArray(message.content[0].content) ||
|
|
390
|
+
JSON.stringify(message.content[0].content) !==
|
|
391
|
+
JSON.stringify(entry.toolUseResult) ||
|
|
392
|
+
(entry.mcpMeta !== undefined && !isRecord(entry.mcpMeta))) {
|
|
393
|
+
throw new Error('Claude MCP tool result metadata is invalid');
|
|
394
|
+
}
|
|
395
|
+
for (const block of entry.toolUseResult) {
|
|
396
|
+
if (!isRecord(block)) {
|
|
397
|
+
throw new Error('Claude MCP tool result metadata is invalid');
|
|
398
|
+
}
|
|
399
|
+
if (block.type === 'text' && typeof block.text === 'string')
|
|
400
|
+
continue;
|
|
401
|
+
if (block.type === 'image' &&
|
|
402
|
+
isRecord(block.source) &&
|
|
403
|
+
block.source.type === 'base64' &&
|
|
404
|
+
isNonEmptyString(block.source.media_type) &&
|
|
405
|
+
APPENDABLE_IMAGE_MEDIA_TYPES.has(block.source.media_type) &&
|
|
406
|
+
isNonEmptyString(block.source.data) &&
|
|
407
|
+
decodedBase64Size(block.source.data) !== null) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
throw new Error('Claude MCP tool result metadata is invalid');
|
|
411
|
+
}
|
|
412
|
+
if (entry.mcpMeta !== undefined) {
|
|
413
|
+
const lastBlock = entry.toolUseResult.at(-1);
|
|
414
|
+
if (!isRecord(entry.mcpMeta) ||
|
|
415
|
+
!('structuredContent' in entry.mcpMeta) ||
|
|
416
|
+
!isRecord(lastBlock) ||
|
|
417
|
+
lastBlock.type !== 'text' ||
|
|
418
|
+
lastBlock.text !== JSON.stringify(entry.mcpMeta.structuredContent)) {
|
|
419
|
+
throw new Error('Claude MCP tool result metadata is invalid');
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
function validateMediaToolResultMetadata(entry, message) {
|
|
425
|
+
if (validateMcpToolResultMetadata(entry, message))
|
|
426
|
+
return;
|
|
427
|
+
const hasMediaMetadata = isRecord(entry.toolUseResult) &&
|
|
428
|
+
(entry.toolUseResult.type === 'image' ||
|
|
429
|
+
entry.toolUseResult.type === 'document' ||
|
|
430
|
+
entry.toolUseResult.type === 'media');
|
|
431
|
+
if (!Array.isArray(message.content)) {
|
|
432
|
+
if (hasMediaMetadata) {
|
|
433
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
434
|
+
}
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const toolResults = message.content.filter((block) => isRecord(block) && block.type === 'tool_result');
|
|
438
|
+
const media = toolResults.flatMap((toolResult) => Array.isArray(toolResult.content)
|
|
439
|
+
? toolResult.content.filter((block) => isRecord(block) &&
|
|
440
|
+
(block.type === 'image' || block.type === 'document'))
|
|
441
|
+
: []);
|
|
442
|
+
if (media.length === 0 && !hasMediaMetadata)
|
|
443
|
+
return;
|
|
444
|
+
const toolResult = toolResults[0];
|
|
445
|
+
if (entry.type !== 'user' ||
|
|
446
|
+
message.content.length !== 1 ||
|
|
447
|
+
toolResults.length !== 1 ||
|
|
448
|
+
!toolResult ||
|
|
449
|
+
toolResult.is_error !== undefined ||
|
|
450
|
+
!Array.isArray(toolResult.content) ||
|
|
451
|
+
media.length === 0 ||
|
|
452
|
+
!isRecord(entry.toolUseResult)) {
|
|
453
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
454
|
+
}
|
|
455
|
+
for (const block of media) {
|
|
456
|
+
const allowedTypes = block.type === 'image'
|
|
457
|
+
? APPENDABLE_IMAGE_MEDIA_TYPES
|
|
458
|
+
: APPENDABLE_DOCUMENT_MEDIA_TYPES;
|
|
459
|
+
if (!isRecord(block.source) ||
|
|
460
|
+
block.source.type !== 'base64' ||
|
|
461
|
+
!isNonEmptyString(block.source.media_type) ||
|
|
462
|
+
!allowedTypes.has(block.source.media_type) ||
|
|
463
|
+
!isNonEmptyString(block.source.data) ||
|
|
464
|
+
decodedBase64Size(block.source.data) === null) {
|
|
465
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (media.length > 1) {
|
|
469
|
+
if (entry.toolUseResult.type !== 'media' ||
|
|
470
|
+
entry.toolUseResult.count !== media.length) {
|
|
471
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
472
|
+
}
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const block = media[0];
|
|
476
|
+
const file = entry.toolUseResult.file;
|
|
477
|
+
if (!block || !isRecord(block.source) || !isRecord(file)) {
|
|
478
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
479
|
+
}
|
|
480
|
+
const decodedSize = decodedBase64Size(String(block.source.data));
|
|
481
|
+
if (entry.toolUseResult.type !== block.type ||
|
|
482
|
+
file.base64 !== block.source.data ||
|
|
483
|
+
file.type !== block.source.media_type ||
|
|
484
|
+
!Number.isSafeInteger(file.originalSize) ||
|
|
485
|
+
typeof file.originalSize !== 'number' ||
|
|
486
|
+
file.originalSize < 0 ||
|
|
487
|
+
decodedSize === null ||
|
|
488
|
+
file.originalSize !== decodedSize) {
|
|
489
|
+
throw new Error('Claude media tool result metadata is invalid');
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function validateNestedMemoryAttachment(entry) {
|
|
493
|
+
if (entry.isSidechain !== false ||
|
|
494
|
+
entry.userType !== 'external' ||
|
|
495
|
+
entry.entrypoint !== 'cli' ||
|
|
496
|
+
!('gitBranch' in entry) ||
|
|
497
|
+
(entry.gitBranch !== null && typeof entry.gitBranch !== 'string') ||
|
|
498
|
+
!isRecord(entry.attachment)) {
|
|
499
|
+
throw new Error('Claude transcript has invalid nested-memory attachment');
|
|
500
|
+
}
|
|
501
|
+
const attachment = entry.attachment;
|
|
502
|
+
if (attachment.type !== 'nested_memory' ||
|
|
503
|
+
!isNonEmptyString(attachment.path) ||
|
|
504
|
+
!isNonEmptyString(attachment.displayPath) ||
|
|
505
|
+
!isRecord(attachment.content)) {
|
|
506
|
+
throw new Error('Claude transcript has invalid nested-memory attachment');
|
|
507
|
+
}
|
|
508
|
+
const content = attachment.content;
|
|
509
|
+
if (content.path !== attachment.path ||
|
|
510
|
+
(content.type !== 'Project' && content.type !== 'User') ||
|
|
511
|
+
typeof content.content !== 'string' ||
|
|
512
|
+
typeof content.rawContent !== 'string' ||
|
|
513
|
+
typeof content.contentDiffersFromDisk !== 'boolean' ||
|
|
514
|
+
!Array.isArray(content.globs) ||
|
|
515
|
+
content.globs.length === 0 ||
|
|
516
|
+
content.globs.some((glob) => !isNonEmptyString(glob))) {
|
|
517
|
+
throw new Error('Claude transcript has invalid nested-memory attachment');
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function validateHookAttachment(entry, allowNativeEntrypoint = false) {
|
|
521
|
+
const validChain = entry.isSidechain === false ||
|
|
522
|
+
(entry.isSidechain === true && isNonEmptyString(entry.agentId));
|
|
523
|
+
if (!validChain ||
|
|
524
|
+
entry.userType !== 'external' ||
|
|
525
|
+
(entry.entrypoint !== 'cli' &&
|
|
526
|
+
(!allowNativeEntrypoint ||
|
|
527
|
+
(entry.entrypoint !== 'sdk-cli' && entry.entrypoint !== 'sdk-ts'))) ||
|
|
528
|
+
!('gitBranch' in entry) ||
|
|
529
|
+
(entry.gitBranch !== null && typeof entry.gitBranch !== 'string') ||
|
|
530
|
+
!isRecord(entry.attachment)) {
|
|
531
|
+
throw new Error('Claude transcript has invalid hook attachment');
|
|
532
|
+
}
|
|
533
|
+
const attachment = entry.attachment;
|
|
534
|
+
if (!isNonEmptyString(attachment.hookName) ||
|
|
535
|
+
!isNonEmptyString(attachment.toolUseID) ||
|
|
536
|
+
!isNonEmptyString(attachment.hookEvent)) {
|
|
537
|
+
throw new Error('Claude transcript has invalid hook attachment metadata');
|
|
538
|
+
}
|
|
539
|
+
if (attachment.type === 'hook_additional_context') {
|
|
540
|
+
if (!Array.isArray(attachment.content) ||
|
|
541
|
+
attachment.content.length === 0 ||
|
|
542
|
+
attachment.content.some((value) => !isNonEmptyString(value))) {
|
|
543
|
+
throw new Error('Claude transcript has invalid hook context attachment');
|
|
544
|
+
}
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
if ((attachment.type !== 'hook_success' && attachment.type !== 'hook_error') ||
|
|
548
|
+
typeof attachment.content !== 'string' ||
|
|
549
|
+
typeof attachment.stdout !== 'string' ||
|
|
550
|
+
typeof attachment.stderr !== 'string' ||
|
|
551
|
+
!Number.isInteger(attachment.exitCode) ||
|
|
552
|
+
!isNonEmptyString(attachment.command) ||
|
|
553
|
+
typeof attachment.durationMs !== 'number' ||
|
|
554
|
+
attachment.durationMs < 0) {
|
|
555
|
+
throw new Error('Claude transcript has invalid hook success attachment');
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function validateAttachment(entry, allowNativeEntrypoint = false) {
|
|
559
|
+
if (!isRecord(entry.attachment)) {
|
|
560
|
+
throw new Error('Claude transcript has invalid attachment');
|
|
561
|
+
}
|
|
562
|
+
if (entry.attachment.type === 'nested_memory') {
|
|
563
|
+
validateNestedMemoryAttachment(entry);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
if (entry.attachment.type === 'hook_success' ||
|
|
567
|
+
entry.attachment.type === 'hook_error' ||
|
|
568
|
+
entry.attachment.type === 'hook_additional_context') {
|
|
569
|
+
validateHookAttachment(entry, allowNativeEntrypoint);
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
throw new Error('Claude transcript has unsupported attachment type');
|
|
573
|
+
}
|
|
574
|
+
function isNonNegativeNumber(value) {
|
|
575
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
576
|
+
}
|
|
577
|
+
function validateCompactBoundary(entry) {
|
|
578
|
+
const metadata = entry.compactMetadata;
|
|
579
|
+
if (entry.subtype !== 'compact_boundary' ||
|
|
580
|
+
entry.content !== 'Conversation compacted' ||
|
|
581
|
+
entry.parentUuid !== null ||
|
|
582
|
+
entry.isSidechain !== false ||
|
|
583
|
+
entry.isMeta !== false ||
|
|
584
|
+
entry.level !== 'info' ||
|
|
585
|
+
entry.userType !== 'external' ||
|
|
586
|
+
(entry.entrypoint !== 'cli' && entry.entrypoint !== 'sdk-cli') ||
|
|
587
|
+
!('gitBranch' in entry) ||
|
|
588
|
+
(entry.gitBranch !== null && typeof entry.gitBranch !== 'string') ||
|
|
589
|
+
!isNonEmptyString(entry.logicalParentUuid) ||
|
|
590
|
+
!isRecord(metadata)) {
|
|
591
|
+
throw new Error('Claude transcript has invalid compact boundary');
|
|
592
|
+
}
|
|
593
|
+
const segment = metadata.preservedSegment;
|
|
594
|
+
const messages = metadata.preservedMessages;
|
|
595
|
+
if ((metadata.trigger !== 'auto' && metadata.trigger !== 'manual') ||
|
|
596
|
+
!isNonNegativeNumber(metadata.preTokens) ||
|
|
597
|
+
!isNonNegativeNumber(metadata.postTokens) ||
|
|
598
|
+
!isNonNegativeNumber(metadata.durationMs) ||
|
|
599
|
+
!isNonNegativeNumber(metadata.cumulativeDroppedTokens) ||
|
|
600
|
+
!isRecord(segment) ||
|
|
601
|
+
segment.headUuid !== entry.logicalParentUuid ||
|
|
602
|
+
segment.tailUuid !== entry.logicalParentUuid ||
|
|
603
|
+
!isNonEmptyString(segment.anchorUuid) ||
|
|
604
|
+
!isRecord(messages) ||
|
|
605
|
+
messages.anchorUuid !== segment.anchorUuid ||
|
|
606
|
+
!Array.isArray(messages.uuids) ||
|
|
607
|
+
messages.uuids.length === 0 ||
|
|
608
|
+
messages.uuids.some((value) => !isNonEmptyString(value)) ||
|
|
609
|
+
!Array.isArray(messages.allUuids) ||
|
|
610
|
+
messages.allUuids.length === 0 ||
|
|
611
|
+
messages.allUuids.some((value) => !isNonEmptyString(value))) {
|
|
612
|
+
throw new Error('Claude transcript has invalid compact metadata');
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
function validateCompactSummary(entry) {
|
|
616
|
+
if (entry.type !== 'user' ||
|
|
617
|
+
entry.isCompactSummary !== true ||
|
|
618
|
+
entry.isVisibleInTranscriptOnly !== true ||
|
|
619
|
+
entry.isSidechain !== false ||
|
|
620
|
+
entry.userType !== 'external' ||
|
|
621
|
+
(entry.entrypoint !== 'cli' && entry.entrypoint !== 'sdk-cli') ||
|
|
622
|
+
!('gitBranch' in entry) ||
|
|
623
|
+
(entry.gitBranch !== null && typeof entry.gitBranch !== 'string') ||
|
|
624
|
+
!isNonEmptyString(entry.promptId) ||
|
|
625
|
+
!isRecord(entry.message) ||
|
|
626
|
+
entry.message.role !== 'user' ||
|
|
627
|
+
!isNonEmptyString(entry.message.content)) {
|
|
628
|
+
throw new Error('Claude transcript has invalid compact summary');
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
function validateAppendableEntry(entry) {
|
|
632
|
+
if (entry.type === 'file-history-snapshot') {
|
|
633
|
+
if (!isNonEmptyString(entry.messageId) ||
|
|
634
|
+
entry.isSnapshotUpdate !== false ||
|
|
635
|
+
!isRecord(entry.snapshot) ||
|
|
636
|
+
entry.snapshot.messageId !== entry.messageId ||
|
|
637
|
+
!isNonEmptyString(entry.snapshot.timestamp) ||
|
|
638
|
+
!isRecord(entry.snapshot.trackedFileBackups)) {
|
|
639
|
+
throw new Error('Claude file-history snapshot is invalid');
|
|
640
|
+
}
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
if (entry.type === 'file-history-delta') {
|
|
644
|
+
if (!isNonEmptyString(entry.messageId) ||
|
|
645
|
+
!isNonEmptyString(entry.snapshotMessageId) ||
|
|
646
|
+
!isNonEmptyString(entry.trackingPath) ||
|
|
647
|
+
!isRecord(entry.backup) ||
|
|
648
|
+
!isNonEmptyString(entry.timestamp)) {
|
|
649
|
+
throw new Error('Claude file-history delta is invalid');
|
|
650
|
+
}
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
if (entry.type === 'worktree-state') {
|
|
654
|
+
if (!isNonEmptyString(entry.sessionId)) {
|
|
655
|
+
throw new Error('Claude worktree-state entry has invalid sessionId');
|
|
656
|
+
}
|
|
657
|
+
if (entry.worktreeSession === null)
|
|
658
|
+
return;
|
|
659
|
+
if (!isRecord(entry.worktreeSession)) {
|
|
660
|
+
throw new Error('Claude worktree-state entry has invalid state');
|
|
661
|
+
}
|
|
662
|
+
for (const field of [
|
|
663
|
+
'originalCwd',
|
|
664
|
+
'preEnterOriginalCwd',
|
|
665
|
+
'worktreePath',
|
|
666
|
+
'worktreeName',
|
|
667
|
+
'originalHeadCommit',
|
|
668
|
+
'sessionId',
|
|
669
|
+
]) {
|
|
670
|
+
if (!isNonEmptyString(entry.worktreeSession[field])) {
|
|
671
|
+
throw new Error(`Claude worktree-state is missing ${field}`);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
for (const field of ['worktreeBranch', 'originalBranch']) {
|
|
675
|
+
const value = entry.worktreeSession[field];
|
|
676
|
+
if (value !== null && !isNonEmptyString(value)) {
|
|
677
|
+
throw new Error(`Claude worktree-state has invalid ${field}`);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if (entry.type === 'custom-title') {
|
|
683
|
+
if (!isNonEmptyString(entry.customTitle) ||
|
|
684
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
685
|
+
throw new Error('Claude custom-title entry has invalid metadata');
|
|
686
|
+
}
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
if (entry.type === 'agent-name') {
|
|
690
|
+
if (!isNonEmptyString(entry.agentName) ||
|
|
691
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
692
|
+
throw new Error('Claude agent-name entry has invalid metadata');
|
|
693
|
+
}
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
if (entry.type === 'agent-setting') {
|
|
697
|
+
if (!isNonEmptyString(entry.agentSetting) ||
|
|
698
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
699
|
+
throw new Error('Claude agent-setting entry has invalid metadata');
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (entry.type === 'permission-mode') {
|
|
704
|
+
if (!isNonEmptyString(entry.permissionMode) ||
|
|
705
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
706
|
+
throw new Error('Claude permission-mode entry has invalid metadata');
|
|
707
|
+
}
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (entry.type === 'last-prompt') {
|
|
711
|
+
if (!isNonEmptyString(entry.leafUuid)) {
|
|
712
|
+
throw new Error('Claude last-prompt entry has invalid leafUuid');
|
|
713
|
+
}
|
|
714
|
+
if (!isNonEmptyString(entry.sessionId) ||
|
|
715
|
+
!isNonEmptyString(entry.lastPrompt)) {
|
|
716
|
+
throw new Error('Claude last-prompt entry has invalid metadata');
|
|
717
|
+
}
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (entry.type === 'pr-link') {
|
|
721
|
+
if (!isNonEmptyString(entry.sessionId) ||
|
|
722
|
+
typeof entry.prNumber !== 'number' ||
|
|
723
|
+
!Number.isSafeInteger(entry.prNumber) ||
|
|
724
|
+
entry.prNumber < 1 ||
|
|
725
|
+
!isNonEmptyString(entry.prUrl) ||
|
|
726
|
+
!isNonEmptyString(entry.prRepository) ||
|
|
727
|
+
!isNonEmptyString(entry.timestamp)) {
|
|
728
|
+
throw new Error('Claude pr-link entry has invalid metadata');
|
|
729
|
+
}
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
for (const field of ['uuid', 'sessionId', 'timestamp', 'cwd', 'version']) {
|
|
733
|
+
if (typeof entry[field] !== 'string' || entry[field].length === 0) {
|
|
734
|
+
throw new Error(`Claude transcript entry is missing ${field}`);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (entry.version !== SUPPORTED_VERSION) {
|
|
738
|
+
throw new Error(`Claude transcript append must target Claude Code ${SUPPORTED_VERSION}`);
|
|
739
|
+
}
|
|
740
|
+
if (!('parentUuid' in entry) ||
|
|
741
|
+
(entry.parentUuid !== null && !isNonEmptyString(entry.parentUuid))) {
|
|
742
|
+
throw new Error('Claude transcript entry has invalid parentUuid');
|
|
743
|
+
}
|
|
744
|
+
if (entry.type === 'system') {
|
|
745
|
+
validateCompactBoundary(entry);
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (entry.isCompactSummary === true) {
|
|
749
|
+
validateCompactSummary(entry);
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
if (entry.isSidechain === true) {
|
|
753
|
+
throw new Error('Praxis cannot append Claude sidechains yet');
|
|
754
|
+
}
|
|
755
|
+
if (entry.toolDenialKind !== undefined) {
|
|
756
|
+
throw new Error('Praxis cannot append Claude tool denials yet');
|
|
757
|
+
}
|
|
758
|
+
if (entry.type === 'attachment') {
|
|
759
|
+
validateAttachment(entry);
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (!isRecord(entry.message)) {
|
|
763
|
+
throw new Error('Claude transcript entry is missing message');
|
|
764
|
+
}
|
|
765
|
+
const role = entry.message.role;
|
|
766
|
+
if (role !== entry.type) {
|
|
767
|
+
throw new Error('Claude transcript message role does not match entry type');
|
|
768
|
+
}
|
|
769
|
+
validateMediaToolResultMetadata(entry, entry.message);
|
|
770
|
+
if (entry.type === 'user') {
|
|
771
|
+
validateUserContent(entry.message.content);
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
validateAssistantMessage(entry.message);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
function validateSidechainEntry(entry) {
|
|
778
|
+
for (const field of [
|
|
779
|
+
'uuid',
|
|
780
|
+
'sessionId',
|
|
781
|
+
'timestamp',
|
|
782
|
+
'cwd',
|
|
783
|
+
'version',
|
|
784
|
+
'agentId',
|
|
785
|
+
]) {
|
|
786
|
+
if (!isNonEmptyString(entry[field])) {
|
|
787
|
+
throw new Error(`Claude sidechain entry is missing ${field}`);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
if (entry.version !== SUPPORTED_VERSION) {
|
|
791
|
+
throw new Error(`Claude sidechain append must target Claude Code ${SUPPORTED_VERSION}`);
|
|
792
|
+
}
|
|
793
|
+
if (!('parentUuid' in entry) ||
|
|
794
|
+
(entry.parentUuid !== null && !isNonEmptyString(entry.parentUuid))) {
|
|
795
|
+
throw new Error('Claude sidechain entry has invalid parentUuid');
|
|
796
|
+
}
|
|
797
|
+
if (entry.isSidechain !== true ||
|
|
798
|
+
entry.userType !== 'external' ||
|
|
799
|
+
entry.entrypoint !== 'cli' ||
|
|
800
|
+
!('gitBranch' in entry) ||
|
|
801
|
+
(entry.gitBranch !== null && typeof entry.gitBranch !== 'string')) {
|
|
802
|
+
throw new Error('Claude sidechain entry has invalid metadata');
|
|
803
|
+
}
|
|
804
|
+
if (entry.toolDenialKind !== undefined || entry.isCompactSummary === true) {
|
|
805
|
+
throw new Error('Claude sidechain entry has unsupported runtime metadata');
|
|
806
|
+
}
|
|
807
|
+
if (entry.type === 'attachment') {
|
|
808
|
+
validateAttachment(entry);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (entry.type !== 'user' && entry.type !== 'assistant') {
|
|
812
|
+
throw new Error(`Claude sidechain entry type ${entry.type} is unsupported`);
|
|
813
|
+
}
|
|
814
|
+
if (!isRecord(entry.message) || entry.message.role !== entry.type) {
|
|
815
|
+
throw new Error('Claude sidechain entry has invalid message role');
|
|
816
|
+
}
|
|
817
|
+
validateMediaToolResultMetadata(entry, entry.message);
|
|
818
|
+
if (entry.type === 'user') {
|
|
819
|
+
if (!isNonEmptyString(entry.promptId)) {
|
|
820
|
+
throw new Error('Claude sidechain user entry is missing promptId');
|
|
821
|
+
}
|
|
822
|
+
validateUserContent(entry.message.content);
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
if (!isNonEmptyString(entry.attributionAgent)) {
|
|
826
|
+
throw new Error('Claude sidechain assistant is missing attributionAgent');
|
|
827
|
+
}
|
|
828
|
+
validateAssistantMessage(entry.message);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
function validateForkableEntry(entry) {
|
|
832
|
+
if (entry.type === 'custom-title' || entry.type === 'agent-name') {
|
|
833
|
+
validateAppendableEntry(entry);
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
if (entry.type === 'ai-title') {
|
|
837
|
+
if (!isNonEmptyString(entry.aiTitle) ||
|
|
838
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
839
|
+
throw new Error('Claude ai-title entry has invalid metadata');
|
|
840
|
+
}
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
if (entry.type === 'agent-setting') {
|
|
844
|
+
validateAppendableEntry(entry);
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
if (entry.type === 'last-prompt') {
|
|
848
|
+
if (!isNonEmptyString(entry.sessionId) ||
|
|
849
|
+
!isNonEmptyString(entry.leafUuid) ||
|
|
850
|
+
(entry.lastPrompt !== undefined && !isNonEmptyString(entry.lastPrompt))) {
|
|
851
|
+
throw new Error('Claude last-prompt entry has invalid metadata');
|
|
852
|
+
}
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
if (entry.type === 'mode') {
|
|
856
|
+
if (!isNonEmptyString(entry.mode) || !isNonEmptyString(entry.sessionId)) {
|
|
857
|
+
throw new Error('Claude mode entry has invalid metadata');
|
|
858
|
+
}
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (entry.type === 'permission-mode') {
|
|
862
|
+
if (!isNonEmptyString(entry.permissionMode) ||
|
|
863
|
+
!isNonEmptyString(entry.sessionId)) {
|
|
864
|
+
throw new Error('Claude permission-mode entry has invalid metadata');
|
|
865
|
+
}
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
if (entry.type === 'pr-link') {
|
|
869
|
+
validateAppendableEntry(entry);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
for (const field of ['uuid', 'sessionId', 'timestamp', 'cwd', 'version']) {
|
|
873
|
+
if (!isNonEmptyString(entry[field])) {
|
|
874
|
+
throw new Error(`Claude transcript entry is missing ${field}`);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if (entry.version !== SUPPORTED_VERSION) {
|
|
878
|
+
throw new Error(`Claude transcript fork must target Claude Code ${SUPPORTED_VERSION}`);
|
|
879
|
+
}
|
|
880
|
+
if (!('parentUuid' in entry) ||
|
|
881
|
+
(entry.parentUuid !== null && !isNonEmptyString(entry.parentUuid))) {
|
|
882
|
+
throw new Error('Claude transcript entry has invalid parentUuid');
|
|
883
|
+
}
|
|
884
|
+
if (entry.isSidechain !== false) {
|
|
885
|
+
throw new Error('Claude fork entry must belong to the main chain');
|
|
886
|
+
}
|
|
887
|
+
if (entry.type === 'system') {
|
|
888
|
+
if (!FORKABLE_SYSTEM_SUBTYPES.has(String(entry.subtype))) {
|
|
889
|
+
throw new Error('Claude system entry has unsupported subtype');
|
|
890
|
+
}
|
|
891
|
+
if (entry.subtype === 'compact_boundary')
|
|
892
|
+
validateCompactBoundary(entry);
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
if (entry.isCompactSummary === true) {
|
|
896
|
+
validateCompactSummary(entry);
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
if (entry.type === 'attachment') {
|
|
900
|
+
if (!isRecord(entry.attachment) ||
|
|
901
|
+
!FORKABLE_ATTACHMENT_TYPES.has(String(entry.attachment.type))) {
|
|
902
|
+
throw new Error('Claude transcript has unsupported attachment');
|
|
903
|
+
}
|
|
904
|
+
if (entry.attachment.type === 'nested_memory' ||
|
|
905
|
+
entry.attachment.type === 'hook_success' ||
|
|
906
|
+
entry.attachment.type === 'hook_error' ||
|
|
907
|
+
entry.attachment.type === 'hook_additional_context') {
|
|
908
|
+
validateAttachment(entry, true);
|
|
909
|
+
}
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
if (!isRecord(entry.message) || entry.message.role !== entry.type) {
|
|
913
|
+
throw new Error('Claude fork entry has invalid message role');
|
|
914
|
+
}
|
|
915
|
+
if (entry.type === 'user')
|
|
916
|
+
validateForkUserContent(entry.message.content);
|
|
917
|
+
else
|
|
918
|
+
validateForkAssistantMessage(entry.message);
|
|
919
|
+
}
|
|
920
|
+
class ClaudeCode21208Adapter {
|
|
921
|
+
version = SUPPORTED_VERSION;
|
|
922
|
+
writeMode = 'read-write';
|
|
923
|
+
parse(line) {
|
|
924
|
+
return parseEntry(line);
|
|
925
|
+
}
|
|
926
|
+
serialize(entry) {
|
|
927
|
+
return serializeEntry(entry);
|
|
928
|
+
}
|
|
929
|
+
serializeForAppend(entry) {
|
|
930
|
+
if (!APPENDABLE_ENTRY_TYPES.has(entry.type)) {
|
|
931
|
+
throw new Error(`Claude transcript entry type ${entry.type} is not appendable by Praxis`);
|
|
932
|
+
}
|
|
933
|
+
validateAppendableEntry(entry);
|
|
934
|
+
return serializeEntry(entry);
|
|
935
|
+
}
|
|
936
|
+
serializeForSidechainAppend(entry) {
|
|
937
|
+
validateSidechainEntry(entry);
|
|
938
|
+
return serializeEntry(entry);
|
|
939
|
+
}
|
|
940
|
+
serializeForFork(entry) {
|
|
941
|
+
if (!isClaudeForkableEntryType(entry.type)) {
|
|
942
|
+
throw new Error(`Claude transcript entry type ${entry.type} is not forkable by Praxis`);
|
|
943
|
+
}
|
|
944
|
+
validateForkableEntry(entry);
|
|
945
|
+
return serializeForkEntry(entry);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
class ReadOnlyClaudeAdapter {
|
|
949
|
+
version;
|
|
950
|
+
writeMode = 'read-only';
|
|
951
|
+
constructor(version) {
|
|
952
|
+
this.version = version;
|
|
953
|
+
}
|
|
954
|
+
parse(line) {
|
|
955
|
+
return parseEntry(line);
|
|
956
|
+
}
|
|
957
|
+
serialize(entry) {
|
|
958
|
+
return serializeEntry(entry);
|
|
959
|
+
}
|
|
960
|
+
serializeForAppend() {
|
|
961
|
+
throw new Error(`Unsupported Claude Code transcript version ${this.version}; read-only mode`);
|
|
962
|
+
}
|
|
963
|
+
serializeForSidechainAppend() {
|
|
964
|
+
throw new Error(`Unsupported Claude Code transcript version ${this.version}; read-only mode`);
|
|
965
|
+
}
|
|
966
|
+
serializeForFork() {
|
|
967
|
+
throw new Error(`Unsupported Claude Code transcript version ${this.version}; read-only mode`);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
export function selectClaudeSchemaAdapter(version) {
|
|
971
|
+
if (version === SUPPORTED_VERSION) {
|
|
972
|
+
return new ClaudeCode21208Adapter();
|
|
973
|
+
}
|
|
974
|
+
return new ReadOnlyClaudeAdapter(version);
|
|
975
|
+
}
|
|
976
|
+
export function parseClaudeVersionOutput(output) {
|
|
977
|
+
const match = /^(\d+\.\d+\.\d+)\s+\(Claude Code\)\s*$/.exec(output);
|
|
978
|
+
if (!match?.[1]) {
|
|
979
|
+
throw new Error('Unable to detect Claude Code version');
|
|
980
|
+
}
|
|
981
|
+
return match[1];
|
|
982
|
+
}
|
|
983
|
+
//# sourceMappingURL=schema.js.map
|