@cabane/companion 0.6.203 → 0.6.204
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 +25 -1
- package/dist/cli.js +1544 -1730
- package/dist/launch.js +5 -23
- package/dist/pairing-config.js +29 -45
- package/dist/runtime.js +92 -111
- package/package.json +1 -1
package/dist/launch.js
CHANGED
|
@@ -71,25 +71,7 @@ var prepareHookSchema = z.object({
|
|
|
71
71
|
// Wall-clock cap for the hook. Provisioning is slow (minutes), so the
|
|
72
72
|
// default is generous; a hook that hangs past this is killed and the turn
|
|
73
73
|
// fails with a clear timeout message rather than pinning the companion.
|
|
74
|
-
timeoutMs: z.number().int().positive().optional()
|
|
75
|
-
// Re-invoke the hook when a prepared result already exists, in VALIDATE
|
|
76
|
-
// mode: the cached result is handed back as `prepared` and stdout is
|
|
77
|
-
// ignored, so the cwd cannot move. Its only power is to exit non-zero and
|
|
78
|
-
// fail the turn. The hook resolves once per (conversation, agent), so a
|
|
79
|
-
// later message asking for a different environment is otherwise silently
|
|
80
|
-
// ignored; this lets a hook refuse it out loud.
|
|
81
|
-
//
|
|
82
|
-
// Default OFF: a hook that provisions unconditionally must not start
|
|
83
|
-
// running on every turn because the companion upgraded.
|
|
84
|
-
validateCached: z.boolean().optional(),
|
|
85
|
-
// Independent operator-owned reporter. Receives sanitized failure metadata
|
|
86
|
-
// on stdin; never re-enters this hook and cannot change the turn outcome.
|
|
87
|
-
failureReporter: z.object({
|
|
88
|
-
command: z.string().min(1),
|
|
89
|
-
args: z.array(z.string()).optional(),
|
|
90
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
91
|
-
timeoutMs: z.number().int().positive().max(3e4).optional()
|
|
92
|
-
}).strict().optional()
|
|
74
|
+
timeoutMs: z.number().int().positive().optional()
|
|
93
75
|
}).strict();
|
|
94
76
|
var DEFAULT_TIMEOUT_MS = 10 * 6e4;
|
|
95
77
|
var prepareResultSchema = z.object({
|
|
@@ -161,8 +143,7 @@ var companionConfigSchema = z2.object({
|
|
|
161
143
|
// The DEVICE-LEVEL prepare hook, for every agent assigned here unless its own
|
|
162
144
|
// `agents` row names one. Per-agent hooks alone make the config a second
|
|
163
145
|
// silent roster: an agent nobody listed gets no hook and no error, and starts
|
|
164
|
-
// in the operator's `$HOME
|
|
165
|
-
// 2026-08-17).
|
|
146
|
+
// in the operator's `$HOME`.
|
|
166
147
|
prepareHook: prepareHookSchema.optional(),
|
|
167
148
|
// `dashboardPort` and `autoOpen` are IGNORED by the CLI (no port, no browser)
|
|
168
149
|
// but stay in the schema so an existing file still parses; the Electron shell
|
|
@@ -199,9 +180,10 @@ var companionConfigSchema = z2.object({
|
|
|
199
180
|
root: z2.string().min(1).refine(isRootPath, { message: "must be an absolute path, or start with ~/" }).optional(),
|
|
200
181
|
// An argv prefix the operator puts in front of every turn's runner: the companion starts
|
|
201
182
|
// `<prefix…> <its own run-turn command…>` instead of the runner bare. What the prefix does
|
|
202
|
-
// is the operator's (a
|
|
183
|
+
// is the operator's (a container or VM per turn, say); the companion knows nothing of it
|
|
203
184
|
// beyond handing the runner over, with the turn's inputs in its environment and the
|
|
204
|
-
// credential and secrets on its stdin (`runner/launch.ts`, `
|
|
185
|
+
// credential and secrets on its stdin (`runner/launch.ts`, `wrapped`). The README lists
|
|
186
|
+
// what a wrapper can rely on.
|
|
205
187
|
runner: z2.object({
|
|
206
188
|
command: z2.array(z2.string().min(1)).min(1)
|
|
207
189
|
}).strict().optional()
|
package/dist/pairing-config.js
CHANGED
|
@@ -93,25 +93,7 @@ var prepareHookSchema = z.object({
|
|
|
93
93
|
// Wall-clock cap for the hook. Provisioning is slow (minutes), so the
|
|
94
94
|
// default is generous; a hook that hangs past this is killed and the turn
|
|
95
95
|
// fails with a clear timeout message rather than pinning the companion.
|
|
96
|
-
timeoutMs: z.number().int().positive().optional()
|
|
97
|
-
// Re-invoke the hook when a prepared result already exists, in VALIDATE
|
|
98
|
-
// mode: the cached result is handed back as `prepared` and stdout is
|
|
99
|
-
// ignored, so the cwd cannot move. Its only power is to exit non-zero and
|
|
100
|
-
// fail the turn. The hook resolves once per (conversation, agent), so a
|
|
101
|
-
// later message asking for a different environment is otherwise silently
|
|
102
|
-
// ignored; this lets a hook refuse it out loud.
|
|
103
|
-
//
|
|
104
|
-
// Default OFF: a hook that provisions unconditionally must not start
|
|
105
|
-
// running on every turn because the companion upgraded.
|
|
106
|
-
validateCached: z.boolean().optional(),
|
|
107
|
-
// Independent operator-owned reporter. Receives sanitized failure metadata
|
|
108
|
-
// on stdin; never re-enters this hook and cannot change the turn outcome.
|
|
109
|
-
failureReporter: z.object({
|
|
110
|
-
command: z.string().min(1),
|
|
111
|
-
args: z.array(z.string()).optional(),
|
|
112
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
113
|
-
timeoutMs: z.number().int().positive().max(3e4).optional()
|
|
114
|
-
}).strict().optional()
|
|
96
|
+
timeoutMs: z.number().int().positive().optional()
|
|
115
97
|
}).strict();
|
|
116
98
|
var DEFAULT_TIMEOUT_MS = 10 * 6e4;
|
|
117
99
|
var prepareResultSchema = z.object({
|
|
@@ -186,8 +168,7 @@ var companionConfigSchema = z2.object({
|
|
|
186
168
|
// The DEVICE-LEVEL prepare hook, for every agent assigned here unless its own
|
|
187
169
|
// `agents` row names one. Per-agent hooks alone make the config a second
|
|
188
170
|
// silent roster: an agent nobody listed gets no hook and no error, and starts
|
|
189
|
-
// in the operator's `$HOME
|
|
190
|
-
// 2026-08-17).
|
|
171
|
+
// in the operator's `$HOME`.
|
|
191
172
|
prepareHook: prepareHookSchema.optional(),
|
|
192
173
|
// `dashboardPort` and `autoOpen` are IGNORED by the CLI (no port, no browser)
|
|
193
174
|
// but stay in the schema so an existing file still parses; the Electron shell
|
|
@@ -224,40 +205,43 @@ var companionConfigSchema = z2.object({
|
|
|
224
205
|
root: z2.string().min(1).refine(isRootPath, { message: "must be an absolute path, or start with ~/" }).optional(),
|
|
225
206
|
// An argv prefix the operator puts in front of every turn's runner: the companion starts
|
|
226
207
|
// `<prefix…> <its own run-turn command…>` instead of the runner bare. What the prefix does
|
|
227
|
-
// is the operator's (a
|
|
208
|
+
// is the operator's (a container or VM per turn, say); the companion knows nothing of it
|
|
228
209
|
// beyond handing the runner over, with the turn's inputs in its environment and the
|
|
229
|
-
// credential and secrets on its stdin (`runner/launch.ts`, `
|
|
210
|
+
// credential and secrets on its stdin (`runner/launch.ts`, `wrapped`). The README lists
|
|
211
|
+
// what a wrapper can rely on.
|
|
230
212
|
runner: z2.object({
|
|
231
213
|
command: z2.array(z2.string().min(1)).min(1)
|
|
232
214
|
}).strict().optional()
|
|
233
215
|
});
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
216
|
+
var RETIRED_ROW_KEYS = ["sandbox"];
|
|
217
|
+
var RETIRED_HOOK_KEYS = ["validateCached", "failureReporter"];
|
|
218
|
+
function isObject(value) {
|
|
219
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
220
|
+
}
|
|
221
|
+
function splitRetired(raw) {
|
|
237
222
|
const keys = [];
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
223
|
+
const without = (obj, names, path) => {
|
|
224
|
+
const out = {};
|
|
225
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
226
|
+
if (names.includes(k)) keys.push(`${path}${k}`);
|
|
227
|
+
else out[k] = v;
|
|
243
228
|
}
|
|
229
|
+
return out;
|
|
230
|
+
};
|
|
231
|
+
const hook = (row, path) => isObject(row.prepareHook) ? { ...row, prepareHook: without(row.prepareHook, RETIRED_HOOK_KEYS, `${path}prepareHook.`) } : row;
|
|
232
|
+
const kept = hook(without(raw, ["runners"], ""), "");
|
|
233
|
+
if (isObject(kept.agents)) {
|
|
234
|
+
const agents = {};
|
|
235
|
+
for (const [key, row] of Object.entries(kept.agents)) {
|
|
236
|
+
const path = `agents.${key}.`;
|
|
237
|
+
agents[key] = isObject(row) ? hook(without(row, RETIRED_ROW_KEYS, path), path) : row;
|
|
238
|
+
}
|
|
239
|
+
kept.agents = agents;
|
|
244
240
|
}
|
|
245
|
-
return keys;
|
|
241
|
+
return { keys, kept };
|
|
246
242
|
}
|
|
247
243
|
function withoutRetiredKeys(raw) {
|
|
248
|
-
|
|
249
|
-
const { runners: _runners, ...rest } = raw;
|
|
250
|
-
if (!rest.agents || typeof rest.agents !== "object") return rest;
|
|
251
|
-
const agents = {};
|
|
252
|
-
for (const [key, row] of Object.entries(rest.agents)) {
|
|
253
|
-
if (row && typeof row === "object" && "sandbox" in row) {
|
|
254
|
-
const { sandbox: _sandbox, ...kept } = row;
|
|
255
|
-
agents[key] = kept;
|
|
256
|
-
} else {
|
|
257
|
-
agents[key] = row;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return { ...rest, agents };
|
|
244
|
+
return isObject(raw) ? splitRetired(raw).kept : raw;
|
|
261
245
|
}
|
|
262
246
|
var legacyOfferSchema = z2.object({
|
|
263
247
|
claudeCode: z2.object({ enabled: z2.boolean().optional() }).passthrough().optional(),
|