@agentshouse/kit 0.1.0-alpha.25 → 0.1.0-alpha.27
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 +172 -158
- package/bin/connect-linux.sh +15 -4
- package/bin/kit.js +48 -46
- package/bootstrap.json +3 -3
- package/package.json +1 -1
- package/src/adapter-mcp.js +23 -1
- package/src/bridge.js +4 -0
- package/src/configuration.js +13 -209
- package/src/connector-login.js +3 -84
- package/src/contract.js +4 -0
- package/src/delivery.js +4 -7
- package/src/directory.js +6 -26
- package/src/google/calendar.js +39 -45
- package/src/google/drive.js +61 -186
- package/src/google/entries.js +346 -0
- package/src/google/gateway.js +3 -6
- package/src/google/gmail.js +33 -23
- package/src/google/oauth.js +106 -66
- package/src/google/source.js +21 -23
- package/src/house.js +43 -5
- package/src/how-we-work.md +25 -0
- package/src/kit-work-stream.js +1 -1
- package/src/launcher.js +11 -4
- package/src/mcp.js +5 -0
- package/src/setup.js +8 -14
- package/src/skill-set/ask-matt/PHASE-BOUNDARIES.md +55 -0
- package/src/skill-set/ask-matt/SKILL.md +91 -0
- package/src/skill-set/ask-matt/agents/openai.yaml +4 -0
- package/src/skill-set/code-review/LICENSE +21 -0
- package/src/skill-set/code-review/SKILL.md +89 -0
- package/src/skill-set/code-review/agents/openai.yaml +3 -0
- package/src/skill-set/codebase-design/DEEPENING.md +37 -0
- package/src/skill-set/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/src/skill-set/codebase-design/LICENSE +21 -0
- package/src/skill-set/codebase-design/SKILL.md +116 -0
- package/src/skill-set/codebase-design/agents/openai.yaml +3 -0
- package/src/skill-set/diagnosing-bugs/LICENSE +21 -0
- package/src/skill-set/diagnosing-bugs/SKILL.md +140 -0
- package/src/skill-set/diagnosing-bugs/agents/openai.yaml +3 -0
- package/src/skill-set/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/src/skill-set/domain-modeling/ADR-FORMAT.md +47 -0
- package/src/skill-set/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/src/skill-set/domain-modeling/LICENSE +21 -0
- package/src/skill-set/domain-modeling/SKILL.md +76 -0
- package/src/skill-set/domain-modeling/agents/openai.yaml +3 -0
- package/src/skill-set/grill-me/LICENSE +21 -0
- package/src/skill-set/grill-me/SKILL.md +8 -0
- package/src/skill-set/grill-me/agents/openai.yaml +4 -0
- package/src/skill-set/grill-with-docs/LICENSE +21 -0
- package/src/skill-set/grill-with-docs/SKILL.md +8 -0
- package/src/skill-set/grill-with-docs/agents/openai.yaml +4 -0
- package/src/skill-set/grilling/LICENSE +21 -0
- package/src/{starter-set → skill-set}/grilling/SKILL.md +1 -1
- package/src/skill-set/handoff/LICENSE +21 -0
- package/src/skill-set/handoff/SKILL.md +17 -0
- package/src/skill-set/handoff/agents/openai.yaml +4 -0
- package/src/skill-set/implement/LICENSE +21 -0
- package/src/skill-set/implement/SKILL.md +16 -0
- package/src/skill-set/implement/agents/openai.yaml +4 -0
- package/src/skill-set/improve-codebase-architecture/HTML-REPORT.md +123 -0
- package/src/skill-set/improve-codebase-architecture/LICENSE +21 -0
- package/src/skill-set/improve-codebase-architecture/SKILL.md +72 -0
- package/src/skill-set/improve-codebase-architecture/agents/openai.yaml +4 -0
- package/src/skill-set/prototype/LICENSE +21 -0
- package/src/skill-set/prototype/LOGIC.md +67 -0
- package/src/skill-set/prototype/SKILL.md +28 -0
- package/src/skill-set/prototype/UI.md +112 -0
- package/src/skill-set/prototype/agents/openai.yaml +3 -0
- package/src/skill-set/research/LICENSE +21 -0
- package/src/skill-set/research/SKILL.md +14 -0
- package/src/skill-set/research/agents/openai.yaml +3 -0
- package/src/skill-set/resolving-merge-conflicts/LICENSE +21 -0
- package/src/skill-set/resolving-merge-conflicts/SKILL.md +16 -0
- package/src/skill-set/resolving-merge-conflicts/agents/openai.yaml +3 -0
- package/src/skill-set/tdd/LICENSE +21 -0
- package/src/skill-set/tdd/SKILL.md +40 -0
- package/src/skill-set/tdd/agents/openai.yaml +3 -0
- package/src/skill-set/tdd/mocking.md +59 -0
- package/src/skill-set/tdd/tests.md +77 -0
- package/src/skill-set/teach/GLOSSARY-FORMAT.md +35 -0
- package/src/skill-set/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/src/skill-set/teach/LICENSE +21 -0
- package/src/skill-set/teach/MISSION-FORMAT.md +31 -0
- package/src/skill-set/teach/RESOURCES-FORMAT.md +32 -0
- package/src/skill-set/teach/SKILL.md +141 -0
- package/src/skill-set/teach/agents/openai.yaml +4 -0
- package/src/skill-set/to-questionnaire/LICENSE +21 -0
- package/src/skill-set/to-questionnaire/SKILL.md +55 -0
- package/src/skill-set/to-questionnaire/agents/openai.yaml +4 -0
- package/src/skill-set/to-spec/LICENSE +21 -0
- package/src/skill-set/to-spec/SKILL.md +76 -0
- package/src/skill-set/to-spec/agents/openai.yaml +4 -0
- package/src/skill-set/to-tickets/LICENSE +21 -0
- package/src/skill-set/to-tickets/SKILL.md +106 -0
- package/src/skill-set/to-tickets/agents/openai.yaml +4 -0
- package/src/skill-set/wait-what/LICENSE +21 -0
- package/src/skill-set/wait-what/SKILL.md +8 -0
- package/src/skill-set/wait-what/agents/openai.yaml +4 -0
- package/src/skill-set/wayfinder/LICENSE +21 -0
- package/src/skill-set/wayfinder/SKILL.md +129 -0
- package/src/skill-set/wayfinder/agents/openai.yaml +4 -0
- package/src/skill-set/writing-for-agents/LICENSE +21 -0
- package/src/skill-set/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/src/skill-set/writing-for-agents/SKILL.md +83 -0
- package/src/skill-set/writing-for-agents/agents/openai.yaml +3 -0
- package/src/skill-set.js +85 -0
- package/src/source.js +51 -26
- package/src/state.js +19 -1
- package/src/tasks.js +72 -0
- package/src/worker.js +46 -68
- package/src/working-copy.js +1 -15
- package/src/google/declared.js +0 -146
- package/src/google/id.js +0 -1
- package/src/instance/google.js +0 -1
- package/src/starter-set.js +0 -17
- /package/src/{starter-set/grilling → skill-set/ask-matt}/LICENSE +0 -0
- /package/src/{starter-set → skill-set}/grilling/agents/openai.yaml +0 -0
package/README.md
CHANGED
|
@@ -4,12 +4,15 @@ House Kit is a public package repository. Product development is planned and
|
|
|
4
4
|
coordinated in the [Agents House repository](https://github.com/trof3039/agents.house);
|
|
5
5
|
this repository contains only the package source and its operator documentation.
|
|
6
6
|
|
|
7
|
+
The Skill set Kit installs is Matt Pocock's
|
|
8
|
+
[`mattpocock/skills`](https://github.com/mattpocock/skills); thank you, Matt.
|
|
9
|
+
|
|
7
10
|
## Connect a Linux computer
|
|
8
11
|
|
|
9
12
|
On Linux `amd64` or `arm64`, run the published, versioned bootstrap once:
|
|
10
13
|
|
|
11
14
|
```sh
|
|
12
|
-
bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.
|
|
15
|
+
bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.27/connect-linux.sh)
|
|
13
16
|
```
|
|
14
17
|
|
|
15
18
|
The bootstrap first establishes Docker Engine from what it observes on the
|
|
@@ -40,13 +43,18 @@ and starts the container with Docker's `unless-stopped` lifecycle. Pass
|
|
|
40
43
|
`--workspace /absolute/path` for one other workspace root or `--manual` for
|
|
41
44
|
the existing URL and one-time-code login route. `--house <origin>` selects
|
|
42
45
|
another House and is retained in Kit home. A repeated invocation reuses the
|
|
43
|
-
same container, credential and Environment.
|
|
46
|
+
same container, credential and Environment. Every invocation that is not a
|
|
47
|
+
forwarded command also sets `skills` in Kit's configuration: `--no-skills`
|
|
48
|
+
declines [the Skill set](#the-skill-set) and an invocation without it accepts
|
|
49
|
+
the set again.
|
|
44
50
|
|
|
45
51
|
Running a newer release's bootstrap the same way is the only update. When the
|
|
46
52
|
installed container runs another image, the bootstrap pulls this release's
|
|
47
53
|
image and asks the running resident Kit to drain with `kit resident drain`. The
|
|
48
|
-
resident stops acquiring Runs, resumptions, setup
|
|
49
|
-
|
|
54
|
+
resident stops acquiring Runs, resumptions, setup, agent CLI work, Google
|
|
55
|
+
sign-ins and scheduled Google captures, while the Sessions it supervises keep
|
|
56
|
+
their renewal, owner stops, answers and reports and a capture already running
|
|
57
|
+
finishes.
|
|
50
58
|
While any Agent Session is still running or unreported, including one whose Run
|
|
51
59
|
was being acquired when the drain began, the bootstrap names it and leaves the
|
|
52
60
|
container as it is; rerun it once they end. Once nothing remains,
|
|
@@ -135,21 +143,17 @@ anything reaches House.
|
|
|
135
143
|
|
|
136
144
|
## Building the package
|
|
137
145
|
|
|
138
|
-
The repository checkout is the development source. Build the package
|
|
139
|
-
|
|
140
|
-
Google OAuth client, its id and its client secret:
|
|
146
|
+
The repository checkout is the development source. Build the package that can
|
|
147
|
+
be published:
|
|
141
148
|
|
|
142
149
|
```sh
|
|
143
|
-
HOUSE_KIT_GOOGLE_OAUTH_CLIENT_ID=kit-client.apps.googleusercontent.com \
|
|
144
|
-
HOUSE_KIT_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-kit-installed-app \
|
|
145
150
|
npm run build
|
|
146
151
|
```
|
|
147
152
|
|
|
148
|
-
The command writes the publishable package to `dist/package`.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
from its runtime environment and never requests them from House.
|
|
153
|
+
The command writes the publishable package to `dist/package`. It reads no
|
|
154
|
+
environment and ships no provider OAuth client: each Google account signs in
|
|
155
|
+
with the User's own client, as [the Google preset](#the-google-preset)
|
|
156
|
+
describes.
|
|
153
157
|
|
|
154
158
|
Runtime dependencies stay minimal and exactly pinned in `package.json` and
|
|
155
159
|
`package-lock.json`: House's own `@agentshouse/mdmodel`, `yaml`, which reads
|
|
@@ -227,7 +231,8 @@ never printed by Kit.
|
|
|
227
231
|
"settings": "/home/ada/.claude/settings.json"
|
|
228
232
|
}
|
|
229
233
|
],
|
|
230
|
-
"host": null
|
|
234
|
+
"host": null,
|
|
235
|
+
"skills": true
|
|
231
236
|
}
|
|
232
237
|
```
|
|
233
238
|
|
|
@@ -247,13 +252,19 @@ mode: `"intermittent"` for a laptop or other normally offline placement,
|
|
|
247
252
|
any other value refuses as `kit_configuration_invalid`; `kit apply` sends the
|
|
248
253
|
declared mode with the rest of the desired state. An
|
|
249
254
|
instance declares one or more services, and under the `custom` preset each
|
|
250
|
-
service owns the command that produces it.
|
|
255
|
+
service owns the command that produces it. The Kit reads only `custom` instances
|
|
256
|
+
and passes over any other entry of `instances`.
|
|
251
257
|
|
|
252
258
|
`host` declares the Linux host this installation measures for
|
|
253
259
|
[host capacity reporting](#host-capacity). `null` declares that this Kit reports
|
|
254
260
|
no capacity; the section is required like the others, so a host is measured only
|
|
255
261
|
where the Environment owner says so.
|
|
256
262
|
|
|
263
|
+
`skills` is this Environment's choice of [the Skill set](#the-skill-set):
|
|
264
|
+
`true` accepts it and `false` declines it. A configuration that omits it
|
|
265
|
+
accepts the set. The bootstrap writes it on every invocation that is not a
|
|
266
|
+
forwarded command.
|
|
267
|
+
|
|
257
268
|
`clients` is the local Agent client catalogue and never leaves the installation.
|
|
258
269
|
Each entry names one client whose lifecycle hook configuration this Kit
|
|
259
270
|
reconciles: `kind` is `claude-code`, the one client this Kit installs a hook
|
|
@@ -348,119 +359,81 @@ refuses as `kit_hook_rejected` instead of leaving whatever was installed before.
|
|
|
348
359
|
|
|
349
360
|
## The Google preset
|
|
350
361
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
362
|
+
House holds this Environment's Google Sources, and its owner sets them in the
|
|
363
|
+
App. Each entry names an account name the owner chooses, one service -
|
|
364
|
+
`gmail`, `calendar` or `drive` - the Rooms it goes to, and what its first
|
|
365
|
+
capture takes: `{ "new": true }` for new activity only, `{ "days": n }`,
|
|
366
|
+
`{ "items": n }` or `{ "all": true }`. Neither the configuration file nor any
|
|
367
|
+
command on this computer declares one.
|
|
368
|
+
|
|
369
|
+
Each service captures a fixed corpus under its own read-only scope: Gmail every
|
|
370
|
+
message but Spam and Trash, Calendar the account's primary calendar, and Drive
|
|
371
|
+
the files the account owns.
|
|
372
|
+
|
|
373
|
+
The resident reads the list from `/kit/sources/desired` each time its Kit
|
|
374
|
+
control stream connects and each time House signals `sources` on it, then
|
|
375
|
+
reconciles:
|
|
376
|
+
|
|
377
|
+
- a new entry gets its local state and is captured once its account is signed
|
|
378
|
+
in for its service;
|
|
379
|
+
- a changed entry's Rooms take effect on its next capture;
|
|
380
|
+
- an entry House no longer lists stops, and its checkpoint, health, gaps,
|
|
381
|
+
dropped items and unsaved originals are deleted;
|
|
382
|
+
- an account left with no entry has each of its grants revoked at Google's
|
|
383
|
+
revocation endpoint and its credentials, its OAuth client included, deleted.
|
|
384
|
+
Google's revocation ends every grant the Google user gave the client's
|
|
385
|
+
project, so when another listed account is signed in to the same Google user,
|
|
386
|
+
the Kit deletes the local credentials and revokes nothing.
|
|
387
|
+
|
|
388
|
+
It then reports every entry to `/kit/sources/report`, and reports an entry
|
|
389
|
+
again after each sign-in and each capture: `signed_out` while its
|
|
390
|
+
account holds no grant for its service, `failed` with its cause code when its
|
|
391
|
+
last capture failed, and `ready` otherwise, each with the account's signed-in
|
|
392
|
+
email once the Kit knows it.
|
|
393
|
+
|
|
394
|
+
The Kit ships no Google OAuth client. Each account signs in with the User's
|
|
395
|
+
own: an OAuth client of type Desktop app in the User's Google Cloud project,
|
|
396
|
+
with the service's API enabled there. An entry whose account holds no grant for
|
|
397
|
+
its service opens a login renewal for integration `google`, instance the
|
|
398
|
+
account name and service the entry's service, and presents its ceremony on
|
|
399
|
+
House's owner-authenticated page, so the owner's browser never has to reach
|
|
400
|
+
this Environment. When the account has no client yet, the page first collects
|
|
401
|
+
the client id and secret. It then links to Google's consent for that service's
|
|
402
|
+
scope only; Google sends the browser to a `http://127.0.0.1:<port>/` address
|
|
403
|
+
that nothing answers, and the owner pastes that whole address into the page.
|
|
404
|
+
The Kit accepts it only when it carries the state its own consent issued,
|
|
405
|
+
exchanges the code with its PKCE verifier and the account's client, and stores
|
|
406
|
+
the grant beside the client in `state/google/credentials/<account>.json`. The
|
|
407
|
+
collected values pass through House's live relay only; neither they nor any
|
|
408
|
+
token enter a report, a log or anything House stores. Adding a
|
|
409
|
+
service to a signed-in account asks only for that service's consent, and each
|
|
410
|
+
service keeps its own grant. An address that answers another consent, or a code
|
|
411
|
+
Google refuses to exchange, stores nothing; a declined consent or a ceremony
|
|
412
|
+
that outlives its ten-minute bound cancels the sign-in, and the Kit tries again
|
|
413
|
+
at the next reconciliation.
|
|
414
|
+
|
|
415
|
+
The resident captures each signed-in entry every 15 minutes, with no command.
|
|
416
|
+
An occurrence never overlaps its entry's previous one, and one missed while the
|
|
417
|
+
resident was stopped is not replayed: the next resumes from the checkpoint. The
|
|
418
|
+
first capture fixes the initial choice's boundary, so `new` captures nothing
|
|
419
|
+
that existed then and everything that arrives after.
|
|
361
420
|
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
"migrators": [],
|
|
367
|
-
"instances": [
|
|
368
|
-
{
|
|
369
|
-
"id": "google-account",
|
|
370
|
-
"preset": "google",
|
|
371
|
-
"scopes": ["https://www.googleapis.com/auth/contacts.readonly"],
|
|
372
|
-
"services": [
|
|
373
|
-
{
|
|
374
|
-
"service": "gmail",
|
|
375
|
-
"source_ref": "src_google_mail",
|
|
376
|
-
"rooms": ["work-room"],
|
|
377
|
-
"backfill": { "days": 30 },
|
|
378
|
-
"selection": { "labels": ["INBOX"] }
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
"service": "calendar",
|
|
382
|
-
"source_ref": "src_google_calendar",
|
|
383
|
-
"rooms": ["work-room"],
|
|
384
|
-
"backfill": { "all": true },
|
|
385
|
-
"selection": { "calendars": ["primary"] }
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
"service": "drive",
|
|
389
|
-
"source_ref": "src_google_drive",
|
|
390
|
-
"rooms": ["work-room"],
|
|
391
|
-
"backfill": { "count": 500 },
|
|
392
|
-
"selection": { "files": ["file-id"], "folders": ["folder-id"] }
|
|
393
|
-
}
|
|
394
|
-
]
|
|
395
|
-
}
|
|
396
|
-
],
|
|
397
|
-
"clients": [],
|
|
398
|
-
"host": null
|
|
399
|
-
}
|
|
421
|
+
```sh
|
|
422
|
+
kit source capture work # one occurrence of every entry of the account now
|
|
423
|
+
kit source capture work gmail # one occurrence of one entry now
|
|
424
|
+
kit source status work
|
|
400
425
|
```
|
|
401
426
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
Additional Google API scopes are declared once on the preset instance and
|
|
407
|
-
remain local; a declared service names only scopes that instance already
|
|
408
|
-
holds. Drive requires at least one explicit file or folder selection and never
|
|
409
|
-
defaults to the whole account.
|
|
410
|
-
|
|
411
|
-
A Google API outside the three curated services may use the closed declared
|
|
412
|
-
service schema. The declaration is data only: no script or executable transform
|
|
413
|
-
is loaded. Its host must be a Google API domain and it runs under scopes the
|
|
414
|
-
instance already holds.
|
|
415
|
-
|
|
416
|
-
```json
|
|
417
|
-
{
|
|
418
|
-
"service": "people",
|
|
419
|
-
"source_ref": "src_google_people",
|
|
420
|
-
"rooms": ["work-room"],
|
|
421
|
-
"backfill": { "all": true },
|
|
422
|
-
"declaration": {
|
|
423
|
-
"host": "people.googleapis.com",
|
|
424
|
-
"path": "/v1/people/me/connections",
|
|
425
|
-
"query": { "personFields": "names,emailAddresses,metadata" },
|
|
426
|
-
"page_size": "pageSize",
|
|
427
|
-
"scopes": ["https://www.googleapis.com/auth/contacts.readonly"],
|
|
428
|
-
"page_token": {
|
|
429
|
-
"request": "pageToken",
|
|
430
|
-
"response": "nextPageToken",
|
|
431
|
-
"checkpoint_request": "syncToken",
|
|
432
|
-
"checkpoint_response": "nextSyncToken"
|
|
433
|
-
},
|
|
434
|
-
"items": "connections",
|
|
435
|
-
"fields": {
|
|
436
|
-
"native_id": "resourceName",
|
|
437
|
-
"native_version": "etag",
|
|
438
|
-
"provider_modified_at": "metadata.sources.0.updateTime",
|
|
439
|
-
"observed_at": "metadata.sources.0.updateTime",
|
|
440
|
-
"body": ["names.0.displayName", "emailAddresses.0.value"],
|
|
441
|
-
"container": "metadata.sources.0.type"
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
```
|
|
427
|
+
`kit source capture` and `kit source status` take the account name where a
|
|
428
|
+
custom connector takes its instance; a name House lists as an account is read
|
|
429
|
+
as the account. While the resident runs, it performs the requested occurrence
|
|
430
|
+
itself, after any occurrence of that entry already running.
|
|
446
431
|
|
|
447
|
-
A Google
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
nothing answers: the owner copies that whole address from the address bar and
|
|
453
|
-
pastes it into the page. The Kit accepts it only when it carries the state its
|
|
454
|
-
own consent issued, exchanges the code with its PKCE verifier and the built
|
|
455
|
-
client, and stores the grant locally. An address that answers another consent,
|
|
456
|
-
or a code Google refuses to exchange, fails the login and stores nothing; a
|
|
457
|
-
declined consent cancels it. Grants already completed for earlier services stay.
|
|
458
|
-
|
|
459
|
-
`kit source sign-in <instance>` signs in a custom connector instance through
|
|
460
|
-
its own command, described below. It skips an instance whose local
|
|
461
|
-
authorization is already valid and answers `ready`, `skipped`, or
|
|
462
|
-
`needs_attention`. A Google instance refuses it as `kit_connector_login_guided`
|
|
463
|
-
and names House setup.
|
|
432
|
+
A failed occurrence records its cause. A Google 403 for an API disabled in the
|
|
433
|
+
client's project fails as `api_disabled`, and `kit source status` names the API
|
|
434
|
+
to enable; a revoked scope (`google_scope_revoked`), an expired or revoked grant
|
|
435
|
+
(`google_authority_revoked`) and a provider failure
|
|
436
|
+
(`google_provider_unavailable`) keep their own codes.
|
|
464
437
|
|
|
465
438
|
## Environment setup
|
|
466
439
|
|
|
@@ -577,8 +550,10 @@ An object whose content changes without its native version changing keeps its
|
|
|
577
550
|
key and is refused by House as a delivery-key conflict rather than silently
|
|
578
551
|
overwriting the earlier Record.
|
|
579
552
|
|
|
580
|
-
The same command owns its module authorization. `kit source sign-in
|
|
581
|
-
|
|
553
|
+
The same command owns its module authorization. `kit source sign-in <instance>`
|
|
554
|
+
skips an instance whose local authorization is already valid and answers
|
|
555
|
+
`ready`, `skipped`, or `needs_attention`. It and the setup walk's status check
|
|
556
|
+
send one JSON line
|
|
582
557
|
with `action: "authorization"` and `mode: "status"` or `mode: "login"`; the
|
|
583
558
|
command returns exactly one JSON object such as `{ "authorized": true }`.
|
|
584
559
|
|
|
@@ -653,27 +628,12 @@ inside `/agents/house` is somebody else's default or an owner's own workspace,
|
|
|
653
628
|
never this Agent's. Every path that is not this exact equality, one deeper
|
|
654
629
|
inside `/agents/house` included, must
|
|
655
630
|
already exist in this Environment as a directory the installation can enter;
|
|
656
|
-
Kit never creates
|
|
657
|
-
|
|
658
|
-
When the Agent's own default directory is absent, Kit
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
directory and uses the directory the winner put there, so the pair still leaves
|
|
663
|
-
one complete directory and nothing partial. A present default directory -
|
|
664
|
-
including one whose starter files the owner edited or removed - launches
|
|
665
|
-
exactly as it is, and a deleted default directory is recreated with a fresh
|
|
666
|
-
starter set on its next launch.
|
|
667
|
-
|
|
668
|
-
The starter set is `AGENTS.md` with the single line ``The agents.house `house`
|
|
669
|
-
CLI is available: run `house --help`.``, `CLAUDE.md` as a relative symbolic link to it, `.agents/skills/grilling/`
|
|
670
|
-
vendored from [`mattpocock/skills`](https://github.com/mattpocock/skills)
|
|
671
|
-
`skills/productivity/grilling` at a pinned commit with its MIT license and a
|
|
672
|
-
provenance header naming that commit, and `.claude/skills` as a relative
|
|
673
|
-
symbolic link to `.agents/skills`. Once seeded the files belong to the owner:
|
|
674
|
-
Kit never syncs, refreshes, or restores them, and refreshing the vendored skill
|
|
675
|
-
for new Agents is an ordinary Kit release that never touches an already seeded
|
|
676
|
-
directory.
|
|
631
|
+
Kit never creates it.
|
|
632
|
+
|
|
633
|
+
When the Agent's own default directory is absent, Kit creates it empty; two
|
|
634
|
+
concurrent first launches create the same directory. A present default
|
|
635
|
+
directory launches exactly as it is, and a deleted one is created empty again
|
|
636
|
+
on its next launch. Kit writes no file into any working directory.
|
|
677
637
|
|
|
678
638
|
A relative, missing, inaccessible, or non-directory working directory refuses
|
|
679
639
|
with `kit_launch_directory_unavailable` before any provider process starts. Kit falls back to no other location - not the
|
|
@@ -681,6 +641,52 @@ base, not `$HOUSE_KIT_HOME`, and not its own current directory - and neither
|
|
|
681
641
|
connecting an installation nor launching a session moves, copies, overwrites,
|
|
682
642
|
or removes anything a working directory holds.
|
|
683
643
|
|
|
644
|
+
## The Skill set
|
|
645
|
+
|
|
646
|
+
The Skill set is every skill the `mattpocock/skills` plugin manifest names at
|
|
647
|
+
one pinned commit but `setup-matt-pocock-skills`, `triage` and `wizard`. Each
|
|
648
|
+
is vendored under `src/skill-set/<name>/` with every file it ships, the
|
|
649
|
+
upstream MIT `LICENSE` and a provenance header in `SKILL.md` naming the commit
|
|
650
|
+
and upstream path. Nothing else is edited but two lines: a
|
|
651
|
+
`disable-model-invocation: true` frontmatter line in `SKILL.md` and an
|
|
652
|
+
`allow_implicit_invocation: false` line in `agents/openai.yaml` are removed, so
|
|
653
|
+
an agent reaches every skill without being told its name.
|
|
654
|
+
|
|
655
|
+
Kit installs the Skill set once for the Environment, for every Agent whatever
|
|
656
|
+
its working directory, under the home it launches agent CLIs with: each skill
|
|
657
|
+
as the directory `$HOME/.agents/skills/<name>`, which Codex and Grok Build
|
|
658
|
+
read, and a relative symbolic link `$HOME/.claude/skills/<name>` to it, which
|
|
659
|
+
Claude Code reads; when `$HOME/.claude/skills` already resolves to
|
|
660
|
+
`$HOME/.agents/skills`, Claude Code reads the directory there and Kit makes no
|
|
661
|
+
link. In a container that home is Kit home, so the set survives
|
|
662
|
+
container recreation; on a native host it is the host user's home.
|
|
663
|
+
|
|
664
|
+
`$HOUSE_KIT_HOME/state/skill-set.json` records the names Kit installed and the
|
|
665
|
+
Kit version that installed them, and Kit owns exactly those names: the
|
|
666
|
+
directory and the link of each. At start and on every resident pass, when
|
|
667
|
+
the set is accepted and the record names another version or none, Kit deletes
|
|
668
|
+
every recorded name, installs the current Skill set and rewrites the record. A
|
|
669
|
+
name whose directory or link exists without being recorded is the owner's: Kit
|
|
670
|
+
leaves it untouched and installs nothing under it. Kit never compares, merges
|
|
671
|
+
or restores a file, so an edit to an installed skill is lost at the next
|
|
672
|
+
release and a copy under another name is kept. When `skills` is `false`, Kit
|
|
673
|
+
deletes every recorded name and the record and installs nothing.
|
|
674
|
+
|
|
675
|
+
After Kit first installs the Skill set, the first Session it launches whose
|
|
676
|
+
Profile ceiling lets it write the owner's How-we-work document
|
|
677
|
+
`/private/library/how-we-work.md` creates it, when it is absent, with the text
|
|
678
|
+
Kit ships in `src/how-we-work.md`, over the Session's own bridge before its
|
|
679
|
+
first prompt is built. Kit then notes in `$HOUSE_KIT_HOME/state/how-we-work`,
|
|
680
|
+
apart from the record, that the document exists, and a present document is
|
|
681
|
+
noted the same way without being touched. Nothing ever creates it again: a
|
|
682
|
+
release, a declined Skill set and a later acceptance leave the note, so an
|
|
683
|
+
owner's edit stands and a deleted document stays deleted. A Session whose
|
|
684
|
+
ceiling cannot write the document launches without it and leaves it for the
|
|
685
|
+
next one; any other refused creation refuses the attempt as
|
|
686
|
+
`kit_how_we_work_unwritable` with House's answer before a prompt is sent. A
|
|
687
|
+
Skill set Kit cannot install or remove refuses the pass as
|
|
688
|
+
`kit_skill_set_unavailable` and names the path.
|
|
689
|
+
|
|
684
690
|
## The declared agent CLIs
|
|
685
691
|
|
|
686
692
|
The Environment owner installs no adapter binary by hand. `kit agents update`
|
|
@@ -1165,8 +1171,8 @@ on the door's own deduplication. When House stops a batch early, its answer
|
|
|
1165
1171
|
settles only the prefix it reached, and the unsettled tail is reoffered with the
|
|
1166
1172
|
rest. The loop repeats while the connector still returns items and no Room
|
|
1167
1173
|
destination is blocked, and every run ends by writing the service's health into
|
|
1168
|
-
this installation's own state. House holds no
|
|
1169
|
-
or health
|
|
1174
|
+
this installation's own state. House holds no custom connector's service, route,
|
|
1175
|
+
checkpoint or health, and no Google entry's checkpoint or health.
|
|
1170
1176
|
|
|
1171
1177
|
A Capture item that declares a `file` attachment answers one Record per Room
|
|
1172
1178
|
destination: Rooms of one owner share that owner's Record, and a Room of another
|
|
@@ -1708,8 +1714,16 @@ $HOUSE_KIT_HOME/
|
|
|
1708
1714
|
state/conversation-originals/<attachment identity>.json
|
|
1709
1715
|
state/sessions/<tmux session>.json
|
|
1710
1716
|
state/update-drain
|
|
1717
|
+
state/skill-set.json
|
|
1718
|
+
state/how-we-work
|
|
1711
1719
|
state/continuations/<run identity>.json
|
|
1712
|
-
state
|
|
1720
|
+
state/google/entries/<source>.json
|
|
1721
|
+
state/google/credentials/<account>.json
|
|
1722
|
+
state/google/checkpoints/<source>.json
|
|
1723
|
+
state/google/health/<source>.json
|
|
1724
|
+
state/google/gaps/<source>.json
|
|
1725
|
+
state/google/dropped/<source>.json
|
|
1726
|
+
state/google/originals/<source>.json
|
|
1713
1727
|
state/<instance>/checkpoints/<service>.json
|
|
1714
1728
|
state/<instance>/health/<service>.json
|
|
1715
1729
|
state/<instance>/gaps/<service>.json
|
|
@@ -1719,15 +1733,18 @@ $HOUSE_KIT_HOME/
|
|
|
1719
1733
|
|
|
1720
1734
|
Every file is written atomically and readable only by its owner. A file the Kit
|
|
1721
1735
|
cannot read is refused rather than treated as a service that never captured.
|
|
1722
|
-
|
|
1723
|
-
|
|
1736
|
+
A Google entry's state is keyed by its Source reference and lives only while
|
|
1737
|
+
House lists the entry. Disabling a custom service or instance leaves its state
|
|
1738
|
+
in place, so re-enabling resumes from the stored cursor instead of importing
|
|
1739
|
+
again.
|
|
1724
1740
|
|
|
1725
1741
|
```sh
|
|
1726
1742
|
kit source reset acme # every service
|
|
1727
1743
|
kit source reset acme notes # one service
|
|
1728
1744
|
```
|
|
1729
1745
|
|
|
1730
|
-
Reset is the only deletion of captured
|
|
1746
|
+
Reset serves custom connectors, and is the only deletion of their captured
|
|
1747
|
+
state. It removes the named checkpoints
|
|
1731
1748
|
and their outstanding retained references so the next capture restarts exactly at
|
|
1732
1749
|
the configured backfill boundary. It takes the same
|
|
1733
1750
|
Environment control lease a capture takes, so it cannot delete a checkpoint a
|
|
@@ -1947,10 +1964,7 @@ workspaces.
|
|
|
1947
1964
|
```sh
|
|
1948
1965
|
docker compose -f test/compose.yaml build kit
|
|
1949
1966
|
docker compose -f test/compose.yaml run --rm kit npm test
|
|
1950
|
-
docker compose -f test/compose.yaml run --rm
|
|
1951
|
-
-e HOUSE_KIT_GOOGLE_OAUTH_CLIENT_ID=kit-client.apps.googleusercontent.com \
|
|
1952
|
-
-e HOUSE_KIT_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-kit-installed-app \
|
|
1953
|
-
kit npm run build
|
|
1967
|
+
docker compose -f test/compose.yaml run --rm kit npm run build
|
|
1954
1968
|
```
|
|
1955
1969
|
|
|
1956
1970
|
`test/pair/run.sh` boots real Core, Auth and PostgreSQL and runs the installed
|
package/bin/connect-linux.sh
CHANGED
|
@@ -6,6 +6,7 @@ NAME='house-kit'
|
|
|
6
6
|
HOUSE='https://agents.house'
|
|
7
7
|
WORKSPACE="$HOME/AgentsHouse"
|
|
8
8
|
MANUAL=0
|
|
9
|
+
SKILLS=true
|
|
9
10
|
WORKSPACE_SELECTED=0
|
|
10
11
|
HOUSE_SELECTED=0
|
|
11
12
|
FORWARDING=0
|
|
@@ -160,6 +161,10 @@ while (($#)); do
|
|
|
160
161
|
MANUAL=1
|
|
161
162
|
shift
|
|
162
163
|
;;
|
|
164
|
+
--no-skills)
|
|
165
|
+
SKILLS=false
|
|
166
|
+
shift
|
|
167
|
+
;;
|
|
163
168
|
*) refuse "unknown argument $1" ;;
|
|
164
169
|
esac
|
|
165
170
|
done
|
|
@@ -208,6 +213,16 @@ if [[ -f "$KIT_HOME/house" ]]; then
|
|
|
208
213
|
HOUSE="$BOUND_HOUSE"
|
|
209
214
|
fi
|
|
210
215
|
[[ "$HOUSE" == https://* || "$HOUSE" == http://127.0.0.1:* || "$HOUSE" == http://localhost:* ]] || refuse 'House origin must use HTTPS or local loopback HTTP'
|
|
216
|
+
if ((FORWARDING == 0)); then
|
|
217
|
+
if [[ ! -f "$KIT_HOME/kit.json" ]]; then
|
|
218
|
+
printf '{"availability":"intermittent","execution_authority":"allow","migrators":[],"instances":[],"clients":[],"host":null,"skills":%s}\n' "$SKILLS" > "$KIT_HOME/kit.json"
|
|
219
|
+
elif grep -Eq '"skills"[[:space:]]*:' "$KIT_HOME/kit.json"; then
|
|
220
|
+
sed -E -i "s/(\"skills\"[[:space:]]*:[[:space:]]*)(true|false)/\\1$SKILLS/" "$KIT_HOME/kit.json" || refuse 'kit.json could not be updated'
|
|
221
|
+
else
|
|
222
|
+
sed -E -i "1s/^([[:space:]]*)\\{/\\1{\"skills\":$SKILLS,/" "$KIT_HOME/kit.json" || refuse 'kit.json could not be updated'
|
|
223
|
+
fi
|
|
224
|
+
grep -Eq "\"skills\"[[:space:]]*:[[:space:]]*$SKILLS" "$KIT_HOME/kit.json" || refuse 'kit.json could not be updated'
|
|
225
|
+
fi
|
|
211
226
|
DOCKER_RUN=(docker run --rm --network host --user "$(id -u):$(id -g)" --mount "$KIT_HOME_MOUNT" --mount "$WORKSPACE_MOUNT" --env HOME=/kit-home --env HOUSE_KIT_HOME=/kit-home --env HOUSE_KIT_CONTAINER=1 --env "HOUSE_KIT_HOSTNAME=$(hostname)" "$IMAGE")
|
|
212
227
|
|
|
213
228
|
if docker container inspect "$NAME" >/dev/null 2>&1; then
|
|
@@ -271,10 +286,6 @@ fi
|
|
|
271
286
|
|
|
272
287
|
docker pull --quiet --platform "linux/$ARCH" "$IMAGE" >/dev/null
|
|
273
288
|
|
|
274
|
-
if [[ ! -f "$KIT_HOME/kit.json" ]]; then
|
|
275
|
-
printf '{"availability":"intermittent","execution_authority":"allow","migrators":[],"instances":[],"clients":[],"host":null}\n' > "$KIT_HOME/kit.json"
|
|
276
|
-
fi
|
|
277
|
-
|
|
278
289
|
if [[ -f "$KIT_HOME/credential" ]]; then
|
|
279
290
|
"${DOCKER_RUN[@]}" credential check
|
|
280
291
|
else
|