@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.
Files changed (107) hide show
  1. package/out/agent/command.js +4 -4
  2. package/out/agent/render.d.ts +24 -0
  3. package/out/agent/render.js +35 -3
  4. package/out/agent/session.d.ts +6 -1
  5. package/out/agent/session.js +17 -8
  6. package/out/commands/agents.js +3 -3
  7. package/out/commands/ask.js +8 -8
  8. package/out/commands/codemap.d.ts +1 -1
  9. package/out/commands/codemap.js +3 -3
  10. package/out/commands/commands-thin.js +4 -4
  11. package/out/commands/config.js +1 -1
  12. package/out/commands/cost.js +4 -4
  13. package/out/commands/decisionEngine.d.ts +1 -0
  14. package/out/commands/decisionEngine.js +66 -0
  15. package/out/commands/hooks.js +1 -1
  16. package/out/commands/install.d.ts +1 -1
  17. package/out/commands/install.js +3 -2
  18. package/out/commands/instructions.js +1 -1
  19. package/out/commands/integrations.js +4 -4
  20. package/out/commands/keys.js +6 -6
  21. package/out/commands/login.js +37 -21
  22. package/out/commands/permissions.js +2 -2
  23. package/out/commands/plugins.js +3 -3
  24. package/out/commands/privacy.js +2 -2
  25. package/out/commands/repl.js +107 -83
  26. package/out/commands/review.js +6 -6
  27. package/out/commands/settings.js +30 -123
  28. package/out/commands/skills.js +2 -2
  29. package/out/commands/unattended.js +6 -6
  30. package/out/commands/update.js +1 -1
  31. package/out/commands/welcome.js +20 -29
  32. package/out/commands/worktrees.d.ts +1 -1
  33. package/out/graph/sync.d.ts +1 -1
  34. package/out/graph/sync.js +6 -6
  35. package/out/lib/attach.js +4 -3
  36. package/out/lib/commandlist.d.ts +1 -1
  37. package/out/lib/commandlist.js +2 -2
  38. package/out/lib/config.d.ts +3 -2
  39. package/out/lib/config.js +7 -8
  40. package/out/lib/connection.js +1 -1
  41. package/out/lib/gateway.d.ts +5 -5
  42. package/out/lib/machine.js +1 -1
  43. package/out/lib/project-ops.d.ts +1 -1
  44. package/out/lib/project-ops.js +4 -4
  45. package/out/lib/queue.js +1 -1
  46. package/out/lib/readiness.d.ts +3 -30
  47. package/out/lib/readiness.js +13 -82
  48. package/out/lib/servicecommand.d.ts +14 -0
  49. package/out/lib/servicecommand.js +74 -0
  50. package/out/lib/sessions.js +3 -3
  51. package/out/lib/ui.d.ts +9 -6
  52. package/out/lib/ui.js +20 -26
  53. package/out/lib/voice.d.ts +2 -39
  54. package/out/lib/voice.js +7 -148
  55. package/out/lib/words.d.ts +20 -0
  56. package/out/lib/words.js +27 -0
  57. package/out/machine/codemap/build.d.ts +45 -0
  58. package/out/machine/codemap/build.js +91 -0
  59. package/out/machine/codemap/facts.d.ts +47 -0
  60. package/out/machine/codemap/facts.js +12 -0
  61. package/out/machine/codemap/files.d.ts +45 -0
  62. package/out/machine/codemap/files.js +207 -0
  63. package/out/machine/codemap/read-locales.d.ts +29 -0
  64. package/out/machine/codemap/read-locales.js +246 -0
  65. package/out/machine/codemap/read-python.d.ts +11 -0
  66. package/out/machine/codemap/read-python.js +116 -0
  67. package/out/machine/codemap/read-typescript.d.ts +16 -0
  68. package/out/machine/codemap/read-typescript.js +292 -0
  69. package/out/machine/executor/browser.d.ts +14 -0
  70. package/out/machine/executor/browser.js +270 -0
  71. package/out/machine/executor/diagnostics.d.ts +2 -0
  72. package/out/machine/executor/diagnostics.js +181 -0
  73. package/out/machine/executor/documents.d.ts +40 -0
  74. package/out/machine/executor/documents.js +170 -0
  75. package/out/machine/executor/files.d.ts +2 -0
  76. package/out/machine/executor/files.js +590 -0
  77. package/out/machine/executor/git.d.ts +48 -0
  78. package/out/machine/executor/git.js +145 -0
  79. package/out/machine/executor/hooks.d.ts +51 -0
  80. package/out/machine/executor/hooks.js +154 -0
  81. package/out/machine/executor/index.d.ts +45 -0
  82. package/out/machine/executor/index.js +367 -0
  83. package/out/machine/executor/notebook.d.ts +2 -0
  84. package/out/machine/executor/notebook.js +147 -0
  85. package/out/machine/executor/paths.d.ts +20 -0
  86. package/out/machine/executor/paths.js +154 -0
  87. package/out/machine/executor/sandbox.d.ts +40 -0
  88. package/out/machine/executor/sandbox.js +299 -0
  89. package/out/machine/executor/shell.d.ts +86 -0
  90. package/out/machine/executor/shell.js +582 -0
  91. package/out/machine/executor/toolservers.d.ts +20 -0
  92. package/out/machine/executor/toolservers.js +189 -0
  93. package/out/machine/executor/worktree.d.ts +9 -0
  94. package/out/machine/executor/worktree.js +119 -0
  95. package/out/machine/folder/project.d.ts +28 -0
  96. package/out/machine/folder/project.js +114 -0
  97. package/out/machine/runtime/home.d.ts +2 -0
  98. package/out/machine/runtime/home.js +48 -0
  99. package/out/machine/runtime/needs.d.ts +30 -0
  100. package/out/machine/runtime/needs.js +89 -0
  101. package/out/machine/runtime/self.d.ts +23 -0
  102. package/out/machine/runtime/self.js +124 -0
  103. package/out/machine/voice/record.d.ts +38 -0
  104. package/out/machine/voice/record.js +208 -0
  105. package/out/providers/index.js +2 -1
  106. package/out/thin.js +18 -10
  107. package/package.json +4 -4
@@ -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
- try {
82
- const saved = JSON.parse(node_fs_1.default.readFileSync(workspaceFile(), 'utf8'));
83
- if (saved.path && node_fs_1.default.existsSync(saved.path))
84
- return { path: saved.path, source: 'saved' };
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 workspace could not tell us which vendors it can reach.'));
111
- out(` ${ui.c.dim(reply.message || reply.decision.rationale || 'no answer from the workspace')}`);
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
- const cfg = (0, config_1.loadConfig)();
140
- const named = args.find((a) => !a.startsWith('--'));
141
- out(ui.banner('Your comparison model'));
142
- out();
143
- out(ui.c.dim(' The model you would have used anyway. Savings are measured against it.'));
144
- out(` ${ui.c.dim('Now:')} ${ui.c.bold(cfg.defaultModel || 'not set')}`);
145
- out();
146
- const reply = await (0, gateway_1.ask)({ intent: 'catalog', prompt: '' });
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
- out(ui.ok(`Comparing against ${ui.c.bold(chosen.label)}.`));
195
- out(` ${ui.c.dim('every receipt from now on prices your work against this model')}`);
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
- const named = args.find((a) => !a.startsWith('--'));
200
- const current = currentWorkspace();
201
- out(ui.banner('Project folder'));
202
- out();
203
- out(` ${ui.c.bold(current.path)}`);
204
- out(` ${ui.c.dim(current.source === 'cwd'
205
- ? 'the folder you are standing in'
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;
@@ -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("../lib/project");
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 workspace." };
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("../lib/project");
57
- const self_1 = require("../lib/self");
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 workspace could not be reached.";
67
+ return reply.message || "Your organization could not be reached.";
68
68
  if (reply.served === false)
69
- return "Your workspace is running an older build that does not answer this yet.";
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 project folder ${job.project_root} is not on this machine` });
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);
@@ -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("../lib/self");
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`);
@@ -96,40 +96,31 @@ async function session() {
96
96
  return reply.session;
97
97
  }
98
98
  /**
99
- * The mark: the app icon as a terminal can draw it cleanly. A five layer prism,
100
- * each layer two blocks wider than the one above and a shade deeper, with
101
- * three beams leaving its right side (up, level and down) and a ring of the
102
- * icon's cyan to purple around it (owner, 28 September 2026).
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).
103
105
  *
104
- * Solid blocks only, no blended edges and no white, because a terminal draws a
105
- * solid block sharply in any font and a white one vanishes on a white screen.
106
- * Drawn two pixels to a character, so it is nine lines tall.
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.
107
110
  *
108
111
  * Without color the picture cannot be drawn, so the four row block pyramid
109
112
  * stands in: full blocks only, which render the same in every font.
110
113
  */
111
114
  const ICON = [
112
- '..........................................53a6ed51a1ed509cee4f98ee4d93ee4c8eee4a89ee..................................................................',
113
- '..............................54abed53a6ed51a1ed..............................4984ef477fef467bef......................................................',
114
- '........................54abed53a6ed......................................................4476ef4371ef................................................',
115
- '..................54abed53a6ed..................................................................426cf04067f0..........................................',
116
- '..................53a6ed....................................a8d8f7a8d8f7..............................3f62f0..........................................',
117
- '............53a6ed51a1ed....................................a8d8f7a8d8f7..............................3f5ff0425ef0..................4292f23f8af43b82f6',
118
- '............51a1ed....................................74aef074aef074aef074aef0..............................455cf0......49a2ee469af0..................',
119
- '............509cee....................................74aef074aef074aef074aef0........................54bbe851b3ea4daaec..............................',
120
- '............4f98ee..............................4f86e64f86e64f86e64f86e64f86e64f86e6......5bcbe458c3e6......4b59f1....................................',
121
- '............4d93ee..............................4f86e64f86e64f86e64f86e64f86e64f86e6f07a36f0e35befe25aeee259ece158eae057e9df56e8de55e6de54e4dd53e3dc52',
122
- '............4c8eee........................3e60d83e60d83e60d83e60d83e60d83e60d83e60d83e60d8ed7435ea6e34......5056f1....................................',
123
- '............4a89ee........................3e60d83e60d83e60d83e60d83e60d83e60d83e60d83e60d8............e76932e46331e15d30..............................',
124
- '............4984ef477fef............2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a......5355f15653f2......de572fdb512e..................',
125
- '..................467bef............2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a2e3a9a......5653f2........................d84c2cd5462bd2402a',
126
- '..................4476ef4371ef..................................................................5653f25952f2..........................................',
127
- '........................426cf04067f0......................................................5653f25952f2................................................',
128
- '..............................3f62f03f5ff0425ef0..............................5355f15653f25952f2......................................................',
129
- '..........................................455cf0485bf14b59f14e58f15056f15355f15653f2..................................................................',
115
+ '..............................f69f97f69f97..............................',
116
+ '........................ffbd8affbd8affbd8affbd8a........................',
117
+ '..................ffdf7fffdf7fffdf7fffdf7fffdf7fffdf7f..................',
118
+ '............a1d38ca1d38ca1d38ca1d38ca1d38ca1d38ca1d38ca1d38c............',
119
+ '......95d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f095d2f0......',
120
+ 'bba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1ddbba1dd',
130
121
  ];
131
122
  function mark() {
132
- const picture = ui.pixelArt(ICON);
123
+ const picture = ui.cellArt(ICON);
133
124
  if (picture.length)
134
125
  return picture;
135
126
  const rows = [];
@@ -176,7 +167,6 @@ async function showWelcome(known, signingIn = false, withMark = true) {
176
167
  // Nothing else here is knowable yet, and the one useful thing to say is the
177
168
  // single command that changes that.
178
169
  out(row('Signed in', ui.c.amber('not yet')));
179
- out(row('Comparing', cfg.defaultModel || 'not set'));
180
170
  out(row('Workspace', `${folder.path} ${ui.c.dim('(where you are)')}`));
181
171
  out();
182
172
  // Not said when signing in follows at once: naming a command to type, just
@@ -205,7 +195,8 @@ async function showWelcome(known, signingIn = false, withMark = true) {
205
195
  out(row('User', who));
206
196
  out(row('Company', company));
207
197
  out(row('Server', local ? address : ui.c.dim(address)));
208
- out(row('Comparing', `${cfg.defaultModel || ui.c.amber('not set')} ${ui.c.dim('change with `comprism model`')}`));
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`')}`));
209
200
  out(row('Workspace', `${folder.path} ${ui.c.dim(folder.source === 'cwd' ? '(where you are)' : '(saved)')}`));
210
201
  if (plan) {
211
202
  out(row('Plan', allowance
@@ -214,7 +205,7 @@ async function showWelcome(known, signingIn = false, withMark = true) {
214
205
  }
215
206
  if (!me) {
216
207
  out();
217
- out(` ${ui.c.amber('your workspace could not be reached, so only local settings are shown')}`);
208
+ out(` ${ui.c.amber('your organization could not be reached, so only local settings are shown')}`);
218
209
  out(` ${ui.c.dim('nothing here is known about your account, including your provider keys')}`);
219
210
  }
220
211
  else if (me.vendors_known === false) {
@@ -1,4 +1,4 @@
1
- import type { ProjectFacts } from "../lib/project";
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>;
@@ -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 project's new fingerprint travel together, 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("./build");
26
- const read_python_1 = require("./read-python");
27
- const read_typescript_1 = require("./read-typescript");
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 project.` };
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 project.`;
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 project's new fingerprint travel together, 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: `not found: ${shown}` };
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: `cannot read ${shown}: permission denied` };
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: `cannot read ${shown}: permission denied` };
161
+ return { code: 'unreadable', message: (0, words_1.word)('fileNoPermission', { file: shown }) };
161
162
  }
162
163
  return undefined;
163
164
  }
@@ -1,7 +1,7 @@
1
1
  export interface Listed {
2
2
  name: string;
3
3
  description: string;
4
- /** `session`, `project skill`, `company skill`, `project command`, ... */
4
+ /** `session`, `workspace skill`, `company skill`, `workspace command`, ... */
5
5
  source: string;
6
6
  }
7
7
  export interface CommandList {
@@ -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) {
@@ -1,5 +1,7 @@
1
1
  import type { ExecutionMode, FooterConfig, Provider } from './types';
2
- export declare const HOME_DIR_NAME = ".comprism";
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
  *
package/out/lib/config.js CHANGED
@@ -3,8 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.HOME_DIR_NAME = void 0;
7
- exports.homeDir = homeDir;
6
+ exports.homeDir = exports.HOME_DIR_NAME = void 0;
8
7
  exports.ensureHome = ensureHome;
9
8
  exports.configPath = configPath;
10
9
  exports.defaultConfig = defaultConfig;
@@ -41,10 +40,10 @@ exports.envVarName = envVarName;
41
40
  const node_fs_1 = __importDefault(require("node:fs"));
42
41
  const node_os_1 = __importDefault(require("node:os"));
43
42
  const node_path_1 = __importDefault(require("node:path"));
44
- exports.HOME_DIR_NAME = '.comprism';
45
- function homeDir() {
46
- return process.env.COMPRISM_HOME || node_path_1.default.join(node_os_1.default.homedir(), exports.HOME_DIR_NAME);
47
- }
43
+ var home_1 = require("../machine/runtime/home");
44
+ Object.defineProperty(exports, "HOME_DIR_NAME", { enumerable: true, get: function () { return home_1.HOME_DIR_NAME; } });
45
+ const home_2 = require("../machine/runtime/home");
46
+ Object.defineProperty(exports, "homeDir", { enumerable: true, get: function () { return home_2.homeDir; } });
48
47
  /**
49
48
  * Create the home directory at mode 700 if it is not there.
50
49
  *
@@ -53,7 +52,7 @@ function homeDir() {
53
52
  * never noticed afterwards.
54
53
  */
55
54
  function ensureHome() {
56
- const dir = homeDir();
55
+ const dir = (0, home_2.homeDir)();
57
56
  node_fs_1.default.mkdirSync(dir, { recursive: true, mode: 0o700 });
58
57
  try {
59
58
  node_fs_1.default.chmodSync(dir, 0o700);
@@ -64,7 +63,7 @@ function ensureHome() {
64
63
  return dir;
65
64
  }
66
65
  function configPath() {
67
- return node_path_1.default.join(homeDir(), 'config.json');
66
+ return node_path_1.default.join((0, home_2.homeDir)(), 'config.json');
68
67
  }
69
68
  function defaultConfig() {
70
69
  const now = new Date().toISOString();
@@ -141,7 +141,7 @@ function isLocalAddress(url) {
141
141
  function writeConnection(connection, typed = false) {
142
142
  if (!typed && isLocalAddress(connection.url)) {
143
143
  throw new Error(`refusing to point this machine at ${connection.url}, which is this computer `
144
- + 'rather than a workspace. Pass it with --workspace if that is genuinely what you want.');
144
+ + 'rather than an organization. Pass it with --workspace if that is genuinely what you want.');
145
145
  }
146
146
  (0, config_1.ensureHome)();
147
147
  node_fs_1.default.writeFileSync(connectionPath(), `${JSON.stringify(connection, null, 2)}\n`, { mode: 0o600 });
@@ -62,7 +62,7 @@ export interface SpendReport {
62
62
  export interface GatewayReply {
63
63
  /** Local transport metadata, not an authentication decision. */
64
64
  httpStatus?: number;
65
- intent: 'decide' | 'answer' | 'catalog' | 'store_key' | 'session' | 'job_start' | 'resolve_workspace' | 'sign_in' | 'sign_out' | 'attach' | 'transcribe' | 'graph' | 'spend' | 'project' | 'commands' | 'transcript' | 'context' | 'compact' | 'sessions' | 'permissions' | 'jobs' | 'agents' | 'integrations' | 'skills' | 'plugins' | 'schema' | 'usage' | 'instructions' | 'config' | 'memory' | 'worktrees' | 'privacy' | 'hooks' | 'queue' | 'review' | 'release';
65
+ intent: 'decide' | 'answer' | 'catalog' | 'store_key' | 'session' | 'job_start' | 'resolve_workspace' | 'sign_in' | 'sign_out' | 'attach' | 'transcribe' | 'graph' | 'spend' | 'project' | 'commands' | 'transcript' | 'context' | 'compact' | 'sessions' | 'permissions' | 'jobs' | 'agents' | 'integrations' | 'skills' | 'plugins' | 'schema' | 'usage' | 'instructions' | 'config' | 'memory' | 'worktrees' | 'privacy' | 'hooks' | 'queue' | 'review' | 'release' | 'decision_engine' | 'command';
66
66
  client: string;
67
67
  decision: Decision;
68
68
  answer: string | null;
@@ -94,7 +94,7 @@ export interface GatewayReply {
94
94
  /**
95
95
  * Did this workspace's build serve the intent that was asked for.
96
96
  *
97
- * False is a COMPLETE answer meaning "your workspace is behind", never an
97
+ * False is a COMPLETE answer meaning "your organization is behind", never an
98
98
  * error and never an absence. A caller that reads it as an absence repeats
99
99
  * the 17 September fault: a tool asked a workspace for its vendor list, the
100
100
  * build did not carry that question, and the refusal was reported to the
@@ -246,8 +246,8 @@ export interface GatewayReply {
246
246
  *
247
247
  * False means we never heard from it, so EVERY other field here is this
248
248
  * client's own placeholder rather than anything the workspace said. Without
249
- * this a caller could not tell "the workspace says you have no provider key"
250
- * from "the workspace did not answer", and it read the second as the first:
249
+ * this a caller could not tell "the organization says you have no provider key"
250
+ * from "the organization did not answer", and it read the second as the first:
251
251
  * somebody whose keys were all present and correct was told none was stored
252
252
  * and walked into a form asking them to paste one.
253
253
  */
@@ -342,7 +342,7 @@ export interface SessionOut {
342
342
  can_write: boolean;
343
343
  }
344
344
  export interface Ask {
345
- intent: 'decide' | 'answer' | 'catalog' | 'store_key' | 'session' | 'job_start' | 'resolve_workspace' | 'sign_in' | 'sign_out' | 'attach' | 'transcribe' | 'graph' | 'spend' | 'project' | 'commands' | 'transcript' | 'context' | 'compact' | 'sessions' | 'permissions' | 'jobs' | 'agents' | 'integrations' | 'skills' | 'plugins' | 'schema' | 'usage' | 'instructions' | 'config' | 'memory' | 'worktrees' | 'privacy' | 'hooks' | 'queue' | 'review' | 'release';
345
+ intent: 'decide' | 'answer' | 'catalog' | 'store_key' | 'session' | 'job_start' | 'resolve_workspace' | 'sign_in' | 'sign_out' | 'attach' | 'transcribe' | 'graph' | 'spend' | 'project' | 'commands' | 'transcript' | 'context' | 'compact' | 'sessions' | 'permissions' | 'jobs' | 'agents' | 'integrations' | 'skills' | 'plugins' | 'schema' | 'usage' | 'instructions' | 'config' | 'memory' | 'worktrees' | 'privacy' | 'hooks' | 'queue' | 'review' | 'release' | 'decision_engine' | 'command';
346
346
  prompt: string;
347
347
  callingModel?: string;
348
348
  contextTokens?: number;
@@ -15,7 +15,7 @@ exports.isPlain = isPlain;
15
15
  * Kept in the tool's own `config.json`, never on the service, because none of
16
16
  * them changes what the agent does: two people sharing a project can each have
17
17
  * their own theme. Settings that do change what the agent does are the
18
- * service's and the project's (manual 2.10), and are not written here.
18
+ * service's and the workspace's (manual 2.10), and are not written here.
19
19
  */
20
20
  const config_1 = require("./config");
21
21
  /** Every machine setting, its allowed values, and its default. `editor` takes
@@ -1,5 +1,5 @@
1
1
  import { type GatewayReply } from "./gateway";
2
- import { type ProjectFacts } from "./project";
2
+ import { type ProjectFacts } from "../machine/folder/project";
3
3
  export type Intent = "instructions" | "config" | "memory" | "worktrees" | "hooks";
4
4
  export declare function useSessionFolder(folder: string | null): void;
5
5
  /** The project for this command: the session's folder, the saved default, or
@@ -50,8 +50,8 @@ exports.openEditor = openEditor;
50
50
  const fs = __importStar(require("node:fs"));
51
51
  const path = __importStar(require("node:path"));
52
52
  const gateway_1 = require("./gateway");
53
- const project_1 = require("./project");
54
- const paths_1 = require("../executor/paths");
53
+ const project_1 = require("../machine/folder/project");
54
+ const paths_1 = require("../machine/executor/paths");
55
55
  const ui = __importStar(require("./ui"));
56
56
  const out = (s = "") => process.stdout.write(s + "\n");
57
57
  /** The largest file sent. An instruction or settings file is a page, not a book. */
@@ -104,8 +104,8 @@ async function call(intent, op, payload, facts, quiet = false) {
104
104
  });
105
105
  if (!reply.ok || reply.served === false) {
106
106
  out(ui.fail(reply.served === false
107
- ? "Your workspace is running an older build that does not answer this yet."
108
- : `Your workspace could not be reached: ${reply.message || "no answer"}`));
107
+ ? "Your organization is running an older build that does not answer this yet."
108
+ : `Your organization could not be reached: ${reply.message || "no answer"}`));
109
109
  return null;
110
110
  }
111
111
  if (reply.granted === false) {