@tokenfactory/acc-runner 0.2.0-internal
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/README.md +116 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +77 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +48 -0
- package/dist/config.js.map +1 -0
- package/dist/doctor.d.ts +13 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +251 -0
- package/dist/doctor.js.map +1 -0
- package/dist/gh.d.ts +16 -0
- package/dist/gh.d.ts.map +1 -0
- package/dist/gh.js +37 -0
- package/dist/gh.js.map +1 -0
- package/dist/git.d.ts +9 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +25 -0
- package/dist/git.js.map +1 -0
- package/dist/keychain.d.ts +21 -0
- package/dist/keychain.d.ts.map +1 -0
- package/dist/keychain.js +45 -0
- package/dist/keychain.js.map +1 -0
- package/dist/login.d.ts +8 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +124 -0
- package/dist/login.js.map +1 -0
- package/dist/logout.d.ts +2 -0
- package/dist/logout.d.ts.map +1 -0
- package/dist/logout.js +31 -0
- package/dist/logout.js.map +1 -0
- package/dist/prompt.d.ts +38 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +78 -0
- package/dist/prompt.js.map +1 -0
- package/dist/supabase.d.ts +4 -0
- package/dist/supabase.d.ts.map +1 -0
- package/dist/supabase.js +22 -0
- package/dist/supabase.js.map +1 -0
- package/dist/task-runner.d.ts +48 -0
- package/dist/task-runner.d.ts.map +1 -0
- package/dist/task-runner.js +222 -0
- package/dist/task-runner.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/dist/version-check.d.ts +17 -0
- package/dist/version-check.d.ts.map +1 -0
- package/dist/version-check.js +40 -0
- package/dist/version-check.js.map +1 -0
- package/dist/watch.d.ts +12 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +132 -0
- package/dist/watch.js.map +1 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# `@tokenfactory/acc-runner`
|
|
2
|
+
|
|
3
|
+
Local runner for [Agent Control Center](https://github.com/tokenfactory-pvt-ltd/agent-control-center).
|
|
4
|
+
Subscribes to ACC over Supabase Realtime; on a task assignment, spawns
|
|
5
|
+
your local `claude` CLI with the rendered prompt, streams logs back, and
|
|
6
|
+
opens a PR via `gh` when done.
|
|
7
|
+
|
|
8
|
+
> Status: internal beta. Ships with ACC v0.2.0-internal.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
pnpm add -g @tokenfactory/acc-runner
|
|
14
|
+
# or
|
|
15
|
+
npm i -g @tokenfactory/acc-runner
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires:
|
|
19
|
+
|
|
20
|
+
- Node.js 20.6+
|
|
21
|
+
- `claude` (Claude Code CLI) in `$PATH`
|
|
22
|
+
- `gh` (GitHub CLI) in `$PATH`, authenticated (`gh auth login`)
|
|
23
|
+
- `git`, configured with `user.email`
|
|
24
|
+
- A local clone of the target repo (default `~/work/TechArch`)
|
|
25
|
+
|
|
26
|
+
Run `acc-runner doctor` after install to verify all the above.
|
|
27
|
+
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
The CLI reads from environment variables — set these in your shell
|
|
31
|
+
profile so `acc-runner watch` finds them.
|
|
32
|
+
|
|
33
|
+
| Variable | Required | Notes |
|
|
34
|
+
| ------------------------- | :------: | ----------------------------------------------------- |
|
|
35
|
+
| `ACC_PUBLIC_URL` | ✓ | e.g. `https://acc.techarch.dev` |
|
|
36
|
+
| `ACC_SUPABASE_URL` | ✓ | Mirror of the SPA's `VITE_SUPABASE_URL` |
|
|
37
|
+
| `ACC_SUPABASE_ANON_KEY` | ✓ | Same anon key the SPA uses |
|
|
38
|
+
| `ACC_REPO_PATH` | | Defaults to `~/work/TechArch` |
|
|
39
|
+
| `ACC_TARGET_REPO` | | Defaults to `tokenfactory-pvt-ltd/TechArch` |
|
|
40
|
+
| `ACC_INTEGRATION_BRANCH` | | Defaults to `acc/integration` |
|
|
41
|
+
|
|
42
|
+
## Quickstart
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
acc-runner login # device-code OAuth in your browser
|
|
46
|
+
acc-runner doctor # verify env (all green)
|
|
47
|
+
acc-runner watch # long-running; receives + executes tasks
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then, in ACC, assign a task to this machine and click **Start**. The CLI
|
|
51
|
+
will:
|
|
52
|
+
|
|
53
|
+
1. Transition the task to `running`
|
|
54
|
+
2. `git fetch && git checkout -B acc/T-XX-<slug>`
|
|
55
|
+
3. Pipe the rendered prompt into `claude --print`
|
|
56
|
+
4. Stream stdout/stderr to `acc.task_events` (visible in the History tab)
|
|
57
|
+
5. `git push` and open a PR titled `[T-XX] <task title>`
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
### `acc-runner login`
|
|
62
|
+
|
|
63
|
+
Device-code OAuth flow. Stores a JWT in your OS keychain (`acc-runner`
|
|
64
|
+
service) and registers this machine in `acc.runners`.
|
|
65
|
+
|
|
66
|
+
### `acc-runner logout`
|
|
67
|
+
|
|
68
|
+
Clears the keychain entry and marks this runner offline.
|
|
69
|
+
|
|
70
|
+
### `acc-runner watch`
|
|
71
|
+
|
|
72
|
+
Subscribes to a Realtime broadcast channel scoped to your runner. Sends a
|
|
73
|
+
heartbeat every 4s. Cancellation is honored via `task_cancelled`
|
|
74
|
+
broadcasts (sends SIGTERM to the in-flight `claude` child).
|
|
75
|
+
|
|
76
|
+
### `acc-runner doctor`
|
|
77
|
+
|
|
78
|
+
Runs every environment check and prints a green/red list. Exits 0 if all
|
|
79
|
+
pass, 1 otherwise. Suitable for CI.
|
|
80
|
+
|
|
81
|
+
### `acc-runner version`
|
|
82
|
+
|
|
83
|
+
Prints the CLI version and the protocol version it speaks. The server
|
|
84
|
+
exposes a minimum-protocol-version pin at `/api/runner/min-version`; the
|
|
85
|
+
CLI refuses to start if behind.
|
|
86
|
+
|
|
87
|
+
## Troubleshooting
|
|
88
|
+
|
|
89
|
+
**`✗ Not signed in. Run \`acc-runner login\` first.`** — keychain entry
|
|
90
|
+
was cleared or never created. Run `acc-runner login`.
|
|
91
|
+
|
|
92
|
+
**`✗ keychain read/write` (FAIL)** — on Linux, install `libsecret`. On
|
|
93
|
+
macOS, ensure your login keychain is unlocked. On Windows, run from a
|
|
94
|
+
session with credential manager access.
|
|
95
|
+
|
|
96
|
+
**`✗ register_runner failed`** — the migration that ships the
|
|
97
|
+
`acc.register_runner` RPC may not be applied to your environment yet.
|
|
98
|
+
Coordinate with the operator who ran `supabase db push`.
|
|
99
|
+
|
|
100
|
+
**Task transitions to `failed` immediately** — check the History tab for
|
|
101
|
+
the underlying error. Common causes: `git fetch` permission denied (push
|
|
102
|
+
auth), `claude --print` returned non-zero, or the rendered prompt lacked
|
|
103
|
+
acceptance criteria.
|
|
104
|
+
|
|
105
|
+
## Security notes
|
|
106
|
+
|
|
107
|
+
- The CLI never reads or writes your git credentials, gh credentials, or
|
|
108
|
+
Anthropic API keys. It calls binaries you already have authenticated.
|
|
109
|
+
- The Supabase JWT is short-lived; the CLI stores it in your OS keychain
|
|
110
|
+
via `keytar`, never in plaintext on disk.
|
|
111
|
+
- Heartbeat interval is 4s — do not tighten this. The server expects to
|
|
112
|
+
see it; tighter intervals consume the Realtime budget.
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
Proprietary. Not for redistribution.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* acc-runner — CLI entry point. commander wires subcommands into named
|
|
4
|
+
* functions in their own files; this module is intentionally thin.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
import { loginCommand } from "./login.js";
|
|
10
|
+
import { logoutCommand } from "./logout.js";
|
|
11
|
+
import { watchCommand } from "./watch.js";
|
|
12
|
+
import { doctorCommand } from "./doctor.js";
|
|
13
|
+
import { PROTOCOL_VERSION } from "./types.js";
|
|
14
|
+
const require = createRequire(import.meta.url);
|
|
15
|
+
const pkg = require("../package.json");
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program
|
|
18
|
+
.name("acc-runner")
|
|
19
|
+
.description("Agent Control Center local runner. Subscribes to ACC, spawns Claude Code on assignment, and opens a PR when done.")
|
|
20
|
+
.version(`${pkg.version} (protocol v${PROTOCOL_VERSION})`);
|
|
21
|
+
program
|
|
22
|
+
.command("login")
|
|
23
|
+
.description("Sign in via device-code OAuth and register this machine.")
|
|
24
|
+
.action(async () => {
|
|
25
|
+
try {
|
|
26
|
+
await loginCommand();
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
program
|
|
34
|
+
.command("logout")
|
|
35
|
+
.description("Clear the local session and mark this runner offline.")
|
|
36
|
+
.action(async () => {
|
|
37
|
+
try {
|
|
38
|
+
await logoutCommand();
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
42
|
+
process.exitCode = 1;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
program
|
|
46
|
+
.command("watch")
|
|
47
|
+
.description("Long-running. Receive task assignments and execute them.")
|
|
48
|
+
.action(async () => {
|
|
49
|
+
try {
|
|
50
|
+
await watchCommand();
|
|
51
|
+
// Keep the process alive — stop() runs in the SIGINT handler.
|
|
52
|
+
await new Promise(() => { });
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
program
|
|
60
|
+
.command("doctor")
|
|
61
|
+
.description("Run environment checks. Exit 0 if all green, 1 otherwise.")
|
|
62
|
+
.action(async () => {
|
|
63
|
+
const code = await doctorCommand();
|
|
64
|
+
process.exitCode = code;
|
|
65
|
+
});
|
|
66
|
+
program
|
|
67
|
+
.command("version")
|
|
68
|
+
.description("Print CLI + protocol versions.")
|
|
69
|
+
.action(() => {
|
|
70
|
+
console.log(`acc-runner ${pkg.version}`);
|
|
71
|
+
console.log(`protocol ${PROTOCOL_VERSION}`);
|
|
72
|
+
});
|
|
73
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
74
|
+
console.error(chalk.red(`✗ ${err.message}`));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface RunnerConfig {
|
|
2
|
+
publicUrl: string;
|
|
3
|
+
supabaseUrl: string;
|
|
4
|
+
supabaseAnonKey: string;
|
|
5
|
+
repoPath: string;
|
|
6
|
+
targetRepo: string;
|
|
7
|
+
integrationBranch: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function loadConfig(): RunnerConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Best-effort version of loadConfig() for commands that should still
|
|
12
|
+
* partially succeed without env (e.g. `version`, `--help`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfigOrNull(): RunnerConfig | null;
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAUD,wBAAgB,UAAU,IAAI,YAAY,CAazC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,IAAI,CAMtD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolved runtime config for the CLI. Reads from environment variables
|
|
3
|
+
* so the binary stays portable across machines without rebuilding.
|
|
4
|
+
*
|
|
5
|
+
* Required at runtime:
|
|
6
|
+
* ACC_PUBLIC_URL — e.g. https://acc.techarch.dev
|
|
7
|
+
* ACC_SUPABASE_URL — Supabase project URL (mirror of VITE_SUPABASE_URL)
|
|
8
|
+
* ACC_SUPABASE_ANON_KEY — Supabase anon key (used for the JS client)
|
|
9
|
+
*
|
|
10
|
+
* Optional:
|
|
11
|
+
* ACC_REPO_PATH — local clone of TechArch (defaults to ~/work/TechArch)
|
|
12
|
+
* ACC_TARGET_REPO — slug, defaults to tokenfactory-pvt-ltd/TechArch
|
|
13
|
+
* ACC_INTEGRATION_BRANCH — base branch for new PRs, defaults to acc/integration
|
|
14
|
+
*/
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
function envRequired(name) {
|
|
18
|
+
const v = (process.env[name] ?? "").trim();
|
|
19
|
+
if (!v) {
|
|
20
|
+
throw new Error(`Missing required env var: ${name}`);
|
|
21
|
+
}
|
|
22
|
+
return v;
|
|
23
|
+
}
|
|
24
|
+
export function loadConfig() {
|
|
25
|
+
const repoPath = process.env.ACC_REPO_PATH?.trim() ||
|
|
26
|
+
path.resolve(os.homedir(), "work", "TechArch");
|
|
27
|
+
return {
|
|
28
|
+
publicUrl: envRequired("ACC_PUBLIC_URL"),
|
|
29
|
+
supabaseUrl: envRequired("ACC_SUPABASE_URL"),
|
|
30
|
+
supabaseAnonKey: envRequired("ACC_SUPABASE_ANON_KEY"),
|
|
31
|
+
repoPath,
|
|
32
|
+
targetRepo: process.env.ACC_TARGET_REPO?.trim() || "tokenfactory-pvt-ltd/TechArch",
|
|
33
|
+
integrationBranch: process.env.ACC_INTEGRATION_BRANCH?.trim() || "acc/integration",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Best-effort version of loadConfig() for commands that should still
|
|
38
|
+
* partially succeed without env (e.g. `version`, `--help`).
|
|
39
|
+
*/
|
|
40
|
+
export function loadConfigOrNull() {
|
|
41
|
+
try {
|
|
42
|
+
return loadConfig();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GACZ,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE;QACjC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IACjD,OAAO;QACL,SAAS,EAAE,WAAW,CAAC,gBAAgB,CAAC;QACxC,WAAW,EAAE,WAAW,CAAC,kBAAkB,CAAC;QAC5C,eAAe,EAAE,WAAW,CAAC,uBAAuB,CAAC;QACrD,QAAQ;QACR,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,+BAA+B;QAClF,iBAAiB,EACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,IAAI,iBAAiB;KAClE,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,OAAO,UAAU,EAAE,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface CheckOutcome {
|
|
2
|
+
name: string;
|
|
3
|
+
ok: boolean;
|
|
4
|
+
detail: string;
|
|
5
|
+
fix?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DoctorOptions {
|
|
8
|
+
/** Stub the checks for tests. */
|
|
9
|
+
checks?: Array<() => Promise<CheckOutcome>>;
|
|
10
|
+
}
|
|
11
|
+
export declare function doctorCommand(options?: DoctorOptions): Promise<number>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAaA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA6ND,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;CAC7C;AAQD,wBAAsB,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BhF"}
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `acc-runner doctor` — environment checks. Returns 0 if all green, 1 if
|
|
3
|
+
* any check failed. Each check carries a remediation hint so users can
|
|
4
|
+
* self-serve.
|
|
5
|
+
*/
|
|
6
|
+
import { execa } from "execa";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import { loadConfigOrNull } from "./config.js";
|
|
9
|
+
import { loadSession } from "./keychain.js";
|
|
10
|
+
import { createRunnerClient } from "./supabase.js";
|
|
11
|
+
import { checkVersion } from "./version-check.js";
|
|
12
|
+
import { PROTOCOL_VERSION } from "./types.js";
|
|
13
|
+
async function checkBinary(bin, args) {
|
|
14
|
+
try {
|
|
15
|
+
const { stdout } = await execa(bin, args, { env: process.env });
|
|
16
|
+
const first = stdout.split(/\r?\n/)[0]?.trim() ?? bin;
|
|
17
|
+
return { ok: true, detail: first };
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
return { ok: false, detail: err.message.split("\n")[0] };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function checkNode() {
|
|
24
|
+
const major = Number(process.versions.node.split(".")[0]);
|
|
25
|
+
return {
|
|
26
|
+
name: "node 20+",
|
|
27
|
+
ok: major >= 20,
|
|
28
|
+
detail: `node ${process.versions.node}`,
|
|
29
|
+
fix: "Install Node 20.6+ (https://nodejs.org).",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function checkClaude() {
|
|
33
|
+
const r = await checkBinary("claude", ["--version"]);
|
|
34
|
+
return {
|
|
35
|
+
name: "claude CLI in PATH",
|
|
36
|
+
ok: r.ok,
|
|
37
|
+
detail: r.detail,
|
|
38
|
+
fix: "Install Claude Code (https://claude.com/claude-code) and re-run.",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function checkGh() {
|
|
42
|
+
const ghOk = await checkBinary("gh", ["--version"]);
|
|
43
|
+
if (!ghOk.ok) {
|
|
44
|
+
return {
|
|
45
|
+
name: "gh CLI in PATH",
|
|
46
|
+
ok: false,
|
|
47
|
+
detail: ghOk.detail,
|
|
48
|
+
fix: "Install GitHub CLI (https://cli.github.com).",
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
await execa("gh", ["auth", "status"], { env: process.env });
|
|
53
|
+
return { name: "gh CLI in PATH", ok: true, detail: ghOk.detail };
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return {
|
|
57
|
+
name: "gh CLI in PATH",
|
|
58
|
+
ok: false,
|
|
59
|
+
detail: "gh installed but not authenticated",
|
|
60
|
+
fix: "Run `gh auth login`.",
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function checkGit() {
|
|
65
|
+
const r = await checkBinary("git", ["--version"]);
|
|
66
|
+
if (!r.ok) {
|
|
67
|
+
return {
|
|
68
|
+
name: "git installed",
|
|
69
|
+
ok: false,
|
|
70
|
+
detail: r.detail,
|
|
71
|
+
fix: "Install git (https://git-scm.com).",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Soft-check that user.email is set; agents can't push commits without it.
|
|
75
|
+
try {
|
|
76
|
+
const { stdout } = await execa("git", ["config", "user.email"], { env: process.env });
|
|
77
|
+
if (!stdout.trim())
|
|
78
|
+
throw new Error("user.email empty");
|
|
79
|
+
return { name: "git installed and configured", ok: true, detail: r.detail };
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return {
|
|
83
|
+
name: "git installed and configured",
|
|
84
|
+
ok: false,
|
|
85
|
+
detail: "git.user.email is not set",
|
|
86
|
+
fix: "Run `git config --global user.email <you@example.com>`.",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function checkKeychain() {
|
|
91
|
+
try {
|
|
92
|
+
const keytar = (await import("keytar"));
|
|
93
|
+
const k = keytar.default ?? keytar;
|
|
94
|
+
await k.setPassword("acc-runner-doctor", "sentinel", "ok");
|
|
95
|
+
const v = await k.getPassword("acc-runner-doctor", "sentinel");
|
|
96
|
+
await k.deletePassword("acc-runner-doctor", "sentinel");
|
|
97
|
+
return {
|
|
98
|
+
name: "keychain read/write",
|
|
99
|
+
ok: v === "ok",
|
|
100
|
+
detail: v === "ok" ? "ok" : `unexpected: ${String(v)}`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return {
|
|
105
|
+
name: "keychain read/write",
|
|
106
|
+
ok: false,
|
|
107
|
+
detail: err.message.split("\n")[0],
|
|
108
|
+
fix: "On Linux: install libsecret. On macOS/Windows: ensure the keychain service is unlocked.",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function checkServer(publicUrl) {
|
|
113
|
+
try {
|
|
114
|
+
const res = await fetch(`${publicUrl.replace(/\/+$/, "")}/api/health`, {
|
|
115
|
+
headers: { "User-Agent": `acc-runner/${PROTOCOL_VERSION}` },
|
|
116
|
+
});
|
|
117
|
+
if (!res.ok) {
|
|
118
|
+
return {
|
|
119
|
+
name: "/api/health reachable",
|
|
120
|
+
ok: false,
|
|
121
|
+
detail: `HTTP ${res.status}`,
|
|
122
|
+
fix: "Check ACC_PUBLIC_URL points to a deployment that is up.",
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { name: "/api/health reachable", ok: true, detail: "200 OK" };
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
return {
|
|
129
|
+
name: "/api/health reachable",
|
|
130
|
+
ok: false,
|
|
131
|
+
detail: err.message.split("\n")[0],
|
|
132
|
+
fix: "Check ACC_PUBLIC_URL and your network connection.",
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function checkProtocolVersion(publicUrl) {
|
|
137
|
+
const r = await checkVersion(publicUrl);
|
|
138
|
+
if (r.ok) {
|
|
139
|
+
return {
|
|
140
|
+
name: "protocol version",
|
|
141
|
+
ok: true,
|
|
142
|
+
detail: `server min v${r.serverMin}, you have v${PROTOCOL_VERSION}`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (r.reason === "outdated") {
|
|
146
|
+
return {
|
|
147
|
+
name: "protocol version",
|
|
148
|
+
ok: false,
|
|
149
|
+
detail: `server min v${r.serverMin}, you have v${PROTOCOL_VERSION}`,
|
|
150
|
+
fix: "Run `pnpm add -g @tokenfactory/acc-runner@latest`.",
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
name: "protocol version",
|
|
155
|
+
ok: false,
|
|
156
|
+
detail: r.detail ?? "unreachable",
|
|
157
|
+
fix: "Check ACC_PUBLIC_URL and connectivity.",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
async function checkRegistration() {
|
|
161
|
+
const cfg = loadConfigOrNull();
|
|
162
|
+
if (!cfg) {
|
|
163
|
+
return {
|
|
164
|
+
name: "runner registered",
|
|
165
|
+
ok: false,
|
|
166
|
+
detail: "ACC_PUBLIC_URL / ACC_SUPABASE_URL / ACC_SUPABASE_ANON_KEY not set",
|
|
167
|
+
fix: "Populate the env vars in .env.example.",
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const session = await loadSession();
|
|
171
|
+
if (!session) {
|
|
172
|
+
return {
|
|
173
|
+
name: "runner registered",
|
|
174
|
+
ok: false,
|
|
175
|
+
detail: "no session in keychain",
|
|
176
|
+
fix: "Run `acc-runner login`.",
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const supabase = createRunnerClient(cfg, session.jwt);
|
|
181
|
+
const { data, error } = await supabase
|
|
182
|
+
.from("runners")
|
|
183
|
+
.select("id,bound_user_id,status")
|
|
184
|
+
.eq("id", session.runner_id)
|
|
185
|
+
.maybeSingle();
|
|
186
|
+
if (error) {
|
|
187
|
+
return {
|
|
188
|
+
name: "runner registered",
|
|
189
|
+
ok: false,
|
|
190
|
+
detail: error.message,
|
|
191
|
+
fix: "Re-run `acc-runner login`.",
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (!data) {
|
|
195
|
+
return {
|
|
196
|
+
name: "runner registered",
|
|
197
|
+
ok: false,
|
|
198
|
+
detail: `runner row ${session.runner_id} not found`,
|
|
199
|
+
fix: "Re-run `acc-runner login`.",
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (data.bound_user_id !== session.user_id) {
|
|
203
|
+
return {
|
|
204
|
+
name: "runner registered",
|
|
205
|
+
ok: false,
|
|
206
|
+
detail: "runner bound to a different user",
|
|
207
|
+
fix: "Run `acc-runner logout` then `acc-runner login` again.",
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return { name: "runner registered", ok: true, detail: `${session.runner_id} (status=${data.status})` };
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
return {
|
|
214
|
+
name: "runner registered",
|
|
215
|
+
ok: false,
|
|
216
|
+
detail: err.message.split("\n")[0],
|
|
217
|
+
fix: "Re-run `acc-runner login`.",
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function format(outcome) {
|
|
222
|
+
const tag = outcome.ok ? chalk.green("[OK ]") : chalk.red("[FAIL]");
|
|
223
|
+
const fix = !outcome.ok && outcome.fix ? chalk.gray(`\n → ${outcome.fix}`) : "";
|
|
224
|
+
return `${tag} ${outcome.name.padEnd(28, " ")} ${chalk.gray(outcome.detail)}${fix}`;
|
|
225
|
+
}
|
|
226
|
+
export async function doctorCommand(options = {}) {
|
|
227
|
+
const cfg = loadConfigOrNull();
|
|
228
|
+
const checks = options.checks ?? [
|
|
229
|
+
checkNode,
|
|
230
|
+
checkClaude,
|
|
231
|
+
checkGh,
|
|
232
|
+
checkGit,
|
|
233
|
+
checkKeychain,
|
|
234
|
+
...(cfg ? [() => checkServer(cfg.publicUrl)] : []),
|
|
235
|
+
...(cfg ? [() => checkProtocolVersion(cfg.publicUrl)] : []),
|
|
236
|
+
checkRegistration,
|
|
237
|
+
];
|
|
238
|
+
let failed = 0;
|
|
239
|
+
for (const fn of checks) {
|
|
240
|
+
const outcome = await fn();
|
|
241
|
+
if (!outcome.ok)
|
|
242
|
+
failed++;
|
|
243
|
+
console.log(format(outcome));
|
|
244
|
+
}
|
|
245
|
+
if (!cfg && !options.checks) {
|
|
246
|
+
console.log(chalk.yellow("\n! ACC_PUBLIC_URL / ACC_SUPABASE_URL / ACC_SUPABASE_ANON_KEY are not set; server-side checks were skipped."));
|
|
247
|
+
failed += 1;
|
|
248
|
+
}
|
|
249
|
+
return failed === 0 ? 0 : 1;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/gh.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface OpenPRArgs {
|
|
2
|
+
title: string;
|
|
3
|
+
body: string;
|
|
4
|
+
base: string;
|
|
5
|
+
head?: string;
|
|
6
|
+
/** Open as draft. Defaults to false (matches Track P2-C convention). */
|
|
7
|
+
draft?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface GhRunner {
|
|
10
|
+
isAuthenticated(): Promise<boolean>;
|
|
11
|
+
openPR(repoPath: string, args: OpenPRArgs): Promise<{
|
|
12
|
+
url: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export declare const gh: GhRunner;
|
|
16
|
+
//# sourceMappingURL=gh.d.ts.map
|
package/dist/gh.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.d.ts","sourceRoot":"","sources":["../src/gh.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,eAAO,MAAM,EAAE,EAAE,QA2BhB,CAAC"}
|
package/dist/gh.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gh CLI wrapper. We rely on whatever auth `gh auth status` already has —
|
|
3
|
+
* never touching the user's credentials.
|
|
4
|
+
*/
|
|
5
|
+
import { execa } from "execa";
|
|
6
|
+
export const gh = {
|
|
7
|
+
async isAuthenticated() {
|
|
8
|
+
try {
|
|
9
|
+
await execa("gh", ["auth", "status"], { env: process.env });
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
async openPR(repoPath, args) {
|
|
17
|
+
const argv = [
|
|
18
|
+
"pr",
|
|
19
|
+
"create",
|
|
20
|
+
"--title",
|
|
21
|
+
args.title,
|
|
22
|
+
"--body",
|
|
23
|
+
args.body,
|
|
24
|
+
"--base",
|
|
25
|
+
args.base,
|
|
26
|
+
];
|
|
27
|
+
if (args.head)
|
|
28
|
+
argv.push("--head", args.head);
|
|
29
|
+
if (args.draft)
|
|
30
|
+
argv.push("--draft");
|
|
31
|
+
const { stdout } = await execa("gh", argv, { cwd: repoPath, env: process.env });
|
|
32
|
+
// gh prints the PR URL on the last line of stdout.
|
|
33
|
+
const url = stdout.trim().split(/\r?\n/).pop() ?? "";
|
|
34
|
+
return { url };
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=gh.js.map
|
package/dist/gh.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gh.js","sourceRoot":"","sources":["../src/gh.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAgB9B,MAAM,CAAC,MAAM,EAAE,GAAa;IAC1B,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI;QACzB,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,QAAQ;YACR,SAAS;YACT,IAAI,CAAC,KAAK;YACV,QAAQ;YACR,IAAI,CAAC,IAAI;YACT,QAAQ;YACR,IAAI,CAAC,IAAI;SACV,CAAC;QACF,IAAI,IAAI,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChF,mDAAmD;QACnD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QACrD,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;CACF,CAAC"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface GitRunner {
|
|
2
|
+
fetch(repoPath: string): Promise<void>;
|
|
3
|
+
checkout(repoPath: string, branch: string): Promise<void>;
|
|
4
|
+
push(repoPath: string, branch: string): Promise<void>;
|
|
5
|
+
/** True when the working tree has no uncommitted changes. */
|
|
6
|
+
isClean(repoPath: string): Promise<boolean>;
|
|
7
|
+
}
|
|
8
|
+
export declare const git: GitRunner;
|
|
9
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C;AAMD,eAAO,MAAM,GAAG,EAAE,SAejB,CAAC"}
|