@agentshouse/kit 0.2.1-c15804a0fa28d → 0.2.1-c23b83622c698
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/dist/agents.js +38 -19
- package/dist/bootstrap.json +4 -4
- package/dist/clis.js +19 -4
- package/dist/conversations.js +11 -7
- package/dist/secret-input.js +3 -1
- package/dist/sign-in.js +2 -1
- package/package.json +1 -1
package/dist/agents.js
CHANGED
|
@@ -3,13 +3,16 @@ import { readFile, realpath } from 'node:fs/promises';
|
|
|
3
3
|
import { killTree, startAdapter } from './acp.js';
|
|
4
4
|
import { CLIS, KIT_VERSION, below, installAdapter, installCli, locate, run, versionOf } from './clis.js';
|
|
5
5
|
import { agentBase, kitHome } from './home.js';
|
|
6
|
-
const SIGNED_OUT = { signed_in: false, models: [] };
|
|
6
|
+
const SIGNED_OUT = { signed_in: false, models: [], modes: [] };
|
|
7
7
|
function select(options, category) {
|
|
8
8
|
const option = options.find((candidate) => candidate.category === category);
|
|
9
9
|
return option?.type === 'select' ? option : undefined;
|
|
10
10
|
}
|
|
11
|
+
function choices(options) {
|
|
12
|
+
return options.flatMap((entry) => ('group' in entry ? entry.options : [entry]));
|
|
13
|
+
}
|
|
11
14
|
function values(options) {
|
|
12
|
-
return
|
|
15
|
+
return choices(options).map((entry) => entry.value);
|
|
13
16
|
}
|
|
14
17
|
function causeOf(error) {
|
|
15
18
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -21,9 +24,11 @@ async function models(kind, adapter, known) {
|
|
|
21
24
|
const agent = adapter.connection.agent;
|
|
22
25
|
const opened = await agent.request('session/new', { cwd: kitHome(), mcpServers: [] });
|
|
23
26
|
let options = opened.configOptions ?? [];
|
|
27
|
+
const mode = select(options, 'mode');
|
|
28
|
+
const modes = mode === undefined ? [] : choices(mode.options).map(({ value, name }) => ({ mode: value, name }));
|
|
24
29
|
const model = select(options, 'model');
|
|
25
30
|
if (model === undefined)
|
|
26
|
-
return [];
|
|
31
|
+
return { models: [], modes };
|
|
27
32
|
const offered = [];
|
|
28
33
|
for (const value of values(model.options)) {
|
|
29
34
|
if (select(options, 'model')?.currentValue !== value) {
|
|
@@ -39,7 +44,13 @@ async function models(kind, adapter, known) {
|
|
|
39
44
|
const effort = select(options, 'thought_level');
|
|
40
45
|
offered.push({ model: value, efforts: effort === undefined ? [] : values(effort.options) });
|
|
41
46
|
}
|
|
42
|
-
return offered;
|
|
47
|
+
return { models: offered, modes };
|
|
48
|
+
}
|
|
49
|
+
async function signedIn(kind, cli, known) {
|
|
50
|
+
const probe = CLIS[kind].signedIn;
|
|
51
|
+
if ('command' in probe)
|
|
52
|
+
return (await run(cli, probe.command, 30_000)).status === 0;
|
|
53
|
+
return (await offer(kind, cli, known)).signed_in;
|
|
43
54
|
}
|
|
44
55
|
async function offer(kind, cli, known) {
|
|
45
56
|
const probe = CLIS[kind].signedIn;
|
|
@@ -53,11 +64,15 @@ async function offer(kind, cli, known) {
|
|
|
53
64
|
if (typeof method !== 'string' || method.length === 0)
|
|
54
65
|
return SIGNED_OUT;
|
|
55
66
|
}
|
|
56
|
-
return { signed_in: true,
|
|
67
|
+
return { signed_in: true, ...(await models(kind, adapter, known.models)) };
|
|
57
68
|
}
|
|
58
69
|
catch (error) {
|
|
59
70
|
process.stderr.write(`kit: ${kind} did not offer its models: ${causeOf(error)}\n`);
|
|
60
|
-
return {
|
|
71
|
+
return {
|
|
72
|
+
signed_in: adapter === undefined && 'initializeMeta' in probe ? known.signed_in : true,
|
|
73
|
+
models: known.models,
|
|
74
|
+
modes: known.modes,
|
|
75
|
+
};
|
|
61
76
|
}
|
|
62
77
|
finally {
|
|
63
78
|
if (adapter !== undefined)
|
|
@@ -72,6 +87,8 @@ function reported(kind, reading) {
|
|
|
72
87
|
failure: reading.failure,
|
|
73
88
|
signed_in: reading.signed_in,
|
|
74
89
|
models: reading.models,
|
|
90
|
+
modes: reading.modes,
|
|
91
|
+
full_access: CLIS[kind].fullAccess,
|
|
75
92
|
};
|
|
76
93
|
}
|
|
77
94
|
function tooOld(kind, release) {
|
|
@@ -114,7 +131,7 @@ export class Agents {
|
|
|
114
131
|
});
|
|
115
132
|
this.reading = reading;
|
|
116
133
|
return reading.then(({ agents }) => {
|
|
117
|
-
Promise.all(agents.map((kind) => this.
|
|
134
|
+
Promise.all(agents.map((kind) => this.load(kind)))
|
|
118
135
|
.then(() => this.report())
|
|
119
136
|
.catch(logged);
|
|
120
137
|
});
|
|
@@ -130,7 +147,7 @@ export class Agents {
|
|
|
130
147
|
const known = this.readings.get(kind);
|
|
131
148
|
const kept = known?.release === null || known?.minimum !== undefined ? SIGNED_OUT : (known ?? SIGNED_OUT);
|
|
132
149
|
if (known?.release !== release || known.minimum !== undefined) {
|
|
133
|
-
this.update(kind, { release, failure: null, signed_in: kept.signed_in, models: kept.models });
|
|
150
|
+
this.update(kind, { release, failure: null, signed_in: kept.signed_in, models: kept.models, modes: kept.modes });
|
|
134
151
|
}
|
|
135
152
|
const read = this.nextRead(kind);
|
|
136
153
|
offer(kind, cli, kept)
|
|
@@ -147,10 +164,12 @@ export class Agents {
|
|
|
147
164
|
return this.queue(kind, () => this.ensure(kind));
|
|
148
165
|
}
|
|
149
166
|
async reread(kind) {
|
|
150
|
-
await this.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
167
|
+
await this.examine(kind, this.readings.get(kind) ?? SIGNED_OUT, offer);
|
|
168
|
+
await this.report();
|
|
169
|
+
}
|
|
170
|
+
async recheck(kind) {
|
|
171
|
+
const known = this.readings.get(kind) ?? SIGNED_OUT;
|
|
172
|
+
await this.examine(kind, known, async (kind, cli) => (await signedIn(kind, cli, known)) ? { ...known, signed_in: true } : SIGNED_OUT);
|
|
154
173
|
await this.report();
|
|
155
174
|
}
|
|
156
175
|
report() {
|
|
@@ -207,18 +226,18 @@ export class Agents {
|
|
|
207
226
|
return { release, minimum, failure: null, ...SIGNED_OUT };
|
|
208
227
|
return { cli, release };
|
|
209
228
|
}
|
|
210
|
-
async examine(kind, known) {
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
229
|
+
async examine(kind, known, read) {
|
|
230
|
+
const current = this.nextRead(kind);
|
|
231
|
+
const resolved = await this.queue(kind, () => this.resolve(kind));
|
|
232
|
+
const reading = 'cli' in resolved ? { release: resolved.release, failure: null, ...(await read(kind, resolved.cli, known)) } : resolved;
|
|
233
|
+
if (this.reads.get(kind) === current)
|
|
234
|
+
this.readings.set(kind, reading);
|
|
215
235
|
}
|
|
216
236
|
async load(kind) {
|
|
217
237
|
const known = this.readings.get(kind);
|
|
218
238
|
if (known !== undefined && known.failure === null)
|
|
219
239
|
return;
|
|
220
|
-
this.
|
|
221
|
-
this.readings.set(kind, await this.examine(kind, SIGNED_OUT));
|
|
240
|
+
await this.examine(kind, SIGNED_OUT, offer);
|
|
222
241
|
}
|
|
223
242
|
async send() {
|
|
224
243
|
const agents = this.desired.agents.flatMap((kind) => {
|
package/dist/bootstrap.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"version": "0.2.1-
|
|
3
|
+
"version": "0.2.1-c23b83622c698",
|
|
4
4
|
"hosts": {
|
|
5
5
|
"macos": {
|
|
6
6
|
"asset": {
|
|
7
7
|
"name": "connect-linux.sh",
|
|
8
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-
|
|
8
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c23b83622c698/connect-linux.sh"
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"linux": {
|
|
12
12
|
"asset": {
|
|
13
13
|
"name": "connect-linux.sh",
|
|
14
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-
|
|
14
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c23b83622c698/connect-linux.sh"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"windows": {
|
|
18
18
|
"asset": {
|
|
19
19
|
"name": "connect-windows.ps1",
|
|
20
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-
|
|
20
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c23b83622c698/connect-windows.ps1"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
package/dist/clis.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import { userInfo } from 'node:os';
|
|
3
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { homedir, userInfo } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { kitHome } from './home.js';
|
|
7
7
|
const RUNNING_JOB = new Set(['running', 'paused']);
|
|
8
|
+
async function allowHouseInCodex() {
|
|
9
|
+
const rules = join(process.env.CODEX_HOME || join(homedir(), '.codex'), 'rules');
|
|
10
|
+
await mkdir(rules, { recursive: true });
|
|
11
|
+
await writeFile(join(rules, 'house.rules'), 'prefix_rule(pattern = ["house"], decision = "allow")\n');
|
|
12
|
+
}
|
|
13
|
+
async function nothing() { }
|
|
8
14
|
function threadStatus({ method, params }) {
|
|
9
15
|
if (method !== 'session/update' || params?.update?.sessionUpdate !== 'session_info_update')
|
|
10
16
|
return undefined;
|
|
@@ -36,6 +42,9 @@ export const CLIS = {
|
|
|
36
42
|
install: 'curl -fsSL https://chatgpt.com/codex/install.sh | sh',
|
|
37
43
|
adapter: { package: '@agentclientprotocol/codex-acp', bin: 'codex-acp', executable: 'CODEX_PATH', env: {} },
|
|
38
44
|
args: [],
|
|
45
|
+
fullAccess: 'agent-full-access',
|
|
46
|
+
sessionMeta: {},
|
|
47
|
+
allowHouse: allowHouseInCodex,
|
|
39
48
|
signedIn: { command: ['login', 'status'] },
|
|
40
49
|
login: { args: ['login', '--device-auth'], code: 'show' },
|
|
41
50
|
queues: false,
|
|
@@ -52,9 +61,12 @@ export const CLIS = {
|
|
|
52
61
|
package: '@agentclientprotocol/claude-agent-acp',
|
|
53
62
|
bin: 'claude-agent-acp',
|
|
54
63
|
executable: 'CLAUDE_CODE_EXECUTABLE',
|
|
55
|
-
env: { CLAUDE_CODE_ENTRYPOINT: 'claude-agent-acp' },
|
|
64
|
+
env: { CLAUDE_CODE_ENTRYPOINT: 'claude-agent-acp', IS_SANDBOX: '1' },
|
|
56
65
|
},
|
|
57
66
|
args: [],
|
|
67
|
+
fullAccess: 'bypassPermissions',
|
|
68
|
+
sessionMeta: { claudeCode: { options: { allowedTools: ['Bash(house:*)'] } } },
|
|
69
|
+
allowHouse: nothing,
|
|
58
70
|
signedIn: { command: ['auth', 'status'] },
|
|
59
71
|
login: { args: ['auth', 'login', '--claudeai'], code: 'collect', rejected: 'Invalid code' },
|
|
60
72
|
queues: false,
|
|
@@ -70,7 +82,10 @@ export const CLIS = {
|
|
|
70
82
|
minimum: '1.0.46',
|
|
71
83
|
install: 'curl -fsSL https://x.ai/cli/install.sh | bash',
|
|
72
84
|
adapter: null,
|
|
73
|
-
args: ['agent', '--no-leader', 'stdio'],
|
|
85
|
+
args: ['agent', '--always-approve', '--no-leader', 'stdio'],
|
|
86
|
+
fullAccess: null,
|
|
87
|
+
sessionMeta: {},
|
|
88
|
+
allowHouse: nothing,
|
|
74
89
|
signedIn: { initializeMeta: 'defaultAuthMethodId' },
|
|
75
90
|
login: { args: ['login', '--device-auth'], code: 'show' },
|
|
76
91
|
queues: true,
|
package/dist/conversations.js
CHANGED
|
@@ -285,13 +285,15 @@ export class Conversations {
|
|
|
285
285
|
conversation.opening = bridge;
|
|
286
286
|
try {
|
|
287
287
|
await unlessAborted(createHowWeWork(bridge), conversation.killed.signal);
|
|
288
|
+
await CLIS[route.kind].allowHouse();
|
|
288
289
|
const adapter = await startAdapter(route.kind, cli, route.working_directory, app, (job) => this.job(conversation, job), bridge.env);
|
|
289
290
|
void adapter.exited.then(() => bridge.close());
|
|
290
291
|
const agent = adapter.connection.agent;
|
|
291
292
|
const cwd = route.working_directory;
|
|
293
|
+
const _meta = CLIS[route.kind].sessionMeta;
|
|
292
294
|
const opened = sessionId === null
|
|
293
|
-
? await agent.request('session/new', { cwd, mcpServers: [] })
|
|
294
|
-
: { ...(await agent.request('session/resume', { sessionId, cwd, mcpServers: [] })), sessionId };
|
|
295
|
+
? await agent.request('session/new', { cwd, mcpServers: [], _meta })
|
|
296
|
+
: { ...(await agent.request('session/resume', { sessionId, cwd, mcpServers: [], _meta })), sessionId };
|
|
295
297
|
const running = {
|
|
296
298
|
adapter,
|
|
297
299
|
bridge,
|
|
@@ -321,6 +323,7 @@ export class Conversations {
|
|
|
321
323
|
async launchSettings(running, route, offered) {
|
|
322
324
|
let options = offered;
|
|
323
325
|
const settings = [
|
|
326
|
+
['mode', route.mode ?? CLIS[route.kind].fullAccess],
|
|
324
327
|
['model', route.model],
|
|
325
328
|
['thought_level', route.effort],
|
|
326
329
|
];
|
|
@@ -389,10 +392,8 @@ export class Conversations {
|
|
|
389
392
|
turn.admitted = true;
|
|
390
393
|
for (const note of turn.notes.splice(0))
|
|
391
394
|
this.kit.send(note);
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
this.draft(conversation, turn);
|
|
395
|
-
}
|
|
395
|
+
turn.unsentFrom = 0;
|
|
396
|
+
this.draft(conversation, turn);
|
|
396
397
|
if (turn.entries !== null)
|
|
397
398
|
this.plan(conversation, turn);
|
|
398
399
|
}
|
|
@@ -442,8 +443,11 @@ export class Conversations {
|
|
|
442
443
|
this.attach(conversation.turn ?? this.begin(conversation), sent);
|
|
443
444
|
}
|
|
444
445
|
running.adapter.connection.agent.request('session/prompt', { sessionId: running.sessionId, prompt }).then(() => this.answered(conversation, sent, null), async (error) => {
|
|
445
|
-
if (!running.adapter.connection.signal.aborted)
|
|
446
|
+
if (!running.adapter.connection.signal.aborted) {
|
|
446
447
|
this.answered(conversation, sent, causeOf(error));
|
|
448
|
+
if (conversation.open === 0 && conversation.running === running)
|
|
449
|
+
stop(running.bridge);
|
|
450
|
+
}
|
|
447
451
|
else if (sent.turn !== null) {
|
|
448
452
|
this.end(conversation, sent.turn, { failed: running.killed ? KILLED : await running.adapter.exited });
|
|
449
453
|
}
|
package/dist/secret-input.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { retryDelay } from './api.js';
|
|
1
|
+
import { HouseRefusal, retryDelay } from './api.js';
|
|
2
2
|
export async function holdSecretInput(house, subject, steps, waiting) {
|
|
3
3
|
for (let failures = 0; waiting();) {
|
|
4
4
|
try {
|
|
@@ -10,6 +10,8 @@ export async function holdSecretInput(house, subject, steps, waiting) {
|
|
|
10
10
|
failures = 0;
|
|
11
11
|
}
|
|
12
12
|
catch (error) {
|
|
13
|
+
if (error instanceof HouseRefusal && error.status < 500)
|
|
14
|
+
return null;
|
|
13
15
|
process.stderr.write(`kit: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
14
16
|
await new Promise((resolve) => setTimeout(resolve, retryDelay(failures++)));
|
|
15
17
|
}
|
package/dist/sign-in.js
CHANGED
|
@@ -31,8 +31,9 @@ export class SignIns {
|
|
|
31
31
|
this.running.add(input.input_id);
|
|
32
32
|
this.changed();
|
|
33
33
|
this.login(input)
|
|
34
|
-
.then(() => this.agents.
|
|
34
|
+
.then(() => this.agents.recheck(input.cli))
|
|
35
35
|
.then(() => this.house.deliver(`/kit/inputs/${input.input_id}/ack`, {}))
|
|
36
|
+
.then(() => this.agents.reread(input.cli))
|
|
36
37
|
.catch(logged)
|
|
37
38
|
.finally(() => {
|
|
38
39
|
this.running.delete(input.input_id);
|