@agentshouse/kit 0.2.1-c3895fcff473b → 0.2.1-c3cf4b145dcda
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 +8 -9
- package/dist/acp.js +26 -13
- package/dist/agents.js +61 -31
- package/dist/api.js +30 -2
- package/dist/app-git.js +64 -0
- package/dist/bootstrap.json +4 -4
- package/dist/bridge.js +25 -17
- package/dist/clis.js +38 -62
- package/dist/conversations.js +277 -229
- package/dist/copies.js +3 -5
- package/dist/end.js +8 -0
- package/dist/events.js +587 -0
- package/dist/files.js +14 -0
- package/dist/house-main.js +4 -1
- package/dist/kit-main.js +3 -0
- package/dist/login.js +4 -0
- package/dist/logout.js +3 -0
- package/dist/parts.js +64 -0
- package/dist/refusals.js +12 -0
- package/dist/resident.js +3 -3
- package/dist/secret-input.js +4 -1
- package/dist/shell.js +3 -0
- package/dist/sign-in.js +33 -8
- package/dist/stream.js +29 -4
- package/dist/transcription.js +54 -6
- package/dist/update.js +2 -0
- package/package.json +1 -1
- package/dist/blocks.js +0 -51
package/dist/clis.js
CHANGED
|
@@ -4,37 +4,12 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
4
4
|
import { homedir, userInfo } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import { kitHome } from './home.js';
|
|
7
|
-
const RUNNING_JOB = new Set(['running', 'paused']);
|
|
8
7
|
async function allowHouseInCodex() {
|
|
9
8
|
const rules = join(process.env.CODEX_HOME || join(homedir(), '.codex'), 'rules');
|
|
10
9
|
await mkdir(rules, { recursive: true });
|
|
11
10
|
await writeFile(join(rules, 'house.rules'), 'prefix_rule(pattern = ["house"], decision = "allow")\n');
|
|
12
11
|
}
|
|
13
12
|
async function nothing() { }
|
|
14
|
-
function threadStatus({ method, params }) {
|
|
15
|
-
if (method !== 'session/update' || params?.update?.sessionUpdate !== 'session_info_update')
|
|
16
|
-
return undefined;
|
|
17
|
-
return params.update._meta?.codex?.threadStatus?.type;
|
|
18
|
-
}
|
|
19
|
-
function asyncTask({ method, params }) {
|
|
20
|
-
const update = params?.update;
|
|
21
|
-
if (method !== 'session/update' || update?.asyncTaskId === undefined)
|
|
22
|
-
return null;
|
|
23
|
-
if (update.sessionUpdate === 'async_task_spawned')
|
|
24
|
-
return { id: update.asyncTaskId, running: true };
|
|
25
|
-
if (update.sessionUpdate === 'async_task_state_update' && !RUNNING_JOB.has(update.state ?? '')) {
|
|
26
|
-
return { id: update.asyncTaskId, running: false };
|
|
27
|
-
}
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
function airPhase({ _meta }) {
|
|
31
|
-
const phase = _meta?.jetbrains?.air?.phase;
|
|
32
|
-
if (phase === 'commentary')
|
|
33
|
-
return 'note';
|
|
34
|
-
if (phase === 'final_answer')
|
|
35
|
-
return 'answer';
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
13
|
export const CLIS = {
|
|
39
14
|
'codex-acp': {
|
|
40
15
|
bin: 'codex',
|
|
@@ -47,11 +22,7 @@ export const CLIS = {
|
|
|
47
22
|
allowHouse: allowHouseInCodex,
|
|
48
23
|
signedIn: { command: ['login', 'status'] },
|
|
49
24
|
login: { args: ['login', '--device-auth'], code: 'show' },
|
|
50
|
-
|
|
51
|
-
turnStarted: (notice) => threadStatus(notice) === 'active',
|
|
52
|
-
turnEnded: (notice) => threadStatus(notice) === 'idle',
|
|
53
|
-
job: asyncTask,
|
|
54
|
-
phase: airPhase,
|
|
25
|
+
air: ['asyncTasks', 'nativeSubagentSessions'],
|
|
55
26
|
},
|
|
56
27
|
'claude-agent-acp': {
|
|
57
28
|
bin: 'claude',
|
|
@@ -65,17 +36,16 @@ export const CLIS = {
|
|
|
65
36
|
},
|
|
66
37
|
args: [],
|
|
67
38
|
fullAccess: 'bypassPermissions',
|
|
68
|
-
sessionMeta: {
|
|
39
|
+
sessionMeta: {
|
|
40
|
+
claudeCode: {
|
|
41
|
+
options: { allowedTools: ['Bash(house:*)'] },
|
|
42
|
+
emitRawSDKMessages: ['background_tasks_changed', 'session_state_changed', 'task_started', 'task_notification'].map((subtype) => ({ type: 'system', subtype })),
|
|
43
|
+
},
|
|
44
|
+
},
|
|
69
45
|
allowHouse: nothing,
|
|
70
46
|
signedIn: { command: ['auth', 'status'] },
|
|
71
47
|
login: { args: ['auth', 'login', '--claudeai'], code: 'collect', rejected: 'Invalid code' },
|
|
72
|
-
|
|
73
|
-
turnStarted: () => false,
|
|
74
|
-
turnEnded: ({ method, params }) => method === 'session/update' &&
|
|
75
|
-
params?.update?.sessionUpdate === 'usage_update' &&
|
|
76
|
-
params.update._meta?.['_claude/origin'] !== undefined,
|
|
77
|
-
job: asyncTask,
|
|
78
|
-
phase: () => null,
|
|
48
|
+
air: ['asyncTasks', 'sessionFailure'],
|
|
79
49
|
},
|
|
80
50
|
'grok-build': {
|
|
81
51
|
bin: 'grok',
|
|
@@ -88,24 +58,16 @@ export const CLIS = {
|
|
|
88
58
|
allowHouse: nothing,
|
|
89
59
|
signedIn: { initializeMeta: 'defaultAuthMethodId' },
|
|
90
60
|
login: { args: ['login', '--device-auth'], code: 'show' },
|
|
91
|
-
|
|
92
|
-
turnStarted: ({ method, params }) => method === '_x.ai/queue/changed' && params?.runningPromptId !== undefined,
|
|
93
|
-
turnEnded: ({ method, params }) => method === '_x.ai/session_notification' && params?.update?.sessionUpdate === 'turn_completed',
|
|
94
|
-
job: ({ method, params }) => {
|
|
95
|
-
if (method === '_x.ai/task_backgrounded')
|
|
96
|
-
return { id: params.update.task_id, running: true };
|
|
97
|
-
if (method === '_x.ai/task_completed')
|
|
98
|
-
return { id: params.update.task_snapshot.task_id, running: false };
|
|
99
|
-
return null;
|
|
100
|
-
},
|
|
101
|
-
phase: () => null,
|
|
61
|
+
air: ['asyncTasks'],
|
|
102
62
|
},
|
|
103
63
|
};
|
|
104
64
|
const KIT_PACKAGE = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
105
65
|
export const KIT_VERSION = KIT_PACKAGE.version;
|
|
106
66
|
const PROXY = /^https?_proxy$/i;
|
|
107
67
|
const VERSION = /\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?/;
|
|
68
|
+
// An install still running after fifteen minutes is ended and reported as failed, so a hung download cannot hold its CLI's report.
|
|
108
69
|
const INSTALL_MS = 15 * 60_000;
|
|
70
|
+
// A login shell or a version read is ended after half a minute, so a profile that waits for input cannot stall the report.
|
|
109
71
|
const READ_MS = 30_000;
|
|
110
72
|
const CAUSE_CHARACTERS = 4000;
|
|
111
73
|
function prefix(kind) {
|
|
@@ -133,8 +95,22 @@ export function run(command, args, timeoutMs, detached = false, signal) {
|
|
|
133
95
|
timeout: timeoutMs,
|
|
134
96
|
env: withoutProxy(),
|
|
135
97
|
detached,
|
|
136
|
-
signal,
|
|
98
|
+
signal: detached ? undefined : signal,
|
|
137
99
|
});
|
|
100
|
+
const stop = () => {
|
|
101
|
+
try {
|
|
102
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
103
|
+
}
|
|
104
|
+
catch { }
|
|
105
|
+
};
|
|
106
|
+
if (detached && signal?.aborted)
|
|
107
|
+
stop();
|
|
108
|
+
if (detached)
|
|
109
|
+
signal?.addEventListener('abort', stop, { once: true });
|
|
110
|
+
const ended = (ran) => {
|
|
111
|
+
signal?.removeEventListener('abort', stop);
|
|
112
|
+
resolve(ran);
|
|
113
|
+
};
|
|
138
114
|
let stdout = '';
|
|
139
115
|
let output = '';
|
|
140
116
|
child.stdout.setEncoding('utf8').on('data', (chunk) => {
|
|
@@ -144,25 +120,25 @@ export function run(command, args, timeoutMs, detached = false, signal) {
|
|
|
144
120
|
child.stderr.setEncoding('utf8').on('data', (chunk) => {
|
|
145
121
|
output += chunk;
|
|
146
122
|
});
|
|
147
|
-
child.on('error', (error) =>
|
|
148
|
-
child.on('close', (status) =>
|
|
123
|
+
child.on('error', (error) => ended({ status: null, stdout, output: error.message }));
|
|
124
|
+
child.on('close', (status) => ended({ status, stdout, output }));
|
|
149
125
|
});
|
|
150
126
|
}
|
|
151
127
|
export function failureOf(ran, program) {
|
|
152
128
|
return ran.output.trim().slice(-CAUSE_CHARACTERS) || `${program} exited with ${ran.status ?? 'a signal'}`;
|
|
153
129
|
}
|
|
154
|
-
export async function installAdapter(kind) {
|
|
130
|
+
export async function installAdapter(kind, signal) {
|
|
155
131
|
const adapter = CLIS[kind].adapter;
|
|
156
132
|
if (adapter === null)
|
|
157
133
|
return null;
|
|
158
134
|
const release = KIT_PACKAGE.peerDependencies[adapter.package];
|
|
159
135
|
if ((await installedAdapter(kind)) === release)
|
|
160
136
|
return null;
|
|
161
|
-
const ran = await run('npm', ['install', '--prefix', prefix(kind), '--no-save', '--no-audit', '--no-fund', '--omit=optional', `${adapter.package}@${release}`], INSTALL_MS);
|
|
137
|
+
const ran = await run('npm', ['install', '--prefix', prefix(kind), '--no-save', '--no-audit', '--no-fund', '--omit=optional', `${adapter.package}@${release}`], INSTALL_MS, true, signal);
|
|
162
138
|
return ran.status === 0 ? null : failureOf(ran, 'npm');
|
|
163
139
|
}
|
|
164
|
-
export async function installCli(kind) {
|
|
165
|
-
const ran = await run('bash', ['-o', 'pipefail', '-c', CLIS[kind].install], INSTALL_MS, true);
|
|
140
|
+
export async function installCli(kind, signal) {
|
|
141
|
+
const ran = await run('bash', ['-o', 'pipefail', '-c', CLIS[kind].install], INSTALL_MS, true, signal);
|
|
166
142
|
return ran.status === 0 ? null : failureOf(ran, 'the install');
|
|
167
143
|
}
|
|
168
144
|
function loginShell() {
|
|
@@ -171,11 +147,11 @@ function loginShell() {
|
|
|
171
147
|
const FOUND = 'house-kit-cli ';
|
|
172
148
|
const LOOKUP = `found=$(command -v "$1") || exit 0; case $found in /*) ;; *) found=$(pwd -P)/$found ;; esac; printf "${FOUND}%s\\n" "$found"`;
|
|
173
149
|
const USER_BIN = 'case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) PATH="$PATH:$HOME/.local/bin" ;; esac; export PATH';
|
|
174
|
-
function inLoginShell(script, argument = '') {
|
|
175
|
-
return run(loginShell(), ['-l', '-i', '-c', `exec /bin/sh -c '${USER_BIN}; ${script}' sh ${argument}`], READ_MS, true);
|
|
150
|
+
function inLoginShell(script, argument = '', signal) {
|
|
151
|
+
return run(loginShell(), ['-l', '-i', '-c', `exec /bin/sh -c '${USER_BIN}; ${script}' sh ${argument}`], READ_MS, true, signal);
|
|
176
152
|
}
|
|
177
|
-
export async function locate(kind) {
|
|
178
|
-
const ran = await inLoginShell(LOOKUP, CLIS[kind].bin);
|
|
153
|
+
export async function locate(kind, signal) {
|
|
154
|
+
const ran = await inLoginShell(LOOKUP, CLIS[kind].bin, signal);
|
|
179
155
|
return ran.stdout.split('\n').findLast((line) => line.startsWith(FOUND))?.slice(FOUND.length) ?? null;
|
|
180
156
|
}
|
|
181
157
|
export async function loginPath() {
|
|
@@ -183,8 +159,8 @@ export async function loginPath() {
|
|
|
183
159
|
const ran = await inLoginShell(`printf "${marker}%s\\n" "$PATH"`);
|
|
184
160
|
return ran.stdout.split('\n').findLast((line) => line.startsWith(marker)).slice(marker.length);
|
|
185
161
|
}
|
|
186
|
-
export async function versionOf(path) {
|
|
187
|
-
return VERSION.exec((await run(path, ['--version'], READ_MS)).stdout)?.[0] ?? null;
|
|
162
|
+
export async function versionOf(path, signal) {
|
|
163
|
+
return VERSION.exec((await run(path, ['--version'], READ_MS, false, signal)).stdout)?.[0] ?? null;
|
|
188
164
|
}
|
|
189
165
|
function numbers(version) {
|
|
190
166
|
return version.split(/[.-]/, 3).map(Number);
|