@koda-sl/baker-cli 0.542.0 → 0.543.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.
@@ -45,6 +45,12 @@ function publishHints(publish) {
45
45
  }
46
46
  return hints;
47
47
  }
48
+ function stillPublishingHints(status) {
49
+ if (status !== "publishing") return [];
50
+ return [
51
+ "This Session is still publishing: its changes are not live yet. Work that has to wait for it (a check on the live page, a test lead) is a Scheduled agent staged now with `baker scheduled-agents create --run-at <time>`, whose brief first checks this Session went live. It exists only once your own chat is published: a page trigger staged now misses this Session's publish, and a `--run-at` that has passed by then is created switched off, so leave hours of headroom, not minutes, and tell the user it runs only once they publish this chat. Never ask the user to come back and tell you when it is done."
52
+ ];
53
+ }
48
54
 
49
55
  // src/commands/chats/index.ts
50
56
  var STATUS_GROUPS = ["active", "archived", "all"];
@@ -163,6 +169,7 @@ var viewCommand = defineCommand({
163
169
  "This Session is still in progress \u2014 read its current file changes with `baker chats diff <id> --live`."
164
170
  );
165
171
  }
172
+ hints.push(...stillPublishingHints(response.data.status));
166
173
  hints.push("Read the conversation with `baker chats transcript <id>`.");
167
174
  writeJson({ ...response, hints });
168
175
  } catch (err) {
@@ -439,4 +446,4 @@ Full guide: __tooling__/docs/tools/baker/chats.md`
439
446
  export {
440
447
  chatsCommand
441
448
  };
442
- //# sourceMappingURL=chats-HNOUUEII.js.map
449
+ //# sourceMappingURL=chats-A3XSSBJF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/chats/index.ts","../src/commands/chats/publish-hints.ts"],"sourcesContent":["import type { ChatsDiffResponse, ChatsListResponse, ChatsTranscriptResponse, ChatsViewResponse } from \"@baker/api\";\nimport { CHAT_IMPORT_SURFACES, type ChatsImportResponse } from \"@baker/api/chats\";\n\ntype ChatImportSurface = (typeof CHAT_IMPORT_SURFACES)[number];\n\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { getEnv, requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi } from \"../actions/shared.ts\";\nimport { publishHints, stillPublishingHints } from \"./publish-hints.ts\";\n\nconst STATUS_GROUPS = [\"active\", \"archived\", \"all\"] as const;\nconst REPO_SURFACES = [\"knowledge\", \"company\", \"brand\", \"landings\", \"flows\", \"creatives\"] as const;\n\nfunction parseBoundedInt(raw: string | undefined, name: string, min: number, max: number): number | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const value = Number.parseInt(raw, 10);\n if (Number.isNaN(value) || value < min || value > max) {\n throw new Error(`--${name} must be an integer between ${min} and ${max}`);\n }\n return value;\n}\n\nregisterSchema({\n command: \"chats.list\",\n description:\n 'Start here: list other Sessions on this account (newest first) so you can reuse what was done before. Each row shows the Session id, title, status, and a count of what it produced (creatives, landings, actions, flows, reports…). Looking for one? `--search \"PMax Brasil\"` finds the Sessions whose title or conversation holds any of the words, newest first, each with the `match` it was found by; read the match before trusting a row, since more words match more Sessions. Then drill in with `baker chats view <id>`, `baker chats transcript <id>`, or `baker chats diff <id>`. Read-only.',\n args: {\n status: { type: \"string\", description: \"Filter: active|archived|all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max Sessions to return, 1-100 (default: 20)\", required: false },\n full: { type: \"boolean\", description: \"Include each Session's full change list\", required: false, default: false },\n search: {\n type: \"string\",\n description:\n 'Sessions whose title or conversation holds any of these words, newest first, each with its `match` (e.g. --search \"PMax Brasil\")',\n required: false,\n },\n },\n});\n\nconst listCommand = defineCommand({\n meta: { name: \"list\", description: \"List other Sessions on this account, newest first.\" },\n args: {\n status: { type: \"string\", description: \"Filter: active|archived|all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max Sessions (1-100, default 20)\", required: false },\n full: { type: \"boolean\", description: \"Include each Session's full change list\", required: false, default: false },\n search: {\n type: \"string\",\n description: \"Sessions whose title or conversation holds any of these words\",\n required: false,\n },\n },\n run: async ({ args }) => {\n try {\n const body: Record<string, unknown> = {};\n if (args.search) {\n body.search = args.search;\n }\n if (args.status) {\n if (!(STATUS_GROUPS as readonly string[]).includes(args.status)) {\n throw new Error(`--status must be one of: ${STATUS_GROUPS.join(\"|\")}`);\n }\n body.status = args.status;\n }\n const limit = parseBoundedInt(args.limit, \"limit\", 1, 100);\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (args.full) {\n body.full = true;\n }\n // Exclude our own Session so we never list ourselves as a reusable \"other\".\n const selfChatId = getEnv().BAKER_CHAT_ID;\n if (selfChatId) {\n body.excludeChatId = selfChatId;\n }\n const response = await apiPost<ChatsListResponse>(\"/api/chats/list\", body);\n writeJson({\n ...response,\n meta: { count: response.data.chats.length },\n ...(response.data.chats.length === 0\n ? {\n hints: [\n args.search\n ? \"No Session's title or conversation holds any of those words. Try other words (a name, a figure), widen with --status all, or drop --search to list the newest.\"\n : \"No Sessions matched. Widen with --status all or a larger --limit.\",\n ],\n }\n : {\n hints: [\n \"Drill in: `baker chats view <id>` for outputs, `chats transcript <id>` for the conversation, `chats diff <id>` for the real file changes.\",\n ],\n }),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nregisterSchema({\n command: \"chats.view\",\n description:\n \"Inspect one Session's FULL picture of what it changed — the unified `effects`: git content (landings, creatives, flows, knowledge, brand), plus DB-only effects that never touch the repo — Actions, Scheduled agents, Tags, Tag Manager, Google Analytics, ad-platform writes, the funnel (`funnel`: which steps it added, changed or removed, and which ways in it added or removed in `triggersAdded`/`triggersRemoved`), what counts as a conversion (`conversions`), conversion sends, event sources, and every other staged or already-applied change (`otherChanges`: A/B tests, recipes, library images) — each resolved to real detail (names, descriptions, priorities, tag types, ad operations) and, once published, its `outcome`. Also `publish` (what each external surface actually did, with the provider's own error), `activity` (the chat's own timeline: status changes, publish start/fail, workspace recoveries, timeouts), `usage` (per-thread cost and the Session's token totals), the kickoff (how it was asked), threads, and commits. Effects are `staged` (in-progress draft) or applied. A completed Session is NOT proof its external changes landed — read `publish`. Use after `baker chats list` to decide whether to reuse it. Read-only.\",\n args: {\n id: { type: \"positional\", description: \"The Session id (from `baker chats list`)\", required: true },\n full: {\n type: \"boolean\",\n description: \"Untruncated effect lists and full activity metadata (compact caps each list at 25)\",\n required: false,\n default: false,\n },\n },\n});\n\nconst viewCommand = defineCommand({\n meta: {\n name: \"view\",\n description: \"Inspect one Session's full effects — git content + actions/tags/ads, kickoff, commits.\",\n },\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n full: { type: \"boolean\", description: \"Include full detail\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n const response = await apiPost<ChatsViewResponse>(\"/api/chats/view\", {\n chatId: args.id,\n ...(args.full ? { full: true } : {}),\n });\n const hints: string[] = response.data.publish ? publishHints(response.data.publish) : [];\n if (response.data.diffAvailable) {\n hints.push(\"See the real file-level diff of the git content with `baker chats diff <id> --full`.\");\n } else if (response.data.status === \"in_progress\" || response.data.status === \"publishing\") {\n hints.push(\n \"This Session is still in progress — read its current file changes with `baker chats diff <id> --live`.\",\n );\n }\n hints.push(...stillPublishingHints(response.data.status));\n hints.push(\"Read the conversation with `baker chats transcript <id>`.\");\n writeJson({ ...response, hints });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst TRANSCRIPT_ROLES = [\"user\", \"assistant\"] as const;\n\nregisterSchema({\n command: \"chats.transcript\",\n description:\n \"Start here: read a Session's conversation (user + agent turns), the most recent messages last. Leave out the id to read THIS chat — the way to recover its own earlier words after a context summary (never grep the raw logs on disk). `--search \\\"5.700\\\"` returns only the messages holding the text, from the whole conversation however long; `--role user` keeps one side; `--turns` keeps each request and the agent's closing message of that turn (a recap). Compact truncates long messages (around the match when searching); add --full for verbatim text. Read-only.\",\n args: {\n id: {\n type: \"positional\",\n description: \"The Session id (from `baker chats list`). Default: this chat\",\n required: false,\n },\n search: {\n type: \"string\",\n description: 'Only messages containing this text, case-insensitive (e.g. --search \"5.700\")',\n required: false,\n },\n role: { type: \"string\", description: \"Only one side: user|assistant\", required: false },\n turns: {\n type: \"boolean\",\n description: \"Only each user message and the agent's closing message of that turn\",\n required: false,\n default: false,\n },\n limit: { type: \"string\", description: \"Max messages to return, 1-1000 (default: 100)\", required: false },\n full: {\n type: \"boolean\",\n description: \"Return verbatim (untruncated) message text\",\n required: false,\n default: false,\n },\n },\n});\n\nconst transcriptCommand = defineCommand({\n meta: { name: \"transcript\", description: \"Read a Session's conversation — another one, or this chat's own.\" },\n args: {\n id: { type: \"positional\", description: \"The Session id (default: this chat)\", required: false },\n search: { type: \"string\", description: \"Only messages containing this text\", required: false },\n role: { type: \"string\", description: \"Only one side: user|assistant\", required: false },\n turns: { type: \"boolean\", description: \"Each request + the closing reply\", required: false, default: false },\n limit: { type: \"string\", description: \"Max messages (1-1000, default 100)\", required: false },\n full: { type: \"boolean\", description: \"Verbatim message text\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n // No id reads the caller's own chat, so its earlier words survive a context summary.\n const chatId = args.id ?? getEnv().BAKER_CHAT_ID;\n if (!chatId) {\n throw new Error(\"Pass the Session id: `baker chats transcript <id>` (find it with `baker chats list`).\");\n }\n const body: Record<string, unknown> = { chatId };\n if (args.search) {\n body.search = args.search;\n }\n if (args.role) {\n if (!(TRANSCRIPT_ROLES as readonly string[]).includes(args.role)) {\n throw new Error(`--role must be one of: ${TRANSCRIPT_ROLES.join(\"|\")}`);\n }\n body.role = args.role;\n }\n if (args.turns) {\n body.turns = true;\n }\n const limit = parseBoundedInt(args.limit, \"limit\", 1, 1000);\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (args.full) {\n body.full = true;\n }\n const response = await apiPost<ChatsTranscriptResponse>(\"/api/chats/transcript\", body);\n const hints: string[] = [];\n if (response.data.truncated) {\n hints.push(\"Older messages were dropped to fit --limit. Raise --limit, or narrow with --search.\");\n }\n if (args.search && response.data.entries.length === 0) {\n hints.push(\n \"No message holds that text. The whole conversation was searched — try a shorter or differently written piece of it.\",\n );\n }\n writeJson({ ...response, meta: { count: response.data.entries.length }, ...(hints.length > 0 ? { hints } : {}) });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nregisterSchema({\n command: \"chats.diff\",\n description:\n \"See the real file-level changes a Session made (landings, creatives, brand, flows, knowledge). Published Sessions read from git; for an in-progress (unpublished) Session pass --live to read its changes straight from its running workspace. Without --live, an unpublished Session returns available:false — use `baker chats view` for the staged summary. Compact lists changed files with +/- counts; add --full for the actual diff text. Read-only.\",\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n surface: {\n type: \"string\",\n description: \"Filter to one surface: knowledge|company|brand|landings|flows|creatives\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Include the unified-diff patch text per file\",\n required: false,\n default: false,\n },\n live: {\n type: \"boolean\",\n description:\n \"For an in-progress Session, read its changes from the live workspace (slower; resumes the paused Runtime). Ignored for published Sessions.\",\n required: false,\n default: false,\n },\n },\n});\n\nconst diffCommand = defineCommand({\n meta: { name: \"diff\", description: \"See a published Session's real file-level changes.\" },\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n surface: {\n type: \"string\",\n description: \"Filter: knowledge|company|brand|landings|flows|creatives\",\n required: false,\n },\n full: { type: \"boolean\", description: \"Include the diff patch text per file\", required: false, default: false },\n live: {\n type: \"boolean\",\n description: \"Read an in-progress Session's changes from its live workspace (slower)\",\n required: false,\n default: false,\n },\n },\n run: async ({ args }) => {\n try {\n const body: Record<string, unknown> = { chatId: args.id };\n if (args.surface) {\n if (!(REPO_SURFACES as readonly string[]).includes(args.surface)) {\n throw new Error(`--surface must be one of: ${REPO_SURFACES.join(\"|\")}`);\n }\n body.surface = args.surface;\n }\n if (args.full) {\n body.full = true;\n }\n if (args.live) {\n body.live = true;\n }\n const response = await apiPost<ChatsDiffResponse>(\"/api/chats/diff\", body);\n writeJson({\n ...response,\n meta: { count: response.data.files.length },\n ...(!response.data.available && response.data.reason ? { hints: [response.data.reason] } : {}),\n ...(response.data.available && !args.full && response.data.files.length > 0\n ? { hints: [\"Add --full to read the actual diff text for each file.\"] }\n : {}),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst IMPORT_DESCRIPTION = `Move what another open chat has staged into this chat, in one call — and out of that chat, so publishing both can never apply anything twice.\n\nStart here when the user wants another chat's unpublished work brought into this one (\"bring over\",\n\"merge the two chats\", \"include what the other chat prepared\"):\n baker chats import --from-chat <chat-id>\n baker chats import --from-chat <chat-id> --only meta-ads,tasks # only these surfaces\n\nIt moves every surface exactly as staged: ads (Google, Meta, LinkedIn, X, ChatGPT), Shopify, Tag Manager,\nGoogle Analytics, tracking tags, Tasks, scheduled agents, ActiveCampaign, site settings, ad goals, the funnel,\nconversions, conversion sends, event sources and lead routes. When both chats change the same thing, nothing\nmoves and the refusal names each clash — ask the user which version wins. What the other chat changed in\nfiles (Knowledge, pages, Forms), and what depends on those files, stays there; the result says what and why.\nA change moved here cannot go back: to leave one behind, ask the user first and use --only (Google Ads alone\ncan pick single changes: \\`baker ads google draft import --from-chat <id> --refs|--exclude\\`).\nFind chat ids with \\`baker chats list\\`; see what one staged with \\`baker chats view <id>\\`.`;\n\nregisterSchema({\n command: \"chats.import\",\n description: IMPORT_DESCRIPTION,\n args: {\n \"from-chat\": { type: \"string\", description: \"The other open chat whose staged changes move here\", required: true },\n only: {\n type: \"string\",\n description: `Comma-separated surfaces to move (default: all): ${CHAT_IMPORT_SURFACES.join(\", \")}`,\n required: false,\n },\n },\n});\n\n/** What the agent needs after a move: what stayed behind in the other chat, and what to check next. */\nfunction importHints(data: ChatsImportResponse[\"data\"]): string[] {\n const hints: string[] = [];\n const moved = data.surfaces.reduce((sum, surface) => sum + surface.moved, 0);\n const stayed = data.surfaces.filter((surface) => surface.left);\n if (moved === 0 && stayed.length === 0) {\n hints.push(`Chat ${data.fromChatId} had no unpublished changes staged, so nothing moved.`);\n }\n for (const surface of stayed) {\n hints.push(\n `${surface.left?.count ? `${surface.left.count} ` : \"\"}${surface.surface} change(s) stayed in chat ${data.fromChatId}: ${surface.left?.reason}`,\n );\n }\n if (data.filesStayed > 0) {\n hints.push(\n `Chat ${data.fromChatId} also changed ${data.filesStayed} file(s) (Knowledge, pages, Forms…), which never move. Read them with \\`baker chats diff ${data.fromChatId} --live --full\\` and make the same changes here if the user wants them.`,\n );\n }\n if (moved > 0) {\n hints.push(\n \"The moved changes are this chat's now and publish with it; the other chat no longer holds them. Review them with each surface's `draft list` (and `baker ads google draft validate` when Google Ads changes moved).\",\n );\n }\n if (moved > 0 && stayed.length === 0) {\n hints.push(\n \"Nothing staged stayed in the other chat. Never tell the user to discard it for this: its other work is still there.\",\n );\n }\n return hints;\n}\n\ntype OnlyFlag = { surfaces?: ChatImportSurface[] } | { refusal: string };\n\n/** The surfaces `--only` names; absent means every surface, and a list naming none is refused. */\nfunction onlyFlag(value: unknown): OnlyFlag {\n if (typeof value !== \"string\") return {};\n const named = value\n .split(\",\")\n .map((surface) => surface.trim())\n .filter((surface) => surface.length > 0);\n if (named.length === 0) return { refusal: \"--only names no surface\" };\n const unknown = named.filter((surface) => !(CHAT_IMPORT_SURFACES as readonly string[]).includes(surface));\n if (unknown.length > 0) return { refusal: `--only names ${unknown.join(\", \")}, which is not a surface` };\n return { surfaces: named as ChatImportSurface[] };\n}\n\nfunction refuse(message: string, fix: string): never {\n writeJson({ ok: false, error: { code: \"VALIDATION_ERROR\", message, fix } });\n process.exit(1);\n}\n\nconst importCommand = defineCommand({\n meta: { name: \"import\", description: IMPORT_DESCRIPTION },\n args: {\n \"from-chat\": { type: \"string\", description: \"The other open chat whose staged changes move here\" },\n only: { type: \"string\", description: \"Comma-separated surfaces to move (default: all)\" },\n },\n run: async ({ args }) => {\n const fromChatId = typeof args[\"from-chat\"] === \"string\" ? args[\"from-chat\"].trim() : \"\";\n if (!fromChatId) {\n refuse(\n \"--from-chat is required\",\n \"Name the other chat: baker chats import --from-chat <chat-id> (ids from `baker chats list`).\",\n );\n }\n const only = onlyFlag(args.only);\n if (\"refusal\" in only) {\n // A list naming nothing must never widen to \"every surface\": the move takes them out of the other chat.\n refuse(\n only.refusal,\n `Name surfaces from: ${CHAT_IMPORT_SURFACES.join(\", \")} — or leave --only off to move them all.`,\n );\n }\n try {\n const response = await apiPost<ChatsImportResponse>(\"/api/chats/import\", {\n chatId: requireChatId(),\n fromChatId,\n ...(only.surfaces ? { surfaces: only.surfaces } : {}),\n });\n writeJson({ ...response, hints: importHints(response.data) });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nexport const chatsCommand = defineCommand({\n meta: {\n name: \"chats\",\n description: `Inspect other Sessions on this account: list them, view what they produced, read their conversation, and see their real file changes — so you can reuse past work for a new goal. \\`import --from-chat <id>\\` moves another open Session's staged changes into this one.\nFull guide: __tooling__/docs/tools/baker/chats.md`,\n },\n subCommands: {\n list: listCommand,\n view: viewCommand,\n transcript: transcriptCommand,\n diff: diffCommand,\n import: importCommand,\n },\n});\n","import type { ChatPublishSummary } from \"@baker/api/chats\";\n\n/**\n * What a reader must not conclude from a completed Session: that it published\n * everything it staged (better than one published draft in three did not), or\n * that every change it sent is now what the platform holds.\n */\nexport function publishHints(publish: ChatPublishSummary): string[] {\n const hints: string[] = [];\n if (!publish.complete) {\n const failed = publish.failedTotal;\n hints.push(\n `This Session's publish left ${failed} change${failed === 1 ? \"\" : \"s\"} behind — see \\`publish.surfaces\\` for the platform's own words. Do not report those changes as live.`,\n );\n }\n const unconfirmed = publish.unconfirmedTotal ?? 0;\n if (unconfirmed > 0) {\n hints.push(\n `${unconfirmed} change${unconfirmed === 1 ? \"\" : \"s\"} went through but could not be confirmed when read back from the platform — \\`publish.surfaces[].unconfirmedChanges\\` says what it shows instead. Check before reporting them as done.`,\n );\n }\n return hints;\n}\n\n/**\n * A Session still publishing is not live yet, and nothing in this chat runs\n * once it is: work that has to wait for it is a Scheduled agent (BAKER-1743).\n */\nexport function stillPublishingHints(status: string): string[] {\n if (status !== \"publishing\") return [];\n return [\n \"This Session is still publishing: its changes are not live yet. Work that has to wait for it (a check on the live page, a test lead) is a Scheduled agent staged now with `baker scheduled-agents create --run-at <time>`, whose brief first checks this Session went live. It exists only once your own chat is published: a page trigger staged now misses this Session's publish, and a `--run-at` that has passed by then is created switched off, so leave hours of headroom, not minutes, and tell the user it runs only once they publish this chat. Never ask the user to come back and tell you when it is done.\",\n ];\n}\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -484,7 +484,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
484
484
  canvas: () => import("./canvas-FWG5JGG4.js").then((m) => m.canvasCommand),
485
485
  tags: () => import("./tags-CBINFGAN.js").then((m) => m.tagsCommand),
486
486
  "tag-manager": () => import("./tag-manager-KWITWX6Y.js").then((m) => m.tagManagerCommand),
487
- chats: () => import("./chats-HNOUUEII.js").then((m) => m.chatsCommand),
487
+ chats: () => import("./chats-A3XSSBJF.js").then((m) => m.chatsCommand),
488
488
  history: () => import("./history-BRWYSJQL.js").then((m) => m.historyCommand),
489
489
  credentials: () => import("./credentials-CMOO7W6D.js").then((m) => m.credentialsCommand),
490
490
  hubspot: () => import("./hubspot-YEZGTOM2.js").then((m) => m.hubspotCommand),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koda-sl/baker-cli",
3
- "version": "0.542.0",
3
+ "version": "0.543.0",
4
4
  "description": "AI-agent-first CLI for interacting with Baker, including the Baker creative canvas.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/chats/index.ts","../src/commands/chats/publish-hints.ts"],"sourcesContent":["import type { ChatsDiffResponse, ChatsListResponse, ChatsTranscriptResponse, ChatsViewResponse } from \"@baker/api\";\nimport { CHAT_IMPORT_SURFACES, type ChatsImportResponse } from \"@baker/api/chats\";\n\ntype ChatImportSurface = (typeof CHAT_IMPORT_SURFACES)[number];\n\nimport { defineCommand } from \"citty\";\nimport { apiPost } from \"../../client.ts\";\nimport { getEnv, requireChatId } from \"../../env.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { failApi } from \"../actions/shared.ts\";\nimport { publishHints } from \"./publish-hints.ts\";\n\nconst STATUS_GROUPS = [\"active\", \"archived\", \"all\"] as const;\nconst REPO_SURFACES = [\"knowledge\", \"company\", \"brand\", \"landings\", \"flows\", \"creatives\"] as const;\n\nfunction parseBoundedInt(raw: string | undefined, name: string, min: number, max: number): number | undefined {\n if (raw === undefined) {\n return undefined;\n }\n const value = Number.parseInt(raw, 10);\n if (Number.isNaN(value) || value < min || value > max) {\n throw new Error(`--${name} must be an integer between ${min} and ${max}`);\n }\n return value;\n}\n\nregisterSchema({\n command: \"chats.list\",\n description:\n 'Start here: list other Sessions on this account (newest first) so you can reuse what was done before. Each row shows the Session id, title, status, and a count of what it produced (creatives, landings, actions, flows, reports…). Looking for one? `--search \"PMax Brasil\"` finds the Sessions whose title or conversation holds any of the words, newest first, each with the `match` it was found by; read the match before trusting a row, since more words match more Sessions. Then drill in with `baker chats view <id>`, `baker chats transcript <id>`, or `baker chats diff <id>`. Read-only.',\n args: {\n status: { type: \"string\", description: \"Filter: active|archived|all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max Sessions to return, 1-100 (default: 20)\", required: false },\n full: { type: \"boolean\", description: \"Include each Session's full change list\", required: false, default: false },\n search: {\n type: \"string\",\n description:\n 'Sessions whose title or conversation holds any of these words, newest first, each with its `match` (e.g. --search \"PMax Brasil\")',\n required: false,\n },\n },\n});\n\nconst listCommand = defineCommand({\n meta: { name: \"list\", description: \"List other Sessions on this account, newest first.\" },\n args: {\n status: { type: \"string\", description: \"Filter: active|archived|all (default: all)\", required: false },\n limit: { type: \"string\", description: \"Max Sessions (1-100, default 20)\", required: false },\n full: { type: \"boolean\", description: \"Include each Session's full change list\", required: false, default: false },\n search: {\n type: \"string\",\n description: \"Sessions whose title or conversation holds any of these words\",\n required: false,\n },\n },\n run: async ({ args }) => {\n try {\n const body: Record<string, unknown> = {};\n if (args.search) {\n body.search = args.search;\n }\n if (args.status) {\n if (!(STATUS_GROUPS as readonly string[]).includes(args.status)) {\n throw new Error(`--status must be one of: ${STATUS_GROUPS.join(\"|\")}`);\n }\n body.status = args.status;\n }\n const limit = parseBoundedInt(args.limit, \"limit\", 1, 100);\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (args.full) {\n body.full = true;\n }\n // Exclude our own Session so we never list ourselves as a reusable \"other\".\n const selfChatId = getEnv().BAKER_CHAT_ID;\n if (selfChatId) {\n body.excludeChatId = selfChatId;\n }\n const response = await apiPost<ChatsListResponse>(\"/api/chats/list\", body);\n writeJson({\n ...response,\n meta: { count: response.data.chats.length },\n ...(response.data.chats.length === 0\n ? {\n hints: [\n args.search\n ? \"No Session's title or conversation holds any of those words. Try other words (a name, a figure), widen with --status all, or drop --search to list the newest.\"\n : \"No Sessions matched. Widen with --status all or a larger --limit.\",\n ],\n }\n : {\n hints: [\n \"Drill in: `baker chats view <id>` for outputs, `chats transcript <id>` for the conversation, `chats diff <id>` for the real file changes.\",\n ],\n }),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nregisterSchema({\n command: \"chats.view\",\n description:\n \"Inspect one Session's FULL picture of what it changed — the unified `effects`: git content (landings, creatives, flows, knowledge, brand), plus DB-only effects that never touch the repo — Actions, Scheduled agents, Tags, Tag Manager, Google Analytics, ad-platform writes, the funnel (`funnel`: which steps it added, changed or removed, and which ways in it added or removed in `triggersAdded`/`triggersRemoved`), what counts as a conversion (`conversions`), conversion sends, event sources, and every other staged or already-applied change (`otherChanges`: A/B tests, recipes, library images) — each resolved to real detail (names, descriptions, priorities, tag types, ad operations) and, once published, its `outcome`. Also `publish` (what each external surface actually did, with the provider's own error), `activity` (the chat's own timeline: status changes, publish start/fail, workspace recoveries, timeouts), `usage` (per-thread cost and the Session's token totals), the kickoff (how it was asked), threads, and commits. Effects are `staged` (in-progress draft) or applied. A completed Session is NOT proof its external changes landed — read `publish`. Use after `baker chats list` to decide whether to reuse it. Read-only.\",\n args: {\n id: { type: \"positional\", description: \"The Session id (from `baker chats list`)\", required: true },\n full: {\n type: \"boolean\",\n description: \"Untruncated effect lists and full activity metadata (compact caps each list at 25)\",\n required: false,\n default: false,\n },\n },\n});\n\nconst viewCommand = defineCommand({\n meta: {\n name: \"view\",\n description: \"Inspect one Session's full effects — git content + actions/tags/ads, kickoff, commits.\",\n },\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n full: { type: \"boolean\", description: \"Include full detail\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n const response = await apiPost<ChatsViewResponse>(\"/api/chats/view\", {\n chatId: args.id,\n ...(args.full ? { full: true } : {}),\n });\n const hints: string[] = response.data.publish ? publishHints(response.data.publish) : [];\n if (response.data.diffAvailable) {\n hints.push(\"See the real file-level diff of the git content with `baker chats diff <id> --full`.\");\n } else if (response.data.status === \"in_progress\" || response.data.status === \"publishing\") {\n hints.push(\n \"This Session is still in progress — read its current file changes with `baker chats diff <id> --live`.\",\n );\n }\n hints.push(\"Read the conversation with `baker chats transcript <id>`.\");\n writeJson({ ...response, hints });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst TRANSCRIPT_ROLES = [\"user\", \"assistant\"] as const;\n\nregisterSchema({\n command: \"chats.transcript\",\n description:\n \"Start here: read a Session's conversation (user + agent turns), the most recent messages last. Leave out the id to read THIS chat — the way to recover its own earlier words after a context summary (never grep the raw logs on disk). `--search \\\"5.700\\\"` returns only the messages holding the text, from the whole conversation however long; `--role user` keeps one side; `--turns` keeps each request and the agent's closing message of that turn (a recap). Compact truncates long messages (around the match when searching); add --full for verbatim text. Read-only.\",\n args: {\n id: {\n type: \"positional\",\n description: \"The Session id (from `baker chats list`). Default: this chat\",\n required: false,\n },\n search: {\n type: \"string\",\n description: 'Only messages containing this text, case-insensitive (e.g. --search \"5.700\")',\n required: false,\n },\n role: { type: \"string\", description: \"Only one side: user|assistant\", required: false },\n turns: {\n type: \"boolean\",\n description: \"Only each user message and the agent's closing message of that turn\",\n required: false,\n default: false,\n },\n limit: { type: \"string\", description: \"Max messages to return, 1-1000 (default: 100)\", required: false },\n full: {\n type: \"boolean\",\n description: \"Return verbatim (untruncated) message text\",\n required: false,\n default: false,\n },\n },\n});\n\nconst transcriptCommand = defineCommand({\n meta: { name: \"transcript\", description: \"Read a Session's conversation — another one, or this chat's own.\" },\n args: {\n id: { type: \"positional\", description: \"The Session id (default: this chat)\", required: false },\n search: { type: \"string\", description: \"Only messages containing this text\", required: false },\n role: { type: \"string\", description: \"Only one side: user|assistant\", required: false },\n turns: { type: \"boolean\", description: \"Each request + the closing reply\", required: false, default: false },\n limit: { type: \"string\", description: \"Max messages (1-1000, default 100)\", required: false },\n full: { type: \"boolean\", description: \"Verbatim message text\", required: false, default: false },\n },\n run: async ({ args }) => {\n try {\n // No id reads the caller's own chat, so its earlier words survive a context summary.\n const chatId = args.id ?? getEnv().BAKER_CHAT_ID;\n if (!chatId) {\n throw new Error(\"Pass the Session id: `baker chats transcript <id>` (find it with `baker chats list`).\");\n }\n const body: Record<string, unknown> = { chatId };\n if (args.search) {\n body.search = args.search;\n }\n if (args.role) {\n if (!(TRANSCRIPT_ROLES as readonly string[]).includes(args.role)) {\n throw new Error(`--role must be one of: ${TRANSCRIPT_ROLES.join(\"|\")}`);\n }\n body.role = args.role;\n }\n if (args.turns) {\n body.turns = true;\n }\n const limit = parseBoundedInt(args.limit, \"limit\", 1, 1000);\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (args.full) {\n body.full = true;\n }\n const response = await apiPost<ChatsTranscriptResponse>(\"/api/chats/transcript\", body);\n const hints: string[] = [];\n if (response.data.truncated) {\n hints.push(\"Older messages were dropped to fit --limit. Raise --limit, or narrow with --search.\");\n }\n if (args.search && response.data.entries.length === 0) {\n hints.push(\n \"No message holds that text. The whole conversation was searched — try a shorter or differently written piece of it.\",\n );\n }\n writeJson({ ...response, meta: { count: response.data.entries.length }, ...(hints.length > 0 ? { hints } : {}) });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nregisterSchema({\n command: \"chats.diff\",\n description:\n \"See the real file-level changes a Session made (landings, creatives, brand, flows, knowledge). Published Sessions read from git; for an in-progress (unpublished) Session pass --live to read its changes straight from its running workspace. Without --live, an unpublished Session returns available:false — use `baker chats view` for the staged summary. Compact lists changed files with +/- counts; add --full for the actual diff text. Read-only.\",\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n surface: {\n type: \"string\",\n description: \"Filter to one surface: knowledge|company|brand|landings|flows|creatives\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Include the unified-diff patch text per file\",\n required: false,\n default: false,\n },\n live: {\n type: \"boolean\",\n description:\n \"For an in-progress Session, read its changes from the live workspace (slower; resumes the paused Runtime). Ignored for published Sessions.\",\n required: false,\n default: false,\n },\n },\n});\n\nconst diffCommand = defineCommand({\n meta: { name: \"diff\", description: \"See a published Session's real file-level changes.\" },\n args: {\n id: { type: \"positional\", description: \"The Session id\", required: true },\n surface: {\n type: \"string\",\n description: \"Filter: knowledge|company|brand|landings|flows|creatives\",\n required: false,\n },\n full: { type: \"boolean\", description: \"Include the diff patch text per file\", required: false, default: false },\n live: {\n type: \"boolean\",\n description: \"Read an in-progress Session's changes from its live workspace (slower)\",\n required: false,\n default: false,\n },\n },\n run: async ({ args }) => {\n try {\n const body: Record<string, unknown> = { chatId: args.id };\n if (args.surface) {\n if (!(REPO_SURFACES as readonly string[]).includes(args.surface)) {\n throw new Error(`--surface must be one of: ${REPO_SURFACES.join(\"|\")}`);\n }\n body.surface = args.surface;\n }\n if (args.full) {\n body.full = true;\n }\n if (args.live) {\n body.live = true;\n }\n const response = await apiPost<ChatsDiffResponse>(\"/api/chats/diff\", body);\n writeJson({\n ...response,\n meta: { count: response.data.files.length },\n ...(!response.data.available && response.data.reason ? { hints: [response.data.reason] } : {}),\n ...(response.data.available && !args.full && response.data.files.length > 0\n ? { hints: [\"Add --full to read the actual diff text for each file.\"] }\n : {}),\n });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nconst IMPORT_DESCRIPTION = `Move what another open chat has staged into this chat, in one call — and out of that chat, so publishing both can never apply anything twice.\n\nStart here when the user wants another chat's unpublished work brought into this one (\"bring over\",\n\"merge the two chats\", \"include what the other chat prepared\"):\n baker chats import --from-chat <chat-id>\n baker chats import --from-chat <chat-id> --only meta-ads,tasks # only these surfaces\n\nIt moves every surface exactly as staged: ads (Google, Meta, LinkedIn, X, ChatGPT), Shopify, Tag Manager,\nGoogle Analytics, tracking tags, Tasks, scheduled agents, ActiveCampaign, site settings, ad goals, the funnel,\nconversions, conversion sends, event sources and lead routes. When both chats change the same thing, nothing\nmoves and the refusal names each clash — ask the user which version wins. What the other chat changed in\nfiles (Knowledge, pages, Forms), and what depends on those files, stays there; the result says what and why.\nA change moved here cannot go back: to leave one behind, ask the user first and use --only (Google Ads alone\ncan pick single changes: \\`baker ads google draft import --from-chat <id> --refs|--exclude\\`).\nFind chat ids with \\`baker chats list\\`; see what one staged with \\`baker chats view <id>\\`.`;\n\nregisterSchema({\n command: \"chats.import\",\n description: IMPORT_DESCRIPTION,\n args: {\n \"from-chat\": { type: \"string\", description: \"The other open chat whose staged changes move here\", required: true },\n only: {\n type: \"string\",\n description: `Comma-separated surfaces to move (default: all): ${CHAT_IMPORT_SURFACES.join(\", \")}`,\n required: false,\n },\n },\n});\n\n/** What the agent needs after a move: what stayed behind in the other chat, and what to check next. */\nfunction importHints(data: ChatsImportResponse[\"data\"]): string[] {\n const hints: string[] = [];\n const moved = data.surfaces.reduce((sum, surface) => sum + surface.moved, 0);\n const stayed = data.surfaces.filter((surface) => surface.left);\n if (moved === 0 && stayed.length === 0) {\n hints.push(`Chat ${data.fromChatId} had no unpublished changes staged, so nothing moved.`);\n }\n for (const surface of stayed) {\n hints.push(\n `${surface.left?.count ? `${surface.left.count} ` : \"\"}${surface.surface} change(s) stayed in chat ${data.fromChatId}: ${surface.left?.reason}`,\n );\n }\n if (data.filesStayed > 0) {\n hints.push(\n `Chat ${data.fromChatId} also changed ${data.filesStayed} file(s) (Knowledge, pages, Forms…), which never move. Read them with \\`baker chats diff ${data.fromChatId} --live --full\\` and make the same changes here if the user wants them.`,\n );\n }\n if (moved > 0) {\n hints.push(\n \"The moved changes are this chat's now and publish with it; the other chat no longer holds them. Review them with each surface's `draft list` (and `baker ads google draft validate` when Google Ads changes moved).\",\n );\n }\n if (moved > 0 && stayed.length === 0) {\n hints.push(\n \"Nothing staged stayed in the other chat. Never tell the user to discard it for this: its other work is still there.\",\n );\n }\n return hints;\n}\n\ntype OnlyFlag = { surfaces?: ChatImportSurface[] } | { refusal: string };\n\n/** The surfaces `--only` names; absent means every surface, and a list naming none is refused. */\nfunction onlyFlag(value: unknown): OnlyFlag {\n if (typeof value !== \"string\") return {};\n const named = value\n .split(\",\")\n .map((surface) => surface.trim())\n .filter((surface) => surface.length > 0);\n if (named.length === 0) return { refusal: \"--only names no surface\" };\n const unknown = named.filter((surface) => !(CHAT_IMPORT_SURFACES as readonly string[]).includes(surface));\n if (unknown.length > 0) return { refusal: `--only names ${unknown.join(\", \")}, which is not a surface` };\n return { surfaces: named as ChatImportSurface[] };\n}\n\nfunction refuse(message: string, fix: string): never {\n writeJson({ ok: false, error: { code: \"VALIDATION_ERROR\", message, fix } });\n process.exit(1);\n}\n\nconst importCommand = defineCommand({\n meta: { name: \"import\", description: IMPORT_DESCRIPTION },\n args: {\n \"from-chat\": { type: \"string\", description: \"The other open chat whose staged changes move here\" },\n only: { type: \"string\", description: \"Comma-separated surfaces to move (default: all)\" },\n },\n run: async ({ args }) => {\n const fromChatId = typeof args[\"from-chat\"] === \"string\" ? args[\"from-chat\"].trim() : \"\";\n if (!fromChatId) {\n refuse(\n \"--from-chat is required\",\n \"Name the other chat: baker chats import --from-chat <chat-id> (ids from `baker chats list`).\",\n );\n }\n const only = onlyFlag(args.only);\n if (\"refusal\" in only) {\n // A list naming nothing must never widen to \"every surface\": the move takes them out of the other chat.\n refuse(\n only.refusal,\n `Name surfaces from: ${CHAT_IMPORT_SURFACES.join(\", \")} — or leave --only off to move them all.`,\n );\n }\n try {\n const response = await apiPost<ChatsImportResponse>(\"/api/chats/import\", {\n chatId: requireChatId(),\n fromChatId,\n ...(only.surfaces ? { surfaces: only.surfaces } : {}),\n });\n writeJson({ ...response, hints: importHints(response.data) });\n } catch (err) {\n failApi(err);\n }\n },\n});\n\nexport const chatsCommand = defineCommand({\n meta: {\n name: \"chats\",\n description: `Inspect other Sessions on this account: list them, view what they produced, read their conversation, and see their real file changes — so you can reuse past work for a new goal. \\`import --from-chat <id>\\` moves another open Session's staged changes into this one.\nFull guide: __tooling__/docs/tools/baker/chats.md`,\n },\n subCommands: {\n list: listCommand,\n view: viewCommand,\n transcript: transcriptCommand,\n diff: diffCommand,\n import: importCommand,\n },\n});\n","import type { ChatPublishSummary } from \"@baker/api/chats\";\n\n/**\n * What a reader must not conclude from a completed Session: that it published\n * everything it staged (better than one published draft in three did not), or\n * that every change it sent is now what the platform holds.\n */\nexport function publishHints(publish: ChatPublishSummary): string[] {\n const hints: string[] = [];\n if (!publish.complete) {\n const failed = publish.failedTotal;\n hints.push(\n `This Session's publish left ${failed} change${failed === 1 ? \"\" : \"s\"} behind — see \\`publish.surfaces\\` for the platform's own words. Do not report those changes as live.`,\n );\n }\n const unconfirmed = publish.unconfirmedTotal ?? 0;\n if (unconfirmed > 0) {\n hints.push(\n `${unconfirmed} change${unconfirmed === 1 ? \"\" : \"s\"} went through but could not be confirmed when read back from the platform — \\`publish.surfaces[].unconfirmedChanges\\` says what it shows instead. Check before reporting them as done.`,\n );\n }\n return hints;\n}\n"],"mappings":"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","names":[]}