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.
- package/README.md +4 -4
- package/dist/captureSignals.js +2 -0
- package/dist/cli.js +38 -50
- package/dist/codexHookTrust.js +67 -4
- package/dist/codie.js +23 -74
- package/dist/codieLauncher.js +18 -22
- package/dist/commands/agentTemplates.generated.js +136 -0
- package/dist/commands/agents.js +1068 -0
- package/dist/commands/agentsSdk.generated.js +7 -0
- package/dist/commands/doctor.js +12 -38
- package/dist/commands/evals.js +187 -0
- package/dist/commands/pack.js +1 -1
- package/dist/commands/traces.js +79 -15
- package/dist/commands/tracesLabel.js +348 -0
- package/dist/connect.js +11 -52
- package/dist/copilotHooks.js +0 -4
- package/dist/cursorHooks.js +0 -15
- package/dist/harnessDirs.js +4 -0
- package/dist/hook.js +33 -197
- package/dist/limitEventReporter.js +1 -1
- package/dist/managedPi.js +240 -0
- package/dist/mcp.js +0 -307
- package/dist/packs/harnesses.js +40 -3
- package/dist/packs/install.js +2 -1
- package/dist/piHooks.js +216 -0
- package/dist/piRuntime.js +120 -0
- package/dist/selfUpdate.js +47 -2
- package/dist/utils.js +232 -115
- package/package.json +5 -7
- package/dist/codieStartup.js +0 -27
- package/dist/commands/promote.js +0 -53
- package/dist/commands/react.js +0 -38
- package/dist/commands/reverseTicket.js +0 -444
- package/dist/commands/security.js +0 -156
- package/dist/prUrl.js +0 -28
- package/dist/security.js +0 -417
- package/dist/securityDeepScan.js +0 -235
- package/dist/securityDoctor.js +0 -61
- package/dist/securityFeature.js +0 -6
- package/dist/securityInstall.js +0 -232
- package/dist/securityInventory.js +0 -566
- package/dist/securityPilot.js +0 -59
- package/dist/securityPolicy.js +0 -181
- 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",
|
|
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",
|
|
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",
|
|
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",
|
|
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("
|
|
288
|
-
|
|
289
|
-
|
|
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
|
}
|
package/dist/copilotHooks.js
CHANGED
|
@@ -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
|
}
|
package/dist/cursorHooks.js
CHANGED
|
@@ -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 {
|
package/dist/harnessDirs.js
CHANGED
|
@@ -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
|
}
|