@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,96 +0,0 @@
|
|
|
1
|
-
// Unit tests for `stigmer auth whoami`'s result (commands/auth/whoami.ts;
|
|
2
|
-
// 20260911.11 A3): the command runs the SDK's ensureMyIdentityAccount — the
|
|
3
|
-
// same first-sign-in flow the console runs — and RENDERS what it learned.
|
|
4
|
-
// whoamiResult is the pure half: given the account and whether this call
|
|
5
|
-
// created it, the CommandResult a person reads. A first sign-in says so
|
|
6
|
-
// (visibility of system status); a missing organization is a hint, not a
|
|
7
|
-
// failure; an empty profile (the unconfigured laptop's operator) renders
|
|
8
|
-
// only the fields it has. Accounts are built with the generated schema
|
|
9
|
-
// (DD-007: the generated type is the contract; refinement 12, slice 4).
|
|
10
|
-
|
|
11
|
-
import { create } from "@bufbuild/protobuf";
|
|
12
|
-
import { IdentityAccountSchema } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
|
|
13
|
-
import { describe, expect, it } from "vitest";
|
|
14
|
-
|
|
15
|
-
import { whoamiResult } from "./whoami.js";
|
|
16
|
-
|
|
17
|
-
const ALICE = {
|
|
18
|
-
metadata: { id: "ida_wtr3jcf281yfk9xx61kj59fsme", name: "alice@example.com" },
|
|
19
|
-
spec: {
|
|
20
|
-
idpId: "auth0|alice",
|
|
21
|
-
email: "alice@example.com",
|
|
22
|
-
firstName: "Alice",
|
|
23
|
-
lastName: "Liddell",
|
|
24
|
-
isMachineAccount: false,
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
const ACCOUNT = create(IdentityAccountSchema, ALICE);
|
|
28
|
-
|
|
29
|
-
function fields(
|
|
30
|
-
result: ReturnType<typeof whoamiResult>,
|
|
31
|
-
): Record<string, string> {
|
|
32
|
-
return Object.fromEntries(
|
|
33
|
-
result.sections.flatMap((s) => s.fields.map((f) => [f.key, f.value])),
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
describe("whoamiResult", () => {
|
|
38
|
-
it("renders an existing account as 'Authenticated' with its identity fields", () => {
|
|
39
|
-
const result = whoamiResult(ACCOUNT, { created: false, org: "acme" });
|
|
40
|
-
expect(result.status).toBe("success");
|
|
41
|
-
expect(result.message).toBe("Authenticated");
|
|
42
|
-
expect(fields(result)).toEqual({
|
|
43
|
-
"Account ID": "ida_wtr3jcf281yfk9xx61kj59fsme",
|
|
44
|
-
Name: "alice@example.com",
|
|
45
|
-
Email: "alice@example.com",
|
|
46
|
-
"Full Name": "Alice Liddell",
|
|
47
|
-
"Account Type": "User Account",
|
|
48
|
-
Organization: "acme",
|
|
49
|
-
});
|
|
50
|
-
expect(result.hints).toEqual([]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("says so when this call created the account — the first sign-in is visible, never silent", () => {
|
|
54
|
-
const result = whoamiResult(ACCOUNT, { created: true, org: "acme" });
|
|
55
|
-
expect(result.status).toBe("success");
|
|
56
|
-
expect(result.message).toBe(
|
|
57
|
-
"Authenticated — your account was created on this first sign-in",
|
|
58
|
-
);
|
|
59
|
-
expect(fields(result)["Account ID"]).toBe("ida_wtr3jcf281yfk9xx61kj59fsme");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("a missing organization is a hint with the command that sets it", () => {
|
|
63
|
-
const result = whoamiResult(ACCOUNT, { created: false, org: "" });
|
|
64
|
-
expect(fields(result).Organization).toBeUndefined();
|
|
65
|
-
expect(result.hints).toEqual([
|
|
66
|
-
"No organization set. Use: stigmer config context set --org <slug>",
|
|
67
|
-
]);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("renders only the fields an empty profile has (the unconfigured laptop's operator)", () => {
|
|
71
|
-
const result = whoamiResult(
|
|
72
|
-
create(IdentityAccountSchema, {
|
|
73
|
-
metadata: { id: "ida_fn0zdvkkkhhrb4wry43zba8gnn", name: "system" },
|
|
74
|
-
spec: { idpId: "local|system" },
|
|
75
|
-
}),
|
|
76
|
-
{ created: false, org: "local" },
|
|
77
|
-
);
|
|
78
|
-
expect(fields(result)).toEqual({
|
|
79
|
-
"Account ID": "ida_fn0zdvkkkhhrb4wry43zba8gnn",
|
|
80
|
-
Name: "system",
|
|
81
|
-
"Account Type": "User Account",
|
|
82
|
-
Organization: "local",
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("names a machine account", () => {
|
|
87
|
-
const result = whoamiResult(
|
|
88
|
-
create(IdentityAccountSchema, {
|
|
89
|
-
...ALICE,
|
|
90
|
-
spec: { ...ALICE.spec, isMachineAccount: true },
|
|
91
|
-
}),
|
|
92
|
-
{ created: false, org: "acme" },
|
|
93
|
-
);
|
|
94
|
-
expect(fields(result)["Account Type"]).toBe("Machine Account");
|
|
95
|
-
});
|
|
96
|
-
});
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
// Command-level contract for `stigmer bootstrap`: against the configured
|
|
2
|
-
// backend it ensures the organization the CLI falls back to (`stigmer`) and
|
|
3
|
-
// installs nothing, so the command creates the organization and renders one
|
|
4
|
-
// Organization section; a second run over a ready backend reports the org
|
|
5
|
-
// present and creates nothing. A real Connect backend over h2c serves the org
|
|
6
|
-
// controllers; the config file (HOME redirected) points a selfhost backend at
|
|
7
|
-
// it.
|
|
8
|
-
|
|
9
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
10
|
-
import {
|
|
11
|
-
createServer as createHttp2Server,
|
|
12
|
-
type Http2Server,
|
|
13
|
-
type ServerHttp2Session,
|
|
14
|
-
} from "node:http2";
|
|
15
|
-
import type { AddressInfo } from "node:net";
|
|
16
|
-
import { tmpdir } from "node:os";
|
|
17
|
-
import { join } from "node:path";
|
|
18
|
-
import { create } from "@bufbuild/protobuf";
|
|
19
|
-
import type { ConnectRouter } from "@connectrpc/connect";
|
|
20
|
-
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
21
|
-
import {
|
|
22
|
-
type Organization,
|
|
23
|
-
OrganizationSchema,
|
|
24
|
-
} from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
25
|
-
import { OrganizationCommandController } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/command_pb";
|
|
26
|
-
import { OrganizationsSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/io_pb";
|
|
27
|
-
import { OrganizationQueryController } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/query_pb";
|
|
28
|
-
import {
|
|
29
|
-
afterAll,
|
|
30
|
-
afterEach,
|
|
31
|
-
beforeAll,
|
|
32
|
-
beforeEach,
|
|
33
|
-
describe,
|
|
34
|
-
expect,
|
|
35
|
-
it,
|
|
36
|
-
vi,
|
|
37
|
-
} from "vitest";
|
|
38
|
-
import { DEFAULT_LOCAL_ORG } from "../config/index.js";
|
|
39
|
-
import { classify, ExitCode } from "../errors/index.js";
|
|
40
|
-
import { buildProgram } from "../program.js";
|
|
41
|
-
|
|
42
|
-
let backend: Http2Server;
|
|
43
|
-
let port: number;
|
|
44
|
-
const openSessions = new Set<ServerHttp2Session>();
|
|
45
|
-
|
|
46
|
-
let orgs: Map<string, Organization>;
|
|
47
|
-
let creates: number;
|
|
48
|
-
|
|
49
|
-
let home: string;
|
|
50
|
-
let originalHome: string | undefined;
|
|
51
|
-
|
|
52
|
-
beforeAll(async () => {
|
|
53
|
-
const routes = (router: ConnectRouter) => {
|
|
54
|
-
router.service(OrganizationQueryController, {
|
|
55
|
-
findMyOrganizations: () =>
|
|
56
|
-
create(OrganizationsSchema, { entries: [...orgs.values()] }),
|
|
57
|
-
});
|
|
58
|
-
router.service(OrganizationCommandController, {
|
|
59
|
-
create: (org) => {
|
|
60
|
-
creates += 1;
|
|
61
|
-
const row = create(OrganizationSchema, org);
|
|
62
|
-
if (row.metadata !== undefined) row.metadata.id = "org_1";
|
|
63
|
-
orgs.set(row.metadata?.slug ?? "", row);
|
|
64
|
-
return row;
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
};
|
|
68
|
-
backend = createHttp2Server(connectNodeAdapter({ routes }));
|
|
69
|
-
backend.on("session", (session) => {
|
|
70
|
-
openSessions.add(session);
|
|
71
|
-
session.on("close", () => openSessions.delete(session));
|
|
72
|
-
});
|
|
73
|
-
await new Promise<void>((resolve) => backend.listen(0, "127.0.0.1", resolve));
|
|
74
|
-
port = (backend.address() as AddressInfo).port;
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
afterAll(async () => {
|
|
78
|
-
for (const session of openSessions) session.destroy();
|
|
79
|
-
await new Promise<void>((resolve) => backend.close(() => resolve()));
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
beforeEach(() => {
|
|
83
|
-
orgs = new Map();
|
|
84
|
-
creates = 0;
|
|
85
|
-
originalHome = process.env.HOME;
|
|
86
|
-
home = mkdtempSync(join(tmpdir(), "stigmer-bootstrap-cmd-"));
|
|
87
|
-
process.env.HOME = home;
|
|
88
|
-
mkdirSync(join(home, ".stigmer"), { recursive: true });
|
|
89
|
-
writeFileSync(
|
|
90
|
-
join(home, ".stigmer", "config.yaml"),
|
|
91
|
-
[
|
|
92
|
-
"backend:",
|
|
93
|
-
" type: cloud",
|
|
94
|
-
"backends:",
|
|
95
|
-
" test:",
|
|
96
|
-
" type: selfhost",
|
|
97
|
-
` endpoint: 127.0.0.1:${port}`,
|
|
98
|
-
"current_backend: test",
|
|
99
|
-
"",
|
|
100
|
-
].join("\n"),
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
afterEach(() => {
|
|
105
|
-
if (originalHome === undefined) delete process.env.HOME;
|
|
106
|
-
else process.env.HOME = originalHome;
|
|
107
|
-
rmSync(home, { recursive: true, force: true });
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
interface RunOutcome {
|
|
111
|
-
readonly exitCode: number;
|
|
112
|
-
readonly message: string;
|
|
113
|
-
readonly stdout: string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function run(...args: string[]): Promise<RunOutcome> {
|
|
117
|
-
const program = buildProgram();
|
|
118
|
-
program.exitOverride();
|
|
119
|
-
let stdout = "";
|
|
120
|
-
const outSpy = vi
|
|
121
|
-
.spyOn(process.stdout, "write")
|
|
122
|
-
.mockImplementation((chunk) => {
|
|
123
|
-
stdout += String(chunk);
|
|
124
|
-
return true;
|
|
125
|
-
});
|
|
126
|
-
const errSpy = vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
127
|
-
try {
|
|
128
|
-
await program.parseAsync(["node", "stigmer", "bootstrap", ...args]);
|
|
129
|
-
return { exitCode: ExitCode.Success, message: "", stdout };
|
|
130
|
-
} catch (err) {
|
|
131
|
-
return {
|
|
132
|
-
exitCode: classify(err)?.exitCode ?? -1,
|
|
133
|
-
message: err instanceof Error ? err.message : String(err),
|
|
134
|
-
stdout,
|
|
135
|
-
};
|
|
136
|
-
} finally {
|
|
137
|
-
outSpy.mockRestore();
|
|
138
|
-
errSpy.mockRestore();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
interface JsonSection {
|
|
143
|
-
title?: string;
|
|
144
|
-
fields?: { key: string; value: string }[];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function section(payload: { sections?: JsonSection[] }, title: string) {
|
|
148
|
-
return payload.sections?.find((s) => s.title === title);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
describe("bootstrap", () => {
|
|
152
|
-
it("creates the organization, installs nothing, and reports it", async () => {
|
|
153
|
-
const outcome = await run("--json");
|
|
154
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
155
|
-
expect(orgs.has(DEFAULT_LOCAL_ORG)).toBe(true);
|
|
156
|
-
|
|
157
|
-
const payload = JSON.parse(outcome.stdout);
|
|
158
|
-
expect(payload.status).toBe("success");
|
|
159
|
-
expect(payload.message).toBe("Backend is ready");
|
|
160
|
-
expect(payload.sections?.map((s: JsonSection) => s.title)).toEqual(["Organization"]);
|
|
161
|
-
expect(section(payload, "Organization")?.fields).toEqual([
|
|
162
|
-
{ key: "Slug", value: DEFAULT_LOCAL_ORG },
|
|
163
|
-
{ key: "State", value: "created" },
|
|
164
|
-
]);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it("is a no-op the second time: org present, nothing created", async () => {
|
|
168
|
-
await run("--json");
|
|
169
|
-
const outcome = await run("--json");
|
|
170
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
171
|
-
expect(creates).toBe(1);
|
|
172
|
-
const payload = JSON.parse(outcome.stdout);
|
|
173
|
-
expect(section(payload, "Organization")?.fields).toContainEqual({
|
|
174
|
-
key: "State",
|
|
175
|
-
value: "present",
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
});
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
// Command-level contract for the named-backend surface (O3):
|
|
2
|
-
// add/use/list/remove over the real config file (HOME redirected to a
|
|
3
|
-
// throwaway dir), the reserved-name refusals, and the remove-current guard.
|
|
4
|
-
// The model-level semantics (migration, resolution, credentials) are pinned
|
|
5
|
-
// in config.test.ts / resolve.test.ts — this file pins the command layer's
|
|
6
|
-
// own rules.
|
|
7
|
-
|
|
8
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
9
|
-
import { tmpdir } from "node:os";
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
12
|
-
import { load } from "../../config/index.js";
|
|
13
|
-
import { classify, ExitCode } from "../../errors/index.js";
|
|
14
|
-
import { buildProgram } from "../../program.js";
|
|
15
|
-
|
|
16
|
-
let home: string;
|
|
17
|
-
let originalHome: string | undefined;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
originalHome = process.env.HOME;
|
|
21
|
-
home = mkdtempSync(join(tmpdir(), "stigmer-backend-cmd-"));
|
|
22
|
-
process.env.HOME = home;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(() => {
|
|
26
|
-
if (originalHome === undefined) delete process.env.HOME;
|
|
27
|
-
else process.env.HOME = originalHome;
|
|
28
|
-
rmSync(home, { recursive: true, force: true });
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
interface RunOutcome {
|
|
32
|
-
readonly exitCode: number;
|
|
33
|
-
readonly message: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async function run(...args: string[]): Promise<RunOutcome> {
|
|
37
|
-
const program = buildProgram();
|
|
38
|
-
program.exitOverride();
|
|
39
|
-
const outSpy = vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
40
|
-
const errSpy = vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
41
|
-
try {
|
|
42
|
-
await program.parseAsync(["node", "stigmer", "config", "backend", ...args]);
|
|
43
|
-
return { exitCode: ExitCode.Success, message: "" };
|
|
44
|
-
} catch (err) {
|
|
45
|
-
return {
|
|
46
|
-
exitCode: classify(err)?.exitCode ?? -1,
|
|
47
|
-
message: err instanceof Error ? err.message : String(err),
|
|
48
|
-
};
|
|
49
|
-
} finally {
|
|
50
|
-
outSpy.mockRestore();
|
|
51
|
-
errSpy.mockRestore();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
describe("config backend add/use/list/remove", () => {
|
|
56
|
-
it("add persists a selfhost entry with its endpoint and api key", async () => {
|
|
57
|
-
const outcome = await run(
|
|
58
|
-
"add",
|
|
59
|
-
"staging",
|
|
60
|
-
"--endpoint",
|
|
61
|
-
"stigmer.example.com:7234",
|
|
62
|
-
"--api-key",
|
|
63
|
-
"stk_x",
|
|
64
|
-
);
|
|
65
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
66
|
-
const config = load();
|
|
67
|
-
expect(config.backends?.["staging"]).toEqual({
|
|
68
|
-
type: "selfhost",
|
|
69
|
-
endpoint: "stigmer.example.com:7234",
|
|
70
|
-
api_key: "stk_x",
|
|
71
|
-
});
|
|
72
|
-
// Adding never switches — the user opts in with `use`.
|
|
73
|
-
expect(config.current_backend).toBe("local");
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("add updates an existing entry without dropping its credential", async () => {
|
|
77
|
-
await run("add", "staging", "--endpoint", "old:7234", "--api-key", "stk_x");
|
|
78
|
-
await run("add", "staging", "--endpoint", "new:7234");
|
|
79
|
-
const entry = load().backends?.["staging"];
|
|
80
|
-
expect(entry?.endpoint).toBe("new:7234");
|
|
81
|
-
expect(entry?.api_key).toBe("stk_x");
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("use switches the current backend; unknown names refuse", async () => {
|
|
85
|
-
await run("add", "staging", "--endpoint", "host:7234");
|
|
86
|
-
expect((await run("use", "staging")).exitCode).toBe(ExitCode.Success);
|
|
87
|
-
expect(load().current_backend).toBe("staging");
|
|
88
|
-
|
|
89
|
-
const unknown = await run("use", "nope");
|
|
90
|
-
expect(unknown.exitCode).toBe(ExitCode.Usage);
|
|
91
|
-
expect(unknown.message).toContain('unknown backend "nope"');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("the local name is reserved: add and remove refuse it", async () => {
|
|
95
|
-
const add = await run("add", "local", "--endpoint", "host:7234");
|
|
96
|
-
expect(add.exitCode).toBe(ExitCode.Usage);
|
|
97
|
-
const remove = await run("remove", "local");
|
|
98
|
-
expect(remove.exitCode).toBe(ExitCode.Usage);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("remove refuses the current backend and deletes others", async () => {
|
|
102
|
-
await run("add", "staging", "--endpoint", "host:7234");
|
|
103
|
-
await run("use", "staging");
|
|
104
|
-
|
|
105
|
-
const current = await run("remove", "staging");
|
|
106
|
-
expect(current.exitCode).toBe(ExitCode.Usage);
|
|
107
|
-
expect(current.message).toContain("current backend");
|
|
108
|
-
|
|
109
|
-
await run("use", "local");
|
|
110
|
-
expect((await run("remove", "staging")).exitCode).toBe(ExitCode.Success);
|
|
111
|
-
expect(load().backends?.["staging"]).toBeUndefined();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("set cloud seeds and selects the reserved cloud entry (legacy sugar)", async () => {
|
|
115
|
-
expect((await run("set", "cloud")).exitCode).toBe(ExitCode.Success);
|
|
116
|
-
const config = load();
|
|
117
|
-
expect(config.current_backend).toBe("cloud");
|
|
118
|
-
expect(config.backends?.["cloud"]?.endpoint).toBe("api.stigmer.ai:443");
|
|
119
|
-
expect((await run("set", "local")).exitCode).toBe(ExitCode.Success);
|
|
120
|
-
expect(load().current_backend).toBe("local");
|
|
121
|
-
});
|
|
122
|
-
});
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
// Command-level contract for `stigmer config context set --org`: an
|
|
2
|
-
// organization the caller belongs to on the active backend is persisted as
|
|
3
|
-
// the context and then resolved by every command; a slug the backend does not
|
|
4
|
-
// list among the caller's own is refused as not found and the config file is
|
|
5
|
-
// left byte-for-byte as it was; an empty slug clears the context without
|
|
6
|
-
// asking the backend; no `--org` at all is a usage error. And `context show`
|
|
7
|
-
// names the active backend, not the legacy local/cloud switch the file also
|
|
8
|
-
// carries. A real Connect backend over h2c serves findMyOrganizations; the
|
|
9
|
-
// config file (HOME redirected) points a selfhost backend at it.
|
|
10
|
-
|
|
11
|
-
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
12
|
-
import {
|
|
13
|
-
createServer as createHttp2Server,
|
|
14
|
-
type Http2Server,
|
|
15
|
-
type ServerHttp2Session,
|
|
16
|
-
} from "node:http2";
|
|
17
|
-
import type { AddressInfo } from "node:net";
|
|
18
|
-
import { tmpdir } from "node:os";
|
|
19
|
-
import { join } from "node:path";
|
|
20
|
-
import { create } from "@bufbuild/protobuf";
|
|
21
|
-
import type { ConnectRouter } from "@connectrpc/connect";
|
|
22
|
-
import { connectNodeAdapter } from "@connectrpc/connect-node";
|
|
23
|
-
import { OrganizationSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
24
|
-
import { OrganizationsSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/io_pb";
|
|
25
|
-
import { OrganizationQueryController } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/query_pb";
|
|
26
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
27
|
-
import { load, resolveOrganization } from "../../config/index.js";
|
|
28
|
-
import { classify, ExitCode } from "../../errors/index.js";
|
|
29
|
-
import { buildProgram } from "../../program.js";
|
|
30
|
-
|
|
31
|
-
let backend: Http2Server;
|
|
32
|
-
let port: number;
|
|
33
|
-
const openSessions = new Set<ServerHttp2Session>();
|
|
34
|
-
let lookups: number;
|
|
35
|
-
|
|
36
|
-
let home: string;
|
|
37
|
-
let originalHome: string | undefined;
|
|
38
|
-
|
|
39
|
-
beforeAll(async () => {
|
|
40
|
-
const routes = (router: ConnectRouter) => {
|
|
41
|
-
router.service(OrganizationQueryController, {
|
|
42
|
-
findMyOrganizations: () => {
|
|
43
|
-
lookups += 1;
|
|
44
|
-
return create(OrganizationsSchema, {
|
|
45
|
-
entries: [create(OrganizationSchema, { metadata: { id: "acme", slug: "acme" } })],
|
|
46
|
-
});
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
backend = createHttp2Server(connectNodeAdapter({ routes }));
|
|
51
|
-
backend.on("session", (session) => {
|
|
52
|
-
openSessions.add(session);
|
|
53
|
-
session.on("close", () => openSessions.delete(session));
|
|
54
|
-
});
|
|
55
|
-
await new Promise<void>((resolve) => backend.listen(0, "127.0.0.1", resolve));
|
|
56
|
-
port = (backend.address() as AddressInfo).port;
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
afterAll(async () => {
|
|
60
|
-
for (const session of openSessions) session.destroy();
|
|
61
|
-
await new Promise<void>((resolve) => backend.close(() => resolve()));
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
beforeEach(() => {
|
|
65
|
-
lookups = 0;
|
|
66
|
-
originalHome = process.env.HOME;
|
|
67
|
-
home = mkdtempSync(join(tmpdir(), "stigmer-context-cmd-"));
|
|
68
|
-
process.env.HOME = home;
|
|
69
|
-
mkdirSync(join(home, ".stigmer"), { recursive: true });
|
|
70
|
-
writeFileSync(
|
|
71
|
-
configFile(),
|
|
72
|
-
[
|
|
73
|
-
"backend:",
|
|
74
|
-
" type: cloud",
|
|
75
|
-
"backends:",
|
|
76
|
-
" team:",
|
|
77
|
-
" type: selfhost",
|
|
78
|
-
` endpoint: 127.0.0.1:${port}`,
|
|
79
|
-
"current_backend: team",
|
|
80
|
-
"",
|
|
81
|
-
].join("\n"),
|
|
82
|
-
);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
afterEach(() => {
|
|
86
|
-
if (originalHome === undefined) delete process.env.HOME;
|
|
87
|
-
else process.env.HOME = originalHome;
|
|
88
|
-
rmSync(home, { recursive: true, force: true });
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
function configFile(): string {
|
|
92
|
-
return join(home, ".stigmer", "config.yaml");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
interface RunOutcome {
|
|
96
|
-
readonly exitCode: number;
|
|
97
|
-
readonly message: string;
|
|
98
|
-
readonly stdout: string;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
async function run(...args: string[]): Promise<RunOutcome> {
|
|
102
|
-
return runContext("set", ...args);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function runContext(...args: string[]): Promise<RunOutcome> {
|
|
106
|
-
const program = buildProgram();
|
|
107
|
-
program.exitOverride();
|
|
108
|
-
let stdout = "";
|
|
109
|
-
const outSpy = vi.spyOn(process.stdout, "write").mockImplementation((chunk) => {
|
|
110
|
-
stdout += String(chunk);
|
|
111
|
-
return true;
|
|
112
|
-
});
|
|
113
|
-
const errSpy = vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
114
|
-
try {
|
|
115
|
-
await program.parseAsync(["node", "stigmer", "config", "context", ...args]);
|
|
116
|
-
return { exitCode: ExitCode.Success, message: "", stdout };
|
|
117
|
-
} catch (err) {
|
|
118
|
-
return {
|
|
119
|
-
exitCode: classify(err)?.exitCode ?? -1,
|
|
120
|
-
message: err instanceof Error ? err.message : String(err),
|
|
121
|
-
stdout,
|
|
122
|
-
};
|
|
123
|
-
} finally {
|
|
124
|
-
outSpy.mockRestore();
|
|
125
|
-
errSpy.mockRestore();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
describe("config context set --org", () => {
|
|
130
|
-
it("persists an organization the caller belongs to, which every command then resolves", async () => {
|
|
131
|
-
const outcome = await run("--org", "acme");
|
|
132
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
133
|
-
expect(lookups).toBe(1);
|
|
134
|
-
expect(resolveOrganization(load())).toBe("acme");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("refuses a slug the backend does not list as the caller's and leaves the config untouched", async () => {
|
|
138
|
-
const before = readFileSync(configFile(), "utf8");
|
|
139
|
-
const outcome = await run("--org", "acmee");
|
|
140
|
-
expect(outcome.exitCode).toBe(ExitCode.NotFound);
|
|
141
|
-
expect(outcome.message).toMatch(/organization 'acmee' is not one you belong to on the 'team' backend/);
|
|
142
|
-
expect(readFileSync(configFile(), "utf8")).toBe(before);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("clears the context with an empty slug, without asking the backend", async () => {
|
|
146
|
-
await run("--org", "acme");
|
|
147
|
-
const outcome = await run("--org", "");
|
|
148
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
149
|
-
expect(lookups).toBe(1);
|
|
150
|
-
expect(resolveOrganization(load())).toBe("stigmer");
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("is a usage error without --org", async () => {
|
|
154
|
-
const outcome = await run();
|
|
155
|
-
expect(outcome.exitCode).toBe(ExitCode.Usage);
|
|
156
|
-
expect(outcome.message).toMatch(/--org is required/);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
describe("config context show", () => {
|
|
161
|
-
it("names the active backend, not the legacy local/cloud switch", async () => {
|
|
162
|
-
await run("--org", "acme");
|
|
163
|
-
const outcome = await runContext("show", "--json");
|
|
164
|
-
expect(outcome.exitCode).toBe(ExitCode.Success);
|
|
165
|
-
const fields = JSON.parse(outcome.stdout).sections[0].fields as { key: string; value: string }[];
|
|
166
|
-
expect(fields).toEqual([
|
|
167
|
-
{ key: "Organization", value: "acme" },
|
|
168
|
-
{ key: "Backend", value: "team" },
|
|
169
|
-
]);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// Command-level contract for the `connect mcp-server` org guard (issue #140).
|
|
2
|
-
//
|
|
3
|
-
// Connecting pushes to the backend, which requires an org. Rather than let the
|
|
4
|
-
// backend reject the request with the cryptic "org value length must be at least
|
|
5
|
-
// 1" validation error, the command fails fast with actionable guidance — but
|
|
6
|
-
// only when it is actually going to push. `--dry-run` discovers locally and must
|
|
7
|
-
// stay usable with no org configured.
|
|
8
|
-
//
|
|
9
|
-
// Local mode always resolves an org (the single-tenant DEFAULT_LOCAL_ORG
|
|
10
|
-
// fallback in resolveOrganization), so the guard can only fire in cloud mode
|
|
11
|
-
// with no org selected. The guard test injects that shape by overriding
|
|
12
|
-
// `load()`; everything else stays real. The guard runs before any network
|
|
13
|
-
// call, so both cases are fully deterministic and offline.
|
|
14
|
-
|
|
15
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
16
|
-
import type { Config } from "../config/index.js";
|
|
17
|
-
import { classify, ExitCode } from "../errors/index.js";
|
|
18
|
-
import { buildProgram } from "../program.js";
|
|
19
|
-
|
|
20
|
-
// When set, `load()` returns this config instead of reading disk/defaults.
|
|
21
|
-
// Reset in beforeEach so each test opts in explicitly.
|
|
22
|
-
let configOverride: Config | undefined;
|
|
23
|
-
|
|
24
|
-
vi.mock("../config/index.js", async (importOriginal) => {
|
|
25
|
-
const actual = await importOriginal<typeof import("../config/index.js")>();
|
|
26
|
-
return {
|
|
27
|
-
...actual,
|
|
28
|
-
load: (path?: string) => configOverride ?? actual.load(path),
|
|
29
|
-
};
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
/** An authenticated cloud config with no org selected — the guard's target shape. */
|
|
33
|
-
function cloudConfigWithoutOrg(): Config {
|
|
34
|
-
return {
|
|
35
|
-
backend: { type: "cloud" },
|
|
36
|
-
backends: { cloud: { type: "cloud", token: "test-token" } },
|
|
37
|
-
current_backend: "cloud",
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
interface RunOutcome {
|
|
42
|
-
readonly exitCode: number;
|
|
43
|
-
readonly message: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Runs `connect mcp-server <ref> [flags]` in standalone mode with output
|
|
47
|
-
// suppressed, returning the thrown error's classified exit code and message (or
|
|
48
|
-
// a success sentinel). `--standalone` is a program-global flag, so it must
|
|
49
|
-
// precede the subcommand (commander's enablePositionalOptions).
|
|
50
|
-
async function runConnect(
|
|
51
|
-
ref: string,
|
|
52
|
-
...flags: string[]
|
|
53
|
-
): Promise<RunOutcome> {
|
|
54
|
-
const program = buildProgram();
|
|
55
|
-
program.exitOverride();
|
|
56
|
-
const outSpy = vi.spyOn(process.stdout, "write").mockReturnValue(true);
|
|
57
|
-
const errSpy = vi.spyOn(process.stderr, "write").mockReturnValue(true);
|
|
58
|
-
try {
|
|
59
|
-
await program.parseAsync([
|
|
60
|
-
"node",
|
|
61
|
-
"stigmer",
|
|
62
|
-
"--standalone",
|
|
63
|
-
"connect",
|
|
64
|
-
"mcp-server",
|
|
65
|
-
ref,
|
|
66
|
-
...flags,
|
|
67
|
-
]);
|
|
68
|
-
return { exitCode: ExitCode.Success, message: "" };
|
|
69
|
-
} catch (err) {
|
|
70
|
-
return {
|
|
71
|
-
exitCode: classify(err)?.exitCode ?? -1,
|
|
72
|
-
message: err instanceof Error ? err.message : String(err),
|
|
73
|
-
};
|
|
74
|
-
} finally {
|
|
75
|
-
outSpy.mockRestore();
|
|
76
|
-
errSpy.mockRestore();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let savedOrg: string | undefined;
|
|
81
|
-
let savedApiKey: string | undefined;
|
|
82
|
-
|
|
83
|
-
beforeEach(() => {
|
|
84
|
-
configOverride = undefined;
|
|
85
|
-
savedOrg = process.env.STIGMER_ORG_ID;
|
|
86
|
-
savedApiKey = process.env.STIGMER_API_KEY;
|
|
87
|
-
delete process.env.STIGMER_ORG_ID;
|
|
88
|
-
delete process.env.STIGMER_API_KEY;
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
afterEach(() => {
|
|
92
|
-
if (savedOrg === undefined) delete process.env.STIGMER_ORG_ID;
|
|
93
|
-
else process.env.STIGMER_ORG_ID = savedOrg;
|
|
94
|
-
if (savedApiKey === undefined) delete process.env.STIGMER_API_KEY;
|
|
95
|
-
else process.env.STIGMER_API_KEY = savedApiKey;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe("connect mcp-server org guard", () => {
|
|
99
|
-
it("fails fast with actionable guidance when cloud mode has no org (non-dry-run)", async () => {
|
|
100
|
-
configOverride = cloudConfigWithoutOrg();
|
|
101
|
-
const outcome = await runConnect("mcp_test");
|
|
102
|
-
expect(outcome.message).toContain("organization not set");
|
|
103
|
-
expect(outcome.exitCode).toBe(ExitCode.Usage);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it("does not apply the org guard in dry-run mode (offline dry-run stays usable)", async () => {
|
|
107
|
-
// Dry-run skips the push, so the guard must not fire even with no org. The
|
|
108
|
-
// command proceeds past the guard and fails later for an unrelated reason
|
|
109
|
-
// (no reachable backend) — never with the org guidance error.
|
|
110
|
-
const outcome = await runConnect("mcp_test", "--dry-run");
|
|
111
|
-
expect(outcome.message).not.toContain("organization not set");
|
|
112
|
-
});
|
|
113
|
-
});
|