@koda-sl/baker-cli 0.482.0-dev.a5555ab55 → 0.483.0-dev.6a297fc5c

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.
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  buildNext,
9
9
  ideasReport
10
- } from "./chunk-JRFVSSKP.js";
10
+ } from "./chunk-TGIL4L4L.js";
11
11
  import {
12
12
  buildSearchBody
13
13
  } from "./chunk-MXWOYFI2.js";
@@ -535,4 +535,4 @@ export {
535
535
  tastePart,
536
536
  whatWorks
537
537
  };
538
- //# sourceMappingURL=brief-JIARAUIR.js.map
538
+ //# sourceMappingURL=brief-MNWFEJ3L.js.map
@@ -37,7 +37,7 @@ import { defineCommand } from "citty";
37
37
  var BUILD_NEXT = 3;
38
38
  var DESCRIPTION = `Check and rank the ad ideas in src/creatives/_ideas/: is each backed by something a customer said (src/content/insights/), does it claim only what the Knowledge holds, is it a different ad from the others, does it fill a gap the live ads leave. Free and local.
39
39
 
40
- Start here, after writing 4-8 idea files (one per file, eight fields: who, message, evidence, awareness, angle, format, job, why):
40
+ Start here, after writing 4-8 idea files (one per file: who, message, evidence, awareness, angle, shows, job, why; format only for a video or a container the person asked for):
41
41
  baker creatives ideas # ranked, with problems; build_next names the ones to make
42
42
  baker creatives make <idea> # then build each one in build_next
43
43
  An idea with a problem is not built until it is fixed. An idea with no evidence is an explore bet: it may be built, and says so.`;
@@ -55,7 +55,7 @@ function ideasHints(report) {
55
55
  const toBuild = report.ideas.filter((i) => i.status === "idea");
56
56
  if (toBuild.length === 0 && report.unreadable.length === 0) {
57
57
  hints.push(
58
- "No ideas yet. Write 4-8 files in src/creatives/_ideas/<idea>.md (who, message, evidence, awareness, angle, format, job, why), then run this again."
58
+ "No ideas yet. Write 4-8 files in src/creatives/_ideas/<idea>.md (who, message, evidence, awareness, angle, shows, job, why), then run this again."
59
59
  );
60
60
  }
61
61
  if (report.unreadable.length > 0) {
@@ -157,4 +157,4 @@ export {
157
157
  ideasReport,
158
158
  ideasCommand
159
159
  };
160
- //# sourceMappingURL=chunk-JRFVSSKP.js.map
160
+ //# sourceMappingURL=chunk-TGIL4L4L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/creatives/ideas.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport { readAllRules } from \"../../engine/creative-context/index.ts\";\nimport { selectRules } from \"../../engine/creative-rules/select.ts\";\nimport type { AskNouls } from \"../../engine/lib/remembered-nouls.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { marketFromCompanyDoc } from \"../../viewer-profile.ts\";\nimport { findWorkspaceRoot } from \"../canvas/normalize-paths.ts\";\nimport { sameMessageRead } from \"./ideas-judgments.ts\";\nimport { checkIdeas, IDEA_ANGLES, IDEA_FORMATS, type IdeaCheck } from \"./ideas-model.ts\";\nimport {\n coverageOf,\n readCreativeRecords,\n readIdeas,\n readInsights,\n readKnowledgeCorpus,\n readPersonaIds,\n type UnreadableIdea,\n workspaceIdeasJudge,\n} from \"./ideas-workspace.ts\";\n\nconst BUILD_NEXT = 3;\n\nconst DESCRIPTION = `Check and rank the ad ideas in src/creatives/_ideas/: is each backed by something a customer said (src/content/insights/), does it claim only what the Knowledge holds, is it a different ad from the others, does it fill a gap the live ads leave. Free and local.\n\nStart here, after writing 4-8 idea files (one per file: who, message, evidence, awareness, angle, shows, job, why; format only for a video or a container the person asked for):\n baker creatives ideas # ranked, with problems; build_next names the ones to make\n baker creatives make <idea> # then build each one in build_next\nAn idea with a problem is not built until it is fixed. An idea with no evidence is an explore bet: it may be built, and says so.`;\n\nconst ARGS = {\n full: {\n type: \"boolean\",\n description: \"Every idea with its warnings and gaps, and the allowed angle and format values\",\n required: false,\n default: false,\n },\n} as const;\n\nregisterSchema({ command: \"creatives.ideas\", description: DESCRIPTION, args: ARGS });\n\ntype IdeasReport = {\n ideas: IdeaCheck[];\n unreadable: UnreadableIdea[];\n insightCount: number;\n observedCount: number;\n};\n\n/** What the agent does next. Pure. */\nexport function ideasHints(report: IdeasReport): string[] {\n const hints: string[] = [];\n const toBuild = report.ideas.filter((i) => i.status === \"idea\");\n if (toBuild.length === 0 && report.unreadable.length === 0) {\n hints.push(\n \"No ideas yet. Write 4-8 files in src/creatives/_ideas/<idea>.md (who, message, evidence, awareness, angle, shows, job, why), then run this again.\",\n );\n }\n if (report.unreadable.length > 0) {\n hints.push(`Fix ${report.unreadable.map((u) => u.id).join(\", \")}: each names what is missing or unknown.`);\n }\n const blocked = toBuild.filter((i) => i.problems.length > 0);\n if (blocked.length > 0) hints.push(`Fix before building: ${blocked.map((i) => i.id).join(\", \")}.`);\n if (report.observedCount < 3) {\n hints.push(\n \"Few customer quotes on file: run `baker research customers` so ideas stand on what customers said; until then they are explore bets.\",\n );\n } else if (toBuild.length > 0 && toBuild.every((i) => i.evidence === \"explore\")) {\n hints.push(\"No idea cites an insight: put the insight ids that back each one in its `evidence`.\");\n }\n const next = buildNext(report.ideas);\n if (next.length === 1) hints.push(`Build: \\`baker creatives make ${next[0]}\\`.`);\n // A render takes about five minutes: built one after another, three ideas took forty (dev, Oct 2026).\n if (next.length > 1)\n hints.push(\n `Build ${next.join(\", \")} at once: one \\`creative-producer\\` per idea, all spawned in one message in the background, each given its idea id, and handle each as it returns. Never build them one after another: each render takes minutes. Edited an idea after this check? Run \\`baker creatives ideas\\` again first: a producer cannot build an idea with a problem.`,\n );\n return hints;\n}\n\n/** The ideas to build now: the best-ranked ones still to build with nothing blocking. Pure. */\nexport function buildNext(ideas: readonly IdeaCheck[], count = BUILD_NEXT): string[] {\n // One explore bet a batch: the rest stand on what customers said.\n const ready = ideas.filter((i) => i.status === \"idea\" && i.problems.length === 0);\n const firstBet = ready.find((i) => i.evidence === \"explore\");\n return ready\n .filter((i) => i.evidence !== \"explore\" || i === firstBet)\n .slice(0, count)\n .map((i) => i.id);\n}\n\n/** One idea as the agent reads it by default: what decides building it, nothing more. Pure. */\nexport function compactIdea(check: IdeaCheck) {\n return {\n idea: check.id,\n status: check.status,\n evidence: check.evidence,\n ...(check.quote ? { quote: check.quote.length > 120 ? `${check.quote.slice(0, 117)}...` : check.quote } : {}),\n awareness: check.awareness,\n angle: check.angle,\n ...(check.shows ? { shows: check.shows } : {}),\n ...(check.format ? { format: check.format } : {}),\n platforms: check.platforms ?? (\"unset\" as const),\n ...(check.problems.length > 0 ? { problems: check.problems } : {}),\n ...(check.warnings.length > 0 ? { warnings: check.warnings } : {}),\n };\n}\n\n/** Everything `checkIdeas` needs, read from the workspace. */\nexport async function ideasReport(root: string, opts: { ask?: AskNouls } = {}): Promise<IdeasReport> {\n const judge = opts.ask ? { ask: opts.ask, done: () => Promise.resolve() } : workspaceIdeasJudge(root);\n const [{ ideas, unreadable }, insights, knowledge, personas, creatives, rules, companyDoc] = await Promise.all([\n readIdeas(root),\n readInsights(root, { ask: judge.ask }),\n readKnowledgeCorpus(root),\n readPersonaIds(root),\n readCreativeRecords(root),\n readAllRules(root).then((all) => selectRules(all, {})),\n readFile(path.join(root, \"COMPANY.md\"), \"utf8\").catch(() => null),\n ]);\n const language = marketFromCompanyDoc(companyDoc)?.language;\n const sameMessage = await sameMessageRead(ideas, judge.ask);\n await judge.done();\n const checked = checkIdeas({\n ideas,\n insights,\n knowledge,\n personas,\n sameMessage,\n rules,\n ...(language ? { language } : {}),\n ...coverageOf(ideas, creatives),\n });\n return {\n ideas: checked,\n unreadable,\n insightCount: insights.length,\n observedCount: insights.filter((i) => i.status === \"observed\").length,\n };\n}\n\nexport const ideasCommand = defineCommand({\n meta: { name: \"ideas\", description: DESCRIPTION },\n args: ARGS,\n async run({ args }) {\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const report = await ideasReport(root);\n const full = args.full === true;\n writeJson({\n ok: true,\n data: {\n build_next: buildNext(report.ideas),\n ideas: full ? report.ideas : report.ideas.map(compactIdea),\n ...(report.unreadable.length > 0 ? { unreadable: report.unreadable } : {}),\n customer_quotes: { total: report.insightCount, observed: report.observedCount },\n ...(full ? { allowed: { angle: IDEA_ANGLES, format: IDEA_FORMATS } } : {}),\n },\n hints: ideasHints(report),\n });\n },\n});\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -123,7 +123,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
123
123
  gsc: () => import("./gsc-UU3T2C6B.js").then((m) => m.gscCommand),
124
124
  research: () => import("./research-4ASN2KMB.js").then((m) => m.researchCommand),
125
125
  decide: () => import("./decide-TWKH5QQU.js").then((m) => m.decideCommand),
126
- creatives: () => import("./creatives-5VY3LT6X.js").then((m) => m.creativesCommand),
126
+ creatives: () => import("./creatives-ZOK7PZSG.js").then((m) => m.creativesCommand),
127
127
  flows: () => import("./flows-TD6PNUDM.js").then((m) => m.flowsCommand),
128
128
  funnel: () => import("./funnel-CJRFDTCD.js").then((m) => m.funnelCommand),
129
129
  images: () => import("./images-XY5DLJEA.js").then((m) => m.imagesCommand),
@@ -39,8 +39,8 @@ How published creatives are doing in live Meta ads (results, fatigue, angle; hoo
39
39
  Full guide: __tooling__/docs/tools/baker/creatives.md`
40
40
  },
41
41
  subCommands: {
42
- brief: () => import("./brief-JIARAUIR.js").then((m) => m.briefCommand),
43
- ideas: () => import("./ideas-LD6X753E.js").then((m) => m.ideasCommand),
42
+ brief: () => import("./brief-MNWFEJ3L.js").then((m) => m.briefCommand),
43
+ ideas: () => import("./ideas-NBQPCC5C.js").then((m) => m.ideasCommand),
44
44
  make: () => import("./make-EWHS4EHQ.js").then((m) => m.makeCommand),
45
45
  translate: () => import("./translate-C5LZ6KVN.js").then((m) => m.translateCommand),
46
46
  learn: () => import("./learn-6HVDSTTJ.js").then((m) => m.learnCommand),
@@ -55,4 +55,4 @@ Full guide: __tooling__/docs/tools/baker/creatives.md`
55
55
  export {
56
56
  creativesCommand
57
57
  };
58
- //# sourceMappingURL=creatives-5VY3LT6X.js.map
58
+ //# sourceMappingURL=creatives-ZOK7PZSG.js.map
@@ -4,7 +4,7 @@ import {
4
4
  ideasCommand,
5
5
  ideasHints,
6
6
  ideasReport
7
- } from "./chunk-JRFVSSKP.js";
7
+ } from "./chunk-TGIL4L4L.js";
8
8
  import "./chunk-QKABEX3F.js";
9
9
  import "./chunk-64HQDJ2E.js";
10
10
  import "./chunk-TY4BDVLG.js";
@@ -37,4 +37,4 @@ export {
37
37
  ideasHints,
38
38
  ideasReport
39
39
  };
40
- //# sourceMappingURL=ideas-LD6X753E.js.map
40
+ //# sourceMappingURL=ideas-NBQPCC5C.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koda-sl/baker-cli",
3
- "version": "0.482.0-dev.a5555ab55",
3
+ "version": "0.483.0-dev.6a297fc5c",
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/creatives/ideas.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { defineCommand } from \"citty\";\nimport { readAllRules } from \"../../engine/creative-context/index.ts\";\nimport { selectRules } from \"../../engine/creative-rules/select.ts\";\nimport type { AskNouls } from \"../../engine/lib/remembered-nouls.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\nimport { marketFromCompanyDoc } from \"../../viewer-profile.ts\";\nimport { findWorkspaceRoot } from \"../canvas/normalize-paths.ts\";\nimport { sameMessageRead } from \"./ideas-judgments.ts\";\nimport { checkIdeas, IDEA_ANGLES, IDEA_FORMATS, type IdeaCheck } from \"./ideas-model.ts\";\nimport {\n coverageOf,\n readCreativeRecords,\n readIdeas,\n readInsights,\n readKnowledgeCorpus,\n readPersonaIds,\n type UnreadableIdea,\n workspaceIdeasJudge,\n} from \"./ideas-workspace.ts\";\n\nconst BUILD_NEXT = 3;\n\nconst DESCRIPTION = `Check and rank the ad ideas in src/creatives/_ideas/: is each backed by something a customer said (src/content/insights/), does it claim only what the Knowledge holds, is it a different ad from the others, does it fill a gap the live ads leave. Free and local.\n\nStart here, after writing 4-8 idea files (one per file, eight fields: who, message, evidence, awareness, angle, format, job, why):\n baker creatives ideas # ranked, with problems; build_next names the ones to make\n baker creatives make <idea> # then build each one in build_next\nAn idea with a problem is not built until it is fixed. An idea with no evidence is an explore bet: it may be built, and says so.`;\n\nconst ARGS = {\n full: {\n type: \"boolean\",\n description: \"Every idea with its warnings and gaps, and the allowed angle and format values\",\n required: false,\n default: false,\n },\n} as const;\n\nregisterSchema({ command: \"creatives.ideas\", description: DESCRIPTION, args: ARGS });\n\ntype IdeasReport = {\n ideas: IdeaCheck[];\n unreadable: UnreadableIdea[];\n insightCount: number;\n observedCount: number;\n};\n\n/** What the agent does next. Pure. */\nexport function ideasHints(report: IdeasReport): string[] {\n const hints: string[] = [];\n const toBuild = report.ideas.filter((i) => i.status === \"idea\");\n if (toBuild.length === 0 && report.unreadable.length === 0) {\n hints.push(\n \"No ideas yet. Write 4-8 files in src/creatives/_ideas/<idea>.md (who, message, evidence, awareness, angle, format, job, why), then run this again.\",\n );\n }\n if (report.unreadable.length > 0) {\n hints.push(`Fix ${report.unreadable.map((u) => u.id).join(\", \")}: each names what is missing or unknown.`);\n }\n const blocked = toBuild.filter((i) => i.problems.length > 0);\n if (blocked.length > 0) hints.push(`Fix before building: ${blocked.map((i) => i.id).join(\", \")}.`);\n if (report.observedCount < 3) {\n hints.push(\n \"Few customer quotes on file: run `baker research customers` so ideas stand on what customers said; until then they are explore bets.\",\n );\n } else if (toBuild.length > 0 && toBuild.every((i) => i.evidence === \"explore\")) {\n hints.push(\"No idea cites an insight: put the insight ids that back each one in its `evidence`.\");\n }\n const next = buildNext(report.ideas);\n if (next.length === 1) hints.push(`Build: \\`baker creatives make ${next[0]}\\`.`);\n // A render takes about five minutes: built one after another, three ideas took forty (dev, Oct 2026).\n if (next.length > 1)\n hints.push(\n `Build ${next.join(\", \")} at once: one \\`creative-producer\\` per idea, all spawned in one message in the background, each given its idea id, and handle each as it returns. Never build them one after another: each render takes minutes. Edited an idea after this check? Run \\`baker creatives ideas\\` again first: a producer cannot build an idea with a problem.`,\n );\n return hints;\n}\n\n/** The ideas to build now: the best-ranked ones still to build with nothing blocking. Pure. */\nexport function buildNext(ideas: readonly IdeaCheck[], count = BUILD_NEXT): string[] {\n // One explore bet a batch: the rest stand on what customers said.\n const ready = ideas.filter((i) => i.status === \"idea\" && i.problems.length === 0);\n const firstBet = ready.find((i) => i.evidence === \"explore\");\n return ready\n .filter((i) => i.evidence !== \"explore\" || i === firstBet)\n .slice(0, count)\n .map((i) => i.id);\n}\n\n/** One idea as the agent reads it by default: what decides building it, nothing more. Pure. */\nexport function compactIdea(check: IdeaCheck) {\n return {\n idea: check.id,\n status: check.status,\n evidence: check.evidence,\n ...(check.quote ? { quote: check.quote.length > 120 ? `${check.quote.slice(0, 117)}...` : check.quote } : {}),\n awareness: check.awareness,\n angle: check.angle,\n ...(check.shows ? { shows: check.shows } : {}),\n ...(check.format ? { format: check.format } : {}),\n platforms: check.platforms ?? (\"unset\" as const),\n ...(check.problems.length > 0 ? { problems: check.problems } : {}),\n ...(check.warnings.length > 0 ? { warnings: check.warnings } : {}),\n };\n}\n\n/** Everything `checkIdeas` needs, read from the workspace. */\nexport async function ideasReport(root: string, opts: { ask?: AskNouls } = {}): Promise<IdeasReport> {\n const judge = opts.ask ? { ask: opts.ask, done: () => Promise.resolve() } : workspaceIdeasJudge(root);\n const [{ ideas, unreadable }, insights, knowledge, personas, creatives, rules, companyDoc] = await Promise.all([\n readIdeas(root),\n readInsights(root, { ask: judge.ask }),\n readKnowledgeCorpus(root),\n readPersonaIds(root),\n readCreativeRecords(root),\n readAllRules(root).then((all) => selectRules(all, {})),\n readFile(path.join(root, \"COMPANY.md\"), \"utf8\").catch(() => null),\n ]);\n const language = marketFromCompanyDoc(companyDoc)?.language;\n const sameMessage = await sameMessageRead(ideas, judge.ask);\n await judge.done();\n const checked = checkIdeas({\n ideas,\n insights,\n knowledge,\n personas,\n sameMessage,\n rules,\n ...(language ? { language } : {}),\n ...coverageOf(ideas, creatives),\n });\n return {\n ideas: checked,\n unreadable,\n insightCount: insights.length,\n observedCount: insights.filter((i) => i.status === \"observed\").length,\n };\n}\n\nexport const ideasCommand = defineCommand({\n meta: { name: \"ideas\", description: DESCRIPTION },\n args: ARGS,\n async run({ args }) {\n const root = findWorkspaceRoot(process.cwd()) ?? process.cwd();\n const report = await ideasReport(root);\n const full = args.full === true;\n writeJson({\n ok: true,\n data: {\n build_next: buildNext(report.ideas),\n ideas: full ? report.ideas : report.ideas.map(compactIdea),\n ...(report.unreadable.length > 0 ? { unreadable: report.unreadable } : {}),\n customer_quotes: { total: report.insightCount, observed: report.observedCount },\n ...(full ? { allowed: { angle: IDEA_ANGLES, format: IDEA_FORMATS } } : {}),\n },\n hints: ideasHints(report),\n });\n },\n});\n"],"mappings":"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","names":[]}