speculos-toolkit 1.1.0 → 1.1.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/README.md CHANGED
@@ -20,6 +20,18 @@ host never runs your build.
20
20
  > https://deploy.speculos.ai). Without an account the backend is skipped and the frontend still
21
21
  > ships free.
22
22
 
23
+ ## Who can see your app
24
+
25
+ | | |
26
+ |---|---|
27
+ | **No account** | the app is **public** — anyone with the link. A private app checks who the visitor is when they open it, and there is no account to check against yet. |
28
+ | **Signed in** | a new app is **private** by default. `--public` shares it, `--org` opens it to your org. |
29
+ | **Already deployed anonymously?** | `speculos-toolkit login` links this machine and your existing apps come with it — then redeploy with `--private`, or flip it on the [dashboard](https://deploy.speculos.ai/dashboard). |
30
+
31
+ `--private` or `--org` without an account fails the deploy (`LOGIN_REQUIRED`)
32
+ rather than publishing something public that you asked to keep private.
33
+ A redeploy never changes the visibility of an app that is already live.
34
+
23
35
  ## What it prints
24
36
 
25
37
  The last line of stdout is a single JSON object:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speculos-toolkit",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "The Speculos toolkit for coding agents — deploy any frontend/backend to a live URL and build against your linked data connectors (BigQuery, Postgres, Snowflake, Salesforce, …). Built for Claude Code, Codex, Cursor, and friends.",
5
5
  "bin": {
6
6
  "speculos-toolkit": "bin/speculos-toolkit.js"
package/skill/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: speculos-toolkit
3
- description: Deploy the current project to a live public URL with Speculos, and build against the user's linked data sources (connectors). Builds the frontend locally, hosts it, wires its API calls to the deployed backend, and reports the URLs. Use when the user says "deploy", "ship it", "publish", "put it live", "get me a URL", "deploy to speculos", "deploy the frontend/backend", or wants an app built on their connected data (BigQuery, Postgres, Snowflake, Salesforce, ...). Handles plain static sites and Vite / Next / CRA / Angular / Svelte frontends; deploys Node/Python/Bun backends once the user has signed in (`speculos-toolkit login`) — one backend app is included with every Speculos account (frontend-only needs no account).
3
+ description: Deploy the current project to a live URL with Speculos (public by default with no account; private once signed in), and build against the user's linked data sources (connectors). Builds the frontend locally, hosts it, wires its API calls to the deployed backend, and reports the URLs. Use when the user says "deploy", "ship it", "publish", "put it live", "get me a URL", "deploy to speculos", "deploy the frontend/backend", or wants an app built on their connected data (BigQuery, Postgres, Snowflake, Salesforce, ...). Handles plain static sites and Vite / Next / CRA / Angular / Svelte frontends; deploys Node/Python/Bun backends once the user has signed in (`speculos-toolkit login`) — one backend app is included with every Speculos account (frontend-only needs no account).
4
4
  ---
5
5
 
6
6
  # Speculos Toolkit
@@ -146,6 +146,9 @@ npx -y speculos-toolkit@latest connectors list --json
146
146
  The last stdout line is `{ ok, brokerUrl, connectors: [{ alias, name, kind, accountIdentifier, tools: [...] }] }`.
147
147
 
148
148
  - `ok:false` + `code:"NO_TOKEN"` → the device isn't logged in; run `login` (step 4) first.
149
+ - `ok:false` + `code:"LOGIN_REQUIRED"` on a deploy → `--private`/`--org` was asked for on a
150
+ machine with no account. Nothing was published. Either run `login` and deploy again, or
151
+ drop the flag (the app ships public) and lock it down after linking.
149
152
  - `ok:true` with empty `connectors` → nothing linked (or nothing granted to this user).
150
153
  If the app clearly wants external data, tell the user to link a source (or ask their org
151
154
  admin for access) at **https://deploy.speculos.ai/dashboard**, then **re-run the list** —
@@ -289,6 +292,23 @@ Builds run locally (this machine already has the toolchain); only static output
289
292
  - Useful flags: `--slug <name>`, `--env KEY=VAL` (repeatable, backend env), `--build`
290
293
  (force the frontend through its build step), `--env-file <file>`.
291
294
 
295
+ ### Who can see the deployed app
296
+
297
+ - **No account -> the app is PUBLIC**, anyone with the link. That is the only
298
+ thing it can be: a private app checks who the visitor is when they open it,
299
+ and there is no account to check against yet. Frontend-only deploys need no
300
+ account and this is the normal path.
301
+ - **Once the machine is linked** (`speculos-toolkit login`), a NEW app is
302
+ **private by default**. Pass `--public` to share it, `--org` for the whole org.
303
+ - `--private` / `--org` from an UNLINKED machine **fails the deploy** with
304
+ `code:"LOGIN_REQUIRED"` before anything is published. It does not quietly
305
+ deploy something public that the user asked to be private. Recovery: run
306
+ `speculos-toolkit login`, then deploy again.
307
+ - Already deployed anonymously and now want it private? `speculos-toolkit login`
308
+ links this machine and its existing apps come with it — then redeploy with
309
+ `--private`, or flip it at https://deploy.speculos.ai/dashboard.
310
+ - A redeploy never changes the visibility of an app that is already live.
311
+
292
312
  The **last line of stdout is one JSON object**:
293
313
  ```json
294
314
  { "ok": true, "userId": "...", "urls": { "frontend": "https://user-deployed.speculos.ai/...", "backend": "https://...daytonaproxy01.net" } }
package/src/index.js CHANGED
@@ -87,9 +87,20 @@ USAGE
87
87
  run one connector tool through the broker
88
88
  (read-only discovery, live queries)
89
89
 
90
- Frontends are hosted FREE at user-deployed.speculos.ai/<userId>/<slugUuid>.
91
- A NEW app is PRIVATE — deploy with --public (or flip it on the dashboard) to
92
- share it. A redeploy never changes the visibility of an app that is already live.
90
+ Frontends are hosted FREE at user-deployed.speculos.ai/<userId>/<slugUuid>,
91
+ with no account and no sign-up.
92
+
93
+ WHO CAN SEE IT
94
+ No account the app is PUBLIC — anyone with the link. That is the only thing
95
+ it can be: a private app checks who you are when someone opens
96
+ it, and there is no account to check against yet.
97
+ Linked a NEW app is PRIVATE by default. --public to share it.
98
+ Already
99
+ deployed? run 'speculos-toolkit login' to link this machine — your existing
100
+ apps come with it — then deploy again with --private, or flip it
101
+ on https://deploy.speculos.ai/dashboard.
102
+
103
+ A redeploy never changes the visibility of an app that is already live.
93
104
  Every Speculos account includes one backend app free (an isolated sandbox per app) —
94
105
  sign up at https://deploy.speculos.ai and run 'speculos-toolkit login'.
95
106
  Without an account a detected backend is skipped (frontend still ships free).
@@ -103,8 +114,9 @@ OPTIONS
103
114
  --build force the frontend through its build step (vs serve as static)
104
115
  --static serve the frontend dir as-is even if it has a build script
105
116
  --no-backend frontend-only: skip backend even if one is detected
106
- --private only you can open the deployed app (DEFAULT for a new app)
107
- --org anyone in your org can open it
117
+ --private only you can open the deployed app (needs an account;
118
+ the DEFAULT for a new app once this machine is linked)
119
+ --org anyone in your org can open it (needs an account)
108
120
  --public anyone with the link can open it, no sign-in
109
121
  --no-frontend backend-only: skip frontend even if one is detected
110
122
  --output <dir> frontend build output dir (dist/build/out — auto-detected)
@@ -187,7 +199,13 @@ async function cmdDeploy(root, opts) {
187
199
  let alloc;
188
200
  try {
189
201
  alloc = await client.allocate({ userId: identity && identity.userId, userKey: identity && identity.userKey, slug: d.slug, visibility: opts.visibility }, opts);
190
- } catch (e) { emit({ ok: false, error: e.message, code: e.code || "ALLOCATE" }); return 1; }
202
+ } catch (e) {
203
+ // Readable first: emit() is JSON for the agent case, but a person who typed
204
+ // --private with no account needs to see WHY in plain words.
205
+ log(opts, `\u2717 ${e.message}`);
206
+ emit({ ok: false, error: e.message, code: e.code || "ALLOCATE" });
207
+ return 1;
208
+ }
191
209
  if (alloc.userKey) { // freshly minted on the server
192
210
  identity = { userId: alloc.userId, userKey: alloc.userKey };
193
211
  creds.saveIdentity(identity);