@stackbone/cli 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +165 -0
- package/README.md +18 -18
- package/main.js +1973 -8697
- package/migrations/0046_runtime_identity_control_plane.sql +28 -0
- package/migrations/0050_run_steps_model_provider.sql +30 -0
- package/package.json +1 -1
- package/runtime-deps/@stackbone/workflow-world/index.js +71 -71
- package/stackbone-cli-0.3.4.tgz +0 -0
- package/stackbone-cli-0.3.2.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,171 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.4] - 2026-08-19
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`stackbone init` installs the workspace dependencies itself.** After the
|
|
15
|
+
files are written it runs `pnpm install` when `pnpm` answers on `PATH` and
|
|
16
|
+
`npm install` otherwise, so the workspace is ready for `stackbone dev` the
|
|
17
|
+
moment the command returns. The scaffold works under both: its `.npmrc` pins
|
|
18
|
+
a hoisted `node_modules`, its root `package.json` now declares the
|
|
19
|
+
`workflows` subpackage in a `workspaces` field as well as in
|
|
20
|
+
`pnpm-workspace.yaml` (npm does not read the yaml), and neither `build` nor
|
|
21
|
+
`package` install from the workspace. Best-effort like the coding-agent setup: a failed
|
|
22
|
+
install prints the package manager's last lines as a warning, the command still
|
|
23
|
+
exits `0`, and the "Next steps" note keeps the `<pm> install` line — naming
|
|
24
|
+
the manager that ran, not a hard-coded `pnpm`. `--no-install` skips the step.
|
|
25
|
+
The JSON envelope gains `dependencies: { status, package_manager, error? }`
|
|
26
|
+
(`installed` | `failed` | `skipped`).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **`stackbone init` and `stackbone link` ask which coding agents you use, and
|
|
31
|
+
that one answer installs the skills AND configures the documentation MCP
|
|
32
|
+
server.** The CLI used to guess: it called `npx skills` with no agent list and
|
|
33
|
+
let upstream detection decide where to copy. That detection is
|
|
34
|
+
`existsSync(~/.<agent>)`, so a leftover directory from an old `skills add -g`
|
|
35
|
+
made every later `init` copy into tools the creator had never opened, and when
|
|
36
|
+
it detected nothing at all it installed into every known agent. There is now a
|
|
37
|
+
multiselect of the seven supported agents (Claude Code, Cursor, GitHub
|
|
38
|
+
Copilot, Gemini CLI, Windsurf, Cline, Codex) with the ones present on disk
|
|
39
|
+
pre-ticked, and whatever you tick gets both halves: the four agent skills, and
|
|
40
|
+
a `stackbone-docs` entry in that agent's own MCP configuration. Zero is a
|
|
41
|
+
valid answer.
|
|
42
|
+
|
|
43
|
+
The seven MCP entries do **not** share a shape, and that is registry data
|
|
44
|
+
rather than branches in code: VS Code keys its map `servers`, not
|
|
45
|
+
`mcpServers`; Gemini CLI reads `httpUrl` and treats `url` as SSE; Windsurf
|
|
46
|
+
reads `serverUrl`; Cline spells the transport `streamableHttp` in that exact
|
|
47
|
+
casing (with `streamable-http` it falls back to SSE and the endpoint answers
|
|
48
|
+
405); and Codex is TOML. Every wrong shape parses without complaining and then
|
|
49
|
+
fails to connect, which is the worst failure we could ship because the creator
|
|
50
|
+
sees a config file that looks right. Every write MERGES: the other MCP servers
|
|
51
|
+
in the file survive, so do foreign root keys (`inputs` in `.vscode/mcp.json`),
|
|
52
|
+
and an existing `stackbone-docs` entry is left byte for byte as it is, because
|
|
53
|
+
the creator may have edited it. A file we cannot parse is left untouched and
|
|
54
|
+
that one target is marked `failed`; the rest are still written.
|
|
55
|
+
|
|
56
|
+
The four project-scoped MCP files (`.mcp.json`, `.cursor/mcp.json`,
|
|
57
|
+
`.vscode/mcp.json`, `.gemini/settings.json`) are deliberately NOT added to the
|
|
58
|
+
`.gitignore` block: they are meant to be committed, so a teammate who clones
|
|
59
|
+
the repository inherits the documentation server without running anything.
|
|
60
|
+
|
|
61
|
+
**Breaking.** In non-interactive mode (`--json`, `--yes`, no TTY, or `CI` set
|
|
62
|
+
in the environment) `init` and `link` now install **nothing** unless you pass
|
|
63
|
+
`--agents <list>`. `stackbone init --json` used to install the skills for
|
|
64
|
+
whichever agents were auto-detected; it now installs none. A multiselect fired
|
|
65
|
+
under `--json` would hang a pipeline forever with nothing on stdout to explain
|
|
66
|
+
it, so the gate is hard. Any script or CI job that relied on `init --json`
|
|
67
|
+
leaving the skills in place has to add `--agents claude-code,cursor,…`.
|
|
68
|
+
`--no-agents` is the explicit switch for setting nothing up.
|
|
69
|
+
|
|
70
|
+
The JSON envelope of both commands changes with it: `skills_install` is gone
|
|
71
|
+
and `agent_setup` takes its place, shaped
|
|
72
|
+
`{ ok, selected, steps: { skills, mcp } }` where `mcp` carries a per-agent
|
|
73
|
+
status (`written` | `already` | `failed` | `skipped`). The shape stays constant
|
|
74
|
+
even when nothing is selected, so an agent reading the output never has to
|
|
75
|
+
branch on a missing block.
|
|
76
|
+
|
|
77
|
+
- **`stackbone docs` hands over MCP connection details instead of printing the
|
|
78
|
+
documentation.** The CLI used to compile a copy of the wiki into the binary
|
|
79
|
+
and render a page inline (`stackbone docs cli/commands`). That copy was 544 KB
|
|
80
|
+
of a 2.8 MB bundle, it had no search so the reader had to guess an exact topic
|
|
81
|
+
key, and an old install could hand out documentation that quietly disagreed
|
|
82
|
+
with the live site. The wiki now serves the same pages over MCP at
|
|
83
|
+
`https://docs.stackbone.ai/mcp`, which searches by meaning and always reflects
|
|
84
|
+
the current deploy, so the command's job is the connection details: the
|
|
85
|
+
endpoint, the `claude mcp add` one-liner, and the `mcpServers` block every
|
|
86
|
+
other client accepts. `--json` returns them structured, with
|
|
87
|
+
`install.mcpServers` ready to write into a client config without parsing the
|
|
88
|
+
human output.
|
|
89
|
+
|
|
90
|
+
**Breaking.** Passing a topic now exits `4` and names the replacement rather
|
|
91
|
+
than rendering a page. Rejecting the argument beats ignoring it: a script that
|
|
92
|
+
still passes one finds out, instead of silently reading a help screen where it
|
|
93
|
+
expected a reference page. The binary lost ~518 KB.
|
|
94
|
+
|
|
95
|
+
### Removed
|
|
96
|
+
|
|
97
|
+
- **The wiki-to-CLI documentation sync.** `apps/cli/src/docs/` (including the
|
|
98
|
+
generated `topics.generated.ts`), the `sync-docs` and `sync-docs:check` Nx
|
|
99
|
+
targets, the `cli:sync-docs` / `cli:sync-docs:check` workspace scripts, and the
|
|
100
|
+
`sync-docs` dependency of `cli:build`. Nothing regenerates into the binary any
|
|
101
|
+
more, so nothing can drift against it.
|
|
102
|
+
|
|
103
|
+
## [0.3.3] - 2026-08-11
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- **The folder `stackbone package` writes now brings object storage, not just a
|
|
108
|
+
database and a queue.** The generated compose already shipped a pgvector
|
|
109
|
+
Postgres because of managed RAG, but managed RAG stores the ingested original
|
|
110
|
+
in a bucket before it chunks and embeds it. So an operator who ran
|
|
111
|
+
`docker compose up -d` got the vector database and nowhere to put files:
|
|
112
|
+
ingestion died on the first upload, `client.storage` answered
|
|
113
|
+
`s3_credentials_missing`, and the file browser had nothing to talk to, while
|
|
114
|
+
`/health` said `ok` throughout because it only probes Postgres and Redis. The
|
|
115
|
+
compose now brings a MinIO plus a one-shot container that creates the bucket,
|
|
116
|
+
and the agent waits for the bucket to exist rather than for MinIO to be
|
|
117
|
+
healthy. Unlike the two datastores, this one publishes a port and generates
|
|
118
|
+
its own password: a presigned download link carries the endpoint it was
|
|
119
|
+
signed with, so a link signed against an address only the compose network
|
|
120
|
+
resolves is useless to a browser.
|
|
121
|
+
- **The folder also gains a `.env.example`,** rendered from the same template as
|
|
122
|
+
the real `.env` so the committable copy cannot drift into a stale list of
|
|
123
|
+
variables.
|
|
124
|
+
- **`STACKBONE_S3_FORCE_PATH_STYLE` picks how the box addresses its bucket.** It
|
|
125
|
+
was hardcoded to path-style, which made every subdomain-only backend (AWS S3,
|
|
126
|
+
Railway Buckets) unusable. Additive, and still defaulting to path-style, which
|
|
127
|
+
is what the bundled MinIO speaks.
|
|
128
|
+
|
|
129
|
+
### Fixed
|
|
130
|
+
|
|
131
|
+
- **`stackbone build` now ships the config schema itself, not just a flag saying
|
|
132
|
+
one exists.** `stackbone dev` extracted the creator's `config.schema.ts` and
|
|
133
|
+
served the Studio config form off it; `build` stamped `config: { schema: true }`
|
|
134
|
+
on the manifest and emitted no schema. A packaged box found nothing on disk and
|
|
135
|
+
degraded the form to a raw JSON field with writes unvalidated, so a config that
|
|
136
|
+
worked in dev silently did not in the box. The compiler now writes the artifact
|
|
137
|
+
using the same extractor `dev` runs. A declared schema that will not convert
|
|
138
|
+
warns and ships without the file rather than failing the build.
|
|
139
|
+
- **`stackbone link` teaches the box which installation it answers for.** The box
|
|
140
|
+
learns its organization and installation id at registration, and the browser
|
|
141
|
+
wizard already did this; `link` registered a deployment and taught nothing, so
|
|
142
|
+
every box linked from the terminal refused all Studio and CLI traffic with a
|
|
143
|
+
401 blaming a tenant mismatch that did not exist. `link` now holds the same
|
|
144
|
+
prove, teach, then write order as the wizard, and fails closed: a box that
|
|
145
|
+
cannot be taught is not registered at all.
|
|
146
|
+
- **A box locks its secrets with the key the agent opens them with.** A secret
|
|
147
|
+
written from Studio or the CLI landed encrypted under the documented dev seed,
|
|
148
|
+
while `client.secrets.get()` inside the agent decrypts with the per-agent
|
|
149
|
+
`STACKBONE_SECRET_KEY`. The row was there and the read still failed, so a
|
|
150
|
+
workflow reported the secret as missing. Only deployed boxes were affected;
|
|
151
|
+
`stackbone dev` falls back to the same seed on both sides. **Secrets stored
|
|
152
|
+
under the old key cannot be recovered and have to be set again once the new
|
|
153
|
+
image is running.**
|
|
154
|
+
- **A box defaults to the Stackbone control plane and says so at boot.**
|
|
155
|
+
`STACKBONE_CONTROL_PLANE_URL` had no default and nothing in the product set
|
|
156
|
+
it, so a box armed no browser-identity verifier and answered 401 on every
|
|
157
|
+
Studio screen. It now falls back to `https://api.stackbone.ai`, and the boot
|
|
158
|
+
line prints which control plane it armed against and whether the operator
|
|
159
|
+
chose it. A box belonging to a self-hosted control plane still has to name it.
|
|
160
|
+
|
|
161
|
+
### Changed
|
|
162
|
+
|
|
163
|
+
- **An identity token is minted per organization, and names the box it is for.**
|
|
164
|
+
The old mint read the caller's earliest-joined membership, so an operator in
|
|
165
|
+
two organizations got a token no box in the second one accepts, carrying their
|
|
166
|
+
role from the first. The token now also carries the installation it was minted
|
|
167
|
+
for, and a box admits a request only when that claim matches the installation
|
|
168
|
+
it answers for: a token lifted off one box is worthless against the next.
|
|
169
|
+
- **The box says which check refused the request.** One code answered three
|
|
170
|
+
different refusals, and the copy named the signature, so an operator whose real
|
|
171
|
+
problem was the token's organization went and checked a secret, a clock and a
|
|
172
|
+
container that were all fine. Now `invalid_signature`, `invalid_token` and
|
|
173
|
+
`invalid_token_tenant` are distinct. Nothing about who is admitted changed.
|
|
174
|
+
|
|
10
175
|
## [0.3.2] - 2026-08-10
|
|
11
176
|
|
|
12
177
|
### Added
|
package/README.md
CHANGED
|
@@ -19,23 +19,23 @@ That's it. `init` scaffolds a new workspace shell (agents + workflows + coding-a
|
|
|
19
19
|
|
|
20
20
|
## Commands
|
|
21
21
|
|
|
22
|
-
| Command | What it does
|
|
23
|
-
| ----------------------------- |
|
|
24
|
-
| `stackbone init [name]` | Scaffold a new workspace shell and link it to your org (needs login).
|
|
25
|
-
| `stackbone add <kind> <name>` | Add an agent / workflow / workflow-agent to the workspace (offline).
|
|
26
|
-
| `stackbone dev` | Boot the whole workspace locally + Stackbone Studio.
|
|
27
|
-
| `stackbone workflows <verb>` | List, inspect the schema of, or start the install's workflows.
|
|
28
|
-
| `stackbone build` | Compile the workspace into the bundle your container image bakes in.
|
|
29
|
-
| `stackbone login` / `logout` | Authenticate the CLI via the device-code flow (RFC 8628).
|
|
30
|
-
| `stackbone whoami` | Show the active user and organization.
|
|
31
|
-
| `stackbone current` | Print the organization currently linked to this session.
|
|
32
|
-
| `stackbone link` | Link the current directory to an existing organization + agent.
|
|
33
|
-
| `stackbone list` | List organizations the current user owns.
|
|
34
|
-
| `stackbone metadata` | Agent-friendly snapshot of the workspace state.
|
|
35
|
-
| `stackbone db <subcmd>` | Manage the local emulator database (migrations, queries).
|
|
36
|
-
| `stackbone docs
|
|
37
|
-
|
|
38
|
-
Run any command with `--help` for the full flag reference
|
|
22
|
+
| Command | What it does |
|
|
23
|
+
| ----------------------------- | --------------------------------------------------------------------- |
|
|
24
|
+
| `stackbone init [name]` | Scaffold a new workspace shell and link it to your org (needs login). |
|
|
25
|
+
| `stackbone add <kind> <name>` | Add an agent / workflow / workflow-agent to the workspace (offline). |
|
|
26
|
+
| `stackbone dev` | Boot the whole workspace locally + Stackbone Studio. |
|
|
27
|
+
| `stackbone workflows <verb>` | List, inspect the schema of, or start the install's workflows. |
|
|
28
|
+
| `stackbone build` | Compile the workspace into the bundle your container image bakes in. |
|
|
29
|
+
| `stackbone login` / `logout` | Authenticate the CLI via the device-code flow (RFC 8628). |
|
|
30
|
+
| `stackbone whoami` | Show the active user and organization. |
|
|
31
|
+
| `stackbone current` | Print the organization currently linked to this session. |
|
|
32
|
+
| `stackbone link` | Link the current directory to an existing organization + agent. |
|
|
33
|
+
| `stackbone list` | List organizations the current user owns. |
|
|
34
|
+
| `stackbone metadata` | Agent-friendly snapshot of the workspace state. |
|
|
35
|
+
| `stackbone db <subcmd>` | Manage the local emulator database (migrations, queries). |
|
|
36
|
+
| `stackbone docs` | Show how to reach the documentation over MCP. |
|
|
37
|
+
|
|
38
|
+
Run any command with `--help` for the full flag reference. The full documentation lives at <https://docs.stackbone.ai>, and is also served to coding agents over MCP at <https://docs.stackbone.ai/mcp> — run `stackbone docs` for the connection details.
|
|
39
39
|
|
|
40
40
|
## Requirements
|
|
41
41
|
|
|
@@ -46,7 +46,7 @@ Run any command with `--help` for the full flag reference, or `npx @stackbone/cl
|
|
|
46
46
|
|
|
47
47
|
- Documentation: <https://docs.stackbone.ai>
|
|
48
48
|
- Marketplace: <https://stackbone.ai>
|
|
49
|
-
- Issues & feedback:
|
|
49
|
+
- Issues & feedback: contact the team directly.
|
|
50
50
|
|
|
51
51
|
## License
|
|
52
52
|
|