@stigmer/cli 3.35.0 → 3.37.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/auth/auth0.d.ts.map +1 -1
- package/auth/auth0.js.map +1 -1
- package/auth/callback-server.d.ts.map +1 -1
- package/auth/callback-server.js.map +1 -1
- package/auth/index.d.ts.map +1 -1
- package/auth/index.js.map +1 -1
- package/auth/login.d.ts.map +1 -1
- package/auth/login.js.map +1 -1
- package/auth/pages.d.ts.map +1 -1
- package/auth/pages.js.map +1 -1
- package/auth/pkce.d.ts.map +1 -1
- package/auth/pkce.js.map +1 -1
- package/auth/token.d.ts.map +1 -1
- package/auth/token.js.map +1 -1
- package/backend.d.ts.map +1 -1
- package/backend.js.map +1 -1
- package/cli/stigmer.d.ts.map +1 -1
- package/cli/stigmer.js.map +1 -1
- package/client/client.d.ts.map +1 -1
- package/client/client.js.map +1 -1
- package/client/index.d.ts.map +1 -1
- package/client/index.js.map +1 -1
- package/commands/agent-exec-flags.d.ts.map +1 -1
- package/commands/agent-exec-flags.js.map +1 -1
- package/commands/apikey/duration.d.ts.map +1 -1
- package/commands/apikey/duration.js.map +1 -1
- package/commands/apikey/index.d.ts.map +1 -1
- package/commands/apikey/index.js.map +1 -1
- package/commands/apply.d.ts.map +1 -1
- package/commands/apply.js.map +1 -1
- package/commands/auth/index.d.ts.map +1 -1
- package/commands/auth/index.js.map +1 -1
- package/commands/auth/login.d.ts.map +1 -1
- package/commands/auth/login.js.map +1 -1
- package/commands/auth/whoami.d.ts.map +1 -1
- package/commands/auth/whoami.js.map +1 -1
- package/commands/bootstrap.d.ts.map +1 -1
- package/commands/bootstrap.js.map +1 -1
- package/commands/completion.d.ts.map +1 -1
- package/commands/completion.js.map +1 -1
- package/commands/config/backend.d.ts.map +1 -1
- package/commands/config/backend.js.map +1 -1
- package/commands/config/context.d.ts.map +1 -1
- package/commands/config/context.js.map +1 -1
- package/commands/config/index.d.ts.map +1 -1
- package/commands/config/index.js.map +1 -1
- package/commands/config/kv.d.ts.map +1 -1
- package/commands/config/kv.js.map +1 -1
- package/commands/connect.d.ts.map +1 -1
- package/commands/connect.js.map +1 -1
- package/commands/delete.d.ts.map +1 -1
- package/commands/delete.js.map +1 -1
- package/commands/diff.d.ts.map +1 -1
- package/commands/diff.js.map +1 -1
- package/commands/down.d.ts.map +1 -1
- package/commands/down.js.map +1 -1
- package/commands/download.d.ts.map +1 -1
- package/commands/download.js.map +1 -1
- package/commands/execution/approve.d.ts.map +1 -1
- package/commands/execution/approve.js.map +1 -1
- package/commands/execution/control.d.ts.map +1 -1
- package/commands/execution/control.js.map +1 -1
- package/commands/execution/index.d.ts.map +1 -1
- package/commands/execution/index.js.map +1 -1
- package/commands/execution/logs.d.ts.map +1 -1
- package/commands/execution/logs.js.map +1 -1
- package/commands/execution/trace.d.ts.map +1 -1
- package/commands/execution/trace.js.map +1 -1
- package/commands/get.d.ts.map +1 -1
- package/commands/get.js.map +1 -1
- package/commands/install.d.ts.map +1 -1
- package/commands/install.js.map +1 -1
- package/commands/internal-daemon.d.ts.map +1 -1
- package/commands/internal-daemon.js.map +1 -1
- package/commands/list.d.ts.map +1 -1
- package/commands/list.js.map +1 -1
- package/commands/logs.d.ts.map +1 -1
- package/commands/logs.js.map +1 -1
- package/commands/marketplace.d.ts.map +1 -1
- package/commands/marketplace.js.map +1 -1
- package/commands/mcp-server.d.ts.map +1 -1
- package/commands/mcp-server.js.map +1 -1
- package/commands/push.d.ts.map +1 -1
- package/commands/push.js.map +1 -1
- package/commands/reset.d.ts.map +1 -1
- package/commands/reset.js.map +1 -1
- package/commands/resume.d.ts.map +1 -1
- package/commands/resume.js.map +1 -1
- package/commands/run.d.ts.map +1 -1
- package/commands/run.js.map +1 -1
- package/commands/schedule.d.ts.map +1 -1
- package/commands/schedule.js.map +1 -1
- package/commands/search.d.ts.map +1 -1
- package/commands/search.js.map +1 -1
- package/commands/setup.d.ts.map +1 -1
- package/commands/setup.js.map +1 -1
- package/commands/share.d.ts.map +1 -1
- package/commands/share.js.map +1 -1
- package/commands/shared.d.ts.map +1 -1
- package/commands/shared.js.map +1 -1
- package/commands/status.d.ts.map +1 -1
- package/commands/status.js.map +1 -1
- package/commands/tag.d.ts.map +1 -1
- package/commands/tag.js.map +1 -1
- package/commands/up.d.ts.map +1 -1
- package/commands/up.js.map +1 -1
- package/commands/usage.d.ts.map +1 -1
- package/commands/usage.js.map +1 -1
- package/commands/validate.d.ts.map +1 -1
- package/commands/validate.js.map +1 -1
- package/commands/version.d.ts.map +1 -1
- package/commands/version.js.map +1 -1
- package/config/config.d.ts.map +1 -1
- package/config/config.js.map +1 -1
- package/config/index.d.ts.map +1 -1
- package/config/index.js.map +1 -1
- package/config/keys.d.ts.map +1 -1
- package/config/keys.js.map +1 -1
- package/config/paths.d.ts.map +1 -1
- package/config/paths.js.map +1 -1
- package/config/resolve.d.ts.map +1 -1
- package/config/resolve.js.map +1 -1
- package/errors/classify.d.ts.map +1 -1
- package/errors/classify.js.map +1 -1
- package/errors/cli-exit-error.d.ts.map +1 -1
- package/errors/cli-exit-error.js.map +1 -1
- package/errors/exit-codes.d.ts.map +1 -1
- package/errors/exit-codes.js.map +1 -1
- package/errors/handle.d.ts.map +1 -1
- package/errors/handle.js.map +1 -1
- package/errors/index.d.ts.map +1 -1
- package/errors/index.js.map +1 -1
- package/errors/usage-error.d.ts.map +1 -1
- package/errors/usage-error.js.map +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/local/artifact.d.ts.map +1 -1
- package/local/artifact.js.map +1 -1
- package/local/bootstrap.d.ts.map +1 -1
- package/local/bootstrap.js.map +1 -1
- package/local/constants.d.ts.map +1 -1
- package/local/constants.js.map +1 -1
- package/local/daemon/components.d.ts.map +1 -1
- package/local/daemon/components.js.map +1 -1
- package/local/daemon/env.d.ts.map +1 -1
- package/local/daemon/env.js.map +1 -1
- package/local/daemon/host.d.ts.map +1 -1
- package/local/daemon/host.js.map +1 -1
- package/local/daemon/index.d.ts.map +1 -1
- package/local/daemon/index.js.map +1 -1
- package/local/daemon/launch.d.ts.map +1 -1
- package/local/daemon/launch.js.map +1 -1
- package/local/daemon/process.d.ts.map +1 -1
- package/local/daemon/process.js.map +1 -1
- package/local/daemon/supervisor.d.ts.map +1 -1
- package/local/daemon/supervisor.js.map +1 -1
- package/local/daemon/types.d.ts.map +1 -1
- package/local/daemon/types.js.map +1 -1
- package/local/llm-config.d.ts.map +1 -1
- package/local/llm-config.js.map +1 -1
- package/local/logs/tail.d.ts.map +1 -1
- package/local/logs/tail.js.map +1 -1
- package/local/logs/view.d.ts.map +1 -1
- package/local/logs/view.js.map +1 -1
- package/local/net/tcp.d.ts.map +1 -1
- package/local/net/tcp.js.map +1 -1
- package/local/operator-config.d.ts.map +1 -1
- package/local/operator-config.js.map +1 -1
- package/local/paths.d.ts.map +1 -1
- package/local/paths.js.map +1 -1
- package/local/reset.d.ts.map +1 -1
- package/local/reset.js.map +1 -1
- package/local/runtime/index.d.ts.map +1 -1
- package/local/runtime/index.js.map +1 -1
- package/local/runtime/node.d.ts.map +1 -1
- package/local/runtime/node.js.map +1 -1
- package/local/runtime/runner.d.ts.map +1 -1
- package/local/runtime/runner.js.map +1 -1
- package/local/runtime/runtimes-install.d.ts.map +1 -1
- package/local/runtime/runtimes-install.js.map +1 -1
- package/local/runtime/server.d.ts.map +1 -1
- package/local/runtime/server.js.map +1 -1
- package/local/runtime/which.d.ts.map +1 -1
- package/local/runtime/which.js.map +1 -1
- package/local/setup/prompt.d.ts.map +1 -1
- package/local/setup/prompt.js.map +1 -1
- package/local/setup/wizard.d.ts.map +1 -1
- package/local/setup/wizard.js.map +1 -1
- package/local/state/health-state.d.ts.map +1 -1
- package/local/state/health-state.js.map +1 -1
- package/local/state/index.d.ts.map +1 -1
- package/local/state/index.js.map +1 -1
- package/local/state/lock.d.ts.map +1 -1
- package/local/state/lock.js.map +1 -1
- package/local/state/log-rotation.d.ts.map +1 -1
- package/local/state/log-rotation.js.map +1 -1
- package/local/state/pidfile.d.ts.map +1 -1
- package/local/state/pidfile.js.map +1 -1
- package/local/state/proc.d.ts.map +1 -1
- package/local/state/proc.js.map +1 -1
- package/local/state/startup-config.d.ts.map +1 -1
- package/local/state/startup-config.js.map +1 -1
- package/local/status.d.ts.map +1 -1
- package/local/status.js.map +1 -1
- package/local/temporal/download.d.ts.map +1 -1
- package/local/temporal/download.js.map +1 -1
- package/local/temporal/index.d.ts.map +1 -1
- package/local/temporal/index.js.map +1 -1
- package/local/temporal/inspect.d.ts.map +1 -1
- package/local/temporal/inspect.js.map +1 -1
- package/local/temporal/manager.d.ts.map +1 -1
- package/local/temporal/manager.js.map +1 -1
- package/local/temporal/supervisor.d.ts.map +1 -1
- package/local/temporal/supervisor.js.map +1 -1
- package/local/webconsole/index.d.ts.map +1 -1
- package/local/webconsole/index.js.map +1 -1
- package/logger.d.ts.map +1 -1
- package/logger.js.map +1 -1
- package/marketplace/config.d.ts.map +1 -1
- package/marketplace/config.js.map +1 -1
- package/marketplace/github.d.ts.map +1 -1
- package/marketplace/github.js.map +1 -1
- package/marketplace/index.d.ts.map +1 -1
- package/marketplace/index.js.map +1 -1
- package/marketplace/install.d.ts.map +1 -1
- package/marketplace/install.js.map +1 -1
- package/marketplace/materialize.d.ts.map +1 -1
- package/marketplace/materialize.js.map +1 -1
- package/marketplace/official.d.ts.map +1 -1
- package/marketplace/official.js.map +1 -1
- package/marketplace/read.d.ts.map +1 -1
- package/marketplace/read.js.map +1 -1
- package/marketplace/ref.d.ts.map +1 -1
- package/marketplace/ref.js.map +1 -1
- package/marketplace/render.d.ts.map +1 -1
- package/marketplace/render.js.map +1 -1
- package/output/command-result.d.ts.map +1 -1
- package/output/command-result.js.map +1 -1
- package/output/confirm.d.ts.map +1 -1
- package/output/confirm.js.map +1 -1
- package/output/format.d.ts.map +1 -1
- package/output/format.js.map +1 -1
- package/output/index.d.ts.map +1 -1
- package/output/index.js.map +1 -1
- package/output/ndjson.d.ts.map +1 -1
- package/output/ndjson.js.map +1 -1
- package/output/proto.d.ts.map +1 -1
- package/output/proto.js.map +1 -1
- package/output/style.d.ts.map +1 -1
- package/output/style.js.map +1 -1
- package/output/table.d.ts.map +1 -1
- package/output/table.js.map +1 -1
- package/package.json +7 -7
- package/program.d.ts.map +1 -1
- package/program.js.map +1 -1
- package/registry/aliases.d.ts.map +1 -1
- package/registry/aliases.js.map +1 -1
- package/registry/index.d.ts.map +1 -1
- package/registry/index.js.map +1 -1
- package/registry/metadata.d.ts.map +1 -1
- package/registry/metadata.js.map +1 -1
- package/registry/registry.d.ts.map +1 -1
- package/registry/registry.js.map +1 -1
- package/registry/verb-support.d.ts.map +1 -1
- package/registry/verb-support.js.map +1 -1
- package/registry/verbs.d.ts.map +1 -1
- package/registry/verbs.js.map +1 -1
- package/resources/apply/apply.d.ts.map +1 -1
- package/resources/apply/apply.js.map +1 -1
- package/resources/apply/discovery.d.ts.map +1 -1
- package/resources/apply/discovery.js.map +1 -1
- package/resources/apply/handlers.d.ts.map +1 -1
- package/resources/apply/handlers.js.map +1 -1
- package/resources/connect/connect.d.ts.map +1 -1
- package/resources/connect/connect.js.map +1 -1
- package/resources/connect/discover.d.ts.map +1 -1
- package/resources/connect/discover.js.map +1 -1
- package/resources/connect/display.d.ts.map +1 -1
- package/resources/connect/display.js.map +1 -1
- package/resources/connect/oauth.d.ts.map +1 -1
- package/resources/connect/oauth.js.map +1 -1
- package/resources/cursor-pages.d.ts.map +1 -1
- package/resources/cursor-pages.js.map +1 -1
- package/resources/delete.d.ts.map +1 -1
- package/resources/delete.js.map +1 -1
- package/resources/diff.d.ts.map +1 -1
- package/resources/diff.js.map +1 -1
- package/resources/documents.d.ts.map +1 -1
- package/resources/documents.js.map +1 -1
- package/resources/download.d.ts.map +1 -1
- package/resources/download.js.map +1 -1
- package/resources/execution-approve.d.ts.map +1 -1
- package/resources/execution-approve.js.map +1 -1
- package/resources/execution-control.d.ts.map +1 -1
- package/resources/execution-control.js.map +1 -1
- package/resources/execution-format.d.ts.map +1 -1
- package/resources/execution-format.js.map +1 -1
- package/resources/execution-logs.d.ts.map +1 -1
- package/resources/execution-logs.js.map +1 -1
- package/resources/execution-trace.d.ts.map +1 -1
- package/resources/execution-trace.js.map +1 -1
- package/resources/execution.d.ts.map +1 -1
- package/resources/execution.js.map +1 -1
- package/resources/get-bindings.d.ts.map +1 -1
- package/resources/get-bindings.js.map +1 -1
- package/resources/get.d.ts.map +1 -1
- package/resources/get.js.map +1 -1
- package/resources/git.d.ts.map +1 -1
- package/resources/git.js.map +1 -1
- package/resources/ignore/index.d.ts.map +1 -1
- package/resources/ignore/index.js.map +1 -1
- package/resources/ignore/matcher.d.ts.map +1 -1
- package/resources/ignore/matcher.js.map +1 -1
- package/resources/list.d.ts.map +1 -1
- package/resources/list.js.map +1 -1
- package/resources/mcp/placeholder-resolver.d.ts.map +1 -1
- package/resources/mcp/placeholder-resolver.js.map +1 -1
- package/resources/mcp/runtime-env.d.ts.map +1 -1
- package/resources/mcp/runtime-env.js.map +1 -1
- package/resources/picker/ink.d.ts.map +1 -1
- package/resources/picker/ink.js.map +1 -1
- package/resources/picker/tty.d.ts.map +1 -1
- package/resources/picker/tty.js.map +1 -1
- package/resources/plugin.d.ts.map +1 -1
- package/resources/plugin.js.map +1 -1
- package/resources/reference.d.ts.map +1 -1
- package/resources/reference.js.map +1 -1
- package/resources/render.d.ts.map +1 -1
- package/resources/render.js.map +1 -1
- package/resources/run/agent-exec.d.ts.map +1 -1
- package/resources/run/agent-exec.js.map +1 -1
- package/resources/run/attachments.d.ts.map +1 -1
- package/resources/run/attachments.js.map +1 -1
- package/resources/run/create.d.ts.map +1 -1
- package/resources/run/create.js.map +1 -1
- package/resources/run/env.d.ts.map +1 -1
- package/resources/run/env.js.map +1 -1
- package/resources/run/epilogue.d.ts.map +1 -1
- package/resources/run/epilogue.js.map +1 -1
- package/resources/run/header.d.ts.map +1 -1
- package/resources/run/header.js.map +1 -1
- package/resources/run/prepare.d.ts.map +1 -1
- package/resources/run/prepare.js.map +1 -1
- package/resources/run/resolve.d.ts.map +1 -1
- package/resources/run/resolve.js.map +1 -1
- package/resources/run/resume.d.ts.map +1 -1
- package/resources/run/resume.js.map +1 -1
- package/resources/run/stream.d.ts.map +1 -1
- package/resources/run/stream.js.map +1 -1
- package/resources/run/workflow-stream.d.ts.map +1 -1
- package/resources/run/workflow-stream.js.map +1 -1
- package/resources/run/workspace.d.ts.map +1 -1
- package/resources/run/workspace.js.map +1 -1
- package/resources/schedule.d.ts.map +1 -1
- package/resources/schedule.js.map +1 -1
- package/resources/search.d.ts.map +1 -1
- package/resources/search.js.map +1 -1
- package/resources/session.d.ts.map +1 -1
- package/resources/session.js.map +1 -1
- package/resources/share.d.ts.map +1 -1
- package/resources/share.js.map +1 -1
- package/resources/skill.d.ts.map +1 -1
- package/resources/skill.js.map +1 -1
- package/resources/stream/approval-detect.d.ts.map +1 -1
- package/resources/stream/approval-detect.js.map +1 -1
- package/resources/stream/convert.d.ts.map +1 -1
- package/resources/stream/convert.js.map +1 -1
- package/resources/stream/diff.d.ts.map +1 -1
- package/resources/stream/diff.js.map +1 -1
- package/resources/stream/events.d.ts.map +1 -1
- package/resources/stream/events.js.map +1 -1
- package/resources/stream/headless.d.ts.map +1 -1
- package/resources/stream/headless.js.map +1 -1
- package/resources/stream/ink.d.ts.map +1 -1
- package/resources/stream/ink.js.map +1 -1
- package/resources/stream/render-ndjson.d.ts.map +1 -1
- package/resources/stream/render-ndjson.js.map +1 -1
- package/resources/stream/render-plaintext.d.ts.map +1 -1
- package/resources/stream/render-plaintext.js.map +1 -1
- package/resources/stream/snapshot.d.ts.map +1 -1
- package/resources/stream/snapshot.js.map +1 -1
- package/resources/stream/subagent.d.ts.map +1 -1
- package/resources/stream/subagent.js.map +1 -1
- package/resources/stream/submit.d.ts.map +1 -1
- package/resources/stream/submit.js.map +1 -1
- package/resources/stream/todo.d.ts.map +1 -1
- package/resources/stream/todo.js.map +1 -1
- package/resources/stream/tool-state.d.ts.map +1 -1
- package/resources/stream/tool-state.js.map +1 -1
- package/resources/stream/tty.d.ts.map +1 -1
- package/resources/stream/tty.js.map +1 -1
- package/resources/stream/workflow-event-view.d.ts.map +1 -1
- package/resources/stream/workflow-event-view.js.map +1 -1
- package/resources/stream/workflow-render-ndjson.d.ts.map +1 -1
- package/resources/stream/workflow-render-ndjson.js.map +1 -1
- package/resources/stream/workflow-render-plaintext.d.ts.map +1 -1
- package/resources/stream/workflow-render-plaintext.js.map +1 -1
- package/resources/tag.d.ts.map +1 -1
- package/resources/tag.js.map +1 -1
- package/resources/task-configs.d.ts.map +1 -1
- package/resources/task-configs.js.map +1 -1
- package/resources/usage.d.ts.map +1 -1
- package/resources/usage.js.map +1 -1
- package/resources/validate.d.ts.map +1 -1
- package/resources/validate.js.map +1 -1
- package/resources/version.d.ts.map +1 -1
- package/resources/version.js.map +1 -1
- package/runtime.d.ts.map +1 -1
- package/runtime.js.map +1 -1
- package/version.d.ts.map +1 -1
- package/version.js.map +1 -1
- package/src/auth/pkce.test.ts +0 -37
- package/src/auth/token.test.ts +0 -151
- package/src/client/client.test.ts +0 -142
- package/src/commands/apikey/duration.test.ts +0 -23
- package/src/commands/auth/login.test.ts +0 -52
- package/src/commands/auth/whoami.test.ts +0 -96
- package/src/commands/bootstrap.test.ts +0 -178
- package/src/commands/config/backend.test.ts +0 -122
- package/src/commands/config/context.test.ts +0 -171
- package/src/commands/connect.test.ts +0 -113
- package/src/commands/install.test.ts +0 -307
- package/src/commands/marketplace.test.ts +0 -205
- package/src/commands/mcp-server.test.ts +0 -65
- package/src/commands/validate.test.ts +0 -168
- package/src/config/config.test.ts +0 -132
- package/src/config/keys.test.ts +0 -61
- package/src/config/resolve.test.ts +0 -242
- package/src/errors/clierr.test.ts +0 -172
- package/src/local/artifact.test.ts +0 -54
- package/src/local/bootstrap.test.ts +0 -166
- package/src/local/daemon/components.test.ts +0 -148
- package/src/local/daemon/daemon.integration.test.ts +0 -216
- package/src/local/daemon/env.test.ts +0 -108
- package/src/local/daemon/launch.test.ts +0 -136
- package/src/local/daemon/supervisor.test.ts +0 -260
- package/src/local/llm-config.test.ts +0 -66
- package/src/local/logs/tail.test.ts +0 -70
- package/src/local/logs/view.test.ts +0 -46
- package/src/local/operator-config.test.ts +0 -72
- package/src/local/reset.test.ts +0 -53
- package/src/local/runtime/runtime.test.ts +0 -240
- package/src/local/runtime/runtimes-install.test.ts +0 -58
- package/src/local/runtime/server.test.ts +0 -253
- package/src/local/setup/wizard.test.ts +0 -94
- package/src/local/state/state.test.ts +0 -210
- package/src/local/status.test.ts +0 -108
- package/src/local/temporal/download.test.ts +0 -248
- package/src/local/temporal/inspect.test.ts +0 -83
- package/src/local/temporal/manager.test.ts +0 -64
- package/src/local/temporal/supervisor.test.ts +0 -77
- package/src/marketplace/__fixtures__/cursor-marketplace.ts +0 -69
- package/src/marketplace/config.test.ts +0 -254
- package/src/marketplace/github.test.ts +0 -394
- package/src/marketplace/install.test.ts +0 -261
- package/src/marketplace/official.test.ts +0 -107
- package/src/marketplace/read.test.ts +0 -93
- package/src/marketplace/ref.test.ts +0 -179
- package/src/output/command-result.test.ts +0 -73
- package/src/output/confirm.test.ts +0 -43
- package/src/output/format.test.ts +0 -65
- package/src/output/proto.test.ts +0 -72
- package/src/output/table.test.ts +0 -37
- package/src/program.test.ts +0 -62
- package/src/registry/aliases.test.ts +0 -142
- package/src/registry/registry.test.ts +0 -355
- package/src/resources/apply/apply.integration.test.ts +0 -353
- package/src/resources/apply/apply.test.ts +0 -134
- package/src/resources/apply/discovery.integration.test.ts +0 -99
- package/src/resources/connect/__fixtures__/stdio-crash.mjs +0 -6
- package/src/resources/connect/__fixtures__/stdio-server.mjs +0 -48
- package/src/resources/connect/connect.integration.test.ts +0 -383
- package/src/resources/connect/discover.test.ts +0 -84
- package/src/resources/connect/oauth.test.ts +0 -158
- package/src/resources/cursor-pages.test.ts +0 -55
- package/src/resources/diff.integration.test.ts +0 -103
- package/src/resources/diff.test.ts +0 -34
- package/src/resources/documents.test.ts +0 -67
- package/src/resources/execution-approve.test.ts +0 -50
- package/src/resources/execution-format.test.ts +0 -48
- package/src/resources/execution.integration.test.ts +0 -285
- package/src/resources/execution.test.ts +0 -138
- package/src/resources/ignore/ignore.test.ts +0 -62
- package/src/resources/mcp/placeholder-resolver.test.ts +0 -71
- package/src/resources/mcp/runtime-env.test.ts +0 -102
- package/src/resources/mutate-verbs.integration.test.ts +0 -455
- package/src/resources/picker/tty.test.ts +0 -37
- package/src/resources/plugin.test.ts +0 -379
- package/src/resources/push-download.integration.test.ts +0 -175
- package/src/resources/read-completion.integration.test.ts +0 -164
- package/src/resources/read-verbs.integration.test.ts +0 -603
- package/src/resources/reference.test.ts +0 -107
- package/src/resources/run/agent-exec.test.ts +0 -179
- package/src/resources/run/attachments.test.ts +0 -135
- package/src/resources/run/create.test.ts +0 -336
- package/src/resources/run/env.test.ts +0 -131
- package/src/resources/run/header.test.ts +0 -79
- package/src/resources/run/prepare.test.ts +0 -428
- package/src/resources/run/workflow-stream.integration.test.ts +0 -157
- package/src/resources/run/workspace.test.ts +0 -93
- package/src/resources/share.test.ts +0 -523
- package/src/resources/skill.test.ts +0 -364
- package/src/resources/stream/diff.test.ts +0 -338
- package/src/resources/stream/headless.test.ts +0 -119
- package/src/resources/stream/lazy-import.test.ts +0 -63
- package/src/resources/stream/render-ndjson.test.ts +0 -126
- package/src/resources/stream/render-plaintext.test.ts +0 -127
- package/src/resources/stream/snapshot.test.ts +0 -111
- package/src/resources/stream/submit.test.ts +0 -77
- package/src/resources/stream/workflow-event-view.test.ts +0 -116
- package/src/resources/stream/workflow-render.test.ts +0 -81
- package/src/resources/task-configs.test.ts +0 -98
- package/src/resources/usage.test.ts +0 -94
- package/src/resources/validate.test.ts +0 -79
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
// Scenario tests for the snapshot→event differ. Each test drives a sequence of
|
|
2
|
-
// AgentExecution snapshots through a single SnapshotDiffer and asserts the
|
|
3
|
-
// resulting event sequence — the wire-parity contract with Go's streamToEvents.
|
|
4
|
-
|
|
5
|
-
import { create } from "@bufbuild/protobuf";
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
import {
|
|
8
|
-
AgentExecutionSchema,
|
|
9
|
-
AgentExecutionStatusSchema,
|
|
10
|
-
type AgentExecution,
|
|
11
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
12
|
-
import { AgentExecutionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/spec_pb";
|
|
13
|
-
import {
|
|
14
|
-
AgentMessageSchema,
|
|
15
|
-
ToolCallSchema,
|
|
16
|
-
type AgentMessage,
|
|
17
|
-
type ToolCall,
|
|
18
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
19
|
-
import {
|
|
20
|
-
SubAgentExecutionSchema,
|
|
21
|
-
type SubAgentExecution,
|
|
22
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/subagent_pb";
|
|
23
|
-
import { TodoItemSchema, type TodoItem } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/todo_pb";
|
|
24
|
-
import {
|
|
25
|
-
PendingApprovalSchema,
|
|
26
|
-
type PendingApproval,
|
|
27
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
|
|
28
|
-
import {
|
|
29
|
-
ContextInfoSchema,
|
|
30
|
-
SummarizationEventSchema,
|
|
31
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/context_pb";
|
|
32
|
-
import {
|
|
33
|
-
ExecutionPhase,
|
|
34
|
-
MessageType,
|
|
35
|
-
SubAgentStatus,
|
|
36
|
-
ToolCallStatus,
|
|
37
|
-
TodoStatus,
|
|
38
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
39
|
-
import { SnapshotDiffer } from "./diff.js";
|
|
40
|
-
import type { StreamEvent } from "./events.js";
|
|
41
|
-
|
|
42
|
-
// --- Snapshot builders ---------------------------------------------------------
|
|
43
|
-
|
|
44
|
-
interface SnapshotOpts {
|
|
45
|
-
message?: string;
|
|
46
|
-
phase?: ExecutionPhase;
|
|
47
|
-
messages?: AgentMessage[];
|
|
48
|
-
subAgents?: SubAgentExecution[];
|
|
49
|
-
todos?: Record<string, TodoItem>;
|
|
50
|
-
pendingApprovals?: PendingApproval[];
|
|
51
|
-
summarizations?: Array<{ source?: number; tokensBefore?: number; tokensAfter?: number }>;
|
|
52
|
-
error?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function snapshot(opts: SnapshotOpts): AgentExecution {
|
|
56
|
-
const contextInfo =
|
|
57
|
-
opts.summarizations !== undefined
|
|
58
|
-
? create(ContextInfoSchema, {
|
|
59
|
-
summarizationEvents: opts.summarizations.map((s) =>
|
|
60
|
-
create(SummarizationEventSchema, {
|
|
61
|
-
tokensBefore: s.tokensBefore ?? 0,
|
|
62
|
-
tokensAfter: s.tokensAfter ?? 0,
|
|
63
|
-
}),
|
|
64
|
-
),
|
|
65
|
-
})
|
|
66
|
-
: undefined;
|
|
67
|
-
|
|
68
|
-
return create(AgentExecutionSchema, {
|
|
69
|
-
spec: create(AgentExecutionSpecSchema, { message: opts.message ?? "" }),
|
|
70
|
-
status: create(AgentExecutionStatusSchema, {
|
|
71
|
-
phase: opts.phase ?? ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
72
|
-
messages: opts.messages ?? [],
|
|
73
|
-
subAgentExecutions: opts.subAgents ?? [],
|
|
74
|
-
todos: opts.todos ?? {},
|
|
75
|
-
pendingApprovals: opts.pendingApprovals ?? [],
|
|
76
|
-
contextInfo,
|
|
77
|
-
error: opts.error ?? "",
|
|
78
|
-
}),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function aiMsg(content: string, opts: { streaming?: boolean; toolCalls?: ToolCall[] } = {}): AgentMessage {
|
|
83
|
-
return create(AgentMessageSchema, {
|
|
84
|
-
type: MessageType.MESSAGE_AI,
|
|
85
|
-
content,
|
|
86
|
-
isStreaming: opts.streaming ?? false,
|
|
87
|
-
toolCalls: opts.toolCalls ?? [],
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function toolMsg(content: string, toolCalls: ToolCall[]): AgentMessage {
|
|
92
|
-
return create(AgentMessageSchema, { type: MessageType.MESSAGE_TOOL, content, toolCalls });
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function humanMsg(content: string): AgentMessage {
|
|
96
|
-
return create(AgentMessageSchema, { type: MessageType.MESSAGE_HUMAN, content });
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function systemMsg(content: string): AgentMessage {
|
|
100
|
-
return create(AgentMessageSchema, { type: MessageType.MESSAGE_SYSTEM, content });
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function tool(id: string, name: string, status: ToolCallStatus, opts: { result?: string; isStreaming?: boolean } = {}): ToolCall {
|
|
104
|
-
return create(ToolCallSchema, { id, name, status, result: opts.result ?? "", isStreaming: opts.isStreaming ?? false });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function subAgent(
|
|
108
|
-
id: string,
|
|
109
|
-
status: SubAgentStatus,
|
|
110
|
-
opts: { name?: string; subject?: string; input?: string; output?: string; messages?: AgentMessage[] } = {},
|
|
111
|
-
): SubAgentExecution {
|
|
112
|
-
return create(SubAgentExecutionSchema, {
|
|
113
|
-
id,
|
|
114
|
-
status,
|
|
115
|
-
name: opts.name ?? "researcher",
|
|
116
|
-
subject: opts.subject ?? "",
|
|
117
|
-
input: opts.input ?? "",
|
|
118
|
-
output: opts.output ?? "",
|
|
119
|
-
messages: opts.messages ?? [],
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function todo(id: string, content: string, status: TodoStatus): TodoItem {
|
|
124
|
-
return create(TodoItemSchema, { id, content, status });
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function approval(toolCallId: string, toolName: string, message: string): PendingApproval {
|
|
128
|
-
return create(PendingApprovalSchema, { toolCallId, toolName, message });
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Drive a snapshot sequence through one differ; return flattened event kinds.
|
|
132
|
-
function kindsFor(snapshots: AgentExecution[]): string[] {
|
|
133
|
-
const differ = new SnapshotDiffer();
|
|
134
|
-
const out: string[] = [];
|
|
135
|
-
for (const s of snapshots) out.push(...differ.next(s).map((e) => e.kind));
|
|
136
|
-
return out;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Drive a sequence and return the full event objects.
|
|
140
|
-
function eventsFor(snapshots: AgentExecution[]): StreamEvent[] {
|
|
141
|
-
const differ = new SnapshotDiffer();
|
|
142
|
-
const out: StreamEvent[] = [];
|
|
143
|
-
for (const s of snapshots) out.push(...differ.next(s));
|
|
144
|
-
return out;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// --- Tests ---------------------------------------------------------------------
|
|
148
|
-
|
|
149
|
-
describe("human message", () => {
|
|
150
|
-
it("emits once and suppresses the 'execute' placeholder", () => {
|
|
151
|
-
expect(kindsFor([snapshot({ message: "hi" }), snapshot({ message: "hi" })])).toEqual([
|
|
152
|
-
"humanMessage",
|
|
153
|
-
"phaseChange",
|
|
154
|
-
]);
|
|
155
|
-
expect(kindsFor([snapshot({ message: "execute" })])).toEqual(["phaseChange"]);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
describe("AI streaming lifecycle", () => {
|
|
160
|
-
it("start → delta → end across snapshots", () => {
|
|
161
|
-
const seq = [
|
|
162
|
-
snapshot({ messages: [aiMsg("Hel", { streaming: true })] }),
|
|
163
|
-
snapshot({ messages: [aiMsg("Hello", { streaming: true })] }),
|
|
164
|
-
snapshot({ messages: [aiMsg("Hello world", { streaming: false })] }),
|
|
165
|
-
];
|
|
166
|
-
expect(kindsFor(seq)).toEqual(["aiStreamStart", "phaseChange", "aiStreamDelta", "aiStreamEnd"]);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
describe("tool call interleaving", () => {
|
|
171
|
-
it("running tool is an orphan event, completion lands at the tool-message position", () => {
|
|
172
|
-
const seq = [
|
|
173
|
-
snapshot({ messages: [aiMsg("calling", { toolCalls: [tool("t1", "read", ToolCallStatus.TOOL_CALL_RUNNING)] })] }),
|
|
174
|
-
snapshot({
|
|
175
|
-
messages: [
|
|
176
|
-
aiMsg("calling", { toolCalls: [tool("t1", "read", ToolCallStatus.TOOL_CALL_COMPLETED, { result: "data" })] }),
|
|
177
|
-
toolMsg("data", [tool("t1", "read", ToolCallStatus.TOOL_CALL_COMPLETED, { result: "data" })]),
|
|
178
|
-
],
|
|
179
|
-
}),
|
|
180
|
-
];
|
|
181
|
-
expect(kindsFor(seq)).toEqual(["aiMessage", "toolRunning", "phaseChange", "toolCompleted"]);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
it("first-sight terminal tool synthesizes a completion", () => {
|
|
185
|
-
const seq = [
|
|
186
|
-
snapshot({
|
|
187
|
-
messages: [toolMsg("data", [tool("t1", "read", ToolCallStatus.TOOL_CALL_COMPLETED, { result: "data" })])],
|
|
188
|
-
}),
|
|
189
|
-
];
|
|
190
|
-
expect(kindsFor(seq)).toContain("toolCompleted");
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("running → interrupted closes the block with toolInterrupted, not toolCompleted", () => {
|
|
194
|
-
// Issue #207: the platform settles an in-flight call to INTERRUPTED when
|
|
195
|
-
// the execution terminalizes; the live differ must close its running block
|
|
196
|
-
// with the honest event (a checkmark would claim the tool finished).
|
|
197
|
-
const seq = [
|
|
198
|
-
snapshot({ messages: [aiMsg("calling", { toolCalls: [tool("t1", "shell", ToolCallStatus.TOOL_CALL_RUNNING)] })] }),
|
|
199
|
-
snapshot({ messages: [aiMsg("calling", { toolCalls: [tool("t1", "shell", ToolCallStatus.TOOL_CALL_INTERRUPTED)] })] }),
|
|
200
|
-
];
|
|
201
|
-
const kinds = kindsFor(seq);
|
|
202
|
-
expect(kinds).toContain("toolInterrupted");
|
|
203
|
-
expect(kinds).not.toContain("toolCompleted");
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it("first-sight interrupted tool (re-attach) synthesizes toolInterrupted", () => {
|
|
207
|
-
const seq = [
|
|
208
|
-
snapshot({
|
|
209
|
-
messages: [toolMsg("", [tool("t1", "read", ToolCallStatus.TOOL_CALL_INTERRUPTED)])],
|
|
210
|
-
}),
|
|
211
|
-
];
|
|
212
|
-
expect(kindsFor(seq)).toContain("toolInterrupted");
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("emits a streaming delta when a running tool's result grows", () => {
|
|
216
|
-
const seq = [
|
|
217
|
-
snapshot({
|
|
218
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "shell", ToolCallStatus.TOOL_CALL_RUNNING, { isStreaming: true, result: "a" })] })],
|
|
219
|
-
}),
|
|
220
|
-
snapshot({
|
|
221
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "shell", ToolCallStatus.TOOL_CALL_RUNNING, { isStreaming: true, result: "ab" })] })],
|
|
222
|
-
}),
|
|
223
|
-
];
|
|
224
|
-
expect(kindsFor(seq)).toContain("toolStreamDelta");
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
describe("system messages", () => {
|
|
229
|
-
it("sanitizes raw API errors and suppresses approval noise", () => {
|
|
230
|
-
const events = eventsFor([
|
|
231
|
-
snapshot({ messages: [systemMsg('Boom: Error code: 500 - {"type": "error"}'), systemMsg("Approval received: ok")] }),
|
|
232
|
-
]);
|
|
233
|
-
const system = events.filter((e) => e.kind === "systemMessage");
|
|
234
|
-
expect(system).toHaveLength(1);
|
|
235
|
-
expect(system[0].kind === "systemMessage" && system[0].content).toContain("internal error");
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
describe("approval detection", () => {
|
|
240
|
-
it("emits ApprovalNeeded from pending_approvals once", () => {
|
|
241
|
-
const snap = snapshot({
|
|
242
|
-
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
243
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "delete", ToolCallStatus.TOOL_CALL_WAITING_APPROVAL)] })],
|
|
244
|
-
pendingApprovals: [approval("t1", "delete", "Delete repo?")],
|
|
245
|
-
});
|
|
246
|
-
// Same snapshot twice — the dedup set prevents a second prompt.
|
|
247
|
-
const events = eventsFor([snap, snap]);
|
|
248
|
-
const approvals = events.filter((e) => e.kind === "approvalNeeded");
|
|
249
|
-
expect(approvals).toHaveLength(1);
|
|
250
|
-
expect(approvals[0].kind === "approvalNeeded" && approvals[0].toolName).toBe("delete");
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it("defense-in-depth: detects approval via tool status when pending_approvals is empty", () => {
|
|
254
|
-
const snap = snapshot({
|
|
255
|
-
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
256
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "delete", ToolCallStatus.TOOL_CALL_WAITING_APPROVAL)] })],
|
|
257
|
-
pendingApprovals: [],
|
|
258
|
-
});
|
|
259
|
-
expect(kindsFor([snap])).toContain("approvalNeeded");
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it("re-prompts after an approval cycle (IN_PROGRESS → WAITING_FOR_APPROVAL)", () => {
|
|
263
|
-
const waiting = () =>
|
|
264
|
-
snapshot({
|
|
265
|
-
phase: ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL,
|
|
266
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "delete", ToolCallStatus.TOOL_CALL_WAITING_APPROVAL)] })],
|
|
267
|
-
pendingApprovals: [approval("t1", "delete", "Delete?")],
|
|
268
|
-
});
|
|
269
|
-
const running = snapshot({
|
|
270
|
-
phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
|
|
271
|
-
messages: [aiMsg("", { toolCalls: [tool("t1", "delete", ToolCallStatus.TOOL_CALL_RUNNING)] })],
|
|
272
|
-
});
|
|
273
|
-
const events = eventsFor([waiting(), running, waiting()]);
|
|
274
|
-
expect(events.filter((e) => e.kind === "approvalNeeded")).toHaveLength(2);
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
describe("todos", () => {
|
|
279
|
-
it("emits an update only when the fingerprint changes", () => {
|
|
280
|
-
const t = todo("a", "do x", TodoStatus.TODO_PENDING);
|
|
281
|
-
const seq = [
|
|
282
|
-
snapshot({ todos: { a: t } }),
|
|
283
|
-
snapshot({ todos: { a: t } }),
|
|
284
|
-
snapshot({ todos: { a: todo("a", "do x", TodoStatus.TODO_COMPLETED) } }),
|
|
285
|
-
];
|
|
286
|
-
expect(kindsFor(seq).filter((k) => k === "todoUpdate")).toHaveLength(2);
|
|
287
|
-
});
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
describe("context compaction", () => {
|
|
291
|
-
it("emits one event per new summarization entry", () => {
|
|
292
|
-
const seq = [
|
|
293
|
-
snapshot({ summarizations: [{ tokensBefore: 100, tokensAfter: 50 }] }),
|
|
294
|
-
snapshot({ summarizations: [{ tokensBefore: 100, tokensAfter: 50 }, { tokensBefore: 80, tokensAfter: 40 }] }),
|
|
295
|
-
];
|
|
296
|
-
expect(kindsFor(seq).filter((k) => k === "contextCompacted")).toHaveLength(2);
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
describe("sub-agents", () => {
|
|
301
|
-
it("emits started, nested messages, then completed", () => {
|
|
302
|
-
const seq = [
|
|
303
|
-
snapshot({
|
|
304
|
-
subAgents: [subAgent("s1", SubAgentStatus.SUB_AGENT_IN_PROGRESS, { subject: "Explore", messages: [aiMsg("thinking")] })],
|
|
305
|
-
}),
|
|
306
|
-
snapshot({
|
|
307
|
-
subAgents: [
|
|
308
|
-
subAgent("s1", SubAgentStatus.SUB_AGENT_COMPLETED, {
|
|
309
|
-
subject: "Explore",
|
|
310
|
-
output: "done",
|
|
311
|
-
messages: [aiMsg("thinking"), aiMsg("result")],
|
|
312
|
-
}),
|
|
313
|
-
],
|
|
314
|
-
}),
|
|
315
|
-
];
|
|
316
|
-
const events = eventsFor(seq);
|
|
317
|
-
const subKinds = events.filter((e) => ["subAgentStarted", "subAgentCompleted"].includes(e.kind)).map((e) => e.kind);
|
|
318
|
-
expect(subKinds).toEqual(["subAgentStarted", "subAgentCompleted"]);
|
|
319
|
-
const nested = events.filter((e) => e.kind === "aiMessage" && e.subAgentId === "s1");
|
|
320
|
-
expect(nested).toHaveLength(2);
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
describe("terminal", () => {
|
|
325
|
-
it("emits done and ignores all later snapshots", () => {
|
|
326
|
-
const differ = new SnapshotDiffer();
|
|
327
|
-
const first = differ.next(snapshot({ phase: ExecutionPhase.EXECUTION_COMPLETED }));
|
|
328
|
-
expect(first.map((e) => e.kind)).toContain("done");
|
|
329
|
-
const second = differ.next(snapshot({ phase: ExecutionPhase.EXECUTION_COMPLETED }));
|
|
330
|
-
expect(second).toEqual([]);
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
it("carries the error message on failure", () => {
|
|
334
|
-
const events = eventsFor([snapshot({ phase: ExecutionPhase.EXECUTION_FAILED, error: "boom" })]);
|
|
335
|
-
const done = events.find((e) => e.kind === "done");
|
|
336
|
-
expect(done?.kind === "done" && done.error).toBe("boom");
|
|
337
|
-
});
|
|
338
|
-
});
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// Tests for the headless stream driver: terminal result propagation, approval
|
|
2
|
-
// auto-resolution + submission, submit-failure → stream_error, clean abort.
|
|
3
|
-
|
|
4
|
-
import { create } from "@bufbuild/protobuf";
|
|
5
|
-
import { describe, expect, it } from "vitest";
|
|
6
|
-
import { Code, ConnectError } from "@connectrpc/connect";
|
|
7
|
-
import {
|
|
8
|
-
AgentExecutionSchema,
|
|
9
|
-
AgentExecutionStatusSchema,
|
|
10
|
-
type AgentExecution,
|
|
11
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
12
|
-
import { AgentMessageSchema, ToolCallSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
13
|
-
import { PendingApprovalSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
|
|
14
|
-
import {
|
|
15
|
-
ApprovalAction,
|
|
16
|
-
ExecutionPhase,
|
|
17
|
-
MessageType,
|
|
18
|
-
ToolCallStatus,
|
|
19
|
-
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
20
|
-
import type { ApprovalNeededEvent, StreamEvent } from "./events.js";
|
|
21
|
-
import { type HeadlessRenderer, runHeadlessStream } from "./headless.js";
|
|
22
|
-
|
|
23
|
-
function snapshot(phase: ExecutionPhase, opts: { waiting?: boolean } = {}): AgentExecution {
|
|
24
|
-
const toolCalls = opts.waiting
|
|
25
|
-
? [create(ToolCallSchema, { id: "t1", name: "delete", status: ToolCallStatus.TOOL_CALL_WAITING_APPROVAL })]
|
|
26
|
-
: [];
|
|
27
|
-
return create(AgentExecutionSchema, {
|
|
28
|
-
status: create(AgentExecutionStatusSchema, {
|
|
29
|
-
phase,
|
|
30
|
-
messages: [create(AgentMessageSchema, { type: MessageType.MESSAGE_AI, content: "hi", toolCalls })],
|
|
31
|
-
pendingApprovals: opts.waiting ? [create(PendingApprovalSchema, { toolCallId: "t1", toolName: "delete" })] : [],
|
|
32
|
-
}),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function source(snapshots: AgentExecution[]): (signal: AbortSignal) => AsyncIterable<AgentExecution> {
|
|
37
|
-
return async function* (signal: AbortSignal) {
|
|
38
|
-
for (const s of snapshots) {
|
|
39
|
-
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
40
|
-
yield s;
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
class RecordingRenderer implements HeadlessRenderer {
|
|
46
|
-
readonly kinds: string[] = [];
|
|
47
|
-
constructor(private readonly action: ApprovalAction = ApprovalAction.SKIP) {}
|
|
48
|
-
render(event: StreamEvent): void {
|
|
49
|
-
this.kinds.push(event.kind);
|
|
50
|
-
}
|
|
51
|
-
resolveApproval(_event: ApprovalNeededEvent): ApprovalAction {
|
|
52
|
-
return this.action;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
describe("runHeadlessStream", () => {
|
|
57
|
-
it("drives to a terminal done and returns the phase", async () => {
|
|
58
|
-
const renderer = new RecordingRenderer();
|
|
59
|
-
const result = await runHeadlessStream({
|
|
60
|
-
subscribe: source([snapshot(ExecutionPhase.EXECUTION_IN_PROGRESS), snapshot(ExecutionPhase.EXECUTION_COMPLETED)]),
|
|
61
|
-
submitApproval: async () => {},
|
|
62
|
-
renderer,
|
|
63
|
-
sessionId: "ses_1",
|
|
64
|
-
signal: new AbortController().signal,
|
|
65
|
-
});
|
|
66
|
-
expect(result).toEqual({ phase: "completed", error: "" });
|
|
67
|
-
expect(renderer.kinds).toContain("done");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("resolves and submits an approval, then completes", async () => {
|
|
71
|
-
const renderer = new RecordingRenderer(ApprovalAction.SKIP);
|
|
72
|
-
const submitted: Array<{ id: string; action: ApprovalAction }> = [];
|
|
73
|
-
const result = await runHeadlessStream({
|
|
74
|
-
subscribe: source([
|
|
75
|
-
snapshot(ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL, { waiting: true }),
|
|
76
|
-
snapshot(ExecutionPhase.EXECUTION_COMPLETED),
|
|
77
|
-
]),
|
|
78
|
-
submitApproval: async (id, action) => void submitted.push({ id, action }),
|
|
79
|
-
renderer,
|
|
80
|
-
sessionId: "ses_1",
|
|
81
|
-
signal: new AbortController().signal,
|
|
82
|
-
});
|
|
83
|
-
expect(submitted).toEqual([{ id: "t1", action: ApprovalAction.SKIP }]);
|
|
84
|
-
expect(renderer.kinds).toContain("approvalNeeded");
|
|
85
|
-
expect(result.phase).toBe("completed");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("renders a stream_error and stops when submission fails permanently", async () => {
|
|
89
|
-
const renderer = new RecordingRenderer();
|
|
90
|
-
const result = await runHeadlessStream({
|
|
91
|
-
subscribe: source([
|
|
92
|
-
snapshot(ExecutionPhase.EXECUTION_WAITING_FOR_APPROVAL, { waiting: true }),
|
|
93
|
-
snapshot(ExecutionPhase.EXECUTION_COMPLETED),
|
|
94
|
-
]),
|
|
95
|
-
submitApproval: async () => {
|
|
96
|
-
throw new ConnectError("nope", Code.InvalidArgument);
|
|
97
|
-
},
|
|
98
|
-
renderer,
|
|
99
|
-
sessionId: "ses_9",
|
|
100
|
-
signal: new AbortController().signal,
|
|
101
|
-
});
|
|
102
|
-
expect(renderer.kinds).toContain("streamError");
|
|
103
|
-
expect(result.error).toContain("Failed to submit approval");
|
|
104
|
-
expect(result.error).toContain("stigmer resume ses_9");
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("exits cleanly when aborted", async () => {
|
|
108
|
-
const controller = new AbortController();
|
|
109
|
-
controller.abort();
|
|
110
|
-
const result = await runHeadlessStream({
|
|
111
|
-
subscribe: source([snapshot(ExecutionPhase.EXECUTION_IN_PROGRESS)]),
|
|
112
|
-
submitApproval: async () => {},
|
|
113
|
-
renderer: new RecordingRenderer(),
|
|
114
|
-
sessionId: "",
|
|
115
|
-
signal: controller.signal,
|
|
116
|
-
});
|
|
117
|
-
expect(result).toEqual({ phase: "", error: "" });
|
|
118
|
-
});
|
|
119
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// DD-001 boundary guard: React/Ink must load lazily so non-streaming commands
|
|
2
|
-
// and `--help` never pay for them. This codifies the boundary structurally so a
|
|
3
|
-
// regression (a stray static import) fails CI instead of silently slowing every
|
|
4
|
-
// command. The one allowed static importer is ink.tsx, which is itself only ever
|
|
5
|
-
// reached through a dynamic import().
|
|
6
|
-
|
|
7
|
-
import { readFileSync, readdirSync } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
|
-
import { describe, expect, it } from "vitest";
|
|
11
|
-
|
|
12
|
-
const SRC_ROOT = fileURLToPath(new URL("../..", import.meta.url));
|
|
13
|
-
// The only modules allowed to statically import react/ink/@stigmer/ink. Each is
|
|
14
|
-
// itself reached exclusively through a dynamic import() in a command action, so
|
|
15
|
-
// the heavy graph stays out of every non-interactive path (DD-001).
|
|
16
|
-
const INK_MODULES = [
|
|
17
|
-
join(SRC_ROOT, "resources/stream/ink.tsx"),
|
|
18
|
-
join(SRC_ROOT, "resources/picker/ink.tsx"),
|
|
19
|
-
];
|
|
20
|
-
const STATIC_HEAVY_IMPORT = /^\s*import\s+[^;]*?from\s+["'](?:react|ink|@stigmer\/ink)["']/m;
|
|
21
|
-
|
|
22
|
-
function walk(dir: string): string[] {
|
|
23
|
-
const out: string[] = [];
|
|
24
|
-
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
25
|
-
const path = join(dir, entry.name);
|
|
26
|
-
if (entry.isDirectory()) out.push(...walk(path));
|
|
27
|
-
else if (/\.(ts|tsx)$/.test(entry.name)) out.push(path);
|
|
28
|
-
}
|
|
29
|
-
return out;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
describe("lazy-import boundary (DD-001)", () => {
|
|
33
|
-
it("only the lazy Ink entrypoints statically import react/ink/@stigmer/ink", () => {
|
|
34
|
-
const offenders = walk(SRC_ROOT)
|
|
35
|
-
.filter((path) => !INK_MODULES.includes(path))
|
|
36
|
-
.filter((path) => STATIC_HEAVY_IMPORT.test(readFileSync(path, "utf8")));
|
|
37
|
-
expect(offenders).toEqual([]);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("the Ink entrypoints are reached only through dynamic import()", () => {
|
|
41
|
-
const staticImporters = walk(SRC_ROOT).filter((path) => {
|
|
42
|
-
if (INK_MODULES.includes(path)) return false;
|
|
43
|
-
const src = readFileSync(path, "utf8");
|
|
44
|
-
return /^\s*import\s+[^;]*?from\s+["'][^"']*(?:stream|picker)\/ink(?:\.js)?["']/m.test(src);
|
|
45
|
-
});
|
|
46
|
-
expect(staticImporters).toEqual([]);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// The workflow run stream renders over a CLI-local plaintext/NDJSON renderer
|
|
50
|
-
// (no Ink WorkflowView this round), so it must stay out of the React/Ink graph.
|
|
51
|
-
it("workflow-stream.ts has no static react/ink imports", () => {
|
|
52
|
-
const src = readFileSync(join(SRC_ROOT, "resources/run/workflow-stream.ts"), "utf8");
|
|
53
|
-
expect(STATIC_HEAVY_IMPORT.test(src)).toBe(false);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// `connect` renders plaintext only; its command + resources stay Ink-free.
|
|
57
|
-
it("connect command and resources have no static react/ink imports", () => {
|
|
58
|
-
for (const rel of ["commands/connect.ts", "resources/connect/connect.ts", "resources/connect/display.ts"]) {
|
|
59
|
-
const src = readFileSync(join(SRC_ROOT, rel), "utf8");
|
|
60
|
-
expect(STATIC_HEAVY_IMPORT.test(src)).toBe(false);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
});
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
// Golden-line tests for the NDJSON renderer: event type strings, payload shape,
|
|
2
|
-
// and Go-parity payload cleaning (empty strings dropped, false/0 kept).
|
|
3
|
-
|
|
4
|
-
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
|
-
import type { StreamEvent, ToolCallInfo } from "./events.js";
|
|
7
|
-
import { NdjsonRenderer } from "./render-ndjson.js";
|
|
8
|
-
|
|
9
|
-
const FIXED_TS = "2026-01-01T00:00:00.000Z";
|
|
10
|
-
|
|
11
|
-
function buffer(): {
|
|
12
|
-
writer: { write(s: string): void };
|
|
13
|
-
raw: () => string;
|
|
14
|
-
lines: () => Array<Record<string, unknown>>;
|
|
15
|
-
} {
|
|
16
|
-
let raw = "";
|
|
17
|
-
return {
|
|
18
|
-
writer: { write: (s: string) => void (raw += s) },
|
|
19
|
-
raw: () => raw,
|
|
20
|
-
lines: () =>
|
|
21
|
-
raw
|
|
22
|
-
.split("\n")
|
|
23
|
-
.filter((l) => l !== "")
|
|
24
|
-
.map((l) => JSON.parse(l) as Record<string, unknown>),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function renderer(defaultAction = ApprovalAction.SKIP) {
|
|
29
|
-
const data = buffer();
|
|
30
|
-
const status = buffer();
|
|
31
|
-
const r = new NdjsonRenderer({ data: data.writer, status: status.writer, defaultAction, now: () => FIXED_TS });
|
|
32
|
-
return { r, data, status };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function toolInfo(overrides: Partial<ToolCallInfo> = {}): ToolCallInfo {
|
|
36
|
-
return { id: "", name: "read", status: "running", args: undefined, result: "", error: "", durationMs: 0, ...overrides };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function render(events: StreamEvent[], defaultAction = ApprovalAction.SKIP) {
|
|
40
|
-
const ctx = renderer(defaultAction);
|
|
41
|
-
for (const e of events) ctx.r.render(e);
|
|
42
|
-
return ctx;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
describe("envelope", () => {
|
|
46
|
-
it("wraps each event as {type, ts, payload} and strips empty payload fields", () => {
|
|
47
|
-
const { data } = render([{ kind: "aiStreamDelta", content: "", subAgentId: "" }]);
|
|
48
|
-
const [line] = data.lines();
|
|
49
|
-
expect(line.type).toBe("ai_stream_delta");
|
|
50
|
-
expect(line.ts).toBe(FIXED_TS);
|
|
51
|
-
expect(line.payload).toEqual({});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("keeps boolean false and present strings", () => {
|
|
55
|
-
const { data } = render([
|
|
56
|
-
{ kind: "approvalNeeded", toolCallId: "t1", toolName: "delete", argsPreview: "", message: "ok", fromSubAgent: false, subAgentName: "" },
|
|
57
|
-
]);
|
|
58
|
-
const [line] = data.lines();
|
|
59
|
-
expect(line.type).toBe("approval_needed");
|
|
60
|
-
expect(line.payload).toEqual({ tool_call_id: "t1", tool_name: "delete", message: "ok", from_sub_agent: false });
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe("tool events", () => {
|
|
65
|
-
it("emits tool_interrupted as its own wire type (issue #207)", () => {
|
|
66
|
-
const { data } = render([
|
|
67
|
-
{ kind: "toolInterrupted", toolCallId: "t1", subAgentId: "", toolCall: toolInfo({ id: "t1", name: "shell", status: "interrupted" }) },
|
|
68
|
-
]);
|
|
69
|
-
expect(data.lines()[0]).toMatchObject({
|
|
70
|
-
type: "tool_interrupted",
|
|
71
|
-
payload: { tool_call_id: "t1", tool_name: "shell", status: "interrupted" },
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("emits tool_running with only the meaningful fields", () => {
|
|
76
|
-
const { data } = render([
|
|
77
|
-
{ kind: "toolRunning", toolCallId: "t1", subAgentId: "", toolCall: toolInfo({ id: "t1", result: "out", durationMs: 42 }) },
|
|
78
|
-
]);
|
|
79
|
-
expect(data.lines()[0]).toMatchObject({
|
|
80
|
-
type: "tool_running",
|
|
81
|
-
payload: { tool_call_id: "t1", tool_name: "read", status: "running", result: "out", duration_ms: 42 },
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("includes tool_calls in ai_stream_end, omits when empty", () => {
|
|
86
|
-
const { data } = render([
|
|
87
|
-
{ kind: "aiStreamEnd", content: "done", subAgentId: "", toolCalls: [toolInfo({ id: "t1", status: "completed" })] },
|
|
88
|
-
{ kind: "aiMessage", content: "x", subAgentId: "", toolCalls: [] },
|
|
89
|
-
]);
|
|
90
|
-
const [end, msg] = data.lines();
|
|
91
|
-
expect((end.payload as Record<string, unknown>).tool_calls).toEqual([{ name: "read", status: "completed", id: "t1" }]);
|
|
92
|
-
expect((msg.payload as Record<string, unknown>).tool_calls).toBeUndefined();
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
describe("done", () => {
|
|
97
|
-
it("drops an empty error but keeps a present one", () => {
|
|
98
|
-
const { data } = render([
|
|
99
|
-
{ kind: "done", phase: "completed", error: "" },
|
|
100
|
-
{ kind: "done", phase: "failed", error: "boom" },
|
|
101
|
-
]);
|
|
102
|
-
const [ok, fail] = data.lines();
|
|
103
|
-
expect(ok.payload).toEqual({ phase: "completed" });
|
|
104
|
-
expect(fail.payload).toEqual({ phase: "failed", error: "boom" });
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe("approval policy", () => {
|
|
109
|
-
it("honors the configured default action without warning", () => {
|
|
110
|
-
const { r, status } = renderer(ApprovalAction.APPROVE);
|
|
111
|
-
const action = r.resolveApproval({
|
|
112
|
-
kind: "approvalNeeded", toolCallId: "t1", toolName: "delete", argsPreview: "", message: "", fromSubAgent: false, subAgentName: "",
|
|
113
|
-
});
|
|
114
|
-
expect(action).toBe(ApprovalAction.APPROVE);
|
|
115
|
-
expect(status.lines()).toHaveLength(0);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("auto-skips with a stderr warning when no default is set", () => {
|
|
119
|
-
const { r, status } = renderer(ApprovalAction.UNSPECIFIED);
|
|
120
|
-
const action = r.resolveApproval({
|
|
121
|
-
kind: "approvalNeeded", toolCallId: "t1", toolName: "delete", argsPreview: "", message: "", fromSubAgent: false, subAgentName: "",
|
|
122
|
-
});
|
|
123
|
-
expect(action).toBe(ApprovalAction.SKIP);
|
|
124
|
-
expect(status.raw()).toContain("auto-skipping approval for delete");
|
|
125
|
-
});
|
|
126
|
-
});
|