@flydocs/cli 0.6.0-alpha.13 → 0.6.0-alpha.20

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.
Files changed (152) hide show
  1. package/dist/cli.js +281 -256
  2. package/package.json +1 -1
  3. package/template/.claude/CLAUDE.md +62 -66
  4. package/template/.claude/agents/implementation-agent.md +1 -1
  5. package/template/.claude/agents/pm-agent.md +1 -1
  6. package/template/.claude/commands/activate.md +1 -1
  7. package/template/.claude/commands/attach.md +1 -1
  8. package/template/.claude/commands/block.md +2 -2
  9. package/template/.claude/commands/capture.md +1 -1
  10. package/template/.claude/commands/close.md +1 -1
  11. package/template/.claude/commands/flydocs-setup.md +261 -58
  12. package/template/.claude/commands/flydocs-upgrade.md +26 -27
  13. package/template/.claude/commands/implement.md +1 -1
  14. package/template/.claude/commands/new-project.md +1 -1
  15. package/template/.claude/commands/onboard.md +275 -0
  16. package/template/.claude/commands/project-update.md +1 -1
  17. package/template/.claude/commands/refine.md +1 -1
  18. package/template/.claude/commands/review.md +1 -1
  19. package/template/.claude/commands/start-session.md +1 -1
  20. package/template/.claude/commands/status.md +1 -1
  21. package/template/.claude/commands/validate.md +1 -1
  22. package/template/.claude/commands/wrap-session.md +1 -1
  23. package/template/.claude/hooks/auto-approve.py +132 -0
  24. package/template/.claude/hooks/post-pr-check.py +108 -0
  25. package/template/.claude/hooks/post-transition-check.py +94 -0
  26. package/template/{.flydocs → .claude}/hooks/prompt-submit.py +167 -17
  27. package/template/.claude/hooks/session-start.py +146 -0
  28. package/template/.claude/hooks/stop-gate.py +109 -0
  29. package/template/.claude/settings.json +41 -4
  30. package/template/.claude/skills/README.md +23 -25
  31. package/template/.claude/skills/flydocs-workflow/SKILL.md +121 -34
  32. package/template/.claude/skills/flydocs-workflow/cursor-rule.mdc +9 -8
  33. package/template/.claude/skills/flydocs-workflow/reference/golden-rules.md +28 -17
  34. package/template/.claude/skills/flydocs-workflow/reference/graph-schema.md +116 -0
  35. package/template/.claude/skills/flydocs-workflow/reference/pr-workflow.md +30 -15
  36. package/template/.claude/skills/flydocs-workflow/reference/priority-estimates.md +1 -1
  37. package/template/.claude/skills/flydocs-workflow/reference/service-descriptor-schema.md +251 -0
  38. package/template/.claude/skills/flydocs-workflow/reference/status-workflow.md +26 -26
  39. package/template/.claude/skills/flydocs-workflow/scripts/_local/__init__.py +0 -0
  40. package/template/.claude/skills/{flydocs-local/scripts/flydocs_api.py → flydocs-workflow/scripts/_local/file_store.py} +133 -46
  41. package/template/.claude/skills/flydocs-workflow/scripts/flydocs_api.py +693 -0
  42. package/template/{.flydocs → .claude/skills/flydocs-workflow}/scripts/generate_manifest.py +4 -4
  43. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_build.py +132 -1
  44. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_query.py +18 -5
  45. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_session.py +1 -1
  46. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_update.py +4 -4
  47. package/template/.claude/skills/{flydocs-context-graph → flydocs-workflow}/scripts/graph_utils.py +2 -1
  48. package/template/.claude/skills/flydocs-workflow/scripts/issues.py +489 -0
  49. package/template/.claude/skills/flydocs-workflow/scripts/projects.py +144 -0
  50. package/template/.claude/skills/flydocs-workflow/scripts/pull_services.py +128 -0
  51. package/template/.claude/skills/flydocs-workflow/scripts/push_service.py +132 -0
  52. package/template/.claude/skills/flydocs-workflow/scripts/session.py +54 -0
  53. package/template/.claude/skills/flydocs-workflow/scripts/workspace.py +860 -0
  54. package/template/.claude/skills/flydocs-workflow/session.md +16 -11
  55. package/template/.claude/skills/flydocs-workflow/stages/activate.md +13 -8
  56. package/template/.claude/skills/flydocs-workflow/stages/capture.md +4 -4
  57. package/template/.claude/skills/flydocs-workflow/stages/close.md +1 -1
  58. package/template/.claude/skills/flydocs-workflow/stages/implement.md +7 -7
  59. package/template/.claude/skills/flydocs-workflow/stages/refine.md +5 -5
  60. package/template/.claude/skills/flydocs-workflow/stages/review.md +2 -2
  61. package/template/.claude/skills/flydocs-workflow/stages/validate.md +3 -1
  62. package/template/.claude/skills/flydocs-workflow/templates/pr/default.md +33 -0
  63. package/template/.cursor/agents/implementation-agent.md +1 -1
  64. package/template/.cursor/agents/pm-agent.md +2 -2
  65. package/template/.cursor/hooks.json +10 -3
  66. package/template/.env.example +6 -6
  67. package/template/.flydocs/config.json +2 -1
  68. package/template/.flydocs/templates/README.md +13 -14
  69. package/template/.flydocs/templates/quick-capture.md +4 -8
  70. package/template/.flydocs/version +1 -1
  71. package/template/AGENTS.md +39 -32
  72. package/template/flydocs/README.md +1 -3
  73. package/template/flydocs/context/project.md +6 -3
  74. package/template/flydocs/design-system/README.md +3 -3
  75. package/template/manifest.json +17 -19
  76. package/template/.claude/skills/flydocs-cloud/SKILL.md +0 -138
  77. package/template/.claude/skills/flydocs-cloud/cursor-rule.mdc +0 -50
  78. package/template/.claude/skills/flydocs-cloud/scripts/assign.py +0 -28
  79. package/template/.claude/skills/flydocs-cloud/scripts/assign_cycle.py +0 -28
  80. package/template/.claude/skills/flydocs-cloud/scripts/assign_milestone.py +0 -22
  81. package/template/.claude/skills/flydocs-cloud/scripts/comment.py +0 -29
  82. package/template/.claude/skills/flydocs-cloud/scripts/create_issue.py +0 -83
  83. package/template/.claude/skills/flydocs-cloud/scripts/create_milestone.py +0 -35
  84. package/template/.claude/skills/flydocs-cloud/scripts/create_project.py +0 -33
  85. package/template/.claude/skills/flydocs-cloud/scripts/create_team.py +0 -39
  86. package/template/.claude/skills/flydocs-cloud/scripts/delete_milestone.py +0 -21
  87. package/template/.claude/skills/flydocs-cloud/scripts/estimate.py +0 -33
  88. package/template/.claude/skills/flydocs-cloud/scripts/flydocs_api.py +0 -241
  89. package/template/.claude/skills/flydocs-cloud/scripts/generate_config.py +0 -125
  90. package/template/.claude/skills/flydocs-cloud/scripts/get_estimate_scale.py +0 -23
  91. package/template/.claude/skills/flydocs-cloud/scripts/get_issue.py +0 -24
  92. package/template/.claude/skills/flydocs-cloud/scripts/get_me.py +0 -103
  93. package/template/.claude/skills/flydocs-cloud/scripts/link.py +0 -28
  94. package/template/.claude/skills/flydocs-cloud/scripts/list_cycles.py +0 -28
  95. package/template/.claude/skills/flydocs-cloud/scripts/list_issues.py +0 -44
  96. package/template/.claude/skills/flydocs-cloud/scripts/list_labels.py +0 -19
  97. package/template/.claude/skills/flydocs-cloud/scripts/list_milestones.py +0 -28
  98. package/template/.claude/skills/flydocs-cloud/scripts/list_projects.py +0 -31
  99. package/template/.claude/skills/flydocs-cloud/scripts/list_providers.py +0 -19
  100. package/template/.claude/skills/flydocs-cloud/scripts/list_statuses.py +0 -19
  101. package/template/.claude/skills/flydocs-cloud/scripts/list_teams.py +0 -19
  102. package/template/.claude/skills/flydocs-cloud/scripts/priority.py +0 -29
  103. package/template/.claude/skills/flydocs-cloud/scripts/project_update.py +0 -45
  104. package/template/.claude/skills/flydocs-cloud/scripts/refresh_labels.py +0 -87
  105. package/template/.claude/skills/flydocs-cloud/scripts/set_identity.py +0 -54
  106. package/template/.claude/skills/flydocs-cloud/scripts/set_labels.py +0 -54
  107. package/template/.claude/skills/flydocs-cloud/scripts/set_preferences.py +0 -49
  108. package/template/.claude/skills/flydocs-cloud/scripts/set_provider.py +0 -31
  109. package/template/.claude/skills/flydocs-cloud/scripts/set_status_mapping.py +0 -57
  110. package/template/.claude/skills/flydocs-cloud/scripts/set_team.py +0 -28
  111. package/template/.claude/skills/flydocs-cloud/scripts/transition.py +0 -26
  112. package/template/.claude/skills/flydocs-cloud/scripts/update_description.py +0 -36
  113. package/template/.claude/skills/flydocs-cloud/scripts/update_issue.py +0 -100
  114. package/template/.claude/skills/flydocs-cloud/scripts/update_milestone.py +0 -42
  115. package/template/.claude/skills/flydocs-cloud/scripts/validate_setup.py +0 -120
  116. package/template/.claude/skills/flydocs-context-graph/SKILL.md +0 -94
  117. package/template/.claude/skills/flydocs-context-graph/schema.md +0 -78
  118. package/template/.claude/skills/flydocs-context-graph/scripts/graph_context.py +0 -338
  119. package/template/.claude/skills/flydocs-context7/SKILL.md +0 -105
  120. package/template/.claude/skills/flydocs-context7/cursor-rule.mdc +0 -49
  121. package/template/.claude/skills/flydocs-context7/scripts/context7.py +0 -293
  122. package/template/.claude/skills/flydocs-estimates/SKILL.md +0 -384
  123. package/template/.claude/skills/flydocs-figma/SKILL.md +0 -377
  124. package/template/.claude/skills/flydocs-figma/references/PROMPTING.md +0 -108
  125. package/template/.claude/skills/flydocs-figma/references/TROUBLESHOOTING.md +0 -112
  126. package/template/.claude/skills/flydocs-local/SKILL.md +0 -103
  127. package/template/.claude/skills/flydocs-local/cursor-rule.mdc +0 -43
  128. package/template/.claude/skills/flydocs-local/scripts/assign.py +0 -29
  129. package/template/.claude/skills/flydocs-local/scripts/comment.py +0 -27
  130. package/template/.claude/skills/flydocs-local/scripts/create_issue.py +0 -44
  131. package/template/.claude/skills/flydocs-local/scripts/estimate.py +0 -37
  132. package/template/.claude/skills/flydocs-local/scripts/get_issue.py +0 -20
  133. package/template/.claude/skills/flydocs-local/scripts/link.py +0 -41
  134. package/template/.claude/skills/flydocs-local/scripts/list_issues.py +0 -50
  135. package/template/.claude/skills/flydocs-local/scripts/priority.py +0 -37
  136. package/template/.claude/skills/flydocs-local/scripts/project_update.py +0 -67
  137. package/template/.claude/skills/flydocs-local/scripts/status_summary.py +0 -16
  138. package/template/.claude/skills/flydocs-local/scripts/transition.py +0 -24
  139. package/template/.claude/skills/flydocs-local/scripts/update_description.py +0 -35
  140. package/template/.claude/skills/flydocs-local/scripts/update_issue.py +0 -84
  141. package/template/.flydocs/hooks/auto-approve.py +0 -71
  142. package/template/.flydocs/scripts/skill_manager.py +0 -541
  143. package/template/.flydocs/templates/bug.md +0 -166
  144. package/template/.flydocs/templates/chore.md +0 -110
  145. package/template/.flydocs/templates/feature.md +0 -173
  146. package/template/.flydocs/templates/idea.md +0 -122
  147. /package/template/{.flydocs → .claude}/hooks/post-edit.py +0 -0
  148. /package/template/.claude/skills/{flydocs-estimates/references → flydocs-workflow/reference}/provider-costs.md +0 -0
  149. /package/template/.claude/skills/flydocs-workflow/templates/{bug.md → issues/bug.md} +0 -0
  150. /package/template/.claude/skills/flydocs-workflow/templates/{chore.md → issues/chore.md} +0 -0
  151. /package/template/.claude/skills/flydocs-workflow/templates/{feature.md → issues/feature.md} +0 -0
  152. /package/template/.claude/skills/flydocs-workflow/templates/{idea.md → issues/idea.md} +0 -0
package/dist/cli.js CHANGED
@@ -15,7 +15,7 @@ var CLI_VERSION, CLI_NAME, PACKAGE_NAME, POSTHOG_API_KEY;
15
15
  var init_constants = __esm({
16
16
  "src/lib/constants.ts"() {
17
17
  "use strict";
18
- CLI_VERSION = "0.6.0-alpha.13";
18
+ CLI_VERSION = "0.6.0-alpha.20";
19
19
  CLI_NAME = "flydocs";
20
20
  PACKAGE_NAME = "@flydocs/cli";
21
21
  POSTHOG_API_KEY = "phc_v1MSJTQDFkMS90CBh3mxIz3v8bYCCnKU6v1ir6bz0Xn";
@@ -299,6 +299,7 @@ function extractPreservedValues(config) {
299
299
  issueLabels: config.issueLabels ?? {},
300
300
  detectedStack: config.detectedStack ?? {},
301
301
  skills: config.skills ?? {},
302
+ topology: config.topology,
302
303
  designSystem: config.designSystem ?? null,
303
304
  aiLabor: config.aiLabor ?? {}
304
305
  };
@@ -328,6 +329,9 @@ async function mergeConfig(templateDir, version, tierFlag, preserved) {
328
329
  if (Object.keys(preserved.skills).length > 0) {
329
330
  config.skills = preserved.skills;
330
331
  }
332
+ if (preserved.topology !== void 0) {
333
+ config.topology = preserved.topology;
334
+ }
331
335
  if (preserved.designSystem !== null) {
332
336
  config.designSystem = preserved.designSystem;
333
337
  }
@@ -344,75 +348,32 @@ var init_config = __esm({
344
348
 
345
349
  // src/lib/skills.ts
346
350
  import { join as join4 } from "path";
347
- async function installOwnedSkills(templateDir, targetDir, tier) {
351
+ async function installOwnedSkills(templateDir, targetDir, _tier) {
348
352
  const skillsDir = join4(targetDir, ".claude", "skills");
349
353
  const templateSkillsDir = join4(templateDir, ".claude", "skills");
350
354
  await replaceDirectory(
351
- join4(templateSkillsDir, "flydocs-workflow"),
352
- join4(skillsDir, "flydocs-workflow")
353
- );
354
- const activeMech = MECHANISM_SKILLS[tier];
355
- const inactiveMech = tier === "local" ? MECHANISM_SKILLS.cloud : MECHANISM_SKILLS.local;
356
- await replaceDirectory(
357
- join4(templateSkillsDir, activeMech),
358
- join4(skillsDir, activeMech)
355
+ join4(templateSkillsDir, OWNED_SKILL),
356
+ join4(skillsDir, OWNED_SKILL)
359
357
  );
360
- const { rm: rm6 } = await import("fs/promises");
361
- const inactivePath = join4(skillsDir, inactiveMech);
362
- if (await pathExists(inactivePath)) {
363
- await rm6(inactivePath, { recursive: true, force: true });
364
- }
365
- for (const skill of CORE_SKILLS) {
366
- if (skill === "flydocs-workflow") continue;
367
- const src = join4(templateSkillsDir, skill);
368
- if (await pathExists(src)) {
369
- await replaceDirectory(src, join4(skillsDir, skill));
370
- }
371
- }
372
- if (tier === "cloud") {
373
- for (const skill of CLOUD_ONLY_SKILLS) {
374
- const src = join4(templateSkillsDir, skill);
375
- if (await pathExists(src)) {
376
- await replaceDirectory(src, join4(skillsDir, skill));
377
- }
378
- }
379
- }
380
358
  const readmeSrc = join4(templateSkillsDir, "README.md");
381
359
  if (await pathExists(readmeSrc)) {
382
360
  await copyFile(readmeSrc, join4(skillsDir, "README.md"));
383
361
  }
384
362
  }
385
- async function replaceOwnedSkills(templateDir, targetDir, tier) {
363
+ async function replaceOwnedSkills(templateDir, targetDir, _tier) {
386
364
  const skillsDir = join4(targetDir, ".claude", "skills");
387
365
  const templateSkillsDir = join4(templateDir, ".claude", "skills");
388
366
  const { rm: rm6 } = await import("fs/promises");
389
- for (const skill of CORE_SKILLS) {
390
- const src = join4(templateSkillsDir, skill);
391
- if (await pathExists(src)) {
392
- await replaceDirectory(src, join4(skillsDir, skill));
393
- }
394
- }
395
- for (const skill of CLOUD_ONLY_SKILLS) {
396
- const dest = join4(skillsDir, skill);
397
- if (tier === "cloud") {
398
- const src = join4(templateSkillsDir, skill);
399
- if (await pathExists(src)) {
400
- await replaceDirectory(src, dest);
401
- }
402
- } else if (await pathExists(dest)) {
403
- await rm6(dest, { recursive: true, force: true });
404
- }
405
- }
406
- const activeMech = MECHANISM_SKILLS[tier];
407
- const inactiveMech = tier === "local" ? MECHANISM_SKILLS.cloud : MECHANISM_SKILLS.local;
408
- const inactivePath = join4(skillsDir, inactiveMech);
409
- if (await pathExists(inactivePath)) {
410
- await rm6(inactivePath, { recursive: true, force: true });
411
- }
412
367
  await replaceDirectory(
413
- join4(templateSkillsDir, activeMech),
414
- join4(skillsDir, activeMech)
368
+ join4(templateSkillsDir, OWNED_SKILL),
369
+ join4(skillsDir, OWNED_SKILL)
415
370
  );
371
+ for (const legacy of LEGACY_SKILLS) {
372
+ const legacyPath = join4(skillsDir, legacy);
373
+ if (await pathExists(legacyPath)) {
374
+ await rm6(legacyPath, { recursive: true, force: true });
375
+ }
376
+ }
416
377
  const readmeSrc = join4(templateSkillsDir, "README.md");
417
378
  if (await pathExists(readmeSrc)) {
418
379
  await copyFile(readmeSrc, join4(skillsDir, "README.md"));
@@ -426,50 +387,34 @@ async function copyCursorRules(targetDir) {
426
387
  targetDir,
427
388
  ".claude",
428
389
  "skills",
429
- "flydocs-workflow",
390
+ OWNED_SKILL,
430
391
  "cursor-rule.mdc"
431
392
  );
432
393
  if (await pathExists(workflowRule)) {
433
394
  await copyFile(workflowRule, join4(rulesDir, "flydocs-workflow.mdc"));
434
395
  }
435
- for (const mech of ["flydocs-local", "flydocs-cloud"]) {
436
- const mechRule = join4(
437
- targetDir,
438
- ".claude",
439
- "skills",
440
- mech,
441
- "cursor-rule.mdc"
442
- );
443
- if (await pathExists(mechRule)) {
444
- await copyFile(mechRule, join4(rulesDir, "flydocs-mechanism.mdc"));
396
+ const { rm: rm6 } = await import("fs/promises");
397
+ for (const legacy of ["flydocs-mechanism.mdc", "flydocs-context7.mdc"]) {
398
+ const legacyRule = join4(rulesDir, legacy);
399
+ if (await pathExists(legacyRule)) {
400
+ await rm6(legacyRule, { force: true });
445
401
  }
446
402
  }
447
- const context7Rule = join4(
448
- targetDir,
449
- ".claude",
450
- "skills",
451
- "flydocs-context7",
452
- "cursor-rule.mdc"
453
- );
454
- if (await pathExists(context7Rule)) {
455
- await copyFile(context7Rule, join4(rulesDir, "flydocs-context7.mdc"));
456
- }
457
403
  }
458
- var CORE_SKILLS, CLOUD_ONLY_SKILLS, MECHANISM_SKILLS;
404
+ var OWNED_SKILL, LEGACY_SKILLS;
459
405
  var init_skills = __esm({
460
406
  "src/lib/skills.ts"() {
461
407
  "use strict";
462
408
  init_fs_ops();
463
- CORE_SKILLS = [
464
- "flydocs-workflow",
409
+ OWNED_SKILL = "flydocs-workflow";
410
+ LEGACY_SKILLS = [
411
+ "flydocs-cloud",
412
+ "flydocs-local",
465
413
  "flydocs-context-graph",
466
- "flydocs-context7"
414
+ "flydocs-context7",
415
+ "flydocs-figma",
416
+ "flydocs-estimates"
467
417
  ];
468
- CLOUD_ONLY_SKILLS = ["flydocs-figma", "flydocs-estimates"];
469
- MECHANISM_SKILLS = {
470
- local: "flydocs-local",
471
- cloud: "flydocs-cloud"
472
- };
473
418
  }
474
419
  });
475
420
 
@@ -711,7 +656,9 @@ import { join as join7 } from "path";
711
656
  async function runManifestGeneration(targetDir) {
712
657
  const scriptPath = join7(
713
658
  targetDir,
714
- ".flydocs",
659
+ ".claude",
660
+ "skills",
661
+ "flydocs-workflow",
715
662
  "scripts",
716
663
  "generate_manifest.py"
717
664
  );
@@ -731,7 +678,7 @@ async function runContextGraphBuild(targetDir) {
731
678
  targetDir,
732
679
  ".claude",
733
680
  "skills",
734
- "flydocs-context-graph",
681
+ "flydocs-workflow",
735
682
  "scripts",
736
683
  "graph_build.py"
737
684
  );
@@ -1332,10 +1279,19 @@ async function scanDeprecated(targetDir) {
1332
1279
  found.push(dir);
1333
1280
  }
1334
1281
  }
1335
- for (const hook of DEPRECATED_HOOKS) {
1336
- const p = join10(targetDir, ".flydocs", "hooks", hook);
1337
- if (await pathExists(p)) {
1338
- found.push(`.flydocs/hooks/${hook}`);
1282
+ const foundFlydocsDirs = /* @__PURE__ */ new Set();
1283
+ for (const dir of DEPRECATED_FLYDOCS_DIRS) {
1284
+ if (await pathExists(join10(targetDir, dir))) {
1285
+ found.push(dir);
1286
+ foundFlydocsDirs.add(dir);
1287
+ }
1288
+ }
1289
+ if (!foundFlydocsDirs.has(".flydocs/hooks")) {
1290
+ for (const hook of DEPRECATED_HOOKS) {
1291
+ const p = join10(targetDir, ".flydocs", "hooks", hook);
1292
+ if (await pathExists(p)) {
1293
+ found.push(`.flydocs/hooks/${hook}`);
1294
+ }
1339
1295
  }
1340
1296
  }
1341
1297
  for (const rule of DEPRECATED_CURSOR_RULES) {
@@ -1420,7 +1376,7 @@ async function promptCleanup(targetDir, paths) {
1420
1376
  printStatus(`Deleted: ${p}`);
1421
1377
  }
1422
1378
  }
1423
- var DEPRECATED_DIRS, DEPRECATED_FILES, DEPRECATED_SKILLS, DEPRECATED_RULES_DIR, DEPRECATED_HOOKS, DEPRECATED_CURSOR_RULES, DEPRECATED_CURSOR_RULE_DIRS, DEPRECATED_COMMANDS;
1379
+ var DEPRECATED_DIRS, DEPRECATED_FILES, DEPRECATED_SKILLS, DEPRECATED_RULES_DIR, DEPRECATED_FLYDOCS_DIRS, DEPRECATED_HOOKS, DEPRECATED_CURSOR_RULES, DEPRECATED_CURSOR_RULE_DIRS, DEPRECATED_COMMANDS;
1424
1380
  var init_deprecated = __esm({
1425
1381
  "src/lib/deprecated.ts"() {
1426
1382
  "use strict";
@@ -1436,10 +1392,14 @@ var init_deprecated = __esm({
1436
1392
  "figma-mcp"
1437
1393
  ];
1438
1394
  DEPRECATED_RULES_DIR = [".flydocs/rules"];
1395
+ DEPRECATED_FLYDOCS_DIRS = [".flydocs/hooks", ".flydocs/scripts"];
1439
1396
  DEPRECATED_HOOKS = [
1440
1397
  "linear-auto-approve.py",
1441
1398
  "session-end.py",
1442
- "prefer-scripts.py"
1399
+ "prefer-scripts.py",
1400
+ "auto-approve.py",
1401
+ "post-edit.py",
1402
+ "prompt-submit.py"
1443
1403
  ];
1444
1404
  DEPRECATED_CURSOR_RULES = [
1445
1405
  "designer-agent.mdc",
@@ -1529,6 +1489,7 @@ var init_gitignore = __esm({
1529
1489
  ".flydocs/backup-*/",
1530
1490
  ".flydocs/me.json",
1531
1491
  ".flydocs/validation-cache.json",
1492
+ ".flydocs/integrity-cache.json",
1532
1493
  ".flydocs/session/",
1533
1494
  "flydocs/context/graph.json"
1534
1495
  ];
@@ -1543,6 +1504,7 @@ var init_gitignore = __esm({
1543
1504
  .flydocs/backup-*/
1544
1505
  .flydocs/me.json
1545
1506
  .flydocs/validation-cache.json
1507
+ .flydocs/integrity-cache.json
1546
1508
  .flydocs/session/
1547
1509
  flydocs/context/graph.json
1548
1510
 
@@ -1904,6 +1866,28 @@ async function fetchWorkspaces(apiKey) {
1904
1866
  const data = await response.json();
1905
1867
  return data;
1906
1868
  }
1869
+ async function fetchMe(apiKey) {
1870
+ const baseUrl = process.env.FLYDOCS_RELAY_URL?.replace(/\/$/, "") ?? "https://app.flydocs.ai/api/relay";
1871
+ const response = await fetch(`${baseUrl}/auth/me`, {
1872
+ method: "GET",
1873
+ headers: {
1874
+ Authorization: `Bearer ${apiKey}`
1875
+ },
1876
+ signal: AbortSignal.timeout(15e3)
1877
+ });
1878
+ if (!response.ok) {
1879
+ throw new Error(`Failed to fetch user identity: ${response.status}`);
1880
+ }
1881
+ const data = await response.json();
1882
+ return {
1883
+ displayName: data.displayName ?? null,
1884
+ email: data.email ?? null,
1885
+ providerId: data.providerId ?? null,
1886
+ provider: data.provider ?? null,
1887
+ providerIdentities: data.providerIdentities ?? [],
1888
+ preferences: data.preferences ?? {}
1889
+ };
1890
+ }
1907
1891
  async function validateLinearKey(apiKey) {
1908
1892
  const response = await fetch("https://api.linear.app/graphql", {
1909
1893
  method: "POST",
@@ -1951,6 +1935,36 @@ var init_api_key = __esm({
1951
1935
  }
1952
1936
  });
1953
1937
 
1938
+ // src/lib/integrity.ts
1939
+ import { readFile as readFile11, writeFile as writeFile8 } from "fs/promises";
1940
+ import { join as join15 } from "path";
1941
+ async function generateIntegrity(targetDir, version) {
1942
+ const manifestPath = join15(targetDir, ".flydocs", "manifest.json");
1943
+ if (!await pathExists(manifestPath)) return;
1944
+ const manifest = JSON.parse(await readFile11(manifestPath, "utf-8"));
1945
+ const ownership = manifest.ownership;
1946
+ if (!ownership) return;
1947
+ const ownedDirs = ownership.owned_directories?.paths ?? [];
1948
+ const ownedFiles = ownership.owned_files?.paths ?? [];
1949
+ const integrity = {
1950
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1951
+ version,
1952
+ ownedFiles,
1953
+ ownedDirectories: ownedDirs
1954
+ };
1955
+ await writeFile8(
1956
+ join15(targetDir, ".flydocs", "integrity.json"),
1957
+ JSON.stringify(integrity, null, 2) + "\n",
1958
+ "utf-8"
1959
+ );
1960
+ }
1961
+ var init_integrity = __esm({
1962
+ "src/lib/integrity.ts"() {
1963
+ "use strict";
1964
+ init_fs_ops();
1965
+ }
1966
+ });
1967
+
1954
1968
  // src/commands/install.ts
1955
1969
  var install_exports = {};
1956
1970
  __export(install_exports, {
@@ -1958,8 +1972,8 @@ __export(install_exports, {
1958
1972
  });
1959
1973
  import { defineCommand } from "citty";
1960
1974
  import { resolve as resolve2 } from "path";
1961
- import { join as join15 } from "path";
1962
- import { mkdir as mkdir7 } from "fs/promises";
1975
+ import { join as join16 } from "path";
1976
+ import { mkdir as mkdir7, writeFile as writeFile9 } from "fs/promises";
1963
1977
  import { confirm as confirm2, select, text, isCancel as isCancel3, cancel as cancel2 } from "@clack/prompts";
1964
1978
  import pc6 from "picocolors";
1965
1979
  var install_default;
@@ -1980,6 +1994,7 @@ var init_install = __esm({
1980
1994
  init_update_check();
1981
1995
  init_telemetry();
1982
1996
  init_api_key();
1997
+ init_integrity();
1983
1998
  install_default = defineCommand({
1984
1999
  meta: {
1985
2000
  name: "install",
@@ -2041,7 +2056,7 @@ var init_install = __esm({
2041
2056
  process.exit(1);
2042
2057
  }
2043
2058
  tier = args.tier;
2044
- } else if (await pathExists(join15(targetDir, ".flydocs", "config.json"))) {
2059
+ } else if (await pathExists(join16(targetDir, ".flydocs", "config.json"))) {
2045
2060
  try {
2046
2061
  const existing = await readConfig(targetDir);
2047
2062
  if (existing.tier) {
@@ -2092,6 +2107,7 @@ var init_install = __esm({
2092
2107
  await capture("install_tier_selected", { tier });
2093
2108
  let selectedWorkspaceId = null;
2094
2109
  let selectedWorkspaceName = null;
2110
+ let apiKey = null;
2095
2111
  if (tier === "cloud") {
2096
2112
  console.log();
2097
2113
  console.log(` ${pc6.bold("Connect to FlyDocs Cloud")}`);
@@ -2115,7 +2131,7 @@ var init_install = __esm({
2115
2131
  cancel2("Installation cancelled.");
2116
2132
  process.exit(0);
2117
2133
  }
2118
- const apiKey = keyInput.trim();
2134
+ apiKey = keyInput.trim();
2119
2135
  printInfo("Validating API key...");
2120
2136
  try {
2121
2137
  const result = await validateRelayKey(apiKey);
@@ -2175,10 +2191,36 @@ var init_install = __esm({
2175
2191
  }
2176
2192
  }
2177
2193
  let skipConfigOverwrite = false;
2178
- if (!await pathExists(join15(targetDir, ".git"))) {
2194
+ if (!await pathExists(join16(targetDir, ".git"))) {
2179
2195
  printWarning("No git repository detected. Run git init when ready.");
2180
2196
  }
2181
2197
  await ensureDirectories(targetDir, tier);
2198
+ if (tier === "cloud" && apiKey) {
2199
+ try {
2200
+ const me = await fetchMe(apiKey);
2201
+ const meData = {
2202
+ displayName: me.displayName,
2203
+ email: me.email,
2204
+ providerId: me.providerId,
2205
+ provider: me.provider,
2206
+ providerIdentities: me.providerIdentities,
2207
+ preferences: me.preferences
2208
+ };
2209
+ const mePath = join16(targetDir, ".flydocs", "me.json");
2210
+ await writeFile9(
2211
+ mePath,
2212
+ JSON.stringify(meData, null, 2) + "\n",
2213
+ "utf-8"
2214
+ );
2215
+ if (me.displayName) {
2216
+ printStatus(`Identity: ${pc6.bold(me.displayName)}`);
2217
+ }
2218
+ } catch {
2219
+ printWarning(
2220
+ "Could not fetch user identity. Run /flydocs-setup to configure later."
2221
+ );
2222
+ }
2223
+ }
2182
2224
  const existingFiles = await detectExistingConfigs(targetDir);
2183
2225
  if (existingFiles.length > 0) {
2184
2226
  console.log();
@@ -2227,31 +2269,29 @@ var init_install = __esm({
2227
2269
  }
2228
2270
  console.log("Installing framework files...");
2229
2271
  await replaceDirectory(
2230
- join15(templateDir, ".flydocs", "templates"),
2231
- join15(targetDir, ".flydocs", "templates")
2232
- );
2233
- await replaceDirectory(
2234
- join15(templateDir, ".flydocs", "hooks"),
2235
- join15(targetDir, ".flydocs", "hooks")
2272
+ join16(templateDir, ".flydocs", "templates"),
2273
+ join16(targetDir, ".flydocs", "templates")
2236
2274
  );
2237
2275
  await replaceDirectory(
2238
- join15(templateDir, ".flydocs", "scripts"),
2239
- join15(targetDir, ".flydocs", "scripts")
2276
+ join16(templateDir, ".claude", "hooks"),
2277
+ join16(targetDir, ".claude", "hooks")
2240
2278
  );
2241
2279
  await copyFile(
2242
- join15(templateDir, ".flydocs", "version"),
2243
- join15(targetDir, ".flydocs", "version")
2280
+ join16(templateDir, ".flydocs", "version"),
2281
+ join16(targetDir, ".flydocs", "version")
2244
2282
  );
2245
- const manifestSrc = join15(templateDir, "manifest.json");
2283
+ const manifestSrc = join16(templateDir, "manifest.json");
2246
2284
  if (await pathExists(manifestSrc)) {
2247
- await copyFile(manifestSrc, join15(targetDir, ".flydocs", "manifest.json"));
2285
+ await copyFile(manifestSrc, join16(targetDir, ".flydocs", "manifest.json"));
2248
2286
  }
2249
- const changelogSrc = join15(templateDir, "CHANGELOG.md");
2287
+ const changelogSrc = join16(templateDir, "CHANGELOG.md");
2250
2288
  if (await pathExists(changelogSrc)) {
2251
- await copyFile(changelogSrc, join15(targetDir, ".flydocs", "CHANGELOG.md"));
2289
+ await copyFile(changelogSrc, join16(targetDir, ".flydocs", "CHANGELOG.md"));
2252
2290
  }
2253
- printStatus(".flydocs/templates, hooks, version, manifest, changelog");
2254
- const configPath = join15(targetDir, ".flydocs", "config.json");
2291
+ printStatus(
2292
+ ".flydocs/templates, .claude/hooks, version, manifest, changelog"
2293
+ );
2294
+ const configPath = join16(targetDir, ".flydocs", "config.json");
2255
2295
  if (!await pathExists(configPath)) {
2256
2296
  const config = await createFreshConfig(templateDir, version, tier);
2257
2297
  if (selectedWorkspaceId) {
@@ -2327,20 +2367,20 @@ var init_install = __esm({
2327
2367
  }
2328
2368
  await capture("install_agents_chosen", { install_agents: installAgents });
2329
2369
  if (installAgents) {
2330
- const claudeAgentsSrc = join15(templateDir, ".claude", "agents");
2370
+ const claudeAgentsSrc = join16(templateDir, ".claude", "agents");
2331
2371
  if (await pathExists(claudeAgentsSrc)) {
2332
- await mkdir7(join15(targetDir, ".claude", "agents"), { recursive: true });
2372
+ await mkdir7(join16(targetDir, ".claude", "agents"), { recursive: true });
2333
2373
  await copyDirectoryContents(
2334
2374
  claudeAgentsSrc,
2335
- join15(targetDir, ".claude", "agents")
2375
+ join16(targetDir, ".claude", "agents")
2336
2376
  );
2337
2377
  }
2338
- const cursorAgentsSrc = join15(templateDir, ".cursor", "agents");
2378
+ const cursorAgentsSrc = join16(templateDir, ".cursor", "agents");
2339
2379
  if (await pathExists(cursorAgentsSrc)) {
2340
- await mkdir7(join15(targetDir, ".cursor", "agents"), { recursive: true });
2380
+ await mkdir7(join16(targetDir, ".cursor", "agents"), { recursive: true });
2341
2381
  await copyDirectoryContents(
2342
2382
  cursorAgentsSrc,
2343
- join15(targetDir, ".cursor", "agents")
2383
+ join16(targetDir, ".cursor", "agents")
2344
2384
  );
2345
2385
  }
2346
2386
  printStatus("Sub-agents installed (.claude/agents, .cursor/agents)");
@@ -2350,30 +2390,30 @@ var init_install = __esm({
2350
2390
  console.log();
2351
2391
  console.log("Installing commands and settings...");
2352
2392
  await copyDirectoryContents(
2353
- join15(templateDir, ".claude", "commands"),
2354
- join15(targetDir, ".claude", "commands")
2393
+ join16(templateDir, ".claude", "commands"),
2394
+ join16(targetDir, ".claude", "commands")
2355
2395
  );
2356
2396
  if (!skipConfigOverwrite) {
2357
2397
  await copyFile(
2358
- join15(templateDir, ".claude", "CLAUDE.md"),
2359
- join15(targetDir, ".claude", "CLAUDE.md")
2398
+ join16(templateDir, ".claude", "CLAUDE.md"),
2399
+ join16(targetDir, ".claude", "CLAUDE.md")
2360
2400
  );
2361
2401
  await copyFile(
2362
- join15(templateDir, ".claude", "settings.json"),
2363
- join15(targetDir, ".claude", "settings.json")
2402
+ join16(templateDir, ".claude", "settings.json"),
2403
+ join16(targetDir, ".claude", "settings.json")
2364
2404
  );
2365
2405
  printStatus(".claude/ (commands, CLAUDE.md, settings)");
2366
2406
  } else {
2367
2407
  printStatus(".claude/ (commands only \u2014 existing config preserved)");
2368
2408
  }
2369
2409
  await copyDirectoryContents(
2370
- join15(templateDir, ".claude", "commands"),
2371
- join15(targetDir, ".cursor", "commands")
2410
+ join16(templateDir, ".claude", "commands"),
2411
+ join16(targetDir, ".cursor", "commands")
2372
2412
  );
2373
2413
  if (!skipConfigOverwrite) {
2374
2414
  await copyFile(
2375
- join15(templateDir, ".cursor", "hooks.json"),
2376
- join15(targetDir, ".cursor", "hooks.json")
2415
+ join16(templateDir, ".cursor", "hooks.json"),
2416
+ join16(targetDir, ".cursor", "hooks.json")
2377
2417
  );
2378
2418
  printStatus(".cursor/ (commands, hooks)");
2379
2419
  } else {
@@ -2383,8 +2423,8 @@ var init_install = __esm({
2383
2423
  printStatus(".cursor/rules/");
2384
2424
  if (!skipConfigOverwrite) {
2385
2425
  await copyFile(
2386
- join15(templateDir, "AGENTS.md"),
2387
- join15(targetDir, "AGENTS.md")
2426
+ join16(templateDir, "AGENTS.md"),
2427
+ join16(targetDir, "AGENTS.md")
2388
2428
  );
2389
2429
  printStatus("AGENTS.md");
2390
2430
  } else {
@@ -2392,44 +2432,46 @@ var init_install = __esm({
2392
2432
  }
2393
2433
  await runManifestGeneration(targetDir);
2394
2434
  await runContextGraphBuild(targetDir);
2435
+ await generateIntegrity(targetDir, version);
2436
+ printStatus("Install integrity recorded");
2395
2437
  console.log();
2396
2438
  console.log("Installing project templates...");
2397
2439
  const userFiles = [
2398
2440
  {
2399
- src: join15(templateDir, "flydocs", "context", "project.md"),
2400
- dest: join15(targetDir, "flydocs", "context", "project.md"),
2441
+ src: join16(templateDir, "flydocs", "context", "project.md"),
2442
+ dest: join16(targetDir, "flydocs", "context", "project.md"),
2401
2443
  label: "flydocs/context/project.md"
2402
2444
  },
2403
2445
  {
2404
- src: join15(templateDir, "flydocs", "knowledge", "INDEX.md"),
2405
- dest: join15(targetDir, "flydocs", "knowledge", "INDEX.md"),
2446
+ src: join16(templateDir, "flydocs", "knowledge", "INDEX.md"),
2447
+ dest: join16(targetDir, "flydocs", "knowledge", "INDEX.md"),
2406
2448
  label: "flydocs/knowledge/INDEX.md"
2407
2449
  },
2408
2450
  {
2409
- src: join15(templateDir, "flydocs", "knowledge", "README.md"),
2410
- dest: join15(targetDir, "flydocs", "knowledge", "README.md"),
2451
+ src: join16(templateDir, "flydocs", "knowledge", "README.md"),
2452
+ dest: join16(targetDir, "flydocs", "knowledge", "README.md"),
2411
2453
  label: "flydocs/knowledge/README.md"
2412
2454
  },
2413
2455
  {
2414
- src: join15(
2456
+ src: join16(
2415
2457
  templateDir,
2416
2458
  "flydocs",
2417
2459
  "knowledge",
2418
2460
  "product",
2419
2461
  "personas.md"
2420
2462
  ),
2421
- dest: join15(targetDir, "flydocs", "knowledge", "product", "personas.md"),
2463
+ dest: join16(targetDir, "flydocs", "knowledge", "product", "personas.md"),
2422
2464
  label: "flydocs/knowledge/product/personas.md"
2423
2465
  },
2424
2466
  {
2425
- src: join15(
2467
+ src: join16(
2426
2468
  templateDir,
2427
2469
  "flydocs",
2428
2470
  "knowledge",
2429
2471
  "product",
2430
2472
  "user-flows.md"
2431
2473
  ),
2432
- dest: join15(
2474
+ dest: join16(
2433
2475
  targetDir,
2434
2476
  "flydocs",
2435
2477
  "knowledge",
@@ -2439,14 +2481,14 @@ var init_install = __esm({
2439
2481
  label: "flydocs/knowledge/product/user-flows.md"
2440
2482
  },
2441
2483
  {
2442
- src: join15(
2484
+ src: join16(
2443
2485
  templateDir,
2444
2486
  "flydocs",
2445
2487
  "knowledge",
2446
2488
  "templates",
2447
2489
  "decision.md"
2448
2490
  ),
2449
- dest: join15(
2491
+ dest: join16(
2450
2492
  targetDir,
2451
2493
  "flydocs",
2452
2494
  "knowledge",
@@ -2456,14 +2498,14 @@ var init_install = __esm({
2456
2498
  label: "flydocs/knowledge/templates/decision.md"
2457
2499
  },
2458
2500
  {
2459
- src: join15(
2501
+ src: join16(
2460
2502
  templateDir,
2461
2503
  "flydocs",
2462
2504
  "knowledge",
2463
2505
  "templates",
2464
2506
  "feature.md"
2465
2507
  ),
2466
- dest: join15(
2508
+ dest: join16(
2467
2509
  targetDir,
2468
2510
  "flydocs",
2469
2511
  "knowledge",
@@ -2473,23 +2515,23 @@ var init_install = __esm({
2473
2515
  label: "flydocs/knowledge/templates/feature.md"
2474
2516
  },
2475
2517
  {
2476
- src: join15(templateDir, "flydocs", "knowledge", "templates", "note.md"),
2477
- dest: join15(targetDir, "flydocs", "knowledge", "templates", "note.md"),
2518
+ src: join16(templateDir, "flydocs", "knowledge", "templates", "note.md"),
2519
+ dest: join16(targetDir, "flydocs", "knowledge", "templates", "note.md"),
2478
2520
  label: "flydocs/knowledge/templates/note.md"
2479
2521
  },
2480
2522
  {
2481
- src: join15(templateDir, "flydocs", "design-system", "README.md"),
2482
- dest: join15(targetDir, "flydocs", "design-system", "README.md"),
2523
+ src: join16(templateDir, "flydocs", "design-system", "README.md"),
2524
+ dest: join16(targetDir, "flydocs", "design-system", "README.md"),
2483
2525
  label: "flydocs/design-system/README.md"
2484
2526
  },
2485
2527
  {
2486
- src: join15(
2528
+ src: join16(
2487
2529
  templateDir,
2488
2530
  "flydocs",
2489
2531
  "design-system",
2490
2532
  "component-patterns.md"
2491
2533
  ),
2492
- dest: join15(
2534
+ dest: join16(
2493
2535
  targetDir,
2494
2536
  "flydocs",
2495
2537
  "design-system",
@@ -2498,13 +2540,13 @@ var init_install = __esm({
2498
2540
  label: "flydocs/design-system/component-patterns.md"
2499
2541
  },
2500
2542
  {
2501
- src: join15(templateDir, "flydocs", "design-system", "token-mapping.md"),
2502
- dest: join15(targetDir, "flydocs", "design-system", "token-mapping.md"),
2543
+ src: join16(templateDir, "flydocs", "design-system", "token-mapping.md"),
2544
+ dest: join16(targetDir, "flydocs", "design-system", "token-mapping.md"),
2503
2545
  label: "flydocs/design-system/token-mapping.md"
2504
2546
  },
2505
2547
  {
2506
- src: join15(templateDir, "flydocs", "README.md"),
2507
- dest: join15(targetDir, "flydocs", "README.md"),
2548
+ src: join16(templateDir, "flydocs", "README.md"),
2549
+ dest: join16(targetDir, "flydocs", "README.md"),
2508
2550
  label: "flydocs/README.md"
2509
2551
  }
2510
2552
  ];
@@ -2518,9 +2560,9 @@ var init_install = __esm({
2518
2560
  }
2519
2561
  }
2520
2562
  }
2521
- const envExampleSrc = join15(templateDir, ".env.example");
2563
+ const envExampleSrc = join16(templateDir, ".env.example");
2522
2564
  if (await pathExists(envExampleSrc)) {
2523
- await copyFile(envExampleSrc, join15(targetDir, ".env.example"));
2565
+ await copyFile(envExampleSrc, join16(targetDir, ".env.example"));
2524
2566
  printStatus(".env.example");
2525
2567
  }
2526
2568
  await ensureGitignore(targetDir);
@@ -2698,8 +2740,8 @@ __export(update_exports, {
2698
2740
  default: () => update_default
2699
2741
  });
2700
2742
  import { defineCommand as defineCommand2 } from "citty";
2701
- import { resolve as resolve3, join as join16 } from "path";
2702
- import { mkdir as mkdir8, cp as cp2, readFile as readFile11, readdir as readdir3, rm as rm4 } from "fs/promises";
2743
+ import { resolve as resolve3, join as join17 } from "path";
2744
+ import { mkdir as mkdir8, cp as cp2, readFile as readFile12, readdir as readdir4, rm as rm4 } from "fs/promises";
2703
2745
  import { select as select2, text as text2, confirm as confirm3, isCancel as isCancel4, cancel as cancel3 } from "@clack/prompts";
2704
2746
  import pc7 from "picocolors";
2705
2747
  var update_default;
@@ -2719,6 +2761,7 @@ var init_update = __esm({
2719
2761
  init_post_install();
2720
2762
  init_update_check();
2721
2763
  init_telemetry();
2764
+ init_integrity();
2722
2765
  update_default = defineCommand2({
2723
2766
  meta: {
2724
2767
  name: "update",
@@ -2806,9 +2849,9 @@ var init_update = __esm({
2806
2849
  }
2807
2850
  targetDir = resolve3(targetDir);
2808
2851
  process.chdir(targetDir);
2809
- const hasVersion = await pathExists(join16(targetDir, ".flydocs", "version"));
2852
+ const hasVersion = await pathExists(join17(targetDir, ".flydocs", "version"));
2810
2853
  const hasConfig = await pathExists(
2811
- join16(targetDir, ".flydocs", "config.json")
2854
+ join17(targetDir, ".flydocs", "config.json")
2812
2855
  );
2813
2856
  if (!hasVersion && !hasConfig) {
2814
2857
  printError(`Not a FlyDocs project: ${targetDir}`);
@@ -2819,8 +2862,8 @@ var init_update = __esm({
2819
2862
  console.log();
2820
2863
  let currentVersion = "0.1.0";
2821
2864
  if (hasVersion) {
2822
- const vContent = await readFile11(
2823
- join16(targetDir, ".flydocs", "version"),
2865
+ const vContent = await readFile12(
2866
+ join17(targetDir, ".flydocs", "version"),
2824
2867
  "utf-8"
2825
2868
  );
2826
2869
  currentVersion = vContent.trim();
@@ -2854,7 +2897,7 @@ var init_update = __esm({
2854
2897
  });
2855
2898
  console.log(`Updating: v${currentVersion} \u2192 v${version}`);
2856
2899
  console.log();
2857
- const changelogPath = join16(templateDir, "CHANGELOG.md");
2900
+ const changelogPath = join17(templateDir, "CHANGELOG.md");
2858
2901
  const whatsNew = await getWhatsNew(changelogPath, currentVersion, version);
2859
2902
  if (whatsNew.length > 0) {
2860
2903
  console.log(pc7.cyan("What's new:"));
@@ -2866,29 +2909,29 @@ var init_update = __esm({
2866
2909
  }
2867
2910
  const now = /* @__PURE__ */ new Date();
2868
2911
  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")}`;
2869
- const backupDir = join16(targetDir, ".flydocs", `backup-${ts}`);
2912
+ const backupDir = join17(targetDir, ".flydocs", `backup-${ts}`);
2870
2913
  await mkdir8(backupDir, { recursive: true });
2871
2914
  if (hasConfig) {
2872
2915
  await cp2(
2873
- join16(targetDir, ".flydocs", "config.json"),
2874
- join16(backupDir, "config.json")
2916
+ join17(targetDir, ".flydocs", "config.json"),
2917
+ join17(backupDir, "config.json")
2875
2918
  );
2876
2919
  printStatus(`Config backed up to .flydocs/backup-${ts}/`);
2877
2920
  }
2878
2921
  try {
2879
- const flydocsDir = join16(targetDir, ".flydocs");
2880
- const entries = await readdir3(flydocsDir);
2922
+ const flydocsDir = join17(targetDir, ".flydocs");
2923
+ const entries = await readdir4(flydocsDir);
2881
2924
  const backups = entries.filter((e) => e.startsWith("backup-")).sort();
2882
2925
  if (backups.length > 3) {
2883
2926
  const toRemove = backups.slice(0, backups.length - 3);
2884
2927
  for (const old of toRemove) {
2885
- await rm4(join16(flydocsDir, old), { recursive: true, force: true });
2928
+ await rm4(join17(flydocsDir, old), { recursive: true, force: true });
2886
2929
  }
2887
2930
  }
2888
2931
  } catch {
2889
2932
  }
2890
2933
  let preserved = {
2891
- tier: "cloud",
2934
+ tier: "local",
2892
2935
  setupComplete: false,
2893
2936
  workspaceId: null,
2894
2937
  configVersion: void 0,
@@ -2896,6 +2939,7 @@ var init_update = __esm({
2896
2939
  issueLabels: {},
2897
2940
  detectedStack: {},
2898
2941
  skills: {},
2942
+ topology: void 0,
2899
2943
  designSystem: null,
2900
2944
  aiLabor: {}
2901
2945
  };
@@ -2920,20 +2964,17 @@ var init_update = __esm({
2920
2964
  await ensureDirectories(targetDir, effectiveTier);
2921
2965
  console.log("Replacing framework directories...");
2922
2966
  await replaceDirectory(
2923
- join16(templateDir, ".flydocs", "templates"),
2924
- join16(targetDir, ".flydocs", "templates")
2925
- );
2926
- await replaceDirectory(
2927
- join16(templateDir, ".flydocs", "hooks"),
2928
- join16(targetDir, ".flydocs", "hooks")
2967
+ join17(templateDir, ".flydocs", "templates"),
2968
+ join17(targetDir, ".flydocs", "templates")
2929
2969
  );
2970
+ printStatus(".flydocs/templates");
2930
2971
  await replaceDirectory(
2931
- join16(templateDir, ".flydocs", "scripts"),
2932
- join16(targetDir, ".flydocs", "scripts")
2972
+ join17(templateDir, ".claude", "hooks"),
2973
+ join17(targetDir, ".claude", "hooks")
2933
2974
  );
2934
- printStatus(".flydocs/templates, hooks, scripts");
2975
+ printStatus(".claude/hooks");
2935
2976
  const hasExistingAgents = await pathExists(
2936
- join16(targetDir, ".claude", "agents")
2977
+ join17(targetDir, ".claude", "agents")
2937
2978
  );
2938
2979
  let installAgents;
2939
2980
  if (args.yes) {
@@ -2965,20 +3006,20 @@ var init_update = __esm({
2965
3006
  }
2966
3007
  }
2967
3008
  if (installAgents) {
2968
- const claudeAgentsSrc = join16(templateDir, ".claude", "agents");
3009
+ const claudeAgentsSrc = join17(templateDir, ".claude", "agents");
2969
3010
  if (await pathExists(claudeAgentsSrc)) {
2970
- await mkdir8(join16(targetDir, ".claude", "agents"), { recursive: true });
3011
+ await mkdir8(join17(targetDir, ".claude", "agents"), { recursive: true });
2971
3012
  await copyDirectoryContents(
2972
3013
  claudeAgentsSrc,
2973
- join16(targetDir, ".claude", "agents")
3014
+ join17(targetDir, ".claude", "agents")
2974
3015
  );
2975
3016
  }
2976
- const cursorAgentsSrc = join16(templateDir, ".cursor", "agents");
3017
+ const cursorAgentsSrc = join17(templateDir, ".cursor", "agents");
2977
3018
  if (await pathExists(cursorAgentsSrc)) {
2978
- await mkdir8(join16(targetDir, ".cursor", "agents"), { recursive: true });
3019
+ await mkdir8(join17(targetDir, ".cursor", "agents"), { recursive: true });
2979
3020
  await copyDirectoryContents(
2980
3021
  cursorAgentsSrc,
2981
- join16(targetDir, ".cursor", "agents")
3022
+ join17(targetDir, ".cursor", "agents")
2982
3023
  );
2983
3024
  }
2984
3025
  printStatus(
@@ -2992,47 +3033,47 @@ var init_update = __esm({
2992
3033
  console.log();
2993
3034
  console.log("Replacing framework files...");
2994
3035
  await copyFile(
2995
- join16(templateDir, ".claude", "CLAUDE.md"),
2996
- join16(targetDir, ".claude", "CLAUDE.md")
3036
+ join17(templateDir, ".claude", "CLAUDE.md"),
3037
+ join17(targetDir, ".claude", "CLAUDE.md")
2997
3038
  );
2998
3039
  await copyFile(
2999
- join16(templateDir, ".claude", "settings.json"),
3000
- join16(targetDir, ".claude", "settings.json")
3040
+ join17(templateDir, ".claude", "settings.json"),
3041
+ join17(targetDir, ".claude", "settings.json")
3001
3042
  );
3002
3043
  printStatus(".claude/CLAUDE.md, settings.json");
3003
3044
  await copyDirectoryContents(
3004
- join16(templateDir, ".claude", "commands"),
3005
- join16(targetDir, ".claude", "commands")
3045
+ join17(templateDir, ".claude", "commands"),
3046
+ join17(targetDir, ".claude", "commands")
3006
3047
  );
3007
3048
  await copyDirectoryContents(
3008
- join16(templateDir, ".claude", "commands"),
3009
- join16(targetDir, ".cursor", "commands")
3049
+ join17(templateDir, ".claude", "commands"),
3050
+ join17(targetDir, ".cursor", "commands")
3010
3051
  );
3011
3052
  printStatus(".claude/commands, .cursor/commands");
3012
- const skillsReadmeSrc = join16(templateDir, ".claude", "skills", "README.md");
3053
+ const skillsReadmeSrc = join17(templateDir, ".claude", "skills", "README.md");
3013
3054
  if (await pathExists(skillsReadmeSrc)) {
3014
3055
  await copyFile(
3015
3056
  skillsReadmeSrc,
3016
- join16(targetDir, ".claude", "skills", "README.md")
3057
+ join17(targetDir, ".claude", "skills", "README.md")
3017
3058
  );
3018
3059
  }
3019
3060
  printStatus(".claude/skills/README.md");
3020
3061
  await copyFile(
3021
- join16(templateDir, ".cursor", "hooks.json"),
3022
- join16(targetDir, ".cursor", "hooks.json")
3062
+ join17(templateDir, ".cursor", "hooks.json"),
3063
+ join17(targetDir, ".cursor", "hooks.json")
3023
3064
  );
3024
3065
  printStatus(".cursor/hooks.json");
3025
3066
  await copyFile(
3026
- join16(templateDir, "AGENTS.md"),
3027
- join16(targetDir, "AGENTS.md")
3067
+ join17(templateDir, "AGENTS.md"),
3068
+ join17(targetDir, "AGENTS.md")
3028
3069
  );
3029
3070
  printStatus("AGENTS.md");
3030
- const envExampleSrc = join16(templateDir, ".env.example");
3071
+ const envExampleSrc = join17(templateDir, ".env.example");
3031
3072
  if (await pathExists(envExampleSrc)) {
3032
- await copyFile(envExampleSrc, join16(targetDir, ".env.example"));
3073
+ await copyFile(envExampleSrc, join17(targetDir, ".env.example"));
3033
3074
  printStatus(".env.example");
3034
3075
  }
3035
- const knowledgeTemplatesDir = join16(
3076
+ const knowledgeTemplatesDir = join17(
3036
3077
  targetDir,
3037
3078
  "flydocs",
3038
3079
  "knowledge",
@@ -3042,8 +3083,8 @@ var init_update = __esm({
3042
3083
  await mkdir8(knowledgeTemplatesDir, { recursive: true });
3043
3084
  }
3044
3085
  for (const tmpl of ["decision.md", "feature.md", "note.md"]) {
3045
- const src = join16(templateDir, "flydocs", "knowledge", "templates", tmpl);
3046
- const dest = join16(knowledgeTemplatesDir, tmpl);
3086
+ const src = join17(templateDir, "flydocs", "knowledge", "templates", tmpl);
3087
+ const dest = join17(knowledgeTemplatesDir, tmpl);
3047
3088
  if (await pathExists(src) && !await pathExists(dest)) {
3048
3089
  await copyFile(src, dest);
3049
3090
  }
@@ -3070,20 +3111,22 @@ var init_update = __esm({
3070
3111
  printWarning("Config merge failed \u2014 config.json preserved as-is");
3071
3112
  }
3072
3113
  await copyFile(
3073
- join16(templateDir, ".flydocs", "version"),
3074
- join16(targetDir, ".flydocs", "version")
3114
+ join17(templateDir, ".flydocs", "version"),
3115
+ join17(targetDir, ".flydocs", "version")
3075
3116
  );
3076
3117
  printStatus(`.flydocs/version \u2192 ${version}`);
3077
- const clSrc = join16(templateDir, "CHANGELOG.md");
3118
+ const clSrc = join17(templateDir, "CHANGELOG.md");
3078
3119
  if (await pathExists(clSrc)) {
3079
- await copyFile(clSrc, join16(targetDir, ".flydocs", "CHANGELOG.md"));
3120
+ await copyFile(clSrc, join17(targetDir, ".flydocs", "CHANGELOG.md"));
3080
3121
  printStatus(".flydocs/CHANGELOG.md");
3081
3122
  }
3082
- const mfSrc = join16(templateDir, "manifest.json");
3123
+ const mfSrc = join17(templateDir, "manifest.json");
3083
3124
  if (await pathExists(mfSrc)) {
3084
- await copyFile(mfSrc, join16(targetDir, ".flydocs", "manifest.json"));
3125
+ await copyFile(mfSrc, join17(targetDir, ".flydocs", "manifest.json"));
3085
3126
  printStatus(".flydocs/manifest.json");
3086
3127
  }
3128
+ await generateIntegrity(targetDir, version);
3129
+ printStatus("Install integrity recorded");
3087
3130
  console.log();
3088
3131
  console.log("Detecting project stack...");
3089
3132
  const stack = await detectStack(targetDir);
@@ -3141,21 +3184,21 @@ __export(uninstall_exports, {
3141
3184
  default: () => uninstall_default
3142
3185
  });
3143
3186
  import { defineCommand as defineCommand3 } from "citty";
3144
- import { resolve as resolve4, join as join17 } from "path";
3145
- import { readdir as readdir4, rm as rm5, rename as rename2 } from "fs/promises";
3187
+ import { resolve as resolve4, join as join18 } from "path";
3188
+ import { readdir as readdir5, rm as rm5, rename as rename2 } from "fs/promises";
3146
3189
  import { confirm as confirm4, select as select3, isCancel as isCancel5, cancel as cancel4 } from "@clack/prompts";
3147
3190
  import pc8 from "picocolors";
3148
3191
  async function removeOwnedSkills(targetDir) {
3149
- const skillsDir = join17(targetDir, ".claude", "skills");
3192
+ const skillsDir = join18(targetDir, ".claude", "skills");
3150
3193
  const removed = [];
3151
3194
  if (!await pathExists(skillsDir)) {
3152
3195
  return removed;
3153
3196
  }
3154
3197
  try {
3155
- const entries = await readdir4(skillsDir);
3198
+ const entries = await readdir5(skillsDir);
3156
3199
  for (const entry of entries) {
3157
3200
  if (entry.startsWith(OWNED_SKILL_PREFIX)) {
3158
- await rm5(join17(skillsDir, entry), { recursive: true, force: true });
3201
+ await rm5(join18(skillsDir, entry), { recursive: true, force: true });
3159
3202
  removed.push(`.claude/skills/${entry}`);
3160
3203
  }
3161
3204
  }
@@ -3164,16 +3207,16 @@ async function removeOwnedSkills(targetDir) {
3164
3207
  return removed;
3165
3208
  }
3166
3209
  async function removeOwnedCursorRules(targetDir) {
3167
- const rulesDir = join17(targetDir, ".cursor", "rules");
3210
+ const rulesDir = join18(targetDir, ".cursor", "rules");
3168
3211
  const removed = [];
3169
3212
  if (!await pathExists(rulesDir)) {
3170
3213
  return removed;
3171
3214
  }
3172
3215
  try {
3173
- const entries = await readdir4(rulesDir);
3216
+ const entries = await readdir5(rulesDir);
3174
3217
  for (const entry of entries) {
3175
3218
  if (entry.startsWith(OWNED_RULE_PREFIX) && entry.endsWith(".mdc")) {
3176
- await rm5(join17(rulesDir, entry), { force: true });
3219
+ await rm5(join18(rulesDir, entry), { force: true });
3177
3220
  removed.push(`.cursor/rules/${entry}`);
3178
3221
  }
3179
3222
  }
@@ -3183,7 +3226,7 @@ async function removeOwnedCursorRules(targetDir) {
3183
3226
  }
3184
3227
  async function isEmptyDir(dirPath) {
3185
3228
  try {
3186
- const entries = await readdir4(dirPath);
3229
+ const entries = await readdir5(dirPath);
3187
3230
  return entries.length === 0;
3188
3231
  } catch {
3189
3232
  return false;
@@ -3192,7 +3235,7 @@ async function isEmptyDir(dirPath) {
3192
3235
  async function cleanupEmptyParents(targetDir, dirs) {
3193
3236
  const cleaned = [];
3194
3237
  for (const dir of dirs) {
3195
- const fullPath = join17(targetDir, dir);
3238
+ const fullPath = join18(targetDir, dir);
3196
3239
  if (await pathExists(fullPath) && await isEmptyDir(fullPath)) {
3197
3240
  await rm5(fullPath, { recursive: true, force: true });
3198
3241
  cleaned.push(dir);
@@ -3213,9 +3256,11 @@ var init_uninstall = __esm({
3213
3256
  [".claude/settings.json", "file"],
3214
3257
  [".claude/agents", "dir"],
3215
3258
  [".claude/commands", "dir"],
3259
+ [".claude/hooks", "dir"],
3216
3260
  [".claude/skills/README.md", "file"],
3217
3261
  [".cursor/hooks.json", "file"],
3218
3262
  [".cursor/agents", "dir"],
3263
+ [".cursor/commands", "dir"],
3219
3264
  [".flydocs", "dir"],
3220
3265
  ["AGENTS.md", "file"],
3221
3266
  [".env.example", "file"]
@@ -3269,8 +3314,8 @@ var init_uninstall = __esm({
3269
3314
  process.exit(1);
3270
3315
  }
3271
3316
  targetDir = resolve4(targetDir);
3272
- const hasFlydocs = await pathExists(join17(targetDir, ".flydocs"));
3273
- const hasAgentsMd = await pathExists(join17(targetDir, "AGENTS.md"));
3317
+ const hasFlydocs = await pathExists(join18(targetDir, ".flydocs"));
3318
+ const hasAgentsMd = await pathExists(join18(targetDir, "AGENTS.md"));
3274
3319
  if (!hasFlydocs && !hasAgentsMd) {
3275
3320
  printError(`Not a FlyDocs project: ${targetDir}`);
3276
3321
  printInfo("No .flydocs/ directory or AGENTS.md found.");
@@ -3282,7 +3327,7 @@ var init_uninstall = __esm({
3282
3327
  const removeAll = forceAll || args.all;
3283
3328
  const skipPrompts = forceAll || args.yes;
3284
3329
  let contentAction = "preserve";
3285
- const hasUserContent = await pathExists(join17(targetDir, "flydocs"));
3330
+ const hasUserContent = await pathExists(join18(targetDir, "flydocs"));
3286
3331
  if (hasUserContent) {
3287
3332
  if (removeAll) {
3288
3333
  contentAction = "remove";
@@ -3365,7 +3410,7 @@ var init_uninstall = __esm({
3365
3410
  const removedRules = await removeOwnedCursorRules(targetDir);
3366
3411
  result.removed.push(...removedRules);
3367
3412
  for (const [relativePath, type] of ALWAYS_REMOVED) {
3368
- const fullPath = join17(targetDir, relativePath);
3413
+ const fullPath = join18(targetDir, relativePath);
3369
3414
  if (!await pathExists(fullPath)) {
3370
3415
  result.skipped.push(relativePath);
3371
3416
  continue;
@@ -3383,9 +3428,9 @@ var init_uninstall = __esm({
3383
3428
  }
3384
3429
  }
3385
3430
  if (hasUserContent) {
3386
- const flydocsPath = join17(targetDir, "flydocs");
3431
+ const flydocsPath = join18(targetDir, "flydocs");
3387
3432
  if (contentAction === "archive") {
3388
- const archivePath = join17(targetDir, "flydocs-archive");
3433
+ const archivePath = join18(targetDir, "flydocs-archive");
3389
3434
  if (await pathExists(archivePath)) {
3390
3435
  await rm5(archivePath, { recursive: true, force: true });
3391
3436
  }
@@ -3626,7 +3671,7 @@ __export(connect_exports, {
3626
3671
  import { defineCommand as defineCommand6 } from "citty";
3627
3672
  import { text as text3, confirm as confirm5, isCancel as isCancel6, cancel as cancel5 } from "@clack/prompts";
3628
3673
  import pc11 from "picocolors";
3629
- import { join as join18 } from "path";
3674
+ import { join as join19 } from "path";
3630
3675
  var connect_default;
3631
3676
  var init_connect = __esm({
3632
3677
  "src/commands/connect.ts"() {
@@ -3661,7 +3706,7 @@ var init_connect = __esm({
3661
3706
  },
3662
3707
  async run({ args }) {
3663
3708
  const targetDir = args.path ?? process.cwd();
3664
- const configPath = join18(targetDir, ".flydocs", "config.json");
3709
+ const configPath = join19(targetDir, ".flydocs", "config.json");
3665
3710
  if (!await pathExists(configPath)) {
3666
3711
  printError("Not a FlyDocs project (.flydocs/config.json not found).");
3667
3712
  console.log(
@@ -3759,27 +3804,9 @@ var init_connect = __esm({
3759
3804
  await writeConfig(targetDir, config);
3760
3805
  printStatus("Config updated to cloud tier");
3761
3806
  if (wasLocal) {
3762
- try {
3763
- const templateDir = await resolveTemplatePath(
3764
- args["local-source"] || void 0
3765
- );
3766
- const templateSkillsDir = join18(templateDir, ".claude", "skills");
3767
- const skillsDir = join18(targetDir, ".claude", "skills");
3768
- await replaceDirectory(
3769
- join18(templateSkillsDir, "flydocs-cloud"),
3770
- join18(skillsDir, "flydocs-cloud")
3771
- );
3772
- const { rm: rm6 } = await import("fs/promises");
3773
- const localSkillDir = join18(skillsDir, "flydocs-local");
3774
- if (await pathExists(localSkillDir)) {
3775
- await rm6(localSkillDir, { recursive: true, force: true });
3776
- }
3777
- printStatus("Cloud mechanism skill installed");
3778
- } catch {
3779
- printInfo(
3780
- "Could not swap mechanism skills automatically. Run flydocs update to complete."
3781
- );
3782
- }
3807
+ printInfo(
3808
+ "Tier changed to cloud. Run flydocs update to refresh skill scripts."
3809
+ );
3783
3810
  }
3784
3811
  console.log();
3785
3812
  console.log(
@@ -3842,9 +3869,7 @@ var init_upgrade = __esm({
3842
3869
  ` ${pc12.green("\u2713")} You're already on the ${pc12.bold("cloud")} tier.`
3843
3870
  );
3844
3871
  console.log();
3845
- console.log(
3846
- ` Your issues sync with your provider via the cloud mechanism skill.`
3847
- );
3872
+ console.log(` Your issues sync with your provider via the relay API.`);
3848
3873
  console.log(
3849
3874
  ` Run ${pc12.cyan("flydocs connect")} to update your connection settings.`
3850
3875
  );