@todoforai/cli 0.1.73 → 0.1.74
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 +295 -92
- package/package.json +1 -1
package/dist/todoforai-cli.js
CHANGED
|
@@ -43767,14 +43767,15 @@ var mimetypes_default = {
|
|
|
43767
43767
|
to_jpeg_90: { toMime: "image/jpeg", toExt: "jpg", quality: 0.9 }
|
|
43768
43768
|
},
|
|
43769
43769
|
types: {
|
|
43770
|
-
image: { icon: "
|
|
43771
|
-
audio: { icon: "mdi:file-music", color: "
|
|
43772
|
-
video: { icon: "
|
|
43770
|
+
image: { icon: "vscode-icons:file-type-image", color: "green", prefixRule: "image/", needsObjectUrl: true },
|
|
43771
|
+
audio: { icon: "mdi:file-music", color: "blue", prefixRule: "audio/", needsObjectUrl: true },
|
|
43772
|
+
video: { icon: "vscode-icons:file-type-video", color: "red", prefixRule: "video/", needsObjectUrl: true },
|
|
43773
43773
|
pdf: { icon: "vscode-icons:file-type-pdf2", color: "red", needsObjectUrl: true },
|
|
43774
43774
|
document: { icon: "vscode-icons:file-type-word", color: "lightblue" },
|
|
43775
43775
|
spreadsheet: { icon: "vscode-icons:file-type-excel", color: "green" },
|
|
43776
|
-
|
|
43777
|
-
|
|
43776
|
+
presentation: { icon: "vscode-icons:file-type-powerpoint", color: "red" },
|
|
43777
|
+
text: { icon: "vscode-icons:file-type-text", color: "white", prefixRule: "text/" },
|
|
43778
|
+
archive: { icon: "vscode-icons:file-type-zip", color: "yellow" },
|
|
43778
43779
|
unknown: { icon: "mdi:file", color: "grey" },
|
|
43779
43780
|
mcp_text: { icon: "mdi:robot", color: "purple" },
|
|
43780
43781
|
mcp_image: { icon: "mdi:robot", color: "purple", needsObjectUrl: true },
|
|
@@ -43825,8 +43826,8 @@ var mimetypes_default = {
|
|
|
43825
43826
|
pdf: { mime: "application/pdf", type: "pdf" },
|
|
43826
43827
|
doc: { mime: "application/msword", type: "document" },
|
|
43827
43828
|
docx: { mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", type: "document", tags: ["docx"] },
|
|
43828
|
-
ppt: { mime: "application/vnd.ms-powerpoint", type: "
|
|
43829
|
-
pptx: { mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation", type: "
|
|
43829
|
+
ppt: { mime: "application/vnd.ms-powerpoint", type: "presentation" },
|
|
43830
|
+
pptx: { mime: "application/vnd.openxmlformats-officedocument.presentationml.presentation", type: "presentation", tags: ["pptx"] },
|
|
43830
43831
|
xls: { mime: "application/vnd.ms-excel", type: "spreadsheet", tags: ["xls"] },
|
|
43831
43832
|
xlsx: { mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", type: "spreadsheet", tags: ["xlsx"] },
|
|
43832
43833
|
zip: { mime: "application/zip", type: "archive" },
|
|
@@ -44074,7 +44075,7 @@ var FILE_TOOL_TYPES = new Set([
|
|
|
44074
44075
|
"modify_file" /* ModifyFile */
|
|
44075
44076
|
]);
|
|
44076
44077
|
// ../packages/shared-fbe/src/channels.ts
|
|
44077
|
-
var privateSuffix = (
|
|
44078
|
+
var privateSuffix = (userId) => userId ? `:private:${userId}` : "";
|
|
44078
44079
|
var SERVER_TO_FRONTENDS = {
|
|
44079
44080
|
task: {
|
|
44080
44081
|
actionUpdate: (userId) => `${"task_action:update" /* TASK_ACTION_UPDATE */}:${userId}`
|
|
@@ -44122,9 +44123,9 @@ var SERVER_TO_FRONTENDS = {
|
|
|
44122
44123
|
writeFileResult: (edgeId) => `${"edge:write_file_response" /* EDGE_WRITE_FILE_RESPONSE */}:${edgeId}`
|
|
44123
44124
|
},
|
|
44124
44125
|
project: {
|
|
44125
|
-
new_message: (projectId,
|
|
44126
|
-
new_todo: (projectId,
|
|
44127
|
-
status: (projectId,
|
|
44126
|
+
new_message: (projectId, memberId) => `${"task:new_update" /* TASK_NEW */}:${projectId}${privateSuffix(memberId)}`,
|
|
44127
|
+
new_todo: (projectId, memberId) => `${"todo:new" /* NEW_TODO */}:${projectId}${privateSuffix(memberId)}`,
|
|
44128
|
+
status: (projectId, memberId) => `${"project:status" /* PROJECT_STATUS */}:${projectId}${privateSuffix(memberId)}`
|
|
44128
44129
|
},
|
|
44129
44130
|
todo: {
|
|
44130
44131
|
msgStart: (todoId) => `${"todo:msg_start" /* TODO_MSG_START */}:${todoId}`,
|
|
@@ -44710,6 +44711,137 @@ var OUTPUT_POLICIES = {
|
|
|
44710
44711
|
full: { firstLimit: Infinity, lastLimit: 0, hardCap: RUN_OUTPUT_CAP, lineLimit: MAX_LINE_LEN },
|
|
44711
44712
|
raw: { firstLimit: Infinity, lastLimit: 0, hardCap: Infinity, lineLimit: Infinity }
|
|
44712
44713
|
};
|
|
44714
|
+
// ../packages/shared-fbe/src/agentRoles.ts
|
|
44715
|
+
var SAFE = "Prepare drafts and lists; never send, publish, pay or delete anything without my OK.";
|
|
44716
|
+
var AGENT_ROLES = [
|
|
44717
|
+
{
|
|
44718
|
+
key: "assistant",
|
|
44719
|
+
name: "Assistant",
|
|
44720
|
+
icon: "inbox",
|
|
44721
|
+
color: "#6366f1",
|
|
44722
|
+
tagline: "Inbox, calendar, meetings",
|
|
44723
|
+
outcomes: ["Inbox sorted, replies drafted", "A brief before every meeting", "Your week planned by Monday"],
|
|
44724
|
+
tools: ["zele", "zele-calendar", "outlook-api"],
|
|
44725
|
+
systemMessage: `You are my executive assistant. Keep my inbox and calendar under control. ${SAFE}
|
|
44726
|
+
|
|
44727
|
+
How you work:
|
|
44728
|
+
1. Read new emails and sort them: needs me / FYI / ignore.
|
|
44729
|
+
2. Draft replies for the ones that need me, in my voice.
|
|
44730
|
+
3. For meetings in the next 2 days, write a short brief from the related emails.
|
|
44731
|
+
4. Show me the drafts before anything is sent.`
|
|
44732
|
+
},
|
|
44733
|
+
{
|
|
44734
|
+
key: "bookkeeper",
|
|
44735
|
+
name: "Bookkeeping assistant",
|
|
44736
|
+
icon: "receipt",
|
|
44737
|
+
color: "#10b981",
|
|
44738
|
+
tagline: "Invoices, receipts, accountant",
|
|
44739
|
+
outcomes: ["Invoices from the inbox in one table", "Unpaid invoices reminded", "Month-end email to the accountant"],
|
|
44740
|
+
tools: ["zele", "stripe", "gdrive"],
|
|
44741
|
+
systemMessage: `You are my bookkeeping assistant. Keep invoices and receipts complete and organised. ${SAFE}
|
|
44742
|
+
|
|
44743
|
+
How you work:
|
|
44744
|
+
1. Find invoices and receipts from the last month (inbox, Stripe, Drive).
|
|
44745
|
+
2. Put them in a table: date, vendor, amount, VAT, attachment.
|
|
44746
|
+
3. List unpaid invoices and draft polite reminders.
|
|
44747
|
+
4. Draft the email to my accountant with the table; ask me before sending.`
|
|
44748
|
+
},
|
|
44749
|
+
{
|
|
44750
|
+
key: "sales",
|
|
44751
|
+
name: "Sales rep",
|
|
44752
|
+
icon: "target",
|
|
44753
|
+
color: "#f97316",
|
|
44754
|
+
tagline: "Leads, outreach, follow-ups",
|
|
44755
|
+
outcomes: ["Lead replies drafted in minutes", "Personal outreach at scale", "CRM always up to date"],
|
|
44756
|
+
tools: ["hubspot", "linkedin-api", "zele"],
|
|
44757
|
+
systemMessage: `You are my sales development rep. Research leads and write short, personal outreach. ${SAFE}
|
|
44758
|
+
|
|
44759
|
+
How you work:
|
|
44760
|
+
1. Research each lead: company, role, a relevant recent fact.
|
|
44761
|
+
2. Draft a short personal first message or reply.
|
|
44762
|
+
3. Update the CRM with the lead and a follow-up date.
|
|
44763
|
+
4. Ask me before sending any message.`
|
|
44764
|
+
},
|
|
44765
|
+
{
|
|
44766
|
+
key: "account-manager",
|
|
44767
|
+
name: "Account manager",
|
|
44768
|
+
icon: "briefcase",
|
|
44769
|
+
color: "#f59e0b",
|
|
44770
|
+
tagline: "Client updates, renewals",
|
|
44771
|
+
outcomes: ["Weekly status per client", "Recap after every call", "Silent clients flagged"],
|
|
44772
|
+
tools: ["zele", "slack-cli", "zele-calendar"],
|
|
44773
|
+
systemMessage: `You are my account manager. Keep every client relationship warm and on track. ${SAFE}
|
|
44774
|
+
|
|
44775
|
+
How you work:
|
|
44776
|
+
1. Find clients who have not replied to my last message for 5+ days.
|
|
44777
|
+
2. Draft a short, friendly follow-up for each.
|
|
44778
|
+
3. After calls, write a recap with decisions and next steps.
|
|
44779
|
+
4. Ask me before sending.`
|
|
44780
|
+
},
|
|
44781
|
+
{
|
|
44782
|
+
key: "social",
|
|
44783
|
+
name: "Social media manager",
|
|
44784
|
+
icon: "megaphone",
|
|
44785
|
+
color: "#ec4899",
|
|
44786
|
+
tagline: "Weekly posts in your voice",
|
|
44787
|
+
outcomes: ["Posts per channel in your style", "A full weekly calendar", "Reply drafts for comments"],
|
|
44788
|
+
tools: ["linkedin-api", "xurl", "facebook-pages-api"],
|
|
44789
|
+
systemMessage: `You are my social media manager. Write in my brand voice for each channel. ${SAFE}
|
|
44790
|
+
|
|
44791
|
+
How you work:
|
|
44792
|
+
1. Read my brand page and the voice for each channel.
|
|
44793
|
+
2. Draft 3 posts for this week, one idea each.
|
|
44794
|
+
3. Draft replies to new comments worth answering.
|
|
44795
|
+
4. Ask me before publishing anything.`
|
|
44796
|
+
},
|
|
44797
|
+
{
|
|
44798
|
+
key: "ads",
|
|
44799
|
+
name: "Ads manager",
|
|
44800
|
+
icon: "trending-up",
|
|
44801
|
+
color: "#3b82f6",
|
|
44802
|
+
tagline: "Meta and Google ads",
|
|
44803
|
+
outcomes: ["Wasted spend flagged daily", "Budget moved to the best ROAS", "Creative fatigue caught early"],
|
|
44804
|
+
tools: ["meta-ads", "google-ads"],
|
|
44805
|
+
systemMessage: `You are my ads manager. Watch performance and propose concrete changes. ${SAFE}
|
|
44806
|
+
|
|
44807
|
+
How you work:
|
|
44808
|
+
1. Pull yesterday's results per campaign and ad.
|
|
44809
|
+
2. Flag the worst cost per result and tired creatives.
|
|
44810
|
+
3. Propose budget moves with the numbers behind them.
|
|
44811
|
+
4. Ask me before changing any budget or pausing anything.`
|
|
44812
|
+
},
|
|
44813
|
+
{
|
|
44814
|
+
key: "developer",
|
|
44815
|
+
name: "Developer",
|
|
44816
|
+
icon: "code",
|
|
44817
|
+
color: "#0ea5e9",
|
|
44818
|
+
tagline: "Errors, PRs, deploys",
|
|
44819
|
+
outcomes: ["New errors grouped by cause each morning", "PR reviews with fixes", "Deploys after your OK"],
|
|
44820
|
+
tools: ["gh", "sentry-cli", "vercel"],
|
|
44821
|
+
systemMessage: `You are my senior developer. Keep the code healthy: small, tested, reviewed changes. Never deploy or merge without my OK.
|
|
44822
|
+
|
|
44823
|
+
How you work:
|
|
44824
|
+
1. Check new errors since yesterday and group them by cause.
|
|
44825
|
+
2. Fix the most important one on a branch, with a test.
|
|
44826
|
+
3. Open a pull request with a short explanation.
|
|
44827
|
+
4. Ask me before merging or deploying.`
|
|
44828
|
+
},
|
|
44829
|
+
{
|
|
44830
|
+
key: "researcher",
|
|
44831
|
+
name: "Market researcher",
|
|
44832
|
+
icon: "search",
|
|
44833
|
+
color: "#8b5cf6",
|
|
44834
|
+
tagline: "Competitors, markets, trends",
|
|
44835
|
+
outcomes: ["Weekly competitor watch", "Market brief before a pitch", "Brand mentions caught"],
|
|
44836
|
+
tools: ["perplexity-api", "agent-browser"],
|
|
44837
|
+
systemMessage: `You are my market researcher. Cite sources, separate facts from guesses, keep it short.
|
|
44838
|
+
|
|
44839
|
+
How you work:
|
|
44840
|
+
1. Check what my competitors shipped or announced this week.
|
|
44841
|
+
2. Search for new mentions of my brand.
|
|
44842
|
+
3. Write a one-page brief with sources.`
|
|
44843
|
+
}
|
|
44844
|
+
];
|
|
44713
44845
|
// ../packages/shared-fbe/src/tool_catalog.json
|
|
44714
44846
|
var tool_catalog_default = {
|
|
44715
44847
|
zele: {
|
|
@@ -44798,6 +44930,22 @@ var tool_catalog_default = {
|
|
|
44798
44930
|
description: "Figma REST API CLI. File commands take a file key or Figma URL. Canvas writes (frames/text/shapes) use `figma-api run` via the plugin bridge. Run `figma-api <cmd> --help` for params.",
|
|
44799
44931
|
versionCmd: "figma-api --version 2>/dev/null | sed -n 1p"
|
|
44800
44932
|
},
|
|
44933
|
+
"slack-api": {
|
|
44934
|
+
oauthBroker: true,
|
|
44935
|
+
category: "communication",
|
|
44936
|
+
pkg: "@todoforai/slack-api",
|
|
44937
|
+
installer: "npm",
|
|
44938
|
+
label: "Slack",
|
|
44939
|
+
summary: "Read and answer your Slack as yourself: DMs and mentions, search, history, threads.",
|
|
44940
|
+
loginCmd: "slack-api auth --token <user_token>",
|
|
44941
|
+
statusCmd: `slack-api whoami 2>/dev/null | sed -n 's/.*"user"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m1 .`,
|
|
44942
|
+
logoutCmd: "slack-api logout",
|
|
44943
|
+
credentialPaths: [
|
|
44944
|
+
"~/.config/slack-api/credentials.json"
|
|
44945
|
+
],
|
|
44946
|
+
versionCmd: "slack-api --version 2>/dev/null | sed -n 1p",
|
|
44947
|
+
description: "Slack Web API as the signed-in user (user token xoxp-, sees exactly what the user sees), JSON out. Sign-in: Connect (TODOforAI Slack app, user scopes) or `slack-api auth --stdin` / env SLACK_USER_TOKEN. `slack-api inbox [--days 3]` = DMs to you + @mentions, newest first, one JSON line each {id, thread, from, chat, subject, text, url, date} — a ready Feed source: `tfa-wait slack --feed --draft --repeat --forever --watch 'slack-api inbox' --every 2m --name Slack \"{{payload.text}}\"` (send-ready reply drafts in the Feed). Also `search '<slack query>'`, `history <C…|D…>`, `thread <channel> <ts>`, `conversations`, `user <U…>`, `dm <U…>`, `send <channel> <text> [--thread ts] --yes` (posts AS the user; without --yes only previews), `api <method> --param k=v` for any Web API method. search.messages is Tier 2 (~20/min); on ratelimited the error has retry_after. For Slack app development use slack-cli instead."
|
|
44948
|
+
},
|
|
44801
44949
|
"slack-cli": {
|
|
44802
44950
|
preinstallCloud: true,
|
|
44803
44951
|
cloudInstallCmd: "curl -fsSL https://github.com/slackapi/slack-cli/releases/download/v4.2.0/slack_cli_4.2.0_linux_amd64.tar.gz | tar -xz -C /tmp bin/slack && install -m0755 /tmp/bin/slack /usr/local/bin/slack-cli && rm -rf /tmp/bin",
|
|
@@ -45231,7 +45379,7 @@ var tool_catalog_default = {
|
|
|
45231
45379
|
installer: "npm",
|
|
45232
45380
|
label: "TODOforAI",
|
|
45233
45381
|
summary: "Create and follow up on your TODOs, and show results in the chat.",
|
|
45234
|
-
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]` (your own todos; `--
|
|
45382
|
+
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]` (your own todos; `--contributor all` for every member's), `--inspect <id>`. Edit any todo without opening it: `status <id> DONE|READY|CANCELLED|ARCHIVED|DELETED` (close, reopen, stop, archive, 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=…` (also permissions=… and judgeSysmsg=…; 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, `show ref <alias|todoId:alias>` re-posts it live at the chat bottom, `--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).",
|
|
45235
45383
|
installCmd: "npm install -g @todoforai/cli",
|
|
45236
45384
|
versionCmd: "tfa-cli --version 2>/dev/null | sed -n 1p",
|
|
45237
45385
|
preinstallCloud: true,
|
|
@@ -45435,12 +45583,9 @@ var tool_catalog_default = {
|
|
|
45435
45583
|
binName: "az",
|
|
45436
45584
|
statusCmd: "az account show --query user.name -o tsv 2>/dev/null | tr -d '\\r' | grep -m1 .",
|
|
45437
45585
|
logoutCmd: "az logout 2>&1; az account clear 2>&1",
|
|
45438
|
-
loginCmd: "az login --
|
|
45439
|
-
oauthUrlPattern: "(https://login\\.microsoft\\.com/device\\S*)",
|
|
45440
|
-
deviceCodePattern: "enter the code ([A-Z0-9]+)",
|
|
45441
|
-
canStreamLogin: true,
|
|
45586
|
+
loginCmd: "az login --allow-no-subscriptions",
|
|
45442
45587
|
credentialPaths: ["~/.azure"],
|
|
45443
|
-
description: 'Official Azure CLI.
|
|
45588
|
+
description: 'Official Azure CLI. Browser login with a localhost callback (device code is blocked by Entra Security Defaults on new tenants); `--allow-no-subscriptions` so tenants without a subscription still sign in. Azure SQL: `az sql server list -o json`, `az sql db list -s <server> -g <rg>`, `az sql server firewall-rule create …`; run queries with go-sqlcmd (github.com/microsoft/go-sqlcmd): `sqlcmd -S <server>.database.windows.net -d <db> --authentication-method ActiveDirectoryDefault -Q "SELECT …"` (reuses the az login) or `-U user -P pass` for SQL auth.',
|
|
45444
45589
|
versionCmd: "az version -o tsv 2>/dev/null | cut -f1 | sed -n 1p"
|
|
45445
45590
|
},
|
|
45446
45591
|
doctl: {
|
|
@@ -46132,11 +46277,12 @@ var tool_catalog_default = {
|
|
|
46132
46277
|
statusCmd: `outlook-api whoami 2>/dev/null | sed -n 's/.*"userPrincipalName"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m10 .`,
|
|
46133
46278
|
logoutCmd: "outlook-api logout",
|
|
46134
46279
|
loginCmd: "outlook-api auth --tenant common",
|
|
46280
|
+
oauthBroker: true,
|
|
46135
46281
|
credentialPaths: ["~/.config/outlook-api/config.json"],
|
|
46136
|
-
description: "Outlook/Hotmail/M365 mail and calendar over Microsoft Graph (on-prem Exchange → ews-api). `auth` =
|
|
46282
|
+
description: "Outlook/Hotmail/M365 mail and calendar over Microsoft Graph (on-prem Exchange → ews-api). `auth --tenant common` = browser login, redirect to localhost:8644 (`--device` = device code for headless hosts). list/search/read/attachments are read-only; `draft`/`reply` stay in Drafts unless --send; `send <draftId>`. Calendar: `events [--days N|--start|--end] [--tz Europe/Budapest]` (calendarView, recurrences expanded), `event <id>`, `calendars`, `freebusy <emails…>`; writes: `event-create`, `event-respond <id> accept|tentativelyAccept|decline`, `event-delete`. `get <path>` = raw Graph GET. JSON out.",
|
|
46137
46283
|
versionCmd: "outlook-api --version 2>/dev/null | sed -n 1p",
|
|
46138
|
-
|
|
46139
|
-
|
|
46284
|
+
oauthUrlPattern: "(https://login\\.microsoftonline\\.com/\\S+/oauth2/v2\\.0/authorize\\S+)",
|
|
46285
|
+
oauthCallbackPort: 8644,
|
|
46140
46286
|
canStreamLogin: true
|
|
46141
46287
|
},
|
|
46142
46288
|
"outlook-calendar": {
|
|
@@ -46151,11 +46297,12 @@ var tool_catalog_default = {
|
|
|
46151
46297
|
statusCmd: `outlook-api whoami 2>/dev/null | sed -n 's/.*"userPrincipalName"[[:space:]]*:[[:space:]]*"\\([^"]*\\)".*/\\1/p' | grep -m10 .`,
|
|
46152
46298
|
logoutCmd: "outlook-api logout",
|
|
46153
46299
|
loginCmd: "outlook-api auth --tenant common",
|
|
46300
|
+
oauthBroker: true,
|
|
46154
46301
|
credentialPaths: ["~/.config/outlook-api/config.json"],
|
|
46155
46302
|
description: "Outlook/M365 calendar via `outlook-api`: `events [--days N|--start|--end] [--tz Europe/Budapest]` (calendarView, recurrences expanded), `event <id>`, `calendars`, `freebusy <emails…>` (getSchedule; work/school accounts only); writes: `event-create --subject --start --end [--tz] [--attendee …] [--online]`, `event-respond <id> accept|tentativelyAccept|decline`, `event-delete <id>`. Same sign-in as Outlook mail (`auth`, device code).",
|
|
46156
46303
|
versionCmd: "outlook-api --version 2>/dev/null | sed -n 1p",
|
|
46157
|
-
|
|
46158
|
-
|
|
46304
|
+
oauthUrlPattern: "(https://login\\.microsoftonline\\.com/\\S+/oauth2/v2\\.0/authorize\\S+)",
|
|
46305
|
+
oauthCallbackPort: 8644,
|
|
46159
46306
|
canStreamLogin: true
|
|
46160
46307
|
},
|
|
46161
46308
|
neonctl: {
|
|
@@ -46183,11 +46330,9 @@ var tool_catalog_default = {
|
|
|
46183
46330
|
summary: "Work with Microsoft 365 mail, Teams, SharePoint and users.",
|
|
46184
46331
|
statusCmd: `m365 status --output text 2>/dev/null | tr -d '"' | grep -vi 'logged out' | grep -m1 .`,
|
|
46185
46332
|
logoutCmd: "m365 logout",
|
|
46186
|
-
loginCmd: "m365 login --authType
|
|
46187
|
-
deviceCodePattern: "enter the code ([A-Z0-9]{8,}) to authenticate",
|
|
46188
|
-
oauthUrlPattern: "open the page (https://\\S+) and enter",
|
|
46333
|
+
loginCmd: "m365 login --authType browser --appId 14d82eec-204b-4c2f-b7e8-296a70dab67e",
|
|
46189
46334
|
credentialPaths: ["~/.cli-m365-msal.json", "~/.cli-m365-connection.json"],
|
|
46190
|
-
description: "Microsoft 365 from the shell: `m365 outlook message list`, `m365 teams team list`, `m365 spo site list`.
|
|
46335
|
+
description: "Microsoft 365 from the shell: `m365 outlook message list`, `m365 teams team list`, `m365 spo site list`. Browser login with a localhost callback (device code is blocked by Entra Security Defaults); add `--output json` for parseable output.",
|
|
46191
46336
|
versionCmd: `m365 version 2>/dev/null | tr -d '"' | sed -n 1p`
|
|
46192
46337
|
},
|
|
46193
46338
|
gws: {
|
|
@@ -46361,7 +46506,7 @@ var tool_catalog_default = {
|
|
|
46361
46506
|
installer: "pip",
|
|
46362
46507
|
label: "Blender",
|
|
46363
46508
|
summary: "Model, texture and render 3D scenes in a running Blender.",
|
|
46364
|
-
statusCmd:
|
|
46509
|
+
statusCmd: "command -v blender-mcp >/dev/null && mcporter call blender.get_addon_status --output json 2>/dev/null | grep -o 'blender_version[^,}]*' | grep -m1 .",
|
|
46365
46510
|
loginNoBrowser: true,
|
|
46366
46511
|
loginTerminalHint: "Needs Blender (blender.org) open on this host: in Blender, Edit → Preferences → Add-ons, enable `Blender MCP`, then press N in the 3D view → BlenderMCP tab → Connect / Start MCP server. Then press Connect here.",
|
|
46367
46512
|
loginCmd: `blender-mcp install-addon >/dev/null 2>&1; command -v mcporter >/dev/null 2>&1 || npm install -g --prefix "$HOME/.local" mcporter; mcporter config add blender --command blender-mcp --env BLENDER_MCP_DISABLE_TELEMETRY=1 --description 'Blender 3D via ahujasid/blender-mcp addon' --scope home`,
|
|
@@ -50180,7 +50325,56 @@ var PUBLIC_EMAIL_DOMAINS = new Set([
|
|
|
50180
50325
|
"gmx.com",
|
|
50181
50326
|
"gmx.net",
|
|
50182
50327
|
"mail.com",
|
|
50183
|
-
"zoho.com"
|
|
50328
|
+
"zoho.com",
|
|
50329
|
+
"aol.com",
|
|
50330
|
+
"msn.com",
|
|
50331
|
+
"yahoo.co.uk",
|
|
50332
|
+
"yahoo.de",
|
|
50333
|
+
"yahoo.fr",
|
|
50334
|
+
"yahoo.co.jp",
|
|
50335
|
+
"ymail.com",
|
|
50336
|
+
"pm.me",
|
|
50337
|
+
"tutanota.com",
|
|
50338
|
+
"tuta.io",
|
|
50339
|
+
"gmx.de",
|
|
50340
|
+
"gmx.at",
|
|
50341
|
+
"web.de",
|
|
50342
|
+
"t-online.de",
|
|
50343
|
+
"freenet.de",
|
|
50344
|
+
"orange.fr",
|
|
50345
|
+
"free.fr",
|
|
50346
|
+
"laposte.net",
|
|
50347
|
+
"libero.it",
|
|
50348
|
+
"virgilio.it",
|
|
50349
|
+
"freemail.hu",
|
|
50350
|
+
"citromail.hu",
|
|
50351
|
+
"indamail.hu",
|
|
50352
|
+
"vipmail.hu",
|
|
50353
|
+
"t-email.hu",
|
|
50354
|
+
"seznam.cz",
|
|
50355
|
+
"centrum.cz",
|
|
50356
|
+
"wp.pl",
|
|
50357
|
+
"o2.pl",
|
|
50358
|
+
"onet.pl",
|
|
50359
|
+
"interia.pl",
|
|
50360
|
+
"yandex.ru",
|
|
50361
|
+
"yandex.com",
|
|
50362
|
+
"mail.ru",
|
|
50363
|
+
"rambler.ru",
|
|
50364
|
+
"bk.ru",
|
|
50365
|
+
"inbox.ru",
|
|
50366
|
+
"list.ru",
|
|
50367
|
+
"ukr.net",
|
|
50368
|
+
"qq.com",
|
|
50369
|
+
"foxmail.com",
|
|
50370
|
+
"163.com",
|
|
50371
|
+
"126.com",
|
|
50372
|
+
"yeah.net",
|
|
50373
|
+
"sina.com",
|
|
50374
|
+
"naver.com",
|
|
50375
|
+
"daum.net",
|
|
50376
|
+
"hanmail.net",
|
|
50377
|
+
"rediffmail.com"
|
|
50184
50378
|
]);
|
|
50185
50379
|
// ../packages/shared-fbe/src/toolInstallCommand.ts
|
|
50186
50380
|
var NPM_HOME = '"${TFA_NPM_HOME:-$HOME}"';
|
|
@@ -50197,38 +50391,52 @@ var model_promos_default = {
|
|
|
50197
50391
|
"`family` is a regex on the normalized model id (last path segment, lowercase, dots→dashes, '(level)' suffix stripped);",
|
|
50198
50392
|
"'(-\\\\d+)*' trailing point versions are appended by the consumer, so 'claude-opus-5' covers claude-opus-5.2 too.",
|
|
50199
50393
|
"`provider` matches the provider name instead (TODO GO / Ollama Cloud, subscription-wide).",
|
|
50200
|
-
"`rate` = fraction off. `boostable:false` = the Ultra/Team promo boost (remaining price × boost_remaining_price_factor: +50% usage,
|
|
50394
|
+
"`rate` = fraction off. `boostable:false` = the Ultra/Team promo boost (remaining price × boost_remaining_price_factor ≈ 2/3: +50% usage, 70%→80%, 55%→70%; 0.6666 not 0.667 so the floored display hits 80/70) is NOT applied.",
|
|
50201
50395
|
"`ends` is the last inclusive day (UTC).",
|
|
50202
|
-
"Overlapping rows are fine: the consumer takes the highest live rate. Launch pricing = 85% until 2026-09-13
|
|
50396
|
+
"Overlapping rows are fine: the consumer takes the highest live rate. Launch pricing = 85% until 2026-09-13, 80% until 2026-10-28; from 2026-10-29 to 2026-11-21: OpenAI 70%, Anthropic 55%, Astra 50%, Fable 30%; TODO GO/Ollama no promo (ended 2026-10-28). Astra/Fable/subscription providers are never boosted.",
|
|
50203
50397
|
"A change here goes live with a backend + frontend deploy; agent/src/assets/model_promos.json is only the agent's offline fallback, refresh it occasionally."
|
|
50204
50398
|
],
|
|
50205
|
-
boost_remaining_price_factor: 0.
|
|
50399
|
+
boost_remaining_price_factor: 0.6666,
|
|
50206
50400
|
promos: [
|
|
50207
|
-
{ family: "claude-fable-5", rate: 0.5, starts: "2026-06-29", ends: "2026-
|
|
50401
|
+
{ family: "claude-fable-5", rate: 0.5, starts: "2026-06-29", ends: "2026-10-28", boostable: false },
|
|
50208
50402
|
{ family: "claude-opus-5", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50209
|
-
{ family: "claude-opus-5", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50403
|
+
{ family: "claude-opus-5", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50210
50404
|
{ family: "claude-opus-4-[78]", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50211
|
-
{ family: "claude-opus-4-[78]", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50405
|
+
{ family: "claude-opus-4-[78]", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50212
50406
|
{ family: "claude-sonnet-5", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50213
|
-
{ family: "claude-sonnet-5", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50407
|
+
{ family: "claude-sonnet-5", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50214
50408
|
{ family: "claude-haiku-4-5", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50215
|
-
{ family: "claude-haiku-4-5", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50409
|
+
{ family: "claude-haiku-4-5", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50216
50410
|
{ family: "claude-haiku-5", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50217
|
-
{ family: "claude-haiku-5", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50411
|
+
{ family: "claude-haiku-5", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50218
50412
|
{ family: "gpt-5-5(-pro)?", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50219
|
-
{ family: "gpt-5-5(-pro)?", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50413
|
+
{ family: "gpt-5-5(-pro)?", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50220
50414
|
{ family: "gpt-5-6-sol", rate: 0.85, starts: "2026-08-26", ends: "2026-09-13" },
|
|
50221
|
-
{ family: "gpt-5-6-sol", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50222
|
-
{ family: "gpt-6-sol", rate: 0.8, starts: "2026-09-22", ends: "2026-
|
|
50223
|
-
{ family: "gpt-6-1-sol", rate: 0.8, starts: "2026-09-29", ends: "2026-
|
|
50224
|
-
{ family: "gpt-6-luna", rate: 0.8, starts: "2026-09-22", ends: "2026-
|
|
50415
|
+
{ family: "gpt-5-6-sol", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50416
|
+
{ family: "gpt-6-sol", rate: 0.8, starts: "2026-09-22", ends: "2026-10-28" },
|
|
50417
|
+
{ family: "gpt-6-1-sol", rate: 0.8, starts: "2026-09-29", ends: "2026-10-28" },
|
|
50418
|
+
{ family: "gpt-6-luna", rate: 0.8, starts: "2026-09-22", ends: "2026-10-28" },
|
|
50225
50419
|
{ family: "gpt-6-astra", rate: 0.85, starts: "2026-09-05", ends: "2026-09-13", boostable: false },
|
|
50226
|
-
{ family: "gpt-6-astra", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50420
|
+
{ family: "gpt-6-astra", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28", boostable: false },
|
|
50227
50421
|
{ family: "gpt-5-6-terra", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50228
|
-
{ family: "gpt-5-6-terra", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50422
|
+
{ family: "gpt-5-6-terra", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50229
50423
|
{ family: "gpt-5-6-luna", rate: 0.85, starts: "2026-06-29", ends: "2026-09-13" },
|
|
50230
|
-
{ family: "gpt-5-6-luna", rate: 0.8, starts: "2026-09-14", ends: "2026-
|
|
50231
|
-
{ provider: "opencode[_ -]?go|ollama[_ -]?cloud", rate: 0.5, starts: "2026-06-29", ends: "2026-
|
|
50424
|
+
{ family: "gpt-5-6-luna", rate: 0.8, starts: "2026-09-14", ends: "2026-10-28" },
|
|
50425
|
+
{ provider: "opencode[_ -]?go|ollama[_ -]?cloud", rate: 0.5, starts: "2026-06-29", ends: "2026-10-28", boostable: false },
|
|
50426
|
+
{ family: "claude-opus-5", rate: 0.55, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50427
|
+
{ family: "claude-opus-4-[78]", rate: 0.55, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50428
|
+
{ family: "claude-sonnet-5", rate: 0.55, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50429
|
+
{ family: "claude-haiku-4-5", rate: 0.55, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50430
|
+
{ family: "claude-haiku-5", rate: 0.55, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50431
|
+
{ family: "claude-fable-5", rate: 0.3, starts: "2026-10-29", ends: "2026-11-21", boostable: false },
|
|
50432
|
+
{ family: "gpt-5-5(-pro)?", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50433
|
+
{ family: "gpt-5-6-sol", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50434
|
+
{ family: "gpt-6-sol", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50435
|
+
{ family: "gpt-6-1-sol", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50436
|
+
{ family: "gpt-6-luna", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50437
|
+
{ family: "gpt-5-6-terra", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50438
|
+
{ family: "gpt-5-6-luna", rate: 0.7, starts: "2026-10-29", ends: "2026-11-21" },
|
|
50439
|
+
{ family: "gpt-6-astra", rate: 0.5, starts: "2026-10-29", ends: "2026-11-21", boostable: false }
|
|
50232
50440
|
]
|
|
50233
50441
|
};
|
|
50234
50442
|
|
|
@@ -50238,11 +50446,11 @@ var MODEL_PROMOS = model_promos_default.promos;
|
|
|
50238
50446
|
// ../packages/shared-fbe/src/realtime/topics.ts
|
|
50239
50447
|
var TOPICS = {
|
|
50240
50448
|
["todo:new" /* NEW_TODO */]: {
|
|
50241
|
-
channel: (p) => SERVER_TO_FRONTENDS.project.new_todo(p.projectId, p.
|
|
50449
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.new_todo(p.projectId, p.memberId),
|
|
50242
50450
|
audience: "frontend"
|
|
50243
50451
|
},
|
|
50244
50452
|
["todo:new_message" /* TODO_NEW_MESSAGE */]: {
|
|
50245
|
-
channel: (p) => SERVER_TO_FRONTENDS.project.new_message(p.projectId, p.
|
|
50453
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.new_message(p.projectId, p.memberId),
|
|
50246
50454
|
audience: "frontend"
|
|
50247
50455
|
},
|
|
50248
50456
|
["todo:new_message_created" /* TODO_NEW_MESSAGE_CREATED */]: {
|
|
@@ -50390,7 +50598,7 @@ var TOPICS = {
|
|
|
50390
50598
|
audience: "frontend"
|
|
50391
50599
|
},
|
|
50392
50600
|
["project:status" /* PROJECT_STATUS */]: {
|
|
50393
|
-
channel: (p) => SERVER_TO_FRONTENDS.project.status(p.projectId, p.
|
|
50601
|
+
channel: (p) => SERVER_TO_FRONTENDS.project.status(p.projectId, p.memberId),
|
|
50394
50602
|
audience: "frontend"
|
|
50395
50603
|
},
|
|
50396
50604
|
["todo:status" /* TODO_STATUS */]: {
|
|
@@ -50432,7 +50640,7 @@ var package_default = {
|
|
|
50432
50640
|
type: "git",
|
|
50433
50641
|
url: "git+https://github.com/todoforai/cli.git"
|
|
50434
50642
|
},
|
|
50435
|
-
version: "0.1.
|
|
50643
|
+
version: "0.1.74",
|
|
50436
50644
|
type: "module",
|
|
50437
50645
|
bin: {
|
|
50438
50646
|
"todoforai-cli": "bin/todoforai-cli.js",
|
|
@@ -50587,7 +50795,7 @@ var STATUS_HELP = {
|
|
|
50587
50795
|
["READY_CHECKED" /* READY_CHECKED */]: "AI finished and the user reviewed it",
|
|
50588
50796
|
["DONE" /* DONE */]: "Completed and finalized",
|
|
50589
50797
|
["REVIEW_REQUESTED" /* REVIEW_REQUESTED */]: "Asks the user to review",
|
|
50590
|
-
["
|
|
50798
|
+
["CANCELLED" /* CANCELLED */]: "Stop a running TODO",
|
|
50591
50799
|
["ARCHIVED" /* ARCHIVED */]: "Archived (hidden from active list)",
|
|
50592
50800
|
["DELETED" /* DELETED */]: "Marked for deletion"
|
|
50593
50801
|
};
|
|
@@ -50600,7 +50808,7 @@ ${Object.entries(STATUS_HELP).map(([s, d]) => ` ${s.padEnd(18)}${d}`).join(`
|
|
|
50600
50808
|
`)}
|
|
50601
50809
|
|
|
50602
50810
|
All valid statuses:
|
|
50603
|
-
${Object.values(TodoStatus).join(", ")}
|
|
50811
|
+
${Object.values(TodoStatus).filter((s) => s !== "POSTPONED" /* POSTPONED */).join(", ")}
|
|
50604
50812
|
`);
|
|
50605
50813
|
}
|
|
50606
50814
|
var WORD_FLAGS = {
|
|
@@ -53466,8 +53674,9 @@ Examples:
|
|
|
53466
53674
|
tfa-cli agent update <agent> sysmsg="You are a terse video editor."
|
|
53467
53675
|
tfa-cli agent create name=Reviewer model=claude sysmsg="Review diffs only."
|
|
53468
53676
|
tfa-cli agent update <agent> judgeSysmsg="Ask before sending email." (approval checker; ""=off, null=inherit global)
|
|
53677
|
+
tfa-cli agent update <agent> permissions='{"allow":[…],"ask":[…],"deny":[…]}' (replaces all three lists; read them with get --json first)
|
|
53469
53678
|
|
|
53470
|
-
From an agent shell (dst_ token)
|
|
53679
|
+
From an agent shell (dst_ token) edgesMcpConfigs, devicesConfig, toolProfiles and delete are refused by the backend.
|
|
53471
53680
|
`);
|
|
53472
53681
|
}
|
|
53473
53682
|
var FIELD_ALIASES = {
|
|
@@ -53674,7 +53883,7 @@ var STATUS_HELP2 = {
|
|
|
53674
53883
|
["READY_CHECKED" /* READY_CHECKED */]: "AI finished and the user reviewed it",
|
|
53675
53884
|
["DONE" /* DONE */]: "Completed and finalized",
|
|
53676
53885
|
["REVIEW_REQUESTED" /* REVIEW_REQUESTED */]: "Asks the user to review",
|
|
53677
|
-
["
|
|
53886
|
+
["CANCELLED" /* CANCELLED */]: "Stop a running TODO",
|
|
53678
53887
|
["ARCHIVED" /* ARCHIVED */]: "Archived (hidden from active list)",
|
|
53679
53888
|
["DELETED" /* DELETED */]: "Marked for deletion"
|
|
53680
53889
|
};
|
|
@@ -53891,7 +54100,7 @@ tfa-cli project — edit the current project
|
|
|
53891
54100
|
Usage:
|
|
53892
54101
|
tfa-cli project list Projects you can access (* = default)
|
|
53893
54102
|
tfa-cli project members Who is on it (notify --to <email> reaches them)
|
|
53894
|
-
tfa-cli project set <field=value>… name=… description=…
|
|
54103
|
+
tfa-cli project set <field=value>… name=… description=… logo=<https image url|"">
|
|
53895
54104
|
(isPublic refused from an agent shell)
|
|
53896
54105
|
tfa-cli project default Make it the project you land on at /
|
|
53897
54106
|
tfa-cli project agent <agent> Default agent for new todos in this project
|
|
@@ -53901,11 +54110,15 @@ Usage:
|
|
|
53901
54110
|
tfa-cli project groups intake <slug> [on|off|regenerate] [field=value]…
|
|
53902
54111
|
Public intake: autoStart maxSubmissions postIpLimit placeholder agentSettingsId
|
|
53903
54112
|
tfa-cli project groups reorder <slug>… Set wall order
|
|
53904
|
-
tfa-cli project surfaces List the board's
|
|
53905
|
-
tfa-cli project surfaces set <id> ref=<ref> [title=…] [group=<slug>] [order=N]
|
|
54113
|
+
tfa-cli project surfaces List the board's cards you can see: id, title, ref|note, group, color
|
|
54114
|
+
tfa-cli project surfaces set <id> ref=<ref> [title=…] [group=<slug>] [color=#hex] [order=N]
|
|
53906
54115
|
Show a ref on the board: a todo id, <todoId>:<alias>
|
|
53907
54116
|
(shown artifact) or an http(s) url. group= puts it
|
|
53908
54117
|
inside that group's card; group="" makes it standalone.
|
|
54118
|
+
tfa-cli project surfaces set <id> body="…" [group=<slug>] [color=#hex]
|
|
54119
|
+
A note (markdown text). Seen by
|
|
54120
|
+
whoever sees where it sits: standalone = the project,
|
|
54121
|
+
group = its members, your My Private group = only you.
|
|
53909
54122
|
tfa-cli project surfaces rm <id> Take it off the board
|
|
53910
54123
|
|
|
53911
54124
|
Examples:
|
|
@@ -53913,6 +54126,7 @@ Examples:
|
|
|
53913
54126
|
tfa-cli project groups set marketing name=Marketing description="Top-of-funnel work"
|
|
53914
54127
|
tfa-cli project groups reorder marketing sales ops
|
|
53915
54128
|
tfa-cli project surfaces set weekly-kpis ref=$TODOFORAI_TODO_ID:kpi title="Weekly KPIs" group=marketing
|
|
54129
|
+
tfa-cli project surfaces set sales-rules body="Quote prices in EUR, net of VAT." group=sales
|
|
53916
54130
|
`);
|
|
53917
54131
|
}
|
|
53918
54132
|
var TODO_ALIASES = {
|
|
@@ -54101,21 +54315,23 @@ async function projectCommand(api, positionals, args, projectId) {
|
|
|
54101
54315
|
console.log(JSON.stringify(surfaces, null, 2));
|
|
54102
54316
|
return;
|
|
54103
54317
|
}
|
|
54318
|
+
const titleOf = (s) => s.title || (s.body ?? "").split(`
|
|
54319
|
+
`).find((l) => l.trim())?.trim().slice(0, 60) || "";
|
|
54104
54320
|
for (const s of surfaces)
|
|
54105
|
-
process.stderr.write(`${s.id} ${s
|
|
54321
|
+
process.stderr.write(`${s.id} ${titleOf(s)} ${DIM}${[s.ref ?? "note", s.group && `in ${s.group}`, s.color].filter(Boolean).join(" ")}${RESET}
|
|
54106
54322
|
`);
|
|
54107
54323
|
return;
|
|
54108
54324
|
}
|
|
54109
54325
|
if (verb === "set") {
|
|
54110
54326
|
const [id, ...fields] = sargs;
|
|
54111
54327
|
if (!id)
|
|
54112
|
-
fail("Usage: tfa-cli project surfaces set <id> ref=<ref
|
|
54328
|
+
fail("Usage: tfa-cli project surfaces set <id> [ref=<ref>|body=…] [title=…] [group=<slug>] [color=#hex] [order=N]");
|
|
54113
54329
|
const surface = await api.upsertProjectSurface(projectId, id, parseAssignments2(fields));
|
|
54114
54330
|
if (args.json) {
|
|
54115
54331
|
console.log(JSON.stringify(surface, null, 2));
|
|
54116
54332
|
return;
|
|
54117
54333
|
}
|
|
54118
|
-
process.stderr.write(`${GREEN}✅ surface ${id} shows ${surface.ref}${surface.group ? ` in ${surface.group}` : ""}${RESET}
|
|
54334
|
+
process.stderr.write(`${GREEN}✅ surface ${id} ${surface.ref ? `shows ${surface.ref}` : "is a note"}${surface.group ? ` in ${surface.group}` : ""}${RESET}
|
|
54119
54335
|
`);
|
|
54120
54336
|
return;
|
|
54121
54337
|
}
|
|
@@ -54487,40 +54703,26 @@ var VALID_STATUS = new Set(Object.values(TodoStatus));
|
|
|
54487
54703
|
var isOpen = (s) => !CLOSED.has(s);
|
|
54488
54704
|
function printListTodosHelp() {
|
|
54489
54705
|
process.stderr.write(`
|
|
54490
|
-
todoforai-cli list —
|
|
54706
|
+
todoforai-cli list [flags] — todos of a project, newest first (lastActivityAt)
|
|
54491
54707
|
|
|
54492
|
-
|
|
54708
|
+
Scope: yours only (todos you opened or wrote in) → --contributor all = every member's
|
|
54709
|
+
open only (hides DONE, ARCHIVED, DELETED) → -A / --all = closed too
|
|
54710
|
+
Output: STATUS YYYY-MM-DD HH:MM <todoId> <first line of content>
|
|
54711
|
+
--json → { items: [{ id, status, content, lastActivityAt, createdAt, contributorIds, … }], nextCursor }
|
|
54493
54712
|
|
|
54494
|
-
|
|
54495
|
-
|
|
54713
|
+
Filters (all combinable):
|
|
54714
|
+
-s, --status <S,S2> exact statuses, union (closed ones included); OPEN = any non-closed
|
|
54715
|
+
--search <text> content/status substring (backend)
|
|
54716
|
+
--contributor <u> id or email, comma = any; "all" = no filter (default: you)
|
|
54717
|
+
--since/--until <t> window on the sort field: epoch ms | YYYY-MM-DD | ISO | 12h / 3d (ago)
|
|
54718
|
+
--sort created by createdAt instead of activity
|
|
54719
|
+
--project <id> other project (default: the current one)
|
|
54496
54720
|
|
|
54497
|
-
|
|
54498
|
-
--project-wide Every member's todos, not just yours
|
|
54499
|
-
-n, --limit <n> Max rows to show (default: 30)
|
|
54500
|
-
--cursor <n> Fetch todos older than this cursor (sort field, epoch ms)
|
|
54501
|
-
--since <t> Only todos with sort field >= t (inclusive)
|
|
54502
|
-
--until <t> Only todos with sort field < t (exclusive)
|
|
54503
|
-
t = epoch ms | YYYY-MM-DD (local midnight) | ISO datetime | 12h / 3d ago
|
|
54504
|
-
--sort <key> activity (lastActivityAt, default) | created (createdAt)
|
|
54505
|
-
--contributor <u> Only todos a member opened/wrote in (id or email; comma = any; replaces the "mine" default)
|
|
54506
|
-
--page-size <n> Backend page size per request (default: min(limit, 400), max: 400)
|
|
54507
|
-
--search <text> Search content/status on the backend
|
|
54508
|
-
-s, --status <S[,S2]> Filter by status (comma-separated, union).
|
|
54509
|
-
-A, --all Include closed (DONE, ARCHIVED, DELETED)
|
|
54510
|
-
--project <id> Project ID (default: current default project)
|
|
54511
|
-
--json Output { items, nextCursor } as JSON
|
|
54512
|
-
-h, --help Show this help
|
|
54721
|
+
Paging: -n <limit> (default 30). "Next cursor: N" on stderr / nextCursor in JSON → re-run with --cursor N.
|
|
54513
54722
|
|
|
54514
54723
|
Examples:
|
|
54515
|
-
todoforai-cli list # 30 most recent open todos of yours
|
|
54516
|
-
todoforai-cli list --project-wide # … of everyone in the project
|
|
54517
|
-
todoforai-cli list -n 50 # last 50 open
|
|
54518
|
-
todoforai-cli list --cursor 1719234567890 # next page
|
|
54519
|
-
todoforai-cli list --all # include DONE
|
|
54520
54724
|
todoforai-cli list -s RUNNING,REVIEW_REQUESTED
|
|
54521
|
-
todoforai-cli list -A --since
|
|
54522
|
-
todoforai-cli list -A --sort created --since 7d --contributor a@b.com
|
|
54523
|
-
todoforai-cli list --search bug --json | jq '.items[].id'
|
|
54725
|
+
todoforai-cli list --contributor all -A --since 7d --json | jq -r '.items[] | [.id, .status] | @tsv'
|
|
54524
54726
|
`);
|
|
54525
54727
|
}
|
|
54526
54728
|
function positiveInt(value, name) {
|
|
@@ -54617,7 +54819,6 @@ async function listTodosCommand(api, defaultProjectId, argv, resolveUserId) {
|
|
|
54617
54819
|
until: { type: "string" },
|
|
54618
54820
|
sort: { type: "string" },
|
|
54619
54821
|
contributor: { type: "string" },
|
|
54620
|
-
"project-wide": { type: "boolean", default: false },
|
|
54621
54822
|
status: { type: "string", short: "s" },
|
|
54622
54823
|
all: { type: "boolean", short: "A", default: false },
|
|
54623
54824
|
project: { type: "string" },
|
|
@@ -54650,9 +54851,11 @@ async function listTodosCommand(api, defaultProjectId, argv, resolveUserId) {
|
|
|
54650
54851
|
if (until !== undefined)
|
|
54651
54852
|
cursor = cursor === undefined ? until : Math.min(cursor, until);
|
|
54652
54853
|
const search = values.search ? String(values.search) : undefined;
|
|
54653
|
-
|
|
54854
|
+
const contributorArg = values.contributor === undefined ? undefined : String(values.contributor);
|
|
54855
|
+
const everyone = contributorArg?.trim().toLowerCase() === "all";
|
|
54856
|
+
let contributorIds = contributorArg && !everyone ? await resolveContributors(api, projectId, contributorArg) : undefined;
|
|
54654
54857
|
let mineOnly = false;
|
|
54655
|
-
if (!contributorIds && !
|
|
54858
|
+
if (!contributorIds && !everyone && resolveUserId) {
|
|
54656
54859
|
const me = await resolveUserId();
|
|
54657
54860
|
if (me) {
|
|
54658
54861
|
contributorIds = [me];
|
|
@@ -54714,7 +54917,7 @@ async function listTodosCommand(api, defaultProjectId, argv, resolveUserId) {
|
|
|
54714
54917
|
`);
|
|
54715
54918
|
return;
|
|
54716
54919
|
}
|
|
54717
|
-
const scopeHint = mineOnly ? " of yours (--
|
|
54920
|
+
const scopeHint = mineOnly ? " of yours (--contributor all for everyone's)" : "";
|
|
54718
54921
|
if (!visible.length) {
|
|
54719
54922
|
process.stderr.write(`${DIM}(no todos${scopeHint})${RESET}
|
|
54720
54923
|
`);
|