@aeolus-fleet/trierarch 0.24.1 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/adapters/claude-code-home.d.ts +43 -0
- package/dist/adapters/claude-code-home.js +51 -0
- package/dist/adapters/claude-code-home.js.map +1 -0
- package/dist/adapters/claude-code.d.ts +12 -5
- package/dist/adapters/claude-code.js +33 -10
- package/dist/adapters/claude-code.js.map +1 -1
- package/dist/adapters/clone-workspace.d.ts +6 -0
- package/dist/adapters/clone-workspace.js +79 -0
- package/dist/adapters/clone-workspace.js.map +1 -0
- package/dist/adapters/codex.d.ts +2 -3
- package/dist/adapters/codex.js +9 -4
- package/dist/adapters/codex.js.map +1 -1
- package/dist/adapters/container-host.d.ts +15 -0
- package/dist/adapters/container-host.js +52 -0
- package/dist/adapters/container-host.js.map +1 -0
- package/dist/adapters/container.d.ts +43 -0
- package/dist/adapters/container.js +176 -0
- package/dist/adapters/container.js.map +1 -0
- package/dist/adapters/harnesses.d.ts +7 -3
- package/dist/adapters/harnesses.js +2 -2
- package/dist/adapters/harnesses.js.map +1 -1
- package/dist/adapters/json-state.js +0 -1
- package/dist/adapters/json-state.js.map +1 -1
- package/dist/adapters/paths.d.ts +7 -0
- package/dist/adapters/paths.js +6 -0
- package/dist/adapters/paths.js.map +1 -1
- package/dist/adapters/plugin-identity.d.ts +9 -1
- package/dist/adapters/plugin-identity.js +23 -3
- package/dist/adapters/plugin-identity.js.map +1 -1
- package/dist/adapters/runtime-adapters.d.ts +27 -0
- package/dist/adapters/runtime-adapters.js +30 -0
- package/dist/adapters/runtime-adapters.js.map +1 -0
- package/dist/adapters/tmux.d.ts +12 -30
- package/dist/adapters/tmux.js +11 -0
- package/dist/adapters/tmux.js.map +1 -1
- package/dist/cli/config-check.d.ts +13 -2
- package/dist/cli/config-check.js +20 -1
- package/dist/cli/config-check.js.map +1 -1
- package/dist/cli/main.js +2 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/run.js +16 -8
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/status.d.ts +2 -2
- package/dist/core/check-session-runtime.d.ts +15 -0
- package/dist/core/check-session-runtime.js +49 -0
- package/dist/core/check-session-runtime.js.map +1 -0
- package/dist/core/entry.d.ts +0 -5
- package/dist/core/entry.js.map +1 -1
- package/dist/core/ports.d.ts +60 -8
- package/dist/core/reconciler.d.ts +2 -1
- package/dist/core/reconciler.js +7 -10
- package/dist/core/reconciler.js.map +1 -1
- package/dist/core/report-self.d.ts +2 -2
- package/dist/core/report-self.js +2 -0
- package/dist/core/report-self.js.map +1 -1
- package/dist/core/run-pass.d.ts +2 -2
- package/dist/core/run-pass.js +15 -10
- package/dist/core/run-pass.js.map +1 -1
- package/dist/core/uninstall.d.ts +2 -2
- package/dist/core/uninstall.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { setTimeout as wait } from 'node:timers/promises';
|
|
5
|
+
import { idSchema } from '@aeolus-fleet/common';
|
|
6
|
+
import { shipHome } from './paths.js';
|
|
7
|
+
import { runCommand } from './run-command.js';
|
|
8
|
+
const PREFIX = 'trierarch-';
|
|
9
|
+
const OWNER_LABEL = 'aeolus.trierarch';
|
|
10
|
+
const CONTAINER_OWNER = 'aeolus-trierarch';
|
|
11
|
+
/** The variable Claude Code reads its long-lived model token from (`claude setup-token`). */
|
|
12
|
+
export const MODEL_TOKEN_VARIABLE = 'CLAUDE_CODE_OAUTH_TOKEN';
|
|
13
|
+
/** The session user's home in the image, where each container gets its ship's own home. */
|
|
14
|
+
export const SESSION_HOME = '/home/ubuntu';
|
|
15
|
+
/** The image's session user (ubuntu), whose subordinate ids the nested Podman maps. */
|
|
16
|
+
const SESSION_USER = 'uid=1000,gid=1000';
|
|
17
|
+
/** The tmux session inside each container: one per container, so one name serves. */
|
|
18
|
+
const TMUX_TARGET = '=session:';
|
|
19
|
+
/**
|
|
20
|
+
* The most processes and threads a container may hold, a hard cap beside
|
|
21
|
+
* memory and cpus (decision 0039): room for Claude Code, a test run with its
|
|
22
|
+
* workers, a browser and a nested Postgres, and none for a runaway fork.
|
|
23
|
+
*/
|
|
24
|
+
const PIDS_LIMIT = 4096;
|
|
25
|
+
/** How many lines back a screen is read, as on the host. */
|
|
26
|
+
const SCREEN_LINES = 200;
|
|
27
|
+
/**
|
|
28
|
+
* The container's command: tmux runs the session's command, keeping its pane
|
|
29
|
+
* on exit, as on the host. Once the command ends, it prints the pane and ends,
|
|
30
|
+
* so the container exits and the runtime's log keeps the last screen. The pane
|
|
31
|
+
* starts with the shell and is respawned with the command once remain-on-exit
|
|
32
|
+
* is set, so even a command that ends at once leaves its exit to see.
|
|
33
|
+
*/
|
|
34
|
+
const SESSION_SCRIPT = `
|
|
35
|
+
tmux new-session -d -s session -x 200 -y 50 || exit 1
|
|
36
|
+
tmux set-option -w -t '${TMUX_TARGET}' remain-on-exit on
|
|
37
|
+
tmux respawn-pane -k -t '${TMUX_TARGET}' -- "$@"
|
|
38
|
+
while [ "$(tmux display-message -p -t '${TMUX_TARGET}' '#{pane_dead}' 2> /dev/null)" = 0 ]; do sleep 1; done
|
|
39
|
+
tmux capture-pane -p -J -S -${String(SCREEN_LINES)} -t '${TMUX_TARGET}'
|
|
40
|
+
`;
|
|
41
|
+
function containerName(shipId) {
|
|
42
|
+
return `${PREFIX}${shipId}`;
|
|
43
|
+
}
|
|
44
|
+
/** The env file's lines; a value over more than one line has no place in one. */
|
|
45
|
+
function envFileOf(env) {
|
|
46
|
+
return Object.entries(env)
|
|
47
|
+
.map(([variable, value]) => {
|
|
48
|
+
if (value.includes('\n')) {
|
|
49
|
+
throw new Error(`the environment value of ${variable} spans more than one line, which an env file cannot hold`);
|
|
50
|
+
}
|
|
51
|
+
return `${variable}=${value}\n`;
|
|
52
|
+
})
|
|
53
|
+
.join('');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The container session runtime (decision 0039): one container per ship,
|
|
57
|
+
* named after its ship id, with tmux inside, so typing and screen reads are an
|
|
58
|
+
* exec into it. Rootless only, with hard memory and cpu caps and no restart
|
|
59
|
+
* policy: the trierarch starts a dead container again itself. The container
|
|
60
|
+
* sees its folder and its ship's own home, as its home, and nothing else of
|
|
61
|
+
* the host, never the runtime's socket. The home is made, for its owner
|
|
62
|
+
* alone, when the ship has none yet.
|
|
63
|
+
*
|
|
64
|
+
* The model token and the session's environment reach the container through
|
|
65
|
+
* an env file only its owner reads, removed once the container runs, never a
|
|
66
|
+
* command line (#445). Under a systemd unit the run goes through a scope of its
|
|
67
|
+
* own, so the container's monitor is not in the service's control group and a
|
|
68
|
+
* restart or upgrade ends no session (#479, #537).
|
|
69
|
+
*/
|
|
70
|
+
export function createContainerRuntime(options) {
|
|
71
|
+
const owner = options.owner ?? CONTAINER_OWNER;
|
|
72
|
+
const launch = options.launch ?? [];
|
|
73
|
+
const run = options.run ?? runCommand;
|
|
74
|
+
const runtime = async (args) => run(options.binary, { args });
|
|
75
|
+
const must = async (args) => {
|
|
76
|
+
const result = await runtime(args);
|
|
77
|
+
if (result.status !== 0) {
|
|
78
|
+
throw new Error(`${options.binary} ${args[0] ?? ''} failed: ${result.stderr.trim()}`);
|
|
79
|
+
}
|
|
80
|
+
return result.stdout;
|
|
81
|
+
};
|
|
82
|
+
const stop = async (shipId) => {
|
|
83
|
+
// Kill, then remove: a remove alone waits out the stop timeout on podman.
|
|
84
|
+
await runtime(['kill', containerName(shipId)]);
|
|
85
|
+
await runtime(['rm', '--force', containerName(shipId)]);
|
|
86
|
+
};
|
|
87
|
+
const tmux = (shipId, args) => ['exec', containerName(shipId), 'tmux', ...args];
|
|
88
|
+
return {
|
|
89
|
+
list: async () => {
|
|
90
|
+
const listed = await must(['ps', '--all', '--filter', `label=${OWNER_LABEL}=${owner}`, '--format', '{{.Names}} {{.State}}']);
|
|
91
|
+
return listed.split('\n').flatMap((line) => {
|
|
92
|
+
const [name = '', state = ''] = line.trim().split(' ');
|
|
93
|
+
const shipId = idSchema('ship').safeParse(name.slice(PREFIX.length));
|
|
94
|
+
return name.startsWith(PREFIX) && shipId.success ? [{ shipId: shipId.data, status: state === 'running' ? 'running' : 'exited' }] : [];
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
stop,
|
|
98
|
+
start: async ({ shipId, folder, command, env = {} }) => {
|
|
99
|
+
const token = (await readFile(options.tokenFile, 'utf8')).trim();
|
|
100
|
+
const content = envFileOf({ ...env, [MODEL_TOKEN_VARIABLE]: token });
|
|
101
|
+
await stop(shipId);
|
|
102
|
+
const home = shipHome(options.homes, shipId);
|
|
103
|
+
await mkdir(home, { recursive: true, mode: 0o700 });
|
|
104
|
+
const secrets = await mkdtemp(join(tmpdir(), 'aeolus-trierarch-env-'));
|
|
105
|
+
try {
|
|
106
|
+
const envFile = join(secrets, 'session.env');
|
|
107
|
+
await writeFile(envFile, content, { mode: 0o600 });
|
|
108
|
+
const [program = options.binary, ...args] = [
|
|
109
|
+
...launch,
|
|
110
|
+
options.binary,
|
|
111
|
+
'run',
|
|
112
|
+
'--detach',
|
|
113
|
+
'--name',
|
|
114
|
+
containerName(shipId),
|
|
115
|
+
'--label',
|
|
116
|
+
`${OWNER_LABEL}=${owner}`,
|
|
117
|
+
'--memory',
|
|
118
|
+
options.memory,
|
|
119
|
+
'--cpus',
|
|
120
|
+
String(options.cpus),
|
|
121
|
+
'--pids-limit',
|
|
122
|
+
String(PIDS_LIMIT),
|
|
123
|
+
`--userns=keep-id:${SESSION_USER}`,
|
|
124
|
+
'--device',
|
|
125
|
+
'/dev/fuse',
|
|
126
|
+
'--device',
|
|
127
|
+
'/dev/net/tun',
|
|
128
|
+
'--cap-add',
|
|
129
|
+
'SYS_ADMIN',
|
|
130
|
+
'--security-opt',
|
|
131
|
+
'unmask=ALL',
|
|
132
|
+
'--volume',
|
|
133
|
+
`${folder}:${folder}`,
|
|
134
|
+
'--volume',
|
|
135
|
+
`${home}:${SESSION_HOME}`,
|
|
136
|
+
'--env',
|
|
137
|
+
`HOME=${SESSION_HOME}`,
|
|
138
|
+
'--workdir',
|
|
139
|
+
folder,
|
|
140
|
+
'--env-file',
|
|
141
|
+
envFile,
|
|
142
|
+
options.image,
|
|
143
|
+
'sh',
|
|
144
|
+
'-c',
|
|
145
|
+
SESSION_SCRIPT,
|
|
146
|
+
'sh',
|
|
147
|
+
...command,
|
|
148
|
+
];
|
|
149
|
+
const started = await run(program, { args });
|
|
150
|
+
if (started.status !== 0) {
|
|
151
|
+
throw new Error(`${options.binary} run failed: ${started.stderr.trim()}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
await rm(secrets, { recursive: true, force: true });
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
type: async ({ shipId, text, settleMs }) => {
|
|
159
|
+
await must(tmux(shipId, ['send-keys', '-t', TMUX_TARGET, '-l', text]));
|
|
160
|
+
if (settleMs !== undefined) {
|
|
161
|
+
await wait(settleMs);
|
|
162
|
+
}
|
|
163
|
+
await must(tmux(shipId, ['send-keys', '-t', TMUX_TARGET, 'Enter']));
|
|
164
|
+
},
|
|
165
|
+
screen: async (shipId) => {
|
|
166
|
+
const shown = await runtime(tmux(shipId, ['capture-pane', '-p', '-J', '-S', `-${String(SCREEN_LINES)}`, '-t', TMUX_TARGET]));
|
|
167
|
+
if (shown.status === 0) {
|
|
168
|
+
return shown.stdout;
|
|
169
|
+
}
|
|
170
|
+
// An exited container printed its last screen as it ended.
|
|
171
|
+
const logged = await runtime(['logs', containerName(shipId)]);
|
|
172
|
+
return logged.status === 0 ? logged.stdout : '';
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=container.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/adapters/container.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAe,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAC;AAElE,MAAM,MAAM,GAAG,YAAY,CAAC;AAC5B,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAC3C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAC9D,2FAA2F;AAC3F,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,CAAC;AAC3C,uFAAuF;AACvF,MAAM,YAAY,GAAG,mBAAmB,CAAC;AACzC,qFAAqF;AACrF,MAAM,WAAW,GAAG,WAAW,CAAC;AAChC;;;;GAIG;AACH,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,4DAA4D;AAC5D,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,cAAc,GAAG;;yBAEE,WAAW;2BACT,WAAW;yCACG,WAAW;8BACtB,MAAM,CAAC,YAAY,CAAC,QAAQ,WAAW;CACpE,CAAC;AAsBF,SAAS,aAAa,CAAC,MAAc;IACnC,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,iFAAiF;AACjF,SAAS,SAAS,CAAC,GAAqC;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,0DAA0D,CAAC,CAAC;QAClH,CAAC;QACD,OAAO,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC;IAClC,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,eAAe,CAAC;IAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAuB,EAA0B,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACzG,MAAM,IAAI,GAAG,KAAK,EAAE,IAAuB,EAAmB,EAAE;QAC9D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,YAAY,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACnD,0EAA0E;QAC1E,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,IAAuB,EAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAE9H,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,WAAW,IAAI,KAAK,EAAE,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC,CAAC;YAC7H,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAqB,EAAE;gBAC5D,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBACrE,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxI,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI;QACJ,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE;YACrD,MAAM,KAAK,GAAG,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YACrE,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;YACnB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;gBAC7C,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBACnD,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG;oBAC1C,GAAG,MAAM;oBACT,OAAO,CAAC,MAAM;oBACd,KAAK;oBACL,UAAU;oBACV,QAAQ;oBACR,aAAa,CAAC,MAAM,CAAC;oBACrB,SAAS;oBACT,GAAG,WAAW,IAAI,KAAK,EAAE;oBACzB,UAAU;oBACV,OAAO,CAAC,MAAM;oBACd,QAAQ;oBACR,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;oBACpB,cAAc;oBACd,MAAM,CAAC,UAAU,CAAC;oBAClB,oBAAoB,YAAY,EAAE;oBAClC,UAAU;oBACV,WAAW;oBACX,UAAU;oBACV,cAAc;oBACd,WAAW;oBACX,WAAW;oBACX,gBAAgB;oBAChB,YAAY;oBACZ,UAAU;oBACV,GAAG,MAAM,IAAI,MAAM,EAAE;oBACrB,UAAU;oBACV,GAAG,IAAI,IAAI,YAAY,EAAE;oBACzB,OAAO;oBACP,QAAQ,YAAY,EAAE;oBACtB,WAAW;oBACX,MAAM;oBACN,YAAY;oBACZ,OAAO;oBACP,OAAO,CAAC,KAAK;oBACb,IAAI;oBACJ,IAAI;oBACJ,cAAc;oBACd,IAAI;oBACJ,GAAG,OAAO;iBACX,CAAC;gBACF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,gBAAgB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;YACzC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YACvE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACvB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;YAC7H,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAC,MAAM,CAAC;YACtB,CAAC;YACD,2DAA2D;YAC3D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC9D,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { TrierarchConfiguration } from '@aeolus-fleet/common';
|
|
2
|
-
import type { AdapterFlag, Detected, HarnessPort } from '../core/ports.js';
|
|
2
|
+
import type { AdapterFlag, Detected, HarnessPort, SessionRuntime } from '../core/ports.js';
|
|
3
3
|
import { type ClaudeCodeSetup } from './claude-code-setup.js';
|
|
4
4
|
import type { CommandPart } from './command-line.js';
|
|
5
5
|
import type { AeolusPlugin } from './plugin-identity.js';
|
|
6
|
-
import type { Tmux } from './tmux.js';
|
|
7
6
|
/** What config check reads of the harnesses' own files to show their command lines. */
|
|
8
7
|
export interface HarnessFiles {
|
|
9
8
|
claudeCode: Pick<ClaudeCodeSetup, 'defaultPermissionMode'>;
|
|
@@ -37,7 +36,12 @@ export declare function createHarnesses(at: {
|
|
|
37
36
|
managedSettings: string;
|
|
38
37
|
/** What detection last found, read at each launch (#517). */
|
|
39
38
|
detected: () => Detected;
|
|
40
|
-
sessions: Pick<
|
|
39
|
+
sessions: Pick<SessionRuntime, 'start' | 'type' | 'screen'>;
|
|
40
|
+
/** For sessions in containers: a home of each ship's own (decision 0039). */
|
|
41
|
+
shipHomes?: {
|
|
42
|
+
homes: string;
|
|
43
|
+
managedSettings: string;
|
|
44
|
+
};
|
|
41
45
|
}): Promise<{
|
|
42
46
|
harnesses: Record<string, HarnessPort>;
|
|
43
47
|
plugins: Record<string, AeolusPlugin>;
|
|
@@ -48,7 +48,7 @@ export async function commandLinesOf(at) {
|
|
|
48
48
|
* so no request for it is ever crewed.
|
|
49
49
|
*/
|
|
50
50
|
export async function createHarnesses(at) {
|
|
51
|
-
const { configuration, homeDirectory, env, managedSettings, detected, sessions } = at;
|
|
51
|
+
const { configuration, homeDirectory, env, managedSettings, detected, sessions, shipHomes } = at;
|
|
52
52
|
const harnesses = {};
|
|
53
53
|
const plugins = {};
|
|
54
54
|
for (const name of Object.keys(configuration.harnesses)) {
|
|
@@ -57,7 +57,7 @@ export async function createHarnesses(at) {
|
|
|
57
57
|
}
|
|
58
58
|
const plugin = await findAeolusPlugin({ homeDirectory, env, harness: name });
|
|
59
59
|
plugins[name] = plugin;
|
|
60
|
-
harnesses[name] = name === 'codex' ? createCodexHarness({ configuration, plugin, sessions, setup: createCodexSetup() }) : createClaudeCodeHarness({ configuration, plugin, sessions, permissionModes: () => detected()['claude-code']?.permissionModes, projects: join(env.CLAUDE_CONFIG_DIR ?? join(homeDirectory, '.claude'), 'projects'), setup: createClaudeCodeSetup({ homeDirectory, managedSettings, ...(env.CLAUDE_CONFIG_DIR !== undefined && { configDirectory: env.CLAUDE_CONFIG_DIR }) }) });
|
|
60
|
+
harnesses[name] = name === 'codex' ? createCodexHarness({ configuration, plugin, sessions, setup: createCodexSetup() }) : createClaudeCodeHarness({ configuration, plugin, sessions, permissionModes: () => detected()['claude-code']?.permissionModes, projects: join(env.CLAUDE_CONFIG_DIR ?? join(homeDirectory, '.claude'), 'projects'), setup: createClaudeCodeSetup({ homeDirectory, managedSettings, ...(env.CLAUDE_CONFIG_DIR !== undefined && { configDirectory: env.CLAUDE_CONFIG_DIR }) }), ...(shipHomes !== undefined && { shipHomes }) });
|
|
61
61
|
}
|
|
62
62
|
return { harnesses, plugins };
|
|
63
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harnesses.js","sourceRoot":"","sources":["../../src/adapters/harnesses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAKjC,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,WAAW,IAAI,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC7M,OAAO,EAAE,qBAAqB,EAAwB,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5I,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"harnesses.js","sourceRoot":"","sources":["../../src/adapters/harnesses.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,7 +33,6 @@ const stateSchema = z.object({
|
|
|
33
33
|
launchId: z.string().optional(),
|
|
34
34
|
isReleasedElsewhere: z.literal(true).optional(),
|
|
35
35
|
isIdentityGone: z.literal(true).optional(),
|
|
36
|
-
wake: z.object({ waiting: z.int().nonnegative(), isPending: z.boolean() }),
|
|
37
36
|
})),
|
|
38
37
|
kept: z.array(z.object({ shipId: idSchema('ship'), repository: z.string(), path: z.string() })),
|
|
39
38
|
orphans: z.array(z.object({ path: z.string(), repository: z.string(), name: z.string() })),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-state.js","sourceRoot":"","sources":["../../src/adapters/json-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAuB,MAAM,kBAAkB,CAAC;AAGlF;;;;;;;GAOG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEhD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,CACf,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,MAAM,CAAC;QACP,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC;QACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,eAAe,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;QACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,SAAS,EAAE,wBAAwB;QACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAClC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACzC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;QACvB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;QAC/C,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"json-state.js","sourceRoot":"","sources":["../../src/adapters/json-state.ts"],"names":[],"mappings":"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"}
|
package/dist/adapters/paths.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ShipId } from '@aeolus-fleet/common';
|
|
1
2
|
/**
|
|
2
3
|
* Where the trierarch keeps its files (docs/architecture.md, "Files on the
|
|
3
4
|
* machine"): everything under `~/.aeolus/trierarch/`. The configuration's
|
|
@@ -9,14 +10,20 @@ export interface TrierarchPaths {
|
|
|
9
10
|
readonly config: string;
|
|
10
11
|
readonly configSchema: string;
|
|
11
12
|
readonly crewToken: string;
|
|
13
|
+
/** The machine's long-lived model token, handed to each container session (decision 0039); never in the configuration. */
|
|
14
|
+
readonly modelToken: string;
|
|
12
15
|
readonly state: string;
|
|
13
16
|
/** What detection found per harness (#365), apart from the configuration. */
|
|
14
17
|
readonly detected: string;
|
|
15
18
|
readonly running: string;
|
|
16
19
|
readonly logs: string;
|
|
17
20
|
readonly worktrees: string;
|
|
21
|
+
/** The homes of the ships whose sessions run in containers, one folder per ship (decision 0039). */
|
|
22
|
+
readonly homes: string;
|
|
18
23
|
}
|
|
19
24
|
export declare function trierarchPaths(at: {
|
|
20
25
|
homeDirectory: string;
|
|
21
26
|
config?: string;
|
|
22
27
|
}): TrierarchPaths;
|
|
28
|
+
/** A ship's own home among the homes: the one place a ship id becomes its home's path. */
|
|
29
|
+
export declare function shipHome(homes: string, shipId: ShipId): string;
|
package/dist/adapters/paths.js
CHANGED
|
@@ -6,11 +6,17 @@ export function trierarchPaths(at) {
|
|
|
6
6
|
config: at.config ?? join(home, 'config.json'),
|
|
7
7
|
configSchema: join(home, 'config.schema.json'),
|
|
8
8
|
crewToken: join(home, 'crew-token'),
|
|
9
|
+
modelToken: join(home, 'model-token'),
|
|
9
10
|
state: join(home, 'state.json'),
|
|
10
11
|
detected: join(home, 'detected.json'),
|
|
11
12
|
running: join(home, 'running.json'),
|
|
12
13
|
logs: join(home, 'logs'),
|
|
13
14
|
worktrees: join(home, 'worktrees'),
|
|
15
|
+
homes: join(home, 'homes'),
|
|
14
16
|
};
|
|
15
17
|
}
|
|
18
|
+
/** A ship's own home among the homes: the one place a ship id becomes its home's path. */
|
|
19
|
+
export function shipHome(homes, shipId) {
|
|
20
|
+
return join(homes, shipId);
|
|
21
|
+
}
|
|
16
22
|
//# sourceMappingURL=paths.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/adapters/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/adapters/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA2BjC,MAAM,UAAU,cAAc,CAAC,EAA8C;IAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5D,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QAC9C,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC;QAC9C,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC;QACnC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACrC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC;QAC/B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC;QACrC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;QAClC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,MAAc;IACpD,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ShipId } from '@aeolus-fleet/common';
|
|
1
2
|
import type { HarnessPort } from '../core/ports.js';
|
|
2
3
|
/** The aeolus plugin as a harness installed it: its scripts, its data folder, and where its sessions' identities live. */
|
|
3
4
|
export interface AeolusPlugin {
|
|
@@ -15,6 +16,13 @@ export declare function runIdentity(plugin: AeolusPlugin, at: {
|
|
|
15
16
|
stdout: string;
|
|
16
17
|
stderr: string;
|
|
17
18
|
}>;
|
|
19
|
+
/** What the plugin does for a hand-over: the line to type into the session, or none when nothing is handed. */
|
|
20
|
+
export interface PluginHandOver {
|
|
21
|
+
readonly handOverLine: (session: {
|
|
22
|
+
shipId: ShipId;
|
|
23
|
+
folder: string;
|
|
24
|
+
}) => Promise<string | undefined>;
|
|
25
|
+
}
|
|
18
26
|
/**
|
|
19
27
|
* A session's identity and turn, through the aeolus plugin's own
|
|
20
28
|
* `aeolus-identity.sh`, never a copy of how the plugin names its files. The
|
|
@@ -22,4 +30,4 @@ export declare function runIdentity(plugin: AeolusPlugin, at: {
|
|
|
22
30
|
* data folder goes along, so the script moves an identity an older plugin
|
|
23
31
|
* kept there.
|
|
24
32
|
*/
|
|
25
|
-
export declare function createPluginIdentity(plugin: AeolusPlugin): Pick<HarnessPort, 'prepareIdentity' | 'crewTokenOf' | 'removeIdentity' | 'turnOf'
|
|
33
|
+
export declare function createPluginIdentity(plugin: AeolusPlugin): Pick<HarnessPort, 'prepareIdentity' | 'crewTokenOf' | 'removeIdentity' | 'turnOf' | 'isHolding' | 'sessionDied'> & PluginHandOver;
|
|
@@ -4,6 +4,12 @@ import { runCommand } from './run-command.js';
|
|
|
4
4
|
export function runIdentity(plugin, at) {
|
|
5
5
|
return runCommand('bash', { args: [`${plugin.root}/scripts/aeolus-identity.sh`, ...at.args], env: { AEOLUS_FOLDER: at.folder, AEOLUS_DATA: plugin.data, AEOLUS_CREWS: plugin.crews } });
|
|
6
6
|
}
|
|
7
|
+
/** Runs the plugin's own `aeolus-push.sh` for the folder (#756), as `runIdentity` runs `aeolus-identity.sh`. */
|
|
8
|
+
function runPush(plugin, at) {
|
|
9
|
+
return runCommand('bash', { args: [`${plugin.root}/scripts/aeolus-push.sh`, ...at.args], env: { AEOLUS_FOLDER: at.folder, AEOLUS_DATA: plugin.data, AEOLUS_CREWS: plugin.crews } });
|
|
10
|
+
}
|
|
11
|
+
/** The states of a store entry the trierarch hands over (#756): received, handed and not confirmed, or to hand once more. */
|
|
12
|
+
const TO_HAND = new Set(['received', 'handed', 'onceMore']);
|
|
7
13
|
/**
|
|
8
14
|
* A session's identity and turn, through the aeolus plugin's own
|
|
9
15
|
* `aeolus-identity.sh`, never a copy of how the plugin names its files. The
|
|
@@ -29,19 +35,33 @@ export function createPluginIdentity(plugin) {
|
|
|
29
35
|
throw new Error(`aeolus-identity.sh write failed: ${written.stderr.trim()}`);
|
|
30
36
|
}
|
|
31
37
|
},
|
|
32
|
-
crewTokenOf: async (folder) => {
|
|
38
|
+
crewTokenOf: async ({ folder }) => {
|
|
33
39
|
const path = (await identity(folder, ['path'])).stdout.trim();
|
|
34
40
|
const text = await readFile(path, 'utf8').catch(() => '');
|
|
35
41
|
return /^crewToken=(.+)$/m.exec(text)?.[1];
|
|
36
42
|
},
|
|
37
|
-
removeIdentity: async (folder) => {
|
|
43
|
+
removeIdentity: async ({ folder }) => {
|
|
38
44
|
await identity(folder, ['delete']);
|
|
39
45
|
},
|
|
40
|
-
turnOf: async (folder) => {
|
|
46
|
+
turnOf: async ({ folder }) => {
|
|
41
47
|
const turn = await identity(folder, ['turn']);
|
|
42
48
|
const [state] = turn.stdout.split(' ');
|
|
43
49
|
return turn.status === 0 && (state === 'busy' || state === 'idle') ? state : 'unknown';
|
|
44
50
|
},
|
|
51
|
+
// The store keeps one line per entry: its delivery id, its state and when.
|
|
52
|
+
isHolding: async ({ folder }) => (await identity(folder, ['store'])).stdout.split('\n').some((line) => TO_HAND.has(line.split(' ')[1] ?? '')),
|
|
53
|
+
// Exit 0 hands a message over and prints its line; anything else hands nothing.
|
|
54
|
+
handOverLine: async ({ folder }) => {
|
|
55
|
+
const handed = await runPush(plugin, { folder, args: ['hand'] });
|
|
56
|
+
const line = handed.stdout.trim();
|
|
57
|
+
return handed.status === 0 && line !== '' ? line : undefined;
|
|
58
|
+
},
|
|
59
|
+
sessionDied: async ({ folder }) => {
|
|
60
|
+
const died = await runPush(plugin, { folder, args: ['died'] });
|
|
61
|
+
if (died.status !== 0) {
|
|
62
|
+
throw new Error(`aeolus-push.sh died failed: ${died.stderr.trim()}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
45
65
|
};
|
|
46
66
|
}
|
|
47
67
|
//# sourceMappingURL=plugin-identity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-identity.js","sourceRoot":"","sources":["../../src/adapters/plugin-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-identity.js","sourceRoot":"","sources":["../../src/adapters/plugin-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TrierarchConfiguration } from '@aeolus-fleet/common';
|
|
2
|
+
import type { SessionRuntime, WorkspacePort } from '../core/ports.js';
|
|
3
|
+
import type { TrierarchPaths } from './paths.js';
|
|
4
|
+
/** What runs the sessions, where their workspaces go, and, in containers, where each ship's home is kept. */
|
|
5
|
+
export interface RuntimeAdapters {
|
|
6
|
+
readonly sessions: SessionRuntime;
|
|
7
|
+
readonly workspace: WorkspacePort;
|
|
8
|
+
/** The homes of the ships, one each, for sessions in containers; none on the host, where every session shares the user's. */
|
|
9
|
+
readonly shipHomes?: {
|
|
10
|
+
homes: string;
|
|
11
|
+
managedSettings: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The adapters the configuration's session runtime picks (decision 0039): on
|
|
16
|
+
* the host, tmux and a worktree per ship; in containers, a container per ship
|
|
17
|
+
* from the image of the trierarch's own version, with the configured binary
|
|
18
|
+
* and caps and the machine's model token, a clone per ship in place of the
|
|
19
|
+
* worktree, by its real path, and a home of each ship's own.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runtimeAdaptersOf(at: {
|
|
22
|
+
configuration: TrierarchConfiguration;
|
|
23
|
+
paths: TrierarchPaths;
|
|
24
|
+
version: string;
|
|
25
|
+
launch: readonly string[];
|
|
26
|
+
managedSettings: string;
|
|
27
|
+
}): RuntimeAdapters;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { realpath } from 'node:fs/promises';
|
|
2
|
+
import { createCloneWorkspace } from './clone-workspace.js';
|
|
3
|
+
import { createContainerRuntime } from './container.js';
|
|
4
|
+
import { createGitWorkspace } from './git-workspace.js';
|
|
5
|
+
import { createTmux } from './tmux.js';
|
|
6
|
+
/** The session image `release.yml` publishes with each version (decision 0011, 0039). */
|
|
7
|
+
const SESSION_IMAGE = 'ghcr.io/thomashendrickx/aeolus-session';
|
|
8
|
+
/**
|
|
9
|
+
* The adapters the configuration's session runtime picks (decision 0039): on
|
|
10
|
+
* the host, tmux and a worktree per ship; in containers, a container per ship
|
|
11
|
+
* from the image of the trierarch's own version, with the configured binary
|
|
12
|
+
* and caps and the machine's model token, a clone per ship in place of the
|
|
13
|
+
* worktree, by its real path, and a home of each ship's own.
|
|
14
|
+
*/
|
|
15
|
+
export function runtimeAdaptersOf(at) {
|
|
16
|
+
const { configuration, paths, version, launch, managedSettings } = at;
|
|
17
|
+
const root = configuration.worktreeRoot ?? paths.worktrees;
|
|
18
|
+
const { runtime } = configuration;
|
|
19
|
+
if (runtime?.kind !== 'container') {
|
|
20
|
+
return { sessions: createTmux({ launch }), workspace: createGitWorkspace({ configuration, root }) };
|
|
21
|
+
}
|
|
22
|
+
const clones = createCloneWorkspace({ configuration, root });
|
|
23
|
+
return {
|
|
24
|
+
sessions: createContainerRuntime({ binary: runtime.binary, image: `${SESSION_IMAGE}:${version}`, tokenFile: paths.modelToken, homes: paths.homes, memory: runtime.memory, cpus: runtime.cpus, launch }),
|
|
25
|
+
// The container mounts the folder at the path it is given, where the plugin inside keys it by `pwd -P` as the host's does: one path for both, the real one.
|
|
26
|
+
workspace: { ...clones, prepare: async (at) => ({ folder: await realpath((await clones.prepare(at)).folder) }) },
|
|
27
|
+
shipHomes: { homes: paths.homes, managedSettings },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=runtime-adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-adapters.js","sourceRoot":"","sources":["../../src/adapters/runtime-adapters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,yFAAyF;AACzF,MAAM,aAAa,GAAG,wCAAwC,CAAC;AAU/D;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAyI;IACzK,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC;IACtE,MAAM,IAAI,GAAG,aAAa,CAAC,YAAY,IAAI,KAAK,CAAC,SAAS,CAAC;IAC3D,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC;IAClC,IAAI,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,kBAAkB,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACtG,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO;QACL,QAAQ,EAAE,sBAAsB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,IAAI,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACvM,4JAA4J;QAC5J,SAAS,EAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QAChH,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE;KACnD,CAAC;AACJ,CAAC"}
|
package/dist/adapters/tmux.d.ts
CHANGED
|
@@ -1,40 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type { SessionRuntime } from '../core/ports.js';
|
|
2
|
+
export declare const TMUX_SERVER = "aeolus-trierarch";
|
|
3
|
+
/** What the tmux command that may start the server runs through: a systemd scope of its own under a systemd unit, which sets INVOCATION_ID. */
|
|
4
|
+
export declare function sessionsLaunch(at: {
|
|
5
|
+
platform: string;
|
|
6
|
+
env: Readonly<Record<string, string | undefined>>;
|
|
7
|
+
}): readonly string[];
|
|
3
8
|
/**
|
|
4
|
-
*
|
|
5
|
-
* per ship, named after its ship id, kept on exit so an exit is seen.
|
|
6
|
-
* trierarch uses its own tmux server (`tmux -L aeolus-trierarch`), so it
|
|
7
|
-
* touches the operator's own sessions.
|
|
9
|
+
* The host session runtime (docs/architecture.md, "First adapters"): one tmux
|
|
10
|
+
* session per ship, named after its ship id, kept on exit so an exit is seen.
|
|
11
|
+
* The trierarch uses its own tmux server (`tmux -L aeolus-trierarch`), so it
|
|
12
|
+
* never touches the operator's own sessions.
|
|
8
13
|
*
|
|
9
14
|
* The first session started forks the tmux server, which keeps running when
|
|
10
15
|
* the trierarch stops. Under a systemd unit it starts in a scope of its own
|
|
11
16
|
* (`systemd-run --scope`), so it is not left over in the service's control
|
|
12
17
|
* group on a restart (#537), and the unit's stop leaves it alone (#479).
|
|
13
18
|
*/
|
|
14
|
-
export interface Tmux extends ProcessPort {
|
|
15
|
-
/** Starts the command in the folder, with the environment given, in a new session for the ship; an exited one is replaced. */
|
|
16
|
-
start(session: {
|
|
17
|
-
shipId: ShipId;
|
|
18
|
-
folder: string;
|
|
19
|
-
command: readonly string[];
|
|
20
|
-
env?: Readonly<Record<string, string>>;
|
|
21
|
-
}): Promise<void>;
|
|
22
|
-
/** Types the text into the ship's session and presses Enter, after `settleMs` when given. */
|
|
23
|
-
type(at: {
|
|
24
|
-
shipId: ShipId;
|
|
25
|
-
text: string;
|
|
26
|
-
settleMs?: number;
|
|
27
|
-
}): Promise<void>;
|
|
28
|
-
/** What the ship's session shows: its last lines, wrapped ones joined; empty with no session. */
|
|
29
|
-
screen(shipId: ShipId): Promise<string>;
|
|
30
|
-
}
|
|
31
|
-
export declare const TMUX_SERVER = "aeolus-trierarch";
|
|
32
|
-
/** What the tmux command that may start the server runs through: a systemd scope of its own under a systemd unit, which sets INVOCATION_ID. */
|
|
33
|
-
export declare function sessionsLaunch(at: {
|
|
34
|
-
platform: string;
|
|
35
|
-
env: Readonly<Record<string, string | undefined>>;
|
|
36
|
-
}): readonly string[];
|
|
37
19
|
export declare function createTmux(options?: {
|
|
38
20
|
server?: string;
|
|
39
21
|
launch?: readonly string[];
|
|
40
|
-
}):
|
|
22
|
+
}): SessionRuntime;
|
package/dist/adapters/tmux.js
CHANGED
|
@@ -12,6 +12,17 @@ export function sessionsLaunch(at) {
|
|
|
12
12
|
function sessionName(shipId) {
|
|
13
13
|
return `${PREFIX}${shipId}`;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* The host session runtime (docs/architecture.md, "First adapters"): one tmux
|
|
17
|
+
* session per ship, named after its ship id, kept on exit so an exit is seen.
|
|
18
|
+
* The trierarch uses its own tmux server (`tmux -L aeolus-trierarch`), so it
|
|
19
|
+
* never touches the operator's own sessions.
|
|
20
|
+
*
|
|
21
|
+
* The first session started forks the tmux server, which keeps running when
|
|
22
|
+
* the trierarch stops. Under a systemd unit it starts in a scope of its own
|
|
23
|
+
* (`systemd-run --scope`), so it is not left over in the service's control
|
|
24
|
+
* group on a restart (#537), and the unit's stop leaves it alone (#479).
|
|
25
|
+
*/
|
|
15
26
|
export function createTmux(options = {}) {
|
|
16
27
|
const server = options.server ?? TMUX_SERVER;
|
|
17
28
|
const launch = options.launch ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/adapters/tmux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAe,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/adapters/tmux.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,QAAQ,EAAe,MAAM,sBAAsB,CAAC;AAG7D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,MAAM,GAAG,YAAY,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAC9C,+FAA+F;AAC/F,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB,+IAA+I;AAC/I,MAAM,UAAU,cAAc,CAAC,EAA2E;IACxG,OAAO,EAAE,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACjJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,UAA2D,EAAE;IACtF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,EAAE,IAAuB,EAA+D,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IACnK,MAAM,IAAI,GAAG,KAAK,EAAE,IAAuB,EAAmB,EAAE;QAC9D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,8BAA8B,CAAC,CAAC,CAAC;YACtF,iDAAiD;YACjD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,OAAO,MAAM,CAAC,MAAM;iBACjB,KAAK,CAAC,IAAI,CAAC;iBACX,OAAO,CAAC,CAAC,IAAI,EAAqB,EAAE;gBACnC,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;gBACrE,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnI,CAAC,CAAC,CAAC;QACP,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACrB,MAAM,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,EAAE,EAAE;YACrD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/C,iIAAiI;YACjI,6DAA6D;YAC7D,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACrI,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,IAAI,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5E,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;YACvG,MAAM,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;QACxG,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;YAC1C,MAAM,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5H,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { TrierarchConfiguration } from '@aeolus-fleet/common';
|
|
1
2
|
import { type CommandPart } from '../adapters/command-line.js';
|
|
3
|
+
import { TrierarchFileError } from '../adapters/files.js';
|
|
2
4
|
import { type HarnessFiles } from '../adapters/harnesses.js';
|
|
3
|
-
import type { AdapterFlag } from '../core/ports.js';
|
|
5
|
+
import type { AdapterFlag, ContainerHostPort } from '../core/ports.js';
|
|
4
6
|
import type { TrierarchPaths } from '../adapters/paths.js';
|
|
5
7
|
/** `aeolus-trierarch config check`: checks the configuration and gives the effective command per harness. */
|
|
6
8
|
export interface ConfigCheckReport {
|
|
@@ -17,6 +19,15 @@ export interface ConfigCheckReport {
|
|
|
17
19
|
firstStart?: readonly CommandPart[];
|
|
18
20
|
restart?: readonly CommandPart[];
|
|
19
21
|
}>>;
|
|
22
|
+
/** Where the sessions run: on the host unless the configuration names the container runtime (decision 0039). */
|
|
23
|
+
readonly runtime: NonNullable<TrierarchConfiguration['runtime']>;
|
|
20
24
|
readonly text: string;
|
|
21
25
|
}
|
|
22
|
-
|
|
26
|
+
/** The configuration's session runtime refused, with every reason: config check and the run both say it so. */
|
|
27
|
+
export declare function runtimeRefused(config: string, refusals: readonly string[]): TrierarchFileError;
|
|
28
|
+
/** What config check reads of the machine beside the configuration: the harnesses' own files and what the container runtime needs. */
|
|
29
|
+
export interface CheckedMachine {
|
|
30
|
+
readonly files: HarnessFiles;
|
|
31
|
+
readonly host: ContainerHostPort;
|
|
32
|
+
}
|
|
33
|
+
export declare function configCheck(paths: TrierarchPaths, machine: CheckedMachine): Promise<ConfigCheckReport>;
|