@tokenfactory/acc-runner 0.41.7 → 0.42.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/README.md +87 -4
- package/dist/acc.d.ts +3 -0
- package/dist/acc.d.ts.map +1 -0
- package/dist/acc.js +21 -0
- package/dist/acc.js.map +1 -0
- package/dist/cli-name.d.ts +29 -0
- package/dist/cli-name.d.ts.map +1 -0
- package/dist/cli-name.js +17 -0
- package/dist/cli-name.js.map +1 -0
- package/dist/cli.d.ts +20 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +45 -289
- package/dist/cli.js.map +1 -1
- package/dist/keychain.d.ts +17 -0
- package/dist/keychain.d.ts.map +1 -1
- package/dist/keychain.js +36 -0
- package/dist/keychain.js.map +1 -1
- package/dist/login.d.ts +45 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +91 -4
- package/dist/login.js.map +1 -1
- package/dist/program.d.ts +16 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +342 -0
- package/dist/program.js.map +1 -0
- package/dist/user-auth/device-login.d.ts +47 -0
- package/dist/user-auth/device-login.d.ts.map +1 -0
- package/dist/user-auth/device-login.js +189 -0
- package/dist/user-auth/device-login.js.map +1 -0
- package/dist/user-auth/liveness.d.ts +27 -0
- package/dist/user-auth/liveness.d.ts.map +1 -0
- package/dist/user-auth/liveness.js +128 -0
- package/dist/user-auth/liveness.js.map +1 -0
- package/dist/user-auth/session.d.ts +82 -0
- package/dist/user-auth/session.d.ts.map +1 -0
- package/dist/user-auth/session.js +172 -0
- package/dist/user-auth/session.js.map +1 -0
- package/dist/user-cli/chat.d.ts +44 -0
- package/dist/user-cli/chat.d.ts.map +1 -0
- package/dist/user-cli/chat.js +199 -0
- package/dist/user-cli/chat.js.map +1 -0
- package/dist/user-cli/client.d.ts +20 -0
- package/dist/user-cli/client.d.ts.map +1 -0
- package/dist/user-cli/client.js +60 -0
- package/dist/user-cli/client.js.map +1 -0
- package/dist/user-cli/tasks.d.ts +37 -0
- package/dist/user-cli/tasks.d.ts.map +1 -0
- package/dist/user-cli/tasks.js +131 -0
- package/dist/user-cli/tasks.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @tokenfactory/acc-runner
|
|
2
2
|
|
|
3
|
-
CLI
|
|
4
|
-
|
|
3
|
+
The Agent Control Center CLI. Sign in as yourself, read the task board, ask ACC,
|
|
4
|
+
and run agents on this machine.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
@@ -11,14 +11,97 @@ npm i -g @tokenfactory/acc-runner
|
|
|
11
11
|
pnpm add -g @tokenfactory/acc-runner
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
This installs **two commands**:
|
|
15
|
+
|
|
16
|
+
| Command | Status |
|
|
17
|
+
| ------------ | ------------------------------------------------------------------- |
|
|
18
|
+
| `acc` | The CLI. Use this. |
|
|
19
|
+
| `acc-runner` | Deprecated alias. Everything still works; prints a notice on stderr. |
|
|
20
|
+
|
|
21
|
+
Requires Node.js ≥ 20.6. Running agents on this machine additionally needs these
|
|
22
|
+
binaries on `PATH`:
|
|
15
23
|
|
|
16
24
|
- `claude` — Claude Code CLI, signed in
|
|
17
25
|
- `gh` — GitHub CLI, signed in (`gh auth login`)
|
|
18
26
|
- `git` — with `user.email` configured
|
|
19
27
|
- A local clone of the target repo (the `repoPath`, see below)
|
|
20
28
|
|
|
21
|
-
Run `acc
|
|
29
|
+
Run `acc doctor` after install to verify everything resolves.
|
|
30
|
+
|
|
31
|
+
## The two lanes
|
|
32
|
+
|
|
33
|
+
There are two different things a terminal can be, and they are separate
|
|
34
|
+
credentials with separate lifecycles. A workstation can hold both at once.
|
|
35
|
+
|
|
36
|
+
**You, signed in as yourself** — a device-code login that leaves you with your
|
|
37
|
+
own session (the same one your browser holds) and no runner registration:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
acc login # device-code sign-in; stores a session in the OS keychain
|
|
41
|
+
acc whoami # who this terminal is signed in as
|
|
42
|
+
acc logout # revoke this terminal's session, server-side and locally
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The session shows up on **Settings → Sessions** as `acc CLI · <hostname>`, so you
|
|
46
|
+
can revoke it from the browser like any other.
|
|
47
|
+
|
|
48
|
+
**This machine, enrolled as a runner** — the fleet credential that lets ACC
|
|
49
|
+
assign tasks here:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
acc runner login # enrol this host, register a runner
|
|
53
|
+
acc runner logout # clear the local session, mark this runner offline
|
|
54
|
+
acc watch # long-running: receive assignments and execute them
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Reading the board
|
|
58
|
+
|
|
59
|
+
Read-only, under your own token — RLS decides what you can see, exactly as in the
|
|
60
|
+
UI.
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
acc task list # 25 most recently updated
|
|
64
|
+
acc task list --status in_progress --limit 50
|
|
65
|
+
acc task list --repo owner/name --json
|
|
66
|
+
acc task show T-1234
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Asking ACC
|
|
70
|
+
|
|
71
|
+
Hits the same `/api/chat/stream` endpoint the browser uses, so the same tools,
|
|
72
|
+
delegation ceiling and audit trail apply.
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
acc chat "which tasks are blocked?" # one shot
|
|
76
|
+
acc chat # interactive session on a TTY
|
|
77
|
+
git log --oneline -20 | acc chat # piped
|
|
78
|
+
acc chat --conversation <id> "and the risky ones?"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If no provider key resolves for you, the turn is queued for a companion runner
|
|
82
|
+
to drain and `acc chat` says so — read the reply in the ACC conversation.
|
|
83
|
+
|
|
84
|
+
## Migrating from `acc-runner`
|
|
85
|
+
|
|
86
|
+
The alias is a true alias: every command keeps the meaning it already had, so no
|
|
87
|
+
script needs changing today.
|
|
88
|
+
|
|
89
|
+
| You typed | Keeps working | New name |
|
|
90
|
+
| ------------------------ | ------------- | --------------------- |
|
|
91
|
+
| `acc-runner login` | yes | `acc runner login` |
|
|
92
|
+
| `acc-runner logout` | yes | `acc runner logout` |
|
|
93
|
+
| `acc-runner auth login` | yes | `acc login` |
|
|
94
|
+
| `acc-runner auth status` | yes | `acc whoami` |
|
|
95
|
+
| `acc-runner auth logout` | yes | `acc logout` |
|
|
96
|
+
| `acc-runner <anything>` | yes | `acc <anything>` |
|
|
97
|
+
|
|
98
|
+
Note the one thing a blind rename would get wrong: **`acc login` and
|
|
99
|
+
`acc-runner login` are different lanes.** `acc-runner login` enrols a machine
|
|
100
|
+
(what it always did); `acc login` signs a person in. Use `acc runner login` when
|
|
101
|
+
you mean the machine.
|
|
102
|
+
|
|
103
|
+
Set `ACC_SUPPRESS_ALIAS_NOTICE=1` to silence the deprecation line — worth doing
|
|
104
|
+
in launchd plists, docker entrypoints and CI where the output was quiet before.
|
|
22
105
|
|
|
23
106
|
## Configuration
|
|
24
107
|
|
package/dist/acc.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acc.d.ts","sourceRoot":"","sources":["../src/acc.ts"],"names":[],"mappings":";AAkBA,eAAO,MAAM,OAAO,6BAAqC,CAAC"}
|
package/dist/acc.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `acc` — the unified CLI. One command for signing in, reading the board,
|
|
4
|
+
* asking ACC, and running agents on this machine.
|
|
5
|
+
*
|
|
6
|
+
* A separate bin file rather than a name sniff on `process.argv[1]`: npm
|
|
7
|
+
* installs a symlink on POSIX (whose basename IS the bin name) but a `.cmd`
|
|
8
|
+
* shim on Windows that invokes node with the built file's own path, so the
|
|
9
|
+
* typed name is simply not recoverable from argv there. Two entry files make
|
|
10
|
+
* the invoked name a fact of which file ran, on every platform.
|
|
11
|
+
*
|
|
12
|
+
* The command tree lives in program.ts and is shared with the acc-runner alias.
|
|
13
|
+
*/
|
|
14
|
+
import { setInvokedAs } from "./cli-name.js";
|
|
15
|
+
import { buildProgram, isMainModule, runProgram } from "./program.js";
|
|
16
|
+
setInvokedAs("acc");
|
|
17
|
+
export const program = buildProgram({ invokedAs: "acc" });
|
|
18
|
+
if (isMainModule(import.meta.url)) {
|
|
19
|
+
runProgram(program);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=acc.js.map
|
package/dist/acc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acc.js","sourceRoot":"","sources":["../src/acc.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtE,YAAY,CAAC,KAAK,CAAC,CAAC;AAEpB,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AAE1D,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,UAAU,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which binary the operator actually typed.
|
|
3
|
+
*
|
|
4
|
+
* The package ships two bins over ONE command tree: `acc` (the unified CLI) and
|
|
5
|
+
* `acc-runner` (the original name, retained as a deprecated alias). Almost
|
|
6
|
+
* everything behaves identically under both, but two things must not:
|
|
7
|
+
*
|
|
8
|
+
* 1. `login` / `logout` mean different lanes under the two names — see
|
|
9
|
+
* buildProgram in program.ts for why that is a compatibility requirement
|
|
10
|
+
* rather than a wart.
|
|
11
|
+
* 2. Every "run `… auth login`" hint the CLI prints should name the binary the
|
|
12
|
+
* operator is holding. A person who installed `acc` and is told to run
|
|
13
|
+
* `acc-runner` has been handed a puzzle instead of an instruction.
|
|
14
|
+
*
|
|
15
|
+
* This is process-scoped state set once by the bin entry point, before any
|
|
16
|
+
* command runs. It defaults to the legacy name so that importing a module in a
|
|
17
|
+
* test (or from the alias entry) prints exactly what it printed before.
|
|
18
|
+
*/
|
|
19
|
+
export type CliName = "acc" | "acc-runner";
|
|
20
|
+
/** Called by the bin entry points (cli.ts / acc.ts) before parsing argv. */
|
|
21
|
+
export declare function setInvokedAs(name: CliName): void;
|
|
22
|
+
/** The binary name to use in operator-facing copy. */
|
|
23
|
+
export declare function cliName(): CliName;
|
|
24
|
+
/**
|
|
25
|
+
* `acc login` under the unified bin; `acc-runner auth login` under the alias.
|
|
26
|
+
* Both start the same person-lane device flow — only the spelling differs.
|
|
27
|
+
*/
|
|
28
|
+
export declare function signInCommand(): string;
|
|
29
|
+
//# sourceMappingURL=cli-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-name.d.ts","sourceRoot":"","sources":["../src/cli-name.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,YAAY,CAAC;AAI3C,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAEhD;AAED,sDAAsD;AACtD,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/cli-name.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
let invokedAs = "acc-runner";
|
|
2
|
+
/** Called by the bin entry points (cli.ts / acc.ts) before parsing argv. */
|
|
3
|
+
export function setInvokedAs(name) {
|
|
4
|
+
invokedAs = name;
|
|
5
|
+
}
|
|
6
|
+
/** The binary name to use in operator-facing copy. */
|
|
7
|
+
export function cliName() {
|
|
8
|
+
return invokedAs;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `acc login` under the unified bin; `acc-runner auth login` under the alias.
|
|
12
|
+
* Both start the same person-lane device flow — only the spelling differs.
|
|
13
|
+
*/
|
|
14
|
+
export function signInCommand() {
|
|
15
|
+
return invokedAs === "acc" ? "acc login" : "acc-runner auth login";
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=cli-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-name.js","sourceRoot":"","sources":["../src/cli-name.ts"],"names":[],"mappings":"AAoBA,IAAI,SAAS,GAAY,YAAY,CAAC;AAEtC,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,OAAO;IACrB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC;AACrE,CAAC"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export declare const program: import("commander").Command;
|
|
3
|
+
/**
|
|
4
|
+
* Set to any non-empty value to silence the alias notice — for launchd plists,
|
|
5
|
+
* docker entrypoints and CI logs that were quiet before and should stay quiet.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SUPPRESS_ENV = "ACC_SUPPRESS_ALIAS_NOTICE";
|
|
8
|
+
/**
|
|
9
|
+
* Subcommands that must never gain a line of output. `_precommit-guard` runs
|
|
10
|
+
* inside `git commit`, where extra stderr is noise attached to every commit an
|
|
11
|
+
* agent makes.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SILENT_SUBCOMMANDS: Set<string>;
|
|
14
|
+
/**
|
|
15
|
+
* The alias notice. It deliberately does NOT name a removal date: the
|
|
16
|
+
* deprecation window is an operator decision that has not been made, and
|
|
17
|
+
* inventing one here would put a date in front of users that nobody agreed to.
|
|
18
|
+
* When the window is decided, this string is the single place it lands.
|
|
19
|
+
*/
|
|
20
|
+
export declare function aliasNotice(): string;
|
|
21
|
+
export declare function shouldWarnAlias(argv: string[], env?: NodeJS.ProcessEnv): boolean;
|
|
4
22
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA0BA,eAAO,MAAM,OAAO,6BAA4C,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,YAAY,8BAA8B,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,aAAgC,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAIT"}
|
package/dist/cli.js
CHANGED
|
@@ -1,303 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* acc-runner —
|
|
4
|
-
*
|
|
3
|
+
* `acc-runner` — the ORIGINAL bin, retained as a deprecated alias of `acc`.
|
|
4
|
+
*
|
|
5
|
+
* Everything this entry point could do before, it still does, with identical
|
|
6
|
+
* semantics: `acc-runner login` still enrols a machine, `acc-runner auth login`
|
|
7
|
+
* still signs a person in, `acc-runner watch` / `companion` / `doctor` are
|
|
8
|
+
* unchanged, and the hidden `_precommit-guard` hook re-invoke still resolves
|
|
9
|
+
* here. See program.ts for why `login` is the one verb whose meaning depends on
|
|
10
|
+
* which bin was typed.
|
|
11
|
+
*
|
|
12
|
+
* The only new behaviour is one stderr line naming the replacement. It goes to
|
|
13
|
+
* stderr on purpose — `acc-runner companion status` is consumed by menu-bar
|
|
14
|
+
* scripts that parse stdout, and a deprecation notice must not become a parse
|
|
15
|
+
* error in someone's status bar.
|
|
5
16
|
*/
|
|
6
|
-
import { realpathSync } from "node:fs";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
|
-
import { Command } from "commander";
|
|
9
17
|
import chalk from "chalk";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
import { logoutCommand } from "./logout.js";
|
|
14
|
-
import { watchCommand } from "./watch.js";
|
|
15
|
-
import { companionCommand, companionInstallCommand, companionStatusCommand, companionUninstallCommand, } from "./companion-run.js";
|
|
16
|
-
import { doctorCommand } from "./doctor.js";
|
|
17
|
-
import { clarifyCommand } from "./clarification.js";
|
|
18
|
-
import { clearQuarantine, getQuarantine } from "./runtime/quarantine.js";
|
|
19
|
-
import { clearChatCircuit, getChatCircuit } from "./runtime/chat-circuit-breaker.js";
|
|
20
|
-
import { runCommitGuardHook } from "./commit-guard.js";
|
|
21
|
-
import { PROTOCOL_VERSION } from "./types.js";
|
|
22
|
-
import { PACKAGE_VERSION } from "./pkg-version.js";
|
|
18
|
+
import { setInvokedAs } from "./cli-name.js";
|
|
19
|
+
import { buildProgram, isMainModule, runProgram } from "./program.js";
|
|
20
|
+
setInvokedAs("acc-runner");
|
|
23
21
|
// Exported so the enrollment-guidance contract test (tests/unit/) can parse the
|
|
24
22
|
// printed `acc-runner companion` command against the ACTUAL command tree without
|
|
25
23
|
// spawning the CLI — the auto-parse below is entry-guarded so importing this
|
|
26
24
|
// module never executes a command. See tests/unit/enroll-guidance-cli-contract.test.ts.
|
|
27
|
-
export const program =
|
|
28
|
-
program
|
|
29
|
-
.name("acc-runner")
|
|
30
|
-
.description("Agent Control Center local runner. Subscribes to ACC, spawns Claude Code on assignment, and opens a PR when done.")
|
|
31
|
-
.version(`${PACKAGE_VERSION} (protocol v${PROTOCOL_VERSION})`);
|
|
32
|
-
program
|
|
33
|
-
.command("login")
|
|
34
|
-
.description("Sign in via device-code OAuth and register this machine.")
|
|
35
|
-
.action(async () => {
|
|
36
|
-
try {
|
|
37
|
-
await loginCommand();
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
41
|
-
process.exitCode = 1;
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
program
|
|
45
|
-
.command("logout")
|
|
46
|
-
.description("Clear the local session and mark this runner offline.")
|
|
47
|
-
.action(async () => {
|
|
48
|
-
try {
|
|
49
|
-
await logoutCommand();
|
|
50
|
-
}
|
|
51
|
-
catch (err) {
|
|
52
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
53
|
-
process.exitCode = 1;
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
program
|
|
57
|
-
.command("watch")
|
|
58
|
-
.description("Long-running. Receive task assignments and execute them.")
|
|
59
|
-
.action(async () => {
|
|
60
|
-
try {
|
|
61
|
-
// Warm the cost-pricing cache before the realtime loop opens.
|
|
62
|
-
// fetchPricing handles its own logging; embedded fallback governs
|
|
63
|
-
// if the endpoint is unreachable.
|
|
64
|
-
await fetchPricing(loadConfig().publicUrl);
|
|
65
|
-
await watchCommand();
|
|
66
|
-
// Keep the process alive — stop() runs in the SIGINT handler.
|
|
67
|
-
await new Promise(() => { });
|
|
68
|
-
}
|
|
69
|
-
catch (err) {
|
|
70
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
71
|
-
process.exitCode = 1;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
// CC-3C (COMPANION): companion mode — an owner-affinity chat runner. Serves
|
|
75
|
-
// ONLY the logged-in owner's interactive chat turns (no code tasks), mirrors
|
|
76
|
-
// the turn stream to the same-machine browser over a loopback socket, and on
|
|
77
|
-
// exit requeues in-flight turns so an Auto turn fails over to the fleet.
|
|
78
|
-
const companionCmd = program
|
|
79
|
-
.command("companion")
|
|
80
|
-
.description("Long-running. Serve the owner's interactive chat turns (companion mode).")
|
|
81
|
-
.action(async () => {
|
|
82
|
-
try {
|
|
83
|
-
const handle = await companionCommand();
|
|
84
|
-
const shutdown = () => {
|
|
85
|
-
void handle.stop().finally(() => process.exit(0));
|
|
86
|
-
};
|
|
87
|
-
process.on("SIGINT", shutdown);
|
|
88
|
-
process.on("SIGTERM", shutdown);
|
|
89
|
-
// Keep the process alive; the loop runs on timers until a signal.
|
|
90
|
-
await new Promise(() => { });
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
94
|
-
process.exitCode = 1;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
companionCmd
|
|
98
|
-
.command("status")
|
|
99
|
-
.description("Print the one-line companion status (menu-bar friendly).")
|
|
100
|
-
.action(async () => {
|
|
101
|
-
try {
|
|
102
|
-
await companionStatusCommand();
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
106
|
-
process.exitCode = 1;
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
companionCmd
|
|
110
|
-
.command("install")
|
|
111
|
-
.description("Install the companion login agent (autostart at login).")
|
|
112
|
-
.action(async () => {
|
|
113
|
-
try {
|
|
114
|
-
await companionInstallCommand();
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
118
|
-
process.exitCode = 1;
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
companionCmd
|
|
122
|
-
.command("uninstall")
|
|
123
|
-
.description("Remove the companion login agent.")
|
|
124
|
-
.action(async () => {
|
|
125
|
-
try {
|
|
126
|
-
await companionUninstallCommand();
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
130
|
-
process.exitCode = 1;
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
program
|
|
134
|
-
.command("doctor")
|
|
135
|
-
.description("Run environment checks. Exit 0 if all green, 1 otherwise.")
|
|
136
|
-
.option("--strict", "Treat advisory warnings (missing ANTHROPIC_API_KEY, version drift, etc.) as failures.")
|
|
137
|
-
.action(async (opts) => {
|
|
138
|
-
const code = await doctorCommand({ strict: opts.strict === true });
|
|
139
|
-
process.exitCode = code;
|
|
140
|
-
});
|
|
141
|
-
// SH-6 NEEDS-INFO-HALT: a spawned agent that needs clarification / approval /
|
|
142
|
-
// missing information raises a needs_clarification halt for its task and hands
|
|
143
|
-
// the question off to JOJO, instead of guessing or dead-lettering. The operator
|
|
144
|
-
// answers by resolving the halt, which resumes the SAME task blocked -> queued.
|
|
145
|
-
program
|
|
146
|
-
.command("clarify")
|
|
147
|
-
.description("Raise a needs_clarification halt for a task and hand the question off to JOJO.")
|
|
148
|
-
.requiredOption("--task <id>", "Task id the agent is blocked on (e.g. T-1234).")
|
|
149
|
-
.requiredOption("--question <text>", "The question / missing info the operator must answer.")
|
|
150
|
-
.option("--context <json>", "Optional JSON object merged into the halt payload.")
|
|
151
|
-
.action(async (opts) => {
|
|
152
|
-
try {
|
|
153
|
-
await clarifyCommand(opts);
|
|
154
|
-
}
|
|
155
|
-
catch (err) {
|
|
156
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
157
|
-
process.exitCode = 1;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
// v0.48: quarantine management. The runner enters quarantine automatically
|
|
161
|
-
// when the failure classifier detects a machine-level failure. An operator
|
|
162
|
-
// resolves the underlying issue then clears the quarantine to resume work.
|
|
163
|
-
const quarantineCmd = program
|
|
164
|
-
.command("quarantine")
|
|
165
|
-
.description("Inspect or clear the runner quarantine state.");
|
|
166
|
-
quarantineCmd
|
|
167
|
-
.command("status")
|
|
168
|
-
.description("Show quarantine state.")
|
|
169
|
-
.action(async () => {
|
|
170
|
-
try {
|
|
171
|
-
const q = await getQuarantine();
|
|
172
|
-
if (!q) {
|
|
173
|
-
console.log("Runner is not quarantined.");
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
console.log(chalk.red.bold(`QUARANTINED (${q.cause})`));
|
|
177
|
-
console.log(` Detail: ${q.detail}`);
|
|
178
|
-
console.log(` Task: ${q.taskId}`);
|
|
179
|
-
console.log(` Since: ${q.classifiedAt}`);
|
|
180
|
-
// v0.53 T-53-4: consecutive instant-empty count (1 = definitive,
|
|
181
|
-
// 2 = heuristic confirmed by retry). Omitted for pre-0.53 states.
|
|
182
|
-
if (q.consecutive !== undefined) {
|
|
183
|
-
console.log(` Streak: ${q.consecutive} consecutive instant-empty exit(s)`);
|
|
184
|
-
}
|
|
185
|
-
console.log(chalk.gray(`\nResolve the underlying ${q.cause} issue, then run \`acc-runner quarantine clear\`.`));
|
|
186
|
-
process.exitCode = 1;
|
|
187
|
-
}
|
|
188
|
-
catch (err) {
|
|
189
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
190
|
-
process.exitCode = 1;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
quarantineCmd
|
|
194
|
-
.command("clear")
|
|
195
|
-
.description("Clear quarantine and allow the runner to resume claiming tasks.")
|
|
196
|
-
.action(async () => {
|
|
197
|
-
try {
|
|
198
|
-
await clearQuarantine();
|
|
199
|
-
console.log(chalk.green("✓ Quarantine cleared. Runner will resume on next task assignment."));
|
|
200
|
-
}
|
|
201
|
-
catch (err) {
|
|
202
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
203
|
-
process.exitCode = 1;
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
// CC-1B (TURN-LANE): chat-circuit management. The runner opens the chat circuit
|
|
207
|
-
// automatically when a `claude_exit_1`-class fault surfaces while serving a chat
|
|
208
|
-
// turn — benching ONLY the chat lane (code/review keep running). An operator
|
|
209
|
-
// resolves the credential/host issue then clears the circuit to resume chat.
|
|
210
|
-
const chatCircuitCmd = program
|
|
211
|
-
.command("chat-circuit")
|
|
212
|
-
.description("Inspect or clear the chat-capability circuit breaker (chat lane only).");
|
|
213
|
-
chatCircuitCmd
|
|
214
|
-
.command("status")
|
|
215
|
-
.description("Show chat circuit state.")
|
|
216
|
-
.action(async () => {
|
|
217
|
-
try {
|
|
218
|
-
const c = await getChatCircuit();
|
|
219
|
-
if (!c) {
|
|
220
|
-
console.log("Chat circuit is closed (chat lane serving).");
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
console.log(chalk.red.bold(`CHAT CIRCUIT OPEN (${c.cause})`));
|
|
224
|
-
console.log(` Detail: ${c.detail}`);
|
|
225
|
-
console.log(` Turn: ${c.turnId}`);
|
|
226
|
-
console.log(` Conversation: ${c.conversationId}`);
|
|
227
|
-
console.log(` Since: ${c.trippedAt}`);
|
|
228
|
-
console.log(chalk.gray(`\nResolve the underlying ${c.cause} issue, then run \`acc-runner chat-circuit clear\`. ` +
|
|
229
|
-
`Code/review lanes are unaffected.`));
|
|
230
|
-
process.exitCode = 1;
|
|
231
|
-
}
|
|
232
|
-
catch (err) {
|
|
233
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
234
|
-
process.exitCode = 1;
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
chatCircuitCmd
|
|
238
|
-
.command("clear")
|
|
239
|
-
.description("Close the chat circuit and allow the runner to resume claiming chat turns.")
|
|
240
|
-
.action(async () => {
|
|
241
|
-
try {
|
|
242
|
-
await clearChatCircuit();
|
|
243
|
-
console.log(chalk.green("✓ Chat circuit closed. Runner will resume claiming chat turns."));
|
|
244
|
-
}
|
|
245
|
-
catch (err) {
|
|
246
|
-
console.error(chalk.red(`✗ ${err.message}`));
|
|
247
|
-
process.exitCode = 1;
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
// RR-4: the git pre-commit hook the runner installs into a
|
|
251
|
-
// task worktree (see commit-guard.ts) re-invokes this hidden subcommand. It
|
|
252
|
-
// scans the STAGED text files and exits non-zero (with an actionable message on
|
|
253
|
-
// stderr) when a NUL byte / invalid UTF-8 / binary-blob-where-text is found, so
|
|
254
|
-
// git aborts the commit and the agent fixes it in-session. Hidden — it is a hook
|
|
255
|
-
// entry point, not an operator command.
|
|
256
|
-
program
|
|
257
|
-
.command("_precommit-guard", { hidden: true })
|
|
258
|
-
.description("Internal: commit-time mechanical guard (pre-commit hook entry).")
|
|
259
|
-
.action(async () => {
|
|
260
|
-
try {
|
|
261
|
-
const result = await runCommitGuardHook();
|
|
262
|
-
if (!result.ok) {
|
|
263
|
-
console.error(result.message);
|
|
264
|
-
process.exitCode = 1;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
catch (err) {
|
|
268
|
-
// Fail OPEN on an internal error: a guard bug must never wedge the agent's
|
|
269
|
-
// ability to commit. The pre-PR gate (prepr-gate.ts) is the backstop.
|
|
270
|
-
console.error(chalk.yellow(`acc-runner commit-guard skipped (internal error): ${err.message}`));
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
program
|
|
274
|
-
.command("version")
|
|
275
|
-
.description("Print CLI + protocol versions.")
|
|
276
|
-
.action(() => {
|
|
277
|
-
console.log(`acc-runner ${PACKAGE_VERSION}`);
|
|
278
|
-
console.log(`protocol ${PROTOCOL_VERSION}`);
|
|
279
|
-
});
|
|
25
|
+
export const program = buildProgram({ invokedAs: "acc-runner" });
|
|
280
26
|
/**
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* a test. realpath resolves the npm bin symlink to dist/cli.js so the compare
|
|
284
|
-
* holds for a globally-installed CLI.
|
|
27
|
+
* Set to any non-empty value to silence the alias notice — for launchd plists,
|
|
28
|
+
* docker entrypoints and CI logs that were quiet before and should stay quiet.
|
|
285
29
|
*/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
30
|
+
export const SUPPRESS_ENV = "ACC_SUPPRESS_ALIAS_NOTICE";
|
|
31
|
+
/**
|
|
32
|
+
* Subcommands that must never gain a line of output. `_precommit-guard` runs
|
|
33
|
+
* inside `git commit`, where extra stderr is noise attached to every commit an
|
|
34
|
+
* agent makes.
|
|
35
|
+
*/
|
|
36
|
+
export const SILENT_SUBCOMMANDS = new Set(["_precommit-guard"]);
|
|
37
|
+
/**
|
|
38
|
+
* The alias notice. It deliberately does NOT name a removal date: the
|
|
39
|
+
* deprecation window is an operator decision that has not been made, and
|
|
40
|
+
* inventing one here would put a date in front of users that nobody agreed to.
|
|
41
|
+
* When the window is decided, this string is the single place it lands.
|
|
42
|
+
*/
|
|
43
|
+
export function aliasNotice() {
|
|
44
|
+
return ("acc-runner is now `acc`. Every command works the same under the new name " +
|
|
45
|
+
"— `acc-runner login` is `acc runner login`, `acc-runner auth login` is `acc login`.\n" +
|
|
46
|
+
`The acc-runner alias still works; set ${SUPPRESS_ENV}=1 to hide this notice.`);
|
|
47
|
+
}
|
|
48
|
+
export function shouldWarnAlias(argv, env = process.env) {
|
|
49
|
+
if (env[SUPPRESS_ENV])
|
|
294
50
|
return false;
|
|
295
|
-
|
|
51
|
+
const first = argv.slice(2).find((arg) => !arg.startsWith("-"));
|
|
52
|
+
return !(first && SILENT_SUBCOMMANDS.has(first));
|
|
296
53
|
}
|
|
297
|
-
if (isMainModule()) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
});
|
|
54
|
+
if (isMainModule(import.meta.url)) {
|
|
55
|
+
if (shouldWarnAlias(process.argv))
|
|
56
|
+
process.stderr.write(`${chalk.yellow(aliasNotice())}\n`);
|
|
57
|
+
runProgram(program);
|
|
302
58
|
}
|
|
303
59
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtE,YAAY,CAAC,YAAY,CAAC,CAAC;AAE3B,gFAAgF;AAChF,iFAAiF;AACjF,6EAA6E;AAC7E,wFAAwF;AACxF,MAAM,CAAC,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;AAEjE;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,2BAA2B,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,CACL,2EAA2E;QAC3E,uFAAuF;QACvF,yCAAyC,YAAY,yBAAyB,CAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAc,EACd,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,CAAC,KAAK,IAAI,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,IAAI,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5F,UAAU,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC"}
|
package/dist/keychain.d.ts
CHANGED
|
@@ -15,6 +15,23 @@ type KeytarLike = {
|
|
|
15
15
|
export declare function saveSession(session: StoredSession): Promise<void>;
|
|
16
16
|
export declare function loadSession(): Promise<StoredSession | null>;
|
|
17
17
|
export declare function clearSession(): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* AX-G1: a SECOND entry in the same keychain service, under a different account.
|
|
20
|
+
*
|
|
21
|
+
* The runner session lives at (service "acc-runner", account "default") and its
|
|
22
|
+
* JSON shape is a frozen contract. A person's CLI session is a different
|
|
23
|
+
* credential with a different shape and a different lifecycle — it is the
|
|
24
|
+
* human's own Supabase session, not a runner impersonation token — so it gets
|
|
25
|
+
* its own account slot rather than being squeezed into the frozen one. A machine
|
|
26
|
+
* that is both a runner and a signed-in workstation holds both, independently,
|
|
27
|
+
* and `acc-runner logout` still only clears the runner's.
|
|
28
|
+
*
|
|
29
|
+
* Same rule as the runner slot: the keychain is the ONLY writable surface for a
|
|
30
|
+
* credential. Nothing here ever touches the filesystem.
|
|
31
|
+
*/
|
|
32
|
+
export declare function saveSlot(account: string, value: unknown): Promise<void>;
|
|
33
|
+
export declare function loadSlot<T>(account: string): Promise<T | null>;
|
|
34
|
+
export declare function clearSlot(account: string): Promise<boolean>;
|
|
18
35
|
/** Test-only seam used by the keychain test (overrides the lazy import). */
|
|
19
36
|
export declare function __setKeytar(impl: KeytarLike | null): void;
|
|
20
37
|
export {};
|
package/dist/keychain.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAIzE,KAAK,UAAU,GAAG;IAChB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE,CAAC;AAYF,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAUjE;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAGrD;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAEzD"}
|
|
1
|
+
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../src/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAIzE,KAAK,UAAU,GAAG;IAChB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE,CAAC;AAYF,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAUjE;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAGrD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7E;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAWpE;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGjE;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAEzD"}
|