@flydocs/cli 0.5.0-beta.5 → 0.5.0-beta.7
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 +373 -271
- package/package.json +1 -1
- package/template/.claude/agents/implementation-agent.md +1 -1
- package/template/.claude/agents/research-agent.md +1 -1
- package/template/.claude/commands/flydocs-setup.md +3 -3
- package/template/.claude/commands/flydocs-update.md +3 -4
- package/template/.claude/settings.json +0 -10
- package/template/.claude/skills/README.md +35 -41
- package/template/.cursor/hooks.json +0 -5
- package/template/.env.example +2 -1
- package/template/.flydocs/config.json +3 -8
- package/template/.flydocs/hooks/auto-approve.py +2 -2
- package/template/.flydocs/hooks/post-edit.py +13 -0
- package/template/.flydocs/templates/instructions.md +17 -69
- package/template/.flydocs/version +1 -1
- package/template/flydocs/README.md +36 -55
- package/template/flydocs/design-system/README.md +21 -13
- package/template/manifest.json +4 -17
- package/template/.cursor/mcp.json +0 -16
- package/template/.flydocs/hooks/prefer-scripts.py +0 -89
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.
|
|
18
|
+
CLI_VERSION = "0.5.0-beta.7";
|
|
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
|
|
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,8 @@ 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
|
-
}
|
|
398
|
-
}
|
|
399
374
|
}
|
|
400
|
-
var OWNED_SKILLS,
|
|
375
|
+
var OWNED_SKILLS, MECHANISM_SKILLS;
|
|
401
376
|
var init_skills = __esm({
|
|
402
377
|
"src/lib/skills.ts"() {
|
|
403
378
|
"use strict";
|
|
@@ -408,22 +383,61 @@ var init_skills = __esm({
|
|
|
408
383
|
"flydocs-estimates",
|
|
409
384
|
"flydocs-context-graph"
|
|
410
385
|
];
|
|
411
|
-
SUPPORTING_SKILLS = [
|
|
412
|
-
"implementation-flow",
|
|
413
|
-
"review-workflow",
|
|
414
|
-
"spec-templates"
|
|
415
|
-
];
|
|
416
386
|
MECHANISM_SKILLS = {
|
|
417
387
|
local: "flydocs-local",
|
|
418
388
|
cloud: "flydocs-cloud"
|
|
419
389
|
};
|
|
420
|
-
PREMIUM_CURSOR_RULES = ["flydocs-figma", "flydocs-estimates"];
|
|
421
390
|
}
|
|
422
391
|
});
|
|
423
392
|
|
|
424
393
|
// src/lib/stack.ts
|
|
425
394
|
import { readFile as readFile3 } from "fs/promises";
|
|
426
395
|
import { join as join5 } from "path";
|
|
396
|
+
async function parseProjectMdStack(targetDir) {
|
|
397
|
+
const detected = /* @__PURE__ */ new Set();
|
|
398
|
+
const projectMdPath = join5(targetDir, "flydocs", "context", "project.md");
|
|
399
|
+
try {
|
|
400
|
+
const content = await readFile3(projectMdPath, "utf-8");
|
|
401
|
+
const stackMatch = content.match(/## Stack\n([\s\S]*?)(?=\n## |\n---|\z)/);
|
|
402
|
+
if (!stackMatch) return detected;
|
|
403
|
+
const stackSection = stackMatch[1].toLowerCase();
|
|
404
|
+
const keywordMap = {
|
|
405
|
+
"next.js": ["nextjs", "react"],
|
|
406
|
+
nextjs: ["nextjs", "react"],
|
|
407
|
+
react: ["react"],
|
|
408
|
+
vue: ["vue"],
|
|
409
|
+
nuxt: ["nuxt", "vue"],
|
|
410
|
+
angular: ["angular"],
|
|
411
|
+
svelte: ["svelte"],
|
|
412
|
+
sveltekit: ["svelte"],
|
|
413
|
+
expo: ["expo", "react"],
|
|
414
|
+
typescript: ["typescript"],
|
|
415
|
+
tailwind: ["tailwind"],
|
|
416
|
+
convex: ["convex"],
|
|
417
|
+
prisma: ["prisma"],
|
|
418
|
+
postgresql: ["prisma"],
|
|
419
|
+
clerk: ["clerk"],
|
|
420
|
+
python: ["python"],
|
|
421
|
+
django: ["python"],
|
|
422
|
+
flask: ["python"],
|
|
423
|
+
fastapi: ["python"],
|
|
424
|
+
golang: ["go"],
|
|
425
|
+
" go ": ["go"],
|
|
426
|
+
rust: ["rust"],
|
|
427
|
+
vitest: ["vitest"],
|
|
428
|
+
jest: ["jest"]
|
|
429
|
+
};
|
|
430
|
+
for (const [keyword, triggers] of Object.entries(keywordMap)) {
|
|
431
|
+
if (stackSection.includes(keyword)) {
|
|
432
|
+
for (const trigger of triggers) {
|
|
433
|
+
detected.add(trigger);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
} catch {
|
|
438
|
+
}
|
|
439
|
+
return detected;
|
|
440
|
+
}
|
|
427
441
|
async function detectStack(targetDir) {
|
|
428
442
|
const detected = /* @__PURE__ */ new Set();
|
|
429
443
|
const pkgPath = join5(targetDir, "package.json");
|
|
@@ -492,6 +506,10 @@ async function detectStack(targetDir) {
|
|
|
492
506
|
if (await pathExists(join5(targetDir, "Cargo.toml"))) {
|
|
493
507
|
detected.add("rust");
|
|
494
508
|
}
|
|
509
|
+
const projectMdStack = await parseProjectMdStack(targetDir);
|
|
510
|
+
for (const item of projectMdStack) {
|
|
511
|
+
detected.add(item);
|
|
512
|
+
}
|
|
495
513
|
const raw = Array.from(detected);
|
|
496
514
|
return {
|
|
497
515
|
raw,
|
|
@@ -530,7 +548,7 @@ var init_stack = __esm({
|
|
|
530
548
|
});
|
|
531
549
|
|
|
532
550
|
// src/lib/post-install.ts
|
|
533
|
-
import {
|
|
551
|
+
import { execFileSync } from "child_process";
|
|
534
552
|
import { join as join6 } from "path";
|
|
535
553
|
async function runManifestGeneration(targetDir) {
|
|
536
554
|
const scriptPath = join6(
|
|
@@ -541,7 +559,7 @@ async function runManifestGeneration(targetDir) {
|
|
|
541
559
|
);
|
|
542
560
|
if (!await pathExists(scriptPath)) return;
|
|
543
561
|
try {
|
|
544
|
-
|
|
562
|
+
execFileSync("python3", [scriptPath], {
|
|
545
563
|
cwd: targetDir,
|
|
546
564
|
stdio: "pipe"
|
|
547
565
|
});
|
|
@@ -561,7 +579,7 @@ async function runContextGraphBuild(targetDir) {
|
|
|
561
579
|
);
|
|
562
580
|
if (!await pathExists(scriptPath)) return;
|
|
563
581
|
try {
|
|
564
|
-
|
|
582
|
+
execFileSync("python3", [scriptPath], {
|
|
565
583
|
cwd: targetDir,
|
|
566
584
|
stdio: "pipe"
|
|
567
585
|
});
|
|
@@ -944,6 +962,7 @@ var init_skill_manager = __esm({
|
|
|
944
962
|
});
|
|
945
963
|
|
|
946
964
|
// src/lib/community-skills.ts
|
|
965
|
+
import { join as join8 } from "path";
|
|
947
966
|
import { multiselect, isCancel, cancel } from "@clack/prompts";
|
|
948
967
|
import pc4 from "picocolors";
|
|
949
968
|
function suggestSkills(stack) {
|
|
@@ -962,7 +981,14 @@ function suggestSkills(stack) {
|
|
|
962
981
|
}
|
|
963
982
|
async function promptCommunitySkills(targetDir, stack, autoYes) {
|
|
964
983
|
const suggestions = suggestSkills(stack);
|
|
965
|
-
|
|
984
|
+
const skillsDir = join8(targetDir, ".claude", "skills");
|
|
985
|
+
const filtered = [];
|
|
986
|
+
for (const skill of suggestions) {
|
|
987
|
+
if (!await pathExists(join8(skillsDir, skill.name))) {
|
|
988
|
+
filtered.push(skill);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
if (filtered.length === 0) {
|
|
966
992
|
printInfo("No community skills suggested for detected stack.");
|
|
967
993
|
console.log(` Browse more at: ${pc4.cyan("https://skills.sh/")}`);
|
|
968
994
|
return;
|
|
@@ -977,10 +1003,10 @@ async function promptCommunitySkills(targetDir, stack, autoYes) {
|
|
|
977
1003
|
console.log();
|
|
978
1004
|
let selected;
|
|
979
1005
|
if (autoYes) {
|
|
980
|
-
selected =
|
|
1006
|
+
selected = filtered;
|
|
981
1007
|
console.log(" Auto-accepting all (--yes)");
|
|
982
1008
|
} else {
|
|
983
|
-
const options =
|
|
1009
|
+
const options = filtered.map((s) => ({
|
|
984
1010
|
value: s,
|
|
985
1011
|
label: s.name,
|
|
986
1012
|
hint: s.description,
|
|
@@ -990,7 +1016,7 @@ async function promptCommunitySkills(targetDir, stack, autoYes) {
|
|
|
990
1016
|
message: "Select community skills to install (space to toggle, enter to confirm)",
|
|
991
1017
|
options,
|
|
992
1018
|
required: false,
|
|
993
|
-
initialValues:
|
|
1019
|
+
initialValues: filtered
|
|
994
1020
|
});
|
|
995
1021
|
if (isCancel(result)) {
|
|
996
1022
|
cancel("Skipped community skills");
|
|
@@ -1026,6 +1052,7 @@ var COMMUNITY_SKILLS_MAP;
|
|
|
1026
1052
|
var init_community_skills = __esm({
|
|
1027
1053
|
"src/lib/community-skills.ts"() {
|
|
1028
1054
|
"use strict";
|
|
1055
|
+
init_fs_ops();
|
|
1029
1056
|
init_ui();
|
|
1030
1057
|
init_skill_manager();
|
|
1031
1058
|
COMMUNITY_SKILLS_MAP = [
|
|
@@ -1115,47 +1142,47 @@ var init_community_skills = __esm({
|
|
|
1115
1142
|
|
|
1116
1143
|
// src/lib/deprecated.ts
|
|
1117
1144
|
import { readdir as readdir2, mkdir as mkdir3, rename, rm as rm3 } from "fs/promises";
|
|
1118
|
-
import { join as
|
|
1145
|
+
import { join as join9 } from "path";
|
|
1119
1146
|
import { confirm, isCancel as isCancel2 } from "@clack/prompts";
|
|
1120
1147
|
async function scanDeprecated(targetDir) {
|
|
1121
1148
|
const found = [];
|
|
1122
1149
|
for (const item of [...DEPRECATED_DIRS, ...DEPRECATED_FILES]) {
|
|
1123
|
-
if (await pathExists(
|
|
1150
|
+
if (await pathExists(join9(targetDir, item))) {
|
|
1124
1151
|
found.push(item);
|
|
1125
1152
|
}
|
|
1126
1153
|
}
|
|
1127
1154
|
for (const skill of DEPRECATED_SKILLS) {
|
|
1128
|
-
const p =
|
|
1155
|
+
const p = join9(targetDir, ".claude", "skills", skill);
|
|
1129
1156
|
if (await pathExists(p)) {
|
|
1130
1157
|
found.push(`.claude/skills/${skill}`);
|
|
1131
1158
|
}
|
|
1132
1159
|
}
|
|
1133
1160
|
for (const dir of DEPRECATED_RULES_DIR) {
|
|
1134
|
-
if (await pathExists(
|
|
1161
|
+
if (await pathExists(join9(targetDir, dir))) {
|
|
1135
1162
|
found.push(dir);
|
|
1136
1163
|
}
|
|
1137
1164
|
}
|
|
1138
1165
|
for (const hook of DEPRECATED_HOOKS) {
|
|
1139
|
-
const p =
|
|
1166
|
+
const p = join9(targetDir, ".flydocs", "hooks", hook);
|
|
1140
1167
|
if (await pathExists(p)) {
|
|
1141
1168
|
found.push(`.flydocs/hooks/${hook}`);
|
|
1142
1169
|
}
|
|
1143
1170
|
}
|
|
1144
1171
|
for (const rule of DEPRECATED_CURSOR_RULES) {
|
|
1145
|
-
const p =
|
|
1172
|
+
const p = join9(targetDir, ".cursor", "rules", rule);
|
|
1146
1173
|
if (await pathExists(p)) {
|
|
1147
1174
|
found.push(`.cursor/rules/${rule}`);
|
|
1148
1175
|
}
|
|
1149
1176
|
}
|
|
1150
1177
|
for (const dir of DEPRECATED_CURSOR_RULE_DIRS) {
|
|
1151
|
-
const p =
|
|
1178
|
+
const p = join9(targetDir, ".cursor", "rules", dir);
|
|
1152
1179
|
if (await pathExists(p)) {
|
|
1153
1180
|
found.push(`.cursor/rules/${dir}`);
|
|
1154
1181
|
}
|
|
1155
1182
|
}
|
|
1156
1183
|
for (const cmd of DEPRECATED_COMMANDS) {
|
|
1157
1184
|
for (const prefix of [".cursor/commands", ".claude/commands"]) {
|
|
1158
|
-
const p =
|
|
1185
|
+
const p = join9(targetDir, prefix, cmd);
|
|
1159
1186
|
if (await pathExists(p)) {
|
|
1160
1187
|
found.push(`${prefix}/${cmd}`);
|
|
1161
1188
|
}
|
|
@@ -1164,12 +1191,12 @@ async function scanDeprecated(targetDir) {
|
|
|
1164
1191
|
return found;
|
|
1165
1192
|
}
|
|
1166
1193
|
async function handleLegacyContext(targetDir) {
|
|
1167
|
-
const contextDir =
|
|
1168
|
-
const legacyDir =
|
|
1194
|
+
const contextDir = join9(targetDir, "flydocs", "context");
|
|
1195
|
+
const legacyDir = join9(contextDir, "legacy");
|
|
1169
1196
|
const oldFiles = ["overview.md", "stack.md", "standards.md"];
|
|
1170
1197
|
let hasOld = false;
|
|
1171
1198
|
for (const f of oldFiles) {
|
|
1172
|
-
if (await pathExists(
|
|
1199
|
+
if (await pathExists(join9(contextDir, f))) {
|
|
1173
1200
|
hasOld = true;
|
|
1174
1201
|
break;
|
|
1175
1202
|
}
|
|
@@ -1177,9 +1204,9 @@ async function handleLegacyContext(targetDir) {
|
|
|
1177
1204
|
if (hasOld) {
|
|
1178
1205
|
await mkdir3(legacyDir, { recursive: true });
|
|
1179
1206
|
for (const f of oldFiles) {
|
|
1180
|
-
const src =
|
|
1207
|
+
const src = join9(contextDir, f);
|
|
1181
1208
|
if (await pathExists(src)) {
|
|
1182
|
-
await rename(src,
|
|
1209
|
+
await rename(src, join9(legacyDir, f));
|
|
1183
1210
|
printStatus(`Moved flydocs/context/${f} \u2192 legacy/`);
|
|
1184
1211
|
}
|
|
1185
1212
|
}
|
|
@@ -1189,7 +1216,7 @@ async function handleLegacyContext(targetDir) {
|
|
|
1189
1216
|
}
|
|
1190
1217
|
}
|
|
1191
1218
|
async function checkLegacyFolder(targetDir) {
|
|
1192
|
-
const legacyDir =
|
|
1219
|
+
const legacyDir = join9(targetDir, "flydocs", "context", "legacy");
|
|
1193
1220
|
if (!await pathExists(legacyDir)) return null;
|
|
1194
1221
|
try {
|
|
1195
1222
|
const entries = await readdir2(legacyDir);
|
|
@@ -1219,7 +1246,7 @@ async function promptCleanup(targetDir, paths) {
|
|
|
1219
1246
|
return;
|
|
1220
1247
|
}
|
|
1221
1248
|
for (const p of paths) {
|
|
1222
|
-
await rm3(
|
|
1249
|
+
await rm3(join9(targetDir, p), { recursive: true, force: true });
|
|
1223
1250
|
printStatus(`Deleted: ${p}`);
|
|
1224
1251
|
}
|
|
1225
1252
|
}
|
|
@@ -1230,19 +1257,20 @@ var init_deprecated = __esm({
|
|
|
1230
1257
|
init_fs_ops();
|
|
1231
1258
|
init_ui();
|
|
1232
1259
|
DEPRECATED_DIRS = [".docflow", "docflow"];
|
|
1233
|
-
DEPRECATED_FILES = ["AGENTS.md.bak"];
|
|
1260
|
+
DEPRECATED_FILES = ["AGENTS.md.bak", ".cursor/mcp.json"];
|
|
1234
1261
|
DEPRECATED_SKILLS = [
|
|
1235
1262
|
"linear-workflow",
|
|
1236
1263
|
"session-workflow",
|
|
1237
1264
|
"ai-labor-estimate",
|
|
1238
1265
|
"component-workflow",
|
|
1239
|
-
"figma-mcp"
|
|
1240
|
-
"implementation-flow",
|
|
1241
|
-
"review-workflow",
|
|
1242
|
-
"spec-templates"
|
|
1266
|
+
"figma-mcp"
|
|
1243
1267
|
];
|
|
1244
1268
|
DEPRECATED_RULES_DIR = [".flydocs/rules"];
|
|
1245
|
-
DEPRECATED_HOOKS = [
|
|
1269
|
+
DEPRECATED_HOOKS = [
|
|
1270
|
+
"linear-auto-approve.py",
|
|
1271
|
+
"session-end.py",
|
|
1272
|
+
"prefer-scripts.py"
|
|
1273
|
+
];
|
|
1246
1274
|
DEPRECATED_CURSOR_RULES = [
|
|
1247
1275
|
"designer-agent.mdc",
|
|
1248
1276
|
"docflow-core.mdc",
|
|
@@ -1270,9 +1298,9 @@ var init_deprecated = __esm({
|
|
|
1270
1298
|
|
|
1271
1299
|
// src/lib/gitignore.ts
|
|
1272
1300
|
import { readFile as readFile5, writeFile as writeFile3, appendFile } from "fs/promises";
|
|
1273
|
-
import { join as
|
|
1301
|
+
import { join as join10 } from "path";
|
|
1274
1302
|
async function ensureGitignore(targetDir) {
|
|
1275
|
-
const gitignorePath =
|
|
1303
|
+
const gitignorePath = join10(targetDir, ".gitignore");
|
|
1276
1304
|
if (await pathExists(gitignorePath)) {
|
|
1277
1305
|
const content = await readFile5(gitignorePath, "utf-8");
|
|
1278
1306
|
if (!content.includes("# FlyDocs")) {
|
|
@@ -1286,7 +1314,7 @@ async function ensureGitignore(targetDir) {
|
|
|
1286
1314
|
}
|
|
1287
1315
|
}
|
|
1288
1316
|
async function migrateGitignore(targetDir) {
|
|
1289
|
-
const gitignorePath =
|
|
1317
|
+
const gitignorePath = join10(targetDir, ".gitignore");
|
|
1290
1318
|
if (!await pathExists(gitignorePath)) return;
|
|
1291
1319
|
const content = await readFile5(gitignorePath, "utf-8");
|
|
1292
1320
|
if (!content.includes("flydocs/context/graph.json")) {
|
|
@@ -1370,8 +1398,10 @@ __pycache__/
|
|
|
1370
1398
|
// src/lib/version.ts
|
|
1371
1399
|
import { readFile as readFile6 } from "fs/promises";
|
|
1372
1400
|
function compareVersions(v1, v2) {
|
|
1373
|
-
const
|
|
1374
|
-
const
|
|
1401
|
+
const [core1, pre1] = v1.split("-", 2);
|
|
1402
|
+
const [core2, pre2] = v2.split("-", 2);
|
|
1403
|
+
const parts1 = core1.split(".").map(Number);
|
|
1404
|
+
const parts2 = core2.split(".").map(Number);
|
|
1375
1405
|
const len = Math.max(parts1.length, parts2.length);
|
|
1376
1406
|
for (let i = 0; i < len; i++) {
|
|
1377
1407
|
const a = parts1[i] ?? 0;
|
|
@@ -1379,6 +1409,27 @@ function compareVersions(v1, v2) {
|
|
|
1379
1409
|
if (a < b) return "older";
|
|
1380
1410
|
if (a > b) return "newer";
|
|
1381
1411
|
}
|
|
1412
|
+
if (!pre1 && pre2) return "newer";
|
|
1413
|
+
if (pre1 && !pre2) return "older";
|
|
1414
|
+
if (!pre1 && !pre2) return "equal";
|
|
1415
|
+
const preParts1 = pre1.split(".");
|
|
1416
|
+
const preParts2 = pre2.split(".");
|
|
1417
|
+
const preLen = Math.max(preParts1.length, preParts2.length);
|
|
1418
|
+
for (let i = 0; i < preLen; i++) {
|
|
1419
|
+
const a = preParts1[i];
|
|
1420
|
+
const b = preParts2[i];
|
|
1421
|
+
if (a === void 0) return "older";
|
|
1422
|
+
if (b === void 0) return "newer";
|
|
1423
|
+
const numA = Number(a);
|
|
1424
|
+
const numB = Number(b);
|
|
1425
|
+
if (!Number.isNaN(numA) && !Number.isNaN(numB)) {
|
|
1426
|
+
if (numA < numB) return "older";
|
|
1427
|
+
if (numA > numB) return "newer";
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
if (a < b) return "older";
|
|
1431
|
+
if (a > b) return "newer";
|
|
1432
|
+
}
|
|
1382
1433
|
return "equal";
|
|
1383
1434
|
}
|
|
1384
1435
|
async function getWhatsNew(changelogPath, fromVersion, toVersion) {
|
|
@@ -1391,7 +1442,7 @@ async function getWhatsNew(changelogPath, fromVersion, toVersion) {
|
|
|
1391
1442
|
const sections = content.split(/^## \[/m);
|
|
1392
1443
|
const relevant = [];
|
|
1393
1444
|
for (const section of sections.slice(1)) {
|
|
1394
|
-
const match = section.match(/^([\d.]+)\]/);
|
|
1445
|
+
const match = section.match(/^([\d.]+(?:-[\w.]+)?)\]/);
|
|
1395
1446
|
if (!match) continue;
|
|
1396
1447
|
const ver = match[1];
|
|
1397
1448
|
if (compareVersions(ver, fromVersion) !== "older" && compareVersions(ver, fromVersion) !== "equal" && (compareVersions(ver, toVersion) === "older" || compareVersions(ver, toVersion) === "equal")) {
|
|
@@ -1414,7 +1465,7 @@ var init_version = __esm({
|
|
|
1414
1465
|
|
|
1415
1466
|
// src/lib/update-check.ts
|
|
1416
1467
|
import { readFile as readFile7, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
|
|
1417
|
-
import { join as
|
|
1468
|
+
import { join as join11 } from "path";
|
|
1418
1469
|
import { homedir } from "os";
|
|
1419
1470
|
import pc5 from "picocolors";
|
|
1420
1471
|
async function readCache() {
|
|
@@ -1431,7 +1482,7 @@ async function readCache() {
|
|
|
1431
1482
|
}
|
|
1432
1483
|
async function writeCache(cache) {
|
|
1433
1484
|
try {
|
|
1434
|
-
await mkdir4(
|
|
1485
|
+
await mkdir4(join11(homedir(), ".flydocs"), { recursive: true });
|
|
1435
1486
|
await writeFile4(CACHE_FILE, JSON.stringify(cache), "utf-8");
|
|
1436
1487
|
} catch {
|
|
1437
1488
|
}
|
|
@@ -1500,7 +1551,7 @@ var init_update_check = __esm({
|
|
|
1500
1551
|
"use strict";
|
|
1501
1552
|
init_constants();
|
|
1502
1553
|
init_version();
|
|
1503
|
-
CACHE_FILE =
|
|
1554
|
+
CACHE_FILE = join11(homedir(), ".flydocs", "update-check.json");
|
|
1504
1555
|
CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
1505
1556
|
FETCH_TIMEOUT_MS = 5e3;
|
|
1506
1557
|
}
|
|
@@ -1513,8 +1564,8 @@ __export(install_exports, {
|
|
|
1513
1564
|
});
|
|
1514
1565
|
import { defineCommand } from "citty";
|
|
1515
1566
|
import { resolve as resolve2 } from "path";
|
|
1516
|
-
import { join as
|
|
1517
|
-
import { confirm as confirm2, isCancel as isCancel3, cancel as cancel2 } from "@clack/prompts";
|
|
1567
|
+
import { join as join12 } from "path";
|
|
1568
|
+
import { confirm as confirm2, select, isCancel as isCancel3, cancel as cancel2 } from "@clack/prompts";
|
|
1518
1569
|
var install_default;
|
|
1519
1570
|
var init_install = __esm({
|
|
1520
1571
|
"src/commands/install.ts"() {
|
|
@@ -1591,7 +1642,7 @@ var init_install = __esm({
|
|
|
1591
1642
|
}
|
|
1592
1643
|
tier = args.tier;
|
|
1593
1644
|
printInfo(`Tier set via flag: ${tier}`);
|
|
1594
|
-
} else if (await pathExists(
|
|
1645
|
+
} else if (await pathExists(join12(targetDir, ".flydocs", "config.json"))) {
|
|
1595
1646
|
try {
|
|
1596
1647
|
const existing = await readConfig(targetDir);
|
|
1597
1648
|
if (existing.tier) {
|
|
@@ -1613,37 +1664,37 @@ var init_install = __esm({
|
|
|
1613
1664
|
tier = "local";
|
|
1614
1665
|
console.log();
|
|
1615
1666
|
}
|
|
1616
|
-
if (!await pathExists(
|
|
1667
|
+
if (!await pathExists(join12(targetDir, ".git"))) {
|
|
1617
1668
|
printWarning("No git repository detected. Run git init when ready.");
|
|
1618
1669
|
}
|
|
1619
1670
|
await ensureDirectories(targetDir, tier);
|
|
1620
1671
|
console.log("Installing framework files...");
|
|
1621
1672
|
await replaceDirectory(
|
|
1622
|
-
|
|
1623
|
-
|
|
1673
|
+
join12(templateDir, ".flydocs", "templates"),
|
|
1674
|
+
join12(targetDir, ".flydocs", "templates")
|
|
1624
1675
|
);
|
|
1625
1676
|
await replaceDirectory(
|
|
1626
|
-
|
|
1627
|
-
|
|
1677
|
+
join12(templateDir, ".flydocs", "hooks"),
|
|
1678
|
+
join12(targetDir, ".flydocs", "hooks")
|
|
1628
1679
|
);
|
|
1629
1680
|
await replaceDirectory(
|
|
1630
|
-
|
|
1631
|
-
|
|
1681
|
+
join12(templateDir, ".flydocs", "scripts"),
|
|
1682
|
+
join12(targetDir, ".flydocs", "scripts")
|
|
1632
1683
|
);
|
|
1633
1684
|
await copyFile(
|
|
1634
|
-
|
|
1635
|
-
|
|
1685
|
+
join12(templateDir, ".flydocs", "version"),
|
|
1686
|
+
join12(targetDir, ".flydocs", "version")
|
|
1636
1687
|
);
|
|
1637
|
-
const manifestSrc =
|
|
1688
|
+
const manifestSrc = join12(templateDir, "manifest.json");
|
|
1638
1689
|
if (await pathExists(manifestSrc)) {
|
|
1639
|
-
await copyFile(manifestSrc,
|
|
1690
|
+
await copyFile(manifestSrc, join12(targetDir, ".flydocs", "manifest.json"));
|
|
1640
1691
|
}
|
|
1641
|
-
const changelogSrc =
|
|
1692
|
+
const changelogSrc = join12(templateDir, "CHANGELOG.md");
|
|
1642
1693
|
if (await pathExists(changelogSrc)) {
|
|
1643
|
-
await copyFile(changelogSrc,
|
|
1694
|
+
await copyFile(changelogSrc, join12(targetDir, ".flydocs", "CHANGELOG.md"));
|
|
1644
1695
|
}
|
|
1645
1696
|
printStatus(".flydocs/templates, hooks, version, manifest, changelog");
|
|
1646
|
-
const configPath =
|
|
1697
|
+
const configPath = join12(targetDir, ".flydocs", "config.json");
|
|
1647
1698
|
if (!await pathExists(configPath)) {
|
|
1648
1699
|
const config = await createFreshConfig(templateDir, version, tier);
|
|
1649
1700
|
await writeConfig(targetDir, config);
|
|
@@ -1669,56 +1720,47 @@ var init_install = __esm({
|
|
|
1669
1720
|
printStatus(`Skills installed (tier: ${tier})`);
|
|
1670
1721
|
console.log();
|
|
1671
1722
|
console.log("Installing agents and commands...");
|
|
1672
|
-
const claudeAgentsSrc =
|
|
1723
|
+
const claudeAgentsSrc = join12(templateDir, ".claude", "agents");
|
|
1673
1724
|
if (await pathExists(claudeAgentsSrc)) {
|
|
1674
1725
|
await copyDirectoryContents(
|
|
1675
1726
|
claudeAgentsSrc,
|
|
1676
|
-
|
|
1727
|
+
join12(targetDir, ".claude", "agents")
|
|
1677
1728
|
);
|
|
1678
1729
|
}
|
|
1679
1730
|
await copyDirectoryContents(
|
|
1680
|
-
|
|
1681
|
-
|
|
1731
|
+
join12(templateDir, ".claude", "commands"),
|
|
1732
|
+
join12(targetDir, ".claude", "commands")
|
|
1682
1733
|
);
|
|
1683
1734
|
await copyFile(
|
|
1684
|
-
|
|
1685
|
-
|
|
1735
|
+
join12(templateDir, ".claude", "CLAUDE.md"),
|
|
1736
|
+
join12(targetDir, ".claude", "CLAUDE.md")
|
|
1686
1737
|
);
|
|
1687
1738
|
await copyFile(
|
|
1688
|
-
|
|
1689
|
-
|
|
1739
|
+
join12(templateDir, ".claude", "settings.json"),
|
|
1740
|
+
join12(targetDir, ".claude", "settings.json")
|
|
1690
1741
|
);
|
|
1691
1742
|
printStatus(".claude/ (agents, commands, CLAUDE.md, settings)");
|
|
1692
|
-
const cursorAgentsSrc =
|
|
1743
|
+
const cursorAgentsSrc = join12(templateDir, ".cursor", "agents");
|
|
1693
1744
|
if (await pathExists(cursorAgentsSrc)) {
|
|
1694
1745
|
await copyDirectoryContents(
|
|
1695
1746
|
cursorAgentsSrc,
|
|
1696
|
-
|
|
1747
|
+
join12(targetDir, ".cursor", "agents")
|
|
1697
1748
|
);
|
|
1698
1749
|
}
|
|
1699
1750
|
await copyDirectoryContents(
|
|
1700
|
-
|
|
1701
|
-
|
|
1751
|
+
join12(templateDir, ".claude", "commands"),
|
|
1752
|
+
join12(targetDir, ".cursor", "commands")
|
|
1702
1753
|
);
|
|
1703
1754
|
await copyFile(
|
|
1704
|
-
|
|
1705
|
-
|
|
1755
|
+
join12(templateDir, ".cursor", "hooks.json"),
|
|
1756
|
+
join12(targetDir, ".cursor", "hooks.json")
|
|
1706
1757
|
);
|
|
1707
1758
|
printStatus(".cursor/ (agents, commands, hooks)");
|
|
1708
1759
|
await copyCursorRules(targetDir);
|
|
1709
1760
|
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
1761
|
await copyFile(
|
|
1720
|
-
|
|
1721
|
-
|
|
1762
|
+
join12(templateDir, "AGENTS.md"),
|
|
1763
|
+
join12(targetDir, "AGENTS.md")
|
|
1722
1764
|
);
|
|
1723
1765
|
printStatus("AGENTS.md");
|
|
1724
1766
|
await runManifestGeneration(targetDir);
|
|
@@ -1727,40 +1769,40 @@ var init_install = __esm({
|
|
|
1727
1769
|
console.log("Installing project templates...");
|
|
1728
1770
|
const userFiles = [
|
|
1729
1771
|
{
|
|
1730
|
-
src:
|
|
1731
|
-
dest:
|
|
1772
|
+
src: join12(templateDir, "flydocs", "context", "project.md"),
|
|
1773
|
+
dest: join12(targetDir, "flydocs", "context", "project.md"),
|
|
1732
1774
|
label: "flydocs/context/project.md"
|
|
1733
1775
|
},
|
|
1734
1776
|
{
|
|
1735
|
-
src:
|
|
1736
|
-
dest:
|
|
1777
|
+
src: join12(templateDir, "flydocs", "knowledge", "INDEX.md"),
|
|
1778
|
+
dest: join12(targetDir, "flydocs", "knowledge", "INDEX.md"),
|
|
1737
1779
|
label: "flydocs/knowledge/INDEX.md"
|
|
1738
1780
|
},
|
|
1739
1781
|
{
|
|
1740
|
-
src:
|
|
1741
|
-
dest:
|
|
1782
|
+
src: join12(templateDir, "flydocs", "knowledge", "README.md"),
|
|
1783
|
+
dest: join12(targetDir, "flydocs", "knowledge", "README.md"),
|
|
1742
1784
|
label: "flydocs/knowledge/README.md"
|
|
1743
1785
|
},
|
|
1744
1786
|
{
|
|
1745
|
-
src:
|
|
1787
|
+
src: join12(
|
|
1746
1788
|
templateDir,
|
|
1747
1789
|
"flydocs",
|
|
1748
1790
|
"knowledge",
|
|
1749
1791
|
"product",
|
|
1750
1792
|
"personas.md"
|
|
1751
1793
|
),
|
|
1752
|
-
dest:
|
|
1794
|
+
dest: join12(targetDir, "flydocs", "knowledge", "product", "personas.md"),
|
|
1753
1795
|
label: "flydocs/knowledge/product/personas.md"
|
|
1754
1796
|
},
|
|
1755
1797
|
{
|
|
1756
|
-
src:
|
|
1798
|
+
src: join12(
|
|
1757
1799
|
templateDir,
|
|
1758
1800
|
"flydocs",
|
|
1759
1801
|
"knowledge",
|
|
1760
1802
|
"product",
|
|
1761
1803
|
"user-flows.md"
|
|
1762
1804
|
),
|
|
1763
|
-
dest:
|
|
1805
|
+
dest: join12(
|
|
1764
1806
|
targetDir,
|
|
1765
1807
|
"flydocs",
|
|
1766
1808
|
"knowledge",
|
|
@@ -1770,18 +1812,18 @@ var init_install = __esm({
|
|
|
1770
1812
|
label: "flydocs/knowledge/product/user-flows.md"
|
|
1771
1813
|
},
|
|
1772
1814
|
{
|
|
1773
|
-
src:
|
|
1774
|
-
dest:
|
|
1815
|
+
src: join12(templateDir, "flydocs", "design-system", "README.md"),
|
|
1816
|
+
dest: join12(targetDir, "flydocs", "design-system", "README.md"),
|
|
1775
1817
|
label: "flydocs/design-system/README.md"
|
|
1776
1818
|
},
|
|
1777
1819
|
{
|
|
1778
|
-
src:
|
|
1820
|
+
src: join12(
|
|
1779
1821
|
templateDir,
|
|
1780
1822
|
"flydocs",
|
|
1781
1823
|
"design-system",
|
|
1782
1824
|
"component-patterns.md"
|
|
1783
1825
|
),
|
|
1784
|
-
dest:
|
|
1826
|
+
dest: join12(
|
|
1785
1827
|
targetDir,
|
|
1786
1828
|
"flydocs",
|
|
1787
1829
|
"design-system",
|
|
@@ -1790,13 +1832,13 @@ var init_install = __esm({
|
|
|
1790
1832
|
label: "flydocs/design-system/component-patterns.md"
|
|
1791
1833
|
},
|
|
1792
1834
|
{
|
|
1793
|
-
src:
|
|
1794
|
-
dest:
|
|
1835
|
+
src: join12(templateDir, "flydocs", "design-system", "token-mapping.md"),
|
|
1836
|
+
dest: join12(targetDir, "flydocs", "design-system", "token-mapping.md"),
|
|
1795
1837
|
label: "flydocs/design-system/token-mapping.md"
|
|
1796
1838
|
},
|
|
1797
1839
|
{
|
|
1798
|
-
src:
|
|
1799
|
-
dest:
|
|
1840
|
+
src: join12(templateDir, "flydocs", "README.md"),
|
|
1841
|
+
dest: join12(targetDir, "flydocs", "README.md"),
|
|
1800
1842
|
label: "flydocs/README.md"
|
|
1801
1843
|
}
|
|
1802
1844
|
];
|
|
@@ -1810,12 +1852,12 @@ var init_install = __esm({
|
|
|
1810
1852
|
}
|
|
1811
1853
|
}
|
|
1812
1854
|
}
|
|
1813
|
-
const envExampleSrc =
|
|
1855
|
+
const envExampleSrc = join12(templateDir, ".env.example");
|
|
1814
1856
|
if (await pathExists(envExampleSrc)) {
|
|
1815
|
-
const hasEnv = await pathExists(
|
|
1816
|
-
const hasEnvExample = await pathExists(
|
|
1857
|
+
const hasEnv = await pathExists(join12(targetDir, ".env"));
|
|
1858
|
+
const hasEnvExample = await pathExists(join12(targetDir, ".env.example"));
|
|
1817
1859
|
if (!hasEnv && !hasEnvExample) {
|
|
1818
|
-
await copyFile(envExampleSrc,
|
|
1860
|
+
await copyFile(envExampleSrc, join12(targetDir, ".env.example"));
|
|
1819
1861
|
printStatus(".env.example (new)");
|
|
1820
1862
|
}
|
|
1821
1863
|
}
|
|
@@ -1877,50 +1919,94 @@ var init_install = __esm({
|
|
|
1877
1919
|
printCompletionBox("Installation Complete!", nextSteps);
|
|
1878
1920
|
printBetaCta();
|
|
1879
1921
|
try {
|
|
1880
|
-
const { execSync:
|
|
1922
|
+
const { execSync: execSync2, spawn } = await import("child_process");
|
|
1881
1923
|
const isInstalled = (cmd) => {
|
|
1882
1924
|
try {
|
|
1883
|
-
|
|
1925
|
+
execSync2(`which ${cmd}`, { stdio: "pipe" });
|
|
1884
1926
|
return true;
|
|
1885
1927
|
} catch {
|
|
1886
1928
|
return false;
|
|
1887
1929
|
}
|
|
1888
1930
|
};
|
|
1889
|
-
const
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1931
|
+
const ideOptions = [];
|
|
1932
|
+
if (isInstalled("claude")) {
|
|
1933
|
+
ideOptions.push({
|
|
1934
|
+
cmd: "claude",
|
|
1935
|
+
label: "Claude Code",
|
|
1936
|
+
hint: "Opens and runs /flydocs-setup automatically",
|
|
1937
|
+
passCommand: true
|
|
1895
1938
|
});
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1939
|
+
}
|
|
1940
|
+
if (isInstalled("cursor")) {
|
|
1941
|
+
ideOptions.push({
|
|
1942
|
+
cmd: "cursor",
|
|
1943
|
+
label: "Cursor",
|
|
1944
|
+
hint: copiedToClipboard ? "Opens project \u2014 paste /flydocs-setup from clipboard" : "Opens project \u2014 run /flydocs-setup in chat",
|
|
1945
|
+
passCommand: false
|
|
1946
|
+
});
|
|
1947
|
+
}
|
|
1948
|
+
if (isInstalled("code")) {
|
|
1949
|
+
ideOptions.push({
|
|
1950
|
+
cmd: "code",
|
|
1951
|
+
label: "VS Code",
|
|
1952
|
+
hint: copiedToClipboard ? "Opens project \u2014 paste /flydocs-setup from clipboard" : "Opens project \u2014 run /flydocs-setup in chat",
|
|
1953
|
+
passCommand: false
|
|
1906
1954
|
});
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1955
|
+
}
|
|
1956
|
+
if (ideOptions.length === 1) {
|
|
1957
|
+
const ide = ideOptions[0];
|
|
1958
|
+
const launchConfirm = await confirm2({
|
|
1959
|
+
message: ide.passCommand ? `Open ${ide.label} and run /flydocs-setup now?` : `Open ${ide.label}?`
|
|
1960
|
+
});
|
|
1961
|
+
if (!isCancel3(launchConfirm) && launchConfirm) {
|
|
1962
|
+
if (ide.passCommand) {
|
|
1963
|
+
spawn(ide.cmd, ["/flydocs-setup"], {
|
|
1964
|
+
cwd: targetDir,
|
|
1965
|
+
stdio: "inherit"
|
|
1966
|
+
});
|
|
1967
|
+
return;
|
|
1968
|
+
} else {
|
|
1969
|
+
spawn(ide.cmd, [targetDir], {
|
|
1970
|
+
stdio: "ignore",
|
|
1971
|
+
detached: true
|
|
1972
|
+
}).unref();
|
|
1973
|
+
printInfo(
|
|
1974
|
+
`${ide.label} opening \u2014 paste /flydocs-setup in the chat panel`
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1913
1977
|
}
|
|
1914
|
-
} else if (
|
|
1915
|
-
const
|
|
1916
|
-
|
|
1978
|
+
} else if (ideOptions.length > 1) {
|
|
1979
|
+
const options = [
|
|
1980
|
+
...ideOptions.map((ide) => ({
|
|
1981
|
+
value: ide.cmd,
|
|
1982
|
+
label: ide.label,
|
|
1983
|
+
hint: ide.hint
|
|
1984
|
+
})),
|
|
1985
|
+
{ value: "skip", label: "Skip", hint: "I'll open my IDE manually" }
|
|
1986
|
+
];
|
|
1987
|
+
const choice = await select({
|
|
1988
|
+
message: "Open an IDE to run /flydocs-setup?",
|
|
1989
|
+
options
|
|
1917
1990
|
});
|
|
1918
|
-
if (!isCancel3(
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1991
|
+
if (!isCancel3(choice) && choice !== "skip") {
|
|
1992
|
+
const ide = ideOptions.find((o) => o.cmd === choice);
|
|
1993
|
+
if (ide) {
|
|
1994
|
+
if (ide.passCommand) {
|
|
1995
|
+
spawn(ide.cmd, ["/flydocs-setup"], {
|
|
1996
|
+
cwd: targetDir,
|
|
1997
|
+
stdio: "inherit"
|
|
1998
|
+
});
|
|
1999
|
+
return;
|
|
2000
|
+
} else {
|
|
2001
|
+
spawn(ide.cmd, [targetDir], {
|
|
2002
|
+
stdio: "ignore",
|
|
2003
|
+
detached: true
|
|
2004
|
+
}).unref();
|
|
2005
|
+
printInfo(
|
|
2006
|
+
`${ide.label} opening \u2014 paste /flydocs-setup in the chat panel`
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
1924
2010
|
}
|
|
1925
2011
|
}
|
|
1926
2012
|
} catch {
|
|
@@ -1943,9 +2029,9 @@ __export(update_exports, {
|
|
|
1943
2029
|
default: () => update_default
|
|
1944
2030
|
});
|
|
1945
2031
|
import { defineCommand as defineCommand2 } from "citty";
|
|
1946
|
-
import { resolve as resolve3, join as
|
|
2032
|
+
import { resolve as resolve3, join as join13 } from "path";
|
|
1947
2033
|
import { mkdir as mkdir5, cp as cp2, readFile as readFile8, readdir as readdir3, rm as rm4 } from "fs/promises";
|
|
1948
|
-
import { select, text, confirm as confirm3, isCancel as isCancel4, cancel as cancel3 } from "@clack/prompts";
|
|
2034
|
+
import { select as select2, text, confirm as confirm3, isCancel as isCancel4, cancel as cancel3 } from "@clack/prompts";
|
|
1949
2035
|
import pc6 from "picocolors";
|
|
1950
2036
|
var update_default;
|
|
1951
2037
|
var init_update = __esm({
|
|
@@ -2011,7 +2097,7 @@ var init_update = __esm({
|
|
|
2011
2097
|
} else if (args.here) {
|
|
2012
2098
|
targetDir = process.cwd();
|
|
2013
2099
|
} else {
|
|
2014
|
-
const choice = await
|
|
2100
|
+
const choice = await select2({
|
|
2015
2101
|
message: "Which project would you like to update?",
|
|
2016
2102
|
options: [
|
|
2017
2103
|
{
|
|
@@ -2049,9 +2135,9 @@ var init_update = __esm({
|
|
|
2049
2135
|
}
|
|
2050
2136
|
targetDir = resolve3(targetDir);
|
|
2051
2137
|
process.chdir(targetDir);
|
|
2052
|
-
const hasVersion = await pathExists(
|
|
2138
|
+
const hasVersion = await pathExists(join13(targetDir, ".flydocs", "version"));
|
|
2053
2139
|
const hasConfig = await pathExists(
|
|
2054
|
-
|
|
2140
|
+
join13(targetDir, ".flydocs", "config.json")
|
|
2055
2141
|
);
|
|
2056
2142
|
if (!hasVersion && !hasConfig) {
|
|
2057
2143
|
printError(`Not a FlyDocs project: ${targetDir}`);
|
|
@@ -2063,7 +2149,7 @@ var init_update = __esm({
|
|
|
2063
2149
|
let currentVersion = "0.1.0";
|
|
2064
2150
|
if (hasVersion) {
|
|
2065
2151
|
const vContent = await readFile8(
|
|
2066
|
-
|
|
2152
|
+
join13(targetDir, ".flydocs", "version"),
|
|
2067
2153
|
"utf-8"
|
|
2068
2154
|
);
|
|
2069
2155
|
currentVersion = vContent.trim();
|
|
@@ -2091,7 +2177,7 @@ var init_update = __esm({
|
|
|
2091
2177
|
}
|
|
2092
2178
|
console.log(`Updating: v${currentVersion} \u2192 v${version}`);
|
|
2093
2179
|
console.log();
|
|
2094
|
-
const changelogPath =
|
|
2180
|
+
const changelogPath = join13(templateDir, "CHANGELOG.md");
|
|
2095
2181
|
const whatsNew = await getWhatsNew(changelogPath, currentVersion, version);
|
|
2096
2182
|
if (whatsNew.length > 0) {
|
|
2097
2183
|
console.log(pc6.cyan("What's new:"));
|
|
@@ -2103,23 +2189,23 @@ var init_update = __esm({
|
|
|
2103
2189
|
}
|
|
2104
2190
|
const now = /* @__PURE__ */ new Date();
|
|
2105
2191
|
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")}`;
|
|
2106
|
-
const backupDir =
|
|
2192
|
+
const backupDir = join13(targetDir, ".flydocs", `backup-${ts}`);
|
|
2107
2193
|
await mkdir5(backupDir, { recursive: true });
|
|
2108
2194
|
if (hasConfig) {
|
|
2109
2195
|
await cp2(
|
|
2110
|
-
|
|
2111
|
-
|
|
2196
|
+
join13(targetDir, ".flydocs", "config.json"),
|
|
2197
|
+
join13(backupDir, "config.json")
|
|
2112
2198
|
);
|
|
2113
2199
|
printStatus(`Config backed up to .flydocs/backup-${ts}/`);
|
|
2114
2200
|
}
|
|
2115
2201
|
try {
|
|
2116
|
-
const flydocsDir =
|
|
2202
|
+
const flydocsDir = join13(targetDir, ".flydocs");
|
|
2117
2203
|
const entries = await readdir3(flydocsDir);
|
|
2118
2204
|
const backups = entries.filter((e) => e.startsWith("backup-")).sort();
|
|
2119
2205
|
if (backups.length > 3) {
|
|
2120
2206
|
const toRemove = backups.slice(0, backups.length - 3);
|
|
2121
2207
|
for (const old of toRemove) {
|
|
2122
|
-
await rm4(
|
|
2208
|
+
await rm4(join13(flydocsDir, old), { recursive: true, force: true });
|
|
2123
2209
|
}
|
|
2124
2210
|
}
|
|
2125
2211
|
} catch {
|
|
@@ -2132,7 +2218,6 @@ var init_update = __esm({
|
|
|
2132
2218
|
issueLabels: {},
|
|
2133
2219
|
statusMapping: {},
|
|
2134
2220
|
detectedStack: {},
|
|
2135
|
-
mcp: {},
|
|
2136
2221
|
skills: {},
|
|
2137
2222
|
designSystem: null,
|
|
2138
2223
|
aiLabor: {}
|
|
@@ -2157,72 +2242,72 @@ var init_update = __esm({
|
|
|
2157
2242
|
}
|
|
2158
2243
|
console.log("Replacing framework directories...");
|
|
2159
2244
|
await replaceDirectory(
|
|
2160
|
-
|
|
2161
|
-
|
|
2245
|
+
join13(templateDir, ".flydocs", "templates"),
|
|
2246
|
+
join13(targetDir, ".flydocs", "templates")
|
|
2162
2247
|
);
|
|
2163
2248
|
await replaceDirectory(
|
|
2164
|
-
|
|
2165
|
-
|
|
2249
|
+
join13(templateDir, ".flydocs", "hooks"),
|
|
2250
|
+
join13(targetDir, ".flydocs", "hooks")
|
|
2166
2251
|
);
|
|
2167
2252
|
await replaceDirectory(
|
|
2168
|
-
|
|
2169
|
-
|
|
2253
|
+
join13(templateDir, ".flydocs", "scripts"),
|
|
2254
|
+
join13(targetDir, ".flydocs", "scripts")
|
|
2170
2255
|
);
|
|
2171
2256
|
printStatus(".flydocs/templates, hooks, scripts");
|
|
2172
|
-
const claudeAgentsSrc =
|
|
2257
|
+
const claudeAgentsSrc = join13(templateDir, ".claude", "agents");
|
|
2173
2258
|
if (await pathExists(claudeAgentsSrc)) {
|
|
2174
2259
|
await copyDirectoryContents(
|
|
2175
2260
|
claudeAgentsSrc,
|
|
2176
|
-
|
|
2261
|
+
join13(targetDir, ".claude", "agents")
|
|
2177
2262
|
);
|
|
2178
2263
|
}
|
|
2179
2264
|
printStatus(".claude/agents");
|
|
2180
2265
|
await replaceOwnedSkills(templateDir, targetDir, effectiveTier);
|
|
2181
2266
|
printStatus(`.claude/skills (tier: ${effectiveTier})`);
|
|
2182
|
-
const cursorAgentsSrc =
|
|
2267
|
+
const cursorAgentsSrc = join13(templateDir, ".cursor", "agents");
|
|
2183
2268
|
if (await pathExists(cursorAgentsSrc)) {
|
|
2184
2269
|
await copyDirectoryContents(
|
|
2185
2270
|
cursorAgentsSrc,
|
|
2186
|
-
|
|
2271
|
+
join13(targetDir, ".cursor", "agents")
|
|
2187
2272
|
);
|
|
2188
2273
|
}
|
|
2189
2274
|
printStatus(".cursor/agents");
|
|
2190
2275
|
console.log();
|
|
2191
2276
|
console.log("Replacing framework files...");
|
|
2192
2277
|
await copyFile(
|
|
2193
|
-
|
|
2194
|
-
|
|
2278
|
+
join13(templateDir, ".claude", "CLAUDE.md"),
|
|
2279
|
+
join13(targetDir, ".claude", "CLAUDE.md")
|
|
2195
2280
|
);
|
|
2196
2281
|
await copyFile(
|
|
2197
|
-
|
|
2198
|
-
|
|
2282
|
+
join13(templateDir, ".claude", "settings.json"),
|
|
2283
|
+
join13(targetDir, ".claude", "settings.json")
|
|
2199
2284
|
);
|
|
2200
2285
|
printStatus(".claude/CLAUDE.md, settings.json");
|
|
2201
2286
|
await copyDirectoryContents(
|
|
2202
|
-
|
|
2203
|
-
|
|
2287
|
+
join13(templateDir, ".claude", "commands"),
|
|
2288
|
+
join13(targetDir, ".claude", "commands")
|
|
2204
2289
|
);
|
|
2205
2290
|
await copyDirectoryContents(
|
|
2206
|
-
|
|
2207
|
-
|
|
2291
|
+
join13(templateDir, ".claude", "commands"),
|
|
2292
|
+
join13(targetDir, ".cursor", "commands")
|
|
2208
2293
|
);
|
|
2209
2294
|
printStatus(".claude/commands, .cursor/commands");
|
|
2210
|
-
const skillsReadmeSrc =
|
|
2295
|
+
const skillsReadmeSrc = join13(templateDir, ".claude", "skills", "README.md");
|
|
2211
2296
|
if (await pathExists(skillsReadmeSrc)) {
|
|
2212
2297
|
await copyFile(
|
|
2213
2298
|
skillsReadmeSrc,
|
|
2214
|
-
|
|
2299
|
+
join13(targetDir, ".claude", "skills", "README.md")
|
|
2215
2300
|
);
|
|
2216
2301
|
}
|
|
2217
2302
|
printStatus(".claude/skills/README.md");
|
|
2218
2303
|
await copyFile(
|
|
2219
|
-
|
|
2220
|
-
|
|
2304
|
+
join13(templateDir, ".cursor", "hooks.json"),
|
|
2305
|
+
join13(targetDir, ".cursor", "hooks.json")
|
|
2221
2306
|
);
|
|
2222
2307
|
printStatus(".cursor/hooks.json");
|
|
2223
2308
|
await copyFile(
|
|
2224
|
-
|
|
2225
|
-
|
|
2309
|
+
join13(templateDir, "AGENTS.md"),
|
|
2310
|
+
join13(targetDir, "AGENTS.md")
|
|
2226
2311
|
);
|
|
2227
2312
|
printStatus("AGENTS.md");
|
|
2228
2313
|
await runManifestGeneration(targetDir);
|
|
@@ -2247,18 +2332,18 @@ var init_update = __esm({
|
|
|
2247
2332
|
printWarning("Config merge failed \u2014 config.json preserved as-is");
|
|
2248
2333
|
}
|
|
2249
2334
|
await copyFile(
|
|
2250
|
-
|
|
2251
|
-
|
|
2335
|
+
join13(templateDir, ".flydocs", "version"),
|
|
2336
|
+
join13(targetDir, ".flydocs", "version")
|
|
2252
2337
|
);
|
|
2253
2338
|
printStatus(`.flydocs/version \u2192 ${version}`);
|
|
2254
|
-
const clSrc =
|
|
2339
|
+
const clSrc = join13(templateDir, "CHANGELOG.md");
|
|
2255
2340
|
if (await pathExists(clSrc)) {
|
|
2256
|
-
await copyFile(clSrc,
|
|
2341
|
+
await copyFile(clSrc, join13(targetDir, ".flydocs", "CHANGELOG.md"));
|
|
2257
2342
|
printStatus(".flydocs/CHANGELOG.md");
|
|
2258
2343
|
}
|
|
2259
|
-
const mfSrc =
|
|
2344
|
+
const mfSrc = join13(templateDir, "manifest.json");
|
|
2260
2345
|
if (await pathExists(mfSrc)) {
|
|
2261
|
-
await copyFile(mfSrc,
|
|
2346
|
+
await copyFile(mfSrc, join13(targetDir, ".flydocs", "manifest.json"));
|
|
2262
2347
|
printStatus(".flydocs/manifest.json");
|
|
2263
2348
|
}
|
|
2264
2349
|
console.log();
|
|
@@ -2312,18 +2397,32 @@ __export(setup_exports, {
|
|
|
2312
2397
|
default: () => setup_default
|
|
2313
2398
|
});
|
|
2314
2399
|
import { defineCommand as defineCommand3 } from "citty";
|
|
2400
|
+
import pc7 from "picocolors";
|
|
2315
2401
|
var setup_default;
|
|
2316
2402
|
var init_setup = __esm({
|
|
2317
2403
|
"src/commands/setup.ts"() {
|
|
2318
2404
|
"use strict";
|
|
2319
|
-
init_ui();
|
|
2320
2405
|
setup_default = defineCommand3({
|
|
2321
2406
|
meta: {
|
|
2322
2407
|
name: "setup",
|
|
2323
2408
|
description: "Configure FlyDocs settings for this project"
|
|
2324
2409
|
},
|
|
2325
2410
|
run() {
|
|
2326
|
-
|
|
2411
|
+
console.log();
|
|
2412
|
+
console.log(` ${pc7.bold("FlyDocs Setup")}`);
|
|
2413
|
+
console.log();
|
|
2414
|
+
console.log(` Setup runs inside your IDE as an interactive AI command.`);
|
|
2415
|
+
console.log();
|
|
2416
|
+
console.log(
|
|
2417
|
+
` ${pc7.cyan("Claude Code:")} Type ${pc7.bold("/flydocs-setup")} in chat`
|
|
2418
|
+
);
|
|
2419
|
+
console.log(
|
|
2420
|
+
` ${pc7.cyan("Cursor:")} Type ${pc7.bold("/flydocs-setup")} in chat`
|
|
2421
|
+
);
|
|
2422
|
+
console.log();
|
|
2423
|
+
console.log(` This configures your project context, detects your stack,`);
|
|
2424
|
+
console.log(` and installs community skills tailored to your codebase.`);
|
|
2425
|
+
console.log();
|
|
2327
2426
|
}
|
|
2328
2427
|
});
|
|
2329
2428
|
}
|
|
@@ -2335,7 +2434,7 @@ __export(skills_exports, {
|
|
|
2335
2434
|
default: () => skills_default
|
|
2336
2435
|
});
|
|
2337
2436
|
import { defineCommand as defineCommand4 } from "citty";
|
|
2338
|
-
import
|
|
2437
|
+
import pc8 from "picocolors";
|
|
2339
2438
|
var list, search, add, remove, skills_default;
|
|
2340
2439
|
var init_skills2 = __esm({
|
|
2341
2440
|
"src/commands/skills.ts"() {
|
|
@@ -2357,19 +2456,19 @@ var init_skills2 = __esm({
|
|
|
2357
2456
|
console.log(`${total} skill(s) installed:`);
|
|
2358
2457
|
if (result.platform.length > 0) {
|
|
2359
2458
|
console.log();
|
|
2360
|
-
console.log(
|
|
2459
|
+
console.log(pc8.bold("Platform"));
|
|
2361
2460
|
for (const skill of result.platform) {
|
|
2362
2461
|
console.log(
|
|
2363
|
-
` ${skill.name} ${
|
|
2462
|
+
` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
|
|
2364
2463
|
);
|
|
2365
2464
|
}
|
|
2366
2465
|
}
|
|
2367
2466
|
if (result.community.length > 0) {
|
|
2368
2467
|
console.log();
|
|
2369
|
-
console.log(
|
|
2468
|
+
console.log(pc8.bold("Community"));
|
|
2370
2469
|
for (const skill of result.community) {
|
|
2371
2470
|
console.log(
|
|
2372
|
-
` ${skill.name} ${
|
|
2471
|
+
` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
|
|
2373
2472
|
);
|
|
2374
2473
|
}
|
|
2375
2474
|
}
|
|
@@ -2392,18 +2491,18 @@ var init_skills2 = __esm({
|
|
|
2392
2491
|
const results = await searchCatalog(args.keyword);
|
|
2393
2492
|
if (results.length === 0) {
|
|
2394
2493
|
console.log(`No skills found for "${args.keyword}".`);
|
|
2395
|
-
console.log(` Browse the catalog at: ${
|
|
2494
|
+
console.log(` Browse the catalog at: ${pc8.cyan("https://skills.sh/")}`);
|
|
2396
2495
|
return;
|
|
2397
2496
|
}
|
|
2398
2497
|
console.log();
|
|
2399
2498
|
console.log(`${results.length} skill(s) matching "${args.keyword}":`);
|
|
2400
2499
|
console.log();
|
|
2401
2500
|
for (const skill of results) {
|
|
2402
|
-
console.log(` ${
|
|
2501
|
+
console.log(` ${pc8.bold(skill.name)}`);
|
|
2403
2502
|
console.log(` ${skill.description}`);
|
|
2404
|
-
console.log(` ${
|
|
2503
|
+
console.log(` ${pc8.dim(skill.repo)}`);
|
|
2405
2504
|
if (skill.tags.length > 0) {
|
|
2406
|
-
console.log(` ${
|
|
2505
|
+
console.log(` ${pc8.dim(skill.tags.join(", "))}`);
|
|
2407
2506
|
}
|
|
2408
2507
|
console.log();
|
|
2409
2508
|
}
|
|
@@ -2463,10 +2562,9 @@ __export(connect_exports, {
|
|
|
2463
2562
|
});
|
|
2464
2563
|
import { defineCommand as defineCommand5 } from "citty";
|
|
2465
2564
|
import { text as text2, confirm as confirm4, isCancel as isCancel5, cancel as cancel4 } from "@clack/prompts";
|
|
2466
|
-
import
|
|
2565
|
+
import pc9 from "picocolors";
|
|
2467
2566
|
import { readFile as readFile9, writeFile as writeFile5, appendFile as appendFile2 } from "fs/promises";
|
|
2468
|
-
import { join as
|
|
2469
|
-
import { execSync as execSync2 } from "child_process";
|
|
2567
|
+
import { join as join14 } from "path";
|
|
2470
2568
|
var connect_default;
|
|
2471
2569
|
var init_connect = __esm({
|
|
2472
2570
|
"src/commands/connect.ts"() {
|
|
@@ -2500,11 +2598,11 @@ var init_connect = __esm({
|
|
|
2500
2598
|
},
|
|
2501
2599
|
async run({ args }) {
|
|
2502
2600
|
const targetDir = args.path ?? process.cwd();
|
|
2503
|
-
const configPath =
|
|
2601
|
+
const configPath = join14(targetDir, ".flydocs", "config.json");
|
|
2504
2602
|
if (!await pathExists(configPath)) {
|
|
2505
2603
|
printError("Not a FlyDocs project (.flydocs/config.json not found).");
|
|
2506
2604
|
console.log(
|
|
2507
|
-
` Run ${
|
|
2605
|
+
` Run ${pc9.cyan("flydocs")} first to install FlyDocs in this project.`
|
|
2508
2606
|
);
|
|
2509
2607
|
process.exit(1);
|
|
2510
2608
|
}
|
|
@@ -2521,10 +2619,10 @@ var init_connect = __esm({
|
|
|
2521
2619
|
}
|
|
2522
2620
|
}
|
|
2523
2621
|
console.log();
|
|
2524
|
-
console.log(` ${
|
|
2622
|
+
console.log(` ${pc9.bold("Connect to Linear")}`);
|
|
2525
2623
|
console.log();
|
|
2526
2624
|
console.log(
|
|
2527
|
-
` ${
|
|
2625
|
+
` ${pc9.dim("Get your API key from: Linear \u2192 Settings \u2192 API \u2192 Personal API keys")}`
|
|
2528
2626
|
);
|
|
2529
2627
|
console.log();
|
|
2530
2628
|
let apiKey = args.key ?? "";
|
|
@@ -2547,27 +2645,31 @@ var init_connect = __esm({
|
|
|
2547
2645
|
}
|
|
2548
2646
|
printInfo("Validating API key...");
|
|
2549
2647
|
try {
|
|
2550
|
-
const
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
const
|
|
2563
|
-
|
|
2648
|
+
const response = await fetch("https://api.linear.app/graphql", {
|
|
2649
|
+
method: "POST",
|
|
2650
|
+
headers: {
|
|
2651
|
+
Authorization: apiKey,
|
|
2652
|
+
"Content-Type": "application/json"
|
|
2653
|
+
},
|
|
2654
|
+
body: JSON.stringify({ query: "{ viewer { id name email } }" }),
|
|
2655
|
+
signal: AbortSignal.timeout(15e3)
|
|
2656
|
+
});
|
|
2657
|
+
if (!response.ok) {
|
|
2658
|
+
throw new Error(`HTTP ${response.status}`);
|
|
2659
|
+
}
|
|
2660
|
+
const data = await response.json();
|
|
2661
|
+
if (!data.data?.viewer) {
|
|
2662
|
+
throw new Error("Invalid response");
|
|
2663
|
+
}
|
|
2664
|
+
const viewer = data.data.viewer;
|
|
2665
|
+
printStatus(`Authenticated as ${pc9.bold(viewer.name)} (${viewer.email})`);
|
|
2564
2666
|
} catch {
|
|
2565
2667
|
printError("Invalid API key or network error.");
|
|
2566
2668
|
console.log(` Check your key and try again.`);
|
|
2567
2669
|
process.exit(1);
|
|
2568
2670
|
}
|
|
2569
|
-
const envPath =
|
|
2570
|
-
const envLocalPath =
|
|
2671
|
+
const envPath = join14(targetDir, ".env");
|
|
2672
|
+
const envLocalPath = join14(targetDir, ".env.local");
|
|
2571
2673
|
const targetEnvPath = await pathExists(envLocalPath) ? envLocalPath : envPath;
|
|
2572
2674
|
if (await pathExists(targetEnvPath)) {
|
|
2573
2675
|
const envContent = await readFile9(targetEnvPath, "utf-8");
|
|
@@ -2587,7 +2689,7 @@ LINEAR_API_KEY=${apiKey}
|
|
|
2587
2689
|
`, "utf-8");
|
|
2588
2690
|
}
|
|
2589
2691
|
printStatus(
|
|
2590
|
-
`API key stored in ${
|
|
2692
|
+
`API key stored in ${pc9.dim(targetEnvPath === envLocalPath ? ".env.local" : ".env")}`
|
|
2591
2693
|
);
|
|
2592
2694
|
const wasLocal = config.tier === "local";
|
|
2593
2695
|
config.tier = "cloud";
|
|
@@ -2600,14 +2702,14 @@ LINEAR_API_KEY=${apiKey}
|
|
|
2600
2702
|
const templateDir = await resolveTemplatePath(
|
|
2601
2703
|
args["local-source"] || void 0
|
|
2602
2704
|
);
|
|
2603
|
-
const templateSkillsDir =
|
|
2604
|
-
const skillsDir =
|
|
2705
|
+
const templateSkillsDir = join14(templateDir, ".claude", "skills");
|
|
2706
|
+
const skillsDir = join14(targetDir, ".claude", "skills");
|
|
2605
2707
|
await replaceDirectory(
|
|
2606
|
-
|
|
2607
|
-
|
|
2708
|
+
join14(templateSkillsDir, "flydocs-cloud"),
|
|
2709
|
+
join14(skillsDir, "flydocs-cloud")
|
|
2608
2710
|
);
|
|
2609
2711
|
const { rm: rm5 } = await import("fs/promises");
|
|
2610
|
-
const localSkillDir =
|
|
2712
|
+
const localSkillDir = join14(skillsDir, "flydocs-local");
|
|
2611
2713
|
if (await pathExists(localSkillDir)) {
|
|
2612
2714
|
await rm5(localSkillDir, { recursive: true, force: true });
|
|
2613
2715
|
}
|
|
@@ -2620,14 +2722,14 @@ LINEAR_API_KEY=${apiKey}
|
|
|
2620
2722
|
}
|
|
2621
2723
|
console.log();
|
|
2622
2724
|
console.log(
|
|
2623
|
-
` ${
|
|
2725
|
+
` ${pc9.bold("Connected!")} Your project now syncs with Linear.`
|
|
2624
2726
|
);
|
|
2625
2727
|
console.log();
|
|
2626
2728
|
console.log(` Next steps:`);
|
|
2627
2729
|
console.log(
|
|
2628
|
-
` 1. Run ${
|
|
2730
|
+
` 1. Run ${pc9.cyan("/flydocs-setup")} in your IDE to configure your Linear project`
|
|
2629
2731
|
);
|
|
2630
|
-
console.log(` 2. Run ${
|
|
2732
|
+
console.log(` 2. Run ${pc9.cyan("/start-session")} to begin working`);
|
|
2631
2733
|
console.log();
|
|
2632
2734
|
}
|
|
2633
2735
|
});
|
|
@@ -2640,7 +2742,7 @@ __export(upgrade_exports, {
|
|
|
2640
2742
|
default: () => upgrade_default
|
|
2641
2743
|
});
|
|
2642
2744
|
import { defineCommand as defineCommand6 } from "citty";
|
|
2643
|
-
import
|
|
2745
|
+
import pc10 from "picocolors";
|
|
2644
2746
|
var upgrade_default;
|
|
2645
2747
|
var init_upgrade = __esm({
|
|
2646
2748
|
"src/commands/upgrade.ts"() {
|
|
@@ -2676,37 +2778,37 @@ var init_upgrade = __esm({
|
|
|
2676
2778
|
console.log();
|
|
2677
2779
|
if (currentTier === "cloud") {
|
|
2678
2780
|
console.log(
|
|
2679
|
-
` ${
|
|
2781
|
+
` ${pc10.green("\u2713")} You're already on the ${pc10.bold("cloud")} tier.`
|
|
2680
2782
|
);
|
|
2681
2783
|
console.log();
|
|
2682
2784
|
console.log(
|
|
2683
2785
|
` Your issues sync with Linear via the cloud mechanism skill.`
|
|
2684
2786
|
);
|
|
2685
2787
|
console.log(
|
|
2686
|
-
` Run ${
|
|
2788
|
+
` Run ${pc10.cyan("flydocs connect")} to update your connection settings.`
|
|
2687
2789
|
);
|
|
2688
2790
|
console.log();
|
|
2689
2791
|
return;
|
|
2690
2792
|
}
|
|
2691
|
-
console.log(` ${
|
|
2793
|
+
console.log(` ${pc10.bold("FlyDocs Cloud Tier")}`);
|
|
2692
2794
|
console.log();
|
|
2693
|
-
console.log(` You're currently on the ${
|
|
2795
|
+
console.log(` You're currently on the ${pc10.yellow("local")} tier.`);
|
|
2694
2796
|
console.log(` Upgrade to cloud for:`);
|
|
2695
2797
|
console.log();
|
|
2696
2798
|
console.log(
|
|
2697
|
-
` ${
|
|
2799
|
+
` ${pc10.cyan("\u2192")} Issue sync with Linear (Jira coming soon)`
|
|
2698
2800
|
);
|
|
2699
|
-
console.log(` ${
|
|
2700
|
-
console.log(` ${
|
|
2701
|
-
console.log(` ${
|
|
2702
|
-
console.log(` ${
|
|
2801
|
+
console.log(` ${pc10.cyan("\u2192")} Project milestones and cycle management`);
|
|
2802
|
+
console.log(` ${pc10.cyan("\u2192")} Team assignment and priority tracking`);
|
|
2803
|
+
console.log(` ${pc10.cyan("\u2192")} Project health updates and dashboards`);
|
|
2804
|
+
console.log(` ${pc10.cyan("\u2192")} Cross-project issue linking`);
|
|
2703
2805
|
console.log();
|
|
2704
|
-
console.log(` ${
|
|
2806
|
+
console.log(` ${pc10.bold("How to upgrade:")}`);
|
|
2705
2807
|
console.log();
|
|
2706
|
-
console.log(` 1. Sign up at ${
|
|
2808
|
+
console.log(` 1. Sign up at ${pc10.cyan("https://www.flydocs.ai")}`);
|
|
2707
2809
|
console.log(` 2. Get your Linear API key from Linear \u2192 Settings \u2192 API`);
|
|
2708
2810
|
console.log(
|
|
2709
|
-
` 3. Run ${
|
|
2811
|
+
` 3. Run ${pc10.cyan("flydocs connect")} to connect your project`
|
|
2710
2812
|
);
|
|
2711
2813
|
console.log();
|
|
2712
2814
|
}
|
|
@@ -2720,8 +2822,8 @@ __export(self_update_exports, {
|
|
|
2720
2822
|
default: () => self_update_default
|
|
2721
2823
|
});
|
|
2722
2824
|
import { defineCommand as defineCommand7 } from "citty";
|
|
2723
|
-
import { execSync
|
|
2724
|
-
import
|
|
2825
|
+
import { execSync } from "child_process";
|
|
2826
|
+
import pc11 from "picocolors";
|
|
2725
2827
|
var self_update_default;
|
|
2726
2828
|
var init_self_update = __esm({
|
|
2727
2829
|
"src/commands/self-update.ts"() {
|
|
@@ -2735,10 +2837,10 @@ var init_self_update = __esm({
|
|
|
2735
2837
|
},
|
|
2736
2838
|
async run() {
|
|
2737
2839
|
console.log();
|
|
2738
|
-
console.log(` Updating ${
|
|
2840
|
+
console.log(` Updating ${pc11.cyan(PACKAGE_NAME)}...`);
|
|
2739
2841
|
console.log();
|
|
2740
2842
|
try {
|
|
2741
|
-
|
|
2843
|
+
execSync(`npm install -g ${PACKAGE_NAME}@beta`, {
|
|
2742
2844
|
stdio: "inherit",
|
|
2743
2845
|
timeout: 6e4
|
|
2744
2846
|
});
|