@agentshouse/kit 0.2.1-c3fc787e93f0e → 0.2.1-c441d29eb63f4
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 +30 -29
- package/dist/acp.js +36 -16
- package/dist/agents.js +87 -19
- package/dist/api.js +5 -5
- package/dist/app-git.js +10 -26
- package/dist/bootstrap.json +4 -4
- package/dist/bridge.js +3 -6
- package/dist/calls.js +63 -0
- package/dist/chatgpt.js +7 -1
- package/dist/clis.js +17 -4
- package/dist/connection.js +126 -0
- package/dist/conversations.js +399 -153
- package/dist/copies.js +77 -50
- package/dist/end.js +9 -4
- package/dist/events.js +6 -2
- package/dist/files.js +123 -37
- package/dist/git.js +3 -4
- package/dist/home.js +31 -13
- package/dist/house-cli.js +286 -0
- package/dist/house-main.js +7 -262
- package/dist/instructions.js +6 -10
- package/dist/kit-cli.js +68 -0
- package/dist/kit-main.js +8 -67
- package/dist/login.js +34 -11
- package/dist/logout.js +0 -2
- package/dist/mcp.js +4 -2
- package/dist/placement.js +9 -18
- package/dist/resident.js +88 -37
- package/dist/scope.js +3 -0
- package/dist/service.js +23 -1
- package/dist/sign-in.js +19 -37
- package/dist/skills.js +12 -34
- package/dist/transcription.js +53 -22
- package/dist/translate.js +2 -8
- package/dist/update.js +42 -45
- package/dist/web-wizard.js +100 -0
- package/dist/wire.js +19 -3
- package/dist/work.js +3 -5
- package/package.json +7 -6
- package/dist/stream.js +0 -77
- package/how-we-work.md +0 -23
- package/skills/ask-matt/LICENSE +0 -21
- package/skills/ask-matt/PHASE-BOUNDARIES.md +0 -55
- package/skills/ask-matt/SKILL.md +0 -91
- package/skills/ask-matt/agents/openai.yaml +0 -4
- package/skills/code-review/LICENSE +0 -21
- package/skills/code-review/SKILL.md +0 -89
- package/skills/code-review/agents/openai.yaml +0 -3
- package/skills/codebase-design/DEEPENING.md +0 -37
- package/skills/codebase-design/DESIGN-IT-TWICE.md +0 -44
- package/skills/codebase-design/LICENSE +0 -21
- package/skills/codebase-design/SKILL.md +0 -116
- package/skills/codebase-design/agents/openai.yaml +0 -3
- package/skills/diagnosing-bugs/LICENSE +0 -21
- package/skills/diagnosing-bugs/SKILL.md +0 -140
- package/skills/diagnosing-bugs/agents/openai.yaml +0 -3
- package/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -44
- package/skills/domain-modeling/ADR-FORMAT.md +0 -47
- package/skills/domain-modeling/CONTEXT-FORMAT.md +0 -60
- package/skills/domain-modeling/LICENSE +0 -21
- package/skills/domain-modeling/SKILL.md +0 -76
- package/skills/domain-modeling/agents/openai.yaml +0 -3
- package/skills/grill-me/LICENSE +0 -21
- package/skills/grill-me/SKILL.md +0 -8
- package/skills/grill-me/agents/openai.yaml +0 -4
- package/skills/grill-with-docs/LICENSE +0 -21
- package/skills/grill-with-docs/SKILL.md +0 -8
- package/skills/grill-with-docs/agents/openai.yaml +0 -4
- package/skills/grilling/LICENSE +0 -21
- package/skills/grilling/SKILL.md +0 -30
- package/skills/grilling/agents/openai.yaml +0 -3
- package/skills/handoff/LICENSE +0 -21
- package/skills/handoff/SKILL.md +0 -17
- package/skills/handoff/agents/openai.yaml +0 -4
- package/skills/implement/LICENSE +0 -21
- package/skills/implement/SKILL.md +0 -16
- package/skills/implement/agents/openai.yaml +0 -4
- package/skills/improve-codebase-architecture/HTML-REPORT.md +0 -123
- package/skills/improve-codebase-architecture/LICENSE +0 -21
- package/skills/improve-codebase-architecture/SKILL.md +0 -72
- package/skills/improve-codebase-architecture/agents/openai.yaml +0 -4
- package/skills/prototype/LICENSE +0 -21
- package/skills/prototype/LOGIC.md +0 -67
- package/skills/prototype/SKILL.md +0 -28
- package/skills/prototype/UI.md +0 -112
- package/skills/prototype/agents/openai.yaml +0 -3
- package/skills/research/LICENSE +0 -21
- package/skills/research/SKILL.md +0 -14
- package/skills/research/agents/openai.yaml +0 -3
- package/skills/resolving-merge-conflicts/LICENSE +0 -21
- package/skills/resolving-merge-conflicts/SKILL.md +0 -16
- package/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/skills/tdd/LICENSE +0 -21
- package/skills/tdd/SKILL.md +0 -40
- package/skills/tdd/agents/openai.yaml +0 -3
- package/skills/tdd/mocking.md +0 -59
- package/skills/tdd/tests.md +0 -77
- package/skills/teach/GLOSSARY-FORMAT.md +0 -35
- package/skills/teach/LEARNING-RECORD-FORMAT.md +0 -46
- package/skills/teach/LICENSE +0 -21
- package/skills/teach/MISSION-FORMAT.md +0 -31
- package/skills/teach/RESOURCES-FORMAT.md +0 -32
- package/skills/teach/SKILL.md +0 -141
- package/skills/teach/agents/openai.yaml +0 -4
- package/skills/to-questionnaire/LICENSE +0 -21
- package/skills/to-questionnaire/SKILL.md +0 -55
- package/skills/to-questionnaire/agents/openai.yaml +0 -4
- package/skills/to-spec/LICENSE +0 -21
- package/skills/to-spec/SKILL.md +0 -76
- package/skills/to-spec/agents/openai.yaml +0 -4
- package/skills/to-tickets/LICENSE +0 -21
- package/skills/to-tickets/SKILL.md +0 -106
- package/skills/to-tickets/agents/openai.yaml +0 -4
- package/skills/wait-what/LICENSE +0 -21
- package/skills/wait-what/SKILL.md +0 -8
- package/skills/wait-what/agents/openai.yaml +0 -4
- package/skills/wayfinder/LICENSE +0 -21
- package/skills/wayfinder/SKILL.md +0 -129
- package/skills/wayfinder/agents/openai.yaml +0 -4
- package/skills/writing-for-agents/LICENSE +0 -21
- package/skills/writing-for-agents/SKILL-MECHANICS.md +0 -22
- package/skills/writing-for-agents/SKILL.md +0 -83
- package/skills/writing-for-agents/agents/openai.yaml +0 -3
package/dist/chatgpt.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseArgs } from 'node:util';
|
|
2
|
+
import { placeAppGit } from './app-git.js';
|
|
2
3
|
import { kitHome, readOwnAgent, writeOwnAgent } from './home.js';
|
|
3
4
|
import { accepted, DEFAULT_HOUSE } from './login.js';
|
|
4
5
|
const KEY_SOURCE = 'New key for a script on Connections';
|
|
@@ -17,10 +18,15 @@ export async function chatgpt(argv) {
|
|
|
17
18
|
}
|
|
18
19
|
if (values.key === undefined)
|
|
19
20
|
throw new Error(`pass --key with a key from ${KEY_SOURCE}`);
|
|
20
|
-
const
|
|
21
|
+
const before = await readOwnAgent();
|
|
22
|
+
const house = values.house ?? before?.house ?? DEFAULT_HOUSE;
|
|
21
23
|
if (!(await accepted(house, values.key)))
|
|
22
24
|
throw new Error(`${house} does not accept this key; pass one from ${KEY_SOURCE}`);
|
|
23
25
|
const relay = process.env.HOUSE_KIT_RELAY || undefined;
|
|
24
26
|
await writeOwnAgent({ house, ...(relay === undefined ? {} : { relay }), credential: values.key });
|
|
27
|
+
await placeAppGit(await readOwnAgent()).catch((error) => process.stderr.write(`kit: ${error.message}\n`));
|
|
28
|
+
if (before !== null && before.credential !== values.key) {
|
|
29
|
+
process.stdout.write('This replaced the key this Kit home held; give each session its own HOUSE_KIT_HOME to keep its own key.\n');
|
|
30
|
+
}
|
|
25
31
|
process.stdout.write(`house now calls ${house} as you, with the key kept in ${kitHome()}.\n`);
|
|
26
32
|
}
|
package/dist/clis.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import { constants, readFileSync } from 'node:fs';
|
|
3
4
|
import { access, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
4
5
|
import { homedir, userInfo } from 'node:os';
|
|
@@ -54,11 +55,14 @@ export async function allowHouseInCodex(path) {
|
|
|
54
55
|
houses.push(house);
|
|
55
56
|
}
|
|
56
57
|
await mkdir(rules, { recursive: true });
|
|
57
|
-
const temporary = `${file}.${
|
|
58
|
+
const temporary = `${file}.${randomUUID()}`;
|
|
58
59
|
await writeFile(temporary, houseRule(houses));
|
|
59
60
|
await rename(temporary, file);
|
|
60
61
|
}
|
|
61
62
|
async function nothing() { }
|
|
63
|
+
function answered(error) {
|
|
64
|
+
return typeof error === 'object' && error !== null ? error : {};
|
|
65
|
+
}
|
|
62
66
|
function bridgeInClaudeSandbox(bridge) {
|
|
63
67
|
return process.platform === 'darwin' ? { allowUnixSockets: [bridge] } : { allowAllUnixSockets: true };
|
|
64
68
|
}
|
|
@@ -76,6 +80,10 @@ export const CLIS = {
|
|
|
76
80
|
args: [],
|
|
77
81
|
fullAccess: 'agent-full-access',
|
|
78
82
|
sessionMeta: () => ({}),
|
|
83
|
+
unknownSession: (error) => {
|
|
84
|
+
const { code, data } = answered(error);
|
|
85
|
+
return code === -32603 && typeof data?.details === 'string' && data.details.startsWith('no rollout found');
|
|
86
|
+
},
|
|
79
87
|
renames: true,
|
|
80
88
|
allowHouse: allowHouseInCodex,
|
|
81
89
|
signedIn: { command: ['login', 'status'] },
|
|
@@ -105,6 +113,7 @@ export const CLIS = {
|
|
|
105
113
|
emitRawSDKMessages: RAW_SUBTYPES.map((subtype) => ({ type: 'system', subtype })),
|
|
106
114
|
},
|
|
107
115
|
}),
|
|
116
|
+
unknownSession: (error) => answered(error).code === -32002,
|
|
108
117
|
renames: false,
|
|
109
118
|
allowHouse: nothing,
|
|
110
119
|
signedIn: { command: ['auth', 'status'] },
|
|
@@ -119,6 +128,7 @@ export const CLIS = {
|
|
|
119
128
|
args: ['--sandbox', 'off', 'agent', '--always-approve', '--no-leader', 'stdio'],
|
|
120
129
|
fullAccess: null,
|
|
121
130
|
sessionMeta: () => ({}),
|
|
131
|
+
unknownSession: (error) => answered(error).data?.code === 'FS_NOT_FOUND',
|
|
122
132
|
renames: false,
|
|
123
133
|
allowHouse: nothing,
|
|
124
134
|
signedIn: { initializeMeta: 'defaultAuthMethodId' },
|
|
@@ -127,7 +137,7 @@ export const CLIS = {
|
|
|
127
137
|
},
|
|
128
138
|
};
|
|
129
139
|
const KIT_PACKAGE = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
130
|
-
export const
|
|
140
|
+
export const KIT_RELEASE = KIT_PACKAGE.version;
|
|
131
141
|
const PROXY = /^https?_proxy$/i;
|
|
132
142
|
const VERSION = /\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?/;
|
|
133
143
|
// An install still running after fifteen minutes is ended and reported as failed, so a hung download cannot hold its CLI's report.
|
|
@@ -215,10 +225,13 @@ const USER_BIN = 'case ":$PATH:" in *":$HOME/.local/bin:"*) ;; *) PATH="$PATH:$H
|
|
|
215
225
|
function inLoginShell(script, argument = '', signal) {
|
|
216
226
|
return run(loginShell(), ['-l', '-i', '-c', `exec /bin/sh -c '${USER_BIN}; ${script}' sh ${argument}`], READ_MS, true, signal);
|
|
217
227
|
}
|
|
218
|
-
export async function
|
|
219
|
-
const ran = await inLoginShell(LOOKUP,
|
|
228
|
+
export async function onLoginPath(program, signal) {
|
|
229
|
+
const ran = await inLoginShell(LOOKUP, program, signal);
|
|
220
230
|
return ran.stdout.split('\n').findLast((line) => line.startsWith(FOUND))?.slice(FOUND.length) ?? null;
|
|
221
231
|
}
|
|
232
|
+
export function locate(kind, signal) {
|
|
233
|
+
return onLoginPath(CLIS[kind].bin, signal);
|
|
234
|
+
}
|
|
222
235
|
export async function loginPath() {
|
|
223
236
|
const marker = 'house-kit-path ';
|
|
224
237
|
const ran = await inLoginShell(`printf "${marker}%s\\n" "$PATH"`);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { subscribe } from 'node:diagnostics_channel';
|
|
2
|
+
import { HouseRefusal, retryDelay } from './api.js';
|
|
3
|
+
import { end, REPLACED, signInAgain } from './end.js';
|
|
4
|
+
import { readEnrolment } from './home.js';
|
|
5
|
+
import { relayed } from './relay.js';
|
|
6
|
+
import { endUnserved, KIT_WIRE } from './wire.js';
|
|
7
|
+
const PATH = '/kit/stream';
|
|
8
|
+
const SUBPROTOCOL = `house.kit.stream.${KIT_WIRE}`;
|
|
9
|
+
const REFUSAL_HEADER = 'x-house-refusal';
|
|
10
|
+
// House beats each Kit connection every thirty seconds, so two silent beats mean this Kit process cannot hear House.
|
|
11
|
+
export const CONNECTION_SILENCE_MS = 60_000;
|
|
12
|
+
const SYSTEM_CONNECTION_CLOCK = {
|
|
13
|
+
later: (delay, callback) => setTimeout(callback, delay),
|
|
14
|
+
clear: (timer) => clearTimeout(timer),
|
|
15
|
+
};
|
|
16
|
+
export class ConnectionSilence {
|
|
17
|
+
timer = null;
|
|
18
|
+
silent;
|
|
19
|
+
clock;
|
|
20
|
+
interval;
|
|
21
|
+
constructor(silent, clock = SYSTEM_CONNECTION_CLOCK, interval = CONNECTION_SILENCE_MS) {
|
|
22
|
+
this.silent = silent;
|
|
23
|
+
this.clock = clock;
|
|
24
|
+
this.interval = interval;
|
|
25
|
+
}
|
|
26
|
+
heard() {
|
|
27
|
+
this.stop();
|
|
28
|
+
this.timer = this.clock.later(this.interval, () => {
|
|
29
|
+
this.timer = null;
|
|
30
|
+
this.silent();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
stop() {
|
|
34
|
+
if (this.timer === null)
|
|
35
|
+
return;
|
|
36
|
+
this.clock.clear(this.timer);
|
|
37
|
+
this.timer = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function connectionUrl(house) {
|
|
41
|
+
const url = new URL(PATH, house);
|
|
42
|
+
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
43
|
+
return url;
|
|
44
|
+
}
|
|
45
|
+
function header(headers, name) {
|
|
46
|
+
for (let index = 0; index < headers.length; index += 2) {
|
|
47
|
+
if (headers[index].toString('latin1').toLowerCase() === name)
|
|
48
|
+
return headers[index + 1].toString('latin1');
|
|
49
|
+
}
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
let refused = null;
|
|
53
|
+
subscribe('undici:request:headers', (message) => {
|
|
54
|
+
const { request, response } = message;
|
|
55
|
+
if (!request.path.endsWith(PATH))
|
|
56
|
+
return;
|
|
57
|
+
refused = new HouseRefusal(PATH, response.statusCode, header(response.headers, REFUSAL_HEADER) || response.statusText);
|
|
58
|
+
});
|
|
59
|
+
export function holdConnection(handlers) {
|
|
60
|
+
let connection = null;
|
|
61
|
+
let failures = 0;
|
|
62
|
+
const connect = async () => {
|
|
63
|
+
const { house, credential } = (await readEnrolment());
|
|
64
|
+
refused = null;
|
|
65
|
+
const opening = new WebSocket(relayed(connectionUrl(house)), {
|
|
66
|
+
protocols: [SUBPROTOCOL],
|
|
67
|
+
headers: { authorization: `Bearer ${credential}` },
|
|
68
|
+
});
|
|
69
|
+
let opened = false;
|
|
70
|
+
let silence = null;
|
|
71
|
+
const closed = (event) => {
|
|
72
|
+
silence?.stop();
|
|
73
|
+
silence = null;
|
|
74
|
+
if (connection === opening)
|
|
75
|
+
connection = null;
|
|
76
|
+
handlers.closed();
|
|
77
|
+
process.stderr.write(`kit: connection closed ${event.code} ${event.reason}\n`);
|
|
78
|
+
if (event.reason === 'replaced')
|
|
79
|
+
end(REPLACED);
|
|
80
|
+
if (event.reason === 'credential_rejected' || refused?.status === 401) {
|
|
81
|
+
void signInAgain(credential);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (refused !== null)
|
|
85
|
+
endUnserved(refused.text);
|
|
86
|
+
if (!opened && refused !== null)
|
|
87
|
+
process.stderr.write(`kit: ${refused.message}\n`);
|
|
88
|
+
// A closed connection reopens in one to three seconds, spread so Kit processes one restart closed return apart; an opening House refused or left unanswered backs off on the jittered curve, retryable or not, since a resident outlives a House deploy.
|
|
89
|
+
setTimeout(() => void connect(), opened ? 1000 + Math.random() * 2000 : retryDelay(failures++));
|
|
90
|
+
};
|
|
91
|
+
opening.onopen = () => {
|
|
92
|
+
opened = true;
|
|
93
|
+
failures = 0;
|
|
94
|
+
connection = opening;
|
|
95
|
+
silence = new ConnectionSilence(() => {
|
|
96
|
+
if (connection !== opening)
|
|
97
|
+
return;
|
|
98
|
+
connection = null;
|
|
99
|
+
opening.onclose = null;
|
|
100
|
+
opening.close();
|
|
101
|
+
closed(new CloseEvent('close', { code: 1006, reason: 'heartbeat_missed' }));
|
|
102
|
+
});
|
|
103
|
+
silence.heard();
|
|
104
|
+
handlers.opened();
|
|
105
|
+
};
|
|
106
|
+
opening.onmessage = (event) => {
|
|
107
|
+
silence?.heard();
|
|
108
|
+
const arrived = JSON.parse(String(event.data));
|
|
109
|
+
if (arrived.type === 'input')
|
|
110
|
+
handlers.call(arrived);
|
|
111
|
+
else if (arrived.type !== 'beat')
|
|
112
|
+
handlers.notification(arrived);
|
|
113
|
+
};
|
|
114
|
+
opening.onerror = () => undefined;
|
|
115
|
+
opening.onclose = closed;
|
|
116
|
+
};
|
|
117
|
+
void connect();
|
|
118
|
+
return {
|
|
119
|
+
send(notification) {
|
|
120
|
+
if (connection === null || connection.readyState !== WebSocket.OPEN)
|
|
121
|
+
return false;
|
|
122
|
+
connection.send(JSON.stringify(notification));
|
|
123
|
+
return true;
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|