experimental-ash 0.30.1 → 0.33.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/CHANGELOG.md +32 -0
- package/dist/docs/public/auth-and-route-protection.md +95 -17
- package/dist/docs/public/channels/README.md +9 -3
- package/dist/src/channel/send.js +1 -1
- package/dist/src/cli/dev/repl.js +2 -2
- package/dist/src/cli/run.d.ts +0 -1
- package/dist/src/cli/run.js +2 -2
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/compiled/.vendor-stamp.json +6 -6
- package/dist/src/compiled/@ai-sdk/anthropic/index.d.ts +2 -2
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/anthropic/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/google/index.d.ts +14 -1
- package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
- package/dist/src/compiled/@ai-sdk/google/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/openai/package.json +1 -1
- package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/otel/package.json +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +34 -11
- package/dist/src/compiled/_chunks/workflow/{dist-DZZY3Zyp.js → dist-Dl-X5RB3.js} +1 -1
- package/dist/src/compiled/just-bash/index.d.ts +48 -0
- package/dist/src/compiler/normalize-helpers.js +1 -1
- package/dist/src/context/serialize.d.ts +1 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/discover/skills.js +1 -1
- package/dist/src/execution/code-mode-authorization-lifecycle.d.ts +15 -0
- package/dist/src/execution/code-mode-authorization-lifecycle.js +1 -0
- package/dist/src/execution/connection-auth-tool-result.d.ts +2 -0
- package/dist/src/execution/connection-auth-tool-result.js +1 -0
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/durable-session-store.d.ts +1 -1
- package/dist/src/execution/next-driver-action.d.ts +1 -0
- package/dist/src/execution/node-step.d.ts +12 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/sandbox/bash-tool.js +1 -1
- package/dist/src/execution/sandbox/bindings/local.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/sandbox/glob-tool.js +1 -1
- package/dist/src/execution/sandbox/grep-tool.js +1 -1
- package/dist/src/execution/sandbox/ripgrep-probe.js +1 -1
- package/dist/src/execution/sandbox/session.d.ts +3 -1
- package/dist/src/execution/sandbox/session.js +1 -1
- package/dist/src/execution/sandbox/shell-quote.d.ts +1 -1
- package/dist/src/execution/session-callback-step.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +4 -8
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/attachment-staging.js +1 -1
- package/dist/src/harness/authorization.d.ts +81 -0
- package/dist/src/harness/authorization.js +1 -0
- package/dist/src/harness/code-mode-approval.d.ts +22 -0
- package/dist/src/harness/code-mode-approval.js +1 -0
- package/dist/src/harness/code-mode-connection-auth-state.d.ts +15 -0
- package/dist/src/harness/code-mode-connection-auth-state.js +1 -0
- package/dist/src/harness/code-mode.d.ts +31 -0
- package/dist/src/harness/code-mode.js +1 -0
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/input-extraction.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/logging.d.ts +10 -0
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/code-mode-worker-asset.d.ts +18 -0
- package/dist/src/internal/nitro/host/code-mode-worker-asset.js +1 -0
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +3 -3
- package/dist/src/internal/nitro/host/create-application-nitro.d.ts +0 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +0 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/dispatch-schedule-in-dev.d.ts +41 -0
- package/dist/src/internal/nitro/host/dispatch-schedule-in-dev.js +1 -0
- package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.d.ts +6 -1
- package/dist/src/internal/nitro/host/start-development-server.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/dev-schedule-dispatch.d.ts +15 -0
- package/dist/src/internal/nitro/routes/dev-schedule-dispatch.js +1 -0
- package/dist/src/internal/nitro/routes/info.d.ts +4 -2
- package/dist/src/internal/nitro/routes/info.js +1 -1
- package/dist/src/internal/workflow-bundle/builder-support.js +1 -1
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/approval-continuation.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/approval-response.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/code-mode-tool.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/continuation-capability.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/errors.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/fetch-policy.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/host-interrupt.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/index.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/interrupt-continuation.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/options.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/run-code-mode.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/manager.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/max-workers.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime/worker-source.js +1153 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/runtime-assets.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/serialization.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/source-cache.js +4 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/telemetry.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/tool-invocation.js +1 -0
- package/dist/src/node_modules/.pnpm/experimental-ai-sdk-code-mode@1.0.9_ai@7.0.0-canary.154_zod@4.4.3_/node_modules/experimental-ai-sdk-code-mode/dist/tool-prompt.js +9 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/checks.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/coerce.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/compat.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/from-json-schema.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/api.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/checks.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/doc.js +3 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js +2 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/index.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-generator.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/parse.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/regexes.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/schemas.js +60 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js +3 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ar.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/az.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/be.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/bg.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ca.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/cs.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/da.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/de.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/el.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/en.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/eo.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/es.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fa.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fi.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr-CA.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/he.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hr.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hu.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hy.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/id.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/index.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/is.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/it.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ja.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ka.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/kh.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/km.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ko.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/lt.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/mk.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ms.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/nl.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/no.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ota.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pl.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ps.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pt.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ro.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ru.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sl.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sv.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ta.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/th.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/tr.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ua.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uk.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ur.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uz.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/vi.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/yo.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-CN.js +1 -0
- package/dist/src/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-TW.js +1 -0
- package/dist/src/protocol/message.d.ts +18 -45
- package/dist/src/protocol/message.js +1 -1
- package/dist/src/protocol/routes.d.ts +25 -3
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/ash.d.ts +9 -1
- package/dist/src/public/channels/ash.js +1 -1
- package/dist/src/public/channels/auth.d.ts +68 -3
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.d.ts +2 -3
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/connections.d.ts +3 -3
- package/dist/src/public/channels/slack/defaults.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.d.ts +5 -6
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +2 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +2 -3
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -3
- package/dist/src/public/connections/errors.d.ts +1 -1
- package/dist/src/public/connections/index.js +1 -1
- package/dist/src/public/definitions/connections/mcp.d.ts +3 -3
- package/dist/src/public/definitions/defineChannel.d.ts +2 -3
- package/dist/src/public/definitions/defineChannel.js +1 -1
- package/dist/src/public/definitions/sandbox.d.ts +1 -1
- package/dist/src/public/sandbox/index.d.ts +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +4 -3
- package/dist/src/runtime/connections/callback-route.js +1 -1
- package/dist/src/runtime/connections/mcp-client.d.ts +1 -1
- package/dist/src/runtime/connections/mcp-client.js +1 -1
- package/dist/src/runtime/connections/principal.d.ts +2 -9
- package/dist/src/runtime/connections/principal.js +1 -1
- package/dist/src/runtime/connections/types.d.ts +6 -6
- package/dist/src/runtime/framework-channels/index.d.ts +8 -0
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/framework-tools/code-mode-connection-auth.d.ts +27 -0
- package/dist/src/runtime/framework-tools/code-mode-connection-auth.js +1 -0
- package/dist/src/runtime/framework-tools/connection-search.d.ts +5 -3
- package/dist/src/runtime/framework-tools/connection-search.js +1 -1
- package/dist/src/runtime/framework-tools/connection-tools.d.ts +22 -4
- package/dist/src/runtime/framework-tools/connection-tools.js +1 -1
- package/dist/src/runtime/prompt/connections.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/services/dev-client/request-headers.d.ts +3 -2
- package/dist/src/shared/code-mode.d.ts +2 -0
- package/dist/src/shared/code-mode.js +1 -0
- package/dist/src/shared/sandbox-session.d.ts +38 -10
- package/package.json +9 -8
- package/dist/src/execution/authorization-challenge-defaults.d.ts +0 -43
- package/dist/src/execution/authorization-challenge-defaults.js +0 -1
- package/dist/src/execution/await-authorization-orchestrator.d.ts +0 -26
- package/dist/src/execution/await-authorization-orchestrator.js +0 -1
- package/dist/src/execution/await-authorization-splice.d.ts +0 -23
- package/dist/src/execution/await-authorization-splice.js +0 -1
- package/dist/src/execution/connection-auth-steps.d.ts +0 -108
- package/dist/src/execution/connection-auth-steps.js +0 -1
- package/dist/src/runtime/connections/principal-context.d.ts +0 -101
- package/dist/src/runtime/connections/principal-context.js +0 -1
- package/dist/src/runtime/framework-tools/pending-connection-tool-calls.d.ts +0 -78
- package/dist/src/runtime/framework-tools/pending-connection-tool-calls.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# experimental-ash
|
|
2
2
|
|
|
3
|
+
## 0.33.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- fde16ec: Typed authorization API with channel events: replace the generic `suspend()` / `getSuspension()` primitive with a purpose-built `requestAuthorization` / `getAuthorizationResult` / `getHookUrl` API. The harness now emits typed `authorization.required` and `authorization.completed` stream events that channels can handle directly (sign-in buttons, adaptive cards). A single per-session auth hook with a deterministic token replaces the old per-challenge orchestrator. Custom authored tools can use the same API for OAuth flows.
|
|
8
|
+
|
|
9
|
+
Connection authorization now works in code mode. When a connection tool or `connection_search` needs OAuth inside the code-mode sandbox, the harness parks the session, emits `authorization.required`, and resumes via the SDK's `continueCodeModeInterrupt` after the callback — matching the direct-mode behavior.
|
|
10
|
+
|
|
11
|
+
- cb16d9a: Log failed tool calls, code-mode failures, and channel/runtime errors with full stack traces. Throwing tools (previously caught by the AI SDK and reduced to a message) now log the live error and cause chain; channel dispatch catches handler throws and logs rejected background tasks instead of dropping them; and the runtime logs `run`/`deliver` failures with full detail. Adds `ASH_LOG_LEVEL` (`debug`|`info`|`warn`|`error`, defaulting to `info` in production) to control verbosity.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- dc97980: Limit `ash dev` lockfile watcher paths to the app root when no workspace marker is found, avoiding Windows fs watcher crashes from watching filesystem-root ancestors.
|
|
16
|
+
- cb16d9a: The workflow bundler now fails the build with a clear, attributed error when a Node.js built-in reaches the durable workflow driver body (which runs in a VM with no `require`). Previously such an import — typically pulled in transitively by a plain helper imported into a `"use workflow"` body — only surfaced at workflow run time as a cryptic `ReferenceError: require is not defined`. The error now names the offending builtin and the importing module and points to the fix (move the Node API behind a `"use step"`).
|
|
17
|
+
|
|
18
|
+
## 0.32.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- a274bcd: `ashChannel({ auth })` now accepts an ordered `AuthFn[]` (or a single `AuthFn`) walked by a new public `routeAuth(request, auth)` helper: first `SessionAuthContext` wins, `null` / `undefined` skips, exhaustion (including `[]`) returns 401. Adds a new `localDev()` helper that authenticates requests addressed to a loopback hostname so `[localDev(), vercelOidc()]` is the canonical dev-and-prod chain — and the new framework default for the ash channel and `/ash/v1/info`. **Breaking:** `none()` now returns a synthetic `SessionAuthContext` with `principalType: "anonymous"` instead of `undefined`; routes detecting anonymous traffic should check `principalType === "anonymous"` rather than `session.auth.current === null`.
|
|
23
|
+
|
|
24
|
+
## 0.31.0
|
|
25
|
+
|
|
26
|
+
### Minor Changes
|
|
27
|
+
|
|
28
|
+
- d665a4a: Add opt-in code-mode tool routing behind `CODE_MODE=1`. When enabled, executable Ash tools route through `experimental-ai-sdk-code-mode@1.0.7`, including sandbox, file, connection search, and discovered connection tools; when unset, tools remain on the direct path.
|
|
29
|
+
- 21c4d5a: Remove `ash dev --schedules` and the cron-driven schedule firing it enabled during development. `ash dev` no longer registers Nitro scheduled tasks at all, so authored schedules will not fire on their cron expressions while developing. To trigger an authored schedule on demand, `POST` the dev-only `/ash/v1/dev/schedules/:scheduleId` route; the response body is `{ scheduleId, sessionIds }`, and each session id can be streamed from the existing `/ash/v1/session/:sessionId/stream` route. The dispatch route is only mounted when Nitro is running in dev mode — production builds never expose it.
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- e756718: feat(ash): update to latest AI SDK versions, add `spawn` to `SandboxSession` and rename `runCommand` to `run`
|
|
34
|
+
|
|
3
35
|
## 0.30.1
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
|
@@ -15,35 +15,79 @@ These settings apply to:
|
|
|
15
15
|
- `POST /ash/v1/session/:sessionId`
|
|
16
16
|
- `GET /ash/v1/session/:sessionId/stream`
|
|
17
17
|
|
|
18
|
-
## The
|
|
18
|
+
## The Default
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
`pnpm create experimental-ash-agent` scaffolds `agent/channels/ash.ts` with the same default chain
|
|
21
|
+
the framework applies when no file exists:
|
|
21
22
|
|
|
22
23
|
```ts
|
|
23
24
|
// agent/channels/ash.ts
|
|
24
25
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
25
|
-
import { vercelOidc } from "experimental-ash/channels/auth";
|
|
26
|
+
import { localDev, vercelOidc } from "experimental-ash/channels/auth";
|
|
26
27
|
|
|
27
28
|
export default ashChannel({
|
|
28
|
-
auth: vercelOidc(),
|
|
29
|
+
auth: [localDev(), vercelOidc()],
|
|
29
30
|
});
|
|
30
31
|
```
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
over framework defaults by name.
|
|
33
|
+
Deleting the file restores the framework default — the array above is the framework default, just
|
|
34
|
+
written out so you can see and edit it.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
## Walking The Auth Array
|
|
37
|
+
|
|
38
|
+
`auth` accepts either a single `AuthFn` or an array of them walked in order. Each entry returns:
|
|
39
|
+
|
|
40
|
+
- a `SessionAuthContext` — accept the request and halt the walk
|
|
41
|
+
- `null` or `undefined` — skip to the next entry
|
|
42
|
+
|
|
43
|
+
If every entry skips, the request is rejected with `401`. An empty array `auth: []` therefore
|
|
44
|
+
rejects every request.
|
|
45
|
+
|
|
46
|
+
To accept anonymous traffic, include `none()` as the final entry:
|
|
37
47
|
|
|
38
48
|
```ts
|
|
39
49
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
40
50
|
import { none } from "experimental-ash/channels/auth";
|
|
41
51
|
|
|
42
52
|
export default ashChannel({
|
|
43
|
-
auth: none(),
|
|
53
|
+
auth: [none()],
|
|
44
54
|
});
|
|
45
55
|
```
|
|
46
56
|
|
|
57
|
+
`none()` returns a synthetic `SessionAuthContext` with `principalType: "anonymous"`, which
|
|
58
|
+
terminates the walk.
|
|
59
|
+
|
|
60
|
+
## Layering Providers
|
|
61
|
+
|
|
62
|
+
The array shape makes it easy to layer providers without rewriting a resolver. Insert new entries
|
|
63
|
+
before the catch-all helpers:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { ashChannel } from "experimental-ash/channels/ash";
|
|
67
|
+
import { type AuthFn, localDev, vercelOidc } from "experimental-ash/channels/auth";
|
|
68
|
+
import { getAuthJsSession } from "@/lib/auth";
|
|
69
|
+
|
|
70
|
+
function authjsSession(): AuthFn<Request> {
|
|
71
|
+
return async (request) => {
|
|
72
|
+
const session = await getAuthJsSession(request);
|
|
73
|
+
if (!session) return null;
|
|
74
|
+
return {
|
|
75
|
+
attributes: { providerId: session.providerId },
|
|
76
|
+
authenticator: "authjs",
|
|
77
|
+
principalId: session.profile.sub,
|
|
78
|
+
principalType: "user",
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default ashChannel({
|
|
84
|
+
auth: [authjsSession(), localDev(), vercelOidc()],
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Each entry that doesn't recognize the caller returns `null` and the walk falls through to the
|
|
89
|
+
next.
|
|
90
|
+
|
|
47
91
|
## Network Policy
|
|
48
92
|
|
|
49
93
|
Ash exposes IP allow-list helpers in `experimental-ash/channels/auth`.
|
|
@@ -57,6 +101,7 @@ If a request fails the network policy, Ash rejects it before auth or runtime exe
|
|
|
57
101
|
|
|
58
102
|
Ash currently ships these channel-auth helpers:
|
|
59
103
|
|
|
104
|
+
- `localDev`
|
|
60
105
|
- `none`
|
|
61
106
|
- `httpBasic`
|
|
62
107
|
- `jwtHmac`
|
|
@@ -64,17 +109,46 @@ Ash currently ships these channel-auth helpers:
|
|
|
64
109
|
- `oidc`
|
|
65
110
|
- `vercelOidc`
|
|
66
111
|
|
|
67
|
-
You can compose them with the low-level verifier helpers when you need custom request handling.
|
|
112
|
+
You can compose them with the low-level verifier helpers when you need custom request handling. For
|
|
113
|
+
custom channels built on `defineChannel`, call `routeAuth(request, auth)` from
|
|
114
|
+
`experimental-ash/channels/auth` to share the same walk semantics.
|
|
68
115
|
|
|
69
116
|
## Strategy Notes
|
|
70
117
|
|
|
118
|
+
### `localDev`
|
|
119
|
+
|
|
120
|
+
Authenticates with a synthetic `local-dev` principal **when the inbound request is addressed to
|
|
121
|
+
a loopback hostname**. The check is on the request URL, not on environment variables. A hostname
|
|
122
|
+
counts as loopback when it is:
|
|
123
|
+
|
|
124
|
+
- `localhost` or any `*.localhost` subdomain (RFC 6761),
|
|
125
|
+
- any IPv4 address in `127.0.0.0/8`, or
|
|
126
|
+
- the IPv6 loopback `::1`.
|
|
127
|
+
|
|
128
|
+
Every other request (a deployed Vercel hostname, a `fly.dev` URL, a public IP, etc.) returns
|
|
129
|
+
`null` so the walk falls through to the next entry.
|
|
130
|
+
|
|
131
|
+
This is deliberately not an env check. Sniffing `process.env.VERCEL` is unsafe: a deployment
|
|
132
|
+
outside Vercel (Fly, Railway, self-hosted, a raw container) leaves `VERCEL` unset, which under
|
|
133
|
+
the env-based model would accept every request from the public internet. Inspecting the request
|
|
134
|
+
hostname is correct on `ash dev`, `vercel dev`, smoke tests, Vitest workers, and any deployment
|
|
135
|
+
target — Vercel or otherwise.
|
|
136
|
+
|
|
137
|
+
Caveat: `localDev()` trusts whatever hostname the request advertises. If you publish an origin
|
|
138
|
+
that lets attacker-controlled `Host` headers through (no CDN, no normalizing reverse proxy in
|
|
139
|
+
front), an attacker can spoof `Host: localhost` and reach `localDev()`. Layer a real
|
|
140
|
+
authenticator on such deployments and do not rely on `localDev()` alone.
|
|
141
|
+
|
|
71
142
|
### `vercelOidc`
|
|
72
143
|
|
|
73
|
-
Use this for the common Vercel deployment path.
|
|
144
|
+
Use this for the common Vercel deployment path. Verifies a bearer JWT against the Vercel OIDC
|
|
145
|
+
issuer; tokens minted for the current `VERCEL_PROJECT_ID` are always accepted (so internal
|
|
146
|
+
subagent / runtime callers authenticate without configuration).
|
|
74
147
|
|
|
75
148
|
### `none`
|
|
76
149
|
|
|
77
|
-
Use
|
|
150
|
+
Returns a synthetic anonymous `SessionAuthContext`. Use as the final entry in `auth` to accept
|
|
151
|
+
unauthenticated traffic explicitly.
|
|
78
152
|
|
|
79
153
|
### `httpBasic`
|
|
80
154
|
|
|
@@ -108,7 +182,9 @@ Important behavior:
|
|
|
108
182
|
- `auth.current` is the caller for the active inbound turn
|
|
109
183
|
- `auth.initiator` is the caller that started the durable session
|
|
110
184
|
- follow-up messages update `auth.current` without changing `auth.initiator`
|
|
111
|
-
-
|
|
185
|
+
- both are `null` only on internal runtime paths (e.g. subagents) that never went through an
|
|
186
|
+
authored channel route — HTTP traffic always populates `auth.current` because the walker either
|
|
187
|
+
accepts with a `SessionAuthContext` or returns `401`
|
|
112
188
|
|
|
113
189
|
Auth on follow-up messages (`deliver()`) is honored by the workflow runtime. When a different
|
|
114
190
|
user sends a follow-up to the same session, `session.auth.current` reflects the new caller on
|
|
@@ -131,10 +207,12 @@ import { ashChannel } from "experimental-ash/channels/ash";
|
|
|
131
207
|
import { httpBasic } from "experimental-ash/channels/auth";
|
|
132
208
|
|
|
133
209
|
export default ashChannel({
|
|
134
|
-
auth:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
210
|
+
auth: [
|
|
211
|
+
httpBasic({
|
|
212
|
+
username: "ops",
|
|
213
|
+
password: process.env.ROUTE_AUTH_BASIC_PASSWORD,
|
|
214
|
+
}),
|
|
215
|
+
],
|
|
138
216
|
});
|
|
139
217
|
```
|
|
140
218
|
|
|
@@ -97,18 +97,24 @@ The framework ships its canonical session protocol on `experimental-ash/channels
|
|
|
97
97
|
This is the channel the Ash dev client and any deployed-agent SDK talk to — it mounts the routes
|
|
98
98
|
under `/ash/v1/session*` documented in [Ash External Agent Protocol](../../external-agent-protocol.md).
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
`auth` accepts either a single `AuthFn` or an ordered array walked in order: the first entry
|
|
101
|
+
returning a `SessionAuthContext` wins, `null` / `undefined` skips, exhaustion (including `[]`)
|
|
102
|
+
returns `401`. Use `experimental-ash/channels/auth` for the common helpers such as `localDev()`,
|
|
101
103
|
`vercelOidc()`, `httpBasic()`, and `none()`.
|
|
102
104
|
|
|
103
105
|
```ts
|
|
104
106
|
import { ashChannel } from "experimental-ash/channels/ash";
|
|
105
|
-
import { vercelOidc } from "experimental-ash/channels/auth";
|
|
107
|
+
import { localDev, vercelOidc } from "experimental-ash/channels/auth";
|
|
106
108
|
|
|
107
109
|
export default ashChannel({
|
|
108
|
-
auth: vercelOidc(),
|
|
110
|
+
auth: [localDev(), vercelOidc()],
|
|
109
111
|
});
|
|
110
112
|
```
|
|
111
113
|
|
|
114
|
+
`pnpm create experimental-ash-agent` scaffolds exactly this file at `agent/channels/ash.ts` —
|
|
115
|
+
deleting it restores the same default. See [Auth and Route Protection](../auth-and-route-protection.md)
|
|
116
|
+
for the full walking semantics and helper reference.
|
|
117
|
+
|
|
112
118
|
## Slack Channels
|
|
113
119
|
|
|
114
120
|
Slack channels are authored with a single `slackChannel()` factory. Pass no config for the
|
package/dist/src/channel/send.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSession}from"#channel/session.js";import{
|
|
1
|
+
import{createSession}from"#channel/session.js";import{createLogger}from"#internal/logging.js";import{isRuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{serializeUrlFilePart}from"#internal/attachments/url-refs.js";const log=createLogger(`channel.send`);function createSendFn(t,r,i){return async(a,o)=>{let s=o.auth,c=o.callback,l=o.mode??`conversation`,u=o.state,d=o.continuationToken,f=`${i}:${d}`,{message:p,inputResponses:m,modelContext:h}=normalizeSendInput(a),g=serializeUrlFilePartsInMessage(p);try{let{sessionId:n}=await t.deliver({auth:s,continuationToken:f,payload:{inputResponses:m,message:g,modelContext:h}});return createSession(n,d,t)}catch(e){isRuntimeNoActiveSessionError(e)||log.warn(`deliver failed, falling back to starting a new session`,{continuationToken:f})}if(m&&m.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let _=u?{...r,state:{...r.state,...u}}:r;return createSession((await t.run({adapter:_,auth:s,capabilities:l===`conversation`?{requestInput:!0}:void 0,callback:c,continuationToken:f,input:{message:g??``,modelContext:h},mode:l})).sessionId,d,t)}}function serializeUrlFilePartsInMessage(e){if(e===void 0||typeof e==`string`)return e;let t=!1,n=e.map(e=>e.type===`file`&&e.data instanceof URL&&e.data.protocol!==`data:`?(t=!0,{...e,data:serializeUrlFilePart(e.data)}):e);return t?n:e}function normalizeSendInput(e){return typeof e==`string`||Array.isArray(e)?{message:e}:e}export{createSendFn};
|
package/dist/src/cli/dev/repl.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function normalizeStepMessage(e){let t=e.trim();return t.length>0?t:null}function getRenderTag(e){return e.options?.isSubagent===!0?`subagent`:e.fallback}function getRenderTone(e){return e.options?.isSubagent===!0?`subagent`:e.fallback}function prefixSourceLabel(e){return e.options?.sourceLabel===void 0?e.message:`${e.options.sourceLabel}${e.separator??` `}${e.message}`}function formatContentEvent(e,t,n){switch(t.type){case`message.appended`:return{finalized:!1,kind:`message`,line:renderCliSpeakerLine(e,{message:t.data.messageSoFar,speaker:n?.sourceLabel??`agent`,tone:getRenderTone({fallback:`accent`,options:n})})};case`message.completed`:if(t.data.message===null)return;if(t.data.finishReason===`tool-calls`){let r=normalizeStepMessage(t.data.message);return r===null?void 0:{finalized:!0,kind:`message`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:r,options:n,separator:`: `}),tag:getRenderTag({fallback:`step`,options:n}),tone:getRenderTone({fallback:`accent`,options:n})})}}return{finalized:!0,kind:`message`,line:renderCliSpeakerLine(e,{message:t.data.message,speaker:n?.sourceLabel??`agent`,tone:getRenderTone({fallback:`accent`,options:n})})};case`reasoning.appended`:return{finalized:!1,kind:`reasoning`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:t.data.reasoningSoFar,options:n,separator:`: `}),tag:getRenderTag({fallback:`reasoning`,options:n}),tone:getRenderTone({fallback:`info`,options:n})})};case`reasoning.completed`:return{finalized:!0,kind:`reasoning`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:t.data.reasoning,options:n,separator:`: `}),tag:getRenderTag({fallback:`reasoning`,options:n}),tone:getRenderTone({fallback:`info`,options:n})})};default:return}}function formatEvent(e,t,n){let r=formatContentEvent(e,t,n);if(r!==void 0)return r.line;switch(t.type){case`message.received`:return;case`actions.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.actions.length} action${t.data.actions.length===1?``:`s`})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`input.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.requests.length} request${t.data.requests.length===1?``:`s`})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`action.result`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${formatActionResultLabel(t.data.result)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`session.waiting`:case`session.completed`:return;case`connection.authorization_required`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.connectionName}: ${t.data.description}${formatAuthorizationChallengeSuffix(t.data.authorization)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`warning`,options:n})});case`compaction.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`compacting conversation history`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`compaction.completed`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`conversation history compacted`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`step.failed`:case`turn.failed`:case`session.failed`:return;case`subagent.called`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.name} -> ${t.data.childSessionId})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`subagent.started`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`subagent.event`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName}: ${formatNestedSubagentEventLabel(t.data.event)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`subagent.completed`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});default:return}}function getEventDisplayBlockKind(e){switch(e.type){case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:return`content`;default:return`meta`}}function createTurnDisplayState(){return{activeLiveContentKind:null,lastPrintedBlockKind:null}}function printDisplayLine(e){let t=e.state;return t.activeLiveContentKind!==null&&(e.terminal.commitLive(),t={activeLiveContentKind:null,lastPrintedBlockKind:`content`}),t.lastPrintedBlockKind!==null&&t.lastPrintedBlockKind!==e.kind&&e.terminal.print(``),e.terminal.print(e.line),{activeLiveContentKind:null,lastPrintedBlockKind:e.kind}}function renderTurnEvent(e){let t=formatContentEvent(e.theme,e.event,e.options);if(t!==void 0){let n=e.state;return n.activeLiveContentKind!==null&&n.activeLiveContentKind!==t.kind&&(e.terminal.commitLive(),n={activeLiveContentKind:null,lastPrintedBlockKind:`content`}),n.lastPrintedBlockKind!==null&&n.lastPrintedBlockKind!==`content`&&e.terminal.print(``),e.terminal.updateLive(t.line),t.finalized?(e.terminal.commitLive(),{activeLiveContentKind:null,lastPrintedBlockKind:`content`}):{activeLiveContentKind:t.kind,lastPrintedBlockKind:`content`}}let n=formatEvent(e.theme,e.event,e.options);return n===void 0?e.state:printDisplayLine({kind:getEventDisplayBlockKind(e.event),line:n,state:e.state,terminal:e.terminal})}function isAbortLikeError(e){return(e instanceof DOMException||e instanceof Error)&&e.name===`AbortError`}function shouldDrainSubagentStreamsOnBoundary(e){return e.length===0}var ReplSubagentStreamManager=class{#e=new Map;#t;#n;#r;#i;constructor(e){this.#t=e.displayStateRef,this.#n=e.serverUrl,this.#r=e.terminal,this.#i=e.theme}subscribe(e){if(this.#e.has(e.sessionId))return;let t=new AbortController,n=this.#a({controller:t,sessionId:e.sessionId,subagentName:e.subagentName}).finally(()=>{this.#e.delete(e.sessionId)});this.#e.set(e.sessionId,{controller:t,done:n,label:e.subagentName})}async waitForIdle(){for(;this.#e.size>0;)await Promise.all([...this.#e.values()].map(e=>e.done))}async close(){let e=[...this.#e.values()];for(let t of e)t.controller.abort();await Promise.allSettled(e.map(e=>e.done))}async#a(t){let n=resolveDevelopmentServerResourceUrl({resource:createAshMessageStreamRoutePath(t.sessionId),serverUrl:this.#n});try{for await(let e of openStreamIterable({host:this.#n,maxReconnectAttempts:3,resolveHeaders:async()=>await createDevelopmentRequestHeadersAsync({resourceUrl:n}),sessionId:t.sessionId,signal:t.controller.signal,startIndex:0}))if(this.#t.current=renderTurnEvent({event:e,options:{isSubagent:!0,sourceLabel:t.subagentName},state:this.#t.current,terminal:this.#r,theme:this.#i}),e.type===`subagent.called`&&this.subscribe({sessionId:e.data.childSessionId,subagentName:e.data.name}),isCurrentTurnBoundaryEvent(e))return}catch(n){if(isAbortLikeError(n))return;let r=toErrorMessage(n);this.#t.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(this.#i,{message:`${t.subagentName} stream failed: ${r}`,tag:`subagent`,tone:`danger`}),state:this.#t.current,terminal:this.#r})}finally{t.controller.abort()}}};function formatActionResultLabel(e){switch(e.kind){case`load-skill-result`:return e.kind;case`subagent-result`:return`${e.kind}:${e.subagentName}`;case`tool-result`:return`${e.kind}:${e.toolName}`}}function formatAuthorizationChallengeSuffix(e){if(e===void 0)return``;let t=[];return e.url!==void 0&&t.push(e.url),e.userCode!==void 0&&t.push(`code ${e.userCode}`),e.instructions!==void 0&&t.push(e.instructions),t.length===0?``:` — ${t.join(`, `)}`}function formatNestedSubagentEventLabel(e){switch(e.type){case`actions.requested`:{let t=e.data.actions,n=t.map(e=>e.kind===`tool-call`?e.toolName:e.kind).join(`,`);return`${e.type} (${t.length} action${t.length===1?``:`s`}${n.length>0?`: ${n}`:``})`}case`action.result`:return`${e.type} (${formatActionResultLabel(e.data.result)})`;case`input.requested`:return`${e.type} (${e.data.requests.length} request${e.data.requests.length===1?``:`s`})`;default:return e.type}}function formatDispatch(e,t){return t.continuationToken?renderCliTaggedLine(e,{message:`resuming session ${t.continuationToken}`,tag:`session`,tone:`info`}):renderCliTaggedLine(e,{message:`starting a new session`,tag:`session`,tone:`info`})}function formatTurnDispatch(e,t){return t.turn.inputResponses!==void 0&&t.turn.message===void 0?renderCliTaggedLine(e,{message:`responding to pending input request${t.turn.inputResponses.length===1?``:`s`}`,tag:`session`,tone:`info`}):formatDispatch(e,t.session)}function formatSessionBoundary(e,t){let n=extractCurrentTurnBoundaryEvent(t),r=extractPendingRuntimeInputRequests(t);switch(n?.type){case`session.waiting`:return[renderCliTaggedLine(e,{message:r.length>0?`waiting for input approval/answer or the next message`:`waiting for the next message`,tag:`session`,tone:`success`})];case`session.completed`:return[renderCliTaggedLine(e,{message:`session completed; the next input starts a new session`,tag:`session`,tone:`success`})];case`session.failed`:{let t=n.data.details&&typeof n.data.details.name==`string`?n.data.details.name:void 0;return[renderCliTaggedLine(e,{message:t?`session failed (${t}): ${n.data.message}`:`session failed: ${n.data.message}`,tag:`session`,tone:`danger`}),renderCliTaggedLine(e,{message:`cleared; the next input starts a new session`,tag:`session`,tone:`warning`})]}default:return[]}}async function waitForInputLine(e,t,n={}){return await new Promise(r=>{let i=e.input,cleanup=()=>{e.off(`close`,handleClose),e.off(`line`,handleLine),i.off(`keypress`,handleKeypress)},handleClose=()=>{cleanup(),r(void 0)},handleLine=e=>{cleanup(),r(e)},handleKeypress=(t,i)=>{n.allowEscape!==!0||i.name!==`escape`||(cleanup(),e.write(null,{ctrl:!0,name:`u`}),r(ESCAPED_RUNTIME_INPUT_PROMPT))};e.setPrompt(t),e.once(`close`,handleClose),e.once(`line`,handleLine),n.allowEscape&&(emitKeypressEvents(i,e),i.on(`keypress`,handleKeypress)),e.prompt()})}async function runTurn(e){let t=e.turn,n={current:createTurnDisplayState()},r=new ReplSubagentStreamManager({displayStateRef:n,serverUrl:e.serverUrl,terminal:e.terminal,theme:e.theme}),ask=async t=>{e.terminal.startPrompt(e.rl,t);let n=await waitForInputLine(e.rl,t,{allowEscape:!0});return e.terminal.stopPrompt(),n};try{for(;;){let a=e.client.getSession();n.current=printDisplayLine({kind:`meta`,line:formatTurnDispatch(e.theme,{session:a,turn:t}),state:n.current,terminal:e.terminal});let o=await e.client.send({inputResponses:t.inputResponses,message:t.message,onEvent(t){n.current=renderTurnEvent({event:t,state:n.current,terminal:e.terminal,theme:e.theme}),t.type===`subagent.called`&&r.subscribe({sessionId:t.data.childSessionId,subagentName:t.data.name})},onResponseStart(t){t.sessionId&&a.sessionId!==t.sessionId&&(n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:t.sessionId,tag:`session`,tone:`accent`}),state:n.current,terminal:e.terminal}),n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:resolveDevelopmentServerResourceUrl({resource:createAshMessageStreamRoutePath(t.sessionId),serverUrl:e.serverUrl}).toString(),tag:`stream`,tone:`info`}),state:n.current,terminal:e.terminal}))}}),s=extractPendingRuntimeInputRequests(o.events);if(shouldDrainSubagentStreamsOnBoundary(s)){await r.waitForIdle();for(let t of formatSessionBoundary(e.theme,o.events))n.current=printDisplayLine({kind:`meta`,line:t,state:n.current,terminal:e.terminal});return`continue`}let c=await promptForRuntimeInputRequests({ask,print(t){n.current=printDisplayLine({kind:`meta`,line:t,state:n.current,terminal:e.terminal})},requests:s,theme:e.theme});if(c.kind===`aborted`)return`exit`;if(c.kind===`deferred`)return n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:`left pending input requests unresolved; send a new message to ignore them`,tag:`session`,tone:`warning`}),state:n.current,terminal:e.terminal}),`continue`;t={inputResponses:c.inputResponses}}}finally{await r.close()}}async function runDevelopmentRepl(t){let n=createDevelopmentTerminal(),r=createCliTheme({color:!0}),i=createInterface({input:process.stdin,output:n.output,terminal:!0});i.on(`SIGINT`,()=>{i.close()});let o=createDevClient({serverUrl:t.serverUrl});try{for(n.print(renderIntro(r,t)),n.print(``);;){n.print(``),n.startPrompt(i,`you> `);let a=await waitForInputLine(i,`you> `);if(n.stopPrompt(),a===void 0)return;let s=parseDevReplInput(a);switch(s.kind!==`empty`&&s.kind!==`exit`&&n.print(``),s.kind){case`empty`:continue;case`help`:n.print(renderIntro(r,t)),n.print(``);continue;case`exit`:return;case`new`:await o.clear(),n.print(renderCliTaggedLine(r,{message:`cleared; the next input starts a new session`,tag:`session`,tone:`warning`})),n.print(``);continue;case`message`:try{if(await runTurn({client:o,rl:i,serverUrl:t.serverUrl,terminal:n,theme:r,turn:{message:s.message}})===`exit`)return}catch(i){isVercelAuthChallenge(i)?n.printError(renderCliTaggedLine(r,{message:formatVercelAuthChallengeMessage({serverUrl:t.serverUrl}),tag:`auth`,tone:`warning`})):n.printError(renderCliTaggedLine(r,{message:toErrorMessage(i),tag:`error`,tone:`danger`}))}n.print(``)}}}finally{await o.close(),i.close(),n.dispose()}}export{createTurnDisplayState,formatContentEvent,formatEvent,renderTurnEvent,runDevelopmentRepl,shouldDrainSubagentStreamsOnBoundary};
|
|
1
|
+
import{ASH_CONTINUE_SESSION_ROUTE_PATTERN,ASH_CREATE_SESSION_ROUTE_PATH,ASH_MESSAGE_STREAM_ROUTE_PATTERN,createAshMessageStreamRoutePath}from"#protocol/routes.js";import{createCliTheme,renderCliBanner,renderCliSection,renderCliSpeakerLine,renderCliTaggedLine}from"#cli/ui/output.js";import{createInterface,emitKeypressEvents}from"node:readline";import{openStreamIterable}from"#client/open-stream.js";import{isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{toErrorMessage}from"#shared/errors.js";import{createDevelopmentRequestHeadersAsync}from"#services/dev-client/request-headers.js";import{extractCurrentTurnBoundaryEvent}from"#services/dev-client/stream.js";import{resolveDevelopmentServerResourceUrl}from"#services/dev-client/url.js";import{formatVercelAuthChallengeMessage,isVercelAuthChallenge}from"#services/dev-client/vercel-auth-error.js";import{createDevClient}from"#services/dev-client.js";import{parseDevReplInput}from"#cli/dev/input.js";import{ESCAPED_RUNTIME_INPUT_PROMPT,extractPendingRuntimeInputRequests,promptForRuntimeInputRequests}from"#cli/dev/input-requests.js";import{createDevelopmentTerminal}from"#cli/dev/terminal.js";function renderConnectionRows(r){let i=[{label:`Server`,tone:`info`,value:r.serverUrl},{label:`Create`,tone:`info`,value:`POST ${ASH_CREATE_SESSION_ROUTE_PATH}`},{label:`Continue`,tone:`info`,value:`POST ${ASH_CONTINUE_SESSION_ROUTE_PATTERN}`},{label:`Stream`,tone:`info`,value:`GET ${ASH_MESSAGE_STREAM_ROUTE_PATTERN}`}];return i.push({label:`Session`,value:`Follow-up messages reuse the active continuation token.`}),i}function renderCommandRows(){return[{label:`/help`,value:`Print the connection contract and available commands.`},{label:`/new`,value:`Clear the current durable session cursor.`},{label:`/exit`,value:`Exit the REPL.`}]}function renderIntro(e,t){return[renderCliBanner(e,{subtitle:`Interactive development REPL for the active Ash server.`,title:`Ash Dev`}),``,renderCliSection(e,{rows:renderConnectionRows(t),title:`Connection`}),``,renderCliSection(e,{rows:renderCommandRows(),title:`Commands`})].join(`
|
|
2
|
+
`)}function normalizeStepMessage(e){let t=e.trim();return t.length>0?t:null}function getRenderTag(e){return e.options?.isSubagent===!0?`subagent`:e.fallback}function getRenderTone(e){return e.options?.isSubagent===!0?`subagent`:e.fallback}function prefixSourceLabel(e){return e.options?.sourceLabel===void 0?e.message:`${e.options.sourceLabel}${e.separator??` `}${e.message}`}function formatContentEvent(e,t,n){switch(t.type){case`message.appended`:return{finalized:!1,kind:`message`,line:renderCliSpeakerLine(e,{message:t.data.messageSoFar,speaker:n?.sourceLabel??`agent`,tone:getRenderTone({fallback:`accent`,options:n})})};case`message.completed`:if(t.data.message===null)return;if(t.data.finishReason===`tool-calls`){let r=normalizeStepMessage(t.data.message);return r===null?void 0:{finalized:!0,kind:`message`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:r,options:n,separator:`: `}),tag:getRenderTag({fallback:`step`,options:n}),tone:getRenderTone({fallback:`accent`,options:n})})}}return{finalized:!0,kind:`message`,line:renderCliSpeakerLine(e,{message:t.data.message,speaker:n?.sourceLabel??`agent`,tone:getRenderTone({fallback:`accent`,options:n})})};case`reasoning.appended`:return{finalized:!1,kind:`reasoning`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:t.data.reasoningSoFar,options:n,separator:`: `}),tag:getRenderTag({fallback:`reasoning`,options:n}),tone:getRenderTone({fallback:`info`,options:n})})};case`reasoning.completed`:return{finalized:!0,kind:`reasoning`,line:renderCliTaggedLine(e,{message:prefixSourceLabel({message:t.data.reasoning,options:n,separator:`: `}),tag:getRenderTag({fallback:`reasoning`,options:n}),tone:getRenderTone({fallback:`info`,options:n})})};default:return}}function formatEvent(e,t,n){let r=formatContentEvent(e,t,n);if(r!==void 0)return r.line;switch(t.type){case`message.received`:return;case`actions.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.actions.length} action${t.data.actions.length===1?``:`s`})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`input.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.requests.length} request${t.data.requests.length===1?``:`s`})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`action.result`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${formatActionResultLabel(t.data.result)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`session.waiting`:case`session.completed`:return;case`authorization.required`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.name}: ${t.data.description}${formatAuthorizationChallengeSuffix(t.data.authorization)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`warning`,options:n})});case`compaction.requested`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`compacting conversation history`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`compaction.completed`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`conversation history compacted`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`step.failed`:case`turn.failed`:case`session.failed`:return;case`subagent.called`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.name} -> ${t.data.childSessionId})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`subagent.started`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});case`subagent.event`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName}: ${formatNestedSubagentEventLabel(t.data.event)})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`muted`,options:n})});case`subagent.completed`:return renderCliTaggedLine(e,{message:prefixSourceLabel({message:`${t.type} (${t.data.subagentName})`,options:n}),tag:getRenderTag({fallback:`event`,options:n}),tone:getRenderTone({fallback:`info`,options:n})});default:return}}function getEventDisplayBlockKind(e){switch(e.type){case`message.appended`:case`message.completed`:case`reasoning.appended`:case`reasoning.completed`:return`content`;default:return`meta`}}function createTurnDisplayState(){return{activeLiveContentKind:null,lastPrintedBlockKind:null}}function printDisplayLine(e){let t=e.state;return t.activeLiveContentKind!==null&&(e.terminal.commitLive(),t={activeLiveContentKind:null,lastPrintedBlockKind:`content`}),t.lastPrintedBlockKind!==null&&t.lastPrintedBlockKind!==e.kind&&e.terminal.print(``),e.terminal.print(e.line),{activeLiveContentKind:null,lastPrintedBlockKind:e.kind}}function renderTurnEvent(e){let t=formatContentEvent(e.theme,e.event,e.options);if(t!==void 0){let n=e.state;return n.activeLiveContentKind!==null&&n.activeLiveContentKind!==t.kind&&(e.terminal.commitLive(),n={activeLiveContentKind:null,lastPrintedBlockKind:`content`}),n.lastPrintedBlockKind!==null&&n.lastPrintedBlockKind!==`content`&&e.terminal.print(``),e.terminal.updateLive(t.line),t.finalized?(e.terminal.commitLive(),{activeLiveContentKind:null,lastPrintedBlockKind:`content`}):{activeLiveContentKind:t.kind,lastPrintedBlockKind:`content`}}let n=formatEvent(e.theme,e.event,e.options);return n===void 0?e.state:printDisplayLine({kind:getEventDisplayBlockKind(e.event),line:n,state:e.state,terminal:e.terminal})}function isAbortLikeError(e){return(e instanceof DOMException||e instanceof Error)&&e.name===`AbortError`}function shouldDrainSubagentStreamsOnBoundary(e){return e.length===0}var ReplSubagentStreamManager=class{#e=new Map;#t;#n;#r;#i;constructor(e){this.#t=e.displayStateRef,this.#n=e.serverUrl,this.#r=e.terminal,this.#i=e.theme}subscribe(e){if(this.#e.has(e.sessionId))return;let t=new AbortController,n=this.#a({controller:t,sessionId:e.sessionId,subagentName:e.subagentName}).finally(()=>{this.#e.delete(e.sessionId)});this.#e.set(e.sessionId,{controller:t,done:n,label:e.subagentName})}async waitForIdle(){for(;this.#e.size>0;)await Promise.all([...this.#e.values()].map(e=>e.done))}async close(){let e=[...this.#e.values()];for(let t of e)t.controller.abort();await Promise.allSettled(e.map(e=>e.done))}async#a(e){let t=resolveDevelopmentServerResourceUrl({resource:createAshMessageStreamRoutePath(e.sessionId),serverUrl:this.#n});try{for await(let n of openStreamIterable({host:this.#n,maxReconnectAttempts:3,resolveHeaders:async()=>await createDevelopmentRequestHeadersAsync({resourceUrl:t}),sessionId:e.sessionId,signal:e.controller.signal,startIndex:0}))if(this.#t.current=renderTurnEvent({event:n,options:{isSubagent:!0,sourceLabel:e.subagentName},state:this.#t.current,terminal:this.#r,theme:this.#i}),n.type===`subagent.called`&&this.subscribe({sessionId:n.data.childSessionId,subagentName:n.data.name}),isCurrentTurnBoundaryEvent(n))return}catch(t){if(isAbortLikeError(t))return;let n=toErrorMessage(t);this.#t.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(this.#i,{message:`${e.subagentName} stream failed: ${n}`,tag:`subagent`,tone:`danger`}),state:this.#t.current,terminal:this.#r})}finally{e.controller.abort()}}};function formatActionResultLabel(e){switch(e.kind){case`load-skill-result`:return e.kind;case`subagent-result`:return`${e.kind}:${e.subagentName}`;case`tool-result`:return`${e.kind}:${e.toolName}`}}function formatAuthorizationChallengeSuffix(e){if(e===void 0)return``;let t=[];return e.url!==void 0&&t.push(e.url),e.userCode!==void 0&&t.push(`code ${e.userCode}`),e.instructions!==void 0&&t.push(e.instructions),t.length===0?``:` — ${t.join(`, `)}`}function formatNestedSubagentEventLabel(e){switch(e.type){case`actions.requested`:{let t=e.data.actions,n=t.map(e=>e.kind===`tool-call`?e.toolName:e.kind).join(`,`);return`${e.type} (${t.length} action${t.length===1?``:`s`}${n.length>0?`: ${n}`:``})`}case`action.result`:return`${e.type} (${formatActionResultLabel(e.data.result)})`;case`input.requested`:return`${e.type} (${e.data.requests.length} request${e.data.requests.length===1?``:`s`})`;default:return e.type}}function formatDispatch(e,t){return t.continuationToken?renderCliTaggedLine(e,{message:`resuming session ${t.continuationToken}`,tag:`session`,tone:`info`}):renderCliTaggedLine(e,{message:`starting a new session`,tag:`session`,tone:`info`})}function formatTurnDispatch(e,t){return t.turn.inputResponses!==void 0&&t.turn.message===void 0?renderCliTaggedLine(e,{message:`responding to pending input request${t.turn.inputResponses.length===1?``:`s`}`,tag:`session`,tone:`info`}):formatDispatch(e,t.session)}function formatSessionBoundary(e,t){let n=extractCurrentTurnBoundaryEvent(t),r=extractPendingRuntimeInputRequests(t);switch(n?.type){case`session.waiting`:return[renderCliTaggedLine(e,{message:r.length>0?`waiting for input approval/answer or the next message`:`waiting for the next message`,tag:`session`,tone:`success`})];case`session.completed`:return[renderCliTaggedLine(e,{message:`session completed; the next input starts a new session`,tag:`session`,tone:`success`})];case`session.failed`:{let t=n.data.details&&typeof n.data.details.name==`string`?n.data.details.name:void 0;return[renderCliTaggedLine(e,{message:t?`session failed (${t}): ${n.data.message}`:`session failed: ${n.data.message}`,tag:`session`,tone:`danger`}),renderCliTaggedLine(e,{message:`cleared; the next input starts a new session`,tag:`session`,tone:`warning`})]}default:return[]}}async function waitForInputLine(e,t,n={}){return await new Promise(r=>{let i=e.input,cleanup=()=>{e.off(`close`,handleClose),e.off(`line`,handleLine),i.off(`keypress`,handleKeypress)},handleClose=()=>{cleanup(),r(void 0)},handleLine=e=>{cleanup(),r(e)},handleKeypress=(t,i)=>{n.allowEscape!==!0||i.name!==`escape`||(cleanup(),e.write(null,{ctrl:!0,name:`u`}),r(ESCAPED_RUNTIME_INPUT_PROMPT))};e.setPrompt(t),e.once(`close`,handleClose),e.once(`line`,handleLine),n.allowEscape&&(emitKeypressEvents(i,e),i.on(`keypress`,handleKeypress)),e.prompt()})}async function runTurn(e){let t=e.turn,n={current:createTurnDisplayState()},i=new ReplSubagentStreamManager({displayStateRef:n,serverUrl:e.serverUrl,terminal:e.terminal,theme:e.theme}),ask=async t=>{e.terminal.startPrompt(e.rl,t);let n=await waitForInputLine(e.rl,t,{allowEscape:!0});return e.terminal.stopPrompt(),n};try{for(;;){let a=e.client.getSession();n.current=printDisplayLine({kind:`meta`,line:formatTurnDispatch(e.theme,{session:a,turn:t}),state:n.current,terminal:e.terminal});let o=await e.client.send({inputResponses:t.inputResponses,message:t.message,onEvent(t){n.current=renderTurnEvent({event:t,state:n.current,terminal:e.terminal,theme:e.theme}),t.type===`subagent.called`&&i.subscribe({sessionId:t.data.childSessionId,subagentName:t.data.name})},onResponseStart(t){t.sessionId&&a.sessionId!==t.sessionId&&(n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:t.sessionId,tag:`session`,tone:`accent`}),state:n.current,terminal:e.terminal}),n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:resolveDevelopmentServerResourceUrl({resource:createAshMessageStreamRoutePath(t.sessionId),serverUrl:e.serverUrl}).toString(),tag:`stream`,tone:`info`}),state:n.current,terminal:e.terminal}))}}),s=extractPendingRuntimeInputRequests(o.events);if(shouldDrainSubagentStreamsOnBoundary(s)){await i.waitForIdle();for(let t of formatSessionBoundary(e.theme,o.events))n.current=printDisplayLine({kind:`meta`,line:t,state:n.current,terminal:e.terminal});return`continue`}let c=await promptForRuntimeInputRequests({ask,print(t){n.current=printDisplayLine({kind:`meta`,line:t,state:n.current,terminal:e.terminal})},requests:s,theme:e.theme});if(c.kind===`aborted`)return`exit`;if(c.kind===`deferred`)return n.current=printDisplayLine({kind:`meta`,line:renderCliTaggedLine(e.theme,{message:`left pending input requests unresolved; send a new message to ignore them`,tag:`session`,tone:`warning`}),state:n.current,terminal:e.terminal}),`continue`;t={inputResponses:c.inputResponses}}}finally{await i.close()}}async function runDevelopmentRepl(e){let t=createDevelopmentTerminal(),n=createCliTheme({color:!0}),r=createInterface({input:process.stdin,output:t.output,terminal:!0});r.on(`SIGINT`,()=>{r.close()});let a=createDevClient({serverUrl:e.serverUrl});try{for(t.print(renderIntro(n,e)),t.print(``);;){t.print(``),t.startPrompt(r,`you> `);let i=await waitForInputLine(r,`you> `);if(t.stopPrompt(),i===void 0)return;let o=parseDevReplInput(i);switch(o.kind!==`empty`&&o.kind!==`exit`&&t.print(``),o.kind){case`empty`:continue;case`help`:t.print(renderIntro(n,e)),t.print(``);continue;case`exit`:return;case`new`:await a.clear(),t.print(renderCliTaggedLine(n,{message:`cleared; the next input starts a new session`,tag:`session`,tone:`warning`})),t.print(``);continue;case`message`:try{if(await runTurn({client:a,rl:r,serverUrl:e.serverUrl,terminal:t,theme:n,turn:{message:o.message}})===`exit`)return}catch(r){isVercelAuthChallenge(r)?t.printError(renderCliTaggedLine(n,{message:formatVercelAuthChallengeMessage({serverUrl:e.serverUrl}),tag:`auth`,tone:`warning`})):t.printError(renderCliTaggedLine(n,{message:toErrorMessage(r),tag:`error`,tone:`danger`}))}t.print(``)}}}finally{await a.close(),r.close(),t.dispose()}}export{createTurnDisplayState,formatContentEvent,formatEvent,renderTurnEvent,runDevelopmentRepl,shouldDrainSubagentStreamsOnBoundary};
|
package/dist/src/cli/run.d.ts
CHANGED
package/dist/src/cli/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";async function loadBuildHost(){return(await import(`#internal/nitro/host.js`)).buildApplication}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentRepl(){return(await import(`#cli/dev/repl.js`)).runDevelopmentRepl}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).startDevelopmentServer}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function rewriteDevelopmentUrlShorthand(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function resolveRemoteDevelopmentServerUrl(e){if(e.url){if(e.host!==void 0)throw new InvalidArgumentError(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new InvalidArgumentError(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new InvalidArgumentError(`The --no-repl option cannot be used with --url.`);return e.url}}function createCliProgram(r,i){let c=resolveApplicationRoot(),l=resolveInstalledPackageInfo().version,u=new Command,d=createCliTheme();u.name(`ash`).description(`Build and run an Ash application.`).version(l).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{shouldPrintCliBootBanner(t)&&r.log(`Ash (v${l})`)}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}});let f=u.command(`channels`).description(`Manage user-authored channels in the current project.`);return f.command(`add [kind]`).description(`Scaffold a channel (slack) into the current project.`).option(`-f, --force`,`Overwrite existing channel files`).action(async(e,t)=>{let{runChannelsAddCommand:n}=await import(`#cli/commands/channels.js`);await n(r,c,{kind:e,options:t})}),f.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async e=>{let{runChannelsListCommand:t}=await import(`#cli/commands/channels.js`);await t(r,c,e)}),u.command(`build`).description(`Build the current Ash application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:e}=await import(`#cli/dev/environment.js`);e(c);let n=await(i.buildHost??await loadBuildHost())(c);r.log(renderCliTaggedLine(d,{message:`built output at ${n}`,tag:`build`,tone:`success`}))}),u.command(`start`).description(`Start a built Ash application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async e=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:e.host,port:e.port});r.log(renderCliTaggedLine(d,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),u.command(`dev`).description(`Start the Ash development server or connect the REPL to an existing URL.`).option(`--host <host>`,`Host interface to bind`).option(`--no-repl`,`Start the server without the interactive REPL`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).option(
|
|
1
|
+
import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";async function loadBuildHost(){return(await import(`#internal/nitro/host.js`)).buildApplication}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentRepl(){return(await import(`#cli/dev/repl.js`)).runDevelopmentRepl}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).startDevelopmentServer}async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function rewriteDevelopmentUrlShorthand(e){let t=e[1];return e[0]!==`dev`||e.length!==2||t===void 0||t.startsWith(`-`)?[...e]:[`dev`,`--url`,t]}function resolveRemoteDevelopmentServerUrl(e){if(e.url){if(e.host!==void 0)throw new InvalidArgumentError(`The --host option cannot be used with --url.`);if(e.port!==void 0)throw new InvalidArgumentError(`The --port option cannot be used with --url.`);if(e.repl===!1)throw new InvalidArgumentError(`The --no-repl option cannot be used with --url.`);return e.url}}function createCliProgram(r,i){let c=resolveApplicationRoot(),l=resolveInstalledPackageInfo().version,u=new Command,d=createCliTheme();u.name(`ash`).description(`Build and run an Ash application.`).version(l).showHelpAfterError().exitOverride().hook(`preAction`,(e,t)=>{shouldPrintCliBootBanner(t)&&r.log(`Ash (v${l})`)}).configureOutput({writeErr:e=>{r.error(e.trimEnd())},writeOut:e=>{r.log(e.trimEnd())}});let f=u.command(`channels`).description(`Manage user-authored channels in the current project.`);return f.command(`add [kind]`).description(`Scaffold a channel (slack) into the current project.`).option(`-f, --force`,`Overwrite existing channel files`).action(async(e,t)=>{let{runChannelsAddCommand:n}=await import(`#cli/commands/channels.js`);await n(r,c,{kind:e,options:t})}),f.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async e=>{let{runChannelsListCommand:t}=await import(`#cli/commands/channels.js`);await t(r,c,e)}),u.command(`build`).description(`Build the current Ash application.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:e}=await import(`#cli/dev/environment.js`);e(c);let n=await(i.buildHost??await loadBuildHost())(c);r.log(renderCliTaggedLine(d,{message:`built output at ${n}`,tag:`build`,tone:`success`}))}),u.command(`start`).description(`Start a built Ash application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async e=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:e.host,port:e.port});r.log(renderCliTaggedLine(d,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),u.command(`dev`).description(`Start the Ash development server or connect the REPL to an existing URL.`).option(`--host <host>`,`Host interface to bind`).option(`--no-repl`,`Start the server without the interactive REPL`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).option(`-u, --url <url>`,`Connect the REPL to an existing server URL`,parseDevelopmentServerUrl).addHelpText(`after`,`
|
|
2
2
|
You can also pass a bare URL as the only argument, for example: ash dev https://example.com
|
|
3
|
-
`).action(async e=>{let n=resolveRemoteDevelopmentServerUrl(e),{loadDevelopmentEnvironmentFiles:a}=await import(`#cli/dev/environment.js`);if(a(c),n){if(r.log(renderCliTaggedLine(d,{message:`REPL connecting to ${n}`,tag:`dev`,tone:`info`})),!hasInteractiveTerminal()){r.log(renderCliTaggedLine(d,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}r.log(``),await(i.runDevelopmentRepl??await loadRunDevelopmentRepl())({serverUrl:n});return}let o=await(i.startHost??await loadStartHost())(c,{host:e.host,port:e.port
|
|
3
|
+
`).action(async e=>{let n=resolveRemoteDevelopmentServerUrl(e),{loadDevelopmentEnvironmentFiles:a}=await import(`#cli/dev/environment.js`);if(a(c),n){if(r.log(renderCliTaggedLine(d,{message:`REPL connecting to ${n}`,tag:`dev`,tone:`info`})),!hasInteractiveTerminal()){r.log(renderCliTaggedLine(d,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}r.log(``),await(i.runDevelopmentRepl??await loadRunDevelopmentRepl())({serverUrl:n});return}let o=await(i.startHost??await loadStartHost())(c,{host:e.host,port:e.port}),s=!1,closeServer=async()=>{s||(s=!0,await o.close())};try{if(r.log(renderCliTaggedLine(d,{message:`server listening at ${o.url}`,tag:`dev`,tone:`success`})),e.repl===!1)return await waitForShutdownSignal({close:closeServer});if(!hasInteractiveTerminal())return r.log(renderCliTaggedLine(d,{message:`Interactive REPL disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await waitForShutdownSignal({close:closeServer});r.log(``),await(i.runDevelopmentRepl??await loadRunDevelopmentRepl())({serverUrl:o.url})}finally{await closeServer()}}),u.command(`info`).description(`Print resolved application information.`).action(async()=>{await(i.printApplicationInfo??await loadPrintApplicationInfo())(r,c)}),u.command(`eval`).description(`Run eval suites against an Ash agent.`).option(`--suite <id...>`,`Suite IDs to run (repeatable)`).option(`--all`,`Run all discovered suites`).option(`--url <url>`,`Remote agent URL (skip local host startup)`).option(`--timeout <ms>`,`Per-case timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent case executions per suite`).option(`--json`,`Output results as JSON`).option(`--skip-report`,`Skip suite-defined reporters (e.g. Braintrust)`).action(async e=>{await(i.runEvalCommand??await loadRunEvalCommand())(e,r)}),u}async function runCli(e=process.argv.slice(2),t=console,n={}){let i=createCliProgram(t,n),a=e.length===0?[`info`]:rewriteDevelopmentUrlShorthand(e);try{await i.parseAsync(a,{from:`user`})}catch(e){if(e instanceof CommanderError){if(e.exitCode===0)return;throw Error(e.message)}throw e}}export{runCli};
|
|
@@ -6,7 +6,7 @@ export { ClientSession } from "#client/session.js";
|
|
|
6
6
|
export type { ClientAuth, ClientOptions, HeadersValue, HealthResult, MessageResult, OpenStreamOptions, SendMessageOptions, SendTurnInput, SessionState, TokenValue, } from "#client/types.js";
|
|
7
7
|
export type { AshAgentReducer, AshAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
|
|
8
8
|
export type { AshMessageData, AshDynamicToolPart, AshMessageInputRequest, AshMessage, AshMessageMetadata, AshMessagePart, AshMessageToolMetadata, } from "#client/message-reducer.js";
|
|
9
|
-
export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent,
|
|
9
|
+
export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionStartedStreamEvent, SessionWaitingStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, SubagentCalledStreamEvent, SubagentChildEventStreamEvent, SubagentCompletedStreamEvent, SubagentStartedStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, } from "#protocol/message.js";
|
|
10
10
|
export { isCurrentTurnBoundaryEvent } from "#protocol/message.js";
|
|
11
11
|
export type { InputOption, InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
12
12
|
export { inputOptionSchema, inputRequestSchema, inputResponseSchema, isInputRequest, isInputResponse, } from "#runtime/input/types.js";
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"moduleVersions": {
|
|
3
|
-
"@ai-sdk/anthropic": "4.0.0-canary.
|
|
3
|
+
"@ai-sdk/anthropic": "4.0.0-canary.60",
|
|
4
4
|
"chat": "4.29.0",
|
|
5
5
|
"@chat-adapter/slack": "4.29.0",
|
|
6
6
|
"@chat-adapter/state-memory": "4.29.0",
|
|
7
7
|
"chokidar": "5.0.0",
|
|
8
8
|
"commander": "14.0.3",
|
|
9
|
-
"@ai-sdk/google": "4.0.0-canary.
|
|
9
|
+
"@ai-sdk/google": "4.0.0-canary.73",
|
|
10
10
|
"gray-matter": "4.0.3",
|
|
11
11
|
"jose": "6.2.3",
|
|
12
12
|
"just-bash": "3.0.1",
|
|
13
13
|
"jsonc-parser": "3.3.1",
|
|
14
|
-
"@ai-sdk/mcp": "2.0.0-canary.
|
|
15
|
-
"@ai-sdk/openai": "4.0.0-canary.
|
|
14
|
+
"@ai-sdk/mcp": "2.0.0-canary.55",
|
|
15
|
+
"@ai-sdk/openai": "4.0.0-canary.64",
|
|
16
16
|
"@opentelemetry/api": "1.9.1",
|
|
17
|
-
"@ai-sdk/otel": "1.0.0-canary.
|
|
17
|
+
"@ai-sdk/otel": "1.0.0-canary.100",
|
|
18
18
|
"picocolors": "1.1.1",
|
|
19
19
|
"@ai-sdk/provider": "4.0.0-canary.17",
|
|
20
20
|
"@standard-schema/spec": "1.1.0",
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"zod": "4.4.3",
|
|
27
27
|
"zod-validation-error": "5.0.0"
|
|
28
28
|
},
|
|
29
|
-
"scriptHash": "
|
|
29
|
+
"scriptHash": "d4ce5a47e0f6620d682bfcba879a1eabaa5c61cc9c9cfe24e3a54c38aaf1edb0"
|
|
30
30
|
}
|
|
@@ -303,7 +303,7 @@ type Bash20241022Options<OUTPUT> = {
|
|
|
303
303
|
onInputDelta?: Tool<Bash20241022Input, OUTPUT, {}>['onInputDelta'];
|
|
304
304
|
onInputAvailable?: Tool<Bash20241022Input, OUTPUT, {}>['onInputAvailable'];
|
|
305
305
|
};
|
|
306
|
-
type Bash20241022DefaultOutput = Awaited<ReturnType<Experimental_Sandbox['
|
|
306
|
+
type Bash20241022DefaultOutput = Awaited<ReturnType<Experimental_Sandbox['run']>>;
|
|
307
307
|
declare function bash_20241022(options?: Omit<Bash20241022Options<Bash20241022DefaultOutput>, 'execute'> & {
|
|
308
308
|
execute?: undefined;
|
|
309
309
|
}): ProviderDefinedTool<Bash20241022Input, Bash20241022DefaultOutput, {}>;
|
|
@@ -332,7 +332,7 @@ type Bash20250124Options<OUTPUT> = {
|
|
|
332
332
|
onInputDelta?: Tool<Bash20250124Input, OUTPUT, {}>['onInputDelta'];
|
|
333
333
|
onInputAvailable?: Tool<Bash20250124Input, OUTPUT, {}>['onInputAvailable'];
|
|
334
334
|
};
|
|
335
|
-
type Bash20250124DefaultOutput = Awaited<ReturnType<Experimental_Sandbox['
|
|
335
|
+
type Bash20250124DefaultOutput = Awaited<ReturnType<Experimental_Sandbox['run']>>;
|
|
336
336
|
declare function bash_20250124(options?: Omit<Bash20250124Options<Bash20250124DefaultOutput>, 'execute'> & {
|
|
337
337
|
execute?: undefined;
|
|
338
338
|
}): ProviderDefinedTool<Bash20250124Input, Bash20250124DefaultOutput, {}>;
|