chainlesschain 0.162.171 → 0.162.173

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 (176) hide show
  1. package/bin/chainlesschain.js +8 -0
  2. package/package.json +6 -1
  3. package/src/assets/web-panel/assets/{AIOps-Cf8yb18C.js → AIOps-228_yS1K.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CsFT6FMt.js → ActionButton-qEKhWWk_.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-DQe_hXMA.js → Analytics-Drma7Pkx.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-Cl9Pp7jk.js → AppLayout-B-gexhEy.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-CBEzLVjF.js → Artifacts-CWNSO5Af.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-BS2Un14C.js → Audit-DY3j9Ltk.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-DmcDH8OK.js → BackgroundAgents-Bz2pcyfS.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-DvzjTkkn.js → Backup-Bg5aAkWT.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DnbpuyME.js → BaseInput-35_LrETp.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-BJRRCm2P.js → Chat-CWvrCIuL.js} +5 -5
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Bgpxyqd_.js → ChatBubbleRenderer-7iAWWEmJ.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-DFOrWmvm.js → Checkbox-B4qv17qH.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BIQ2kU6Q.js → Codegen-Co18wV4m.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-BI3R-N4I.js → Col-D0RjQKek.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-CPiAwsHT.js → Community-C5r80sMV.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-Bv4cslSK.js → Compact-Cnwsi_GQ.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-CSlDG1NZ.js → Compliance-EFmGHrSw.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CFcRumXf.js → Cowork-7Ix8iqrx.js} +4 -4
  21. package/src/assets/web-panel/assets/{Cron-DKYKMmOn.js → Cron-Dpvn36K7.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CxPMByp2.js → Crosschain-DgwE0dXI.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DJqiYw1C.js → DID-79Xkd_Iy.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-D2dLMxqy.js → Dashboard-BX-kQk9j.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BnJc384A.js → Dropdown-B2hIzIKh.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-DctFvm-J.js → EmailListRenderer-CwgczLkA.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-J_xg-Qop.js → FamilyGuardDashboard-D1dpW73p.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BckL07Uw.js → Federation-CzGSfm-g.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-B8s5ccSO.js → FormItemContext-Bdgq6Ctr.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-hPMBK2No.js → GenericCardRenderer-BdiR-AVP.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-CfMpYLo7.js → Git-CyFl_ZOb.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-Bt3OcrC7.js → Governance-CIJfns5M.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-BlKc336N.js → Inference-U2SL3a9n.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-B6p7og2c.js → KnowledgeGraph-B8TRMic6.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-uv5Re6YR.js → Logs-CN3aA59h.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-CId5JWjX.js → MarkdownRenderer-Op_hHJCw.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-CfNbntHt.js → Marketplace-CIu4bo4n.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-YRXt74Yk.js → McpTools-dMtEtLGH.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-BfQQs-Jd.js → Memory-B2a1qG3t.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-BuGC-4S2.js → MobileBridge-Ci8N7KT8.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-Czieqw1m.js → MobileProjects-CnJwGBSZ.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-DHWHOVCO.js → Mtc-B_yNoA93.js} +5 -5
  43. package/src/assets/web-panel/assets/{MtcAudit-DWSEbMW-.js → MtcAudit-DLYUJLFa.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-DrhEv1vq.js → Multisig-lGvE7Ulk.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-D8wKCu7E.js → NLProgramming-CSl7-p0U.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-AFeqq0I_.js → Notes-CRzhFyCr.js} +4 -4
  47. package/src/assets/web-panel/assets/{NotificationSettings-D6qenYUo.js → NotificationSettings-D8vIFpxx.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-CF0X4fyB.js → OrderTableRenderer-BK07A_0l.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-DdfbNqf6.js → Organization-5CnL1jaB.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-BFEvnLfd.js → Overflow-B4QvQ7ku.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-DtL6wbkz.js → P2P-IwrXGm2f.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-CQPriTud.js → PdhVaultBrowser-CNr6Ocb1.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-Bj25ANmR.js → Permissions-CcKqZlw6.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-BNj2Oux0.js → PersonalDataHub-zUZb-JzZ.js} +3 -3
  55. package/src/assets/web-panel/assets/{Pipeline-Dyj8UEaG.js → Pipeline-mMelf_X6.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-BBUrWRFz.js → Privacy-BaA6CMRz.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-BdX7uQn6.js → ProjectInit-CI8OJYpf.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-BghtW1zr.js → ProjectSettings-C6ZJ3hQv.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-9VTquZCz.js → Projects-BVljPeGz.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-D-0K_Eza.js → Providers-D_bjZHj6.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-DDaN30_D.js → QrScannerModal-TgVSKKTP.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-DfHlifOj.js → QuickAsk-CnnleZmK.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-CgLIvYE2.js → Recommend-zqJL4tgH.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DpOPrwE4.js → RemoteSession-bBFpdwjH.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-wMexlbCE.js → Reputation-tKkKrza-.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-D9aD_nrc.js → Row-DgQaPsSR.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-Drg7l6zu.js → RssFeed-B3PJQQ_a.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-BKO1nrwN.js → Search-BX2HUESa.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-G3Kyk-TG.js → Security-aqzxU6JQ.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-xJReTOna.js → Services-BiehYAcJ.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-ldVDVTPG.js → Skeleton-aWL9v64n.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-emwNYV0j.js → Skills-DnLhre12.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-CZYwGp1K.js → Sla-C2ZJiegm.js} +1 -1
  74. package/src/assets/web-panel/assets/SpeechSettings-BpQdJ1IM.js +1 -0
  75. package/src/assets/web-panel/assets/{SyncSettings-Dcs5Hhj6.js → SyncSettings-C93cxqz8.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-CerFAo26.js → Tasks-oSM3jeQI.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BdZUbOg3.js → Templates-DJa_a4iY.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-B4c_7Bsw.js → Tenant-B7p9ktEF.js} +1 -1
  79. package/src/assets/web-panel/assets/Terminal-aljUKGFD.js +3 -0
  80. package/src/assets/web-panel/assets/{TimelineRenderer-tc6sp0TV.js → TimelineRenderer-CDcFH-4e.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-Bw_vkMJq.js → Tokens-KISm6N5n.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DkbJnpvz.js → Trigger-BBYrtPba.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-CIf9kqN1.js → Trust-BMuSnufM.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-Cjwllnea.js → UkeySign-BqZbe27i.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-kgfkY7AN.js → VideoEditing-C-21zOQc.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-CYWXt4u9.js → Wallet-EwfAuGhE.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-QgPwyWCO.js → WebAuthn-D__2NkcW.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Co0lha18.js → WorkflowEditor-C7pTi9eg.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-CI__Ox-r.js → chat-DGJsLa46.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-Csv0eYYd.js → colors-DLGee_hV.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-e53UCdHy.js → compact-item-uXOmbkDm.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-BMPGRDhV.js → createContext-CsPfwwcp.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-CVrl2cXX.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-Dz68qIAq.js → hasIn-BHvO8oYD.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CoGSbW5J.js → index-477LYji2.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-53ljQo_x.js → index-9F6z582g.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-ajz0E0pK.js → index-B2NtdqkO.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-ygfUVVFv.js → index-B5XTuu1V.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-wcCouSNq.js → index-BDV08Lfd.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-t6f80uqL.js → index-BOXMd0h7.js} +17 -17
  101. package/src/assets/web-panel/assets/index-BPY_5R3R.js +1 -0
  102. package/src/assets/web-panel/assets/{index-BHkDRNA5.js → index-BZa2DYkz.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DCl4Xb4N.js → index-Bb8I5bJW.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BW2dImbg.js → index-By5mviLz.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Dk9Gi8xd.js → index-C0mLGe0N.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CXuON9OG.js → index-C0w_0UmL.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B1s1B8Iy.js → index-CN3eksmo.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DJqQL6so.js → index-CNCYZBCQ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BT3CV4Nh.js → index-Cc_spyrU.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CNtZMPKV.js → index-CeJ_IuUy.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C-NbcAbP.js → index-Ckb7veFD.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-K5E_wjut.js → index-ClWReh9U.js} +1 -1
  113. package/src/assets/web-panel/assets/index-CrRvYSFJ.js +1 -0
  114. package/src/assets/web-panel/assets/{index-5iicv5af.js → index-D3UkkZps.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CrsoSnQF.js → index-D73CnO2G.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-HbhQRrM2.js → index-D7EKxUXQ.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DyqcHiL1.js → index-DA8wNocR.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dtjm1K1a.js → index-DEOm1Go8.js} +1 -1
  119. package/src/assets/web-panel/assets/{index--7tHEadk.js → index-DHMZKkRS.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DnXm3Qsh.js → index-DJBB-U5Z.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DVCd2aMX.js → index-DJkVI1UW.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CpTzqJ0Z.js → index-DbkMc0Qq.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DctYrVMq.js → index-DjX8mK9d.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-_LmPlyeV.js → index-DmcFSHuA.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CvLBQk_M.js → index-DqNI4xlm.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C53o-MdJ.js → index-DvQrYrw_.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BOpz2qS1.js → index-Gqs5qts7.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-N9DkR1i7.js → index-MAaNHDU0.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CYUxs6J1.js → index-YslvEzZs.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-D0bg74e1.js → index-gTQZVYbs.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C5hLtxVz.js → index-hzI1TGEs.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-B4lKPJy1.js → index-vWJiZGAS.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CyLUaP2i.js → index-wnZd4y25.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-DVCeQJrT.js → initDefaultProps-oK6Ac1vm.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-chBCR_8v.js → motion-BmETDqwI.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-BziPlrh6.js → move-0DfUhr7q.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-Cenk0OD7.js → mtc-parser-BDG-x4aO.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-D-AiRsei.js → omit-C_n1NOjZ.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-CHw3Fvqt.js → pickAttrs-j5w-2Trf.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-g8I-rCad.js → placementArrow-DDVTNAah.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-BWffAr9k.js → responsiveObserve-DM30qzcv.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-BmUQqhkb.js → slide-BcVzNlnc.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-B89gCO-y.js → statusUtils-VQh4j7zt.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-x1bnCF73.js → styleChecker-DcHl95y_.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-B-k1_Ggw.js → useFlexGapSupport-C5bRw-Km.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-Bc3PUqQk.js → useFs-IcE9exrQ.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-D8qFDX1I.js → usePersonalDataHub-BGv3NgE4.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-UaL5-WGg.js → vnode-B9pXxNhd.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-Dv7bsbLs.js → zoom-Bba0fIkh.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/permissions.js +24 -1
  152. package/src/index.js +63 -845
  153. package/src/lib/agent-ipc-bus.js +331 -0
  154. package/src/lib/context-source-ledger.js +164 -0
  155. package/src/lib/execution-trace/index.js +10 -0
  156. package/src/lib/execution-trace/metrics-collector.js +218 -0
  157. package/src/lib/execution-trace/trace-context.js +182 -0
  158. package/src/lib/hook-manager.js +17 -0
  159. package/src/lib/hooks-v2-runtime.js +278 -0
  160. package/src/lib/metrics-collector.js +127 -0
  161. package/src/lib/observability/index.js +35 -0
  162. package/src/lib/observability/otlp-exporter.js +260 -0
  163. package/src/lib/otlp-exporter.js +45 -0
  164. package/src/lib/process-execution-broker/SPAWN_AUDIT_REPORT.md +117 -0
  165. package/src/lib/process-execution-broker/index.js +450 -0
  166. package/src/lib/process-execution-broker/patch-child-process.js +50 -0
  167. package/src/lib/process-execution-broker/spawn-audit.json +3814 -0
  168. package/src/lib/runtime-provenance-ledger.js +190 -0
  169. package/src/lib/session-hooks.js +41 -0
  170. package/src/program-base.js +4 -1
  171. package/src/repl/agent-repl.js +2 -0
  172. package/src/assets/web-panel/assets/SpeechSettings-CyaPrzOF.js +0 -1
  173. package/src/assets/web-panel/assets/Terminal-VVFLS3Ol.js +0 -3
  174. package/src/assets/web-panel/assets/devWarning-BIulobq7.js +0 -1
  175. package/src/assets/web-panel/assets/index-BGkiYnET.js +0 -1
  176. package/src/assets/web-panel/assets/index-Eyhrr_3u.js +0 -1
@@ -0,0 +1,127 @@
1
+ /**
2
+ * MetricsCollector - CLI runtime metrics collection (M3)
3
+ *
4
+ * Collects counters, gauges, histograms for performance monitoring
5
+ * with OTLP export support (M8 integration)
6
+ */
7
+
8
+ export class MetricsCollector {
9
+ constructor() {
10
+ this._counters = new Map();
11
+ this._gauges = new Map();
12
+ this._histograms = new Map();
13
+ }
14
+
15
+ /**
16
+ * Increment a counter metric
17
+ * @param {string} name - Metric name
18
+ * @param {number} value - Increment amount (default 1)
19
+ * @param {object} labels - Metric labels
20
+ */
21
+ counter(name, value = 1, labels = {}) {
22
+ const key = this._key(name, labels);
23
+ if (!this._counters.has(key)) {
24
+ this._counters.set(key, { name, value: 0, labels });
25
+ }
26
+ this._counters.get(key).value += value;
27
+ }
28
+
29
+ /**
30
+ * Set a gauge metric
31
+ * @param {string} name - Metric name
32
+ * @param {number} value - Gauge value
33
+ * @param {object} labels - Metric labels
34
+ */
35
+ gauge(name, value, labels = {}) {
36
+ const key = this._key(name, labels);
37
+ this._gauges.set(key, { name, value, labels, timestamp: Date.now() });
38
+ }
39
+
40
+ /**
41
+ * Record a histogram observation
42
+ * @param {string} name - Metric name
43
+ * @param {number} value - Observed value
44
+ * @param {object} labels - Metric labels
45
+ */
46
+ histogram(name, value, labels = {}) {
47
+ const key = this._key(name, labels);
48
+ if (!this._histograms.has(key)) {
49
+ this._histograms.set(key, {
50
+ name,
51
+ count: 0,
52
+ sum: 0,
53
+ min: Infinity,
54
+ max: -Infinity,
55
+ labels,
56
+ values: [],
57
+ });
58
+ }
59
+ const h = this._histograms.get(key);
60
+ h.count++;
61
+ h.sum += value;
62
+ h.min = Math.min(h.min, value);
63
+ h.max = Math.max(h.max, value);
64
+ // Keep last 1000 values for percentile calculation
65
+ if (h.values.length < 1000) {
66
+ h.values.push(value);
67
+ } else {
68
+ h.values[h.count % 1000] = value;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Time a function execution and record duration
74
+ * @param {string} name - Metric name
75
+ * @param {Function} fn - Function to time
76
+ * @param {object} labels - Metric labels
77
+ * @returns {*} Function result
78
+ */
79
+ async timer(name, fn, labels = {}) {
80
+ const start = performance.now();
81
+ try {
82
+ return await fn();
83
+ } finally {
84
+ const duration = performance.now() - start;
85
+ this.histogram(name, duration, labels);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Get all collected metrics
91
+ * @returns {object} All metrics
92
+ */
93
+ snapshot() {
94
+ return {
95
+ counters: Array.from(this._counters.values()),
96
+ gauges: Array.from(this._gauges.values()),
97
+ histograms: Array.from(this._histograms.values()).map((h) => ({
98
+ name: h.name,
99
+ count: h.count,
100
+ sum: h.sum,
101
+ min: h.min,
102
+ max: h.max,
103
+ avg: h.sum / h.count,
104
+ labels: h.labels,
105
+ })),
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Reset all metrics
111
+ */
112
+ reset() {
113
+ this._counters.clear();
114
+ this._gauges.clear();
115
+ this._histograms.clear();
116
+ }
117
+
118
+ _key(name, labels) {
119
+ const labelStr = Object.entries(labels)
120
+ .sort(([a], [b]) => a.localeCompare(b))
121
+ .map(([k, v]) => `${k}=${v}`)
122
+ .join(",");
123
+ return labelStr ? `${name}{${labelStr}}` : name;
124
+ }
125
+ }
126
+
127
+ export const metricsCollector = new MetricsCollector();
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Observability - 可观测性模块统一导出
3
+ * M3 阶段模块:包含分布式追踪 + 性能指标收集
4
+ */
5
+
6
+ import {
7
+ traceContext,
8
+ TraceContext,
9
+ } from "../execution-trace/trace-context.js";
10
+ import {
11
+ metricsCollector,
12
+ MetricsCollector,
13
+ } from "../execution-trace/metrics-collector.js";
14
+
15
+ export { traceContext, TraceContext, metricsCollector, MetricsCollector };
16
+
17
+ /**
18
+ * 初始化可观测性模块
19
+ * @param {Object} [options={}]
20
+ * @param {boolean} [options.tracingEnabled=true] - 是否启用追踪
21
+ * @param {boolean} [options.metricsEnabled=true] - 是否启用指标收集
22
+ */
23
+ export function initObservability(options = {}) {
24
+ const { tracingEnabled = true, metricsEnabled = true } = options;
25
+
26
+ // 可观测性模块初始化逻辑
27
+ return {
28
+ tracingEnabled,
29
+ metricsEnabled,
30
+ traceContext,
31
+ metricsCollector,
32
+ };
33
+ }
34
+
35
+ export * from "../execution-trace/index.js";
@@ -0,0 +1,260 @@
1
+ /**
2
+ * OTLP Exporter — M8 Observability
3
+ * OpenTelemetry Protocol exporter for spans and metrics
4
+ * Sends to localhost:4318 by default, with batching and retry
5
+ */
6
+
7
+ import http from "node:http";
8
+ import https from "node:https";
9
+ import { URL } from "node:url";
10
+
11
+ class OtlpExporter {
12
+ constructor(options = {}) {
13
+ this.endpoint =
14
+ options.endpoint ||
15
+ process.env.OTEL_EXPORTER_OTLP_ENDPOINT ||
16
+ "http://localhost:4318";
17
+ this.headers = options.headers || {};
18
+ this.serviceName =
19
+ options.serviceName ||
20
+ process.env.OTEL_SERVICE_NAME ||
21
+ "chainlesschain-cli";
22
+ this.batchSize = options.batchSize || 512;
23
+ this.flushIntervalMs = options.flushIntervalMs || 5000;
24
+ this._spanBuffer = [];
25
+ this._metricBuffer = [];
26
+ this._timer = null;
27
+ this._droppedSpans = 0;
28
+ this._droppedMetrics = 0;
29
+ this._failedExports = 0;
30
+ this._successfulExports = 0;
31
+ this._enabled = options.enabled !== false;
32
+ if (this._enabled) {
33
+ this._startFlushTimer();
34
+ }
35
+ }
36
+
37
+ _startFlushTimer() {
38
+ if (this._timer) clearInterval(this._timer);
39
+ this._timer = setInterval(() => this.flush(), this.flushIntervalMs);
40
+ this._timer.unref?.();
41
+ }
42
+
43
+ _getHttpModule(urlStr) {
44
+ return urlStr.startsWith("https:") ? https : http;
45
+ }
46
+
47
+ _post(path, data, contentType) {
48
+ if (!this._enabled) return Promise.resolve();
49
+ return new Promise((resolve) => {
50
+ try {
51
+ const url = new URL(path, this.endpoint);
52
+ const mod = this._getHttpModule(url.protocol);
53
+ const payload = JSON.stringify(data);
54
+ const req = mod.request(
55
+ {
56
+ hostname: url.hostname,
57
+ port: url.port,
58
+ path: url.pathname + url.search,
59
+ method: "POST",
60
+ headers: {
61
+ "Content-Type": contentType,
62
+ "Content-Length": Buffer.byteLength(payload),
63
+ ...this.headers,
64
+ },
65
+ timeout: 10000,
66
+ },
67
+ (res) => {
68
+ res.resume();
69
+ if (res.statusCode >= 200 && res.statusCode < 300) {
70
+ this._successfulExports++;
71
+ } else {
72
+ this._failedExports++;
73
+ }
74
+ resolve();
75
+ },
76
+ );
77
+ req.on("error", () => {
78
+ this._failedExports++;
79
+ resolve();
80
+ });
81
+ req.on("timeout", () => {
82
+ req.destroy();
83
+ this._failedExports++;
84
+ resolve();
85
+ });
86
+ req.write(payload);
87
+ req.end();
88
+ } catch {
89
+ resolve();
90
+ }
91
+ });
92
+ }
93
+
94
+ exportSpans(spans) {
95
+ if (!this._enabled) return;
96
+ for (const span of spans) {
97
+ if (this._spanBuffer.length >= this.batchSize) {
98
+ this._spanBuffer.shift();
99
+ this._droppedSpans++;
100
+ }
101
+ this._spanBuffer.push({
102
+ resourceSpans: [
103
+ {
104
+ resource: {
105
+ attributes: [
106
+ {
107
+ key: "service.name",
108
+ value: { stringValue: this.serviceName },
109
+ },
110
+ ],
111
+ },
112
+ scopeSpans: [
113
+ {
114
+ scope: { name: span.component || "chainlesschain" },
115
+ spans: [this._toOtlpSpan(span)],
116
+ },
117
+ ],
118
+ },
119
+ ],
120
+ });
121
+ }
122
+ }
123
+
124
+ _toOtlpSpan(span) {
125
+ return {
126
+ traceId: span.traceId || "",
127
+ spanId: span.spanId || "",
128
+ parentSpanId: span.parentSpanId || "",
129
+ name: span.name || "unknown",
130
+ kind: this._toSpanKind(span.kind),
131
+ startTimeUnixNano: (span.startTime || Date.now()) * 1_000_000,
132
+ endTimeUnixNano: (span.endTime || Date.now()) * 1_000_000,
133
+ attributes: Object.entries(span.attributes || {}).map(([k, v]) => ({
134
+ key: k,
135
+ value: this._toAttrValue(v),
136
+ })),
137
+ status: { code: span.error ? 2 : 1, message: span.error?.message || "" },
138
+ events: (span.events || []).map((e) => ({
139
+ timeUnixNano: (e.time || Date.now()) * 1_000_000,
140
+ name: e.name,
141
+ attributes: Object.entries(e.attributes || {}).map(([k, v]) => ({
142
+ key: k,
143
+ value: this._toAttrValue(v),
144
+ })),
145
+ })),
146
+ };
147
+ }
148
+
149
+ _toSpanKind(kind) {
150
+ const map = { internal: 0, server: 1, client: 2, producer: 3, consumer: 4 };
151
+ return map[kind] ?? 0;
152
+ }
153
+
154
+ _toAttrValue(v) {
155
+ if (typeof v === "string") return { stringValue: v };
156
+ if (typeof v === "number")
157
+ return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };
158
+ if (typeof v === "boolean") return { boolValue: v };
159
+ return { stringValue: String(v) };
160
+ }
161
+
162
+ exportMetrics(metrics) {
163
+ if (!this._enabled) return;
164
+ for (const metric of metrics) {
165
+ if (this._metricBuffer.length >= this.batchSize) {
166
+ this._metricBuffer.shift();
167
+ this._droppedMetrics++;
168
+ }
169
+ this._metricBuffer.push({
170
+ resourceMetrics: [
171
+ {
172
+ resource: {
173
+ attributes: [
174
+ {
175
+ key: "service.name",
176
+ value: { stringValue: this.serviceName },
177
+ },
178
+ ],
179
+ },
180
+ scopeMetrics: [
181
+ {
182
+ scope: { name: metric.component || "chainlesschain" },
183
+ metrics: [this._toOtlpMetric(metric)],
184
+ },
185
+ ],
186
+ },
187
+ ],
188
+ });
189
+ }
190
+ }
191
+
192
+ _toOtlpMetric(metric) {
193
+ return {
194
+ name: metric.name,
195
+ description: metric.description || "",
196
+ unit: metric.unit || "1",
197
+ [metric.type === "histogram"
198
+ ? "histogram"
199
+ : metric.type === "sum"
200
+ ? "sum"
201
+ : "gauge"]: {
202
+ dataPoints: [
203
+ {
204
+ attributes: Object.entries(metric.attributes || {}).map(
205
+ ([k, v]) => ({ key: k, value: this._toAttrValue(v) }),
206
+ ),
207
+ timeUnixNano: Date.now() * 1_000_000,
208
+ ...(metric.type === "histogram"
209
+ ? {
210
+ count: metric.value?.count || 0,
211
+ sum: metric.value?.sum || 0,
212
+ bucketCounts: metric.value?.bucketCounts || [],
213
+ explicitBounds: metric.value?.explicitBounds || [],
214
+ }
215
+ : { asDouble: metric.value || 0 }),
216
+ },
217
+ ],
218
+ aggregationTemporality: 1,
219
+ isMonotonic: metric.type === "sum",
220
+ },
221
+ };
222
+ }
223
+
224
+ async flush() {
225
+ if (!this._enabled) return;
226
+ const spans = this._spanBuffer.splice(0);
227
+ const metrics = this._metricBuffer.splice(0);
228
+ const promises = [];
229
+ for (const span of spans)
230
+ promises.push(this._post("/v1/traces", span, "application/json"));
231
+ for (const metric of metrics)
232
+ promises.push(this._post("/v1/metrics", metric, "application/json"));
233
+ await Promise.allSettled(promises);
234
+ }
235
+
236
+ shutdown() {
237
+ if (this._timer) clearInterval(this._timer);
238
+ return this.flush();
239
+ }
240
+
241
+ getStats() {
242
+ return {
243
+ enabled: this._enabled,
244
+ bufferedSpans: this._spanBuffer.length,
245
+ bufferedMetrics: this._metricBuffer.length,
246
+ droppedSpans: this._droppedSpans,
247
+ droppedMetrics: this._droppedMetrics,
248
+ failedExports: this._failedExports,
249
+ successfulExports: this._successfulExports,
250
+ };
251
+ }
252
+ }
253
+
254
+ let _defaultExporter = null;
255
+ export function getDefaultOtlpExporter() {
256
+ if (!_defaultExporter) _defaultExporter = new OtlpExporter();
257
+ return _defaultExporter;
258
+ }
259
+ export { OtlpExporter };
260
+ export default OtlpExporter;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * OTLP Exporter - Minimal OTLP/HTTP trace exporter for M6 observability
3
+ * Strictly bounded to observability layer only, no cross-layer calls
4
+ */
5
+ export class OTLPTraceExporter {
6
+ constructor(options = {}) {
7
+ this.endpoint = options.endpoint || "http://localhost:4318/v1/traces";
8
+ this._queue = [];
9
+ }
10
+
11
+ export(span) {
12
+ const payload = {
13
+ resourceSpans: [{
14
+ resource: { attributes: [{ key: "service.name", value: { stringValue: "cc-cli" } }] },
15
+ scopeSpans: [{
16
+ spans: [{
17
+ traceId: span.traceId,
18
+ spanId: span.spanId,
19
+ name: span.name || "span",
20
+ kind: 1,
21
+ startTimeUnixNano: span.startTime ? BigInt(span.startTime * 1e6).toString() : BigInt(Date.now() * 1e6).toString(),
22
+ endTimeUnixNano: span.endTime ? BigInt(span.endTime * 1e6).toString() : undefined,
23
+ attributes: (span.metadata ? Object.entries(span.metadata).map(([k, v]) => ({ key: k, value: { stringValue: String(v) } })) : []),
24
+ }]
25
+ }]
26
+ }]
27
+ };
28
+ // Fire and forget, no blocking
29
+ fetch(this.endpoint, {
30
+ method: "POST",
31
+ headers: { "Content-Type": "application/json" },
32
+ body: JSON.stringify(payload),
33
+ }).catch(() => {});
34
+ return true;
35
+ }
36
+ }
37
+
38
+ let defaultExporter = null;
39
+ export function initOTLPExporter(endpoint) {
40
+ if (!defaultExporter && endpoint) {
41
+ defaultExporter = new OTLPTraceExporter({ endpoint: endpoint.endsWith("/v1/traces") ? endpoint : endpoint.replace(/\/?$/, "/v1/traces") });
42
+ globalThis.ccRuntime?.traceContext.onEnd((span) => defaultExporter.export(span));
43
+ }
44
+ return defaultExporter;
45
+ }
@@ -0,0 +1,117 @@
1
+ # Process Execution Broker - Spawn/Exec Call Site Audit Report
2
+
3
+ > Audit Date: 2026-07-18
4
+ > Auditor: Agent
5
+ > Scope: `packages/cli/src`
6
+
7
+ ## Executive Summary
8
+
9
+ Total direct `child_process` call sites identified: **~85+**
10
+ - `spawn`: ~40 call sites
11
+ - `spawnSync`: ~25 call sites
12
+ - `execSync`: ~15 call sites
13
+ - `execFileSync`: ~8 call sites
14
+ - `execFile`: ~2 call sites
15
+ - `fork`: ~1 call site
16
+
17
+ ## Classification by Risk Category
18
+
19
+ ### A. Agent Self-Spawn (HIGH PRIORITY - must route through Broker)
20
+ These are the primary surfaces where the agent spawns sub-agents or child cc processes:
21
+
22
+ | File | Function | Type | Purpose |
23
+ |------|----------|------|---------|
24
+ | `commands/agenda.js` | `defaultSpawnAgent()` | spawn | Wakeup/cron scheduled agent execution |
25
+ | `commands/background-session.js` | - | spawn | Background session agent |
26
+ | `commands/batch.js` | `spawnAgent()` | spawn + execFileSync | Batch agent execution |
27
+ | `commands/eval.js` | - | spawn + spawnSync | Eval child processes |
28
+ | `commands/loop.js` | `spawnIteration()` | spawn | Loop mode iteration self-spawn |
29
+ | `commands/routine.js` | - | spawn + execFile | Routine execution |
30
+ | `commands/team.js` | `spawnAgent()` | spawn | Team/cowork multi-agent |
31
+ | `gateways/ws/ws-server.js` | - | spawn | WebSocket gateway spawned CLI commands |
32
+ | `harness/background-task-manager.js` | - | fork | Background task forked workers |
33
+ | `lib/background-agent-supervisor.js` | - | spawn + spawnSync | Background agent supervision |
34
+ | `lib/agent-team/team-worktree.js` | - | spawn + execFileSync | Team worktree agent |
35
+ | `lib/claude-code-bridge.js` | - | spawn + execSync | Claude Code bridge execution |
36
+ | `lib/agent-sandbox.js` | - | spawnSync | Sandbox (docker/bwrap) execution |
37
+
38
+ ### B. MCP Server Process (MEDIUM PRIORITY)
39
+ | File | Function | Type | Purpose |
40
+ |------|----------|------|---------|
41
+ | `harness/mcp-client.js` | - | spawn | MCP stdio server processes |
42
+ | `lib/lsp/lsp-client.js` | - | spawn | LSP server processes |
43
+
44
+ ### C. Git Operations (SAFE - can keep direct)
45
+ | File | Type | Count |
46
+ |------|------|-------|
47
+ | `commands/review.js` | spawnSync | 2 |
48
+ | `commands/session.js` | execFileSync | 1 |
49
+ | `harness/worktree-isolator.js` | execSync | 3 |
50
+ | `lib/agent-worktree.js` | execFileSync/execSync | multiple |
51
+ | `lib/checkpoint-store.js` | spawnSync | multiple |
52
+ | `lib/cloud/bundle.js` | execFileSync | multiple |
53
+ | `lib/git-integration.js` | execSync/spawnSync | multiple |
54
+
55
+ ### D. Package/System Management (SAFE - can keep direct)
56
+ | File | Type | Purpose |
57
+ |------|------|---------|
58
+ | `auth/npm-auth.js` | execSync | npm login/whoami |
59
+ | `commands/config.js` | execSync | Open editor |
60
+ | `commands/init.js` | execSync/spawnSync | Init tool probing |
61
+ | `commands/memory.js` | execSync | Open editor |
62
+ | `commands/update.js` | execSync | npm install -g |
63
+ | `lib/api-key-helper.js` | execSync | Credential helper |
64
+ | `lib/chrome-connector.js` | spawn | Chrome debugger |
65
+ | `lib/doctor-checkup.js` | execSync/spawnSync | Doctor checks |
66
+ | `lib/downloader.js` | execFileSync | Binary downloads |
67
+ | `lib/ensure-utf8.js` | execSync | Windows codepage |
68
+ | `lib/host-adb-bridge.js` | execFile | ADB bridge |
69
+
70
+ ### E. Hook Execution (BROKER-AWARE already)
71
+ | File | Type | Purpose |
72
+ |------|------|---------|
73
+ | `lib/async-hook-supervisor.cjs` | spawn/spawnSync | Async hooks |
74
+ | `lib/hook-manager.js` | execSync | Legacy hook manager |
75
+ | `lib/hook-runner.cjs` | spawn/spawnSync | Hook runner |
76
+
77
+ ### F. Evaluation/Benchmark (TEST only)
78
+ | File | Type | Purpose |
79
+ |------|------|---------|
80
+ | `lib/eval/tasks.js` | execFileSync | Eval task fixtures |
81
+ | `lib/lsp/benchmark.js` | execFileSync | LSP benchmarks |
82
+ | `lib/computer-use/control-backend.js` | spawnSync | Computer use |
83
+
84
+ ### G. Execution Backend
85
+ | File | Type | Purpose |
86
+ |------|------|---------|
87
+ | `lib/execution-backend.js` | execSync | Shell/Docker/SSH backend |
88
+
89
+ ### H. Background Task Worker
90
+ | File | Type | Purpose |
91
+ |------|------|---------|
92
+ | `harness/background-task-worker.js` | execSync | Worker task execution |
93
+
94
+ ## Migration Plan
95
+
96
+ ### Phase 1 (M1 Deliverable)
97
+ Create ProcessExecutionBroker with core interface, then migrate:
98
+ 1. Category A (Agent Self-Spawn) - all HIGH priority sites
99
+ 2. Instrument with audit events + logging
100
+
101
+ ### Phase 2 (Post-M1)
102
+ 1. Category B (MCP/LSP) - register server processes as supervised children
103
+ 2. Keep Categories C/D as `bypassBroker: true` approved calls (with explicit allowlist)
104
+
105
+ ### Phase 3 (M3 deliverable)
106
+ 3. Route Category E hooks through Broker for unified supervision
107
+
108
+ ## Bypass Allowlist (Initial)
109
+ The following patterns will be initially marked as `bypassBroker: true` with reason:
110
+ - All `git` command executions (known safe, no agent control over args)
111
+ - Editor opening (`$EDITOR`, `vim`, `nano`, etc.)
112
+ - Package manager operations (`npm`, `pip`)
113
+ - Chrome/ADB debug bridge connections
114
+ - Doctor/diagnostic probes
115
+ - Windows codepage setup (`chcp`)
116
+ - File downloads/extraction (unzip)
117
+ - Test fixtures and benchmarks (test-only code)