@shepai/cli 1.154.0 → 1.155.0-pr481.af47b59

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 (179) hide show
  1. package/README.md +117 -113
  2. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  3. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +4 -1
  4. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/pr-branding.d.ts +5 -0
  5. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/pr-branding.d.ts.map +1 -0
  6. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/pr-branding.js +4 -0
  7. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.d.ts.map +1 -1
  8. package/dist/packages/core/src/infrastructure/services/deployment/deployment.service.js +6 -5
  9. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.d.ts +2 -0
  10. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.d.ts.map +1 -1
  11. package/dist/packages/core/src/infrastructure/services/deployment/detect-dev-script.js +52 -3
  12. package/dist/packages/core/src/infrastructure/services/git/git-fork.service.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/services/git/git-fork.service.js +3 -1
  14. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  15. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +2 -1
  16. package/dist/packages/core/src/infrastructure/services/git/pr-branding.d.ts +17 -0
  17. package/dist/packages/core/src/infrastructure/services/git/pr-branding.d.ts.map +1 -0
  18. package/dist/packages/core/src/infrastructure/services/git/pr-branding.js +31 -0
  19. package/dist/tsconfig.build.tsbuildinfo +1 -1
  20. package/package.json +1 -1
  21. package/web/.next/BUILD_ID +1 -1
  22. package/web/.next/build-manifest.json +2 -2
  23. package/web/.next/fallback-build-manifest.json +2 -2
  24. package/web/.next/prerender-manifest.json +3 -3
  25. package/web/.next/required-server-files.js +3 -3
  26. package/web/.next/required-server-files.json +3 -3
  27. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  28. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  30. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +26 -26
  31. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  32. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  33. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +29 -29
  34. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  35. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  37. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  40. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  41. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  43. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  46. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +26 -26
  49. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  50. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  51. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +29 -29
  52. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  53. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  54. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  55. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  56. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  58. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  59. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  61. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  62. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +26 -26
  64. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  65. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  67. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  68. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/app/_global-error.html +2 -2
  70. package/web/.next/server/app/_global-error.rsc +1 -1
  71. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  72. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  73. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  74. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  75. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  76. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +5 -5
  77. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  78. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  80. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  81. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  82. package/web/.next/server/app/skills/page/server-reference-manifest.json +10 -10
  83. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  84. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  85. package/web/.next/server/app/tools/page/server-reference-manifest.json +10 -10
  86. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  87. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/version/page/server-reference-manifest.json +5 -5
  89. package/web/.next/server/app/version/page.js.nft.json +1 -1
  90. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  92. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +1 -1
  93. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  94. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  95. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  96. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  97. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js +1 -1
  98. package/web/.next/server/chunks/ssr/[root-of-the-server]__17ed7ed1._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/[root-of-the-server]__28d0d265._.js +2 -2
  100. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  101. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js +1 -1
  102. package/web/.next/server/chunks/ssr/[root-of-the-server]__42bf1807._.js.map +1 -1
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js +1 -1
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__88f7e8e6._.js.map +1 -1
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +1 -1
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js.map +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__f80bfc75._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__f8dd4422._.js +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__f8dd4422._.js.map +1 -1
  114. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  115. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  117. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/_3a0b989f._.js +2 -2
  119. package/web/.next/server/chunks/ssr/_3a0b989f._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/{_27154347._.js → _4640978c._.js} +2 -2
  121. package/web/.next/server/chunks/ssr/{_27154347._.js.map → _4640978c._.js.map} +1 -1
  122. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  123. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/_5f69c13f._.js +1 -1
  125. package/web/.next/server/chunks/ssr/_5f69c13f._.js.map +1 -1
  126. package/web/.next/server/chunks/ssr/{_4af8a3cb._.js → _65f2dbe6._.js} +2 -2
  127. package/web/.next/server/chunks/ssr/{_4af8a3cb._.js.map → _65f2dbe6._.js.map} +1 -1
  128. package/web/.next/server/chunks/ssr/_7c5b97c6._.js +1 -1
  129. package/web/.next/server/chunks/ssr/_7c5b97c6._.js.map +1 -1
  130. package/web/.next/server/chunks/ssr/_82c57f10._.js +1 -1
  131. package/web/.next/server/chunks/ssr/_82c57f10._.js.map +1 -1
  132. package/web/.next/server/chunks/ssr/_9495d50b._.js +1 -1
  133. package/web/.next/server/chunks/ssr/_9495d50b._.js.map +1 -1
  134. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js +1 -1
  135. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js.map +1 -1
  136. package/web/.next/server/chunks/ssr/_ac4a3873._.js +1 -1
  137. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js +1 -1
  138. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/_cb5a021e._.js +1 -1
  140. package/web/.next/server/chunks/ssr/_cb5a021e._.js.map +1 -1
  141. package/web/.next/server/chunks/ssr/{_a0e4c32f._.js → _d1120ef4._.js} +2 -2
  142. package/web/.next/server/chunks/ssr/{_a0e4c32f._.js.map → _d1120ef4._.js.map} +1 -1
  143. package/web/.next/server/chunks/ssr/_d86175ae._.js +1 -1
  144. package/web/.next/server/chunks/ssr/_d86175ae._.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/_d8bedf13._.js +1 -1
  146. package/web/.next/server/chunks/ssr/_d8bedf13._.js.map +1 -1
  147. package/web/.next/server/chunks/ssr/_fa7efce3._.js +2 -2
  148. package/web/.next/server/chunks/ssr/_fa7efce3._.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  150. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  151. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js +1 -1
  152. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_cdc632e3.js.map +1 -1
  153. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js +1 -1
  154. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_39ca0924.js.map +1 -1
  155. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  156. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js +1 -1
  157. package/web/.next/server/chunks/ssr/src_presentation_web_components_357e3eb0._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  159. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  160. package/web/.next/server/pages/500.html +2 -2
  161. package/web/.next/server/server-reference-manifest.js +1 -1
  162. package/web/.next/server/server-reference-manifest.json +45 -45
  163. package/web/.next/static/chunks/14a6cecd54027e13.js +1 -0
  164. package/web/.next/static/chunks/{9545412c334d71c5.js → 31d74fa1d6acc5e7.js} +1 -1
  165. package/web/.next/static/chunks/3432338262ea5cfa.js +1 -0
  166. package/web/.next/static/chunks/{a18fcdf7dd4055a5.js → 345fcb2e225b77d5.js} +3 -3
  167. package/web/.next/static/chunks/{f10c138c3fae4680.js → 362b815754eed954.js} +2 -2
  168. package/web/.next/static/chunks/{be495f0642b9f423.js → 64b598518cbee0d3.js} +1 -1
  169. package/web/.next/static/chunks/{e0104cdb4b857e49.js → 71e12e354ae78bc5.js} +1 -1
  170. package/web/.next/static/chunks/{e333a91862ff2423.js → a6e1c13997e2772b.js} +1 -1
  171. package/web/.next/static/chunks/{0e258f8cce588570.js → b9e6584f428f2e87.js} +1 -1
  172. package/web/.next/static/chunks/{ae61d24b1bcc8cf7.js → c4651ed82a2fbfc6.js} +2 -2
  173. package/web/.next/static/chunks/{b5bf0ff0a2bc910a.js → c599446f655681bd.js} +1 -1
  174. package/web/.next/static/chunks/{e9cce6c925c64f10.js → dd83670b0a141611.js} +1 -1
  175. package/web/.next/static/chunks/2eb2e32a6181e9ed.js +0 -1
  176. package/web/.next/static/chunks/502fd2cb6c8beb89.js +0 -1
  177. /package/web/.next/static/{9ZnNgGSTMM2ACNp4ImvQo → K7WzDNsT2rF466QGhk8x9}/_buildManifest.js +0 -0
  178. /package/web/.next/static/{9ZnNgGSTMM2ACNp4ImvQo → K7WzDNsT2rF466QGhk8x9}/_clientMiddlewareManifest.json +0 -0
  179. /package/web/.next/static/{9ZnNgGSTMM2ACNp4ImvQo → K7WzDNsT2rF466QGhk8x9}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -2,22 +2,15 @@
2
2
 
3
3
  # Shep AI
4
4
 
5
- ### One command. Full lifecycle. Merged PR.
5
+ ### AI-assisted feature development with human checkpoints
6
6
 
7
- _Describe a feature in plain English Shep researches, plans, codes, tests, and opens a PR. You approve when you want to, or let it run hands-free._
7
+ _Describe a feature in plain English. Shep builds it step by step — researching, planning, coding, and testing pausing for your approval at every critical decision._
8
8
 
9
9
  [![CI](https://github.com/shep-ai/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/shep-ai/cli/actions/workflows/ci.yml)
10
10
  [![npm version](https://img.shields.io/npm/v/@shepai/cli.svg?color=cb3837&logo=npm)](https://www.npmjs.com/package/@shepai/cli)
11
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-3178c6.svg?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
13
- [![Node.js](https://img.shields.io/badge/Node.js-≥18-339933.svg?logo=node.js&logoColor=white)](https://nodejs.org/)
14
- [![pnpm](https://img.shields.io/badge/pnpm-≥8-f69220.svg?logo=pnpm&logoColor=white)](https://pnpm.io/)
15
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/shep-ai/cli/pulls)
16
- [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-fe5196.svg?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
17
12
 
18
- <br />
19
-
20
- [Features](#features) · [Quick Start](#quick-start) · [CLI Reference](#cli-reference) · [Architecture](#architecture) · [Contributing](#contributing)
13
+ [How It Works](#how-it-works) · [Quick Start](#quick-start) · [Trust & Safety](#trust--safety) · [CLI Reference](#cli-reference) · [FAQ](#faq)
21
14
 
22
15
  <br />
23
16
 
@@ -27,6 +20,46 @@ _Describe a feature in plain English — Shep researches, plans, codes, tests, a
27
20
 
28
21
  ---
29
22
 
23
+ ## Who is Shep for?
24
+
25
+ Solo developers and small teams who use AI coding agents (Claude Code, Cursor, Gemini CLI) and want structure around the messy parts — turning a feature idea into a clear plan, keeping work isolated per feature, and not losing context when switching between tasks.
26
+
27
+ Shep is not a replacement for your coding agent. It's the orchestration layer that sits above it: it manages requirements, plans, git branches, and review gates so you can focus on the parts that need human judgment.
28
+
29
+ ---
30
+
31
+ ## How It Works
32
+
33
+ Every feature moves through a structured pipeline. You control how much autonomy the agent gets.
34
+
35
+ ```
36
+ You describe Shep generates Shep researches Shep writes Shep codes Shep opens
37
+ a feature → requirements → your codebase → a plan → + tests → a PR
38
+ ▲ ▲ ▲
39
+ Gate 1: PRD Gate 2: Plan Gate 3: Merge
40
+ (approve/edit) (approve/edit) (approve/reject)
41
+ ```
42
+
43
+ **Three approval gates.** Each one pauses execution and waits for you to review, edit, or approve before the agent continues. You choose which gates to enable:
44
+
45
+ | Flag | Gate | What you're approving |
46
+ |------|------|-----------------------|
47
+ | `--allow-prd` | Requirements | Auto-approve the generated PRD |
48
+ | `--allow-plan` | Plan | Auto-approve the implementation plan |
49
+ | `--allow-merge` | Merge | Auto-approve the final PR |
50
+ | `--allow-all` | All three | Fully autonomous — agent handles everything |
51
+
52
+ **With no flags**, every gate requires your explicit approval. You see exactly what the agent intends to do before it does it.
53
+
54
+ ### What happens when things go wrong
55
+
56
+ - **CI fails after PR creation.** Shep reads the CI logs, diagnoses the failure, and pushes a fix. It retries up to 3 times before pausing and asking for your input.
57
+ - **Agent gets stuck or produces bad output.** The feature enters a `Blocked` state. You get notified and can provide feedback, reject the current phase, or restart from a checkpoint.
58
+ - **You don't like the plan.** Reject it with comments. Shep regenerates the plan incorporating your feedback.
59
+ - **You want to take over mid-feature.** The code lives in a standard git worktree on a named branch. You can open it in your IDE and work on it directly at any point.
60
+
61
+ ---
62
+
30
63
  ## Quick Start
31
64
 
32
65
  ```bash
@@ -35,28 +68,62 @@ npx @shepai/cli
35
68
 
36
69
  # Or install globally
37
70
  npm i -g @shepai/cli
71
+
72
+ # Start Shep — opens the web dashboard at http://localhost:4050
38
73
  shep
74
+ ```
39
75
 
40
- # Browser opens at http://localhost:4050 — you're in
76
+ ### Your first feature
77
+
78
+ ```bash
79
+ # With approval gates (recommended to start)
80
+ shep feat new "add a /health endpoint that returns uptime and version"
81
+
82
+ # Shep will pause at each gate for your review.
83
+ # Once you're comfortable, try autonomous mode:
84
+ shep feat new "add rate limiting to the API" --allow-all --push --pr
41
85
  ```
42
86
 
43
- ---
87
+ ### Parallel features
44
88
 
45
- ## Features
89
+ Each feature gets its own git worktree — no stashing, no branch conflicts:
46
90
 
47
91
  ```bash
48
- shep feat new "add stripe payments" --allow-all --push --pr
49
- # PRD research plan code → tests → PR → CI watch — done.
92
+ shep feat new "add stripe payments" --push --pr
93
+ shep feat new "add dark mode toggle" --push --pr
94
+ # Both run simultaneously in isolated worktrees
50
95
  ```
51
96
 
52
- - **Full lifecycle in one shot** — From idea to merged PR: requirements, technical research, implementation plan, code with tests, PR creation, and CI fix loop
53
- - **Approve or go hands-free** — Three review gates (PRD, Plan, Merge) you can enable, disable, or skip entirely with `--allow-all`
54
- - **Run 10 features in parallel** — Each gets its own git worktree — switch context instantly, no stashing, no branch juggling, no conflicts
55
- - **Pick your agent** — Claude Code, Cursor CLI, or Gemini CLI — swap per feature, per repo, anytime
56
- - **Live dashboard** — Interactive graph of every repo and feature — review diffs, approve merges, launch dev servers, all in-browser
57
- - **100% local, zero signup** — SQLite in `~/.shep/`, nothing leaves your machine, no account needed
97
+ ---
58
98
 
59
- > **[See the full Features Guide with screenshots →](./docs/FEATURES.md)**
99
+ ## Trust & Safety
100
+
101
+ Shep runs entirely on your machine. Here's the security model:
102
+
103
+ | Concern | How Shep handles it |
104
+ |---------|-------------------|
105
+ | **Data stays local** | All data lives in `~/.shep/` as SQLite databases. Nothing is sent to Shep servers — there are none. |
106
+ | **Agent sandboxing** | Shep delegates coding to your chosen agent (Claude Code, Cursor CLI, Gemini CLI). The agent's own permission model applies. Shep does not grant additional permissions. |
107
+ | **Git isolation** | Every feature runs in its own git worktree branched from your main branch. Your working directory is never modified. |
108
+ | **No credential access** | Shep never reads, stores, or transmits your API keys. Agent authentication is handled by the agent itself. |
109
+ | **Review before merge** | Unless you explicitly pass `--allow-merge`, no code is merged without your approval. PRs are created as drafts when using `--pr`. |
110
+ | **Audit trail** | Every agent action, approval, and state transition is logged. View with `shep feat logs <id>`. |
111
+
112
+ **What `--allow-all` actually means:** The agent will auto-approve requirements, auto-approve the plan, and auto-merge the PR. It does _not_ bypass CI — your CI pipeline still runs and must pass. Use this for low-risk tasks on repos with good test coverage, not for changes to production infrastructure.
113
+
114
+ ---
115
+
116
+ ## Features
117
+
118
+ - **Structured lifecycle** — Requirements, research, planning, implementation, and review as distinct phases, not one opaque prompt
119
+ - **Three configurable approval gates** — Full control, full autonomy, or anything in between
120
+ - **Parallel features via worktrees** — Multiple features in flight at once with zero branch conflicts
121
+ - **Agent-agnostic** — Claude Code, Cursor CLI, or Gemini CLI — swap anytime per feature or per repo
122
+ - **Web dashboard** — Interactive graph of repos and features with real-time status, diff review, and approval actions at `localhost:4050`
123
+ - **CI fix loop** — When CI fails, the agent reads logs, diagnoses, and retries before asking for help
124
+ - **100% local** — SQLite storage, no cloud dependency, no account needed
125
+
126
+ > **[Full features guide with screenshots →](./docs/FEATURES.md)**
60
127
 
61
128
  ---
62
129
 
@@ -141,119 +208,56 @@ shep run <agent> [-p prompt] [-r repo] [-s] Run an agent directly
141
208
 
142
209
  ---
143
210
 
144
- ## Architecture
145
-
146
- Clean Architecture with four layers. Dependencies point inward — domain has zero external deps.
147
-
148
- ```mermaid
149
- flowchart TB
150
- P["<b>Presentation</b><br/>CLI · Web UI · TUI"]
151
- A["<b>Application</b><br/>Use Cases · Orchestration · Ports"]
152
- D["<b>Domain</b><br/>Entities · Value Objects · Services"]
153
- I["<b>Infrastructure</b><br/>SQLite · LangGraph · DI"]
154
-
155
- P --> A --> D
156
- I --> A
211
+ ## FAQ
157
212
 
158
- style P fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
159
- style A fill:#fef3c7,stroke:#f59e0b,color:#78350f
160
- style D fill:#d1fae5,stroke:#10b981,color:#064e3b
161
- style I fill:#ede9fe,stroke:#8b5cf6,color:#4c1d95
162
- ```
163
-
164
- | Layer | Path | Responsibility |
165
- | -------------- | ----------------------------------- | ------------------------------------------------- |
166
- | Domain | `packages/core/src/domain/` | Business logic, TypeSpec-generated types |
167
- | Application | `packages/core/src/application/` | Use cases, output port interfaces |
168
- | Infrastructure | `packages/core/src/infrastructure/` | SQLite repos, LangGraph agents, DI (tsyringe) |
169
- | Presentation | `src/presentation/` | CLI (Commander), TUI (Inquirer), Web UI (Next.js) |
170
-
171
- ### Feature Lifecycle
172
-
173
- Every feature progresses through a structured SDLC pipeline with 9 states:
174
-
175
- ```
176
- Started -> Analyze -> Requirements -> Research -> Planning -> Implementation -> Review -> Maintain
177
- |
178
- (Blocked)
179
- ```
213
+ **How is this different from just using Claude Code / Cursor directly?**
214
+ Those tools are excellent at writing code given a prompt. Shep adds the layer above: breaking a feature into structured phases, managing requirements and plans as reviewable artifacts, isolating work in git worktrees, and handling the PR/CI lifecycle. Think of it as a project manager for your AI coding agent.
180
215
 
181
- Human approval gates are configurable at PRD, Plan, and Merge phases. In `--allow-all` mode the agent handles everything autonomously.
216
+ **What happens if the agent writes bad code?**
217
+ The same thing that happens in a normal code review. Shep creates a PR. Your CI runs. If tests fail, Shep attempts to fix them. If the fix loop exhausts retries, the feature pauses and you're notified. You can also reject at any approval gate with feedback, and Shep will regenerate.
182
218
 
183
- ### Tech Stack
219
+ **Does this work on large codebases?**
220
+ Shep's research phase scans your codebase to build context before planning. The quality of the output depends on the underlying agent's ability to handle your repo. If Claude Code or Cursor works well on your codebase directly, Shep will too — it adds structure, not limitations.
184
221
 
185
- | Component | Technology |
186
- | --------------- | ------------------------------------------------------------------------- |
187
- | Language | TypeScript (ES2022) |
188
- | Package Manager | pnpm |
189
- | CLI Framework | Commander |
190
- | TUI Framework | [@inquirer/prompts](https://github.com/SBoudrias/Inquirer.js) |
191
- | Web UI | Next.js 16 + React 19 + shadcn/ui + Tailwind CSS 4 |
192
- | Graph Viz | React Flow (XYFlow) 12 |
193
- | Design System | Storybook 8.x |
194
- | Build Tool | tsc + tsc-alias (prod), tsx (CLI dev), Next.js (web dev) |
195
- | Database | SQLite (better-sqlite3, per-repo) |
196
- | Domain Models | TypeSpec -> generated TypeScript |
197
- | Agent System | [LangGraph](https://www.langchain.com/langgraph) (`@langchain/langgraph`) |
198
- | DI Container | tsyringe |
199
- | Testing | Vitest (unit/integration) + Playwright (e2e) |
200
- | Methodology | TDD (Red-Green-Refactor) |
222
+ **Can I use this on a team?**
223
+ Shep runs locally and operates on your git repo. Multiple team members can each run Shep independently. Features are just branches and PRs — your existing review process applies. There is no shared server or collaboration layer today.
201
224
 
202
- ### Supported Tools
225
+ **Is my code sent anywhere?**
226
+ Not by Shep. Your code is sent to whichever AI agent you configure (Claude, Cursor, Gemini) under that agent's own privacy terms. Shep itself stores everything in local SQLite and makes no network calls.
203
227
 
204
- Shep can detect, install, and manage the following tools:
228
+ ---
205
229
 
206
- | Category | Tools |
207
- | ---------- | --------------------------------------------------------------------------------- |
208
- | IDEs | Alacritty, Antigravity, Cursor, iTerm2, Kitty, TMux, VS Code, Warp, Windsurf, Zed |
209
- | CLI Agents | Claude Code, Cursor CLI, Gemini CLI |
210
- | Dev Tools | Git, GitHub CLI |
230
+ ## Architecture
211
231
 
212
- ### Web UI
232
+ Shep follows Clean Architecture with four layers. If you're interested in contributing or understanding the internals:
213
233
 
214
- The web dashboard runs at `http://localhost:4050` and provides:
234
+ | Layer | Path | Responsibility |
235
+ |-------|------|---------------|
236
+ | Domain | `packages/core/src/domain/` | Business logic, TypeSpec-generated types |
237
+ | Application | `packages/core/src/application/` | Use cases, port interfaces |
238
+ | Infrastructure | `packages/core/src/infrastructure/` | SQLite, LangGraph agents, DI |
239
+ | Presentation | `src/presentation/` | CLI, TUI, Web UI |
215
240
 
216
- - **Dashboard canvas** Interactive React Flow graph with feature and repository nodes
217
- - **Feature drawer** — Tabs for overview, activity, approval, rejection, PR info, deployment, and timeline
218
- - **Create feature form** — Start new features from the UI
219
- - **Settings, Tools, Skills, and Version pages**
220
- - **Real-time updates** via Server-Sent Events (SSE)
241
+ > **[Full architecture docs →](./docs/architecture/overview.md)**
221
242
 
222
- ### Data Model
243
+ ---
223
244
 
224
- ```
225
- Repository --+-- Feature --+-- Plan --+-- Task -- ActionItem
226
- | | +-- Artifact
227
- | +-- Requirement -- Research
228
- ```
245
+ ## Supported Agents & Tools
229
246
 
230
- All data lives locally in `~/.shep/`. Per-repo SQLite databases. No cloud dependency.
247
+ | Category | Supported |
248
+ |----------|-----------|
249
+ | AI Agents | Claude Code, Cursor CLI, Gemini CLI |
250
+ | IDEs | VS Code, Cursor, Zed, Windsurf, and [more](./docs/FEATURES.md) |
251
+ | Required | Git, GitHub CLI |
231
252
 
232
253
  ---
233
254
 
234
- ## Documentation
235
-
236
- | Document | Description |
237
- | -------------------------------------------------- | ------------------------------------------ |
238
- | [Features Guide](./docs/FEATURES.md) | Full features overview with screenshots |
239
- | [Competitive Landscape](./docs/competitors/) | How Shep fits in the AI dev tool ecosystem |
240
- | [CLAUDE.md](./CLAUDE.md) | Guidance for Claude Code instances |
241
- | [AGENTS.md](./AGENTS.md) | Agent system architecture |
242
- | [CONTRIBUTING-AGENTS.md](./CONTRIBUTING-AGENTS.md) | AI agent contribution guidelines |
243
- | [Architecture](./docs/architecture/) | System design and patterns |
244
- | [Concepts](./docs/concepts/) | Core domain concepts |
245
- | [UI](./docs/ui/) | Web UI architecture and design system |
246
- | [Guides](./docs/guides/) | User guides and tutorials |
247
- | [Development](./docs/development/) | Contributing and development setup |
248
- | [API Reference](./docs/api/) | Interface and model documentation |
249
-
250
255
  ## Contributing
251
256
 
252
257
  We welcome contributions from humans and AI agents alike.
253
258
 
254
259
  - **Humans**: See [CONTRIBUTING.md](./CONTRIBUTING.md)
255
260
  - **AI Agents**: See [CONTRIBUTING-AGENTS.md](./CONTRIBUTING-AGENTS.md)
256
- - **Spec-driven workflow**: All features start with `/shep-kit:new-feature` — see [Spec-Driven Workflow](./docs/development/spec-driven-workflow.md)
257
261
 
258
262
  ## License
259
263
 
@@ -1 +1 @@
1
- {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAyER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqDzD"}
1
+ {"version":3,"file":"merge-prompts.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAyCxD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAU9F;AAuCD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAAE,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CA2ER;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CA0BR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqDzD"}
@@ -11,6 +11,7 @@
11
11
  import yaml from 'js-yaml';
12
12
  import { EvidenceType } from '../../../../../../domain/generated/output.js';
13
13
  import { readSpecFile, buildResumeContext } from '../node-helpers.js';
14
+ import { PR_BRANDING } from './pr-branding.js';
14
15
  /**
15
16
  * Extract merge-phase rejection feedback from spec.yaml.
16
17
  */
@@ -152,7 +153,9 @@ export function buildCommitPushPrPrompt(state, branch, baseBranch, repoUrl) {
152
153
  steps.push(`${shouldPush ? '6' : '4'}. Create a pull request:
153
154
  - Run \`gh pr create --base ${baseBranch} --head ${branch} --title "<title>" --body "<body>"\`
154
155
  - Write a descriptive PR title using conventional commit format
155
- - Write a rich PR body that summarizes the changes using the spec context below`);
156
+ - Write a rich PR body that summarizes the changes using the spec context below
157
+ - The PR body MUST end with this exact branding line (on its own line): \`${PR_BRANDING}\`
158
+ - Do NOT include any other attribution footer (e.g. "Generated with Claude Code" or similar) — only the Shep branding line above`);
156
159
  }
157
160
  const resumeContext = buildResumeContext(state.resumeReason);
158
161
  return `${resumeContext}You are performing git operations in a feature worktree.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-export PR branding from the canonical location in git services.
3
+ */
4
+ export { PR_BRANDING, applyPrBranding } from '../../../../../services/git/pr-branding.js';
5
+ //# sourceMappingURL=pr-branding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-branding.d.ts","sourceRoot":"","sources":["../../../../../../../../../../packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/pr-branding.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,8CAA8C,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Re-export PR branding from the canonical location in git services.
3
+ */
4
+ export { PR_BRANDING, applyPrBranding } from '../../../../../services/git/pr-branding.js';
@@ -1 +1 @@
1
- {"version":3,"file":"deployment.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/deployment.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAmC,MAAM,oBAAoB,CAAC;AAK5E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACT,MAAM,qEAAqE,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAiCzD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AA0CD,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,EAAE,CAAkC;gBAEhC,IAAI,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAIrD;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIxC;;;;;;;;;;;;OAYG;IACH,UAAU,IAAI,IAAI;IAqFlB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,SAAe,GAAG,IAAI;IA6H5E;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IA4CpD;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAef;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAI1D;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAM3D,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,WAAW;IAQnB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YA4Dd,aAAa;IAW3B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;YACW,kBAAkB;IAsChC;;;OAGG;IACH,OAAO,CAAC,SAAS;CAwBlB"}
1
+ {"version":3,"file":"deployment.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/deployment.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,EAAmC,MAAM,oBAAoB,CAAC;AAK5E,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACT,MAAM,qEAAqE,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAiCzD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACnC;AA0CD,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,EAAE,CAAkC;gBAEhC,IAAI,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAIrD;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAIxC;;;;;;;;;;;;OAYG;IACH,UAAU,IAAI,IAAI;IAqFlB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,SAAe,GAAG,IAAI;IA8H5E;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IA4CpD;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAef;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,IAAI;IAM5C;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAI1D;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAM3D,OAAO,CAAC,QAAQ;IAuBhB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,WAAW;IAQnB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;YA4Dd,aAAa;IAW3B,OAAO,CAAC,WAAW;IAUnB;;;;OAIG;YACW,kBAAkB;IAsChC;;;OAGG;IACH,OAAO,CAAC,SAAS;CAwBlB"}
@@ -188,14 +188,15 @@ export class DeploymentService {
188
188
  throw new Error(detection.error);
189
189
  }
190
190
  // Build spawn args based on package manager
191
- const { packageManager, scriptName, command, needsInstall } = detection;
191
+ const { packageManager, scriptName, command, needsInstall, resolvedDir } = detection;
192
+ const spawnDir = resolvedDir;
192
193
  const args = packageManager === 'npm' ? ['run', scriptName] : [scriptName];
193
194
  // Install dependencies if node_modules is missing (e.g. fresh worktree)
194
195
  if (needsInstall) {
195
- log.info(`node_modules missing in "${targetPath}" — running ${packageManager} install`);
196
+ log.info(`node_modules missing in "${spawnDir}" — running ${packageManager} install`);
196
197
  try {
197
198
  execFileSync(packageManager, ['install'], {
198
- cwd: targetPath,
199
+ cwd: spawnDir,
199
200
  shell: true,
200
201
  stdio: 'ignore',
201
202
  ...(IS_WINDOWS ? { windowsHide: true } : {}),
@@ -207,10 +208,10 @@ export class DeploymentService {
207
208
  throw new Error(`Failed to install dependencies: ${err}`);
208
209
  }
209
210
  }
210
- log.info(`Spawning dev server: command="${command}", packageManager="${packageManager}", scriptName="${scriptName}", cwd="${targetPath}"`);
211
+ log.info(`Spawning dev server: command="${command}", packageManager="${packageManager}", scriptName="${scriptName}", cwd="${spawnDir}"`);
211
212
  const child = this.deps.spawn(packageManager, args, {
212
213
  shell: true,
213
- cwd: targetPath,
214
+ cwd: spawnDir,
214
215
  // On Unix, detached: true creates a process group via setsid() so we can
215
216
  // kill the entire tree with process.kill(-pid). On Windows this flag causes
216
217
  // CREATE_NEW_CONSOLE which opens a visible terminal window and disconnects
@@ -11,6 +11,8 @@ export interface DetectDevScriptSuccess {
11
11
  scriptName: string;
12
12
  command: string;
13
13
  needsInstall: boolean;
14
+ /** The directory where package.json was found (may differ from input when scanning subdirs) */
15
+ resolvedDir: string;
14
16
  }
15
17
  export interface DetectDevScriptError {
16
18
  success: false;
@@ -1 +1 @@
1
- {"version":3,"file":"detect-dev-script.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/detect-dev-script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,IAAI,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAIlF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAwCtE"}
1
+ {"version":3,"file":"detect-dev-script.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/deployment/detect-dev-script.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,IAAI,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAIlF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAetE"}
@@ -5,7 +5,7 @@
5
5
  * scripts (dev, start, serve), and detects the package manager from lockfile
6
6
  * presence. Returns the detected command or an error.
7
7
  */
8
- import { readFileSync, existsSync } from 'node:fs';
8
+ import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
  import { createDeploymentLogger } from './deployment-logger.js';
11
11
  /** Script names to search for, in priority order */
@@ -25,6 +25,23 @@ const log = createDeploymentLogger('[detectDevScript]');
25
25
  */
26
26
  export function detectDevScript(dirPath) {
27
27
  log.info(`scanning dirPath="${dirPath}"`);
28
+ // Try the given directory first
29
+ const directResult = detectDevScriptInDir(dirPath);
30
+ if (directResult.success)
31
+ return directResult;
32
+ // Fallback: scan immediate subdirectories for a package.json with a dev script.
33
+ // This handles monorepos and projects where the app lives in a subdirectory
34
+ // (e.g., worktree root has no package.json but `site/` or `app/` does).
35
+ log.info(`no dev script at root, scanning subdirectories of "${dirPath}"`);
36
+ const subdirResult = scanSubdirectories(dirPath);
37
+ if (subdirResult)
38
+ return subdirResult;
39
+ return directResult;
40
+ }
41
+ /**
42
+ * Attempt detection in a single directory.
43
+ */
44
+ function detectDevScriptInDir(dirPath) {
28
45
  // Read and parse package.json
29
46
  let packageJson;
30
47
  try {
@@ -51,8 +68,40 @@ export function detectDevScript(dirPath) {
51
68
  // Build the command — pnpm/yarn use `<pm> <script>`, npm uses `npm run <script>`
52
69
  const command = packageManager === 'npm' ? `npm run ${scriptName}` : `${packageManager} ${scriptName}`;
53
70
  const needsInstall = !existsSync(join(dirPath, 'node_modules'));
54
- log.info(`detected — packageManager="${packageManager}", scriptName="${scriptName}", command="${command}", needsInstall=${needsInstall}`);
55
- return { success: true, packageManager, scriptName, command, needsInstall };
71
+ log.info(`detected — packageManager="${packageManager}", scriptName="${scriptName}", command="${command}", needsInstall=${needsInstall}, resolvedDir="${dirPath}"`);
72
+ return { success: true, packageManager, scriptName, command, needsInstall, resolvedDir: dirPath };
73
+ }
74
+ /**
75
+ * Scan immediate subdirectories for a package.json with a dev script.
76
+ * Skips hidden dirs, node_modules, and common non-project directories.
77
+ */
78
+ function scanSubdirectories(dirPath) {
79
+ const SKIP_DIRS = new Set(['node_modules', '.git', '.next', 'dist', 'build', 'out', '.cache']);
80
+ let entries;
81
+ try {
82
+ entries = readdirSync(dirPath);
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ for (const entry of entries) {
88
+ if (entry.startsWith('.') || SKIP_DIRS.has(entry))
89
+ continue;
90
+ const subPath = join(dirPath, entry);
91
+ try {
92
+ if (!statSync(subPath).isDirectory())
93
+ continue;
94
+ }
95
+ catch {
96
+ continue;
97
+ }
98
+ const result = detectDevScriptInDir(subPath);
99
+ if (result.success) {
100
+ log.info(`found dev script in subdirectory "${entry}" — resolvedDir="${subPath}"`);
101
+ return result;
102
+ }
103
+ }
104
+ return null;
56
105
  }
57
106
  /**
58
107
  * Detect the package manager by checking for lockfile presence.
@@ -1 +1 @@
1
- {"version":3,"file":"git-fork.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-fork.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0EAA0E,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0EAA0E,CAAC;AAKjH,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,qBACa,cAAe,YAAW,eAAe;IAChB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0C1C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatD,gBAAgB,CACpB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC;IAiDtB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsBpF;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAU3B"}
1
+ {"version":3,"file":"git-fork.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-fork.service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0EAA0E,CAAC;AAChH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0EAA0E,CAAC;AAKjH,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,qBACa,cAAe,YAAW,eAAe;IAChB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0C1C,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatD,gBAAgB,CACpB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC;IAkDtB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsBpF;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAU3B"}
@@ -20,6 +20,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
20
20
  import { injectable, inject } from 'tsyringe';
21
21
  import { GitForkError, GitForkErrorCode, } from '../../../application/ports/output/services/git-fork-service.interface.js';
22
22
  import { PrStatus } from '../../../domain/generated/output.js';
23
+ import { applyPrBranding } from './pr-branding.js';
23
24
  let GitForkService = class GitForkService {
24
25
  execFile;
25
26
  constructor(execFile) {
@@ -80,6 +81,7 @@ let GitForkService = class GitForkService {
80
81
  });
81
82
  const forkRepo = this.extractRepoFromUrl(forkUrl.trim());
82
83
  const forkOwner = forkRepo.split('/')[0];
84
+ const brandedBody = applyPrBranding(body);
83
85
  const { stdout } = await this.execFile('gh', [
84
86
  'pr',
85
87
  'create',
@@ -88,7 +90,7 @@ let GitForkService = class GitForkService {
88
90
  '--title',
89
91
  title,
90
92
  '--body',
91
- body,
93
+ brandedBody,
92
94
  '--head',
93
95
  `${forkOwner}:${head}`,
94
96
  '--base',
@@ -1 +1 @@
1
- {"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-pr.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/git-pr.service.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ import { readFileSync, writeFileSync, unlinkSync } from 'node:fs';
22
22
  import { tmpdir } from 'node:os';
23
23
  import { join } from 'node:path';
24
24
  import yaml from 'js-yaml';
25
+ import { applyPrBranding } from './pr-branding.js';
25
26
  let GitPrService = class GitPrService {
26
27
  execFile;
27
28
  constructor(execFile) {
@@ -161,7 +162,7 @@ let GitPrService = class GitPrService {
161
162
  const prYamlContent = readFileSync(prYamlPath, 'utf-8');
162
163
  const prData = yaml.load(prYamlContent);
163
164
  const title = prData.title ?? 'Untitled PR';
164
- const body = prData.body ?? '';
165
+ const body = applyPrBranding(prData.body ?? '');
165
166
  const args = ['pr', 'create', '--title', title, '--body', body];
166
167
  if (prData.baseBranch) {
167
168
  args.push('--base', prData.baseBranch);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * PR Branding
3
+ *
4
+ * Centralizes the branding footer used in pull request bodies
5
+ * created by Shep. Ensures consistent attribution across all
6
+ * PR creation paths (agent-driven, fork-and-PR, etc.).
7
+ */
8
+ /** The branding line to append to PR bodies. */
9
+ export declare const PR_BRANDING = "Built with Shep \uD83D\uDC11 [Shep Bot](https://github.com/shep-ai/cli)";
10
+ /**
11
+ * Ensure a PR body carries the correct Shep branding.
12
+ *
13
+ * 1. Strips any unwanted AI-tool attribution footers
14
+ * 2. Appends the Shep branding line if not already present
15
+ */
16
+ export declare function applyPrBranding(body: string): string;
17
+ //# sourceMappingURL=pr-branding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-branding.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/git/pr-branding.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gDAAgD;AAChD,eAAO,MAAM,WAAW,4EACmD,CAAC;AAS5E;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAapD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * PR Branding
3
+ *
4
+ * Centralizes the branding footer used in pull request bodies
5
+ * created by Shep. Ensures consistent attribution across all
6
+ * PR creation paths (agent-driven, fork-and-PR, etc.).
7
+ */
8
+ /** The branding line to append to PR bodies. */
9
+ export const PR_BRANDING = 'Built with Shep \uD83D\uDC11 [Shep Bot](https://github.com/shep-ai/cli)';
10
+ /**
11
+ * Pattern matching common AI-tool attribution footers that should be
12
+ * replaced (e.g. "Generated with Claude Code", "Co-Authored-By: Claude").
13
+ */
14
+ const UNWANTED_BRANDING_PATTERN = /\n*(?:🤖\s*)?Generated with \[Claude Code\]\(https:\/\/claude\.com\/claude-code\)\s*/gi;
15
+ /**
16
+ * Ensure a PR body carries the correct Shep branding.
17
+ *
18
+ * 1. Strips any unwanted AI-tool attribution footers
19
+ * 2. Appends the Shep branding line if not already present
20
+ */
21
+ export function applyPrBranding(body) {
22
+ // Strip unwanted branding
23
+ let cleaned = body.replace(UNWANTED_BRANDING_PATTERN, '');
24
+ // Trim trailing whitespace/newlines before appending branding
25
+ cleaned = cleaned.trimEnd();
26
+ // Only append if not already present
27
+ if (!cleaned.includes(PR_BRANDING)) {
28
+ cleaned = `${cleaned}\n\n${PR_BRANDING}`;
29
+ }
30
+ return cleaned;
31
+ }