@todoforai/cli 0.1.59 → 0.1.61
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 +47 -20
- package/package.json +1 -1
package/dist/todoforai-cli.js
CHANGED
|
@@ -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.
|
|
46138
|
+
version: "0.1.61",
|
|
46127
46139
|
type: "module",
|
|
46128
46140
|
bin: {
|
|
46129
46141
|
"todoforai-cli": "bin/todoforai-cli.js",
|
|
@@ -46302,7 +46314,6 @@ function parseCliArgs() {
|
|
|
46302
46314
|
link: { type: "boolean", default: false },
|
|
46303
46315
|
direction: { type: "string" },
|
|
46304
46316
|
url: { type: "string" },
|
|
46305
|
-
"pasted-file": { type: "string" },
|
|
46306
46317
|
account: { type: "string" },
|
|
46307
46318
|
"from-company": { type: "boolean", default: false },
|
|
46308
46319
|
"dry-run": { type: "boolean", default: false },
|
|
@@ -49487,7 +49498,7 @@ var ADAPTERS = { Gmail: gmail, Outlook: outlook, Chat: chat };
|
|
|
49487
49498
|
var DEVICE_CHANNELS = Object.keys(ADAPTERS);
|
|
49488
49499
|
function checkChannel(channel) {
|
|
49489
49500
|
const a = ADAPTERS[channel];
|
|
49490
|
-
return a ? a.check() : `${channel} is not read on the device (server-side: pass --url
|
|
49501
|
+
return a ? a.check() : `${channel} is not read on the device (server-side: pass --url)`;
|
|
49491
49502
|
}
|
|
49492
49503
|
function collectChannel(channel, max = 40) {
|
|
49493
49504
|
const a = ADAPTERS[channel];
|
|
@@ -49767,12 +49778,12 @@ Usage:
|
|
|
49767
49778
|
tfa-cli brand rename <name>
|
|
49768
49779
|
tfa-cli brand voice Learned profile + sources
|
|
49769
49780
|
tfa-cli brand voice answers [<q>=<a>…] Show / set the Manual source: answers to the style questions
|
|
49770
|
-
tfa-cli brand voice collect <channel> [--url U | --
|
|
49781
|
+
tfa-cli brand voice collect <channel> [--url U | --max N]
|
|
49771
49782
|
Add a writing sample source.
|
|
49772
49783
|
On this device (signed-in CLI, reply pairs):
|
|
49773
49784
|
Gmail (zele) Outlook (outlook-api) Chat (tfa-memory)
|
|
49774
|
-
Server-side (--url
|
|
49775
|
-
X LinkedIn Facebook Instagram
|
|
49785
|
+
Server-side (--url):
|
|
49786
|
+
X LinkedIn Facebook Instagram
|
|
49776
49787
|
--dry-run print the samples as JSONL, store nothing
|
|
49777
49788
|
tfa-cli brand voice check [<channel>|--all] Can this device read the channel? tool, login, sample count
|
|
49778
49789
|
tfa-cli brand voice remove <channel>
|
|
@@ -49780,7 +49791,6 @@ Usage:
|
|
|
49780
49791
|
tfa-cli brand voice correct "<what is off>" Tell the learner what it got wrong; profile is updated
|
|
49781
49792
|
in one pass and the correction is kept for every re-learn
|
|
49782
49793
|
|
|
49783
|
-
--pasted-file - reads stdin. Delete is UI-only.
|
|
49784
49794
|
|
|
49785
49795
|
Questions the UI asks (keys for 'answers'):
|
|
49786
49796
|
"What makes you different from competitors?"
|
|
@@ -49880,7 +49890,7 @@ async function voiceDeviceCommand(rest, args) {
|
|
|
49880
49890
|
async function voiceCommand(api, projectId, rest, args) {
|
|
49881
49891
|
const [verb, ...vargs] = rest;
|
|
49882
49892
|
if (verb === "collect" && !vargs[0])
|
|
49883
|
-
fail("Usage: tfa-cli brand voice collect <channel> [--url U | --
|
|
49893
|
+
fail("Usage: tfa-cli brand voice collect <channel> [--url U | --account <page-id> | --max N] [--dry-run]");
|
|
49884
49894
|
if (verb === "answers") {
|
|
49885
49895
|
const answers = manualAnswersOf((await api.listVoiceSources(projectId)).sources);
|
|
49886
49896
|
if (vargs.length) {
|
|
@@ -49926,12 +49936,7 @@ ${DIM}match ${profile.match}/100 · source ${profile.source}${RESET}
|
|
|
49926
49936
|
}
|
|
49927
49937
|
if (verb === "collect") {
|
|
49928
49938
|
const channel = vargs[0];
|
|
49929
|
-
|
|
49930
|
-
if (args["pasted-file"]) {
|
|
49931
|
-
const { readFileSync: readFileSync3 } = await import("node:fs");
|
|
49932
|
-
pasted = readFileSync3(args["pasted-file"] === "-" ? 0 : args["pasted-file"], "utf8");
|
|
49933
|
-
}
|
|
49934
|
-
const onDevice = !pasted && !args.url && ADAPTERS[channel];
|
|
49939
|
+
const onDevice = !args.url && ADAPTERS[channel];
|
|
49935
49940
|
if (onDevice) {
|
|
49936
49941
|
const reason = checkChannel(channel);
|
|
49937
49942
|
if (reason)
|
|
@@ -49946,7 +49951,7 @@ ${DIM}match ${profile.match}/100 · source ${profile.source}${RESET}
|
|
|
49946
49951
|
`);
|
|
49947
49952
|
return;
|
|
49948
49953
|
}
|
|
49949
|
-
const { sources } = await api.collectVoiceSource(projectId, channel, { url: args.url,
|
|
49954
|
+
const { sources } = await api.collectVoiceSource(projectId, channel, { url: args.url, account: args.account });
|
|
49950
49955
|
process.stderr.write(`${GREEN}✅ ${channel} collected (${sources.length} source(s))${RESET}
|
|
49951
49956
|
`);
|
|
49952
49957
|
return;
|
|
@@ -50006,9 +50011,13 @@ Usage:
|
|
|
50006
50011
|
tfa-cli device list
|
|
50007
50012
|
tfa-cli device rename <device> <name> name: [a-zA-Z0-9][a-zA-Z0-9_]*, ≤64
|
|
50008
50013
|
tfa-cli device wallpaper <device> auto|off desktop-wallpaper capture (off deletes stored images)
|
|
50014
|
+
tfa-cli device access <device> who you shared the device with
|
|
50015
|
+
tfa-cli device share <device> <email> let a teammate use it (their runs act as THEM)
|
|
50016
|
+
tfa-cli device unshare <device> <email>
|
|
50009
50017
|
|
|
50010
50018
|
<device> is an id, name or hostname (unique partial works).
|
|
50011
|
-
|
|
50019
|
+
Devices shared with you are marked "shared"; only the owner can rename/share them.
|
|
50020
|
+
exec / reboot / update / unpair / workspace paths / share are UI-only from an agent shell.
|
|
50012
50021
|
`);
|
|
50013
50022
|
}
|
|
50014
50023
|
async function deviceCommand(api, positionals, args) {
|
|
@@ -50019,9 +50028,11 @@ async function deviceCommand(api, positionals, args) {
|
|
|
50019
50028
|
console.log(JSON.stringify(devices, null, 2));
|
|
50020
50029
|
return;
|
|
50021
50030
|
}
|
|
50022
|
-
for (const d of devices)
|
|
50023
|
-
|
|
50031
|
+
for (const d of devices) {
|
|
50032
|
+
const sharing = !d.accessIds ? " shared with you" : d.accessIds.length ? ` shared ×${d.accessIds.length}` : "";
|
|
50033
|
+
process.stderr.write(`${d.status === "ONLINE" ? GREEN + "●" : DIM + "○"}${RESET} ${d.name} ${DIM}${d.deviceType} ${d.metadata?.identity?.hostname ?? ""} ${d.id}${sharing}${RESET}
|
|
50024
50034
|
`);
|
|
50035
|
+
}
|
|
50025
50036
|
return;
|
|
50026
50037
|
}
|
|
50027
50038
|
if (!query)
|
|
@@ -50039,6 +50050,22 @@ async function deviceCommand(api, positionals, args) {
|
|
|
50039
50050
|
fail("Usage: tfa-cli device rename <device> <name>");
|
|
50040
50051
|
await api.renameDevice(found.id, value);
|
|
50041
50052
|
process.stderr.write(`${GREEN}✅ ${found.name} → ${value}${RESET}
|
|
50053
|
+
`);
|
|
50054
|
+
return;
|
|
50055
|
+
}
|
|
50056
|
+
if (sub === "access" || sub === "share" || sub === "unshare") {
|
|
50057
|
+
if (sub !== "access" && !value)
|
|
50058
|
+
fail(`Usage: tfa-cli device ${sub} <device> <email>`);
|
|
50059
|
+
const list = sub === "access" ? await api.getDeviceAccess(found.id) : sub === "share" ? await api.shareDevice(found.id, value) : await api.unshareDevice(found.id, value);
|
|
50060
|
+
if (args.json) {
|
|
50061
|
+
console.log(JSON.stringify(list, null, 2));
|
|
50062
|
+
return;
|
|
50063
|
+
}
|
|
50064
|
+
if (sub !== "access")
|
|
50065
|
+
process.stderr.write(`${GREEN}✅ ${found.name} ${sub === "share" ? "shared with" : "no longer shared with"} ${value}${RESET}
|
|
50066
|
+
`);
|
|
50067
|
+
process.stderr.write(list.length ? list.map((u) => ` ${u.email}${u.name ? ` ${DIM}(${u.name})${RESET}` : ""}
|
|
50068
|
+
`).join("") : ` ${DIM}not shared${RESET}
|
|
50042
50069
|
`);
|
|
50043
50070
|
return;
|
|
50044
50071
|
}
|
|
@@ -75312,7 +75339,7 @@ async function main() {
|
|
|
75312
75339
|
await deviceLogin();
|
|
75313
75340
|
return;
|
|
75314
75341
|
}
|
|
75315
|
-
let apiKey = args["api-key"] || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
|
|
75342
|
+
let apiKey = args["api-key"] || runActorToken() || readCredential(apiUrl) || getEnv("API_TOKEN") || "";
|
|
75316
75343
|
if (!apiKey && positionals[0] !== "acp")
|
|
75317
75344
|
apiKey = await deviceLogin();
|
|
75318
75345
|
if (args["debug-dump"]) {
|