@agentshouse/kit 0.1.0-alpha.4 → 0.1.0-alpha.41
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 +41 -1671
- package/bin/connect-linux.sh +501 -53
- package/bin/connect-windows.ps1 +440 -0
- package/bin/kit.js +200 -159
- package/bootstrap.json +28 -0
- package/docs/configuration.md +104 -0
- package/docs/google.md +33 -0
- package/docs/linux.md +77 -0
- package/docs/macos.md +26 -0
- package/docs/telegram.md +29 -0
- package/docs/windows.md +37 -0
- package/package.json +7 -2
- package/src/adapter-mcp.js +92 -12
- package/src/agents.js +63 -8
- package/src/binding.js +52 -0
- package/src/blocks.js +2 -26
- package/src/bridge.js +28 -14
- package/src/bytes.js +19 -8
- package/src/configuration.js +14 -211
- package/src/connector-login.js +3 -84
- package/src/contract.js +44 -12
- package/src/conversation-originals.js +1 -3
- package/src/delivery.js +4 -7
- package/src/directory.js +6 -26
- package/src/draft.js +4 -82
- package/src/git-main.js +138 -0
- package/src/git.js +62 -0
- package/src/google/calendar.js +39 -45
- package/src/google/drive.js +61 -186
- package/src/google/entries.js +349 -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/host.js +6 -2
- package/src/house-main.js +65 -8
- package/src/house.js +446 -127
- package/src/how-we-work.md +25 -0
- package/src/inbound.js +2 -18
- package/src/kit-work-stream.js +120 -0
- package/src/launcher.js +46 -10
- package/src/local-files.js +3 -11
- package/src/login.js +27 -14
- package/src/mcp.js +18 -0
- package/src/mount.js +9 -18
- package/src/original.js +4 -4
- package/src/pacing.js +41 -0
- package/src/plan.js +37 -45
- package/src/repository.js +3 -61
- package/src/session-bin/git +2 -0
- package/src/setup.js +14 -15
- 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 +93 -54
- package/src/state.js +19 -1
- package/src/sync-library.js +7 -11
- package/src/sync-state.js +12 -3
- package/src/sync.js +142 -43
- package/src/tasks.js +92 -0
- package/src/telegram-view.js +217 -0
- package/src/telegram.js +204 -69
- package/src/turn-frames.js +69 -0
- package/src/worker.js +738 -189
- package/src/working-copy.js +1274 -0
- package/src/workspace.js +299 -88
- 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/bin/kit.js
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
|
-
import { connectHouse, storedEnvironment, storedHouse } from "../src/login.js";
|
|
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
|
-
import { openSession, releaseControl } from "../src/house.js";
|
|
13
|
-
import { GOOGLE_OAUTH_CLIENT } from "../src/instance/google.js";
|
|
13
|
+
import { openSession, releaseControl, requestDrain } from "../src/house.js";
|
|
14
14
|
import { reportHost } from "../src/host.js";
|
|
15
15
|
import { signInAgent, updateAgents } from "../src/agents.js";
|
|
16
|
-
import { serveWorkspaces } from "../src/workspace.js";
|
|
16
|
+
import { serveWorkspaces, updateWorkspaces } from "../src/workspace.js";
|
|
17
17
|
import { captureRepository } from "../src/repository.js";
|
|
18
18
|
import { bootstrap, pull, rebootstrap, submit } from "../src/sync.js";
|
|
19
19
|
import { formatMount, formatUnmount, mountPackage, unmountSubtree } from "../src/mount.js";
|
|
@@ -32,44 +32,44 @@ const USAGE =
|
|
|
32
32
|
"usage: kit <login|resident|credential|setup|apply|agents|source|repository|worker|sync|migrate|attachment|host|workspace|telegram> ...";
|
|
33
33
|
const LOGIN_USAGE =
|
|
34
34
|
"usage: kit login [--house <url>] [--environment <uuid>] [--manual|--host-browser]";
|
|
35
|
-
const HOST_USAGE = "usage: kit host report [--
|
|
35
|
+
const HOST_USAGE = "usage: kit host report [--config <path>]";
|
|
36
36
|
const AGENTS_USAGE =
|
|
37
|
-
"usage: kit agents update [--
|
|
38
|
-
const WORKSPACE_USAGE = "usage: kit workspace host [--
|
|
37
|
+
"usage: kit agents update [--config <path>] | kit agents sign-in <kind> [--config <path>]";
|
|
38
|
+
const WORKSPACE_USAGE = "usage: kit workspace host [--config <path>] [--passes <count>] | kit workspace update";
|
|
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
|
-
const SETUP_USAGE = "usage: kit setup [--
|
|
43
|
+
const SETUP_USAGE = "usage: kit setup [--config <path>]";
|
|
44
44
|
const REPOSITORY_USAGE =
|
|
45
|
-
"usage: kit repository capture <checkout> --room <room> --source-handle <handle>
|
|
45
|
+
"usage: kit repository capture <checkout> --room <room> --source-handle <handle>";
|
|
46
46
|
const WORKER_USAGE =
|
|
47
|
-
"usage: kit worker run [--
|
|
47
|
+
"usage: kit worker run [--config <path>] | kit worker attach [<session>]";
|
|
48
48
|
const SYNC_USAGE =
|
|
49
49
|
"usage: kit sync <bootstrap|pull|rebootstrap|submit> ...";
|
|
50
50
|
const SYNC_BOOTSTRAP_USAGE =
|
|
51
|
-
"usage: kit sync bootstrap <directory>
|
|
52
|
-
const SYNC_PULL_USAGE = "usage: kit sync pull <directory>
|
|
53
|
-
const SYNC_REBOOTSTRAP_USAGE = "usage: kit sync rebootstrap <directory>
|
|
51
|
+
"usage: kit sync bootstrap <directory> --prefix <path> [--prefix <path> ...]";
|
|
52
|
+
const SYNC_PULL_USAGE = "usage: kit sync pull <directory>";
|
|
53
|
+
const SYNC_REBOOTSTRAP_USAGE = "usage: kit sync rebootstrap <directory>";
|
|
54
54
|
const SYNC_SUBMIT_USAGE =
|
|
55
|
-
"usage: kit sync submit <directory> [--
|
|
55
|
+
"usage: kit sync submit <directory> [--changes <path>]";
|
|
56
56
|
const MIGRATE_USAGE = "usage: kit migrate <emit|mount|unmount|run> ...";
|
|
57
57
|
const MIGRATE_EMIT_USAGE =
|
|
58
58
|
"usage: kit migrate emit <migrator> --package <directory> [--config <path>]";
|
|
59
59
|
const MIGRATE_MOUNT_USAGE =
|
|
60
|
-
"usage: kit migrate mount <package>
|
|
60
|
+
"usage: kit migrate mount <package> --subtree <path>";
|
|
61
61
|
const MIGRATE_UNMOUNT_USAGE =
|
|
62
|
-
"usage: kit migrate unmount <subtree> [--
|
|
62
|
+
"usage: kit migrate unmount <subtree> [--confirm <subtree>]";
|
|
63
63
|
const MIGRATE_RUN_USAGE =
|
|
64
|
-
"usage: kit migrate run <migrator>
|
|
64
|
+
"usage: kit migrate run <migrator> --subtree <path> --package <directory> [--config <path>]";
|
|
65
65
|
const ATTACHMENT_USAGE = "usage: kit attachment <upload|get> ...";
|
|
66
66
|
const ATTACHMENT_UPLOAD_USAGE =
|
|
67
|
-
"usage: kit attachment upload <file>
|
|
67
|
+
"usage: kit attachment upload <file> (--room <ref> | --private) [--name <name>] [--media-type <type>]";
|
|
68
68
|
const ATTACHMENT_GET_USAGE =
|
|
69
|
-
"usage: kit attachment get
|
|
69
|
+
"usage: kit attachment get --attachment <at_ref> (--room <ref> | --private) [--output <path>]";
|
|
70
70
|
const TELEGRAM_USAGE =
|
|
71
|
-
"usage: kit telegram <connect|disconnect
|
|
72
|
-
" kit telegram serve [--
|
|
71
|
+
"usage: kit telegram <connect|disconnect>\n" +
|
|
72
|
+
" kit telegram serve [--passes <count>]";
|
|
73
73
|
|
|
74
74
|
function declared(argv, accepted, positionals, options = {}) {
|
|
75
75
|
const repeated = options.repeated ?? [];
|
|
@@ -108,21 +108,10 @@ 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
|
-
async function selectedHouse(values, directory) {
|
|
119
|
-
return storedHouse(directory, false, values["--house"]);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
111
|
async function runLogin(args, directory) {
|
|
123
112
|
const { values } = declared(args, ["--house", "--manual", "--host-browser", "--environment"], 0, { flags: ["--host-browser"] });
|
|
124
113
|
if (values["--manual"] && values["--host-browser"]) throw new Error(LOGIN_USAGE);
|
|
125
|
-
const house = await
|
|
114
|
+
const house = await loginHouse(directory, values["--house"]);
|
|
126
115
|
const presentation = values["--manual"] === true ? "manual" : "loopback";
|
|
127
116
|
await connectHouse({
|
|
128
117
|
house,
|
|
@@ -130,17 +119,18 @@ async function runLogin(args, directory) {
|
|
|
130
119
|
directory,
|
|
131
120
|
hostBrowser: values["--host-browser"] === true,
|
|
132
121
|
hostname: process.env.HOUSE_KIT_HOSTNAME,
|
|
122
|
+
loginPort: process.env.HOUSE_KIT_LOGIN_PORT,
|
|
133
123
|
...(values["--environment"] === undefined ? {} : { environment: values["--environment"] }),
|
|
134
124
|
});
|
|
135
125
|
}
|
|
136
126
|
|
|
137
127
|
async function runCredentialCheck(args, directory) {
|
|
138
|
-
|
|
128
|
+
declared(args, [], 0, { exact: true });
|
|
139
129
|
if (await storedEnvironment(directory) === null) throw new KitRefusal("kit_environment_invalid", "no enrolled Environment id");
|
|
140
|
-
const house = await
|
|
130
|
+
const house = await storedHouse(directory);
|
|
141
131
|
let session;
|
|
142
132
|
try {
|
|
143
|
-
session = await openSession({ house, directory });
|
|
133
|
+
session = await openSession({ house, directory, acquire: true });
|
|
144
134
|
} catch (error) {
|
|
145
135
|
if (error instanceof KitRefusal && error.code === "environment_control_lease_active") {
|
|
146
136
|
write("Stored Kit authority is accepted; its Environment already has an active control lease.");
|
|
@@ -153,8 +143,8 @@ async function runCredentialCheck(args, directory) {
|
|
|
153
143
|
}
|
|
154
144
|
|
|
155
145
|
async function runResidentCommand(args, directory) {
|
|
156
|
-
const { values } = declared(args, ["--
|
|
157
|
-
const house = await
|
|
146
|
+
const { values } = declared(args, ["--config"], 0, { exact: true });
|
|
147
|
+
const house = await storedHouse(directory);
|
|
158
148
|
const cancellation = new AbortController();
|
|
159
149
|
const stop = () => cancellation.abort();
|
|
160
150
|
process.once("SIGINT", stop);
|
|
@@ -167,24 +157,37 @@ async function runResidentCommand(args, directory) {
|
|
|
167
157
|
}
|
|
168
158
|
}
|
|
169
159
|
|
|
160
|
+
async function runResidentDrain(args, directory) {
|
|
161
|
+
declared(args, [], 0, { exact: true });
|
|
162
|
+
const answer = await requestDrain(directory);
|
|
163
|
+
if (answer.ready === true) {
|
|
164
|
+
write("House Kit is ready for its update.");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
write(
|
|
168
|
+
answer.sessions.length > 0
|
|
169
|
+
? `House Kit is draining for its update and waits for Agent Sessions ${answer.sessions.join(", ")}.`
|
|
170
|
+
: answer.serving === true
|
|
171
|
+
? "House Kit is draining for its update and waits for the Kit command it serves."
|
|
172
|
+
: `House Kit is draining for its update; House refused its lease release (${answer.refused}).`,
|
|
173
|
+
);
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
170
177
|
async function runSetup(args, directory) {
|
|
171
|
-
const { values } = declared(args, ["--
|
|
172
|
-
const house = await
|
|
173
|
-
if (!house) throw new Error(SETUP_USAGE);
|
|
178
|
+
const { values } = declared(args, ["--config"], 0, { exact: true });
|
|
179
|
+
const house = await storedHouse(directory);
|
|
174
180
|
const cancellation = new AbortController();
|
|
175
181
|
const cancel = () => cancellation.abort();
|
|
176
182
|
process.once("SIGINT", cancel);
|
|
177
183
|
let setup;
|
|
178
184
|
try {
|
|
179
|
-
setup = await setupEnvironment(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
},
|
|
186
|
-
{ googleOAuthClient: builtGoogleOAuthClient },
|
|
187
|
-
);
|
|
185
|
+
setup = await setupEnvironment({
|
|
186
|
+
house,
|
|
187
|
+
directory,
|
|
188
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
189
|
+
signal: cancellation.signal,
|
|
190
|
+
});
|
|
188
191
|
} finally {
|
|
189
192
|
process.removeListener("SIGINT", cancel);
|
|
190
193
|
}
|
|
@@ -223,9 +226,8 @@ async function runSourceSignIn(args, directory) {
|
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
async function runApply(args, directory) {
|
|
226
|
-
const { values } = declared(args, ["--
|
|
227
|
-
const house = await
|
|
228
|
-
if (!house) throw new Error("usage: kit apply --house <url> [--config <path>]");
|
|
229
|
+
const { values } = declared(args, ["--config"], 0);
|
|
230
|
+
const house = await storedHouse(directory);
|
|
229
231
|
const cancellation = new AbortController();
|
|
230
232
|
const cancel = () => cancellation.abort();
|
|
231
233
|
process.once("SIGINT", cancel);
|
|
@@ -252,27 +254,32 @@ async function runApply(args, directory) {
|
|
|
252
254
|
}
|
|
253
255
|
|
|
254
256
|
async function runSourceCapture(args, directory) {
|
|
255
|
-
const { values, rest } = declared(args, ["--
|
|
256
|
-
|
|
257
|
-
|
|
257
|
+
const { values, rest } = declared(args, ["--config"], 2);
|
|
258
|
+
if (rest.length === 0) throw new Error(SOURCE_USAGE);
|
|
259
|
+
const house = await storedHouse(directory);
|
|
258
260
|
const cancellation = new AbortController();
|
|
259
261
|
process.once("SIGINT", () => cancellation.abort());
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
262
|
+
const entries = await accountEntries(directory, rest[0]);
|
|
263
|
+
const options = {
|
|
264
|
+
house,
|
|
265
|
+
directory,
|
|
266
|
+
service: rest[1] ?? null,
|
|
267
|
+
signal: cancellation.signal,
|
|
268
|
+
};
|
|
269
|
+
const result =
|
|
270
|
+
entries.length > 0
|
|
271
|
+
? await captureAccount({ ...options, account: rest[0], entries })
|
|
272
|
+
: await captureSource({
|
|
273
|
+
...options,
|
|
274
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
275
|
+
instance: rest[0],
|
|
276
|
+
});
|
|
271
277
|
for (const delivered of result.services) {
|
|
272
278
|
const category =
|
|
273
279
|
delivered.health.category === null ? "" : ` (${delivered.health.category})`;
|
|
280
|
+
const cause = delivered.health.cause === undefined ? "" : `, cause ${delivered.health.cause}`;
|
|
274
281
|
write(
|
|
275
|
-
`Delivered ${delivered.delivered} items for ${result.instance}/${delivered.service} in ${delivered.batches} batches; health ${delivered.health.state}${category}.`,
|
|
282
|
+
`Delivered ${delivered.delivered} items for ${result.instance}/${delivered.service} in ${delivered.batches} batches; health ${delivered.health.state}${category}${cause}.`,
|
|
276
283
|
);
|
|
277
284
|
if (delivered.refused !== null) {
|
|
278
285
|
write(
|
|
@@ -297,9 +304,9 @@ function writeSourceOriginals(instance, service) {
|
|
|
297
304
|
}
|
|
298
305
|
|
|
299
306
|
async function runSourceRetryFiles(args, directory) {
|
|
300
|
-
const { values, rest } = declared(args, ["--
|
|
301
|
-
|
|
302
|
-
|
|
307
|
+
const { values, rest } = declared(args, ["--config"], 2);
|
|
308
|
+
if (rest.length === 0) throw new Error(SOURCE_USAGE);
|
|
309
|
+
const house = await storedHouse(directory);
|
|
303
310
|
const cancellation = new AbortController();
|
|
304
311
|
process.once("SIGINT", () => cancellation.abort());
|
|
305
312
|
const result = await retrySourceOriginals({
|
|
@@ -321,30 +328,40 @@ async function runSourceRetryFiles(args, directory) {
|
|
|
321
328
|
async function runSourceStatus(args, directory) {
|
|
322
329
|
const { values, rest } = declared(args, ["--config"], 2);
|
|
323
330
|
if (rest.length === 0) throw new Error(SOURCE_USAGE);
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
const entries = await accountEntries(directory, rest[0]);
|
|
332
|
+
const result =
|
|
333
|
+
entries.length > 0
|
|
334
|
+
? await accountStatus({ directory, account: rest[0], entries, service: rest[1] ?? null })
|
|
335
|
+
: await sourceStatus({
|
|
336
|
+
directory,
|
|
337
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
338
|
+
instance: rest[0],
|
|
339
|
+
service: rest[1] ?? null,
|
|
340
|
+
});
|
|
330
341
|
for (const reported of result.services) {
|
|
331
342
|
const category = reported.health.category === null ? "" : ` (${reported.health.category})`;
|
|
343
|
+
const cause = reported.health.cause === undefined ? "" : `, cause ${reported.health.cause}`;
|
|
332
344
|
const observed =
|
|
333
345
|
reported.health.observed_at === null ? "never observed" : reported.health.observed_at;
|
|
346
|
+
const signedIn =
|
|
347
|
+
reported.signed_in === undefined ? "" : reported.signed_in ? "signed in; " : "signed out; ";
|
|
334
348
|
write(
|
|
335
349
|
`${result.instance}/${reported.service} -> ${reported.source_ref} in ${reported.rooms.join(", ")}: ` +
|
|
336
|
-
`${reported.health.state}${category} at ${observed}; ` +
|
|
350
|
+
`${signedIn}${reported.health.state}${category}${cause} at ${observed}; ` +
|
|
337
351
|
`cursor ${reported.checkpoint?.cursor ?? "none"}, ${reported.gaps.length} gaps, ` +
|
|
338
352
|
`${reported.dropped.length} dropped items, ${reported.originals.length} unsaved originals.`,
|
|
339
353
|
);
|
|
354
|
+
if (reported.enable !== null && reported.enable !== undefined) {
|
|
355
|
+
write(`Enable the ${reported.enable} in the Google Cloud project of ${result.instance}'s OAuth client.`);
|
|
356
|
+
}
|
|
340
357
|
}
|
|
341
358
|
if (result.services.some((reported) => reported.health.state !== "ok")) process.exitCode = 1;
|
|
342
359
|
}
|
|
343
360
|
|
|
344
361
|
async function runSourceReset(args, directory) {
|
|
345
|
-
const { values, rest } = declared(args, ["--
|
|
346
|
-
|
|
347
|
-
|
|
362
|
+
const { values, rest } = declared(args, ["--config"], 2);
|
|
363
|
+
if (rest.length === 0) throw new Error(SOURCE_USAGE);
|
|
364
|
+
const house = await storedHouse(directory);
|
|
348
365
|
const result = await resetSource({
|
|
349
366
|
house,
|
|
350
367
|
directory,
|
|
@@ -360,11 +377,11 @@ async function runSourceReset(args, directory) {
|
|
|
360
377
|
}
|
|
361
378
|
|
|
362
379
|
async function runRepositoryCapture(args, directory) {
|
|
363
|
-
const { values, rest } = declared(args, ["--
|
|
364
|
-
const house = await selectedHouse(values, directory);
|
|
380
|
+
const { values, rest } = declared(args, ["--room", "--source-handle"], 1);
|
|
365
381
|
const room = values["--room"];
|
|
366
382
|
const sourceHandle = values["--source-handle"];
|
|
367
|
-
if (!
|
|
383
|
+
if (!room || !sourceHandle || rest.length !== 1) throw new Error(REPOSITORY_USAGE);
|
|
384
|
+
const house = await storedHouse(directory);
|
|
368
385
|
const cancellation = new AbortController();
|
|
369
386
|
const cancel = () => cancellation.abort();
|
|
370
387
|
process.once("SIGINT", cancel);
|
|
@@ -412,17 +429,13 @@ function writeConversationFiles(supervised) {
|
|
|
412
429
|
}
|
|
413
430
|
|
|
414
431
|
async function runWorkerRun(args, directory) {
|
|
415
|
-
const { values } = declared(args, ["--
|
|
416
|
-
const house = await
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
423
|
-
},
|
|
424
|
-
{ googleOAuthClient: builtGoogleOAuthClient },
|
|
425
|
-
);
|
|
432
|
+
const { values } = declared(args, ["--config"], 0);
|
|
433
|
+
const house = await storedHouse(directory);
|
|
434
|
+
const supervised = await runWorkers({
|
|
435
|
+
house,
|
|
436
|
+
directory,
|
|
437
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
438
|
+
});
|
|
426
439
|
write(`Worker runtime ready on tmux ${supervised.tmux} in namespace ${supervised.namespace}.`);
|
|
427
440
|
if (supervised.epochReport !== null) {
|
|
428
441
|
write(`House started a new log epoch; reported ${supervised.epochReport.length} held Runs and House settled each.`);
|
|
@@ -466,8 +479,10 @@ async function runWorkerRun(args, directory) {
|
|
|
466
479
|
`Run ${run.run} stays bound to this installation until House accepts that report` +
|
|
467
480
|
`${run.refused === null ? "" : ` (${run.refused.code})`}.`,
|
|
468
481
|
);
|
|
482
|
+
} else if (run.refused !== null) {
|
|
483
|
+
write(`House refused that report (${run.refused.code}); this installation no longer holds Run ${run.run}.`);
|
|
469
484
|
}
|
|
470
|
-
if (!run.settled || reported?.outcome === "failed") process.exitCode = 1;
|
|
485
|
+
if (!run.settled || run.refused !== null || reported?.outcome === "failed") process.exitCode = 1;
|
|
471
486
|
}
|
|
472
487
|
|
|
473
488
|
function syncCancellation() {
|
|
@@ -483,12 +498,12 @@ function syncCancellation() {
|
|
|
483
498
|
}
|
|
484
499
|
|
|
485
500
|
async function runSyncBootstrap(args, directory) {
|
|
486
|
-
const {
|
|
501
|
+
const { lists, rest } = declared(args, ["--prefix"], 1, {
|
|
487
502
|
repeated: ["--prefix"],
|
|
488
503
|
exact: true,
|
|
489
504
|
});
|
|
490
|
-
|
|
491
|
-
|
|
505
|
+
if (lists["--prefix"].length === 0) throw new Error(SYNC_BOOTSTRAP_USAGE);
|
|
506
|
+
const house = await storedHouse(directory);
|
|
492
507
|
const run = syncCancellation();
|
|
493
508
|
try {
|
|
494
509
|
const result = await bootstrap({
|
|
@@ -507,9 +522,8 @@ async function runSyncBootstrap(args, directory) {
|
|
|
507
522
|
}
|
|
508
523
|
|
|
509
524
|
async function runSyncPull(args, directory) {
|
|
510
|
-
const {
|
|
511
|
-
const house = await
|
|
512
|
-
if (!house) throw new Error(SYNC_PULL_USAGE);
|
|
525
|
+
const { rest } = declared(args, [], 1, { exact: true });
|
|
526
|
+
const house = await storedHouse(directory);
|
|
513
527
|
const run = syncCancellation();
|
|
514
528
|
try {
|
|
515
529
|
const result = await pull({
|
|
@@ -527,9 +541,8 @@ async function runSyncPull(args, directory) {
|
|
|
527
541
|
}
|
|
528
542
|
|
|
529
543
|
async function runSyncRebootstrap(args, directory) {
|
|
530
|
-
const {
|
|
531
|
-
const house = await
|
|
532
|
-
if (!house) throw new Error(SYNC_REBOOTSTRAP_USAGE);
|
|
544
|
+
const { rest } = declared(args, [], 1, { exact: true });
|
|
545
|
+
const house = await storedHouse(directory);
|
|
533
546
|
const run = syncCancellation();
|
|
534
547
|
try {
|
|
535
548
|
const result = await rebootstrap({
|
|
@@ -554,9 +567,8 @@ async function readChanges(path) {
|
|
|
554
567
|
}
|
|
555
568
|
|
|
556
569
|
async function runSyncSubmit(args, directory) {
|
|
557
|
-
const { values, rest } = declared(args, ["--
|
|
558
|
-
const house = await
|
|
559
|
-
if (!house) throw new Error(SYNC_SUBMIT_USAGE);
|
|
570
|
+
const { values, rest } = declared(args, ["--changes"], 1, { exact: true });
|
|
571
|
+
const house = await storedHouse(directory);
|
|
560
572
|
const run = syncCancellation();
|
|
561
573
|
try {
|
|
562
574
|
const result = await submit({
|
|
@@ -629,11 +641,11 @@ async function mountEmitted(packagePath, options, run) {
|
|
|
629
641
|
}
|
|
630
642
|
|
|
631
643
|
async function runMigrateMount(args, directory) {
|
|
632
|
-
const { values, rest } = declared(args, ["--
|
|
633
|
-
|
|
634
|
-
if (!house || rest.length !== 1 || values["--subtree"] === undefined) {
|
|
644
|
+
const { values, rest } = declared(args, ["--subtree"], 1, { exact: true });
|
|
645
|
+
if (rest.length !== 1 || values["--subtree"] === undefined) {
|
|
635
646
|
throw new Error(MIGRATE_MOUNT_USAGE);
|
|
636
647
|
}
|
|
648
|
+
const house = await storedHouse(directory);
|
|
637
649
|
const run = migrateCancellation();
|
|
638
650
|
try {
|
|
639
651
|
await mountEmitted(rest[0], { house, directory, subtree: values["--subtree"] }, run);
|
|
@@ -643,18 +655,17 @@ async function runMigrateMount(args, directory) {
|
|
|
643
655
|
}
|
|
644
656
|
|
|
645
657
|
async function runMigrateRun(args, directory) {
|
|
646
|
-
const { values, rest } = declared(args, ["--
|
|
658
|
+
const { values, rest } = declared(args, ["--subtree", "--package", "--config"], 1, {
|
|
647
659
|
exact: true,
|
|
648
660
|
});
|
|
649
|
-
const house = await selectedHouse(values, directory);
|
|
650
661
|
if (
|
|
651
|
-
!house ||
|
|
652
662
|
rest.length !== 1 ||
|
|
653
663
|
values["--subtree"] === undefined ||
|
|
654
664
|
values["--package"] === undefined
|
|
655
665
|
) {
|
|
656
666
|
throw new Error(MIGRATE_RUN_USAGE);
|
|
657
667
|
}
|
|
668
|
+
const house = await storedHouse(directory);
|
|
658
669
|
const run = migrateCancellation();
|
|
659
670
|
try {
|
|
660
671
|
const emitted = await emitPackage(
|
|
@@ -671,9 +682,9 @@ async function runMigrateRun(args, directory) {
|
|
|
671
682
|
}
|
|
672
683
|
|
|
673
684
|
async function runMigrateUnmount(args, directory) {
|
|
674
|
-
const { values, rest } = declared(args, ["--
|
|
675
|
-
|
|
676
|
-
|
|
685
|
+
const { values, rest } = declared(args, ["--confirm"], 1, { exact: true });
|
|
686
|
+
if (rest.length !== 1) throw new Error(MIGRATE_UNMOUNT_USAGE);
|
|
687
|
+
const house = await storedHouse(directory);
|
|
677
688
|
const run = migrateCancellation();
|
|
678
689
|
try {
|
|
679
690
|
const result = await unmountSubtree({
|
|
@@ -729,12 +740,12 @@ function attachmentCancellation() {
|
|
|
729
740
|
async function runAttachmentUpload(args, directory) {
|
|
730
741
|
const { values, rest } = declared(
|
|
731
742
|
args,
|
|
732
|
-
["--
|
|
743
|
+
["--room", "--private", "--name", "--media-type"],
|
|
733
744
|
1,
|
|
734
745
|
{ flags: ["--private"] },
|
|
735
746
|
);
|
|
736
|
-
|
|
737
|
-
|
|
747
|
+
if (rest.length !== 1) throw new Error(ATTACHMENT_UPLOAD_USAGE);
|
|
748
|
+
const house = await storedHouse(directory);
|
|
738
749
|
const run = attachmentCancellation();
|
|
739
750
|
try {
|
|
740
751
|
const result = await uploadAttachment({
|
|
@@ -756,13 +767,13 @@ async function runAttachmentUpload(args, directory) {
|
|
|
756
767
|
async function runAttachmentGet(args, directory) {
|
|
757
768
|
const { values } = declared(
|
|
758
769
|
args,
|
|
759
|
-
["--
|
|
770
|
+
["--attachment", "--room", "--private", "--output"],
|
|
760
771
|
0,
|
|
761
772
|
{ flags: ["--private"] },
|
|
762
773
|
);
|
|
763
|
-
const house = await selectedHouse(values, directory);
|
|
764
774
|
const attachment = values["--attachment"];
|
|
765
|
-
if (!
|
|
775
|
+
if (!attachment) throw new Error(ATTACHMENT_GET_USAGE);
|
|
776
|
+
const house = await storedHouse(directory);
|
|
766
777
|
const run = attachmentCancellation();
|
|
767
778
|
try {
|
|
768
779
|
const result = await getAttachment({
|
|
@@ -788,9 +799,8 @@ async function runAttachment(args, directory) {
|
|
|
788
799
|
}
|
|
789
800
|
|
|
790
801
|
async function runHostReport(args, directory) {
|
|
791
|
-
const { values } = declared(args, ["--
|
|
792
|
-
const house = await
|
|
793
|
-
if (!house) throw new Error(HOST_USAGE);
|
|
802
|
+
const { values } = declared(args, ["--config"], 0, { exact: true });
|
|
803
|
+
const house = await storedHouse(directory);
|
|
794
804
|
const observed = await reportHost({
|
|
795
805
|
house,
|
|
796
806
|
directory,
|
|
@@ -802,9 +812,8 @@ async function runHostReport(args, directory) {
|
|
|
802
812
|
}
|
|
803
813
|
|
|
804
814
|
async function runAgentsUpdate(args, directory) {
|
|
805
|
-
const { values } = declared(args, ["--
|
|
806
|
-
const house = await
|
|
807
|
-
if (!house) throw new Error(AGENTS_USAGE);
|
|
815
|
+
const { values } = declared(args, ["--config"], 0, { exact: true });
|
|
816
|
+
const house = await storedHouse(directory);
|
|
808
817
|
const { updated } = await updateAgents({
|
|
809
818
|
house,
|
|
810
819
|
directory,
|
|
@@ -830,10 +839,10 @@ async function runAgentsUpdate(args, directory) {
|
|
|
830
839
|
}
|
|
831
840
|
|
|
832
841
|
async function runAgentsSignIn(args, directory) {
|
|
833
|
-
const { values, rest } = declared(args, ["--
|
|
834
|
-
const house = await selectedHouse(values, directory);
|
|
842
|
+
const { values, rest } = declared(args, ["--config"], 1, { exact: true });
|
|
835
843
|
const [kind] = rest;
|
|
836
|
-
if (!
|
|
844
|
+
if (!kind) throw new Error(AGENTS_USAGE);
|
|
845
|
+
const house = await storedHouse(directory);
|
|
837
846
|
const { status, reported } = await signInAgent({
|
|
838
847
|
house,
|
|
839
848
|
directory,
|
|
@@ -850,19 +859,29 @@ async function runAgentsSignIn(args, directory) {
|
|
|
850
859
|
}
|
|
851
860
|
|
|
852
861
|
async function runWorkspaceHost(args, directory) {
|
|
853
|
-
const { values } = declared(args, ["--
|
|
854
|
-
const house = await selectedHouse(values, directory);
|
|
855
|
-
if (!house) throw new Error(WORKSPACE_USAGE);
|
|
862
|
+
const { values } = declared(args, ["--config", "--passes"], 0, { exact: true });
|
|
856
863
|
const passes = values["--passes"] === undefined ? undefined : Number(values["--passes"]);
|
|
857
864
|
if (passes !== undefined && (!Number.isSafeInteger(passes) || passes < 1)) {
|
|
858
865
|
throw new Error(WORKSPACE_USAGE);
|
|
859
866
|
}
|
|
860
|
-
const
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
867
|
+
const house = await storedHouse(directory);
|
|
868
|
+
const cancellation = new AbortController();
|
|
869
|
+
const cancel = () => cancellation.abort();
|
|
870
|
+
process.once("SIGINT", cancel);
|
|
871
|
+
process.once("SIGTERM", cancel);
|
|
872
|
+
let served;
|
|
873
|
+
try {
|
|
874
|
+
served = await serveWorkspaces({
|
|
875
|
+
house,
|
|
876
|
+
directory,
|
|
877
|
+
configuration: values["--config"] ?? join(directory, "kit.json"),
|
|
878
|
+
passes,
|
|
879
|
+
signal: cancellation.signal,
|
|
880
|
+
});
|
|
881
|
+
} finally {
|
|
882
|
+
process.removeListener("SIGINT", cancel);
|
|
883
|
+
process.removeListener("SIGTERM", cancel);
|
|
884
|
+
}
|
|
866
885
|
for (const name of served.reconciled) {
|
|
867
886
|
write(`Stopped ${name}; House authorizes no running workspace for it.`);
|
|
868
887
|
}
|
|
@@ -876,10 +895,24 @@ async function runWorkspaceHost(args, directory) {
|
|
|
876
895
|
}
|
|
877
896
|
}
|
|
878
897
|
|
|
898
|
+
async function runWorkspaceUpdate(args, directory) {
|
|
899
|
+
declared(args, [], 0, { exact: true });
|
|
900
|
+
const answered = await updateWorkspaces({
|
|
901
|
+
house: await storedHouse(directory),
|
|
902
|
+
configuration: join(directory, "kit.json"),
|
|
903
|
+
});
|
|
904
|
+
for (const { workspace, running } of answered.updated) {
|
|
905
|
+
write(running ? `Updated workspace ${workspace}.` : `Updated workspace ${workspace}; it stays stopped.`);
|
|
906
|
+
}
|
|
907
|
+
for (const { workspace, cause } of answered.unchanged) {
|
|
908
|
+
write(`Workspace ${workspace} is unchanged: ${cause}`);
|
|
909
|
+
}
|
|
910
|
+
if (answered.unchanged.length > 0) process.exitCode = 1;
|
|
911
|
+
}
|
|
912
|
+
|
|
879
913
|
async function runTelegramConnect(args, directory) {
|
|
880
|
-
|
|
881
|
-
const house = await
|
|
882
|
-
if (!house) throw new Error(TELEGRAM_USAGE);
|
|
914
|
+
declared(args, [], 0, { exact: true });
|
|
915
|
+
const house = await storedHouse(directory);
|
|
883
916
|
const cancellation = new AbortController();
|
|
884
917
|
const cancel = () => cancellation.abort();
|
|
885
918
|
process.once("SIGINT", cancel);
|
|
@@ -897,9 +930,8 @@ async function runTelegramConnect(args, directory) {
|
|
|
897
930
|
}
|
|
898
931
|
|
|
899
932
|
async function runTelegramDisconnect(args, directory) {
|
|
900
|
-
|
|
901
|
-
const house = await
|
|
902
|
-
if (!house) throw new Error(TELEGRAM_USAGE);
|
|
933
|
+
declared(args, [], 0, { exact: true });
|
|
934
|
+
const house = await storedHouse(directory);
|
|
903
935
|
const cancellation = new AbortController();
|
|
904
936
|
const cancel = () => cancellation.abort();
|
|
905
937
|
process.once("SIGINT", cancel);
|
|
@@ -919,20 +951,25 @@ async function runTelegramDisconnect(args, directory) {
|
|
|
919
951
|
}
|
|
920
952
|
|
|
921
953
|
async function runTelegramServe(args, directory) {
|
|
922
|
-
const { values } = declared(args, ["--
|
|
923
|
-
const house = await selectedHouse(values, directory);
|
|
924
|
-
if (!house) throw new Error(TELEGRAM_USAGE);
|
|
954
|
+
const { values } = declared(args, ["--passes"], 0, { exact: true });
|
|
925
955
|
const passes = values["--passes"] === undefined ? undefined : Number(values["--passes"]);
|
|
926
956
|
if (passes !== undefined && (!Number.isSafeInteger(passes) || passes < 1)) {
|
|
927
957
|
throw new Error(TELEGRAM_USAGE);
|
|
928
958
|
}
|
|
959
|
+
const house = await storedHouse(directory);
|
|
929
960
|
const cancellation = new AbortController();
|
|
930
961
|
const cancel = () => cancellation.abort();
|
|
931
962
|
process.once("SIGINT", cancel);
|
|
932
963
|
process.once("SIGTERM", cancel);
|
|
933
964
|
let served;
|
|
934
965
|
try {
|
|
935
|
-
served = await serveTelegramGateway({
|
|
966
|
+
served = await serveTelegramGateway({
|
|
967
|
+
house,
|
|
968
|
+
directory,
|
|
969
|
+
passes,
|
|
970
|
+
signal: cancellation.signal,
|
|
971
|
+
refused: (failure) => write(refusedPassLine(failure)),
|
|
972
|
+
});
|
|
936
973
|
} finally {
|
|
937
974
|
process.removeListener("SIGINT", cancel);
|
|
938
975
|
process.removeListener("SIGTERM", cancel);
|
|
@@ -952,20 +989,23 @@ async function runTelegramServe(args, directory) {
|
|
|
952
989
|
`File send ${settled.upload} settled ${settled.outcome}${settled.reason === null ? "" : ` (${settled.reason})`}.`,
|
|
953
990
|
);
|
|
954
991
|
}
|
|
955
|
-
for (const failure of served.failures)
|
|
956
|
-
write(
|
|
957
|
-
`The ${failure.activity} pass${failure.item === null ? "" : ` for ${failure.item}`} could not finish (${failure.code}).`,
|
|
958
|
-
);
|
|
959
|
-
}
|
|
992
|
+
for (const failure of served.failures) write(refusedPassLine(failure));
|
|
960
993
|
if (served.failures.length > 0) process.exitCode = 1;
|
|
961
994
|
}
|
|
962
995
|
|
|
996
|
+
function refusedPassLine(failure) {
|
|
997
|
+
return `The ${failure.activity} pass${failure.item === null ? "" : ` for ${failure.item}`} could not finish (${failure.code}).`;
|
|
998
|
+
}
|
|
999
|
+
|
|
963
1000
|
async function main() {
|
|
964
1001
|
const [command, ...args] = process.argv.slice(2);
|
|
965
1002
|
const directory = process.env.HOUSE_KIT_HOME ?? join(homedir(), ".house-kit");
|
|
966
1003
|
if (command === "login") return runLogin(args, directory);
|
|
967
1004
|
if (command === "credential" && args[0] === "check") return runCredentialCheck(args.slice(1), directory);
|
|
968
|
-
if (command === "resident")
|
|
1005
|
+
if (command === "resident") {
|
|
1006
|
+
if (args[0] === "drain") return runResidentDrain(args.slice(1), directory);
|
|
1007
|
+
return runResidentCommand(args, directory);
|
|
1008
|
+
}
|
|
969
1009
|
if (command === "setup") return runSetup(args, directory);
|
|
970
1010
|
if (command === "apply") return runApply(args, directory);
|
|
971
1011
|
if (command === "worker") {
|
|
@@ -1002,6 +1042,7 @@ async function main() {
|
|
|
1002
1042
|
if (command === "workspace") {
|
|
1003
1043
|
const [action, ...rest] = args;
|
|
1004
1044
|
if (action === "host") return runWorkspaceHost(rest, directory);
|
|
1045
|
+
if (action === "update") return runWorkspaceUpdate(rest, directory);
|
|
1005
1046
|
throw new Error(WORKSPACE_USAGE);
|
|
1006
1047
|
}
|
|
1007
1048
|
if (command === "telegram") {
|