@illuminis/comprism 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -36
- package/out/agent/command.d.ts +75 -4
- package/out/agent/command.js +220 -25
- package/out/agent/render.d.ts +17 -2
- package/out/agent/render.js +157 -14
- package/out/agent/session.d.ts +141 -2
- package/out/agent/session.js +735 -149
- package/out/commands/agents.d.ts +2 -0
- package/out/commands/agents.js +79 -0
- package/out/commands/ask.d.ts +1 -1
- package/out/commands/ask.js +78 -11
- package/out/commands/commands-thin.js +79 -17
- package/out/commands/config.d.ts +1 -0
- package/out/commands/config.js +138 -0
- package/out/commands/cost.d.ts +1 -0
- package/out/commands/cost.js +167 -0
- package/out/commands/hooks.d.ts +1 -0
- package/out/commands/hooks.js +83 -0
- package/out/commands/install.d.ts +44 -1
- package/out/commands/install.js +198 -4
- package/out/commands/instructions.d.ts +1 -0
- package/out/commands/instructions.js +113 -0
- package/out/commands/integrations.d.ts +3 -0
- package/out/commands/integrations.js +215 -0
- package/out/commands/jobs.d.ts +5 -0
- package/out/commands/jobs.js +157 -0
- package/out/commands/login.js +188 -36
- package/out/commands/memory.d.ts +3 -0
- package/out/commands/memory.js +113 -0
- package/out/commands/permissions.d.ts +1 -0
- package/out/commands/permissions.js +94 -0
- package/out/commands/plugins.d.ts +4 -0
- package/out/commands/plugins.js +192 -0
- package/out/commands/privacy.d.ts +1 -0
- package/out/commands/privacy.js +57 -0
- package/out/commands/providerKey.d.ts +32 -0
- package/out/commands/providerKey.js +108 -0
- package/out/commands/repl.d.ts +8 -1
- package/out/commands/repl.js +1207 -118
- package/out/commands/report.d.ts +39 -0
- package/out/commands/report.js +115 -0
- package/out/commands/review.d.ts +5 -0
- package/out/commands/review.js +223 -0
- package/out/commands/sessions.d.ts +23 -0
- package/out/commands/sessions.js +115 -0
- package/out/commands/settings.d.ts +3 -1
- package/out/commands/settings.js +18 -16
- package/out/commands/skills.d.ts +21 -0
- package/out/commands/skills.js +207 -0
- package/out/commands/unattended.d.ts +7 -0
- package/out/commands/unattended.js +351 -0
- package/out/commands/update.d.ts +1 -0
- package/out/commands/update.js +123 -0
- package/out/commands/worktrees.d.ts +5 -0
- package/out/commands/worktrees.js +186 -0
- package/out/executor/browser.d.ts +14 -0
- package/out/executor/browser.js +270 -0
- package/out/executor/diagnostics.d.ts +2 -0
- package/out/executor/diagnostics.js +181 -0
- package/out/executor/files.js +270 -40
- package/out/executor/git.js +42 -29
- package/out/executor/hooks.d.ts +42 -58
- package/out/executor/hooks.js +89 -182
- package/out/executor/index.d.ts +21 -5
- package/out/executor/index.js +160 -14
- package/out/executor/paths.d.ts +6 -1
- package/out/executor/paths.js +34 -6
- package/out/executor/sandbox.d.ts +40 -0
- package/out/executor/sandbox.js +299 -0
- package/out/executor/shell.d.ts +49 -4
- package/out/executor/shell.js +302 -56
- package/out/executor/toolservers.d.ts +20 -0
- package/out/executor/toolservers.js +189 -0
- package/out/executor/worktree.d.ts +9 -0
- package/out/executor/worktree.js +119 -0
- package/out/graph/read-python.js +2 -1
- package/out/lib/attach.d.ts +56 -12
- package/out/lib/attach.js +230 -63
- package/out/lib/clipboard.d.ts +23 -0
- package/out/lib/clipboard.js +182 -0
- package/out/lib/commandlist.d.ts +20 -0
- package/out/lib/commandlist.js +58 -0
- package/out/lib/decision.d.ts +22 -0
- package/out/lib/decision.js +50 -0
- package/out/lib/fingerprint.d.ts +25 -0
- package/out/lib/fingerprint.js +58 -0
- package/out/lib/gateway.d.ts +186 -2
- package/out/lib/gateway.js +59 -4
- package/out/lib/history.d.ts +24 -0
- package/out/lib/history.js +137 -0
- package/out/lib/ide.d.ts +19 -0
- package/out/lib/ide.js +131 -0
- package/out/lib/keyboard.d.ts +95 -0
- package/out/lib/keyboard.js +383 -0
- package/out/lib/machine.d.ts +21 -0
- package/out/lib/machine.js +91 -0
- package/out/lib/notify.d.ts +4 -0
- package/out/lib/notify.js +52 -0
- package/out/lib/output.d.ts +48 -0
- package/out/lib/output.js +108 -0
- package/out/lib/project-ops.d.ts +19 -0
- package/out/lib/project-ops.js +146 -0
- package/out/lib/project.d.ts +28 -0
- package/out/lib/project.js +114 -0
- package/out/lib/prompt.js +15 -2
- package/out/lib/queue.d.ts +13 -0
- package/out/lib/queue.js +116 -0
- package/out/lib/readiness.d.ts +19 -0
- package/out/lib/readiness.js +170 -1
- package/out/lib/self.d.ts +23 -0
- package/out/lib/self.js +124 -0
- package/out/lib/sessions.d.ts +19 -0
- package/out/lib/sessions.js +221 -0
- package/out/lib/stdin.d.ts +32 -0
- package/out/lib/stdin.js +117 -0
- package/out/lib/store.d.ts +40 -0
- package/out/lib/store.js +138 -0
- package/out/lib/sync.d.ts +18 -0
- package/out/lib/sync.js +81 -0
- package/out/lib/ui.d.ts +2 -4
- package/out/lib/ui.js +31 -25
- package/out/lib/voice.js +24 -0
- package/out/postinstall.js +42 -14
- package/out/providers/anthropic.d.ts +22 -0
- package/out/providers/anthropic.js +80 -0
- package/out/providers/index.d.ts +8 -0
- package/out/providers/index.js +83 -0
- package/out/providers/openai.d.ts +11 -0
- package/out/providers/openai.js +57 -0
- package/out/thin.js +609 -21
- package/package.json +9 -49
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PLUGINS_HELP = void 0;
|
|
37
|
+
exports.readFolder = readFolder;
|
|
38
|
+
exports.cmdPlugins = cmdPlugins;
|
|
39
|
+
/**
|
|
40
|
+
* `comprism plugins` (manual 9.15 to 9.17): install from a folder or the
|
|
41
|
+
* company's catalog, then enable, disable, update and remove.
|
|
42
|
+
*
|
|
43
|
+
* Installing reads the folder's text files and sends them; nothing in the
|
|
44
|
+
* folder is ever run. The service decides what a plugin adds, who it is for,
|
|
45
|
+
* whether the company allows it, and every word shown.
|
|
46
|
+
*/
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const readline = __importStar(require("readline"));
|
|
50
|
+
const gateway_1 = require("../lib/gateway");
|
|
51
|
+
const project_1 = require("../lib/project");
|
|
52
|
+
const ui = __importStar(require("../lib/ui"));
|
|
53
|
+
const out = (s = "") => process.stdout.write(`${s}\n`);
|
|
54
|
+
const MAX_FILES = 200;
|
|
55
|
+
const MAX_BYTES = 50_000;
|
|
56
|
+
const SKIP = new Set([".git", "node_modules", ".DS_Store"]);
|
|
57
|
+
/** Every text file in the folder, by path inside it. Never runs anything. */
|
|
58
|
+
function readFolder(dir) {
|
|
59
|
+
const files = {};
|
|
60
|
+
const walk = (at, rel) => {
|
|
61
|
+
for (const e of fs.readdirSync(at, { withFileTypes: true })) {
|
|
62
|
+
if (Object.keys(files).length >= MAX_FILES || SKIP.has(e.name))
|
|
63
|
+
continue;
|
|
64
|
+
const full = path.join(at, e.name);
|
|
65
|
+
const inside = rel ? `${rel}/${e.name}` : e.name;
|
|
66
|
+
if (e.isDirectory()) {
|
|
67
|
+
walk(full, inside);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (!e.isFile() || fs.statSync(full).size > MAX_BYTES)
|
|
71
|
+
continue;
|
|
72
|
+
const text = fs.readFileSync(full, "utf8");
|
|
73
|
+
if (!text.includes("\u0000"))
|
|
74
|
+
files[inside] = text;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
walk(dir, "");
|
|
78
|
+
return files;
|
|
79
|
+
}
|
|
80
|
+
async function call(payload) {
|
|
81
|
+
const reply = await (0, gateway_1.ask)({ intent: "plugins", prompt: "", pluginsPayload: payload });
|
|
82
|
+
const body = reply.plugins;
|
|
83
|
+
if (!reply.ok || reply.served === false || !body) {
|
|
84
|
+
out(` ${ui.fail(reply.message || "Your plugins could not be read from your workspace.")}`);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
if (body.error) {
|
|
88
|
+
out(` ${ui.fail(body.error)}`);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return body;
|
|
92
|
+
}
|
|
93
|
+
function question(prompt) {
|
|
94
|
+
if (!process.stdin.isTTY && process.stdin.readableEnded)
|
|
95
|
+
return Promise.resolve("");
|
|
96
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
97
|
+
return new Promise((resolve) => rl.question(prompt, (a) => { rl.close(); resolve(a.trim()); }));
|
|
98
|
+
}
|
|
99
|
+
exports.PLUGINS_HELP = ` comprism plugins installed plugins and their state
|
|
100
|
+
comprism plugins install <name|folder> install from your company's catalog or a folder
|
|
101
|
+
--scope project|personal skip the question
|
|
102
|
+
comprism plugins enable <name> comprism plugins disable <name>
|
|
103
|
+
comprism plugins update <name> shows what changes, then asks
|
|
104
|
+
comprism plugins remove <name>`;
|
|
105
|
+
async function cmdPlugins(args) {
|
|
106
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
107
|
+
out(exports.PLUGINS_HELP);
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
const valued = new Set(["--scope", "--cwd"]);
|
|
111
|
+
const [sub, target] = args.filter((a, i) => !a.startsWith("--") && !valued.has(args[i - 1] ?? ""));
|
|
112
|
+
const at = args.indexOf("--cwd");
|
|
113
|
+
const root = (0, project_1.resolveProject)(at >= 0 && args[at + 1] ? String(args[at + 1]) : process.cwd()).root;
|
|
114
|
+
const base = { project: root };
|
|
115
|
+
const yes = args.includes("--yes");
|
|
116
|
+
if (!sub) {
|
|
117
|
+
const body = await call({ ...base, op: "list" });
|
|
118
|
+
if (!body)
|
|
119
|
+
return 1;
|
|
120
|
+
for (const l of body.lines ?? [])
|
|
121
|
+
out(` ${l}`);
|
|
122
|
+
return 0;
|
|
123
|
+
}
|
|
124
|
+
if (!target) {
|
|
125
|
+
out(` ${ui.fail(`comprism plugins ${sub} takes a plugin${sub === "install" ? " name or folder" : " name"}.`)}`);
|
|
126
|
+
return 2;
|
|
127
|
+
}
|
|
128
|
+
if (sub === "install") {
|
|
129
|
+
const folder = path.resolve(target);
|
|
130
|
+
const fromFolder = fs.existsSync(folder) && fs.statSync(folder).isDirectory();
|
|
131
|
+
const source = fromFolder ? { files: readFolder(folder), folder } : { name: target };
|
|
132
|
+
const preview = await call({ ...base, ...source, op: "preview" });
|
|
133
|
+
if (!preview)
|
|
134
|
+
return 1;
|
|
135
|
+
for (const l of preview.lines ?? [])
|
|
136
|
+
out(` ${l}`);
|
|
137
|
+
let scope = args.indexOf("--scope") >= 0 ? args[args.indexOf("--scope") + 1] : undefined;
|
|
138
|
+
if (!scope) {
|
|
139
|
+
const said = await question(` Install for: 1 this project 2 just me 3 cancel `);
|
|
140
|
+
scope = said === "1" ? "project" : said === "2" ? "personal" : undefined;
|
|
141
|
+
if (!scope) {
|
|
142
|
+
out(" Nothing was installed.");
|
|
143
|
+
return 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const done = await call({ ...base, ...source, op: "install", scope });
|
|
147
|
+
if (!done)
|
|
148
|
+
return 1;
|
|
149
|
+
out(` ${done.line ?? ""}`);
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
if (sub === "update") {
|
|
153
|
+
let preview = await call({ ...base, op: "update_preview", name: target });
|
|
154
|
+
let files;
|
|
155
|
+
if (preview?.folder) {
|
|
156
|
+
if (!fs.existsSync(preview.folder)) {
|
|
157
|
+
out(` ${ui.fail(`${target} was installed from ${preview.folder}, which is not on this machine.`)}`);
|
|
158
|
+
return 1;
|
|
159
|
+
}
|
|
160
|
+
files = readFolder(preview.folder);
|
|
161
|
+
preview = await call({ ...base, op: "update_preview", name: target, files });
|
|
162
|
+
}
|
|
163
|
+
if (!preview)
|
|
164
|
+
return 1;
|
|
165
|
+
for (const l of preview.lines ?? [])
|
|
166
|
+
out(` ${l}`);
|
|
167
|
+
if (preview.same) {
|
|
168
|
+
out(` ${target} is already up to date.`);
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
const go = yes || /^y(es)?$/i.test(await question(" Apply this update? [y/N] "));
|
|
172
|
+
if (!go) {
|
|
173
|
+
out(" Nothing was changed.");
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
const done = await call({ ...base, op: "update", name: target, ...(files ? { files } : {}) });
|
|
177
|
+
if (!done)
|
|
178
|
+
return 1;
|
|
179
|
+
out(` ${done.line ?? ""}`);
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
if (["enable", "disable", "remove"].includes(sub)) {
|
|
183
|
+
const done = await call({ ...base, op: sub, name: target });
|
|
184
|
+
if (!done)
|
|
185
|
+
return 1;
|
|
186
|
+
out(` ${done.line ?? ""}`);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
out(` ${ui.fail(`\`plugins ${sub}\` is not a plugins command.`)}`);
|
|
190
|
+
out(exports.PLUGINS_HELP);
|
|
191
|
+
return 2;
|
|
192
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function cmdPrivacy(): Promise<number>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.cmdPrivacy = cmdPrivacy;
|
|
37
|
+
/**
|
|
38
|
+
* `comprism privacy` (manual 2.13): what your company keeps about your work,
|
|
39
|
+
* exactly as the service and the portal state it.
|
|
40
|
+
*/
|
|
41
|
+
const gateway_1 = require("../lib/gateway");
|
|
42
|
+
const ui = __importStar(require("../lib/ui"));
|
|
43
|
+
const out = (s = "") => process.stdout.write(s + "\n");
|
|
44
|
+
async function cmdPrivacy() {
|
|
45
|
+
const reply = await (0, gateway_1.ask)({ intent: "privacy", prompt: "" });
|
|
46
|
+
if (!reply.ok || reply.served === false) {
|
|
47
|
+
out(ui.fail(reply.served === false
|
|
48
|
+
? "Your workspace is running an older build that does not answer this yet."
|
|
49
|
+
: `Your workspace could not be reached: ${reply.message || "no answer"}`));
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
out();
|
|
53
|
+
for (const line of reply.lines ?? [])
|
|
54
|
+
out(line);
|
|
55
|
+
out();
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface RemoteKeyStatus {
|
|
2
|
+
is_set: boolean;
|
|
3
|
+
last_four: string | null;
|
|
4
|
+
updated_at: string | null;
|
|
5
|
+
effective_source: 'tenant' | 'shared' | null;
|
|
6
|
+
is_base_tenant: boolean;
|
|
7
|
+
request_header: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Target {
|
|
10
|
+
url: string;
|
|
11
|
+
token: string;
|
|
12
|
+
tenant?: string;
|
|
13
|
+
}
|
|
14
|
+
/** The tenant we are signed in to, or null with the reason left to the caller. */
|
|
15
|
+
export declare function target(overrides?: Partial<Target>): Target | null;
|
|
16
|
+
export declare function remoteStatus(t: Target): Promise<RemoteKeyStatus>;
|
|
17
|
+
/** Send the key this machine already resolves, for the connector surface. */
|
|
18
|
+
export declare function push(t: Target, value: string): Promise<RemoteKeyStatus>;
|
|
19
|
+
export declare function clear(t: Target): Promise<RemoteKeyStatus>;
|
|
20
|
+
/**
|
|
21
|
+
* The Anthropic key this machine would use, and where it came from.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately the same resolution the recorder and the proxy use rather than a
|
|
24
|
+
* second reading of the environment: a `key push` that sent something other
|
|
25
|
+
* than the key this machine actually works with would be worse than useless,
|
|
26
|
+
* because the person would have proved the wrong secret.
|
|
27
|
+
*/
|
|
28
|
+
export declare function localKey(): {
|
|
29
|
+
value: string | null;
|
|
30
|
+
from: 'env' | 'command' | 'none';
|
|
31
|
+
};
|
|
32
|
+
export declare function localKeyHint(): string;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.target = target;
|
|
4
|
+
exports.remoteStatus = remoteStatus;
|
|
5
|
+
exports.push = push;
|
|
6
|
+
exports.clear = clear;
|
|
7
|
+
exports.localKey = localKey;
|
|
8
|
+
exports.localKeyHint = localKeyHint;
|
|
9
|
+
/**
|
|
10
|
+
* The tenant's stored Anthropic key, from this machine.
|
|
11
|
+
*
|
|
12
|
+
* ── Why a command exists for something we would rather not do ─────────────
|
|
13
|
+
*
|
|
14
|
+
* This product's default is that a provider key never leaves the machine it
|
|
15
|
+
* lives on: `config.ts` resolves it from the environment or a key command at
|
|
16
|
+
* the moment of use, writes it to no file, and the proxy forwards the caller's
|
|
17
|
+
* own credential without reading it. Nothing in the terminal or IDE path needs
|
|
18
|
+
* a key held anywhere else, and that is the path most people are on.
|
|
19
|
+
*
|
|
20
|
+
* One surface cannot work that way. An MCP connector - Claude Desktop,
|
|
21
|
+
* claude.ai - reaches the tenant through a protocol with no channel for a
|
|
22
|
+
* provider credential, so the server has to hold one to answer those prompts at
|
|
23
|
+
* all. The alternative was the server quietly answering them on illuminis's
|
|
24
|
+
* key, which is worse for the customer in every direction: an invoice they
|
|
25
|
+
* cannot audit, a saving measured on somebody else's account, and no way to
|
|
26
|
+
* turn it off.
|
|
27
|
+
*
|
|
28
|
+
* So the key can be pushed, deliberately, by a person typing a verb that says
|
|
29
|
+
* what it does. Three properties hold either way:
|
|
30
|
+
*
|
|
31
|
+
* - it still is not written to any file on this machine;
|
|
32
|
+
* - it travels once, over TLS, to the tenant that person is signed in to;
|
|
33
|
+
* - `comprism key clear` takes it back out, and after that the connector
|
|
34
|
+
* refuses rather than falling back to anyone else's account.
|
|
35
|
+
*/
|
|
36
|
+
const config_1 = require("../lib/config");
|
|
37
|
+
const connection_1 = require("../lib/connection");
|
|
38
|
+
/** The tenant we are signed in to, or null with the reason left to the caller. */
|
|
39
|
+
function target(overrides = {}) {
|
|
40
|
+
const stored = (0, connection_1.readConnection)();
|
|
41
|
+
const url = overrides.url || stored?.url;
|
|
42
|
+
const token = overrides.token || process.env.COMPRISM_TOKEN || stored?.token;
|
|
43
|
+
if (!url || !token)
|
|
44
|
+
return null;
|
|
45
|
+
const tenant = overrides.tenant || stored?.tenant;
|
|
46
|
+
return { url: url.replace(/\/+$/, ''), token, ...(tenant ? { tenant } : {}) };
|
|
47
|
+
}
|
|
48
|
+
function headers(t) {
|
|
49
|
+
const h = {
|
|
50
|
+
'content-type': 'application/json',
|
|
51
|
+
authorization: `Bearer ${t.token}`,
|
|
52
|
+
};
|
|
53
|
+
// Only needed on localhost, where there is no subdomain to resolve the tenant
|
|
54
|
+
// from. Hyphenated, because that is the tenant NAME - the schema is spelled
|
|
55
|
+
// with an underscore and mixing the two is this codebase's classic bug.
|
|
56
|
+
if (t.tenant)
|
|
57
|
+
h['X-Tenant-ID'] = t.tenant;
|
|
58
|
+
return h;
|
|
59
|
+
}
|
|
60
|
+
async function call(t, method, body) {
|
|
61
|
+
const res = await fetch(`${t.url}/api/v1/completion/provider-key`, {
|
|
62
|
+
method,
|
|
63
|
+
headers: headers(t),
|
|
64
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
65
|
+
});
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
// The detail, where the API gave one - it carries the remedy. Never the
|
|
68
|
+
// whole body blind: an error body on a credential route can echo input.
|
|
69
|
+
let detail = `${res.status} ${res.statusText}`;
|
|
70
|
+
try {
|
|
71
|
+
const parsed = (await res.json());
|
|
72
|
+
if (parsed?.detail)
|
|
73
|
+
detail = parsed.detail;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* a body we cannot parse tells us nothing worth saying */
|
|
77
|
+
}
|
|
78
|
+
throw new Error(detail);
|
|
79
|
+
}
|
|
80
|
+
return (await res.json());
|
|
81
|
+
}
|
|
82
|
+
function remoteStatus(t) {
|
|
83
|
+
return call(t, 'GET');
|
|
84
|
+
}
|
|
85
|
+
/** Send the key this machine already resolves, for the connector surface. */
|
|
86
|
+
function push(t, value) {
|
|
87
|
+
return call(t, 'PUT', { value });
|
|
88
|
+
}
|
|
89
|
+
function clear(t) {
|
|
90
|
+
return call(t, 'DELETE');
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The Anthropic key this machine would use, and where it came from.
|
|
94
|
+
*
|
|
95
|
+
* Deliberately the same resolution the recorder and the proxy use rather than a
|
|
96
|
+
* second reading of the environment: a `key push` that sent something other
|
|
97
|
+
* than the key this machine actually works with would be worse than useless,
|
|
98
|
+
* because the person would have proved the wrong secret.
|
|
99
|
+
*/
|
|
100
|
+
function localKey() {
|
|
101
|
+
const cfg = (0, config_1.loadConfig)();
|
|
102
|
+
const from = (0, config_1.keySource)(cfg, 'anthropic');
|
|
103
|
+
const value = (0, config_1.resolveKeys)(cfg).anthropic || null;
|
|
104
|
+
return { value, from };
|
|
105
|
+
}
|
|
106
|
+
function localKeyHint() {
|
|
107
|
+
return `set ${(0, config_1.envVarName)('anthropic')}, or configure a key command in config.json`;
|
|
108
|
+
}
|
package/out/commands/repl.d.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/** How a session is opened: fresh, the latest in this project, a named one,
|
|
2
|
+
* or chosen from the list (manual 8.4, 8.5). */
|
|
3
|
+
export interface Opening {
|
|
4
|
+
latest?: boolean;
|
|
5
|
+
resume?: string;
|
|
6
|
+
pick?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function runRepl(how?: Opening): Promise<void>;
|