worktrust 0.6.3 → 0.6.4

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/worktrust.mjs +38 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worktrust",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Couple this computer to WorkTrust: approve a code in your browser, and every AI app here reports what you built. Metadata only, no dependencies.",
5
5
  "type": "module",
6
6
  "bin": {
package/worktrust.mjs CHANGED
@@ -9,6 +9,7 @@
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)
12
13
  * npx worktrust disconnect show what comes out, ask, take it out again
13
14
  * npx worktrust status what is coupled here
14
15
  *
@@ -401,6 +402,7 @@ async function connect() {
401
402
  const hookArgs = ["--install", ...(BUNDLED ? ["--counter", paths["count-behaviour.mjs"]] : []), ...(direct ? [] : ["--via", STABLE])];
402
403
  if ((await run(paths["log-session.mjs"], hookArgs, token)).code !== 0) fail("installing the session hook failed; the output above says where.");
403
404
  await offerHistory(paths, token, device ? device.privateKey.export({ format: "pem", type: "pkcs8" }) : null);
405
+ await offerWeb();
404
406
  say();
405
407
  say(" Done. Quit your AI apps completely and open them again. This computer appears in WorkTrust");
406
408
  say(" under Sources → Devices once one of them has spoken.");
@@ -426,6 +428,40 @@ async function offerHistory(paths, token, devicePem, url = MCP) {
426
428
  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
429
  }
428
430
 
431
+ /**
432
+ * CLAUDE AND CHATGPT ON THE WEB, FROM HERE (owner, 2026-10-04). A web connector lives in the person's
433
+ * own account at Anthropic or OpenAI, and neither lets a program add one: the person adds it and
434
+ * approves it there. What this can do is the rest: copy the door's address, open the right page,
435
+ * say the three steps, and wait. Enter, --yes and a closed terminal mean No.
436
+ */
437
+ const WEB = [
438
+ { name: "Claude (claude.ai)", page: "https://claude.ai/settings/connectors", steps: ["Add custom connector", "Name: WorkTrust.io · URL: paste (it is on your clipboard) · leave the OAuth fields empty", "Connect, then approve on the WorkTrust page that opens"] },
439
+ { name: "ChatGPT (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: paste (it is on your clipboard) · Authentication: OAuth", "Create, then approve on the WorkTrust page that opens"] },
440
+ ];
441
+ function copyToClipboard(text) {
442
+ const [cmd, cmdArgs] = OS === "macos" ? ["pbcopy", []] : OS === "windows" ? ["clip", []] : ["xclip", ["-selection", "clipboard"]];
443
+ return new Promise((resolve) => {
444
+ try {
445
+ const child = spawn(cmd, cmdArgs, { stdio: ["pipe", "ignore", "ignore"] });
446
+ child.on("error", () => resolve(false)).on("exit", (code) => resolve(code === 0));
447
+ child.stdin.end(text);
448
+ } catch { resolve(false); }
449
+ });
450
+ }
451
+ async function offerWeb() {
452
+ if (has("dry-run")) return;
453
+ say();
454
+ for (const web of WEB) {
455
+ if (!(await ask(`Also connect ${web.name} in your browser?`, false))) continue;
456
+ const copied = await copyToClipboard(MCP);
457
+ say(` ${copied ? "✓ Copied" : "The address is"} ${MCP}${copied ? " to your clipboard" : ""}`);
458
+ say(` Opening ${web.page}. There:`);
459
+ web.steps.forEach((step, i) => say(` ${i + 1}. ${step}`));
460
+ openBrowser(web.page);
461
+ 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(); }
462
+ }
463
+ }
464
+
429
465
  async function history() {
430
466
  const key = await freshKey();
431
467
  if (!key) fail("this computer is not coupled through the key file. Run npx worktrust first.");
@@ -484,6 +520,7 @@ function help() {
484
520
  say(" --direct put the key in each app's settings instead of the key file");
485
521
  say(" worktrust connect couple again, also when this computer is already coupled");
486
522
  say(" worktrust history send this computer's earlier sessions as history (asks first)");
523
+ say(" worktrust web connect Claude or ChatGPT on the web: copies the address, opens the page");
487
524
  say(" worktrust disconnect take WorkTrust out of every AI app here (asks first)");
488
525
  say(" worktrust status what is coupled here");
489
526
  }
@@ -496,6 +533,7 @@ else if (command === "mcp") await bridge();
496
533
  else if (command === "hook") await hook();
497
534
  else if (command === "connect") await connect();
498
535
  else if (command === "history") await history();
536
+ else if (command === "web") await offerWeb();
499
537
  else if (command === "disconnect") await disconnect();
500
538
  else if (command === "status") status();
501
539
  else help();