@phnx-labs/agents-cli 1.22.47 → 1.22.49

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 (249) hide show
  1. package/CHANGELOG.md +401 -17
  2. package/README.md +66 -32
  3. package/dist/bootstrap.js +4 -2
  4. package/dist/cli/command-registry.d.ts +1 -0
  5. package/dist/cli/command-registry.js +2 -0
  6. package/dist/commands/accounts.d.ts +58 -0
  7. package/dist/commands/accounts.js +206 -32
  8. package/dist/commands/artifacts.js +7 -6
  9. package/dist/commands/attach.js +1 -1
  10. package/dist/commands/browser.js +501 -103
  11. package/dist/commands/config.d.ts +0 -1
  12. package/dist/commands/config.js +0 -20
  13. package/dist/commands/daemon.d.ts +21 -0
  14. package/dist/commands/daemon.js +147 -12
  15. package/dist/commands/exec.js +52 -15
  16. package/dist/commands/focus.d.ts +14 -0
  17. package/dist/commands/focus.js +48 -5
  18. package/dist/commands/go.d.ts +3 -0
  19. package/dist/commands/go.js +16 -3
  20. package/dist/commands/inspect.js +2 -2
  21. package/dist/commands/lease.d.ts +1 -1
  22. package/dist/commands/lease.js +4 -3
  23. package/dist/commands/mailboxes.js +4 -3
  24. package/dist/commands/menubar.js +11 -4
  25. package/dist/commands/projects.d.ts +16 -1
  26. package/dist/commands/projects.js +58 -64
  27. package/dist/commands/resume.js +1 -1
  28. package/dist/commands/route.js +4 -4
  29. package/dist/commands/routines.js +3 -2
  30. package/dist/commands/run-broadcast.d.ts +1 -1
  31. package/dist/commands/run-broadcast.js +1 -1
  32. package/dist/commands/sessions-picker.d.ts +22 -0
  33. package/dist/commands/sessions-picker.js +48 -9
  34. package/dist/commands/sessions-trace.js +1 -1
  35. package/dist/commands/sessions.js +1 -0
  36. package/dist/commands/setup-secrets.js +23 -0
  37. package/dist/commands/share.d.ts +20 -5
  38. package/dist/commands/share.js +152 -52
  39. package/dist/commands/ssh.js +54 -7
  40. package/dist/commands/traces.d.ts +2 -0
  41. package/dist/commands/traces.js +184 -0
  42. package/dist/commands/view.d.ts +1 -1
  43. package/dist/commands/view.js +17 -34
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +5 -0
  46. package/dist/lib/accounting/usage.d.ts +14 -3
  47. package/dist/lib/accounting/usage.js +64 -18
  48. package/dist/lib/agent-spec/agents.js +11 -9
  49. package/dist/lib/browser/drivers/ssh.d.ts +16 -2
  50. package/dist/lib/browser/drivers/ssh.js +36 -9
  51. package/dist/lib/browser/ipc.js +8 -3
  52. package/dist/lib/browser/profiles.d.ts +35 -101
  53. package/dist/lib/browser/profiles.js +130 -301
  54. package/dist/lib/browser/registry.d.ts +39 -0
  55. package/dist/lib/browser/registry.js +149 -0
  56. package/dist/lib/browser/remote-control.d.ts +8 -6
  57. package/dist/lib/browser/remote-control.js +8 -6
  58. package/dist/lib/browser/resolve-target.d.ts +68 -0
  59. package/dist/lib/browser/resolve-target.js +250 -0
  60. package/dist/lib/browser/runtime-state.d.ts +40 -16
  61. package/dist/lib/browser/runtime-state.js +92 -25
  62. package/dist/lib/browser/service.d.ts +28 -9
  63. package/dist/lib/browser/service.js +139 -62
  64. package/dist/lib/browser/task-index.d.ts +70 -0
  65. package/dist/lib/browser/task-index.js +180 -0
  66. package/dist/lib/byok-usage.js +2 -2
  67. package/dist/lib/claude-statusline.d.ts +29 -0
  68. package/dist/lib/claude-statusline.js +139 -0
  69. package/dist/lib/cloud/host.d.ts +1 -1
  70. package/dist/lib/cloud/host.js +1 -1
  71. package/dist/lib/cloud/rush.js +1 -1
  72. package/dist/lib/computer/computer-rpc.js +2 -2
  73. package/dist/lib/computer/download.d.ts +15 -15
  74. package/dist/lib/computer/download.js +35 -98
  75. package/dist/lib/computer/ssh-tunnel.d.ts +0 -3
  76. package/dist/lib/computer/ssh-tunnel.js +12 -22
  77. package/dist/lib/config-keys.d.ts +2 -8
  78. package/dist/lib/config-keys.js +2 -13
  79. package/dist/lib/crabbox/cli.d.ts +1 -1
  80. package/dist/lib/crabbox/cli.js +2 -2
  81. package/dist/lib/crabbox/lease.d.ts +9 -0
  82. package/dist/lib/crabbox/lease.js +70 -15
  83. package/dist/lib/crabbox/runtimes.js +1 -1
  84. package/dist/lib/daemon/account-state-daemon-service.d.ts +16 -0
  85. package/dist/lib/daemon/account-state-daemon-service.js +26 -0
  86. package/dist/lib/daemon/browser-ipc-service.d.ts +20 -0
  87. package/dist/lib/daemon/browser-ipc-service.js +46 -0
  88. package/dist/lib/daemon/daemon.d.ts +3 -0
  89. package/dist/lib/daemon/daemon.js +212 -444
  90. package/dist/lib/daemon/device-probe-service.d.ts +26 -0
  91. package/dist/lib/daemon/device-probe-service.js +47 -0
  92. package/dist/lib/daemon/keychain-reap-service.d.ts +17 -0
  93. package/dist/lib/daemon/keychain-reap-service.js +32 -0
  94. package/dist/lib/daemon/monitor-engine-service.d.ts +22 -0
  95. package/dist/lib/daemon/monitor-engine-service.js +29 -0
  96. package/dist/lib/daemon/secrets-broker-service.d.ts +20 -0
  97. package/dist/lib/daemon/secrets-broker-service.js +66 -0
  98. package/dist/lib/daemon/self-heal-service.d.ts +27 -0
  99. package/dist/lib/daemon/self-heal-service.js +48 -0
  100. package/dist/lib/daemon/service.d.ts +102 -0
  101. package/dist/lib/daemon/service.js +98 -0
  102. package/dist/lib/daemon/session-index-service.d.ts +22 -0
  103. package/dist/lib/daemon/session-index-service.js +40 -0
  104. package/dist/lib/daemon/state-dir-check-service.d.ts +43 -0
  105. package/dist/lib/daemon/state-dir-check-service.js +63 -0
  106. package/dist/lib/daemon/supervisor.d.ts +87 -0
  107. package/dist/lib/daemon/supervisor.js +298 -0
  108. package/dist/lib/daemon/watchdog-service.d.ts +19 -0
  109. package/dist/lib/daemon/watchdog-service.js +40 -0
  110. package/dist/lib/daemon-health.d.ts +15 -0
  111. package/dist/lib/daemon-health.js +29 -5
  112. package/dist/lib/daemon-services.d.ts +8 -1
  113. package/dist/lib/daemon-services.js +55 -0
  114. package/dist/lib/daemon-ticks.d.ts +13 -2
  115. package/dist/lib/daemon-ticks.js +20 -18
  116. package/dist/lib/device-config.d.ts +0 -2
  117. package/dist/lib/device-config.js +1 -23
  118. package/dist/lib/devices/registry.d.ts +1 -1
  119. package/dist/lib/devices/registry.js +1 -1
  120. package/dist/lib/devices/stats-cache.d.ts +20 -0
  121. package/dist/lib/devices/stats-cache.js +49 -5
  122. package/dist/lib/devices/worker-pick.d.ts +48 -0
  123. package/dist/lib/devices/worker-pick.js +113 -0
  124. package/dist/lib/exec.d.ts +67 -13
  125. package/dist/lib/exec.js +85 -29
  126. package/dist/lib/harness/adapters/cursor.js +8 -11
  127. package/dist/lib/helper-download.d.ts +108 -0
  128. package/dist/lib/helper-download.js +194 -0
  129. package/dist/lib/helper-versions.d.ts +52 -0
  130. package/dist/lib/helper-versions.js +58 -0
  131. package/dist/lib/hooks/cache.js +11 -0
  132. package/dist/lib/hooks/install.js +2 -2
  133. package/dist/lib/hosts/credentials.d.ts +1 -1
  134. package/dist/lib/hosts/credentials.js +1 -1
  135. package/dist/lib/hosts/dispatch.d.ts +7 -1
  136. package/dist/lib/hosts/dispatch.js +24 -5
  137. package/dist/lib/hosts/passthrough.d.ts +8 -15
  138. package/dist/lib/hosts/passthrough.js +19 -16
  139. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  140. package/dist/lib/hosts/providers/devices.js +1 -1
  141. package/dist/lib/hosts/reconnect.d.ts +179 -21
  142. package/dist/lib/hosts/reconnect.js +266 -45
  143. package/dist/lib/installations/migrate.d.ts +4 -5
  144. package/dist/lib/installations/migrate.js +6 -7
  145. package/dist/lib/installations/shims.d.ts +1 -1
  146. package/dist/lib/installations/shims.js +23 -13
  147. package/dist/lib/installations/versions.js +25 -2
  148. package/dist/lib/linear-autoclose.d.ts +1 -1
  149. package/dist/lib/linear-autoclose.js +1 -1
  150. package/dist/lib/loop.d.ts +2 -2
  151. package/dist/lib/loop.js +1 -1
  152. package/dist/lib/menubar/download-menubar.d.ts +47 -0
  153. package/dist/lib/menubar/download-menubar.js +60 -0
  154. package/dist/lib/menubar/install-menubar.d.ts +31 -7
  155. package/dist/lib/menubar/install-menubar.js +79 -21
  156. package/dist/lib/menubar/notify-desktop.d.ts +3 -3
  157. package/dist/lib/menubar/notify-desktop.js +6 -6
  158. package/dist/lib/model-tiers.d.ts +1 -1
  159. package/dist/lib/project-probe.d.ts +1 -1
  160. package/dist/lib/project-probe.js +1 -1
  161. package/dist/lib/project-pull.d.ts +1 -1
  162. package/dist/lib/project-pull.js +2 -2
  163. package/dist/lib/projects.d.ts +1 -1
  164. package/dist/lib/projects.js +1 -1
  165. package/dist/lib/sandbox.js +6 -7
  166. package/dist/lib/secrets/download-keychain.d.ts +47 -0
  167. package/dist/lib/secrets/download-keychain.js +70 -0
  168. package/dist/lib/secrets/install-helper.d.ts +20 -1
  169. package/dist/lib/secrets/install-helper.js +44 -3
  170. package/dist/lib/session/active.js +17 -1
  171. package/dist/lib/session/db.d.ts +11 -1
  172. package/dist/lib/session/db.js +138 -6
  173. package/dist/lib/session/discover.d.ts +21 -1
  174. package/dist/lib/session/discover.js +33 -5
  175. package/dist/lib/session/highlights.d.ts +49 -1
  176. package/dist/lib/session/highlights.js +95 -0
  177. package/dist/lib/session/host-link.d.ts +16 -2
  178. package/dist/lib/session/host-link.js +7 -1
  179. package/dist/lib/session/parse.js +33 -1
  180. package/dist/lib/session/remote/remote-list.d.ts +9 -0
  181. package/dist/lib/session/remote/remote-list.js +19 -2
  182. package/dist/lib/session/remote/watch.js +11 -2
  183. package/dist/lib/session/session-cache.d.ts +53 -0
  184. package/dist/lib/session/session-cache.js +88 -0
  185. package/dist/lib/session/state.js +1 -1
  186. package/dist/lib/session/tool-calls.d.ts +2 -0
  187. package/dist/lib/session/tool-calls.js +1 -1
  188. package/dist/lib/session/trajectory-html.d.ts +5 -1
  189. package/dist/lib/session/trajectory-html.js +42 -22
  190. package/dist/lib/session/trajectory-text.js +9 -2
  191. package/dist/lib/session/trajectory.js +53 -4
  192. package/dist/lib/session/types.d.ts +15 -0
  193. package/dist/lib/sha256-asset.d.ts +26 -0
  194. package/dist/lib/sha256-asset.js +41 -0
  195. package/dist/lib/share/backend.d.ts +95 -0
  196. package/dist/lib/share/backend.js +139 -0
  197. package/dist/lib/share/delete.d.ts +6 -2
  198. package/dist/lib/share/delete.js +8 -9
  199. package/dist/lib/share/html.d.ts +22 -0
  200. package/dist/lib/share/html.js +88 -0
  201. package/dist/lib/share/provision.d.ts +18 -4
  202. package/dist/lib/share/provision.js +38 -4
  203. package/dist/lib/share/publish.d.ts +39 -15
  204. package/dist/lib/share/publish.js +55 -26
  205. package/dist/lib/share/worker-template.js +171 -11
  206. package/dist/lib/sqlite.js +16 -3
  207. package/dist/lib/ssh-exec.d.ts +65 -0
  208. package/dist/lib/ssh-exec.js +120 -4
  209. package/dist/lib/startup/command-registry.js +1 -1
  210. package/dist/lib/startup/dev-build.js +3 -3
  211. package/dist/lib/state.d.ts +1 -1
  212. package/dist/lib/state.js +7 -3
  213. package/dist/lib/subagents-registry.js +1 -1
  214. package/dist/lib/terminal/index.d.ts +1 -1
  215. package/dist/lib/terminal/types.d.ts +1 -1
  216. package/dist/lib/terminal/types.js +1 -1
  217. package/dist/lib/tmux/orphan-reap.js +1 -1
  218. package/dist/lib/tmux/session.js +31 -0
  219. package/dist/lib/traces/backend.d.ts +29 -0
  220. package/dist/lib/traces/backend.js +46 -0
  221. package/dist/lib/traces/classify.d.ts +52 -0
  222. package/dist/lib/traces/classify.js +72 -0
  223. package/dist/lib/traces/config.d.ts +10 -0
  224. package/dist/lib/traces/config.js +2 -0
  225. package/dist/lib/traces/provision.d.ts +19 -0
  226. package/dist/lib/traces/provision.js +30 -0
  227. package/dist/lib/traces/sync.d.ts +150 -0
  228. package/dist/lib/traces/sync.js +447 -0
  229. package/dist/lib/traces/worker-template.d.ts +4 -0
  230. package/dist/lib/traces/worker-template.js +159 -0
  231. package/dist/lib/types.d.ts +18 -19
  232. package/dist/lib/types.js +14 -0
  233. package/dist/lib/usage-refresh.d.ts +1 -1
  234. package/dist/lib/usage-refresh.js +11 -8
  235. package/dist/lib/workflows.d.ts +1 -1
  236. package/package.json +4 -6
  237. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  238. package/dist/lib/menubar/MenubarHelper.app/Contents/Info.plist +0 -24
  239. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  240. package/dist/lib/menubar/MenubarHelper.app/Contents/Resources/AppIcon.icns +0 -0
  241. package/dist/lib/menubar/MenubarHelper.app/Contents/_CodeSignature/CodeResources +0 -128
  242. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  243. package/dist/lib/secrets/Agents CLI.app/Contents/Info.plist +0 -26
  244. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  245. package/dist/lib/secrets/Agents CLI.app/Contents/Resources/AppIcon.icns +0 -0
  246. package/dist/lib/secrets/Agents CLI.app/Contents/_CodeSignature/CodeResources +0 -135
  247. package/dist/lib/secrets/Agents CLI.app/Contents/embedded.provisionprofile +0 -0
  248. package/dist/lib/usage-fleet.d.ts +0 -32
  249. package/dist/lib/usage-fleet.js +0 -125
@@ -93,7 +93,7 @@ export declare function orderUsageAccounts(accounts: LocalUsageAccount[], cache:
93
93
  * canonicalization `getUsageInfoByIdentity` uses). Each carries a closure that
94
94
  * live-fetches its usage. This is the daemon's `listAccounts`; because it only
95
95
  * ever lists local, signed-in accounts, each host is the sole writer for its own
96
- * accounts' caches. `runUsageRefreshTick` calls this only on the fleet publisher.
96
+ * accounts' caches. `runUsageRefreshTick` calls this on every host.
97
97
  */
98
98
  export declare function buildLocalUsageAccounts(): Promise<LocalUsageAccount[]>;
99
99
  /** Injectable side effects, so `runUsageRefresh` is drivable without the daemon. */
@@ -1,17 +1,17 @@
1
1
  /**
2
- * Daemon-owned usage refresher (publisher host).
2
+ * Daemon-owned usage refresher runs on every host.
3
3
  *
4
4
  * The routing hot path (`agents run` → collectRunCandidates) reads usage
5
5
  * CACHE-ONLY (`getUsageInfoForIdentity`, RUSH-2061) and never blocks
6
6
  * on a provider fetch. Something still has to keep that cache fresh — this
7
- * module is that something, running inside the daemon on the configured
8
- * `usage.primary-host` (or locally when no primary is configured).
7
+ * module is that something, running inside the daemon on every host
8
+ * (RUSH-3193 #15: no primary/subscriber split — each host refreshes only
9
+ * the accounts it holds credentials for).
9
10
  *
10
11
  * Design:
11
12
  *
12
- * - **Fleet sole writer.** Only the configured primary lists credential-backed
13
- * accounts and calls providers. It exports derived snapshots/headroom;
14
- * subscriber hosts import that token-free envelope (`usage-fleet.ts`).
13
+ * - **Per-host writer.** Each host lists its own credential-backed accounts
14
+ * and calls providers directly; there is no cross-host broadcast.
15
15
  * - **Fixed 5-minute cadence** (`REFRESH_INTERVAL_MS`). Enough to keep
16
16
  * balanced/`agents view` off multi-hour stale data without thrashing
17
17
  * provider APIs when the user runs agents frequently. The delay helpers
@@ -222,7 +222,7 @@ export function orderUsageAccounts(accounts, cache, tick) {
222
222
  * canonicalization `getUsageInfoByIdentity` uses). Each carries a closure that
223
223
  * live-fetches its usage. This is the daemon's `listAccounts`; because it only
224
224
  * ever lists local, signed-in accounts, each host is the sole writer for its own
225
- * accounts' caches. `runUsageRefreshTick` calls this only on the fleet publisher.
225
+ * accounts' caches. `runUsageRefreshTick` calls this on every host.
226
226
  */
227
227
  export async function buildLocalUsageAccounts() {
228
228
  const accounts = [];
@@ -296,7 +296,10 @@ export async function runUsageRefresh(deps) {
296
296
  }
297
297
  try {
298
298
  const usage = await account.fetch();
299
- if (usage.snapshot?.source === 'live') {
299
+ if (usage.snapshot) {
300
+ // `source` is provenance, not freshness. A forced collection that just
301
+ // reread a local harness event returns `last_seen`; that is still a
302
+ // successful collection and belongs in the shared read cache.
300
303
  deps.writeUsageCache(account.usageKey, usage.snapshot);
301
304
  updates[account.usageKey] = nextHeadroomEntry(entry, usage.snapshot, now);
302
305
  result.refreshed += 1;
@@ -9,7 +9,7 @@ import type { AgentId } from './types.js';
9
9
  /**
10
10
  * The `loop:` block as it appears in WORKFLOW.md frontmatter (YAML, snake_case).
11
11
  * Parsed defensively and translated to the camelCase LoopConfig the driver
12
- * consumes (src/lib/loop.ts). See docs/entrypoints-and-loops.md.
12
+ * consumes (src/lib/loop.ts). See docs/execution.md.
13
13
  */
14
14
  export interface LoopConfigRaw {
15
15
  /** Stop condition. Only `signal` is supported today. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phnx-labs/agents-cli",
3
- "version": "1.22.47",
3
+ "version": "1.22.49",
4
4
  "description": "One CLI for all your AI coding agents - versions, config, cloud dispatch, sessions, and teams (now with first-class Grok Build CLI support)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,8 +25,6 @@
25
25
  "dist/**/*.d.ts",
26
26
  "dist/**/*.json",
27
27
  "dist/**/*.sh",
28
- "dist/lib/secrets/Agents CLI.app/**",
29
- "dist/lib/menubar/MenubarHelper.app/**",
30
28
  "scripts/postinstall.js",
31
29
  "scripts/install-helper.js",
32
30
  "CHANGELOG.md",
@@ -45,10 +43,10 @@
45
43
  "url": "https://github.com/phnx-labs/agents-cli/issues"
46
44
  },
47
45
  "scripts": {
48
- "build": "tsc && rm -rf 'dist/lib/secrets/AgentsKeychain.app' 'dist/lib/secrets/Agents CLI.app' 'dist/lib/menubar/MenubarHelper.app' && ([ -d 'bin/Agents CLI.app' ] && cp -R 'bin/Agents CLI.app' 'dist/lib/secrets/Agents CLI.app' || true) && ([ -d 'bin/MenubarHelper.app' ] && mkdir -p 'dist/lib/menubar' && cp -R 'bin/MenubarHelper.app' 'dist/lib/menubar/MenubarHelper.app' || true) && ([ -f 'bin/agents-macos' ] && mkdir -p dist/bin && cp -f 'bin/agents-macos' 'dist/bin/agents' && chmod 755 'dist/bin/agents' || true)",
46
+ "build": "tsc && rm -rf 'dist/lib/secrets/AgentsKeychain.app' 'dist/lib/secrets/Agents CLI.app' 'dist/lib/menubar/MenubarHelper.app' && ([ -f 'bin/agents-macos' ] && mkdir -p dist/bin && cp -f 'bin/agents-macos' 'dist/bin/agents' && chmod 755 'dist/bin/agents' || true)",
49
47
  "build:bin": "scripts/build-bin.sh",
50
48
  "prepare": "npm run build",
51
- "prepack": "cp ../../README.md README.md && scripts/verify-keychain-helper.sh && scripts/verify-menubar-helper.sh",
49
+ "prepack": "cp ../README.md README.md",
52
50
  "postinstall": "node scripts/postinstall.js",
53
51
  "dev": "tsx src/index.ts",
54
52
  "changelog": "bun scripts/gen-changelog.ts",
@@ -58,7 +56,7 @@
58
56
  "test": "node ./node_modules/vitest/vitest.mjs run",
59
57
  "bench": "node ./node_modules/vitest/vitest.mjs bench --run",
60
58
  "typecheck:bench": "tsc --noEmit --ignoreConfig --skipLibCheck --module esnext --moduleResolution bundler --target es2022 --strict --esModuleInterop --lib es2022 --types node src/lib/*.bench.ts src/lib/**/*.bench.ts",
61
- "test:remote": "scripts/sandbox.sh 'cd apps/cli && bun install && bun run build && bun run test'",
59
+ "test:remote": "scripts/sandbox.sh test",
62
60
  "verify-docs": "scripts/verify-docs.sh",
63
61
  "test:watch": "node ./node_modules/vitest/vitest.mjs"
64
62
  },
@@ -1,24 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleExecutable</key>
6
- <string>MenubarHelper</string>
7
- <key>CFBundleIdentifier</key>
8
- <string>com.phnx-labs.agents-menubar</string>
9
- <key>CFBundleName</key>
10
- <string>AGI Menu</string>
11
- <key>CFBundleDisplayName</key>
12
- <string>AGI Menu</string>
13
- <key>CFBundleIconFile</key>
14
- <string>AppIcon</string>
15
- <key>CFBundlePackageType</key>
16
- <string>APPL</string>
17
- <key>CFBundleShortVersionString</key>
18
- <string>0.1.0</string>
19
- <key>CFBundleVersion</key>
20
- <string>1</string>
21
- <key>LSUIElement</key>
22
- <true/>
23
- </dict>
24
- </plist>
@@ -1,128 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/AppIcon.icns</key>
8
- <data>
9
- jOjZVimcFRHoP2VPzgn8uM8mjkA=
10
- </data>
11
- </dict>
12
- <key>files2</key>
13
- <dict>
14
- <key>Resources/AppIcon.icns</key>
15
- <dict>
16
- <key>hash2</key>
17
- <data>
18
- GFvSLeNYJ3ASxW3OzcuiB4aID0gZUBkpozmWZkbTFNw=
19
- </data>
20
- </dict>
21
- </dict>
22
- <key>rules</key>
23
- <dict>
24
- <key>^Resources/</key>
25
- <true/>
26
- <key>^Resources/.*\.lproj/</key>
27
- <dict>
28
- <key>optional</key>
29
- <true/>
30
- <key>weight</key>
31
- <real>1000</real>
32
- </dict>
33
- <key>^Resources/.*\.lproj/locversion.plist$</key>
34
- <dict>
35
- <key>omit</key>
36
- <true/>
37
- <key>weight</key>
38
- <real>1100</real>
39
- </dict>
40
- <key>^Resources/Base\.lproj/</key>
41
- <dict>
42
- <key>weight</key>
43
- <real>1010</real>
44
- </dict>
45
- <key>^version.plist$</key>
46
- <true/>
47
- </dict>
48
- <key>rules2</key>
49
- <dict>
50
- <key>.*\.dSYM($|/)</key>
51
- <dict>
52
- <key>weight</key>
53
- <real>11</real>
54
- </dict>
55
- <key>^(.*/)?\.DS_Store$</key>
56
- <dict>
57
- <key>omit</key>
58
- <true/>
59
- <key>weight</key>
60
- <real>2000</real>
61
- </dict>
62
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
63
- <dict>
64
- <key>nested</key>
65
- <true/>
66
- <key>weight</key>
67
- <real>10</real>
68
- </dict>
69
- <key>^.*</key>
70
- <true/>
71
- <key>^Info\.plist$</key>
72
- <dict>
73
- <key>omit</key>
74
- <true/>
75
- <key>weight</key>
76
- <real>20</real>
77
- </dict>
78
- <key>^PkgInfo$</key>
79
- <dict>
80
- <key>omit</key>
81
- <true/>
82
- <key>weight</key>
83
- <real>20</real>
84
- </dict>
85
- <key>^Resources/</key>
86
- <dict>
87
- <key>weight</key>
88
- <real>20</real>
89
- </dict>
90
- <key>^Resources/.*\.lproj/</key>
91
- <dict>
92
- <key>optional</key>
93
- <true/>
94
- <key>weight</key>
95
- <real>1000</real>
96
- </dict>
97
- <key>^Resources/.*\.lproj/locversion.plist$</key>
98
- <dict>
99
- <key>omit</key>
100
- <true/>
101
- <key>weight</key>
102
- <real>1100</real>
103
- </dict>
104
- <key>^Resources/Base\.lproj/</key>
105
- <dict>
106
- <key>weight</key>
107
- <real>1010</real>
108
- </dict>
109
- <key>^[^/]+$</key>
110
- <dict>
111
- <key>nested</key>
112
- <true/>
113
- <key>weight</key>
114
- <real>10</real>
115
- </dict>
116
- <key>^embedded\.provisionprofile$</key>
117
- <dict>
118
- <key>weight</key>
119
- <real>20</real>
120
- </dict>
121
- <key>^version\.plist$</key>
122
- <dict>
123
- <key>weight</key>
124
- <real>20</real>
125
- </dict>
126
- </dict>
127
- </dict>
128
- </plist>
@@ -1,26 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleIdentifier</key>
6
- <string>com.phnx-labs.agents-keychain</string>
7
- <key>CFBundleName</key>
8
- <string>Agents CLI</string>
9
- <key>CFBundleDisplayName</key>
10
- <string>Agents CLI</string>
11
- <key>CFBundleIconFile</key>
12
- <string>AppIcon</string>
13
- <key>CFBundleExecutable</key>
14
- <string>Agents CLI</string>
15
- <key>CFBundlePackageType</key>
16
- <string>APPL</string>
17
- <key>CFBundleVersion</key>
18
- <string>1</string>
19
- <key>CFBundleShortVersionString</key>
20
- <string>1.0</string>
21
- <key>LSMinimumSystemVersion</key>
22
- <string>12.0</string>
23
- <key>LSUIElement</key>
24
- <true/>
25
- </dict>
26
- </plist>
@@ -1,135 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/AppIcon.icns</key>
8
- <data>
9
- DFq5H08EkhgWIC3UvGMR9B58BZw=
10
- </data>
11
- </dict>
12
- <key>files2</key>
13
- <dict>
14
- <key>Resources/AppIcon.icns</key>
15
- <dict>
16
- <key>hash2</key>
17
- <data>
18
- mBSjM6jlvN7J1jQowsvqTl7CHM0pur0e6qsHMuzk5k0=
19
- </data>
20
- </dict>
21
- <key>embedded.provisionprofile</key>
22
- <dict>
23
- <key>hash2</key>
24
- <data>
25
- 2vfA/eR3dTYgNc/fXhdADUPkp5tRIepPzE3FCLfDx4w=
26
- </data>
27
- </dict>
28
- </dict>
29
- <key>rules</key>
30
- <dict>
31
- <key>^Resources/</key>
32
- <true/>
33
- <key>^Resources/.*\.lproj/</key>
34
- <dict>
35
- <key>optional</key>
36
- <true/>
37
- <key>weight</key>
38
- <real>1000</real>
39
- </dict>
40
- <key>^Resources/.*\.lproj/locversion.plist$</key>
41
- <dict>
42
- <key>omit</key>
43
- <true/>
44
- <key>weight</key>
45
- <real>1100</real>
46
- </dict>
47
- <key>^Resources/Base\.lproj/</key>
48
- <dict>
49
- <key>weight</key>
50
- <real>1010</real>
51
- </dict>
52
- <key>^version.plist$</key>
53
- <true/>
54
- </dict>
55
- <key>rules2</key>
56
- <dict>
57
- <key>.*\.dSYM($|/)</key>
58
- <dict>
59
- <key>weight</key>
60
- <real>11</real>
61
- </dict>
62
- <key>^(.*/)?\.DS_Store$</key>
63
- <dict>
64
- <key>omit</key>
65
- <true/>
66
- <key>weight</key>
67
- <real>2000</real>
68
- </dict>
69
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
70
- <dict>
71
- <key>nested</key>
72
- <true/>
73
- <key>weight</key>
74
- <real>10</real>
75
- </dict>
76
- <key>^.*</key>
77
- <true/>
78
- <key>^Info\.plist$</key>
79
- <dict>
80
- <key>omit</key>
81
- <true/>
82
- <key>weight</key>
83
- <real>20</real>
84
- </dict>
85
- <key>^PkgInfo$</key>
86
- <dict>
87
- <key>omit</key>
88
- <true/>
89
- <key>weight</key>
90
- <real>20</real>
91
- </dict>
92
- <key>^Resources/</key>
93
- <dict>
94
- <key>weight</key>
95
- <real>20</real>
96
- </dict>
97
- <key>^Resources/.*\.lproj/</key>
98
- <dict>
99
- <key>optional</key>
100
- <true/>
101
- <key>weight</key>
102
- <real>1000</real>
103
- </dict>
104
- <key>^Resources/.*\.lproj/locversion.plist$</key>
105
- <dict>
106
- <key>omit</key>
107
- <true/>
108
- <key>weight</key>
109
- <real>1100</real>
110
- </dict>
111
- <key>^Resources/Base\.lproj/</key>
112
- <dict>
113
- <key>weight</key>
114
- <real>1010</real>
115
- </dict>
116
- <key>^[^/]+$</key>
117
- <dict>
118
- <key>nested</key>
119
- <true/>
120
- <key>weight</key>
121
- <real>10</real>
122
- </dict>
123
- <key>^embedded\.provisionprofile$</key>
124
- <dict>
125
- <key>weight</key>
126
- <real>20</real>
127
- </dict>
128
- <key>^version\.plist$</key>
129
- <dict>
130
- <key>weight</key>
131
- <real>20</real>
132
- </dict>
133
- </dict>
134
- </dict>
135
- </plist>
@@ -1,32 +0,0 @@
1
- import { type HeadroomEntry } from './usage-refresh.js';
2
- import { type UsageWindow } from './accounting/usage.js';
3
- export declare const USAGE_FLEET_VERSION = 1;
4
- export declare const USAGE_FLEET_FILE = ".usage-fleet.json";
5
- export interface UsageFleetWindow {
6
- key: UsageWindow['key'];
7
- label: string;
8
- shortLabel: string;
9
- usedPercent: number;
10
- resetsAt: string | null;
11
- windowMinutes: number | null;
12
- }
13
- export interface UsageFleetSnapshot {
14
- capturedAt: string | null;
15
- plan: string | null;
16
- windows: UsageFleetWindow[];
17
- }
18
- export interface UsageFleetExport {
19
- version: 1;
20
- publishedAt: number;
21
- usage: Record<string, UsageFleetSnapshot>;
22
- headroom: Record<string, HeadroomEntry>;
23
- }
24
- /** Publisher/subscriber role selection, kept pure for the daemon gate test. */
25
- export declare function usageRefreshRole(primaryHost: string | undefined, self: string): 'publisher' | 'subscriber';
26
- export declare function setUsageFleetExportPathForTest(value: string | null): string | null;
27
- /** Build and persist the primary's safe cache envelope. */
28
- export declare function exportUsageFleet(now?: number): UsageFleetExport;
29
- /** Merge a primary-host envelope into the subscriber's existing caches. */
30
- export declare function importUsageFleet(value: unknown): UsageFleetExport;
31
- /** Fetch the primary's published envelope over the registered device SSH path. */
32
- export declare function importUsageFleetFromHost(host: string): Promise<UsageFleetExport>;
@@ -1,125 +0,0 @@
1
- /**
2
- * Token-free usage replication from the configured primary host.
3
- *
4
- * The publisher writes only the already-derived usage windows and routing
5
- * headroom. Credentials, OAuth material, and provider responses never enter
6
- * this envelope. Subscribers fetch that file over the existing SSH trust path
7
- * and merge it into their local caches.
8
- */
9
- import { spawn } from 'node:child_process';
10
- import * as path from 'node:path';
11
- import { buildSshInvocation, writeAskpassShim } from './devices/connect.js';
12
- import { loadDevices } from './devices/registry.js';
13
- import { atomicWriteFileSync } from './fs-atomic.js';
14
- import { getCacheDir } from './state.js';
15
- import { readHeadroomCache, writeHeadroomEntries, } from './usage-refresh.js';
16
- import { readClaudeUsageCache, writeClaudeUsageCache, } from './accounting/usage.js';
17
- export const USAGE_FLEET_VERSION = 1;
18
- export const USAGE_FLEET_FILE = '.usage-fleet.json';
19
- /** Publisher/subscriber role selection, kept pure for the daemon gate test. */
20
- export function usageRefreshRole(primaryHost, self) {
21
- return primaryHost && primaryHost !== self ? 'subscriber' : 'publisher';
22
- }
23
- let exportPathOverride = null;
24
- export function setUsageFleetExportPathForTest(value) {
25
- const previous = exportPathOverride;
26
- exportPathOverride = value;
27
- return previous;
28
- }
29
- function exportPath() {
30
- return exportPathOverride ?? path.join(getCacheDir(), USAGE_FLEET_FILE);
31
- }
32
- function safeSnapshot(snapshot) {
33
- return {
34
- capturedAt: snapshot.capturedAt?.toISOString() ?? null,
35
- plan: snapshot.plan ?? null,
36
- windows: snapshot.windows.map((window) => ({
37
- key: window.key,
38
- label: window.label,
39
- shortLabel: window.shortLabel,
40
- usedPercent: window.usedPercent,
41
- resetsAt: window.resetsAt?.toISOString() ?? null,
42
- windowMinutes: window.windowMinutes,
43
- })),
44
- };
45
- }
46
- function liveSnapshot(snapshot) {
47
- return {
48
- source: 'last_seen',
49
- sourceLabel: 'primary host cache',
50
- capturedAt: snapshot.capturedAt ? new Date(snapshot.capturedAt) : null,
51
- plan: snapshot.plan,
52
- windows: snapshot.windows.map((window) => ({
53
- ...window,
54
- resetsAt: window.resetsAt ? new Date(window.resetsAt) : null,
55
- })),
56
- };
57
- }
58
- /** Build and persist the primary's safe cache envelope. */
59
- export function exportUsageFleet(now = Date.now()) {
60
- const headroom = readHeadroomCache();
61
- const usage = {};
62
- for (const usageKey of Object.keys(headroom)) {
63
- const snapshot = readClaudeUsageCache(usageKey);
64
- if (snapshot)
65
- usage[usageKey] = safeSnapshot(snapshot);
66
- }
67
- const payload = {
68
- version: USAGE_FLEET_VERSION,
69
- publishedAt: now,
70
- usage,
71
- headroom,
72
- };
73
- atomicWriteFileSync(exportPath(), JSON.stringify(payload, null, 2), 'utf-8');
74
- return payload;
75
- }
76
- function isUsageFleetExport(value) {
77
- if (!value || typeof value !== 'object')
78
- return false;
79
- const payload = value;
80
- return payload.version === USAGE_FLEET_VERSION
81
- && typeof payload.publishedAt === 'number'
82
- && !!payload.usage && typeof payload.usage === 'object'
83
- && !!payload.headroom && typeof payload.headroom === 'object';
84
- }
85
- /** Merge a primary-host envelope into the subscriber's existing caches. */
86
- export function importUsageFleet(value) {
87
- if (!isUsageFleetExport(value))
88
- throw new Error('usage fleet export has an unsupported shape');
89
- for (const [usageKey, snapshot] of Object.entries(value.usage)) {
90
- writeClaudeUsageCache(usageKey, liveSnapshot(snapshot));
91
- }
92
- writeHeadroomEntries(value.headroom);
93
- return value;
94
- }
95
- /** Fetch the primary's published envelope over the registered device SSH path. */
96
- export async function importUsageFleetFromHost(host) {
97
- const device = (await loadDevices())[host];
98
- if (!device)
99
- throw new Error(`usage primary host '${host}' is not a registered device`);
100
- const remoteRead = device.shell === 'powershell'
101
- ? ['Get-Content', '-Raw', '(Join-Path $HOME \'.agents/.cache/.usage-fleet.json\')']
102
- : ['cat', '"$HOME/.agents/.cache/.usage-fleet.json"'];
103
- const { args, env } = buildSshInvocation(device, remoteRead, writeAskpassShim(), {}, { agentOnly: true });
104
- const raw = await new Promise((resolve, reject) => {
105
- const child = spawn('ssh', args, {
106
- env: { ...process.env, ...env },
107
- stdio: ['ignore', 'pipe', 'pipe'],
108
- windowsHide: true,
109
- });
110
- let stdout = '';
111
- let stderr = '';
112
- child.stdout.setEncoding('utf-8');
113
- child.stderr.setEncoding('utf-8');
114
- child.stdout.on('data', (chunk) => { stdout += chunk; });
115
- child.stderr.on('data', (chunk) => { stderr += chunk; });
116
- child.on('error', reject);
117
- child.on('close', (code) => {
118
- if (code === 0)
119
- resolve(stdout);
120
- else
121
- reject(new Error(`usage primary host '${host}' export failed: ${stderr.trim() || `ssh exited ${code}`}`));
122
- });
123
- });
124
- return importUsageFleet(JSON.parse(raw));
125
- }