@agentshouse/kit 0.2.1-c3e4a20bb3183 → 0.2.1-cb6679d048e60
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 +18 -18
- package/dist/bootstrap.json +10 -17
- package/dist/copies.js +5 -5
- package/dist/home.js +15 -2
- package/dist/house-main.js +11 -12
- package/dist/instructions.js +1 -1
- package/dist/kit-main.js +4 -1
- package/dist/login.js +2 -2
- package/dist/logout.js +18 -0
- package/dist/resident.js +25 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,17 +6,17 @@ through the agent CLIs you chose and gives each Agent the `house` command.
|
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
Run `curl -fsSL agents.house/kit | sh`, or `irm agents.house/kit.ps1 | iex` on
|
|
10
|
+
Windows, and again to update; options follow `sh -s --`. On macOS and Linux it
|
|
11
|
+
installs House Kit natively under your own account, without an admin password,
|
|
12
|
+
as a service that runs while you are logged in. `kit` and `house` are then on
|
|
13
|
+
your login shell's `PATH`, and your workspace is `~/AgentsHouse` unless you
|
|
14
|
+
pass `--workspace <path>`.
|
|
15
15
|
|
|
16
16
|
Add `--container` to run House Kit in one Docker container instead, with your
|
|
17
17
|
workspace mounted at `/agents/house`; your Agents then reach only that
|
|
18
18
|
workspace. On Windows 11 the container is the one choice. Append a `kit` or
|
|
19
|
-
`house` command to the container's
|
|
19
|
+
`house` command to the container's options to run it in that container.
|
|
20
20
|
Running the command for the other choice on a connected computer asks you to
|
|
21
21
|
confirm, then replaces its Environment, whose Agents end, with a new one.
|
|
22
22
|
|
|
@@ -24,14 +24,12 @@ On your own Ubuntu 26.04 server, run the Linux command with `--linux` to
|
|
|
24
24
|
install House Kit natively, with its workspace at `/agents/house`; `kit` and
|
|
25
25
|
`house` are then on the server's `PATH`.
|
|
26
26
|
|
|
27
|
-
House Kit runs the agent CLIs your login shell finds and installs a missing
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
`--no-skills` to the command to leave them out; running it again without the
|
|
34
|
-
flag brings them back.
|
|
27
|
+
House Kit runs the agent CLIs your login shell finds and installs a missing one
|
|
28
|
+
through that CLI's own installer. Running the command again offers to update
|
|
29
|
+
each CLI older than House Kit needs; add `--update-clis` to update every one to
|
|
30
|
+
its latest release without asking. House Kit also gives every Agent on the
|
|
31
|
+
Environment a set of agent skills. Add `--no-skills` to the command to leave
|
|
32
|
+
them out; running it again without the flag brings them back.
|
|
35
33
|
|
|
36
34
|
## Commands
|
|
37
35
|
|
|
@@ -40,13 +38,15 @@ Environment's credential in `~/.house-kit`, or in `$HOUSE_KIT_HOME` when it is
|
|
|
40
38
|
set. Pass `--manual` to paste the code by hand on a machine without a browser,
|
|
41
39
|
and `--environment <id>` to reconnect an Environment you already have. It also
|
|
42
40
|
connects your own agent: `house <tool>` run outside an Agent conversation calls
|
|
43
|
-
House as you, until you revoke that connection on Connections.
|
|
41
|
+
House as you, until you revoke that connection on Connections. `house help`
|
|
42
|
+
lists the Tools. `kit logout` disconnects this computer and stops House Kit; a
|
|
43
|
+
later `kit login` reconnects the same Environment.
|
|
44
44
|
|
|
45
45
|
`kit resident` keeps the Environment connected, and keeps the Rooms you chose
|
|
46
46
|
for this Environment as Git repositories under `local-copies` in the
|
|
47
|
-
workspace. Commit in one and run `house
|
|
47
|
+
workspace. Commit in one and run `house push --owner` there to send the
|
|
48
48
|
commit to House; in the container, run it through the install command from the
|
|
49
|
-
copy's directory. Inside an Agent conversation the Agent runs `house
|
|
49
|
+
copy's directory. Inside an Agent conversation the Agent runs `house push`.
|
|
50
50
|
|
|
51
51
|
House Kit turns each audio file of your message to an Agent into text on this
|
|
52
52
|
computer before the Agent reads the message. The first audio file downloads the
|
package/dist/bootstrap.json
CHANGED
|
@@ -1,30 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
3
|
-
"version": "0.2.1-
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"version": "0.2.1-cb6679d048e60",
|
|
4
4
|
"hosts": {
|
|
5
|
+
"macos": {
|
|
6
|
+
"asset": {
|
|
7
|
+
"name": "connect-linux.sh",
|
|
8
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-cb6679d048e60/connect-linux.sh"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
5
11
|
"linux": {
|
|
6
|
-
"command": "bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.2.1-c3e4a20bb3183/connect-linux.sh)",
|
|
7
12
|
"asset": {
|
|
8
13
|
"name": "connect-linux.sh",
|
|
9
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-
|
|
10
|
-
},
|
|
11
|
-
"workspace": {
|
|
12
|
-
"argument": "--workspace",
|
|
13
|
-
"quoting": "posix"
|
|
14
|
-
},
|
|
15
|
-
"container": {
|
|
16
|
-
"argument": "--container"
|
|
14
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-cb6679d048e60/connect-linux.sh"
|
|
17
15
|
}
|
|
18
16
|
},
|
|
19
17
|
"windows": {
|
|
20
|
-
"command": "& ([scriptblock]::Create((irm https://github.com/agentshouse/kit/releases/download/v0.2.1-c3e4a20bb3183/connect-windows.ps1)))",
|
|
21
18
|
"asset": {
|
|
22
19
|
"name": "connect-windows.ps1",
|
|
23
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-
|
|
24
|
-
},
|
|
25
|
-
"workspace": {
|
|
26
|
-
"argument": "--workspace",
|
|
27
|
-
"quoting": "powershell"
|
|
20
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.2.1-cb6679d048e60/connect-windows.ps1"
|
|
28
21
|
}
|
|
29
22
|
}
|
|
30
23
|
}
|
package/dist/copies.js
CHANGED
|
@@ -255,11 +255,11 @@ export class LocalCopies {
|
|
|
255
255
|
async push(cwd, selector, caller) {
|
|
256
256
|
const located = await run(cwd, ['rev-parse', '--path-format=absolute', '--git-common-dir', '--show-toplevel']);
|
|
257
257
|
if (located.status !== 0)
|
|
258
|
-
return { refused: true, text: `${cwd} is not a House Local copy; run house
|
|
258
|
+
return { refused: true, text: `${cwd} is not a House Local copy; run house push inside one` };
|
|
259
259
|
const [common, worktree] = located.stdout.toString('utf8').split('\n');
|
|
260
260
|
const key = await this.keyAt(dirname(common));
|
|
261
261
|
if (key === undefined)
|
|
262
|
-
return { refused: true, text: `${worktree} is not a House Local copy; run house
|
|
262
|
+
return { refused: true, text: `${worktree} is not a House Local copy; run house push inside one` };
|
|
263
263
|
return this.exclusive(key, () => this.pushed(key, worktree, selector, caller));
|
|
264
264
|
}
|
|
265
265
|
async keyAt(repository) {
|
|
@@ -597,7 +597,7 @@ export class LocalCopies {
|
|
|
597
597
|
const refusal = error instanceof HouseRefusal ? refusalOf(error.text) : null;
|
|
598
598
|
return {
|
|
599
599
|
refused: true,
|
|
600
|
-
text: refusal?.text ?? `House's answer to ${short(push.commit)} did not arrive; run house
|
|
600
|
+
text: refusal?.text ?? `House's answer to ${short(push.commit)} did not arrive; run house push again`,
|
|
601
601
|
};
|
|
602
602
|
}
|
|
603
603
|
if ('refused' in outcome) {
|
|
@@ -636,7 +636,7 @@ export class LocalCopies {
|
|
|
636
636
|
await this.save(without(current));
|
|
637
637
|
return {
|
|
638
638
|
refused: true,
|
|
639
|
-
text: `House does not hold ${short(push.commit)}; run house
|
|
639
|
+
text: `House does not hold ${short(push.commit)}; run house push again`,
|
|
640
640
|
};
|
|
641
641
|
}
|
|
642
642
|
const written = [];
|
|
@@ -664,7 +664,7 @@ export class LocalCopies {
|
|
|
664
664
|
catch {
|
|
665
665
|
return {
|
|
666
666
|
refused: false,
|
|
667
|
-
text: `House accepted ${short(commit)}; run house
|
|
667
|
+
text: `House accepted ${short(commit)}; run house push again to finish integrating it here`,
|
|
668
668
|
};
|
|
669
669
|
}
|
|
670
670
|
}
|
package/dist/home.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
1
2
|
import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { homedir } from 'node:os';
|
|
3
4
|
import { join } from 'node:path';
|
|
4
5
|
const ENROLMENT = 'credential.json';
|
|
6
|
+
const DISCONNECTED = 'disconnected.json';
|
|
5
7
|
const CONFIGURATION = 'kit.json';
|
|
6
8
|
const OWN_AGENT = 'own-agent.json';
|
|
7
9
|
export function kitHome() {
|
|
@@ -33,8 +35,19 @@ export async function writeHome(name, value) {
|
|
|
33
35
|
export function readEnrolment() {
|
|
34
36
|
return readHome(ENROLMENT);
|
|
35
37
|
}
|
|
36
|
-
export function writeEnrolment(enrolment) {
|
|
37
|
-
|
|
38
|
+
export async function writeEnrolment(enrolment) {
|
|
39
|
+
await writeHome(ENROLMENT, enrolment);
|
|
40
|
+
await rm(join(kitHome(), DISCONNECTED), { force: true });
|
|
41
|
+
}
|
|
42
|
+
export function readDisconnected() {
|
|
43
|
+
return readHome(DISCONNECTED);
|
|
44
|
+
}
|
|
45
|
+
export async function forgetEnrolment({ house, environment }) {
|
|
46
|
+
await writeHome(DISCONNECTED, { house, environment });
|
|
47
|
+
await rm(join(kitHome(), ENROLMENT), { force: true });
|
|
48
|
+
}
|
|
49
|
+
export function enrolled() {
|
|
50
|
+
return existsSync(join(kitHome(), ENROLMENT));
|
|
38
51
|
}
|
|
39
52
|
export function readOwnAgent() {
|
|
40
53
|
return readHome(OWN_AGENT);
|
package/dist/house-main.js
CHANGED
|
@@ -7,7 +7,8 @@ import { kitHome, readOwnAgent } from './home.js';
|
|
|
7
7
|
import { callHouse, rpc, UNREACHABLE } from './mcp.js';
|
|
8
8
|
import { refusalOf } from './refusals.js';
|
|
9
9
|
const USAGE = "usage: house <tool> ['<arguments as JSON>']";
|
|
10
|
-
const
|
|
10
|
+
const PUSH_USAGE = 'usage: house push [commit] [--owner]';
|
|
11
|
+
const PUSH = "push [commit]: sends the Local copy's committed changes to House";
|
|
11
12
|
const ARGUMENTS = `the arguments are one JSON object in single quotes, like house search '{"query":"invoice"}'`;
|
|
12
13
|
const CLOSED = "this conversation's House connection is closed; nothing to do from here";
|
|
13
14
|
const REVOKED = 'this conversation no longer has House access; nothing to do from here';
|
|
@@ -97,17 +98,15 @@ async function upload(path, roomRef, missing) {
|
|
|
97
98
|
throw new Error(`${path} was not saved: ${saved.upload_failure}; call again later`);
|
|
98
99
|
return saved.attachment;
|
|
99
100
|
}
|
|
100
|
-
async function
|
|
101
|
+
async function push(args) {
|
|
101
102
|
if (args.includes('--help'))
|
|
102
|
-
return
|
|
103
|
-
if (args[0] !== 'push')
|
|
104
|
-
throw new Error('only house git push [commit] exists; use plain git for the rest');
|
|
103
|
+
return PUSH_USAGE;
|
|
105
104
|
const owner = args.includes('--owner');
|
|
106
|
-
const commit = args.
|
|
105
|
+
const commit = args.find((arg) => arg !== '--owner') ?? 'HEAD';
|
|
107
106
|
if (owner && socketPath !== undefined)
|
|
108
|
-
throw new Error('--owner is not for Agent conversations; run house
|
|
107
|
+
throw new Error('--owner is not for Agent conversations; run house push without it');
|
|
109
108
|
if (!owner && socketPath === undefined)
|
|
110
|
-
throw new Error('outside an Agent conversation, house
|
|
109
|
+
throw new Error('outside an Agent conversation, house push needs --owner');
|
|
111
110
|
const pushed = JSON.parse(await bridged('/git/push', { cwd: process.cwd(), commit }, undefined, owner ? join(kitHome(), 'owner.sock') : socketPath));
|
|
112
111
|
if (pushed.refused)
|
|
113
112
|
throw new Error(pushed.text);
|
|
@@ -128,14 +127,14 @@ function argumentsOf(argument) {
|
|
|
128
127
|
return parsed;
|
|
129
128
|
}
|
|
130
129
|
async function house([verb, argument]) {
|
|
131
|
-
if (verb === undefined || verb === '--help') {
|
|
132
|
-
return [USAGE, '
|
|
130
|
+
if (verb === undefined || verb === '--help' || verb === 'help') {
|
|
131
|
+
return [USAGE, 'help', PUSH, ...(await tools()).map((tool) => (tool.description === undefined ? tool.name : `${tool.name}: ${tool.description}`))].join('\n');
|
|
133
132
|
}
|
|
134
133
|
if (argument === '--help') {
|
|
135
134
|
const tool = (await tools()).find((listed) => listed.name === verb);
|
|
136
135
|
if (tool === undefined)
|
|
137
136
|
throw new Error(`${verb} is no Tool; house find_command '{"query":"${verb}"}' finds Commands`);
|
|
138
|
-
return
|
|
137
|
+
return [...(tool.description === undefined ? [] : [tool.description]), JSON.stringify(tool.inputSchema)].join('\n');
|
|
139
138
|
}
|
|
140
139
|
const args = argumentsOf(argument);
|
|
141
140
|
if (socketPath !== undefined && verb === 'upload_attachment') {
|
|
@@ -155,7 +154,7 @@ async function house([verb, argument]) {
|
|
|
155
154
|
return text;
|
|
156
155
|
}
|
|
157
156
|
const argv = process.argv.slice(2);
|
|
158
|
-
(argv[0] === '
|
|
157
|
+
(argv[0] === 'push' ? push(argv.slice(1)) : house(argv)).then((text) => {
|
|
159
158
|
process.stdout.write(`${text}\n`);
|
|
160
159
|
}, (error) => {
|
|
161
160
|
process.stderr.write(`house: ${error instanceof Error ? error.message : String(error)}\n`);
|
package/dist/instructions.js
CHANGED
|
@@ -2,7 +2,7 @@ import { HOW_WE_WORK } from './skills.js';
|
|
|
2
2
|
const HOUSE_LINE = 'Work with House through the `house` CLI: run `house --help`.';
|
|
3
3
|
const FILE_LINE = 'To give the User a file or a page, upload it with `house upload_attachment` and link it; never start a server.';
|
|
4
4
|
const READ_LINE = 'Before working in a Room, read `/private/rooms/<handle>/AGENTS.md`.';
|
|
5
|
-
const COPIES_LINE = 'House Local copies; commit, then `house
|
|
5
|
+
const COPIES_LINE = 'House Local copies; commit, then `house push`:';
|
|
6
6
|
const UNREADABLE = /^(?:\S+: )?(?:path_not_found|room_not_found|operation_denied)\b/;
|
|
7
7
|
const FAILED = /^exit: [1-9]\d*$/;
|
|
8
8
|
const CUT = /^stderr: shell: output_cut (\d+) of \d+ bytes; continue with: (.+)$/;
|
package/dist/kit-main.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { setGlobalProxyFromEnv } from 'node:http';
|
|
3
3
|
import { login } from './login.js';
|
|
4
|
+
import { logout } from './logout.js';
|
|
4
5
|
import { resident } from './resident.js';
|
|
5
6
|
const [command, ...argv] = process.argv.slice(2);
|
|
6
7
|
setGlobalProxyFromEnv();
|
|
7
8
|
async function run() {
|
|
8
9
|
if (command === 'login')
|
|
9
10
|
return login(argv);
|
|
11
|
+
if (command === 'logout')
|
|
12
|
+
return logout();
|
|
10
13
|
if (command === 'resident')
|
|
11
14
|
return resident();
|
|
12
|
-
process.stderr.write('usage: kit <login|resident>\n');
|
|
15
|
+
process.stderr.write('usage: kit <login|logout|resident>\n');
|
|
13
16
|
process.exitCode = 2;
|
|
14
17
|
}
|
|
15
18
|
run().catch((error) => {
|
package/dist/login.js
CHANGED
|
@@ -4,7 +4,7 @@ import { hostname } from 'node:os';
|
|
|
4
4
|
import { createInterface } from 'node:readline/promises';
|
|
5
5
|
import { parseArgs } from 'node:util';
|
|
6
6
|
import { post } from './api.js';
|
|
7
|
-
import { forgetOwnAgent, readEnrolment, readOwnAgent, writeEnrolment, writeOwnAgent } from './home.js';
|
|
7
|
+
import { forgetOwnAgent, readDisconnected, readEnrolment, readOwnAgent, writeEnrolment, writeOwnAgent } from './home.js';
|
|
8
8
|
import { callHouse, rpc } from './mcp.js';
|
|
9
9
|
const DEFAULT_HOUSE = 'https://agents.house';
|
|
10
10
|
function listen() {
|
|
@@ -78,7 +78,7 @@ export async function login(argv) {
|
|
|
78
78
|
manual: { type: 'boolean', default: false },
|
|
79
79
|
},
|
|
80
80
|
});
|
|
81
|
-
const enrolled = await readEnrolment();
|
|
81
|
+
const enrolled = (await readEnrolment()) ?? (await readDisconnected());
|
|
82
82
|
const house = values.house ?? enrolled?.house ?? DEFAULT_HOUSE;
|
|
83
83
|
const replaces = process.env.HOUSE_KIT_REPLACES;
|
|
84
84
|
const environment = replaces === undefined ? (values.environment ?? (enrolled?.house === house ? enrolled.environment : undefined)) : undefined;
|
package/dist/logout.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { HouseRefusal, post } from './api.js';
|
|
2
|
+
import { forgetEnrolment, readEnrolment } from './home.js';
|
|
3
|
+
export async function logout() {
|
|
4
|
+
const enrolled = await readEnrolment();
|
|
5
|
+
if (enrolled === null) {
|
|
6
|
+
process.stdout.write('This computer is not connected to House.\n');
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
await post(enrolled.house, '/kit/logout', {}, enrolled.credential);
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (!(error instanceof HouseRefusal && error.status === 401))
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
await forgetEnrolment(enrolled);
|
|
17
|
+
process.stdout.write(`Environment ${enrolled.environment} is disconnected; kit login reconnects it.\n`);
|
|
18
|
+
}
|
package/dist/resident.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { once } from 'node:events';
|
|
2
|
+
import { watch } from 'node:fs';
|
|
2
3
|
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
|
3
4
|
import { createServer } from 'node:http';
|
|
4
5
|
import { extname, join } from 'node:path';
|
|
@@ -9,7 +10,7 @@ import { house } from './api.js';
|
|
|
9
10
|
import { received } from './bridge.js';
|
|
10
11
|
import { Conversations } from './conversations.js';
|
|
11
12
|
import { LocalCopies } from './copies.js';
|
|
12
|
-
import { agentBase,
|
|
13
|
+
import { agentBase, enrolled, kitHome } from './home.js';
|
|
13
14
|
import { SignIns } from './sign-in.js';
|
|
14
15
|
import { placeSkillSet } from './skills.js';
|
|
15
16
|
import { holdStream } from './stream.js';
|
|
@@ -50,12 +51,30 @@ async function serveOwner(copies) {
|
|
|
50
51
|
server.listen(socketPath);
|
|
51
52
|
await once(server, 'listening');
|
|
52
53
|
}
|
|
54
|
+
function connected() {
|
|
55
|
+
return new Promise((resolve) => {
|
|
56
|
+
const watcher = watch(kitHome(), () => {
|
|
57
|
+
if (!enrolled())
|
|
58
|
+
return;
|
|
59
|
+
watcher.close();
|
|
60
|
+
resolve();
|
|
61
|
+
});
|
|
62
|
+
if (!enrolled()) {
|
|
63
|
+
process.stderr.write('kit: this Environment is not connected; run kit login\n');
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
watcher.close();
|
|
67
|
+
resolve();
|
|
68
|
+
});
|
|
69
|
+
}
|
|
53
70
|
export async function resident() {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
71
|
+
await connected();
|
|
72
|
+
watch(kitHome(), () => {
|
|
73
|
+
if (enrolled())
|
|
74
|
+
return;
|
|
75
|
+
killDescendants();
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
59
78
|
await placeSkillSet();
|
|
60
79
|
await mkdir(agentBase(), { recursive: true });
|
|
61
80
|
process.env.HOUSE_KIT_RESIDENT = String(process.pid);
|