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,285 @@
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.codexPackHooksPath = codexPackHooksPath;
37
+ exports.codexPackTrustEntries = codexPackTrustEntries;
38
+ exports.installPacks = installPacks;
39
+ exports.uninstallPacks = uninstallPacks;
40
+ exports.formatUninstallLines = formatUninstallLines;
41
+ exports.formatResultLines = formatResultLines;
42
+ const fs = __importStar(require("fs"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const harnessDirs_1 = require("../harnessDirs");
46
+ const codexHookTrust_1 = require("../codexHookTrust");
47
+ const harnesses_1 = require("./harnesses");
48
+ const manifest_1 = require("./manifest");
49
+ const paths_1 = require("./paths");
50
+ const shim_1 = require("./shim");
51
+ const store_1 = require("./store");
52
+ function marketplaceEntries(registry) {
53
+ return Object.entries(registry.packs).map(([slug, entry]) => ({
54
+ slug,
55
+ version: entry.version,
56
+ description: entry.description,
57
+ }));
58
+ }
59
+ function codexPackHooksPath(codexDir, slug, version) {
60
+ const base = path.join(codexDir, "plugins", "cache", paths_1.MARKETPLACE_NAME, slug);
61
+ const exact = path.join(base, (0, store_1.pluginVersion)(version), "hooks", "hooks.json");
62
+ if (fs.existsSync(exact))
63
+ return exact;
64
+ let best = null;
65
+ try {
66
+ for (const entry of fs.readdirSync(base)) {
67
+ const file = path.join(base, entry, "hooks", "hooks.json");
68
+ try {
69
+ const mtime = fs.statSync(file).mtimeMs;
70
+ if (!best || mtime > best.mtime)
71
+ best = { file, mtime };
72
+ }
73
+ catch {
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ return best?.file ?? null;
81
+ }
82
+ function codexPackTrustEntries(registry, codexDir) {
83
+ const bySlug = new Map();
84
+ for (const [slug, entry] of Object.entries(registry.packs).sort(([a], [b]) => a.localeCompare(b))) {
85
+ if (!entry.harnesses?.includes("codex"))
86
+ continue;
87
+ const hooksPath = codexPackHooksPath(codexDir, slug, entry.version);
88
+ if (!hooksPath)
89
+ continue;
90
+ try {
91
+ bySlug.set(slug, (0, codexHookTrust_1.packCodexHookTrustEntries)(hooksPath, JSON.parse(fs.readFileSync(hooksPath, "utf8"))));
92
+ }
93
+ catch {
94
+ }
95
+ }
96
+ return bySlug;
97
+ }
98
+ function shimInputs(registry) {
99
+ const packs = [];
100
+ for (const [slug, entry] of Object.entries(registry.packs).sort(([a], [b]) => a.localeCompare(b))) {
101
+ if (!entry.harnesses?.includes("codie"))
102
+ continue;
103
+ try {
104
+ const parsed = JSON.parse(fs.readFileSync(path.join(entry.dir, "hooks", "hooks.json"), "utf8"));
105
+ if (parsed?.hooks && typeof parsed.hooks === "object")
106
+ packs.push({ slug, root: entry.dir, hooks: parsed.hooks });
107
+ }
108
+ catch {
109
+ }
110
+ }
111
+ return packs;
112
+ }
113
+ function installPacks(options) {
114
+ const env = options.env ?? process.env;
115
+ const home = options.home ?? os.homedir();
116
+ const run = options.run ?? (0, harnesses_1.defaultRunner)(env);
117
+ const now = options.now ?? Date.now;
118
+ const root = (0, paths_1.packsRoot)(env, home);
119
+ const selected = new Set(options.harnesses ?? harnesses_1.ADAPTERS.map((a) => a.name));
120
+ const adapters = harnesses_1.ADAPTERS.filter((a) => selected.has(a.name));
121
+ const registry = (0, store_1.readRegistry)(root);
122
+ const detected = new Map();
123
+ for (const adapter of adapters)
124
+ detected.set(adapter.name, adapter.detect({ root, env, home, run }));
125
+ const output = [];
126
+ for (const manifest of options.manifests) {
127
+ const dir = (0, paths_1.pluginDir)(root, manifest.slug);
128
+ const previous = registry.packs[manifest.slug];
129
+ const files = Object.keys((0, store_1.pluginFiles)(manifest)).sort();
130
+ const results = [];
131
+ if (options.dryRun) {
132
+ for (const adapter of adapters) {
133
+ const ctx = { root, env, home, run, manifest, pluginDir: dir, portablePluginDir: (0, paths_1.pluginDir)((0, paths_1.portableRoot)(root), manifest.slug), previous };
134
+ results.push(detected.get(adapter.name)
135
+ ? { harness: adapter.name, status: "dry-run", detail: `would run: ${adapter.plan(ctx)}` }
136
+ : { harness: adapter.name, status: "skipped", detail: "not detected" });
137
+ }
138
+ output.push({ slug: manifest.slug, version: manifest.version, contentHash: manifest.contentHash, dir, files, results, harnesses: [] });
139
+ continue;
140
+ }
141
+ (0, store_1.writePluginDir)(root, manifest);
142
+ (0, store_1.writePluginDir)((0, paths_1.portableRoot)(root), manifest, { portable: true });
143
+ const pending = {
144
+ packs: {
145
+ ...registry.packs,
146
+ [manifest.slug]: {
147
+ version: manifest.version,
148
+ contentHash: manifest.contentHash,
149
+ dir,
150
+ installedAt: previous?.installedAt ?? now(),
151
+ harnesses: previous?.harnesses ?? [],
152
+ name: manifest.name,
153
+ description: manifest.description,
154
+ },
155
+ },
156
+ };
157
+ (0, store_1.writeMarketplace)(root, marketplaceEntries(pending));
158
+ (0, store_1.writeMarketplace)((0, paths_1.portableRoot)(root), marketplaceEntries(pending));
159
+ for (const adapter of adapters) {
160
+ if (!detected.get(adapter.name)) {
161
+ results.push({ harness: adapter.name, status: "skipped", detail: "not detected" });
162
+ continue;
163
+ }
164
+ try {
165
+ const detail = adapter.install({ root, env, home, run, manifest, pluginDir: dir, portablePluginDir: (0, paths_1.pluginDir)((0, paths_1.portableRoot)(root), manifest.slug), previous });
166
+ results.push({ harness: adapter.name, status: "ok", detail });
167
+ }
168
+ catch (error) {
169
+ results.push({ harness: adapter.name, status: "failed", detail: error instanceof Error ? error.message : String(error) });
170
+ }
171
+ }
172
+ const kept = (previous?.harnesses ?? []).filter((h) => !selected.has(h));
173
+ const succeeded = results.filter((r) => r.status === "ok").map((r) => r.harness);
174
+ const harnesses = [...new Set([...kept, ...succeeded])].sort();
175
+ registry.packs[manifest.slug] = {
176
+ version: manifest.version,
177
+ contentHash: manifest.contentHash,
178
+ dir,
179
+ installedAt: now(),
180
+ harnesses,
181
+ name: manifest.name,
182
+ description: manifest.description,
183
+ ...(manifest.channel ? { channel: manifest.channel } : {}),
184
+ ...(manifest.icon ? { icon: manifest.icon } : {}),
185
+ };
186
+ (0, store_1.writeRegistry)(root, registry);
187
+ output.push({ slug: manifest.slug, ...(manifest.channel ? { channel: manifest.channel } : {}), version: manifest.version, contentHash: manifest.contentHash, dir, files, results, harnesses });
188
+ }
189
+ if (options.dryRun || options.manifests.length === 0)
190
+ return output;
191
+ if (selected.has("codex") && detected.get("codex")) {
192
+ const bySlug = regenerateCodexTrust(registry, env, home);
193
+ for (const pack of output) {
194
+ const codex = pack.results.find((r) => r.harness === "codex" && r.status === "ok");
195
+ const count = bySlug.get(pack.slug)?.length ?? 0;
196
+ if (codex && count)
197
+ codex.detail += `; ${count} hook${count === 1 ? "" : "s"} trusted`;
198
+ }
199
+ }
200
+ if (selected.has("codie")) {
201
+ (0, shim_1.writeShim)((0, paths_1.shimPath)(root), shimInputs(registry));
202
+ const skipped = (0, shim_1.unsupportedShimEvents)(shimInputs(registry));
203
+ for (const pack of output) {
204
+ const codie = pack.results.find((r) => r.harness === "codie" && r.status === "ok");
205
+ const events = skipped.get(pack.slug);
206
+ if (codie && events?.length)
207
+ codie.notes = [`hooks Codie can't run were skipped: ${events.join(", ")}`];
208
+ }
209
+ }
210
+ return output;
211
+ }
212
+ function regenerateCodexTrust(registry, env, home) {
213
+ const codexDir = (0, harnessDirs_1.codexHome)(env, home);
214
+ const bySlug = codexPackTrustEntries(registry, codexDir);
215
+ (0, codexHookTrust_1.writeCodexPackHookTrust)(path.join(codexDir, "config.toml"), [...bySlug.values()].flat());
216
+ return bySlug;
217
+ }
218
+ function uninstallPacks(options) {
219
+ const env = options.env ?? process.env;
220
+ const home = options.home ?? os.homedir();
221
+ const run = options.run ?? (0, harnesses_1.defaultRunner)(env);
222
+ const root = (0, paths_1.packsRoot)(env, home);
223
+ const registry = (0, store_1.readRegistry)(root);
224
+ const output = [];
225
+ for (const slug of options.slugs) {
226
+ const entry = registry.packs[slug];
227
+ if (!entry || !(0, manifest_1.isSafeSegment)(slug))
228
+ continue;
229
+ const results = [];
230
+ for (const adapter of harnesses_1.ADAPTERS) {
231
+ if (!entry.harnesses?.includes(adapter.name))
232
+ continue;
233
+ if (!adapter.detect({ root, env, home, run })) {
234
+ results.push({ harness: adapter.name, status: "skipped", detail: "not detected" });
235
+ continue;
236
+ }
237
+ try {
238
+ results.push({ harness: adapter.name, status: "ok", detail: adapter.uninstall({ root, env, home, run, slug }) });
239
+ }
240
+ catch (error) {
241
+ results.push({ harness: adapter.name, status: "failed", detail: error instanceof Error ? error.message : String(error) });
242
+ }
243
+ }
244
+ delete registry.packs[slug];
245
+ fs.rmSync((0, paths_1.pluginDir)(root, slug), { recursive: true, force: true });
246
+ fs.rmSync((0, paths_1.pluginDir)((0, paths_1.portableRoot)(root), slug), { recursive: true, force: true });
247
+ output.push({ slug, results });
248
+ }
249
+ if (output.length === 0)
250
+ return output;
251
+ (0, store_1.writeRegistry)(root, registry);
252
+ (0, store_1.writeMarketplace)(root, marketplaceEntries(registry));
253
+ (0, store_1.writeMarketplace)((0, paths_1.portableRoot)(root), marketplaceEntries(registry));
254
+ const codexConfig = path.join((0, harnessDirs_1.codexHome)(env, home), "config.toml");
255
+ if (fs.existsSync(codexConfig))
256
+ regenerateCodexTrust(registry, env, home);
257
+ (0, shim_1.writeShim)((0, paths_1.shimPath)(root), shimInputs(registry));
258
+ return output;
259
+ }
260
+ function formatUninstallLines(results) {
261
+ const lines = [];
262
+ for (const pack of results) {
263
+ lines.push(`${pack.slug} removed (no longer assigned to your team)`);
264
+ for (const r of pack.results) {
265
+ const mark = r.status === "ok" ? "✓" : r.status === "failed" ? "✗" : "-";
266
+ lines.push(` ${mark} ${r.harness}: ${r.status === "failed" ? "failed: " : r.status === "skipped" ? "skipped: " : ""}${r.detail}`);
267
+ }
268
+ }
269
+ return lines;
270
+ }
271
+ function formatResultLines(results) {
272
+ const lines = [];
273
+ for (const pack of results) {
274
+ lines.push(`${pack.slug} v${pack.version}${pack.channel ? ` (${pack.channel})` : ""} → ${pack.dir}`);
275
+ for (const r of pack.results) {
276
+ const mark = r.status === "ok" ? "✓" : r.status === "failed" ? "✗" : r.status === "dry-run" ? "·" : "-";
277
+ const word = r.status === "ok" ? "" : r.status === "failed" ? "failed: " : r.status === "skipped" ? "skipped: " : "";
278
+ lines.push(` ${mark} ${r.harness}: ${word}${r.detail}`);
279
+ if (process.env.CODIEDEV_DEBUG)
280
+ for (const note of r.notes ?? [])
281
+ lines.push(` note: ${note}`);
282
+ }
283
+ }
284
+ return lines;
285
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ManifestError = void 0;
4
+ exports.isSafeSegment = isSafeSegment;
5
+ exports.isSafeSkillName = isSafeSkillName;
6
+ exports.parseManifest = parseManifest;
7
+ exports.cleanLabel = cleanLabel;
8
+ exports.displayName = displayName;
9
+ exports.parseFrontmatter = parseFrontmatter;
10
+ const SAFE_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
11
+ function isSafeSegment(value) {
12
+ return typeof value === "string" && SAFE_SEGMENT.test(value) && !value.includes("..");
13
+ }
14
+ const SAFE_SKILL_NAME = /^[A-Za-z0-9][A-Za-z0-9._ -]{0,127}$/;
15
+ function isSafeSkillName(value) {
16
+ return typeof value === "string" && SAFE_SKILL_NAME.test(value) && !value.includes("..") && value.trim() === value;
17
+ }
18
+ class ManifestError extends Error {
19
+ }
20
+ exports.ManifestError = ManifestError;
21
+ function fileList(value, field, safe) {
22
+ if (value === undefined || value === null)
23
+ return [];
24
+ if (!Array.isArray(value))
25
+ throw new ManifestError(`manifest.${field} must be an array`);
26
+ const seen = new Set();
27
+ return value.map((item, index) => {
28
+ const entry = item;
29
+ if (!entry || typeof entry !== "object")
30
+ throw new ManifestError(`manifest.${field}[${index}] is not an object`);
31
+ if (!safe(entry.name)) {
32
+ throw new ManifestError(`manifest.${field}[${index}] has an unsafe name: ${JSON.stringify(entry.name)}`);
33
+ }
34
+ if (typeof entry.content !== "string")
35
+ throw new ManifestError(`manifest.${field}[${index}].content must be a string`);
36
+ const key = entry.name.toLowerCase();
37
+ if (seen.has(key))
38
+ throw new ManifestError(`manifest.${field} has a duplicate name: ${entry.name}`);
39
+ seen.add(key);
40
+ const artifactId = typeof entry.artifactId === "string" && /^[a-z0-9]{16,64}$/i.test(entry.artifactId) ? entry.artifactId : undefined;
41
+ return { name: entry.name, content: entry.content, ...(artifactId ? { artifactId } : {}) };
42
+ });
43
+ }
44
+ function parseManifest(input) {
45
+ let raw = input;
46
+ if (typeof raw === "string") {
47
+ try {
48
+ raw = JSON.parse(raw);
49
+ }
50
+ catch {
51
+ throw new ManifestError("manifest is not valid JSON");
52
+ }
53
+ }
54
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
55
+ throw new ManifestError("manifest is not an object");
56
+ const m = raw;
57
+ if (!isSafeSegment(m.slug))
58
+ throw new ManifestError(`manifest has an unsafe slug: ${JSON.stringify(m.slug)}`);
59
+ const version = Number(m.version);
60
+ if (!Number.isInteger(version) || version < 0)
61
+ throw new ManifestError("manifest.version must be a non-negative integer");
62
+ if (typeof m.contentHash !== "string" || !m.contentHash)
63
+ throw new ManifestError("manifest.contentHash is missing");
64
+ let hooksJson = null;
65
+ if (m.hooksJson !== undefined && m.hooksJson !== null) {
66
+ if (typeof m.hooksJson !== "string")
67
+ throw new ManifestError("manifest.hooksJson must be a string or null");
68
+ if (m.hooksJson.trim()) {
69
+ let parsed;
70
+ try {
71
+ parsed = JSON.parse(m.hooksJson);
72
+ }
73
+ catch {
74
+ throw new ManifestError("manifest.hooksJson is not valid JSON");
75
+ }
76
+ const hooks = parsed?.hooks;
77
+ if (!hooks || typeof hooks !== "object" || Array.isArray(hooks)) {
78
+ throw new ManifestError("manifest.hooksJson must look like {\"hooks\":{...}}");
79
+ }
80
+ hooksJson = m.hooksJson;
81
+ }
82
+ }
83
+ return {
84
+ slug: m.slug,
85
+ name: typeof m.name === "string" && m.name ? m.name : m.slug,
86
+ description: typeof m.description === "string" ? m.description : "",
87
+ version,
88
+ contentHash: m.contentHash,
89
+ skills: fileList(m.skills, "skills", isSafeSkillName),
90
+ agents: fileList(m.agents, "agents", isSafeSegment),
91
+ hooksJson,
92
+ ...(cleanLabel(m.channel, 16) ? { channel: cleanLabel(m.channel, 16) } : {}),
93
+ ...(cleanLabel(m.icon, 16) ? { icon: cleanLabel(m.icon, 16) } : {}),
94
+ };
95
+ }
96
+ function cleanLabel(value, max) {
97
+ if (typeof value !== "string")
98
+ return undefined;
99
+ const clean = value
100
+ .replace(/\u001b\[[0-9;?]*[ -\/]*[@-~]/g, "")
101
+ .replace(/[\u0000-\u001f\u007f-\u009f]/g, "")
102
+ .trim();
103
+ return clean ? [...clean].slice(0, max).join("") : undefined;
104
+ }
105
+ function displayName(pack) {
106
+ const icon = cleanLabel(pack.icon, 8);
107
+ const name = pack.name || pack.slug;
108
+ return icon ? `${icon} ${name}` : name;
109
+ }
110
+ function parseFrontmatter(content) {
111
+ const match = content.match(/^?---\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/);
112
+ if (!match)
113
+ return { data: {}, body: content };
114
+ const data = {};
115
+ for (const line of match[1].split(/\r?\n/)) {
116
+ const kv = line.match(/^([A-Za-z0-9_-]+)\s*:\s*(.*)$/);
117
+ if (!kv)
118
+ continue;
119
+ let value = kv[2].trim();
120
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
121
+ value = value.slice(1, -1);
122
+ }
123
+ data[kv[1]] = value;
124
+ }
125
+ return { data, body: content.slice(match[0].length) };
126
+ }
@@ -0,0 +1,81 @@
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.MARKETPLACE_NAME = void 0;
37
+ exports.packsRoot = packsRoot;
38
+ exports.pluginsDir = pluginsDir;
39
+ exports.pluginDir = pluginDir;
40
+ exports.portableRoot = portableRoot;
41
+ exports.marketplacePath = marketplacePath;
42
+ exports.registryPath = registryPath;
43
+ exports.shimPath = shimPath;
44
+ exports.lastSyncPath = lastSyncPath;
45
+ exports.statusCachePath = statusCachePath;
46
+ exports.lastNagPath = lastNagPath;
47
+ const os = __importStar(require("os"));
48
+ const path = __importStar(require("path"));
49
+ exports.MARKETPLACE_NAME = "codiedev-packs";
50
+ function packsRoot(env = process.env, home = os.homedir()) {
51
+ const override = env.CODIEDEV_CONFIG_DIR?.trim();
52
+ const stateDir = override ? path.resolve(override) : path.join(home, ".codiedev");
53
+ return path.join(stateDir, "packs");
54
+ }
55
+ function pluginsDir(root) {
56
+ return path.join(root, "plugins");
57
+ }
58
+ function pluginDir(root, slug) {
59
+ return path.join(pluginsDir(root), slug);
60
+ }
61
+ function portableRoot(root) {
62
+ return path.join(root, "portable");
63
+ }
64
+ function marketplacePath(root) {
65
+ return path.join(root, ".claude-plugin", "marketplace.json");
66
+ }
67
+ function registryPath(root) {
68
+ return path.join(root, "installed.json");
69
+ }
70
+ function shimPath(root) {
71
+ return path.join(root, "codie-hook-shim.mjs");
72
+ }
73
+ function lastSyncPath(root) {
74
+ return path.join(root, ".last-sync");
75
+ }
76
+ function statusCachePath(root) {
77
+ return path.join(root, "status-cache.json");
78
+ }
79
+ function lastNagPath(root) {
80
+ return path.join(root, ".last-nag");
81
+ }