@north-light/crouter 0.3.318 → 0.3.320
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/README.md +0 -3
- package/dist/api/client.js +2 -912
- package/dist/api/dto/attach.js +0 -13
- package/dist/api/dto/bash-jobs.js +1 -9
- package/dist/api/dto/broker-ops.js +0 -6
- package/dist/api/dto/broker.js +0 -20
- package/dist/api/dto/canvas.js +0 -2
- package/dist/api/dto/chat-inventory.js +0 -11
- package/dist/api/dto/common.js +1 -15
- package/dist/api/dto/config.js +0 -3
- package/dist/api/dto/crons.js +1 -10
- package/dist/api/dto/files.js +0 -7
- package/dist/api/dto/focus.js +0 -10
- package/dist/api/dto/health.js +0 -2
- package/dist/api/dto/human-requests.js +0 -4
- package/dist/api/dto/human.js +0 -4
- package/dist/api/dto/inbox.js +0 -4
- package/dist/api/dto/lifecycle.js +0 -3
- package/dist/api/dto/mail.js +0 -1
- package/dist/api/dto/memory.js +0 -6
- package/dist/api/dto/messages.js +0 -2
- package/dist/api/dto/model-config.js +0 -1
- package/dist/api/dto/modelauth.js +0 -4
- package/dist/api/dto/node-outcomes.js +0 -2
- package/dist/api/dto/nodes.js +0 -3
- package/dist/api/dto/profiles.js +1 -4
- package/dist/api/dto/recovery.js +0 -1
- package/dist/api/dto/reports.js +0 -2
- package/dist/api/dto/review-comments.js +0 -5
- package/dist/api/dto/reviews.js +0 -5
- package/dist/api/dto/subscriptions.js +0 -2
- package/dist/api/dto/worktree.js +0 -6
- package/dist/api/errors.js +1 -40
- package/dist/api/index.js +1 -33
- package/dist/api/plugin-manifest-schema.js +0 -23
- package/dist/api/routes.js +1 -147
- package/dist/build-root.js +1 -198
- package/dist/cli.js +3 -99
- package/dist/clients/attach/ansi-cells.js +1 -137
- package/dist/clients/attach/chrome/bash-jobs.js +1 -31
- package/dist/clients/attach/chrome/canvas-panels.js +1 -194
- package/dist/clients/attach/chrome/completion-bell.js +1 -89
- package/dist/clients/attach/chrome/cron-wait.js +1 -34
- package/dist/clients/attach/chrome/git-info.js +2 -44
- package/dist/clients/attach/chrome/header.js +1 -30
- package/dist/clients/attach/chrome/inbox-strip.js +1 -199
- package/dist/clients/attach/chrome/recap.js +1 -19
- package/dist/clients/attach/chrome/review-wait.js +1 -22
- package/dist/clients/attach/chrome/roster.js +4 -275
- package/dist/clients/attach/chrome/status-line.js +1 -117
- package/dist/clients/attach/chrome/ticket-panel.js +1 -280
- package/dist/clients/attach/chrome/widgets.js +1 -51
- package/dist/clients/attach/command.js +1 -107
- package/dist/clients/attach/config.js +1 -274
- package/dist/clients/attach/input/capabilities.js +1 -104
- package/dist/clients/attach/input/clipboard-image.js +3 -220
- package/dist/clients/attach/input/completion-frecency.js +1 -141
- package/dist/clients/attach/input/controller.js +7 -377
- package/dist/clients/attach/input/overlay-owner.js +1 -199
- package/dist/clients/attach/input/ref-autocomplete.js +2 -176
- package/dist/clients/attach/input/titled-editor.js +4 -859
- package/dist/clients/attach/overlays/auth.js +2 -271
- package/dist/clients/attach/overlays/dialogs.js +2 -102
- package/dist/clients/attach/overlays/file-review.js +2 -128
- package/dist/clients/attach/overlays/graph.js +1 -661
- package/dist/clients/attach/overlays/help.js +1 -211
- package/dist/clients/attach/overlays/mcp.js +1 -302
- package/dist/clients/attach/overlays/pickers.js +1 -163
- package/dist/clients/attach/render/activity-slot.js +1 -13
- package/dist/clients/attach/render/assistant-message.js +1 -56
- package/dist/clients/attach/render/card-presentation.js +5 -218
- package/dist/clients/attach/render/chat-view.js +5 -1708
- package/dist/clients/attach/render/condensed-history.js +1 -60
- package/dist/clients/attach/render/context-message.js +1 -63
- package/dist/clients/attach/render/crtr-output.js +17 -905
- package/dist/clients/attach/render/diagram.js +7 -111
- package/dist/clients/attach/render/edit-diff.js +5 -304
- package/dist/clients/attach/render/glyph-codepoints.js +1 -42
- package/dist/clients/attach/render/group-activity.js +2 -263
- package/dist/clients/attach/render/group-recap.js +1 -152
- package/dist/clients/attach/render/markdown-source.js +5 -266
- package/dist/clients/attach/render/measured-container.js +1 -322
- package/dist/clients/attach/render/page-block.js +1 -183
- package/dist/clients/attach/render/scroll-animation.js +1 -80
- package/dist/clients/attach/render/tool-calls.js +3 -361
- package/dist/clients/attach/render/transcript-copy.js +2 -81
- package/dist/clients/attach/render/transcript-search.js +1 -152
- package/dist/clients/attach/render/viewport.js +1 -184
- package/dist/clients/attach/session/banner.js +1 -29
- package/dist/clients/attach/session/bindings.js +1 -71
- package/dist/clients/attach/session/chrome-refresh.js +1 -94
- package/dist/clients/attach/session/connection.js +1 -186
- package/dist/clients/attach/session/context.js +0 -16
- package/dist/clients/attach/session/editor-frame.js +1 -142
- package/dist/clients/attach/session/editor-inventory.js +6 -160
- package/dist/clients/attach/session/file-links.js +1 -68
- package/dist/clients/attach/session/focus-events.js +1 -12
- package/dist/clients/attach/session/frame.js +1 -214
- package/dist/clients/attach/session/frames.js +1 -188
- package/dist/clients/attach/session/identity.js +1 -26
- package/dist/clients/attach/session/input-wiring.js +1 -140
- package/dist/clients/attach/session/invariant.js +1 -15
- package/dist/clients/attach/session/keys.js +1 -77
- package/dist/clients/attach/session/layout.js +1 -59
- package/dist/clients/attach/session/mouse.js +1 -78
- package/dist/clients/attach/session/pane-focus.js +1 -42
- package/dist/clients/attach/session/pane-tag.js +1 -112
- package/dist/clients/attach/session/pi-assets.js +1 -24
- package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
- package/dist/clients/attach/session/profile-files.js +1 -228
- package/dist/clients/attach/session/reconnect.js +1 -175
- package/dist/clients/attach/session/selection.js +3 -108
- package/dist/clients/attach/session/state-sync.js +1 -67
- package/dist/clients/attach/session/surface-frame.js +1 -73
- package/dist/clients/attach/session/surface-host.js +1 -255
- package/dist/clients/attach/session/teardown.js +5 -94
- package/dist/clients/attach/session/transcript-search.js +3 -151
- package/dist/clients/attach/session/whip-achievements.js +2 -145
- package/dist/clients/attach/session/whip.js +1 -362
- package/dist/clients/attach/slash/dispatch.js +1 -706
- package/dist/clients/attach/slash/prompt-preview.js +1 -121
- package/dist/clients/attach/viewer.js +441 -441
- package/dist/clients/conversation/projection.js +1 -324
- package/dist/clients/conversation/submit.js +1 -51
- package/dist/clients/inbox/controller.js +1 -701
- package/dist/clients/inbox/dto-adapt.js +1 -93
- package/dist/clients/inbox/layout.js +1 -9
- package/dist/clients/inbox/page-adapter.js +1 -55
- package/dist/clients/inbox/resolve.js +1 -35
- package/dist/clients/inbox/review/anchors.js +1 -89
- package/dist/clients/inbox/review/comments-client.js +1 -98
- package/dist/clients/inbox/review/companion-pane.js +1 -82
- package/dist/clients/inbox/review/document-surface.js +2 -1188
- package/dist/clients/inbox/review/frame.js +1 -216
- package/dist/clients/inbox/review/keys.js +1 -123
- package/dist/clients/inbox/review/launch.js +1 -151
- package/dist/clients/inbox/review/live-source.js +1 -160
- package/dist/clients/inbox/review/nvim.js +1 -44
- package/dist/clients/inbox/review/remap.js +1 -157
- package/dist/clients/inbox/review/review-client.js +1 -123
- package/dist/clients/inbox/review/roundtrip.js +3 -36
- package/dist/clients/inbox/review/state.js +4 -315
- package/dist/clients/inbox/review-adapter.js +1 -43
- package/dist/clients/inbox/surface.js +1 -152
- package/dist/clients/inbox/tui/ansi.js +3 -321
- package/dist/clients/inbox/tui/input.js +5 -392
- package/dist/clients/inbox/tui/keys.js +1 -104
- package/dist/clients/inbox/tui/page-body.js +1 -66
- package/dist/clients/inbox/tui/panel.js +1 -84
- package/dist/clients/inbox/tui/render.js +2 -368
- package/dist/clients/inbox/tui/slots.js +3 -134
- package/dist/clients/inbox/tui/types.js +0 -1
- package/dist/clients/inbox/tui.js +1 -86
- package/dist/clients/surfaces/host.js +0 -1
- package/dist/commands/api-client.js +4 -290
- package/dist/commands/attention.js +1 -215
- package/dist/commands/canvas-browse.js +1 -70
- package/dist/commands/canvas-config.js +2 -192
- package/dist/commands/canvas-history/grep.js +7 -85
- package/dist/commands/canvas-history/read.js +3 -50
- package/dist/commands/canvas-history/search.js +10 -99
- package/dist/commands/canvas-history/shared.js +1 -139
- package/dist/commands/canvas-history/stats.js +6 -68
- package/dist/commands/canvas-history.js +1 -32
- package/dist/commands/canvas-issue.js +14 -149
- package/dist/commands/canvas-prune.js +1 -108
- package/dist/commands/canvas-roster.js +1 -69
- package/dist/commands/canvas-snapshot.js +1 -34
- package/dist/commands/canvas-use.js +1 -61
- package/dist/commands/canvas.js +1 -49
- package/dist/commands/chord.js +1 -241
- package/dist/commands/cron.js +11 -534
- package/dist/commands/dashboard.js +1 -85
- package/dist/commands/human/components.js +3 -77
- package/dist/commands/human/feedback.js +1 -112
- package/dist/commands/human/prompts.js +1 -331
- package/dist/commands/human/queue.js +1 -191
- package/dist/commands/human/request.js +1 -266
- package/dist/commands/human/review.js +1 -288
- package/dist/commands/human/shared.js +1 -67
- package/dist/commands/human.js +4 -60
- package/dist/commands/memory/delete.js +1 -100
- package/dist/commands/memory/edit.js +21 -219
- package/dist/commands/memory/find.js +2 -244
- package/dist/commands/memory/history.js +5 -199
- package/dist/commands/memory/lint.js +1 -107
- package/dist/commands/memory/list.js +1 -142
- package/dist/commands/memory/move.js +1 -223
- package/dist/commands/memory/origin.js +1 -130
- package/dist/commands/memory/read.js +6 -232
- package/dist/commands/memory/shared.js +12 -802
- package/dist/commands/memory/write.js +13 -235
- package/dist/commands/memory.js +1 -30
- package/dist/commands/node/bash.js +5 -245
- package/dist/commands/node/create.js +3 -332
- package/dist/commands/node/inspect.js +12 -300
- package/dist/commands/node/lifecycle.js +2 -453
- package/dist/commands/node/message.js +1 -161
- package/dist/commands/node/outcome.js +4 -134
- package/dist/commands/node/pyramid.js +2 -79
- package/dist/commands/node/subscription.js +1 -78
- package/dist/commands/node/wait.js +7 -163
- package/dist/commands/node-context.js +2 -159
- package/dist/commands/node-inspect-artifacts.js +8 -109
- package/dist/commands/node-lifecycle-revive.js +1 -217
- package/dist/commands/node-snapshot.js +1 -37
- package/dist/commands/node-transcript.js +1 -62
- package/dist/commands/node-worktree.js +1 -138
- package/dist/commands/node.js +1 -29
- package/dist/commands/pkg/browse/actions.js +1 -198
- package/dist/commands/pkg/browse/catalog.js +1 -466
- package/dist/commands/pkg/browse/command-view.js +1 -191
- package/dist/commands/pkg/browse/detail-panel.js +1 -402
- package/dist/commands/pkg/browse/doc-view.js +1 -89
- package/dist/commands/pkg/browse/list-panel.js +2 -168
- package/dist/commands/pkg/browse/model.js +1 -36
- package/dist/commands/pkg/browse/shell.js +1 -640
- package/dist/commands/pkg/browse.js +1 -27
- package/dist/commands/pkg/market-inspect.js +1 -141
- package/dist/commands/pkg/market-manage.js +1 -327
- package/dist/commands/pkg/market.js +1 -14
- package/dist/commands/pkg/plugin-inspect.js +1 -168
- package/dist/commands/pkg/plugin-manage.js +17 -1109
- package/dist/commands/pkg/plugin.js +1 -14
- package/dist/commands/pkg/shared.js +1 -62
- package/dist/commands/pkg.js +1 -21
- package/dist/commands/profile/default.js +1 -139
- package/dist/commands/profile/delete.js +1 -66
- package/dist/commands/profile/env.js +3 -188
- package/dist/commands/profile/kind.js +2 -35
- package/dist/commands/profile/list.js +1 -43
- package/dist/commands/profile/meta.js +1 -67
- package/dist/commands/profile/new.js +1 -115
- package/dist/commands/profile/pause.js +1 -59
- package/dist/commands/profile/project.js +1 -113
- package/dist/commands/profile/rename.js +1 -38
- package/dist/commands/profile/show.js +1 -52
- package/dist/commands/profile.js +1 -35
- package/dist/commands/push.js +9 -265
- package/dist/commands/revive.js +10 -181
- package/dist/commands/surface/node/cycle.js +1 -83
- package/dist/commands/surface/node/focus.js +1 -81
- package/dist/commands/surface/node/id.js +1 -38
- package/dist/commands/surface/node/pin.js +1 -42
- package/dist/commands/surface/node/placement.js +1 -134
- package/dist/commands/surface-edit.js +1 -157
- package/dist/commands/surface-inbox.js +1 -98
- package/dist/commands/surface-inspect.js +1 -39
- package/dist/commands/surface-node.js +1 -19
- package/dist/commands/surface-reload.js +2 -134
- package/dist/commands/surface-tmux-spread.js +1 -214
- package/dist/commands/surface.js +1 -28
- package/dist/commands/sys/branch.js +1 -19
- package/dist/commands/sys/config.js +1 -353
- package/dist/commands/sys/context/admin/actions.js +2 -246
- package/dist/commands/sys/context/admin/detail-panel.js +1 -247
- package/dist/commands/sys/context/admin/docs-panel.js +1 -191
- package/dist/commands/sys/context/admin/list-view.js +1 -183
- package/dist/commands/sys/context/admin/model.js +1 -229
- package/dist/commands/sys/context/admin/rail-panel.js +1 -227
- package/dist/commands/sys/context/admin/read-view.js +2 -194
- package/dist/commands/sys/context/admin/shell.js +1 -910
- package/dist/commands/sys/context/admin.js +2 -126
- package/dist/commands/sys/context/doc.js +3 -197
- package/dist/commands/sys/context/prompt-review.js +11 -291
- package/dist/commands/sys/context/resolve.js +10 -489
- package/dist/commands/sys/context/sysprompt.js +5 -96
- package/dist/commands/sys/context.js +1 -20
- package/dist/commands/sys/daemon.js +1 -313
- package/dist/commands/sys/doctor.js +1 -617
- package/dist/commands/sys/feedback.js +7 -228
- package/dist/commands/sys/logs.js +3 -129
- package/dist/commands/sys/migrate.js +1 -94
- package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
- package/dist/commands/sys/panels/dependencies-panel.js +1 -80
- package/dist/commands/sys/panels/keybindings-panel.js +1 -703
- package/dist/commands/sys/panels/models-panel.js +1 -1133
- package/dist/commands/sys/panels/plugins-panel.js +1 -80
- package/dist/commands/sys/panels/prefs-panel.js +1 -85
- package/dist/commands/sys/panels/profiles-panel.js +1 -601
- package/dist/commands/sys/panels/provider-panel.js +1 -538
- package/dist/commands/sys/settings-shell.js +1 -400
- package/dist/commands/sys/settings.js +1 -46
- package/dist/commands/sys/setup-core.js +6 -579
- package/dist/commands/sys/setup-settings-runner.js +1 -16
- package/dist/commands/sys/setup-wizard.js +1 -279
- package/dist/commands/sys/setup.js +1 -34
- package/dist/commands/sys/shared.js +1 -81
- package/dist/commands/sys/support/prepare.js +3 -239
- package/dist/commands/sys/support/submit.js +6 -524
- package/dist/commands/sys/support.js +1 -18
- package/dist/commands/sys/sync-deps.js +15 -498
- package/dist/commands/sys/sync-project-guidance.js +4 -481
- package/dist/commands/sys/sync-shared.js +1 -49
- package/dist/commands/sys/sync-skills.js +2 -311
- package/dist/commands/sys/sync.js +1 -18
- package/dist/commands/sys/update.js +1 -147
- package/dist/commands/sys/worktrees.js +5 -53
- package/dist/commands/sys.js +1 -18
- package/dist/core/activity-signal.js +2 -38
- package/dist/core/asset-root.js +1 -18
- package/dist/core/auth-file.js +2 -179
- package/dist/core/auth-interaction.js +3 -94
- package/dist/core/auto-update.js +4 -94
- package/dist/core/bash-guard.js +11 -393
- package/dist/core/bash-jobs.js +7 -411
- package/dist/core/bootstrap.js +2 -53
- package/dist/core/broker-client/client.js +1 -184
- package/dist/core/broker-client/index.js +1 -13
- package/dist/core/broker-client/transport-relay.js +1 -157
- package/dist/core/broker-client/transport-socket.js +1 -179
- package/dist/core/broker-client/transport.js +1 -26
- package/dist/core/canvas/attention.js +1 -47
- package/dist/core/canvas/boot-id.js +1 -26
- package/dist/core/canvas/boot.js +1 -186
- package/dist/core/canvas/browse/app.js +3 -919
- package/dist/core/canvas/browse/model.js +1 -477
- package/dist/core/canvas/browse/pins.js +1 -29
- package/dist/core/canvas/browse/render.js +3 -1055
- package/dist/core/canvas/canvas.js +15 -922
- package/dist/core/canvas/crons.js +11 -481
- package/dist/core/canvas/daemon-owner.js +2 -146
- package/dist/core/canvas/db.js +2 -100
- package/dist/core/canvas/deliveries.js +22 -283
- package/dist/core/canvas/delivery-contract.js +1 -8
- package/dist/core/canvas/executions.js +1 -68
- package/dist/core/canvas/extensions.js +1 -83
- package/dist/core/canvas/focuses.js +1 -77
- package/dist/core/canvas/history.js +24 -860
- package/dist/core/canvas/index.js +1 -15
- package/dist/core/canvas/install-id.js +1 -84
- package/dist/core/canvas/labels.js +1 -43
- package/dist/core/canvas/meta-file.js +1 -89
- package/dist/core/canvas/migrations.js +41 -1150
- package/dist/core/canvas/nav-model.js +1 -231
- package/dist/core/canvas/nav-render.js +1 -260
- package/dist/core/canvas/node-order.js +1 -37
- package/dist/core/canvas/node-recap.js +2 -67
- package/dist/core/canvas/node-sql-migration.js +2 -209
- package/dist/core/canvas/paths.js +1 -153
- package/dist/core/canvas/pid.js +4 -683
- package/dist/core/canvas/recovery.js +3 -565
- package/dist/core/canvas/remote-canvas-source.js +1 -288
- package/dist/core/canvas/remote-transport.js +1 -57
- package/dist/core/canvas/render-source.js +10 -635
- package/dist/core/canvas/sessions.js +1 -78
- package/dist/core/canvas/source.js +1 -47
- package/dist/core/canvas/status-glyph.js +1 -132
- package/dist/core/canvas/telemetry.js +1 -35
- package/dist/core/canvas/types.js +1 -6
- package/dist/core/canvas/waits.js +4 -68
- package/dist/core/canvas/worktrees.js +1 -93
- package/dist/core/clipboard-text.js +1 -57
- package/dist/core/command-hooks/artifact.js +1 -145
- package/dist/core/command-hooks/catalog.js +1 -38
- package/dist/core/command-hooks/compose.js +1 -99
- package/dist/core/command-hooks/discovery.js +1 -228
- package/dist/core/command-hooks/help.js +1 -18
- package/dist/core/command-hooks/index.js +1 -7
- package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
- package/dist/core/command-hooks/lifecycle-create.js +1 -51
- package/dist/core/command-hooks/report.js +1 -28
- package/dist/core/command-hooks/schema.js +1 -157
- package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
- package/dist/core/command-manifests/manifest.js +1 -324
- package/dist/core/command-manifests/registry.js +1 -118
- package/dist/core/command-manifests/schema.js +1 -736
- package/dist/core/command-plugins/bundle.js +1 -261
- package/dist/core/command-plugins/compose.js +1 -65
- package/dist/core/command-plugins/discovery.js +1 -245
- package/dist/core/command-plugins/endpoint.js +1 -48
- package/dist/core/command-plugins/extensions.js +1 -166
- package/dist/core/command-plugins/help-addenda.js +1 -44
- package/dist/core/command-plugins/presence.js +1 -17
- package/dist/core/command-plugins/revalidate.js +2 -152
- package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
- package/dist/core/command-plugins/transport/http-fetch.js +1 -68
- package/dist/core/command-plugins/transport/http-invoke.js +3 -546
- package/dist/core/command.js +10 -739
- package/dist/core/config.js +1 -1059
- package/dist/core/document-lines.js +3 -6
- package/dist/core/env-name.js +1 -9
- package/dist/core/errors.js +1 -52
- package/dist/core/events/emit.js +1 -17
- package/dist/core/events/envelope.js +1 -84
- package/dist/core/events/errors.js +1 -69
- package/dist/core/events/index.js +1 -4
- package/dist/core/events/operation-id.js +1 -24
- package/dist/core/events/read.js +1 -623
- package/dist/core/events/serialize.js +1 -199
- package/dist/core/events/source.js +1 -31
- package/dist/core/events/types.js +1 -11
- package/dist/core/exclusive-lock.js +1 -197
- package/dist/core/fault-classifier.js +1 -96
- package/dist/core/feed/feed.js +7 -202
- package/dist/core/feed/inbox-migrate.js +3 -135
- package/dist/core/feed/inbox.js +10 -122
- package/dist/core/feed/messages.js +6 -212
- package/dist/core/frontmatter.js +1 -35
- package/dist/core/fs-utils.js +3 -202
- package/dist/core/git.js +2 -103
- package/dist/core/help.js +9 -310
- package/dist/core/host-exports/builtins.js +9 -68
- package/dist/core/host-exports/export.js +3 -124
- package/dist/core/human/action-binding.js +1 -40
- package/dist/core/human/answer-text.js +5 -100
- package/dist/core/human/answer.js +1 -119
- package/dist/core/human/claim.js +3 -67
- package/dist/core/human/completion.js +1 -27
- package/dist/core/human/component-docs.js +78 -272
- package/dist/core/human/convention.js +2 -82
- package/dist/core/human/feedback-companion.js +1 -106
- package/dist/core/human/feedback.js +1 -88
- package/dist/core/human/page-authoring.js +1 -19
- package/dist/core/human/page-catalog.js +1 -172
- package/dist/core/human/page-errors.js +1 -7
- package/dist/core/human/page-eval.js +1 -125
- package/dist/core/human/page-html-markdown.js +8 -260
- package/dist/core/human/page-markdown.js +17 -295
- package/dist/core/human/page-schema.js +1 -373
- package/dist/core/human/page-synth.js +8 -27
- package/dist/core/human/page.js +1 -198
- package/dist/core/human/requests.js +15 -466
- package/dist/core/human/review-schema.js +1 -34
- package/dist/core/human/root.js +1 -11
- package/dist/core/human/scan.js +1 -69
- package/dist/core/human/summary.js +1 -5
- package/dist/core/human/tickets.js +1 -171
- package/dist/core/human/types.js +0 -1
- package/dist/core/human/visible-paths.js +1 -77
- package/dist/core/human-actions.js +1 -101
- package/dist/core/inspector/chrome.js +1 -14
- package/dist/core/inspector/contract.js +0 -1
- package/dist/core/inspector/core.js +2 -295
- package/dist/core/inspector/host.js +4 -538
- package/dist/core/inspector/model.js +2 -226
- package/dist/core/inspector/text.js +6 -45
- package/dist/core/inspector/transport.js +1 -36
- package/dist/core/inspector/tui.js +2 -295
- package/dist/core/installed-plugins.js +1 -78
- package/dist/core/io.js +7 -356
- package/dist/core/keybindings/attach-control.js +1 -42
- package/dist/core/keybindings/background-bash.js +1 -33
- package/dist/core/keybindings/catalog.js +1 -256
- package/dist/core/keybindings/inbox.js +1 -25
- package/dist/core/keybindings/index.js +1 -7
- package/dist/core/keybindings/match.js +1 -127
- package/dist/core/keybindings/persistence.js +1 -49
- package/dist/core/keybindings/resolve.js +1 -348
- package/dist/core/keybindings/types.js +0 -1
- package/dist/core/locked-file.js +1 -118
- package/dist/core/log.js +3 -27
- package/dist/core/manifest-recovery.js +1 -72
- package/dist/core/manifest-stale.js +1 -39
- package/dist/core/manifest.js +1 -20
- package/dist/core/memory/doc-link-grammar.js +2 -109
- package/dist/core/memory/extensions.js +1 -221
- package/dist/core/memory/history.js +6 -268
- package/dist/core/memory/identity.js +1 -181
- package/dist/core/memory/inline-ref-grammar.js +1 -98
- package/dist/core/memory/inline-ref-guidance.js +2 -35
- package/dist/core/memory/inline-ref-inventory.js +1 -59
- package/dist/core/memory/lint.js +2 -671
- package/dist/core/memory/project-namespace.js +2 -85
- package/dist/core/memory/repository-association.js +1 -129
- package/dist/core/memory/tree.js +1 -93
- package/dist/core/memory-resolver.js +2 -611
- package/dist/core/model-config.js +1 -107
- package/dist/core/model-routes.js +1 -201
- package/dist/core/nested-stores.js +2 -166
- package/dist/core/output.js +7 -99
- package/dist/core/pagination.js +1 -88
- package/dist/core/plugin-swap-lock.js +1 -31
- package/dist/core/pool-credential-store.js +1 -116
- package/dist/core/predicate.js +1 -191
- package/dist/core/preview-registry.js +2 -411
- package/dist/core/preview-result-path.js +1 -26
- package/dist/core/profiles/default-binding.js +1 -24
- package/dist/core/profiles/deletion-reservation.js +1 -42
- package/dist/core/profiles/env-store.js +2 -162
- package/dist/core/profiles/fuzzy-match.js +1 -92
- package/dist/core/profiles/manifest.js +1 -574
- package/dist/core/profiles/select.js +35 -741
- package/dist/core/profiles/state-block.js +3 -17
- package/dist/core/provider-error-recognition.js +1 -74
- package/dist/core/provider-failure.js +1 -86
- package/dist/core/provider-management.js +1 -22
- package/dist/core/remote-canvas-target.js +1 -30
- package/dist/core/render.js +18 -138
- package/dist/core/resolver.js +1 -111
- package/dist/core/review/birth.js +1 -52
- package/dist/core/review/comments.js +5 -279
- package/dist/core/review/companion.js +1 -215
- package/dist/core/review/document.js +2 -138
- package/dist/core/review/project.js +1 -36
- package/dist/core/review/realize.js +1 -71
- package/dist/core/review/remap.js +4 -141
- package/dist/core/review/signal.js +1 -12
- package/dist/core/review/stage.js +1 -184
- package/dist/core/review/store.js +1 -168
- package/dist/core/review/types.js +1 -23
- package/dist/core/runtime/advertised-command-invocation.js +1 -233
- package/dist/core/runtime/auth-reload.js +1 -67
- package/dist/core/runtime/banner.js +1 -51
- package/dist/core/runtime/bearings-render.js +18 -250
- package/dist/core/runtime/bearings.js +7 -194
- package/dist/core/runtime/bin-contributions.js +2 -186
- package/dist/core/runtime/boot-root.js +1 -107
- package/dist/core/runtime/branded-host.js +2 -264
- package/dist/core/runtime/broker/auth-reload.js +1 -157
- package/dist/core/runtime/broker/client-registry.js +1 -179
- package/dist/core/runtime/broker/daemon-ops.js +1 -88
- package/dist/core/runtime/broker/engine-drive.js +1 -354
- package/dist/core/runtime/broker/engine-routing.js +1 -211
- package/dist/core/runtime/broker/event-projection.js +1 -193
- package/dist/core/runtime/broker/extension-abort.js +1 -36
- package/dist/core/runtime/broker/fault-retry.js +1 -588
- package/dist/core/runtime/broker/frame-client.js +1 -132
- package/dist/core/runtime/broker/frame-dispatch.js +1 -183
- package/dist/core/runtime/broker/frame-engine-control.js +1 -231
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
- package/dist/core/runtime/broker/frame-model-query.js +1 -69
- package/dist/core/runtime/broker/frame-read.js +1 -116
- package/dist/core/runtime/broker/frame-replies.js +1 -64
- package/dist/core/runtime/broker/frame-session.js +4 -203
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
- package/dist/core/runtime/broker/inbox.js +13 -163
- package/dist/core/runtime/broker/node-named.js +1 -27
- package/dist/core/runtime/broker/read-ops.js +1 -171
- package/dist/core/runtime/broker/rebind.js +1 -318
- package/dist/core/runtime/broker/tool-groups.js +1 -246
- package/dist/core/runtime/broker/turn-admission.js +1 -31
- package/dist/core/runtime/broker/turn-ignition.js +1 -84
- package/dist/core/runtime/broker-cli.js +3 -81
- package/dist/core/runtime/broker-extension-render.js +5 -135
- package/dist/core/runtime/broker-inventory.js +1 -116
- package/dist/core/runtime/broker-persona-guidance.js +4 -154
- package/dist/core/runtime/broker-protocol.js +3 -152
- package/dist/core/runtime/broker-request.js +1 -85
- package/dist/core/runtime/broker-sdk.js +1 -129
- package/dist/core/runtime/broker.js +1 -1214
- package/dist/core/runtime/canvas-extensions.js +1 -96
- package/dist/core/runtime/chat-inventory-rows.js +1 -105
- package/dist/core/runtime/close.js +1 -265
- package/dist/core/runtime/command-expansion.js +9 -104
- package/dist/core/runtime/command-surface.js +1 -117
- package/dist/core/runtime/connectivity.js +1 -73
- package/dist/core/runtime/deliver-live.js +1 -88
- package/dist/core/runtime/fault-recovery.js +1 -83
- package/dist/core/runtime/fault.js +1 -17
- package/dist/core/runtime/fleet.js +1 -58
- package/dist/core/runtime/front-door-env.js +1 -16
- package/dist/core/runtime/front-door.js +7 -183
- package/dist/core/runtime/headless-pi.js +1 -161
- package/dist/core/runtime/host.js +1 -457
- package/dist/core/runtime/interactive-deliver.js +1 -51
- package/dist/core/runtime/invocation.js +0 -10
- package/dist/core/runtime/kickoff.js +30 -327
- package/dist/core/runtime/launch-config-worker.js +1 -12
- package/dist/core/runtime/launch-prompt.js +4 -13
- package/dist/core/runtime/launch-target.js +1 -55
- package/dist/core/runtime/launch.js +1 -483
- package/dist/core/runtime/lifecycle.js +2 -213
- package/dist/core/runtime/managed-provider-cooling.js +1 -62
- package/dist/core/runtime/memory.js +1 -17
- package/dist/core/runtime/model-registry.js +1 -13
- package/dist/core/runtime/model-selection.js +1 -135
- package/dist/core/runtime/model-swap.js +1 -86
- package/dist/core/runtime/naming.js +14 -298
- package/dist/core/runtime/nerd-font.js +2 -127
- package/dist/core/runtime/node-read.js +2 -386
- package/dist/core/runtime/nodes.js +1 -331
- package/dist/core/runtime/outcome-document.js +1 -97
- package/dist/core/runtime/package-health.js +4 -99
- package/dist/core/runtime/persona.js +2 -55
- package/dist/core/runtime/pi-cli.js +1 -65
- package/dist/core/runtime/pi-vendored.js +1 -66
- package/dist/core/runtime/placement-tmux.js +1 -81
- package/dist/core/runtime/placement.js +1 -386
- package/dist/core/runtime/promote.js +1 -174
- package/dist/core/runtime/prospective-inventory-cli.js +3 -61
- package/dist/core/runtime/prospective-inventory.js +2 -88
- package/dist/core/runtime/recap.js +27 -103
- package/dist/core/runtime/recycle.js +1 -190
- package/dist/core/runtime/reopen.js +1 -138
- package/dist/core/runtime/reset.js +1 -245
- package/dist/core/runtime/resume-root.js +10 -290
- package/dist/core/runtime/revive-all.js +1 -107
- package/dist/core/runtime/revive.js +4 -544
- package/dist/core/runtime/roadmap.js +4 -38
- package/dist/core/runtime/session-branch.js +1 -46
- package/dist/core/runtime/session-cycles.js +1 -110
- package/dist/core/runtime/session-list-cache.js +1 -406
- package/dist/core/runtime/session-visibility.js +1 -99
- package/dist/core/runtime/shell-expansion.js +9 -100
- package/dist/core/runtime/situational-context.js +2 -67
- package/dist/core/runtime/situational-live.js +1 -41
- package/dist/core/runtime/spawn-env.js +1 -255
- package/dist/core/runtime/spawn.js +3 -577
- package/dist/core/runtime/stamp/channel.js +1 -76
- package/dist/core/runtime/stamp/protocol.js +1 -113
- package/dist/core/runtime/stop-guard.js +7 -116
- package/dist/core/runtime/stop-signals.js +1 -46
- package/dist/core/runtime/stream-watchdog.js +1 -134
- package/dist/core/runtime/structured-output.js +4 -156
- package/dist/core/runtime/surface-bg.js +1 -85
- package/dist/core/runtime/tmux-bindings.js +4 -730
- package/dist/core/runtime/tmux-chrome.js +1 -5
- package/dist/core/runtime/tmux-driver.js +7 -637
- package/dist/core/runtime/tool-group-summary.js +6 -85
- package/dist/core/runtime/turn-visibility.js +1 -31
- package/dist/core/runtime/view-socket.js +1 -83
- package/dist/core/runtime/warm-pool.js +1 -395
- package/dist/core/scope.js +1 -254
- package/dist/core/scoped-state/db.js +1 -135
- package/dist/core/scoped-state/migrate.js +3 -181
- package/dist/core/scoped-state/paths.js +1 -27
- package/dist/core/scoped-state/profiles.js +1 -62
- package/dist/core/scoped-state/providers.js +1 -8
- package/dist/core/scoped-state/schema.js +3 -16
- package/dist/core/scoped-state/settings.js +1 -82
- package/dist/core/secrets.js +2 -55
- package/dist/core/self-update.js +1 -71
- package/dist/core/session-model/session-state.js +1 -180
- package/dist/core/shell-segments.js +4 -169
- package/dist/core/spawn.js +1 -26
- package/dist/core/stdout-errors.js +1 -14
- package/dist/core/subscription-state.js +3 -193
- package/dist/core/substrate/frontmatter-validation.js +1 -105
- package/dist/core/substrate/gate-explain.js +1 -424
- package/dist/core/substrate/gate.js +1 -26
- package/dist/core/substrate/index.js +1 -30
- package/dist/core/substrate/injected-store.js +1 -249
- package/dist/core/substrate/listings.js +1 -115
- package/dist/core/substrate/on-read-node.js +1 -36
- package/dist/core/substrate/on-read.js +9 -315
- package/dist/core/substrate/plan.js +1 -266
- package/dist/core/substrate/render-node.js +1 -30
- package/dist/core/substrate/render.js +65 -689
- package/dist/core/substrate/schema.js +1 -186
- package/dist/core/substrate/session-cache.js +1 -83
- package/dist/core/substrate/subject-fields.js +1 -35
- package/dist/core/substrate/subject.js +1 -47
- package/dist/core/substrate/surface-match.js +1 -242
- package/dist/core/termrender/code-doc.js +5 -92
- package/dist/core/termrender/display.js +2 -56
- package/dist/core/termrender/termrender.js +14 -719
- package/dist/core/termrender/version.js +1 -1
- package/dist/core/timing.js +2 -94
- package/dist/core/tui/draw.js +2 -378
- package/dist/core/tui/fuzzy.js +1 -38
- package/dist/core/tui/markdown.js +3 -407
- package/dist/core/tui/page-host.js +1 -74
- package/dist/core/tui/panel.js +1 -137
- package/dist/core/tui/terminal.js +2 -100
- package/dist/core/user-settings.js +1 -454
- package/dist/core/wake.js +1 -296
- package/dist/core/worktree-close.js +6 -228
- package/dist/core/worktree-containment.js +3 -48
- package/dist/core/worktree-landing.js +4 -56
- package/dist/core/worktree-mutation-async.js +10 -280
- package/dist/core/worktree-quarantine.js +1 -54
- package/dist/core/worktree-sweep.js +6 -453
- package/dist/core/worktree.js +18 -899
- package/dist/daemon/api/bridge.js +8 -418
- package/dist/daemon/api/handlers/attach.js +1 -65
- package/dist/daemon/api/handlers/bash-jobs.js +2 -91
- package/dist/daemon/api/handlers/broker-ops.js +1 -447
- package/dist/daemon/api/handlers/broker-recovery.js +1 -251
- package/dist/daemon/api/handlers/canvas.js +6 -490
- package/dist/daemon/api/handlers/chat-inventory.js +1 -25
- package/dist/daemon/api/handlers/crons.js +1 -373
- package/dist/daemon/api/handlers/daemon.js +1 -76
- package/dist/daemon/api/handlers/feedback-comments.js +3 -199
- package/dist/daemon/api/handlers/files.js +1 -63
- package/dist/daemon/api/handlers/focus.js +1 -92
- package/dist/daemon/api/handlers/health.js +1 -76
- package/dist/daemon/api/handlers/human-requests.js +1 -379
- package/dist/daemon/api/handlers/human.js +1 -3
- package/dist/daemon/api/handlers/inbox-page.js +1 -89
- package/dist/daemon/api/handlers/inbox.js +1 -301
- package/dist/daemon/api/handlers/memory.js +1 -50
- package/dist/daemon/api/handlers/messages.js +2 -506
- package/dist/daemon/api/handlers/model-config.js +1 -44
- package/dist/daemon/api/handlers/modelauth.js +1 -165
- package/dist/daemon/api/handlers/node-outcomes.js +1 -181
- package/dist/daemon/api/handlers/nodes.js +1 -939
- package/dist/daemon/api/handlers/profiles.js +1 -140
- package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
- package/dist/daemon/api/handlers/reports.js +16 -332
- package/dist/daemon/api/handlers/review-comments.js +1 -465
- package/dist/daemon/api/handlers/reviews.js +1 -200
- package/dist/daemon/api/handlers/subscriptions.js +1 -53
- package/dist/daemon/api/handlers/validate.js +1 -58
- package/dist/daemon/api/handlers/worktree.js +1 -39
- package/dist/daemon/api/map.js +2 -735
- package/dist/daemon/api/router.js +1 -190
- package/dist/daemon/api/server.js +11 -408
- package/dist/daemon/boot-migrations.js +1 -31
- package/dist/daemon/companion-retire.js +1 -34
- package/dist/daemon/control.js +1 -22
- package/dist/daemon/cron/armed-context.js +1 -100
- package/dist/daemon/cron/capture.js +2 -45
- package/dist/daemon/cron/disposition.js +1 -55
- package/dist/daemon/cron/escalation.js +3 -124
- package/dist/daemon/cron/held.js +1 -20
- package/dist/daemon/cron/lease-recovery.js +1 -119
- package/dist/daemon/cron/live-runs.js +1 -23
- package/dist/daemon/cron/passes.js +1 -58
- package/dist/daemon/cron/settle.js +1 -61
- package/dist/daemon/cron/sinks.js +2 -59
- package/dist/daemon/cron-run.js +1 -405
- package/dist/daemon/crtrd-cli.js +1 -23
- package/dist/daemon/crtrd.js +8 -854
- package/dist/daemon/delivery/run-delivery.js +1 -164
- package/dist/daemon/fleet.js +17 -475
- package/dist/daemon/human/finish.js +10 -179
- package/dist/daemon/human/settle.js +1 -89
- package/dist/daemon/human/sweep.js +1 -66
- package/dist/daemon/manage.js +2 -595
- package/dist/daemon/messaging/node-message.js +1 -99
- package/dist/daemon/park-activity.js +1 -30
- package/dist/daemon/park-pending.js +1 -52
- package/dist/daemon/pidfile.js +1 -37
- package/dist/daemon/profile-delete.js +1 -306
- package/dist/daemon/reconcilers/bash-deadline.js +1 -80
- package/dist/daemon/reconcilers/broker-supervision.js +4 -761
- package/dist/daemon/reconcilers/controller-death.js +1 -14
- package/dist/daemon/reconcilers/cron-lane.js +1 -29
- package/dist/daemon/reconcilers/delivery-lane.js +1 -130
- package/dist/daemon/reconcilers/live-obligation.js +1 -87
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
- package/dist/daemon/reconcilers/node-deadline.js +1 -82
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
- package/dist/daemon/review/comment-notify.js +2 -109
- package/dist/daemon/review/companion.js +1 -29
- package/dist/daemon/review/deliver.js +3 -8
- package/dist/daemon/review/finish.js +1 -122
- package/dist/daemon/review/sweep.js +1 -18
- package/dist/daemon/startup-policy.js +1 -1
- package/dist/daemon/supervise-cadence.js +1 -6
- package/dist/hook-authoring.js +5 -447
- package/dist/hook-process.js +1 -34
- package/dist/index.js +1 -52
- package/dist/migrations/001-surfaces-frontmatter.js +1 -161
- package/dist/migrations/002-profile-project-memory.js +1 -72
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
- package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
- package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
- package/dist/migrations/activation.js +2 -89
- package/dist/migrations/convergent.js +2 -82
- package/dist/migrations/corpus.js +3 -483
- package/dist/migrations/frontmatter-splice.js +8 -176
- package/dist/migrations/profile-manifests.js +2 -70
- package/dist/migrations/registry.js +1 -42
- package/dist/migrations/runner.js +1 -85
- package/dist/migrations/types.js +0 -24
- package/dist/pi-extensions/broker-local.js +2 -106
- package/dist/pi-extensions/canvas-bash-valve.js +7 -461
- package/dist/pi-extensions/canvas-context-intro.js +2 -113
- package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
- package/dist/pi-extensions/canvas-goal-capture.js +1 -83
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
- package/dist/pi-extensions/canvas-passive-context.js +14 -203
- package/dist/pi-extensions/canvas-preview-result.js +2 -72
- package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
- package/dist/pi-extensions/canvas-recap.js +11 -405
- package/dist/pi-extensions/canvas-review-boundary.js +3 -63
- package/dist/pi-extensions/canvas-stamp.js +2 -77
- package/dist/pi-extensions/canvas-stophook.js +1 -643
- package/dist/pi-extensions/canvas-structured-output.js +13 -35
- package/dist/pi-extensions/canvas-tool-guide.js +9 -78
- package/dist/pi-extensions/envelope-merge.js +8 -29
- package/dist/prompts/review.js +20 -42
- package/dist/shared/birth-announcement.js +1 -25
- package/dist/shared/crtr-version.js +1 -18
- package/dist/shared/env.js +1 -214
- package/dist/shared/generated-context.js +11 -226
- package/dist/shared/predicates.js +1 -4
- package/dist/shared/shell-quote.js +1 -5
- package/dist/shared/tool-groups.js +1 -64
- package/dist/shared/working-activity.js +1 -27
- package/dist/suppress-experimental-warnings.js +1 -15
- package/dist/types.js +1 -185
- package/docs/public-api.md +10 -9
- package/package.json +6 -4
- package/runtime.lock.json +5 -5
- package/scripts/pack-minify.mjs +108 -0
- package/dist/api/__tests__/integration/client.test.d.ts +0 -1
- package/dist/api/__tests__/integration/client.test.js +0 -163
- package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
- package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
- package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
- package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
- package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/context-message.test.js +0 -130
- package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
- package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/diagram.test.js +0 -42
- package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
- package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
- package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
- package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
- package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
- package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
- package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
- package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
- package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
- package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
- package/dist/commands/__tests__/human.test.d.ts +0 -1
- package/dist/commands/__tests__/human.test.js +0 -172
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
- package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
- package/dist/commands/__tests__/node-message.test.d.ts +0 -1
- package/dist/commands/__tests__/node-message.test.js +0 -112
- package/dist/commands/__tests__/node-new.test.d.ts +0 -1
- package/dist/commands/__tests__/node-new.test.js +0 -58
- package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
- package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
- package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
- package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
- package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
- package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
- package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
- package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
- package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
- package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
- package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
- package/dist/core/__tests__/bash-guard.test.js +0 -190
- package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
- package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
- package/dist/core/__tests__/boot.test.d.ts +0 -1
- package/dist/core/__tests__/boot.test.js +0 -274
- package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
- package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
- package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
- package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
- package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
- package/dist/core/__tests__/broker-preflight.test.js +0 -95
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
- package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
- package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
- package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
- package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
- package/dist/core/__tests__/canvas.test.d.ts +0 -1
- package/dist/core/__tests__/canvas.test.js +0 -138
- package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
- package/dist/core/__tests__/child-death-wake.test.js +0 -153
- package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
- package/dist/core/__tests__/cli-help-contract.test.js +0 -152
- package/dist/core/__tests__/close.test.d.ts +0 -1
- package/dist/core/__tests__/close.test.js +0 -284
- package/dist/core/__tests__/collectible.test.d.ts +0 -1
- package/dist/core/__tests__/collectible.test.js +0 -89
- package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
- package/dist/core/__tests__/config-change-delta.test.js +0 -108
- package/dist/core/__tests__/context-intro.test.d.ts +0 -1
- package/dist/core/__tests__/context-intro.test.js +0 -123
- package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
- package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
- package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
- package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
- package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
- package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
- package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-boot.test.js +0 -422
- package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-wedge.test.js +0 -106
- package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
- package/dist/core/__tests__/events-contract.test.d.ts +0 -1
- package/dist/core/__tests__/events-contract.test.js +0 -76
- package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
- package/dist/core/__tests__/extension-abort.test.js +0 -21
- package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
- package/dist/core/__tests__/fault-classifier.test.js +0 -138
- package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
- package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
- package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
- package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
- package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
- package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
- package/dist/core/__tests__/focuses.test.d.ts +0 -1
- package/dist/core/__tests__/focuses.test.js +0 -113
- package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
- package/dist/core/__tests__/fs-utils.test.js +0 -50
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
- package/dist/core/__tests__/helpers/broker-clients.js +0 -174
- package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
- package/dist/core/__tests__/helpers/fleet.js +0 -50
- package/dist/core/__tests__/helpers/harness.d.ts +0 -124
- package/dist/core/__tests__/helpers/harness.js +0 -806
- package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
- package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
- package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
- package/dist/core/__tests__/history-inbox.test.js +0 -121
- package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/human-action-delivery.test.js +0 -162
- package/dist/core/__tests__/human-actions.test.d.ts +0 -1
- package/dist/core/__tests__/human-actions.test.js +0 -120
- package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
- package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
- package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
- package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
- package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
- package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
- package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
- package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
- package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
- package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
- package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
- package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
- package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
- package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
- package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
- package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
- package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
- package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
- package/dist/core/__tests__/integration/revive.test.js +0 -615
- package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
- package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
- package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
- package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
- package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
- package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
- package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
- package/dist/core/__tests__/kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/kickoff.test.js +0 -196
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
- package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle.test.js +0 -176
- package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
- package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
- package/dist/core/__tests__/migration.test.d.ts +0 -1
- package/dist/core/__tests__/migration.test.js +0 -946
- package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
- package/dist/core/__tests__/model-pin-durability.test.js +0 -195
- package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes-config.test.js +0 -150
- package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
- package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
- package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
- package/dist/core/__tests__/node-outcome.test.js +0 -246
- package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
- package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
- package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
- package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
- package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
- package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
- package/dist/core/__tests__/passive-subscription.test.js +0 -120
- package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
- package/dist/core/__tests__/pid-identity-match.test.js +0 -145
- package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
- package/dist/core/__tests__/pid-zombie.test.js +0 -42
- package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-kinds.test.js +0 -182
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
- package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-page-components.test.js +0 -159
- package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
- package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
- package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
- package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
- package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
- package/dist/core/__tests__/prune.test.d.ts +0 -1
- package/dist/core/__tests__/prune.test.js +0 -243
- package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
- package/dist/core/__tests__/push-final-guard.test.js +0 -191
- package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
- package/dist/core/__tests__/relaunch-root.test.js +0 -249
- package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
- package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
- package/dist/core/__tests__/repository-association.test.d.ts +0 -1
- package/dist/core/__tests__/repository-association.test.js +0 -153
- package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
- package/dist/core/__tests__/repository-root-identity.test.js +0 -223
- package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
- package/dist/core/__tests__/respawn-throttle.test.js +0 -20
- package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -83
- package/dist/core/__tests__/revive-all.test.d.ts +0 -1
- package/dist/core/__tests__/revive-all.test.js +0 -157
- package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
- package/dist/core/__tests__/revive-capacity.test.js +0 -184
- package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
- package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
- package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
- package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
- package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
- package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
- package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
- package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
- package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
- package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
- package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
- package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
- package/dist/core/__tests__/secrets.test.d.ts +0 -1
- package/dist/core/__tests__/secrets.test.js +0 -49
- package/dist/core/__tests__/self-update.test.d.ts +0 -1
- package/dist/core/__tests__/self-update.test.js +0 -46
- package/dist/core/__tests__/session-branch.test.d.ts +0 -1
- package/dist/core/__tests__/session-branch.test.js +0 -61
- package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
- package/dist/core/__tests__/session-cycles.test.js +0 -133
- package/dist/core/__tests__/session-model.test.d.ts +0 -1
- package/dist/core/__tests__/session-model.test.js +0 -111
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
- package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
- package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
- package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
- package/dist/core/__tests__/stdout-errors.test.js +0 -16
- package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
- package/dist/core/__tests__/stop-guard.test.js +0 -237
- package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
- package/dist/core/__tests__/stream-watchdog.test.js +0 -154
- package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
- package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
- package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
- package/dist/core/__tests__/worktree-landing.test.js +0 -11
- package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
- package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
- package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
- package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
- package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/attention.test.js +0 -83
- package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
- package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
- package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/session-window.test.js +0 -70
- package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
- package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
- package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-catalog.test.js +0 -20
- package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
- package/dist/core/human/__tests__/page.test.d.ts +0 -1
- package/dist/core/human/__tests__/page.test.js +0 -92
- package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
- package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +0 -99
- package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
- package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
- package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
- package/dist/core/review/__tests__/capture-origin.test.js +0 -150
- package/dist/core/review/__tests__/comments.test.d.ts +0 -1
- package/dist/core/review/__tests__/comments.test.js +0 -116
- package/dist/core/review/__tests__/remap.test.d.ts +0 -1
- package/dist/core/review/__tests__/remap.test.js +0 -177
- package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
- package/dist/core/review/__tests__/stage-identity.test.js +0 -150
- package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
- package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/node-env.test.js +0 -73
- package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
- package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
- package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
- package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
- package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
- package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
- package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
- package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
- package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
- package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
- package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
- package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
- package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
- package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
- package/dist/daemon/__tests__/thaw-order.test.js +0 -55
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
- package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
- package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
- package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/model-config.test.js +0 -73
- package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-create-description.test.js +0 -127
- package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
- package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
- package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
- package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
- package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
- package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
- package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
- package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
- package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
- package/dist/migrations/__tests__/activation.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation.test.js +0 -152
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
- package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
- package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
- package/dist/shared/__tests__/env-boundary.test.js +0 -95
- package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
- package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
- package/docs/compat/hearth-crtr-v1.md +0 -179
- package/docs/compat/hearth-crtr-v2.md +0 -177
- package/docs/compat/hearth-crtr-v3.md +0 -176
- package/docs/compat/hearth-crtr-v4.md +0 -182
- package/docs/compat/hearth-crtr-v5.md +0 -169
|
@@ -1,1509 +0,0 @@
|
|
|
1
|
-
// fake-engine.ts — a deterministic in-process stand-in for the pi SDK engine,
|
|
2
|
-
// the SDK analog of fixtures/fake-pi-host.ts.
|
|
3
|
-
//
|
|
4
|
-
// This is NOT an LLM and NOT a mock of the canvas extensions. It occupies the
|
|
5
|
-
// pi SDK's place INSIDE the REAL broker (src/core/runtime/broker.ts): the broker
|
|
6
|
-
// loads it through the `CRTR_BROKER_ENGINE` seam (broker-sdk.ts `loadBrokerEngine`),
|
|
7
|
-
// then drives it exactly as it drives the real `@earendil-works/pi-coding-agent`
|
|
8
|
-
// engine — SessionManager.open/create, createAgentSession, session.bindExtensions,
|
|
9
|
-
// session.subscribe, session.prompt. We load the REAL `-e` canvas extensions (the
|
|
10
|
-
// modules the runtime put in the node's broker-launch.json) and fire REAL
|
|
11
|
-
// lifecycle events under harness control, so the real hooks (canvas-stophook,
|
|
12
|
-
// canvas-inbox-watcher) and the real broker drive real canvas state — across the
|
|
13
|
-
// detached broker process boundary, with NOTHING in the broker mocked.
|
|
14
|
-
//
|
|
15
|
-
// It is run UNDER tsx in the broker process (the harness puts `--import tsx/esm`
|
|
16
|
-
// in the broker's NODE_OPTIONS), so the `.ts` extension paths and this `.ts`
|
|
17
|
-
// module both resolve. By the time the broker calls our SessionManager/
|
|
18
|
-
// createAgentSession, piInvocationToSdkConfig has merged inv.env into
|
|
19
|
-
// process.env, so CRTR_NODE_ID / CRTR_HOME are set — that is how we find the
|
|
20
|
-
// node dir.
|
|
21
|
-
//
|
|
22
|
-
// Proof / control surface — IDENTICAL filenames to fake-pi-host.ts, so the
|
|
23
|
-
// EXISTING harness observers (awaitBoot, awaitWake, eventCount, bootCount,
|
|
24
|
-
// injected) work for broker nodes UNCHANGED:
|
|
25
|
-
// <nodeDir>/fake-pi.boot.json — argv + env + loaded exts (latest boot)
|
|
26
|
-
// <nodeDir>/fake-pi.boots.jsonl — append-only, one line per boot (broker pid)
|
|
27
|
-
// <nodeDir>/fake-pi.events.jsonl — append-only, one line per fired event
|
|
28
|
-
// <nodeDir>/fake-pi.injected.jsonl — every sendUserMessage (inbox-watcher wake)
|
|
29
|
-
// <nodeDir>/fake-pi.error — any boot/import failure
|
|
30
|
-
// <nodeDir>/fake-pi.cmd — harness writes ONE JSON command (turn|stop|auto_retry|dialog)
|
|
31
|
-
// <nodeDir>/fake-pi.dialog.jsonl — one line per resolved unattended dialog (§5.4)
|
|
32
|
-
import { spawn } from 'node:child_process';
|
|
33
|
-
import { writeFileSync, readFileSync, existsSync, mkdirSync, appendFileSync, unlinkSync, } from 'node:fs';
|
|
34
|
-
import { join, dirname, resolve } from 'node:path';
|
|
35
|
-
import { randomUUID } from 'node:crypto';
|
|
36
|
-
import { DefaultPackageManager, DefaultResourceLoader, getAgentDir, SettingsManager } from '@earendil-works/pi-coding-agent';
|
|
37
|
-
import { MANAGED_PROVIDER_COOLING_DIAGNOSTIC } from '../../runtime/managed-provider-cooling.js';
|
|
38
|
-
import { PROVIDER_FAILURE_DIAGNOSTIC } from '../../provider-failure.js';
|
|
39
|
-
import { CANVAS_EXTENSIONS } from '../../runtime/canvas-extensions.js';
|
|
40
|
-
import registerCanvasBashValve, { createValveOperations } from '../../../pi-extensions/canvas-bash-valve.js';
|
|
41
|
-
/** Test seams for prompt-scoped failures before session_start. The one-shot
|
|
42
|
-
* variant records its first failure per node so the next cycling retry can
|
|
43
|
-
* reach boot confirmation. */
|
|
44
|
-
export const FAIL_BEFORE_SESSION_START = '__FAIL_BEFORE_SESSION_START__';
|
|
45
|
-
export const FAIL_BEFORE_SESSION_START_ONCE = '__FAIL_BEFORE_SESSION_START_ONCE__';
|
|
46
|
-
/** Text marker that makes `session.prompt()` REJECT outright (no agent_start,
|
|
47
|
-
* no turn) — the shape a broker whose model resolved but whose provider has
|
|
48
|
-
* no installed credential produces ("No API key found for <provider>"). */
|
|
49
|
-
export const REJECT_PROMPT_CALL = '__REJECT_PROMPT_CALL__';
|
|
50
|
-
// node dir / proof helpers
|
|
51
|
-
function nodeDirFromEnv() {
|
|
52
|
-
const home = (process.env['CRTR_HOME'] ?? '').trim();
|
|
53
|
-
const nodeId = (process.env['CRTR_NODE_ID'] ?? '').trim();
|
|
54
|
-
if (home === '' || nodeId === '') {
|
|
55
|
-
throw new Error('[fake-engine] CRTR_HOME / CRTR_NODE_ID missing in env');
|
|
56
|
-
}
|
|
57
|
-
const dir = join(home, 'nodes', nodeId);
|
|
58
|
-
mkdirSync(dir, { recursive: true });
|
|
59
|
-
return dir;
|
|
60
|
-
}
|
|
61
|
-
function recordError(dir, msg) {
|
|
62
|
-
try {
|
|
63
|
-
appendFileSync(join(dir, 'fake-pi.error'), msg + '\n');
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
/* best effort */
|
|
67
|
-
}
|
|
68
|
-
try {
|
|
69
|
-
process.stderr.write('[fake-engine] ' + msg + '\n');
|
|
70
|
-
}
|
|
71
|
-
catch {
|
|
72
|
-
/* ignore */
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
// SessionManager — the broker calls .open(path) (resume) or .create(cwd) (fresh)
|
|
76
|
-
// and hands the result to createAgentSession. sessionId/sessionFile round-trip
|
|
77
|
-
// through it, so a resume (`--session <pi_session_file>`) re-opens the SAME
|
|
78
|
-
// .jsonl the fresh start created — the load-bearing identity for revive.
|
|
79
|
-
export class SessionManager {
|
|
80
|
-
sessionId;
|
|
81
|
-
sessionFile;
|
|
82
|
-
resumed;
|
|
83
|
-
constructor(sessionId, sessionFile, resumed) {
|
|
84
|
-
this.sessionId = sessionId;
|
|
85
|
-
this.sessionFile = sessionFile;
|
|
86
|
-
this.resumed = resumed;
|
|
87
|
-
}
|
|
88
|
-
/** Fresh start: a brand-new session whose .jsonl lives under the node dir
|
|
89
|
-
* (created empty if missing, like fake-pi-host). */
|
|
90
|
-
static create(_cwd) {
|
|
91
|
-
const dir = nodeDirFromEnv();
|
|
92
|
-
const sessionFile = join(dir, 'fake-session.jsonl');
|
|
93
|
-
if (!existsSync(sessionFile))
|
|
94
|
-
writeFileSync(sessionFile, '');
|
|
95
|
-
const sessionId = `fake-sess-${randomUUID()}`;
|
|
96
|
-
writeFileSync(`${sessionFile}.id`, sessionId);
|
|
97
|
-
return new SessionManager(sessionId, sessionFile, false);
|
|
98
|
-
}
|
|
99
|
-
/** Spawn-time fork: create the fork's distinct fake session. The focused
|
|
100
|
-
* broker tests do not replay source history, but they must reach the same
|
|
101
|
-
* post-fork model/session construction path as the real engine. */
|
|
102
|
-
static forkFrom(_source, cwd) {
|
|
103
|
-
return SessionManager.create(cwd);
|
|
104
|
-
}
|
|
105
|
-
/** Resume: round-trip the saved session identity with its .jsonl path. */
|
|
106
|
-
static open(path) {
|
|
107
|
-
const sessionId = readFileSync(`${path}.id`, 'utf8').trim();
|
|
108
|
-
if (sessionId === '')
|
|
109
|
-
throw new Error(`fake session identity is empty: ${path}.id`);
|
|
110
|
-
return new SessionManager(sessionId, path, true);
|
|
111
|
-
}
|
|
112
|
-
getSessionId() {
|
|
113
|
-
return this.sessionId;
|
|
114
|
-
}
|
|
115
|
-
getSessionFile() {
|
|
116
|
-
return this.sessionFile;
|
|
117
|
-
}
|
|
118
|
-
/** The directory containing the session file — the real SessionManager's
|
|
119
|
-
* getSessionDir(). The broker prewarms the session-list cache with it at boot
|
|
120
|
-
* (broker.ts runBroker), so the fixture must expose it or every broker boot
|
|
121
|
-
* crashes before it binds view.sock. */
|
|
122
|
-
getSessionDir() {
|
|
123
|
-
return dirname(this.sessionFile);
|
|
124
|
-
}
|
|
125
|
-
leafId = null;
|
|
126
|
-
/** Cycling support (crtr-cycle marker) — mirrors the real SDK's getLeafId/
|
|
127
|
-
* resetLeaf/appendCustomEntry just enough that `buildBrokerSession`'s cycling
|
|
128
|
-
* branch (broker.ts) doesn't throw. The fake has no real cross-boot tree at
|
|
129
|
-
* this point (FakeSession builds a fresh SessionTree every boot regardless),
|
|
130
|
-
* so these are recording stubs, not a faithful branch model —
|
|
131
|
-
* cycleAwareMessages already degrades to single-cycle passthrough for a
|
|
132
|
-
* session manager without getEntries/getBranch (never implemented on the
|
|
133
|
-
* fake), so multi-cycle REPLAY is out of scope for the fixture; only "does
|
|
134
|
-
* not crash" is in scope. */
|
|
135
|
-
getLeafId() {
|
|
136
|
-
return this.leafId;
|
|
137
|
-
}
|
|
138
|
-
resetLeaf() {
|
|
139
|
-
this.leafId = null;
|
|
140
|
-
}
|
|
141
|
-
appendCustomEntry(_customType, _data) {
|
|
142
|
-
this.leafId = `fake-cycle-${randomUUID().slice(0, 8)}`;
|
|
143
|
-
return this.leafId;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
// AgentSessionEvent stream synthesis. The fake emits a
|
|
147
|
-
// REALISTIC streaming assistant turn through session.subscribe — the SAME channel
|
|
148
|
-
// the real pi engine feeds the broker's fan-out — so the frames a `crtr surface attach`
|
|
149
|
-
// client receives are byte-for-byte real AgentSessionEvents. The EMITTED event
|
|
150
|
-
// shapes are typed against the real `AgentSessionEvent` union from pi (whose full
|
|
151
|
-
// 17 variants are message_start/update/end, tool_execution_start/update/end,
|
|
152
|
-
// agent_start/end, turn_start/end, queue_update, compaction_start/end, auto_retry_
|
|
153
|
-
// start/end, session_info_changed, thinking_level_changed) — emit() takes that
|
|
154
|
-
// union, so a drift in the shape of any variant emitTurn() constructs (the
|
|
155
|
-
// streaming subset: the message_*, tool_execution_*, agent/turn start+end events)
|
|
156
|
-
// fails the build, not a test.
|
|
157
|
-
/** A minimal but fully-typed AssistantMessage. `pad` bytes of filler text let a
|
|
158
|
-
* test size a single frame to multiple MiB (G8 backpressure flood). */
|
|
159
|
-
function assistantMessage(text, pad = 0) {
|
|
160
|
-
return {
|
|
161
|
-
role: 'assistant',
|
|
162
|
-
content: [{ type: 'text', text: pad > 0 ? `${text} ${'x'.repeat(pad)}` : text }],
|
|
163
|
-
api: 'anthropic-messages',
|
|
164
|
-
provider: 'anthropic',
|
|
165
|
-
model: 'fake-sonnet',
|
|
166
|
-
usage: {
|
|
167
|
-
input: 10,
|
|
168
|
-
output: 5,
|
|
169
|
-
cacheRead: 0,
|
|
170
|
-
cacheWrite: 0,
|
|
171
|
-
totalTokens: 15,
|
|
172
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
173
|
-
},
|
|
174
|
-
stopReason: 'stop',
|
|
175
|
-
timestamp: Date.now(),
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
/** A streaming text-delta event (the `assistantMessageEvent` carried by a
|
|
179
|
-
* message_update). Kept small (the big payload rides in message_update.message). */
|
|
180
|
-
function textDelta(partial, delta) {
|
|
181
|
-
return { type: 'text_delta', contentIndex: 0, delta, partial };
|
|
182
|
-
}
|
|
183
|
-
class SessionTree {
|
|
184
|
-
entries = new Map();
|
|
185
|
-
children = new Map();
|
|
186
|
-
leafId = null;
|
|
187
|
-
append(message) {
|
|
188
|
-
const entry = {
|
|
189
|
-
type: 'message',
|
|
190
|
-
id: randomUUID().slice(0, 8),
|
|
191
|
-
parentId: this.leafId,
|
|
192
|
-
timestamp: new Date().toISOString(),
|
|
193
|
-
message,
|
|
194
|
-
};
|
|
195
|
-
this.entries.set(entry.id, entry);
|
|
196
|
-
const siblings = this.children.get(entry.parentId) ?? [];
|
|
197
|
-
siblings.push(entry.id);
|
|
198
|
-
this.children.set(entry.parentId, siblings);
|
|
199
|
-
this.leafId = entry.id;
|
|
200
|
-
return entry;
|
|
201
|
-
}
|
|
202
|
-
/** Reconstructs a prior process's tree from its persisted snapshot — the
|
|
203
|
-
* fake's analog of the real SessionManager.open() reading every entry back
|
|
204
|
-
* from the .jsonl. A genuine resume (not a fresh cycle) must see this
|
|
205
|
-
* broker's actual history, not an empty tree, or nothing downstream that
|
|
206
|
-
* reads the branch past a crash can ever observe real prior content. */
|
|
207
|
-
hydrate(entries, leafId) {
|
|
208
|
-
for (const entry of entries) {
|
|
209
|
-
this.entries.set(entry.id, entry);
|
|
210
|
-
const siblings = this.children.get(entry.parentId) ?? [];
|
|
211
|
-
siblings.push(entry.id);
|
|
212
|
-
this.children.set(entry.parentId, siblings);
|
|
213
|
-
}
|
|
214
|
-
this.leafId = leafId;
|
|
215
|
-
}
|
|
216
|
-
/** Synthetic in-place rewind for the broker navigate_tree regression lock:
|
|
217
|
-
* drop the last turn (assistant leaf + its user parent) by re-anchoring the
|
|
218
|
-
* leaf past it. The abandoned tail is left in the map (not deleted), mirroring
|
|
219
|
-
* a real branch switch — only the ACTIVE branch shortens. */
|
|
220
|
-
rewindOneTurn() {
|
|
221
|
-
const leaf = this.leafId === null ? undefined : this.entries.get(this.leafId);
|
|
222
|
-
if (leaf === undefined)
|
|
223
|
-
return;
|
|
224
|
-
const user = leaf.parentId === null ? undefined : this.entries.get(leaf.parentId);
|
|
225
|
-
this.leafId = user !== undefined ? user.parentId : leaf.parentId;
|
|
226
|
-
}
|
|
227
|
-
getLeafId() {
|
|
228
|
-
return this.leafId;
|
|
229
|
-
}
|
|
230
|
-
getEntry(id) {
|
|
231
|
-
return this.entries.get(id);
|
|
232
|
-
}
|
|
233
|
-
getTree() {
|
|
234
|
-
return (this.children.get(null) ?? []).map((id) => this.node(id)).filter((node) => node !== null);
|
|
235
|
-
}
|
|
236
|
-
getUserMessagesForForking() {
|
|
237
|
-
return [...this.entries.values()]
|
|
238
|
-
.filter((entry) => entry.message.role === 'user')
|
|
239
|
-
.map((entry) => ({ entryId: entry.id, text: this.textOf(entry.message), timestamp: entry.timestamp }));
|
|
240
|
-
}
|
|
241
|
-
buildSessionContext() {
|
|
242
|
-
return { messages: this.branchMessages(), thinkingLevel: 'off', model: null };
|
|
243
|
-
}
|
|
244
|
-
/** Every entry in the session file, active branch or abandoned tail alike —
|
|
245
|
-
* the real SessionManager.getEntries(). */
|
|
246
|
-
getEntries() {
|
|
247
|
-
return [...this.entries.values()];
|
|
248
|
-
}
|
|
249
|
-
/** The active branch root→leaf — the real SessionManager.getBranch(). The
|
|
250
|
-
* extensions that scan for their own marker read THIS, not the whole file:
|
|
251
|
-
* a new cycle must not see a previous branch's markers. */
|
|
252
|
-
getBranch(fromId) {
|
|
253
|
-
return this.branchIds(fromId).map((id) => this.entries.get(id)).filter((entry) => entry !== undefined);
|
|
254
|
-
}
|
|
255
|
-
branchMessages() {
|
|
256
|
-
return this.branchIds().map((id) => this.entries.get(id)?.message).filter((m) => m !== undefined);
|
|
257
|
-
}
|
|
258
|
-
/** One branch's entry ids, root→leaf, from `fromId` (default: the current
|
|
259
|
-
* leaf) — the real SessionManager.getBranch(fromId?) contract. */
|
|
260
|
-
branchIds(fromId) {
|
|
261
|
-
const ids = [];
|
|
262
|
-
let cur = fromId ?? this.leafId;
|
|
263
|
-
while (cur !== null && cur !== undefined) {
|
|
264
|
-
const entry = this.entries.get(cur);
|
|
265
|
-
if (entry === undefined)
|
|
266
|
-
break;
|
|
267
|
-
ids.push(cur);
|
|
268
|
-
cur = entry.parentId;
|
|
269
|
-
}
|
|
270
|
-
ids.reverse();
|
|
271
|
-
return ids;
|
|
272
|
-
}
|
|
273
|
-
node(id) {
|
|
274
|
-
const entry = this.entries.get(id);
|
|
275
|
-
if (entry === undefined)
|
|
276
|
-
return null;
|
|
277
|
-
return {
|
|
278
|
-
entry,
|
|
279
|
-
children: (this.children.get(id) ?? []).map((child) => this.node(child)).filter((node) => node !== null),
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
textOf(message) {
|
|
283
|
-
const content = Array.isArray(message.content) ? message.content : [];
|
|
284
|
-
for (const part of content) {
|
|
285
|
-
if (typeof part?.text === 'string' && part.text !== '')
|
|
286
|
-
return part.text;
|
|
287
|
-
}
|
|
288
|
-
return '';
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
class FakeSession {
|
|
292
|
-
sm;
|
|
293
|
-
loader;
|
|
294
|
-
dir;
|
|
295
|
-
tree = new SessionTree();
|
|
296
|
-
promptFailuresRemaining;
|
|
297
|
-
extensions = [];
|
|
298
|
-
injected = [];
|
|
299
|
-
uiContext;
|
|
300
|
-
shutdownHandler;
|
|
301
|
-
streaming = false;
|
|
302
|
-
disposed = false;
|
|
303
|
-
eventSeq = 0;
|
|
304
|
-
timer;
|
|
305
|
-
/** Compiled-seam graceful-teardown vehicle: a real active turn that only settles
|
|
306
|
-
* after abort(), so the broker's bounded abort wait is observable. */
|
|
307
|
-
heldTurn;
|
|
308
|
-
retryAbort;
|
|
309
|
-
// The broker's fan-out subscribers (broker.ts `session.subscribe(...)`) and the
|
|
310
|
-
// accumulating message history the catch-up snapshot serializes (G3).
|
|
311
|
-
listeners = new Set();
|
|
312
|
-
/** Idle watcher sends received while bindExtensions is still running. They
|
|
313
|
-
* start naturally as soon as broker.ts subscribes, without a retry loop that
|
|
314
|
-
* could keep a failed broker process alive forever. */
|
|
315
|
-
pendingIdlePrompts = [];
|
|
316
|
-
messageLog = [];
|
|
317
|
-
turnEndLeafId = null;
|
|
318
|
-
/** Testability seam: `hasPendingMessages()` reported to `agent_settled`
|
|
319
|
-
* handlers. Real pi's `AgentSession.hasPendingMessages()` reflects its
|
|
320
|
-
* steer+followUp queue; this fake has no such queue, so a test that needs to
|
|
321
|
-
* reproduce a settle observed WITH pending sends (the real incident this
|
|
322
|
-
* fixture otherwise cannot exercise) sets CRTR_FAKE_ENGINE_PENDING_AT_SETTLE=1
|
|
323
|
-
* before spawning the broker. Unset → false, matching the fixture's actual
|
|
324
|
-
* (queueless) state. */
|
|
325
|
-
pendingAtSettle = process.env['CRTR_FAKE_ENGINE_PENDING_AT_SETTLE'] === '1';
|
|
326
|
-
// The construction-time services.modelRuntime (broker-sdk services path). For
|
|
327
|
-
// a model-less (tier-3) boot this is broker.ts's SELF-HEALING masking PROXY
|
|
328
|
-
// (modelLessRegistry): getAvailable()/getModel() answer empty/undefined while
|
|
329
|
-
// masked, then broker.ts reveal()s the SAME proxy the instant construction
|
|
330
|
-
// returns. Exposing it as `session.modelRuntime` (real-SDK parity — broker.ts
|
|
331
|
-
// registryOf(session) builds its facade over it) lets the broker's
|
|
332
|
-
// list_models handler observe the 0a self-heal — a post-/login list_models
|
|
333
|
-
// reports the now-available model iff reveal() actually ran.
|
|
334
|
-
modelRt;
|
|
335
|
-
constructor(sm, loader, model, modelRuntime) {
|
|
336
|
-
this.sm = sm;
|
|
337
|
-
this.loader = loader;
|
|
338
|
-
this.modelRt = modelRuntime;
|
|
339
|
-
this.dir = nodeDirFromEnv();
|
|
340
|
-
// Mirror the real pi SDK: a model-less construction (`model === undefined`)
|
|
341
|
-
// does NOT leave `session.model` undefined — Agent.createMutableAgentState()
|
|
342
|
-
// falls back to a hardcoded unknown-stub. Representing that here is what
|
|
343
|
-
// makes the compiled seam tests exercise the broker's real sessionHasNoModel()/
|
|
344
|
-
// isUnknownModel() guard path (broker.ts) rather than the `=== undefined`
|
|
345
|
-
// shortcut that never happens against the real engine.
|
|
346
|
-
this.currentModel = model ?? UNKNOWN_MODEL_STUB;
|
|
347
|
-
this.recordModel();
|
|
348
|
-
const configured = Number(process.env['CRTR_FAKE_ENGINE_PROMPT_FAILS'] ?? '0');
|
|
349
|
-
this.promptFailuresRemaining = Number.isFinite(configured) && configured > 0 ? Math.floor(configured) : 0;
|
|
350
|
-
// A genuine resume (not a fresh cycle) must see this broker's own prior
|
|
351
|
-
// history — the fake's analog of the real SessionManager.open() replaying
|
|
352
|
-
// every persisted entry. A cycling revive has already rooted a fresh cycle
|
|
353
|
-
// marker on `sm` before this construction (broker.ts), which is exactly what
|
|
354
|
-
// distinguishes it here: `sm.getLeafId()` is non-null only on that path, so
|
|
355
|
-
// a cycling boot deliberately skips hydration and starts clean.
|
|
356
|
-
if (sm.resumed && sm.getLeafId() === null)
|
|
357
|
-
this.hydrateFromPriorSnapshot();
|
|
358
|
-
this.syncTreeSnapshot();
|
|
359
|
-
}
|
|
360
|
-
// --- broker-read getters. buildSnapshot (on a client hello) reads messages/
|
|
361
|
-
// stats/model: T8 clients attach and assert on welcome.snapshot, so messages
|
|
362
|
-
// returns the accrued history; stats/model stay cheap stubs. ---------------
|
|
363
|
-
get messages() {
|
|
364
|
-
return this.tree.buildSessionContext().messages;
|
|
365
|
-
}
|
|
366
|
-
// The broker's catch-up snapshot reconstructs history from the persisted
|
|
367
|
-
// session tree (sessionManager.buildSessionContext) — the single source of
|
|
368
|
-
// truth, since `session.messages` can be sliced by pi's retry/overflow/
|
|
369
|
-
// compaction recovery. Mirror that surface so the fake's snapshot still serves
|
|
370
|
-
// the accrued history (G2/G3). The fake's persisted analog is the active branch.
|
|
371
|
-
// Built once and cached: the real SessionManager is a single object the
|
|
372
|
-
// broker's advertised-command contract monkey-patches
|
|
373
|
-
// (appendCustomMessageEntry), so a fresh literal per access would silently
|
|
374
|
-
// discard that patch.
|
|
375
|
-
smFacade;
|
|
376
|
-
get sessionManager() {
|
|
377
|
-
this.smFacade ??= {
|
|
378
|
-
buildSessionContext: () => this.tree.buildSessionContext(),
|
|
379
|
-
getLeafId: () => this.tree.getLeafId(),
|
|
380
|
-
getEntry: (id) => this.tree.getEntry(id),
|
|
381
|
-
getTree: () => this.tree.getTree(),
|
|
382
|
-
getBranch: (fromId) => this.tree.getBranch(fromId),
|
|
383
|
-
getEntries: () => this.tree.getEntries(),
|
|
384
|
-
getUserMessagesForForking: () => this.tree.getUserMessagesForForking(),
|
|
385
|
-
getSessionId: () => this.sm.getSessionId(),
|
|
386
|
-
getSessionFile: () => this.sm.getSessionFile(),
|
|
387
|
-
getSessionDir: () => this.sm.getSessionDir(),
|
|
388
|
-
appendCustomMessageEntry: (customType, content, display, details) => this.tree.append({ role: 'custom', customType, content, display, details }).id,
|
|
389
|
-
};
|
|
390
|
-
return this.smFacade;
|
|
391
|
-
}
|
|
392
|
-
get sessionId() {
|
|
393
|
-
return this.sm.getSessionId();
|
|
394
|
-
}
|
|
395
|
-
get sessionFile() {
|
|
396
|
-
return this.sm.getSessionFile();
|
|
397
|
-
}
|
|
398
|
-
get model() {
|
|
399
|
-
return this.currentModel;
|
|
400
|
-
}
|
|
401
|
-
// set_model regression surface: the broker resolves the spec via the services
|
|
402
|
-
// registry stub below, calls setModel, then broadcasts `model_changed` off
|
|
403
|
-
// this getter — store whatever it hands us.
|
|
404
|
-
currentModel;
|
|
405
|
-
currentThinkingLevel;
|
|
406
|
-
bashAbort;
|
|
407
|
-
bashRun;
|
|
408
|
-
get thinkingLevel() {
|
|
409
|
-
return this.currentThinkingLevel;
|
|
410
|
-
}
|
|
411
|
-
setThinkingLevel(level) {
|
|
412
|
-
if (this.currentThinkingLevel === level)
|
|
413
|
-
return;
|
|
414
|
-
this.currentThinkingLevel = level;
|
|
415
|
-
this.emit({ type: 'thinking_level_changed', level });
|
|
416
|
-
}
|
|
417
|
-
cycleThinkingLevel() {
|
|
418
|
-
const levels = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh'];
|
|
419
|
-
const current = this.currentThinkingLevel === undefined ? -1 : levels.indexOf(this.currentThinkingLevel);
|
|
420
|
-
const next = levels[(current + 1) % levels.length];
|
|
421
|
-
this.setThinkingLevel(next);
|
|
422
|
-
return next;
|
|
423
|
-
}
|
|
424
|
-
recordModel() {
|
|
425
|
-
// Treat the unknown-stub as "no model" on the recorded surface (parity with
|
|
426
|
-
// broker.ts formatModelSpec) so a zero-auth boot's model reads `null`, not
|
|
427
|
-
// a bogus `unknown/unknown`.
|
|
428
|
-
const m = this.currentModel;
|
|
429
|
-
const record = m === undefined || isUnknownModelStub(m) ? null : m;
|
|
430
|
-
writeFileSync(join(this.dir, 'fake-pi.model.json'), JSON.stringify(record));
|
|
431
|
-
}
|
|
432
|
-
setModel(model) {
|
|
433
|
-
this.currentModel = model;
|
|
434
|
-
this.recordModel();
|
|
435
|
-
return Promise.resolve();
|
|
436
|
-
}
|
|
437
|
-
// list_models / cycle_model read surface (real-SDK parity)
|
|
438
|
-
/** The broker's read-op picker data (buildListModelsData → registryOf(session))
|
|
439
|
-
* reads this. For a model-less boot it is the self-healing mask proxy — see
|
|
440
|
-
* modelRt. */
|
|
441
|
-
get modelRuntime() {
|
|
442
|
-
// Inert empty runtime if a construction ever omitted it — no production
|
|
443
|
-
// path does (createAgentSessionFromServices always threads it), so this only
|
|
444
|
-
// guards list_models against throwing inside the broker's data builder.
|
|
445
|
-
return this.modelRt ?? {
|
|
446
|
-
getModel: () => undefined,
|
|
447
|
-
getAvailableSnapshot: () => [],
|
|
448
|
-
getAvailable: async () => [],
|
|
449
|
-
getModels: () => [],
|
|
450
|
-
hasConfiguredAuth: () => false,
|
|
451
|
-
getError: () => undefined,
|
|
452
|
-
refresh: async () => { },
|
|
453
|
-
};
|
|
454
|
-
}
|
|
455
|
-
/** The `--models` scoped cycle set — none in these fixtures. */
|
|
456
|
-
get scopedModels() {
|
|
457
|
-
return [];
|
|
458
|
-
}
|
|
459
|
-
/** The slice of SettingsManager the list_models data builder touches. */
|
|
460
|
-
get settingsManager() {
|
|
461
|
-
return { getEnabledModels: () => null };
|
|
462
|
-
}
|
|
463
|
-
get isStreaming() {
|
|
464
|
-
return this.streaming;
|
|
465
|
-
}
|
|
466
|
-
getSessionStats() {
|
|
467
|
-
return { messages: 0, tokens: 0 };
|
|
468
|
-
}
|
|
469
|
-
getContextUsage() {
|
|
470
|
-
try {
|
|
471
|
-
const tokens = Number(readFileSync(join(this.dir, 'fake-pi.context-tokens'), 'utf8'));
|
|
472
|
-
return Number.isFinite(tokens) ? { tokens } : undefined;
|
|
473
|
-
}
|
|
474
|
-
catch {
|
|
475
|
-
return { tokens: 1000 };
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
syncTreeSnapshot() {
|
|
479
|
-
try {
|
|
480
|
-
writeFileSync(join(this.dir, 'fake-pi.tree.json'), JSON.stringify({
|
|
481
|
-
leafId: this.tree.getLeafId(),
|
|
482
|
-
activeBranch: this.tree.buildSessionContext().messages,
|
|
483
|
-
tree: this.tree.getTree(),
|
|
484
|
-
// Flat entries + leafId are the reload shape a future process's
|
|
485
|
-
// hydrateFromPriorSnapshot() reads back — getTree()'s nested form is
|
|
486
|
-
// proof-only and not reconstructed from.
|
|
487
|
-
entries: this.tree.getEntries(),
|
|
488
|
-
userMessagesForForking: this.tree.getUserMessagesForForking(),
|
|
489
|
-
}, null, 2));
|
|
490
|
-
}
|
|
491
|
-
catch {
|
|
492
|
-
/* best effort */
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
/** Reads the crashed process's last `fake-pi.tree.json` (if any) and rebuilds
|
|
496
|
-
* this process's tree from it. Best-effort: a first boot (no snapshot yet)
|
|
497
|
-
* leaves the tree empty, matching today's behavior. */
|
|
498
|
-
hydrateFromPriorSnapshot() {
|
|
499
|
-
try {
|
|
500
|
-
const raw = readFileSync(join(this.dir, 'fake-pi.tree.json'), 'utf8');
|
|
501
|
-
const parsed = JSON.parse(raw);
|
|
502
|
-
if (!Array.isArray(parsed.entries) || parsed.entries.length === 0)
|
|
503
|
-
return;
|
|
504
|
-
this.tree.hydrate(parsed.entries, parsed.leafId ?? null);
|
|
505
|
-
}
|
|
506
|
-
catch {
|
|
507
|
-
/* no prior snapshot — fresh tree */
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
// naming is cosmetic (broker calls it in a try/catch)
|
|
511
|
-
setSessionName(_name) {
|
|
512
|
-
/* no-op recording stub */
|
|
513
|
-
}
|
|
514
|
-
// controller-drive stubs (no controller connects in these tests)
|
|
515
|
-
prompt(text, options) {
|
|
516
|
-
// Rejection seam: the engine refuses the call itself (pi's no-provider-
|
|
517
|
-
// credential shape) — the promise rejects and NO lifecycle event fires.
|
|
518
|
-
if (text.includes(REJECT_PROMPT_CALL)) {
|
|
519
|
-
return Promise.reject(new Error('No API key found for anthropic'));
|
|
520
|
-
}
|
|
521
|
-
options?.preflightResult?.(true);
|
|
522
|
-
// The inbox watcher now enters through the broker-owned prompt bridge, not
|
|
523
|
-
// the Pi extension runtime. Keep its existing observable wake record for
|
|
524
|
-
// the compiled dormancy seam while the prompt drives the real lifecycle.
|
|
525
|
-
if (text.startsWith('<runtime kind="inbox"'))
|
|
526
|
-
this.recordInjected({ content: text });
|
|
527
|
-
// The broker calls this for the controller-less retry path. Emit the turn
|
|
528
|
-
// on the broker's subscribe channel and also run the real extension hooks so
|
|
529
|
-
// the canvas stophook records the fault marker and the broker can schedule
|
|
530
|
-
// the next retry.
|
|
531
|
-
const fail = this.promptFailuresRemaining > 0;
|
|
532
|
-
if (fail)
|
|
533
|
-
this.promptFailuresRemaining--;
|
|
534
|
-
return this.emitTurn(text, { fail, runHooks: true });
|
|
535
|
-
}
|
|
536
|
-
/** The unrun queues the welcome snapshot reports (`snapshot.queued`). Real
|
|
537
|
-
* pi holds a steer + followUp queue and drains it when the next turn runs;
|
|
538
|
-
* the fake records the same texts and clears them in emitTurn, so a client
|
|
539
|
-
* attaching mid-queue sees what a real broker would hand it. Both readers
|
|
540
|
-
* exist on the real AgentSession, so omitting them does not make the fake
|
|
541
|
-
* merely queueless — it makes buildSnapshot throw, and every attach test
|
|
542
|
-
* then times out waiting for a welcome the broker never built. */
|
|
543
|
-
steering = [];
|
|
544
|
-
followUps = [];
|
|
545
|
-
getSteeringMessages() {
|
|
546
|
-
return this.steering;
|
|
547
|
-
}
|
|
548
|
-
getFollowUpMessages() {
|
|
549
|
-
return this.followUps;
|
|
550
|
-
}
|
|
551
|
-
steer(text) {
|
|
552
|
-
this.steering.push(text);
|
|
553
|
-
return Promise.resolve();
|
|
554
|
-
}
|
|
555
|
-
followUp(text) {
|
|
556
|
-
this.followUps.push(text);
|
|
557
|
-
return Promise.resolve();
|
|
558
|
-
}
|
|
559
|
-
/** In-memory recording only — no proof file, matching the offline in-process
|
|
560
|
-
* contract broker-sdk-wiring.test.ts's REAL-SDK tests already use. Purely
|
|
561
|
-
* defensive: broker.ts's driveEngine now calls `session.sendCustomMessage`
|
|
562
|
-
* on ANY frame whose inline memory-reference guidance resolves, so a fake-
|
|
563
|
-
* engine-backed lifecycle test whose fixture prompt text happens to contain
|
|
564
|
-
* a resolvable `/name` token must not crash on a missing method. */
|
|
565
|
-
customMessages = [];
|
|
566
|
-
sendCustomMessage(message, options) {
|
|
567
|
-
const customMessage = {
|
|
568
|
-
customType: message.customType,
|
|
569
|
-
content: message.content,
|
|
570
|
-
display: message.display,
|
|
571
|
-
deliverAs: options?.deliverAs,
|
|
572
|
-
};
|
|
573
|
-
this.customMessages.push(customMessage);
|
|
574
|
-
try {
|
|
575
|
-
appendFileSync(join(this.dir, 'fake-pi.custom-messages.jsonl'), JSON.stringify(customMessage) + '\n');
|
|
576
|
-
}
|
|
577
|
-
catch {
|
|
578
|
-
/* best effort test proof */
|
|
579
|
-
}
|
|
580
|
-
return Promise.resolve();
|
|
581
|
-
}
|
|
582
|
-
abort() {
|
|
583
|
-
const held = this.heldTurn;
|
|
584
|
-
if (held !== undefined) {
|
|
585
|
-
held.release();
|
|
586
|
-
return held.settled;
|
|
587
|
-
}
|
|
588
|
-
this.bashAbort?.abort();
|
|
589
|
-
return this.bashRun ?? Promise.resolve();
|
|
590
|
-
}
|
|
591
|
-
abortRetry() {
|
|
592
|
-
this.retryAbort?.();
|
|
593
|
-
}
|
|
594
|
-
/** In-place tree rewind (broker `navigate_tree`). Mirrors the real SDK's
|
|
595
|
-
* contract: the session file is unchanged, the live history is truncated,
|
|
596
|
-
* and the navigated-to user message's text comes back as `editorText`. The
|
|
597
|
-
* fake's "rewind" re-anchors the active branch without deleting the abandoned
|
|
598
|
-
* tail so the welcome snapshot can prove the one-nudge property. */
|
|
599
|
-
async navigateTree(targetId, _options) {
|
|
600
|
-
// The broker regression this locks is pure frame plumbing (navigate_tree →
|
|
601
|
-
// reWelcomeAll + ack.detail), not real tree traversal, so the viewer sends a
|
|
602
|
-
// SYNTHETIC targetId. Rewind the active branch by one full turn (the last
|
|
603
|
-
// user+assistant pair) so the re-welcome serves an observably shorter
|
|
604
|
-
// transcript, and echo the target as editorText (pi parity: the navigator
|
|
605
|
-
// restores the navigated-to user message's text to the editor).
|
|
606
|
-
const hold = join(this.dir, 'fake-pi.navigate-hold');
|
|
607
|
-
if (existsSync(hold)) {
|
|
608
|
-
writeFileSync(join(this.dir, 'fake-pi.navigate-started'), '');
|
|
609
|
-
await new Promise((resolve) => {
|
|
610
|
-
const wait = () => {
|
|
611
|
-
if (existsSync(join(this.dir, 'fake-pi.navigate-release')))
|
|
612
|
-
resolve();
|
|
613
|
-
else
|
|
614
|
-
setTimeout(wait, 10);
|
|
615
|
-
};
|
|
616
|
-
wait();
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
this.tree.rewindOneTurn();
|
|
620
|
-
this.syncTreeSnapshot();
|
|
621
|
-
return { cancelled: false, editorText: `rewound-to:${targetId}` };
|
|
622
|
-
}
|
|
623
|
-
// --- the single engine event stream the broker fans out (broker.ts subscribes
|
|
624
|
-
// here and broadcasts each event VERBATIM to every attached viewer) --------
|
|
625
|
-
subscribe(listener) {
|
|
626
|
-
const l = listener;
|
|
627
|
-
this.listeners.add(l);
|
|
628
|
-
// The loader starts extension timers before broker.ts reaches subscribe().
|
|
629
|
-
// An idle watcher send in that narrow bind window is held here until the
|
|
630
|
-
// broker can observe its lifecycle; no polling/retry loop survives a failed
|
|
631
|
-
// bind with no subscriber.
|
|
632
|
-
const pending = this.pendingIdlePrompts.splice(0);
|
|
633
|
-
for (const content of pending)
|
|
634
|
-
this.startIdlePrompt(content);
|
|
635
|
-
return () => {
|
|
636
|
-
this.listeners.delete(l);
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
startIdlePrompt(content) {
|
|
640
|
-
setImmediate(() => {
|
|
641
|
-
if (this.disposed)
|
|
642
|
-
return;
|
|
643
|
-
void this.prompt(content).catch((e) => recordError(this.dir, `inbox prompt: ${String(e)}`));
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
/** Fan one typed AgentSessionEvent out to every broker subscriber. A throwing
|
|
647
|
-
* listener is recorded, never propagated (mirrors the broker's m7 try/catch). */
|
|
648
|
-
emit(event) {
|
|
649
|
-
for (const l of this.listeners) {
|
|
650
|
-
try {
|
|
651
|
-
l(event);
|
|
652
|
-
}
|
|
653
|
-
catch (e) {
|
|
654
|
-
recordError(this.dir, `subscribe listener threw: ${String(e)}`);
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
/** Emit a realistic streaming assistant turn on the subscribe channel:
|
|
659
|
-
* agent_start → turn_start → message_start → message_update×N →
|
|
660
|
-
* tool_execution_start/update/end → message_end → turn_end → agent_end. Drives
|
|
661
|
-
* G1 (controller prompt relay), G3 (produce-while-detached, accrues messageLog),
|
|
662
|
-
* and G8 (a fast event stream — `updates`/`padBytes` size the flood that sheds a
|
|
663
|
-
* stalled viewer at the broker HWM). A per-update setImmediate yield lets a
|
|
664
|
-
* fast viewer drain between frames so only the stalled one trips the HWM. */
|
|
665
|
-
async emitTurn(text, opts = {}) {
|
|
666
|
-
if (this.disposed)
|
|
667
|
-
return;
|
|
668
|
-
const updates = opts.updates ?? 3;
|
|
669
|
-
const pad = opts.padBytes ?? 0;
|
|
670
|
-
const withTool = opts.tool ?? true;
|
|
671
|
-
const fail = opts.fail === true;
|
|
672
|
-
const small = assistantMessage(text);
|
|
673
|
-
// A normal turn yields with setImmediate (fast). A sized flood (G8, pad>0) is
|
|
674
|
-
// PACED with a small real delay so a fast (reading) viewer always drains each
|
|
675
|
-
// frame and stays under the HWM, while a stalled (non-reading) viewer's backlog
|
|
676
|
-
// still climbs monotonically past the 32 MiB byte cap and is shed. Without the
|
|
677
|
-
// pace the burst outruns the reader's event loop and sheds the fast viewer too.
|
|
678
|
-
const yieldTick = () => pad > 0 ? new Promise((r) => setTimeout(r, 3)) : new Promise((r) => setImmediate(r));
|
|
679
|
-
// A turn consumes whatever was queued for it, as the real session does.
|
|
680
|
-
this.steering.length = 0;
|
|
681
|
-
this.followUps.length = 0;
|
|
682
|
-
let releaseGate;
|
|
683
|
-
if (process.env['PI_FAKE_ENGINE_HOLD_TURN'] === '1') {
|
|
684
|
-
let release;
|
|
685
|
-
let resolveSettled;
|
|
686
|
-
const settled = new Promise((resolve) => { resolveSettled = resolve; });
|
|
687
|
-
releaseGate = new Promise((resolve) => { release = resolve; });
|
|
688
|
-
this.heldTurn = { release, settled, resolveSettled };
|
|
689
|
-
}
|
|
690
|
-
this.streaming = true;
|
|
691
|
-
if (opts.runHooks === true) {
|
|
692
|
-
await this.fire('agent_start', {}, this.buildCtx());
|
|
693
|
-
}
|
|
694
|
-
this.emit({ type: 'agent_start' });
|
|
695
|
-
this.emit({ type: 'turn_start' });
|
|
696
|
-
this.emit({ type: 'message_start', message: small });
|
|
697
|
-
await releaseGate;
|
|
698
|
-
// F2 (message_update coalescing): the broker now coalesces message_update
|
|
699
|
-
// relays (latest-wins, ~75 ms window), so a padded flood riding message_update
|
|
700
|
-
// can no longer climb a stalled viewer's backlog — the coalescer would shed
|
|
701
|
-
// the flood before the HWM does. A sized flood (pad>0, G8) therefore rides
|
|
702
|
-
// tool_execution_update frames, which the broker relays VERBATIM (only
|
|
703
|
-
// message_update is coalesced — tool output streams remain the realistic
|
|
704
|
-
// unbounded-backlog vector M1 guards against). The flood gets its own
|
|
705
|
-
// tool_execution_start so the frame sequence stays well-formed.
|
|
706
|
-
const floodToolCallId = pad > 0 ? `flood-${++this.eventSeq}` : undefined;
|
|
707
|
-
if (floodToolCallId !== undefined) {
|
|
708
|
-
this.emit({
|
|
709
|
-
type: 'tool_execution_start',
|
|
710
|
-
toolCallId: floodToolCallId,
|
|
711
|
-
toolName: 'read',
|
|
712
|
-
args: { path: 'flood.txt' },
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
for (let i = 0; i < updates; i++) {
|
|
716
|
-
if (this.disposed)
|
|
717
|
-
return;
|
|
718
|
-
this.emit({
|
|
719
|
-
type: 'message_update',
|
|
720
|
-
message: assistantMessage(`${text} [${i + 1}/${updates}]`),
|
|
721
|
-
assistantMessageEvent: textDelta(small, `chunk ${i + 1}`),
|
|
722
|
-
});
|
|
723
|
-
if (floodToolCallId !== undefined) {
|
|
724
|
-
// The big payload (G8) rides the partialResult; ~padBytes per frame.
|
|
725
|
-
this.emit({
|
|
726
|
-
type: 'tool_execution_update',
|
|
727
|
-
toolCallId: floodToolCallId,
|
|
728
|
-
toolName: 'read',
|
|
729
|
-
args: { path: 'flood.txt' },
|
|
730
|
-
partialResult: { chunk: 'x'.repeat(pad) },
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
await yieldTick();
|
|
734
|
-
}
|
|
735
|
-
if (floodToolCallId !== undefined) {
|
|
736
|
-
this.emit({
|
|
737
|
-
type: 'tool_execution_end',
|
|
738
|
-
toolCallId: floodToolCallId,
|
|
739
|
-
toolName: 'read',
|
|
740
|
-
result: { ok: true },
|
|
741
|
-
isError: false,
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
if (withTool) {
|
|
745
|
-
const toolCallId = `call-${++this.eventSeq}`;
|
|
746
|
-
this.emit({ type: 'tool_execution_start', toolCallId, toolName: 'read', args: { path: 'README.md' } });
|
|
747
|
-
this.emit({
|
|
748
|
-
type: 'tool_execution_update',
|
|
749
|
-
toolCallId,
|
|
750
|
-
toolName: 'read',
|
|
751
|
-
args: { path: 'README.md' },
|
|
752
|
-
partialResult: { bytes: 42 },
|
|
753
|
-
});
|
|
754
|
-
this.emit({ type: 'tool_execution_end', toolCallId, toolName: 'read', result: { ok: true }, isError: false });
|
|
755
|
-
}
|
|
756
|
-
if (this.disposed)
|
|
757
|
-
return;
|
|
758
|
-
const userMsg = {
|
|
759
|
-
role: 'user',
|
|
760
|
-
content: [{ type: 'text', text }],
|
|
761
|
-
timestamp: Date.now(),
|
|
762
|
-
};
|
|
763
|
-
this.tree.append(userMsg);
|
|
764
|
-
this.syncTreeSnapshot();
|
|
765
|
-
const finalMsg = fail
|
|
766
|
-
? { ...assistantMessage(text), stopReason: 'error', errorMessage: 'Connection error.' }
|
|
767
|
-
: assistantMessage(text);
|
|
768
|
-
this.emit({ type: 'message_end', message: finalMsg });
|
|
769
|
-
this.emit({ type: 'turn_end', message: finalMsg, toolResults: [] });
|
|
770
|
-
this.messageLog.push(finalMsg);
|
|
771
|
-
const anchorBeforeFinal = this.tree.getLeafId();
|
|
772
|
-
this.turnEndLeafId = anchorBeforeFinal;
|
|
773
|
-
this.tree.append(finalMsg);
|
|
774
|
-
this.syncTreeSnapshot();
|
|
775
|
-
if (opts.runHooks === true) {
|
|
776
|
-
const hookCtx = this.buildCtx();
|
|
777
|
-
await this.fire('turn_end', { message: finalMsg, toolResults: [] }, hookCtx);
|
|
778
|
-
const hookMessages = fail
|
|
779
|
-
? [...this.tree.buildSessionContext().messages, finalMsg]
|
|
780
|
-
: this.tree.buildSessionContext().messages.slice();
|
|
781
|
-
await this.fire('agent_end', { messages: hookMessages, willRetry: false }, hookCtx);
|
|
782
|
-
// Pi settles extensions before it notifies session subscribers. This order
|
|
783
|
-
// is load-bearing for the broker's cooperative shutdown: the watcher
|
|
784
|
-
// commits its inbox cursor at settle, then the broker may exit.
|
|
785
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, hookCtx);
|
|
786
|
-
}
|
|
787
|
-
this.turnEndLeafId = null;
|
|
788
|
-
// Pi exposes agent_end while the run is still active; agent_settled is the
|
|
789
|
-
// first subscriber event after isStreaming clears. Keep that production
|
|
790
|
-
// ordering so broker retry tests cannot green-light an impossible arm point.
|
|
791
|
-
const agentEndMessages = fail
|
|
792
|
-
? [...this.tree.buildSessionContext().messages, finalMsg]
|
|
793
|
-
: this.tree.buildSessionContext().messages.slice();
|
|
794
|
-
this.emit({ type: 'agent_end', messages: agentEndMessages, willRetry: false });
|
|
795
|
-
this.streaming = false;
|
|
796
|
-
this.emit({ type: 'agent_settled' });
|
|
797
|
-
const held = this.heldTurn;
|
|
798
|
-
this.heldTurn = undefined;
|
|
799
|
-
held?.resolveSettled();
|
|
800
|
-
}
|
|
801
|
-
dispose() {
|
|
802
|
-
this.disposed = true;
|
|
803
|
-
if (this.timer !== undefined)
|
|
804
|
-
clearInterval(this.timer);
|
|
805
|
-
}
|
|
806
|
-
// --- bindExtensions: drive the loader's ALREADY-loaded extensions. The REAL
|
|
807
|
-
// DefaultResourceLoader.reload() (broker.ts, BEFORE createAgentSession) has
|
|
808
|
-
// already imported the `-e` canvas extensions via jiti and called each
|
|
809
|
-
// default(pi) against the SDK's `notInitialized` runtime — registering their
|
|
810
|
-
// handlers but leaving every action method (pi.sendUserMessage, …) a stub
|
|
811
|
-
// that THROWS during load. We must NOT re-import them: a native import() is a
|
|
812
|
-
// jiti-independent SECOND module instance, so the inbox-watcher's module-
|
|
813
|
-
// level timer would run TWICE — and the reload() copy (bound to the throwing
|
|
814
|
-
// runtime) wins the race for the shared on-disk inbox cursor, consuming the
|
|
815
|
-
// entry and never delivering. Instead we replicate the minimal slice of
|
|
816
|
-
// agent-session's bindCore: swap the shared runtime's action methods IN PLACE
|
|
817
|
-
// so the real handlers' pi.sendUserMessage delivers into our proof files,
|
|
818
|
-
// then emit session_start into their handler maps so the REAL canvas-stophook
|
|
819
|
-
// records pi_session_id/file + recordPid(process.pid=broker pid). The broker's
|
|
820
|
-
// shutdownHandler is wired into ctx.shutdown so the stophook's done/idle-
|
|
821
|
-
// release/refresh branches exit the broker. -------------------------------
|
|
822
|
-
async bindExtensions(opts) {
|
|
823
|
-
this.uiContext = opts.uiContext;
|
|
824
|
-
this.shutdownHandler = opts.shutdownHandler;
|
|
825
|
-
const { argv, extPaths, label, prompt } = readLaunch(this.dir);
|
|
826
|
-
// SessionManager.open backs both strict resume and in-place cycling. The
|
|
827
|
-
// latter roots a fresh context, so report and fault-inject it as non-resuming.
|
|
828
|
-
const resuming = this.sm.resumed && !argv.includes('--crtr-new-cycle');
|
|
829
|
-
// M-1 regression seam: simulate a broker that throws BEFORE session_start
|
|
830
|
-
// (no pid, no session ever recorded). Only a fresh start carries the kickoff
|
|
831
|
-
// prompt; the throw propagates out of bindExtensions → runBroker rejects →
|
|
832
|
-
// broker-cli's fatal catch logs to job/broker.log + exit(1).
|
|
833
|
-
if (!resuming && (prompt ?? '').includes(FAIL_BEFORE_SESSION_START)) {
|
|
834
|
-
throw new Error('[fake-engine] simulated pre-session_start boot failure');
|
|
835
|
-
}
|
|
836
|
-
if (!resuming && (prompt ?? '').includes(FAIL_BEFORE_SESSION_START_ONCE)) {
|
|
837
|
-
const marker = join(this.dir, 'yield-retry.once-failed');
|
|
838
|
-
if (!existsSync(marker)) {
|
|
839
|
-
writeFileSync(marker, '1');
|
|
840
|
-
throw new Error('[fake-engine] simulated one-shot pre-session_start boot failure');
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
|
-
// bindCore (minimal): adopt the loader's extensions + their shared runtime, and
|
|
844
|
-
// replace the throwing notInitialized action methods with working ones. The
|
|
845
|
-
// handlers themselves stay the REAL ones the SDK registered during reload().
|
|
846
|
-
const loaded = [];
|
|
847
|
-
const failedExt = [];
|
|
848
|
-
try {
|
|
849
|
-
const result = this.loader?.getExtensions();
|
|
850
|
-
this.extensions = result?.extensions ?? [];
|
|
851
|
-
for (const e of this.extensions)
|
|
852
|
-
loaded.push(e.path);
|
|
853
|
-
for (const err of result?.errors ?? []) {
|
|
854
|
-
failedExt.push(String(err?.error ?? err));
|
|
855
|
-
}
|
|
856
|
-
const rt = result?.runtime;
|
|
857
|
-
if (rt !== undefined) {
|
|
858
|
-
rt.assertActive = () => { };
|
|
859
|
-
rt.sendUserMessage = (content, options) => {
|
|
860
|
-
this.recordInjected({ content, deliverAs: options?.deliverAs });
|
|
861
|
-
// Pi's unqualified idle send starts a prompt. Drive that actual fake
|
|
862
|
-
// session lifecycle so a watcher wake reaches agent_end/settled and the
|
|
863
|
-
// broker subscriber naturally, rather than asking a test to dispatch a
|
|
864
|
-
// separate synthetic turn. Steered/follow-up sends remain queued proof
|
|
865
|
-
// records: they belong to an already-running turn in this focused fake.
|
|
866
|
-
if (options?.deliverAs === undefined) {
|
|
867
|
-
// The loader's watcher timer can tick while bindExtensions is still
|
|
868
|
-
// awaiting session_start, before broker.ts installs subscribe(). Hold
|
|
869
|
-
// that send until subscription rather than completing an unobserved
|
|
870
|
-
// turn or spinning an event-loop retry if bind fails.
|
|
871
|
-
if (this.listeners.size === 0)
|
|
872
|
-
this.pendingIdlePrompts.push(content);
|
|
873
|
-
else
|
|
874
|
-
this.startIdlePrompt(content);
|
|
875
|
-
}
|
|
876
|
-
};
|
|
877
|
-
rt.sendMessage = (message, options) => this.recordInjected({ content: JSON.stringify(message), deliverAs: options?.deliverAs });
|
|
878
|
-
rt.setSessionName = () => { };
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
recordError(this.dir, 'bindExtensions: resourceLoader.getExtensions() returned no runtime');
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
catch (e) {
|
|
885
|
-
recordError(this.dir, `bindExtensions getExtensions/bindCore failed: ${String(e)}`);
|
|
886
|
-
}
|
|
887
|
-
const ctx = this.buildCtx();
|
|
888
|
-
// session_start: the real boot-confirm hook captures session id/file + the
|
|
889
|
-
// broker's pid (recordPid(process.pid)) and clears any pending refresh.
|
|
890
|
-
await this.fire('session_start', { reason: resuming ? 'resume' : 'startup' }, ctx);
|
|
891
|
-
// The boot proof the harness asserts on (same shape as fake-pi-host's boot).
|
|
892
|
-
const env = process.env;
|
|
893
|
-
const boot = {
|
|
894
|
-
pid: process.pid, // the broker pid (recorded as pi_pid by the stophook)
|
|
895
|
-
nodeId: (env['CRTR_NODE_ID'] ?? '').trim(),
|
|
896
|
-
home: (env['CRTR_HOME'] ?? '').trim(),
|
|
897
|
-
rawArgv: argv,
|
|
898
|
-
extPaths,
|
|
899
|
-
loaded,
|
|
900
|
-
failedExt,
|
|
901
|
-
sessionId: this.sm.getSessionId(),
|
|
902
|
-
sessionFile: this.sm.getSessionFile(),
|
|
903
|
-
resuming,
|
|
904
|
-
label: label ?? null,
|
|
905
|
-
prompt: prompt ?? null,
|
|
906
|
-
env: {
|
|
907
|
-
CRTR_NODE_ID: env['CRTR_NODE_ID'] ?? null,
|
|
908
|
-
CRTR_KIND: env['CRTR_KIND'] ?? null,
|
|
909
|
-
CRTR_MODE: env['CRTR_MODE'] ?? null,
|
|
910
|
-
CRTR_LIFECYCLE: env['CRTR_LIFECYCLE'] ?? null,
|
|
911
|
-
CRTR_NODE_CWD: env['CRTR_NODE_CWD'] ?? null,
|
|
912
|
-
CRTR_PROFILE_ID: env['CRTR_PROFILE_ID'] ?? null,
|
|
913
|
-
CRTR_HOME: env['CRTR_HOME'] ?? null,
|
|
914
|
-
CRTR_PARENT_NODE_ID: env['CRTR_PARENT_NODE_ID'] ?? null,
|
|
915
|
-
CRTR_ROOT_SESSION: env['CRTR_ROOT_SESSION'] ?? null,
|
|
916
|
-
CRTR_SUBTREE: env['CRTR_SUBTREE'] ?? null,
|
|
917
|
-
CRTR_FRONT_DOOR: env['CRTR_FRONT_DOOR'] ?? null,
|
|
918
|
-
},
|
|
919
|
-
injectedDuringBoot: this.injected.slice(),
|
|
920
|
-
};
|
|
921
|
-
writeFileSync(join(this.dir, 'fake-pi.boot.json'), JSON.stringify(boot, null, 2));
|
|
922
|
-
try {
|
|
923
|
-
appendFileSync(join(this.dir, 'fake-pi.boots.jsonl'), JSON.stringify(boot) + '\n');
|
|
924
|
-
}
|
|
925
|
-
catch {
|
|
926
|
-
/* best effort */
|
|
927
|
-
}
|
|
928
|
-
// Control loop: poll for one harness command at a time (turn | stop | dialog).
|
|
929
|
-
this.timer = setInterval(() => {
|
|
930
|
-
void this.step().catch((e) => recordError(this.dir, `step: ${String(e)}`));
|
|
931
|
-
}, 100);
|
|
932
|
-
if (typeof this.timer.unref === 'function')
|
|
933
|
-
this.timer.unref();
|
|
934
|
-
}
|
|
935
|
-
// --- record an injected user message (the inbox-watcher wake proof). Called by
|
|
936
|
-
// the runtime's swapped-in sendUserMessage/sendMessage. ---------------------
|
|
937
|
-
recordInjected(rec) {
|
|
938
|
-
this.injected.push(rec);
|
|
939
|
-
try {
|
|
940
|
-
appendFileSync(join(this.dir, 'fake-pi.injected.jsonl'), JSON.stringify({ ...rec, ts: Date.now() }) + '\n');
|
|
941
|
-
}
|
|
942
|
-
catch {
|
|
943
|
-
/* best effort */
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
// the ctx passed to fired handlers (union across both focus extensions)
|
|
947
|
-
buildCtx() {
|
|
948
|
-
return {
|
|
949
|
-
sessionManager: {
|
|
950
|
-
getSessionId: () => this.sm.getSessionId(),
|
|
951
|
-
getSessionFile: () => this.sm.getSessionFile(),
|
|
952
|
-
getLeafId: () => this.turnEndLeafId ?? this.tree.getLeafId(),
|
|
953
|
-
// The session-scanning extensions (context-intro, review-boundary,
|
|
954
|
-
// recap) read the branch at session_start to decide whether their own
|
|
955
|
-
// marker is already present. Both exist on the real SessionManager, so
|
|
956
|
-
// a fake missing them is not a degraded fixture but a broken one: the
|
|
957
|
-
// handler throws, session_start never completes, and every attach test
|
|
958
|
-
// times out waiting for a welcome that the broker never sends.
|
|
959
|
-
getBranch: () => this.tree.getBranch(),
|
|
960
|
-
getEntries: () => this.tree.getEntries(),
|
|
961
|
-
},
|
|
962
|
-
getContextUsage: () => this.getContextUsage(),
|
|
963
|
-
// Wired to the broker's shutdownHandler: the stophook calls ctx.shutdown()
|
|
964
|
-
// in exactly its done / idle-release / refresh branches → disposeAndExit.
|
|
965
|
-
shutdown: () => {
|
|
966
|
-
this.shutdownHandler?.();
|
|
967
|
-
},
|
|
968
|
-
isIdle: () => !this.streaming,
|
|
969
|
-
abort: () => { },
|
|
970
|
-
hasPendingMessages: () => this.pendingAtSettle,
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
// Append a durable record of every fired event BEFORE its handlers run — the
|
|
974
|
-
// harness's robust "the broker received my command and is dispatching it"
|
|
975
|
-
// signal, surviving a handler that exits the process (agent_end → ctx.shutdown
|
|
976
|
-
// → broker disposeAndExit → process.exit).
|
|
977
|
-
recordEvent(event, ev) {
|
|
978
|
-
try {
|
|
979
|
-
const reason = ev?.reason;
|
|
980
|
-
appendFileSync(join(this.dir, 'fake-pi.events.jsonl'), JSON.stringify({ seq: ++this.eventSeq, event, reason: reason ?? null, ts: Date.now() }) + '\n');
|
|
981
|
-
}
|
|
982
|
-
catch {
|
|
983
|
-
/* best effort */
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
async fire(event, ev, ctx) {
|
|
987
|
-
this.recordEvent(event, ev);
|
|
988
|
-
// Dispatch into the loader's REAL extension handler maps (the same handlers
|
|
989
|
-
// the SDK's reload() registered as each extension called pi.on(event, …)).
|
|
990
|
-
for (const ext of this.extensions) {
|
|
991
|
-
for (const h of ext.handlers.get(event) ?? []) {
|
|
992
|
-
try {
|
|
993
|
-
await h(ev, ctx);
|
|
994
|
-
}
|
|
995
|
-
catch (e) {
|
|
996
|
-
recordError(this.dir, `handler ${event} threw: ${String(e)}`);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
// --- the command channel: one JSON command at a time, atomically renamed in --
|
|
1002
|
-
async step() {
|
|
1003
|
-
if (this.disposed)
|
|
1004
|
-
return;
|
|
1005
|
-
const cmdFile = join(this.dir, 'fake-pi.cmd');
|
|
1006
|
-
if (!existsSync(cmdFile))
|
|
1007
|
-
return;
|
|
1008
|
-
let cmd = null;
|
|
1009
|
-
try {
|
|
1010
|
-
cmd = JSON.parse(readFileSync(cmdFile, 'utf8'));
|
|
1011
|
-
}
|
|
1012
|
-
catch {
|
|
1013
|
-
cmd = null;
|
|
1014
|
-
}
|
|
1015
|
-
try {
|
|
1016
|
-
unlinkSync(cmdFile);
|
|
1017
|
-
}
|
|
1018
|
-
catch {
|
|
1019
|
-
/* ignore */
|
|
1020
|
-
}
|
|
1021
|
-
if (cmd)
|
|
1022
|
-
await this.dispatch(cmd);
|
|
1023
|
-
}
|
|
1024
|
-
async dispatch(cmd) {
|
|
1025
|
-
const ctx = this.buildCtx();
|
|
1026
|
-
switch (cmd.cmd) {
|
|
1027
|
-
case 'self_close': {
|
|
1028
|
-
const cli = join(dirname(new URL(import.meta.url).pathname), '../../../cli.js');
|
|
1029
|
-
const resultPath = join(this.dir, 'self-close-result');
|
|
1030
|
-
const pidPath = join(this.dir, 'self-close-shell.pid');
|
|
1031
|
-
const shell = spawn('sh', ['-c', `"${process.execPath}" "${cli}" node lifecycle close --node "$CRTR_NODE_ID"; code=$?; printf '%s\\n' "$code" > "${resultPath}"; while :; do sleep 1; done`], { detached: true, stdio: 'ignore', env: process.env });
|
|
1032
|
-
if (shell.pid !== undefined)
|
|
1033
|
-
writeFileSync(pidPath, `${shell.pid}\n`);
|
|
1034
|
-
shell.unref();
|
|
1035
|
-
break;
|
|
1036
|
-
}
|
|
1037
|
-
case 'stream':
|
|
1038
|
-
// Drive a subscribe-channel streaming turn WITHOUT a controller (G3:
|
|
1039
|
-
// produce-while-detached) or with sized frames (G8: a fast event stream
|
|
1040
|
-
// that sheds a stalled viewer at the HWM). Pure fan-out — no stophook, no
|
|
1041
|
-
// exit — so the broker stays alive.
|
|
1042
|
-
await this.emitTurn(cmd.text ?? 'streamed turn', {
|
|
1043
|
-
updates: cmd.updates,
|
|
1044
|
-
padBytes: cmd.padBytes,
|
|
1045
|
-
tool: cmd.tool,
|
|
1046
|
-
});
|
|
1047
|
-
break;
|
|
1048
|
-
case 'bash': {
|
|
1049
|
-
const nodeId = process.env['CRTR_NODE_ID'];
|
|
1050
|
-
const contextDir = process.env['CRTR_CONTEXT_DIR'];
|
|
1051
|
-
if (nodeId === undefined || contextDir === undefined)
|
|
1052
|
-
throw new Error('bash control requires canvas node paths');
|
|
1053
|
-
this.streaming = true;
|
|
1054
|
-
await this.fire('agent_start', {}, ctx);
|
|
1055
|
-
this.emit({ type: 'agent_start' });
|
|
1056
|
-
// The resource loader imports extensions through jiti while this fixture
|
|
1057
|
-
// imports its valve operations through Node. Register the same module
|
|
1058
|
-
// instance here so its SIGTERM listener owns this real test job too.
|
|
1059
|
-
registerCanvasBashValve({ on: () => { } });
|
|
1060
|
-
const controller = new AbortController();
|
|
1061
|
-
this.bashAbort = controller;
|
|
1062
|
-
const run = createValveOperations(nodeId, contextDir).exec(cmd.command ?? 'true', process.cwd(), {
|
|
1063
|
-
onData: () => { },
|
|
1064
|
-
signal: controller.signal,
|
|
1065
|
-
}).then(() => { });
|
|
1066
|
-
this.bashRun = run;
|
|
1067
|
-
try {
|
|
1068
|
-
await run;
|
|
1069
|
-
}
|
|
1070
|
-
finally {
|
|
1071
|
-
this.bashAbort = undefined;
|
|
1072
|
-
this.bashRun = undefined;
|
|
1073
|
-
this.streaming = false;
|
|
1074
|
-
}
|
|
1075
|
-
await this.fire('agent_end', { messages: [] }, ctx);
|
|
1076
|
-
this.emit({ type: 'agent_end', messages: [], willRetry: false });
|
|
1077
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
1078
|
-
this.emit({ type: 'agent_settled' });
|
|
1079
|
-
break;
|
|
1080
|
-
}
|
|
1081
|
-
case 'turn':
|
|
1082
|
-
this.streaming = true;
|
|
1083
|
-
await this.fire('agent_start', {}, ctx);
|
|
1084
|
-
this.emit({ type: 'agent_start' });
|
|
1085
|
-
this.streaming = false;
|
|
1086
|
-
await this.fire('turn_end', { message: { role: 'assistant', usage: { input: 10, output: 5 }, model: 'fake' } }, ctx);
|
|
1087
|
-
await this.fire('agent_end', { messages: [{ role: 'assistant', stopReason: 'stop', content: [{ type: 'text', text: cmd.text ?? '' }] }] }, ctx);
|
|
1088
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
1089
|
-
this.emit({ type: 'agent_settled' });
|
|
1090
|
-
break;
|
|
1091
|
-
case 'stop': {
|
|
1092
|
-
// Match pi's lifecycle: message_end reaches broker fallback policy
|
|
1093
|
-
// before the stophook sees agent_end while the run is active; the
|
|
1094
|
-
// subscriber receives agent_settled after it clears.
|
|
1095
|
-
this.streaming = true;
|
|
1096
|
-
const diagnostics = [
|
|
1097
|
-
...(cmd.deadline === undefined ? [] : [{
|
|
1098
|
-
type: MANAGED_PROVIDER_COOLING_DIAGNOSTIC,
|
|
1099
|
-
timestamp: Date.now(),
|
|
1100
|
-
details: { rateLimitedUntil: cmd.deadline },
|
|
1101
|
-
}]),
|
|
1102
|
-
...(cmd.providerFailure === undefined ? [] : [{
|
|
1103
|
-
type: PROVIDER_FAILURE_DIAGNOSTIC,
|
|
1104
|
-
timestamp: Date.now(),
|
|
1105
|
-
details: cmd.providerFailure,
|
|
1106
|
-
}]),
|
|
1107
|
-
];
|
|
1108
|
-
const stopMessages = [
|
|
1109
|
-
{
|
|
1110
|
-
role: 'assistant',
|
|
1111
|
-
stopReason: cmd.reason ?? 'stop',
|
|
1112
|
-
// A real engine attaches errorMessage on a stopReason:'error'
|
|
1113
|
-
// turn; the stophook classifies it for the active-fault marker.
|
|
1114
|
-
// Forward it so a test can drive a CONNECTION stall faithfully.
|
|
1115
|
-
...(cmd.errorMessage === undefined ? {} : { errorMessage: cmd.errorMessage }),
|
|
1116
|
-
...(diagnostics.length === 0 ? {} : { diagnostics }),
|
|
1117
|
-
content: [{ type: 'text', text: cmd.text ?? '' }],
|
|
1118
|
-
},
|
|
1119
|
-
];
|
|
1120
|
-
this.emit({ type: 'message_end', message: stopMessages[0] });
|
|
1121
|
-
await this.fire('agent_end', { messages: stopMessages }, ctx);
|
|
1122
|
-
// Every attempt reaches the broker subscriber while streaming; only the
|
|
1123
|
-
// following settled event may publish its fault or arm a retry timer.
|
|
1124
|
-
this.emit({ type: 'agent_end', messages: stopMessages, willRetry: false });
|
|
1125
|
-
this.streaming = false;
|
|
1126
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
1127
|
-
this.emit({ type: 'agent_settled' });
|
|
1128
|
-
break;
|
|
1129
|
-
}
|
|
1130
|
-
case 'overflow': {
|
|
1131
|
-
const raw = {
|
|
1132
|
-
role: 'assistant',
|
|
1133
|
-
stopReason: 'error',
|
|
1134
|
-
errorMessage: 'Your input exceeds the context window of this model.',
|
|
1135
|
-
content: [],
|
|
1136
|
-
};
|
|
1137
|
-
const rawMessages = [raw];
|
|
1138
|
-
const emitAttemptEnd = async () => {
|
|
1139
|
-
await this.fire('agent_end', { messages: rawMessages, willRetry: false }, ctx);
|
|
1140
|
-
this.emit({ type: 'agent_end', messages: rawMessages, willRetry: false });
|
|
1141
|
-
};
|
|
1142
|
-
const emitRecoveredContinuation = async () => {
|
|
1143
|
-
await this.fire('agent_start', {}, ctx);
|
|
1144
|
-
this.emit({ type: 'agent_start' });
|
|
1145
|
-
const recovered = assistantMessage('recovered after compaction');
|
|
1146
|
-
await this.fire('turn_end', { message: recovered, toolResults: [] }, ctx);
|
|
1147
|
-
this.emit({ type: 'turn_end', message: recovered, toolResults: [] });
|
|
1148
|
-
await this.fire('agent_end', { messages: [recovered], willRetry: false }, ctx);
|
|
1149
|
-
this.emit({ type: 'agent_end', messages: [recovered], willRetry: false });
|
|
1150
|
-
};
|
|
1151
|
-
const emitDefinitiveOverflowFailure = () => {
|
|
1152
|
-
this.emit({
|
|
1153
|
-
type: 'compaction_end',
|
|
1154
|
-
reason: 'overflow',
|
|
1155
|
-
result: undefined,
|
|
1156
|
-
aborted: false,
|
|
1157
|
-
willRetry: false,
|
|
1158
|
-
errorMessage: 'Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model.',
|
|
1159
|
-
});
|
|
1160
|
-
};
|
|
1161
|
-
this.streaming = true;
|
|
1162
|
-
await this.fire('agent_start', {}, ctx);
|
|
1163
|
-
this.emit({ type: 'agent_start' });
|
|
1164
|
-
await emitAttemptEnd();
|
|
1165
|
-
if (cmd.outcome === 'recover') {
|
|
1166
|
-
this.emit({
|
|
1167
|
-
type: 'compaction_end',
|
|
1168
|
-
reason: 'overflow',
|
|
1169
|
-
result: { summary: 'compacted', firstKeptEntryId: 'entry-1', tokensBefore: 200_000 },
|
|
1170
|
-
aborted: false,
|
|
1171
|
-
willRetry: true,
|
|
1172
|
-
});
|
|
1173
|
-
await emitRecoveredContinuation();
|
|
1174
|
-
}
|
|
1175
|
-
else if (cmd.outcome === 'fail') {
|
|
1176
|
-
this.emit({
|
|
1177
|
-
type: 'compaction_end',
|
|
1178
|
-
reason: 'overflow',
|
|
1179
|
-
result: { summary: 'compacted', firstKeptEntryId: 'entry-1', tokensBefore: 200_000 },
|
|
1180
|
-
aborted: false,
|
|
1181
|
-
willRetry: true,
|
|
1182
|
-
});
|
|
1183
|
-
await this.fire('agent_start', {}, ctx);
|
|
1184
|
-
this.emit({ type: 'agent_start' });
|
|
1185
|
-
await emitAttemptEnd();
|
|
1186
|
-
emitDefinitiveOverflowFailure();
|
|
1187
|
-
}
|
|
1188
|
-
else if (cmd.outcome === 'failure-continued') {
|
|
1189
|
-
emitDefinitiveOverflowFailure();
|
|
1190
|
-
await emitRecoveredContinuation();
|
|
1191
|
-
}
|
|
1192
|
-
this.streaming = false;
|
|
1193
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
1194
|
-
this.emit({ type: 'agent_settled' });
|
|
1195
|
-
writeFileSync(join(this.dir, 'fake-pi.overflow.json'), JSON.stringify({ outcome: cmd.outcome ?? 'uncompacted' }));
|
|
1196
|
-
break;
|
|
1197
|
-
}
|
|
1198
|
-
case 'auto_retry': {
|
|
1199
|
-
// Pi emits agent_end for the failed attempt, then auto_retry_start, and
|
|
1200
|
-
// only then creates the AbortController for its delay. The capacity
|
|
1201
|
-
// fallback must defer abortRetry one microtask to cancel this retry.
|
|
1202
|
-
const retryMessages = [{
|
|
1203
|
-
role: 'assistant', stopReason: 'error', errorMessage: cmd.errorMessage ?? 'rate limit exceeded', content: [],
|
|
1204
|
-
}];
|
|
1205
|
-
this.streaming = true;
|
|
1206
|
-
await this.fire('agent_end', { messages: retryMessages }, ctx);
|
|
1207
|
-
this.emit({ type: 'agent_end', messages: retryMessages, willRetry: true });
|
|
1208
|
-
this.emit({ type: 'auto_retry_start', errorMessage: cmd.errorMessage ?? 'rate limit exceeded' });
|
|
1209
|
-
let aborted = false;
|
|
1210
|
-
this.retryAbort = () => { aborted = true; };
|
|
1211
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
1212
|
-
this.retryAbort = undefined;
|
|
1213
|
-
if (aborted)
|
|
1214
|
-
this.emit({ type: 'auto_retry_end', success: false, finalError: 'Retry cancelled' });
|
|
1215
|
-
this.streaming = false;
|
|
1216
|
-
await this.fire('agent_settled', { type: 'agent_settled' }, ctx);
|
|
1217
|
-
this.emit({ type: 'agent_settled' });
|
|
1218
|
-
writeFileSync(join(this.dir, 'fake-pi.auto-retry.json'), JSON.stringify({ at: Date.now(), aborted }));
|
|
1219
|
-
break;
|
|
1220
|
-
}
|
|
1221
|
-
case 'display':
|
|
1222
|
-
// Paint through the broker's REAL uiContext exactly as an extension does.
|
|
1223
|
-
// These are LEVELS with no pi getter, so the broker is their only holder
|
|
1224
|
-
// and must carry them in the catch-up snapshot for a LATE joiner.
|
|
1225
|
-
this.uiContext?.setStatus?.(cmd.text ?? 'k', cmd.reason ?? 'v');
|
|
1226
|
-
this.uiContext?.setWidget?.(cmd.text ?? 'k', [cmd.reason ?? 'v'], {
|
|
1227
|
-
placement: 'aboveEditor',
|
|
1228
|
-
});
|
|
1229
|
-
this.uiContext?.setTitle?.(cmd.reason ?? 'v');
|
|
1230
|
-
break;
|
|
1231
|
-
case 'dialog':
|
|
1232
|
-
// Raise a blocking confirm() through the broker's REAL uiContext. The path
|
|
1233
|
-
// taken depends on who is attached when it raises:
|
|
1234
|
-
// • ZERO viewers (C2 / G6a): makeBrokerUiContext resolves the default
|
|
1235
|
-
// (false) IMMEDIATELY — noOp fallback, no timer, no wait, no deadlock.
|
|
1236
|
-
// • a controller attached (G5): forwarded as an extension_ui_request the
|
|
1237
|
-
// controller answers via extension_ui_response — the engine proceeds.
|
|
1238
|
-
// • a controller attached but silent (G6b): resolves on the broker-side
|
|
1239
|
-
// timeout. Pass a SHORT explicit per-dialog `timeout` so that path is
|
|
1240
|
-
// fast and deterministic (never the broker's 120s default).
|
|
1241
|
-
await this.runDialog(cmd.timeout ?? 0);
|
|
1242
|
-
break;
|
|
1243
|
-
default:
|
|
1244
|
-
recordError(this.dir, `unknown cmd: ${String(cmd.cmd)}`);
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
async runDialog(timeout) {
|
|
1248
|
-
const start = Date.now();
|
|
1249
|
-
try {
|
|
1250
|
-
const resolved = await Promise.resolve(this.uiContext?.confirm?.('headless-dialog', 'forward-progress check', { timeout }));
|
|
1251
|
-
appendFileSync(join(this.dir, 'fake-pi.dialog.jsonl'), JSON.stringify({ resolved: resolved ?? null, ms: Date.now() - start, ts: Date.now() }) + '\n');
|
|
1252
|
-
}
|
|
1253
|
-
catch (e) {
|
|
1254
|
-
recordError(this.dir, `dialog: ${String(e)}`);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
}
|
|
1258
|
-
function fakeModel(provider, id) {
|
|
1259
|
-
try {
|
|
1260
|
-
const capacities = JSON.parse(readFileSync(join(nodeDirFromEnv(), 'fake-pi.model-capacities.json'), 'utf8'));
|
|
1261
|
-
const contextWindow = capacities[`${provider}/${id}`];
|
|
1262
|
-
return typeof contextWindow === 'number' && Number.isFinite(contextWindow)
|
|
1263
|
-
? { provider, id, contextWindow }
|
|
1264
|
-
: { provider, id };
|
|
1265
|
-
}
|
|
1266
|
-
catch {
|
|
1267
|
-
return { provider, id };
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
/** The real pi SDK's model-less sentinel (Agent.DEFAULT_MODEL). The fake mirrors
|
|
1271
|
-
* it so `session.model` is NEVER literally `undefined` after a model-less boot,
|
|
1272
|
-
* matching prod — see the FakeSession constructor. */
|
|
1273
|
-
const UNKNOWN_MODEL_STUB = { provider: 'unknown', id: 'unknown', api: 'unknown' };
|
|
1274
|
-
function isUnknownModelStub(m) {
|
|
1275
|
-
return m !== undefined && m.provider === 'unknown' && m.id === 'unknown' && m.api === 'unknown';
|
|
1276
|
-
}
|
|
1277
|
-
const FAKE_AVAILABLE_MODEL = { provider: 'fake', id: 'fake-model' };
|
|
1278
|
-
// Every model cell the default ladders (types.ts defaultModelLaddersConfig) can
|
|
1279
|
-
// resolve to must appear here: `getModels()` IS the ordered fallback set the
|
|
1280
|
-
// broker's launch resolver enumerates, so a ladder cell missing from this roster
|
|
1281
|
-
// resolves as a bare stub through `getModel()` yet can never be chosen as a
|
|
1282
|
-
// fallback — which silently inverts fallback direction. Keep in step with the
|
|
1283
|
-
// ladders.
|
|
1284
|
-
const FAKE_REGISTERED_MODELS = [
|
|
1285
|
-
{ provider: 'anthropic', id: 'claude-fable-5' },
|
|
1286
|
-
{ provider: 'anthropic', id: 'claude-opus-5' },
|
|
1287
|
-
{ provider: 'anthropic', id: 'claude-opus-4-8' },
|
|
1288
|
-
{ provider: 'anthropic', id: 'claude-sonnet-5' },
|
|
1289
|
-
{ provider: 'anthropic', id: 'claude-haiku-4-5' },
|
|
1290
|
-
{ provider: 'openai-codex', id: 'gpt-6-astra' },
|
|
1291
|
-
{ provider: 'openai-codex', id: 'gpt-5.6-sol' },
|
|
1292
|
-
{ provider: 'openai-codex', id: 'gpt-5.6-terra' },
|
|
1293
|
-
{ provider: 'openai-codex', id: 'gpt-5.6-luna' },
|
|
1294
|
-
FAKE_AVAILABLE_MODEL,
|
|
1295
|
-
];
|
|
1296
|
-
/** Source harnesses use native imports only for an isolated, mandatory-only
|
|
1297
|
-
* canvas fixture. Every other source stays on the SDK file-loader path. */
|
|
1298
|
-
async function sourceCanvasExtensionLoaderOptions(cwd, agentDir, options) {
|
|
1299
|
-
const extensionPaths = options?.additionalExtensionPaths;
|
|
1300
|
-
const mandatoryOnly = extensionPaths?.length === CANVAS_EXTENSIONS.length
|
|
1301
|
-
&& extensionPaths.every((path, index) => path === CANVAS_EXTENSIONS[index]);
|
|
1302
|
-
if (!import.meta.url.endsWith('.ts') || !mandatoryOnly)
|
|
1303
|
-
return { additionalExtensionPaths: extensionPaths };
|
|
1304
|
-
const settingsManager = SettingsManager.create(cwd, agentDir);
|
|
1305
|
-
const resolved = await new DefaultPackageManager({ cwd, agentDir, settingsManager }).resolve();
|
|
1306
|
-
if (resolved.extensions.some((extension) => extension.enabled)) {
|
|
1307
|
-
return { additionalExtensionPaths: extensionPaths, settingsManager };
|
|
1308
|
-
}
|
|
1309
|
-
const inlinePaths = new Map();
|
|
1310
|
-
const fileLoaderErrors = new Map();
|
|
1311
|
-
const missingPaths = [];
|
|
1312
|
-
const extensionFactories = [];
|
|
1313
|
-
for (const inputPath of extensionPaths) {
|
|
1314
|
-
const path = resolve(cwd, inputPath);
|
|
1315
|
-
if (!existsSync(path)) {
|
|
1316
|
-
missingPaths.push(path);
|
|
1317
|
-
continue;
|
|
1318
|
-
}
|
|
1319
|
-
inlinePaths.set(`<inline:${path}>`, path);
|
|
1320
|
-
let factory;
|
|
1321
|
-
try {
|
|
1322
|
-
const loaded = await import(path);
|
|
1323
|
-
if (typeof loaded.default !== 'function') {
|
|
1324
|
-
fileLoaderErrors.set(path, `Extension does not export a valid factory function: ${path}`);
|
|
1325
|
-
factory = () => { throw new Error(fileLoaderErrors.get(path)); };
|
|
1326
|
-
}
|
|
1327
|
-
else {
|
|
1328
|
-
factory = loaded.default;
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
catch {
|
|
1332
|
-
// Let the original loader produce its own import/transform diagnostic.
|
|
1333
|
-
return { additionalExtensionPaths: extensionPaths, settingsManager };
|
|
1334
|
-
}
|
|
1335
|
-
extensionFactories.push({ name: path, factory });
|
|
1336
|
-
}
|
|
1337
|
-
return {
|
|
1338
|
-
additionalExtensionPaths: [],
|
|
1339
|
-
extensionFactories,
|
|
1340
|
-
settingsManager,
|
|
1341
|
-
restoreCliExtensionMetadata: (loader) => {
|
|
1342
|
-
const result = loader.getExtensions();
|
|
1343
|
-
for (const extension of result.extensions) {
|
|
1344
|
-
const path = inlinePaths.get(extension.path);
|
|
1345
|
-
if (path === undefined)
|
|
1346
|
-
continue;
|
|
1347
|
-
const sourceInfo = { path, source: 'cli', scope: 'temporary', origin: 'top-level', baseDir: undefined };
|
|
1348
|
-
extension.path = path;
|
|
1349
|
-
extension.resolvedPath = path;
|
|
1350
|
-
extension.sourceInfo = sourceInfo;
|
|
1351
|
-
for (const command of extension.commands.values())
|
|
1352
|
-
command.sourceInfo = sourceInfo;
|
|
1353
|
-
for (const tool of extension.tools.values())
|
|
1354
|
-
tool.sourceInfo = sourceInfo;
|
|
1355
|
-
}
|
|
1356
|
-
for (const error of result.errors) {
|
|
1357
|
-
const path = inlinePaths.get(error.path);
|
|
1358
|
-
if (path !== undefined) {
|
|
1359
|
-
error.path = path;
|
|
1360
|
-
const isConflict = /^(?:Tool|Flag) ".*" conflicts with /.test(error.error);
|
|
1361
|
-
error.error = fileLoaderErrors.get(path) ?? (isConflict ? error.error : `Failed to load extension: ${error.error}`);
|
|
1362
|
-
}
|
|
1363
|
-
for (const [inlinePath, filePath] of inlinePaths) {
|
|
1364
|
-
error.error = error.error.replaceAll(inlinePath, filePath);
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
result.errors.push(...missingPaths.map((path) => ({ path, error: `Extension path does not exist: ${path}` })));
|
|
1368
|
-
},
|
|
1369
|
-
};
|
|
1370
|
-
}
|
|
1371
|
-
export async function createAgentSessionServices(options) {
|
|
1372
|
-
const agentDir = options.agentDir ?? getAgentDir();
|
|
1373
|
-
const extensionOptions = await sourceCanvasExtensionLoaderOptions(options.cwd, agentDir, options.resourceLoaderOptions);
|
|
1374
|
-
const { restoreCliExtensionMetadata, ...loaderOptions } = extensionOptions;
|
|
1375
|
-
const loader = new DefaultResourceLoader({
|
|
1376
|
-
cwd: options.cwd,
|
|
1377
|
-
agentDir,
|
|
1378
|
-
...loaderOptions,
|
|
1379
|
-
appendSystemPrompt: options.resourceLoaderOptions?.appendSystemPrompt,
|
|
1380
|
-
});
|
|
1381
|
-
await loader.reload();
|
|
1382
|
-
restoreCliExtensionMetadata?.(loader);
|
|
1383
|
-
// Zero-auth test seam. While <CRTR_HOME>/fake-pi.no-auth exists, the registry
|
|
1384
|
-
// reports a GENUINE zero-auth boot (nothing registered, nothing authenticated)
|
|
1385
|
-
// so resolveLaunchModel (broker.ts) falls all the way to a tier-3 model-less
|
|
1386
|
-
// boot — the stock always-authenticated FAKE_AVAILABLE_MODEL below can't
|
|
1387
|
-
// express that. Two properties matter, both satisfied by a HOME-level sentinel
|
|
1388
|
-
// FILE checked LIVE (not a one-shot env read — custom env vars don't survive
|
|
1389
|
-
// cleanBaseEnv into the initial `node new --headless` boot):
|
|
1390
|
-
// • RACE-FREE ARMING: the test writes it BEFORE spawning (no per-node-dir
|
|
1391
|
-
// dependency on an id that only exists post-spawn, and the broker races to
|
|
1392
|
-
// read the registry the instant it boots).
|
|
1393
|
-
// • LIVE FLIP: a reload_auth frame's modelRegistry.refresh() re-reads these
|
|
1394
|
-
// getters, so DELETING the sentinel mid-test flips auth ON and the broker's
|
|
1395
|
-
// reload_auth re-drive observes it with zero extra plumbing — the exact
|
|
1396
|
-
// login/re-drive transition.
|
|
1397
|
-
// Absent (the common case) → unchanged always-authenticated behavior.
|
|
1398
|
-
const home = (process.env['CRTR_HOME'] ?? '').trim();
|
|
1399
|
-
const noAuthSentinel = join(home, 'fake-pi.no-auth');
|
|
1400
|
-
const unauthenticatedProviderSentinel = join(home, 'fake-pi.unauthenticated-provider');
|
|
1401
|
-
const zeroAuth = () => home !== '' && existsSync(noAuthSentinel);
|
|
1402
|
-
const readUnauthenticatedProvider = () => {
|
|
1403
|
-
try {
|
|
1404
|
-
return readFileSync(unauthenticatedProviderSentinel, 'utf8').trim() || undefined;
|
|
1405
|
-
}
|
|
1406
|
-
catch {
|
|
1407
|
-
return undefined;
|
|
1408
|
-
}
|
|
1409
|
-
};
|
|
1410
|
-
// Unlike the all-or-nothing no-auth seam, this mirrors ModelRuntime's cached
|
|
1411
|
-
// configuredProviders snapshot: a provider-specific auth change becomes
|
|
1412
|
-
// visible only after refresh() completes.
|
|
1413
|
-
let unauthenticatedProvider = readUnauthenticatedProvider();
|
|
1414
|
-
return {
|
|
1415
|
-
resourceLoader: loader,
|
|
1416
|
-
modelRuntime: {
|
|
1417
|
-
// A minimal model stub for any spec — the set_model regression test drives
|
|
1418
|
-
// the broker's findModelSpec → session.setModel path through it. Nothing is
|
|
1419
|
-
// findable during a zero-auth window.
|
|
1420
|
-
getModel: (provider, id) => (zeroAuth() ? undefined : fakeModel(provider, id)),
|
|
1421
|
-
// Always-authenticated single fake model — the M-9 no-boot-model branch
|
|
1422
|
-
// (broker.ts) picks `available[0]` and must never see an empty list here —
|
|
1423
|
-
// EXCEPT during a zero-auth window, when nothing is available/registered.
|
|
1424
|
-
getAvailableSnapshot: () => (zeroAuth() ? [] : [FAKE_AVAILABLE_MODEL]),
|
|
1425
|
-
getAvailable: async () => (zeroAuth() ? [] : [FAKE_AVAILABLE_MODEL]),
|
|
1426
|
-
getModels: () => (zeroAuth() ? [] : FAKE_REGISTERED_MODELS),
|
|
1427
|
-
hasConfiguredAuth: (provider) => !zeroAuth() && provider !== unauthenticatedProvider,
|
|
1428
|
-
getError: () => undefined,
|
|
1429
|
-
refresh: async () => {
|
|
1430
|
-
await new Promise((resolve) => setImmediate(resolve));
|
|
1431
|
-
unauthenticatedProvider = readUnauthenticatedProvider();
|
|
1432
|
-
},
|
|
1433
|
-
},
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
export async function createAgentSessionFromServices(options) {
|
|
1437
|
-
const session = new FakeSession(options.sessionManager, options.services.resourceLoader, options.model, options.services.modelRuntime);
|
|
1438
|
-
// Parity with the real SDK: a construction-time thinking level IS the
|
|
1439
|
-
// session's thinking level from the first turn on. The broker formats
|
|
1440
|
-
// `model:thinking` off this getter, and that suffix is what distinguishes two
|
|
1441
|
-
// ladder cells sharing one model id — dropping it here silently misroutes
|
|
1442
|
-
// turn-time rotation.
|
|
1443
|
-
if (options.thinkingLevel !== undefined)
|
|
1444
|
-
session.setThinkingLevel(options.thinkingLevel);
|
|
1445
|
-
return { session };
|
|
1446
|
-
}
|
|
1447
|
-
class FakeAgentSessionRuntime {
|
|
1448
|
-
createRuntime;
|
|
1449
|
-
cwd;
|
|
1450
|
-
agentDir;
|
|
1451
|
-
session;
|
|
1452
|
-
services;
|
|
1453
|
-
rebindSession;
|
|
1454
|
-
constructor(createRuntime, cwd, agentDir, session, services) {
|
|
1455
|
-
this.createRuntime = createRuntime;
|
|
1456
|
-
this.cwd = cwd;
|
|
1457
|
-
this.agentDir = agentDir;
|
|
1458
|
-
this.session = session;
|
|
1459
|
-
this.services = services;
|
|
1460
|
-
}
|
|
1461
|
-
setRebindSession(rebindSession) {
|
|
1462
|
-
this.rebindSession = rebindSession;
|
|
1463
|
-
}
|
|
1464
|
-
async newSession() {
|
|
1465
|
-
const next = await this.createRuntime({ cwd: this.cwd, agentDir: this.agentDir, sessionManager: SessionManager.create(this.cwd) });
|
|
1466
|
-
this.session = next.session;
|
|
1467
|
-
this.services = next.services;
|
|
1468
|
-
await this.rebindSession?.(next.session);
|
|
1469
|
-
return { cancelled: false };
|
|
1470
|
-
}
|
|
1471
|
-
async dispose() {
|
|
1472
|
-
this.session.dispose();
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
export async function createAgentSessionRuntime(createRuntime, options) {
|
|
1476
|
-
const initial = await createRuntime(options);
|
|
1477
|
-
return new FakeAgentSessionRuntime(createRuntime, options.cwd, options.agentDir, initial.session, initial.services);
|
|
1478
|
-
}
|
|
1479
|
-
// VERSION — set to the SDK's published version so assertEngineVersion (which
|
|
1480
|
-
// only logs, never throws) emits no spurious mismatch warning.
|
|
1481
|
-
export const VERSION = '0.78.1';
|
|
1482
|
-
// Parse the broker-launch.json recipe the host serialized (the PiInvocation
|
|
1483
|
-
// buildPiArgv produced) for the proof shape — the same `-e`/`-n`/positional
|
|
1484
|
-
// vocabulary fake-pi-host parses off its argv.
|
|
1485
|
-
function readLaunch(dir) {
|
|
1486
|
-
let argv = [];
|
|
1487
|
-
try {
|
|
1488
|
-
const inv = JSON.parse(readFileSync(join(dir, 'broker-launch.json'), 'utf8'));
|
|
1489
|
-
argv = Array.isArray(inv.argv) ? inv.argv : [];
|
|
1490
|
-
}
|
|
1491
|
-
catch {
|
|
1492
|
-
/* no launch file — leave argv empty */
|
|
1493
|
-
}
|
|
1494
|
-
const extPaths = [];
|
|
1495
|
-
let label;
|
|
1496
|
-
let prompt;
|
|
1497
|
-
for (let i = 0; i < argv.length; i++) {
|
|
1498
|
-
const a = argv[i];
|
|
1499
|
-
if (a === '-e')
|
|
1500
|
-
extPaths.push(argv[++i]);
|
|
1501
|
-
else if (a === '-n')
|
|
1502
|
-
label = argv[++i];
|
|
1503
|
-
else if (a === '--session' || a === '--model' || a === '--tools' || a === '--append-system-prompt' || a === '--fork')
|
|
1504
|
-
i++;
|
|
1505
|
-
else if (!a.startsWith('-'))
|
|
1506
|
-
prompt = a; // positional kickoff (fresh start only)
|
|
1507
|
-
}
|
|
1508
|
-
return { argv, extPaths, label, prompt };
|
|
1509
|
-
}
|