codiedev 0.10.0-beta.4 → 0.10.0-beta.6
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 +11 -5
- package/assets/tui-brand-plugin.tsx +14 -2
- package/dist/backup/cache.js +1 -5
- package/dist/backup/match.js +0 -6
- package/dist/backup/run.js +3 -35
- package/dist/captureExclusions.js +0 -12
- package/dist/captureLog.js +0 -28
- package/dist/captureReadiness.js +0 -58
- package/dist/captureSignals.js +68 -3
- package/dist/cli.js +75 -64
- package/dist/codexHookTrust.js +125 -6
- package/dist/codexLimitScan.js +2 -109
- package/dist/codie.js +50 -114
- package/dist/codieBrandInstall.js +0 -18
- package/dist/codieLauncher.js +20 -92
- package/dist/codieRuntime.js +19 -23
- package/dist/codieRuntimeInstall.js +108 -23
- package/dist/codieUsage.js +38 -41
- package/dist/commands/agentTemplates.generated.js +136 -0
- package/dist/commands/agents.js +1066 -0
- package/dist/commands/agentsSdk.generated.js +7 -0
- package/dist/commands/ask.js +0 -3
- package/dist/commands/capture.js +0 -2
- package/dist/commands/createTicket.js +0 -10
- package/dist/commands/doctor.js +53 -120
- package/dist/commands/evals.js +187 -0
- package/dist/commands/inbox.js +0 -2
- package/dist/commands/library.js +0 -3
- package/dist/commands/pack.js +573 -0
- package/dist/commands/ping.js +0 -2
- package/dist/commands/pull.js +6 -10
- package/dist/commands/push.js +2 -12
- package/dist/commands/search.js +0 -4
- package/dist/commands/send.js +0 -5
- package/dist/commands/share.js +0 -4
- package/dist/commands/shared.js +0 -35
- package/dist/commands/traces.js +344 -0
- package/dist/commands/tracesLabel.js +348 -0
- package/dist/configDir.js +0 -10
- package/dist/connect.js +19 -116
- package/dist/connectFlow.js +0 -9
- package/dist/copilotHooks.js +391 -0
- package/dist/copilotInstallation.js +64 -0
- package/dist/cursorHooks.js +38 -30
- package/dist/cursorLifecycle.js +109 -0
- package/dist/detection.js +0 -30
- package/dist/harnessDirs.js +77 -0
- package/dist/hook.js +182 -469
- package/dist/inboxFormat.js +0 -24
- package/dist/launchContext.js +150 -0
- package/dist/launcher.js +140 -0
- package/dist/limitEvent.js +41 -35
- package/dist/limitEventReporter.js +1 -1
- package/dist/managedPi.js +240 -0
- package/dist/mcp.js +3 -384
- package/dist/nativeSteering.js +24 -0
- package/dist/packs/codie.js +182 -0
- package/dist/packs/harnesses.js +411 -0
- package/dist/packs/hookGate.js +256 -0
- package/dist/packs/install.js +286 -0
- package/dist/packs/manifest.js +126 -0
- package/dist/packs/paths.js +81 -0
- package/dist/packs/shim.js +214 -0
- package/dist/packs/store.js +155 -0
- package/dist/packs/sync.js +170 -0
- package/dist/piHooks.js +216 -0
- package/dist/piRuntime.js +120 -0
- package/dist/repoResolver.js +0 -19
- package/dist/secret.js +0 -3
- package/dist/selfUpdate.js +376 -0
- package/dist/skillMarker.js +23 -0
- package/dist/subagents.js +135 -0
- package/dist/teamSkillContext.js +10 -0
- package/dist/transcriptModels.js +6 -8
- package/dist/upgradeNudge.js +0 -30
- package/dist/utils.js +494 -824
- package/dist/version.js +0 -10
- package/dist/versionCheck.js +0 -33
- package/package.json +8 -9
- package/dist/backup/cache.d.ts +0 -14
- package/dist/backup/match.d.ts +0 -2
- package/dist/backup/run.d.ts +0 -25
- package/dist/captureExclusions.d.ts +0 -30
- package/dist/captureLog.d.ts +0 -20
- package/dist/captureReadiness.d.ts +0 -65
- package/dist/captureSignals.d.ts +0 -19
- package/dist/cli.d.ts +0 -16
- package/dist/codexHookTrust.d.ts +0 -34
- package/dist/codexLimitScan.d.ts +0 -64
- package/dist/codie.d.ts +0 -2
- package/dist/codieBrandInstall.d.ts +0 -11
- package/dist/codieLauncher.d.ts +0 -86
- package/dist/codieRuntime.d.ts +0 -29
- package/dist/codieRuntimeInstall.d.ts +0 -28
- package/dist/codieStartup.d.ts +0 -26
- package/dist/codieStartup.js +0 -30
- package/dist/codieUsage.d.ts +0 -57
- package/dist/commands/ask.d.ts +0 -1
- package/dist/commands/capture.d.ts +0 -14
- package/dist/commands/createTicket.d.ts +0 -27
- package/dist/commands/delete.d.ts +0 -1
- package/dist/commands/doctor.d.ts +0 -1
- package/dist/commands/inbox.d.ts +0 -3
- package/dist/commands/library.d.ts +0 -2
- package/dist/commands/note.d.ts +0 -1
- package/dist/commands/ping.d.ts +0 -1
- package/dist/commands/promote.d.ts +0 -1
- package/dist/commands/promote.js +0 -53
- package/dist/commands/pull.d.ts +0 -2
- package/dist/commands/push.d.ts +0 -33
- package/dist/commands/react.d.ts +0 -2
- package/dist/commands/react.js +0 -40
- package/dist/commands/reverseTicket.d.ts +0 -2
- package/dist/commands/reverseTicket.js +0 -477
- package/dist/commands/search.d.ts +0 -2
- package/dist/commands/security.d.ts +0 -1
- package/dist/commands/security.js +0 -156
- package/dist/commands/send.d.ts +0 -2
- package/dist/commands/share.d.ts +0 -2
- package/dist/commands/shared.d.ts +0 -64
- package/dist/configDir.d.ts +0 -1
- package/dist/connect.d.ts +0 -1
- package/dist/connectFlow.d.ts +0 -13
- package/dist/cursorHooks.d.ts +0 -23
- package/dist/detection.d.ts +0 -30
- package/dist/hook.d.ts +0 -6
- package/dist/inboxFormat.d.ts +0 -38
- package/dist/limitEvent.d.ts +0 -16
- package/dist/limitEventReporter.d.ts +0 -21
- package/dist/mcp.d.ts +0 -12
- package/dist/prUrl.d.ts +0 -9
- package/dist/prUrl.js +0 -33
- package/dist/repoResolver.d.ts +0 -17
- package/dist/secret.d.ts +0 -1
- package/dist/security.d.ts +0 -102
- package/dist/security.js +0 -437
- 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 -63
- package/dist/securityInstall.js +0 -239
- 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 -33
- package/dist/securityPolicy.js +0 -188
- package/dist/securitySession.d.ts +0 -6
- package/dist/securitySession.js +0 -72
- package/dist/transcriptModels.d.ts +0 -18
- package/dist/upgradeNudge.d.ts +0 -25
- package/dist/utils.d.ts +0 -346
- package/dist/version.d.ts +0 -1
- package/dist/versionCheck.d.ts +0 -68
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* Codiedev CLI dispatcher.
|
|
5
|
-
*
|
|
6
|
-
* Subcommands:
|
|
7
|
-
* codiedev connect — link agent CLIs to your org
|
|
8
|
-
* codiedev push <file> — author/update a spec/review/decision/etc.
|
|
9
|
-
* codiedev pull <key> — fetch an artifact by filename key
|
|
10
|
-
* codiedev ping <user> "<msg>" — send a message (optionally --with <key>)
|
|
11
|
-
* codiedev inbox — list pings (use --unread to filter)
|
|
12
|
-
* codiedev read <ping-id> — mark read + show full message
|
|
13
|
-
* codiedev note "<text>" — capture a thought
|
|
14
|
-
* codiedev promote <artifact-id> — promote an extracted artifact to authored
|
|
15
|
-
* codiedev help — show this help
|
|
16
|
-
*/
|
|
17
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
4
|
const connect_1 = require("./connect");
|
|
19
5
|
const push_1 = require("./commands/push");
|
|
@@ -23,17 +9,19 @@ const ask_1 = require("./commands/ask");
|
|
|
23
9
|
const ping_1 = require("./commands/ping");
|
|
24
10
|
const inbox_1 = require("./commands/inbox");
|
|
25
11
|
const note_1 = require("./commands/note");
|
|
26
|
-
const promote_1 = require("./commands/promote");
|
|
27
|
-
const reverseTicket_1 = require("./commands/reverseTicket");
|
|
28
12
|
const createTicket_1 = require("./commands/createTicket");
|
|
29
13
|
const doctor_1 = require("./commands/doctor");
|
|
30
14
|
const search_1 = require("./commands/search");
|
|
31
15
|
const library_1 = require("./commands/library");
|
|
32
16
|
const share_1 = require("./commands/share");
|
|
33
17
|
const send_1 = require("./commands/send");
|
|
34
|
-
const react_1 = require("./commands/react");
|
|
35
18
|
const capture_1 = require("./commands/capture");
|
|
36
|
-
const
|
|
19
|
+
const pack_1 = require("./commands/pack");
|
|
20
|
+
const traces_1 = require("./commands/traces");
|
|
21
|
+
const agents_1 = require("./commands/agents");
|
|
22
|
+
const evals_1 = require("./commands/evals");
|
|
23
|
+
const hookGate_1 = require("./packs/hookGate");
|
|
24
|
+
const sync_1 = require("./packs/sync");
|
|
37
25
|
const version_1 = require("./version");
|
|
38
26
|
const HELP = `
|
|
39
27
|
Codiedev CLI
|
|
@@ -43,14 +31,9 @@ Codiedev CLI
|
|
|
43
31
|
someone left off across sessions and providers.
|
|
44
32
|
|
|
45
33
|
Connect:
|
|
46
|
-
codiedev connect Link Claude Code / Codex / Cursor
|
|
47
|
-
|
|
48
|
-
codiedev
|
|
49
|
-
codiedev security inventory Inventory MCPs, skills, hooks, plugins,
|
|
50
|
-
instructions, and editor extensions
|
|
51
|
-
codiedev security scan --deep Run installed open-source scanners too
|
|
52
|
-
codiedev security sync Fetch administrator policy locally
|
|
53
|
-
codiedev security rollback --yes Restore pre-update hook configuration
|
|
34
|
+
codiedev connect Link Claude Code / Codex / Cursor /
|
|
35
|
+
GitHub Copilot / pi to your org
|
|
36
|
+
codiedev doctor Verify setup and capture
|
|
54
37
|
|
|
55
38
|
Harness:
|
|
56
39
|
codie Launch the governed Codie harness.
|
|
@@ -70,14 +53,6 @@ Artifacts:
|
|
|
70
53
|
team's collective memory. Returns an
|
|
71
54
|
LLM-synthesized answer with citations
|
|
72
55
|
pointing at sessions + artifacts.
|
|
73
|
-
codiedev promote <artifact-id> Promote an auto-extracted artifact
|
|
74
|
-
to an authored one
|
|
75
|
-
codiedev reverse-ticket [<pr-url>] Generate a Jira ticket draft.
|
|
76
|
-
No URL = branch mode (uses your current
|
|
77
|
-
local git branch, no PR needed).
|
|
78
|
-
Draft lands in /portal/agentic-ticketing.
|
|
79
|
-
codiedev reverse-ticket --base <ref> Override the base ref in branch mode
|
|
80
|
-
(defaults to origin/main).
|
|
81
56
|
codiedev create-ticket [<prompt>] Forward-write a scoped ticket plan.
|
|
82
57
|
Claude investigates the codebase, asks
|
|
83
58
|
"single repo or multiple? where?", then
|
|
@@ -96,6 +71,30 @@ Messaging:
|
|
|
96
71
|
codiedev inbox [--unread] [--limit N] Show messages
|
|
97
72
|
codiedev read <ping-id> Mark read + show full message
|
|
98
73
|
|
|
74
|
+
Starter packs:
|
|
75
|
+
codiedev pack list Packs assigned to your team
|
|
76
|
+
codiedev pack install [slug] [--harness claude,codex,copilot,cursor,codie,pi]
|
|
77
|
+
[--dry-run] [--json]
|
|
78
|
+
Install a pack (or all) into every
|
|
79
|
+
detected tool
|
|
80
|
+
codiedev pack status Installed packs, up to date or not
|
|
81
|
+
|
|
82
|
+
Traces (agents on the gateway):
|
|
83
|
+
codiedev agents init | deploy | run | runs | show | secrets | webhook
|
|
84
|
+
Deploy agents and run them in fresh sandboxes
|
|
85
|
+
(codiedev agents help)
|
|
86
|
+
codiedev traces agents Agents you maintain, with saved test cases
|
|
87
|
+
codiedev traces cases <agent> [--dataset name [--version n]] [--model id]
|
|
88
|
+
Pull an agent's test cases (or one dataset)
|
|
89
|
+
into this repo for your coding agent to
|
|
90
|
+
run, optionally on another model
|
|
91
|
+
codiedev traces report <results.json> Send the results back to Traces
|
|
92
|
+
codiedev traces overview | runs | run | score | scores | score-kinds | queue | judge | import | add-example | versions | save-version
|
|
93
|
+
Agents, runs, failures, scores, review queues,
|
|
94
|
+
automatic scoring and datasets (codiedev traces help)
|
|
95
|
+
codiedev evals report <run.json> File one variant's eval scores under an experiment
|
|
96
|
+
codiedev evals last <subject> Latest experiment on a subject + its champion
|
|
97
|
+
|
|
99
98
|
Discovery:
|
|
100
99
|
codiedev search "<query>" Semantic search across the team's
|
|
101
100
|
captured sessions and artifacts
|
|
@@ -103,9 +102,6 @@ Discovery:
|
|
|
103
102
|
[--type T] [--tag X] [--limit N]
|
|
104
103
|
List artifacts in your workspace
|
|
105
104
|
|
|
106
|
-
Feed:
|
|
107
|
-
codiedev react <postId> <emoji> Toggle a reaction on a feed post
|
|
108
|
-
|
|
109
105
|
Privacy:
|
|
110
106
|
codiedev ignore <path> Never capture this folder or its children
|
|
111
107
|
codiedev unignore <path> Stop ignoring a folder
|
|
@@ -159,6 +155,10 @@ locally before any capture leaves your machine, so an offline or failed portal
|
|
|
159
155
|
status sync never weakens it.
|
|
160
156
|
`.trim();
|
|
161
157
|
const COMMAND_HELP = {
|
|
158
|
+
pack: pack_1.PACK_HELP,
|
|
159
|
+
traces: traces_1.TRACES_HELP,
|
|
160
|
+
agents: agents_1.AGENTS_HELP,
|
|
161
|
+
evals: evals_1.EVALS_HELP,
|
|
162
162
|
connect: `
|
|
163
163
|
codiedev connect — link your agent CLI to Codiedev
|
|
164
164
|
|
|
@@ -168,8 +168,11 @@ codiedev connect — link your agent CLI to Codiedev
|
|
|
168
168
|
- ~/.claude/CLAUDE.md instructions (teaches Claude the commands)
|
|
169
169
|
- ~/.codex/hooks.json hook (same, for Codex)
|
|
170
170
|
- ~/.codex/AGENTS.md instructions (same, for Codex)
|
|
171
|
-
- ~/.cursor/hooks.json hooks (session,
|
|
171
|
+
- ~/.cursor/hooks.json hooks (session, backup, capture)
|
|
172
172
|
- ~/.cursor/rules/codiedev.mdc (teaches Cursor the commands)
|
|
173
|
+
- ~/.copilot/hooks/codiedev.json (GitHub Copilot: VS Code + CLI capture)
|
|
174
|
+
- ~/.pi/agent/extensions/codiedev.ts (pi: session, prompt, capture)
|
|
175
|
+
- ~/.pi/agent/AGENTS.md (teaches pi the commands)
|
|
173
176
|
|
|
174
177
|
Re-run anytime to swap accounts or refresh the instruction block.
|
|
175
178
|
|
|
@@ -275,20 +278,6 @@ codiedev note — capture a passing thought, linked to your session
|
|
|
275
278
|
unignore: IGNORE_HELP,
|
|
276
279
|
ignored: IGNORE_HELP,
|
|
277
280
|
capture: IGNORE_HELP,
|
|
278
|
-
promote: `
|
|
279
|
-
codiedev promote — promote an auto-extracted artifact to authored
|
|
280
|
-
|
|
281
|
-
Usage:
|
|
282
|
-
codiedev promote <artifact-id> [--key filename.md]
|
|
283
|
-
|
|
284
|
-
The session-capture pipeline auto-extracts spec/bugfix/decision
|
|
285
|
-
artifacts from each agent session. Promote turns one of those into
|
|
286
|
-
a first-class authored artifact your team can ping, pull, and
|
|
287
|
-
update versions of.
|
|
288
|
-
|
|
289
|
-
Find artifact-ids in the portal under Knowledge → Memory, or via
|
|
290
|
-
the portal search.
|
|
291
|
-
`.trim(),
|
|
292
281
|
"create-ticket": `
|
|
293
282
|
codiedev create-ticket — forward-write a scoped ticket plan
|
|
294
283
|
|
|
@@ -414,8 +403,27 @@ Run 'codiedev help <command>' for each, or see the quick list:
|
|
|
414
403
|
|
|
415
404
|
Tokens are per-user. Rotate any time by revoking + creating a new one.
|
|
416
405
|
`.trim();
|
|
406
|
+
const REMOVED_COMMANDS = {
|
|
407
|
+
promote: "Share an auto-saved spec with 'Promote to team' in the portal's My artifacts list.",
|
|
408
|
+
"reverse-ticket": "Use 'codiedev create-ticket' to draft Jira tickets.",
|
|
409
|
+
reverseTicket: "Use 'codiedev create-ticket' to draft Jira tickets.",
|
|
410
|
+
react: "React to feed posts in the portal.",
|
|
411
|
+
};
|
|
412
|
+
function removedCommand(command) {
|
|
413
|
+
console.error(`'codiedev ${command}' has been removed. ${REMOVED_COMMANDS[command] ?? ""}`.trim());
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
417
416
|
async function main() {
|
|
418
417
|
const [, , command, ...rest] = process.argv;
|
|
418
|
+
if (command === "hook-gate") {
|
|
419
|
+
(0, hookGate_1.runHookGateCli)(rest);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (command && !["pack", "packs", "help", "docs", "version", "--version", "-v", "--help", "-h"].includes(command) && !rest.includes("--json")) {
|
|
423
|
+
const nag = (0, sync_1.packNagLine)();
|
|
424
|
+
if (nag)
|
|
425
|
+
console.error(`\n${nag}\n`);
|
|
426
|
+
}
|
|
419
427
|
if (!command || command === "--help" || command === "-h") {
|
|
420
428
|
console.log(HELP);
|
|
421
429
|
return;
|
|
@@ -438,7 +446,6 @@ async function main() {
|
|
|
438
446
|
console.log(DOCS);
|
|
439
447
|
return;
|
|
440
448
|
}
|
|
441
|
-
// Support `codiedev <command> --help` too.
|
|
442
449
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
443
450
|
if (COMMAND_HELP[command]) {
|
|
444
451
|
console.log(COMMAND_HELP[command]);
|
|
@@ -458,9 +465,6 @@ async function main() {
|
|
|
458
465
|
case "verify":
|
|
459
466
|
await (0, doctor_1.runDoctor)(rest);
|
|
460
467
|
return;
|
|
461
|
-
case "security":
|
|
462
|
-
await (0, security_1.runSecurityCommand)(rest);
|
|
463
|
-
return;
|
|
464
468
|
case "push":
|
|
465
469
|
await (0, push_1.runPush)(rest);
|
|
466
470
|
return;
|
|
@@ -479,7 +483,6 @@ async function main() {
|
|
|
479
483
|
return;
|
|
480
484
|
case "inbox":
|
|
481
485
|
case "check":
|
|
482
|
-
// Support `codiedev check inbox` as an alias.
|
|
483
486
|
if (command === "check" && rest[0] === "inbox") {
|
|
484
487
|
await (0, inbox_1.runInbox)(rest.slice(1));
|
|
485
488
|
}
|
|
@@ -494,11 +497,10 @@ async function main() {
|
|
|
494
497
|
await (0, note_1.runNote)(rest);
|
|
495
498
|
return;
|
|
496
499
|
case "promote":
|
|
497
|
-
await (0, promote_1.runPromote)(rest);
|
|
498
|
-
return;
|
|
499
500
|
case "reverse-ticket":
|
|
500
501
|
case "reverseTicket":
|
|
501
|
-
|
|
502
|
+
case "react":
|
|
503
|
+
removedCommand(command);
|
|
502
504
|
return;
|
|
503
505
|
case "create-ticket":
|
|
504
506
|
case "createTicket":
|
|
@@ -511,22 +513,31 @@ async function main() {
|
|
|
511
513
|
case "ls":
|
|
512
514
|
await (0, library_1.runLibrary)(rest);
|
|
513
515
|
return;
|
|
516
|
+
case "traces":
|
|
517
|
+
await (0, traces_1.runTraces)(rest);
|
|
518
|
+
return;
|
|
519
|
+
case "agents":
|
|
520
|
+
await (0, agents_1.runAgents)(rest);
|
|
521
|
+
return;
|
|
522
|
+
case "evals":
|
|
523
|
+
await (0, evals_1.runEvals)(rest);
|
|
524
|
+
return;
|
|
514
525
|
case "share":
|
|
515
526
|
await (0, share_1.runShare)(rest);
|
|
516
527
|
return;
|
|
517
528
|
case "send":
|
|
518
529
|
await (0, send_1.runSend)(rest);
|
|
519
530
|
return;
|
|
520
|
-
case "react":
|
|
521
|
-
await (0, react_1.runReact)(rest);
|
|
522
|
-
return;
|
|
523
531
|
case "ignore":
|
|
524
532
|
case "unignore":
|
|
525
533
|
case "ignored":
|
|
526
534
|
await (0, capture_1.runCaptureCommand)([command, ...rest]);
|
|
527
535
|
return;
|
|
536
|
+
case "pack":
|
|
537
|
+
case "packs":
|
|
538
|
+
await (0, pack_1.runPack)(rest);
|
|
539
|
+
return;
|
|
528
540
|
case "capture":
|
|
529
|
-
// Back-compat alias for the earlier `codiedev capture <sub>` form.
|
|
530
541
|
await (0, capture_1.runCaptureCommand)(rest);
|
|
531
542
|
return;
|
|
532
543
|
default:
|
package/dist/codexHookTrust.js
CHANGED
|
@@ -33,10 +33,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.codexPluginContentHash = codexPluginContentHash;
|
|
36
37
|
exports.codexCommandHookHash = codexCommandHookHash;
|
|
37
38
|
exports.codiedevCodexHookTrustEntries = codiedevCodexHookTrustEntries;
|
|
38
39
|
exports.writeCodexHookTrust = writeCodexHookTrust;
|
|
39
40
|
exports.inspectCodexHookTrust = inspectCodexHookTrust;
|
|
41
|
+
exports.packCodexHookTrustEntries = packCodexHookTrustEntries;
|
|
42
|
+
exports.writeCodexPackHookTrust = writeCodexPackHookTrust;
|
|
40
43
|
const crypto = __importStar(require("crypto"));
|
|
41
44
|
const fs = __importStar(require("fs"));
|
|
42
45
|
const path = __importStar(require("path"));
|
|
@@ -67,6 +70,42 @@ const MATCHER_EVENTS = new Set([
|
|
|
67
70
|
"SubagentStart",
|
|
68
71
|
"SubagentStop",
|
|
69
72
|
]);
|
|
73
|
+
function codexPluginContentHash(root) {
|
|
74
|
+
const hash = crypto.createHash("sha256");
|
|
75
|
+
hash.update("codex-plugin-bundle-v1");
|
|
76
|
+
const u64 = (n) => {
|
|
77
|
+
const b = Buffer.alloc(8);
|
|
78
|
+
b.writeBigUInt64LE(BigInt(n));
|
|
79
|
+
return b;
|
|
80
|
+
};
|
|
81
|
+
const pending = [root];
|
|
82
|
+
while (pending.length) {
|
|
83
|
+
const current = pending.pop();
|
|
84
|
+
const relative = path.relative(root, current).split(path.sep).join("/");
|
|
85
|
+
const name = path.posix.basename(relative);
|
|
86
|
+
if (name === "__pycache__" || name === ".venv" || name.endsWith(".pyc") || name.endsWith(".egg-info"))
|
|
87
|
+
continue;
|
|
88
|
+
const nameBytes = Buffer.from(relative, "utf8");
|
|
89
|
+
hash.update(u64(nameBytes.length));
|
|
90
|
+
hash.update(nameBytes);
|
|
91
|
+
const stat = fs.lstatSync(current);
|
|
92
|
+
if (stat.isDirectory()) {
|
|
93
|
+
hash.update("directory");
|
|
94
|
+
const entries = fs.readdirSync(current).sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)));
|
|
95
|
+
for (const entry of entries.reverse())
|
|
96
|
+
pending.push(path.join(current, entry));
|
|
97
|
+
}
|
|
98
|
+
else if (stat.isFile()) {
|
|
99
|
+
hash.update("file");
|
|
100
|
+
hash.update(u64(stat.size));
|
|
101
|
+
hash.update(fs.readFileSync(current));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
throw new Error(`unsupported plugin entry type: ${current}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return `sha256:${hash.digest("hex")}`;
|
|
108
|
+
}
|
|
70
109
|
function canonicalize(value) {
|
|
71
110
|
if (Array.isArray(value))
|
|
72
111
|
return value.map(canonicalize);
|
|
@@ -85,8 +124,6 @@ function normalizedTimeout(eventName, value) {
|
|
|
85
124
|
return Math.min(3, Math.max(1, configured ?? 1));
|
|
86
125
|
return Math.max(1, configured ?? 600);
|
|
87
126
|
}
|
|
88
|
-
/** Codex hashes a canonical, normalized hook identity before it will execute a
|
|
89
|
-
* user hook. Keep this compatible with codex_config::version_for_toml. */
|
|
90
127
|
function codexCommandHookHash(eventName, group, handler) {
|
|
91
128
|
const normalizedHandler = {
|
|
92
129
|
type: "command",
|
|
@@ -155,6 +192,27 @@ function codiedevCodexHookTrustEntries(hooksPath, hooksFile) {
|
|
|
155
192
|
}
|
|
156
193
|
return entries;
|
|
157
194
|
}
|
|
195
|
+
function stripBlockKeepingForeign(text, begin, end) {
|
|
196
|
+
const foreign = [];
|
|
197
|
+
const stripped = text.replace(new RegExp(`\\n?${begin}\\n([\\s\\S]*?)${end}\\n?`, "g"), (_match, body) => {
|
|
198
|
+
let table = null;
|
|
199
|
+
const flush = () => {
|
|
200
|
+
if (table && table.join("").trim())
|
|
201
|
+
foreign.push(table.join("\n").trimEnd());
|
|
202
|
+
};
|
|
203
|
+
for (const line of body.split("\n")) {
|
|
204
|
+
if (/^\s*\[/.test(line)) {
|
|
205
|
+
flush();
|
|
206
|
+
table = /^\s*\[hooks\.state\./.test(line) ? null : [];
|
|
207
|
+
}
|
|
208
|
+
if (table)
|
|
209
|
+
table.push(line);
|
|
210
|
+
}
|
|
211
|
+
flush();
|
|
212
|
+
return "\n";
|
|
213
|
+
});
|
|
214
|
+
return foreign.length ? `${stripped.trimEnd()}\n\n${foreign.join("\n\n")}\n` : stripped;
|
|
215
|
+
}
|
|
158
216
|
function tableHeader(key) {
|
|
159
217
|
return `[hooks.state.${JSON.stringify(key)}]`;
|
|
160
218
|
}
|
|
@@ -173,13 +231,10 @@ function removeTable(lines, header) {
|
|
|
173
231
|
}
|
|
174
232
|
return output;
|
|
175
233
|
}
|
|
176
|
-
/** `codiedev connect` is an explicit install action, so trust only the exact
|
|
177
|
-
* Codiedev commands it just wrote. Any later command change produces a new
|
|
178
|
-
* hash and Codex disables that hook until connect is run again. */
|
|
179
234
|
function writeCodexHookTrust(configPath, hooksPath, hooksFile) {
|
|
180
235
|
const entries = codiedevCodexHookTrustEntries(hooksPath, hooksFile);
|
|
181
236
|
let existing = fs.existsSync(configPath) ? fs.readFileSync(configPath, "utf8") : "";
|
|
182
|
-
existing = existing
|
|
237
|
+
existing = stripBlockKeepingForeign(existing, TRUST_BEGIN, TRUST_END);
|
|
183
238
|
let lines = existing.split("\n");
|
|
184
239
|
for (const entry of entries)
|
|
185
240
|
lines = removeTable(lines, tableHeader(entry.key));
|
|
@@ -226,3 +281,67 @@ function inspectCodexHookTrust(configPath, hooksPath, hooksFile, requiredSubcomm
|
|
|
226
281
|
}).length;
|
|
227
282
|
return { ok: entries.length > 0 && trusted === entries.length, total: entries.length, trusted };
|
|
228
283
|
}
|
|
284
|
+
const PACK_TRUST_BEGIN = "# codiedev-pack-trust:begin";
|
|
285
|
+
const PACK_TRUST_END = "# codiedev-pack-trust:end";
|
|
286
|
+
function packCodexHookTrustEntries(hooksPath, hooksFile, plugin) {
|
|
287
|
+
const events = hooksFile?.hooks;
|
|
288
|
+
if (!events || typeof events !== "object")
|
|
289
|
+
return [];
|
|
290
|
+
const source = plugin
|
|
291
|
+
? `${plugin.id}:${path.relative(plugin.root, hooksPath).split(path.sep).join("/")}`
|
|
292
|
+
: normalizedHooksPath(hooksPath);
|
|
293
|
+
const contentHash = plugin ? codexPluginContentHash(plugin.root) : undefined;
|
|
294
|
+
const entries = [];
|
|
295
|
+
for (const [eventName, groupsValue] of Object.entries(events)) {
|
|
296
|
+
const eventLabel = EVENT_LABELS[eventName];
|
|
297
|
+
if (!eventLabel || !Array.isArray(groupsValue))
|
|
298
|
+
continue;
|
|
299
|
+
groupsValue.forEach((groupValue, groupIndex) => {
|
|
300
|
+
const group = groupValue;
|
|
301
|
+
if (!group || !Array.isArray(group.hooks))
|
|
302
|
+
return;
|
|
303
|
+
group.hooks.forEach((handlerValue, handlerIndex) => {
|
|
304
|
+
const handler = handlerValue;
|
|
305
|
+
if (!handler || handler.type !== "command" || typeof handler.command !== "string")
|
|
306
|
+
return;
|
|
307
|
+
entries.push({
|
|
308
|
+
key: `${source}:${eventLabel}:${groupIndex}:${handlerIndex}`,
|
|
309
|
+
eventName,
|
|
310
|
+
command: handler.command,
|
|
311
|
+
currentHash: codexCommandHookHash(eventName, group, handler),
|
|
312
|
+
...(contentHash ? { contentHash } : {}),
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
return entries;
|
|
318
|
+
}
|
|
319
|
+
function writeCodexPackHookTrust(configPath, entries) {
|
|
320
|
+
let existing = fs.existsSync(configPath) ? fs.readFileSync(configPath, "utf8") : "";
|
|
321
|
+
existing = stripBlockKeepingForeign(existing, PACK_TRUST_BEGIN, PACK_TRUST_END);
|
|
322
|
+
let lines = existing.split("\n");
|
|
323
|
+
for (const entry of entries)
|
|
324
|
+
lines = removeTable(lines, tableHeader(entry.key));
|
|
325
|
+
const base = lines.join("\n").trimEnd();
|
|
326
|
+
if (entries.length === 0) {
|
|
327
|
+
const next = base ? `${base}\n` : "";
|
|
328
|
+
if (!fs.existsSync(configPath) && !next)
|
|
329
|
+
return entries;
|
|
330
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true, mode: 0o700 });
|
|
331
|
+
fs.writeFileSync(configPath, next, { encoding: "utf8", mode: 0o600 });
|
|
332
|
+
fs.chmodSync(configPath, 0o600);
|
|
333
|
+
return entries;
|
|
334
|
+
}
|
|
335
|
+
const trustBlock = entries.flatMap((entry) => [
|
|
336
|
+
tableHeader(entry.key),
|
|
337
|
+
"enabled = true",
|
|
338
|
+
`trusted_hash = ${JSON.stringify(entry.currentHash)}`,
|
|
339
|
+
...(entry.contentHash ? [`trusted_content_hash = ${JSON.stringify(entry.contentHash)}`] : []),
|
|
340
|
+
"",
|
|
341
|
+
]).join("\n");
|
|
342
|
+
const next = `${base}${base ? "\n\n" : ""}${PACK_TRUST_BEGIN}\n${trustBlock}${PACK_TRUST_END}\n`;
|
|
343
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true, mode: 0o700 });
|
|
344
|
+
fs.writeFileSync(configPath, next, { encoding: "utf8", mode: 0o600 });
|
|
345
|
+
fs.chmodSync(configPath, 0o600);
|
|
346
|
+
return entries;
|
|
347
|
+
}
|