@illuminis/comprism 0.1.4 → 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 +5 -5
- package/out/agent/render.d.ts +39 -6
- package/out/agent/render.js +287 -28
- package/out/agent/session.d.ts +21 -1
- package/out/agent/session.js +81 -17
- package/out/commands/agents.js +3 -3
- package/out/commands/ask.js +20 -11
- 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 +97 -27
- 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.d.ts +4 -0
- package/out/commands/repl.js +563 -101
- 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.d.ts +25 -1
- package/out/commands/welcome.js +65 -38
- 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 +9 -5
- package/out/lib/keyboard.d.ts +3 -0
- package/out/lib/keyboard.js +7 -0
- package/out/lib/lastlogin.d.ts +14 -0
- package/out/lib/lastlogin.js +105 -0
- package/out/lib/machine.js +1 -1
- package/out/lib/picker.d.ts +1 -0
- package/out/lib/picker.js +158 -0
- package/out/lib/project-ops.d.ts +1 -1
- package/out/lib/project-ops.js +4 -4
- package/out/lib/prompt.d.ts +3 -0
- package/out/lib/prompt.js +21 -0
- 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/startcache.d.ts +13 -0
- package/out/lib/startcache.js +78 -0
- package/out/lib/ui.d.ts +11 -0
- package/out/lib/ui.js +28 -0
- package/out/lib/voice.d.ts +36 -0
- package/out/lib/voice.js +137 -2
- 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/native/dictate +0 -0
- package/out/providers/index.js +2 -1
- package/out/thin.js +13 -12
- package/package.json +5 -4
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);
|
package/out/commands/settings.js
CHANGED
|
@@ -41,29 +41,9 @@ exports.currentWorkspace = currentWorkspace;
|
|
|
41
41
|
exports.cmdProviders = cmdProviders;
|
|
42
42
|
exports.cmdModel = cmdModel;
|
|
43
43
|
exports.cmdProject = cmdProject;
|
|
44
|
-
/**
|
|
45
|
-
* The three things a person sets once and then forgets: which model they are
|
|
46
|
-
* compared against, which vendors they can reach, and which folder they work in.
|
|
47
|
-
*
|
|
48
|
-
* ── What is stored here, and what is not ──────────────────────────────────
|
|
49
|
-
*
|
|
50
|
-
* A PREFERENCE lives on this machine: the model you would otherwise have used,
|
|
51
|
-
* and the folder you work in. Neither is a secret and neither is model logic;
|
|
52
|
-
* they are two facts about you, and a round trip to ask us for them would be
|
|
53
|
-
* slower and no safer.
|
|
54
|
-
*
|
|
55
|
-
* THE MODEL LIST does not live here. It comes from our server on every call,
|
|
56
|
-
* because the models and their prices are ours, and because a copy on a
|
|
57
|
-
* customer's laptop goes stale the day a vendor changes a price. A stale price
|
|
58
|
-
* silently corrupts every figure downstream of it, which is the exact failure
|
|
59
|
-
* this product exists to replace.
|
|
60
|
-
*/
|
|
61
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
62
44
|
const node_path_1 = __importDefault(require("node:path"));
|
|
63
|
-
const prompt_1 = require("../lib/prompt");
|
|
64
45
|
const gateway_1 = require("../lib/gateway");
|
|
65
46
|
const config_1 = require("../lib/config");
|
|
66
|
-
const project_1 = require("../lib/project");
|
|
67
47
|
const ui = __importStar(require("../lib/ui"));
|
|
68
48
|
const out = (s = '') => process.stdout.write(s + '\n');
|
|
69
49
|
/** Where the chosen folder is remembered. Beside the rest of the settings. */
|
|
@@ -78,12 +58,10 @@ function workspaceFile() {
|
|
|
78
58
|
* current one would be a trap.
|
|
79
59
|
*/
|
|
80
60
|
function currentWorkspace() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
catch { /* nothing saved, which is the normal case */ }
|
|
61
|
+
// The folder you are standing in, as in every other terminal tool. A folder
|
|
62
|
+
// saved on this laptop used to override it; workspaces now live on the
|
|
63
|
+
// service, the same in every client, and `workspace <name>` opens another
|
|
64
|
+
// (web manual 13.2).
|
|
87
65
|
return { path: process.cwd(), source: 'cwd' };
|
|
88
66
|
}
|
|
89
67
|
/**
|
|
@@ -107,8 +85,8 @@ async function cmdProviders() {
|
|
|
107
85
|
// have, which is the fault reported on 17 September 2026.
|
|
108
86
|
if (!reply.ok || reply.served === false || reply.complete === false
|
|
109
87
|
|| !reply.providers || reply.providers.length === 0) {
|
|
110
|
-
out(ui.fail('Your
|
|
111
|
-
out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the
|
|
88
|
+
out(ui.fail('Your organization could not tell us which vendors it can reach.'));
|
|
89
|
+
out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the organization')}`);
|
|
112
90
|
out(` ${ui.c.dim('check the address with')} ${ui.c.bold('comprism status')}`);
|
|
113
91
|
out();
|
|
114
92
|
process.exitCode = 1;
|
|
@@ -136,111 +114,40 @@ async function cmdProviders() {
|
|
|
136
114
|
* have used, which is the only thing a saving can honestly be measured against.
|
|
137
115
|
*/
|
|
138
116
|
async function cmdModel(args) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const models = (reply.providers || []).flatMap((p) => p.models);
|
|
148
|
-
// Same rule as every other reader: an answer we did not get is not an answer
|
|
149
|
-
// of none.
|
|
150
|
-
if (!reply.ok || reply.served === false || reply.complete === false
|
|
151
|
-
|| models.length === 0) {
|
|
152
|
-
out(ui.fail('Your workspace could not tell us which models it can reach.'));
|
|
153
|
-
out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the workspace')}`);
|
|
154
|
-
out();
|
|
155
|
-
process.exitCode = 1;
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
const match = (value) => models.find((m) => m.id === value || m.key === value
|
|
159
|
-
|| m.label.toLowerCase() === value.toLowerCase());
|
|
160
|
-
let chosen = named ? match(named) : undefined;
|
|
161
|
-
if (named && !chosen) {
|
|
162
|
-
out(ui.fail(`No model called "${named}".`));
|
|
163
|
-
out(` ${ui.c.dim('see the list with')} ${ui.c.bold('comprism providers')}`);
|
|
164
|
-
out();
|
|
117
|
+
// The comparison model is the person's own setting on the service, the same
|
|
118
|
+
// in every client (service catalog 14); the service lists, checks and words it.
|
|
119
|
+
const named = args.filter((a) => !a.startsWith('--')).join(' ');
|
|
120
|
+
const reply = await (0, gateway_1.ask)({
|
|
121
|
+
intent: 'command', prompt: '', payload: { words: `model ${named}`.trim() },
|
|
122
|
+
});
|
|
123
|
+
if (!reply.lines?.length) {
|
|
124
|
+
out(ui.fail(reply.message || 'Your organization could not answer that.'));
|
|
165
125
|
process.exitCode = 1;
|
|
166
126
|
return;
|
|
167
127
|
}
|
|
168
|
-
if (!chosen) {
|
|
169
|
-
models.forEach((m, i) => {
|
|
170
|
-
const n = String(i + 1).padStart(2);
|
|
171
|
-
out(` ${n}. ${m.label.padEnd(24)} ${ui.c.dim(`${m.provider} ${m.tier}`)}`);
|
|
172
|
-
});
|
|
173
|
-
out();
|
|
174
|
-
const answer = await (0, prompt_1.ask)(' number, or a model name: ');
|
|
175
|
-
(0, prompt_1.closePrompt)();
|
|
176
|
-
if (!answer) {
|
|
177
|
-
out(ui.info('Left as it was.'));
|
|
178
|
-
out();
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
const asNumber = Number(answer);
|
|
182
|
-
chosen = Number.isInteger(asNumber) && asNumber >= 1 && asNumber <= models.length
|
|
183
|
-
? models[asNumber - 1]
|
|
184
|
-
: match(answer);
|
|
185
|
-
if (!chosen) {
|
|
186
|
-
out(ui.fail(`"${answer}" is not on the list.`));
|
|
187
|
-
out();
|
|
188
|
-
process.exitCode = 1;
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
(0, config_1.saveConfig)({ ...cfg, defaultModel: chosen.id });
|
|
193
128
|
out();
|
|
194
|
-
|
|
195
|
-
|
|
129
|
+
for (const line of reply.lines)
|
|
130
|
+
out(line);
|
|
196
131
|
out();
|
|
132
|
+
if (reply.granted === false)
|
|
133
|
+
process.exitCode = 1;
|
|
197
134
|
}
|
|
198
135
|
async function cmdProject(args) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
: 'saved, so it is used wherever you run the command from')}`);
|
|
207
|
-
out();
|
|
208
|
-
if (args.includes('--clear')) {
|
|
209
|
-
try {
|
|
210
|
-
node_fs_1.default.unlinkSync(workspaceFile());
|
|
211
|
-
}
|
|
212
|
-
catch { /* nothing was saved */ }
|
|
213
|
-
out(ui.ok('Cleared. The folder you are standing in is used again.'));
|
|
214
|
-
out();
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
// `comprism project` on its own shows the folder (manual 2.1). Asking only
|
|
218
|
-
// when a person is at the keyboard and typed nothing, as before.
|
|
219
|
-
let target = named;
|
|
220
|
-
if (!target) {
|
|
221
|
-
if (!process.stdin.isTTY)
|
|
222
|
-
return;
|
|
223
|
-
const answer = await (0, prompt_1.ask)(' new folder, or enter to keep it: ');
|
|
224
|
-
(0, prompt_1.closePrompt)();
|
|
225
|
-
if (!answer) {
|
|
226
|
-
out(ui.info('Left as it was.'));
|
|
227
|
-
out();
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
target = answer;
|
|
231
|
-
}
|
|
232
|
-
const found = (0, project_1.checkFolder)(target);
|
|
233
|
-
if (!found.ok) {
|
|
234
|
-
out(ui.fail(found.why));
|
|
235
|
-
out();
|
|
236
|
-
process.exitCode = 2;
|
|
136
|
+
// `comprism workspace ...` typed at the shell: the same service command a
|
|
137
|
+
// session runs (web manual 13.2). Opening one takes effect in a session.
|
|
138
|
+
const { runServiceCommand } = await Promise.resolve().then(() => __importStar(require('../lib/servicecommand')));
|
|
139
|
+
const said = await runServiceCommand(['workspace', ...args].join(' ').trim(), { cwd: process.cwd() });
|
|
140
|
+
if (!said.reached) {
|
|
141
|
+
out(ui.fail(said.message || 'Your organization could not answer that.'));
|
|
142
|
+
process.exitCode = 1;
|
|
237
143
|
return;
|
|
238
144
|
}
|
|
239
|
-
node_fs_1.default.mkdirSync((0, config_1.homeDir)(), { recursive: true });
|
|
240
|
-
node_fs_1.default.writeFileSync(workspaceFile(), JSON.stringify({ path: found.path }, null, 2), { mode: 0o600 });
|
|
241
|
-
out(ui.ok(`Project folder set to ${ui.c.bold(found.path)}.`));
|
|
242
|
-
out(` ${ui.c.dim('clear it with')} ${ui.c.bold('comprism project --clear')}`);
|
|
243
145
|
out();
|
|
146
|
+
for (const line of said.lines)
|
|
147
|
+
out(line);
|
|
148
|
+
out();
|
|
149
|
+
if (!said.ok)
|
|
150
|
+
process.exitCode = 1;
|
|
244
151
|
}
|
|
245
152
|
/** The older name, kept so nothing that calls it breaks. */
|
|
246
153
|
exports.cmdWorkspace = cmdProject;
|
package/out/commands/skills.js
CHANGED
|
@@ -50,7 +50,7 @@ const fs = __importStar(require("fs"));
|
|
|
50
50
|
const path = __importStar(require("path"));
|
|
51
51
|
const commandlist_1 = require("../lib/commandlist");
|
|
52
52
|
const gateway_1 = require("../lib/gateway");
|
|
53
|
-
const project_1 = require("../
|
|
53
|
+
const project_1 = require("../machine/folder/project");
|
|
54
54
|
const ui = __importStar(require("../lib/ui"));
|
|
55
55
|
const ROUNDS = 6;
|
|
56
56
|
/** What a folder sent with `add` may hold, beside its SKILL.md. The service
|
|
@@ -65,7 +65,7 @@ async function skillRows(folder, op = "list") {
|
|
|
65
65
|
const reply = await (0, gateway_1.ask)({ intent: "skills", prompt: "", skillsPayload: { op, round, files, listings, project: root } });
|
|
66
66
|
const body = reply.skills;
|
|
67
67
|
if (!reply.ok || reply.served === false || !body) {
|
|
68
|
-
return { rows: [], error: reply.message || "The skill list could not be read from your
|
|
68
|
+
return { rows: [], error: reply.message || "The skill list could not be read from your organization." };
|
|
69
69
|
}
|
|
70
70
|
if (!body.wants) {
|
|
71
71
|
return op === "check"
|
|
@@ -53,8 +53,8 @@ const path = __importStar(require("path"));
|
|
|
53
53
|
const child_process_1 = require("child_process");
|
|
54
54
|
const ui = __importStar(require("../lib/ui"));
|
|
55
55
|
const queue_1 = require("../lib/queue");
|
|
56
|
-
const project_1 = require("../
|
|
57
|
-
const self_1 = require("../
|
|
56
|
+
const project_1 = require("../machine/folder/project");
|
|
57
|
+
const self_1 = require("../machine/runtime/self");
|
|
58
58
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
59
59
|
const err = (s = "") => process.stderr.write(`${s}\n`);
|
|
60
60
|
/** Values typed after flags, so they are never read as the request. */
|
|
@@ -64,9 +64,9 @@ function words(args) {
|
|
|
64
64
|
}
|
|
65
65
|
function failed(reply) {
|
|
66
66
|
if (!reply.ok)
|
|
67
|
-
return reply.message || "Your
|
|
67
|
+
return reply.message || "Your organization could not be reached.";
|
|
68
68
|
if (reply.served === false)
|
|
69
|
-
return "Your
|
|
69
|
+
return "Your organization is running an older build that does not answer this yet.";
|
|
70
70
|
if (reply.granted === false)
|
|
71
71
|
return reply.message || "Refused.";
|
|
72
72
|
return null;
|
|
@@ -216,7 +216,7 @@ async function runCloud(job) {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
const base = git(work, ["rev-parse", "HEAD"]).out.trim();
|
|
219
|
-
const { availability } = await Promise.resolve().then(() => __importStar(require("../executor/sandbox")));
|
|
219
|
+
const { availability } = await Promise.resolve().then(() => __importStar(require("../machine/executor/sandbox")));
|
|
220
220
|
const code = await runJob(job, work, availability().system ? ["--sandbox"] : []);
|
|
221
221
|
git(work, ["add", "-A"]);
|
|
222
222
|
const patch = git(work, ["diff", "--cached", "--binary", base]).out;
|
|
@@ -258,7 +258,7 @@ async function cmdWorker(args) {
|
|
|
258
258
|
else {
|
|
259
259
|
const folder = job.project_root && fs.existsSync(job.project_root) ? job.project_root : null;
|
|
260
260
|
if (!folder) {
|
|
261
|
-
await (0, queue_1.queue)("failed", { id: job.id, why: `the
|
|
261
|
+
await (0, queue_1.queue)("failed", { id: job.id, why: `the workspace folder ${job.project_root} is not on this machine` });
|
|
262
262
|
}
|
|
263
263
|
else {
|
|
264
264
|
const code = await runJob(job, folder);
|
package/out/commands/update.js
CHANGED
|
@@ -50,7 +50,7 @@ const fs = __importStar(require("fs"));
|
|
|
50
50
|
const path = __importStar(require("path"));
|
|
51
51
|
const ui = __importStar(require("../lib/ui"));
|
|
52
52
|
const gateway_1 = require("../lib/gateway");
|
|
53
|
-
const self_1 = require("../
|
|
53
|
+
const self_1 = require("../machine/runtime/self");
|
|
54
54
|
const version_1 = require("../lib/version");
|
|
55
55
|
const install_1 = require("./install");
|
|
56
56
|
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
@@ -1 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SessionOut } from '../lib/gateway';
|
|
2
|
+
/**
|
|
3
|
+
* Who this machine is signed in as, and everything else the header prints.
|
|
4
|
+
*
|
|
5
|
+
* ── One call, to the one service ──────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* This used to call the platform's own `whoami` for the identity, and the
|
|
8
|
+
* header then had no way at all to say how many vendor keys the account held.
|
|
9
|
+
* Two questions, two addresses, and the header could show a person facts that
|
|
10
|
+
* disagreed with each other. On 17 September 2026 it did exactly that: "User
|
|
11
|
+
* unknown" beside a company name, and a session that then announced no provider
|
|
12
|
+
* key was stored while four were stored and active.
|
|
13
|
+
*
|
|
14
|
+
* Every line below now comes from one request to the single service, so the
|
|
15
|
+
* header either shows a consistent picture or says plainly that it could not
|
|
16
|
+
* reach the workspace. There is no third state in which half of it is true.
|
|
17
|
+
*
|
|
18
|
+
* Null rather than an error when it cannot be reached. A header is the wrong
|
|
19
|
+
* place to fail: somebody on a plane still gets the local facts, and the lines
|
|
20
|
+
* needing the server say so.
|
|
21
|
+
*/
|
|
22
|
+
export declare function session(): Promise<SessionOut | null>;
|
|
23
|
+
/** `known` is who this machine is, when the caller already has it (the last
|
|
24
|
+
* answer, drawn at once while a fresh one is asked for). */
|
|
25
|
+
export declare function showWelcome(known?: SessionOut | null, signingIn?: boolean, withMark?: boolean): Promise<void>;
|
package/out/commands/welcome.js
CHANGED
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.session = session;
|
|
36
37
|
exports.showWelcome = showWelcome;
|
|
37
38
|
/**
|
|
38
39
|
* The first thing anybody sees.
|
|
@@ -95,33 +96,37 @@ async function session() {
|
|
|
95
96
|
return reply.session;
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
|
-
* The mark: a prism
|
|
99
|
+
* The mark: a six layer prism, each layer two cells wider than the one above,
|
|
100
|
+
* colored bottom to top in the illuminis gradient: light purple at the base,
|
|
101
|
+
* then light blue, light green, light gold, light orange and light red at the
|
|
102
|
+
* top, so the cool colors carry the weight of the wide layers. The purple,
|
|
103
|
+
* green and gold are pale shades of the illuminis logo's own
|
|
104
|
+
* (platform/branding/assets).
|
|
99
105
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* carrying the design is the color, which is the point of a prism.
|
|
106
|
+
* No ring and no beams: at terminal size both read as rough, and straight
|
|
107
|
+
* layers stay clean in any terminal (owner, 28 September 2026). Solid colored
|
|
108
|
+
* cells only: a terminal paints a cell's background edge to edge in any font.
|
|
109
|
+
* One pixel to a character, six lines tall.
|
|
105
110
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* base carries all eight. That is a prism doing its job: one input at the top,
|
|
109
|
-
* the whole spectrum at the bottom. Banding it by row would have shown four of
|
|
110
|
-
* the eight and read as a striped triangle instead.
|
|
111
|
-
*
|
|
112
|
-
* The eight values come from the same helper as the rule beneath it, so the
|
|
113
|
-
* mark and the rule can never drift apart.
|
|
111
|
+
* Without color the picture cannot be drawn, so the four row block pyramid
|
|
112
|
+
* stands in: full blocks only, which render the same in every font.
|
|
114
113
|
*/
|
|
115
|
-
const
|
|
114
|
+
const ICON = [
|
|
115
|
+
'..............................f69f97f69f97..............................',
|
|
116
|
+
'........................ffbd8affbd8affbd8affbd8a........................',
|
|
117
|
+
'..................ffdf7fffdf7fffdf7fffdf7fffdf7fffdf7f..................',
|
|
118
|
+
'............a1d38ca1d38ca1d38ca1d38ca1d38ca1d38ca1d38ca1d38c............',
|
|
119
|
+
'......95d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f0......',
|
|
120
|
+
'bba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1dd',
|
|
121
|
+
];
|
|
116
122
|
function mark() {
|
|
123
|
+
const picture = ui.cellArt(ICON);
|
|
124
|
+
if (picture.length)
|
|
125
|
+
return picture;
|
|
117
126
|
const rows = [];
|
|
118
127
|
for (let r = 1; r <= 4; r++) {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
let line = ' '.repeat(left);
|
|
122
|
-
for (let i = 0; i < blocks; i++)
|
|
123
|
-
line += ui.spectrumAt(left + i, '\u2588');
|
|
124
|
-
rows.push(line + ' '.repeat(left));
|
|
128
|
+
const left = 4 - r;
|
|
129
|
+
rows.push(' '.repeat(left) + '\u2588'.repeat(r * 2) + ' '.repeat(left));
|
|
125
130
|
}
|
|
126
131
|
return rows;
|
|
127
132
|
}
|
|
@@ -133,28 +138,43 @@ function row(label, value) {
|
|
|
133
138
|
function readable(name) {
|
|
134
139
|
return name.replace(/[-_]/g, ' ').replace(/\b\w/g, (m) => m.toUpperCase());
|
|
135
140
|
}
|
|
136
|
-
|
|
141
|
+
/** `known` is who this machine is, when the caller already has it (the last
|
|
142
|
+
* answer, drawn at once while a fresh one is asked for). */
|
|
143
|
+
async function showWelcome(known, signingIn = false, withMark = true) {
|
|
137
144
|
const conn = (0, connection_1.readConnection)();
|
|
138
145
|
const cfg = (0, config_1.loadConfig)();
|
|
139
146
|
const folder = (0, settings_1.currentWorkspace)();
|
|
140
|
-
const me = await session();
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
const me = known !== undefined ? known : await session();
|
|
148
|
+
// The mark once per start. Signing in first draws it; the session that
|
|
149
|
+
// follows draws only the account, so nobody sees the same screen twice.
|
|
150
|
+
if (withMark) {
|
|
151
|
+
const art = mark();
|
|
152
|
+
// The name and the line under it sit beside the middle of the mark.
|
|
153
|
+
const at = Math.max(0, Math.floor(art.length / 2) - 1);
|
|
154
|
+
const beside = {
|
|
155
|
+
[at]: `${ui.c.bold('CompletionPrism')} ${ui.c.dim(`v${version_1.COMPRISM_VERSION}`)}`,
|
|
156
|
+
[at + 1]: ui.c.muted('Optimize AI completion economics by optimizing work.'),
|
|
157
|
+
};
|
|
158
|
+
out();
|
|
159
|
+
art.forEach((line, i) => out(beside[i] ? ` ${line} ${beside[i]}` : ` ${line}`));
|
|
160
|
+
out(ui.prismRule());
|
|
161
|
+
out();
|
|
162
|
+
}
|
|
163
|
+
// Signing in comes next and says everything else itself.
|
|
164
|
+
if (signingIn && !conn?.url)
|
|
165
|
+
return;
|
|
149
166
|
if (!conn?.url) {
|
|
150
167
|
// Nothing else here is knowable yet, and the one useful thing to say is the
|
|
151
168
|
// single command that changes that.
|
|
152
169
|
out(row('Signed in', ui.c.amber('not yet')));
|
|
153
|
-
out(row('Comparing', cfg.defaultModel || 'not set'));
|
|
154
170
|
out(row('Workspace', `${folder.path} ${ui.c.dim('(where you are)')}`));
|
|
155
171
|
out();
|
|
156
|
-
|
|
157
|
-
|
|
172
|
+
// Not said when signing in follows at once: naming a command to type, just
|
|
173
|
+
// above the sign in it would start, reads as a second step.
|
|
174
|
+
if (!signingIn) {
|
|
175
|
+
out(` ${ui.c.dim('start with')} ${ui.c.bold('comprism login')}`);
|
|
176
|
+
out();
|
|
177
|
+
}
|
|
158
178
|
return;
|
|
159
179
|
}
|
|
160
180
|
const company = me?.company || readable(conn.tenant || 'unknown');
|
|
@@ -165,11 +185,18 @@ async function showWelcome() {
|
|
|
165
185
|
// machine happens to hold. A client that can only echo its own stored address
|
|
166
186
|
// can never tell a person that the address is the thing that is wrong, which
|
|
167
187
|
// is exactly what happened when a machine sat pointed at a dead laptop port.
|
|
168
|
-
|
|
188
|
+
// Except on this laptop: there the server names its public address, which is
|
|
189
|
+
// not where this machine is talking, and "you are on production" is the
|
|
190
|
+
// single most confusing thing a developer testing locally can be told.
|
|
191
|
+
const local = (0, connection_1.isLocalAddress)(conn.url);
|
|
192
|
+
const address = local
|
|
193
|
+
? `${conn.url.replace(/^https?:\/\//, '')} ${ui.c.dim('(this laptop)')}`
|
|
194
|
+
: (me?.workspace_url || conn.url).replace(/^https?:\/\//, '');
|
|
169
195
|
out(row('User', who));
|
|
170
196
|
out(row('Company', company));
|
|
171
|
-
out(row('Server', ui.c.dim(address)));
|
|
172
|
-
|
|
197
|
+
out(row('Server', local ? address : ui.c.dim(address)));
|
|
198
|
+
// The service's own record of the person's choice (service catalog 14).
|
|
199
|
+
out(row('Comparing', `${me?.comparing || ui.c.amber('not set')} ${ui.c.dim('change with `comprism model`')}`));
|
|
173
200
|
out(row('Workspace', `${folder.path} ${ui.c.dim(folder.source === 'cwd' ? '(where you are)' : '(saved)')}`));
|
|
174
201
|
if (plan) {
|
|
175
202
|
out(row('Plan', allowance
|
|
@@ -178,7 +205,7 @@ async function showWelcome() {
|
|
|
178
205
|
}
|
|
179
206
|
if (!me) {
|
|
180
207
|
out();
|
|
181
|
-
out(` ${ui.c.amber('your
|
|
208
|
+
out(` ${ui.c.amber('your organization could not be reached, so only local settings are shown')}`);
|
|
182
209
|
out(` ${ui.c.dim('nothing here is known about your account, including your provider keys')}`);
|
|
183
210
|
}
|
|
184
211
|
else if (me.vendors_known === false) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProjectFacts } from "../
|
|
1
|
+
import type { ProjectFacts } from "../machine/folder/project";
|
|
2
2
|
/** The folder a `--worktree` job runs in, creating the worktree the first time.
|
|
3
3
|
* Null after saying why, when it cannot be made. */
|
|
4
4
|
export declare function ensureWorktree(facts: ProjectFacts, name: string, session: string): Promise<string | null>;
|
package/out/graph/sync.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export declare function readerReport(): string;
|
|
|
57
57
|
* behind, and the agent is told the thing it just created does not exist.
|
|
58
58
|
*
|
|
59
59
|
* So this is awaited before the write's result goes back. One round trip: the
|
|
60
|
-
* file's facts and the
|
|
60
|
+
* file's facts and the workspace's new fingerprint travel together, and the
|
|
61
61
|
* service stores, stamps and rejoins in that single call.
|
|
62
62
|
*
|
|
63
63
|
* Failure is silent on purpose. A map that could not be updated must never turn
|
package/out/graph/sync.js
CHANGED
|
@@ -22,9 +22,9 @@ exports.pushFile = pushFile;
|
|
|
22
22
|
* says what it needs; the machine reads exactly that and sends structure back.
|
|
23
23
|
*/
|
|
24
24
|
const gateway_1 = require("../lib/gateway");
|
|
25
|
-
const build_1 = require("
|
|
26
|
-
const read_python_1 = require("
|
|
27
|
-
const read_typescript_1 = require("
|
|
25
|
+
const build_1 = require("../machine/codemap/build");
|
|
26
|
+
const read_python_1 = require("../machine/codemap/read-python");
|
|
27
|
+
const read_typescript_1 = require("../machine/codemap/read-typescript");
|
|
28
28
|
/** How many files' facts go in one call.
|
|
29
29
|
*
|
|
30
30
|
* A whole project in one request is several megabytes and fails in the least
|
|
@@ -83,7 +83,7 @@ async function refresh(root, workspace, opts = {}) {
|
|
|
83
83
|
return { ...blank, current: false, message: "The service could not be reached, so the map was left as it is. Work carries on without it." };
|
|
84
84
|
}
|
|
85
85
|
if (now.fresh && !opts.force) {
|
|
86
|
-
return { ...blank, current: true, message: `The map already matches all ${state.files.length} files in this
|
|
86
|
+
return { ...blank, current: true, message: `The map already matches all ${state.files.length} files in this workspace.` };
|
|
87
87
|
}
|
|
88
88
|
// What the service already holds, so only what moved is read. It came back
|
|
89
89
|
// with the status above when there was a map to describe, which is one round
|
|
@@ -165,7 +165,7 @@ function coverageSentence(unread, total) {
|
|
|
165
165
|
gaps.push(`${unread.typescript} TypeScript files could not be read because this installation has no TypeScript compiler`);
|
|
166
166
|
}
|
|
167
167
|
if (!gaps.length)
|
|
168
|
-
return `It covers all ${total} code files in this
|
|
168
|
+
return `It covers all ${total} code files in this workspace.`;
|
|
169
169
|
return `It covers ${total - unread.python - unread.typescript} of ${total} code files: ${gaps.join("; ")}.`;
|
|
170
170
|
}
|
|
171
171
|
/** What this machine can read at all. Asked before anything else, so a person
|
|
@@ -193,7 +193,7 @@ function readerReport() {
|
|
|
193
193
|
* behind, and the agent is told the thing it just created does not exist.
|
|
194
194
|
*
|
|
195
195
|
* So this is awaited before the write's result goes back. One round trip: the
|
|
196
|
-
* file's facts and the
|
|
196
|
+
* file's facts and the workspace's new fingerprint travel together, and the
|
|
197
197
|
* service stores, stamps and rejoins in that single call.
|
|
198
198
|
*
|
|
199
199
|
* Failure is silent on purpose. A map that could not be updated must never turn
|
package/out/lib/attach.js
CHANGED
|
@@ -83,6 +83,7 @@ const fs = __importStar(require("node:fs"));
|
|
|
83
83
|
const os = __importStar(require("node:os"));
|
|
84
84
|
const path = __importStar(require("node:path"));
|
|
85
85
|
const gateway_1 = require("./gateway");
|
|
86
|
+
const words_1 = require("./words");
|
|
86
87
|
/**
|
|
87
88
|
* Take the shell's escaping back off a path.
|
|
88
89
|
*
|
|
@@ -136,7 +137,7 @@ function localProblem(file, shown) {
|
|
|
136
137
|
link = fs.lstatSync(file);
|
|
137
138
|
}
|
|
138
139
|
catch {
|
|
139
|
-
return { code: 'not_found', message:
|
|
140
|
+
return { code: 'not_found', message: (0, words_1.word)('fileNotFound', { file: shown }) };
|
|
140
141
|
}
|
|
141
142
|
let stat;
|
|
142
143
|
try {
|
|
@@ -145,7 +146,7 @@ function localProblem(file, shown) {
|
|
|
145
146
|
catch {
|
|
146
147
|
return link.isSymbolicLink()
|
|
147
148
|
? { code: 'broken_link', message: `${shown} points to a file that does not exist` }
|
|
148
|
-
: { code: 'unreadable', message:
|
|
149
|
+
: { code: 'unreadable', message: (0, words_1.word)('fileNoPermission', { file: shown }) };
|
|
149
150
|
}
|
|
150
151
|
if (stat.isDirectory()) {
|
|
151
152
|
return {
|
|
@@ -157,7 +158,7 @@ function localProblem(file, shown) {
|
|
|
157
158
|
fs.closeSync(fs.openSync(file, 'r'));
|
|
158
159
|
}
|
|
159
160
|
catch {
|
|
160
|
-
return { code: 'unreadable', message:
|
|
161
|
+
return { code: 'unreadable', message: (0, words_1.word)('fileNoPermission', { file: shown }) };
|
|
161
162
|
}
|
|
162
163
|
return undefined;
|
|
163
164
|
}
|
package/out/lib/commandlist.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface Listed {
|
|
2
2
|
name: string;
|
|
3
3
|
description: string;
|
|
4
|
-
/** `session`, `
|
|
4
|
+
/** `session`, `workspace skill`, `company skill`, `workspace command`, ... */
|
|
5
5
|
source: string;
|
|
6
6
|
}
|
|
7
7
|
export interface CommandList {
|
package/out/lib/commandlist.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.fetchCommandList = fetchCommandList;
|
|
|
13
13
|
* what counts as a skill, what it is called and what its line says is made on
|
|
14
14
|
* the service.
|
|
15
15
|
*/
|
|
16
|
-
const files_1 = require("../executor/files");
|
|
16
|
+
const files_1 = require("../machine/executor/files");
|
|
17
17
|
const gateway_1 = require("./gateway");
|
|
18
18
|
const ROUNDS = 6;
|
|
19
19
|
const MAX_CHARS = 8000;
|
|
@@ -35,7 +35,7 @@ async function fetchCommandList(root, words) {
|
|
|
35
35
|
for (let round = 0; round < ROUNDS; round += 1) {
|
|
36
36
|
const reply = await (0, gateway_1.ask)({
|
|
37
37
|
intent: 'commands', prompt: '',
|
|
38
|
-
commandsPayload: { words, round, files, listings, project: root },
|
|
38
|
+
commandsPayload: { words, round, files, listings, project: root, forwards: true },
|
|
39
39
|
});
|
|
40
40
|
const body = reply.commands;
|
|
41
41
|
if (!reply.ok || reply.served === false || !body) {
|
package/out/lib/config.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ExecutionMode, FooterConfig, Provider } from './types';
|
|
2
|
-
export
|
|
2
|
+
export { HOME_DIR_NAME } from '../machine/runtime/home';
|
|
3
|
+
import { homeDir } from '../machine/runtime/home';
|
|
4
|
+
export { homeDir };
|
|
3
5
|
export interface ContentPolicy {
|
|
4
6
|
/**
|
|
5
7
|
* Store request and response text alongside the records. Default false, and
|
|
@@ -68,7 +70,6 @@ export interface Config {
|
|
|
68
70
|
updated: string;
|
|
69
71
|
}
|
|
70
72
|
export type Keys = Partial<Record<Provider, string>>;
|
|
71
|
-
export declare function homeDir(): string;
|
|
72
73
|
/**
|
|
73
74
|
* Create the home directory at mode 700 if it is not there.
|
|
74
75
|
*
|