agentpacks 0.2.0

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 (172) hide show
  1. package/dist/api.d.ts +32 -0
  2. package/dist/api.js +2852 -0
  3. package/dist/cli/export-cmd.d.ts +12 -0
  4. package/dist/cli/export-cmd.js +786 -0
  5. package/dist/cli/generate.d.ts +13 -0
  6. package/dist/cli/generate.js +2018 -0
  7. package/dist/cli/import-cmd.d.ts +9 -0
  8. package/dist/cli/import-cmd.js +691 -0
  9. package/dist/cli/init.d.ts +5 -0
  10. package/dist/cli/init.js +214 -0
  11. package/dist/cli/install.d.ts +11 -0
  12. package/dist/cli/install.js +610 -0
  13. package/dist/cli/pack/create.d.ts +4 -0
  14. package/dist/cli/pack/create.js +175 -0
  15. package/dist/cli/pack/enable.d.ts +8 -0
  16. package/dist/cli/pack/enable.js +96 -0
  17. package/dist/cli/pack/list.d.ts +4 -0
  18. package/dist/cli/pack/list.js +699 -0
  19. package/dist/cli/pack/validate.d.ts +4 -0
  20. package/dist/cli/pack/validate.js +364 -0
  21. package/dist/core/config.d.ts +77 -0
  22. package/dist/core/config.js +181 -0
  23. package/dist/core/dependency-resolver.d.ts +38 -0
  24. package/dist/core/dependency-resolver.js +151 -0
  25. package/dist/core/feature-merger.d.ts +61 -0
  26. package/dist/core/feature-merger.js +139 -0
  27. package/dist/core/index.d.ts +5 -0
  28. package/dist/core/index.js +924 -0
  29. package/dist/core/lockfile.d.ts +50 -0
  30. package/dist/core/lockfile.js +72 -0
  31. package/dist/core/metarepo.d.ts +26 -0
  32. package/dist/core/metarepo.js +218 -0
  33. package/dist/core/pack-loader.d.ts +61 -0
  34. package/dist/core/pack-loader.js +646 -0
  35. package/dist/exporters/cursor-plugin.d.ts +29 -0
  36. package/dist/exporters/cursor-plugin.js +258 -0
  37. package/dist/exporters/index.d.ts +1 -0
  38. package/dist/exporters/index.js +258 -0
  39. package/dist/features/agents.d.ts +48 -0
  40. package/dist/features/agents.js +190 -0
  41. package/dist/features/commands.d.ts +33 -0
  42. package/dist/features/commands.js +190 -0
  43. package/dist/features/hooks.d.ts +33 -0
  44. package/dist/features/hooks.js +182 -0
  45. package/dist/features/ignore.d.ts +21 -0
  46. package/dist/features/ignore.js +72 -0
  47. package/dist/features/index.d.ts +8 -0
  48. package/dist/features/index.js +426 -0
  49. package/dist/features/mcp.d.ts +34 -0
  50. package/dist/features/mcp.js +172 -0
  51. package/dist/features/plugins.d.ts +23 -0
  52. package/dist/features/plugins.js +168 -0
  53. package/dist/features/rules.d.ts +53 -0
  54. package/dist/features/rules.js +198 -0
  55. package/dist/features/skills.d.ts +42 -0
  56. package/dist/features/skills.js +198 -0
  57. package/dist/importers/claude-code.d.ts +5 -0
  58. package/dist/importers/claude-code.js +224 -0
  59. package/dist/importers/cursor.d.ts +5 -0
  60. package/dist/importers/cursor.js +288 -0
  61. package/dist/importers/opencode.d.ts +5 -0
  62. package/dist/importers/opencode.js +261 -0
  63. package/dist/importers/rulesync.d.ts +14 -0
  64. package/dist/importers/rulesync.js +280 -0
  65. package/dist/index.d.ts +2 -0
  66. package/dist/index.js +3464 -0
  67. package/dist/node/api.js +2852 -0
  68. package/dist/node/cli/export-cmd.js +786 -0
  69. package/dist/node/cli/generate.js +2018 -0
  70. package/dist/node/cli/import-cmd.js +691 -0
  71. package/dist/node/cli/init.js +214 -0
  72. package/dist/node/cli/install.js +610 -0
  73. package/dist/node/cli/pack/create.js +175 -0
  74. package/dist/node/cli/pack/enable.js +96 -0
  75. package/dist/node/cli/pack/list.js +699 -0
  76. package/dist/node/cli/pack/validate.js +364 -0
  77. package/dist/node/core/config.js +181 -0
  78. package/dist/node/core/dependency-resolver.js +151 -0
  79. package/dist/node/core/feature-merger.js +139 -0
  80. package/dist/node/core/index.js +924 -0
  81. package/dist/node/core/lockfile.js +72 -0
  82. package/dist/node/core/metarepo.js +218 -0
  83. package/dist/node/core/pack-loader.js +646 -0
  84. package/dist/node/exporters/cursor-plugin.js +258 -0
  85. package/dist/node/exporters/index.js +258 -0
  86. package/dist/node/features/agents.js +190 -0
  87. package/dist/node/features/commands.js +190 -0
  88. package/dist/node/features/hooks.js +182 -0
  89. package/dist/node/features/ignore.js +72 -0
  90. package/dist/node/features/index.js +426 -0
  91. package/dist/node/features/mcp.js +172 -0
  92. package/dist/node/features/plugins.js +168 -0
  93. package/dist/node/features/rules.js +198 -0
  94. package/dist/node/features/skills.js +198 -0
  95. package/dist/node/importers/claude-code.js +224 -0
  96. package/dist/node/importers/cursor.js +288 -0
  97. package/dist/node/importers/opencode.js +261 -0
  98. package/dist/node/importers/rulesync.js +280 -0
  99. package/dist/node/index.js +3464 -0
  100. package/dist/node/sources/git-ref.js +79 -0
  101. package/dist/node/sources/git.js +245 -0
  102. package/dist/node/sources/index.js +416 -0
  103. package/dist/node/sources/local.js +52 -0
  104. package/dist/node/sources/npm-ref.js +84 -0
  105. package/dist/node/sources/npm.js +211 -0
  106. package/dist/node/targets/additional-targets.js +428 -0
  107. package/dist/node/targets/agents-md.js +239 -0
  108. package/dist/node/targets/base-target.js +51 -0
  109. package/dist/node/targets/claude-code.js +490 -0
  110. package/dist/node/targets/codex-cli.js +297 -0
  111. package/dist/node/targets/copilot.js +390 -0
  112. package/dist/node/targets/cursor.js +441 -0
  113. package/dist/node/targets/gemini-cli.js +352 -0
  114. package/dist/node/targets/generic-md-target.js +319 -0
  115. package/dist/node/targets/index.js +1351 -0
  116. package/dist/node/targets/opencode.js +556 -0
  117. package/dist/node/targets/registry.js +1343 -0
  118. package/dist/node/utils/diff.js +144 -0
  119. package/dist/node/utils/filesystem.js +152 -0
  120. package/dist/node/utils/frontmatter.js +52 -0
  121. package/dist/node/utils/global.js +81 -0
  122. package/dist/node/utils/markdown.js +62 -0
  123. package/dist/sources/git-ref.d.ts +27 -0
  124. package/dist/sources/git-ref.js +79 -0
  125. package/dist/sources/git.d.ts +29 -0
  126. package/dist/sources/git.js +245 -0
  127. package/dist/sources/index.d.ts +5 -0
  128. package/dist/sources/index.js +416 -0
  129. package/dist/sources/local.d.ts +8 -0
  130. package/dist/sources/local.js +52 -0
  131. package/dist/sources/npm-ref.d.ts +30 -0
  132. package/dist/sources/npm-ref.js +84 -0
  133. package/dist/sources/npm.d.ts +20 -0
  134. package/dist/sources/npm.js +211 -0
  135. package/dist/targets/additional-targets.d.ts +65 -0
  136. package/dist/targets/additional-targets.js +428 -0
  137. package/dist/targets/agents-md.d.ts +13 -0
  138. package/dist/targets/agents-md.js +239 -0
  139. package/dist/targets/base-target.d.ts +61 -0
  140. package/dist/targets/base-target.js +51 -0
  141. package/dist/targets/claude-code.d.ts +13 -0
  142. package/dist/targets/claude-code.js +490 -0
  143. package/dist/targets/codex-cli.d.ts +12 -0
  144. package/dist/targets/codex-cli.js +297 -0
  145. package/dist/targets/copilot.d.ts +12 -0
  146. package/dist/targets/copilot.js +390 -0
  147. package/dist/targets/cursor.d.ts +13 -0
  148. package/dist/targets/cursor.js +441 -0
  149. package/dist/targets/gemini-cli.d.ts +12 -0
  150. package/dist/targets/gemini-cli.js +352 -0
  151. package/dist/targets/generic-md-target.d.ts +25 -0
  152. package/dist/targets/generic-md-target.js +319 -0
  153. package/dist/targets/index.d.ts +9 -0
  154. package/dist/targets/index.js +1351 -0
  155. package/dist/targets/opencode.d.ts +13 -0
  156. package/dist/targets/opencode.js +556 -0
  157. package/dist/targets/registry.d.ts +17 -0
  158. package/dist/targets/registry.js +1343 -0
  159. package/dist/utils/diff.d.ts +13 -0
  160. package/dist/utils/diff.js +144 -0
  161. package/dist/utils/filesystem.d.ts +49 -0
  162. package/dist/utils/filesystem.js +152 -0
  163. package/dist/utils/frontmatter.d.ts +19 -0
  164. package/dist/utils/frontmatter.js +52 -0
  165. package/dist/utils/global.d.ts +17 -0
  166. package/dist/utils/global.js +81 -0
  167. package/dist/utils/markdown.d.ts +20 -0
  168. package/dist/utils/markdown.js +62 -0
  169. package/package.json +808 -0
  170. package/templates/pack/pack.json +10 -0
  171. package/templates/pack/rules/overview.md +22 -0
  172. package/templates/workspace/agentpacks.jsonc +34 -0
@@ -0,0 +1,610 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
+ var __require = import.meta.require;
31
+
32
+ // src/core/config.ts
33
+ var exports_config = {};
34
+ __export(exports_config, {
35
+ resolveTargets: () => resolveTargets,
36
+ resolveFeatures: () => resolveFeatures,
37
+ loadWorkspaceConfig: () => loadWorkspaceConfig,
38
+ loadPackManifest: () => loadPackManifest,
39
+ WorkspaceConfigSchema: () => WorkspaceConfigSchema,
40
+ TARGET_IDS: () => TARGET_IDS,
41
+ REPO_MODES: () => REPO_MODES,
42
+ PackManifestSchema: () => PackManifestSchema,
43
+ FEATURE_IDS: () => FEATURE_IDS
44
+ });
45
+ import { z } from "zod";
46
+ import { readFileSync, existsSync } from "fs";
47
+ import { resolve } from "path";
48
+ import { parse as parseJsonc } from "jsonc-parser";
49
+ function loadWorkspaceConfig(projectRoot) {
50
+ for (const filename of CONFIG_FILES) {
51
+ const filepath = resolve(projectRoot, filename);
52
+ if (existsSync(filepath)) {
53
+ const raw = readFileSync(filepath, "utf-8");
54
+ const parsed = parseJsonc(raw);
55
+ return WorkspaceConfigSchema.parse(parsed);
56
+ }
57
+ }
58
+ return WorkspaceConfigSchema.parse({});
59
+ }
60
+ function loadPackManifest(packDir) {
61
+ const filepath = resolve(packDir, "pack.json");
62
+ if (!existsSync(filepath)) {
63
+ const dirName = packDir.split("/").pop() ?? "unknown";
64
+ return PackManifestSchema.parse({ name: dirName });
65
+ }
66
+ const raw = readFileSync(filepath, "utf-8");
67
+ const parsed = JSON.parse(raw);
68
+ return PackManifestSchema.parse(parsed);
69
+ }
70
+ function resolveFeatures(config, targetId) {
71
+ const { features } = config;
72
+ if (features === "*") {
73
+ return [...FEATURE_IDS];
74
+ }
75
+ if (Array.isArray(features)) {
76
+ if (features.includes("*"))
77
+ return [...FEATURE_IDS];
78
+ return features.filter((f) => FEATURE_IDS.includes(f));
79
+ }
80
+ const targetFeatures = features[targetId];
81
+ if (!targetFeatures)
82
+ return [];
83
+ if (targetFeatures === "*")
84
+ return [...FEATURE_IDS];
85
+ if (Array.isArray(targetFeatures) && targetFeatures.includes("*"))
86
+ return [...FEATURE_IDS];
87
+ return targetFeatures.filter((f) => FEATURE_IDS.includes(f));
88
+ }
89
+ function resolveTargets(config) {
90
+ if (config.targets === "*")
91
+ return [...TARGET_IDS];
92
+ return config.targets;
93
+ }
94
+ var TARGET_IDS, FEATURE_IDS, REPO_MODES, PackManifestSchema, FeaturesSchema, WorkspaceConfigSchema, CONFIG_FILES;
95
+ var init_config = __esm(() => {
96
+ TARGET_IDS = [
97
+ "opencode",
98
+ "cursor",
99
+ "claudecode",
100
+ "codexcli",
101
+ "geminicli",
102
+ "copilot",
103
+ "agentsmd",
104
+ "cline",
105
+ "kilo",
106
+ "roo",
107
+ "qwencode",
108
+ "kiro",
109
+ "factorydroid",
110
+ "antigravity",
111
+ "junie",
112
+ "augmentcode",
113
+ "windsurf",
114
+ "warp",
115
+ "replit",
116
+ "zed"
117
+ ];
118
+ FEATURE_IDS = [
119
+ "rules",
120
+ "commands",
121
+ "agents",
122
+ "skills",
123
+ "hooks",
124
+ "plugins",
125
+ "mcp",
126
+ "ignore"
127
+ ];
128
+ REPO_MODES = ["repo", "monorepo", "metarepo"];
129
+ PackManifestSchema = z.object({
130
+ name: z.string().min(1),
131
+ version: z.string().default("1.0.0"),
132
+ description: z.string().default(""),
133
+ author: z.union([
134
+ z.string(),
135
+ z.object({ name: z.string(), email: z.string().optional() })
136
+ ]).optional(),
137
+ tags: z.array(z.string()).default([]),
138
+ dependencies: z.array(z.string()).default([]),
139
+ conflicts: z.array(z.string()).default([]),
140
+ targets: z.union([z.literal("*"), z.array(z.string())]).default("*"),
141
+ features: z.union([z.literal("*"), z.array(z.string())]).default("*")
142
+ });
143
+ FeaturesSchema = z.union([
144
+ z.literal("*"),
145
+ z.array(z.string()),
146
+ z.record(z.string(), z.union([z.literal("*"), z.array(z.string())]))
147
+ ]);
148
+ WorkspaceConfigSchema = z.object({
149
+ $schema: z.string().optional(),
150
+ packs: z.array(z.string()).default(["./packs/default"]),
151
+ disabled: z.array(z.string()).default([]),
152
+ targets: z.union([z.literal("*"), z.array(z.string())]).default("*"),
153
+ features: FeaturesSchema.default("*"),
154
+ mode: z.enum(REPO_MODES).default("repo"),
155
+ baseDirs: z.array(z.string()).default(["."]),
156
+ global: z.boolean().default(false),
157
+ delete: z.boolean().default(true),
158
+ verbose: z.boolean().default(false),
159
+ silent: z.boolean().default(false),
160
+ overrides: z.record(z.string(), z.record(z.string(), z.string())).default({}),
161
+ sources: z.array(z.object({
162
+ source: z.string(),
163
+ packs: z.array(z.string()).optional(),
164
+ skills: z.array(z.string()).optional()
165
+ })).default([])
166
+ });
167
+ CONFIG_FILES = ["agentpacks.local.jsonc", "agentpacks.jsonc"];
168
+ });
169
+
170
+ // src/core/lockfile.ts
171
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
172
+ import { resolve as resolve2 } from "path";
173
+ import { createHash } from "crypto";
174
+ var LOCKFILE_VERSION = 1;
175
+ var LOCKFILE_NAME = "agentpacks.lock";
176
+ function loadLockfile(projectRoot) {
177
+ const filepath = resolve2(projectRoot, LOCKFILE_NAME);
178
+ if (!existsSync2(filepath)) {
179
+ return { lockfileVersion: LOCKFILE_VERSION, sources: {} };
180
+ }
181
+ const raw = readFileSync2(filepath, "utf-8");
182
+ return JSON.parse(raw);
183
+ }
184
+ function saveLockfile(projectRoot, lockfile) {
185
+ const filepath = resolve2(projectRoot, LOCKFILE_NAME);
186
+ writeFileSync(filepath, JSON.stringify(lockfile, null, 2) + `
187
+ `);
188
+ }
189
+ function getLockedSource(lockfile, sourceKey) {
190
+ return lockfile.sources[sourceKey];
191
+ }
192
+ function setLockedSource(lockfile, sourceKey, entry) {
193
+ lockfile.sources[sourceKey] = entry;
194
+ }
195
+ function computeIntegrity(content) {
196
+ const hash = createHash("sha256").update(content).digest("hex");
197
+ return `sha256-${hash}`;
198
+ }
199
+ function isLockfileFrozenValid(lockfile, sourceKeys) {
200
+ const missing = sourceKeys.filter((key) => !(key in lockfile.sources));
201
+ return { valid: missing.length === 0, missing };
202
+ }
203
+
204
+ // src/sources/local.ts
205
+ import { existsSync as existsSync3 } from "fs";
206
+ import { resolve as resolve3, isAbsolute } from "path";
207
+ function resolveLocalPack(packRef, projectRoot) {
208
+ let resolved;
209
+ if (isAbsolute(packRef)) {
210
+ resolved = packRef;
211
+ } else {
212
+ resolved = resolve3(projectRoot, packRef);
213
+ }
214
+ if (!existsSync3(resolved))
215
+ return null;
216
+ return resolved;
217
+ }
218
+ function isLocalPackRef(packRef) {
219
+ return packRef.startsWith("./") || packRef.startsWith("../") || isAbsolute(packRef);
220
+ }
221
+
222
+ // src/sources/git-ref.ts
223
+ function parseGitSourceRef(source) {
224
+ let s = source;
225
+ if (s.startsWith("github:")) {
226
+ s = s.slice(7);
227
+ }
228
+ let path = "";
229
+ const atIdx = s.indexOf("@");
230
+ const colonIdx = s.indexOf(":", atIdx > -1 ? atIdx : 0);
231
+ if (colonIdx > -1) {
232
+ path = s.slice(colonIdx + 1);
233
+ s = s.slice(0, colonIdx);
234
+ }
235
+ let ref = "main";
236
+ if (atIdx > -1) {
237
+ ref = s.slice(atIdx + 1);
238
+ s = s.slice(0, atIdx);
239
+ }
240
+ const parts = s.split("/");
241
+ if (parts.length < 2) {
242
+ throw new Error(`Invalid git source reference: "${source}". Expected owner/repo format.`);
243
+ }
244
+ return {
245
+ owner: parts[0],
246
+ repo: parts[1],
247
+ ref,
248
+ path: path || ""
249
+ };
250
+ }
251
+ function isGitPackRef(packRef) {
252
+ if (packRef.startsWith("github:"))
253
+ return true;
254
+ if (packRef.startsWith("./") || packRef.startsWith("../") || packRef.startsWith("/")) {
255
+ return false;
256
+ }
257
+ if (packRef.startsWith("@") || packRef.startsWith("npm:"))
258
+ return false;
259
+ const parts = packRef.split("/");
260
+ return parts.length === 2 && !packRef.includes("node_modules");
261
+ }
262
+ function gitSourceKey(parsed) {
263
+ return `${parsed.owner}/${parsed.repo}`;
264
+ }
265
+
266
+ // src/sources/npm-ref.ts
267
+ function parseNpmSourceRef(source) {
268
+ let s = source;
269
+ if (s.startsWith("npm:")) {
270
+ s = s.slice(4);
271
+ }
272
+ let path = "";
273
+ const pathColonIdx = findPathColon(s);
274
+ if (pathColonIdx > -1) {
275
+ path = s.slice(pathColonIdx + 1);
276
+ s = s.slice(0, pathColonIdx);
277
+ }
278
+ let version = "latest";
279
+ const versionAtIdx = findVersionAt(s);
280
+ if (versionAtIdx > -1) {
281
+ version = s.slice(versionAtIdx + 1);
282
+ s = s.slice(0, versionAtIdx);
283
+ }
284
+ if (!s) {
285
+ throw new Error(`Invalid npm source reference: "${source}". Expected package name.`);
286
+ }
287
+ return { packageName: s, version, path };
288
+ }
289
+ function findPathColon(s) {
290
+ const startAfter = s.startsWith("@") ? s.indexOf("/") + 1 : 0;
291
+ const vAt = findVersionAt(s);
292
+ const searchFrom = vAt > -1 ? vAt : startAfter;
293
+ return s.indexOf(":", searchFrom);
294
+ }
295
+ function findVersionAt(s) {
296
+ if (s.startsWith("@")) {
297
+ const slashIdx = s.indexOf("/");
298
+ if (slashIdx === -1)
299
+ return -1;
300
+ return s.indexOf("@", slashIdx + 1);
301
+ }
302
+ return s.indexOf("@");
303
+ }
304
+ function isNpmPackRef(packRef) {
305
+ if (packRef.startsWith("npm:"))
306
+ return true;
307
+ if (packRef.startsWith("@") && packRef.includes("/"))
308
+ return true;
309
+ return false;
310
+ }
311
+ function npmSourceKey(parsed) {
312
+ return `npm:${parsed.packageName}`;
313
+ }
314
+
315
+ // src/sources/git.ts
316
+ import { mkdirSync, writeFileSync as writeFileSync2 } from "fs";
317
+ import { resolve as resolve4, join } from "path";
318
+ var GITHUB_API = "https://api.github.com";
319
+ function githubHeaders(token) {
320
+ const h = {
321
+ Accept: "application/vnd.github.v3+json",
322
+ "User-Agent": "agentpacks"
323
+ };
324
+ if (token)
325
+ h.Authorization = `token ${token}`;
326
+ return h;
327
+ }
328
+ async function resolveGitRef(parsed, token) {
329
+ const base = `${GITHUB_API}/repos/${parsed.owner}/${parsed.repo}/git/ref`;
330
+ const res = await fetch(`${base}/heads/${parsed.ref}`, {
331
+ headers: githubHeaders(token)
332
+ });
333
+ if (!res.ok) {
334
+ const tagRes = await fetch(`${base}/tags/${parsed.ref}`, {
335
+ headers: githubHeaders(token)
336
+ });
337
+ if (!tagRes.ok) {
338
+ throw new Error(`Could not resolve ref "${parsed.ref}" for ${parsed.owner}/${parsed.repo}: ${res.status}`);
339
+ }
340
+ const tagData = await tagRes.json();
341
+ return tagData.object.sha;
342
+ }
343
+ const data = await res.json();
344
+ return data.object.sha;
345
+ }
346
+ async function fetchGitDirectory(parsed, sha, subpath, token) {
347
+ const path = parsed.path ? `${parsed.path}/${subpath}` : subpath;
348
+ const url = `${GITHUB_API}/repos/${parsed.owner}/${parsed.repo}/contents/${path}?ref=${sha}`;
349
+ const res = await fetch(url, { headers: githubHeaders(token) });
350
+ if (!res.ok)
351
+ return [];
352
+ return await res.json();
353
+ }
354
+ async function fetchGitFile(downloadUrl, token) {
355
+ const headers = { "User-Agent": "agentpacks" };
356
+ if (token)
357
+ headers.Authorization = `token ${token}`;
358
+ const res = await fetch(downloadUrl, { headers });
359
+ if (!res.ok) {
360
+ throw new Error(`Failed to fetch ${downloadUrl}: ${res.status}`);
361
+ }
362
+ return res.text();
363
+ }
364
+ async function fetchAndWriteSubdir(parsed, sha, remotePath, localDir, installed, token) {
365
+ mkdirSync(localDir, { recursive: true });
366
+ const entries = await fetchGitDirectory(parsed, sha, remotePath, token);
367
+ for (const entry of entries) {
368
+ if (entry.type === "file" && entry.download_url) {
369
+ const content = await fetchGitFile(entry.download_url, token);
370
+ const filepath = join(localDir, entry.name);
371
+ writeFileSync2(filepath, content);
372
+ installed.push(filepath);
373
+ } else if (entry.type === "dir") {
374
+ await fetchAndWriteSubdir(parsed, sha, `${remotePath}/${entry.name}`, join(localDir, entry.name), installed, token);
375
+ }
376
+ }
377
+ }
378
+ async function installGitSource(projectRoot, source, lockfile, options = {}) {
379
+ const parsed = parseGitSourceRef(source);
380
+ const sourceKey = gitSourceKey(parsed);
381
+ const installed = [];
382
+ const warnings = [];
383
+ let resolvedSha;
384
+ const locked = getLockedSource(lockfile, sourceKey);
385
+ if (options.frozen && !locked) {
386
+ throw new Error(`Frozen mode: no lockfile entry for source "${sourceKey}".`);
387
+ }
388
+ if (locked && !options.update) {
389
+ resolvedSha = locked.resolvedRef;
390
+ } else {
391
+ resolvedSha = await resolveGitRef(parsed, options.token);
392
+ }
393
+ const basePath = parsed.path || "packs";
394
+ const entries = await fetchGitDirectory(parsed, resolvedSha, basePath, options.token);
395
+ const curatedDir = resolve4(projectRoot, ".agentpacks", ".curated");
396
+ mkdirSync(curatedDir, { recursive: true });
397
+ const newLockEntry = {
398
+ requestedRef: parsed.ref,
399
+ resolvedRef: resolvedSha,
400
+ resolvedAt: new Date().toISOString(),
401
+ skills: {},
402
+ packs: {}
403
+ };
404
+ const packDirs = entries.filter((e) => e.type === "dir");
405
+ for (const packEntry of packDirs) {
406
+ const packName = packEntry.name;
407
+ const packOutDir = resolve4(curatedDir, packName);
408
+ const packFiles = await fetchGitDirectory(parsed, resolvedSha, `${basePath}/${packName}`, options.token);
409
+ mkdirSync(packOutDir, { recursive: true });
410
+ for (const file of packFiles) {
411
+ if (file.type === "file" && file.download_url) {
412
+ const content = await fetchGitFile(file.download_url, options.token);
413
+ writeFileSync2(join(packOutDir, file.name), content);
414
+ installed.push(join(packOutDir, file.name));
415
+ if (newLockEntry.packs) {
416
+ newLockEntry.packs[packName] = {
417
+ integrity: computeIntegrity(content)
418
+ };
419
+ }
420
+ } else if (file.type === "dir") {
421
+ await fetchAndWriteSubdir(parsed, resolvedSha, `${basePath}/${packName}/${file.name}`, join(packOutDir, file.name), installed, options.token);
422
+ }
423
+ }
424
+ }
425
+ if (packDirs.length === 0) {
426
+ const fileEntries = entries.filter((e) => e.type === "file");
427
+ if (fileEntries.length > 0) {
428
+ const packName = parsed.path.split("/").pop() ?? parsed.repo;
429
+ const packOutDir = resolve4(curatedDir, packName);
430
+ mkdirSync(packOutDir, { recursive: true });
431
+ for (const file of entries) {
432
+ if (file.type === "file" && file.download_url) {
433
+ const content = await fetchGitFile(file.download_url, options.token);
434
+ writeFileSync2(join(packOutDir, file.name), content);
435
+ installed.push(join(packOutDir, file.name));
436
+ } else if (file.type === "dir") {
437
+ await fetchAndWriteSubdir(parsed, resolvedSha, `${basePath}/${file.name}`, join(packOutDir, file.name), installed, options.token);
438
+ }
439
+ }
440
+ }
441
+ }
442
+ setLockedSource(lockfile, sourceKey, newLockEntry);
443
+ return { installed, warnings };
444
+ }
445
+
446
+ // src/sources/npm.ts
447
+ import { mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
448
+ import { resolve as resolve5, join as join2 } from "path";
449
+ import { execSync } from "child_process";
450
+ var NPM_REGISTRY = "https://registry.npmjs.org";
451
+ async function resolveNpmVersion(parsed) {
452
+ const url = `${NPM_REGISTRY}/${encodeURIComponent(parsed.packageName)}/${parsed.version}`;
453
+ const res = await fetch(url, {
454
+ headers: { Accept: "application/json" }
455
+ });
456
+ if (!res.ok) {
457
+ throw new Error(`Could not resolve npm package "${parsed.packageName}@${parsed.version}": ${res.status}`);
458
+ }
459
+ const data = await res.json();
460
+ return { version: data.version, tarball: data.dist.tarball };
461
+ }
462
+ async function installNpmSource(projectRoot, source, lockfile, options = {}) {
463
+ const parsed = parseNpmSourceRef(source);
464
+ const sourceKey = npmSourceKey(parsed);
465
+ const installed = [];
466
+ const warnings = [];
467
+ const locked = getLockedSource(lockfile, sourceKey);
468
+ if (options.frozen && !locked) {
469
+ throw new Error(`Frozen mode: no lockfile entry for source "${sourceKey}".`);
470
+ }
471
+ let resolvedVersion;
472
+ let tarballUrl;
473
+ if (locked && !options.update) {
474
+ resolvedVersion = locked.resolvedRef;
475
+ tarballUrl = "";
476
+ } else {
477
+ const resolved = await resolveNpmVersion(parsed);
478
+ resolvedVersion = resolved.version;
479
+ tarballUrl = resolved.tarball;
480
+ }
481
+ const curatedDir = resolve5(projectRoot, ".agentpacks", ".curated");
482
+ mkdirSync2(curatedDir, { recursive: true });
483
+ const packDir = extractNpmPack(parsed, resolvedVersion, curatedDir, installed, warnings);
484
+ const newEntry = {
485
+ requestedRef: parsed.version,
486
+ resolvedRef: resolvedVersion,
487
+ resolvedAt: new Date().toISOString(),
488
+ skills: {},
489
+ packs: {}
490
+ };
491
+ setLockedSource(lockfile, sourceKey, newEntry);
492
+ return { installed, warnings };
493
+ }
494
+ function extractNpmPack(parsed, version, curatedDir, installed, warnings) {
495
+ const pkgSpec = `${parsed.packageName}@${version}`;
496
+ const packName = parsed.packageName.replace(/^@/, "").replace(/\//g, "-");
497
+ const packOutDir = resolve5(curatedDir, packName);
498
+ try {
499
+ const tmpDir = resolve5(curatedDir, ".tmp-npm");
500
+ mkdirSync2(tmpDir, { recursive: true });
501
+ execSync(`npm pack ${pkgSpec} --pack-destination "${tmpDir}"`, {
502
+ stdio: "pipe",
503
+ timeout: 30000
504
+ });
505
+ const tgzFiles = __require("fs").readdirSync(tmpDir).filter((f) => f.endsWith(".tgz"));
506
+ if (tgzFiles.length === 0) {
507
+ warnings.push(`No tarball found for ${pkgSpec}`);
508
+ return packOutDir;
509
+ }
510
+ const tgzPath = join2(tmpDir, tgzFiles[0]);
511
+ mkdirSync2(packOutDir, { recursive: true });
512
+ execSync(`tar xzf "${tgzPath}" -C "${packOutDir}" --strip-components=1`, {
513
+ stdio: "pipe",
514
+ timeout: 15000
515
+ });
516
+ execSync(`rm -rf "${tmpDir}"`, { stdio: "pipe" });
517
+ const subpath = parsed.path || "";
518
+ const targetDir = subpath ? join2(packOutDir, subpath) : packOutDir;
519
+ if (existsSync4(targetDir)) {
520
+ collectFiles(targetDir, installed);
521
+ }
522
+ } catch (err) {
523
+ warnings.push(`Failed to extract npm pack ${pkgSpec}: ${err instanceof Error ? err.message : String(err)}`);
524
+ }
525
+ return packOutDir;
526
+ }
527
+ function collectFiles(dir, out) {
528
+ const fs = __require("fs");
529
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
530
+ for (const entry of entries) {
531
+ const full = join2(dir, entry.name);
532
+ if (entry.isDirectory()) {
533
+ collectFiles(full, out);
534
+ } else {
535
+ out.push(full);
536
+ }
537
+ }
538
+ }
539
+
540
+ // src/cli/install.ts
541
+ init_config();
542
+ import chalk from "chalk";
543
+ async function runInstall(projectRoot, options) {
544
+ const config = loadWorkspaceConfig(projectRoot);
545
+ const lockfile = loadLockfile(projectRoot);
546
+ const verbose = options.verbose ?? config.verbose;
547
+ const remotePacks = config.packs.filter((ref) => isGitPackRef(ref) || isNpmPackRef(ref));
548
+ const localPacks = config.packs.filter((ref) => isLocalPackRef(ref));
549
+ if (remotePacks.length === 0) {
550
+ console.log(chalk.dim("No remote packs to install. All packs are local."));
551
+ return;
552
+ }
553
+ if (verbose) {
554
+ console.log(chalk.dim(`Found ${remotePacks.length} remote pack(s) to install`));
555
+ console.log(chalk.dim(` (${localPacks.length} local pack(s) skipped)`));
556
+ }
557
+ if (options.frozen) {
558
+ const sourceKeys = remotePacks.map((ref) => ref);
559
+ const frozenCheck = isLockfileFrozenValid(lockfile, sourceKeys);
560
+ if (!frozenCheck.valid) {
561
+ console.log(chalk.red(`Frozen install failed. Missing lockfile entries: ${frozenCheck.missing.join(", ")}`));
562
+ process.exit(1);
563
+ }
564
+ }
565
+ let totalInstalled = 0;
566
+ const allWarnings = [];
567
+ for (const packRef of remotePacks) {
568
+ if (verbose) {
569
+ console.log(chalk.dim(` Installing ${packRef}...`));
570
+ }
571
+ try {
572
+ let result;
573
+ if (isGitPackRef(packRef)) {
574
+ const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN ?? undefined;
575
+ result = await installGitSource(projectRoot, packRef, lockfile, {
576
+ update: options.update,
577
+ frozen: options.frozen,
578
+ token
579
+ });
580
+ } else if (isNpmPackRef(packRef)) {
581
+ result = await installNpmSource(projectRoot, packRef, lockfile, {
582
+ update: options.update,
583
+ frozen: options.frozen
584
+ });
585
+ } else {
586
+ continue;
587
+ }
588
+ totalInstalled += result.installed.length;
589
+ allWarnings.push(...result.warnings);
590
+ if (verbose && result.installed.length > 0) {
591
+ console.log(chalk.dim(` ${result.installed.length} file(s) installed`));
592
+ }
593
+ } catch (err) {
594
+ const msg = err instanceof Error ? err.message : String(err);
595
+ console.log(chalk.red(` error [${packRef}]: ${msg}`));
596
+ allWarnings.push(`Failed to install ${packRef}: ${msg}`);
597
+ }
598
+ }
599
+ for (const w of allWarnings) {
600
+ console.log(chalk.yellow(` warn: ${w}`));
601
+ }
602
+ saveLockfile(projectRoot, lockfile);
603
+ console.log(chalk.green(`Installed ${totalInstalled} file(s) from ${remotePacks.length} source(s)`));
604
+ if (verbose) {
605
+ console.log(chalk.dim("Lockfile updated: agentpacks.lock"));
606
+ }
607
+ }
608
+ export {
609
+ runInstall
610
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Create a new pack scaffold.
3
+ */
4
+ export declare function runPackCreate(projectRoot: string, name: string): void;