@stackbone/cli 0.3.5 → 0.4.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/CHANGELOG.md +149 -0
- package/main.js +29895 -15492
- package/migrations/0056_trigger_subscriptions_scope.sql +20 -0
- package/migrations/0057_trigger_subscriptions_fold_mailbox_into_scope.sql +35 -0
- package/migrations/0058_trigger_subscriptions_cursor_column.sql +9 -0
- package/migrations/0059_trigger_subscriptions_last_error.sql +26 -0
- package/migrations/0060_trigger_subscriptions_capped_state.sql +39 -0
- package/migrations/0061_trigger_subscriptions_cursor_held.sql +35 -0
- package/migrations/0062_trigger_deliveries_retention.sql +40 -0
- package/migrations/0063_eval_case_results_not_evaluable.sql +42 -0
- package/migrations/0064_workflow_file_outputs.sql +90 -0
- package/migrations/0065_parked_file_outputs_filing_claim.sql +36 -0
- package/migrations/0066_filed_file_outputs.sql +70 -0
- package/migrations/0067_parked_outputs_carry_a_kind.sql +72 -0
- package/migrations/0068_poll_revision_and_delivery_last_seen.sql +12 -0
- package/migrations/0069_trigger_deliveries_queued_and_starting_status.sql +50 -0
- package/migrations/0070_trigger_deliveries_takeover_count.sql +39 -0
- package/migrations/0071_api_keys.sql +75 -0
- package/migrations/0072_control_plane_identity_mcp_resource.sql +23 -0
- package/package.json +3 -1
- package/stackbone-cli-0.4.0.tgz +0 -0
- package/stackbone-cli-0.3.5.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,155 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-09-10
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **A workflow declares what it sends outward, and `stackbone dev` types it.**
|
|
15
|
+
`export const declaredOutputs = [{ name: 'report', kind: 'file' }, { name:
|
|
16
|
+
'fileIssue', kind: 'action' }]` is a sibling export next to
|
|
17
|
+
`inputSchema`/`outputSchema`, read out of the workflow module or its
|
|
18
|
+
`.contract.ts`. The emulator writes `.stackbone/outputs.d.ts` from it, which
|
|
19
|
+
closes the name sets the SDK's `stackbone.outputs.write` and
|
|
20
|
+
`stackbone.action` accept — naming an action where a file output belongs
|
|
21
|
+
becomes a compile error instead of a run-time `unbound`. The list is read by
|
|
22
|
+
PARSING, never by evaluating: an operator binds a name to a destination before
|
|
23
|
+
any run exists, so a name that only appears once the workflow is running is a
|
|
24
|
+
name nobody can point a destination at, and the parse refuses it where it is
|
|
25
|
+
written, with a line. `kind` is required in source and defaulted on both wires
|
|
26
|
+
(PLA-1092, PLA-1251).
|
|
27
|
+
|
|
28
|
+
- **`.stackbone/connect.d.ts` types the connections the box has registered, not
|
|
29
|
+
just the connectors declared as files.** For seven of the eight built-ins the
|
|
30
|
+
difference is cosmetic, because their operations are a published API. For
|
|
31
|
+
Supabase it is the whole problem: a connection's operations ARE the customer's
|
|
32
|
+
schema, one per table, so they exist in no file and used to be retyped by hand
|
|
33
|
+
off the picker with nothing checking either half. The codegen now also reads
|
|
34
|
+
the box's own management surface. The box introspects and the CLI consumes,
|
|
35
|
+
which is forced rather than chosen — the credential is custodied in the broker
|
|
36
|
+
and Supabase refuses its metadata endpoint to an unauthenticated read. An id
|
|
37
|
+
declared in `connect/*.json` wins on collision, so the existing path stays
|
|
38
|
+
byte-identical.
|
|
39
|
+
|
|
40
|
+
- **`stackbone init` offers the organization's existing workspaces.** It used to
|
|
41
|
+
resolve the workspace by (org, slug) and create on a 404, so a creator who had
|
|
42
|
+
made a workspace in the browser and then ran `init` in a folder of that name
|
|
43
|
+
silently got a second, empty one. When nothing else names the workspace it now
|
|
44
|
+
lists the organization's agents and offers to pick one. The non-interactive
|
|
45
|
+
contract does not move: `--name`, a positional directory, `--json`, `--yes`
|
|
46
|
+
and a missing terminal all skip the listing and the prompt (PLA-1204).
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **BREAKING: `stackbone link` registers a box against one INSTALLATION, named
|
|
51
|
+
by `--installation <id>`, and never creates one.** The deployment registry
|
|
52
|
+
used to hold one row per agent template, while a box answers for exactly one
|
|
53
|
+
installation id and refuses every other with a 401 — so with two installations
|
|
54
|
+
of the same template at most one could be reached. The row now belongs to the
|
|
55
|
+
installation (`POST /api/v1/deployments` requires `installationId`), and
|
|
56
|
+
`link` has to be told which one: `--installation <id>` is one of the linked
|
|
57
|
+
agent's `cloud` rows in `stackbone agents list`. It is validated before the
|
|
58
|
+
box is touched — an id of another agent, an id this organization does not
|
|
59
|
+
hold, or a local-dev id (served by its `stackbone dev` tunnel, never by a
|
|
60
|
+
registered deployment) is refused with no teach and no registration. Without
|
|
61
|
+
the flag, `link` refuses before any network call and names the discovery
|
|
62
|
+
command, except on a `--force` re-run in a directory whose
|
|
63
|
+
`.stackbone/project.json` remembers the id the last link wrote (new field
|
|
64
|
+
`deploymentInstallationId`, named that because it sits next to
|
|
65
|
+
`localDevInstallationId` and the two are different rows; older files still
|
|
66
|
+
load, including one written under the interim `installationId` spelling —
|
|
67
|
+
that key is simply dropped, so the next `link --force` in that directory asks
|
|
68
|
+
for `--installation` once and rewrites the file. Nothing has to migrate it).
|
|
69
|
+
`link` no longer creates a cloud
|
|
70
|
+
installation when the agent has none — install the agent first. When the
|
|
71
|
+
target installation already answers somewhere, `link` prints the address it
|
|
72
|
+
is about to replace before proceeding. The JSON envelope keeps
|
|
73
|
+
`installation {id, organization_id, kind}` and drops `deployment_reachable`,
|
|
74
|
+
which could only ever say `reachable: true` now that a local-dev target is
|
|
75
|
+
refused up front (PLA-853).
|
|
76
|
+
|
|
77
|
+
### Removed
|
|
78
|
+
|
|
79
|
+
- **BREAKING: `stackbone runs retry` is gone.** `POST /api/runs/:id/retry`
|
|
80
|
+
copied the failed run's input, inserted a fresh `running` row and published
|
|
81
|
+
`run.created` so Studio repainted — and stopped there. Nothing ever advanced
|
|
82
|
+
that row, because nothing dispatched the payload to the agent. Three surfaces
|
|
83
|
+
sold it as real anyway, this verb among them, gated behind `--yes` as if it
|
|
84
|
+
were destructive. The route now answers 404 and a test pins it there, so the
|
|
85
|
+
placebo cannot come back without a dispatch behind it. Nothing is lost: the
|
|
86
|
+
action never did anything (PLA-949).
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- **`stackbone eval` counts `not_evaluable` as an ending, and a swallowed
|
|
91
|
+
refusal no longer grades as a quality regression.** The CLI holds a twin of
|
|
92
|
+
Studio's ending list and only Studio's had been widened, so the same run got
|
|
93
|
+
one verdict in CI and another in the browser. The connector registry is now
|
|
94
|
+
asked before the row's status is read, on all three terminal paths and on the
|
|
95
|
+
timeout, rather than on `failed` alone — a workflow that catches its refused
|
|
96
|
+
connector call and returns anyway ends `done`, and the criteria would
|
|
97
|
+
otherwise grade an answer produced without the call ever happening.
|
|
98
|
+
|
|
99
|
+
- **`stackbone package` ends `mc`'s flag parsing before the minted MinIO
|
|
100
|
+
password.** A generated password beginning with a dash was read as a flag.
|
|
101
|
+
|
|
102
|
+
- **The CLI sends the bearer of the control plane it is actually calling.** The
|
|
103
|
+
session was picked by `credentials.activeUrl`, a single global pointer, while
|
|
104
|
+
the URL was resolved per invocation from `STACKBONE_API_URL`, the project's
|
|
105
|
+
`.stackbone/project.json` and the global config. On a machine signed in to
|
|
106
|
+
both production and a local stack the two disagreed constantly, so `whoami`,
|
|
107
|
+
`metadata` and `dev` sent one environment's token to another and got a 401
|
|
108
|
+
whose only suggestion — `stackbone login` — could not fix it, because the
|
|
109
|
+
operator was already logged in. Any CLI command run from a second workspace
|
|
110
|
+
rewrote the pointer and broke a session in progress. Sessions are now read
|
|
111
|
+
from `sessions[apiUrl]`, the active organization is keyed the same way,
|
|
112
|
+
`logout` revokes at the URL it prints in `control_plane_url` instead of
|
|
113
|
+
wherever the pointer aimed, and a missing session names the URL:
|
|
114
|
+
`No session for http://localhost:3790` (PLA-797).
|
|
115
|
+
|
|
116
|
+
## [0.4.0-alpha.0] - 2026-08-31
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
|
|
120
|
+
- **`stackbone package --target byoc | self-host` picks which folder the command
|
|
121
|
+
writes.** It used to write one artifact, the two-service self-host stack.
|
|
122
|
+
`byoc` is the default and the historic folder — the agent alone, registered
|
|
123
|
+
from app.stackbone.ai — while `self-host` keeps the control plane and Studio
|
|
124
|
+
beside it. The exclusion is the point, not a convenience: a box that finds
|
|
125
|
+
`STUDIO_STANDALONE_TOKEN` on its boot env authenticates the operator by static
|
|
126
|
+
bearer and turns the browser identity gate off, so a BYOC folder carrying that
|
|
127
|
+
variable would be a box anyone holding one string could drive, with every
|
|
128
|
+
container still healthy. The BYOC inputs have no field to write it into
|
|
129
|
+
(PLA-1056).
|
|
130
|
+
|
|
131
|
+
- **The `self-host` target generates both application services.** The shipped
|
|
132
|
+
Compose started the control plane, Postgres, Redis and MinIO and no agent at
|
|
133
|
+
all, so nothing served the box-owned routes Studio needs. It now brings up the
|
|
134
|
+
control plane with the Studio SPA and the workspace image beside it, on
|
|
135
|
+
separate configurable host ports, sharing one database, one `HMAC_SECRET` and
|
|
136
|
+
one operator token, with health checks and real startup ordering. The control
|
|
137
|
+
plane addresses the box as `http://agent:8080`, its Compose service name
|
|
138
|
+
(PLA-1069).
|
|
139
|
+
|
|
140
|
+
### Changed
|
|
141
|
+
|
|
142
|
+
- **The offline archives are named apart.** `agent-image.tar` carries one image
|
|
143
|
+
and never pulls a control plane; `stackbone-images.tar` carries both. A script
|
|
144
|
+
that hardcoded the single old name has to pick the one its target writes.
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- **A rejected payload prints the fields it names, not just the sentence.**
|
|
149
|
+
`stackbone secrets set` printed `Request body failed schema validation.` and
|
|
150
|
+
nothing else, because the per-field detail rides under `details.issues` and
|
|
151
|
+
the reader took only `message`. It now prints the server's sentence followed
|
|
152
|
+
by one ` - name: Required` line per offending field, three at most and then a
|
|
153
|
+
` (+<n> more)` line. A refusal carrying no issues prints its sentence
|
|
154
|
+
byte-for-byte, and a malformed or non-JSON body still prints `HTTP <status>`.
|
|
155
|
+
A local `ZodError` renders through the same bound, so the CLI's own rejections
|
|
156
|
+
and the box's read alike. SSE and multipart inherit it through the same
|
|
157
|
+
function (PLA-1044).
|
|
158
|
+
|
|
10
159
|
## [0.3.5] - 2026-08-27
|
|
11
160
|
|
|
12
161
|
### Added
|