janissary 0.5.0 → 0.5.2

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 (69) hide show
  1. package/ai/guidelines/architecture-principles.md +75 -0
  2. package/ai/guidelines/code-guidelines.md +17 -0
  3. package/ai/guidelines/conventional-commits.md +192 -0
  4. package/ai/guidelines/developer-documentation.md +124 -0
  5. package/ai/guidelines/documentation.md +80 -0
  6. package/ai/guidelines/human-writing-guidelines.md +42 -0
  7. package/ai/guidelines/imports-and-barrel-files.md +49 -0
  8. package/ai/guidelines/pull-request-automation.md +98 -0
  9. package/ai/guidelines/strategies-for-readable-summaries.md +27 -0
  10. package/ai/guidelines/user-documentation.md +177 -0
  11. package/ai/personas/algorithm.md +14 -0
  12. package/ai/personas/assistant.md +25 -0
  13. package/ai/personas/link-scout.md +16 -0
  14. package/ai/personas/researcher.md +12 -0
  15. package/ai/personas/security.md +12 -0
  16. package/ai/personas/summarizer.md +11 -0
  17. package/ai/tasks/build-a-feature.md +133 -0
  18. package/ai/tasks/fix-a-small-issue.md +138 -0
  19. package/ai/tasks/improve-codebase.md +187 -0
  20. package/ai/tasks/improve-modularity.md +188 -0
  21. package/ai/tasks/improve-namespacing.md +253 -0
  22. package/ai/tasks/improve-plan.md +121 -0
  23. package/ai/tasks/improve-security.md +144 -0
  24. package/ai/tasks/improve-style.md +147 -0
  25. package/ai/tasks/improve-test-coverage.md +178 -0
  26. package/ai/tasks/merge-change-to-master.md +144 -0
  27. package/ai/tasks/open-feature-pull-request.md +161 -0
  28. package/ai/tasks/plan-ready-features.md +154 -0
  29. package/ai/tasks/prepare-workspace.md +35 -0
  30. package/ai/tasks/quick-commit.md +82 -0
  31. package/ai/tasks/reduce-complexity.md +185 -0
  32. package/ai/tasks/remove-deadcode.md +206 -0
  33. package/ai/tasks/remove-duplication.md +202 -0
  34. package/ai/tasks/update-package.md +137 -0
  35. package/package.json +5 -3
  36. package/scripts/changed-files.mjs +22 -0
  37. package/scripts/check-diff.mjs +100 -0
  38. package/scripts/coverage-file.mjs +85 -0
  39. package/scripts/docs-screenshots/capture.mjs +82 -0
  40. package/scripts/docs-screenshots/fixtures/docs/api.md +3 -0
  41. package/scripts/docs-screenshots/fixtures/docs/guide.md +3 -0
  42. package/scripts/docs-screenshots/fixtures/page.html +31 -0
  43. package/scripts/docs-screenshots/fixtures/profiles/demo/editor.json +1 -0
  44. package/scripts/docs-screenshots/fixtures/profiles/demo/writer.json +1 -0
  45. package/scripts/docs-screenshots/fixtures/sample.md +26 -0
  46. package/scripts/docs-screenshots/fixtures/sample.png +0 -0
  47. package/scripts/docs-screenshots/fixtures/sample.ts +25 -0
  48. package/scripts/docs-screenshots/fixtures/src/app.ts +2 -0
  49. package/scripts/docs-screenshots/fixtures/src/tides.ts +2 -0
  50. package/scripts/docs-screenshots/janus.mjs +51 -0
  51. package/scripts/docs-screenshots/manifest.mjs +122 -0
  52. package/scripts/docs-screenshots/scratch.mjs +53 -0
  53. package/scripts/docs-screenshots.mjs +86 -0
  54. package/scripts/lint-files.mjs +47 -0
  55. package/scripts/postinstall.mjs +14 -0
  56. package/scripts/pr-check-changes.sh +15 -0
  57. package/scripts/pr-check-gate.sh +29 -0
  58. package/scripts/pr-check-mergeable.sh +29 -0
  59. package/scripts/pr-commit.sh +23 -0
  60. package/scripts/pr-create-branch.sh +20 -0
  61. package/scripts/pr-create-pr.sh +29 -0
  62. package/scripts/pr-merge.sh +22 -0
  63. package/scripts/pr-push-branch.sh +24 -0
  64. package/scripts/pr-rebase.sh +56 -0
  65. package/scripts/pr-resolve-remote.sh +9 -0
  66. package/scripts/pr-wait-checks.sh +41 -0
  67. package/scripts/publish.mjs +61 -0
  68. package/scripts/release.mjs +209 -0
  69. package/scripts/run.mjs +40 -0
@@ -0,0 +1,147 @@
1
+ # Improve CSS Style (one fix per run)
2
+
3
+ Your job: run the CSS linter, pick the single most valuable fix, assess its risk, and either apply it yourself or ask the user to approve it. Do exactly **one fix**, then verify.
4
+
5
+ **No AI attribution — anywhere.** Never credit an AI agent as an author or contributor in anything this task produces. That means: no `Co-Authored-By:` trailers naming Claude or any other AI, no “Generated with Claude Code” (or similar) lines or badges, and no AI authorship notes in code, comments, docs, spec files, plan files, commit messages, or PR titles and bodies. This overrides any default convention that appends such attribution. The commit's configured git author is the only authorship ever recorded.
6
+
7
+ **Run everything synchronously, in the foreground.** Never use `run_in_background`, `&`, or otherwise start a background process (dev servers, watchers, long-lived processes) — every command must finish and return its exit code before you move to the next step.
8
+
9
+ **No subagents, no background agents.** Do every step yourself — never launch a subagent (Task/Agent tool, `fork`, or otherwise) to research, explore, or implement any part of this task on your behalf.
10
+
11
+ Do the steps below **in order**. Do not skip steps. Do not invent your own process.
12
+
13
+ **Shell hygiene:** run every command on its own line — no `&&` chaining, no `; echo "Exit code: $?"` suffixes, no subshell captures. The exit code and output are visible in the tool result. To run a project script, always use `./scripts/run.mjs <name>` — never call `node scripts/<name>.mjs` directly.
14
+
15
+ ---
16
+
17
+ ## Step 0 — Prepare the workspace
18
+
19
+ Execute `ai/tasks/prepare-workspace.md` in full before doing anything else.
20
+
21
+ ---
22
+
23
+ ## Step 1 — Verify the baseline is green
24
+
25
+ Run all three and read all output:
26
+
27
+ ```bash
28
+ npx tsc --noEmit 2>&1
29
+ npm test 2>&1
30
+ npm run lint:css 2>&1
31
+ ```
32
+
33
+ Record:
34
+ - **Compiler:** must finish with **no errors**. If it errors, STOP and tell the user.
35
+ - **Tests:** every test must pass. If any test is already failing, STOP and tell the user — do not fix CSS on a broken suite.
36
+ - **CSS lint (`npm run lint:css`):** copy out the full finding list — every line. Write down the total count. **If there are no findings, report "No CSS issues found" and stop.**
37
+
38
+ Always run these fresh. Do not trust earlier output in the conversation.
39
+
40
+ ---
41
+
42
+ ## Step 2 — Rank the findings
43
+
44
+ Read the `npm run lint:css` output. Each finding looks like:
45
+
46
+ ```
47
+ web/src/theme.css
48
+ 137:27 ✖ Expected modern color-function notation color-function-notation
49
+ ```
50
+
51
+ Group findings by **stylelint rule name** (the last token on each line). For each rule, count how many findings it contributes.
52
+
53
+ Rank from most valuable to fix first, using this order of priority:
54
+
55
+ 1. **Correctness** — deprecated values (`declaration-property-value-keyword-no-deprecated`), invalid syntax, unknown properties.
56
+ 2. **Modernisation** — outdated but valid notation (`color-function-notation`, `alpha-value-notation`, `color-function-alias-notation`, `value-keyword-case`).
57
+ 3. **Convention** — style rules the config-standard enables and that aren't purely about whitespace.
58
+
59
+ Within each tier, prefer the rule with the **most findings** (highest bang-for-buck per edit).
60
+
61
+ Write out your ranked list before picking.
62
+
63
+ ---
64
+
65
+ ## Step 3 — Pick exactly one rule to fix
66
+
67
+ From the ranked list, pick the **top rule** — the highest-priority finding with the most occurrences.
68
+
69
+ State: the rule name, how many findings it has, and in one sentence what the fix is.
70
+
71
+ ---
72
+
73
+ ## Step 4 — Plan the fix
74
+
75
+ Write out every individual change the fix requires:
76
+
77
+ - For each finding, the **file**, the **line**, what the current code is, and what it becomes.
78
+ - If `--fix` can apply the change automatically, say so.
79
+
80
+ Keep the diff as small as possible — do not reformat or tidy unrelated lines.
81
+
82
+ ---
83
+
84
+ ## Step 5 — Assess risk and decide
85
+
86
+ Rate the plan **Low risk** or **High risk** using these criteria.
87
+
88
+ **Low risk** (apply automatically, without asking):
89
+ - The change is a mechanical substitution: rewriting a color notation, quoting a font name, replacing a deprecated keyword with its modern equivalent.
90
+ - `--fix` applies it, or each change is a literal find-and-replace within the CSS file.
91
+ - Zero TypeScript, zero test files, zero config files are touched.
92
+ - The visual result in the browser is identical — no layout, color, or spacing change.
93
+
94
+ **High risk** (skip and pick the next rule):
95
+ - The fix could change rendered output — for example, changing a `color` value where the browser interprets the old and new forms differently, changing a `font-family` ordering, or restructuring a selector.
96
+ - More than one file must be edited.
97
+ - You are unsure whether the old and new forms are semantically identical.
98
+ - The fix requires deleting or restructuring a rule block, not just rewriting a value.
99
+
100
+ If **High risk**: do **not** apply the fix and do **not** ask the user. Go back to Step 3, remove this rule from the ranked list, and pick the next-ranked rule. If every rule is High risk, list all of them in your report under "Skipped (high risk)" and stop without making any changes.
101
+
102
+ If **Low risk**: proceed directly to Step 6 without asking.
103
+
104
+ ---
105
+
106
+ ## Step 6 — Apply the fix
107
+
108
+ **Back up the file first:**
109
+
110
+ ```bash
111
+ cp web/src/theme.css web/src/theme.css.bak
112
+ ```
113
+
114
+ Apply the fix:
115
+
116
+ - If `--fix` covers it: run `npm run lint:css:fix`, then inspect the diff to confirm only the intended lines changed. If the diff touches anything unexpected, restore the backup and report what happened.
117
+ - If manual: edit the file directly, changing only the lines listed in your plan.
118
+
119
+ ---
120
+
121
+ ## Step 7 — Verify (run in this order; everything must be green)
122
+
123
+ ```bash
124
+ npx tsc --noEmit 2>&1
125
+ npm test 2>&1
126
+ npm run lint:css 2>&1
127
+ ```
128
+
129
+ 1. **Compiler — no errors.** If a type error appeared, the CSS change somehow affected a TypeScript file that wasn't supposed to change. Restore the backup and report.
130
+ 2. **Tests — all pass.** If a test fails, restore the backup and report. Never edit a test to make it pass.
131
+ 3. **CSS lint — the rule you fixed no longer appears.** The finding count must be lower than Step 1. If the same findings are still there, your fix did not take effect — restore the backup and report.
132
+
133
+ When all three pass, delete the backup: `rm web/src/theme.css.bak`.
134
+
135
+ ---
136
+
137
+ ## Step 8 — Report
138
+
139
+ ```
140
+ Rule fixed: <rule name, or "none — all rules were high risk">
141
+ Findings: <count before> -> <count after>
142
+ Changes: <one line per edit: file:line old → new, or "none">
143
+ Skipped: <rules skipped as high risk, or "none">
144
+ Tests: all pass / <what failed>
145
+ ```
146
+
147
+ Keep it brief. Done.
@@ -0,0 +1,178 @@
1
+ # Improve Test Coverage (one file per run)
2
+
3
+ Your job: add tests that raise this project's test coverage. Do exactly **one file's worth** of new tests, then verify it worked.
4
+
5
+ **No AI attribution — anywhere.** Never credit an AI agent as an author or contributor in anything this task produces. That means: no `Co-Authored-By:` trailers naming Claude or any other AI, no “Generated with Claude Code” (or similar) lines or badges, and no AI authorship notes in code, comments, docs, spec files, plan files, commit messages, or PR titles and bodies. This overrides any default convention that appends such attribution. The commit's configured git author is the only authorship ever recorded.
6
+
7
+ **Run everything synchronously, in the foreground.** Never use `run_in_background`, `&`, or otherwise start a background process (dev servers, watchers, long-lived processes) — every command must finish and return its exit code before you move to the next step.
8
+
9
+ **No subagents, no background agents.** Do every step yourself — never launch a subagent (Task/Agent tool, `fork`, or otherwise) to research, explore, or implement any part of this task on your behalf.
10
+
11
+ Do the steps below **in order**. Do not skip steps. Do not invent your own process.
12
+
13
+ **Shell hygiene:** run every command on its own line — no `&&` chaining, no `; echo "Exit code: $?"` suffixes, no subshell captures. The exit code and output are visible in the tool result. To run a project script, always use `./scripts/run.mjs <name>` — never call `node scripts/<name>.mjs` directly.
14
+
15
+ **Run autonomously.** This task runs unattended — do not ask the user questions or wait for feedback at any step. Make the best judgment call yourself, using the rules in this document, and keep going. Only stop early if the project isn't green before you start (Step 1), or if every remaining candidate target is blocked (see "Blocked work" below).
16
+
17
+ ## What you may and may not do
18
+
19
+ ### Safe work — DO IT AUTOMATICALLY, never ask
20
+
21
+ This work is always allowed. When your plan contains **only** safe work, you **must carry it out yourself, start to finish, without stopping.** Do **not** ask "Do you want me to proceed?". Do **not** pause to show the plan for approval. Do **not** wait for confirmation. Just write the tests and run them.
22
+
23
+ Safe work is:
24
+
25
+ - **Creating new test files** named `*.test.ts` or `*.test.tsx`, placed next to the file they test.
26
+ - **Adding new `it(...)` / `describe(...)` blocks** to an existing test file.
27
+ - Using a small mock for a **single** function or value when a test needs one.
28
+
29
+ ### Blocked work — skip and pick a different target
30
+
31
+ Do **not** attempt any of the following. If your plan for the chosen file requires one of these, **go back to Step 3** and pick the next-lowest file instead. Never ask the user — just skip and move on.
32
+
33
+ 1. Editing, deleting, or rewriting an **existing test**.
34
+ 2. Changing **any file that is not a `*.test.ts(x)` file** (for example, editing real source code "to make it testable").
35
+ 3. Replacing a **whole module** with a mock (e.g. `vi.mock('./something.js')` for a module that many files import).
36
+ 4. Testing **security, password/crypto, shell command, PTY/terminal, or network** code (applies to `src/` files only — `web/src/` files have no restrictions).
37
+ 5. Writing **more than 3** new test files in one run.
38
+
39
+ If every remaining candidate is blocked, report what you found (file, why it was blocked) and stop without writing any tests.
40
+
41
+ ---
42
+
43
+ ## Step 0 — Prepare the workspace
44
+
45
+ Execute `ai/tasks/prepare-workspace.md` in full before doing anything else.
46
+
47
+ ---
48
+
49
+ ## Step 1 — Run coverage and lint
50
+
51
+ Run both commands and read all of their output:
52
+
53
+ ```bash
54
+ npm run coverage 2>&1
55
+ npm run lint 2>&1
56
+ ```
57
+
58
+ Always run them fresh. Do not trust an old `coverage/` folder or earlier output in the conversation.
59
+
60
+ - **Tests:** `npm run coverage` executes the whole test suite. Every test must be passing before you add anything. If any test is already failing, STOP and tell the user — do not build on a broken suite.
61
+ - **Lint:** note the summary line — `✖ N problems (E errors, W warnings)`. Write down E and W. There must be **0 errors** to proceed. Warnings are pre-existing guidance and are expected.
62
+
63
+ ---
64
+
65
+ ## Step 2 — Read the coverage table
66
+
67
+ At the bottom of the Step 1 output is a table with one row per file. The columns are:
68
+
69
+ ```
70
+ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
71
+ ```
72
+
73
+ The **right-most column ("Uncovered Line #s")** lists the exact line numbers that have no test. This is all the information you need. **You do not need to open or parse `coverage/coverage-final.json`.**
74
+
75
+ ---
76
+
77
+ ## Step 3 — Pick exactly one target file
78
+
79
+ Choose the target with this exact procedure:
80
+
81
+ **First pass — `src/` (core logic):**
82
+
83
+ 1. Look at rows whose file path starts with **`src/`**.
84
+ 2. **Cross out** any row that is:
85
+ - `src/main.ts` (program entry point — nothing to test).
86
+ - `src/pty.ts` (only runs inside a real terminal).
87
+ - Already at **90% or higher** in the `% Lines` column.
88
+ 3. From the rows that remain, pick the **one with the lowest `% Lines`**.
89
+ - Tie? Pick the lower `% Branch`.
90
+ - Still tied? Pick the one with the most numbers in the "Uncovered Line #s" column.
91
+ 4. **Open that source file** and look at the uncovered lines from the table. If you discover the file can only run by launching a **real web browser (not JSDOM), a real terminal/PTY, a real network connection, or a real spawned program** (look for imports of `playwright`, `puppeteer`, `node-pty`, `ws`, `WebSocket`, or `child_process` / `node:child_process`), then skip it and go back to step 3 to take the next-lowest file.
92
+
93
+ **Second pass — `web/src/` (frontend):**
94
+
95
+ If **every `src/` row is crossed out** (all at ≥90% or blocked), repeat the procedure on rows whose file path starts with **`web/src/`**:
96
+ 1. **Cross out** any row already at **90% or higher** in the `% Lines` column.
97
+ 2. Pick the **one with the lowest `% Lines`** (same tie-breakers as above).
98
+ 3. **Open that source file.** No restrictions apply to `web/src/` files — proceed with testing any file you find.
99
+
100
+ State your pick in one short paragraph: the file path, its current `% Lines`, and the uncovered line numbers you will target.
101
+
102
+ ---
103
+
104
+ ## Step 4 — Plan the tests (a quick note to yourself, then keep going)
105
+
106
+ Jot down a short, plain list of the tests you will add. This is a note for yourself, not a message to send to the user — do **not** post it and wait for a reply.
107
+
108
+ - One bullet per test: its name, the input you give it, and the output or behavior you expect.
109
+ - Say which test file they go in. If no `*.test.ts` file exists next to the source file, you will create one.
110
+ - If a test needs a mock, name the one function or value you will mock and what it returns. Keep mocks as small as possible so the real code still runs.
111
+
112
+ Now check your plan against **What you may and may not do** above:
113
+
114
+ - If any of points 1–5 applies → go back to Step 3 and pick a different file.
115
+ - Otherwise (your plan is all **safe work**) → go straight to Step 5 and write the tests **now, on your own, without asking.**
116
+
117
+ ---
118
+
119
+ ## Step 5 — Write the tests
120
+
121
+ Create or extend the test file. Match the project's existing style exactly:
122
+
123
+ - Import test tools from vitest: `import { describe, it, expect } from 'vitest';` (add `vi` only if you mock).
124
+ - **`src/` files:** Relative imports must end in `.js`, even though the source file is `.ts`. Example: to test `src/foo.ts`, import `from './foo.js'`.
125
+ - **`web/src/` files:** Relative imports drop the extension. Example: to test `web/src/foo.ts`, import `from './foo'`.
126
+ - Put the test file right next to the source file (same folder), named `<name>.test.ts` (or `.test.tsx` for a React component).
127
+
128
+ Skeleton to copy:
129
+
130
+ ```ts
131
+ import { describe, it, expect } from 'vitest';
132
+ import { functionUnderTest } from './FILENAME.js'; // .js on purpose
133
+
134
+ describe('functionUnderTest', () => {
135
+ it('returns X when given Y', () => {
136
+ expect(functionUnderTest(Y)).toBe(X);
137
+ });
138
+ });
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Step 6 — Verify
144
+
145
+ Run both commands again, in this order:
146
+
147
+ ```bash
148
+ npm run lint 2>&1
149
+ npm run coverage 2>&1
150
+ ```
151
+
152
+ Fix any lint issues before looking at coverage — a lint error in a new test file will also distort the coverage output.
153
+
154
+ Then check, in this order:
155
+
156
+ 1. **Lint is no worse** — errors must be 0 (same as Step 1). Warnings must be equal to or fewer than Step 1. If a new lint error or warning appeared in a file you added or edited, fix it in that file. Do **not** suppress with `eslint-disable` — fix the underlying code.
157
+ 2. **The whole test suite passes** — every test, including ones you did not write. Adding tests must **never** make a previously-passing test fail.
158
+ - If one of **your new** tests fails because the test itself is wrong, fix the test and re-run.
159
+ - If a test fails because the real source code looks buggy, do **not** change the source — stop and report the suspected bug to the user.
160
+ - If you broke a previously-passing test, or the suite will not go green without editing source code or other tests, **delete the test file(s) you added** and report what blocked you. Never edit source or existing tests just to make the suite pass.
161
+ 3. **Coverage went up** — the target file's `% Lines` is higher than in Step 2.
162
+
163
+ ---
164
+
165
+ ## Step 7 — Report
166
+
167
+ Give the user a short report in this exact shape:
168
+
169
+ ```
170
+ Target file: <path>
171
+ Tests added: <count> in <test file path>
172
+ % Lines: <before> -> <after>
173
+ % Branch: <before> -> <after>
174
+ Lint: <before E errors, W warnings> -> <after>
175
+ Tests: all pass / <what failed>
176
+ ```
177
+
178
+ Keep it brief. Done.
@@ -0,0 +1,144 @@
1
+ # Merge a Workspaced Change to master
2
+
3
+ Your job: take the code changes present in this workspaced tab, package them into a pull request against `master` on GitHub, and **merge it once there are no conflicts** — rebasing past any conflicts. Do not wait on PR checks before merging.
4
+
5
+ **No AI attribution — anywhere.** Never credit an AI agent as an author or contributor in anything this task produces. That means: no `Co-Authored-By:` trailers naming Claude or any other AI, no “Generated with Claude Code” (or similar) lines or badges, and no AI authorship notes in code, comments, docs, spec files, plan files, commit messages, or PR titles and bodies. This overrides any default convention that appends such attribution. The commit's configured git author is the only authorship ever recorded.
6
+
7
+ The changes may have been made manually or produced by a preceding task — either way, this runs in a workspaced agent tab. That tab is a disposable, independent `git clone` of the root repo's `origin` remote living under `.janissary/workspace/<name>/`, so **its `origin` already points at GitHub.**
8
+
9
+ Every step is a script in `scripts/pr-*.sh`, invoked through the script runner. The steps below contain **no inline shell logic** — each one invokes its script.
10
+
11
+ **Always run scripts in the foreground.** Never use `run_in_background` — each script must complete and return its exit code before the next step begins.
12
+
13
+ **No subagents, no background agents.** Do every step yourself — never launch a subagent (Task/Agent tool, `fork`, or otherwise) to do any part of this task on your behalf.
14
+
15
+ **Do not ask the user for input at any point.** Make all decisions autonomously — branch names, commit messages, PR titles and bodies. The only valid reason to stop is an unresolvable error.
16
+
17
+ ---
18
+
19
+ ## Step 0 — Confirm there are changes to ship
20
+
21
+ ```bash
22
+ ./scripts/run.mjs pr-check-changes
23
+ ```
24
+
25
+ Prints the working-tree status and any commits ahead of `master`, and **exits non-zero** when there is nothing to ship. If it reports **"No changes to open a PR for"**, stop.
26
+
27
+ ---
28
+
29
+ ## Step 1 — Create a feature branch
30
+
31
+ Pick a short, **descriptive** `kebab-case` name that reflects the actual change, ideally prefixed by the change area. Avoid generic names like `fix` or `update`. **Choose the name yourself — do not ask the user.**
32
+
33
+ Good: `quality/extract-parsespec-helper`, `style/modern-color-notation`, `dedup/buffer-writer`
34
+ Bad: `patch-1`, `changes`, `wip`
35
+
36
+ ```bash
37
+ ./scripts/run.mjs pr-create-branch <branch>
38
+ ```
39
+
40
+ Any uncommitted changes carry over onto the new branch. (If the changes were already committed on the default branch, the new branch starts at those commits — that is fine.)
41
+
42
+ ---
43
+
44
+ ## Step 2 — Commit the changes (conventional commits message, **no co-authors**)
45
+
46
+ Write **one** commit. The subject line must follow the [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/) specification (see [`ai/guidelines/conventional-commits.md`](../guidelines/conventional-commits.md)): `<type>[optional scope]: <description>`. Valid types: `refactor`, `feat`, `fix`, `build`, `chore`, `ci`, `docs`, `style`, `perf`, `test`, `revert`. Include a body explaining *what* changed and *why*. `pr:commit` stages everything (`git add -A`) and commits with a **single author**:
47
+
48
+ ```bash
49
+ ./scripts/run.mjs pr-commit "refactor: extract parseSpec() helper to cut loadConfig cognitive complexity" \
50
+ "loadConfig exceeded the complexity limit; the spec-parsing block is now a small pure helper. No behavior change."
51
+ ```
52
+
53
+ Hard rule for the commit:
54
+
55
+ - **No co-authors.** The script adds **no** `Co-Authored-By:` trailer. This **overrides** any default convention that appends a Claude co-author — the commit must have a single author and no co-authors.
56
+
57
+ If earlier commits already exist on the branch, consolidate so the **final** state is a clean history with **no** co-author (amend as needed).
58
+
59
+ ---
60
+
61
+ ## Step 3 — Resolve the GitHub remote and push the branch
62
+
63
+ `origin` always points at GitHub — the workspace is an independent `git clone` of the root repo's `origin` remote. `pr-resolve-remote` reads it and prints the values to carry through the rest of the task:
64
+
65
+ ```bash
66
+ ./scripts/run.mjs pr-resolve-remote
67
+ ```
68
+
69
+ This prints a single space-separated line: `OWNER_REPO BRANCH GH_URL`. Read those three values from the output — each Bash command runs in its own fresh shell with no state persisted from the previous one, so substitute the actual literal values you read into each subsequent command rather than referencing shell variables — then push:
70
+
71
+ ```bash
72
+ ./scripts/run.mjs pr-push-branch origin my-branch-name
73
+ ```
74
+
75
+ If the push fails with an HTTP 400 RPC error ("unexpected disconnect while reading sideband packet"), `pr-push-branch` handles it for you: it raises `http.postBuffer` and forces HTTP/1.1, then retries automatically. No manual intervention is needed — just let the script run.
76
+
77
+ ---
78
+
79
+ ## Step 4 — Open the PR against `master`
80
+
81
+ Use the commit subject (which follows Conventional Commits format) as `<title>`. The PR title must match the commit subject and therefore also follows the Conventional Commits specification. Write the PR body to a file first — this avoids shell quoting issues with multi-line content. The body should have a **What** (one or two sentences on the change) and a **Why** (the warning/goal it addresses).
82
+
83
+ Write the body to `./temp/pr-body.md`, then open the PR:
84
+
85
+ ```bash
86
+ ./scripts/run.mjs pr-create-pr "$OWNER_REPO" "$BRANCH" "<title>" ./temp/pr-body.md
87
+ ```
88
+
89
+ Record the PR number/URL that the command prints.
90
+
91
+ ---
92
+
93
+ ## Step 5 — Check for conflicts
94
+
95
+ GitHub computes conflict status asynchronously; `pr:check-mergeable` polls until it is known:
96
+
97
+ ```bash
98
+ ./scripts/run.mjs pr-check-mergeable "$BRANCH" "$OWNER_REPO"
99
+ ```
100
+
101
+ - `MERGEABLE` → **no conflicts with master.** Go to **Step 7 (merge)**.
102
+ - `CONFLICTING` → **conflicts with master.** Go to **Step 6 (resolve conflicts)**.
103
+
104
+ ---
105
+
106
+ ## Step 6 — Resolve conflicts against master (repeat up to 5 times)
107
+
108
+ `pr:rebase` fetches `master`, rebases your branch onto it, re-runs the check gate, and force-pushes (with `--force-with-lease`) when the result is clean:
109
+
110
+ ```bash
111
+ ./scripts/run.mjs pr-rebase origin my-branch-name
112
+ ```
113
+
114
+ - **Exit 0** → rebased cleanly and pushed. Re-check conflict status (Step 5); when `MERGEABLE`, go to Step 7 (merge).
115
+ - **Exit 2** → it stopped on conflicts and listed the files. Open each, resolve the markers correctly (preserve the intent of *both* sides; never blindly drop master's changes), then **re-run the same command** — it continues the in-progress rebase.
116
+
117
+ Run this loop **at most 5 times**. If the PR is **still conflicting after 5 attempts**, **STOP**: report that conflicts could not be resolved automatically and leave the PR open for a human.
118
+
119
+ ---
120
+
121
+ ## Step 7 — Merge the PR
122
+
123
+ The PR is `MERGEABLE` (no conflicts). Squash-merge it and delete the remote branch — **do not wait on PR checks**; merge as soon as the PR is mergeable:
124
+
125
+ ```bash
126
+ ./scripts/run.mjs pr-merge "$BRANCH" "$OWNER_REPO"
127
+ ```
128
+
129
+ If the merge fails, report the error and leave the PR open for a human.
130
+
131
+ ---
132
+
133
+ ## Step 8 — Report
134
+
135
+ Give the user a short report in this exact shape:
136
+
137
+ ```
138
+ Branch: <branch>
139
+ PR: <url> (#<number>)
140
+ Conflicts: none | resolved in <n> rebase attempt(s) | unresolved after 5 attempts
141
+ Status: merged | open (merge failed — see error above) | open (conflicts unresolved after 5 attempts)
142
+ ```
143
+
144
+ Keep it brief. Done.
@@ -0,0 +1,161 @@
1
+ # Open a Feature Pull Request
2
+
3
+ Your job: take the uncommitted work in this repository, package it into a well-described pull request against `master` on GitHub, and open it. **Do not merge the PR** — just open it with a thorough description so reviewers understand exactly what changed and why.
4
+
5
+ **No AI attribution — anywhere.** Never credit an AI agent as an author or contributor in anything this task produces. That means: no `Co-Authored-By:` trailers naming Claude or any other AI, no “Generated with Claude Code” (or similar) lines or badges, and no AI authorship notes in code, comments, docs, spec files, plan files, commit messages, or PR titles and bodies. This overrides any default convention that appends such attribution. The commit's configured git author is the only authorship ever recorded.
6
+
7
+ **Do not ask the user for input at any point.** Make all decisions autonomously — branch name, commit message, PR title and body. The only valid reason to stop is "No changes to open a PR for" (Step 0) or an unresolvable error.
8
+
9
+ **Run everything synchronously, in the foreground.** Never use `run_in_background`, `&`, or otherwise start a background process (dev servers, watchers, long-lived processes) — every command must finish and return its exit code before you move to the next step.
10
+
11
+ **No subagents, no background agents.** Do every step yourself — never launch a subagent (Task/Agent tool, `fork`, or otherwise) to research, explore, or implement any part of this task on your behalf.
12
+
13
+ ## The PR description
14
+
15
+ The PR body is the deliverable. It must be **thorough and self-contained** — a reviewer should understand the feature without reading the code. Write it to `./temp/pr-body.md`, then pass that file to the create-PR script.
16
+
17
+ The body must include **every section below**, in this order:
18
+
19
+ ### What
20
+
21
+ Three to five paragraphs explaining the feature. Cover:
22
+ - What the feature does from the user's perspective
23
+ - What problem it solves or workflow it enables
24
+ - Which parts of the system it touches (server, web, both) and at a high level how it fits into the architecture
25
+ - Any design decisions worth calling out (e.g. "we chose a ref pattern instead of lifting state because…")
26
+
27
+ ### Behavior examples
28
+
29
+ Show the feature in action. Use **CLI transcripts** (for CLI/server features) or **reproducible user flows** (for UI features):
30
+
31
+ ```
32
+ # Before — the old behavior, if applicable
33
+ $ some-command --flag
34
+ <output showing the old/wrong/missing behavior>
35
+
36
+ # After — the new behavior
37
+ $ some-command --flag
38
+ <output showing the new/correct behavior>
39
+ ```
40
+
41
+ For UI changes, describe the flow step by step: what the user clicks, what they see, what happens next. Use ASCII diagrams when spatial relationships matter.
42
+
43
+ ### How to verify
44
+
45
+ A short list of manual verification steps a reviewer can follow. Keep each step concrete and testable — "open the app, run `foo`, confirm you see `bar`" rather than "make sure it works." Include edge cases: empty states, error paths, interactions with existing features.
46
+
47
+ ### Files changed
48
+
49
+ A concise summary of every file touched, grouped by area (`src/`, `web/src/`, `web/src/theme.css`, tests), with a one-line description of what changed in each.
50
+
51
+ ---
52
+
53
+ ## Step 0 — Confirm there are changes to ship
54
+
55
+ ```bash
56
+ ./scripts/run.mjs pr-check-changes
57
+ ```
58
+
59
+ Prints the working-tree status and any commits ahead of `master`, and **exits non-zero** when there is nothing to ship. If it reports **"No changes to open a PR for"**, stop.
60
+
61
+ ---
62
+
63
+ ## Step 1 — Make the check gate pass
64
+
65
+ This is the end-of-work gate. Run the full check:
66
+
67
+ ```bash
68
+ ./scripts/run.mjs pr-check-gate
69
+ ```
70
+
71
+ The gate runs **hard** checks only: typecheck, lint errors, tests, CSS. It does not run the advisory quality checks (complexity, duplication, dead code) — those belong to the human end-of-work gate (`npm run check:full`), not this automated step.
72
+
73
+ The hard checks **must pass**. If they fail **because of the changes**, fix the offending code and re-run until green. If you cannot get them green, **STOP** — do not open a PR on a red gate — and report exactly what failed. Never weaken a test or lint rule to make a hard check pass.
74
+
75
+ ---
76
+
77
+ ## Step 2 — Create a feature branch
78
+
79
+ Pick a short, **descriptive** `kebab-case` name that reflects the feature, ideally prefixed by the change area. **Choose the name yourself — do not ask the user.**
80
+
81
+ Good: `feature/unread-badge`, `cli/help-version-flags`, `ui/transcript-click-prefill`
82
+ Bad: `patch-1`, `changes`, `wip`
83
+
84
+ ```bash
85
+ ./scripts/run.mjs pr-create-branch <branch>
86
+ ```
87
+
88
+ Any uncommitted changes carry over onto the new branch.
89
+
90
+ ---
91
+
92
+ ## Step 3 — Commit the changes (conventional commits message, **no co-authors**)
93
+
94
+ Write **one** commit. The subject line must follow the [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/) specification (see [`ai/guidelines/conventional-commits.md`](../guidelines/conventional-commits.md)): `<type>[optional scope]: <description>`. Valid types: `feat`, `fix`, `build`, `chore`, `ci`, `docs`, `style`, `refactor`, `perf`, `test`, `revert`. Include a body explaining *what* changed and *why*. `pr-commit` stages everything (`git add -A`) and commits with a **single author**:
95
+
96
+ ```bash
97
+ ./scripts/run.mjs pr-commit "feat(ui): add unread badge on inactive tabs" \
98
+ "When a background tab receives new transcript content (messages, command output, shell completion), a sparkle badge appears on the tab strip. Focusing the tab clears it. Covers all content-delivery paths (append, finishRunning, shell onDone) and all activation paths (click, next, reorderTab, closeTab)."
99
+ ```
100
+
101
+ Hard rule for the commit:
102
+
103
+ - **No co-authors.** The script adds **no** `Co-Authored-By:` trailer. The commit must have a single author and no co-authors.
104
+
105
+ If earlier commits already exist on the branch, consolidate so the **final** state is a clean history with **no** co-author (amend as needed).
106
+
107
+ ---
108
+
109
+ ## Step 4 — Resolve the GitHub remote and push the branch
110
+
111
+ `origin` always points at GitHub — the workspace is an independent `git clone` of the root repo's `origin` remote. `pr-resolve-remote` reads it and prints the values later steps need:
112
+
113
+ ```bash
114
+ ./scripts/run.mjs pr-resolve-remote
115
+ ```
116
+
117
+ This prints a single space-separated line: `OWNER_REPO BRANCH GH_URL`. Read those three values directly from the command's stdout output. Each Bash command runs in its own fresh shell with no state persisted from the previous one, so do not reference them as shell variables in later commands — substitute the actual literal values you read into each subsequent command:
118
+
119
+ ```bash
120
+ ./scripts/run.mjs pr-push-branch origin my-branch-name
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Step 5 — Write the PR body
126
+
127
+ Write the full PR body to `./temp/pr-body.md` following the structure at the top of this document:
128
+
129
+ 1. **What** — 3-5 paragraphs
130
+ 2. **Behavior examples** — CLI transcripts or user flows
131
+ 3. **How to verify** — concrete manual verification steps
132
+ 5. **Files changed** — grouped summary
133
+
134
+ Use natural line breaks — never wrap lines at a fixed column.
135
+
136
+ ---
137
+
138
+ ## Step 6 — Open the PR against `master`
139
+
140
+ Use the commit subject (which follows Conventional Commits format) as `<title>`. The PR title must match the commit subject and therefore also follows the Conventional Commits specification. Substitute the actual `OWNER_REPO` and `BRANCH` values you read in Step 4, and pass the body file:
141
+
142
+ ```bash
143
+ ./scripts/run.mjs pr-create-pr owner/repo my-branch-name "<title>" ./temp/pr-body.md
144
+ ```
145
+
146
+ Record the PR number and URL that the command prints.
147
+
148
+ ---
149
+
150
+ ## Step 7 — Report
151
+
152
+ Give the user a short report in this exact shape:
153
+
154
+ ```
155
+ Branch: <branch>
156
+ PR: <url> (#<number>)
157
+ Check gate: pass (warnings allowed) | see errors above
158
+ Status: open
159
+ ```
160
+
161
+ Keep it brief. Done.