@flydocs/cli 0.5.0-beta.6 → 0.5.0-beta.8

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 CHANGED
@@ -15,7 +15,7 @@ var CLI_VERSION, CLI_NAME, PACKAGE_NAME;
15
15
  var init_constants = __esm({
16
16
  "src/lib/constants.ts"() {
17
17
  "use strict";
18
- CLI_VERSION = "0.5.0-beta.6";
18
+ CLI_VERSION = "0.5.0-beta.8";
19
19
  CLI_NAME = "flydocs";
20
20
  PACKAGE_NAME = "@flydocs/cli";
21
21
  }
@@ -148,9 +148,6 @@ function printError(message) {
148
148
  function printInfo(message) {
149
149
  console.log(`${pc2.cyan("\u2139")} ${message}`);
150
150
  }
151
- function printStub(command) {
152
- printWarning(`${pc2.bold(command)} is not yet implemented.`);
153
- }
154
151
  function printBanner(version) {
155
152
  const pink = (t) => pc2.bold(pc2.magenta(t));
156
153
  const purple = (t) => pc2.bold(pc2.cyan(t));
@@ -242,7 +239,6 @@ function extractPreservedValues(config) {
242
239
  issueLabels: config.issueLabels ?? {},
243
240
  statusMapping: config.statusMapping ?? {},
244
241
  detectedStack: config.detectedStack ?? {},
245
- mcp: config.mcp ?? {},
246
242
  skills: config.skills ?? {},
247
243
  designSystem: config.designSystem ?? null,
248
244
  aiLabor: config.aiLabor ?? {}
@@ -275,9 +271,6 @@ async function mergeConfig(templateDir, version, tierFlag, preserved) {
275
271
  if (Object.keys(preserved.detectedStack).length > 0) {
276
272
  config.detectedStack = preserved.detectedStack;
277
273
  }
278
- if (Object.keys(preserved.mcp).length > 0) {
279
- config.mcp = preserved.mcp;
280
- }
281
274
  if (Object.keys(preserved.skills).length > 0) {
282
275
  config.skills = preserved.skills;
283
276
  }
@@ -322,12 +315,6 @@ async function installOwnedSkills(templateDir, targetDir, tier) {
322
315
  await replaceDirectory(src, join4(skillsDir, skill));
323
316
  }
324
317
  }
325
- for (const skill of SUPPORTING_SKILLS) {
326
- const src = join4(templateSkillsDir, skill);
327
- if (await pathExists(src)) {
328
- await replaceDirectory(src, join4(skillsDir, skill));
329
- }
330
- }
331
318
  const readmeSrc = join4(templateSkillsDir, "README.md");
332
319
  if (await pathExists(readmeSrc)) {
333
320
  await copyFile(readmeSrc, join4(skillsDir, "README.md"));
@@ -336,7 +323,7 @@ async function installOwnedSkills(templateDir, targetDir, tier) {
336
323
  async function replaceOwnedSkills(templateDir, targetDir, tier) {
337
324
  const skillsDir = join4(targetDir, ".claude", "skills");
338
325
  const templateSkillsDir = join4(templateDir, ".claude", "skills");
339
- for (const skill of [...OWNED_SKILLS, ...SUPPORTING_SKILLS]) {
326
+ for (const skill of OWNED_SKILLS) {
340
327
  const src = join4(templateSkillsDir, skill);
341
328
  if (await pathExists(src)) {
342
329
  await replaceDirectory(src, join4(skillsDir, skill));
@@ -384,20 +371,18 @@ async function copyCursorRules(targetDir) {
384
371
  await copyFile(mechRule, join4(rulesDir, "flydocs-mechanism.mdc"));
385
372
  }
386
373
  }
387
- for (const skill of PREMIUM_CURSOR_RULES) {
388
- const skillRule = join4(
389
- targetDir,
390
- ".claude",
391
- "skills",
392
- skill,
393
- "cursor-rule.mdc"
394
- );
395
- if (await pathExists(skillRule)) {
396
- await copyFile(skillRule, join4(rulesDir, `${skill}.mdc`));
397
- }
374
+ const context7Rule = join4(
375
+ targetDir,
376
+ ".claude",
377
+ "skills",
378
+ "flydocs-context7",
379
+ "cursor-rule.mdc"
380
+ );
381
+ if (await pathExists(context7Rule)) {
382
+ await copyFile(context7Rule, join4(rulesDir, "flydocs-context7.mdc"));
398
383
  }
399
384
  }
400
- var OWNED_SKILLS, SUPPORTING_SKILLS, MECHANISM_SKILLS, PREMIUM_CURSOR_RULES;
385
+ var OWNED_SKILLS, MECHANISM_SKILLS;
401
386
  var init_skills = __esm({
402
387
  "src/lib/skills.ts"() {
403
388
  "use strict";
@@ -406,24 +391,64 @@ var init_skills = __esm({
406
391
  "flydocs-workflow",
407
392
  "flydocs-figma",
408
393
  "flydocs-estimates",
409
- "flydocs-context-graph"
410
- ];
411
- SUPPORTING_SKILLS = [
412
- "implementation-flow",
413
- "review-workflow",
414
- "spec-templates"
394
+ "flydocs-context-graph",
395
+ "flydocs-context7"
415
396
  ];
416
397
  MECHANISM_SKILLS = {
417
398
  local: "flydocs-local",
418
399
  cloud: "flydocs-cloud"
419
400
  };
420
- PREMIUM_CURSOR_RULES = ["flydocs-figma", "flydocs-estimates"];
421
401
  }
422
402
  });
423
403
 
424
404
  // src/lib/stack.ts
425
405
  import { readFile as readFile3 } from "fs/promises";
426
406
  import { join as join5 } from "path";
407
+ async function parseProjectMdStack(targetDir) {
408
+ const detected = /* @__PURE__ */ new Set();
409
+ const projectMdPath = join5(targetDir, "flydocs", "context", "project.md");
410
+ try {
411
+ const content = await readFile3(projectMdPath, "utf-8");
412
+ const stackMatch = content.match(/## Stack\n([\s\S]*?)(?=\n## |\n---|\z)/);
413
+ if (!stackMatch) return detected;
414
+ const stackSection = stackMatch[1].toLowerCase();
415
+ const keywordMap = {
416
+ "next.js": ["nextjs", "react"],
417
+ nextjs: ["nextjs", "react"],
418
+ react: ["react"],
419
+ vue: ["vue"],
420
+ nuxt: ["nuxt", "vue"],
421
+ angular: ["angular"],
422
+ svelte: ["svelte"],
423
+ sveltekit: ["svelte"],
424
+ expo: ["expo", "react"],
425
+ typescript: ["typescript"],
426
+ tailwind: ["tailwind"],
427
+ convex: ["convex"],
428
+ prisma: ["prisma"],
429
+ postgresql: ["prisma"],
430
+ clerk: ["clerk"],
431
+ python: ["python"],
432
+ django: ["python"],
433
+ flask: ["python"],
434
+ fastapi: ["python"],
435
+ golang: ["go"],
436
+ " go ": ["go"],
437
+ rust: ["rust"],
438
+ vitest: ["vitest"],
439
+ jest: ["jest"]
440
+ };
441
+ for (const [keyword, triggers] of Object.entries(keywordMap)) {
442
+ if (stackSection.includes(keyword)) {
443
+ for (const trigger of triggers) {
444
+ detected.add(trigger);
445
+ }
446
+ }
447
+ }
448
+ } catch {
449
+ }
450
+ return detected;
451
+ }
427
452
  async function detectStack(targetDir) {
428
453
  const detected = /* @__PURE__ */ new Set();
429
454
  const pkgPath = join5(targetDir, "package.json");
@@ -492,6 +517,10 @@ async function detectStack(targetDir) {
492
517
  if (await pathExists(join5(targetDir, "Cargo.toml"))) {
493
518
  detected.add("rust");
494
519
  }
520
+ const projectMdStack = await parseProjectMdStack(targetDir);
521
+ for (const item of projectMdStack) {
522
+ detected.add(item);
523
+ }
495
524
  const raw = Array.from(detected);
496
525
  return {
497
526
  raw,
@@ -530,7 +559,7 @@ var init_stack = __esm({
530
559
  });
531
560
 
532
561
  // src/lib/post-install.ts
533
- import { execSync } from "child_process";
562
+ import { execFileSync } from "child_process";
534
563
  import { join as join6 } from "path";
535
564
  async function runManifestGeneration(targetDir) {
536
565
  const scriptPath = join6(
@@ -541,7 +570,7 @@ async function runManifestGeneration(targetDir) {
541
570
  );
542
571
  if (!await pathExists(scriptPath)) return;
543
572
  try {
544
- execSync(`python3 "${scriptPath}"`, {
573
+ execFileSync("python3", [scriptPath], {
545
574
  cwd: targetDir,
546
575
  stdio: "pipe"
547
576
  });
@@ -561,7 +590,7 @@ async function runContextGraphBuild(targetDir) {
561
590
  );
562
591
  if (!await pathExists(scriptPath)) return;
563
592
  try {
564
- execSync(`python3 "${scriptPath}"`, {
593
+ execFileSync("python3", [scriptPath], {
565
594
  cwd: targetDir,
566
595
  stdio: "pipe"
567
596
  });
@@ -944,6 +973,7 @@ var init_skill_manager = __esm({
944
973
  });
945
974
 
946
975
  // src/lib/community-skills.ts
976
+ import { join as join8 } from "path";
947
977
  import { multiselect, isCancel, cancel } from "@clack/prompts";
948
978
  import pc4 from "picocolors";
949
979
  function suggestSkills(stack) {
@@ -962,7 +992,14 @@ function suggestSkills(stack) {
962
992
  }
963
993
  async function promptCommunitySkills(targetDir, stack, autoYes) {
964
994
  const suggestions = suggestSkills(stack);
965
- if (suggestions.length === 0) {
995
+ const skillsDir = join8(targetDir, ".claude", "skills");
996
+ const filtered = [];
997
+ for (const skill of suggestions) {
998
+ if (!await pathExists(join8(skillsDir, skill.name))) {
999
+ filtered.push(skill);
1000
+ }
1001
+ }
1002
+ if (filtered.length === 0) {
966
1003
  printInfo("No community skills suggested for detected stack.");
967
1004
  console.log(` Browse more at: ${pc4.cyan("https://skills.sh/")}`);
968
1005
  return;
@@ -977,10 +1014,10 @@ async function promptCommunitySkills(targetDir, stack, autoYes) {
977
1014
  console.log();
978
1015
  let selected;
979
1016
  if (autoYes) {
980
- selected = suggestions;
1017
+ selected = filtered;
981
1018
  console.log(" Auto-accepting all (--yes)");
982
1019
  } else {
983
- const options = suggestions.map((s) => ({
1020
+ const options = filtered.map((s) => ({
984
1021
  value: s,
985
1022
  label: s.name,
986
1023
  hint: s.description,
@@ -990,7 +1027,7 @@ async function promptCommunitySkills(targetDir, stack, autoYes) {
990
1027
  message: "Select community skills to install (space to toggle, enter to confirm)",
991
1028
  options,
992
1029
  required: false,
993
- initialValues: suggestions
1030
+ initialValues: filtered
994
1031
  });
995
1032
  if (isCancel(result)) {
996
1033
  cancel("Skipped community skills");
@@ -1026,6 +1063,7 @@ var COMMUNITY_SKILLS_MAP;
1026
1063
  var init_community_skills = __esm({
1027
1064
  "src/lib/community-skills.ts"() {
1028
1065
  "use strict";
1066
+ init_fs_ops();
1029
1067
  init_ui();
1030
1068
  init_skill_manager();
1031
1069
  COMMUNITY_SKILLS_MAP = [
@@ -1115,47 +1153,47 @@ var init_community_skills = __esm({
1115
1153
 
1116
1154
  // src/lib/deprecated.ts
1117
1155
  import { readdir as readdir2, mkdir as mkdir3, rename, rm as rm3 } from "fs/promises";
1118
- import { join as join8 } from "path";
1156
+ import { join as join9 } from "path";
1119
1157
  import { confirm, isCancel as isCancel2 } from "@clack/prompts";
1120
1158
  async function scanDeprecated(targetDir) {
1121
1159
  const found = [];
1122
1160
  for (const item of [...DEPRECATED_DIRS, ...DEPRECATED_FILES]) {
1123
- if (await pathExists(join8(targetDir, item))) {
1161
+ if (await pathExists(join9(targetDir, item))) {
1124
1162
  found.push(item);
1125
1163
  }
1126
1164
  }
1127
1165
  for (const skill of DEPRECATED_SKILLS) {
1128
- const p = join8(targetDir, ".claude", "skills", skill);
1166
+ const p = join9(targetDir, ".claude", "skills", skill);
1129
1167
  if (await pathExists(p)) {
1130
1168
  found.push(`.claude/skills/${skill}`);
1131
1169
  }
1132
1170
  }
1133
1171
  for (const dir of DEPRECATED_RULES_DIR) {
1134
- if (await pathExists(join8(targetDir, dir))) {
1172
+ if (await pathExists(join9(targetDir, dir))) {
1135
1173
  found.push(dir);
1136
1174
  }
1137
1175
  }
1138
1176
  for (const hook of DEPRECATED_HOOKS) {
1139
- const p = join8(targetDir, ".flydocs", "hooks", hook);
1177
+ const p = join9(targetDir, ".flydocs", "hooks", hook);
1140
1178
  if (await pathExists(p)) {
1141
1179
  found.push(`.flydocs/hooks/${hook}`);
1142
1180
  }
1143
1181
  }
1144
1182
  for (const rule of DEPRECATED_CURSOR_RULES) {
1145
- const p = join8(targetDir, ".cursor", "rules", rule);
1183
+ const p = join9(targetDir, ".cursor", "rules", rule);
1146
1184
  if (await pathExists(p)) {
1147
1185
  found.push(`.cursor/rules/${rule}`);
1148
1186
  }
1149
1187
  }
1150
1188
  for (const dir of DEPRECATED_CURSOR_RULE_DIRS) {
1151
- const p = join8(targetDir, ".cursor", "rules", dir);
1189
+ const p = join9(targetDir, ".cursor", "rules", dir);
1152
1190
  if (await pathExists(p)) {
1153
1191
  found.push(`.cursor/rules/${dir}`);
1154
1192
  }
1155
1193
  }
1156
1194
  for (const cmd of DEPRECATED_COMMANDS) {
1157
1195
  for (const prefix of [".cursor/commands", ".claude/commands"]) {
1158
- const p = join8(targetDir, prefix, cmd);
1196
+ const p = join9(targetDir, prefix, cmd);
1159
1197
  if (await pathExists(p)) {
1160
1198
  found.push(`${prefix}/${cmd}`);
1161
1199
  }
@@ -1164,12 +1202,12 @@ async function scanDeprecated(targetDir) {
1164
1202
  return found;
1165
1203
  }
1166
1204
  async function handleLegacyContext(targetDir) {
1167
- const contextDir = join8(targetDir, "flydocs", "context");
1168
- const legacyDir = join8(contextDir, "legacy");
1205
+ const contextDir = join9(targetDir, "flydocs", "context");
1206
+ const legacyDir = join9(contextDir, "legacy");
1169
1207
  const oldFiles = ["overview.md", "stack.md", "standards.md"];
1170
1208
  let hasOld = false;
1171
1209
  for (const f of oldFiles) {
1172
- if (await pathExists(join8(contextDir, f))) {
1210
+ if (await pathExists(join9(contextDir, f))) {
1173
1211
  hasOld = true;
1174
1212
  break;
1175
1213
  }
@@ -1177,9 +1215,9 @@ async function handleLegacyContext(targetDir) {
1177
1215
  if (hasOld) {
1178
1216
  await mkdir3(legacyDir, { recursive: true });
1179
1217
  for (const f of oldFiles) {
1180
- const src = join8(contextDir, f);
1218
+ const src = join9(contextDir, f);
1181
1219
  if (await pathExists(src)) {
1182
- await rename(src, join8(legacyDir, f));
1220
+ await rename(src, join9(legacyDir, f));
1183
1221
  printStatus(`Moved flydocs/context/${f} \u2192 legacy/`);
1184
1222
  }
1185
1223
  }
@@ -1189,7 +1227,7 @@ async function handleLegacyContext(targetDir) {
1189
1227
  }
1190
1228
  }
1191
1229
  async function checkLegacyFolder(targetDir) {
1192
- const legacyDir = join8(targetDir, "flydocs", "context", "legacy");
1230
+ const legacyDir = join9(targetDir, "flydocs", "context", "legacy");
1193
1231
  if (!await pathExists(legacyDir)) return null;
1194
1232
  try {
1195
1233
  const entries = await readdir2(legacyDir);
@@ -1219,7 +1257,7 @@ async function promptCleanup(targetDir, paths) {
1219
1257
  return;
1220
1258
  }
1221
1259
  for (const p of paths) {
1222
- await rm3(join8(targetDir, p), { recursive: true, force: true });
1260
+ await rm3(join9(targetDir, p), { recursive: true, force: true });
1223
1261
  printStatus(`Deleted: ${p}`);
1224
1262
  }
1225
1263
  }
@@ -1230,19 +1268,20 @@ var init_deprecated = __esm({
1230
1268
  init_fs_ops();
1231
1269
  init_ui();
1232
1270
  DEPRECATED_DIRS = [".docflow", "docflow"];
1233
- DEPRECATED_FILES = ["AGENTS.md.bak"];
1271
+ DEPRECATED_FILES = ["AGENTS.md.bak", ".cursor/mcp.json"];
1234
1272
  DEPRECATED_SKILLS = [
1235
1273
  "linear-workflow",
1236
1274
  "session-workflow",
1237
1275
  "ai-labor-estimate",
1238
1276
  "component-workflow",
1239
- "figma-mcp",
1240
- "implementation-flow",
1241
- "review-workflow",
1242
- "spec-templates"
1277
+ "figma-mcp"
1243
1278
  ];
1244
1279
  DEPRECATED_RULES_DIR = [".flydocs/rules"];
1245
- DEPRECATED_HOOKS = ["linear-auto-approve.py", "session-end.py"];
1280
+ DEPRECATED_HOOKS = [
1281
+ "linear-auto-approve.py",
1282
+ "session-end.py",
1283
+ "prefer-scripts.py"
1284
+ ];
1246
1285
  DEPRECATED_CURSOR_RULES = [
1247
1286
  "designer-agent.mdc",
1248
1287
  "docflow-core.mdc",
@@ -1270,9 +1309,9 @@ var init_deprecated = __esm({
1270
1309
 
1271
1310
  // src/lib/gitignore.ts
1272
1311
  import { readFile as readFile5, writeFile as writeFile3, appendFile } from "fs/promises";
1273
- import { join as join9 } from "path";
1312
+ import { join as join10 } from "path";
1274
1313
  async function ensureGitignore(targetDir) {
1275
- const gitignorePath = join9(targetDir, ".gitignore");
1314
+ const gitignorePath = join10(targetDir, ".gitignore");
1276
1315
  if (await pathExists(gitignorePath)) {
1277
1316
  const content = await readFile5(gitignorePath, "utf-8");
1278
1317
  if (!content.includes("# FlyDocs")) {
@@ -1286,7 +1325,7 @@ async function ensureGitignore(targetDir) {
1286
1325
  }
1287
1326
  }
1288
1327
  async function migrateGitignore(targetDir) {
1289
- const gitignorePath = join9(targetDir, ".gitignore");
1328
+ const gitignorePath = join10(targetDir, ".gitignore");
1290
1329
  if (!await pathExists(gitignorePath)) return;
1291
1330
  const content = await readFile5(gitignorePath, "utf-8");
1292
1331
  if (!content.includes("flydocs/context/graph.json")) {
@@ -1370,8 +1409,10 @@ __pycache__/
1370
1409
  // src/lib/version.ts
1371
1410
  import { readFile as readFile6 } from "fs/promises";
1372
1411
  function compareVersions(v1, v2) {
1373
- const parts1 = v1.split(".").map(Number);
1374
- const parts2 = v2.split(".").map(Number);
1412
+ const [core1, pre1] = v1.split("-", 2);
1413
+ const [core2, pre2] = v2.split("-", 2);
1414
+ const parts1 = core1.split(".").map(Number);
1415
+ const parts2 = core2.split(".").map(Number);
1375
1416
  const len = Math.max(parts1.length, parts2.length);
1376
1417
  for (let i = 0; i < len; i++) {
1377
1418
  const a = parts1[i] ?? 0;
@@ -1379,6 +1420,27 @@ function compareVersions(v1, v2) {
1379
1420
  if (a < b) return "older";
1380
1421
  if (a > b) return "newer";
1381
1422
  }
1423
+ if (!pre1 && pre2) return "newer";
1424
+ if (pre1 && !pre2) return "older";
1425
+ if (!pre1 && !pre2) return "equal";
1426
+ const preParts1 = pre1.split(".");
1427
+ const preParts2 = pre2.split(".");
1428
+ const preLen = Math.max(preParts1.length, preParts2.length);
1429
+ for (let i = 0; i < preLen; i++) {
1430
+ const a = preParts1[i];
1431
+ const b = preParts2[i];
1432
+ if (a === void 0) return "older";
1433
+ if (b === void 0) return "newer";
1434
+ const numA = Number(a);
1435
+ const numB = Number(b);
1436
+ if (!Number.isNaN(numA) && !Number.isNaN(numB)) {
1437
+ if (numA < numB) return "older";
1438
+ if (numA > numB) return "newer";
1439
+ continue;
1440
+ }
1441
+ if (a < b) return "older";
1442
+ if (a > b) return "newer";
1443
+ }
1382
1444
  return "equal";
1383
1445
  }
1384
1446
  async function getWhatsNew(changelogPath, fromVersion, toVersion) {
@@ -1391,7 +1453,7 @@ async function getWhatsNew(changelogPath, fromVersion, toVersion) {
1391
1453
  const sections = content.split(/^## \[/m);
1392
1454
  const relevant = [];
1393
1455
  for (const section of sections.slice(1)) {
1394
- const match = section.match(/^([\d.]+)\]/);
1456
+ const match = section.match(/^([\d.]+(?:-[\w.]+)?)\]/);
1395
1457
  if (!match) continue;
1396
1458
  const ver = match[1];
1397
1459
  if (compareVersions(ver, fromVersion) !== "older" && compareVersions(ver, fromVersion) !== "equal" && (compareVersions(ver, toVersion) === "older" || compareVersions(ver, toVersion) === "equal")) {
@@ -1414,7 +1476,7 @@ var init_version = __esm({
1414
1476
 
1415
1477
  // src/lib/update-check.ts
1416
1478
  import { readFile as readFile7, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
1417
- import { join as join10 } from "path";
1479
+ import { join as join11 } from "path";
1418
1480
  import { homedir } from "os";
1419
1481
  import pc5 from "picocolors";
1420
1482
  async function readCache() {
@@ -1431,7 +1493,7 @@ async function readCache() {
1431
1493
  }
1432
1494
  async function writeCache(cache) {
1433
1495
  try {
1434
- await mkdir4(join10(homedir(), ".flydocs"), { recursive: true });
1496
+ await mkdir4(join11(homedir(), ".flydocs"), { recursive: true });
1435
1497
  await writeFile4(CACHE_FILE, JSON.stringify(cache), "utf-8");
1436
1498
  } catch {
1437
1499
  }
@@ -1500,7 +1562,7 @@ var init_update_check = __esm({
1500
1562
  "use strict";
1501
1563
  init_constants();
1502
1564
  init_version();
1503
- CACHE_FILE = join10(homedir(), ".flydocs", "update-check.json");
1565
+ CACHE_FILE = join11(homedir(), ".flydocs", "update-check.json");
1504
1566
  CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
1505
1567
  FETCH_TIMEOUT_MS = 5e3;
1506
1568
  }
@@ -1513,7 +1575,7 @@ __export(install_exports, {
1513
1575
  });
1514
1576
  import { defineCommand } from "citty";
1515
1577
  import { resolve as resolve2 } from "path";
1516
- import { join as join11 } from "path";
1578
+ import { join as join12 } from "path";
1517
1579
  import { confirm as confirm2, select, isCancel as isCancel3, cancel as cancel2 } from "@clack/prompts";
1518
1580
  var install_default;
1519
1581
  var init_install = __esm({
@@ -1591,7 +1653,7 @@ var init_install = __esm({
1591
1653
  }
1592
1654
  tier = args.tier;
1593
1655
  printInfo(`Tier set via flag: ${tier}`);
1594
- } else if (await pathExists(join11(targetDir, ".flydocs", "config.json"))) {
1656
+ } else if (await pathExists(join12(targetDir, ".flydocs", "config.json"))) {
1595
1657
  try {
1596
1658
  const existing = await readConfig(targetDir);
1597
1659
  if (existing.tier) {
@@ -1613,37 +1675,37 @@ var init_install = __esm({
1613
1675
  tier = "local";
1614
1676
  console.log();
1615
1677
  }
1616
- if (!await pathExists(join11(targetDir, ".git"))) {
1678
+ if (!await pathExists(join12(targetDir, ".git"))) {
1617
1679
  printWarning("No git repository detected. Run git init when ready.");
1618
1680
  }
1619
1681
  await ensureDirectories(targetDir, tier);
1620
1682
  console.log("Installing framework files...");
1621
1683
  await replaceDirectory(
1622
- join11(templateDir, ".flydocs", "templates"),
1623
- join11(targetDir, ".flydocs", "templates")
1684
+ join12(templateDir, ".flydocs", "templates"),
1685
+ join12(targetDir, ".flydocs", "templates")
1624
1686
  );
1625
1687
  await replaceDirectory(
1626
- join11(templateDir, ".flydocs", "hooks"),
1627
- join11(targetDir, ".flydocs", "hooks")
1688
+ join12(templateDir, ".flydocs", "hooks"),
1689
+ join12(targetDir, ".flydocs", "hooks")
1628
1690
  );
1629
1691
  await replaceDirectory(
1630
- join11(templateDir, ".flydocs", "scripts"),
1631
- join11(targetDir, ".flydocs", "scripts")
1692
+ join12(templateDir, ".flydocs", "scripts"),
1693
+ join12(targetDir, ".flydocs", "scripts")
1632
1694
  );
1633
1695
  await copyFile(
1634
- join11(templateDir, ".flydocs", "version"),
1635
- join11(targetDir, ".flydocs", "version")
1696
+ join12(templateDir, ".flydocs", "version"),
1697
+ join12(targetDir, ".flydocs", "version")
1636
1698
  );
1637
- const manifestSrc = join11(templateDir, "manifest.json");
1699
+ const manifestSrc = join12(templateDir, "manifest.json");
1638
1700
  if (await pathExists(manifestSrc)) {
1639
- await copyFile(manifestSrc, join11(targetDir, ".flydocs", "manifest.json"));
1701
+ await copyFile(manifestSrc, join12(targetDir, ".flydocs", "manifest.json"));
1640
1702
  }
1641
- const changelogSrc = join11(templateDir, "CHANGELOG.md");
1703
+ const changelogSrc = join12(templateDir, "CHANGELOG.md");
1642
1704
  if (await pathExists(changelogSrc)) {
1643
- await copyFile(changelogSrc, join11(targetDir, ".flydocs", "CHANGELOG.md"));
1705
+ await copyFile(changelogSrc, join12(targetDir, ".flydocs", "CHANGELOG.md"));
1644
1706
  }
1645
1707
  printStatus(".flydocs/templates, hooks, version, manifest, changelog");
1646
- const configPath = join11(targetDir, ".flydocs", "config.json");
1708
+ const configPath = join12(targetDir, ".flydocs", "config.json");
1647
1709
  if (!await pathExists(configPath)) {
1648
1710
  const config = await createFreshConfig(templateDir, version, tier);
1649
1711
  await writeConfig(targetDir, config);
@@ -1669,56 +1731,47 @@ var init_install = __esm({
1669
1731
  printStatus(`Skills installed (tier: ${tier})`);
1670
1732
  console.log();
1671
1733
  console.log("Installing agents and commands...");
1672
- const claudeAgentsSrc = join11(templateDir, ".claude", "agents");
1734
+ const claudeAgentsSrc = join12(templateDir, ".claude", "agents");
1673
1735
  if (await pathExists(claudeAgentsSrc)) {
1674
1736
  await copyDirectoryContents(
1675
1737
  claudeAgentsSrc,
1676
- join11(targetDir, ".claude", "agents")
1738
+ join12(targetDir, ".claude", "agents")
1677
1739
  );
1678
1740
  }
1679
1741
  await copyDirectoryContents(
1680
- join11(templateDir, ".claude", "commands"),
1681
- join11(targetDir, ".claude", "commands")
1742
+ join12(templateDir, ".claude", "commands"),
1743
+ join12(targetDir, ".claude", "commands")
1682
1744
  );
1683
1745
  await copyFile(
1684
- join11(templateDir, ".claude", "CLAUDE.md"),
1685
- join11(targetDir, ".claude", "CLAUDE.md")
1746
+ join12(templateDir, ".claude", "CLAUDE.md"),
1747
+ join12(targetDir, ".claude", "CLAUDE.md")
1686
1748
  );
1687
1749
  await copyFile(
1688
- join11(templateDir, ".claude", "settings.json"),
1689
- join11(targetDir, ".claude", "settings.json")
1750
+ join12(templateDir, ".claude", "settings.json"),
1751
+ join12(targetDir, ".claude", "settings.json")
1690
1752
  );
1691
1753
  printStatus(".claude/ (agents, commands, CLAUDE.md, settings)");
1692
- const cursorAgentsSrc = join11(templateDir, ".cursor", "agents");
1754
+ const cursorAgentsSrc = join12(templateDir, ".cursor", "agents");
1693
1755
  if (await pathExists(cursorAgentsSrc)) {
1694
1756
  await copyDirectoryContents(
1695
1757
  cursorAgentsSrc,
1696
- join11(targetDir, ".cursor", "agents")
1758
+ join12(targetDir, ".cursor", "agents")
1697
1759
  );
1698
1760
  }
1699
1761
  await copyDirectoryContents(
1700
- join11(templateDir, ".claude", "commands"),
1701
- join11(targetDir, ".cursor", "commands")
1762
+ join12(templateDir, ".claude", "commands"),
1763
+ join12(targetDir, ".cursor", "commands")
1702
1764
  );
1703
1765
  await copyFile(
1704
- join11(templateDir, ".cursor", "hooks.json"),
1705
- join11(targetDir, ".cursor", "hooks.json")
1766
+ join12(templateDir, ".cursor", "hooks.json"),
1767
+ join12(targetDir, ".cursor", "hooks.json")
1706
1768
  );
1707
1769
  printStatus(".cursor/ (agents, commands, hooks)");
1708
1770
  await copyCursorRules(targetDir);
1709
1771
  printStatus(".cursor/rules/");
1710
- const mcpResult = await copyFileIfNotExists(
1711
- join11(templateDir, ".cursor", "mcp.json"),
1712
- join11(targetDir, ".cursor", "mcp.json")
1713
- );
1714
- if (mcpResult === "created") {
1715
- printStatus(".cursor/mcp.json (new)");
1716
- } else {
1717
- printWarning(".cursor/mcp.json exists, preserving");
1718
- }
1719
1772
  await copyFile(
1720
- join11(templateDir, "AGENTS.md"),
1721
- join11(targetDir, "AGENTS.md")
1773
+ join12(templateDir, "AGENTS.md"),
1774
+ join12(targetDir, "AGENTS.md")
1722
1775
  );
1723
1776
  printStatus("AGENTS.md");
1724
1777
  await runManifestGeneration(targetDir);
@@ -1727,40 +1780,40 @@ var init_install = __esm({
1727
1780
  console.log("Installing project templates...");
1728
1781
  const userFiles = [
1729
1782
  {
1730
- src: join11(templateDir, "flydocs", "context", "project.md"),
1731
- dest: join11(targetDir, "flydocs", "context", "project.md"),
1783
+ src: join12(templateDir, "flydocs", "context", "project.md"),
1784
+ dest: join12(targetDir, "flydocs", "context", "project.md"),
1732
1785
  label: "flydocs/context/project.md"
1733
1786
  },
1734
1787
  {
1735
- src: join11(templateDir, "flydocs", "knowledge", "INDEX.md"),
1736
- dest: join11(targetDir, "flydocs", "knowledge", "INDEX.md"),
1788
+ src: join12(templateDir, "flydocs", "knowledge", "INDEX.md"),
1789
+ dest: join12(targetDir, "flydocs", "knowledge", "INDEX.md"),
1737
1790
  label: "flydocs/knowledge/INDEX.md"
1738
1791
  },
1739
1792
  {
1740
- src: join11(templateDir, "flydocs", "knowledge", "README.md"),
1741
- dest: join11(targetDir, "flydocs", "knowledge", "README.md"),
1793
+ src: join12(templateDir, "flydocs", "knowledge", "README.md"),
1794
+ dest: join12(targetDir, "flydocs", "knowledge", "README.md"),
1742
1795
  label: "flydocs/knowledge/README.md"
1743
1796
  },
1744
1797
  {
1745
- src: join11(
1798
+ src: join12(
1746
1799
  templateDir,
1747
1800
  "flydocs",
1748
1801
  "knowledge",
1749
1802
  "product",
1750
1803
  "personas.md"
1751
1804
  ),
1752
- dest: join11(targetDir, "flydocs", "knowledge", "product", "personas.md"),
1805
+ dest: join12(targetDir, "flydocs", "knowledge", "product", "personas.md"),
1753
1806
  label: "flydocs/knowledge/product/personas.md"
1754
1807
  },
1755
1808
  {
1756
- src: join11(
1809
+ src: join12(
1757
1810
  templateDir,
1758
1811
  "flydocs",
1759
1812
  "knowledge",
1760
1813
  "product",
1761
1814
  "user-flows.md"
1762
1815
  ),
1763
- dest: join11(
1816
+ dest: join12(
1764
1817
  targetDir,
1765
1818
  "flydocs",
1766
1819
  "knowledge",
@@ -1770,18 +1823,18 @@ var init_install = __esm({
1770
1823
  label: "flydocs/knowledge/product/user-flows.md"
1771
1824
  },
1772
1825
  {
1773
- src: join11(templateDir, "flydocs", "design-system", "README.md"),
1774
- dest: join11(targetDir, "flydocs", "design-system", "README.md"),
1826
+ src: join12(templateDir, "flydocs", "design-system", "README.md"),
1827
+ dest: join12(targetDir, "flydocs", "design-system", "README.md"),
1775
1828
  label: "flydocs/design-system/README.md"
1776
1829
  },
1777
1830
  {
1778
- src: join11(
1831
+ src: join12(
1779
1832
  templateDir,
1780
1833
  "flydocs",
1781
1834
  "design-system",
1782
1835
  "component-patterns.md"
1783
1836
  ),
1784
- dest: join11(
1837
+ dest: join12(
1785
1838
  targetDir,
1786
1839
  "flydocs",
1787
1840
  "design-system",
@@ -1790,13 +1843,13 @@ var init_install = __esm({
1790
1843
  label: "flydocs/design-system/component-patterns.md"
1791
1844
  },
1792
1845
  {
1793
- src: join11(templateDir, "flydocs", "design-system", "token-mapping.md"),
1794
- dest: join11(targetDir, "flydocs", "design-system", "token-mapping.md"),
1846
+ src: join12(templateDir, "flydocs", "design-system", "token-mapping.md"),
1847
+ dest: join12(targetDir, "flydocs", "design-system", "token-mapping.md"),
1795
1848
  label: "flydocs/design-system/token-mapping.md"
1796
1849
  },
1797
1850
  {
1798
- src: join11(templateDir, "flydocs", "README.md"),
1799
- dest: join11(targetDir, "flydocs", "README.md"),
1851
+ src: join12(templateDir, "flydocs", "README.md"),
1852
+ dest: join12(targetDir, "flydocs", "README.md"),
1800
1853
  label: "flydocs/README.md"
1801
1854
  }
1802
1855
  ];
@@ -1810,12 +1863,12 @@ var init_install = __esm({
1810
1863
  }
1811
1864
  }
1812
1865
  }
1813
- const envExampleSrc = join11(templateDir, ".env.example");
1866
+ const envExampleSrc = join12(templateDir, ".env.example");
1814
1867
  if (await pathExists(envExampleSrc)) {
1815
- const hasEnv = await pathExists(join11(targetDir, ".env"));
1816
- const hasEnvExample = await pathExists(join11(targetDir, ".env.example"));
1868
+ const hasEnv = await pathExists(join12(targetDir, ".env"));
1869
+ const hasEnvExample = await pathExists(join12(targetDir, ".env.example"));
1817
1870
  if (!hasEnv && !hasEnvExample) {
1818
- await copyFile(envExampleSrc, join11(targetDir, ".env.example"));
1871
+ await copyFile(envExampleSrc, join12(targetDir, ".env.example"));
1819
1872
  printStatus(".env.example (new)");
1820
1873
  }
1821
1874
  }
@@ -1877,10 +1930,10 @@ var init_install = __esm({
1877
1930
  printCompletionBox("Installation Complete!", nextSteps);
1878
1931
  printBetaCta();
1879
1932
  try {
1880
- const { execSync: execSync4, spawn } = await import("child_process");
1933
+ const { execSync: execSync2, spawn } = await import("child_process");
1881
1934
  const isInstalled = (cmd) => {
1882
1935
  try {
1883
- execSync4(`which ${cmd}`, { stdio: "pipe" });
1936
+ execSync2(`which ${cmd}`, { stdio: "pipe" });
1884
1937
  return true;
1885
1938
  } catch {
1886
1939
  return false;
@@ -1987,7 +2040,7 @@ __export(update_exports, {
1987
2040
  default: () => update_default
1988
2041
  });
1989
2042
  import { defineCommand as defineCommand2 } from "citty";
1990
- import { resolve as resolve3, join as join12 } from "path";
2043
+ import { resolve as resolve3, join as join13 } from "path";
1991
2044
  import { mkdir as mkdir5, cp as cp2, readFile as readFile8, readdir as readdir3, rm as rm4 } from "fs/promises";
1992
2045
  import { select as select2, text, confirm as confirm3, isCancel as isCancel4, cancel as cancel3 } from "@clack/prompts";
1993
2046
  import pc6 from "picocolors";
@@ -2093,9 +2146,9 @@ var init_update = __esm({
2093
2146
  }
2094
2147
  targetDir = resolve3(targetDir);
2095
2148
  process.chdir(targetDir);
2096
- const hasVersion = await pathExists(join12(targetDir, ".flydocs", "version"));
2149
+ const hasVersion = await pathExists(join13(targetDir, ".flydocs", "version"));
2097
2150
  const hasConfig = await pathExists(
2098
- join12(targetDir, ".flydocs", "config.json")
2151
+ join13(targetDir, ".flydocs", "config.json")
2099
2152
  );
2100
2153
  if (!hasVersion && !hasConfig) {
2101
2154
  printError(`Not a FlyDocs project: ${targetDir}`);
@@ -2107,7 +2160,7 @@ var init_update = __esm({
2107
2160
  let currentVersion = "0.1.0";
2108
2161
  if (hasVersion) {
2109
2162
  const vContent = await readFile8(
2110
- join12(targetDir, ".flydocs", "version"),
2163
+ join13(targetDir, ".flydocs", "version"),
2111
2164
  "utf-8"
2112
2165
  );
2113
2166
  currentVersion = vContent.trim();
@@ -2135,7 +2188,7 @@ var init_update = __esm({
2135
2188
  }
2136
2189
  console.log(`Updating: v${currentVersion} \u2192 v${version}`);
2137
2190
  console.log();
2138
- const changelogPath = join12(templateDir, "CHANGELOG.md");
2191
+ const changelogPath = join13(templateDir, "CHANGELOG.md");
2139
2192
  const whatsNew = await getWhatsNew(changelogPath, currentVersion, version);
2140
2193
  if (whatsNew.length > 0) {
2141
2194
  console.log(pc6.cyan("What's new:"));
@@ -2147,23 +2200,23 @@ var init_update = __esm({
2147
2200
  }
2148
2201
  const now = /* @__PURE__ */ new Date();
2149
2202
  const ts = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}-${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}${String(now.getSeconds()).padStart(2, "0")}`;
2150
- const backupDir = join12(targetDir, ".flydocs", `backup-${ts}`);
2203
+ const backupDir = join13(targetDir, ".flydocs", `backup-${ts}`);
2151
2204
  await mkdir5(backupDir, { recursive: true });
2152
2205
  if (hasConfig) {
2153
2206
  await cp2(
2154
- join12(targetDir, ".flydocs", "config.json"),
2155
- join12(backupDir, "config.json")
2207
+ join13(targetDir, ".flydocs", "config.json"),
2208
+ join13(backupDir, "config.json")
2156
2209
  );
2157
2210
  printStatus(`Config backed up to .flydocs/backup-${ts}/`);
2158
2211
  }
2159
2212
  try {
2160
- const flydocsDir = join12(targetDir, ".flydocs");
2213
+ const flydocsDir = join13(targetDir, ".flydocs");
2161
2214
  const entries = await readdir3(flydocsDir);
2162
2215
  const backups = entries.filter((e) => e.startsWith("backup-")).sort();
2163
2216
  if (backups.length > 3) {
2164
2217
  const toRemove = backups.slice(0, backups.length - 3);
2165
2218
  for (const old of toRemove) {
2166
- await rm4(join12(flydocsDir, old), { recursive: true, force: true });
2219
+ await rm4(join13(flydocsDir, old), { recursive: true, force: true });
2167
2220
  }
2168
2221
  }
2169
2222
  } catch {
@@ -2176,7 +2229,6 @@ var init_update = __esm({
2176
2229
  issueLabels: {},
2177
2230
  statusMapping: {},
2178
2231
  detectedStack: {},
2179
- mcp: {},
2180
2232
  skills: {},
2181
2233
  designSystem: null,
2182
2234
  aiLabor: {}
@@ -2201,72 +2253,72 @@ var init_update = __esm({
2201
2253
  }
2202
2254
  console.log("Replacing framework directories...");
2203
2255
  await replaceDirectory(
2204
- join12(templateDir, ".flydocs", "templates"),
2205
- join12(targetDir, ".flydocs", "templates")
2256
+ join13(templateDir, ".flydocs", "templates"),
2257
+ join13(targetDir, ".flydocs", "templates")
2206
2258
  );
2207
2259
  await replaceDirectory(
2208
- join12(templateDir, ".flydocs", "hooks"),
2209
- join12(targetDir, ".flydocs", "hooks")
2260
+ join13(templateDir, ".flydocs", "hooks"),
2261
+ join13(targetDir, ".flydocs", "hooks")
2210
2262
  );
2211
2263
  await replaceDirectory(
2212
- join12(templateDir, ".flydocs", "scripts"),
2213
- join12(targetDir, ".flydocs", "scripts")
2264
+ join13(templateDir, ".flydocs", "scripts"),
2265
+ join13(targetDir, ".flydocs", "scripts")
2214
2266
  );
2215
2267
  printStatus(".flydocs/templates, hooks, scripts");
2216
- const claudeAgentsSrc = join12(templateDir, ".claude", "agents");
2268
+ const claudeAgentsSrc = join13(templateDir, ".claude", "agents");
2217
2269
  if (await pathExists(claudeAgentsSrc)) {
2218
2270
  await copyDirectoryContents(
2219
2271
  claudeAgentsSrc,
2220
- join12(targetDir, ".claude", "agents")
2272
+ join13(targetDir, ".claude", "agents")
2221
2273
  );
2222
2274
  }
2223
2275
  printStatus(".claude/agents");
2224
2276
  await replaceOwnedSkills(templateDir, targetDir, effectiveTier);
2225
2277
  printStatus(`.claude/skills (tier: ${effectiveTier})`);
2226
- const cursorAgentsSrc = join12(templateDir, ".cursor", "agents");
2278
+ const cursorAgentsSrc = join13(templateDir, ".cursor", "agents");
2227
2279
  if (await pathExists(cursorAgentsSrc)) {
2228
2280
  await copyDirectoryContents(
2229
2281
  cursorAgentsSrc,
2230
- join12(targetDir, ".cursor", "agents")
2282
+ join13(targetDir, ".cursor", "agents")
2231
2283
  );
2232
2284
  }
2233
2285
  printStatus(".cursor/agents");
2234
2286
  console.log();
2235
2287
  console.log("Replacing framework files...");
2236
2288
  await copyFile(
2237
- join12(templateDir, ".claude", "CLAUDE.md"),
2238
- join12(targetDir, ".claude", "CLAUDE.md")
2289
+ join13(templateDir, ".claude", "CLAUDE.md"),
2290
+ join13(targetDir, ".claude", "CLAUDE.md")
2239
2291
  );
2240
2292
  await copyFile(
2241
- join12(templateDir, ".claude", "settings.json"),
2242
- join12(targetDir, ".claude", "settings.json")
2293
+ join13(templateDir, ".claude", "settings.json"),
2294
+ join13(targetDir, ".claude", "settings.json")
2243
2295
  );
2244
2296
  printStatus(".claude/CLAUDE.md, settings.json");
2245
2297
  await copyDirectoryContents(
2246
- join12(templateDir, ".claude", "commands"),
2247
- join12(targetDir, ".claude", "commands")
2298
+ join13(templateDir, ".claude", "commands"),
2299
+ join13(targetDir, ".claude", "commands")
2248
2300
  );
2249
2301
  await copyDirectoryContents(
2250
- join12(templateDir, ".claude", "commands"),
2251
- join12(targetDir, ".cursor", "commands")
2302
+ join13(templateDir, ".claude", "commands"),
2303
+ join13(targetDir, ".cursor", "commands")
2252
2304
  );
2253
2305
  printStatus(".claude/commands, .cursor/commands");
2254
- const skillsReadmeSrc = join12(templateDir, ".claude", "skills", "README.md");
2306
+ const skillsReadmeSrc = join13(templateDir, ".claude", "skills", "README.md");
2255
2307
  if (await pathExists(skillsReadmeSrc)) {
2256
2308
  await copyFile(
2257
2309
  skillsReadmeSrc,
2258
- join12(targetDir, ".claude", "skills", "README.md")
2310
+ join13(targetDir, ".claude", "skills", "README.md")
2259
2311
  );
2260
2312
  }
2261
2313
  printStatus(".claude/skills/README.md");
2262
2314
  await copyFile(
2263
- join12(templateDir, ".cursor", "hooks.json"),
2264
- join12(targetDir, ".cursor", "hooks.json")
2315
+ join13(templateDir, ".cursor", "hooks.json"),
2316
+ join13(targetDir, ".cursor", "hooks.json")
2265
2317
  );
2266
2318
  printStatus(".cursor/hooks.json");
2267
2319
  await copyFile(
2268
- join12(templateDir, "AGENTS.md"),
2269
- join12(targetDir, "AGENTS.md")
2320
+ join13(templateDir, "AGENTS.md"),
2321
+ join13(targetDir, "AGENTS.md")
2270
2322
  );
2271
2323
  printStatus("AGENTS.md");
2272
2324
  await runManifestGeneration(targetDir);
@@ -2291,18 +2343,18 @@ var init_update = __esm({
2291
2343
  printWarning("Config merge failed \u2014 config.json preserved as-is");
2292
2344
  }
2293
2345
  await copyFile(
2294
- join12(templateDir, ".flydocs", "version"),
2295
- join12(targetDir, ".flydocs", "version")
2346
+ join13(templateDir, ".flydocs", "version"),
2347
+ join13(targetDir, ".flydocs", "version")
2296
2348
  );
2297
2349
  printStatus(`.flydocs/version \u2192 ${version}`);
2298
- const clSrc = join12(templateDir, "CHANGELOG.md");
2350
+ const clSrc = join13(templateDir, "CHANGELOG.md");
2299
2351
  if (await pathExists(clSrc)) {
2300
- await copyFile(clSrc, join12(targetDir, ".flydocs", "CHANGELOG.md"));
2352
+ await copyFile(clSrc, join13(targetDir, ".flydocs", "CHANGELOG.md"));
2301
2353
  printStatus(".flydocs/CHANGELOG.md");
2302
2354
  }
2303
- const mfSrc = join12(templateDir, "manifest.json");
2355
+ const mfSrc = join13(templateDir, "manifest.json");
2304
2356
  if (await pathExists(mfSrc)) {
2305
- await copyFile(mfSrc, join12(targetDir, ".flydocs", "manifest.json"));
2357
+ await copyFile(mfSrc, join13(targetDir, ".flydocs", "manifest.json"));
2306
2358
  printStatus(".flydocs/manifest.json");
2307
2359
  }
2308
2360
  console.log();
@@ -2356,18 +2408,32 @@ __export(setup_exports, {
2356
2408
  default: () => setup_default
2357
2409
  });
2358
2410
  import { defineCommand as defineCommand3 } from "citty";
2411
+ import pc7 from "picocolors";
2359
2412
  var setup_default;
2360
2413
  var init_setup = __esm({
2361
2414
  "src/commands/setup.ts"() {
2362
2415
  "use strict";
2363
- init_ui();
2364
2416
  setup_default = defineCommand3({
2365
2417
  meta: {
2366
2418
  name: "setup",
2367
2419
  description: "Configure FlyDocs settings for this project"
2368
2420
  },
2369
2421
  run() {
2370
- printStub("flydocs setup");
2422
+ console.log();
2423
+ console.log(` ${pc7.bold("FlyDocs Setup")}`);
2424
+ console.log();
2425
+ console.log(` Setup runs inside your IDE as an interactive AI command.`);
2426
+ console.log();
2427
+ console.log(
2428
+ ` ${pc7.cyan("Claude Code:")} Type ${pc7.bold("/flydocs-setup")} in chat`
2429
+ );
2430
+ console.log(
2431
+ ` ${pc7.cyan("Cursor:")} Type ${pc7.bold("/flydocs-setup")} in chat`
2432
+ );
2433
+ console.log();
2434
+ console.log(` This configures your project context, detects your stack,`);
2435
+ console.log(` and installs community skills tailored to your codebase.`);
2436
+ console.log();
2371
2437
  }
2372
2438
  });
2373
2439
  }
@@ -2379,7 +2445,7 @@ __export(skills_exports, {
2379
2445
  default: () => skills_default
2380
2446
  });
2381
2447
  import { defineCommand as defineCommand4 } from "citty";
2382
- import pc7 from "picocolors";
2448
+ import pc8 from "picocolors";
2383
2449
  var list, search, add, remove, skills_default;
2384
2450
  var init_skills2 = __esm({
2385
2451
  "src/commands/skills.ts"() {
@@ -2401,19 +2467,19 @@ var init_skills2 = __esm({
2401
2467
  console.log(`${total} skill(s) installed:`);
2402
2468
  if (result.platform.length > 0) {
2403
2469
  console.log();
2404
- console.log(pc7.bold("Platform"));
2470
+ console.log(pc8.bold("Platform"));
2405
2471
  for (const skill of result.platform) {
2406
2472
  console.log(
2407
- ` ${skill.name} ${pc7.dim(`(${skill.triggers} triggers)`)}`
2473
+ ` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
2408
2474
  );
2409
2475
  }
2410
2476
  }
2411
2477
  if (result.community.length > 0) {
2412
2478
  console.log();
2413
- console.log(pc7.bold("Community"));
2479
+ console.log(pc8.bold("Community"));
2414
2480
  for (const skill of result.community) {
2415
2481
  console.log(
2416
- ` ${skill.name} ${pc7.dim(`(${skill.triggers} triggers)`)}`
2482
+ ` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
2417
2483
  );
2418
2484
  }
2419
2485
  }
@@ -2436,18 +2502,18 @@ var init_skills2 = __esm({
2436
2502
  const results = await searchCatalog(args.keyword);
2437
2503
  if (results.length === 0) {
2438
2504
  console.log(`No skills found for "${args.keyword}".`);
2439
- console.log(` Browse the catalog at: ${pc7.cyan("https://skills.sh/")}`);
2505
+ console.log(` Browse the catalog at: ${pc8.cyan("https://skills.sh/")}`);
2440
2506
  return;
2441
2507
  }
2442
2508
  console.log();
2443
2509
  console.log(`${results.length} skill(s) matching "${args.keyword}":`);
2444
2510
  console.log();
2445
2511
  for (const skill of results) {
2446
- console.log(` ${pc7.bold(skill.name)}`);
2512
+ console.log(` ${pc8.bold(skill.name)}`);
2447
2513
  console.log(` ${skill.description}`);
2448
- console.log(` ${pc7.dim(skill.repo)}`);
2514
+ console.log(` ${pc8.dim(skill.repo)}`);
2449
2515
  if (skill.tags.length > 0) {
2450
- console.log(` ${pc7.dim(skill.tags.join(", "))}`);
2516
+ console.log(` ${pc8.dim(skill.tags.join(", "))}`);
2451
2517
  }
2452
2518
  console.log();
2453
2519
  }
@@ -2507,10 +2573,9 @@ __export(connect_exports, {
2507
2573
  });
2508
2574
  import { defineCommand as defineCommand5 } from "citty";
2509
2575
  import { text as text2, confirm as confirm4, isCancel as isCancel5, cancel as cancel4 } from "@clack/prompts";
2510
- import pc8 from "picocolors";
2576
+ import pc9 from "picocolors";
2511
2577
  import { readFile as readFile9, writeFile as writeFile5, appendFile as appendFile2 } from "fs/promises";
2512
- import { join as join13 } from "path";
2513
- import { execSync as execSync2 } from "child_process";
2578
+ import { join as join14 } from "path";
2514
2579
  var connect_default;
2515
2580
  var init_connect = __esm({
2516
2581
  "src/commands/connect.ts"() {
@@ -2544,11 +2609,11 @@ var init_connect = __esm({
2544
2609
  },
2545
2610
  async run({ args }) {
2546
2611
  const targetDir = args.path ?? process.cwd();
2547
- const configPath = join13(targetDir, ".flydocs", "config.json");
2612
+ const configPath = join14(targetDir, ".flydocs", "config.json");
2548
2613
  if (!await pathExists(configPath)) {
2549
2614
  printError("Not a FlyDocs project (.flydocs/config.json not found).");
2550
2615
  console.log(
2551
- ` Run ${pc8.cyan("flydocs")} first to install FlyDocs in this project.`
2616
+ ` Run ${pc9.cyan("flydocs")} first to install FlyDocs in this project.`
2552
2617
  );
2553
2618
  process.exit(1);
2554
2619
  }
@@ -2565,10 +2630,10 @@ var init_connect = __esm({
2565
2630
  }
2566
2631
  }
2567
2632
  console.log();
2568
- console.log(` ${pc8.bold("Connect to Linear")}`);
2633
+ console.log(` ${pc9.bold("Connect to Linear")}`);
2569
2634
  console.log();
2570
2635
  console.log(
2571
- ` ${pc8.dim("Get your API key from: Linear \u2192 Settings \u2192 API \u2192 Personal API keys")}`
2636
+ ` ${pc9.dim("Get your API key from: Linear \u2192 Settings \u2192 API \u2192 Personal API keys")}`
2572
2637
  );
2573
2638
  console.log();
2574
2639
  let apiKey = args.key ?? "";
@@ -2591,27 +2656,31 @@ var init_connect = __esm({
2591
2656
  }
2592
2657
  printInfo("Validating API key...");
2593
2658
  try {
2594
- const result = execSync2(
2595
- `python3 -c "
2596
- import urllib.request, json
2597
- req = urllib.request.Request('https://api.linear.app/graphql',
2598
- data=json.dumps({'query': '{ viewer { id name email } }'}).encode(),
2599
- headers={'Authorization': '${apiKey}', 'Content-Type': 'application/json'})
2600
- res = urllib.request.urlopen(req)
2601
- data = json.loads(res.read())
2602
- print(json.dumps(data['data']['viewer']))
2603
- "`,
2604
- { encoding: "utf-8", timeout: 15e3 }
2605
- );
2606
- const viewer = JSON.parse(result.trim());
2607
- printStatus(`Authenticated as ${pc8.bold(viewer.name)} (${viewer.email})`);
2659
+ const response = await fetch("https://api.linear.app/graphql", {
2660
+ method: "POST",
2661
+ headers: {
2662
+ Authorization: apiKey,
2663
+ "Content-Type": "application/json"
2664
+ },
2665
+ body: JSON.stringify({ query: "{ viewer { id name email } }" }),
2666
+ signal: AbortSignal.timeout(15e3)
2667
+ });
2668
+ if (!response.ok) {
2669
+ throw new Error(`HTTP ${response.status}`);
2670
+ }
2671
+ const data = await response.json();
2672
+ if (!data.data?.viewer) {
2673
+ throw new Error("Invalid response");
2674
+ }
2675
+ const viewer = data.data.viewer;
2676
+ printStatus(`Authenticated as ${pc9.bold(viewer.name)} (${viewer.email})`);
2608
2677
  } catch {
2609
2678
  printError("Invalid API key or network error.");
2610
2679
  console.log(` Check your key and try again.`);
2611
2680
  process.exit(1);
2612
2681
  }
2613
- const envPath = join13(targetDir, ".env");
2614
- const envLocalPath = join13(targetDir, ".env.local");
2682
+ const envPath = join14(targetDir, ".env");
2683
+ const envLocalPath = join14(targetDir, ".env.local");
2615
2684
  const targetEnvPath = await pathExists(envLocalPath) ? envLocalPath : envPath;
2616
2685
  if (await pathExists(targetEnvPath)) {
2617
2686
  const envContent = await readFile9(targetEnvPath, "utf-8");
@@ -2631,7 +2700,7 @@ LINEAR_API_KEY=${apiKey}
2631
2700
  `, "utf-8");
2632
2701
  }
2633
2702
  printStatus(
2634
- `API key stored in ${pc8.dim(targetEnvPath === envLocalPath ? ".env.local" : ".env")}`
2703
+ `API key stored in ${pc9.dim(targetEnvPath === envLocalPath ? ".env.local" : ".env")}`
2635
2704
  );
2636
2705
  const wasLocal = config.tier === "local";
2637
2706
  config.tier = "cloud";
@@ -2644,14 +2713,14 @@ LINEAR_API_KEY=${apiKey}
2644
2713
  const templateDir = await resolveTemplatePath(
2645
2714
  args["local-source"] || void 0
2646
2715
  );
2647
- const templateSkillsDir = join13(templateDir, ".claude", "skills");
2648
- const skillsDir = join13(targetDir, ".claude", "skills");
2716
+ const templateSkillsDir = join14(templateDir, ".claude", "skills");
2717
+ const skillsDir = join14(targetDir, ".claude", "skills");
2649
2718
  await replaceDirectory(
2650
- join13(templateSkillsDir, "flydocs-cloud"),
2651
- join13(skillsDir, "flydocs-cloud")
2719
+ join14(templateSkillsDir, "flydocs-cloud"),
2720
+ join14(skillsDir, "flydocs-cloud")
2652
2721
  );
2653
2722
  const { rm: rm5 } = await import("fs/promises");
2654
- const localSkillDir = join13(skillsDir, "flydocs-local");
2723
+ const localSkillDir = join14(skillsDir, "flydocs-local");
2655
2724
  if (await pathExists(localSkillDir)) {
2656
2725
  await rm5(localSkillDir, { recursive: true, force: true });
2657
2726
  }
@@ -2664,14 +2733,14 @@ LINEAR_API_KEY=${apiKey}
2664
2733
  }
2665
2734
  console.log();
2666
2735
  console.log(
2667
- ` ${pc8.bold("Connected!")} Your project now syncs with Linear.`
2736
+ ` ${pc9.bold("Connected!")} Your project now syncs with Linear.`
2668
2737
  );
2669
2738
  console.log();
2670
2739
  console.log(` Next steps:`);
2671
2740
  console.log(
2672
- ` 1. Run ${pc8.cyan("/flydocs-setup")} in your IDE to configure your Linear project`
2741
+ ` 1. Run ${pc9.cyan("/flydocs-setup")} in your IDE to configure your Linear project`
2673
2742
  );
2674
- console.log(` 2. Run ${pc8.cyan("/start-session")} to begin working`);
2743
+ console.log(` 2. Run ${pc9.cyan("/start-session")} to begin working`);
2675
2744
  console.log();
2676
2745
  }
2677
2746
  });
@@ -2684,7 +2753,7 @@ __export(upgrade_exports, {
2684
2753
  default: () => upgrade_default
2685
2754
  });
2686
2755
  import { defineCommand as defineCommand6 } from "citty";
2687
- import pc9 from "picocolors";
2756
+ import pc10 from "picocolors";
2688
2757
  var upgrade_default;
2689
2758
  var init_upgrade = __esm({
2690
2759
  "src/commands/upgrade.ts"() {
@@ -2720,37 +2789,37 @@ var init_upgrade = __esm({
2720
2789
  console.log();
2721
2790
  if (currentTier === "cloud") {
2722
2791
  console.log(
2723
- ` ${pc9.green("\u2713")} You're already on the ${pc9.bold("cloud")} tier.`
2792
+ ` ${pc10.green("\u2713")} You're already on the ${pc10.bold("cloud")} tier.`
2724
2793
  );
2725
2794
  console.log();
2726
2795
  console.log(
2727
2796
  ` Your issues sync with Linear via the cloud mechanism skill.`
2728
2797
  );
2729
2798
  console.log(
2730
- ` Run ${pc9.cyan("flydocs connect")} to update your connection settings.`
2799
+ ` Run ${pc10.cyan("flydocs connect")} to update your connection settings.`
2731
2800
  );
2732
2801
  console.log();
2733
2802
  return;
2734
2803
  }
2735
- console.log(` ${pc9.bold("FlyDocs Cloud Tier")}`);
2804
+ console.log(` ${pc10.bold("FlyDocs Cloud Tier")}`);
2736
2805
  console.log();
2737
- console.log(` You're currently on the ${pc9.yellow("local")} tier.`);
2806
+ console.log(` You're currently on the ${pc10.yellow("local")} tier.`);
2738
2807
  console.log(` Upgrade to cloud for:`);
2739
2808
  console.log();
2740
2809
  console.log(
2741
- ` ${pc9.cyan("\u2192")} Issue sync with Linear (Jira coming soon)`
2810
+ ` ${pc10.cyan("\u2192")} Issue sync with Linear (Jira coming soon)`
2742
2811
  );
2743
- console.log(` ${pc9.cyan("\u2192")} Project milestones and cycle management`);
2744
- console.log(` ${pc9.cyan("\u2192")} Team assignment and priority tracking`);
2745
- console.log(` ${pc9.cyan("\u2192")} Project health updates and dashboards`);
2746
- console.log(` ${pc9.cyan("\u2192")} Cross-project issue linking`);
2812
+ console.log(` ${pc10.cyan("\u2192")} Project milestones and cycle management`);
2813
+ console.log(` ${pc10.cyan("\u2192")} Team assignment and priority tracking`);
2814
+ console.log(` ${pc10.cyan("\u2192")} Project health updates and dashboards`);
2815
+ console.log(` ${pc10.cyan("\u2192")} Cross-project issue linking`);
2747
2816
  console.log();
2748
- console.log(` ${pc9.bold("How to upgrade:")}`);
2817
+ console.log(` ${pc10.bold("How to upgrade:")}`);
2749
2818
  console.log();
2750
- console.log(` 1. Sign up at ${pc9.cyan("https://www.flydocs.ai")}`);
2819
+ console.log(` 1. Sign up at ${pc10.cyan("https://www.flydocs.ai")}`);
2751
2820
  console.log(` 2. Get your Linear API key from Linear \u2192 Settings \u2192 API`);
2752
2821
  console.log(
2753
- ` 3. Run ${pc9.cyan("flydocs connect")} to connect your project`
2822
+ ` 3. Run ${pc10.cyan("flydocs connect")} to connect your project`
2754
2823
  );
2755
2824
  console.log();
2756
2825
  }
@@ -2764,8 +2833,8 @@ __export(self_update_exports, {
2764
2833
  default: () => self_update_default
2765
2834
  });
2766
2835
  import { defineCommand as defineCommand7 } from "citty";
2767
- import { execSync as execSync3 } from "child_process";
2768
- import pc10 from "picocolors";
2836
+ import { execSync } from "child_process";
2837
+ import pc11 from "picocolors";
2769
2838
  var self_update_default;
2770
2839
  var init_self_update = __esm({
2771
2840
  "src/commands/self-update.ts"() {
@@ -2779,10 +2848,10 @@ var init_self_update = __esm({
2779
2848
  },
2780
2849
  async run() {
2781
2850
  console.log();
2782
- console.log(` Updating ${pc10.cyan(PACKAGE_NAME)}...`);
2851
+ console.log(` Updating ${pc11.cyan(PACKAGE_NAME)}...`);
2783
2852
  console.log();
2784
2853
  try {
2785
- execSync3(`npm install -g ${PACKAGE_NAME}@beta`, {
2854
+ execSync(`npm install -g ${PACKAGE_NAME}@beta`, {
2786
2855
  stdio: "inherit",
2787
2856
  timeout: 6e4
2788
2857
  });