@aeolus-fleet/trierarch 0.33.1 → 0.35.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 +7 -4
- package/dist/adapters/claude-code-setup.d.ts +11 -0
- package/dist/adapters/claude-code-setup.js +60 -0
- package/dist/adapters/claude-code-setup.js.map +1 -1
- package/dist/adapters/claude-code-usage.d.ts +2 -0
- package/dist/adapters/claude-code-usage.js +16 -12
- package/dist/adapters/claude-code-usage.js.map +1 -1
- package/dist/adapters/claude-code.d.ts +21 -18
- package/dist/adapters/claude-code.js +46 -36
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/clone-workspace.js +4 -0
- package/dist/adapters/clone-workspace.js.map +1 -1
- package/dist/adapters/codex-setup.d.ts +2 -0
- package/dist/adapters/codex-setup.js +6 -0
- package/dist/adapters/codex-setup.js.map +1 -1
- package/dist/adapters/codex-usage.d.ts +2 -0
- package/dist/adapters/codex-usage.js +16 -11
- package/dist/adapters/codex-usage.js.map +1 -1
- package/dist/adapters/codex.d.ts +2 -0
- package/dist/adapters/codex.js +31 -3
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/container.d.ts +36 -15
- package/dist/adapters/container.js +72 -93
- package/dist/adapters/container.js.map +1 -1
- package/dist/adapters/copilot-detector.d.ts +13 -0
- package/dist/adapters/copilot-detector.js +62 -0
- package/dist/adapters/copilot-detector.js.map +1 -0
- package/dist/adapters/copilot.d.ts +79 -0
- package/dist/adapters/copilot.js +187 -0
- package/dist/adapters/copilot.js.map +1 -0
- package/dist/adapters/core-version.d.ts +1 -1
- package/dist/adapters/core-version.js +1 -1
- package/dist/adapters/detectors.js +6 -0
- package/dist/adapters/detectors.js.map +1 -1
- package/dist/adapters/files.d.ts +16 -0
- package/dist/adapters/files.js +5 -0
- package/dist/adapters/files.js.map +1 -1
- package/dist/adapters/harnesses.d.ts +3 -2
- package/dist/adapters/harnesses.js +21 -9
- package/dist/adapters/harnesses.js.map +1 -1
- package/dist/adapters/hold-runtime.d.ts +19 -5
- package/dist/adapters/hold-runtime.js +23 -10
- package/dist/adapters/hold-runtime.js.map +1 -1
- package/dist/adapters/hold.d.ts +12 -0
- package/dist/adapters/hold.js +66 -31
- package/dist/adapters/hold.js.map +1 -1
- package/dist/adapters/json-state.js +5 -0
- package/dist/adapters/json-state.js.map +1 -1
- package/dist/adapters/key-files.d.ts +16 -0
- package/dist/adapters/key-files.js +28 -0
- package/dist/adapters/key-files.js.map +1 -0
- package/dist/adapters/key-states.d.ts +21 -0
- package/dist/adapters/key-states.js +43 -0
- package/dist/adapters/key-states.js.map +1 -0
- package/dist/adapters/model-logins.d.ts +21 -0
- package/dist/adapters/model-logins.js +48 -0
- package/dist/adapters/model-logins.js.map +1 -0
- package/dist/adapters/model-proxy.d.ts +32 -0
- package/dist/adapters/model-proxy.js +171 -0
- package/dist/adapters/model-proxy.js.map +1 -0
- package/dist/adapters/paths.d.ts +4 -0
- package/dist/adapters/paths.js +2 -0
- package/dist/adapters/paths.js.map +1 -1
- package/dist/adapters/plugin.d.ts +11 -8
- package/dist/adapters/plugin.js +47 -13
- package/dist/adapters/plugin.js.map +1 -1
- package/dist/adapters/proxy-runtime.d.ts +31 -0
- package/dist/adapters/proxy-runtime.js +100 -0
- package/dist/adapters/proxy-runtime.js.map +1 -0
- package/dist/adapters/proxy-tokens.d.ts +25 -0
- package/dist/adapters/proxy-tokens.js +67 -0
- package/dist/adapters/proxy-tokens.js.map +1 -0
- package/dist/adapters/rest-fleet.js +3 -5
- package/dist/adapters/rest-fleet.js.map +1 -1
- package/dist/adapters/runtime-adapters.d.ts +11 -6
- package/dist/adapters/runtime-adapters.js +25 -11
- package/dist/adapters/runtime-adapters.js.map +1 -1
- package/dist/adapters/service.d.ts +3 -1
- package/dist/adapters/service.js +6 -2
- package/dist/adapters/service.js.map +1 -1
- package/dist/adapters/ship-sockets.d.ts +1 -1
- package/dist/adapters/ship-sockets.js +2 -2
- package/dist/adapters/ship-sockets.js.map +1 -1
- package/dist/adapters/tokens-per-login.d.ts +8 -0
- package/dist/adapters/tokens-per-login.js +15 -0
- package/dist/adapters/tokens-per-login.js.map +1 -0
- package/dist/adapters/trust.d.ts +2 -1
- package/dist/adapters/trust.js +4 -1
- package/dist/adapters/trust.js.map +1 -1
- package/dist/adapters/usage.d.ts +2 -0
- package/dist/adapters/usage.js +1 -1
- package/dist/adapters/usage.js.map +1 -1
- package/dist/adapters/vendor-answers.d.ts +6 -0
- package/dist/adapters/vendor-answers.js +38 -0
- package/dist/adapters/vendor-answers.js.map +1 -0
- package/dist/adapters/vendor-key-check.d.ts +23 -0
- package/dist/adapters/vendor-key-check.js +36 -0
- package/dist/adapters/vendor-key-check.js.map +1 -0
- package/dist/bin/aeolus-trierarch.js +7 -2
- package/dist/bin/aeolus-trierarch.js.map +1 -1
- package/dist/cli/add.d.ts +2 -2
- package/dist/cli/add.js +1 -1
- package/dist/cli/add.js.map +1 -1
- package/dist/cli/config-check.js +1 -1
- package/dist/cli/config-check.js.map +1 -1
- package/dist/cli/hold.js +13 -4
- package/dist/cli/hold.js.map +1 -1
- package/dist/cli/init.js +19 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/login.d.ts +72 -0
- package/dist/cli/login.js +114 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/main.js +89 -8
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/proxy.d.ts +2 -0
- package/dist/cli/proxy.js +58 -0
- package/dist/cli/proxy.js.map +1 -0
- package/dist/cli/run.js +31 -5
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/upgrade.d.ts +5 -3
- package/dist/cli/upgrade.js +9 -3
- package/dist/cli/upgrade.js.map +1 -1
- package/dist/core/argo-reports.d.ts +10 -0
- package/dist/core/argo-reports.js +17 -0
- package/dist/core/argo-reports.js.map +1 -1
- package/dist/core/check-session-runtime.js +3 -1
- package/dist/core/check-session-runtime.js.map +1 -1
- package/dist/core/check-settings.d.ts +2 -0
- package/dist/core/check-settings.js +6 -1
- package/dist/core/check-settings.js.map +1 -1
- package/dist/core/entry.d.ts +14 -0
- package/dist/core/entry.js.map +1 -1
- package/dist/core/login.d.ts +49 -0
- package/dist/core/login.js +24 -0
- package/dist/core/login.js.map +1 -0
- package/dist/core/ports.d.ts +39 -4
- package/dist/core/read-usage.d.ts +2 -1
- package/dist/core/read-usage.js +6 -3
- package/dist/core/read-usage.js.map +1 -1
- package/dist/core/reconciler.d.ts +5 -0
- package/dist/core/reconciler.js +12 -7
- package/dist/core/reconciler.js.map +1 -1
- package/dist/core/report-self.d.ts +6 -2
- package/dist/core/report-self.js +34 -8
- package/dist/core/report-self.js.map +1 -1
- package/dist/core/run-pass.d.ts +6 -1
- package/dist/core/run-pass.js +84 -14
- package/dist/core/run-pass.js.map +1 -1
- package/package.json +3 -4
- package/dist/adapters/claude-code-screen.d.ts +0 -1
- package/dist/adapters/claude-code-screen.js +0 -22
- package/dist/adapters/claude-code-screen.js.map +0 -1
- package/dist/adapters/held-command.d.ts +0 -13
- package/dist/adapters/held-command.js +0 -16
- package/dist/adapters/held-command.js.map +0 -1
- package/dist/adapters/launch-screen.d.ts +0 -14
- package/dist/adapters/launch-screen.js +0 -5
- package/dist/adapters/launch-screen.js.map +0 -1
- package/dist/adapters/stop-turn.d.ts +0 -13
- package/dist/adapters/stop-turn.js +0 -26
- package/dist/adapters/stop-turn.js.map +0 -1
- package/dist/adapters/tmux.d.ts +0 -13
- package/dist/adapters/tmux.js +0 -33
- package/dist/adapters/tmux.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Keeps the ships whose crew requests are assigned to it crewed on the machine it
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
On the machine that will run the sessions (macOS or Linux), with Node 26, `git`,
|
|
7
|
+
On the machine that will run the sessions (macOS or Linux), with Node 26, `git`, and Claude Code with the aeolus-fleet plugin for Claude Code, Codex with the aeolus-fleet plugin for Codex, or both, installed. Codex must be on the `PATH` as `codex`:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
npm install --global @aeolus-fleet/trierarch
|
|
@@ -41,6 +41,7 @@ That gives the command `aeolus-trierarch`.
|
|
|
41
41
|
| `aeolus-trierarch list` | The ships it crews: ship, state, harness, workspace, since, restarts |
|
|
42
42
|
| `aeolus-trierarch logs [--lines <n>] [--follow]` | The last lines of the log, and with `--follow` each new one: on macOS `~/.aeolus/trierarch/logs/trierarch.log`, where the launchd agent writes, with the log before it in `trierarch.log.1` (docs/trierarch.md says when it moves aside); on Linux the journal the systemd user unit writes to, read through `journalctl --user --unit aeolus-trierarch.service`. The log holds one JSON record per line: each action the loop takes for a ship (crew, launch, wake, report, release, confirm, forget, leave, stop) as `{ time, shipId, shipName, action, outcome, next }`, where `next` says what happens after a failure, or a message as `{ time, level, message }`. `logs` renders them as text, and `--json` gives the records as they are (a line that is no record as `{ line }`). `run` in a terminal writes the text |
|
|
43
43
|
| `aeolus-trierarch add repository <name> <path>`, `aeolus-trierarch add folder <name> <path>` | Adds a repository to make worktrees of, or a folder to crew a ship in as it is, checked as init checks it, and trusts it for every configured harness in one step: adding a place is what trusts it. Then it restarts the service so the trierarch offers it, and waits until the new process says its version (at most 30 seconds); sessions keep running. A place written into `config.json` by hand is never offered and never crewed until it is added |
|
|
44
|
+
| `aeolus-trierarch login`, `aeolus-trierarch login <harness> --api-key`, `aeolus-trierarch login <harness> --remove-key`, `aeolus-trierarch login <harness> --default api-key\|subscription`, `aeolus-trierarch login --ship <name> api-key\|subscription\|default`, `aeolus-trierarch login <harness> --check` | `--check` has the model proxy check a key out of credit at once, as it does every 15 minutes. Alone, gives each harness's default login, whether it holds an API key, and each ship on a login of its own. `--default` sets the login a harness's sessions run on, `--ship` a ship's own login or its harness's default again, in the configuration's `logins`, each from a session's next start. With `--api-key`, reads a key for `claude-code` (Anthropic) or `codex` (OpenAI) from stdin, without echo when typed at a terminal, never from a flag; checks it with one free call to the vendor's model list and keeps it in `~/.aeolus/trierarch/keys/<harness>` (mode 600) only when the vendor takes it, else says the vendor's status and error code and writes nothing. `--remove-key` removes it. Each change restarts the service; sessions keep running. The key is never said back, logged or put in the configuration |
|
|
44
45
|
| `aeolus-trierarch config check` | Checks the configuration and gives the flags each harness launches with, and each option value's flags. Then the command each harness launches on a first start and on a restart, with each flag marked `(configuration)` or `(adapter)` when the adapter adds it itself (`--json` for Codex, `--continue` on a Claude Code restart, `--permission-mode manual` (or `default`) where Claude Code's settings make plan the default mode, with when it applies where the folder's settings decide) |
|
|
45
46
|
| `aeolus-trierarch detect` | Detects again what each configured harness offers (its models, and effort where its CLI has a flag for it) and keeps it in `~/.aeolus/trierarch/detected.json`, then gives per harness its version, each option's values and when its models were last confirmed. Restart the trierarch so it reads them ([docs/trierarch.md](../../docs/trierarch.md#detected-options)) |
|
|
46
47
|
| `aeolus-trierarch start`, `stop`, `restart` | The service. `stop` returns once the trierarch has exited; a stopped one starts again at the next login. `start` and `restart` return once the new process says its version (at most 30 seconds). Restart it after you change the configuration |
|
|
@@ -52,7 +53,7 @@ That gives the command `aeolus-trierarch`.
|
|
|
52
53
|
|
|
53
54
|
Every command takes `--json`, so a ship can read what it says, and `--config <path>`. `status`, `list` and `logs` read what is on the machine and send no message; `status` asks the fleet `whoami` once, for the lease.
|
|
54
55
|
|
|
55
|
-
To stop the trierarch: `aeolus-trierarch stop`, or `aeolus-trierarch uninstall` to keep it from starting at login.
|
|
56
|
+
To stop the trierarch: `aeolus-trierarch stop`, or `aeolus-trierarch uninstall` to keep it from starting at login. Each session runs under a hold of its own, in a container of its own with the container runtime, and has no terminal to attach to: what it writes is in `~/.aeolus/trierarch/sessions/<ship id>/events.jsonl`.
|
|
56
57
|
|
|
57
58
|
## Configure
|
|
58
59
|
|
|
@@ -87,6 +88,7 @@ To stop the trierarch: `aeolus-trierarch stop`, or `aeolus-trierarch uninstall`
|
|
|
87
88
|
- **harnesses**: `claude-code`, `codex` or both: the flags every launch gets, and named options. A crew request's settings pick option values by name; they never add a flag or carry a path. There is no policy on which flags: put `--dangerously-skip-permissions` in `flags` if you want it. The trierarch never adds a flag by itself. `--remote-control` is refused on every runtime; `aeolus-trierarch upgrade` takes it out of a configuration that has it. Claude Code's `--permission-mode plan`, in `flags` or an option, is ignored: a crewed session runs without plan mode's tools, so it could never leave plan mode (#465); `config check` shows the command without it. For the same reason, when Claude Code's settings make `plan` the default mode and the flags name no permission mode, a launch adds `--permission-mode manual`, or `default` where the detected Claude Code's `--help` lists no `manual` mode (#505, #507, #517). It reads `permissions.defaultMode` where Claude Code does, the first that names one winning: the managed settings files (`managed-settings.json`, then `managed-settings.d/*.json`, in `/Library/Application Support/ClaudeCode` or `/etc/claude-code`), `--settings` in the flags (JSON, or a file, relative to the folder), then of the sources `--setting-sources` loads (none with `--restricted`) the folder's `.claude/settings.local.json`, its `.claude/settings.json` and the user's `settings.json` (in `CLAUDE_CONFIG_DIR` when set, else `~/.claude`). A plan default mode from server-managed settings or a macOS configuration profile is not overridden: those are an admin's deliberate policy, and are not read. `config check` shows the override as the launch adds it, and where the folder's settings decide, with when it applies.
|
|
88
89
|
|
|
89
90
|
- **prices** (optional): the price per model, in US dollars per million tokens of each kind, that the cost of a ship's tokens is estimated by in its report: `{ "claude-opus-5-5": { "input": 4, "output": 20, "cacheRead": 0.2, "cacheWrite": 8 } }`. It replaces a model's list price, which the trierarch carries for the current Claude and OpenAI models, or prices one it does not carry ([docs/trierarch.md](../../docs/trierarch.md#what-a-trierarch-reports)).
|
|
91
|
+
- **logins** (optional): which login each session runs on, an API key or its harness's subscription: `{ "default": { "claude-code": "apiKey" }, "ships": { "build-docs": "subscription" } }`. A ship's login is its entry in `ships`, else its harness's `default`, else `subscription`. Values are `apiKey` or `subscription`, never a key or a path: the key is kept by `aeolus-trierarch login <harness> --api-key`, which also sets these ([docs/trierarch.md](../../docs/trierarch.md#api-keys)).
|
|
90
92
|
|
|
91
93
|
`aeolus-trierarch init` writes caps, repositories, folders, and Claude Code's and Codex's flags, and detects each harness's models and effort levels into `detected.json` ([docs/trierarch.md](../../docs/trierarch.md#detected-options)). Options you write here replace the detected option of the same name whole, except `model`: model ids come from detection only, and a `model` here is ignored (#382). The example above narrows Claude Code's effort to two levels with a default, and takes the detected models as they are. Edit the file for options and `worktreeRoot`, then `aeolus-trierarch config check` and `aeolus-trierarch restart`.
|
|
92
94
|
|
|
@@ -101,9 +103,10 @@ The trierarch finds the aeolus-fleet plugin in each offered harness's plugin cac
|
|
|
101
103
|
- the ports.
|
|
102
104
|
- **Adapters** (`src/adapters`):
|
|
103
105
|
- the fleet over REST;
|
|
104
|
-
- the hold (`aeolus-trierarch hold <ship id>`), one per
|
|
106
|
+
- the hold (`aeolus-trierarch hold <ship id>`), one per session, which runs the harness, or with the container runtime the container it runs in, keeps its input and output and writes its events to `~/.aeolus/trierarch/sessions/<ship id>/events.jsonl`;
|
|
105
107
|
- git worktrees and folders;
|
|
106
108
|
- Claude Code and Codex, through the aeolus-fleet plugin's `aeolus-identity.sh`. Each passes its prompt last, after `--`, so a prompt never reads as a flag. A Claude Code session on the host is `claude -p` with streamed JSON, handed each line on its stdin. A Codex session on the host is one `codex exec --json ... -- <prompt>` per turn: it starts with the first prompt, comes back with `codex exec resume --last`, and takes each later line as `codex exec resume <thread id>`;
|
|
109
|
+
- Copilot, through the same scripts of the aeolus-fleet plugin Copilot installed: one `copilot` per turn with JSON output, every tool allowed and no question tool, its prompt the value of `--prompt=`, each later turn and a restart resuming the session by the id its last result named. `init` does not ask about Copilot: to offer it, sign Copilot in (`copilot login`), install the plugin for it (its README), and add `"copilot": { "flags": [], "options": {} }` to the configuration's `harnesses`. The trierarch starts without that plugin, and names Copilot as not offered until it is installed. The machine offers it on Copilot CLI 1.0.105 on the host only;
|
|
107
110
|
- the JSON state store.
|
|
108
|
-
- **The command** (`src/cli`): `init`, `status`, `list`, `logs`, `config check`, `detect`, `hold`, `start`, `stop`, `restart`, `install`, `uninstall`, `run`.
|
|
111
|
+
- **The command** (`src/cli`): `init`, `status`, `list`, `logs`, `config check`, `detect`, `login`, `hold`, `start`, `stop`, `restart`, `install`, `uninstall`, `run`.
|
|
109
112
|
- **Adapters for the setup**: the service (launchd or systemd), Claude Code's own files and Codex's app server for their one-time questions.
|
|
@@ -39,6 +39,17 @@ export interface ClaudeCodeSetup {
|
|
|
39
39
|
settings?: string;
|
|
40
40
|
sources: readonly SettingSource[];
|
|
41
41
|
}): Promise<SettingsDefaultMode>;
|
|
42
|
+
/**
|
|
43
|
+
* What in the settings Claude Code reads would give a session a key instead
|
|
44
|
+
* of its subscription (api keys K6): an `apiKeyHelper`, or a key or cloud
|
|
45
|
+
* provider variable in `env`, named with where it is, never its value; none
|
|
46
|
+
* when nothing does. The same files as the default mode, every one of them.
|
|
47
|
+
*/
|
|
48
|
+
keyInReach(at: {
|
|
49
|
+
folder?: string;
|
|
50
|
+
settings?: string;
|
|
51
|
+
sources: readonly SettingSource[];
|
|
52
|
+
}): Promise<string | undefined>;
|
|
42
53
|
}
|
|
43
54
|
/** The settings files `--setting-sources` picks from. */
|
|
44
55
|
export type SettingSource = 'user' | 'project' | 'local';
|
|
@@ -58,6 +58,34 @@ async function commandLineDefaultMode(settings, folder) {
|
|
|
58
58
|
}
|
|
59
59
|
return folder === undefined ? undefined : defaultModeIn(join(folder, settings));
|
|
60
60
|
}
|
|
61
|
+
/** The variables in a settings file's `env` that sign Claude Code in with something other than its subscription. */
|
|
62
|
+
const KEY_VARIABLES = ['ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN', 'CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX', 'CLAUDE_CODE_USE_FOUNDRY'];
|
|
63
|
+
/** What in settings text gives a key, named, never its value; none for text that is no JSON object. */
|
|
64
|
+
function keyIn(text) {
|
|
65
|
+
const settings = jsonObjectSchema.safeParse(parsedJson(text)).data;
|
|
66
|
+
if (settings === undefined) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (typeof settings.apiKeyHelper === 'string' && settings.apiKeyHelper !== '') {
|
|
70
|
+
return 'apiKeyHelper';
|
|
71
|
+
}
|
|
72
|
+
const env = jsonObjectSchema.safeParse(settings.env).data ?? {};
|
|
73
|
+
return KEY_VARIABLES.find((variable) => typeof env[variable] === 'string' && env[variable] !== '');
|
|
74
|
+
}
|
|
75
|
+
function parsedJson(text) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(text);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** What in a settings file gives a key, with the file's path; none for a missing file. */
|
|
84
|
+
async function keyInFile(path) {
|
|
85
|
+
const text = await readFile(path, 'utf8').catch(() => undefined);
|
|
86
|
+
const found = text === undefined ? undefined : keyIn(text);
|
|
87
|
+
return found === undefined ? undefined : `${found} in ${path}`;
|
|
88
|
+
}
|
|
61
89
|
async function writeJsonObject(path, value) {
|
|
62
90
|
const mode = (await stat(path).catch(() => undefined))?.mode ?? PRIVATE_MODE;
|
|
63
91
|
await mkdir(dirname(path), { recursive: true });
|
|
@@ -99,6 +127,38 @@ export function createClaudeCodeSetup(at) {
|
|
|
99
127
|
const claude = await readJsonObject(state);
|
|
100
128
|
return claude.hasCompletedOnboarding === true && fullscreenOfferSeen(claude) >= FULLSCREEN_OFFER_SHOWN_MAX;
|
|
101
129
|
},
|
|
130
|
+
keyInReach: async ({ folder, settings: commandLine, sources }) => {
|
|
131
|
+
const dropIns = join(at.managedSettings, 'managed-settings.d');
|
|
132
|
+
const managed = [join(at.managedSettings, 'managed-settings.json'), ...(await readdir(dropIns).catch(() => [])).filter((file) => file.endsWith('.json') && !file.startsWith('.')).sort().map((file) => join(dropIns, file))];
|
|
133
|
+
for (const file of managed) {
|
|
134
|
+
const found = await keyInFile(file);
|
|
135
|
+
if (found !== undefined) {
|
|
136
|
+
return found;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (commandLine !== undefined) {
|
|
140
|
+
if (commandLine.trimStart().startsWith('{')) {
|
|
141
|
+
const found = keyIn(commandLine);
|
|
142
|
+
if (found !== undefined) {
|
|
143
|
+
return `${found} in --settings`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (isAbsolute(commandLine) || folder !== undefined) {
|
|
147
|
+
const found = await keyInFile(isAbsolute(commandLine) ? commandLine : join(folder ?? '', commandLine));
|
|
148
|
+
if (found !== undefined) {
|
|
149
|
+
return found;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (const source of SETTING_SOURCES.filter((source) => sources.includes(source))) {
|
|
154
|
+
const file = source === 'user' ? settings : folder === undefined ? undefined : join(folder, '.claude', source === 'local' ? 'settings.local.json' : 'settings.json');
|
|
155
|
+
const found = file === undefined ? undefined : await keyInFile(file);
|
|
156
|
+
if (found !== undefined) {
|
|
157
|
+
return found;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
},
|
|
102
162
|
defaultPermissionMode: async ({ folder, settings: commandLine, sources }) => {
|
|
103
163
|
const above = (await managedDefaultMode(at.managedSettings)) ?? (commandLine === undefined ? undefined : await commandLineDefaultMode(commandLine, folder));
|
|
104
164
|
if (above !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code-setup.js","sourceRoot":"","sources":["../../src/adapters/claude-code-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code-setup.js","sourceRoot":"","sources":["../../src/adapters/claude-code-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ShipId } from '@aeolus-fleet/common';
|
|
2
|
+
import { type SessionLogins } from '../core/login.js';
|
|
2
3
|
import type { ModelTokens, SubscriptionWindow } from '../core/ports.js';
|
|
3
4
|
import type { CommandResult } from './run-command.js';
|
|
4
5
|
export declare function createClaudeCodeUsage(deps: {
|
|
@@ -18,6 +19,7 @@ export declare function createClaudeCodeUsage(deps: {
|
|
|
18
19
|
tokensOf: (ship: {
|
|
19
20
|
shipId: ShipId;
|
|
20
21
|
folder: string;
|
|
22
|
+
logins?: SessionLogins;
|
|
21
23
|
}) => Promise<ModelTokens[]>;
|
|
22
24
|
subscription: () => Promise<SubscriptionWindow[] | undefined>;
|
|
23
25
|
};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { readdir, rm } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { loginAt } from '../core/login.js';
|
|
4
5
|
import { createAppendedLines } from './appended-lines.js';
|
|
5
6
|
import { CLAUDE_CODE_PROBE_TIMEOUT_MS } from './claude-code-detector.js';
|
|
7
|
+
import { createTokensPerLogin } from './tokens-per-login.js';
|
|
6
8
|
/**
|
|
7
9
|
* What Claude Code says of its usage (#353). A ship's tokens come from the
|
|
8
10
|
* transcripts in its projects folder: its folder's conversations and their
|
|
9
11
|
* sub-agents', one line per content block, each line of a message carrying
|
|
10
|
-
* the message's whole usage, so each message counts once by its id
|
|
12
|
+
* the message's whole usage, so each message counts once by its id, to the
|
|
13
|
+
* login of the session that wrote it when the ship's logins are given (api
|
|
14
|
+
* keys K8). Its
|
|
11
15
|
* subscription comes from the rate limit event a print-mode turn streams,
|
|
12
16
|
* a short turn on the cheapest model, from an empty folder. Claude Code
|
|
13
17
|
* documents neither: the readers are tested on captured ones (test/logs).
|
|
@@ -42,9 +46,6 @@ function jsonOf(line) {
|
|
|
42
46
|
return undefined;
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
|
-
function plus(a, b) {
|
|
46
|
-
return a === undefined ? b : { input: a.input + b.input, output: a.output + b.output, cacheRead: a.cacheRead + b.cacheRead, cacheWrite: a.cacheWrite + b.cacheWrite };
|
|
47
|
-
}
|
|
48
49
|
/** The conversations Claude Code keeps of the folder: each `.jsonl` in its projects folder, and the sub-agents' of each. */
|
|
49
50
|
async function transcriptsIn(project) {
|
|
50
51
|
const entries = await readdir(project, { withFileTypes: true }).catch(() => []);
|
|
@@ -77,9 +78,11 @@ function windowsIn(stream) {
|
|
|
77
78
|
export function createClaudeCodeUsage(deps) {
|
|
78
79
|
const appended = createAppendedLines();
|
|
79
80
|
const transcripts = new Map();
|
|
80
|
-
|
|
81
|
+
// A transcript is read on, never again from its start: a message counted to a login stays counted to it, as a later change of login is kept from its start on.
|
|
82
|
+
const readTranscript = async (path, at) => {
|
|
83
|
+
const { since, logins } = at;
|
|
81
84
|
const { lines, isFromStart } = await appended.read(path);
|
|
82
|
-
const totals = isFromStart ?
|
|
85
|
+
const totals = (isFromStart ? undefined : transcripts.get(path)) ?? { seen: new Set(), counted: createTokensPerLogin() };
|
|
83
86
|
for (const line of lines) {
|
|
84
87
|
const parsed = assistantLineSchema.safeParse(jsonOf(line));
|
|
85
88
|
if (!parsed.success || parsed.data.message.model === SYNTHETIC_MODEL || totals.seen.has(parsed.data.message.id) || Date.parse(parsed.data.timestamp) < since.getTime()) {
|
|
@@ -87,7 +90,8 @@ export function createClaudeCodeUsage(deps) {
|
|
|
87
90
|
}
|
|
88
91
|
const { id, model, usage } = parsed.data.message;
|
|
89
92
|
totals.seen.add(id);
|
|
90
|
-
|
|
93
|
+
const login = logins === undefined ? undefined : loginAt(logins, new Date(parsed.data.timestamp));
|
|
94
|
+
totals.counted.add({ model, ...(login !== undefined && { login }), tokens: { input: usage.input_tokens, output: usage.output_tokens, cacheRead: usage.cache_read_input_tokens ?? 0, cacheWrite: usage.cache_creation_input_tokens ?? 0 } });
|
|
91
95
|
}
|
|
92
96
|
transcripts.set(path, totals);
|
|
93
97
|
return totals;
|
|
@@ -96,13 +100,13 @@ export function createClaudeCodeUsage(deps) {
|
|
|
96
100
|
tokensOf: async (ship) => {
|
|
97
101
|
const since = await deps.madeAt(ship.folder);
|
|
98
102
|
const project = join(deps.projectsOf(ship.shipId), ship.folder.replace(/[^a-zA-Z0-9]/gu, '-'));
|
|
99
|
-
const
|
|
103
|
+
const counted = createTokensPerLogin();
|
|
100
104
|
for (const path of await transcriptsIn(project)) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
105
|
+
(await readTranscript(path, { since, logins: ship.logins })).counted.list().forEach((used) => {
|
|
106
|
+
counted.add(used);
|
|
107
|
+
});
|
|
104
108
|
}
|
|
105
|
-
return
|
|
109
|
+
return counted.list();
|
|
106
110
|
},
|
|
107
111
|
subscription: async () => {
|
|
108
112
|
const folder = await deps.neutralFolder();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code-usage.js","sourceRoot":"","sources":["../../src/adapters/claude-code-usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code-usage.js","sourceRoot":"","sources":["../../src/adapters/claude-code-usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAsB,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAuB,MAAM,uBAAuB,CAAC;AAElF;;;;;;;;;;GAUG;AAEH,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAC5B,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;QACd,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,2BAA2B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;KAC7K,CAAC;CACH,CAAC,CAAC;AAEH,sGAAsG;AACtG,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACnC,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;CACjI,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,cAAc,GAAqC,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAE/F,MAAM,WAAW,GAAG,OAAO,CAAC;AAC5B,MAAM,YAAY,GAAG,UAAU,CAAC;AAChC,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,+CAA+C;AAC/C,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAQD,4HAA4H;AAC5H,KAAK,UAAU,aAAa,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACjI,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,OAAO;SACJ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;SACtC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACtD,OAAO,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7H,CAAC,CAAC,CACL,CAAC;IACF,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,2GAA2G;AAC3G,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,MAAM,GAAG,MAAM;SAClB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;SAC3D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;QAC7F,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;QACjH,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IACrI,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IASrC;IACC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;IAExD,+JAA+J;IAC/J,MAAM,cAAc,GAAG,KAAK,EAAE,IAAY,EAAE,EAAsD,EAA6B,EAAE;QAC/H,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,EAAU,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,CAAC;QACjI,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBACvK,SAAS;YACX,CAAC;YACD,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YAClG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,EAAE,SAAS,EAAE,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,2BAA2B,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9O,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,IAAgE,EAA0B,EAAE;YAC3G,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;YAC/F,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;YACvC,KAAK,MAAM,IAAI,IAAI,MAAM,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChD,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;oBAC3F,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;QACD,YAAY,EAAE,KAAK,IAA+C,EAAE;YAClE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE;oBACtD,IAAI,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,CAAC;oBACrH,GAAG,EAAE,MAAM;oBACX,SAAS,EAAE,4BAA4B;iBACxC,CAAC,CAAC;gBACH,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClC,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -7,12 +7,11 @@ import { type AeolusPlugin } from './plugin-identity.js';
|
|
|
7
7
|
* Claude Code as a harness (docs/architecture.md, "First adapters"): `claude`
|
|
8
8
|
* in the folder, `--continue` on a restart when the folder has a conversation
|
|
9
9
|
* to continue, `/aeolus-fleet:wake` sent to wake an idle session, each prompt with
|
|
10
|
-
* the line that no human reads its terminal (#585).
|
|
11
|
-
*
|
|
12
|
-
* stream-json lines on stdin, each prompt one line, a busy turn stopped by
|
|
13
|
-
* hold, and a start that shows no activity explained by its last error
|
|
14
|
-
* (H13).
|
|
15
|
-
* S3 of the headless design. Always
|
|
10
|
+
* the line that no human reads its terminal (#585). It runs headless on every
|
|
11
|
+
* runtime (headless H11, H18): one long-lived `claude -p` taking user messages
|
|
12
|
+
* as stream-json lines on stdin, each prompt one line, a busy turn stopped by
|
|
13
|
+
* its hold, and a start that shows no activity explained by its last error
|
|
14
|
+
* event (H13). Always
|
|
16
15
|
* without AskUserQuestion and plan mode: nobody watches the session's pane, so
|
|
17
16
|
* it asks its questions over the fleet, and a question form or a plan approval
|
|
18
17
|
* waiting there would take the keys of a wake (#457, #460). Plan mode goes as a
|
|
@@ -44,20 +43,23 @@ export declare function claudeCodeSettingsDefaultMode(setup: Pick<ClaudeCodeSetu
|
|
|
44
43
|
flags: readonly string[];
|
|
45
44
|
folder?: string;
|
|
46
45
|
}): Promise<SettingsDefaultMode>;
|
|
46
|
+
/** What in the settings Claude Code reads with these flags would give a session a key instead of its subscription (api keys K6). */
|
|
47
|
+
type HarnessConfiguration = TrierarchConfiguration['harnesses'][string];
|
|
48
|
+
export declare function claudeCodeKeyInReach(setup: Pick<ClaudeCodeSetup, 'keyInReach'>, at: {
|
|
49
|
+
harness: HarnessConfiguration;
|
|
50
|
+
options: Readonly<Record<string, string>>;
|
|
51
|
+
folder?: string;
|
|
52
|
+
}): Promise<string | undefined>;
|
|
47
53
|
/**
|
|
48
|
-
* `claude`, headless in print mode with streamed JSON
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* the prompt is the first line on stdin instead.
|
|
54
|
+
* `claude`, headless in print mode with streamed JSON, the flags without plan
|
|
55
|
+
* mode, `--permission-mode manual` (or `default`, as the installed Claude Code
|
|
56
|
+
* lists) when the settings' default mode is plan and the flags name none (or
|
|
57
|
+
* where it depends on the folder, with when it applies), AskUserQuestion and
|
|
58
|
+
* plan mode disallowed, `--continue` on a restart. The prompt is no word of
|
|
59
|
+
* it: it is the first line on stdin.
|
|
55
60
|
*/
|
|
56
61
|
export declare function claudeCodeCommandLine(at: {
|
|
57
62
|
flags: readonly string[];
|
|
58
|
-
/** The first prompt in a terminal; none headless, where it is sent as the first line. */
|
|
59
|
-
prompt?: string;
|
|
60
|
-
isHeadless: boolean;
|
|
61
63
|
isFirstStart: boolean;
|
|
62
64
|
defaultPermissionMode?: SettingsDefaultMode;
|
|
63
65
|
permissionModes?: readonly string[] | undefined;
|
|
@@ -73,8 +75,6 @@ export declare function createClaudeCodeHarness(options: {
|
|
|
73
75
|
configuration: TrierarchConfiguration;
|
|
74
76
|
plugin: AeolusPlugin;
|
|
75
77
|
sessions: Pick<SessionRuntime, 'start' | 'send' | 'interrupt' | 'events'>;
|
|
76
|
-
/** Whether its sessions run headless, as on the host (headless H11), or in a terminal, as in a container until S3. */
|
|
77
|
-
isHeadless: boolean;
|
|
78
78
|
/** Claude Code's projects folder, where it keeps each folder's conversations. */
|
|
79
79
|
projects: string;
|
|
80
80
|
/** Claude Code's own files, where its onboarding is completed before each launch (#403) and its settings' default mode is read (#505, #507). */
|
|
@@ -88,4 +88,7 @@ export declare function createClaudeCodeHarness(options: {
|
|
|
88
88
|
permissionModes: () => readonly string[] | undefined;
|
|
89
89
|
/** The program to run; `claude` unless a test runs another. */
|
|
90
90
|
command?: string;
|
|
91
|
+
/** Where sessions on an API key reach the model proxy (headless H16); none before it first listened, or on a machine with no proxy. */
|
|
92
|
+
proxyUrl?: () => Promise<string | undefined>;
|
|
91
93
|
}): HarnessPort;
|
|
94
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readdir } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { createHostClaudeCodeHomes, createShipClaudeCodeHomes } from './claude-code-home.js';
|
|
4
|
-
import { claudeCodeScreenStoppedAt } from './claude-code-screen.js';
|
|
5
4
|
import { parsedLine } from './hold-protocol.js';
|
|
6
5
|
import { SETTING_SOURCES } from './claude-code-setup.js';
|
|
7
6
|
import { partsWithWords, wordsOf } from './command-line.js';
|
|
@@ -9,16 +8,16 @@ import { effectiveFlags } from '../core/effective-flags.js';
|
|
|
9
8
|
import { firstPromptOf, wakePromptOf } from '../core/no-terminal-questions.js';
|
|
10
9
|
import { createLaunchMarks } from './launch-marker.js';
|
|
11
10
|
import { createPluginIdentity } from './plugin-identity.js';
|
|
11
|
+
import { newProxyToken } from './proxy-tokens.js';
|
|
12
12
|
/**
|
|
13
13
|
* Claude Code as a harness (docs/architecture.md, "First adapters"): `claude`
|
|
14
14
|
* in the folder, `--continue` on a restart when the folder has a conversation
|
|
15
15
|
* to continue, `/aeolus-fleet:wake` sent to wake an idle session, each prompt with
|
|
16
|
-
* the line that no human reads its terminal (#585).
|
|
17
|
-
*
|
|
18
|
-
* stream-json lines on stdin, each prompt one line, a busy turn stopped by
|
|
19
|
-
* hold, and a start that shows no activity explained by its last error
|
|
20
|
-
* (H13).
|
|
21
|
-
* S3 of the headless design. Always
|
|
16
|
+
* the line that no human reads its terminal (#585). It runs headless on every
|
|
17
|
+
* runtime (headless H11, H18): one long-lived `claude -p` taking user messages
|
|
18
|
+
* as stream-json lines on stdin, each prompt one line, a busy turn stopped by
|
|
19
|
+
* its hold, and a start that shows no activity explained by its last error
|
|
20
|
+
* event (H13). Always
|
|
22
21
|
* without AskUserQuestion and plan mode: nobody watches the session's pane, so
|
|
23
22
|
* it asks its questions over the fleet, and a question form or a plan approval
|
|
24
23
|
* waiting there would take the keys of a wake (#457, #460). Plan mode goes as a
|
|
@@ -45,7 +44,6 @@ const HEADLESS = ['-p', '--input-format', 'stream-json', '--output-format', 'str
|
|
|
45
44
|
const CONTINUE = '--continue';
|
|
46
45
|
/** Lets the session read a folder beside its own without asking: each of its read-only checkouts (#1182). */
|
|
47
46
|
const ADD_DIR = '--add-dir';
|
|
48
|
-
const END_OF_FLAGS = '--';
|
|
49
47
|
const NO_PANE_PROMPTS = '--disallowedTools=AskUserQuestion,EnterPlanMode,ExitPlanMode';
|
|
50
48
|
const PERMISSION_MODE = '--permission-mode';
|
|
51
49
|
const PLAN_MODE = 'plan';
|
|
@@ -91,6 +89,12 @@ export function claudeCodeSettingsDefaultMode(setup, at) {
|
|
|
91
89
|
const settings = valueOf(at.flags, SETTINGS);
|
|
92
90
|
return setup.defaultPermissionMode({ sources: settingSourcesOf(at.flags), ...(at.folder !== undefined && { folder: at.folder }), ...(settings !== undefined && { settings }) });
|
|
93
91
|
}
|
|
92
|
+
export function claudeCodeKeyInReach(setup, at) {
|
|
93
|
+
// The flags the session would start with, the picked options' own among them, as launch takes them.
|
|
94
|
+
const flags = effectiveFlags(at.harness, at.options);
|
|
95
|
+
const settings = valueOf(flags, SETTINGS);
|
|
96
|
+
return setup.keyInReach({ sources: settingSourcesOf(flags), ...(at.folder !== undefined && { folder: at.folder }), ...(settings !== undefined && { settings }) });
|
|
97
|
+
}
|
|
94
98
|
/** `--permission-mode manual` (or `default` where the installed Claude Code lists no manual) where the settings' default mode is plan and the flags name none, and with when it applies where that depends on the folder. */
|
|
95
99
|
function planOverride(flags, installed) {
|
|
96
100
|
const { defaultMode, permissionModes } = installed;
|
|
@@ -101,25 +105,23 @@ function planOverride(flags, installed) {
|
|
|
101
105
|
return { words: [PERMISSION_MODE, mode], source: 'adapter', ...(defaultMode.kind === 'per folder' && { when: WHEN_PLAN_PER_FOLDER }) };
|
|
102
106
|
}
|
|
103
107
|
/**
|
|
104
|
-
* `claude`, headless in print mode with streamed JSON
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* the prompt is the first line on stdin instead.
|
|
108
|
+
* `claude`, headless in print mode with streamed JSON, the flags without plan
|
|
109
|
+
* mode, `--permission-mode manual` (or `default`, as the installed Claude Code
|
|
110
|
+
* lists) when the settings' default mode is plan and the flags name none (or
|
|
111
|
+
* where it depends on the folder, with when it applies), AskUserQuestion and
|
|
112
|
+
* plan mode disallowed, `--continue` on a restart. The prompt is no word of
|
|
113
|
+
* it: it is the first line on stdin.
|
|
111
114
|
*/
|
|
112
115
|
export function claudeCodeCommandLine(at) {
|
|
113
116
|
const flags = withoutPlanMode(at.flags);
|
|
114
117
|
return partsWithWords([
|
|
115
118
|
{ words: [at.program ?? 'claude'] },
|
|
116
|
-
{ words:
|
|
119
|
+
{ words: HEADLESS, source: 'adapter' },
|
|
117
120
|
{ words: flags, source: 'configuration' },
|
|
118
121
|
planOverride(flags, { defaultMode: at.defaultPermissionMode, permissionModes: at.permissionModes }),
|
|
119
122
|
{ words: [NO_PANE_PROMPTS], source: 'adapter' },
|
|
120
123
|
{ words: at.isFirstStart ? [] : [CONTINUE], source: 'adapter' },
|
|
121
124
|
{ words: (at.readOnly ?? []).flatMap((path) => [ADD_DIR, path]), source: 'adapter' },
|
|
122
|
-
{ words: at.isHeadless || at.prompt === undefined ? [] : [END_OF_FLAGS, at.prompt] },
|
|
123
125
|
]);
|
|
124
126
|
}
|
|
125
127
|
/**
|
|
@@ -153,9 +155,22 @@ export function claudeCodeErrorIn(events) {
|
|
|
153
155
|
return undefined;
|
|
154
156
|
}
|
|
155
157
|
export function createClaudeCodeHarness(options) {
|
|
156
|
-
const { configuration, plugin, sessions
|
|
157
|
-
/**
|
|
158
|
-
|
|
158
|
+
const { configuration, plugin, sessions } = options;
|
|
159
|
+
/**
|
|
160
|
+
* The session's way to its model (api keys K6): on an API key, the model
|
|
161
|
+
* proxy's address and a token of the session's own, fresh for each start;
|
|
162
|
+
* on the subscription, nothing, so it signs in as Claude Code does.
|
|
163
|
+
*/
|
|
164
|
+
const routeOf = async (login) => {
|
|
165
|
+
if (login === 'subscription') {
|
|
166
|
+
return { env: {} };
|
|
167
|
+
}
|
|
168
|
+
const url = await options.proxyUrl?.();
|
|
169
|
+
if (url === undefined) {
|
|
170
|
+
throw new Error('the model proxy is not running yet');
|
|
171
|
+
}
|
|
172
|
+
return { env: { ANTHROPIC_BASE_URL: `${url}/anthropic` }, proxyToken: { harness: 'claude-code', variable: 'ANTHROPIC_AUTH_TOKEN', token: newProxyToken() } };
|
|
173
|
+
};
|
|
159
174
|
const homes = options.shipHomes === undefined
|
|
160
175
|
? createHostClaudeCodeHomes({ plugin, projects: options.projects, setup: options.setup })
|
|
161
176
|
: createShipClaudeCodeHomes({ ...options.shipHomes, pluginRoot: plugin.root, host: options.setup });
|
|
@@ -170,19 +185,18 @@ export function createClaudeCodeHarness(options) {
|
|
|
170
185
|
},
|
|
171
186
|
turnOf: (session) => identityOf(session.shipId).turnOf(session),
|
|
172
187
|
startProblem: () => createPluginIdentity(plugin).startProblem(),
|
|
173
|
-
launch: async ({ shipId, folder, checkouts, harness, options: picked, isFirstStart, launchId, firstPrompt }) => {
|
|
188
|
+
launch: async ({ shipId, folder, checkouts, harness, options: picked, isFirstStart, launchId, login, firstPrompt }) => {
|
|
174
189
|
const settings = configuration.harnesses[harness];
|
|
175
190
|
if (settings === undefined) {
|
|
176
191
|
throw new Error(`The configuration has no harness ${harness}`);
|
|
177
192
|
}
|
|
193
|
+
const route = await routeOf(login);
|
|
178
194
|
const home = homes.of(shipId);
|
|
179
195
|
await homes.prepare({ shipId, folder });
|
|
180
196
|
const prompt = isFirstStart && firstPrompt !== undefined ? firstPromptOf(firstPrompt) : wakePromptOf(WAKE_PROMPT);
|
|
181
197
|
const flags = effectiveFlags(settings, picked);
|
|
182
198
|
const command = claudeCodeCommandLine({
|
|
183
199
|
flags,
|
|
184
|
-
isHeadless,
|
|
185
|
-
prompt,
|
|
186
200
|
isFirstStart: isFirstStart || !(await hasConversation(home.projects, folder)),
|
|
187
201
|
defaultPermissionMode: await claudeCodeSettingsDefaultMode(home.setup, { flags, folder }),
|
|
188
202
|
permissionModes: options.permissionModes(),
|
|
@@ -191,17 +205,15 @@ export function createClaudeCodeHarness(options) {
|
|
|
191
205
|
});
|
|
192
206
|
const marks = marksOf(shipId);
|
|
193
207
|
await marks.clear(folder);
|
|
194
|
-
await sessions.start({ shipId, folder, command: wordsOf(command), harness, env: { [LAUNCH_VARIABLE]: launchId }, ...(checkouts.length > 0 && { readOnly: checkouts.map((checkout) => checkout.path) }) });
|
|
195
|
-
|
|
196
|
-
await sessions.send({ shipId, line: userLine(prompt) });
|
|
197
|
-
}
|
|
208
|
+
await sessions.start({ shipId, folder, command: wordsOf(command), harness, env: { [LAUNCH_VARIABLE]: launchId, ...route.env }, ...(route.proxyToken !== undefined && { proxyToken: route.proxyToken }), ...(checkouts.length > 0 && { readOnly: checkouts.map((checkout) => checkout.path) }) });
|
|
209
|
+
await sessions.send({ shipId, line: userLine(prompt) });
|
|
198
210
|
},
|
|
199
211
|
handOver: async (session) => {
|
|
200
212
|
const line = await identityOf(session.shipId).handOverLine(session);
|
|
201
213
|
if (line === undefined) {
|
|
202
214
|
return 'nothing';
|
|
203
215
|
}
|
|
204
|
-
await sessions.send({ shipId: session.shipId, line:
|
|
216
|
+
await sessions.send({ shipId: session.shipId, line: userLine(wakePromptOf(line)) });
|
|
205
217
|
return 'handed';
|
|
206
218
|
},
|
|
207
219
|
forceOver: async ({ shipId, folder, isTurnBusy }) => {
|
|
@@ -212,13 +224,15 @@ export function createClaudeCodeHarness(options) {
|
|
|
212
224
|
if (isTurnBusy) {
|
|
213
225
|
await sessions.interrupt(shipId);
|
|
214
226
|
}
|
|
215
|
-
await sessions.send({ shipId, line:
|
|
227
|
+
await sessions.send({ shipId, line: userLine(wakePromptOf(line)) });
|
|
216
228
|
return 'handed';
|
|
217
229
|
},
|
|
218
230
|
isHolding: (session) => identityOf(session.shipId).isHolding(session),
|
|
219
231
|
sessionDied: (session) => identityOf(session.shipId).sessionDied(session),
|
|
220
232
|
marksLaunches: () => createLaunchMarks(plugin).isMarking(),
|
|
221
|
-
//
|
|
233
|
+
// Claude Code is offered wherever its plugin is: no build or runtime of it is held back.
|
|
234
|
+
notOfferedReason: () => Promise.resolve(undefined),
|
|
235
|
+
// The marker says what the session did; the last error event names why a start shows none (H13).
|
|
222
236
|
launchSeen: async ({ shipId, folder, launchId, model }) => {
|
|
223
237
|
const marker = await marksOf(shipId).read({ folder, launchId });
|
|
224
238
|
if (marker?.refused !== undefined) {
|
|
@@ -228,12 +242,8 @@ export function createClaudeCodeHarness(options) {
|
|
|
228
242
|
if (marker?.isActive === true) {
|
|
229
243
|
return { kind: 'active' };
|
|
230
244
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return { kind: 'none', ...(cause !== undefined && { cause }) };
|
|
234
|
-
}
|
|
235
|
-
const screen = marker?.isStarted === true ? undefined : claudeCodeScreenStoppedAt((await sessions.events(shipId)).join('\n'));
|
|
236
|
-
return { kind: 'none', ...(screen !== undefined && { screen }) };
|
|
245
|
+
const cause = claudeCodeErrorIn(await sessions.events(shipId));
|
|
246
|
+
return { kind: 'none', ...(cause !== undefined && { cause }) };
|
|
237
247
|
},
|
|
238
248
|
};
|
|
239
249
|
}
|