get-tbd 0.1.9 → 0.1.11

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 (34) hide show
  1. package/README.md +3 -3
  2. package/dist/bin.mjs +281 -98
  3. package/dist/bin.mjs.map +1 -1
  4. package/dist/cli.mjs +281 -98
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/docs/README.md +3 -3
  7. package/dist/docs/SKILL.md +5 -3
  8. package/dist/docs/shortcuts/standard/agent-handoff.md +58 -0
  9. package/dist/docs/shortcuts/standard/commit-code.md +0 -2
  10. package/dist/docs/shortcuts/standard/create-or-update-pr-simple.md +0 -2
  11. package/dist/docs/shortcuts/standard/create-or-update-pr-with-validation-plan.md +0 -2
  12. package/dist/docs/shortcuts/standard/implement-beads.md +0 -2
  13. package/dist/docs/shortcuts/standard/new-architecture-doc.md +0 -2
  14. package/dist/docs/shortcuts/standard/new-guideline.md +0 -2
  15. package/dist/docs/shortcuts/standard/new-plan-spec.md +0 -2
  16. package/dist/docs/shortcuts/standard/new-research-brief.md +0 -2
  17. package/dist/docs/shortcuts/standard/new-shortcut.md +53 -0
  18. package/dist/docs/shortcuts/standard/new-validation-plan.md +0 -2
  19. package/dist/docs/shortcuts/standard/plan-implementation-with-beads.md +25 -0
  20. package/dist/docs/shortcuts/standard/precommit-process.md +0 -2
  21. package/dist/docs/shortcuts/standard/review-code-python.md +0 -2
  22. package/dist/docs/shortcuts/standard/review-code-typescript.md +0 -2
  23. package/dist/docs/shortcuts/standard/welcome-user.md +1 -3
  24. package/dist/docs/shortcuts/system/shortcut-explanation.md +0 -2
  25. package/dist/docs/shortcuts/system/skill-brief.md +4 -2
  26. package/dist/docs/shortcuts/system/skill.md +5 -3
  27. package/dist/docs/skill-brief.md +4 -2
  28. package/dist/docs/tbd-design.md +10 -7
  29. package/dist/index.mjs +1 -1
  30. package/dist/{src-4YQOOM4t.mjs → src-DlYKGbJl.mjs} +2 -2
  31. package/dist/{src-4YQOOM4t.mjs.map → src-DlYKGbJl.mjs.map} +1 -1
  32. package/dist/tbd +281 -98
  33. package/package.json +1 -1
  34. package/dist/docs/shortcuts/standard/new-implementation-beads-from-spec.md +0 -29
package/README.md CHANGED
@@ -94,7 +94,7 @@ status or context or knowledge and know what to do next:
94
94
  | What you say | What happens | What runs |
95
95
  | --- | --- | --- |
96
96
  | "Let's plan a new feature that …" | Agent creates a spec from a template | `tbd shortcut new-plan-spec` |
97
- | "Break this spec into beads" | Agent creates implementation beads from the spec | `tbd shortcut new-implementation-beads-from-spec` |
97
+ | "Break this spec into beads" | Agent creates implementation beads from the spec | `tbd shortcut plan-implementation-with-beads` |
98
98
  | "Implement these beads" | Agent works through beads systematically | `tbd shortcut implement-beads` |
99
99
  | "Create a bead for the bug where …" | Agent creates and tracks a bead | `tbd create "..." --type=bug` |
100
100
  | "Let's work on current beads" | Agent finds ready beads and starts working | `tbd ready` |
@@ -340,7 +340,7 @@ tbd template --add=<url> --name=<name>
340
340
  | `new-research-brief` | Create a research document |
341
341
  | `new-architecture-doc` | Create an architecture document |
342
342
  | `new-validation-plan` | Create a test/validation plan |
343
- | `new-implementation-beads-from-spec` | Break a spec into implementation beads |
343
+ | `plan-implementation-with-beads` | Break a spec into implementation beads |
344
344
  | `implement-beads` | Implement beads from a spec |
345
345
  | `precommit-process` | Pre-commit review and testing |
346
346
  | `commit-code` | Commit with pre-commit checks |
@@ -386,7 +386,7 @@ For non-trivial features, tbd supports a full spec-driven workflow:
386
386
 
387
387
  1. **Plan**: Create a planning spec (`tbd shortcut new-plan-spec`)
388
388
  2. **Break down**: Convert spec into implementation beads
389
- (`tbd shortcut new-implementation-beads-from-spec`)
389
+ (`tbd shortcut plan-implementation-with-beads`)
390
390
  3. **Implement**: Work through beads systematically (`tbd shortcut implement-beads`)
391
391
  4. **Validate**: Create validation plan, run tests (`tbd shortcut new-validation-plan`)
392
392
  5. **Ship**: Commit, create PR (`tbd shortcut create-or-update-pr-with-validation-plan`)
package/dist/bin.mjs CHANGED
@@ -13576,7 +13576,7 @@ function serializeIssue(issue) {
13576
13576
  * Package version, derived from git at build time.
13577
13577
  * Format: X.Y.Z for releases, X.Y.Z-dev.N.hash for dev builds.
13578
13578
  */
13579
- const VERSION$1 = "0.1.9";
13579
+ const VERSION$1 = "0.1.11";
13580
13580
 
13581
13581
  //#endregion
13582
13582
  //#region src/cli/lib/version.ts
@@ -98364,6 +98364,26 @@ async function repairWorktree(baseDir, status, remote = "origin", syncBranch = S
98364
98364
  }
98365
98365
  }
98366
98366
  /**
98367
+ * Ensure worktree is attached to sync branch, not detached HEAD.
98368
+ * Old tbd versions (pre-v0.1.9) created worktrees with --detach flag.
98369
+ * This repairs them automatically.
98370
+ *
98371
+ * @param worktreePath - Path to the worktree directory
98372
+ * @returns true if worktree was detached and repaired, false if already attached
98373
+ */
98374
+ async function ensureWorktreeAttached(worktreePath) {
98375
+ try {
98376
+ if (!await git("-C", worktreePath, "branch", "--show-current").catch(() => "")) {
98377
+ await git("-C", worktreePath, "checkout", SYNC_BRANCH);
98378
+ return true;
98379
+ }
98380
+ return false;
98381
+ } catch (error) {
98382
+ console.warn("Warning: Could not check worktree HEAD status:", error);
98383
+ return false;
98384
+ }
98385
+ }
98386
+ /**
98367
98387
  * Migrate data from wrong location (.tbd/data-sync/) to worktree.
98368
98388
  *
98369
98389
  * Used when data was incorrectly written to the direct path instead of the worktree.
@@ -98383,6 +98403,7 @@ async function migrateDataToWorktree(baseDir, removeSource = false) {
98383
98403
  const correctPath = join(baseDir, WORKTREE_DIR, TBD_DIR, DATA_SYNC_DIR_NAME);
98384
98404
  const worktreePath = join(baseDir, WORKTREE_DIR);
98385
98405
  try {
98406
+ await ensureWorktreeAttached(worktreePath);
98386
98407
  const wrongIssuesPath = join(wrongPath, "issues");
98387
98408
  const wrongMappingsPath = join(wrongPath, "mappings");
98388
98409
  let issueFiles = [];
@@ -101152,6 +101173,7 @@ var SyncHandler = class extends BaseCommand {
101152
101173
  async commitWorktreeChanges() {
101153
101174
  const worktreePath = join(this.tbdRoot, WORKTREE_DIR);
101154
101175
  try {
101176
+ await ensureWorktreeAttached(worktreePath);
101155
101177
  const status = await git("-C", worktreePath, "status", "--porcelain");
101156
101178
  if (!status || status.trim() === "") return emptyTallies();
101157
101179
  const tallies = parseGitStatus(status);
@@ -101492,6 +101514,158 @@ const searchCommand = new Command("search").description("Search issues by text")
101492
101514
  await new SearchHandler(command).run(query, options);
101493
101515
  });
101494
101516
 
101517
+ //#endregion
101518
+ //#region src/cli/lib/sections.ts
101519
+ /**
101520
+ * Render the REPOSITORY section.
101521
+ *
101522
+ * Used by: status, doctor
101523
+ *
101524
+ * Shows:
101525
+ * - tbd version
101526
+ * - Repository path
101527
+ * - Initialization status
101528
+ * - Git repository status and branch
101529
+ * - Git version (with support warning if needed)
101530
+ *
101531
+ * @param data - Repository data to render
101532
+ * @param colors - Color functions
101533
+ * @param options - Rendering options
101534
+ */
101535
+ function renderRepositorySection(data, colors, options) {
101536
+ if (options?.showHeading) console.log(colors.bold(formatHeading("Repository")));
101537
+ console.log(`${colors.bold("tbd")} v${data.version}`);
101538
+ console.log(`Repository: ${data.workingDirectory}`);
101539
+ if (data.initialized) console.log(` ${colors.success(ICONS.SUCCESS)} Initialized (.tbd/)`);
101540
+ else console.log(` ${colors.error(ICONS.ERROR)} Not initialized`);
101541
+ if (data.gitRepository) {
101542
+ const branchInfo = data.gitBranch ? ` (${data.gitBranch})` : "";
101543
+ console.log(` ${colors.success(ICONS.SUCCESS)} Git repository${branchInfo}`);
101544
+ if (data.gitVersion) {
101545
+ const versionIcon = data.gitVersionSupported ? colors.success(ICONS.SUCCESS) : colors.warn(ICONS.WARN);
101546
+ const versionNote = data.gitVersionSupported ? "" : ` ${colors.dim(`(requires ${MIN_GIT_VERSION}+)`)}`;
101547
+ console.log(` ${versionIcon} Git ${data.gitVersion}${versionNote}`);
101548
+ }
101549
+ } else console.log(` ${colors.error(ICONS.ERROR)} Git repository not found`);
101550
+ }
101551
+ /**
101552
+ * Render the CONFIG section (sync branch, remote, prefix).
101553
+ *
101554
+ * Used by: status, doctor
101555
+ *
101556
+ * Shows key-value pairs with dim keys.
101557
+ *
101558
+ * @param data - Config data to render
101559
+ * @param colors - Color functions
101560
+ */
101561
+ function renderConfigSection(data, colors) {
101562
+ if (!data.syncBranch && !data.remote && !data.displayPrefix) return;
101563
+ console.log("");
101564
+ if (data.syncBranch) console.log(`${colors.dim("Sync branch:")} ${data.syncBranch}`);
101565
+ if (data.remote) console.log(`${colors.dim("Remote:")} ${data.remote}`);
101566
+ if (data.displayPrefix) console.log(`${colors.dim("ID prefix:")} ${data.displayPrefix}-`);
101567
+ }
101568
+ /**
101569
+ * Render the INTEGRATIONS section.
101570
+ *
101571
+ * Used by: status, doctor
101572
+ *
101573
+ * Shows diagnostic lines for each integration check.
101574
+ *
101575
+ * @param checks - Array of integration checks
101576
+ * @param colors - Color functions
101577
+ * @returns Whether any integrations are missing (for follow-up suggestions)
101578
+ */
101579
+ function renderIntegrationsSection(checks, colors) {
101580
+ console.log("");
101581
+ console.log(colors.bold(formatHeading("Integrations")));
101582
+ let hasMissing = false;
101583
+ for (const check of checks) {
101584
+ const icon = check.installed ? colors.success(ICONS.SUCCESS) : colors.dim(ICONS.ERROR);
101585
+ const pathDim = colors.dim(`(${check.path})`);
101586
+ console.log(` ${icon} ${check.name} ${pathDim}`);
101587
+ if (!check.installed) hasMissing = true;
101588
+ }
101589
+ return hasMissing;
101590
+ }
101591
+ /**
101592
+ * Render the STATISTICS section.
101593
+ *
101594
+ * Used by: stats, doctor
101595
+ *
101596
+ * Shows aligned statistic block with labels and values.
101597
+ *
101598
+ * @param data - Statistics data to render
101599
+ * @param colors - Color functions
101600
+ * @param options - Rendering options
101601
+ */
101602
+ function renderStatisticsSection(data, colors, options) {
101603
+ if (options?.showHeading !== false) {
101604
+ console.log("");
101605
+ console.log(colors.bold(formatHeading("Statistics")));
101606
+ }
101607
+ const maxLabelLen = Math.max(...[
101608
+ "Ready",
101609
+ "In progress",
101610
+ "Blocked",
101611
+ "Open",
101612
+ "Total"
101613
+ ].map((l) => l.length));
101614
+ const formatLine = (label, value) => {
101615
+ return ` ${label}:${" ".repeat(maxLabelLen - label.length + 1)}${value}`;
101616
+ };
101617
+ console.log(formatLine("Ready", data.ready));
101618
+ console.log(formatLine("In progress", data.inProgress));
101619
+ console.log(formatLine("Blocked", data.blocked));
101620
+ console.log(formatLine("Open", data.open));
101621
+ console.log(formatLine("Total", data.total));
101622
+ }
101623
+ /**
101624
+ * Render a warning block about beads coexistence.
101625
+ *
101626
+ * Used by: status
101627
+ *
101628
+ * @param colors - Color functions
101629
+ */
101630
+ function renderBeadsWarning(colors) {
101631
+ console.log("");
101632
+ console.log(`${colors.warn(ICONS.WARN)} Beads directory detected alongside tbd`);
101633
+ console.log("This may cause confusion for AI agents.");
101634
+ console.log(`Run ${colors.bold("tbd setup beads --disable")} for migration options`);
101635
+ }
101636
+ /**
101637
+ * Render worktree status line.
101638
+ *
101639
+ * Used by: status
101640
+ *
101641
+ * @param path - Worktree path
101642
+ * @param healthy - Whether worktree is healthy
101643
+ * @param colors - Color functions
101644
+ */
101645
+ function renderWorktreeStatus(path, healthy, colors) {
101646
+ console.log("");
101647
+ if (healthy) console.log(`${colors.dim("Worktree:")} ${path} (healthy)`);
101648
+ else {
101649
+ console.log(`${colors.warn("Worktree:")} ${path} (${colors.error("unhealthy")})`);
101650
+ console.log(" Run: tbd doctor --fix");
101651
+ }
101652
+ }
101653
+ /**
101654
+ * Render footer with command suggestions.
101655
+ *
101656
+ * Used by: status, doctor, stats
101657
+ *
101658
+ * @param suggestions - Array of {command, description} pairs
101659
+ * @param colors - Color functions
101660
+ */
101661
+ function renderFooter(suggestions, colors) {
101662
+ console.log("");
101663
+ if (suggestions.length === 0) return;
101664
+ const parts = suggestions.map((s) => `${colors.bold(`'${s.command}'`)} for ${s.description}`);
101665
+ if (parts.length === 1) console.log(`Use ${parts[0]}.`);
101666
+ else console.log(`Use ${parts.join(", ")}.`);
101667
+ }
101668
+
101495
101669
  //#endregion
101496
101670
  //#region src/cli/commands/status.ts
101497
101671
  /**
@@ -101628,82 +101802,72 @@ var StatusHandler = class extends BaseCommand {
101628
101802
  renderText(data) {
101629
101803
  const colors = this.output.getColors();
101630
101804
  if (!data.initialized) {
101631
- console.log(`${colors.warn("Not a tbd repository.")}`);
101632
- console.log("");
101633
- console.log("Detected:");
101634
- if (data.git_repository) {
101635
- const branchInfo = data.git_branch ? ` (${data.git_branch} branch)` : "";
101636
- console.log(` ${colors.success("✓")} Git repository${branchInfo}`);
101637
- if (data.git_version) {
101638
- const versionStatus = data.git_version_supported ? colors.success("✓") : colors.warn("⚠");
101639
- const versionNote = data.git_version_supported ? "" : ` ${colors.dim(`(requires ${MIN_GIT_VERSION}+)`)}`;
101640
- console.log(` ${versionStatus} Git ${data.git_version}${versionNote}`);
101641
- }
101642
- } else console.log(` ${colors.error("✗")} Git repository not found`);
101643
- if (data.beads_detected) {
101644
- const countInfo = data.beads_issue_count !== null ? ` (.beads/ with ${data.beads_issue_count} issues)` : "";
101645
- console.log(` ${colors.success("✓")} Beads repository${countInfo}`);
101646
- } else console.log(` ${colors.dim("✗")} Beads not detected`);
101647
- console.log(` ${colors.error("✗")} tbd not initialized`);
101648
- console.log("");
101649
- console.log("To get started:");
101650
- if (data.beads_detected) console.log(` ${colors.bold("tbd setup --auto")} # Migrate from Beads (recommended)`);
101651
- else console.log(` ${colors.bold("tbd setup --auto --prefix=<name>")} # Full setup with prefix`);
101652
- console.log(` ${colors.bold("tbd init --prefix=X")} # Surgical init only`);
101805
+ this.renderPreInitText(data, colors);
101653
101806
  return;
101654
101807
  }
101655
- console.log(`${colors.bold("tbd")} v${data.tbd_version}`);
101808
+ renderRepositorySection({
101809
+ version: data.tbd_version,
101810
+ workingDirectory: data.working_directory,
101811
+ initialized: data.initialized,
101812
+ gitRepository: data.git_repository,
101813
+ gitBranch: data.git_branch,
101814
+ gitVersion: data.git_version,
101815
+ gitVersionSupported: data.git_version_supported
101816
+ }, colors);
101817
+ if (data.beads_detected) renderBeadsWarning(colors);
101818
+ renderConfigSection({
101819
+ syncBranch: data.sync_branch,
101820
+ remote: data.remote,
101821
+ displayPrefix: data.display_prefix
101822
+ }, colors);
101823
+ if (renderIntegrationsSection([{
101824
+ name: "Claude Code hooks",
101825
+ installed: data.integrations.claude_code,
101826
+ path: data.integrations.claude_code_path
101827
+ }, {
101828
+ name: "Codex AGENTS.md",
101829
+ installed: data.integrations.codex,
101830
+ path: data.integrations.codex_path
101831
+ }], colors)) {
101832
+ console.log("");
101833
+ console.log(`Run ${colors.bold("tbd setup auto")} to configure detected agents`);
101834
+ }
101835
+ if (data.worktree_healthy !== null && data.worktree_path) renderWorktreeStatus(data.worktree_path, data.worktree_healthy, colors);
101836
+ renderFooter([{
101837
+ command: "tbd stats",
101838
+ description: "issue statistics"
101839
+ }, {
101840
+ command: "tbd doctor",
101841
+ description: "health checks"
101842
+ }], colors);
101843
+ }
101844
+ /**
101845
+ * Render pre-init text (unique to status command).
101846
+ * This is not shared with doctor since doctor requires initialization.
101847
+ */
101848
+ renderPreInitText(data, colors) {
101849
+ console.log(`${colors.warn("Not a tbd repository.")}`);
101656
101850
  console.log("");
101657
- console.log(`Repository: ${data.working_directory}`);
101658
- console.log(` ${colors.success("✓")} Initialized (.tbd/)`);
101851
+ console.log("Detected:");
101659
101852
  if (data.git_repository) {
101660
- const branchInfo = data.git_branch ? ` (${data.git_branch})` : "";
101661
- console.log(` ${colors.success("✓")} Git repository${branchInfo}`);
101853
+ const branchInfo = data.git_branch ? ` (${data.git_branch} branch)` : "";
101854
+ console.log(` ${colors.success(ICONS.SUCCESS)} Git repository${branchInfo}`);
101662
101855
  if (data.git_version) {
101663
- const versionStatus = data.git_version_supported ? colors.success("✓") : colors.warn("⚠");
101856
+ const versionStatus = data.git_version_supported ? colors.success(ICONS.SUCCESS) : colors.warn(ICONS.WARN);
101664
101857
  const versionNote = data.git_version_supported ? "" : ` ${colors.dim(`(requires ${MIN_GIT_VERSION}+)`)}`;
101665
101858
  console.log(` ${versionStatus} Git ${data.git_version}${versionNote}`);
101666
101859
  }
101667
- }
101860
+ } else console.log(` ${colors.error(ICONS.ERROR)} Git repository not found`);
101668
101861
  if (data.beads_detected) {
101669
- console.log("");
101670
- console.log(`${colors.warn("⚠")} Beads directory detected alongside tbd`);
101671
- console.log(` This may cause confusion for AI agents.`);
101672
- console.log(` Run ${colors.bold("tbd setup beads --disable")} for migration options`);
101673
- }
101674
- if (data.sync_branch || data.remote || data.display_prefix) {
101675
- console.log("");
101676
- if (data.sync_branch) console.log(`${colors.dim("Sync branch:")} ${data.sync_branch}`);
101677
- if (data.remote) console.log(`${colors.dim("Remote:")} ${data.remote}`);
101678
- if (data.display_prefix) console.log(`${colors.dim("ID prefix:")} ${data.display_prefix}-`);
101679
- }
101862
+ const countInfo = data.beads_issue_count !== null ? ` (.beads/ with ${data.beads_issue_count} issues)` : "";
101863
+ console.log(` ${colors.success(ICONS.SUCCESS)} Beads repository${countInfo}`);
101864
+ } else console.log(` ${colors.dim(ICONS.ERROR)} Beads not detected`);
101865
+ console.log(` ${colors.error(ICONS.ERROR)} tbd not initialized`);
101680
101866
  console.log("");
101681
- console.log(colors.bold(formatHeading("Integrations")));
101682
- let hasMissingIntegrations = false;
101683
- if (data.integrations.claude_code) console.log(` ${colors.success("")} Claude Code hooks ${colors.dim(`(${data.integrations.claude_code_path})`)}`);
101684
- else {
101685
- console.log(` ${colors.dim("✗")} Claude Code hooks ${colors.dim(`(${data.integrations.claude_code_path})`)}`);
101686
- hasMissingIntegrations = true;
101687
- }
101688
- if (data.integrations.codex) console.log(` ${colors.success("✓")} Codex AGENTS.md ${colors.dim(`(${data.integrations.codex_path})`)}`);
101689
- else {
101690
- console.log(` ${colors.dim("✗")} Codex AGENTS.md ${colors.dim(`(${data.integrations.codex_path})`)}`);
101691
- hasMissingIntegrations = true;
101692
- }
101693
- if (hasMissingIntegrations) {
101694
- console.log("");
101695
- console.log(`Run ${colors.bold("tbd setup auto")} to configure detected agents`);
101696
- }
101697
- if (data.worktree_healthy !== null) {
101698
- console.log("");
101699
- if (data.worktree_healthy) console.log(`${colors.dim("Worktree:")} ${data.worktree_path} (healthy)`);
101700
- else {
101701
- console.log(`${colors.warn("Worktree:")} ${data.worktree_path} (${colors.error("unhealthy")})`);
101702
- console.log(` Run: tbd doctor --fix`);
101703
- }
101704
- }
101705
- console.log("");
101706
- console.log(`Use ${colors.bold("'tbd stats'")} for issue statistics, ${colors.bold("'tbd doctor'")} for health checks.`);
101867
+ console.log("To get started:");
101868
+ if (data.beads_detected) console.log(` ${colors.bold("tbd setup --auto")} # Migrate from Beads (recommended)`);
101869
+ else console.log(` ${colors.bold("tbd setup --auto --prefix=<name>")} # Full setup with prefix`);
101870
+ console.log(` ${colors.bold("tbd init --prefix=X")} # Surgical init only`);
101707
101871
  }
101708
101872
  };
101709
101873
  const statusCommand = new Command("status").description("Show repository status and orientation").action(async (_options, command) => {
@@ -101770,14 +101934,21 @@ var StatsHandler = class extends BaseCommand {
101770
101934
  this.output.data(stats, () => {
101771
101935
  const colors = this.output.getColors();
101772
101936
  console.log(colors.bold("Summary:"));
101773
- console.log(` Ready: ${stats.ready}`);
101774
- console.log(` In progress: ${stats.byStatus.in_progress}`);
101775
- console.log(` Blocked: ${stats.blocked}`);
101776
- console.log(` Open: ${stats.byStatus.open}`);
101777
- console.log(` Total: ${stats.total}`);
101937
+ renderStatisticsSection({
101938
+ ready: stats.ready,
101939
+ inProgress: stats.byStatus.in_progress,
101940
+ blocked: stats.blocked,
101941
+ open: stats.byStatus.open,
101942
+ total: stats.total
101943
+ }, colors, { showHeading: false });
101778
101944
  if (stats.total === 0) {
101779
- console.log("");
101780
- console.log(`Use ${colors.bold("'tbd status'")} for setup info, ${colors.bold("'tbd doctor'")} for health checks.`);
101945
+ renderFooter([{
101946
+ command: "tbd status",
101947
+ description: "setup info"
101948
+ }, {
101949
+ command: "tbd doctor",
101950
+ description: "health checks"
101951
+ }], colors);
101781
101952
  return;
101782
101953
  }
101783
101954
  console.log("");
@@ -101799,8 +101970,13 @@ var StatsHandler = class extends BaseCommand {
101799
101970
  const count = stats.byPriority[i];
101800
101971
  if (count !== void 0 && count > 0) console.log(` ${formatPriority(i)} (${priorityLabels[i].padEnd(8)}) ${count}`);
101801
101972
  }
101802
- console.log("");
101803
- console.log(`Use ${colors.bold("'tbd status'")} for setup info, ${colors.bold("'tbd doctor'")} for health checks.`);
101973
+ renderFooter([{
101974
+ command: "tbd status",
101975
+ description: "setup info"
101976
+ }, {
101977
+ command: "tbd doctor",
101978
+ description: "health checks"
101979
+ }], colors);
101804
101980
  });
101805
101981
  }
101806
101982
  };
@@ -101908,24 +102084,21 @@ var DoctorHandler = class extends BaseCommand {
101908
102084
  healthy: allOk
101909
102085
  }, () => {
101910
102086
  const colors = this.output.getColors();
101911
- console.log(colors.bold(formatHeading("Repository")));
101912
- console.log(`tbd v${VERSION}`);
101913
- console.log(`Repository: ${this.cwd}`);
101914
- console.log(` ${colors.success("✓")} Initialized (.tbd/)`);
101915
- if (statusInfo.gitBranch) console.log(` ${colors.success("✓")} Git repository (${statusInfo.gitBranch})`);
101916
- if (this.config) {
101917
- console.log("");
101918
- console.log(`${colors.dim("Sync branch:")} ${this.config.sync.branch}`);
101919
- console.log(`${colors.dim("Remote:")} ${this.config.sync.remote}`);
101920
- if (this.config.display.id_prefix) console.log(`${colors.dim("ID prefix:")} ${this.config.display.id_prefix}-`);
101921
- }
101922
- console.log("");
101923
- console.log(colors.bold(formatHeading("Statistics")));
101924
- console.log(` Ready: ${statsInfo.ready}`);
101925
- console.log(` In progress: ${statsInfo.inProgress}`);
101926
- console.log(` Blocked: ${statsInfo.blocked}`);
101927
- console.log(` Open: ${statsInfo.open}`);
101928
- console.log(` Total: ${statsInfo.total}`);
102087
+ renderRepositorySection({
102088
+ version: VERSION,
102089
+ workingDirectory: this.cwd,
102090
+ initialized: true,
102091
+ gitRepository: !!statusInfo.gitBranch,
102092
+ gitBranch: statusInfo.gitBranch,
102093
+ gitVersion: null,
102094
+ gitVersionSupported: true
102095
+ }, colors, { showHeading: true });
102096
+ if (this.config) renderConfigSection({
102097
+ syncBranch: this.config.sync.branch,
102098
+ remote: this.config.sync.remote,
102099
+ displayPrefix: this.config.display.id_prefix
102100
+ }, colors);
102101
+ renderStatisticsSection(statsInfo, colors);
101929
102102
  console.log("");
101930
102103
  console.log(colors.bold(formatHeading("Integrations")));
101931
102104
  renderDiagnostics(integrationChecks, colors);
@@ -105731,8 +105904,18 @@ const TBD_SESSION_SCRIPT = `#!/bin/bash
105731
105904
  # Installed by: tbd setup --auto
105732
105905
  # This script runs on SessionStart and PreCompact
105733
105906
 
105907
+ # Get npm global bin directory (if npm is available)
105908
+ NPM_GLOBAL_BIN=""
105909
+ if command -v npm &> /dev/null; then
105910
+ NPM_PREFIX=$(npm config get prefix 2>/dev/null)
105911
+ if [ -n "$NPM_PREFIX" ] && [ -d "$NPM_PREFIX/bin" ]; then
105912
+ NPM_GLOBAL_BIN="$NPM_PREFIX/bin"
105913
+ fi
105914
+ fi
105915
+
105734
105916
  # Add common binary locations to PATH (persists for entire script)
105735
- export PATH="$HOME/.local/bin:$HOME/bin:/usr/local/bin:$PATH"
105917
+ # Include npm global bin if found
105918
+ export PATH="$NPM_GLOBAL_BIN:$HOME/.local/bin:$HOME/bin:/usr/local/bin:$PATH"
105736
105919
 
105737
105920
  # Function to ensure tbd is available
105738
105921
  ensure_tbd() {
@@ -105775,9 +105958,9 @@ ensure_tbd() {
105775
105958
  else
105776
105959
  echo "[tbd] WARNING: tbd installed but not found in PATH"
105777
105960
  echo "[tbd] Checking common locations..."
105778
- # Try to find and add to path
105779
- for dir in ~/.local/bin ~/.local/node_modules/.bin /usr/local/bin; do
105780
- if [ -x "$dir/tbd" ]; then
105961
+ # Try to find and add to path (include npm global bin)
105962
+ for dir in "$NPM_GLOBAL_BIN" ~/.local/bin ~/.local/node_modules/.bin /usr/local/bin; do
105963
+ if [ -n "$dir" ] && [ -x "$dir/tbd" ]; then
105781
105964
  export PATH="$dir:$PATH"
105782
105965
  echo "[tbd] Found at $dir/tbd"
105783
105966
  return 0