@kaitranntt/ccs 7.77.1-dev.9 → 7.78.0-dev.1

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 (211) hide show
  1. package/dist/auth/auth-commands.d.ts +2 -1
  2. package/dist/auth/auth-commands.d.ts.map +1 -1
  3. package/dist/auth/auth-commands.js +18 -4
  4. package/dist/auth/auth-commands.js.map +1 -1
  5. package/dist/auth/commands/backup-command.d.ts.map +1 -1
  6. package/dist/auth/commands/backup-command.js +7 -2
  7. package/dist/auth/commands/backup-command.js.map +1 -1
  8. package/dist/auth/commands/create-command.d.ts.map +1 -1
  9. package/dist/auth/commands/create-command.js +14 -16
  10. package/dist/auth/commands/create-command.js.map +1 -1
  11. package/dist/auth/commands/default-command.d.ts +1 -1
  12. package/dist/auth/commands/default-command.d.ts.map +1 -1
  13. package/dist/auth/commands/default-command.js +10 -2
  14. package/dist/auth/commands/default-command.js.map +1 -1
  15. package/dist/auth/commands/index.d.ts +1 -0
  16. package/dist/auth/commands/index.d.ts.map +1 -1
  17. package/dist/auth/commands/index.js +3 -1
  18. package/dist/auth/commands/index.js.map +1 -1
  19. package/dist/auth/commands/list-command.d.ts.map +1 -1
  20. package/dist/auth/commands/list-command.js +16 -3
  21. package/dist/auth/commands/list-command.js.map +1 -1
  22. package/dist/auth/commands/remove-command.d.ts.map +1 -1
  23. package/dist/auth/commands/remove-command.js +5 -1
  24. package/dist/auth/commands/remove-command.js.map +1 -1
  25. package/dist/auth/commands/resources-command.d.ts +3 -0
  26. package/dist/auth/commands/resources-command.d.ts.map +1 -0
  27. package/dist/auth/commands/resources-command.js +115 -0
  28. package/dist/auth/commands/resources-command.js.map +1 -0
  29. package/dist/auth/commands/show-command.d.ts.map +1 -1
  30. package/dist/auth/commands/show-command.js +13 -4
  31. package/dist/auth/commands/show-command.js.map +1 -1
  32. package/dist/auth/commands/types.d.ts +11 -1
  33. package/dist/auth/commands/types.d.ts.map +1 -1
  34. package/dist/auth/commands/types.js +41 -2
  35. package/dist/auth/commands/types.js.map +1 -1
  36. package/dist/auth/profile-continuity-inheritance.d.ts.map +1 -1
  37. package/dist/auth/profile-continuity-inheritance.js +2 -1
  38. package/dist/auth/profile-continuity-inheritance.js.map +1 -1
  39. package/dist/auth/profile-detector.d.ts.map +1 -1
  40. package/dist/auth/profile-detector.js +1 -0
  41. package/dist/auth/profile-detector.js.map +1 -1
  42. package/dist/auth/profile-registry.d.ts +2 -0
  43. package/dist/auth/profile-registry.d.ts.map +1 -1
  44. package/dist/auth/profile-registry.js +6 -2
  45. package/dist/auth/profile-registry.js.map +1 -1
  46. package/dist/auth/shared-resource-policy.d.ts +20 -0
  47. package/dist/auth/shared-resource-policy.d.ts.map +1 -0
  48. package/dist/auth/shared-resource-policy.js +69 -0
  49. package/dist/auth/shared-resource-policy.js.map +1 -0
  50. package/dist/cliproxy/auth/oauth-handler.d.ts +34 -0
  51. package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
  52. package/dist/cliproxy/auth/oauth-handler.js +106 -13
  53. package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
  54. package/dist/cliproxy/auth/oauth-process.d.ts.map +1 -1
  55. package/dist/cliproxy/auth/oauth-process.js +94 -3
  56. package/dist/cliproxy/auth/oauth-process.js.map +1 -1
  57. package/dist/cliproxy/auth/oauth-start-failure-guidance.d.ts +22 -0
  58. package/dist/cliproxy/auth/oauth-start-failure-guidance.d.ts.map +1 -0
  59. package/dist/cliproxy/auth/oauth-start-failure-guidance.js +82 -0
  60. package/dist/cliproxy/auth/oauth-start-failure-guidance.js.map +1 -0
  61. package/dist/cliproxy/auth/oauth-trace/diagnose-failure.d.ts +24 -0
  62. package/dist/cliproxy/auth/oauth-trace/diagnose-failure.d.ts.map +1 -0
  63. package/dist/cliproxy/auth/oauth-trace/diagnose-failure.js +159 -0
  64. package/dist/cliproxy/auth/oauth-trace/diagnose-failure.js.map +1 -0
  65. package/dist/cliproxy/auth/oauth-trace/index.d.ts +4 -0
  66. package/dist/cliproxy/auth/oauth-trace/index.d.ts.map +1 -0
  67. package/dist/cliproxy/auth/oauth-trace/index.js +14 -0
  68. package/dist/cliproxy/auth/oauth-trace/index.js.map +1 -0
  69. package/dist/cliproxy/auth/oauth-trace/redactor.d.ts +22 -0
  70. package/dist/cliproxy/auth/oauth-trace/redactor.d.ts.map +1 -0
  71. package/dist/cliproxy/auth/oauth-trace/redactor.js +112 -0
  72. package/dist/cliproxy/auth/oauth-trace/redactor.js.map +1 -0
  73. package/dist/cliproxy/auth/oauth-trace/sink-file.d.ts +18 -0
  74. package/dist/cliproxy/auth/oauth-trace/sink-file.d.ts.map +1 -0
  75. package/dist/cliproxy/auth/oauth-trace/sink-file.js +90 -0
  76. package/dist/cliproxy/auth/oauth-trace/sink-file.js.map +1 -0
  77. package/dist/cliproxy/auth/oauth-trace/sink-memory.d.ts +13 -0
  78. package/dist/cliproxy/auth/oauth-trace/sink-memory.d.ts.map +1 -0
  79. package/dist/cliproxy/auth/oauth-trace/sink-memory.js +31 -0
  80. package/dist/cliproxy/auth/oauth-trace/sink-memory.js.map +1 -0
  81. package/dist/cliproxy/auth/oauth-trace/sink-verbose-stdout.d.ts +11 -0
  82. package/dist/cliproxy/auth/oauth-trace/sink-verbose-stdout.d.ts.map +1 -0
  83. package/dist/cliproxy/auth/oauth-trace/sink-verbose-stdout.js +47 -0
  84. package/dist/cliproxy/auth/oauth-trace/sink-verbose-stdout.js.map +1 -0
  85. package/dist/cliproxy/auth/oauth-trace/trace-events.d.ts +51 -0
  86. package/dist/cliproxy/auth/oauth-trace/trace-events.d.ts.map +1 -0
  87. package/dist/cliproxy/auth/oauth-trace/trace-events.js +44 -0
  88. package/dist/cliproxy/auth/oauth-trace/trace-events.js.map +1 -0
  89. package/dist/cliproxy/auth/oauth-trace/trace-recorder.d.ts +34 -0
  90. package/dist/cliproxy/auth/oauth-trace/trace-recorder.d.ts.map +1 -0
  91. package/dist/cliproxy/auth/oauth-trace/trace-recorder.js +83 -0
  92. package/dist/cliproxy/auth/oauth-trace/trace-recorder.js.map +1 -0
  93. package/dist/commands/command-catalog.d.ts +1 -1
  94. package/dist/commands/command-catalog.d.ts.map +1 -1
  95. package/dist/commands/command-catalog.js +1 -0
  96. package/dist/commands/command-catalog.js.map +1 -1
  97. package/dist/commands/completion-backend.d.ts.map +1 -1
  98. package/dist/commands/completion-backend.js +7 -0
  99. package/dist/commands/completion-backend.js.map +1 -1
  100. package/dist/commands/help-command.d.ts.map +1 -1
  101. package/dist/commands/help-command.js +1 -0
  102. package/dist/commands/help-command.js.map +1 -1
  103. package/dist/commands/sync-command.d.ts.map +1 -1
  104. package/dist/commands/sync-command.js +3 -2
  105. package/dist/commands/sync-command.js.map +1 -1
  106. package/dist/config/migration-manager.d.ts.map +1 -1
  107. package/dist/config/migration-manager.js +12 -0
  108. package/dist/config/migration-manager.js.map +1 -1
  109. package/dist/config/schemas/auth.d.ts +2 -0
  110. package/dist/config/schemas/auth.d.ts.map +1 -1
  111. package/dist/config/schemas/auth.js.map +1 -1
  112. package/dist/dispatcher/flows/account-flow.d.ts.map +1 -1
  113. package/dist/dispatcher/flows/account-flow.js +4 -3
  114. package/dist/dispatcher/flows/account-flow.js.map +1 -1
  115. package/dist/shared/claude-extension-setup.d.ts.map +1 -1
  116. package/dist/shared/claude-extension-setup.js +5 -1
  117. package/dist/shared/claude-extension-setup.js.map +1 -1
  118. package/dist/types/config.d.ts +2 -0
  119. package/dist/types/config.d.ts.map +1 -1
  120. package/dist/types/config.js.map +1 -1
  121. package/dist/ui/assets/accounts-BavG_0Lp.js +1 -0
  122. package/dist/ui/assets/{alert-dialog-BM9gIsRp.js → alert-dialog-CwbcF3cM.js} +1 -1
  123. package/dist/ui/assets/{api-0YJdilQb.js → api-XKc5ORgC.js} +1 -1
  124. package/dist/ui/assets/{auth-section-C1ljCo7W.js → auth-section-JYi_w0iY.js} +1 -1
  125. package/dist/ui/assets/{backups-section-C-iLf1kg.js → backups-section-B8rlcnmC.js} +1 -1
  126. package/dist/ui/assets/{channels-DDSqllsQ.js → channels-AoyzfHeo.js} +1 -1
  127. package/dist/ui/assets/{checkbox-5R1YTubE.js → checkbox-BvotO8ov.js} +1 -1
  128. package/dist/ui/assets/{claude-extension-CEGefl3-.js → claude-extension-CVxbFjPB.js} +1 -1
  129. package/dist/ui/assets/{cliproxy-ai-providers-DVF3FnXM.js → cliproxy-ai-providers-CZzq109C.js} +1 -1
  130. package/dist/ui/assets/{cliproxy-control-panel-CIsKyGK6.js → cliproxy-control-panel-CTHL_h9B.js} +1 -1
  131. package/dist/ui/assets/{cliproxy-R4kPUeL-.js → cliproxy-x0y8HBwr.js} +3 -2
  132. package/dist/ui/assets/{codex-BiEEUC4Y.js → codex-CSIkJL2R.js} +1 -1
  133. package/dist/ui/assets/{confirm-dialog-BhJV4F_d.js → confirm-dialog-BTjfIKq_.js} +1 -1
  134. package/dist/ui/assets/{copilot-DgRLuQfV.js → copilot-BvUgiXUb.js} +1 -1
  135. package/dist/ui/assets/{cursor-BuOjfajj.js → cursor-CB9xJXy9.js} +1 -1
  136. package/dist/ui/assets/{droid-BPiviAW2.js → droid--IsHK3iC.js} +1 -1
  137. package/dist/ui/assets/{globalenv-section-DAqbiNI1.js → globalenv-section-CE2ldHJ4.js} +1 -1
  138. package/dist/ui/assets/{health-B_CfF7J0.js → health-DD9gcO8M.js} +1 -1
  139. package/dist/ui/assets/{icons-DIVjDO-z.js → icons-DzKUh8vG.js} +1 -1
  140. package/dist/ui/assets/{index-LJitUhfE.js → index-BeGUeif2.js} +1 -1
  141. package/dist/ui/assets/{index-CzKdWNe5.js → index-DF8caRNZ.js} +1 -1
  142. package/dist/ui/assets/{index-Bc-AbZRU.js → index-Dk1F8Ovl.js} +1 -1
  143. package/dist/ui/assets/{index-BJl0cazY.js → index-Dm_dDmYb.js} +27 -27
  144. package/dist/ui/assets/{index-BqR6NZDE.js → index-IN2T_Dpm.js} +1 -1
  145. package/dist/ui/assets/index-a3U2tSQf.css +1 -0
  146. package/dist/ui/assets/{index-Cj4mWFVK.js → index-b5UbBJdP.js} +1 -1
  147. package/dist/ui/assets/{index-BEGD-4HR.js → index-zv39jop-.js} +1 -1
  148. package/dist/ui/assets/{logs-Lqv-I3_T.js → logs-CyO00yGk.js} +1 -1
  149. package/dist/ui/assets/{masked-input-CgCDYXYf.js → masked-input-BH4lufWZ.js} +1 -1
  150. package/dist/ui/assets/{proxy-status-widget-Df-4cfdm.js → proxy-status-widget-6_YTJ6Xm.js} +1 -1
  151. package/dist/ui/assets/{raw-json-settings-editor-panel-BpXdUisD.js → raw-json-settings-editor-panel-BErB7VIF.js} +1 -1
  152. package/dist/ui/assets/{searchable-select-DCOfw3f0.js → searchable-select-KOr7UsSu.js} +1 -1
  153. package/dist/ui/assets/{separator-Ct6a34bG.js → separator-mYtigESV.js} +1 -1
  154. package/dist/ui/assets/shared-C8ZW3jNG.js +8 -0
  155. package/dist/ui/assets/{table-DsU2UX-e.js → table-CwSuE62H.js} +1 -1
  156. package/dist/ui/assets/{updates-D-0gOqSU.js → updates-CKsRAm2k.js} +1 -1
  157. package/dist/ui/assets/use-accounts-BYZkfTwy.js +1 -0
  158. package/dist/ui/index.html +3 -3
  159. package/dist/web-server/routes/account-route-helpers.d.ts +3 -0
  160. package/dist/web-server/routes/account-route-helpers.d.ts.map +1 -1
  161. package/dist/web-server/routes/account-route-helpers.js.map +1 -1
  162. package/dist/web-server/routes/account-routes.d.ts.map +1 -1
  163. package/dist/web-server/routes/account-routes.js +97 -4
  164. package/dist/web-server/routes/account-routes.js.map +1 -1
  165. package/dist/web-server/routes/cliproxy-auth-routes.d.ts.map +1 -1
  166. package/dist/web-server/routes/cliproxy-auth-routes.js +59 -3
  167. package/dist/web-server/routes/cliproxy-auth-routes.js.map +1 -1
  168. package/dist/web-server/shared-routes-collections.d.ts +13 -0
  169. package/dist/web-server/shared-routes-collections.d.ts.map +1 -0
  170. package/dist/web-server/shared-routes-collections.js +170 -0
  171. package/dist/web-server/shared-routes-collections.js.map +1 -0
  172. package/dist/web-server/shared-routes-content.d.ts +16 -0
  173. package/dist/web-server/shared-routes-content.d.ts.map +1 -0
  174. package/dist/web-server/shared-routes-content.js +152 -0
  175. package/dist/web-server/shared-routes-content.js.map +1 -0
  176. package/dist/web-server/shared-routes-markdown-walker.d.ts +12 -0
  177. package/dist/web-server/shared-routes-markdown-walker.d.ts.map +1 -0
  178. package/dist/web-server/shared-routes-markdown-walker.js +97 -0
  179. package/dist/web-server/shared-routes-markdown-walker.js.map +1 -0
  180. package/dist/web-server/shared-routes-markdown.d.ts +18 -0
  181. package/dist/web-server/shared-routes-markdown.d.ts.map +1 -0
  182. package/dist/web-server/shared-routes-markdown.js +167 -0
  183. package/dist/web-server/shared-routes-markdown.js.map +1 -0
  184. package/dist/web-server/shared-routes-path-guards.d.ts +16 -0
  185. package/dist/web-server/shared-routes-path-guards.d.ts.map +1 -0
  186. package/dist/web-server/shared-routes-path-guards.js +93 -0
  187. package/dist/web-server/shared-routes-path-guards.js.map +1 -0
  188. package/dist/web-server/shared-routes-plugin-registry-content.d.ts +12 -0
  189. package/dist/web-server/shared-routes-plugin-registry-content.d.ts.map +1 -0
  190. package/dist/web-server/shared-routes-plugin-registry-content.js +93 -0
  191. package/dist/web-server/shared-routes-plugin-registry-content.js.map +1 -0
  192. package/dist/web-server/shared-routes-plugins.d.ts +21 -0
  193. package/dist/web-server/shared-routes-plugins.d.ts.map +1 -0
  194. package/dist/web-server/shared-routes-plugins.js +197 -0
  195. package/dist/web-server/shared-routes-plugins.js.map +1 -0
  196. package/dist/web-server/shared-routes-symlink-status.d.ts +27 -0
  197. package/dist/web-server/shared-routes-symlink-status.d.ts.map +1 -0
  198. package/dist/web-server/shared-routes-symlink-status.js +135 -0
  199. package/dist/web-server/shared-routes-symlink-status.js.map +1 -0
  200. package/dist/web-server/shared-routes-types.d.ts +23 -0
  201. package/dist/web-server/shared-routes-types.d.ts.map +1 -0
  202. package/dist/web-server/shared-routes-types.js +15 -0
  203. package/dist/web-server/shared-routes-types.js.map +1 -0
  204. package/dist/web-server/shared-routes.d.ts +2 -1
  205. package/dist/web-server/shared-routes.d.ts.map +1 -1
  206. package/dist/web-server/shared-routes.js +49 -455
  207. package/dist/web-server/shared-routes.js.map +1 -1
  208. package/package.json +1 -1
  209. package/dist/ui/assets/accounts-DkID6f81.js +0 -1
  210. package/dist/ui/assets/index-Cm0qoAXb.css +0 -1
  211. package/dist/ui/assets/shared-D-JFc_Cw.js +0 -8
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REDACTED_PLACEHOLDER = exports.redactBearer = exports.redactJsonShallow = exports.redactUrl = exports.redactString = exports.createOAuthTraceRecorder = exports.OAuthTracePhase = void 0;
4
+ var trace_events_1 = require("./trace-events");
5
+ Object.defineProperty(exports, "OAuthTracePhase", { enumerable: true, get: function () { return trace_events_1.OAuthTracePhase; } });
6
+ var trace_recorder_1 = require("./trace-recorder");
7
+ Object.defineProperty(exports, "createOAuthTraceRecorder", { enumerable: true, get: function () { return trace_recorder_1.createOAuthTraceRecorder; } });
8
+ var redactor_1 = require("./redactor");
9
+ Object.defineProperty(exports, "redactString", { enumerable: true, get: function () { return redactor_1.redactString; } });
10
+ Object.defineProperty(exports, "redactUrl", { enumerable: true, get: function () { return redactor_1.redactUrl; } });
11
+ Object.defineProperty(exports, "redactJsonShallow", { enumerable: true, get: function () { return redactor_1.redactJsonShallow; } });
12
+ Object.defineProperty(exports, "redactBearer", { enumerable: true, get: function () { return redactor_1.redactBearer; } });
13
+ Object.defineProperty(exports, "REDACTED_PLACEHOLDER", { enumerable: true, get: function () { return redactor_1.REDACTED_PLACEHOLDER; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/index.ts"],"names":[],"mappings":";;;AAAA,+CAA4F;AAAnF,+GAAA,eAAe,OAAA;AACxB,mDAI0B;AAHxB,0HAAA,wBAAwB,OAAA;AAI1B,uCAMoB;AALlB,wGAAA,YAAY,OAAA;AACZ,qGAAA,SAAS,OAAA;AACT,6GAAA,iBAAiB,OAAA;AACjB,wGAAA,YAAY,OAAA;AACZ,gHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * OAuth secret redactor — single choke point.
3
+ *
4
+ * Every value reaching any sink passes through these helpers first.
5
+ * Adding a new sensitive key here is the only place it has to change.
6
+ *
7
+ * DEFERRED: per-event syscall throttling; fsync / file-size cap on file sink.
8
+ */
9
+ /** Redact sensitive query-param values inside any string. Idempotent. */
10
+ export declare function redactString(s: string): string;
11
+ /** Redact a parsed URL by name; returns redacted href or original on parse error. */
12
+ export declare function redactUrl(u: string): string;
13
+ /**
14
+ * Shallow-redact a plain object. Returns a new object; original is not mutated.
15
+ * Arrays are recursed so token arrays (e.g. `{tokens:[{access_token:'AT'}]}`)
16
+ * do not bypass redaction.
17
+ */
18
+ export declare function redactJsonShallow(input: Record<string, unknown>): Record<string, unknown>;
19
+ /** Redact an Authorization header value. */
20
+ export declare function redactBearer(header: string): string;
21
+ export declare const REDACTED_PLACEHOLDER = "***REDACTED***";
22
+ //# sourceMappingURL=redactor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactor.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/redactor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmCH,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAiC3C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzF;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,eAAO,MAAM,oBAAoB,mBAAW,CAAC"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth secret redactor — single choke point.
4
+ *
5
+ * Every value reaching any sink passes through these helpers first.
6
+ * Adding a new sensitive key here is the only place it has to change.
7
+ *
8
+ * DEFERRED: per-event syscall throttling; fsync / file-size cap on file sink.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.REDACTED_PLACEHOLDER = exports.redactBearer = exports.redactJsonShallow = exports.redactUrl = exports.redactString = void 0;
12
+ const SENSITIVE_QUERY_KEYS = [
13
+ 'code',
14
+ 'state',
15
+ 'access_token',
16
+ 'refresh_token',
17
+ 'id_token',
18
+ 'client_secret',
19
+ 'authorization',
20
+ // PKCE / device-flow / assertion keys
21
+ 'code_verifier',
22
+ 'device_code',
23
+ 'assertion',
24
+ 'subject_token',
25
+ ];
26
+ const SENSITIVE_OBJECT_KEYS = new Set(SENSITIVE_QUERY_KEYS.map((k) => k.toLowerCase()).concat(['authorization', 'bearer', 'token']));
27
+ const REDACTED = '***REDACTED***';
28
+ /**
29
+ * Matches sensitive keys in query strings, fragments, and standard params.
30
+ * Lookbehind covers: `?`, `&`, `#`, and `&#` (fragment-then-amp) delimiters.
31
+ * Keys are decoded before matching to catch URL-encoded bypass attempts.
32
+ */
33
+ const QUERY_PARAM_REGEX = new RegExp(`(?<=[?&#])(${SENSITIVE_QUERY_KEYS.join('|')})=[^&#\\s]+`, 'gi');
34
+ const BEARER_REGEX = /Bearer\s+[A-Za-z0-9._\-~+/=]+/gi;
35
+ /** Redact sensitive query-param values inside any string. Idempotent. */
36
+ function redactString(s) {
37
+ if (!s)
38
+ return s;
39
+ return s
40
+ .replace(QUERY_PARAM_REGEX, (_full, key) => `${key}=${REDACTED}`)
41
+ .replace(BEARER_REGEX, `Bearer ${REDACTED}`);
42
+ }
43
+ exports.redactString = redactString;
44
+ /** Redact a parsed URL by name; returns redacted href or original on parse error. */
45
+ function redactUrl(u) {
46
+ try {
47
+ const url = new URL(u);
48
+ // Redact query params — URL parser already decoded keys, compare decoded.
49
+ for (const key of SENSITIVE_QUERY_KEYS) {
50
+ if (url.searchParams.has(key))
51
+ url.searchParams.set(key, REDACTED);
52
+ }
53
+ // Also catch URL-encoded key names that URL.searchParams may not normalise
54
+ // (e.g. `?%63%6F%64%65=SECRET`). Decode all keys and re-check.
55
+ for (const [rawKey, rawVal] of [...url.searchParams.entries()]) {
56
+ const decoded = decodeURIComponent(rawKey).toLowerCase();
57
+ if ((SENSITIVE_OBJECT_KEYS.has(decoded) || SENSITIVE_QUERY_KEYS.includes(decoded)) &&
58
+ rawVal !== REDACTED) {
59
+ url.searchParams.set(rawKey, REDACTED);
60
+ }
61
+ }
62
+ // Redact fragment — strip leading `#`, prepend `?` so QUERY_PARAM_REGEX
63
+ // matches the first param (lookbehind requires `?`, `&`, or `#`).
64
+ if (url.hash) {
65
+ const bare = url.hash.slice(1); // remove leading '#'
66
+ const fakeQuery = `?${bare}`;
67
+ const redacted = redactString(fakeQuery);
68
+ url.hash = redacted.slice(1); // put back without the fake '?'
69
+ }
70
+ return url.toString();
71
+ }
72
+ catch {
73
+ return redactString(u);
74
+ }
75
+ }
76
+ exports.redactUrl = redactUrl;
77
+ /**
78
+ * Shallow-redact a plain object. Returns a new object; original is not mutated.
79
+ * Arrays are recursed so token arrays (e.g. `{tokens:[{access_token:'AT'}]}`)
80
+ * do not bypass redaction.
81
+ */
82
+ function redactJsonShallow(input) {
83
+ const out = {};
84
+ for (const [key, value] of Object.entries(input)) {
85
+ if (SENSITIVE_OBJECT_KEYS.has(key.toLowerCase())) {
86
+ out[key] = REDACTED;
87
+ }
88
+ else if (typeof value === 'string') {
89
+ out[key] = redactString(value);
90
+ }
91
+ else if (Array.isArray(value)) {
92
+ out[key] = value.map((item) => item && typeof item === 'object' && !Array.isArray(item)
93
+ ? redactJsonShallow(item)
94
+ : item);
95
+ }
96
+ else if (value && typeof value === 'object') {
97
+ out[key] = redactJsonShallow(value);
98
+ }
99
+ else {
100
+ out[key] = value;
101
+ }
102
+ }
103
+ return out;
104
+ }
105
+ exports.redactJsonShallow = redactJsonShallow;
106
+ /** Redact an Authorization header value. */
107
+ function redactBearer(header) {
108
+ return header.replace(BEARER_REGEX, `Bearer ${REDACTED}`);
109
+ }
110
+ exports.redactBearer = redactBearer;
111
+ exports.REDACTED_PLACEHOLDER = REDACTED;
112
+ //# sourceMappingURL=redactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactor.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/redactor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { OAuthTraceSink } from './trace-events';
2
+ /**
3
+ * Append-mode JSONL file sink. Off by default; enabled when callers pass an instance.
4
+ *
5
+ * - File path: `${dir}/oauth-YYYYMMDD.log` (date from `now()` per write call).
6
+ * - Permissions: dir 0o700, file 0o600 (user-only). World-readable would leak machine info.
7
+ * - Failure-tolerant: if write fails (disk full, perm denied), logs once to stderr and
8
+ * keeps dropping events silently — sink must never throw out of `write()`.
9
+ */
10
+ export interface FileSinkOptions {
11
+ dir: string;
12
+ /** Test seam — defaults to `() => new Date()`. */
13
+ now?: () => Date;
14
+ /** Test seam — error notifier (defaults to one-shot stderr write). */
15
+ onError?: (msg: string) => void;
16
+ }
17
+ export declare function createFileSink(options: FileSinkOptions): OAuthTraceSink;
18
+ //# sourceMappingURL=sink-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-file.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-file.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA+DvE"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.createFileSink = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ function createFileSink(options) {
30
+ const now = options.now ?? (() => new Date());
31
+ let warned = false;
32
+ const onError = options.onError ??
33
+ ((msg) => {
34
+ if (!warned) {
35
+ warned = true;
36
+ process.stderr.write(`[oauth-trace] file sink disabled: ${msg}\n`);
37
+ }
38
+ });
39
+ let cachedDate = null;
40
+ function ensureDir() {
41
+ fs.mkdirSync(options.dir, { recursive: true, mode: 0o700 });
42
+ }
43
+ function dateStr(d) {
44
+ const yyyy = d.getFullYear().toString().padStart(4, '0');
45
+ const mm = (d.getMonth() + 1).toString().padStart(2, '0');
46
+ const dd = d.getDate().toString().padStart(2, '0');
47
+ return `${yyyy}${mm}${dd}`;
48
+ }
49
+ function pathForToday() {
50
+ const ds = dateStr(now());
51
+ cachedDate = ds;
52
+ return path.join(options.dir, `oauth-${ds}.log`);
53
+ }
54
+ function appendOne(event) {
55
+ const file = pathForToday();
56
+ const line = JSON.stringify(event) + '\n';
57
+ let fd = null;
58
+ try {
59
+ ensureDir();
60
+ fd = fs.openSync(file, 'a', 0o600);
61
+ fs.writeSync(fd, line);
62
+ }
63
+ finally {
64
+ if (fd !== null) {
65
+ try {
66
+ fs.closeSync(fd);
67
+ }
68
+ catch {
69
+ // ignore
70
+ }
71
+ }
72
+ }
73
+ }
74
+ return {
75
+ write(event) {
76
+ try {
77
+ appendOne(event);
78
+ }
79
+ catch (err) {
80
+ onError(err.message);
81
+ }
82
+ },
83
+ async flush() {
84
+ // appendSync paths are flushed per-write; no buffer to drain.
85
+ void cachedDate;
86
+ },
87
+ };
88
+ }
89
+ exports.createFileSink = createFileSink;
90
+ //# sourceMappingURL=sink-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-file.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-file.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAmB7B,SAAgB,cAAc,CAAC,OAAwB;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,OAAO,GACX,OAAO,CAAC,OAAO;QACf,CAAC,CAAC,GAAW,EAAE,EAAE;YACf,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,IAAI,CAAC;gBACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,GAAG,IAAI,CAAC,CAAC;YACrE,CAAC;QACH,CAAC,CAAC,CAAC;IAEL,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,SAAS,SAAS;QAChB,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,OAAO,CAAC,CAAO;QACtB,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnD,OAAO,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;IAC7B,CAAC;IAED,SAAS,YAAY;QACnB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1B,UAAU,GAAG,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,SAAS,SAAS,CAAC,KAAsB;QACvC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,IAAI,EAAE,GAAkB,IAAI,CAAC;QAC7B,IAAI,CAAC;YACH,SAAS,EAAE,CAAC;YACZ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzB,CAAC;gBAAS,CAAC;YACT,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC;oBACH,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACnB,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,CAAC;gBACH,SAAS,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK;YACT,8DAA8D;YAC9D,KAAK,UAAU,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AA/DD,wCA+DC"}
@@ -0,0 +1,13 @@
1
+ import { OAuthTraceEvent, OAuthTraceSink } from './trace-events';
2
+ /** Default ring-buffer capacity. Keeps latest N events; oldest are dropped. */
3
+ export declare const MEMORY_SINK_MAX_EVENTS = 1000;
4
+ /**
5
+ * In-memory ring buffer sink. Used for diagnose-failure analysis after a flow ends.
6
+ * Caps at MAX_EVENTS to bound memory; oldest are dropped when full.
7
+ * `droppedCount` tracks how many events were discarded so callers know data loss occurred.
8
+ */
9
+ export declare function createMemorySink(maxEvents?: number): OAuthTraceSink & {
10
+ snapshot(): OAuthTraceEvent[];
11
+ droppedCount(): number;
12
+ };
13
+ //# sourceMappingURL=sink-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-memory.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,SAAyB,GACjC,cAAc,GAAG;IAAE,QAAQ,IAAI,eAAe,EAAE,CAAC;IAAC,YAAY,IAAI,MAAM,CAAA;CAAE,CAkB5E"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMemorySink = exports.MEMORY_SINK_MAX_EVENTS = void 0;
4
+ /** Default ring-buffer capacity. Keeps latest N events; oldest are dropped. */
5
+ exports.MEMORY_SINK_MAX_EVENTS = 1000;
6
+ /**
7
+ * In-memory ring buffer sink. Used for diagnose-failure analysis after a flow ends.
8
+ * Caps at MAX_EVENTS to bound memory; oldest are dropped when full.
9
+ * `droppedCount` tracks how many events were discarded so callers know data loss occurred.
10
+ */
11
+ function createMemorySink(maxEvents = exports.MEMORY_SINK_MAX_EVENTS) {
12
+ const events = [];
13
+ let dropped = 0;
14
+ return {
15
+ write(event) {
16
+ if (events.length >= maxEvents) {
17
+ events.shift();
18
+ dropped++;
19
+ }
20
+ events.push(event);
21
+ },
22
+ snapshot() {
23
+ return events.slice();
24
+ },
25
+ droppedCount() {
26
+ return dropped;
27
+ },
28
+ };
29
+ }
30
+ exports.createMemorySink = createMemorySink;
31
+ //# sourceMappingURL=sink-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-memory.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-memory.ts"],"names":[],"mappings":";;;AAEA,+EAA+E;AAClE,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAE3C;;;;GAIG;AACH,SAAgB,gBAAgB,CAC9B,SAAS,GAAG,8BAAsB;IAElC,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC/B,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,QAAQ;YACN,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QACD,YAAY;YACV,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AApBD,4CAoBC"}
@@ -0,0 +1,11 @@
1
+ import { OAuthTraceSink } from './trace-events';
2
+ /**
3
+ * Verbose stdout sink. Writes one ASCII line per event when verbose=true.
4
+ * Format: `[oauth-trace] +{elapsedMs}ms {phase} {key=val ...}`
5
+ * No emojis (CCS terminal rule). Goes to stderr to avoid mingling with normal stdout.
6
+ */
7
+ export declare function createVerboseStdoutSink(opts: {
8
+ enabled: boolean;
9
+ out?: (line: string) => void;
10
+ }): OAuthTraceSink;
11
+ //# sourceMappingURL=sink-verbose-stdout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-verbose-stdout.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-verbose-stdout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B,GAAG,cAAc,CAoBjB"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createVerboseStdoutSink = void 0;
4
+ /**
5
+ * Verbose stdout sink. Writes one ASCII line per event when verbose=true.
6
+ * Format: `[oauth-trace] +{elapsedMs}ms {phase} {key=val ...}`
7
+ * No emojis (CCS terminal rule). Goes to stderr to avoid mingling with normal stdout.
8
+ */
9
+ function createVerboseStdoutSink(opts) {
10
+ const out = opts.out ?? ((line) => process.stderr.write(line + '\n'));
11
+ return {
12
+ write(event) {
13
+ if (!opts.enabled)
14
+ return;
15
+ const parts = [];
16
+ parts.push(`[oauth-trace] +${event.elapsedMs}ms ${event.phase}`);
17
+ if (event.data) {
18
+ for (const [k, v] of Object.entries(event.data)) {
19
+ if (v === undefined)
20
+ continue;
21
+ parts.push(`${k}=${formatValue(v)}`);
22
+ }
23
+ }
24
+ if (event.error) {
25
+ parts.push(`error_code=${event.error.code ?? 'unknown'}`);
26
+ parts.push(`error_msg="${event.error.message.replace(/"/g, "'")}"`);
27
+ }
28
+ out(parts.join(' '));
29
+ },
30
+ };
31
+ }
32
+ exports.createVerboseStdoutSink = createVerboseStdoutSink;
33
+ function formatValue(v) {
34
+ if (v === null)
35
+ return 'null';
36
+ if (typeof v === 'string')
37
+ return v.includes(' ') ? `"${v.replace(/"/g, "'")}"` : v;
38
+ if (typeof v === 'number' || typeof v === 'boolean')
39
+ return String(v);
40
+ try {
41
+ return JSON.stringify(v);
42
+ }
43
+ catch {
44
+ return '[unserializable]';
45
+ }
46
+ }
47
+ //# sourceMappingURL=sink-verbose-stdout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink-verbose-stdout.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/sink-verbose-stdout.ts"],"names":[],"mappings":";;;AAEA;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,IAGvC;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9E,OAAO;QACL,KAAK,CAAC,KAAK;YACT,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAO;YAC1B,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,CAAC,SAAS,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YACjE,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAChD,IAAI,CAAC,KAAK,SAAS;wBAAE,SAAS;oBAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;gBAC1D,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YACtE,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAvBD,0DAuBC;AAED,SAAS,WAAW,CAAC,CAAU;IAC7B,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpF,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,kBAAkB,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * OAuth trace event taxonomy.
3
+ *
4
+ * Single source of truth for phase IDs that flow through the OAuth pipeline.
5
+ * Additive only — never remove or renumber.
6
+ */
7
+ export declare enum OAuthTracePhase {
8
+ PreflightStart = "preflight.start",
9
+ PreflightOk = "preflight.ok",
10
+ PreflightPortBlocked = "preflight.port_blocked",
11
+ BinarySpawn = "binary.spawn",
12
+ BinaryStdout = "binary.stdout",
13
+ BinaryStderr = "binary.stderr",
14
+ BinaryExit = "binary.exit",
15
+ AuthUrlDisplayed = "auth.url_displayed",
16
+ BrowserOpened = "browser.opened",
17
+ CallbackObservedHeuristic = "callback.observed_heuristic",
18
+ PasteCallbackPrompted = "paste.prompted",
19
+ PasteCallbackReceived = "paste.received",
20
+ PasteCallbackInvalid = "paste.invalid",
21
+ PasteCallbackSubmitted = "paste.submitted",
22
+ TokenExchangePending = "token.exchange_pending",
23
+ TokenFileAppeared = "token.file_appeared",
24
+ TokenFileMissing = "token.file_missing",
25
+ ProjectSelectionPrompted = "project.selection_prompted",
26
+ ProjectSelectionResolved = "project.selection_resolved",
27
+ AgyResponsibilityPrompted = "agy.responsibility_prompted",
28
+ AgyResponsibilityResolved = "agy.responsibility_resolved",
29
+ Timeout = "timeout",
30
+ Cancelled = "cancelled",
31
+ Error = "error"
32
+ }
33
+ /** A single OAuth trace event. `data` MUST be redacted before construction. */
34
+ export interface OAuthTraceEvent {
35
+ sessionId: string;
36
+ provider: string;
37
+ phase: OAuthTracePhase;
38
+ ts: number;
39
+ elapsedMs: number;
40
+ data?: Record<string, unknown>;
41
+ error?: {
42
+ code?: string;
43
+ message: string;
44
+ };
45
+ }
46
+ /** Sink interface — accept events that have already been redacted. */
47
+ export interface OAuthTraceSink {
48
+ write(event: OAuthTraceEvent): void;
49
+ flush?(): Promise<void>;
50
+ }
51
+ //# sourceMappingURL=trace-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-events.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/trace-events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oBAAY,eAAe;IAEzB,cAAc,oBAAoB;IAClC,WAAW,iBAAiB;IAC5B,oBAAoB,2BAA2B;IAG/C,WAAW,iBAAiB;IAC5B,YAAY,kBAAkB;IAC9B,YAAY,kBAAkB;IAC9B,UAAU,gBAAgB;IAG1B,gBAAgB,uBAAuB;IACvC,aAAa,mBAAmB;IAChC,yBAAyB,gCAAgC;IAGzD,qBAAqB,mBAAmB;IACxC,qBAAqB,mBAAmB;IACxC,oBAAoB,kBAAkB;IACtC,sBAAsB,oBAAoB;IAG1C,oBAAoB,2BAA2B;IAC/C,iBAAiB,wBAAwB;IACzC,gBAAgB,uBAAuB;IAGvC,wBAAwB,+BAA+B;IACvD,wBAAwB,+BAA+B;IACvD,yBAAyB,gCAAgC;IACzD,yBAAyB,gCAAgC;IAGzD,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,KAAK,UAAU;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,sEAAsE;AACtE,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth trace event taxonomy.
4
+ *
5
+ * Single source of truth for phase IDs that flow through the OAuth pipeline.
6
+ * Additive only — never remove or renumber.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.OAuthTracePhase = void 0;
10
+ var OAuthTracePhase;
11
+ (function (OAuthTracePhase) {
12
+ // Pre-flight
13
+ OAuthTracePhase["PreflightStart"] = "preflight.start";
14
+ OAuthTracePhase["PreflightOk"] = "preflight.ok";
15
+ OAuthTracePhase["PreflightPortBlocked"] = "preflight.port_blocked";
16
+ // Binary process lifecycle (CLIProxyAPI Go binary)
17
+ OAuthTracePhase["BinarySpawn"] = "binary.spawn";
18
+ OAuthTracePhase["BinaryStdout"] = "binary.stdout";
19
+ OAuthTracePhase["BinaryStderr"] = "binary.stderr";
20
+ OAuthTracePhase["BinaryExit"] = "binary.exit";
21
+ // Browser / URL flow (Authorization Code)
22
+ OAuthTracePhase["AuthUrlDisplayed"] = "auth.url_displayed";
23
+ OAuthTracePhase["BrowserOpened"] = "browser.opened";
24
+ OAuthTracePhase["CallbackObservedHeuristic"] = "callback.observed_heuristic";
25
+ // Paste-callback (CCS-owned end-to-end)
26
+ OAuthTracePhase["PasteCallbackPrompted"] = "paste.prompted";
27
+ OAuthTracePhase["PasteCallbackReceived"] = "paste.received";
28
+ OAuthTracePhase["PasteCallbackInvalid"] = "paste.invalid";
29
+ OAuthTracePhase["PasteCallbackSubmitted"] = "paste.submitted";
30
+ // Token exchange + persistence
31
+ OAuthTracePhase["TokenExchangePending"] = "token.exchange_pending";
32
+ OAuthTracePhase["TokenFileAppeared"] = "token.file_appeared";
33
+ OAuthTracePhase["TokenFileMissing"] = "token.file_missing";
34
+ // Provider-specific gates (Phase 4/5 extend)
35
+ OAuthTracePhase["ProjectSelectionPrompted"] = "project.selection_prompted";
36
+ OAuthTracePhase["ProjectSelectionResolved"] = "project.selection_resolved";
37
+ OAuthTracePhase["AgyResponsibilityPrompted"] = "agy.responsibility_prompted";
38
+ OAuthTracePhase["AgyResponsibilityResolved"] = "agy.responsibility_resolved";
39
+ // Terminal states
40
+ OAuthTracePhase["Timeout"] = "timeout";
41
+ OAuthTracePhase["Cancelled"] = "cancelled";
42
+ OAuthTracePhase["Error"] = "error";
43
+ })(OAuthTracePhase || (exports.OAuthTracePhase = OAuthTracePhase = {}));
44
+ //# sourceMappingURL=trace-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-events.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/trace-events.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,IAAY,eAsCX;AAtCD,WAAY,eAAe;IACzB,aAAa;IACb,qDAAkC,CAAA;IAClC,+CAA4B,CAAA;IAC5B,kEAA+C,CAAA;IAE/C,mDAAmD;IACnD,+CAA4B,CAAA;IAC5B,iDAA8B,CAAA;IAC9B,iDAA8B,CAAA;IAC9B,6CAA0B,CAAA;IAE1B,0CAA0C;IAC1C,0DAAuC,CAAA;IACvC,mDAAgC,CAAA;IAChC,4EAAyD,CAAA;IAEzD,wCAAwC;IACxC,2DAAwC,CAAA;IACxC,2DAAwC,CAAA;IACxC,yDAAsC,CAAA;IACtC,6DAA0C,CAAA;IAE1C,+BAA+B;IAC/B,kEAA+C,CAAA;IAC/C,4DAAyC,CAAA;IACzC,0DAAuC,CAAA;IAEvC,6CAA6C;IAC7C,0EAAuD,CAAA;IACvD,0EAAuD,CAAA;IACvD,4EAAyD,CAAA;IACzD,4EAAyD,CAAA;IAEzD,kBAAkB;IAClB,sCAAmB,CAAA;IACnB,0CAAuB,CAAA;IACvB,kCAAe,CAAA;AACjB,CAAC,EAtCW,eAAe,+BAAf,eAAe,QAsC1B"}
@@ -0,0 +1,34 @@
1
+ import { OAuthTraceEvent, OAuthTracePhase, OAuthTraceSink } from './trace-events';
2
+ export interface OAuthTraceRecorder {
3
+ record(phase: OAuthTracePhase, data?: Record<string, unknown>, error?: {
4
+ code?: string;
5
+ message: string;
6
+ } | Error): void;
7
+ snapshot(): OAuthTraceEvent[];
8
+ summary(): {
9
+ totalMs: number;
10
+ phaseCounts: Record<string, number>;
11
+ lastPhase?: OAuthTracePhase;
12
+ };
13
+ flush(): Promise<void>;
14
+ }
15
+ export interface OAuthTraceRecorderOptions {
16
+ sessionId: string;
17
+ provider: string;
18
+ verbose: boolean;
19
+ fileSink?: OAuthTraceSink;
20
+ /** Test seam — defaults to `Date.now`. */
21
+ now?: () => number;
22
+ /** Test seam — override verbose sink output channel. */
23
+ verboseOut?: (line: string) => void;
24
+ }
25
+ /**
26
+ * Create a per-attempt recorder. Always wires:
27
+ * - memory sink (read via `snapshot()`)
28
+ * - verbose stdout sink (no-op when verbose=false)
29
+ * - optional file sink (Phase 8)
30
+ *
31
+ * All event data passes through the redactor before reaching any sink.
32
+ */
33
+ export declare function createOAuthTraceRecorder(options: OAuthTraceRecorderOptions): OAuthTraceRecorder;
34
+ //# sourceMappingURL=trace-recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-recorder.d.ts","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/trace-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKlF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CACJ,KAAK,EAAE,eAAe,EACtB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,GACjD,IAAI,CAAC;IACR,QAAQ,IAAI,eAAe,EAAE,CAAC;IAC9B,OAAO,IAAI;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,CAAC;IACF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CAmE/F"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOAuthTraceRecorder = void 0;
4
+ const sink_memory_1 = require("./sink-memory");
5
+ const sink_verbose_stdout_1 = require("./sink-verbose-stdout");
6
+ const redactor_1 = require("./redactor");
7
+ /**
8
+ * Create a per-attempt recorder. Always wires:
9
+ * - memory sink (read via `snapshot()`)
10
+ * - verbose stdout sink (no-op when verbose=false)
11
+ * - optional file sink (Phase 8)
12
+ *
13
+ * All event data passes through the redactor before reaching any sink.
14
+ */
15
+ function createOAuthTraceRecorder(options) {
16
+ const now = options.now ?? Date.now;
17
+ const start = now();
18
+ const memory = (0, sink_memory_1.createMemorySink)();
19
+ const verbose = (0, sink_verbose_stdout_1.createVerboseStdoutSink)({ enabled: options.verbose, out: options.verboseOut });
20
+ const sinks = [memory, verbose];
21
+ if (options.fileSink)
22
+ sinks.push(options.fileSink);
23
+ const phaseCounts = {};
24
+ let lastPhase;
25
+ function toErrorObj(err) {
26
+ if (!err)
27
+ return undefined;
28
+ if (err instanceof Error) {
29
+ return { message: err.message };
30
+ }
31
+ return { code: err.code, message: err.message };
32
+ }
33
+ return {
34
+ record(phase, data, error) {
35
+ const ts = now();
36
+ const elapsedMs = ts - start;
37
+ const redacted = data ? (0, redactor_1.redactJsonShallow)(data) : undefined;
38
+ const event = {
39
+ sessionId: options.sessionId,
40
+ provider: options.provider,
41
+ phase,
42
+ ts,
43
+ elapsedMs,
44
+ data: redacted,
45
+ error: toErrorObj(error),
46
+ };
47
+ phaseCounts[phase] = (phaseCounts[phase] ?? 0) + 1;
48
+ lastPhase = phase;
49
+ for (const sink of sinks) {
50
+ try {
51
+ sink.write(event);
52
+ }
53
+ catch {
54
+ // Sinks must never throw out — drop on failure.
55
+ }
56
+ }
57
+ },
58
+ snapshot() {
59
+ return memory.snapshot();
60
+ },
61
+ summary() {
62
+ return {
63
+ totalMs: now() - start,
64
+ phaseCounts: { ...phaseCounts },
65
+ lastPhase,
66
+ };
67
+ },
68
+ async flush() {
69
+ for (const sink of sinks) {
70
+ if (sink.flush) {
71
+ try {
72
+ await sink.flush();
73
+ }
74
+ catch {
75
+ // ignore
76
+ }
77
+ }
78
+ }
79
+ },
80
+ };
81
+ }
82
+ exports.createOAuthTraceRecorder = createOAuthTraceRecorder;
83
+ //# sourceMappingURL=trace-recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-recorder.js","sourceRoot":"","sources":["../../../../src/cliproxy/auth/oauth-trace/trace-recorder.ts"],"names":[],"mappings":";;;AACA,+CAAiD;AACjD,+DAAgE;AAChE,yCAA+C;AA4B/C;;;;;;;GAOG;AACH,SAAgB,wBAAwB,CAAC,OAAkC;IACzE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,IAAA,8BAAgB,GAAE,CAAC;IAClC,MAAM,OAAO,GAAG,IAAA,6CAAuB,EAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAqB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,IAAI,SAAsC,CAAC;IAE3C,SAAS,UAAU,CACjB,GAA2D;QAE3D,IAAI,CAAC,GAAG;YAAE,OAAO,SAAS,CAAC;QAC3B,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAClC,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAClD,CAAC;IAED,OAAO;QACL,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK;YACvB,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,EAAE,GAAG,KAAK,CAAC;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,IAAA,4BAAiB,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5D,MAAM,KAAK,GAAoB;gBAC7B,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK;gBACL,EAAE;gBACF,SAAS;gBACT,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC;aACzB,CAAC;YACF,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnD,SAAS,GAAG,KAAK,CAAC;YAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;gBAAC,MAAM,CAAC;oBACP,gDAAgD;gBAClD,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ;YACN,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC3B,CAAC;QACD,OAAO;YACL,OAAO;gBACL,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK;gBACtB,WAAW,EAAE,EAAE,GAAG,WAAW,EAAE;gBAC/B,SAAS;aACV,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,KAAK;YACT,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;oBACrB,CAAC;oBAAC,MAAM,CAAC;wBACP,SAAS;oBACX,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAnED,4DAmEC"}