get-tbd 0.1.13 → 0.1.15

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 (57) hide show
  1. package/README.md +47 -28
  2. package/dist/bin.mjs +410 -170
  3. package/dist/bin.mjs.map +1 -1
  4. package/dist/cli.mjs +202 -94
  5. package/dist/cli.mjs.map +1 -1
  6. package/dist/docs/README.md +47 -28
  7. package/dist/docs/SKILL.md +61 -18
  8. package/dist/docs/guidelines/bun-monorepo-patterns.md +2096 -0
  9. package/dist/docs/guidelines/cli-agent-skill-patterns.md +79 -5
  10. package/dist/docs/guidelines/error-handling-rules.md +66 -0
  11. package/dist/docs/guidelines/pnpm-monorepo-patterns.md +2868 -0
  12. package/dist/docs/guidelines/release-notes-guidelines.md +140 -0
  13. package/dist/docs/guidelines/{sync-troubleshooting.md → tbd-sync-troubleshooting.md} +1 -1
  14. package/dist/docs/guidelines/typescript-sorting-patterns.md +234 -0
  15. package/dist/docs/guidelines/typescript-yaml-handling-rules.md +195 -0
  16. package/dist/docs/install/claude-header.md +13 -6
  17. package/dist/docs/shortcuts/standard/agent-handoff.md +1 -0
  18. package/dist/docs/shortcuts/standard/checkout-third-party-repo.md +50 -0
  19. package/dist/docs/shortcuts/standard/{cleanup-all.md → code-cleanup-all.md} +3 -2
  20. package/dist/docs/shortcuts/standard/{cleanup-update-docstrings.md → code-cleanup-docstrings.md} +1 -0
  21. package/dist/docs/shortcuts/standard/{cleanup-remove-trivial-tests.md → code-cleanup-tests.md} +1 -0
  22. package/dist/docs/shortcuts/standard/{commit-code.md → code-review-and-commit.md} +1 -0
  23. package/dist/docs/shortcuts/standard/coding-spike.md +54 -0
  24. package/dist/docs/shortcuts/standard/create-or-update-pr-simple.md +1 -0
  25. package/dist/docs/shortcuts/standard/create-or-update-pr-with-validation-plan.md +1 -0
  26. package/dist/docs/shortcuts/standard/implement-beads.md +1 -0
  27. package/dist/docs/shortcuts/standard/merge-upstream.md +1 -0
  28. package/dist/docs/shortcuts/standard/new-architecture-doc.md +1 -0
  29. package/dist/docs/shortcuts/standard/new-guideline.md +8 -0
  30. package/dist/docs/shortcuts/standard/new-plan-spec.md +1 -0
  31. package/dist/docs/shortcuts/standard/new-research-brief.md +1 -0
  32. package/dist/docs/shortcuts/standard/new-shortcut.md +27 -1
  33. package/dist/docs/shortcuts/standard/new-validation-plan.md +1 -0
  34. package/dist/docs/shortcuts/standard/plan-implementation-with-beads.md +1 -0
  35. package/dist/docs/shortcuts/standard/precommit-process.md +1 -0
  36. package/dist/docs/shortcuts/standard/review-code-python.md +1 -0
  37. package/dist/docs/shortcuts/standard/review-code-typescript.md +1 -0
  38. package/dist/docs/shortcuts/standard/review-code.md +1 -0
  39. package/dist/docs/shortcuts/standard/review-github-pr.md +89 -17
  40. package/dist/docs/shortcuts/standard/revise-all-architecture-docs.md +1 -0
  41. package/dist/docs/shortcuts/standard/revise-architecture-doc.md +1 -0
  42. package/dist/docs/shortcuts/standard/setup-github-cli.md +1 -0
  43. package/dist/docs/shortcuts/standard/sync-failure-recovery.md +6 -53
  44. package/dist/docs/shortcuts/standard/update-specs-status.md +1 -0
  45. package/dist/docs/shortcuts/standard/welcome-user.md +2 -1
  46. package/dist/docs/shortcuts/system/skill-brief.md +1 -1
  47. package/dist/docs/shortcuts/system/skill.md +48 -12
  48. package/dist/docs/skill-brief.md +1 -1
  49. package/dist/docs/tbd-design.md +13 -1
  50. package/dist/index.d.mts +20 -6
  51. package/dist/index.mjs +2 -2
  52. package/dist/{src-BfhjLZXE.mjs → src-Ct16P2Ox.mjs} +154 -22
  53. package/dist/src-Ct16P2Ox.mjs.map +1 -0
  54. package/dist/tbd +410 -170
  55. package/package.json +1 -1
  56. package/dist/docs/guidelines/typescript-monorepo-patterns.md +0 -72
  57. package/dist/src-BfhjLZXE.mjs.map +0 -1
@@ -0,0 +1,140 @@
1
+ ---
2
+ title: Release Notes Guidelines
3
+ description: Guidelines for writing clear, accurate release notes
4
+ ---
5
+ # Release Notes Guidelines
6
+
7
+ Write release notes that are accurate, scannable, and useful to users deciding whether
8
+ to upgrade.
9
+
10
+ ## Structure
11
+
12
+ Use these sections in order (omit empty sections):
13
+
14
+ ```markdown
15
+ ## What's Changed
16
+
17
+ ### Features
18
+ - New capabilities users can now do
19
+
20
+ ### Fixes
21
+ - Bug fixes and corrections
22
+
23
+ ### Refactoring
24
+ - Internal improvements (only if user-visible impact)
25
+
26
+ ### Documentation
27
+ - Doc improvements (only notable ones)
28
+
29
+ **Full commit history**: [link to compare]
30
+ ```
31
+
32
+ ## Core Principle: Describe the Delta
33
+
34
+ **Think in terms of two points in time:**
35
+
36
+ 1. The state of the application at the previous release
37
+ 2. The state of the application at this release
38
+
39
+ Release notes describe the **aggregate difference** between these two states.
40
+ Don’t recap individual commits or intermediate changes - describe what’s different now
41
+ compared to before.
42
+
43
+ **Example:** If a feature was added and then bug-fixed before release, don’t list the
44
+ bug fix separately.
45
+ Describe the feature as it now works (the complete, working version).
46
+
47
+ ## Writing Principles
48
+
49
+ ### 1. Consolidate Related Changes
50
+
51
+ Group sub-features, fixes, and improvements with their parent feature rather than
52
+ listing them separately.
53
+ If a bug fix is for a feature added in the same release, incorporate it into the feature
54
+ description.
55
+
56
+ **Bad:**
57
+
58
+ ```markdown
59
+ ### Features
60
+ - **Workspace sync**: New tbd save command
61
+ - **Workspace list**: Show saved workspaces
62
+
63
+ ### Fixes
64
+ - **Workspace mappings**: Save now filters mappings correctly
65
+ ```
66
+
67
+ **Good:**
68
+
69
+ ```markdown
70
+ ### Features
71
+ - **Workspace sync feature**: New commands for managing local workspace backups:
72
+ - `tbd save` to export issues (filters mappings correctly)
73
+ - `tbd workspace list` to show saved workspaces with counts
74
+ ```
75
+
76
+ ### 2. Write From the User’s Perspective
77
+
78
+ Describe capabilities users now have, not implementation details.
79
+ A user reading the notes should understand what they can do differently after upgrading.
80
+
81
+ ### 3. Be Specific About Impact
82
+
83
+ Include the user-facing impact, not just the implementation detail.
84
+
85
+ **Bad:**
86
+
87
+ > Increased git maxBuffer
88
+
89
+ **Good:**
90
+
91
+ > Git maxBuffer overflow: Increased buffer from 1MB to 50MB to prevent sync failures on
92
+ > large repos
93
+
94
+ ### 4. Use Consistent Formatting
95
+
96
+ - Bold the feature/fix name
97
+ - Use bullet points for sub-items
98
+ - Include command names in backticks
99
+ - Keep descriptions concise (1-2 lines)
100
+
101
+ ### 5. Skip Internal-Only Changes
102
+
103
+ Don’t include:
104
+
105
+ - Test-only changes (unless they fix flaky tests users noticed)
106
+ - Pure refactoring with no user impact
107
+ - CI/tooling changes
108
+ - Minor doc typo fixes
109
+
110
+ ## Review Checklist
111
+
112
+ Before finalizing release notes:
113
+
114
+ - [ ] Does each item describe the aggregate delta from the previous release?
115
+ - [ ] Are related changes (features + their fixes) consolidated under one heading?
116
+ - [ ] Would a user understand what’s different after upgrading?
117
+ - [ ] Are feature names/commands in consistent format?
118
+ - [ ] Are internal-only changes excluded?
119
+
120
+ ## Example
121
+
122
+ ```markdown
123
+ ## What's Changed
124
+
125
+ ### Features
126
+
127
+ - **Workspace sync feature**: New commands for managing local workspace backups:
128
+ - `tbd save` to export issues to workspace directories (supports `--updates-only`)
129
+ - `tbd workspace list` to show saved workspaces with issue counts
130
+ - `tbd import --workspace` to restore from workspace backups
131
+ - **Child bead ordering**: New `child_order` field allows explicit ordering of child
132
+ beads
133
+
134
+ ### Fixes
135
+
136
+ - **Git maxBuffer overflow**: Increased buffer from 1MB to 50MB to prevent sync
137
+ failures on large repos
138
+
139
+ **Full commit history**: https://github.com/org/repo/compare/v0.1.12...v0.1.13
140
+ ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- title: Sync and Workspace Troubleshooting
2
+ title: tbd Sync and Workspace Troubleshooting
3
3
  description: Common issues and solutions for tbd sync and workspace operations
4
4
  author: Joshua Levy (github.com/jlevy) with LLM assistance
5
5
  ---
@@ -0,0 +1,234 @@
1
+ ---
2
+ title: TypeScript Sorting Patterns
3
+ description: Deterministic sorting patterns and comparison chains for TypeScript
4
+ author: Joshua Levy (github.com/jlevy) with LLM assistance
5
+ ---
6
+ # TypeScript Sorting Patterns
7
+
8
+ **Related**: `tbd guidelines typescript-rules`, `tbd guidelines general-testing-rules`
9
+
10
+ ## 1. Always Make Sorting Deterministic
11
+
12
+ Never leave a sort with only a primary key.
13
+ When two items have the same primary sort value, the output order is undefined and will
14
+ vary across runs, platforms, and data sizes.
15
+ This causes flaky tests, confusing UI, and unreproducible bugs.
16
+
17
+ **Always add a secondary (or tertiary) sort key that is guaranteed unique**, such as an
18
+ ID or timestamp.
19
+
20
+ ### BAD: Primary sort only
21
+
22
+ ```typescript
23
+ // If two issues share the same priority, order is random.
24
+ issues.sort((a, b) => a.priority - b.priority);
25
+ ```
26
+
27
+ ### GOOD: Secondary sort for determinism
28
+
29
+ ```typescript
30
+ issues.sort((a, b) => {
31
+ const cmp = a.priority - b.priority;
32
+ if (cmp !== 0) return cmp;
33
+ return a.id.localeCompare(b.id);
34
+ });
35
+ ```
36
+
37
+ This pattern applies everywhere: UI lists, CLI output, test assertions, API responses.
38
+ If you can’t guarantee uniqueness of the primary key, you need a tiebreaker.
39
+
40
+ ## 2. Use Comparison Chains for Multi-Field Sorts
41
+
42
+ Hand-written multi-field comparators are verbose and error-prone.
43
+ A **comparison chain** (inspired by Google Guava’s `ComparisonChain`) provides a fluent
44
+ API that’s easier to read, write, and maintain.
45
+
46
+ ### Before: Manual multi-field sort with nulls
47
+
48
+ ```typescript
49
+ items.sort((a, b) => {
50
+ // Primary: priority ascending
51
+ if (a.priority !== b.priority) return a.priority - b.priority;
52
+ // Secondary: title, nulls last
53
+ if (a.title === null && b.title !== null) return 1;
54
+ if (a.title !== null && b.title === null) return -1;
55
+ if (a.title !== null && b.title !== null) {
56
+ const cmp = a.title.localeCompare(b.title);
57
+ if (cmp !== 0) return cmp;
58
+ }
59
+ // Tertiary: ID for determinism
60
+ return a.id.localeCompare(b.id);
61
+ });
62
+ ```
63
+
64
+ ### After: Comparison chain
65
+
66
+ ```typescript
67
+ items.sort(
68
+ comparisonChain<Item>()
69
+ .compare((i) => i.priority)
70
+ .compare((i) => i.title, ordering.nullsLast)
71
+ .compare((i) => i.id)
72
+ .result(),
73
+ );
74
+ ```
75
+
76
+ The chain short-circuits: once a `.compare()` step returns non-zero, subsequent steps
77
+ are skipped. This matches the semantics of manual `if (cmp !== 0) return cmp` chains.
78
+
79
+ ## 3. Comparison Chain Reference Implementation
80
+
81
+ The following is a standalone, dependency-free utility.
82
+ Copy it into your project:
83
+
84
+ ```typescript
85
+ export type Selector<T, K> = (item: T) => K;
86
+ export type Comparator<T> = (a: T, b: T) => number;
87
+
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ const defaultCompare: Comparator<any> = (a, b) => {
90
+ if (typeof a === 'string' && typeof b === 'string') {
91
+ return a.localeCompare(b);
92
+ }
93
+ if (a < b) return -1;
94
+ if (a > b) return 1;
95
+ return 0;
96
+ };
97
+
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ const nullLastCompare: Comparator<any> = (a, b) => {
100
+ if (a == null) return b == null ? 0 : 1;
101
+ if (b == null) return -1;
102
+ return defaultCompare(a, b);
103
+ };
104
+
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ const nullFirstCompare: Comparator<any> = (a, b) => {
107
+ if (a == null) return b == null ? 0 : -1;
108
+ if (b == null) return 1;
109
+ return defaultCompare(a, b);
110
+ };
111
+
112
+ /**
113
+ * A Google Guava-style comparison chain for fluent multi-field sorting.
114
+ *
115
+ * items.sort(comparisonChain<Item>()
116
+ * .compare(item => item.title, ordering.nullsLast)
117
+ * .compare(item => item.url)
118
+ * .result());
119
+ */
120
+ export const comparisonChain = <T>() => {
121
+ let compare: Comparator<T> = () => 0;
122
+
123
+ const chain: {
124
+ compare: <K>(selector: Selector<T, K>, comparator?: Comparator<K>) => typeof chain;
125
+ result: () => Comparator<T>;
126
+ } = {
127
+ compare: <K>(selector: Selector<T, K>, comparator: Comparator<K> = defaultCompare) => {
128
+ const prevCompare = compare;
129
+ compare = (a, b) => prevCompare(a, b) || comparator(selector(a), selector(b));
130
+ return chain;
131
+ },
132
+ result: () => compare,
133
+ };
134
+
135
+ return chain;
136
+ };
137
+
138
+ export const reverse =
139
+ <T>(comparator: Comparator<T>) =>
140
+ (a: T, b: T) =>
141
+ comparator(b, a);
142
+
143
+ const manualOrderComparator = <T>(order: readonly T[]): Comparator<T> => {
144
+ const orderMap = new Map(order.map((value, index) => [value, index]));
145
+ return (a: T, b: T): number => {
146
+ const indexA = orderMap.get(a);
147
+ const indexB = orderMap.get(b);
148
+ if (indexA === undefined) return indexB === undefined ? 0 : 1;
149
+ if (indexB === undefined) return -1;
150
+ return indexA - indexB;
151
+ };
152
+ };
153
+
154
+ export const ordering = {
155
+ nullsLast: nullLastCompare,
156
+ nullsFirst: nullFirstCompare,
157
+ default: defaultCompare,
158
+ reversed: reverse(defaultCompare),
159
+ manual: manualOrderComparator,
160
+ };
161
+ ```
162
+
163
+ ## 4. Common Ordering Strategies
164
+
165
+ | Ordering | Behavior |
166
+ | --- | --- |
167
+ | `ordering.default` | Strings via `localeCompare`, numbers via `<`/`>` |
168
+ | `ordering.reversed` | Reverse of default (descending) |
169
+ | `ordering.nullsLast` | `null`/`undefined` sort after all non-null values |
170
+ | `ordering.nullsFirst` | `null`/`undefined` sort before all non-null values |
171
+ | `ordering.manual(…)` | Sort by position in an explicit array; unlisted go last |
172
+ | `reverse(cmp)` | Wrap any comparator to invert its direction |
173
+
174
+ ## 5. Usage Examples
175
+
176
+ ### Simple priority + ID sort
177
+
178
+ ```typescript
179
+ issues.sort(
180
+ comparisonChain<Issue>()
181
+ .compare((i) => i.priority)
182
+ .compare((i) => i.id)
183
+ .result(),
184
+ );
185
+ ```
186
+
187
+ ### Descending date with ID tiebreaker
188
+
189
+ ```typescript
190
+ staleItems.sort(
191
+ comparisonChain<StaleItem>()
192
+ .compare((s) => s.daysSinceUpdate, ordering.reversed)
193
+ .compare((s) => s.issue.id)
194
+ .result(),
195
+ );
196
+ ```
197
+
198
+ ### Multi-field with nulls
199
+
200
+ ```typescript
201
+ items.sort(
202
+ comparisonChain<Item>()
203
+ .compare((i) => i.title, ordering.nullsLast)
204
+ .compare((i) => i.url, ordering.nullsLast)
205
+ .compare((i) => i.sequenceNum, ordering.nullsLast)
206
+ .result(),
207
+ );
208
+ ```
209
+
210
+ ### Custom enum ordering
211
+
212
+ ```typescript
213
+ const statusOrder = ['active', 'pending', 'archived'] as const;
214
+
215
+ items.sort(
216
+ comparisonChain<Item>()
217
+ .compare((i) => i.status, ordering.manual(statusOrder))
218
+ .compare((i) => i.name)
219
+ .result(),
220
+ );
221
+ ```
222
+
223
+ ### With a custom comparator (e.g. natural sort)
224
+
225
+ ```typescript
226
+ import { naturalCompare } from './sort.js';
227
+
228
+ items.sort(
229
+ comparisonChain<Item>()
230
+ .compare((i) => i.priority)
231
+ .compare((i) => getShortId(i), (a, b) => naturalCompare(a, b))
232
+ .result(),
233
+ );
234
+ ```
@@ -0,0 +1,195 @@
1
+ ---
2
+ title: TypeScript YAML Handling Rules
3
+ description: Best practices for parsing and serializing YAML in TypeScript
4
+ author: Joshua Levy (github.com/jlevy) with LLM assistance
5
+ globs: "*.ts"
6
+ ---
7
+ # TypeScript YAML Handling Rules
8
+
9
+ These guidelines ensure consistent, safe, and readable YAML handling across TypeScript
10
+ codebases. YAML is deceptively tricky—inconsistent quoting, serialization differences,
11
+ and lack of validation cause subtle bugs.
12
+
13
+ ## Use the Right Package
14
+
15
+ - **Use `yaml` (v2.x)**, not `js-yaml`. The `yaml` package has better TypeScript
16
+ support, more control over output formatting, and proper handling of edge cases.
17
+
18
+ ```ts
19
+ // Good
20
+ import { parse, stringify } from 'yaml';
21
+
22
+ // Avoid
23
+ import yaml from 'js-yaml';
24
+ ```
25
+
26
+ ## Centralize Serialization Options
27
+
28
+ - **Externalize settings to a central file** instead of scattering `stringify()` calls
29
+ with ad-hoc options throughout the codebase.
30
+
31
+ ```ts
32
+ // lib/settings.ts
33
+ export const DEFAULT_YAML_LINE_WIDTH = 88;
34
+
35
+ // Readable YAML output:
36
+ // - No forced quoting (YAML only quotes when necessary)
37
+ // - Line wrapping at 88 chars for readability
38
+ // - Sorted keys for deterministic diffs
39
+ export const YAML_STRINGIFY_OPTIONS = {
40
+ lineWidth: DEFAULT_YAML_LINE_WIDTH,
41
+ defaultStringType: 'PLAIN',
42
+ defaultKeyType: 'PLAIN',
43
+ sortMapEntries: true,
44
+ } as const;
45
+ ```
46
+
47
+ - **Use the centralized options** wherever you serialize YAML:
48
+
49
+ ```ts
50
+ // serialize.ts
51
+ import { stringify } from 'yaml';
52
+ import { YAML_STRINGIFY_OPTIONS } from '../lib/settings.js';
53
+
54
+ const yamlStr = stringify(frontmatterObj, YAML_STRINGIFY_OPTIONS);
55
+ ```
56
+
57
+ - **Optionally create wrapper functions** for additional convenience:
58
+
59
+ ```ts
60
+ // utils/yaml-utils.ts
61
+ import { stringify } from 'yaml';
62
+ import { YAML_STRINGIFY_OPTIONS } from '../lib/settings.js';
63
+
64
+ export function stringifyYaml(data: unknown, options?: object): string {
65
+ return stringify(data, { ...YAML_STRINGIFY_OPTIONS, ...options });
66
+ }
67
+ ```
68
+
69
+ ## Recommended Defaults
70
+
71
+ These defaults produce clean, readable YAML without unnecessary quoting:
72
+
73
+ | Option | Value | Rationale |
74
+ | --- | --- | --- |
75
+ | `lineWidth` | 88 | Line wrapping for readability (matches Black formatter) |
76
+ | `defaultStringType` | `'PLAIN'` | No quotes unless necessary (e.g., special chars, colons) |
77
+ | `defaultKeyType` | `'PLAIN'` | Unquoted keys: `name:` not `"name":` |
78
+ | `sortMapEntries` | `true` | Deterministic output for clean diffs |
79
+
80
+ The key insight: YAML is designed to be human-readable.
81
+ Forcing quotes everywhere (e.g., `"value"` instead of `value`) defeats this purpose.
82
+ Use `PLAIN` types to let YAML quote only when semantically required.
83
+
84
+ ## Validate with Zod
85
+
86
+ - **Always validate parsed YAML** with a Zod schema.
87
+ Raw `parse()` returns `unknown` and provides no guarantees about structure.
88
+
89
+ ```ts
90
+ // Good
91
+ import { z } from 'zod';
92
+ import { parse } from 'yaml';
93
+
94
+ const ConfigSchema = z.object({
95
+ name: z.string(),
96
+ version: z.string(),
97
+ });
98
+
99
+ const rawData = parse(content);
100
+ const result = ConfigSchema.safeParse(rawData);
101
+ if (!result.success) {
102
+ throw new Error(`Invalid config: ${result.error.message}`);
103
+ }
104
+ const config = result.data; // Typed and validated
105
+
106
+ // Avoid
107
+ const config = parse(content) as Config; // Type assertion with no runtime validation
108
+ ```
109
+
110
+ ## Handle Merge Conflicts
111
+
112
+ - **Check for git merge conflict markers** before parsing user-editable files.
113
+ Conflict markers cause cryptic YAML parse errors.
114
+
115
+ ```ts
116
+ export function parseYamlWithConflictDetection<T>(content: string, filePath?: string): T {
117
+ if (/^<<<<<<< /m.test(content) || /^=======/m.test(content) || /^>>>>>>> /m.test(content)) {
118
+ throw new MergeConflictError(
119
+ `File contains unresolved git merge conflict markers`,
120
+ filePath
121
+ );
122
+ }
123
+ return parse(content) as T;
124
+ }
125
+ ```
126
+
127
+ ## Common Antipatterns
128
+
129
+ ### Antipattern: Manual String Building
130
+
131
+ ```ts
132
+ // Bad: Manual YAML string construction
133
+ const yaml = `name: ${name}\nversion: ${version}`;
134
+
135
+ // Good: Use stringify()
136
+ const yaml = stringifyYaml({ name, version });
137
+ ```
138
+
139
+ ### Antipattern: Inconsistent Quoting
140
+
141
+ ```ts
142
+ // Bad: Inconsistent options across codebase
143
+ stringify(data1, { lineWidth: 80 });
144
+ stringify(data2, { lineWidth: 100, defaultStringType: 'QUOTE_DOUBLE' });
145
+ stringify(data3); // No options
146
+
147
+ // Good: Use centralized wrapper
148
+ stringifyYaml(data1);
149
+ stringifyYaml(data2);
150
+ stringifyYaml(data3);
151
+ ```
152
+
153
+ ### Antipattern: Unvalidated Parsing
154
+
155
+ ```ts
156
+ // Bad: Type assertion without validation
157
+ const config = parse(content) as Config;
158
+
159
+ // Good: Runtime validation
160
+ const config = ConfigSchema.parse(parse(content));
161
+ ```
162
+
163
+ ### Antipattern: Using gray-matter Directly for Serialization
164
+
165
+ ```ts
166
+ // Bad: gray-matter.stringify() has limited formatting control
167
+ import matter from 'gray-matter';
168
+ const output = matter.stringify(body, frontmatter);
169
+
170
+ // Good: Use gray-matter for parsing, yaml package for serialization
171
+ import matter from 'gray-matter';
172
+ import { stringifyYaml } from './yaml-utils.js';
173
+
174
+ const { data, content } = matter(input);
175
+ const output = `---\n${stringifyYaml(data)}---\n\n${content}`;
176
+ ```
177
+
178
+ ## Testing YAML Output
179
+
180
+ - **Don’t rely on key order in tests** when using `sortMapEntries: true`. Keys are
181
+ sorted alphabetically.
182
+
183
+ ```ts
184
+ // Fragile: Depends on key order
185
+ expect(yaml).toMatch(/^---\nname: foo\nversion: 1/);
186
+
187
+ // Robust: Tests presence, not order
188
+ expect(yaml).toContain('name: foo');
189
+ expect(yaml).toContain('version: 1');
190
+ ```
191
+
192
+ ## Related Guidelines
193
+
194
+ - For general TypeScript rules, see `tbd guidelines typescript-rules`
195
+ - For error handling patterns, see `tbd guidelines error-handling-rules`
@@ -1,12 +1,19 @@
1
1
  ---
2
2
  name: tbd
3
3
  description: >-
4
- Git-native issue tracking (beads), coding guidelines, and spec-driven planning for AI agents.
5
- Use for tracking issues with dependencies, creating and closing bugs, features, and tasks,
6
- planning specs for new features, implementing features from specs, code reviews, committing code,
7
- creating PRs, research briefs, and architecture docs. Invoke when user mentions: tbd, beads,
8
- issues, bugs, tasks, todo, tracking, specs, planning, implementation, validation, guidelines,
9
- shortcuts, templates, commit, PR workflows, code review, testing best practices, or monorepo patterns.
4
+ Git-native issue tracking (beads), coding guidelines, knowledge injection, and spec-driven
5
+ planning for AI agents. Drop-in replacement for bd/Beads with simpler architecture.
6
+
7
+ Use for: tracking issues/beads with dependencies, creating bugs/features/tasks, planning specs,
8
+ implementing features from specs, code reviews, committing code, creating PRs, loading coding
9
+ guidelines (TypeScript, Python, TDD, golden testing, Convex, monorepo patterns), code cleanup,
10
+ research briefs, architecture docs, agent handoffs, and checking out third-party library source code.
11
+
12
+ Invoke when user mentions: tbd, beads, bd, shortcuts, issues, bugs, tasks, features, epics, todo,
13
+ tracking, specs, planning, implementation, validation, guidelines, templates, commit, PR, pull request,
14
+ code review, testing, TDD, test-driven, golden testing, snapshot testing, TypeScript, Python, Convex,
15
+ monorepo, cleanup, dead code, refactor, handoff, research, architecture, labels, search, checkout library,
16
+ source code review, or any workflow shortcut.
10
17
  allowed-tools: Bash(tbd:*), Read, Write
11
18
  ---
12
19
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Agent Handoff
3
3
  description: Generate a concise handoff prompt for another coding agent to continue work
4
+ category: session
4
5
  author: Joshua Levy (github.com/jlevy) with LLM assistance
5
6
  ---
6
7
  Generate a high-signal handoff prompt for the next agent.
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Checkout Third-Party Repo
3
+ description: Get source code for libraries and third-party repos using git. Essential for reliable source code review. Prefer this to web searches or fetching of web pages from github.com as it is far more effective (github.com blocks web scraping from main website).
4
+ category: research
5
+ author: Joshua Levy (github.com/jlevy) with LLM assistance
6
+ ---
7
+ Clone a third-party library or tool’s repository locally to review its source code.
8
+
9
+ ## Why This Approach
10
+
11
+ **Do not** use web search or try to scrape GitHub.com for source code.
12
+ GitHub blocks scraping, results are messy, and you lose full codebase context.
13
+ Cloning locally gives you reliable, complete, searchable access to the exact version you
14
+ need.
15
+
16
+ ## Steps
17
+
18
+ 1. **Create attic directory** (if not exists):
19
+ ```bash
20
+ mkdir -p attic
21
+ ```
22
+
23
+ 2. **Add to .gitignore** (if not already):
24
+ ```bash
25
+ echo "attic/" >> .gitignore
26
+ ```
27
+
28
+ 3. **Identify the version in use**: Check `package.json`, `requirements.txt`,
29
+ `Cargo.toml`, etc. for the exact version of the dependency you’re investigating.
30
+
31
+ 4. **Clone the repo**:
32
+ ```bash
33
+ git clone <repo-url> attic/<repo-name>
34
+ ```
35
+
36
+ 5. **Checkout the matching version**: Find the tag or branch matching your project’s
37
+ version:
38
+ ```bash
39
+ cd attic/<repo-name>
40
+ git tag -l | grep <version> # Find matching tag
41
+ git checkout <tag-or-branch>
42
+ ```
43
+
44
+ 6. **Explore**: Now use standard tools (Grep, Read, Glob) to investigate the source.
45
+
46
+ ## Notes
47
+
48
+ - The `attic/` directory is gitignored—cloned repos won’t pollute your project
49
+ - You can clone multiple repos into attic/ as needed
50
+ - Delete cloned repos when done to save disk space
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Clean Up All Code
3
3
  description: Full cleanup cycle including duplicate removal, dead code, and code quality improvements
4
+ category: cleanup
4
5
  author: Joshua Levy (github.com/jlevy) with LLM assistance
5
6
  ---
6
7
  # Shortcut: Clean Up Code
@@ -52,9 +53,9 @@ cycle afterwords, fixing all build or test issues.
52
53
  - Review types and eliminate use of optional types as possible so we don’t spread
53
54
  state checks throughout the codebase.
54
55
 
55
- 7. **Remove trivial tests**: Follow `tbd shortcut cleanup-remove-trivial-tests`.
56
+ 7. **Remove trivial tests**: Follow `tbd shortcut code-cleanup-tests`.
56
57
 
57
- 8. **Update docstrings**: Follow `tbd shortcut cleanup-update-docstrings`.
58
+ 8. **Update docstrings**: Follow `tbd shortcut code-cleanup-docstrings`.
58
59
 
59
60
  9. **Consolidate constants and settings**: Determine what files hold shared settings
60
61
  (such as `settings.ts` or similar).
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: "Cleanup: Update Docstrings"
3
3
  description: Review and add concise docstrings to major functions and types
4
+ category: cleanup
4
5
  author: Joshua Levy (github.com/jlevy) with LLM assistance
5
6
  ---
6
7
  # Shortcut: Update Docstrings
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: "Cleanup: Remove Trivial Tests"
3
3
  description: Review and remove tests that do not add meaningful coverage
4
+ category: cleanup
4
5
  author: Joshua Levy (github.com/jlevy) with LLM assistance
5
6
  ---
6
7
  # Shortcut: Remove Trivial Tests