stonecut 1.2.0 → 1.2.1

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 CHANGED
@@ -7,7 +7,9 @@ A CLI that drives PRD-driven development with agentic coding CLIs. You write the
7
7
 
8
8
  ## Workflow
9
9
 
10
- Ideas can come from anywhere — Jira tickets, Slack threads, MCP servers, or just a conversation. The pipeline starts once you're ready to act on one:
10
+ Ideas can come from anywhere — Jira tickets, Slack threads, MCP servers, or just a conversation. The pipeline has two entry points depending on where work originates:
11
+
12
+ **From a raw idea:** `roadmap issue → interview → PRD → issues → execute`
11
13
 
12
14
  1. **`/stonecut-interview`** — Stress-test the idea. Get grilled on the plan until it's solid.
13
15
  2. **`/stonecut-prd`** — Turn the validated idea into a PRD (local file or GitHub issue).
@@ -15,11 +17,15 @@ Ideas can come from anywhere — Jira tickets, Slack threads, MCP servers, or ju
15
17
  4. **`stonecut import`** _(optional)_ — If the PRD lives in GitHub, import it and its issues into `.stonecut/`.
16
18
  5. **`stonecut`** — Execute the issues sequentially with an agentic coding CLI.
17
19
 
20
+ **From a technical exploration:** `RFC issue → PRD → issues → execute`
21
+
22
+ Architecture decisions and refactoring plans that emerge from a technical investigation (e.g. a codebase review) skip the interview — the exploration itself produces the design decisions. Capture the outcome as an `rfc`-labeled GitHub issue, then write the PRD referencing it.
23
+
18
24
  Steps 1–3 are Claude Code skills installed via `stonecut setup-skills`. Steps 4–5 are the Stonecut CLI.
19
25
 
20
- ### Suggested: managing your idea backlog
26
+ ### Suggested: managing your backlog
21
27
 
22
- For projects using GitHub issues, we recommend tracking ideas with a `roadmap` label. When an idea is ready, interview it, write the PRD (which closes the roadmap issue), break it into sub-issues, import with `stonecut import --github`, and execute. See [DESIGN.md](DESIGN.md#suggested-practice-managing-your-idea-backlog-with-github-labels) for the full flow.
28
+ For projects using GitHub issues, we recommend tracking ideas with a `roadmap` label and architecture decisions with an `rfc` label. When an idea is ready, interview it, write the PRD (which closes the roadmap issue), break it into sub-issues, import with `stonecut import --github`, and execute. See [DESIGN.md](DESIGN.md#entry-points) for the full flow.
23
29
 
24
30
  ## Installation
25
31
 
@@ -342,13 +348,13 @@ To add a new source provider (e.g. Jira, Linear):
342
348
 
343
349
  ## Skills
344
350
 
345
- The repo ships three Claude Code skills for steps 1–3 of the workflow. Install them with:
351
+ The repo ships four Claude Code skills for the workflow. Install them with:
346
352
 
347
353
  ```sh
348
354
  stonecut setup-skills
349
355
  ```
350
356
 
351
- This creates symlinks in `~/.claude/skills/` pointing to the installed package. Once linked, they're available as `/stonecut-interview`, `/stonecut-prd`, and `/stonecut-issues` in any Claude Code session.
357
+ This creates symlinks in `~/.claude/skills/` pointing to the installed package. Once linked, they're available as `/stonecut-interview`, `/stonecut-prd`, `/stonecut-issues`, and `/stonecut-review-architecture` in any Claude Code session.
352
358
 
353
359
  For non-default Claude Code installations, pass `--target` with the Claude root path:
354
360
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stonecut",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "CLI that drives PRD-driven development with agentic coding CLIs",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.ts CHANGED
@@ -86,7 +86,7 @@ export interface LocalPrdEntry {
86
86
  * Scan .stonecut subdirectories for directories containing prd.md and compute
87
87
  * completion counts from status.json.
88
88
  */
89
- export function scanLocalPrds(baseDir: string = ".stonecut"): LocalPrdEntry[] {
89
+ export function scanLocalPrds(baseDir: string = ".stonecut/prd"): LocalPrdEntry[] {
90
90
  if (!existsSync(baseDir)) return [];
91
91
 
92
92
  const entries: LocalPrdEntry[] = [];
@@ -240,8 +240,6 @@ export async function preExecution(
240
240
  suggestedBranch: string,
241
241
  prefilled?: { branch?: string; baseBranch?: string },
242
242
  ): Promise<[string, string]> {
243
- ensureCleanTree();
244
-
245
243
  let branch: string;
246
244
  if (prefilled?.branch) {
247
245
  branch = prefilled.branch;
@@ -380,10 +378,12 @@ export function buildProgram(): Command {
380
378
  program
381
379
  .command("run", { isDefault: true })
382
380
  .description("Execute issues from a local PRD.")
383
- .option("--local <name>", "Local PRD name (.stonecut/<name>/)")
381
+ .option("--local <name>", "Local PRD name (.stonecut/prd/<name>/)")
384
382
  .option("-i, --iterations <value>", "Number of issues to process, or 'all'")
385
383
  .option("--runner <name>", "Agentic CLI runner (claude, codex)")
386
384
  .action(async (opts) => {
385
+ ensureCleanTree();
386
+
387
387
  const config = loadConfig();
388
388
 
389
389
  const validated = validateRunSource(opts.local);
package/src/import.ts CHANGED
@@ -37,7 +37,7 @@ export async function importSpec(options: ImportOptions): Promise<ImportResult>
37
37
  throw new Error("Could not derive a spec name from the PRD title. Use --name to specify one.");
38
38
  }
39
39
 
40
- const specDir = join(".stonecut", specName);
40
+ const specDir = join(".stonecut", "prd", specName);
41
41
 
42
42
  if (existsSync(specDir)) {
43
43
  if (!options.force) {
package/src/local.ts CHANGED
@@ -1,4 +1,4 @@
1
- /** Local spec source — reads issues from .stonecut/<name>/. */
1
+ /** Local spec source — reads issues from .stonecut/prd/<name>/. */
2
2
 
3
3
  import { existsSync, readdirSync, readFileSync, writeFileSync, appendFileSync, statSync } from "fs";
4
4
  import { join } from "path";
@@ -11,7 +11,7 @@ export class LocalSource implements Source<Issue> {
11
11
 
12
12
  constructor(name: string) {
13
13
  this.name = name;
14
- this.specDir = join(".stonecut", name);
14
+ this.specDir = join(".stonecut", "prd", name);
15
15
  this.validate();
16
16
  }
17
17
 
@@ -0,0 +1,109 @@
1
+ # Reference
2
+
3
+ ## Dependency Categories
4
+
5
+ When assessing a candidate for deepening, classify its dependencies:
6
+
7
+ ### 1. In-process
8
+
9
+ Pure computation, in-memory state, no I/O. Always deepenable — just merge the modules and test directly.
10
+
11
+ ### 2. Local-substitutable
12
+
13
+ Dependencies that have local test stand-ins (e.g., PGLite for Postgres, in-memory filesystem). Deepenable if the test substitute exists. The deepened module is tested with the local stand-in running in the test suite.
14
+
15
+ ### 3. Remote but owned (Ports & Adapters)
16
+
17
+ Your own services across a network boundary (microservices, internal APIs). Define a port (interface) at the module boundary. The deep module owns the logic; the transport is injected. Tests use an in-memory adapter. Production uses the real HTTP/gRPC/queue adapter.
18
+
19
+ Recommendation shape: "Define a shared interface (port), implement an HTTP adapter for production and an in-memory adapter for testing, so the logic can be tested as one deep module even though it's deployed across a network boundary."
20
+
21
+ ### 4. True external (Mock)
22
+
23
+ Third-party services (Stripe, Twilio, etc.) you don't control. Mock at the boundary. The deepened module takes the external dependency as an injected port, and tests provide a mock implementation.
24
+
25
+ ## Testing Strategy
26
+
27
+ The core principle: **replace, don't layer.**
28
+
29
+ - Old unit tests on shallow modules are waste once boundary tests exist — delete them
30
+ - Write new tests at the deepened module's interface boundary
31
+ - Tests assert on observable outcomes through the public interface, not internal state
32
+ - Tests should survive internal refactors — they describe behavior, not implementation
33
+
34
+ ## RFC Template
35
+
36
+ <rfc-template>
37
+
38
+ ## Context
39
+
40
+ Why this exploration was initiated:
41
+
42
+ - What motivated the review (e.g., preparing for new features, observable friction, scaling concerns)
43
+ - What areas of the codebase were explored
44
+ - High-level findings from the exploration
45
+
46
+ ## Constraints
47
+
48
+ Non-negotiable rules that narrow the solution space:
49
+
50
+ - Architectural invariants that must be preserved
51
+ - Backward compatibility requirements
52
+ - Testing or deployment constraints
53
+
54
+ ## Problem
55
+
56
+ Describe the architectural friction:
57
+
58
+ - Which modules are shallow and tightly coupled
59
+ - What integration risk exists in the seams between them
60
+ - Why this makes the codebase harder to navigate and maintain
61
+
62
+ ## Alternatives Considered
63
+
64
+ For each design explored during the multi-agent step:
65
+
66
+ - **Design name** — One-line summary of the approach
67
+ - Key trade-offs: what it gains, what it loses
68
+ - Why it was accepted, rejected, or partially adopted
69
+
70
+ Include a comparison (table or prose) so the reader can see why the chosen design won.
71
+
72
+ ## Proposed Design
73
+
74
+ The chosen design. For each new or modified module:
75
+
76
+ - What the module owns (responsibilities)
77
+ - What it hides (implementation details callers don't see)
78
+ - What it exposes (the public surface area — described, not full signatures)
79
+ - Dependency graph between modules (which depends on which, and why)
80
+
81
+ ## Dependency Strategy
82
+
83
+ Which category applies and how dependencies are handled:
84
+
85
+ - **In-process**: merged directly
86
+ - **Local-substitutable**: tested with [specific stand-in]
87
+ - **Ports & adapters**: port definition, production adapter, test adapter
88
+ - **Mock**: mock boundary for external services
89
+
90
+ ## Testing Impact
91
+
92
+ High-level testing implications of the design:
93
+
94
+ - What new boundary tests the design enables
95
+ - What existing test patterns become redundant
96
+ - Any test infrastructure changes needed
97
+
98
+ ## Implementation Guidance
99
+
100
+ Durable architectural guidance — the _what and why_, not the _how_:
101
+
102
+ - What the module should own (responsibilities)
103
+ - What it should hide (implementation details)
104
+ - What it should expose (the interface contract)
105
+ - Key invariants the implementation must preserve
106
+
107
+ Do NOT include specific file-level migration steps, exact function signatures, or line-by-line changes. Those belong in the PRD and issues.
108
+
109
+ </rfc-template>
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: stonecut-review-architecture
3
+ description: Explore a codebase to find opportunities for architectural improvement, focusing on making the codebase more testable by deepening shallow modules. Use when user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more AI-navigable.
4
+ ---
5
+
6
+ # Review Architecture
7
+
8
+ Explore a codebase like an AI would, surface architectural friction, discover opportunities for improving testability, and propose module-deepening refactors.
9
+
10
+ A **deep module** (John Ousterhout, "A Philosophy of Software Design") has a small interface hiding a large implementation. Deep modules are more testable, more AI-navigable, and let you test at the boundary instead of inside.
11
+
12
+ ## Process
13
+
14
+ ### 1. Explore the codebase
15
+
16
+ Use the Agent tool with subagent_type=Explore to navigate the codebase naturally. Do NOT follow rigid heuristics — explore organically and note where you experience friction:
17
+
18
+ - Where does understanding one concept require bouncing between many small files?
19
+ - Where are modules so shallow that the interface is nearly as complex as the implementation?
20
+ - Where have pure functions been extracted just for testability, but the real bugs hide in how they're called?
21
+ - Where do tightly-coupled modules create integration risk in the seams between them?
22
+ - Which parts of the codebase are untested, or hard to test?
23
+
24
+ The friction you encounter IS the signal.
25
+
26
+ ### 2. Present candidates
27
+
28
+ Present a numbered list of deepening opportunities. For each candidate, show:
29
+
30
+ - **Cluster**: Which modules/concepts are involved
31
+ - **Why they're coupled**: Shared types, call patterns, co-ownership of a concept
32
+ - **Dependency category**: See [REFERENCE.md](REFERENCE.md) for the four categories
33
+ - **Test impact**: What existing tests would be replaced by boundary tests
34
+
35
+ Do NOT propose interfaces yet. Ask the user: "Which of these would you like to explore?"
36
+
37
+ ### 3. User picks a candidate
38
+
39
+ ### 4. Frame the problem space
40
+
41
+ Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
42
+
43
+ - The constraints any new interface would need to satisfy
44
+ - The dependencies it would need to rely on
45
+ - A rough illustrative code sketch to make the constraints concrete
46
+
47
+ Show this to the user, then immediately proceed to Step 5.
48
+
49
+ ### 5. Design multiple interfaces
50
+
51
+ Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module.
52
+
53
+ Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category, what's being hidden). This brief is independent of the user-facing explanation in Step 4. Give each agent a different design constraint:
54
+
55
+ - Agent 1: "Minimize the interface — aim for 1-3 entry points max"
56
+ - Agent 2: "Maximize flexibility — support many use cases and extension"
57
+ - Agent 3: "Optimize for the most common caller — make the default case trivial"
58
+ - Agent 4 (if applicable): "Design around the ports & adapters pattern for cross-boundary dependencies"
59
+
60
+ Each sub-agent outputs:
61
+
62
+ 1. Interface signature (types, methods, params)
63
+ 2. Usage example showing how callers use it
64
+ 3. What complexity it hides internally
65
+ 4. Dependency strategy (how deps are handled — see [REFERENCE.md](REFERENCE.md))
66
+ 5. Trade-offs
67
+
68
+ Present designs sequentially, then compare them in prose.
69
+
70
+ After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid.
71
+
72
+ ### 6. User picks an interface (or accepts recommendation)
73
+
74
+ ### 7. Choose a destination
75
+
76
+ Ask the user where to save the RFC:
77
+
78
+ - **Local file** — Save as `.stonecut/<name>/rfc.md` in the project. Ask the user: "What should I name this spec?" Create the `.stonecut/<name>/` directory if it doesn't exist.
79
+ - **GitHub issue** — Create a GitHub issue using `gh issue create --label rfc`. Before creating, ensure the `rfc` label exists:
80
+
81
+ ```bash
82
+ # Only create the label if it doesn't already exist
83
+ if ! gh label list --search "rfc" --json name --jq '.[].name' | grep -qx "rfc"; then
84
+ gh label create rfc --description "Request for Comments — architecture/design decision" --color "D93F0B"
85
+ fi
86
+ ```
87
+
88
+ If the project already has a `.stonecut/` directory, default to suggesting local. Otherwise, just ask.
89
+
90
+ ### 8. Write the RFC
91
+
92
+ Use the template in [REFERENCE.md](REFERENCE.md). Do NOT ask the user to review before creating — just create it and share the result.
93
+
94
+ The RFC captures design decisions — what was chosen, what was rejected, and why. The PRD writer (whether in this session or a future one) will explore the codebase itself; the RFC's job is to carry the decisions so they don't need to be re-derived. Leave implementation-level detail (exact signatures, migration steps, test file changes) for the PRD and issues.
95
+
96
+ ## Next Step
97
+
98
+ Once the RFC is saved, ask the user: "Ready to write the PRD? I can run `/stonecut-prd` next."
package/src/skills.ts CHANGED
@@ -17,7 +17,12 @@ import {
17
17
  import { join, resolve } from "node:path";
18
18
  import { homedir } from "node:os";
19
19
 
20
- export const SKILL_NAMES = ["stonecut-interview", "stonecut-prd", "stonecut-issues"];
20
+ export const SKILL_NAMES = [
21
+ "stonecut-interview",
22
+ "stonecut-prd",
23
+ "stonecut-issues",
24
+ "stonecut-review-architecture",
25
+ ];
21
26
 
22
27
  /**
23
28
  * Return the path to the skills/ directory shipped with this package.