rvlib-shipkit 1.3.0 → 1.5.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.
Files changed (203) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +17 -17
  3. package/package.json +3 -2
  4. package/src/asks/asks-queue.ts +4 -2
  5. package/src/assets/kits/identity-kit.ts +15 -13
  6. package/src/assets/run-assets.ts +12 -2
  7. package/src/check.ts +73 -98
  8. package/src/checks/SK001-package-json-shape.check.ts +26 -4
  9. package/src/checks/SK002-contracts-fulfillness.check.ts +4 -0
  10. package/src/checks/SK003-claude-md-shape.check.ts +5 -1
  11. package/src/checks/SK004-gitignore-policy.check.ts +7 -4
  12. package/src/checks/SK005-rvlib-versions.check.ts +53 -21
  13. package/src/checks/SK006-npm-publish-safety.check.ts +4 -0
  14. package/src/checks/SK007-github-visibility.check.ts +4 -2
  15. package/src/checks/SK008-reviewer-agent.check.ts +6 -4
  16. package/src/checks/SK009-commit-ai-tells.check.ts +94 -74
  17. package/src/checks/SK010-undeclared-unit.check.ts +4 -0
  18. package/src/checks/SK011-sibling-unit-ranges.check.ts +4 -0
  19. package/src/checks/SK012-config-barrel-import.check.ts +5 -1
  20. package/src/checks/SK013-one-way-in-policy.check.ts +7 -3
  21. package/src/checks/SK014-prose-ste.check.ts +20 -6
  22. package/src/checks/SK015-nested-repo.check.ts +4 -2
  23. package/src/checks/SK016-legacy-check-shapes.check.ts +23 -16
  24. package/src/checks/SK017-vscode-hub-task.check.ts +22 -7
  25. package/src/checks/SK018-test-files-run.check.ts +6 -2
  26. package/src/checks/SK019-tests-run-in-units.check.ts +8 -4
  27. package/src/checks/SK020-self-spawning-check.check.ts +4 -0
  28. package/src/checks/SK022-machine-runs-the-pin.check.ts +6 -4
  29. package/src/checks/SK024-identity-colors.check.ts +5 -3
  30. package/src/checks/SK025-release-drift.check.ts +4 -5
  31. package/src/checks/SK026-asks-autoclose.check.ts +4 -4
  32. package/src/checks/SK027-agent-wiki-links.check.ts +34 -9
  33. package/src/checks/SK028-readme.check.ts +10 -2
  34. package/src/checks/SK029-explicit-check-files.check.ts +95 -0
  35. package/src/cli/cmd_Asks.ts +5 -5
  36. package/src/cli/cmd_Assets.ts +7 -7
  37. package/src/cli/cmd_Bump.ts +12 -11
  38. package/src/cli/cmd_Check.ts +8 -7
  39. package/src/cli/cmd_Checks.ts +7 -6
  40. package/src/cli/cmd_Ci.ts +12 -11
  41. package/src/cli/cmd_Commands.ts +16 -13
  42. package/src/cli/cmd_ConfigKeys.ts +7 -6
  43. package/src/cli/cmd_Contracts.ts +3 -3
  44. package/src/cli/cmd_CrossRepoActivity.ts +10 -6
  45. package/src/cli/cmd_Fleet.ts +9 -7
  46. package/src/cli/cmd_GlobalProcesses.ts +116 -4
  47. package/src/cli/cmd_Home.ts +23 -17
  48. package/src/cli/cmd_Hooks.ts +6 -5
  49. package/src/cli/cmd_Init.ts +5 -4
  50. package/src/cli/cmd_Keys.ts +8 -7
  51. package/src/cli/cmd_Mv.ts +7 -6
  52. package/src/cli/cmd_Needs.ts +4 -3
  53. package/src/cli/cmd_Overview.ts +4 -3
  54. package/src/cli/cmd_Pb.ts +2 -2
  55. package/src/cli/cmd_Planned.ts +6 -5
  56. package/src/cli/cmd_Prose.ts +5 -5
  57. package/src/cli/cmd_Reflect.ts +7 -7
  58. package/src/cli/cmd_Release.ts +6 -5
  59. package/src/cli/cmd_Releases.ts +5 -4
  60. package/src/cli/cmd_Serve.ts +4 -3
  61. package/src/cli/cmd_Smoke.ts +5 -4
  62. package/src/cli/cmd_Start.ts +7 -6
  63. package/src/cli/cmd_Status.ts +4 -3
  64. package/src/cli/cmd_Tui.ts +3 -2
  65. package/src/cli/cmd_When.ts +71 -0
  66. package/src/cli/cmd_Wiki.ts +4 -4
  67. package/src/cli.ts +7 -2
  68. package/src/collections/checks.ts +2 -0
  69. package/src/collections/collection-types.ts +24 -4
  70. package/src/collections/providers.ts +6 -2
  71. package/src/contracts/apply-contracts.ts +9 -8
  72. package/src/contracts/contract-types.ts +8 -2
  73. package/src/contracts/contracts-engine.ts +34 -13
  74. package/src/contracts/manifests/identity.contract.ts +6 -5
  75. package/src/contracts/manifests/social.contract.ts +4 -2
  76. package/src/contracts/manifests/steam.contract.ts +7 -3
  77. package/src/contracts/web-surface.ts +59 -0
  78. package/src/core/budget.ts +19 -9
  79. package/src/core/canonical-scripts.ts +1 -1
  80. package/src/core/check-runner.ts +63 -25
  81. package/src/core/config-rewrite.ts +37 -24
  82. package/src/core/discover-checks.ts +31 -7
  83. package/src/core/layout.ts +2 -0
  84. package/src/core/legacy-shapes.ts +39 -10
  85. package/src/core/motherhome.ts +88 -66
  86. package/src/core/one-way-in-policy.ts +2 -2
  87. package/src/core/outcome-words.ts +18 -2
  88. package/src/core/port-check-cli.ts +52 -0
  89. package/src/core/port-check-file.ts +295 -0
  90. package/src/core/port-check-files.ts +31 -0
  91. package/src/core/retention.ts +0 -14
  92. package/src/core/run-check.ts +14 -14
  93. package/src/core/run-ci.ts +11 -7
  94. package/src/core/run-fix.ts +30 -23
  95. package/src/core/run-fixers.ts +42 -5
  96. package/src/core/runs-matrix.ts +179 -0
  97. package/src/core/runs.ts +242 -0
  98. package/src/core/update-policy.ts +20 -0
  99. package/src/core/when-block.ts +29 -30
  100. package/src/core/when.ts +41 -103
  101. package/src/core/wire.ts +34 -9
  102. package/src/fleet/scan-fleet.ts +20 -4
  103. package/src/fleet/update-fleet.ts +6 -6
  104. package/src/home/activity-shape.ts +4 -1
  105. package/src/home/activity.ts +22 -15
  106. package/src/home/gui-app/ShipkitGui.swift +144 -25
  107. package/src/home/gui-app.ts +93 -30
  108. package/src/home/home-launchd.ts +30 -6
  109. package/src/home/home-routes.ts +14 -2
  110. package/src/home/home-start.ts +33 -5
  111. package/src/home/hubs.ts +5 -5
  112. package/src/home/machine-stores.ts +4 -2
  113. package/src/home/open-app.ts +23 -10
  114. package/src/home/pm-config.ts +15 -11
  115. package/src/home/pm-inputs.ts +76 -0
  116. package/src/home/pm.ts +11 -3
  117. package/src/home/process-rows.ts +23 -6
  118. package/src/home/resources.ts +67 -15
  119. package/src/home/run-daemon.ts +6 -1
  120. package/src/home/run-pm.ts +30 -5
  121. package/src/home/serve-web.ts +2 -2
  122. package/src/home/supervise.ts +24 -1
  123. package/src/home/widgets.ts +32 -3
  124. package/src/hooks/commit-message.ts +2 -3
  125. package/src/hooks/run-hooks.ts +60 -6
  126. package/src/init-repo.ts +6 -6
  127. package/src/ledger/gate-checks.ts +115 -61
  128. package/src/ledger/git-key.ts +5 -1
  129. package/src/ledger/ledger.ts +5 -5
  130. package/src/ledger/store.ts +11 -0
  131. package/src/ledger/toolchain-identity.ts +45 -27
  132. package/src/ledger/world-cache.ts +17 -15
  133. package/src/plan/repo-source.ts +18 -39
  134. package/src/release/run-release.ts +5 -0
  135. package/src/repo-config.ts +36 -56
  136. package/src/rules/rule.ts +2 -2
  137. package/src/scaffold/files/agent-coding.md +1 -1
  138. package/src/scaffold/files/agent-index.md +1 -1
  139. package/src/scaffold/files/verify-skill.md +2 -2
  140. package/src/serve/hub-app/activity-st.ts +5 -4
  141. package/src/serve/hub-app/activity-view.tsx +4 -4
  142. package/src/serve/hub-app/admin-view.tsx +13 -11
  143. package/src/serve/hub-app/check-view.tsx +66 -46
  144. package/src/serve/hub-app/check-words.ts +1 -11
  145. package/src/serve/hub-app/checks-svc.ts +16 -36
  146. package/src/serve/hub-app/col-tables-view.tsx +131 -0
  147. package/src/serve/hub-app/col-tables.ts +115 -0
  148. package/src/serve/hub-app/cols-svc.ts +33 -4
  149. package/src/serve/hub-app/dock-st.ts +3 -2
  150. package/src/serve/hub-app/dock-view.tsx +36 -0
  151. package/src/serve/hub-app/dock.css +7 -1
  152. package/src/serve/hub-app/float-cards.tsx +30 -0
  153. package/src/serve/hub-app/floating.tsx +41 -4
  154. package/src/serve/hub-app/git-st.ts +42 -0
  155. package/src/serve/hub-app/git-view.tsx +61 -0
  156. package/src/serve/hub-app/hash-route.ts +45 -1
  157. package/src/serve/hub-app/header-bar.tsx +62 -72
  158. package/src/serve/hub-app/health-svc.ts +3 -2
  159. package/src/serve/hub-app/home-st.ts +15 -3
  160. package/src/serve/hub-app/home-strip.css +69 -19
  161. package/src/serve/hub-app/home-strip.tsx +192 -118
  162. package/src/serve/hub-app/home.html +1 -0
  163. package/src/serve/hub-app/hub-app.tsx +21 -5
  164. package/src/serve/hub-app/hub-types.ts +11 -5
  165. package/src/serve/hub-app/hub.css +88 -44
  166. package/src/serve/hub-app/icons.tsx +15 -0
  167. package/src/serve/hub-app/index.html +1 -0
  168. package/src/serve/hub-app/keys.ts +11 -8
  169. package/src/serve/hub-app/live-svc.ts +3 -2
  170. package/src/serve/hub-app/machine-st.ts +34 -49
  171. package/src/serve/hub-app/palette-st.ts +5 -5
  172. package/src/serve/hub-app/palette-view.tsx +1 -1
  173. package/src/serve/hub-app/plan-view.tsx +51 -0
  174. package/src/serve/hub-app/planned-st.ts +9 -4
  175. package/src/serve/hub-app/processes-view.tsx +38 -0
  176. package/src/serve/hub-app/project-list.tsx +3 -3
  177. package/src/serve/hub-app/projects-svc.ts +15 -10
  178. package/src/serve/hub-app/prose-hits-st.ts +3 -2
  179. package/src/serve/hub-app/reach.ts +36 -0
  180. package/src/serve/hub-app/readme-svc.ts +3 -2
  181. package/src/serve/hub-app/repo-sections.ts +117 -0
  182. package/src/serve/hub-app/repo-st.ts +47 -10
  183. package/src/serve/hub-app/runs-tabs.ts +1 -1
  184. package/src/serve/hub-app/sidebar.tsx +12 -37
  185. package/src/serve/hub-app/timeline-svc.ts +3 -2
  186. package/src/serve/hub-app/timeline-view.tsx +14 -11
  187. package/src/serve/hub-app/tree-build.ts +149 -155
  188. package/src/serve/hub-app/tree-row.tsx +39 -9
  189. package/src/serve/hub-app/tree-svc.ts +70 -49
  190. package/src/serve/hub-app/when-view.tsx +89 -0
  191. package/src/serve/hub-app/when.css +17 -0
  192. package/src/serve/hub-runtime.ts +3 -16
  193. package/src/serve/project-gutter.ts +1 -2
  194. package/src/serve/run-serve.ts +1 -1
  195. package/src/serve/serve-hub.ts +4 -14
  196. package/src/serve/warm-cell.ts +49 -16
  197. package/src/suite/judge-suites.ts +42 -17
  198. package/src/suite/suite-cli.ts +5 -8
  199. package/src/wiki/lint-md.ts +2 -0
  200. package/src/wiki/scan-md.ts +37 -10
  201. package/src/serve/hub-app/processes-svc.ts +0 -63
  202. package/src/serve/hub-app/repo-sections.tsx +0 -61
  203. package/src/serve/repo-processes.ts +0 -89
@@ -14,11 +14,11 @@ export class FleetCommand extends Command {
14
14
  category: 'Health',
15
15
  description: 'every repo on this disk that installs the toolkit, and how far behind each one is',
16
16
  examples: [
17
- ['what is stale out there', 'shipkit fleet'],
18
- ['filesystem only, no registry', 'shipkit fleet --offline'],
19
- ['bring every behind repo up, through its own gate', 'shipkit fleet --update'],
20
- ['one repo only', 'shipkit fleet --update --only my-app'],
21
- ['machine-readable', 'shipkit fleet --json'],
17
+ ['what is stale out there', 'sk fleet'],
18
+ ['filesystem only, no registry', 'sk fleet --offline'],
19
+ ['bring every behind repo up, through its own gate', 'sk fleet --update'],
20
+ ['one repo only', 'sk fleet --update --only my-app'],
21
+ ['machine-readable', 'sk fleet --json'],
22
22
  ],
23
23
  })
24
24
 
@@ -66,10 +66,12 @@ export class FleetCommand extends Command {
66
66
  private row(r: FleetRepo): string {
67
67
  const cells = r.deps.map((d) => {
68
68
  if (d.pin.startsWith('link:') || d.pin.startsWith('file:')) return `${short(d.name)}=source`
69
- const at = d.installed ?? 'absent'
69
+ // a linked dep reads as its pin: the source it links is always newest
70
+ const at = d.linkedInstall ? `pin ${d.at ?? d.pin}` : (d.installed ?? 'absent')
71
+ const tag = d.linkedInstall ? ' (linked)' : ''
70
72
  const stale = r.behind.some((b) => b.name === d.name)
71
73
  const breaks = r.breaking.some((b) => b.name === d.name)
72
- return stale ? `${short(d.name)} ${at} → ${d.latest}${breaks ? ' BREAKING' : ''}` : `${short(d.name)} ${at}`
74
+ return stale ? `${short(d.name)} ${at} → ${d.latest}${breaks ? ' BREAKING' : ''}${d.linkedInstall ? ' (linked, stale pin)' : ''}` : `${short(d.name)} ${at}${tag}`
73
75
  })
74
76
  const flag = r.linked ? 'source' : r.breaking.length > 0 ? `${r.breaking.length} BREAKING` : r.behind.length > 0 ? `${r.behind.length} behind` : 'current'
75
77
  return ` ${r.name.padEnd(24)} ${flag.padEnd(10)} ${cells.join(', ')}`
@@ -9,6 +9,7 @@ import { Command, Option } from 'clipanion'
9
9
  import { daemonPort, daemonUrl, homePort, pmPort, pmUrl } from '../home/home-paths.ts'
10
10
  import { houseRootOf } from '../home/home-start.ts'
11
11
  import type { PmAnswer } from '../home/pm.ts'
12
+ import type { ResourceView } from '../home/resources.ts'
12
13
  import { coreGroup, declaredRow, groupRows, processGroups, stateWords, type ProcessGroup } from '../home/process-rows.ts'
13
14
  import type { PmConfig } from '../home/pm-config.ts'
14
15
  import { readPmConfig } from '../home/run-pm.ts'
@@ -133,11 +134,12 @@ export class GlobalProcessesCommand extends Command {
133
134
 
134
135
  static override usage = Command.Usage({
135
136
  category: 'Home',
136
- description: 'every process on the machine and its state, as the overview shows them: shipkit\'s own (pm, the daemon, the web, with their version) first, then per repo, one line per global process with its state, url, pid and last log line. When pm is down, the declared ones with their state unknown. Always exits 0',
137
+ description: 'every process on the machine and its state, as the overview shows it',
138
+ details: 'every process on the machine and its state, as the overview shows them: shipkit\'s own (pm, the daemon, the web, with their version) first, then per repo, one line per global process with its state, url, pid and last log line. When pm is down, the declared ones with their state unknown. Always exits 0',
137
139
  examples: [
138
- ['the table', 'shipkit global-processes'],
139
- ['the same, short', 'shipkit gp'],
140
- ['the rows the overview draws, as json', 'shipkit global-processes --json'],
140
+ ['the table', 'sk global-processes'],
141
+ ['the same, short', 'sk gp'],
142
+ ['the rows the overview draws, as json', 'sk global-processes --json'],
141
143
  ],
142
144
  })
143
145
 
@@ -153,3 +155,113 @@ export class GlobalProcessesCommand extends Command {
153
155
  return 0
154
156
  }
155
157
  }
158
+
159
+ export type SwitchAct = 'start' | 'stop' | 'restart'
160
+
161
+ export type SwitchDeps = {
162
+ /** pm's answer to the switch: null when it took it, else why not */
163
+ post: (id: string, act: SwitchAct) => Promise<string | null>
164
+ /** the process as pm sees it now, null when pm does not answer */
165
+ view: (id: string) => Promise<ResourceView | null>
166
+ sleep: (ms: number) => Promise<void>
167
+ now: () => number
168
+ log: (line: string) => void
169
+ }
170
+
171
+ /** the longest a switch is followed: a bring-up polls its health for minutes */
172
+ export const SWITCH_WAIT_MS = 10 * 60_000
173
+ const SWITCH_POLL_MS = 1_000
174
+
175
+ /** flip a global process through pm, then follow pm's state until its probe
176
+ * settles it: 0 once it is up (or down for stop), 1 otherwise. The launcher's
177
+ * exit code proves nothing, pm's probe does */
178
+ export async function switchProcess(id: string, act: SwitchAct, d: SwitchDeps, waitMs = SWITCH_WAIT_MS): Promise<number> {
179
+ const refused = await d.post(id, act)
180
+ if (refused != null) {
181
+ d.log(`FAIL ${act} ${id}: ${refused}`)
182
+ return 1
183
+ }
184
+ const want = act === 'stop' ? 'down' : 'up'
185
+ const end = d.now() + waitMs
186
+ let said = ''
187
+ for (;;) {
188
+ const v = await d.view(id)
189
+ if (v == null) {
190
+ d.log(`FAIL pm stopped answering while ${id} was switched ${want}: shipkit gp`)
191
+ return 1
192
+ }
193
+ if (v.status !== said) {
194
+ said = v.status
195
+ d.log(`${id}: ${v.status}`)
196
+ }
197
+ const moving = v.status === 'starting' || v.status === 'stopping' || v.want !== want
198
+ if (!moving) {
199
+ if (v.status === want) return 0
200
+ d.log(`FAIL ${id} is ${v.status}, not ${want}${v.note == null ? '' : `: ${v.note}`}`)
201
+ for (const l of v.tail.slice(-10)) d.log(` log: ${l}`)
202
+ return 1
203
+ }
204
+ if (d.now() >= end) {
205
+ d.log(`FAIL ${id} still ${v.status} after ${Math.round(waitMs / 1000)}s: shipkit gp shows where it stands`)
206
+ return 1
207
+ }
208
+ await d.sleep(SWITCH_POLL_MS)
209
+ }
210
+ }
211
+
212
+ /** the switch against the running pm */
213
+ export const pmSwitchDeps = (log: (line: string) => void, url = pmUrl()): SwitchDeps => ({
214
+ post: async (id, act) => {
215
+ try {
216
+ const r = await fetch(`${url}/api/pm/resource`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ id, act }), signal: AbortSignal.timeout(5_000) })
217
+ return r.ok ? null : await r.text()
218
+ } catch (e) {
219
+ return `pm does not answer on ${url} (${(e as Error).message}): shipkit pm install`
220
+ }
221
+ },
222
+ view: async (id) => (await askPm(url))?.resources.find((r) => r.id === id) ?? null,
223
+ sleep: (ms) => Bun.sleep(ms),
224
+ now: () => Date.now(),
225
+ log,
226
+ })
227
+
228
+ abstract class SwitchCommand extends Command {
229
+ abstract readonly act: SwitchAct
230
+ id = Option.String({ required: true, name: 'id' })
231
+
232
+ async execute(): Promise<number> {
233
+ return switchProcess(this.id, this.act, pmSwitchDeps((l) => this.context.stdout.write(`${l}\n`)))
234
+ }
235
+ }
236
+
237
+ export class GlobalProcessStartCommand extends SwitchCommand {
238
+ readonly act = 'start'
239
+ static override paths = [['global-processes', 'start'], ['gp', 'start']]
240
+ static override usage = Command.Usage({
241
+ category: 'Home',
242
+ description: 'start a global process through pm, wait until its probe answers',
243
+ details: 'start a global process through pm, the same switch as the overview\'s play, and wait until its probe answers. Exit 0 once it is up, 1 when it crashed, stayed down or pm refused',
244
+ examples: [['start ComfyUI on the GPU box', 'sk gp start comfyui']],
245
+ })
246
+ }
247
+
248
+ export class GlobalProcessStopCommand extends SwitchCommand {
249
+ readonly act = 'stop'
250
+ static override paths = [['global-processes', 'stop'], ['gp', 'stop']]
251
+ static override usage = Command.Usage({
252
+ category: 'Home',
253
+ description: 'stop a global process through pm, wait until it is down',
254
+ details: 'stop a global process through pm, the same switch as the overview\'s stop, and wait until its probe no longer answers. Exit 0 once it is down',
255
+ examples: [['stop ComfyUI', 'sk gp stop comfyui']],
256
+ })
257
+ }
258
+
259
+ export class GlobalProcessRestartCommand extends SwitchCommand {
260
+ readonly act = 'restart'
261
+ static override paths = [['global-processes', 'restart'], ['gp', 'restart']]
262
+ static override usage = Command.Usage({
263
+ category: 'Home',
264
+ description: 'restart a global process through pm and wait until its probe answers again. Exit 0 once it is up',
265
+ examples: [['restart ComfyUI, so it rescans its models', 'sk gp restart comfyui']],
266
+ })
267
+ }
@@ -35,10 +35,11 @@ export class PmCommand extends Command {
35
35
 
36
36
  static override usage = Command.Usage({
37
37
  category: 'Serve',
38
- description: 'the machine\'s process manager: runs `shipkit daemon` and `shipkit web` as detached children, starts one again when it dies, owns the global processes every house repo declares in its .shipkit.ts files, and serves its api on port 4797 (SHIPKIT_PM_PORT). A pm restarted or killed leaves its children running and the next one adopts them. Run from the repo that hosts the house wiki',
38
+ description: 'the machine\'s process manager: runs the daemon, the web and every global process',
39
+ details: 'the machine\'s process manager: runs `shipkit daemon` and `shipkit web` as detached children, starts one again when it dies, owns the global processes every house repo declares in its .shipkit.ts files, and serves its api on port 4797 (SHIPKIT_PM_PORT). A pm restarted or killed leaves its children running and the next one adopts them. Run from the repo that hosts the house wiki',
39
40
  examples: [
40
- ['run pm in this terminal', 'shipkit pm'],
41
- ['on test ports', 'SHIPKIT_PM_PORT=4887 SHIPKIT_HOME_PORT=4889 SHIPKIT_DAEMON_PORT=4888 SHIPKIT_HOME_DIR=/tmp/home shipkit pm'],
41
+ ['run pm in this terminal', 'sk pm'],
42
+ ['on test ports', 'SHIPKIT_PM_PORT=4887 SHIPKIT_HOME_PORT=4889 SHIPKIT_DAEMON_PORT=4888 SHIPKIT_HOME_DIR=/tmp/home sk pm'],
42
43
  ],
43
44
  })
44
45
 
@@ -57,10 +58,11 @@ export class DaemonCommand extends Command {
57
58
 
58
59
  static override usage = Command.Usage({
59
60
  category: 'Serve',
60
- description: 'the home\'s daemon: loads every house repo hub in this one process and serves their api, their run streams and the home api under /r/<repo>/ on an internal port. No page: `shipkit web` serves it. Run from the repo that hosts the house wiki',
61
+ description: 'the home daemon: every house repo\'s hub in one process',
62
+ details: 'the home\'s daemon: loads every house repo hub in this one process and serves their api, their run streams and the home api under /r/<repo>/ on an internal port. No page: `shipkit web` serves it. Run from the repo that hosts the house wiki',
61
63
  examples: [
62
- ['the daemon alone', 'shipkit daemon'],
63
- ['on another port', 'shipkit daemon --port 4888'],
64
+ ['the daemon alone', 'sk daemon'],
65
+ ['on another port', 'sk daemon --port 4888'],
64
66
  ],
65
67
  })
66
68
 
@@ -78,10 +80,11 @@ export class WebCommand extends Command {
78
80
 
79
81
  static override usage = Command.Usage({
80
82
  category: 'Serve',
81
- description: 'the home\'s page: one server on the home port that serves the page and proxies every api request to the daemon, so a browser only sees this origin. It loads no repo',
83
+ description: 'the home page server: serves the page, proxies the api to the daemon',
84
+ details: 'the home\'s page: one server on the home port that serves the page and proxies every api request to the daemon, so a browser only sees this origin. It loads no repo',
82
85
  examples: [
83
- ['the page alone', 'shipkit web'],
84
- ['on another port', 'shipkit web --port 4889'],
86
+ ['the page alone', 'sk web'],
87
+ ['on another port', 'sk web --port 4889'],
85
88
  ],
86
89
  })
87
90
 
@@ -99,8 +102,9 @@ export class PmInstallCommand extends Command {
99
102
 
100
103
  static override usage = Command.Usage({
101
104
  category: 'Serve',
102
- description: 'keep pm running, and through it the daemon and the web: a macOS LaunchAgent starts it now and at every login, and restarts it when it dies. Idempotent',
103
- examples: [['install from the house repo', 'shipkit pm install']],
105
+ description: 'keep pm running at every login through a macOS LaunchAgent',
106
+ details: 'keep pm running, and through it the daemon and the web: a macOS LaunchAgent starts it now and at every login, and restarts it when it dies. Idempotent',
107
+ examples: [['install from the house repo', 'sk pm install']],
104
108
  })
105
109
 
106
110
  async execute(): Promise<number> {
@@ -114,8 +118,9 @@ export class PmUninstallCommand extends Command {
114
118
 
115
119
  static override usage = Command.Usage({
116
120
  category: 'Serve',
117
- description: 'stop pm, the daemon and the web, and remove the LaunchAgent. The resources and repo processes keep running. No later command starts pm on its own until `shipkit pm install`',
118
- examples: [['remove the agent', 'shipkit pm uninstall']],
121
+ description: 'stop pm, the daemon and the web, and remove the LaunchAgent',
122
+ details: 'stop pm, the daemon and the web, and remove the LaunchAgent. The resources and repo processes keep running. No later command starts pm on its own until `shipkit pm install`',
123
+ examples: [['remove the agent', 'sk pm uninstall']],
119
124
  })
120
125
 
121
126
  async execute(): Promise<number> {
@@ -130,11 +135,12 @@ export class GuiCommand extends Command {
130
135
 
131
136
  static override usage = Command.Usage({
132
137
  category: 'Serve',
133
- description: 'open the home in its own window, outside VS Code and the browser, starting pm first when the web does not answer (and installing its LaunchAgent the first time). Every call opens one more window',
138
+ description: 'open the home in its own window',
139
+ details: 'open the home in its own window, outside VS Code and the browser, starting pm first when the web does not answer (and installing its LaunchAgent the first time). Every call opens one more window',
134
140
  examples: [
135
- ['a window on the home', 'shipkit gui'],
136
- ['a window on one repo', 'shipkit gui my-app'],
137
- ['a window on the repo you stand in', 'shipkit gui .'],
141
+ ['a window on the home', 'sk gui'],
142
+ ['a window on one repo', 'sk gui my-app'],
143
+ ['a window on the repo you stand in', 'sk gui .'],
138
144
  ],
139
145
  })
140
146
 
@@ -1,7 +1,7 @@
1
1
  // shipkit hooks, install the git hooks, run their gates, or list what
2
2
  // blocks a commit. Thin clipanion surface; logic in hooks/run-hooks.ts.
3
3
  import { Command, Option } from 'clipanion'
4
- import { hookBinInvocation, installHooks, listGates, runCommitMsg, runPreCommit, type GateOutcome } from '../hooks/run-hooks.ts'
4
+ import { hookBinInvocation, installHooks, listGates, preCommitChecks, runCommitMsg, runPreCommit, type GateOutcome } from '../hooks/run-hooks.ts'
5
5
  import { loadRepoConfig } from '../repo-config.ts'
6
6
 
7
7
  const report = (out: GateOutcome[], write: (s: string) => void): number => {
@@ -13,8 +13,9 @@ export class HooksInstallCommand extends Command {
13
13
  static override paths = [['hooks', 'install']]
14
14
  static override usage = Command.Usage({
15
15
  category: 'Gate',
16
- description: 'write .shipkit/hooks/pre-commit + .shipkit/hooks/commit-msg and point core.hooksPath at them (idempotent)',
17
- examples: [['wire the hooks', 'shipkit hooks install']],
16
+ description: 'write the pre-commit and commit-msg hooks and point core.hooksPath at them',
17
+ details: 'write .shipkit/hooks/pre-commit + .shipkit/hooks/commit-msg and point core.hooksPath at them (idempotent)',
18
+ examples: [['wire the hooks', 'sk hooks install']],
18
19
  })
19
20
 
20
21
  bin = Option.String('--bin', { description: 'how the hook body invokes shipkit (default: the repo\'s own node_modules copy, else the running cli — in-repo consumers pass `bun <path to cli.ts>`)' })
@@ -56,12 +57,12 @@ export class HooksListCommand extends Command {
56
57
  static override usage = Command.Usage({
57
58
  category: 'Gate',
58
59
  description: 'what blocks a commit in this repo, built-ins and repo-declared',
59
- examples: [['list the gates', 'shipkit hooks list']],
60
+ examples: [['list the gates', 'sk hooks list']],
60
61
  })
61
62
 
62
63
  async execute(): Promise<number> {
63
64
  const config = await loadRepoConfig(process.cwd())
64
- for (const l of listGates(config, process.cwd())) this.context.stdout.write(`${l}\n`)
65
+ for (const l of listGates(config, process.cwd(), await preCommitChecks(process.cwd(), config))) this.context.stdout.write(`${l}\n`)
65
66
  return 0
66
67
  }
67
68
  }
@@ -8,11 +8,12 @@ export class InitCommand extends Command {
8
8
 
9
9
  static override usage = Command.Usage({
10
10
  category: 'Setup',
11
- description: 'wire THE CURRENT DIRECTORY as a shipkit repo, like git init: cwd only, never creates a project dir. scaffolds repo.config.ts + ci/check/contracts package.json scripts + the create-only .vscode/ that starts the watchers and the hub on folder open, prints how the floor resolved, and runs the bootstrap chain around it: git init, then first commit + PRIVATE github repo + push once the scaffold is in. Idempotent on an already-wired repo. To create or adopt ~/dev/<name> from anywhere: `shipkit start <name>`',
11
+ description: 'wire the current directory as a shipkit repo, like git init',
12
+ details: 'wire THE CURRENT DIRECTORY as a shipkit repo, like git init: cwd only, never creates a project dir. scaffolds repo.config.ts + ci/check/contracts package.json scripts + the create-only .vscode/ that starts the watchers and the hub on folder open, prints how the floor resolved, and runs the bootstrap chain around it: git init, then first commit + PRIVATE github repo + push once the scaffold is in. Idempotent on an already-wired repo. To create or adopt ~/dev/<name> from anywhere: `shipkit start <name>`',
12
13
  examples: [
13
- ['wire the repo you are standing in', 'shipkit init'],
14
- ['local git and the first commit, never touch github', 'shipkit init --no-github'],
15
- ['in-repo-source consumer: scripts run the CLI by path', 'shipkit init --bin wiki/build/shipkit/rvlib-shipkit/src/cli.ts'],
14
+ ['wire the repo you are standing in', 'sk init'],
15
+ ['local git and the first commit, never touch github', 'sk init --no-github'],
16
+ ['in-repo-source consumer: scripts run the CLI by path', 'sk init --bin wiki/build/shipkit/rvlib-shipkit/src/cli.ts'],
16
17
  ],
17
18
  })
18
19
 
@@ -19,14 +19,15 @@ export class KeysCommand extends Command {
19
19
 
20
20
  static override usage = Command.Usage({
21
21
  category: 'Health',
22
- description: 'the cache key of every gate check, and the reason the undeclared ones have none. Reports, never gates',
22
+ description: 'the cache key of every gate check, and why the others have none',
23
+ details: 'the cache key of every gate check, and the reason the undeclared ones have none. Reports, never gates',
23
24
  examples: [
24
- ['every check and its key', 'shipkit keys'],
25
- ['only the ones nothing can cache yet', 'shipkit keys --burn-down'],
26
- ['why this key is what it is', 'shipkit keys --why typecheck'],
27
- ['re-hash after the fact and report drift', 'shipkit keys --rescan'],
28
- ['the keys a --full gate asks for', 'shipkit keys --full'],
29
- ['machine-readable', 'shipkit keys --json'],
25
+ ['every check and its key', 'sk keys'],
26
+ ['only the ones nothing can cache yet', 'sk keys --burn-down'],
27
+ ['why this key is what it is', 'sk keys --why typecheck'],
28
+ ['re-hash after the fact and report drift', 'sk keys --rescan'],
29
+ ['the keys a --full gate asks for', 'sk keys --full'],
30
+ ['machine-readable', 'sk keys --json'],
30
31
  ],
31
32
  })
32
33
 
package/src/cli/cmd_Mv.ts CHANGED
@@ -12,13 +12,14 @@ export class MvCommand extends Command {
12
12
 
13
13
  static override usage = Command.Usage({
14
14
  category: 'Refactor',
15
- description: 'rename anything and sweep every reference: an md page (plus its sibling dir and its check file) or a code file or folder. Dry run by default. Renames must be CHEAP',
15
+ description: 'rename a file, folder or md page and rewrite every reference (dry run by default)',
16
+ details: 'rename anything and sweep every reference: an md page (plus its sibling dir and its check file) or a code file or folder. Dry run by default. Renames must be CHEAP',
16
17
  examples: [
17
- ['dry run, the default, shows what changes', 'shipkit mv docs/old-name.md docs/new-name.md'],
18
- ['apply it', 'shipkit mv docs/old-name.md docs/new-name.md --write'],
19
- ['apply + one conventional commit', 'shipkit mv docs/old-name.md docs/new-name.md --commit'],
20
- ['a code file, every import rewritten', 'shipkit mv src/old-mod.ts src/new-mod.ts --write'],
21
- ['a whole folder', 'shipkit mv src/old-dir src/new-dir --write'],
18
+ ['dry run, the default, shows what changes', 'sk mv docs/old-name.md docs/new-name.md'],
19
+ ['apply it', 'sk mv docs/old-name.md docs/new-name.md --write'],
20
+ ['apply + one conventional commit', 'sk mv docs/old-name.md docs/new-name.md --commit'],
21
+ ['a code file, every import rewritten', 'sk mv src/old-mod.ts src/new-mod.ts --write'],
22
+ ['a whole folder', 'sk mv src/old-dir src/new-dir --write'],
22
23
  ],
23
24
  })
24
25
 
@@ -12,10 +12,11 @@ export class NeedsCommand extends Command {
12
12
 
13
13
  static override usage = Command.Usage({
14
14
  category: 'Health',
15
- description: 'everything blocked on a human, red/yellow by collection — report-only, exit 0 always (check/ci are the gates)',
15
+ description: 'everything blocked on a human, by collection. Report only',
16
+ details: 'everything blocked on a human, red/yellow by collection — report-only, exit 0 always (check/ci are the gates)',
16
17
  examples: [
17
- ['what needs me', 'shipkit needs'],
18
- ['machine-readable (agents, drills, cross-repo rollups)', 'shipkit needs --json'],
18
+ ['what needs me', 'sk needs'],
19
+ ['machine-readable (agents, drills, cross-repo rollups)', 'sk needs --json'],
19
20
  ],
20
21
  })
21
22
 
@@ -77,10 +77,11 @@ export class OverviewCommand extends Command {
77
77
 
78
78
  static override usage = Command.Usage({
79
79
  category: 'Home',
80
- description: 'the overview page in the console: every monitor widget as text, from the html the daemon last rendered, then the processes as `shipkit gp` prints them (pm, the daemon and the web with pid, uptime and version, then every global process). When pm or the daemon does not answer, it says which and prints what is still known. Always exits 0',
80
+ description: 'the overview page as text: the widgets, then every process',
81
+ details: 'the overview page in the console: every monitor widget as text, from the html the daemon last rendered, then the processes as `shipkit gp` prints them (pm, the daemon and the web with pid, uptime and version, then every global process). When pm or the daemon does not answer, it says which and prints what is still known. Always exits 0',
81
82
  examples: [
82
- ['the overview', 'shipkit overview'],
83
- ['the answers the page reads, as json', 'shipkit overview --json'],
83
+ ['the overview', 'sk overview'],
84
+ ['the answers the page reads, as json', 'sk overview --json'],
84
85
  ],
85
86
  })
86
87
 
package/src/cli/cmd_Pb.ts CHANGED
@@ -10,8 +10,8 @@ export class PbCollectionCommand extends Command {
10
10
  category: 'Scaffold',
11
11
  description: "a collection's CRUD UI folder from the app's generated pb types: columns, card, grid, form, index",
12
12
  examples: [
13
- ['see the whole folder before it exists', 'shipkit pb collection orders --dry-run'],
14
- ['write src/collections/orders/', 'shipkit pb collection orders'],
13
+ ['see the whole folder before it exists', 'sk pb collection orders --dry-run'],
14
+ ['write src/collections/orders/', 'sk pb collection orders'],
15
15
  ],
16
16
  })
17
17
 
@@ -78,12 +78,13 @@ export class PlannedCommand extends Command {
78
78
 
79
79
  static override usage = Command.Usage({
80
80
  category: 'Home',
81
- description: 'the planned page in the console: every check the machine runs on its own time, running now, then next, each with its repo, check and title, when, the rule that planned it and its last result. Asks the daemon, which holds the plan. With the daemon down it says so and exits 0',
81
+ description: 'the plan as text: every check the machine runs on its own time',
82
+ details: 'the planned page in the console: every check the machine runs on its own time, running now, then next, each with its repo, check and title, when, the rule that planned it and its last result. Asks the daemon, which holds the plan. With the daemon down it says so and exits 0',
82
83
  examples: [
83
- ['the plan, as the page lists it', 'shipkit planned'],
84
- ['one repo only', 'shipkit planned --repo my-app'],
85
- ['also the checks that only a save runs', 'shipkit planned --all'],
86
- ['the route\'s exact payload', 'shipkit planned --json'],
84
+ ['the plan, as the page lists it', 'sk planned'],
85
+ ['one repo only', 'sk planned --repo my-app'],
86
+ ['also the checks that only a save runs', 'sk planned --all'],
87
+ ['the route\'s exact payload', 'sk planned --json'],
87
88
  ],
88
89
  })
89
90
 
@@ -13,11 +13,11 @@ export class ProseCommand extends Command {
13
13
  category: 'Health',
14
14
  description: 'STE prose check (identity/writing-voice.md): mechanical fixes, hard violations, soft warnings',
15
15
  examples: [
16
- ['every file this repo declares as prose', 'shipkit prose'],
17
- ['one file while drafting', 'shipkit prose wiki/build/shipkit.md'],
18
- ['apply every mechanical rewrite', 'shipkit prose --fix'],
19
- ['the procedural 20-word limit', 'shipkit prose --strict'],
20
- ['machine-readable', 'shipkit prose --json'],
16
+ ['every file this repo declares as prose', 'sk prose'],
17
+ ['one file while drafting', 'sk prose wiki/build/shipkit.md'],
18
+ ['apply every mechanical rewrite', 'sk prose --fix'],
19
+ ['the procedural 20-word limit', 'sk prose --strict'],
20
+ ['machine-readable', 'sk prose --json'],
21
21
  ],
22
22
  })
23
23
 
@@ -17,14 +17,14 @@ export class ReflectCommand extends Command {
17
17
 
18
18
  static override usage = Command.Usage({
19
19
  category: 'Health',
20
- description:
21
- "the user's typed prompts across every Claude Code session of a repo — chronological md corpus for retrospectives",
20
+ description: "the user's prompts across every Claude Code session of a repo, as a corpus",
21
+ details: "the user's typed prompts across every Claude Code session of a repo — chronological md corpus for retrospectives",
22
22
  examples: [
23
- ['corpus for the current repo', 'shipkit reflect'],
24
- ['corpus for other repos', 'shipkit reflect ~/dev/one-repo ~/dev/another-repo'],
25
- ['drop the long pastes', 'shipkit reflect --short'],
26
- ['batch to files instead of stdout', 'shipkit reflect ~/dev/a ~/dev/b --out stats'],
27
- ['machine-readable', 'shipkit reflect --json'],
23
+ ['corpus for the current repo', 'sk reflect'],
24
+ ['corpus for other repos', 'sk reflect ~/dev/one-repo ~/dev/another-repo'],
25
+ ['drop the long pastes', 'sk reflect --short'],
26
+ ['batch to files instead of stdout', 'sk reflect ~/dev/a ~/dev/b --out stats'],
27
+ ['machine-readable', 'sk reflect --json'],
28
28
  ],
29
29
  })
30
30
 
@@ -9,12 +9,13 @@ export class ReleaseCommand extends Command {
9
9
 
10
10
  static override usage = Command.Usage({
11
11
  category: 'Gate',
12
- description: 'cut a release for ONE unit (default the repo root): ci gate → npm publish (non-private only) → git tag → push → GitHub release, notes from that unit CHANGELOG section. Resumable after a partial failure, which is why it takes no --all.',
12
+ description: 'cut a release of one unit: gate, npm publish, tag, push, GitHub release',
13
+ details: 'cut a release for ONE unit (default the repo root): ci gate → npm publish (non-private only) → git tag → push → GitHub release, notes from that unit CHANGELOG section. Resumable after a partial failure, which is why it takes no --all.',
13
14
  examples: [
14
- ['rehearse — touches nothing', 'shipkit release --dry-run'],
15
- ['release the version in package.json', 'shipkit release'],
16
- ['finish a sub-unit bump stopped part way (ids: shipkit releases)', 'shipkit release rvlib-shipkit'],
17
- ['release with dirt elsewhere in the worktree', 'shipkit release --allow-dirty'],
15
+ ['rehearse — touches nothing', 'sk release --dry-run'],
16
+ ['release the version in package.json', 'sk release'],
17
+ ['finish a sub-unit bump stopped part way (ids: shipkit releases)', 'sk release rvlib-shipkit'],
18
+ ['release with dirt elsewhere in the worktree', 'sk release --allow-dirty'],
18
19
  ],
19
20
  })
20
21
 
@@ -9,11 +9,12 @@ export class ReleasesCommand extends Command {
9
9
 
10
10
  static override usage = Command.Usage({
11
11
  category: 'Gate',
12
- description: 'every unit that releases and where it stands: version, npm, tag local and remote, GitHub release, drift. Reports, never gates (only an unresolvable config exits non-zero)',
12
+ description: 'every release unit and where it stands: version, npm, tags, GitHub',
13
+ details: 'every unit that releases and where it stands: version, npm, tag local and remote, GitHub release, drift. Reports, never gates (only an unresolvable config exits non-zero)',
13
14
  examples: [
14
- ['what is published and what is not', 'shipkit releases'],
15
- ['filesystem + local git only, no network', 'shipkit releases --offline'],
16
- ['machine-readable', 'shipkit releases --json'],
15
+ ['what is published and what is not', 'sk releases'],
16
+ ['filesystem + local git only, no network', 'sk releases --offline'],
17
+ ['machine-readable', 'sk releases --json'],
17
18
  ],
18
19
  })
19
20
 
@@ -8,10 +8,11 @@ export class ServeCommand extends Command {
8
8
 
9
9
  static override usage = Command.Usage({
10
10
  category: 'Serve',
11
- description: 'ONE server, ONE page: media studio + asks + creds + posts + health + wikis, each wiki a link graph page',
11
+ description: 'the repo hub: one server, one page (assets, asks, creds, posts, health, wikis)',
12
+ details: 'ONE server, ONE page: media studio + asks + creds + posts + health + wikis, each wiki a link graph page',
12
13
  examples: [
13
- ['serve the repo toolbox', 'shipkit serve'],
14
- ['pin the port for this launch', 'shipkit serve --port 4804'],
14
+ ['serve the repo toolbox', 'sk serve'],
15
+ ['pin the port for this launch', 'sk serve --port 4804'],
15
16
  ],
16
17
  })
17
18
 
@@ -10,11 +10,12 @@ export class SmokeCommand extends Command {
10
10
 
11
11
  static override usage = Command.Usage({
12
12
  category: 'Health',
13
- description: 'browser smoke pass over a deployed web app: login through the app, visit every declared route, read only, screenshots + console/network problems + host quota. Exit code = failed routes',
13
+ description: 'browser smoke pass over a deployed web app, every declared route',
14
+ details: 'browser smoke pass over a deployed web app: login through the app, visit every declared route, read only, screenshots + console/network problems + host quota. Exit code = failed routes',
14
15
  examples: [
15
- ['every route in repo.config smoke, against its base url', 'shipkit smoke'],
16
- ['a preview deploy', 'shipkit smoke --base https://abc123.my-app.pages.dev'],
17
- ['two routes only', 'shipkit smoke --routes /orders,/clients'],
16
+ ['every route in repo.config smoke, against its base url', 'sk smoke'],
17
+ ['a preview deploy', 'sk smoke --base https://abc123.my-app.pages.dev'],
18
+ ['two routes only', 'sk smoke --routes /orders,/clients'],
18
19
  ],
19
20
  })
20
21
 
@@ -9,13 +9,14 @@ export class StartCommand extends Command {
9
9
 
10
10
  static override usage = Command.Usage({
11
11
  category: 'Setup',
12
- description: 'create (or enter) ~/dev/<name> from ANY cwd, READY to work in. On any dir with no commit history it writes the day-one shape (package.json + src/index.ts + lint/fmt/typecheck, tsconfig, .vscode tasks + settings, the verify skill, an agent/ wiki, .shipkit/reflections), installs the toolchain, wires shipkit (repo.config.ts via init), and runs the whole bootstrap chain: git init, first commit, PRIVATE github repo, push. Loose files ride in that first commit, and only a repo with real history is left as it is. Writes are create-only for files, additive for package.json scripts and .gitignore. CLAUDE.md is the two-line house template on its own (HOUSE_INCLUDE in src/start-repo.ts: the base wiki include, then `@./agent/index.md`, and --include overrides it), applied only on a machine where the house index exists, and the agent route lands last whenever the repo has agent/index.md. The house lines also opt the repo into the .claude/ policy files (a pre-approved shell allowlist + the attribution silencer), so a start with no house widens no agent permissions. Prints the dir on stdout so a shell alias can cd there. cwd-only sibling: `shipkit init`',
12
+ description: 'create or enter ~/dev/<name> from anywhere, ready to work in',
13
+ details: 'create (or enter) ~/dev/<name> from ANY cwd, READY to work in. On any dir with no commit history it writes the day-one shape (package.json + src/index.ts + lint/fmt/typecheck, tsconfig, .vscode tasks + settings, the verify skill, an agent/ wiki, .shipkit/reflections), installs the toolchain, wires shipkit (repo.config.ts via init), and runs the whole bootstrap chain: git init, first commit, PRIVATE github repo, push. Loose files ride in that first commit, and only a repo with real history is left as it is. Writes are create-only for files, additive for package.json scripts and .gitignore. CLAUDE.md is the two-line house template on its own (HOUSE_INCLUDE in src/start-repo.ts: the base wiki include, then `@./agent/index.md`, and --include overrides it), applied only on a machine where the house index exists, and the agent route lands last whenever the repo has agent/index.md. The house lines also opt the repo into the .claude/ policy files (a pre-approved shell allowlist + the attribution silencer), so a start with no house widens no agent permissions. Prints the dir on stdout so a shell alias can cd there. cwd-only sibling: `shipkit init`',
13
14
  examples: [
14
- ['create or enter ~/dev/pong: dir, package.json, shipkit wiring, git, first commit, private github repo, push, the two-line CLAUDE.md', 'shipkit start pong'],
15
- ['another house: replace the include lines', "shipkit start pong --include '@~/wiki/index.md' --include '@./agent/index.md'"],
16
- ['adopt a pre-existing repo from anywhere', 'shipkit start my-old-project'],
17
- ['force the private github repo for a folder that was already there', 'shipkit start old-notes --github'],
18
- ['local git and the first commit, never touch github', 'shipkit start pong --no-github'],
15
+ ['create or enter ~/dev/pong: dir, package.json, shipkit wiring, git, first commit, private github repo, push, the two-line CLAUDE.md', 'sk start pong'],
16
+ ['another house: replace the include lines', "sk start pong --include '@~/wiki/index.md' --include '@./agent/index.md'"],
17
+ ['adopt a pre-existing repo from anywhere', 'sk start my-old-project'],
18
+ ['force the private github repo for a folder that was already there', 'sk start old-notes --github'],
19
+ ['local git and the first commit, never touch github', 'sk start pong --no-github'],
19
20
  ],
20
21
  })
21
22
 
@@ -8,10 +8,11 @@ export class StatusCommand extends Command {
8
8
 
9
9
  static override usage = Command.Usage({
10
10
  category: 'Gate',
11
- description: `a gate started with \`shipkit ci --detach\`: its wire lines so far, then its verdict. Exit code = the gate's own once it finished, ${STILL_RUNNING} while it still runs, 1 when it died without one`,
11
+ description: 'the output and verdict of a gate started with `sk ci --detach`',
12
+ details: `a gate started with \`shipkit ci --detach\`: its wire lines so far, then its verdict. Exit code = the gate's own once it finished, ${STILL_RUNNING} while it still runs, 1 when it died without one`,
12
13
  examples: [
13
- ['the latest detached run of this checkout', 'shipkit status'],
14
- ['one run by id', 'shipkit status ci-mf3k2a-1x2y'],
14
+ ['the latest detached run of this checkout', 'sk status'],
15
+ ['one run by id', 'sk status ci-mf3k2a-1x2y'],
15
16
  ],
16
17
  })
17
18
 
@@ -11,8 +11,9 @@ export class TuiCommand extends Command {
11
11
 
12
12
  static override usage = Command.Usage({
13
13
  category: 'Health',
14
- description: 'live dashboard: the gate build steps + every other check, plus panels the repo injects via repo.config tui.panels',
15
- examples: [['open the dashboard', 'shipkit tui']],
14
+ description: 'live dashboard: the gate steps, every other check, the repo\'s panels',
15
+ details: 'live dashboard: the gate build steps + every other check, plus panels the repo injects via repo.config tui.panels',
16
+ examples: [['open the dashboard', 'sk tui']],
16
17
  })
17
18
 
18
19
  async execute(): Promise<number> {