chainlesschain 0.162.78 → 0.162.80

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 (194) hide show
  1. package/README.md +37 -1
  2. package/bin/chainlesschain.js +20 -1
  3. package/package.json +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-BhKMd38k.js → AIOps-CwebRiRI.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-BzhKY5C_.js → ActionButton-C7h2xsW3.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-CATIz2Jc.js → Analytics-BRdOQzzK.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-eCx64YWg.js → AppLayout-D_i-Jbsu.js} +5 -5
  8. package/src/assets/web-panel/assets/{Audit-CGOHfCHj.js → Audit-AgCF_nLK.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-Dyr6R0Ra.js → Backup-Be9up1Uo.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CVhBu7NZ.js → BaseInput-2j-7gyTU.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DOCCKp2k.js → Chat-ZyYadHdk.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-DcXCCnjN.js → ChatBubbleRenderer-CwnbmcAg.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-3yjnENud.js → Checkbox-Di0bejSO.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-D06sn8kB.js → Codegen-BgEwqrVh.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-Bjn5vFES.js → Col-FIduoerd.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-BYHpQHmf.js → Community-Bf7olKXg.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-MKRmnUDQ.js → Compact-CsjIF6B3.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CVtPe8dh.js → Compliance-CQchRaQh.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BRu5M3dv.js → Cowork-gJzDgX9E.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-D_7eU5Ut.js → Cron-CDjeagXb.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BFyVp_e9.js → Crosschain-D4UE5bt0.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-DRoG7638.js → DID-OwvsxTzD.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-NfM_v-Oe.js → Dashboard-CbmOlZ1l.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CGN1Ksu0.js → Dropdown-B6tBUMev.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-DhsY_z_a.js → EmailListRenderer-DnM2-O3n.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-vW_VsKUG.js → FamilyGuardDashboard-DPD9znJH.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-D2ob_c7h.js → Federation-DjUj87Vr.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-Cpem15Pr.js → FormItemContext-DyPgrKLf.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-P6XfmXwT.js → GenericCardRenderer-D3fmbO1W.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-CfSeec1R.js → Git-IvwC_R2h.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-4ipIpqNl.js → Governance-CTVEvxpW.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CiQY_P9Y.js → Inference-DQlp7Rf1.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-B3Qem78R.js → KnowledgeGraph-Cg8pVh5j.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-De2zWVy6.js → Logs-D7kLXyaK.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-CTNu4c1A.js → Marketplace-QOj6g-oT.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-Xx25EA2f.js → McpTools-PO9yrTD6.js} +5 -5
  37. package/src/assets/web-panel/assets/{Memory-YzzCCrch.js → Memory-B1FwSFmt.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-CJZY98f0.js → MobileBridge-CYiQSoKu.js} +3 -3
  39. package/src/assets/web-panel/assets/{MobileProjects-Dw7yl4KN.js → MobileProjects-BThUga4r.js} +1 -1
  40. package/src/assets/web-panel/assets/{Mtc-D7TzGJhH.js → Mtc-B4pMzmr7.js} +4 -4
  41. package/src/assets/web-panel/assets/{MtcAudit-THyGhf0h.js → MtcAudit-D6-KGsvR.js} +6 -6
  42. package/src/assets/web-panel/assets/{Multisig-RVxuGPUR.js → Multisig-BlZigJMj.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-DK7TCzKF.js → NLProgramming-Dhy92OLw.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-BaOU0psj.js → Notes-DOSv2Lb0.js} +4 -4
  45. package/src/assets/web-panel/assets/{NotificationSettings-BMivJy85.js → NotificationSettings-FRWsHQfi.js} +1 -1
  46. package/src/assets/web-panel/assets/{OrderTableRenderer-BZOiY8Yw.js → OrderTableRenderer-xRSRWRZg.js} +1 -1
  47. package/src/assets/web-panel/assets/{Organization-zVRtW1n_.js → Organization-DApwYY-B.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-C0YLldFH.js → Overflow-DyJQHxIY.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-Xxgzghqp.js → P2P-NKTPd_Bn.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-DH_LO13b.js → PdhVaultBrowser-DCgGt1BE.js} +5 -5
  51. package/src/assets/web-panel/assets/{Permissions-CvAd1VBw.js → Permissions-BX9MCb2z.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-CWQGgCAK.js → PersonalDataHub-Bcg4az84.js} +3 -3
  53. package/src/assets/web-panel/assets/{Pipeline-BNAoh-Lb.js → Pipeline-DjsbfwbG.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-CNO5pFq-.js → Privacy-kDWl06vo.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-WaVVDsm3.js → ProjectInit-yCe-Imkv.js} +2 -2
  56. package/src/assets/web-panel/assets/{ProjectSettings-D1WfkuJ3.js → ProjectSettings-tVcxlGJ5.js} +2 -2
  57. package/src/assets/web-panel/assets/{Projects-BzjvJYMW.js → Projects-DGL4Za4o.js} +1 -1
  58. package/src/assets/web-panel/assets/{Providers-IOOJ4_wy.js → Providers-CciGxskW.js} +1 -1
  59. package/src/assets/web-panel/assets/{QuickAsk-ChHZqVZy.js → QuickAsk-It17rT4F.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-CSiW6Qv9.js → Recommend-CixKdpBl.js} +1 -1
  61. package/src/assets/web-panel/assets/{Reputation-BQe0rkfF.js → Reputation-LB0_D2lx.js} +1 -1
  62. package/src/assets/web-panel/assets/{Row-Dem0Wxxb.js → Row-BoiDd-zb.js} +1 -1
  63. package/src/assets/web-panel/assets/{RssFeed-pBY5G41C.js → RssFeed-yA5FdTgh.js} +2 -2
  64. package/src/assets/web-panel/assets/{Search-CtRepO6B.js → Search-xYldUFeJ.js} +1 -1
  65. package/src/assets/web-panel/assets/{Security-nrSlKpWq.js → Security-BtRMnkFm.js} +4 -4
  66. package/src/assets/web-panel/assets/{Services-DeaDBASi.js → Services-CNKTgE2v.js} +2 -2
  67. package/src/assets/web-panel/assets/{Skeleton-Cz9R-Wjb.js → Skeleton-B9goiUo_.js} +1 -1
  68. package/src/assets/web-panel/assets/{Skills-B3U-XLH3.js → Skills-CUf2Z5Ge.js} +1 -1
  69. package/src/assets/web-panel/assets/{Sla-Bu46dIA_.js → Sla-TPga8c2I.js} +1 -1
  70. package/src/assets/web-panel/assets/{SpeechSettings-C9Z0V0pk.js → SpeechSettings-B8zrmLP6.js} +1 -1
  71. package/src/assets/web-panel/assets/{SyncSettings-Ctj9KHHr.js → SyncSettings-DGyAbZ84.js} +2 -2
  72. package/src/assets/web-panel/assets/{Tasks-D4upQgR_.js → Tasks-DPeVrQNM.js} +1 -1
  73. package/src/assets/web-panel/assets/{Templates-JHsPGU_c.js → Templates-CNLco6pc.js} +1 -1
  74. package/src/assets/web-panel/assets/{Tenant-uoaQL3fB.js → Tenant-CL9Eczo8.js} +1 -1
  75. package/src/assets/web-panel/assets/Terminal-DGLvbp97.js +3 -0
  76. package/src/assets/web-panel/assets/{TimelineRenderer-BTicmSAV.js → TimelineRenderer-Cv0LxMwd.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tokens-Bp3BUe2K.js → Tokens-DLhHgtcS.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trigger-CgoISw5d.js → Trigger-DzDaE-An.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trust-CC29awNT.js → Trust-CRh-fhYe.js} +1 -1
  80. package/src/assets/web-panel/assets/{UkeySign-CB1SB6Nc.js → UkeySign-_xBJ16UC.js} +1 -1
  81. package/src/assets/web-panel/assets/{VideoEditing-D7vptDUg.js → VideoEditing-Z5m_edIa.js} +1 -1
  82. package/src/assets/web-panel/assets/{Wallet-BWfjzF7p.js → Wallet-DgmchNit.js} +4 -4
  83. package/src/assets/web-panel/assets/{WebAuthn-Dzz5OnPc.js → WebAuthn-BxuKxjuf.js} +5 -5
  84. package/src/assets/web-panel/assets/{WorkflowEditor-CiDeVmsG.js → WorkflowEditor-luJ180aM.js} +1 -1
  85. package/src/assets/web-panel/assets/{chat-DQbciNb5.js → chat-DzglnTps.js} +1 -1
  86. package/src/assets/web-panel/assets/{colors-DcLbPJzb.js → colors-DelLNoxZ.js} +1 -1
  87. package/src/assets/web-panel/assets/{compact-item-CvYrR3rc.js → compact-item-BZaabUge.js} +1 -1
  88. package/src/assets/web-panel/assets/{createContext-BR4P7Rgm.js → createContext-DqTSTjmk.js} +1 -1
  89. package/src/assets/web-panel/assets/devWarning-CJLMPKYL.js +1 -0
  90. package/src/assets/web-panel/assets/{hasIn-IQ88RNRJ.js → hasIn-CAeHUQj2.js} +1 -1
  91. package/src/assets/web-panel/assets/index-7CJalvEf.js +1 -0
  92. package/src/assets/web-panel/assets/{index-Bw0Dm_P6.js → index-7FxBHcH8.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-Db5LFFCN.js → index-BAcpfWwI.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B5W1vQHV.js → index-BAfdWN9t.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BUTN1VlO.js → index-BR-DF81e.js} +3 -3
  96. package/src/assets/web-panel/assets/{index-BmPuR0aA.js → index-BTbN0V4A.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-D8OJdOc_.js → index-Bv2Tp7kz.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BhkZZXtI.js → index-BzLgm3Jm.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CzERBV9P.js → index-CBZPDGTg.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-UbB2IcFR.js → index-CBtnHlYF.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-eKd1n8pw.js → index-CDw1am9U.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-JqOP7puJ.js → index-CI5cynRw.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BiMlLIZ-.js → index-CKZQVcH1.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CgP5aQmA.js → index-CV4FisuU.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BH2RT15D.js → index-CaSLz8-6.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DgaCUxpi.js → index-Cj7oeTxA.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DdQBxvpt.js → index-Clq1OP4B.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Bl1TSbTE.js → index-CppTZ4SW.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BQXs-5db.js → index-D-QuIaEh.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DGwa8mnJ.js → index-D-lVDXUg.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DHIp5msb.js → index-DE4-6oHW.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CCO8yc1h.js → index-DM7xncnU.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-b6FjzfoJ.js → index-DRt2lx0X.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bo7HAK6G.js → index-DSATjRyg.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Dpmnk2qv.js → index-DU9QWJO5.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Mn8_ryOe.js → index-DXvcxNo5.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dox9vEhP.js → index-DhMSUhbW.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-bRT7u-51.js → index-Dk1R9vFq.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BHxJnExB.js → index-DrSuq6t6.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CPOupQSX.js → index-DtfTElxo.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BxY0ozve.js → index-KeadEGaZ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BvQpTO67.js → index-NZBXGj64.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CiOZ_Whh.js → index-OGKhEFZZ.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CeCWyiFl.js → index-RZ23Wlp8.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BVb6RI7f.js → index-WzAdJ0PX.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-Cm74AosZ.js → index-Xo2WWPZ4.js} +1 -1
  127. package/src/assets/web-panel/assets/index-_hLbeSOT.js +1 -0
  128. package/src/assets/web-panel/assets/{index-CE2mqX8w.js → index-kJ30C4m8.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Bu8931Yi.js → index-vLR-ssxc.js} +1 -1
  130. package/src/assets/web-panel/assets/{initDefaultProps-C0arzCLE.js → initDefaultProps-BiHvIjo1.js} +1 -1
  131. package/src/assets/web-panel/assets/{motion-C1K6JxwD.js → motion-COD0OBOe.js} +1 -1
  132. package/src/assets/web-panel/assets/{move-DREsRLHj.js → move-DJNLMhIj.js} +1 -1
  133. package/src/assets/web-panel/assets/{omit-BtPS3EDq.js → omit-4qrDRhlN.js} +1 -1
  134. package/src/assets/web-panel/assets/{pickAttrs-BPz6tHoT.js → pickAttrs-3jv8tAgW.js} +1 -1
  135. package/src/assets/web-panel/assets/{placementArrow-B0CR_CSI.js → placementArrow-N1UVUOH_.js} +1 -1
  136. package/src/assets/web-panel/assets/{responsiveObserve-Ch2ojiNn.js → responsiveObserve-D67_gjCH.js} +1 -1
  137. package/src/assets/web-panel/assets/{slide-9qU9vOhj.js → slide-DiDh7_u4.js} +1 -1
  138. package/src/assets/web-panel/assets/{statusUtils-Cr4fICjV.js → statusUtils-Dzz3tSiz.js} +1 -1
  139. package/src/assets/web-panel/assets/{styleChecker-Cor2-FwV.js → styleChecker-L-tgt7xx.js} +1 -1
  140. package/src/assets/web-panel/assets/{useFlexGapSupport-BINo_rNH.js → useFlexGapSupport-vAgElNal.js} +1 -1
  141. package/src/assets/web-panel/assets/{useFs-Dm1tDNYC.js → useFs-af0c_HYI.js} +1 -1
  142. package/src/assets/web-panel/assets/{usePersonalDataHub-__JgBEkX.js → usePersonalDataHub-V9U2Mbny.js} +1 -1
  143. package/src/assets/web-panel/assets/{vnode-1hQKpRgP.js → vnode-C7zS_LLr.js} +1 -1
  144. package/src/assets/web-panel/assets/{zoom-C1EY9X2J.js → zoom-DdXBDemd.js} +1 -1
  145. package/src/assets/web-panel/index.html +1 -1
  146. package/src/commands/audit.js +4 -3
  147. package/src/commands/automation.js +6 -14
  148. package/src/commands/bi.js +10 -9
  149. package/src/commands/codegen.js +5 -13
  150. package/src/commands/dao.js +8 -6
  151. package/src/commands/dbevo.js +13 -14
  152. package/src/commands/economy.js +3 -2
  153. package/src/commands/evolution.js +3 -2
  154. package/src/commands/federation.js +4 -3
  155. package/src/commands/governance.js +9 -4
  156. package/src/commands/hardening.js +5 -4
  157. package/src/commands/incentive.js +6 -5
  158. package/src/commands/kg.js +17 -10
  159. package/src/commands/lowcode.js +23 -11
  160. package/src/commands/marketplace.js +4 -3
  161. package/src/commands/mcp.js +17 -5
  162. package/src/commands/ops.js +9 -4
  163. package/src/commands/recommend.js +7 -5
  164. package/src/commands/scim.js +3 -2
  165. package/src/commands/session.js +9 -6
  166. package/src/commands/social.js +4 -3
  167. package/src/commands/sync.js +3 -2
  168. package/src/commands/tenant.js +11 -6
  169. package/src/commands/zkp.js +8 -9
  170. package/src/gateways/ws/ws-agent-handler.js +12 -3
  171. package/src/gateways/ws/ws-server.js +6 -0
  172. package/src/harness/background-task-manager.js +44 -18
  173. package/src/harness/mcp-client.js +125 -46
  174. package/src/lib/chat-core.js +209 -107
  175. package/src/lib/claude-code-bridge.js +13 -1
  176. package/src/lib/dao-governance.js +3 -3
  177. package/src/lib/downloader.js +82 -25
  178. package/src/lib/headless-config-command.js +62 -0
  179. package/src/lib/json-schema-output.js +55 -11
  180. package/src/lib/mcp-oauth.js +110 -21
  181. package/src/lib/mcp-serve.js +70 -11
  182. package/src/lib/multisig-runtime.js +22 -3
  183. package/src/lib/parse-json-option.js +35 -0
  184. package/src/lib/parse-number-option.js +27 -0
  185. package/src/lib/runnable-provider.js +216 -0
  186. package/src/repl/agent-repl.js +76 -17
  187. package/src/repl/config-summary.js +66 -0
  188. package/src/runtime/agent-core.js +210 -37
  189. package/src/runtime/headless-runner.js +49 -1
  190. package/src/runtime/headless-stream.js +34 -0
  191. package/src/assets/web-panel/assets/Terminal-CWRWr8bq.js +0 -3
  192. package/src/assets/web-panel/assets/devWarning-CnV02N63.js +0 -1
  193. package/src/assets/web-panel/assets/index-DJ2gkaIH.js +0 -1
  194. package/src/assets/web-panel/assets/index-Dvm_-AOi.js +0 -1
@@ -5,6 +5,8 @@
5
5
 
6
6
  import chalk from "chalk";
7
7
  import { logger } from "../lib/logger.js";
8
+ import { parseJsonOption } from "../lib/parse-json-option.js";
9
+ import { parseNumberOption } from "../lib/parse-number-option.js";
8
10
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
9
11
  import {
10
12
  ensureDAOv2Tables,
@@ -109,7 +111,7 @@ export function registerDaoCommand(program) {
109
111
  proposalId,
110
112
  options.voter,
111
113
  direction,
112
- parseFloat(options.weight),
114
+ parseNumberOption(options.weight, "--weight", 1),
113
115
  );
114
116
  logger.success("Vote recorded");
115
117
  logger.log(
@@ -144,7 +146,7 @@ export function registerDaoCommand(program) {
144
146
  db,
145
147
  delegator,
146
148
  delegateTo,
147
- parseFloat(options.weight),
149
+ parseNumberOption(options.weight, "--weight", 1),
148
150
  );
149
151
  logger.success("Delegation set");
150
152
  logger.log(` ${chalk.bold("From:")} ${result.delegator}`);
@@ -383,7 +385,7 @@ export function registerDaoCommand(program) {
383
385
  description: options.description,
384
386
  proposerDid: options.proposerDid || "did:cli:user",
385
387
  type: options.type,
386
- actions: JSON.parse(options.actions),
388
+ actions: parseJsonOption(options.actions, "--actions"),
387
389
  votingDurationMs: options.votingDuration
388
390
  ? parseInt(options.votingDuration)
389
391
  : undefined,
@@ -489,7 +491,7 @@ export function registerDaoCommand(program) {
489
491
  const d = delegateVotingPower(db, {
490
492
  fromDid,
491
493
  toDid,
492
- weight: parseFloat(options.weight),
494
+ weight: parseNumberOption(options.weight, "--weight", 1),
493
495
  expiresAt: options.expiresAt || null,
494
496
  });
495
497
  logger.success(`Delegated ${fromDid} → ${toDid}`);
@@ -663,7 +665,7 @@ export function registerDaoCommand(program) {
663
665
  const tx = allocateFundsV2(db, {
664
666
  proposalId,
665
667
  recipient: options.recipient,
666
- amount: parseFloat(options.amount),
668
+ amount: parseNumberOption(options.amount, "--amount"),
667
669
  asset: options.asset,
668
670
  memo: options.memo,
669
671
  });
@@ -705,7 +707,7 @@ export function registerDaoCommand(program) {
705
707
  ensureDAOv2Tables(db);
706
708
 
707
709
  const tx = depositToTreasuryV2(db, {
708
- amount: parseFloat(options.amount),
710
+ amount: parseNumberOption(options.amount, "--amount"),
709
711
  asset: options.asset,
710
712
  depositorDid: options.depositorDid,
711
713
  memo: options.memo,
@@ -64,15 +64,7 @@ import {
64
64
  autoFailStuckMigrationRuns,
65
65
  getDbEvoStatsV2,
66
66
  } from "../lib/dbevo.js";
67
-
68
- function _parseMetaV2(raw) {
69
- if (!raw) return undefined;
70
- try {
71
- return JSON.parse(raw);
72
- } catch {
73
- throw new Error("--metadata must be valid JSON");
74
- }
75
- }
67
+ import { parseJsonOption } from "../lib/parse-json-option.js";
76
68
 
77
69
  function _dbFromCtx(cmd) {
78
70
  const root = cmd?.parent?.parent ?? cmd?.parent;
@@ -272,7 +264,14 @@ export function registerDbEvoCommand(program) {
272
264
  .option("--json", "JSON output")
273
265
  .action((sql, durationMs, opts) => {
274
266
  const db = _dbFromCtx(dbevo);
275
- const params = opts.params ? JSON.parse(opts.params) : undefined;
267
+ let params;
268
+ try {
269
+ params = parseJsonOption(opts.params, "--params");
270
+ } catch (e) {
271
+ console.error(e.message);
272
+ process.exitCode = 1;
273
+ return;
274
+ }
276
275
  const result = logQuery(db, sql, parseFloat(durationMs), {
277
276
  params,
278
277
  source: opts.source,
@@ -532,7 +531,7 @@ export function registerDbEvoCommand(program) {
532
531
  databaseId: opts.database,
533
532
  version: opts.version,
534
533
  initialStatus: opts.initialStatus,
535
- metadata: _parseMetaV2(opts.metadata),
534
+ metadata: parseJsonOption(opts.metadata, "--metadata"),
536
535
  });
537
536
  console.log(JSON.stringify(r, null, 2));
538
537
  });
@@ -558,7 +557,7 @@ export function registerDbEvoCommand(program) {
558
557
  .action((id, status, opts) => {
559
558
  const r = setBaselineStatusV2(null, id, status, {
560
559
  reason: opts.reason,
561
- metadata: _parseMetaV2(opts.metadata),
560
+ metadata: parseJsonOption(opts.metadata, "--metadata"),
562
561
  });
563
562
  console.log(JSON.stringify(r, null, 2));
564
563
  });
@@ -602,7 +601,7 @@ export function registerDbEvoCommand(program) {
602
601
  databaseId: opts.database,
603
602
  migrationId: opts.migration,
604
603
  direction: opts.direction,
605
- metadata: _parseMetaV2(opts.metadata),
604
+ metadata: parseJsonOption(opts.metadata, "--metadata"),
606
605
  });
607
606
  console.log(JSON.stringify(r, null, 2));
608
607
  });
@@ -628,7 +627,7 @@ export function registerDbEvoCommand(program) {
628
627
  .action((id, status, opts) => {
629
628
  const r = setMigrationRunStatusV2(null, id, status, {
630
629
  reason: opts.reason,
631
- metadata: _parseMetaV2(opts.metadata),
630
+ metadata: parseJsonOption(opts.metadata, "--metadata"),
632
631
  });
633
632
  console.log(JSON.stringify(r, null, 2));
634
633
  });
@@ -5,6 +5,7 @@
5
5
 
6
6
  import chalk from "chalk";
7
7
  import { logger } from "../lib/logger.js";
8
+ import { parseJsonOption } from "../lib/parse-json-option.js";
8
9
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
9
10
  import {
10
11
  ensureEconomyTables,
@@ -324,7 +325,7 @@ export function registerEconomyCommand(program) {
324
325
  const db = ctx.db.getDatabase();
325
326
  ensureEconomyTables(db);
326
327
 
327
- const metadata = options.metadata ? JSON.parse(options.metadata) : {};
328
+ const metadata = parseJsonOption(options.metadata, "--metadata", {});
328
329
  const nftObj = mintNFT(db, owner, type, metadata);
329
330
  logger.success("NFT minted");
330
331
  logger.log(` ${chalk.bold("ID:")} ${chalk.cyan(nftObj.id)}`);
@@ -722,7 +723,7 @@ export function registerEconomyCommand(program) {
722
723
  owner,
723
724
  assetType,
724
725
  royaltyPercent: options.royalty,
725
- metadata: options.metadata ? JSON.parse(options.metadata) : {},
726
+ metadata: parseJsonOption(options.metadata, "--metadata", {}),
726
727
  });
727
728
  if (options.json) console.log(JSON.stringify(n, null, 2));
728
729
  else
@@ -6,6 +6,7 @@
6
6
  import chalk from "chalk";
7
7
  import ora from "ora";
8
8
  import { logger } from "../lib/logger.js";
9
+ import { parseJsonOption } from "../lib/parse-json-option.js";
9
10
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
11
  import {
11
12
  assessCapability,
@@ -469,7 +470,7 @@ export function registerEvolutionCommand(program) {
469
470
  .option("--json", "Output as JSON")
470
471
  .action((dimension, score, options) => {
471
472
  try {
472
- const metadata = JSON.parse(options.metadata);
473
+ const metadata = parseJsonOption(options.metadata, "--metadata");
473
474
  const r = assessCapabilityV2({
474
475
  dimension,
475
476
  score: parseFloat(score),
@@ -673,7 +674,7 @@ export function registerEvolutionCommand(program) {
673
674
  .option("--json", "Output as JSON")
674
675
  .action((type, options) => {
675
676
  try {
676
- const details = JSON.parse(options.details);
677
+ const details = parseJsonOption(options.details, "--details");
677
678
  const r = recordMilestone({
678
679
  type,
679
680
  description: options.description,
@@ -52,6 +52,7 @@ import {
52
52
  autoIsolateUnhealthyNodes,
53
53
  getFederationHardeningStatsV2,
54
54
  } from "../lib/federation-hardening.js";
55
+ import { parseJsonOption } from "../lib/parse-json-option.js";
55
56
 
56
57
  function _dbFromCtx(cmd) {
57
58
  const root = cmd?.parent?.parent ?? cmd?.parent;
@@ -598,7 +599,7 @@ export function registerFederationCommand(program) {
598
599
  .option("--json", "JSON output")
599
600
  .action((nodeId, opts) => {
600
601
  const db = _dbFromCtx(fed);
601
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
602
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
602
603
  const r = registerNodeV2(db, { nodeId, metadata });
603
604
  if (opts.json) return console.log(JSON.stringify(r, null, 2));
604
605
  console.log(`Registered ${nodeId} (status: ${r.status})`);
@@ -626,7 +627,7 @@ export function registerFederationCommand(program) {
626
627
  const patch = {};
627
628
  if (opts.reason !== undefined) patch.reason = opts.reason;
628
629
  if (opts.metadata !== undefined)
629
- patch.metadata = JSON.parse(opts.metadata);
630
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
630
631
  const r = setNodeStatusV2(db, nodeId, status, patch);
631
632
  if (opts.json) return console.log(JSON.stringify(r, null, 2));
632
633
  console.log(`${nodeId} → ${r.status}`);
@@ -649,7 +650,7 @@ export function registerFederationCommand(program) {
649
650
  .option("--json", "JSON output")
650
651
  .action((nodeId, opts) => {
651
652
  const db = _dbFromCtx(fed);
652
- const metrics = opts.metrics ? JSON.parse(opts.metrics) : undefined;
653
+ const metrics = parseJsonOption(opts.metrics, "--metrics");
653
654
  const r = recordHealthCheckV2(db, {
654
655
  nodeId,
655
656
  checkType: opts.type,
@@ -7,6 +7,7 @@
7
7
 
8
8
  import chalk from "chalk";
9
9
  import { logger } from "../lib/logger.js";
10
+ import { parseJsonOption } from "../lib/parse-json-option.js";
10
11
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
11
12
  import {
12
13
  ensureGovernanceTables,
@@ -648,7 +649,8 @@ export function registerGovernanceCommand(program) {
648
649
  const config = { proposerId, realm: opts.realm };
649
650
  if (opts.displayName) config.displayName = opts.displayName;
650
651
  if (opts.initialStatus) config.initialStatus = opts.initialStatus;
651
- if (opts.metadata) config.metadata = JSON.parse(opts.metadata);
652
+ if (opts.metadata)
653
+ config.metadata = parseJsonOption(opts.metadata, "--metadata");
652
654
  console.log(JSON.stringify(registerProposerV2(null, config), null, 2));
653
655
  });
654
656
 
@@ -667,7 +669,8 @@ export function registerGovernanceCommand(program) {
667
669
  .action((proposerId, status, opts) => {
668
670
  const patch = {};
669
671
  if (opts.reason !== undefined) patch.reason = opts.reason;
670
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
672
+ if (opts.metadata)
673
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
671
674
  console.log(
672
675
  JSON.stringify(
673
676
  setProposerMaturityV2(null, proposerId, status, patch),
@@ -734,7 +737,8 @@ export function registerGovernanceCommand(program) {
734
737
  scope: opts.scope,
735
738
  };
736
739
  if (opts.expiresAt) config.expiresAt = Number(opts.expiresAt);
737
- if (opts.metadata) config.metadata = JSON.parse(opts.metadata);
740
+ if (opts.metadata)
741
+ config.metadata = parseJsonOption(opts.metadata, "--metadata");
738
742
  console.log(JSON.stringify(createDelegationV2(null, config), null, 2));
739
743
  });
740
744
 
@@ -753,7 +757,8 @@ export function registerGovernanceCommand(program) {
753
757
  .action((delegationId, status, opts) => {
754
758
  const patch = {};
755
759
  if (opts.reason !== undefined) patch.reason = opts.reason;
756
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
760
+ if (opts.metadata)
761
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
757
762
  console.log(
758
763
  JSON.stringify(
759
764
  setDelegationStatusV2(null, delegationId, status, patch),
@@ -5,6 +5,7 @@
5
5
 
6
6
  import chalk from "chalk";
7
7
  import { logger } from "../lib/logger.js";
8
+ import { parseJsonOption } from "../lib/parse-json-option.js";
8
9
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
9
10
  import {
10
11
  ensureHardeningTables,
@@ -518,7 +519,7 @@ export function registerHardeningCommand(program) {
518
519
  try {
519
520
  const { db } = await bootstrap();
520
521
  ensureHardeningTables(db);
521
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
522
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
522
523
  const r = registerAuditV2(db, {
523
524
  name,
524
525
  type: opts.type,
@@ -594,7 +595,7 @@ export function registerHardeningCommand(program) {
594
595
  if (opts.errorMessage !== undefined)
595
596
  patch.errorMessage = opts.errorMessage;
596
597
  if (opts.metadata !== undefined)
597
- patch.metadata = JSON.parse(opts.metadata);
598
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
598
599
  const r = setAuditStatusV2(db, auditId, status, patch);
599
600
  if (opts.json) console.log(JSON.stringify(r, null, 2));
600
601
  else console.log(`${auditId} → ${r.status}`);
@@ -644,7 +645,7 @@ export function registerHardeningCommand(program) {
644
645
  try {
645
646
  const { db } = await bootstrap();
646
647
  ensureHardeningTables(db);
647
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
648
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
648
649
  const r = createBaselineV2(db, {
649
650
  name,
650
651
  version: opts.version,
@@ -690,7 +691,7 @@ export function registerHardeningCommand(program) {
690
691
  const patch = {};
691
692
  if (opts.reason !== undefined) patch.reason = opts.reason;
692
693
  if (opts.metadata !== undefined)
693
- patch.metadata = JSON.parse(opts.metadata);
694
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
694
695
  const r = setBaselineStatusV2(db, baselineId, status, patch);
695
696
  if (opts.json) console.log(JSON.stringify(r, null, 2));
696
697
  else console.log(`${baselineId} → ${r.status}`);
@@ -6,6 +6,7 @@
6
6
 
7
7
  import chalk from "chalk";
8
8
  import { logger } from "../lib/logger.js";
9
+ import { parseJsonOption } from "../lib/parse-json-option.js";
9
10
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
11
  import {
11
12
  ensureTokenTables,
@@ -267,7 +268,7 @@ export function registerIncentiveCommand(program) {
267
268
  try {
268
269
  const ctx = await bootstrap({ verbose: program.opts().verbose });
269
270
  const db = _dbFromCtx(ctx);
270
- const metadata = options.metadata ? JSON.parse(options.metadata) : null;
271
+ const metadata = parseJsonOption(options.metadata, "--metadata", null);
271
272
  const contribution = recordContribution(db, {
272
273
  userId,
273
274
  type,
@@ -485,7 +486,7 @@ export function registerIncentiveCommand(program) {
485
486
  const ctx = bootstrap();
486
487
  try {
487
488
  const db = _dbFromCtx(ctx);
488
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
489
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
489
490
  const entry = registerAccountV2(db, { accountId, metadata });
490
491
  logger.log(JSON.stringify(entry, null, 2));
491
492
  } finally {
@@ -514,7 +515,7 @@ export function registerIncentiveCommand(program) {
514
515
  const ctx = bootstrap();
515
516
  try {
516
517
  const db = _dbFromCtx(ctx);
517
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
518
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
518
519
  const entry = setAccountStatusV2(db, accountId, status, {
519
520
  reason: opts.reason,
520
521
  metadata,
@@ -581,7 +582,7 @@ export function registerIncentiveCommand(program) {
581
582
  const ctx = bootstrap();
582
583
  try {
583
584
  const db = _dbFromCtx(ctx);
584
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
585
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
585
586
  const entry = submitClaimV2(db, {
586
587
  claimId,
587
588
  userId: opts.user,
@@ -616,7 +617,7 @@ export function registerIncentiveCommand(program) {
616
617
  const ctx = bootstrap();
617
618
  try {
618
619
  const db = _dbFromCtx(ctx);
619
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
620
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
620
621
  const entry = setClaimStatusV2(db, claimId, status, {
621
622
  reason: opts.reason,
622
623
  metadata,
@@ -7,6 +7,7 @@
7
7
  import fs from "fs";
8
8
  import chalk from "chalk";
9
9
  import { logger } from "../lib/logger.js";
10
+ import { parseJsonOption } from "../lib/parse-json-option.js";
10
11
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
11
12
  import {
12
13
  ensureKnowledgeGraphTables,
@@ -111,9 +112,11 @@ export function registerKgCommand(program) {
111
112
  try {
112
113
  const ctx = await bootstrap({ verbose: program.opts().verbose });
113
114
  const db = _dbFromCtx(ctx);
114
- const properties = options.properties
115
- ? JSON.parse(options.properties)
116
- : null;
115
+ const properties = parseJsonOption(
116
+ options.properties,
117
+ "--properties",
118
+ null,
119
+ );
117
120
  const tags = options.tags
118
121
  ? options.tags
119
122
  .split(",")
@@ -221,9 +224,11 @@ export function registerKgCommand(program) {
221
224
  try {
222
225
  const ctx = await bootstrap({ verbose: program.opts().verbose });
223
226
  const db = _dbFromCtx(ctx);
224
- const properties = options.properties
225
- ? JSON.parse(options.properties)
226
- : null;
227
+ const properties = parseJsonOption(
228
+ options.properties,
229
+ "--properties",
230
+ null,
231
+ );
227
232
  const relation = addRelation(db, {
228
233
  sourceId,
229
234
  targetId,
@@ -492,7 +497,7 @@ export function registerKgCommand(program) {
492
497
  .option("--json", "Output as JSON")
493
498
  .action((entityId, opts) => {
494
499
  try {
495
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
500
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
496
501
  const rec = registerEntityV2(null, {
497
502
  entityId,
498
503
  ownerId: opts.owner,
@@ -533,7 +538,8 @@ export function registerKgCommand(program) {
533
538
  try {
534
539
  const patch = {};
535
540
  if (opts.reason) patch.reason = opts.reason;
536
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
541
+ if (opts.metadata)
542
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
537
543
  const rec = setEntityStatusV2(null, entityId, status, patch);
538
544
  logger.success(`Entity ${entityId} → ${rec.status}`);
539
545
  } catch (err) {
@@ -615,7 +621,7 @@ export function registerKgCommand(program) {
615
621
  .option("--json", "Output as JSON")
616
622
  .action((relationId, opts) => {
617
623
  try {
618
- const metadata = opts.metadata ? JSON.parse(opts.metadata) : undefined;
624
+ const metadata = parseJsonOption(opts.metadata, "--metadata");
619
625
  const rec = registerRelationV2(null, {
620
626
  relationId,
621
627
  sourceEntityId: opts.source,
@@ -659,7 +665,8 @@ export function registerKgCommand(program) {
659
665
  try {
660
666
  const patch = {};
661
667
  if (opts.reason) patch.reason = opts.reason;
662
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
668
+ if (opts.metadata)
669
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
663
670
  const rec = setRelationStatusV2(null, relationId, status, patch);
664
671
  logger.success(`Relation ${relationId} → ${rec.status}`);
665
672
  } catch (err) {
@@ -226,12 +226,18 @@ export function registerLowcodeCommand(program) {
226
226
  const db = ctx.db.getDatabase();
227
227
  ensureLowcodeTables(db);
228
228
 
229
- let config;
230
- try {
231
- config = JSON.parse(options.config);
232
- } catch (_err) {
233
- // Intentionally ignore parse error — use empty config
234
- config = {};
229
+ let config = {};
230
+ if (options.config) {
231
+ try {
232
+ config = JSON.parse(options.config);
233
+ } catch (err) {
234
+ // Non-fatal by design (fall back to empty config), but surface the
235
+ // problem instead of swallowing it — a typo'd --config was silently
236
+ // dropped before, so the data source looked configured but wasn't.
237
+ logger.warn(
238
+ `Ignoring invalid --config JSON (using empty config): ${err.message}`,
239
+ );
240
+ }
235
241
  }
236
242
 
237
243
  const result = addDataSource(db, appId, name, type, config);
@@ -413,11 +419,17 @@ export function registerLowcodeCommand(program) {
413
419
  const db = ctx.db.getDatabase();
414
420
  ensureLowcodeTables(db);
415
421
 
416
- let config;
417
- try {
418
- config = JSON.parse(options.config);
419
- } catch (_err) {
420
- config = {};
422
+ let config = {};
423
+ if (options.config) {
424
+ try {
425
+ config = JSON.parse(options.config);
426
+ } catch (err) {
427
+ // Non-fatal by design (fall back to empty config), but surface the
428
+ // problem instead of swallowing it silently.
429
+ logger.warn(
430
+ `Ignoring invalid --config JSON (using empty config): ${err.message}`,
431
+ );
432
+ }
421
433
  }
422
434
 
423
435
  const result = registerDataSourceV2(db, {
@@ -6,6 +6,7 @@
6
6
 
7
7
  import chalk from "chalk";
8
8
  import { logger } from "../lib/logger.js";
9
+ import { parseJsonOption } from "../lib/parse-json-option.js";
9
10
  import { bootstrap, shutdown } from "../runtime/bootstrap.js";
10
11
  import {
11
12
  ensureMarketplaceTables,
@@ -122,7 +123,7 @@ export function registerMarketplaceCommand(program) {
122
123
  try {
123
124
  const ctx = await bootstrap({ verbose: program.opts().verbose });
124
125
  const db = _dbFromCtx(ctx);
125
- const pricing = options.pricing ? JSON.parse(options.pricing) : null;
126
+ const pricing = parseJsonOption(options.pricing, "--pricing", null);
126
127
  const service = publishService(db, {
127
128
  name,
128
129
  version: options.version,
@@ -246,8 +247,8 @@ export function registerMarketplaceCommand(program) {
246
247
  try {
247
248
  const ctx = await bootstrap({ verbose: program.opts().verbose });
248
249
  const db = _dbFromCtx(ctx);
249
- const input = options.input ? JSON.parse(options.input) : null;
250
- const output = options.output ? JSON.parse(options.output) : null;
250
+ const input = parseJsonOption(options.input, "--input", null);
251
+ const output = parseJsonOption(options.output, "--output", null);
251
252
  const inv = recordInvocation(db, {
252
253
  serviceId,
253
254
  callerId: options.caller,
@@ -22,6 +22,7 @@ import {
22
22
  generateMcpServerScaffold,
23
23
  SUPPORTED_TRANSPORTS,
24
24
  } from "../lib/mcp-scaffold.js";
25
+ import { parseJsonOption } from "../lib/parse-json-option.js";
25
26
  import {
26
27
  CATALOG as REGISTRY_CATALOG,
27
28
  CATEGORIES as REGISTRY_CATEGORIES,
@@ -236,7 +237,9 @@ export function registerMcpCommand(program) {
236
237
  });
237
238
  logger.log(chalk.bold("MCP server ready (Streamable-HTTP)"));
238
239
  logger.log(` URL: ${chalk.cyan(handle.url)}`);
239
- logger.log(` Root: ${handle.root}${handle.readOnly ? " (read-only)" : ""}`);
240
+ logger.log(
241
+ ` Root: ${handle.root}${handle.readOnly ? " (read-only)" : ""}`,
242
+ );
240
243
  if (handle.token) {
241
244
  logger.log(` Auth: Bearer ${handle.token}`);
242
245
  } else {
@@ -555,8 +558,17 @@ export function registerMcpCommand(program) {
555
558
  if (options.json) {
556
559
  console.log(JSON.stringify(result, null, 2));
557
560
  } else {
558
- logger.success(`Connected to ${chalk.cyan(name)}`);
559
- logger.log(` ${chalk.gray("Tools:")} ${result.tools.length}`);
561
+ // initialize succeeded but tools/list failed → connected, yet the
562
+ // tool list is unreliable. Surface it rather than a misleading
563
+ // "Tools: 0" (Claude-Code 2.1.181 parity).
564
+ if (result.toolsError) {
565
+ logger.warn(
566
+ `${chalk.yellow("!")} Connected to ${chalk.cyan(name)} ${chalk.gray("·")} tools fetch failed: ${result.toolsError}`,
567
+ );
568
+ } else {
569
+ logger.success(`Connected to ${chalk.cyan(name)}`);
570
+ logger.log(` ${chalk.gray("Tools:")} ${result.tools.length}`);
571
+ }
560
572
  logger.log(
561
573
  ` ${chalk.gray("Resources:")} ${result.resources.length}`,
562
574
  );
@@ -650,7 +662,7 @@ export function registerMcpCommand(program) {
650
662
  serverName = match.server;
651
663
  }
652
664
 
653
- const args = options.args ? JSON.parse(options.args) : {};
665
+ const args = parseJsonOption(options.args, "--args", {});
654
666
  const spinner = ora(`Calling ${tool}...`).start();
655
667
 
656
668
  const result = await client.callTool(serverName, tool, args);
@@ -822,7 +834,7 @@ export function registerMcpCommand(program) {
822
834
  }
823
835
  server = match.server;
824
836
  }
825
- const args = options.args ? JSON.parse(options.args) : {};
837
+ const args = parseJsonOption(options.args, "--args", {});
826
838
  const result = await client.getPrompt(server, name, args);
827
839
  if (options.json) {
828
840
  console.log(JSON.stringify(result, null, 2));
@@ -61,6 +61,7 @@ import {
61
61
  autoTimeoutStuckRemediations,
62
62
  getAiOpsStatsV2,
63
63
  } from "../lib/aiops.js";
64
+ import { parseJsonOption } from "../lib/parse-json-option.js";
64
65
 
65
66
  function _dbFromCtx(cmd) {
66
67
  const root = cmd?.parent?.parent ?? cmd?.parent;
@@ -549,7 +550,8 @@ export function registerOpsCommand(program) {
549
550
  const config = { playbookId, ownerId: opts.owner };
550
551
  if (opts.name) config.name = opts.name;
551
552
  if (opts.initialStatus) config.initialStatus = opts.initialStatus;
552
- if (opts.metadata) config.metadata = JSON.parse(opts.metadata);
553
+ if (opts.metadata)
554
+ config.metadata = parseJsonOption(opts.metadata, "--metadata");
553
555
  console.log(JSON.stringify(registerPlaybookV2(db, config), null, 2));
554
556
  });
555
557
 
@@ -570,7 +572,8 @@ export function registerOpsCommand(program) {
570
572
  const db = _dbFromCtx(cmd);
571
573
  const patch = {};
572
574
  if (opts.reason !== undefined) patch.reason = opts.reason;
573
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
575
+ if (opts.metadata)
576
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
574
577
  console.log(
575
578
  JSON.stringify(
576
579
  setPlaybookMaturityV2(db, playbookId, status, patch),
@@ -639,7 +642,8 @@ export function registerOpsCommand(program) {
639
642
  playbookId: opts.playbook,
640
643
  };
641
644
  if (opts.incident) config.incidentId = opts.incident;
642
- if (opts.metadata) config.metadata = JSON.parse(opts.metadata);
645
+ if (opts.metadata)
646
+ config.metadata = parseJsonOption(opts.metadata, "--metadata");
643
647
  console.log(JSON.stringify(submitRemediationV2(db, config), null, 2));
644
648
  });
645
649
 
@@ -660,7 +664,8 @@ export function registerOpsCommand(program) {
660
664
  const db = _dbFromCtx(cmd);
661
665
  const patch = {};
662
666
  if (opts.reason !== undefined) patch.reason = opts.reason;
663
- if (opts.metadata) patch.metadata = JSON.parse(opts.metadata);
667
+ if (opts.metadata)
668
+ patch.metadata = parseJsonOption(opts.metadata, "--metadata");
664
669
  console.log(
665
670
  JSON.stringify(
666
671
  setRemediationStatusV2(db, remediationId, status, patch),
@@ -65,6 +65,7 @@ import {
65
65
  autoArchiveStaleFeeds,
66
66
  getRecommendationStatsV2,
67
67
  } from "../lib/content-recommendation.js";
68
+ import { parseJsonOption } from "../lib/parse-json-option.js";
68
69
 
69
70
  function _dbFromCtx(cmd) {
70
71
  const root = cmd?.parent?.parent ?? cmd?.parent;
@@ -140,8 +141,8 @@ export function registerRecommendCommand(program) {
140
141
  .option("--json", "JSON output")
141
142
  .action((userId, opts) => {
142
143
  const db = _dbFromCtx(rec);
143
- const topics = opts.topics ? JSON.parse(opts.topics) : {};
144
- const interactionWeights = opts.weights ? JSON.parse(opts.weights) : {};
144
+ const topics = parseJsonOption(opts.topics, "--topics", {});
145
+ const interactionWeights = parseJsonOption(opts.weights, "--weights", {});
145
146
  const result = createProfile(db, userId, { topics, interactionWeights });
146
147
  if (opts.json) return console.log(JSON.stringify(result, null, 2));
147
148
  if (result.profileId) console.log(`Profile created: ${result.profileId}`);
@@ -158,8 +159,9 @@ export function registerRecommendCommand(program) {
158
159
  .action((userId, opts) => {
159
160
  const db = _dbFromCtx(rec);
160
161
  const params = {};
161
- if (opts.topics) params.topics = JSON.parse(opts.topics);
162
- if (opts.weights) params.interactionWeights = JSON.parse(opts.weights);
162
+ if (opts.topics) params.topics = parseJsonOption(opts.topics, "--topics");
163
+ if (opts.weights)
164
+ params.interactionWeights = parseJsonOption(opts.weights, "--weights");
163
165
  if (opts.decay !== undefined) params.decayFactor = opts.decay;
164
166
  const result = updateProfile(db, userId, params);
165
167
  if (opts.json) return console.log(JSON.stringify(result, null, 2));
@@ -228,7 +230,7 @@ export function registerRecommendCommand(program) {
228
230
  if (!opts.pool) {
229
231
  return console.log("Provide --pool as JSON array of content items.");
230
232
  }
231
- const pool = JSON.parse(opts.pool);
233
+ const pool = parseJsonOption(opts.pool, "--pool");
232
234
  const result = generateRecommendations(db, userId, pool, {
233
235
  limit: opts.limit,
234
236
  minScore: opts.minScore,