chainlesschain 0.162.130 → 0.162.132

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 (168) hide show
  1. package/README.md +12 -3
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-DlBanM-D.js → AIOps-C3EMV_C8.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-yoBaBWJy.js → ActionButton-BnChvwOT.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BmrOyYD0.js → Analytics-4qJF0UgZ.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-GFuM9A3X.js → AppLayout-BNvZIVu2.js} +5 -5
  8. package/src/assets/web-panel/assets/Audit-XK9SNjI1.js +1 -0
  9. package/src/assets/web-panel/assets/Backup-DpG3a6_C.js +1 -0
  10. package/src/assets/web-panel/assets/{BaseInput-Be6KNmhp.js → BaseInput-DRFAaZU4.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DwsFF4yj.js → Chat-BBx7bBGe.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-BBiURq4R.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-CJMgWRaw.js → Checkbox-MSz5cYJs.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DmUTxgww.js → Codegen-IYShumwd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-DKiqcZD4.js → Col-Bmv6mthP.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DwkBuQJ9.js → Community-CHeLo7dI.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-ClnINh4j.js → Compact-BkJNQs7E.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CiT8aABn.js → Compliance-C25JJC2u.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-CSdl80o1.js → Cowork-Dla0k0Ww.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-EpM2_dN5.js → Cron-DGkuHZUa.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-D0k0wjwX.js → Crosschain-cX_-njSd.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-CC4U6GEI.js → DID-BKS-omUL.js} +2 -2
  23. package/src/assets/web-panel/assets/Dashboard-BoFR9biz.js +3 -0
  24. package/src/assets/web-panel/assets/{Dropdown-z6Y524uk.js → Dropdown-Cmpq1SBD.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-Bs_NxIAQ.js → EmailListRenderer-DyJhg_Vk.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BdMikomZ.js → FamilyGuardDashboard-B0MWkRfs.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BaBybFmU.js → Federation-po5WbpBo.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-bOifggcW.js → FormItemContext-w8jmOFY0.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BEhi1SaZ.js → GenericCardRenderer-C8x1Xukd.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BoISA30j.js → Git-DRHr1S-_.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-D8XZcZmr.js → Governance-DS24dY8i.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-DF0zfQ35.js → Inference-BLg0DmZ-.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-Bx28A0s9.js → KnowledgeGraph-DhKarFuO.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CxP6elqM.js → Logs-DJEThUCf.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-BhyVR9xn.js → Marketplace-DEyDcNY0.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-TYU8DcM5.js → McpTools-BFmO9TXt.js} +3 -3
  37. package/src/assets/web-panel/assets/{Memory-UDwDvKuv.js → Memory-C1JB4k5K.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-DEa4DTPm.js → MobileBridge-B5gsBjMt.js} +1 -1
  39. package/src/assets/web-panel/assets/{MobileProjects-BU-T_VO4.js → MobileProjects-DdmW0Pq3.js} +1 -1
  40. package/src/assets/web-panel/assets/{Mtc-hYAzBWQi.js → Mtc-fUpipvt9.js} +5 -5
  41. package/src/assets/web-panel/assets/{MtcAudit-0417bzil.js → MtcAudit-B3dAe-X-.js} +2 -2
  42. package/src/assets/web-panel/assets/{Multisig-C8mNrESc.js → Multisig-Ck0yvwfE.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-Cq73NSD-.js → NLProgramming-KkotDdq3.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-CuyXdYfG.js → Notes-DpYODayK.js} +3 -3
  45. package/src/assets/web-panel/assets/{NotificationSettings-4dP5jtLG.js → NotificationSettings-M5iEaYts.js} +1 -1
  46. package/src/assets/web-panel/assets/OrderTableRenderer-BVcICQBo.js +1 -0
  47. package/src/assets/web-panel/assets/{Organization-DM8-EgzR.js → Organization-EyZ6nhjD.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-B9pMMIE8.js → Overflow-yvn3oxJl.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-CNxt3m8G.js → P2P-B0GwW04x.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-BbppiJQa.js → PdhVaultBrowser-0Cm-xe1W.js} +5 -5
  51. package/src/assets/web-panel/assets/{Permissions-CkbU4k5w.js → Permissions-CWtOiGDk.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-CTP1cWxo.js → PersonalDataHub-BrU4PqRW.js} +2 -2
  53. package/src/assets/web-panel/assets/{Pipeline-DOXykOA8.js → Pipeline-BeZNtjqS.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-BWrp8ZRY.js → Privacy-DFLhKDT4.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-B6OQPTTl.js → ProjectInit-7P8fYCPr.js} +2 -2
  56. package/src/assets/web-panel/assets/{ProjectSettings-CYu0yAVQ.js → ProjectSettings-rGtMRQ0z.js} +2 -2
  57. package/src/assets/web-panel/assets/{Projects-Dcu-tF8M.js → Projects-UMCUiwar.js} +1 -1
  58. package/src/assets/web-panel/assets/{Providers-mR6PwgKV.js → Providers-DyjvkuWD.js} +1 -1
  59. package/src/assets/web-panel/assets/{QuickAsk-EWtGuBnr.js → QuickAsk-Bkm8QioD.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-YKMSZwfC.js → Recommend-Br1CiFuH.js} +1 -1
  61. package/src/assets/web-panel/assets/{Reputation-yK5aobGy.js → Reputation-BEFYjLix.js} +1 -1
  62. package/src/assets/web-panel/assets/{Row-D1s181ke.js → Row-D3CZf-GP.js} +1 -1
  63. package/src/assets/web-panel/assets/RssFeed-eRS7lVjf.js +3 -0
  64. package/src/assets/web-panel/assets/{Search-CN4DO-B5.js → Search-VvFALPmV.js} +1 -1
  65. package/src/assets/web-panel/assets/{Security-DU7zt02X.js → Security-D1WEaJQi.js} +4 -4
  66. package/src/assets/web-panel/assets/{Services-ithSFJ8m.js → Services-ChKY66HU.js} +2 -2
  67. package/src/assets/web-panel/assets/{Skeleton-AdnDEpv-.js → Skeleton-FNnDIIwx.js} +1 -1
  68. package/src/assets/web-panel/assets/{Skills-DbzSM7vB.js → Skills-mK0_kv2B.js} +1 -1
  69. package/src/assets/web-panel/assets/{Sla-DX54_u0l.js → Sla-DIi5A7gn.js} +1 -1
  70. package/src/assets/web-panel/assets/{SpeechSettings-CRHZuDqy.js → SpeechSettings-Sc1lCVFY.js} +1 -1
  71. package/src/assets/web-panel/assets/{SyncSettings-DbFnDg_K.js → SyncSettings-B2hi5KhL.js} +2 -2
  72. package/src/assets/web-panel/assets/{Tasks-Dhsmw2CQ.js → Tasks-Bk4qH2Fh.js} +1 -1
  73. package/src/assets/web-panel/assets/{Templates-DeBl9D2A.js → Templates-F6_MGKtm.js} +1 -1
  74. package/src/assets/web-panel/assets/{Tenant-CF-RiJ0g.js → Tenant-016H5VNi.js} +1 -1
  75. package/src/assets/web-panel/assets/{Terminal-_66-j6JZ.js → Terminal-CfDOP3qx.js} +2 -2
  76. package/src/assets/web-panel/assets/TimelineRenderer-cScSUp9s.js +1 -0
  77. package/src/assets/web-panel/assets/{Tokens-Bv1_BfYT.js → Tokens-BBorZAWd.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trigger-CCYW_wGy.js → Trigger-Bw6PqkhA.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trust-C8NW132a.js → Trust-DrwSI5ES.js} +1 -1
  80. package/src/assets/web-panel/assets/{UkeySign-C4VPSFe9.js → UkeySign-BcTNMCvx.js} +1 -1
  81. package/src/assets/web-panel/assets/{VideoEditing-1zzclNfS.js → VideoEditing-DegU0PBJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Wallet-DafZQtOh.js → Wallet-Dag7x_Lu.js} +4 -4
  83. package/src/assets/web-panel/assets/{WebAuthn-we7YNPUy.js → WebAuthn-BZNuN4K8.js} +5 -5
  84. package/src/assets/web-panel/assets/{WorkflowEditor-C0ufqV_h.js → WorkflowEditor-Bg640TSc.js} +1 -1
  85. package/src/assets/web-panel/assets/{chat-D-OyV5Td.js → chat-BGl_G5G0.js} +1 -1
  86. package/src/assets/web-panel/assets/{colors-DfY_daVD.js → colors-BkWmah_5.js} +1 -1
  87. package/src/assets/web-panel/assets/{compact-item-BZGEQaH7.js → compact-item-D4VOkMUL.js} +1 -1
  88. package/src/assets/web-panel/assets/{createContext-Ha9KgHfb.js → createContext-ChPtvrwq.js} +1 -1
  89. package/src/assets/web-panel/assets/devWarning-Cw_2FlQ9.js +1 -0
  90. package/src/assets/web-panel/assets/{hasIn-DGcsqYDb.js → hasIn-Cw0H6G0n.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-BhX3LQ5F.js → index--xcO8suF.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-CLAWGH1Z.js → index-5CPgvuH8.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DMggRtTA.js → index-9wpIl6bu.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-i7FGX3Og.js → index-B6BPVZR9.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-C4PD8V1s.js → index-BCCYbwmv.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DiHUtyKj.js → index-BDruxhx0.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BCDaH6SF.js → index-BF1vTqzW.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CZ18sJL-.js → index-BVbkWEOb.js} +3 -3
  99. package/src/assets/web-panel/assets/{index-DNHsZmjx.js → index-BoDZA6sR.js} +2 -2
  100. package/src/assets/web-panel/assets/{index-Cn6dP-P7.js → index-C1-3BSVH.js} +1 -1
  101. package/src/assets/web-panel/assets/index-C4TtP0Q2.js +1 -0
  102. package/src/assets/web-panel/assets/index-CN8GZ9VU.js +1 -0
  103. package/src/assets/web-panel/assets/{index-DvCAWCE_.js → index-COKpurFE.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CCMhrAQQ.js → index-CRVNn7el.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CaQ_9au2.js → index-CVy9ZQAd.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DYnWmaCw.js → index-CZ2lHEaO.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DihK8yMW.js → index-CbxmVBWd.js} +1 -1
  108. package/src/assets/web-panel/assets/{index--WXQ2y49.js → index-CiNzQzee.js} +2 -2
  109. package/src/assets/web-panel/assets/{index-DZU8HRgG.js → index-CkFRK11e.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-BsdgGEmW.js → index-DAQfL1Hk.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BvJxHGRq.js → index-DID2JJeq.js} +3 -3
  112. package/src/assets/web-panel/assets/{index-B6Lk_-uR.js → index-DMQAaKMl.js} +1 -1
  113. package/src/assets/web-panel/assets/index-DY2piSG3.js +1 -0
  114. package/src/assets/web-panel/assets/{index-Da-1E5Dk.js → index-DdRGzy8K.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CcaG1Gci.js → index-DfrKyB8I.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CNRFSxql.js → index-DiulGuu1.js} +2 -2
  117. package/src/assets/web-panel/assets/{index-C5t-g1rX.js → index-DkBdCDhe.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-ybjPuUmk.js → index-DpsGRdPj.js} +2 -2
  119. package/src/assets/web-panel/assets/{index-DN6Qj7JH.js → index-Dr_gyRsu.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BDDEWfQx.js → index-Dsz0YyEu.js} +1 -1
  121. package/src/assets/web-panel/assets/index-Du5E0dEZ.js +1 -0
  122. package/src/assets/web-panel/assets/{index-D8304Ulf.js → index-DzQrazEI.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-gTYJ-BfG.js → index-PiXVtyKZ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-LODjH1N_.js → index-WZR0xDpN.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CiPMeSUC.js → index-Ywxbu_wi.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-42LImEfZ.js → index-aOagfVdp.js} +4 -4
  127. package/src/assets/web-panel/assets/{index-C5Jgl_3A.js → index-jQd5N7FE.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BvhP7rmX.js → index-oiwK8eXM.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CCWbpajj.js → index-rYUU9e_x.js} +2 -2
  130. package/src/assets/web-panel/assets/{initDefaultProps-B5HHTM2M.js → initDefaultProps-CUw6waFC.js} +1 -1
  131. package/src/assets/web-panel/assets/{motion-BGMk0sIO.js → motion-TZ6CfWYP.js} +2 -2
  132. package/src/assets/web-panel/assets/{move-5FLoyfX1.js → move-Br-sZYQi.js} +1 -1
  133. package/src/assets/web-panel/assets/{mtc-parser-DJl_jRfZ.js → mtc-parser-CgXn9cD3.js} +1 -1
  134. package/src/assets/web-panel/assets/{omit-Db-_WlEN.js → omit-CUwPDHNv.js} +1 -1
  135. package/src/assets/web-panel/assets/{pickAttrs-DsZsLkAT.js → pickAttrs-Bt8vtkVp.js} +1 -1
  136. package/src/assets/web-panel/assets/{placementArrow-M5UE9Uuc.js → placementArrow-CuhrIGfZ.js} +1 -1
  137. package/src/assets/web-panel/assets/{responsiveObserve-c4k_3oW2.js → responsiveObserve-CrXOALdo.js} +1 -1
  138. package/src/assets/web-panel/assets/{slide-Bk5r7ti1.js → slide-vvlw8CYg.js} +1 -1
  139. package/src/assets/web-panel/assets/{statusUtils-CKIS5RY_.js → statusUtils-BJHl-aZk.js} +1 -1
  140. package/src/assets/web-panel/assets/{styleChecker-BYIaM5uH.js → styleChecker-CnA7jour.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFlexGapSupport-CcjrBzHi.js → useFlexGapSupport-Da6VMAbW.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFs-CkMOMjsE.js → useFs-Ca-gj7Dy.js} +1 -1
  143. package/src/assets/web-panel/assets/{usePersonalDataHub-Djl3wiRP.js → usePersonalDataHub-DZvpSTIW.js} +1 -1
  144. package/src/assets/web-panel/assets/{vnode-V3dEKndy.js → vnode-C-BBJHmo.js} +1 -1
  145. package/src/assets/web-panel/assets/{zoom-DroVkKDe.js → zoom-BTSyaEBN.js} +1 -1
  146. package/src/assets/web-panel/index.html +1 -1
  147. package/src/commands/agents.js +15 -28
  148. package/src/lib/agents.js +57 -0
  149. package/src/repl/add-dir.js +73 -0
  150. package/src/repl/agent-repl.js +311 -1
  151. package/src/repl/agents-status.js +122 -0
  152. package/src/repl/hooks-status.js +67 -0
  153. package/src/repl/pr-comments.js +197 -0
  154. package/src/repl/release-notes.js +29 -0
  155. package/src/repl/status-summary.js +33 -0
  156. package/src/repl/todos-status.js +65 -0
  157. package/src/assets/web-panel/assets/Audit-XknQ2_0O.js +0 -1
  158. package/src/assets/web-panel/assets/Backup-B1iEUtGw.js +0 -1
  159. package/src/assets/web-panel/assets/ChatBubbleRenderer-Dw1_CWh4.js +0 -1
  160. package/src/assets/web-panel/assets/Dashboard-CxHIpA4F.js +0 -3
  161. package/src/assets/web-panel/assets/OrderTableRenderer-BlFX_WW9.js +0 -1
  162. package/src/assets/web-panel/assets/RssFeed-DVoFZ5kC.js +0 -3
  163. package/src/assets/web-panel/assets/TimelineRenderer-9RbokKX3.js +0 -1
  164. package/src/assets/web-panel/assets/devWarning-CnWCtTRg.js +0 -1
  165. package/src/assets/web-panel/assets/index-35rCdAfK.js +0 -1
  166. package/src/assets/web-panel/assets/index-BdYrVSXl.js +0 -1
  167. package/src/assets/web-panel/assets/index-DN16qFHw.js +0 -1
  168. package/src/assets/web-panel/assets/index-Dw0NH-KM.js +0 -1
@@ -686,7 +686,9 @@ export async function startAgentRepl(options = {}) {
686
686
  // --system-prompt replaces the built-in prompt; --append-system-prompt
687
687
  // extends it (parity with the headless runners). The base is kept so an
688
688
  // output-style persona can be swapped in/out at runtime via /output-style.
689
- const _replBaseSystem = composeSystemPrompt(
689
+ // `let` (not const): /add-dir rebuilds this mid-session to re-advertise the
690
+ // updated working roots; output-style swaps also read it live.
691
+ let _replBaseSystem = composeSystemPrompt(
690
692
  buildSystemPrompt(process.cwd(), { additionalDirectories }),
691
693
  {
692
694
  systemPrompt: options.systemPrompt,
@@ -1035,6 +1037,8 @@ export async function startAgentRepl(options = {}) {
1035
1037
  // so it follows `/cd` mid-session.
1036
1038
  // Keep in sync with the rl.on("line") handlers + /help below.
1037
1039
  slashCommands: [
1040
+ "/add-dir",
1041
+ "/agents",
1038
1042
  "/auto",
1039
1043
  "/cd",
1040
1044
  "/clear",
@@ -1048,7 +1052,9 @@ export async function startAgentRepl(options = {}) {
1048
1052
  "/exit",
1049
1053
  "/export",
1050
1054
  "/help",
1055
+ "/hooks",
1051
1056
  "/ide",
1057
+ "/init",
1052
1058
  "/mcp",
1053
1059
  "/memory",
1054
1060
  "/microcompact",
@@ -1056,10 +1062,12 @@ export async function startAgentRepl(options = {}) {
1056
1062
  "/output-style",
1057
1063
  "/permissions",
1058
1064
  "/plan",
1065
+ "/pr-comments",
1059
1066
  "/profile",
1060
1067
  "/provider",
1061
1068
  "/quit",
1062
1069
  "/reindex",
1070
+ "/release-notes",
1063
1071
  "/reload-skills",
1064
1072
  "/review",
1065
1073
  "/rewind",
@@ -1067,6 +1075,7 @@ export async function startAgentRepl(options = {}) {
1067
1075
  "/session",
1068
1076
  "/sessions",
1069
1077
  "/stats",
1078
+ "/status",
1070
1079
  "/statusline",
1071
1080
  "/sub-agents",
1072
1081
  "/task",
@@ -1074,6 +1083,7 @@ export async function startAgentRepl(options = {}) {
1074
1083
  "/terminal-setup",
1075
1084
  "/theme",
1076
1085
  "/think",
1086
+ "/todos",
1077
1087
  "/ultrathink",
1078
1088
  "/vim",
1079
1089
  ],
@@ -1526,9 +1536,18 @@ export async function startAgentRepl(options = {}) {
1526
1536
  logger.log(
1527
1537
  ` ${chalk.cyan("/doctor")} Session health check (provider/key/IDE/MCP/hooks)`,
1528
1538
  );
1539
+ logger.log(
1540
+ ` ${chalk.cyan("/status")} Environment snapshot (version/model/session/cwd/roots/IDE·MCP·hooks)`,
1541
+ );
1542
+ logger.log(
1543
+ ` ${chalk.cyan("/release-notes")} Running version + changelog links + how to upgrade`,
1544
+ );
1529
1545
  logger.log(
1530
1546
  ` ${chalk.cyan("/memory")} Project-memory files loaded (cc.md hierarchy + rules)`,
1531
1547
  );
1548
+ logger.log(
1549
+ ` ${chalk.cyan("/init")} Inventory this folder into a cc.md project-memory file (/init [--force])`,
1550
+ );
1532
1551
  logger.log(
1533
1552
  ` ${chalk.cyan("/context")} Live context-window usage by role`,
1534
1553
  );
@@ -1550,12 +1569,18 @@ export async function startAgentRepl(options = {}) {
1550
1569
  logger.log(
1551
1570
  ` ${chalk.cyan("/cd <dir>")} Change working directory mid-session (completion/memory follow)`,
1552
1571
  );
1572
+ logger.log(
1573
+ ` ${chalk.cyan("/add-dir")} Add an extra working root (/add-dir <dir>; no arg lists roots)`,
1574
+ );
1553
1575
  logger.log(
1554
1576
  ` ${chalk.cyan("/reload-skills")} Re-scan skill layers without restarting`,
1555
1577
  );
1556
1578
  logger.log(
1557
1579
  ` ${chalk.cyan("/review")} Diff-first code review (/review [high] [--security|--simplify] [--fix])`,
1558
1580
  );
1581
+ logger.log(
1582
+ ` ${chalk.cyan("/pr-comments")} Fetch a GitHub PR's comments and address them (/pr-comments [<n>] [--repo o/r]; needs gh)`,
1583
+ );
1559
1584
  logger.log(
1560
1585
  ` ${chalk.cyan("/compact")} Smart compact (importance-based)`,
1561
1586
  );
@@ -1596,18 +1621,27 @@ export async function startAgentRepl(options = {}) {
1596
1621
  ` ${chalk.cyan("/plan approve")} Approve and execute the plan`,
1597
1622
  );
1598
1623
  logger.log(` ${chalk.cyan("/plan reject")} Reject the plan`);
1624
+ logger.log(
1625
+ ` ${chalk.cyan("/agents")} Manage sub-agent definitions (/agents [show|new] <name>; cc agents)`,
1626
+ );
1599
1627
  logger.log(
1600
1628
  ` ${chalk.cyan("/sub-agents")} Show active/completed sub-agents`,
1601
1629
  );
1602
1630
  logger.log(
1603
1631
  ` ${chalk.cyan("/tasks")} Show background shell tasks (kill <id> · kill-all)`,
1604
1632
  );
1633
+ logger.log(
1634
+ ` ${chalk.cyan("/todos")} Show the session TODO list (what the agent tracks with todo_write)`,
1635
+ );
1605
1636
  logger.log(
1606
1637
  ` ${chalk.cyan("/ide")} IDE bridge status (connected editor, tools, or why not)`,
1607
1638
  );
1608
1639
  logger.log(
1609
1640
  ` ${chalk.cyan("/mcp")} MCP server status + tools (/mcp <name> for one server)`,
1610
1641
  );
1642
+ logger.log(
1643
+ ` ${chalk.cyan("/hooks")} Loaded .claude/settings.json hooks (cc hook for observe-only DB hooks)`,
1644
+ );
1611
1645
  logger.log(chalk.bold("\nCapabilities:"));
1612
1646
  logger.log(" Read, write, and edit files");
1613
1647
  logger.log(" Run shell commands (git, npm, etc.)");
@@ -1671,6 +1705,192 @@ export async function startAgentRepl(options = {}) {
1671
1705
  return;
1672
1706
  }
1673
1707
 
1708
+ // `/todos` — the session's TODO list (what the agent tracks with the
1709
+ // todo_write tool). Read-only view; the data lives in todo-manager keyed by
1710
+ // sessionId (same store the tool writes). Claude-Code /todos parity.
1711
+ if (trimmed === "/todos" || trimmed === "/todo") {
1712
+ try {
1713
+ const { getTodos } = await import("../lib/todo-manager.js");
1714
+ const { formatTodos } = await import("./todos-status.js");
1715
+ logger.log("\n" + formatTodos(getTodos(sessionId)) + "\n");
1716
+ } catch (err) {
1717
+ logger.error(chalk.red(`/todos failed: ${err.message}`));
1718
+ }
1719
+ prompt();
1720
+ return;
1721
+ }
1722
+
1723
+ // `/hooks` — the decision-capable .claude/settings.json `hooks` block loaded
1724
+ // for this session (PreToolUse/PostToolUse/…). Observe-only DB hooks
1725
+ // (`cc hook add`) are managed via the `cc hook` CLI. Claude-Code /hooks parity.
1726
+ if (trimmed === "/hooks" || trimmed.startsWith("/hooks ")) {
1727
+ try {
1728
+ const { formatSettingsHooks } = await import("./hooks-status.js");
1729
+ logger.log("\n" + formatSettingsHooks(_settingsHooks) + "\n");
1730
+ } catch (err) {
1731
+ logger.error(chalk.red(`/hooks failed: ${err.message}`));
1732
+ }
1733
+ prompt();
1734
+ return;
1735
+ }
1736
+
1737
+ // `/add-dir [dir]` — add an extra working root mid-session (or, with no
1738
+ // arg, list the current roots). The new root is threaded into every
1739
+ // subsequent turn's options.additionalDirectories (so read/search/edit span
1740
+ // it) and re-advertised in the system prompt. Claude-Code /add-dir parity.
1741
+ if (trimmed === "/add-dir" || trimmed.startsWith("/add-dir ")) {
1742
+ const arg = trimmed.slice("/add-dir".length).trim();
1743
+ try {
1744
+ const { resolveAddDir, formatAddDirRoots } =
1745
+ await import("./add-dir.js");
1746
+ if (!arg) {
1747
+ logger.log(
1748
+ "\n" +
1749
+ formatAddDirRoots(process.cwd(), additionalDirectories) +
1750
+ "\n",
1751
+ );
1752
+ } else {
1753
+ const res = resolveAddDir(arg, {
1754
+ cwd: process.cwd(),
1755
+ existing: additionalDirectories,
1756
+ });
1757
+ if (!res.ok) {
1758
+ logger.log(chalk.yellow(`/add-dir: ${res.reason}`));
1759
+ } else if (res.alreadyPresent) {
1760
+ logger.log(chalk.dim(`Already a working root: ${res.dir}`));
1761
+ } else {
1762
+ additionalDirectories.push(res.dir);
1763
+ // Re-advertise the updated roots in the system prompt; keep the
1764
+ // active output-style body layered on top (same as /output-style).
1765
+ _replBaseSystem = composeSystemPrompt(
1766
+ buildSystemPrompt(process.cwd(), { additionalDirectories }),
1767
+ {
1768
+ systemPrompt: options.systemPrompt,
1769
+ appendSystemPrompt: options.appendSystemPrompt,
1770
+ },
1771
+ );
1772
+ messages[0].content = _activeOutputStyle
1773
+ ? `${_replBaseSystem}\n\n${_activeOutputStyle.body}`
1774
+ : _replBaseSystem;
1775
+ logger.log(chalk.green(`Added working root: ${res.dir}`));
1776
+ }
1777
+ }
1778
+ } catch (err) {
1779
+ logger.error(chalk.red(`/add-dir failed: ${err.message}`));
1780
+ }
1781
+ prompt();
1782
+ return;
1783
+ }
1784
+
1785
+ // `/init [--force]` — inventory the current folder into a cc.md
1786
+ // project-memory file (Claude-Code /init parity). Non-interactive: reuses
1787
+ // the same offline census as `cc init`. Loaded as project context next
1788
+ // session (or inspect with /memory).
1789
+ if (trimmed === "/init" || trimmed.startsWith("/init ")) {
1790
+ const force = /(^|\s)(--force|-f)(\s|$)/.test(trimmed);
1791
+ try {
1792
+ const { inventoryProject, renderMemoryFile } =
1793
+ await import("../lib/project-inventory.js");
1794
+ const initCwd = process.cwd();
1795
+ const target = path.join(initCwd, "cc.md");
1796
+ if (fs.existsSync(target) && !force) {
1797
+ logger.log(
1798
+ chalk.yellow(
1799
+ `cc.md already exists at ${target} — /init --force to overwrite.`,
1800
+ ),
1801
+ );
1802
+ } else {
1803
+ const inv = inventoryProject(initCwd);
1804
+ fs.writeFileSync(target, renderMemoryFile(inv), "utf-8");
1805
+ logger.log(chalk.green(`Generated ${target}`));
1806
+ const langs = (inv.languages || [])
1807
+ .slice(0, 5)
1808
+ .map(([l, n]) => `${l} (${n})`)
1809
+ .join(", ");
1810
+ if (langs) logger.log(chalk.dim(` Languages: ${langs}`));
1811
+ if (inv.packageManager)
1812
+ logger.log(chalk.dim(` Package manager: ${inv.packageManager}`));
1813
+ if (inv.scripts && inv.scripts.length)
1814
+ logger.log(
1815
+ chalk.dim(` Scripts documented: ${inv.scripts.length}`),
1816
+ );
1817
+ logger.log(
1818
+ chalk.dim(
1819
+ " Loaded as project context next session (or /memory to inspect).",
1820
+ ),
1821
+ );
1822
+ }
1823
+ } catch (err) {
1824
+ logger.error(chalk.red(`/init failed: ${err.message}`));
1825
+ }
1826
+ prompt();
1827
+ return;
1828
+ }
1829
+
1830
+ // `/agents [list|show <name>|new <name> …]` — manage sub-agent DEFINITIONS
1831
+ // (.chainlesschain/agents/*.md / .claude/agents/*.md). Mirrors `cc agents`;
1832
+ // distinct from /sub-agents (running instances). Claude-Code /agents parity.
1833
+ if (trimmed === "/agents" || trimmed.startsWith("/agents ")) {
1834
+ try {
1835
+ const { parseAgentsCommand, formatAgentsList, formatAgentDetail } =
1836
+ await import("./agents-status.js");
1837
+ const { discoverAgents, getAgent, scaffoldAgent } =
1838
+ await import("../lib/agents.js");
1839
+ const { listSubAgentProfiles } =
1840
+ await import("../lib/sub-agent-profiles.js");
1841
+ const cmd = parseAgentsCommand(trimmed);
1842
+ if (cmd.action === "help") {
1843
+ logger.log(
1844
+ "Usage: /agents [list] · /agents show <name> · /agents new <name> [--tools a,b] [--claude|--personal] [--description <text>]",
1845
+ );
1846
+ } else if (cmd.action === "list") {
1847
+ logger.log(
1848
+ "\n" +
1849
+ formatAgentsList(
1850
+ discoverAgents(process.cwd()),
1851
+ listSubAgentProfiles(),
1852
+ ) +
1853
+ "\n",
1854
+ );
1855
+ } else if (cmd.action === "show") {
1856
+ if (!cmd.name) {
1857
+ logger.log(chalk.yellow("Usage: /agents show <name>"));
1858
+ } else {
1859
+ const a = getAgent(cmd.name, process.cwd());
1860
+ if (!a) logger.log(chalk.yellow(`No such agent: ${cmd.name}`));
1861
+ else logger.log("\n" + formatAgentDetail(a) + "\n");
1862
+ }
1863
+ } else if (cmd.action === "new") {
1864
+ if (!cmd.name) {
1865
+ logger.log(
1866
+ chalk.yellow("Usage: /agents new <name> [--description <text>]"),
1867
+ );
1868
+ } else {
1869
+ const res = scaffoldAgent({
1870
+ name: cmd.name,
1871
+ description: cmd.description,
1872
+ tools: cmd.tools,
1873
+ location: cmd.location,
1874
+ });
1875
+ if (!res.ok) {
1876
+ logger.log(chalk.yellow(`/agents new: ${res.reason}`));
1877
+ } else {
1878
+ logger.log(chalk.green(`✓ created ${res.file}`));
1879
+ logger.log(
1880
+ chalk.dim(
1881
+ ` edit it, then spawn it from the agent or run: cc agents run ${res.name} "<task>"`,
1882
+ ),
1883
+ );
1884
+ }
1885
+ }
1886
+ }
1887
+ } catch (err) {
1888
+ logger.error(chalk.red(`/agents failed: ${err.message}`));
1889
+ }
1890
+ prompt();
1891
+ return;
1892
+ }
1893
+
1674
1894
  if (trimmed === "/sub-agents" || trimmed === "/subagents") {
1675
1895
  try {
1676
1896
  const { SubAgentRegistry } =
@@ -3057,6 +3277,73 @@ export async function startAgentRepl(options = {}) {
3057
3277
  return;
3058
3278
  }
3059
3279
 
3280
+ // `/status` — concise environment snapshot (version / model / session / cwd
3281
+ // / roots / IDE·MCP·hooks). Lighter than /doctor. Claude-Code /status parity
3282
+ // (minus account/billing, which cc has no notion of).
3283
+ if (trimmed === "/status" || trimmed.startsWith("/status ")) {
3284
+ try {
3285
+ const { VERSION } = await import("../constants.js");
3286
+ const { readDiskVersion } = await import("../lib/version-skew.js");
3287
+ const { ideToolNames } = await import("./ide-status.js");
3288
+ const { formatStatus } = await import("./status-summary.js");
3289
+ const mcpConnected = _adhocMcp?.connected;
3290
+ const mcpCount = Array.isArray(mcpConnected)
3291
+ ? mcpConnected.length
3292
+ : typeof mcpConnected === "number"
3293
+ ? mcpConnected
3294
+ : mcpConnected
3295
+ ? 1
3296
+ : 0;
3297
+ logger.log(
3298
+ "\n" +
3299
+ formatStatus({
3300
+ version: VERSION,
3301
+ installedVersion: readDiskVersion(),
3302
+ node: process.version,
3303
+ platform: `${process.platform}-${process.arch}`,
3304
+ provider,
3305
+ model: _curModel || model,
3306
+ sessionId,
3307
+ messageCount: messages.length,
3308
+ cwd: process.cwd(),
3309
+ extraRoots: additionalDirectories.length,
3310
+ ideConnected: ideToolNames(_adhocMcp).length > 0,
3311
+ mcpServers: mcpCount,
3312
+ hookEvents: _settingsHooks
3313
+ ? Object.keys(_settingsHooks).length
3314
+ : 0,
3315
+ }) +
3316
+ "\n",
3317
+ );
3318
+ } catch (err) {
3319
+ logger.error(chalk.red(`/status failed: ${err.message}`));
3320
+ }
3321
+ prompt();
3322
+ return;
3323
+ }
3324
+
3325
+ // `/release-notes` — running version + a pointer to the full changelog +
3326
+ // how to upgrade. Claude-Code /release-notes parity.
3327
+ if (trimmed === "/release-notes" || trimmed.startsWith("/release-notes ")) {
3328
+ try {
3329
+ const { VERSION } = await import("../constants.js");
3330
+ const { readDiskVersion } = await import("../lib/version-skew.js");
3331
+ const { formatReleaseNotes } = await import("./release-notes.js");
3332
+ logger.log(
3333
+ "\n" +
3334
+ formatReleaseNotes({
3335
+ version: VERSION,
3336
+ installedVersion: readDiskVersion(),
3337
+ }) +
3338
+ "\n",
3339
+ );
3340
+ } catch (err) {
3341
+ logger.error(chalk.red(`/release-notes failed: ${err.message}`));
3342
+ }
3343
+ prompt();
3344
+ return;
3345
+ }
3346
+
3060
3347
  // `/export [path]` — dump the live conversation to a Markdown transcript
3061
3348
  // (Claude-Code parity). Distinct from `cc export` (knowledge base). Captures
3062
3349
  // exactly what's in context now, persisted or not.
@@ -3275,6 +3562,29 @@ export async function startAgentRepl(options = {}) {
3275
3562
  return;
3276
3563
  }
3277
3564
  }
3565
+
3566
+ // `/pr-comments [<n>|<url>] [--repo owner/name]` (Claude-Code parity):
3567
+ // fetch a GitHub PR's reviews + conversation + inline comments via `gh` and
3568
+ // feed them as this turn's input so the agent can address the feedback.
3569
+ if (promptText.startsWith("/pr-comments")) {
3570
+ try {
3571
+ const { expandPrComments } = await import("./pr-comments.js");
3572
+ const res = await expandPrComments(promptText);
3573
+ if (res != null) {
3574
+ promptText = res.text;
3575
+ logger.log(
3576
+ chalk.gray(
3577
+ `[pr] PR #${res.number}: ${res.count} comment(s) fetched`,
3578
+ ),
3579
+ );
3580
+ }
3581
+ } catch (err) {
3582
+ logger.info(chalk.yellow(`[pr-comments] ${err.message}`));
3583
+ prompt();
3584
+ return;
3585
+ }
3586
+ }
3587
+
3278
3588
  try {
3279
3589
  const macro = await resolveSlashMacro(trimmed, { cwd: process.cwd() });
3280
3590
  if (macro.matched) {
@@ -0,0 +1,122 @@
1
+ /**
2
+ * `/agents` REPL command (Claude-Code parity) — manage user-defined sub-agent
3
+ * DEFINITIONS (`.chainlesschain/agents/*.md` / `.claude/agents/*.md`) from
4
+ * inside an interactive session: list / show / new. Mirrors the `cc agents`
5
+ * CLI; the discovery + scaffold live in lib/agents.js (single source of truth),
6
+ * this module is the pure arg-parse + render layer. Distinct from `/sub-agents`
7
+ * which shows running instances.
8
+ */
9
+
10
+ function stripQuotes(s) {
11
+ const t = String(s || "").trim();
12
+ if (
13
+ (t.startsWith('"') && t.endsWith('"')) ||
14
+ (t.startsWith("'") && t.endsWith("'"))
15
+ ) {
16
+ return t.slice(1, -1);
17
+ }
18
+ return t;
19
+ }
20
+
21
+ /**
22
+ * Parse a `/agents …` line.
23
+ * Forms: `/agents [list]`, `/agents show <name>`, `/agents <name>` (= show),
24
+ * `/agents new <name> [--tools a,b] [--claude|--personal] [--description <text>]`,
25
+ * `/agents help`.
26
+ * @returns {{action:string, name?:string|null, description?:string|null,
27
+ * tools?:string|null, location?:string}}
28
+ */
29
+ export function parseAgentsCommand(line) {
30
+ let rest = String(line || "")
31
+ .trim()
32
+ .replace(/^\/agents\b/, "")
33
+ .trim();
34
+
35
+ let location = "project";
36
+ if (/(^|\s)--personal(\s|$)/.test(rest)) {
37
+ location = "personal";
38
+ rest = rest.replace(/(^|\s)--personal(\s|$)/, " ");
39
+ }
40
+ if (/(^|\s)--claude(\s|$)/.test(rest)) {
41
+ if (location !== "personal") location = "claude";
42
+ rest = rest.replace(/(^|\s)--claude(\s|$)/, " ");
43
+ }
44
+
45
+ let tools = null;
46
+ const tm = rest.match(/(^|\s)--tools\s+("[^"]*"|'[^']*'|\S+)/);
47
+ if (tm) {
48
+ tools = stripQuotes(tm[2]);
49
+ rest = rest.replace(tm[0], " ");
50
+ }
51
+
52
+ // --description takes the rest of the line (may contain spaces).
53
+ let description = null;
54
+ const dm = rest.match(/(^|\s)--description\s+(.*)$/);
55
+ if (dm) {
56
+ description = stripQuotes(dm[2].trim()) || null;
57
+ rest = rest.slice(0, dm.index).trim();
58
+ }
59
+
60
+ rest = rest.replace(/\s+/g, " ").trim();
61
+ const tokens = rest.length ? rest.split(" ") : [];
62
+ const first = tokens[0] || "";
63
+
64
+ if (!first || first === "list" || first === "ls") return { action: "list" };
65
+ if (first === "help") return { action: "help" };
66
+ if (first === "show") return { action: "show", name: tokens[1] || null };
67
+ if (first === "new") {
68
+ return {
69
+ action: "new",
70
+ name: tokens[1] || null,
71
+ description,
72
+ tools,
73
+ location,
74
+ };
75
+ }
76
+ // A bare token is treated as a name to show.
77
+ return { action: "show", name: first };
78
+ }
79
+
80
+ /** Render the list of agent definitions + built-in profiles. */
81
+ export function formatAgentsList(agents, profiles) {
82
+ const list = Array.isArray(agents) ? agents : [];
83
+ const profs = Array.isArray(profiles) ? profiles : [];
84
+ const lines = [
85
+ `Agent definitions (${list.length}) — .chainlesschain/agents · .claude/agents · ~/.claude/agents:`,
86
+ ];
87
+ if (list.length === 0) {
88
+ lines.push(" (none — create one with /agents new <name>)");
89
+ } else {
90
+ for (const a of list) {
91
+ const tools = a.tools ? a.tools.join(",") : "(all)";
92
+ lines.push(` ${a.name} [${a.scope}] ${a.description || ""}`.trimEnd());
93
+ lines.push(` tools: ${tools}${a.model ? ` · model: ${a.model}` : ""}`);
94
+ }
95
+ }
96
+ if (profs.length) {
97
+ lines.push("", "Built-in profiles (spawn_sub_agent profile:):");
98
+ for (const p of profs) {
99
+ lines.push(` ${p.name} — ${p.shortDescription || ""}`.trimEnd());
100
+ }
101
+ }
102
+ lines.push(
103
+ "",
104
+ 'Manage: /agents show <name> · /agents new <name> · run via `cc agents run <name> "<task>"`',
105
+ );
106
+ return lines.join("\n");
107
+ }
108
+
109
+ /** Render one agent definition's metadata + system prompt. */
110
+ export function formatAgentDetail(agent) {
111
+ if (!agent) return null;
112
+ const tools = agent.tools ? agent.tools.join(",") : "(all)";
113
+ const lines = [
114
+ `${agent.name} [${agent.scope}]`,
115
+ agent.description ? ` ${agent.description}` : null,
116
+ ` tools: ${tools}${agent.model ? ` · model: ${agent.model}` : ""}`,
117
+ ` file: ${agent.file}`,
118
+ "",
119
+ agent.systemPrompt || "(empty system prompt)",
120
+ ].filter((l) => l != null);
121
+ return lines.join("\n");
122
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Pure renderer for the `/hooks` REPL command — a user-facing view of the
3
+ * decision-capable `.claude/settings.json` `hooks` block loaded for this
4
+ * session. The data comes from settings-hooks' loadHooks(); this module only
5
+ * formats it, so it stays deterministic and unit-testable.
6
+ *
7
+ * Mirrors Claude Code's /hooks view. The separate observe-only DB hooks
8
+ * (`cc hook add`) are not part of this block — a pointer to `cc hook list` is
9
+ * shown instead.
10
+ *
11
+ * Input shape (the settings.json `hooks` object):
12
+ * { <Event>: [ { matcher, hooks: [ { type, command, timeout } ] } ], ... }
13
+ * Event ∈ PreToolUse | PostToolUse | UserPromptSubmit | SessionStart |
14
+ * SessionEnd | Stop | PreCompact | SubagentStop | Notification
15
+ */
16
+
17
+ /** One hook command rendered to a single line. */
18
+ function fmtHook(h) {
19
+ if (!h || typeof h !== "object") return " (invalid hook)";
20
+ const cmd =
21
+ h.type === "command"
22
+ ? String(h.command || "").trim() || "(no command)"
23
+ : `(${h.type || "unknown"} hook)`;
24
+ const to =
25
+ h.timeout != null && Number.isFinite(Number(h.timeout))
26
+ ? ` [timeout ${Number(h.timeout)}s]`
27
+ : "";
28
+ return ` ${cmd}${to}`;
29
+ }
30
+
31
+ /**
32
+ * Render the loaded settings.json hooks block as a plain-text block.
33
+ * @param {object|null} hooks the merged `hooks` object, or null when none
34
+ */
35
+ export function formatSettingsHooks(hooks) {
36
+ const events = hooks && typeof hooks === "object" ? Object.keys(hooks) : [];
37
+ if (events.length === 0) {
38
+ return (
39
+ "No settings.json hooks loaded.\n" +
40
+ " Define a `hooks` block in .claude/settings.json (PreToolUse / " +
41
+ "PostToolUse / UserPromptSubmit / SessionStart / Stop / PreCompact / …).\n" +
42
+ " Observe-only DB hooks: cc hook list"
43
+ );
44
+ }
45
+ let total = 0;
46
+ const body = [];
47
+ for (const ev of events) {
48
+ const entries = Array.isArray(hooks[ev]) ? hooks[ev] : [];
49
+ body.push(` ${ev}:`);
50
+ for (const entry of entries) {
51
+ const matcher = entry?.matcher ? String(entry.matcher) : "*";
52
+ body.push(` matcher ${matcher}`);
53
+ const hs = Array.isArray(entry?.hooks) ? entry.hooks : [];
54
+ for (const h of hs) {
55
+ total += 1;
56
+ body.push(fmtHook(h));
57
+ }
58
+ }
59
+ }
60
+ const header = `settings.json hooks (decision-capable, ${total} command(s) across ${events.length} event(s)):`;
61
+ return (
62
+ header +
63
+ "\n" +
64
+ body.join("\n") +
65
+ "\n Test a hook: cc hook test <event> <tool> --run · observe-only DB hooks: cc hook list"
66
+ );
67
+ }