@astrale-os/cli 1.0.0-beta.8 → 1.0.0-npm-deprecated.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -166
- package/package.json +10 -102
- package/.check-workspace.cjs +0 -40
- package/LICENSE +0 -202
- package/THIRD-PARTY-NOTICES.md +0 -27
- package/dist/astrale.js +0 -93172
- package/dist/public/connect-core.js +0 -29187
- package/dist/public/keys/index.js +0 -5651
- package/dist/public/paths/index.js +0 -4282
- package/dist/types/admin/instance/model.d.ts +0 -39
- package/dist/types/connect-core.d.ts +0 -22
- package/dist/types/connection/auth.d.ts +0 -36
- package/dist/types/errors.d.ts +0 -23
- package/dist/types/identity/registry.d.ts +0 -25
- package/dist/types/keys/algorithm.d.ts +0 -6
- package/dist/types/keys/credential.d.ts +0 -21
- package/dist/types/keys/index.d.ts +0 -4
- package/dist/types/keys/pair.d.ts +0 -34
- package/dist/types/lib/admin-target.d.ts +0 -78
- package/dist/types/lib/ca-fetch.d.ts +0 -2
- package/dist/types/lib/config.d.ts +0 -71
- package/dist/types/lib/failure-debug.d.ts +0 -1
- package/dist/types/lib/format.d.ts +0 -1
- package/dist/types/lib/idp-session.d.ts +0 -33
- package/dist/types/lib/idp.d.ts +0 -404
- package/dist/types/lib/instance-target.d.ts +0 -38
- package/dist/types/lib/instance.d.ts +0 -196
- package/dist/types/lib/invocation.d.ts +0 -3
- package/dist/types/lib/log.d.ts +0 -33
- package/dist/types/lib/login-flow.d.ts +0 -49
- package/dist/types/lib/meta.d.ts +0 -36
- package/dist/types/lib/output.d.ts +0 -87
- package/dist/types/lib/proc.d.ts +0 -43
- package/dist/types/lib/table.d.ts +0 -18
- package/dist/types/lib/update.d.ts +0 -131
- package/dist/types/lib/validation.d.ts +0 -11
- package/dist/types/paths/index.d.ts +0 -2
- package/dist/types/state/exchange-credentials.d.ts +0 -25
- package/dist/types/state/files.d.ts +0 -9
- package/dist/types/state/identities.d.ts +0 -42
- package/dist/types/state/index.d.ts +0 -8
- package/dist/types/state/paths.d.ts +0 -32
- package/src/__tests__/fixtures/publication.ts +0 -20
- package/src/admin/.spec/api.d.ts +0 -3
- package/src/admin/.spec/architecture.md +0 -15
- package/src/admin/.spec/icon.svg +0 -3
- package/src/admin/.spec/layout.ts +0 -6
- package/src/admin/__tests__/binding.test.ts +0 -31
- package/src/admin/__tests__/fixture.ts +0 -101
- package/src/admin/binding.ts +0 -98
- package/src/admin/catalog/.spec/api.d.ts +0 -65
- package/src/admin/catalog/.spec/architecture.md +0 -6
- package/src/admin/catalog/.spec/icon.svg +0 -3
- package/src/admin/catalog/.spec/layout.ts +0 -6
- package/src/admin/catalog/__tests__/client.test.ts +0 -142
- package/src/admin/catalog/client.ts +0 -218
- package/src/admin/catalog/index.ts +0 -13
- package/src/admin/catalog/model.ts +0 -41
- package/src/admin/catalog/tsconfig.json +0 -8
- package/src/admin/graph/.spec/api.d.ts +0 -22
- package/src/admin/graph/.spec/architecture.md +0 -5
- package/src/admin/graph/.spec/icon.svg +0 -3
- package/src/admin/graph/.spec/layout.ts +0 -3
- package/src/admin/graph/index.ts +0 -6
- package/src/admin/graph/nodes.ts +0 -56
- package/src/admin/index.ts +0 -2
- package/src/admin/instance/.spec/api.d.ts +0 -66
- package/src/admin/instance/.spec/architecture.md +0 -10
- package/src/admin/instance/.spec/icon.svg +0 -3
- package/src/admin/instance/.spec/layout.ts +0 -6
- package/src/admin/instance/__tests__/client.test.ts +0 -266
- package/src/admin/instance/client.ts +0 -290
- package/src/admin/instance/index.ts +0 -16
- package/src/admin/instance/model.ts +0 -66
- package/src/admin/instance/tsconfig.json +0 -8
- package/src/commands/__tests__/admin-instance.test.ts +0 -88
- package/src/commands/__tests__/auth-login.test.ts +0 -231
- package/src/commands/__tests__/auth-token.test.ts +0 -223
- package/src/commands/__tests__/call-describe.test.ts +0 -80
- package/src/commands/__tests__/call.test.ts +0 -29
- package/src/commands/__tests__/domain-install-operation.test.ts +0 -126
- package/src/commands/__tests__/domain-install-owned.test.ts +0 -191
- package/src/commands/__tests__/domain-list.test.ts +0 -133
- package/src/commands/__tests__/domain-uninstall.test.ts +0 -53
- package/src/commands/__tests__/install-direct.test.ts +0 -21
- package/src/commands/__tests__/install-identity-override.test.ts +0 -76
- package/src/commands/__tests__/instance-bookmark.test.ts +0 -166
- package/src/commands/__tests__/instance-create-hosts.test.ts +0 -29
- package/src/commands/__tests__/instance-list-admin.test.ts +0 -26
- package/src/commands/__tests__/instance-list-rows.test.ts +0 -64
- package/src/commands/__tests__/instance-use.test.ts +0 -67
- package/src/commands/__tests__/introspect-parse.test.ts +0 -21
- package/src/commands/__tests__/logs.test.ts +0 -97
- package/src/commands/__tests__/read-commands.test.ts +0 -294
- package/src/commands/__tests__/setup-plan.test.ts +0 -61
- package/src/commands/__tests__/studio-descriptor.test.ts +0 -22
- package/src/commands/__tests__/token-ttl.test.ts +0 -21
- package/src/commands/__tests__/update.test.ts +0 -95
- package/src/commands/__tests__/view-build.test.ts +0 -58
- package/src/commands/__tests__/view.test.ts +0 -149
- package/src/commands/admin/status.ts +0 -61
- package/src/commands/admin/use.ts +0 -100
- package/src/commands/auth/login.ts +0 -82
- package/src/commands/auth/logout.ts +0 -52
- package/src/commands/auth/status.ts +0 -86
- package/src/commands/auth/token.ts +0 -174
- package/src/commands/browser.ts +0 -207
- package/src/commands/call-describe.ts +0 -123
- package/src/commands/call.ts +0 -205
- package/src/commands/domain/install.ts +0 -548
- package/src/commands/domain/list.ts +0 -155
- package/src/commands/domain/publish.ts +0 -133
- package/src/commands/domain/uninstall.ts +0 -128
- package/src/commands/get.ts +0 -69
- package/src/commands/identity/__tests__/register.test.ts +0 -93
- package/src/commands/identity/create.ts +0 -35
- package/src/commands/identity/delete.ts +0 -24
- package/src/commands/identity/export.ts +0 -46
- package/src/commands/identity/import.ts +0 -61
- package/src/commands/identity/list.ts +0 -56
- package/src/commands/identity/register.ts +0 -196
- package/src/commands/identity/sync.ts +0 -38
- package/src/commands/identity/unsync.ts +0 -34
- package/src/commands/identity/use.ts +0 -24
- package/src/commands/identity/whoami.ts +0 -34
- package/src/commands/idp/add.ts +0 -150
- package/src/commands/idp/list.ts +0 -57
- package/src/commands/idp/refresh.ts +0 -38
- package/src/commands/idp/remove.ts +0 -36
- package/src/commands/idp/show.ts +0 -29
- package/src/commands/instance/active.ts +0 -73
- package/src/commands/instance/bookmark.ts +0 -101
- package/src/commands/instance/create.ts +0 -69
- package/src/commands/instance/delete.ts +0 -68
- package/src/commands/instance/forget.ts +0 -26
- package/src/commands/instance/list.ts +0 -197
- package/src/commands/instance/status.ts +0 -38
- package/src/commands/instance/use.ts +0 -259
- package/src/commands/introspect.ts +0 -110
- package/src/commands/logs.ts +0 -283
- package/src/commands/mutate.ts +0 -122
- package/src/commands/query.ts +0 -136
- package/src/commands/session/analyze.ts +0 -50
- package/src/commands/session/list.ts +0 -36
- package/src/commands/setup.ts +0 -54
- package/src/commands/status.ts +0 -60
- package/src/commands/studio.ts +0 -434
- package/src/commands/token.ts +0 -107
- package/src/commands/update.ts +0 -334
- package/src/commands/use.ts +0 -86
- package/src/commands/view-serve.ts +0 -26
- package/src/commands/view.ts +0 -614
- package/src/connect-core.test.ts +0 -38
- package/src/connect-core.ts +0 -42
- package/src/connection/.spec/api.d.ts +0 -110
- package/src/connection/.spec/architecture.md +0 -47
- package/src/connection/.spec/capabilities/connection.ts +0 -13
- package/src/connection/.spec/examples/call.ts +0 -7
- package/src/connection/.spec/flows/command.ts +0 -20
- package/src/connection/.spec/flows/session.ts +0 -61
- package/src/connection/.spec/laws/connection.ts +0 -205
- package/src/connection/.spec/layout.ts +0 -21
- package/src/connection/__tests__/auth.test.ts +0 -128
- package/src/connection/__tests__/ca-fetch.test.ts +0 -60
- package/src/connection/__tests__/call.test.ts +0 -17
- package/src/connection/__tests__/credential.test.ts +0 -119
- package/src/connection/__tests__/errors.test.ts +0 -577
- package/src/connection/__tests__/exchange.test.ts +0 -295
- package/src/connection/__tests__/failure-fixtures.ts +0 -39
- package/src/connection/__tests__/failure-safety.test.ts +0 -75
- package/src/connection/__tests__/fixtures/localhost-cert.pem +0 -19
- package/src/connection/__tests__/fixtures/localhost-key.base64 +0 -1
- package/src/connection/__tests__/managed.test.ts +0 -39
- package/src/connection/__tests__/reasons.test.ts +0 -78
- package/src/connection/__tests__/self.test.ts +0 -71
- package/src/connection/__tests__/session.test.ts +0 -140
- package/src/connection/__tests__/target.test.ts +0 -93
- package/src/connection/auth.ts +0 -236
- package/src/connection/call.ts +0 -7
- package/src/connection/command.ts +0 -67
- package/src/connection/credential.ts +0 -117
- package/src/connection/errors.ts +0 -1
- package/src/connection/exchange.ts +0 -311
- package/src/connection/failure/classify.ts +0 -110
- package/src/connection/failure/index.ts +0 -18
- package/src/connection/failure/model.ts +0 -28
- package/src/connection/failure/render.ts +0 -116
- package/src/connection/index.ts +0 -8
- package/src/connection/reasons.ts +0 -209
- package/src/connection/self.ts +0 -138
- package/src/connection/session.ts +0 -185
- package/src/connection/target.ts +0 -112
- package/src/connection/tsconfig.json +0 -6
- package/src/errors.ts +0 -66
- package/src/graph/.spec/api.d.ts +0 -41
- package/src/graph/.spec/laws/documents.ts +0 -24
- package/src/graph/.spec/laws/projection.ts +0 -13
- package/src/graph/.spec/layout.ts +0 -14
- package/src/graph/__tests__/mutation.test.ts +0 -51
- package/src/graph/__tests__/projection.test.ts +0 -22
- package/src/graph/__tests__/query.test.ts +0 -173
- package/src/graph/class.ts +0 -30
- package/src/graph/index.ts +0 -4
- package/src/graph/mutation.ts +0 -46
- package/src/graph/projection.ts +0 -21
- package/src/graph/query.ts +0 -97
- package/src/graph/tsconfig.json +0 -6
- package/src/identity/.history/ard/bootstrap-root-transfer.md +0 -57
- package/src/identity/.history/ard/domain-mediated-registration.md +0 -36
- package/src/identity/.spec/api.d.ts +0 -124
- package/src/identity/.spec/architecture.md +0 -33
- package/src/identity/.spec/capabilities/identity.ts +0 -7
- package/src/identity/.spec/flows/bootstrap-root.ts +0 -79
- package/src/identity/.spec/flows/domain-mediated-registration.ts +0 -51
- package/src/identity/.spec/flows/import.ts +0 -29
- package/src/identity/.spec/laws/identity.ts +0 -56
- package/src/identity/.spec/layout.ts +0 -13
- package/src/identity/.spec/schemas/identity-export-v1.schema.json +0 -25
- package/src/identity/__tests__/fixtures/registry-journey.ts +0 -53
- package/src/identity/__tests__/registration.test.ts +0 -64
- package/src/identity/__tests__/registry.test.ts +0 -70
- package/src/identity/__tests__/transfer.test.ts +0 -198
- package/src/identity/index.ts +0 -23
- package/src/identity/registration.ts +0 -72
- package/src/identity/registry.ts +0 -179
- package/src/identity/transfer.ts +0 -187
- package/src/identity/tsconfig.json +0 -6
- package/src/index.ts +0 -1
- package/src/keys/.spec/api.d.ts +0 -74
- package/src/keys/.spec/architecture.md +0 -13
- package/src/keys/.spec/laws/keys.ts +0 -43
- package/src/keys/.spec/layout.ts +0 -6
- package/src/keys/__tests__/algorithm.test.ts +0 -39
- package/src/keys/__tests__/keys.test.ts +0 -168
- package/src/keys/algorithm.ts +0 -33
- package/src/keys/credential.ts +0 -112
- package/src/keys/index.ts +0 -14
- package/src/keys/pair.ts +0 -219
- package/src/keys/tsconfig.json +0 -6
- package/src/lib/__tests__/admin-target.test.ts +0 -184
- package/src/lib/__tests__/binary.test.ts +0 -55
- package/src/lib/__tests__/command-dx.test.ts +0 -102
- package/src/lib/__tests__/concurrency.test.ts +0 -62
- package/src/lib/__tests__/config.test.ts +0 -54
- package/src/lib/__tests__/design.test.ts +0 -99
- package/src/lib/__tests__/domain-publication.test.ts +0 -133
- package/src/lib/__tests__/format.test.ts +0 -22
- package/src/lib/__tests__/idp-session.driver.ts +0 -53
- package/src/lib/__tests__/idp-session.test.ts +0 -379
- package/src/lib/__tests__/idp.test.ts +0 -415
- package/src/lib/__tests__/instance-candidates.test.ts +0 -148
- package/src/lib/__tests__/instance-target.test.ts +0 -212
- package/src/lib/__tests__/instance.test.ts +0 -192
- package/src/lib/__tests__/local-status.test.ts +0 -202
- package/src/lib/__tests__/log-errors.test.ts +0 -64
- package/src/lib/__tests__/log.test.ts +0 -31
- package/src/lib/__tests__/meta.test.ts +0 -55
- package/src/lib/__tests__/output.test.ts +0 -162
- package/src/lib/__tests__/panel.test.ts +0 -40
- package/src/lib/__tests__/port.test.ts +0 -44
- package/src/lib/__tests__/prompt.test.ts +0 -25
- package/src/lib/__tests__/sdk-deps.test.ts +0 -68
- package/src/lib/__tests__/self.test.ts +0 -50
- package/src/lib/__tests__/studio-server-deps.test.ts +0 -111
- package/src/lib/__tests__/table.test.ts +0 -53
- package/src/lib/__tests__/update.test.ts +0 -351
- package/src/lib/__tests__/use-target.test.ts +0 -56
- package/src/lib/__tests__/validation.test.ts +0 -34
- package/src/lib/__tests__/view-assets.test.ts +0 -146
- package/src/lib/__tests__/view-open-intent.test.ts +0 -280
- package/src/lib/__tests__/view-port-allocation.test.ts +0 -82
- package/src/lib/__tests__/view-server.test.ts +0 -68
- package/src/lib/__tests__/view-session.test.ts +0 -99
- package/src/lib/__tests__/view-snapshot.test.ts +0 -77
- package/src/lib/admin-domain.ts +0 -43
- package/src/lib/admin-instance.ts +0 -50
- package/src/lib/admin-target.ts +0 -290
- package/src/lib/binary.ts +0 -110
- package/src/lib/browser.ts +0 -150
- package/src/lib/ca-fetch.ts +0 -133
- package/src/lib/command-dx.ts +0 -188
- package/src/lib/concurrency.ts +0 -31
- package/src/lib/config.ts +0 -46
- package/src/lib/domain-publication.ts +0 -102
- package/src/lib/failure-debug.ts +0 -26
- package/src/lib/format.ts +0 -4
- package/src/lib/idp-session.ts +0 -134
- package/src/lib/idp.ts +0 -906
- package/src/lib/instance-candidates.ts +0 -49
- package/src/lib/instance-target.ts +0 -197
- package/src/lib/instance.ts +0 -463
- package/src/lib/invocation.ts +0 -11
- package/src/lib/local-status.ts +0 -152
- package/src/lib/log.ts +0 -143
- package/src/lib/login-flow.ts +0 -201
- package/src/lib/meta.ts +0 -90
- package/src/lib/output.ts +0 -238
- package/src/lib/panel.ts +0 -61
- package/src/lib/port.ts +0 -41
- package/src/lib/proc.ts +0 -82
- package/src/lib/prompt.ts +0 -136
- package/src/lib/provision-instance.ts +0 -162
- package/src/lib/sdk-deps.ts +0 -104
- package/src/lib/self.ts +0 -22
- package/src/lib/skills.ts +0 -171
- package/src/lib/table.ts +0 -62
- package/src/lib/update.ts +0 -409
- package/src/lib/use-target.ts +0 -24
- package/src/lib/validation.ts +0 -59
- package/src/lib/view/assets.ts +0 -78
- package/src/lib/view/open-intent.ts +0 -67
- package/src/lib/view/port-allocation.ts +0 -19
- package/src/lib/view/resolve.ts +0 -111
- package/src/lib/view/server.ts +0 -244
- package/src/lib/view/session.ts +0 -152
- package/src/lib/view/snapshot.ts +0 -101
- package/src/paths/.spec/api.d.ts +0 -13
- package/src/paths/.spec/architecture.md +0 -5
- package/src/paths/.spec/layout.ts +0 -3
- package/src/paths/index.ts +0 -13
- package/src/program/.spec/api.d.ts +0 -42
- package/src/program/.spec/architecture.md +0 -18
- package/src/program/.spec/laws/program.ts +0 -29
- package/src/program/.spec/layout.ts +0 -14
- package/src/program/__tests__/program.test.ts +0 -362
- package/src/program/build.ts +0 -183
- package/src/program/command.ts +0 -42
- package/src/program/index.ts +0 -2
- package/src/program/options.ts +0 -41
- package/src/program/registry.ts +0 -63
- package/src/program/tsconfig.json +0 -6
- package/src/setup/__tests__/instance-step.test.ts +0 -239
- package/src/setup/__tests__/util.test.ts +0 -29
- package/src/setup/engine.ts +0 -83
- package/src/setup/render.ts +0 -107
- package/src/setup/steps/admin.ts +0 -93
- package/src/setup/steps/agent-browser.ts +0 -81
- package/src/setup/steps/auth.ts +0 -54
- package/src/setup/steps/domain.ts +0 -68
- package/src/setup/steps/index.ts +0 -18
- package/src/setup/steps/instance.ts +0 -199
- package/src/setup/steps/skills-bridge.ts +0 -70
- package/src/setup/steps/skills.ts +0 -59
- package/src/setup/types.ts +0 -61
- package/src/setup/util.ts +0 -34
- package/src/state/.spec/api.d.ts +0 -133
- package/src/state/.spec/architecture.md +0 -31
- package/src/state/.spec/capabilities/state.ts +0 -7
- package/src/state/.spec/flows/identity-update.ts +0 -22
- package/src/state/.spec/laws/state.ts +0 -73
- package/src/state/.spec/layout.ts +0 -14
- package/src/state/__tests__/exchange-credentials.test.ts +0 -188
- package/src/state/__tests__/files.test.ts +0 -113
- package/src/state/__tests__/fixtures/identity-transition.ts +0 -37
- package/src/state/__tests__/identities.test.ts +0 -142
- package/src/state/__tests__/paths.test.ts +0 -27
- package/src/state/exchange-credentials.ts +0 -219
- package/src/state/files.ts +0 -129
- package/src/state/identities.ts +0 -229
- package/src/state/index.ts +0 -29
- package/src/state/paths.ts +0 -61
- package/src/state/tsconfig.json +0 -6
- package/src/telemetry/__tests__/gate.test.ts +0 -63
- package/src/telemetry/__tests__/recorder.test.ts +0 -110
- package/src/telemetry/__tests__/redact.test.ts +0 -79
- package/src/telemetry/__tests__/session.test.ts +0 -166
- package/src/telemetry/__tests__/trigger.test.ts +0 -49
- package/src/telemetry/adapters/__tests__/claude-code.test.ts +0 -89
- package/src/telemetry/adapters/__tests__/codex.test.ts +0 -138
- package/src/telemetry/adapters/__tests__/index.test.ts +0 -88
- package/src/telemetry/adapters/claude-code.ts +0 -90
- package/src/telemetry/adapters/codex.ts +0 -160
- package/src/telemetry/adapters/index.ts +0 -45
- package/src/telemetry/adapters/types.ts +0 -21
- package/src/telemetry/analyze.ts +0 -227
- package/src/telemetry/gate.ts +0 -79
- package/src/telemetry/recorder.ts +0 -57
- package/src/telemetry/redact.ts +0 -53
- package/src/telemetry/session.ts +0 -88
- package/src/telemetry/settings.ts +0 -26
- package/src/telemetry/store.ts +0 -91
- package/src/telemetry/trigger.ts +0 -119
- package/src/telemetry/types.ts +0 -64
- package/src/test-utils.ts +0 -18
- package/studio/client/dist/assets/elk-api-Di4OXGNH.js +0 -1
- package/studio/client/dist/assets/elk-worker.min-C9JGDOE-.js +0 -6312
- package/studio/client/dist/assets/index-BLm6J11H.js +0 -81
- package/studio/client/dist/assets/index-BiGR8Oo9.css +0 -1
- package/studio/client/dist/assets/index-ChOr3yP0.css +0 -1
- package/studio/client/dist/assets/index-DTjvkOUX.js +0 -8
- package/studio/client/dist/index.html +0 -13
- package/studio/package.json +0 -65
- package/studio/server/agent/ask.test.ts +0 -74
- package/studio/server/agent/ask.ts +0 -71
- package/studio/server/agent/bridge/client.test.ts +0 -49
- package/studio/server/agent/bridge/client.ts +0 -37
- package/studio/server/agent/bridge/grant.test.ts +0 -62
- package/studio/server/agent/bridge/grant.ts +0 -84
- package/studio/server/agent/bridge/routes.test.ts +0 -151
- package/studio/server/agent/bridge/routes.ts +0 -148
- package/studio/server/agent/bridge/stdio.ts +0 -195
- package/studio/server/agent/conversation.test.ts +0 -89
- package/studio/server/agent/conversation.ts +0 -158
- package/studio/server/agent/harness/adapter.ts +0 -171
- package/studio/server/agent/harness/claude/adapter.test.ts +0 -348
- package/studio/server/agent/harness/claude/adapter.ts +0 -71
- package/studio/server/agent/harness/claude/ask.ts +0 -114
- package/studio/server/agent/harness/claude/capabilities.ts +0 -27
- package/studio/server/agent/harness/claude/command.ts +0 -63
- package/studio/server/agent/harness/claude/events.ts +0 -215
- package/studio/server/agent/harness/claude/loadout.ts +0 -132
- package/studio/server/agent/harness/claude/mcp.test.ts +0 -36
- package/studio/server/agent/harness/claude/mcp.ts +0 -41
- package/studio/server/agent/harness/claude/skills.ts +0 -43
- package/studio/server/agent/harness/codex/adapter.test.ts +0 -269
- package/studio/server/agent/harness/codex/adapter.ts +0 -116
- package/studio/server/agent/harness/codex/ask.test.ts +0 -176
- package/studio/server/agent/harness/codex/ask.ts +0 -181
- package/studio/server/agent/harness/codex/command.test.ts +0 -69
- package/studio/server/agent/harness/codex/command.ts +0 -43
- package/studio/server/agent/harness/codex/events.test.ts +0 -94
- package/studio/server/agent/harness/codex/events.ts +0 -132
- package/studio/server/agent/harness/codex/exec.ts +0 -113
- package/studio/server/agent/harness/codex/loadout.ts +0 -60
- package/studio/server/agent/harness/codex/mcp.test.ts +0 -32
- package/studio/server/agent/harness/codex/mcp.ts +0 -27
- package/studio/server/agent/harness/codex/models.test.ts +0 -167
- package/studio/server/agent/harness/codex/models.ts +0 -211
- package/studio/server/agent/harness/codex/skills.ts +0 -33
- package/studio/server/agent/harness/gateway/config.test.ts +0 -98
- package/studio/server/agent/harness/gateway/config.ts +0 -214
- package/studio/server/agent/harness/gateway/token.test.ts +0 -133
- package/studio/server/agent/harness/gateway/token.ts +0 -166
- package/studio/server/agent/harness/mock/adapter.ts +0 -190
- package/studio/server/agent/harness/mock/domain-edit.ts +0 -41
- package/studio/server/agent/harness/process.test.ts +0 -46
- package/studio/server/agent/harness/process.ts +0 -104
- package/studio/server/agent/harness/registry.ts +0 -37
- package/studio/server/agent/harness/selection.test.ts +0 -75
- package/studio/server/agent/harness/selection.ts +0 -85
- package/studio/server/agent/harness/skills.test.ts +0 -95
- package/studio/server/agent/harness/skills.ts +0 -100
- package/studio/server/agent/layout.test.ts +0 -95
- package/studio/server/agent/notify.ts +0 -12
- package/studio/server/agent/prompts/anchors.test.ts +0 -70
- package/studio/server/agent/prompts/anchors.ts +0 -153
- package/studio/server/agent/prompts/ask.ts +0 -34
- package/studio/server/agent/prompts/system.test.ts +0 -13
- package/studio/server/agent/prompts/system.ts +0 -99
- package/studio/server/agent/prompts/turn.ts +0 -66
- package/studio/server/agent/routes.test.ts +0 -176
- package/studio/server/agent/routes.ts +0 -214
- package/studio/server/agent/run/completion.ts +0 -193
- package/studio/server/agent/run/coordinator.test.ts +0 -337
- package/studio/server/agent/run/coordinator.ts +0 -104
- package/studio/server/agent/run/live-state.ts +0 -73
- package/studio/server/agent/run/preparation.ts +0 -163
- package/studio/server/agent/run/transcript.test.ts +0 -81
- package/studio/server/agent/run/transcript.ts +0 -196
- package/studio/server/agent/run/usage.test.ts +0 -70
- package/studio/server/agent/run/usage.ts +0 -62
- package/studio/server/agent/stream.ts +0 -37
- package/studio/server/agent/telemetry.ts +0 -13
- package/studio/server/api/canvas.ts +0 -43
- package/studio/server/api/comments.ts +0 -85
- package/studio/server/api/context.ts +0 -61
- package/studio/server/api/deployment.ts +0 -39
- package/studio/server/api/documents.ts +0 -55
- package/studio/server/api/domain.ts +0 -59
- package/studio/server/api/http.ts +0 -45
- package/studio/server/api/project.ts +0 -57
- package/studio/server/api/schema.ts +0 -12
- package/studio/server/api/views.ts +0 -57
- package/studio/server/api/workspace.ts +0 -60
- package/studio/server/api-agent-loadout.test.ts +0 -69
- package/studio/server/api.test.ts +0 -147
- package/studio/server/api.ts +0 -34
- package/studio/server/cache.test.ts +0 -122
- package/studio/server/cache.ts +0 -303
- package/studio/server/cli-consumers.test.ts +0 -494
- package/studio/server/cli.test.ts +0 -88
- package/studio/server/cli.ts +0 -240
- package/studio/server/client-package.test.ts +0 -147
- package/studio/server/client-package.ts +0 -266
- package/studio/server/detect.ts +0 -81
- package/studio/server/domain.test.ts +0 -77
- package/studio/server/domain.ts +0 -124
- package/studio/server/environment/dotenv-preview.test.ts +0 -39
- package/studio/server/environment/dotenv-preview.ts +0 -27
- package/studio/server/environment/files.test.ts +0 -53
- package/studio/server/environment/files.ts +0 -120
- package/studio/server/handoff/copy.ts +0 -171
- package/studio/server/handoff/service.test.ts +0 -22
- package/studio/server/handoff/service.ts +0 -62
- package/studio/server/index.ts +0 -148
- package/studio/server/instances/active.ts +0 -72
- package/studio/server/instances/deploy-record.test.ts +0 -31
- package/studio/server/instances/deploy-record.ts +0 -37
- package/studio/server/instances/deploy.ts +0 -56
- package/studio/server/instances/probe.test.ts +0 -67
- package/studio/server/instances/probe.ts +0 -67
- package/studio/server/instances/status.test.ts +0 -12
- package/studio/server/instances/status.ts +0 -49
- package/studio/server/introspect/anatomy/client-tree.ts +0 -57
- package/studio/server/introspect/anatomy/env-fields.ts +0 -66
- package/studio/server/introspect/anatomy/schema-definition.ts +0 -53
- package/studio/server/introspect/anatomy/source.ts +0 -181
- package/studio/server/introspect/anatomy/views/routes.ts +0 -114
- package/studio/server/introspect/anatomy/views.ts +0 -53
- package/studio/server/introspect/anatomy-extras.test.ts +0 -265
- package/studio/server/introspect/anatomy-extras.ts +0 -10
- package/studio/server/introspect/anatomy.test.ts +0 -41
- package/studio/server/introspect/anatomy.ts +0 -147
- package/studio/server/introspect/bundle.ts +0 -69
- package/studio/server/introspect/canonical-schema.test.ts +0 -179
- package/studio/server/introspect/canonical-schema.ts +0 -583
- package/studio/server/introspect/config-preview.test.ts +0 -32
- package/studio/server/introspect/config-preview.ts +0 -119
- package/studio/server/introspect/core-extractor.ts +0 -30
- package/studio/server/introspect/core.ts +0 -45
- package/studio/server/introspect/diff.test.ts +0 -124
- package/studio/server/introspect/diff.ts +0 -316
- package/studio/server/introspect/extractor.ts +0 -41
- package/studio/server/introspect/hash.ts +0 -24
- package/studio/server/introspect/overlay-tsmorph.test.ts +0 -146
- package/studio/server/introspect/overlay-tsmorph.ts +0 -9
- package/studio/server/introspect/overlay.test.ts +0 -44
- package/studio/server/introspect/overlay.ts +0 -40
- package/studio/server/introspect/revision.test.ts +0 -54
- package/studio/server/introspect/revision.ts +0 -49
- package/studio/server/introspect/runtime.test.ts +0 -157
- package/studio/server/introspect/runtime.ts +0 -140
- package/studio/server/introspect/schema-ir-json.test.ts +0 -70
- package/studio/server/introspect/schema-ir-json.ts +0 -151
- package/studio/server/introspect/schema-refs.test.ts +0 -55
- package/studio/server/introspect/schema-refs.ts +0 -32
- package/studio/server/introspect/source-overlay/annotations.ts +0 -14
- package/studio/server/introspect/source-overlay/handlers.ts +0 -161
- package/studio/server/introspect/source-overlay/kernel-calls.ts +0 -46
- package/studio/server/introspect/source-overlay/project.ts +0 -248
- package/studio/server/introspect/source-overlay/spans.ts +0 -330
- package/studio/server/json.ts +0 -46
- package/studio/server/lifecycle.ts +0 -42
- package/studio/server/sse.test.ts +0 -26
- package/studio/server/sse.ts +0 -60
- package/studio/server/state/baseline.test.ts +0 -267
- package/studio/server/state/baseline.ts +0 -354
- package/studio/server/state/comments.test.ts +0 -94
- package/studio/server/state/comments.ts +0 -484
- package/studio/server/state/context.ts +0 -199
- package/studio/server/state/documents.ts +0 -111
- package/studio/server/state/integrations.ts +0 -81
- package/studio/server/state/layout.test.ts +0 -34
- package/studio/server/state/layout.ts +0 -82
- package/studio/server/state/settings.test.ts +0 -78
- package/studio/server/state/settings.ts +0 -73
- package/studio/server/state/store.test.ts +0 -122
- package/studio/server/state/store.ts +0 -146
- package/studio/server/state/visibility.ts +0 -48
- package/studio/server/views/model.test.ts +0 -57
- package/studio/server/views/model.ts +0 -66
- package/studio/server/views/runtime.ts +0 -40
- package/studio/server/views/selection-repository.test.ts +0 -31
- package/studio/server/views/selection-repository.ts +0 -60
- package/studio/server/views/session.test.ts +0 -73
- package/studio/server/views/session.ts +0 -166
- package/studio/server/views/target.test.ts +0 -78
- package/studio/server/views/target.ts +0 -222
- package/studio/server/watch.test.ts +0 -36
- package/studio/server/watch.ts +0 -93
- package/studio/server/workspace/catalog.test.ts +0 -17
- package/studio/server/workspace/catalog.ts +0 -43
- package/studio/server/workspace/create.test.ts +0 -37
- package/studio/server/workspace/create.ts +0 -162
- package/studio/server/workspace/git.ts +0 -75
- package/studio/server/workspace/updates.ts +0 -83
- package/studio/server/workspace-state.ts +0 -26
- package/studio/server/workspace-watch.ts +0 -106
- package/studio/shared/agent-effort.test.ts +0 -12
- package/studio/shared/agent-effort.ts +0 -15
- package/studio/shared/agent-models.test.ts +0 -9
- package/studio/shared/agent-models.ts +0 -14
- package/studio/shared/contracts/README.md +0 -16
- package/studio/shared/contracts/agent.ts +0 -270
- package/studio/shared/contracts/runtime.ts +0 -50
- package/studio/shared/contracts/schema.ts +0 -393
- package/studio/shared/contracts/surface.test.ts +0 -317
- package/studio/shared/contracts/workspace.ts +0 -265
- package/studio/shared/layout.test.ts +0 -116
- package/studio/shared/schema/identity.test.ts +0 -34
- package/studio/shared/schema/identity.ts +0 -68
- package/studio/shared/settings-values.test.ts +0 -18
- package/studio/shared/settings-values.ts +0 -20
- package/studio/shared/types.ts +0 -14
- package/studio/tsconfig.json +0 -23
- package/tsconfig.json +0 -14
- package/viewer/dist/index.html +0 -93
- package/viewer/dist/main.js +0 -76
- package/viewer/tsconfig.json +0 -13
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* harness/adapter.ts — the executable boundary implemented by each local agent
|
|
3
|
-
* harness.
|
|
4
|
-
*
|
|
5
|
-
* A *harness* is whatever local AI agent does the edits (Claude Code, Codex, …).
|
|
6
|
-
* The studio never talks to a model API directly; it shells out to the harness
|
|
7
|
-
* the user already has running locally (no cloud API key of our own). Each
|
|
8
|
-
* harness maps its native streaming output onto `AgentStreamEvent`s and returns
|
|
9
|
-
* a final text blob (which carries the machine-state reply block).
|
|
10
|
-
*/
|
|
11
|
-
import type {
|
|
12
|
-
AgentAccess,
|
|
13
|
-
AgentEffort,
|
|
14
|
-
AgentEventKind,
|
|
15
|
-
HarnessCapabilities,
|
|
16
|
-
HarnessLoadout,
|
|
17
|
-
} from '../../../shared/types'
|
|
18
|
-
|
|
19
|
-
/** A single normalized activity event emitted while the harness runs. */
|
|
20
|
-
export interface AgentStreamEvent {
|
|
21
|
-
kind: AgentEventKind
|
|
22
|
-
text: string
|
|
23
|
-
tool?: string
|
|
24
|
-
target?: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** Harness-neutral description of one stdio MCP server. Each harness is
|
|
28
|
-
* responsible for expressing this in its native CLI/config shape. */
|
|
29
|
-
export interface HarnessMcpServer {
|
|
30
|
-
name: string
|
|
31
|
-
command: string
|
|
32
|
-
args?: string[]
|
|
33
|
-
env?: Record<string, string>
|
|
34
|
-
required?: boolean
|
|
35
|
-
/** Studio's run-scoped write-back tools are user-authorized by the submit. */
|
|
36
|
-
approvalMode?: 'auto' | 'prompt' | 'writes' | 'approve'
|
|
37
|
-
enabledTools?: string[]
|
|
38
|
-
/** In-process harnesses may invoke the same grant without spawning stdio. */
|
|
39
|
-
invoke?: (tool: string, args: Record<string, unknown>) => Promise<unknown>
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface AgentTurnInput {
|
|
43
|
-
/** the domain repo root — the agent's working directory */
|
|
44
|
-
root: string
|
|
45
|
-
/** the turn message (scaffolded handoff / delta) */
|
|
46
|
-
prompt: string
|
|
47
|
-
/** appended to the harness's default system prompt — the reply protocol */
|
|
48
|
-
appendSystemPrompt?: string
|
|
49
|
-
/** prior harness session id → resume the same conversation */
|
|
50
|
-
sessionId?: string
|
|
51
|
-
/** explicit model override; absent preserves the harness's native config/default */
|
|
52
|
-
model?: string
|
|
53
|
-
/** harness reasoning effort for this turn */
|
|
54
|
-
effort?: AgentEffort
|
|
55
|
-
/** authority granted to the local harness */
|
|
56
|
-
access?: AgentAccess
|
|
57
|
-
/** generated MCP servers exposing Studio write-back */
|
|
58
|
-
mcpServers?: HarnessMcpServer[]
|
|
59
|
-
/** extra env merged into the harness CHILD process only. Never touches the
|
|
60
|
-
* studio's own env or the user's shell/global harness process. */
|
|
61
|
-
env?: Record<string, string>
|
|
62
|
-
/** abort the turn (user pressed Cancel) */
|
|
63
|
-
signal: AbortSignal
|
|
64
|
-
/** called for every normalized activity event */
|
|
65
|
-
onEvent: (e: AgentStreamEvent) => void
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface AgentTurnResult {
|
|
69
|
-
/** session id to persist for the next turn's resume */
|
|
70
|
-
sessionId?: string
|
|
71
|
-
/** the agent's final message text (parsed for the machine-state reply block) */
|
|
72
|
-
finalText: string
|
|
73
|
-
costUsd?: number
|
|
74
|
-
numTurns?: number
|
|
75
|
-
/** total token usage reported by the harness */
|
|
76
|
-
tokens?: number
|
|
77
|
-
isError: boolean
|
|
78
|
-
errorMessage?: string
|
|
79
|
-
/** the resume sessionId we passed was rejected by the harness (the conversation
|
|
80
|
-
* no longer exists / expired). The runner uses this to transparently restart the
|
|
81
|
-
* turn as a fresh conversation instead of failing — and to know it's safe to drop
|
|
82
|
-
* the stored id (vs. keeping it across an unrelated transient failure). */
|
|
83
|
-
resumeRejected?: boolean
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** A quick, ephemeral "side question" — a FORK of the conversation that inherits
|
|
87
|
-
* the parent's context but writes nothing back to it (see agent/ask.ts). Streamed. */
|
|
88
|
-
export interface AskInput {
|
|
89
|
-
root: string
|
|
90
|
-
/** the composed question (prefix + injected target context + the user's text) */
|
|
91
|
-
prompt: string
|
|
92
|
-
/** the ask protocol, appended to the harness default system prompt */
|
|
93
|
-
appendSystemPrompt?: string
|
|
94
|
-
/** the domain's live conversation session id to FORK from (undefined ⇒ fresh, no fork) */
|
|
95
|
-
sessionId?: string
|
|
96
|
-
/** explicit model override; absent preserves the harness's native config/default */
|
|
97
|
-
model?: string
|
|
98
|
-
/** harness reasoning effort for this side question */
|
|
99
|
-
effort?: AgentEffort
|
|
100
|
-
/** authority granted to the local harness */
|
|
101
|
-
access?: AgentAccess
|
|
102
|
-
/** extra env merged into the harness child only — see AgentTurnInput.env */
|
|
103
|
-
env?: Record<string, string>
|
|
104
|
-
signal: AbortSignal
|
|
105
|
-
/** called with each chunk of the answer as it streams in */
|
|
106
|
-
onDelta: (text: string) => void
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface AskResult {
|
|
110
|
-
text: string
|
|
111
|
-
isError: boolean
|
|
112
|
-
errorMessage?: string
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** A richer install/health probe result for the UI (binary found? which version?). */
|
|
116
|
-
export interface HarnessHealth {
|
|
117
|
-
ok: boolean
|
|
118
|
-
version?: string
|
|
119
|
-
/** the binary / command probed (so the user can fix PATH) */
|
|
120
|
-
bin?: string
|
|
121
|
-
/** human-readable reason when not ok */
|
|
122
|
-
detail?: string
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export interface HarnessLoadoutOptions {
|
|
126
|
-
/** Child-only environment overrides used while probing the harness. */
|
|
127
|
-
env?: Record<string, string>
|
|
128
|
-
/** Studio's per-domain override for the selected harness. */
|
|
129
|
-
model?: string
|
|
130
|
-
/** Bypass the adapter's short-lived probe cache for an explicit user re-probe. */
|
|
131
|
-
refresh?: boolean
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export interface AgentHarness {
|
|
135
|
-
/** stable id, e.g. 'claude' | 'mock' | 'codex' */
|
|
136
|
-
id: string
|
|
137
|
-
/** human label for the UI */
|
|
138
|
-
label: string
|
|
139
|
-
capabilities: HarnessCapabilities
|
|
140
|
-
/** is the underlying CLI/binary actually invokable here? */
|
|
141
|
-
isAvailable(signal?: AbortSignal): Promise<boolean>
|
|
142
|
-
/** optional: a richer install probe for the UI (version + reason). Harnesses that
|
|
143
|
-
* omit it fall back to isAvailable(). */
|
|
144
|
-
health?(signal?: AbortSignal): Promise<HarnessHealth>
|
|
145
|
-
run(input: AgentTurnInput): Promise<AgentTurnResult>
|
|
146
|
-
/** optional: answer a quick forked side question (Ask). Harnesses without a
|
|
147
|
-
* fork concept simply omit this; the studio falls back gracefully. */
|
|
148
|
-
ask?(input: AskInput): Promise<AskResult>
|
|
149
|
-
/** optional: report what the harness ACTUALLY loaded for `root` (skills, MCP,
|
|
150
|
-
* tools, agents) — a read-only window into the agent for the Settings page.
|
|
151
|
-
* Harnesses without an introspectable loadout omit it. `env` (e.g. a custom
|
|
152
|
-
* model gateway) is merged into the probe child so the reported model reflects it. */
|
|
153
|
-
loadout?(root: string, options?: HarnessLoadoutOptions): Promise<HarnessLoadout>
|
|
154
|
-
/** optional: the raw SKILL.md for a skill command, so the UI can show it. */
|
|
155
|
-
skillContent?(
|
|
156
|
-
root: string,
|
|
157
|
-
command: string,
|
|
158
|
-
): Promise<{ command: string; content: string; path: string } | null>
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** Normalize optional rich health probes into one route-facing result. */
|
|
162
|
-
export async function inspectHarnessHealth(
|
|
163
|
-
harness: AgentHarness,
|
|
164
|
-
signal?: AbortSignal,
|
|
165
|
-
): Promise<HarnessHealth> {
|
|
166
|
-
if (harness.health) return harness.health(signal)
|
|
167
|
-
return {
|
|
168
|
-
ok: await harness.isAvailable(signal),
|
|
169
|
-
bin: harness.id,
|
|
170
|
-
}
|
|
171
|
-
}
|
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import { afterEach, expect, test } from 'bun:test'
|
|
2
|
-
import { chmodSync, existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
-
import { tmpdir } from 'node:os'
|
|
4
|
-
import { join } from 'node:path'
|
|
5
|
-
|
|
6
|
-
import { ClaudeCodeHarness } from './adapter'
|
|
7
|
-
|
|
8
|
-
const roots: string[] = []
|
|
9
|
-
|
|
10
|
-
afterEach(() => {
|
|
11
|
-
while (roots.length) rmSync(roots.pop()!, { recursive: true, force: true })
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
function fakeClaude(root: string): string {
|
|
15
|
-
const file = join(root, 'fake-claude')
|
|
16
|
-
writeFileSync(
|
|
17
|
-
file,
|
|
18
|
-
`#!/usr/bin/env bun
|
|
19
|
-
const fs = require('node:fs')
|
|
20
|
-
const { spawn } = require('node:child_process')
|
|
21
|
-
const args = process.argv.slice(2)
|
|
22
|
-
if (args[0] === '--version') {
|
|
23
|
-
console.log('2.1.test')
|
|
24
|
-
process.exit(0)
|
|
25
|
-
}
|
|
26
|
-
if (process.env.FAKE_CLAUDE_LOG) {
|
|
27
|
-
fs.appendFileSync(process.env.FAKE_CLAUDE_LOG, JSON.stringify({ args }) + '\\n')
|
|
28
|
-
}
|
|
29
|
-
const modelAt = args.indexOf('--model')
|
|
30
|
-
const model = modelAt >= 0 ? args[modelAt + 1] + '-resolved' : 'native-default'
|
|
31
|
-
const resumedAt = args.indexOf('--resume')
|
|
32
|
-
const session = resumedAt >= 0 ? args[resumedAt + 1] : 'fresh-session'
|
|
33
|
-
const send = (event) => process.stdout.write(JSON.stringify(event) + '\\n')
|
|
34
|
-
send({
|
|
35
|
-
type: 'system',
|
|
36
|
-
subtype: 'init',
|
|
37
|
-
session_id: session,
|
|
38
|
-
model,
|
|
39
|
-
permissionMode: 'bypassPermissions',
|
|
40
|
-
apiKeySource: 'none',
|
|
41
|
-
cwd: process.cwd(),
|
|
42
|
-
tools: ['Read', 'Edit'],
|
|
43
|
-
mcp_servers: [],
|
|
44
|
-
slash_commands: [],
|
|
45
|
-
agents: [],
|
|
46
|
-
})
|
|
47
|
-
let prompt = ''
|
|
48
|
-
process.stdin.setEncoding('utf8')
|
|
49
|
-
process.stdin.on('data', (chunk) => { prompt += chunk })
|
|
50
|
-
process.stdin.on('end', () => {
|
|
51
|
-
if (prompt === '.') return setInterval(() => {}, 1000)
|
|
52
|
-
if (process.env.FAKE_CLAUDE_MODE === 'no-result') process.exit(0)
|
|
53
|
-
send({ type: 'assistant', message: { content: [{ type: 'text', text: 'answer' }] } })
|
|
54
|
-
if (process.env.FAKE_CLAUDE_MODE === 'text-then-crash') {
|
|
55
|
-
console.error('crashed after text')
|
|
56
|
-
process.exit(7)
|
|
57
|
-
}
|
|
58
|
-
if (process.env.FAKE_CLAUDE_MODE === 'result-error') {
|
|
59
|
-
send({ type: 'result', subtype: 'error_during_execution', is_error: true, result: 'failed' })
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
if (process.env.FAKE_CLAUDE_MODE === 'hang-ignore-term') {
|
|
63
|
-
process.on('SIGTERM', () => {})
|
|
64
|
-
const child = spawn(process.execPath, ['-e', "process.on('SIGTERM',()=>{});setInterval(()=>{},1000)"], {
|
|
65
|
-
stdio: 'ignore',
|
|
66
|
-
})
|
|
67
|
-
fs.writeFileSync(
|
|
68
|
-
process.env.FAKE_CLAUDE_PID_LOG,
|
|
69
|
-
JSON.stringify({ parent: process.pid, child: child.pid }),
|
|
70
|
-
)
|
|
71
|
-
return setInterval(() => {}, 1000)
|
|
72
|
-
}
|
|
73
|
-
send({
|
|
74
|
-
type: 'result',
|
|
75
|
-
subtype: 'success',
|
|
76
|
-
result: 'done',
|
|
77
|
-
session_id: session,
|
|
78
|
-
num_turns: 1,
|
|
79
|
-
usage: { input_tokens: 2, output_tokens: 3 },
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
`,
|
|
83
|
-
)
|
|
84
|
-
chmodSync(file, 0o755)
|
|
85
|
-
return file
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function invocations(log: string): { args: string[] }[] {
|
|
89
|
-
return readFileSync(log, 'utf8')
|
|
90
|
-
.trim()
|
|
91
|
-
.split('\n')
|
|
92
|
-
.map((line) => JSON.parse(line))
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async function waitFor(predicate: () => boolean, timeoutMs = 3_000): Promise<void> {
|
|
96
|
-
const deadline = Date.now() + timeoutMs
|
|
97
|
-
while (!predicate()) {
|
|
98
|
-
if (Date.now() >= deadline) throw new Error('condition did not become true before timeout')
|
|
99
|
-
await Bun.sleep(20)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function processExists(pid: number): boolean {
|
|
104
|
-
try {
|
|
105
|
-
process.kill(pid, 0)
|
|
106
|
-
return true
|
|
107
|
-
} catch {
|
|
108
|
-
return false
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
test('Claude loadout probing reports and passes the Studio model override', async () => {
|
|
113
|
-
const root = mkdtempSync(join(tmpdir(), 'studio-claude-model-probe-'))
|
|
114
|
-
roots.push(root)
|
|
115
|
-
const log = join(root, 'claude.jsonl')
|
|
116
|
-
const harness = new ClaudeCodeHarness(fakeClaude(root))
|
|
117
|
-
|
|
118
|
-
const loadout = await harness.loadout(root, {
|
|
119
|
-
model: 'sonnet',
|
|
120
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
expect(loadout).toMatchObject({
|
|
124
|
-
ok: true,
|
|
125
|
-
model: 'sonnet-resolved',
|
|
126
|
-
modelSource: 'studio',
|
|
127
|
-
})
|
|
128
|
-
const args = invocations(log)[0].args
|
|
129
|
-
const modelAt = args.indexOf('--model')
|
|
130
|
-
expect(args.slice(modelAt, modelAt + 2)).toEqual(['--model', 'sonnet'])
|
|
131
|
-
|
|
132
|
-
await harness.loadout(root, {
|
|
133
|
-
model: 'sonnet',
|
|
134
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
135
|
-
})
|
|
136
|
-
expect(invocations(log)).toHaveLength(1)
|
|
137
|
-
await harness.loadout(root, {
|
|
138
|
-
model: 'sonnet',
|
|
139
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
140
|
-
refresh: true,
|
|
141
|
-
})
|
|
142
|
-
expect(invocations(log)).toHaveLength(2)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
test('Claude turns and Ask calls carry selected models and native effort modes', async () => {
|
|
146
|
-
const root = mkdtempSync(join(tmpdir(), 'studio-claude-model-turns-'))
|
|
147
|
-
roots.push(root)
|
|
148
|
-
const log = join(root, 'claude.jsonl')
|
|
149
|
-
const harness = new ClaudeCodeHarness(fakeClaude(root))
|
|
150
|
-
const signal = new AbortController().signal
|
|
151
|
-
|
|
152
|
-
const normal = await harness.run({
|
|
153
|
-
root,
|
|
154
|
-
prompt: 'normal turn',
|
|
155
|
-
model: 'sonnet',
|
|
156
|
-
effort: 'ultracode',
|
|
157
|
-
access: 'full',
|
|
158
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
159
|
-
signal,
|
|
160
|
-
onEvent: () => {},
|
|
161
|
-
})
|
|
162
|
-
expect(normal).toMatchObject({
|
|
163
|
-
sessionId: 'fresh-session',
|
|
164
|
-
finalText: 'done',
|
|
165
|
-
isError: false,
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
const resumed = await harness.run({
|
|
169
|
-
root,
|
|
170
|
-
prompt: 'resumed turn',
|
|
171
|
-
sessionId: 'parent-session',
|
|
172
|
-
model: 'opus',
|
|
173
|
-
effort: 'max',
|
|
174
|
-
access: 'full',
|
|
175
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
176
|
-
signal,
|
|
177
|
-
onEvent: () => {},
|
|
178
|
-
})
|
|
179
|
-
expect(resumed).toMatchObject({
|
|
180
|
-
sessionId: 'parent-session',
|
|
181
|
-
finalText: 'done',
|
|
182
|
-
isError: false,
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
const fresh = await harness.ask({
|
|
186
|
-
root,
|
|
187
|
-
prompt: 'fresh ask',
|
|
188
|
-
model: 'fable',
|
|
189
|
-
effort: 'max',
|
|
190
|
-
access: 'workspace',
|
|
191
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
192
|
-
signal,
|
|
193
|
-
onDelta: () => {},
|
|
194
|
-
})
|
|
195
|
-
const forked = await harness.ask({
|
|
196
|
-
root,
|
|
197
|
-
prompt: 'forked ask',
|
|
198
|
-
sessionId: 'parent-session',
|
|
199
|
-
model: 'sonnet',
|
|
200
|
-
effort: 'max',
|
|
201
|
-
access: 'workspace',
|
|
202
|
-
env: { FAKE_CLAUDE_LOG: log },
|
|
203
|
-
signal,
|
|
204
|
-
onDelta: () => {},
|
|
205
|
-
})
|
|
206
|
-
expect(fresh).toEqual({ text: 'done', isError: false })
|
|
207
|
-
expect(forked).toEqual({ text: 'done', isError: false })
|
|
208
|
-
|
|
209
|
-
const [normalArgs, resumedArgs, freshArgs, forkArgs] = invocations(log).map((entry) => entry.args)
|
|
210
|
-
expect(normalArgs).not.toContain('--resume')
|
|
211
|
-
expect(
|
|
212
|
-
normalArgs.slice(normalArgs.indexOf('--model'), normalArgs.indexOf('--model') + 2),
|
|
213
|
-
).toEqual(['--model', 'sonnet'])
|
|
214
|
-
expect(
|
|
215
|
-
resumedArgs.slice(resumedArgs.indexOf('--resume'), resumedArgs.indexOf('--resume') + 2),
|
|
216
|
-
).toEqual(['--resume', 'parent-session'])
|
|
217
|
-
expect(
|
|
218
|
-
resumedArgs.slice(resumedArgs.indexOf('--model'), resumedArgs.indexOf('--model') + 2),
|
|
219
|
-
).toEqual(['--model', 'opus'])
|
|
220
|
-
expect(freshArgs.slice(freshArgs.indexOf('--model'), freshArgs.indexOf('--model') + 2)).toEqual([
|
|
221
|
-
'--model',
|
|
222
|
-
'fable',
|
|
223
|
-
])
|
|
224
|
-
expect(freshArgs).not.toContain('--resume')
|
|
225
|
-
expect(forkArgs.slice(forkArgs.indexOf('--model'), forkArgs.indexOf('--model') + 2)).toEqual([
|
|
226
|
-
'--model',
|
|
227
|
-
'sonnet',
|
|
228
|
-
])
|
|
229
|
-
expect(forkArgs.slice(forkArgs.indexOf('--resume'), forkArgs.indexOf('--resume') + 3)).toEqual([
|
|
230
|
-
'--resume',
|
|
231
|
-
'parent-session',
|
|
232
|
-
'--fork-session',
|
|
233
|
-
])
|
|
234
|
-
const normalEffortAt = normalArgs.indexOf('--effort')
|
|
235
|
-
expect(normalArgs.slice(normalEffortAt, normalEffortAt + 2)).toEqual(['--effort', 'xhigh'])
|
|
236
|
-
const settingsAt = normalArgs.indexOf('--settings')
|
|
237
|
-
expect(normalArgs.slice(settingsAt, settingsAt + 2)).toEqual(['--settings', '{"ultracode":true}'])
|
|
238
|
-
expect(normalArgs).not.toContain('ultracode')
|
|
239
|
-
|
|
240
|
-
for (const args of [resumedArgs, freshArgs, forkArgs]) {
|
|
241
|
-
const effortAt = args.indexOf('--effort')
|
|
242
|
-
expect(args.slice(effortAt, effortAt + 2)).toEqual(['--effort', 'max'])
|
|
243
|
-
}
|
|
244
|
-
})
|
|
245
|
-
|
|
246
|
-
test('Claude turns and Ask reject incomplete terminal protocols', async () => {
|
|
247
|
-
const root = mkdtempSync(join(tmpdir(), 'studio-claude-terminal-'))
|
|
248
|
-
roots.push(root)
|
|
249
|
-
const harness = new ClaudeCodeHarness(fakeClaude(root))
|
|
250
|
-
const input = {
|
|
251
|
-
root,
|
|
252
|
-
prompt: 'work',
|
|
253
|
-
signal: new AbortController().signal,
|
|
254
|
-
onEvent: () => {},
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const noResult = await harness.run({
|
|
258
|
-
...input,
|
|
259
|
-
env: { FAKE_CLAUDE_MODE: 'no-result' },
|
|
260
|
-
})
|
|
261
|
-
expect(noResult).toMatchObject({
|
|
262
|
-
isError: true,
|
|
263
|
-
errorMessage: 'claude exited without a result event',
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
const crashed = await harness.run({
|
|
267
|
-
...input,
|
|
268
|
-
env: { FAKE_CLAUDE_MODE: 'text-then-crash' },
|
|
269
|
-
})
|
|
270
|
-
expect(crashed).toMatchObject({
|
|
271
|
-
isError: true,
|
|
272
|
-
errorMessage: expect.stringContaining('claude exited 7'),
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
const askInput = {
|
|
276
|
-
root,
|
|
277
|
-
prompt: 'question',
|
|
278
|
-
signal: new AbortController().signal,
|
|
279
|
-
onDelta: () => {},
|
|
280
|
-
}
|
|
281
|
-
const askNoResult = await harness.ask({
|
|
282
|
-
...askInput,
|
|
283
|
-
env: { FAKE_CLAUDE_MODE: 'no-result' },
|
|
284
|
-
})
|
|
285
|
-
expect(askNoResult).toMatchObject({
|
|
286
|
-
isError: true,
|
|
287
|
-
errorMessage: 'claude exited without a result event',
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
const askCrashed = await harness.ask({
|
|
291
|
-
...askInput,
|
|
292
|
-
env: { FAKE_CLAUDE_MODE: 'text-then-crash' },
|
|
293
|
-
})
|
|
294
|
-
expect(askCrashed).toMatchObject({
|
|
295
|
-
isError: true,
|
|
296
|
-
errorMessage: expect.stringContaining('claude exited 7'),
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
const askTerminalError = await harness.ask({
|
|
300
|
-
...askInput,
|
|
301
|
-
env: { FAKE_CLAUDE_MODE: 'result-error' },
|
|
302
|
-
})
|
|
303
|
-
expect(askTerminalError).toEqual({
|
|
304
|
-
text: 'failed',
|
|
305
|
-
isError: true,
|
|
306
|
-
errorMessage: 'error_during_execution',
|
|
307
|
-
})
|
|
308
|
-
})
|
|
309
|
-
|
|
310
|
-
test('Claude Ask cancellation kills the entire stubborn subprocess group', async () => {
|
|
311
|
-
const root = mkdtempSync(join(tmpdir(), 'studio-claude-ask-cancel-'))
|
|
312
|
-
roots.push(root)
|
|
313
|
-
const pidLog = join(root, 'pids.json')
|
|
314
|
-
const controller = new AbortController()
|
|
315
|
-
const resultPromise = new ClaudeCodeHarness(fakeClaude(root)).ask({
|
|
316
|
-
root,
|
|
317
|
-
prompt: 'question',
|
|
318
|
-
env: {
|
|
319
|
-
FAKE_CLAUDE_MODE: 'hang-ignore-term',
|
|
320
|
-
FAKE_CLAUDE_PID_LOG: pidLog,
|
|
321
|
-
},
|
|
322
|
-
signal: controller.signal,
|
|
323
|
-
onDelta: () => {},
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
let pids: { parent: number; child: number } | undefined
|
|
327
|
-
await waitFor(() => {
|
|
328
|
-
if (!existsSync(pidLog)) return false
|
|
329
|
-
try {
|
|
330
|
-
pids = JSON.parse(readFileSync(pidLog, 'utf8')) as { parent: number; child: number }
|
|
331
|
-
return Number.isInteger(pids.parent) && Number.isInteger(pids.child)
|
|
332
|
-
} catch {
|
|
333
|
-
return false
|
|
334
|
-
}
|
|
335
|
-
})
|
|
336
|
-
if (!pids) throw new Error('fake Claude did not publish complete process evidence')
|
|
337
|
-
const processIds = pids
|
|
338
|
-
expect(processExists(processIds.parent)).toBe(true)
|
|
339
|
-
expect(processExists(processIds.child)).toBe(true)
|
|
340
|
-
controller.abort()
|
|
341
|
-
|
|
342
|
-
expect(await resultPromise).toEqual({
|
|
343
|
-
text: '',
|
|
344
|
-
isError: true,
|
|
345
|
-
errorMessage: 'canceled',
|
|
346
|
-
})
|
|
347
|
-
await waitFor(() => !processExists(processIds.parent) && !processExists(processIds.child))
|
|
348
|
-
})
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import type { HarnessLoadout } from '../../../../shared/types'
|
|
2
|
-
import type {
|
|
3
|
-
AgentHarness,
|
|
4
|
-
AgentTurnInput,
|
|
5
|
-
AgentTurnResult,
|
|
6
|
-
AskInput,
|
|
7
|
-
HarnessHealth,
|
|
8
|
-
HarnessLoadoutOptions,
|
|
9
|
-
} from '../adapter'
|
|
10
|
-
|
|
11
|
-
import { readSkillContent } from '../skills'
|
|
12
|
-
import { runClaudeAsk } from './ask'
|
|
13
|
-
import { CLAUDE_CAPABILITIES } from './capabilities'
|
|
14
|
-
import { runClaudeTurn } from './events'
|
|
15
|
-
import { loadClaudeConfiguration, probeClaudeHealth } from './loadout'
|
|
16
|
-
import { scanClaudeSkills } from './skills'
|
|
17
|
-
|
|
18
|
-
const DEFAULT_BIN = process.env.DOMAIN_STUDIO_CLAUDE_BIN || 'claude'
|
|
19
|
-
|
|
20
|
-
export class ClaudeCodeHarness implements AgentHarness {
|
|
21
|
-
id = 'claude'
|
|
22
|
-
label = 'Claude Code (local)'
|
|
23
|
-
capabilities = CLAUDE_CAPABILITIES
|
|
24
|
-
|
|
25
|
-
private availCache?: { at: number; health: HarnessHealth }
|
|
26
|
-
private loadoutCache?: { at: number; key: string; data: HarnessLoadout }
|
|
27
|
-
|
|
28
|
-
constructor(private readonly bin = DEFAULT_BIN) {}
|
|
29
|
-
|
|
30
|
-
async health(signal?: AbortSignal): Promise<HarnessHealth> {
|
|
31
|
-
const now = Date.now()
|
|
32
|
-
if (this.availCache && now - this.availCache.at < 30_000) return this.availCache.health
|
|
33
|
-
const health = await probeClaudeHealth(this.bin, signal)
|
|
34
|
-
if (!signal?.aborted) this.availCache = { at: now, health }
|
|
35
|
-
return health
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async isAvailable(signal?: AbortSignal): Promise<boolean> {
|
|
39
|
-
return (await this.health(signal)).ok
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async loadout(root: string, options?: HarnessLoadoutOptions): Promise<HarnessLoadout> {
|
|
43
|
-
const now = Date.now()
|
|
44
|
-
const key = `${root}\u0000${options?.model ?? ''}\u0000${JSON.stringify(options?.env ?? {})}`
|
|
45
|
-
if (
|
|
46
|
-
!options?.refresh &&
|
|
47
|
-
this.loadoutCache &&
|
|
48
|
-
this.loadoutCache.key === key &&
|
|
49
|
-
now - this.loadoutCache.at < 60_000
|
|
50
|
-
)
|
|
51
|
-
return this.loadoutCache.data
|
|
52
|
-
const data = await loadClaudeConfiguration(this.bin, root, options)
|
|
53
|
-
this.loadoutCache = { at: now, key, data }
|
|
54
|
-
return data
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async skillContent(
|
|
58
|
-
root: string,
|
|
59
|
-
command: string,
|
|
60
|
-
): Promise<{ command: string; content: string; path: string } | null> {
|
|
61
|
-
return readSkillContent(scanClaudeSkills(root), command)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
run(input: AgentTurnInput): Promise<AgentTurnResult> {
|
|
65
|
-
return runClaudeTurn(this.bin, input)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
ask(input: AskInput) {
|
|
69
|
-
return runClaudeAsk(this.bin, input)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process'
|
|
2
|
-
|
|
3
|
-
import type { AskInput, AskResult } from '../adapter'
|
|
4
|
-
|
|
5
|
-
import { childEnvironment, terminateProcessTree } from '../process'
|
|
6
|
-
import { buildClaudeAskArgs } from './command'
|
|
7
|
-
|
|
8
|
-
/** Execute one ephemeral Claude side-question stream. */
|
|
9
|
-
export function runClaudeAsk(bin: string, input: AskInput): Promise<AskResult> {
|
|
10
|
-
return new Promise((resolve) => {
|
|
11
|
-
let finalText = ''
|
|
12
|
-
let stderr = ''
|
|
13
|
-
let isError = false
|
|
14
|
-
let errorMessage: string | undefined
|
|
15
|
-
let sawResult = false
|
|
16
|
-
let settled = false
|
|
17
|
-
let forceKillTimer: ReturnType<typeof setTimeout> | undefined
|
|
18
|
-
let onAbort = () => {}
|
|
19
|
-
const finish = (result: AskResult) => {
|
|
20
|
-
if (settled) return
|
|
21
|
-
settled = true
|
|
22
|
-
if (forceKillTimer) clearTimeout(forceKillTimer)
|
|
23
|
-
input.signal.removeEventListener('abort', onAbort)
|
|
24
|
-
resolve(result)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let child: ReturnType<typeof spawn>
|
|
28
|
-
try {
|
|
29
|
-
child = spawn(bin, buildClaudeAskArgs(input), {
|
|
30
|
-
cwd: input.root,
|
|
31
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
32
|
-
env: childEnvironment(input.env),
|
|
33
|
-
detached: process.platform !== 'win32',
|
|
34
|
-
})
|
|
35
|
-
} catch (error) {
|
|
36
|
-
finish({
|
|
37
|
-
text: finalText,
|
|
38
|
-
isError: true,
|
|
39
|
-
errorMessage: `failed to spawn ${bin}: ${String(error)}`,
|
|
40
|
-
})
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
onAbort = () => {
|
|
44
|
-
terminateProcessTree(child)
|
|
45
|
-
forceKillTimer = setTimeout(() => terminateProcessTree(child, 'SIGKILL'), 2_000)
|
|
46
|
-
forceKillTimer.unref?.()
|
|
47
|
-
}
|
|
48
|
-
if (input.signal.aborted) onAbort()
|
|
49
|
-
else input.signal.addEventListener('abort', onAbort, { once: true })
|
|
50
|
-
child.stdin?.write(input.prompt)
|
|
51
|
-
child.stdin?.end()
|
|
52
|
-
|
|
53
|
-
const handleLine = (line: string) => {
|
|
54
|
-
let event: any
|
|
55
|
-
try {
|
|
56
|
-
event = JSON.parse(line)
|
|
57
|
-
} catch {
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
|
-
if (event.type === 'assistant' && Array.isArray(event.message?.content)) {
|
|
61
|
-
for (const block of event.message.content)
|
|
62
|
-
if (block.type === 'text' && block.text) input.onDelta(block.text)
|
|
63
|
-
} else if (event.type === 'result') {
|
|
64
|
-
sawResult = true
|
|
65
|
-
if (typeof event.result === 'string') finalText = event.result
|
|
66
|
-
if (
|
|
67
|
-
event.is_error ||
|
|
68
|
-
event.subtype === 'error_during_execution' ||
|
|
69
|
-
event.subtype === 'error_max_turns'
|
|
70
|
-
) {
|
|
71
|
-
isError = true
|
|
72
|
-
errorMessage = event.subtype || 'ask error'
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
let buffer = ''
|
|
77
|
-
child.stdout?.setEncoding('utf8')
|
|
78
|
-
child.stdout?.on('data', (chunk: string) => {
|
|
79
|
-
buffer += chunk
|
|
80
|
-
let newline: number
|
|
81
|
-
while ((newline = buffer.indexOf('\n')) >= 0) {
|
|
82
|
-
const line = buffer.slice(0, newline).trim()
|
|
83
|
-
buffer = buffer.slice(newline + 1)
|
|
84
|
-
if (line) handleLine(line)
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
child.stderr?.setEncoding('utf8')
|
|
88
|
-
child.stderr?.on('data', (chunk: string) => {
|
|
89
|
-
stderr += chunk
|
|
90
|
-
})
|
|
91
|
-
child.on('error', (error) =>
|
|
92
|
-
finish({
|
|
93
|
-
text: finalText,
|
|
94
|
-
isError: true,
|
|
95
|
-
errorMessage: `failed to spawn ${bin}: ${error.message}`,
|
|
96
|
-
}),
|
|
97
|
-
)
|
|
98
|
-
child.on('close', (code) => {
|
|
99
|
-
const trailing = buffer.trim()
|
|
100
|
-
if (trailing) handleLine(trailing)
|
|
101
|
-
if (input.signal.aborted)
|
|
102
|
-
return finish({ text: finalText, isError: true, errorMessage: 'canceled' })
|
|
103
|
-
if (code !== 0) {
|
|
104
|
-
isError = true
|
|
105
|
-
errorMessage =
|
|
106
|
-
errorMessage || `claude exited ${code}${stderr ? `: ${stderr.slice(-300)}` : ''}`
|
|
107
|
-
} else if (!sawResult) {
|
|
108
|
-
isError = true
|
|
109
|
-
errorMessage = 'claude exited without a result event'
|
|
110
|
-
}
|
|
111
|
-
finish({ text: finalText, isError, errorMessage })
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
}
|