claude-code-session-manager 0.111.0 → 0.112.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 (282) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/dist/assets/{AgentLibrary-rBO1daqM.js → AgentLibrary-RwPvEgqm.js} +2 -2
  3. package/dist/assets/{Button-DsEYRZg0.js → Button-36j3PzYv.js} +1 -1
  4. package/dist/assets/{DataModel-D8sbvvBC.js → DataModel-DUhANo4l.js} +1 -1
  5. package/dist/assets/{History-BEHLtxia.js → History-BeZzNjmv.js} +2 -2
  6. package/dist/assets/{Hooks-CKpvlXrg.js → Hooks-iQ8845Hp.js} +3 -3
  7. package/dist/assets/{Library-CeF4qh9d.js → Library-DPE1h-1L.js} +6 -6
  8. package/dist/assets/{ListDetail-DcfmxPFk.js → ListDetail-PStOuQAo.js} +1 -1
  9. package/dist/assets/{MarkdownEditor-CvK1pyto.js → MarkdownEditor-DPw-N2-m.js} +1 -1
  10. package/dist/assets/{McpServers-D-h2ihzJ.js → McpServers-CUyRTNep.js} +2 -2
  11. package/dist/assets/{Memory-BnF89x8v.js → Memory-bZ2xjBGy.js} +3 -3
  12. package/dist/assets/{Panel-CQY5zano.js → Panel-_VZ_uXNg.js} +1 -1
  13. package/dist/assets/{Permissions-DLukmmsz.js → Permissions-PPRmfNbK.js} +3 -3
  14. package/dist/assets/{Plugins-0Pf0OZ4l.js → Plugins-BFcvfvlx.js} +2 -2
  15. package/dist/assets/{ProvenanceBadge-vC7Tj-JP.js → ProvenanceBadge-B1WUknak.js} +1 -1
  16. package/dist/assets/RemoteMachines-D5V0lzgW.js +3 -0
  17. package/dist/assets/{SaveBar-DjijiUb0.js → SaveBar-Dw64FVdM.js} +1 -1
  18. package/dist/assets/{Scheduler-Cm3EXZvE.js → Scheduler-C8s_pJ3I.js} +9 -9
  19. package/dist/assets/{ScopeSwitcher-B-P-kSfq.js → ScopeSwitcher-D-nKDMAE.js} +1 -1
  20. package/dist/assets/{Settings-DYDlp2m_.js → Settings-CQSrR4mO.js} +4 -4
  21. package/dist/assets/{SkillReferenceGraph-Epv2GJmj.js → SkillReferenceGraph-BbZFMHim.js} +1 -1
  22. package/dist/assets/{Skills-DHO0N0C2.js → Skills-Bzyrh6EQ.js} +1 -1
  23. package/dist/assets/SystemPrompt-DP6i3Dx0.js +1 -0
  24. package/dist/assets/TagLibrary-iip0C6Bl.js +1 -0
  25. package/dist/assets/{TiptapBody-DAMO3DhO.js → TiptapBody-Cr-hxX8L.js} +1 -1
  26. package/dist/assets/Toggle-7WpPzcZH.js +1 -0
  27. package/dist/assets/{ViewTabs-CGX6MAhc.js → ViewTabs-9lQCRwWJ.js} +1 -1
  28. package/dist/assets/{historyTotals-vgfk8EOL.js → historyTotals-BrFxw5J1.js} +1 -1
  29. package/dist/assets/{index-CPieAFsl.js → index-CTBpf-26.js} +250 -250
  30. package/dist/assets/{settingsSchema-D0FxNrTy.js → settingsSchema-Dh5Kl7VO.js} +1 -1
  31. package/dist/assets/{useAgentsDirWatch-DCu6BNYN.js → useAgentsDirWatch-CMpx0d04.js} +1 -1
  32. package/dist/assets/{useRemotePeers-D4cdJDyh.js → useRemotePeers-CI2axd-L.js} +1 -1
  33. package/dist/index.html +1 -1
  34. package/package.json +3 -2
  35. package/plugins/CLAUDE.md +5 -8
  36. package/plugins/session-manager-dev/.claude-plugin/plugin.json +3 -6
  37. package/plugins/session-manager-dev/skills/builder/1-classify-and-bump/SKILL.md +2 -2
  38. package/plugins/session-manager-dev/skills/builder/SKILL.md +2 -3
  39. package/plugins/session-manager-dev/skills/develop/SKILL.md +1 -1
  40. package/plugins/session-manager-dev/skills/develop/standards.md +3 -3
  41. package/scripts/README.md +3 -3
  42. package/scripts/audit-ops-hygiene.cjs +4 -4
  43. package/scripts/hooks/guard-destructive-git.cjs +4 -4
  44. package/scripts/hooks/guard-inline-implementation.cjs +1 -1
  45. package/scripts/hooks/guard-prd-writes.cjs +2 -2
  46. package/scripts/hooks/lib/guard-destructive-git-policy.cjs +1 -1
  47. package/scripts/mint-epic.cjs +2 -2
  48. package/scripts/scheduler-mcp-server.cjs +4 -4
  49. package/src/main/agentLibrary.cjs +5 -5
  50. package/src/main/agentsIpc.cjs +76 -0
  51. package/src/main/build-info.json +4 -4
  52. package/src/main/chatRunner.cjs +12 -12
  53. package/src/main/config.cjs +2 -2
  54. package/src/main/crashDiagnostics.cjs +2 -2
  55. package/src/main/docEdit.cjs +5 -5
  56. package/src/main/files.cjs +2 -2
  57. package/src/main/git.cjs +1 -1
  58. package/src/main/health.cjs +20 -18
  59. package/src/main/heapSnapshot.cjs +1 -1
  60. package/src/main/historyAggregator.cjs +2 -2
  61. package/src/main/index.cjs +44 -132
  62. package/src/main/ipcSchemas.cjs +10 -10
  63. package/src/main/lib/CLAUDE.md +48 -0
  64. package/src/main/lib/activeSessions.cjs +1 -1
  65. package/src/main/lib/classifyPromptTicket.cjs +2 -2
  66. package/src/main/lib/{agentModelResolve.cjs → claude/agentModelResolve.cjs} +7 -7
  67. package/src/main/lib/{claudeBin.cjs → claude/claudeBin.cjs} +4 -4
  68. package/src/main/lib/{effectiveModelInfo.cjs → claude/effectiveModelInfo.cjs} +9 -9
  69. package/src/main/lib/{modelCatalog.cjs → claude/modelCatalog.cjs} +3 -3
  70. package/src/main/lib/{rateLimitDetect.cjs → claude/rateLimitDetect.cjs} +1 -1
  71. package/src/main/lib/{rateLimitWindow.cjs → claude/rateLimitWindow.cjs} +1 -1
  72. package/src/main/lib/{runClaudeP.cjs → claude/runClaudeP.cjs} +1 -1
  73. package/src/main/lib/credentials.cjs +3 -3
  74. package/src/main/lib/cwdClassify.cjs +1 -1
  75. package/src/main/lib/{activeIndexMerge.cjs → epic/activeIndexMerge.cjs} +3 -3
  76. package/src/main/lib/{activeIndexRebuild.cjs → epic/activeIndexRebuild.cjs} +1 -1
  77. package/src/main/lib/{delegationReadiness.cjs → epic/delegationReadiness.cjs} +21 -29
  78. package/src/main/lib/{epicContextDigest.cjs → epic/epicContextDigest.cjs} +1 -1
  79. package/src/main/lib/{epicDelegationStats.cjs → epic/epicDelegationStats.cjs} +2 -2
  80. package/src/main/lib/{epicMint.cjs → epic/epicMint.cjs} +11 -11
  81. package/src/main/lib/{epicSpawnPlan.cjs → epic/epicSpawnPlan.cjs} +3 -3
  82. package/src/main/lib/{epicStatusMirror.cjs → epic/epicStatusMirror.cjs} +2 -2
  83. package/src/main/lib/{epicTranscriptDiagnostic.cjs → epic/epicTranscriptDiagnostic.cjs} +2 -2
  84. package/src/main/lib/{epicTranscriptPath.cjs → epic/epicTranscriptPath.cjs} +2 -2
  85. package/src/main/lib/{epicValidationHook.cjs → epic/epicValidationHook.cjs} +3 -3
  86. package/src/main/lib/{epicWorktreeBoot.cjs → epic/epicWorktreeBoot.cjs} +1 -1
  87. package/src/main/lib/{epicWorktreeMerge.cjs → epic/epicWorktreeMerge.cjs} +3 -3
  88. package/src/main/lib/{epicWorktreeMint.cjs → epic/epicWorktreeMint.cjs} +3 -3
  89. package/src/main/lib/{epicWorktreeProjectConfig.cjs → epic/epicWorktreeProjectConfig.cjs} +4 -4
  90. package/src/main/lib/{promptSessionsCreateEpic.cjs → epic/promptSessionsCreateEpic.cjs} +4 -4
  91. package/src/main/lib/{crossProjectFeedback.cjs → feedback-remote/crossProjectFeedback.cjs} +7 -7
  92. package/src/main/lib/{customerFeedbackClient.cjs → feedback-remote/customerFeedbackClient.cjs} +3 -3
  93. package/src/main/lib/{customerFeedbackInbox.cjs → feedback-remote/customerFeedbackInbox.cjs} +2 -2
  94. package/src/main/lib/{customerFeedbackIpc.cjs → feedback-remote/customerFeedbackIpc.cjs} +1 -1
  95. package/src/main/lib/{localAdminHttp.cjs → feedback-remote/localAdminHttp.cjs} +2 -2
  96. package/src/main/lib/{macroAdminRoutes.cjs → feedback-remote/macroAdminRoutes.cjs} +1 -1
  97. package/src/main/lib/{projectHomeAdminRoutes.cjs → feedback-remote/projectHomeAdminRoutes.cjs} +4 -4
  98. package/src/main/lib/{relayClientAuth.cjs → feedback-remote/relayClientAuth.cjs} +2 -2
  99. package/src/main/lib/{remoteClientSessions.cjs → feedback-remote/remoteClientSessions.cjs} +1 -1
  100. package/src/main/lib/{gitWorktree.cjs → git/gitWorktree.cjs} +7 -7
  101. package/src/main/lib/historyRollup.cjs +1 -1
  102. package/src/main/lib/importReferences.cjs +1 -1
  103. package/src/main/lib/machineProfile.cjs +1 -1
  104. package/src/main/lib/openExternalApp.cjs +1 -1
  105. package/src/main/lib/opsOwnership.cjs +3 -3
  106. package/src/main/lib/{agentPersonaSchema.cjs → persona-macro/agentPersonaSchema.cjs} +2 -2
  107. package/src/main/lib/{macroLibrary.cjs → persona-macro/macroLibrary.cjs} +5 -5
  108. package/src/main/lib/{personaMerge.cjs → persona-macro/personaMerge.cjs} +4 -4
  109. package/src/main/lib/{prdAdminRoutes.cjs → prd/prdAdminRoutes.cjs} +7 -7
  110. package/src/main/lib/{prdAgentType.cjs → prd/prdAgentType.cjs} +3 -3
  111. package/src/main/lib/{prdCreate.cjs → prd/prdCreate.cjs} +12 -12
  112. package/src/main/lib/{prdDeclaredPaths.cjs → prd/prdDeclaredPaths.cjs} +1 -1
  113. package/src/main/lib/{prdGateFiles.cjs → prd/prdGateFiles.cjs} +1 -1
  114. package/src/main/lib/{prdLocations.cjs → prd/prdLocations.cjs} +2 -2
  115. package/src/main/lib/{prdMigration.cjs → prd/prdMigration.cjs} +3 -3
  116. package/src/main/lib/prereqs.cjs +2 -2
  117. package/src/main/lib/{instanceLock.cjs → process/instanceLock.cjs} +4 -11
  118. package/src/main/lib/{pidAlive.cjs → process/pidAlive.cjs} +1 -1
  119. package/src/main/lib/{procName.cjs → process/procName.cjs} +2 -2
  120. package/src/main/lib/{timeoutShim.cjs → process/timeoutShim.cjs} +1 -1
  121. package/src/main/lib/projectRootResolve.cjs +1 -1
  122. package/src/main/lib/promptSessionSchema.cjs +1 -1
  123. package/src/main/lib/{definitionOfDone.cjs → scheduler/definitionOfDone.cjs} +6 -12
  124. package/src/main/lib/{fixChainDepth.cjs → scheduler/fixChainDepth.cjs} +1 -1
  125. package/src/main/lib/{jobDirtFilter.cjs → scheduler/jobDirtFilter.cjs} +1 -1
  126. package/src/main/lib/{jobSupervisorRecord.cjs → scheduler/jobSupervisorRecord.cjs} +1 -1
  127. package/src/main/lib/{launchFailure.cjs → scheduler/launchFailure.cjs} +2 -2
  128. package/src/main/lib/{queueStore.cjs → scheduler/queueStore.cjs} +6 -6
  129. package/src/main/lib/{quietMachineLease.cjs → scheduler/quietMachineLease.cjs} +1 -1
  130. package/src/main/lib/{rcaReport.cjs → scheduler/rcaReport.cjs} +4 -4
  131. package/src/main/lib/{reaperHelpers.cjs → scheduler/reaperHelpers.cjs} +3 -3
  132. package/src/main/lib/{reservationExpiry.cjs → scheduler/reservationExpiry.cjs} +4 -11
  133. package/src/main/lib/{reviewNotice.cjs → scheduler/reviewNotice.cjs} +1 -1
  134. package/src/main/lib/{scheduleJobTransitions.cjs → scheduler/scheduleJobTransitions.cjs} +3 -3
  135. package/src/main/lib/{schedulerBatch.cjs → scheduler/schedulerBatch.cjs} +2 -2
  136. package/src/main/lib/{schedulerConfig.cjs → scheduler/schedulerConfig.cjs} +1 -1
  137. package/src/main/lib/{schedulerRuntimeState.cjs → scheduler/schedulerRuntimeState.cjs} +1 -1
  138. package/src/main/lib/{sessionSlots.cjs → scheduler/sessionSlots.cjs} +2 -2
  139. package/src/main/lib/{upgradeDrain.cjs → scheduler/upgradeDrain.cjs} +8 -11
  140. package/src/main/lib/{watchdogHelpers.cjs → scheduler/watchdogHelpers.cjs} +5 -19
  141. package/src/main/lib/{auditLog.cjs → telemetry/auditLog.cjs} +1 -1
  142. package/src/main/lib/{opsErrorLog.cjs → telemetry/opsErrorLog.cjs} +4 -4
  143. package/src/main/lib/{telemetryBacklog.cjs → telemetry/telemetryBacklog.cjs} +4 -4
  144. package/src/main/lib/{telemetryBoot.cjs → telemetry/telemetryBoot.cjs} +1 -1
  145. package/src/main/lib/{telemetryClient.cjs → telemetry/telemetryClient.cjs} +4 -4
  146. package/src/main/lib/{telemetrySettings.cjs → telemetry/telemetrySettings.cjs} +1 -1
  147. package/src/main/logs.cjs +1 -1
  148. package/src/main/mcpStatus.cjs +2 -2
  149. package/src/main/memoryAggregate.cjs +3 -3
  150. package/src/main/memoryTool.cjs +1 -1
  151. package/src/main/otel.cjs +2 -2
  152. package/src/main/pluginInstall.cjs +29 -3
  153. package/src/main/projectBrief.cjs +6 -6
  154. package/src/main/projectPages.cjs +1 -1
  155. package/src/main/promptSessionEvents.cjs +2 -2
  156. package/src/main/pty.cjs +7 -7
  157. package/src/main/queueOps.cjs +6 -6
  158. package/src/main/remoteClient.cjs +4 -4
  159. package/src/main/remoteClientIpc.cjs +1 -1
  160. package/src/main/runVerify.cjs +1 -1
  161. package/src/main/scheduler/CLAUDE.md +26 -0
  162. package/src/main/scheduler/budget.cjs +576 -0
  163. package/src/main/scheduler/gitTreeGuard.cjs +672 -0
  164. package/src/main/scheduler/prdParser.cjs +4 -4
  165. package/src/main/scheduler/prdPaths.cjs +487 -0
  166. package/src/main/scheduler/reviewLadder.cjs +1011 -0
  167. package/src/main/scheduler/starvation.cjs +390 -0
  168. package/src/main/scheduler.cjs +289 -3311
  169. package/src/main/seedAgentPersonas.cjs +5 -5
  170. package/src/main/seedDevPlugin.cjs +70 -3
  171. package/src/main/seedSchedulerMcp.cjs +2 -2
  172. package/src/main/supervisor.cjs +5 -5
  173. package/src/main/telemetryIpc.cjs +51 -0
  174. package/src/main/transcripts.cjs +3 -3
  175. package/src/main/updaterIpc.cjs +1 -1
  176. package/src/main/usage.cjs +1 -1
  177. package/src/main/watchers.cjs +1 -1
  178. package/src/main/webRemote.cjs +7 -7
  179. package/src/preload/api.d.ts +8 -8
  180. package/src/preload/index.cjs +3 -3
  181. package/dist/assets/RemoteMachines-CWnKbFHc.js +0 -3
  182. package/dist/assets/SystemPrompt-DxeNofL9.js +0 -1
  183. package/dist/assets/TagLibrary-QOAs7ISO.js +0 -1
  184. package/dist/assets/Toggle-Ba_f7q_m.js +0 -1
  185. package/plugins/session-manager-dev/skills/blog-for-project-feature/0-select/SKILL.md +0 -39
  186. package/plugins/session-manager-dev/skills/blog-for-project-feature/1-research/SKILL.md +0 -37
  187. package/plugins/session-manager-dev/skills/blog-for-project-feature/2-storyboard/SKILL.md +0 -64
  188. package/plugins/session-manager-dev/skills/blog-for-project-feature/3-capture/SKILL.md +0 -52
  189. package/plugins/session-manager-dev/skills/blog-for-project-feature/4-draft-copy/SKILL.md +0 -37
  190. package/plugins/session-manager-dev/skills/blog-for-project-feature/5-illustrate/SKILL.md +0 -50
  191. package/plugins/session-manager-dev/skills/blog-for-project-feature/6-compose/SKILL.md +0 -51
  192. package/plugins/session-manager-dev/skills/blog-for-project-feature/7-review/SKILL.md +0 -54
  193. package/plugins/session-manager-dev/skills/blog-for-project-feature/SKILL.md +0 -144
  194. package/plugins/session-manager-dev/skills/blog-for-project-feature/feature.config.yaml +0 -90
  195. package/plugins/session-manager-dev/skills/discover-features/SKILL.md +0 -95
  196. package/plugins/session-manager-dev/skills/explain-to-me/SKILL.md +0 -205
  197. package/plugins/session-manager-dev/skills/explain-to-me/assets/style-reference.html +0 -163
  198. package/plugins/session-manager-dev/skills/find-opportunity/SKILL.md +0 -83
  199. package/plugins/session-manager-dev/skills/issue-address/0-select/0-fetch-pool/SKILL.md +0 -38
  200. package/plugins/session-manager-dev/skills/issue-address/0-select/1-reject-fixed/SKILL.md +0 -64
  201. package/plugins/session-manager-dev/skills/issue-address/0-select/2-reject-claimed/SKILL.md +0 -71
  202. package/plugins/session-manager-dev/skills/issue-address/0-select/3-rank-impact/SKILL.md +0 -39
  203. package/plugins/session-manager-dev/skills/issue-address/0-select/SKILL.md +0 -75
  204. package/plugins/session-manager-dev/skills/issue-address/1-confirm-open/SKILL.md +0 -39
  205. package/plugins/session-manager-dev/skills/issue-address/2-claim/SKILL.md +0 -57
  206. package/plugins/session-manager-dev/skills/issue-address/3-reproduce/SKILL.md +0 -40
  207. package/plugins/session-manager-dev/skills/issue-address/4-fix/SKILL.md +0 -33
  208. package/plugins/session-manager-dev/skills/issue-address/5-verify/SKILL.md +0 -40
  209. package/plugins/session-manager-dev/skills/issue-address/SKILL.md +0 -120
  210. package/plugins/session-manager-dev/skills/local-project-health/SKILL.md +0 -58
  211. package/plugins/session-manager-dev/skills/memory-sanitation/SKILL.md +0 -147
  212. package/plugins/session-manager-dev/skills/ops-sweep/SKILL.md +0 -137
  213. package/plugins/session-manager-dev/skills/pr-review-sweep/0-fetch/SKILL.md +0 -41
  214. package/plugins/session-manager-dev/skills/pr-review-sweep/1-classify/SKILL.md +0 -56
  215. package/plugins/session-manager-dev/skills/pr-review-sweep/2-check-fixed/SKILL.md +0 -49
  216. package/plugins/session-manager-dev/skills/pr-review-sweep/3-queue/SKILL.md +0 -57
  217. package/plugins/session-manager-dev/skills/pr-review-sweep/4-land-and-resolve/SKILL.md +0 -60
  218. package/plugins/session-manager-dev/skills/pr-review-sweep/SKILL.md +0 -124
  219. package/plugins/session-manager-dev/skills/pr-signal/SKILL.md +0 -67
  220. package/plugins/session-manager-dev/skills/project-status/SKILL.md +0 -243
  221. package/plugins/session-manager-dev/skills/requesting-code-review/SKILL.md +0 -98
  222. package/plugins/session-manager-dev/skills/requesting-code-review/code-reviewer.md +0 -146
  223. /package/src/main/lib/{agentEffortResolve.cjs → claude/agentEffortResolve.cjs} +0 -0
  224. /package/src/main/lib/{claudeCliCaps.cjs → claude/claudeCliCaps.cjs} +0 -0
  225. /package/src/main/lib/{usageCircuit.cjs → claude/usageCircuit.cjs} +0 -0
  226. /package/src/main/lib/{epicSpawnCwd.cjs → epic/epicSpawnCwd.cjs} +0 -0
  227. /package/src/main/lib/{customerFeedbackAdminRoutes.cjs → feedback-remote/customerFeedbackAdminRoutes.cjs} +0 -0
  228. /package/src/main/lib/{remoteE2eCrypto.cjs → feedback-remote/remoteE2eCrypto.cjs} +0 -0
  229. /package/src/main/lib/{branchSweep.cjs → git/branchSweep.cjs} +0 -0
  230. /package/src/main/lib/{gitExec.cjs → git/gitExec.cjs} +0 -0
  231. /package/src/main/lib/{jobWorktree.cjs → git/jobWorktree.cjs} +0 -0
  232. /package/src/main/lib/{jobWorktreeBootLive.cjs → git/jobWorktreeBootLive.cjs} +0 -0
  233. /package/src/main/lib/{jobWorktreeTerminalOrphanLive.cjs → git/jobWorktreeTerminalOrphanLive.cjs} +0 -0
  234. /package/src/main/lib/{builtinMacros.cjs → persona-macro/builtinMacros.cjs} +0 -0
  235. /package/src/main/lib/{personaImportHealth.cjs → persona-macro/personaImportHealth.cjs} +0 -0
  236. /package/src/main/lib/{shippedPersonaSeeds.cjs → persona-macro/shippedPersonaSeeds.cjs} +0 -0
  237. /package/src/main/lib/{depSlugResolve.cjs → prd/depSlugResolve.cjs} +0 -0
  238. /package/src/main/lib/{planValidator.cjs → prd/planValidator.cjs} +0 -0
  239. /package/src/main/lib/{prdAuthoringSeed.cjs → prd/prdAuthoringSeed.cjs} +0 -0
  240. /package/src/main/lib/{prdDisposition.cjs → prd/prdDisposition.cjs} +0 -0
  241. /package/src/main/lib/{prdFrontmatter.cjs → prd/prdFrontmatter.cjs} +0 -0
  242. /package/src/main/lib/{prdSizing.cjs → prd/prdSizing.cjs} +0 -0
  243. /package/src/main/lib/{workTypeLibrary.cjs → prd/workTypeLibrary.cjs} +0 -0
  244. /package/src/main/lib/{childWithLog.cjs → process/childWithLog.cjs} +0 -0
  245. /package/src/main/lib/{cleanEnv.cjs → process/cleanEnv.cjs} +0 -0
  246. /package/src/main/lib/{defaultShell.cjs → process/defaultShell.cjs} +0 -0
  247. /package/src/main/lib/{killTree.cjs → process/killTree.cjs} +0 -0
  248. /package/src/main/lib/{loginShellPath.cjs → process/loginShellPath.cjs} +0 -0
  249. /package/src/main/lib/{procIdentity.cjs → process/procIdentity.cjs} +0 -0
  250. /package/src/main/lib/{singleInstanceGuard.cjs → process/singleInstanceGuard.cjs} +0 -0
  251. /package/src/main/lib/{smProcNames.cjs → process/smProcNames.cjs} +0 -0
  252. /package/src/main/lib/{timeoutShimScript.cjs → process/timeoutShimScript.cjs} +0 -0
  253. /package/src/main/lib/{winSpawn.cjs → process/winSpawn.cjs} +0 -0
  254. /package/src/main/lib/{adoptedRunSupervisor.cjs → scheduler/adoptedRunSupervisor.cjs} +0 -0
  255. /package/src/main/lib/{dispatchLoop.cjs → scheduler/dispatchLoop.cjs} +0 -0
  256. /package/src/main/lib/{dodDrainHook.cjs → scheduler/dodDrainHook.cjs} +0 -0
  257. /package/src/main/lib/{fixPlanSlug.cjs → scheduler/fixPlanSlug.cjs} +0 -0
  258. /package/src/main/lib/{gateAuthority.cjs → scheduler/gateAuthority.cjs} +0 -0
  259. /package/src/main/lib/{landedSinceRun.cjs → scheduler/landedSinceRun.cjs} +0 -0
  260. /package/src/main/lib/{loadGate.cjs → scheduler/loadGate.cjs} +0 -0
  261. /package/src/main/lib/{needsReviewLedger.cjs → scheduler/needsReviewLedger.cjs} +0 -0
  262. /package/src/main/lib/{queueHealth.cjs → scheduler/queueHealth.cjs} +0 -0
  263. /package/src/main/lib/{queueHistory.cjs → scheduler/queueHistory.cjs} +0 -0
  264. /package/src/main/lib/{runLogRetention.cjs → scheduler/runLogRetention.cjs} +0 -0
  265. /package/src/main/lib/{scheduleJobSchema.cjs → scheduler/scheduleJobSchema.cjs} +0 -0
  266. /package/src/main/lib/{schedulerPaths.cjs → scheduler/schedulerPaths.cjs} +0 -0
  267. /package/src/main/lib/{terminalRunOutcome.cjs → scheduler/terminalRunOutcome.cjs} +0 -0
  268. /package/src/main/lib/{validationSentinels.cjs → scheduler/validationSentinels.cjs} +0 -0
  269. /package/src/main/lib/{crashTelemetry.cjs → telemetry/crashTelemetry.cjs} +0 -0
  270. /package/src/main/lib/{otlpTraceExporter.cjs → telemetry/otlpTraceExporter.cjs} +0 -0
  271. /package/src/main/lib/{telemetryConsent.cjs → telemetry/telemetryConsent.cjs} +0 -0
  272. /package/src/main/lib/{telemetryCounters.cjs → telemetry/telemetryCounters.cjs} +0 -0
  273. /package/src/main/lib/{atomicFs.cjs → util/atomicFs.cjs} +0 -0
  274. /package/src/main/lib/{encodeCwd.cjs → util/encodeCwd.cjs} +0 -0
  275. /package/src/main/lib/{expandHome.cjs → util/expandHome.cjs} +0 -0
  276. /package/src/main/lib/{extractJson.cjs → util/extractJson.cjs} +0 -0
  277. /package/src/main/lib/{fileTail.cjs → util/fileTail.cjs} +0 -0
  278. /package/src/main/lib/{headTailBuffer.cjs → util/headTailBuffer.cjs} +0 -0
  279. /package/src/main/lib/{kebabCase.cjs → util/kebabCase.cjs} +0 -0
  280. /package/src/main/lib/{loopDelay.cjs → util/loopDelay.cjs} +0 -0
  281. /package/src/main/lib/{lruCache.cjs → util/lruCache.cjs} +0 -0
  282. /package/src/main/lib/{withTimeout.cjs → util/withTimeout.cjs} +0 -0
@@ -12,7 +12,7 @@
12
12
  * `seedVersion` frontmatter stamp (missing counts as 1) against the
13
13
  * bundled file's own stamp. Same or higher stays untouched. Lower checks
14
14
  * the installed file's body against every body this app has ever shipped
15
- * for that persona (`lib/shippedPersonaSeeds.cjs`). No match means a
15
+ * for that persona (`lib/persona-macro/shippedPersonaSeeds.cjs`). No match means a
16
16
  * person wrote or edited that file; it is left alone and the skip is
17
17
  * logged. Why: a lower stamp alone does not prove the file is a stale
18
18
  * shipped copy — only a body match does. A match replaces the installed
@@ -77,8 +77,8 @@ const path = require('node:path');
77
77
  const os = require('node:os');
78
78
  const crypto = require('node:crypto');
79
79
  const { writeJsonSync, writeTextAtomic, validatePath, validateWrite } = require('./config.cjs');
80
- const { splitFrontmatter } = require('./lib/prdFrontmatter.cjs');
81
- const { SHIPPED_PERSONA_SEEDS } = require('./lib/shippedPersonaSeeds.cjs');
80
+ const { splitFrontmatter } = require('./lib/prd/prdFrontmatter.cjs');
81
+ const { SHIPPED_PERSONA_SEEDS } = require('./lib/persona-macro/shippedPersonaSeeds.cjs');
82
82
 
83
83
  const PERSONAS = ['architect', 'dev-lead', 'project-home-builder', 'validator', 'demo-video-builder'];
84
84
  // What `{ done: true }` (the pre-seeded-set marker format) meant: only these two personas existed
@@ -140,7 +140,7 @@ function normalizeNewlines(text) {
140
140
  return text.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
141
141
  }
142
142
 
143
- /** sha256 hex of a persona's body only (frontmatter stripped, newlines normalized, trimmed) — the key the upgrade pass matches against `lib/shippedPersonaSeeds.cjs`. */
143
+ /** sha256 hex of a persona's body only (frontmatter stripped, newlines normalized, trimmed) — the key the upgrade pass matches against `lib/persona-macro/shippedPersonaSeeds.cjs`. */
144
144
  function personaBodyHash(text) {
145
145
  const { body } = splitFrontmatter(normalizeNewlines(text));
146
146
  return crypto.createHash('sha256').update(body.trim()).digest('hex');
@@ -269,7 +269,7 @@ function buildUpgradedPersona(bundledText, installedText, matches) {
269
269
  * Replaces a stale installed persona with the current bundled one, once per
270
270
  * boot, for every name in `PERSONAS` whose installed file is both PRESENT
271
271
  * and behind the bundled `seedVersion` AND whose body matches a body this
272
- * app has shipped before (`shippedSeeds`, normally `lib/shippedPersonaSeeds.cjs`
272
+ * app has shipped before (`shippedSeeds`, normally `lib/persona-macro/shippedPersonaSeeds.cjs`
273
273
  * — injectable so tests can supply a fake list). See this file's header for
274
274
  * the full rule, and `buildUpgradedPersona` for how frontmatter keys merge.
275
275
  * Never overwrites a same-or-newer installed file, or one whose body never
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * First-boot seeder for the bundled `session-manager-dev` plugin.
3
3
  *
4
- * The plugin (the dev skills under plugins/session-manager-dev/skills) ships inside the npx distribution. To make it
4
+ * The plugin (3 skills under plugins/session-manager-dev/skills: builder, develop, send-feedback) ships inside the npx distribution. To make it
5
5
  * a true default, the app installs it on first launch from its own bundled
6
6
  * marketplace (offline — no GitHub/registry). Idempotent two ways:
7
7
  *
@@ -16,6 +16,12 @@
16
16
  * plugin is already enabled (e.g. installed by hand), we just write the
17
17
  * marker and skip the install.
18
18
  *
19
+ * Stay-current pass (`upgradeIfStale`, like seedAgentPersonas' upgrade pass): runs on EVERY
20
+ * call, independent of the done-marker. If the plugin is installed AND enabled at a version
21
+ * older than the bundled plugin.json version, it runs the claude CLI marketplace update +
22
+ * plugin update. Never acts when not installed, disabled (a deliberate disable stays), or
23
+ * versions are equal/newer. Failures are logged, never thrown.
24
+ *
19
25
  * Fire-and-forget: called post-window from index.cjs. Errors are logged, never
20
26
  * thrown. Kill-switch: SM_SEED_DEV_PLUGIN_DISABLE=1.
21
27
  */
@@ -23,7 +29,7 @@
23
29
  const fs = require('node:fs');
24
30
  const path = require('node:path');
25
31
  const os = require('node:os');
26
- const { install } = require('./pluginInstall.cjs');
32
+ const { install, update } = require('./pluginInstall.cjs');
27
33
 
28
34
  const PLUGIN_SLUG = 'session-manager-dev';
29
35
  const MARKETPLACE = { add: 'bundled', name: 'session-manager' };
@@ -65,8 +71,69 @@ function writeMarker(state) {
65
71
  }
66
72
  }
67
73
 
74
+ /** Compare dotted numeric versions (pre-release suffixes ignored). <0, 0, >0. */
75
+ function compareSemver(a, b) {
76
+ const parse = (v) => String(v).split('-')[0].split('.').map((n) => Number(n) || 0);
77
+ const pa = parse(a);
78
+ const pb = parse(b);
79
+ for (let i = 0; i < Math.max(pa.length, pb.length, 3); i++) {
80
+ const d = (pa[i] || 0) - (pb[i] || 0);
81
+ if (d !== 0) return d;
82
+ }
83
+ return 0;
84
+ }
85
+
86
+ function readJson(p) {
87
+ try { return JSON.parse(fs.readFileSync(p, 'utf8')); } catch { return null; }
88
+ }
89
+
90
+ function bundledVersion() {
91
+ const m = readJson(path.join(__dirname, '..', '..', 'plugins', PLUGIN_SLUG, '.claude-plugin', 'plugin.json'));
92
+ return typeof m?.version === 'string' ? m.version : null;
93
+ }
94
+
95
+ /**
96
+ * Stay-current pass. Update the installed plugin when older than the bundled one.
97
+ * Never throws. Deps injectable for tests.
98
+ */
99
+ async function upgradeIfStale({
100
+ logger = console,
101
+ writeLog = () => {},
102
+ home = os.homedir(),
103
+ bundledVersion: bundled = bundledVersion(),
104
+ runUpdate = update,
105
+ } = {}) {
106
+ if (process.env.SM_SEED_DEV_PLUGIN_DISABLE === '1') return;
107
+ try {
108
+ const entries = readJson(path.join(home, '.claude', 'plugins', 'installed_plugins.json'))?.plugins?.[ENABLED_KEY];
109
+ const installedVersion = Array.isArray(entries) ? entries[0]?.version : null;
110
+ if (!installedVersion || !bundled) return; // not installed / no bundle
111
+ const enabled = readJson(path.join(home, '.claude', 'settings.json'))?.enabledPlugins;
112
+ if (!enabled?.[ENABLED_KEY]) return; // deliberate disable stays
113
+ if (compareSemver(installedVersion, bundled) >= 0) return; // current or newer
114
+ logger.log?.(`[seedDevPlugin] updating ${ENABLED_KEY} ${installedVersion} → ${bundled}`);
115
+ const r = await runUpdate({ slug: PLUGIN_SLUG, marketplaceName: MARKETPLACE.name });
116
+ if (!r?.ok) {
117
+ writeLog({
118
+ scope: 'seed-dev-plugin',
119
+ level: 'error',
120
+ message: 'upgrade failed',
121
+ meta: { exitCode: r?.exitCode, error: r?.error, from: installedVersion, to: bundled },
122
+ });
123
+ }
124
+ } catch (err) {
125
+ writeLog({
126
+ scope: 'seed-dev-plugin',
127
+ level: 'error',
128
+ message: 'upgrade error',
129
+ meta: { error: err?.message ?? String(err) },
130
+ });
131
+ }
132
+ }
133
+
68
134
  async function seedDevPlugin({ logger = console, writeLog = () => {} } = {}) {
69
135
  if (process.env.SM_SEED_DEV_PLUGIN_DISABLE === '1') return;
136
+ await upgradeIfStale({ logger, writeLog });
70
137
  const marker = readMarker();
71
138
  if (marker.done) return; // succeeded before — leave it alone.
72
139
  if (marker.attempts >= MAX_ATTEMPTS) return; // gave up — manual install only.
@@ -104,4 +171,4 @@ async function seedDevPlugin({ logger = console, writeLog = () => {} } = {}) {
104
171
  }
105
172
  }
106
173
 
107
- module.exports = { seedDevPlugin, markerPath, MAX_ATTEMPTS };
174
+ module.exports = { seedDevPlugin, upgradeIfStale, compareSemver, markerPath, MAX_ATTEMPTS };
@@ -35,8 +35,8 @@ const fs = require('node:fs');
35
35
  const path = require('node:path');
36
36
  const os = require('node:os');
37
37
  const { spawn } = require('node:child_process');
38
- const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claudeBin.cjs');
39
- const { cleanChildEnv, pathWithUserBins } = require('./lib/cleanEnv.cjs');
38
+ const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claude/claudeBin.cjs');
39
+ const { cleanChildEnv, pathWithUserBins } = require('./lib/process/cleanEnv.cjs');
40
40
  const { writeJsonSync } = require('./config.cjs');
41
41
  const { nodeSpawnSpec } = require('./lib/appRuntime.cjs');
42
42
 
@@ -16,10 +16,10 @@ const path = require('node:path');
16
16
  const os = require('node:os');
17
17
  const { spawn, execFileSync } = require('node:child_process');
18
18
  const { ipcMain } = require('electron');
19
- const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claudeBin.cjs');
20
- const { headlessPermissionArgs, ensureCliCapsProbed } = require('./lib/claudeCliCaps.cjs');
21
- const { withProcRole } = require('./lib/cleanEnv.cjs');
22
- const schedulerPaths = require('./lib/schedulerPaths.cjs');
19
+ const { resolveClaudeBin, claudeSpawnTarget } = require('./lib/claude/claudeBin.cjs');
20
+ const { headlessPermissionArgs, ensureCliCapsProbed } = require('./lib/claude/claudeCliCaps.cjs');
21
+ const { withProcRole } = require('./lib/process/cleanEnv.cjs');
22
+ const schedulerPaths = require('./lib/scheduler/schedulerPaths.cjs');
23
23
 
24
24
  const HOME = os.homedir();
25
25
  const SUPERVISOR_LOG_PATH = path.join(HOME, '.claude', 'session-manager', 'supervisor.log');
@@ -103,7 +103,7 @@ function getChildBashCmdlines(jobPid) {
103
103
 
104
104
  // ─── Log tail helpers ───────────────────────────────────────────────────────
105
105
 
106
- const { readTail: readTailBytes } = require('./lib/fileTail.cjs');
106
+ const { readTail: readTailBytes } = require('./lib/util/fileTail.cjs');
107
107
 
108
108
  /**
109
109
  * Skim the last 16 KB of a run log for the most recent assistant/user/result
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * telemetryIpc.cjs — registers the `otel:*` and `telemetry:*` IPC handlers. Moved verbatim out of
5
+ * index.cjs; channel names and handler bodies are unchanged.
6
+ */
7
+
8
+ const { schemas, validated } = require('./ipcSchemas.cjs');
9
+ const otel = require('./otel.cjs');
10
+ const otelSettings = require('./otelSettings.cjs');
11
+ const telemetrySettings = require('./lib/telemetry/telemetrySettings.cjs');
12
+ const telemetryClient = require('./lib/telemetry/telemetryClient.cjs');
13
+ const telemetryBacklog = require('./lib/telemetry/telemetryBacklog.cjs');
14
+ const telemetryConsent = require('./lib/telemetry/telemetryConsent.cjs');
15
+
16
+ /**
17
+ * @param {{ ipcMain: any }} opts
18
+ */
19
+ function registerTelemetryHandlers({ ipcMain }) {
20
+ // OTEL telemetry export (opt-in via ~/.claude/session-manager/otel.json).
21
+ ipcMain.handle('otel:get-config', async () => otelSettings.load());
22
+ ipcMain.handle('otel:set-config', async (_e, cfg) => {
23
+ if (!otelSettings.isValid(cfg)) {
24
+ return { ok: false, error: 'invalid config' };
25
+ }
26
+ const saved = await otelSettings.save(cfg);
27
+ const result = await otel.applyConfig(saved);
28
+ return { ok: !!result?.ok, error: result?.error ?? null, config: saved, status: otel.status() };
29
+ });
30
+ ipcMain.handle('otel:status', () => otel.status());
31
+ ipcMain.handle('otel:config-path', () => otelSettings.storePath());
32
+
33
+ // Product telemetry (bilko.run) — anonymous, on-by-default, opt-out consent
34
+ // UX + inspector over the client PRDs above wired. Settings > Telemetry's
35
+ // "Product telemetry" section is the sole UI surface for this; see
36
+ // session-manager-operations/architecture/telemetry.md for the data model.
37
+ ipcMain.handle('telemetry:get-config', async () => telemetrySettings.load());
38
+ ipcMain.handle('telemetry:set-config', validated(schemas.telemetrySetConfig, async (cfg) => {
39
+ const saved = await telemetryConsent.applyConsentUpdate(cfg, { telemetrySettings, telemetryClient });
40
+ return { ok: true, config: saved, status: telemetryClient.status() };
41
+ }));
42
+ ipcMain.handle('telemetry:status', () => ({
43
+ ...telemetryClient.status(),
44
+ backlog: telemetryBacklog.lastRunSummary(),
45
+ }));
46
+ ipcMain.handle('telemetry:config-path', () => telemetrySettings.storePath());
47
+ ipcMain.handle('telemetry:recent-records', () => telemetryClient.recentRecords());
48
+ ipcMain.handle('telemetry:flush-now', () => telemetryClient.flush('manual'));
49
+ }
50
+
51
+ module.exports = { registerTelemetryHandlers };
@@ -36,10 +36,10 @@ function attachWindow(w) {
36
36
  window = w;
37
37
  }
38
38
 
39
- const { encodeCwd } = require('./lib/encodeCwd.cjs');
40
- const { LRUCache } = require('./lib/lruCache.cjs');
39
+ const { encodeCwd } = require('./lib/util/encodeCwd.cjs');
40
+ const { LRUCache } = require('./lib/util/lruCache.cjs');
41
41
  const { classifyLine } = require('./lib/classifyTranscriptLine.cjs');
42
- const { resolveEpicTranscriptPath } = require('./lib/epicTranscriptPath.cjs');
42
+ const { resolveEpicTranscriptPath } = require('./lib/epic/epicTranscriptPath.cjs');
43
43
 
44
44
  /**
45
45
  * Where the CLI's JSONL for this session lives. Epic sessions run in a
@@ -28,7 +28,7 @@ function defaultDeps() {
28
28
  platform: process.platform,
29
29
  env: process.env,
30
30
  settings: require('./lib/updaterSettings.cjs'),
31
- sessionSlots: require('./lib/sessionSlots.cjs'),
31
+ sessionSlots: require('./lib/scheduler/sessionSlots.cjs'),
32
32
  currentVersion: () => require('electron').app.getVersion(),
33
33
  log: (message, meta) => {
34
34
  try {
@@ -23,7 +23,7 @@ const os = require('node:os');
23
23
  const { ipcMain } = require('electron');
24
24
  const { refreshIfNeeded, expiresAtMs } = require('./lib/credentials.cjs');
25
25
  const { writeJson } = require('./config.cjs');
26
- const { createUsageCircuit, singleFlight } = require('./lib/usageCircuit.cjs');
26
+ const { createUsageCircuit, singleFlight } = require('./lib/claude/usageCircuit.cjs');
27
27
 
28
28
  const USAGE_URL = 'https://api.anthropic.com/api/oauth/usage';
29
29
 
@@ -14,7 +14,7 @@ const crypto = require('node:crypto');
14
14
  const path = require('node:path');
15
15
  const os = require('node:os');
16
16
  const fs = require('node:fs');
17
- const { cleanChildEnv } = require('./lib/cleanEnv.cjs');
17
+ const { cleanChildEnv } = require('./lib/process/cleanEnv.cjs');
18
18
  const { checkInsideHome } = require('./lib/insideHome.cjs');
19
19
  const { sendIfAlive } = require('./lib/sendToRenderer.cjs');
20
20
 
@@ -27,11 +27,11 @@ const fs = require('node:fs');
27
27
  const { writeTextAtomic, validatePath } = require('./config.cjs');
28
28
  const logs = require('./logs.cjs');
29
29
  const { sendIfAlive } = require('./lib/sendToRenderer.cjs');
30
- const { claudeHome } = require('./lib/schedulerPaths.cjs');
30
+ const { claudeHome } = require('./lib/scheduler/schedulerPaths.cjs');
31
31
  const { schemas } = require('./ipcSchemas.cjs');
32
32
  const { summarize: _sharedSummarize } = require('./lib/summarize.cjs');
33
33
  const { makeState, confirmSas: confirmSasLogic } = require('./lib/e2eStateMachine.cjs');
34
- const { createClientSessions, LEGACY_CLIENT_KEY } = require('./lib/remoteClientSessions.cjs');
34
+ const { createClientSessions, LEGACY_CLIENT_KEY } = require('./lib/feedback-remote/remoteClientSessions.cjs');
35
35
 
36
36
  // ─── Constants ───────────────────────────────────────────────────────────────
37
37
 
@@ -69,8 +69,8 @@ const MSG_MAX_BYTES = 256 * 1024;
69
69
  const { ALLOWED_COMMANDS, MUTATE_COMMANDS, SAS_GATED_READS } = require('./ipcSchemas.cjs');
70
70
 
71
71
  // ─── E2E encryption helpers (P-256 ECDH + AES-256-GCM, ADR §5.2) ────────────
72
- // Implemented in ./lib/remoteE2eCrypto.cjs (shared with the desktop client role).
73
- const { generateE2EKeyPair, deriveSessionKey, deriveSas, encryptBox, decryptBox } = require('./lib/remoteE2eCrypto.cjs');
72
+ // Implemented in ./lib/feedback-remote/remoteE2eCrypto.cjs (shared with the desktop client role).
73
+ const { generateE2EKeyPair, deriveSessionKey, deriveSas, encryptBox, decryptBox } = require('./lib/feedback-remote/remoteE2eCrypto.cjs');
74
74
 
75
75
  // ─── Module state ────────────────────────────────────────────────────────────
76
76
 
@@ -735,7 +735,7 @@ async function pushSessionList() {
735
735
  const data = await sessionsStore.load();
736
736
  // Tabs + their ACTIVE Epics → SessionMeta. tabId === claude sessionId so it
737
737
  // matches the transcript JSONL name used by cmd:session:subscribe.
738
- const { readActiveIndex } = require('./lib/epicMint.cjs');
738
+ const { readActiveIndex } = require('./lib/epic/epicMint.cjs');
739
739
  const sessions = buildRemoteSessionList(data?.tabs ?? [], readActiveIndex).map((s) => ({
740
740
  ...s,
741
741
  state: _sessionWatchers.get(s.tabId)?.state ?? null,
@@ -1092,7 +1092,7 @@ function getDispatchMap() {
1092
1092
  sessionsStore.load(),
1093
1093
 
1094
1094
  'cmd:sessions:list': async () => {
1095
- const { readActiveIndex } = require('./lib/epicMint.cjs');
1095
+ const { readActiveIndex } = require('./lib/epic/epicMint.cjs');
1096
1096
  const data = await sessionsStore.load();
1097
1097
  return {
1098
1098
  sessions: buildRemoteSessionList(data?.tabs ?? [], readActiveIndex),
@@ -1196,7 +1196,7 @@ function getDispatchMap() {
1196
1196
  'cmd:session:options': async () => {
1197
1197
  const { EpicTagSchema } = require('./lib/promptSessionSchema.cjs');
1198
1198
  const agentLibrary = require('./agentLibrary.cjs');
1199
- const macroLibrary = require('./lib/macroLibrary.cjs');
1199
+ const macroLibrary = require('./lib/persona-macro/macroLibrary.cjs');
1200
1200
  const { tabs } = await sessionsStore.load();
1201
1201
  const personas = await agentLibrary.listPersonas();
1202
1202
  return {
@@ -254,7 +254,7 @@ export interface McpCatalogResult {
254
254
  recipes: McpRecipe[];
255
255
  }
256
256
 
257
- /** Mirrors WorkType (src/main/lib/workTypeLibrary.cjs) / EpicTag (tagLibrary.ts) — the
257
+ /** Mirrors WorkType (src/main/lib/prd/workTypeLibrary.cjs) / EpicTag (tagLibrary.ts) — the
258
258
  * same Epic-mission taxonomy, reused here since an Agent persona's `tags` field is that
259
259
  * same concept, not a free-form string list. */
260
260
  export type AgentPersonaTag = 'feature' | 'bug' | 'discussion' | 'build' | 'project-home-builder';
@@ -491,7 +491,7 @@ export interface OtelSetConfigResult {
491
491
  }
492
492
 
493
493
  // Customer feedback — client submissions + owner inbox. Shapes mirror
494
- // src/main/lib/customerFeedbackClient.cjs and customerFeedbackInbox.cjs.
494
+ // src/main/lib/feedback-remote/customerFeedbackClient.cjs and customerFeedbackInbox.cjs.
495
495
  export type CustomerFeedbackTag = 'bug' | 'feature' | 'discussion';
496
496
  export type CustomerFeedbackStatus = 'open' | 'in_progress' | 'resolved' | 'wontfix';
497
497
 
@@ -610,7 +610,7 @@ export interface ScheduleConfig {
610
610
  schemaVersion: 1;
611
611
  }
612
612
 
613
- /** Mirrors JOB_STATUSES (src/main/lib/scheduleJobSchema.cjs) — the single
613
+ /** Mirrors JOB_STATUSES (src/main/lib/scheduler/scheduleJobSchema.cjs) — the single
614
614
  * source of truth asserted at read time by queueStore.cjs's shapeJobs. This
615
615
  * file can't require that .cjs module (types-only, erased at build time),
616
616
  * so this union is a manually-kept copy; drift from JOB_STATUSES (and from
@@ -868,7 +868,7 @@ export interface ScheduleJobHold {
868
868
  reason?: string | null;
869
869
  }
870
870
 
871
- /** Why a headless run never got a model turn (lib/launchFailure.cjs, issue #11). */
871
+ /** Why a headless run never got a model turn (lib/scheduler/launchFailure.cjs, issue #11). */
872
872
  export type ScheduleLaunchFailureKind =
873
873
  | 'model_config_rejected'
874
874
  | 'bad_request'
@@ -2266,22 +2266,22 @@ export interface SessionManagerAPI {
2266
2266
  * live instead of waiting for a restart. */
2267
2267
  onEventAppended: (handler: (e: PromptSessionEventAppendedPayload) => void) => () => void;
2268
2268
  /** Main-side read-merge-write of a cwd's active-index.json
2269
- * (lib/activeIndexMerge.cjs) — persistActiveIndex sends only its own
2269
+ * (lib/epic/activeIndexMerge.cjs) — persistActiveIndex sends only its own
2270
2270
  * in-memory contribution for the cwd; disk stays main's truth, merged
2271
2271
  * inside the same lock epicMint.cjs's ensureEpic serializes through. */
2272
2272
  mergeActiveIndex: (payload: PromptSessionsMergeActiveIndexPayload) => Promise<PromptSessionsMergeActiveIndexResult>;
2273
2273
  /** Mints a brand-new 'proposed' Epic through main's own ensureEpic()
2274
- * (lib/promptSessionsCreateEpic.cjs) instead of the renderer
2274
+ * (lib/epic/promptSessionsCreateEpic.cjs) instead of the renderer
2275
2275
  * hand-constructing the PromptSession record itself. Unused today —
2276
2276
  * additive step 1 of a two-PRD chain; a later PRD routes
2277
2277
  * createPromptSession through this. */
2278
2278
  create: (payload: PromptSessionsCreateEpicPayload) => Promise<PromptSessionsCreateEpicResult>;
2279
2279
  /** Creates this Epic's isolated `git worktree` checkout
2280
- * (lib/epicWorktreeMint.cjs) — resolves to the `worktree` field shape on
2280
+ * (lib/epic/epicWorktreeMint.cjs) — resolves to the `worktree` field shape on
2281
2281
  * success, or null on any failure (never rejects). */
2282
2282
  createWorktree: (payload: PromptSessionsCreateWorktreePayload) => Promise<PromptSessionsCreateWorktreeResult | null>;
2283
2283
  /** Folds an Epic's isolated git worktree branch back into its owning
2284
- * project's main tree (lib/epicWorktreeMerge.cjs) — the ONLY point
2284
+ * project's main tree (lib/epic/epicWorktreeMerge.cjs) — the ONLY point
2285
2285
  * where PRD 1033's per-Epic isolation resolves back into the shared
2286
2286
  * tree. Never rejects. */
2287
2287
  mergeToMain: (payload: PromptSessionsMergeToMainPayload) => Promise<PromptSessionsMergeToMainResult>;
@@ -553,12 +553,12 @@ contextBridge.exposeInMainWorld('api', {
553
553
  return () => ipcRenderer.removeListener('promptSession:event-appended', listener);
554
554
  },
555
555
  /** Main-side read-merge-write of a cwd's active-index.json
556
- * (lib/activeIndexMerge.cjs) — replaces persistActiveIndex's old
556
+ * (lib/epic/activeIndexMerge.cjs) — replaces persistActiveIndex's old
557
557
  * renderer-side read-merge-write. Payload carries only this renderer's
558
558
  * own in-memory contribution for the cwd; disk stays main's truth. */
559
559
  mergeActiveIndex: (payload) => ipcRenderer.invoke('promptSessions:merge-active-index', payload),
560
560
  /** Mints a brand-new 'proposed' Epic through main's own ensureEpic()
561
- * (lib/promptSessionsCreateEpic.cjs) instead of the renderer
561
+ * (lib/epic/promptSessionsCreateEpic.cjs) instead of the renderer
562
562
  * hand-constructing the PromptSession record itself. Unused today —
563
563
  * additive step 1 of a two-PRD chain; a later PRD routes
564
564
  * createPromptSession through this. */
@@ -571,7 +571,7 @@ contextBridge.exposeInMainWorld('api', {
571
571
  createWorktree: (payload) => ipcRenderer.invoke('promptSessions:create-worktree', payload),
572
572
  /** Folds an Epic's isolated git worktree branch back into its owning
573
573
  * project's main tree (main-side gitWorktree.cjs's integrateEpicBranch,
574
- * via lib/epicWorktreeMerge.cjs) — the ONLY point where PRD 1033's
574
+ * via lib/epic/epicWorktreeMerge.cjs) — the ONLY point where PRD 1033's
575
575
  * per-Epic isolation resolves back into the shared tree. Never rejects:
576
576
  * resolves `{ ok: true, status: 'merged', integrated }` on a clean
577
577
  * merge (worktree cleaned up), or `{ ok: false, status:
@@ -1,3 +0,0 @@
1
- import{bc as M,aD as d,an as e,a as N,bk as D,W as O,D as P,_ as H,a0 as U}from"./index-CPieAFsl.js";import{b as L,P as k,E as $,R as z,u as W,S as G}from"./useRemotePeers-D4cdJDyh.js";import"./monaco-editor-BsIlgG7c.js";function A(o){return o instanceof Error?o.message:String(o)}function _(o){const i=o.replace(/\/+$/,"").split("/");return i[i.length-1]||o}function V({peerId:o,machineName:i,onOpenTerminal:y}){const c=M(a=>a.show),[x,m]=d.useState([]),[p,w]=d.useState("loading"),[h,E]=d.useState(null),[t,j]=d.useState(""),[C,I]=d.useState(!1),f=d.useRef(0),v=d.useCallback(async()=>{const a=++f.current;w("loading");try{let u;try{const s=await window.api.remoteClient.send(o,"cmd:sessions:list",{});u=Array.isArray(s==null?void 0:s.sessions)?s.sessions:[]}catch{if(a!==f.current)return;const s=await window.api.remoteClient.send(o,"cmd:sessions:load",{});u=(Array.isArray(s==null?void 0:s.tabs)?s.tabs:[]).map(b=>({kind:"project",tabId:b.sessionId,cwd:b.cwd,title:b.label||b.cwd,project:b.label||_(b.cwd)}))}if(a!==f.current)return;m(u),w("ready")}catch(u){if(a!==f.current)return;w("error"),c("error",`Could not load sessions from ${i}: ${A(u)}`)}},[o,i,c]);d.useEffect(()=>(v(),()=>{f.current++}),[v]);const S=d.useMemo(()=>{const a=new Map;for(const s of x){const g=s.project||_(s.cwd);(a.get(g)??a.set(g,[]).get(g)).push(s)}const u=s=>s.kind==="project"?0:1;for(const s of a.values())s.sort((g,b)=>u(g)-u(b));return[...a.entries()].sort((s,g)=>s[0].localeCompare(g[0]))},[x]),n=t.trim(),T=h!==null&&n.length>0&&!C,R=d.useCallback(async()=>{if(!(h===null||t.trim().length===0)){I(!0);try{await window.api.remoteClient.send(o,"cmd:chat:send",{tabId:h,prompt:t}),j("")}catch(a){c("error",`Could not send prompt to ${i}: ${A(a)}`)}finally{I(!1)}}},[o,i,h,t,c]);return e.jsxs("div",{"data-testid":"remote-sessions-panel",className:"flex flex-col gap-3",children:[e.jsx(L,{right:e.jsx(N,{tone:"accent",className:"",title:`Sessions on ${i}`,children:e.jsxs("span",{"data-testid":"remote-sessions-badge",children:["Remote: ",i]})}),children:"Remote sessions"}),e.jsx("div",{className:"flex justify-end",children:e.jsx(k,{icon:"history",testId:"remote-sessions-refresh",onClick:()=>{v()},disabled:p==="loading",children:"Refresh"})}),p==="loading"&&e.jsx($,{testId:"remote-sessions-loading",children:"Loading sessions…"}),p==="error"&&e.jsxs($,{testId:"remote-sessions-error",children:["Could not load sessions from ",i,"."]}),p==="ready"&&x.length===0&&e.jsxs($,{testId:"remote-sessions-empty",children:["No sessions open on ",i,"."]}),p==="ready"&&S.map(([a,u])=>e.jsx("div",{"data-testid":"remote-sessions-group",className:"flex flex-col gap-2",children:u.map(s=>e.jsx(z,{testId:`remote-session-${s.tabId}`,icon:"terminal",title:s.title||s.cwd,subtitle:s.cwd,badge:s.kind==="epic"&&s.tag?e.jsx(N,{tone:"accent",children:s.tag}):void 0,action:e.jsxs("div",{className:"flex items-center gap-2",children:[s.kind==="project"&&y&&e.jsx(k,{icon:"terminal",kind:"ghost",testId:`remote-session-terminal-${s.tabId}`,onClick:()=>y(s.cwd),children:"Terminal here"}),e.jsx(k,{kind:h===s.tabId?"soft":"ghost",testId:`remote-session-select-${s.tabId}`,onClick:()=>E(s.tabId),children:h===s.tabId?"Selected":"Select"})]})},s.tabId))},a)),p==="ready"&&x.length>0&&e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("textarea",{"data-testid":"remote-sessions-prompt",value:t,onChange:a=>j(a.target.value),rows:3,placeholder:h?`Prompt for the selected session on ${i}`:"Select a session first",className:"w-full rounded-lg bg-bg-hi border border-line px-3 py-2 text-[13px] text-fg placeholder:text-fg-faint"}),e.jsx("div",{className:"flex justify-end",children:e.jsx(k,{icon:"play",testId:"remote-sessions-send",onClick:()=>{R()},disabled:!T,children:"Send"})})]})]})}const q=260;function J({peerId:o,machineName:i,cwd:y,onClose:c}){const x=d.useRef(null),m=d.useRef(null),p=M(t=>t.show),[w,h]=d.useState(!1);d.useEffect(()=>{const t=x.current;if(!t)return;const j=crypto.randomUUID();let C=!0,I=!1,f=!1;const v=(r,l)=>{C&&p("error",`Remote terminal ${r} failed: ${l instanceof Error?l.message:String(l)}`)},S=(r,l)=>window.api.remoteClient.send(o,r,l),n=new D.Terminal({fontFamily:'"IBM Plex Mono", JetBrains Mono, ui-monospace, Menlo, monospace',fontSize:P.fontSize,lineHeight:1.2,cursorBlink:!0,allowProposedApi:!0,theme:O[P.theme]}),T=new H.FitAddon;n.loadAddon(T);const R=()=>{if(U(t.clientWidth,t.clientHeight))try{T.fit()}catch{}};n.open(t),R(),n.focus();const a=window.api.remoteClient.onEvent(r=>{if(r.peerId!==o)return;const l=r.payload??{};l.tabId===j&&(r.type==="event:pty:data"?typeof l.data=="string"&&n.write(l.data):r.type==="event:pty:exit"&&(I=!0,n.options.disableStdin=!0,n.write(`\r
2
- \x1B[38;5;240m[remote session exited code=${l.exitCode??"?"}]\x1B[0m\r
3
- `),h(!0)))}),u=n.onData(r=>{I||S("cmd:pty:write",{tabId:j,data:r}).catch(l=>v("write",l))}),s=n.onResize(({cols:r,rows:l})=>{I||S("cmd:pty:resize",{tabId:j,cols:r,rows:l}).catch(F=>v("resize",F))});S("cmd:pty:spawn",{tabId:j,cwd:y,cols:n.cols,rows:n.rows}).catch(r=>v("spawn",r)),m.current=()=>{f||(f=!0,S("cmd:pty:kill",{tabId:j}).catch(r=>v("kill",r)))};const g=()=>R();window.addEventListener("resize",g);const b=new ResizeObserver(()=>R());return b.observe(t),()=>{var r;window.removeEventListener("resize",g),b.disconnect(),a(),u.dispose(),s.dispose(),(r=m.current)==null||r.call(m),m.current=null,C=!1,n.dispose()}},[o,y,p]);const E=()=>{var t;(t=m.current)==null||t.call(m),c()};return e.jsxs("div",{"data-testid":"remote-terminal-panel",className:"bg-bg-hi border border-line rounded-xl overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 px-[18px] pt-3.5 pb-2",children:[e.jsxs("div",{className:"flex items-center gap-2.5 min-w-0",children:[e.jsx(L,{children:"Remote terminal"}),e.jsx(N,{tone:"accent",children:e.jsxs("span",{"data-testid":"remote-terminal-badge",children:["Remote: ",i]})}),w&&e.jsx(N,{tone:"dim",children:"exited"})]}),e.jsx(k,{kind:"ghost",onClick:E,testId:"remote-terminal-close",children:"Close"})]}),e.jsx("div",{ref:x,"data-testid":"remote-terminal-host",className:"w-full bg-bg",style:{height:q}})]})}const X="relay_client_auth_unavailable",K="device_offline",Q={win32:"Windows",darwin:"macOS",linux:"Linux"},B=o=>o?Q[o]??o:"OS unknown";function Y({peers:o,selectedId:i,onSelect:y}){return e.jsxs("div",{className:"w-[240px] shrink-0 border-r border-line p-3 space-y-2 overflow-y-auto","data-testid":"remote-view-switcher",children:[e.jsx(L,{children:"Machines"}),o.map(c=>{const x=c.status==="authenticated";return e.jsxs("button",{type:"button","data-testid":"remote-view-machine","aria-pressed":c.peerId===i,onClick:()=>y(c.peerId),className:`w-full text-left rounded-lg border px-3 py-2 transition-colors ${c.peerId===i?"bg-bg-hi border-accent/40":"bg-bg border-line hover:bg-bg-hi"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-fg truncate",children:c.machineName}),x?e.jsx(N,{tone:"good",children:"online"}):e.jsx(N,{tone:"dim",children:"offline"})]}),e.jsx("div",{className:"text-[11.5px] text-fg-faint",children:B(c.os)})]},c.peerId)})]})}function se({onOpenSettings:o}){const{peers:i,connect:y,confirmSas:c}=W(),[x,m]=d.useState(null),[p,w]=d.useState("sessions"),[h,E]=d.useState("");if(i.length===0)return e.jsxs("div",{className:"p-6 space-y-3","data-testid":"remote-view",children:[e.jsx($,{testId:"remote-view-empty",children:"No machines paired yet. Pair a machine in Settings → Phone remote."}),e.jsx(k,{testId:"remote-view-open-settings",onClick:o,children:"Open Settings"})]});const t=i.find(n=>n.peerId===x)??i[0],j=t.status==="authenticated",C=t.status==="failed"&&t.reason===X,I=t.status==="connecting",f=`Remote: ${t.machineName}`,v=n=>{m(n),w("sessions"),E("")},S=n=>{E(n),w("terminal")};return e.jsxs("div",{className:"flex h-full min-h-0","data-testid":"remote-view",children:[e.jsx(Y,{peers:i,selectedId:t.peerId,onSelect:v}),e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col p-4 gap-3 overflow-y-auto",children:[e.jsxs("div",{"data-testid":"remote-view-header",className:"flex items-center gap-2.5",children:[e.jsx(N,{tone:"accent",className:"",title:t.peerId,children:e.jsx("span",{"data-testid":"remote-view-header-badge",children:f})}),e.jsx("span",{className:"text-[12.5px] text-fg-faint",children:B(t.os)})]}),t.status==="pending_sas"&&t.sas&&e.jsx(G,{peer:"other machine",testId:"remote-view-sas",code:t.sas,onConfirm:()=>{c(t.peerId)}}),j?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex gap-2 border-b border-line pb-2",children:["sessions","terminal"].map(n=>e.jsxs("button",{type:"button","data-testid":`remote-view-tab-${n}`,onClick:()=>w(n),className:`inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-[13px] font-semibold ${p===n?"bg-bg-hi text-fg border border-line":"text-fg-dim hover:text-fg"}`,children:[n==="sessions"?"Sessions":"Terminal",e.jsx(N,{tone:"accent",children:f})]},n))}),p==="sessions"?e.jsx(V,{peerId:t.peerId,machineName:t.machineName,onOpenTerminal:S},t.peerId):e.jsx(J,{peerId:t.peerId,machineName:t.machineName,cwd:h,onClose:()=>w("sessions")},t.peerId)]}):e.jsxs("div",{className:"space-y-2","data-testid":"remote-view-offline",children:[e.jsx($,{children:C?"The bilko.run relay does not support desktop clients yet":t.reason===K?`${t.machineName} is offline.`:`Not connected to ${t.machineName}.`}),!C&&t.status!=="pending_sas"&&e.jsx(z,{icon:"terminal",title:t.machineName,subtitle:t.peerId,action:e.jsx(k,{testId:"remote-view-connect",disabled:I,onClick:()=>{y(t.peerId)},children:I?"Connecting…":"Connect"})})]})]})]})}export{se as RemoteMachines};
@@ -1 +0,0 @@
1
- import{aD as i,aX as g,an as e,aU as _,b0 as B,al as $,am as I,aQ as V,a4 as z,e as H,h as L,t as D,s as M,l as Q,a9 as X,b1 as q,C as G,n as T,a8 as J}from"./index-CPieAFsl.js";import{P as U}from"./Panel-CQY5zano.js";import{S as K}from"./SaveBar-DjijiUb0.js";import{f as W,V as A}from"./Library-CeF4qh9d.js";import"./monaco-editor-BsIlgG7c.js";import"./Button-DsEYRZg0.js";import"./listSkills-C1aWKf0T.js";const Y=300;function P(t){return t.split("/").pop()||t}function Z({activePath:t,selectedPath:o,onSelect:u}){const[l,a]=i.useState([]),h=i.useRef(0),r=i.useRef(u);r.current=u;const y=g(n=>{var d;return t?(d=n.files[t])==null?void 0:d.diskRaw:void 0}),f=i.useRef(null);if(i.useEffect(()=>{r.current(null)},[t]),i.useEffect(()=>{if(h.current+=1,!t){f.current=null,a([]);return}const n=f.current!==t;f.current=t;let d=!1;const m=()=>{h.current+=1;const b=h.current;window.api.config.parseImports(t).then(v=>{d||h.current!==b||(v.ok?a(v.imports):(a([]),_.error(v.error||"failed to parse @-imports")))})},j=n?null:setTimeout(m,Y);return n&&m(),()=>{d=!0,j&&clearTimeout(j)}},[t,y]),l.length===0||!t)return null;const x=o===t||o===null;return e.jsxs("div",{className:"w-64 shrink-0 border-r border-line bg-bg-elev overflow-auto","data-testid":"referenced-files-rail",children:[e.jsxs("div",{className:"px-3 py-2 text-[10px] uppercase tracking-wide text-fg-faint border-b border-line",children:["Documents · ",l.length+1]}),e.jsxs("button",{type:"button",onClick:()=>u(null),"aria-current":x,"data-testid":"referenced-file-root",className:`w-full text-left px-3 py-2 border-b border-line ${x?"bg-bg-hi text-fg":"text-fg-dim hover:bg-bg"}`,children:[e.jsx("div",{className:"text-[11.5px] font-medium truncate",children:P(t)}),e.jsx("div",{className:"text-[10px] text-fg-faint truncate",title:t,children:"this system prompt"})]}),l.map(n=>{const d=!n.ok||!n.exists,m=o===n.path;return e.jsxs("button",{type:"button",onClick:()=>u(n),"aria-current":m,"data-testid":"referenced-file-row",className:`w-full text-left px-3 py-2 border-b border-line last:border-b-0 ${m?"bg-bg-hi text-fg":"text-fg-dim hover:bg-bg"}`,children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-[11.5px] font-medium truncate flex-1",children:P(n.path)}),d&&e.jsx("span",{className:"shrink-0 px-1.5 py-0.5 rounded text-[9px] uppercase tracking-wide text-amber-400/90 border border-amber-400/30","data-testid":"referenced-file-missing",children:"missing"})]}),e.jsx("div",{className:"text-[10px] text-fg-faint truncate",title:n.path,children:n.path}),e.jsxs("div",{className:"text-[10px] text-fg-faint",children:[n.sizeBytes.toLocaleString()," bytes · ~",n.tokenEstimate.toLocaleString()," tokens"]})]},n.path)})]})}function F(t){return t.split("/").filter(Boolean).pop()||t}function ee({path:t,value:o,onChange:u,onSave:l,readOnly:a,defaultMode:h,headerRight:r,hideStatusBar:y}){const f=B(),x=$(t),n=I(t),d=V(t),[m,j]=i.useState(()=>a&&n?"preview":h??z(t)),[b,v]=i.useState(!0),[w,R]=i.useState(null),E=i.useRef(null),c=i.useRef(null),k=i.useCallback(s=>{E.current=s},[]),S=i.useCallback(()=>E.current,[]),C=a?n?["preview","edit"]:[]:d?["edit","preview","split"]:n?["edit","preview"]:[],p=n?m:"edit",N=e.jsx(H,{path:t,name:F(t),value:o,onChange:u,onSave:()=>l==null?void 0:l(),onReady:k,onCursor:R,readOnly:a});return e.jsxs("div",{className:"flex flex-col h-full min-h-0","data-testid":"document-editor-pane",children:[e.jsxs("div",{className:"flex items-center gap-1 px-2 h-7 shrink-0 border-b border-line bg-bg-elev",children:[e.jsx("span",{className:"text-[11px] font-medium text-fg truncate",children:F(t)}),a&&e.jsx("span",{className:"ml-1 px-1.5 py-0.5 rounded text-[9px] uppercase tracking-wide text-fg-faint border border-line",children:"read-only"}),e.jsx("div",{className:"flex-1"}),r,x&&(p==="preview"||p==="split")&&e.jsx("button",{onClick:()=>v(s=>!s),"data-testid":"document-outline-toggle",className:`px-2 py-0.5 text-[10px] border border-line rounded ${b?"bg-bg-hi text-fg":"text-fg-faint hover:text-fg"}`,title:"Toggle document outline",children:"Outline"}),C.length>0&&e.jsx("div",{className:"flex items-center ml-1 rounded border border-line overflow-hidden","data-testid":"document-mode-toggle",children:C.map(s=>e.jsx("button",{onClick:()=>j(s),className:`px-2 py-0.5 text-[10px] capitalize transition-colors ${p===s?"bg-bg-hi text-fg":"text-fg-faint hover:text-fg"}`,children:s},s))})]}),e.jsx("div",{className:"flex-1 min-h-0",children:p==="split"&&x?e.jsxs("div",{className:"flex h-full",children:[b&&e.jsx(L,{text:o,scrollRef:c}),e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col border-r border-line",children:[!a&&e.jsx(D,{getEditor:S}),e.jsx("div",{className:"flex-1 min-h-0",children:N})]}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(M,{ref:c,text:o,flush:!0,wideMeasure:f.wideMeasure})})]}):p==="preview"&&x?e.jsxs("div",{className:"flex h-full",children:[b&&e.jsx(L,{text:o,scrollRef:c}),e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(M,{ref:c,text:o,wideMeasure:f.wideMeasure})})]}):x?e.jsxs("div",{className:"flex flex-col h-full",children:[!a&&e.jsx(D,{getEditor:S}),e.jsx("div",{className:"flex-1 min-h-0",children:N})]}):N}),!y&&e.jsx(Q,{text:o,cursor:w,language:X(t)||void 0})]})}const O={title:"User system prompt",body:"This is the real ~/.claude/CLAUDE.md on disk — the instructions the claude CLI loads into every session it starts on this machine, in every project. A project's own CLAUDE.md / CLAUDE.local.md are read from that project's directory when a session launches there; they are not edited here."};function te(){const t=q(),[o,u]=i.useState("installed"),l=i.useMemo(()=>t?G.resolve("user",t,null):null,[t]),[a,h]=i.useState(null),r=(a==null?void 0:a.path)??l,y=!!a&&(!a.ok||!a.exists),f=g(s=>s.files),x=g(s=>s.loadText),n=g(s=>s.setDraft),d=g(s=>s.saveText),m=g(s=>s.revert),j=g(s=>s.watchFile),b=g(s=>s.unwatchFile);i.useEffect(()=>{if(l)return x(l,!0),j(l),()=>{b(l)}},[l]),i.useEffect(()=>{if(!(!r||r===l))return x(r,!0),j(r),()=>{b(r)}},[r,l]);const[v,w]=i.useState(null),R=i.useCallback(s=>{w(null),h(s)},[]);if(!t)return e.jsx(T,{title:"loading…"});if(o==="library")return e.jsx(U,{toolbar:e.jsx(A,{active:o,onChange:u,installedLabel:"Editor",libraryLabel:"Presets"}),children:e.jsx(W,{})});const E=l?f[l]:null,c=r?f[r]:null,k=(c==null?void 0:c.draftRaw)??"",S=J(k),C=k.length,p=y,N=async()=>{if(!r)return;w(null);const s=await d(r);s.ok||w(s.error??"save failed")};return e.jsx(U,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(A,{active:o,onChange:u,installedLabel:"Editor",libraryLabel:"Presets"}),e.jsx("span",{className:"mx-2 text-fg-faint",children:"·"}),e.jsx("span",{className:"text-fg-dim",children:"User scope"}),e.jsx("span",{className:"ml-3 text-fg-faint truncate",children:r??"—"}),e.jsx("div",{className:"flex-1"}),e.jsxs("span",{className:"text-fg-faint",children:[C.toLocaleString()," chars · ~",S.toLocaleString()," tokens"]})]}),footer:r&&c&&!p?e.jsx(K,{dirty:c.dirty,busy:c.busy,parseError:v,lastSavedAt:c.lastSavedAt,leading:c.exists?a?e.jsx("span",{children:"editing an imported file"}):null:e.jsx("span",{children:"file will be created on save"}),onSave:N,onRevert:()=>{w(null),m(r)}}):null,children:l&&E?e.jsxs("div",{className:"h-full flex flex-col",children:[e.jsxs("div",{"data-testid":"system-prompt-scope-note",className:"shrink-0 border-b border-line bg-bg-elev px-3 py-2 text-[11.5px] leading-snug",children:[e.jsx("span",{className:"font-semibold text-fg",children:O.title}),e.jsx("span",{className:"mx-1.5 text-fg-faint",children:"·"}),e.jsx("span",{className:"text-fg-dim",children:O.body}),e.jsx("span",{className:"ml-1.5 font-mono text-fg-faint",children:l})]}),e.jsxs("div",{className:"flex-1 min-h-0 flex",children:[e.jsx(Z,{activePath:l,selectedPath:r,onSelect:R}),e.jsxs("div",{className:"flex-1 min-w-0 flex flex-col",children:[p&&e.jsx("div",{"data-testid":"system-prompt-missing-note",className:"shrink-0 border-b border-line bg-bg-elev px-3 py-1.5 text-[11px] text-amber-400/90",children:"This import does not resolve to a readable file — the CLI will skip it."}),r&&e.jsx("div",{className:"flex-1 min-h-0",children:e.jsx(ee,{path:r,value:k,readOnly:p,defaultMode:"split",onChange:s=>{w(null),n(r,s)},onSave:()=>{N()}},r)})]})]})]}):e.jsx(T,{title:"resolving…"})})}const ce=i.memo(te);export{ce as SystemPrompt};
@@ -1 +0,0 @@
1
- import{aD as r,V as p,an as e,n as k,aT as w,aU as b,$ as y}from"./index-CPieAFsl.js";import{P}from"./Panel-CQY5zano.js";import{L as $}from"./ListDetail-DcfmxPFk.js";import{u as E,a as v,t as N}from"./useAgentsDirWatch-DCu6BNYN.js";import"./monaco-editor-BsIlgG7c.js";function S(){const[s,i]=r.useState(p[0].tag),[l,g]=r.useState(null),[h,x]=r.useState(!1),c=r.useRef(!0);r.useEffect(()=>()=>{c.current=!1},[]);const f=r.useRef(0),o=async()=>{const t=++f.current;try{const n=await window.api.agents.listPersonas();c.current&&f.current===t&&g(n)}catch(n){if(!c.current||f.current!==t)return;g([]),b.error(n.message||"failed to load agent personas")}};r.useEffect(()=>{o()},[]),r.useEffect(()=>window.api.agents.onChanged(()=>o()),[]),E(null,()=>o());const m=p.find(t=>t.tag===s)??null,a=async(t,n)=>{try{await window.api.agents.savePersona(v(t,{tags:N([...t.tags,n])})),x(!1),await o()}catch(d){b.error(d.message||"failed to assign tag")}},u=async(t,n)=>{try{await window.api.agents.savePersona(v(t,{tags:N(t.tags.filter(d=>d!==n))})),await o()}catch(d){b.error(d.message||"failed to remove tag")}};return e.jsx(P,{toolbar:e.jsxs("span",{className:"text-fg-faint",children:[p.length," tag",p.length===1?"":"s"]}),children:e.jsx($,{sidebar:e.jsx("div",{className:"py-1",children:p.map(t=>{const n=w(t.tag),d=s===t.tag,j=(l==null?void 0:l.filter(T=>T.tags.includes(t.tag)).length)??0;return e.jsxs("button",{onClick:()=>{i(t.tag),x(!1)},className:`w-full text-left px-3 py-1.5 text-xs flex items-center gap-2 border-l-2 ${d?"bg-bg-hi text-fg border-accent":"text-fg-dim hover:text-fg hover:bg-bg-hi border-transparent"}`,children:[e.jsxs("span",{className:`px-1.5 py-0.5 rounded text-[10px] font-mono font-semibold ${n.bg} ${n.text} ${n.border?"border border-current/30":""}`,children:["#",t.tag]}),e.jsx("span",{className:"truncate",children:t.label}),j>0&&e.jsx("span",{className:"ml-auto text-[10.5px] text-fg-faint font-mono shrink-0",children:j})]},t.tag)})}),detail:m?e.jsx(C,{entry:m,personas:l,adding:h,setAdding:x,onAssign:a,onUnassign:u}):e.jsx(k,{title:"select a tag"})})})}const q=r.memo(S);function C({entry:s,personas:i,adding:l,setAdding:g,onAssign:h,onUnassign:x}){const c=w(s.tag),f=y(s.tag),o=(i==null?void 0:i.filter(a=>a.tags.includes(s.tag)))??[],m=(i==null?void 0:i.filter(a=>!a.tags.includes(s.tag)))??[];return e.jsxs("div",{className:"p-4 space-y-4 max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsxs("span",{className:`px-2 py-1 rounded text-xs font-mono font-semibold ${c.bg} ${c.text} ${c.border?"border border-current/30":""}`,children:["#",s.tag]}),e.jsx("span",{className:"text-sm font-semibold text-fg",children:s.label})]}),e.jsx("div",{className:"text-xs text-fg-dim leading-relaxed",children:s.description}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10.5px] uppercase tracking-wide text-fg-faint mb-1.5 font-mono",children:"/develop eagerness"}),e.jsx("span",{className:"px-1.5 py-0.5 text-[10px] rounded border border-line text-fg-dim font-mono",children:s.developEagerness})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10.5px] uppercase tracking-wide text-fg-faint mb-1.5 font-mono",children:"develops via"}),e.jsx("span",{className:"px-1.5 py-0.5 text-[10px] rounded border border-line text-fg-dim font-mono",children:s.developsVia})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10.5px] uppercase tracking-wide text-fg-faint mb-1.5 font-mono",children:"agents carrying this tag"}),i===null?e.jsx("div",{className:"text-xs text-fg-faint italic",children:"loading…"}):e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[o.map(a=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 bg-bg-elev border border-line rounded px-2 py-0.5 text-[11px] font-mono text-fg-dim",children:[a.name,e.jsx("button",{onClick:()=>x(a,s.tag),title:"Remove this tag from the agent",className:"text-fg-faint hover:text-fg",children:"×"})]},a.name)),o.length===0&&!l&&e.jsx("span",{className:"text-xs text-fg-faint italic mr-1",children:"no agent carries this tag yet."}),l?m.length>0?e.jsxs("select",{autoFocus:!0,defaultValue:"",onChange:a=>{const u=i.find(t=>t.name===a.target.value);u&&h(u,s.tag)},onBlur:()=>g(!1),className:"bg-bg border border-line rounded px-2 py-0.5 text-[11px] text-fg font-mono",children:[e.jsx("option",{value:"",disabled:!0,children:"pick an agent…"}),m.map(a=>e.jsx("option",{value:a.name,children:a.name},a.name))]}):e.jsx("span",{className:"text-xs text-fg-faint italic",children:"every agent already carries this tag."}):e.jsx("button",{onClick:()=>g(!0),className:"px-2 py-0.5 rounded-full text-[11px] font-mono border border-line text-fg-faint hover:text-fg hover:bg-bg-hi",children:"+ assign agent"})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-[10.5px] uppercase tracking-wide text-fg-faint mb-1.5 font-mono",children:"opening framing — sent before the human's goal"}),e.jsx("pre",{className:"text-xs text-fg-dim whitespace-pre-wrap bg-bg-elev border border-line rounded p-3 leading-relaxed font-sans",children:f.initialPromptTemplate})]})]})}export{q as TagLibrary};
@@ -1 +0,0 @@
1
- import{an as r}from"./index-CPieAFsl.js";function a({checked:t,onChange:e,label:s,disabled:n}){return r.jsxs("label",{className:`inline-flex items-center gap-2 text-xs ${n?"opacity-50 cursor-not-allowed":"cursor-pointer"}`,children:[r.jsx("button",{type:"button",role:"switch","aria-checked":t,disabled:n,onClick:()=>!n&&e(!t),className:`relative w-7 h-4 rounded-full transition-colors ${t?"bg-accent":"bg-bg-hi border border-line"}`,children:r.jsx("span",{className:`absolute top-0.5 w-3 h-3 rounded-full bg-fg transition-transform ${t?"translate-x-3.5":"translate-x-0.5"}`})}),s&&r.jsx("span",{className:"text-fg-dim",children:s})]})}export{a as T};
@@ -1,39 +0,0 @@
1
- ---
2
- name: blog-for-project-feature:select
3
- description: Step 0 of blog-for-project-feature — confirm exactly ONE project and ONE feature to showcase. Only asks the user when the feature genuinely can't be inferred; otherwise picks the most demo-worthy recently-shipped feature and states why.
4
- ---
5
-
6
- # blog-for-project-feature:select
7
-
8
- ## Input
9
- - The project: current working directory's repo, or a project name/path explicitly given by
10
- the caller.
11
- - Optional: a feature name or hint from the caller ("showcase the click-run screen", "the new
12
- ticker-tracker queue").
13
-
14
- ## Steps
15
-
16
- 1. **Confirm the project.** Read its root `CLAUDE.md`/`README.md`/`AGENTS.md` (whichever
17
- exists) to confirm you're pointed at a real, buildable/runnable project — not an empty or
18
- scaffold-only repo.
19
-
20
- 2. **If a feature was named**, confirm it exists: grep for it in code, routes, or docs. If it
21
- doesn't resolve to anything real, say so and stop rather than guessing at a nearby feature.
22
-
23
- 3. **If no feature was named**, pick one:
24
- - Prefer something with a real UI surface (a screen, a flow, a page) — this skill's whole
25
- value is a click-through demo, so a pure-backend/CLI-only feature is a weak fit unless the
26
- project exposes it through a dashboard.
27
- - Prefer recently shipped (`git log --oneline -20` on the relevant paths) over long-stable —
28
- showcases are most useful for things a reader hasn't seen yet.
29
- - Prefer one coherent flow over a grab-bag of unrelated changes — this produces ONE feature
30
- page, not a changelog.
31
-
32
- 4. **State the justification** in one or two sentences: what the feature is, why it's the right
33
- one to demo right now.
34
-
35
- ## Output
36
-
37
- Hand off to `:research`: confirmed project (path/repo), confirmed feature name, one-line
38
- justification. If no confirmable feature exists, **STOP** and report why instead of forcing a
39
- pick.
@@ -1,37 +0,0 @@
1
- ---
2
- name: blog-for-project-feature:research
3
- description: Step 1 of blog-for-project-feature — ground the project's mission/description and the confirmed feature's description in real docs and code, before any HTML gets written. Flags gaps explicitly instead of inventing claims.
4
- ---
5
-
6
- # blog-for-project-feature:research
7
-
8
- ## Input
9
- Confirmed project + confirmed feature name + justification, from `:select`.
10
-
11
- ## Steps
12
-
13
- 1. **Project mission & description.** Pull from the project's own root docs (`README.md`,
14
- `CLAUDE.md`'s "What this project is" section if it has one, `package.json`/`pyproject.toml`
15
- description field as a fallback). 2-4 sentences, in the project's own words where possible —
16
- don't invent a mission statement it doesn't already have.
17
-
18
- 2. **Feature description.** Locate the actual entry point(s) — route, component, CLI command,
19
- pipeline — and read enough of the real implementation to describe, in plain language:
20
- - what it does (user-facing behavior, not implementation detail)
21
- - why it matters (what it replaces, what it makes possible)
22
- - any real constraint worth knowing (auth required, feature-flagged, still in beta) — surface
23
- these rather than smoothing them over
24
-
25
- 3. **Identify the demo surface.** Note exact URLs/routes, the commands needed to run the app
26
- locally, any seed data / login required to reach the feature — `:storyboard` and `:capture`
27
- need this to actually drive the app.
28
-
29
- 4. **Flag gaps.** If the mission statement doesn't exist, or the feature's purpose isn't
30
- evident from code/docs, say so explicitly in the output rather than filling it in with
31
- plausible-sounding marketing language.
32
-
33
- ## Output
34
-
35
- Hand off to `:storyboard`: mission/description (2-4 sentences), feature description (what/why/
36
- constraints), demo surface (routes, run command, any setup needed to reach the feature), and any
37
- flagged gaps.