@flydocs/cli 0.5.0-beta.11 → 0.5.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -15,7 +15,7 @@ var CLI_VERSION, CLI_NAME, PACKAGE_NAME;
15
15
  var init_constants = __esm({
16
16
  "src/lib/constants.ts"() {
17
17
  "use strict";
18
- CLI_VERSION = "0.5.0-beta.11";
18
+ CLI_VERSION = "0.5.0-beta.13";
19
19
  CLI_NAME = "flydocs";
20
20
  PACKAGE_NAME = "@flydocs/cli";
21
21
  }
@@ -42,9 +42,7 @@ async function ensureDirectories(targetDir, tier) {
42
42
  const dirs = [
43
43
  ".flydocs",
44
44
  ".claude/skills",
45
- ".claude/agents",
46
45
  ".claude/commands",
47
- ".cursor/agents",
48
46
  ".cursor/commands",
49
47
  ".cursor/rules",
50
48
  "flydocs/context",
@@ -139,6 +137,59 @@ import pc2 from "picocolors";
139
137
  function hyperlink(text3, url) {
140
138
  return `\x1B]8;;${url}\x07${text3}\x1B]8;;\x07`;
141
139
  }
140
+ function shadow(text3) {
141
+ return `\x1B[38;2;55;45;70m${text3}\x1B[0m`;
142
+ }
143
+ function renderBannerBlock() {
144
+ const height = BANNER_ROWS.length;
145
+ const width = BANNER_ROWS[0].length;
146
+ const padded = BANNER_ROWS.map((r) => r.padEnd(width));
147
+ console.log(` ${GRADIENT[0](padded[0])}`);
148
+ for (let i = 1; i < height; i++) {
149
+ let line = "";
150
+ const shadowSrc2 = padded[i - 1];
151
+ const textSrc = padded[i];
152
+ for (let c = 0; c < width; c++) {
153
+ const textChar = textSrc[c];
154
+ const shadowChar = c > 0 ? shadowSrc2[c - 1] : " ";
155
+ if (textChar === "\u2588") {
156
+ line += "\u2588";
157
+ } else if (shadowChar === "\u2588") {
158
+ line += "\u2593";
159
+ } else {
160
+ line += " ";
161
+ }
162
+ }
163
+ let colored = " ";
164
+ let j = 0;
165
+ while (j < line.length) {
166
+ const ch = line[j];
167
+ let run = "";
168
+ while (j < line.length && line[j] === ch) {
169
+ run += line[j];
170
+ j++;
171
+ }
172
+ if (ch === "\u2588") {
173
+ colored += GRADIENT[i](run);
174
+ } else if (ch === "\u2593") {
175
+ colored += shadow(run);
176
+ } else {
177
+ colored += run;
178
+ }
179
+ }
180
+ console.log(colored);
181
+ }
182
+ const shadowSrc = padded[height - 1];
183
+ let bottomShadow = "";
184
+ for (let c = 0; c < width + 1; c++) {
185
+ const shadowChar = c > 0 ? shadowSrc[c - 1] : " ";
186
+ bottomShadow += shadowChar === "\u2588" ? "\u2593" : " ";
187
+ }
188
+ bottomShadow = bottomShadow.replace(/\s+$/, "");
189
+ if (bottomShadow.trim()) {
190
+ console.log(` ${shadow(" " + bottomShadow)}`);
191
+ }
192
+ }
142
193
  function printStatus(message) {
143
194
  console.log(`${pc2.green("\u2714")} ${message}`);
144
195
  }
@@ -152,26 +203,13 @@ function printInfo(message) {
152
203
  console.log(`${pc2.cyan("\u2139")} ${message}`);
153
204
  }
154
205
  function printBanner(version) {
155
- const pink = (t) => pc2.bold(pc2.magenta(t));
156
- const purple = (t) => pc2.bold(pc2.cyan(t));
157
- const dim = pc2.dim;
158
- const bold = pc2.bold;
159
- const pinkBlock12 = pink("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588");
160
- const pinkBlock4 = pink("\u2588\u2588\u2588\u2588");
161
- const purpleBlock12 = purple("\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588");
162
- const purpleBlock4 = purple("\u2588\u2588\u2588\u2588");
163
206
  console.log();
164
- console.log(` ${pinkBlock12}`);
165
- console.log(` ${pinkBlock12}`);
166
- console.log(` ${pinkBlock4}`);
167
- console.log(
168
- ` ${pinkBlock4} ${purpleBlock12} ${bold("FlyDocs")} ${dim("(Beta)")}`
169
- );
207
+ renderBannerBlock();
208
+ console.log();
170
209
  console.log(
171
- ` ${purpleBlock12} ${dim("Spec-Driven Context That Helps Engineers Fly")}`
210
+ ` ${pc2.bold(pc2.white("Structured context for AI coding tools"))} ${pc2.dim("(Beta)")}`
172
211
  );
173
- console.log(` ${purpleBlock4}`);
174
- console.log(` ${purpleBlock4} ${dim(`v${version}`)}`);
212
+ console.log(` ${pc2.dim(`Version: ${version}`)}`);
175
213
  console.log();
176
214
  }
177
215
  function printCompletionBox(title, lines) {
@@ -192,22 +230,43 @@ function printCompletionBox(title, lines) {
192
230
  }
193
231
  function printBetaCta() {
194
232
  const dim = pc2.dim;
195
- const url = "https://www.flydocs.ai?utm_source=cli&utm_medium=install&utm_campaign=beta";
233
+ const discordUrl = "https://discord.com/invite/YAkjePmZTQ";
234
+ const siteUrl = "https://www.flydocs.ai?utm_source=cli&utm_medium=install&utm_campaign=beta";
196
235
  console.log(
197
236
  dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")
198
237
  );
199
238
  console.log();
200
- console.log(` ${pc2.bold("Join the FlyDocs Closed Beta")}`);
201
239
  console.log(
202
- ` ${dim("Early access to cloud features, web portal, and more.")}`
240
+ ` ${pc2.bold("Join the community")} ${dim("\u2014 bugs, ideas, and updates")}`
241
+ );
242
+ console.log(
243
+ ` ${hyperlink(pc2.cyan("discord.com/invite/YAkjePmZTQ"), discordUrl)}`
244
+ );
245
+ console.log();
246
+ console.log(
247
+ ` ${dim("Docs and updates:")} ${hyperlink(pc2.cyan("flydocs.ai"), siteUrl)}`
203
248
  );
204
- console.log(` ${hyperlink(pc2.cyan("https://www.flydocs.ai"), url)}`);
205
249
  console.log();
206
250
  }
251
+ var GRADIENT, BANNER_ROWS;
207
252
  var init_ui = __esm({
208
253
  "src/lib/ui.ts"() {
209
254
  "use strict";
210
255
  init_constants();
256
+ GRADIENT = [
257
+ (t) => `\x1B[1;38;2;255;0;128m${t}\x1B[0m`,
258
+ (t) => `\x1B[1;38;2;225;15;158m${t}\x1B[0m`,
259
+ (t) => `\x1B[1;38;2;190;30;190m${t}\x1B[0m`,
260
+ (t) => `\x1B[1;38;2;158;44;214m${t}\x1B[0m`,
261
+ (t) => `\x1B[1;38;2;124;58;237m${t}\x1B[0m`
262
+ ];
263
+ BANNER_ROWS = [
264
+ "\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588",
265
+ "\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ",
266
+ "\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 ",
267
+ "\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588",
268
+ "\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588"
269
+ ];
211
270
  }
212
271
  });
213
272
 
@@ -348,9 +407,9 @@ async function replaceOwnedSkills(templateDir, targetDir, tier) {
348
407
  }
349
408
  }
350
409
  async function copyCursorRules(targetDir) {
351
- const { mkdir: mkdir6 } = await import("fs/promises");
410
+ const { mkdir: mkdir7 } = await import("fs/promises");
352
411
  const rulesDir = join4(targetDir, ".cursor", "rules");
353
- await mkdir6(rulesDir, { recursive: true });
412
+ await mkdir7(rulesDir, { recursive: true });
354
413
  const workflowRule = join4(
355
414
  targetDir,
356
415
  ".claude",
@@ -1578,7 +1637,9 @@ __export(install_exports, {
1578
1637
  import { defineCommand } from "citty";
1579
1638
  import { resolve as resolve2 } from "path";
1580
1639
  import { join as join12 } from "path";
1640
+ import { mkdir as mkdir5 } from "fs/promises";
1581
1641
  import { confirm as confirm2, select, isCancel as isCancel3, cancel as cancel2 } from "@clack/prompts";
1642
+ import pc6 from "picocolors";
1582
1643
  var install_default;
1583
1644
  var init_install = __esm({
1584
1645
  "src/commands/install.ts"() {
@@ -1732,14 +1793,56 @@ var init_install = __esm({
1732
1793
  await installOwnedSkills(templateDir, targetDir, tier);
1733
1794
  printStatus(`Skills installed (tier: ${tier})`);
1734
1795
  console.log();
1735
- console.log("Installing agents and commands...");
1736
- const claudeAgentsSrc = join12(templateDir, ".claude", "agents");
1737
- if (await pathExists(claudeAgentsSrc)) {
1738
- await copyDirectoryContents(
1739
- claudeAgentsSrc,
1740
- join12(targetDir, ".claude", "agents")
1741
- );
1796
+ console.log(` ${pc6.bold(pc6.yellow("Sub-Agents (Recommended)"))}`);
1797
+ console.log();
1798
+ console.log(
1799
+ " Sub-agents are specialized roles (PM, implementation, review,"
1800
+ );
1801
+ console.log(
1802
+ " research) that your AI tool can delegate tasks to. They help"
1803
+ );
1804
+ console.log(
1805
+ " structure work but are not required \u2014 everything works without them."
1806
+ );
1807
+ console.log();
1808
+ let installAgents;
1809
+ if (args.yes) {
1810
+ installAgents = true;
1811
+ console.log(" Auto-accepting (--yes)");
1812
+ } else {
1813
+ const agentConfirm = await confirm2({
1814
+ message: "Install sub-agents?",
1815
+ initialValue: true
1816
+ });
1817
+ if (isCancel3(agentConfirm)) {
1818
+ installAgents = false;
1819
+ } else {
1820
+ installAgents = agentConfirm;
1821
+ }
1742
1822
  }
1823
+ if (installAgents) {
1824
+ const claudeAgentsSrc = join12(templateDir, ".claude", "agents");
1825
+ if (await pathExists(claudeAgentsSrc)) {
1826
+ await mkdir5(join12(targetDir, ".claude", "agents"), { recursive: true });
1827
+ await copyDirectoryContents(
1828
+ claudeAgentsSrc,
1829
+ join12(targetDir, ".claude", "agents")
1830
+ );
1831
+ }
1832
+ const cursorAgentsSrc = join12(templateDir, ".cursor", "agents");
1833
+ if (await pathExists(cursorAgentsSrc)) {
1834
+ await mkdir5(join12(targetDir, ".cursor", "agents"), { recursive: true });
1835
+ await copyDirectoryContents(
1836
+ cursorAgentsSrc,
1837
+ join12(targetDir, ".cursor", "agents")
1838
+ );
1839
+ }
1840
+ printStatus("Sub-agents installed (.claude/agents, .cursor/agents)");
1841
+ } else {
1842
+ printInfo("Skipped sub-agents");
1843
+ }
1844
+ console.log();
1845
+ console.log("Installing commands and settings...");
1743
1846
  await copyDirectoryContents(
1744
1847
  join12(templateDir, ".claude", "commands"),
1745
1848
  join12(targetDir, ".claude", "commands")
@@ -1752,14 +1855,7 @@ var init_install = __esm({
1752
1855
  join12(templateDir, ".claude", "settings.json"),
1753
1856
  join12(targetDir, ".claude", "settings.json")
1754
1857
  );
1755
- printStatus(".claude/ (agents, commands, CLAUDE.md, settings)");
1756
- const cursorAgentsSrc = join12(templateDir, ".cursor", "agents");
1757
- if (await pathExists(cursorAgentsSrc)) {
1758
- await copyDirectoryContents(
1759
- cursorAgentsSrc,
1760
- join12(targetDir, ".cursor", "agents")
1761
- );
1762
- }
1858
+ printStatus(".claude/ (commands, CLAUDE.md, settings)");
1763
1859
  await copyDirectoryContents(
1764
1860
  join12(templateDir, ".claude", "commands"),
1765
1861
  join12(targetDir, ".cursor", "commands")
@@ -1768,7 +1864,7 @@ var init_install = __esm({
1768
1864
  join12(templateDir, ".cursor", "hooks.json"),
1769
1865
  join12(targetDir, ".cursor", "hooks.json")
1770
1866
  );
1771
- printStatus(".cursor/ (agents, commands, hooks)");
1867
+ printStatus(".cursor/ (commands, hooks)");
1772
1868
  await copyCursorRules(targetDir);
1773
1869
  printStatus(".cursor/rules/");
1774
1870
  await copyFile(
@@ -1898,7 +1994,7 @@ var init_install = __esm({
1898
1994
  " 1. Run /flydocs-setup to configure your project",
1899
1995
  " 2. Start working with /start-session",
1900
1996
  "",
1901
- "Documentation: flydocs/README.md"
1997
+ "Docs: https://www.flydocs.ai/docs"
1902
1998
  ] : [
1903
1999
  `Tier: ${tier}`,
1904
2000
  `Version: ${version}`,
@@ -1908,7 +2004,7 @@ var init_install = __esm({
1908
2004
  " 2. Run /flydocs-setup to configure your Linear workspace",
1909
2005
  " 3. Start working with /start-session",
1910
2006
  "",
1911
- "Documentation: flydocs/README.md"
2007
+ "Docs: https://www.flydocs.ai/docs"
1912
2008
  ];
1913
2009
  let copiedToClipboard = false;
1914
2010
  try {
@@ -2039,9 +2135,9 @@ __export(update_exports, {
2039
2135
  });
2040
2136
  import { defineCommand as defineCommand2 } from "citty";
2041
2137
  import { resolve as resolve3, join as join13 } from "path";
2042
- import { mkdir as mkdir5, cp as cp2, readFile as readFile8, readdir as readdir3, rm as rm4 } from "fs/promises";
2138
+ import { mkdir as mkdir6, cp as cp2, readFile as readFile8, readdir as readdir3, rm as rm4 } from "fs/promises";
2043
2139
  import { select as select2, text, confirm as confirm3, isCancel as isCancel4, cancel as cancel3 } from "@clack/prompts";
2044
- import pc6 from "picocolors";
2140
+ import pc7 from "picocolors";
2045
2141
  var update_default;
2046
2142
  var init_update = __esm({
2047
2143
  "src/commands/update.ts"() {
@@ -2189,7 +2285,7 @@ var init_update = __esm({
2189
2285
  const changelogPath = join13(templateDir, "CHANGELOG.md");
2190
2286
  const whatsNew = await getWhatsNew(changelogPath, currentVersion, version);
2191
2287
  if (whatsNew.length > 0) {
2192
- console.log(pc6.cyan("What's new:"));
2288
+ console.log(pc7.cyan("What's new:"));
2193
2289
  console.log();
2194
2290
  for (const entry of whatsNew) {
2195
2291
  console.log(` ${entry}`);
@@ -2199,7 +2295,7 @@ var init_update = __esm({
2199
2295
  const now = /* @__PURE__ */ new Date();
2200
2296
  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")}`;
2201
2297
  const backupDir = join13(targetDir, ".flydocs", `backup-${ts}`);
2202
- await mkdir5(backupDir, { recursive: true });
2298
+ await mkdir6(backupDir, { recursive: true });
2203
2299
  if (hasConfig) {
2204
2300
  await cp2(
2205
2301
  join13(targetDir, ".flydocs", "config.json"),
@@ -2263,24 +2359,63 @@ var init_update = __esm({
2263
2359
  join13(targetDir, ".flydocs", "scripts")
2264
2360
  );
2265
2361
  printStatus(".flydocs/templates, hooks, scripts");
2266
- const claudeAgentsSrc = join13(templateDir, ".claude", "agents");
2267
- if (await pathExists(claudeAgentsSrc)) {
2268
- await copyDirectoryContents(
2269
- claudeAgentsSrc,
2270
- join13(targetDir, ".claude", "agents")
2362
+ const hasExistingAgents = await pathExists(
2363
+ join13(targetDir, ".claude", "agents")
2364
+ );
2365
+ let installAgents;
2366
+ if (args.yes) {
2367
+ installAgents = hasExistingAgents ? true : true;
2368
+ } else if (hasExistingAgents) {
2369
+ installAgents = true;
2370
+ } else {
2371
+ console.log();
2372
+ console.log(` ${pc7.bold(pc7.yellow("Sub-Agents (Recommended)"))}`);
2373
+ console.log();
2374
+ console.log(
2375
+ " Sub-agents are specialized roles (PM, implementation, review,"
2376
+ );
2377
+ console.log(
2378
+ " research) that your AI tool can delegate tasks to. They help"
2271
2379
  );
2380
+ console.log(
2381
+ " structure work but are not required \u2014 everything works without them."
2382
+ );
2383
+ console.log();
2384
+ const agentConfirm = await confirm3({
2385
+ message: "Install sub-agents?",
2386
+ initialValue: true
2387
+ });
2388
+ if (isCancel4(agentConfirm)) {
2389
+ installAgents = false;
2390
+ } else {
2391
+ installAgents = agentConfirm;
2392
+ }
2272
2393
  }
2273
- printStatus(".claude/agents");
2274
- await replaceOwnedSkills(templateDir, targetDir, effectiveTier);
2275
- printStatus(`.claude/skills (tier: ${effectiveTier})`);
2276
- const cursorAgentsSrc = join13(templateDir, ".cursor", "agents");
2277
- if (await pathExists(cursorAgentsSrc)) {
2278
- await copyDirectoryContents(
2279
- cursorAgentsSrc,
2280
- join13(targetDir, ".cursor", "agents")
2394
+ if (installAgents) {
2395
+ const claudeAgentsSrc = join13(templateDir, ".claude", "agents");
2396
+ if (await pathExists(claudeAgentsSrc)) {
2397
+ await mkdir6(join13(targetDir, ".claude", "agents"), { recursive: true });
2398
+ await copyDirectoryContents(
2399
+ claudeAgentsSrc,
2400
+ join13(targetDir, ".claude", "agents")
2401
+ );
2402
+ }
2403
+ const cursorAgentsSrc = join13(templateDir, ".cursor", "agents");
2404
+ if (await pathExists(cursorAgentsSrc)) {
2405
+ await mkdir6(join13(targetDir, ".cursor", "agents"), { recursive: true });
2406
+ await copyDirectoryContents(
2407
+ cursorAgentsSrc,
2408
+ join13(targetDir, ".cursor", "agents")
2409
+ );
2410
+ }
2411
+ printStatus(
2412
+ hasExistingAgents ? "Sub-agents updated (.claude/agents, .cursor/agents)" : "Sub-agents installed (.claude/agents, .cursor/agents)"
2281
2413
  );
2414
+ } else {
2415
+ printInfo("Skipped sub-agents");
2282
2416
  }
2283
- printStatus(".cursor/agents");
2417
+ await replaceOwnedSkills(templateDir, targetDir, effectiveTier);
2418
+ printStatus(`.claude/skills (tier: ${effectiveTier})`);
2284
2419
  console.log();
2285
2420
  console.log("Replacing framework files...");
2286
2421
  await copyFile(
@@ -2411,7 +2546,7 @@ __export(setup_exports, {
2411
2546
  default: () => setup_default
2412
2547
  });
2413
2548
  import { defineCommand as defineCommand3 } from "citty";
2414
- import pc7 from "picocolors";
2549
+ import pc8 from "picocolors";
2415
2550
  var setup_default;
2416
2551
  var init_setup = __esm({
2417
2552
  "src/commands/setup.ts"() {
@@ -2423,15 +2558,15 @@ var init_setup = __esm({
2423
2558
  },
2424
2559
  run() {
2425
2560
  console.log();
2426
- console.log(` ${pc7.bold("FlyDocs Setup")}`);
2561
+ console.log(` ${pc8.bold("FlyDocs Setup")}`);
2427
2562
  console.log();
2428
2563
  console.log(` Setup runs inside your IDE as an interactive AI command.`);
2429
2564
  console.log();
2430
2565
  console.log(
2431
- ` ${pc7.cyan("Claude Code:")} Type ${pc7.bold("/flydocs-setup")} in chat`
2566
+ ` ${pc8.cyan("Claude Code:")} Type ${pc8.bold("/flydocs-setup")} in chat`
2432
2567
  );
2433
2568
  console.log(
2434
- ` ${pc7.cyan("Cursor:")} Type ${pc7.bold("/flydocs-setup")} in chat`
2569
+ ` ${pc8.cyan("Cursor:")} Type ${pc8.bold("/flydocs-setup")} in chat`
2435
2570
  );
2436
2571
  console.log();
2437
2572
  console.log(` This configures your project context, detects your stack,`);
@@ -2448,7 +2583,7 @@ __export(skills_exports, {
2448
2583
  default: () => skills_default
2449
2584
  });
2450
2585
  import { defineCommand as defineCommand4 } from "citty";
2451
- import pc8 from "picocolors";
2586
+ import pc9 from "picocolors";
2452
2587
  var list, search, add, remove, skills_default;
2453
2588
  var init_skills2 = __esm({
2454
2589
  "src/commands/skills.ts"() {
@@ -2470,19 +2605,19 @@ var init_skills2 = __esm({
2470
2605
  console.log(`${total} skill(s) installed:`);
2471
2606
  if (result.platform.length > 0) {
2472
2607
  console.log();
2473
- console.log(pc8.bold("Platform"));
2608
+ console.log(pc9.bold("Platform"));
2474
2609
  for (const skill of result.platform) {
2475
2610
  console.log(
2476
- ` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
2611
+ ` ${skill.name} ${pc9.dim(`(${skill.triggers} triggers)`)}`
2477
2612
  );
2478
2613
  }
2479
2614
  }
2480
2615
  if (result.community.length > 0) {
2481
2616
  console.log();
2482
- console.log(pc8.bold("Community"));
2617
+ console.log(pc9.bold("Community"));
2483
2618
  for (const skill of result.community) {
2484
2619
  console.log(
2485
- ` ${skill.name} ${pc8.dim(`(${skill.triggers} triggers)`)}`
2620
+ ` ${skill.name} ${pc9.dim(`(${skill.triggers} triggers)`)}`
2486
2621
  );
2487
2622
  }
2488
2623
  }
@@ -2505,18 +2640,18 @@ var init_skills2 = __esm({
2505
2640
  const results = await searchCatalog(args.keyword);
2506
2641
  if (results.length === 0) {
2507
2642
  console.log(`No skills found for "${args.keyword}".`);
2508
- console.log(` Browse the catalog at: ${pc8.cyan("https://skills.sh/")}`);
2643
+ console.log(` Browse the catalog at: ${pc9.cyan("https://skills.sh/")}`);
2509
2644
  return;
2510
2645
  }
2511
2646
  console.log();
2512
2647
  console.log(`${results.length} skill(s) matching "${args.keyword}":`);
2513
2648
  console.log();
2514
2649
  for (const skill of results) {
2515
- console.log(` ${pc8.bold(skill.name)}`);
2650
+ console.log(` ${pc9.bold(skill.name)}`);
2516
2651
  console.log(` ${skill.description}`);
2517
- console.log(` ${pc8.dim(skill.repo)}`);
2652
+ console.log(` ${pc9.dim(skill.repo)}`);
2518
2653
  if (skill.tags.length > 0) {
2519
- console.log(` ${pc8.dim(skill.tags.join(", "))}`);
2654
+ console.log(` ${pc9.dim(skill.tags.join(", "))}`);
2520
2655
  }
2521
2656
  console.log();
2522
2657
  }
@@ -2576,7 +2711,7 @@ __export(connect_exports, {
2576
2711
  });
2577
2712
  import { defineCommand as defineCommand5 } from "citty";
2578
2713
  import { text as text2, confirm as confirm4, isCancel as isCancel5, cancel as cancel4 } from "@clack/prompts";
2579
- import pc9 from "picocolors";
2714
+ import pc10 from "picocolors";
2580
2715
  import { readFile as readFile9, writeFile as writeFile5, appendFile as appendFile2 } from "fs/promises";
2581
2716
  import { join as join14 } from "path";
2582
2717
  var connect_default;
@@ -2616,7 +2751,7 @@ var init_connect = __esm({
2616
2751
  if (!await pathExists(configPath)) {
2617
2752
  printError("Not a FlyDocs project (.flydocs/config.json not found).");
2618
2753
  console.log(
2619
- ` Run ${pc9.cyan("flydocs")} first to install FlyDocs in this project.`
2754
+ ` Run ${pc10.cyan("flydocs")} first to install FlyDocs in this project.`
2620
2755
  );
2621
2756
  process.exit(1);
2622
2757
  }
@@ -2633,10 +2768,10 @@ var init_connect = __esm({
2633
2768
  }
2634
2769
  }
2635
2770
  console.log();
2636
- console.log(` ${pc9.bold("Connect to Linear")}`);
2771
+ console.log(` ${pc10.bold("Connect to Linear")}`);
2637
2772
  console.log();
2638
2773
  console.log(
2639
- ` ${pc9.dim("Get your API key from: Linear \u2192 Settings \u2192 API \u2192 Personal API keys")}`
2774
+ ` ${pc10.dim("Get your API key from: Linear \u2192 Settings \u2192 API \u2192 Personal API keys")}`
2640
2775
  );
2641
2776
  console.log();
2642
2777
  let apiKey = args.key ?? "";
@@ -2676,7 +2811,7 @@ var init_connect = __esm({
2676
2811
  throw new Error("Invalid response");
2677
2812
  }
2678
2813
  const viewer = data.data.viewer;
2679
- printStatus(`Authenticated as ${pc9.bold(viewer.name)} (${viewer.email})`);
2814
+ printStatus(`Authenticated as ${pc10.bold(viewer.name)} (${viewer.email})`);
2680
2815
  } catch {
2681
2816
  printError("Invalid API key or network error.");
2682
2817
  console.log(` Check your key and try again.`);
@@ -2703,7 +2838,7 @@ LINEAR_API_KEY=${apiKey}
2703
2838
  `, "utf-8");
2704
2839
  }
2705
2840
  printStatus(
2706
- `API key stored in ${pc9.dim(targetEnvPath === envLocalPath ? ".env.local" : ".env")}`
2841
+ `API key stored in ${pc10.dim(targetEnvPath === envLocalPath ? ".env.local" : ".env")}`
2707
2842
  );
2708
2843
  const wasLocal = config.tier === "local";
2709
2844
  config.tier = "cloud";
@@ -2736,14 +2871,14 @@ LINEAR_API_KEY=${apiKey}
2736
2871
  }
2737
2872
  console.log();
2738
2873
  console.log(
2739
- ` ${pc9.bold("Connected!")} Your project now syncs with Linear.`
2874
+ ` ${pc10.bold("Connected!")} Your project now syncs with Linear.`
2740
2875
  );
2741
2876
  console.log();
2742
2877
  console.log(` Next steps:`);
2743
2878
  console.log(
2744
- ` 1. Run ${pc9.cyan("/flydocs-setup")} in your IDE to configure your Linear project`
2879
+ ` 1. Run ${pc10.cyan("/flydocs-setup")} in your IDE to configure your Linear project`
2745
2880
  );
2746
- console.log(` 2. Run ${pc9.cyan("/start-session")} to begin working`);
2881
+ console.log(` 2. Run ${pc10.cyan("/start-session")} to begin working`);
2747
2882
  console.log();
2748
2883
  }
2749
2884
  });
@@ -2756,7 +2891,7 @@ __export(upgrade_exports, {
2756
2891
  default: () => upgrade_default
2757
2892
  });
2758
2893
  import { defineCommand as defineCommand6 } from "citty";
2759
- import pc10 from "picocolors";
2894
+ import pc11 from "picocolors";
2760
2895
  var upgrade_default;
2761
2896
  var init_upgrade = __esm({
2762
2897
  "src/commands/upgrade.ts"() {
@@ -2792,37 +2927,37 @@ var init_upgrade = __esm({
2792
2927
  console.log();
2793
2928
  if (currentTier === "cloud") {
2794
2929
  console.log(
2795
- ` ${pc10.green("\u2713")} You're already on the ${pc10.bold("cloud")} tier.`
2930
+ ` ${pc11.green("\u2713")} You're already on the ${pc11.bold("cloud")} tier.`
2796
2931
  );
2797
2932
  console.log();
2798
2933
  console.log(
2799
2934
  ` Your issues sync with Linear via the cloud mechanism skill.`
2800
2935
  );
2801
2936
  console.log(
2802
- ` Run ${pc10.cyan("flydocs connect")} to update your connection settings.`
2937
+ ` Run ${pc11.cyan("flydocs connect")} to update your connection settings.`
2803
2938
  );
2804
2939
  console.log();
2805
2940
  return;
2806
2941
  }
2807
- console.log(` ${pc10.bold("FlyDocs Cloud Tier")}`);
2942
+ console.log(` ${pc11.bold("FlyDocs Cloud Tier")}`);
2808
2943
  console.log();
2809
- console.log(` You're currently on the ${pc10.yellow("local")} tier.`);
2944
+ console.log(` You're currently on the ${pc11.yellow("local")} tier.`);
2810
2945
  console.log(` Upgrade to cloud for:`);
2811
2946
  console.log();
2812
2947
  console.log(
2813
- ` ${pc10.cyan("\u2192")} Issue sync with Linear (Jira coming soon)`
2948
+ ` ${pc11.cyan("\u2192")} Issue sync with Linear (Jira coming soon)`
2814
2949
  );
2815
- console.log(` ${pc10.cyan("\u2192")} Project milestones and cycle management`);
2816
- console.log(` ${pc10.cyan("\u2192")} Team assignment and priority tracking`);
2817
- console.log(` ${pc10.cyan("\u2192")} Project health updates and dashboards`);
2818
- console.log(` ${pc10.cyan("\u2192")} Cross-project issue linking`);
2950
+ console.log(` ${pc11.cyan("\u2192")} Project milestones and cycle management`);
2951
+ console.log(` ${pc11.cyan("\u2192")} Team assignment and priority tracking`);
2952
+ console.log(` ${pc11.cyan("\u2192")} Project health updates and dashboards`);
2953
+ console.log(` ${pc11.cyan("\u2192")} Cross-project issue linking`);
2819
2954
  console.log();
2820
- console.log(` ${pc10.bold("How to upgrade:")}`);
2955
+ console.log(` ${pc11.bold("How to upgrade:")}`);
2821
2956
  console.log();
2822
- console.log(` 1. Sign up at ${pc10.cyan("https://www.flydocs.ai")}`);
2957
+ console.log(` 1. Sign up at ${pc11.cyan("https://www.flydocs.ai")}`);
2823
2958
  console.log(` 2. Get your Linear API key from Linear \u2192 Settings \u2192 API`);
2824
2959
  console.log(
2825
- ` 3. Run ${pc10.cyan("flydocs connect")} to connect your project`
2960
+ ` 3. Run ${pc11.cyan("flydocs connect")} to connect your project`
2826
2961
  );
2827
2962
  console.log();
2828
2963
  }
@@ -2837,7 +2972,7 @@ __export(self_update_exports, {
2837
2972
  });
2838
2973
  import { defineCommand as defineCommand7 } from "citty";
2839
2974
  import { execSync } from "child_process";
2840
- import pc11 from "picocolors";
2975
+ import pc12 from "picocolors";
2841
2976
  var self_update_default;
2842
2977
  var init_self_update = __esm({
2843
2978
  "src/commands/self-update.ts"() {
@@ -2851,7 +2986,7 @@ var init_self_update = __esm({
2851
2986
  },
2852
2987
  async run() {
2853
2988
  console.log();
2854
- console.log(` Updating ${pc11.cyan(PACKAGE_NAME)}...`);
2989
+ console.log(` Updating ${pc12.cyan(PACKAGE_NAME)}...`);
2855
2990
  console.log();
2856
2991
  try {
2857
2992
  execSync(`npm install -g ${PACKAGE_NAME}@beta`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flydocs/cli",
3
- "version": "0.5.0-beta.11",
3
+ "version": "0.5.0-beta.13",
4
4
  "type": "module",
5
5
  "description": "FlyDocs AI CLI — install, setup, and manage FlyDocs projects",
6
6
  "bin": {
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: implementation-agent
3
3
  description: "Builds features, fixes bugs, writes code. Invoke for implementation, coding, or technical work."
4
- model: opus
5
4
  tools: [Read, Glob, Grep, Bash, Write, Edit, WebFetch, WebSearch]
6
5
  skills:
7
6
  - flydocs-workflow
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: pm-agent
3
3
  description: "Specs, workflow, issue management. Invoke for capturing, refining, activating, reviewing, closing, or session management."
4
- model: opus
5
4
  tools: [Read, Glob, Grep, Bash, WebFetch]
6
5
  disallowedTools: [Write, Edit]
7
6
  skills:
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: research-agent
3
3
  description: "Codebase exploration and research. Invoke for understanding code structure, finding patterns, or gathering technical context."
4
- model: sonnet
5
4
  tools: [Read, Glob, Grep, WebFetch, WebSearch]
6
5
  disallowedTools: [Bash, Write, Edit]
7
6
  skills:
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: review-agent
3
3
  description: "Code review and quality analysis. Invoke for reviewing implementations, checking quality, or validating acceptance criteria."
4
- model: sonnet
5
4
  tools: [Read, Glob, Grep, Bash]
6
5
  disallowedTools: [Write, Edit]
7
6
  skills:
@@ -576,20 +576,21 @@ Stage all new and modified FlyDocs files (`.flydocs/`, `.claude/`, `.cursor/`,
576
576
  If the user declines, remind them to commit before starting work:
577
577
  "No problem — just remember to commit these files before your first session."
578
578
 
579
- ### Step 5: Beta CTA
579
+ ### Step 5: Community CTA
580
580
 
581
- Always end with the beta call-to-action:
581
+ Always end with the community call-to-action:
582
582
 
583
583
  ```
584
584
  ─────────────────────────────────────────────────────
585
585
 
586
- FlyDocs is in active development. Premium features coming soon:
587
- Cloud sync with Linear, Jira, and more
588
- AI-powered skills and automation
589
- Team analytics and cost intelligence
586
+ What's coming next:
587
+ Project management tool sync Linear, Jira, and more
588
+ Web portal project setup, team visibility, session analytics
589
+ Cost intelligence — AI usage tracking and spend analysis
590
590
 
591
- Join the beta for early access and updates:
592
- https://www.flydocs.ai?utm_source=cli&utm_medium=setup&utm_campaign=beta
591
+ Join the community:
592
+ Discord: https://discord.com/invite/YAkjePmZTQ
593
+ Docs & updates: https://www.flydocs.ai
593
594
 
594
595
  ─────────────────────────────────────────────────────
595
596
  ```
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.0-beta.11",
2
+ "version": "0.5.0-beta.13",
3
3
  "sourceRepo": "github.com/plastrlab/flydocs-core",
4
4
  "tier": "local",
5
5
  "setupComplete": false,
@@ -1 +1 @@
1
- 0.5.0-beta.11
1
+ 0.5.0-beta.13
@@ -7,6 +7,33 @@ Versioning: [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.5.0-beta.13] — 2026-02-24
11
+
12
+ ### Changed
13
+
14
+ - **New ASCII banner** — gradient block-letter "FlyDocs" heading with subtle drop shadow,
15
+ replacing the block mark logo. Pink-to-purple gradient matches brand colors using true
16
+ color (24-bit) escape sequences. Tagline in bold white, version label in dim.
17
+
18
+ ---
19
+
20
+ ## [0.5.0-beta.12] — 2026-02-24
21
+
22
+ ### Changed
23
+
24
+ - **Optional sub-agents** — sub-agents (PM, implementation, review, research) are now
25
+ an opt-in prompt during install and update. Recommended but not required. Existing
26
+ installs are silently updated on next `flydocs update`.
27
+ - **Removed hardcoded model selections** — Claude Code agent files no longer specify
28
+ `model: opus` or `model: sonnet`. Agents inherit the user's configured model,
29
+ matching the Cursor agent behavior.
30
+ - **CLI copy alignment** — banner tagline updated to "Structured context for AI coding
31
+ tools", beta CTA refocused on Discord community, docs references point to flydocs.ai.
32
+ - **Setup command CTA** — updated to show community links (Discord, flydocs.ai) and
33
+ upcoming features instead of "join the beta" messaging.
34
+
35
+ ---
36
+
10
37
  ## [0.5.0-beta.11] — 2026-02-23
11
38
 
12
39
  ### Fixed
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.0-beta.11",
2
+ "version": "0.5.0-beta.13",
3
3
  "description": "FlyDocs Core - Manifest of all managed files",
4
4
  "repository": "github.com/plastrlab/flydocs-core",
5
5