@monomit/primer-templates 0.1.0

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.
@@ -0,0 +1,44 @@
1
+ # {{projectName}} — Claude Code Guide
2
+
3
+ This file is read automatically by Claude Code at session start.
4
+ Read `AGENTS.md` first — this file extends it with Claude-specific conventions.
5
+
6
+ ## Commands
7
+
8
+ These slash commands are available in `.claude/commands/`:
9
+
10
+ | Command | Purpose |
11
+ |---|---|
12
+ | `/git-start-work` | Start a new branch before any work |
13
+ | `/git-commit-progress` | Commit in-progress work with checks |
14
+ | `/git-finish-work` | Push branch and open PR |
15
+
16
+ Load a command by reading its file before invoking it.
17
+
18
+ ## Claude-specific conventions
19
+
20
+ ### Before writing any code
21
+ 1. Read `AGENTS.md` fully
22
+ 2. Read `docs/CANONICAL_ARCHITECTURE.md`
23
+ 3. Read `docs/CANONICAL_PATTERNS.md`
24
+ 4. Check existing files before creating new ones
25
+
26
+ ### Phase boundaries
27
+ Every discrete unit of work must end with:
28
+ - An explicit list of files written or modified
29
+ - A summary of what was done
30
+ - A STOP marker before starting the next phase:
31
+
32
+ ```
33
+ --- STOP ---
34
+ Phase complete. Files written:
35
+ - src/commands/example.ts
36
+ - docs/CANONICAL_PATTERNS.md (updated)
37
+
38
+ Awaiting human review before proceeding.
39
+ ```
40
+
41
+ ### When you are uncertain
42
+ - Stop and ask — do not guess at APIs or conventions
43
+ - Check canonical docs before inventing patterns
44
+ - Prefer doing less and confirming over doing more and breaking things
@@ -0,0 +1,27 @@
1
+ # /git-commit-progress
2
+
3
+ Commit in-progress work with full pre-commit checks.
4
+
5
+ ## Usage
6
+
7
+ `/git-commit-progress <type> <description>`
8
+
9
+ ## Steps
10
+
11
+ 1. Confirm we're not on `main` — if we are, stop
12
+ 2. Derive scope from the branch name (`<type>/<scope>-<description>`)
13
+ 3. Run pre-commit checks:
14
+ - `{{packageManagerRun}} typecheck`
15
+ - `{{packageManagerRun}} lint`
16
+ - `{{packageManagerRun}} test`
17
+ - If any fails, stop and report — do not commit
18
+ 4. Show `git status` and `git diff --stat` to the user
19
+ 5. Propose specific files to stage — never propose `git add .`
20
+ 6. Wait for confirmation, then stage and commit:
21
+ - `git commit -m "<type>(<scope>): <description>"`
22
+ 7. Report the commit hash and files changed
23
+
24
+ ## Do not
25
+ - Push (that's `/git-finish-work`)
26
+ - `git add .` without showing the user what gets staged
27
+ - Commit to `main`
@@ -0,0 +1,31 @@
1
+ # /git-finish-work
2
+
3
+ Finalize a branch, push it, and open a PR.
4
+
5
+ ## Usage
6
+
7
+ `/git-finish-work`
8
+
9
+ ## Steps
10
+
11
+ 1. Confirm we're not on `main` — if we are, stop
12
+ 2. Run all pre-commit checks one final time:
13
+ - `{{packageManagerRun}} typecheck`
14
+ - `{{packageManagerRun}} lint`
15
+ - `{{packageManagerRun}} test`
16
+ - `{{packageManagerRun}} build`
17
+ - If any fails, stop and report
18
+ 3. Check for uncommitted changes — if any, ask the user whether to commit them
19
+ 4. `git push -u origin <branch-name>` — if push fails, stop (no force push)
20
+ 5. Open PR via GitHub CLI:
21
+ ```
22
+ gh pr create --base main --head <branch> --title "<title>" --body "<body>"
23
+ ```
24
+ PR body must include: what changed, why, follow-ups, confirmation checks pass
25
+ 6. Report the PR URL
26
+ 7. Tell the user: "Review in GitHub UI, squash-merge when ready, delete branch after merge."
27
+
28
+ ## Do not
29
+ - Merge the PR — that's the user's job
30
+ - Force push
31
+ - Skip final checks
@@ -0,0 +1,19 @@
1
+ # /git-start-work
2
+
3
+ Start a new piece of work on a fresh branch.
4
+
5
+ ## Usage
6
+
7
+ `/git-start-work <type> <scope> <description>`
8
+
9
+ ## Steps
10
+
11
+ 1. Run `git status` — if uncommitted changes exist, stop and tell the user
12
+ 2. `git checkout main && git pull origin main`
13
+ 3. `git checkout -b <type>/<scope>-<description>`
14
+ 4. Confirm the branch is active and report the branch name and last commit hash
15
+ 5. Tell the user: "Branch ready. Use `/git-commit-progress` as you work."
16
+
17
+ ## Do not
18
+ - Branch without pulling main first
19
+ - Branch if uncommitted changes exist on the current branch
@@ -0,0 +1,27 @@
1
+ # /git-commit-progress
2
+
3
+ Commit in-progress work with full pre-commit checks.
4
+
5
+ ## Usage
6
+
7
+ `/git-commit-progress <type> <description>`
8
+
9
+ ## Steps
10
+
11
+ 1. Confirm we're not on `main` — if we are, stop
12
+ 2. Derive scope from the branch name (`<type>/<scope>-<description>`)
13
+ 3. Run pre-commit checks:
14
+ - `{{packageManagerRun}} typecheck`
15
+ - `{{packageManagerRun}} lint`
16
+ - `{{packageManagerRun}} test`
17
+ - If any fails, stop and report — do not commit
18
+ 4. Show `git status` and `git diff --stat` to the user
19
+ 5. Propose specific files to stage — never propose `git add .`
20
+ 6. Wait for confirmation, then stage and commit:
21
+ - `git commit -m "<type>(<scope>): <description>"`
22
+ 7. Report the commit hash and files changed
23
+
24
+ ## Do not
25
+ - Push (that's `/git-finish-work`)
26
+ - `git add .` without showing the user what gets staged
27
+ - Commit to `main`
@@ -0,0 +1,29 @@
1
+ # /git-finish-work
2
+
3
+ Finalize a branch, push it, and open a PR.
4
+
5
+ ## Usage
6
+
7
+ `/git-finish-work`
8
+
9
+ ## Steps
10
+
11
+ 1. Confirm we're not on `main` — if we are, stop
12
+ 2. Run all pre-commit checks one final time:
13
+ - `{{packageManagerRun}} typecheck`
14
+ - `{{packageManagerRun}} lint`
15
+ - `{{packageManagerRun}} test`
16
+ - `{{packageManagerRun}} build`
17
+ - If any fails, stop and report
18
+ 3. Check for uncommitted changes — if any, ask the user whether to commit them
19
+ 4. `git push -u origin <branch-name>` — if push fails, stop (no force push)
20
+ 5. Open PR via GitHub CLI:
21
+ gh pr create --base main --head <branch> --title "<title>" --body "<body>"
22
+ PR body must include: what changed, why, follow-ups, confirmation checks pass
23
+ 6. Report the PR URL
24
+ 7. Tell the user: "Review in GitHub UI, squash-merge when ready, delete branch after merge."
25
+
26
+ ## Do not
27
+ - Merge the PR — that's the user's job
28
+ - Force push
29
+ - Skip final checks
@@ -0,0 +1,19 @@
1
+ # /git-start-work
2
+
3
+ Start a new piece of work on a fresh branch.
4
+
5
+ ## Usage
6
+
7
+ `/git-start-work <type> <scope> <description>`
8
+
9
+ ## Steps
10
+
11
+ 1. Run `git status` — if uncommitted changes exist, stop and tell the user
12
+ 2. `git checkout main && git pull origin main`
13
+ 3. `git checkout -b <type>/<scope>-<description>`
14
+ 4. Confirm the branch is active and report the branch name and last commit hash
15
+ 5. Tell the user: "Branch ready. Use `/git-commit-progress` as you work."
16
+
17
+ ## Do not
18
+ - Branch without pulling main first
19
+ - Branch if uncommitted changes exist on the current branch
@@ -0,0 +1,46 @@
1
+ ---
2
+ description: Core engineering rules for {{projectName}}
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Core rules
8
+
9
+ These rules apply to every file in the project.
10
+ They are non-negotiable and take precedence over convenience.
11
+
12
+ ## TypeScript
13
+
14
+ - Strict mode is on — no `any`, no type assertions without a comment explaining why
15
+ - Use `node:` prefix for all Node built-in imports (`node:fs`, `node:path`, etc.)
16
+ - ESM only — no `require()`, no CommonJS
17
+ - Import `.ts` extensions in source files (bundler mode resolves them)
18
+
19
+ ## Code style
20
+
21
+ - Functions over classes unless state management genuinely requires a class
22
+ - Explicit return types on all exported functions
23
+ - No default exports in `src/**` — named exports only
24
+ - Config files at the project root (e.g. `tsup.config.ts`, `eslint.config.js`) are
25
+ exempt from this rule and may use default exports as required by their tooling
26
+ - Early returns over nested conditionals
27
+
28
+ ## File organization
29
+
30
+ - One concept per file
31
+ - `src/commands/` — one file per CLI subcommand
32
+ - `src/lib/` — shared utilities including I/O helpers, git operations, and other
33
+ infrastructure concerns; keep functions focused and explicitly typed
34
+ - No barrel files (`index.ts` re-exports) — import directly from the source file
35
+
36
+ ## Error handling
37
+
38
+ - Never swallow errors silently
39
+ - User-facing errors go through the CLI output layer (never raw `console.error`)
40
+ - All async functions must handle rejection explicitly
41
+
42
+ ## Testing
43
+
44
+ - Tests live alongside source in `src/**/*.test.ts`
45
+ - Test pure functions in `src/lib/` first — highest leverage
46
+ - No arbitrary `setTimeout` in tests — use deterministic assertions
@@ -0,0 +1,52 @@
1
+ ---
2
+ description: Git and version control discipline for {{projectName}}
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Git discipline
8
+
9
+ These rules apply to every git operation.
10
+ They are non-negotiable and take precedence over user convenience.
11
+
12
+ ## Branches
13
+
14
+ ### Never commit directly to main
15
+ - `main` is protected — always work on a branch
16
+ - If on `main` and asked to commit, stop and create a branch first
17
+ - If the user insists after warning, refuse — this is a hard rule
18
+
19
+ ### Branch naming
20
+ Format: `<type>/<scope>-<short-description>` in kebab-case
21
+
22
+ - `type`: `feat` | `fix` | `chore` | `docs` | `refactor` | `test`
23
+ - `scope`: short package or domain name
24
+ - `short-description`: 2–5 words
25
+
26
+ Examples:
27
+ - `feat/cli-add-retrofit-command`
28
+ - `fix/cli-template-resolution`
29
+ - `chore/deps-bump`
30
+
31
+ ## Commits
32
+
33
+ ### Conventional Commits format
34
+
35
+ <type>(<scope>): <description>
36
+
37
+ - Imperative mood, no trailing period, 50 chars max
38
+ - Good: `add template resolution for cli-tool type`
39
+ - Bad: `Added template resolution.`
40
+
41
+ ### Pre-commit checks (run in this order)
42
+ 1. `{{packageManagerRun}} typecheck` — must pass
43
+ 2. `{{packageManagerRun}} lint` — must pass
44
+ 3. `{{packageManagerRun}} test` — must pass
45
+
46
+ Never commit if any check fails without explicit user consent.
47
+
48
+ ## Forbidden without explicit confirmation
49
+ - `git push --force`
50
+ - `git reset --hard` on pushed commits
51
+ - `git rebase` on pushed branches
52
+ - Merging into `main`
@@ -0,0 +1,2 @@
1
+ * text=auto eol=lf
2
+ *.sh text eol=lf
@@ -0,0 +1 @@
1
+ 22
@@ -0,0 +1,63 @@
1
+ # {{projectName}} — Agent Guide
2
+
3
+ This file is the mandatory entry point for all AI coding agents.
4
+ Read it fully before writing any code.
5
+
6
+ ## Project overview
7
+
8
+ **Name:** {{projectName}}
9
+ **Package manager:** {{packageManager}}
10
+ **Type:** CLI tool (Node.js, TypeScript, ESM)
11
+
12
+ ## Before you write any code
13
+
14
+ - Read `docs/CANONICAL_ARCHITECTURE.md` — stack decisions and rationale
15
+ - Read `docs/CANONICAL_PATTERNS.md` — code patterns you must follow
16
+ {{#cursorEnabled}}
17
+ - Read `.cursor/rules/core.mdc` — non-negotiable engineering rules
18
+ - Read `.cursor/rules/git-discipline.mdc` — branch and commit rules
19
+ {{/cursorEnabled}}
20
+ {{#claudeEnabled}}
21
+ - Read `.claude/CLAUDE.md` — Claude-specific conventions and rules
22
+ {{/claudeEnabled}}
23
+
24
+ ## Commands available to you
25
+
26
+ These commands enforce git discipline and pre-commit checks.
27
+ Load them from your tool's commands directory before using them.
28
+
29
+ | Command | Purpose |
30
+ |---|---|
31
+ | `/git-start-work` | Start a new branch before any work |
32
+ | `/git-commit-progress` | Commit in-progress work with checks |
33
+ | `/git-finish-work` | Push branch and open PR |
34
+
35
+ ## Non-negotiables
36
+
37
+ - Never commit directly to `main`
38
+ - Never skip typecheck, lint, or tests before committing
39
+ - Never invent APIs — check canonical docs first
40
+ - Always stop and confirm with the human before destructive operations
41
+ - Every phase of work ends with an explicit file list and a STOP marker
42
+
43
+ ## Project structure
44
+
45
+ ```
46
+ {{projectName}}/
47
+ ├── src/
48
+ │ ├── index.ts ← entry point
49
+ │ ├── commands/ ← one file per subcommand
50
+ │ └── lib/ ← shared utilities
51
+ ├── docs/ ← canonical documentation (read before coding)
52
+ {{#cursorEnabled}}
53
+ ├── .cursor/
54
+ │ ├── rules/ ← scoped agent rules
55
+ │ └── commands/ ← agent slash commands
56
+ {{/cursorEnabled}}
57
+ {{#claudeEnabled}}
58
+ ├── .claude/
59
+ │ ├── CLAUDE.md ← Claude-specific conventions
60
+ │ └── commands/ ← agent slash commands
61
+ {{/claudeEnabled}}
62
+ └── AGENTS.md ← you are here
63
+ ```
@@ -0,0 +1,34 @@
1
+ # {{projectName}} — Canonical Architecture
2
+
3
+ **Last updated:** (fill in after initial setup)
4
+ **Status:** Living document — update when stack decisions change
5
+
6
+ > Agents: read this before generating any code. Do not invent
7
+ > dependencies or patterns not listed here.
8
+
9
+ ## Stack
10
+
11
+ | Layer | Choice | Rationale |
12
+ |---|---|---|
13
+ | Runtime | Node.js 22+ | LTS, native ESM, built-in test runner |
14
+ | Language | TypeScript 5, strict mode | Type safety at boundaries |
15
+ | Package manager | {{packageManager}} | (fill in rationale) |
16
+ | CLI prompts | @clack/prompts | Clean UX, actively maintained |
17
+ | Build | tsup | Zero-config, ESM output |
18
+ | Test | (fill in) | |
19
+ | Lint | (fill in) | |
20
+
21
+ ## Key decisions
22
+
23
+ ### ESM only
24
+ No CommonJS. All imports use `node:` prefix for built-ins.
25
+ No barrel files — import directly from source.
26
+
27
+ ### No framework lock-in
28
+ (Describe what this project deliberately avoids and why.)
29
+
30
+ ## What does NOT belong here
31
+
32
+ - Business logic in the entry point (`src/index.ts`)
33
+ - Direct I/O in library functions (`src/lib/`)
34
+ - Any LLM API calls — this tool generates static files only
@@ -0,0 +1,46 @@
1
+ # {{projectName}} — Canonical Patterns
2
+
3
+ > Agents: these are the exact patterns to follow when generating code.
4
+ > Do not deviate without updating this document and getting human approval.
5
+
6
+ ## Command pattern
7
+
8
+ Every CLI subcommand lives in `src/commands/<name>.ts` and exports
9
+ a single async function:
10
+
11
+ ```typescript
12
+ export async function run<Name>(): Promise<void> {
13
+ // use @clack/prompts for all user interaction
14
+ // delegate file I/O to src/lib/scaffold.ts
15
+ // delegate git operations to src/lib/git.ts
16
+ }
17
+ ```
18
+
19
+ ## Error handling pattern
20
+
21
+ ```typescript
22
+ import * as p from "@clack/prompts";
23
+
24
+ try {
25
+ // operation
26
+ } catch (err) {
27
+ p.cancel(err instanceof Error ? err.message : String(err));
28
+ process.exit(1);
29
+ }
30
+ ```
31
+
32
+ ## File writing pattern
33
+
34
+ Always use the scaffold lib — never write files directly in commands:
35
+
36
+ ```typescript
37
+ import { writeOutputFile, renderTemplate } from "../lib/scaffold.ts";
38
+ ```
39
+
40
+ ## Adding a new command
41
+
42
+ 1. Create `src/commands/<name>.ts`
43
+ 2. Export `run<Name>(): Promise<void>`
44
+ 3. Import and wire it in `src/index.ts`
45
+ 4. Add a corresponding `.cursor/commands/<name>.md` slash command
46
+ 5. Update this document
@@ -0,0 +1,23 @@
1
+ import js from "@eslint/js";
2
+ import tseslint from "typescript-eslint";
3
+
4
+ export default tseslint.config(
5
+ js.configs.recommended,
6
+ ...tseslint.configs.recommended,
7
+ {
8
+ rules: {
9
+ "@typescript-eslint/no-unused-vars": [
10
+ "error",
11
+ { argsIgnorePattern: "^_" },
12
+ ],
13
+ "@typescript-eslint/explicit-function-return-type": [
14
+ "error",
15
+ { allowExpressions: true },
16
+ ],
17
+ "no-console": "warn",
18
+ },
19
+ },
20
+ {
21
+ ignores: ["dist/**"],
22
+ }
23
+ );
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ .turbo/
4
+ *.log
5
+ .DS_Store
package/cli-tool/npmrc ADDED
@@ -0,0 +1,2 @@
1
+ shamefully-hoist=false
2
+ strict-peer-dependencies=false
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "packageManager": "{{packageManager}}@{{packageManagerVersion}}",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "bin": {
11
+ "{{projectName}}": "./dist/index.js"
12
+ },
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsup --watch",
16
+ "typecheck": "tsc --noEmit",
17
+ "lint": "eslint src",
18
+ "test": "node --test",
19
+ "clean": "rm -rf dist"
20
+ },
21
+ "dependencies": {
22
+ "@clack/prompts": "^0.9"
23
+ },
24
+ "devDependencies": {
25
+ "@eslint/js": "^9",
26
+ "@types/node": "^22",
27
+ "eslint": "^9",
28
+ "tsup": "^8",
29
+ "typescript": "^5",
30
+ "typescript-eslint": "^8"
31
+ }
32
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import * as p from "@clack/prompts";
3
+
4
+ p.intro("{{projectName}}");
5
+
6
+ // TODO: wire your commands here
7
+
8
+ p.outro("Done.");
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "strict": true,
7
+ "skipLibCheck": true,
8
+ "outDir": "dist",
9
+ "allowImportingTsExtensions": true,
10
+ "noEmit": true
11
+ },
12
+ "include": ["src"]
13
+ }
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.ts"],
5
+ format: ["esm"],
6
+ target: "node22",
7
+ clean: true,
8
+ shims: true,
9
+ });
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // Entry point for path resolution only.
2
+ // Templates are files in subdirectories alongside this file.
3
+ export const templatesVersion = "0.1.0";
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@monomit/primer-templates",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "files": [
7
+ "index.js",
8
+ "cli-tool"
9
+ ],
10
+ "exports": {
11
+ ".": "./index.js"
12
+ },
13
+ "scripts": {
14
+ "clean": "rm -rf dist"
15
+ }
16
+ }