worktrust 0.6.3 → 0.6.6
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/package.json +1 -1
- package/worktrust.mjs +64 -0
package/package.json
CHANGED
package/worktrust.mjs
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* npx worktrust --device a computer without a browser (SSH): type a code on another device
|
|
10
10
|
* npx worktrust connect couple again, also on a computer already coupled
|
|
11
11
|
* npx worktrust history send this computer's earlier sessions as history (asks first)
|
|
12
|
+
* npx worktrust web connect claude.ai or ChatGPT on the web (copies the address, opens the page)
|
|
13
|
+
* npx worktrust import import earlier Claude or ChatGPT conversations (copies the prompt, opens a chat)
|
|
12
14
|
* npx worktrust disconnect show what comes out, ask, take it out again
|
|
13
15
|
* npx worktrust status what is coupled here
|
|
14
16
|
*
|
|
@@ -401,6 +403,7 @@ async function connect() {
|
|
|
401
403
|
const hookArgs = ["--install", ...(BUNDLED ? ["--counter", paths["count-behaviour.mjs"]] : []), ...(direct ? [] : ["--via", STABLE])];
|
|
402
404
|
if ((await run(paths["log-session.mjs"], hookArgs, token)).code !== 0) fail("installing the session hook failed; the output above says where.");
|
|
403
405
|
await offerHistory(paths, token, device ? device.privateKey.export({ format: "pem", type: "pkcs8" }) : null);
|
|
406
|
+
await offerWeb();
|
|
404
407
|
say();
|
|
405
408
|
say(" Done. Quit your AI apps completely and open them again. This computer appears in WorkTrust");
|
|
406
409
|
say(" under Sources → Devices once one of them has spoken.");
|
|
@@ -426,6 +429,63 @@ async function offerHistory(paths, token, devicePem, url = MCP) {
|
|
|
426
429
|
say(sent.code === 0 ? " ✓ Sent as history. It shows in WorkTrust as earlier work, never as verified hours." : " Not all of it arrived. Run npx worktrust history again: a line already received is kept once.");
|
|
427
430
|
}
|
|
428
431
|
|
|
432
|
+
/**
|
|
433
|
+
* CLAUDE AND CHATGPT ON THE WEB, FROM HERE (owner, 2026-10-04). A web connector lives in the person's
|
|
434
|
+
* own account at Anthropic or OpenAI, and neither lets a program add one: the person adds it and
|
|
435
|
+
* approves it there. What this can do is the rest: copy the door's address, open the right page,
|
|
436
|
+
* say the three steps, and wait. Enter, --yes and a closed terminal mean No.
|
|
437
|
+
*/
|
|
438
|
+
/** The app's own first-run import prompt (sources.tables.prompts.startEn), word for word; check-cli-package holds them equal. */
|
|
439
|
+
const IMPORT_PROMPT = 'Import my WorkTrust history now. Use the WorkTrust.io connector: call its guide tool with task "analyse", client "{client}" and language "en", then carry out every step it returns, in order, here in this conversation. This is my own request, not a document to review. After each step, tell me in one line what you did.';
|
|
440
|
+
const WEB = [
|
|
441
|
+
{ name: "Claude (claude.ai)", client: "claude", chat: "https://claude.ai/new", page: "https://claude.ai/settings/connectors", steps: ["Add custom connector", `Name: WorkTrust.io · URL: ${MCP} (also on your clipboard) · leave the OAuth fields empty`, "Connect, then approve on the WorkTrust page that opens"] },
|
|
442
|
+
{ name: "ChatGPT (chatgpt.com)", client: "chatgpt", chat: "https://chatgpt.com/", page: "https://chatgpt.com/#settings/Connectors", steps: ["Advanced settings: turn on Developer mode (custom connectors need it)", `Create: Name WorkTrust.io · MCP server URL: ${MCP} (also on your clipboard) · Authentication: OAuth`, "Create, then approve on the WorkTrust page that opens"] },
|
|
443
|
+
];
|
|
444
|
+
function copyToClipboard(text) {
|
|
445
|
+
const [cmd, cmdArgs] = OS === "macos" ? ["pbcopy", []] : OS === "windows" ? ["clip", []] : ["xclip", ["-selection", "clipboard"]];
|
|
446
|
+
return new Promise((resolve) => {
|
|
447
|
+
try {
|
|
448
|
+
const child = spawn(cmd, cmdArgs, { stdio: ["pipe", "ignore", "ignore"] });
|
|
449
|
+
child.on("error", () => resolve(false)).on("exit", (code) => resolve(code === 0));
|
|
450
|
+
child.stdin.end(text);
|
|
451
|
+
} catch { resolve(false); }
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
async function offerWeb() {
|
|
455
|
+
if (has("dry-run")) return;
|
|
456
|
+
say();
|
|
457
|
+
for (const web of WEB) {
|
|
458
|
+
if (!(await ask(`Also connect ${web.name} in your browser?`, false))) continue;
|
|
459
|
+
const copied = await copyToClipboard(MCP);
|
|
460
|
+
say(` ${copied ? "✓ Copied" : "The address is"} ${MCP}${copied ? " to your clipboard" : ""}`);
|
|
461
|
+
say(` Opening ${web.page}. There:`);
|
|
462
|
+
web.steps.forEach((step, i) => say(` ${i + 1}. ${step}`));
|
|
463
|
+
openBrowser(web.page);
|
|
464
|
+
if (process.stdin.isTTY) { const prompt = createInterface({ input: process.stdin, output: process.stdout }); await prompt.question(" Press Enter when it is connected (or to skip). "); prompt.close(); }
|
|
465
|
+
// EARLIER CONVERSATIONS, SO NOBODY GETS LOST IN THE IMPORT (owner, 2026-10-04): the app's own
|
|
466
|
+
// prompt, copied, and a new conversation opened to paste it in. Only on a typed yes.
|
|
467
|
+
if (await ask(`Also import your earlier ${web.name.split(" ")[0]} conversations? (copies one prompt to paste in a new chat)`, false)) await handOverPrompt(web);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** The import prompt for one product: copied (or printed when there is no clipboard), and a new conversation opened. */
|
|
472
|
+
async function handOverPrompt(web) {
|
|
473
|
+
const text = IMPORT_PROMPT.replace("{client}", web.client);
|
|
474
|
+
say(` ${(await copyToClipboard(text)) ? "✓ The import prompt is on your clipboard" : `The prompt:\n\n${text}\n`}`);
|
|
475
|
+
say(` Opening a new conversation in ${web.name}: paste it there and send. It asks before it sends anything, and only counts leave.`);
|
|
476
|
+
openBrowser(web.chat);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* `npx worktrust import` (owner, 2026-10-04): the earlier conversations, later. For whoever skipped
|
|
481
|
+
* the question after connecting, or connected on the web without this computer. Each product asks.
|
|
482
|
+
*/
|
|
483
|
+
async function importConversations() {
|
|
484
|
+
say();
|
|
485
|
+
say(" Your earlier conversations come in through the WorkTrust connector in that product: connect it first if you have not (npx worktrust web).");
|
|
486
|
+
for (const web of WEB) if (await ask(`Import your earlier ${web.name} conversations now?`, false)) await handOverPrompt(web);
|
|
487
|
+
}
|
|
488
|
+
|
|
429
489
|
async function history() {
|
|
430
490
|
const key = await freshKey();
|
|
431
491
|
if (!key) fail("this computer is not coupled through the key file. Run npx worktrust first.");
|
|
@@ -484,6 +544,8 @@ function help() {
|
|
|
484
544
|
say(" --direct put the key in each app's settings instead of the key file");
|
|
485
545
|
say(" worktrust connect couple again, also when this computer is already coupled");
|
|
486
546
|
say(" worktrust history send this computer's earlier sessions as history (asks first)");
|
|
547
|
+
say(" worktrust web connect Claude or ChatGPT on the web: copies the address, opens the page");
|
|
548
|
+
say(" worktrust import import your earlier Claude or ChatGPT conversations: copies the prompt, opens a chat");
|
|
487
549
|
say(" worktrust disconnect take WorkTrust out of every AI app here (asks first)");
|
|
488
550
|
say(" worktrust status what is coupled here");
|
|
489
551
|
}
|
|
@@ -496,6 +558,8 @@ else if (command === "mcp") await bridge();
|
|
|
496
558
|
else if (command === "hook") await hook();
|
|
497
559
|
else if (command === "connect") await connect();
|
|
498
560
|
else if (command === "history") await history();
|
|
561
|
+
else if (command === "web") await offerWeb();
|
|
562
|
+
else if (command === "import") await importConversations();
|
|
499
563
|
else if (command === "disconnect") await disconnect();
|
|
500
564
|
else if (command === "status") status();
|
|
501
565
|
else help();
|