@illuminis/comprism 0.1.5 → 0.1.6
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/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/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.js +1 -1
- 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/providers/index.js +2 -1
- package/out/thin.js +11 -10
- package/package.json +4 -4
package/out/agent/command.js
CHANGED
|
@@ -56,11 +56,11 @@ exports.runAgent = runAgent;
|
|
|
56
56
|
const fs = __importStar(require("fs"));
|
|
57
57
|
const readline = __importStar(require("readline"));
|
|
58
58
|
const connection_1 = require("../lib/connection");
|
|
59
|
-
const project_1 = require("../
|
|
59
|
+
const project_1 = require("../machine/folder/project");
|
|
60
60
|
const session_1 = require("./session");
|
|
61
61
|
const ui = __importStar(require("./render"));
|
|
62
62
|
const output_1 = require("../lib/output");
|
|
63
|
-
const self_1 = require("../
|
|
63
|
+
const self_1 = require("../machine/runtime/self");
|
|
64
64
|
/** The WebSocket the session needs is a global from Node 22.
|
|
65
65
|
*
|
|
66
66
|
* Checked here with a message somebody can act on. Without it the failure is
|
|
@@ -219,7 +219,7 @@ async function runAgent(args) {
|
|
|
219
219
|
// `--sandbox` never runs without one (manual 4.12): refused before anything
|
|
220
220
|
// runs or is charged.
|
|
221
221
|
if (args.sandbox) {
|
|
222
|
-
const { availability } = await Promise.resolve().then(() => __importStar(require("../executor/sandbox")));
|
|
222
|
+
const { availability } = await Promise.resolve().then(() => __importStar(require("../machine/executor/sandbox")));
|
|
223
223
|
const found = availability();
|
|
224
224
|
if (!found.system) {
|
|
225
225
|
process.stderr.write(ui.red(` --sandbox cannot start: ${found.why}.`)
|
|
@@ -414,7 +414,7 @@ ${ui.bold("comprism work")} — a coding agent in your terminal
|
|
|
414
414
|
comprism work "add a test for the parser and make it pass"
|
|
415
415
|
|
|
416
416
|
${ui.bold("What it does")}
|
|
417
|
-
Reads your
|
|
417
|
+
Reads your workspace, changes files, runs commands and runs your tests. It
|
|
418
418
|
shows you every change as it makes it, asks before deleting a file or
|
|
419
419
|
running a command, and can undo the whole job. Each step is routed to whichever
|
|
420
420
|
model finishes the work for least, and the receipt at the end says what it
|
package/out/agent/session.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ProjectFacts } from "../
|
|
1
|
+
import { type ProjectFacts } from "../machine/folder/project";
|
|
2
2
|
import * as ui from "./render";
|
|
3
3
|
export interface SessionOptions {
|
|
4
4
|
/** Where the workspace lives, and the URL of the server that owns it. */
|
|
@@ -106,7 +106,12 @@ export interface SessionOptions {
|
|
|
106
106
|
/** `--output stream`: handed the service's stream lines as they arrive. */
|
|
107
107
|
onStream?: (items: Array<Record<string, unknown>>) => void;
|
|
108
108
|
}
|
|
109
|
+
/** How many next steps the last job offered (web manual 13.4), so a bare number
|
|
110
|
+
* typed next is sent to the service to run one rather than to the agent. */
|
|
111
|
+
export declare let waitingNextSteps: number;
|
|
109
112
|
export interface JobResult {
|
|
113
|
+
/** The service's lines for the next steps it offered, printed as sent. */
|
|
114
|
+
nextSteps?: string[];
|
|
110
115
|
outcome: string;
|
|
111
116
|
detail?: string | null;
|
|
112
117
|
jobId?: string;
|
package/out/agent/session.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.TerminalSession = void 0;
|
|
36
|
+
exports.TerminalSession = exports.waitingNextSteps = void 0;
|
|
37
37
|
/**
|
|
38
38
|
* A coding job, run from a terminal.
|
|
39
39
|
*
|
|
@@ -63,12 +63,15 @@ const gateway_1 = require("../lib/gateway");
|
|
|
63
63
|
const fs = __importStar(require("fs"));
|
|
64
64
|
const path = __importStar(require("path"));
|
|
65
65
|
const readline = __importStar(require("readline"));
|
|
66
|
-
const executor_1 = require("../executor");
|
|
67
|
-
const project_1 = require("../
|
|
66
|
+
const executor_1 = require("../machine/executor");
|
|
67
|
+
const project_1 = require("../machine/folder/project");
|
|
68
68
|
const ui = __importStar(require("./render"));
|
|
69
69
|
const jobs_1 = require("../commands/jobs");
|
|
70
70
|
/** The actions that change a file, whose change is shown as it is made. */
|
|
71
71
|
const CHANGES = new Set(["edit_file", "multi_edit", "write_file"]);
|
|
72
|
+
/** How many next steps the last job offered (web manual 13.4), so a bare number
|
|
73
|
+
* typed next is sent to the service to run one rather than to the agent. */
|
|
74
|
+
exports.waitingNextSteps = 0;
|
|
72
75
|
/** Files with changes in Git as the job starts: the person's, not the agent's. */
|
|
73
76
|
function dirtyFiles(root) {
|
|
74
77
|
try {
|
|
@@ -158,7 +161,7 @@ class TerminalSession {
|
|
|
158
161
|
// A real refusal, in the service's own words: a plan that does not
|
|
159
162
|
// include coding and an allowance that has been spent have different
|
|
160
163
|
// fixes, and a caller told only "refused" looks in the wrong place.
|
|
161
|
-
this.refusal = reply.message || "your
|
|
164
|
+
this.refusal = reply.message || "your organization could not be reached";
|
|
162
165
|
// The reason word, for the exit number (Appendix B): the service's own
|
|
163
166
|
// when it answered, else what the missing answer means.
|
|
164
167
|
this.refusalReason = reply.reason
|
|
@@ -313,7 +316,7 @@ class TerminalSession {
|
|
|
313
316
|
// long pause for a feature they did not ask for, to save money on a
|
|
314
317
|
// job they have not started. So the job runs now, reading files the
|
|
315
318
|
// ordinary way, and the second job in this project has the map.
|
|
316
|
-
this.out(ui.dim(" reading a map of this
|
|
319
|
+
this.out(ui.dim(" reading a map of this workspace in the background;"
|
|
317
320
|
+ " your next job here will use it\n"));
|
|
318
321
|
void refresh(this.opts.root, this.project()).catch(() => undefined);
|
|
319
322
|
}
|
|
@@ -568,7 +571,7 @@ class TerminalSession {
|
|
|
568
571
|
if (frame.type === "event" && frame.kind === "sandbox") {
|
|
569
572
|
// The service turned the sandbox on for this job: every command from
|
|
570
573
|
// here runs inside it, with its allowed addresses (manual 4.12).
|
|
571
|
-
const { Sandbox } = await Promise.resolve().then(() => __importStar(require("../executor/sandbox")));
|
|
574
|
+
const { Sandbox } = await Promise.resolve().then(() => __importStar(require("../machine/executor/sandbox")));
|
|
572
575
|
const system = this.sandboxSystem();
|
|
573
576
|
if (system) {
|
|
574
577
|
const box = new Sandbox(system, this.opts.root, this.opts.project?.added ?? []);
|
|
@@ -639,6 +642,9 @@ class TerminalSession {
|
|
|
639
642
|
// cost and saving comes from here.
|
|
640
643
|
result.receipt = String(frame.receipt ?? "");
|
|
641
644
|
result.card = frame.card ?? null;
|
|
645
|
+
result.nextSteps = Array.isArray(frame.next_steps_lines)
|
|
646
|
+
? frame.next_steps_lines.map(String) : [];
|
|
647
|
+
exports.waitingNextSteps = Array.isArray(frame.next_steps) ? frame.next_steps.length : 0;
|
|
642
648
|
result.reusedPct = ui.reusePct(0, frame.cached_tokens, Math.max(0, Number(frame.context_tokens ?? 0) - Number(frame.cached_tokens ?? 0)));
|
|
643
649
|
result.text = String(frame.text ?? "");
|
|
644
650
|
result.why = this.lastWhy;
|
|
@@ -696,7 +702,7 @@ class TerminalSession {
|
|
|
696
702
|
// is the live connection that carries the work, and the wording names
|
|
697
703
|
// that instead.
|
|
698
704
|
if (!ready && first) {
|
|
699
|
-
reject(new Error("The live connection to your
|
|
705
|
+
reject(new Error("The live connection to your organization could not be opened. "
|
|
700
706
|
+ "You are signed in; the work stream is what failed."));
|
|
701
707
|
}
|
|
702
708
|
};
|
|
@@ -871,7 +877,7 @@ class TerminalSession {
|
|
|
871
877
|
sandboxSystem() {
|
|
872
878
|
if (this.sandboxChecked === undefined) {
|
|
873
879
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
874
|
-
const { availability } = require("../executor/sandbox");
|
|
880
|
+
const { availability } = require("../machine/executor/sandbox");
|
|
875
881
|
this.sandboxChecked = availability().system;
|
|
876
882
|
}
|
|
877
883
|
return (this.sandboxChecked ?? null);
|
|
@@ -1204,6 +1210,9 @@ class TerminalSession {
|
|
|
1204
1210
|
this.out(ui.dim(` ${line}\n`));
|
|
1205
1211
|
this.out(ui.receipt(r.receipt, r.models, r.ending ? undefined : r.testsPassed, r.card));
|
|
1206
1212
|
}
|
|
1213
|
+
// What would finish the request, worded by the service (web manual 13.4).
|
|
1214
|
+
for (const line of r.nextSteps ?? [])
|
|
1215
|
+
this.out(`${line}\n`);
|
|
1207
1216
|
if (r.jobId) {
|
|
1208
1217
|
// The job's own reference, so a person can quote it. The link to the
|
|
1209
1218
|
// account sits in the receipt above, where the server put it.
|
package/out/commands/agents.js
CHANGED
|
@@ -41,8 +41,8 @@ exports.cmdAgents = cmdAgents;
|
|
|
41
41
|
* wins a clash and what each line says; this reads the files it names, inside
|
|
42
42
|
* the project and through the executor's own checks, and prints its lines.
|
|
43
43
|
*/
|
|
44
|
-
const files_1 = require("../executor/files");
|
|
45
|
-
const project_1 = require("../
|
|
44
|
+
const files_1 = require("../machine/executor/files");
|
|
45
|
+
const project_1 = require("../machine/folder/project");
|
|
46
46
|
const gateway_1 = require("../lib/gateway");
|
|
47
47
|
const ui = __importStar(require("../lib/ui"));
|
|
48
48
|
const ROUNDS = 6;
|
|
@@ -54,7 +54,7 @@ async function helperLines(folder) {
|
|
|
54
54
|
const reply = await (0, gateway_1.ask)({ intent: "agents", prompt: "", agentsPayload: { round, files, listings, project: root } });
|
|
55
55
|
const body = reply.agents;
|
|
56
56
|
if (!reply.ok || reply.served === false || !body) {
|
|
57
|
-
return [ui.fail(reply.message || "The helper list could not be read from your
|
|
57
|
+
return [ui.fail(reply.message || "The helper list could not be read from your organization.")];
|
|
58
58
|
}
|
|
59
59
|
if (!body.wants)
|
|
60
60
|
return body.lines;
|
package/out/commands/ask.js
CHANGED
|
@@ -48,7 +48,6 @@ exports.cmdAsk = cmdAsk;
|
|
|
48
48
|
*/
|
|
49
49
|
const gateway_1 = require("../lib/gateway");
|
|
50
50
|
const connection_1 = require("../lib/connection");
|
|
51
|
-
const config_1 = require("../lib/config");
|
|
52
51
|
const ui = __importStar(require("../lib/ui"));
|
|
53
52
|
const render_1 = require("../agent/render");
|
|
54
53
|
const prompt_1 = require("../lib/prompt");
|
|
@@ -87,12 +86,13 @@ async function cmdAsk(args) {
|
|
|
87
86
|
// remember what they set last week is asking them to take the figure on
|
|
88
87
|
// trust. Shown every time, so the number that comes back is never a surprise.
|
|
89
88
|
const flagged = args.indexOf('--model');
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
// Named on the line, or else the person's own comparison model, which the
|
|
90
|
+
// service fills in and names in its reply (service catalog 14).
|
|
91
|
+
const comparedTo = flagged >= 0 ? args[flagged + 1] : undefined;
|
|
92
|
+
if (comparedTo) {
|
|
93
|
+
out(ui.c.dim(` comparing against ${ui.c.bold(comparedTo)}`));
|
|
94
|
+
out();
|
|
95
|
+
}
|
|
96
96
|
// Either way round: on the line for somebody who knows what they want, or
|
|
97
97
|
// asked for when they simply typed the command.
|
|
98
98
|
// Text piped in is read to its end first and attached as `standard input`:
|
|
@@ -202,7 +202,7 @@ async function cmdAsk(args) {
|
|
|
202
202
|
const verb = saved !== null && saved !== undefined && saved < 0 ? 'more' : 'less';
|
|
203
203
|
const amount = money(Math.abs(saved ?? 0));
|
|
204
204
|
out(` ran on ${ui.c.bold(ran)} ${ours} to finish`);
|
|
205
|
-
out(` ${ui.c.dim(`on ${callingModel} it would have been ${theirs}, so ${amount} ${verb}`)}`);
|
|
205
|
+
out(` ${ui.c.dim(`on ${reply.decision.would_have_used || callingModel} it would have been ${theirs}, so ${amount} ${verb}`)}`);
|
|
206
206
|
}
|
|
207
207
|
else {
|
|
208
208
|
out(` ran on ${ui.c.bold(ran)}`);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const MAP_HELP = "\n comprism map what the map of this
|
|
1
|
+
export declare const MAP_HELP = "\n comprism map what the map of this workspace holds\n comprism map refresh read every file again, now\n comprism map forget remove this workspace's map from the service\n comprism map off ask your administrator to switch it off\n\n The map is a record of what your workspace is made of: its functions, screens,\n endpoints and tables, and what connects to what. It is read on this machine\n and only its structure is sent. Your source code never leaves here.\n\n It is kept current by itself. Every job checks the files first and reads back\n whatever moved, so you should not normally need any of this.\n";
|
|
2
2
|
export declare function cmdMap(args: string[]): Promise<number>;
|
package/out/commands/codemap.js
CHANGED
|
@@ -55,12 +55,12 @@ const sync_1 = require("../graph/sync");
|
|
|
55
55
|
const settings_1 = require("./settings");
|
|
56
56
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
57
57
|
exports.MAP_HELP = `
|
|
58
|
-
comprism map what the map of this
|
|
58
|
+
comprism map what the map of this workspace holds
|
|
59
59
|
comprism map refresh read every file again, now
|
|
60
|
-
comprism map forget remove this
|
|
60
|
+
comprism map forget remove this workspace's map from the service
|
|
61
61
|
comprism map off ask your administrator to switch it off
|
|
62
62
|
|
|
63
|
-
The map is a record of what your
|
|
63
|
+
The map is a record of what your workspace is made of: its functions, screens,
|
|
64
64
|
endpoints and tables, and what connects to what. It is read on this machine
|
|
65
65
|
and only its structure is sent. Your source code never leaves here.
|
|
66
66
|
|
|
@@ -178,14 +178,14 @@ async function cmdStatus() {
|
|
|
178
178
|
process.exitCode = 3;
|
|
179
179
|
}
|
|
180
180
|
else if (reply.httpStatus) {
|
|
181
|
-
out(ui.fail('The
|
|
181
|
+
out(ui.fail('The organization could not confirm this account.'));
|
|
182
182
|
out(` ${ui.c.dim(reply.message || 'the service refused the request')}`);
|
|
183
183
|
process.exitCode = 1;
|
|
184
184
|
}
|
|
185
185
|
else {
|
|
186
186
|
// Only what this machine knows, and said to be only that (manual 1.4).
|
|
187
187
|
out(ui.fail(`This machine is pointed at ${ui.c.bold(c.url)}, which did not answer.`));
|
|
188
|
-
out(` ${ui.c.dim(reply.message || 'no answer from the
|
|
188
|
+
out(` ${ui.c.dim(reply.message || 'no answer from the organization')}`);
|
|
189
189
|
out(` ${ui.c.dim('on this machine only:')} ${machineLine(c)}`);
|
|
190
190
|
process.exitCode = 6;
|
|
191
191
|
}
|
|
@@ -194,12 +194,12 @@ async function cmdStatus() {
|
|
|
194
194
|
}
|
|
195
195
|
if (reply.served === false) {
|
|
196
196
|
out(ui.warn(`${ui.c.bold(c.url)} answered, but is running a build that cannot report a session.`));
|
|
197
|
-
out(ui.c.dim(reply.message || 'Ask your
|
|
197
|
+
out(ui.c.dim(reply.message || 'Ask your organization administrator to update the service.'));
|
|
198
198
|
process.exitCode = 1;
|
|
199
199
|
return;
|
|
200
200
|
}
|
|
201
201
|
if (reply.granted === false || !me?.signed_in) {
|
|
202
|
-
out(ui.fail(reply.message || 'The
|
|
202
|
+
out(ui.fail(reply.message || 'The organization did not confirm a signed in account.'));
|
|
203
203
|
out(' Run comprism login to sign in.');
|
|
204
204
|
process.exitCode = 3;
|
|
205
205
|
return;
|
package/out/commands/config.js
CHANGED
|
@@ -67,7 +67,7 @@ async function service(op, payload) {
|
|
|
67
67
|
const out = (s = '') => process.stdout.write(s + '\n');
|
|
68
68
|
function notHere(key) {
|
|
69
69
|
out(ui.fail(`\`${key}\` is not a setting for this machine, so nothing was changed.`));
|
|
70
|
-
out(ui.c.dim(` This machine keeps: ${Object.keys(machine_1.MACHINE_KEYS).join(', ')}.
|
|
70
|
+
out(ui.c.dim(` This machine keeps: ${Object.keys(machine_1.MACHINE_KEYS).join(', ')}. Workspace and personal settings are kept by the service (manual 2.10).`));
|
|
71
71
|
out();
|
|
72
72
|
return 1;
|
|
73
73
|
}
|
package/out/commands/cost.js
CHANGED
|
@@ -87,7 +87,7 @@ async function cmdCost(args) {
|
|
|
87
87
|
// would tell somebody their work cost nothing.
|
|
88
88
|
if (reply.served === false) {
|
|
89
89
|
out();
|
|
90
|
-
out(ui.warn('This
|
|
90
|
+
out(ui.warn('This organization is running a build that cannot answer this yet.'));
|
|
91
91
|
out(` ${ui.c.dim(reply.message || '')}`);
|
|
92
92
|
out();
|
|
93
93
|
return 1;
|
|
@@ -95,7 +95,7 @@ async function cmdCost(args) {
|
|
|
95
95
|
const report = reply.spend;
|
|
96
96
|
if (!report || !report.session) {
|
|
97
97
|
out();
|
|
98
|
-
out(ui.info(reply.message || 'No work has been recorded in this
|
|
98
|
+
out(ui.info(reply.message || 'No work has been recorded in this organization yet.'));
|
|
99
99
|
out();
|
|
100
100
|
return 0;
|
|
101
101
|
}
|
|
@@ -105,8 +105,8 @@ async function cmdCost(args) {
|
|
|
105
105
|
const p = report.presentation;
|
|
106
106
|
if (!p) {
|
|
107
107
|
out();
|
|
108
|
-
out(ui.warn('This
|
|
109
|
-
out(` ${ui.c.dim('Deploy the
|
|
108
|
+
out(ui.warn('This organization answered without the breakdown this version draws.'));
|
|
109
|
+
out(` ${ui.c.dim('Deploy the organization, or run `comprism status` to see which one you are on.')}`);
|
|
110
110
|
out();
|
|
111
111
|
return 1;
|
|
112
112
|
}
|
package/out/commands/hooks.js
CHANGED
|
@@ -43,7 +43,7 @@ exports.cmdHooks = cmdHooks;
|
|
|
43
43
|
*/
|
|
44
44
|
const ui = __importStar(require("../lib/ui"));
|
|
45
45
|
const project_ops_1 = require("../lib/project-ops");
|
|
46
|
-
const hooks_1 = require("../executor/hooks");
|
|
46
|
+
const hooks_1 = require("../machine/executor/hooks");
|
|
47
47
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
48
48
|
async function cmdHooks(args) {
|
|
49
49
|
const facts = await (0, project_ops_1.currentProject)();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type InstallMethod } from '../
|
|
1
|
+
import { type InstallMethod } from '../machine/runtime/self';
|
|
2
2
|
/** The header the tenant reads to decide whether this machine may be served. */
|
|
3
3
|
export declare const WORKSPACE_KEY_HEADER = "x-comprism-key";
|
|
4
4
|
export declare function envScriptPath(): string;
|
package/out/commands/install.js
CHANGED
|
@@ -78,7 +78,8 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
78
78
|
const node_child_process_1 = require("node:child_process");
|
|
79
79
|
const config_1 = require("../lib/config");
|
|
80
80
|
const connection_1 = require("../lib/connection");
|
|
81
|
-
const self_1 = require("../
|
|
81
|
+
const self_1 = require("../machine/runtime/self");
|
|
82
|
+
const words_1 = require("../lib/words");
|
|
82
83
|
/** The header the tenant reads to decide whether this machine may be served. */
|
|
83
84
|
exports.WORKSPACE_KEY_HEADER = 'x-comprism-key';
|
|
84
85
|
const MARKER_START = '# >>> comprism >>>';
|
|
@@ -391,7 +392,7 @@ async function probeDesktopConnector(binary) {
|
|
|
391
392
|
catch (err) {
|
|
392
393
|
resolve({
|
|
393
394
|
ok: false,
|
|
394
|
-
detail: err instanceof Error ? err.message :
|
|
395
|
+
detail: err instanceof Error ? err.message : (0, words_1.word)('connectorNotStarted'),
|
|
395
396
|
});
|
|
396
397
|
return;
|
|
397
398
|
}
|
|
@@ -80,7 +80,7 @@ async function cmdInstructions(args) {
|
|
|
80
80
|
const facts = await (0, project_ops_1.currentProject)();
|
|
81
81
|
if (args[0] === "edit") {
|
|
82
82
|
if (!args.includes("--personal")) {
|
|
83
|
-
out(ui.fail("
|
|
83
|
+
out(ui.fail("Workspace instructions are files in the workspace; edit them there. "
|
|
84
84
|
+ "For yours: comprism instructions edit --personal"));
|
|
85
85
|
return 2;
|
|
86
86
|
}
|
|
@@ -41,7 +41,7 @@ exports.projectSettings = projectSettings;
|
|
|
41
41
|
* adding one by address or by command, signing in, its tools, removing one.
|
|
42
42
|
*
|
|
43
43
|
* The service decides every status, tool, rule and word. This sends the
|
|
44
|
-
* project's settings file so the
|
|
44
|
+
* project's settings file so the workspace's own connections are known, writes
|
|
45
45
|
* the key the service returns for a project connection, starts an approved
|
|
46
46
|
* local tool server only long enough to count its tools, opens the browser
|
|
47
47
|
* for a sign in and waits for it. No token ever reaches this machine.
|
|
@@ -49,10 +49,10 @@ exports.projectSettings = projectSettings;
|
|
|
49
49
|
const child_process_1 = require("child_process");
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
|
-
const toolservers_1 = require("../executor/toolservers");
|
|
52
|
+
const toolservers_1 = require("../machine/executor/toolservers");
|
|
53
53
|
const gateway_1 = require("../lib/gateway");
|
|
54
54
|
const project_ops_1 = require("../lib/project-ops");
|
|
55
|
-
const project_1 = require("../
|
|
55
|
+
const project_1 = require("../machine/folder/project");
|
|
56
56
|
const ui = __importStar(require("../lib/ui"));
|
|
57
57
|
const SETTINGS = ".completionprism/settings.json";
|
|
58
58
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
@@ -77,7 +77,7 @@ async function call(root, payload) {
|
|
|
77
77
|
body = reply.integrations;
|
|
78
78
|
}
|
|
79
79
|
if (!reply.ok || reply.served === false || !body) {
|
|
80
|
-
out(` ${ui.fail(reply.message || "Your connections could not be read from your
|
|
80
|
+
out(` ${ui.fail(reply.message || "Your connections could not be read from your organization.")}`);
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
83
83
|
if (body.error) {
|
package/out/commands/keys.js
CHANGED
|
@@ -104,17 +104,17 @@ async function keyState() {
|
|
|
104
104
|
// then this client's placeholder, and reading an empty `providers` as "no
|
|
105
105
|
// keys" is precisely the fault above.
|
|
106
106
|
if (!reply.ok)
|
|
107
|
-
return { reached: false, why: reply.message || 'the
|
|
107
|
+
return { reached: false, why: reply.message || 'the organization could not be reached' };
|
|
108
108
|
// An older workspace that does not serve this question has also not told us
|
|
109
109
|
// there are no keys. It has told us it cannot answer.
|
|
110
110
|
if (reply.served === false)
|
|
111
|
-
return { reached: false, why: reply.message || 'this
|
|
111
|
+
return { reached: false, why: reply.message || 'this organization is running an older build' };
|
|
112
112
|
// The workspace answered but could not establish part of what it answered.
|
|
113
113
|
// An empty vendor list here is a list we failed to obtain, not a list of
|
|
114
114
|
// nothing, and drawing it as "you have no keys" is the original fault with
|
|
115
115
|
// one more layer in front of it.
|
|
116
116
|
if (reply.complete === false)
|
|
117
|
-
return { reached: false, why: reply.message || 'your
|
|
117
|
+
return { reached: false, why: reply.message || 'your organization could not check its vendor keys' };
|
|
118
118
|
return { reached: true, hasKey: reply.providers.some((p) => p.has_key) };
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
@@ -182,15 +182,15 @@ async function show() {
|
|
|
182
182
|
if (!reply.ok || reply.served === false || reply.complete === false) {
|
|
183
183
|
// NOT "you have no keys". We did not get an answer, so nothing is known
|
|
184
184
|
// about this account, and saying otherwise is the 17 September fault.
|
|
185
|
-
out(ui.fail('Your
|
|
186
|
-
out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the
|
|
185
|
+
out(ui.fail('Your organization could not be reached, so nothing is known about your keys.'));
|
|
186
|
+
out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the organization')}`);
|
|
187
187
|
out();
|
|
188
188
|
return { reached: false, stored: 0, total: 0 };
|
|
189
189
|
}
|
|
190
190
|
if (reply.providers.length === 0) {
|
|
191
191
|
// A workspace with no vendors at all is not a workspace that told us it
|
|
192
192
|
// holds no keys. Treated as unreachable so no caller offers to take one.
|
|
193
|
-
out(ui.fail('Your
|
|
193
|
+
out(ui.fail('Your organization returned no vendors, so nothing is known about your keys.'));
|
|
194
194
|
out(` ${ui.c.dim(reply.message || 'the vendor list came back empty')}`);
|
|
195
195
|
out();
|
|
196
196
|
return { reached: false, stored: 0, total: 0 };
|
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.");
|