@agentshouse/kit 0.2.1-c64c31420c9bf → 0.2.1-c70284f7a7466
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 +5 -5
- package/dist/bootstrap.json +4 -4
- package/dist/clis.js +9 -0
- package/dist/conversations.js +49 -18
- package/dist/copies.js +34 -17
- package/dist/events.js +2 -1
- package/dist/instructions.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,11 +45,11 @@ longer act as you here; a later `kit login` reconnects the same Environment, or
|
|
|
45
45
|
this computer as a new one when House no longer holds it.
|
|
46
46
|
In a container you do not control, such as ChatGPT's, `npm i -g @agentshouse/kit` and `kit chatgpt --key <key>` with a key made on Connections let `house <tool>` act as you, starting and configuring nothing else.
|
|
47
47
|
|
|
48
|
-
`kit resident` keeps the Environment connected and, as it connects, copies the text of each Room
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`house push --owner` in the copy, through the install command in
|
|
52
|
-
both, without `--owner`. `house upload` and `house download` move a Room's other files.
|
|
48
|
+
`kit resident` keeps the Environment connected and, as it connects, copies the text of each Room you chose for it as a
|
|
49
|
+
Git repository in the workspace's `local-copies`, and erases a Room's copy, unpushed commits included, once the Room
|
|
50
|
+
may no longer be copied here. `house fetch` does the same and records House's changes on each copy's
|
|
51
|
+
`refs/house/received`; rebase onto it, commit and run `house push --owner` in the copy, through the install command in
|
|
52
|
+
the container. An Agent runs both, without `--owner`. `house upload` and `house download` move a Room's other files.
|
|
53
53
|
|
|
54
54
|
House Kit turns each audio file of your message to an Agent into text on this
|
|
55
55
|
computer before the Agent reads it. While transcription is on, the speech
|
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-c70284f7a7466",
|
|
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-c70284f7a7466/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-c70284f7a7466/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-c70284f7a7466/connect-windows.ps1"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
package/dist/clis.js
CHANGED
|
@@ -60,6 +60,9 @@ export async function allowHouseInCodex(path) {
|
|
|
60
60
|
await rename(temporary, file);
|
|
61
61
|
}
|
|
62
62
|
async function nothing() { }
|
|
63
|
+
function answered(error) {
|
|
64
|
+
return typeof error === 'object' && error !== null ? error : {};
|
|
65
|
+
}
|
|
63
66
|
function bridgeInClaudeSandbox(bridge) {
|
|
64
67
|
return process.platform === 'darwin' ? { allowUnixSockets: [bridge] } : { allowAllUnixSockets: true };
|
|
65
68
|
}
|
|
@@ -77,6 +80,10 @@ export const CLIS = {
|
|
|
77
80
|
args: [],
|
|
78
81
|
fullAccess: 'agent-full-access',
|
|
79
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
|
+
},
|
|
80
87
|
renames: true,
|
|
81
88
|
allowHouse: allowHouseInCodex,
|
|
82
89
|
signedIn: { command: ['login', 'status'] },
|
|
@@ -106,6 +113,7 @@ export const CLIS = {
|
|
|
106
113
|
emitRawSDKMessages: RAW_SUBTYPES.map((subtype) => ({ type: 'system', subtype })),
|
|
107
114
|
},
|
|
108
115
|
}),
|
|
116
|
+
unknownSession: (error) => answered(error).code === -32002,
|
|
109
117
|
renames: false,
|
|
110
118
|
allowHouse: nothing,
|
|
111
119
|
signedIn: { command: ['auth', 'status'] },
|
|
@@ -120,6 +128,7 @@ export const CLIS = {
|
|
|
120
128
|
args: ['--sandbox', 'off', 'agent', '--always-approve', '--no-leader', 'stdio'],
|
|
121
129
|
fullAccess: null,
|
|
122
130
|
sessionMeta: () => ({}),
|
|
131
|
+
unknownSession: (error) => answered(error).data?.code === 'FS_NOT_FOUND',
|
|
123
132
|
renames: false,
|
|
124
133
|
allowHouse: nothing,
|
|
125
134
|
signedIn: { initializeMeta: 'defaultAuthMethodId' },
|
package/dist/conversations.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { client, } from '@agentclientprotocol/sdk';
|
|
1
|
+
import { client, RequestError, } from '@agentclientprotocol/sdk';
|
|
2
2
|
import { createHash, randomUUID } from 'node:crypto';
|
|
3
3
|
import { mkdir } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
@@ -16,6 +16,7 @@ import { holdSecretInput } from './secret-input.js';
|
|
|
16
16
|
import { createHowWeWork } from './skills.js';
|
|
17
17
|
import { transcribe } from './transcription.js';
|
|
18
18
|
import { workFor } from './work.js';
|
|
19
|
+
const SIGNED_OUT = RequestError.authRequired().code;
|
|
19
20
|
const KILLED = 'the conversation was killed';
|
|
20
21
|
const REFUSED = 'the CLI refused the prompt';
|
|
21
22
|
const NO_CONNECTION = "the Kit could not open this conversation's connection";
|
|
@@ -45,6 +46,13 @@ export const CONVERSATION_INPUTS = new Set(['open', 'message', 'interrupt', 'kil
|
|
|
45
46
|
function causeOf(error) {
|
|
46
47
|
return error instanceof Error ? error.message : String(error);
|
|
47
48
|
}
|
|
49
|
+
function answeredWith(error) {
|
|
50
|
+
const signedOut = typeof error === 'object' && error !== null && error.code === SIGNED_OUT;
|
|
51
|
+
return { failure: signedOut ? 'signed_out' : 'error', cause: causeOf(error) };
|
|
52
|
+
}
|
|
53
|
+
function exitedWith(running, cause) {
|
|
54
|
+
return running.killed ? { failure: 'killed', cause: KILLED } : { failure: 'exited', cause };
|
|
55
|
+
}
|
|
48
56
|
function answerMessage(request, response) {
|
|
49
57
|
return `The User answered a question you asked earlier.\nQuestion: ${JSON.stringify(request)}\nAnswer: ${JSON.stringify(response)}`;
|
|
50
58
|
}
|
|
@@ -88,6 +96,7 @@ class Conversation {
|
|
|
88
96
|
subagents = new Map();
|
|
89
97
|
held = [];
|
|
90
98
|
opening = null;
|
|
99
|
+
prompted = null;
|
|
91
100
|
kills = 0;
|
|
92
101
|
killed = new AbortController();
|
|
93
102
|
interrupts = 0;
|
|
@@ -231,7 +240,7 @@ export class Conversations {
|
|
|
231
240
|
if (conversation.running !== null)
|
|
232
241
|
return {};
|
|
233
242
|
try {
|
|
234
|
-
return { provider_session_id: await this.start(conversation, await this.route(conversation, input.agent_id), null) };
|
|
243
|
+
return { provider_session_id: await this.start(conversation, await this.route(conversation, input.agent_id), null, true) };
|
|
235
244
|
}
|
|
236
245
|
catch (error) {
|
|
237
246
|
return { refused: refusal(conversation, error) };
|
|
@@ -274,13 +283,17 @@ export class Conversations {
|
|
|
274
283
|
async send(conversation, waiting) {
|
|
275
284
|
const { input } = waiting;
|
|
276
285
|
let ack = {};
|
|
286
|
+
let started = false;
|
|
277
287
|
const prompt = [];
|
|
278
288
|
try {
|
|
279
289
|
if (conversation.running === null) {
|
|
280
|
-
const
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
290
|
+
const stored = conversation.session ?? input.provider_session_id;
|
|
291
|
+
const empty = input.first === true && conversation.prompted !== stored;
|
|
292
|
+
started = (await this.start(conversation, waiting.route, stored, empty)) !== stored;
|
|
293
|
+
}
|
|
294
|
+
const session = conversation.running.sessionId;
|
|
295
|
+
if (started || (input.first === true && session !== input.provider_session_id)) {
|
|
296
|
+
ack = { provider_session_id: session };
|
|
284
297
|
}
|
|
285
298
|
if (input.first === true) {
|
|
286
299
|
prompt.push({
|
|
@@ -292,7 +305,7 @@ export class Conversations {
|
|
|
292
305
|
throw new Error(KILLED);
|
|
293
306
|
}
|
|
294
307
|
catch (error) {
|
|
295
|
-
if (
|
|
308
|
+
if (started) {
|
|
296
309
|
conversation.session = null;
|
|
297
310
|
await this.kill(conversation);
|
|
298
311
|
}
|
|
@@ -374,7 +387,7 @@ export class Conversations {
|
|
|
374
387
|
}
|
|
375
388
|
return route;
|
|
376
389
|
}
|
|
377
|
-
async start(conversation, route, sessionId) {
|
|
390
|
+
async start(conversation, route, sessionId, empty) {
|
|
378
391
|
const reader = readerFor(route.kind);
|
|
379
392
|
reader.session = sessionId;
|
|
380
393
|
const app = client({ name: '@agentshouse/kit' })
|
|
@@ -402,11 +415,10 @@ export class Conversations {
|
|
|
402
415
|
const agent = adapter.connection.agent;
|
|
403
416
|
const cwd = route.working_directory;
|
|
404
417
|
const _meta = CLIS[route.kind].sessionMeta(bridge.env.HOUSE_BRIDGE, conversation.id);
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
: { ...(await step(NO_RESUME, agent.request('session/resume', { sessionId, cwd, mcpServers: [], _meta }))), sessionId };
|
|
418
|
+
const resumed = sessionId === null ? null : await this.resume(conversation, route.kind, adapter, { sessionId, cwd, mcpServers: [], _meta }, empty);
|
|
419
|
+
const opened = resumed ?? (await step(NO_SESSION, agent.request('session/new', { cwd, mcpServers: [], _meta })));
|
|
408
420
|
reader.session = opened.sessionId;
|
|
409
|
-
if (sessionId
|
|
421
|
+
if (opened.sessionId !== sessionId && CLIS[route.kind].renames) {
|
|
410
422
|
const prompt = [{ type: 'text', text: `/rename ${conversation.id}` }];
|
|
411
423
|
await step(NO_SESSION, agent.request('session/prompt', { sessionId: opened.sessionId, prompt }));
|
|
412
424
|
}
|
|
@@ -433,6 +445,18 @@ export class Conversations {
|
|
|
433
445
|
conversation.opening = null;
|
|
434
446
|
}
|
|
435
447
|
}
|
|
448
|
+
async resume(conversation, kind, adapter, request, empty) {
|
|
449
|
+
try {
|
|
450
|
+
return { ...(await adapter.connection.agent.request('session/resume', request)), sessionId: request.sessionId };
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
if (!empty || conversation.kills > 0 || !CLIS[kind].unknownSession(error)) {
|
|
454
|
+
throw new NotStarted(NO_RESUME, { cause: error });
|
|
455
|
+
}
|
|
456
|
+
logged(new Error(`conversation ${conversation.id} opens a new session: ${NO_RESUME}: ${causeOf(error)}`));
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
436
460
|
async launchSettings(running, route, offered) {
|
|
437
461
|
let options = offered;
|
|
438
462
|
const settings = [
|
|
@@ -460,7 +484,7 @@ export class Conversations {
|
|
|
460
484
|
return;
|
|
461
485
|
this.detach(conversation, running);
|
|
462
486
|
if (conversation.turn !== null) {
|
|
463
|
-
this.end(conversation, conversation.turn,
|
|
487
|
+
this.end(conversation, conversation.turn, exitedWith(running, cause));
|
|
464
488
|
}
|
|
465
489
|
this.next(conversation);
|
|
466
490
|
this.kit.changed();
|
|
@@ -527,6 +551,8 @@ export class Conversations {
|
|
|
527
551
|
end(conversation, turn, failed, notice = null) {
|
|
528
552
|
if (turn.ended)
|
|
529
553
|
return;
|
|
554
|
+
if (failed !== null)
|
|
555
|
+
logged(new Error(`conversation ${conversation.id} turn ${turn.id} failed: ${failed.cause}`));
|
|
530
556
|
if (conversation.turn === turn) {
|
|
531
557
|
for (const event of conversation.running?.reader.closeTurn() ?? [])
|
|
532
558
|
this.apply(conversation, turn, event);
|
|
@@ -540,7 +566,7 @@ export class Conversations {
|
|
|
540
566
|
const body = Promise.allSettled(turn.uploads).then(() => ({
|
|
541
567
|
parts: turn.parts.saved(),
|
|
542
568
|
context: turn.parts.context,
|
|
543
|
-
...failed,
|
|
569
|
+
...(failed === null ? {} : { failed: failed.failure }),
|
|
544
570
|
}));
|
|
545
571
|
void this.deliver(conversation, turn, 'ended', body).catch(logged);
|
|
546
572
|
this.next(conversation);
|
|
@@ -550,20 +576,25 @@ export class Conversations {
|
|
|
550
576
|
const running = conversation.running;
|
|
551
577
|
const turn = this.begin(conversation);
|
|
552
578
|
turn.prompted = true;
|
|
579
|
+
conversation.prompted = running.sessionId;
|
|
553
580
|
running.adapter.connection.agent.request('session/prompt', { sessionId: running.sessionId, prompt }).then((answer) => {
|
|
554
581
|
const notice = answeredFailure(answer);
|
|
555
|
-
|
|
556
|
-
|
|
582
|
+
if (notice !== null) {
|
|
583
|
+
this.end(conversation, turn, { failure: notice.limit ? 'limit' : 'error', cause: notice.title }, notice.title);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
this.end(conversation, turn, answer.stopReason === 'refusal' ? { failure: 'refused', cause: REFUSED } : null);
|
|
587
|
+
}
|
|
557
588
|
}, async (error) => {
|
|
558
589
|
if (running.adapter.connection.signal.aborted) {
|
|
559
|
-
this.end(conversation, turn,
|
|
590
|
+
this.end(conversation, turn, exitedWith(running, await running.adapter.exited));
|
|
560
591
|
}
|
|
561
592
|
else {
|
|
562
593
|
if (conversation.open === 1 && conversation.running === running) {
|
|
563
594
|
running.scope.kill();
|
|
564
595
|
this.detach(conversation, running);
|
|
565
596
|
}
|
|
566
|
-
this.end(conversation, turn,
|
|
597
|
+
this.end(conversation, turn, answeredWith(error));
|
|
567
598
|
}
|
|
568
599
|
});
|
|
569
600
|
}
|
package/dist/copies.js
CHANGED
|
@@ -36,6 +36,9 @@ function textOnly(paths) {
|
|
|
36
36
|
const [named, them] = paths.length === 1 ? [`${paths[0]} is`, 'it'] : [`${paths.join(', ')} are`, 'them'];
|
|
37
37
|
return `${named} not text, and house push sends text only; remove ${them} from the commit and place ${them} with house upload`;
|
|
38
38
|
}
|
|
39
|
+
function outside(path) {
|
|
40
|
+
return { refused: true, text: `${path} is not a House Local copy; run house push inside one` };
|
|
41
|
+
}
|
|
39
42
|
function short(commit) {
|
|
40
43
|
return commit.slice(0, 12);
|
|
41
44
|
}
|
|
@@ -63,6 +66,9 @@ function sidecar(path) {
|
|
|
63
66
|
segments.splice(-1, 0, PROVENANCE);
|
|
64
67
|
return segments.join('/');
|
|
65
68
|
}
|
|
69
|
+
function recordOf(key) {
|
|
70
|
+
return join(kitHome(), 'local-copies', `${key}.json`);
|
|
71
|
+
}
|
|
66
72
|
function rootOf(handle) {
|
|
67
73
|
return `/rooms/${handle}`;
|
|
68
74
|
}
|
|
@@ -209,7 +215,7 @@ export class LocalCopies {
|
|
|
209
215
|
async mapping() {
|
|
210
216
|
await this.answering;
|
|
211
217
|
return [...this.copies.values()]
|
|
212
|
-
.filter((copy) => copy.
|
|
218
|
+
.filter((copy) => copy.erasing === undefined)
|
|
213
219
|
.map((copy) => `${rootOf(copy.room_handle)}: ${copy.repository}`)
|
|
214
220
|
.sort();
|
|
215
221
|
}
|
|
@@ -232,25 +238,30 @@ export class LocalCopies {
|
|
|
232
238
|
return this.holding([...new Set([...this.copies.keys(), ...synced.keys()])].sort(), async () => {
|
|
233
239
|
const said = [];
|
|
234
240
|
let refused = false;
|
|
235
|
-
for (const copy of this.copies.values()) {
|
|
236
|
-
|
|
241
|
+
for (const copy of [...this.copies.values()]) {
|
|
242
|
+
const returned = synced.has(copy.key);
|
|
243
|
+
if (returned && copy.erasing === undefined)
|
|
237
244
|
continue;
|
|
238
|
-
|
|
239
|
-
|
|
245
|
+
try {
|
|
246
|
+
await this.erase(copy);
|
|
247
|
+
said.push(`${rootOf(copy.room_handle)}: ${returned ? '' : 'no longer synced to this Environment; '}erased from the Local copy`);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
refused = true;
|
|
251
|
+
said.push(`${rootOf(copy.room_handle)}: ${causeOf(error)}`);
|
|
252
|
+
}
|
|
240
253
|
}
|
|
241
254
|
const current = [];
|
|
242
255
|
for (const [key, handle] of synced) {
|
|
243
256
|
try {
|
|
244
257
|
const held = this.copies.get(key);
|
|
258
|
+
if (held?.erasing)
|
|
259
|
+
continue;
|
|
245
260
|
if (held === undefined || !(await exists(held.repository))) {
|
|
246
261
|
said.push(await this.materialize(key, handle));
|
|
247
262
|
continue;
|
|
248
263
|
}
|
|
249
|
-
|
|
250
|
-
if (copy.active)
|
|
251
|
-
current.push(copy);
|
|
252
|
-
else
|
|
253
|
-
said.push(...moved(copy, await this.save(await this.received({ ...copy, active: true }))));
|
|
264
|
+
current.push(held.room_handle === handle ? held : await this.save({ ...held, room_handle: handle }));
|
|
254
265
|
}
|
|
255
266
|
catch (error) {
|
|
256
267
|
refused = true;
|
|
@@ -276,6 +287,8 @@ export class LocalCopies {
|
|
|
276
287
|
return;
|
|
277
288
|
await this.exclusive(key, async () => {
|
|
278
289
|
const copy = this.copies.get(key);
|
|
290
|
+
if (copy === undefined || copy.erasing)
|
|
291
|
+
return;
|
|
279
292
|
let moves = copy.moves;
|
|
280
293
|
for (const { from, to } of report.moves) {
|
|
281
294
|
const held = moves.find((move) => move.worktree === report.worktree && move.to === from);
|
|
@@ -298,11 +311,11 @@ export class LocalCopies {
|
|
|
298
311
|
async push(cwd, selector, caller) {
|
|
299
312
|
const located = await run(cwd, ['rev-parse', '--path-format=absolute', '--git-common-dir', '--show-toplevel']);
|
|
300
313
|
if (located.status !== 0)
|
|
301
|
-
return
|
|
314
|
+
return outside(cwd);
|
|
302
315
|
const [common, worktree] = located.stdout.toString('utf8').split('\n');
|
|
303
316
|
const key = await this.keyAt(dirname(common));
|
|
304
317
|
if (key === undefined)
|
|
305
|
-
return
|
|
318
|
+
return outside(worktree);
|
|
306
319
|
return this.exclusive(key, () => this.pushed(key, worktree, selector, caller));
|
|
307
320
|
}
|
|
308
321
|
async keyAt(repository) {
|
|
@@ -323,7 +336,7 @@ export class LocalCopies {
|
|
|
323
336
|
return key === undefined ? work() : this.exclusive(key, () => this.holding(rest, work));
|
|
324
337
|
}
|
|
325
338
|
async save(copy) {
|
|
326
|
-
const path =
|
|
339
|
+
const path = recordOf(copy.key);
|
|
327
340
|
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
328
341
|
const temporary = `${path}.${process.pid}`;
|
|
329
342
|
await writeFile(temporary, JSON.stringify(copy), { mode: 0o600 });
|
|
@@ -331,6 +344,12 @@ export class LocalCopies {
|
|
|
331
344
|
this.copies.set(copy.key, copy);
|
|
332
345
|
return copy;
|
|
333
346
|
}
|
|
347
|
+
async erase(copy) {
|
|
348
|
+
await this.save({ ...copy, erasing: true });
|
|
349
|
+
await rm(copy.repository, { recursive: true, force: true });
|
|
350
|
+
await rm(recordOf(copy.key), { force: true });
|
|
351
|
+
this.copies.delete(copy.key);
|
|
352
|
+
}
|
|
334
353
|
async read(handle) {
|
|
335
354
|
const prefixes = [rootOf(handle)];
|
|
336
355
|
const discovery = await this.house.post('/kit/door/discover', { prefixes });
|
|
@@ -397,7 +416,6 @@ export class LocalCopies {
|
|
|
397
416
|
room_ref: read.anchor,
|
|
398
417
|
room_handle: handle,
|
|
399
418
|
repository,
|
|
400
|
-
active: true,
|
|
401
419
|
house,
|
|
402
420
|
position: read.position,
|
|
403
421
|
log_epoch: read.log_epoch,
|
|
@@ -526,6 +544,8 @@ export class LocalCopies {
|
|
|
526
544
|
}
|
|
527
545
|
async pushed(key, worktree, selector, caller) {
|
|
528
546
|
let copy = this.copies.get(key);
|
|
547
|
+
if (copy === undefined || copy.erasing)
|
|
548
|
+
return outside(worktree);
|
|
529
549
|
if (copy.push?.state === 'submitted')
|
|
530
550
|
return this.settle(copy, caller);
|
|
531
551
|
const selected = await run(worktree, ['rev-parse', '--verify', '--quiet', '--end-of-options', `${selector}^{commit}`]);
|
|
@@ -539,9 +559,6 @@ export class LocalCopies {
|
|
|
539
559
|
}
|
|
540
560
|
copy = await this.save(without(copy));
|
|
541
561
|
}
|
|
542
|
-
if (!copy.active) {
|
|
543
|
-
return { refused: true, text: `${rootOf(copy.room_handle)} is no longer synced to this Environment, so House takes no push from it` };
|
|
544
|
-
}
|
|
545
562
|
const listed = (await git(copy.repository, ['rev-list', '--topo-order', commit])).split('\n');
|
|
546
563
|
const base = listed.find((ancestor) => ancestor in copy.manifests);
|
|
547
564
|
if (base === undefined) {
|
package/dist/events.js
CHANGED
|
@@ -513,7 +513,8 @@ class GrokReader extends Reader {
|
|
|
513
513
|
}
|
|
514
514
|
}
|
|
515
515
|
export function answeredFailure(answer) {
|
|
516
|
-
|
|
516
|
+
const failure = answer._meta?.jetbrains?.air?.sessionFailure;
|
|
517
|
+
return typeof failure?.title === 'string' ? { title: failure.title, limit: failure.category === 'limit' } : null;
|
|
517
518
|
}
|
|
518
519
|
export function readerFor(kind) {
|
|
519
520
|
if (kind === 'claude-agent-acp')
|
package/dist/instructions.js
CHANGED
|
@@ -4,8 +4,9 @@ const SOURCE_LINE = "From House:";
|
|
|
4
4
|
const HOUSE_LINE = "Work with House through the `house` CLI: run `house --help`, and `house find_command` for House's guides and formats.";
|
|
5
5
|
const FILE_LINE = 'To give the User a file, upload it with `house upload` and link it; for an App, a Site or a website, follow `house find_command \'{"query":"app"}\'`. Never start a server.';
|
|
6
6
|
const READ_LINE = "Optional per-Room instructions: `/rooms/private/rooms/<handle>/AGENTS.md`.";
|
|
7
|
+
const WAIT_LINE = 'To get what another Agent will write into a Room, `create_trigger` on where it will land with a `conversation` action, then end your turn: this conversation continues when it lands.';
|
|
7
8
|
const COPIES_LINE = `House Local copies; before work run \`house fetch\` and rebase onto \`${HOUSE_REF}\`; after it commit, then \`house push\`:`;
|
|
8
9
|
export async function instructions(bridge, base, copies) {
|
|
9
|
-
const lines = [SOURCE_LINE, HOUSE_LINE, FILE_LINE, READ_LINE, ...(copies.length === 0 ? [] : [COPIES_LINE, ...copies])];
|
|
10
|
+
const lines = [SOURCE_LINE, HOUSE_LINE, FILE_LINE, READ_LINE, WAIT_LINE, ...(copies.length === 0 ? [] : [COPIES_LINE, ...copies])];
|
|
10
11
|
return [lines.join('\n'), base, (await readHowWeWork(bridge)).replace(/\n$/, '')].filter((part) => part !== '').join('\n\n');
|
|
11
12
|
}
|