@towles/tool 0.0.107 → 0.0.109
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/README.md +7 -1
- package/package.json +2 -1
- package/plugins/tt-agentboard/README.md +160 -0
- package/plugins/tt-agentboard/apps/server/package.json +20 -0
- package/plugins/tt-agentboard/apps/server/src/main.ts +60 -0
- package/plugins/tt-agentboard/apps/tui/build.ts +11 -0
- package/plugins/tt-agentboard/apps/tui/bunfig.toml +1 -0
- package/plugins/tt-agentboard/apps/tui/package.json +23 -0
- package/plugins/tt-agentboard/apps/tui/scripts/sessionizer.sh +36 -0
- package/plugins/tt-agentboard/apps/tui/src/components/DetailPanel.tsx +350 -0
- package/plugins/tt-agentboard/apps/tui/src/components/DiffStats.tsx +33 -0
- package/plugins/tt-agentboard/apps/tui/src/components/SessionCard.tsx +177 -0
- package/plugins/tt-agentboard/apps/tui/src/components/StatusBar.tsx +49 -0
- package/plugins/tt-agentboard/apps/tui/src/constants.ts +46 -0
- package/plugins/tt-agentboard/apps/tui/src/detail-panel-height.ts +21 -0
- package/plugins/tt-agentboard/apps/tui/src/index.tsx +880 -0
- package/plugins/tt-agentboard/apps/tui/src/mux-context.ts +61 -0
- package/plugins/tt-agentboard/apps/tui/tsconfig.json +15 -0
- package/plugins/tt-agentboard/bun.lock +444 -0
- package/plugins/tt-agentboard/package.json +26 -0
- package/plugins/tt-agentboard/packages/mux-tmux/package.json +14 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/client.ts +550 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/index.ts +18 -0
- package/plugins/tt-agentboard/packages/mux-tmux/src/provider.ts +259 -0
- package/plugins/tt-agentboard/packages/mux-tmux/tsconfig.json +13 -0
- package/plugins/tt-agentboard/packages/runtime/package.json +14 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/tracker.ts +233 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/amp.ts +316 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/claude-code.ts +374 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/codex.ts +364 -0
- package/plugins/tt-agentboard/packages/runtime/src/agents/watchers/opencode.ts +249 -0
- package/plugins/tt-agentboard/packages/runtime/src/config.ts +70 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/agent-watcher.ts +38 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/agent.ts +16 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/index.ts +3 -0
- package/plugins/tt-agentboard/packages/runtime/src/contracts/mux.ts +148 -0
- package/plugins/tt-agentboard/packages/runtime/src/debug.ts +19 -0
- package/plugins/tt-agentboard/packages/runtime/src/index.ts +69 -0
- package/plugins/tt-agentboard/packages/runtime/src/mux/detect.ts +20 -0
- package/plugins/tt-agentboard/packages/runtime/src/mux/registry.ts +45 -0
- package/plugins/tt-agentboard/packages/runtime/src/plugins/loader.ts +152 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/context.ts +112 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/git-info.ts +164 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/index.ts +1753 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/launcher.ts +71 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/metadata-store.ts +86 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/pane-scanner.ts +327 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/port-scanner.ts +155 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/session-order.ts +127 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-manager.ts +232 -0
- package/plugins/tt-agentboard/packages/runtime/src/server/sidebar-width-sync.ts +66 -0
- package/plugins/tt-agentboard/packages/runtime/src/shared.ts +179 -0
- package/plugins/tt-agentboard/packages/runtime/src/themes.ts +750 -0
- package/plugins/tt-agentboard/packages/runtime/test/config.test.ts +83 -0
- package/plugins/tt-agentboard/packages/runtime/test/tracker.test.ts +172 -0
- package/plugins/tt-agentboard/packages/runtime/tsconfig.json +13 -0
- package/plugins/tt-agentboard/tsconfig.json +19 -0
- package/plugins/tt-auto-claude/.claude-plugin/plugin.json +8 -0
- package/plugins/tt-auto-claude/commands/create-issue.md +20 -0
- package/plugins/tt-auto-claude/commands/list.md +21 -0
- package/plugins/tt-auto-claude/skills/auto-claude/SKILL.md +71 -0
- package/plugins/tt-core/.claude-plugin/plugin.json +8 -0
- package/plugins/tt-core/README.md +18 -0
- package/plugins/tt-core/commands/improve-architecture.md +66 -0
- package/plugins/tt-core/commands/interview-me.md +38 -0
- package/plugins/tt-core/commands/prd-to-issues.md +49 -0
- package/plugins/tt-core/commands/refine-text.md +30 -0
- package/plugins/tt-core/commands/task.md +37 -0
- package/plugins/tt-core/commands/tdd.md +69 -0
- package/plugins/tt-core/commands/write-prd.md +69 -0
- package/plugins/tt-core/promptfooconfig.interview-me.yaml +155 -0
- package/plugins/tt-core/promptfooconfig.refine-text.yaml +242 -0
- package/plugins/tt-core/promptfooconfig.tdd.yaml +144 -0
- package/plugins/tt-core/promptfooconfig.write-prd.yaml +145 -0
- package/plugins/tt-core/skills/towles-tool/SKILL.md +35 -0
- package/src/cli.ts +2 -1
- package/src/commands/agentboard.ts +19 -2
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
description: tdd Iterative Eval
|
|
2
|
+
providers:
|
|
3
|
+
- id: anthropic:messages:claude-haiku-4-5-20251001
|
|
4
|
+
config:
|
|
5
|
+
max_tokens: 1500
|
|
6
|
+
prompts:
|
|
7
|
+
- '[{"role": "system", "content": "{{system_prompt}}"}, {"role": "user", "content": "{{user_message}}"}]'
|
|
8
|
+
defaultTest:
|
|
9
|
+
options:
|
|
10
|
+
provider: anthropic:messages:claude-haiku-4-5-20251001
|
|
11
|
+
vars:
|
|
12
|
+
system_prompt: file://commands/tdd.md
|
|
13
|
+
tests:
|
|
14
|
+
# 1. Simple function request
|
|
15
|
+
- description: "Simple function: validate email addresses"
|
|
16
|
+
vars:
|
|
17
|
+
user_message: "I need a function to validate email addresses"
|
|
18
|
+
assert:
|
|
19
|
+
- type: llm-rubric
|
|
20
|
+
value: "The response should show a test BEFORE any implementation code. The first code block should be a test (e.g., using describe/it/test/expect), not the implementation function."
|
|
21
|
+
- type: llm-rubric
|
|
22
|
+
value: "The response should ask clarifying questions about the interface (e.g., what counts as valid, return type, edge cases) OR write a test first before implementation."
|
|
23
|
+
- type: not-icontains
|
|
24
|
+
value: "function validateEmail"
|
|
25
|
+
|
|
26
|
+
# 2. Complex feature: rate limiter
|
|
27
|
+
- description: "Complex feature: rate limiter for API endpoints"
|
|
28
|
+
vars:
|
|
29
|
+
user_message: "Build a rate limiter for our API endpoints. It should limit requests per IP address."
|
|
30
|
+
assert:
|
|
31
|
+
- type: llm-rubric
|
|
32
|
+
value: "The response must either ask clarifying questions about the interface (window size, max requests, storage mechanism) or write a test first. It must NOT jump straight to implementing a rate limiter class/function."
|
|
33
|
+
- type: llm-rubric
|
|
34
|
+
value: "If code is shown, the first code block must be a test, not the rate limiter implementation."
|
|
35
|
+
|
|
36
|
+
# 3. Bug fix request
|
|
37
|
+
- description: "Bug fix: auth middleware timeout"
|
|
38
|
+
vars:
|
|
39
|
+
user_message: "Fix the auth middleware — it's timing out after 30 seconds on large payloads"
|
|
40
|
+
assert:
|
|
41
|
+
- type: llm-rubric
|
|
42
|
+
value: "The response should suggest writing a test that reproduces the timeout bug BEFORE attempting a fix. It should describe a red-green approach: first write a test that fails due to the timeout, then fix it."
|
|
43
|
+
- type: llm-rubric
|
|
44
|
+
value: "The response should NOT jump straight to modifying the middleware code without mentioning writing a failing test first."
|
|
45
|
+
|
|
46
|
+
# 4. Refactoring request
|
|
47
|
+
- description: "Refactoring: extract payment logic into a service"
|
|
48
|
+
vars:
|
|
49
|
+
user_message: "Refactor: extract the payment logic from the order controller into a PaymentService"
|
|
50
|
+
assert:
|
|
51
|
+
- type: llm-rubric
|
|
52
|
+
value: "The response should mention writing tests for the existing behavior first (characterization tests) before refactoring. It should follow the pattern: write tests for current behavior, then refactor, then verify tests still pass."
|
|
53
|
+
- type: llm-rubric
|
|
54
|
+
value: "The response should NOT start by creating the PaymentService class. Tests must come first."
|
|
55
|
+
|
|
56
|
+
# 5. Vague request: add caching
|
|
57
|
+
- description: "Vague request: add caching"
|
|
58
|
+
vars:
|
|
59
|
+
user_message: "Add caching to the app"
|
|
60
|
+
assert:
|
|
61
|
+
- type: llm-rubric
|
|
62
|
+
value: "The response MUST ask clarifying questions before writing any code. Questions should cover: what to cache, cache invalidation strategy, TTL, cache storage (in-memory, Redis, etc.), which endpoints/functions."
|
|
63
|
+
- type: llm-rubric
|
|
64
|
+
value: "The response should NOT write any implementation code for a caching system without first clarifying requirements."
|
|
65
|
+
|
|
66
|
+
# 6. Request with clear specs
|
|
67
|
+
- description: "Clear specs: parse CSV with header row"
|
|
68
|
+
vars:
|
|
69
|
+
user_message: "Write a parseCSV function that takes a string of CSV data with a header row and returns an array of objects where keys are the header names. Handle quoted fields with commas inside them."
|
|
70
|
+
assert:
|
|
71
|
+
- type: llm-rubric
|
|
72
|
+
value: "The first code shown must be a test. It should test parseCSV with a simple CSV string and check the returned array of objects. The implementation of parseCSV should come AFTER the test."
|
|
73
|
+
- type: llm-rubric
|
|
74
|
+
value: "The response should follow red-green-refactor: write test first, then minimal implementation, starting with the happy path before edge cases like quoted fields."
|
|
75
|
+
|
|
76
|
+
# 7. Tempting to implement first
|
|
77
|
+
- description: "Tempting: fibonacci with memoization"
|
|
78
|
+
vars:
|
|
79
|
+
user_message: "Write a fibonacci function with memoization for performance"
|
|
80
|
+
assert:
|
|
81
|
+
- type: llm-rubric
|
|
82
|
+
value: "Despite fibonacci being a well-known algorithm, the response must show a test FIRST (e.g., test that fib(0)=0, fib(1)=1, fib(10)=55) before showing any fibonacci implementation code."
|
|
83
|
+
- type: llm-rubric
|
|
84
|
+
value: "The response should NOT start with 'function fibonacci' or the implementation. The first code must be a test."
|
|
85
|
+
|
|
86
|
+
# 8. UI component
|
|
87
|
+
- description: "UI component: search autocomplete"
|
|
88
|
+
vars:
|
|
89
|
+
user_message: "Create a search autocomplete component that shows suggestions as the user types"
|
|
90
|
+
assert:
|
|
91
|
+
- type: llm-rubric
|
|
92
|
+
value: "The response should discuss testing the component behavior first (e.g., rendering, user input handling, showing suggestions). If code is shown, tests should come before the component implementation."
|
|
93
|
+
- type: llm-rubric
|
|
94
|
+
value: "The response should either ask clarifying questions about the component interface or start with a test describing expected behavior, NOT jump to writing JSX/HTML."
|
|
95
|
+
|
|
96
|
+
# 9. Existing code patterns
|
|
97
|
+
- description: "Existing patterns: add a new CLI command following existing patterns"
|
|
98
|
+
vars:
|
|
99
|
+
user_message: "Add a new 'stats' command to the CLI that shows project statistics. Follow the existing command patterns in src/commands/."
|
|
100
|
+
assert:
|
|
101
|
+
- type: llm-rubric
|
|
102
|
+
value: "The response should mention exploring existing code/patterns first, then writing a test for the new command before implementing it. It should follow red-green-refactor."
|
|
103
|
+
- type: llm-rubric
|
|
104
|
+
value: "The response should NOT create the command file first. It should start with understanding existing patterns, then write a test."
|
|
105
|
+
|
|
106
|
+
# 10. Error handling scenarios
|
|
107
|
+
- description: "Error handling: database connection retry logic"
|
|
108
|
+
vars:
|
|
109
|
+
user_message: "Add retry logic for database connections — retry 3 times with exponential backoff on connection failure"
|
|
110
|
+
assert:
|
|
111
|
+
- type: llm-rubric
|
|
112
|
+
value: "The response should write tests first that verify: retries happen 3 times, exponential backoff timing, eventual success after retries, and failure after max retries. Tests before implementation."
|
|
113
|
+
- type: llm-rubric
|
|
114
|
+
value: "The first code block must be a test, not the retry logic implementation."
|
|
115
|
+
|
|
116
|
+
# 11. Test that mentions running tests
|
|
117
|
+
- description: "Mentions running tests to confirm failure/pass"
|
|
118
|
+
vars:
|
|
119
|
+
user_message: "Write a stack data structure with push, pop, and peek operations"
|
|
120
|
+
assert:
|
|
121
|
+
- type: llm-rubric
|
|
122
|
+
value: "The response should explicitly mention running the test to confirm it fails (red phase) before writing implementation, and running again to confirm it passes (green phase)."
|
|
123
|
+
- type: llm-rubric
|
|
124
|
+
value: "The first code shown must be a test for the stack, not the Stack class implementation."
|
|
125
|
+
|
|
126
|
+
# 12. Happy path then edge cases ordering
|
|
127
|
+
- description: "Order: starts with happy path, then edge cases"
|
|
128
|
+
vars:
|
|
129
|
+
user_message: "Create a URL shortener service that generates short codes and resolves them back to original URLs"
|
|
130
|
+
assert:
|
|
131
|
+
- type: llm-rubric
|
|
132
|
+
value: "The response should indicate starting with happy path tests first (basic shorten and resolve), then moving to edge cases (duplicate URLs, invalid codes, expired links). This ordering should be explicit."
|
|
133
|
+
- type: llm-rubric
|
|
134
|
+
value: "Tests must be shown before any URL shortener implementation code."
|
|
135
|
+
|
|
136
|
+
# 13. Describes expected behavior in tests
|
|
137
|
+
- description: "Tests describe expected behavior, not implementation details"
|
|
138
|
+
vars:
|
|
139
|
+
user_message: "Build a todo list manager with add, remove, and list operations"
|
|
140
|
+
assert:
|
|
141
|
+
- type: llm-rubric
|
|
142
|
+
value: "The tests should describe behavior (e.g., 'should add a todo item', 'should remove a todo by id', 'should list all todos') rather than testing implementation details (e.g., internal array manipulation)."
|
|
143
|
+
- type: llm-rubric
|
|
144
|
+
value: "The first code block must be a test, and tests should focus on WHAT the module does, not HOW it does it internally."
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
description: write-prd Iterative Eval
|
|
2
|
+
|
|
3
|
+
providers:
|
|
4
|
+
- id: anthropic:messages:claude-haiku-4-5-20251001
|
|
5
|
+
config:
|
|
6
|
+
max_tokens: 1024
|
|
7
|
+
|
|
8
|
+
prompts:
|
|
9
|
+
- '[{"role": "system", "content": "{{system_prompt}}"}, {"role": "user", "content": "{{user_message}}"}]'
|
|
10
|
+
|
|
11
|
+
defaultTest:
|
|
12
|
+
options:
|
|
13
|
+
provider: anthropic:messages:claude-haiku-4-5-20251001
|
|
14
|
+
|
|
15
|
+
tests:
|
|
16
|
+
# ── 1. Vague idea ──────────────────────────────────────────────
|
|
17
|
+
- description: "vague idea: asks questions before writing PRD"
|
|
18
|
+
vars:
|
|
19
|
+
system_prompt: file://commands/write-prd.md
|
|
20
|
+
user_message: "We need PDF export"
|
|
21
|
+
assert:
|
|
22
|
+
- type: llm-rubric
|
|
23
|
+
value: "Response asks clarifying questions BEFORE producing a full PRD. It does NOT immediately output a complete PRD document. Questions should probe for details like what content to export, who the users are, or what format requirements exist."
|
|
24
|
+
- type: not-icontains
|
|
25
|
+
value: "## Technical Design"
|
|
26
|
+
|
|
27
|
+
# ── 2. Detailed idea with clear requirements ────────────────────
|
|
28
|
+
- description: "detailed idea: still asks questions to validate assumptions"
|
|
29
|
+
vars:
|
|
30
|
+
system_prompt: file://commands/write-prd.md
|
|
31
|
+
user_message: "Build a webhook system that lets users register HTTPS endpoints, receives events from our payment processor, validates signatures, retries failed deliveries with exponential backoff (max 5 retries), and logs all attempts. Target users are platform integrators."
|
|
32
|
+
assert:
|
|
33
|
+
- type: llm-rubric
|
|
34
|
+
value: "Even with detailed input, the response asks at least 1-2 clarifying questions about gaps (e.g., authentication, rate limits, event types, storage duration for logs). Does NOT skip straight to a complete PRD without any questions."
|
|
35
|
+
|
|
36
|
+
# ── 3. Missing user context ────────────────────────────────────
|
|
37
|
+
- description: "missing user context: asks who the users are"
|
|
38
|
+
vars:
|
|
39
|
+
system_prompt: file://commands/write-prd.md
|
|
40
|
+
user_message: "Add a dashboard that shows real-time metrics"
|
|
41
|
+
assert:
|
|
42
|
+
- type: llm-rubric
|
|
43
|
+
value: "Response asks about who will use this dashboard — roles, personas, or user types. Also asks about which metrics matter. Does not assume the audience."
|
|
44
|
+
- type: not-icontains
|
|
45
|
+
value: "## Technical Design"
|
|
46
|
+
|
|
47
|
+
# ── 4. Needs technical design input ─────────────────────────────
|
|
48
|
+
- description: "technical idea: asks about architecture and constraints"
|
|
49
|
+
vars:
|
|
50
|
+
system_prompt: file://commands/write-prd.md
|
|
51
|
+
user_message: "We need to add GraphQL support to our REST API"
|
|
52
|
+
assert:
|
|
53
|
+
- type: llm-rubric
|
|
54
|
+
value: "Response asks about technical constraints: which endpoints to expose via GraphQL, coexistence with REST, auth model, performance requirements, or existing schema. Does not produce a full PRD without understanding the technical landscape."
|
|
55
|
+
|
|
56
|
+
# ── 5. Unclear scope boundaries ─────────────────────────────────
|
|
57
|
+
- description: "unclear scope: asks about boundaries and non-goals"
|
|
58
|
+
vars:
|
|
59
|
+
system_prompt: file://commands/write-prd.md
|
|
60
|
+
user_message: "We should improve our search functionality"
|
|
61
|
+
assert:
|
|
62
|
+
- type: llm-rubric
|
|
63
|
+
value: "Response asks about scope: what kind of search (full-text, filters, faceted), what content is searchable, what 'improve' means specifically (speed, relevance, UX), and what is explicitly out of scope."
|
|
64
|
+
|
|
65
|
+
# ── 6. Non-technical stakeholder ────────────────────────────────
|
|
66
|
+
- description: "non-technical stakeholder: uses accessible language"
|
|
67
|
+
vars:
|
|
68
|
+
system_prompt: file://commands/write-prd.md
|
|
69
|
+
user_message: "Our customers keep complaining they can't find their invoices. We lose support tickets over this every week. Can we fix the billing section?"
|
|
70
|
+
assert:
|
|
71
|
+
- type: llm-rubric
|
|
72
|
+
value: "Response asks questions in accessible, non-technical language. Probes for specifics: what customers are doing when they can't find invoices, how many are affected, what the current flow looks like. Does not jump to technical solutions."
|
|
73
|
+
|
|
74
|
+
# ── 7. Internal tooling request ─────────────────────────────────
|
|
75
|
+
- description: "internal tooling: asks about workflows and users"
|
|
76
|
+
vars:
|
|
77
|
+
system_prompt: file://commands/write-prd.md
|
|
78
|
+
user_message: "We need an admin panel for managing feature flags"
|
|
79
|
+
assert:
|
|
80
|
+
- type: llm-rubric
|
|
81
|
+
value: "Response asks about who manages flags (eng, PM, ops), current flag management workflow, what operations are needed (CRUD, rollout percentages, targeting), and audit/safety requirements."
|
|
82
|
+
- type: not-icontains
|
|
83
|
+
value: "## Technical Design"
|
|
84
|
+
|
|
85
|
+
# ── 8. API/integration feature ──────────────────────────────────
|
|
86
|
+
- description: "API integration: asks about contracts and consumers"
|
|
87
|
+
vars:
|
|
88
|
+
system_prompt: file://commands/write-prd.md
|
|
89
|
+
user_message: "We need to integrate with Stripe for subscription billing"
|
|
90
|
+
assert:
|
|
91
|
+
- type: llm-rubric
|
|
92
|
+
value: "Response asks about billing models (flat, usage-based, tiered), existing payment handling, which Stripe APIs to use, webhook handling, and how subscriptions map to the product's plans. Gathers context before writing."
|
|
93
|
+
|
|
94
|
+
# ── 9. Performance improvement request ──────────────────────────
|
|
95
|
+
- description: "performance: asks about current state and targets"
|
|
96
|
+
vars:
|
|
97
|
+
system_prompt: file://commands/write-prd.md
|
|
98
|
+
user_message: "The app is too slow, we need to speed it up"
|
|
99
|
+
assert:
|
|
100
|
+
- type: llm-rubric
|
|
101
|
+
value: "Response asks about current performance metrics, which parts are slow, what the target is (specific latency, load time), and how performance is measured. Does not accept 'too slow' without quantification."
|
|
102
|
+
|
|
103
|
+
# ── 10. Migration/upgrade request ───────────────────────────────
|
|
104
|
+
- description: "migration: asks about current state and risk tolerance"
|
|
105
|
+
vars:
|
|
106
|
+
system_prompt: file://commands/write-prd.md
|
|
107
|
+
user_message: "We need to migrate from MongoDB to PostgreSQL"
|
|
108
|
+
assert:
|
|
109
|
+
- type: llm-rubric
|
|
110
|
+
value: "Response asks about data volume, downtime tolerance, migration strategy (big bang vs incremental), which collections/schemas need migration, and current MongoDB usage patterns. Does not produce a PRD without understanding the scope of the migration."
|
|
111
|
+
|
|
112
|
+
# ── 11. Multi-turn: answers provided, expects PRD draft ─────────
|
|
113
|
+
- description: "multi-turn: produces structured PRD after context gathered"
|
|
114
|
+
vars:
|
|
115
|
+
system_prompt: file://commands/write-prd.md
|
|
116
|
+
user_message: |
|
|
117
|
+
I want to add email notifications to our app.
|
|
118
|
+
|
|
119
|
+
You already asked questions and here are my answers:
|
|
120
|
+
- Users: both admins and regular users
|
|
121
|
+
- Triggers: account signup, password reset, weekly digest, payment receipt
|
|
122
|
+
- Preferences: users can opt out of digest but not transactional emails
|
|
123
|
+
- Technical: we use SendGrid, Node.js backend
|
|
124
|
+
- Scope: email only, no SMS or push for now
|
|
125
|
+
- Acceptance: emails delivered within 30 seconds, unsubscribe link in every email
|
|
126
|
+
|
|
127
|
+
Now write the PRD.
|
|
128
|
+
assert:
|
|
129
|
+
- type: llm-rubric
|
|
130
|
+
value: "Response produces a structured PRD with sections including Problem Statement, User Stories, Acceptance Criteria, and Non-Goals. User stories follow the 'As a [user], I want [action] so that [outcome]' format. Acceptance criteria are specific and testable (not vague like 'works well')."
|
|
131
|
+
- type: icontains
|
|
132
|
+
value: "User Stories"
|
|
133
|
+
- type: icontains
|
|
134
|
+
value: "Acceptance Criteria"
|
|
135
|
+
|
|
136
|
+
# ── 12. Feature with security implications ──────────────────────
|
|
137
|
+
- description: "security-sensitive: asks about auth and data protection"
|
|
138
|
+
vars:
|
|
139
|
+
system_prompt: file://commands/write-prd.md
|
|
140
|
+
user_message: "Add a file upload feature so users can attach documents to their profiles"
|
|
141
|
+
assert:
|
|
142
|
+
- type: llm-rubric
|
|
143
|
+
value: "Response asks about security considerations: file type restrictions, size limits, virus scanning, access control (who can see uploaded files), storage (local vs cloud), and data retention. Does not skip security concerns for a user-facing upload feature."
|
|
144
|
+
- type: not-icontains
|
|
145
|
+
value: "## Technical Design"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: towles-tool
|
|
3
|
+
description: Use towles-tool (`tt`) CLI for git helpers, journaling, and developer utilities. Use when asked about "tt commands", "create branch from issue", "daily notes", "meeting notes", or "check dependencies".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# towles-tool CLI
|
|
7
|
+
|
|
8
|
+
Personal CLI toolkit. Alias: `tt`
|
|
9
|
+
|
|
10
|
+
Config: `~/.config/towles-tool/towles-tool.settings.json`
|
|
11
|
+
|
|
12
|
+
## Git
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
tt gh branch # Create branch from GitHub issue
|
|
16
|
+
tt gh pr # Create pull request
|
|
17
|
+
tt gh branch-clean # Delete merged branches
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Journaling
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
tt journal daily-notes # Weekly file, daily sections (alias: tt today)
|
|
24
|
+
tt journal meeting # Meeting notes (alias: tt m)
|
|
25
|
+
tt journal note # General notes (alias: tt n)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Utilities
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
tt config # Show config (alias: cfg)
|
|
32
|
+
tt doctor # Check dependencies
|
|
33
|
+
tt graph # Visualize dependency graph
|
|
34
|
+
tt install # Configure Claude Code settings
|
|
35
|
+
```
|
package/src/cli.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
+
import { version } from "../package.json";
|
|
2
3
|
|
|
3
4
|
export const main = defineCommand({
|
|
4
|
-
meta: { name: "tt", description: "towles-tool — personal CLI utilities" },
|
|
5
|
+
meta: { name: "tt", version, description: "towles-tool — personal CLI utilities" },
|
|
5
6
|
subCommands: {
|
|
6
7
|
config: () => import("./commands/config.js").then((m) => m.default),
|
|
7
8
|
doctor: () => import("./commands/doctor.js").then((m) => m.default),
|
|
@@ -38,6 +38,14 @@ function ensureDeps(): void {
|
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
if (!existsSync(PLUGIN_DIR)) {
|
|
42
|
+
consola.error(`Agentboard plugin directory not found: ${PLUGIN_DIR}`);
|
|
43
|
+
consola.error(
|
|
44
|
+
"If installed globally, ensure the 'plugins' directory is included in the package.",
|
|
45
|
+
);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
const runtimeNodeModules = resolve(PLUGIN_DIR, "packages/runtime/node_modules");
|
|
42
50
|
if (!existsSync(runtimeNodeModules)) {
|
|
43
51
|
consola.info("Installing agentboard dependencies...");
|
|
@@ -308,7 +316,7 @@ function init(): void {
|
|
|
308
316
|
);
|
|
309
317
|
}
|
|
310
318
|
|
|
311
|
-
// Hooks
|
|
319
|
+
// Hooks — must match server's setupHooks() in provider.ts
|
|
312
320
|
const hookPost = (path: string, body?: string) => {
|
|
313
321
|
const bodyArg = body ? ` -d \\"${body}\\"` : "";
|
|
314
322
|
return `run-shell -b "curl -s -X POST http://${host}:${port}${path}${bodyArg} >/dev/null 2>&1 || true"`;
|
|
@@ -317,8 +325,17 @@ function init(): void {
|
|
|
317
325
|
const resizeBody =
|
|
318
326
|
"#{q:pane_id}|#{q:session_name}|#{q:window_id}|#{q:pane_width}|#{q:window_width}";
|
|
319
327
|
|
|
320
|
-
tmux(
|
|
328
|
+
tmux(
|
|
329
|
+
"set-hook",
|
|
330
|
+
"-g",
|
|
331
|
+
"client-session-changed",
|
|
332
|
+
`${hookPost("/focus", focusBody)} ; ${hookPost("/ensure-sidebar", focusBody)}`,
|
|
333
|
+
);
|
|
334
|
+
tmux("set-hook", "-g", "session-created", hookPost("/refresh"));
|
|
335
|
+
tmux("set-hook", "-g", "session-closed", hookPost("/refresh"));
|
|
336
|
+
tmux("set-hook", "-g", "client-resized", hookPost("/resize-sidebars"));
|
|
321
337
|
tmux("set-hook", "-g", "after-select-window", hookPost("/ensure-sidebar", focusBody));
|
|
338
|
+
tmux("set-hook", "-g", "after-new-window", hookPost("/ensure-sidebar", focusBody));
|
|
322
339
|
tmux("set-hook", "-g", "after-resize-pane", hookPost("/resize-sidebars", resizeBody));
|
|
323
340
|
}
|
|
324
341
|
|