apex-code 0.0.1-alpha.1 → 0.0.1-alpha.10
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/CHANGELOG.md +471 -0
- package/README.md +74 -680
- package/dist/cli/args.d.ts +21 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +119 -15
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +3 -3
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/concurrent-session.d.ts +3 -0
- package/dist/cli/concurrent-session.d.ts.map +1 -0
- package/dist/cli/concurrent-session.js +13 -0
- package/dist/cli/concurrent-session.js.map +1 -0
- package/dist/cli/cost-command.d.ts +19 -0
- package/dist/cli/cost-command.d.ts.map +1 -0
- package/dist/cli/cost-command.js +107 -0
- package/dist/cli/cost-command.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +99 -16
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -20
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +2 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +28 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +140 -4
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +121 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +364 -123
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -14
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +11 -10
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context/deferred-schemas.d.ts +92 -0
- package/dist/core/context/deferred-schemas.d.ts.map +1 -0
- package/dist/core/context/deferred-schemas.js +74 -0
- package/dist/core/context/deferred-schemas.js.map +1 -0
- package/dist/core/context/eviction.d.ts +47 -0
- package/dist/core/context/eviction.d.ts.map +1 -0
- package/dist/core/context/eviction.js +83 -0
- package/dist/core/context/eviction.js.map +1 -0
- package/dist/core/context/pipeline.d.ts +90 -0
- package/dist/core/context/pipeline.d.ts.map +1 -0
- package/dist/core/context/pipeline.js +109 -0
- package/dist/core/context/pipeline.js.map +1 -0
- package/dist/core/credential-failover.d.ts +30 -0
- package/dist/core/credential-failover.d.ts.map +1 -0
- package/dist/core/credential-failover.js +46 -0
- package/dist/core/credential-failover.js.map +1 -0
- package/dist/core/credential-pool.d.ts +60 -0
- package/dist/core/credential-pool.d.ts.map +1 -0
- package/dist/core/credential-pool.js +84 -0
- package/dist/core/credential-pool.js.map +1 -0
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/delegation/agents.d.ts +15 -0
- package/dist/core/delegation/agents.d.ts.map +1 -0
- package/dist/core/delegation/agents.js +55 -0
- package/dist/core/delegation/agents.js.map +1 -0
- package/dist/core/delegation/ceiling.d.ts +29 -0
- package/dist/core/delegation/ceiling.d.ts.map +1 -0
- package/dist/core/delegation/ceiling.js +34 -0
- package/dist/core/delegation/ceiling.js.map +1 -0
- package/dist/core/delegation/runtime.d.ts +94 -0
- package/dist/core/delegation/runtime.d.ts.map +1 -0
- package/dist/core/delegation/runtime.js +117 -0
- package/dist/core/delegation/runtime.js.map +1 -0
- package/dist/core/durable-state/daemon.d.ts +37 -0
- package/dist/core/durable-state/daemon.d.ts.map +1 -0
- package/dist/core/durable-state/daemon.js +62 -0
- package/dist/core/durable-state/daemon.js.map +1 -0
- package/dist/core/durable-state/provenance.d.ts +7 -0
- package/dist/core/durable-state/provenance.d.ts.map +1 -0
- package/dist/core/durable-state/provenance.js +24 -0
- package/dist/core/durable-state/provenance.js.map +1 -0
- package/dist/core/durable-state/sqlite.d.ts +84 -0
- package/dist/core/durable-state/sqlite.d.ts.map +1 -0
- package/dist/core/durable-state/sqlite.js +355 -0
- package/dist/core/durable-state/sqlite.js.map +1 -0
- package/dist/core/environment.d.ts +12 -0
- package/dist/core/environment.d.ts.map +1 -0
- package/dist/core/environment.js +69 -0
- package/dist/core/environment.js.map +1 -0
- package/dist/core/evidence-policy.d.ts +17 -0
- package/dist/core/evidence-policy.d.ts.map +1 -0
- package/dist/core/evidence-policy.js +25 -0
- package/dist/core/evidence-policy.js.map +1 -0
- package/dist/core/evidence.d.ts +16 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +51 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +6 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +115 -48
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +44 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +1 -2
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -17
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/http-idle-timeout.d.ts +12 -0
- package/dist/core/http-idle-timeout.d.ts.map +1 -0
- package/dist/core/http-idle-timeout.js +27 -0
- package/dist/core/http-idle-timeout.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +38 -13
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lsp/client.d.ts +78 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +494 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/diagnostics.d.ts +47 -0
- package/dist/core/lsp/diagnostics.d.ts.map +1 -0
- package/dist/core/lsp/diagnostics.js +224 -0
- package/dist/core/lsp/diagnostics.js.map +1 -0
- package/dist/core/lsp/pool.d.ts +48 -0
- package/dist/core/lsp/pool.d.ts.map +1 -0
- package/dist/core/lsp/pool.js +150 -0
- package/dist/core/lsp/pool.js.map +1 -0
- package/dist/core/lsp/registry.d.ts +49 -0
- package/dist/core/lsp/registry.d.ts.map +1 -0
- package/dist/core/lsp/registry.js +215 -0
- package/dist/core/lsp/registry.js.map +1 -0
- package/dist/core/lsp/status.d.ts +23 -0
- package/dist/core/lsp/status.d.ts.map +1 -0
- package/dist/core/lsp/status.js +35 -0
- package/dist/core/lsp/status.js.map +1 -0
- package/dist/core/lsp/sync.d.ts +13 -0
- package/dist/core/lsp/sync.d.ts.map +1 -0
- package/dist/core/lsp/sync.js +71 -0
- package/dist/core/lsp/sync.js.map +1 -0
- package/dist/core/model-config.d.ts +18 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +25 -6
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +21 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +73 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +73 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +225 -8
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/observability/aggregate.d.ts +21 -0
- package/dist/core/observability/aggregate.d.ts.map +1 -0
- package/dist/core/observability/aggregate.js +36 -0
- package/dist/core/observability/aggregate.js.map +1 -0
- package/dist/core/observability/otlp.d.ts +66 -0
- package/dist/core/observability/otlp.d.ts.map +1 -0
- package/dist/core/observability/otlp.js +95 -0
- package/dist/core/observability/otlp.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +40 -16
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions/gate.d.ts +42 -0
- package/dist/core/permissions/gate.d.ts.map +1 -0
- package/dist/core/permissions/gate.js +72 -0
- package/dist/core/permissions/gate.js.map +1 -0
- package/dist/core/permissions/modes.d.ts +18 -0
- package/dist/core/permissions/modes.d.ts.map +1 -0
- package/dist/core/permissions/modes.js +57 -0
- package/dist/core/permissions/modes.js.map +1 -0
- package/dist/core/permissions/responder.d.ts +30 -0
- package/dist/core/permissions/responder.d.ts.map +1 -0
- package/dist/core/permissions/responder.js +32 -0
- package/dist/core/permissions/responder.js.map +1 -0
- package/dist/core/permissions/rules.d.ts +34 -0
- package/dist/core/permissions/rules.d.ts.map +1 -0
- package/dist/core/permissions/rules.js +74 -0
- package/dist/core/permissions/rules.js.map +1 -0
- package/dist/core/permissions/startup.d.ts +45 -0
- package/dist/core/permissions/startup.d.ts.map +1 -0
- package/dist/core/permissions/startup.js +63 -0
- package/dist/core/permissions/startup.js.map +1 -0
- package/dist/core/permissions/store.d.ts +114 -0
- package/dist/core/permissions/store.d.ts.map +1 -0
- package/dist/core/permissions/store.js +229 -0
- package/dist/core/permissions/store.js.map +1 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +6 -7
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +2 -2
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +22 -17
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/bwrap-arguments.d.ts +52 -0
- package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
- package/dist/core/sandbox/bwrap-arguments.js +86 -0
- package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
- package/dist/core/sandbox/child-entry.d.ts +2 -0
- package/dist/core/sandbox/child-entry.d.ts.map +1 -0
- package/dist/core/sandbox/child-entry.js +22 -0
- package/dist/core/sandbox/child-entry.js.map +1 -0
- package/dist/core/sandbox/cli-launch.d.ts +88 -0
- package/dist/core/sandbox/cli-launch.d.ts.map +1 -0
- package/dist/core/sandbox/cli-launch.js +272 -0
- package/dist/core/sandbox/cli-launch.js.map +1 -0
- package/dist/core/sandbox/cli-supervisor.d.ts +30 -0
- package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/cli-supervisor.js +123 -0
- package/dist/core/sandbox/cli-supervisor.js.map +1 -0
- package/dist/core/sandbox/default-hosts.d.ts +28 -0
- package/dist/core/sandbox/default-hosts.d.ts.map +1 -0
- package/dist/core/sandbox/default-hosts.js +69 -0
- package/dist/core/sandbox/default-hosts.js.map +1 -0
- package/dist/core/sandbox/full-access.d.ts +28 -0
- package/dist/core/sandbox/full-access.d.ts.map +1 -0
- package/dist/core/sandbox/full-access.js +63 -0
- package/dist/core/sandbox/full-access.js.map +1 -0
- package/dist/core/sandbox/git-identity.d.ts +57 -0
- package/dist/core/sandbox/git-identity.d.ts.map +1 -0
- package/dist/core/sandbox/git-identity.js +78 -0
- package/dist/core/sandbox/git-identity.js.map +1 -0
- package/dist/core/sandbox/host-approval.d.ts +42 -0
- package/dist/core/sandbox/host-approval.d.ts.map +1 -0
- package/dist/core/sandbox/host-approval.js +99 -0
- package/dist/core/sandbox/host-approval.js.map +1 -0
- package/dist/core/sandbox/linux-backend.d.ts +46 -0
- package/dist/core/sandbox/linux-backend.d.ts.map +1 -0
- package/dist/core/sandbox/linux-backend.js +304 -0
- package/dist/core/sandbox/linux-backend.js.map +1 -0
- package/dist/core/sandbox/macos-backend.d.ts +28 -0
- package/dist/core/sandbox/macos-backend.d.ts.map +1 -0
- package/dist/core/sandbox/macos-backend.js +313 -0
- package/dist/core/sandbox/macos-backend.js.map +1 -0
- package/dist/core/sandbox/network-proxy.d.ts +38 -0
- package/dist/core/sandbox/network-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/network-proxy.js +153 -0
- package/dist/core/sandbox/network-proxy.js.map +1 -0
- package/dist/core/sandbox/network-refusal.d.ts +24 -0
- package/dist/core/sandbox/network-refusal.d.ts.map +1 -0
- package/dist/core/sandbox/network-refusal.js +72 -0
- package/dist/core/sandbox/network-refusal.js.map +1 -0
- package/dist/core/sandbox/policy.d.ts +40 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -0
- package/dist/core/sandbox/policy.js +55 -0
- package/dist/core/sandbox/policy.js.map +1 -0
- package/dist/core/sandbox/profiles.d.ts +25 -0
- package/dist/core/sandbox/profiles.d.ts.map +1 -0
- package/dist/core/sandbox/profiles.js +23 -0
- package/dist/core/sandbox/profiles.js.map +1 -0
- package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
- package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-client.js +86 -0
- package/dist/core/sandbox/rpc/command-client.js.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.js +120 -0
- package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts +20 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.js +170 -0
- package/dist/core/sandbox/rpc/credential-client.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts +44 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.js +287 -0
- package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/framing.d.ts +35 -0
- package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/framing.js +114 -0
- package/dist/core/sandbox/rpc/framing.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts +40 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js +152 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js +142 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
- package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
- package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor-temp.js +21 -0
- package/dist/core/sandbox/supervisor-temp.js.map +1 -0
- package/dist/core/sandbox/supervisor.d.ts +51 -0
- package/dist/core/sandbox/supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor.js +18 -0
- package/dist/core/sandbox/supervisor.js.map +1 -0
- package/dist/core/sandbox/terminal-handoff.d.ts +45 -0
- package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-handoff.js +176 -0
- package/dist/core/sandbox/terminal-handoff.js.map +1 -0
- package/dist/core/sandbox/terminal-size.d.ts +40 -0
- package/dist/core/sandbox/terminal-size.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-size.js +105 -0
- package/dist/core/sandbox/terminal-size.js.map +1 -0
- package/dist/core/sandbox/violations.d.ts +23 -0
- package/dist/core/sandbox/violations.d.ts.map +1 -0
- package/dist/core/sandbox/violations.js +30 -0
- package/dist/core/sandbox/violations.js.map +1 -0
- package/dist/core/sdk.d.ts +32 -41
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +161 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-lease.d.ts +31 -0
- package/dist/core/session-lease.d.ts.map +1 -0
- package/dist/core/session-lease.js +138 -0
- package/dist/core/session-lease.js.map +1 -0
- package/dist/core/session-manager.d.ts +46 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +62 -4
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-share.d.ts +31 -0
- package/dist/core/session-share.d.ts.map +1 -0
- package/dist/core/session-share.js +45 -0
- package/dist/core/session-share.js.map +1 -0
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +92 -9
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +138 -36
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +19 -7
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +128 -52
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +5 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -2
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +59 -68
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +3 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/ask-user.d.ts +25 -0
- package/dist/core/tools/ask-user.d.ts.map +1 -0
- package/dist/core/tools/ask-user.js +49 -0
- package/dist/core/tools/ask-user.js.map +1 -0
- package/dist/core/tools/bash-command-segments.d.ts +22 -0
- package/dist/core/tools/bash-command-segments.d.ts.map +1 -0
- package/dist/core/tools/bash-command-segments.js +128 -0
- package/dist/core/tools/bash-command-segments.js.map +1 -0
- package/dist/core/tools/bash.d.ts +40 -4
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +183 -32
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/contract.d.ts +183 -0
- package/dist/core/tools/contract.d.ts.map +1 -0
- package/dist/core/tools/contract.js +48 -0
- package/dist/core/tools/contract.js.map +1 -0
- package/dist/core/tools/delegate.d.ts +38 -0
- package/dist/core/tools/delegate.d.ts.map +1 -0
- package/dist/core/tools/delegate.js +90 -0
- package/dist/core/tools/delegate.js.map +1 -0
- package/dist/core/tools/diagnostics.d.ts +39 -0
- package/dist/core/tools/diagnostics.d.ts.map +1 -0
- package/dist/core/tools/diagnostics.js +62 -0
- package/dist/core/tools/diagnostics.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +12 -2
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +61 -10
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +13 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +47 -10
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +51 -6
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +145 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +17 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/lsp.d.ts +62 -0
- package/dist/core/tools/lsp.d.ts.map +1 -0
- package/dist/core/tools/lsp.js +216 -0
- package/dist/core/tools/lsp.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-permission.d.ts +18 -0
- package/dist/core/tools/path-permission.d.ts.map +1 -0
- package/dist/core/tools/path-permission.js +28 -0
- package/dist/core/tools/path-permission.js.map +1 -0
- package/dist/core/tools/plan-present.d.ts +27 -0
- package/dist/core/tools/plan-present.d.ts.map +1 -0
- package/dist/core/tools/plan-present.js +55 -0
- package/dist/core/tools/plan-present.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +14 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/skill-search.d.ts +32 -0
- package/dist/core/tools/skill-search.d.ts.map +1 -0
- package/dist/core/tools/skill-search.js +56 -0
- package/dist/core/tools/skill-search.js.map +1 -0
- package/dist/core/tools/test.d.ts +34 -0
- package/dist/core/tools/test.d.ts.map +1 -0
- package/dist/core/tools/test.js +75 -0
- package/dist/core/tools/test.js.map +1 -0
- package/dist/core/tools/todo-write.d.ts +31 -0
- package/dist/core/tools/todo-write.d.ts.map +1 -0
- package/dist/core/tools/todo-write.js +51 -0
- package/dist/core/tools/todo-write.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -2
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +11 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/tool-schema.d.ts +22 -0
- package/dist/core/tools/tool-schema.d.ts.map +1 -0
- package/dist/core/tools/tool-schema.js +45 -0
- package/dist/core/tools/tool-schema.js.map +1 -0
- package/dist/core/tools/web-fetch.d.ts +26 -0
- package/dist/core/tools/web-fetch.d.ts.map +1 -0
- package/dist/core/tools/web-fetch.js +62 -0
- package/dist/core/tools/web-fetch.js.map +1 -0
- package/dist/core/tools/web-search-exa.d.ts +33 -0
- package/dist/core/tools/web-search-exa.d.ts.map +1 -0
- package/dist/core/tools/web-search-exa.js +128 -0
- package/dist/core/tools/web-search-exa.js.map +1 -0
- package/dist/core/tools/web-search.d.ts +26 -0
- package/dist/core/tools/web-search.d.ts.map +1 -0
- package/dist/core/tools/web-search.js +53 -0
- package/dist/core/tools/web-search.js.map +1 -0
- package/dist/core/tools/write.d.ts +16 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +48 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-performance-store.d.ts +56 -0
- package/dist/core/usage-performance-store.d.ts.map +1 -0
- package/dist/core/usage-performance-store.js +85 -0
- package/dist/core/usage-performance-store.js.map +1 -0
- package/dist/core/web-search-provider.d.ts +64 -0
- package/dist/core/web-search-provider.d.ts.map +1 -0
- package/dist/core/web-search-provider.js +149 -0
- package/dist/core/web-search-provider.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +87 -22
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +6 -5
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +9 -6
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +72 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +338 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +7 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +11 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +4 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +24 -6
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +17 -41
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/first-use-hints.d.ts +8 -0
- package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-use-hints.js +22 -0
- package/dist/modes/interactive/components/first-use-hints.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +23 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +182 -21
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +31 -9
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +236 -96
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +25 -5
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +226 -58
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/splash-header.d.ts +66 -0
- package/dist/modes/interactive/components/splash-header.d.ts.map +1 -0
- package/dist/modes/interactive/components/splash-header.js +180 -0
- package/dist/modes/interactive/components/splash-header.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +16 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +113 -35
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-panel.d.ts +30 -0
- package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-panel.js +130 -0
- package/dist/modes/interactive/components/tool-panel.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +60 -10
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +61 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +642 -203
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +34 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/apex.json +93 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +3 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +11 -3
- package/dist/modes/interactive/theme/theme.d.ts +14 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +65 -10
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +18 -12
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +22 -5
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +211 -14
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +2 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/server/create-harness.d.ts +1 -1
- package/dist/server/create-harness.d.ts.map +1 -1
- package/dist/server/create-harness.js +8 -5
- package/dist/server/create-harness.js.map +1 -1
- package/dist/testing/replay/metrics.d.ts +24 -0
- package/dist/testing/replay/metrics.d.ts.map +1 -0
- package/dist/testing/replay/metrics.js +35 -0
- package/dist/testing/replay/metrics.js.map +1 -0
- package/dist/testing/replay/recorded-provider.d.ts +10 -0
- package/dist/testing/replay/recorded-provider.d.ts.map +1 -0
- package/dist/testing/replay/recorded-provider.js +108 -0
- package/dist/testing/replay/recorded-provider.js.map +1 -0
- package/dist/testing/replay/runner.d.ts +56 -0
- package/dist/testing/replay/runner.d.ts.map +1 -0
- package/dist/testing/replay/runner.js +406 -0
- package/dist/testing/replay/runner.js.map +1 -0
- package/dist/themes/apex-logo.d.ts +41 -0
- package/dist/themes/apex-logo.d.ts.map +1 -0
- package/dist/themes/apex-logo.js +35 -0
- package/dist/themes/apex-logo.js.map +1 -0
- package/dist/utils/apex-code-user-agent.d.ts +2 -0
- package/dist/utils/apex-code-user-agent.d.ts.map +1 -0
- package/dist/utils/apex-code-user-agent.js +5 -0
- package/dist/utils/apex-code-user-agent.js.map +1 -0
- package/dist/utils/changelog.d.ts +7 -2
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +82 -13
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +70 -2
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +280 -124
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +7 -5
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +25 -14
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/compaction.md +39 -24
- package/docs/containerization.md +24 -21
- package/docs/custom-provider.md +15 -12
- package/docs/development.md +11 -11
- package/docs/environment-variables.md +37 -77
- package/docs/extensions.md +68 -54
- package/docs/index.md +12 -24
- package/docs/json.md +18 -11
- package/docs/keybindings.md +18 -12
- package/docs/llama-cpp.md +9 -7
- package/docs/models.md +17 -11
- package/docs/packages.md +47 -43
- package/docs/prompt-templates.md +3 -3
- package/docs/providers.md +10 -10
- package/docs/quickstart.md +49 -32
- package/docs/rpc.md +35 -18
- package/docs/sdk.md +20 -6
- package/docs/security.md +18 -18
- package/docs/session-format.md +9 -9
- package/docs/sessions.md +13 -13
- package/docs/settings.md +83 -16
- package/docs/shell-aliases.md +1 -1
- package/docs/skills.md +66 -15
- package/docs/terminal-setup.md +44 -19
- package/docs/termux.md +4 -4
- package/docs/themes.md +32 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +5 -5
- package/docs/usage.md +61 -53
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +3 -1
- package/examples/extensions/subagent/agents.ts +40 -9
- package/examples/extensions/subagent/index.ts +27 -4
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +280 -445
- package/package.json +9 -12
- package/dist/core/telemetry.d.ts +0 -3
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js +0 -9
- package/dist/core/telemetry.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -5
- package/dist/utils/pi-user-agent.js.map +0 -1
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { InMemoryModelsStore, Type, } from "@earendil-works/pi-ai";
|
|
4
|
+
import { Agent } from "apex-code-agent-core";
|
|
5
|
+
import { AuthStorage } from "../../core/auth-storage.js";
|
|
6
|
+
import { estimateTokens } from "../../core/compaction/compaction.js";
|
|
7
|
+
import { installContextPipeline } from "../../core/context/pipeline.js";
|
|
8
|
+
import { ModelRuntime } from "../../core/model-runtime.js";
|
|
9
|
+
import { buildSessionContext, loadEntriesFromFile, SessionManager, } from "../../core/session-manager.js";
|
|
10
|
+
import { buildSystemPrompt } from "../../core/system-prompt.js";
|
|
11
|
+
import { createAllToolDefinitions } from "../../core/tools/index.js";
|
|
12
|
+
import { buildReplayMetrics } from "./metrics.js";
|
|
13
|
+
import { registerRecordedProvider } from "./recorded-provider.js";
|
|
14
|
+
/**
|
|
15
|
+
* Dedicated eviction budget for the replay harness — deliberately **not** derived
|
|
16
|
+
* from the fixture model's `contextWindow` (`recorded-provider.ts` hardcodes
|
|
17
|
+
* `1_000_000` for unrelated reasons predating this pipeline, shared by every
|
|
18
|
+
* fixture in the corpus, and is not to be changed here). Feeding that real
|
|
19
|
+
* `contextWindow` through production's `evictionBudget` formula
|
|
20
|
+
* (`../../core/context/pipeline.ts`) would yield a budget of roughly 490,000 tokens
|
|
21
|
+
* — orders of magnitude above anything in this corpus, so eviction would never
|
|
22
|
+
* observably fire and the gate it is meant to measure would stay blind, which is
|
|
23
|
+
* exactly the gap this task closes.
|
|
24
|
+
*
|
|
25
|
+
* `1_000` was chosen empirically — measured directly against `replayCorpus()`, not
|
|
26
|
+
* estimated — against three constraints that all have to hold simultaneously:
|
|
27
|
+
*
|
|
28
|
+
* - `tool-error-recovery.jsonl`'s single turn carries its entire ~759 tokens
|
|
29
|
+
* (mostly the static system prompt/tool-schema prefix) under budget, so its
|
|
30
|
+
* recorded `contextTokensByTurn: [759]` (`test/replay-runner.test.ts`) is
|
|
31
|
+
* unaffected — confirmed unchanged at this budget.
|
|
32
|
+
* - `heavy-tool-output.jsonl` carries a single ~8,400-token recoverable `read`
|
|
33
|
+
* result — comfortably over budget, so it evicts, which is the fixture's
|
|
34
|
+
* documented purpose ("Large deterministic result for eviction measurements",
|
|
35
|
+
* `fixtures/corpus/README.md`). Measured post-eviction turn: 748 tokens.
|
|
36
|
+
* - `long-tool-heavy.jsonl` accumulates roughly 14,300 evictable tokens by turn 20
|
|
37
|
+
* across ten interleaved `read`/`grep` results. `1_000` was verified against
|
|
38
|
+
* `REPLAY_EVICTION_BUDGET: 0` (the theoretical floor — evict every eligible
|
|
39
|
+
* result unconditionally) and produces the *same* turn-20 result, 1,769 tokens
|
|
40
|
+
* — an 88.4% drop from the pre-pipeline baseline of 15,272 — confirming `1_000`
|
|
41
|
+
* already reaches that floor rather than under-evicting. A first pass at
|
|
42
|
+
* `3_000` measured 3,195 (79.1%, just short of the phase's 80% per-fixture
|
|
43
|
+
* goal); `1_000` was chosen after confirming the floor is actually lower.
|
|
44
|
+
*
|
|
45
|
+
* This constant governs replay measurement only; it has no effect on production,
|
|
46
|
+
* which always calls `evictionBudget` with the real model's `contextWindow`.
|
|
47
|
+
*/
|
|
48
|
+
export const REPLAY_EVICTION_BUDGET = 1_000;
|
|
49
|
+
/**
|
|
50
|
+
* Builds a `ContractLookup` from the real production tool definitions — a second,
|
|
51
|
+
* independent call to `createAllToolDefinitions` alongside the one
|
|
52
|
+
* `productionPromptAndSchemas` already makes for the static-prompt baseline. Kept
|
|
53
|
+
* separate rather than threading that function's `definitions` out: the two
|
|
54
|
+
* concerns (building the static prompt/schema baseline vs. resolving a tool's
|
|
55
|
+
* contract for the pipeline) are unrelated, and `createAllToolDefinitions` is cheap
|
|
56
|
+
* and pure, so a second call costs nothing and keeps both call sites simple.
|
|
57
|
+
*/
|
|
58
|
+
function replayContractLookup(cwd) {
|
|
59
|
+
const definitions = createAllToolDefinitions(cwd);
|
|
60
|
+
return (name) => Reflect.get(definitions, name)?.contract;
|
|
61
|
+
}
|
|
62
|
+
function isVersionThreeHeader(entry) {
|
|
63
|
+
if (entry === null || typeof entry !== "object")
|
|
64
|
+
return false;
|
|
65
|
+
return Reflect.get(entry, "type") === "session" && Reflect.get(entry, "version") === 3;
|
|
66
|
+
}
|
|
67
|
+
function isSessionEntry(entry) {
|
|
68
|
+
if (entry === null || typeof entry !== "object")
|
|
69
|
+
return false;
|
|
70
|
+
const type = Reflect.get(entry, "type");
|
|
71
|
+
const id = Reflect.get(entry, "id");
|
|
72
|
+
const parentId = Reflect.get(entry, "parentId");
|
|
73
|
+
return (type !== "session" &&
|
|
74
|
+
typeof type === "string" &&
|
|
75
|
+
typeof id === "string" &&
|
|
76
|
+
(parentId === null || typeof parentId === "string"));
|
|
77
|
+
}
|
|
78
|
+
function validateSessionTree(entries) {
|
|
79
|
+
const ids = new Set();
|
|
80
|
+
const parentById = new Map();
|
|
81
|
+
let roots = 0;
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
if (!entry || typeof entry.id !== "string" || ids.has(entry.id))
|
|
84
|
+
throw new Error("Replay session contains invalid or duplicate entry ids");
|
|
85
|
+
ids.add(entry.id);
|
|
86
|
+
parentById.set(entry.id, entry.parentId);
|
|
87
|
+
if (entry.parentId === null)
|
|
88
|
+
roots++;
|
|
89
|
+
else if (typeof entry.parentId !== "string")
|
|
90
|
+
throw new Error("Replay session contains an invalid parentId");
|
|
91
|
+
}
|
|
92
|
+
if (roots !== 1)
|
|
93
|
+
throw new Error("Replay session must contain exactly one tree root");
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
if (entry.parentId !== null && !ids.has(entry.parentId))
|
|
96
|
+
throw new Error(`Replay session has missing parent ${entry.parentId}`);
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
let current = entry.id;
|
|
99
|
+
while (current !== null) {
|
|
100
|
+
if (seen.has(current))
|
|
101
|
+
throw new Error("Replay session contains a parent cycle");
|
|
102
|
+
seen.add(current);
|
|
103
|
+
current = parentById.get(current) ?? null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function isMessageEntry(entry) {
|
|
108
|
+
return entry.type === "message";
|
|
109
|
+
}
|
|
110
|
+
function selectedResponses(entries) {
|
|
111
|
+
return entries
|
|
112
|
+
.filter(isMessageEntry)
|
|
113
|
+
.map((entry) => entry.message)
|
|
114
|
+
.filter((message) => message.role === "assistant");
|
|
115
|
+
}
|
|
116
|
+
function selectedToolResults(entries) {
|
|
117
|
+
return entries
|
|
118
|
+
.filter(isMessageEntry)
|
|
119
|
+
.map((entry) => entry.message)
|
|
120
|
+
.filter((message) => message.role === "toolResult");
|
|
121
|
+
}
|
|
122
|
+
function selectedUserEntries(entries) {
|
|
123
|
+
return entries.filter(isMessageEntry).filter((entry) => entry.message.role === "user");
|
|
124
|
+
}
|
|
125
|
+
function toolCalls(responses) {
|
|
126
|
+
return responses.flatMap((message) => message.content.filter((part) => part.type === "toolCall"));
|
|
127
|
+
}
|
|
128
|
+
function createRecordedTools(calls, results) {
|
|
129
|
+
const resultByCallId = new Map(results.map((result) => [result.toolCallId, structuredClone(result)]));
|
|
130
|
+
const unconsumed = new Set(resultByCallId.keys());
|
|
131
|
+
const tools = [...new Set(calls.map((call) => call.name))].map((name) => ({
|
|
132
|
+
name,
|
|
133
|
+
label: `Recorded ${name}`,
|
|
134
|
+
description: "Replays a recorded tool result without external side effects.",
|
|
135
|
+
parameters: Type.Any(),
|
|
136
|
+
execute: async (toolCallId) => {
|
|
137
|
+
const result = resultByCallId.get(toolCallId);
|
|
138
|
+
if (!result)
|
|
139
|
+
throw new Error(`Missing recorded tool result for ${toolCallId}`);
|
|
140
|
+
unconsumed.delete(toolCallId);
|
|
141
|
+
if (result.isError) {
|
|
142
|
+
const text = result.content.find((part) => part.type === "text")?.text ?? "Recorded tool error";
|
|
143
|
+
throw new Error(text);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
content: structuredClone(result.content),
|
|
147
|
+
details: structuredClone(result.details),
|
|
148
|
+
usage: structuredClone(result.usage),
|
|
149
|
+
addedToolNames: structuredClone(result.addedToolNames),
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
}));
|
|
153
|
+
return {
|
|
154
|
+
tools,
|
|
155
|
+
assertExhausted() {
|
|
156
|
+
if (unconsumed.size > 0)
|
|
157
|
+
throw new Error(`Replay left ${unconsumed.size} tool result(s) unused`);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function assertResponsesMatch(actual, expected) {
|
|
162
|
+
if (actual.length !== expected.length) {
|
|
163
|
+
throw new Error(`Replayed ${actual.length} assistant response(s), expected ${expected.length}`);
|
|
164
|
+
}
|
|
165
|
+
for (const [index, response] of actual.entries()) {
|
|
166
|
+
if (JSON.stringify(response) !== JSON.stringify(expected[index])) {
|
|
167
|
+
throw new Error(`Replayed assistant response ${index + 1} does not match the recording`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function assertToolResultsMatch(actual, expected) {
|
|
172
|
+
if (actual.length !== expected.length) {
|
|
173
|
+
throw new Error(`Replayed ${actual.length} tool result(s), expected ${expected.length}`);
|
|
174
|
+
}
|
|
175
|
+
for (const [index, result] of actual.entries()) {
|
|
176
|
+
const recorded = expected[index];
|
|
177
|
+
if (!recorded)
|
|
178
|
+
throw new Error(`Missing recorded tool result ${index + 1}`);
|
|
179
|
+
const { timestamp: _actualTimestamp, ...actualStable } = result;
|
|
180
|
+
const { timestamp: _recordedTimestamp, ...recordedStable } = recorded;
|
|
181
|
+
const actualComparable = { ...actualStable };
|
|
182
|
+
const recordedComparable = { ...recordedStable };
|
|
183
|
+
if (actualComparable.details === undefined ||
|
|
184
|
+
(typeof actualComparable.details === "object" && Object.keys(actualComparable.details ?? {}).length === 0))
|
|
185
|
+
delete actualComparable.details;
|
|
186
|
+
if (recordedComparable.details === undefined ||
|
|
187
|
+
(typeof recordedComparable.details === "object" && Object.keys(recordedComparable.details ?? {}).length === 0))
|
|
188
|
+
delete recordedComparable.details;
|
|
189
|
+
if (JSON.stringify(actualComparable) !== JSON.stringify(recordedComparable)) {
|
|
190
|
+
throw new Error(`Replayed tool result ${index + 1} does not match the recording`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function productionPromptAndSchemas(toolNames) {
|
|
195
|
+
const definitions = createAllToolDefinitions("$HOME/replay-fixtures");
|
|
196
|
+
const defaultToolNames = ["read", "bash", "edit", "write"];
|
|
197
|
+
const selected = [...new Set([...defaultToolNames, ...toolNames])].sort().flatMap((name) => {
|
|
198
|
+
const definition = Reflect.get(definitions, name);
|
|
199
|
+
return definition && typeof definition === "object" ? [definition] : [];
|
|
200
|
+
});
|
|
201
|
+
const toolSnippets = Object.fromEntries(selected.flatMap((definition) => typeof definition.promptSnippet === "string" ? [[definition.name, definition.promptSnippet]] : []));
|
|
202
|
+
const promptGuidelines = selected.flatMap((definition) => definition.promptGuidelines ?? []);
|
|
203
|
+
return {
|
|
204
|
+
systemPrompt: buildSystemPrompt({
|
|
205
|
+
cwd: "$HOME/replay-fixtures",
|
|
206
|
+
customPrompt: "You are an expert coding assistant operating inside Apex Code.",
|
|
207
|
+
selectedTools: selected.map((definition) => definition.name),
|
|
208
|
+
toolSnippets,
|
|
209
|
+
promptGuidelines,
|
|
210
|
+
}),
|
|
211
|
+
tools: selected.map((definition) => ({
|
|
212
|
+
name: definition.name,
|
|
213
|
+
description: definition.description,
|
|
214
|
+
parameters: definition.parameters,
|
|
215
|
+
})),
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
export async function replay(filePath) {
|
|
219
|
+
let physicalLines;
|
|
220
|
+
try {
|
|
221
|
+
physicalLines = readFileSync(filePath, "utf8")
|
|
222
|
+
.split("\n")
|
|
223
|
+
.filter((line) => line.trim().length > 0)
|
|
224
|
+
.map((line) => JSON.parse(line));
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
throw new Error(`Replay requires valid JSONL: ${filePath}`, { cause: error });
|
|
228
|
+
}
|
|
229
|
+
const fileEntries = loadEntriesFromFile(filePath);
|
|
230
|
+
if (physicalLines.length !== fileEntries.length)
|
|
231
|
+
throw new Error("Replay session contains an invalid physical line");
|
|
232
|
+
if (!isVersionThreeHeader(fileEntries[0])) {
|
|
233
|
+
throw new Error(`Replay requires a native version 3 session: ${filePath}`);
|
|
234
|
+
}
|
|
235
|
+
const rawEntries = fileEntries.slice(1);
|
|
236
|
+
const rawSessionEntries = rawEntries.filter(isSessionEntry);
|
|
237
|
+
if (rawSessionEntries.length !== rawEntries.length)
|
|
238
|
+
throw new Error("Replay session contains an invalid entry");
|
|
239
|
+
validateSessionTree(rawSessionEntries);
|
|
240
|
+
const sessionManager = SessionManager.open(filePath);
|
|
241
|
+
const entries = sessionManager.getBranch();
|
|
242
|
+
validateSessionTree(entries);
|
|
243
|
+
const responses = selectedResponses(entries);
|
|
244
|
+
const recordedToolResults = selectedToolResults(entries);
|
|
245
|
+
const users = selectedUserEntries(entries);
|
|
246
|
+
if (users.length === 0 || responses.length === 0)
|
|
247
|
+
throw new Error("Replay session must contain user and assistant messages");
|
|
248
|
+
const runtime = await ModelRuntime.create({
|
|
249
|
+
credentials: AuthStorage.inMemory(),
|
|
250
|
+
modelsPath: null,
|
|
251
|
+
modelsStore: new InMemoryModelsStore(),
|
|
252
|
+
allowModelNetwork: false,
|
|
253
|
+
refreshOnCreate: false,
|
|
254
|
+
});
|
|
255
|
+
const recorded = registerRecordedProvider(runtime, responses);
|
|
256
|
+
const recordedTools = createRecordedTools(toolCalls(responses), recordedToolResults);
|
|
257
|
+
const replayedResponses = [];
|
|
258
|
+
const replayedToolResults = [];
|
|
259
|
+
const contextTokensByTurn = [];
|
|
260
|
+
let turnsCompleted = 0;
|
|
261
|
+
const promptBaseline = productionPromptAndSchemas(recordedTools.tools.map((tool) => tool.name));
|
|
262
|
+
let networkCalls = 0;
|
|
263
|
+
const rejectNetwork = async () => {
|
|
264
|
+
networkCalls++;
|
|
265
|
+
throw new Error("Network access is disabled during replay");
|
|
266
|
+
};
|
|
267
|
+
const firstContext = buildSessionContext(entries, users[0]?.id);
|
|
268
|
+
const firstResponse = responses[0];
|
|
269
|
+
if (!firstResponse)
|
|
270
|
+
throw new Error("Replay session has no recorded response");
|
|
271
|
+
const agent = new Agent({
|
|
272
|
+
initialState: {
|
|
273
|
+
model: recorded.getModel(firstContext.model?.modelId ?? firstResponse.model),
|
|
274
|
+
systemPrompt: promptBaseline.systemPrompt,
|
|
275
|
+
tools: recordedTools.tools,
|
|
276
|
+
},
|
|
277
|
+
streamFn: (model, context, options) => runtime.streamSimple(model, context, { ...options, fetch: rejectNetwork }),
|
|
278
|
+
getApiKey: () => "offline-replay",
|
|
279
|
+
convertToLlm: (messages) => {
|
|
280
|
+
const converted = [];
|
|
281
|
+
for (const message of messages) {
|
|
282
|
+
if (message.role === "user") {
|
|
283
|
+
converted.push({ role: "user", content: message.content, timestamp: message.timestamp });
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (message.role === "assistant") {
|
|
287
|
+
converted.push(message);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (message.role !== "toolResult")
|
|
291
|
+
continue;
|
|
292
|
+
// Validate the call id is one this replay actually recorded, but send the
|
|
293
|
+
// *incoming* message — not a fresh lookup by id — so that whatever the
|
|
294
|
+
// context pipeline's eviction stage did to `message.content` upstream
|
|
295
|
+
// (in `transformContext`) is what reaches the provider request. Re-fetching
|
|
296
|
+
// the original recorded content here would silently discard eviction,
|
|
297
|
+
// since eviction never touches `recordedToolResults` itself (see
|
|
298
|
+
// `assertToolResultsMatch`, which intentionally still compares against the
|
|
299
|
+
// untouched recording).
|
|
300
|
+
const recordedResult = recordedToolResults.find((result) => result.toolCallId === message.toolCallId);
|
|
301
|
+
if (!recordedResult)
|
|
302
|
+
throw new Error(`Missing recorded tool result for ${message.toolCallId}`);
|
|
303
|
+
converted.push(structuredClone(message));
|
|
304
|
+
}
|
|
305
|
+
return converted;
|
|
306
|
+
},
|
|
307
|
+
afterToolCall: async ({ toolCall }) => {
|
|
308
|
+
const result = recordedToolResults.find((candidate) => candidate.toolCallId === toolCall.id);
|
|
309
|
+
if (!result)
|
|
310
|
+
throw new Error(`Missing recorded tool result for ${toolCall.id}`);
|
|
311
|
+
return {
|
|
312
|
+
content: structuredClone(result.content),
|
|
313
|
+
details: result.details,
|
|
314
|
+
usage: result.usage,
|
|
315
|
+
isError: result.isError,
|
|
316
|
+
};
|
|
317
|
+
},
|
|
318
|
+
toolExecution: "sequential",
|
|
319
|
+
});
|
|
320
|
+
// Same pipeline `AgentSession` installs in production (`_installContextPipeline`
|
|
321
|
+
// in `core/agent-session.ts`), via the shared `installContextPipeline` — deferred
|
|
322
|
+
// -schema resolution ahead of every request, then tool-result eviction — so the
|
|
323
|
+
// replay gate can observe both. The contract lookup is built from the real
|
|
324
|
+
// production tool definitions; the budget is `REPLAY_EVICTION_BUDGET`, a
|
|
325
|
+
// dedicated constant documented above (not derived from the fixture model's
|
|
326
|
+
// `contextWindow`; see that constant's comment for why).
|
|
327
|
+
installContextPipeline(agent, {
|
|
328
|
+
contractLookup: replayContractLookup("$HOME/replay-fixtures"),
|
|
329
|
+
evictionBudget: () => REPLAY_EVICTION_BUDGET,
|
|
330
|
+
});
|
|
331
|
+
const contextsByTurn = [];
|
|
332
|
+
for (const user of users) {
|
|
333
|
+
const historical = buildSessionContext(entries, user.id);
|
|
334
|
+
const nextResponse = responses[recorded.requestCount];
|
|
335
|
+
if (!nextResponse)
|
|
336
|
+
throw new Error(`Missing recorded response for user turn ${contextTokensByTurn.length + 1}`);
|
|
337
|
+
agent.state.model = recorded.getModel(historical.model?.modelId ?? nextResponse.model);
|
|
338
|
+
agent.state.messages = historical.messages.slice(0, -1);
|
|
339
|
+
const requestStart = recorded.requestCount;
|
|
340
|
+
await agent.prompt(user.message);
|
|
341
|
+
const turnContexts = recorded.contexts.slice(requestStart);
|
|
342
|
+
const lastContext = turnContexts.at(-1);
|
|
343
|
+
if (!lastContext)
|
|
344
|
+
throw new Error(`User turn ${contextTokensByTurn.length + 1} made no provider request`);
|
|
345
|
+
const staticInputTokens = Math.ceil(`${promptBaseline.systemPrompt}\n${JSON.stringify(promptBaseline.tools)}`.length / 4);
|
|
346
|
+
contextTokensByTurn.push(staticInputTokens + lastContext.messages.reduce((total, message) => total + estimateTokens(message), 0));
|
|
347
|
+
// Normalize toolResult timestamps to the recorded value before exposing this
|
|
348
|
+
// turn's context, mirroring the same normalization the `toolResults` field
|
|
349
|
+
// below already does and for the same reason: a toolResult's timestamp is
|
|
350
|
+
// stamped live (via `agent.state.messages`) rather than replayed from the
|
|
351
|
+
// fixture, so leaving it as-is would make `contextsByTurn` — and anything
|
|
352
|
+
// that serializes it, like the determinism test below — flaky across runs.
|
|
353
|
+
// Content (what eviction may have rewritten) is untouched.
|
|
354
|
+
contextsByTurn.push(lastContext.messages.map((message) => message.role === "toolResult"
|
|
355
|
+
? {
|
|
356
|
+
...message,
|
|
357
|
+
timestamp: recordedToolResults.find((result) => result.toolCallId === message.toolCallId)?.timestamp ??
|
|
358
|
+
message.timestamp,
|
|
359
|
+
}
|
|
360
|
+
: message));
|
|
361
|
+
for (const message of agent.state.messages.slice(historical.messages.length - 1)) {
|
|
362
|
+
if (message.role === "assistant")
|
|
363
|
+
replayedResponses.push(message);
|
|
364
|
+
if (message.role === "toolResult")
|
|
365
|
+
replayedToolResults.push(message);
|
|
366
|
+
}
|
|
367
|
+
const terminalResponse = replayedResponses.at(-1);
|
|
368
|
+
if (terminalResponse && terminalResponse.stopReason !== "error" && terminalResponse.stopReason !== "aborted") {
|
|
369
|
+
turnsCompleted++;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
recorded.assertExhausted();
|
|
373
|
+
recordedTools.assertExhausted();
|
|
374
|
+
assertResponsesMatch(replayedResponses, responses);
|
|
375
|
+
assertToolResultsMatch(replayedToolResults, recordedToolResults);
|
|
376
|
+
return {
|
|
377
|
+
turns: users.length,
|
|
378
|
+
requests: recorded.requestCount,
|
|
379
|
+
networkCalls,
|
|
380
|
+
responses: replayedResponses,
|
|
381
|
+
toolResults: replayedToolResults.map((result, index) => ({
|
|
382
|
+
...structuredClone(result),
|
|
383
|
+
timestamp: recordedToolResults[index]?.timestamp ?? result.timestamp,
|
|
384
|
+
})),
|
|
385
|
+
contextsByTurn,
|
|
386
|
+
metrics: buildReplayMetrics({
|
|
387
|
+
systemPrompt: promptBaseline.systemPrompt,
|
|
388
|
+
tools: promptBaseline.tools,
|
|
389
|
+
recordedResponses: responses,
|
|
390
|
+
replayedResponses,
|
|
391
|
+
contextTokensByTurn,
|
|
392
|
+
turnsCompleted,
|
|
393
|
+
}),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
/** Replay every JSONL fixture in lexical order for byte-stable corpus output. */
|
|
397
|
+
export async function replayCorpus(directory) {
|
|
398
|
+
const metrics = {};
|
|
399
|
+
for (const name of readdirSync(directory)
|
|
400
|
+
.filter((entry) => entry.endsWith(".jsonl"))
|
|
401
|
+
.sort()) {
|
|
402
|
+
metrics[name] = (await replay(join(directory, name))).metrics;
|
|
403
|
+
}
|
|
404
|
+
return metrics;
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/testing/replay/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n\ttype AssistantMessage,\n\tInMemoryModelsStore,\n\ttype Message,\n\ttype Tool,\n\ttype ToolCall,\n\ttype ToolResultMessage,\n\tType,\n} from \"@earendil-works/pi-ai\";\nimport { Agent, type AgentTool, type AgentToolResult } from \"apex-code-agent-core\";\nimport { AuthStorage } from \"../../core/auth-storage.ts\";\nimport { estimateTokens } from \"../../core/compaction/compaction.ts\";\nimport type { ContractLookup } from \"../../core/context/eviction.ts\";\nimport { installContextPipeline } from \"../../core/context/pipeline.ts\";\nimport { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport {\n\tbuildSessionContext,\n\tloadEntriesFromFile,\n\ttype SessionEntry,\n\ttype SessionHeader,\n\tSessionManager,\n\ttype SessionMessageEntry,\n} from \"../../core/session-manager.ts\";\nimport { buildSystemPrompt } from \"../../core/system-prompt.ts\";\nimport { createAllToolDefinitions, type ToolDef } from \"../../core/tools/index.ts\";\nimport { buildReplayMetrics, type ReplayMetrics } from \"./metrics.ts\";\nimport { registerRecordedProvider } from \"./recorded-provider.ts\";\n\nexport interface ReplayResult {\n\tturns: number;\n\trequests: number;\n\tnetworkCalls: number;\n\tresponses: AssistantMessage[];\n\ttoolResults: ToolResultMessage[];\n\tmetrics: ReplayMetrics;\n\t/**\n\t * The final outbound provider request's messages for each user turn — the same\n\t * array `contextTokensByTurn` is measured from, exposed so tests can assert\n\t * directly on context-pipeline effects (eviction markers, deferred schemas)\n\t * without reaching into `RecordedProvider` internals.\n\t */\n\tcontextsByTurn: Message[][];\n}\n\n/**\n * Dedicated eviction budget for the replay harness — deliberately **not** derived\n * from the fixture model's `contextWindow` (`recorded-provider.ts` hardcodes\n * `1_000_000` for unrelated reasons predating this pipeline, shared by every\n * fixture in the corpus, and is not to be changed here). Feeding that real\n * `contextWindow` through production's `evictionBudget` formula\n * (`../../core/context/pipeline.ts`) would yield a budget of roughly 490,000 tokens\n * — orders of magnitude above anything in this corpus, so eviction would never\n * observably fire and the gate it is meant to measure would stay blind, which is\n * exactly the gap this task closes.\n *\n * `1_000` was chosen empirically — measured directly against `replayCorpus()`, not\n * estimated — against three constraints that all have to hold simultaneously:\n *\n * - `tool-error-recovery.jsonl`'s single turn carries its entire ~759 tokens\n * (mostly the static system prompt/tool-schema prefix) under budget, so its\n * recorded `contextTokensByTurn: [759]` (`test/replay-runner.test.ts`) is\n * unaffected — confirmed unchanged at this budget.\n * - `heavy-tool-output.jsonl` carries a single ~8,400-token recoverable `read`\n * result — comfortably over budget, so it evicts, which is the fixture's\n * documented purpose (\"Large deterministic result for eviction measurements\",\n * `fixtures/corpus/README.md`). Measured post-eviction turn: 748 tokens.\n * - `long-tool-heavy.jsonl` accumulates roughly 14,300 evictable tokens by turn 20\n * across ten interleaved `read`/`grep` results. `1_000` was verified against\n * `REPLAY_EVICTION_BUDGET: 0` (the theoretical floor — evict every eligible\n * result unconditionally) and produces the *same* turn-20 result, 1,769 tokens\n * — an 88.4% drop from the pre-pipeline baseline of 15,272 — confirming `1_000`\n * already reaches that floor rather than under-evicting. A first pass at\n * `3_000` measured 3,195 (79.1%, just short of the phase's 80% per-fixture\n * goal); `1_000` was chosen after confirming the floor is actually lower.\n *\n * This constant governs replay measurement only; it has no effect on production,\n * which always calls `evictionBudget` with the real model's `contextWindow`.\n */\nexport const REPLAY_EVICTION_BUDGET = 1_000;\n\n/**\n * Builds a `ContractLookup` from the real production tool definitions — a second,\n * independent call to `createAllToolDefinitions` alongside the one\n * `productionPromptAndSchemas` already makes for the static-prompt baseline. Kept\n * separate rather than threading that function's `definitions` out: the two\n * concerns (building the static prompt/schema baseline vs. resolving a tool's\n * contract for the pipeline) are unrelated, and `createAllToolDefinitions` is cheap\n * and pure, so a second call costs nothing and keeps both call sites simple.\n */\nfunction replayContractLookup(cwd: string): ContractLookup {\n\tconst definitions = createAllToolDefinitions(cwd);\n\treturn (name) => (Reflect.get(definitions, name) as Partial<ToolDef> | undefined)?.contract;\n}\n\nfunction isVersionThreeHeader(entry: unknown): entry is SessionHeader & { version: 3 } {\n\tif (entry === null || typeof entry !== \"object\") return false;\n\treturn Reflect.get(entry, \"type\") === \"session\" && Reflect.get(entry, \"version\") === 3;\n}\n\nfunction isSessionEntry(entry: unknown): entry is SessionEntry {\n\tif (entry === null || typeof entry !== \"object\") return false;\n\tconst type = Reflect.get(entry, \"type\");\n\tconst id = Reflect.get(entry, \"id\");\n\tconst parentId = Reflect.get(entry, \"parentId\");\n\treturn (\n\t\ttype !== \"session\" &&\n\t\ttypeof type === \"string\" &&\n\t\ttypeof id === \"string\" &&\n\t\t(parentId === null || typeof parentId === \"string\")\n\t);\n}\n\nfunction validateSessionTree(entries: readonly SessionEntry[]): void {\n\tconst ids = new Set<string>();\n\tconst parentById = new Map<string, string | null>();\n\tlet roots = 0;\n\tfor (const entry of entries) {\n\t\tif (!entry || typeof entry.id !== \"string\" || ids.has(entry.id))\n\t\t\tthrow new Error(\"Replay session contains invalid or duplicate entry ids\");\n\t\tids.add(entry.id);\n\t\tparentById.set(entry.id, entry.parentId);\n\t\tif (entry.parentId === null) roots++;\n\t\telse if (typeof entry.parentId !== \"string\") throw new Error(\"Replay session contains an invalid parentId\");\n\t}\n\tif (roots !== 1) throw new Error(\"Replay session must contain exactly one tree root\");\n\tfor (const entry of entries) {\n\t\tif (entry.parentId !== null && !ids.has(entry.parentId))\n\t\t\tthrow new Error(`Replay session has missing parent ${entry.parentId}`);\n\t\tconst seen = new Set<string>();\n\t\tlet current: string | null = entry.id;\n\t\twhile (current !== null) {\n\t\t\tif (seen.has(current)) throw new Error(\"Replay session contains a parent cycle\");\n\t\t\tseen.add(current);\n\t\t\tcurrent = parentById.get(current) ?? null;\n\t\t}\n\t}\n}\n\nfunction isMessageEntry(entry: SessionEntry): entry is SessionMessageEntry {\n\treturn entry.type === \"message\";\n}\n\nfunction selectedResponses(entries: readonly SessionEntry[]): AssistantMessage[] {\n\treturn entries\n\t\t.filter(isMessageEntry)\n\t\t.map((entry) => entry.message)\n\t\t.filter((message): message is AssistantMessage => message.role === \"assistant\");\n}\n\nfunction selectedToolResults(entries: readonly SessionEntry[]): ToolResultMessage[] {\n\treturn entries\n\t\t.filter(isMessageEntry)\n\t\t.map((entry) => entry.message)\n\t\t.filter((message): message is ToolResultMessage => message.role === \"toolResult\");\n}\n\nfunction selectedUserEntries(entries: readonly SessionEntry[]): SessionMessageEntry[] {\n\treturn entries.filter(isMessageEntry).filter((entry) => entry.message.role === \"user\");\n}\n\nfunction toolCalls(responses: readonly AssistantMessage[]): ToolCall[] {\n\treturn responses.flatMap((message) => message.content.filter((part): part is ToolCall => part.type === \"toolCall\"));\n}\n\nfunction createRecordedTools(\n\tcalls: readonly ToolCall[],\n\tresults: readonly ToolResultMessage[],\n): { tools: AgentTool[]; assertExhausted(): void } {\n\tconst resultByCallId = new Map(results.map((result) => [result.toolCallId, structuredClone(result)]));\n\tconst unconsumed = new Set(resultByCallId.keys());\n\tconst tools = [...new Set(calls.map((call) => call.name))].map(\n\t\t(name): AgentTool => ({\n\t\t\tname,\n\t\t\tlabel: `Recorded ${name}`,\n\t\t\tdescription: \"Replays a recorded tool result without external side effects.\",\n\t\t\tparameters: Type.Any(),\n\t\t\texecute: async (toolCallId): Promise<AgentToolResult<unknown>> => {\n\t\t\t\tconst result = resultByCallId.get(toolCallId);\n\t\t\t\tif (!result) throw new Error(`Missing recorded tool result for ${toolCallId}`);\n\t\t\t\tunconsumed.delete(toolCallId);\n\t\t\t\tif (result.isError) {\n\t\t\t\t\tconst text = result.content.find((part) => part.type === \"text\")?.text ?? \"Recorded tool error\";\n\t\t\t\t\tthrow new Error(text);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tcontent: structuredClone(result.content),\n\t\t\t\t\tdetails: structuredClone(result.details),\n\t\t\t\t\tusage: structuredClone(result.usage),\n\t\t\t\t\taddedToolNames: structuredClone(result.addedToolNames),\n\t\t\t\t};\n\t\t\t},\n\t\t}),\n\t);\n\treturn {\n\t\ttools,\n\t\tassertExhausted() {\n\t\t\tif (unconsumed.size > 0) throw new Error(`Replay left ${unconsumed.size} tool result(s) unused`);\n\t\t},\n\t};\n}\n\nfunction assertResponsesMatch(actual: readonly AssistantMessage[], expected: readonly AssistantMessage[]): void {\n\tif (actual.length !== expected.length) {\n\t\tthrow new Error(`Replayed ${actual.length} assistant response(s), expected ${expected.length}`);\n\t}\n\tfor (const [index, response] of actual.entries()) {\n\t\tif (JSON.stringify(response) !== JSON.stringify(expected[index])) {\n\t\t\tthrow new Error(`Replayed assistant response ${index + 1} does not match the recording`);\n\t\t}\n\t}\n}\n\nfunction assertToolResultsMatch(actual: readonly ToolResultMessage[], expected: readonly ToolResultMessage[]): void {\n\tif (actual.length !== expected.length) {\n\t\tthrow new Error(`Replayed ${actual.length} tool result(s), expected ${expected.length}`);\n\t}\n\tfor (const [index, result] of actual.entries()) {\n\t\tconst recorded = expected[index];\n\t\tif (!recorded) throw new Error(`Missing recorded tool result ${index + 1}`);\n\t\tconst { timestamp: _actualTimestamp, ...actualStable } = result;\n\t\tconst { timestamp: _recordedTimestamp, ...recordedStable } = recorded;\n\t\tconst actualComparable = { ...actualStable };\n\t\tconst recordedComparable = { ...recordedStable };\n\t\tif (\n\t\t\tactualComparable.details === undefined ||\n\t\t\t(typeof actualComparable.details === \"object\" && Object.keys(actualComparable.details ?? {}).length === 0)\n\t\t)\n\t\t\tdelete actualComparable.details;\n\t\tif (\n\t\t\trecordedComparable.details === undefined ||\n\t\t\t(typeof recordedComparable.details === \"object\" && Object.keys(recordedComparable.details ?? {}).length === 0)\n\t\t)\n\t\t\tdelete recordedComparable.details;\n\t\tif (JSON.stringify(actualComparable) !== JSON.stringify(recordedComparable)) {\n\t\t\tthrow new Error(`Replayed tool result ${index + 1} does not match the recording`);\n\t\t}\n\t}\n}\n\nfunction productionPromptAndSchemas(toolNames: readonly string[]): { systemPrompt: string; tools: Tool[] } {\n\tconst definitions = createAllToolDefinitions(\"$HOME/replay-fixtures\");\n\tconst defaultToolNames = [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst selected = [...new Set([...defaultToolNames, ...toolNames])].sort().flatMap((name) => {\n\t\tconst definition = Reflect.get(definitions, name);\n\t\treturn definition && typeof definition === \"object\" ? [definition] : [];\n\t});\n\tconst toolSnippets = Object.fromEntries(\n\t\tselected.flatMap((definition) =>\n\t\t\ttypeof definition.promptSnippet === \"string\" ? [[definition.name, definition.promptSnippet]] : [],\n\t\t),\n\t);\n\tconst promptGuidelines = selected.flatMap((definition) => definition.promptGuidelines ?? []);\n\treturn {\n\t\tsystemPrompt: buildSystemPrompt({\n\t\t\tcwd: \"$HOME/replay-fixtures\",\n\t\t\tcustomPrompt: \"You are an expert coding assistant operating inside Apex Code.\",\n\t\t\tselectedTools: selected.map((definition) => definition.name),\n\t\t\ttoolSnippets,\n\t\t\tpromptGuidelines,\n\t\t}),\n\t\ttools: selected.map((definition) => ({\n\t\t\tname: definition.name,\n\t\t\tdescription: definition.description,\n\t\t\tparameters: definition.parameters,\n\t\t})),\n\t};\n}\n\nexport async function replay(filePath: string): Promise<ReplayResult> {\n\tlet physicalLines: unknown[];\n\ttry {\n\t\tphysicalLines = readFileSync(filePath, \"utf8\")\n\t\t\t.split(\"\\n\")\n\t\t\t.filter((line) => line.trim().length > 0)\n\t\t\t.map((line) => JSON.parse(line));\n\t} catch (error) {\n\t\tthrow new Error(`Replay requires valid JSONL: ${filePath}`, { cause: error });\n\t}\n\tconst fileEntries = loadEntriesFromFile(filePath);\n\tif (physicalLines.length !== fileEntries.length) throw new Error(\"Replay session contains an invalid physical line\");\n\tif (!isVersionThreeHeader(fileEntries[0])) {\n\t\tthrow new Error(`Replay requires a native version 3 session: ${filePath}`);\n\t}\n\tconst rawEntries = fileEntries.slice(1);\n\tconst rawSessionEntries = rawEntries.filter(isSessionEntry);\n\tif (rawSessionEntries.length !== rawEntries.length) throw new Error(\"Replay session contains an invalid entry\");\n\tvalidateSessionTree(rawSessionEntries);\n\tconst sessionManager = SessionManager.open(filePath);\n\tconst entries = sessionManager.getBranch();\n\tvalidateSessionTree(entries);\n\tconst responses = selectedResponses(entries);\n\tconst recordedToolResults = selectedToolResults(entries);\n\tconst users = selectedUserEntries(entries);\n\tif (users.length === 0 || responses.length === 0)\n\t\tthrow new Error(\"Replay session must contain user and assistant messages\");\n\n\tconst runtime = await ModelRuntime.create({\n\t\tcredentials: AuthStorage.inMemory(),\n\t\tmodelsPath: null,\n\t\tmodelsStore: new InMemoryModelsStore(),\n\t\tallowModelNetwork: false,\n\t\trefreshOnCreate: false,\n\t});\n\tconst recorded = registerRecordedProvider(runtime, responses);\n\tconst recordedTools = createRecordedTools(toolCalls(responses), recordedToolResults);\n\tconst replayedResponses: AssistantMessage[] = [];\n\tconst replayedToolResults: ToolResultMessage[] = [];\n\tconst contextTokensByTurn: number[] = [];\n\tlet turnsCompleted = 0;\n\tconst promptBaseline = productionPromptAndSchemas(recordedTools.tools.map((tool) => tool.name));\n\tlet networkCalls = 0;\n\tconst rejectNetwork: typeof globalThis.fetch = async () => {\n\t\tnetworkCalls++;\n\t\tthrow new Error(\"Network access is disabled during replay\");\n\t};\n\tconst firstContext = buildSessionContext(entries, users[0]?.id);\n\tconst firstResponse = responses[0];\n\tif (!firstResponse) throw new Error(\"Replay session has no recorded response\");\n\tconst agent = new Agent({\n\t\tinitialState: {\n\t\t\tmodel: recorded.getModel(firstContext.model?.modelId ?? firstResponse.model),\n\t\t\tsystemPrompt: promptBaseline.systemPrompt,\n\t\t\ttools: recordedTools.tools,\n\t\t},\n\t\tstreamFn: (model, context, options) => runtime.streamSimple(model, context, { ...options, fetch: rejectNetwork }),\n\t\tgetApiKey: () => \"offline-replay\",\n\t\tconvertToLlm: (messages) => {\n\t\t\tconst converted: Message[] = [];\n\t\t\tfor (const message of messages) {\n\t\t\t\tif (message.role === \"user\") {\n\t\t\t\t\tconverted.push({ role: \"user\", content: message.content, timestamp: message.timestamp });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.role === \"assistant\") {\n\t\t\t\t\tconverted.push(message);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (message.role !== \"toolResult\") continue;\n\t\t\t\t// Validate the call id is one this replay actually recorded, but send the\n\t\t\t\t// *incoming* message — not a fresh lookup by id — so that whatever the\n\t\t\t\t// context pipeline's eviction stage did to `message.content` upstream\n\t\t\t\t// (in `transformContext`) is what reaches the provider request. Re-fetching\n\t\t\t\t// the original recorded content here would silently discard eviction,\n\t\t\t\t// since eviction never touches `recordedToolResults` itself (see\n\t\t\t\t// `assertToolResultsMatch`, which intentionally still compares against the\n\t\t\t\t// untouched recording).\n\t\t\t\tconst recordedResult = recordedToolResults.find((result) => result.toolCallId === message.toolCallId);\n\t\t\t\tif (!recordedResult) throw new Error(`Missing recorded tool result for ${message.toolCallId}`);\n\t\t\t\tconverted.push(structuredClone(message));\n\t\t\t}\n\t\t\treturn converted;\n\t\t},\n\t\tafterToolCall: async ({ toolCall }) => {\n\t\t\tconst result = recordedToolResults.find((candidate) => candidate.toolCallId === toolCall.id);\n\t\t\tif (!result) throw new Error(`Missing recorded tool result for ${toolCall.id}`);\n\t\t\treturn {\n\t\t\t\tcontent: structuredClone(result.content),\n\t\t\t\tdetails: result.details,\n\t\t\t\tusage: result.usage,\n\t\t\t\tisError: result.isError,\n\t\t\t};\n\t\t},\n\t\ttoolExecution: \"sequential\",\n\t});\n\n\t// Same pipeline `AgentSession` installs in production (`_installContextPipeline`\n\t// in `core/agent-session.ts`), via the shared `installContextPipeline` — deferred\n\t// -schema resolution ahead of every request, then tool-result eviction — so the\n\t// replay gate can observe both. The contract lookup is built from the real\n\t// production tool definitions; the budget is `REPLAY_EVICTION_BUDGET`, a\n\t// dedicated constant documented above (not derived from the fixture model's\n\t// `contextWindow`; see that constant's comment for why).\n\tinstallContextPipeline(agent, {\n\t\tcontractLookup: replayContractLookup(\"$HOME/replay-fixtures\"),\n\t\tevictionBudget: () => REPLAY_EVICTION_BUDGET,\n\t});\n\n\tconst contextsByTurn: Message[][] = [];\n\tfor (const user of users) {\n\t\tconst historical = buildSessionContext(entries, user.id);\n\t\tconst nextResponse = responses[recorded.requestCount];\n\t\tif (!nextResponse) throw new Error(`Missing recorded response for user turn ${contextTokensByTurn.length + 1}`);\n\t\tagent.state.model = recorded.getModel(historical.model?.modelId ?? nextResponse.model);\n\t\tagent.state.messages = historical.messages.slice(0, -1);\n\t\tconst requestStart = recorded.requestCount;\n\t\tawait agent.prompt(user.message);\n\t\tconst turnContexts = recorded.contexts.slice(requestStart);\n\t\tconst lastContext = turnContexts.at(-1);\n\t\tif (!lastContext) throw new Error(`User turn ${contextTokensByTurn.length + 1} made no provider request`);\n\t\tconst staticInputTokens = Math.ceil(\n\t\t\t`${promptBaseline.systemPrompt}\\n${JSON.stringify(promptBaseline.tools)}`.length / 4,\n\t\t);\n\t\tcontextTokensByTurn.push(\n\t\t\tstaticInputTokens + lastContext.messages.reduce((total, message) => total + estimateTokens(message), 0),\n\t\t);\n\t\t// Normalize toolResult timestamps to the recorded value before exposing this\n\t\t// turn's context, mirroring the same normalization the `toolResults` field\n\t\t// below already does and for the same reason: a toolResult's timestamp is\n\t\t// stamped live (via `agent.state.messages`) rather than replayed from the\n\t\t// fixture, so leaving it as-is would make `contextsByTurn` — and anything\n\t\t// that serializes it, like the determinism test below — flaky across runs.\n\t\t// Content (what eviction may have rewritten) is untouched.\n\t\tcontextsByTurn.push(\n\t\t\tlastContext.messages.map((message) =>\n\t\t\t\tmessage.role === \"toolResult\"\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...message,\n\t\t\t\t\t\t\ttimestamp:\n\t\t\t\t\t\t\t\trecordedToolResults.find((result) => result.toolCallId === message.toolCallId)?.timestamp ??\n\t\t\t\t\t\t\t\tmessage.timestamp,\n\t\t\t\t\t\t}\n\t\t\t\t\t: message,\n\t\t\t),\n\t\t);\n\t\tfor (const message of agent.state.messages.slice(historical.messages.length - 1)) {\n\t\t\tif (message.role === \"assistant\") replayedResponses.push(message);\n\t\t\tif (message.role === \"toolResult\") replayedToolResults.push(message);\n\t\t}\n\t\tconst terminalResponse = replayedResponses.at(-1);\n\t\tif (terminalResponse && terminalResponse.stopReason !== \"error\" && terminalResponse.stopReason !== \"aborted\") {\n\t\t\tturnsCompleted++;\n\t\t}\n\t}\n\trecorded.assertExhausted();\n\trecordedTools.assertExhausted();\n\tassertResponsesMatch(replayedResponses, responses);\n\tassertToolResultsMatch(replayedToolResults, recordedToolResults);\n\n\treturn {\n\t\tturns: users.length,\n\t\trequests: recorded.requestCount,\n\t\tnetworkCalls,\n\t\tresponses: replayedResponses,\n\t\ttoolResults: replayedToolResults.map((result, index) => ({\n\t\t\t...structuredClone(result),\n\t\t\ttimestamp: recordedToolResults[index]?.timestamp ?? result.timestamp,\n\t\t})),\n\t\tcontextsByTurn,\n\t\tmetrics: buildReplayMetrics({\n\t\t\tsystemPrompt: promptBaseline.systemPrompt,\n\t\t\ttools: promptBaseline.tools,\n\t\t\trecordedResponses: responses,\n\t\t\treplayedResponses,\n\t\t\tcontextTokensByTurn,\n\t\t\tturnsCompleted,\n\t\t}),\n\t};\n}\n\n/** Replay every JSONL fixture in lexical order for byte-stable corpus output. */\nexport async function replayCorpus(directory: string): Promise<Record<string, ReplayMetrics>> {\n\tconst metrics: Record<string, ReplayMetrics> = {};\n\tfor (const name of readdirSync(directory)\n\t\t.filter((entry) => entry.endsWith(\".jsonl\"))\n\t\t.sort()) {\n\t\tmetrics[name] = (await replay(join(directory, name))).metrics;\n\t}\n\treturn metrics;\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Apex Code brand mark, in the forms a terminal can actually render.
|
|
3
|
+
*
|
|
4
|
+
* Only the five-row block wordmark survives a monospace grid. Every monospace
|
|
5
|
+
* face leaves a hairline gap at the cell boundary, so a letterform two or three
|
|
6
|
+
* rows tall dissolves into texture rather than reading as a word. The mark
|
|
7
|
+
* therefore does not shrink: below the width the block form needs, it is
|
|
8
|
+
* replaced outright by a glyph-and-type lockup.
|
|
9
|
+
*
|
|
10
|
+
* A mark is a list of rows, each split into an accent run and a text run. That
|
|
11
|
+
* one shape covers both forms: the block wordmark puts its whole baseline row
|
|
12
|
+
* in the accent so the letters sit on an ember footing, and the inline lockup
|
|
13
|
+
* puts only its leading glyph there.
|
|
14
|
+
*/
|
|
15
|
+
export interface MarkRow {
|
|
16
|
+
/** Leading run, painted in the brand accent. */
|
|
17
|
+
readonly accent: string;
|
|
18
|
+
/** Trailing run, painted in the neutral text tone. */
|
|
19
|
+
readonly text: string;
|
|
20
|
+
}
|
|
21
|
+
export interface BrandMark {
|
|
22
|
+
readonly rows: readonly MarkRow[];
|
|
23
|
+
/** Widest row, in terminal columns. */
|
|
24
|
+
readonly width: number;
|
|
25
|
+
}
|
|
26
|
+
export type MarkSymbolPreset = "unicode" | "ascii";
|
|
27
|
+
/** 5 rows x 30 columns. The brand mark, with the baseline row in the accent. */
|
|
28
|
+
export declare const APEX_MARK_BLOCK: BrandMark;
|
|
29
|
+
/** 1 row x 11 columns. Used when the block mark will not fit. */
|
|
30
|
+
export declare const APEX_MARK_INLINE: BrandMark;
|
|
31
|
+
/**
|
|
32
|
+
* 1 row x 12 columns. Honours `terminal.symbolPreset: "ascii"`, whose users
|
|
33
|
+
* opted out of block drawing because it renders badly for them. The previous
|
|
34
|
+
* ASCII mark was line-drawn art whose first letter was an O, so it read "OPEX".
|
|
35
|
+
*/
|
|
36
|
+
export declare const APEX_MARK_INLINE_ASCII: BrandMark;
|
|
37
|
+
/** Pick the widest mark that fits. ASCII users always get the type lockup. */
|
|
38
|
+
export declare function selectBrandMark(contentWidth: number, symbolPreset: MarkSymbolPreset): BrandMark;
|
|
39
|
+
/** Wrap a mark supplied by a rebranding extension. It carries no accent run. */
|
|
40
|
+
export declare function customBrandMark(logo: string): BrandMark;
|
|
41
|
+
//# sourceMappingURL=apex-logo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apex-logo.d.ts","sourceRoot":"","sources":["../../src/themes/apex-logo.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,OAAO;IACvB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAAC;AAiBnD,gFAAgF;AAChF,eAAO,MAAM,eAAe,WAI3B,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,WAA8C,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,WAAgD,CAAC;AAEpF,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,GAAG,SAAS,CAG/F;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAEvD","sourcesContent":["import { visibleWidth } from \"@earendil-works/pi-tui\";\n\n/**\n * The Apex Code brand mark, in the forms a terminal can actually render.\n *\n * Only the five-row block wordmark survives a monospace grid. Every monospace\n * face leaves a hairline gap at the cell boundary, so a letterform two or three\n * rows tall dissolves into texture rather than reading as a word. The mark\n * therefore does not shrink: below the width the block form needs, it is\n * replaced outright by a glyph-and-type lockup.\n *\n * A mark is a list of rows, each split into an accent run and a text run. That\n * one shape covers both forms: the block wordmark puts its whole baseline row\n * in the accent so the letters sit on an ember footing, and the inline lockup\n * puts only its leading glyph there.\n */\n\nexport interface MarkRow {\n\t/** Leading run, painted in the brand accent. */\n\treadonly accent: string;\n\t/** Trailing run, painted in the neutral text tone. */\n\treadonly text: string;\n}\n\nexport interface BrandMark {\n\treadonly rows: readonly MarkRow[];\n\t/** Widest row, in terminal columns. */\n\treadonly width: number;\n}\n\nexport type MarkSymbolPreset = \"unicode\" | \"ascii\";\n\nfunction mark(rows: readonly MarkRow[]): BrandMark {\n\treturn {\n\t\trows,\n\t\twidth: rows.reduce((max, row) => Math.max(max, visibleWidth(row.accent + row.text)), 0),\n\t};\n}\n\nconst BLOCK_ROWS = [\n\t\" ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄ ▄▄\",\n\t\"██ ██ ██ ██ ██ ██ ██ \",\n\t\"███████ ██████ █████ ███ \",\n\t\"██ ██ ██ ██ ██ ██ \",\n\t\"▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀\",\n];\n\n/** 5 rows x 30 columns. The brand mark, with the baseline row in the accent. */\nexport const APEX_MARK_BLOCK = mark(\n\tBLOCK_ROWS.map((row, index) =>\n\t\tindex === BLOCK_ROWS.length - 1 ? { accent: row, text: \"\" } : { accent: \"\", text: row },\n\t),\n);\n\n/** 1 row x 11 columns. Used when the block mark will not fit. */\nexport const APEX_MARK_INLINE = mark([{ accent: \"◤\", text: \" apex code\" }]);\n\n/**\n * 1 row x 12 columns. Honours `terminal.symbolPreset: \"ascii\"`, whose users\n * opted out of block drawing because it renders badly for them. The previous\n * ASCII mark was line-drawn art whose first letter was an O, so it read \"OPEX\".\n */\nexport const APEX_MARK_INLINE_ASCII = mark([{ accent: \"/\\\\\", text: \" apex code\" }]);\n\n/** Pick the widest mark that fits. ASCII users always get the type lockup. */\nexport function selectBrandMark(contentWidth: number, symbolPreset: MarkSymbolPreset): BrandMark {\n\tif (symbolPreset === \"ascii\") return APEX_MARK_INLINE_ASCII;\n\treturn contentWidth >= APEX_MARK_BLOCK.width ? APEX_MARK_BLOCK : APEX_MARK_INLINE;\n}\n\n/** Wrap a mark supplied by a rebranding extension. It carries no accent run. */\nexport function customBrandMark(logo: string): BrandMark {\n\treturn mark(logo.split(\"\\n\").map((row) => ({ accent: \"\", text: row })));\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { visibleWidth } from "@earendil-works/pi-tui";
|
|
2
|
+
function mark(rows) {
|
|
3
|
+
return {
|
|
4
|
+
rows,
|
|
5
|
+
width: rows.reduce((max, row) => Math.max(max, visibleWidth(row.accent + row.text)), 0),
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
const BLOCK_ROWS = [
|
|
9
|
+
" ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄ ▄▄",
|
|
10
|
+
"██ ██ ██ ██ ██ ██ ██ ",
|
|
11
|
+
"███████ ██████ █████ ███ ",
|
|
12
|
+
"██ ██ ██ ██ ██ ██ ",
|
|
13
|
+
"▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀",
|
|
14
|
+
];
|
|
15
|
+
/** 5 rows x 30 columns. The brand mark, with the baseline row in the accent. */
|
|
16
|
+
export const APEX_MARK_BLOCK = mark(BLOCK_ROWS.map((row, index) => index === BLOCK_ROWS.length - 1 ? { accent: row, text: "" } : { accent: "", text: row }));
|
|
17
|
+
/** 1 row x 11 columns. Used when the block mark will not fit. */
|
|
18
|
+
export const APEX_MARK_INLINE = mark([{ accent: "◤", text: " apex code" }]);
|
|
19
|
+
/**
|
|
20
|
+
* 1 row x 12 columns. Honours `terminal.symbolPreset: "ascii"`, whose users
|
|
21
|
+
* opted out of block drawing because it renders badly for them. The previous
|
|
22
|
+
* ASCII mark was line-drawn art whose first letter was an O, so it read "OPEX".
|
|
23
|
+
*/
|
|
24
|
+
export const APEX_MARK_INLINE_ASCII = mark([{ accent: "/\\", text: " apex code" }]);
|
|
25
|
+
/** Pick the widest mark that fits. ASCII users always get the type lockup. */
|
|
26
|
+
export function selectBrandMark(contentWidth, symbolPreset) {
|
|
27
|
+
if (symbolPreset === "ascii")
|
|
28
|
+
return APEX_MARK_INLINE_ASCII;
|
|
29
|
+
return contentWidth >= APEX_MARK_BLOCK.width ? APEX_MARK_BLOCK : APEX_MARK_INLINE;
|
|
30
|
+
}
|
|
31
|
+
/** Wrap a mark supplied by a rebranding extension. It carries no accent run. */
|
|
32
|
+
export function customBrandMark(logo) {
|
|
33
|
+
return mark(logo.split("\n").map((row) => ({ accent: "", text: row })));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=apex-logo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apex-logo.js","sourceRoot":"","sources":["../../src/themes/apex-logo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAgCtD,SAAS,IAAI,CAAC,IAAwB,EAAa;IAClD,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;KACvF,CAAC;AAAA,CACF;AAED,MAAM,UAAU,GAAG;IAClB,0EAAgC;IAChC,4DAAgC;IAChC,0EAAgC;IAChC,wDAAgC;IAChC,gEAAgC;CAChC,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAClC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAC7B,KAAK,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CACvF,CACD,CAAC;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,KAAG,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAE5E;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAEpF,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAE,YAA8B,EAAa;IAChG,IAAI,YAAY,KAAK,OAAO;QAAE,OAAO,sBAAsB,CAAC;IAC5D,OAAO,YAAY,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC;AAAA,CAClF;AAED,gFAAgF;AAChF,MAAM,UAAU,eAAe,CAAC,IAAY,EAAa;IACxD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AAAA,CACxE","sourcesContent":["import { visibleWidth } from \"@earendil-works/pi-tui\";\n\n/**\n * The Apex Code brand mark, in the forms a terminal can actually render.\n *\n * Only the five-row block wordmark survives a monospace grid. Every monospace\n * face leaves a hairline gap at the cell boundary, so a letterform two or three\n * rows tall dissolves into texture rather than reading as a word. The mark\n * therefore does not shrink: below the width the block form needs, it is\n * replaced outright by a glyph-and-type lockup.\n *\n * A mark is a list of rows, each split into an accent run and a text run. That\n * one shape covers both forms: the block wordmark puts its whole baseline row\n * in the accent so the letters sit on an ember footing, and the inline lockup\n * puts only its leading glyph there.\n */\n\nexport interface MarkRow {\n\t/** Leading run, painted in the brand accent. */\n\treadonly accent: string;\n\t/** Trailing run, painted in the neutral text tone. */\n\treadonly text: string;\n}\n\nexport interface BrandMark {\n\treadonly rows: readonly MarkRow[];\n\t/** Widest row, in terminal columns. */\n\treadonly width: number;\n}\n\nexport type MarkSymbolPreset = \"unicode\" | \"ascii\";\n\nfunction mark(rows: readonly MarkRow[]): BrandMark {\n\treturn {\n\t\trows,\n\t\twidth: rows.reduce((max, row) => Math.max(max, visibleWidth(row.accent + row.text)), 0),\n\t};\n}\n\nconst BLOCK_ROWS = [\n\t\" ▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄ ▄▄ ▄▄\",\n\t\"██ ██ ██ ██ ██ ██ ██ \",\n\t\"███████ ██████ █████ ███ \",\n\t\"██ ██ ██ ██ ██ ██ \",\n\t\"▀▀ ▀▀ ▀▀ ▀▀▀▀▀▀ ▀▀ ▀▀\",\n];\n\n/** 5 rows x 30 columns. The brand mark, with the baseline row in the accent. */\nexport const APEX_MARK_BLOCK = mark(\n\tBLOCK_ROWS.map((row, index) =>\n\t\tindex === BLOCK_ROWS.length - 1 ? { accent: row, text: \"\" } : { accent: \"\", text: row },\n\t),\n);\n\n/** 1 row x 11 columns. Used when the block mark will not fit. */\nexport const APEX_MARK_INLINE = mark([{ accent: \"◤\", text: \" apex code\" }]);\n\n/**\n * 1 row x 12 columns. Honours `terminal.symbolPreset: \"ascii\"`, whose users\n * opted out of block drawing because it renders badly for them. The previous\n * ASCII mark was line-drawn art whose first letter was an O, so it read \"OPEX\".\n */\nexport const APEX_MARK_INLINE_ASCII = mark([{ accent: \"/\\\\\", text: \" apex code\" }]);\n\n/** Pick the widest mark that fits. ASCII users always get the type lockup. */\nexport function selectBrandMark(contentWidth: number, symbolPreset: MarkSymbolPreset): BrandMark {\n\tif (symbolPreset === \"ascii\") return APEX_MARK_INLINE_ASCII;\n\treturn contentWidth >= APEX_MARK_BLOCK.width ? APEX_MARK_BLOCK : APEX_MARK_INLINE;\n}\n\n/** Wrap a mark supplied by a rebranding extension. It carries no accent run. */\nexport function customBrandMark(logo: string): BrandMark {\n\treturn mark(logo.split(\"\\n\").map((row) => ({ accent: \"\", text: row })));\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apex-code-user-agent.d.ts","sourceRoot":"","sources":["../../src/utils/apex-code-user-agent.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAG5D","sourcesContent":["export function getApexCodeUserAgent(version: string): string {\n\tconst runtime = process.versions.bun ? `bun/${process.versions.bun}` : `node/${process.version}`;\n\treturn `apex-code/${version} (${process.platform}; ${runtime}; ${process.arch})`;\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function getApexCodeUserAgent(version) {
|
|
2
|
+
const runtime = process.versions.bun ? `bun/${process.versions.bun}` : `node/${process.version}`;
|
|
3
|
+
return `apex-code/${version} (${process.platform}; ${runtime}; ${process.arch})`;
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=apex-code-user-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apex-code-user-agent.js","sourceRoot":"","sources":["../../src/utils/apex-code-user-agent.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAU;IAC7D,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;IACjG,OAAO,aAAa,OAAO,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC;AAAA,CACjF","sourcesContent":["export function getApexCodeUserAgent(version: string): string {\n\tconst runtime = process.versions.bun ? `bun/${process.versions.bun}` : `node/${process.version}`;\n\treturn `apex-code/${version} (${process.platform}; ${runtime}; ${process.arch})`;\n}\n"]}
|
|
@@ -2,12 +2,15 @@ export interface ChangelogEntry {
|
|
|
2
2
|
major: number;
|
|
3
3
|
minor: number;
|
|
4
4
|
patch: number;
|
|
5
|
+
/** Prerelease identifier without the leading dash, e.g. "alpha.4". Absent on stable releases. */
|
|
6
|
+
prerelease?: string;
|
|
5
7
|
content: string;
|
|
6
8
|
}
|
|
7
9
|
export declare function normalizeChangelogLinks(markdown: string, version: string | ChangelogEntry): string;
|
|
8
10
|
/**
|
|
9
11
|
* Parse changelog entries from CHANGELOG.md
|
|
10
|
-
* Scans for ## lines and collects content until next ## or EOF
|
|
12
|
+
* Scans for ## lines and collects content until next ## or EOF.
|
|
13
|
+
* Stops at the upstream history heading — those entries are attribution, not Apex Code releases.
|
|
11
14
|
*/
|
|
12
15
|
export declare function parseChangelog(changelogPath: string): ChangelogEntry[];
|
|
13
16
|
/**
|
|
@@ -15,7 +18,9 @@ export declare function parseChangelog(changelogPath: string): ChangelogEntry[];
|
|
|
15
18
|
*/
|
|
16
19
|
export declare function compareVersions(v1: ChangelogEntry, v2: ChangelogEntry): number;
|
|
17
20
|
/**
|
|
18
|
-
* Get entries newer than lastVersion
|
|
21
|
+
* Get entries newer than lastVersion.
|
|
22
|
+
* An unparseable lastVersion yields nothing: replaying the entire changelog on every launch
|
|
23
|
+
* is a far worse failure than staying quiet about one upgrade.
|
|
19
24
|
*/
|
|
20
25
|
export declare function getNewEntries(entries: ChangelogEntry[], lastVersion: string): ChangelogEntry[];
|
|
21
26
|
export { getChangelogPath } from "../config.ts";
|