@comet/cli 9.0.0-beta.2 → 9.0.0-beta.4

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.
@@ -116,7 +116,7 @@ exports.injectSiteConfigsCommand = new commander_1.Command("inject-site-configs"
116
116
  .option("--base64", "use base64 encoding")
117
117
  .option("-f, --site-config-file <file>", "Path to ts-file which provides a default export with (env: string) => SiteConfig[]")
118
118
  .action(function (options) { return __awaiter(void 0, void 0, void 0, function () {
119
- var configFile, getSiteConfigs, str, getUrlFromDomain, replacerFunctions;
119
+ var configFile, getSiteConfigs, siteConfigsCache, getCachedSiteConfigs, str, getUrlFromDomain, replacerFunctions;
120
120
  return __generator(this, function (_a) {
121
121
  switch (_a.label) {
122
122
  case 0:
@@ -124,6 +124,23 @@ exports.injectSiteConfigsCommand = new commander_1.Command("inject-site-configs"
124
124
  return [4 /*yield*/, Promise.resolve("".concat(configFile)).then(function (s) { return __importStar(require(s)); })];
125
125
  case 1:
126
126
  getSiteConfigs = (_a.sent()).default;
127
+ siteConfigsCache = new Map();
128
+ getCachedSiteConfigs = function (env) { return __awaiter(void 0, void 0, void 0, function () {
129
+ var cached;
130
+ return __generator(this, function (_a) {
131
+ switch (_a.label) {
132
+ case 0:
133
+ cached = siteConfigsCache.get(env);
134
+ if (!!cached) return [3 /*break*/, 2];
135
+ return [4 /*yield*/, getSiteConfigs(env)];
136
+ case 1:
137
+ cached = _a.sent();
138
+ siteConfigsCache.set(env, cached);
139
+ _a.label = 2;
140
+ case 2: return [2 /*return*/, cached];
141
+ }
142
+ });
143
+ }); };
127
144
  console.log("inject-site-configs: Replace site-configs in ".concat(options.inFile));
128
145
  str = fs_1.default.readFileSync((0, path_1.resolve)(process.cwd(), options.inFile)).toString();
129
146
  getUrlFromDomain = function (domain) {
@@ -151,7 +168,7 @@ exports.injectSiteConfigsCommand = new commander_1.Command("inject-site-configs"
151
168
  var siteConfigs, ret;
152
169
  return __generator(this, function (_a) {
153
170
  switch (_a.label) {
154
- case 0: return [4 /*yield*/, getSiteConfigs(env)];
171
+ case 0: return [4 /*yield*/, getCachedSiteConfigs(env)];
155
172
  case 1:
156
173
  siteConfigs = _a.sent();
157
174
  console.log("inject-site-configs: - ".concat(substr, " (").concat(siteConfigs.length, " sites)"));
@@ -175,7 +192,7 @@ exports.injectSiteConfigsCommand = new commander_1.Command("inject-site-configs"
175
192
  var siteConfigs, filteredSiteConfigs;
176
193
  return __generator(this, function (_a) {
177
194
  switch (_a.label) {
178
- case 0: return [4 /*yield*/, getSiteConfigs(env)];
195
+ case 0: return [4 /*yield*/, getCachedSiteConfigs(env)];
179
196
  case 1:
180
197
  siteConfigs = _a.sent();
181
198
  console.log("inject-site-domains: - ".concat(substr, " (").concat(siteConfigs.length, " sites)"));
@@ -199,8 +216,9 @@ exports.injectSiteConfigsCommand = new commander_1.Command("inject-site-configs"
199
216
  }); });
200
217
  var resolveOpReferences = function (input) {
201
218
  var opRefs = input.match(/\{\{ op:\/\/[^ }]+ \}\}/g);
202
- if (!opRefs)
219
+ if (!opRefs) {
203
220
  return input;
221
+ }
204
222
  try {
205
223
  (0, child_process_1.execSync)("op --version", { stdio: "ignore" });
206
224
  }
@@ -208,12 +226,17 @@ var resolveOpReferences = function (input) {
208
226
  throw new Error("inject-site-configs: Config contains 1Password references (op://) but the 1Password CLI (op) is not installed. " +
209
227
  "Install from https://developer.1password.com/docs/cli/");
210
228
  }
229
+ var opCache = new Map();
211
230
  var result = input;
212
231
  for (var _i = 0, opRefs_1 = opRefs; _i < opRefs_1.length; _i++) {
213
232
  var ref = opRefs_1[_i];
214
233
  var opUri = ref.replace("{{ ", "").replace(" }}", "");
215
234
  try {
216
- var secret = (0, child_process_1.execSync)("op read \"".concat(opUri, "\""), { encoding: "utf-8" }).trim();
235
+ var secret = opCache.get(opUri);
236
+ if (!secret) {
237
+ secret = (0, child_process_1.execSync)("op read \"".concat(opUri, "\""), { encoding: "utf-8" }).trim();
238
+ opCache.set(opUri, secret);
239
+ }
217
240
  console.log("inject-site-configs: - Resolved ".concat(ref));
218
241
  result = result.replace(ref, secret);
219
242
  }
@@ -14,10 +14,12 @@ var mockedExecSync = vitest_1.vi.mocked(child_process_1.execSync);
14
14
  (0, vitest_1.describe)("resolveOpReferences", function () {
15
15
  (0, vitest_1.it)("should resolve op:// references", function () {
16
16
  mockedExecSync.mockImplementation(function (cmd) {
17
- if (cmd === "op --version")
17
+ if (cmd === "op --version") {
18
18
  return Buffer.from("2.0.0");
19
- if (cmd === 'op read "op://vault/item/password"')
19
+ }
20
+ if (cmd === 'op read "op://vault/item/password"') {
20
21
  return "resolved-secret\n";
22
+ }
21
23
  return "";
22
24
  });
23
25
  var result = (0, site_configs_1.resolveOpReferences)('{"key":"{{ op://vault/item/password }}"}');
@@ -31,8 +33,9 @@ var mockedExecSync = vitest_1.vi.mocked(child_process_1.execSync);
31
33
  });
32
34
  (0, vitest_1.it)("should throw an error when op reference resolution fails", function () {
33
35
  mockedExecSync.mockImplementation(function (cmd) {
34
- if (cmd === "op --version")
36
+ if (cmd === "op --version") {
35
37
  return Buffer.from("2.0.0");
38
+ }
36
39
  if (cmd === 'op read "op://vault/item/password"') {
37
40
  throw new Error("Item not found");
38
41
  }
@@ -42,14 +45,18 @@ var mockedExecSync = vitest_1.vi.mocked(child_process_1.execSync);
42
45
  });
43
46
  (0, vitest_1.it)("should resolve multiple op:// references", function () {
44
47
  mockedExecSync.mockImplementation(function (cmd) {
45
- if (cmd === "op --version")
48
+ if (cmd === "op --version") {
46
49
  return Buffer.from("2.0.0");
47
- if (cmd === 'op read "op://vault/item/api-key"')
50
+ }
51
+ if (cmd === 'op read "op://vault/item/api-key"') {
48
52
  return "resolved-api-key\n";
49
- if (cmd === 'op read "op://vault/item/api-secret"')
53
+ }
54
+ if (cmd === 'op read "op://vault/item/api-secret"') {
50
55
  return "resolved-api-secret\n";
51
- if (cmd === 'op read "op://vault/database/password"')
56
+ }
57
+ if (cmd === 'op read "op://vault/database/password"') {
52
58
  return "resolved-db-password\n";
59
+ }
53
60
  return "";
54
61
  });
55
62
  var result = (0, site_configs_1.resolveOpReferences)('{"apiKey":"{{ op://vault/item/api-key }}","apiSecret":"{{ op://vault/item/api-secret }}","dbPassword":"{{ op://vault/database/password }}"}');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comet/cli",
3
- "version": "9.0.0-beta.2",
3
+ "version": "9.0.0-beta.4",
4
4
  "description": "A collection of CLI tools for Comet projects",
5
5
  "repository": {
6
6
  "directory": "packages/cli",
@@ -14,25 +14,26 @@
14
14
  "bin": {
15
15
  "comet": "bin/comet.js"
16
16
  },
17
+ "sideEffects": false,
17
18
  "files": [
18
19
  "bin/**/*.js",
19
20
  "lib/*"
20
21
  ],
21
22
  "dependencies": {
22
23
  "commander": "^9.5.0",
23
- "js-yaml": "^4.1.0",
24
+ "js-yaml": "^4.1.1",
24
25
  "prettier": "^3.6.2",
25
26
  "ts-node": "^10.9.2"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/js-yaml": "^4.0.9",
29
- "@types/node": "^24.12.0",
30
- "eslint": "^9.39.2",
30
+ "@types/node": "^24.12.4",
31
+ "eslint": "^9.39.4",
31
32
  "npm-run-all2": "^8.0.4",
32
33
  "rimraf": "^6.1.2",
33
34
  "typescript": "^5.9.3",
34
35
  "vitest": "^4.0.16",
35
- "@comet/eslint-config": "9.0.0-beta.2"
36
+ "@comet/eslint-config": "9.0.0-beta.4"
36
37
  },
37
38
  "engines": {
38
39
  "node": ">=22.0.0"
@@ -1,15 +0,0 @@
1
- import { Command } from "commander";
2
- export interface SkillSource {
3
- label: string;
4
- directory: string;
5
- /** If true, create symlinks; if false, copy files (used for tmp clone dirs) */
6
- symlink: boolean;
7
- /** If true, skills with metadata.internal: true in their SKILL.md are excluded */
8
- filterInternal?: boolean;
9
- }
10
- export interface InstallOptions {
11
- dryRun: boolean;
12
- }
13
- export declare function isInternalSkill(skillFolderPath: string): boolean;
14
- export declare function installSkills(sources: SkillSource[], targetDirs: string[], { dryRun }: InstallOptions): void;
15
- export declare const installAgentSkillsCommand: Command;
@@ -1,244 +0,0 @@
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
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __generator = (this && this.__generator) || function (thisArg, body) {
45
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
46
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
47
- function verb(n) { return function (v) { return step([n, v]); }; }
48
- function step(op) {
49
- if (f) throw new TypeError("Generator is already executing.");
50
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
51
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
52
- if (y = 0, t) op = [op[0] & 2, t.value];
53
- switch (op[0]) {
54
- case 0: case 1: t = op; break;
55
- case 4: _.label++; return { value: op[1], done: false };
56
- case 5: _.label++; y = op[1]; op = [0]; continue;
57
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
58
- default:
59
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
60
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
61
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
62
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
63
- if (t[2]) _.ops.pop();
64
- _.trys.pop(); continue;
65
- }
66
- op = body.call(thisArg, _);
67
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
68
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
69
- }
70
- };
71
- Object.defineProperty(exports, "__esModule", { value: true });
72
- exports.installAgentSkillsCommand = void 0;
73
- exports.isInternalSkill = isInternalSkill;
74
- exports.installSkills = installSkills;
75
- /* eslint-disable no-console */
76
- var child_process_1 = require("child_process");
77
- var commander_1 = require("commander");
78
- var fs = __importStar(require("fs"));
79
- var yaml = __importStar(require("js-yaml"));
80
- var os = __importStar(require("os"));
81
- var path = __importStar(require("path"));
82
- function parseRepoUrl(rawUrl) {
83
- var hashIndex = rawUrl.lastIndexOf("#");
84
- if (hashIndex === -1) {
85
- return { repoUrl: rawUrl, ref: undefined };
86
- }
87
- return { repoUrl: rawUrl.slice(0, hashIndex), ref: rawUrl.slice(hashIndex + 1) || undefined };
88
- }
89
- function cloneRepo(rawUrl) {
90
- var _a = parseRepoUrl(rawUrl), repoUrl = _a.repoUrl, ref = _a.ref;
91
- var tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "comet-agent-skills-"));
92
- // Use sparse checkout to fetch only the skills/ folder
93
- (0, child_process_1.execFileSync)("git", ["init", tmpDir], { stdio: "pipe" });
94
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "remote", "add", "origin", "--", repoUrl], { stdio: "pipe" });
95
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "config", "core.sparseCheckout", "true"], { stdio: "pipe" });
96
- fs.writeFileSync(path.join(tmpDir, ".git", "info", "sparse-checkout"), "skills/\n");
97
- var fetchRef = ref !== null && ref !== void 0 ? ref : "HEAD";
98
- try {
99
- console.log("Fetching ".concat(repoUrl, " ref \"").concat(fetchRef, "\" (sparse, skills/ only)..."));
100
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "fetch", "--depth", "1", "origin", fetchRef], { stdio: "pipe" });
101
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "checkout", "FETCH_HEAD"], { stdio: "pipe" });
102
- }
103
- catch (_b) {
104
- console.log("Shallow fetch failed for ref \"".concat(fetchRef, "\"; falling back to full fetch..."));
105
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "fetch", "origin", fetchRef], { stdio: "pipe" });
106
- (0, child_process_1.execFileSync)("git", ["-C", tmpDir, "checkout", "FETCH_HEAD"], { stdio: "pipe" });
107
- }
108
- return tmpDir;
109
- }
110
- function pathExists(p) {
111
- try {
112
- fs.lstatSync(p);
113
- return true;
114
- }
115
- catch (_a) {
116
- return false;
117
- }
118
- }
119
- function isInternalSkill(skillFolderPath) {
120
- var _a;
121
- var skillMdPath = path.join(skillFolderPath, "SKILL.md");
122
- var skillMdContent;
123
- try {
124
- skillMdContent = fs.readFileSync(skillMdPath, "utf-8");
125
- }
126
- catch (_b) {
127
- return false;
128
- }
129
- var frontmatterMatch = skillMdContent.match(/^---\n([\s\S]*?)\n---/);
130
- if (!frontmatterMatch)
131
- return false;
132
- try {
133
- var parsed = yaml.load(frontmatterMatch[1]);
134
- return ((_a = parsed === null || parsed === void 0 ? void 0 : parsed.metadata) === null || _a === void 0 ? void 0 : _a.internal) === true;
135
- }
136
- catch (_c) {
137
- return false;
138
- }
139
- }
140
- function listSkillFolders(directory, filterInternal) {
141
- if (filterInternal === void 0) { filterInternal = false; }
142
- if (!fs.existsSync(directory))
143
- return [];
144
- return fs
145
- .readdirSync(directory)
146
- .filter(function (f) { return fs.statSync(path.join(directory, f)).isDirectory(); })
147
- .filter(function (folder) { return !filterInternal || !isInternalSkill(path.join(directory, folder)); })
148
- .sort();
149
- }
150
- function installSkills(sources, targetDirs, _a) {
151
- var dryRun = _a.dryRun;
152
- var installed = new Set();
153
- for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
154
- var _b = sources_1[_i], label = _b.label, directory = _b.directory, symlink = _b.symlink, filterInternal = _b.filterInternal;
155
- var folders = listSkillFolders(directory, filterInternal);
156
- if (folders.length === 0) {
157
- console.log("No skills found in ".concat(label));
158
- continue;
159
- }
160
- console.log("Installing ".concat(folders.length, " skill(s) from ").concat(label, "..."));
161
- for (var _c = 0, folders_1 = folders; _c < folders_1.length; _c++) {
162
- var folder = folders_1[_c];
163
- if (installed.has(folder)) {
164
- console.warn(" CONFLICT: \"".concat(folder, "\" from ").concat(label, " skipped (already installed from a higher-priority source)"));
165
- continue;
166
- }
167
- var srcPath = path.resolve(path.join(directory, folder));
168
- for (var _d = 0, targetDirs_1 = targetDirs; _d < targetDirs_1.length; _d++) {
169
- var targetDir = targetDirs_1[_d];
170
- var destPath = path.join(targetDir, folder);
171
- var exists = pathExists(destPath);
172
- if (dryRun) {
173
- console.log(" [dry-run] Would ".concat(symlink ? "symlink" : "copy", ": ").concat(srcPath, " -> ").concat(destPath));
174
- }
175
- else {
176
- if (exists)
177
- fs.rmSync(destPath, { recursive: true, force: true });
178
- if (symlink) {
179
- fs.symlinkSync(srcPath, destPath);
180
- }
181
- else {
182
- fs.cpSync(srcPath, destPath, { recursive: true });
183
- }
184
- console.log(" ".concat(symlink ? "Symlinked" : "Copied", ": ").concat(folder));
185
- }
186
- }
187
- installed.add(folder);
188
- }
189
- }
190
- console.log("\nTotal skills installed: ".concat(installed.size));
191
- }
192
- function loadConfig(configPath) {
193
- var resolved = path.resolve(configPath);
194
- if (!fs.existsSync(resolved)) {
195
- throw new Error("Config file not found: ".concat(resolved));
196
- }
197
- var raw = fs.readFileSync(resolved, "utf-8");
198
- return JSON.parse(raw);
199
- }
200
- exports.installAgentSkillsCommand = new commander_1.Command("install-agent-skills")
201
- .description("Install agent skills from local directories and optional external git repos")
202
- .option("--config <path>", "Path to a JSON config file specifying repos to install skills from", "agent-skills.json")
203
- .option("--dry-run", "Show which symlinks/copies would be created without making changes", false)
204
- .action(function (options) { return __awaiter(void 0, void 0, void 0, function () {
205
- var configPath, dryRun, resolvedConfig, repos, cwd, targetDirs, _i, targetDirs_2, dir, sources, tempDirs, _a, repos_1, rawUrl, cloneDir, _b, tempDirs_1, tmpDir;
206
- var _c;
207
- return __generator(this, function (_d) {
208
- configPath = options.config, dryRun = options.dryRun;
209
- resolvedConfig = path.resolve(configPath);
210
- repos = fs.existsSync(resolvedConfig) ? ((_c = loadConfig(configPath).repos) !== null && _c !== void 0 ? _c : []) : [];
211
- console.log("=== Installing agent skills".concat(dryRun ? " (dry run)" : "", " ==="));
212
- cwd = process.cwd();
213
- targetDirs = [path.join(cwd, ".agents", "skills"), path.join(cwd, ".claude", "skills")];
214
- // Ensure target directories exist (without clearing existing contents)
215
- for (_i = 0, targetDirs_2 = targetDirs; _i < targetDirs_2.length; _i++) {
216
- dir = targetDirs_2[_i];
217
- fs.mkdirSync(dir, { recursive: true });
218
- }
219
- sources = [{ label: "local skills/", directory: path.join(cwd, "skills"), symlink: true }];
220
- tempDirs = [];
221
- try {
222
- for (_a = 0, repos_1 = repos; _a < repos_1.length; _a++) {
223
- rawUrl = repos_1[_a];
224
- cloneDir = cloneRepo(rawUrl);
225
- tempDirs.push(cloneDir);
226
- sources.push({
227
- label: "external ".concat(rawUrl),
228
- directory: path.join(cloneDir, "skills"),
229
- symlink: false,
230
- filterInternal: true,
231
- });
232
- }
233
- installSkills(sources, targetDirs, { dryRun: dryRun });
234
- }
235
- finally {
236
- for (_b = 0, tempDirs_1 = tempDirs; _b < tempDirs_1.length; _b++) {
237
- tmpDir = tempDirs_1[_b];
238
- fs.rmSync(tmpDir, { recursive: true, force: true });
239
- }
240
- }
241
- console.log("=== Finished ===");
242
- return [2 /*return*/];
243
- });
244
- }); });