codiedev 0.10.0-beta.5 → 0.10.0-beta.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 (44) hide show
  1. package/README.md +4 -4
  2. package/dist/captureSignals.js +2 -0
  3. package/dist/cli.js +38 -50
  4. package/dist/codexHookTrust.js +67 -4
  5. package/dist/codie.js +23 -74
  6. package/dist/codieLauncher.js +18 -22
  7. package/dist/commands/agentTemplates.generated.js +136 -0
  8. package/dist/commands/agents.js +1068 -0
  9. package/dist/commands/agentsSdk.generated.js +7 -0
  10. package/dist/commands/doctor.js +12 -38
  11. package/dist/commands/evals.js +187 -0
  12. package/dist/commands/pack.js +1 -1
  13. package/dist/commands/traces.js +79 -15
  14. package/dist/commands/tracesLabel.js +348 -0
  15. package/dist/connect.js +11 -52
  16. package/dist/copilotHooks.js +0 -4
  17. package/dist/cursorHooks.js +0 -15
  18. package/dist/harnessDirs.js +4 -0
  19. package/dist/hook.js +33 -197
  20. package/dist/limitEventReporter.js +1 -1
  21. package/dist/managedPi.js +240 -0
  22. package/dist/mcp.js +0 -307
  23. package/dist/packs/harnesses.js +40 -3
  24. package/dist/packs/install.js +2 -1
  25. package/dist/piHooks.js +216 -0
  26. package/dist/piRuntime.js +120 -0
  27. package/dist/selfUpdate.js +47 -2
  28. package/dist/utils.js +232 -115
  29. package/package.json +5 -7
  30. package/dist/codieStartup.js +0 -27
  31. package/dist/commands/promote.js +0 -53
  32. package/dist/commands/react.js +0 -38
  33. package/dist/commands/reverseTicket.js +0 -444
  34. package/dist/commands/security.js +0 -156
  35. package/dist/prUrl.js +0 -28
  36. package/dist/security.js +0 -417
  37. package/dist/securityDeepScan.js +0 -235
  38. package/dist/securityDoctor.js +0 -61
  39. package/dist/securityFeature.js +0 -6
  40. package/dist/securityInstall.js +0 -232
  41. package/dist/securityInventory.js +0 -566
  42. package/dist/securityPilot.js +0 -59
  43. package/dist/securityPolicy.js +0 -181
  44. package/dist/securitySession.js +0 -72
@@ -0,0 +1,348 @@
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.parseArgs = parseArgs;
37
+ exports.scoreValue = scoreValue;
38
+ exports.runScore = runScore;
39
+ exports.runScores = runScores;
40
+ exports.runQueue = runQueue;
41
+ exports.runJudge = runJudge;
42
+ exports.runImport = runImport;
43
+ exports.runAddExample = runAddExample;
44
+ exports.runVersions = runVersions;
45
+ exports.runSaveVersion = runSaveVersion;
46
+ exports.runOverview = runOverview;
47
+ exports.runRuns = runRuns;
48
+ exports.runRun = runRun;
49
+ exports.runScoreKinds = runScoreKinds;
50
+ exports.runQueueCreate = runQueueCreate;
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ const shared_1 = require("./shared");
54
+ const BOOL_FLAGS = new Set(["--failed", "--on", "--off", "--json"]);
55
+ function parseArgs(args) {
56
+ const out = { positional: [], flags: {}, bools: new Set(), runs: [] };
57
+ for (let i = 0; i < args.length; i++) {
58
+ const a = args[i];
59
+ if (BOOL_FLAGS.has(a)) {
60
+ out.bools.add(a);
61
+ continue;
62
+ }
63
+ if (a.startsWith("--")) {
64
+ const eq = a.indexOf("=");
65
+ const name = eq > 0 ? a.slice(0, eq) : a;
66
+ const value = eq > 0 ? a.slice(eq + 1) : args[++i];
67
+ if (value === undefined)
68
+ throw new Error(`${name} needs a value`);
69
+ if (name === "--run")
70
+ out.runs.push(value);
71
+ else
72
+ out.flags[name] = value;
73
+ continue;
74
+ }
75
+ out.positional.push(a);
76
+ }
77
+ return out;
78
+ }
79
+ function scoreValue(raw) {
80
+ const t = raw.trim();
81
+ if (/^(true|false)$/i.test(t))
82
+ return t.toLowerCase() === "true";
83
+ if (t !== "" && Number.isFinite(Number(t)))
84
+ return Number(t);
85
+ return t;
86
+ }
87
+ async function call(config, tool, method, route, opts) {
88
+ const start = Date.now();
89
+ try {
90
+ const res = await (0, shared_1.apiRequest)(method, `/api/cli/traces/${route}`, { config, ...opts });
91
+ (0, shared_1.recordAgentEvent)(config, { tool, ok: true, latencyMs: Date.now() - start });
92
+ return res;
93
+ }
94
+ catch (err) {
95
+ const e = err;
96
+ (0, shared_1.recordAgentEvent)(config, { tool, ok: false, latencyMs: Date.now() - start, error: e.message });
97
+ console.error(e.message);
98
+ process.exit(1);
99
+ }
100
+ }
101
+ function usage(text) {
102
+ console.error(`Usage: ${text}`);
103
+ process.exit(1);
104
+ }
105
+ async function runScore(args, config) {
106
+ const p = parseArgs(args);
107
+ const [run, name, value] = p.positional;
108
+ if (!run || !name || value === undefined)
109
+ usage("codiedev traces score <run> <score> <value> [--agent name] [--comment text] [--step n]");
110
+ const res = await call(config, "codiedev_traces_score", "POST", "score", {
111
+ body: { run, name, value: scoreValue(value), agent: p.flags["--agent"], comment: p.flags["--comment"], ...(p.flags["--step"] ? { step: Number(p.flags["--step"]) } : {}) },
112
+ });
113
+ console.log(`✓ Scored ${res.runId}: ${name} = ${value}`);
114
+ }
115
+ async function runScores(args, config) {
116
+ const p = parseArgs(args);
117
+ const agent = p.positional[0];
118
+ if (!agent)
119
+ usage("codiedev traces scores <agent> [--days n] [--json]");
120
+ const res = await call(config, "codiedev_traces_scores", "GET", "scores", { query: { agent, days: p.flags["--days"] ?? "7" } });
121
+ if (p.bools.has("--json")) {
122
+ process.stdout.write(JSON.stringify(res, null, 2) + "\n");
123
+ return;
124
+ }
125
+ if (!res.summary.length)
126
+ console.log(`No scores on ${res.agent} in the last ${p.flags["--days"] ?? 7} days.`);
127
+ for (const s of res.summary) {
128
+ const head = s.dataType === "boolean" && s.average !== null ? `${Math.round(s.average * 100)}% true`
129
+ : s.dataType === "numeric" && s.average !== null ? `avg ${Math.round(s.average * 100) / 100}`
130
+ : s.categories.map((c) => `${c.label} ${c.count}`).join(", ");
131
+ const from = [s.bySource.annotation ? `${s.bySource.annotation} people` : "", s.bySource.api ? `${s.bySource.api} your app` : "", s.bySource.judge ? `${s.bySource.judge} judge` : ""].filter(Boolean).join(", ");
132
+ console.log(`${s.name.padEnd(24)} ${head.padEnd(28)} ${s.count} scores (${from})`);
133
+ }
134
+ if (res.kinds.length)
135
+ console.log(`\nScore kinds: ${res.kinds.map((k) => `${k.name} (${k.dataType === "numeric" ? `${k.min ?? ""}–${k.max ?? ""}` : k.dataType === "boolean" ? "true/false" : k.categories.join("/")})`).join(", ")}`);
136
+ }
137
+ async function runQueue(args, config) {
138
+ const [verb, ...rest] = args;
139
+ if (verb === "list" || verb === undefined) {
140
+ const res = await call(config, "codiedev_traces_queue_list", "GET", "queues", {});
141
+ const live = res.queues.filter((q) => !q.archived);
142
+ if (!live.length)
143
+ console.log("No review queues yet. Make one in Codiedev → Traces → Review.");
144
+ for (const q of live)
145
+ console.log(`${q.name.padEnd(28)} ${String(q.pending).padStart(4)} to review ${String(q.done).padStart(4)} done ${q.scoreNames.join(", ")}`);
146
+ return;
147
+ }
148
+ if (verb === "create")
149
+ return runQueueCreate(rest, config);
150
+ if (verb !== "add")
151
+ usage("codiedev traces queue list | queue create <name> [--scores a,b] | queue add <queue> --agent <name> [--failed] [--days n] [--run id ...]");
152
+ const p = parseArgs(rest);
153
+ const queue = p.positional[0];
154
+ if (!queue || (!p.flags["--agent"] && !p.runs.length))
155
+ usage("codiedev traces queue add <queue> --agent <name> [--failed] [--days n] [--run id ...]");
156
+ const res = await call(config, "codiedev_traces_queue_add", "POST", "queue", {
157
+ body: { queue, agent: p.flags["--agent"], failed: p.bools.has("--failed"), ...(p.flags["--days"] ? { days: Number(p.flags["--days"]) } : {}), ...(p.runs.length ? { runs: p.runs } : {}) },
158
+ });
159
+ console.log(`✓ Added ${res.added} ${res.added === 1 ? "run" : "runs"} to ${res.queue}${res.skipped ? ` (${res.skipped} already there or not yours)` : ""}. Review them in Codiedev → Traces → Review.`);
160
+ }
161
+ function printJudge(agent, judge) {
162
+ if (!judge || judge === "none") {
163
+ console.log(`Automatic scoring isn't set up for ${agent}.`);
164
+ return;
165
+ }
166
+ console.log(`${agent}: automatic scoring ${judge.enabled ? "on" : "off"}`);
167
+ console.log(` scores ${judge.scoreNames.join(", ")} · ${Math.round(judge.sampleRate * 100)}% of runs, up to ${judge.dailyMaxRuns}/day · ${judge.model}`);
168
+ if (judge.judgeKey)
169
+ console.log(` billed to ${judge.judgeKey.name}${judge.judgeKey.monthlyBudgetUsd !== null ? ` ($${judge.judgeKey.monthlyBudgetUsd}/mo)` : ""} · ${judge.judgedToday} judged in 24h${judge.errorsToday ? `, ${judge.errorsToday} failed` : ""}`);
170
+ if (judge.lastError)
171
+ console.log(` last problem: ${judge.lastError}`);
172
+ }
173
+ async function runJudge(args, config) {
174
+ const p = parseArgs(args);
175
+ const agent = p.positional[0];
176
+ const help = "codiedev traces judge <agent> [--on | --off] [--scores a,b] [--instructions text] [--model id] [--sample percent] [--daily n] [--budget usd | --key cdvm_…]";
177
+ if (!agent)
178
+ usage(help);
179
+ const changing = p.bools.has("--on") || p.bools.has("--off") || Object.keys(p.flags).length > 0;
180
+ if (!changing) {
181
+ const res = await call(config, "codiedev_traces_judge", "GET", "judge", { query: { agent } });
182
+ printJudge(res.agent, res.judge);
183
+ return;
184
+ }
185
+ const res = await call(config, "codiedev_traces_judge_set", "POST", "judge", {
186
+ body: {
187
+ agent,
188
+ ...(p.bools.has("--on") ? { enabled: true } : p.bools.has("--off") ? { enabled: false } : {}),
189
+ ...(p.flags["--scores"] ? { scores: p.flags["--scores"].split(",").map((s) => s.trim()).filter(Boolean) } : {}),
190
+ ...(p.flags["--instructions"] ? { instructions: p.flags["--instructions"] } : {}),
191
+ ...(p.flags["--model"] ? { model: p.flags["--model"] } : {}),
192
+ ...(p.flags["--sample"] ? { sampleRate: Number(p.flags["--sample"]) / 100 } : {}),
193
+ ...(p.flags["--daily"] ? { dailyMaxRuns: Number(p.flags["--daily"]) } : {}),
194
+ ...(p.flags["--budget"] ? { newKeyBudgetUsd: Number(p.flags["--budget"]) } : {}),
195
+ ...(p.flags["--key"] ? { pastedKey: p.flags["--key"] } : {}),
196
+ },
197
+ });
198
+ printJudge(res.agent, res.judge);
199
+ }
200
+ async function runImport(args, config) {
201
+ const p = parseArgs(args);
202
+ const [agent, file] = p.positional;
203
+ const dataset = p.flags["--dataset"];
204
+ if (!agent || !file || !dataset)
205
+ usage("codiedev traces import <agent> <file.csv|file.jsonl> --dataset <name>");
206
+ let text;
207
+ try {
208
+ text = fs.readFileSync(path.resolve(process.cwd(), file), "utf8");
209
+ }
210
+ catch (err) {
211
+ console.error(`Couldn't read ${file}: ${err.message}`);
212
+ process.exit(1);
213
+ }
214
+ const res = await call(config, "codiedev_traces_import", "POST", "examples", { body: { agent, dataset, text } });
215
+ console.log(`✓ Imported ${res.added} ${res.added === 1 ? "example" : "examples"} into ${dataset} for ${agent}.`);
216
+ for (const e of res.errors.slice(0, 10))
217
+ console.log(` skipped${e.line ? ` line ${e.line}` : ""}: ${e.error}`);
218
+ }
219
+ async function runAddExample(args, config) {
220
+ const p = parseArgs(args);
221
+ const agent = p.positional[0];
222
+ const dataset = p.flags["--dataset"];
223
+ const input = p.flags["--input"];
224
+ if (!agent || !dataset || !input)
225
+ usage("codiedev traces add-example <agent> --dataset <name> --input <text> [--expected <text>] [--name <text>]");
226
+ await call(config, "codiedev_traces_add_example", "POST", "examples", { body: { agent, dataset, input, expected: p.flags["--expected"], name: p.flags["--name"] } });
227
+ console.log(`✓ Added an example to ${dataset} for ${agent}.`);
228
+ }
229
+ async function runVersions(args, config) {
230
+ const dataset = parseArgs(args).positional[0];
231
+ if (!dataset)
232
+ usage("codiedev traces versions <dataset>");
233
+ const res = await call(config, "codiedev_traces_versions", "GET", "versions", { query: { dataset } });
234
+ if (!res.versions.length)
235
+ console.log(`${dataset} has no saved versions. Save one with: codiedev traces save-version "${dataset}"`);
236
+ for (const v of res.versions)
237
+ console.log(`v${v.version} ${String(v.cases).padStart(4)} cases ${new Date(v.createdAt).toISOString().slice(0, 10)} +${v.added} −${v.removed} ${v.changed} edited${v.note ? ` ${v.note}` : ""}`);
238
+ if (res.unsaved)
239
+ console.log(`Unsaved since v${res.versions[0].version}: +${res.unsaved.added} −${res.unsaved.removed} ${res.unsaved.changed} edited`);
240
+ }
241
+ async function runSaveVersion(args, config) {
242
+ const p = parseArgs(args);
243
+ const dataset = p.positional[0];
244
+ if (!dataset)
245
+ usage("codiedev traces save-version <dataset> [--note text]");
246
+ const res = await call(config, "codiedev_traces_save_version", "POST", "versions", { body: { dataset, note: p.flags["--note"] } });
247
+ console.log(`✓ Saved ${dataset} as v${res.version} (${res.cases} cases). Run it later with --dataset "${dataset}" --version ${res.version}.`);
248
+ }
249
+ const usd = (n) => (n === 0 ? "$0" : n < 0.01 ? "<$0.01" : `$${n.toFixed(2)}`);
250
+ const json = (p, value) => { if (p.bools.has("--json")) {
251
+ process.stdout.write(JSON.stringify(value, null, 2) + "\n");
252
+ return true;
253
+ } return false; };
254
+ async function runOverview(args, config) {
255
+ const p = parseArgs(args);
256
+ const res = await call(config, "codiedev_traces_overview", "GET", "overview", { query: { days: p.flags["--days"] ?? "7" } });
257
+ if (json(p, res))
258
+ return;
259
+ if (!res.agents.length) {
260
+ console.log("No agents you can see yet. Connect one in Codiedev → Traces.");
261
+ return;
262
+ }
263
+ console.log(`Agents, last ${res.range}:`);
264
+ for (const a of res.agents)
265
+ console.log(` ${a.name.padEnd(28)} ${String(a.runs).padStart(6)} runs ${String(a.failedRuns).padStart(5)} failed ${usd(a.spend7dUsd).padStart(9)} 7d spend ${a.keepsPromptsDays ? `prompts ${a.keepsPromptsDays}d` : "metadata only"}${a.spike ? " spend spike" : ""}${a.budgetBlock ? " budget block" : ""}`);
266
+ if (res.issues.length) {
267
+ console.log("\nWhat's going wrong:");
268
+ for (const i of res.issues)
269
+ console.log(` ${i.label.padEnd(18)} ${String(i.runs).padStart(5)} runs ${usd(i.wastedUsd).padStart(9)} wasted ${i.agents.join(", ")}${i.exampleRun ? ` e.g. ${i.exampleRun}` : ""}`);
270
+ }
271
+ }
272
+ async function runRuns(args, config) {
273
+ const p = parseArgs(args);
274
+ const agent = p.positional[0];
275
+ if (!agent)
276
+ usage("codiedev traces runs <agent> [--failed] [--flag errors|truncated|tool_loop|context_overflow|budget_block] [--model id] [--verdict pass|fail] [--days n] [--limit n] [--json]");
277
+ const res = await call(config, "codiedev_traces_runs", "GET", "runs", {
278
+ query: { agent, days: p.flags["--days"] ?? "7", ...(p.bools.has("--failed") ? { failed: "1" } : {}), ...(p.flags["--flag"] ? { flag: p.flags["--flag"] } : {}), ...(p.flags["--model"] ? { model: p.flags["--model"] } : {}), ...(p.flags["--verdict"] ? { verdict: p.flags["--verdict"] } : {}), limit: p.flags["--limit"] ?? "50" },
279
+ });
280
+ if (json(p, res))
281
+ return;
282
+ console.log(`${res.total} ${res.total === 1 ? "run" : "runs"} for ${res.agent}, last ${res.range}${res.total > res.runs.length ? ` (newest ${res.runs.length})` : ""}:`);
283
+ for (const r of res.runs)
284
+ console.log(` ${r.startedAt.slice(0, 16).replace("T", " ")} ${r.status === "failed" ? "FAIL" : " ok "} ${r.runId.padEnd(24)} ${String(r.steps).padStart(3)} calls ${usd(r.costUsd).padStart(8)} ${r.model ?? ""}${r.flags.length ? ` [${r.flags.join(", ")}]` : ""}${r.verdict ? ` marked ${r.verdict}` : ""}`);
285
+ if (res.runs.length)
286
+ console.log(`\nOpen one: codiedev traces run ${res.runs[0].runId} --agent "${res.agent}"`);
287
+ }
288
+ async function runRun(args, config) {
289
+ const p = parseArgs(args);
290
+ const run = p.positional[0];
291
+ if (!run)
292
+ usage("codiedev traces run <run> [--agent name] [--json]");
293
+ const res = await call(config, "codiedev_traces_run", "GET", "run", { query: { run, ...(p.flags["--agent"] ? { agent: p.flags["--agent"] } : {}) } });
294
+ if (json(p, res))
295
+ return;
296
+ const r = res.run;
297
+ console.log(`${r.title} · ${r.id}`);
298
+ console.log(`${new Date(r.startedAt).toISOString().slice(0, 16).replace("T", " ")} · ${r.status === "failed" ? "FAILED" : "ok"} · ${Math.round(r.durationMs / 100) / 10}s · ${usd(r.costUsd)}${r.flags.length ? ` · ${r.flags.join(", ")}` : ""}`);
299
+ if (r.diagnosis)
300
+ console.log(`\nWhat went wrong: ${r.diagnosis.title}\n ${r.diagnosis.why}\n\nFix (for your coding agent):\n${r.diagnosis.fix.split("\n").map((l) => ` ${l}`).join("\n")}`);
301
+ if (r.annotation)
302
+ console.log(`\nMarked ${r.annotation.verdict} by ${r.annotation.by}${r.annotation.reason ? `: ${r.annotation.reason}` : ""}`);
303
+ if (res.scores.length)
304
+ console.log(`\nScores: ${res.scores.map((s) => `${s.name} ${s.text}${s.step ? ` (step ${s.step})` : ""} by ${s.by ?? s.source}${s.comment ? ` "${s.comment}"` : ""}`).join("; ")}`);
305
+ console.log("\nSteps:");
306
+ for (const s of r.spans.filter((x) => x.kind !== "run")) {
307
+ console.log(` ${s.kind === "tool" ? "tool" : "call"} ${s.name} ${Math.round(s.durationMs)}ms${s.costUsd !== undefined ? ` ${usd(s.costUsd)}` : ""}${s.finishReason ? ` finish: ${s.finishReason}` : ""}${s.statusCode && s.statusCode >= 400 ? ` HTTP ${s.statusCode}` : ""}${s.flag ? ` [${s.flag}]` : ""}${s.note ? ` ${s.note}` : ""}`);
308
+ if (s.input)
309
+ console.log(` prompt: ${s.input.replace(/\s+/g, " ").slice(0, 300)}`);
310
+ if (s.output)
311
+ console.log(` reply: ${s.output.replace(/\s+/g, " ").slice(0, 300)}`);
312
+ }
313
+ if (!r.bodiesVisible)
314
+ console.log("\n(Prompts and replies are shown only to the agent's maintainers.)");
315
+ }
316
+ async function runScoreKinds(args, config) {
317
+ const [verb, ...rest] = args;
318
+ if (verb === "add") {
319
+ const p = parseArgs(rest);
320
+ const name = p.positional[0];
321
+ const type = p.flags["--type"];
322
+ if (!name || !type)
323
+ usage("codiedev traces score-kinds add <name> --type number|categories|boolean [--min n --max n] [--categories a,b,c] [--description text]");
324
+ const dataType = type === "number" || type === "numeric" ? "numeric" : type === "categories" || type === "categorical" ? "categorical" : type === "boolean" || type === "bool" ? "boolean" : type;
325
+ await call(config, "codiedev_traces_score_kind_add", "POST", "score-kinds", {
326
+ body: { name, type: dataType, ...(p.flags["--min"] ? { min: Number(p.flags["--min"]) } : {}), ...(p.flags["--max"] ? { max: Number(p.flags["--max"]) } : {}), ...(p.flags["--categories"] ? { categories: p.flags["--categories"].split(",").map((c) => c.trim()) } : {}), ...(p.flags["--description"] ? { description: p.flags["--description"] } : {}) },
327
+ });
328
+ console.log(`✓ Added score kind ${name}.`);
329
+ return;
330
+ }
331
+ const p = parseArgs(verb === undefined || verb === "list" ? rest : args);
332
+ const res = await call(config, "codiedev_traces_score_kinds", "GET", "score-kinds", {});
333
+ if (json(p, res))
334
+ return;
335
+ const live = res.kinds.filter((k) => !k.archived);
336
+ if (!live.length)
337
+ console.log("No score kinds yet. Add one: codiedev traces score-kinds add helpfulness --type number --min 1 --max 5");
338
+ for (const k of live)
339
+ console.log(` ${k.name.padEnd(24)} ${k.dataType === "numeric" ? `number ${k.min ?? ""}–${k.max ?? ""}` : k.dataType === "boolean" ? "true / false" : k.categories.join(" / ")}${k.description ? ` ${k.description}` : ""}`);
340
+ }
341
+ async function runQueueCreate(args, config) {
342
+ const p = parseArgs(args);
343
+ const name = p.positional[0];
344
+ if (!name)
345
+ usage("codiedev traces queue create <name> [--scores a,b] [--description text]");
346
+ await call(config, "codiedev_traces_queue_create", "POST", "queues", { body: { name, scores: (p.flags["--scores"] ?? "").split(",").map((s) => s.trim()).filter(Boolean), ...(p.flags["--description"] ? { description: p.flags["--description"] } : {}) } });
347
+ console.log(`✓ Created review queue ${name}. Add runs: codiedev traces queue add "${name}" --agent <name> --failed`);
348
+ }
package/dist/connect.js CHANGED
@@ -39,16 +39,12 @@ 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
42
  const path = __importStar(require("path"));
44
43
  const utils_1 = require("./utils");
45
44
  const connectFlow_1 = require("./connectFlow");
46
45
  const version_1 = require("./version");
47
46
  const upgradeNudge_1 = require("./upgradeNudge");
48
47
  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
48
  const harnessDirs_1 = require("./harnessDirs");
53
49
  const BACKEND_URL = process.env.CODIEDEV_URL || "https://cli.codiedev.com";
54
50
  function promptHidden(question) {
@@ -178,7 +174,6 @@ async function runConnect(args = []) {
178
174
  }
179
175
  const companyId = responseData.companyId;
180
176
  const companyName = responseData.companyName;
181
- const agentSecurityEnabled = responseData.agentSecurityEnabled === true;
182
177
  const repos = responseData.repos ?? [];
183
178
  if (!companyId || !companyName) {
184
179
  console.error("\nError: Invalid response from server. Token may be invalid.");
@@ -191,7 +186,6 @@ async function runConnect(args = []) {
191
186
  repos,
192
187
  lastSynced: new Date().toISOString(),
193
188
  backendUrl: BACKEND_URL,
194
- agentSecurityEnabled,
195
189
  deviceId: saved?.deviceId || crypto.randomUUID(),
196
190
  deviceName: saved?.deviceName || os.hostname(),
197
191
  captureIgnoredPaths: saved?.captureIgnoredPaths ?? [],
@@ -233,23 +227,15 @@ async function runConnect(args = []) {
233
227
  const hasCursor = (0, utils_1.cursorInstalled)();
234
228
  const hasOpenCode = (0, utils_1.openCodeInstalled)();
235
229
  const hasCopilot = (0, utils_1.copilotInstalled)();
230
+ const hasPi = (0, utils_1.piInstalled)();
236
231
  (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "claude-code", ok: hasClaude });
237
232
  (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "codex", ok: hasCodex });
238
233
  (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "cursor", ok: hasCursor });
239
234
  (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "opencode", ok: hasOpenCode });
240
235
  (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "copilot", ok: hasCopilot });
236
+ (0, shared_1.recordInstallEvent)(config, { step: "detect", target: "pi", ok: hasPi });
241
237
  const installed = [];
242
238
  const installedTargets = [];
243
- const home = os.homedir();
244
- const securityConfigPaths = [
245
- path.join((0, harnessDirs_1.claudeConfigDir)(), "settings.json"),
246
- path.join((0, harnessDirs_1.codexHome)(), "hooks.json"),
247
- path.join(home, ".cursor", "hooks.json"),
248
- path.join((0, harnessDirs_1.openCodeConfigDir)(), "plugins", "codiedev.js"),
249
- path.join((0, harnessDirs_1.codexHome)(), "config.toml"),
250
- (0, utils_1.copilotHooksPath)(),
251
- ];
252
- const securitySnapshot = (0, securityInstall_1.createSecurityInstallSnapshot)(securityConfigPaths);
253
239
  const runInstall = (target, fn, label, targetKey) => {
254
240
  try {
255
241
  fn();
@@ -269,50 +255,26 @@ async function runConnect(args = []) {
269
255
  }
270
256
  };
271
257
  if (hasClaude) {
272
- runInstall("claude-code-hook", () => (0, utils_1.installHook)(agentSecurityEnabled), `Claude Code SessionEnd (capture) + UserPromptSubmit (skill discovery) + Stop (auto-backup) hooks (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.claudeConfigDir)(), "settings.json"))})`, "claudeCode-hook");
258
+ runInstall("claude-code-hook", utils_1.installHook, `Claude Code SessionEnd (capture) + UserPromptSubmit (skill discovery) + Stop (auto-backup) hooks (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.claudeConfigDir)(), "settings.json"))})`, "claudeCode-hook");
273
259
  runInstall("claude-code-instructions", utils_1.installClaudeCodeInstructions, `Claude Code agent instructions (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.claudeConfigDir)(), "CLAUDE.md"))})`, "claudeCode-instructions");
274
260
  }
275
261
  if (hasCodex) {
276
- runInstall("codex-hook", () => (0, utils_1.installCodexHook)(agentSecurityEnabled), `Codex Stop (capture + auto-backup) hooks (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.codexHome)(), "hooks.json"))})`, "codex-hook");
262
+ runInstall("codex-hook", utils_1.installCodexHook, `Codex Stop (capture + auto-backup) hooks (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.codexHome)(), "hooks.json"))})`, "codex-hook");
277
263
  runInstall("codex-instructions", utils_1.installCodexInstructions, `Codex agent instructions (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.codexHome)(), "AGENTS.md"))})`, "codex-instructions");
278
264
  }
279
265
  if (hasCursor) {
280
- runInstall("cursor-hook", () => (0, utils_1.installCursorHook)(agentSecurityEnabled), "Cursor sessionStart + prompt security + stop backup + sessionEnd capture hooks (~/.cursor/hooks.json)", "cursor-hook");
266
+ runInstall("cursor-hook", utils_1.installCursorHook, "Cursor sessionStart + stop backup + sessionEnd capture hooks (~/.cursor/hooks.json)", "cursor-hook");
281
267
  runInstall("cursor-instructions", utils_1.installCursorInstructions, "Cursor agent instructions (~/.cursor/rules/codiedev.mdc)", "cursor-instructions");
282
268
  }
283
269
  if (hasCopilot) {
284
- runInstall("copilot-hook", () => (0, utils_1.installCopilotHook)(agentSecurityEnabled), `GitHub Copilot (VS Code + CLI) sessionStart + agentStop backup + sessionEnd capture hooks (${(0, utils_1.copilotHooksPath)()})`, "copilot-hook");
270
+ runInstall("copilot-hook", utils_1.installCopilotHook, `GitHub Copilot (VS Code + CLI) sessionStart + agentStop backup + sessionEnd capture hooks (${(0, utils_1.copilotHooksPath)()})`, "copilot-hook");
285
271
  runInstall("copilot-instructions", utils_1.installCopilotInstructions, "GitHub Copilot CLI team artifact instructions", "copilot-instructions");
286
272
  }
287
- runInstall("opencode-capture-adapter", () => (0, utils_1.installOpenCodeCapturePlugin)(agentSecurityEnabled), `OpenCode session capture adapter (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.openCodeConfigDir)(), "plugins", "codiedev.js"))})`, "opencode-capture");
288
- try {
289
- const hookScriptPath = path.join(__dirname, "hook.js");
290
- if (agentSecurityEnabled && fs.existsSync(hookScriptPath)) {
291
- const targets = [];
292
- if (installedTargets.includes("claudeCode-hook"))
293
- targets.push({ surface: "claude-code", configPath: securityConfigPaths[0] });
294
- if (installedTargets.includes("codex-hook"))
295
- targets.push({ surface: "codex", configPath: securityConfigPaths[1] });
296
- if (installedTargets.includes("cursor-hook"))
297
- targets.push({ surface: "cursor", configPath: securityConfigPaths[2] });
298
- if (installedTargets.includes("copilot-hook"))
299
- targets.push({ surface: "copilot", configPath: (0, utils_1.copilotHooksPath)() });
300
- if (installedTargets.includes("opencode-capture"))
301
- targets.push({ surface: "codie-harness", configPath: securityConfigPaths[3] });
302
- (0, securityInstall_1.writeSecurityInstallManifest)({ hookScriptPath, snapshot: securitySnapshot, targets });
303
- }
304
- }
305
- catch (err) {
306
- console.warn(`Warning: Security hooks installed, but integrity manifest could not be written — ${err.message}`);
307
- }
308
- if (agentSecurityEnabled) {
309
- try {
310
- await (0, securityPolicy_1.syncEndpointSecurityPolicy)(config);
311
- }
312
- catch (err) {
313
- console.warn(`Warning: Agent-security policy will use safe defaults until sync succeeds — ${err.message}`);
314
- }
273
+ runInstall("pi-extension", utils_1.installPiExtension, `pi session start + skill discovery + capture extension (${(0, harnessDirs_1.displayPath)((0, utils_1.piExtensionPath)())})`, "pi-extension");
274
+ if (hasPi) {
275
+ runInstall("pi-instructions", utils_1.installPiInstructions, `pi agent instructions (${(0, harnessDirs_1.displayPath)((0, utils_1.piInstructionsPath)())})`, "pi-instructions");
315
276
  }
277
+ runInstall("opencode-capture-adapter", utils_1.installOpenCodeCapturePlugin, `OpenCode session capture adapter (${(0, harnessDirs_1.displayPath)(path.join((0, harnessDirs_1.openCodeConfigDir)(), "plugins", "codiedev.js"))})`, "opencode-capture");
316
278
  if (installedTargets.length > 0) {
317
279
  try {
318
280
  await postJson(`${BACKEND_URL}/api/cli/markInstalled`, {
@@ -331,7 +293,7 @@ async function runConnect(args = []) {
331
293
  });
332
294
  }
333
295
  }
334
- if (!hasClaude && !hasCodex && !hasCursor && !hasOpenCode && !hasCopilot) {
296
+ if (!hasClaude && !hasCodex && !hasCursor && !hasOpenCode && !hasCopilot && !hasPi) {
335
297
  console.warn("\nNo existing AI client detected; the Codie/OpenCode adapter is ready for a later install.");
336
298
  console.warn("If you just installed Claude Code, launch it once (so ~/.claude is created),");
337
299
  console.warn("then re-run `npx codiedev connect` to wire up the capture hook.");
@@ -348,8 +310,5 @@ async function runConnect(args = []) {
348
310
  console.log();
349
311
  console.log("Run `codiedev doctor` to verify everything's wired up.");
350
312
  console.log("If `codiedev` is not on PATH, run `npx codiedev@latest doctor` instead.");
351
- if ((0, securityFeature_1.isAgentSecurityEnabled)(config)) {
352
- console.log("Run `codiedev security pilot` to validate blocking safely.");
353
- }
354
313
  console.log();
355
314
  }
@@ -41,7 +41,6 @@ exports.parseCopilotWorkspace = parseCopilotWorkspace;
41
41
  exports.readCopilotWorkspace = readCopilotWorkspace;
42
42
  exports.copilotLaunch = copilotLaunch;
43
43
  exports.normalizeCopilotHookInput = normalizeCopilotHookInput;
44
- exports.copilotPreToolBlockResponse = copilotPreToolBlockResponse;
45
44
  exports.isCopilotTranscriptEmpty = isCopilotTranscriptEmpty;
46
45
  exports.hasCopilotShutdown = hasCopilotShutdown;
47
46
  exports.normalizeCopilotTranscript = normalizeCopilotTranscript;
@@ -140,9 +139,6 @@ function copilotToolCalls(input) {
140
139
  const name = firstString(input.toolName, input.tool_name);
141
140
  return name ? [{ name, input: parse(input.toolArgs ?? input.tool_input) }] : [];
142
141
  }
143
- function copilotPreToolBlockResponse(reason) {
144
- return { permissionDecision: "deny", permissionDecisionReason: reason };
145
- }
146
142
  function isCopilotTranscriptEmpty(content) {
147
143
  return content.trim().length === 0;
148
144
  }
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeCursorHookInput = normalizeCursorHookInput;
4
4
  exports.normalizeCursorTranscript = normalizeCursorTranscript;
5
5
  exports.isCursorTranscriptEmpty = isCursorTranscriptEmpty;
6
- exports.cursorPreToolBlockResponse = cursorPreToolBlockResponse;
7
- exports.cursorPromptBlockResponse = cursorPromptBlockResponse;
8
6
  exports.cursorTranscriptHasUsage = cursorTranscriptHasUsage;
9
7
  exports.cursorObservedModel = cursorObservedModel;
10
8
  function normalizeCursorHookInput(input) {
@@ -65,19 +63,6 @@ function firstString(...values) {
65
63
  function firstNumber(...values) {
66
64
  return values.find((value) => typeof value === "number" && Number.isFinite(value));
67
65
  }
68
- function cursorPreToolBlockResponse(reason) {
69
- return {
70
- permission: "deny",
71
- user_message: reason,
72
- agent_message: reason,
73
- };
74
- }
75
- function cursorPromptBlockResponse(reason) {
76
- return {
77
- continue: false,
78
- user_message: reason,
79
- };
80
- }
81
66
  function cursorTranscriptHasUsage(content) {
82
67
  return content.split("\n").some((line) => {
83
68
  try {
@@ -37,6 +37,7 @@ exports.claudeConfigDir = claudeConfigDir;
37
37
  exports.claudeUserConfigPath = claudeUserConfigPath;
38
38
  exports.codexHome = codexHome;
39
39
  exports.openCodeConfigDir = openCodeConfigDir;
40
+ exports.piAgentDir = piAgentDir;
40
41
  exports.displayPath = displayPath;
41
42
  exports.claudeConfigDirInUse = claudeConfigDirInUse;
42
43
  exports.codexHomeInUse = codexHomeInUse;
@@ -60,6 +61,9 @@ function codexHome(env = process.env, home = os.homedir()) {
60
61
  function openCodeConfigDir(env = process.env, home = os.homedir()) {
61
62
  return path.join(override(env.XDG_CONFIG_HOME) ?? path.join(home, ".config"), "opencode");
62
63
  }
64
+ function piAgentDir(env = process.env, home = os.homedir()) {
65
+ return override(env.PI_CODING_AGENT_DIR) ?? path.join(home, ".pi", "agent");
66
+ }
63
67
  function displayPath(p, home = os.homedir()) {
64
68
  return p === home || p.startsWith(home + path.sep) ? "~" + p.slice(home.length) : p;
65
69
  }