codiedev 0.10.0-beta.4 → 0.10.0-beta.5

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 (146) hide show
  1. package/README.md +7 -1
  2. package/assets/tui-brand-plugin.tsx +14 -2
  3. package/dist/backup/cache.js +1 -5
  4. package/dist/backup/match.js +0 -6
  5. package/dist/backup/run.js +3 -35
  6. package/dist/captureExclusions.js +0 -12
  7. package/dist/captureLog.js +0 -28
  8. package/dist/captureReadiness.js +0 -58
  9. package/dist/captureSignals.js +66 -3
  10. package/dist/cli.js +41 -18
  11. package/dist/codexHookTrust.js +61 -5
  12. package/dist/codexLimitScan.js +2 -109
  13. package/dist/codie.js +27 -40
  14. package/dist/codieBrandInstall.js +0 -18
  15. package/dist/codieLauncher.js +2 -70
  16. package/dist/codieRuntime.js +19 -23
  17. package/dist/codieRuntimeInstall.js +108 -23
  18. package/dist/codieStartup.js +0 -3
  19. package/dist/codieUsage.js +38 -41
  20. package/dist/commands/ask.js +0 -3
  21. package/dist/commands/capture.js +0 -2
  22. package/dist/commands/createTicket.js +0 -10
  23. package/dist/commands/doctor.js +41 -82
  24. package/dist/commands/inbox.js +0 -2
  25. package/dist/commands/library.js +0 -3
  26. package/dist/commands/pack.js +573 -0
  27. package/dist/commands/ping.js +0 -2
  28. package/dist/commands/pull.js +6 -10
  29. package/dist/commands/push.js +2 -12
  30. package/dist/commands/react.js +0 -2
  31. package/dist/commands/reverseTicket.js +0 -33
  32. package/dist/commands/search.js +0 -4
  33. package/dist/commands/send.js +0 -5
  34. package/dist/commands/share.js +0 -4
  35. package/dist/commands/shared.js +0 -35
  36. package/dist/commands/traces.js +280 -0
  37. package/dist/configDir.js +0 -10
  38. package/dist/connect.js +21 -77
  39. package/dist/connectFlow.js +0 -9
  40. package/dist/copilotHooks.js +395 -0
  41. package/dist/copilotInstallation.js +64 -0
  42. package/dist/cursorHooks.js +40 -17
  43. package/dist/cursorLifecycle.js +109 -0
  44. package/dist/detection.js +0 -30
  45. package/dist/harnessDirs.js +73 -0
  46. package/dist/hook.js +193 -316
  47. package/dist/inboxFormat.js +0 -24
  48. package/dist/launchContext.js +150 -0
  49. package/dist/launcher.js +140 -0
  50. package/dist/limitEvent.js +41 -35
  51. package/dist/limitEventReporter.js +1 -1
  52. package/dist/mcp.js +3 -77
  53. package/dist/nativeSteering.js +24 -0
  54. package/dist/packs/codie.js +182 -0
  55. package/dist/packs/harnesses.js +374 -0
  56. package/dist/packs/hookGate.js +256 -0
  57. package/dist/packs/install.js +285 -0
  58. package/dist/packs/manifest.js +126 -0
  59. package/dist/packs/paths.js +81 -0
  60. package/dist/packs/shim.js +214 -0
  61. package/dist/packs/store.js +155 -0
  62. package/dist/packs/sync.js +170 -0
  63. package/dist/prUrl.js +0 -5
  64. package/dist/repoResolver.js +0 -19
  65. package/dist/secret.js +0 -3
  66. package/dist/security.js +0 -20
  67. package/dist/securityDeepScan.js +1 -14
  68. package/dist/securityDoctor.js +0 -2
  69. package/dist/securityFeature.js +0 -1
  70. package/dist/securityInstall.js +6 -13
  71. package/dist/securityInventory.js +23 -13
  72. package/dist/securityPilot.js +0 -2
  73. package/dist/securityPolicy.js +0 -7
  74. package/dist/selfUpdate.js +331 -0
  75. package/dist/skillMarker.js +23 -0
  76. package/dist/subagents.js +135 -0
  77. package/dist/teamSkillContext.js +10 -0
  78. package/dist/transcriptModels.js +6 -8
  79. package/dist/upgradeNudge.js +0 -30
  80. package/dist/utils.js +286 -733
  81. package/dist/version.js +0 -10
  82. package/dist/versionCheck.js +0 -33
  83. package/package.json +7 -6
  84. package/dist/backup/cache.d.ts +0 -14
  85. package/dist/backup/match.d.ts +0 -2
  86. package/dist/backup/run.d.ts +0 -25
  87. package/dist/captureExclusions.d.ts +0 -30
  88. package/dist/captureLog.d.ts +0 -20
  89. package/dist/captureReadiness.d.ts +0 -65
  90. package/dist/captureSignals.d.ts +0 -19
  91. package/dist/cli.d.ts +0 -16
  92. package/dist/codexHookTrust.d.ts +0 -34
  93. package/dist/codexLimitScan.d.ts +0 -64
  94. package/dist/codie.d.ts +0 -2
  95. package/dist/codieBrandInstall.d.ts +0 -11
  96. package/dist/codieLauncher.d.ts +0 -86
  97. package/dist/codieRuntime.d.ts +0 -29
  98. package/dist/codieRuntimeInstall.d.ts +0 -28
  99. package/dist/codieStartup.d.ts +0 -26
  100. package/dist/codieUsage.d.ts +0 -57
  101. package/dist/commands/ask.d.ts +0 -1
  102. package/dist/commands/capture.d.ts +0 -14
  103. package/dist/commands/createTicket.d.ts +0 -27
  104. package/dist/commands/delete.d.ts +0 -1
  105. package/dist/commands/doctor.d.ts +0 -1
  106. package/dist/commands/inbox.d.ts +0 -3
  107. package/dist/commands/library.d.ts +0 -2
  108. package/dist/commands/note.d.ts +0 -1
  109. package/dist/commands/ping.d.ts +0 -1
  110. package/dist/commands/promote.d.ts +0 -1
  111. package/dist/commands/pull.d.ts +0 -2
  112. package/dist/commands/push.d.ts +0 -33
  113. package/dist/commands/react.d.ts +0 -2
  114. package/dist/commands/reverseTicket.d.ts +0 -2
  115. package/dist/commands/search.d.ts +0 -2
  116. package/dist/commands/security.d.ts +0 -1
  117. package/dist/commands/send.d.ts +0 -2
  118. package/dist/commands/share.d.ts +0 -2
  119. package/dist/commands/shared.d.ts +0 -64
  120. package/dist/configDir.d.ts +0 -1
  121. package/dist/connect.d.ts +0 -1
  122. package/dist/connectFlow.d.ts +0 -13
  123. package/dist/cursorHooks.d.ts +0 -23
  124. package/dist/detection.d.ts +0 -30
  125. package/dist/hook.d.ts +0 -6
  126. package/dist/inboxFormat.d.ts +0 -38
  127. package/dist/limitEvent.d.ts +0 -16
  128. package/dist/limitEventReporter.d.ts +0 -21
  129. package/dist/mcp.d.ts +0 -12
  130. package/dist/prUrl.d.ts +0 -9
  131. package/dist/repoResolver.d.ts +0 -17
  132. package/dist/secret.d.ts +0 -1
  133. package/dist/security.d.ts +0 -102
  134. package/dist/securityDeepScan.d.ts +0 -41
  135. package/dist/securityDoctor.d.ts +0 -32
  136. package/dist/securityFeature.d.ts +0 -5
  137. package/dist/securityInstall.d.ts +0 -63
  138. package/dist/securityInventory.d.ts +0 -54
  139. package/dist/securityPilot.d.ts +0 -19
  140. package/dist/securityPolicy.d.ts +0 -33
  141. package/dist/securitySession.d.ts +0 -6
  142. package/dist/transcriptModels.d.ts +0 -18
  143. package/dist/upgradeNudge.d.ts +0 -25
  144. package/dist/utils.d.ts +0 -346
  145. package/dist/version.d.ts +0 -1
  146. package/dist/versionCheck.d.ts +0 -68
@@ -0,0 +1,214 @@
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.SHIM_EVENTS = void 0;
37
+ exports.unsupportedShimEvents = unsupportedShimEvents;
38
+ exports.shimPacks = shimPacks;
39
+ exports.generateShimSource = generateShimSource;
40
+ exports.writeShim = writeShim;
41
+ const fs = __importStar(require("fs"));
42
+ const store_1 = require("./store");
43
+ exports.SHIM_EVENTS = ["SessionStart", "PreToolUse", "PostToolUse", "Stop"];
44
+ function normalizeHooks(hooks) {
45
+ const out = {};
46
+ for (const event of exports.SHIM_EVENTS) {
47
+ const groups = hooks[event];
48
+ if (!Array.isArray(groups))
49
+ continue;
50
+ const normalized = [];
51
+ for (const groupValue of groups) {
52
+ const group = groupValue;
53
+ if (!group || !Array.isArray(group.hooks))
54
+ continue;
55
+ const handlers = [];
56
+ for (const handlerValue of group.hooks) {
57
+ const handler = handlerValue;
58
+ if (!handler || handler.type !== "command" || typeof handler.command !== "string")
59
+ continue;
60
+ handlers.push({
61
+ command: handler.command,
62
+ ...(typeof handler.timeout === "number" && handler.timeout > 0 ? { timeout: handler.timeout } : {}),
63
+ });
64
+ }
65
+ if (handlers.length === 0)
66
+ continue;
67
+ normalized.push({
68
+ ...(typeof group.matcher === "string" ? { matcher: group.matcher } : {}),
69
+ hooks: handlers,
70
+ });
71
+ }
72
+ if (normalized.length)
73
+ out[event] = normalized;
74
+ }
75
+ return out;
76
+ }
77
+ function unsupportedShimEvents(packs) {
78
+ const out = new Map();
79
+ for (const pack of packs) {
80
+ const events = Object.keys(pack.hooks ?? {}).filter((e) => !exports.SHIM_EVENTS.includes(e)).sort();
81
+ if (events.length)
82
+ out.set(pack.slug, events);
83
+ }
84
+ return out;
85
+ }
86
+ function shimPacks(packs) {
87
+ return packs
88
+ .map((pack) => ({ slug: pack.slug, root: pack.root, hooks: normalizeHooks(pack.hooks) }))
89
+ .filter((pack) => Object.keys(pack.hooks).length > 0);
90
+ }
91
+ function generateShimSource(packs) {
92
+ const data = shimPacks(packs);
93
+ return `// Managed by \`codiedev pack install\`. Regenerated on every install; do not edit.
94
+ import { spawnSync } from "node:child_process";
95
+ import { existsSync } from "node:fs";
96
+
97
+ const PACKS = ${JSON.stringify(data, null, 2)};
98
+
99
+ // OpenCode tool ids are lowercase; Claude hook matchers use Claude casing.
100
+ const TOOL_NAMES = {
101
+ bash: "Bash", edit: "Edit", write: "Write", read: "Read", grep: "Grep",
102
+ glob: "Glob", list: "LS", ls: "LS", webfetch: "WebFetch", websearch: "WebSearch",
103
+ todowrite: "TodoWrite", todoread: "TodoRead", task: "Task", multiedit: "MultiEdit",
104
+ patch: "Edit", apply_patch: "Edit",
105
+ };
106
+
107
+ export function claudeToolName(tool) {
108
+ const name = String(tool ?? "");
109
+ if (!name) return "unknown";
110
+ return TOOL_NAMES[name.toLowerCase()] ?? name.charAt(0).toUpperCase() + name.slice(1);
111
+ }
112
+
113
+ // Claude semantics: empty or "*" matches everything; otherwise a regex that
114
+ // must match the whole tool name ("Edit|Write", "Notebook.*").
115
+ export function matches(matcher, value) {
116
+ if (matcher === undefined || matcher === null || matcher === "" || matcher === "*") return true;
117
+ try {
118
+ return new RegExp("^(?:" + matcher + ")$").test(value);
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+
124
+ function handlersFor(event, value) {
125
+ const out = [];
126
+ for (const pack of PACKS) {
127
+ for (const group of pack.hooks[event] ?? []) {
128
+ if (!matches(group.matcher, value)) continue;
129
+ for (const handler of group.hooks) out.push({ ...handler, root: pack.root });
130
+ }
131
+ }
132
+ return out;
133
+ }
134
+
135
+ function run(handler, payload) {
136
+ const cwd = typeof payload.cwd === "string" && existsSync(payload.cwd) ? payload.cwd : undefined;
137
+ return spawnSync(handler.command, [], {
138
+ input: JSON.stringify(payload),
139
+ encoding: "utf8",
140
+ shell: true,
141
+ cwd,
142
+ timeout: (handler.timeout ?? 60) * 1000,
143
+ env: { ...process.env, CLAUDE_PLUGIN_ROOT: handler.root },
144
+ });
145
+ }
146
+
147
+ function sessionId(value) {
148
+ return value?.sessionID ?? value?.sessionId ?? value?.properties?.sessionID ?? value?.properties?.info?.id ?? undefined;
149
+ }
150
+
151
+ export const CodiedevPackHooks = async (ctx = {}) => {
152
+ const cwd = ctx?.worktree || ctx?.directory || process.cwd();
153
+ const childSessions = new Set();
154
+ return {
155
+ "tool.execute.before": async (input, output) => {
156
+ const tool_name = claudeToolName(input?.tool);
157
+ for (const handler of handlersFor("PreToolUse", tool_name)) {
158
+ const result = run(handler, {
159
+ hook_event_name: "PreToolUse",
160
+ session_id: sessionId(input),
161
+ cwd,
162
+ tool_name,
163
+ tool_input: output?.args ?? {},
164
+ });
165
+ if (result.status === 2) throw new Error(String(result.stderr ?? "").trim() || "Blocked by hook");
166
+ }
167
+ },
168
+ "tool.execute.after": async (input, output) => {
169
+ const tool_name = claudeToolName(input?.tool);
170
+ for (const handler of handlersFor("PostToolUse", tool_name)) {
171
+ run(handler, {
172
+ hook_event_name: "PostToolUse",
173
+ session_id: sessionId(input),
174
+ cwd,
175
+ tool_name,
176
+ tool_input: input?.args ?? {},
177
+ tool_response: output ?? null,
178
+ });
179
+ }
180
+ },
181
+ event: async ({ event } = {}) => {
182
+ // OpenCode also emits session.created/idle for subagent (child)
183
+ // sessions. Claude's SessionStart/Stop are top-level only, so remember
184
+ // children (info.parentID) and skip them. session.idle carries only the
185
+ // sessionID, hence the set.
186
+ const info = event?.properties?.info;
187
+ if (info?.id && info?.parentID) childSessions.add(info.id);
188
+ if (event?.type === "session.created") {
189
+ if (info?.parentID) return;
190
+ for (const handler of handlersFor("SessionStart", "startup")) {
191
+ run(handler, { hook_event_name: "SessionStart", session_id: sessionId(event), cwd, source: "startup" });
192
+ }
193
+ return;
194
+ }
195
+ if (event?.type === "session.idle") {
196
+ const id = sessionId(event);
197
+ if (info?.parentID || (id && childSessions.has(id))) return;
198
+ for (const handler of handlersFor("Stop", "")) {
199
+ run(handler, { hook_event_name: "Stop", session_id: sessionId(event), cwd, stop_hook_active: false });
200
+ }
201
+ }
202
+ },
203
+ };
204
+ };
205
+ `;
206
+ }
207
+ function writeShim(file, packs) {
208
+ if (shimPacks(packs).length === 0) {
209
+ fs.rmSync(file, { force: true });
210
+ return null;
211
+ }
212
+ (0, store_1.writeFileAtomic)(file, generateShimSource(packs), 0o600);
213
+ return file;
214
+ }
@@ -0,0 +1,155 @@
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.AGENT_LEVELS = void 0;
37
+ exports.pluginVersion = pluginVersion;
38
+ exports.writeFileAtomic = writeFileAtomic;
39
+ exports.portableAgentContent = portableAgentContent;
40
+ exports.pluginFiles = pluginFiles;
41
+ exports.writePluginDir = writePluginDir;
42
+ exports.readRegistry = readRegistry;
43
+ exports.writeRegistry = writeRegistry;
44
+ exports.marketplaceDocument = marketplaceDocument;
45
+ exports.writeMarketplace = writeMarketplace;
46
+ const fs = __importStar(require("fs"));
47
+ const skillMarker_1 = require("../skillMarker");
48
+ const path = __importStar(require("path"));
49
+ const paths_1 = require("./paths");
50
+ function pluginVersion(version) {
51
+ return `${version}.0.0`;
52
+ }
53
+ function writeFileAtomic(file, content, mode = 0o644) {
54
+ fs.mkdirSync(path.dirname(file), { recursive: true });
55
+ const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
56
+ fs.writeFileSync(tmp, content, { encoding: "utf8", mode });
57
+ fs.renameSync(tmp, file);
58
+ }
59
+ exports.AGENT_LEVELS = new Set(["opus", "sonnet", "haiku"]);
60
+ function portableAgentContent(content) {
61
+ const fm = content.match(/^(\uFEFF?---\r?\n)([\s\S]*?)(\r?\n---[ \t]*(?:\r?\n|$))/);
62
+ if (!fm)
63
+ return content;
64
+ const lines = fm[2].split(/\r?\n/);
65
+ const kept = lines.filter((line) => {
66
+ const m = line.match(/^model\s*:\s*["']?([^"'\r\n]*?)["']?\s*$/);
67
+ return !m || m[1].includes("/");
68
+ });
69
+ if (kept.length === lines.length)
70
+ return content;
71
+ return fm[1] + kept.join("\n") + fm[3] + content.slice(fm[0].length);
72
+ }
73
+ function pluginFiles(manifest, options = {}) {
74
+ const files = {};
75
+ files[path.join(".claude-plugin", "plugin.json")] = JSON.stringify({
76
+ name: manifest.slug,
77
+ version: pluginVersion(manifest.version),
78
+ description: manifest.description || manifest.name,
79
+ }, null, 2) + "\n";
80
+ for (const skill of manifest.skills) {
81
+ files[path.join("skills", skill.name, "SKILL.md")] = (0, skillMarker_1.stampSkillMarker)(skill.content, skill.artifactId);
82
+ }
83
+ for (const agent of manifest.agents) {
84
+ files[path.join("agents", `${agent.name}.md`)] = options.portable ? portableAgentContent(agent.content) : agent.content;
85
+ }
86
+ if (manifest.hooksJson) {
87
+ files[path.join("hooks", "hooks.json")] = manifest.hooksJson;
88
+ }
89
+ return files;
90
+ }
91
+ function assertInside(parent, child) {
92
+ const rel = path.relative(parent, child);
93
+ if (!rel || rel.startsWith("..") || path.isAbsolute(rel)) {
94
+ throw new Error(`refusing to write outside the pack dir: ${child}`);
95
+ }
96
+ }
97
+ function writePluginDir(root, manifest, options = {}) {
98
+ const target = (0, paths_1.pluginDir)(root, manifest.slug);
99
+ const parent = (0, paths_1.pluginsDir)(root);
100
+ assertInside(parent, target);
101
+ fs.mkdirSync(parent, { recursive: true });
102
+ const stamp = `${process.pid}-${Date.now()}`;
103
+ const tmp = path.join(parent, `.${manifest.slug}.tmp-${stamp}`);
104
+ const old = path.join(parent, `.${manifest.slug}.old-${stamp}`);
105
+ try {
106
+ for (const [rel, content] of Object.entries(pluginFiles(manifest, options))) {
107
+ const file = path.join(tmp, rel);
108
+ assertInside(tmp, file);
109
+ fs.mkdirSync(path.dirname(file), { recursive: true });
110
+ fs.writeFileSync(file, content, "utf8");
111
+ }
112
+ if (fs.existsSync(target))
113
+ fs.renameSync(target, old);
114
+ fs.renameSync(tmp, target);
115
+ }
116
+ catch (error) {
117
+ fs.rmSync(tmp, { recursive: true, force: true });
118
+ if (!fs.existsSync(target) && fs.existsSync(old))
119
+ fs.renameSync(old, target);
120
+ throw error;
121
+ }
122
+ fs.rmSync(old, { recursive: true, force: true });
123
+ return target;
124
+ }
125
+ function readRegistry(root) {
126
+ try {
127
+ const parsed = JSON.parse(fs.readFileSync((0, paths_1.registryPath)(root), "utf8"));
128
+ if (parsed && typeof parsed === "object" && parsed.packs && typeof parsed.packs === "object") {
129
+ return { packs: parsed.packs };
130
+ }
131
+ }
132
+ catch {
133
+ }
134
+ return { packs: {} };
135
+ }
136
+ function writeRegistry(root, registry) {
137
+ writeFileAtomic((0, paths_1.registryPath)(root), JSON.stringify(registry, null, 2) + "\n");
138
+ }
139
+ function marketplaceDocument(entries) {
140
+ const sorted = [...entries].sort((a, b) => a.slug.localeCompare(b.slug));
141
+ return {
142
+ name: paths_1.MARKETPLACE_NAME,
143
+ owner: { name: "Codiedev" },
144
+ metadata: { description: "Codiedev team starter packs" },
145
+ plugins: sorted.map((entry) => ({
146
+ name: entry.slug,
147
+ source: `./plugins/${entry.slug}`,
148
+ description: entry.description || entry.slug,
149
+ version: pluginVersion(entry.version),
150
+ })),
151
+ };
152
+ }
153
+ function writeMarketplace(root, entries) {
154
+ writeFileAtomic((0, paths_1.marketplacePath)(root), JSON.stringify(marketplaceDocument(entries), null, 2) + "\n");
155
+ }
@@ -0,0 +1,170 @@
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.EMPTY_RECHECK_MS = exports.NAG_INTERVAL_MS = exports.SYNC_INTERVAL_MS = void 0;
37
+ exports.isPackCiMode = isPackCiMode;
38
+ exports.readStatusCache = readStatusCache;
39
+ exports.writeStatusCache = writeStatusCache;
40
+ exports.autosyncDisabled = autosyncDisabled;
41
+ exports.decideSync = decideSync;
42
+ exports.cliEntry = cliEntry;
43
+ exports.maybeSpawnPackSync = maybeSpawnPackSync;
44
+ exports.packNagLine = packNagLine;
45
+ const fs = __importStar(require("fs"));
46
+ const os = __importStar(require("os"));
47
+ const path = __importStar(require("path"));
48
+ const child_process_1 = require("child_process");
49
+ const paths_1 = require("./paths");
50
+ const store_1 = require("./store");
51
+ exports.SYNC_INTERVAL_MS = 60 * 60 * 1000;
52
+ function isPackCiMode(env = process.env) {
53
+ const ci = (env.CI ?? "").trim().toLowerCase();
54
+ return (env.CODIEDEV_TOKEN ?? "").trim().startsWith("cdvci_") || ci === "true" || ci === "1";
55
+ }
56
+ exports.NAG_INTERVAL_MS = 24 * 60 * 60 * 1000;
57
+ exports.EMPTY_RECHECK_MS = 24 * 60 * 60 * 1000;
58
+ function readStatusCache(root) {
59
+ try {
60
+ const parsed = JSON.parse(fs.readFileSync((0, paths_1.statusCachePath)(root), "utf8"));
61
+ if (typeof parsed?.checkedAt !== "number")
62
+ return null;
63
+ return {
64
+ checkedAt: parsed.checkedAt,
65
+ available: typeof parsed.available === "number" ? parsed.available : 0,
66
+ outdated: Array.isArray(parsed.outdated) ? parsed.outdated.filter((o) => typeof o?.slug === "string") : [],
67
+ };
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ }
73
+ function writeStatusCache(root, cache) {
74
+ try {
75
+ (0, store_1.writeFileAtomic)((0, paths_1.statusCachePath)(root), JSON.stringify(cache) + "\n");
76
+ }
77
+ catch {
78
+ }
79
+ }
80
+ function mtime(file) {
81
+ try {
82
+ return fs.statSync(file).mtimeMs;
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ function registryNonEmpty(root) {
89
+ try {
90
+ const parsed = JSON.parse(fs.readFileSync((0, paths_1.registryPath)(root), "utf8"));
91
+ return Boolean(parsed?.packs && Object.keys(parsed.packs).length > 0);
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ function autosyncDisabled(env) {
98
+ const v = (env.CODIEDEV_PACK_AUTOSYNC ?? "").trim().toLowerCase();
99
+ return v === "0" || v === "false" || v === "off" || v === "no";
100
+ }
101
+ function decideSync(root, env, now) {
102
+ const last = mtime((0, paths_1.lastSyncPath)(root));
103
+ if (last !== null && now - last < exports.SYNC_INTERVAL_MS && last <= now)
104
+ return "throttled";
105
+ if (!registryNonEmpty(root)) {
106
+ const cache = readStatusCache(root);
107
+ if (cache && cache.available === 0 && now - cache.checkedAt < exports.EMPTY_RECHECK_MS)
108
+ return "no-packs";
109
+ }
110
+ return autosyncDisabled(env) ? "spawn-check" : "spawn-install";
111
+ }
112
+ function cliEntry() {
113
+ return path.join(__dirname, "..", "cli.js");
114
+ }
115
+ function maybeSpawnPackSync(options = {}) {
116
+ try {
117
+ if (options.connected === false)
118
+ return "not-connected";
119
+ const env = options.env ?? process.env;
120
+ if (isPackCiMode(env))
121
+ return "ci";
122
+ const root = (0, paths_1.packsRoot)(env, options.home ?? os.homedir());
123
+ const now = options.now ?? Date.now();
124
+ const decision = decideSync(root, env, now);
125
+ if (decision !== "spawn-install" && decision !== "spawn-check")
126
+ return decision;
127
+ fs.mkdirSync(root, { recursive: true });
128
+ fs.writeFileSync((0, paths_1.lastSyncPath)(root), String(now));
129
+ const time = new Date(now);
130
+ fs.utimesSync((0, paths_1.lastSyncPath)(root), time, time);
131
+ const args = decision === "spawn-install"
132
+ ? ["pack", "install", "--quiet"]
133
+ : ["pack", "status", "--quiet", "--no-prune"];
134
+ const child = (options.spawn ?? child_process_1.spawn)(process.execPath, [options.cli ?? cliEntry(), ...args], {
135
+ detached: true,
136
+ stdio: "ignore",
137
+ env: { ...env, CODIEDEV_PACK_BACKGROUND: "1" },
138
+ });
139
+ child.on?.("error", () => { });
140
+ child.unref?.();
141
+ return decision;
142
+ }
143
+ catch {
144
+ return "error";
145
+ }
146
+ }
147
+ function packNagLine(options = {}) {
148
+ try {
149
+ const env = options.env ?? process.env;
150
+ if (env.CODIEDEV_PACK_BACKGROUND || isPackCiMode(env))
151
+ return null;
152
+ const root = (0, paths_1.packsRoot)(env, options.home ?? os.homedir());
153
+ const now = options.now ?? Date.now();
154
+ const cache = readStatusCache(root);
155
+ if (!cache || cache.outdated.length === 0)
156
+ return null;
157
+ const last = mtime((0, paths_1.lastNagPath)(root));
158
+ if (last !== null && now - last < exports.NAG_INTERVAL_MS && last <= now)
159
+ return null;
160
+ fs.writeFileSync((0, paths_1.lastNagPath)(root), String(now));
161
+ const time = new Date(now);
162
+ fs.utimesSync((0, paths_1.lastNagPath)(root), time, time);
163
+ const first = cache.outdated[0];
164
+ const more = cache.outdated.length > 1 ? ` (+${cache.outdated.length - 1} more)` : "";
165
+ return `Starter pack ${first.name || first.slug}${more} has updates. Run \`codiedev pack install\`.`;
166
+ }
167
+ catch {
168
+ return null;
169
+ }
170
+ }
package/dist/prUrl.js CHANGED
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- // PR/MR URL parser. GitHub uses `/pull/<n>`, GitLab uses `/-/merge_requests/<n>`.
3
- // Self-hosted GitLab keeps the same path shape on a different host (Sonifi
4
- // runs git.sonifi.com behind a Cloudflare tunnel, for example). Nested groups
5
- // land in `owner` as a slash-joined path so we can rebuild the full project
6
- // path when calling the GitLab API.
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.parsePrOrMrUrl = parsePrOrMrUrl;
9
4
  function parsePrOrMrUrl(url) {
@@ -1,12 +1,4 @@
1
1
  "use strict";
2
- // Pure resolver — given a captured remoteUrl, an optional client-cached
3
- // repoId, and the company's current repo list, decide which repoId (if any)
4
- // the session belongs to. Used both inline by the CLI hook and (mirrored
5
- // in convex/repoResolver.ts) by the /api/captureSession endpoint so that
6
- // repos added after the user's last `connect` still get matched.
7
- //
8
- // "unmatched" is intentional — the backend will accept the session anyway
9
- // and surface it for triage rather than silently dropping it.
10
2
  Object.defineProperty(exports, "__esModule", { value: true });
11
3
  exports.resolveRepoForCapture = resolveRepoForCapture;
12
4
  function parseRemoteUrl(url) {
@@ -17,12 +9,6 @@ function parseRemoteUrl(url) {
17
9
  if (https) {
18
10
  return { host: https[1].toLowerCase(), ownerName: https[2].toLowerCase() };
19
11
  }
20
- // Codie strips SSH userinfo before putting a remote in the gateway header,
21
- // so `git@gitlab.com:owner/repo.git` arrives here as
22
- // `gitlab.com:owner/repo.git`. Accept both forms; otherwise every SSH-cloned
23
- // Harness checkout loses its repoId even though transcript capture can
24
- // resolve the same raw remote correctly. Check this after URL forms so the
25
- // colon in `https://` is never mistaken for an SCP separator.
26
12
  const scp = s.match(/^(?:[^@\s]+@)?([^:/\s]+):([^/]+\/.+)$/);
27
13
  if (scp) {
28
14
  return { host: scp[1].toLowerCase(), ownerName: scp[2].toLowerCase() };
@@ -31,11 +17,6 @@ function parseRemoteUrl(url) {
31
17
  }
32
18
  function resolveRepoForCapture(input) {
33
19
  const { remoteUrl, providedRepoId, companyRepos } = input;
34
- // The remoteUrl is the ground truth of where the work happened — resolve it
35
- // FIRST. A buggy client can send a wrong-but-valid providedRepoId (the Sonifi
36
- // case: client matchRepo stamped every session with the org's first repo), so
37
- // we must not blindly trust it over the URL. Keep providedRepoId only when it
38
- // AGREES with the URL match, or when the URL can't be resolved at all.
39
20
  const parsed = remoteUrl ? parseRemoteUrl(remoteUrl) : null;
40
21
  const urlMatch = parsed
41
22
  ? companyRepos.find((r) => `${r.owner}/${r.name}`.toLowerCase() === parsed.ownerName)
package/dist/secret.js CHANGED
@@ -1,7 +1,4 @@
1
1
  "use strict";
2
- // Display helpers for credential-shaped strings. Use anywhere a token /
3
- // secret might end up in user-visible output (logs, success lines, error
4
- // messages) so a stray `console.log` can't leak the full value.
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.maskToken = maskToken;
7
4
  const PREFIX_LEN = 12;
package/dist/security.js CHANGED
@@ -42,9 +42,6 @@ exports.buildSecurityWorkflowEvent = buildSecurityWorkflowEvent;
42
42
  exports.buildSecurityPromptEvent = buildSecurityPromptEvent;
43
43
  exports.buildBlockedSecurityPromptEvent = buildBlockedSecurityPromptEvent;
44
44
  const crypto = __importStar(require("crypto"));
45
- // Advances only when endpoint enforcement behavior changes. This is
46
- // intentionally independent from the package version so security coverage can
47
- // remain current across unrelated CLI releases.
48
45
  exports.SECURITY_RUNTIME_VERSION = 1;
49
46
  function withEndpointIdentity(event, identity) {
50
47
  return {
@@ -140,12 +137,6 @@ function containsSecretValue(text) {
140
137
  SECRET_ASSIGNMENT.lastIndex = 0;
141
138
  return false;
142
139
  }
143
- /**
144
- * Runs before a user prompt reaches the model. This is intentionally narrow:
145
- * block credential material, but allow safe references such as
146
- * `$OPENAI_API_KEY` so developers can ask agents to use environment variables
147
- * without pasting their values.
148
- */
149
140
  function evaluatePromptSecurity(prompt, policy, source) {
150
141
  if (!prompt || !containsSecretValue(prompt))
151
142
  return { action: "allow" };
@@ -210,7 +201,6 @@ function destructiveTargetOutsideWorkspace(command, cwd) {
210
201
  const normalizedCwd = cwd.replace(/\/+$/, "");
211
202
  return target !== normalizedCwd && !target.startsWith(`${normalizedCwd}/`);
212
203
  }
213
- /** Runs synchronously before a tool executes. No network or model is involved. */
214
204
  function evaluateToolSecurity(input, phase, policy, source, sessionContext) {
215
205
  if (phase !== "pre")
216
206
  return { action: "allow" };
@@ -324,8 +314,6 @@ function redactString(value) {
324
314
  return `[REDACTED_SECRET:${fingerprint(match)}]`;
325
315
  });
326
316
  }
327
- // Keep hook payloads bounded. Full transcripts already use Codie's existing
328
- // capture path; the detector only needs immediate causal context here.
329
317
  if (redacted.length > 16_384)
330
318
  redacted = `${redacted.slice(0, 16_384)}[TRUNCATED]`;
331
319
  return { value: redacted, count };
@@ -386,12 +374,6 @@ function buildSecurityWorkflowEvent(input, phase, source, now = Date.now) {
386
374
  redactionCount: sanitized.count,
387
375
  };
388
376
  }
389
- /**
390
- * Captures the intent side of the causal chain without weakening the local
391
- * privacy boundary. A prompt that the deterministic policy blocks never
392
- * becomes an uploadable event; allowed prompts are redacted and bounded using
393
- * the same sanitizer as tool payloads.
394
- */
395
377
  function buildSecurityPromptEvent(input, source, now = Date.now, policy) {
396
378
  const sessionId = input.session_id ?? input.sessionId ?? "";
397
379
  if (!sessionId || !input.prompt) {
@@ -415,8 +397,6 @@ function buildSecurityPromptEvent(input, source, now = Date.now, policy) {
415
397
  localCategory: decision.action === "alert" ? decision.category : undefined,
416
398
  };
417
399
  }
418
- /** Audit-safe evidence for a blocked prompt. The secret-bearing prompt is
419
- * intentionally omitted; administrators still see that prevention occurred. */
420
400
  function buildBlockedSecurityPromptEvent(input, source, category, now = Date.now) {
421
401
  const sessionId = input.session_id ?? input.sessionId ?? "";
422
402
  if (!sessionId)