ccdeck 3.29.11 → 3.31.0

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 (178) hide show
  1. package/README.md +4 -3
  2. package/bin/agent-dag.js +67 -118
  3. package/bin/cli/help.js +67 -0
  4. package/bin/cli/login-item.js +182 -0
  5. package/bin/cli/one-shot.js +254 -0
  6. package/bin/cli/package.js +39 -0
  7. package/bin/cli/pulse.js +98 -0
  8. package/bin/cli/restart.js +179 -0
  9. package/bin/cli/screen.js +166 -0
  10. package/bin/cli/second-start.js +120 -0
  11. package/bin/cli/startup.js +459 -0
  12. package/bin/cli/uninstall.js +169 -0
  13. package/bin/deck.js +112 -1559
  14. package/dist/web/assets/BrowserWatchModal-n63GjLhv.js +1 -0
  15. package/dist/web/assets/UsageHistoryModal-DEwBX4Fk.js +1 -0
  16. package/dist/web/assets/index-CZJf1Cpp.js +299 -0
  17. package/dist/web/assets/index-D4q1ElXU.css +1 -0
  18. package/dist/web/index.html +2 -2
  19. package/hook/hook.js +15 -14
  20. package/package.json +1 -1
  21. package/release-notes.json +40 -0
  22. package/src/server/account-projects.mjs +25 -11
  23. package/src/server/account-routes.mjs +254 -0
  24. package/src/server/activity.mjs +3 -3
  25. package/src/server/append-budget.mjs +185 -0
  26. package/src/server/append-failures.mjs +147 -0
  27. package/src/server/args.mjs +37 -5
  28. package/src/server/atomic-write.mjs +300 -0
  29. package/src/server/block-notify.mjs +0 -5
  30. package/src/server/boot-lock.mjs +1 -1
  31. package/src/server/brand.mjs +7 -6
  32. package/src/server/browser-react.mjs +10 -2
  33. package/src/server/browser-watch-decks.mjs +146 -0
  34. package/src/server/browser-watch-feed.mjs +69 -0
  35. package/src/server/browser-watch-log.mjs +173 -0
  36. package/src/server/browser-watch-mtime.mjs +18 -0
  37. package/src/server/browser-watch-relay.mjs +112 -0
  38. package/src/server/browser-watch-routes.mjs +172 -0
  39. package/src/server/browser-watch-seen.mjs +127 -0
  40. package/src/server/browser-watch-store.mjs +14 -143
  41. package/src/server/browser-watch.mjs +278 -626
  42. package/src/server/canonical-path.mjs +150 -0
  43. package/src/server/ccusage-failure.mjs +64 -0
  44. package/src/server/ccusage-install.mjs +459 -0
  45. package/src/server/ccusage-runner.mjs +271 -0
  46. package/src/server/ccusage.mjs +21 -756
  47. package/src/server/claude-accounts.mjs +220 -464
  48. package/src/server/claude-collector.mjs +189 -0
  49. package/src/server/claude-dir.mjs +7 -3
  50. package/src/server/claude-identity.mjs +5 -4
  51. package/src/server/claude-reset-credits.mjs +130 -0
  52. package/src/server/claude-verdicts.mjs +174 -0
  53. package/src/server/clear-route.mjs +191 -0
  54. package/src/server/codex-auth.mjs +4 -4
  55. package/src/server/codex-dir.mjs +52 -8
  56. package/src/server/codex-enrichment.mjs +310 -0
  57. package/src/server/codex-quota.mjs +5 -3
  58. package/src/server/codex-translate.mjs +407 -0
  59. package/src/server/codex-usage.mjs +8 -5
  60. package/src/server/codex-watch.mjs +496 -0
  61. package/src/server/cswap-auto-loop.mjs +342 -0
  62. package/src/server/cswap-auto-readers.mjs +303 -0
  63. package/src/server/cswap-auto.mjs +51 -609
  64. package/src/server/cswap-install.mjs +69 -265
  65. package/src/server/cswap-layout.mjs +242 -0
  66. package/src/server/deck-home.mjs +2 -2
  67. package/src/server/deck-prefs.mjs +58 -184
  68. package/src/server/deck-scope.mjs +52 -0
  69. package/src/server/desktop-update-routes.mjs +75 -0
  70. package/src/server/detach.mjs +78 -0
  71. package/src/server/discovery.mjs +298 -0
  72. package/src/server/event-log.mjs +328 -0
  73. package/src/server/event-pipeline.mjs +235 -0
  74. package/src/server/event-ring.mjs +214 -0
  75. package/src/server/event-routes.mjs +352 -0
  76. package/src/server/event-sink.mjs +26 -0
  77. package/src/server/exec-children.mjs +128 -0
  78. package/src/server/exec-not-found.mjs +213 -0
  79. package/src/server/exec-output.mjs +23 -0
  80. package/src/server/exec-spec.mjs +341 -0
  81. package/src/server/exec.mjs +74 -661
  82. package/src/server/health-route.mjs +42 -0
  83. package/src/server/hook-challenge.mjs +37 -0
  84. package/src/server/http-io.mjs +104 -0
  85. package/src/server/index.mjs +174 -7620
  86. package/src/server/install-layout.mjs +506 -0
  87. package/src/server/installer.mjs +79 -608
  88. package/src/server/jsonl-chunks.mjs +139 -0
  89. package/src/server/lan-accounts.mjs +27 -0
  90. package/src/server/lan-beacon.mjs +457 -0
  91. package/src/server/lan-call.mjs +239 -0
  92. package/src/server/lan-copies.mjs +270 -0
  93. package/src/server/lan-deck.mjs +583 -0
  94. package/src/server/lan-dials.mjs +161 -0
  95. package/src/server/lan-engine.mjs +475 -1024
  96. package/src/server/lan-hearing.mjs +49 -0
  97. package/src/server/lan-inbound.mjs +100 -0
  98. package/src/server/lan-invite-offer.mjs +77 -0
  99. package/src/server/lan-invite.mjs +207 -0
  100. package/src/server/lan-lines.mjs +73 -0
  101. package/src/server/lan-manifest.mjs +74 -0
  102. package/src/server/lan-reach.mjs +82 -69
  103. package/src/server/lan-requests.mjs +249 -0
  104. package/src/server/lan-round-record.mjs +45 -0
  105. package/src/server/lan-round-timer.mjs +62 -0
  106. package/src/server/lan-routes.mjs +143 -0
  107. package/src/server/lan-serve.mjs +112 -0
  108. package/src/server/lan-socket.mjs +243 -925
  109. package/src/server/lan-sync.mjs +58 -1026
  110. package/src/server/lan-tailnet-poll.mjs +57 -0
  111. package/src/server/lan-turns.mjs +80 -0
  112. package/src/server/lan-wire.mjs +620 -0
  113. package/src/server/lifecycle.mjs +421 -0
  114. package/src/server/listen.mjs +110 -0
  115. package/src/server/live-decks.mjs +138 -0
  116. package/src/server/load-average.mjs +32 -0
  117. package/src/server/log-election.mjs +235 -0
  118. package/src/server/log-replay.mjs +374 -0
  119. package/src/server/log-writer.mjs +72 -557
  120. package/src/server/login-service.mjs +3 -2
  121. package/src/server/macmon.mjs +1 -1
  122. package/src/server/memory-files.mjs +163 -0
  123. package/src/server/memory-metrics.mjs +178 -0
  124. package/src/server/metrics-history.mjs +94 -0
  125. package/src/server/metrics-run.mjs +100 -0
  126. package/src/server/music-routes.mjs +134 -0
  127. package/src/server/network-metrics.mjs +5 -3
  128. package/src/server/network-sampler.mjs +256 -0
  129. package/src/server/npm-latest.mjs +385 -0
  130. package/src/server/npm-upgrade.mjs +352 -0
  131. package/src/server/npx.mjs +41 -7
  132. package/src/server/output-watch.mjs +5 -4
  133. package/src/server/pinned-build.mjs +110 -0
  134. package/src/server/prefs-give-back.mjs +206 -0
  135. package/src/server/prefs-path.mjs +14 -0
  136. package/src/server/prefs-refusal.mjs +86 -0
  137. package/src/server/prefs-routes.mjs +99 -0
  138. package/src/server/prefs-set-aside.mjs +86 -0
  139. package/src/server/prefs-state.mjs +70 -0
  140. package/src/server/process-command.mjs +104 -0
  141. package/src/server/process-list.mjs +547 -0
  142. package/src/server/provider-status.mjs +307 -0
  143. package/src/server/pulse-line.mjs +132 -0
  144. package/src/server/purge-key.mjs +7 -7
  145. package/src/server/quota-cli.mjs +174 -0
  146. package/src/server/quota-oauth.mjs +190 -0
  147. package/src/server/quota-shape.mjs +229 -0
  148. package/src/server/quota-store-resets.mjs +206 -0
  149. package/src/server/quota.mjs +123 -509
  150. package/src/server/relay-guard.mjs +3 -3
  151. package/src/server/request-gates.mjs +441 -0
  152. package/src/server/restart-note.mjs +180 -0
  153. package/src/server/retire-sound-hook.mjs +3 -3
  154. package/src/server/ring-bounds.mjs +215 -0
  155. package/src/server/running-deck.mjs +1 -1
  156. package/src/server/running-version.mjs +24 -0
  157. package/src/server/self-update.mjs +39 -1371
  158. package/src/server/session-enrichment.mjs +622 -0
  159. package/src/server/session-read-gate.mjs +49 -0
  160. package/src/server/session-tracking.mjs +242 -0
  161. package/src/server/sse-clients.mjs +222 -0
  162. package/src/server/stale-discovery.mjs +30 -0
  163. package/src/server/static-serve.mjs +81 -0
  164. package/src/server/supervisor.mjs +73 -12
  165. package/src/server/system-metrics.mjs +169 -1935
  166. package/src/server/term.mjs +11 -249
  167. package/src/server/thermal-metrics.mjs +520 -0
  168. package/src/server/thermal-sampler.mjs +204 -0
  169. package/src/server/token-redact.mjs +123 -0
  170. package/src/server/transcript-gate.mjs +107 -0
  171. package/src/server/transcript-scan.mjs +563 -0
  172. package/src/server/usage-routes.mjs +108 -0
  173. package/src/server/uv-bootstrap.mjs +1 -1
  174. package/src/server/wordmark.mjs +127 -0
  175. package/dist/web/assets/BrowserWatchModal-CyAFTvAY.js +0 -1
  176. package/dist/web/assets/UsageHistoryModal-KJfli0oa.js +0 -1
  177. package/dist/web/assets/index-Ck2RAla3.css +0 -1
  178. package/dist/web/assets/index-jmrcEsCj.js +0 -298
@@ -0,0 +1,57 @@
1
+ // Reading the tailnet on a timer while discovery over it is switched on, lifted
2
+ // out of createEngine in lan-engine.mjs with the two variables only it used.
3
+ // The reader itself — spawning the CLI, keeping its last answer — is
4
+ // createTailnet in tailscale.mjs; this is only WHEN the engine asks it.
5
+ import { TAILNET_MS } from "./tailscale.mjs";
6
+
7
+ /**
8
+ * `tailnet` is the engine's reader, or null on a deck that has none.
9
+ * `beaconNow` answers the engine's beacon as it is at the moment of asking —
10
+ * null while it is down, and a different one after a restart — and `wanted`
11
+ * whether the settings in force ask for the tailnet at all.
12
+ */
13
+ export function createTailnetPoll({ tailnet, beaconNow, wanted }) {
14
+ /** The tailnet read's own timer, running only while the switch is on. */
15
+ let tailTimer = null;
16
+ // An in-flight refresh may finish after discovery is disabled or restarted.
17
+ let tailRefreshGeneration = 0;
18
+
19
+ /**
20
+ * Read the tailnet on a timer while the switch is on, and not at all while it
21
+ * is off — the read at start covers telling a tailnet address from a local
22
+ * one, and the dialog's own poll covers whether Tailscale is there at all.
23
+ *
24
+ * TURNING IT ON ANNOUNCES AT ONCE, after one read, so the owner's machines
25
+ * hear about this one in the second after the press rather than on the next
26
+ * beacon, up to half a minute later.
27
+ */
28
+ const sync = () => {
29
+ const beacon = beaconNow();
30
+ const want = !!(beacon && tailnet && wanted());
31
+ if (want && !tailTimer) {
32
+ const startedIn = ++tailRefreshGeneration;
33
+ const currentBeacon = beacon;
34
+ void tailnet.refresh().then(() => {
35
+ if (startedIn === tailRefreshGeneration && beaconNow() === currentBeacon && wanted()) {
36
+ currentBeacon.announce();
37
+ }
38
+ }, () => {});
39
+ tailTimer = setInterval(() => { void tailnet.refresh(); }, TAILNET_MS);
40
+ tailTimer.unref?.();
41
+ } else if (!want && tailTimer) {
42
+ tailRefreshGeneration++;
43
+ clearInterval(tailTimer);
44
+ tailTimer = null;
45
+ }
46
+ };
47
+
48
+ /** Stop reading, and make a read still in flight announce nothing when it
49
+ * lands: the listener it would announce is gone. */
50
+ const stop = () => {
51
+ tailRefreshGeneration++;
52
+ if (tailTimer) clearInterval(tailTimer);
53
+ tailTimer = null;
54
+ };
55
+
56
+ return { sync, stop };
57
+ }
@@ -0,0 +1,80 @@
1
+ // The one line every sync round waits in, lifted out of createEngine in
2
+ // lan-engine.mjs so the rule it keeps — whichever round is running is running
3
+ // alone — can be read, and tested, without a network. Nothing here knows what
4
+ // a round does: the engine hands it the job and the session it was asked in.
5
+
6
+ /**
7
+ * Where every round waits its turn — the whole list, or one deck from its own
8
+ * dialog — so that whichever is running is running alone. `round` and
9
+ * `roundOne` are the only two ways in, and both come through here.
10
+ *
11
+ * A LINE RATHER THAN A FLAG, because the two ways in want different things
12
+ * from what is already running and both have to end up behind it. A round
13
+ * asked for during a check cannot join it — a check asks one deck, and a
14
+ * round was asked to ask all of them — so it waits. A check asked for during
15
+ * a round can often join it, and sometimes cannot. Both need somewhere to
16
+ * stand that is after whatever is in flight, and this is it.
17
+ *
18
+ * The tail never rejects: `roundWith` reports a failure per peer instead of
19
+ * throwing, and anything else is swallowed here rather than left to stop
20
+ * every turn after it. The caller of the turn that threw still hears it.
21
+ */
22
+ export function createTurns() {
23
+ let _turn = Promise.resolve();
24
+ const inTurn = job => {
25
+ const run = _turn.then(job);
26
+ _turn = run.then(() => {}, () => {});
27
+ return run;
28
+ };
29
+
30
+ /** The whole round in flight or waiting its turn, or null. See `round` below. */
31
+ let _round = null;
32
+ /** The session `_round` was asked for in. */
33
+ let _roundIn = -1;
34
+
35
+ /**
36
+ * One round at a time, and the one already running is the answer (#1040).
37
+ *
38
+ * The sequential loop in the engine's oneRound reasons about peers being
39
+ * dialled one after another, which is a statement about the WHOLE round and
40
+ * was only ever true of a round running alone. Two ways in, and they meet: a
41
+ * self-scheduling timer (SYNC_MS, or ASKING_MS while somebody is waiting) and
42
+ * the "Sync now" press, which calls this straight from the route. A press
43
+ * landing on the timer's round gave two rounds walking the same peer list,
44
+ * each reading the same slot as empty and each force-importing a credential
45
+ * over the other — and the second one's blob wins for no reason anybody
46
+ * chose.
47
+ *
48
+ * JOINING rather than skipping, because the press has a reply to send: a
49
+ * caller that got `[]` for "a round is already running" would report "nothing
50
+ * to sync" about a round that was at that moment moving a credential. This is
51
+ * the shape `codexScanOnce` and ccusage's `_inflight` already use.
52
+ *
53
+ * THERE WAS A THIRD WAY IN, and it did not come through here (#1132). The
54
+ * `check now` in a deck's own dialog reaches `roundOne`, which called
55
+ * `roundWith` straight — so a press landing on the timer's round dialled the
56
+ * deck that round was already healing from, and the far side exported the
57
+ * same login twice for one account that needed repairing once. Both now take
58
+ * their turn in one line, above. A round joins only another whole round,
59
+ * never a check: joining a check would answer "ask every deck" with one
60
+ * deck's work and leave the rest waiting another minute.
61
+ *
62
+ * NEVER A ROUND FROM A SESSION THAT ENDED. LAN switched off and on again
63
+ * while one ran: that round stops at its next peer and reports nothing, so
64
+ * joining it would answer the new session's first tick with nothing and
65
+ * leave every deck unasked for a whole SYNC_MS. The new one queues behind it.
66
+ */
67
+ const round = (session, oneRound) => {
68
+ if (_round && _roundIn === session) return _round;
69
+ _roundIn = session;
70
+ const mine = inTurn(oneRound).finally(() => { if (_round === mine) _round = null; });
71
+ _round = mine;
72
+ return mine;
73
+ };
74
+
75
+ /** Everything already in the line, settled — what a check waits behind
76
+ * before it decides whether it still has to ask. Never rejects. */
77
+ const ahead = () => _turn;
78
+
79
+ return { inTurn, round, ahead };
80
+ }