@agentshouse/kit 0.2.1-c441d29eb63f4 → 0.2.1-c44c14117631a
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/acp.js +3 -2
- package/dist/authority-main.js +2 -2
- package/dist/bridge.js +1 -1
- package/dist/building.js +46 -0
- package/dist/clis-main.js +2 -2
- package/dist/clis.js +32 -12
- package/dist/conversations.js +9 -5
- package/dist/files.js +33 -17
- package/dist/git.js +2 -2
- package/dist/house-cli.js +24 -11
- package/dist/house-main.js +3 -3
- package/dist/kit-cli.js +2 -2
- package/dist/kit-main.js +3 -3
- package/dist/relay.js +21 -0
- package/dist/sign-in.js +3 -2
- package/dist/transcription.js +32 -23
- package/dist/update.js +30 -4
- package/dist/web-wizard.js +3 -2
- package/package.json +16 -17
- package/dist/bootstrap.json +0 -24
package/dist/acp.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ndJsonStream, PROTOCOL_VERSION, } from '@agentclientprotocol/sdk';
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { Readable, Writable } from 'node:stream';
|
|
4
|
-
import { CLIS, KIT_RELEASE, adapterCommand
|
|
4
|
+
import { CLIS, KIT_RELEASE, adapterCommand } from './clis.js';
|
|
5
|
+
import { childEnvironment } from './relay.js';
|
|
5
6
|
import { killTree } from './scope.js';
|
|
6
7
|
const RETIRED = 'the CLI was retired';
|
|
7
8
|
export async function startAdapter(kind, cli, cwd, app, events = () => undefined, added = {}, signal, scope = null) {
|
|
@@ -10,7 +11,7 @@ export async function startAdapter(kind, cli, cwd, app, events = () => undefined
|
|
|
10
11
|
const [command, args] = scope?.command(...started) ?? started;
|
|
11
12
|
const child = spawn(command, args, {
|
|
12
13
|
cwd,
|
|
13
|
-
env: { ...
|
|
14
|
+
env: { ...childEnvironment(), ...(adapter === null ? {} : { ...adapter.env, [adapter.executable]: cli }), ...added },
|
|
14
15
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
15
16
|
detached: true,
|
|
16
17
|
});
|
package/dist/authority-main.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { setGlobalProxyFromEnv } from 'node:http';
|
|
2
1
|
import { HouseRefusal, post } from './api.js';
|
|
3
2
|
import { readEnrolment } from './home.js';
|
|
3
|
+
import { proxyUnlessRelayed } from './relay.js';
|
|
4
4
|
function unanswered(error) {
|
|
5
5
|
return error instanceof HouseRefusal ? error.status >= 500 : error instanceof TypeError && error.message === 'fetch failed';
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
proxyUnlessRelayed();
|
|
8
8
|
try {
|
|
9
9
|
const { house, credential } = (await readEnrolment());
|
|
10
10
|
try {
|
package/dist/bridge.js
CHANGED
|
@@ -13,7 +13,7 @@ import { callHouse, mcpBody, rpc, UNREACHABLE } from './mcp.js';
|
|
|
13
13
|
import { operationId } from './operation.js';
|
|
14
14
|
import { refusalOf, retryable } from './refusals.js';
|
|
15
15
|
import { relayed } from './relay.js';
|
|
16
|
-
const MCP_REQUEST_BYTES =
|
|
16
|
+
const MCP_REQUEST_BYTES = 4_000_000;
|
|
17
17
|
export async function received(request) {
|
|
18
18
|
let text = '';
|
|
19
19
|
request.setEncoding('utf8');
|
package/dist/building.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { createWriteStream } from 'node:fs';
|
|
3
|
+
import { rm } from 'node:fs/promises';
|
|
4
|
+
import { Transform } from 'node:stream';
|
|
5
|
+
import { pipeline } from 'node:stream/promises';
|
|
6
|
+
import { readEnrolment } from './home.js';
|
|
7
|
+
import { relayed } from './relay.js';
|
|
8
|
+
const MANIFEST = 'bootstrap.json';
|
|
9
|
+
async function served(name, signal) {
|
|
10
|
+
const enrolment = await readEnrolment();
|
|
11
|
+
if (enrolment === null)
|
|
12
|
+
throw new Error('this Kit is connected to no House');
|
|
13
|
+
const answer = await fetch(relayed(new URL(`/kit-installer/${encodeURIComponent(name)}`, enrolment.house)), { signal });
|
|
14
|
+
if (answer.status === 200 && answer.body !== null)
|
|
15
|
+
return answer;
|
|
16
|
+
await answer.body?.cancel();
|
|
17
|
+
throw new Error(`House answered ${answer.status} for ${name}`);
|
|
18
|
+
}
|
|
19
|
+
export async function servedDigest(name, signal) {
|
|
20
|
+
const manifest = (await (await served(MANIFEST, signal)).json());
|
|
21
|
+
const sha256 = manifest.files?.[name]?.sha256;
|
|
22
|
+
return typeof sha256 === 'string' ? sha256 : null;
|
|
23
|
+
}
|
|
24
|
+
export async function downloadServed(name, sha256, destination, signal, most = Infinity) {
|
|
25
|
+
const answer = await served(name, signal);
|
|
26
|
+
const digest = createHash('sha256');
|
|
27
|
+
let bytes = 0;
|
|
28
|
+
const hashed = new Transform({
|
|
29
|
+
transform(chunk, _encoding, done) {
|
|
30
|
+
bytes += chunk.length;
|
|
31
|
+
if (bytes > most)
|
|
32
|
+
return done(new Error(`${name} is larger than its pinned ${most} bytes`));
|
|
33
|
+
digest.update(chunk);
|
|
34
|
+
done(null, chunk);
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
await pipeline(answer.body, hashed, createWriteStream(destination), { signal });
|
|
39
|
+
if (digest.digest('hex') !== sha256)
|
|
40
|
+
throw new Error(`${name} does not match its sha256`);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
await rm(destination, { force: true });
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
package/dist/clis-main.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { setGlobalProxyFromEnv } from 'node:http';
|
|
2
1
|
import { post } from './api.js';
|
|
3
2
|
import { CLIS, below, locate, versionOf } from './clis.js';
|
|
4
3
|
import { readEnrolment } from './home.js';
|
|
5
|
-
|
|
4
|
+
import { proxyUnlessRelayed } from './relay.js';
|
|
5
|
+
proxyUnlessRelayed();
|
|
6
6
|
try {
|
|
7
7
|
const { house, credential } = (await readEnrolment());
|
|
8
8
|
const { agents } = await post(house, '/kit/agents/desired', {}, credential);
|
package/dist/clis.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { constants, readFileSync } from 'node:fs';
|
|
4
|
-
import { access, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { access, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
5
5
|
import { homedir, userInfo } from 'node:os';
|
|
6
6
|
import { delimiter, dirname, isAbsolute, join } from 'node:path';
|
|
7
|
+
import { downloadServed, servedDigest } from './building.js';
|
|
7
8
|
import { kitHome } from './home.js';
|
|
9
|
+
import { childEnvironment } from './relay.js';
|
|
8
10
|
const HOUSE_EXECUTABLES = /^host_executable\(name = "house", paths = (\[.*\])\)$/m;
|
|
9
11
|
function houseRule(houses) {
|
|
10
12
|
return `prefix_rule(pattern = ["house"], decision = "allow")\nhost_executable(name = "house", paths = ${JSON.stringify(houses)})\n`;
|
|
@@ -69,7 +71,7 @@ function bridgeInClaudeSandbox(bridge) {
|
|
|
69
71
|
export const CLIS = {
|
|
70
72
|
'codex-acp': {
|
|
71
73
|
bin: 'codex',
|
|
72
|
-
minimum: '0.
|
|
74
|
+
minimum: '0.160.1',
|
|
73
75
|
install: 'curl -fsSL https://chatgpt.com/codex/install.sh | sh',
|
|
74
76
|
adapter: {
|
|
75
77
|
package: '@agentclientprotocol/codex-acp',
|
|
@@ -92,7 +94,7 @@ export const CLIS = {
|
|
|
92
94
|
},
|
|
93
95
|
'claude-agent-acp': {
|
|
94
96
|
bin: 'claude',
|
|
95
|
-
minimum: '2.1.
|
|
97
|
+
minimum: '2.1.303',
|
|
96
98
|
install: 'curl -fsSL https://claude.ai/install.sh | bash',
|
|
97
99
|
adapter: {
|
|
98
100
|
package: '@agentclientprotocol/claude-agent-acp',
|
|
@@ -138,7 +140,6 @@ export const CLIS = {
|
|
|
138
140
|
};
|
|
139
141
|
const KIT_PACKAGE = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
140
142
|
export const KIT_RELEASE = KIT_PACKAGE.version;
|
|
141
|
-
const PROXY = /^https?_proxy$/i;
|
|
142
143
|
const VERSION = /\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?/;
|
|
143
144
|
// An install still running after fifteen minutes is ended and reported as failed, so a hung download cannot hold its CLI's report.
|
|
144
145
|
const INSTALL_MS = 15 * 60_000;
|
|
@@ -160,15 +161,12 @@ async function installedAdapter(kind) {
|
|
|
160
161
|
return null;
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
|
-
export function withoutProxy() {
|
|
164
|
-
return Object.fromEntries(Object.entries(process.env).filter(([name]) => !PROXY.test(name)));
|
|
165
|
-
}
|
|
166
164
|
export function run(command, args, timeoutMs, detached = false, signal) {
|
|
167
165
|
return new Promise((resolve) => {
|
|
168
166
|
const child = spawn(command, args, {
|
|
169
167
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
170
168
|
timeout: timeoutMs,
|
|
171
|
-
env:
|
|
169
|
+
env: childEnvironment(),
|
|
172
170
|
detached,
|
|
173
171
|
signal: detached ? undefined : signal,
|
|
174
172
|
});
|
|
@@ -202,15 +200,37 @@ export function run(command, args, timeoutMs, detached = false, signal) {
|
|
|
202
200
|
export function failureOf(ran, program) {
|
|
203
201
|
return ran.output.trim().slice(-CAUSE_CHARACTERS) || `${program} exited with ${ran.status ?? 'a signal'}`;
|
|
204
202
|
}
|
|
203
|
+
export function adapterArchive(kind) {
|
|
204
|
+
return `${kind}-${KIT_PACKAGE.peerDependencies[CLIS[kind].adapter.package]}.tar.gz`;
|
|
205
|
+
}
|
|
205
206
|
export async function installAdapter(kind, signal) {
|
|
206
207
|
const adapter = CLIS[kind].adapter;
|
|
207
208
|
if (adapter === null)
|
|
208
209
|
return null;
|
|
209
|
-
|
|
210
|
-
if ((await installedAdapter(kind)) === release)
|
|
210
|
+
if ((await installedAdapter(kind)) === KIT_PACKAGE.peerDependencies[adapter.package])
|
|
211
211
|
return null;
|
|
212
|
-
const
|
|
213
|
-
|
|
212
|
+
const name = adapterArchive(kind);
|
|
213
|
+
const archive = `${prefix(kind)}.tar.gz`;
|
|
214
|
+
const deadline = AbortSignal.timeout(INSTALL_MS);
|
|
215
|
+
const bounded = signal === undefined ? deadline : AbortSignal.any([signal, deadline]);
|
|
216
|
+
try {
|
|
217
|
+
const sha256 = await servedDigest(name, bounded);
|
|
218
|
+
if (sha256 === null)
|
|
219
|
+
return `House serves no ${name}`;
|
|
220
|
+
await rm(prefix(kind), { recursive: true, force: true });
|
|
221
|
+
await mkdir(prefix(kind), { recursive: true });
|
|
222
|
+
await downloadServed(name, sha256, archive, bounded);
|
|
223
|
+
const ran = await run('tar', ['-xzf', archive, '-C', prefix(kind)], INSTALL_MS, true, signal);
|
|
224
|
+
return ran.status === 0 ? null : failureOf(ran, 'tar');
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (deadline.aborted && signal?.aborted !== true)
|
|
228
|
+
return `${name} did not arrive within ${INSTALL_MS / 1000} seconds`;
|
|
229
|
+
return error instanceof Error ? error.message : String(error);
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
await rm(archive, { force: true });
|
|
233
|
+
}
|
|
214
234
|
}
|
|
215
235
|
export async function installCli(kind, signal) {
|
|
216
236
|
const ran = await run('bash', ['-o', 'pipefail', '-c', CLIS[kind].install], INSTALL_MS, true, signal);
|
package/dist/conversations.js
CHANGED
|
@@ -78,8 +78,8 @@ function exitedWith(running, cause) {
|
|
|
78
78
|
function answerMessage(request, response) {
|
|
79
79
|
return `The User answered a question you asked earlier.\nQuestion: ${JSON.stringify(request)}\nAnswer: ${JSON.stringify(response)}`;
|
|
80
80
|
}
|
|
81
|
-
async function sentPart(url, bytes) {
|
|
82
|
-
const answer = await fetch(relayed(url), { method: 'PUT', body: bytes });
|
|
81
|
+
async function sentPart(url, bytes, headers) {
|
|
82
|
+
const answer = await fetch(relayed(url), { method: 'PUT', headers, body: bytes });
|
|
83
83
|
await answer.arrayBuffer();
|
|
84
84
|
if (!answer.ok)
|
|
85
85
|
throw storeRefusal('upload', answer.status);
|
|
@@ -914,17 +914,21 @@ export class Conversations {
|
|
|
914
914
|
async image(conversation, turn, reserved, data, mediaType) {
|
|
915
915
|
const bytes = Buffer.from(data, 'base64');
|
|
916
916
|
const name = `image-${++turn.images}.${mediaType.split('/')[1]}`;
|
|
917
|
+
const sha256 = createHash('sha256').update(bytes).digest('hex');
|
|
917
918
|
try {
|
|
918
919
|
const declared = (await this.deliver(conversation, turn, 'images', {
|
|
919
920
|
name,
|
|
920
921
|
media_type: mediaType,
|
|
921
922
|
bytes: bytes.length,
|
|
922
|
-
sha256
|
|
923
|
+
sha256,
|
|
923
924
|
}));
|
|
924
925
|
const saved = await uploaded(declared.upload, {
|
|
926
|
+
name,
|
|
925
927
|
bytes: bytes.length,
|
|
926
|
-
|
|
927
|
-
|
|
928
|
+
sha256,
|
|
929
|
+
read: (start, end) => [bytes.subarray(start, end)],
|
|
930
|
+
send: (url, start, end, headers) => sentPart(url, bytes.subarray(start, end), headers),
|
|
931
|
+
finish: (upload, partSha256) => this.kit.house.deliver('/kit/uploads/finish', { upload, part_sha256: partSha256 }),
|
|
928
932
|
});
|
|
929
933
|
turn.parts.arrive({ type: 'image', file: saved.path, name, media_type: mediaType }, reserved);
|
|
930
934
|
}
|
package/dist/files.js
CHANGED
|
@@ -9,6 +9,7 @@ import { retryDelay } from './api.js';
|
|
|
9
9
|
import { Unsettled } from './mcp.js';
|
|
10
10
|
import { relayed } from './relay.js';
|
|
11
11
|
const STALLED_ROUNDS = 8;
|
|
12
|
+
const PART_CHECKSUM = 'x-amz-checksum-sha256';
|
|
12
13
|
const LINK = /\]\((\/rooms\/[^/)\s]+\/[^)\s]+)\)/gu;
|
|
13
14
|
export function linkedPaths(text) {
|
|
14
15
|
return [...new Set(Array.from(text.matchAll(LINK), (link) => link[1]))];
|
|
@@ -32,17 +33,39 @@ function paused(milliseconds) {
|
|
|
32
33
|
export function storeRefusal(act, status) {
|
|
33
34
|
return new Error(`the ${act} answered ${status}; ${act} the file again`);
|
|
34
35
|
}
|
|
36
|
+
async function partDigests(uploading, partBytes) {
|
|
37
|
+
const whole = createHash('sha256');
|
|
38
|
+
const digests = [];
|
|
39
|
+
for (let start = 0; digests.length === 0 || start < uploading.bytes; start += partBytes) {
|
|
40
|
+
const end = Math.min(start + partBytes, uploading.bytes);
|
|
41
|
+
const digest = createHash('sha256');
|
|
42
|
+
for await (const chunk of uploading.read(start, end)) {
|
|
43
|
+
digest.update(chunk);
|
|
44
|
+
whole.update(chunk);
|
|
45
|
+
}
|
|
46
|
+
digests.push(digest.digest());
|
|
47
|
+
}
|
|
48
|
+
if (whole.digest('hex') !== uploading.sha256)
|
|
49
|
+
throw new Error(`${uploading.name} changed while it was uploaded; upload it again`);
|
|
50
|
+
return digests;
|
|
51
|
+
}
|
|
35
52
|
export async function uploaded(declared, uploading) {
|
|
36
|
-
|
|
53
|
+
const partBytes = declared.part_bytes;
|
|
54
|
+
const digests = await partDigests(uploading, partBytes);
|
|
55
|
+
const partSha256 = digests.map((digest) => digest.toString('hex'));
|
|
56
|
+
let answer = await finishing(uploading, declared.id, partSha256);
|
|
37
57
|
let idle = 0;
|
|
38
58
|
let stalled = 0;
|
|
39
|
-
|
|
59
|
+
while ('upload' in answer) {
|
|
60
|
+
const { id, parts } = answer.upload;
|
|
40
61
|
let sent = 0;
|
|
41
62
|
let failure = null;
|
|
42
|
-
for (const { part, url } of
|
|
43
|
-
const start = (part - 1) *
|
|
63
|
+
for (const { part, url } of parts ?? []) {
|
|
64
|
+
const start = (part - 1) * partBytes;
|
|
44
65
|
try {
|
|
45
|
-
await uploading.send(url, start, Math.min(start +
|
|
66
|
+
await uploading.send(url, start, Math.min(start + partBytes, uploading.bytes), {
|
|
67
|
+
[PART_CHECKSUM]: digests[part - 1].toString('base64'),
|
|
68
|
+
});
|
|
46
69
|
sent++;
|
|
47
70
|
}
|
|
48
71
|
catch (error) {
|
|
@@ -57,24 +80,17 @@ export async function uploaded(declared, uploading) {
|
|
|
57
80
|
else {
|
|
58
81
|
if (failure !== null && ++stalled >= STALLED_ROUNDS)
|
|
59
82
|
throw failure;
|
|
60
|
-
// A round that sent no part, its store unreachable
|
|
83
|
+
// A round that sent no part, its store unreachable, is followed by the next finishing call on the jittered curve.
|
|
61
84
|
await paused(retryDelay(idle++));
|
|
62
85
|
}
|
|
63
|
-
|
|
64
|
-
while ('checking' in answer) {
|
|
65
|
-
// A finishing call that finds House still checking the stored bytes is sent again after five seconds, the cadence at which House takes up a check it handed over.
|
|
66
|
-
await paused(5_000);
|
|
67
|
-
answer = await finishing(uploading, upload.id);
|
|
68
|
-
}
|
|
69
|
-
if (!('upload' in answer))
|
|
70
|
-
return answer;
|
|
71
|
-
upload = answer.upload;
|
|
86
|
+
answer = await finishing(uploading, id, partSha256);
|
|
72
87
|
}
|
|
88
|
+
return answer;
|
|
73
89
|
}
|
|
74
|
-
async function finishing(uploading, upload) {
|
|
90
|
+
async function finishing(uploading, upload, partSha256) {
|
|
75
91
|
for (let unsettled = 1;; unsettled++) {
|
|
76
92
|
try {
|
|
77
|
-
return await uploading.finish(upload);
|
|
93
|
+
return await uploading.finish(upload, partSha256);
|
|
78
94
|
}
|
|
79
95
|
catch (error) {
|
|
80
96
|
if (!(error instanceof Unsettled) || unsettled === STALLED_ROUNDS)
|
package/dist/git.js
CHANGED
|
@@ -2,8 +2,8 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { isUtf8 } from 'node:buffer';
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { withoutProxy } from './clis.js';
|
|
6
5
|
import { workspaceRoot } from './home.js';
|
|
6
|
+
import { childEnvironment } from './relay.js';
|
|
7
7
|
export function localCopies() {
|
|
8
8
|
return join(workspaceRoot(), 'local-copies');
|
|
9
9
|
}
|
|
@@ -11,7 +11,7 @@ export const HOUSE_REF = 'refs/house/received';
|
|
|
11
11
|
const COMMITTER = 'Kit <house-kit@localhost>';
|
|
12
12
|
export function run(cwd, args, input, env = {}) {
|
|
13
13
|
return new Promise((resolve, reject) => {
|
|
14
|
-
const child = spawn('git', args, { cwd, env: { ...
|
|
14
|
+
const child = spawn('git', args, { cwd, env: { ...childEnvironment(), ...env } });
|
|
15
15
|
const stdout = [];
|
|
16
16
|
let stderr = '';
|
|
17
17
|
child.stdout.on('data', (chunk) => stdout.push(chunk));
|
package/dist/house-cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { createReadStream } from 'node:fs';
|
|
3
|
-
import { request
|
|
3
|
+
import { request } from 'node:http';
|
|
4
4
|
import { request as httpsRequest } from 'node:https';
|
|
5
5
|
import { extname, join, resolve } from 'node:path';
|
|
6
6
|
import { Readable } from 'node:stream';
|
|
@@ -10,7 +10,7 @@ import { HOUSE_REF } from './git.js';
|
|
|
10
10
|
import { ownerSocket, readOwnAgent } from './home.js';
|
|
11
11
|
import { callHouse, rpc, UNREACHABLE, Unsettled } from './mcp.js';
|
|
12
12
|
import { refusalOf, retryable } from './refusals.js';
|
|
13
|
-
import { relayed, selectRelay } from './relay.js';
|
|
13
|
+
import { proxyUnlessRelayed, relayed, selectRelay } from './relay.js';
|
|
14
14
|
import { parse } from 'yaml';
|
|
15
15
|
const USAGE = "usage: house <tool> ['<arguments as JSON>']";
|
|
16
16
|
const PUSH_USAGE = 'usage: house push [commit] [--owner]';
|
|
@@ -89,7 +89,6 @@ async function direct(message) {
|
|
|
89
89
|
if (ownAgent === null)
|
|
90
90
|
throw new Error(UNCONNECTED);
|
|
91
91
|
selectRelay(process.env.HOUSE_KIT_RELAY || ownAgent.relay);
|
|
92
|
-
setGlobalProxyFromEnv();
|
|
93
92
|
const answer = await callHouse(ownAgent.house, ownAgent.credential, message).catch(() => {
|
|
94
93
|
throw new Unsettled(UNREACHABLE);
|
|
95
94
|
});
|
|
@@ -120,7 +119,7 @@ function opened(url, method, headers, body) {
|
|
|
120
119
|
const local = socketPath !== undefined;
|
|
121
120
|
const target = local ? null : relayed(url);
|
|
122
121
|
if (!local)
|
|
123
|
-
|
|
122
|
+
proxyUnlessRelayed();
|
|
124
123
|
const sent = target === null
|
|
125
124
|
? request({ socketPath, path: url, method, headers }, answered)
|
|
126
125
|
: (target.protocol === 'https:' ? httpsRequest : request)(target, { method, headers }, answered);
|
|
@@ -131,8 +130,19 @@ function opened(url, method, headers, body) {
|
|
|
131
130
|
pipeline(body, sent).catch(() => undefined);
|
|
132
131
|
});
|
|
133
132
|
}
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
function ranged(file, start, end) {
|
|
134
|
+
return end === start ? undefined : createReadStream(file, { start, end: end - 1 });
|
|
135
|
+
}
|
|
136
|
+
async function* read(file, start, end) {
|
|
137
|
+
try {
|
|
138
|
+
yield* ranged(file, start, end) ?? [];
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw unreadable(file, error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function sentPart(url, file, start, end, headers) {
|
|
145
|
+
const answer = await opened(url, 'PUT', { ...headers, 'content-length': String(end - start) }, ranged(file, start, end));
|
|
136
146
|
await answer.toArray();
|
|
137
147
|
if (answer.statusCode !== 200)
|
|
138
148
|
throw storeRefusal('upload', answer.statusCode);
|
|
@@ -171,10 +181,10 @@ async function described(file) {
|
|
|
171
181
|
const mediaType = MEDIA_TYPES.get(extname(file).slice(1).toLowerCase());
|
|
172
182
|
return { bytes, sha256: digest.digest('hex'), ...(mediaType === undefined ? {} : { media_type: mediaType }) };
|
|
173
183
|
}
|
|
174
|
-
async function finished(upload, room) {
|
|
175
|
-
const text = await called('upload', { upload, room_ref: room });
|
|
184
|
+
async function finished(upload, room, partSha256) {
|
|
185
|
+
const text = await called('upload', { upload, room_ref: room, part_sha256: partSha256 });
|
|
176
186
|
const answer = parse(text);
|
|
177
|
-
return answer !== null &&
|
|
187
|
+
return answer !== null && 'upload' in answer ? answer : { text };
|
|
178
188
|
}
|
|
179
189
|
async function upload({ file, ...destination }) {
|
|
180
190
|
if (typeof file !== 'string' || file === '')
|
|
@@ -185,9 +195,12 @@ async function upload({ file, ...destination }) {
|
|
|
185
195
|
if (declared?.upload === undefined)
|
|
186
196
|
return answer;
|
|
187
197
|
const accepted = await uploaded(declared.upload, {
|
|
198
|
+
name: file,
|
|
188
199
|
bytes: description.bytes,
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
sha256: description.sha256,
|
|
201
|
+
read: (start, end) => read(file, start, end),
|
|
202
|
+
send: (url, start, end, headers) => sentPart(url, file, start, end, headers),
|
|
203
|
+
finish: (id, partSha256) => finished(id, destination.room_ref, partSha256),
|
|
191
204
|
});
|
|
192
205
|
return accepted.text;
|
|
193
206
|
}
|
package/dist/house-main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const [major = 0, minor = 0] = process.versions.node.split('.').map(Number);
|
|
3
|
-
if (major < 24 || (major === 24 && minor <
|
|
4
|
-
process.stderr.write(`house: the Kit needs Node 24.
|
|
2
|
+
const [major = 0, minor = 0, patch = 0] = process.versions.node.split('.').map(Number);
|
|
3
|
+
if (major < 24 || (major === 24 && (minor < 22 || (minor === 22 && patch < 1)))) {
|
|
4
|
+
process.stderr.write(`house: the Kit needs Node 24.22.1 or newer; this is ${process.versions.node}\n`);
|
|
5
5
|
process.exitCode = 1;
|
|
6
6
|
}
|
|
7
7
|
else {
|
package/dist/kit-cli.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { setGlobalProxyFromEnv } from 'node:http';
|
|
2
1
|
import { parseArgs } from 'node:util';
|
|
3
2
|
import { answerGitCredential } from './app-git.js';
|
|
4
3
|
import { chatgpt } from './chatgpt.js';
|
|
5
4
|
import { login } from './login.js';
|
|
6
5
|
import { logout } from './logout.js';
|
|
6
|
+
import { proxyUnlessRelayed } from './relay.js';
|
|
7
7
|
import { resident } from './resident.js';
|
|
8
8
|
const USAGE = 'usage: kit <login|logout|resident|chatgpt>\n';
|
|
9
9
|
const COMMANDS = new Map([
|
|
@@ -36,7 +36,7 @@ const COMMANDS = new Map([
|
|
|
36
36
|
],
|
|
37
37
|
]);
|
|
38
38
|
const [command, ...argv] = process.argv.slice(2);
|
|
39
|
-
|
|
39
|
+
proxyUnlessRelayed();
|
|
40
40
|
async function run() {
|
|
41
41
|
if (command === 'login')
|
|
42
42
|
return login(argv);
|
package/dist/kit-main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const [major = 0, minor = 0] = process.versions.node.split('.').map(Number);
|
|
3
|
-
if (major < 24 || (major === 24 && minor <
|
|
4
|
-
process.stderr.write(`kit: the Kit needs Node 24.
|
|
2
|
+
const [major = 0, minor = 0, patch = 0] = process.versions.node.split('.').map(Number);
|
|
3
|
+
if (major < 24 || (major === 24 && (minor < 22 || (minor === 22 && patch < 1)))) {
|
|
4
|
+
process.stderr.write(`kit: the Kit needs Node 24.22.1 or newer; this is ${process.versions.node}\n`);
|
|
5
5
|
process.exitCode = 1;
|
|
6
6
|
}
|
|
7
7
|
else {
|
package/dist/relay.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { setGlobalProxyFromEnv } from 'node:http';
|
|
2
|
+
const PROXY = /^https?_proxy$/i;
|
|
3
|
+
const LOOPBACK = ['127.0.0.1', 'localhost', '::1'];
|
|
1
4
|
let selected;
|
|
5
|
+
let restoreProxy;
|
|
2
6
|
export function selectRelay(relay) {
|
|
3
7
|
selected = relay === undefined || relay === '' ? null : relay;
|
|
8
|
+
proxyUnlessRelayed();
|
|
4
9
|
}
|
|
5
10
|
export function relayOrigin() {
|
|
6
11
|
if (selected !== undefined)
|
|
@@ -8,6 +13,22 @@ export function relayOrigin() {
|
|
|
8
13
|
const ambient = process.env.HOUSE_KIT_RELAY;
|
|
9
14
|
return ambient === undefined || ambient === '' ? undefined : ambient;
|
|
10
15
|
}
|
|
16
|
+
function unlessRelayed() {
|
|
17
|
+
if (relayOrigin() === undefined)
|
|
18
|
+
return { ...process.env };
|
|
19
|
+
return Object.fromEntries(Object.entries(process.env).filter(([name]) => !PROXY.test(name)));
|
|
20
|
+
}
|
|
21
|
+
export function proxyUnlessRelayed() {
|
|
22
|
+
restoreProxy?.();
|
|
23
|
+
restoreProxy = setGlobalProxyFromEnv(unlessRelayed());
|
|
24
|
+
}
|
|
25
|
+
export function childEnvironment() {
|
|
26
|
+
const environment = unlessRelayed();
|
|
27
|
+
if (!Object.keys(environment).some((name) => PROXY.test(name)))
|
|
28
|
+
return environment;
|
|
29
|
+
const bypassed = [environment.NO_PROXY ?? environment.no_proxy, ...LOOPBACK].filter((entry) => entry !== undefined && entry !== '').join(',');
|
|
30
|
+
return { ...environment, NO_PROXY: bypassed, no_proxy: bypassed };
|
|
31
|
+
}
|
|
11
32
|
export function relayed(target) {
|
|
12
33
|
const url = new URL(target);
|
|
13
34
|
const relay = relayOrigin();
|
package/dist/sign-in.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { createInterface } from 'node:readline';
|
|
3
|
-
import { CLIS
|
|
3
|
+
import { CLIS } from './clis.js';
|
|
4
|
+
import { childEnvironment } from './relay.js';
|
|
4
5
|
import { killTree } from './scope.js';
|
|
5
6
|
import { holdSecretInput } from './secret-input.js';
|
|
6
7
|
const ESCAPE = /\u001b\[[\d;]*m/g;
|
|
@@ -56,7 +57,7 @@ export class SignIns {
|
|
|
56
57
|
const child = spawn(cli, login.args, {
|
|
57
58
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
58
59
|
detached: true,
|
|
59
|
-
env:
|
|
60
|
+
env: childEnvironment(),
|
|
60
61
|
});
|
|
61
62
|
const running = () => child.exitCode === null && child.signalCode === null;
|
|
62
63
|
const stop = () => killTree(child);
|
package/dist/transcription.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { createReadStream } from 'node:fs';
|
|
3
1
|
import { chmod, mkdir, mkdtemp, readdir, readFile, rename, rm, stat } from 'node:fs/promises';
|
|
4
2
|
import { availableParallelism, tmpdir } from 'node:os';
|
|
5
3
|
import { basename, join } from 'node:path';
|
|
6
|
-
import { pipeline } from 'node:stream/promises';
|
|
7
4
|
import { unlessAborted } from './abort.js';
|
|
5
|
+
import { downloadServed } from './building.js';
|
|
8
6
|
import { failureOf, run } from './clis.js';
|
|
9
7
|
import { downloaded, fetched } from './files.js';
|
|
10
8
|
import { kitHome } from './home.js';
|
|
11
9
|
const RELEASE = 'https://github.com/agentshouse/kit/releases/download/engine-2';
|
|
12
10
|
export const MODEL = {
|
|
13
|
-
|
|
11
|
+
name: 'ggml-parakeet-tdt-0.6b-v3-q4_k.bin',
|
|
12
|
+
from: 'https://huggingface.co/ggml-org/parakeet-GGUF/resolve/35156454d1a39de06863303dd209fd2bed6ee079/ggml-parakeet-tdt-0.6b-v3-q4_k.bin',
|
|
14
13
|
sha256: '8b205b8b39c6535e153de6fb11c51db46125d45c4f16ba496fe41a0fe71b885e',
|
|
14
|
+
bytes: 415_611_879,
|
|
15
15
|
executable: false,
|
|
16
16
|
};
|
|
17
17
|
export const ENGINES = {
|
|
18
18
|
'linux-x64': {
|
|
19
|
-
decoder: {
|
|
20
|
-
engine: {
|
|
19
|
+
decoder: { name: 'ffmpeg-linux-x86_64', from: `${RELEASE}/ffmpeg-linux-x86_64`, sha256: '1f8235d206428305afb89c6e8ab99d100425a0ba61e22bb4c7aff017db8c8de5', bytes: 5_175_832, executable: true },
|
|
20
|
+
engine: { name: 'parakeet-cli-linux-x86_64', from: `${RELEASE}/parakeet-cli-linux-x86_64`, sha256: 'bb2585695992fe1927a33960002cdf51b8a90a96ad65593c3d0a9f1fbc0865c2', bytes: 3_801_616, executable: true },
|
|
21
21
|
},
|
|
22
22
|
'linux-arm64': {
|
|
23
|
-
decoder: {
|
|
24
|
-
engine: {
|
|
23
|
+
decoder: { name: 'ffmpeg-linux-aarch64', from: `${RELEASE}/ffmpeg-linux-aarch64`, sha256: 'a7e08a0fae0179d1078312f6bb13d2a9aa4d4c71a1d82a022953f25dee452f5e', bytes: 4_590_208, executable: true },
|
|
24
|
+
engine: { name: 'parakeet-cli-linux-aarch64', from: `${RELEASE}/parakeet-cli-linux-aarch64`, sha256: 'cbc0bedc8daae97f1ef9dcee4200c06226218e300e0fd62ead1306d22742b7ed', bytes: 3_477_624, executable: true },
|
|
25
25
|
},
|
|
26
26
|
'darwin-arm64': {
|
|
27
|
-
decoder: {
|
|
28
|
-
engine: {
|
|
27
|
+
decoder: { name: 'ffmpeg-darwin-arm64', from: `${RELEASE}/ffmpeg-darwin-arm64`, sha256: '7abe154aaed3d6b49f5167ca7221bb66bed51388925d99a7e4261a41fe52fba6', bytes: 3_696_768, executable: true },
|
|
28
|
+
engine: { name: 'parakeet-cli-darwin-arm64', from: `${RELEASE}/parakeet-cli-darwin-arm64`, sha256: '9a2aafc0922ad7c0b6db6eff1641e96572ba32ac40bf995a1df242ed2febf297', bytes: 1_939_728, executable: true },
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
31
|
const CHUNK_SECONDS = 20;
|
|
@@ -46,7 +46,7 @@ function installed(artifact) {
|
|
|
46
46
|
return join(directory(), artifact.sha256);
|
|
47
47
|
}
|
|
48
48
|
async function executed(command, args, signal) {
|
|
49
|
-
// A
|
|
49
|
+
// A decode or a transcription runs as long as its audio needs; the setting turning off or the turn's interrupt or end aborts it instead.
|
|
50
50
|
const ran = await run(command, args, 0, false, signal);
|
|
51
51
|
if (ran.status !== 0)
|
|
52
52
|
throw new Error(failureOf(ran, basename(command)));
|
|
@@ -60,11 +60,6 @@ async function threads() {
|
|
|
60
60
|
const allowed = quota === 'max' ? Infinity : Math.ceil(Number(quota) / Number(period));
|
|
61
61
|
return Math.max(1, Math.floor(Math.min(availableParallelism(), allowed) / 2));
|
|
62
62
|
}
|
|
63
|
-
async function sha256(path) {
|
|
64
|
-
const hash = createHash('sha256');
|
|
65
|
-
await pipeline(createReadStream(path), hash);
|
|
66
|
-
return hash.digest('hex');
|
|
67
|
-
}
|
|
68
63
|
function causeOf(error) {
|
|
69
64
|
return error instanceof Error ? error.message : String(error);
|
|
70
65
|
}
|
|
@@ -85,6 +80,25 @@ function ready() {
|
|
|
85
80
|
function pinnedHere() {
|
|
86
81
|
return ENGINES[`${process.platform}-${process.arch}`];
|
|
87
82
|
}
|
|
83
|
+
const DOWNLOADS = 3;
|
|
84
|
+
async function downloadedAgain(artifact, signal) {
|
|
85
|
+
// An artifact arrives at a hundred kilobytes a second or its download ends, so a stalled Building cannot hold the install open.
|
|
86
|
+
const deadlineMs = Math.ceil(artifact.bytes / 100);
|
|
87
|
+
const deadline = AbortSignal.timeout(deadlineMs);
|
|
88
|
+
for (let attempt = 1;; attempt++) {
|
|
89
|
+
try {
|
|
90
|
+
return await downloadServed(artifact.name, artifact.sha256, `${installed(artifact)}.part`, AbortSignal.any([signal, deadline]), artifact.bytes);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (signal.aborted)
|
|
94
|
+
throw error;
|
|
95
|
+
if (deadline.aborted)
|
|
96
|
+
throw new Error(`${artifact.name} did not arrive within ${Math.ceil(deadlineMs / 1000)} seconds`);
|
|
97
|
+
if (attempt === DOWNLOADS)
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
88
102
|
async function install(artifacts, signal) {
|
|
89
103
|
await mkdir(directory(), { recursive: true });
|
|
90
104
|
const pinned = new Set(artifacts.map((artifact) => artifact.sha256));
|
|
@@ -97,13 +111,8 @@ async function install(artifacts, signal) {
|
|
|
97
111
|
if (!(await present(installed(artifact))))
|
|
98
112
|
missing.push(artifact);
|
|
99
113
|
try {
|
|
100
|
-
for (const artifact of missing)
|
|
101
|
-
|
|
102
|
-
// Three retries carry a large download past a dropped connection before the download fails.
|
|
103
|
-
await executed('curl', ['-fsSL', '--retry', '3', '-o', part, artifact.url], signal);
|
|
104
|
-
if ((await sha256(part)) !== artifact.sha256)
|
|
105
|
-
throw new Error(`${artifact.url} does not match its sha256`);
|
|
106
|
-
}
|
|
114
|
+
for (const artifact of missing)
|
|
115
|
+
await downloadedAgain(artifact, signal);
|
|
107
116
|
for (const artifact of missing) {
|
|
108
117
|
if (artifact.executable)
|
|
109
118
|
await chmod(`${installed(artifact)}.part`, 0o755);
|
package/dist/update.js
CHANGED
|
@@ -6,6 +6,10 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { run } from './clis.js';
|
|
7
7
|
import { kitHome, workspaceRoot } from './home.js';
|
|
8
8
|
import { service, throughSudo } from './placement.js';
|
|
9
|
+
import { relayed } from './relay.js';
|
|
10
|
+
const BOOTSTRAP_BYTES = 1_000_000;
|
|
11
|
+
// A bootstrap is at most a million bytes, so two minutes carry it over ten kilobytes a second and no stalled host holds the update queue.
|
|
12
|
+
const BOOTSTRAP_MS = 120_000;
|
|
9
13
|
function directory() {
|
|
10
14
|
return join(kitHome(), 'update');
|
|
11
15
|
}
|
|
@@ -66,6 +70,17 @@ async function finished(callId) {
|
|
|
66
70
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
67
71
|
}
|
|
68
72
|
}
|
|
73
|
+
async function bounded(body, most) {
|
|
74
|
+
const chunks = [];
|
|
75
|
+
let bytes = 0;
|
|
76
|
+
for await (const chunk of body ?? []) {
|
|
77
|
+
bytes += chunk.length;
|
|
78
|
+
if (bytes > most)
|
|
79
|
+
return null;
|
|
80
|
+
chunks.push(chunk);
|
|
81
|
+
}
|
|
82
|
+
return Buffer.concat(chunks, bytes);
|
|
83
|
+
}
|
|
69
84
|
function rerun(script, callId, flags) {
|
|
70
85
|
return new Promise((resolve) => {
|
|
71
86
|
const [command, ...args] = [
|
|
@@ -119,10 +134,21 @@ export class KitUpdate {
|
|
|
119
134
|
async carry(call) {
|
|
120
135
|
if ((await pendingCall()) === call.input_id)
|
|
121
136
|
return finished(call.input_id);
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
const deadline = AbortSignal.timeout(BOOTSTRAP_MS);
|
|
138
|
+
let script;
|
|
139
|
+
try {
|
|
140
|
+
const answer = await fetch(relayed(call.bootstrap), { signal: deadline });
|
|
141
|
+
if (!answer.ok)
|
|
142
|
+
return { refused: `the Kit bootstrap could not be downloaded: ${answer.status}` };
|
|
143
|
+
script = await bounded(answer.body, BOOTSTRAP_BYTES);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (!deadline.aborted)
|
|
147
|
+
throw error;
|
|
148
|
+
return { refused: `the Kit bootstrap did not arrive within ${BOOTSTRAP_MS / 1000} seconds` };
|
|
149
|
+
}
|
|
150
|
+
if (script === null)
|
|
151
|
+
return { refused: `the Kit bootstrap is larger than ${BOOTSTRAP_BYTES} bytes` };
|
|
126
152
|
if (createHash('sha256').update(script).digest('hex') !== call.sha256) {
|
|
127
153
|
return { refused: 'the Kit bootstrap does not match its sha256' };
|
|
128
154
|
}
|
package/dist/web-wizard.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { loginPath, onLoginPath
|
|
1
|
+
import { loginPath, onLoginPath } from './clis.js';
|
|
2
|
+
import { childEnvironment } from './relay.js';
|
|
2
3
|
import { killTree } from './scope.js';
|
|
3
4
|
const TERMINAL = 'xterm-256color';
|
|
4
5
|
const SIGNALLED = 128;
|
|
@@ -62,7 +63,7 @@ export class WebWizards {
|
|
|
62
63
|
name: TERMINAL,
|
|
63
64
|
...run.size,
|
|
64
65
|
cwd: process.cwd(),
|
|
65
|
-
env: { ...
|
|
66
|
+
env: { ...childEnvironment(), PATH: path },
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentshouse/kit",
|
|
3
|
-
"version": "0.2.1-
|
|
3
|
+
"version": "0.2.1-c44c14117631a",
|
|
4
4
|
"description": "Kit connects an Environment to agents.house.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,28 +12,27 @@
|
|
|
12
12
|
"kit": "dist/kit-main.js",
|
|
13
13
|
"house": "dist/house-main.js"
|
|
14
14
|
},
|
|
15
|
-
"exports": {
|
|
16
|
-
"./bootstrap": "./dist/bootstrap.json"
|
|
17
|
-
},
|
|
18
15
|
"files": [
|
|
19
16
|
"dist"
|
|
20
17
|
],
|
|
21
18
|
"scripts": {
|
|
22
|
-
"
|
|
19
|
+
"bootstrap-manifest": "node scripts/bootstrap-manifest.mjs",
|
|
20
|
+
"build": "tsc -p tsconfig.build.json",
|
|
23
21
|
"engine": "mkdir -p tmp/engine && docker run --rm -v \"$PWD:/kit\" -w /kit alpine:3.24@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6 sh scripts/engine.sh tmp/engine",
|
|
24
22
|
"follow-skills": "node scripts/follow-skills.mjs",
|
|
23
|
+
"release-files": "node scripts/release-files.mjs",
|
|
25
24
|
"test": "tsc -p tsconfig.json && vitest run"
|
|
26
25
|
},
|
|
27
26
|
"dependencies": {
|
|
28
|
-
"@agentclientprotocol/sdk": "
|
|
29
|
-
"@agentshouse/mdmodel": "0.1.0-
|
|
30
|
-
"@agentshouse/skills": "0.1.0-
|
|
27
|
+
"@agentclientprotocol/sdk": "2.0.1",
|
|
28
|
+
"@agentshouse/mdmodel": "0.1.0-c4f4d37bc9d6a",
|
|
29
|
+
"@agentshouse/skills": "0.1.0-ccce31cfa5fec",
|
|
31
30
|
"@lydell/node-pty": "1.2.0-beta.15",
|
|
32
31
|
"yaml": "2.9.1"
|
|
33
32
|
},
|
|
34
33
|
"peerDependencies": {
|
|
35
|
-
"@agentclientprotocol/claude-agent-acp": "0.
|
|
36
|
-
"@agentclientprotocol/codex-acp": "2.
|
|
34
|
+
"@agentclientprotocol/claude-agent-acp": "0.94.0",
|
|
35
|
+
"@agentclientprotocol/codex-acp": "2.2.2"
|
|
37
36
|
},
|
|
38
37
|
"peerDependenciesMeta": {
|
|
39
38
|
"@agentclientprotocol/claude-agent-acp": {
|
|
@@ -44,26 +43,26 @@
|
|
|
44
43
|
}
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
|
-
"@types/node": "24.
|
|
46
|
+
"@types/node": "24.19.2",
|
|
48
47
|
"@types/ws": "8.18.2",
|
|
49
48
|
"typescript": "7.0.2",
|
|
50
|
-
"vitest": "5.0.
|
|
49
|
+
"vitest": "5.0.5",
|
|
51
50
|
"ws": "8.22.0"
|
|
52
51
|
},
|
|
53
|
-
"packageManager": "npm@11.19.
|
|
52
|
+
"packageManager": "npm@11.19.1",
|
|
54
53
|
"engines": {
|
|
55
|
-
"node": "24.
|
|
56
|
-
"npm": "11.19.
|
|
54
|
+
"node": "24.22.1",
|
|
55
|
+
"npm": "11.19.1"
|
|
57
56
|
},
|
|
58
57
|
"devEngines": {
|
|
59
58
|
"runtime": {
|
|
60
59
|
"name": "node",
|
|
61
|
-
"version": "24.
|
|
60
|
+
"version": "24.22.1",
|
|
62
61
|
"onFail": "error"
|
|
63
62
|
},
|
|
64
63
|
"packageManager": {
|
|
65
64
|
"name": "npm",
|
|
66
|
-
"version": "11.19.
|
|
65
|
+
"version": "11.19.1",
|
|
67
66
|
"onFail": "error"
|
|
68
67
|
}
|
|
69
68
|
}
|
package/dist/bootstrap.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 2,
|
|
3
|
-
"version": "0.2.1-c441d29eb63f4",
|
|
4
|
-
"hosts": {
|
|
5
|
-
"macos": {
|
|
6
|
-
"asset": {
|
|
7
|
-
"name": "connect-linux.sh",
|
|
8
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c441d29eb63f4/connect-linux.sh"
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
"linux": {
|
|
12
|
-
"asset": {
|
|
13
|
-
"name": "connect-linux.sh",
|
|
14
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c441d29eb63f4/connect-linux.sh"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"windows": {
|
|
18
|
-
"asset": {
|
|
19
|
-
"name": "connect-windows.ps1",
|
|
20
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-c441d29eb63f4/connect-windows.ps1"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|