@agentshouse/kit 0.1.0-alpha.26 → 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 +104 -136
- package/bin/kit.js +48 -46
- package/bootstrap.json +3 -3
- package/package.json +1 -1
- package/src/configuration.js +9 -209
- package/src/connector-login.js +3 -84
- package/src/contract.js +4 -0
- package/src/delivery.js +4 -7
- 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/kit-work-stream.js +1 -1
- package/src/setup.js +8 -14
- package/src/source.js +51 -26
- package/src/state.js +19 -1
- package/src/tasks.js +72 -0
- package/src/worker.js +26 -60
- 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/README.md
CHANGED
|
@@ -12,7 +12,7 @@ The Skill set Kit installs is Matt Pocock's
|
|
|
12
12
|
On Linux `amd64` or `arm64`, run the published, versioned bootstrap once:
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
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)
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
The bootstrap first establishes Docker Engine from what it observes on the
|
|
@@ -51,8 +51,10 @@ the set again.
|
|
|
51
51
|
Running a newer release's bootstrap the same way is the only update. When the
|
|
52
52
|
installed container runs another image, the bootstrap pulls this release's
|
|
53
53
|
image and asks the running resident Kit to drain with `kit resident drain`. The
|
|
54
|
-
resident stops acquiring Runs, resumptions, setup
|
|
55
|
-
|
|
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.
|
|
56
58
|
While any Agent Session is still running or unreported, including one whose Run
|
|
57
59
|
was being acquired when the drain began, the bootstrap names it and leaves the
|
|
58
60
|
container as it is; rerun it once they end. Once nothing remains,
|
|
@@ -141,21 +143,17 @@ anything reaches House.
|
|
|
141
143
|
|
|
142
144
|
## Building the package
|
|
143
145
|
|
|
144
|
-
The repository checkout is the development source. Build the package
|
|
145
|
-
|
|
146
|
-
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:
|
|
147
148
|
|
|
148
149
|
```sh
|
|
149
|
-
HOUSE_KIT_GOOGLE_OAUTH_CLIENT_ID=kit-client.apps.googleusercontent.com \
|
|
150
|
-
HOUSE_KIT_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-kit-installed-app \
|
|
151
150
|
npm run build
|
|
152
151
|
```
|
|
153
152
|
|
|
154
|
-
The command writes the publishable package to `dist/package`.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
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.
|
|
159
157
|
|
|
160
158
|
Runtime dependencies stay minimal and exactly pinned in `package.json` and
|
|
161
159
|
`package-lock.json`: House's own `@agentshouse/mdmodel`, `yaml`, which reads
|
|
@@ -254,7 +252,8 @@ mode: `"intermittent"` for a laptop or other normally offline placement,
|
|
|
254
252
|
any other value refuses as `kit_configuration_invalid`; `kit apply` sends the
|
|
255
253
|
declared mode with the rest of the desired state. An
|
|
256
254
|
instance declares one or more services, and under the `custom` preset each
|
|
257
|
-
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`.
|
|
258
257
|
|
|
259
258
|
`host` declares the Linux host this installation measures for
|
|
260
259
|
[host capacity reporting](#host-capacity). `null` declares that this Kit reports
|
|
@@ -360,120 +359,81 @@ refuses as `kit_hook_rejected` instead of leaving whatever was installed before.
|
|
|
360
359
|
|
|
361
360
|
## The Google preset
|
|
362
361
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
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.
|
|
367
420
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
them all, and no instance can read another's provider credential.
|
|
373
|
-
|
|
374
|
-
```json
|
|
375
|
-
{
|
|
376
|
-
"availability": "intermittent",
|
|
377
|
-
"execution_authority": "refuse",
|
|
378
|
-
"migrators": [],
|
|
379
|
-
"instances": [
|
|
380
|
-
{
|
|
381
|
-
"id": "google-account",
|
|
382
|
-
"preset": "google",
|
|
383
|
-
"scopes": ["https://www.googleapis.com/auth/contacts.readonly"],
|
|
384
|
-
"services": [
|
|
385
|
-
{
|
|
386
|
-
"service": "gmail",
|
|
387
|
-
"source_ref": "src_google_mail",
|
|
388
|
-
"rooms": ["work-room"],
|
|
389
|
-
"backfill": { "days": 30 },
|
|
390
|
-
"selection": { "labels": ["INBOX"] }
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
"service": "calendar",
|
|
394
|
-
"source_ref": "src_google_calendar",
|
|
395
|
-
"rooms": ["work-room"],
|
|
396
|
-
"backfill": { "all": true },
|
|
397
|
-
"selection": { "calendars": ["primary"] }
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
"service": "drive",
|
|
401
|
-
"source_ref": "src_google_drive",
|
|
402
|
-
"rooms": ["work-room"],
|
|
403
|
-
"backfill": { "count": 500 },
|
|
404
|
-
"selection": { "files": ["file-id"], "folders": ["folder-id"] }
|
|
405
|
-
}
|
|
406
|
-
]
|
|
407
|
-
}
|
|
408
|
-
],
|
|
409
|
-
"clients": [],
|
|
410
|
-
"host": null,
|
|
411
|
-
"skills": false
|
|
412
|
-
}
|
|
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
|
|
413
425
|
```
|
|
414
426
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
Additional Google API scopes are declared once on the preset instance and
|
|
420
|
-
remain local; a declared service names only scopes that instance already
|
|
421
|
-
holds. Drive requires at least one explicit file or folder selection and never
|
|
422
|
-
defaults to the whole account.
|
|
423
|
-
|
|
424
|
-
A Google API outside the three curated services may use the closed declared
|
|
425
|
-
service schema. The declaration is data only: no script or executable transform
|
|
426
|
-
is loaded. Its host must be a Google API domain and it runs under scopes the
|
|
427
|
-
instance already holds.
|
|
428
|
-
|
|
429
|
-
```json
|
|
430
|
-
{
|
|
431
|
-
"service": "people",
|
|
432
|
-
"source_ref": "src_google_people",
|
|
433
|
-
"rooms": ["work-room"],
|
|
434
|
-
"backfill": { "all": true },
|
|
435
|
-
"declaration": {
|
|
436
|
-
"host": "people.googleapis.com",
|
|
437
|
-
"path": "/v1/people/me/connections",
|
|
438
|
-
"query": { "personFields": "names,emailAddresses,metadata" },
|
|
439
|
-
"page_size": "pageSize",
|
|
440
|
-
"scopes": ["https://www.googleapis.com/auth/contacts.readonly"],
|
|
441
|
-
"page_token": {
|
|
442
|
-
"request": "pageToken",
|
|
443
|
-
"response": "nextPageToken",
|
|
444
|
-
"checkpoint_request": "syncToken",
|
|
445
|
-
"checkpoint_response": "nextSyncToken"
|
|
446
|
-
},
|
|
447
|
-
"items": "connections",
|
|
448
|
-
"fields": {
|
|
449
|
-
"native_id": "resourceName",
|
|
450
|
-
"native_version": "etag",
|
|
451
|
-
"provider_modified_at": "metadata.sources.0.updateTime",
|
|
452
|
-
"observed_at": "metadata.sources.0.updateTime",
|
|
453
|
-
"body": ["names.0.displayName", "emailAddresses.0.value"],
|
|
454
|
-
"container": "metadata.sources.0.type"
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
```
|
|
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.
|
|
459
431
|
|
|
460
|
-
A Google
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
nothing answers: the owner copies that whole address from the address bar and
|
|
466
|
-
pastes it into the page. The Kit accepts it only when it carries the state its
|
|
467
|
-
own consent issued, exchanges the code with its PKCE verifier and the built
|
|
468
|
-
client, and stores the grant locally. An address that answers another consent,
|
|
469
|
-
or a code Google refuses to exchange, fails the login and stores nothing; a
|
|
470
|
-
declined consent cancels it. Grants already completed for earlier services stay.
|
|
471
|
-
|
|
472
|
-
`kit source sign-in <instance>` signs in a custom connector instance through
|
|
473
|
-
its own command, described below. It skips an instance whose local
|
|
474
|
-
authorization is already valid and answers `ready`, `skipped`, or
|
|
475
|
-
`needs_attention`. A Google instance refuses it as `kit_connector_login_guided`
|
|
476
|
-
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.
|
|
477
437
|
|
|
478
438
|
## Environment setup
|
|
479
439
|
|
|
@@ -590,8 +550,10 @@ An object whose content changes without its native version changing keeps its
|
|
|
590
550
|
key and is refused by House as a delivery-key conflict rather than silently
|
|
591
551
|
overwriting the earlier Record.
|
|
592
552
|
|
|
593
|
-
The same command owns its module authorization. `kit source sign-in
|
|
594
|
-
|
|
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
|
|
595
557
|
with `action: "authorization"` and `mode: "status"` or `mode: "login"`; the
|
|
596
558
|
command returns exactly one JSON object such as `{ "authorized": true }`.
|
|
597
559
|
|
|
@@ -1209,8 +1171,8 @@ on the door's own deduplication. When House stops a batch early, its answer
|
|
|
1209
1171
|
settles only the prefix it reached, and the unsettled tail is reoffered with the
|
|
1210
1172
|
rest. The loop repeats while the connector still returns items and no Room
|
|
1211
1173
|
destination is blocked, and every run ends by writing the service's health into
|
|
1212
|
-
this installation's own state. House holds no
|
|
1213
|
-
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.
|
|
1214
1176
|
|
|
1215
1177
|
A Capture item that declares a `file` attachment answers one Record per Room
|
|
1216
1178
|
destination: Rooms of one owner share that owner's Record, and a Room of another
|
|
@@ -1755,7 +1717,13 @@ $HOUSE_KIT_HOME/
|
|
|
1755
1717
|
state/skill-set.json
|
|
1756
1718
|
state/how-we-work
|
|
1757
1719
|
state/continuations/<run identity>.json
|
|
1758
|
-
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
|
|
1759
1727
|
state/<instance>/checkpoints/<service>.json
|
|
1760
1728
|
state/<instance>/health/<service>.json
|
|
1761
1729
|
state/<instance>/gaps/<service>.json
|
|
@@ -1765,15 +1733,18 @@ $HOUSE_KIT_HOME/
|
|
|
1765
1733
|
|
|
1766
1734
|
Every file is written atomically and readable only by its owner. A file the Kit
|
|
1767
1735
|
cannot read is refused rather than treated as a service that never captured.
|
|
1768
|
-
|
|
1769
|
-
|
|
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.
|
|
1770
1740
|
|
|
1771
1741
|
```sh
|
|
1772
1742
|
kit source reset acme # every service
|
|
1773
1743
|
kit source reset acme notes # one service
|
|
1774
1744
|
```
|
|
1775
1745
|
|
|
1776
|
-
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
|
|
1777
1748
|
and their outstanding retained references so the next capture restarts exactly at
|
|
1778
1749
|
the configured backfill boundary. It takes the same
|
|
1779
1750
|
Environment control lease a capture takes, so it cannot delete a checkpoint a
|
|
@@ -1993,10 +1964,7 @@ workspaces.
|
|
|
1993
1964
|
```sh
|
|
1994
1965
|
docker compose -f test/compose.yaml build kit
|
|
1995
1966
|
docker compose -f test/compose.yaml run --rm kit npm test
|
|
1996
|
-
docker compose -f test/compose.yaml run --rm
|
|
1997
|
-
-e HOUSE_KIT_GOOGLE_OAUTH_CLIENT_ID=kit-client.apps.googleusercontent.com \
|
|
1998
|
-
-e HOUSE_KIT_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-kit-installed-app \
|
|
1999
|
-
kit npm run build
|
|
1967
|
+
docker compose -f test/compose.yaml run --rm kit npm run build
|
|
2000
1968
|
```
|
|
2001
1969
|
|
|
2002
1970
|
`test/pair/run.sh` boots real Core, Auth and PostgreSQL and runs the installed
|
package/bin/kit.js
CHANGED
|
@@ -5,12 +5,12 @@ import { join, resolve } from "node:path";
|
|
|
5
5
|
import { connectHouse, loginHouse, storedEnvironment, storedHouse } from "../src/login.js";
|
|
6
6
|
import { apply } from "../src/apply.js";
|
|
7
7
|
import { captureSource, resetSource, retrySourceOriginals, sourceStatus } from "../src/source.js";
|
|
8
|
+
import { accountEntries, accountStatus, captureAccount } from "../src/google/entries.js";
|
|
8
9
|
import { setupEnvironment } from "../src/setup.js";
|
|
9
10
|
import { signInConnector } from "../src/connector-login.js";
|
|
10
11
|
import { attachSession } from "../src/attach.js";
|
|
11
12
|
import { runResident, runWorkers } from "../src/worker.js";
|
|
12
13
|
import { openSession, releaseControl, requestDrain } from "../src/house.js";
|
|
13
|
-
import { GOOGLE_OAUTH_CLIENT } from "../src/instance/google.js";
|
|
14
14
|
import { reportHost } from "../src/host.js";
|
|
15
15
|
import { signInAgent, updateAgents } from "../src/agents.js";
|
|
16
16
|
import { serveWorkspaces } from "../src/workspace.js";
|
|
@@ -37,8 +37,8 @@ const AGENTS_USAGE =
|
|
|
37
37
|
"usage: kit agents update [--config <path>] | kit agents sign-in <kind> [--config <path>]";
|
|
38
38
|
const WORKSPACE_USAGE = "usage: kit workspace host [--config <path>] [--passes <count>]";
|
|
39
39
|
const SOURCE_USAGE =
|
|
40
|
-
"usage: kit source <capture|
|
|
41
|
-
" kit source
|
|
40
|
+
"usage: kit source <capture|status> <account|instance> [service] [--config <path>]\n" +
|
|
41
|
+
" kit source <reset|retry-files> <instance> [service] [--config <path>]\n" +
|
|
42
42
|
" kit source sign-in <instance> [--config <path>]";
|
|
43
43
|
const SETUP_USAGE = "usage: kit setup [--config <path>]";
|
|
44
44
|
const REPOSITORY_USAGE =
|
|
@@ -108,13 +108,6 @@ function write(line) {
|
|
|
108
108
|
process.stdout.write(`${line}\n`);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
function builtGoogleOAuthClient() {
|
|
112
|
-
if (GOOGLE_OAUTH_CLIENT === null) {
|
|
113
|
-
throw new KitRefusal("google_oauth_client_unconfigured", "run npm run build");
|
|
114
|
-
}
|
|
115
|
-
return GOOGLE_OAUTH_CLIENT;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
111
|
async function runLogin(args, directory) {
|
|
119
112
|
const { values } = declared(args, ["--house", "--manual", "--host-browser", "--environment"], 0, { flags: ["--host-browser"] });
|
|
120
113
|
if (values["--manual"] && values["--host-browser"]) throw new Error(LOGIN_USAGE);
|
|
@@ -188,15 +181,12 @@ async function runSetup(args, directory) {
|
|
|
188
181
|
process.once("SIGINT", cancel);
|
|
189
182
|
let setup;
|
|
190
183
|
try {
|
|
191
|
-
setup = await setupEnvironment(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
},
|
|
198
|
-
{ googleOAuthClient: builtGoogleOAuthClient },
|
|
199
|
-
);
|
|
184
|
+
setup = await setupEnvironment({
|
|
185
|
+
house,
|
|
186
|
+
directory,
|
|
187
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
188
|
+
signal: cancellation.signal,
|
|
189
|
+
});
|
|
200
190
|
} finally {
|
|
201
191
|
process.removeListener("SIGINT", cancel);
|
|
202
192
|
}
|
|
@@ -268,22 +258,27 @@ async function runSourceCapture(args, directory) {
|
|
|
268
258
|
const house = await storedHouse(directory);
|
|
269
259
|
const cancellation = new AbortController();
|
|
270
260
|
process.once("SIGINT", () => cancellation.abort());
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
261
|
+
const entries = await accountEntries(directory, rest[0]);
|
|
262
|
+
const options = {
|
|
263
|
+
house,
|
|
264
|
+
directory,
|
|
265
|
+
service: rest[1] ?? null,
|
|
266
|
+
signal: cancellation.signal,
|
|
267
|
+
};
|
|
268
|
+
const result =
|
|
269
|
+
entries.length > 0
|
|
270
|
+
? await captureAccount({ ...options, account: rest[0], entries })
|
|
271
|
+
: await captureSource({
|
|
272
|
+
...options,
|
|
273
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
274
|
+
instance: rest[0],
|
|
275
|
+
});
|
|
282
276
|
for (const delivered of result.services) {
|
|
283
277
|
const category =
|
|
284
278
|
delivered.health.category === null ? "" : ` (${delivered.health.category})`;
|
|
279
|
+
const cause = delivered.health.cause === undefined ? "" : `, cause ${delivered.health.cause}`;
|
|
285
280
|
write(
|
|
286
|
-
`Delivered ${delivered.delivered} items for ${result.instance}/${delivered.service} in ${delivered.batches} batches; health ${delivered.health.state}${category}.`,
|
|
281
|
+
`Delivered ${delivered.delivered} items for ${result.instance}/${delivered.service} in ${delivered.batches} batches; health ${delivered.health.state}${category}${cause}.`,
|
|
287
282
|
);
|
|
288
283
|
if (delivered.refused !== null) {
|
|
289
284
|
write(
|
|
@@ -332,22 +327,32 @@ async function runSourceRetryFiles(args, directory) {
|
|
|
332
327
|
async function runSourceStatus(args, directory) {
|
|
333
328
|
const { values, rest } = declared(args, ["--config"], 2);
|
|
334
329
|
if (rest.length === 0) throw new Error(SOURCE_USAGE);
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
330
|
+
const entries = await accountEntries(directory, rest[0]);
|
|
331
|
+
const result =
|
|
332
|
+
entries.length > 0
|
|
333
|
+
? await accountStatus({ directory, account: rest[0], entries, service: rest[1] ?? null })
|
|
334
|
+
: await sourceStatus({
|
|
335
|
+
directory,
|
|
336
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
337
|
+
instance: rest[0],
|
|
338
|
+
service: rest[1] ?? null,
|
|
339
|
+
});
|
|
341
340
|
for (const reported of result.services) {
|
|
342
341
|
const category = reported.health.category === null ? "" : ` (${reported.health.category})`;
|
|
342
|
+
const cause = reported.health.cause === undefined ? "" : `, cause ${reported.health.cause}`;
|
|
343
343
|
const observed =
|
|
344
344
|
reported.health.observed_at === null ? "never observed" : reported.health.observed_at;
|
|
345
|
+
const signedIn =
|
|
346
|
+
reported.signed_in === undefined ? "" : reported.signed_in ? "signed in; " : "signed out; ";
|
|
345
347
|
write(
|
|
346
348
|
`${result.instance}/${reported.service} -> ${reported.source_ref} in ${reported.rooms.join(", ")}: ` +
|
|
347
|
-
`${reported.health.state}${category} at ${observed}; ` +
|
|
349
|
+
`${signedIn}${reported.health.state}${category}${cause} at ${observed}; ` +
|
|
348
350
|
`cursor ${reported.checkpoint?.cursor ?? "none"}, ${reported.gaps.length} gaps, ` +
|
|
349
351
|
`${reported.dropped.length} dropped items, ${reported.originals.length} unsaved originals.`,
|
|
350
352
|
);
|
|
353
|
+
if (reported.enable !== null && reported.enable !== undefined) {
|
|
354
|
+
write(`Enable the ${reported.enable} in the Google Cloud project of ${result.instance}'s OAuth client.`);
|
|
355
|
+
}
|
|
351
356
|
}
|
|
352
357
|
if (result.services.some((reported) => reported.health.state !== "ok")) process.exitCode = 1;
|
|
353
358
|
}
|
|
@@ -425,14 +430,11 @@ function writeConversationFiles(supervised) {
|
|
|
425
430
|
async function runWorkerRun(args, directory) {
|
|
426
431
|
const { values } = declared(args, ["--config"], 0);
|
|
427
432
|
const house = await storedHouse(directory);
|
|
428
|
-
const supervised = await runWorkers(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
},
|
|
434
|
-
{ googleOAuthClient: builtGoogleOAuthClient },
|
|
435
|
-
);
|
|
433
|
+
const supervised = await runWorkers({
|
|
434
|
+
house,
|
|
435
|
+
directory,
|
|
436
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
437
|
+
});
|
|
436
438
|
write(`Worker runtime ready on tmux ${supervised.tmux} in namespace ${supervised.namespace}.`);
|
|
437
439
|
if (supervised.epochReport !== null) {
|
|
438
440
|
write(`House started a new log epoch; reported ${supervised.epochReport.length} held Runs and House settled each.`);
|
package/bootstrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.27",
|
|
4
4
|
"hosts": {
|
|
5
5
|
"linux": {
|
|
6
|
-
"command": "bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.
|
|
6
|
+
"command": "bash <(curl -fsSL https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.27/connect-linux.sh)",
|
|
7
7
|
"asset": {
|
|
8
8
|
"name": "connect-linux.sh",
|
|
9
|
-
"url": "https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.
|
|
9
|
+
"url": "https://github.com/agentshouse/kit/releases/download/v0.1.0-alpha.27/connect-linux.sh"
|
|
10
10
|
},
|
|
11
11
|
"workspace": {
|
|
12
12
|
"argument": "--workspace",
|