@agentshouse/kit 0.2.1-cb6679d048e60 → 0.2.1-cb997daca91ed
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 +42 -41
- package/dist/acp.js +50 -106
- package/dist/agents.js +180 -51
- package/dist/api.js +36 -3
- package/dist/app-git.js +48 -0
- package/dist/authority-main.js +2 -2
- package/dist/bridge.js +40 -59
- package/dist/building.js +46 -0
- package/dist/calls.js +63 -0
- package/dist/chatgpt.js +32 -0
- package/dist/clis-main.js +2 -2
- package/dist/clis.js +171 -76
- package/dist/codex-main.js +58 -0
- package/dist/connection.js +143 -0
- package/dist/conversations.js +625 -323
- package/dist/copies.js +205 -150
- package/dist/end.js +27 -0
- package/dist/enrol-main.js +7 -1
- package/dist/events.js +525 -0
- package/dist/files.js +140 -17
- package/dist/git.js +13 -11
- package/dist/home.js +96 -7
- package/dist/house-cli.js +299 -0
- package/dist/house-main.js +7 -159
- package/dist/instructions.js +8 -10
- package/dist/kit-cli.js +68 -0
- package/dist/kit-main.js +8 -19
- package/dist/login.js +117 -104
- package/dist/logout.js +14 -13
- package/dist/mcp.js +6 -3
- package/dist/parts.js +82 -0
- package/dist/placement.js +39 -0
- package/dist/refusals.js +12 -0
- package/dist/relay.js +41 -0
- package/dist/resident.js +116 -51
- package/dist/scope.js +206 -0
- package/dist/secret-input.js +4 -1
- package/dist/service-main.js +9 -0
- package/dist/service.js +55 -0
- package/dist/shell.js +3 -0
- package/dist/sign-in.js +40 -32
- package/dist/skills.js +49 -35
- package/dist/transcription.js +129 -41
- package/dist/translate.js +2 -8
- package/dist/update.js +112 -53
- package/dist/web-wizard.js +101 -0
- package/dist/wire.js +22 -0
- package/dist/work.js +346 -0
- package/package.json +20 -20
- package/dist/blocks.js +0 -51
- package/dist/bootstrap.json +0 -24
- package/dist/stream.js +0 -46
- 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/bridge.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'node:crypto';
|
|
2
2
|
import { once } from 'node:events';
|
|
3
3
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
|
-
import { mkdir } from 'node:fs/promises';
|
|
5
4
|
import { createServer, request as httpRequest } from 'node:http';
|
|
6
5
|
import { request as httpsRequest } from 'node:https';
|
|
7
6
|
import { delimiter, dirname, join } from 'node:path';
|
|
8
7
|
import { parse } from 'yaml';
|
|
9
|
-
import { HouseRefusal, retryDelay } from './api.js';
|
|
8
|
+
import { finalRefusal, HouseRefusal, retryDelay, retrying } from './api.js';
|
|
10
9
|
import { loginPath } from './clis.js';
|
|
11
10
|
import { changedPaths, } from './copies.js';
|
|
12
|
-
import { kitHome, readEnrolment } from './home.js';
|
|
11
|
+
import { kitHome, readEnrolment, socketDirectory } from './home.js';
|
|
13
12
|
import { callHouse, mcpBody, rpc, UNREACHABLE } from './mcp.js';
|
|
14
|
-
import { operationId
|
|
15
|
-
import { refusalOf } from './refusals.js';
|
|
16
|
-
|
|
17
|
-
const
|
|
13
|
+
import { operationId } from './operation.js';
|
|
14
|
+
import { refusalOf, retryable } from './refusals.js';
|
|
15
|
+
import { relayed } from './relay.js';
|
|
16
|
+
const MCP_REQUEST_BYTES = 4_000_000;
|
|
18
17
|
export async function received(request) {
|
|
19
18
|
let text = '';
|
|
20
19
|
request.setEncoding('utf8');
|
|
@@ -22,7 +21,8 @@ export async function received(request) {
|
|
|
22
21
|
text += chunk;
|
|
23
22
|
return text;
|
|
24
23
|
}
|
|
25
|
-
function relay(request, response,
|
|
24
|
+
function relay(request, response, house, authorization) {
|
|
25
|
+
const target = relayed(house);
|
|
26
26
|
const send = target.protocol === 'https:' ? httpsRequest : httpRequest;
|
|
27
27
|
const forwarded = send(target, {
|
|
28
28
|
method: request.method,
|
|
@@ -38,8 +38,6 @@ function refusalIn(text, status) {
|
|
|
38
38
|
return refusalOf(text) ?? { code: '', text: text === '' ? `House refused it with ${status}` : text, conflicts: [] };
|
|
39
39
|
}
|
|
40
40
|
function answered(forwarded) {
|
|
41
|
-
if (forwarded.status >= 500)
|
|
42
|
-
throw new HouseRefusal('/', forwarded.status, forwarded.text);
|
|
43
41
|
if (forwarded.status !== 200)
|
|
44
42
|
return { refused: refusalIn(forwarded.text, forwarded.status) };
|
|
45
43
|
const answer = JSON.parse(forwarded.text);
|
|
@@ -63,16 +61,11 @@ function pendingSeconds(forwarded) {
|
|
|
63
61
|
function resendAfter(forwarded, attempt) {
|
|
64
62
|
if (forwarded === null)
|
|
65
63
|
return retryDelay(attempt);
|
|
66
|
-
if (forwarded.status
|
|
67
|
-
return
|
|
64
|
+
if (forwarded.status !== 200)
|
|
65
|
+
return retryable(forwarded.text) === false ? null : retryDelay(attempt);
|
|
68
66
|
const seconds = pendingSeconds(forwarded);
|
|
69
67
|
return seconds === null ? null : seconds * 1000;
|
|
70
68
|
}
|
|
71
|
-
function versioned(conversationId, text) {
|
|
72
|
-
const file = JSON.parse(text);
|
|
73
|
-
const identity = JSON.stringify([conversationId, file.room_ref ?? null, file.name, file.sha256]);
|
|
74
|
-
return JSON.stringify({ ...file, version: uuidOf(createHash('sha256').update(identity).digest(), 8) });
|
|
75
|
-
}
|
|
76
69
|
function editAnswer(forwarded) {
|
|
77
70
|
const answer = answered(forwarded);
|
|
78
71
|
if ('refused' in answer)
|
|
@@ -88,7 +81,7 @@ function editAnswer(forwarded) {
|
|
|
88
81
|
export async function openBridge(house, copies, conversationId, signal) {
|
|
89
82
|
const path = [join(kitHome(), 'shim'), dirname(process.execPath), await loginPath()].join(delimiter);
|
|
90
83
|
const origin = (await readEnrolment()).house;
|
|
91
|
-
const { credential } = await house.post(`/kit/conversations/${conversationId}/credential`, {}, signal);
|
|
84
|
+
const { credential } = await retrying(() => house.post(`/kit/conversations/${conversationId}/credential`, {}, signal), signal);
|
|
92
85
|
const closed = new AbortController();
|
|
93
86
|
const sent = (message, operation) => callHouse(origin, credential, message, operation, closed.signal);
|
|
94
87
|
const send = async (message, operation) => {
|
|
@@ -103,6 +96,7 @@ export async function openBridge(house, copies, conversationId, signal) {
|
|
|
103
96
|
const after = resendAfter(forwarded, attempt);
|
|
104
97
|
if (after === null)
|
|
105
98
|
return forwarded;
|
|
99
|
+
// A Tool call House did not settle is sent again on the jittered curve, or after the wait House names for a pending one.
|
|
106
100
|
await delay(after, undefined, { signal: closed.signal });
|
|
107
101
|
}
|
|
108
102
|
};
|
|
@@ -117,46 +111,32 @@ export async function openBridge(house, copies, conversationId, signal) {
|
|
|
117
111
|
if ('refused' in prepared)
|
|
118
112
|
return prepared;
|
|
119
113
|
const { transfer } = parse(prepared.text);
|
|
120
|
-
|
|
121
|
-
method: 'POST',
|
|
122
|
-
headers: { 'content-type': 'text/plain; charset=utf-8' },
|
|
123
|
-
body: Buffer.concat([Buffer.from(`${transfer.operation}\n`), bytes]),
|
|
124
|
-
signal: closed.signal,
|
|
125
|
-
});
|
|
126
|
-
const text = await posted.text();
|
|
127
|
-
if (posted.status >= 500)
|
|
128
|
-
throw new HouseRefusal('/', posted.status, text);
|
|
129
|
-
if (!posted.ok)
|
|
130
|
-
return { refused: refusalIn(text, posted.status) };
|
|
131
|
-
const held = JSON.parse(text).transfer;
|
|
132
|
-
return { url: held.url, operation: held.operation, bytes: bytes.length, sha256 };
|
|
133
|
-
};
|
|
134
|
-
let mutations = null;
|
|
135
|
-
const writes = async (tool) => {
|
|
136
|
-
mutations ??= house
|
|
137
|
-
.post('/kit/tools/mutations', {}, closed.signal)
|
|
138
|
-
.then(({ tools }) => new Set(tools.filter((listed) => listed.writes).map((listed) => listed.name)));
|
|
114
|
+
let text;
|
|
139
115
|
try {
|
|
140
|
-
|
|
116
|
+
text = await retrying(async () => {
|
|
117
|
+
const posted = await fetch(relayed(transfer.url), {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
headers: { 'content-type': 'text/plain; charset=utf-8' },
|
|
120
|
+
body: Buffer.concat([Buffer.from(`${transfer.operation}\n`), bytes]),
|
|
121
|
+
signal: closed.signal,
|
|
122
|
+
});
|
|
123
|
+
const answer = await posted.text();
|
|
124
|
+
if (!posted.ok)
|
|
125
|
+
throw new HouseRefusal('/', posted.status, answer);
|
|
126
|
+
return answer;
|
|
127
|
+
}, closed.signal);
|
|
141
128
|
}
|
|
142
129
|
catch (error) {
|
|
143
|
-
|
|
144
|
-
|
|
130
|
+
if (!finalRefusal(error))
|
|
131
|
+
throw error;
|
|
132
|
+
return { refused: refusalIn(error.text, error.status) };
|
|
145
133
|
}
|
|
134
|
+
const held = JSON.parse(text).transfer;
|
|
135
|
+
return { url: held.url, operation: held.operation, bytes: bytes.length, sha256 };
|
|
146
136
|
};
|
|
147
|
-
const forward =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const tool = message.method === 'tools/call' ? String(message.params.name) : null;
|
|
151
|
-
return send(message, tool !== null && (await writes(tool)) ? operationId() : null);
|
|
152
|
-
}
|
|
153
|
-
const answer = await fetch(new URL(path, origin), {
|
|
154
|
-
method: 'POST',
|
|
155
|
-
headers: { 'content-type': 'application/json', authorization: `Bearer ${credential}` },
|
|
156
|
-
body: versioned(conversationId, text),
|
|
157
|
-
signal: closed.signal,
|
|
158
|
-
});
|
|
159
|
-
return { status: answer.status, text: await answer.text() };
|
|
137
|
+
const forward = (text) => {
|
|
138
|
+
const message = JSON.parse(text);
|
|
139
|
+
return send(message, message.method === 'tools/call' ? operationId() : null);
|
|
160
140
|
};
|
|
161
141
|
const caller = {
|
|
162
142
|
key: `conversation:${conversationId}`,
|
|
@@ -178,15 +158,15 @@ export async function openBridge(house, copies, conversationId, signal) {
|
|
|
178
158
|
const { cwd, commit } = JSON.parse(text);
|
|
179
159
|
return { status: 200, text: JSON.stringify(await copies.push(cwd, commit, caller)) };
|
|
180
160
|
}
|
|
161
|
+
if (path === '/git/fetch')
|
|
162
|
+
return { status: 200, text: JSON.stringify(await copies.fetch()) };
|
|
181
163
|
if (path === '/git/observed') {
|
|
182
164
|
await copies.observed(JSON.parse(text));
|
|
183
165
|
return { status: 200, text: '{}' };
|
|
184
166
|
}
|
|
185
|
-
return path === '/'
|
|
167
|
+
return path === '/' ? forward(text) : { status: 404, text: '' };
|
|
186
168
|
};
|
|
187
|
-
const
|
|
188
|
-
await mkdir(sockets, { recursive: true, mode: 0o700 });
|
|
189
|
-
const socketPath = join(sockets, `${randomUUID()}.sock`);
|
|
169
|
+
const socketPath = join(socketDirectory(), `${randomUUID()}.sock`);
|
|
190
170
|
const bridge = createServer(async (request, response) => {
|
|
191
171
|
try {
|
|
192
172
|
const path = request.url ?? '';
|
|
@@ -202,7 +182,8 @@ export async function openBridge(house, copies, conversationId, signal) {
|
|
|
202
182
|
response.writeHead(error.status, { 'content-type': 'application/json' }).end(error.text);
|
|
203
183
|
return;
|
|
204
184
|
}
|
|
205
|
-
|
|
185
|
+
const verb = request.url === '/git/push' || request.url === '/git/fetch';
|
|
186
|
+
response.writeHead(502).end(verb && error instanceof Error ? error.message : UNREACHABLE);
|
|
206
187
|
}
|
|
207
188
|
});
|
|
208
189
|
bridge.listen(socketPath);
|
|
@@ -229,7 +210,7 @@ export async function openBridge(house, copies, conversationId, signal) {
|
|
|
229
210
|
GIT_CONFIG_VALUE_0: app,
|
|
230
211
|
},
|
|
231
212
|
tool: async (name, args) => {
|
|
232
|
-
const forwarded = await forward(
|
|
213
|
+
const forwarded = await forward(JSON.stringify(call(name, args)));
|
|
233
214
|
if (forwarded.status !== 200)
|
|
234
215
|
throw new Error(`House refused ${name} with ${forwarded.status}: ${forwarded.text}`);
|
|
235
216
|
const answer = JSON.parse(forwarded.text);
|
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/calls.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { kitHome } from './home.js';
|
|
4
|
+
function logged(error) {
|
|
5
|
+
process.stderr.write(`kit: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
6
|
+
}
|
|
7
|
+
export class Calls {
|
|
8
|
+
house;
|
|
9
|
+
changed;
|
|
10
|
+
carried = new Map();
|
|
11
|
+
path = join(kitHome(), 'call-results.json');
|
|
12
|
+
results;
|
|
13
|
+
returned = new Set();
|
|
14
|
+
open = 0;
|
|
15
|
+
constructor(house, changed) {
|
|
16
|
+
this.house = house;
|
|
17
|
+
this.changed = changed;
|
|
18
|
+
this.results = new Map(existsSync(this.path) ? Object.entries(JSON.parse(readFileSync(this.path, 'utf8'))) : []);
|
|
19
|
+
}
|
|
20
|
+
keepResult(callId, result) {
|
|
21
|
+
if (this.returned.has(callId))
|
|
22
|
+
return;
|
|
23
|
+
this.results.set(callId, result);
|
|
24
|
+
this.save();
|
|
25
|
+
}
|
|
26
|
+
idle() {
|
|
27
|
+
return this.open === 0;
|
|
28
|
+
}
|
|
29
|
+
carry(callId, work) {
|
|
30
|
+
const known = this.carried.get(callId);
|
|
31
|
+
const result = this.results.get(callId);
|
|
32
|
+
const carried = known ?? (result === undefined ? work() : Promise.resolve({ result }));
|
|
33
|
+
if (known === undefined) {
|
|
34
|
+
this.carried.set(callId, carried);
|
|
35
|
+
carried.catch(() => this.carried.delete(callId));
|
|
36
|
+
}
|
|
37
|
+
this.open++;
|
|
38
|
+
this.changed();
|
|
39
|
+
return carried
|
|
40
|
+
.then(async ({ result, returned }) => {
|
|
41
|
+
try {
|
|
42
|
+
await this.house.deliver(`/kit/inputs/${callId}/ack`, result);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
this.returned.add(callId);
|
|
46
|
+
if (this.results.delete(callId))
|
|
47
|
+
this.save();
|
|
48
|
+
}
|
|
49
|
+
if (known === undefined)
|
|
50
|
+
await returned?.();
|
|
51
|
+
})
|
|
52
|
+
.catch(logged)
|
|
53
|
+
.finally(() => {
|
|
54
|
+
this.open--;
|
|
55
|
+
this.changed();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
save() {
|
|
59
|
+
const temporary = `${this.path}.${process.pid}`;
|
|
60
|
+
writeFileSync(temporary, JSON.stringify(Object.fromEntries(this.results)), { mode: 0o600 });
|
|
61
|
+
renameSync(temporary, this.path);
|
|
62
|
+
}
|
|
63
|
+
}
|
package/dist/chatgpt.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { placeAppGit } from './app-git.js';
|
|
3
|
+
import { kitHome, readOwnAgent, writeOwnAgent } from './home.js';
|
|
4
|
+
import { accepted, DEFAULT_HOUSE } from './login.js';
|
|
5
|
+
const KEY_SOURCE = 'New key for a script on Connections';
|
|
6
|
+
const USAGE = `usage: kit chatgpt --key <key> [--house <origin>]
|
|
7
|
+
--key <key> a key from ${KEY_SOURCE}
|
|
8
|
+
--house <origin> the House of the key, ${DEFAULT_HOUSE} unless one is stored
|
|
9
|
+
`;
|
|
10
|
+
export async function chatgpt(argv) {
|
|
11
|
+
const { values } = parseArgs({
|
|
12
|
+
args: argv,
|
|
13
|
+
options: { key: { type: 'string' }, house: { type: 'string' }, help: { type: 'boolean', default: false } },
|
|
14
|
+
});
|
|
15
|
+
if (values.help) {
|
|
16
|
+
process.stdout.write(USAGE);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (values.key === undefined)
|
|
20
|
+
throw new Error(`pass --key with a key from ${KEY_SOURCE}`);
|
|
21
|
+
const before = await readOwnAgent();
|
|
22
|
+
const house = values.house ?? before?.house ?? DEFAULT_HOUSE;
|
|
23
|
+
if (!(await accepted(house, values.key)))
|
|
24
|
+
throw new Error(`${house} does not accept this key; pass one from ${KEY_SOURCE}`);
|
|
25
|
+
const relay = process.env.HOUSE_KIT_RELAY || undefined;
|
|
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
|
+
}
|
|
31
|
+
process.stdout.write(`house now calls ${house} as you, with the key kept in ${kitHome()}.\n`);
|
|
32
|
+
}
|
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);
|