@tabbio-technologies/cli 1.2.8 → 1.3.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.
Files changed (27) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +86 -19
  3. package/dist/chunks/{chunk-7LNC3FIV.js → chunk-GGJEDG3P.js} +95 -14
  4. package/dist/chunks/{chunk-7LNC3FIV.js.map → chunk-GGJEDG3P.js.map} +4 -4
  5. package/dist/chunks/{chunk-Y6GWIFHI.js → chunk-KBIQKZUK.js} +3 -53
  6. package/dist/chunks/chunk-KBIQKZUK.js.map +7 -0
  7. package/dist/chunks/{chunk-QVR5KIEQ.js → chunk-KHLGZ5IV.js} +1796 -244
  8. package/dist/chunks/chunk-KHLGZ5IV.js.map +7 -0
  9. package/dist/chunks/{chunk-NAWA6NCZ.js → chunk-NRFVKK3S.js} +37 -96
  10. package/dist/chunks/chunk-NRFVKK3S.js.map +7 -0
  11. package/dist/chunks/chunk-TP3CRQJD.js +106 -0
  12. package/dist/chunks/chunk-TP3CRQJD.js.map +7 -0
  13. package/dist/chunks/{entry-WENOOT6W.js → entry-ZAXWZSEE.js} +2023 -770
  14. package/dist/chunks/entry-ZAXWZSEE.js.map +7 -0
  15. package/dist/chunks/{mount-NGUARMCL.js → mount-36JUVX3R.js} +3 -2
  16. package/dist/chunks/{mount-NGUARMCL.js.map → mount-36JUVX3R.js.map} +1 -1
  17. package/dist/chunks/{program-O2BA5L6Z.js → program-J6GENE2V.js} +314 -375
  18. package/dist/chunks/program-J6GENE2V.js.map +7 -0
  19. package/dist/chunks/{status-I5UAQPBY.js → status-2C7BECKK.js} +3 -3
  20. package/dist/cli.js +1 -1
  21. package/package.json +4 -8
  22. package/dist/chunks/chunk-NAWA6NCZ.js.map +0 -7
  23. package/dist/chunks/chunk-QVR5KIEQ.js.map +0 -7
  24. package/dist/chunks/chunk-Y6GWIFHI.js.map +0 -7
  25. package/dist/chunks/entry-WENOOT6W.js.map +0 -7
  26. package/dist/chunks/program-O2BA5L6Z.js.map +0 -7
  27. /package/dist/chunks/{status-I5UAQPBY.js.map → status-2C7BECKK.js.map} +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ ## 1.3.1 - 2026-09-27
4
+
5
+ ### Fixed
6
+
7
+ - Remove private repository and issue tracker links from the public npm package metadata.
8
+
9
+ ## 1.3.0 - 2026-09-27
10
+
11
+ ### Added
12
+
13
+ - Sign in and out from the interactive home and chat screens.
14
+ - Result cards for jobs, applications, CVs, skills, automations, and generated files.
15
+ - Save generated pages, documents, slides, images, and CV exports to disk, with chat commands to open and inspect them.
16
+ - Apply to a job from its numbered result card and open related links from chat.
17
+
18
+ ### Changed
19
+
20
+ - Use `--remember` for chat mode preferences; `--no-save` controls generated file saving.
21
+ - Keep bare or unknown slash commands in the command palette instead of sending them to the agent.
22
+
23
+ ### Fixed
24
+
25
+ - Suppress repeated text in streamed answers and persist the trimmed answer on the API.
26
+ - Wait for the `/threads` screen state in the terminal UI test instead of relying on a fixed delay.
27
+ - Save generated files in non-interactive chat, report save failures in NDJSON, and surface document PDF download errors.
28
+ - Return a failing exit status for partial agent errors and failed automatic saves; save the exact artifact version produced by each tool.
29
+ - Stop interactive file downloads when chat closes or the account changes.
30
+
31
+ ### Security
32
+
33
+ - Create saved artifact folders and downloaded files with private local permissions.
34
+ - Strip terminal controls from streamed answers, research sources, and other server-provided labels.
35
+
36
+ ## 1.2.8 - 2026-09-26
37
+
38
+ ### Added
39
+
40
+ - Browser and email sign-in using the Tabbio app session.
41
+ - MCP tool commands, streaming agent chat, approvals, and artifact commands.
42
+ - Machine-readable output and a stdio MCP bridge for other clients.
43
+
44
+ ### Security
45
+
46
+ - Direct MCP tool calls use server-side credit metering and approval checks.
47
+ - The CLI does not create personal MCP tokens for app-session sign-in.
package/README.md CHANGED
@@ -10,7 +10,7 @@ It is a thin client. Every capability comes from the same API the Tabbio apps
10
10
  use, over the same authentication, so the CLI can never do more than you can do
11
11
  in the app.
12
12
 
13
- Version 1.2.8. Where this guide and the code disagree, the code is right.
13
+ Version 1.3.1. Where this guide and the code disagree, the code is right.
14
14
 
15
15
  - [Install](#install)
16
16
  - [First run](#first-run)
@@ -191,6 +191,26 @@ personal token, it only deletes the local copy: the token itself stays valid,
191
191
  because other clients may use it. Revoke it in Settings › MCP Access if you
192
192
  want it gone.
193
193
 
194
+ ### Inside the app: `/login` and `/logout`
195
+
196
+ `tabbio` opens the home screen even when you are not signed in: the account
197
+ line says **Not signed in**, the palette offers `/login`, `/help` and `/exit`,
198
+ and `/chat`, `/tools`, `/approvals` and `/status` answer "Sign in first:
199
+ /login" instead of failing. `/login` works on the home screen and in a chat,
200
+ without leaving the app:
201
+
202
+ | Command | Method |
203
+ |---|---|
204
+ | `/login` | A chooser: open the browser (recommended), email code, or personal token |
205
+ | `/login browser` | Opens the approval page and waits; the link is shown too, and Esc cancels |
206
+ | `/login email you@example.com` | Sends a 6-digit code and asks for it in place (three tries) |
207
+ | `/login token` | Asks for a personal MCP token (masked) and checks it against the tool list |
208
+ | `/logout` | Ends the session on the server, deletes this profile's credentials and returns to the signed-out home screen |
209
+
210
+ They use the same flows and the same credential store as `tabbio login` and
211
+ `tabbio logout`, and the home screen, the plan, the tool count and your skills
212
+ refresh for the new account right away.
213
+
194
214
  ## Commands
195
215
 
196
216
  ```
@@ -209,7 +229,7 @@ tabbio workflows says that workflows are not exposed ove
209
229
  tabbio approvals [list] [--json] ; approvals show <id> ; approvals approve <id> [--reason r] [--wait] ; approvals reject <id> [--reason r] ; approvals wait <id> [--timeout 10m]
210
230
  tabbio artifacts [list] [--kind k] [--status s] ; artifacts get|open|versions|delete|wait <id> ; artifacts download <id> [--format f] [--out p] [--force] [--wait] ; artifacts restore <id> <versionId>
211
231
  tabbio ask "<question>" [--mode m] [--via-mcp] [--json] one question through the chat stream (app session)
212
- tabbio chat [message] [--mode seeker|employer] [--company <id>] [--thread <id>] [--model <id>] [--research auto|on|off] [--image auto|on|off] [--result auto|summary|document|slides|page|image] [--save] [--json]
232
+ tabbio chat [message] [--mode seeker|employer] [--company <id>] [--thread <id>] [--model <id>] [--research auto|on|off] [--image auto|on|off] [--result auto|summary|document|slides|page|image] [--remember] [--no-save] [--json]
213
233
  tabbio mcp serve [--profile p] stdio ↔ remote MCP bridge for stdio-only clients
214
234
  tabbio mcp url prints the MCP URL for `claude mcp add`
215
235
  tabbio completion bash|zsh|fish
@@ -347,9 +367,14 @@ tabbio ask "Summarise my application pipeline" --json
347
367
 
348
368
  One question, one answer. With an app session (browser or email sign-in) the
349
369
  question goes through the chat stream (`POST /api/agent/chat`), exactly like a
350
- one-message `tabbio chat`: the answer streams, sources and files are listed,
351
- and it is metered like any chat reply. It sends the profile's saved research,
352
- image and result choice.
370
+ one-message `tabbio chat`: the answer streams, tool results print as the app's
371
+ cards (numbered jobs with their apply links, CVs with `/download <id>`,
372
+ skills as `/<skill-id>`), sources are listed, and it is metered like any chat
373
+ reply. It sends the profile's saved research, image and result choice.
374
+
375
+ Files the answer makes (pages, documents, slide decks, images) and CV exports
376
+ are saved to `./tabbio-artifacts` (see [Saved files](#saved-files)); `--no-save`
377
+ skips that.
353
378
 
354
379
  With a personal token, or with `--via-mcp`, it looks for the MCP ask tool
355
380
  (`ask_tabbio`) instead. Today's server does not offer that tool (the MCP
@@ -365,16 +390,43 @@ tabbio chat --mode employer --company cmp_456
365
390
  ```
366
391
 
367
392
  Streaming chat with the Tabbio agent, rendered as Markdown, with one-line
368
- tool-call rows (`ctrl+o` expands them) and inline approval prompts. Inside
369
- chat, `/new`, `/threads`, `/mode`, `/model`, `/research`, `/image`,
370
- `/result`, `/help` and `/exit` are available. With `--json`, chat prints the
371
- stream as NDJSON: one JSON event per line, exactly as the server sent it
372
- (including event types this version does not know). Needs a full sign-in.
393
+ tool-call rows (`ctrl+o` expands the raw result) and inline approval prompts.
394
+ A result the app shows as a card prints as one under its row: numbered rows,
395
+ dim details, links (clickable where the terminal supports it, and always
396
+ printed as plain URLs so they can be copied) and the next step, such as
397
+ `/open 2` or `/apply 2` for a job or `/download <id>` for a CV. Files Tabbio
398
+ makes and CV exports are saved to `./tabbio-artifacts` as soon as they are
399
+ ready, with the path, the size and the first lines of a page or document
400
+ (`--no-save` or `TABBIO_NO_ARTIFACT_SAVE=1` turn that off). Inside
401
+ chat, the slash commands below are available. With `--json`, chat prints
402
+ NDJSON: one server event per line (including unknown event types), followed
403
+ by a local `files-saved` event for each generated file or CV export. A
404
+ `files-saved` event includes the saved paths or an error; save errors make
405
+ the command exit nonzero. Needs a full sign-in.
406
+
407
+ | Slash command | What it does |
408
+ |---|---|
409
+ | `/` | Opens the palette: the commands, then your Tabbio skills under **Skills** (loaded once per session). A bare `/` is never sent to the agent; Esc clears it. |
410
+ | `/<skill> [details]` | Runs one of your skills exactly like the app does (`/cv-health-check`). A `/name` that is neither a command nor a skill shows a notice and is not sent. |
411
+ | `/new`, `/threads` | Start a new chat, or resume a recent one |
412
+ | `/mode seeker\|employer`, `/model <id\|auto>` | Switch workspace or model |
413
+ | `/research`, `/image`, `/result` | Research, image and result modes (see below) |
414
+ | `/open <n>` | Opens link `n` of the last result card in the browser; the URL is printed as well |
415
+ | `/open <id>` | Opens a file Tabbio made (a 15-minute preview link) |
416
+ | `/apply <n>` | Asks Tabbio to prepare your application for job `n` of the last job result |
417
+ | `/save <id> [folder]` | Saves a file Tabbio made into `./tabbio-artifacts` (or the folder) |
418
+ | `/show <id>` | Prints a saved page or document in the terminal (saves it first when needed) |
419
+ | `/download [cvId] [pdf\|docx\|txt\|md]` | Saves a CV export; without an id, your main CV |
420
+ | `/login [email you@x.com\|token]`, `/logout` | Sign in or out without leaving the app (see [Signing in](#signing-in)) |
421
+ | `/help`, `/home`, `/exit` | Keys and commands, back to the home screen, quit |
422
+
423
+ Esc interrupts a reply, clears the composer, or goes back to the home screen;
424
+ Ctrl+C twice quits from any screen.
373
425
 
374
426
  ```sh
375
427
  tabbio chat --research on "What changed in UAE labour law this year? Two sources."
376
428
  tabbio chat --result document "A one-page brief on my job search"
377
- tabbio chat --result page --save # every chat on this profile asks for pages until changed
429
+ tabbio chat --result page --remember # every chat on this profile asks for pages until changed
378
430
  ```
379
431
 
380
432
  See [Research, documents, pages and images](#research-documents-pages-and-images).
@@ -387,7 +439,7 @@ tabbio artifacts list --kind document --json
387
439
  tabbio artifacts get art_123
388
440
  tabbio artifacts open art_123 # prints a 15-minute link and opens it (on a terminal)
389
441
  tabbio artifacts open art_123 --variant pdf --print
390
- tabbio artifacts download art_123 # ./<title>.pdf (documents), .pptx (slides), .html (pages), the image
442
+ tabbio artifacts download art_123 # ./tabbio-artifacts/<title>-<id>.pdf (documents), .pptx (slides), .html (pages), the image
391
443
  tabbio artifacts download art_123 --format html --out ~/Downloads --force
392
444
  tabbio artifacts wait art_123 --timeout 2m # exit 0 ready, 1 failed, 7 still rendering
393
445
  tabbio artifacts versions art_123
@@ -396,8 +448,10 @@ tabbio artifacts delete art_123 --yes
396
448
  ```
397
449
 
398
450
  The documents, slide decks, pages and images Tabbio made for you. `download`
399
- never overwrites a file unless you pass `--force`, writes through a temporary
400
- file, and names the file after the title. It fetches a signed link (15
451
+ saves into `./tabbio-artifacts` (or `TABBIO_ARTIFACTS_DIR`) unless `--out`
452
+ says otherwise, prints the path, never overwrites a file (a taken name gets
453
+ `-2`; with `--out`, it stops unless you pass `--force`), writes through a
454
+ temporary file, and names the file after the title. It fetches a signed link (15
401
455
  minutes) without sending your session to the storage host. `delete` asks
402
456
  first unless `--yes` (and a published site of that file goes offline). Needs a
403
457
  full sign-in; with a personal token, `tabbio artifact list|get|read` reach the
@@ -438,8 +492,8 @@ The output format is chosen in this order:
438
492
  | `--plain` | Tab-separated values, no colour. |
439
493
  | `--fields a,b` | Only these fields (tables, plain and JSON). |
440
494
 
441
- `tabbio chat --json` is the exception: it writes NDJSON, one stream event per
442
- line.
495
+ `tabbio chat --json` is the exception: it writes NDJSON, one event per line,
496
+ including local `files-saved` events after the server stream.
443
497
 
444
498
  Colour is decided in this order: `--color` / `--no-color`, then `FORCE_COLOR`,
445
499
  then `NO_COLOR`, then `CLICOLOR_FORCE` / `CLICOLOR`, then `TERM=dumb` (no
@@ -491,6 +545,16 @@ Files live in `$TABBIO_CONFIG_DIR`, else `$XDG_CONFIG_HOME/tabbio`, else
491
545
  The tool catalog cache, update-check stamp and recent-runs history live in
492
546
  `$TABBIO_CACHE_DIR`, else `$XDG_CACHE_HOME/tabbio`, else `~/.cache/tabbio`.
493
547
 
548
+ ### Saved files
549
+
550
+ `chat` and `ask` save what Tabbio makes as soon as it is ready: a page as
551
+ `.html`, a document as `.html` and `.pdf`, slides as `.pptx`, an image as its
552
+ own format, and a CV export as the PDF (or the format you asked for). Files go
553
+ to `TABBIO_ARTIFACTS_DIR`, else `./tabbio-artifacts` in the current directory,
554
+ named `<title>-<last 6 characters of the id>.<ext>`, and are never
555
+ overwritten (`-2`, `-3`). `--no-save` or `TABBIO_NO_ARTIFACT_SAVE=1` turn it
556
+ off.
557
+
494
558
  Other environment variables:
495
559
 
496
560
  | Variable | Effect |
@@ -498,6 +562,8 @@ Other environment variables:
498
562
  | `TABBIO_OUTPUT` | Default output format: `json`, `table` or `plain`. |
499
563
  | `TABBIO_THEME` | `light` or `dark`, when the accent colour guesses the terminal background wrong. |
500
564
  | `TABBIO_DEBUG=1` | Same as `--debug`. |
565
+ | `TABBIO_ARTIFACTS_DIR` | Where `chat`, `ask` and `artifacts download` save files. Default: `./tabbio-artifacts`. |
566
+ | `TABBIO_NO_ARTIFACT_SAVE=1` | Do not save files from `chat` and `ask` (same as `--no-save`). |
501
567
  | `TABBIO_DEVICE_LABEL` | The name this computer shows on the sign-in page and in your sessions. Defaults to the hostname. |
502
568
  | `TABBIO_NO_UPDATE_CHECK=1` | Skip the once-a-day check for a newer version on npm (printed on stderr). Also skipped under `CI`. |
503
569
  | `TABBIO_ALLOW_INSECURE_HTTP=1` | Allow plain `http://` API URLs other than localhost. Development only. |
@@ -595,7 +661,7 @@ controls under the app's message box:
595
661
  They are sent with every message in seeker chats, together with your
596
662
  timezone (`Intl` timezone, so "today" and the daily limits follow your day).
597
663
  Employer chats do not send them; the server ignores them there. Flags apply to
598
- one run; `/research on` in the chat and `tabbio chat … --save` remember the
664
+ one run; `/research on` in the chat and `tabbio chat … --remember` remember the
599
665
  choice for the profile (`profiles.<name>.capabilities` in `config.json`). The
600
666
  status bar shows every control you changed from `auto`. If your account
601
667
  cannot use a control you switched on (the server has it off, you are outside
@@ -617,13 +683,14 @@ What you see in the chat:
617
683
  - **Limits** (daily quota, plan tier, a switched-off feature) as a dim line
618
684
  under the tool row with the reason.
619
685
 
620
- `tabbio chat --json` passes every event through, including `artifact-draft`
686
+ `tabbio chat --json` passes every server event through, including `artifact-draft`
621
687
  (the streaming writer's progress). Research sources are in the
622
688
  `tool-result` payloads of `webSearch`, `readUrl`, `readPdf`,
623
689
  `readGithubRepo` and `readSkill` (`result.sources`); files are in the
624
690
  `tool-result` payloads of `createDocument`, `createPage`, `generateImage`,
625
691
  `updatePage`, `updateDocument` and `editImage` (`result.artifactId`,
626
- `result.status`: `pending`, `ready` or `failed`).
692
+ `result.status`: `pending`, `ready` or `failed`). Generated files also produce
693
+ local `files-saved` events after the turn unless `--no-save` is set.
627
694
 
628
695
  Over MCP (`tabbio research …`, `tabbio artifact …`, `tabbio site …`), the
629
696
  file tools and `site publish` always need your approval first, because they
@@ -744,7 +744,7 @@ function warn(message, hint) {
744
744
  // src/core/version.ts
745
745
  import { readFileSync as readFileSync2 } from "node:fs";
746
746
  import { join as join3 } from "node:path";
747
- var CLI_VERSION = true ? "1.2.8" : readPackageField("version") ?? "0.0.0-dev";
747
+ var CLI_VERSION = true ? "1.3.1" : readPackageField("version") ?? "0.0.0-dev";
748
748
  var CLI_PACKAGE_NAME = true ? "@tabbio-technologies/cli" : readPackageField("name") ?? "@tabbio-technologies/cli";
749
749
  function userAgent() {
750
750
  return `tabbio-cli/${CLI_VERSION} node/${process.versions.node} ${process.platform}-${process.arch}`;
@@ -1653,23 +1653,58 @@ function paletteCss() {
1653
1653
  function escapeHtml(value) {
1654
1654
  return value.replace(/[&<>"']/g, (c) => `&#${c.charCodeAt(0)};`);
1655
1655
  }
1656
+ var NEXT_STEPS = [
1657
+ ["tabbio", "home: chat, tools, approvals"],
1658
+ ["tabbio chat", "talk to Tabbio in the terminal"],
1659
+ ["/logout", "sign out again, from inside the app"]
1660
+ ];
1661
+ var RETRY_STEPS = [
1662
+ ["/login", "try again from the app (tabbio)"],
1663
+ ["tabbio login --email you@example.com", "sign in with a code instead"]
1664
+ ];
1656
1665
  function renderLoopbackPage(kind, message) {
1657
- const title = kind === "success" ? "Tabbio CLI connected" : "Tabbio CLI sign-in";
1658
- const heading2 = kind === "success" ? "You are signed in to the Tabbio CLI" : "Sign-in did not finish";
1659
- const mark = kind === "success" ? "&#10003;" : "!";
1666
+ const ok = kind === "success";
1667
+ const title = ok ? "Tabbio CLI connected" : "Tabbio CLI sign-in";
1668
+ const heading2 = ok ? "Connected." : "Not signed in.";
1669
+ const lead = ok ? "This computer is signed in to Tabbio." : "The terminal is still waiting, or the sign-in was stopped.";
1670
+ const list = ok ? NEXT_STEPS : RETRY_STEPS;
1671
+ const stacked = list.some(([command]) => command.length > 20);
1672
+ const steps = list.map(([command, what]) => `<dt><code>${escapeHtml(command)}</code></dt><dd>${escapeHtml(what)}</dd>`).join("");
1660
1673
  return `<!doctype html>
1661
1674
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
1662
- <meta name="referrer" content="no-referrer"><title>${title}</title>
1675
+ <meta name="referrer" content="no-referrer"><meta name="color-scheme" content="light dark"><title>${title}</title>
1663
1676
  <style>
1664
1677
  ${paletteCss()}
1665
- *{box-sizing:border-box}body{margin:0;min-height:100vh;display:grid;place-items:center;background:var(--bg);color:var(--fg);
1666
- font:16px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;padding:24px}
1667
- main{max-width:420px;width:100%;background:var(--card);border:1px solid var(--line);border-radius:16px;padding:32px;text-align:start}
1668
- .mark{width:40px;height:40px;border-radius:12px;display:grid;place-items:center;background:var(--accent);color:var(--on-accent);font-weight:700;margin-bottom:16px}
1669
- h1{font-size:20px;margin:0 0 8px}p{margin:0;color:var(--muted)}.brand{font-weight:600;color:var(--accent);margin-bottom:24px;font-size:14px}
1678
+ *{box-sizing:border-box}
1679
+ html{background:var(--bg)}
1680
+ body{margin:0;min-height:100vh;background:var(--bg);color:var(--fg);-webkit-font-smoothing:antialiased;
1681
+ font:16px/1.55 system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}
1682
+ main{max-width:600px;padding-block:min(14vh,120px) 48px;padding-inline:clamp(20px,6vw,56px)}
1683
+ code,.tag{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace}
1684
+ .tag{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--muted);letter-spacing:.02em}
1685
+ .dot{width:8px;height:8px;border-radius:50%;background:${ok ? "var(--accent)" : "transparent"};box-shadow:inset 0 0 0 1.5px ${ok ? "var(--accent)" : "var(--muted)"}}
1686
+ h1{font-size:clamp(34px,6vw,44px);line-height:1.1;letter-spacing:-.025em;font-weight:650;margin:40px 0 14px}
1687
+ .lead{font-size:18px;margin:0 0 6px}
1688
+ .note{color:var(--muted);margin:0}
1689
+ hr{border:0;border-top:1px solid var(--line);margin:36px 0 22px}
1690
+ h2{font:500 12px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:0 0 14px}
1691
+ dl{display:grid;grid-template-columns:max-content 1fr;gap:10px 24px;margin:0}
1692
+ dt{margin:0}dd{margin:0;color:var(--muted)}
1693
+ dt code{font-size:14px;color:var(--fg)}
1694
+ footer{margin-top:44px;font-size:13px;color:var(--muted)}
1695
+ dl.stack{grid-template-columns:1fr;gap:2px}dl.stack dd{margin-bottom:14px}
1696
+ @media (max-width:480px){dl{grid-template-columns:1fr;gap:2px}dd{margin-bottom:12px}}
1670
1697
  </style></head>
1671
- <body><main><div class="brand">tabbio</div><div class="mark">${mark}</div><h1>${escapeHtml(heading2)}</h1>
1672
- <p dir="auto">${escapeHtml(message)}</p></main></body></html>`;
1698
+ <body><main>
1699
+ <div class="tag"><span class="dot" aria-hidden="true"></span>tabbio cli</div>
1700
+ <h1>${escapeHtml(heading2)}</h1>
1701
+ <p class="lead">${escapeHtml(lead)}</p>
1702
+ <p class="note" dir="auto">${escapeHtml(message)}</p>
1703
+ <hr>
1704
+ <h2>${ok ? "Next, in your terminal" : "In your terminal"}</h2>
1705
+ <dl${stacked ? ' class="stack"' : ""}>${steps}</dl>
1706
+ <footer>This page was served by the tabbio CLI on this computer (127.0.0.1).</footer>
1707
+ </main></body></html>`;
1673
1708
  }
1674
1709
  function send(res, status, html) {
1675
1710
  res.writeHead(status, {
@@ -1950,6 +1985,48 @@ async function logoutProfile(profile, creds, opts = {}) {
1950
1985
  return { warnings, revokedSession };
1951
1986
  }
1952
1987
 
1988
+ // src/core/context.ts
1989
+ function readGlobalOptions(cmd) {
1990
+ const raw = cmd ? cmd.optsWithGlobals() : {};
1991
+ const current = getGlobalOptions();
1992
+ return setGlobalOptions({
1993
+ profile: raw.profile ?? current.profile,
1994
+ apiUrl: raw.apiUrl ?? current.apiUrl,
1995
+ appUrl: raw.appUrl ?? current.appUrl,
1996
+ json: Boolean(raw.json ?? current.json),
1997
+ color: raw.color ?? current.color,
1998
+ debug: Boolean(raw.debug ?? current.debug),
1999
+ yes: Boolean(raw.yes ?? current.yes),
2000
+ quiet: Boolean(raw.quiet ?? current.quiet)
2001
+ });
2002
+ }
2003
+ function createCommandContext(cmd) {
2004
+ const globals2 = readGlobalOptions(cmd);
2005
+ const { profile, sources } = resolveProfileWithSources({
2006
+ profile: globals2.profile,
2007
+ apiUrl: globals2.apiUrl,
2008
+ appUrl: globals2.appUrl
2009
+ });
2010
+ const credentials = loadCredentials(profile.name);
2011
+ const api = new ApiClient(profile, credentials);
2012
+ let session = null;
2013
+ return {
2014
+ globals: globals2,
2015
+ profile,
2016
+ sources,
2017
+ credentials,
2018
+ api,
2019
+ interactive: isInteractive() && !globals2.json,
2020
+ mcp() {
2021
+ session ??= McpSession.connect(profile, api.credentials ?? credentials, { api });
2022
+ return session;
2023
+ },
2024
+ async close() {
2025
+ if (session) await (await session.catch(() => null))?.close();
2026
+ }
2027
+ };
2028
+ }
2029
+
1953
2030
  export {
1954
2031
  ExitCode,
1955
2032
  EXIT_CODE_DOCS,
@@ -1967,6 +2044,7 @@ export {
1967
2044
  heading,
1968
2045
  relativeTime,
1969
2046
  DEFAULT_PROFILE,
2047
+ PRODUCTION_APP_URL,
1970
2048
  PROFILE_PRESETS,
1971
2049
  configPaths,
1972
2050
  loadConfig,
@@ -1994,6 +2072,7 @@ export {
1994
2072
  CLI_PACKAGE_NAME,
1995
2073
  checkForUpdate,
1996
2074
  readRequestId,
2075
+ combineSignals,
1997
2076
  ApiClient,
1998
2077
  parseJsonResponse,
1999
2078
  PRIMARY_AGENT_KEY,
@@ -2014,6 +2093,8 @@ export {
2014
2093
  getMcpAccessState,
2015
2094
  revokeSession,
2016
2095
  credentialsFromLogin,
2017
- logoutProfile
2096
+ logoutProfile,
2097
+ readGlobalOptions,
2098
+ createCommandContext
2018
2099
  };
2019
- //# sourceMappingURL=chunk-7LNC3FIV.js.map
2100
+ //# sourceMappingURL=chunk-GGJEDG3P.js.map