chainlesschain 0.162.142 → 0.162.147

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 (192) hide show
  1. package/bin/chainlesschain.js +5 -3
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/assets/{AIOps-Dc6fWgoa.js → AIOps-DywJ7xTv.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DzMx25vJ.js → ActionButton-BTlqcY-q.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-eDC3KNht.js → Analytics-FdG1Mvwy.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-uA1TOtNp.js → AppLayout-CVsnbvN1.js} +3 -3
  7. package/src/assets/web-panel/assets/{Audit-Bq3QX9Cj.js → Audit-ITdpJ7vR.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-B1V3Jfyv.js → Backup-BfXqnXo1.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-DMFwddIF.js → BaseInput-C09ip3_E.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-CKWQDH5j.js → Chat-qdkhB42l.js} +6 -6
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CStSBCnk.js → ChatBubbleRenderer-D2KfETZD.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-DepIzI7G.js → Checkbox-j6WZCuff.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-ClanWll2.js → Codegen-CGZ-K3uK.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-CFBzsL4W.js → Col-CIlPOAu6.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-CaAyZ_Pt.js → Community-sY-i-hic.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-3dCHRSVe.js → Compact-DcoEfyL8.js} +1 -1
  17. package/src/assets/web-panel/assets/Compliance-T8EtTecW.js +1 -0
  18. package/src/assets/web-panel/assets/{Cowork-DkJmdQaU.js → Cowork-DLY_fkLv.js} +3 -3
  19. package/src/assets/web-panel/assets/{Cron-DKfNf6J2.js → Cron-D049pZBC.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-COu1aQIO.js → Crosschain-DCXdE8M9.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-CkAgFLkI.js → DID-JCvPZtjW.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard-CfaKWZCU.js → Dashboard-Cg2xu3iE.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-Cjw97sdb.js → Dropdown-DjJLjbLh.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-DROLQgOn.js → EmailListRenderer-DugNcSLR.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-o_cYzlLq.js → FamilyGuardDashboard-J6Nb-E30.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-Boex3ljt.js → Federation-CQ3Ttpbl.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-BQQ05T_3.js → FormItemContext-Cz0NKag4.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-CdfL8PBd.js → GenericCardRenderer-NYcMP6iz.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-CfZ07qJy.js → Git-B4hYN18N.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-B21ISudq.js → Governance-DOQPCcC0.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-CGIK4Im1.js → Inference-HtLF746W.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-CI1kmfdT.js → KnowledgeGraph-BXrk8rMm.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-Dpc1-__h.js → Logs-DS0JnD3-.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-BpMtMWyK.js → Marketplace-Cqnjihrz.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-B94WvOOS.js → McpTools-Cx3Psk-U.js} +5 -5
  36. package/src/assets/web-panel/assets/{Memory-DODsAxZf.js → Memory-BjyysPtj.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-C3Bjshem.js → MobileBridge-CYaITZ7w.js} +1 -1
  38. package/src/assets/web-panel/assets/{MobileProjects-Bi8IHDv_.js → MobileProjects-Xwf-fdOQ.js} +1 -1
  39. package/src/assets/web-panel/assets/{Mtc-CH5BSuWG.js → Mtc-Djkql5m5.js} +2 -2
  40. package/src/assets/web-panel/assets/{MtcAudit-DN3MzNtL.js → MtcAudit-D2BAZlu0.js} +2 -2
  41. package/src/assets/web-panel/assets/{Multisig-CO6GWQOh.js → Multisig-ByqP1ZzH.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-DhIr3V_u.js → NLProgramming-C_kn0nE2.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-CNgrvZCJ.js → Notes-7l7eXHPq.js} +3 -3
  44. package/src/assets/web-panel/assets/{NotificationSettings-Crr4LPjQ.js → NotificationSettings-BrCDoitw.js} +1 -1
  45. package/src/assets/web-panel/assets/{OrderTableRenderer-C8q-kK2z.js → OrderTableRenderer-CmtqIdwr.js} +1 -1
  46. package/src/assets/web-panel/assets/{Organization-hWhCmeUn.js → Organization-DdoNAxsM.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow-t_EBxns-.js → Overflow-Bw7R6dE3.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-B8fqfwis.js → P2P-DJNtBugA.js} +2 -2
  49. package/src/assets/web-panel/assets/{PdhVaultBrowser-d-wlJw3R.js → PdhVaultBrowser-Dwhd5_ue.js} +3 -3
  50. package/src/assets/web-panel/assets/{Permissions-Ch13YpBo.js → Permissions-BYoSfhPR.js} +4 -4
  51. package/src/assets/web-panel/assets/{PersonalDataHub-DW7LlLbS.js → PersonalDataHub-aYCYJbnH.js} +2 -2
  52. package/src/assets/web-panel/assets/{Pipeline-BHh3HqOQ.js → Pipeline-DJp6CprF.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-DAhlJDSC.js → Privacy-Cq9HZweR.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-BRtddAM_.js → ProjectInit-CmF0HsSt.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-CzR1EC7b.js → ProjectSettings-P8V5Aea2.js} +2 -2
  56. package/src/assets/web-panel/assets/{Projects-DSavX602.js → Projects-DPd5-lNS.js} +1 -1
  57. package/src/assets/web-panel/assets/{Providers-D55_kGZs.js → Providers-D589v0q2.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-BR5qDIaT.js → QuickAsk-lvRV2osB.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-CTFAM97K.js → Recommend-sb84MTpY.js} +1 -1
  60. package/src/assets/web-panel/assets/{Reputation-Z7pvEha9.js → Reputation-d9Y3vy-W.js} +1 -1
  61. package/src/assets/web-panel/assets/{Row-MqKcIsjP.js → Row-DMdhLUTp.js} +1 -1
  62. package/src/assets/web-panel/assets/{RssFeed-DdLDjRpk.js → RssFeed-OL-SMDkz.js} +3 -3
  63. package/src/assets/web-panel/assets/{Search-CeOzh2hz.js → Search-BjStLKq1.js} +1 -1
  64. package/src/assets/web-panel/assets/{Security-gHrXaf4o.js → Security-MeI411qr.js} +3 -3
  65. package/src/assets/web-panel/assets/{Services-B8Y7pmY1.js → Services-UajosuhT.js} +2 -2
  66. package/src/assets/web-panel/assets/{Skeleton-CRS0WNut.js → Skeleton-CGpG-QJ1.js} +1 -1
  67. package/src/assets/web-panel/assets/{Skills--a5_Pdxx.js → Skills-C6P2RPY-.js} +1 -1
  68. package/src/assets/web-panel/assets/{Sla-EcTyL6EM.js → Sla-B_fPprgw.js} +1 -1
  69. package/src/assets/web-panel/assets/{SpeechSettings-QpfvOiJr.js → SpeechSettings-CqxLjSlQ.js} +1 -1
  70. package/src/assets/web-panel/assets/{SyncSettings-DaLBBzlE.js → SyncSettings-DixSfFOQ.js} +2 -2
  71. package/src/assets/web-panel/assets/{Tasks-Ca6xvO-I.js → Tasks-PavzPBxc.js} +1 -1
  72. package/src/assets/web-panel/assets/{Templates-CWguiCoE.js → Templates-BYdGRnfX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Tenant-BGLLZulu.js → Tenant-BQLgnarD.js} +1 -1
  74. package/src/assets/web-panel/assets/Terminal-BzOHpq-B.js +3 -0
  75. package/src/assets/web-panel/assets/{TimelineRenderer-CLjvjbmr.js → TimelineRenderer-Bv7uZRM7.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tokens-De5mmw_a.js → Tokens-DxhgszRJ.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trigger-Chbq6U0N.js → Trigger-nQYHayuc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trust-CYxUO2lv.js → Trust-CvqZDuZ4.js} +1 -1
  79. package/src/assets/web-panel/assets/{UkeySign-iyoZXXF6.js → UkeySign-DaR8GV2I.js} +1 -1
  80. package/src/assets/web-panel/assets/{VideoEditing-CHg3ifJs.js → VideoEditing-C6Mpsokw.js} +1 -1
  81. package/src/assets/web-panel/assets/{Wallet-DfjqObsO.js → Wallet-B57VRrWc.js} +4 -4
  82. package/src/assets/web-panel/assets/{WebAuthn-0FI6xfud.js → WebAuthn-BbtEEtpq.js} +4 -4
  83. package/src/assets/web-panel/assets/{WorkflowEditor-CJgGcctS.js → WorkflowEditor-C5LwvKmH.js} +1 -1
  84. package/src/assets/web-panel/assets/{chat-fH-E4vhY.js → chat-MzuPR5jh.js} +1 -1
  85. package/src/assets/web-panel/assets/{colors-CuxsOD6d.js → colors-HyW8mi_y.js} +1 -1
  86. package/src/assets/web-panel/assets/{compact-item-AfVcFrFU.js → compact-item-DvUSzWAp.js} +1 -1
  87. package/src/assets/web-panel/assets/{createContext-DTsD7sPO.js → createContext-4MppZl7X.js} +1 -1
  88. package/src/assets/web-panel/assets/devWarning-6YJJMjSH.js +1 -0
  89. package/src/assets/web-panel/assets/{hasIn-DJR763M6.js → hasIn-D9q3CJ-u.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-DhM9FZUH.js → index--Bm6OqmU.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-OZwLoscJ.js → index-B5E4DhVc.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-CF8OSTin.js → index-B994UQfE.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-9cryBBzh.js → index-BF2JsbiX.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BMVULNUC.js → index-BFGfC5RS.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Dj1_lz3M.js → index-BGQtFso0.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DBPAH7rp.js → index-BcunsBIx.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-mLAfJXAf.js → index-Bl-E4W4q.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Cfppli6E.js → index-BmCo2Xdp.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-_hP8-Y2F.js → index-Btz8pU68.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DvlzcX3Q.js → index-C0DiL97c.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CBBStCbO.js → index-C9I5MuJ0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-SuJ2_OzM.js → index-CLAZs1Vd.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-B8DLT-F4.js → index-Caqtu6Et.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Cm4cHE5_.js → index-CgIfXOD9.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DbQX0Zbf.js → index-Ci6adKh8.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BEGMojUg.js → index-CifKUNtV.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CdV7a6-K.js → index-Cs-RKRUM.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Dswd93W4.js → index-CucRo4Vz.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D2KdGSMa.js → index-CvAqCAo9.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BqflTl_b.js → index-D2jrnaq3.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Cl7chKuM.js → index-D7TDMMfu.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CAbZ3dW9.js → index-DDZ6fP5Z.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BD4-kWQY.js → index-DFqvWeGc.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DejUsZOw.js → index-DNYqw0MO.js} +1 -1
  115. package/src/assets/web-panel/assets/index-D_oeGLr6.js +1 -0
  116. package/src/assets/web-panel/assets/{index-DH-dA4pG.js → index-DcMkjb92.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CMcYdHhK.js → index-DmZ6-suL.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-85iIi3qF.js → index-Dv7ffI2g.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DJIFQ-Ay.js → index-Dvg5xYuP.js} +1 -1
  120. package/src/assets/web-panel/assets/index-Qa57YG19.js +1 -0
  121. package/src/assets/web-panel/assets/{index-DxD03TL7.js → index-SDblbKj6.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CmUxSTNy.js → index-UUMCA2Sq.js} +3 -3
  123. package/src/assets/web-panel/assets/{index-BJl6Ob-o.js → index-Zvtru2oE.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DPHYW3IK.js → index-eOQO6KnV.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B-rcowKd.js → index-m0b6Fj9q.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BTtL2Qkb.js → index-ryFLxB1p.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-fj3ZXgiy.js → index-xvUVuFnA.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BbpuFc8C.js → index-zLwYpvX0.js} +1 -1
  129. package/src/assets/web-panel/assets/{initDefaultProps-BGoLJP6T.js → initDefaultProps-CC--PMsC.js} +1 -1
  130. package/src/assets/web-panel/assets/{motion-23xdoVi0.js → motion-DdrBjRF1.js} +1 -1
  131. package/src/assets/web-panel/assets/{move-C3Bnnft-.js → move-D712Gwl2.js} +1 -1
  132. package/src/assets/web-panel/assets/{mtc-parser-Dv0C3a90.js → mtc-parser-39y-keKO.js} +1 -1
  133. package/src/assets/web-panel/assets/{omit-C3r9qzDO.js → omit-6Y51gDB9.js} +1 -1
  134. package/src/assets/web-panel/assets/{pickAttrs-B4bJOcNp.js → pickAttrs-Cy6EHbq9.js} +1 -1
  135. package/src/assets/web-panel/assets/{placementArrow-Dxf48wcO.js → placementArrow-BYxdAm0p.js} +1 -1
  136. package/src/assets/web-panel/assets/{responsiveObserve-Rq9U2hbz.js → responsiveObserve-C9R6q_cr.js} +1 -1
  137. package/src/assets/web-panel/assets/{slide-BeWiqbdF.js → slide-CXUJlilB.js} +1 -1
  138. package/src/assets/web-panel/assets/{statusUtils-yX9N1cEc.js → statusUtils-DOtrOeql.js} +1 -1
  139. package/src/assets/web-panel/assets/{styleChecker-5Ko9NorO.js → styleChecker-D5r39o92.js} +1 -1
  140. package/src/assets/web-panel/assets/{useFlexGapSupport-WKpkTLok.js → useFlexGapSupport-DfAD5U4Z.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFs-BV4X0JOG.js → useFs-BkrT-Zbc.js} +1 -1
  142. package/src/assets/web-panel/assets/{usePersonalDataHub-g41wq_2p.js → usePersonalDataHub-BwnnnZjU.js} +1 -1
  143. package/src/assets/web-panel/assets/{vnode-BAurbOH8.js → vnode-SU-N4pum.js} +1 -1
  144. package/src/assets/web-panel/assets/{zoom-Cl5XniRg.js → zoom-DHScfpTP.js} +1 -1
  145. package/src/assets/web-panel/index.html +1 -1
  146. package/src/auth/npm-auth.js +65 -0
  147. package/src/command-manifest.json +1126 -0
  148. package/src/commands/agent.js +92 -0
  149. package/src/commands/agents.js +68 -0
  150. package/src/commands/note.js +2 -1
  151. package/src/commands/permissions.js +66 -10
  152. package/src/commands/plugin.js +50 -3
  153. package/src/commands/search.js +2 -1
  154. package/src/harness/worktree-isolator.js +14 -7
  155. package/src/index.js +4 -12
  156. package/src/lazy-dispatch.js +107 -0
  157. package/src/lib/agent-sandbox.js +72 -0
  158. package/src/lib/background-agent-supervisor.js +197 -0
  159. package/src/lib/code-review.js +72 -0
  160. package/src/lib/ensure-utf8.js +25 -7
  161. package/src/lib/knowledge-exporter.js +3 -2
  162. package/src/lib/permission-engine.js +1 -1
  163. package/src/lib/plugin-security.js +128 -0
  164. package/src/lib/pr-create.js +108 -0
  165. package/src/lib/publish-workspace.js +107 -0
  166. package/src/lib/resume-session.js +111 -0
  167. package/src/lib/session-manager.js +2 -1
  168. package/src/lib/settings-hooks.cjs +68 -25
  169. package/src/lib/settings-loader.cjs +115 -2
  170. package/src/lib/task-list.js +53 -0
  171. package/src/program-base.js +24 -0
  172. package/src/repl/agent-repl.js +108 -3
  173. package/src/repl/agents-status.js +8 -2
  174. package/src/repl/btw-command.js +56 -0
  175. package/src/repl/chat-repl.js +52 -1
  176. package/src/repl/hooks-status.js +1 -2
  177. package/src/repl/slash-command-registry.js +197 -0
  178. package/src/repl/think-command.js +31 -0
  179. package/src/runtime/agent-core.js +137 -1
  180. package/src/runtime/coding-agent-contract-shared.cjs +37 -0
  181. package/src/runtime/coding-agent-policy.cjs +14 -0
  182. package/src/runtime/file-ref-expander.js +100 -14
  183. package/src/runtime/headless-runner.js +26 -6
  184. package/src/runtime/headless-stream.js +25 -6
  185. package/src/runtime/mcp-config.js +46 -2
  186. package/src/runtime/policies/agent-policy.js +1 -0
  187. package/src/workers/background-agent-worker.js +60 -0
  188. package/src/assets/web-panel/assets/Compliance-BKYHHTdq.js +0 -1
  189. package/src/assets/web-panel/assets/Terminal-Bryzb1Rm.js +0 -3
  190. package/src/assets/web-panel/assets/devWarning-DffbPlEe.js +0 -1
  191. package/src/assets/web-panel/assets/index-BAHgOh3h.js +0 -1
  192. package/src/assets/web-panel/assets/index-zfkDb9FC.js +0 -1
@@ -97,7 +97,8 @@ import {
97
97
  import { resolveSlashMacro } from "./slash-macro.js";
98
98
  import { expandMcpPrompt, renderMcpSurface } from "./mcp-prompt.js";
99
99
  import { newCostStore, addUsage } from "./session-cost.js";
100
- import { parseThinkCommand } from "./think-command.js";
100
+ import { parseThinkCommand, parseEffortCommand } from "./think-command.js";
101
+ import { parseBtwCommand, buildAsideBlock, applyAside } from "./btw-command.js";
101
102
  import { shouldStreamLive } from "./stream-decision.js";
102
103
  import { emptyTurnNotice } from "./empty-turn-notice.js";
103
104
  import { buildPermissionPrompt } from "./permission-prompt.js";
@@ -117,6 +118,7 @@ let _approvalGate = null;
117
118
  // confirmer for `ask` matches. Loaded once at REPL startup; null = no file.
118
119
  let _permissionRules = null;
119
120
  let _permissionConfirm = null;
121
+ let _managedPermissionRulesOnly = false;
120
122
  // .claude/settings.json `hooks` block (decision-capable PreToolUse/PostToolUse).
121
123
  let _settingsHooks = null;
122
124
  // .claude/settings.json `respondToBashCommands` (Claude-Code 2.1.186): whether a
@@ -127,6 +129,7 @@ let _respondToBash;
127
129
  // the built-in verification allowlist through the shell-policy classifier (→
128
130
  // ApprovalGate confirm) instead of fast-pathing it. false = unset → off.
129
131
  let _classifyAllShell = false;
132
+ let _sandbox = null;
130
133
  // Bounded log of tool calls the agent was BLOCKED from running this session
131
134
  // (shell-policy / ApprovalGate / settings rule / hook). Surfaced by
132
135
  // `/permissions denials` (Claude-Code 2.1.193 "recent denials"). In-memory only.
@@ -161,6 +164,12 @@ async function _fireNotification(message) {
161
164
  */
162
165
  async function _persistAlwaysAllow(tool, args) {
163
166
  try {
167
+ if (_managedPermissionRulesOnly) {
168
+ process.stderr.write(
169
+ " always-allow is disabled by managed settings; ask your administrator to change the policy.\n",
170
+ );
171
+ return null;
172
+ }
164
173
  const rulesMod = await import("../lib/permission-rules.cjs");
165
174
  const { suggestAllowRule } = rulesMod.default || rulesMod;
166
175
  const rule = suggestAllowRule(tool || "run_shell", args || {});
@@ -194,6 +203,7 @@ async function executeTool(name, args) {
194
203
  permissionConfirm: _permissionConfirm,
195
204
  settingsHooks: _settingsHooks,
196
205
  classifyAllShell: _classifyAllShell,
206
+ sandbox: _sandbox,
197
207
  });
198
208
  }
199
209
 
@@ -371,6 +381,12 @@ export async function startAgentRepl(options = {}) {
371
381
  // (--thinking-budget) is the companion legacy-model budget_tokens override.
372
382
  let thinking = options.thinking || null;
373
383
  const thinkingBudget = options.thinkingBudget || null;
384
+ // `/btw` one-shot asides: queued notes that ride ONLY the next turn (sent to
385
+ // the model, then stripped so they never persist or carry forward).
386
+ // `_btwRestore` holds the user message + its pre-aside content so we can undo
387
+ // the injection after the turn (or as a backstop at the next submit on throw).
388
+ let pendingBtw = [];
389
+ let _btwRestore = null;
374
390
  // Current ApprovalGate session tier (strict|trusted|autopilot), mirrored here
375
391
  // so Shift+Tab can cycle it and `/permissions <tier>` can set it. Kept in sync
376
392
  // with _approvalGate.setSessionPolicy below.
@@ -402,6 +418,7 @@ export async function startAgentRepl(options = {}) {
402
418
  const additionalDirectories = Array.isArray(options.additionalDirectories)
403
419
  ? options.additionalDirectories
404
420
  : [];
421
+ _sandbox = options.sandbox || null;
405
422
  // Snapshot the work tree before each mutating tool (git engine) so the user
406
423
  // can `cc checkpoint restore` to just before any tool call.
407
424
  const autoCheckpoint = options.autoCheckpoint === true;
@@ -542,6 +559,8 @@ export async function startAgentRepl(options = {}) {
542
559
  const { loadSettings, readBooleanSetting } =
543
560
  await import("../lib/settings-loader.cjs");
544
561
  const loaded = loadSettings({ cwd: process.cwd() });
562
+ _managedPermissionRulesOnly =
563
+ loaded.managed?.allowManagedPermissionRulesOnly === true;
545
564
  // Claude-Code 2.1.186 respondToBashCommands (default OFF / opt-in when unset).
546
565
  _respondToBash = readBooleanSetting("respondToBashCommands", {
547
566
  cwd: process.cwd(),
@@ -578,8 +597,10 @@ export async function startAgentRepl(options = {}) {
578
597
  return ans === "y" || ans === "yes";
579
598
  };
580
599
  } catch (_err) {
600
+ if (_err?.code === "CC_MANAGED_SETTINGS_INVALID") throw _err;
581
601
  _permissionRules = null;
582
602
  _permissionConfirm = null;
603
+ _managedPermissionRulesOnly = false;
583
604
  }
584
605
 
585
606
  // Load .claude/settings.json `hooks` block (decision-capable PreToolUse/
@@ -1040,6 +1061,7 @@ export async function startAgentRepl(options = {}) {
1040
1061
  "/add-dir",
1041
1062
  "/agents",
1042
1063
  "/auto",
1064
+ "/btw",
1043
1065
  "/cd",
1044
1066
  "/clear",
1045
1067
  "/compact",
@@ -1049,6 +1071,7 @@ export async function startAgentRepl(options = {}) {
1049
1071
  "/cost",
1050
1072
  "/cowork",
1051
1073
  "/doctor",
1074
+ "/effort",
1052
1075
  "/exit",
1053
1076
  "/export",
1054
1077
  "/help",
@@ -1514,6 +1537,12 @@ export async function startAgentRepl(options = {}) {
1514
1537
  logger.log(
1515
1538
  ` ${chalk.cyan("/think")} Extended thinking on/off (/think [on|off|ultra]; /ultrathink = max; Anthropic)`,
1516
1539
  );
1540
+ logger.log(
1541
+ ` ${chalk.cyan("/effort")} Reasoning effort (/effort low|medium|high|xhigh; Anthropic)`,
1542
+ );
1543
+ logger.log(
1544
+ ` ${chalk.cyan("/btw")} Queue a one-off aside for your next message (not saved to history)`,
1545
+ );
1517
1546
  logger.log(` ${chalk.cyan("/clear")} Clear conversation`);
1518
1547
  logger.log(
1519
1548
  ` ${chalk.cyan("/vim")} Toggle vim-mode line editing (/vim [on|off]; Esc → NORMAL)`,
@@ -2006,6 +2035,47 @@ export async function startAgentRepl(options = {}) {
2006
2035
  }
2007
2036
  }
2008
2037
 
2038
+ // Reasoning-effort alias (/effort low|medium|high|xhigh) — a discrete,
2039
+ // validated front-end over the /think <level> passthrough (Claude-Code parity).
2040
+ {
2041
+ const effort = parseEffortCommand(trimmed);
2042
+ if (effort) {
2043
+ if (effort.error) {
2044
+ logger.info(effort.error);
2045
+ prompt();
2046
+ return;
2047
+ }
2048
+ thinking = effort.thinking;
2049
+ logger.info(
2050
+ `Reasoning effort: ${chalk.cyan(effort.label)} ` +
2051
+ chalk.gray("(Anthropic extended thinking; applies next turn)"),
2052
+ );
2053
+ prompt();
2054
+ return;
2055
+ }
2056
+ }
2057
+
2058
+ // `/btw <note>` — queue a one-shot aside (Claude-Code parity). It rides the
2059
+ // NEXT message to the model, then is stripped so it never bloats history.
2060
+ {
2061
+ const btw = parseBtwCommand(trimmed);
2062
+ if (btw) {
2063
+ if (btw.error) {
2064
+ logger.info(btw.error);
2065
+ prompt();
2066
+ return;
2067
+ }
2068
+ pendingBtw.push(btw.text);
2069
+ logger.info(
2070
+ chalk.gray(
2071
+ `Aside noted (${pendingBtw.length}) — rides your next message only, not saved to history.`,
2072
+ ),
2073
+ );
2074
+ prompt();
2075
+ return;
2076
+ }
2077
+ }
2078
+
2009
2079
  if (trimmed === "/clear") {
2010
2080
  // Stash the conversation first so `/rewind clear` can restore it
2011
2081
  // (Claude-Code 2.1.191). A no-op /clear (nothing to stash) keeps any
@@ -3620,6 +3690,14 @@ export async function startAgentRepl(options = {}) {
3620
3690
  logger.verbose(`[hook] prompt rewritten by UserPromptSubmit hook`);
3621
3691
  }
3622
3692
 
3693
+ // Backstop: if the previous turn's agentLoop threw before the success-path
3694
+ // restore ran, undo its /btw aside now so it never leaks into this turn's
3695
+ // history/model call. (Normal turns clear _btwRestore right after agentLoop.)
3696
+ if (_btwRestore) {
3697
+ _btwRestore.msg.content = _btwRestore.content;
3698
+ _btwRestore = null;
3699
+ }
3700
+
3623
3701
  // Expand @path file references into context blocks (Claude-Code parity),
3624
3702
  // so `review @src/x.js` injects the file contents. Typo'd paths are warned
3625
3703
  // about and left as-is.
@@ -3722,8 +3800,10 @@ export async function startAgentRepl(options = {}) {
3722
3800
  }
3723
3801
  }
3724
3802
 
3725
- // Add user message
3726
- messages.push({ role: "user", content: _userMessageContent });
3803
+ // Add user message (keep the object ref so a /btw aside can be injected for
3804
+ // this turn's model call and then stripped before persistence).
3805
+ const _userMsg = { role: "user", content: _userMessageContent };
3806
+ messages.push(_userMsg);
3727
3807
 
3728
3808
  // Slot-filling: detect intent and fill missing parameters interactively
3729
3809
  try {
@@ -3832,6 +3912,23 @@ export async function startAgentRepl(options = {}) {
3832
3912
  }
3833
3913
  : {};
3834
3914
  if (_streamLive) process.stdout.write("\n");
3915
+ // Inject any queued /btw asides into THIS turn's user message just before
3916
+ // the model call. We remember the pre-aside content so it's restored right
3917
+ // after agentLoop returns — the aside steers this answer but is never
3918
+ // persisted (saveMessages/JSONL) or carried into later turns. Consumed on
3919
+ // send (cleared now) so a thrown turn doesn't re-inject next time; the
3920
+ // submit-start backstop restores if agentLoop throws before we get back.
3921
+ if (pendingBtw.length > 0) {
3922
+ const block = buildAsideBlock(pendingBtw);
3923
+ if (block) {
3924
+ _btwRestore = { msg: _userMsg, content: _userMsg.content };
3925
+ _userMsg.content = applyAside(_userMsg.content, block);
3926
+ logger.verbose(
3927
+ `[btw] applied ${pendingBtw.length} aside(s) to this turn`,
3928
+ );
3929
+ }
3930
+ pendingBtw = [];
3931
+ }
3835
3932
  // Consume the one-shot resume-degeneracy flag for THIS turn so the role
3836
3933
  // merge fires exactly once (2.1.187 parity; see _sanitizeRolesNextTurn).
3837
3934
  const _mergeRolesThisTurn = _sanitizeRolesNextTurn;
@@ -3889,6 +3986,7 @@ export async function startAgentRepl(options = {}) {
3889
3986
  sessionId,
3890
3987
  cwd: process.cwd(),
3891
3988
  additionalDirectories,
3989
+ sandbox: _sandbox,
3892
3990
  autoCheckpoint,
3893
3991
  checkpointSession: sessionId,
3894
3992
  checkpointMarks: _checkpointMarks,
@@ -3912,6 +4010,13 @@ export async function startAgentRepl(options = {}) {
3912
4010
  });
3913
4011
  _turnAbort = null;
3914
4012
 
4013
+ // Strip the one-shot /btw aside now the model has seen it — so it is never
4014
+ // persisted (DB saveMessages below) or carried into the next turn.
4015
+ if (_btwRestore) {
4016
+ _btwRestore.msg.content = _btwRestore.content;
4017
+ _btwRestore = null;
4018
+ }
4019
+
3915
4020
  // Running spend for `/cost` (in-memory, works without persistence).
3916
4021
  if (usageEvents?.length) addUsage(_costStore, usageEvents);
3917
4022
 
@@ -65,7 +65,13 @@ export function parseAgentsCommand(line) {
65
65
  if (first === "help") return { action: "help" };
66
66
  if (first === "show") return { action: "show", name: tokens[1] || null };
67
67
  if (first === "new") {
68
- return { action: "new", name: tokens[1] || null, description, tools, location };
68
+ return {
69
+ action: "new",
70
+ name: tokens[1] || null,
71
+ description,
72
+ tools,
73
+ location,
74
+ };
69
75
  }
70
76
  // A bare token is treated as a name to show.
71
77
  return { action: "show", name: first };
@@ -95,7 +101,7 @@ export function formatAgentsList(agents, profiles) {
95
101
  }
96
102
  lines.push(
97
103
  "",
98
- "Manage: /agents show <name> · /agents new <name> · run via `cc agents run <name> \"<task>\"`",
104
+ 'Manage: /agents show <name> · /agents new <name> · run via `cc agents run <name> "<task>"`',
99
105
  );
100
106
  return lines.join("\n");
101
107
  }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Pure helpers for the REPL `/btw` aside (Claude-Code parity, one-shot variant).
3
+ *
4
+ * `/btw <note>` queues a side note that rides ONLY the next message: it is sent
5
+ * to the model for that one turn (so it can steer the answer) and then removed,
6
+ * so it is never persisted to the session history and never carried into later
7
+ * turns — i.e. context without bloat. vscode/readline-free → unit-testable; the
8
+ * REPL owns the queue + the inject/restore around the agentLoop call.
9
+ *
10
+ * /btw I'm on Windows, use PowerShell → queued, applied to the next turn only
11
+ * /btw → usage error (nothing queued)
12
+ */
13
+
14
+ /** Parse a `/btw …` line. Returns { text } | { error } | null (not a /btw). */
15
+ export function parseBtwCommand(trimmed) {
16
+ const t = String(trimmed == null ? "" : trimmed).trim();
17
+ if (t !== "/btw" && !t.startsWith("/btw ")) return null;
18
+ const text = t.slice("/btw".length).trim();
19
+ if (!text) {
20
+ return {
21
+ error:
22
+ "usage: /btw <note> — a one-off aside for your next message (sent to the model, not saved to history)",
23
+ };
24
+ }
25
+ return { text };
26
+ }
27
+
28
+ /**
29
+ * Render queued asides into a single tagged block, or null when there is
30
+ * nothing to add. The note tells the model this is ephemeral user guidance.
31
+ */
32
+ export function buildAsideBlock(asides) {
33
+ const list = (Array.isArray(asides) ? asides : [])
34
+ .map((s) => String(s == null ? "" : s).trim())
35
+ .filter(Boolean);
36
+ if (!list.length) return null;
37
+ return (
38
+ '<aside note="one-off side note from the user — applies to THIS message only, not saved to history">\n' +
39
+ list.join("\n") +
40
+ "\n</aside>"
41
+ );
42
+ }
43
+
44
+ /**
45
+ * Append an aside block to a user message's content, preserving multimodal
46
+ * arrays (OpenAI-style content parts from --image turns). Returns the new
47
+ * content; a falsy block returns the content unchanged.
48
+ */
49
+ export function applyAside(content, block) {
50
+ if (!block) return content;
51
+ if (Array.isArray(content)) {
52
+ return [...content, { type: "text", text: block }];
53
+ }
54
+ const s = content == null ? "" : String(content);
55
+ return s.length ? `${s}\n\n${block}` : block;
56
+ }
@@ -1,5 +1,34 @@
1
1
  /**
2
- * Interactive AI chat REPL with streaming output
2
+
3
+ // Parity command handlers
4
+ if (cmd in SLASH_COMMANDS && !["/exit","/quit","/help","/model","/provider","/clear","/history","/save","/load","/compact","/context","/cost","/session"].includes(cmd)) {
5
+ const help = {
6
+ '/config': '💡 Use "cc config" to view/modify settings',
7
+ '/doctor': '💡 Run "cc doctor" for full system health check',
8
+ '/status': '💡 Run "cc status" to see system status',
9
+ '/agents': '💡 Run "cc agent list" to see available agents',
10
+ '/tasks': '💡 Run "cc cowork task list" for background tasks',
11
+ '/todos': '💡 TODO list is available in plan mode',
12
+ '/memory': '💡 Run "cc memory status" for memory statistics',
13
+ '/mcp': '💡 Run "cc mcp list" to see MCP servers',
14
+ '/permissions': '💡 Permissions are in ~/.chainlesschain/config.json',
15
+ '/hooks': '💡 Run "cc hook list" to see event hooks',
16
+ '/sessions': '💡 Run "cc session list" to see recent sessions',
17
+ '/resume': '💡 Use /sessions first to select a session',
18
+ '/review': '💡 Run "cc review" for full code review',
19
+ '/export': '💡 Run "cc chat export" to export history',
20
+ '/theme': '💡 Dark mode is the default theme',
21
+ '/think': '💡 Thinking mode enabled for complex queries',
22
+ '/btw': '💡 Incidental notes are auto-saved to memory',
23
+ '/release-notes': '💡 See https://github.com/chainlesschain/chainlesschain/releases',
24
+ '/ide': '💡 VS Code/JetBrains plugins are available',
25
+ '/publish': '💡 Run "cc skill publish" to publish skills',
26
+ };
27
+ console.log(chalk.dim(help[cmd] || 'Command recognized'));
28
+ rl.prompt();
29
+ continue;
30
+ }
31
+ * Interactive AI chat REPL with streaming output
3
32
  *
4
33
  * Features:
5
34
  * - Streaming token output
@@ -32,6 +61,28 @@ const SLASH_COMMANDS = {
32
61
  "/clear": "Clear conversation history",
33
62
  "/history": "Show conversation history",
34
63
  "/help": "Show available commands",
64
+
65
+ // Claude Code parity commands (v0.162.132)
66
+ "/config": "View/modify configuration",
67
+ "/doctor": "Run system health check",
68
+ "/status": "Show system status summary",
69
+ "/agents": "List available agents",
70
+ "/tasks": "List background tasks",
71
+ "/todos": "Manage task list",
72
+ "/memory": "Show memory status",
73
+ "/mcp": "Manage MCP servers",
74
+ "/permissions": "View permission settings",
75
+ "/hooks": "Manage event hooks",
76
+ "/sessions": "List recent sessions",
77
+ "/resume": "Resume previous session",
78
+ "/review": "Request code review",
79
+ "/export": "Export conversation",
80
+ "/theme": "Set REPL theme",
81
+ "/think": "Toggle thinking mode",
82
+ "/btw": "Add incidental note",
83
+ "/release-notes": "Show release notes",
84
+ "/ide": "Check IDE integration",
85
+ "/publish": "Publish session as skill",
35
86
  };
36
87
 
37
88
  /**
@@ -33,8 +33,7 @@ function fmtHook(h) {
33
33
  * @param {object|null} hooks the merged `hooks` object, or null when none
34
34
  */
35
35
  export function formatSettingsHooks(hooks) {
36
- const events =
37
- hooks && typeof hooks === "object" ? Object.keys(hooks) : [];
36
+ const events = hooks && typeof hooks === "object" ? Object.keys(hooks) : [];
38
37
  if (events.length === 0) {
39
38
  return (
40
39
  "No settings.json hooks loaded.\n" +
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Slash Command Registry - Singleton for managing REPL slash commands
3
+ * Provides centralized command registration and lookup (ESM)
4
+ */
5
+
6
+ import { formatBackgroundTasks } from "./tasks-status.js";
7
+ import { runDoctorChecks } from "./doctor-status.js";
8
+
9
+ export class SlashCommandRegistry {
10
+ static _instance = null;
11
+
12
+ constructor() {
13
+ this._commands = new Map();
14
+ this._registerBuiltinCommands();
15
+ }
16
+
17
+ static getInstance() {
18
+ if (!SlashCommandRegistry._instance) {
19
+ SlashCommandRegistry._instance = new SlashCommandRegistry();
20
+ }
21
+ return SlashCommandRegistry._instance;
22
+ }
23
+
24
+ static resetInstance() {
25
+ SlashCommandRegistry._instance = null;
26
+ }
27
+
28
+ register(name, options = {}) {
29
+ this._commands.set(name, {
30
+ name,
31
+ description: options.description || "",
32
+ handler: options.handler || (() => {}),
33
+ aliases: options.aliases || [],
34
+ });
35
+ }
36
+
37
+ getCommand(name) {
38
+ return this._commands.get(name);
39
+ }
40
+
41
+ getAllCommands() {
42
+ return Array.from(this._commands.values());
43
+ }
44
+
45
+ hasCommand(name) {
46
+ return this._commands.has(name);
47
+ }
48
+
49
+ _registerBuiltinCommands() {
50
+ // All Claude Code parity commands
51
+ const commands = [
52
+ [
53
+ "/bug",
54
+ "Submit a bug report",
55
+ (args, { write }) => {
56
+ write(
57
+ "Bug report feature coming soon. Open issues at: https://github.com/chainlesschain/chainlesschain/issues",
58
+ );
59
+ },
60
+ ],
61
+ [
62
+ "/clear",
63
+ "Clear conversation history",
64
+ async (args, { repl }) => {
65
+ if (repl?.clearConversation) await repl.clearConversation();
66
+ },
67
+ ],
68
+ [
69
+ "/compact",
70
+ "Compact and summarize context",
71
+ (args, { write }) => {
72
+ write("Compacting conversation context...");
73
+ },
74
+ ],
75
+ [
76
+ "/config",
77
+ "View/edit configuration",
78
+ (args, { write }) => {
79
+ write("Use `cc config` command to manage configuration");
80
+ },
81
+ ],
82
+ [
83
+ "/cost",
84
+ "Show token usage and cost",
85
+ (args, { write, tokenTracker }) => {
86
+ if (tokenTracker) {
87
+ const stats = tokenTracker.getStats();
88
+ write(
89
+ `Total tokens: ${stats.totalTokens}\nEstimated cost: $${stats.estimatedCost?.toFixed(4) || "0.0000"}`,
90
+ );
91
+ } else {
92
+ write("Cost tracking active");
93
+ }
94
+ },
95
+ ],
96
+ [
97
+ "/doctor",
98
+ "Check system health",
99
+ async (args, { write }) => {
100
+ write("Running system diagnostics...");
101
+ await runDoctorChecks(write);
102
+ },
103
+ ],
104
+ [
105
+ "/help",
106
+ "Show help for slash commands",
107
+ (args, { write }) => {
108
+ write("Available slash commands:\n");
109
+ for (const cmd of this.getAllCommands()) {
110
+ write(` ${cmd.name.padEnd(20)} ${cmd.description}`);
111
+ }
112
+ },
113
+ ],
114
+ [
115
+ "/init",
116
+ "Initialize ChainlessChain",
117
+ (args, { write }) => {
118
+ write("Run `cc setup` to initialize ChainlessChain");
119
+ },
120
+ ],
121
+ [
122
+ "/login",
123
+ "Authenticate with services",
124
+ (args, { write }) => {
125
+ write("Login/authentication initialized");
126
+ },
127
+ ],
128
+ [
129
+ "/logout",
130
+ "Sign out of services",
131
+ (args, { write }) => {
132
+ write("Logged out successfully");
133
+ },
134
+ ],
135
+ [
136
+ "/pr",
137
+ "Create/review pull requests",
138
+ (args, { write }) => {
139
+ write("PR review mode activated");
140
+ },
141
+ ],
142
+ [
143
+ "/publish",
144
+ "Publish to registry",
145
+ (args, { write }) => {
146
+ write("Publishing to registry...");
147
+ },
148
+ ],
149
+ [
150
+ "/resume",
151
+ "Resume previous session",
152
+ (args, { write }) => {
153
+ write("Use /sessions to list available sessions");
154
+ },
155
+ ],
156
+ [
157
+ "/review",
158
+ "Request code review",
159
+ (args, { write }) => {
160
+ write("Starting code review...");
161
+ },
162
+ ],
163
+ [
164
+ "/tasks",
165
+ "Show background tasks",
166
+ (args, { write }) => {
167
+ write(formatBackgroundTasks());
168
+ },
169
+ ],
170
+ [
171
+ "/terminal-setup",
172
+ "Setup terminal integration",
173
+ (args, { write }) => {
174
+ write("Terminal setup complete. Shell integration enabled.");
175
+ },
176
+ ],
177
+ [
178
+ "/vim",
179
+ "Toggle Vim editing mode",
180
+ (args, { write, repl }) => {
181
+ if (repl?.toggleVimMode) {
182
+ repl.toggleVimMode();
183
+ write("Vim mode toggled");
184
+ } else {
185
+ write("Vim mode not available in this terminal");
186
+ }
187
+ },
188
+ ],
189
+ ];
190
+
191
+ for (const [name, description, handler] of commands) {
192
+ this.register(name, { description, handler });
193
+ }
194
+ }
195
+ }
196
+
197
+ export default SlashCommandRegistry;
@@ -34,3 +34,34 @@ export function parseThinkCommand(trimmed) {
34
34
  // An explicit effort level (low/medium/high/…) — passed through to the engine.
35
35
  return { thinking: arg, label: arg, anthropic: true };
36
36
  }
37
+
38
+ /**
39
+ * Pure parser for the REPL `/effort low|medium|high|xhigh` command — a discrete,
40
+ * validated alias over `/think <level>` (Claude-Code `/effort` parity). Returns
41
+ * the same shape parseThinkCommand yields ({ thinking, label, anthropic }) so the
42
+ * REPL applies it identically, or `{ error }` for a missing/unknown level, or
43
+ * null when the input is not an effort command (REPL falls through).
44
+ *
45
+ * /effort low|medium|high|xhigh (synonyms: med→medium, max→xhigh)
46
+ */
47
+ export function parseEffortCommand(trimmed) {
48
+ const t = String(trimmed == null ? "" : trimmed).trim();
49
+ if (t !== "/effort" && !t.startsWith("/effort ")) return null;
50
+ const arg = t.slice("/effort".length).trim().toLowerCase();
51
+ if (!arg) {
52
+ return { error: "usage: /effort low|medium|high|xhigh" };
53
+ }
54
+ const LEVELS = {
55
+ low: "low",
56
+ medium: "medium",
57
+ med: "medium",
58
+ high: "high",
59
+ xhigh: "xhigh",
60
+ max: "xhigh",
61
+ };
62
+ const level = LEVELS[arg];
63
+ if (!level) {
64
+ return { error: `unknown effort "${arg}" — use low|medium|high|xhigh` };
65
+ }
66
+ return { thinking: level, label: `effort ${level}`, anthropic: true };
67
+ }