@stackbone/cli 0.4.0-alpha.0 → 0.4.1

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 CHANGED
@@ -7,6 +7,144 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.1] - 2026-09-11
11
+
12
+ ### Added
13
+
14
+ - **Every generated connector signature declares its second parameter.**
15
+ `connection(id).<op>(args, opts)` has forwarded a second argument at run time
16
+ since it existed and no generated signature declared it, so the SDK's
17
+ `idempotent` was reachable only through the untyped `.call(…)` — not the path
18
+ a creator is steered to. Each signature now prints
19
+ `opts?: CallConnectorOptions`, the three overloads of a `'when-requested'` raw
20
+ response included. An operation with no declared arguments prints
21
+ `args?: undefined` rather than nothing: the runtime proxy is `(args?, opts?)`
22
+ for every operation, so a signature that let `opts` come first would hand the
23
+ creator's options to the provider as arguments. The field itself needs
24
+ `@stackbone/sdk` 0.4.1.
25
+
26
+ ### Fixed
27
+
28
+ - **A guarded PATCH whose body columns share names with query filters can now be
29
+ called.** Swagger's body argument name is preserved and its object sent
30
+ separately from the query filters, so a partial write no longer collides with
31
+ the filter that selects the row. Flat POST bodies are unchanged, the narrowing
32
+ guard applies to PATCH before the request leaves, and a fetched row schema no
33
+ longer makes a partial write mandatory by way of its server-generated columns.
34
+ Verified against local PostgREST for partial PATCH, stale-version no-op,
35
+ unsafe PATCH refusal and flat POST.
36
+
37
+ ### Changed
38
+
39
+ - The coding-agent labels in the setup flow come from `@stackbone/format`, so
40
+ the browser and the CLI render one list instead of two that drift.
41
+
42
+ ## [0.4.0] - 2026-09-10
43
+
44
+ ### Added
45
+
46
+ - **A workflow declares what it sends outward, and `stackbone dev` types it.**
47
+ `export const declaredOutputs = [{ name: 'report', kind: 'file' }, { name:
48
+ 'fileIssue', kind: 'action' }]` is a sibling export next to
49
+ `inputSchema`/`outputSchema`, read out of the workflow module or its
50
+ `.contract.ts`. The emulator writes `.stackbone/outputs.d.ts` from it, which
51
+ closes the name sets the SDK's `stackbone.outputs.write` and
52
+ `stackbone.action` accept — naming an action where a file output belongs
53
+ becomes a compile error instead of a run-time `unbound`. The list is read by
54
+ PARSING, never by evaluating: an operator binds a name to a destination before
55
+ any run exists, so a name that only appears once the workflow is running is a
56
+ name nobody can point a destination at, and the parse refuses it where it is
57
+ written, with a line. `kind` is required in source and defaulted on both wires
58
+ (PLA-1092, PLA-1251).
59
+
60
+ - **`.stackbone/connect.d.ts` types the connections the box has registered, not
61
+ just the connectors declared as files.** For seven of the eight built-ins the
62
+ difference is cosmetic, because their operations are a published API. For
63
+ Supabase it is the whole problem: a connection's operations ARE the customer's
64
+ schema, one per table, so they exist in no file and used to be retyped by hand
65
+ off the picker with nothing checking either half. The codegen now also reads
66
+ the box's own management surface. The box introspects and the CLI consumes,
67
+ which is forced rather than chosen — the credential is custodied in the broker
68
+ and Supabase refuses its metadata endpoint to an unauthenticated read. An id
69
+ declared in `connect/*.json` wins on collision, so the existing path stays
70
+ byte-identical.
71
+
72
+ - **`stackbone init` offers the organization's existing workspaces.** It used to
73
+ resolve the workspace by (org, slug) and create on a 404, so a creator who had
74
+ made a workspace in the browser and then ran `init` in a folder of that name
75
+ silently got a second, empty one. When nothing else names the workspace it now
76
+ lists the organization's agents and offers to pick one. The non-interactive
77
+ contract does not move: `--name`, a positional directory, `--json`, `--yes`
78
+ and a missing terminal all skip the listing and the prompt (PLA-1204).
79
+
80
+ ### Changed
81
+
82
+ - **BREAKING: `stackbone link` registers a box against one INSTALLATION, named
83
+ by `--installation <id>`, and never creates one.** The deployment registry
84
+ used to hold one row per agent template, while a box answers for exactly one
85
+ installation id and refuses every other with a 401 — so with two installations
86
+ of the same template at most one could be reached. The row now belongs to the
87
+ installation (`POST /api/v1/deployments` requires `installationId`), and
88
+ `link` has to be told which one: `--installation <id>` is one of the linked
89
+ agent's `cloud` rows in `stackbone agents list`. It is validated before the
90
+ box is touched — an id of another agent, an id this organization does not
91
+ hold, or a local-dev id (served by its `stackbone dev` tunnel, never by a
92
+ registered deployment) is refused with no teach and no registration. Without
93
+ the flag, `link` refuses before any network call and names the discovery
94
+ command, except on a `--force` re-run in a directory whose
95
+ `.stackbone/project.json` remembers the id the last link wrote (new field
96
+ `deploymentInstallationId`, named that because it sits next to
97
+ `localDevInstallationId` and the two are different rows; older files still
98
+ load, including one written under the interim `installationId` spelling —
99
+ that key is simply dropped, so the next `link --force` in that directory asks
100
+ for `--installation` once and rewrites the file. Nothing has to migrate it).
101
+ `link` no longer creates a cloud
102
+ installation when the agent has none — install the agent first. When the
103
+ target installation already answers somewhere, `link` prints the address it
104
+ is about to replace before proceeding. The JSON envelope keeps
105
+ `installation {id, organization_id, kind}` and drops `deployment_reachable`,
106
+ which could only ever say `reachable: true` now that a local-dev target is
107
+ refused up front (PLA-853).
108
+
109
+ ### Removed
110
+
111
+ - **BREAKING: `stackbone runs retry` is gone.** `POST /api/runs/:id/retry`
112
+ copied the failed run's input, inserted a fresh `running` row and published
113
+ `run.created` so Studio repainted — and stopped there. Nothing ever advanced
114
+ that row, because nothing dispatched the payload to the agent. Three surfaces
115
+ sold it as real anyway, this verb among them, gated behind `--yes` as if it
116
+ were destructive. The route now answers 404 and a test pins it there, so the
117
+ placebo cannot come back without a dispatch behind it. Nothing is lost: the
118
+ action never did anything (PLA-949).
119
+
120
+ ### Fixed
121
+
122
+ - **`stackbone eval` counts `not_evaluable` as an ending, and a swallowed
123
+ refusal no longer grades as a quality regression.** The CLI holds a twin of
124
+ Studio's ending list and only Studio's had been widened, so the same run got
125
+ one verdict in CI and another in the browser. The connector registry is now
126
+ asked before the row's status is read, on all three terminal paths and on the
127
+ timeout, rather than on `failed` alone — a workflow that catches its refused
128
+ connector call and returns anyway ends `done`, and the criteria would
129
+ otherwise grade an answer produced without the call ever happening.
130
+
131
+ - **`stackbone package` ends `mc`'s flag parsing before the minted MinIO
132
+ password.** A generated password beginning with a dash was read as a flag.
133
+
134
+ - **The CLI sends the bearer of the control plane it is actually calling.** The
135
+ session was picked by `credentials.activeUrl`, a single global pointer, while
136
+ the URL was resolved per invocation from `STACKBONE_API_URL`, the project's
137
+ `.stackbone/project.json` and the global config. On a machine signed in to
138
+ both production and a local stack the two disagreed constantly, so `whoami`,
139
+ `metadata` and `dev` sent one environment's token to another and got a 401
140
+ whose only suggestion — `stackbone login` — could not fix it, because the
141
+ operator was already logged in. Any CLI command run from a second workspace
142
+ rewrote the pointer and broke a session in progress. Sessions are now read
143
+ from `sessions[apiUrl]`, the active organization is keyed the same way,
144
+ `logout` revokes at the URL it prints in `control_plane_url` instead of
145
+ wherever the pointer aimed, and a missing session names the URL:
146
+ `No session for http://localhost:3790` (PLA-797).
147
+
10
148
  ## [0.4.0-alpha.0] - 2026-08-31
11
149
 
12
150
  ### Added