claudekit-cli 3.37.0-dev.4 → 3.37.0-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +872 -695
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12977,7 +12977,7 @@ async function installCodexToml(items, provider, portableType, options2) {
|
|
|
12977
12977
|
slug,
|
|
12978
12978
|
agentTomlPath,
|
|
12979
12979
|
sourcePath: item.sourcePath,
|
|
12980
|
-
sourceChecksum: await computeContentChecksum(
|
|
12980
|
+
sourceChecksum: await computeContentChecksum(result.content),
|
|
12981
12981
|
targetChecksum: await computeContentChecksum(result.content)
|
|
12982
12982
|
});
|
|
12983
12983
|
}
|
|
@@ -13157,6 +13157,204 @@ var init_codex_toml_installer = __esm(() => {
|
|
|
13157
13157
|
import_proper_lockfile2 = __toESM(require_proper_lockfile(), 1);
|
|
13158
13158
|
});
|
|
13159
13159
|
|
|
13160
|
+
// src/commands/portable/merge-single-sections.ts
|
|
13161
|
+
function isManagedHeadingLine(line) {
|
|
13162
|
+
return Object.values(SECTION_HEADING_PATTERNS).some((regex) => regex.test(line));
|
|
13163
|
+
}
|
|
13164
|
+
function findNextNonBlankLineIndex(lines, startIndex) {
|
|
13165
|
+
for (let index = startIndex;index < lines.length; index += 1) {
|
|
13166
|
+
if (lines[index].trim().length > 0) {
|
|
13167
|
+
return index;
|
|
13168
|
+
}
|
|
13169
|
+
}
|
|
13170
|
+
return -1;
|
|
13171
|
+
}
|
|
13172
|
+
function hasLaterManagedHeading(lines, startIndex) {
|
|
13173
|
+
let inFence = false;
|
|
13174
|
+
for (let index = startIndex;index < lines.length; index += 1) {
|
|
13175
|
+
const trimmedLine = lines[index].trim();
|
|
13176
|
+
if (trimmedLine.startsWith("```") || trimmedLine.startsWith("~~~")) {
|
|
13177
|
+
inFence = !inFence;
|
|
13178
|
+
continue;
|
|
13179
|
+
}
|
|
13180
|
+
if (!inFence && isManagedHeadingLine(trimmedLine)) {
|
|
13181
|
+
return true;
|
|
13182
|
+
}
|
|
13183
|
+
}
|
|
13184
|
+
return false;
|
|
13185
|
+
}
|
|
13186
|
+
function splitManagedContent(content) {
|
|
13187
|
+
const lines = content.split(/\r?\n/);
|
|
13188
|
+
const lineOffsets = [];
|
|
13189
|
+
let offset = 0;
|
|
13190
|
+
for (const line of lines) {
|
|
13191
|
+
lineOffsets.push(offset);
|
|
13192
|
+
offset += line.length + 1;
|
|
13193
|
+
}
|
|
13194
|
+
let inFence = false;
|
|
13195
|
+
let firstManagedIndex = -1;
|
|
13196
|
+
const separatorIndices = [];
|
|
13197
|
+
for (let lineIndex = 0;lineIndex < lines.length; lineIndex += 1) {
|
|
13198
|
+
const trimmedLine = lines[lineIndex].trim();
|
|
13199
|
+
if (trimmedLine.startsWith("```") || trimmedLine.startsWith("~~~")) {
|
|
13200
|
+
inFence = !inFence;
|
|
13201
|
+
}
|
|
13202
|
+
if (!inFence) {
|
|
13203
|
+
if (isManagedHeadingLine(trimmedLine) && firstManagedIndex === -1) {
|
|
13204
|
+
firstManagedIndex = lineOffsets[lineIndex];
|
|
13205
|
+
}
|
|
13206
|
+
if (/^[ \t]*---[ \t]*$/.test(trimmedLine)) {
|
|
13207
|
+
const nextNonBlankLineIndex = findNextNonBlankLineIndex(lines, lineIndex + 1);
|
|
13208
|
+
if (nextNonBlankLineIndex === -1) {
|
|
13209
|
+
separatorIndices.push(lineOffsets[lineIndex]);
|
|
13210
|
+
continue;
|
|
13211
|
+
}
|
|
13212
|
+
const nextNonBlankLine = lines[nextNonBlankLineIndex].trim();
|
|
13213
|
+
if (isManagedHeadingLine(nextNonBlankLine) || !hasLaterManagedHeading(lines, nextNonBlankLineIndex)) {
|
|
13214
|
+
separatorIndices.push(lineOffsets[lineIndex]);
|
|
13215
|
+
}
|
|
13216
|
+
}
|
|
13217
|
+
}
|
|
13218
|
+
}
|
|
13219
|
+
if (firstManagedIndex === -1) {
|
|
13220
|
+
return { preambleEnd: content.length, parts: [] };
|
|
13221
|
+
}
|
|
13222
|
+
const managedContent = content.slice(firstManagedIndex);
|
|
13223
|
+
const managedStart = firstManagedIndex;
|
|
13224
|
+
const parts = [];
|
|
13225
|
+
let lastSplitPos = 0;
|
|
13226
|
+
for (const separatorIndex of separatorIndices) {
|
|
13227
|
+
if (separatorIndex < managedStart)
|
|
13228
|
+
continue;
|
|
13229
|
+
const relativeIndex = separatorIndex - managedStart;
|
|
13230
|
+
if (relativeIndex > lastSplitPos) {
|
|
13231
|
+
const part = managedContent.slice(lastSplitPos, relativeIndex).trim();
|
|
13232
|
+
if (part)
|
|
13233
|
+
parts.push(part);
|
|
13234
|
+
}
|
|
13235
|
+
const separatorLineEnd = managedContent.indexOf(`
|
|
13236
|
+
`, relativeIndex);
|
|
13237
|
+
lastSplitPos = separatorLineEnd >= 0 ? separatorLineEnd + 1 : managedContent.length;
|
|
13238
|
+
}
|
|
13239
|
+
const finalPart = managedContent.slice(lastSplitPos).trim();
|
|
13240
|
+
if (finalPart)
|
|
13241
|
+
parts.push(finalPart);
|
|
13242
|
+
return { preambleEnd: firstManagedIndex, parts };
|
|
13243
|
+
}
|
|
13244
|
+
function parseSectionMetadata(content) {
|
|
13245
|
+
const agentMatch = content.match(SECTION_HEADING_PATTERNS.agent);
|
|
13246
|
+
if (agentMatch) {
|
|
13247
|
+
return { kind: "agent", key: agentMatch[1].trim() };
|
|
13248
|
+
}
|
|
13249
|
+
const ruleMatch = content.match(SECTION_HEADING_PATTERNS.rule);
|
|
13250
|
+
if (ruleMatch) {
|
|
13251
|
+
return { kind: "rule", key: ruleMatch[1].trim() };
|
|
13252
|
+
}
|
|
13253
|
+
if (SECTION_HEADING_PATTERNS.config.test(content)) {
|
|
13254
|
+
return { kind: "config", key: "config" };
|
|
13255
|
+
}
|
|
13256
|
+
return null;
|
|
13257
|
+
}
|
|
13258
|
+
function parseMergedSections(content) {
|
|
13259
|
+
const sections = [];
|
|
13260
|
+
const warnings = [];
|
|
13261
|
+
const { preambleEnd, parts } = splitManagedContent(content);
|
|
13262
|
+
if (parts.length === 0) {
|
|
13263
|
+
return {
|
|
13264
|
+
sections,
|
|
13265
|
+
preamble: content.trim(),
|
|
13266
|
+
warnings
|
|
13267
|
+
};
|
|
13268
|
+
}
|
|
13269
|
+
let unknownIndex = 0;
|
|
13270
|
+
const seenKeys = new Map;
|
|
13271
|
+
for (const part of parts) {
|
|
13272
|
+
const trimmed = part.trim();
|
|
13273
|
+
if (!trimmed)
|
|
13274
|
+
continue;
|
|
13275
|
+
const metadata = parseSectionMetadata(trimmed);
|
|
13276
|
+
if (metadata) {
|
|
13277
|
+
const compositeKey = `${metadata.kind}:${metadata.key}`;
|
|
13278
|
+
const existingIndex = seenKeys.get(compositeKey);
|
|
13279
|
+
if (existingIndex !== undefined) {
|
|
13280
|
+
warnings.push(`Duplicate ${metadata.kind} section "${metadata.key}" in existing file; keeping last occurrence`);
|
|
13281
|
+
sections.splice(existingIndex, 1);
|
|
13282
|
+
for (const [key, index] of seenKeys) {
|
|
13283
|
+
if (index > existingIndex) {
|
|
13284
|
+
seenKeys.set(key, index - 1);
|
|
13285
|
+
}
|
|
13286
|
+
}
|
|
13287
|
+
}
|
|
13288
|
+
const nextIndex = sections.length;
|
|
13289
|
+
sections.push({
|
|
13290
|
+
kind: metadata.kind,
|
|
13291
|
+
key: metadata.key,
|
|
13292
|
+
content: trimmed
|
|
13293
|
+
});
|
|
13294
|
+
seenKeys.set(compositeKey, nextIndex);
|
|
13295
|
+
continue;
|
|
13296
|
+
}
|
|
13297
|
+
unknownIndex += 1;
|
|
13298
|
+
sections.push({
|
|
13299
|
+
kind: "unknown",
|
|
13300
|
+
key: `unknown-${unknownIndex}`,
|
|
13301
|
+
content: trimmed
|
|
13302
|
+
});
|
|
13303
|
+
}
|
|
13304
|
+
let preamble = content.slice(0, preambleEnd).trimEnd();
|
|
13305
|
+
preamble = preamble.replace(/^# Agents\r?\n\r?\n> Ported from Claude Code agents via ClaudeKit CLI \(ck agents\)\r?\n> Target: .*\r?\n+/is, "").replace(/^# Rules\r?\n\r?\n> Ported from Claude Code rules via ClaudeKit CLI \(ck migrate --rules\)\r?\n> Target: .*\r?\n+/is, "").replace(/^# Config\r?\n\r?\n> Ported from Claude Code config via ClaudeKit CLI.*\r?\n+/is, "").trimEnd();
|
|
13306
|
+
return {
|
|
13307
|
+
sections,
|
|
13308
|
+
preamble: preamble.trim(),
|
|
13309
|
+
warnings
|
|
13310
|
+
};
|
|
13311
|
+
}
|
|
13312
|
+
function getMergeSectionKey(kind, item) {
|
|
13313
|
+
if (kind === "config")
|
|
13314
|
+
return "config";
|
|
13315
|
+
if (kind === "agent")
|
|
13316
|
+
return item.frontmatter.name || item.name;
|
|
13317
|
+
return item.name;
|
|
13318
|
+
}
|
|
13319
|
+
function buildMergeSectionContent(kind, sectionKey, convertedContent) {
|
|
13320
|
+
if (kind === "config") {
|
|
13321
|
+
return `## Config
|
|
13322
|
+
|
|
13323
|
+
${convertedContent.trim()}
|
|
13324
|
+
`;
|
|
13325
|
+
}
|
|
13326
|
+
if (kind === "rule") {
|
|
13327
|
+
return `## Rule: ${sectionKey}
|
|
13328
|
+
|
|
13329
|
+
${convertedContent.trim()}
|
|
13330
|
+
`;
|
|
13331
|
+
}
|
|
13332
|
+
return convertedContent.trimEnd();
|
|
13333
|
+
}
|
|
13334
|
+
function getManagedSectionChecksumKey(kind, key) {
|
|
13335
|
+
return `${kind}:${key}`;
|
|
13336
|
+
}
|
|
13337
|
+
function computeManagedSectionChecksums(content) {
|
|
13338
|
+
const checksums = {};
|
|
13339
|
+
for (const section of parseMergedSections(content).sections) {
|
|
13340
|
+
if (section.kind === "unknown")
|
|
13341
|
+
continue;
|
|
13342
|
+
const normalizedContent = section.kind === "agent" ? section.content.trimEnd() : `${section.content.trimEnd()}
|
|
13343
|
+
`;
|
|
13344
|
+
checksums[getManagedSectionChecksumKey(section.kind, section.key)] = computeContentChecksum(normalizedContent);
|
|
13345
|
+
}
|
|
13346
|
+
return checksums;
|
|
13347
|
+
}
|
|
13348
|
+
var SECTION_HEADING_PATTERNS;
|
|
13349
|
+
var init_merge_single_sections = __esm(() => {
|
|
13350
|
+
init_checksum_utils();
|
|
13351
|
+
SECTION_HEADING_PATTERNS = {
|
|
13352
|
+
agent: /^##\s*agent\s*:\s*(.+?)\s*$/im,
|
|
13353
|
+
rule: /^##\s*rule\s*:\s*(.+?)\s*$/im,
|
|
13354
|
+
config: /^##\s*config\s*$/im
|
|
13355
|
+
};
|
|
13356
|
+
});
|
|
13357
|
+
|
|
13160
13358
|
// src/commands/portable/portable-installer.ts
|
|
13161
13359
|
import { existsSync as existsSync4 } from "node:fs";
|
|
13162
13360
|
import { mkdir as mkdir3, readFile as readFile4, unlink as unlink3, writeFile as writeFile3 } from "node:fs/promises";
|
|
@@ -13315,146 +13513,6 @@ async function restoreFileSnapshots2(snapshots) {
|
|
|
13315
13513
|
await restoreFileSnapshot2(snapshots[index]);
|
|
13316
13514
|
}
|
|
13317
13515
|
}
|
|
13318
|
-
function splitManagedContent(content) {
|
|
13319
|
-
const lines = content.split(/\r?\n/);
|
|
13320
|
-
let inFence = false;
|
|
13321
|
-
let firstManagedIndex = -1;
|
|
13322
|
-
const separatorIndices = [];
|
|
13323
|
-
let currentLineIndex = 0;
|
|
13324
|
-
for (let i = 0;i < lines.length; i++) {
|
|
13325
|
-
const line = lines[i];
|
|
13326
|
-
const trimmedLine = line.trim();
|
|
13327
|
-
if (trimmedLine.startsWith("```") || trimmedLine.startsWith("~~~")) {
|
|
13328
|
-
inFence = !inFence;
|
|
13329
|
-
}
|
|
13330
|
-
if (!inFence) {
|
|
13331
|
-
const isManagedHeading = Object.values(SECTION_HEADING_PATTERNS).some((regex) => regex.test(trimmedLine));
|
|
13332
|
-
if (isManagedHeading) {
|
|
13333
|
-
if (firstManagedIndex === -1) {
|
|
13334
|
-
firstManagedIndex = currentLineIndex;
|
|
13335
|
-
}
|
|
13336
|
-
}
|
|
13337
|
-
if (/^[ \t]*---[ \t]*$/.test(trimmedLine)) {
|
|
13338
|
-
separatorIndices.push(currentLineIndex);
|
|
13339
|
-
}
|
|
13340
|
-
}
|
|
13341
|
-
currentLineIndex += line.length + 1;
|
|
13342
|
-
}
|
|
13343
|
-
if (firstManagedIndex === -1) {
|
|
13344
|
-
return { preambleEnd: content.length, parts: [] };
|
|
13345
|
-
}
|
|
13346
|
-
const managedContent = content.slice(firstManagedIndex);
|
|
13347
|
-
const managedStart = firstManagedIndex;
|
|
13348
|
-
const parts = [];
|
|
13349
|
-
let lastSplitPos = 0;
|
|
13350
|
-
for (const sepIdx of separatorIndices) {
|
|
13351
|
-
if (sepIdx >= managedStart) {
|
|
13352
|
-
const relativeIdx = sepIdx - managedStart;
|
|
13353
|
-
if (relativeIdx > lastSplitPos) {
|
|
13354
|
-
const part = managedContent.slice(lastSplitPos, relativeIdx).trim();
|
|
13355
|
-
if (part)
|
|
13356
|
-
parts.push(part);
|
|
13357
|
-
}
|
|
13358
|
-
const sepLineEnd = managedContent.indexOf(`
|
|
13359
|
-
`, relativeIdx);
|
|
13360
|
-
lastSplitPos = sepLineEnd >= 0 ? sepLineEnd + 1 : managedContent.length;
|
|
13361
|
-
}
|
|
13362
|
-
}
|
|
13363
|
-
const finalPart = managedContent.slice(lastSplitPos).trim();
|
|
13364
|
-
if (finalPart)
|
|
13365
|
-
parts.push(finalPart);
|
|
13366
|
-
return { preambleEnd: firstManagedIndex, parts };
|
|
13367
|
-
}
|
|
13368
|
-
function parseSectionMetadata(content) {
|
|
13369
|
-
const agentMatch = content.match(SECTION_HEADING_PATTERNS.agent);
|
|
13370
|
-
if (agentMatch) {
|
|
13371
|
-
return { kind: "agent", key: agentMatch[1].trim() };
|
|
13372
|
-
}
|
|
13373
|
-
const ruleMatch = content.match(SECTION_HEADING_PATTERNS.rule);
|
|
13374
|
-
if (ruleMatch) {
|
|
13375
|
-
return { kind: "rule", key: ruleMatch[1].trim() };
|
|
13376
|
-
}
|
|
13377
|
-
if (SECTION_HEADING_PATTERNS.config.test(content)) {
|
|
13378
|
-
return { kind: "config", key: "config" };
|
|
13379
|
-
}
|
|
13380
|
-
return null;
|
|
13381
|
-
}
|
|
13382
|
-
function parseMergedSections(content) {
|
|
13383
|
-
const sections = [];
|
|
13384
|
-
const warnings = [];
|
|
13385
|
-
const { preambleEnd, parts } = splitManagedContent(content);
|
|
13386
|
-
if (parts.length === 0) {
|
|
13387
|
-
return {
|
|
13388
|
-
sections,
|
|
13389
|
-
preamble: content.trim(),
|
|
13390
|
-
warnings
|
|
13391
|
-
};
|
|
13392
|
-
}
|
|
13393
|
-
let unknownIndex = 0;
|
|
13394
|
-
const seenKeys = new Map;
|
|
13395
|
-
for (const part of parts) {
|
|
13396
|
-
const trimmed = part.trim();
|
|
13397
|
-
if (!trimmed)
|
|
13398
|
-
continue;
|
|
13399
|
-
const metadata = parseSectionMetadata(trimmed);
|
|
13400
|
-
if (metadata) {
|
|
13401
|
-
const compositeKey = `${metadata.kind}:${metadata.key}`;
|
|
13402
|
-
const existingIndex = seenKeys.get(compositeKey);
|
|
13403
|
-
if (existingIndex !== undefined) {
|
|
13404
|
-
warnings.push(`Duplicate ${metadata.kind} section "${metadata.key}" in existing file; keeping last occurrence`);
|
|
13405
|
-
sections.splice(existingIndex, 1);
|
|
13406
|
-
for (const [key, idx] of seenKeys) {
|
|
13407
|
-
if (idx > existingIndex) {
|
|
13408
|
-
seenKeys.set(key, idx - 1);
|
|
13409
|
-
}
|
|
13410
|
-
}
|
|
13411
|
-
}
|
|
13412
|
-
const newIndex = sections.length;
|
|
13413
|
-
sections.push({
|
|
13414
|
-
kind: metadata.kind,
|
|
13415
|
-
key: metadata.key,
|
|
13416
|
-
content: trimmed
|
|
13417
|
-
});
|
|
13418
|
-
seenKeys.set(compositeKey, newIndex);
|
|
13419
|
-
continue;
|
|
13420
|
-
}
|
|
13421
|
-
unknownIndex += 1;
|
|
13422
|
-
sections.push({
|
|
13423
|
-
kind: "unknown",
|
|
13424
|
-
key: `unknown-${unknownIndex}`,
|
|
13425
|
-
content: trimmed
|
|
13426
|
-
});
|
|
13427
|
-
}
|
|
13428
|
-
let preamble = content.slice(0, preambleEnd).trimEnd();
|
|
13429
|
-
preamble = preamble.replace(/^# Agents\r?\n\r?\n> Ported from Claude Code agents via ClaudeKit CLI \(ck agents\)\r?\n> Target: .*\r?\n+/is, "").replace(/^# Rules\r?\n\r?\n> Ported from Claude Code rules via ClaudeKit CLI \(ck migrate --rules\)\r?\n> Target: .*\r?\n+/is, "").replace(/^# Config\r?\n\r?\n> Ported from Claude Code config via ClaudeKit CLI.*\r?\n+/is, "").trimEnd();
|
|
13430
|
-
return {
|
|
13431
|
-
sections,
|
|
13432
|
-
preamble: preamble.trim(),
|
|
13433
|
-
warnings
|
|
13434
|
-
};
|
|
13435
|
-
}
|
|
13436
|
-
function getMergeSectionKey(kind, item) {
|
|
13437
|
-
if (kind === "config")
|
|
13438
|
-
return "config";
|
|
13439
|
-
if (kind === "agent")
|
|
13440
|
-
return item.frontmatter.name || item.name;
|
|
13441
|
-
return item.name;
|
|
13442
|
-
}
|
|
13443
|
-
function buildMergeSectionContent(kind, sectionKey, convertedContent) {
|
|
13444
|
-
if (kind === "config") {
|
|
13445
|
-
return `## Config
|
|
13446
|
-
|
|
13447
|
-
${convertedContent.trim()}
|
|
13448
|
-
`;
|
|
13449
|
-
}
|
|
13450
|
-
if (kind === "rule") {
|
|
13451
|
-
return `## Rule: ${sectionKey}
|
|
13452
|
-
|
|
13453
|
-
${convertedContent.trim()}
|
|
13454
|
-
`;
|
|
13455
|
-
}
|
|
13456
|
-
return convertedContent.trimEnd();
|
|
13457
|
-
}
|
|
13458
13516
|
function parseYamlModesFile(content) {
|
|
13459
13517
|
const modes = new Map;
|
|
13460
13518
|
const match = content.match(/customModes:\s*\n/);
|
|
@@ -14223,7 +14281,7 @@ async function installPortableItems(items, targetProviders, portableType, option
|
|
|
14223
14281
|
}
|
|
14224
14282
|
return results;
|
|
14225
14283
|
}
|
|
14226
|
-
var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema
|
|
14284
|
+
var import_proper_lockfile3, ClineCustomModeSchema, ClineCustomModesFileSchema;
|
|
14227
14285
|
var init_portable_installer = __esm(() => {
|
|
14228
14286
|
init_zod();
|
|
14229
14287
|
init_checksum_utils();
|
|
@@ -14231,6 +14289,7 @@ var init_portable_installer = __esm(() => {
|
|
|
14231
14289
|
init_fm_to_json();
|
|
14232
14290
|
init_fm_to_yaml();
|
|
14233
14291
|
init_converters();
|
|
14292
|
+
init_merge_single_sections();
|
|
14234
14293
|
init_portable_registry();
|
|
14235
14294
|
init_provider_registry();
|
|
14236
14295
|
import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
@@ -14244,11 +14303,6 @@ var init_portable_installer = __esm(() => {
|
|
|
14244
14303
|
ClineCustomModesFileSchema = exports_external.object({
|
|
14245
14304
|
customModes: exports_external.array(ClineCustomModeSchema).optional()
|
|
14246
14305
|
});
|
|
14247
|
-
SECTION_HEADING_PATTERNS = {
|
|
14248
|
-
agent: /^##\s*agent\s*:\s*(.+?)\s*$/im,
|
|
14249
|
-
rule: /^##\s*rule\s*:\s*(.+?)\s*$/im,
|
|
14250
|
-
config: /^##\s*config\s*$/im
|
|
14251
|
-
};
|
|
14252
14306
|
});
|
|
14253
14307
|
|
|
14254
14308
|
// src/commands/portable/types.ts
|
|
@@ -52006,6 +52060,161 @@ var init_portable_manifest = __esm(() => {
|
|
|
52006
52060
|
}).passthrough();
|
|
52007
52061
|
});
|
|
52008
52062
|
|
|
52063
|
+
// src/commands/portable/reconcile-registry-backfill.ts
|
|
52064
|
+
function shouldBackfillRegistry(action) {
|
|
52065
|
+
return action.action === "skip" && action.backfillRegistry === true && typeof action.targetPath === "string" && action.targetPath.length > 0 && typeof action.sourceChecksum === "string" && !isUnknownChecksum(action.sourceChecksum) && typeof action.currentTargetChecksum === "string" && !isUnknownChecksum(action.currentTargetChecksum);
|
|
52066
|
+
}
|
|
52067
|
+
async function backfillRegistryChecksums(actions, registry) {
|
|
52068
|
+
for (const action of actions) {
|
|
52069
|
+
if (!shouldBackfillRegistry(action))
|
|
52070
|
+
continue;
|
|
52071
|
+
const registryEntry = registry.installations.find((entry) => entry.item === action.item && entry.type === action.type && entry.provider === action.provider && entry.global === action.global);
|
|
52072
|
+
if (!registryEntry)
|
|
52073
|
+
continue;
|
|
52074
|
+
await addPortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
|
|
52075
|
+
sourceChecksum: action.sourceChecksum,
|
|
52076
|
+
targetChecksum: action.currentTargetChecksum,
|
|
52077
|
+
ownedSections: registryEntry.ownedSections,
|
|
52078
|
+
installSource: registryEntry.installSource === "manual" ? "manual" : "kit"
|
|
52079
|
+
});
|
|
52080
|
+
}
|
|
52081
|
+
}
|
|
52082
|
+
var init_reconcile_registry_backfill = __esm(() => {
|
|
52083
|
+
init_portable_registry();
|
|
52084
|
+
});
|
|
52085
|
+
|
|
52086
|
+
// src/commands/portable/reconcile-state-builders.ts
|
|
52087
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
52088
|
+
import { readFile as readFile18 } from "node:fs/promises";
|
|
52089
|
+
function getProviderPathKeyForPortableType2(type) {
|
|
52090
|
+
switch (type) {
|
|
52091
|
+
case "agent":
|
|
52092
|
+
return "agents";
|
|
52093
|
+
case "command":
|
|
52094
|
+
return "commands";
|
|
52095
|
+
case "skill":
|
|
52096
|
+
return "skills";
|
|
52097
|
+
case "config":
|
|
52098
|
+
return "config";
|
|
52099
|
+
case "rules":
|
|
52100
|
+
return "rules";
|
|
52101
|
+
case "hooks":
|
|
52102
|
+
return "hooks";
|
|
52103
|
+
}
|
|
52104
|
+
}
|
|
52105
|
+
function getProviderPathConfig(provider, type) {
|
|
52106
|
+
return providers[provider]?.[getProviderPathKeyForPortableType2(type)] ?? null;
|
|
52107
|
+
}
|
|
52108
|
+
function usesMergeSingleChecksums(entry) {
|
|
52109
|
+
const pathConfig = getProviderPathConfig(entry.provider, entry.type);
|
|
52110
|
+
return pathConfig?.writeStrategy === "merge-single";
|
|
52111
|
+
}
|
|
52112
|
+
function buildTargetChecksum(item, type, provider, convertedContent) {
|
|
52113
|
+
const pathConfig = getProviderPathConfig(provider, type);
|
|
52114
|
+
if (!pathConfig) {
|
|
52115
|
+
return computeContentChecksum(item.body);
|
|
52116
|
+
}
|
|
52117
|
+
if (pathConfig.writeStrategy === "yaml-merge" || pathConfig.writeStrategy === "json-merge") {
|
|
52118
|
+
return;
|
|
52119
|
+
}
|
|
52120
|
+
if (pathConfig.writeStrategy !== "merge-single") {
|
|
52121
|
+
return computeContentChecksum(convertedContent);
|
|
52122
|
+
}
|
|
52123
|
+
const sectionKind = type === "config" ? "config" : type === "rules" ? "rule" : type === "agent" ? "agent" : null;
|
|
52124
|
+
if (!sectionKind) {
|
|
52125
|
+
return;
|
|
52126
|
+
}
|
|
52127
|
+
const sectionKey = getMergeSectionKey(sectionKind, item);
|
|
52128
|
+
return computeContentChecksum(buildMergeSectionContent(sectionKind, sectionKey, convertedContent));
|
|
52129
|
+
}
|
|
52130
|
+
function buildConvertedChecksums(item, type, selectedProviders, options2) {
|
|
52131
|
+
const rawChecksum = computeContentChecksum(item.body);
|
|
52132
|
+
const convertedChecksums = {};
|
|
52133
|
+
for (const provider of selectedProviders) {
|
|
52134
|
+
const pathConfig = getProviderPathConfig(provider, type);
|
|
52135
|
+
if (!pathConfig) {
|
|
52136
|
+
convertedChecksums[provider] = rawChecksum;
|
|
52137
|
+
continue;
|
|
52138
|
+
}
|
|
52139
|
+
const result = convertItem(item, pathConfig.format, provider);
|
|
52140
|
+
if (result.error) {
|
|
52141
|
+
options2?.onConversionFallback?.({
|
|
52142
|
+
item: item.name,
|
|
52143
|
+
type,
|
|
52144
|
+
provider,
|
|
52145
|
+
format: pathConfig.format,
|
|
52146
|
+
error: result.error
|
|
52147
|
+
});
|
|
52148
|
+
convertedChecksums[provider] = rawChecksum;
|
|
52149
|
+
continue;
|
|
52150
|
+
}
|
|
52151
|
+
convertedChecksums[provider] = computeContentChecksum(result.content);
|
|
52152
|
+
}
|
|
52153
|
+
return convertedChecksums;
|
|
52154
|
+
}
|
|
52155
|
+
function buildSourceItemState(item, type, selectedProviders, options2) {
|
|
52156
|
+
const rawChecksum = computeContentChecksum(item.body);
|
|
52157
|
+
const convertedChecksums = buildConvertedChecksums(item, type, selectedProviders, options2);
|
|
52158
|
+
const targetChecksums = {};
|
|
52159
|
+
for (const provider of selectedProviders) {
|
|
52160
|
+
const pathConfig = getProviderPathConfig(provider, type);
|
|
52161
|
+
if (!pathConfig) {
|
|
52162
|
+
targetChecksums[provider] = rawChecksum;
|
|
52163
|
+
continue;
|
|
52164
|
+
}
|
|
52165
|
+
const result = convertItem(item, pathConfig.format, provider);
|
|
52166
|
+
if (result.error) {
|
|
52167
|
+
targetChecksums[provider] = rawChecksum;
|
|
52168
|
+
continue;
|
|
52169
|
+
}
|
|
52170
|
+
const targetChecksum = buildTargetChecksum(item, type, provider, result.content);
|
|
52171
|
+
if (targetChecksum) {
|
|
52172
|
+
targetChecksums[provider] = targetChecksum;
|
|
52173
|
+
}
|
|
52174
|
+
}
|
|
52175
|
+
return {
|
|
52176
|
+
item: item.name,
|
|
52177
|
+
type,
|
|
52178
|
+
sourceChecksum: rawChecksum,
|
|
52179
|
+
convertedChecksums,
|
|
52180
|
+
targetChecksums
|
|
52181
|
+
};
|
|
52182
|
+
}
|
|
52183
|
+
async function buildTargetStates(entries, options2) {
|
|
52184
|
+
const targetStates = new Map;
|
|
52185
|
+
const entriesByPath = new Map;
|
|
52186
|
+
for (const entry of entries) {
|
|
52187
|
+
if (entry.type === "skill")
|
|
52188
|
+
continue;
|
|
52189
|
+
const group = entriesByPath.get(entry.path) ?? [];
|
|
52190
|
+
group.push(entry);
|
|
52191
|
+
entriesByPath.set(entry.path, group);
|
|
52192
|
+
}
|
|
52193
|
+
for (const [entryPath, groupedEntries] of entriesByPath) {
|
|
52194
|
+
const exists = existsSync24(entryPath);
|
|
52195
|
+
const state = { path: entryPath, exists };
|
|
52196
|
+
if (exists) {
|
|
52197
|
+
try {
|
|
52198
|
+
const content = await readFile18(entryPath, "utf-8");
|
|
52199
|
+
state.currentChecksum = computeContentChecksum(content);
|
|
52200
|
+
if (groupedEntries.some((entry) => usesMergeSingleChecksums(entry))) {
|
|
52201
|
+
state.sectionChecksums = computeManagedSectionChecksums(content);
|
|
52202
|
+
}
|
|
52203
|
+
} catch (error) {
|
|
52204
|
+
options2?.onReadFailure?.(entryPath, error);
|
|
52205
|
+
}
|
|
52206
|
+
}
|
|
52207
|
+
targetStates.set(entryPath, state);
|
|
52208
|
+
}
|
|
52209
|
+
return targetStates;
|
|
52210
|
+
}
|
|
52211
|
+
var init_reconcile_state_builders = __esm(() => {
|
|
52212
|
+
init_checksum_utils();
|
|
52213
|
+
init_converters();
|
|
52214
|
+
init_merge_single_sections();
|
|
52215
|
+
init_provider_registry();
|
|
52216
|
+
});
|
|
52217
|
+
|
|
52009
52218
|
// src/commands/portable/reconciler.ts
|
|
52010
52219
|
import path3 from "node:path";
|
|
52011
52220
|
function normalizePortablePath(value) {
|
|
@@ -52085,12 +52294,39 @@ function buildTargetStateIndex(targetStates) {
|
|
|
52085
52294
|
function lookupTargetState(targetStateIndex, pathValue) {
|
|
52086
52295
|
return targetStateIndex.get(normalizePortablePath(pathValue));
|
|
52087
52296
|
}
|
|
52088
|
-
function
|
|
52297
|
+
function getManagedSectionKind(type) {
|
|
52298
|
+
if (type === "agent")
|
|
52299
|
+
return "agent";
|
|
52300
|
+
if (type === "rules")
|
|
52301
|
+
return "rule";
|
|
52302
|
+
if (type === "config")
|
|
52303
|
+
return "config";
|
|
52304
|
+
return null;
|
|
52305
|
+
}
|
|
52306
|
+
function getExpectedTargetChecksum(source, provider) {
|
|
52307
|
+
return normalizeChecksum(source.targetChecksums?.[provider] ?? source.convertedChecksums[provider]);
|
|
52308
|
+
}
|
|
52309
|
+
function getCurrentTargetChecksum(targetState, registryEntry) {
|
|
52310
|
+
if (!targetState)
|
|
52311
|
+
return UNKNOWN_CHECKSUM;
|
|
52312
|
+
if (!targetState.exists)
|
|
52313
|
+
return UNKNOWN_CHECKSUM;
|
|
52314
|
+
if (targetState.sectionChecksums && registryEntry.ownedSections?.length) {
|
|
52315
|
+
const sectionKind = getManagedSectionKind(registryEntry.type);
|
|
52316
|
+
const sectionName = registryEntry.ownedSections[0];
|
|
52317
|
+
if (sectionKind && sectionName) {
|
|
52318
|
+
return normalizeChecksum(targetState.sectionChecksums[`${sectionKind}:${sectionName}`]);
|
|
52319
|
+
}
|
|
52320
|
+
return UNKNOWN_CHECKSUM;
|
|
52321
|
+
}
|
|
52322
|
+
return normalizeChecksum(targetState.currentChecksum);
|
|
52323
|
+
}
|
|
52324
|
+
function getTargetChangeState(targetState, registryEntry, registeredTargetChecksum) {
|
|
52089
52325
|
if (!targetState)
|
|
52090
52326
|
return "unknown";
|
|
52091
52327
|
if (!targetState.exists)
|
|
52092
52328
|
return "deleted";
|
|
52093
|
-
const currentTargetChecksum =
|
|
52329
|
+
const currentTargetChecksum = getCurrentTargetChecksum(targetState, registryEntry);
|
|
52094
52330
|
if (isUnknownChecksum(currentTargetChecksum) || isUnknownChecksum(registeredTargetChecksum)) {
|
|
52095
52331
|
return "unknown";
|
|
52096
52332
|
}
|
|
@@ -52189,6 +52425,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52189
52425
|
};
|
|
52190
52426
|
const convertedChecksumRaw = source.convertedChecksums[providerConfig.provider];
|
|
52191
52427
|
const convertedChecksum = normalizeChecksum(convertedChecksumRaw);
|
|
52428
|
+
const expectedTargetChecksum = getExpectedTargetChecksum(source, providerConfig.provider);
|
|
52192
52429
|
if (!convertedChecksumRaw || isUnknownChecksum(convertedChecksumRaw)) {
|
|
52193
52430
|
if (registryEntry) {
|
|
52194
52431
|
common.targetPath = registryEntry.path;
|
|
@@ -52222,19 +52459,21 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52222
52459
|
common.targetPath = registryEntry.path;
|
|
52223
52460
|
const registeredSourceChecksum = normalizeChecksum(registryEntry.sourceChecksum);
|
|
52224
52461
|
const registeredTargetChecksum = normalizeChecksum(registryEntry.targetChecksum);
|
|
52462
|
+
const targetState = lookupTargetState(targetStateIndex, registryEntry.path);
|
|
52463
|
+
const currentTargetChecksum = getCurrentTargetChecksum(targetState, registryEntry);
|
|
52464
|
+
const targetMatchesExpectedOutput = targetState?.exists === true && !isUnknownChecksum(expectedTargetChecksum) && currentTargetChecksum === expectedTargetChecksum;
|
|
52225
52465
|
if (isUnknownChecksum(registeredSourceChecksum)) {
|
|
52226
|
-
|
|
52227
|
-
const currentTargetChecksum = normalizeChecksum(targetState2?.currentChecksum);
|
|
52228
|
-
if (currentTargetChecksum === convertedChecksum) {
|
|
52466
|
+
if (targetMatchesExpectedOutput) {
|
|
52229
52467
|
return {
|
|
52230
52468
|
...common,
|
|
52231
52469
|
action: "skip",
|
|
52232
52470
|
reason: "Target up-to-date after registry upgrade — checksums will be backfilled",
|
|
52233
52471
|
sourceChecksum: convertedChecksum,
|
|
52234
|
-
currentTargetChecksum
|
|
52472
|
+
currentTargetChecksum,
|
|
52473
|
+
backfillRegistry: true
|
|
52235
52474
|
};
|
|
52236
52475
|
}
|
|
52237
|
-
if (!
|
|
52476
|
+
if (!targetState || !targetState.exists) {
|
|
52238
52477
|
return {
|
|
52239
52478
|
...common,
|
|
52240
52479
|
action: "install",
|
|
@@ -52250,9 +52489,20 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52250
52489
|
currentTargetChecksum
|
|
52251
52490
|
};
|
|
52252
52491
|
}
|
|
52492
|
+
if (targetMatchesExpectedOutput && (convertedChecksum !== registeredSourceChecksum || currentTargetChecksum !== registeredTargetChecksum)) {
|
|
52493
|
+
return {
|
|
52494
|
+
...common,
|
|
52495
|
+
action: "skip",
|
|
52496
|
+
reason: "Target up-to-date — registry checksums will be backfilled",
|
|
52497
|
+
sourceChecksum: convertedChecksum,
|
|
52498
|
+
registeredSourceChecksum,
|
|
52499
|
+
currentTargetChecksum,
|
|
52500
|
+
registeredTargetChecksum,
|
|
52501
|
+
backfillRegistry: true
|
|
52502
|
+
};
|
|
52503
|
+
}
|
|
52253
52504
|
const sourceChanged = convertedChecksum !== registeredSourceChecksum;
|
|
52254
|
-
const
|
|
52255
|
-
const targetChangeState = getTargetChangeState(targetState, registeredTargetChecksum);
|
|
52505
|
+
const targetChangeState = getTargetChangeState(targetState, registryEntry, registeredTargetChecksum);
|
|
52256
52506
|
if (targetChangeState === "deleted") {
|
|
52257
52507
|
const forceReinstall = input.force && !sourceChanged;
|
|
52258
52508
|
return {
|
|
@@ -52270,7 +52520,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52270
52520
|
reason: sourceChanged ? "Target state unavailable while CK changed — manual review required" : "Target state unavailable, CK unchanged — preserving target",
|
|
52271
52521
|
sourceChecksum: convertedChecksum,
|
|
52272
52522
|
registeredSourceChecksum,
|
|
52273
|
-
currentTargetChecksum
|
|
52523
|
+
currentTargetChecksum,
|
|
52274
52524
|
registeredTargetChecksum
|
|
52275
52525
|
};
|
|
52276
52526
|
}
|
|
@@ -52281,7 +52531,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52281
52531
|
action: "skip",
|
|
52282
52532
|
reason: "No changes",
|
|
52283
52533
|
sourceChecksum: convertedChecksum,
|
|
52284
|
-
currentTargetChecksum
|
|
52534
|
+
currentTargetChecksum
|
|
52285
52535
|
};
|
|
52286
52536
|
}
|
|
52287
52537
|
if (!sourceChanged && targetChanged) {
|
|
@@ -52291,7 +52541,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52291
52541
|
reason: input.force ? "Force overwrite (user edits)" : "User edited, CK unchanged — preserving edits",
|
|
52292
52542
|
sourceChecksum: convertedChecksum,
|
|
52293
52543
|
registeredSourceChecksum,
|
|
52294
|
-
currentTargetChecksum
|
|
52544
|
+
currentTargetChecksum,
|
|
52295
52545
|
registeredTargetChecksum
|
|
52296
52546
|
};
|
|
52297
52547
|
}
|
|
@@ -52302,7 +52552,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52302
52552
|
reason: "CK updated, no user edits — safe overwrite",
|
|
52303
52553
|
sourceChecksum: convertedChecksum,
|
|
52304
52554
|
registeredSourceChecksum,
|
|
52305
|
-
currentTargetChecksum
|
|
52555
|
+
currentTargetChecksum,
|
|
52306
52556
|
registeredTargetChecksum
|
|
52307
52557
|
};
|
|
52308
52558
|
}
|
|
@@ -52312,7 +52562,7 @@ function determineAction(source, providerConfig, input, targetStateIndex, delete
|
|
|
52312
52562
|
reason: "Both CK and user modified this item",
|
|
52313
52563
|
sourceChecksum: convertedChecksum,
|
|
52314
52564
|
registeredSourceChecksum,
|
|
52315
|
-
currentTargetChecksum
|
|
52565
|
+
currentTargetChecksum,
|
|
52316
52566
|
registeredTargetChecksum
|
|
52317
52567
|
};
|
|
52318
52568
|
}
|
|
@@ -52431,8 +52681,8 @@ var init_reconciler = __esm(() => {
|
|
|
52431
52681
|
});
|
|
52432
52682
|
|
|
52433
52683
|
// src/commands/skills/skills-discovery.ts
|
|
52434
|
-
import { existsSync as
|
|
52435
|
-
import { readFile as
|
|
52684
|
+
import { existsSync as existsSync25 } from "node:fs";
|
|
52685
|
+
import { readFile as readFile19, readdir as readdir8, stat as stat6 } from "node:fs/promises";
|
|
52436
52686
|
import { homedir as homedir20 } from "node:os";
|
|
52437
52687
|
import { dirname as dirname10, join as join33 } from "node:path";
|
|
52438
52688
|
function getSkillSourcePath() {
|
|
@@ -52441,12 +52691,12 @@ function getSkillSourcePath() {
|
|
|
52441
52691
|
join33(process.cwd(), ".claude/skills")
|
|
52442
52692
|
];
|
|
52443
52693
|
for (const path4 of bundledPaths) {
|
|
52444
|
-
if (
|
|
52694
|
+
if (existsSync25(path4)) {
|
|
52445
52695
|
return path4;
|
|
52446
52696
|
}
|
|
52447
52697
|
}
|
|
52448
52698
|
const globalSkillsPath = join33(home5, ".claude/skills");
|
|
52449
|
-
if (
|
|
52699
|
+
if (existsSync25(globalSkillsPath)) {
|
|
52450
52700
|
return globalSkillsPath;
|
|
52451
52701
|
}
|
|
52452
52702
|
return null;
|
|
@@ -52462,7 +52712,7 @@ async function hasSkillMd(dir) {
|
|
|
52462
52712
|
}
|
|
52463
52713
|
async function parseSkillMd(skillMdPath) {
|
|
52464
52714
|
try {
|
|
52465
|
-
const content = await
|
|
52715
|
+
const content = await readFile19(skillMdPath, "utf-8");
|
|
52466
52716
|
const { data } = import_gray_matter5.default(content);
|
|
52467
52717
|
const skillDir = dirname10(skillMdPath);
|
|
52468
52718
|
const dirName = skillDir.split(/[/\\]/).pop() || "";
|
|
@@ -52622,8 +52872,8 @@ var init_migration_result_utils = __esm(() => {
|
|
|
52622
52872
|
});
|
|
52623
52873
|
|
|
52624
52874
|
// src/domains/web-server/routes/migration-routes.ts
|
|
52625
|
-
import { existsSync as
|
|
52626
|
-
import { readFile as
|
|
52875
|
+
import { existsSync as existsSync26 } from "node:fs";
|
|
52876
|
+
import { readFile as readFile20, rm as rm6 } from "node:fs/promises";
|
|
52627
52877
|
import { homedir as homedir21 } from "node:os";
|
|
52628
52878
|
import { basename as basename9, join as join34, resolve as resolve8 } from "node:path";
|
|
52629
52879
|
function isDisallowedControlCode(codePoint) {
|
|
@@ -52857,7 +53107,7 @@ async function executePlanDeleteAction(action, options2) {
|
|
|
52857
53107
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
52858
53108
|
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve8(action.targetPath));
|
|
52859
53109
|
try {
|
|
52860
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
53110
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync26(action.targetPath)) {
|
|
52861
53111
|
await rm6(action.targetPath, { recursive: true, force: true });
|
|
52862
53112
|
}
|
|
52863
53113
|
await removePortableInstallation(action.item, action.type, action.provider, action.global);
|
|
@@ -53106,6 +53356,9 @@ function recordHookRegistrationOutcome(provider, mergeResult, warnings, feedback
|
|
|
53106
53356
|
feedbackResults.push(feedback);
|
|
53107
53357
|
}
|
|
53108
53358
|
}
|
|
53359
|
+
function warnConversionFallback(warning) {
|
|
53360
|
+
console.warn(`[migrate] Falling back to raw checksum for ${sanitizeUntrusted(warning.provider)} ${sanitizeUntrusted(warning.type)} "${sanitizeUntrusted(warning.item, 80)}" because ${sanitizeUntrusted(warning.format)} conversion failed: ${sanitizeUntrusted(warning.error, 260)}`);
|
|
53361
|
+
}
|
|
53109
53362
|
async function discoverMigrationItems(include, configSource) {
|
|
53110
53363
|
const agentsSource = include.agents ? getAgentSourcePath() : null;
|
|
53111
53364
|
const commandsSource = include.commands ? getCommandSourcePath() : null;
|
|
@@ -53263,36 +53516,18 @@ function registerMigrationRoutes(app) {
|
|
|
53263
53516
|
const sourceItems = [];
|
|
53264
53517
|
for (const agent of discovered.agents) {
|
|
53265
53518
|
try {
|
|
53266
|
-
|
|
53267
|
-
|
|
53268
|
-
|
|
53269
|
-
for (const provider of selectedProviders) {
|
|
53270
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53271
|
-
}
|
|
53272
|
-
sourceItems.push({
|
|
53273
|
-
item: agent.name,
|
|
53274
|
-
type: "agent",
|
|
53275
|
-
sourceChecksum,
|
|
53276
|
-
convertedChecksums
|
|
53277
|
-
});
|
|
53519
|
+
sourceItems.push(buildSourceItemState(agent, "agent", selectedProviders, {
|
|
53520
|
+
onConversionFallback: warnConversionFallback
|
|
53521
|
+
}));
|
|
53278
53522
|
} catch (error) {
|
|
53279
53523
|
warnReadFailure("agent", agent.name, error);
|
|
53280
53524
|
}
|
|
53281
53525
|
}
|
|
53282
53526
|
for (const command of discovered.commands) {
|
|
53283
53527
|
try {
|
|
53284
|
-
|
|
53285
|
-
|
|
53286
|
-
|
|
53287
|
-
for (const provider of selectedProviders) {
|
|
53288
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53289
|
-
}
|
|
53290
|
-
sourceItems.push({
|
|
53291
|
-
item: command.name,
|
|
53292
|
-
type: "command",
|
|
53293
|
-
sourceChecksum,
|
|
53294
|
-
convertedChecksums
|
|
53295
|
-
});
|
|
53528
|
+
sourceItems.push(buildSourceItemState(command, "command", selectedProviders, {
|
|
53529
|
+
onConversionFallback: warnConversionFallback
|
|
53530
|
+
}));
|
|
53296
53531
|
} catch (error) {
|
|
53297
53532
|
warnReadFailure("command", command.name, error);
|
|
53298
53533
|
}
|
|
@@ -53302,24 +53537,25 @@ function registerMigrationRoutes(app) {
|
|
|
53302
53537
|
const skillMdPath = `${skill.path}/SKILL.md`;
|
|
53303
53538
|
const readmePath = `${skill.path}/README.md`;
|
|
53304
53539
|
let content;
|
|
53305
|
-
if (
|
|
53306
|
-
content = await
|
|
53307
|
-
} else if (
|
|
53308
|
-
content = await
|
|
53540
|
+
if (existsSync26(skillMdPath)) {
|
|
53541
|
+
content = await readFile20(skillMdPath, "utf-8");
|
|
53542
|
+
} else if (existsSync26(readmePath)) {
|
|
53543
|
+
content = await readFile20(readmePath, "utf-8");
|
|
53309
53544
|
} else {
|
|
53310
53545
|
console.warn(`[migrate] Skill "${sanitizeUntrusted(skill.name, 80)}" has neither SKILL.md nor README.md, skipping`);
|
|
53311
53546
|
continue;
|
|
53312
53547
|
}
|
|
53313
|
-
const sourceChecksum = computeContentChecksum(content);
|
|
53314
|
-
const convertedChecksums = {};
|
|
53315
|
-
for (const provider of selectedProviders) {
|
|
53316
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53317
|
-
}
|
|
53318
53548
|
sourceItems.push({
|
|
53319
|
-
|
|
53320
|
-
|
|
53321
|
-
|
|
53322
|
-
|
|
53549
|
+
...buildSourceItemState({
|
|
53550
|
+
name: skill.name,
|
|
53551
|
+
description: skill.description,
|
|
53552
|
+
type: "skill",
|
|
53553
|
+
sourcePath: skill.path,
|
|
53554
|
+
frontmatter: {},
|
|
53555
|
+
body: content
|
|
53556
|
+
}, "skill", selectedProviders, {
|
|
53557
|
+
onConversionFallback: warnConversionFallback
|
|
53558
|
+
})
|
|
53323
53559
|
});
|
|
53324
53560
|
} catch (error) {
|
|
53325
53561
|
warnReadFailure("skill", skill.name, error);
|
|
@@ -53327,75 +53563,35 @@ function registerMigrationRoutes(app) {
|
|
|
53327
53563
|
}
|
|
53328
53564
|
if (discovered.configItem) {
|
|
53329
53565
|
try {
|
|
53330
|
-
|
|
53331
|
-
|
|
53332
|
-
|
|
53333
|
-
for (const provider of selectedProviders) {
|
|
53334
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53335
|
-
}
|
|
53336
|
-
sourceItems.push({
|
|
53337
|
-
item: discovered.configItem.name,
|
|
53338
|
-
type: "config",
|
|
53339
|
-
sourceChecksum,
|
|
53340
|
-
convertedChecksums
|
|
53341
|
-
});
|
|
53566
|
+
sourceItems.push(buildSourceItemState(discovered.configItem, "config", selectedProviders, {
|
|
53567
|
+
onConversionFallback: warnConversionFallback
|
|
53568
|
+
}));
|
|
53342
53569
|
} catch (error) {
|
|
53343
53570
|
warnReadFailure("config", "CLAUDE.md", error);
|
|
53344
53571
|
}
|
|
53345
53572
|
}
|
|
53346
53573
|
for (const rule of discovered.ruleItems) {
|
|
53347
53574
|
try {
|
|
53348
|
-
|
|
53349
|
-
|
|
53350
|
-
|
|
53351
|
-
for (const provider of selectedProviders) {
|
|
53352
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53353
|
-
}
|
|
53354
|
-
sourceItems.push({
|
|
53355
|
-
item: rule.name,
|
|
53356
|
-
type: "rules",
|
|
53357
|
-
sourceChecksum,
|
|
53358
|
-
convertedChecksums
|
|
53359
|
-
});
|
|
53575
|
+
sourceItems.push(buildSourceItemState(rule, "rules", selectedProviders, {
|
|
53576
|
+
onConversionFallback: warnConversionFallback
|
|
53577
|
+
}));
|
|
53360
53578
|
} catch (error) {
|
|
53361
53579
|
warnReadFailure("rule", rule.name, error);
|
|
53362
53580
|
}
|
|
53363
53581
|
}
|
|
53364
53582
|
for (const hook of discovered.hookItems) {
|
|
53365
53583
|
try {
|
|
53366
|
-
|
|
53367
|
-
|
|
53368
|
-
|
|
53369
|
-
for (const provider of selectedProviders) {
|
|
53370
|
-
convertedChecksums[provider] = sourceChecksum;
|
|
53371
|
-
}
|
|
53372
|
-
sourceItems.push({
|
|
53373
|
-
item: hook.name,
|
|
53374
|
-
type: "hooks",
|
|
53375
|
-
sourceChecksum,
|
|
53376
|
-
convertedChecksums
|
|
53377
|
-
});
|
|
53584
|
+
sourceItems.push(buildSourceItemState(hook, "hooks", selectedProviders, {
|
|
53585
|
+
onConversionFallback: warnConversionFallback
|
|
53586
|
+
}));
|
|
53378
53587
|
} catch (error) {
|
|
53379
53588
|
warnReadFailure("hook", hook.name, error);
|
|
53380
53589
|
}
|
|
53381
53590
|
}
|
|
53382
53591
|
const registry = await readPortableRegistry();
|
|
53383
|
-
const targetStates =
|
|
53384
|
-
|
|
53385
|
-
|
|
53386
|
-
continue;
|
|
53387
|
-
const exists = existsSync25(entry.path);
|
|
53388
|
-
const state = { path: entry.path, exists };
|
|
53389
|
-
if (exists) {
|
|
53390
|
-
try {
|
|
53391
|
-
const content = await readFile19(entry.path, "utf-8");
|
|
53392
|
-
state.currentChecksum = computeContentChecksum(content);
|
|
53393
|
-
} catch (error) {
|
|
53394
|
-
warnReadFailure("registry-target", entry.path, error);
|
|
53395
|
-
}
|
|
53396
|
-
}
|
|
53397
|
-
targetStates.set(entry.path, state);
|
|
53398
|
-
}
|
|
53592
|
+
const targetStates = await buildTargetStates(registry.installations, {
|
|
53593
|
+
onReadFailure: (entryPath, error) => warnReadFailure("registry-target", entryPath, error)
|
|
53594
|
+
});
|
|
53399
53595
|
const manifest = discovered.sourcePaths.agents ? await loadPortableManifest(discovered.sourcePaths.agents) : null;
|
|
53400
53596
|
const providerConfigs = selectedProviders.map((provider) => ({
|
|
53401
53597
|
provider,
|
|
@@ -53597,6 +53793,10 @@ function registerMigrationRoutes(app) {
|
|
|
53597
53793
|
deleteResult.itemName = deleteAction.item;
|
|
53598
53794
|
allResults.push(deleteResult);
|
|
53599
53795
|
}
|
|
53796
|
+
try {
|
|
53797
|
+
const registry = await readPortableRegistry();
|
|
53798
|
+
await backfillRegistryChecksums(plan.actions, registry);
|
|
53799
|
+
} catch {}
|
|
53600
53800
|
for (const provider of allPlanProviders) {
|
|
53601
53801
|
if (providers[provider]?.agents?.writeStrategy !== "codex-toml")
|
|
53602
53802
|
continue;
|
|
@@ -53822,7 +54022,6 @@ var init_migration_routes = __esm(() => {
|
|
|
53822
54022
|
init_agents_discovery();
|
|
53823
54023
|
init_commands_discovery();
|
|
53824
54024
|
init_skill_directory_installer();
|
|
53825
|
-
init_checksum_utils();
|
|
53826
54025
|
init_codex_toml_installer();
|
|
53827
54026
|
init_config_discovery();
|
|
53828
54027
|
init_hooks_settings_merger();
|
|
@@ -53830,6 +54029,8 @@ var init_migration_routes = __esm(() => {
|
|
|
53830
54029
|
init_portable_manifest();
|
|
53831
54030
|
init_portable_registry();
|
|
53832
54031
|
init_provider_registry();
|
|
54032
|
+
init_reconcile_registry_backfill();
|
|
54033
|
+
init_reconcile_state_builders();
|
|
53833
54034
|
init_reconciler();
|
|
53834
54035
|
init_types2();
|
|
53835
54036
|
init_skills_discovery();
|
|
@@ -54274,13 +54475,13 @@ var init_plan_table_parser = __esm(() => {
|
|
|
54274
54475
|
});
|
|
54275
54476
|
|
|
54276
54477
|
// src/domains/plan-parser/plan-scanner.ts
|
|
54277
|
-
import { existsSync as
|
|
54478
|
+
import { existsSync as existsSync27, readdirSync as readdirSync3 } from "node:fs";
|
|
54278
54479
|
import { join as join35 } from "node:path";
|
|
54279
54480
|
function scanPlanDir(dir) {
|
|
54280
|
-
if (!
|
|
54481
|
+
if (!existsSync27(dir))
|
|
54281
54482
|
return [];
|
|
54282
54483
|
try {
|
|
54283
|
-
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join35(dir, entry.name, "plan.md")).filter(
|
|
54484
|
+
return readdirSync3(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join35(dir, entry.name, "plan.md")).filter(existsSync27);
|
|
54284
54485
|
} catch {
|
|
54285
54486
|
return [];
|
|
54286
54487
|
}
|
|
@@ -54288,7 +54489,7 @@ function scanPlanDir(dir) {
|
|
|
54288
54489
|
var init_plan_scanner = () => {};
|
|
54289
54490
|
|
|
54290
54491
|
// src/domains/plan-parser/plan-validator.ts
|
|
54291
|
-
import { existsSync as
|
|
54492
|
+
import { existsSync as existsSync28, readFileSync as readFileSync6 } from "node:fs";
|
|
54292
54493
|
import { basename as basename10, dirname as dirname12 } from "node:path";
|
|
54293
54494
|
function validatePlanFile(filePath, strict = false) {
|
|
54294
54495
|
const content = readFileSync6(filePath, "utf8");
|
|
@@ -54328,7 +54529,7 @@ function validatePlanFile(filePath, strict = false) {
|
|
|
54328
54529
|
});
|
|
54329
54530
|
}
|
|
54330
54531
|
for (const phase of phases) {
|
|
54331
|
-
if (phase.file && !
|
|
54532
|
+
if (phase.file && !existsSync28(phase.file)) {
|
|
54332
54533
|
const fileBasename = basename10(phase.file);
|
|
54333
54534
|
const refLine = lines.findIndex((l2) => l2.includes(fileBasename));
|
|
54334
54535
|
issues.push({
|
|
@@ -54354,7 +54555,7 @@ var init_plan_validator = __esm(() => {
|
|
|
54354
54555
|
|
|
54355
54556
|
// src/domains/plan-parser/plan-writer.ts
|
|
54356
54557
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
54357
|
-
import { existsSync as
|
|
54558
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
54358
54559
|
import { basename as basename11, dirname as dirname13, join as join36 } from "node:path";
|
|
54359
54560
|
function phaseNameToFilename(id, name) {
|
|
54360
54561
|
const numMatch = /^(\d+)([a-z]*)$/i.exec(id);
|
|
@@ -54536,7 +54737,7 @@ function updatePhaseStatus(planFile, phaseId, newStatus) {
|
|
|
54536
54737
|
writeFileSync3(planFile, updatedContent, "utf8");
|
|
54537
54738
|
const planDir = dirname13(planFile);
|
|
54538
54739
|
const phaseFilename = phaseNameFilenameFromTableRow(updatedBody, phaseId, planDir);
|
|
54539
|
-
if (phaseFilename &&
|
|
54740
|
+
if (phaseFilename && existsSync29(phaseFilename)) {
|
|
54540
54741
|
updatePhaseFileFrontmatter(phaseFilename, newStatus);
|
|
54541
54742
|
}
|
|
54542
54743
|
}
|
|
@@ -54667,7 +54868,7 @@ var init_plan_parser = __esm(() => {
|
|
|
54667
54868
|
});
|
|
54668
54869
|
|
|
54669
54870
|
// src/domains/web-server/routes/plan-routes.ts
|
|
54670
|
-
import { existsSync as
|
|
54871
|
+
import { existsSync as existsSync30, realpathSync } from "node:fs";
|
|
54671
54872
|
import { basename as basename12, dirname as dirname15, relative as relative6, resolve as resolve10, sep as sep4 } from "node:path";
|
|
54672
54873
|
function isWithinCwd(filePath) {
|
|
54673
54874
|
const cwd2 = process.cwd();
|
|
@@ -54675,7 +54876,7 @@ function isWithinCwd(filePath) {
|
|
|
54675
54876
|
const cwdPrefix = cwd2.endsWith(sep4) ? cwd2 : `${cwd2}${sep4}`;
|
|
54676
54877
|
if (!resolved.startsWith(cwdPrefix) && resolved !== cwd2)
|
|
54677
54878
|
return false;
|
|
54678
|
-
if (
|
|
54879
|
+
if (existsSync30(resolved)) {
|
|
54679
54880
|
try {
|
|
54680
54881
|
const real = realpathSync(resolved);
|
|
54681
54882
|
return real.startsWith(cwdPrefix) || real === cwd2;
|
|
@@ -54706,7 +54907,7 @@ function registerPlanRoutes(app) {
|
|
|
54706
54907
|
res.status(403).json({ error: "Path must be within current working directory" });
|
|
54707
54908
|
return;
|
|
54708
54909
|
}
|
|
54709
|
-
if (!
|
|
54910
|
+
if (!existsSync30(file)) {
|
|
54710
54911
|
res.status(404).json({ error: "File not found" });
|
|
54711
54912
|
return;
|
|
54712
54913
|
}
|
|
@@ -54728,7 +54929,7 @@ function registerPlanRoutes(app) {
|
|
|
54728
54929
|
res.status(403).json({ error: "Path must be within current working directory" });
|
|
54729
54930
|
return;
|
|
54730
54931
|
}
|
|
54731
|
-
if (!
|
|
54932
|
+
if (!existsSync30(file)) {
|
|
54732
54933
|
res.status(404).json({ error: "File not found" });
|
|
54733
54934
|
return;
|
|
54734
54935
|
}
|
|
@@ -54749,7 +54950,7 @@ function registerPlanRoutes(app) {
|
|
|
54749
54950
|
res.status(403).json({ error: "Path must be within current working directory" });
|
|
54750
54951
|
return;
|
|
54751
54952
|
}
|
|
54752
|
-
if (!
|
|
54953
|
+
if (!existsSync30(dir)) {
|
|
54753
54954
|
res.status(404).json({ error: "Directory not found" });
|
|
54754
54955
|
return;
|
|
54755
54956
|
}
|
|
@@ -54774,7 +54975,7 @@ function registerPlanRoutes(app) {
|
|
|
54774
54975
|
res.status(403).json({ error: "Path must be within current working directory" });
|
|
54775
54976
|
return;
|
|
54776
54977
|
}
|
|
54777
|
-
if (!
|
|
54978
|
+
if (!existsSync30(file)) {
|
|
54778
54979
|
res.status(404).json({ error: "File not found" });
|
|
54779
54980
|
return;
|
|
54780
54981
|
}
|
|
@@ -54791,8 +54992,8 @@ var init_plan_routes = __esm(() => {
|
|
|
54791
54992
|
});
|
|
54792
54993
|
|
|
54793
54994
|
// src/domains/web-server/routes/project-routes.ts
|
|
54794
|
-
import { existsSync as
|
|
54795
|
-
import { readFile as
|
|
54995
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
54996
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
54796
54997
|
import { homedir as homedir22 } from "node:os";
|
|
54797
54998
|
import { basename as basename13, join as join37, resolve as resolve11 } from "node:path";
|
|
54798
54999
|
function registerProjectRoutes(app) {
|
|
@@ -54911,7 +55112,7 @@ function registerProjectRoutes(app) {
|
|
|
54911
55112
|
res.status(400).json({ error: "Invalid path after expansion" });
|
|
54912
55113
|
return;
|
|
54913
55114
|
}
|
|
54914
|
-
if (!
|
|
55115
|
+
if (!existsSync31(projectPath)) {
|
|
54915
55116
|
res.status(400).json({ error: `Directory does not exist: ${projectPath}` });
|
|
54916
55117
|
return;
|
|
54917
55118
|
}
|
|
@@ -55027,14 +55228,14 @@ function registerProjectRoutes(app) {
|
|
|
55027
55228
|
async function buildProjectInfoFromRegistry(registered) {
|
|
55028
55229
|
const claudeDir2 = join37(registered.path, ".claude");
|
|
55029
55230
|
const metadataPath = join37(claudeDir2, "metadata.json");
|
|
55030
|
-
if (!
|
|
55231
|
+
if (!existsSync31(registered.path)) {
|
|
55031
55232
|
return null;
|
|
55032
55233
|
}
|
|
55033
|
-
const hasClaudeDir =
|
|
55234
|
+
const hasClaudeDir = existsSync31(claudeDir2);
|
|
55034
55235
|
let metadata = {};
|
|
55035
55236
|
try {
|
|
55036
|
-
if (hasClaudeDir &&
|
|
55037
|
-
const content = await
|
|
55237
|
+
if (hasClaudeDir && existsSync31(metadataPath)) {
|
|
55238
|
+
const content = await readFile21(metadataPath, "utf-8");
|
|
55038
55239
|
try {
|
|
55039
55240
|
metadata = JSON.parse(content);
|
|
55040
55241
|
} catch {}
|
|
@@ -55044,7 +55245,7 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55044
55245
|
const settings = await readSettings();
|
|
55045
55246
|
const skills = await scanSkills();
|
|
55046
55247
|
const settingsPath = join37(homedir22(), ".claude", "settings.json");
|
|
55047
|
-
const health =
|
|
55248
|
+
const health = existsSync31(settingsPath) ? "healthy" : "warning";
|
|
55048
55249
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55049
55250
|
return {
|
|
55050
55251
|
id: registered.id,
|
|
@@ -55068,15 +55269,15 @@ async function buildProjectInfoFromRegistry(registered) {
|
|
|
55068
55269
|
async function detectAndBuildProjectInfo(path4, id) {
|
|
55069
55270
|
const claudeDir2 = id === "global" ? path4 : join37(path4, ".claude");
|
|
55070
55271
|
const metadataPath = join37(claudeDir2, "metadata.json");
|
|
55071
|
-
if (!
|
|
55072
|
-
if (!
|
|
55272
|
+
if (!existsSync31(metadataPath)) {
|
|
55273
|
+
if (!existsSync31(claudeDir2)) {
|
|
55073
55274
|
return null;
|
|
55074
55275
|
}
|
|
55075
55276
|
}
|
|
55076
55277
|
let metadata = {};
|
|
55077
55278
|
try {
|
|
55078
|
-
if (
|
|
55079
|
-
const content = await
|
|
55279
|
+
if (existsSync31(metadataPath)) {
|
|
55280
|
+
const content = await readFile21(metadataPath, "utf-8");
|
|
55080
55281
|
try {
|
|
55081
55282
|
metadata = JSON.parse(content);
|
|
55082
55283
|
} catch {}
|
|
@@ -55086,7 +55287,7 @@ async function detectAndBuildProjectInfo(path4, id) {
|
|
|
55086
55287
|
const settings = await readSettings();
|
|
55087
55288
|
const skills = await scanSkills();
|
|
55088
55289
|
const settingsPath = join37(homedir22(), ".claude", "settings.json");
|
|
55089
|
-
const health =
|
|
55290
|
+
const health = existsSync31(settingsPath) ? "healthy" : "warning";
|
|
55090
55291
|
const model = getCurrentModel() || settings?.model || "claude-sonnet-4";
|
|
55091
55292
|
return {
|
|
55092
55293
|
id,
|
|
@@ -55279,7 +55480,7 @@ var init_settings_routes = __esm(() => {
|
|
|
55279
55480
|
});
|
|
55280
55481
|
|
|
55281
55482
|
// src/commands/skills/agents.ts
|
|
55282
|
-
import { existsSync as
|
|
55483
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
55283
55484
|
import { homedir as homedir25 } from "node:os";
|
|
55284
55485
|
import { join as join39 } from "node:path";
|
|
55285
55486
|
async function detectInstalledAgents() {
|
|
@@ -55301,7 +55502,7 @@ function getInstallPath(skillName, agent, options2) {
|
|
|
55301
55502
|
}
|
|
55302
55503
|
function isSkillInstalled(skillName, agent, options2) {
|
|
55303
55504
|
const installPath = getInstallPath(skillName, agent, options2);
|
|
55304
|
-
return
|
|
55505
|
+
return existsSync32(installPath);
|
|
55305
55506
|
}
|
|
55306
55507
|
var home6, agents;
|
|
55307
55508
|
var init_agents = __esm(() => {
|
|
@@ -55312,105 +55513,105 @@ var init_agents = __esm(() => {
|
|
|
55312
55513
|
displayName: "Claude Code",
|
|
55313
55514
|
projectPath: ".claude/skills",
|
|
55314
55515
|
globalPath: join39(home6, ".claude/skills"),
|
|
55315
|
-
detect: async () =>
|
|
55516
|
+
detect: async () => existsSync32(join39(home6, ".claude"))
|
|
55316
55517
|
},
|
|
55317
55518
|
cursor: {
|
|
55318
55519
|
name: "cursor",
|
|
55319
55520
|
displayName: "Cursor",
|
|
55320
55521
|
projectPath: ".cursor/skills",
|
|
55321
55522
|
globalPath: join39(home6, ".cursor/skills"),
|
|
55322
|
-
detect: async () =>
|
|
55523
|
+
detect: async () => existsSync32(join39(home6, ".cursor"))
|
|
55323
55524
|
},
|
|
55324
55525
|
codex: {
|
|
55325
55526
|
name: "codex",
|
|
55326
55527
|
displayName: "Codex",
|
|
55327
55528
|
projectPath: ".codex/skills",
|
|
55328
55529
|
globalPath: join39(home6, ".codex/skills"),
|
|
55329
|
-
detect: async () =>
|
|
55530
|
+
detect: async () => existsSync32(join39(home6, ".codex"))
|
|
55330
55531
|
},
|
|
55331
55532
|
opencode: {
|
|
55332
55533
|
name: "opencode",
|
|
55333
55534
|
displayName: "OpenCode",
|
|
55334
55535
|
projectPath: ".opencode/skills",
|
|
55335
55536
|
globalPath: join39(home6, ".config/opencode/skills"),
|
|
55336
|
-
detect: async () =>
|
|
55537
|
+
detect: async () => existsSync32(join39(home6, ".config/opencode"))
|
|
55337
55538
|
},
|
|
55338
55539
|
goose: {
|
|
55339
55540
|
name: "goose",
|
|
55340
55541
|
displayName: "Goose",
|
|
55341
55542
|
projectPath: ".goose/skills",
|
|
55342
55543
|
globalPath: join39(home6, ".config/goose/skills"),
|
|
55343
|
-
detect: async () =>
|
|
55544
|
+
detect: async () => existsSync32(join39(home6, ".config/goose"))
|
|
55344
55545
|
},
|
|
55345
55546
|
"gemini-cli": {
|
|
55346
55547
|
name: "gemini-cli",
|
|
55347
55548
|
displayName: "Gemini CLI",
|
|
55348
55549
|
projectPath: ".gemini/skills",
|
|
55349
55550
|
globalPath: join39(home6, ".gemini/skills"),
|
|
55350
|
-
detect: async () =>
|
|
55551
|
+
detect: async () => existsSync32(join39(home6, ".gemini"))
|
|
55351
55552
|
},
|
|
55352
55553
|
antigravity: {
|
|
55353
55554
|
name: "antigravity",
|
|
55354
55555
|
displayName: "Antigravity",
|
|
55355
55556
|
projectPath: ".agent/skills",
|
|
55356
55557
|
globalPath: join39(home6, ".gemini/antigravity/skills"),
|
|
55357
|
-
detect: async () =>
|
|
55558
|
+
detect: async () => existsSync32(join39(process.cwd(), ".agent")) || existsSync32(join39(home6, ".gemini/antigravity"))
|
|
55358
55559
|
},
|
|
55359
55560
|
"github-copilot": {
|
|
55360
55561
|
name: "github-copilot",
|
|
55361
55562
|
displayName: "GitHub Copilot",
|
|
55362
55563
|
projectPath: ".github/skills",
|
|
55363
55564
|
globalPath: join39(home6, ".copilot/skills"),
|
|
55364
|
-
detect: async () =>
|
|
55565
|
+
detect: async () => existsSync32(join39(home6, ".copilot"))
|
|
55365
55566
|
},
|
|
55366
55567
|
amp: {
|
|
55367
55568
|
name: "amp",
|
|
55368
55569
|
displayName: "Amp",
|
|
55369
55570
|
projectPath: ".agents/skills",
|
|
55370
55571
|
globalPath: join39(home6, ".config/agents/skills"),
|
|
55371
|
-
detect: async () =>
|
|
55572
|
+
detect: async () => existsSync32(join39(home6, ".config/amp"))
|
|
55372
55573
|
},
|
|
55373
55574
|
kilo: {
|
|
55374
55575
|
name: "kilo",
|
|
55375
55576
|
displayName: "Kilo Code",
|
|
55376
55577
|
projectPath: ".kilocode/skills",
|
|
55377
55578
|
globalPath: join39(home6, ".kilocode/skills"),
|
|
55378
|
-
detect: async () =>
|
|
55579
|
+
detect: async () => existsSync32(join39(home6, ".kilocode"))
|
|
55379
55580
|
},
|
|
55380
55581
|
roo: {
|
|
55381
55582
|
name: "roo",
|
|
55382
55583
|
displayName: "Roo Code",
|
|
55383
55584
|
projectPath: ".roo/skills",
|
|
55384
55585
|
globalPath: join39(home6, ".roo/skills"),
|
|
55385
|
-
detect: async () =>
|
|
55586
|
+
detect: async () => existsSync32(join39(home6, ".roo"))
|
|
55386
55587
|
},
|
|
55387
55588
|
windsurf: {
|
|
55388
55589
|
name: "windsurf",
|
|
55389
55590
|
displayName: "Windsurf",
|
|
55390
55591
|
projectPath: ".windsurf/skills",
|
|
55391
55592
|
globalPath: join39(home6, ".codeium/windsurf/skills"),
|
|
55392
|
-
detect: async () =>
|
|
55593
|
+
detect: async () => existsSync32(join39(home6, ".codeium/windsurf"))
|
|
55393
55594
|
},
|
|
55394
55595
|
cline: {
|
|
55395
55596
|
name: "cline",
|
|
55396
55597
|
displayName: "Cline",
|
|
55397
55598
|
projectPath: ".cline/skills",
|
|
55398
55599
|
globalPath: join39(home6, ".cline/skills"),
|
|
55399
|
-
detect: async () =>
|
|
55600
|
+
detect: async () => existsSync32(join39(home6, ".cline"))
|
|
55400
55601
|
},
|
|
55401
55602
|
openhands: {
|
|
55402
55603
|
name: "openhands",
|
|
55403
55604
|
displayName: "OpenHands",
|
|
55404
55605
|
projectPath: ".openhands/skills",
|
|
55405
55606
|
globalPath: join39(home6, ".openhands/skills"),
|
|
55406
|
-
detect: async () =>
|
|
55607
|
+
detect: async () => existsSync32(join39(home6, ".openhands"))
|
|
55407
55608
|
}
|
|
55408
55609
|
};
|
|
55409
55610
|
});
|
|
55410
55611
|
|
|
55411
55612
|
// src/commands/skills/skills-registry.ts
|
|
55412
|
-
import { existsSync as
|
|
55413
|
-
import { mkdir as mkdir9, readFile as
|
|
55613
|
+
import { existsSync as existsSync33 } from "node:fs";
|
|
55614
|
+
import { mkdir as mkdir9, readFile as readFile22, writeFile as writeFile11 } from "node:fs/promises";
|
|
55414
55615
|
import { homedir as homedir26 } from "node:os";
|
|
55415
55616
|
import { dirname as dirname16, join as join40 } from "node:path";
|
|
55416
55617
|
function getCliVersion3() {
|
|
@@ -55431,10 +55632,10 @@ function getCliVersion3() {
|
|
|
55431
55632
|
}
|
|
55432
55633
|
async function readRegistry() {
|
|
55433
55634
|
try {
|
|
55434
|
-
if (!
|
|
55635
|
+
if (!existsSync33(REGISTRY_PATH2)) {
|
|
55435
55636
|
return { version: "1.0", installations: [] };
|
|
55436
55637
|
}
|
|
55437
|
-
const content = await
|
|
55638
|
+
const content = await readFile22(REGISTRY_PATH2, "utf-8");
|
|
55438
55639
|
const data = JSON.parse(content);
|
|
55439
55640
|
return SkillRegistrySchema.parse(data);
|
|
55440
55641
|
} catch (error) {
|
|
@@ -55446,7 +55647,7 @@ async function readRegistry() {
|
|
|
55446
55647
|
}
|
|
55447
55648
|
async function writeRegistry(registry) {
|
|
55448
55649
|
const dir = dirname16(REGISTRY_PATH2);
|
|
55449
|
-
if (!
|
|
55650
|
+
if (!existsSync33(dir)) {
|
|
55450
55651
|
await mkdir9(dir, { recursive: true });
|
|
55451
55652
|
}
|
|
55452
55653
|
await writeFile11(REGISTRY_PATH2, JSON.stringify(registry, null, 2), "utf-8");
|
|
@@ -55490,7 +55691,7 @@ async function syncRegistry() {
|
|
|
55490
55691
|
const registry = await readRegistry();
|
|
55491
55692
|
const removed = [];
|
|
55492
55693
|
registry.installations = registry.installations.filter((i) => {
|
|
55493
|
-
if (!
|
|
55694
|
+
if (!existsSync33(i.path)) {
|
|
55494
55695
|
removed.push(i);
|
|
55495
55696
|
return false;
|
|
55496
55697
|
}
|
|
@@ -55522,7 +55723,7 @@ var init_skills_registry = __esm(() => {
|
|
|
55522
55723
|
});
|
|
55523
55724
|
|
|
55524
55725
|
// src/commands/skills/skills-installer.ts
|
|
55525
|
-
import { existsSync as
|
|
55726
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
55526
55727
|
import { cp as cp2, mkdir as mkdir10, stat as stat7 } from "node:fs/promises";
|
|
55527
55728
|
import { dirname as dirname17, resolve as resolve12 } from "node:path";
|
|
55528
55729
|
function isSamePath2(path1, path22) {
|
|
@@ -55567,10 +55768,10 @@ async function installSkillForAgent(skill, agent, options2) {
|
|
|
55567
55768
|
}
|
|
55568
55769
|
try {
|
|
55569
55770
|
const parentDir = dirname17(targetPath);
|
|
55570
|
-
if (!
|
|
55771
|
+
if (!existsSync34(parentDir)) {
|
|
55571
55772
|
await mkdir10(parentDir, { recursive: true });
|
|
55572
55773
|
}
|
|
55573
|
-
if (
|
|
55774
|
+
if (existsSync34(targetPath)) {
|
|
55574
55775
|
const stats = await stat7(targetPath);
|
|
55575
55776
|
if (stats.isFile()) {
|
|
55576
55777
|
return {
|
|
@@ -55626,7 +55827,7 @@ var init_skills_installer = __esm(() => {
|
|
|
55626
55827
|
});
|
|
55627
55828
|
|
|
55628
55829
|
// src/commands/skills/skills-uninstaller.ts
|
|
55629
|
-
import { existsSync as
|
|
55830
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
55630
55831
|
import { rm as rm7 } from "node:fs/promises";
|
|
55631
55832
|
import { join as join41 } from "node:path";
|
|
55632
55833
|
async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
@@ -55646,7 +55847,7 @@ async function uninstallSkillFromAgent(skill, agent, global3) {
|
|
|
55646
55847
|
}
|
|
55647
55848
|
const installation = installations[0];
|
|
55648
55849
|
const path4 = installation.path;
|
|
55649
|
-
const fileExists =
|
|
55850
|
+
const fileExists = existsSync35(path4);
|
|
55650
55851
|
try {
|
|
55651
55852
|
if (fileExists) {
|
|
55652
55853
|
await rm7(path4, { recursive: true, force: true });
|
|
@@ -55677,7 +55878,7 @@ async function forceUninstallSkill(skill, agent, global3) {
|
|
|
55677
55878
|
const agentConfig = agents[agent];
|
|
55678
55879
|
const basePath = global3 ? agentConfig.globalPath : agentConfig.projectPath;
|
|
55679
55880
|
const path4 = join41(basePath, skill);
|
|
55680
|
-
if (!
|
|
55881
|
+
if (!existsSync35(path4)) {
|
|
55681
55882
|
return {
|
|
55682
55883
|
skill,
|
|
55683
55884
|
agent,
|
|
@@ -56217,8 +56418,8 @@ var init_pnpm_detector = __esm(() => {
|
|
|
56217
56418
|
});
|
|
56218
56419
|
|
|
56219
56420
|
// src/domains/installation/package-managers/detection-core.ts
|
|
56220
|
-
import { existsSync as
|
|
56221
|
-
import { chmod as chmod2, mkdir as mkdir11, readFile as
|
|
56421
|
+
import { existsSync as existsSync36, realpathSync as realpathSync2 } from "node:fs";
|
|
56422
|
+
import { chmod as chmod2, mkdir as mkdir11, readFile as readFile23, writeFile as writeFile12 } from "node:fs/promises";
|
|
56222
56423
|
import { platform as platform4 } from "node:os";
|
|
56223
56424
|
import { join as join42 } from "node:path";
|
|
56224
56425
|
function detectFromBinaryPath() {
|
|
@@ -56298,10 +56499,10 @@ function detectFromEnv() {
|
|
|
56298
56499
|
async function readCachedPm() {
|
|
56299
56500
|
try {
|
|
56300
56501
|
const cacheFile = join42(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
56301
|
-
if (!
|
|
56502
|
+
if (!existsSync36(cacheFile)) {
|
|
56302
56503
|
return null;
|
|
56303
56504
|
}
|
|
56304
|
-
const content = await
|
|
56505
|
+
const content = await readFile23(cacheFile, "utf-8");
|
|
56305
56506
|
const data = JSON.parse(content);
|
|
56306
56507
|
if (!data.packageManager || !data.detectedAt) {
|
|
56307
56508
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -56329,7 +56530,7 @@ async function saveCachedPm(pm, getVersion) {
|
|
|
56329
56530
|
try {
|
|
56330
56531
|
const configDir = PathResolver.getConfigDir(false);
|
|
56331
56532
|
const cacheFile = join42(configDir, CACHE_FILE);
|
|
56332
|
-
if (!
|
|
56533
|
+
if (!existsSync36(configDir)) {
|
|
56333
56534
|
await mkdir11(configDir, { recursive: true });
|
|
56334
56535
|
if (platform4() !== "win32") {
|
|
56335
56536
|
await chmod2(configDir, 448);
|
|
@@ -56392,7 +56593,7 @@ async function clearCache() {
|
|
|
56392
56593
|
try {
|
|
56393
56594
|
const { unlink: unlink6 } = await import("node:fs/promises");
|
|
56394
56595
|
const cacheFile = join42(PathResolver.getConfigDir(false), CACHE_FILE);
|
|
56395
|
-
if (
|
|
56596
|
+
if (existsSync36(cacheFile)) {
|
|
56396
56597
|
await unlink6(cacheFile);
|
|
56397
56598
|
logger.debug("Package manager cache cleared");
|
|
56398
56599
|
}
|
|
@@ -56991,7 +57192,7 @@ var package_default;
|
|
|
56991
57192
|
var init_package = __esm(() => {
|
|
56992
57193
|
package_default = {
|
|
56993
57194
|
name: "claudekit-cli",
|
|
56994
|
-
version: "3.37.0-dev.
|
|
57195
|
+
version: "3.37.0-dev.6",
|
|
56995
57196
|
description: "CLI tool for bootstrapping and updating ClaudeKit projects",
|
|
56996
57197
|
type: "module",
|
|
56997
57198
|
repository: {
|
|
@@ -57551,8 +57752,8 @@ var init_error_handler2 = __esm(() => {
|
|
|
57551
57752
|
});
|
|
57552
57753
|
|
|
57553
57754
|
// src/domains/versioning/release-cache.ts
|
|
57554
|
-
import { existsSync as
|
|
57555
|
-
import { mkdir as mkdir12, readFile as
|
|
57755
|
+
import { existsSync as existsSync37 } from "node:fs";
|
|
57756
|
+
import { mkdir as mkdir12, readFile as readFile26, unlink as unlink6, writeFile as writeFile14 } from "node:fs/promises";
|
|
57556
57757
|
import { join as join45 } from "node:path";
|
|
57557
57758
|
var ReleaseCacheEntrySchema, ReleaseCache;
|
|
57558
57759
|
var init_release_cache = __esm(() => {
|
|
@@ -57573,11 +57774,11 @@ var init_release_cache = __esm(() => {
|
|
|
57573
57774
|
async get(key) {
|
|
57574
57775
|
const cacheFile = this.getCachePath(key);
|
|
57575
57776
|
try {
|
|
57576
|
-
if (!
|
|
57777
|
+
if (!existsSync37(cacheFile)) {
|
|
57577
57778
|
logger.debug(`Release cache not found for key: ${key}`);
|
|
57578
57779
|
return null;
|
|
57579
57780
|
}
|
|
57580
|
-
const content = await
|
|
57781
|
+
const content = await readFile26(cacheFile, "utf-8");
|
|
57581
57782
|
const parsed = JSON.parse(content);
|
|
57582
57783
|
const cacheEntry = ReleaseCacheEntrySchema.parse(parsed);
|
|
57583
57784
|
if (this.isExpired(cacheEntry.timestamp)) {
|
|
@@ -57613,7 +57814,7 @@ var init_release_cache = __esm(() => {
|
|
|
57613
57814
|
if (key) {
|
|
57614
57815
|
const cacheFile = this.getCachePath(key);
|
|
57615
57816
|
try {
|
|
57616
|
-
if (
|
|
57817
|
+
if (existsSync37(cacheFile)) {
|
|
57617
57818
|
await unlink6(cacheFile);
|
|
57618
57819
|
logger.debug(`Release cache cleared for key: ${key}`);
|
|
57619
57820
|
}
|
|
@@ -58674,8 +58875,8 @@ var init_update_cli = __esm(() => {
|
|
|
58674
58875
|
});
|
|
58675
58876
|
|
|
58676
58877
|
// src/domains/versioning/version-cache.ts
|
|
58677
|
-
import { existsSync as
|
|
58678
|
-
import { mkdir as mkdir13, readFile as
|
|
58878
|
+
import { existsSync as existsSync38 } from "node:fs";
|
|
58879
|
+
import { mkdir as mkdir13, readFile as readFile28, writeFile as writeFile15 } from "node:fs/promises";
|
|
58679
58880
|
import { join as join47 } from "node:path";
|
|
58680
58881
|
var VersionCacheManager;
|
|
58681
58882
|
var init_version_cache = __esm(() => {
|
|
@@ -58691,11 +58892,11 @@ var init_version_cache = __esm(() => {
|
|
|
58691
58892
|
static async load() {
|
|
58692
58893
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
58693
58894
|
try {
|
|
58694
|
-
if (!
|
|
58895
|
+
if (!existsSync38(cacheFile)) {
|
|
58695
58896
|
logger.debug("Version check cache not found");
|
|
58696
58897
|
return null;
|
|
58697
58898
|
}
|
|
58698
|
-
const content = await
|
|
58899
|
+
const content = await readFile28(cacheFile, "utf-8");
|
|
58699
58900
|
const cache3 = JSON.parse(content);
|
|
58700
58901
|
if (!cache3.lastCheck || !cache3.currentVersion || !cache3.latestVersion) {
|
|
58701
58902
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -58712,7 +58913,7 @@ var init_version_cache = __esm(() => {
|
|
|
58712
58913
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
58713
58914
|
const cacheDir = PathResolver.getCacheDir(false);
|
|
58714
58915
|
try {
|
|
58715
|
-
if (!
|
|
58916
|
+
if (!existsSync38(cacheDir)) {
|
|
58716
58917
|
await mkdir13(cacheDir, { recursive: true, mode: 448 });
|
|
58717
58918
|
}
|
|
58718
58919
|
await writeFile15(cacheFile, JSON.stringify(cache3, null, 2), "utf-8");
|
|
@@ -58734,7 +58935,7 @@ var init_version_cache = __esm(() => {
|
|
|
58734
58935
|
static async clear() {
|
|
58735
58936
|
const cacheFile = VersionCacheManager.getCacheFile();
|
|
58736
58937
|
try {
|
|
58737
|
-
if (
|
|
58938
|
+
if (existsSync38(cacheFile)) {
|
|
58738
58939
|
const fs6 = await import("node:fs/promises");
|
|
58739
58940
|
await fs6.unlink(cacheFile);
|
|
58740
58941
|
logger.debug("Version check cache cleared");
|
|
@@ -58953,8 +59154,8 @@ var init_version_checker = __esm(() => {
|
|
|
58953
59154
|
|
|
58954
59155
|
// src/domains/web-server/routes/system-routes.ts
|
|
58955
59156
|
import { spawn as spawn2 } from "node:child_process";
|
|
58956
|
-
import { existsSync as
|
|
58957
|
-
import { readFile as
|
|
59157
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
59158
|
+
import { readFile as readFile29 } from "node:fs/promises";
|
|
58958
59159
|
import { join as join48 } from "node:path";
|
|
58959
59160
|
function hasCliUpdate(currentVersion, latestVersion) {
|
|
58960
59161
|
if (!latestVersion) {
|
|
@@ -59199,9 +59400,9 @@ async function getPackageJson() {
|
|
|
59199
59400
|
async function getKitMetadata2(kitName) {
|
|
59200
59401
|
try {
|
|
59201
59402
|
const metadataPath = join48(PathResolver.getGlobalKitDir(), "metadata.json");
|
|
59202
|
-
if (!
|
|
59403
|
+
if (!existsSync39(metadataPath))
|
|
59203
59404
|
return null;
|
|
59204
|
-
const content = await
|
|
59405
|
+
const content = await readFile29(metadataPath, "utf-8");
|
|
59205
59406
|
const metadata = JSON.parse(content);
|
|
59206
59407
|
if (metadata.kits?.[kitName]) {
|
|
59207
59408
|
return { version: metadata.kits[kitName].version };
|
|
@@ -59344,8 +59545,8 @@ var init_routes = __esm(() => {
|
|
|
59344
59545
|
});
|
|
59345
59546
|
|
|
59346
59547
|
// src/domains/web-server/static-server.ts
|
|
59347
|
-
import { existsSync as
|
|
59348
|
-
import { dirname as dirname18, extname as extname4, join as join49 } from "node:path";
|
|
59548
|
+
import { existsSync as existsSync40 } from "node:fs";
|
|
59549
|
+
import { dirname as dirname18, extname as extname4, join as join49, resolve as resolve13 } from "node:path";
|
|
59349
59550
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
59350
59551
|
function tryServeFromEmbedded(app) {
|
|
59351
59552
|
if (typeof globalThis.Bun === "undefined" || !globalThis.Bun.embeddedFiles?.length) {
|
|
@@ -59404,25 +59605,38 @@ function tryServeFromEmbedded(app) {
|
|
|
59404
59605
|
});
|
|
59405
59606
|
return true;
|
|
59406
59607
|
}
|
|
59608
|
+
function addRuntimeUiCandidate(candidates, runtimePath) {
|
|
59609
|
+
if (!runtimePath) {
|
|
59610
|
+
return;
|
|
59611
|
+
}
|
|
59612
|
+
const looksLikePath = runtimePath.includes("/") || runtimePath.includes("\\") || existsSync40(runtimePath);
|
|
59613
|
+
if (!looksLikePath) {
|
|
59614
|
+
return;
|
|
59615
|
+
}
|
|
59616
|
+
const entryDir = dirname18(resolve13(runtimePath));
|
|
59617
|
+
candidates.add(join49(entryDir, "ui"));
|
|
59618
|
+
candidates.add(join49(entryDir, "..", "dist", "ui"));
|
|
59619
|
+
}
|
|
59407
59620
|
function resolveUiDistPath() {
|
|
59408
|
-
const candidates =
|
|
59409
|
-
|
|
59410
|
-
|
|
59411
|
-
|
|
59412
|
-
|
|
59621
|
+
const candidates = new Set;
|
|
59622
|
+
addRuntimeUiCandidate(candidates, process.execPath);
|
|
59623
|
+
addRuntimeUiCandidate(candidates, process.argv[1]);
|
|
59624
|
+
candidates.add(join49(__dirname3, "ui"));
|
|
59625
|
+
candidates.add(join49(process.cwd(), "dist", "ui"));
|
|
59626
|
+
candidates.add(join49(process.cwd(), "src", "ui", "dist"));
|
|
59413
59627
|
for (const path4 of candidates) {
|
|
59414
|
-
if (
|
|
59628
|
+
if (existsSync40(join49(path4, "index.html"))) {
|
|
59415
59629
|
return path4;
|
|
59416
59630
|
}
|
|
59417
59631
|
}
|
|
59418
|
-
return candidates[0];
|
|
59632
|
+
return Array.from(candidates)[0] ?? join49(process.cwd(), "dist", "ui");
|
|
59419
59633
|
}
|
|
59420
59634
|
function serveStatic(app) {
|
|
59421
59635
|
if (tryServeFromEmbedded(app)) {
|
|
59422
59636
|
return;
|
|
59423
59637
|
}
|
|
59424
59638
|
const uiDistPath = resolveUiDistPath();
|
|
59425
|
-
if (!
|
|
59639
|
+
if (!existsSync40(uiDistPath)) {
|
|
59426
59640
|
logger.warning(`UI dist not found at ${uiDistPath}. Run 'bun run ui:build' first.`);
|
|
59427
59641
|
app.use((req, res, next) => {
|
|
59428
59642
|
if (req.path.startsWith("/api/")) {
|
|
@@ -62444,10 +62658,10 @@ async function createAppServer(options2 = {}) {
|
|
|
62444
62658
|
wsManager = new WebSocketManager(server);
|
|
62445
62659
|
fileWatcher = new FileWatcher({ wsManager });
|
|
62446
62660
|
fileWatcher.start();
|
|
62447
|
-
await new Promise((
|
|
62661
|
+
await new Promise((resolve14, reject) => {
|
|
62448
62662
|
const onListening = () => {
|
|
62449
62663
|
server.off("error", onError);
|
|
62450
|
-
|
|
62664
|
+
resolve14();
|
|
62451
62665
|
};
|
|
62452
62666
|
const onError = (error) => {
|
|
62453
62667
|
server.off("listening", onListening);
|
|
@@ -62484,16 +62698,16 @@ async function createAppServer(options2 = {}) {
|
|
|
62484
62698
|
};
|
|
62485
62699
|
}
|
|
62486
62700
|
async function closeHttpServer(server) {
|
|
62487
|
-
await new Promise((
|
|
62701
|
+
await new Promise((resolve14) => {
|
|
62488
62702
|
if (!server.listening) {
|
|
62489
|
-
|
|
62703
|
+
resolve14();
|
|
62490
62704
|
return;
|
|
62491
62705
|
}
|
|
62492
62706
|
server.close((err) => {
|
|
62493
62707
|
if (err) {
|
|
62494
62708
|
logger.debug(`Server close error: ${err.message}`);
|
|
62495
62709
|
}
|
|
62496
|
-
|
|
62710
|
+
resolve14();
|
|
62497
62711
|
});
|
|
62498
62712
|
});
|
|
62499
62713
|
}
|
|
@@ -64229,7 +64443,7 @@ var require_picomatch2 = __commonJS((exports, module) => {
|
|
|
64229
64443
|
import { exec as exec7, execFile as execFile7, spawn as spawn3 } from "node:child_process";
|
|
64230
64444
|
import { promisify as promisify13 } from "node:util";
|
|
64231
64445
|
function executeInteractiveScript(command, args, options2) {
|
|
64232
|
-
return new Promise((
|
|
64446
|
+
return new Promise((resolve16, reject) => {
|
|
64233
64447
|
const child = spawn3(command, args, {
|
|
64234
64448
|
stdio: ["ignore", "inherit", "inherit"],
|
|
64235
64449
|
cwd: options2?.cwd,
|
|
@@ -64250,7 +64464,7 @@ function executeInteractiveScript(command, args, options2) {
|
|
|
64250
64464
|
} else if (code !== 0) {
|
|
64251
64465
|
reject(new Error(`Command exited with code ${code}`));
|
|
64252
64466
|
} else {
|
|
64253
|
-
|
|
64467
|
+
resolve16();
|
|
64254
64468
|
}
|
|
64255
64469
|
});
|
|
64256
64470
|
child.on("error", (error) => {
|
|
@@ -64271,7 +64485,7 @@ var init_process_executor = __esm(() => {
|
|
|
64271
64485
|
});
|
|
64272
64486
|
|
|
64273
64487
|
// src/services/package-installer/validators.ts
|
|
64274
|
-
import { resolve as
|
|
64488
|
+
import { resolve as resolve16 } from "node:path";
|
|
64275
64489
|
function validatePackageName(packageName) {
|
|
64276
64490
|
if (!packageName || typeof packageName !== "string") {
|
|
64277
64491
|
throw new Error("Package name must be a non-empty string");
|
|
@@ -64284,8 +64498,8 @@ function validatePackageName(packageName) {
|
|
|
64284
64498
|
}
|
|
64285
64499
|
}
|
|
64286
64500
|
function validateScriptPath(skillsDir2, scriptPath) {
|
|
64287
|
-
const skillsDirResolved =
|
|
64288
|
-
const scriptPathResolved =
|
|
64501
|
+
const skillsDirResolved = resolve16(skillsDir2);
|
|
64502
|
+
const scriptPathResolved = resolve16(scriptPath);
|
|
64289
64503
|
const skillsDirNormalized = isWindows() ? skillsDirResolved.toLowerCase() : skillsDirResolved;
|
|
64290
64504
|
const scriptPathNormalized = isWindows() ? scriptPathResolved.toLowerCase() : scriptPathResolved;
|
|
64291
64505
|
if (!scriptPathNormalized.startsWith(skillsDirNormalized)) {
|
|
@@ -64546,7 +64760,7 @@ var init_opencode_installer = __esm(() => {
|
|
|
64546
64760
|
var PARTIAL_INSTALL_VERSION = "partial", EXIT_CODE_CRITICAL_FAILURE = 1, EXIT_CODE_PARTIAL_SUCCESS = 2;
|
|
64547
64761
|
|
|
64548
64762
|
// src/services/package-installer/install-error-handler.ts
|
|
64549
|
-
import { existsSync as
|
|
64763
|
+
import { existsSync as existsSync51, readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
64550
64764
|
import { join as join68 } from "node:path";
|
|
64551
64765
|
function parseNameReason(str2) {
|
|
64552
64766
|
const colonIndex = str2.indexOf(":");
|
|
@@ -64557,7 +64771,7 @@ function parseNameReason(str2) {
|
|
|
64557
64771
|
}
|
|
64558
64772
|
function displayInstallErrors(skillsDir2) {
|
|
64559
64773
|
const summaryPath = join68(skillsDir2, ".install-error-summary.json");
|
|
64560
|
-
if (!
|
|
64774
|
+
if (!existsSync51(summaryPath)) {
|
|
64561
64775
|
logger.error("Skills installation failed. Run with --verbose for details.");
|
|
64562
64776
|
return;
|
|
64563
64777
|
}
|
|
@@ -64648,7 +64862,7 @@ async function checkNeedsSudoPackages() {
|
|
|
64648
64862
|
}
|
|
64649
64863
|
function hasInstallState(skillsDir2) {
|
|
64650
64864
|
const stateFilePath = join68(skillsDir2, ".install-state.json");
|
|
64651
|
-
return
|
|
64865
|
+
return existsSync51(stateFilePath);
|
|
64652
64866
|
}
|
|
64653
64867
|
var WHICH_COMMAND_TIMEOUT_MS = 5000;
|
|
64654
64868
|
var init_install_error_handler = __esm(() => {
|
|
@@ -64678,7 +64892,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64678
64892
|
};
|
|
64679
64893
|
}
|
|
64680
64894
|
try {
|
|
64681
|
-
const { existsSync:
|
|
64895
|
+
const { existsSync: existsSync52 } = await import("node:fs");
|
|
64682
64896
|
const clack = await Promise.resolve().then(() => (init_dist2(), exports_dist));
|
|
64683
64897
|
const platform7 = process.platform;
|
|
64684
64898
|
const scriptName = platform7 === "win32" ? "install.ps1" : "install.sh";
|
|
@@ -64694,7 +64908,7 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64694
64908
|
error: `Path validation failed: ${errorMessage}`
|
|
64695
64909
|
};
|
|
64696
64910
|
}
|
|
64697
|
-
if (!
|
|
64911
|
+
if (!existsSync52(scriptPath)) {
|
|
64698
64912
|
logger.warning(`Skills installation script not found: ${scriptPath}`);
|
|
64699
64913
|
logger.info("");
|
|
64700
64914
|
logger.info("\uD83D\uDCD6 Manual Installation Instructions:");
|
|
@@ -64714,8 +64928,8 @@ async function installSkillsDependencies(skillsDir2, options2 = {}) {
|
|
|
64714
64928
|
logger.info(` Platform: ${platform7 === "win32" ? "Windows (PowerShell)" : "Unix (bash)"}`);
|
|
64715
64929
|
if (logger.isVerbose()) {
|
|
64716
64930
|
try {
|
|
64717
|
-
const { readFile:
|
|
64718
|
-
const scriptContent = await
|
|
64931
|
+
const { readFile: readFile36 } = await import("node:fs/promises");
|
|
64932
|
+
const scriptContent = await readFile36(scriptPath, "utf-8");
|
|
64719
64933
|
const previewLines = scriptContent.split(`
|
|
64720
64934
|
`).slice(0, 20);
|
|
64721
64935
|
logger.verbose("Script preview (first 20 lines):");
|
|
@@ -64910,12 +65124,12 @@ var init_skills_installer2 = __esm(() => {
|
|
|
64910
65124
|
});
|
|
64911
65125
|
|
|
64912
65126
|
// src/services/package-installer/gemini-mcp/config-manager.ts
|
|
64913
|
-
import { existsSync as
|
|
64914
|
-
import { mkdir as mkdir17, readFile as
|
|
65127
|
+
import { existsSync as existsSync52 } from "node:fs";
|
|
65128
|
+
import { mkdir as mkdir17, readFile as readFile36, writeFile as writeFile20 } from "node:fs/promises";
|
|
64915
65129
|
import { dirname as dirname21, join as join70 } from "node:path";
|
|
64916
65130
|
async function readJsonFile(filePath) {
|
|
64917
65131
|
try {
|
|
64918
|
-
const content = await
|
|
65132
|
+
const content = await readFile36(filePath, "utf-8");
|
|
64919
65133
|
return JSON.parse(content);
|
|
64920
65134
|
} catch (error) {
|
|
64921
65135
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -64928,8 +65142,8 @@ async function addGeminiToGitignore(projectDir) {
|
|
|
64928
65142
|
const geminiPattern = ".gemini/";
|
|
64929
65143
|
try {
|
|
64930
65144
|
let content = "";
|
|
64931
|
-
if (
|
|
64932
|
-
content = await
|
|
65145
|
+
if (existsSync52(gitignorePath)) {
|
|
65146
|
+
content = await readFile36(gitignorePath, "utf-8");
|
|
64933
65147
|
const lines = content.split(`
|
|
64934
65148
|
`).map((line) => line.trim()).filter((line) => !line.startsWith("#"));
|
|
64935
65149
|
const geminiPatterns = [".gemini/", ".gemini", "/.gemini/", "/.gemini"];
|
|
@@ -64953,7 +65167,7 @@ ${geminiPattern}
|
|
|
64953
65167
|
}
|
|
64954
65168
|
async function createNewSettingsWithMerge(geminiSettingsPath, mcpConfigPath) {
|
|
64955
65169
|
const linkDir = dirname21(geminiSettingsPath);
|
|
64956
|
-
if (!
|
|
65170
|
+
if (!existsSync52(linkDir)) {
|
|
64957
65171
|
await mkdir17(linkDir, { recursive: true });
|
|
64958
65172
|
logger.debug(`Created directory: ${linkDir}`);
|
|
64959
65173
|
}
|
|
@@ -65014,7 +65228,7 @@ var init_config_manager2 = __esm(() => {
|
|
|
65014
65228
|
});
|
|
65015
65229
|
|
|
65016
65230
|
// src/services/package-installer/gemini-mcp/validation.ts
|
|
65017
|
-
import { existsSync as
|
|
65231
|
+
import { existsSync as existsSync53, lstatSync, readlinkSync } from "node:fs";
|
|
65018
65232
|
import { homedir as homedir29 } from "node:os";
|
|
65019
65233
|
import { join as join71 } from "node:path";
|
|
65020
65234
|
function getGlobalMcpConfigPath() {
|
|
@@ -65025,12 +65239,12 @@ function getLocalMcpConfigPath(projectDir) {
|
|
|
65025
65239
|
}
|
|
65026
65240
|
function findMcpConfigPath(projectDir) {
|
|
65027
65241
|
const localPath = getLocalMcpConfigPath(projectDir);
|
|
65028
|
-
if (
|
|
65242
|
+
if (existsSync53(localPath)) {
|
|
65029
65243
|
logger.debug(`Found local MCP config: ${localPath}`);
|
|
65030
65244
|
return localPath;
|
|
65031
65245
|
}
|
|
65032
65246
|
const globalPath = getGlobalMcpConfigPath();
|
|
65033
|
-
if (
|
|
65247
|
+
if (existsSync53(globalPath)) {
|
|
65034
65248
|
logger.debug(`Found global MCP config: ${globalPath}`);
|
|
65035
65249
|
return globalPath;
|
|
65036
65250
|
}
|
|
@@ -65045,7 +65259,7 @@ function getGeminiSettingsPath(projectDir, isGlobal) {
|
|
|
65045
65259
|
}
|
|
65046
65260
|
function checkExistingGeminiConfig(projectDir, isGlobal = false) {
|
|
65047
65261
|
const geminiSettingsPath = getGeminiSettingsPath(projectDir, isGlobal);
|
|
65048
|
-
if (!
|
|
65262
|
+
if (!existsSync53(geminiSettingsPath)) {
|
|
65049
65263
|
return { exists: false, isSymlink: false, settingsPath: geminiSettingsPath };
|
|
65050
65264
|
}
|
|
65051
65265
|
try {
|
|
@@ -65069,12 +65283,12 @@ var init_validation = __esm(() => {
|
|
|
65069
65283
|
});
|
|
65070
65284
|
|
|
65071
65285
|
// src/services/package-installer/gemini-mcp/linker-core.ts
|
|
65072
|
-
import { existsSync as
|
|
65286
|
+
import { existsSync as existsSync54 } from "node:fs";
|
|
65073
65287
|
import { mkdir as mkdir18, symlink as symlink2 } from "node:fs/promises";
|
|
65074
65288
|
import { dirname as dirname22, join as join72 } from "node:path";
|
|
65075
65289
|
async function createSymlink(targetPath, linkPath, projectDir, isGlobal) {
|
|
65076
65290
|
const linkDir = dirname22(linkPath);
|
|
65077
|
-
if (!
|
|
65291
|
+
if (!existsSync54(linkDir)) {
|
|
65078
65292
|
await mkdir18(linkDir, { recursive: true });
|
|
65079
65293
|
logger.debug(`Created directory: ${linkDir}`);
|
|
65080
65294
|
}
|
|
@@ -65115,10 +65329,10 @@ __export(exports_gemini_mcp_linker, {
|
|
|
65115
65329
|
checkExistingGeminiConfig: () => checkExistingGeminiConfig,
|
|
65116
65330
|
addGeminiToGitignore: () => addGeminiToGitignore
|
|
65117
65331
|
});
|
|
65118
|
-
import { resolve as
|
|
65332
|
+
import { resolve as resolve17 } from "node:path";
|
|
65119
65333
|
async function linkGeminiMcpConfig(projectDir, options2 = {}) {
|
|
65120
65334
|
const { skipGitignore = false, isGlobal = false } = options2;
|
|
65121
|
-
const resolvedProjectDir =
|
|
65335
|
+
const resolvedProjectDir = resolve17(projectDir);
|
|
65122
65336
|
const geminiSettingsPath = getGeminiSettingsPath(resolvedProjectDir, isGlobal);
|
|
65123
65337
|
const mcpConfigPath = findMcpConfigPath(resolvedProjectDir);
|
|
65124
65338
|
if (!mcpConfigPath) {
|
|
@@ -65766,7 +65980,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
65766
65980
|
};
|
|
65767
65981
|
const { maxBuffer } = options2;
|
|
65768
65982
|
let stream;
|
|
65769
|
-
await new Promise((
|
|
65983
|
+
await new Promise((resolve19, reject) => {
|
|
65770
65984
|
const rejectPromise = (error) => {
|
|
65771
65985
|
if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
|
|
65772
65986
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -65778,7 +65992,7 @@ var require_get_stream = __commonJS((exports, module) => {
|
|
|
65778
65992
|
rejectPromise(error);
|
|
65779
65993
|
return;
|
|
65780
65994
|
}
|
|
65781
|
-
|
|
65995
|
+
resolve19();
|
|
65782
65996
|
});
|
|
65783
65997
|
stream.on("data", () => {
|
|
65784
65998
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -67139,7 +67353,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
67139
67353
|
debug("opening", this.zipPath, "with opts", this.opts);
|
|
67140
67354
|
this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
|
|
67141
67355
|
this.canceled = false;
|
|
67142
|
-
return new Promise((
|
|
67356
|
+
return new Promise((resolve19, reject) => {
|
|
67143
67357
|
this.zipfile.on("error", (err) => {
|
|
67144
67358
|
this.canceled = true;
|
|
67145
67359
|
reject(err);
|
|
@@ -67148,7 +67362,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
67148
67362
|
this.zipfile.on("close", () => {
|
|
67149
67363
|
if (!this.canceled) {
|
|
67150
67364
|
debug("zip extraction complete");
|
|
67151
|
-
|
|
67365
|
+
resolve19();
|
|
67152
67366
|
}
|
|
67153
67367
|
});
|
|
67154
67368
|
this.zipfile.on("entry", async (entry) => {
|
|
@@ -67467,7 +67681,7 @@ async function restoreOriginalBranch(branchName, cwd2, issueNumber) {
|
|
|
67467
67681
|
}
|
|
67468
67682
|
}
|
|
67469
67683
|
function spawnAndCollect(command, args, cwd2) {
|
|
67470
|
-
return new Promise((
|
|
67684
|
+
return new Promise((resolve32, reject) => {
|
|
67471
67685
|
const child = spawn4(command, args, { ...cwd2 && { cwd: cwd2 }, stdio: ["ignore", "pipe", "pipe"] });
|
|
67472
67686
|
const chunks = [];
|
|
67473
67687
|
const stderrChunks = [];
|
|
@@ -67480,7 +67694,7 @@ function spawnAndCollect(command, args, cwd2) {
|
|
|
67480
67694
|
reject(new Error(`${command} ${args[0] ?? ""} exited with code ${code2}: ${stderr}`));
|
|
67481
67695
|
return;
|
|
67482
67696
|
}
|
|
67483
|
-
|
|
67697
|
+
resolve32(Buffer.concat(chunks).toString("utf-8"));
|
|
67484
67698
|
});
|
|
67485
67699
|
});
|
|
67486
67700
|
}
|
|
@@ -67497,8 +67711,8 @@ __export(exports_worktree_manager, {
|
|
|
67497
67711
|
createWorktree: () => createWorktree,
|
|
67498
67712
|
cleanupAllWorktrees: () => cleanupAllWorktrees
|
|
67499
67713
|
});
|
|
67500
|
-
import { existsSync as
|
|
67501
|
-
import { readFile as
|
|
67714
|
+
import { existsSync as existsSync62 } from "node:fs";
|
|
67715
|
+
import { readFile as readFile53, writeFile as writeFile33 } from "node:fs/promises";
|
|
67502
67716
|
import { join as join123 } from "node:path";
|
|
67503
67717
|
async function createWorktree(projectDir, issueNumber, baseBranch) {
|
|
67504
67718
|
const worktreePath = join123(projectDir, WORKTREE_DIR, `issue-${issueNumber}`);
|
|
@@ -67563,7 +67777,7 @@ async function cleanupAllWorktrees(projectDir) {
|
|
|
67563
67777
|
async function ensureGitignore(projectDir) {
|
|
67564
67778
|
const gitignorePath = join123(projectDir, ".gitignore");
|
|
67565
67779
|
try {
|
|
67566
|
-
const content =
|
|
67780
|
+
const content = existsSync62(gitignorePath) ? await readFile53(gitignorePath, "utf-8") : "";
|
|
67567
67781
|
if (!content.includes(".worktrees")) {
|
|
67568
67782
|
const newContent = content.endsWith(`
|
|
67569
67783
|
`) ? `${content}.worktrees/
|
|
@@ -67665,13 +67879,13 @@ var init_content_validator = __esm(() => {
|
|
|
67665
67879
|
|
|
67666
67880
|
// src/commands/content/phases/context-cache-manager.ts
|
|
67667
67881
|
import { createHash as createHash6 } from "node:crypto";
|
|
67668
|
-
import { existsSync as
|
|
67882
|
+
import { existsSync as existsSync68, mkdirSync as mkdirSync4, readFileSync as readFileSync14, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
|
|
67669
67883
|
import { rename as rename9, writeFile as writeFile35 } from "node:fs/promises";
|
|
67670
67884
|
import { homedir as homedir33 } from "node:os";
|
|
67671
67885
|
import { basename as basename19, join as join130 } from "node:path";
|
|
67672
67886
|
function getCachedContext(repoPath) {
|
|
67673
67887
|
const cachePath = getCacheFilePath(repoPath);
|
|
67674
|
-
if (!
|
|
67888
|
+
if (!existsSync68(cachePath))
|
|
67675
67889
|
return null;
|
|
67676
67890
|
try {
|
|
67677
67891
|
const raw2 = readFileSync14(cachePath, "utf-8");
|
|
@@ -67688,7 +67902,7 @@ function getCachedContext(repoPath) {
|
|
|
67688
67902
|
}
|
|
67689
67903
|
}
|
|
67690
67904
|
async function saveCachedContext(repoPath, cache5) {
|
|
67691
|
-
if (!
|
|
67905
|
+
if (!existsSync68(CACHE_DIR)) {
|
|
67692
67906
|
mkdirSync4(CACHE_DIR, { recursive: true });
|
|
67693
67907
|
}
|
|
67694
67908
|
const cachePath = getCacheFilePath(repoPath);
|
|
@@ -67712,7 +67926,7 @@ function computeSourceHash(repoPath) {
|
|
|
67712
67926
|
function getDocSourcePaths(repoPath) {
|
|
67713
67927
|
const paths = [];
|
|
67714
67928
|
const docsDir = join130(repoPath, "docs");
|
|
67715
|
-
if (
|
|
67929
|
+
if (existsSync68(docsDir)) {
|
|
67716
67930
|
try {
|
|
67717
67931
|
const files = readdirSync8(docsDir);
|
|
67718
67932
|
for (const f3 of files) {
|
|
@@ -67722,10 +67936,10 @@ function getDocSourcePaths(repoPath) {
|
|
|
67722
67936
|
} catch {}
|
|
67723
67937
|
}
|
|
67724
67938
|
const readme = join130(repoPath, "README.md");
|
|
67725
|
-
if (
|
|
67939
|
+
if (existsSync68(readme))
|
|
67726
67940
|
paths.push(readme);
|
|
67727
67941
|
const stylesDir = join130(repoPath, "assets", "writing-styles");
|
|
67728
|
-
if (
|
|
67942
|
+
if (existsSync68(stylesDir)) {
|
|
67729
67943
|
try {
|
|
67730
67944
|
const files = readdirSync8(stylesDir);
|
|
67731
67945
|
for (const f3 of files) {
|
|
@@ -67922,7 +68136,7 @@ function extractContentFromResponse(response) {
|
|
|
67922
68136
|
|
|
67923
68137
|
// src/commands/content/phases/docs-summarizer.ts
|
|
67924
68138
|
import { execSync as execSync6 } from "node:child_process";
|
|
67925
|
-
import { existsSync as
|
|
68139
|
+
import { existsSync as existsSync69, readFileSync as readFileSync15, readdirSync as readdirSync9 } from "node:fs";
|
|
67926
68140
|
import { join as join131 } from "node:path";
|
|
67927
68141
|
async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
67928
68142
|
const rawContent = collectRawDocs(repoPath);
|
|
@@ -67967,7 +68181,7 @@ async function summarizeProjectDocs(repoPath, contentLogger) {
|
|
|
67967
68181
|
function collectRawDocs(repoPath) {
|
|
67968
68182
|
let totalChars = 0;
|
|
67969
68183
|
const readCapped = (filePath, maxChars) => {
|
|
67970
|
-
if (!
|
|
68184
|
+
if (!existsSync69(filePath))
|
|
67971
68185
|
return "";
|
|
67972
68186
|
if (totalChars >= MAX_RAW_CONTENT_CHARS)
|
|
67973
68187
|
return "";
|
|
@@ -67978,7 +68192,7 @@ function collectRawDocs(repoPath) {
|
|
|
67978
68192
|
};
|
|
67979
68193
|
const docsContent = [];
|
|
67980
68194
|
const docsDir = join131(repoPath, "docs");
|
|
67981
|
-
if (
|
|
68195
|
+
if (existsSync69(docsDir)) {
|
|
67982
68196
|
try {
|
|
67983
68197
|
const files = readdirSync9(docsDir).filter((f3) => f3.endsWith(".md")).sort();
|
|
67984
68198
|
for (const f3 of files) {
|
|
@@ -68002,7 +68216,7 @@ ${content}`);
|
|
|
68002
68216
|
}
|
|
68003
68217
|
let styles3 = "";
|
|
68004
68218
|
const stylesDir = join131(repoPath, "assets", "writing-styles");
|
|
68005
|
-
if (
|
|
68219
|
+
if (existsSync69(stylesDir)) {
|
|
68006
68220
|
try {
|
|
68007
68221
|
const files = readdirSync9(stylesDir).slice(0, 3);
|
|
68008
68222
|
styles3 = files.map((f3) => readCapped(join131(stylesDir, f3), 1000)).filter(Boolean).join(`
|
|
@@ -68195,12 +68409,12 @@ IMPORTANT: Generate the image and output the path as JSON: {"imagePath": "/path/
|
|
|
68195
68409
|
|
|
68196
68410
|
// src/commands/content/phases/photo-generator.ts
|
|
68197
68411
|
import { execSync as execSync7 } from "node:child_process";
|
|
68198
|
-
import { existsSync as
|
|
68412
|
+
import { existsSync as existsSync70, mkdirSync as mkdirSync5, readdirSync as readdirSync10 } from "node:fs";
|
|
68199
68413
|
import { homedir as homedir34 } from "node:os";
|
|
68200
68414
|
import { join as join132 } from "node:path";
|
|
68201
68415
|
async function generatePhoto(_content, context, config, platform14, contentId, contentLogger) {
|
|
68202
68416
|
const mediaDir = join132(config.contentDir.replace(/^~/, homedir34()), "media", String(contentId));
|
|
68203
|
-
if (!
|
|
68417
|
+
if (!existsSync70(mediaDir)) {
|
|
68204
68418
|
mkdirSync5(mediaDir, { recursive: true });
|
|
68205
68419
|
}
|
|
68206
68420
|
const prompt = buildPhotoPrompt(context, platform14);
|
|
@@ -68216,7 +68430,7 @@ async function generatePhoto(_content, context, config, platform14, contentId, c
|
|
|
68216
68430
|
const parsed = parseClaudeJsonOutput(result);
|
|
68217
68431
|
if (parsed && typeof parsed === "object" && "imagePath" in parsed) {
|
|
68218
68432
|
const imagePath = String(parsed.imagePath);
|
|
68219
|
-
if (
|
|
68433
|
+
if (existsSync70(imagePath)) {
|
|
68220
68434
|
return { path: imagePath, ...dimensions, format: "png" };
|
|
68221
68435
|
}
|
|
68222
68436
|
}
|
|
@@ -68312,7 +68526,7 @@ var init_content_creator = __esm(() => {
|
|
|
68312
68526
|
});
|
|
68313
68527
|
|
|
68314
68528
|
// src/commands/content/phases/content-logger.ts
|
|
68315
|
-
import { createWriteStream as createWriteStream4, existsSync as
|
|
68529
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync71, mkdirSync as mkdirSync6, statSync as statSync11 } from "node:fs";
|
|
68316
68530
|
import { homedir as homedir35 } from "node:os";
|
|
68317
68531
|
import { join as join133 } from "node:path";
|
|
68318
68532
|
|
|
@@ -68326,7 +68540,7 @@ class ContentLogger {
|
|
|
68326
68540
|
this.maxBytes = maxBytes;
|
|
68327
68541
|
}
|
|
68328
68542
|
init() {
|
|
68329
|
-
if (!
|
|
68543
|
+
if (!existsSync71(this.logDir)) {
|
|
68330
68544
|
mkdirSync6(this.logDir, { recursive: true });
|
|
68331
68545
|
}
|
|
68332
68546
|
this.rotateIfNeeded();
|
|
@@ -68413,7 +68627,7 @@ var init_content_logger = __esm(() => {
|
|
|
68413
68627
|
|
|
68414
68628
|
// src/commands/content/phases/db-manager.ts
|
|
68415
68629
|
import { Database } from "bun:sqlite";
|
|
68416
|
-
import { existsSync as
|
|
68630
|
+
import { existsSync as existsSync72, mkdirSync as mkdirSync7 } from "node:fs";
|
|
68417
68631
|
import { dirname as dirname33 } from "node:path";
|
|
68418
68632
|
function initDatabase(dbPath) {
|
|
68419
68633
|
ensureParentDir(dbPath);
|
|
@@ -68436,7 +68650,7 @@ function runRetentionCleanup(db, retentionDays = 90) {
|
|
|
68436
68650
|
}
|
|
68437
68651
|
function ensureParentDir(dbPath) {
|
|
68438
68652
|
const dir = dirname33(dbPath);
|
|
68439
|
-
if (dir && !
|
|
68653
|
+
if (dir && !existsSync72(dir)) {
|
|
68440
68654
|
mkdirSync7(dir, { recursive: true });
|
|
68441
68655
|
}
|
|
68442
68656
|
}
|
|
@@ -68599,7 +68813,7 @@ function isNoiseCommit(title, author) {
|
|
|
68599
68813
|
|
|
68600
68814
|
// src/commands/content/phases/change-detector.ts
|
|
68601
68815
|
import { execSync as execSync9 } from "node:child_process";
|
|
68602
|
-
import { existsSync as
|
|
68816
|
+
import { existsSync as existsSync73, readFileSync as readFileSync16, readdirSync as readdirSync11, statSync as statSync12 } from "node:fs";
|
|
68603
68817
|
import { join as join134 } from "node:path";
|
|
68604
68818
|
function detectCommits(repo, since) {
|
|
68605
68819
|
try {
|
|
@@ -68699,7 +68913,7 @@ function detectTags(repo, since) {
|
|
|
68699
68913
|
}
|
|
68700
68914
|
function detectCompletedPlans(repo, since) {
|
|
68701
68915
|
const plansDir = join134(repo.path, "plans");
|
|
68702
|
-
if (!
|
|
68916
|
+
if (!existsSync73(plansDir))
|
|
68703
68917
|
return [];
|
|
68704
68918
|
const sinceMs = new Date(since).getTime();
|
|
68705
68919
|
const events = [];
|
|
@@ -68709,7 +68923,7 @@ function detectCompletedPlans(repo, since) {
|
|
|
68709
68923
|
if (!entry.isDirectory())
|
|
68710
68924
|
continue;
|
|
68711
68925
|
const planFile = join134(plansDir, entry.name, "plan.md");
|
|
68712
|
-
if (!
|
|
68926
|
+
if (!existsSync73(planFile))
|
|
68713
68927
|
continue;
|
|
68714
68928
|
try {
|
|
68715
68929
|
const stat20 = statSync12(planFile);
|
|
@@ -69465,12 +69679,12 @@ var init_types6 = __esm(() => {
|
|
|
69465
69679
|
});
|
|
69466
69680
|
|
|
69467
69681
|
// src/commands/content/phases/state-manager.ts
|
|
69468
|
-
import { readFile as
|
|
69682
|
+
import { readFile as readFile55, rename as rename10, writeFile as writeFile36 } from "node:fs/promises";
|
|
69469
69683
|
import { join as join136 } from "node:path";
|
|
69470
69684
|
async function loadContentConfig(projectDir) {
|
|
69471
69685
|
const configPath = join136(projectDir, CK_CONFIG_FILE2);
|
|
69472
69686
|
try {
|
|
69473
|
-
const raw2 = await
|
|
69687
|
+
const raw2 = await readFile55(configPath, "utf-8");
|
|
69474
69688
|
const json = JSON.parse(raw2);
|
|
69475
69689
|
return ContentConfigSchema.parse(json.content ?? {});
|
|
69476
69690
|
} catch {
|
|
@@ -69486,7 +69700,7 @@ async function saveContentConfig(projectDir, config) {
|
|
|
69486
69700
|
async function loadContentState(projectDir) {
|
|
69487
69701
|
const configPath = join136(projectDir, CK_CONFIG_FILE2);
|
|
69488
69702
|
try {
|
|
69489
|
-
const raw2 = await
|
|
69703
|
+
const raw2 = await readFile55(configPath, "utf-8");
|
|
69490
69704
|
const json = JSON.parse(raw2);
|
|
69491
69705
|
const contentBlock = json.content ?? {};
|
|
69492
69706
|
return ContentStateSchema.parse(contentBlock.state ?? {});
|
|
@@ -69513,7 +69727,7 @@ async function saveContentState(projectDir, state) {
|
|
|
69513
69727
|
}
|
|
69514
69728
|
async function readJsonSafe(filePath) {
|
|
69515
69729
|
try {
|
|
69516
|
-
const raw2 = await
|
|
69730
|
+
const raw2 = await readFile55(filePath, "utf-8");
|
|
69517
69731
|
return JSON.parse(raw2);
|
|
69518
69732
|
} catch {
|
|
69519
69733
|
return {};
|
|
@@ -69776,7 +69990,7 @@ var init_platform_setup_x = __esm(() => {
|
|
|
69776
69990
|
});
|
|
69777
69991
|
|
|
69778
69992
|
// src/commands/content/phases/setup-wizard.ts
|
|
69779
|
-
import { existsSync as
|
|
69993
|
+
import { existsSync as existsSync74 } from "node:fs";
|
|
69780
69994
|
import { join as join137 } from "node:path";
|
|
69781
69995
|
async function runSetupWizard2(cwd2, contentLogger) {
|
|
69782
69996
|
console.log();
|
|
@@ -69845,8 +70059,8 @@ async function showRepoSummary(cwd2) {
|
|
|
69845
70059
|
function detectBrandAssets(cwd2, contentLogger) {
|
|
69846
70060
|
const repos = discoverRepos2(cwd2);
|
|
69847
70061
|
for (const repo of repos) {
|
|
69848
|
-
const hasGuidelines =
|
|
69849
|
-
const hasStyles =
|
|
70062
|
+
const hasGuidelines = existsSync74(join137(repo.path, "docs", "brand-guidelines.md"));
|
|
70063
|
+
const hasStyles = existsSync74(join137(repo.path, "assets", "writing-styles"));
|
|
69850
70064
|
if (!hasGuidelines) {
|
|
69851
70065
|
f2.warning(`${repo.name}: No docs/brand-guidelines.md — content will use generic tone.`);
|
|
69852
70066
|
contentLogger.warn(`${repo.name}: missing docs/brand-guidelines.md`);
|
|
@@ -69912,13 +70126,13 @@ var init_setup_wizard = __esm(() => {
|
|
|
69912
70126
|
});
|
|
69913
70127
|
|
|
69914
70128
|
// src/commands/content/content-review-commands.ts
|
|
69915
|
-
import { existsSync as
|
|
70129
|
+
import { existsSync as existsSync75 } from "node:fs";
|
|
69916
70130
|
import { homedir as homedir36 } from "node:os";
|
|
69917
70131
|
async function queueContent() {
|
|
69918
70132
|
const cwd2 = process.cwd();
|
|
69919
70133
|
const config = await loadContentConfig(cwd2);
|
|
69920
70134
|
const dbPath = config.dbPath.replace(/^~/, homedir36());
|
|
69921
|
-
if (!
|
|
70135
|
+
if (!existsSync75(dbPath)) {
|
|
69922
70136
|
logger.info("No content database found. Run 'ck content setup' first.");
|
|
69923
70137
|
return;
|
|
69924
70138
|
}
|
|
@@ -69986,12 +70200,12 @@ __export(exports_content_subcommands, {
|
|
|
69986
70200
|
logsContent: () => logsContent,
|
|
69987
70201
|
approveContentCmd: () => approveContentCmd
|
|
69988
70202
|
});
|
|
69989
|
-
import { existsSync as
|
|
70203
|
+
import { existsSync as existsSync76, readFileSync as readFileSync17, unlinkSync as unlinkSync5 } from "node:fs";
|
|
69990
70204
|
import { homedir as homedir37 } from "node:os";
|
|
69991
70205
|
import { join as join138 } from "node:path";
|
|
69992
70206
|
function isDaemonRunning() {
|
|
69993
70207
|
const lockFile = join138(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
69994
|
-
if (!
|
|
70208
|
+
if (!existsSync76(lockFile))
|
|
69995
70209
|
return { running: false, pid: null };
|
|
69996
70210
|
try {
|
|
69997
70211
|
const pidStr = readFileSync17(lockFile, "utf-8").trim();
|
|
@@ -70023,7 +70237,7 @@ async function startContent(options2) {
|
|
|
70023
70237
|
}
|
|
70024
70238
|
async function stopContent() {
|
|
70025
70239
|
const lockFile = join138(LOCK_DIR, `${LOCK_NAME2}.lock`);
|
|
70026
|
-
if (!
|
|
70240
|
+
if (!existsSync76(lockFile)) {
|
|
70027
70241
|
logger.info("Content daemon is not running.");
|
|
70028
70242
|
return;
|
|
70029
70243
|
}
|
|
@@ -70064,7 +70278,7 @@ async function logsContent(options2) {
|
|
|
70064
70278
|
const logDir = join138(homedir37(), ".claudekit", "logs");
|
|
70065
70279
|
const dateStr = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
|
70066
70280
|
const logPath = join138(logDir, `content-${dateStr}.log`);
|
|
70067
|
-
if (!
|
|
70281
|
+
if (!existsSync76(logPath)) {
|
|
70068
70282
|
logger.info("No content logs found for today.");
|
|
70069
70283
|
return;
|
|
70070
70284
|
}
|
|
@@ -70099,7 +70313,7 @@ var init_content_subcommands = __esm(() => {
|
|
|
70099
70313
|
});
|
|
70100
70314
|
|
|
70101
70315
|
// src/commands/content/content-command.ts
|
|
70102
|
-
import { existsSync as
|
|
70316
|
+
import { existsSync as existsSync77, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
70103
70317
|
import { homedir as homedir38 } from "node:os";
|
|
70104
70318
|
import { join as join139 } from "node:path";
|
|
70105
70319
|
async function contentCommand(options2) {
|
|
@@ -70130,7 +70344,7 @@ async function contentCommand(options2) {
|
|
|
70130
70344
|
}
|
|
70131
70345
|
contentLogger.info("Setup complete. Starting daemon...");
|
|
70132
70346
|
}
|
|
70133
|
-
if (!
|
|
70347
|
+
if (!existsSync77(LOCK_DIR2))
|
|
70134
70348
|
mkdirSync8(LOCK_DIR2, { recursive: true });
|
|
70135
70349
|
writeFileSync6(LOCK_FILE, String(process.pid), "utf-8");
|
|
70136
70350
|
const dbPath = config.dbPath.replace(/^~/, homedir38());
|
|
@@ -70262,8 +70476,8 @@ function shouldRunCleanup(lastAt) {
|
|
|
70262
70476
|
return Date.now() - new Date(lastAt).getTime() >= 86400000;
|
|
70263
70477
|
}
|
|
70264
70478
|
function sleep2(ms) {
|
|
70265
|
-
return new Promise((
|
|
70266
|
-
setTimeout(
|
|
70479
|
+
return new Promise((resolve32) => {
|
|
70480
|
+
setTimeout(resolve32, ms);
|
|
70267
70481
|
});
|
|
70268
70482
|
}
|
|
70269
70483
|
var LOCK_DIR2, LOCK_FILE, MAX_CREATION_RETRIES = 3, MAX_PUBLISH_RETRIES_PER_CYCLE = 3, PUBLISH_RETRY_WINDOW_HOURS = 24;
|
|
@@ -71580,7 +71794,7 @@ function getPagerArgs(pagerCmd) {
|
|
|
71580
71794
|
return [];
|
|
71581
71795
|
}
|
|
71582
71796
|
async function trySystemPager(content) {
|
|
71583
|
-
return new Promise((
|
|
71797
|
+
return new Promise((resolve32) => {
|
|
71584
71798
|
const pagerCmd = process.env.PAGER || "less";
|
|
71585
71799
|
const pagerArgs = getPagerArgs(pagerCmd);
|
|
71586
71800
|
try {
|
|
@@ -71590,20 +71804,20 @@ async function trySystemPager(content) {
|
|
|
71590
71804
|
});
|
|
71591
71805
|
const timeout2 = setTimeout(() => {
|
|
71592
71806
|
pager.kill();
|
|
71593
|
-
|
|
71807
|
+
resolve32(false);
|
|
71594
71808
|
}, 30000);
|
|
71595
71809
|
pager.stdin.write(content);
|
|
71596
71810
|
pager.stdin.end();
|
|
71597
71811
|
pager.on("close", (code2) => {
|
|
71598
71812
|
clearTimeout(timeout2);
|
|
71599
|
-
|
|
71813
|
+
resolve32(code2 === 0);
|
|
71600
71814
|
});
|
|
71601
71815
|
pager.on("error", () => {
|
|
71602
71816
|
clearTimeout(timeout2);
|
|
71603
|
-
|
|
71817
|
+
resolve32(false);
|
|
71604
71818
|
});
|
|
71605
71819
|
} catch {
|
|
71606
|
-
|
|
71820
|
+
resolve32(false);
|
|
71607
71821
|
}
|
|
71608
71822
|
});
|
|
71609
71823
|
}
|
|
@@ -71630,16 +71844,16 @@ async function basicPager(content) {
|
|
|
71630
71844
|
break;
|
|
71631
71845
|
}
|
|
71632
71846
|
const remaining = lines.length - currentLine;
|
|
71633
|
-
await new Promise((
|
|
71847
|
+
await new Promise((resolve32) => {
|
|
71634
71848
|
rl.question(`-- More (${remaining} lines) [Enter/q] --`, (answer) => {
|
|
71635
71849
|
if (answer.toLowerCase() === "q") {
|
|
71636
71850
|
rl.close();
|
|
71637
71851
|
process.exitCode = 0;
|
|
71638
|
-
|
|
71852
|
+
resolve32();
|
|
71639
71853
|
return;
|
|
71640
71854
|
}
|
|
71641
71855
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
71642
|
-
|
|
71856
|
+
resolve32();
|
|
71643
71857
|
});
|
|
71644
71858
|
});
|
|
71645
71859
|
}
|
|
@@ -75040,12 +75254,12 @@ async function configUICommand(options2 = {}) {
|
|
|
75040
75254
|
console.log();
|
|
75041
75255
|
console.log(import_picocolors14.default.dim(" Press Ctrl+C to stop"));
|
|
75042
75256
|
console.log();
|
|
75043
|
-
await new Promise((
|
|
75257
|
+
await new Promise((resolve14) => {
|
|
75044
75258
|
const shutdown = async () => {
|
|
75045
75259
|
console.log();
|
|
75046
75260
|
logger.info("Shutting down...");
|
|
75047
75261
|
await server.close();
|
|
75048
|
-
|
|
75262
|
+
resolve14();
|
|
75049
75263
|
};
|
|
75050
75264
|
process.on("SIGINT", shutdown);
|
|
75051
75265
|
process.on("SIGTERM", shutdown);
|
|
@@ -75066,12 +75280,12 @@ async function configUICommand(options2 = {}) {
|
|
|
75066
75280
|
}
|
|
75067
75281
|
async function checkPort(port, host) {
|
|
75068
75282
|
const { createServer: createServer2 } = await import("node:net");
|
|
75069
|
-
return new Promise((
|
|
75283
|
+
return new Promise((resolve14) => {
|
|
75070
75284
|
const server = createServer2();
|
|
75071
|
-
server.once("error", () =>
|
|
75285
|
+
server.once("error", () => resolve14(false));
|
|
75072
75286
|
server.once("listening", () => {
|
|
75073
75287
|
server.close();
|
|
75074
|
-
|
|
75288
|
+
resolve14(true);
|
|
75075
75289
|
});
|
|
75076
75290
|
server.listen(port, host);
|
|
75077
75291
|
});
|
|
@@ -75272,9 +75486,11 @@ async function configCommand(action, keyOrOptions, valueOrOptions, options2) {
|
|
|
75272
75486
|
return;
|
|
75273
75487
|
}
|
|
75274
75488
|
const rawOpts = options2 || (typeof keyOrOptions === "object" ? keyOrOptions : {});
|
|
75489
|
+
const openOption = rawOpts.open;
|
|
75490
|
+
const noOpen = rawOpts.noOpen === true || openOption === false ? true : undefined;
|
|
75275
75491
|
const uiOpts = {
|
|
75276
75492
|
port: rawOpts.port,
|
|
75277
|
-
noOpen
|
|
75493
|
+
noOpen,
|
|
75278
75494
|
dev: rawOpts.dev,
|
|
75279
75495
|
host: rawOpts.host
|
|
75280
75496
|
};
|
|
@@ -76231,7 +76447,7 @@ async function checkCliInstallMethod() {
|
|
|
76231
76447
|
};
|
|
76232
76448
|
}
|
|
76233
76449
|
// src/domains/health-checks/checkers/claude-md-checker.ts
|
|
76234
|
-
import { existsSync as
|
|
76450
|
+
import { existsSync as existsSync42, statSync as statSync5 } from "node:fs";
|
|
76235
76451
|
import { join as join50 } from "node:path";
|
|
76236
76452
|
function checkClaudeMd(setup, projectDir) {
|
|
76237
76453
|
const results = [];
|
|
@@ -76244,7 +76460,7 @@ function checkClaudeMd(setup, projectDir) {
|
|
|
76244
76460
|
return results;
|
|
76245
76461
|
}
|
|
76246
76462
|
function checkClaudeMdFile(path4, name, id) {
|
|
76247
|
-
if (!
|
|
76463
|
+
if (!existsSync42(path4)) {
|
|
76248
76464
|
return {
|
|
76249
76465
|
id,
|
|
76250
76466
|
name,
|
|
@@ -76297,11 +76513,11 @@ function checkClaudeMdFile(path4, name, id) {
|
|
|
76297
76513
|
}
|
|
76298
76514
|
}
|
|
76299
76515
|
// src/domains/health-checks/checkers/active-plan-checker.ts
|
|
76300
|
-
import { existsSync as
|
|
76516
|
+
import { existsSync as existsSync43, readFileSync as readFileSync10 } from "node:fs";
|
|
76301
76517
|
import { join as join51 } from "node:path";
|
|
76302
76518
|
function checkActivePlan(projectDir) {
|
|
76303
76519
|
const activePlanPath = join51(projectDir, ".claude", "active-plan");
|
|
76304
|
-
if (!
|
|
76520
|
+
if (!existsSync43(activePlanPath)) {
|
|
76305
76521
|
return {
|
|
76306
76522
|
id: "ck-active-plan",
|
|
76307
76523
|
name: "Active Plan",
|
|
@@ -76315,7 +76531,7 @@ function checkActivePlan(projectDir) {
|
|
|
76315
76531
|
try {
|
|
76316
76532
|
const targetPath = readFileSync10(activePlanPath, "utf-8").trim();
|
|
76317
76533
|
const fullPath = join51(projectDir, targetPath);
|
|
76318
|
-
if (!
|
|
76534
|
+
if (!existsSync43(fullPath)) {
|
|
76319
76535
|
return {
|
|
76320
76536
|
id: "ck-active-plan",
|
|
76321
76537
|
name: "Active Plan",
|
|
@@ -76351,7 +76567,7 @@ function checkActivePlan(projectDir) {
|
|
|
76351
76567
|
}
|
|
76352
76568
|
}
|
|
76353
76569
|
// src/domains/health-checks/checkers/skills-checker.ts
|
|
76354
|
-
import { existsSync as
|
|
76570
|
+
import { existsSync as existsSync44 } from "node:fs";
|
|
76355
76571
|
import { join as join52 } from "node:path";
|
|
76356
76572
|
function checkSkillsScripts(setup) {
|
|
76357
76573
|
const results = [];
|
|
@@ -76359,7 +76575,7 @@ function checkSkillsScripts(setup) {
|
|
|
76359
76575
|
const scriptName = platform5 === "win32" ? "install.ps1" : "install.sh";
|
|
76360
76576
|
if (setup.global.path) {
|
|
76361
76577
|
const globalScriptPath = join52(setup.global.path, "skills", scriptName);
|
|
76362
|
-
const hasGlobalScript =
|
|
76578
|
+
const hasGlobalScript = existsSync44(globalScriptPath);
|
|
76363
76579
|
results.push({
|
|
76364
76580
|
id: "ck-global-skills-script",
|
|
76365
76581
|
name: "Global Skills Script",
|
|
@@ -76374,7 +76590,7 @@ function checkSkillsScripts(setup) {
|
|
|
76374
76590
|
}
|
|
76375
76591
|
if (setup.project.metadata) {
|
|
76376
76592
|
const projectScriptPath = join52(setup.project.path, "skills", scriptName);
|
|
76377
|
-
const hasProjectScript =
|
|
76593
|
+
const hasProjectScript = existsSync44(projectScriptPath);
|
|
76378
76594
|
results.push({
|
|
76379
76595
|
id: "ck-project-skills-script",
|
|
76380
76596
|
name: "Project Skills Script",
|
|
@@ -76512,7 +76728,7 @@ async function checkGlobalDirWritable() {
|
|
|
76512
76728
|
}
|
|
76513
76729
|
// src/domains/health-checks/checkers/hooks-checker.ts
|
|
76514
76730
|
init_path_resolver();
|
|
76515
|
-
import { existsSync as
|
|
76731
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
76516
76732
|
import { readdir as readdir10 } from "node:fs/promises";
|
|
76517
76733
|
import { join as join54 } from "node:path";
|
|
76518
76734
|
|
|
@@ -76528,8 +76744,8 @@ function normalizePath2(filePath) {
|
|
|
76528
76744
|
async function checkHooksExist(projectDir) {
|
|
76529
76745
|
const globalHooksDir = join54(PathResolver.getGlobalKitDir(), "hooks");
|
|
76530
76746
|
const projectHooksDir = join54(projectDir, ".claude", "hooks");
|
|
76531
|
-
const globalExists =
|
|
76532
|
-
const projectExists =
|
|
76747
|
+
const globalExists = existsSync45(globalHooksDir);
|
|
76748
|
+
const projectExists = existsSync45(projectHooksDir);
|
|
76533
76749
|
let hookCount = 0;
|
|
76534
76750
|
const checkedFiles = new Set;
|
|
76535
76751
|
if (globalExists) {
|
|
@@ -76576,13 +76792,13 @@ async function checkHooksExist(projectDir) {
|
|
|
76576
76792
|
// src/domains/health-checks/checkers/settings-checker.ts
|
|
76577
76793
|
init_logger();
|
|
76578
76794
|
init_path_resolver();
|
|
76579
|
-
import { existsSync as
|
|
76580
|
-
import { readFile as
|
|
76795
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
76796
|
+
import { readFile as readFile30 } from "node:fs/promises";
|
|
76581
76797
|
import { join as join55 } from "node:path";
|
|
76582
76798
|
async function checkSettingsValid(projectDir) {
|
|
76583
76799
|
const globalSettings = join55(PathResolver.getGlobalKitDir(), "settings.json");
|
|
76584
76800
|
const projectSettings = join55(projectDir, ".claude", "settings.json");
|
|
76585
|
-
const settingsPath =
|
|
76801
|
+
const settingsPath = existsSync46(globalSettings) ? globalSettings : existsSync46(projectSettings) ? projectSettings : null;
|
|
76586
76802
|
if (!settingsPath) {
|
|
76587
76803
|
return {
|
|
76588
76804
|
id: "ck-settings-valid",
|
|
@@ -76595,7 +76811,7 @@ async function checkSettingsValid(projectDir) {
|
|
|
76595
76811
|
};
|
|
76596
76812
|
}
|
|
76597
76813
|
try {
|
|
76598
|
-
const content = await
|
|
76814
|
+
const content = await readFile30(settingsPath, "utf-8");
|
|
76599
76815
|
JSON.parse(content);
|
|
76600
76816
|
return {
|
|
76601
76817
|
id: "ck-settings-valid",
|
|
@@ -76651,14 +76867,14 @@ async function checkSettingsValid(projectDir) {
|
|
|
76651
76867
|
// src/domains/health-checks/checkers/path-refs-checker.ts
|
|
76652
76868
|
init_logger();
|
|
76653
76869
|
init_path_resolver();
|
|
76654
|
-
import { existsSync as
|
|
76655
|
-
import { readFile as
|
|
76870
|
+
import { existsSync as existsSync47 } from "node:fs";
|
|
76871
|
+
import { readFile as readFile31 } from "node:fs/promises";
|
|
76656
76872
|
import { homedir as homedir27 } from "node:os";
|
|
76657
|
-
import { dirname as dirname19, join as join56, normalize as normalize5, resolve as
|
|
76873
|
+
import { dirname as dirname19, join as join56, normalize as normalize5, resolve as resolve14 } from "node:path";
|
|
76658
76874
|
async function checkPathRefsValid(projectDir) {
|
|
76659
76875
|
const globalClaudeMd = join56(PathResolver.getGlobalKitDir(), "CLAUDE.md");
|
|
76660
76876
|
const projectClaudeMd = join56(projectDir, ".claude", "CLAUDE.md");
|
|
76661
|
-
const claudeMdPath =
|
|
76877
|
+
const claudeMdPath = existsSync47(globalClaudeMd) ? globalClaudeMd : existsSync47(projectClaudeMd) ? projectClaudeMd : null;
|
|
76662
76878
|
if (!claudeMdPath) {
|
|
76663
76879
|
return {
|
|
76664
76880
|
id: "ck-path-refs-valid",
|
|
@@ -76671,7 +76887,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76671
76887
|
};
|
|
76672
76888
|
}
|
|
76673
76889
|
try {
|
|
76674
|
-
const content = await
|
|
76890
|
+
const content = await readFile31(claudeMdPath, "utf-8");
|
|
76675
76891
|
const refPattern = /@([^\s\)]+)/g;
|
|
76676
76892
|
const refs = [...content.matchAll(refPattern)].map((m2) => m2[1]);
|
|
76677
76893
|
if (refs.length === 0) {
|
|
@@ -76701,7 +76917,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76701
76917
|
} else if (/^[A-Za-z]:/.test(ref)) {
|
|
76702
76918
|
refPath = normalize5(ref);
|
|
76703
76919
|
} else {
|
|
76704
|
-
refPath =
|
|
76920
|
+
refPath = resolve14(baseDir, ref);
|
|
76705
76921
|
}
|
|
76706
76922
|
const normalizedPath = normalize5(refPath);
|
|
76707
76923
|
const isWithinHome = normalizedPath.startsWith(home8);
|
|
@@ -76711,7 +76927,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76711
76927
|
logger.verbose("Skipping potentially unsafe path reference", { ref, refPath });
|
|
76712
76928
|
continue;
|
|
76713
76929
|
}
|
|
76714
|
-
if (!
|
|
76930
|
+
if (!existsSync47(normalizedPath)) {
|
|
76715
76931
|
broken.push(ref);
|
|
76716
76932
|
}
|
|
76717
76933
|
}
|
|
@@ -76750,7 +76966,7 @@ async function checkPathRefsValid(projectDir) {
|
|
|
76750
76966
|
}
|
|
76751
76967
|
}
|
|
76752
76968
|
// src/domains/health-checks/checkers/config-completeness-checker.ts
|
|
76753
|
-
import { existsSync as
|
|
76969
|
+
import { existsSync as existsSync48 } from "node:fs";
|
|
76754
76970
|
import { readdir as readdir11 } from "node:fs/promises";
|
|
76755
76971
|
import { join as join57 } from "node:path";
|
|
76756
76972
|
async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
@@ -76770,11 +76986,11 @@ async function checkProjectConfigCompleteness(setup, projectDir) {
|
|
|
76770
76986
|
const missingDirs = [];
|
|
76771
76987
|
for (const dir of requiredDirs) {
|
|
76772
76988
|
const dirPath = join57(projectClaudeDir, dir);
|
|
76773
|
-
if (!
|
|
76989
|
+
if (!existsSync48(dirPath)) {
|
|
76774
76990
|
missingDirs.push(dir);
|
|
76775
76991
|
}
|
|
76776
76992
|
}
|
|
76777
|
-
const hasRulesOrWorkflows =
|
|
76993
|
+
const hasRulesOrWorkflows = existsSync48(join57(projectClaudeDir, "rules")) || existsSync48(join57(projectClaudeDir, "workflows"));
|
|
76778
76994
|
if (!hasRulesOrWorkflows) {
|
|
76779
76995
|
missingDirs.push("rules");
|
|
76780
76996
|
}
|
|
@@ -77123,24 +77339,24 @@ init_claudekit_constants();
|
|
|
77123
77339
|
init_logger();
|
|
77124
77340
|
init_path_resolver();
|
|
77125
77341
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
77126
|
-
import { existsSync as
|
|
77342
|
+
import { existsSync as existsSync49, readFileSync as readFileSync11, statSync as statSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
77127
77343
|
import { readdir as readdir12 } from "node:fs/promises";
|
|
77128
77344
|
import { tmpdir } from "node:os";
|
|
77129
|
-
import { join as join60, resolve as
|
|
77345
|
+
import { join as join60, resolve as resolve15 } from "node:path";
|
|
77130
77346
|
var HOOK_CHECK_TIMEOUT_MS = 5000;
|
|
77131
77347
|
var PYTHON_CHECK_TIMEOUT_MS = 3000;
|
|
77132
77348
|
var MAX_LOG_FILE_SIZE_BYTES = 10 * 1024 * 1024;
|
|
77133
77349
|
function getHooksDir(projectDir) {
|
|
77134
|
-
const projectHooksDir =
|
|
77135
|
-
const globalHooksDir =
|
|
77136
|
-
if (
|
|
77350
|
+
const projectHooksDir = resolve15(projectDir, ".claude", "hooks");
|
|
77351
|
+
const globalHooksDir = resolve15(PathResolver.getGlobalKitDir(), "hooks");
|
|
77352
|
+
if (existsSync49(projectHooksDir))
|
|
77137
77353
|
return projectHooksDir;
|
|
77138
|
-
if (
|
|
77354
|
+
if (existsSync49(globalHooksDir))
|
|
77139
77355
|
return globalHooksDir;
|
|
77140
77356
|
return null;
|
|
77141
77357
|
}
|
|
77142
77358
|
function isPathWithin(filePath, parentDir) {
|
|
77143
|
-
return
|
|
77359
|
+
return resolve15(filePath).startsWith(resolve15(parentDir));
|
|
77144
77360
|
}
|
|
77145
77361
|
async function checkHookSyntax(projectDir) {
|
|
77146
77362
|
const hooksDir = getHooksDir(projectDir);
|
|
@@ -77270,7 +77486,7 @@ async function checkHookDeps(projectDir) {
|
|
|
77270
77486
|
const resolvedPath = join60(hooksDir, depPath);
|
|
77271
77487
|
const extensions = [".js", ".cjs", ".mjs", ".json"];
|
|
77272
77488
|
const indexFiles = ["index.js", "index.cjs", "index.mjs"];
|
|
77273
|
-
const exists =
|
|
77489
|
+
const exists = existsSync49(resolvedPath) || extensions.some((ext) => existsSync49(resolvedPath + ext)) || indexFiles.some((idx) => existsSync49(join60(resolvedPath, idx)));
|
|
77274
77490
|
if (!exists) {
|
|
77275
77491
|
missingDeps.push(`${file}: ${depPath}`);
|
|
77276
77492
|
}
|
|
@@ -77455,7 +77671,7 @@ async function checkHookRuntime(projectDir) {
|
|
|
77455
77671
|
async function checkHookConfig(projectDir) {
|
|
77456
77672
|
const projectConfigPath = join60(projectDir, ".claude", ".ck.json");
|
|
77457
77673
|
const globalConfigPath = join60(PathResolver.getGlobalKitDir(), ".ck.json");
|
|
77458
|
-
const configPath =
|
|
77674
|
+
const configPath = existsSync49(projectConfigPath) ? projectConfigPath : existsSync49(globalConfigPath) ? globalConfigPath : null;
|
|
77459
77675
|
if (!configPath) {
|
|
77460
77676
|
return {
|
|
77461
77677
|
id: "hook-config",
|
|
@@ -77579,7 +77795,7 @@ async function checkHookLogs(projectDir) {
|
|
|
77579
77795
|
};
|
|
77580
77796
|
}
|
|
77581
77797
|
const logPath = join60(hooksDir, ".logs", "hook-log.jsonl");
|
|
77582
|
-
if (!
|
|
77798
|
+
if (!existsSync49(logPath)) {
|
|
77583
77799
|
return {
|
|
77584
77800
|
id: "hook-logs",
|
|
77585
77801
|
name: "Hook Crash Logs",
|
|
@@ -77836,7 +78052,7 @@ async function checkPythonVenv(projectDir) {
|
|
|
77836
78052
|
const venvBin = isWindows3 ? join60("Scripts", "python.exe") : join60("bin", "python3");
|
|
77837
78053
|
const projectVenvPath = join60(projectDir, ".claude", "skills", ".venv", venvBin);
|
|
77838
78054
|
const globalVenvPath = join60(PathResolver.getGlobalKitDir(), "skills", ".venv", venvBin);
|
|
77839
|
-
const venvPath =
|
|
78055
|
+
const venvPath = existsSync49(projectVenvPath) ? projectVenvPath : existsSync49(globalVenvPath) ? globalVenvPath : null;
|
|
77840
78056
|
if (!venvPath) {
|
|
77841
78057
|
return {
|
|
77842
78058
|
id: "python-venv",
|
|
@@ -78314,7 +78530,7 @@ import { platform as platform6 } from "node:os";
|
|
|
78314
78530
|
// src/domains/health-checks/platform/environment-checker.ts
|
|
78315
78531
|
init_environment();
|
|
78316
78532
|
init_path_resolver();
|
|
78317
|
-
import { constants as constants3, access as access3, mkdir as mkdir14, readFile as
|
|
78533
|
+
import { constants as constants3, access as access3, mkdir as mkdir14, readFile as readFile33, unlink as unlink8, writeFile as writeFile17 } from "node:fs/promises";
|
|
78318
78534
|
import { arch as arch2, homedir as homedir28, platform as platform5 } from "node:os";
|
|
78319
78535
|
import { join as join62, normalize as normalize6 } from "node:path";
|
|
78320
78536
|
function shouldSkipExpensiveOperations4() {
|
|
@@ -78411,7 +78627,7 @@ async function checkGlobalDirAccess() {
|
|
|
78411
78627
|
try {
|
|
78412
78628
|
await mkdir14(globalDir, { recursive: true });
|
|
78413
78629
|
await writeFile17(testFile, "test", "utf-8");
|
|
78414
|
-
const content = await
|
|
78630
|
+
const content = await readFile33(testFile, "utf-8");
|
|
78415
78631
|
await unlink8(testFile);
|
|
78416
78632
|
if (content !== "test")
|
|
78417
78633
|
throw new Error("Read mismatch");
|
|
@@ -79304,7 +79520,7 @@ init_claudekit_constants();
|
|
|
79304
79520
|
init_logger();
|
|
79305
79521
|
init_path_resolver();
|
|
79306
79522
|
var import_compare_versions6 = __toESM(require_umd(), 1);
|
|
79307
|
-
import { mkdir as mkdir16, readFile as
|
|
79523
|
+
import { mkdir as mkdir16, readFile as readFile34, unlink as unlink10, writeFile as writeFile19 } from "node:fs/promises";
|
|
79308
79524
|
import { join as join65 } from "node:path";
|
|
79309
79525
|
var CACHE_TTL_HOURS = 24;
|
|
79310
79526
|
var DEFAULT_CACHE_TTL_MS = CACHE_TTL_HOURS * 60 * 60 * 1000;
|
|
@@ -79347,7 +79563,7 @@ class ConfigVersionChecker {
|
|
|
79347
79563
|
static async loadCache(kitType, global3) {
|
|
79348
79564
|
try {
|
|
79349
79565
|
const cachePath = ConfigVersionChecker.getCacheFilePath(kitType, global3);
|
|
79350
|
-
const data = await
|
|
79566
|
+
const data = await readFile34(cachePath, "utf8");
|
|
79351
79567
|
const parsed = JSON.parse(data);
|
|
79352
79568
|
if (typeof parsed !== "object" || parsed === null || typeof parsed.lastCheck !== "number" || typeof parsed.latestVersion !== "string" || !parsed.latestVersion || parsed.lastCheck < 0 || parsed.lastCheck > Date.now() + 7 * 24 * 60 * 60 * 1000) {
|
|
79353
79569
|
logger.debug("Invalid cache structure, ignoring");
|
|
@@ -79429,7 +79645,7 @@ class ConfigVersionChecker {
|
|
|
79429
79645
|
return null;
|
|
79430
79646
|
}
|
|
79431
79647
|
const delay = baseBackoff * 2 ** attempt;
|
|
79432
|
-
await new Promise((
|
|
79648
|
+
await new Promise((resolve16) => setTimeout(resolve16, delay));
|
|
79433
79649
|
}
|
|
79434
79650
|
}
|
|
79435
79651
|
return null;
|
|
@@ -79504,7 +79720,7 @@ class ConfigVersionChecker {
|
|
|
79504
79720
|
}
|
|
79505
79721
|
}
|
|
79506
79722
|
// src/domains/sync/sync-engine.ts
|
|
79507
|
-
import { lstat as lstat3, readFile as
|
|
79723
|
+
import { lstat as lstat3, readFile as readFile35, readlink, realpath as realpath3, stat as stat9 } from "node:fs/promises";
|
|
79508
79724
|
import { isAbsolute as isAbsolute3, join as join66, normalize as normalize7, relative as relative8 } from "node:path";
|
|
79509
79725
|
|
|
79510
79726
|
// src/services/file-operations/ownership-checker.ts
|
|
@@ -79596,24 +79812,24 @@ function pLimit(concurrency) {
|
|
|
79596
79812
|
activeCount--;
|
|
79597
79813
|
resumeNext();
|
|
79598
79814
|
};
|
|
79599
|
-
const run = async (function_,
|
|
79815
|
+
const run = async (function_, resolve16, arguments_) => {
|
|
79600
79816
|
const result = (async () => function_(...arguments_))();
|
|
79601
|
-
|
|
79817
|
+
resolve16(result);
|
|
79602
79818
|
try {
|
|
79603
79819
|
await result;
|
|
79604
79820
|
} catch {}
|
|
79605
79821
|
next();
|
|
79606
79822
|
};
|
|
79607
|
-
const enqueue = (function_,
|
|
79823
|
+
const enqueue = (function_, resolve16, arguments_) => {
|
|
79608
79824
|
new Promise((internalResolve) => {
|
|
79609
79825
|
queue.enqueue(internalResolve);
|
|
79610
|
-
}).then(run.bind(undefined, function_,
|
|
79826
|
+
}).then(run.bind(undefined, function_, resolve16, arguments_));
|
|
79611
79827
|
if (activeCount < concurrency) {
|
|
79612
79828
|
resumeNext();
|
|
79613
79829
|
}
|
|
79614
79830
|
};
|
|
79615
|
-
const generator = (function_, ...arguments_) => new Promise((
|
|
79616
|
-
enqueue(function_,
|
|
79831
|
+
const generator = (function_, ...arguments_) => new Promise((resolve16) => {
|
|
79832
|
+
enqueue(function_, resolve16, arguments_);
|
|
79617
79833
|
});
|
|
79618
79834
|
Object.defineProperties(generator, {
|
|
79619
79835
|
activeCount: {
|
|
@@ -79664,12 +79880,12 @@ async function mapWithLimit(items, fn, concurrency = DEFAULT_CONCURRENCY) {
|
|
|
79664
79880
|
// src/services/file-operations/ownership-checker.ts
|
|
79665
79881
|
class OwnershipChecker {
|
|
79666
79882
|
static async calculateChecksum(filePath) {
|
|
79667
|
-
return new Promise((
|
|
79883
|
+
return new Promise((resolve16, reject) => {
|
|
79668
79884
|
const hash = createHash3("sha256");
|
|
79669
79885
|
const stream = createReadStream2(filePath);
|
|
79670
79886
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
79671
79887
|
stream.on("end", () => {
|
|
79672
|
-
|
|
79888
|
+
resolve16(hash.digest("hex"));
|
|
79673
79889
|
});
|
|
79674
79890
|
stream.on("error", (err) => {
|
|
79675
79891
|
stream.destroy();
|
|
@@ -81088,7 +81304,7 @@ class SyncEngine {
|
|
|
81088
81304
|
if (lstats.size > MAX_SYNC_FILE_SIZE) {
|
|
81089
81305
|
throw new Error(`File too large for sync (${Math.round(lstats.size / 1024 / 1024)}MB > ${MAX_SYNC_FILE_SIZE / 1024 / 1024}MB limit)`);
|
|
81090
81306
|
}
|
|
81091
|
-
const buffer = await
|
|
81307
|
+
const buffer = await readFile35(filePath);
|
|
81092
81308
|
if (buffer.includes(0)) {
|
|
81093
81309
|
return { content: "", isBinary: true };
|
|
81094
81310
|
}
|
|
@@ -82472,10 +82688,10 @@ init_types3();
|
|
|
82472
82688
|
// src/domains/installation/utils/path-security.ts
|
|
82473
82689
|
init_types3();
|
|
82474
82690
|
import { lstatSync as lstatSync2, realpathSync as realpathSync3 } from "node:fs";
|
|
82475
|
-
import { relative as relative9, resolve as
|
|
82691
|
+
import { relative as relative9, resolve as resolve18 } from "node:path";
|
|
82476
82692
|
var MAX_EXTRACTION_SIZE = 500 * 1024 * 1024;
|
|
82477
82693
|
function isPathSafe(basePath, targetPath) {
|
|
82478
|
-
const resolvedBase =
|
|
82694
|
+
const resolvedBase = resolve18(basePath);
|
|
82479
82695
|
try {
|
|
82480
82696
|
const stat10 = lstatSync2(targetPath);
|
|
82481
82697
|
if (stat10.isSymbolicLink()) {
|
|
@@ -82485,7 +82701,7 @@ function isPathSafe(basePath, targetPath) {
|
|
|
82485
82701
|
}
|
|
82486
82702
|
}
|
|
82487
82703
|
} catch {}
|
|
82488
|
-
const resolvedTarget =
|
|
82704
|
+
const resolvedTarget = resolve18(targetPath);
|
|
82489
82705
|
const relativePath = relative9(resolvedBase, resolvedTarget);
|
|
82490
82706
|
return !relativePath.startsWith("..") && !relativePath.startsWith("/") && resolvedTarget.startsWith(resolvedBase);
|
|
82491
82707
|
}
|
|
@@ -82573,7 +82789,7 @@ class FileDownloader {
|
|
|
82573
82789
|
}
|
|
82574
82790
|
if (downloadedSize !== totalSize) {
|
|
82575
82791
|
fileStream.end();
|
|
82576
|
-
await new Promise((
|
|
82792
|
+
await new Promise((resolve19) => fileStream.once("close", resolve19));
|
|
82577
82793
|
try {
|
|
82578
82794
|
rmSync2(destPath, { force: true });
|
|
82579
82795
|
} catch (cleanupError) {
|
|
@@ -82587,7 +82803,7 @@ class FileDownloader {
|
|
|
82587
82803
|
return destPath;
|
|
82588
82804
|
} catch (error) {
|
|
82589
82805
|
fileStream.end();
|
|
82590
|
-
await new Promise((
|
|
82806
|
+
await new Promise((resolve19) => fileStream.once("close", resolve19));
|
|
82591
82807
|
try {
|
|
82592
82808
|
rmSync2(destPath, { force: true });
|
|
82593
82809
|
} catch (cleanupError) {
|
|
@@ -82653,7 +82869,7 @@ class FileDownloader {
|
|
|
82653
82869
|
const expectedSize = Number(response.headers.get("content-length"));
|
|
82654
82870
|
if (expectedSize > 0 && downloadedSize !== expectedSize) {
|
|
82655
82871
|
fileStream.end();
|
|
82656
|
-
await new Promise((
|
|
82872
|
+
await new Promise((resolve19) => fileStream.once("close", resolve19));
|
|
82657
82873
|
try {
|
|
82658
82874
|
rmSync2(destPath, { force: true });
|
|
82659
82875
|
} catch (cleanupError) {
|
|
@@ -82671,7 +82887,7 @@ class FileDownloader {
|
|
|
82671
82887
|
return destPath;
|
|
82672
82888
|
} catch (error) {
|
|
82673
82889
|
fileStream.end();
|
|
82674
|
-
await new Promise((
|
|
82890
|
+
await new Promise((resolve19) => fileStream.once("close", resolve19));
|
|
82675
82891
|
try {
|
|
82676
82892
|
rmSync2(destPath, { force: true });
|
|
82677
82893
|
} catch (cleanupError) {
|
|
@@ -83270,10 +83486,10 @@ class Minipass extends EventEmitter3 {
|
|
|
83270
83486
|
return this[ENCODING] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
83271
83487
|
}
|
|
83272
83488
|
async promise() {
|
|
83273
|
-
return new Promise((
|
|
83489
|
+
return new Promise((resolve19, reject) => {
|
|
83274
83490
|
this.on(DESTROYED, () => reject(new Error("stream destroyed")));
|
|
83275
83491
|
this.on("error", (er) => reject(er));
|
|
83276
|
-
this.on("end", () =>
|
|
83492
|
+
this.on("end", () => resolve19());
|
|
83277
83493
|
});
|
|
83278
83494
|
}
|
|
83279
83495
|
[Symbol.asyncIterator]() {
|
|
@@ -83292,7 +83508,7 @@ class Minipass extends EventEmitter3 {
|
|
|
83292
83508
|
return Promise.resolve({ done: false, value: res });
|
|
83293
83509
|
if (this[EOF])
|
|
83294
83510
|
return stop();
|
|
83295
|
-
let
|
|
83511
|
+
let resolve19;
|
|
83296
83512
|
let reject;
|
|
83297
83513
|
const onerr = (er) => {
|
|
83298
83514
|
this.off("data", ondata);
|
|
@@ -83306,19 +83522,19 @@ class Minipass extends EventEmitter3 {
|
|
|
83306
83522
|
this.off("end", onend);
|
|
83307
83523
|
this.off(DESTROYED, ondestroy);
|
|
83308
83524
|
this.pause();
|
|
83309
|
-
|
|
83525
|
+
resolve19({ value, done: !!this[EOF] });
|
|
83310
83526
|
};
|
|
83311
83527
|
const onend = () => {
|
|
83312
83528
|
this.off("error", onerr);
|
|
83313
83529
|
this.off("data", ondata);
|
|
83314
83530
|
this.off(DESTROYED, ondestroy);
|
|
83315
83531
|
stop();
|
|
83316
|
-
|
|
83532
|
+
resolve19({ done: true, value: undefined });
|
|
83317
83533
|
};
|
|
83318
83534
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
83319
83535
|
return new Promise((res2, rej) => {
|
|
83320
83536
|
reject = rej;
|
|
83321
|
-
|
|
83537
|
+
resolve19 = res2;
|
|
83322
83538
|
this.once(DESTROYED, ondestroy);
|
|
83323
83539
|
this.once("error", onerr);
|
|
83324
83540
|
this.once("end", onend);
|
|
@@ -84424,10 +84640,10 @@ class Minipass2 extends EventEmitter4 {
|
|
|
84424
84640
|
return this[ENCODING2] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
84425
84641
|
}
|
|
84426
84642
|
async promise() {
|
|
84427
|
-
return new Promise((
|
|
84643
|
+
return new Promise((resolve19, reject) => {
|
|
84428
84644
|
this.on(DESTROYED2, () => reject(new Error("stream destroyed")));
|
|
84429
84645
|
this.on("error", (er) => reject(er));
|
|
84430
|
-
this.on("end", () =>
|
|
84646
|
+
this.on("end", () => resolve19());
|
|
84431
84647
|
});
|
|
84432
84648
|
}
|
|
84433
84649
|
[Symbol.asyncIterator]() {
|
|
@@ -84446,7 +84662,7 @@ class Minipass2 extends EventEmitter4 {
|
|
|
84446
84662
|
return Promise.resolve({ done: false, value: res });
|
|
84447
84663
|
if (this[EOF2])
|
|
84448
84664
|
return stop();
|
|
84449
|
-
let
|
|
84665
|
+
let resolve19;
|
|
84450
84666
|
let reject;
|
|
84451
84667
|
const onerr = (er) => {
|
|
84452
84668
|
this.off("data", ondata);
|
|
@@ -84460,19 +84676,19 @@ class Minipass2 extends EventEmitter4 {
|
|
|
84460
84676
|
this.off("end", onend);
|
|
84461
84677
|
this.off(DESTROYED2, ondestroy);
|
|
84462
84678
|
this.pause();
|
|
84463
|
-
|
|
84679
|
+
resolve19({ value, done: !!this[EOF2] });
|
|
84464
84680
|
};
|
|
84465
84681
|
const onend = () => {
|
|
84466
84682
|
this.off("error", onerr);
|
|
84467
84683
|
this.off("data", ondata);
|
|
84468
84684
|
this.off(DESTROYED2, ondestroy);
|
|
84469
84685
|
stop();
|
|
84470
|
-
|
|
84686
|
+
resolve19({ done: true, value: undefined });
|
|
84471
84687
|
};
|
|
84472
84688
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
84473
84689
|
return new Promise((res2, rej) => {
|
|
84474
84690
|
reject = rej;
|
|
84475
|
-
|
|
84691
|
+
resolve19 = res2;
|
|
84476
84692
|
this.once(DESTROYED2, ondestroy);
|
|
84477
84693
|
this.once("error", onerr);
|
|
84478
84694
|
this.once("end", onend);
|
|
@@ -85900,10 +86116,10 @@ class Minipass3 extends EventEmitter5 {
|
|
|
85900
86116
|
return this[ENCODING3] ? buf.join("") : Buffer.concat(buf, buf.dataLength);
|
|
85901
86117
|
}
|
|
85902
86118
|
async promise() {
|
|
85903
|
-
return new Promise((
|
|
86119
|
+
return new Promise((resolve19, reject) => {
|
|
85904
86120
|
this.on(DESTROYED3, () => reject(new Error("stream destroyed")));
|
|
85905
86121
|
this.on("error", (er) => reject(er));
|
|
85906
|
-
this.on("end", () =>
|
|
86122
|
+
this.on("end", () => resolve19());
|
|
85907
86123
|
});
|
|
85908
86124
|
}
|
|
85909
86125
|
[Symbol.asyncIterator]() {
|
|
@@ -85922,7 +86138,7 @@ class Minipass3 extends EventEmitter5 {
|
|
|
85922
86138
|
return Promise.resolve({ done: false, value: res });
|
|
85923
86139
|
if (this[EOF3])
|
|
85924
86140
|
return stop();
|
|
85925
|
-
let
|
|
86141
|
+
let resolve19;
|
|
85926
86142
|
let reject;
|
|
85927
86143
|
const onerr = (er) => {
|
|
85928
86144
|
this.off("data", ondata);
|
|
@@ -85936,19 +86152,19 @@ class Minipass3 extends EventEmitter5 {
|
|
|
85936
86152
|
this.off("end", onend);
|
|
85937
86153
|
this.off(DESTROYED3, ondestroy);
|
|
85938
86154
|
this.pause();
|
|
85939
|
-
|
|
86155
|
+
resolve19({ value, done: !!this[EOF3] });
|
|
85940
86156
|
};
|
|
85941
86157
|
const onend = () => {
|
|
85942
86158
|
this.off("error", onerr);
|
|
85943
86159
|
this.off("data", ondata);
|
|
85944
86160
|
this.off(DESTROYED3, ondestroy);
|
|
85945
86161
|
stop();
|
|
85946
|
-
|
|
86162
|
+
resolve19({ done: true, value: undefined });
|
|
85947
86163
|
};
|
|
85948
86164
|
const ondestroy = () => onerr(new Error("stream destroyed"));
|
|
85949
86165
|
return new Promise((res2, rej) => {
|
|
85950
86166
|
reject = rej;
|
|
85951
|
-
|
|
86167
|
+
resolve19 = res2;
|
|
85952
86168
|
this.once(DESTROYED3, ondestroy);
|
|
85953
86169
|
this.once("error", onerr);
|
|
85954
86170
|
this.once("end", onend);
|
|
@@ -86719,9 +86935,9 @@ var listFile = (opt, _files) => {
|
|
|
86719
86935
|
const parse4 = new Parser(opt);
|
|
86720
86936
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
86721
86937
|
const file = opt.file;
|
|
86722
|
-
const p = new Promise((
|
|
86938
|
+
const p = new Promise((resolve19, reject) => {
|
|
86723
86939
|
parse4.on("error", reject);
|
|
86724
|
-
parse4.on("end",
|
|
86940
|
+
parse4.on("end", resolve19);
|
|
86725
86941
|
fs9.stat(file, (er, stat10) => {
|
|
86726
86942
|
if (er) {
|
|
86727
86943
|
reject(er);
|
|
@@ -89301,9 +89517,9 @@ var extractFile = (opt, _3) => {
|
|
|
89301
89517
|
const u = new Unpack(opt);
|
|
89302
89518
|
const readSize = opt.maxReadSize || 16 * 1024 * 1024;
|
|
89303
89519
|
const file = opt.file;
|
|
89304
|
-
const p = new Promise((
|
|
89520
|
+
const p = new Promise((resolve19, reject) => {
|
|
89305
89521
|
u.on("error", reject);
|
|
89306
|
-
u.on("close",
|
|
89522
|
+
u.on("close", resolve19);
|
|
89307
89523
|
fs16.stat(file, (er, stat10) => {
|
|
89308
89524
|
if (er) {
|
|
89309
89525
|
reject(er);
|
|
@@ -89436,7 +89652,7 @@ var replaceAsync = (opt, files) => {
|
|
|
89436
89652
|
};
|
|
89437
89653
|
fs17.read(fd, headBuf, 0, 512, position, onread);
|
|
89438
89654
|
};
|
|
89439
|
-
const promise = new Promise((
|
|
89655
|
+
const promise = new Promise((resolve19, reject) => {
|
|
89440
89656
|
p.on("error", reject);
|
|
89441
89657
|
let flag = "r+";
|
|
89442
89658
|
const onopen = (er, fd) => {
|
|
@@ -89461,7 +89677,7 @@ var replaceAsync = (opt, files) => {
|
|
|
89461
89677
|
});
|
|
89462
89678
|
p.pipe(stream);
|
|
89463
89679
|
stream.on("error", reject);
|
|
89464
|
-
stream.on("close",
|
|
89680
|
+
stream.on("close", resolve19);
|
|
89465
89681
|
addFilesAsync2(p, files);
|
|
89466
89682
|
});
|
|
89467
89683
|
});
|
|
@@ -89735,20 +89951,20 @@ class ZipExtractor {
|
|
|
89735
89951
|
if (!isMacOS()) {
|
|
89736
89952
|
return false;
|
|
89737
89953
|
}
|
|
89738
|
-
return new Promise((
|
|
89954
|
+
return new Promise((resolve19) => {
|
|
89739
89955
|
mkdir24(destDir, { recursive: true }).then(() => {
|
|
89740
89956
|
execFile8("unzip", ["-o", "-q", archivePath, "-d", destDir], (error, _stdout, stderr) => {
|
|
89741
89957
|
if (error) {
|
|
89742
89958
|
logger.debug(`Native unzip failed: ${stderr || error.message}`);
|
|
89743
|
-
|
|
89959
|
+
resolve19(false);
|
|
89744
89960
|
return;
|
|
89745
89961
|
}
|
|
89746
89962
|
logger.debug("Native unzip succeeded");
|
|
89747
|
-
|
|
89963
|
+
resolve19(true);
|
|
89748
89964
|
});
|
|
89749
89965
|
}).catch((err) => {
|
|
89750
89966
|
logger.debug(`Failed to create directory for native unzip: ${err.message}`);
|
|
89751
|
-
|
|
89967
|
+
resolve19(false);
|
|
89752
89968
|
});
|
|
89753
89969
|
});
|
|
89754
89970
|
}
|
|
@@ -90261,8 +90477,8 @@ async function handleDownload(ctx) {
|
|
|
90261
90477
|
import { join as join97 } from "node:path";
|
|
90262
90478
|
|
|
90263
90479
|
// src/domains/installation/deletion-handler.ts
|
|
90264
|
-
import { existsSync as
|
|
90265
|
-
import { dirname as dirname24, join as join84, relative as relative11, resolve as
|
|
90480
|
+
import { existsSync as existsSync55, lstatSync as lstatSync3, readdirSync as readdirSync4, rmSync as rmSync3, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
|
|
90481
|
+
import { dirname as dirname24, join as join84, relative as relative11, resolve as resolve20, sep as sep5 } from "node:path";
|
|
90266
90482
|
|
|
90267
90483
|
// src/services/file-operations/manifest/manifest-reader.ts
|
|
90268
90484
|
init_metadata_migration();
|
|
@@ -90444,7 +90660,7 @@ function shouldDeletePath(path13, metadata) {
|
|
|
90444
90660
|
}
|
|
90445
90661
|
function collectFilesRecursively(dir, baseDir) {
|
|
90446
90662
|
const results = [];
|
|
90447
|
-
if (!
|
|
90663
|
+
if (!existsSync55(dir))
|
|
90448
90664
|
return results;
|
|
90449
90665
|
try {
|
|
90450
90666
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
@@ -90479,8 +90695,8 @@ function expandGlobPatterns(patterns, claudeDir2) {
|
|
|
90479
90695
|
}
|
|
90480
90696
|
var MAX_CLEANUP_ITERATIONS = 50;
|
|
90481
90697
|
function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
90482
|
-
const normalizedClaudeDir =
|
|
90483
|
-
let currentDir =
|
|
90698
|
+
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
90699
|
+
let currentDir = resolve20(dirname24(filePath));
|
|
90484
90700
|
let iterations = 0;
|
|
90485
90701
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir) && iterations < MAX_CLEANUP_ITERATIONS) {
|
|
90486
90702
|
iterations++;
|
|
@@ -90489,7 +90705,7 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
90489
90705
|
if (entries.length === 0) {
|
|
90490
90706
|
rmdirSync(currentDir);
|
|
90491
90707
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
90492
|
-
currentDir =
|
|
90708
|
+
currentDir = resolve20(dirname24(currentDir));
|
|
90493
90709
|
} else {
|
|
90494
90710
|
break;
|
|
90495
90711
|
}
|
|
@@ -90499,8 +90715,8 @@ function cleanupEmptyDirectories(filePath, claudeDir2) {
|
|
|
90499
90715
|
}
|
|
90500
90716
|
}
|
|
90501
90717
|
function deletePath(fullPath, claudeDir2) {
|
|
90502
|
-
const normalizedPath =
|
|
90503
|
-
const normalizedClaudeDir =
|
|
90718
|
+
const normalizedPath = resolve20(fullPath);
|
|
90719
|
+
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
90504
90720
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`) && normalizedPath !== normalizedClaudeDir) {
|
|
90505
90721
|
throw new Error(`Path traversal detected: ${fullPath}`);
|
|
90506
90722
|
}
|
|
@@ -90573,8 +90789,8 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
90573
90789
|
const result = { deletedPaths: [], preservedPaths: [], errors: [] };
|
|
90574
90790
|
for (const path13 of deletions) {
|
|
90575
90791
|
const fullPath = join84(claudeDir2, path13);
|
|
90576
|
-
const normalizedPath =
|
|
90577
|
-
const normalizedClaudeDir =
|
|
90792
|
+
const normalizedPath = resolve20(fullPath);
|
|
90793
|
+
const normalizedClaudeDir = resolve20(claudeDir2);
|
|
90578
90794
|
if (!normalizedPath.startsWith(`${normalizedClaudeDir}${sep5}`)) {
|
|
90579
90795
|
logger.warning(`Skipping invalid path: ${path13}`);
|
|
90580
90796
|
result.errors.push(path13);
|
|
@@ -90585,7 +90801,7 @@ async function handleDeletions(sourceMetadata, claudeDir2) {
|
|
|
90585
90801
|
logger.verbose(`Preserved user file: ${path13}`);
|
|
90586
90802
|
continue;
|
|
90587
90803
|
}
|
|
90588
|
-
if (
|
|
90804
|
+
if (existsSync55(fullPath)) {
|
|
90589
90805
|
try {
|
|
90590
90806
|
deletePath(fullPath, claudeDir2);
|
|
90591
90807
|
result.deletedPaths.push(path13);
|
|
@@ -92285,8 +92501,8 @@ import { execSync as execSync4 } from "node:child_process";
|
|
|
92285
92501
|
|
|
92286
92502
|
// src/domains/config/installed-settings-tracker.ts
|
|
92287
92503
|
init_shared();
|
|
92288
|
-
import { existsSync as
|
|
92289
|
-
import { mkdir as mkdir26, readFile as
|
|
92504
|
+
import { existsSync as existsSync56 } from "node:fs";
|
|
92505
|
+
import { mkdir as mkdir26, readFile as readFile39, writeFile as writeFile22 } from "node:fs/promises";
|
|
92290
92506
|
import { dirname as dirname25, join as join86 } from "node:path";
|
|
92291
92507
|
var CK_JSON_FILE = ".ck.json";
|
|
92292
92508
|
|
|
@@ -92307,11 +92523,11 @@ class InstalledSettingsTracker {
|
|
|
92307
92523
|
}
|
|
92308
92524
|
async loadInstalledSettings() {
|
|
92309
92525
|
const ckJsonPath = this.getCkJsonPath();
|
|
92310
|
-
if (!
|
|
92526
|
+
if (!existsSync56(ckJsonPath)) {
|
|
92311
92527
|
return { hooks: [], mcpServers: [] };
|
|
92312
92528
|
}
|
|
92313
92529
|
try {
|
|
92314
|
-
const content = await
|
|
92530
|
+
const content = await readFile39(ckJsonPath, "utf-8");
|
|
92315
92531
|
const data = JSON.parse(content);
|
|
92316
92532
|
const installed = data.kits?.[this.kitName]?.installedSettings;
|
|
92317
92533
|
if (installed) {
|
|
@@ -92327,8 +92543,8 @@ class InstalledSettingsTracker {
|
|
|
92327
92543
|
const ckJsonPath = this.getCkJsonPath();
|
|
92328
92544
|
try {
|
|
92329
92545
|
let data = {};
|
|
92330
|
-
if (
|
|
92331
|
-
const content = await
|
|
92546
|
+
if (existsSync56(ckJsonPath)) {
|
|
92547
|
+
const content = await readFile39(ckJsonPath, "utf-8");
|
|
92332
92548
|
data = JSON.parse(content);
|
|
92333
92549
|
}
|
|
92334
92550
|
if (!data.kits) {
|
|
@@ -93688,7 +93904,7 @@ function buildConflictSummary(fileConflicts, hookConflicts, mcpConflicts) {
|
|
|
93688
93904
|
init_logger();
|
|
93689
93905
|
init_skip_directories();
|
|
93690
93906
|
var import_fs_extra16 = __toESM(require_lib3(), 1);
|
|
93691
|
-
import { join as join92, relative as relative15, resolve as
|
|
93907
|
+
import { join as join92, relative as relative15, resolve as resolve21 } from "node:path";
|
|
93692
93908
|
|
|
93693
93909
|
class FileScanner2 {
|
|
93694
93910
|
static async getFiles(dirPath, relativeTo) {
|
|
@@ -93768,8 +93984,8 @@ class FileScanner2 {
|
|
|
93768
93984
|
return customFiles;
|
|
93769
93985
|
}
|
|
93770
93986
|
static isSafePath(basePath, targetPath) {
|
|
93771
|
-
const resolvedBase =
|
|
93772
|
-
const resolvedTarget =
|
|
93987
|
+
const resolvedBase = resolve21(basePath);
|
|
93988
|
+
const resolvedTarget = resolve21(targetPath);
|
|
93773
93989
|
return resolvedTarget.startsWith(resolvedBase);
|
|
93774
93990
|
}
|
|
93775
93991
|
static toPosixPath(path14) {
|
|
@@ -93785,7 +94001,7 @@ import { join as join94 } from "node:path";
|
|
|
93785
94001
|
|
|
93786
94002
|
// src/services/transformers/commands-prefix/content-transformer.ts
|
|
93787
94003
|
init_logger();
|
|
93788
|
-
import { readFile as
|
|
94004
|
+
import { readFile as readFile43, readdir as readdir20, writeFile as writeFile26 } from "node:fs/promises";
|
|
93789
94005
|
import { join as join93 } from "node:path";
|
|
93790
94006
|
var TRANSFORMABLE_EXTENSIONS = new Set([
|
|
93791
94007
|
".md",
|
|
@@ -93855,7 +94071,7 @@ async function transformCommandReferences(directory, options2 = {}) {
|
|
|
93855
94071
|
await processDirectory(fullPath);
|
|
93856
94072
|
} else if (entry.isFile() && shouldTransformFile(entry.name)) {
|
|
93857
94073
|
try {
|
|
93858
|
-
const content = await
|
|
94074
|
+
const content = await readFile43(fullPath, "utf-8");
|
|
93859
94075
|
const { transformed, changes } = transformCommandContent(content);
|
|
93860
94076
|
if (changes > 0) {
|
|
93861
94077
|
if (options2.dryRun) {
|
|
@@ -94392,7 +94608,7 @@ init_skip_directories();
|
|
|
94392
94608
|
init_types3();
|
|
94393
94609
|
var import_fs_extra21 = __toESM(require_lib3(), 1);
|
|
94394
94610
|
import { createHash as createHash4 } from "node:crypto";
|
|
94395
|
-
import { readFile as
|
|
94611
|
+
import { readFile as readFile45, readdir as readdir24, writeFile as writeFile27 } from "node:fs/promises";
|
|
94396
94612
|
import { join as join98, relative as relative16 } from "node:path";
|
|
94397
94613
|
|
|
94398
94614
|
class SkillsManifestManager {
|
|
@@ -94426,7 +94642,7 @@ class SkillsManifestManager {
|
|
|
94426
94642
|
return null;
|
|
94427
94643
|
}
|
|
94428
94644
|
try {
|
|
94429
|
-
const content = await
|
|
94645
|
+
const content = await readFile45(manifestPath, "utf-8");
|
|
94430
94646
|
const data = JSON.parse(content);
|
|
94431
94647
|
const manifest = SkillsManifestSchema.parse(data);
|
|
94432
94648
|
logger.debug(`Read manifest from: ${manifestPath}`);
|
|
@@ -94498,7 +94714,7 @@ class SkillsManifestManager {
|
|
|
94498
94714
|
files.sort();
|
|
94499
94715
|
for (const file of files) {
|
|
94500
94716
|
const relativePath = relative16(dirPath, file);
|
|
94501
|
-
const content = await
|
|
94717
|
+
const content = await readFile45(file);
|
|
94502
94718
|
hash.update(relativePath);
|
|
94503
94719
|
hash.update(content);
|
|
94504
94720
|
}
|
|
@@ -95238,7 +95454,7 @@ import { relative as relative18 } from "node:path";
|
|
|
95238
95454
|
init_skip_directories();
|
|
95239
95455
|
import { createHash as createHash5 } from "node:crypto";
|
|
95240
95456
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
95241
|
-
import { readFile as
|
|
95457
|
+
import { readFile as readFile46, readdir as readdir28 } from "node:fs/promises";
|
|
95242
95458
|
import { join as join102, relative as relative17 } from "node:path";
|
|
95243
95459
|
async function getAllFiles(dirPath) {
|
|
95244
95460
|
const files = [];
|
|
@@ -95258,12 +95474,12 @@ async function getAllFiles(dirPath) {
|
|
|
95258
95474
|
return files;
|
|
95259
95475
|
}
|
|
95260
95476
|
async function hashFile(filePath) {
|
|
95261
|
-
return new Promise((
|
|
95477
|
+
return new Promise((resolve22, reject) => {
|
|
95262
95478
|
const hash = createHash5("sha256");
|
|
95263
95479
|
const stream = createReadStream3(filePath);
|
|
95264
95480
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
95265
95481
|
stream.on("end", () => {
|
|
95266
|
-
|
|
95482
|
+
resolve22(hash.digest("hex"));
|
|
95267
95483
|
});
|
|
95268
95484
|
stream.on("error", (error) => {
|
|
95269
95485
|
stream.destroy();
|
|
@@ -95277,7 +95493,7 @@ async function hashDirectory(dirPath) {
|
|
|
95277
95493
|
files.sort();
|
|
95278
95494
|
for (const file of files) {
|
|
95279
95495
|
const relativePath = relative17(dirPath, file);
|
|
95280
|
-
const content = await
|
|
95496
|
+
const content = await readFile46(file);
|
|
95281
95497
|
hash.update(relativePath);
|
|
95282
95498
|
hash.update(content);
|
|
95283
95499
|
}
|
|
@@ -95611,7 +95827,7 @@ import { join as join107 } from "node:path";
|
|
|
95611
95827
|
|
|
95612
95828
|
// src/services/transformers/opencode-path-transformer.ts
|
|
95613
95829
|
init_logger();
|
|
95614
|
-
import { readFile as
|
|
95830
|
+
import { readFile as readFile47, readdir as readdir30, writeFile as writeFile28 } from "node:fs/promises";
|
|
95615
95831
|
import { platform as platform12 } from "node:os";
|
|
95616
95832
|
import { extname as extname6, join as join106 } from "node:path";
|
|
95617
95833
|
var IS_WINDOWS2 = platform12() === "win32";
|
|
@@ -95682,7 +95898,7 @@ async function transformPathsForGlobalOpenCode(directory, options2 = {}) {
|
|
|
95682
95898
|
await processDirectory2(fullPath);
|
|
95683
95899
|
} else if (entry.isFile() && shouldTransformFile2(entry.name)) {
|
|
95684
95900
|
try {
|
|
95685
|
-
const content = await
|
|
95901
|
+
const content = await readFile47(fullPath, "utf-8");
|
|
95686
95902
|
const { transformed, changes } = transformOpenCodeContent(content);
|
|
95687
95903
|
if (changes > 0) {
|
|
95688
95904
|
await writeFile28(fullPath, transformed, "utf-8");
|
|
@@ -96022,7 +96238,7 @@ async function handlePostInstall(ctx) {
|
|
|
96022
96238
|
init_config_manager();
|
|
96023
96239
|
init_github_client();
|
|
96024
96240
|
import { mkdir as mkdir30 } from "node:fs/promises";
|
|
96025
|
-
import { join as join110, resolve as
|
|
96241
|
+
import { join as join110, resolve as resolve23 } from "node:path";
|
|
96026
96242
|
|
|
96027
96243
|
// src/domains/github/kit-access-checker.ts
|
|
96028
96244
|
init_logger();
|
|
@@ -96152,8 +96368,8 @@ async function runPreflightChecks() {
|
|
|
96152
96368
|
|
|
96153
96369
|
// src/domains/installation/fresh-installer.ts
|
|
96154
96370
|
init_metadata_migration();
|
|
96155
|
-
import { existsSync as
|
|
96156
|
-
import { dirname as dirname27, join as join109, resolve as
|
|
96371
|
+
import { existsSync as existsSync57, readdirSync as readdirSync5, rmSync as rmSync4, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
|
|
96372
|
+
import { dirname as dirname27, join as join109, resolve as resolve22 } from "node:path";
|
|
96157
96373
|
init_logger();
|
|
96158
96374
|
init_safe_spinner();
|
|
96159
96375
|
var import_fs_extra31 = __toESM(require_lib3(), 1);
|
|
@@ -96201,15 +96417,15 @@ async function analyzeFreshInstallation(claudeDir2) {
|
|
|
96201
96417
|
};
|
|
96202
96418
|
}
|
|
96203
96419
|
function cleanupEmptyDirectories2(filePath, claudeDir2) {
|
|
96204
|
-
const normalizedClaudeDir =
|
|
96205
|
-
let currentDir =
|
|
96420
|
+
const normalizedClaudeDir = resolve22(claudeDir2);
|
|
96421
|
+
let currentDir = resolve22(dirname27(filePath));
|
|
96206
96422
|
while (currentDir !== normalizedClaudeDir && currentDir.startsWith(normalizedClaudeDir)) {
|
|
96207
96423
|
try {
|
|
96208
96424
|
const entries = readdirSync5(currentDir);
|
|
96209
96425
|
if (entries.length === 0) {
|
|
96210
96426
|
rmdirSync2(currentDir);
|
|
96211
96427
|
logger.debug(`Removed empty directory: ${currentDir}`);
|
|
96212
|
-
currentDir =
|
|
96428
|
+
currentDir = resolve22(dirname27(currentDir));
|
|
96213
96429
|
} else {
|
|
96214
96430
|
break;
|
|
96215
96431
|
}
|
|
@@ -96228,7 +96444,7 @@ async function removeFilesByOwnership(claudeDir2, analysis, includeModified) {
|
|
|
96228
96444
|
for (const file of filesToRemove) {
|
|
96229
96445
|
const fullPath = join109(claudeDir2, file.path);
|
|
96230
96446
|
try {
|
|
96231
|
-
if (
|
|
96447
|
+
if (existsSync57(fullPath)) {
|
|
96232
96448
|
unlinkSync4(fullPath);
|
|
96233
96449
|
removedFiles.push(file.path);
|
|
96234
96450
|
logger.debug(`Removed: ${file.path}`);
|
|
@@ -96521,7 +96737,7 @@ async function handleSelection(ctx) {
|
|
|
96521
96737
|
}
|
|
96522
96738
|
}
|
|
96523
96739
|
}
|
|
96524
|
-
const resolvedDir =
|
|
96740
|
+
const resolvedDir = resolve23(targetDir);
|
|
96525
96741
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
96526
96742
|
if (!ctx.options.global && PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
96527
96743
|
logger.warning("You're at HOME directory. Installing here modifies your GLOBAL ClaudeKit.");
|
|
@@ -96695,8 +96911,8 @@ async function handleSelection(ctx) {
|
|
|
96695
96911
|
};
|
|
96696
96912
|
}
|
|
96697
96913
|
// src/commands/init/phases/sync-handler.ts
|
|
96698
|
-
import { copyFile as copyFile8, mkdir as mkdir31, open as open5, readFile as
|
|
96699
|
-
import { dirname as dirname28, join as join111, resolve as
|
|
96914
|
+
import { copyFile as copyFile8, mkdir as mkdir31, open as open5, readFile as readFile49, rename as rename6, stat as stat17, unlink as unlink11, writeFile as writeFile30 } from "node:fs/promises";
|
|
96915
|
+
import { dirname as dirname28, join as join111, resolve as resolve24 } from "node:path";
|
|
96700
96916
|
init_logger();
|
|
96701
96917
|
init_path_resolver();
|
|
96702
96918
|
var import_fs_extra33 = __toESM(require_lib3(), 1);
|
|
@@ -96705,7 +96921,7 @@ async function handleSync(ctx) {
|
|
|
96705
96921
|
if (!ctx.options.sync) {
|
|
96706
96922
|
return ctx;
|
|
96707
96923
|
}
|
|
96708
|
-
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() :
|
|
96924
|
+
const resolvedDir = ctx.options.global ? PathResolver.getGlobalKitDir() : resolve24(ctx.options.dir || ".");
|
|
96709
96925
|
const claudeDir2 = ctx.options.global ? resolvedDir : join111(resolvedDir, ".claude");
|
|
96710
96926
|
if (!await import_fs_extra33.pathExists(claudeDir2)) {
|
|
96711
96927
|
logger.error("Cannot sync: no .claude directory found");
|
|
@@ -96839,7 +97055,7 @@ async function acquireSyncLock(global3) {
|
|
|
96839
97055
|
}
|
|
96840
97056
|
logger.debug(`Lock stat failed: ${statError}`);
|
|
96841
97057
|
}
|
|
96842
|
-
await new Promise((
|
|
97058
|
+
await new Promise((resolve25) => setTimeout(resolve25, 100));
|
|
96843
97059
|
continue;
|
|
96844
97060
|
}
|
|
96845
97061
|
throw err;
|
|
@@ -96863,7 +97079,7 @@ async function executeSyncMerge(ctx) {
|
|
|
96863
97079
|
try {
|
|
96864
97080
|
const sourceMetadataPath = join111(upstreamDir, "metadata.json");
|
|
96865
97081
|
if (await import_fs_extra33.pathExists(sourceMetadataPath)) {
|
|
96866
|
-
const content = await
|
|
97082
|
+
const content = await readFile49(sourceMetadataPath, "utf-8");
|
|
96867
97083
|
const sourceMetadata = JSON.parse(content);
|
|
96868
97084
|
deletions = sourceMetadata.deletions || [];
|
|
96869
97085
|
}
|
|
@@ -97161,7 +97377,7 @@ async function renameFolders(dirsToRename, extractDir, options2) {
|
|
|
97161
97377
|
// src/services/transformers/folder-transform/path-replacer.ts
|
|
97162
97378
|
init_logger();
|
|
97163
97379
|
init_types3();
|
|
97164
|
-
import { readFile as
|
|
97380
|
+
import { readFile as readFile50, readdir as readdir32, writeFile as writeFile31 } from "node:fs/promises";
|
|
97165
97381
|
import { join as join113, relative as relative20 } from "node:path";
|
|
97166
97382
|
var TRANSFORMABLE_FILE_PATTERNS = [
|
|
97167
97383
|
".md",
|
|
@@ -97228,7 +97444,7 @@ async function transformFileContents(dir, compiledReplacements, options2) {
|
|
|
97228
97444
|
if (!shouldTransform)
|
|
97229
97445
|
continue;
|
|
97230
97446
|
try {
|
|
97231
|
-
const content = await
|
|
97447
|
+
const content = await readFile50(fullPath, "utf-8");
|
|
97232
97448
|
let newContent = content;
|
|
97233
97449
|
let changeCount = 0;
|
|
97234
97450
|
for (const { regex: regex2, replacement } of compiledReplacements) {
|
|
@@ -97350,7 +97566,7 @@ async function transformFolderPaths(extractDir, folders, options2 = {}) {
|
|
|
97350
97566
|
|
|
97351
97567
|
// src/services/transformers/global-path-transformer.ts
|
|
97352
97568
|
init_logger();
|
|
97353
|
-
import { readFile as
|
|
97569
|
+
import { readFile as readFile51, readdir as readdir33, writeFile as writeFile32 } from "node:fs/promises";
|
|
97354
97570
|
import { platform as platform13 } from "node:os";
|
|
97355
97571
|
import { extname as extname7, join as join114 } from "node:path";
|
|
97356
97572
|
var IS_WINDOWS3 = platform13() === "win32";
|
|
@@ -97470,7 +97686,7 @@ async function transformPathsForGlobalInstall(directory, options2 = {}) {
|
|
|
97470
97686
|
await processDirectory2(fullPath);
|
|
97471
97687
|
} else if (entry.isFile() && shouldTransformFile3(entry.name)) {
|
|
97472
97688
|
try {
|
|
97473
|
-
const content = await
|
|
97689
|
+
const content = await readFile51(fullPath, "utf-8");
|
|
97474
97690
|
const { transformed, changes } = transformContent(content);
|
|
97475
97691
|
if (changes > 0) {
|
|
97476
97692
|
await writeFile32(fullPath, transformed, "utf-8");
|
|
@@ -97726,14 +97942,13 @@ async function initCommand(options2) {
|
|
|
97726
97942
|
// src/commands/migrate/migrate-command.ts
|
|
97727
97943
|
init_dist2();
|
|
97728
97944
|
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
97729
|
-
import { existsSync as
|
|
97730
|
-
import { readFile as
|
|
97945
|
+
import { existsSync as existsSync58 } from "node:fs";
|
|
97946
|
+
import { readFile as readFile52, rm as rm14, unlink as unlink12 } from "node:fs/promises";
|
|
97731
97947
|
import { homedir as homedir30 } from "node:os";
|
|
97732
|
-
import { basename as basename16, join as join116, resolve as
|
|
97948
|
+
import { basename as basename16, join as join116, resolve as resolve25 } from "node:path";
|
|
97733
97949
|
init_logger();
|
|
97734
97950
|
init_agents_discovery();
|
|
97735
97951
|
init_commands_discovery();
|
|
97736
|
-
init_checksum_utils();
|
|
97737
97952
|
init_codex_toml_installer();
|
|
97738
97953
|
init_config_discovery();
|
|
97739
97954
|
|
|
@@ -98060,6 +98275,8 @@ init_portable_installer();
|
|
|
98060
98275
|
init_portable_manifest();
|
|
98061
98276
|
init_portable_registry();
|
|
98062
98277
|
init_provider_registry();
|
|
98278
|
+
init_reconcile_registry_backfill();
|
|
98279
|
+
init_reconcile_state_builders();
|
|
98063
98280
|
init_reconciler();
|
|
98064
98281
|
init_skills_discovery();
|
|
98065
98282
|
|
|
@@ -98126,9 +98343,9 @@ function shouldExecuteAction2(action) {
|
|
|
98126
98343
|
}
|
|
98127
98344
|
async function executeDeleteAction(action, options2) {
|
|
98128
98345
|
const preservePaths = options2?.preservePaths ?? new Set;
|
|
98129
|
-
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(
|
|
98346
|
+
const shouldPreserveTarget = action.targetPath.length > 0 && preservePaths.has(resolve25(action.targetPath));
|
|
98130
98347
|
try {
|
|
98131
|
-
if (!shouldPreserveTarget && action.targetPath &&
|
|
98348
|
+
if (!shouldPreserveTarget && action.targetPath && existsSync58(action.targetPath)) {
|
|
98132
98349
|
await rm14(action.targetPath, { recursive: true, force: true });
|
|
98133
98350
|
}
|
|
98134
98351
|
await removePortableInstallation(action.item, action.type, action.provider, action.global);
|
|
@@ -98153,12 +98370,12 @@ async function executeDeleteAction(action, options2) {
|
|
|
98153
98370
|
async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
98154
98371
|
if (!skillSourcePath)
|
|
98155
98372
|
return;
|
|
98156
|
-
const sourceMetadataPath = join116(
|
|
98157
|
-
if (!
|
|
98373
|
+
const sourceMetadataPath = join116(resolve25(skillSourcePath, ".."), "metadata.json");
|
|
98374
|
+
if (!existsSync58(sourceMetadataPath))
|
|
98158
98375
|
return;
|
|
98159
98376
|
let sourceMetadata;
|
|
98160
98377
|
try {
|
|
98161
|
-
const content = await
|
|
98378
|
+
const content = await readFile52(sourceMetadataPath, "utf-8");
|
|
98162
98379
|
sourceMetadata = JSON.parse(content);
|
|
98163
98380
|
} catch (error) {
|
|
98164
98381
|
logger.debug(`[migrate] Failed to parse source metadata.json: ${error}`);
|
|
@@ -98167,7 +98384,7 @@ async function processMetadataDeletions(skillSourcePath, installGlobally) {
|
|
|
98167
98384
|
if (!sourceMetadata.deletions || sourceMetadata.deletions.length === 0)
|
|
98168
98385
|
return;
|
|
98169
98386
|
const claudeDir2 = installGlobally ? join116(homedir30(), ".claude") : join116(process.cwd(), ".claude");
|
|
98170
|
-
if (!
|
|
98387
|
+
if (!existsSync58(claudeDir2))
|
|
98171
98388
|
return;
|
|
98172
98389
|
try {
|
|
98173
98390
|
const result = await handleDeletions(sourceMetadata, claudeDir2);
|
|
@@ -98416,9 +98633,9 @@ async function migrateCommand(options2) {
|
|
|
98416
98633
|
const interactive = process.stdout.isTTY && !options2.yes;
|
|
98417
98634
|
const conflictActions = plan.actions.filter((a3) => a3.action === "conflict");
|
|
98418
98635
|
for (const action of conflictActions) {
|
|
98419
|
-
if (!action.diff && action.targetPath &&
|
|
98636
|
+
if (!action.diff && action.targetPath && existsSync58(action.targetPath)) {
|
|
98420
98637
|
try {
|
|
98421
|
-
const targetContent = await
|
|
98638
|
+
const targetContent = await readFile52(action.targetPath, "utf-8");
|
|
98422
98639
|
const sourceItem = agents2.find((a3) => a3.name === action.item) || commands.find((c2) => c2.name === action.item) || (configItem?.name === action.item ? configItem : null) || ruleItems.find((r2) => r2.name === action.item) || hookItems.find((h2) => h2.name === action.item);
|
|
98423
98640
|
if (sourceItem) {
|
|
98424
98641
|
const providerConfig = providers[action.provider];
|
|
@@ -98544,26 +98761,16 @@ async function migrateCommand(options2) {
|
|
|
98544
98761
|
}
|
|
98545
98762
|
}
|
|
98546
98763
|
await processMetadataDeletions(skillSource, installGlobally);
|
|
98547
|
-
const writtenPaths = new Set(allResults.filter((result) => result.success && !result.skipped && result.path.length > 0).map((result) =>
|
|
98764
|
+
const writtenPaths = new Set(allResults.filter((result) => result.success && !result.skipped && result.path.length > 0).map((result) => resolve25(result.path)));
|
|
98548
98765
|
for (const deleteAction of plannedDeleteActions) {
|
|
98549
98766
|
allResults.push(await executeDeleteAction(deleteAction, {
|
|
98550
98767
|
preservePaths: writtenPaths
|
|
98551
98768
|
}));
|
|
98552
98769
|
}
|
|
98553
|
-
|
|
98554
|
-
|
|
98555
|
-
|
|
98556
|
-
|
|
98557
|
-
try {
|
|
98558
|
-
await addPortableInstallation(action.item, action.type, action.provider, action.global, action.targetPath, registryEntry.sourcePath, {
|
|
98559
|
-
sourceChecksum: action.sourceChecksum,
|
|
98560
|
-
targetChecksum: action.currentTargetChecksum,
|
|
98561
|
-
installSource: registryEntry.installSource === "manual" ? "manual" : "kit"
|
|
98562
|
-
});
|
|
98563
|
-
} catch {
|
|
98564
|
-
logger.debug(`Failed to populate checksums for ${action.item} — will retry on next run`);
|
|
98565
|
-
}
|
|
98566
|
-
}
|
|
98770
|
+
try {
|
|
98771
|
+
await backfillRegistryChecksums(plan.actions, registry);
|
|
98772
|
+
} catch {
|
|
98773
|
+
logger.debug("Failed to backfill reconcile registry checksums — will retry on next run");
|
|
98567
98774
|
}
|
|
98568
98775
|
for (const provider of selectedProviders) {
|
|
98569
98776
|
const providerConfig = providers[provider];
|
|
@@ -98582,7 +98789,7 @@ async function migrateCommand(options2) {
|
|
|
98582
98789
|
}
|
|
98583
98790
|
}
|
|
98584
98791
|
try {
|
|
98585
|
-
const kitRoot = (agentSource ?
|
|
98792
|
+
const kitRoot = (agentSource ? resolve25(agentSource, "..") : null) ?? (commandSource ? resolve25(commandSource, "..") : null) ?? (skillSource ? resolve25(skillSource, "..") : null) ?? null;
|
|
98586
98793
|
const manifest = kitRoot ? await loadPortableManifest(kitRoot) : null;
|
|
98587
98794
|
if (manifest?.cliVersion) {
|
|
98588
98795
|
await updateAppliedManifestVersion(manifest.cliVersion);
|
|
@@ -98631,7 +98838,7 @@ async function migrateCommand(options2) {
|
|
|
98631
98838
|
}
|
|
98632
98839
|
async function rollbackResults(results) {
|
|
98633
98840
|
for (const result of results) {
|
|
98634
|
-
if (!result.path || !
|
|
98841
|
+
if (!result.path || !existsSync58(result.path))
|
|
98635
98842
|
continue;
|
|
98636
98843
|
try {
|
|
98637
98844
|
if (result.overwritten)
|
|
@@ -98645,29 +98852,16 @@ async function rollbackResults(results) {
|
|
|
98645
98852
|
} catch {}
|
|
98646
98853
|
}
|
|
98647
98854
|
}
|
|
98855
|
+
function warnConversionFallback2(warning) {
|
|
98856
|
+
logger.warning(logger.sanitize(`[migrate] Falling back to raw checksum for ${warning.provider} ${warning.type} "${warning.item}" because ${warning.format} conversion failed: ${warning.error}`));
|
|
98857
|
+
}
|
|
98648
98858
|
async function computeSourceStates(items, selectedProviders) {
|
|
98649
98859
|
const states = [];
|
|
98650
98860
|
const processItems = async (itemList, type) => {
|
|
98651
98861
|
for (const item of itemList) {
|
|
98652
|
-
|
|
98653
|
-
|
|
98654
|
-
|
|
98655
|
-
const providerConfig = providers[provider];
|
|
98656
|
-
const pathConfigKey = getProviderPathKey(type);
|
|
98657
|
-
const pathConfig = providerConfig[pathConfigKey];
|
|
98658
|
-
if (pathConfig && typeof pathConfig === "object" && "format" in pathConfig) {
|
|
98659
|
-
const converted = convertItem(item, pathConfig.format, provider);
|
|
98660
|
-
if (converted.content) {
|
|
98661
|
-
convertedChecksums[provider] = computeContentChecksum(converted.content);
|
|
98662
|
-
}
|
|
98663
|
-
}
|
|
98664
|
-
}
|
|
98665
|
-
states.push({
|
|
98666
|
-
item: item.name,
|
|
98667
|
-
type,
|
|
98668
|
-
sourceChecksum,
|
|
98669
|
-
convertedChecksums
|
|
98670
|
-
});
|
|
98862
|
+
states.push(buildSourceItemState(item, type, selectedProviders, {
|
|
98863
|
+
onConversionFallback: warnConversionFallback2
|
|
98864
|
+
}));
|
|
98671
98865
|
}
|
|
98672
98866
|
};
|
|
98673
98867
|
await processItems(items.agents, "agent");
|
|
@@ -98681,35 +98875,18 @@ async function computeSourceStates(items, selectedProviders) {
|
|
|
98681
98875
|
}
|
|
98682
98876
|
async function computeTargetStates(selectedProviders, global3) {
|
|
98683
98877
|
const registry = await readPortableRegistry();
|
|
98684
|
-
const
|
|
98685
|
-
for (const entry of registry.installations) {
|
|
98878
|
+
const relevantEntries = registry.installations.filter((entry) => {
|
|
98686
98879
|
if (!selectedProviders.includes(entry.provider))
|
|
98687
|
-
|
|
98880
|
+
return false;
|
|
98688
98881
|
if (entry.global !== global3)
|
|
98689
|
-
|
|
98690
|
-
|
|
98691
|
-
|
|
98692
|
-
|
|
98693
|
-
|
|
98694
|
-
|
|
98695
|
-
path: entry.path,
|
|
98696
|
-
exists: false
|
|
98697
|
-
});
|
|
98698
|
-
continue;
|
|
98699
|
-
}
|
|
98700
|
-
const state = {
|
|
98701
|
-
path: entry.path,
|
|
98702
|
-
exists: true
|
|
98703
|
-
};
|
|
98704
|
-
try {
|
|
98705
|
-
const content = await readFile51(entry.path, "utf-8");
|
|
98706
|
-
state.currentChecksum = computeContentChecksum(content);
|
|
98707
|
-
} catch (error) {
|
|
98708
|
-
logger.debug(`[migrate] Failed to read target for checksum: ${entry.path} (${String(error)})`);
|
|
98882
|
+
return false;
|
|
98883
|
+
return entry.type !== "skill";
|
|
98884
|
+
});
|
|
98885
|
+
return buildTargetStates(relevantEntries, {
|
|
98886
|
+
onReadFailure: (entryPath, error) => {
|
|
98887
|
+
logger.debug(`[migrate] Failed to read target for checksum: ${entryPath} (${String(error)})`);
|
|
98709
98888
|
}
|
|
98710
|
-
|
|
98711
|
-
}
|
|
98712
|
-
return states;
|
|
98889
|
+
});
|
|
98713
98890
|
}
|
|
98714
98891
|
function displayResults3(results) {
|
|
98715
98892
|
console.log();
|
|
@@ -98761,7 +98938,7 @@ var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
|
98761
98938
|
|
|
98762
98939
|
// src/commands/new/phases/directory-setup.ts
|
|
98763
98940
|
init_config_manager();
|
|
98764
|
-
import { resolve as
|
|
98941
|
+
import { resolve as resolve26 } from "node:path";
|
|
98765
98942
|
init_logger();
|
|
98766
98943
|
init_path_resolver();
|
|
98767
98944
|
init_types3();
|
|
@@ -98846,7 +99023,7 @@ async function directorySetup(validOptions, prompts) {
|
|
|
98846
99023
|
targetDir = await prompts.getDirectory(targetDir);
|
|
98847
99024
|
}
|
|
98848
99025
|
}
|
|
98849
|
-
const resolvedDir =
|
|
99026
|
+
const resolvedDir = resolve26(targetDir);
|
|
98850
99027
|
logger.info(`Target directory: ${resolvedDir}`);
|
|
98851
99028
|
if (PathResolver.isLocalSameAsGlobal(resolvedDir)) {
|
|
98852
99029
|
logger.warning("You're creating a project at HOME directory.");
|
|
@@ -99179,16 +99356,16 @@ Please use only one download method.`);
|
|
|
99179
99356
|
}
|
|
99180
99357
|
// src/commands/plan/plan-command.ts
|
|
99181
99358
|
init_output_manager();
|
|
99182
|
-
import { existsSync as
|
|
99183
|
-
import { dirname as dirname30, join as join120, parse as parse6, resolve as
|
|
99359
|
+
import { existsSync as existsSync60, statSync as statSync8 } from "node:fs";
|
|
99360
|
+
import { dirname as dirname30, join as join120, parse as parse6, resolve as resolve29 } from "node:path";
|
|
99184
99361
|
|
|
99185
99362
|
// src/commands/plan/plan-read-handlers.ts
|
|
99186
99363
|
init_plan_parser();
|
|
99187
99364
|
init_logger();
|
|
99188
99365
|
init_output_manager();
|
|
99189
99366
|
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
99190
|
-
import { existsSync as
|
|
99191
|
-
import { basename as basename17, dirname as dirname29, join as join119, relative as relative21, resolve as
|
|
99367
|
+
import { existsSync as existsSync59, statSync as statSync7 } from "node:fs";
|
|
99368
|
+
import { basename as basename17, dirname as dirname29, join as join119, relative as relative21, resolve as resolve27 } from "node:path";
|
|
99192
99369
|
async function handleParse(target, options2) {
|
|
99193
99370
|
const planFile = resolvePlanFile(target);
|
|
99194
99371
|
if (!planFile) {
|
|
@@ -99263,8 +99440,8 @@ async function handleValidate(target, options2) {
|
|
|
99263
99440
|
process.exitCode = 1;
|
|
99264
99441
|
}
|
|
99265
99442
|
async function handleStatus(target, options2) {
|
|
99266
|
-
const t = target ?
|
|
99267
|
-
const plansDir = t &&
|
|
99443
|
+
const t = target ? resolve27(target) : null;
|
|
99444
|
+
const plansDir = t && existsSync59(t) && statSync7(t).isDirectory() && !existsSync59(join119(t, "plan.md")) ? t : null;
|
|
99268
99445
|
if (plansDir) {
|
|
99269
99446
|
const planFiles = scanPlanDir(plansDir);
|
|
99270
99447
|
if (planFiles.length === 0) {
|
|
@@ -99385,7 +99562,7 @@ async function handleKanban(target, options2) {
|
|
|
99385
99562
|
init_plan_parser();
|
|
99386
99563
|
init_output_manager();
|
|
99387
99564
|
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
99388
|
-
import { basename as basename18, relative as relative22, resolve as
|
|
99565
|
+
import { basename as basename18, relative as relative22, resolve as resolve28 } from "node:path";
|
|
99389
99566
|
async function handleCreate(target, options2) {
|
|
99390
99567
|
if (!options2.title) {
|
|
99391
99568
|
output.error("[X] --title is required for create");
|
|
@@ -99419,7 +99596,7 @@ async function handleCreate(target, options2) {
|
|
|
99419
99596
|
const result = scaffoldPlan({
|
|
99420
99597
|
title: options2.title,
|
|
99421
99598
|
phases: phaseNames.map((name2) => ({ name: name2 })),
|
|
99422
|
-
dir:
|
|
99599
|
+
dir: resolve28(dir),
|
|
99423
99600
|
priority,
|
|
99424
99601
|
issue: options2.issue ? Number(options2.issue) : undefined
|
|
99425
99602
|
});
|
|
@@ -99433,7 +99610,7 @@ async function handleCreate(target, options2) {
|
|
|
99433
99610
|
}
|
|
99434
99611
|
console.log();
|
|
99435
99612
|
console.log(import_picocolors31.default.bold(` [OK] Plan created: ${options2.title}`));
|
|
99436
|
-
console.log(` Directory: ${
|
|
99613
|
+
console.log(` Directory: ${resolve28(dir)}`);
|
|
99437
99614
|
console.log(` Phases: ${result.phaseFiles.length}`);
|
|
99438
99615
|
for (const f3 of result.phaseFiles) {
|
|
99439
99616
|
console.log(` [ ] ${basename18(f3)}`);
|
|
@@ -99531,13 +99708,13 @@ async function handleAddPhase(target, options2) {
|
|
|
99531
99708
|
|
|
99532
99709
|
// src/commands/plan/plan-command.ts
|
|
99533
99710
|
function resolvePlanFile(target) {
|
|
99534
|
-
const t = target ?
|
|
99535
|
-
if (
|
|
99711
|
+
const t = target ? resolve29(target) : process.cwd();
|
|
99712
|
+
if (existsSync60(t)) {
|
|
99536
99713
|
const stat18 = statSync8(t);
|
|
99537
99714
|
if (stat18.isFile())
|
|
99538
99715
|
return t;
|
|
99539
99716
|
const candidate = join120(t, "plan.md");
|
|
99540
|
-
if (
|
|
99717
|
+
if (existsSync60(candidate))
|
|
99541
99718
|
return candidate;
|
|
99542
99719
|
}
|
|
99543
99720
|
if (!target) {
|
|
@@ -99545,7 +99722,7 @@ function resolvePlanFile(target) {
|
|
|
99545
99722
|
const root = parse6(dir).root;
|
|
99546
99723
|
while (dir !== root) {
|
|
99547
99724
|
const candidate = join120(dir, "plan.md");
|
|
99548
|
-
if (
|
|
99725
|
+
if (existsSync60(candidate))
|
|
99549
99726
|
return candidate;
|
|
99550
99727
|
dir = dirname30(dir);
|
|
99551
99728
|
}
|
|
@@ -99595,7 +99772,7 @@ async function planCommand(action, target, options2) {
|
|
|
99595
99772
|
let resolvedTarget = target;
|
|
99596
99773
|
if (resolvedAction && !knownActions.has(resolvedAction)) {
|
|
99597
99774
|
const looksLikePath = resolvedAction.includes("/") || resolvedAction.includes("\\") || resolvedAction.endsWith(".md") || resolvedAction === "." || resolvedAction === "..";
|
|
99598
|
-
const existsOnDisk = !looksLikePath &&
|
|
99775
|
+
const existsOnDisk = !looksLikePath && existsSync60(resolve29(resolvedAction));
|
|
99599
99776
|
if (looksLikePath || existsOnDisk) {
|
|
99600
99777
|
resolvedTarget = resolvedAction;
|
|
99601
99778
|
resolvedAction = undefined;
|
|
@@ -99637,13 +99814,13 @@ init_claudekit_data2();
|
|
|
99637
99814
|
init_logger();
|
|
99638
99815
|
init_safe_prompts();
|
|
99639
99816
|
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
99640
|
-
import { existsSync as
|
|
99641
|
-
import { resolve as
|
|
99817
|
+
import { existsSync as existsSync61 } from "node:fs";
|
|
99818
|
+
import { resolve as resolve30 } from "node:path";
|
|
99642
99819
|
async function handleAdd(projectPath, options2) {
|
|
99643
99820
|
logger.debug(`Adding project: ${projectPath}, options: ${JSON.stringify(options2)}`);
|
|
99644
99821
|
intro("Add Project");
|
|
99645
|
-
const absolutePath =
|
|
99646
|
-
if (!
|
|
99822
|
+
const absolutePath = resolve30(projectPath);
|
|
99823
|
+
if (!existsSync61(absolutePath)) {
|
|
99647
99824
|
log.error(`Path does not exist: ${absolutePath}`);
|
|
99648
99825
|
process.exitCode = 1;
|
|
99649
99826
|
return;
|
|
@@ -100571,7 +100748,7 @@ async function detectInstallations() {
|
|
|
100571
100748
|
|
|
100572
100749
|
// src/commands/uninstall/removal-handler.ts
|
|
100573
100750
|
import { readdirSync as readdirSync7, rmSync as rmSync6 } from "node:fs";
|
|
100574
|
-
import { join as join122, resolve as
|
|
100751
|
+
import { join as join122, resolve as resolve31, sep as sep7 } from "node:path";
|
|
100575
100752
|
init_logger();
|
|
100576
100753
|
init_safe_prompts();
|
|
100577
100754
|
init_safe_spinner();
|
|
@@ -100712,8 +100889,8 @@ async function isDirectory(filePath) {
|
|
|
100712
100889
|
}
|
|
100713
100890
|
async function isPathSafeToRemove(filePath, baseDir) {
|
|
100714
100891
|
try {
|
|
100715
|
-
const resolvedPath =
|
|
100716
|
-
const resolvedBase =
|
|
100892
|
+
const resolvedPath = resolve31(filePath);
|
|
100893
|
+
const resolvedBase = resolve31(baseDir);
|
|
100717
100894
|
if (!resolvedPath.startsWith(resolvedBase + sep7) && resolvedPath !== resolvedBase) {
|
|
100718
100895
|
logger.debug(`Path outside installation directory: ${filePath}`);
|
|
100719
100896
|
return false;
|
|
@@ -100721,7 +100898,7 @@ async function isPathSafeToRemove(filePath, baseDir) {
|
|
|
100721
100898
|
const stats = await import_fs_extra37.lstat(filePath);
|
|
100722
100899
|
if (stats.isSymbolicLink()) {
|
|
100723
100900
|
const realPath = await import_fs_extra37.realpath(filePath);
|
|
100724
|
-
const resolvedReal =
|
|
100901
|
+
const resolvedReal = resolve31(realPath);
|
|
100725
100902
|
if (!resolvedReal.startsWith(resolvedBase + sep7) && resolvedReal !== resolvedBase) {
|
|
100726
100903
|
logger.debug(`Symlink points outside installation directory: ${filePath} -> ${realPath}`);
|
|
100727
100904
|
return false;
|
|
@@ -101056,7 +101233,7 @@ ${import_picocolors38.default.bold(import_picocolors38.default.cyan(result.kitCo
|
|
|
101056
101233
|
|
|
101057
101234
|
// src/commands/watch/watch-command.ts
|
|
101058
101235
|
init_logger();
|
|
101059
|
-
import { existsSync as
|
|
101236
|
+
import { existsSync as existsSync67 } from "node:fs";
|
|
101060
101237
|
import { rm as rm15 } from "node:fs/promises";
|
|
101061
101238
|
import { homedir as homedir32 } from "node:os";
|
|
101062
101239
|
import { join as join129 } from "node:path";
|
|
@@ -101128,7 +101305,7 @@ function getDisclaimerMarker() {
|
|
|
101128
101305
|
return AI_DISCLAIMER;
|
|
101129
101306
|
}
|
|
101130
101307
|
function spawnAndCollect2(command, args) {
|
|
101131
|
-
return new Promise((
|
|
101308
|
+
return new Promise((resolve32, reject) => {
|
|
101132
101309
|
const child = spawn5(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
101133
101310
|
const chunks = [];
|
|
101134
101311
|
const stderrChunks = [];
|
|
@@ -101141,7 +101318,7 @@ function spawnAndCollect2(command, args) {
|
|
|
101141
101318
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
101142
101319
|
return;
|
|
101143
101320
|
}
|
|
101144
|
-
|
|
101321
|
+
resolve32(Buffer.concat(chunks).toString("utf-8"));
|
|
101145
101322
|
});
|
|
101146
101323
|
});
|
|
101147
101324
|
}
|
|
@@ -101249,7 +101426,7 @@ function formatResponse(content, showBranding) {
|
|
|
101249
101426
|
return disclaimer + formatted + branding;
|
|
101250
101427
|
}
|
|
101251
101428
|
async function postViaGh(owner, repo, issueNumber, body) {
|
|
101252
|
-
return new Promise((
|
|
101429
|
+
return new Promise((resolve32, reject) => {
|
|
101253
101430
|
const args = [
|
|
101254
101431
|
"issue",
|
|
101255
101432
|
"comment",
|
|
@@ -101271,7 +101448,7 @@ async function postViaGh(owner, repo, issueNumber, body) {
|
|
|
101271
101448
|
reject(new Error(`gh exited with code ${code2}: ${stderr}`));
|
|
101272
101449
|
return;
|
|
101273
101450
|
}
|
|
101274
|
-
|
|
101451
|
+
resolve32();
|
|
101275
101452
|
});
|
|
101276
101453
|
});
|
|
101277
101454
|
}
|
|
@@ -101389,7 +101566,7 @@ After completing the implementation:
|
|
|
101389
101566
|
"--allowedTools",
|
|
101390
101567
|
tools
|
|
101391
101568
|
];
|
|
101392
|
-
await new Promise((
|
|
101569
|
+
await new Promise((resolve32, reject) => {
|
|
101393
101570
|
const child = spawn7("claude", args, { cwd: cwd2, stdio: ["pipe", "pipe", "pipe"], detached: false });
|
|
101394
101571
|
child.stdin.write(prompt);
|
|
101395
101572
|
child.stdin.end();
|
|
@@ -101414,7 +101591,7 @@ After completing the implementation:
|
|
|
101414
101591
|
reject(new Error(`Claude exited ${code2}: ${stderr.slice(0, 500)}`));
|
|
101415
101592
|
return;
|
|
101416
101593
|
}
|
|
101417
|
-
|
|
101594
|
+
resolve32();
|
|
101418
101595
|
});
|
|
101419
101596
|
});
|
|
101420
101597
|
}
|
|
@@ -101558,7 +101735,7 @@ function checkRateLimit2(processedThisHour, maxPerHour) {
|
|
|
101558
101735
|
return processedThisHour < maxPerHour;
|
|
101559
101736
|
}
|
|
101560
101737
|
function spawnAndCollect3(command, args) {
|
|
101561
|
-
return new Promise((
|
|
101738
|
+
return new Promise((resolve32, reject) => {
|
|
101562
101739
|
const child = spawn8(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
101563
101740
|
const chunks = [];
|
|
101564
101741
|
const stderrChunks = [];
|
|
@@ -101571,7 +101748,7 @@ function spawnAndCollect3(command, args) {
|
|
|
101571
101748
|
reject(new Error(`${command} exited with code ${code2}: ${stderr}`));
|
|
101572
101749
|
return;
|
|
101573
101750
|
}
|
|
101574
|
-
|
|
101751
|
+
resolve32(Buffer.concat(chunks).toString("utf-8"));
|
|
101575
101752
|
});
|
|
101576
101753
|
});
|
|
101577
101754
|
}
|
|
@@ -101620,7 +101797,7 @@ async function invokeClaude(options2) {
|
|
|
101620
101797
|
return collectClaudeOutput(child, options2.timeoutSec, verbose);
|
|
101621
101798
|
}
|
|
101622
101799
|
function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
101623
|
-
return new Promise((
|
|
101800
|
+
return new Promise((resolve32, reject) => {
|
|
101624
101801
|
const chunks = [];
|
|
101625
101802
|
const stderrChunks = [];
|
|
101626
101803
|
child.stdout?.on("data", (chunk) => {
|
|
@@ -101650,7 +101827,7 @@ function collectClaudeOutput(child, timeoutSec, verbose = false) {
|
|
|
101650
101827
|
reject(new Error(`Claude exited with code ${code2}: ${stderr}`));
|
|
101651
101828
|
return;
|
|
101652
101829
|
}
|
|
101653
|
-
|
|
101830
|
+
resolve32(verbose ? parseStreamJsonOutput(stdout2) : parseClaudeOutput(stdout2));
|
|
101654
101831
|
});
|
|
101655
101832
|
});
|
|
101656
101833
|
}
|
|
@@ -102353,16 +102530,16 @@ function cleanExpiredIssues(state, ttlDays) {
|
|
|
102353
102530
|
init_ck_config_manager();
|
|
102354
102531
|
init_file_io();
|
|
102355
102532
|
init_logger();
|
|
102356
|
-
import { existsSync as
|
|
102357
|
-
import { mkdir as mkdir33, readFile as
|
|
102533
|
+
import { existsSync as existsSync63 } from "node:fs";
|
|
102534
|
+
import { mkdir as mkdir33, readFile as readFile54 } from "node:fs/promises";
|
|
102358
102535
|
import { dirname as dirname32 } from "node:path";
|
|
102359
102536
|
var PROCESSED_ISSUES_CAP = 500;
|
|
102360
102537
|
async function readCkJson(projectDir) {
|
|
102361
102538
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
102362
102539
|
try {
|
|
102363
|
-
if (!
|
|
102540
|
+
if (!existsSync63(configPath))
|
|
102364
102541
|
return {};
|
|
102365
|
-
const content = await
|
|
102542
|
+
const content = await readFile54(configPath, "utf-8");
|
|
102366
102543
|
return JSON.parse(content);
|
|
102367
102544
|
} catch (error) {
|
|
102368
102545
|
logger.warning(`Failed to parse .ck.json: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
@@ -102386,7 +102563,7 @@ async function loadWatchState(projectDir) {
|
|
|
102386
102563
|
async function saveWatchState(projectDir, state) {
|
|
102387
102564
|
const configPath = CkConfigManager.getProjectConfigPath(projectDir);
|
|
102388
102565
|
const configDir = dirname32(configPath);
|
|
102389
|
-
if (!
|
|
102566
|
+
if (!existsSync63(configDir)) {
|
|
102390
102567
|
await mkdir33(configDir, { recursive: true });
|
|
102391
102568
|
}
|
|
102392
102569
|
const raw2 = await readCkJson(projectDir);
|
|
@@ -102513,7 +102690,7 @@ async function processImplementationQueue(state, config, setup, options2, watchL
|
|
|
102513
102690
|
// src/commands/watch/phases/repo-scanner.ts
|
|
102514
102691
|
init_logger();
|
|
102515
102692
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
102516
|
-
import { existsSync as
|
|
102693
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
102517
102694
|
import { readdir as readdir36, stat as stat19 } from "node:fs/promises";
|
|
102518
102695
|
import { join as join126 } from "node:path";
|
|
102519
102696
|
async function scanForRepos(parentDir) {
|
|
@@ -102527,7 +102704,7 @@ async function scanForRepos(parentDir) {
|
|
|
102527
102704
|
if (!entryStat.isDirectory())
|
|
102528
102705
|
continue;
|
|
102529
102706
|
const gitDir = join126(fullPath, ".git");
|
|
102530
|
-
if (!
|
|
102707
|
+
if (!existsSync64(gitDir))
|
|
102531
102708
|
continue;
|
|
102532
102709
|
const result = spawnSync6("gh", ["repo", "view", "--json", "owner,name"], {
|
|
102533
102710
|
encoding: "utf-8",
|
|
@@ -102551,7 +102728,7 @@ async function scanForRepos(parentDir) {
|
|
|
102551
102728
|
// src/commands/watch/phases/setup-validator.ts
|
|
102552
102729
|
init_logger();
|
|
102553
102730
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
102554
|
-
import { existsSync as
|
|
102731
|
+
import { existsSync as existsSync65 } from "node:fs";
|
|
102555
102732
|
import { homedir as homedir31 } from "node:os";
|
|
102556
102733
|
import { join as join127 } from "node:path";
|
|
102557
102734
|
async function validateSetup(cwd2) {
|
|
@@ -102585,7 +102762,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
102585
102762
|
throw new Error(`Failed to parse repository info: ${ghRepo.stdout}`);
|
|
102586
102763
|
}
|
|
102587
102764
|
const skillsPath = join127(homedir31(), ".claude", "skills");
|
|
102588
|
-
const skillsAvailable =
|
|
102765
|
+
const skillsAvailable = existsSync65(skillsPath);
|
|
102589
102766
|
if (!skillsAvailable) {
|
|
102590
102767
|
logger.warning(`ClaudeKit Engineer skills not found at ${skillsPath}`);
|
|
102591
102768
|
}
|
|
@@ -102601,7 +102778,7 @@ Run this command from a directory with a GitHub remote.`);
|
|
|
102601
102778
|
init_logger();
|
|
102602
102779
|
init_path_resolver();
|
|
102603
102780
|
import { createWriteStream as createWriteStream3, statSync as statSync9 } from "node:fs";
|
|
102604
|
-
import { existsSync as
|
|
102781
|
+
import { existsSync as existsSync66 } from "node:fs";
|
|
102605
102782
|
import { mkdir as mkdir34, rename as rename8 } from "node:fs/promises";
|
|
102606
102783
|
import { join as join128 } from "node:path";
|
|
102607
102784
|
|
|
@@ -102616,7 +102793,7 @@ class WatchLogger {
|
|
|
102616
102793
|
}
|
|
102617
102794
|
async init() {
|
|
102618
102795
|
try {
|
|
102619
|
-
if (!
|
|
102796
|
+
if (!existsSync66(this.logDir)) {
|
|
102620
102797
|
await mkdir34(this.logDir, { recursive: true });
|
|
102621
102798
|
}
|
|
102622
102799
|
const dateStr = formatDate(new Date);
|
|
@@ -102800,7 +102977,7 @@ async function watchCommand(options2) {
|
|
|
102800
102977
|
}
|
|
102801
102978
|
async function discoverRepos(options2, watchLog) {
|
|
102802
102979
|
const cwd2 = process.cwd();
|
|
102803
|
-
const isGitRepo =
|
|
102980
|
+
const isGitRepo = existsSync67(join129(cwd2, ".git"));
|
|
102804
102981
|
if (options2.force) {
|
|
102805
102982
|
await forceRemoveLock(watchLog);
|
|
102806
102983
|
}
|
|
@@ -102909,7 +103086,7 @@ function formatQueueInfo(state) {
|
|
|
102909
103086
|
return "idle";
|
|
102910
103087
|
}
|
|
102911
103088
|
function sleep(ms) {
|
|
102912
|
-
return new Promise((
|
|
103089
|
+
return new Promise((resolve32) => setTimeout(resolve32, ms));
|
|
102913
103090
|
}
|
|
102914
103091
|
// src/cli/command-registry.ts
|
|
102915
103092
|
init_logger();
|
|
@@ -103053,7 +103230,7 @@ init_version_checker();
|
|
|
103053
103230
|
init_logger();
|
|
103054
103231
|
init_path_resolver();
|
|
103055
103232
|
init_types3();
|
|
103056
|
-
import { existsSync as
|
|
103233
|
+
import { existsSync as existsSync78, readFileSync as readFileSync18 } from "node:fs";
|
|
103057
103234
|
import { join as join140 } from "node:path";
|
|
103058
103235
|
var packageVersion = package_default.version;
|
|
103059
103236
|
function formatInstalledKits(metadata) {
|
|
@@ -103090,7 +103267,7 @@ async function displayVersion() {
|
|
|
103090
103267
|
const prefix = PathResolver.getPathPrefix(false);
|
|
103091
103268
|
const localMetadataPath = prefix ? join140(process.cwd(), prefix, "metadata.json") : join140(process.cwd(), "metadata.json");
|
|
103092
103269
|
const isLocalSameAsGlobal = localMetadataPath === globalMetadataPath;
|
|
103093
|
-
if (!isLocalSameAsGlobal &&
|
|
103270
|
+
if (!isLocalSameAsGlobal && existsSync78(localMetadataPath)) {
|
|
103094
103271
|
try {
|
|
103095
103272
|
const rawMetadata = JSON.parse(readFileSync18(localMetadataPath, "utf-8"));
|
|
103096
103273
|
const metadata = MetadataSchema.parse(rawMetadata);
|
|
@@ -103104,7 +103281,7 @@ async function displayVersion() {
|
|
|
103104
103281
|
logger.verbose("Failed to parse local metadata.json", { error });
|
|
103105
103282
|
}
|
|
103106
103283
|
}
|
|
103107
|
-
if (
|
|
103284
|
+
if (existsSync78(globalMetadataPath)) {
|
|
103108
103285
|
try {
|
|
103109
103286
|
const rawMetadata = JSON.parse(readFileSync18(globalMetadataPath, "utf-8"));
|
|
103110
103287
|
const metadata = MetadataSchema.parse(rawMetadata);
|