@todoforai/cli 0.1.52 → 0.1.53

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.
@@ -43809,6 +43809,17 @@ var SERVER_TO_FRONTENDS = {
43809
43809
  function_call_request: (userId) => `${"FUNCTION_CALL_REQUEST_AGENT" /* FUNCTION_CALL_REQUEST_AGENT */}:frontend:${userId}`
43810
43810
  }
43811
43811
  };
43812
+ // ../packages/shared-fbe/src/REST_types.ts
43813
+ var MANUAL_CHANNEL = "Manual";
43814
+ function manualAnswersOf(sources) {
43815
+ const manual = sources?.find((s) => s.channel === MANUAL_CHANNEL);
43816
+ const out = {};
43817
+ for (const x of manual?.items ?? [])
43818
+ if (typeof x !== "string" && x.prompt)
43819
+ out[x.prompt] = x.text;
43820
+ return out;
43821
+ }
43822
+ var manualSamples = (answers) => Object.entries(answers).filter(([, a]) => a.trim()).map(([prompt, text]) => ({ prompt, text: text.trim() }));
43812
43823
  // ../packages/shared-fbe/src/templateBody.ts
43813
43824
  var USER_HEADINGS = new Set([
43814
43825
  "your task",
@@ -44266,7 +44277,6 @@ Exactly ONE \`api_recommend_template\` call per proposal: it carries both what t
44266
44277
  It runs in-process and needs no machine or shell. Never shell out to \`todoregistry-cli\` or \`todoforai-cli\` for this.
44267
44278
 
44268
44279
  3. Propose only todos you genuinely believe fit this business, highest priority first. There is no quota: a weak card costs the user more than no card, so if you can't find good ones, propose fewer or none and say why. Favour the trivial, high-probability moves for this company, the strategic directions its owner would nod at instantly, alongside any cleverer bets. Then reply with a one-line summary per proposal grouped by workstream, and tell the user they're waiting on the board for review (or, if you proposed none, what you'd need to make a confident recommendation).`,
44269
- mcpConfigs: {},
44270
44280
  edgesMcpConfigs: {},
44271
44281
  permissions: {
44272
44282
  allow: [
@@ -44289,7 +44299,6 @@ var JARVIS_AGENT = {
44289
44299
  ownerId: "SYSTEM",
44290
44300
  systemMessage: "",
44291
44301
  model: "",
44292
- mcpConfigs: {},
44293
44302
  edgesMcpConfigs: {},
44294
44303
  createdAt: 0,
44295
44304
  updatedAt: 0
@@ -44299,7 +44308,6 @@ var ONBOARDING_AGENT = {
44299
44308
  name: "Setup",
44300
44309
  ownerId: "SYSTEM",
44301
44310
  systemMessage: "Workspace setup — this todo is a guided stepper and never runs an agent.",
44302
- mcpConfigs: {},
44303
44311
  edgesMcpConfigs: {},
44304
44312
  createdAt: 0,
44305
44313
  updatedAt: 0
@@ -44548,7 +44556,7 @@ import { parseArgs } from "util";
44548
44556
  // package.json
44549
44557
  var package_default = {
44550
44558
  name: "@todoforai/cli",
44551
- version: "0.1.52",
44559
+ version: "0.1.53",
44552
44560
  type: "module",
44553
44561
  bin: {
44554
44562
  "todoforai-cli": "bin/todoforai-cli.js",
@@ -47434,8 +47442,7 @@ Examples:
47434
47442
  tfa-cli agent update <agent> sysmsg="You are a terse video editor."
47435
47443
  tfa-cli agent create name=Reviewer model=claude sysmsg="Review diffs only."
47436
47444
 
47437
- From an agent shell (dst_ token) permissions, mcpConfigs, edgesMcpConfigs,
47438
- devicesConfig and delete are refused by the backend.
47445
+ From an agent shell (dst_ token) permissions, edgesMcpConfigs, devicesConfig and delete are refused by the backend.
47439
47446
  `);
47440
47447
  }
47441
47448
  var FIELD_ALIASES = {
@@ -47886,7 +47893,6 @@ var TODO_ALIASES = {
47886
47893
  agent: "agentSettingsId",
47887
47894
  public: "isPublic"
47888
47895
  };
47889
- var PROJECT_ALIASES = {};
47890
47896
  function fail(msg) {
47891
47897
  process.stderr.write(`${RED}${msg}${RESET}
47892
47898
  `);
@@ -47962,7 +47968,7 @@ async function projectCommand(api, positionals, args) {
47962
47968
  if (sub === "set") {
47963
47969
  if (!rest.length)
47964
47970
  fail("Usage: tfa-cli project set <field=value>…");
47965
- const updates = parseAssignments2(rest, PROJECT_ALIASES);
47971
+ const updates = parseAssignments2(rest);
47966
47972
  await api.updateProject(projectId, updates);
47967
47973
  process.stderr.write(`${GREEN}✅ project updated: ${Object.keys(updates).join(", ")}${RESET}
47968
47974
  `);
@@ -48200,13 +48206,8 @@ async function voiceCommand(api, projectId, rest, args) {
48200
48206
  const [verb, ...vargs] = rest;
48201
48207
  if (verb === "collect" && !vargs[0])
48202
48208
  fail("Usage: tfa-cli brand voice collect <channel> [--url U | --pasted-file F|- | --account <page-id> | --max N] [--dry-run]");
48203
- const brand = await api.getBusinessContext(projectId);
48204
- if (!brand)
48205
- fail("This project has no brand — 'tfa-cli brand create <name>' first");
48206
48209
  if (verb === "answers") {
48207
- const { sources } = await api.listVoiceSources(projectId);
48208
- const manual = sources.find((s) => s.channel === "Manual");
48209
- const answers = Object.fromEntries((manual?.items ?? []).filter((x) => x?.prompt).map((x) => [x.prompt, x.text]));
48210
+ const answers = manualAnswersOf((await api.listVoiceSources(projectId)).sources);
48210
48211
  if (vargs.length) {
48211
48212
  for (const a of vargs) {
48212
48213
  const i = a.indexOf("=");
@@ -48214,8 +48215,7 @@ async function voiceCommand(api, projectId, rest, args) {
48214
48215
  fail(`Expected question=answer, got '${a}'`);
48215
48216
  answers[a.slice(0, i)] = a.slice(i + 1);
48216
48217
  }
48217
- const samples = Object.entries(answers).filter(([, t]) => t.trim()).map(([prompt, text]) => ({ prompt, text }));
48218
- await api.collectVoiceSource(projectId, "Manual", { samples });
48218
+ await api.collectVoiceSource(projectId, MANUAL_CHANNEL, { samples: manualSamples(answers) });
48219
48219
  process.stderr.write(`${GREEN}✅ ${vargs.length} answer(s) saved${RESET}
48220
48220
  `);
48221
48221
  return;
@@ -48231,12 +48231,13 @@ async function voiceCommand(api, projectId, rest, args) {
48231
48231
  return;
48232
48232
  }
48233
48233
  if (!verb || verb === "show") {
48234
- const { sources, profile } = await api.listVoiceSources(projectId);
48234
+ const [{ sources, profile }, brand] = await Promise.all([api.listVoiceSources(projectId), api.getBusinessContext(projectId)]);
48235
48235
  if (args.json) {
48236
48236
  console.log(JSON.stringify({ brand, profile, sources }, null, 2));
48237
48237
  return;
48238
48238
  }
48239
- process.stderr.write(`${brand.name} ${DIM}${brand.id}${RESET}
48239
+ if (brand)
48240
+ process.stderr.write(`${brand.name} ${DIM}${brand.id}${RESET}
48240
48241
  `);
48241
48242
  process.stderr.write(profile ? `
48242
48243
  ${profile.profile}
@@ -48284,11 +48285,11 @@ ${DIM}match ${profile.match}/100 · source ${profile.source}${RESET}
48284
48285
  return;
48285
48286
  }
48286
48287
  if (verb === "learn") {
48287
- process.stderr.write(`${DIM}learning voice for ${brand.name}…${RESET}
48288
+ process.stderr.write(`${DIM}learning voice…${RESET}
48288
48289
  `);
48289
48290
  const res = await api.refineBrandVoice(projectId, args["from-company"] ? "company" : undefined);
48290
48291
  if (!res.profile)
48291
- fail("Nothing to learn from — add answers or collect a source first");
48292
+ fail(args["from-company"] ? "No brand page to learn from — 'tfa-cli brand create <name>' and fill it first" : "Nothing to learn from — add answers, collect a source, or fill the brand page first");
48292
48293
  if (args.json) {
48293
48294
  console.log(JSON.stringify(res, null, 2));
48294
48295
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/cli",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-cli": "bin/todoforai-cli.js",