@illuminis/comprism 0.1.5 → 0.1.7
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/out/agent/command.js +4 -4
- package/out/agent/render.d.ts +24 -0
- package/out/agent/render.js +35 -3
- package/out/agent/session.d.ts +6 -1
- package/out/agent/session.js +17 -8
- package/out/commands/agents.js +3 -3
- package/out/commands/ask.js +8 -8
- package/out/commands/codemap.d.ts +1 -1
- package/out/commands/codemap.js +3 -3
- package/out/commands/commands-thin.js +4 -4
- package/out/commands/config.js +1 -1
- package/out/commands/cost.js +4 -4
- package/out/commands/decisionEngine.d.ts +1 -0
- package/out/commands/decisionEngine.js +66 -0
- package/out/commands/hooks.js +1 -1
- package/out/commands/install.d.ts +1 -1
- package/out/commands/install.js +3 -2
- package/out/commands/instructions.js +1 -1
- package/out/commands/integrations.js +4 -4
- package/out/commands/keys.js +6 -6
- package/out/commands/login.js +37 -21
- package/out/commands/permissions.js +2 -2
- package/out/commands/plugins.js +3 -3
- package/out/commands/privacy.js +2 -2
- package/out/commands/repl.js +107 -83
- package/out/commands/review.js +6 -6
- package/out/commands/settings.js +30 -123
- package/out/commands/skills.js +2 -2
- package/out/commands/unattended.js +6 -6
- package/out/commands/update.js +1 -1
- package/out/commands/welcome.js +20 -29
- package/out/commands/worktrees.d.ts +1 -1
- package/out/graph/sync.d.ts +1 -1
- package/out/graph/sync.js +6 -6
- package/out/lib/attach.js +4 -3
- package/out/lib/commandlist.d.ts +1 -1
- package/out/lib/commandlist.js +2 -2
- package/out/lib/config.d.ts +3 -2
- package/out/lib/config.js +7 -8
- package/out/lib/connection.js +1 -1
- package/out/lib/gateway.d.ts +5 -5
- package/out/lib/machine.js +1 -1
- package/out/lib/project-ops.d.ts +1 -1
- package/out/lib/project-ops.js +4 -4
- package/out/lib/queue.js +1 -1
- package/out/lib/readiness.d.ts +3 -30
- package/out/lib/readiness.js +13 -82
- package/out/lib/servicecommand.d.ts +14 -0
- package/out/lib/servicecommand.js +74 -0
- package/out/lib/sessions.js +3 -3
- package/out/lib/ui.d.ts +9 -6
- package/out/lib/ui.js +20 -26
- package/out/lib/voice.d.ts +2 -39
- package/out/lib/voice.js +7 -148
- package/out/lib/words.d.ts +20 -0
- package/out/lib/words.js +27 -0
- package/out/machine/codemap/build.d.ts +45 -0
- package/out/machine/codemap/build.js +91 -0
- package/out/machine/codemap/facts.d.ts +47 -0
- package/out/machine/codemap/facts.js +12 -0
- package/out/machine/codemap/files.d.ts +45 -0
- package/out/machine/codemap/files.js +207 -0
- package/out/machine/codemap/read-locales.d.ts +29 -0
- package/out/machine/codemap/read-locales.js +246 -0
- package/out/machine/codemap/read-python.d.ts +11 -0
- package/out/machine/codemap/read-python.js +116 -0
- package/out/machine/codemap/read-typescript.d.ts +16 -0
- package/out/machine/codemap/read-typescript.js +292 -0
- package/out/machine/executor/browser.d.ts +14 -0
- package/out/machine/executor/browser.js +270 -0
- package/out/machine/executor/diagnostics.d.ts +2 -0
- package/out/machine/executor/diagnostics.js +181 -0
- package/out/machine/executor/documents.d.ts +40 -0
- package/out/machine/executor/documents.js +170 -0
- package/out/machine/executor/files.d.ts +2 -0
- package/out/machine/executor/files.js +590 -0
- package/out/machine/executor/git.d.ts +48 -0
- package/out/machine/executor/git.js +145 -0
- package/out/machine/executor/hooks.d.ts +51 -0
- package/out/machine/executor/hooks.js +154 -0
- package/out/machine/executor/index.d.ts +45 -0
- package/out/machine/executor/index.js +367 -0
- package/out/machine/executor/notebook.d.ts +2 -0
- package/out/machine/executor/notebook.js +147 -0
- package/out/machine/executor/paths.d.ts +20 -0
- package/out/machine/executor/paths.js +154 -0
- package/out/machine/executor/sandbox.d.ts +40 -0
- package/out/machine/executor/sandbox.js +299 -0
- package/out/machine/executor/shell.d.ts +86 -0
- package/out/machine/executor/shell.js +582 -0
- package/out/machine/executor/toolservers.d.ts +20 -0
- package/out/machine/executor/toolservers.js +189 -0
- package/out/machine/executor/worktree.d.ts +9 -0
- package/out/machine/executor/worktree.js +119 -0
- package/out/machine/folder/project.d.ts +28 -0
- package/out/machine/folder/project.js +114 -0
- package/out/machine/runtime/home.d.ts +2 -0
- package/out/machine/runtime/home.js +48 -0
- package/out/machine/runtime/needs.d.ts +30 -0
- package/out/machine/runtime/needs.js +89 -0
- package/out/machine/runtime/self.d.ts +23 -0
- package/out/machine/runtime/self.js +124 -0
- package/out/machine/voice/record.d.ts +38 -0
- package/out/machine/voice/record.js +208 -0
- package/out/providers/index.js +2 -1
- package/out/thin.js +18 -10
- package/package.json +4 -4
package/out/commands/login.js
CHANGED
|
@@ -78,6 +78,7 @@ const connection_1 = require("../lib/connection");
|
|
|
78
78
|
const gateway_1 = require("../lib/gateway");
|
|
79
79
|
const ui = __importStar(require("../lib/ui"));
|
|
80
80
|
const prompt_1 = require("../lib/prompt");
|
|
81
|
+
const words_1 = require("../lib/words");
|
|
81
82
|
const out = (s = '') => process.stdout.write(s + '\n');
|
|
82
83
|
/** Where a named workspace lives. One format, stated once. */
|
|
83
84
|
const WORKSPACE_DOMAIN = 'completionprism.illuminis.ai';
|
|
@@ -103,6 +104,21 @@ function workspaceUrl(typed) {
|
|
|
103
104
|
return `https://${value}`;
|
|
104
105
|
return `https://${value}.${WORKSPACE_DOMAIN}`;
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Where an organization signs in. A full address is used as typed. A bare name
|
|
109
|
+
* is turned into its address by the service, so every client follows one rule
|
|
110
|
+
* (service catalog 1).
|
|
111
|
+
*/
|
|
112
|
+
async function addressOf(typed) {
|
|
113
|
+
const value = typed.trim().replace(/\/+$/, '');
|
|
114
|
+
if (/^[A-Za-z0-9][A-Za-z0-9-]{0,62}$/.test(value) && value.toLowerCase() !== 'localhost') {
|
|
115
|
+
const reply = await (0, gateway_1.askAt)(`https://${WORKSPACE_DOMAIN}`, { intent: 'resolve_workspace', prompt: value });
|
|
116
|
+
const url = reply.session?.workspace_url;
|
|
117
|
+
if (url)
|
|
118
|
+
return url.replace(/\/+$/, '');
|
|
119
|
+
}
|
|
120
|
+
return workspaceUrl(value);
|
|
121
|
+
}
|
|
106
122
|
/** Localhost needs the tenant named, because there is no subdomain to read. */
|
|
107
123
|
function tenantFor(url, typed, flagged) {
|
|
108
124
|
if (flagged)
|
|
@@ -168,8 +184,8 @@ async function approveInBrowser(url, tenant, noBrowser) {
|
|
|
168
184
|
const res = await fetch(`${url}/oauth/device_authorization`, form({ client_id: CLIENT_ID, scope: 'api:read api:write' }));
|
|
169
185
|
if (!res.ok) {
|
|
170
186
|
out(ui.fail(res.status === 404 || res.status === 405
|
|
171
|
-
? 'That
|
|
172
|
-
: 'The
|
|
187
|
+
? 'That organization is running a build without browser sign in.'
|
|
188
|
+
: 'The organization would not start a browser sign in.'));
|
|
173
189
|
return '';
|
|
174
190
|
}
|
|
175
191
|
started = await res.json();
|
|
@@ -253,7 +269,7 @@ async function runLogin(args) {
|
|
|
253
269
|
out();
|
|
254
270
|
return;
|
|
255
271
|
}
|
|
256
|
-
const last = flag('--username') || flag('--email') || flag('--workspace') ? null : readLast();
|
|
272
|
+
const last = flag('--username') || flag('--email') || (flag('--organization') || flag('--workspace')) ? null : readLast();
|
|
257
273
|
if (last) {
|
|
258
274
|
out(` ${ui.c.dim('last time')} ${ui.c.bold(last.email)} ${ui.c.dim('at')} ${ui.c.bold(last.workspace)}`);
|
|
259
275
|
out(` ${ui.c.dim('press Enter to sign in as them, or type another email')}`);
|
|
@@ -275,15 +291,15 @@ async function runLogin(args) {
|
|
|
275
291
|
return;
|
|
276
292
|
}
|
|
277
293
|
// Where this person's workspace is. Asked of the product, not of them.
|
|
278
|
-
let typedWorkspace = flag('--workspace') || (again ? last?.workspace : undefined);
|
|
294
|
+
let typedWorkspace = (flag('--organization') || flag('--workspace')) || (again ? last?.workspace : undefined);
|
|
279
295
|
// Captured BEFORE the email lookup can fill it in. A workspace the product
|
|
280
296
|
// worked out is not a workspace the person typed, and only the second may be
|
|
281
297
|
// a local address. See the fence in `writeConnection`. The last sign in
|
|
282
298
|
// counts as typed only if it was typed then.
|
|
283
|
-
const typedByHand = Boolean(flag('--workspace')) || Boolean(again && last?.typed);
|
|
299
|
+
const typedByHand = Boolean((flag('--organization') || flag('--workspace'))) || Boolean(again && last?.typed);
|
|
284
300
|
if (!typedWorkspace) {
|
|
285
301
|
const live = new ui.LiveIndicator();
|
|
286
|
-
live.start('finding your
|
|
302
|
+
live.start('finding your organization');
|
|
287
303
|
try {
|
|
288
304
|
typedWorkspace = (await resolveWorkspace(username)) || undefined;
|
|
289
305
|
}
|
|
@@ -295,18 +311,18 @@ async function runLogin(args) {
|
|
|
295
311
|
process.stdout.write('\r');
|
|
296
312
|
if (!typedWorkspace) {
|
|
297
313
|
out();
|
|
298
|
-
out(ui.fail('No
|
|
299
|
-
out(` ${ui.c.dim('if your company uses a different domain, pass --
|
|
314
|
+
out(ui.fail('No organization is registered for that email address.'));
|
|
315
|
+
out(` ${ui.c.dim('if your company uses a different domain, pass --organization <name>')}`);
|
|
300
316
|
out();
|
|
301
317
|
process.exitCode = 1;
|
|
302
318
|
return;
|
|
303
319
|
}
|
|
304
320
|
}
|
|
305
|
-
const url =
|
|
321
|
+
const url = await addressOf(typedWorkspace);
|
|
306
322
|
const tenant = tenantFor(url, typedWorkspace, flag('--tenant'));
|
|
307
323
|
// Said before the password is asked for, so a person can see which company
|
|
308
324
|
// they are about to sign in to (manual 1.3).
|
|
309
|
-
out(`
|
|
325
|
+
out(` organization: ${url}`);
|
|
310
326
|
// COMPANY LOGIN (manual 1.10). A workspace whose company signs in through
|
|
311
327
|
// its own identity provider is signed in to in a browser; this tool never
|
|
312
328
|
// sees that password. `--device` is the same thing for a machine with no
|
|
@@ -346,8 +362,8 @@ async function runLogin(args) {
|
|
|
346
362
|
}, tenant);
|
|
347
363
|
if (reply.served === false) {
|
|
348
364
|
out();
|
|
349
|
-
out(ui.fail('That
|
|
350
|
-
out(` ${ui.c.dim(reply.message || 'the
|
|
365
|
+
out(ui.fail('That organization is running a build that cannot sign you in yet.'));
|
|
366
|
+
out(` ${ui.c.dim(reply.message || 'the organization is behind this copy of the tool')}`);
|
|
351
367
|
out();
|
|
352
368
|
process.exitCode = 1;
|
|
353
369
|
return;
|
|
@@ -394,7 +410,7 @@ async function runLogin(args) {
|
|
|
394
410
|
forgetPassword(username, typedWorkspace);
|
|
395
411
|
out();
|
|
396
412
|
out(ui.fail(reply.message || 'That username and password were not accepted.'));
|
|
397
|
-
out(` ${ui.c.dim('check the
|
|
413
|
+
out(` ${ui.c.dim('check the organization name too: a right password in the wrong organization looks the same')}`);
|
|
398
414
|
out();
|
|
399
415
|
process.exitCode = 1;
|
|
400
416
|
return;
|
|
@@ -447,7 +463,7 @@ async function runLogin(args) {
|
|
|
447
463
|
}
|
|
448
464
|
catch (err) {
|
|
449
465
|
out();
|
|
450
|
-
out(ui.fail(err instanceof Error ? err.message :
|
|
466
|
+
out(ui.fail(err instanceof Error ? err.message : (0, words_1.word)('addressRefused')));
|
|
451
467
|
out();
|
|
452
468
|
process.exitCode = 1;
|
|
453
469
|
return;
|
|
@@ -489,7 +505,7 @@ async function runLogin(args) {
|
|
|
489
505
|
// The workspace's OWN reason, carried back with the sign in. It used to
|
|
490
506
|
// come from a local variable set by a separate call, which meant a blank
|
|
491
507
|
// line whenever that call had not been the thing that failed.
|
|
492
|
-
out(` ${ui.c.dim(signInMessage || 'the
|
|
508
|
+
out(` ${ui.c.dim(signInMessage || 'the organization did not say why')}`);
|
|
493
509
|
out(` ${ui.c.dim('you are signed in; this machine cannot ask for work until it is enrolled')}`);
|
|
494
510
|
}
|
|
495
511
|
out();
|
|
@@ -500,13 +516,13 @@ async function loginWithKey(key, args) {
|
|
|
500
516
|
const i = args.indexOf(name);
|
|
501
517
|
return i >= 0 ? args[i + 1] : undefined;
|
|
502
518
|
};
|
|
503
|
-
const typed = flag('--workspace');
|
|
519
|
+
const typed = (flag('--organization') || flag('--workspace'));
|
|
504
520
|
if (!key || !typed) {
|
|
505
|
-
out(ui.fail('Signing in with a key needs the key and the
|
|
521
|
+
out(ui.fail('Signing in with a key needs the key and the organization: comprism login --key <key> --organization <address>'));
|
|
506
522
|
process.exitCode = 1;
|
|
507
523
|
return;
|
|
508
524
|
}
|
|
509
|
-
const url =
|
|
525
|
+
const url = await addressOf(typed);
|
|
510
526
|
const tenant = tenantFor(url, typed, flag('--tenant'));
|
|
511
527
|
const { ask: askWith } = await Promise.resolve().then(() => __importStar(require('../lib/gateway')));
|
|
512
528
|
const existing = (0, connection_1.readConnection)();
|
|
@@ -518,7 +534,7 @@ async function loginWithKey(key, args) {
|
|
|
518
534
|
}, true);
|
|
519
535
|
}
|
|
520
536
|
catch (err) {
|
|
521
|
-
out(ui.fail(err instanceof Error ? err.message :
|
|
537
|
+
out(ui.fail(err instanceof Error ? err.message : (0, words_1.word)('addressRefused')));
|
|
522
538
|
process.exitCode = 1;
|
|
523
539
|
return;
|
|
524
540
|
}
|
|
@@ -555,7 +571,7 @@ async function resolveWorkspace(email) {
|
|
|
555
571
|
//
|
|
556
572
|
// Working against a local server is still supported and is now something a
|
|
557
573
|
// person SAYS rather than something an environment does to them:
|
|
558
|
-
// `comprism login --
|
|
574
|
+
// `comprism login --organization localhost:8009`.
|
|
559
575
|
// ASKED OF THE ONE SERVICE, at the product's own address.
|
|
560
576
|
//
|
|
561
577
|
// This used to post to the authentication route directly, which made the
|
|
@@ -565,7 +581,7 @@ async function resolveWorkspace(email) {
|
|
|
565
581
|
const root = `https://${WORKSPACE_DOMAIN}`;
|
|
566
582
|
const reply = await (0, gateway_1.askAt)(root, { intent: 'resolve_workspace', prompt: email });
|
|
567
583
|
if (!reply.ok || reply.served === false || reply.complete === false) {
|
|
568
|
-
throw new Error(reply.message || 'Your
|
|
584
|
+
throw new Error(reply.message || 'Your organization could not be looked up. Try again later.');
|
|
569
585
|
}
|
|
570
586
|
const url = reply.session?.workspace_url;
|
|
571
587
|
if (!url)
|
|
@@ -64,7 +64,7 @@ async function cmdPermissions(args) {
|
|
|
64
64
|
process.stderr.write(` ${USAGE}\n`);
|
|
65
65
|
return 2;
|
|
66
66
|
}
|
|
67
|
-
const { resolveProject, asWire } = await Promise.resolve().then(() => __importStar(require('../
|
|
67
|
+
const { resolveProject, asWire } = await Promise.resolve().then(() => __importStar(require('../machine/folder/project')));
|
|
68
68
|
const { currentWorkspace } = await Promise.resolve().then(() => __importStar(require('./settings')));
|
|
69
69
|
const facts = resolveProject(currentWorkspace().path, []);
|
|
70
70
|
const files = {};
|
|
@@ -85,7 +85,7 @@ async function cmdPermissions(args) {
|
|
|
85
85
|
const lines = reply.permissions?.lines;
|
|
86
86
|
if (!reply.ok || !Array.isArray(lines)) {
|
|
87
87
|
process.stderr.write(ui.fail(reply.served === false
|
|
88
|
-
? 'Your
|
|
88
|
+
? 'Your organization is running a build without permission answers yet.'
|
|
89
89
|
: (0, sessions_1.failure)(reply)) + '\n');
|
|
90
90
|
return (0, sessions_1.exitFor)(reply);
|
|
91
91
|
}
|
package/out/commands/plugins.js
CHANGED
|
@@ -48,7 +48,7 @@ const fs = __importStar(require("fs"));
|
|
|
48
48
|
const path = __importStar(require("path"));
|
|
49
49
|
const readline = __importStar(require("readline"));
|
|
50
50
|
const gateway_1 = require("../lib/gateway");
|
|
51
|
-
const project_1 = require("../
|
|
51
|
+
const project_1 = require("../machine/folder/project");
|
|
52
52
|
const ui = __importStar(require("../lib/ui"));
|
|
53
53
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
54
54
|
const MAX_FILES = 200;
|
|
@@ -81,7 +81,7 @@ async function call(payload) {
|
|
|
81
81
|
const reply = await (0, gateway_1.ask)({ intent: "plugins", prompt: "", pluginsPayload: payload });
|
|
82
82
|
const body = reply.plugins;
|
|
83
83
|
if (!reply.ok || reply.served === false || !body) {
|
|
84
|
-
out(` ${ui.fail(reply.message || "Your plugins could not be read from your
|
|
84
|
+
out(` ${ui.fail(reply.message || "Your plugins could not be read from your organization.")}`);
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
87
|
if (body.error) {
|
|
@@ -136,7 +136,7 @@ async function cmdPlugins(args) {
|
|
|
136
136
|
out(` ${l}`);
|
|
137
137
|
let scope = args.indexOf("--scope") >= 0 ? args[args.indexOf("--scope") + 1] : undefined;
|
|
138
138
|
if (!scope) {
|
|
139
|
-
const said = await question(` Install for: 1 this
|
|
139
|
+
const said = await question(` Install for: 1 this workspace 2 just me 3 cancel `);
|
|
140
140
|
scope = said === "1" ? "project" : said === "2" ? "personal" : undefined;
|
|
141
141
|
if (!scope) {
|
|
142
142
|
out(" Nothing was installed.");
|
package/out/commands/privacy.js
CHANGED
|
@@ -45,8 +45,8 @@ async function cmdPrivacy() {
|
|
|
45
45
|
const reply = await (0, gateway_1.ask)({ intent: "privacy", prompt: "" });
|
|
46
46
|
if (!reply.ok || reply.served === false) {
|
|
47
47
|
out(ui.fail(reply.served === false
|
|
48
|
-
? "Your
|
|
49
|
-
: `Your
|
|
48
|
+
? "Your organization is running an older build that does not answer this yet."
|
|
49
|
+
: `Your organization could not be reached: ${reply.message || "no answer"}`));
|
|
50
50
|
return 1;
|
|
51
51
|
}
|
|
52
52
|
out();
|
package/out/commands/repl.js
CHANGED
|
@@ -80,7 +80,7 @@ const keyboard_1 = require("../lib/keyboard");
|
|
|
80
80
|
const machine_1 = require("../lib/machine");
|
|
81
81
|
const ui = __importStar(require("../lib/ui"));
|
|
82
82
|
const render_1 = require("../agent/render");
|
|
83
|
-
const shell_1 = require("../executor/shell");
|
|
83
|
+
const shell_1 = require("../machine/executor/shell");
|
|
84
84
|
const voice = __importStar(require("../lib/voice"));
|
|
85
85
|
const out = (s = '') => process.stdout.write(s + '\n');
|
|
86
86
|
/**
|
|
@@ -285,7 +285,7 @@ function sessionWords() {
|
|
|
285
285
|
return [...COMMANDS, 'project', 'folders', 'instructions', 'remember', 'detach', 'output', 'processes', 'stop', 'agents'];
|
|
286
286
|
}
|
|
287
287
|
async function refreshList() {
|
|
288
|
-
const { resolveProject } = await Promise.resolve().then(() => __importStar(require('../
|
|
288
|
+
const { resolveProject } = await Promise.resolve().then(() => __importStar(require('../machine/folder/project')));
|
|
289
289
|
const root = resolveProject(await sessionFolder(), place.added).root;
|
|
290
290
|
const got = await (0, commandlist_1.fetchCommandList)(root, sessionWords());
|
|
291
291
|
// A failed refresh keeps the list already held rather than emptying it.
|
|
@@ -356,11 +356,12 @@ async function showHelpers() {
|
|
|
356
356
|
out();
|
|
357
357
|
}
|
|
358
358
|
/** The permission modes, in the order Shift+Tab moves through them (4.5). */
|
|
359
|
+
/** The modes Shift+Tab steps through, as the service last listed them. */
|
|
359
360
|
const MODES = ['read_only', 'approve_writes', 'auto_edit', 'full_auto'];
|
|
360
361
|
/** How the next job in this session runs: its mode and whether it plans first
|
|
361
362
|
* (manual 4.1, 4.5). Changed by `mode`, Shift+Tab, `plan` and `plan off`, and
|
|
362
363
|
* applied from the next job; the service still decides what each mode allows. */
|
|
363
|
-
const steering_ = { mode: 'approve_writes', plan: false, pin: '', effort: '' };
|
|
364
|
+
const steering_ = { mode: 'approve_writes', plan: false, pin: '', effort: '', modes: MODES };
|
|
364
365
|
/**
|
|
365
366
|
* The line as a command, with a leading slash taken off.
|
|
366
367
|
*
|
|
@@ -623,7 +624,7 @@ function printHelp() {
|
|
|
623
624
|
out();
|
|
624
625
|
drawList(listedItems());
|
|
625
626
|
if (!listed?.ok) {
|
|
626
|
-
out(ui.c.amber(' Your
|
|
627
|
+
out(ui.c.amber(' Your organization could not be asked for its skills, so only this tool\'s own words are shown.'));
|
|
627
628
|
out();
|
|
628
629
|
}
|
|
629
630
|
else if (listed.needsUpdate.length > 0) {
|
|
@@ -645,9 +646,42 @@ function printHelp() {
|
|
|
645
646
|
/**
|
|
646
647
|
* The folders this session works in (manual 2.1 and 2.3). `project <path>`
|
|
647
648
|
* changes the folder for the rest of the session; `folders add <path>` allows
|
|
648
|
-
* another. Neither changes the saved default, which is `comprism
|
|
649
|
+
* another. Neither changes the saved default, which is `comprism workspace`.
|
|
649
650
|
*/
|
|
650
|
-
const place = { folder: null, added: [] };
|
|
651
|
+
const place = { folder: null, added: [], workspace: '' };
|
|
652
|
+
/**
|
|
653
|
+
* One command the service runs itself (web manual 13.2, 13.3). The service says
|
|
654
|
+
* what it means and writes every line; this answers whether a folder exists on
|
|
655
|
+
* this computer when asked, prints the lines, and carries out the one action it
|
|
656
|
+
* names. True when the session's workspace or folders changed; the request to
|
|
657
|
+
* run when a next step was chosen.
|
|
658
|
+
*/
|
|
659
|
+
async function serviceCommand(words) {
|
|
660
|
+
const { runServiceCommand } = await Promise.resolve().then(() => __importStar(require('../lib/servicecommand')));
|
|
661
|
+
const said = await runServiceCommand(words, { cwd: await sessionFolder(), current: place.workspace });
|
|
662
|
+
if (!said.reached) {
|
|
663
|
+
out(ui.fail(said.message || 'Your organization could not answer that.'));
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
for (const line of said.lines)
|
|
667
|
+
out(line);
|
|
668
|
+
const a = said.action;
|
|
669
|
+
if (!a)
|
|
670
|
+
return false;
|
|
671
|
+
if (a.run)
|
|
672
|
+
return a.run;
|
|
673
|
+
if (a.open_workspace)
|
|
674
|
+
place.workspace = a.open_workspace;
|
|
675
|
+
if (a.use_folder) {
|
|
676
|
+
place.folder = a.use_folder;
|
|
677
|
+
(await Promise.resolve().then(() => __importStar(require('../lib/project-ops')))).useSessionFolder(a.use_folder);
|
|
678
|
+
}
|
|
679
|
+
if (a.add_folder && !place.added.includes(a.add_folder))
|
|
680
|
+
place.added.push(a.add_folder);
|
|
681
|
+
if (a.remove_folder)
|
|
682
|
+
place.added = place.added.filter((f) => f !== a.remove_folder);
|
|
683
|
+
return true;
|
|
684
|
+
}
|
|
651
685
|
async function sessionFolder() {
|
|
652
686
|
if (place.folder)
|
|
653
687
|
return place.folder;
|
|
@@ -656,7 +690,7 @@ async function sessionFolder() {
|
|
|
656
690
|
}
|
|
657
691
|
/** The line this session begins with, as the service wrote it (manual 2.2). */
|
|
658
692
|
async function projectLine() {
|
|
659
|
-
const { resolveProject, asWire } = await Promise.resolve().then(() => __importStar(require('../
|
|
693
|
+
const { resolveProject, asWire } = await Promise.resolve().then(() => __importStar(require('../machine/folder/project')));
|
|
660
694
|
const { ask } = await Promise.resolve().then(() => __importStar(require('../lib/gateway')));
|
|
661
695
|
const facts = resolveProject(await sessionFolder(), place.added);
|
|
662
696
|
const reply = await ask({ intent: 'project', prompt: '', project: asWire(facts, 'approve_writes') });
|
|
@@ -685,7 +719,7 @@ async function contextOf(intent, jobId, keep = '', sessionKey) {
|
|
|
685
719
|
intent, prompt: keep, ...(jobId ? { jobId } : {}), ...(sessionKey ? { spendSession: sessionKey } : {}),
|
|
686
720
|
});
|
|
687
721
|
if (!reply.ok || !reply.context) {
|
|
688
|
-
out(ui.fail(reply.message || 'Your
|
|
722
|
+
out(ui.fail(reply.message || 'Your organization could not answer that.'));
|
|
689
723
|
}
|
|
690
724
|
else {
|
|
691
725
|
for (const line of reply.context.lines)
|
|
@@ -704,7 +738,7 @@ async function showTranscript(jobId) {
|
|
|
704
738
|
const { ask } = await Promise.resolve().then(() => __importStar(require('../lib/gateway')));
|
|
705
739
|
const reply = await ask({ intent: 'transcript', prompt: '', jobId });
|
|
706
740
|
if (!reply.ok || !reply.transcript) {
|
|
707
|
-
out(ui.fail(reply.message || 'The transcript could not be read from your
|
|
741
|
+
out(ui.fail(reply.message || 'The transcript could not be read from your organization.'));
|
|
708
742
|
}
|
|
709
743
|
else {
|
|
710
744
|
for (const line of reply.transcript.lines)
|
|
@@ -1022,7 +1056,7 @@ async function runRepl(how = {}) {
|
|
|
1022
1056
|
});
|
|
1023
1057
|
}
|
|
1024
1058
|
if (!state.reached) {
|
|
1025
|
-
out(ui.fail(`Your
|
|
1059
|
+
out(ui.fail(`Your organization could not be reached, so ${ui.c.bold('nothing is known')} about your keys.`));
|
|
1026
1060
|
out(` ${ui.c.dim(state.why)}`);
|
|
1027
1061
|
out(` ${ui.c.dim('check the address with')} ${ui.c.bold('comprism status')}${ui.c.dim(', or sign in again with')} ${ui.c.bold('comprism login')}`);
|
|
1028
1062
|
out();
|
|
@@ -1059,6 +1093,14 @@ async function runRepl(how = {}) {
|
|
|
1059
1093
|
}
|
|
1060
1094
|
steering_.pin = said.pin ?? '';
|
|
1061
1095
|
steering_.effort = said.effort === 'normal' ? '' : said.effort;
|
|
1096
|
+
// Mode and plan are the service's too (CLI manual 4.1, 4.5); kept here only
|
|
1097
|
+
// to send with the next job and to draw the prompt.
|
|
1098
|
+
if (said.mode)
|
|
1099
|
+
steering_.mode = said.mode;
|
|
1100
|
+
if (typeof said.plan === 'boolean')
|
|
1101
|
+
steering_.plan = said.plan;
|
|
1102
|
+
if (said.modes?.length)
|
|
1103
|
+
steering_.modes = said.modes;
|
|
1062
1104
|
return said;
|
|
1063
1105
|
};
|
|
1064
1106
|
if (how.latest || how.resume || how.pick) {
|
|
@@ -1346,7 +1388,7 @@ async function runRepl(how = {}) {
|
|
|
1346
1388
|
* a drag and drop, and the files wait for the question that follows.
|
|
1347
1389
|
*/
|
|
1348
1390
|
const gather = async (typed) => {
|
|
1349
|
-
const { resolveProject } = await Promise.resolve().then(() => __importStar(require('../
|
|
1391
|
+
const { resolveProject } = await Promise.resolve().then(() => __importStar(require('../machine/folder/project')));
|
|
1350
1392
|
const here = await sessionFolder();
|
|
1351
1393
|
const root = resolveProject(here, place.added).root;
|
|
1352
1394
|
completion.root = root;
|
|
@@ -1639,11 +1681,15 @@ async function runRepl(how = {}) {
|
|
|
1639
1681
|
keys().on('keypress', (_s, key) => {
|
|
1640
1682
|
if (!key || key.name !== 'tab' || !key.shift || working || answering || leaving)
|
|
1641
1683
|
return;
|
|
1642
|
-
|
|
1643
|
-
|
|
1684
|
+
// The next mode in the service's own list, set by the service.
|
|
1685
|
+
const modes = steering_.modes;
|
|
1686
|
+
const next = modes[(modes.indexOf(steering_.mode) + 1) % modes.length];
|
|
1644
1687
|
out();
|
|
1645
|
-
|
|
1646
|
-
|
|
1688
|
+
void steer({ mode: next }).then((said) => {
|
|
1689
|
+
for (const line of said?.lines ?? [])
|
|
1690
|
+
out(ui.c.dim(line));
|
|
1691
|
+
prompt();
|
|
1692
|
+
});
|
|
1647
1693
|
});
|
|
1648
1694
|
async function handle(line) {
|
|
1649
1695
|
const typed = line.trim();
|
|
@@ -1669,38 +1715,27 @@ async function runRepl(how = {}) {
|
|
|
1669
1715
|
out();
|
|
1670
1716
|
return prompt();
|
|
1671
1717
|
}
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
if (where) {
|
|
1685
|
-
place.folder = found.path;
|
|
1686
|
-
(await Promise.resolve().then(() => __importStar(require('../lib/project-ops')))).useSessionFolder(found.path);
|
|
1687
|
-
}
|
|
1688
|
-
else if (!place.added.includes(found.path))
|
|
1689
|
-
place.added.push(found.path);
|
|
1690
|
-
}
|
|
1691
|
-
if (/^folders$/i.test(bare)) {
|
|
1692
|
-
const facts = resolveProject(await sessionFolder(), place.added);
|
|
1693
|
-
out();
|
|
1694
|
-
out(` ${ui.c.bold(facts.root)} ${ui.c.dim('project')}`);
|
|
1695
|
-
for (const f of facts.added)
|
|
1696
|
-
out(` ${ui.c.bold(f)} ${ui.c.dim('added for this session')}`);
|
|
1697
|
-
out();
|
|
1698
|
-
return prompt();
|
|
1699
|
-
}
|
|
1718
|
+
// Commands the service runs itself (web manual 13.2, 13.3): any word the
|
|
1719
|
+
// service lists as its own, and `project`, the old name for `workspace`.
|
|
1720
|
+
// What they mean and every line printed are the service's; this sends what
|
|
1721
|
+
// was typed, answers whether a folder exists, and carries out the action.
|
|
1722
|
+
const head = (bare.split(/\s+/)[0] ?? '').toLowerCase();
|
|
1723
|
+
const { waitingNextSteps } = await Promise.resolve().then(() => __importStar(require('../agent/session')));
|
|
1724
|
+
const serviceWord = head === 'project'
|
|
1725
|
+
|| (/^\d+$/.test(bare) && waitingNextSteps > 0)
|
|
1726
|
+
|| (listed?.items ?? []).some((i) => i.source === 'service' && i.name === head);
|
|
1727
|
+
if (serviceWord) {
|
|
1728
|
+
const words = head === 'project' ? bare.replace(/^project\b/i, 'workspace') : bare;
|
|
1729
|
+
const acted = await serviceCommand(words);
|
|
1700
1730
|
out();
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1731
|
+
// A next step chosen: it runs as the request it stands for.
|
|
1732
|
+
if (typeof acted === 'string')
|
|
1733
|
+
return handle(`work ${acted}`);
|
|
1734
|
+
if (acted) {
|
|
1735
|
+
await showProjectLine();
|
|
1736
|
+
// Another folder has other skills.
|
|
1737
|
+
await refreshList();
|
|
1738
|
+
}
|
|
1704
1739
|
return prompt();
|
|
1705
1740
|
}
|
|
1706
1741
|
// `pin <model>` and `effort <level>` (manual 4.17, 4.18), kept by the
|
|
@@ -1736,16 +1771,12 @@ async function runRepl(how = {}) {
|
|
|
1736
1771
|
}
|
|
1737
1772
|
const effortTo = /^effort\s+(\S+)$/.exec(word);
|
|
1738
1773
|
if (effortTo) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
out(ui.c.dim(` effort ${ui.c.bold(said.effort)} for the next requests`));
|
|
1746
|
-
if (said.effort_note)
|
|
1747
|
-
out(ui.c.dim(` ${said.effort_note}`));
|
|
1748
|
-
}
|
|
1774
|
+
// The service checks the word and says what is allowed.
|
|
1775
|
+
const said = await steer({ effort: effortTo[1] });
|
|
1776
|
+
if (said) {
|
|
1777
|
+
out(ui.c.dim(` effort ${ui.c.bold(said.effort)} for the next requests`));
|
|
1778
|
+
if (said.effort_note)
|
|
1779
|
+
out(ui.c.dim(` ${said.effort_note}`));
|
|
1749
1780
|
}
|
|
1750
1781
|
out();
|
|
1751
1782
|
return prompt();
|
|
@@ -1753,20 +1784,16 @@ async function runRepl(how = {}) {
|
|
|
1753
1784
|
// `mode <name>` and `plan off` (manual 4.1, 4.5).
|
|
1754
1785
|
const modeTo = /^mode\s+(\S+)$/.exec(word);
|
|
1755
1786
|
if (modeTo) {
|
|
1756
|
-
const
|
|
1757
|
-
|
|
1758
|
-
out(ui.
|
|
1759
|
-
}
|
|
1760
|
-
else {
|
|
1761
|
-
steering_.mode = named;
|
|
1762
|
-
out(ui.c.dim(` mode ${ui.c.bold(named)}, from the next job`));
|
|
1763
|
-
}
|
|
1787
|
+
const said = await steer({ mode: modeTo[1] });
|
|
1788
|
+
for (const line of said?.lines ?? [])
|
|
1789
|
+
out(ui.c.dim(line));
|
|
1764
1790
|
out();
|
|
1765
1791
|
return prompt();
|
|
1766
1792
|
}
|
|
1767
1793
|
if (word === 'plan off') {
|
|
1768
|
-
|
|
1769
|
-
|
|
1794
|
+
const said = await steer({ plan: false });
|
|
1795
|
+
for (const line of said?.lines ?? [])
|
|
1796
|
+
out(ui.c.dim(line));
|
|
1770
1797
|
out();
|
|
1771
1798
|
return prompt();
|
|
1772
1799
|
}
|
|
@@ -1784,7 +1811,7 @@ async function runRepl(how = {}) {
|
|
|
1784
1811
|
// `output 3`: a command's whole output, kept on this machine (5.12).
|
|
1785
1812
|
const outputOf = /^output(?:\s+(\d+))?$/.exec(word);
|
|
1786
1813
|
if (outputOf) {
|
|
1787
|
-
const { keptOutput } = await Promise.resolve().then(() => __importStar(require('../executor/shell')));
|
|
1814
|
+
const { keptOutput } = await Promise.resolve().then(() => __importStar(require('../machine/executor/shell')));
|
|
1788
1815
|
const kept = outputOf[1] ? keptOutput(Number(outputOf[1])) : undefined;
|
|
1789
1816
|
if (!outputOf[1])
|
|
1790
1817
|
out(ui.c.dim(' output N shows the whole output of command N, the number on its line.'));
|
|
@@ -1893,16 +1920,20 @@ async function runRepl(how = {}) {
|
|
|
1893
1920
|
}
|
|
1894
1921
|
if (COMMANDS.has(word)) {
|
|
1895
1922
|
switch (word) {
|
|
1896
|
-
case 'plan':
|
|
1897
|
-
|
|
1898
|
-
|
|
1923
|
+
case 'plan': {
|
|
1924
|
+
const said = await steer({ plan: true });
|
|
1925
|
+
for (const line of said?.lines ?? [])
|
|
1926
|
+
out(ui.c.dim(line));
|
|
1899
1927
|
out();
|
|
1900
1928
|
break;
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1929
|
+
}
|
|
1930
|
+
case 'mode': {
|
|
1931
|
+
const said = await steer({});
|
|
1932
|
+
for (const line of said?.lines ?? [])
|
|
1933
|
+
out(ui.c.dim(line));
|
|
1904
1934
|
out();
|
|
1905
1935
|
break;
|
|
1936
|
+
}
|
|
1906
1937
|
case 'pin': {
|
|
1907
1938
|
const said = await steer({});
|
|
1908
1939
|
out(said?.pin
|
|
@@ -2096,17 +2127,10 @@ async function runRepl(how = {}) {
|
|
|
2096
2127
|
// session the moment two are open, and this one is on the screen.
|
|
2097
2128
|
case 'cost':
|
|
2098
2129
|
case 'spend': {
|
|
2099
|
-
// Nothing sent is nothing charged
|
|
2100
|
-
//
|
|
2101
|
-
// session" to a person checking that a refusal cost them nothing
|
|
2102
|
-
// (manual 6.1).
|
|
2103
|
-
if (session.jobs.length === 0) {
|
|
2104
|
-
out(` ${ui.c.dim('session')} ${ui.c.bold(session.id)} ${ui.c.dim('nothing has run yet, so it has cost')} $0.00`);
|
|
2105
|
-
out();
|
|
2106
|
-
break;
|
|
2107
|
-
}
|
|
2130
|
+
// Nothing sent is nothing charged: the service answers even before
|
|
2131
|
+
// the first job, so a refusal can be checked as costing nothing (6.1).
|
|
2108
2132
|
const { cmdCost } = await Promise.resolve().then(() => __importStar(require('./cost')));
|
|
2109
|
-
await cmdCost([session.id]);
|
|
2133
|
+
await cmdCost([session.serverId || session.id]);
|
|
2110
2134
|
break;
|
|
2111
2135
|
}
|
|
2112
2136
|
case 'model': {
|
package/out/commands/review.js
CHANGED
|
@@ -52,8 +52,8 @@ const fs = __importStar(require("fs"));
|
|
|
52
52
|
const path = __importStar(require("path"));
|
|
53
53
|
const ui = __importStar(require("../lib/ui"));
|
|
54
54
|
const gateway_1 = require("../lib/gateway");
|
|
55
|
-
const project_1 = require("../
|
|
56
|
-
const project_2 = require("../
|
|
55
|
+
const project_1 = require("../machine/folder/project");
|
|
56
|
+
const project_2 = require("../machine/folder/project");
|
|
57
57
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
58
58
|
const err = (s = "") => process.stderr.write(`${s}\n`);
|
|
59
59
|
async function review(op, payload, cwd = process.cwd()) {
|
|
@@ -62,9 +62,9 @@ async function review(op, payload, cwd = process.cwd()) {
|
|
|
62
62
|
}
|
|
63
63
|
function refused(reply) {
|
|
64
64
|
if (!reply.ok)
|
|
65
|
-
return reply.message || "Your
|
|
65
|
+
return reply.message || "Your organization could not be reached.";
|
|
66
66
|
if (reply.served === false)
|
|
67
|
-
return "Your
|
|
67
|
+
return "Your organization is running an older build that does not answer this yet.";
|
|
68
68
|
if (reply.granted === false)
|
|
69
69
|
return reply.message || "Refused.";
|
|
70
70
|
return null;
|
|
@@ -162,7 +162,7 @@ async function cmdRewind(args, confirmWith) {
|
|
|
162
162
|
for (const item of items) {
|
|
163
163
|
const where = inside(project.root, item.path);
|
|
164
164
|
if (!where) {
|
|
165
|
-
results.push({ path: item.path, result: "outside this
|
|
165
|
+
results.push({ path: item.path, result: "outside this workspace, not restored" });
|
|
166
166
|
continue;
|
|
167
167
|
}
|
|
168
168
|
// Your later changes are never overwritten (7.4): the file must still be
|
|
@@ -190,7 +190,7 @@ async function cmdRewind(args, confirmWith) {
|
|
|
190
190
|
else if (item.action === "rename_back" && item.to) {
|
|
191
191
|
const from = inside(project.root, item.to);
|
|
192
192
|
if (!from)
|
|
193
|
-
throw new Error("the new name is outside this
|
|
193
|
+
throw new Error("the new name is outside this workspace");
|
|
194
194
|
fs.mkdirSync(path.dirname(where), { recursive: true });
|
|
195
195
|
if (fs.existsSync(from))
|
|
196
196
|
fs.renameSync(from, where);
|