@appforge-ci/admin-cli 0.1.1
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/LICENSE +21 -0
- package/README.md +70 -0
- package/dist/commands/agents.d.ts +55 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +436 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/agents.test.d.ts +2 -0
- package/dist/commands/agents.test.d.ts.map +1 -0
- package/dist/commands/agents.test.js +127 -0
- package/dist/commands/agents.test.js.map +1 -0
- package/dist/commands/login.d.ts +38 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/login.test.d.ts +2 -0
- package/dist/commands/login.test.d.ts.map +1 -0
- package/dist/commands/login.test.js +69 -0
- package/dist/commands/login.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/bootstrap.d.ts +21 -0
- package/dist/lib/bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap.js +242 -0
- package/dist/lib/bootstrap.js.map +1 -0
- package/dist/lib/bootstrap.test.d.ts +2 -0
- package/dist/lib/bootstrap.test.d.ts.map +1 -0
- package/dist/lib/bootstrap.test.js +59 -0
- package/dist/lib/bootstrap.test.js.map +1 -0
- package/dist/lib/config.d.ts +27 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +61 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/config.test.d.ts +2 -0
- package/dist/lib/config.test.d.ts.map +1 -0
- package/dist/lib/config.test.js +120 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/prompt.d.ts +11 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +54 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/prompt.test.d.ts +2 -0
- package/dist/lib/prompt.test.d.ts.map +1 -0
- package/dist/lib/prompt.test.js +22 -0
- package/dist/lib/prompt.test.js.map +1 -0
- package/dist/lib/two-factor.d.ts +21 -0
- package/dist/lib/two-factor.d.ts.map +1 -0
- package/dist/lib/two-factor.js +31 -0
- package/dist/lib/two-factor.js.map +1 -0
- package/dist/lib/two-factor.test.d.ts +2 -0
- package/dist/lib/two-factor.test.d.ts.map +1 -0
- package/dist/lib/two-factor.test.js +51 -0
- package/dist/lib/two-factor.test.js.map +1 -0
- package/dist/test-support/home-sandbox.d.ts +3 -0
- package/dist/test-support/home-sandbox.d.ts.map +1 -0
- package/dist/test-support/home-sandbox.js +47 -0
- package/dist/test-support/home-sandbox.js.map +1 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AppForge CI 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
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @appforge-ci/admin-cli
|
|
2
|
+
|
|
3
|
+
`appforge-admin` — the platform-operator CLI for fleet management (enroll,
|
|
4
|
+
list, drain, resume, reboot, run maintenance scripts on Mac minis). This
|
|
5
|
+
is a **separate** tool from `appforge` (`packages/cli`), which is for
|
|
6
|
+
AppForge's customers and has no fleet commands at all — see
|
|
7
|
+
`docs/self-hosting.md`'s "Fleet management" section for why they're kept
|
|
8
|
+
apart. Config lives in `~/.appforge-admin/config.json`, independent of
|
|
9
|
+
`~/.appforge/config.json`.
|
|
10
|
+
|
|
11
|
+
For the full day-to-day runbook (reading fleet status, troubleshooting a
|
|
12
|
+
`NotReady`/`offline` mini, rotating tokens, decommissioning) once this is
|
|
13
|
+
installed, see **`docs/fleet-management.md`**.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
**On a machine that already has this repo cloned** (the common case —
|
|
18
|
+
your own laptop, or a Mac mini you `git clone`d onto): build it and put
|
|
19
|
+
it on `PATH` with `npm link`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm install # once, from the repo root
|
|
23
|
+
pnpm --filter @appforge-ci/admin-cli build
|
|
24
|
+
cd packages/admin-cli && npm link # symlinks `appforge-admin` onto PATH
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`npm link` needs to be re-run only if the symlink itself ever gets
|
|
28
|
+
removed (e.g. `npm uninstall -g @appforge-ci/admin-cli`) — a plain
|
|
29
|
+
rebuild (`pnpm --filter @appforge-ci/admin-cli build`) is enough to pick
|
|
30
|
+
up code changes afterwards, since the link points at `dist/` in place.
|
|
31
|
+
|
|
32
|
+
**From npm, once published:** `.github/workflows/publish.yml` publishes
|
|
33
|
+
this package (tag-triggered, `git tag vX.Y.Z && git push origin vX.Y.Z`),
|
|
34
|
+
but that workflow needs an `NPM_TOKEN` repo secret that **isn't
|
|
35
|
+
configured yet** — until it is and a version has actually been published,
|
|
36
|
+
`npm install -g @appforge-ci/admin-cli` will 404. The `npm link` path
|
|
37
|
+
above is what actually works today.
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
appforge-admin login --api-url <api-url> --admin-api-url <admin-api-url> # once; add --web to approve in a browser instead of typing your password here
|
|
43
|
+
appforge-admin agents list
|
|
44
|
+
appforge-admin agents add-mac --name "my-mac-mini" # run ON the mini you're enrolling — see docs/self-hosting.md
|
|
45
|
+
appforge-admin agents add-mac --force # re-enroll THIS Mac (rotate token / rename) — same fleet row, never a duplicate
|
|
46
|
+
appforge-admin agents decommission <agentId> # permanently remove a mini (retired machine, or a stale duplicate row)
|
|
47
|
+
appforge-admin agents drain <agentId>
|
|
48
|
+
appforge-admin agents resume <agentId>
|
|
49
|
+
appforge-admin agents reboot <agentId>
|
|
50
|
+
appforge-admin agents restart <agentId> # just the agent process (e.g. after a manual upgrade) — no reboot needed
|
|
51
|
+
appforge-admin agents cancel-build <agentId> <buildId> # kill one wedged build, other concurrent builds on the same mini untouched
|
|
52
|
+
appforge-admin agents allow-remote-control <agentId> --on|--off # authorize (or revoke) the VNC "Connect" button's mouse/keyboard control — off by default for every agent
|
|
53
|
+
appforge-admin agents run-script <agentId> <scriptName>
|
|
54
|
+
appforge-admin agents commands <agentId> [--limit 20] # remote-command history + who issued each one — see docs/fleet-management.md
|
|
55
|
+
appforge-admin agents update <agentId> [--to <version>] # roll one mini onto a new agent build (OTA) — see docs/fleet-management.md
|
|
56
|
+
appforge-admin agents update --all # every enrolled mini, one at a time
|
|
57
|
+
appforge-admin agents bootstrap [--full] # install missing toolchains on THIS Mac
|
|
58
|
+
appforge-admin agents enroll # advanced: just a token, no local enrollment — see add-mac instead
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`--api-url`/`--admin-api-url` only need passing on that first `login` —
|
|
62
|
+
they're saved to `~/.appforge-admin/config.json` and reused after that.
|
|
63
|
+
Only accounts listed in the admin-api Worker's `PLATFORM_ADMIN_EMAILS`
|
|
64
|
+
secret can actually log in here; see `docs/self-hosting.md`.
|
|
65
|
+
|
|
66
|
+
The password-based `login` (not `--web`) prompts interactively for a 2FA
|
|
67
|
+
code if the account has it enabled and neither `--totp-code` nor
|
|
68
|
+
`--recovery-code` was passed — see `docs/security.md`'s "2FA (TOTP)"
|
|
69
|
+
note. `login --web`'s device-authorization flow has no password step at
|
|
70
|
+
all, so it's unaffected either way.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { ApiClient, type AgentCommand } from "@appforge-ci/core";
|
|
3
|
+
/**
|
|
4
|
+
* Polls `GET /agents/:agentId/commands` for one specific command (an
|
|
5
|
+
* UPDATE_AGENT the CLI just sent) until it leaves `pending`/`acked` for a
|
|
6
|
+
* terminal `done`/`failed`, or `timeoutMs` runs out. The agent only picks
|
|
7
|
+
* a command up on its next ~15s heartbeat and a real self-update (npm
|
|
8
|
+
* install / git checkout + pnpm build) can take real minutes, so this is
|
|
9
|
+
* a genuine wait, not a quick round-trip — see `--timeout`.
|
|
10
|
+
*
|
|
11
|
+
* Exported (and `pollIntervalMs` made overridable) purely for direct
|
|
12
|
+
* testing — every real call site still gets the production
|
|
13
|
+
* `UPDATE_POLL_INTERVAL_MS` default; a test injects a near-zero interval
|
|
14
|
+
* so exercising "it actually loops a few times before resolving" doesn't
|
|
15
|
+
* mean a real multi-second wait.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Parses `agents update`'s `--timeout <seconds>` option — pulled out so
|
|
19
|
+
* it's directly testable, same "test seam via extraction" shape this
|
|
20
|
+
* monorepo already uses for CLI flag parsing (`packages/cli/src/lib/
|
|
21
|
+
* parse-rollout.ts`, `packages/agent/src/lib/parse-args.ts`).
|
|
22
|
+
* `Number(opts.timeout)` alone isn't enough: a non-numeric value (a
|
|
23
|
+
* plausible typo like `"5m"`, meant as "5 minutes" — the option's own
|
|
24
|
+
* description just says "seconds") parses to `NaN`, and
|
|
25
|
+
* `waitForCommandResolution`'s deadline math (`Date.now() + timeoutMs`)
|
|
26
|
+
* then becomes `NaN` too — `Date.now() >= NaN` is always `false`, so the
|
|
27
|
+
* command polls forever instead of ever timing out (with `--all`, that
|
|
28
|
+
* hangs the whole fleet rollout). Returns `null` for anything that isn't
|
|
29
|
+
* a finite, positive number of seconds, so the caller can fail fast with
|
|
30
|
+
* a clear error instead of a silent infinite poll.
|
|
31
|
+
*/
|
|
32
|
+
export declare function parseTimeoutSeconds(raw: string): number | null;
|
|
33
|
+
/**
|
|
34
|
+
* `agents commands <agentId>`'s per-row line, pulled out so it's
|
|
35
|
+
* directly testable — same "extract the one real piece of logic" shape
|
|
36
|
+
* `parseTimeoutSeconds` above already established. Every layer below
|
|
37
|
+
* this command already existed and was already tested
|
|
38
|
+
* (`ApiClient.listAgentCommands`, `GET /agents/:agentId/commands`,
|
|
39
|
+
* `packages/db/src/agents.ts`'s `listAgentCommands` LEFT JOIN on
|
|
40
|
+
* `User`) — only a CLI command to call it and print it was missing.
|
|
41
|
+
* `docs/fleet-management.md`'s own "Auditing who ran what" section used
|
|
42
|
+
* to tell a reader there was "still no CLI/dashboard view" for the full
|
|
43
|
+
* history or the issuing admin's email, and to fall back to a raw
|
|
44
|
+
* `curl` — this command is that view. `issuedByEmail` prints as
|
|
45
|
+
* "system/auto" rather than a blank/undefined for a command with none
|
|
46
|
+
* (issued before this was tracked, or a since-deleted account), so the
|
|
47
|
+
* output never looks like a formatting bug. `[AUTO-ROLLBACK]` prefixes
|
|
48
|
+
* an UPDATE_AGENT OTA/self-update Phase 4 auto-issued after detecting a
|
|
49
|
+
* stuck update (`AgentCommand.isAutoRollback`) — otherwise this and an
|
|
50
|
+
* ordinary UPDATE_AGENT look identical in the audit trail.
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatAgentCommandLine(cmd: Pick<AgentCommand, "type" | "status" | "result" | "createdAt" | "issuedByEmail" | "isAutoRollback">): string;
|
|
53
|
+
export declare function waitForCommandResolution(api: ApiClient, agentId: string, commandId: string, timeoutMs: number, pollIntervalMs?: number): Promise<AgentCommand | null>;
|
|
54
|
+
export declare function registerAgentsCommands(program: Command): void;
|
|
55
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,SAAS,EAMT,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAqB3B;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,eAAe,GAAG,gBAAgB,CAAC,GACvG,MAAM,CAIR;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,MAAgC,GAC/C,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAS9B;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,QAyZtD"}
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { ApiClient, computeAgentReadiness, effectiveAgentStatus, isAgentVersionCurrent, parseActiveBuildIds, CURRENT_AGENT_VERSION, } from "@appforge-ci/core";
|
|
4
|
+
import { collectSystemInfo } from "@appforge-ci/agent/dist/lib/system-info.js";
|
|
5
|
+
import { saveConfig as saveAgentConfig, configPath as agentConfigPath } from "@appforge-ci/agent/dist/lib/config.js";
|
|
6
|
+
import { loadAdminCliConfig } from "../lib/config.js";
|
|
7
|
+
import { installAgentLaunchAgent, stableNodePath } from "@appforge-ci/agent/dist/lib/launchd.js";
|
|
8
|
+
import { AGENT_VERSION } from "@appforge-ci/agent/dist/lib/version.js";
|
|
9
|
+
import { AgentApi } from "@appforge-ci/agent/dist/lib/api.js";
|
|
10
|
+
import { installDeviceStreamIfPresent, syncDeviceStreamFleetSecrets } from "@appforge-ci/agent/dist/lib/device-stream-install.js";
|
|
11
|
+
import { bootstrapSafeToolchains, bootstrapPrivileged } from "../lib/bootstrap.js";
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
const UPDATE_POLL_INTERVAL_MS = 5000;
|
|
14
|
+
function client() {
|
|
15
|
+
const cfg = loadAdminCliConfig();
|
|
16
|
+
return {
|
|
17
|
+
cfg,
|
|
18
|
+
api: new ApiClient({ baseUrl: cfg.apiUrl, token: cfg.token, adminApiUrl: cfg.adminApiUrl }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Polls `GET /agents/:agentId/commands` for one specific command (an
|
|
23
|
+
* UPDATE_AGENT the CLI just sent) until it leaves `pending`/`acked` for a
|
|
24
|
+
* terminal `done`/`failed`, or `timeoutMs` runs out. The agent only picks
|
|
25
|
+
* a command up on its next ~15s heartbeat and a real self-update (npm
|
|
26
|
+
* install / git checkout + pnpm build) can take real minutes, so this is
|
|
27
|
+
* a genuine wait, not a quick round-trip — see `--timeout`.
|
|
28
|
+
*
|
|
29
|
+
* Exported (and `pollIntervalMs` made overridable) purely for direct
|
|
30
|
+
* testing — every real call site still gets the production
|
|
31
|
+
* `UPDATE_POLL_INTERVAL_MS` default; a test injects a near-zero interval
|
|
32
|
+
* so exercising "it actually loops a few times before resolving" doesn't
|
|
33
|
+
* mean a real multi-second wait.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Parses `agents update`'s `--timeout <seconds>` option — pulled out so
|
|
37
|
+
* it's directly testable, same "test seam via extraction" shape this
|
|
38
|
+
* monorepo already uses for CLI flag parsing (`packages/cli/src/lib/
|
|
39
|
+
* parse-rollout.ts`, `packages/agent/src/lib/parse-args.ts`).
|
|
40
|
+
* `Number(opts.timeout)` alone isn't enough: a non-numeric value (a
|
|
41
|
+
* plausible typo like `"5m"`, meant as "5 minutes" — the option's own
|
|
42
|
+
* description just says "seconds") parses to `NaN`, and
|
|
43
|
+
* `waitForCommandResolution`'s deadline math (`Date.now() + timeoutMs`)
|
|
44
|
+
* then becomes `NaN` too — `Date.now() >= NaN` is always `false`, so the
|
|
45
|
+
* command polls forever instead of ever timing out (with `--all`, that
|
|
46
|
+
* hangs the whole fleet rollout). Returns `null` for anything that isn't
|
|
47
|
+
* a finite, positive number of seconds, so the caller can fail fast with
|
|
48
|
+
* a clear error instead of a silent infinite poll.
|
|
49
|
+
*/
|
|
50
|
+
export function parseTimeoutSeconds(raw) {
|
|
51
|
+
const seconds = Number(raw);
|
|
52
|
+
return Number.isFinite(seconds) && seconds > 0 ? seconds : null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* `agents commands <agentId>`'s per-row line, pulled out so it's
|
|
56
|
+
* directly testable — same "extract the one real piece of logic" shape
|
|
57
|
+
* `parseTimeoutSeconds` above already established. Every layer below
|
|
58
|
+
* this command already existed and was already tested
|
|
59
|
+
* (`ApiClient.listAgentCommands`, `GET /agents/:agentId/commands`,
|
|
60
|
+
* `packages/db/src/agents.ts`'s `listAgentCommands` LEFT JOIN on
|
|
61
|
+
* `User`) — only a CLI command to call it and print it was missing.
|
|
62
|
+
* `docs/fleet-management.md`'s own "Auditing who ran what" section used
|
|
63
|
+
* to tell a reader there was "still no CLI/dashboard view" for the full
|
|
64
|
+
* history or the issuing admin's email, and to fall back to a raw
|
|
65
|
+
* `curl` — this command is that view. `issuedByEmail` prints as
|
|
66
|
+
* "system/auto" rather than a blank/undefined for a command with none
|
|
67
|
+
* (issued before this was tracked, or a since-deleted account), so the
|
|
68
|
+
* output never looks like a formatting bug. `[AUTO-ROLLBACK]` prefixes
|
|
69
|
+
* an UPDATE_AGENT OTA/self-update Phase 4 auto-issued after detecting a
|
|
70
|
+
* stuck update (`AgentCommand.isAutoRollback`) — otherwise this and an
|
|
71
|
+
* ordinary UPDATE_AGENT look identical in the audit trail.
|
|
72
|
+
*/
|
|
73
|
+
export function formatAgentCommandLine(cmd) {
|
|
74
|
+
const resultTag = cmd.result ? ` result:${cmd.result}` : "";
|
|
75
|
+
const rollbackTag = cmd.isAutoRollback === 1 ? "[AUTO-ROLLBACK] " : "";
|
|
76
|
+
return `${cmd.createdAt} ${rollbackTag}${cmd.type.padEnd(22)} ${cmd.status.padEnd(8)} by:${cmd.issuedByEmail ?? "system/auto"}${resultTag}`;
|
|
77
|
+
}
|
|
78
|
+
export async function waitForCommandResolution(api, agentId, commandId, timeoutMs, pollIntervalMs = UPDATE_POLL_INTERVAL_MS) {
|
|
79
|
+
const deadline = Date.now() + timeoutMs;
|
|
80
|
+
for (;;) {
|
|
81
|
+
const { commands } = await api.listAgentCommands(agentId, 20);
|
|
82
|
+
const command = commands.find((c) => c.id === commandId);
|
|
83
|
+
if (command && (command.status === "done" || command.status === "failed"))
|
|
84
|
+
return command;
|
|
85
|
+
if (Date.now() >= deadline)
|
|
86
|
+
return null;
|
|
87
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function registerAgentsCommands(program) {
|
|
91
|
+
const agents = program.command("agents").description("Manage the Mac mini build fleet");
|
|
92
|
+
agents
|
|
93
|
+
.command("list")
|
|
94
|
+
.action(async () => {
|
|
95
|
+
const { cfg, api } = client();
|
|
96
|
+
const { agents } = await api.listAgents(cfg.orgId);
|
|
97
|
+
for (const a of agents) {
|
|
98
|
+
const { ready } = computeAgentReadiness(a);
|
|
99
|
+
// Not a.status directly — see effectiveAgentStatus's docblock in
|
|
100
|
+
// @appforge-ci/core: the raw column freezes at whatever the mini last
|
|
101
|
+
// heartbeated and never becomes "offline" on its own.
|
|
102
|
+
const status = effectiveAgentStatus(a);
|
|
103
|
+
// isAgentVersionCurrent is null for a row with no reported version
|
|
104
|
+
// yet (pre-migrations/0011, or hasn't (re-)enrolled/heartbeated
|
|
105
|
+
// since) — print nothing for that case rather than guessing.
|
|
106
|
+
const versionSuffix = a.agentVersion === null
|
|
107
|
+
? ""
|
|
108
|
+
: isAgentVersionCurrent(a.agentVersion)
|
|
109
|
+
? ` agent v${a.agentVersion}`
|
|
110
|
+
: ` agent v${a.agentVersion} (outdated — latest is v${CURRENT_AGENT_VERSION})`;
|
|
111
|
+
// See docs/fleet-management.md's "Concurrent builds" section —
|
|
112
|
+
// one Mac mini can run more than one build at once now.
|
|
113
|
+
const slots = `${parseActiveBuildIds(a.activeBuildIds).length}/${a.maxConcurrentBuilds}`;
|
|
114
|
+
console.log(`${a.id} ${a.name.padEnd(20)} ${status.padEnd(10)} slots ${slots.padEnd(5)} ${(ready ? "Ready" : "NotReady").padEnd(9)} cpu ${a.cpuUsagePercent}% mem ${a.memUsagePercent}% disk free ${a.diskFreeGb}GB last seen ${a.lastSeenAt}${versionSuffix}`);
|
|
115
|
+
}
|
|
116
|
+
if (agents.length === 0)
|
|
117
|
+
console.log("No Mac minis enrolled yet. Run 'appforge-admin agents add-mac' on the Mac mini you want to add.");
|
|
118
|
+
});
|
|
119
|
+
agents
|
|
120
|
+
.command("enroll")
|
|
121
|
+
.description("Generate a one-time enrollment token for a new Mac mini (advanced — see 'add-mac' for the one-command version)")
|
|
122
|
+
.action(async () => {
|
|
123
|
+
const { cfg, api } = client();
|
|
124
|
+
const { enrollmentToken, expiresAt } = await api.createEnrollmentToken(cfg.orgId);
|
|
125
|
+
console.log(`Enrollment token (expires ${expiresAt}):\n`);
|
|
126
|
+
console.log(` ${enrollmentToken}\n`);
|
|
127
|
+
console.log("On the Mac mini, run:");
|
|
128
|
+
console.log(` appforge-agent enroll --api-url ${cfg.adminApiUrl} --token ${enrollmentToken} --name <mac-mini-name>`);
|
|
129
|
+
});
|
|
130
|
+
agents
|
|
131
|
+
.command("bootstrap")
|
|
132
|
+
.description("Install missing build toolchains on THIS Mac (Homebrew + PATH wiring only, no sudo) — run before 'add-mac' if any toolchain shows 'not found'")
|
|
133
|
+
.option("--full", "Also apply infra/mac-mini-setup/bootstrap.sh's privileged, dedicated-mini-only setup: a sudoers rule for remote reboot, disables sleep, full Xcode reinstall. Appropriate for a dedicated always-on Mac mini, NOT a machine you use day to day.")
|
|
134
|
+
.action(async (opts) => {
|
|
135
|
+
await bootstrapSafeToolchains();
|
|
136
|
+
if (opts.full) {
|
|
137
|
+
console.log("\n==> --full requested: applying privileged/system changes (sudoers, sleep, Xcode)...");
|
|
138
|
+
bootstrapPrivileged();
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
agents
|
|
142
|
+
.command("add-mac")
|
|
143
|
+
.description("Enroll THIS Mac as a build agent and start it running in the background, in one step — run this ON the Mac mini you want to add (must already be 'appforge-admin login'd)")
|
|
144
|
+
.option("--name <name>", "Name for this Mac in the fleet (default: its hostname)")
|
|
145
|
+
.option("--force", "Re-enroll even though this Mac already has an agent config. The control plane dedupes on hardware UUID, so this updates the existing fleet record rather than adding a second one — use it to rotate the agent token or change the name.")
|
|
146
|
+
.action(async (opts) => {
|
|
147
|
+
const { cfg, api } = client();
|
|
148
|
+
// Guard against the classic double-enrollment: someone runs add-mac
|
|
149
|
+
// again on a Mac that's already in the fleet. Server-side dedup (on
|
|
150
|
+
// hardware UUID) means a re-enroll now updates the existing row
|
|
151
|
+
// rather than creating a duplicate, but it still mints a new agent
|
|
152
|
+
// token and restarts the daemon, which is rarely what you want by
|
|
153
|
+
// accident — so require --force to say you meant it.
|
|
154
|
+
if (existsSync(agentConfigPath()) && !opts.force) {
|
|
155
|
+
let existing = {};
|
|
156
|
+
try {
|
|
157
|
+
existing = JSON.parse(readFileSync(agentConfigPath(), "utf8"));
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
/* unreadable/corrupt — fall through with blanks */
|
|
161
|
+
}
|
|
162
|
+
console.error(`This Mac is already enrolled as "${existing.name ?? "?"}" (${existing.agentId ?? "?"}).\n` +
|
|
163
|
+
`Config: ${agentConfigPath()}\n\n` +
|
|
164
|
+
` • Just (re)install the background service: appforge-agent install-service\n` +
|
|
165
|
+
` • Repair a broken/rotated token or rename: appforge-admin agents add-mac --force\n` +
|
|
166
|
+
` • Retire this machine from the fleet: appforge-admin agents decommission ${existing.agentId ?? "<agentId>"}\n`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
console.log("Reading this Mac's info and build toolchains (this can take a moment — flutter --version isn't instant)...");
|
|
170
|
+
const info = await collectSystemInfo();
|
|
171
|
+
console.log(` Xcode: ${info.xcodeVersion ?? "not found"}`);
|
|
172
|
+
console.log(` Flutter: ${info.flutterVersion ?? "not found"}`);
|
|
173
|
+
console.log(` Java: ${info.javaVersion ?? "not found"}`);
|
|
174
|
+
console.log(` Android SDK: ${info.androidSdkVersion ?? "not found"}`);
|
|
175
|
+
console.log(` CocoaPods: ${info.cocoapodsVersion ?? "not found"}`);
|
|
176
|
+
// Same computeAgentReadiness the fleet dashboard uses — see its
|
|
177
|
+
// docblock in @appforge-ci/core. Printed here too so add-mac's own
|
|
178
|
+
// output doesn't silently disagree with what the dashboard says
|
|
179
|
+
// once this Mac shows up in it. Assumes "online" with a fresh
|
|
180
|
+
// lastSeenAt since that's the state this enrollment is about to set.
|
|
181
|
+
const { androidReady, iosReady, flutterReady, ready } = computeAgentReadiness({
|
|
182
|
+
...info,
|
|
183
|
+
status: "online",
|
|
184
|
+
lastSeenAt: new Date().toISOString(),
|
|
185
|
+
});
|
|
186
|
+
console.log(`\n Fleet readiness: ${ready ? "Ready" : "NotReady"}` +
|
|
187
|
+
` (Android build ${androidReady ? "✓" : "✗"}, iOS build ${iosReady ? "✓" : "✗"}, Flutter build ${flutterReady ? "✓" : info.flutterVersion === null ? "✗ Flutter SDK missing" : "✗ needs Android or iOS toolchain too"})`);
|
|
188
|
+
if (!ready) {
|
|
189
|
+
console.log(" Neither platform toolchain is complete — run 'appforge-admin agents bootstrap' first (or, for a dedicated always-on mini, ./infra/mac-mini-setup/bootstrap.sh).");
|
|
190
|
+
}
|
|
191
|
+
console.log("\nRequesting a one-time enrollment token...");
|
|
192
|
+
const { enrollmentToken } = await api.createEnrollmentToken(cfg.orgId);
|
|
193
|
+
const name = opts.name ?? info.hostname;
|
|
194
|
+
console.log(`Enrolling as "${name}"...`);
|
|
195
|
+
const enrollRes = await fetch(`${cfg.adminApiUrl}/agents/enroll`, {
|
|
196
|
+
method: "POST",
|
|
197
|
+
headers: { "content-type": "application/json" },
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
enrollmentToken,
|
|
200
|
+
name,
|
|
201
|
+
machineId: info.machineId,
|
|
202
|
+
hostname: info.hostname,
|
|
203
|
+
macOsVersion: info.macOsVersion,
|
|
204
|
+
xcodeVersion: info.xcodeVersion,
|
|
205
|
+
flutterVersion: info.flutterVersion,
|
|
206
|
+
javaVersion: info.javaVersion,
|
|
207
|
+
androidSdkVersion: info.androidSdkVersion,
|
|
208
|
+
cocoapodsVersion: info.cocoapodsVersion,
|
|
209
|
+
cpuModel: info.cpuModel,
|
|
210
|
+
agentVersion: AGENT_VERSION,
|
|
211
|
+
}),
|
|
212
|
+
});
|
|
213
|
+
if (!enrollRes.ok) {
|
|
214
|
+
console.error(`Enrollment failed: ${enrollRes.status} ${await enrollRes.text()}`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
const { agentId, agentToken } = (await enrollRes.json());
|
|
218
|
+
saveAgentConfig({ apiUrl: cfg.adminApiUrl, agentId, agentToken, name });
|
|
219
|
+
console.log(`Enrolled as agent ${agentId}. Config saved to ${agentConfigPath()}.`);
|
|
220
|
+
console.log("\nInstalling as a background service (survives reboot/logout, no sudo needed)...");
|
|
221
|
+
const agentDistIndexPath = require.resolve("@appforge-ci/agent/dist/index.js");
|
|
222
|
+
// Same version-pinned-Cellar-node footgun packages/agent's own
|
|
223
|
+
// install-service already dodges (see stableNodePath's docblock) —
|
|
224
|
+
// process.execPath here is whatever ran `appforge-admin` itself, and
|
|
225
|
+
// baking that straight into the plist means the next `brew upgrade
|
|
226
|
+
// node` deletes it out from under launchd. add-mac is the documented
|
|
227
|
+
// one-command onboarding path, so it needs the same fix, not just
|
|
228
|
+
// packages/agent/src/index.ts's installService().
|
|
229
|
+
const nodePath = stableNodePath(process.execPath);
|
|
230
|
+
const { plistPath, logPath } = installAgentLaunchAgent(nodePath, agentDistIndexPath);
|
|
231
|
+
console.log(` Service: ${plistPath}`);
|
|
232
|
+
console.log(` Logs: tail -f ${logPath}`);
|
|
233
|
+
// Folds apps/device-stream's own persistent-service setup into this
|
|
234
|
+
// one-command onboarding path too — same shape
|
|
235
|
+
// packages/agent/src/index.ts's installService() already
|
|
236
|
+
// establishes for the plain `appforge-agent install-service` path
|
|
237
|
+
// (see that file's own docblock for exactly when this does/doesn't
|
|
238
|
+
// fire). A no-op (or an explained skip) never fails add-mac itself:
|
|
239
|
+
// the build agent's own service above is what this command must
|
|
240
|
+
// always succeed at installing.
|
|
241
|
+
const deviceStreamApi = new AgentApi({ apiUrl: cfg.adminApiUrl, agentToken });
|
|
242
|
+
let deviceStream;
|
|
243
|
+
try {
|
|
244
|
+
({ outcome: deviceStream } = await syncDeviceStreamFleetSecrets({
|
|
245
|
+
api: deviceStreamApi,
|
|
246
|
+
agentDistIndexPath,
|
|
247
|
+
nodePath,
|
|
248
|
+
apiUrl: cfg.adminApiUrl,
|
|
249
|
+
env: process.env,
|
|
250
|
+
agentId,
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
console.warn(`Couldn't fetch this org's fleet secrets (${err.message}) — ` +
|
|
255
|
+
`falling back to whatever is set in this shell's environment.`);
|
|
256
|
+
deviceStream = await installDeviceStreamIfPresent(agentDistIndexPath, nodePath, cfg.adminApiUrl, process.env, {}, undefined, undefined, agentId);
|
|
257
|
+
}
|
|
258
|
+
if (deviceStream.message)
|
|
259
|
+
console.log(deviceStream.message);
|
|
260
|
+
console.log(`\nDone — "${name}" is enrolled and already polling for builds.`);
|
|
261
|
+
console.log(`Manage it with: launchctl {start|stop|unload} com.appforge.agent`);
|
|
262
|
+
console.log(`Un-enroll later with the same fleet commands you'd use for any Mac mini (see 'appforge-admin agents --help').`);
|
|
263
|
+
});
|
|
264
|
+
agents
|
|
265
|
+
.command("drain <agentId>")
|
|
266
|
+
.description("Stop an agent from leasing new builds once its current build finishes")
|
|
267
|
+
.action(async (agentId) => {
|
|
268
|
+
const { api } = client();
|
|
269
|
+
await api.sendAgentCommand(agentId, "DRAIN");
|
|
270
|
+
console.log("Drain command sent.");
|
|
271
|
+
});
|
|
272
|
+
agents
|
|
273
|
+
.command("resume <agentId>")
|
|
274
|
+
.action(async (agentId) => {
|
|
275
|
+
const { api } = client();
|
|
276
|
+
await api.sendAgentCommand(agentId, "RESUME");
|
|
277
|
+
console.log("Resume command sent.");
|
|
278
|
+
});
|
|
279
|
+
agents
|
|
280
|
+
.command("reboot <agentId>")
|
|
281
|
+
.description("Reboot the Mac mini (agent must have the sudoers entry from infra/mac-mini-setup)")
|
|
282
|
+
.action(async (agentId) => {
|
|
283
|
+
const { api } = client();
|
|
284
|
+
await api.sendAgentCommand(agentId, "REBOOT_HOST");
|
|
285
|
+
console.log("Reboot command sent.");
|
|
286
|
+
});
|
|
287
|
+
agents
|
|
288
|
+
.command("restart <agentId>")
|
|
289
|
+
.description("Restart just the agent process on a Mac mini (e.g. after upgrading the agent version by hand) " +
|
|
290
|
+
"— it acks done, then re-execs; launchd brings it back up immediately, no reboot needed")
|
|
291
|
+
.action(async (agentId) => {
|
|
292
|
+
const { api } = client();
|
|
293
|
+
await api.sendAgentCommand(agentId, "RESTART_AGENT");
|
|
294
|
+
console.log("Restart command sent.");
|
|
295
|
+
});
|
|
296
|
+
agents
|
|
297
|
+
.command("cancel-build <agentId> <buildId>")
|
|
298
|
+
.description("Kill one specific build running on this Mac mini, leaving any other concurrent build on it untouched " +
|
|
299
|
+
"(unlike restart/reboot, which abandon everything on the machine) — see docs/fleet-management.md")
|
|
300
|
+
.action(async (agentId, buildId) => {
|
|
301
|
+
const { api } = client();
|
|
302
|
+
await api.sendAgentCommand(agentId, "CANCEL_BUILD", undefined, undefined, buildId);
|
|
303
|
+
console.log(`Cancel command sent for build ${buildId}.`);
|
|
304
|
+
});
|
|
305
|
+
agents
|
|
306
|
+
.command("run-script <agentId> <scriptName>")
|
|
307
|
+
.description("Run a named maintenance script from the agent's local allowlist")
|
|
308
|
+
.action(async (agentId, scriptName) => {
|
|
309
|
+
const { api } = client();
|
|
310
|
+
await api.sendAgentCommand(agentId, "RUN_MAINTENANCE_SCRIPT", scriptName);
|
|
311
|
+
console.log(`Maintenance script "${scriptName}" queued.`);
|
|
312
|
+
});
|
|
313
|
+
agents
|
|
314
|
+
.command("commands <agentId>")
|
|
315
|
+
.description("Show recent remote-management commands sent to a Mac mini (drain/resume/reboot/update/...), their status, and who issued them")
|
|
316
|
+
.option("--limit <n>", "How many to show (server caps at 50)", "20")
|
|
317
|
+
.action(async (agentId, opts) => {
|
|
318
|
+
const { api } = client();
|
|
319
|
+
const { commands } = await api.listAgentCommands(agentId, Number(opts.limit));
|
|
320
|
+
if (commands.length === 0) {
|
|
321
|
+
console.log("No commands sent to this agent yet.");
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
for (const cmd of commands) {
|
|
325
|
+
console.log(formatAgentCommandLine(cmd));
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
agents
|
|
329
|
+
.command("update [agentId]")
|
|
330
|
+
.description("Roll a Mac mini onto a new @appforge-ci/agent build via the UPDATE_AGENT remote command (drains, waits out any in-flight build, self-updates, then re-execs)")
|
|
331
|
+
.option("--to <version>", "npm version (or, for a repo-checkout install, a git ref) to update to — omit for latest")
|
|
332
|
+
.option("--all", "Update every enrolled Mac mini, one at a time — a bad agent build only ever takes down the one mini currently updating, never the whole fleet at once")
|
|
333
|
+
.option("--timeout <seconds>", "How long to wait for each mini to ack done/failed before giving up", "600")
|
|
334
|
+
.action(async (agentId, opts) => {
|
|
335
|
+
const { cfg, api } = client();
|
|
336
|
+
if (!opts.all && !agentId) {
|
|
337
|
+
console.error("Specify an agentId, or pass --all to update every enrolled Mac mini one at a time.");
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
const { agents: fleet } = await api.listAgents(cfg.orgId);
|
|
341
|
+
const targets = opts.all ? fleet : fleet.filter((a) => a.id === agentId);
|
|
342
|
+
if (targets.length === 0) {
|
|
343
|
+
console.error(opts.all
|
|
344
|
+
? "No Mac minis enrolled yet."
|
|
345
|
+
: `No agent ${agentId} in this org. 'appforge-admin agents list' shows the current fleet.`);
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
const timeoutSeconds = parseTimeoutSeconds(opts.timeout);
|
|
349
|
+
if (timeoutSeconds === null) {
|
|
350
|
+
console.error(`--timeout must be a positive number of seconds, got "${opts.timeout}".`);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
const timeoutMs = timeoutSeconds * 1000;
|
|
354
|
+
let failures = 0;
|
|
355
|
+
for (const target of targets) {
|
|
356
|
+
console.log(`Updating "${target.name}" (${target.id})${opts.to ? ` to ${opts.to}` : ""}...`);
|
|
357
|
+
const { command } = await api.sendAgentCommand(target.id, "UPDATE_AGENT", undefined, opts.to);
|
|
358
|
+
const resolved = await waitForCommandResolution(api, target.id, command.id, timeoutMs);
|
|
359
|
+
if (!resolved) {
|
|
360
|
+
console.error(` timed out after ${opts.timeout}s waiting for "${target.name}" to ack — check it manually.`);
|
|
361
|
+
failures++;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (resolved.status === "done") {
|
|
365
|
+
console.log(` done: ${resolved.result ?? "updated"}`);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
console.error(` failed: ${resolved.result ?? "no reason given"}`);
|
|
369
|
+
failures++;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// --all is a sequential, drain-aware rollout by design (issue #87):
|
|
373
|
+
// stop nagging with an overall summary only when something actually
|
|
374
|
+
// went wrong, so a clean run just shows the per-mini lines above.
|
|
375
|
+
if (failures > 0) {
|
|
376
|
+
console.error(`\n${failures} of ${targets.length} update(s) did not finish cleanly.`);
|
|
377
|
+
process.exit(1);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
agents
|
|
381
|
+
.command("allow-remote-control <agentId>")
|
|
382
|
+
.description("Grant or revoke authorization for the VNC \"Connect\" button to forward mouse/keyboard input to this Mac, not just watch its screen — off by default for every agent (see docs/fleet-management.md)")
|
|
383
|
+
.option("--on", "Grant remote control")
|
|
384
|
+
.option("--off", "Revoke remote control")
|
|
385
|
+
.action(async (agentId, opts) => {
|
|
386
|
+
if (opts.on === opts.off) {
|
|
387
|
+
// Both flags given, or neither — either way there's no single
|
|
388
|
+
// unambiguous intent to act on. Same "require exactly one" shape
|
|
389
|
+
// `agents update`'s own `--all`/`agentId` check above uses.
|
|
390
|
+
console.error("Specify exactly one of --on or --off.");
|
|
391
|
+
process.exit(1);
|
|
392
|
+
}
|
|
393
|
+
const { cfg, api } = client();
|
|
394
|
+
const { agents: fleet } = await api.listAgents(cfg.orgId);
|
|
395
|
+
const target = fleet.find((a) => a.id === agentId);
|
|
396
|
+
if (!target) {
|
|
397
|
+
console.error(`No agent ${agentId} in this org. 'appforge-admin agents list' shows the current fleet.`);
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
400
|
+
const enabled = !!opts.on;
|
|
401
|
+
await api.setAgentRemoteControl(cfg.orgId, agentId, enabled);
|
|
402
|
+
console.log(enabled
|
|
403
|
+
? `Remote control is now ENABLED for "${target.name}" (${agentId}) — the VNC "Connect" button can now request a control session for it.`
|
|
404
|
+
: `Remote control is now disabled for "${target.name}" (${agentId}).`);
|
|
405
|
+
});
|
|
406
|
+
agents
|
|
407
|
+
.command("decommission <agentId>")
|
|
408
|
+
.description("Permanently remove a Mac mini from the fleet (for a retired machine or a stale duplicate row) — does NOT stop the daemon on the machine itself")
|
|
409
|
+
.action(async (agentId) => {
|
|
410
|
+
const { cfg, api } = client();
|
|
411
|
+
const { agents: fleet } = await api.listAgents(cfg.orgId);
|
|
412
|
+
const target = fleet.find((a) => a.id === agentId);
|
|
413
|
+
if (!target) {
|
|
414
|
+
console.error(`No agent ${agentId} in this org. 'appforge-admin agents list' shows the current fleet.`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
await api.deleteAgent(cfg.orgId, agentId);
|
|
418
|
+
console.log(`Removed "${target.name}" (${agentId}) from the fleet.`);
|
|
419
|
+
// A still-running daemon does NOT re-enroll itself once its row is
|
|
420
|
+
// gone — its next heartbeat 401s (the agent token no longer
|
|
421
|
+
// matches any row), which it treats as a fatal auth failure: it
|
|
422
|
+
// stops leasing builds and idles, logging that it needs
|
|
423
|
+
// `add-mac --force` to come back. It won't silently reappear, but
|
|
424
|
+
// it also won't cleanly stop on its own — only nag about this
|
|
425
|
+
// when the agent looks alive, since that's the case where leaving
|
|
426
|
+
// the daemon running just means a Mac mini quietly erroring
|
|
427
|
+
// forever instead of actually retiring.
|
|
428
|
+
if (effectiveAgentStatus(target) !== "offline") {
|
|
429
|
+
console.log(`\nThis agent was last seen ${target.lastSeenAt} — if its daemon is still running, it will\n` +
|
|
430
|
+
`start failing heartbeats (401) and go idle rather than actually stopping. Stop it ON\n` +
|
|
431
|
+
`that machine to retire it cleanly:\n` +
|
|
432
|
+
` launchctl unload ~/Library/LaunchAgents/com.appforge.agent.plist && rm ~/.appforge-agent/config.json`);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.test.d.ts","sourceRoot":"","sources":["../../src/commands/agents.test.ts"],"names":[],"mappings":"AACA,OAAO,iCAAiC,CAAC"}
|