codiedev 0.9.51 → 0.9.53
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 +8 -1
- package/dist/captureLog.d.ts +1 -1
- package/dist/cli.js +7 -22
- package/dist/codie.js +1 -146
- package/dist/codieLauncher.d.ts +0 -5
- package/dist/codieLauncher.js +1 -22
- package/dist/codieRuntime.d.ts +1 -11
- package/dist/codieRuntime.js +3 -20
- package/dist/codieRuntimeInstall.d.ts +11 -12
- package/dist/codieRuntimeInstall.js +1 -3
- package/dist/commands/doctor.js +0 -8
- package/dist/connect.js +4 -53
- package/dist/cursorHooks.d.ts +9 -0
- package/dist/cursorHooks.js +56 -0
- package/dist/hook.js +95 -227
- package/dist/limitEvent.d.ts +4 -1
- package/dist/limitEvent.js +54 -0
- package/dist/limitEventReporter.d.ts +21 -0
- package/dist/limitEventReporter.js +91 -0
- package/dist/mcp.js +1 -93
- package/dist/repoResolver.js +1 -1
- package/dist/upgradeNudge.d.ts +0 -1
- package/dist/upgradeNudge.js +0 -1
- package/dist/utils.d.ts +10 -8
- package/dist/utils.js +174 -199
- package/package.json +5 -11
- package/dist/codieStartup.d.ts +0 -24
- package/dist/codieStartup.js +0 -29
- package/dist/commands/post.d.ts +0 -2
- package/dist/commands/post.js +0 -96
- package/dist/commands/security.d.ts +0 -1
- package/dist/commands/security.js +0 -156
- package/dist/security.d.ts +0 -97
- package/dist/security.js +0 -422
- package/dist/securityDeepScan.d.ts +0 -41
- package/dist/securityDeepScan.js +0 -248
- package/dist/securityDoctor.d.ts +0 -32
- package/dist/securityDoctor.js +0 -63
- package/dist/securityFeature.d.ts +0 -5
- package/dist/securityFeature.js +0 -7
- package/dist/securityInstall.d.ts +0 -62
- package/dist/securityInstall.js +0 -227
- package/dist/securityInventory.d.ts +0 -54
- package/dist/securityInventory.js +0 -556
- package/dist/securityPilot.d.ts +0 -19
- package/dist/securityPilot.js +0 -61
- package/dist/securityPolicy.d.ts +0 -32
- package/dist/securityPolicy.js +0 -179
- package/dist/securitySession.d.ts +0 -6
- package/dist/securitySession.js +0 -72
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ The CLI will prompt you for an API token (get one at https://codiedev.com/portal
|
|
|
12
12
|
|
|
13
13
|
- **Claude Code** — `SessionEnd` hook in `~/.claude/settings.json`
|
|
14
14
|
- **Codex** — `Stop` hook in `~/.codex/hooks.json`
|
|
15
|
-
- **Cursor** —
|
|
15
|
+
- **Cursor** — native session, backup, and capture hooks in `~/.cursor/hooks.json`
|
|
16
16
|
- **OpenCode / Codie** — plugin in `~/.config/opencode/plugins/codiedev.js`
|
|
17
17
|
|
|
18
18
|
Installed clients are wired automatically. The OpenCode adapter is staged even
|
|
@@ -49,6 +49,13 @@ container needs its own rule unless `~/.codiedev/config.json` is persisted.
|
|
|
49
49
|
|
|
50
50
|
Codex doesn't currently expose a `SessionEnd` event, so the hook runs on `Stop` (fires after each assistant turn). The backend dedupes by `(company, session_id)` and replaces the stored transcript on re-upload so the latest turn's snapshot wins. Summarization happens once per session; subsequent turn uploads keep the raw transcript fresh but don't re-summarize (to avoid running up LLM cost).
|
|
51
51
|
|
|
52
|
+
## Cursor note
|
|
53
|
+
|
|
54
|
+
Cursor uses its native hook events for session start/end and stop-time backup.
|
|
55
|
+
Cursor's `beforeSubmitPrompt` currently cannot inject dynamic context, so task-
|
|
56
|
+
specific discovery remains unavailable there. Cursor sessions keep their source
|
|
57
|
+
label and real transcript statistics through the shared capture pipeline.
|
|
58
|
+
|
|
52
59
|
## OpenCode note
|
|
53
60
|
|
|
54
61
|
OpenCode exposes session lifecycle events through plugins. Codiedev snapshots
|
package/dist/captureLog.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from "fs";
|
|
|
2
2
|
export declare const CAPTURE_LOG_MAX_BYTES: number;
|
|
3
3
|
export declare const CAPTURE_LOG_PATH: string;
|
|
4
4
|
export interface CaptureLogEntry {
|
|
5
|
-
stage: "capture-finish" | "upload" | "upload-deferred" | "
|
|
5
|
+
stage: "capture-finish" | "upload" | "upload-deferred" | "stderr";
|
|
6
6
|
sessionId: string | undefined;
|
|
7
7
|
outcome: string;
|
|
8
8
|
detail?: string;
|
package/dist/cli.js
CHANGED
|
@@ -29,12 +29,10 @@ const createTicket_1 = require("./commands/createTicket");
|
|
|
29
29
|
const doctor_1 = require("./commands/doctor");
|
|
30
30
|
const search_1 = require("./commands/search");
|
|
31
31
|
const library_1 = require("./commands/library");
|
|
32
|
-
const post_1 = require("./commands/post");
|
|
33
32
|
const share_1 = require("./commands/share");
|
|
34
33
|
const send_1 = require("./commands/send");
|
|
35
34
|
const react_1 = require("./commands/react");
|
|
36
35
|
const capture_1 = require("./commands/capture");
|
|
37
|
-
const security_1 = require("./commands/security");
|
|
38
36
|
const version_1 = require("./version");
|
|
39
37
|
const HELP = `
|
|
40
38
|
Codiedev CLI
|
|
@@ -44,14 +42,8 @@ Codiedev CLI
|
|
|
44
42
|
someone left off across sessions and providers.
|
|
45
43
|
|
|
46
44
|
Connect:
|
|
47
|
-
codiedev connect Link Claude Code / Codex to your org
|
|
48
|
-
codiedev doctor Verify setup
|
|
49
|
-
codiedev security pilot Run safe synthetic policy checks
|
|
50
|
-
codiedev security inventory Inventory MCPs, skills, hooks, plugins,
|
|
51
|
-
instructions, and editor extensions
|
|
52
|
-
codiedev security scan --deep Run installed open-source scanners too
|
|
53
|
-
codiedev security sync Fetch administrator policy locally
|
|
54
|
-
codiedev security rollback --yes Restore pre-update hook configuration
|
|
45
|
+
codiedev connect Link Claude Code / Codex / Cursor to your org
|
|
46
|
+
codiedev doctor Verify your setup after connecting
|
|
55
47
|
|
|
56
48
|
Harness:
|
|
57
49
|
codie Launch the governed Codie harness.
|
|
@@ -105,9 +97,6 @@ Discovery:
|
|
|
105
97
|
List artifacts in your workspace
|
|
106
98
|
|
|
107
99
|
Feed:
|
|
108
|
-
codiedev post --title "<t>" --body "<b>" [--intent share|request_review|
|
|
109
|
-
request_expertise|link_share|rfc] [--filename <key>]
|
|
110
|
-
[--mention <name>]... Publish to the team feed
|
|
111
100
|
codiedev react <postId> <emoji> Toggle a reaction on a feed post
|
|
112
101
|
|
|
113
102
|
Privacy:
|
|
@@ -135,7 +124,7 @@ Other artifact types (rare — use the matching prefix):
|
|
|
135
124
|
|
|
136
125
|
Skills (slash commands):
|
|
137
126
|
Add 'name:' + 'description:' YAML frontmatter to any pushed file
|
|
138
|
-
and it shows up as /<name> in Claude Code / Codex. Filename
|
|
127
|
+
and it shows up as /<name> in Claude Code / Codex / Cursor. Filename
|
|
139
128
|
prefix doesn't matter — frontmatter is the signal.
|
|
140
129
|
|
|
141
130
|
Examples:
|
|
@@ -172,6 +161,8 @@ codiedev connect — link your agent CLI to Codiedev
|
|
|
172
161
|
- ~/.claude/CLAUDE.md instructions (teaches Claude the commands)
|
|
173
162
|
- ~/.codex/hooks.json hook (same, for Codex)
|
|
174
163
|
- ~/.codex/AGENTS.md instructions (same, for Codex)
|
|
164
|
+
- ~/.cursor/hooks.json hooks (session, prompt, security, capture)
|
|
165
|
+
- ~/.cursor/rules/codiedev.mdc (teaches Cursor the commands)
|
|
175
166
|
|
|
176
167
|
Re-run anytime to swap accounts or refresh the instruction block.
|
|
177
168
|
|
|
@@ -374,7 +365,7 @@ Default path:
|
|
|
374
365
|
# body...
|
|
375
366
|
3. codiedev push portal-design.md
|
|
376
367
|
|
|
377
|
-
It's now /portal-design in Claude Code / Codex.
|
|
368
|
+
It's now /portal-design in Claude Code / Codex / Cursor.
|
|
378
369
|
|
|
379
370
|
Filename prefix is irrelevant for skills — frontmatter is the only
|
|
380
371
|
signal. The stored artifact type still follows the filename rule
|
|
@@ -392,7 +383,7 @@ email notifications when pinged.
|
|
|
392
383
|
|
|
393
384
|
## Agent-native
|
|
394
385
|
|
|
395
|
-
If you use Claude Code or
|
|
386
|
+
If you use Claude Code, Codex, or Cursor, the agent already knows the commands —
|
|
396
387
|
'codiedev connect' installs instructions into your user-level config.
|
|
397
388
|
Just say things like:
|
|
398
389
|
|
|
@@ -460,9 +451,6 @@ async function main() {
|
|
|
460
451
|
case "verify":
|
|
461
452
|
await (0, doctor_1.runDoctor)(rest);
|
|
462
453
|
return;
|
|
463
|
-
case "security":
|
|
464
|
-
await (0, security_1.runSecurityCommand)(rest);
|
|
465
|
-
return;
|
|
466
454
|
case "push":
|
|
467
455
|
await (0, push_1.runPush)(rest);
|
|
468
456
|
return;
|
|
@@ -513,9 +501,6 @@ async function main() {
|
|
|
513
501
|
case "ls":
|
|
514
502
|
await (0, library_1.runLibrary)(rest);
|
|
515
503
|
return;
|
|
516
|
-
case "post":
|
|
517
|
-
await (0, post_1.runPost)(rest);
|
|
518
|
-
return;
|
|
519
504
|
case "share":
|
|
520
505
|
await (0, share_1.runShare)(rest);
|
|
521
506
|
return;
|
package/dist/codie.js
CHANGED
|
@@ -53,7 +53,6 @@ const configDir_1 = require("./configDir");
|
|
|
53
53
|
const codieLauncher_1 = require("./codieLauncher");
|
|
54
54
|
const codieRuntime_1 = require("./codieRuntime");
|
|
55
55
|
const codieRuntimeInstall_1 = require("./codieRuntimeInstall");
|
|
56
|
-
const codieStartup_1 = require("./codieStartup");
|
|
57
56
|
const upgradeNudge_1 = require("./upgradeNudge");
|
|
58
57
|
function git(args) {
|
|
59
58
|
const result = (0, child_process_1.spawnSync)("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
@@ -170,120 +169,6 @@ function installBrandWordmarkUnsafe(runtime) {
|
|
|
170
169
|
(0, child_process_1.spawnSync)("codesign", ["--force", "--sign", "-", runtime], { stdio: "ignore" });
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
|
-
async function runNonInteractive(runtime, runtimeArgs, env) {
|
|
174
|
-
const detached = process.platform !== "win32";
|
|
175
|
-
const child = (0, child_process_1.spawn)(runtime, runtimeArgs, {
|
|
176
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
177
|
-
env,
|
|
178
|
-
detached,
|
|
179
|
-
});
|
|
180
|
-
if (child.stdin)
|
|
181
|
-
process.stdin.pipe(child.stdin);
|
|
182
|
-
const signalChild = (signal) => {
|
|
183
|
-
if (detached && child.pid) {
|
|
184
|
-
try {
|
|
185
|
-
process.kill(-child.pid, signal);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
// Fall back to the direct child if its process group already exited.
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
child.kill(signal);
|
|
193
|
-
};
|
|
194
|
-
const forwardInterrupt = () => signalChild("SIGINT");
|
|
195
|
-
const forwardTermination = () => signalChild("SIGTERM");
|
|
196
|
-
process.once("SIGINT", forwardInterrupt);
|
|
197
|
-
process.once("SIGTERM", forwardTermination);
|
|
198
|
-
return await new Promise((resolve, reject) => {
|
|
199
|
-
let blockReason;
|
|
200
|
-
const errorPrefixes = [Buffer.from("\x1b[91m\x1b[1mError:"), Buffer.from("Error: {")];
|
|
201
|
-
const retainedPrefixBytes = Math.max(...errorPrefixes.map((prefix) => prefix.length)) - 1;
|
|
202
|
-
// OpenCode's generic UnknownError and the adapter's private reason can be
|
|
203
|
-
// delivered in either order — and the generic block can arrive on stdout
|
|
204
|
-
// or stderr. Gate both streams by content, retaining only a possible final
|
|
205
|
-
// error block. Ordinary output stays streaming apart from the few bytes
|
|
206
|
-
// needed to recognize a split prefix.
|
|
207
|
-
const createOutputGate = (write) => {
|
|
208
|
-
let tail = Buffer.alloc(0);
|
|
209
|
-
let possibleError;
|
|
210
|
-
return {
|
|
211
|
-
push(chunk, blocked) {
|
|
212
|
-
if (blocked) {
|
|
213
|
-
if (possibleError)
|
|
214
|
-
possibleError.push(Buffer.from(chunk));
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
if (possibleError) {
|
|
218
|
-
possibleError.push(Buffer.from(chunk));
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const combined = Buffer.concat([tail, chunk]);
|
|
222
|
-
let errorStart = -1;
|
|
223
|
-
for (const prefix of errorPrefixes) {
|
|
224
|
-
const index = combined.indexOf(prefix);
|
|
225
|
-
if (index >= 0 && (errorStart < 0 || index < errorStart))
|
|
226
|
-
errorStart = index;
|
|
227
|
-
}
|
|
228
|
-
if (errorStart >= 0) {
|
|
229
|
-
if (errorStart > 0)
|
|
230
|
-
write(combined.subarray(0, errorStart));
|
|
231
|
-
possibleError = [combined.subarray(errorStart)];
|
|
232
|
-
tail = Buffer.alloc(0);
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const flushBytes = Math.max(0, combined.length - retainedPrefixBytes);
|
|
236
|
-
if (flushBytes > 0)
|
|
237
|
-
write(combined.subarray(0, flushBytes));
|
|
238
|
-
tail = combined.subarray(flushBytes);
|
|
239
|
-
},
|
|
240
|
-
finish(blocked) {
|
|
241
|
-
if (tail.length > 0)
|
|
242
|
-
write(tail);
|
|
243
|
-
const heldError = possibleError ? Buffer.concat(possibleError).toString() : "";
|
|
244
|
-
const genericBlockError = heldError.includes("UnknownError") &&
|
|
245
|
-
heldError.includes("Unexpected server error");
|
|
246
|
-
if (heldError && (!blocked || !genericBlockError))
|
|
247
|
-
write(heldError);
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
};
|
|
251
|
-
const stdoutGate = createOutputGate((chunk) => process.stdout.write(chunk));
|
|
252
|
-
const stderrGate = createOutputGate((chunk) => process.stderr.write(chunk));
|
|
253
|
-
child.stdout?.on("data", (chunk) => {
|
|
254
|
-
stdoutGate.push(Buffer.from(chunk), Boolean(blockReason));
|
|
255
|
-
});
|
|
256
|
-
child.stderr?.on("data", (chunk) => {
|
|
257
|
-
const text = chunk.toString();
|
|
258
|
-
const reason = (0, codieLauncher_1.extractCodieSecurityBlock)(text);
|
|
259
|
-
if (reason) {
|
|
260
|
-
blockReason = reason;
|
|
261
|
-
signalChild("SIGTERM");
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
stderrGate.push(Buffer.from(chunk), Boolean(blockReason));
|
|
265
|
-
});
|
|
266
|
-
child.once("error", (error) => {
|
|
267
|
-
if (child.stdin)
|
|
268
|
-
process.stdin.unpipe(child.stdin);
|
|
269
|
-
process.removeListener("SIGINT", forwardInterrupt);
|
|
270
|
-
process.removeListener("SIGTERM", forwardTermination);
|
|
271
|
-
reject(error);
|
|
272
|
-
});
|
|
273
|
-
child.once("close", (status) => {
|
|
274
|
-
if (child.stdin)
|
|
275
|
-
process.stdin.unpipe(child.stdin);
|
|
276
|
-
process.removeListener("SIGINT", forwardInterrupt);
|
|
277
|
-
process.removeListener("SIGTERM", forwardTermination);
|
|
278
|
-
stdoutGate.finish(Boolean(blockReason));
|
|
279
|
-
stderrGate.finish(Boolean(blockReason));
|
|
280
|
-
if (blockReason) {
|
|
281
|
-
console.error(`Codie Security blocked this action:\n${blockReason}`);
|
|
282
|
-
}
|
|
283
|
-
resolve(status);
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
172
|
async function main() {
|
|
288
173
|
(0, codieRuntime_1.assertCodieNodeVersion)(process.versions.node);
|
|
289
174
|
const connected = connectedCodiedevConfig();
|
|
@@ -301,10 +186,6 @@ async function main() {
|
|
|
301
186
|
process.exitCode = update.status ?? 0;
|
|
302
187
|
return;
|
|
303
188
|
}
|
|
304
|
-
const policyRefresh = await (0, codieStartup_1.refreshCodieSecurityPolicy)(connected);
|
|
305
|
-
if (policyRefresh.status === "cached") {
|
|
306
|
-
console.error(`codie: security policy refresh failed; using the cached policy (${policyRefresh.error})`);
|
|
307
|
-
}
|
|
308
189
|
const gatewayUrl = process.env.CODIEDEV_GATEWAY_URL || "https://gateway.codiedev.com/api/v1";
|
|
309
190
|
const catalog = await (0, codieLauncher_1.fetchApprovedCatalog)({ baseUrl: gatewayUrl, key });
|
|
310
191
|
const parsed = (0, codieLauncher_1.parseCodieArgs)(process.argv.slice(2));
|
|
@@ -315,20 +196,11 @@ async function main() {
|
|
|
315
196
|
}
|
|
316
197
|
(0, codieLauncher_1.validateCodieArgs)(parsed.args, catalog);
|
|
317
198
|
const stateDir = (0, configDir_1.codiedevStateDir)();
|
|
318
|
-
const runtime =
|
|
199
|
+
const runtime = (0, codieRuntimeInstall_1.ensureCodieRuntimeBinary)({
|
|
319
200
|
resolve: () => (0, codieRuntime_1.resolveCodieRuntime)({
|
|
320
201
|
env: process.env,
|
|
321
202
|
stateDir,
|
|
322
203
|
existsSync: (candidate) => fs.existsSync(candidate),
|
|
323
|
-
readInstalledVersion: (candidate) => {
|
|
324
|
-
try {
|
|
325
|
-
const value = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
326
|
-
return typeof value.version === "string" ? value.version : null;
|
|
327
|
-
}
|
|
328
|
-
catch {
|
|
329
|
-
return null;
|
|
330
|
-
}
|
|
331
|
-
},
|
|
332
204
|
resolveBundled: () => {
|
|
333
205
|
try {
|
|
334
206
|
return require.resolve("opencode-ai/bin/opencode.exe");
|
|
@@ -339,16 +211,6 @@ async function main() {
|
|
|
339
211
|
},
|
|
340
212
|
}),
|
|
341
213
|
install: (missing) => (0, codieRuntimeInstall_1.installCodieRuntimeOnDisk)(missing, stateDir),
|
|
342
|
-
confirmUpdate: async (outdated) => {
|
|
343
|
-
console.error("");
|
|
344
|
-
console.error(`Codie harness ${outdated.expectedVersion} is available (you're on ${outdated.currentVersion}).`);
|
|
345
|
-
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
346
|
-
console.error("Restart `codie` in an interactive terminal to update the harness.");
|
|
347
|
-
console.error("");
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
return await (0, upgradeNudge_1.promptYesNo)(" Update the harness now? [y/N] ");
|
|
351
|
-
},
|
|
352
214
|
});
|
|
353
215
|
const metadataPlugin = (0, url_1.pathToFileURL)(assetPath("opencode-plugin.mjs")).href;
|
|
354
216
|
const capturePlugin = (0, codieLauncher_1.resolveCapturePlugin)({ homeDir: os.homedir(), existsSync: fs.existsSync });
|
|
@@ -370,13 +232,6 @@ async function main() {
|
|
|
370
232
|
OPENCODE_CONFIG_CONTENT: JSON.stringify(config),
|
|
371
233
|
};
|
|
372
234
|
const runtimeArgs = (0, codieLauncher_1.withCodieWorkingDirectory)(parsed.args, process.cwd());
|
|
373
|
-
const nonInteractiveRun = runtimeArgs[0] === "run";
|
|
374
|
-
if (nonInteractiveRun)
|
|
375
|
-
env.CODIEDEV_SECURITY_BLOCK_OUTPUT = "marker";
|
|
376
|
-
if (nonInteractiveRun) {
|
|
377
|
-
process.exitCode = (await runNonInteractive(runtime, runtimeArgs, env)) ?? 1;
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
235
|
const result = (0, child_process_1.spawnSync)(runtime, runtimeArgs, { stdio: "inherit", env });
|
|
381
236
|
if (result.error)
|
|
382
237
|
throw result.error;
|
package/dist/codieLauncher.d.ts
CHANGED
|
@@ -2,11 +2,6 @@ export interface CatalogModel {
|
|
|
2
2
|
id: string;
|
|
3
3
|
name?: string;
|
|
4
4
|
}
|
|
5
|
-
export declare const CODIE_SECURITY_BLOCK_MARKER = "__CODIEDEV_SECURITY_BLOCK__";
|
|
6
|
-
/** Extract the private adapter marker used to carry a local block reason
|
|
7
|
-
* across OpenCode's generic 500 boundary. The marker never contains prompt or
|
|
8
|
-
* tool input — only the deterministic policy reason. */
|
|
9
|
-
export declare function extractCodieSecurityBlock(stderr: string): string | undefined;
|
|
10
5
|
/**
|
|
11
6
|
* Pin non-interactive runs to the directory where `codie` was launched.
|
|
12
7
|
* OpenCode can reuse a previously-known project instance; without an explicit
|
package/dist/codieLauncher.js
CHANGED
|
@@ -42,8 +42,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
42
42
|
};
|
|
43
43
|
})();
|
|
44
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.HIDDEN_WORDMARK = exports.CODIEDEV_WORDMARK = exports.LEGACY_CODIEDEV_WORDMARK = exports.STOCK_WORDMARK = exports.BRAND_PLUGIN_SPEC =
|
|
46
|
-
exports.extractCodieSecurityBlock = extractCodieSecurityBlock;
|
|
45
|
+
exports.HIDDEN_WORDMARK = exports.CODIEDEV_WORDMARK = exports.LEGACY_CODIEDEV_WORDMARK = exports.STOCK_WORDMARK = exports.BRAND_PLUGIN_SPEC = void 0;
|
|
47
46
|
exports.withCodieWorkingDirectory = withCodieWorkingDirectory;
|
|
48
47
|
exports.bareModel = bareModel;
|
|
49
48
|
exports.buildCodieConfig = buildCodieConfig;
|
|
@@ -63,26 +62,6 @@ const DEFAULT_NAMES = {
|
|
|
63
62
|
"z-ai/glm-5.2": "GLM 5.2 · Fireworks ZDR",
|
|
64
63
|
"moonshotai/kimi-k2.7-code": "Kimi K2.7 Code · Fireworks ZDR",
|
|
65
64
|
};
|
|
66
|
-
exports.CODIE_SECURITY_BLOCK_MARKER = "__CODIEDEV_SECURITY_BLOCK__";
|
|
67
|
-
/** Extract the private adapter marker used to carry a local block reason
|
|
68
|
-
* across OpenCode's generic 500 boundary. The marker never contains prompt or
|
|
69
|
-
* tool input — only the deterministic policy reason. */
|
|
70
|
-
function extractCodieSecurityBlock(stderr) {
|
|
71
|
-
for (const line of stderr.split(/\r?\n/)) {
|
|
72
|
-
const markerIndex = line.indexOf(exports.CODIE_SECURITY_BLOCK_MARKER);
|
|
73
|
-
if (markerIndex < 0)
|
|
74
|
-
continue;
|
|
75
|
-
try {
|
|
76
|
-
const parsed = JSON.parse(line.slice(markerIndex + exports.CODIE_SECURITY_BLOCK_MARKER.length));
|
|
77
|
-
if (typeof parsed?.reason === "string" && parsed.reason.trim())
|
|
78
|
-
return parsed.reason.trim();
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
// Ignore malformed or foreign stderr and preserve the original runtime error.
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return undefined;
|
|
85
|
-
}
|
|
86
65
|
/**
|
|
87
66
|
* Pin non-interactive runs to the directory where `codie` was launched.
|
|
88
67
|
* OpenCode can reuse a previously-known project instance; without an explicit
|
package/dist/codieRuntime.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const OPENCODE_RUNTIME_SPEC = "opencode-ai@1.18.4";
|
|
2
|
-
export declare const OPENCODE_RUNTIME_VERSION: string;
|
|
3
2
|
export declare const CODIE_MIN_NODE_MAJOR = 20;
|
|
4
3
|
export type CodieRuntime = {
|
|
5
4
|
kind: "ready";
|
|
@@ -9,21 +8,12 @@ export type CodieRuntime = {
|
|
|
9
8
|
installDir: string;
|
|
10
9
|
binary: string;
|
|
11
10
|
spec: string;
|
|
12
|
-
} | {
|
|
13
|
-
kind: "outdated";
|
|
14
|
-
installDir: string;
|
|
15
|
-
binary: string;
|
|
16
|
-
spec: string;
|
|
17
|
-
currentVersion: string;
|
|
18
|
-
expectedVersion: string;
|
|
19
11
|
};
|
|
20
12
|
export declare function codieRuntimeDir(stateDir: string): string;
|
|
21
|
-
export declare function
|
|
22
|
-
export declare function resolveCodieRuntime({ env, stateDir, existsSync, readInstalledVersion, resolveBundled, }: {
|
|
13
|
+
export declare function resolveCodieRuntime({ env, stateDir, existsSync, resolveBundled, }: {
|
|
23
14
|
env: Record<string, string | undefined>;
|
|
24
15
|
stateDir: string;
|
|
25
16
|
existsSync: (candidate: string) => boolean;
|
|
26
|
-
readInstalledVersion?: (packageJson: string) => string | null;
|
|
27
17
|
resolveBundled: () => string | null;
|
|
28
18
|
}): CodieRuntime;
|
|
29
19
|
export declare function assertCodieNodeVersion(version: string): void;
|
package/dist/codieRuntime.js
CHANGED
|
@@ -43,9 +43,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
43
43
|
};
|
|
44
44
|
})();
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.CODIE_MIN_NODE_MAJOR = exports.
|
|
46
|
+
exports.CODIE_MIN_NODE_MAJOR = exports.OPENCODE_RUNTIME_SPEC = void 0;
|
|
47
47
|
exports.codieRuntimeDir = codieRuntimeDir;
|
|
48
|
-
exports.installedRuntimePackageJson = installedRuntimePackageJson;
|
|
49
48
|
exports.resolveCodieRuntime = resolveCodieRuntime;
|
|
50
49
|
exports.assertCodieNodeVersion = assertCodieNodeVersion;
|
|
51
50
|
const path = __importStar(require("path"));
|
|
@@ -53,7 +52,6 @@ const path = __importStar(require("path"));
|
|
|
53
52
|
// recognizes byte-for-byte, so a floating version would silently regress the
|
|
54
53
|
// terminal branding whenever OpenCode ships a new build.
|
|
55
54
|
exports.OPENCODE_RUNTIME_SPEC = "opencode-ai@1.18.4";
|
|
56
|
-
exports.OPENCODE_RUNTIME_VERSION = exports.OPENCODE_RUNTIME_SPEC.slice(exports.OPENCODE_RUNTIME_SPEC.lastIndexOf("@") + 1);
|
|
57
55
|
// The harness needs 20; capture does not. package.json `engines` stays >=18 so
|
|
58
56
|
// `codiedev connect` still installs for Node 18 users — this floor is enforced
|
|
59
57
|
// at `codie` launch instead.
|
|
@@ -64,10 +62,7 @@ function codieRuntimeDir(stateDir) {
|
|
|
64
62
|
function installedBinary(stateDir) {
|
|
65
63
|
return path.join(codieRuntimeDir(stateDir), "node_modules", "opencode-ai", "bin", "opencode.exe");
|
|
66
64
|
}
|
|
67
|
-
function
|
|
68
|
-
return path.join(codieRuntimeDir(stateDir), "node_modules", "opencode-ai", "package.json");
|
|
69
|
-
}
|
|
70
|
-
function resolveCodieRuntime({ env, stateDir, existsSync, readInstalledVersion, resolveBundled, }) {
|
|
65
|
+
function resolveCodieRuntime({ env, stateDir, existsSync, resolveBundled, }) {
|
|
71
66
|
// 1. Explicit override — the air-gapped / pre-provisioned escape hatch.
|
|
72
67
|
const override = env.CODIEDEV_OPENCODE_BINARY?.trim();
|
|
73
68
|
if (override) {
|
|
@@ -83,20 +78,8 @@ function resolveCodieRuntime({ env, stateDir, existsSync, readInstalledVersion,
|
|
|
83
78
|
return { kind: "ready", binary: bundled };
|
|
84
79
|
// 3. The lazily installed engine.
|
|
85
80
|
const binary = installedBinary(stateDir);
|
|
86
|
-
if (existsSync(binary))
|
|
87
|
-
const currentVersion = readInstalledVersion?.(installedRuntimePackageJson(stateDir)) ?? null;
|
|
88
|
-
if (currentVersion && currentVersion !== exports.OPENCODE_RUNTIME_VERSION) {
|
|
89
|
-
return {
|
|
90
|
-
kind: "outdated",
|
|
91
|
-
installDir: codieRuntimeDir(stateDir),
|
|
92
|
-
binary,
|
|
93
|
-
spec: exports.OPENCODE_RUNTIME_SPEC,
|
|
94
|
-
currentVersion,
|
|
95
|
-
expectedVersion: exports.OPENCODE_RUNTIME_VERSION,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
81
|
+
if (existsSync(binary))
|
|
98
82
|
return { kind: "ready", binary };
|
|
99
|
-
}
|
|
100
83
|
return { kind: "missing", installDir: codieRuntimeDir(stateDir), binary, spec: exports.OPENCODE_RUNTIME_SPEC };
|
|
101
84
|
}
|
|
102
85
|
function assertCodieNodeVersion(version) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { CodieRuntime } from "./codieRuntime";
|
|
2
|
-
type InstallableCodieRuntime = Exclude<CodieRuntime, {
|
|
3
|
-
kind: "ready";
|
|
4
|
-
}>;
|
|
5
2
|
export declare function buildRuntimeInstallArgs(stagingDir: string, spec: string): string[];
|
|
6
3
|
export interface InstallDeps {
|
|
7
|
-
runtime:
|
|
4
|
+
runtime: Extract<CodieRuntime, {
|
|
5
|
+
kind: "missing";
|
|
6
|
+
}>;
|
|
8
7
|
makeStagingDir: () => string;
|
|
9
8
|
run: (args: string[]) => {
|
|
10
9
|
status: number | null;
|
|
@@ -16,13 +15,13 @@ export interface InstallDeps {
|
|
|
16
15
|
log: (message: string) => void;
|
|
17
16
|
}
|
|
18
17
|
export declare function installCodieRuntime(deps: InstallDeps): void;
|
|
19
|
-
export declare function ensureCodieRuntimeBinary({ resolve, install,
|
|
18
|
+
export declare function ensureCodieRuntimeBinary({ resolve, install, }: {
|
|
20
19
|
resolve: () => CodieRuntime;
|
|
21
|
-
install: (runtime:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
install: (runtime: Extract<CodieRuntime, {
|
|
21
|
+
kind: "missing";
|
|
22
|
+
}>) => void;
|
|
23
|
+
}): string;
|
|
24
|
+
export declare function installCodieRuntimeOnDisk(runtime: Extract<CodieRuntime, {
|
|
25
|
+
kind: "missing";
|
|
26
|
+
}>, stateDir: string): void;
|
|
27
27
|
export declare function defaultStagingRoot(): string;
|
|
28
|
-
export {};
|
|
@@ -98,12 +98,10 @@ function installCodieRuntime(deps) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
// Resolve the engine, downloading it once if this is the first `codie` run.
|
|
101
|
-
|
|
101
|
+
function ensureCodieRuntimeBinary({ resolve, install, }) {
|
|
102
102
|
const runtime = resolve();
|
|
103
103
|
if (runtime.kind === "ready")
|
|
104
104
|
return runtime.binary;
|
|
105
|
-
if (runtime.kind === "outdated" && !(await confirmUpdate(runtime)))
|
|
106
|
-
return runtime.binary;
|
|
107
105
|
install(runtime);
|
|
108
106
|
return runtime.binary;
|
|
109
107
|
}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -45,8 +45,6 @@ const version_1 = require("../version");
|
|
|
45
45
|
const upgradeNudge_1 = require("../upgradeNudge");
|
|
46
46
|
const captureReadiness_1 = require("../captureReadiness");
|
|
47
47
|
const captureLog_1 = require("../captureLog");
|
|
48
|
-
const securityDoctor_1 = require("../securityDoctor");
|
|
49
|
-
const securityFeature_1 = require("../securityFeature");
|
|
50
48
|
const CLAUDE_SETTINGS_PATH = path.join(os.homedir(), ".claude", "settings.json");
|
|
51
49
|
const CLAUDE_INSTRUCTIONS_PATH = path.join(os.homedir(), ".claude", "CLAUDE.md");
|
|
52
50
|
const CODEX_HOOKS_PATH = path.join(os.homedir(), ".codex", "hooks.json");
|
|
@@ -484,12 +482,6 @@ async function runDoctor(_args) {
|
|
|
484
482
|
detail: "not installed on this machine",
|
|
485
483
|
});
|
|
486
484
|
}
|
|
487
|
-
// Agent Security is part of installation health, not a separate setup
|
|
488
|
-
// concept. Keep `codiedev security doctor` as an alias for focused output,
|
|
489
|
-
// while the main doctor remains the one command users need to remember.
|
|
490
|
-
if ((0, securityFeature_1.isAgentSecurityEnabled)(config)) {
|
|
491
|
-
checks.push(...(0, securityDoctor_1.securityDoctorChecks)((0, securityDoctor_1.collectSecurityDoctorReport)(config.companyId)));
|
|
492
|
-
}
|
|
493
485
|
// 8. gh / glab CLIs (optional — only needed for reverse-ticket from a
|
|
494
486
|
// specific PR/MR URL; branch mode works without either).
|
|
495
487
|
checks.push({
|
package/dist/connect.js
CHANGED
|
@@ -39,16 +39,11 @@ const https = __importStar(require("https"));
|
|
|
39
39
|
const http = __importStar(require("http"));
|
|
40
40
|
const crypto = __importStar(require("crypto"));
|
|
41
41
|
const os = __importStar(require("os"));
|
|
42
|
-
const fs = __importStar(require("fs"));
|
|
43
|
-
const path = __importStar(require("path"));
|
|
44
42
|
const utils_1 = require("./utils");
|
|
45
43
|
const connectFlow_1 = require("./connectFlow");
|
|
46
44
|
const version_1 = require("./version");
|
|
47
45
|
const upgradeNudge_1 = require("./upgradeNudge");
|
|
48
46
|
const shared_1 = require("./commands/shared");
|
|
49
|
-
const securityInstall_1 = require("./securityInstall");
|
|
50
|
-
const securityPolicy_1 = require("./securityPolicy");
|
|
51
|
-
const securityFeature_1 = require("./securityFeature");
|
|
52
47
|
// cli.codiedev.com is a Convex custom domain on the prod deployment; the
|
|
53
48
|
// underlying judicious-falcon-861.convex.site URL keeps serving, so configs
|
|
54
49
|
// written by older CLI versions stay valid without a re-connect.
|
|
@@ -205,7 +200,6 @@ async function runConnect(args = []) {
|
|
|
205
200
|
// Extract fields from response
|
|
206
201
|
const companyId = responseData.companyId;
|
|
207
202
|
const companyName = responseData.companyName;
|
|
208
|
-
const agentSecurityEnabled = responseData.agentSecurityEnabled === true;
|
|
209
203
|
const repos = responseData.repos ?? [];
|
|
210
204
|
if (!companyId || !companyName) {
|
|
211
205
|
console.error("\nError: Invalid response from server. Token may be invalid.");
|
|
@@ -218,7 +212,6 @@ async function runConnect(args = []) {
|
|
|
218
212
|
repos,
|
|
219
213
|
lastSynced: new Date().toISOString(),
|
|
220
214
|
backendUrl: BACKEND_URL,
|
|
221
|
-
agentSecurityEnabled,
|
|
222
215
|
deviceId: saved?.deviceId || crypto.randomUUID(),
|
|
223
216
|
deviceName: saved?.deviceName || os.hostname(),
|
|
224
217
|
captureIgnoredPaths: saved?.captureIgnoredPaths ?? [],
|
|
@@ -287,16 +280,6 @@ async function runConnect(args = []) {
|
|
|
287
280
|
// /api/cli/markInstalled so the portal's "Connected" state reflects
|
|
288
281
|
// what's actually wired up on this machine, not just "token validated."
|
|
289
282
|
const installedTargets = [];
|
|
290
|
-
const home = os.homedir();
|
|
291
|
-
const securityConfigPaths = [
|
|
292
|
-
path.join(home, ".claude", "settings.json"),
|
|
293
|
-
path.join(home, ".codex", "hooks.json"),
|
|
294
|
-
path.join(home, ".config", "opencode", "plugins", "codiedev.js"),
|
|
295
|
-
path.join(home, ".codex", "config.toml"),
|
|
296
|
-
];
|
|
297
|
-
// Snapshot before any hook update. Rollback is intentionally not automatic:
|
|
298
|
-
// an administrator can inspect these 0600 copies before restoring them.
|
|
299
|
-
const securitySnapshot = (0, securityInstall_1.createSecurityInstallSnapshot)(securityConfigPaths);
|
|
300
283
|
// Wrap each per-target write so we emit one install_target row each. The
|
|
301
284
|
// existing user-visible behavior (console.warn on failure, continue) is
|
|
302
285
|
// unchanged — telemetry just observes the outcome.
|
|
@@ -319,50 +302,21 @@ async function runConnect(args = []) {
|
|
|
319
302
|
}
|
|
320
303
|
};
|
|
321
304
|
if (hasClaude) {
|
|
322
|
-
runInstall("claude-code-hook",
|
|
305
|
+
runInstall("claude-code-hook", utils_1.installHook, "Claude Code SessionEnd (capture) + UserPromptSubmit (skill discovery) + Stop (auto-backup) hooks (~/.claude/settings.json)", "claudeCode-hook");
|
|
323
306
|
runInstall("claude-code-instructions", utils_1.installClaudeCodeInstructions, "Claude Code agent instructions (~/.claude/CLAUDE.md)", "claudeCode-instructions");
|
|
324
307
|
}
|
|
325
308
|
if (hasCodex) {
|
|
326
|
-
runInstall("codex-hook",
|
|
309
|
+
runInstall("codex-hook", utils_1.installCodexHook, "Codex Stop (capture + auto-backup) hooks (~/.codex/hooks.json)", "codex-hook");
|
|
327
310
|
runInstall("codex-instructions", utils_1.installCodexInstructions, "Codex agent instructions (~/.codex/AGENTS.md)", "codex-instructions");
|
|
328
311
|
}
|
|
329
312
|
if (hasCursor) {
|
|
330
|
-
runInstall("cursor-hook", utils_1.installCursorHook, "Cursor
|
|
313
|
+
runInstall("cursor-hook", utils_1.installCursorHook, "Cursor sessionStart + stop backup + sessionEnd capture hooks (~/.cursor/hooks.json)", "cursor-hook");
|
|
331
314
|
runInstall("cursor-instructions", utils_1.installCursorInstructions, "Cursor agent instructions (~/.cursor/rules/codiedev.mdc)", "cursor-instructions");
|
|
332
315
|
}
|
|
333
316
|
// Always stage the adapter. It is dormant until OpenCode starts, which lets
|
|
334
317
|
// a user connect Claude Code today and install the Codie harness tomorrow
|
|
335
318
|
// without needing a second setup ritual.
|
|
336
|
-
runInstall("opencode-capture-adapter",
|
|
337
|
-
// Record the exact installed hook bytes and the pre-update rollback files.
|
|
338
|
-
// This supplies health/integrity checks without requiring a package publish
|
|
339
|
-
// or trusting whichever `node` happens to be first on PATH later.
|
|
340
|
-
try {
|
|
341
|
-
const hookScriptPath = path.join(__dirname, "hook.js");
|
|
342
|
-
if (agentSecurityEnabled && fs.existsSync(hookScriptPath)) {
|
|
343
|
-
const targets = [];
|
|
344
|
-
if (installedTargets.includes("claudeCode-hook"))
|
|
345
|
-
targets.push({ surface: "claude-code", configPath: securityConfigPaths[0] });
|
|
346
|
-
if (installedTargets.includes("codex-hook"))
|
|
347
|
-
targets.push({ surface: "codex", configPath: securityConfigPaths[1] });
|
|
348
|
-
if (installedTargets.includes("opencode-capture"))
|
|
349
|
-
targets.push({ surface: "codie-harness", configPath: securityConfigPaths[2] });
|
|
350
|
-
(0, securityInstall_1.writeSecurityInstallManifest)({ hookScriptPath, snapshot: securitySnapshot, targets });
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
catch (err) {
|
|
354
|
-
console.warn(`Warning: Security hooks installed, but integrity manifest could not be written — ${err.message}`);
|
|
355
|
-
}
|
|
356
|
-
// Prime the local cache after installation. Hooks read this file only, so
|
|
357
|
-
// an endpoint decision never depends on live network latency.
|
|
358
|
-
if (agentSecurityEnabled) {
|
|
359
|
-
try {
|
|
360
|
-
await (0, securityPolicy_1.syncEndpointSecurityPolicy)(config);
|
|
361
|
-
}
|
|
362
|
-
catch (err) {
|
|
363
|
-
console.warn(`Warning: Agent-security policy will use safe defaults until sync succeeds — ${err.message}`);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
319
|
+
runInstall("opencode-capture-adapter", utils_1.installOpenCodeCapturePlugin, "OpenCode session capture adapter (~/.config/opencode/plugins/codiedev.js)", "opencode-capture");
|
|
366
320
|
// Tell the backend which targets we wired up so the portal's onboarding
|
|
367
321
|
// card flips to "Connected" only when something actually installed —
|
|
368
322
|
// not on bare token validation. Best-effort: a network failure here
|
|
@@ -401,8 +355,5 @@ async function runConnect(args = []) {
|
|
|
401
355
|
}
|
|
402
356
|
console.log();
|
|
403
357
|
console.log("Run `codiedev doctor` to verify everything's wired up.");
|
|
404
|
-
if ((0, securityFeature_1.isAgentSecurityEnabled)(config)) {
|
|
405
|
-
console.log("Run `codiedev security pilot` to validate blocking safely.");
|
|
406
|
-
}
|
|
407
358
|
console.log();
|
|
408
359
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Normalize Cursor's native hook payload into the shared capture shape. */
|
|
2
|
+
export declare function normalizeCursorHookInput<T extends Record<string, unknown>>(input: T): T & Record<string, unknown>;
|
|
3
|
+
/** Add Claude-compatible message discriminators while preserving Cursor JSONL. */
|
|
4
|
+
export declare function normalizeCursorTranscript(content: string): string;
|
|
5
|
+
/** Cursor may change its private JSONL record shape independently of the hook
|
|
6
|
+
* contract. Only a byte-empty snapshot is safe to discard; a non-empty file
|
|
7
|
+
* that the current normalizer cannot parse must still be uploaded for backend
|
|
8
|
+
* recovery and diagnosis. */
|
|
9
|
+
export declare function isCursorTranscriptEmpty(content: string): boolean;
|