@todoforai/cli 0.1.58 → 0.1.60

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.
@@ -42884,6 +42884,15 @@ class ApiClient {
42884
42884
  renameDevice(id, name) {
42885
42885
  return this.request("PATCH", `/api/v1/devices/${id}/name`, { id, name });
42886
42886
  }
42887
+ getDeviceAccess(id) {
42888
+ return this.request("GET", `/api/v1/devices/${id}/access`);
42889
+ }
42890
+ shareDevice(id, email) {
42891
+ return this.request("POST", `/api/v1/devices/${id}/share`, { id, email });
42892
+ }
42893
+ unshareDevice(id, email) {
42894
+ return this.request("POST", `/api/v1/devices/${id}/unshare`, { id, email });
42895
+ }
42887
42896
  setDeviceWallpaperMode(id, mode) {
42888
42897
  return this.request("POST", `/api/v1/devices/${id}/wallpaper-mode`, { id, mode });
42889
42898
  }
@@ -43183,6 +43192,9 @@ import WebSocket from "ws";
43183
43192
  import { readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
43184
43193
  import { join, dirname } from "node:path";
43185
43194
  import { homedir, platform } from "node:os";
43195
+ function runActorToken() {
43196
+ return process.env.TODOFORAI_USER_ID ? process.env.TODOFORAI_API_TOKEN || "" : "";
43197
+ }
43186
43198
  function normalizeApiUrl(url) {
43187
43199
  if (url.startsWith("localhost"))
43188
43200
  return `http://${url}`;
@@ -44610,7 +44622,7 @@ var tool_catalog_default = {
44610
44622
  statusCmd: "ntn doctor 2>&1 | grep -E 'Token valid\\s+✔' >/dev/null && echo authenticated",
44611
44623
  loginCmd: "ntn login",
44612
44624
  loginNeedsPty: true,
44613
- oauthUrlPattern: "(https://www\\.notion\\.so/workers/cli-login\\S+)",
44625
+ oauthUrlPattern: "(https://(?:www\\.notion\\.so|app\\.notion\\.com)/workers/cli-login\\S+)",
44614
44626
  sessionIdPattern: "verificationCode=([A-Z0-9-]{5,12})",
44615
44627
  credentialPaths: ["~/.config/notion"],
44616
44628
  versionCmd: "ntn --version 2>/dev/null | sed -n 1p",
@@ -46123,7 +46135,7 @@ import { parseArgs } from "util";
46123
46135
  // package.json
46124
46136
  var package_default = {
46125
46137
  name: "@todoforai/cli",
46126
- version: "0.1.58",
46138
+ version: "0.1.60",
46127
46139
  type: "module",
46128
46140
  bin: {
46129
46141
  "todoforai-cli": "bin/todoforai-cli.js",
@@ -46303,6 +46315,7 @@ function parseCliArgs() {
46303
46315
  direction: { type: "string" },
46304
46316
  url: { type: "string" },
46305
46317
  "pasted-file": { type: "string" },
46318
+ account: { type: "string" },
46306
46319
  "from-company": { type: "boolean", default: false },
46307
46320
  "dry-run": { type: "boolean", default: false },
46308
46321
  max: { type: "string" },
@@ -50005,9 +50018,13 @@ Usage:
50005
50018
  tfa-cli device list
50006
50019
  tfa-cli device rename <device> <name> name: [a-zA-Z0-9][a-zA-Z0-9_]*, ≤64
50007
50020
  tfa-cli device wallpaper <device> auto|off desktop-wallpaper capture (off deletes stored images)
50021
+ tfa-cli device access <device> who you shared the device with
50022
+ tfa-cli device share <device> <email> let a teammate use it (their runs act as THEM)
50023
+ tfa-cli device unshare <device> <email>
50008
50024
 
50009
50025
  <device> is an id, name or hostname (unique partial works).
50010
- exec / reboot / update / unpair / workspace paths are UI-only from an agent shell.
50026
+ Devices shared with you are marked "shared"; only the owner can rename/share them.
50027
+ exec / reboot / update / unpair / workspace paths / share are UI-only from an agent shell.
50011
50028
  `);
50012
50029
  }
50013
50030
  async function deviceCommand(api, positionals, args) {
@@ -50018,9 +50035,11 @@ async function deviceCommand(api, positionals, args) {
50018
50035
  console.log(JSON.stringify(devices, null, 2));
50019
50036
  return;
50020
50037
  }
50021
- for (const d of devices)
50022
- process.stderr.write(`${d.status === "ONLINE" ? GREEN + "●" : DIM + "○"}${RESET} ${d.name} ${DIM}${d.deviceType} ${d.metadata?.identity?.hostname ?? ""} ${d.id}${RESET}
50038
+ for (const d of devices) {
50039
+ const sharing = !d.accessIds ? " shared with you" : d.accessIds.length ? ` shared ×${d.accessIds.length}` : "";
50040
+ process.stderr.write(`${d.status === "ONLINE" ? GREEN + "●" : DIM + "○"}${RESET} ${d.name} ${DIM}${d.deviceType} ${d.metadata?.identity?.hostname ?? ""} ${d.id}${sharing}${RESET}
50023
50041
  `);
50042
+ }
50024
50043
  return;
50025
50044
  }
50026
50045
  if (!query)
@@ -50038,6 +50057,22 @@ async function deviceCommand(api, positionals, args) {
50038
50057
  fail("Usage: tfa-cli device rename <device> <name>");
50039
50058
  await api.renameDevice(found.id, value);
50040
50059
  process.stderr.write(`${GREEN}✅ ${found.name} → ${value}${RESET}
50060
+ `);
50061
+ return;
50062
+ }
50063
+ if (sub === "access" || sub === "share" || sub === "unshare") {
50064
+ if (sub !== "access" && !value)
50065
+ fail(`Usage: tfa-cli device ${sub} <device> <email>`);
50066
+ const list = sub === "access" ? await api.getDeviceAccess(found.id) : sub === "share" ? await api.shareDevice(found.id, value) : await api.unshareDevice(found.id, value);
50067
+ if (args.json) {
50068
+ console.log(JSON.stringify(list, null, 2));
50069
+ return;
50070
+ }
50071
+ if (sub !== "access")
50072
+ process.stderr.write(`${GREEN}✅ ${found.name} ${sub === "share" ? "shared with" : "no longer shared with"} ${value}${RESET}
50073
+ `);
50074
+ process.stderr.write(list.length ? list.map((u) => ` ${u.email}${u.name ? ` ${DIM}(${u.name})${RESET}` : ""}
50075
+ `).join("") : ` ${DIM}not shared${RESET}
50041
50076
  `);
50042
50077
  return;
50043
50078
  }
@@ -75311,7 +75346,7 @@ async function main() {
75311
75346
  await deviceLogin();
75312
75347
  return;
75313
75348
  }
75314
- let apiKey = args["api-key"] || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
75349
+ let apiKey = args["api-key"] || runActorToken() || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
75315
75350
  if (!apiKey && positionals[0] !== "acp")
75316
75351
  apiKey = await deviceLogin();
75317
75352
  if (args["debug-dump"]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/cli",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-cli": "bin/todoforai-cli.js",