@crvouga/dev-fleet 0.0.0-stage → 0.2.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.
- package/.mise/locks/aws-cdk/2.1146.1/aube-lock.yaml +24 -0
- package/.mise/locks/aws-cdk/2.1146.1/package.json +7 -0
- package/.mise/locks/azure-cli/2.91.0~a837e014/pyproject.toml +5 -0
- package/.mise/locks/azure-cli/2.91.0~a837e014/uv.lock +2794 -0
- package/.mise/locks/gemini/0.66.0~84aac8e6/aube-lock.yaml +123 -0
- package/.mise/locks/gemini/0.66.0~84aac8e6/package.json +12 -0
- package/.mise/locks/npm-devcontainers-cli/0.90.0/aube-lock.yaml +24 -0
- package/.mise/locks/npm-devcontainers-cli/0.90.0/package.json +7 -0
- package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/aube-lock.yaml +1432 -0
- package/.mise/locks/npm-modelcontextprotocol-inspector/2.13.0~4c109bea/package.json +7 -0
- package/.mise/locks/npm-vercel/65.8.0/aube-lock.yaml +3595 -0
- package/.mise/locks/npm-vercel/65.8.0/package.json +7 -0
- package/.mise/locks/npm-wrangler/4.156.0/aube-lock.yaml +895 -0
- package/.mise/locks/npm-wrangler/4.156.0/package.json +7 -0
- package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/aube-lock.yaml +24 -0
- package/.mise/locks/npm-yarnpkg-cli-dist/4.18.1/package.json +7 -0
- package/LICENSE +21 -0
- package/README.md +357 -2
- package/agents/antigravity-proxy.ts +3 -0
- package/agents/audit.md +89 -0
- package/agents/claude-proxy +5 -0
- package/agents/claude-proxy.ts +3 -0
- package/agents/codex-proxy.ts +3 -0
- package/agents/grok-proxy.ts +3 -0
- package/agents/managed-proxy.ts +55 -0
- package/agents/opencode-proxy.ts +3 -0
- package/agents/registry.json +209 -0
- package/agents/registry.schema.json +149 -0
- package/agents/setup.md +158 -0
- package/agents/t3.json +40 -0
- package/ansible/macos/manager.yml +30 -0
- package/ansible/macos/policy.json +9 -0
- package/ansible/monitoring/README.md +215 -0
- package/ansible/monitoring/agent-darwin.yml +198 -0
- package/ansible/monitoring/agent.yml +172 -0
- package/ansible/monitoring/beszel-agent.service +42 -0
- package/ansible/monitoring/compose.yml +74 -0
- package/ansible/monitoring/hub-darwin.yml +102 -0
- package/ansible/monitoring/hub-route-darwin.yml +51 -0
- package/ansible/monitoring/lock.json +16 -0
- package/ansible/net/remote-probe.sh +13 -0
- package/ansible/pyproject.toml +12 -0
- package/ansible/ubuntu/authorize-sudo.sh +51 -0
- package/ansible/ubuntu/baseline.yml +89 -0
- package/ansible/ubuntu/disk-gc.py +336 -0
- package/ansible/ubuntu/disk-guard.py +104 -0
- package/ansible/ubuntu/policy.json +52 -0
- package/ansible/ubuntu/recovery.yml +15 -0
- package/ansible/ubuntu/t3/policy.json +7 -0
- package/ansible/ubuntu/t3-desktop.yml +220 -0
- package/ansible/ubuntu/t3-health.sh +33 -0
- package/ansible/ubuntu/t3-policy.yml +76 -0
- package/ansible/ubuntu/t3-route.yml +28 -0
- package/ansible/ubuntu/tailscale.yml +78 -0
- package/ansible/ubuntu/tasks/credentials.yml +47 -0
- package/ansible/ubuntu/tasks/docker.yml +31 -0
- package/ansible/ubuntu/tasks/packages.yml +56 -0
- package/ansible/ubuntu/tasks/power.yml +51 -0
- package/ansible/ubuntu/tasks/recovery.yml +39 -0
- package/ansible/ubuntu/tasks/resources.yml +312 -0
- package/ansible/ubuntu/tasks/services.yml +31 -0
- package/ansible/ubuntu/tasks/ssh.yml +71 -0
- package/ansible/ubuntu/tasks/user.yml +120 -0
- package/ansible/uv.lock +190 -0
- package/bin/devfleet.mjs +36 -0
- package/bootstrap/bootstrap.ps1 +50 -0
- package/bootstrap/bootstrap.sh +80 -0
- package/bootstrap/devfleet +7 -0
- package/bootstrap/docker-desktop.sh +33 -0
- package/bootstrap/doctor.ts +234 -0
- package/bootstrap/fleet-manager-run.sh +103 -0
- package/bootstrap/fleet-remote-bootstrap.sh +258 -0
- package/bootstrap/global-config.ts +171 -0
- package/bootstrap/install-launcher.sh +10 -0
- package/bootstrap/native-aws.ts +86 -0
- package/bootstrap/native-t3.ts +154 -0
- package/bootstrap/npm.ts +358 -0
- package/bootstrap/release-version.ts +157 -0
- package/bootstrap/setup-status.ts +51 -0
- package/bootstrap/setup.ts +88 -0
- package/bootstrap/shell-path.ts +105 -0
- package/bootstrap/verify-t3-archive.py +49 -0
- package/bootstrap/worker-auth.ts +65 -0
- package/bootstrap/worker-github.ts +47 -0
- package/bootstrap/worker-tools.ts +24 -0
- package/cliproxy/AGENTS.md +11 -0
- package/cliproxy/README.md +269 -0
- package/cliproxy/clients/bootstrap.py +143 -0
- package/cliproxy/clients/launcher.py +57 -0
- package/cliproxy/compose.yaml +90 -0
- package/cliproxy/config.template.yaml +70 -0
- package/cliproxy/docs/cloud-adoption.md +16 -0
- package/cliproxy/docs/deployment.png +0 -0
- package/cliproxy/docs/deployment.svg +109 -0
- package/cliproxy/docs/health-workflow.example.yml +185 -0
- package/cliproxy/docs/migration.md +131 -0
- package/cliproxy/docs/model-health-report.schema.json +364 -0
- package/cliproxy/docs/model-health.md +393 -0
- package/cliproxy/image.lock.json +5 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-backup-check.plist +38 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-backup.plist +48 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-fleet.plist +32 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-gc.plist +38 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-monitor.plist +29 -0
- package/cliproxy/launchd/dev.devfleet.cliproxy-vault-renew.plist +31 -0
- package/cliproxy/models.json +1618 -0
- package/cliproxy/requirements.lock +78 -0
- package/cliproxy/scripts/accounts.py +38 -0
- package/cliproxy/scripts/audit.py +123 -0
- package/cliproxy/scripts/backup +234 -0
- package/cliproxy/scripts/check.py +34 -0
- package/cliproxy/scripts/checkpoint.py +226 -0
- package/cliproxy/scripts/cli.py +64 -0
- package/cliproxy/scripts/cliproxy_host.py +257 -0
- package/cliproxy/scripts/cloud_state.py +150 -0
- package/cliproxy/scripts/container-health +6 -0
- package/cliproxy/scripts/docker +24 -0
- package/cliproxy/scripts/external-health.py +79 -0
- package/cliproxy/scripts/fleet_config.py +43 -0
- package/cliproxy/scripts/fleet_sync.py +274 -0
- package/cliproxy/scripts/initialize +84 -0
- package/cliproxy/scripts/install-dependencies +48 -0
- package/cliproxy/scripts/install.py +406 -0
- package/cliproxy/scripts/model_health.py +16 -0
- package/cliproxy/scripts/modelhealth/__init__.py +5 -0
- package/cliproxy/scripts/modelhealth/checks.py +429 -0
- package/cliproxy/scripts/modelhealth/cli.py +117 -0
- package/cliproxy/scripts/modelhealth/config.py +186 -0
- package/cliproxy/scripts/modelhealth/emulator.py +536 -0
- package/cliproxy/scripts/modelhealth/expect.py +88 -0
- package/cliproxy/scripts/modelhealth/findings.py +183 -0
- package/cliproxy/scripts/modelhealth/protocol.py +330 -0
- package/cliproxy/scripts/modelhealth/redact.py +28 -0
- package/cliproxy/scripts/modelhealth/report.py +150 -0
- package/cliproxy/scripts/modelhealth/runner.py +390 -0
- package/cliproxy/scripts/modelhealth/scenario.py +131 -0
- package/cliproxy/scripts/modelhealth/schema.py +63 -0
- package/cliproxy/scripts/modelhealth/simulate.py +111 -0
- package/cliproxy/scripts/modelhealth/transport.py +213 -0
- package/cliproxy/scripts/monitor +68 -0
- package/cliproxy/scripts/ops +527 -0
- package/cliproxy/scripts/public-endpoint +127 -0
- package/cliproxy/scripts/recover_node.py +177 -0
- package/cliproxy/scripts/restore-verify +60 -0
- package/cliproxy/scripts/retention.py +144 -0
- package/cliproxy/scripts/service-start +7 -0
- package/cliproxy/scripts/validate-config +56 -0
- package/cliproxy/scripts/vault-access.py +57 -0
- package/cliproxy/scripts/vault-backup-login +55 -0
- package/cliproxy/scripts/vault-recovery +56 -0
- package/cliproxy/scripts/vault-renew +30 -0
- package/cliproxy/systemd/cliproxy-backup-check.service +10 -0
- package/cliproxy/systemd/cliproxy-backup-check.timer +8 -0
- package/cliproxy/systemd/cliproxy-backup.service +13 -0
- package/cliproxy/systemd/cliproxy-backup.timer +8 -0
- package/cliproxy/systemd/cliproxy-fleet.service +17 -0
- package/cliproxy/systemd/cliproxy-gc.service +13 -0
- package/cliproxy/systemd/cliproxy-gc.timer +8 -0
- package/cliproxy/systemd/cliproxy-monitor.service +8 -0
- package/cliproxy/systemd/cliproxy-monitor.timer +7 -0
- package/cliproxy/systemd/cliproxy-vault-renew.service +8 -0
- package/cliproxy/systemd/cliproxy-vault-renew.timer +7 -0
- package/cliproxy/vendor/LICENSE +22 -0
- package/cliproxy/vendor/config.upstream.yaml +1349 -0
- package/docs/consumer-setup.md +408 -0
- package/docs/declared.md +89 -0
- package/docs/machine-setup.md +399 -0
- package/docs/operations.md +276 -0
- package/docs/releasing.md +103 -0
- package/docs/state.md +254 -0
- package/docs/topology.md +67 -0
- package/docs/ubuntu-sync.md +351 -0
- package/docs/worker-contract.md +67 -0
- package/examples/fleet.json +100 -0
- package/examples/roster.json +13 -0
- package/llms.txt +35 -0
- package/mise.lock +1521 -0
- package/mise.toml +110 -0
- package/package.json +74 -4
- package/schema/fleet.schema.json +420 -0
- package/schema/roster.schema.json +77 -0
- package/src/agents/account-relay.ts +111 -0
- package/src/agents/accounts.ts +85 -0
- package/src/agents/audit.ts +77 -0
- package/src/agents/cli.ts +13 -0
- package/src/agents/command.ts +204 -0
- package/src/agents/converge.ts +123 -0
- package/src/agents/doctor.ts +107 -0
- package/src/agents/errors.ts +2 -0
- package/src/agents/files.ts +73 -0
- package/src/agents/fleet-verify.ts +165 -0
- package/src/agents/launch.ts +290 -0
- package/src/agents/native-verify.ts +371 -0
- package/src/agents/provider-errors.ts +57 -0
- package/src/agents/registry.ts +61 -0
- package/src/agents/render.ts +110 -0
- package/src/agents/round-trip.ts +192 -0
- package/src/agents/secrets.ts +13 -0
- package/src/agents/toolchain.ts +34 -0
- package/src/agents/verify-cache.ts +103 -0
- package/src/agents/verify.ts +127 -0
- package/src/auth-checks.ts +163 -0
- package/src/cli/agent-guide.ts +129 -0
- package/src/cli/app.ts +122 -0
- package/src/cli/cli.ts +28 -0
- package/src/cli/command-index.ts +57 -0
- package/src/cli/contracts.ts +25 -0
- package/src/cli/fleet-reference.ts +17 -0
- package/src/cli/fleet-state.ts +499 -0
- package/src/cli/fleet-sync-checkout.ts +130 -0
- package/src/cli/fleet-sync-enrollment.ts +140 -0
- package/src/cli/fleet-sync-forward.ts +134 -0
- package/src/cli/fleet-sync-manager.ts +249 -0
- package/src/cli/fleet-sync-monitoring.ts +185 -0
- package/src/cli/fleet-sync-output.ts +317 -0
- package/src/cli/fleet-sync-privilege.ts +27 -0
- package/src/cli/fleet-sync-progress.ts +109 -0
- package/src/cli/fleet-sync-remote.ts +242 -0
- package/src/cli/fleet-sync-report.ts +26 -0
- package/src/cli/fleet-sync-schedule.ts +138 -0
- package/src/cli/fleet-sync-state.ts +86 -0
- package/src/cli/fleet-sync-vault.ts +166 -0
- package/src/cli/fleet-sync.ts +375 -0
- package/src/cli/fleet.ts +165 -0
- package/src/cli/managed-health.ts +219 -0
- package/src/cli/node-deployment.ts +34 -0
- package/src/cli/node-sync.ts +121 -0
- package/src/cli/node-t3.ts +31 -0
- package/src/cli/options.ts +141 -0
- package/src/cli/probe-source.ts +7 -0
- package/src/cli/program.ts +185 -0
- package/src/cli/project.ts +51 -0
- package/src/cli/register-fleet.ts +296 -0
- package/src/cli/registry.ts +185 -0
- package/src/cli/repair-apply.ts +67 -0
- package/src/cli/repair-guard.ts +11 -0
- package/src/cli/repair-inspect.ts +150 -0
- package/src/cli/repair-script.ts +76 -0
- package/src/cli/repair.ts +209 -0
- package/src/cli/roster.ts +105 -0
- package/src/cli/search.ts +35 -0
- package/src/cli/settings.ts +67 -0
- package/src/cli/source-operations.ts +102 -0
- package/src/cli/t3/command.ts +90 -0
- package/src/cli/t3/register.ts +55 -0
- package/src/cli/tailnet.ts +127 -0
- package/src/cli/ui-actions.ts +133 -0
- package/src/cli/ui-controller.ts +113 -0
- package/src/cli/ui-data.ts +106 -0
- package/src/cli/ui-execute.ts +163 -0
- package/src/cli/ui-repairs.ts +34 -0
- package/src/cli/ui-reports.ts +211 -0
- package/src/cli/ui-targets.ts +100 -0
- package/src/cli/ui-terminal.ts +109 -0
- package/src/cli/ui-types.ts +49 -0
- package/src/cli/ui-wizard.ts +101 -0
- package/src/cli/ui.ts +9 -0
- package/src/cli/worker-health-output.ts +37 -0
- package/src/config.ts +186 -0
- package/src/configure.ts +255 -0
- package/src/definition.ts +290 -0
- package/src/diagnostics.ts +92 -0
- package/src/doctor-check.ts +10 -0
- package/src/errors.ts +1 -0
- package/src/fingerprint.ts +120 -0
- package/src/fleet-config.ts +174 -0
- package/src/input-hashes.ts +73 -0
- package/src/machine/local-source.ts +52 -0
- package/src/machine/lock-error.ts +2 -0
- package/src/machine/platform.ts +44 -0
- package/src/machine/source.ts +68 -0
- package/src/machine/state.ts +173 -0
- package/src/machine-health.ts +95 -0
- package/src/managed-source.ts +47 -0
- package/src/manager-failure.ts +48 -0
- package/src/manager-sync.ts +405 -0
- package/src/manager.ts +62 -0
- package/src/monitoring/agent-evidence.ts +146 -0
- package/src/monitoring/apply.ts +183 -0
- package/src/monitoring/beszel.ts +198 -0
- package/src/monitoring/enroll.ts +111 -0
- package/src/monitoring/hub-access.ts +114 -0
- package/src/monitoring/hub-backup.ts +121 -0
- package/src/monitoring/hub-viewer.ts +142 -0
- package/src/monitoring/hub.ts +93 -0
- package/src/monitoring/manager-agent.ts +73 -0
- package/src/monitoring/manager-hub.ts +248 -0
- package/src/monitoring/remote.ts +65 -0
- package/src/network-definition.ts +83 -0
- package/src/node-converge-linux.ts +374 -0
- package/src/node-converge-shared.ts +83 -0
- package/src/node-converge.ts +40 -0
- package/src/onboard.ts +35 -0
- package/src/package-info.ts +45 -0
- package/src/platform/ansible-receipt.ts +128 -0
- package/src/platform/ansible.ts +66 -0
- package/src/platform/darwin.ts +203 -0
- package/src/platform/detect.ts +11 -0
- package/src/platform/fallback.ts +110 -0
- package/src/platform/index.ts +38 -0
- package/src/platform/launchd.ts +98 -0
- package/src/platform/linux.ts +139 -0
- package/src/platform/ps.ts +45 -0
- package/src/platform/resource-verify.ts +132 -0
- package/src/platform/systemd-user.ts +95 -0
- package/src/platform/t3-policy.ts +137 -0
- package/src/platform/t3-route.ts +68 -0
- package/src/platform/t3-service.ts +75 -0
- package/src/platform/types.ts +123 -0
- package/src/platform/ubuntu-audit.ts +66 -0
- package/src/platform/ubuntu-verify.ts +105 -0
- package/src/platform/windows.ts +148 -0
- package/src/power-recovery.ts +55 -0
- package/src/probe.ts +51 -0
- package/src/protocol.ts +119 -0
- package/src/proxy-converge.ts +85 -0
- package/src/remote-bootstrap.ts +210 -0
- package/src/remote-entry.ts +89 -0
- package/src/remote-lock.ts +12 -0
- package/src/repair-catalog.ts +206 -0
- package/src/repair-plan.ts +78 -0
- package/src/repair-runner.ts +84 -0
- package/src/report.ts +71 -0
- package/src/runner.ts +104 -0
- package/src/secrets.ts +169 -0
- package/src/service-auth.ts +115 -0
- package/src/ssh.ts +135 -0
- package/src/state/bucket.ts +208 -0
- package/src/state/check.ts +74 -0
- package/src/state/connection.ts +92 -0
- package/src/state/enrollment.ts +45 -0
- package/src/state/legacy.ts +89 -0
- package/src/state/litestream.ts +143 -0
- package/src/state/operator.ts +20 -0
- package/src/state/paths.ts +40 -0
- package/src/state/roster.ts +62 -0
- package/src/state/store.ts +169 -0
- package/src/state/sync.ts +352 -0
- package/src/sync.ts +104 -0
- package/src/t3/accounts.ts +81 -0
- package/src/t3/desired.ts +165 -0
- package/src/t3/files.ts +81 -0
- package/src/t3/names-check.ts +53 -0
- package/src/t3/names.ts +155 -0
- package/src/t3/plan.ts +82 -0
- package/src/t3/providers.ts +74 -0
- package/src/t3/reconcile.ts +123 -0
- package/src/t3-endpoint.ts +104 -0
- package/src/t3-linked-check.ts +123 -0
- package/src/tailnet-health.ts +231 -0
- package/src/tailnet-matching.ts +37 -0
- package/src/tailscale.ts +141 -0
- package/src/toolchain-checks.ts +108 -0
- package/src/topology.ts +24 -0
- package/src/transport.ts +122 -0
- package/src/types.ts +99 -0
- package/src/vault-config.ts +38 -0
- package/src/worker-access-checks.ts +168 -0
- package/src/worker-capacity.ts +34 -0
- package/src/worker-host-checks.ts +181 -0
- package/src/worker-policy.ts +64 -0
- package/src/worker-readiness.ts +64 -0
- package/src/workstation-checks.ts +29 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
lockfileVersion: '9.0'
|
|
2
|
+
|
|
3
|
+
settings:
|
|
4
|
+
autoInstallPeers: true
|
|
5
|
+
excludeLinksFromLockfile: false
|
|
6
|
+
|
|
7
|
+
importers:
|
|
8
|
+
|
|
9
|
+
.:
|
|
10
|
+
dependencies:
|
|
11
|
+
'@yarnpkg/cli-dist':
|
|
12
|
+
specifier: 4.18.1
|
|
13
|
+
version: 4.18.1
|
|
14
|
+
|
|
15
|
+
packages:
|
|
16
|
+
|
|
17
|
+
'@yarnpkg/cli-dist@4.18.1':
|
|
18
|
+
resolution: {integrity: sha512-EH+A4TxAtBWXKE0DGQxW9Bo9crXHLJ73mfxjTQJuv8XonNWWTpei8BQ5JjczHJNU9GROTycwMFn8iOvRIZXUcA==}
|
|
19
|
+
engines: {node: '>=18.12.0'}
|
|
20
|
+
hasBin: true
|
|
21
|
+
|
|
22
|
+
snapshots:
|
|
23
|
+
|
|
24
|
+
'@yarnpkg/cli-dist@4.18.1': {}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dev-fleet contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,358 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dev-fleet
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Keeps a set of development machines in sync: one **manager** and many
|
|
4
|
+
**workers**. One command, `fleet-sync`, brings every machine to the same
|
|
5
|
+
pinned tools, the same coding agents signed in through one proxy, the same
|
|
6
|
+
uptime policy and the same monitoring. Adding or removing a machine is one
|
|
7
|
+
entry in `fleet.json`.
|
|
8
|
+
|
|
9
|
+
Status: extracted from a working three-machine fleet and in daily use there.
|
|
10
|
+
It has not yet been set up from nothing by a second person; expect rough edges
|
|
11
|
+
and read [what is assumed](#what-it-assumes) first.
|
|
12
|
+
|
|
13
|
+
## How you use it
|
|
14
|
+
|
|
15
|
+
You do not clone this repository. dev-fleet is a command you install, and your
|
|
16
|
+
fleet is a small project of your own:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
my-fleet/ your repository
|
|
20
|
+
fleet.json your machines, your services, the bucket that holds the state
|
|
21
|
+
package.json pins the dev-fleet version every machine runs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
You run `devfleet` from inside that project and pass it the credentials of a
|
|
25
|
+
storage bucket you own. Nothing else has to be kept:
|
|
26
|
+
|
|
27
|
+
| What | Where it lives |
|
|
28
|
+
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
29
|
+
| The fleet configuration | `fleet.json`, in your repository |
|
|
30
|
+
| The version of dev-fleet | The `@crvouga/dev-fleet` dependency in your `package.json` |
|
|
31
|
+
| The fleet state: the enrolled workers, the approved revision, the configuration applied | Your bucket (any S3-compatible service) |
|
|
32
|
+
| Secrets | The provider `fleet.json` names (`vault`, `sops`, `file` or `env`) |
|
|
33
|
+
| The source, checkouts, tools and reports dev-fleet puts on a machine | A cache: delete it and `fleet-sync` rebuilds it |
|
|
34
|
+
|
|
35
|
+
The CLI proxy and the monitoring hub on the manager still keep data of their
|
|
36
|
+
own; [known limits](#known-limits) says what is lost with the manager.
|
|
37
|
+
|
|
38
|
+
## What it assumes
|
|
39
|
+
|
|
40
|
+
dev-fleet is opinionated. These are part of it, not options:
|
|
41
|
+
|
|
42
|
+
- The **manager** is a macOS machine. You run `fleet-sync` on it, and it hosts
|
|
43
|
+
the shared services (the CLI proxy and the monitoring hub) in Docker Desktop.
|
|
44
|
+
- **Workers** are Ubuntu 26.04 machines reached over SSH. They are stateless:
|
|
45
|
+
everything on them is rebuilt from Git and your secrets.
|
|
46
|
+
- The fleet state is kept in an **S3-compatible bucket** you own.
|
|
47
|
+
- Machines reach each other over **Tailscale**.
|
|
48
|
+
- Coding agents (Claude Code, Codex, Grok, OpenCode, Antigravity) run through
|
|
49
|
+
**CLIProxyAPI** on the manager, and **T3 Code** lists one provider per
|
|
50
|
+
account signed in on the proxy.
|
|
51
|
+
- Machine policy is **Ansible** (`ansible/`), tool versions are **mise** pins
|
|
52
|
+
(`mise.toml`, `mise.lock`), monitoring is **Beszel**.
|
|
53
|
+
|
|
54
|
+
What dev-fleet puts on a machine is written in tracked files and pinned to a
|
|
55
|
+
version or digest. [What is declared, and where](docs/declared.md) lists it,
|
|
56
|
+
and what is not pinned yet.
|
|
57
|
+
|
|
58
|
+
What it does not assume is anything about you: no account, hostname, domain,
|
|
59
|
+
tailnet or repository is written in this code. They live in your `fleet.json`.
|
|
60
|
+
|
|
61
|
+
## Quickstart
|
|
62
|
+
|
|
63
|
+
Setting it up with a coding agent? Point it at
|
|
64
|
+
[`llms.txt`](llms.txt) or straight at
|
|
65
|
+
[Set up a fleet from your own project](docs/consumer-setup.md): the whole
|
|
66
|
+
procedure in one pass, including what the agent must ask you for and the
|
|
67
|
+
first sync only you can run. Both ship in the package, under
|
|
68
|
+
`node_modules/@crvouga/dev-fleet/`.
|
|
69
|
+
|
|
70
|
+
On the manager you need macOS with Git, Node 22 or newer, Docker Desktop and
|
|
71
|
+
Tailscale signed in. You also need an empty private bucket on any
|
|
72
|
+
S3-compatible service (AWS S3, Cloudflare R2, Backblaze B2, MinIO) and an
|
|
73
|
+
access key that can read and write it.
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
mkdir my-fleet && cd my-fleet && git init
|
|
77
|
+
npm init -y
|
|
78
|
+
npm install --save-dev --save-exact @crvouga/dev-fleet
|
|
79
|
+
|
|
80
|
+
npx devfleet fleet-state --example > fleet.json
|
|
81
|
+
$EDITOR fleet.json # your machines, and your bucket under "state"
|
|
82
|
+
|
|
83
|
+
export DEVFLEET_BUCKET_ACCESS_KEY_ID=…
|
|
84
|
+
export DEVFLEET_BUCKET_SECRET_ACCESS_KEY=…
|
|
85
|
+
npx devfleet fleet-sync --dry-run # preview
|
|
86
|
+
npx devfleet fleet-sync # apply
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Commit `fleet.json`, `package.json` and the lockfile. Keep the two credentials
|
|
90
|
+
out of Git: pass them from wherever you keep secrets (a password manager's
|
|
91
|
+
`run` command, a git-ignored `.env`, your shell). They are read from the
|
|
92
|
+
environment and never taken from arguments.
|
|
93
|
+
|
|
94
|
+
`fleet-sync` converges the manager first, then every worker over SSH. It
|
|
95
|
+
fetches the commit your dev-fleet version was published from, sends it and
|
|
96
|
+
your configuration to each machine, installs the pinned toolchain, applies the
|
|
97
|
+
Ansible policy and verifies the result. It prints one table and writes a full
|
|
98
|
+
JSON report. The first run on a machine installs everything, mise included, so
|
|
99
|
+
Git is the only tool it needs beforehand.
|
|
100
|
+
|
|
101
|
+
`--dry-run` changes no machine. On the manager it checks the release out into
|
|
102
|
+
dev-fleet's cache and installs the Bun that release pins beside any others, so
|
|
103
|
+
that it can run; it never installs the toolchain, publishes the global mise
|
|
104
|
+
configuration, edits shell profiles or touches a worker.
|
|
105
|
+
|
|
106
|
+
`devfleet` finds the closest `fleet.json` in the directory you run it from or
|
|
107
|
+
above it. `DEVFLEET_CONFIG` names a file elsewhere.
|
|
108
|
+
|
|
109
|
+
The CLI runs on [Bun](https://bun.sh), which the package brings as a
|
|
110
|
+
dependency. If your package manager does not run dependency install scripts,
|
|
111
|
+
allow Bun's or install Bun yourself; the CLI uses the one on `PATH`.
|
|
112
|
+
|
|
113
|
+
## The version
|
|
114
|
+
|
|
115
|
+
Every release of `@crvouga/dev-fleet` is published from one commit and names
|
|
116
|
+
it. The version in your `package.json` is therefore the revision of every
|
|
117
|
+
machine in the fleet:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
npx devfleet --version # 1.4.0 (commit 3f2a…)
|
|
121
|
+
npm install --save-dev --save-exact @crvouga/dev-fleet@latest
|
|
122
|
+
npx devfleet fleet-sync # the fleet moves to that release
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Install an older version and run `fleet-sync` to go back. The first worker
|
|
126
|
+
proves a new revision before the others receive it.
|
|
127
|
+
|
|
128
|
+
## Your project's own tools
|
|
129
|
+
|
|
130
|
+
On a fleet machine the global mise configuration (`~/.config/mise/config.toml`
|
|
131
|
+
and its `mise.lock`) belongs to dev-fleet: `fleet-sync` publishes it with the
|
|
132
|
+
fleet's pinned tools and the agent worktree roots mise must trust. A project
|
|
133
|
+
pins its own tools in its own `mise.toml` and installs them with
|
|
134
|
+
`mise install --locked` in its checkout. It never publishes a global
|
|
135
|
+
configuration. If anything replaces dev-fleet's, `fleet-status` fails the check
|
|
136
|
+
`tool:global-mise-config` until the next `fleet-sync`.
|
|
137
|
+
|
|
138
|
+
## Using it from code
|
|
139
|
+
|
|
140
|
+
dev-fleet has no library API. The package is the `devfleet` command: it
|
|
141
|
+
declares no `main` or `exports`, and nothing under `src/`, `bootstrap/` or
|
|
142
|
+
`ansible/` is a supported import. Any release, a patch included, may change
|
|
143
|
+
them, and some modules read the fleet configuration as soon as they are
|
|
144
|
+
imported. If your project needs something dev-fleet does, ask for a command in
|
|
145
|
+
an [issue](#bugs-and-feature-requests).
|
|
146
|
+
|
|
147
|
+
## State
|
|
148
|
+
|
|
149
|
+
Your bucket is the source of truth for everything Git does not hold: the
|
|
150
|
+
roster of enrolled workers, the approved revision, and the configuration
|
|
151
|
+
`fleet-sync` last applied. It is one SQLite database that
|
|
152
|
+
[Litestream](https://litestream.io) replicates to the bucket. `fleet.json`
|
|
153
|
+
says where the bucket is and the command is passed its credentials:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
"state": {
|
|
157
|
+
"bucket": "my-fleet-state",
|
|
158
|
+
"endpoint": "https://ACCOUNT.r2.cloudflarestorage.com",
|
|
159
|
+
"region": "auto"
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
npx devfleet fleet-state # where the state is, and how it stands with the bucket
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The copy on the manager is disposable. **To replace the manager**, clone your
|
|
168
|
+
project on the new machine and run the same two commands:
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
npm ci
|
|
172
|
+
npx devfleet fleet-sync # with the two bucket credentials in the environment
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The roster and the approved revision come back from the bucket, and the
|
|
176
|
+
machine is rebuilt from Git.
|
|
177
|
+
|
|
178
|
+
Some runs are started by a machine rather than by you: a worker that hands
|
|
179
|
+
`fleet-sync` to the manager, for example. They get no environment, so save the
|
|
180
|
+
credentials on the manager once (in `~/.config/dev-fleet/bucket.json`,
|
|
181
|
+
readable by you alone):
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
npx devfleet fleet-state --init
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Without a bucket everything still works from the local copy, and `fleet-sync`
|
|
188
|
+
warns that the manager holds the only one. [docs/state.md](docs/state.md)
|
|
189
|
+
explains how replication stays correct, how to move an existing fleet to a
|
|
190
|
+
project, and which state is not in the bucket yet.
|
|
191
|
+
|
|
192
|
+
## Add or remove a machine
|
|
193
|
+
|
|
194
|
+
1. Set up SSH from the manager to the new Ubuntu box (a non-root user with
|
|
195
|
+
sudo) and join it to your tailnet.
|
|
196
|
+
2. Add it under `workers` in your `fleet.json` and commit:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"id": "worker-three",
|
|
201
|
+
"ssh": "worker-three",
|
|
202
|
+
"os": "linux",
|
|
203
|
+
"network": {
|
|
204
|
+
"tailscaleName": "worker-three.tail0a1b2c.ts.net",
|
|
205
|
+
"sshPort": 22,
|
|
206
|
+
"user": "dev",
|
|
207
|
+
"t3Port": 3773
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
3. Run `fleet-sync`. A machine that has only an SSH server and an account
|
|
213
|
+
with sudo is enough: every pull request proves that against a bare
|
|
214
|
+
Ubuntu machine, over SSH
|
|
215
|
+
([`fresh-box.feature`](features/fresh-box/fresh-box.feature)).
|
|
216
|
+
|
|
217
|
+
Remove a machine by deleting its entry and running `fleet-sync`.
|
|
218
|
+
|
|
219
|
+
## Configuration
|
|
220
|
+
|
|
221
|
+
Your `fleet.json` is validated by
|
|
222
|
+
[`schema/fleet.schema.json`](schema/fleet.schema.json), which the installed
|
|
223
|
+
package carries: `fleet-state --example` prints a complete example that points
|
|
224
|
+
`$schema` at it, so an editor checks the file as you type.
|
|
225
|
+
[`examples/fleet.json`](examples/fleet.json) is the same example.
|
|
226
|
+
|
|
227
|
+
| Block | What it declares |
|
|
228
|
+
| ---------- | ------------------------------------------------------------------- |
|
|
229
|
+
| `source` | The Git repository nodes accept code from (this one, or your fork) |
|
|
230
|
+
| `state` | The bucket that holds the fleet state; never its credentials |
|
|
231
|
+
| `secrets` | Where secrets are kept: `env`, `file`, `sops` or `vault` |
|
|
232
|
+
| `manager` | The one macOS manager |
|
|
233
|
+
| `workers` | The Ubuntu workers |
|
|
234
|
+
| `services` | The proxy's public origin and the monitoring dashboard and accounts |
|
|
235
|
+
| `worker` | Policy every worker must meet |
|
|
236
|
+
|
|
237
|
+
Secrets are asked for by purpose (`proxy-client-key`,
|
|
238
|
+
`monitoring-account-password`, `monitoring-tunnel-token`,
|
|
239
|
+
`proxy-tunnel-token`); see [`src/secrets.ts`](src/secrets.ts).
|
|
240
|
+
|
|
241
|
+
`fleet-sync` records the configuration it applies in the fleet state, so a
|
|
242
|
+
run started outside your project uses the one last applied.
|
|
243
|
+
`fleet-state --export` prints it.
|
|
244
|
+
|
|
245
|
+
To run your own fork, publish it as your own package and name its repository
|
|
246
|
+
under `source`: the commit a package names must be reachable there.
|
|
247
|
+
|
|
248
|
+
## Bugs and feature requests
|
|
249
|
+
|
|
250
|
+
A defect in dev-fleet, or something it cannot do yet, is raised as an
|
|
251
|
+
[issue](https://github.com/crvouga/dev-fleet/issues). From your project that
|
|
252
|
+
is the only way to change dev-fleet, for you and for the coding agents working
|
|
253
|
+
there. Do not patch the installed package, a checkout `fleet-sync` put on a
|
|
254
|
+
machine or a file it manages: the next install or `fleet-sync` replaces them.
|
|
255
|
+
|
|
256
|
+
The tool says so itself: `devfleet --help` names the issue tracker, and the
|
|
257
|
+
agent contract (`devfleet commands --json`, under `agent.support`) carries the
|
|
258
|
+
rule, what an issue should include and what it must leave out. Agents only
|
|
259
|
+
read it if your project sends them there, so put this in the `AGENTS.md` of
|
|
260
|
+
the project that holds your `fleet.json`:
|
|
261
|
+
|
|
262
|
+
```md
|
|
263
|
+
The fleet is managed with dev-fleet (`npx devfleet`, pinned in package.json).
|
|
264
|
+
Read `npx devfleet commands --json` before using it. Never edit dev-fleet
|
|
265
|
+
itself: not node_modules, not a clone, not what it installs on a machine. A
|
|
266
|
+
bug in dev-fleet or a feature it lacks is a GitHub issue at
|
|
267
|
+
https://github.com/crvouga/dev-fleet/issues; tell me what is blocked and link
|
|
268
|
+
it. Issues are public: no credentials, hostnames, accounts, domains or
|
|
269
|
+
fleet.json contents.
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Known limits
|
|
273
|
+
|
|
274
|
+
- Each worker's own login and renewal, and the proxy's backup and recovery,
|
|
275
|
+
are implemented for the **`vault`** secrets provider only. With `env`, `file`
|
|
276
|
+
or `sops` the fleet's three shared secrets are read, but those two features
|
|
277
|
+
are not available yet.
|
|
278
|
+
- The bucket holds the fleet's own state. The CLI proxy keeps its separate
|
|
279
|
+
encrypted backup (`vault` only), and the monitoring hub's database is not
|
|
280
|
+
replicated: `fleet-sync` recreates its accounts and systems, but metric
|
|
281
|
+
history is lost with the manager. See
|
|
282
|
+
[what is not in the bucket yet](docs/state.md#what-is-not-in-the-bucket-yet).
|
|
283
|
+
- Caches and units on machines still use the historical `personal` prefix
|
|
284
|
+
(`~/.local/share/personal/fleet`, `/etc/personal-fleet`, unit names). It
|
|
285
|
+
works, and renaming it needs a migration.
|
|
286
|
+
- The CLI proxy's installed code is a Git worktree of the manager's copy of
|
|
287
|
+
the source repository (`~/.local/share/personal/fleet/manager/source`).
|
|
288
|
+
`fleet-sync` fetches that copy again when it is deleted, but the proxy then
|
|
289
|
+
needs `devfleet cliproxy install` once more.
|
|
290
|
+
- The manager is a Mac host. There is no container image of the manager.
|
|
291
|
+
- `fleet-sync --schedule enable` (unattended runs on a timer) is not available
|
|
292
|
+
from the published package yet, so nothing re-applies the fleet until you
|
|
293
|
+
run `fleet-sync`.
|
|
294
|
+
- Not everything on a machine is pinned. [What is declared, and
|
|
295
|
+
where](docs/declared.md) lists what is and what is not: most of a worker's
|
|
296
|
+
own packages, the manager's applications and every login are outside it.
|
|
297
|
+
- The reference documents under `docs/` were written for the fleet this came
|
|
298
|
+
from and are being revised.
|
|
299
|
+
|
|
300
|
+
## Repository layout
|
|
301
|
+
|
|
302
|
+
| Path | What |
|
|
303
|
+
| ------------ | ----------------------------------------------------------------- |
|
|
304
|
+
| `src/` | Inventory, orchestration, verification, the report; `src/cli` CLI |
|
|
305
|
+
| `src/state/` | The fleet state database and its replication to the bucket |
|
|
306
|
+
| `ansible/` | Machine policy: `ubuntu/`, `macos/`, `monitoring/` |
|
|
307
|
+
| `agents/` | Agent launchers T3 runs, and their registry |
|
|
308
|
+
| `cliproxy/` | The CLIProxyAPI service: install, audit, backup, model health |
|
|
309
|
+
| `bootstrap/` | Toolchain bootstrap and the manager and worker entry scripts |
|
|
310
|
+
| `schema/` | JSON schemas for `fleet.json` and the private roster |
|
|
311
|
+
| `examples/` | A complete example configuration |
|
|
312
|
+
| `features/` | What dev-fleet does, as Gherkin features: the tests |
|
|
313
|
+
| `bin/` | The entry point of the published package |
|
|
314
|
+
|
|
315
|
+
## Develop
|
|
316
|
+
|
|
317
|
+
Working on dev-fleet itself is the only reason to clone it:
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
git clone https://github.com/crvouga/dev-fleet.git && cd dev-fleet
|
|
321
|
+
bash bootstrap/bootstrap.sh
|
|
322
|
+
bun install --frozen-lockfile
|
|
323
|
+
bun run check
|
|
324
|
+
./devfleet fleet-status --local # the CLI, from this checkout
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Run from a checkout, `fleet-sync` converges the fleet to the checkout's `HEAD`
|
|
328
|
+
commit (never to uncommitted files). The checkout's `origin` must be the
|
|
329
|
+
repository `fleet.json` names under `source`. Every merge to `main` publishes a release;
|
|
330
|
+
see [releasing](docs/releasing.md).
|
|
331
|
+
|
|
332
|
+
What dev-fleet does is specified in Gherkin, under
|
|
333
|
+
[`features/`](features/README.md): a `.feature` file states a rule in plain
|
|
334
|
+
words and the steps beside it check it. There are no other TypeScript tests.
|
|
335
|
+
`bun run check` runs formatting, typecheck, lint, every feature and the proxy
|
|
336
|
+
package's Python tests. Features run against `examples/fleet.json` and never
|
|
337
|
+
contact a real machine.
|
|
338
|
+
|
|
339
|
+
Every pull request runs these checks ([`ci.yml`](.github/workflows/ci.yml)):
|
|
340
|
+
|
|
341
|
+
| Check | What it proves |
|
|
342
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
343
|
+
| Check | `bun run check` |
|
|
344
|
+
| Fleet state | The pinned Litestream replicates the fleet state to a directory and to an S3 API, and a second manager restores it |
|
|
345
|
+
| Fresh worker over SSH | A new Ubuntu machine with only an SSH server and sudo is bootstrapped by the production code over real SSH, on amd64 and on arm64 |
|
|
346
|
+
| Workflows | The workflow files pass `actionlint` |
|
|
347
|
+
|
|
348
|
+
Some scenarios need something a laptop may not have, and are skipped there:
|
|
349
|
+
|
|
350
|
+
```sh
|
|
351
|
+
DEVFLEET_TEST_FRESH_BOX=1 bun test features/fresh-box # Docker; tests the HEAD commit
|
|
352
|
+
mise install litestream
|
|
353
|
+
DEVFLEET_TEST_S3=http://127.0.0.1:5000 bun test features/state
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## License
|
|
357
|
+
|
|
358
|
+
MIT. See [LICENSE](LICENSE).
|
package/agents/audit.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Agent configuration audit and ownership
|
|
2
|
+
|
|
3
|
+
Audited against the checked-in tool pins and client source, installed T3 source
|
|
4
|
+
`322f6544dfad0a3c8a0c8cbecf2c7f7874b14268`, and linked vendor documentation.
|
|
5
|
+
This is a compatibility inventory, not a claim that all desktop apps or fleet
|
|
6
|
+
nodes were inspected or authenticated. The execution host exposes Codex, Claude
|
|
7
|
+
and T3 on PATH; the mise catalog additionally includes Gemini, Copilot and OpenCode.
|
|
8
|
+
Cursor and Antigravity are desktop prerequisites, not mise-managed binaries.
|
|
9
|
+
|
|
10
|
+
| Source/owner | Installed destination | Scope |
|
|
11
|
+
| ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
12
|
+
| `mise.toml`, `mise.lock`, `.mise/locks/`; bootstrap | Global mise config, shims and installed tools | Versions; no authentication |
|
|
13
|
+
| `agents/registry.json`; dev-fleet | Dedicated profile outputs described below | Endpoint, models, secret references, node model overrides |
|
|
14
|
+
| `cli/lib/agents/render.ts`; dev-fleet | `ROOT/NODE/codex/{direct,proxy}/config.toml` | Separate CODEX_HOME, Responses HTTP/SSE provider declaration |
|
|
15
|
+
| same | `ROOT/NODE/claude/{direct,proxy}/settings.json` | Passed using native --settings; process environment routes proxy |
|
|
16
|
+
| same | `ROOT/NODE/opencode/{direct,proxy}/opencode.json` | OPENCODE_CONFIG, environment key placeholder |
|
|
17
|
+
| same | `ROOT/NODE/gemini/direct/.gemini/settings.json` | GEMINI_CLI_HOME is the profile root; independent native login |
|
|
18
|
+
| `cli/lib/agents/converge.ts`; dev-fleet | Each profile's receipt.json; ROOT/backups | Nonsecret fingerprints/revision; private migration backups |
|
|
19
|
+
| Existing `opencode/provider-secrets.ts`, OpenRouter package; dev-fleet | Platform OpenCode directory/opencode.json | Vault provider catalog, OpenRouter auto policy; existing sync embeds private keys with mode 0600 |
|
|
20
|
+
| Existing OpenCode plugins/bin and cli/lib/links.ts; dev-fleet | Platform OpenCode plugins/bin, tui.json, notifier files | Notification plugins, sounds, platform-derived app paths |
|
|
21
|
+
| `agents/codex-proxy.ts`; dev-fleet | T3 binaryPath points directly into reviewed Git checkout | Runtime Vault injection; WS_AGENT_NODE is a declared machine value |
|
|
22
|
+
| `agents/t3.json`; personal T3 reconciler | T3CODE_HOME/userdata/settings.json | Owned provider instances only; plan/apply/import/cleanup and private ownership state |
|
|
23
|
+
| `../fleet/definition.json`, cli/lib/net; dev-fleet | Managed SSH block and VS Code Remote-SSH settings | Existing machine aliases, OS/user/identity public paths and T3 ports; no private keys |
|
|
24
|
+
| `.agents/commands/*.md`; agents:sync | Harness command symlinks | Canonical agent commands; do not edit copies |
|
|
25
|
+
| Root AGENTS.md, CLAUDE.md, GEMINI.md, .github/copilot-instructions.md | Repository instruction discovery | Same canonical repository rules |
|
|
26
|
+
| Existing cliproxy clients/bootstrap.py and launcher.py | ~/.config/cliproxy-fleet; ~/.local/bin/*-fleet | Legacy opt-in migration boundary; native settings preserved |
|
|
27
|
+
| Fleet configure | checkout/node_modules/.fleet-revisions/SHA; .fleet-configuration/*.json | Pinned Git deployment worktrees and per-selection rollout receipts |
|
|
28
|
+
|
|
29
|
+
ROOT is `~/.config/personal/agents` on macOS/Linux and
|
|
30
|
+
`%USERPROFILE%\AppData\Local\personal\agents` on native Windows. Home and platform
|
|
31
|
+
are documented machine-derived inputs. The explicit `--node` ID selects checked-in
|
|
32
|
+
`nodes[ID][TOOL].direct` or `.proxy` model overrides over shared defaults. The local
|
|
33
|
+
fleet roster contains connection aliases/paths, not configuration values or secrets.
|
|
34
|
+
|
|
35
|
+
The registry is the portable profile source. Native project settings, organization
|
|
36
|
+
policies, MCP servers, skills and plugins can still affect tools through their
|
|
37
|
+
vendor precedence. These are not silently imported from a home directory. Existing
|
|
38
|
+
home MCP definitions, user skills, marketplace caches and desktop settings remain
|
|
39
|
+
unmanaged until reviewed and added to an appropriate canonical repository source.
|
|
40
|
+
Do not treat the registry as a complete export of arbitrary installed applications.
|
|
41
|
+
Usage tracking in CLIProxyAPI/T3 is independent from the inference route.
|
|
42
|
+
|
|
43
|
+
## Compatibility and authentication evidence
|
|
44
|
+
|
|
45
|
+
- [Codex configuration](https://learn.chatgpt.com/docs/config-file/config-reference):
|
|
46
|
+
CODEX_HOME, model_providers, env_key and wire_api. Direct profiles have separate
|
|
47
|
+
login state. T3 source confirms homePath and binaryPath per provider instance.
|
|
48
|
+
- [Claude gateway](https://code.claude.com/docs/en/llm-gateway-connect) and
|
|
49
|
+
[settings](https://code.claude.com/docs/en/settings): native settings-file override
|
|
50
|
+
plus ANTHROPIC_BASE_URL/AUTH_TOKEN. The registry declares `claude-sonnet-4-6`; availability and authentication are checked separately.
|
|
51
|
+
- [OpenCode](https://opencode.ai/docs/config/): OPENCODE_CONFIG merges with native
|
|
52
|
+
configuration; environment placeholders avoid persisting the proxy key. Direct
|
|
53
|
+
OpenRouter defaults remain owned by the existing provider sync.
|
|
54
|
+
- [Gemini CLI](https://geminicli.com/docs/reference/configuration/): native settings,
|
|
55
|
+
GEMINI_CLI_HOME and Google/API-key/Vertex authentication are distinct. Pinned 0.66.0 also supports `gateway` authentication, `GOOGLE_GEMINI_BASE_URL` and a runtime `GEMINI_API_KEY`; the managed proxy adapter uses those native interfaces. Live native-client acceptance remains unverified.
|
|
56
|
+
- [Cursor](https://prod.cursor.com/help/models-and-usage/api-keys): supported API-key
|
|
57
|
+
setup uses Settings > Models; some features continue through Cursor. No supported
|
|
58
|
+
unattended portable credential/settings adapter was established; no SQLite edits.
|
|
59
|
+
- [Antigravity](https://antigravity.google/docs/settings): native Google identity and
|
|
60
|
+
settings are distinct from Gemini CLI. No verified arbitrary proxy-routing adapter.
|
|
61
|
+
- [Copilot](https://docs.github.com/en/copilot/how-tos/copilot-cli): native independent
|
|
62
|
+
GitHub authentication. No proxy integration is claimed.
|
|
63
|
+
|
|
64
|
+
Runtime OAuth, auth.json, keychains, T3 pairing/control-plane tokens, SSH private
|
|
65
|
+
keys, session databases, conversations, histories, caches and plugin downloaded
|
|
66
|
+
state are never profile source. Never export or copy them between nodes. Backups
|
|
67
|
+
may preserve preexisting local contents and therefore stay private, outside Git.
|
|
68
|
+
New proxy profiles read only Vault `secret/data/personal/prd` field
|
|
69
|
+
`CLIPROXY_FLEET_CLIENT_API_KEY`; neither generated configs nor receipts contain it.
|
|
70
|
+
Missing access fails without retaining Vault responses. No secret is seeded here.
|
|
71
|
+
|
|
72
|
+
## Fleet provider routes
|
|
73
|
+
|
|
74
|
+
The registry’s `proxy.routes` declares the shared accounts (Claude, Codex,
|
|
75
|
+
Gemini, Grok, Muse, Antigravity). Grok Build and the Antigravity CLI are pinned
|
|
76
|
+
native clients with proxy profiles (Grok: `GROK_HOME/config.toml` custom model
|
|
77
|
+
with `env_key`; Antigravity: Gemini API-key mode with `GOOGLE_GEMINI_BASE_URL`).
|
|
78
|
+
Muse runs through the OpenCode harness: native Muse Code only talks to Meta's
|
|
79
|
+
own catalog endpoint. Cursor is not managed (it cannot use the proxy). T3's
|
|
80
|
+
Antigravity instance uses T3's own runtime with the proxy key in T3's per-host
|
|
81
|
+
secret store. See the fleet guide's "Agents on every node".
|
|
82
|
+
Version-specific source evidence:
|
|
83
|
+
[Gemini 0.66.0 gateway interface](https://github.com/google-gemini/gemini-cli/blob/v0.66.0/packages/core/src/core/contentGenerator.ts),
|
|
84
|
+
[CLIProxyAPI 8.0.55 catalog](https://github.com/router-for-me/CLIProxyAPI/blob/v8.0.55/internal/registry/models/models.json).
|
|
85
|
+
A catalog entry is only a supported identifier, not proof that Chris has an
|
|
86
|
+
active account for it. Fleet verifies authenticated availability, inference,
|
|
87
|
+
stream completion and a harmless echo-tool round trip. Native application/T3
|
|
88
|
+
acceptance is recorded separately. Runtime Vault access must work without an
|
|
89
|
+
interactive shell; missing renewal authorization remains action required.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# T3 binaryPath for Claude. The Claude Agent SDK runs any path ending in .ts
|
|
3
|
+
# with node, so T3 needs an extension-less executable; this runs the tracked
|
|
4
|
+
# Bun launcher beside it. No generated copy: this file lives in Git.
|
|
5
|
+
exec bun "${0%/*}/claude-proxy.ts" "$@"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** T3 binaryPath adapter. This file remains in Git; no generated executable copies. */
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { currentPlatform } from '../src/platform';
|
|
4
|
+
import { agentRoot } from '../src/agents/render';
|
|
5
|
+
import { select } from '../src/agents/registry';
|
|
6
|
+
import { plan } from '../src/agents/converge';
|
|
7
|
+
import { launchProfile } from '../src/agents/launch';
|
|
8
|
+
import { AgentConfigurationError } from '../src/agents/errors';
|
|
9
|
+
import { pinnedPath } from '../src/agents/toolchain';
|
|
10
|
+
|
|
11
|
+
const SYNC_HINT =
|
|
12
|
+
'Run devfleet fleet-sync from a terminal to repair this machine.';
|
|
13
|
+
|
|
14
|
+
export async function runManagedProxy(
|
|
15
|
+
tool: 'codex' | 'opencode' | 'claude' | 'grok' | 'antigravity'
|
|
16
|
+
): Promise<void> {
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
// Version probes need no credentials; answering them lets T3 report the real
|
|
19
|
+
// launch error instead of "unable to determine version".
|
|
20
|
+
if (args.length === 1 && ['--version', '-v'].includes(args[0]!)) {
|
|
21
|
+
process.exitCode = await Bun.spawn([tool, ...args], {
|
|
22
|
+
env: { ...process.env, PATH: pinnedPath() },
|
|
23
|
+
stdio: ['inherit', 'inherit', 'inherit'],
|
|
24
|
+
}).exited;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const selection = select(process.env['WS_AGENT_NODE'] ?? '', tool, 'proxy');
|
|
29
|
+
const root = agentRoot(homedir(), currentPlatform().name);
|
|
30
|
+
const result = await plan({ root, selection, revision: 'unverified' });
|
|
31
|
+
if (
|
|
32
|
+
!result.previous ||
|
|
33
|
+
result.previous.fingerprint !== result.fingerprint ||
|
|
34
|
+
result.files.some((file) => file.state !== 'unchanged')
|
|
35
|
+
)
|
|
36
|
+
throw new AgentConfigurationError(
|
|
37
|
+
`The ${tool} proxy profile for node ${selection.node} is missing or out of date.`
|
|
38
|
+
);
|
|
39
|
+
// T3 sets WS_AGENT_ACCOUNT on a provider that is pinned to one account.
|
|
40
|
+
process.exitCode = await launchProfile(
|
|
41
|
+
root,
|
|
42
|
+
selection,
|
|
43
|
+
args,
|
|
44
|
+
process.env['WS_AGENT_ACCOUNT'] || undefined
|
|
45
|
+
);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Configuration errors carry curated, secret-free messages; others do not.
|
|
48
|
+
const reason =
|
|
49
|
+
error instanceof AgentConfigurationError
|
|
50
|
+
? error.message
|
|
51
|
+
: 'Managed provider proxy unavailable.';
|
|
52
|
+
process.stderr.write(`${reason} ${SYNC_HINT}\n`);
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
}
|
|
55
|
+
}
|