@todoforai/cli 0.1.69 → 0.1.70
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/LICENSE +21 -0
- package/README.md +4 -0
- package/dist/todoforai-cli.js +93 -13
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-2026 TODOforAI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
package/dist/todoforai-cli.js
CHANGED
|
@@ -43132,6 +43132,18 @@ class ApiClient {
|
|
|
43132
43132
|
throw new Error(`API POST /resources/open failed: ${res.status} ${await res.text()}`);
|
|
43133
43133
|
return res.json();
|
|
43134
43134
|
}
|
|
43135
|
+
async showConnect(todoId, keys, opts = {}) {
|
|
43136
|
+
const endpoint = `${this.apiUrl}${restBasePath(this.apiKey)}/resources/connect`;
|
|
43137
|
+
const res = await fetch(endpoint, {
|
|
43138
|
+
method: "POST",
|
|
43139
|
+
headers: { "x-api-key": this.apiKey, "Content-Type": "application/json" },
|
|
43140
|
+
body: JSON.stringify({ todoId, keys, ...opts }),
|
|
43141
|
+
signal: AbortSignal.timeout(30000)
|
|
43142
|
+
});
|
|
43143
|
+
if (!res.ok)
|
|
43144
|
+
throw new Error(`API POST /resources/connect failed: ${res.status} ${await res.text()}`);
|
|
43145
|
+
return res.json();
|
|
43146
|
+
}
|
|
43135
43147
|
async listShows(opts = {}) {
|
|
43136
43148
|
const qs = new URLSearchParams;
|
|
43137
43149
|
if (opts.todoId)
|
|
@@ -43976,8 +43988,7 @@ var ToolType;
|
|
|
43976
43988
|
ToolType2["Question"] = "question";
|
|
43977
43989
|
ToolType2["Login"] = "login_prompt";
|
|
43978
43990
|
ToolType2["BusinessOnboarding"] = "business_onboarding";
|
|
43979
|
-
ToolType2["
|
|
43980
|
-
ToolType2["EdgeNotRunning"] = "edge_not_running";
|
|
43991
|
+
ToolType2["ConnectDevice"] = "connect_device";
|
|
43981
43992
|
ToolType2["WebFetch"] = "webfetch";
|
|
43982
43993
|
ToolType2["GoogleSearch"] = "google_search";
|
|
43983
43994
|
ToolType2["WebSearch"] = "web_search";
|
|
@@ -43998,7 +44009,8 @@ var USER_INPUT_BLOCK_TYPES = new Set([
|
|
|
43998
44009
|
"question" /* Question */,
|
|
43999
44010
|
"login_prompt" /* Login */,
|
|
44000
44011
|
"business_onboarding" /* BusinessOnboarding */,
|
|
44001
|
-
"open_browser" /* OpenBrowser
|
|
44012
|
+
"open_browser" /* OpenBrowser */,
|
|
44013
|
+
"connect_device" /* ConnectDevice */
|
|
44002
44014
|
]);
|
|
44003
44015
|
var EDGE_TOOL_TYPES = new Set([
|
|
44004
44016
|
"read" /* Read */,
|
|
@@ -44711,6 +44723,7 @@ var tool_catalog_default = {
|
|
|
44711
44723
|
voiceChannel: "Gmail",
|
|
44712
44724
|
summary: "Read and send Gmail from your own account.",
|
|
44713
44725
|
statusCmd: "zele whoami 2>/dev/null | grep -o 'email: *[^ ]*' | tr -d ' ' | paste -sd ' ' - | grep -m1 .",
|
|
44726
|
+
logoutCmd: "zele logout {{ACCOUNT}}",
|
|
44714
44727
|
loginNeedsPty: true,
|
|
44715
44728
|
loginCmd: "zele login --method google",
|
|
44716
44729
|
oauthUrlPattern: "(https://accounts\\.google\\.com\\S+)",
|
|
@@ -44722,6 +44735,7 @@ var tool_catalog_default = {
|
|
|
44722
44735
|
description: "Gmail (multi-account, OAuth login): inbox, search, send, reply, contacts. Google Calendar via `zele cal`: list/create/update/delete events (Meet links, recurrence), respond to invites, free/busy."
|
|
44723
44736
|
},
|
|
44724
44737
|
"zele-calendar": {
|
|
44738
|
+
subcommands: ["cal"],
|
|
44725
44739
|
preinstallCloud: true,
|
|
44726
44740
|
category: "productivity",
|
|
44727
44741
|
pkg: "zele",
|
|
@@ -44730,6 +44744,7 @@ var tool_catalog_default = {
|
|
|
44730
44744
|
label: "Google Calendar",
|
|
44731
44745
|
summary: "See your Google Calendar and book, move or cancel events.",
|
|
44732
44746
|
statusCmd: "zele whoami 2>/dev/null | grep -o 'email: *[^ ]*' | tr -d ' ' | paste -sd ' ' - | grep -m1 .",
|
|
44747
|
+
logoutCmd: "zele logout {{ACCOUNT}}",
|
|
44733
44748
|
loginNeedsPty: true,
|
|
44734
44749
|
loginCmd: "zele login --method google",
|
|
44735
44750
|
oauthUrlPattern: "(https://accounts\\.google\\.com\\S+)",
|
|
@@ -44940,6 +44955,24 @@ var tool_catalog_default = {
|
|
|
44940
44955
|
versionCmd: "ntn --version 2>/dev/null | sed -n 1p",
|
|
44941
44956
|
description: "Official Notion CLI: raw API calls (`ntn api <path>`), page/data-source management, file uploads, Workers deploy."
|
|
44942
44957
|
},
|
|
44958
|
+
treg: {
|
|
44959
|
+
preinstallCloud: true,
|
|
44960
|
+
packages: ["tools-registry==0.27.0"],
|
|
44961
|
+
category: "research",
|
|
44962
|
+
pkg: "tools-registry",
|
|
44963
|
+
pipModules: ["treg"],
|
|
44964
|
+
installer: "pip",
|
|
44965
|
+
label: "treg",
|
|
44966
|
+
summary: "Call 4000+ paid data/SEO/enrichment APIs through one prepaid key, no vendor accounts.",
|
|
44967
|
+
statusCmd: `python3 -c "import json,os;d=json.load(open(os.path.expanduser('~/.treg/config.json')));print(d.get('email') or '' if d.get('token') else '')" 2>/dev/null | grep -m1 .`,
|
|
44968
|
+
loginCmd: "treg login",
|
|
44969
|
+
oauthUrlPattern: "(https://treg\\.to/login\\?\\S+)",
|
|
44970
|
+
sessionIdPattern: "#code=([A-Z0-9]{4,8})",
|
|
44971
|
+
logoutCmd: "treg logout",
|
|
44972
|
+
credentialPaths: ["~/.treg/config.json"],
|
|
44973
|
+
versionCmd: "treg --version 2>/dev/null | sed -n 1p",
|
|
44974
|
+
description: 'treg.to ("OpenRouter for agent tools"): one prepaid balance, 100+ providers (SE Ranking, DataForSEO, Perplexity, CompanyEnrich, ScrapeCreators, TikHub, cloro AI-search scrapes…) metered per call, credentials injected server-side. Find by intent: `treg catalog search "backlinks for a domain" --json` (each result shows price + a `call_template`); run: `treg call <endpoint.id> --query k=v --json` or `treg call <endpoint.id> --method POST --data \'<json>\' --json` (prints one `{result,_treg}` line); money: `treg balance`, `treg topup`; `treg review` rates a call. Own keys/CLIs: `treg secret|tool|skill`, `treg cli run <vendor> …` and `treg <cmd>` inject the team\'s stored credentials. Team: `treg org ls|use|invite|members`, `treg audit`. `--org <slug>` targets another team. Every catalog call spends real money — check the `cost` field and prefer a connected first-party connector when one exists. Docs: https://treg.to/llms.txt'
|
|
44975
|
+
},
|
|
44943
44976
|
"perplexity-api": {
|
|
44944
44977
|
preinstallCloud: true,
|
|
44945
44978
|
category: "research",
|
|
@@ -45201,7 +45234,7 @@ var tool_catalog_default = {
|
|
|
45201
45234
|
installer: "npm",
|
|
45202
45235
|
label: "TODOforAI",
|
|
45203
45236
|
summary: "Create and follow up on your TODOs, and show results in the chat.",
|
|
45204
|
-
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. Show viewer chrome: `--title` appears in the header; a kebab menu holds file actions, versions and sharing when available. Desktop floating previews add minimize (park in a tab), maximize/restore and close (X); inline blocks have no window controls. For authored HTML, do not duplicate the header/controls or add a rounded, bordered root card: the floating viewer owns the rounded frame. Keep content edge-to-edge; internal layout padding is fine. 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. Project files: `memory sync|path [--project <id>]` requires a project and checks out only projects/<id>/{memory,context} and projects/<id>/me/{memory,context}; legacy global files are read-only recovery. Voice commands use `--scope mine|project` (default mine, private within this project; project is shared).',
|
|
45237
|
+
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. Show viewer chrome: `--title` appears in the header; a kebab menu holds file actions, versions and sharing when available. Desktop floating previews add minimize (park in a tab), maximize/restore and close (X); inline blocks have no window controls. For authored HTML, do not duplicate the header/controls or add a rounded, bordered root card: the floating viewer owns the rounded frame. Keep content edge-to-edge; internal layout padding is fine. 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>] [--url <link>: tap opens it on the phone, e.g. a Google Maps navigation link]` 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. Project files: `memory sync|path [--project <id>]` requires a project and checks out only projects/<id>/{memory,context} and projects/<id>/me/{memory,context}; legacy global files are read-only recovery. Voice commands use `--scope mine|project` (default mine, private within this project; project is shared).',
|
|
45205
45238
|
installCmd: "npm install -g @todoforai/cli",
|
|
45206
45239
|
versionCmd: "tfa-cli --version 2>/dev/null | sed -n 1p",
|
|
45207
45240
|
preinstallCloud: true,
|
|
@@ -45384,6 +45417,7 @@ var tool_catalog_default = {
|
|
|
45384
45417
|
needsPython: true,
|
|
45385
45418
|
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"`,
|
|
45386
45419
|
statusCmd: `gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null | tr -d '\\r' | grep -m1 .`,
|
|
45420
|
+
logoutCmd: "gcloud auth revoke --all --quiet",
|
|
45387
45421
|
loginCmd: "gcloud auth login --no-launch-browser",
|
|
45388
45422
|
loginNeedsPty: true,
|
|
45389
45423
|
stdinPaste: true,
|
|
@@ -45489,7 +45523,7 @@ var tool_catalog_default = {
|
|
|
45489
45523
|
preinstallCloud: true,
|
|
45490
45524
|
label: "Browser",
|
|
45491
45525
|
summary: "Browse websites automatically: click, type, read and screenshot.",
|
|
45492
|
-
description: "Browser automation over CDP (`open`/`snapshot`/`click`/`type`/`fill`/`read`/`screenshot`/`eval`). `connect '<url>'` to a listed live browser (prefer the user's real Chrome),
|
|
45526
|
+
description: "Browser automation over CDP (`open`/`snapshot`/`click`/`type`/`fill`/`read`/`screenshot`/`eval`). `connect '<url>'` to a listed live browser (prefer the user's real Chrome); connect prints `whoami` (browser=extension|embedded|local, headless, ua) — run `agent-browser whoami` again after any error or odd output, and stop on `ERROR`/`DISCONNECTED`/`headless=yes` where the user's browser was expected: re-run the connect command, never continue in another browser. If a page is empty, `close` (own session only) and reconnect once. NEVER `close --all`. Shared browser: `tab new` for your own tab, `tab <id>` before each command. No URL listed: cloud → browser-manager-cli; PC with display → Chrome `--remote-debugging-port=9222`, attach `--cdp 9222`. Never `sleep`: `open` returns after load, but `click`/`fill` fail at once if the element isn't there yet — `wait '<sel>'`, `wait --text 'Done'`, `wait --url '**/dash'`, `wait --load networkidle` or `wait '#spinner' --state hidden` first. Extension browsers (WEB_EXTENSION) only: try sign-in with credentials from `tfa-vault`; request human help only for a step you cannot complete yourself (MFA/CAPTCHA/consent). Use Node/Bun WebSocket on the listed CDP URL; `Target.getTargets` or `device_list` gives `tab-N`, whose N is the numeric tabId. On the SAME socket send `{id: 1, method: 'TodoforAI.requestHumanHelp', params: {tabId: N, message: 'what to do'}}` (message 1–500 chars). This only marks the tab (yellow count badge on the extension icon, needs-you row with Show in the popup); it never pauses you or takes the tab away. Tell the user what to do and to reply here, then end your turn. When resumed, snapshot to verify, then clear the marker with `TodoforAI.clearHumanHelp` `{tabId: N}`. If bootstrap fails on a restricted target, direct CDP `Target.createTarget` with an ordinary URL opens your tab on the SAME socket; pass numeric N from returned `tab-N` as `tabId`.",
|
|
45493
45527
|
versionCmd: "agent-browser --version 2>/dev/null | sed -n 1p",
|
|
45494
45528
|
preinstallJarvis: true
|
|
45495
45529
|
},
|
|
@@ -46090,7 +46124,7 @@ var tool_catalog_default = {
|
|
|
46090
46124
|
summary: "Read and write your Outlook mail.",
|
|
46091
46125
|
statusCmd: `outlook-api whoami 2>/dev/null | sed -n 's/.*"userPrincipalName"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m10 .`,
|
|
46092
46126
|
logoutCmd: "outlook-api logout",
|
|
46093
|
-
loginCmd: "outlook-api auth",
|
|
46127
|
+
loginCmd: "outlook-api auth --tenant common",
|
|
46094
46128
|
credentialPaths: ["~/.config/outlook-api/config.json"],
|
|
46095
46129
|
description: "Outlook/Hotmail/M365 mail over Microsoft Graph (on-prem Exchange → ews-api). `auth` = device-code flow; `--tenant consumers` (default, personal) | `organizations`. list/search/read/attachments are read-only; `draft`/`reply` stay in Drafts unless --send; `send <draftId>`. `get <path>` = raw Graph GET. JSON out.",
|
|
46096
46130
|
versionCmd: "outlook-api --version 2>/dev/null | sed -n 1p",
|
|
@@ -46137,6 +46171,7 @@ var tool_catalog_default = {
|
|
|
46137
46171
|
label: "Google Workspace",
|
|
46138
46172
|
summary: "Work with Google Sheets, Docs, Slides, Drive, Forms, Tasks, Contacts and Chat.",
|
|
46139
46173
|
statusCmd: `gws auth status 2>/dev/null | sed -n 's/.*"user"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m1 .`,
|
|
46174
|
+
logoutCmd: "gws auth logout",
|
|
46140
46175
|
loginCmd: "gws auth login --scopes https://www.googleapis.com/auth/spreadsheets,https://www.googleapis.com/auth/documents,https://www.googleapis.com/auth/presentations,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/forms.body,https://www.googleapis.com/auth/forms.responses.readonly,https://www.googleapis.com/auth/tasks,https://www.googleapis.com/auth/contacts,https://www.googleapis.com/auth/chat.spaces,https://www.googleapis.com/auth/chat.messages,https://www.googleapis.com/auth/chat.memberships,https://www.googleapis.com/auth/chat.delete",
|
|
46141
46176
|
loginTerminalHint: "gws needs your own Google OAuth client first: in console.cloud.google.com create a Desktop-app OAuth client (consent screen External/testing, add yourself as test user), enable the APIs you need (Sheets/Docs/Slides/Drive/Forms/Tasks/People/Chat), save the JSON as ~/.config/gws/client_secret.json (or run `gws auth setup` if gcloud is logged in), then `gws auth login -s sheets,drive`.",
|
|
46142
46177
|
oauthUrlPattern: "(https://accounts\\.google\\.com/o/oauth2/auth\\S+)",
|
|
@@ -46231,6 +46266,7 @@ var tool_catalog_default = {
|
|
|
46231
46266
|
summary: "Read your Granola meeting notes and transcripts.",
|
|
46232
46267
|
statusCmd: `granola auth status -o json 2>/dev/null | sed -n 's/.*"authenticated": *true.*/authenticated/p' | grep -m1 .`,
|
|
46233
46268
|
loginCmd: "granola auth login",
|
|
46269
|
+
logoutCmd: "granola auth logout",
|
|
46234
46270
|
loginTerminalHint: "Imports the Granola desktop app's session: install Granola on this host, sign in there, then run `granola auth login`.",
|
|
46235
46271
|
credentialPaths: ["~/.config/keyring", "~/.config/granola"],
|
|
46236
46272
|
versionCmd: "granola --version 2>/dev/null | sed -n 1p",
|
|
@@ -48798,6 +48834,7 @@ var tool_catalog_default = {
|
|
|
48798
48834
|
label: "Heroku",
|
|
48799
48835
|
summary: "Deploy and manage apps, add-ons and databases on Heroku.",
|
|
48800
48836
|
statusCmd: "heroku auth:whoami 2>/dev/null | tr -d '\\r' | grep -m1 .",
|
|
48837
|
+
logoutCmd: "heroku logout",
|
|
48801
48838
|
loginCmd: `k=<api_key>; f="$HOME/.netrc"; (umask 077; touch "$f"; chmod 600 "$f") && K="$k" python3 -c 'import os,re,sys; f=sys.argv[1]; k=os.environ["K"]; s=re.sub(r"machine\\s+(api|git)\\.heroku\\.com\\s+login\\s+\\S+\\s+password\\s+\\S+\\s*", "", open(f).read()); open(f, "w").write(s + "".join("machine %s.heroku.com\\n login token\\n password %s\\n" % (h, k) for h in ("api", "git")))' "$f" && heroku auth:whoami`,
|
|
48802
48839
|
credentialPaths: ["~/.netrc"],
|
|
48803
48840
|
versionCmd: "heroku --version 2>/dev/null | sed -n 1p",
|
|
@@ -49270,6 +49307,7 @@ var tool_catalog_default = {
|
|
|
49270
49307
|
description: "Official Pinecone CLI (`pc`). Connect with a project API key (app.pinecone.io → API keys). `pc index list`, `pc index create --name <n> --dimension 1536 --metric cosine --cloud aws --region us-east-1`, `pc index describe --name <n>`.",
|
|
49271
49308
|
loginCmd: "pc auth configure --api-key <api_key>",
|
|
49272
49309
|
statusCmd: "pc index list --json >/dev/null 2>&1 && echo authenticated",
|
|
49310
|
+
logoutCmd: "pc auth logout",
|
|
49273
49311
|
versionCmd: "pc version 2>/dev/null | sed -n 1p",
|
|
49274
49312
|
credentialPaths: [
|
|
49275
49313
|
"~/.config/pinecone/secrets.yaml",
|
|
@@ -49647,6 +49685,7 @@ var tool_catalog_default = {
|
|
|
49647
49685
|
cloudinary: {
|
|
49648
49686
|
category: "creative",
|
|
49649
49687
|
pkg: "cloudinary-cli",
|
|
49688
|
+
pipSdist: ["cloudinary-cli"],
|
|
49650
49689
|
installer: "pip",
|
|
49651
49690
|
label: "Cloudinary",
|
|
49652
49691
|
binName: "cld",
|
|
@@ -50099,6 +50138,24 @@ var tool_catalog_default = {
|
|
|
50099
50138
|
|
|
50100
50139
|
// ../packages/shared-fbe/src/toolCatalog.ts
|
|
50101
50140
|
var TOOL_CATALOG = tool_catalog_default;
|
|
50141
|
+
// ../packages/shared-fbe/src/emailDomains.ts
|
|
50142
|
+
var PUBLIC_EMAIL_DOMAINS = new Set([
|
|
50143
|
+
"gmail.com",
|
|
50144
|
+
"googlemail.com",
|
|
50145
|
+
"outlook.com",
|
|
50146
|
+
"hotmail.com",
|
|
50147
|
+
"live.com",
|
|
50148
|
+
"icloud.com",
|
|
50149
|
+
"me.com",
|
|
50150
|
+
"yahoo.com",
|
|
50151
|
+
"proton.me",
|
|
50152
|
+
"protonmail.com",
|
|
50153
|
+
"fastmail.com",
|
|
50154
|
+
"gmx.com",
|
|
50155
|
+
"gmx.net",
|
|
50156
|
+
"mail.com",
|
|
50157
|
+
"zoho.com"
|
|
50158
|
+
]);
|
|
50102
50159
|
// ../packages/shared-fbe/src/toolInstallCommand.ts
|
|
50103
50160
|
var NPM_HOME = '"${TFA_NPM_HOME:-$HOME}"';
|
|
50104
50161
|
var NPM_TOOLS = NPM_HOME.replace('}"', '}/.todoforai/tools"');
|
|
@@ -50338,13 +50395,14 @@ import { parseArgs } from "util";
|
|
|
50338
50395
|
// package.json
|
|
50339
50396
|
var package_default = {
|
|
50340
50397
|
name: "@todoforai/cli",
|
|
50398
|
+
license: "MIT",
|
|
50341
50399
|
description: "TODOforAI CLI — create and manage tasks with tfa-cli.",
|
|
50342
50400
|
homepage: "https://todofor.ai",
|
|
50343
50401
|
repository: {
|
|
50344
50402
|
type: "git",
|
|
50345
50403
|
url: "git+https://github.com/todoforai/cli.git"
|
|
50346
50404
|
},
|
|
50347
|
-
version: "0.1.
|
|
50405
|
+
version: "0.1.70",
|
|
50348
50406
|
type: "module",
|
|
50349
50407
|
bin: {
|
|
50350
50408
|
"todoforai-cli": "bin/todoforai-cli.js",
|
|
@@ -50412,10 +50470,11 @@ Examples:
|
|
|
50412
50470
|
tfa-cli show <file|-> [todo-id] # Render a local file (image/pdf/html…) in the chat; - = stdin
|
|
50413
50471
|
tfa-cli show list|rm … # List / take down shown files
|
|
50414
50472
|
tfa-cli open <url> [todo-id] # Live url preview in the chat
|
|
50473
|
+
tfa-cli connect <key>… [--reason "why"] # Sign-in card for connectors on this machine (several keys = one choice)
|
|
50415
50474
|
tfa-cli recommend --template <id> # Add a template as a recommendation card
|
|
50416
50475
|
tfa-cli inbox [needs-you|messages|activity] [--unread] # Read the notification feed (the bell)
|
|
50417
50476
|
tfa-cli inbox seen [tab] # Mark notifications read
|
|
50418
|
-
tfa-cli notify [--to <email>] "Title" "message" [--href /t/<id>] # Note to your own user, or --to a project member (Messages tab + phone push)
|
|
50477
|
+
tfa-cli notify [--to <email>] "Title" "message" [--href /t/<id>] [--url <link>] # Note to your own user, or --to a project member (Messages tab + phone push)
|
|
50419
50478
|
tfa-cli claim mint --seed <projectId> [--emails a@x,b@y] [--ttl <sec>] # Mint /claim/<token> links for a project you own
|
|
50420
50479
|
tfa-cli next [--direction "<text>"] # Analyzer growth recommendation cards
|
|
50421
50480
|
tfa-cli import [claude|codex|<file>...] [--dry-run] # Import Claude Code / Codex sessions as todos
|
|
@@ -50546,6 +50605,7 @@ function parseCliArgs() {
|
|
|
50546
50605
|
link: { type: "boolean", default: false },
|
|
50547
50606
|
force: { type: "boolean", default: false },
|
|
50548
50607
|
direction: { type: "string" },
|
|
50608
|
+
reason: { type: "string" },
|
|
50549
50609
|
url: { type: "string" },
|
|
50550
50610
|
account: { type: "string" },
|
|
50551
50611
|
"from-company": { type: "boolean", default: false },
|
|
@@ -53361,7 +53421,9 @@ Examples:
|
|
|
53361
53421
|
tfa-cli agent update <agent> sysmsg="You are a terse video editor."
|
|
53362
53422
|
tfa-cli agent create name=Reviewer model=claude sysmsg="Review diffs only."
|
|
53363
53423
|
|
|
53364
|
-
|
|
53424
|
+
tfa-cli agent update <agent> judgeSysmsg="Ask before destructive actions. Everything else can run." (auto-approve policy)
|
|
53425
|
+
|
|
53426
|
+
From an agent shell (dst_ token) permissions, judgeSysmsg, edgesMcpConfigs, devicesConfig and delete are refused by the backend.
|
|
53365
53427
|
`);
|
|
53366
53428
|
}
|
|
53367
53429
|
var FIELD_ALIASES = {
|
|
@@ -54953,15 +55015,17 @@ function printNotifyHelp() {
|
|
|
54953
55015
|
tfa-cli notify — leave a note in someone's Messages inbox (+ phone push)
|
|
54954
55016
|
|
|
54955
55017
|
Usage:
|
|
54956
|
-
tfa-cli notify "Title" "message" [--href /t/<todo-id>] [--subject <key>] [--json]
|
|
55018
|
+
tfa-cli notify "Title" "message" [--href /t/<todo-id>] [--url <link>] [--subject <key>] [--json]
|
|
54957
55019
|
tfa-cli notify --to <email> "Title" "message" [--project <id>]
|
|
54958
55020
|
echo "message" | tfa-cli notify "Title"
|
|
54959
55021
|
|
|
54960
55022
|
Recipient: your own user by default. --to <email> reaches a TEAMMATE: someone who is a member
|
|
54961
55023
|
of the current project (--project, $TODOFORAI_PROJECT_ID or your default), shown as from you.
|
|
54962
55024
|
Anyone else is refused. List them with: tfa-cli project members
|
|
54963
|
-
--subject dedupes: the same subject is delivered once (default: hash of title+message,
|
|
55025
|
+
--subject dedupes: the same subject is delivered once (default: hash of title+message+url,
|
|
54964
55026
|
so a retry never double-notifies). --href must be an in-app path.
|
|
55027
|
+
--url is what tapping the phone notification opens (https/tel/sms/mailto), e.g. navigation:
|
|
55028
|
+
--url "https://www.google.com/maps/dir/?api=1&destination=Deák+tér&dir_action=navigate"
|
|
54965
55029
|
Limits: 10 notes/day to yourself, 20/day to teammates.
|
|
54966
55030
|
`);
|
|
54967
55031
|
}
|
|
@@ -55040,8 +55104,9 @@ async function notifyCommand(api, positionals, args, projectId) {
|
|
|
55040
55104
|
process.exit(2);
|
|
55041
55105
|
}
|
|
55042
55106
|
const subject = args.subject || createHash("sha256").update(`${title}
|
|
55043
|
-
${message}
|
|
55044
|
-
|
|
55107
|
+
${message}${args.url ? `
|
|
55108
|
+
${args.url}` : ""}`).digest("hex").slice(0, 16);
|
|
55109
|
+
const msg = { subject, title, message, ...args.href ? { href: String(args.href) } : {}, ...args.url ? { url: String(args.url) } : {} };
|
|
55045
55110
|
const row = await (to ? api.sendMemberMessage({ ...msg, projectId, to }) : api.sendFeedMessage(msg));
|
|
55046
55111
|
if (args.json) {
|
|
55047
55112
|
console.log(JSON.stringify(row));
|
|
@@ -80252,6 +80317,21 @@ async function main() {
|
|
|
80252
80317
|
console.log(res.ref);
|
|
80253
80318
|
return;
|
|
80254
80319
|
}
|
|
80320
|
+
if (positionals[0] === "connect") {
|
|
80321
|
+
const keys = positionals.slice(1);
|
|
80322
|
+
const todoId = aliasTodoId(args.alias) || getEnv("TODO_ID") || cfgScope.data.last_todo_id;
|
|
80323
|
+
if (!keys.length || !todoId) {
|
|
80324
|
+
process.stderr.write(`${RED3}Usage: tfa-cli connect <key> [<key>\u2026] [--reason "why"]${RESET2}
|
|
80325
|
+
`);
|
|
80326
|
+
process.exit(2);
|
|
80327
|
+
}
|
|
80328
|
+
const res = await api2.showConnect(todoId, keys, { reason: args.reason, alias: args.alias });
|
|
80329
|
+
if (args.json)
|
|
80330
|
+
console.log(JSON.stringify(res, null, 2));
|
|
80331
|
+
else
|
|
80332
|
+
console.log(res.ref);
|
|
80333
|
+
return;
|
|
80334
|
+
}
|
|
80255
80335
|
if (positionals[0] === "recommend") {
|
|
80256
80336
|
const templateId = args.template || positionals[1];
|
|
80257
80337
|
if (!templateId) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@todoforai/cli",
|
|
3
|
+
"license": "MIT",
|
|
3
4
|
"description": "TODOforAI CLI — create and manage tasks with tfa-cli.",
|
|
4
5
|
"homepage": "https://todofor.ai",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "git+https://github.com/todoforai/cli.git"
|
|
8
9
|
},
|
|
9
|
-
"version": "0.1.
|
|
10
|
+
"version": "0.1.70",
|
|
10
11
|
"type": "module",
|
|
11
12
|
"bin": {
|
|
12
13
|
"todoforai-cli": "bin/todoforai-cli.js",
|