@crvouga/dev-fleet 0.0.0-stage → 0.1.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 (333) hide show
  1. package/.mise/locks/aws-cdk/2.1146.1/aube-lock.yaml +24 -0
  2. package/.mise/locks/aws-cdk/2.1146.1/package.json +7 -0
  3. package/.mise/locks/azure-cli/2.91.0~a837e014/pyproject.toml +5 -0
  4. package/.mise/locks/azure-cli/2.91.0~a837e014/uv.lock +2794 -0
  5. package/.mise/locks/gemini/0.66.0~84aac8e6/aube-lock.yaml +123 -0
  6. package/.mise/locks/gemini/0.66.0~84aac8e6/package.json +12 -0
  7. package/.mise/locks/npm-devcontainers-cli/0.90.0/aube-lock.yaml +24 -0
  8. package/.mise/locks/npm-devcontainers-cli/0.90.0/package.json +7 -0
  9. package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/aube-lock.yaml +1432 -0
  10. package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/package.json +7 -0
  11. package/.mise/locks/npm-vercel/65.8.0/aube-lock.yaml +3595 -0
  12. package/.mise/locks/npm-vercel/65.8.0/package.json +7 -0
  13. package/.mise/locks/npm-wrangler/4.156.0/aube-lock.yaml +895 -0
  14. package/.mise/locks/npm-wrangler/4.156.0/package.json +7 -0
  15. package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/aube-lock.yaml +24 -0
  16. package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/package.json +7 -0
  17. package/LICENSE +21 -0
  18. package/README.md +157 -2
  19. package/agents/antigravity-proxy.ts +3 -0
  20. package/agents/audit.md +89 -0
  21. package/agents/claude-proxy +5 -0
  22. package/agents/claude-proxy.ts +3 -0
  23. package/agents/codex-proxy.ts +3 -0
  24. package/agents/grok-proxy.ts +3 -0
  25. package/agents/managed-proxy.ts +55 -0
  26. package/agents/opencode-proxy.ts +3 -0
  27. package/agents/registry.json +209 -0
  28. package/agents/registry.schema.json +149 -0
  29. package/agents/setup.md +128 -0
  30. package/agents/t3.json +40 -0
  31. package/ansible/macos/manager.yml +30 -0
  32. package/ansible/macos/policy.json +17 -0
  33. package/ansible/monitoring/README.md +154 -0
  34. package/ansible/monitoring/agent-darwin.yml +198 -0
  35. package/ansible/monitoring/agent.yml +134 -0
  36. package/ansible/monitoring/beszel-agent.service +42 -0
  37. package/ansible/monitoring/compose.yml +74 -0
  38. package/ansible/monitoring/hub-darwin.yml +102 -0
  39. package/ansible/monitoring/lock.json +11 -0
  40. package/ansible/net/remote-probe.sh +13 -0
  41. package/ansible/ubuntu/authorize-sudo.sh +51 -0
  42. package/ansible/ubuntu/baseline.yml +89 -0
  43. package/ansible/ubuntu/disk-guard.py +104 -0
  44. package/ansible/ubuntu/policy.json +43 -0
  45. package/ansible/ubuntu/recovery.yml +15 -0
  46. package/ansible/ubuntu/t3/policy.json +7 -0
  47. package/ansible/ubuntu/t3-desktop.yml +220 -0
  48. package/ansible/ubuntu/t3-health.sh +33 -0
  49. package/ansible/ubuntu/t3-policy.yml +76 -0
  50. package/ansible/ubuntu/t3-route.yml +28 -0
  51. package/ansible/ubuntu/tailscale.yml +75 -0
  52. package/ansible/ubuntu/tasks/credentials.yml +47 -0
  53. package/ansible/ubuntu/tasks/docker.yml +31 -0
  54. package/ansible/ubuntu/tasks/packages.yml +56 -0
  55. package/ansible/ubuntu/tasks/power.yml +51 -0
  56. package/ansible/ubuntu/tasks/recovery.yml +39 -0
  57. package/ansible/ubuntu/tasks/resources.yml +252 -0
  58. package/ansible/ubuntu/tasks/services.yml +31 -0
  59. package/ansible/ubuntu/tasks/ssh.yml +71 -0
  60. package/ansible/ubuntu/tasks/user.yml +120 -0
  61. package/bin/devfleet.mjs +36 -0
  62. package/bootstrap/bootstrap.ps1 +50 -0
  63. package/bootstrap/bootstrap.sh +73 -0
  64. package/bootstrap/devfleet +7 -0
  65. package/bootstrap/docker-desktop.sh +33 -0
  66. package/bootstrap/doctor.ts +189 -0
  67. package/bootstrap/fleet-manager-run.sh +76 -0
  68. package/bootstrap/fleet-remote-bootstrap.sh +185 -0
  69. package/bootstrap/global-config.ts +113 -0
  70. package/bootstrap/install-launcher.sh +7 -0
  71. package/bootstrap/native-aws.ts +86 -0
  72. package/bootstrap/native-t3.ts +154 -0
  73. package/bootstrap/npm.ts +350 -0
  74. package/bootstrap/setup-status.ts +51 -0
  75. package/bootstrap/setup.ts +88 -0
  76. package/bootstrap/shell-path.ts +105 -0
  77. package/bootstrap/verify-t3-archive.py +49 -0
  78. package/bootstrap/worker-auth.ts +65 -0
  79. package/bootstrap/worker-github.ts +47 -0
  80. package/bootstrap/worker-tools.ts +24 -0
  81. package/cliproxy/AGENTS.md +11 -0
  82. package/cliproxy/README.md +269 -0
  83. package/cliproxy/clients/bootstrap.py +143 -0
  84. package/cliproxy/clients/launcher.py +57 -0
  85. package/cliproxy/compose.yaml +90 -0
  86. package/cliproxy/config.template.yaml +70 -0
  87. package/cliproxy/docs/cloud-adoption.md +16 -0
  88. package/cliproxy/docs/deployment.png +0 -0
  89. package/cliproxy/docs/deployment.svg +109 -0
  90. package/cliproxy/docs/health-workflow.example.yml +185 -0
  91. package/cliproxy/docs/migration.md +131 -0
  92. package/cliproxy/docs/model-health-report.schema.json +364 -0
  93. package/cliproxy/docs/model-health.md +393 -0
  94. package/cliproxy/image.lock.json +5 -0
  95. package/cliproxy/launchd/dev.devfleet.cliproxy-backup-check.plist +38 -0
  96. package/cliproxy/launchd/dev.devfleet.cliproxy-backup.plist +48 -0
  97. package/cliproxy/launchd/dev.devfleet.cliproxy-fleet.plist +32 -0
  98. package/cliproxy/launchd/dev.devfleet.cliproxy-gc.plist +38 -0
  99. package/cliproxy/launchd/dev.devfleet.cliproxy-monitor.plist +29 -0
  100. package/cliproxy/launchd/dev.devfleet.cliproxy-vault-renew.plist +31 -0
  101. package/cliproxy/models.json +1618 -0
  102. package/cliproxy/requirements.lock +78 -0
  103. package/cliproxy/scripts/accounts.py +38 -0
  104. package/cliproxy/scripts/audit.py +123 -0
  105. package/cliproxy/scripts/backup +234 -0
  106. package/cliproxy/scripts/check.py +34 -0
  107. package/cliproxy/scripts/checkpoint.py +226 -0
  108. package/cliproxy/scripts/cli.py +64 -0
  109. package/cliproxy/scripts/cliproxy_host.py +257 -0
  110. package/cliproxy/scripts/cloud_state.py +150 -0
  111. package/cliproxy/scripts/container-health +6 -0
  112. package/cliproxy/scripts/docker +24 -0
  113. package/cliproxy/scripts/external-health.py +79 -0
  114. package/cliproxy/scripts/fleet_config.py +43 -0
  115. package/cliproxy/scripts/fleet_sync.py +274 -0
  116. package/cliproxy/scripts/initialize +84 -0
  117. package/cliproxy/scripts/install-dependencies +48 -0
  118. package/cliproxy/scripts/install.py +406 -0
  119. package/cliproxy/scripts/model_health.py +16 -0
  120. package/cliproxy/scripts/modelhealth/__init__.py +5 -0
  121. package/cliproxy/scripts/modelhealth/checks.py +429 -0
  122. package/cliproxy/scripts/modelhealth/cli.py +117 -0
  123. package/cliproxy/scripts/modelhealth/config.py +186 -0
  124. package/cliproxy/scripts/modelhealth/emulator.py +536 -0
  125. package/cliproxy/scripts/modelhealth/expect.py +88 -0
  126. package/cliproxy/scripts/modelhealth/findings.py +183 -0
  127. package/cliproxy/scripts/modelhealth/protocol.py +330 -0
  128. package/cliproxy/scripts/modelhealth/redact.py +28 -0
  129. package/cliproxy/scripts/modelhealth/report.py +150 -0
  130. package/cliproxy/scripts/modelhealth/runner.py +390 -0
  131. package/cliproxy/scripts/modelhealth/scenario.py +131 -0
  132. package/cliproxy/scripts/modelhealth/schema.py +63 -0
  133. package/cliproxy/scripts/modelhealth/simulate.py +111 -0
  134. package/cliproxy/scripts/modelhealth/transport.py +213 -0
  135. package/cliproxy/scripts/monitor +68 -0
  136. package/cliproxy/scripts/ops +527 -0
  137. package/cliproxy/scripts/public-endpoint +127 -0
  138. package/cliproxy/scripts/recover_node.py +177 -0
  139. package/cliproxy/scripts/restore-verify +60 -0
  140. package/cliproxy/scripts/retention.py +144 -0
  141. package/cliproxy/scripts/service-start +7 -0
  142. package/cliproxy/scripts/validate-config +56 -0
  143. package/cliproxy/scripts/vault-access.py +57 -0
  144. package/cliproxy/scripts/vault-backup-login +55 -0
  145. package/cliproxy/scripts/vault-recovery +56 -0
  146. package/cliproxy/scripts/vault-renew +30 -0
  147. package/cliproxy/systemd/cliproxy-backup-check.service +10 -0
  148. package/cliproxy/systemd/cliproxy-backup-check.timer +8 -0
  149. package/cliproxy/systemd/cliproxy-backup.service +13 -0
  150. package/cliproxy/systemd/cliproxy-backup.timer +8 -0
  151. package/cliproxy/systemd/cliproxy-fleet.service +17 -0
  152. package/cliproxy/systemd/cliproxy-gc.service +13 -0
  153. package/cliproxy/systemd/cliproxy-gc.timer +8 -0
  154. package/cliproxy/systemd/cliproxy-monitor.service +8 -0
  155. package/cliproxy/systemd/cliproxy-monitor.timer +7 -0
  156. package/cliproxy/systemd/cliproxy-vault-renew.service +8 -0
  157. package/cliproxy/systemd/cliproxy-vault-renew.timer +7 -0
  158. package/cliproxy/vendor/LICENSE +22 -0
  159. package/cliproxy/vendor/config.upstream.yaml +1349 -0
  160. package/examples/fleet.json +95 -0
  161. package/examples/roster.json +13 -0
  162. package/mise.lock +1492 -0
  163. package/mise.toml +99 -0
  164. package/package.json +65 -4
  165. package/schema/fleet.schema.json +364 -0
  166. package/schema/roster.schema.json +77 -0
  167. package/src/agents/account-relay.ts +111 -0
  168. package/src/agents/accounts.ts +85 -0
  169. package/src/agents/audit.ts +77 -0
  170. package/src/agents/cli.ts +13 -0
  171. package/src/agents/command.ts +204 -0
  172. package/src/agents/converge.ts +123 -0
  173. package/src/agents/doctor.ts +107 -0
  174. package/src/agents/errors.ts +2 -0
  175. package/src/agents/files.ts +73 -0
  176. package/src/agents/fleet-verify.ts +156 -0
  177. package/src/agents/launch.ts +290 -0
  178. package/src/agents/native-verify.ts +226 -0
  179. package/src/agents/provider-errors.ts +50 -0
  180. package/src/agents/registry.ts +55 -0
  181. package/src/agents/render.ts +110 -0
  182. package/src/agents/round-trip.ts +192 -0
  183. package/src/agents/secrets.ts +13 -0
  184. package/src/agents/toolchain.ts +34 -0
  185. package/src/agents/verify-cache.ts +103 -0
  186. package/src/agents/verify.ts +127 -0
  187. package/src/auth-checks.ts +163 -0
  188. package/src/cli/agent-guide.ts +95 -0
  189. package/src/cli/app.ts +115 -0
  190. package/src/cli/cli.ts +21 -0
  191. package/src/cli/command-index.ts +50 -0
  192. package/src/cli/contracts.ts +25 -0
  193. package/src/cli/fleet-reference.ts +17 -0
  194. package/src/cli/fleet-sync-checkout.ts +91 -0
  195. package/src/cli/fleet-sync-enrollment.ts +144 -0
  196. package/src/cli/fleet-sync-forward.ts +134 -0
  197. package/src/cli/fleet-sync-manager.ts +193 -0
  198. package/src/cli/fleet-sync-monitoring.ts +185 -0
  199. package/src/cli/fleet-sync-output.ts +314 -0
  200. package/src/cli/fleet-sync-privilege.ts +27 -0
  201. package/src/cli/fleet-sync-progress.ts +109 -0
  202. package/src/cli/fleet-sync-remote.ts +236 -0
  203. package/src/cli/fleet-sync-report.ts +26 -0
  204. package/src/cli/fleet-sync-schedule.ts +138 -0
  205. package/src/cli/fleet-sync-vault.ts +166 -0
  206. package/src/cli/fleet-sync.ts +309 -0
  207. package/src/cli/fleet.ts +163 -0
  208. package/src/cli/managed-health.ts +219 -0
  209. package/src/cli/node-deployment.ts +34 -0
  210. package/src/cli/node-sync.ts +114 -0
  211. package/src/cli/node-t3.ts +31 -0
  212. package/src/cli/options.ts +141 -0
  213. package/src/cli/probe-source.ts +7 -0
  214. package/src/cli/program.ts +169 -0
  215. package/src/cli/register-fleet.ts +246 -0
  216. package/src/cli/registry.ts +158 -0
  217. package/src/cli/repair-apply.ts +67 -0
  218. package/src/cli/repair-guard.ts +11 -0
  219. package/src/cli/repair-inspect.ts +150 -0
  220. package/src/cli/repair-script.ts +76 -0
  221. package/src/cli/repair.ts +209 -0
  222. package/src/cli/roster.ts +89 -0
  223. package/src/cli/search.ts +35 -0
  224. package/src/cli/settings.ts +64 -0
  225. package/src/cli/source-operations.ts +78 -0
  226. package/src/cli/t3/command.ts +90 -0
  227. package/src/cli/t3/register.ts +55 -0
  228. package/src/cli/tailnet.ts +127 -0
  229. package/src/cli/ui-actions.ts +133 -0
  230. package/src/cli/ui-controller.ts +113 -0
  231. package/src/cli/ui-data.ts +106 -0
  232. package/src/cli/ui-execute.ts +163 -0
  233. package/src/cli/ui-repairs.ts +34 -0
  234. package/src/cli/ui-reports.ts +211 -0
  235. package/src/cli/ui-targets.ts +100 -0
  236. package/src/cli/ui-terminal.ts +109 -0
  237. package/src/cli/ui-types.ts +49 -0
  238. package/src/cli/ui-wizard.ts +101 -0
  239. package/src/cli/ui.ts +9 -0
  240. package/src/cli/worker-health-output.ts +37 -0
  241. package/src/config.ts +186 -0
  242. package/src/configure.ts +255 -0
  243. package/src/definition.ts +260 -0
  244. package/src/diagnostics.ts +92 -0
  245. package/src/doctor-check.ts +10 -0
  246. package/src/errors.ts +1 -0
  247. package/src/fingerprint.ts +120 -0
  248. package/src/fleet-config.ts +88 -0
  249. package/src/index.ts +6 -0
  250. package/src/input-hashes.ts +73 -0
  251. package/src/machine/local-source.ts +52 -0
  252. package/src/machine/lock-error.ts +2 -0
  253. package/src/machine/platform.ts +44 -0
  254. package/src/machine/source.ts +68 -0
  255. package/src/machine/state.ts +185 -0
  256. package/src/machine-health.ts +95 -0
  257. package/src/managed-source.ts +47 -0
  258. package/src/manager-failure.ts +48 -0
  259. package/src/manager-sync.ts +400 -0
  260. package/src/manager.ts +62 -0
  261. package/src/monitoring/apply.ts +171 -0
  262. package/src/monitoring/beszel.ts +191 -0
  263. package/src/monitoring/enroll.ts +110 -0
  264. package/src/monitoring/hub-access.ts +113 -0
  265. package/src/monitoring/hub-viewer.ts +142 -0
  266. package/src/monitoring/hub.ts +93 -0
  267. package/src/monitoring/manager-agent.ts +73 -0
  268. package/src/monitoring/manager-hub.ts +232 -0
  269. package/src/monitoring/remote.ts +65 -0
  270. package/src/network-definition.ts +83 -0
  271. package/src/node-converge-linux.ts +372 -0
  272. package/src/node-converge-shared.ts +83 -0
  273. package/src/node-converge.ts +40 -0
  274. package/src/onboard.ts +35 -0
  275. package/src/platform/ansible-receipt.ts +128 -0
  276. package/src/platform/ansible.ts +62 -0
  277. package/src/platform/darwin.ts +203 -0
  278. package/src/platform/detect.ts +11 -0
  279. package/src/platform/fallback.ts +110 -0
  280. package/src/platform/index.ts +38 -0
  281. package/src/platform/launchd.ts +98 -0
  282. package/src/platform/linux.ts +139 -0
  283. package/src/platform/ps.ts +45 -0
  284. package/src/platform/resource-verify.ts +128 -0
  285. package/src/platform/systemd-user.ts +95 -0
  286. package/src/platform/t3-policy.ts +137 -0
  287. package/src/platform/t3-route.ts +68 -0
  288. package/src/platform/t3-service.ts +75 -0
  289. package/src/platform/types.ts +123 -0
  290. package/src/platform/ubuntu-audit.ts +63 -0
  291. package/src/platform/ubuntu-verify.ts +105 -0
  292. package/src/platform/windows.ts +148 -0
  293. package/src/power-recovery.ts +55 -0
  294. package/src/probe.ts +51 -0
  295. package/src/protocol.ts +119 -0
  296. package/src/proxy-converge.ts +85 -0
  297. package/src/remote-bootstrap.ts +212 -0
  298. package/src/remote-entry.ts +89 -0
  299. package/src/remote-lock.ts +12 -0
  300. package/src/repair-catalog.ts +206 -0
  301. package/src/repair-plan.ts +78 -0
  302. package/src/repair-runner.ts +84 -0
  303. package/src/report.ts +71 -0
  304. package/src/runner.ts +104 -0
  305. package/src/secrets.ts +169 -0
  306. package/src/service-auth.ts +115 -0
  307. package/src/ssh.ts +135 -0
  308. package/src/sync.ts +104 -0
  309. package/src/t3/accounts.ts +81 -0
  310. package/src/t3/desired.ts +165 -0
  311. package/src/t3/files.ts +81 -0
  312. package/src/t3/names-check.ts +53 -0
  313. package/src/t3/names.ts +155 -0
  314. package/src/t3/plan.ts +82 -0
  315. package/src/t3/providers.ts +74 -0
  316. package/src/t3/reconcile.ts +123 -0
  317. package/src/t3-endpoint.ts +48 -0
  318. package/src/t3-linked-check.ts +101 -0
  319. package/src/tailnet-health.ts +231 -0
  320. package/src/tailnet-matching.ts +37 -0
  321. package/src/tailscale.ts +141 -0
  322. package/src/test-fixtures.ts +36 -0
  323. package/src/toolchain-checks.ts +83 -0
  324. package/src/topology.ts +24 -0
  325. package/src/transport.ts +122 -0
  326. package/src/types.ts +95 -0
  327. package/src/vault-config.ts +38 -0
  328. package/src/worker-access-checks.ts +115 -0
  329. package/src/worker-capacity.ts +34 -0
  330. package/src/worker-host-checks.ts +176 -0
  331. package/src/worker-policy.ts +64 -0
  332. package/src/worker-readiness.ts +64 -0
  333. package/src/workstation-checks.ts +29 -0
@@ -0,0 +1,149 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Personal portable agent registry",
4
+ "type": "object",
5
+ "required": ["version", "defaults", "proxy", "nodes", "tools"],
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string"
10
+ },
11
+ "version": {
12
+ "const": 1
13
+ },
14
+ "defaults": {
15
+ "type": "object"
16
+ },
17
+ "proxy": {
18
+ "type": "object",
19
+ "required": ["models"],
20
+ "properties": {
21
+ "models": {
22
+ "type": "object"
23
+ },
24
+ "accounts": {
25
+ "description": "Tools T3 offers once per signed-in proxy account. Accounts are never listed here: they are discovered from the proxy's model list. provider is the proxy credential type that serves the tool; models are preferred defaults (Claude: opus, sonnet, haiku).",
26
+ "type": "object",
27
+ "additionalProperties": {
28
+ "type": "object",
29
+ "required": ["provider", "models"],
30
+ "additionalProperties": false,
31
+ "properties": {
32
+ "provider": {
33
+ "type": "string",
34
+ "pattern": "^[a-z][a-z0-9]{0,30}$"
35
+ },
36
+ "models": {
37
+ "type": "array",
38
+ "minItems": 1,
39
+ "items": {
40
+ "type": "string",
41
+ "pattern": "^[a-zA-Z0-9_.:+-]+$"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ },
49
+ "nodes": {
50
+ "type": "object",
51
+ "propertyNames": {
52
+ "pattern": "^[a-z0-9][a-z0-9-]{0,62}$"
53
+ },
54
+ "additionalProperties": {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "properties": {
58
+ "codex": {
59
+ "type": "object",
60
+ "additionalProperties": false,
61
+ "properties": {
62
+ "direct": {
63
+ "type": "string",
64
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
65
+ },
66
+ "proxy": {
67
+ "type": "string",
68
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
69
+ }
70
+ }
71
+ },
72
+ "claude": {
73
+ "type": "object",
74
+ "additionalProperties": false,
75
+ "properties": {
76
+ "direct": {
77
+ "type": "string",
78
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
79
+ },
80
+ "proxy": {
81
+ "type": "string",
82
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
83
+ }
84
+ }
85
+ },
86
+ "opencode": {
87
+ "type": "object",
88
+ "additionalProperties": false,
89
+ "properties": {
90
+ "direct": {
91
+ "type": "string",
92
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
93
+ },
94
+ "proxy": {
95
+ "type": "string",
96
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
97
+ }
98
+ }
99
+ },
100
+ "gemini": {
101
+ "type": "object",
102
+ "additionalProperties": false,
103
+ "properties": {
104
+ "direct": {
105
+ "type": "string",
106
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
107
+ },
108
+ "proxy": {
109
+ "type": "string",
110
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
111
+ }
112
+ }
113
+ },
114
+ "grok": {
115
+ "type": "object",
116
+ "additionalProperties": false,
117
+ "properties": {
118
+ "direct": {
119
+ "type": "string",
120
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
121
+ },
122
+ "proxy": {
123
+ "type": "string",
124
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
125
+ }
126
+ }
127
+ },
128
+ "antigravity": {
129
+ "type": "object",
130
+ "additionalProperties": false,
131
+ "properties": {
132
+ "direct": {
133
+ "type": "string",
134
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
135
+ },
136
+ "proxy": {
137
+ "type": "string",
138
+ "pattern": "^[a-zA-Z0-9_./:+-]+$"
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
144
+ },
145
+ "tools": {
146
+ "type": "object"
147
+ }
148
+ }
149
+ }
@@ -0,0 +1,128 @@
1
+ # Manager-led Ubuntu fleet setup
2
+
3
+ For the enrolled Ubuntu development fleet, run on the designated manager:
4
+
5
+ ```sh
6
+ devfleet fleet-sync
7
+ ```
8
+
9
+ Read the [Fleet operator guide](../../fleet/docs/ubuntu-sync.md) for enrollment,
10
+ approved revisions, bootstrap, provider checks and unresolved release gates.
11
+ Routine fleet updates do not require a command sequence on individual nodes.
12
+ The legacy local commands below retain their existing behavior for compatibility.
13
+
14
+ # Developer fleet configuration setup
15
+
16
+ Use **personal** for node and T3 configuration. Workstation and fleet are internal
17
+ implementation packages; neither exports its own executable.
18
+
19
+ After the shared [machine bootstrap](../../../bootstrap/README.md), run in the
20
+ personal checkout:
21
+
22
+ ```sh
23
+ sh bootstrap/install-launcher.sh
24
+ devfleet fleet-node-sync
25
+ devfleet fleet-status
26
+ ```
27
+
28
+ The npm fallback is the same interface:
29
+
30
+ ```sh
31
+ devfleet fleet-node-sync
32
+ ```
33
+
34
+ Use `PERSONAL_WORKSPACE` or `--workspace PATH` when invoking the npm CLI outside
35
+ the checkout. The installed source launcher resolves its checkout automatically.
36
+ Each machine still needs its own authorized Vault session, SSH keys and T3 pairing.
37
+ The sync never copies them or provisions infrastructure.
38
+
39
+ ## Reconciliation
40
+
41
+ `fleet-node-sync` applies by invocation. It reconciles the locked toolchain, installs
42
+ one `personal` launcher, retires the repository-owned `ws` launcher, upserts the
43
+ Codex proxy profile, and reconciles T3 provider instances. `--dry-run` lists these
44
+ steps without writing or installing. The default node ID is the normalized hostname;
45
+ use `--id NAME` to retain an existing node's registry overrides.
46
+
47
+ The selected revision defaults to checkout HEAD. `--revision FULL_SHA` pins a
48
+ reviewed commit already fetched into that checkout. Deployment uses a clean Git
49
+ worktree and preserves developer edits. For whole-fleet maintenance, use the manager command above; this legacy local route does not orchestrate other nodes. A failed step stops later steps and reports
50
+ partial progress; it never claims authentication or inference was verified.
51
+
52
+ Portable models live in `agents/registry.json`; T3 desired provider instances live
53
+ in `agents/t3.json`. Edit these tracked definitions and deploy a reviewed revision.
54
+ New sessions use the updated configuration. Running sessions are not restarted.
55
+
56
+ ## T3 plan, apply, import and cleanup
57
+
58
+ ```sh
59
+ devfleet t3-apply --dry-run --json
60
+ devfleet t3-apply
61
+ devfleet t3-status
62
+ devfleet t3-cleanup --dry-run
63
+ ```
64
+
65
+ Plans show create/update/delete/unchanged/conflict by instance ID, with no settings
66
+ values or credentials. `devfleet t3-apply --plan-hash HASH` binds apply to the exact
67
+ settings, ownership state, desired definitions and destination reviewed in a plan.
68
+ A stale plan fails. A second apply with identical inputs performs no settings write.
69
+
70
+ A provider instance becomes managed when created by personal, or explicitly imported:
71
+
72
+ ```sh
73
+ devfleet t3-apply --import personal_grok_proxy
74
+ devfleet t3-apply
75
+ ```
76
+
77
+ Import grants ownership of the entire named provider instance. It does not change
78
+ its settings immediately. Subsequent applies reconcile that instance to the tracked
79
+ definition, including removal of extra fields. Existing unowned instances cause a
80
+ conflict, even when their names match. Unrelated instances and settings are preserved.
81
+
82
+ Removing an instance from the desired definition removes it on the next apply.
83
+ `devfleet t3-cleanup` removes **all owned provider instances** while retaining
84
+ threads, projects, pairing, native provider instances, credentials and profile files.
85
+ It does not delete T3's data directory or secret store. Historical threads may need
86
+ a replacement provider selected after their managed instance is removed.
87
+
88
+ `--t3-home PATH` selects a T3 base directory (otherwise T3CODE_HOME or ~/.t3).
89
+ `--definition FILE` selects a version-1 desired definition. Supported interpolation
90
+ is `${workspace}`, `${agents}` and `${node}`. The current schema deliberately supports
91
+ the verified Codex proxy adapter fields; it rejects inline credential definitions.
92
+ T3 proxy execution requires macOS/Linux/WSL; native Windows execution is unverified.
93
+
94
+ ## State and concurrency
95
+
96
+ T3 owns `userdata/settings.json`. Personal merges only its declared instances and
97
+ stores IDs in `userdata/personal-managed.json`, with mode 0600. Private settings and
98
+ state backups sit beside that file. They may contain existing secret references or
99
+ values and must never enter Git or reports. Symlink/malformed destinations fail.
100
+
101
+ Personal operations use an exclusive lock, atomic replacement, pre-write freshness
102
+ checks and post-write verification. T3's own theme CLI uses the same optimistic
103
+ external-file update pattern; T3 does not honor personal's lock. Avoid concurrent
104
+ Settings edits during apply: there is no cross-process atomic compare-and-swap with
105
+ T3. No strict transaction across application and ownership files is claimed. Ownership
106
+ intent is saved before settings so interrupted creates/removals can be retried.
107
+ Inspect interrupted operations before removing a stale `.lock` directory.
108
+
109
+ T3's installed server source at revision
110
+ `322f6544dfad0a3c8a0c8cbecf2c7f7874b14268` was inspected for provider-instance shape,
111
+ external settings watch/reload, and optimistic CLI writes. Future T3 schema changes
112
+ require adapter verification. A disk-level success is not a live inference test.
113
+
114
+ ## Other local operations
115
+
116
+ All former workstation operations are available through `dev-fleet`:
117
+
118
+ ```sh
119
+ dev-fleet tools check --json
120
+ bun src/agents/cli.ts agents verify --node NODE --tool codex --profile proxy --json
121
+ dev-fleet opencode sync
122
+ dev-fleet net check
123
+ ```
124
+
125
+ `devfleet fleet-status` diagnoses the manager and registered remote nodes.
126
+ `devfleet fleet-discover` lists visible Tailscale computers. The local SSH roster
127
+ still requires real aliases and checkout paths; discovery never guesses these.
128
+ Use `personal commands --json` to discover the complete interface.
package/agents/t3.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "version": 1,
3
+ "instances": {
4
+ "personal_gateway_models": {
5
+ "driver": "opencode",
6
+ "displayName": "OpenCode CLI Proxy",
7
+ "enabled": true,
8
+ "config": {
9
+ "binaryPath": "${workspace}/agents/opencode-proxy.ts"
10
+ },
11
+ "environment": [
12
+ {
13
+ "name": "WS_AGENT_NODE",
14
+ "value": "${node}",
15
+ "sensitive": false
16
+ }
17
+ ]
18
+ },
19
+ "personal_grok_proxy": {
20
+ "driver": "grok",
21
+ "displayName": "Grok CLI Proxy",
22
+ "enabled": true,
23
+ "config": {
24
+ "binaryPath": "${workspace}/agents/grok-proxy.ts"
25
+ },
26
+ "environment": [
27
+ {
28
+ "name": "WS_AGENT_NODE",
29
+ "value": "${node}",
30
+ "sensitive": false
31
+ },
32
+ {
33
+ "name": "XAI_API_KEY",
34
+ "value": "fleet-cli-proxy",
35
+ "sensitive": false
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,30 @@
1
+ ---
2
+ # Manager power policy. Workers depend on the manager's singleton services
3
+ # (CLI proxy, Beszel hub), so the manager never sleeps on AC power. Sleep on
4
+ # battery is left to the human. Run once with: ansible-playbook -K manager.yml
5
+ - name: Keep the fleet manager awake on AC power
6
+ hosts: localhost
7
+ connection: local
8
+ become: true
9
+ gather_facts: false
10
+ vars:
11
+ manager_pmset_ac:
12
+ sleep: '0'
13
+ womp: '1'
14
+ tasks:
15
+ - name: Inspect effective power management settings
16
+ ansible.builtin.command:
17
+ argv: [/usr/bin/pmset, -g, custom]
18
+ changed_when: false
19
+ register: pmset_custom
20
+ - name: Never sleep while on AC power
21
+ ansible.builtin.command:
22
+ argv: [/usr/bin/pmset, -c, '{{ item.key }}', '{{ item.value }}']
23
+ loop: '{{ manager_pmset_ac | dict2items }}'
24
+ loop_control:
25
+ label: '{{ item.key }}'
26
+ vars:
27
+ ac_section: "{{ pmset_custom.stdout.split('AC Power:') | last }}"
28
+ observed: "{{ ac_section | regex_findall('^\\s*' ~ item.key ~ '\\s+(\\S+)', multiline=True) | first | default('') }}"
29
+ when: observed != item.value
30
+ changed_when: true
@@ -0,0 +1,17 @@
1
+ {
2
+ "version": 1,
3
+ "minimumMajorVersion": 14,
4
+ "ansibleCore": "2.19.9",
5
+ "pmset": {
6
+ "sleep": "0",
7
+ "disksleep": "0",
8
+ "autorestart": "1",
9
+ "womp": "1",
10
+ "powernap": "0"
11
+ },
12
+ "autoLogOutDelay": 0,
13
+ "screensaverIdleTime": 0,
14
+ "tailscaleDaemon": "com.tailscale.tailscaled",
15
+ "beszelDaemon": "dev.devfleet.beszel-agent",
16
+ "credentialRenewalAgent": "dev.devfleet.worker-auth"
17
+ }
@@ -0,0 +1,154 @@
1
+ # Beszel owner and recovery
2
+
3
+ Fleet's [manager guide](../../fleet/docs/ubuntu-sync.md) is the normal entry
4
+ point: `devfleet fleet-sync`, run on the manager. Workstation owns the
5
+ pinned Compose hub, native agent units and local Ansible tasks here. Fleet owns
6
+ membership, registration and freshness evidence. `lock.json` pins Beszel 0.21.1
7
+ and the native agent checksums. Never run an unpinned upstream installer
8
+ alongside these services.
9
+
10
+ ## Manager and workers
11
+
12
+ The fleet has exactly two roles (Fleet `definition.json`, version 3):
13
+
14
+ - **Manager** — the human's macOS machine. It runs fleet-sync locally and hosts the
15
+ singleton hub (`cli/lib/monitoring/manager-hub.ts`, `convergeManagerHub`). Fleet
16
+ keeps it awake on AC power. Nothing is installed on it over SSH.
17
+ - **Workers** — the stateless Linux boxes. They only run the native agent
18
+ (`agent.yml`, a hardened systemd unit) and connect to the manager's private hub
19
+ URL. A worker refuses hub mode (`BESZEL_NOT_HUB`: the hub runs only on the
20
+ manager) and an agent refuses any other hub URL (`BESZEL_HUB_MISMATCH`).
21
+
22
+ The manager is always a monitored system on its own hub. After the hub converges,
23
+ fleet-sync enrolls the manager like a worker and installs its agent locally with
24
+ `agent-darwin.yml`: the same pinned binary (`lock.json` carries the darwin
25
+ checksums) as a per-user launchd agent with `KeepAlive`
26
+ (`~/Library/LaunchAgents/dev.devfleet.beszel-agent.plist`, state under
27
+ `~/Library/Application Support/personal-beszel-agent`). It needs no sudo, so
28
+ fleet-sync stays unattended; it is less sandboxed than the Linux unit. It refuses
29
+ to run beside a leftover root LaunchDaemon with the same label
30
+ (`BESZEL_LEGACY_DAEMON`).
31
+
32
+ ## Hub on the manager
33
+
34
+ `hub-darwin.yml` runs as the signed-in user (no sudo) under Docker Desktop, which
35
+ must be running (`BESZEL_DOCKER_DESKTOP_REQUIRED`); enable _Start Docker Desktop
36
+ when you sign in_. It refuses to replace a different existing image
37
+ (`BESZEL_HUB_UPGRADE_PENDING`). Paths are per-user and `0700`:
38
+
39
+ - data: `~/Library/Application Support/personal-beszel` (bind-mounted as
40
+ `/beszel_data`; it is in the human's normal home backups, but use the stock
41
+ backups below for consistent copies);
42
+ - connector token: `~/Library/Application Support/personal-beszel-tunnel/token`
43
+ (`0600`).
44
+
45
+ The dashboard is `https://<manager-MagicDNS-name>:8443`
46
+ (`hubUrl(definition)`), used by agents and checks. CLI output only ever prints
47
+ the stable public dashboard, `https://beszel.example.com`; tailnet addresses
48
+ are never printed. The Compose port is
49
+ loopback-only; Tailscale Serve (`tailscale serve --bg --https=8443
50
+ http://127.0.0.1:8090`, using `tailscale` on PATH or the app's
51
+ `/Applications/Tailscale.app/Contents/MacOS/Tailscale`) provides private HTTPS.
52
+ No Funnel or inbound listener is configured. Convergence passes `beszel:hub` only
53
+ after `/api/health` answers both locally and at the private URL. Before enrolling
54
+ agents, fleet-sync requires that URL to answer; otherwise workers report
55
+ `BESZEL_HUB_UNREACHABLE` (keep the manager awake and Docker Desktop running).
56
+
57
+ The same hub is also served at `https://beszel.example.com` through an
58
+ outbound-only Cloudflare Tunnel: the inventory's
59
+ `cloudflare.additional_tunnels.beszel` entry makes OpenTofu own the tunnel, its
60
+ proxied DNS record and the isolated `secret/beszel/tunnel` Vault document. The
61
+ hub converge reads that document with the manager's own Vault session (the
62
+ human's session; never printed or placed in argv), writes it to the per-user
63
+ token file and starts the pinned `cloudflared` Compose profile. Until the
64
+ credential is readable the step warns (`BESZEL_TUNNEL_CREDENTIAL_UNAVAILABLE`)
65
+ and the private dashboard is unaffected. Agents and the manager keep using the
66
+ private URL; `fleet-status --workers` reports the public hostname as a
67
+ warning-level `beszel:public-endpoint` check.
68
+
69
+ The dashboard needs no login: the hub runs with `AUTO_LOGIN` set to the
70
+ read-only user `public-viewer@example.com`, so every visitor (public or
71
+ tailnet) is signed in as that account and cannot change systems, alerts or
72
+ settings. Each hub converge (`fleet-sync`) creates that user through the hub's
73
+ loopback API using the fleet admin login from Vault (random unused password,
74
+ never printed), re-reads it to prove the role, and demotes it to read-only if it
75
+ ever had another role (`beszel:public-viewer`). If the admin login is
76
+ unavailable the step warns and the hub shows its normal login page; create the
77
+ user by hand (Settings > Users, role **Read-only**) as a fallback. Never point
78
+ `AUTO_LOGIN` at an admin account. The fleet admin login is still needed to change anything.
79
+
80
+ Native agents use outbound authenticated WebSockets, per-node tokens and
81
+ persistent identity. They do not need inbound SSH monitoring ports, Docker socket
82
+ access or journals.
83
+ `SKIP_SYSTEMD_LOGS=true` deliberately excludes potentially sensitive service logs.
84
+ System services may be visible; user T3 service information is not certified by
85
+ that fact. Missing sensors, SMART privileges, Docker stats and user-service metrics
86
+ remain unavailable until their specific supported permissions are reviewed.
87
+
88
+ Accounts need no manual step. On a hub's first start (empty data directory),
89
+ `hub-darwin.yml` passes Beszel's `USER_EMAIL`/`USER_PASSWORD` once, so the hub
90
+ creates `fleet-manager@example.com` as a verified user and as its superuser,
91
+ with the password OpenTofu generates as `BESZEL_FLEET_AUTH` in
92
+ `secret/personal/prd`. Later runs never pass it, and existing data is never
93
+ changed. Sign in to the dashboard with that account.
94
+ The hub runs with `SHARE_ALL_SYSTEMS=true`, so systems that account registers are
95
+ visible to every hub login.
96
+ A legacy JSON `identity`/`password` value is still accepted. The manager's existing
97
+ Vault credential must renew unattended. Superuser credentials are not distributed
98
+ to nodes or needed for enrollment. Revocation produces action-required results.
99
+
100
+ Configure network monitors and alert thresholds once in the stock UI; these
101
+ settings are runtime application data, preserved in backups. Select explicit probe
102
+ origins rather than an all-to-all mesh. Use sustained resource-pressure alerts,
103
+ disk capacity, offline nodes and supported temperatures. Do not send notifications
104
+ until an authorized destination exists. Service-failure alert delivery has not
105
+ been accepted against this pinned release.
106
+
107
+ ## Stock backup and restore
108
+
109
+ 1. Open the hub's private PocketBase administration route `/_/` and authenticate
110
+ as its superuser. Keep that credential separate from fleet enrollment access.
111
+ 2. Open **Settings → Backups**. Create and download a backup before maintenance.
112
+ Set scheduled backups and retention there using existing authorized storage.
113
+ Do not provision a bucket or reuse unrelated credentials to bypass access gates.
114
+ 3. Protect downloaded archives as secrets: they contain registrations, tokens,
115
+ account data, alert configuration and history. Use the existing approved
116
+ encrypted backup destination; a backup on the same disk is not disaster recovery.
117
+ 4. Restore the archive into an isolated instance of the same pinned release with
118
+ outbound agent connections blocked. Use the stock upload/restore action, never
119
+ database edits. Restoring restarts the hub. Verify original node IDs, fingerprints,
120
+ history and settings before selecting a replacement host. Fence the old hub
121
+ before production recovery; never operate two copies of its identity.
122
+ 5. Run the manager command and require new metric timestamps after recovery.
123
+ Old historical samples do not prove agent connectivity.
124
+
125
+ ## Moving the hub to the manager
126
+
127
+ The hub previously ran on worker `worker-one` (`/var/lib/personal-beszel`,
128
+ Compose project `personal-beszel`). Move it once, as an operator, in this order;
129
+ never run two copies of its identity or two tunnel connectors:
130
+
131
+ 1. On the old hub host, create and download a stock backup (**Settings → Backups**) and keep
132
+ it as a secret.
133
+ 2. Fence the old hub on that host: `sudo docker compose -p personal-beszel down`
134
+ (stops the hub and its `cloudflared` connector; keep `/var/lib/personal-beszel`
135
+ untouched until the move is verified), then
136
+ `sudo tailscale serve --https=8443 off`.
137
+ 3. On the manager, with Docker Desktop running, run fleet-sync. It starts a fresh
138
+ hub, which creates the fleet account itself, and enrolls every worker. To keep
139
+ history instead, restore the backup afterwards through the stock **Backups**
140
+ upload/restore action as the superuser.
141
+ 4. Confirm fresh samples from every worker in the dashboard.
142
+ 5. Only after verification, remove the old host's hub data and its `beszel-hub-read`
143
+ Vault grant (OpenTofu).
144
+
145
+ `tests/upstream.py` exercises real pinned binaries with disposable loopback data:
146
+ authenticated registration, fresh metrics, restart identity preservation, no duplicate
147
+ record, and the supported PocketBase backup/restore API. It does not contact live
148
+ nodes, prove Tailscale routing, verify systemd reboot, or test an off-host encrypted
149
+ backup destination. Those remain explicit release/operational gates.
150
+
151
+ References: [agent](https://beszel.dev/guide/agent-installation),
152
+ [systemd](https://beszel.dev/guide/systemd),
153
+ [network monitors](https://beszel.dev/guide/network-monitors),
154
+ [backup API](https://pocketbase.io/docs/api-backups/).