@todoforai/cli 0.1.61 → 0.1.62
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.
- package/dist/todoforai-cli.js +223 -62
- package/package.json +1 -1
package/dist/todoforai-cli.js
CHANGED
|
@@ -43055,6 +43055,19 @@ class ApiClient {
|
|
|
43055
43055
|
throw new Error(`API GET /resources/show failed: ${res.status} ${await res.text()}`);
|
|
43056
43056
|
return res.json();
|
|
43057
43057
|
}
|
|
43058
|
+
async shareShow(todoId, key) {
|
|
43059
|
+
const url = `${this.apiUrl}${restBasePath(this.apiKey)}/resources/show/${encodeURIComponent(todoId)}/${encodeURIComponent(key)}/share`;
|
|
43060
|
+
const res = await fetch(url, { method: "POST", headers: { "x-api-key": this.apiKey }, signal: AbortSignal.timeout(30000) });
|
|
43061
|
+
if (!res.ok)
|
|
43062
|
+
throw new Error(`API POST /resources/show/share failed: ${res.status} ${await res.text()}`);
|
|
43063
|
+
return res.json();
|
|
43064
|
+
}
|
|
43065
|
+
async unshareShow(todoId, key) {
|
|
43066
|
+
const url = `${this.apiUrl}${restBasePath(this.apiKey)}/resources/show/${encodeURIComponent(todoId)}/${encodeURIComponent(key)}/share`;
|
|
43067
|
+
const res = await fetch(url, { method: "DELETE", headers: { "x-api-key": this.apiKey }, signal: AbortSignal.timeout(30000) });
|
|
43068
|
+
if (!res.ok)
|
|
43069
|
+
throw new Error(`API DELETE /resources/show/share failed: ${res.status} ${await res.text()}`);
|
|
43070
|
+
}
|
|
43058
43071
|
async removeShow(todoId, key) {
|
|
43059
43072
|
const url = `${this.apiUrl}${restBasePath(this.apiKey)}/resources/show/${encodeURIComponent(todoId)}/${encodeURIComponent(key)}`;
|
|
43060
43073
|
const res = await fetch(url, {
|
|
@@ -43597,6 +43610,11 @@ function qualifiedModelIds(listing, filter) {
|
|
|
43597
43610
|
return q ? ids.filter((id) => id.toLowerCase().includes(q)) : ids;
|
|
43598
43611
|
}
|
|
43599
43612
|
// ../packages/shared-fbe/src/billing.ts
|
|
43613
|
+
var HOBBY_ALLOWED = new Set([
|
|
43614
|
+
"anthropic/claude-sonnet-5.5",
|
|
43615
|
+
"anthropic/claude-sonnet-5",
|
|
43616
|
+
"anthropic/claude-haiku-4.5"
|
|
43617
|
+
]);
|
|
43600
43618
|
var USAGE_WINDOWS = {
|
|
43601
43619
|
SESSION_MS: 5 * 60 * 60 * 1000,
|
|
43602
43620
|
WEEK_MS: 7 * 24 * 60 * 60 * 1000,
|
|
@@ -43901,6 +43919,15 @@ function manualAnswersOf(sources) {
|
|
|
43901
43919
|
}
|
|
43902
43920
|
var manualSamples = (answers) => Object.entries(answers).filter(([, a]) => a.trim()).map(([prompt, text]) => ({ prompt, text: text.trim() }));
|
|
43903
43921
|
var senderLabel = (s) => s.kind === "team" ? `${s.name} · TODO for AI team` : s.kind === "member" ? `${s.name} · teammate` : `${s.name} · your agent`;
|
|
43922
|
+
// ../packages/shared-fbe/src/jarvisEvents.ts
|
|
43923
|
+
var STATE = {
|
|
43924
|
+
["READY" /* READY */]: "agent ended its run and handed back; not opened yet",
|
|
43925
|
+
["READY_CHECKED" /* READY_CHECKED */]: "agent ended its run and handed back; its window was opened",
|
|
43926
|
+
["DONE" /* DONE */]: "done and closed",
|
|
43927
|
+
["ERROR" /* ERROR */]: "failed; not opened yet",
|
|
43928
|
+
["ERROR_CHECKED" /* ERROR_CHECKED */]: "failed; its window was opened",
|
|
43929
|
+
["WAITING_FOR_USER" /* WAITING_FOR_USER */]: "blocked, waiting on the user's answer or approval"
|
|
43930
|
+
};
|
|
43904
43931
|
// ../packages/shared-fbe/src/templateBody.ts
|
|
43905
43932
|
var USER_HEADINGS = new Set([
|
|
43906
43933
|
"your task",
|
|
@@ -44478,6 +44505,7 @@ var tool_catalog_default = {
|
|
|
44478
44505
|
versionCmd: "linkedin-api --version 2>/dev/null | sed -n 1p"
|
|
44479
44506
|
},
|
|
44480
44507
|
"figma-api": {
|
|
44508
|
+
preinstallCloud: true,
|
|
44481
44509
|
category: "design",
|
|
44482
44510
|
pkg: "@todoforai/figma-api",
|
|
44483
44511
|
installer: "npm",
|
|
@@ -44612,6 +44640,20 @@ var tool_catalog_default = {
|
|
|
44612
44640
|
],
|
|
44613
44641
|
description: "AI music generation, custom lyrics, multiple genres."
|
|
44614
44642
|
},
|
|
44643
|
+
"tfa-suno": {
|
|
44644
|
+
preinstallCloud: true,
|
|
44645
|
+
category: "media",
|
|
44646
|
+
pkg: "@todoforai/suno-api",
|
|
44647
|
+
installer: "npm",
|
|
44648
|
+
label: "Suno (TODOforAI)",
|
|
44649
|
+
summary: "Generate music and songs from a prompt, billed to your TODOforAI credit.",
|
|
44650
|
+
platformAuth: true,
|
|
44651
|
+
versionCmd: "tfa-suno --version 2>/dev/null | sed -n 1p",
|
|
44652
|
+
credentialPaths: [
|
|
44653
|
+
"~/.config/todoforai/credentials.json"
|
|
44654
|
+
],
|
|
44655
|
+
description: "Suno music generation via TODOforAI — no Suno key needed, billed to the user's TODOforAI credit (generate $0.12 for 2 songs, refunded if the task fails). Same commands as suno-api: `generate [prompt] [--customMode --lyrics <file> --style --title] [--instrumental] [--model V6]` polls until done and prints audio URLs; `--no-poll` + `details <taskId> [--wait]`; `stems`, `midi`, `lyrics-ts`, `replace-section`. Audio URLs expire after 14 days — download the mp3s you keep. Prefer this over suno-api unless the user has their own sunoapi.org key."
|
|
44656
|
+
},
|
|
44615
44657
|
ntn: {
|
|
44616
44658
|
preinstallCloud: true,
|
|
44617
44659
|
category: "utility",
|
|
@@ -44672,6 +44714,9 @@ var tool_catalog_default = {
|
|
|
44672
44714
|
preinstallCloud: true
|
|
44673
44715
|
},
|
|
44674
44716
|
glab: {
|
|
44717
|
+
preinstallCloud: true,
|
|
44718
|
+
cloudInstallCmd: "curl -fsSL https://gitlab.com/gitlab-org/cli/-/releases/v1.119.0/downloads/glab_1.119.0_linux_amd64.tar.gz | tar -xz -C /tmp bin/glab && install -m0755 /tmp/bin/glab /usr/local/bin/glab",
|
|
44719
|
+
cloudVerifyCmd: "glab --version",
|
|
44675
44720
|
category: "development",
|
|
44676
44721
|
pkg: "glab",
|
|
44677
44722
|
installer: "binary",
|
|
@@ -44703,6 +44748,7 @@ var tool_catalog_default = {
|
|
|
44703
44748
|
canStreamLogin: true
|
|
44704
44749
|
},
|
|
44705
44750
|
eas: {
|
|
44751
|
+
preinstallCloud: true,
|
|
44706
44752
|
category: "deployment",
|
|
44707
44753
|
pkg: "eas-cli",
|
|
44708
44754
|
installer: "npm",
|
|
@@ -44718,6 +44764,7 @@ var tool_catalog_default = {
|
|
|
44718
44764
|
versionCmd: "eas --version 2>/dev/null | sed -n 1p"
|
|
44719
44765
|
},
|
|
44720
44766
|
netlify: {
|
|
44767
|
+
preinstallCloud: true,
|
|
44721
44768
|
category: "deployment",
|
|
44722
44769
|
pkg: "netlify-cli",
|
|
44723
44770
|
installer: "npm",
|
|
@@ -44783,6 +44830,9 @@ var tool_catalog_default = {
|
|
|
44783
44830
|
canStreamLogin: true
|
|
44784
44831
|
},
|
|
44785
44832
|
flyctl: {
|
|
44833
|
+
preinstallCloud: true,
|
|
44834
|
+
cloudInstallCmd: "curl -fsSL https://github.com/superfly/flyctl/releases/download/v0.4.108/flyctl_0.4.108_Linux_x86_64.tar.gz | tar -xz -C /usr/local/bin flyctl",
|
|
44835
|
+
cloudVerifyCmd: "flyctl version",
|
|
44786
44836
|
category: "cloud",
|
|
44787
44837
|
pkg: "flyctl",
|
|
44788
44838
|
installer: "binary",
|
|
@@ -44810,6 +44860,7 @@ var tool_catalog_default = {
|
|
|
44810
44860
|
versionCmd: "supabase --version 2>/dev/null | sed -n 1p"
|
|
44811
44861
|
},
|
|
44812
44862
|
railway: {
|
|
44863
|
+
preinstallCloud: true,
|
|
44813
44864
|
category: "cloud",
|
|
44814
44865
|
pkg: "@railway/cli",
|
|
44815
44866
|
installer: "npm",
|
|
@@ -44851,6 +44902,7 @@ var tool_catalog_default = {
|
|
|
44851
44902
|
versionCmd: "shop-app --version 2>/dev/null | sed -n 1p"
|
|
44852
44903
|
},
|
|
44853
44904
|
"datadog-ci": {
|
|
44905
|
+
preinstallCloud: true,
|
|
44854
44906
|
category: "monitoring",
|
|
44855
44907
|
pkg: "@datadog/datadog-ci",
|
|
44856
44908
|
installer: "npm",
|
|
@@ -44879,7 +44931,7 @@ var tool_catalog_default = {
|
|
|
44879
44931
|
installer: "npm",
|
|
44880
44932
|
label: "TODOforAI",
|
|
44881
44933
|
summary: "Create and follow up on your TODOs, and show results in the chat.",
|
|
44882
|
-
description: 'Manage the user\'s OWN TODOforAI tasks (not code `// TODO` comments). Delegate/spin off work: `tfa-cli "prompt"` creates a real TODO with its own agent and chat (`-n` wait for completion, `--no-watch` fire-and-forget, `--project/--agent/--model`, `--resume <id>`, `addmessage <id> "text"`). Inspect: `list [--status open]`, `--inspect <id>`. Edit any todo without opening it: `status <id> DONE|READY|ARCHIVED|POSTPONED|CANCELLED|DELETED` (close, reopen, shelve, trash — `todo restore <id>` undoes a delete) and `todo set <id|-> title=… group=… star=true schedule=<unix-ms> agent=… brand=…` (own todo fields). Both take ONE id, so a loop over `list --json | jq -r \'.items[].id\'` is how you close, retitle, refile or archive MANY todos at once; `project set|settings|groups …` (name, settings, todo groups), `agent create|update <agent> model=… sysmsg=…` (permissions/MCP/device wiring and delete are refused from an agent shell). Surface results into chat: `show <file|-> [todo-id]` (renders by mimetype; `--card <name>` via project renderer; `--alias <name>` updates in place), `open <url>` embeds a live preview. Notifications: `inbox [needs-you|messages|activity] [--unread]` reads the user\'s bell feed (what finished/failed/needs them while away), `inbox seen [tab]` marks it read; `notify "Title" "message" [--href /t/<id>]` leaves a note in the user\'s Messages tab + phone push (shown as from you); `--to <email>` reaches a member of the current project instead (`project members` lists them, 20/day) — nobody else; same text is delivered once, max 10/day to the user, use for things they must see later (not chat replies). This is the ONLY way to display a local file (image, pdf, html) in the chat: markdown `` with a local/relative path does NOT resolve to workspace files or attachments and 404s in the browser. `--template` for registry workflows.',
|
|
44934
|
+
description: 'Manage the user\'s OWN TODOforAI tasks (not code `// TODO` comments). Delegate/spin off work: `tfa-cli "prompt"` creates a real TODO with its own agent and chat (`-n` wait for completion, `--no-watch` fire-and-forget, `--project/--agent/--model`, `--resume <id>`, `addmessage <id> "text"`). Inspect: `list [--status open]`, `--inspect <id>`. Edit any todo without opening it: `status <id> DONE|READY|ARCHIVED|POSTPONED|CANCELLED|DELETED` (close, reopen, shelve, trash — `todo restore <id>` undoes a delete) and `todo set <id|-> title=… group=… star=true schedule=<unix-ms> agent=… brand=…` (own todo fields). Both take ONE id, so a loop over `list --json | jq -r \'.items[].id\'` is how you close, retitle, refile or archive MANY todos at once; `project set|settings|groups …` (name, settings, todo groups), `agent create|update <agent> model=… sysmsg=…` (permissions/MCP/device wiring and delete are refused from an agent shell). Surface results into chat: `show <file|-> [todo-id]` (renders by mimetype, private to the todo\'s readers; `--card <name>` via project renderer; `--alias <name>` updates in place, `--alias <todoId>:<name>` updates another todo\'s artifact; `show share <ref>` makes it public and prints the link, `show unshare <ref>` makes it private again), `open <url>` embeds a live preview. Pick by where the output lives: read once → plain reply; interactive, this chat only → `html_snippet`; kept/revised later → `show --alias`, then `show share` only if someone outside needs a link; format the user asked for (pptx, docx…) → `show` the file. Notifications: `inbox [needs-you|messages|activity] [--unread]` reads the user\'s bell feed (what finished/failed/needs them while away), `inbox seen [tab]` marks it read; `notify "Title" "message" [--href /t/<id>]` leaves a note in the user\'s Messages tab + phone push (shown as from you); `--to <email>` reaches a member of the current project instead (`project members` lists them, 20/day) — nobody else; same text is delivered once, max 10/day to the user, use for things they must see later (not chat replies). This is the ONLY way to display a local file (image, pdf, html) in the chat: markdown `` with a local/relative path does NOT resolve to workspace files or attachments and 404s in the browser. `--template` for registry workflows.',
|
|
44883
44935
|
installCmd: "npm install -g @todoforai/cli",
|
|
44884
44936
|
versionCmd: "tfa-cli --version 2>/dev/null | sed -n 1p",
|
|
44885
44937
|
preinstallCloud: true,
|
|
@@ -45006,7 +45058,7 @@ var tool_catalog_default = {
|
|
|
45006
45058
|
label: "Google Cloud",
|
|
45007
45059
|
summary: "Manage your Google Cloud projects and services.",
|
|
45008
45060
|
needsPython: true,
|
|
45009
|
-
installCmd: `curl -fsSL https://dl.google.com/dl/cloudsdk/channels/rapid/google-cloud-
|
|
45061
|
+
installCmd: `case "$(uname -s)-$(uname -m)" in Darwin-arm64) p=darwin-arm;; Darwin-*) p=darwin-x86_64;; Linux-aarch64|Linux-arm64) p=linux-arm;; *) p=linux-x86_64;; esac && tmp="$HOME/.gcloud-new.$$" && rm -rf "$tmp" && mkdir -p "$tmp" && curl -fsSL "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-$p.tar.gz" | tar -xzC "$tmp" && rm -rf "$HOME/google-cloud-sdk" && mv "$tmp/google-cloud-sdk" "$HOME/google-cloud-sdk" && rm -rf "$tmp" && mkdir -p "$HOME/.todoforai/tools/bin" && rm -f "$HOME/.todoforai/tools/bin/gcloud" && printf '#!/bin/sh\\nCLOUDSDK_PYTHON="\${CLOUDSDK_PYTHON:-%s}" exec "$HOME/google-cloud-sdk/bin/gcloud" "$@"\\n' "$py" > "$HOME/.todoforai/tools/bin/gcloud" && chmod +x "$HOME/.todoforai/tools/bin/gcloud"`,
|
|
45010
45062
|
statusCmd: `gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null | tr -d '\\r' | grep -m1 .`,
|
|
45011
45063
|
loginCmd: "gcloud auth login --no-launch-browser",
|
|
45012
45064
|
loginNeedsPty: true,
|
|
@@ -45015,8 +45067,7 @@ var tool_catalog_default = {
|
|
|
45015
45067
|
credentialPaths: ["~/.config/gcloud"],
|
|
45016
45068
|
description: "Official Google Cloud CLI. `gcloud auth login --no-launch-browser` prints the OAuth URL and waits for the pasted verification code.",
|
|
45017
45069
|
versionCmd: "gcloud --version 2>/dev/null | sed -n 1p",
|
|
45018
|
-
uninstallCmd: 'rm -rf "$HOME/google-cloud-sdk" "$HOME/.todoforai/tools/bin/gcloud"; hash -r 2>/dev/null; ! command -v gcloud >/dev/null 2>&1 || { echo "gcloud is still on PATH: $(command -v gcloud)"; exit 1; }'
|
|
45019
|
-
updateCmd: "gcloud components update --quiet"
|
|
45070
|
+
uninstallCmd: 'rm -rf "$HOME/google-cloud-sdk" "$HOME/.todoforai/tools/bin/gcloud"; hash -r 2>/dev/null; ! command -v gcloud >/dev/null 2>&1 || { echo "gcloud is still on PATH: $(command -v gcloud)"; exit 1; }'
|
|
45020
45071
|
},
|
|
45021
45072
|
az: {
|
|
45022
45073
|
category: "cloud",
|
|
@@ -45150,19 +45201,6 @@ var tool_catalog_default = {
|
|
|
45150
45201
|
},
|
|
45151
45202
|
preinstallJarvis: true
|
|
45152
45203
|
},
|
|
45153
|
-
"todoforai-browser": {
|
|
45154
|
-
category: "development",
|
|
45155
|
-
pkg: "@todoforai/browser",
|
|
45156
|
-
aliases: ["tfa-browser"],
|
|
45157
|
-
installer: "npm",
|
|
45158
|
-
preinstallCloud: true,
|
|
45159
|
-
label: "Browser (Extension)",
|
|
45160
|
-
summary: "Drive your own browser through the TODOforAI extension.",
|
|
45161
|
-
versionCmd: `node -p "require(require('fs').realpathSync(require('child_process').execSync('command -v todoforai-browser',{encoding:'utf8'}).trim()).replace(/\\/dist\\/index\\.js$/, '/package.json')).version" 2>/dev/null`,
|
|
45162
|
-
internal: true,
|
|
45163
|
-
preinstallJarvis: true,
|
|
45164
|
-
description: "Browser automation via extension (non-headless), web scraping, accessibility tree snapshots, screenshots, PDF generation"
|
|
45165
|
-
},
|
|
45166
45204
|
"tfa-explore": {
|
|
45167
45205
|
preinstallCloud: true,
|
|
45168
45206
|
category: "development",
|
|
@@ -45633,6 +45671,20 @@ var tool_catalog_default = {
|
|
|
45633
45671
|
description: "WordPress REST API CLI. `wordpress-api auth --site https://example.com --user <user> --password '<application password>'` (application password, not the login password). Reading published content needs no auth. `posts list|get|create|update|delete`, `pages`, `media`, `categories`. `posts create` saves a draft unless --status publish. On Elementor/JetEngine sites content.rendered comes back empty — fetch the post's public URL for the body.",
|
|
45634
45672
|
versionCmd: "wordpress-api --version 2>/dev/null | sed -n 1p"
|
|
45635
45673
|
},
|
|
45674
|
+
"mailchimp-api": {
|
|
45675
|
+
category: "marketing",
|
|
45676
|
+
pkg: "@todoforai/mailchimp-api",
|
|
45677
|
+
installer: "npm",
|
|
45678
|
+
label: "Mailchimp",
|
|
45679
|
+
summary: "Manage Mailchimp audiences, contacts, email campaigns and reports.",
|
|
45680
|
+
loginCmd: "mailchimp-api auth --api-key <api_key>",
|
|
45681
|
+
statusCmd: `mailchimp-api whoami 2>/dev/null | sed -n 's/.*"account_name"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m1 .`,
|
|
45682
|
+
credentialPaths: [
|
|
45683
|
+
"~/.config/mailchimp-api/credentials.json"
|
|
45684
|
+
],
|
|
45685
|
+
versionCmd: "mailchimp-api --version 2>/dev/null | sed -n 1p",
|
|
45686
|
+
description: "Independent CLI over the official Mailchimp Marketing API: 155 endpoint commands for lists (email audiences), members (contacts; email or MD5), tags, segments, merge fields, interests, notes/events, campaigns/content/tests/scheduling, templates, reports, assets, landing pages, classic automations, journey triggers, webhooks and batches. JSON output; --data JSON|@file|-; --schema; --all pagination. Every write requires --yes; use --dry-run first. Raw request METHOD /path covers other Marketing endpoints. API-key auth, not OAuth onboarding. Plan/API restrictions apply; no Transactional/Mandrill or Open Commerce. Run --help for limits and consent cautions."
|
|
45687
|
+
},
|
|
45636
45688
|
"facebook-pages-api": {
|
|
45637
45689
|
preinstallCloud: true,
|
|
45638
45690
|
category: "social",
|
|
@@ -45647,8 +45699,10 @@ var tool_catalog_default = {
|
|
|
45647
45699
|
versionCmd: "facebook-pages-api --version 2>/dev/null | sed -n 1p"
|
|
45648
45700
|
},
|
|
45649
45701
|
"ews-api": {
|
|
45702
|
+
preinstallCloud: true,
|
|
45650
45703
|
category: "email",
|
|
45651
45704
|
pkg: "ews-api",
|
|
45705
|
+
packages: ["ews-api==0.2.0"],
|
|
45652
45706
|
installer: "pip",
|
|
45653
45707
|
label: "Exchange (EWS)",
|
|
45654
45708
|
summary: "Read and write mail on a company Exchange server.",
|
|
@@ -45676,6 +45730,7 @@ var tool_catalog_default = {
|
|
|
45676
45730
|
canStreamLogin: true
|
|
45677
45731
|
},
|
|
45678
45732
|
neonctl: {
|
|
45733
|
+
preinstallCloud: true,
|
|
45679
45734
|
category: "database",
|
|
45680
45735
|
pkg: "neonctl",
|
|
45681
45736
|
installer: "npm",
|
|
@@ -45698,7 +45753,7 @@ var tool_catalog_default = {
|
|
|
45698
45753
|
label: "Microsoft 365",
|
|
45699
45754
|
summary: "Work with Microsoft 365 mail, Teams, SharePoint and users.",
|
|
45700
45755
|
statusCmd: `m365 status --output text 2>/dev/null | tr -d '"' | grep -vi 'logged out' | grep -m1 .`,
|
|
45701
|
-
loginCmd: "m365 login --authType deviceCode --appId
|
|
45756
|
+
loginCmd: "m365 login --authType deviceCode --appId 14d82eec-204b-4c2f-b7e8-296a70dab67e",
|
|
45702
45757
|
deviceCodePattern: "enter the code ([A-Z0-9]{8,}) to authenticate",
|
|
45703
45758
|
oauthUrlPattern: "open the page (https://\\S+) and enter",
|
|
45704
45759
|
credentialPaths: ["~/.cli-m365-msal.json", "~/.cli-m365-connection.json"],
|
|
@@ -45737,6 +45792,7 @@ var tool_catalog_default = {
|
|
|
45737
45792
|
versionCmd: "posthog-cli --version 2>/dev/null | sed -n 1p"
|
|
45738
45793
|
},
|
|
45739
45794
|
canva: {
|
|
45795
|
+
preinstallCloud: true,
|
|
45740
45796
|
category: "design",
|
|
45741
45797
|
pkg: "@canva/cli",
|
|
45742
45798
|
installer: "npm",
|
|
@@ -45752,6 +45808,7 @@ var tool_catalog_default = {
|
|
|
45752
45808
|
oauthUrlPattern: "OPEN_URL: (https://www\\.canva\\.com/api/oauth/authorize\\S+)"
|
|
45753
45809
|
},
|
|
45754
45810
|
webflow: {
|
|
45811
|
+
preinstallCloud: true,
|
|
45755
45812
|
category: "development",
|
|
45756
45813
|
pkg: "@webflow/webflow-cli",
|
|
45757
45814
|
installer: "npm",
|
|
@@ -45766,6 +45823,7 @@ var tool_catalog_default = {
|
|
|
45766
45823
|
versionCmd: "webflow --version 2>/dev/null | sed -n 1p"
|
|
45767
45824
|
},
|
|
45768
45825
|
readwise: {
|
|
45826
|
+
preinstallCloud: true,
|
|
45769
45827
|
category: "productivity",
|
|
45770
45828
|
pkg: "@readwise/cli",
|
|
45771
45829
|
installer: "npm",
|
|
@@ -45836,6 +45894,7 @@ var tool_catalog_default = {
|
|
|
45836
45894
|
versionCmd: "exa --version 2>/dev/null | sed -n 1p"
|
|
45837
45895
|
},
|
|
45838
45896
|
mobbin: {
|
|
45897
|
+
preinstallCloud: true,
|
|
45839
45898
|
category: "design",
|
|
45840
45899
|
pkg: "mobbin",
|
|
45841
45900
|
installer: "npm",
|
|
@@ -45866,6 +45925,7 @@ var tool_catalog_default = {
|
|
|
45866
45925
|
versionCmd: "{ python -c 'import sys; from importlib.metadata import version; print(version(sys.argv[1]))' blender-mcp || python3 -c 'import sys; from importlib.metadata import version; print(version(sys.argv[1]))' blender-mcp; } 2>/dev/null"
|
|
45867
45926
|
},
|
|
45868
45927
|
"google-ads": {
|
|
45928
|
+
preinstallCloud: true,
|
|
45869
45929
|
category: "marketing",
|
|
45870
45930
|
pkg: "google-ads",
|
|
45871
45931
|
packages: [
|
|
@@ -45935,6 +45995,7 @@ var model_promos_default = {
|
|
|
45935
45995
|
{ family: "gpt-5-6-sol", rate: 0.85, starts: "2026-08-26", ends: "2026-09-13" },
|
|
45936
45996
|
{ family: "gpt-5-6-sol", rate: 0.8, starts: "2026-09-14", ends: "2026-11-21" },
|
|
45937
45997
|
{ family: "gpt-6-sol", rate: 0.8, starts: "2026-09-22", ends: "2026-11-21" },
|
|
45998
|
+
{ family: "gpt-6-1-sol", rate: 0.8, starts: "2026-09-29", ends: "2026-11-21" },
|
|
45938
45999
|
{ family: "gpt-6-luna", rate: 0.8, starts: "2026-09-22", ends: "2026-11-21" },
|
|
45939
46000
|
{ family: "gpt-6-astra", rate: 0.85, starts: "2026-09-05", ends: "2026-09-13", boostable: false },
|
|
45940
46001
|
{ family: "gpt-6-astra", rate: 0.8, starts: "2026-09-14", ends: "2026-11-21", boostable: false },
|
|
@@ -46135,7 +46196,7 @@ import { parseArgs } from "util";
|
|
|
46135
46196
|
// package.json
|
|
46136
46197
|
var package_default = {
|
|
46137
46198
|
name: "@todoforai/cli",
|
|
46138
|
-
version: "0.1.
|
|
46199
|
+
version: "0.1.62",
|
|
46139
46200
|
type: "module",
|
|
46140
46201
|
bin: {
|
|
46141
46202
|
"todoforai-cli": "bin/todoforai-cli.js",
|
|
@@ -46247,15 +46308,27 @@ Usage:
|
|
|
46247
46308
|
tfa-cli show <file|-> [todo-id] Render a file by mimetype (- reads stdin)
|
|
46248
46309
|
[--title T] [--alias A] [--mime M] [--card <name>] [--link] [--json]
|
|
46249
46310
|
--link: compact download chip instead of inline render
|
|
46250
|
-
Prints "<todoId>:<alias|id>
|
|
46251
|
-
--alias updates the block in place
|
|
46252
|
-
|
|
46311
|
+
Prints "<todoId>:<alias|id>". Private: visible to whoever can read the todo.
|
|
46312
|
+
Re-showing with the same --alias updates the block in place (new version)
|
|
46313
|
+
--alias <todoId>:<alias> updates that todo's block instead,
|
|
46314
|
+
so a later chat can revise an artifact made elsewhere
|
|
46315
|
+
tfa-cli show share <ref|alias> Make it public; prints its link (serves the latest version)
|
|
46316
|
+
tfa-cli show unshare <ref|alias> Make it private again (the link stops working)
|
|
46317
|
+
tfa-cli show rm <ref|alias> Take it down (block, link, every version)
|
|
46253
46318
|
tfa-cli show list [todo-id] List show blocks (ref, title, mime/url, card)
|
|
46254
46319
|
[--project <id>] [--card <name>] [--json]
|
|
46255
46320
|
no todo-id + --project (or $TODOFORAI_PROJECT_ID) = every todo
|
|
46256
46321
|
tfa-cli open <url> [todo-id] Live http(s) url as a preview [--title T] [--alias A] [--json]
|
|
46257
46322
|
|
|
46258
46323
|
todo-id defaults to $TODOFORAI_TODO_ID (agent shell) or the last todo this CLI touched.
|
|
46324
|
+
|
|
46325
|
+
When to use what:
|
|
46326
|
+
read once, move on → plain chat reply
|
|
46327
|
+
interactive, this chat only → html_snippet (can exec/connect/chat back)
|
|
46328
|
+
keep / revise later → show <file> --alias <name> (versioned, private)
|
|
46329
|
+
someone outside needs it → show share <alias> (public link, revocable)
|
|
46330
|
+
a live web page → open <url>
|
|
46331
|
+
a format the user asked for → show the file (pptx, docx, xlsx, pdf…)
|
|
46259
46332
|
`);
|
|
46260
46333
|
}
|
|
46261
46334
|
var STATUS_HELP = {
|
|
@@ -48308,7 +48381,7 @@ var createBuilder = (self, _styler, _isEmpty) => {
|
|
|
48308
48381
|
return applyStyle(builder, "" + arguments_[0]);
|
|
48309
48382
|
}
|
|
48310
48383
|
if (arguments_.length === 2) {
|
|
48311
|
-
return applyStyle(builder, arguments_[0]
|
|
48384
|
+
return applyStyle(builder, `${arguments_[0] ?? ""} ${arguments_[1] ?? ""}`);
|
|
48312
48385
|
}
|
|
48313
48386
|
return applyStyle(builder, arguments_.join(" "));
|
|
48314
48387
|
};
|
|
@@ -56024,7 +56097,7 @@ class $ZodCyclicError extends Error {
|
|
|
56024
56097
|
this.name = "ZodCyclicError";
|
|
56025
56098
|
}
|
|
56026
56099
|
}
|
|
56027
|
-
var
|
|
56100
|
+
var STATE2 = "~memo";
|
|
56028
56101
|
var NO_ISSUES = [];
|
|
56029
56102
|
function isRef(value) {
|
|
56030
56103
|
return value !== null && typeof value === "object";
|
|
@@ -56234,10 +56307,10 @@ var memo = {
|
|
|
56234
56307
|
const input = payload.value;
|
|
56235
56308
|
if (!isRef(input))
|
|
56236
56309
|
return base(payload, ctx);
|
|
56237
|
-
let state = ctx[
|
|
56310
|
+
let state = ctx[STATE2];
|
|
56238
56311
|
if (!state) {
|
|
56239
56312
|
state = { buckets: new WeakMap, backEdges: undefined };
|
|
56240
|
-
ctx[
|
|
56313
|
+
ctx[STATE2] = state;
|
|
56241
56314
|
}
|
|
56242
56315
|
let bucket;
|
|
56243
56316
|
if (lastCtx === ctx) {
|
|
@@ -56286,7 +56359,7 @@ function memoizer() {
|
|
|
56286
56359
|
return memo;
|
|
56287
56360
|
}
|
|
56288
56361
|
function isBackEdge(ctx, value) {
|
|
56289
|
-
const backEdges = ctx[
|
|
56362
|
+
const backEdges = ctx[STATE2]?.backEdges;
|
|
56290
56363
|
return backEdges !== undefined && isRef(value) && backEdges.has(value);
|
|
56291
56364
|
}
|
|
56292
56365
|
// node_modules/zod/v4/locales/index.js
|
|
@@ -73525,53 +73598,124 @@ function protocolErrorResponse(error62) {
|
|
|
73525
73598
|
};
|
|
73526
73599
|
}
|
|
73527
73600
|
|
|
73601
|
+
// node_modules/@agentclientprotocol/sdk/dist/stream-limits.js
|
|
73602
|
+
var DEFAULT_MAX_MESSAGE_BYTES = 32 * 1024 * 1024;
|
|
73603
|
+
|
|
73604
|
+
class MessageTooLargeError extends Error {
|
|
73605
|
+
maxMessageBytes;
|
|
73606
|
+
constructor(maxMessageBytes) {
|
|
73607
|
+
super(`Incoming ACP data exceeds the configured ${maxMessageBytes} byte limit`);
|
|
73608
|
+
this.maxMessageBytes = maxMessageBytes;
|
|
73609
|
+
this.name = "MessageTooLargeError";
|
|
73610
|
+
}
|
|
73611
|
+
}
|
|
73612
|
+
function resolveMaxMessageBytes(value) {
|
|
73613
|
+
const maxMessageBytes = value ?? DEFAULT_MAX_MESSAGE_BYTES;
|
|
73614
|
+
if (!Number.isSafeInteger(maxMessageBytes) || maxMessageBytes <= 0) {
|
|
73615
|
+
throw new RangeError("maxMessageBytes must be a positive safe integer");
|
|
73616
|
+
}
|
|
73617
|
+
return maxMessageBytes;
|
|
73618
|
+
}
|
|
73619
|
+
|
|
73620
|
+
class MessageBuffer {
|
|
73621
|
+
#buffer = new Uint8Array(0);
|
|
73622
|
+
#length = 0;
|
|
73623
|
+
#maxMessageBytes;
|
|
73624
|
+
constructor(maxMessageBytes) {
|
|
73625
|
+
this.#maxMessageBytes = resolveMaxMessageBytes(maxMessageBytes);
|
|
73626
|
+
}
|
|
73627
|
+
get byteLength() {
|
|
73628
|
+
return this.#length;
|
|
73629
|
+
}
|
|
73630
|
+
get lastByte() {
|
|
73631
|
+
return this.#buffer[this.#length - 1];
|
|
73632
|
+
}
|
|
73633
|
+
#checkAppend(byteLength) {
|
|
73634
|
+
if (byteLength > this.#maxMessageBytes - this.#length) {
|
|
73635
|
+
this.clear();
|
|
73636
|
+
throw new MessageTooLargeError(this.#maxMessageBytes);
|
|
73637
|
+
}
|
|
73638
|
+
}
|
|
73639
|
+
append(bytes) {
|
|
73640
|
+
this.#checkAppend(bytes.byteLength);
|
|
73641
|
+
const length = this.#length + bytes.byteLength;
|
|
73642
|
+
if (length > this.#buffer.byteLength) {
|
|
73643
|
+
const capacity = Math.min(this.#maxMessageBytes, Math.max(length, this.#buffer.byteLength * 2, 1024));
|
|
73644
|
+
const buffer = new Uint8Array(capacity);
|
|
73645
|
+
buffer.set(this.#buffer.subarray(0, this.#length));
|
|
73646
|
+
this.#buffer = buffer;
|
|
73647
|
+
}
|
|
73648
|
+
this.#buffer.set(bytes, this.#length);
|
|
73649
|
+
this.#length = length;
|
|
73650
|
+
}
|
|
73651
|
+
take() {
|
|
73652
|
+
const bytes = this.#buffer.subarray(0, this.#length);
|
|
73653
|
+
this.clear();
|
|
73654
|
+
return bytes;
|
|
73655
|
+
}
|
|
73656
|
+
clear() {
|
|
73657
|
+
this.#buffer = new Uint8Array(0);
|
|
73658
|
+
this.#length = 0;
|
|
73659
|
+
}
|
|
73660
|
+
}
|
|
73661
|
+
|
|
73528
73662
|
// node_modules/@agentclientprotocol/sdk/dist/line-buffer.js
|
|
73529
73663
|
var newline = 10;
|
|
73530
73664
|
|
|
73531
73665
|
class LineBuffer {
|
|
73532
|
-
#pending
|
|
73533
|
-
|
|
73534
|
-
|
|
73666
|
+
#pending;
|
|
73667
|
+
#maxMessageBytes;
|
|
73668
|
+
constructor(maxMessageBytes) {
|
|
73669
|
+
this.#maxMessageBytes = resolveMaxMessageBytes(maxMessageBytes);
|
|
73670
|
+
this.#pending = new MessageBuffer(Math.min(Number.MAX_SAFE_INTEGER, this.#maxMessageBytes + 1));
|
|
73671
|
+
}
|
|
73672
|
+
*push(chunk) {
|
|
73535
73673
|
let start = 0;
|
|
73536
73674
|
let newlineIndex = chunk.indexOf(newline, start);
|
|
73537
73675
|
while (newlineIndex !== -1) {
|
|
73538
|
-
|
|
73676
|
+
yield this.#takeLine(chunk.subarray(start, newlineIndex));
|
|
73539
73677
|
start = newlineIndex + 1;
|
|
73540
73678
|
newlineIndex = chunk.indexOf(newline, start);
|
|
73541
73679
|
}
|
|
73542
73680
|
if (start < chunk.byteLength) {
|
|
73543
|
-
|
|
73681
|
+
const tail = chunk.subarray(start);
|
|
73682
|
+
this.#checkLine(tail);
|
|
73683
|
+
this.#pending.append(tail);
|
|
73544
73684
|
}
|
|
73545
|
-
return lines;
|
|
73546
73685
|
}
|
|
73547
73686
|
flush() {
|
|
73548
|
-
if (this.#pending.
|
|
73687
|
+
if (this.#pending.byteLength === 0) {
|
|
73549
73688
|
return;
|
|
73550
73689
|
}
|
|
73551
|
-
return this.#
|
|
73690
|
+
return stripCarriageReturn(this.#pending.take());
|
|
73691
|
+
}
|
|
73692
|
+
clear() {
|
|
73693
|
+
this.#pending.clear();
|
|
73552
73694
|
}
|
|
73553
73695
|
#takeLine(tail) {
|
|
73554
|
-
|
|
73555
|
-
|
|
73696
|
+
this.#checkLine(tail);
|
|
73697
|
+
if (this.#pending.byteLength === 0) {
|
|
73698
|
+
return stripCarriageReturn(tail);
|
|
73556
73699
|
}
|
|
73557
|
-
|
|
73558
|
-
|
|
73559
|
-
|
|
73560
|
-
|
|
73561
|
-
const
|
|
73562
|
-
|
|
73563
|
-
|
|
73564
|
-
|
|
73565
|
-
|
|
73700
|
+
this.#pending.append(tail);
|
|
73701
|
+
return stripCarriageReturn(this.#pending.take());
|
|
73702
|
+
}
|
|
73703
|
+
#checkLine(tail) {
|
|
73704
|
+
const lastByte = tail.byteLength > 0 ? tail[tail.byteLength - 1] : this.#pending.lastByte;
|
|
73705
|
+
const byteLength = this.#pending.byteLength + tail.byteLength - (lastByte === 13 ? 1 : 0);
|
|
73706
|
+
if (byteLength > this.#maxMessageBytes) {
|
|
73707
|
+
this.clear();
|
|
73708
|
+
throw new MessageTooLargeError(this.#maxMessageBytes);
|
|
73566
73709
|
}
|
|
73567
|
-
line.set(tail, offset);
|
|
73568
|
-
this.#pending = [];
|
|
73569
|
-
return line;
|
|
73570
73710
|
}
|
|
73571
73711
|
}
|
|
73712
|
+
function stripCarriageReturn(line) {
|
|
73713
|
+
return line[line.byteLength - 1] === 13 ? line.subarray(0, -1) : line;
|
|
73714
|
+
}
|
|
73572
73715
|
|
|
73573
73716
|
// node_modules/@agentclientprotocol/sdk/dist/stream.js
|
|
73574
|
-
function ndJsonStream(output2, input2) {
|
|
73717
|
+
function ndJsonStream(output2, input2, options = {}) {
|
|
73718
|
+
const maxMessageBytes = resolveMaxMessageBytes(options.maxMessageBytes);
|
|
73575
73719
|
const textEncoder = new TextEncoder;
|
|
73576
73720
|
const textDecoder = new TextDecoder;
|
|
73577
73721
|
let cancelled = false;
|
|
@@ -73593,7 +73737,7 @@ function ndJsonStream(output2, input2) {
|
|
|
73593
73737
|
};
|
|
73594
73738
|
const readable = new ReadableStream({
|
|
73595
73739
|
async start(controller) {
|
|
73596
|
-
const lines = new LineBuffer;
|
|
73740
|
+
const lines = new LineBuffer(maxMessageBytes);
|
|
73597
73741
|
const enqueueLine = async (lineBytes) => {
|
|
73598
73742
|
const trimmedLine = textDecoder.decode(lineBytes).trim();
|
|
73599
73743
|
if (!trimmedLine) {
|
|
@@ -73645,8 +73789,10 @@ function ndJsonStream(output2, input2) {
|
|
|
73645
73789
|
return;
|
|
73646
73790
|
}
|
|
73647
73791
|
controller.error(err);
|
|
73792
|
+
reader.cancel(err).catch(() => {});
|
|
73648
73793
|
return;
|
|
73649
73794
|
} finally {
|
|
73795
|
+
lines.clear();
|
|
73650
73796
|
if (inputReader === reader) {
|
|
73651
73797
|
inputReader = undefined;
|
|
73652
73798
|
}
|
|
@@ -73688,8 +73834,8 @@ var zGuardCreateElicitationResponseCancel = object({
|
|
|
73688
73834
|
action: literal("cancel")
|
|
73689
73835
|
});
|
|
73690
73836
|
// node_modules/@agentclientprotocol/sdk/dist/acp.js
|
|
73691
|
-
function ndJsonStream2(output2, input2) {
|
|
73692
|
-
return ndJsonStream(output2, input2);
|
|
73837
|
+
function ndJsonStream2(output2, input2, options) {
|
|
73838
|
+
return ndJsonStream(output2, input2, options);
|
|
73693
73839
|
}
|
|
73694
73840
|
function emptyObjectResponse(response) {
|
|
73695
73841
|
return response ?? {};
|
|
@@ -75128,6 +75274,7 @@ try {
|
|
|
75128
75274
|
const pkgPath = path4.resolve(fileURLToPath(import.meta.url), "../../package.json");
|
|
75129
75275
|
checkForUpdates(JSON.parse(readFileSync3(pkgPath, "utf-8")));
|
|
75130
75276
|
} catch {}
|
|
75277
|
+
var aliasTodoId = (alias) => typeof alias === "string" && alias.includes(":") ? alias.slice(0, alias.indexOf(":")) : undefined;
|
|
75131
75278
|
function formatPathWithTilde(path5) {
|
|
75132
75279
|
const home = homedir3();
|
|
75133
75280
|
return path5.startsWith(home) ? path5.replace(home, "~") : path5;
|
|
@@ -75472,14 +75619,16 @@ async function main() {
|
|
|
75472
75619
|
const kind = it.url ? `url ${it.url}` : it.mime || "";
|
|
75473
75620
|
const card = it.cardRef ? ` card=${it.cardRef}` : "";
|
|
75474
75621
|
const link = it.display === "link" ? " link" : "";
|
|
75475
|
-
|
|
75622
|
+
const shared = it.shareUrl ? ` ${it.shareUrl}` : "";
|
|
75623
|
+
console.log(`${it.ref} ${it.title || it.filename || ""} ${kind}${card}${link}${shared}`);
|
|
75476
75624
|
}
|
|
75477
75625
|
return;
|
|
75478
75626
|
}
|
|
75479
|
-
|
|
75627
|
+
const showSub = positionals[1];
|
|
75628
|
+
if (positionals[0] === "show" && (showSub === "rm" || showSub === "share" || showSub === "unshare")) {
|
|
75480
75629
|
const arg = positionals[2];
|
|
75481
75630
|
if (!arg) {
|
|
75482
|
-
process.stderr.write(`${RED3}Usage: tfa-cli show
|
|
75631
|
+
process.stderr.write(`${RED3}Usage: tfa-cli show ${showSub} <ref|alias>${RESET2}
|
|
75483
75632
|
`);
|
|
75484
75633
|
process.exit(2);
|
|
75485
75634
|
}
|
|
@@ -75487,18 +75636,30 @@ async function main() {
|
|
|
75487
75636
|
const todoId = sep >= 0 ? arg.slice(0, sep) : getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
75488
75637
|
const key = sep >= 0 ? arg.slice(sep + 1) : arg;
|
|
75489
75638
|
if (!todoId || !key) {
|
|
75490
|
-
process.stderr.write(`${RED3}show
|
|
75639
|
+
process.stderr.write(`${RED3}show ${showSub}: need <todoId>:<alias> (no current todo)${RESET2}
|
|
75491
75640
|
`);
|
|
75492
75641
|
process.exit(2);
|
|
75493
75642
|
}
|
|
75494
|
-
|
|
75495
|
-
|
|
75643
|
+
if (showSub === "rm") {
|
|
75644
|
+
await api2.removeShow(todoId, key);
|
|
75645
|
+
process.stderr.write(`${GREEN2}\u2705 removed ${todoId}:${key}${RESET2}
|
|
75496
75646
|
`);
|
|
75647
|
+
} else if (showSub === "share") {
|
|
75648
|
+
const res = await api2.shareShow(todoId, key);
|
|
75649
|
+
if (args.json)
|
|
75650
|
+
console.log(JSON.stringify(res, null, 2));
|
|
75651
|
+
else
|
|
75652
|
+
console.log(res.url);
|
|
75653
|
+
} else {
|
|
75654
|
+
await api2.unshareShow(todoId, key);
|
|
75655
|
+
process.stderr.write(`${GREEN2}\u2705 ${todoId}:${key} is private again${RESET2}
|
|
75656
|
+
`);
|
|
75657
|
+
}
|
|
75497
75658
|
return;
|
|
75498
75659
|
}
|
|
75499
75660
|
if (positionals[0] === "show") {
|
|
75500
75661
|
const [, filePath, todoArg] = positionals;
|
|
75501
|
-
const todoId = todoArg || getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
75662
|
+
const todoId = todoArg || aliasTodoId(args.alias) || getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
75502
75663
|
if (!filePath || !todoId) {
|
|
75503
75664
|
process.stderr.write(`${RED3}Usage: tfa-cli show <file|-> [todo-id] [--title T] [--alias A] [--mime M] [--card <name>] [--link]${RESET2}
|
|
75504
75665
|
`);
|
|
@@ -75536,12 +75697,12 @@ async function main() {
|
|
|
75536
75697
|
if (args.json)
|
|
75537
75698
|
console.log(JSON.stringify(res, null, 2));
|
|
75538
75699
|
else
|
|
75539
|
-
console.log(res.
|
|
75700
|
+
console.log(res.shareUrl ? `${res.ref} ${res.shareUrl}` : res.ref);
|
|
75540
75701
|
return;
|
|
75541
75702
|
}
|
|
75542
75703
|
if (positionals[0] === "open") {
|
|
75543
75704
|
const [, url2, todoArg] = positionals;
|
|
75544
|
-
const todoId = todoArg || getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
75705
|
+
const todoId = todoArg || aliasTodoId(args.alias) || getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
75545
75706
|
if (!url2 || !todoId) {
|
|
75546
75707
|
process.stderr.write(`${RED3}Usage: tfa-cli open <url> [todo-id]${RESET2}
|
|
75547
75708
|
`);
|