@sunasteriskrnd/takumi 1.0.0-dev.47 → 1.0.0-dev.48
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 +137 -113
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19815,7 +19815,7 @@ var package_default;
|
|
|
19815
19815
|
var init_package = __esm(() => {
|
|
19816
19816
|
package_default = {
|
|
19817
19817
|
name: "@sunasteriskrnd/takumi",
|
|
19818
|
-
version: "1.0.0-dev.
|
|
19818
|
+
version: "1.0.0-dev.48",
|
|
19819
19819
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
19820
19820
|
type: "module",
|
|
19821
19821
|
repository: {
|
|
@@ -27299,6 +27299,48 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
27299
27299
|
}
|
|
27300
27300
|
});
|
|
27301
27301
|
|
|
27302
|
+
// src/domains/migration/release-manifest.ts
|
|
27303
|
+
import { join as join11 } from "node:path";
|
|
27304
|
+
function normalizeClaudeReleaseManifestPath(relativePath) {
|
|
27305
|
+
const normalized = relativePath.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
27306
|
+
return normalized.startsWith(".claude/") ? normalized.slice(".claude/".length) : normalized;
|
|
27307
|
+
}
|
|
27308
|
+
|
|
27309
|
+
class ReleaseManifestLoader {
|
|
27310
|
+
static async load(extractDir) {
|
|
27311
|
+
const manifestPath = join11(extractDir, "release-manifest.json");
|
|
27312
|
+
try {
|
|
27313
|
+
const content = await import_fs_extra8.readFile(manifestPath, "utf-8");
|
|
27314
|
+
const parsed = JSON.parse(content);
|
|
27315
|
+
return ReleaseManifestSchema.parse(parsed);
|
|
27316
|
+
} catch (error) {
|
|
27317
|
+
logger.debug(`Release manifest not found or invalid: ${error}`);
|
|
27318
|
+
return null;
|
|
27319
|
+
}
|
|
27320
|
+
}
|
|
27321
|
+
static findFile(manifest, relativePath) {
|
|
27322
|
+
const normalizedPath = normalizeClaudeReleaseManifestPath(relativePath);
|
|
27323
|
+
return manifest.files.find((file) => normalizeClaudeReleaseManifestPath(file.path) === normalizedPath);
|
|
27324
|
+
}
|
|
27325
|
+
}
|
|
27326
|
+
var import_fs_extra8, ReleaseManifestFileSchema, ReleaseManifestSchema;
|
|
27327
|
+
var init_release_manifest = __esm(() => {
|
|
27328
|
+
init_logger();
|
|
27329
|
+
init_zod();
|
|
27330
|
+
import_fs_extra8 = __toESM(require_lib(), 1);
|
|
27331
|
+
ReleaseManifestFileSchema = exports_external.object({
|
|
27332
|
+
path: exports_external.string(),
|
|
27333
|
+
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
27334
|
+
size: exports_external.number(),
|
|
27335
|
+
lastModified: exports_external.string().datetime({ offset: true }).optional()
|
|
27336
|
+
});
|
|
27337
|
+
ReleaseManifestSchema = exports_external.object({
|
|
27338
|
+
version: exports_external.string(),
|
|
27339
|
+
generatedAt: exports_external.string(),
|
|
27340
|
+
files: exports_external.array(ReleaseManifestFileSchema)
|
|
27341
|
+
});
|
|
27342
|
+
});
|
|
27343
|
+
|
|
27302
27344
|
// node_modules/semver/internal/constants.js
|
|
27303
27345
|
var require_constants4 = __commonJS((exports, module) => {
|
|
27304
27346
|
var SEMVER_SPEC_VERSION = "2.0.0";
|
|
@@ -29095,7 +29137,7 @@ class SelectiveMerger {
|
|
|
29095
29137
|
this.manifestMap = new Map;
|
|
29096
29138
|
if (manifest) {
|
|
29097
29139
|
for (const file of manifest.files) {
|
|
29098
|
-
this.manifestMap.set(file.path, file);
|
|
29140
|
+
this.manifestMap.set(normalizeClaudeReleaseManifestPath(file.path), file);
|
|
29099
29141
|
}
|
|
29100
29142
|
}
|
|
29101
29143
|
}
|
|
@@ -29104,25 +29146,26 @@ class SelectiveMerger {
|
|
|
29104
29146
|
this.installingKit = installingKit;
|
|
29105
29147
|
}
|
|
29106
29148
|
async shouldCopyFile(destPath, relativePath) {
|
|
29149
|
+
const providerRelativePath = normalizeClaudeReleaseManifestPath(relativePath);
|
|
29107
29150
|
let destStat;
|
|
29108
29151
|
try {
|
|
29109
29152
|
destStat = await stat2(destPath);
|
|
29110
29153
|
} catch {
|
|
29111
29154
|
if (this.claudeDir && this.installingKit) {
|
|
29112
|
-
const installed = await findFileInInstalledKits(this.claudeDir,
|
|
29155
|
+
const installed = await findFileInInstalledKits(this.claudeDir, providerRelativePath, this.installingKit);
|
|
29113
29156
|
if (installed.exists) {
|
|
29114
29157
|
logger.debug(`File ${relativePath} tracked by ${installed.ownerKit} but missing on disk`);
|
|
29115
29158
|
}
|
|
29116
29159
|
}
|
|
29117
29160
|
return { changed: true, reason: "new" };
|
|
29118
29161
|
}
|
|
29119
|
-
const manifestEntry = this.manifestMap.get(
|
|
29162
|
+
const manifestEntry = this.manifestMap.get(providerRelativePath);
|
|
29120
29163
|
if (!manifestEntry) {
|
|
29121
29164
|
logger.debug(`No manifest entry for ${relativePath}, will copy`);
|
|
29122
29165
|
return { changed: true, reason: "new" };
|
|
29123
29166
|
}
|
|
29124
29167
|
if (this.claudeDir && this.installingKit) {
|
|
29125
|
-
const installed = await findFileInInstalledKits(this.claudeDir,
|
|
29168
|
+
const installed = await findFileInInstalledKits(this.claudeDir, providerRelativePath, this.installingKit);
|
|
29126
29169
|
if (installed.exists && installed.checksum && installed.ownerKit) {
|
|
29127
29170
|
if (installed.checksum === manifestEntry.checksum) {
|
|
29128
29171
|
logger.debug(`Shared identical: ${relativePath} (owned by ${installed.ownerKit})`);
|
|
@@ -29137,7 +29180,7 @@ class SelectiveMerger {
|
|
|
29137
29180
|
const incomingTimestamp = manifestEntry.lastModified ?? null;
|
|
29138
29181
|
const existingTimestamp = installed.sourceTimestamp;
|
|
29139
29182
|
const conflictBase = {
|
|
29140
|
-
relativePath,
|
|
29183
|
+
relativePath: providerRelativePath,
|
|
29141
29184
|
incomingKit: this.installingKit,
|
|
29142
29185
|
existingKit: installed.ownerKit,
|
|
29143
29186
|
incomingTimestamp,
|
|
@@ -29253,6 +29296,7 @@ class SelectiveMerger {
|
|
|
29253
29296
|
}
|
|
29254
29297
|
var import_semver;
|
|
29255
29298
|
var init_selective_merger = __esm(() => {
|
|
29299
|
+
init_release_manifest();
|
|
29256
29300
|
init_manifest_reader();
|
|
29257
29301
|
init_ownership_checker();
|
|
29258
29302
|
init_logger();
|
|
@@ -29261,7 +29305,7 @@ var init_selective_merger = __esm(() => {
|
|
|
29261
29305
|
|
|
29262
29306
|
// src/domains/installation/merger/file-scanner.ts
|
|
29263
29307
|
import { relative as relative3 } from "node:path";
|
|
29264
|
-
import { join as
|
|
29308
|
+
import { join as join12 } from "node:path";
|
|
29265
29309
|
|
|
29266
29310
|
class FileScanner {
|
|
29267
29311
|
includeMatchers = [];
|
|
@@ -29283,12 +29327,12 @@ class FileScanner {
|
|
|
29283
29327
|
}
|
|
29284
29328
|
async getFiles(dir, baseDir = dir) {
|
|
29285
29329
|
const files = [];
|
|
29286
|
-
const entries = await
|
|
29330
|
+
const entries = await import_fs_extra9.readdir(dir, { encoding: "utf8" });
|
|
29287
29331
|
for (const entry of entries) {
|
|
29288
|
-
const fullPath =
|
|
29332
|
+
const fullPath = join12(dir, entry);
|
|
29289
29333
|
const relativePath = relative3(baseDir, fullPath);
|
|
29290
29334
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
29291
|
-
const stats = await
|
|
29335
|
+
const stats = await import_fs_extra9.lstat(fullPath);
|
|
29292
29336
|
if (stats.isSymbolicLink()) {
|
|
29293
29337
|
logger.warning(`Skipping symbolic link: ${normalizedRelativePath}`);
|
|
29294
29338
|
continue;
|
|
@@ -29316,10 +29360,10 @@ class FileScanner {
|
|
|
29316
29360
|
return files;
|
|
29317
29361
|
}
|
|
29318
29362
|
}
|
|
29319
|
-
var
|
|
29363
|
+
var import_fs_extra9, import_ignore, import_picomatch2;
|
|
29320
29364
|
var init_file_scanner = __esm(() => {
|
|
29321
29365
|
init_logger();
|
|
29322
|
-
|
|
29366
|
+
import_fs_extra9 = __toESM(require_lib(), 1);
|
|
29323
29367
|
import_ignore = __toESM(require_ignore(), 1);
|
|
29324
29368
|
import_picomatch2 = __toESM(require_picomatch2(), 1);
|
|
29325
29369
|
});
|
|
@@ -29475,8 +29519,8 @@ var init_shared = __esm(() => {
|
|
|
29475
29519
|
|
|
29476
29520
|
// src/domains/config/installed-settings-tracker.ts
|
|
29477
29521
|
import { existsSync as existsSync5 } from "node:fs";
|
|
29478
|
-
import { mkdir, readFile as
|
|
29479
|
-
import { dirname as dirname2, join as
|
|
29522
|
+
import { mkdir, readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
|
|
29523
|
+
import { dirname as dirname2, join as join13 } from "node:path";
|
|
29480
29524
|
|
|
29481
29525
|
class InstalledSettingsTracker {
|
|
29482
29526
|
projectDir;
|
|
@@ -29489,9 +29533,9 @@ class InstalledSettingsTracker {
|
|
|
29489
29533
|
}
|
|
29490
29534
|
getCkJsonPath() {
|
|
29491
29535
|
if (this.isGlobal) {
|
|
29492
|
-
return
|
|
29536
|
+
return join13(this.projectDir, TAKUMI_JSON_FILE);
|
|
29493
29537
|
}
|
|
29494
|
-
return
|
|
29538
|
+
return join13(this.projectDir, ".claude", TAKUMI_JSON_FILE);
|
|
29495
29539
|
}
|
|
29496
29540
|
async loadInstalledSettings() {
|
|
29497
29541
|
const ckJsonPath = this.getCkJsonPath();
|
|
@@ -29499,7 +29543,7 @@ class InstalledSettingsTracker {
|
|
|
29499
29543
|
return { hooks: [], mcpServers: [] };
|
|
29500
29544
|
}
|
|
29501
29545
|
try {
|
|
29502
|
-
const content = await
|
|
29546
|
+
const content = await readFile7(ckJsonPath, "utf-8");
|
|
29503
29547
|
const data = JSON.parse(content);
|
|
29504
29548
|
const installed = data.kits?.[this.kitName]?.installedSettings;
|
|
29505
29549
|
if (installed) {
|
|
@@ -29516,7 +29560,7 @@ class InstalledSettingsTracker {
|
|
|
29516
29560
|
try {
|
|
29517
29561
|
let data = {};
|
|
29518
29562
|
if (existsSync5(ckJsonPath)) {
|
|
29519
|
-
const content = await
|
|
29563
|
+
const content = await readFile7(ckJsonPath, "utf-8");
|
|
29520
29564
|
data = JSON.parse(content);
|
|
29521
29565
|
}
|
|
29522
29566
|
if (!data.kits) {
|
|
@@ -29965,16 +30009,16 @@ var init_merge_engine = __esm(() => {
|
|
|
29965
30009
|
|
|
29966
30010
|
// src/domains/config/merger/file-io.ts
|
|
29967
30011
|
import { randomUUID } from "node:crypto";
|
|
29968
|
-
import { dirname as dirname3, join as
|
|
30012
|
+
import { dirname as dirname3, join as join14 } from "node:path";
|
|
29969
30013
|
function stripBOM(content) {
|
|
29970
30014
|
return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
|
|
29971
30015
|
}
|
|
29972
30016
|
async function readSettingsFile(filePath) {
|
|
29973
30017
|
try {
|
|
29974
|
-
if (!await
|
|
30018
|
+
if (!await import_fs_extra10.pathExists(filePath)) {
|
|
29975
30019
|
return null;
|
|
29976
30020
|
}
|
|
29977
|
-
const rawContent = await
|
|
30021
|
+
const rawContent = await import_fs_extra10.readFile(filePath, "utf-8");
|
|
29978
30022
|
const content = stripBOM(rawContent);
|
|
29979
30023
|
const parsed = JSON.parse(content);
|
|
29980
30024
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
@@ -29989,14 +30033,14 @@ async function readSettingsFile(filePath) {
|
|
|
29989
30033
|
}
|
|
29990
30034
|
async function atomicWriteFile(filePath, content) {
|
|
29991
30035
|
const dir = dirname3(filePath);
|
|
29992
|
-
const tempPath =
|
|
30036
|
+
const tempPath = join14(dir, `.settings-${randomUUID()}.tmp`);
|
|
29993
30037
|
try {
|
|
29994
|
-
await
|
|
29995
|
-
await
|
|
30038
|
+
await import_fs_extra10.writeFile(tempPath, content, "utf-8");
|
|
30039
|
+
await import_fs_extra10.rename(tempPath, filePath);
|
|
29996
30040
|
} catch (error) {
|
|
29997
30041
|
try {
|
|
29998
|
-
if (await
|
|
29999
|
-
await
|
|
30042
|
+
if (await import_fs_extra10.pathExists(tempPath)) {
|
|
30043
|
+
await import_fs_extra10.unlink(tempPath);
|
|
30000
30044
|
}
|
|
30001
30045
|
} catch {}
|
|
30002
30046
|
throw error;
|
|
@@ -30006,10 +30050,10 @@ async function writeSettingsFile(filePath, settings) {
|
|
|
30006
30050
|
const content = JSON.stringify(settings, null, 2);
|
|
30007
30051
|
await atomicWriteFile(filePath, content);
|
|
30008
30052
|
}
|
|
30009
|
-
var
|
|
30053
|
+
var import_fs_extra10;
|
|
30010
30054
|
var init_file_io = __esm(() => {
|
|
30011
30055
|
init_logger();
|
|
30012
|
-
|
|
30056
|
+
import_fs_extra10 = __toESM(require_lib(), 1);
|
|
30013
30057
|
});
|
|
30014
30058
|
|
|
30015
30059
|
// src/domains/config/merger/index.ts
|
|
@@ -30079,7 +30123,7 @@ class SettingsProcessor {
|
|
|
30079
30123
|
}
|
|
30080
30124
|
async processSettingsJson(sourceFile, destFile) {
|
|
30081
30125
|
try {
|
|
30082
|
-
const sourceContent = await
|
|
30126
|
+
const sourceContent = await import_fs_extra11.readFile(sourceFile, "utf-8");
|
|
30083
30127
|
let transformedSource = sourceContent;
|
|
30084
30128
|
if (this.isGlobal) {
|
|
30085
30129
|
const homeVar = '"$HOME"';
|
|
@@ -30093,7 +30137,7 @@ class SettingsProcessor {
|
|
|
30093
30137
|
logger.debug("Transformed paths to $CLAUDE_PROJECT_DIR/.claude/ in settings.json for local installation");
|
|
30094
30138
|
}
|
|
30095
30139
|
}
|
|
30096
|
-
const destExists = await
|
|
30140
|
+
const destExists = await import_fs_extra11.pathExists(destFile);
|
|
30097
30141
|
if (destExists && !this.forceOverwriteSettings) {
|
|
30098
30142
|
await this.selectiveMergeSettings(transformedSource, destFile);
|
|
30099
30143
|
} else {
|
|
@@ -30114,13 +30158,13 @@ class SettingsProcessor {
|
|
|
30114
30158
|
}
|
|
30115
30159
|
} catch {
|
|
30116
30160
|
const formattedContent = this.formatJsonContent(transformedSource);
|
|
30117
|
-
await
|
|
30161
|
+
await import_fs_extra11.writeFile(destFile, formattedContent, "utf-8");
|
|
30118
30162
|
}
|
|
30119
30163
|
await this.injectTeamHooksIfSupported(destFile);
|
|
30120
30164
|
}
|
|
30121
30165
|
} catch (error) {
|
|
30122
30166
|
logger.error(`Failed to process settings.json: ${error}`);
|
|
30123
|
-
await
|
|
30167
|
+
await import_fs_extra11.copy(sourceFile, destFile, { overwrite: true });
|
|
30124
30168
|
}
|
|
30125
30169
|
}
|
|
30126
30170
|
async selectiveMergeSettings(transformedSourceContent, destFile) {
|
|
@@ -30130,7 +30174,7 @@ class SettingsProcessor {
|
|
|
30130
30174
|
} catch {
|
|
30131
30175
|
logger.warning("Failed to parse source settings.json, falling back to overwrite");
|
|
30132
30176
|
const formattedContent = this.formatJsonContent(transformedSourceContent);
|
|
30133
|
-
await
|
|
30177
|
+
await import_fs_extra11.writeFile(destFile, formattedContent, "utf-8");
|
|
30134
30178
|
return;
|
|
30135
30179
|
}
|
|
30136
30180
|
let destSettings;
|
|
@@ -30322,7 +30366,7 @@ class SettingsProcessor {
|
|
|
30322
30366
|
}
|
|
30323
30367
|
async readAndNormalizeGlobalSettings(destFile) {
|
|
30324
30368
|
try {
|
|
30325
|
-
const content = await
|
|
30369
|
+
const content = await import_fs_extra11.readFile(destFile, "utf-8");
|
|
30326
30370
|
if (!content.trim())
|
|
30327
30371
|
return null;
|
|
30328
30372
|
const homeVar = "$HOME";
|
|
@@ -30527,17 +30571,17 @@ class SettingsProcessor {
|
|
|
30527
30571
|
}
|
|
30528
30572
|
}
|
|
30529
30573
|
}
|
|
30530
|
-
var
|
|
30574
|
+
var import_fs_extra11, import_semver2;
|
|
30531
30575
|
var init_settings_processor = __esm(() => {
|
|
30532
30576
|
init_installed_settings_tracker();
|
|
30533
30577
|
init_settings_merger();
|
|
30534
30578
|
init_logger();
|
|
30535
|
-
|
|
30579
|
+
import_fs_extra11 = __toESM(require_lib(), 1);
|
|
30536
30580
|
import_semver2 = __toESM(require_semver2(), 1);
|
|
30537
30581
|
});
|
|
30538
30582
|
|
|
30539
30583
|
// src/domains/installation/merger/copy-executor.ts
|
|
30540
|
-
import { dirname as dirname4, join as
|
|
30584
|
+
import { dirname as dirname4, join as join15, relative as relative4 } from "node:path";
|
|
30541
30585
|
async function withRetry(fn, retries = 3) {
|
|
30542
30586
|
for (let i = 0;i < retries; i++) {
|
|
30543
30587
|
try {
|
|
@@ -30612,8 +30656,8 @@ class CopyExecutor {
|
|
|
30612
30656
|
for (const file of files) {
|
|
30613
30657
|
const relativePath = relative4(sourceDir, file);
|
|
30614
30658
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
30615
|
-
const destPath =
|
|
30616
|
-
if (await
|
|
30659
|
+
const destPath = join15(destDir, relativePath);
|
|
30660
|
+
if (await import_fs_extra12.pathExists(destPath)) {
|
|
30617
30661
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
30618
30662
|
logger.debug(`Security-sensitive file exists but won't be overwritten: ${normalizedRelativePath}`);
|
|
30619
30663
|
continue;
|
|
@@ -30634,14 +30678,14 @@ class CopyExecutor {
|
|
|
30634
30678
|
for (const file of files) {
|
|
30635
30679
|
const relativePath = relative4(sourceDir, file);
|
|
30636
30680
|
const normalizedRelativePath = relativePath.replace(/\\/g, "/");
|
|
30637
|
-
const destPath =
|
|
30681
|
+
const destPath = join15(destDir, relativePath);
|
|
30638
30682
|
if (this.fileScanner.shouldNeverCopy(normalizedRelativePath)) {
|
|
30639
30683
|
logger.debug(`Skipping security-sensitive file: ${normalizedRelativePath}`);
|
|
30640
30684
|
skippedCount++;
|
|
30641
30685
|
continue;
|
|
30642
30686
|
}
|
|
30643
30687
|
if (this.userConfigChecker.ignores(normalizedRelativePath)) {
|
|
30644
|
-
const fileExists = await
|
|
30688
|
+
const fileExists = await import_fs_extra12.pathExists(destPath);
|
|
30645
30689
|
if (fileExists) {
|
|
30646
30690
|
logger.debug(`Preserving user config: ${normalizedRelativePath}`);
|
|
30647
30691
|
skippedCount++;
|
|
@@ -30672,7 +30716,7 @@ class CopyExecutor {
|
|
|
30672
30716
|
continue;
|
|
30673
30717
|
}
|
|
30674
30718
|
}
|
|
30675
|
-
await withRetry(() =>
|
|
30719
|
+
await withRetry(() => import_fs_extra12.copy(file, destPath, { overwrite: true }));
|
|
30676
30720
|
this.trackInstalledFile(normalizedRelativePath);
|
|
30677
30721
|
copiedCount++;
|
|
30678
30722
|
}
|
|
@@ -30718,7 +30762,7 @@ class CopyExecutor {
|
|
|
30718
30762
|
}
|
|
30719
30763
|
}
|
|
30720
30764
|
}
|
|
30721
|
-
var
|
|
30765
|
+
var import_fs_extra12, import_ignore2, isRetryable = (e2) => {
|
|
30722
30766
|
const code = e2.code ?? "";
|
|
30723
30767
|
return ["EBUSY", "EPERM", "EACCES"].includes(code);
|
|
30724
30768
|
}, delay = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
@@ -30728,7 +30772,7 @@ var init_copy_executor = __esm(() => {
|
|
|
30728
30772
|
init_selective_merger();
|
|
30729
30773
|
init_file_scanner();
|
|
30730
30774
|
init_settings_processor();
|
|
30731
|
-
|
|
30775
|
+
import_fs_extra12 = __toESM(require_lib(), 1);
|
|
30732
30776
|
import_ignore2 = __toESM(require_ignore(), 1);
|
|
30733
30777
|
});
|
|
30734
30778
|
|
|
@@ -30826,7 +30870,7 @@ var init_file_merger = __esm(() => {
|
|
|
30826
30870
|
|
|
30827
30871
|
// src/shared/kit-layout.ts
|
|
30828
30872
|
import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
|
|
30829
|
-
import { join as
|
|
30873
|
+
import { join as join16 } from "node:path";
|
|
30830
30874
|
function uniquePaths(paths) {
|
|
30831
30875
|
return [...new Set(paths)];
|
|
30832
30876
|
}
|
|
@@ -30839,7 +30883,7 @@ function findFirstExistingPath(paths) {
|
|
|
30839
30883
|
return null;
|
|
30840
30884
|
}
|
|
30841
30885
|
function resolveKitLayout(projectRoot) {
|
|
30842
|
-
const packageJsonPath =
|
|
30886
|
+
const packageJsonPath = join16(projectRoot, "package.json");
|
|
30843
30887
|
if (!existsSync6(packageJsonPath)) {
|
|
30844
30888
|
return DEFAULT_KIT_LAYOUT;
|
|
30845
30889
|
}
|
|
@@ -30856,8 +30900,8 @@ function resolveKitLayout(projectRoot) {
|
|
|
30856
30900
|
function getProjectLayoutCandidates(projectRoot, subPath) {
|
|
30857
30901
|
const layout = resolveKitLayout(projectRoot);
|
|
30858
30902
|
return uniquePaths([
|
|
30859
|
-
|
|
30860
|
-
|
|
30903
|
+
join16(projectRoot, layout.sourceDir, subPath),
|
|
30904
|
+
join16(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, subPath)
|
|
30861
30905
|
]);
|
|
30862
30906
|
}
|
|
30863
30907
|
function findExistingProjectLayoutPath(projectRoot, subPath) {
|
|
@@ -30866,9 +30910,9 @@ function findExistingProjectLayoutPath(projectRoot, subPath) {
|
|
|
30866
30910
|
function getProjectConfigCandidates(projectRoot) {
|
|
30867
30911
|
const layout = resolveKitLayout(projectRoot);
|
|
30868
30912
|
return uniquePaths([
|
|
30869
|
-
|
|
30870
|
-
|
|
30871
|
-
|
|
30913
|
+
join16(projectRoot, "CLAUDE.md"),
|
|
30914
|
+
join16(projectRoot, layout.sourceDir, "CLAUDE.md"),
|
|
30915
|
+
join16(projectRoot, DEFAULT_KIT_LAYOUT.sourceDir, "CLAUDE.md")
|
|
30872
30916
|
]);
|
|
30873
30917
|
}
|
|
30874
30918
|
function findExistingProjectConfigPath(projectRoot) {
|
|
@@ -34352,21 +34396,21 @@ var require_gray_matter = __commonJS((exports, module) => {
|
|
|
34352
34396
|
});
|
|
34353
34397
|
|
|
34354
34398
|
// src/domains/installers/shared/skills-discovery.ts
|
|
34355
|
-
import { readFile as
|
|
34399
|
+
import { readFile as readFile10, readdir as readdir3, stat as stat3 } from "node:fs/promises";
|
|
34356
34400
|
import { homedir as homedir5 } from "node:os";
|
|
34357
|
-
import { basename, dirname as dirname5, join as
|
|
34401
|
+
import { basename, dirname as dirname5, join as join17 } from "node:path";
|
|
34358
34402
|
function getSkillSourcePath() {
|
|
34359
|
-
const bundledRoot =
|
|
34403
|
+
const bundledRoot = join17(process.cwd(), "node_modules", "takumi-engineer");
|
|
34360
34404
|
return findFirstExistingPath([
|
|
34361
|
-
|
|
34405
|
+
join17(bundledRoot, "skills"),
|
|
34362
34406
|
...getProjectLayoutCandidates(bundledRoot, "skills"),
|
|
34363
34407
|
...getProjectLayoutCandidates(process.cwd(), "skills"),
|
|
34364
|
-
|
|
34408
|
+
join17(home, ".claude/skills")
|
|
34365
34409
|
]);
|
|
34366
34410
|
}
|
|
34367
34411
|
async function hasSkillMd(dir) {
|
|
34368
34412
|
try {
|
|
34369
|
-
const skillPath =
|
|
34413
|
+
const skillPath = join17(dir, "SKILL.md");
|
|
34370
34414
|
const stats = await stat3(skillPath);
|
|
34371
34415
|
return stats.isFile();
|
|
34372
34416
|
} catch {
|
|
@@ -34375,7 +34419,7 @@ async function hasSkillMd(dir) {
|
|
|
34375
34419
|
}
|
|
34376
34420
|
async function parseSkillMd(skillMdPath) {
|
|
34377
34421
|
try {
|
|
34378
|
-
const content = await
|
|
34422
|
+
const content = await readFile10(skillMdPath, "utf-8");
|
|
34379
34423
|
const { data } = import_gray_matter.default(content);
|
|
34380
34424
|
const skillDir = dirname5(skillMdPath);
|
|
34381
34425
|
const dirName = skillDir.split(/[/\\]/).pop() || "";
|
|
@@ -34423,7 +34467,7 @@ async function readWorkflowSlashNames(workflowsDir) {
|
|
|
34423
34467
|
return names;
|
|
34424
34468
|
}
|
|
34425
34469
|
async function readSiblingWorkflowNames(skillsDir) {
|
|
34426
|
-
return readWorkflowSlashNames(
|
|
34470
|
+
return readWorkflowSlashNames(join17(dirname5(skillsDir), "workflows"));
|
|
34427
34471
|
}
|
|
34428
34472
|
async function discoverSkills(sourcePath) {
|
|
34429
34473
|
const skills = [];
|
|
@@ -34443,9 +34487,9 @@ async function discoverSkills(sourcePath) {
|
|
|
34443
34487
|
logger.verbose(`Skipping skill "${entry.name}": shadowed by workflow with the same name`);
|
|
34444
34488
|
continue;
|
|
34445
34489
|
}
|
|
34446
|
-
const skillDir =
|
|
34490
|
+
const skillDir = join17(searchPath, entry.name);
|
|
34447
34491
|
if (await hasSkillMd(skillDir)) {
|
|
34448
|
-
const skill = await parseSkillMd(
|
|
34492
|
+
const skill = await parseSkillMd(join17(skillDir, "SKILL.md"));
|
|
34449
34493
|
if (skill && !seenNames.has(skill.name)) {
|
|
34450
34494
|
skills.push(skill);
|
|
34451
34495
|
seenNames.add(skill.name);
|
|
@@ -34465,43 +34509,6 @@ var init_skills_discovery = __esm(() => {
|
|
|
34465
34509
|
WORKFLOW_ENTRY_EXTENSIONS = [".js", ".mjs", ".cjs"];
|
|
34466
34510
|
});
|
|
34467
34511
|
|
|
34468
|
-
// src/domains/migration/release-manifest.ts
|
|
34469
|
-
import { join as join17 } from "node:path";
|
|
34470
|
-
|
|
34471
|
-
class ReleaseManifestLoader {
|
|
34472
|
-
static async load(extractDir) {
|
|
34473
|
-
const manifestPath = join17(extractDir, "release-manifest.json");
|
|
34474
|
-
try {
|
|
34475
|
-
const content = await import_fs_extra12.readFile(manifestPath, "utf-8");
|
|
34476
|
-
const parsed = JSON.parse(content);
|
|
34477
|
-
return ReleaseManifestSchema.parse(parsed);
|
|
34478
|
-
} catch (error) {
|
|
34479
|
-
logger.debug(`Release manifest not found or invalid: ${error}`);
|
|
34480
|
-
return null;
|
|
34481
|
-
}
|
|
34482
|
-
}
|
|
34483
|
-
static findFile(manifest, relativePath) {
|
|
34484
|
-
return manifest.files.find((f3) => f3.path === relativePath);
|
|
34485
|
-
}
|
|
34486
|
-
}
|
|
34487
|
-
var import_fs_extra12, ReleaseManifestFileSchema, ReleaseManifestSchema;
|
|
34488
|
-
var init_release_manifest = __esm(() => {
|
|
34489
|
-
init_logger();
|
|
34490
|
-
init_zod();
|
|
34491
|
-
import_fs_extra12 = __toESM(require_lib(), 1);
|
|
34492
|
-
ReleaseManifestFileSchema = exports_external.object({
|
|
34493
|
-
path: exports_external.string(),
|
|
34494
|
-
checksum: exports_external.string().regex(/^[a-f0-9]{64}$/),
|
|
34495
|
-
size: exports_external.number(),
|
|
34496
|
-
lastModified: exports_external.string().datetime({ offset: true }).optional()
|
|
34497
|
-
});
|
|
34498
|
-
ReleaseManifestSchema = exports_external.object({
|
|
34499
|
-
version: exports_external.string(),
|
|
34500
|
-
generatedAt: exports_external.string(),
|
|
34501
|
-
files: exports_external.array(ReleaseManifestFileSchema)
|
|
34502
|
-
});
|
|
34503
|
-
});
|
|
34504
|
-
|
|
34505
34512
|
// src/domains/migration/legacy-migration.ts
|
|
34506
34513
|
import { readdir as readdir4, stat as stat4 } from "node:fs/promises";
|
|
34507
34514
|
import { join as join18, relative as relative5 } from "node:path";
|
|
@@ -35362,6 +35369,28 @@ var init_commands_prefix = __esm(() => {
|
|
|
35362
35369
|
};
|
|
35363
35370
|
});
|
|
35364
35371
|
|
|
35372
|
+
// src/domains/installers/claude-code/ownership-resolver.ts
|
|
35373
|
+
function createClaudeOwnershipResolver(releaseManifest) {
|
|
35374
|
+
return (installedPath) => {
|
|
35375
|
+
const providerRelativePath = normalizeClaudeReleaseManifestPath(installedPath);
|
|
35376
|
+
if (providerRelativePath === "settings.json" || userConfigMatcher.ignores(providerRelativePath)) {
|
|
35377
|
+
return { ownership: "user" };
|
|
35378
|
+
}
|
|
35379
|
+
const entry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
35380
|
+
return {
|
|
35381
|
+
ownership: entry ? "takumi" : "user",
|
|
35382
|
+
sourceTimestamp: entry?.lastModified
|
|
35383
|
+
};
|
|
35384
|
+
};
|
|
35385
|
+
}
|
|
35386
|
+
var import_ignore3, userConfigMatcher;
|
|
35387
|
+
var init_ownership_resolver = __esm(() => {
|
|
35388
|
+
init_release_manifest();
|
|
35389
|
+
init_types2();
|
|
35390
|
+
import_ignore3 = __toESM(require_ignore(), 1);
|
|
35391
|
+
userConfigMatcher = import_ignore3.default().add(USER_CONFIG_PATTERNS);
|
|
35392
|
+
});
|
|
35393
|
+
|
|
35365
35394
|
// src/domains/ui/ownership-display.ts
|
|
35366
35395
|
var exports_ownership_display = {};
|
|
35367
35396
|
__export(exports_ownership_display, {
|
|
@@ -35619,13 +35648,7 @@ async function handleMerge(ctx) {
|
|
|
35619
35648
|
logger.debug(`Cleanup of deprecated files failed: ${error}`);
|
|
35620
35649
|
}
|
|
35621
35650
|
const installedFiles = merger.getAllInstalledFiles();
|
|
35622
|
-
const resolver = (
|
|
35623
|
-
const entry = releaseManifest ? ReleaseManifestLoader.findFile(releaseManifest, installedPath) : null;
|
|
35624
|
-
return {
|
|
35625
|
-
ownership: entry ? "takumi" : "user",
|
|
35626
|
-
sourceTimestamp: entry?.lastModified
|
|
35627
|
-
};
|
|
35628
|
-
};
|
|
35651
|
+
const resolver = createClaudeOwnershipResolver(releaseManifest);
|
|
35629
35652
|
const filesToTrack = buildFileTrackingList({
|
|
35630
35653
|
installedFiles,
|
|
35631
35654
|
providerRoot: ctx.claudeDir,
|
|
@@ -35659,6 +35682,7 @@ var init_merge_handler = __esm(() => {
|
|
|
35659
35682
|
init_commands_prefix();
|
|
35660
35683
|
init_logger();
|
|
35661
35684
|
init_output_manager();
|
|
35685
|
+
init_ownership_resolver();
|
|
35662
35686
|
import_fs_extra18 = __toESM(require_lib(), 1);
|
|
35663
35687
|
});
|
|
35664
35688
|
|
|
@@ -52646,7 +52670,7 @@ import { promises as fs13 } from "node:fs";
|
|
|
52646
52670
|
import { basename as basename12, extname as extname5, resolve as resolve16 } from "node:path";
|
|
52647
52671
|
|
|
52648
52672
|
// src/domains/artifact/folder-walk.ts
|
|
52649
|
-
var
|
|
52673
|
+
var import_ignore4 = __toESM(require_ignore(), 1);
|
|
52650
52674
|
import { promises as fs12 } from "node:fs";
|
|
52651
52675
|
import { join as join72, relative as relative14 } from "node:path";
|
|
52652
52676
|
var MAX_FILE_BYTES = 20 * 1024 * 1024;
|
|
@@ -52661,7 +52685,7 @@ class FolderLimitError extends Error {
|
|
|
52661
52685
|
}
|
|
52662
52686
|
}
|
|
52663
52687
|
async function buildIgnoreMatcher(rootDir) {
|
|
52664
|
-
const ig =
|
|
52688
|
+
const ig = import_ignore4.default();
|
|
52665
52689
|
for (const file of IGNORE_FILES) {
|
|
52666
52690
|
try {
|
|
52667
52691
|
ig.add(await fs12.readFile(join72(rootDir, file), "utf8"));
|
|
@@ -69598,7 +69622,7 @@ function detectBroadGlob(pattern, pathHint) {
|
|
|
69598
69622
|
}
|
|
69599
69623
|
|
|
69600
69624
|
// src/domains/hooks/handlers/guard-breadth-scout/check-ignore.ts
|
|
69601
|
-
var
|
|
69625
|
+
var import_ignore5 = __toESM(require_ignore(), 1);
|
|
69602
69626
|
import { existsSync as existsSync45, readFileSync as readFileSync13 } from "node:fs";
|
|
69603
69627
|
import { dirname as dirname24, join as join93 } from "node:path";
|
|
69604
69628
|
var BUILTIN_HEAVY_DIR_LINES = [
|
|
@@ -69659,7 +69683,7 @@ function cleanLines(lines) {
|
|
|
69659
69683
|
}
|
|
69660
69684
|
function buildIgnoreConfig(lines, sourceLabel) {
|
|
69661
69685
|
const cleaned = cleanLines(lines);
|
|
69662
|
-
const ig =
|
|
69686
|
+
const ig = import_ignore5.default().add(cleaned);
|
|
69663
69687
|
const patterns = cleaned.filter((line) => !line.startsWith("!"));
|
|
69664
69688
|
return { ig, patterns, sourceLabel };
|
|
69665
69689
|
}
|
|
@@ -69699,7 +69723,7 @@ function findMatchingIgnoreRule(candidatePath, config) {
|
|
|
69699
69723
|
let matched = null;
|
|
69700
69724
|
for (const pattern of config.patterns) {
|
|
69701
69725
|
try {
|
|
69702
|
-
if (
|
|
69726
|
+
if (import_ignore5.default().add(pattern).ignores(rel))
|
|
69703
69727
|
matched = pattern;
|
|
69704
69728
|
} catch {}
|
|
69705
69729
|
}
|
|
@@ -77317,7 +77341,7 @@ function registerTempDir(dir) {
|
|
|
77317
77341
|
|
|
77318
77342
|
// src/domains/installation/download-manager.ts
|
|
77319
77343
|
init_types2();
|
|
77320
|
-
var
|
|
77344
|
+
var import_ignore6 = __toESM(require_ignore(), 1);
|
|
77321
77345
|
|
|
77322
77346
|
// src/domains/installation/download/file-downloader.ts
|
|
77323
77347
|
init_logger();
|
|
@@ -81212,11 +81236,11 @@ class DownloadManager {
|
|
|
81212
81236
|
ig;
|
|
81213
81237
|
userExcludePatterns = [];
|
|
81214
81238
|
constructor() {
|
|
81215
|
-
this.ig =
|
|
81239
|
+
this.ig = import_ignore6.default().add(EXCLUDE_PATTERNS);
|
|
81216
81240
|
}
|
|
81217
81241
|
setExcludePatterns(patterns) {
|
|
81218
81242
|
this.userExcludePatterns = patterns;
|
|
81219
|
-
this.ig =
|
|
81243
|
+
this.ig = import_ignore6.default().add([...EXCLUDE_PATTERNS, ...this.userExcludePatterns]);
|
|
81220
81244
|
if (patterns.length > 0) {
|
|
81221
81245
|
logger.info(`Added ${patterns.length} custom exclude pattern(s)`);
|
|
81222
81246
|
patterns.forEach((p2) => logger.debug(` - ${p2}`));
|