@todoforai/cli 0.1.48 → 0.1.49

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 (2) hide show
  1. package/dist/todoforai-cli.js +110 -74
  2. package/package.json +1 -1
@@ -44526,7 +44526,7 @@ import { parseArgs } from "util";
44526
44526
  // package.json
44527
44527
  var package_default = {
44528
44528
  name: "@todoforai/cli",
44529
- version: "0.1.48",
44529
+ version: "0.1.49",
44530
44530
  type: "module",
44531
44531
  bin: {
44532
44532
  "todoforai-cli": "bin/todoforai-cli.js",
@@ -44568,45 +44568,35 @@ function getEnv(name) {
44568
44568
  }
44569
44569
  function printUsage() {
44570
44570
  process.stderr.write(`
44571
- tfa-cli — TODOforAI CLI. Legacy aliases: todoforai-cli, todoai.
44571
+ tfa-cli — TODOforAI CLI
44572
44572
 
44573
- Usage:
44573
+ Usage: tfa-cli [OPTIONS] ["prompt"]
44574
+ tfa-cli [OPTIONS] <COMMAND> [ARGS]
44575
+
44576
+ Examples:
44574
44577
  tfa-cli login # Browser-based device auth
44575
- tfa-cli "prompt text" # Prompt as argument
44576
- tfa-cli -n "Quick task" # Non-interactive (run and exit)
44577
- echo "content" | tfa-cli # Pipe from stdin
44578
- tfa-cli --path /my/project "Fix bug" # Explicit workspace path
44579
- tfa-cli -c ["prompt"] # Resume last todo (optional prompt sent on attach)
44580
- tfa-cli --resume <todo-id> ["prompt"] # Resume specific todo (optional prompt sent on attach)
44581
- tfa-cli --inspect <todo-id>[@<slice>] # Read chat log. <slice> = -3:, :1, 5:10, 7 (Python-style)
44582
- tfa-cli start <id> # Start a TODO from the registry (todoregistry.com)
44583
- tfa-cli acp # Agent Client Protocol server on stdio (Zed, JetBrains, …; see README)
44584
- tfa-cli --list-agents # List available agents and exit
44585
- tfa-cli --list-models [filter] # List models usable with --model and exit
44586
- tfa-cli agent update <agent> model=<model> # Update agent settings (see 'agent --help'; also 'agent create')
44587
- tfa-cli todo set <todo-id|-> title=… group=… star=true # Edit a todo's fields (see 'todo --help')
44588
- tfa-cli project set|settings|groups|default|agent … # Edit the project, groups, defaults (see 'project --help')
44589
- tfa-cli brand list|create|select|voice … # Brands (business contexts) + voice learning (see 'brand --help')
44590
- tfa-cli device list|rename|wallpaper … # Paired machines (see 'device --help')
44591
- tfa-cli list [-n 30] [--cursor N] [--all] [--status S] # List todos (paginated); see 'list --help'
44592
- tfa-cli status <todo-id> <STATUS> # Update a todo's status (run 'status --help' for the full list)
44578
+ tfa-cli "prompt text" # New todo
44579
+ echo "content" | tfa-cli # From stdin
44580
+ tfa-cli start <id> # Registry template
44581
+ tfa-cli acp # Agent Client Protocol (stdio)
44582
+ tfa-cli agents # List agents
44583
+ tfa-cli models [filter] # Available models
44584
+ tfa-cli agent list|get|update|create # Agents (update <agent> model=…)
44585
+ tfa-cli todo set <todo-id|-> title=… group=… star=true # Edit a todo's fields
44586
+ tfa-cli project list|set|settings|groups|default|agent # Projects; edit the current one
44587
+ tfa-cli brand list|create|select|voice … # Brands (business contexts) + voice learning
44588
+ tfa-cli device list|rename|wallpaper # Paired machines
44589
+ tfa-cli list [-n 30] [--cursor N] [--all] [--status S] # List todos (paginated)
44590
+ tfa-cli status <todo-id> <STATUS> # Update a todo's status
44593
44591
  tfa-cli delete <todo-id> # Permanently delete a todo
44594
- tfa-cli addmessage <todo-id> "text" # Add a message to an existing todo
44595
- tfa-cli show <file|-> [todo-id] # Show a file in the chat (rendered by mimetype; - reads stdin)
44596
- # [--title T] [--alias A] [--mime M] [--card <name>] [--link] [--json]
44597
- # --link = compact chip (name+size+download) instead of inline render
44598
- # Prints "<todoId>:<alias|id> <public url>". Re-showing with the same
44599
- # --alias updates that block in place and pushes a new version to the
44600
- # same url (older versions stay reachable at /<id>/<version>).
44601
- tfa-cli show rm <ref|alias> # Take a shown file down (block, url, every version)
44602
- tfa-cli show list [todo-id] # List show blocks (ref, title, mime/url, card)
44603
- # [--project <id>] [--card <name>] [--json]
44604
- # no todo-id + --project (or $TODOFORAI_PROJECT_ID) = every todo
44605
- tfa-cli open <url> [todo-id] # Show a live http(s) url in the chat as a preview
44606
- # [--title T] [--alias A] [--json]
44607
- tfa-cli recommend --template <id> # Add a template as a recommendation card (see 'todoregistry-cli create')
44608
- tfa-cli claim mint --seed <projectId> [--emails a@x,b@y] [--ttl <sec>] # Mint /claim/<token> ownership links for a project you own
44609
- tfa-cli next [--direction "<text>"] # Ask the analyzer for growth recommendation cards (optional free-text steer)
44592
+ tfa-cli addmessage <todo-id> "text" # Send a message and exit (like -r, no watch/bridge)
44593
+ tfa-cli show <file|-> [todo-id] # Render a local file (image/pdf/html…) in the chat; - = stdin
44594
+ tfa-cli show list|rm … # List / take down shown files
44595
+ tfa-cli open <url> [todo-id] # Live url preview in the chat
44596
+ tfa-cli recommend --template <id> # Add a template as a recommendation card
44597
+ tfa-cli claim mint --seed <projectId> [--emails a@x,b@y] [--ttl <sec>] # Mint /claim/<token> links for a project you own
44598
+ tfa-cli next [--direction "<text>"] # Analyzer growth recommendation cards
44599
+ tfa-cli <command> help # Details per command
44610
44600
 
44611
44601
  Options:
44612
44602
  --path <dir> Workspace path (default: cwd)
@@ -44614,36 +44604,46 @@ Options:
44614
44604
  --agent, -a <name> Agent name (partial match)
44615
44605
  --group <slug> Group new todo; omitted inherits TODOFORAI_GROUP_ID
44616
44606
  --group-name <name> Display name for --group (last write wins)
44617
- --model <model> Override the agent's model for this todo
44618
- (e.g. anthropic:anthropic/claude-opus-5, openai:openai/gpt-5.6-sol)
44619
- --list-agents List available agents (name, id, workspace paths) and exit
44620
- --list-models List models usable with --model (optional substring filter) and exit
44621
- --api-url <url> API URL
44622
- --api-key <key> API key
44607
+ --model <model> Model for this todo only (see 'models')
44608
+ --api-url <url>
44609
+ --api-key <key>
44623
44610
  --user-id <id> Admin HTTP impersonation; requires --no-watch
44624
- --inspect, -i <todo-id>[@<slice>] Print chat log (read-only)
44625
- --template, -t <id> ["prompt"] Start from a registry template (alias: start <id>); prompt overrides the template task
44626
- --resume, -r [todo-id] Resume existing todo
44627
- --continue, -c Continue most recent todo
44628
- --non-interactive, -n Run to completion and exit without interactive prompt
44629
- --dangerously-skip-permissions Auto-approve all blocks (for CI/benchmarks)
44630
- --allow-all Set permissions to allow all tools (no approval needed)
44611
+ --inspect, -i <todo-id>[@<slice>] Read chat log; slices: -3:, :1, 5:10, 7
44612
+ --template, -t <id> ["prompt"] Same as start; prompt overrides template task
44613
+ --resume, -r <todo-id> ["prompt"] Resume; optional follow-up
44614
+ --continue, -c ["prompt"] Resume last; optional follow-up
44615
+ --non-interactive, -n Run to completion, then exit
44616
+ --dangerously-skip-permissions CLI auto-approves every block
44617
+ --allow-all Agent permissions allow:*:* nothing ever asks
44631
44618
  --raw-sysmsg <file> Use file contents verbatim as system prompt (new TODO only)
44632
44619
  --no-watch Create todo and exit
44633
- --isolated Spawn an ephemeral, task-scoped bridge: the agent sees ONLY
44634
- this machine (workspace = --path/cwd); session dies with the CLI
44620
+ --isolated Agent sees ONLY this machine + dir (no cloud VM/other devices); ends with CLI
44635
44621
  --no-bridge Do not auto-spawn bridge
44636
- --no-edge Deprecated alias for --no-bridge
44637
- --json Output as JSON
44638
- --detailed 'inspect --json': keep ids, timestamps, agentSettingsId, scheduledTimestamp
44639
- --format-anthropic 'inspect --json': Anthropic-style shape (tool_result in next user msg); attachment sources are uri-typed, so not a 1:1 messages.create input
44622
+ --json
44623
+ --detailed | --format-anthropic inspect --json: keep ids/timestamps | Anthropic messages shape
44640
44624
  --safe Validate API key upfront
44641
- --debug, -d Debug output
44625
+ --debug, -d
44642
44626
  --debug-dump Attach LLM request debug info per turn (requires server grant)
44643
- --show-config Show config
44644
- --reset-config Reset config file
44645
- --version, -v Print version and exit
44646
- --help, -h Show this help
44627
+ help | version | config = -h | -v | --show-config (--reset-config wipes it)
44628
+ `);
44629
+ }
44630
+ function printShowHelp() {
44631
+ process.stderr.write(`
44632
+ tfa-cli show — put a file or url into the chat
44633
+
44634
+ Usage:
44635
+ tfa-cli show <file|-> [todo-id] Render a file by mimetype (- reads stdin)
44636
+ [--title T] [--alias A] [--mime M] [--card <name>] [--link] [--json]
44637
+ --link: compact download chip instead of inline render
44638
+ Prints "<todoId>:<alias|id> <public url>". Re-showing with the same
44639
+ --alias updates the block in place; old versions stay at /<id>/<version>
44640
+ tfa-cli show rm <ref|alias> Take it down (block, url, every version)
44641
+ tfa-cli show list [todo-id] List show blocks (ref, title, mime/url, card)
44642
+ [--project <id>] [--card <name>] [--json]
44643
+ no todo-id + --project (or $TODOFORAI_PROJECT_ID) = every todo
44644
+ tfa-cli open <url> [todo-id] Live http(s) url as a preview [--title T] [--alias A] [--json]
44645
+
44646
+ todo-id defaults to $TODOFORAI_TODO_ID (agent shell) or the last todo this CLI touched.
44647
44647
  `);
44648
44648
  }
44649
44649
  var STATUS_HELP = {
@@ -44667,6 +44667,14 @@ All valid statuses:
44667
44667
  ${Object.values(TodoStatus).join(", ")}
44668
44668
  `);
44669
44669
  }
44670
+ var WORD_FLAGS = {
44671
+ help: "help",
44672
+ version: "version",
44673
+ models: "list-models",
44674
+ agents: "list-agents",
44675
+ config: "show-config"
44676
+ };
44677
+ var HELP_SUBCOMMANDS = ["agent", "todo", "project", "brand", "device", "list", "ls", "status", "show", "open"];
44670
44678
  function parseCliArgs() {
44671
44679
  const { values, positionals } = parseArgs({
44672
44680
  args: process.argv.slice(2),
@@ -44728,6 +44736,15 @@ function parseCliArgs() {
44728
44736
  });
44729
44737
  if (values["no-edge"])
44730
44738
  values["no-bridge"] = true;
44739
+ const asFlag = !values["list-models"] && !values["list-agents"] && !values["show-config"] ? WORD_FLAGS[positionals[0]] : undefined;
44740
+ if (asFlag) {
44741
+ values[asFlag] = true;
44742
+ positionals.shift();
44743
+ }
44744
+ if (positionals[1] === "help" && HELP_SUBCOMMANDS.includes(positionals[0])) {
44745
+ values.help = true;
44746
+ positionals.splice(1, 1);
44747
+ }
44731
44748
  return { values, positionals };
44732
44749
  }
44733
44750
 
@@ -47644,6 +47661,7 @@ tfa-cli project — edit the current project
47644
47661
  --project <id> or $TODOFORAI_PROJECT_ID selects the project.
47645
47662
 
47646
47663
  Usage:
47664
+ tfa-cli project list Projects you can access (* = default)
47647
47665
  tfa-cli project set <field=value>… name=… description=… brand=<businessContextId>
47648
47666
  (isPublic refused from an agent shell)
47649
47667
  tfa-cli project default Make it the project you land on at /
@@ -47725,6 +47743,19 @@ async function projectCommand(api, positionals, args) {
47725
47743
  printProjectHelp();
47726
47744
  process.exit(0);
47727
47745
  }
47746
+ if (sub === "list" || sub === "ls") {
47747
+ const projects = await api.listProjects();
47748
+ if (args.json) {
47749
+ console.log(JSON.stringify(projects, null, 2));
47750
+ return;
47751
+ }
47752
+ for (const p of projects) {
47753
+ const pr = p.project ?? p;
47754
+ process.stderr.write(`${pr.isDefault ? "*" : " "} ${pr.name ?? ""} ${DIM}${pr.id}${RESET}
47755
+ `);
47756
+ }
47757
+ return;
47758
+ }
47728
47759
  if (!projectId)
47729
47760
  fail("No project — pass --project <id> or set TODOFORAI_PROJECT_ID");
47730
47761
  if (sub === "set") {
@@ -72552,6 +72583,16 @@ function formatPathWithTilde(path5) {
72552
72583
  const home = homedir3();
72553
72584
  return path5.startsWith(home) ? path5.replace(home, "~") : path5;
72554
72585
  }
72586
+ function promptArg(words) {
72587
+ if (words.length === 0)
72588
+ return;
72589
+ if (words.length > 1 || !/\s/.test(words[0])) {
72590
+ process.stderr.write(`${RED3}Error: "${words.join(" ")}" is not a subcommand, and a prompt must be ONE quoted argument, e.g. tfa-cli "fix the login bug" (or pipe it on stdin). Run tfa-cli --help for subcommands.${RESET2}
72591
+ `);
72592
+ process.exit(2);
72593
+ }
72594
+ return words[0];
72595
+ }
72555
72596
  async function interactiveLoop(ws, api2, todoId, projectId, agent2, json2, autoApprove, cfg) {
72556
72597
  while (true) {
72557
72598
  try {
@@ -72653,6 +72694,10 @@ Cancelled by user (Ctrl+C)
72653
72694
  printStatusHelp();
72654
72695
  process.exit(0);
72655
72696
  }
72697
+ if ((positionals[0] === "show" || positionals[0] === "open") && args.help) {
72698
+ printShowHelp();
72699
+ process.exit(0);
72700
+ }
72656
72701
  if (positionals[0] === "agent" && args.help) {
72657
72702
  printAgentHelp();
72658
72703
  process.exit(0);
@@ -73143,7 +73188,7 @@ Cancelled by user (Ctrl+C)
73143
73188
  process.exit(1);
73144
73189
  }
73145
73190
  const promptWords = positionals[0] === "start" ? positionals.slice(2) : positionals;
73146
- const content2 = promptWords.join(" ").trim();
73191
+ const content2 = (promptArg(promptWords) ?? "").trim();
73147
73192
  const todo2 = await api2.startFromSpec(projectId2, templateId, {
73148
73193
  ...content2 ? { content: content2 } : {},
73149
73194
  ...groupTag ? { groupTag } : {},
@@ -73218,7 +73263,7 @@ Resumed: ${CYAN2}${getFrontendUrl(apiUrl, todoId)}${RESET2}
73218
73263
  const ws2 = new FrontendWebSocket(apiUrl, apiKey);
73219
73264
  await ws2.connect();
73220
73265
  const autoApprove = !!args["dangerously-skip-permissions"];
73221
- const followUp = positionals.length > 0 ? positionals.join(" ") : process.stdin.isTTY ? "" : await readStdin();
73266
+ const followUp = promptArg(positionals) ?? (process.stdin.isTTY ? "" : await readStdin());
73222
73267
  if (followUp) {
73223
73268
  cfg.addToHistory(followUp);
73224
73269
  await api2.addMessage(projectId2, followUp, agent3, todoId);
@@ -73236,11 +73281,7 @@ Resumed: ${CYAN2}${getFrontendUrl(apiUrl, todoId)}${RESET2}
73236
73281
  `);
73237
73282
  process.exit(2);
73238
73283
  }
73239
- if (positionals.length === 1 && !/\s/.test(positionals[0])) {
73240
- process.stderr.write(`${RED3}Error: "${positionals[0]}" is not a subcommand, and a prompt needs more than one word (or pipe it on stdin).${RESET2}
73241
- `);
73242
- process.exit(2);
73243
- }
73284
+ const argPrompt = promptArg(positionals);
73244
73285
  const ws = args["no-watch"] ? null : new FrontendWebSocket(apiUrl, apiKey);
73245
73286
  const wsReady = ws ? ws.connect() : null;
73246
73287
  const bridgeReady = !args["no-bridge"] && !args["no-watch"] && !args.isolated ? ensureBridgeRunning2(apiUrl, apiKey) : null;
@@ -73300,12 +73341,7 @@ Resumed: ${CYAN2}${getFrontendUrl(apiUrl, todoId)}${RESET2}
73300
73341
  }
73301
73342
  process.stderr.write(`${DIM2}Tip: ${randomTip()}${RESET2}
73302
73343
  `);
73303
- let content;
73304
- if (positionals.length > 0) {
73305
- content = positionals.join(" ");
73306
- } else {
73307
- content = await readStdin();
73308
- }
73344
+ const content = argPrompt ?? await readStdin();
73309
73345
  const envProjectId = getEnv("PROJECT_ID");
73310
73346
  const hasProject = args.project || envProjectId || cfgScope.data.default_project_id;
73311
73347
  const storedAgent = cfgScope.data.default_agent_settings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/cli",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-cli": "bin/todoforai-cli.js",