@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 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.26/connect-linux.sh)
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 and agent CLI work, while the
55
- Sessions it supervises keep their renewal, owner stops, answers and reports.
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
- that can be published by supplying House's dedicated installed-application
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`. Both values are
155
- public instance content fixed into that package at build time: Google issues an
156
- installed application's client secret without treating it as confidential, and
157
- still requires it in every token request. The installed Kit does not read either
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
- The published Kit is built with one House-owned Google installed-application
364
- OAuth client. Its id and client secret are public build-time instance content,
365
- not House secrets and not values served by House at run time. Google refresh
366
- and access tokens remain in the installation's local credential store.
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
- Each Google instance represents one Google account, and one Kit installation
369
- may declare as many as the User has. Each instance owns its own local Google
370
- authorization, selectors, Source references, Room routes, checkpoints and
371
- health under `state/<instance>/`; the installation's one `kit login` covers
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
- Google authorization is incremental. Enabling Gmail requests only Gmail's
416
- read-only scope; Calendar and Drive request their own read-only scopes only
417
- when enabled. Each service scope set has its own local provider grant, so a
418
- later authorization never widens or replaces a sibling service's grant.
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 instance signs in only through [Environment setup](#environment-setup),
461
- on House's owner-authenticated page, so the owner's browser never has to reach
462
- this Environment. For each enabled service whose scopes the instance does not
463
- hold yet, the page links to Google's consent for exactly that service's scopes.
464
- Google then sends the browser to a `http://127.0.0.1:<port>/` address that
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` and the
594
- setup walk's status check send one JSON line
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 preset, service, route, checkpoint
1213
- or health of yours.
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/<instance>/credentials/google.json
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
- Disabling a service or an instance leaves its state in place, so re-enabling
1769
- resumes from the stored cursor instead of importing again.
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 state. It removes the named checkpoints
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|reset|retry-files> <instance> [service] [--config <path>]\n" +
41
- " kit source status <instance> [service] [--config <path>]\n" +
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
- house,
194
- directory,
195
- configuration: values["--config"] ?? join(directory, "kit.json"),
196
- signal: cancellation.signal,
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 result = await captureSource(
272
- {
273
- house,
274
- directory,
275
- configuration: values["--config"] ?? join(directory, "kit.json"),
276
- instance: rest[0],
277
- service: rest[1] ?? null,
278
- signal: cancellation.signal,
279
- },
280
- { googleOAuthClient: builtGoogleOAuthClient },
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 result = await sourceStatus({
336
- directory,
337
- configuration: values["--config"] ?? join(directory, "kit.json"),
338
- instance: rest[0],
339
- service: rest[1] ?? null,
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
- house,
431
- directory,
432
- configuration: values["--config"] ?? join(directory, "kit.json"),
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.26",
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.26/connect-linux.sh)",
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.26/connect-linux.sh"
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentshouse/kit",
3
- "version": "0.1.0-alpha.26",
3
+ "version": "0.1.0-alpha.27",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",