get-tbd 0.1.19 → 0.1.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.
package/dist/bin.mjs CHANGED
@@ -13576,6 +13576,12 @@ const YAML_STRINGIFY_OPTIONS_COMPACT = {
13576
13576
  * ~50 lines is slightly more than one terminal screen.
13577
13577
  */
13578
13578
  const PAGINATION_LINE_THRESHOLD = 50;
13579
+ /**
13580
+ * Maximum lines to display when showing parent bead context in `tbd show`.
13581
+ * The parent's full serialized output is truncated to this many lines,
13582
+ * with an ellipsis and omitted-line count appended if exceeded.
13583
+ */
13584
+ const PARENT_CONTEXT_MAX_LINES = 50;
13579
13585
 
13580
13586
  //#endregion
13581
13587
  //#region src/utils/yaml-utils.ts
@@ -13878,7 +13884,7 @@ function serializeIssue(issue) {
13878
13884
  * Package version, derived from git at build time.
13879
13885
  * Format: X.Y.Z for releases, X.Y.Z-dev.N.hash for dev builds.
13880
13886
  */
13881
- const VERSION$1 = "0.1.19";
13887
+ const VERSION$1 = "0.1.20";
13882
13888
 
13883
13889
  //#endregion
13884
13890
  //#region src/cli/lib/version.ts
@@ -97286,17 +97292,15 @@ async function writeFileAsync(filePath, data, options = DEFAULT_WRITE_OPTIONS) {
97286
97292
  *
97287
97293
  * On main/dev branches:
97288
97294
  * .tbd/
97289
- * config.yml - Project configuration (tracked)
97290
- * state.yml - Local state (gitignored)
97291
- * .gitignore - Ignores docs/, data-sync-worktree/, data-sync/
97292
- * docs/ - Installed documentation (gitignored, regenerated on setup)
97293
- * data-sync-worktree/ - Hidden worktree checkout of tbd-sync branch
97294
- * .tbd/
97295
- * data-sync/
97296
- * issues/
97297
- * mappings/
97298
- * attic/
97299
- * meta.yml
97295
+ * Committed to the repo:
97296
+ * config.yml - Project configuration
97297
+ * .gitignore - Controls what's gitignored below
97298
+ * workspaces/ - Persistent state (outbox, named workspaces)
97299
+ * Gitignored (local only):
97300
+ * state.yml - Local state
97301
+ * docs/ - Installed documentation (regenerated on setup)
97302
+ * data-sync-worktree/ - Hidden worktree checkout of tbd-sync branch
97303
+ * .tbd/data-sync/ - issues/, mappings/, attic/, meta.yml
97300
97304
  *
97301
97305
  * On tbd-sync branch:
97302
97306
  * .tbd/
@@ -99150,7 +99154,10 @@ Example:
99150
99154
  "",
99151
99155
  "# Temporary files",
99152
99156
  "*.tmp",
99153
- "*.temp"
99157
+ "*.temp",
99158
+ "",
99159
+ "# workspaces/ stores state (including outbox) committed to the working branch",
99160
+ "!workspaces/"
99154
99161
  ]);
99155
99162
  this.output.debug(`Created ${TBD_DIR}/.gitignore`);
99156
99163
  await mkdir(join(cwd, TBD_SHORTCUTS_SYSTEM), { recursive: true });
@@ -100802,6 +100809,45 @@ const listCommand = new Command("list").description("List issues").option("--sta
100802
100809
  *
100803
100810
  * See: tbd-design.md §4.4 Show
100804
100811
  */
100812
+ /**
100813
+ * Render a serialized issue with colorized output, optionally truncated.
100814
+ *
100815
+ * @param issue - The issue to render
100816
+ * @param colors - Color functions
100817
+ * @param maxLines - If set, truncate output to this many lines with an omission notice
100818
+ * @returns Array of formatted lines
100819
+ */
100820
+ function renderIssueLines(issue, colors) {
100821
+ const serialized = serializeIssue(issue);
100822
+ const output = [];
100823
+ for (const line of serialized.split("\n")) if (line === "---") output.push(colors.dim(line));
100824
+ else if (line.startsWith("id:")) output.push(`${colors.dim("id:")} ${colors.id(line.slice(4))}`);
100825
+ else if (line.startsWith("status:")) {
100826
+ const status = line.slice(8).trim();
100827
+ const statusColor = getStatusColor(status, colors);
100828
+ output.push(`${colors.dim("status:")} ${statusColor(status)}`);
100829
+ } else if (line.startsWith("priority:")) {
100830
+ const priority = parseInt(line.slice(10).trim(), 10);
100831
+ const priorityColor = getPriorityColor(priority, colors);
100832
+ output.push(`${colors.dim("priority:")} ${priorityColor(formatPriority(priority))}`);
100833
+ } else if (line.startsWith("title:")) output.push(`${colors.dim("title:")} ${colors.bold(line.slice(7))}`);
100834
+ else if (line.startsWith("spec_path:")) output.push(`${colors.dim("spec_path:")} ${colors.id(line.slice(11))}`);
100835
+ else if (line.startsWith("## Notes")) output.push(colors.bold(line));
100836
+ else if (line.startsWith(" - ")) output.push(` - ${colors.label(line.slice(4))}`);
100837
+ else output.push(line);
100838
+ return output;
100839
+ }
100840
+ /**
100841
+ * Print lines with optional max-lines truncation.
100842
+ * If maxLines is set and the output exceeds it, truncates and appends an omission notice.
100843
+ */
100844
+ function printWithTruncation(lines, colors, maxLines) {
100845
+ if (maxLines && lines.length > maxLines) {
100846
+ const omitted = lines.length - maxLines;
100847
+ for (const line of lines.slice(0, maxLines)) console.log(line);
100848
+ console.log(colors.dim(`… [${omitted} line${omitted === 1 ? "" : "s"} omitted]`));
100849
+ } else for (const line of lines) console.log(line);
100850
+ }
100805
100851
  var ShowHandler = class extends BaseCommand {
100806
100852
  async run(id, command, options) {
100807
100853
  const ctx = await loadFullContext(command);
@@ -100812,29 +100858,28 @@ var ShowHandler = class extends BaseCommand {
100812
100858
  } catch {
100813
100859
  throw new NotFoundError("Issue", id);
100814
100860
  }
100861
+ let parentIssue;
100862
+ if (issue.parent_id && options.parent !== false) try {
100863
+ parentIssue = await readIssue(ctx.dataSyncDir, issue.parent_id);
100864
+ } catch {}
100865
+ const maxLines = options.maxLines ? parseInt(options.maxLines, 10) : void 0;
100815
100866
  const displayId = ctx.displayId(issue.id);
100816
100867
  const displayIssue = {
100817
100868
  ...issue,
100818
- displayId
100869
+ displayId,
100870
+ ...parentIssue ? { parent: {
100871
+ ...parentIssue,
100872
+ displayId: ctx.displayId(parentIssue.id)
100873
+ } } : {}
100819
100874
  };
100820
100875
  this.output.data(displayIssue, () => {
100821
100876
  const colors = this.output.getColors();
100822
- const lines = serializeIssue(issue).split("\n");
100823
- for (const line of lines) if (line === "---") console.log(colors.dim(line));
100824
- else if (line.startsWith("id:")) console.log(`${colors.dim("id:")} ${colors.id(line.slice(4))}`);
100825
- else if (line.startsWith("status:")) {
100826
- const status = line.slice(8).trim();
100827
- const statusColor = getStatusColor(status, colors);
100828
- console.log(`${colors.dim("status:")} ${statusColor(status)}`);
100829
- } else if (line.startsWith("priority:")) {
100830
- const priority = parseInt(line.slice(10).trim(), 10);
100831
- const priorityColor = getPriorityColor(priority, colors);
100832
- console.log(`${colors.dim("priority:")} ${priorityColor(formatPriority(priority))}`);
100833
- } else if (line.startsWith("title:")) console.log(`${colors.dim("title:")} ${colors.bold(line.slice(7))}`);
100834
- else if (line.startsWith("spec_path:")) console.log(`${colors.dim("spec_path:")} ${colors.id(line.slice(11))}`);
100835
- else if (line.startsWith("## Notes")) console.log(colors.bold(line));
100836
- else if (line.startsWith(" - ")) console.log(` - ${colors.label(line.slice(4))}`);
100837
- else console.log(line);
100877
+ printWithTruncation(renderIssueLines(issue, colors), colors, maxLines);
100878
+ if (parentIssue) {
100879
+ console.log("");
100880
+ console.log(colors.dim("The parent of this bead is:"));
100881
+ printWithTruncation(renderIssueLines(parentIssue, colors), colors, PARENT_CONTEXT_MAX_LINES);
100882
+ }
100838
100883
  if (options.showOrder) {
100839
100884
  console.log("");
100840
100885
  console.log(colors.dim("child_order_hints:"));
@@ -100847,7 +100892,7 @@ var ShowHandler = class extends BaseCommand {
100847
100892
  });
100848
100893
  }
100849
100894
  };
100850
- const showCommand = new Command("show").description("Show issue details").argument("<id>", "Issue ID").option("--show-order", "Display children ordering hints").action(async (id, options, command) => {
100895
+ const showCommand = new Command("show").description("Show issue details").argument("<id>", "Issue ID").option("--show-order", "Display children ordering hints").option("--no-parent", "Suppress automatic parent context display").option("--max-lines <n>", "Truncate output to N lines").action(async (id, options, command) => {
100851
100896
  await new ShowHandler(command).run(id, command, options);
100852
100897
  });
100853
100898
 
@@ -103178,6 +103223,8 @@ var SyncHandler = class extends BaseCommand {
103178
103223
  console.log(" 1. Commit: git add .tbd/workspaces && git commit -m 'tbd: save outbox'");
103179
103224
  console.log(" 2. Push your working branch: git push");
103180
103225
  console.log(" 3. Run 'tbd sync' when push access is available");
103226
+ console.log("");
103227
+ console.log(" WARNING: Do NOT add .tbd/workspaces/ to .gitignore -- that would cause data loss.");
103181
103228
  } else {
103182
103229
  const totalInOutbox = existingOutboxCount + result.saved;
103183
103230
  if (existingOutboxCount > 0) {
@@ -103193,6 +103240,8 @@ var SyncHandler = class extends BaseCommand {
103193
103240
  console.log(" 2. Push your working branch: git push");
103194
103241
  console.log(" 3. Run 'tbd sync' when push access is available");
103195
103242
  console.log(" (outbox will be imported automatically on successful sync)");
103243
+ console.log("");
103244
+ console.log(" WARNING: Do NOT add .tbd/workspaces/ to .gitignore -- that would cause data loss.");
103196
103245
  }
103197
103246
  } catch (saveError) {
103198
103247
  const saveErrorMsg = saveError instanceof Error ? saveError.message : String(saveError);
@@ -107366,7 +107415,7 @@ function inferGuidelineCategory(name) {
107366
107415
  if (name.startsWith("typescript-")) return "typescript";
107367
107416
  if (name.startsWith("python-")) return "python";
107368
107417
  if (name.includes("tdd") || name.includes("testing") || name.includes("golden")) return "testing";
107369
- if (name.startsWith("general-") || name.includes("rules") || name.includes("patterns") || name.startsWith("backward-") || name.startsWith("convex-") || name.startsWith("release-")) return "general";
107418
+ if (name.startsWith("general-") || name.includes("rules") || name.includes("patterns") || name.startsWith("backward-") || name.startsWith("convex-") || name.startsWith("release-") || name.startsWith("writing-")) return "general";
107370
107419
  }
107371
107420
  var GuidelinesHandler = class extends DocCommandHandler {
107372
107421
  constructor(command) {
@@ -108270,7 +108319,10 @@ var SetupDefaultHandler = class extends BaseCommand {
108270
108319
  "",
108271
108320
  "# Temporary files",
108272
108321
  "*.tmp",
108273
- "*.temp"
108322
+ "*.temp",
108323
+ "",
108324
+ "# workspaces/ stores state (including outbox) committed to the working branch",
108325
+ "!workspaces/"
108274
108326
  ]);
108275
108327
  if (tbdGitignoreResult.created) console.log(` ${colors.success("✓")} Created .tbd/.gitignore`);
108276
108328
  else if (tbdGitignoreResult.added.length > 0) console.log(` ${colors.success("✓")} Updated .tbd/.gitignore with new patterns`);
@@ -108397,7 +108449,10 @@ Example:
108397
108449
  "",
108398
108450
  "# Temporary files",
108399
108451
  "*.tmp",
108400
- "*.temp"
108452
+ "*.temp",
108453
+ "",
108454
+ "# workspaces/ stores state (including outbox) committed to the working branch",
108455
+ "!workspaces/"
108401
108456
  ]);
108402
108457
  if (tbdGitignoreResult.created) console.log(` ${colors.success("✓")} Created .tbd/.gitignore`);
108403
108458
  else if (tbdGitignoreResult.added.length > 0) console.log(` ${colors.success("✓")} Updated .tbd/.gitignore`);