@stigmer/cli 3.35.0 → 3.36.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,383 +0,0 @@
|
|
|
1
|
-
// In-process integration test for `connect mcp-server` orchestration.
|
|
2
|
-
//
|
|
3
|
-
// Stands up a Connect backend serving the McpServer query + command controllers,
|
|
4
|
-
// points an SDK node client at it, and drives connectMcpServer end to end: the
|
|
5
|
-
// push path (asserts ConnectInput fields + rendered capabilities), the OAuth
|
|
6
|
-
// guidance gate, and the dry-run path (local discovery, no Connect RPC).
|
|
7
|
-
|
|
8
|
-
import { create } from "@bufbuild/protobuf";
|
|
9
|
-
import { Code, ConnectError, type ConnectRouter } from "@connectrpc/connect";
|
|
10
|
-
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
11
|
-
import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
12
|
-
import { McpServerCommandController } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/command_pb";
|
|
13
|
-
import {
|
|
14
|
-
type ConnectInput,
|
|
15
|
-
GetOAuthGrantStatusOutputSchema,
|
|
16
|
-
} from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
17
|
-
import { McpServerQueryController } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/query_pb";
|
|
18
|
-
import { McpServerAuthSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/spec_pb";
|
|
19
|
-
import type { Stigmer } from "@stigmer/sdk";
|
|
20
|
-
import { createNodeClient, normalizeEndpoint } from "@stigmer/sdk/node";
|
|
21
|
-
import {
|
|
22
|
-
createServer as createHttp2Server,
|
|
23
|
-
type Http2Server,
|
|
24
|
-
type ServerHttp2Session,
|
|
25
|
-
} from "node:http2";
|
|
26
|
-
import type { AddressInfo } from "node:net";
|
|
27
|
-
import { fileURLToPath } from "node:url";
|
|
28
|
-
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
29
|
-
import { UsageError } from "../../errors/index.js";
|
|
30
|
-
import { connectMcpServer } from "./connect.js";
|
|
31
|
-
import { renderConnectResult } from "./display.js";
|
|
32
|
-
|
|
33
|
-
const FIXTURE = fileURLToPath(
|
|
34
|
-
new URL("./__fixtures__/stdio-server.mjs", import.meta.url),
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
let backend: Http2Server;
|
|
38
|
-
let client: Stigmer;
|
|
39
|
-
const openSessions = new Set<ServerHttp2Session>();
|
|
40
|
-
|
|
41
|
-
let connectCalls: ConnectInput[] = [];
|
|
42
|
-
let grantConnected = false;
|
|
43
|
-
// Delay before the mock Connect RPC answers; lets the --timeout tests
|
|
44
|
-
// simulate a long-running server-side connect. The timer is unref'd so a
|
|
45
|
-
// still-pending delayed response can never hold the test process open.
|
|
46
|
-
let connectDelayMs = 0;
|
|
47
|
-
// The server returned by getByReference; mutated per test for auth scenarios.
|
|
48
|
-
let servedSpec: ReturnType<typeof create<typeof McpServerSchema>>;
|
|
49
|
-
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
connectCalls = [];
|
|
52
|
-
grantConnected = false;
|
|
53
|
-
connectDelayMs = 0;
|
|
54
|
-
servedSpec = create(McpServerSchema, {
|
|
55
|
-
metadata: { id: "mcp_1", name: "github", slug: "github", org: "acme" },
|
|
56
|
-
spec: {
|
|
57
|
-
serverType: {
|
|
58
|
-
case: "stdio",
|
|
59
|
-
value: { command: process.execPath, args: [FIXTURE] },
|
|
60
|
-
},
|
|
61
|
-
env: { GITHUB_TOKEN: { isSecret: true } },
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// The updated server the Connect RPC returns, carrying discovered capabilities.
|
|
67
|
-
const updatedServer = create(McpServerSchema, {
|
|
68
|
-
metadata: { id: "mcp_1", name: "github", slug: "github", org: "acme" },
|
|
69
|
-
spec: { serverType: { case: "stdio", value: { command: "github-mcp" } } },
|
|
70
|
-
status: {
|
|
71
|
-
discoveredCapabilities: {
|
|
72
|
-
tools: [{ name: "search_issues", description: "search issues" }],
|
|
73
|
-
resourceTemplates: [
|
|
74
|
-
{ name: "issue", uriTemplate: "github:///issues/{id}" },
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
beforeAll(async () => {
|
|
81
|
-
const routes = (router: ConnectRouter) => {
|
|
82
|
-
router.service(McpServerQueryController, {
|
|
83
|
-
getByReference: () => servedSpec,
|
|
84
|
-
get: () => servedSpec,
|
|
85
|
-
getOAuthGrantStatus: () =>
|
|
86
|
-
create(GetOAuthGrantStatusOutputSchema, { connected: grantConnected }),
|
|
87
|
-
});
|
|
88
|
-
router.service(McpServerCommandController, {
|
|
89
|
-
// Mirror the backend's protovalidate rule (org min_len=1): reject an empty
|
|
90
|
-
// org so a regression that drops org fails loudly here instead of silently
|
|
91
|
-
// passing (the mock adapter does not run protovalidate on its own).
|
|
92
|
-
connect: async (req) => {
|
|
93
|
-
if (req.org === "")
|
|
94
|
-
throw new ConnectError(
|
|
95
|
-
"org – value length must be at least 1 characters",
|
|
96
|
-
Code.InvalidArgument,
|
|
97
|
-
);
|
|
98
|
-
if (connectDelayMs > 0) {
|
|
99
|
-
await new Promise((resolve) =>
|
|
100
|
-
setTimeout(resolve, connectDelayMs).unref(),
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
connectCalls.push(req);
|
|
104
|
-
return updatedServer;
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
backend = createHttp2Server(connectNodeAdapter({ routes }));
|
|
110
|
-
backend.on("session", (session) => {
|
|
111
|
-
openSessions.add(session);
|
|
112
|
-
session.on("close", () => openSessions.delete(session));
|
|
113
|
-
});
|
|
114
|
-
await new Promise<void>((resolve) => backend.listen(0, "127.0.0.1", resolve));
|
|
115
|
-
const port = (backend.address() as AddressInfo).port;
|
|
116
|
-
client = createNodeClient({
|
|
117
|
-
baseUrl: normalizeEndpoint(`127.0.0.1:${port}`),
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
afterAll(async () => {
|
|
122
|
-
for (const session of openSessions) session.destroy();
|
|
123
|
-
await new Promise<void>((resolve) => backend.close(() => resolve()));
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe("connect push path", () => {
|
|
127
|
-
it("sends ConnectInput with merged runtime env and returns discovered capabilities", async () => {
|
|
128
|
-
const result = await connectMcpServer(client, {
|
|
129
|
-
reference: "github",
|
|
130
|
-
org: "acme",
|
|
131
|
-
timeoutMs: 30_000,
|
|
132
|
-
dryRun: false,
|
|
133
|
-
envOverrides: ["GITHUB_TOKEN=ghp-override"],
|
|
134
|
-
consoleURL: "https://app.stigmer.ai",
|
|
135
|
-
probeLocalConsole: false,
|
|
136
|
-
interactive: false,
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
expect(connectCalls).toHaveLength(1);
|
|
140
|
-
expect(connectCalls[0].mcpServerId).toBe("mcp_1");
|
|
141
|
-
// The org resolved by the command must ride along on ConnectInput — the
|
|
142
|
-
// backend requires it (issue #140: the CLI used to drop it entirely).
|
|
143
|
-
expect(connectCalls[0].org).toBe("acme");
|
|
144
|
-
expect(connectCalls[0].runtimeEnv.GITHUB_TOKEN.value).toBe("ghp-override");
|
|
145
|
-
expect(connectCalls[0].runtimeEnv.GITHUB_TOKEN.isSecret).toBe(true);
|
|
146
|
-
|
|
147
|
-
expect(result.updated?.metadata?.id).toBe("mcp_1");
|
|
148
|
-
expect(result.capabilities?.tools.map((t) => t.name)).toEqual([
|
|
149
|
-
"search_issues",
|
|
150
|
-
]);
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe("--timeout bounds the server-side connect (issue #239)", () => {
|
|
155
|
-
it("stops waiting with actionable guidance when pushTimeoutMs elapses", async () => {
|
|
156
|
-
connectDelayMs = 5_000;
|
|
157
|
-
await expect(
|
|
158
|
-
connectMcpServer(client, {
|
|
159
|
-
reference: "github",
|
|
160
|
-
org: "acme",
|
|
161
|
-
timeoutMs: 30_000,
|
|
162
|
-
pushTimeoutMs: 150,
|
|
163
|
-
dryRun: false,
|
|
164
|
-
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
165
|
-
consoleURL: "https://app.stigmer.ai",
|
|
166
|
-
probeLocalConsole: false,
|
|
167
|
-
interactive: false,
|
|
168
|
-
}),
|
|
169
|
-
).rejects.toThrow(
|
|
170
|
-
/Stopped waiting for the connect of MCP server 'github' after 0\.15s/,
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("does not bound the wait when pushTimeoutMs is unset (default --timeout)", async () => {
|
|
175
|
-
// The flag's 30s default is sized for --dry-run local discovery; a real
|
|
176
|
-
// connect legitimately outlives it, so only an explicit --timeout bounds
|
|
177
|
-
// the push. 200ms of server delay stands in for "longer than the bound
|
|
178
|
-
// would have been".
|
|
179
|
-
connectDelayMs = 200;
|
|
180
|
-
const result = await connectMcpServer(client, {
|
|
181
|
-
reference: "github",
|
|
182
|
-
org: "acme",
|
|
183
|
-
timeoutMs: 100,
|
|
184
|
-
dryRun: false,
|
|
185
|
-
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
186
|
-
consoleURL: "https://app.stigmer.ai",
|
|
187
|
-
probeLocalConsole: false,
|
|
188
|
-
interactive: false,
|
|
189
|
-
});
|
|
190
|
-
expect(result.updated?.metadata?.id).toBe("mcp_1");
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
describe("OAuth guidance gate", () => {
|
|
195
|
-
beforeEach(() => {
|
|
196
|
-
servedSpec.spec!.auth = create(McpServerAuthSchema, {
|
|
197
|
-
targetEnvVar: "GITHUB_TOKEN",
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("stops with actionable guidance when auth is required off an interactive terminal", async () => {
|
|
202
|
-
await expect(
|
|
203
|
-
connectMcpServer(client, {
|
|
204
|
-
reference: "github",
|
|
205
|
-
org: "acme",
|
|
206
|
-
timeoutMs: 30_000,
|
|
207
|
-
dryRun: false,
|
|
208
|
-
envOverrides: [],
|
|
209
|
-
consoleURL: "https://app.stigmer.ai",
|
|
210
|
-
probeLocalConsole: false,
|
|
211
|
-
interactive: false,
|
|
212
|
-
}),
|
|
213
|
-
).rejects.toThrow(UsageError);
|
|
214
|
-
expect(connectCalls).toHaveLength(0);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it("proceeds when an OAuth grant already exists", async () => {
|
|
218
|
-
grantConnected = true;
|
|
219
|
-
await connectMcpServer(client, {
|
|
220
|
-
reference: "github",
|
|
221
|
-
org: "acme",
|
|
222
|
-
timeoutMs: 30_000,
|
|
223
|
-
dryRun: false,
|
|
224
|
-
envOverrides: [],
|
|
225
|
-
consoleURL: "https://app.stigmer.ai",
|
|
226
|
-
probeLocalConsole: false,
|
|
227
|
-
interactive: false,
|
|
228
|
-
});
|
|
229
|
-
expect(connectCalls).toHaveLength(1);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("proceeds when --env credentials are supplied (bypassing OAuth)", async () => {
|
|
233
|
-
await connectMcpServer(client, {
|
|
234
|
-
reference: "github",
|
|
235
|
-
org: "acme",
|
|
236
|
-
timeoutMs: 30_000,
|
|
237
|
-
dryRun: false,
|
|
238
|
-
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
239
|
-
consoleURL: "https://app.stigmer.ai",
|
|
240
|
-
probeLocalConsole: false,
|
|
241
|
-
interactive: false,
|
|
242
|
-
});
|
|
243
|
-
expect(connectCalls).toHaveLength(1);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
describe("oauth_only servers reject the manual-token routes", () => {
|
|
248
|
-
beforeEach(() => {
|
|
249
|
-
servedSpec.spec!.auth = create(McpServerAuthSchema, {
|
|
250
|
-
targetEnvVar: "GITHUB_TOKEN",
|
|
251
|
-
oauthOnly: true,
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it("rejects --env (which cannot satisfy an OAuth-only endpoint) instead of pushing a doomed token", async () => {
|
|
256
|
-
const err = await connectMcpServer(client, {
|
|
257
|
-
reference: "github",
|
|
258
|
-
org: "acme",
|
|
259
|
-
timeoutMs: 30_000,
|
|
260
|
-
dryRun: false,
|
|
261
|
-
envOverrides: ["GITHUB_TOKEN=ghp-x"],
|
|
262
|
-
consoleURL: "https://app.stigmer.ai",
|
|
263
|
-
probeLocalConsole: false,
|
|
264
|
-
interactive: false,
|
|
265
|
-
}).catch((e: unknown) => e);
|
|
266
|
-
|
|
267
|
-
expect(err).toBeInstanceOf(UsageError);
|
|
268
|
-
expect((err as UsageError).message).toMatch(/requires OAuth/i);
|
|
269
|
-
// The guidance must NOT recommend the manual-token route for an oauth_only server.
|
|
270
|
-
expect((err as UsageError).message).not.toContain("--env TOKEN=");
|
|
271
|
-
expect(connectCalls).toHaveLength(0);
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it("omits the --env suggestion from the non-interactive OAuth guidance", async () => {
|
|
275
|
-
const err = await connectMcpServer(client, {
|
|
276
|
-
reference: "github",
|
|
277
|
-
org: "acme",
|
|
278
|
-
timeoutMs: 30_000,
|
|
279
|
-
dryRun: false,
|
|
280
|
-
envOverrides: [],
|
|
281
|
-
consoleURL: "https://app.stigmer.ai",
|
|
282
|
-
probeLocalConsole: false,
|
|
283
|
-
interactive: false,
|
|
284
|
-
}).catch((e: unknown) => e);
|
|
285
|
-
|
|
286
|
-
expect(err).toBeInstanceOf(UsageError);
|
|
287
|
-
expect((err as UsageError).message).not.toContain("--env TOKEN=");
|
|
288
|
-
expect(connectCalls).toHaveLength(0);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it("refuses --dry-run local discovery (no locally-obtainable OAuth token) with a clear message", async () => {
|
|
292
|
-
const err = await connectMcpServer(client, {
|
|
293
|
-
reference: "github",
|
|
294
|
-
org: "acme",
|
|
295
|
-
timeoutMs: 10_000,
|
|
296
|
-
dryRun: true,
|
|
297
|
-
envOverrides: [],
|
|
298
|
-
consoleURL: "https://app.stigmer.ai",
|
|
299
|
-
probeLocalConsole: false,
|
|
300
|
-
interactive: false,
|
|
301
|
-
}).catch((e: unknown) => e);
|
|
302
|
-
|
|
303
|
-
expect(err).toBeInstanceOf(UsageError);
|
|
304
|
-
expect((err as UsageError).message).toMatch(/requires OAuth/i);
|
|
305
|
-
expect((err as UsageError).message).toContain("--dry-run");
|
|
306
|
-
expect(connectCalls).toHaveLength(0);
|
|
307
|
-
});
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
describe("dry-run path", () => {
|
|
311
|
-
it("discovers locally and never calls the Connect RPC", async () => {
|
|
312
|
-
const result = await connectMcpServer(client, {
|
|
313
|
-
reference: "github",
|
|
314
|
-
org: "acme",
|
|
315
|
-
timeoutMs: 10_000,
|
|
316
|
-
dryRun: true,
|
|
317
|
-
envOverrides: [],
|
|
318
|
-
consoleURL: "https://app.stigmer.ai",
|
|
319
|
-
probeLocalConsole: false,
|
|
320
|
-
interactive: false,
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
expect(connectCalls).toHaveLength(0);
|
|
324
|
-
expect(result.updated).toBeUndefined();
|
|
325
|
-
expect(result.capabilities?.tools.map((t) => t.name)).toEqual([
|
|
326
|
-
"echo",
|
|
327
|
-
"noop",
|
|
328
|
-
]);
|
|
329
|
-
|
|
330
|
-
const lines: string[] = [];
|
|
331
|
-
renderConnectResult(result, (l) => lines.push(l), false);
|
|
332
|
-
const text = lines.join("\n");
|
|
333
|
-
expect(text).toContain("MCP Server: acme/github");
|
|
334
|
-
expect(text).toContain("Transport: stdio");
|
|
335
|
-
expect(text).toContain("Tools (2):");
|
|
336
|
-
expect(text).toContain("Dry run — results not saved");
|
|
337
|
-
}, 15_000);
|
|
338
|
-
|
|
339
|
-
it("maps an unresolved ${VAR} arg to actionable guidance and never calls Connect", async () => {
|
|
340
|
-
// Server references a declared env var in its args, but it is not set.
|
|
341
|
-
delete process.env.NEEDED_DIR;
|
|
342
|
-
servedSpec = create(McpServerSchema, {
|
|
343
|
-
metadata: {
|
|
344
|
-
id: "mcp_1",
|
|
345
|
-
name: "filesystem",
|
|
346
|
-
slug: "filesystem",
|
|
347
|
-
org: "acme",
|
|
348
|
-
},
|
|
349
|
-
spec: {
|
|
350
|
-
serverType: {
|
|
351
|
-
case: "stdio",
|
|
352
|
-
value: {
|
|
353
|
-
command: process.execPath,
|
|
354
|
-
args: [FIXTURE, "${NEEDED_DIR}"],
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
env: {
|
|
358
|
-
NEEDED_DIR: {
|
|
359
|
-
isSecret: false,
|
|
360
|
-
description: "Root directory the server may access",
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
},
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
const err = await connectMcpServer(client, {
|
|
367
|
-
reference: "filesystem",
|
|
368
|
-
org: "acme",
|
|
369
|
-
timeoutMs: 10_000,
|
|
370
|
-
dryRun: true,
|
|
371
|
-
envOverrides: [],
|
|
372
|
-
consoleURL: "https://app.stigmer.ai",
|
|
373
|
-
probeLocalConsole: false,
|
|
374
|
-
interactive: false,
|
|
375
|
-
}).catch((e: unknown) => e);
|
|
376
|
-
|
|
377
|
-
expect(err).toBeInstanceOf(UsageError);
|
|
378
|
-
const message = (err as UsageError).message;
|
|
379
|
-
expect(message).toContain("NEEDED_DIR");
|
|
380
|
-
expect(message).toContain("--env");
|
|
381
|
-
expect(connectCalls).toHaveLength(0);
|
|
382
|
-
}, 15_000);
|
|
383
|
-
});
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// Local discovery tests over a real stdio MCP subprocess fixture.
|
|
2
|
-
//
|
|
3
|
-
// Spawns the fixture server (node __fixtures__/stdio-server.mjs), connects via
|
|
4
|
-
// the MCP SDK, and asserts the discovered tools + resource templates convert to
|
|
5
|
-
// the DiscoveredCapabilities proto and render correctly. Also asserts a crashing
|
|
6
|
-
// subprocess surfaces its stderr instead of hanging.
|
|
7
|
-
|
|
8
|
-
import { create } from "@bufbuild/protobuf";
|
|
9
|
-
import { McpServerSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/spec_pb";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
-
import { afterEach, describe, expect, it } from "vitest";
|
|
12
|
-
import { localDiscover } from "./discover.js";
|
|
13
|
-
import { PlaceholderResolutionError } from "../mcp/placeholder-resolver.js";
|
|
14
|
-
|
|
15
|
-
const FIXTURE = fileURLToPath(new URL("./__fixtures__/stdio-server.mjs", import.meta.url));
|
|
16
|
-
const CRASH_FIXTURE = fileURLToPath(new URL("./__fixtures__/stdio-crash.mjs", import.meta.url));
|
|
17
|
-
|
|
18
|
-
function stdioSpec(scriptPath: string) {
|
|
19
|
-
return create(McpServerSpecSchema, {
|
|
20
|
-
serverType: { case: "stdio", value: { command: process.execPath, args: [scriptPath] } },
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// A spec whose args reference ${ALLOWED_DIR}, declared under spec.env — the shape
|
|
25
|
-
// a filesystem MCP server declares its root with (issue #141).
|
|
26
|
-
function stdioSpecWithPlaceholderArg(scriptPath: string) {
|
|
27
|
-
return create(McpServerSpecSchema, {
|
|
28
|
-
serverType: { case: "stdio", value: { command: process.execPath, args: [scriptPath, "${ALLOWED_DIR}"] } },
|
|
29
|
-
env: { ALLOWED_DIR: { isSecret: false, description: "Directory the server may access" } },
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe("localDiscover (stdio subprocess)", () => {
|
|
34
|
-
it("discovers tools and resource templates and converts them to proto", async () => {
|
|
35
|
-
const caps = await localDiscover(stdioSpec(FIXTURE), [], 10_000);
|
|
36
|
-
|
|
37
|
-
expect(caps.tools.map((t) => t.name)).toEqual(["echo", "noop"]);
|
|
38
|
-
expect(caps.tools[0].description).toContain("token=unset");
|
|
39
|
-
expect(caps.tools[0].inputSchema).toBeDefined();
|
|
40
|
-
|
|
41
|
-
expect(caps.resourceTemplates).toHaveLength(1);
|
|
42
|
-
expect(caps.resourceTemplates[0].uriTemplate).toBe("file:///{path}");
|
|
43
|
-
expect(caps.resourceTemplates[0].name).toBe("local-file");
|
|
44
|
-
expect(caps.resourceTemplates[0].mimeType).toBe("text/plain");
|
|
45
|
-
}, 15_000);
|
|
46
|
-
|
|
47
|
-
it("propagates --env overrides into the spawned subprocess", async () => {
|
|
48
|
-
const caps = await localDiscover(stdioSpec(FIXTURE), ["FIXTURE_TOKEN=secret-123"], 10_000);
|
|
49
|
-
expect(caps.tools[0].description).toContain("token=secret-123");
|
|
50
|
-
}, 15_000);
|
|
51
|
-
|
|
52
|
-
it("surfaces subprocess stderr when the server crashes on startup", async () => {
|
|
53
|
-
await expect(localDiscover(stdioSpec(CRASH_FIXTURE), [], 10_000)).rejects.toThrow(/fixture boom: missing CONFIG/);
|
|
54
|
-
}, 15_000);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe("localDiscover (${VAR} argument expansion — issue #141)", () => {
|
|
58
|
-
const original = process.env;
|
|
59
|
-
afterEach(() => {
|
|
60
|
-
process.env = original;
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("expands a declared ${VAR} arg from --env into the spawned subprocess", async () => {
|
|
64
|
-
const caps = await localDiscover(stdioSpecWithPlaceholderArg(FIXTURE), ["ALLOWED_DIR=/tmp/allowed"], 10_000);
|
|
65
|
-
// The fixture echoes the argv it actually received; the resolved value must
|
|
66
|
-
// reach the subprocess, never the literal placeholder.
|
|
67
|
-
expect(caps.tools[0].description).toContain('args=["/tmp/allowed"]');
|
|
68
|
-
expect(caps.tools[0].description).not.toContain("${ALLOWED_DIR}");
|
|
69
|
-
}, 15_000);
|
|
70
|
-
|
|
71
|
-
it("expands a declared ${VAR} arg from the exported shell environment", async () => {
|
|
72
|
-
process.env = { ...original, ALLOWED_DIR: "/tmp/from-shell" };
|
|
73
|
-
const caps = await localDiscover(stdioSpecWithPlaceholderArg(FIXTURE), [], 10_000);
|
|
74
|
-
expect(caps.tools[0].description).toContain('args=["/tmp/from-shell"]');
|
|
75
|
-
}, 15_000);
|
|
76
|
-
|
|
77
|
-
it("rejects with a placeholder error before spawning when the declared var is unset", async () => {
|
|
78
|
-
process.env = { ...original };
|
|
79
|
-
delete process.env.ALLOWED_DIR;
|
|
80
|
-
await expect(localDiscover(stdioSpecWithPlaceholderArg(FIXTURE), [], 10_000)).rejects.toBeInstanceOf(
|
|
81
|
-
PlaceholderResolutionError,
|
|
82
|
-
);
|
|
83
|
-
}, 15_000);
|
|
84
|
-
});
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { create } from "@bufbuild/protobuf";
|
|
2
|
-
import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
3
|
-
import type { Stigmer } from "@stigmer/sdk";
|
|
4
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
5
|
-
import { UsageError } from "../../errors/index.js";
|
|
6
|
-
import {
|
|
7
|
-
browserCommand,
|
|
8
|
-
runOAuthFlow,
|
|
9
|
-
waitForOAuthGrant,
|
|
10
|
-
type OAuthFlowDeps,
|
|
11
|
-
} from "./oauth.js";
|
|
12
|
-
|
|
13
|
-
const server = create(McpServerSchema, {
|
|
14
|
-
metadata: { id: "mcp_1", slug: "github", name: "GitHub" },
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// A fake client whose getOAuthGrantStatus reports `connected` once the call
|
|
18
|
-
// count reaches `connectOnCall` (1 = first poll). Records the call count.
|
|
19
|
-
function fakeClient(connectOnCall: number): {
|
|
20
|
-
client: Stigmer;
|
|
21
|
-
calls: () => number;
|
|
22
|
-
} {
|
|
23
|
-
let calls = 0;
|
|
24
|
-
const client = {
|
|
25
|
-
mcpServer: {
|
|
26
|
-
getOAuthGrantStatus: async () => {
|
|
27
|
-
calls += 1;
|
|
28
|
-
return { connected: calls >= connectOnCall };
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
} as unknown as Stigmer;
|
|
32
|
-
return { client, calls: () => calls };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const noopSleep = async (): Promise<void> => {};
|
|
36
|
-
|
|
37
|
-
describe("browserCommand", () => {
|
|
38
|
-
it("maps each supported platform to its opener", () => {
|
|
39
|
-
expect(browserCommand("darwin", "https://x")).toEqual([
|
|
40
|
-
"open",
|
|
41
|
-
["https://x"],
|
|
42
|
-
]);
|
|
43
|
-
expect(browserCommand("linux", "https://x")).toEqual([
|
|
44
|
-
"xdg-open",
|
|
45
|
-
["https://x"],
|
|
46
|
-
]);
|
|
47
|
-
expect(browserCommand("win32", "https://x")).toEqual([
|
|
48
|
-
"rundll32",
|
|
49
|
-
["url.dll,FileProtocolHandler", "https://x"],
|
|
50
|
-
]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("returns no command for unsupported platforms", () => {
|
|
54
|
-
expect(browserCommand("aix", "https://x")[0]).toBeUndefined();
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe("waitForOAuthGrant", () => {
|
|
59
|
-
it("resolves once the grant connects on a later poll", async () => {
|
|
60
|
-
const { client, calls } = fakeClient(3);
|
|
61
|
-
const deps: OAuthFlowDeps = {
|
|
62
|
-
client,
|
|
63
|
-
server,
|
|
64
|
-
org: "acme",
|
|
65
|
-
consoleURL: "https://app.stigmer.ai",
|
|
66
|
-
probeLocalConsole: false,
|
|
67
|
-
now: () => 0,
|
|
68
|
-
sleep: noopSleep,
|
|
69
|
-
log: () => {},
|
|
70
|
-
};
|
|
71
|
-
await expect(waitForOAuthGrant(deps)).resolves.toBeUndefined();
|
|
72
|
-
expect(calls()).toBe(3);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("throws a UsageError when the poll window elapses", async () => {
|
|
76
|
-
const { client, calls } = fakeClient(Number.POSITIVE_INFINITY);
|
|
77
|
-
// First now() seeds the deadline; the next jumps past it to force a timeout
|
|
78
|
-
// before any grant check runs.
|
|
79
|
-
const clock = [0, 10 * 60 * 1000];
|
|
80
|
-
const deps: OAuthFlowDeps = {
|
|
81
|
-
client,
|
|
82
|
-
server,
|
|
83
|
-
org: "acme",
|
|
84
|
-
consoleURL: "https://app.stigmer.ai",
|
|
85
|
-
probeLocalConsole: false,
|
|
86
|
-
now: () => clock.shift() ?? 10 * 60 * 1000,
|
|
87
|
-
sleep: noopSleep,
|
|
88
|
-
log: () => {},
|
|
89
|
-
};
|
|
90
|
-
await expect(waitForOAuthGrant(deps)).rejects.toThrow(UsageError);
|
|
91
|
-
expect(calls()).toBe(0);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe("runOAuthFlow", () => {
|
|
96
|
-
afterEach(() => {
|
|
97
|
-
vi.restoreAllMocks();
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("opens the org's MCP-server page then waits for the grant", async () => {
|
|
101
|
-
const { client } = fakeClient(1);
|
|
102
|
-
const openBrowser = vi.fn(async () => {});
|
|
103
|
-
await runOAuthFlow({
|
|
104
|
-
client,
|
|
105
|
-
server,
|
|
106
|
-
org: "acme",
|
|
107
|
-
consoleURL: "https://app.stigmer.ai",
|
|
108
|
-
probeLocalConsole: false,
|
|
109
|
-
openBrowser,
|
|
110
|
-
now: () => 0,
|
|
111
|
-
sleep: noopSleep,
|
|
112
|
-
log: () => {},
|
|
113
|
-
});
|
|
114
|
-
expect(openBrowser).toHaveBeenCalledWith(
|
|
115
|
-
"https://app.stigmer.ai/library/mcp-servers/acme/github",
|
|
116
|
-
);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it("aborts before opening the browser when the local console is unreachable", async () => {
|
|
120
|
-
const { client } = fakeClient(1);
|
|
121
|
-
const openBrowser = vi.fn(async () => {});
|
|
122
|
-
await expect(
|
|
123
|
-
runOAuthFlow({
|
|
124
|
-
client,
|
|
125
|
-
server,
|
|
126
|
-
org: "acme",
|
|
127
|
-
consoleURL: "http://localhost:7234",
|
|
128
|
-
probeLocalConsole: true,
|
|
129
|
-
probeConsole: async () => false,
|
|
130
|
-
openBrowser,
|
|
131
|
-
now: () => 0,
|
|
132
|
-
sleep: noopSleep,
|
|
133
|
-
log: () => {},
|
|
134
|
-
}),
|
|
135
|
-
).rejects.toThrow(UsageError);
|
|
136
|
-
expect(openBrowser).not.toHaveBeenCalled();
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it("opens the local console page when the probe succeeds", async () => {
|
|
140
|
-
const { client } = fakeClient(1);
|
|
141
|
-
const openBrowser = vi.fn(async () => {});
|
|
142
|
-
await runOAuthFlow({
|
|
143
|
-
client,
|
|
144
|
-
server,
|
|
145
|
-
org: "acme",
|
|
146
|
-
consoleURL: "http://localhost:7234",
|
|
147
|
-
probeLocalConsole: true,
|
|
148
|
-
probeConsole: async () => true,
|
|
149
|
-
openBrowser,
|
|
150
|
-
now: () => 0,
|
|
151
|
-
sleep: noopSleep,
|
|
152
|
-
log: () => {},
|
|
153
|
-
});
|
|
154
|
-
expect(openBrowser).toHaveBeenCalledWith(
|
|
155
|
-
"http://localhost:7234/library/mcp-servers/acme/github",
|
|
156
|
-
);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Pins readCursorPages, the walk behind `list session` and `list executions`:
|
|
2
|
-
// a --limit above the server's page cap takes several reads, a short page
|
|
3
|
-
// that still carries a token is followed, each read asks only for what is
|
|
4
|
-
// missing, and a limit of zero is one whole-list request.
|
|
5
|
-
import { describe, expect, it } from "vitest";
|
|
6
|
-
import { type CursorPage, readCursorPages } from "./cursor-pages.js";
|
|
7
|
-
|
|
8
|
-
const SERVER_CAP = 100;
|
|
9
|
-
|
|
10
|
-
// A server over `total` rows that caps pages and answers `short` rows on
|
|
11
|
-
// the page whose token is listed there (a scope refusing most of a batch).
|
|
12
|
-
function fakeServer(total: number, short: ReadonlyMap<string, number> = new Map()) {
|
|
13
|
-
const asked: Array<{ pageSize: number; pageToken: string }> = [];
|
|
14
|
-
const read = async (pageSize: number, pageToken: string): Promise<CursorPage<number>> => {
|
|
15
|
-
asked.push({ pageSize, pageToken });
|
|
16
|
-
const start = pageToken === "" ? 0 : Number(pageToken);
|
|
17
|
-
if (pageSize === 0) return { entries: range(start, total), nextPageToken: "" };
|
|
18
|
-
const size = Math.min(pageSize, SERVER_CAP, short.get(pageToken) ?? Number.POSITIVE_INFINITY);
|
|
19
|
-
const end = Math.min(start + size, total);
|
|
20
|
-
return { entries: range(start, end), nextPageToken: end < total ? String(end) : "" };
|
|
21
|
-
};
|
|
22
|
-
return { read, asked };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function range(from: number, to: number): number[] {
|
|
26
|
-
return Array.from({ length: Math.max(0, to - from) }, (_, i) => from + i);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe("readCursorPages", () => {
|
|
30
|
-
it("reads past the server's page cap until the limit is met", async () => {
|
|
31
|
-
const server = fakeServer(500);
|
|
32
|
-
const rows = await readCursorPages(250, server.read);
|
|
33
|
-
expect(rows).toEqual(range(0, 250));
|
|
34
|
-
expect(server.asked.map((a) => a.pageSize)).toEqual([250, 150, 50]);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("follows a short page that carries a token", async () => {
|
|
38
|
-
const server = fakeServer(30, new Map([["", 0], ["0", 4]]));
|
|
39
|
-
const rows = await readCursorPages(10, server.read);
|
|
40
|
-
expect(rows).toEqual(range(0, 10));
|
|
41
|
-
expect(server.asked).toHaveLength(3);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("stops when the list ends before the limit", async () => {
|
|
45
|
-
const server = fakeServer(7);
|
|
46
|
-
expect(await readCursorPages(50, server.read)).toEqual(range(0, 7));
|
|
47
|
-
expect(server.asked).toHaveLength(1);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("sends one page_size 0 request for a limit of zero", async () => {
|
|
51
|
-
const server = fakeServer(150);
|
|
52
|
-
expect(await readCursorPages(0, server.read)).toHaveLength(150);
|
|
53
|
-
expect(server.asked).toEqual([{ pageSize: 0, pageToken: "" }]);
|
|
54
|
-
});
|
|
55
|
-
});
|