@codebyplan/cli 2.0.0 → 2.0.1
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/cli.js +222 -31
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -37,7 +37,7 @@ var VERSION, PACKAGE_NAME;
|
|
|
37
37
|
var init_version = __esm({
|
|
38
38
|
"src/lib/version.ts"() {
|
|
39
39
|
"use strict";
|
|
40
|
-
VERSION = "2.0.
|
|
40
|
+
VERSION = "2.0.1";
|
|
41
41
|
PACKAGE_NAME = "@codebyplan/cli";
|
|
42
42
|
}
|
|
43
43
|
});
|
|
@@ -262,8 +262,14 @@ async function request(method, path, options) {
|
|
|
262
262
|
let code;
|
|
263
263
|
try {
|
|
264
264
|
const body = await res.json();
|
|
265
|
-
if (body.error
|
|
266
|
-
|
|
265
|
+
if (body.error && typeof body.error === "object") {
|
|
266
|
+
const err = body.error;
|
|
267
|
+
if (err.message) message = err.message;
|
|
268
|
+
if (err.code) code = err.code;
|
|
269
|
+
} else if (typeof body.error === "string") {
|
|
270
|
+
message = body.error;
|
|
271
|
+
}
|
|
272
|
+
if (body.code && typeof body.code === "string") code = body.code;
|
|
267
273
|
} catch {
|
|
268
274
|
}
|
|
269
275
|
const apiError = new ApiError(message, res.status, code);
|
|
@@ -727,6 +733,145 @@ var init_confirm = __esm({
|
|
|
727
733
|
}
|
|
728
734
|
});
|
|
729
735
|
|
|
736
|
+
// src/lib/tech-detect.ts
|
|
737
|
+
import { readFile as readFile4, access } from "node:fs/promises";
|
|
738
|
+
import { join as join4 } from "node:path";
|
|
739
|
+
async function fileExists(filePath) {
|
|
740
|
+
try {
|
|
741
|
+
await access(filePath);
|
|
742
|
+
return true;
|
|
743
|
+
} catch {
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
async function detectTechStack(projectPath) {
|
|
748
|
+
const seen = /* @__PURE__ */ new Map();
|
|
749
|
+
try {
|
|
750
|
+
const raw = await readFile4(join4(projectPath, "package.json"), "utf-8");
|
|
751
|
+
const pkg = JSON.parse(raw);
|
|
752
|
+
const allDeps = {
|
|
753
|
+
...pkg.dependencies,
|
|
754
|
+
...pkg.devDependencies
|
|
755
|
+
};
|
|
756
|
+
for (const depName of Object.keys(allDeps)) {
|
|
757
|
+
const rule = PACKAGE_MAP[depName];
|
|
758
|
+
if (rule) {
|
|
759
|
+
const key = rule.name.toLowerCase();
|
|
760
|
+
if (!seen.has(key)) {
|
|
761
|
+
seen.set(key, { name: rule.name, category: rule.category });
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
} catch {
|
|
766
|
+
}
|
|
767
|
+
for (const { file, rule } of CONFIG_FILE_MAP) {
|
|
768
|
+
const key = rule.name.toLowerCase();
|
|
769
|
+
if (!seen.has(key) && await fileExists(join4(projectPath, file))) {
|
|
770
|
+
seen.set(key, { name: rule.name, category: rule.category });
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return Array.from(seen.values()).sort((a, b) => {
|
|
774
|
+
const catCmp = a.category.localeCompare(b.category);
|
|
775
|
+
if (catCmp !== 0) return catCmp;
|
|
776
|
+
return a.name.localeCompare(b.name);
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
function mergeTechStack(remote, detected) {
|
|
780
|
+
const seen = /* @__PURE__ */ new Map();
|
|
781
|
+
for (const entry of remote) {
|
|
782
|
+
seen.set(entry.name.toLowerCase(), entry);
|
|
783
|
+
}
|
|
784
|
+
const added = [];
|
|
785
|
+
for (const entry of detected) {
|
|
786
|
+
const key = entry.name.toLowerCase();
|
|
787
|
+
if (!seen.has(key)) {
|
|
788
|
+
seen.set(key, entry);
|
|
789
|
+
added.push(entry);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
const merged = Array.from(seen.values()).sort((a, b) => {
|
|
793
|
+
const catCmp = a.category.localeCompare(b.category);
|
|
794
|
+
if (catCmp !== 0) return catCmp;
|
|
795
|
+
return a.name.localeCompare(b.name);
|
|
796
|
+
});
|
|
797
|
+
return { merged, added };
|
|
798
|
+
}
|
|
799
|
+
function parseTechStack(raw) {
|
|
800
|
+
if (!Array.isArray(raw)) return [];
|
|
801
|
+
return raw.filter(
|
|
802
|
+
(item) => typeof item === "object" && item !== null && typeof item.name === "string" && typeof item.category === "string"
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
var PACKAGE_MAP, CONFIG_FILE_MAP;
|
|
806
|
+
var init_tech_detect = __esm({
|
|
807
|
+
"src/lib/tech-detect.ts"() {
|
|
808
|
+
"use strict";
|
|
809
|
+
PACKAGE_MAP = {
|
|
810
|
+
// Frameworks
|
|
811
|
+
next: { name: "Next.js", category: "framework" },
|
|
812
|
+
nuxt: { name: "Nuxt", category: "framework" },
|
|
813
|
+
gatsby: { name: "Gatsby", category: "framework" },
|
|
814
|
+
express: { name: "Express", category: "framework" },
|
|
815
|
+
fastify: { name: "Fastify", category: "framework" },
|
|
816
|
+
hono: { name: "Hono", category: "framework" },
|
|
817
|
+
"@remix-run/node": { name: "Remix", category: "framework" },
|
|
818
|
+
svelte: { name: "Svelte", category: "framework" },
|
|
819
|
+
astro: { name: "Astro", category: "framework" },
|
|
820
|
+
"@angular/core": { name: "Angular", category: "framework" },
|
|
821
|
+
// Libraries (UI)
|
|
822
|
+
react: { name: "React", category: "framework" },
|
|
823
|
+
vue: { name: "Vue", category: "framework" },
|
|
824
|
+
"solid-js": { name: "Solid", category: "framework" },
|
|
825
|
+
preact: { name: "Preact", category: "framework" },
|
|
826
|
+
// Languages (detected via devDeps)
|
|
827
|
+
typescript: { name: "TypeScript", category: "language" },
|
|
828
|
+
// Styling
|
|
829
|
+
tailwindcss: { name: "Tailwind CSS", category: "styling" },
|
|
830
|
+
sass: { name: "SCSS", category: "styling" },
|
|
831
|
+
"styled-components": { name: "styled-components", category: "styling" },
|
|
832
|
+
"@emotion/react": { name: "Emotion", category: "styling" },
|
|
833
|
+
// Database
|
|
834
|
+
prisma: { name: "Prisma", category: "database" },
|
|
835
|
+
"@prisma/client": { name: "Prisma", category: "database" },
|
|
836
|
+
"drizzle-orm": { name: "Drizzle", category: "database" },
|
|
837
|
+
"@supabase/supabase-js": { name: "Supabase", category: "database" },
|
|
838
|
+
mongoose: { name: "MongoDB", category: "database" },
|
|
839
|
+
typeorm: { name: "TypeORM", category: "database" },
|
|
840
|
+
knex: { name: "Knex", category: "database" },
|
|
841
|
+
// Testing
|
|
842
|
+
jest: { name: "Jest", category: "testing" },
|
|
843
|
+
vitest: { name: "Vitest", category: "testing" },
|
|
844
|
+
mocha: { name: "Mocha", category: "testing" },
|
|
845
|
+
playwright: { name: "Playwright", category: "testing" },
|
|
846
|
+
"@playwright/test": { name: "Playwright", category: "testing" },
|
|
847
|
+
cypress: { name: "Cypress", category: "testing" },
|
|
848
|
+
// Build tools
|
|
849
|
+
turbo: { name: "Turborepo", category: "build" },
|
|
850
|
+
vite: { name: "Vite", category: "build" },
|
|
851
|
+
webpack: { name: "Webpack", category: "build" },
|
|
852
|
+
esbuild: { name: "esbuild", category: "build" },
|
|
853
|
+
rollup: { name: "Rollup", category: "build" },
|
|
854
|
+
// Tools
|
|
855
|
+
eslint: { name: "ESLint", category: "tool" },
|
|
856
|
+
prettier: { name: "Prettier", category: "tool" },
|
|
857
|
+
"@biomejs/biome": { name: "Biome", category: "tool" }
|
|
858
|
+
};
|
|
859
|
+
CONFIG_FILE_MAP = [
|
|
860
|
+
{ file: "tsconfig.json", rule: { name: "TypeScript", category: "language" } },
|
|
861
|
+
{ file: "next.config.js", rule: { name: "Next.js", category: "framework" } },
|
|
862
|
+
{ file: "next.config.mjs", rule: { name: "Next.js", category: "framework" } },
|
|
863
|
+
{ file: "next.config.ts", rule: { name: "Next.js", category: "framework" } },
|
|
864
|
+
{ file: "tailwind.config.js", rule: { name: "Tailwind CSS", category: "styling" } },
|
|
865
|
+
{ file: "tailwind.config.ts", rule: { name: "Tailwind CSS", category: "styling" } },
|
|
866
|
+
{ file: "turbo.json", rule: { name: "Turborepo", category: "build" } },
|
|
867
|
+
{ file: "docker-compose.yml", rule: { name: "Docker", category: "deployment" } },
|
|
868
|
+
{ file: "docker-compose.yaml", rule: { name: "Docker", category: "deployment" } },
|
|
869
|
+
{ file: "Dockerfile", rule: { name: "Docker", category: "deployment" } },
|
|
870
|
+
{ file: "vercel.json", rule: { name: "Vercel", category: "deployment" } }
|
|
871
|
+
];
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
|
|
730
875
|
// src/cli/pull.ts
|
|
731
876
|
var pull_exports = {};
|
|
732
877
|
__export(pull_exports, {
|
|
@@ -801,6 +946,7 @@ async function runPull() {
|
|
|
801
946
|
if (dryRun) console.log(` Mode: dry-run (no changes will be made)`);
|
|
802
947
|
if (force) console.log(` Mode: force (no confirmation prompt)`);
|
|
803
948
|
console.log();
|
|
949
|
+
const repoRes = await apiGet(`/repos/${repoId}`);
|
|
804
950
|
const result = await executePull({ repoId, projectPath, dryRun, force });
|
|
805
951
|
console.log();
|
|
806
952
|
if (result.created + result.updated + result.deleted === 0) {
|
|
@@ -811,8 +957,29 @@ async function runPull() {
|
|
|
811
957
|
if (dryRun) {
|
|
812
958
|
console.log(" (dry-run \u2014 no changes were made)");
|
|
813
959
|
}
|
|
960
|
+
printTechStack(repoRes.data.tech_stack);
|
|
814
961
|
await printSyncStatus(repoId);
|
|
815
962
|
}
|
|
963
|
+
function printTechStack(techStackRaw) {
|
|
964
|
+
try {
|
|
965
|
+
const entries = parseTechStack(techStackRaw);
|
|
966
|
+
if (entries.length === 0) return;
|
|
967
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
968
|
+
for (const entry of entries) {
|
|
969
|
+
const list = grouped.get(entry.category) ?? [];
|
|
970
|
+
list.push(entry);
|
|
971
|
+
grouped.set(entry.category, list);
|
|
972
|
+
}
|
|
973
|
+
console.log();
|
|
974
|
+
console.log(" Tech stack:");
|
|
975
|
+
for (const [category, items] of grouped) {
|
|
976
|
+
const label = category.charAt(0).toUpperCase() + category.slice(1);
|
|
977
|
+
const names = items.map((e) => e.name).join(", ");
|
|
978
|
+
console.log(` ${label}: ${names}`);
|
|
979
|
+
}
|
|
980
|
+
} catch {
|
|
981
|
+
}
|
|
982
|
+
}
|
|
816
983
|
async function printSyncStatus(currentRepoId) {
|
|
817
984
|
try {
|
|
818
985
|
const statusRes = await apiGet("/sync/status");
|
|
@@ -842,6 +1009,7 @@ var init_pull = __esm({
|
|
|
842
1009
|
init_api();
|
|
843
1010
|
init_sync_engine();
|
|
844
1011
|
init_confirm();
|
|
1012
|
+
init_tech_detect();
|
|
845
1013
|
displayTypeMap = {
|
|
846
1014
|
commands: "command",
|
|
847
1015
|
agents: "agent",
|
|
@@ -854,19 +1022,19 @@ var init_pull = __esm({
|
|
|
854
1022
|
});
|
|
855
1023
|
|
|
856
1024
|
// src/cli/fileMapper.ts
|
|
857
|
-
import { readdir as readdir3, readFile as
|
|
858
|
-
import { join as
|
|
1025
|
+
import { readdir as readdir3, readFile as readFile5 } from "node:fs/promises";
|
|
1026
|
+
import { join as join5, extname } from "node:path";
|
|
859
1027
|
function compositeKey(type, name, category) {
|
|
860
1028
|
return category ? `${type}:${category}/${name}` : `${type}:${name}`;
|
|
861
1029
|
}
|
|
862
1030
|
async function scanLocalFiles(claudeDir) {
|
|
863
1031
|
const result = /* @__PURE__ */ new Map();
|
|
864
|
-
await scanCommands(
|
|
865
|
-
await scanSubfolderType(
|
|
866
|
-
await scanSubfolderType(
|
|
867
|
-
await scanFlatType(
|
|
868
|
-
await scanFlatType(
|
|
869
|
-
await scanTemplates(
|
|
1032
|
+
await scanCommands(join5(claudeDir, "commands", "cbp"), result);
|
|
1033
|
+
await scanSubfolderType(join5(claudeDir, "agents"), "agent", "AGENT.md", result);
|
|
1034
|
+
await scanSubfolderType(join5(claudeDir, "skills"), "skill", "SKILL.md", result);
|
|
1035
|
+
await scanFlatType(join5(claudeDir, "rules"), "rule", ".md", result);
|
|
1036
|
+
await scanFlatType(join5(claudeDir, "hooks"), "hook", ".sh", result);
|
|
1037
|
+
await scanTemplates(join5(claudeDir, "templates"), result);
|
|
870
1038
|
return result;
|
|
871
1039
|
}
|
|
872
1040
|
async function scanCommands(dir, result) {
|
|
@@ -881,10 +1049,10 @@ async function scanCommandsRecursive(baseDir, currentDir, result) {
|
|
|
881
1049
|
}
|
|
882
1050
|
for (const entry of entries) {
|
|
883
1051
|
if (entry.isDirectory()) {
|
|
884
|
-
await scanCommandsRecursive(baseDir,
|
|
1052
|
+
await scanCommandsRecursive(baseDir, join5(currentDir, entry.name), result);
|
|
885
1053
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
886
1054
|
const name = entry.name.slice(0, -3);
|
|
887
|
-
const content = await
|
|
1055
|
+
const content = await readFile5(join5(currentDir, entry.name), "utf-8");
|
|
888
1056
|
const relDir = currentDir.slice(baseDir.length + 1);
|
|
889
1057
|
const category = relDir || null;
|
|
890
1058
|
const key = compositeKey("command", name, category);
|
|
@@ -901,9 +1069,9 @@ async function scanSubfolderType(dir, type, fileName, result) {
|
|
|
901
1069
|
}
|
|
902
1070
|
for (const entry of entries) {
|
|
903
1071
|
if (entry.isDirectory()) {
|
|
904
|
-
const filePath =
|
|
1072
|
+
const filePath = join5(dir, entry.name, fileName);
|
|
905
1073
|
try {
|
|
906
|
-
const content = await
|
|
1074
|
+
const content = await readFile5(filePath, "utf-8");
|
|
907
1075
|
const key = compositeKey(type, entry.name, null);
|
|
908
1076
|
result.set(key, { type, name: entry.name, category: null, content });
|
|
909
1077
|
} catch {
|
|
@@ -921,7 +1089,7 @@ async function scanFlatType(dir, type, ext, result) {
|
|
|
921
1089
|
for (const entry of entries) {
|
|
922
1090
|
if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
923
1091
|
const name = entry.name.slice(0, -ext.length);
|
|
924
|
-
const content = await
|
|
1092
|
+
const content = await readFile5(join5(dir, entry.name), "utf-8");
|
|
925
1093
|
const key = compositeKey(type, name, null);
|
|
926
1094
|
result.set(key, { type, name, category: null, content });
|
|
927
1095
|
}
|
|
@@ -936,7 +1104,7 @@ async function scanTemplates(dir, result) {
|
|
|
936
1104
|
}
|
|
937
1105
|
for (const entry of entries) {
|
|
938
1106
|
if (entry.isFile() && extname(entry.name)) {
|
|
939
|
-
const content = await
|
|
1107
|
+
const content = await readFile5(join5(dir, entry.name), "utf-8");
|
|
940
1108
|
const key = compositeKey("template", entry.name, null);
|
|
941
1109
|
result.set(key, { type: "template", name: entry.name, category: null, content });
|
|
942
1110
|
}
|
|
@@ -1022,7 +1190,7 @@ __export(push_exports, {
|
|
|
1022
1190
|
runPush: () => runPush
|
|
1023
1191
|
});
|
|
1024
1192
|
import { stat as stat2 } from "node:fs/promises";
|
|
1025
|
-
import { join as
|
|
1193
|
+
import { join as join6 } from "node:path";
|
|
1026
1194
|
async function runPush() {
|
|
1027
1195
|
const flags = parseFlags(3);
|
|
1028
1196
|
const dryRun = hasFlag("dry-run", 3);
|
|
@@ -1037,7 +1205,7 @@ async function runPush() {
|
|
|
1037
1205
|
if (dryRun) console.log(` Mode: dry-run (no changes will be made)`);
|
|
1038
1206
|
if (force) console.log(` Mode: force (no conflict prompts)`);
|
|
1039
1207
|
console.log();
|
|
1040
|
-
const claudeDir =
|
|
1208
|
+
const claudeDir = join6(projectPath, ".claude");
|
|
1041
1209
|
try {
|
|
1042
1210
|
await stat2(claudeDir);
|
|
1043
1211
|
} catch {
|
|
@@ -1108,7 +1276,11 @@ async function runPush() {
|
|
|
1108
1276
|
}
|
|
1109
1277
|
}
|
|
1110
1278
|
if (toUpsert.length === 0 && toDelete.length === 0) {
|
|
1111
|
-
|
|
1279
|
+
if (!dryRun) {
|
|
1280
|
+
const repoUpdate2 = { claude_sync_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1281
|
+
await pushTechStack(projectPath, repoRes.data.tech_stack, repoUpdate2);
|
|
1282
|
+
await apiPut(`/repos/${repoId}`, repoUpdate2);
|
|
1283
|
+
}
|
|
1112
1284
|
console.log(" Everything is in sync. Nothing to push.\n");
|
|
1113
1285
|
return;
|
|
1114
1286
|
}
|
|
@@ -1134,10 +1306,28 @@ async function runPush() {
|
|
|
1134
1306
|
})),
|
|
1135
1307
|
delete_keys: toDelete
|
|
1136
1308
|
});
|
|
1137
|
-
|
|
1309
|
+
const repoUpdate = { claude_sync_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1310
|
+
await pushTechStack(projectPath, repoRes.data.tech_stack, repoUpdate);
|
|
1311
|
+
await apiPut(`/repos/${repoId}`, repoUpdate);
|
|
1138
1312
|
console.log(` Done: ${result.data.upserted} upserted, ${result.data.deleted} deleted
|
|
1139
1313
|
`);
|
|
1140
1314
|
}
|
|
1315
|
+
async function pushTechStack(projectPath, remoteTechStack, repoUpdate) {
|
|
1316
|
+
try {
|
|
1317
|
+
const detected = await detectTechStack(projectPath);
|
|
1318
|
+
if (detected.length === 0) return;
|
|
1319
|
+
const remote = parseTechStack(remoteTechStack);
|
|
1320
|
+
const { merged, added } = mergeTechStack(remote, detected);
|
|
1321
|
+
console.log(` Tech stack: ${detected.length} detected${added.length > 0 ? ` (${added.length} new)` : ""}`);
|
|
1322
|
+
for (const entry of added) {
|
|
1323
|
+
console.log(` + ${entry.name} (${entry.category})`);
|
|
1324
|
+
}
|
|
1325
|
+
if (added.length > 0) {
|
|
1326
|
+
repoUpdate.tech_stack = merged;
|
|
1327
|
+
}
|
|
1328
|
+
} catch {
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1141
1331
|
function flattenSyncData(data) {
|
|
1142
1332
|
const result = /* @__PURE__ */ new Map();
|
|
1143
1333
|
const typeMap = {
|
|
@@ -1176,6 +1366,7 @@ var init_push = __esm({
|
|
|
1176
1366
|
init_confirm();
|
|
1177
1367
|
init_api();
|
|
1178
1368
|
init_variables();
|
|
1369
|
+
init_tech_detect();
|
|
1179
1370
|
}
|
|
1180
1371
|
});
|
|
1181
1372
|
|
|
@@ -1187,7 +1378,7 @@ __export(init_exports, {
|
|
|
1187
1378
|
import { createInterface as createInterface4 } from "node:readline/promises";
|
|
1188
1379
|
import { stdin as stdin4, stdout as stdout4 } from "node:process";
|
|
1189
1380
|
import { writeFile as writeFile2, mkdir as mkdir2, chmod as chmod2 } from "node:fs/promises";
|
|
1190
|
-
import { join as
|
|
1381
|
+
import { join as join7, dirname as dirname2 } from "node:path";
|
|
1191
1382
|
async function runInit() {
|
|
1192
1383
|
const flags = parseFlags(3);
|
|
1193
1384
|
const projectPath = flags["path"] ?? process.cwd();
|
|
@@ -1226,7 +1417,7 @@ async function runInit() {
|
|
|
1226
1417
|
if (match) worktreeId = match.id;
|
|
1227
1418
|
} catch {
|
|
1228
1419
|
}
|
|
1229
|
-
const configPath =
|
|
1420
|
+
const configPath = join7(projectPath, ".codebyplan.json");
|
|
1230
1421
|
const configData = { repo_id: repoId };
|
|
1231
1422
|
if (worktreeId) configData.worktree_id = worktreeId;
|
|
1232
1423
|
const configContent = JSON.stringify(configData, null, 2) + "\n";
|
|
@@ -1236,17 +1427,17 @@ async function runInit() {
|
|
|
1236
1427
|
if (seedAnswer === "" || seedAnswer === "y" || seedAnswer === "yes") {
|
|
1237
1428
|
let getFilePath3 = function(typeName, file) {
|
|
1238
1429
|
const cfg = typeConfig2[typeName];
|
|
1239
|
-
const typeDir = typeName === "command" ?
|
|
1430
|
+
const typeDir = typeName === "command" ? join7(claudeDir, cfg.dir, "cbp") : join7(claudeDir, cfg.dir);
|
|
1240
1431
|
if (cfg.subfolder) {
|
|
1241
|
-
return
|
|
1432
|
+
return join7(typeDir, file.name, `${cfg.subfolder}${cfg.ext}`);
|
|
1242
1433
|
}
|
|
1243
1434
|
if (typeName === "command" && file.category) {
|
|
1244
|
-
return
|
|
1435
|
+
return join7(typeDir, file.category, `${file.name}${cfg.ext}`);
|
|
1245
1436
|
}
|
|
1246
1437
|
if (typeName === "template") {
|
|
1247
|
-
return
|
|
1438
|
+
return join7(typeDir, file.name);
|
|
1248
1439
|
}
|
|
1249
|
-
return
|
|
1440
|
+
return join7(typeDir, `${file.name}${cfg.ext}`);
|
|
1250
1441
|
};
|
|
1251
1442
|
var getFilePath2 = getFilePath3;
|
|
1252
1443
|
console.log("\n Fetching default files...");
|
|
@@ -1261,7 +1452,7 @@ async function runInit() {
|
|
|
1261
1452
|
printNextSteps(projectPath);
|
|
1262
1453
|
return;
|
|
1263
1454
|
}
|
|
1264
|
-
const claudeDir =
|
|
1455
|
+
const claudeDir = join7(projectPath, ".claude");
|
|
1265
1456
|
let written = 0;
|
|
1266
1457
|
const typeConfig2 = {
|
|
1267
1458
|
command: { dir: "commands", ext: ".md" },
|
|
@@ -1293,14 +1484,14 @@ async function runInit() {
|
|
|
1293
1484
|
...defaultsData.claude_md ?? []
|
|
1294
1485
|
];
|
|
1295
1486
|
for (const file of specialFiles) {
|
|
1296
|
-
const targetPath =
|
|
1487
|
+
const targetPath = join7(projectPath, "CLAUDE.md");
|
|
1297
1488
|
await mkdir2(dirname2(targetPath), { recursive: true });
|
|
1298
1489
|
await writeFile2(targetPath, file.content, "utf-8");
|
|
1299
1490
|
written++;
|
|
1300
1491
|
}
|
|
1301
1492
|
const settingsFiles = defaultsData.settings ?? [];
|
|
1302
1493
|
for (const file of settingsFiles) {
|
|
1303
|
-
const targetPath =
|
|
1494
|
+
const targetPath = join7(claudeDir, "settings.json");
|
|
1304
1495
|
await mkdir2(dirname2(targetPath), { recursive: true });
|
|
1305
1496
|
await writeFile2(targetPath, file.content, "utf-8");
|
|
1306
1497
|
written++;
|