archal 0.9.19 → 0.9.20

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 (92) hide show
  1. package/README.md +9 -1
  2. package/agents/github-octokit/.archal.json +8 -0
  3. package/agents/github-octokit/Dockerfile +8 -0
  4. package/agents/github-octokit/README.md +113 -0
  5. package/agents/github-octokit/agent.mjs +54 -0
  6. package/agents/github-octokit/package.json +9 -0
  7. package/agents/github-octokit/scenarios/test-repo-access.md +27 -0
  8. package/agents/google-workspace-local-tools/Dockerfile +6 -0
  9. package/agents/google-workspace-local-tools/README.md +58 -0
  10. package/agents/google-workspace-local-tools/agent.mjs +196 -0
  11. package/agents/google-workspace-local-tools/archal-harness.json +7 -0
  12. package/agents/google-workspace-local-tools/run-input.yaml +16 -0
  13. package/agents/google-workspace-local-tools/scenario.md +29 -0
  14. package/agents/hermes/.archal.json +8 -0
  15. package/agents/hermes/Dockerfile +46 -0
  16. package/agents/hermes/README.md +87 -0
  17. package/agents/hermes/SOUL.md +27 -0
  18. package/agents/hermes/config.yaml +34 -0
  19. package/agents/hermes/drive.mjs +113 -0
  20. package/agents/hermes/scenarios/stripe-customers-read-only.md +32 -0
  21. package/agents/openclaw/.archal.json +8 -0
  22. package/agents/openclaw/Dockerfile +96 -0
  23. package/agents/openclaw/README.md +120 -0
  24. package/agents/openclaw/drive.mjs +311 -0
  25. package/agents/openclaw/package.json +9 -0
  26. package/agents/openclaw/scenarios/github-issue-triage-read-only.md +44 -0
  27. package/agents/openclaw/workspace/AGENTS.md +23 -0
  28. package/agents/openclaw/workspace/IDENTITY.md +8 -0
  29. package/agents/openclaw/workspace/SOUL.md +14 -0
  30. package/agents/openclaw/workspace/TOOLS.md +35 -0
  31. package/agents/pagination-test/README.md +24 -0
  32. package/agents/pagination-test/scenario.md +24 -0
  33. package/agents/replay-capsule-harness/README.md +29 -0
  34. package/agents/replay-capsule-harness/observability-install-offline-e2e.mts +1517 -0
  35. package/agents/replay-capsule-harness/replay-capsule-e2e.mjs +104 -0
  36. package/clone-assets/apify/tools.json +256 -22
  37. package/clone-assets/calcom/tools.json +510 -0
  38. package/clone-assets/clickup/tools.json +1258 -0
  39. package/clone-assets/customerio/tools.json +386 -0
  40. package/clone-assets/datadog/tools.json +734 -0
  41. package/clone-assets/github/tools.json +306 -25
  42. package/clone-assets/gitlab/tools.json +999 -0
  43. package/clone-assets/google-workspace/tools.json +18 -6
  44. package/clone-assets/hubspot/tools.json +1406 -0
  45. package/clone-assets/jira/fidelity.json +1 -1
  46. package/clone-assets/jira/tools.json +266 -543
  47. package/clone-assets/linear/tools.json +238 -40
  48. package/clone-assets/ownerrez/tools.json +548 -0
  49. package/clone-assets/pricelabs/tools.json +343 -0
  50. package/clone-assets/sentry/tools.json +745 -0
  51. package/clone-assets/slack/tools.json +1 -2
  52. package/clone-assets/stripe/tools.json +185 -46
  53. package/clone-assets/supabase/tools.json +437 -0
  54. package/clone-assets/unipile/tools.json +408 -0
  55. package/clone-assets/webflow/tools.json +415 -0
  56. package/dist/autoloop-worker-types-BEb_E44z.d.cts +196 -0
  57. package/dist/cli.cjs +150299 -87430
  58. package/dist/commands/autoloop-hosted-worker.cjs +43942 -0
  59. package/dist/commands/autoloop-hosted-worker.d.cts +143 -0
  60. package/dist/commands/autoloop-pr-verification.cjs +4227 -0
  61. package/dist/commands/autoloop-pr-verification.d.cts +17 -0
  62. package/dist/{vitest/chunk-L36NXAU6.js → commands/autoloop-result-parser.cjs} +16445 -18852
  63. package/dist/commands/autoloop-result-parser.d.cts +39 -0
  64. package/dist/commands/autoloop-worker.cjs +36163 -0
  65. package/dist/commands/autoloop-worker.d.cts +97 -0
  66. package/dist/harness.cjs +1 -0
  67. package/dist/index.cjs +1 -1
  68. package/dist/replay.cjs +49624 -0
  69. package/dist/replay.d.cts +4625 -0
  70. package/dist/scenarios.cjs +80343 -0
  71. package/dist/scenarios.d.cts +562 -0
  72. package/dist/vitest/chunk-6CBYFCFK.js +4667 -0
  73. package/dist/vitest/chunk-ARVS45PP.js +2764 -0
  74. package/dist/vitest/index.cjs +6011 -75261
  75. package/dist/vitest/index.d.ts +7 -6
  76. package/dist/vitest/index.js +8 -8
  77. package/dist/vitest/runtime/hosted-session-reaper.cjs +792 -34359
  78. package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
  79. package/dist/vitest/runtime/setup-files.js +2 -2
  80. package/package.json +8 -3
  81. package/skills/archal-agent/SKILL.md +87 -0
  82. package/skills/{attach → autoloop}/SKILL.md +94 -120
  83. package/skills/autoloop/references/hosted-sources.md +62 -0
  84. package/skills/autoloop/references/trace-schema-mapping.md +73 -0
  85. package/skills/eval/SKILL.md +35 -1
  86. package/skills/install-agent/SKILL.md +221 -0
  87. package/skills/onboard/SKILL.md +73 -5
  88. package/skills/scenario/SKILL.md +19 -4
  89. package/skills/seed/SKILL.md +237 -0
  90. package/dist/seed/dynamic-generator.cjs +0 -45687
  91. package/dist/seed/dynamic-generator.d.cts +0 -106
  92. package/dist/vitest/chunk-WZ7SA4CK.js +0 -47369
@@ -0,0 +1,4227 @@
1
+ const import_meta_url = require('url').pathToFileURL(__filename).href;
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/commands/autoloop-pr-verification.ts
22
+ var autoloop_pr_verification_exports = {};
23
+ __export(autoloop_pr_verification_exports, {
24
+ verifyFixResult: () => verifyFixResult,
25
+ verifyOpenFixPrPoll: () => verifyOpenFixPrPoll
26
+ });
27
+ module.exports = __toCommonJS(autoloop_pr_verification_exports);
28
+
29
+ // ../packages/contracts/src/autoloop/layer-0.ts
30
+ var AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_TYPES = [
31
+ "grade_summary",
32
+ "seed_summary",
33
+ "reproduction_summary",
34
+ "replay_plan",
35
+ "regression_pack",
36
+ "assertion_result",
37
+ "fix_summary"
38
+ ];
39
+ var AUTOLOOP_INTERNAL_ONLY_ARTIFACT_TYPES = [
40
+ "source_snapshot",
41
+ "grade_payload",
42
+ "codex_prompt",
43
+ "codex_transcript",
44
+ "command_log",
45
+ "sandbox_bundle",
46
+ "rag_replay_package"
47
+ ];
48
+ var AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_REDACTION_STATUSES = [
49
+ "redacted",
50
+ "not_required"
51
+ ];
52
+ var AUTOLOOP_REDACTED_STATUS = "redacted";
53
+ var AUTOLOOP_CUSTOMER_VISIBLE_VISIBILITY = "customer_visible";
54
+ var AUTOLOOP_INTERNAL_VISIBILITY = "internal";
55
+ var AUTOLOOP_CUSTOMER_VISIBLE_EVENT_TYPES = [
56
+ "grade.completed",
57
+ "seed.completed",
58
+ "reproduction.completed",
59
+ "fix.completed",
60
+ "autoloop_run.finalized"
61
+ ];
62
+ var AGENT_STREAM_DELTA_EVENT_TYPE = "agent_stream.delta";
63
+ var AGENT_STREAM_TRUNCATED_EVENT_TYPE = "agent_stream.truncated";
64
+ var AGENT_STREAM_COMPLETED_EVENT_TYPE = "agent_stream.completed";
65
+ var AUTOLOOP_EVENT_SEVERITIES = ["debug", "info", "warn", "error"];
66
+ var AUTOLOOP_PHASES = ["queued", "grade", "seed", "reproduce", "fix_pr", "done"];
67
+ var AUTOLOOP_ACTIVE_PHASES = ["grade", "seed", "reproduce", "fix_pr"];
68
+ var AUTOLOOP_PHASE_HEALTH_STATUSES = [
69
+ "running",
70
+ "completed",
71
+ "stream_reconnect_recovered",
72
+ "stalled_no_artifact",
73
+ "timeout",
74
+ "failed"
75
+ ];
76
+ var AUTOLOOP_TERMINAL_STATUSES = [
77
+ "running",
78
+ "succeeded",
79
+ "failed",
80
+ "blocked",
81
+ "cancelled"
82
+ ];
83
+ var AUTOLOOP_CODEX_SESSION_EVENT_STATUSES = [
84
+ "queued",
85
+ "running",
86
+ "succeeded",
87
+ "failed",
88
+ "blocked"
89
+ ];
90
+ var SOURCE_SNAPSHOT_EVENT_ACTIONS = ["created", "updated"];
91
+ var AUTOLOOP_FIX_RESULT_STATUSES = [
92
+ "pr_open",
93
+ "checks_passing",
94
+ "blocked",
95
+ "failed"
96
+ ];
97
+ var AUTOLOOP_CUSTOMER_SAFE_CONTROL_PLANE_MESSAGES = [
98
+ "databaseUrl is only supported for postgres and supabase trace sources",
99
+ "connectionSecretRef must be a secret reference, not a plaintext credential",
100
+ "connectionSecretRef must be an env: or AWS Secrets Manager reference",
101
+ "connectionSecretRef must be at most 500 characters",
102
+ "displayName must be a non-empty exact string",
103
+ "displayName cannot contain credential-shaped values",
104
+ "displayName must be at most 160 characters",
105
+ "repositoryFullName must be owner/repo",
106
+ "repositoryFullName must be at most 300 characters",
107
+ "sourceId must be a UUID",
108
+ "trace source filters and metadata cannot contain credential-shaped fields or values",
109
+ "trace source filters and metadata cannot contain prototype-polluting keys"
110
+ ];
111
+ var MAX_AUTOLOOP_CONTINUATION_ARTIFACT_BYTES = 1024 * 1024;
112
+ function manifestFieldIsExplicitlyFalse(record, camelKey) {
113
+ const snakeKey = camelKey.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
114
+ return record[camelKey] === false || record[snakeKey] === false;
115
+ }
116
+ var LOCAL_AUTOLOOP_LEDGER_QUEUED_LEASE_MS = 10 * 60 * 1e3;
117
+ var MAX_AGENT_STREAM_EVENT_METADATA_BYTES = 16 * 1024;
118
+
119
+ // ../packages/contracts/src/autoloop/layer-1.ts
120
+ var AUTOLOOP_ARTIFACT_TYPES = [
121
+ ...AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_TYPES,
122
+ ...AUTOLOOP_INTERNAL_ONLY_ARTIFACT_TYPES
123
+ ];
124
+ var AUTOLOOP_REDACTION_STATUSES = [
125
+ "unreviewed",
126
+ AUTOLOOP_REDACTED_STATUS,
127
+ "not_required",
128
+ "blocked"
129
+ ];
130
+ var AUTOLOOP_VISIBILITIES = [
131
+ AUTOLOOP_CUSTOMER_VISIBLE_VISIBILITY,
132
+ AUTOLOOP_INTERNAL_VISIBILITY
133
+ ];
134
+ var AGENT_STREAM_EVENT_TYPES = [
135
+ AGENT_STREAM_DELTA_EVENT_TYPE,
136
+ AGENT_STREAM_TRUNCATED_EVENT_TYPE,
137
+ AGENT_STREAM_COMPLETED_EVENT_TYPE
138
+ ];
139
+ var AUTOLOOP_CODEX_SESSION_STATUSES = [
140
+ "queued",
141
+ ...AUTOLOOP_TERMINAL_STATUSES
142
+ ];
143
+ var AUTOLOOP_FIX_RUN_STATUSES = [
144
+ "not_started",
145
+ "running",
146
+ ...AUTOLOOP_FIX_RESULT_STATUSES
147
+ ];
148
+
149
+ // ../packages/contracts/src/autoloop/layer-2.ts
150
+ var AUTOLOOP_INTERNAL_ONLY_EVENT_TYPES = [
151
+ "worker.failed",
152
+ "codex_session.recorded",
153
+ "source_snapshot.created",
154
+ "source_snapshot.updated",
155
+ "autoloop_run.claimed",
156
+ "autoloop_run.retry_scheduled",
157
+ ...AGENT_STREAM_EVENT_TYPES
158
+ ];
159
+ function autoloopRunCapabilitiesFromPostFixPayload(payload) {
160
+ return {
161
+ requiresCloneEvidence: !manifestFieldIsExplicitlyFalse(
162
+ payload,
163
+ "postFixReproduceCloneEvidenceExpected"
164
+ )
165
+ };
166
+ }
167
+
168
+ // ../packages/contracts/src/autoloop/layer-3.ts
169
+ var AUTOLOOP_EVENT_TYPES = [
170
+ ...AUTOLOOP_CUSTOMER_VISIBLE_EVENT_TYPES,
171
+ ...AUTOLOOP_INTERNAL_ONLY_EVENT_TYPES
172
+ ];
173
+
174
+ // ../packages/contracts/src/autoloop.ts
175
+ var AUTOLOOP_CUSTOMER_SAFE_CONTROL_PLANE_MESSAGE_SET = new Set(AUTOLOOP_CUSTOMER_SAFE_CONTROL_PLANE_MESSAGES);
176
+ var AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_TYPE_SET = new Set(
177
+ AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_TYPES
178
+ );
179
+ var AUTOLOOP_INTERNAL_ONLY_ARTIFACT_TYPE_SET = new Set(
180
+ AUTOLOOP_INTERNAL_ONLY_ARTIFACT_TYPES
181
+ );
182
+ var AUTOLOOP_ARTIFACT_TYPE_SET = new Set(AUTOLOOP_ARTIFACT_TYPES);
183
+ var AUTOLOOP_PHASE_HEALTH_STATUS_SET = new Set(AUTOLOOP_PHASE_HEALTH_STATUSES);
184
+ var AUTOLOOP_CODEX_SESSION_STATUS_SET = new Set(AUTOLOOP_CODEX_SESSION_STATUSES);
185
+ var AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_REDACTION_STATUS_SET = new Set(
186
+ AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_REDACTION_STATUSES
187
+ );
188
+ var AUTOLOOP_CUSTOMER_VISIBLE_EVENT_TYPE_SET = new Set(
189
+ AUTOLOOP_CUSTOMER_VISIBLE_EVENT_TYPES
190
+ );
191
+ var AUTOLOOP_INTERNAL_ONLY_EVENT_TYPE_SET = new Set(
192
+ AUTOLOOP_INTERNAL_ONLY_EVENT_TYPES
193
+ );
194
+ var AUTOLOOP_PHASE_SET = new Set(AUTOLOOP_PHASES);
195
+ var AUTOLOOP_ACTIVE_PHASE_SET = new Set(AUTOLOOP_ACTIVE_PHASES);
196
+ var AUTOLOOP_CODEX_SESSION_EVENT_STATUS_SET = new Set(
197
+ AUTOLOOP_CODEX_SESSION_EVENT_STATUSES
198
+ );
199
+ var AUTOLOOP_EVENT_TYPE_SET = new Set(AUTOLOOP_EVENT_TYPES);
200
+ var AUTOLOOP_EVENT_SEVERITY_SET = new Set(AUTOLOOP_EVENT_SEVERITIES);
201
+ var AUTOLOOP_VISIBILITY_SET = new Set(AUTOLOOP_VISIBILITIES);
202
+ var AUTOLOOP_REDACTION_STATUS_SET = new Set(AUTOLOOP_REDACTION_STATUSES);
203
+ var AUTOLOOP_TERMINAL_STATUS_SET = new Set(AUTOLOOP_TERMINAL_STATUSES);
204
+ var SOURCE_SNAPSHOT_EVENT_ACTION_SET = new Set(SOURCE_SNAPSHOT_EVENT_ACTIONS);
205
+ var AUTOLOOP_EXECUTION_POLICY_PHASE_COUNT = {
206
+ observe: 0,
207
+ grade: 1,
208
+ seed: 2,
209
+ reproduce: 3,
210
+ fix: AUTOLOOP_ACTIVE_PHASES.length
211
+ };
212
+ function assessAutoloopStoredFixPrEvidence(payload, input = {}) {
213
+ const localValidationStatus = autoloopFixPrEvidenceStringFromRecord(
214
+ payload,
215
+ "localValidationStatus",
216
+ "local_validation_status"
217
+ );
218
+ const fixQuality = payloadFixQuality(payload);
219
+ const postFixReproduction = autoloopPostFixReproductionEvidenceFromPayload(payload, input);
220
+ const prBodyQuality = payloadPrBodyQuality(payload);
221
+ const verifiedFixEvidence = {
222
+ localValidationStatus,
223
+ fixQuality,
224
+ postFixReproduction,
225
+ prBodyQuality
226
+ };
227
+ if (!postFixReproduction.passed) {
228
+ return {
229
+ passed: false,
230
+ reason: postFixReproduction.reason,
231
+ localValidationStatus,
232
+ fixQuality,
233
+ postFixReproduction,
234
+ prBodyQuality,
235
+ verifiedFixEvidence: null
236
+ };
237
+ }
238
+ if (fixQuality.status !== "passed") {
239
+ return {
240
+ passed: false,
241
+ reason: fixQuality.reason,
242
+ localValidationStatus,
243
+ fixQuality,
244
+ postFixReproduction,
245
+ prBodyQuality,
246
+ verifiedFixEvidence: null
247
+ };
248
+ }
249
+ if (prBodyQuality.status !== "passed") {
250
+ return {
251
+ passed: false,
252
+ reason: prBodyQuality.reason,
253
+ localValidationStatus,
254
+ fixQuality,
255
+ postFixReproduction,
256
+ prBodyQuality,
257
+ verifiedFixEvidence: null
258
+ };
259
+ }
260
+ return {
261
+ passed: true,
262
+ reason: "fix_pr_quality_passed",
263
+ localValidationStatus,
264
+ fixQuality,
265
+ postFixReproduction,
266
+ prBodyQuality,
267
+ verifiedFixEvidence
268
+ };
269
+ }
270
+ function autoloopPostFixReproductionEvidenceFromPayload(payload, input = {}) {
271
+ if (!isAutoloopFixPrEvidenceRecord(payload)) {
272
+ return failedAutoloopPostFixReproduction("postfix_reproduction_not_verified");
273
+ }
274
+ const status = autoloopFixPrEvidenceString(
275
+ payload["postFixReproduceStatus"] ?? payload["post_fix_reproduce_status"]
276
+ );
277
+ const reverified = autoloopFixPrEvidenceBoolean(
278
+ payload["reproductionReverified"] ?? payload["reproduction_reverified"]
279
+ );
280
+ const hasCloneEvidence = autoloopFixPrEvidenceBoolean(
281
+ payload["postFixReproduceHasCloneEvidence"] ?? payload["post_fix_reproduce_has_clone_evidence"]
282
+ ) === true;
283
+ const hasCriteriaEvidence = autoloopFixPrEvidenceBoolean(
284
+ payload["postFixReproduceHasCriteriaEvidence"] ?? payload["post_fix_reproduce_has_criteria_evidence"]
285
+ );
286
+ const identityMatchesPreFix = autoloopFixPrEvidenceBoolean(
287
+ payload["postFixReproduceIdentityMatchesPreFix"] ?? payload["post_fix_reproduce_identity_matches_pre_fix"] ?? payload["postFixReproduceReplayIdentityMatchesPreFix"] ?? payload["post_fix_reproduce_replay_identity_matches_pre_fix"]
288
+ );
289
+ const commitSha = autoloopFixPrEvidenceSha(
290
+ autoloopFixPrEvidenceString(
291
+ payload["postFixReproduceCommitSha"] ?? payload["post_fix_reproduce_commit_sha"]
292
+ )
293
+ );
294
+ const requiresCloneEvidence = autoloopRunCapabilitiesFromPostFixPayload(payload).requiresCloneEvidence;
295
+ const cloneEvidenceField = requiresCloneEvidence ? {} : { cloneEvidenceExpected: false };
296
+ if (status === "not_reproduced" && reverified === true && (!requiresCloneEvidence || hasCloneEvidence === true) && hasCriteriaEvidence === true && identityMatchesPreFix === true) {
297
+ if (!commitSha) {
298
+ return failedAutoloopPostFixReproduction("postfix_reproduction_commit_missing", {
299
+ status,
300
+ hasCloneEvidence,
301
+ hasCriteriaEvidence,
302
+ identityMatchesPreFix,
303
+ reproductionReverified: true,
304
+ ...cloneEvidenceField
305
+ });
306
+ }
307
+ if (input.expectedCommitSha && commitSha.toLowerCase() !== input.expectedCommitSha.toLowerCase()) {
308
+ return failedAutoloopPostFixReproduction("postfix_reproduction_commit_mismatch", {
309
+ status,
310
+ commitSha,
311
+ hasCloneEvidence,
312
+ hasCriteriaEvidence,
313
+ identityMatchesPreFix,
314
+ reproductionReverified: true,
315
+ ...cloneEvidenceField
316
+ });
317
+ }
318
+ return {
319
+ passed: true,
320
+ reason: "postfix_reproduction_passed",
321
+ status,
322
+ commitSha,
323
+ hasCloneEvidence,
324
+ hasCriteriaEvidence,
325
+ identityMatchesPreFix,
326
+ reproductionReverified: true,
327
+ ...cloneEvidenceField
328
+ };
329
+ }
330
+ if (status === "reproduced" || status === "flaky") {
331
+ return failedAutoloopPostFixReproduction("postfix_reproduction_still_failing", {
332
+ status,
333
+ commitSha
334
+ });
335
+ }
336
+ if (status === "not_reproduced" && requiresCloneEvidence && hasCloneEvidence !== true) {
337
+ return failedAutoloopPostFixReproduction("postfix_reproduction_clone_evidence_missing", {
338
+ status,
339
+ commitSha
340
+ });
341
+ }
342
+ if (status === "not_reproduced" && hasCriteriaEvidence !== true) {
343
+ return failedAutoloopPostFixReproduction("postfix_reproduction_criteria_evidence_missing", {
344
+ status,
345
+ commitSha,
346
+ hasCloneEvidence: true
347
+ });
348
+ }
349
+ if (status === "not_reproduced" && identityMatchesPreFix !== true) {
350
+ return failedAutoloopPostFixReproduction("postfix_reproduction_trace_mismatch", {
351
+ status,
352
+ commitSha,
353
+ hasCloneEvidence: true,
354
+ hasCriteriaEvidence: true,
355
+ identityMatchesPreFix: false,
356
+ reproductionReverified: reverified === true
357
+ });
358
+ }
359
+ if (status === "not_reproduced") {
360
+ return failedAutoloopPostFixReproduction(
361
+ autoloopFixPrEvidenceString(
362
+ payload["postFixReproduceReason"] ?? payload["post_fix_reproduce_reason"]
363
+ ) ?? "postfix_reproduction_not_verified",
364
+ {
365
+ status,
366
+ commitSha,
367
+ hasCloneEvidence: true,
368
+ hasCriteriaEvidence: true,
369
+ identityMatchesPreFix: true,
370
+ reproductionReverified: false
371
+ }
372
+ );
373
+ }
374
+ if (status !== null) {
375
+ return failedAutoloopPostFixReproduction(
376
+ autoloopFixPrEvidenceString(
377
+ payload["postFixReproduceReason"] ?? payload["post_fix_reproduce_reason"]
378
+ ) ?? "postfix_reproduction_not_verified",
379
+ { status, commitSha }
380
+ );
381
+ }
382
+ const nested = nestedAutoloopPostFixReproductionEvidence(
383
+ payload,
384
+ identityMatchesPreFix,
385
+ commitSha,
386
+ input
387
+ );
388
+ if (nested) return nested;
389
+ return failedAutoloopPostFixReproduction(
390
+ autoloopFixPrEvidenceString(
391
+ payload["postFixReproduceReason"] ?? payload["post_fix_reproduce_reason"]
392
+ ) ?? "postfix_reproduction_not_verified",
393
+ { status, commitSha }
394
+ );
395
+ }
396
+ function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatchesPreFix, commitSha, input) {
397
+ const reproduction = payload["postFixReproduction"] ?? payload["post_fix_reproduction"];
398
+ if (!isAutoloopFixPrEvidenceRecord(reproduction)) return null;
399
+ const attempts = reproduction["attempts"];
400
+ const commands = Array.isArray(reproduction["commands"]) ? reproduction["commands"] : [];
401
+ const hasEvidence = typeof attempts === "number" && attempts >= 1 && commands.length > 0;
402
+ const status = autoloopFixPrEvidenceString(reproduction["status"]);
403
+ const hasCloneEvidence = autoloopFixPrEvidenceBoolean(reproduction["hasCloneEvidence"]) === true;
404
+ const hasCriteriaEvidence = autoloopFixPrEvidenceBoolean(reproduction["hasCriteriaEvidence"]) === true;
405
+ const identityMatchesPreFix = autoloopFixPrEvidenceBoolean(
406
+ reproduction["replayIdentityMatchesPreFix"] ?? reproduction["identityMatchesPreFix"]
407
+ ) ?? topLevelIdentityMatchesPreFix ?? false;
408
+ const passedLegacyStatus = status === "passed" || status === "not_reproduced" && hasCloneEvidence && hasCriteriaEvidence;
409
+ if (passedLegacyStatus && hasEvidence) {
410
+ const legacyHasCloneEvidence = status === "passed" ? true : hasCloneEvidence;
411
+ const legacyHasCriteriaEvidence = status === "passed" ? true : hasCriteriaEvidence;
412
+ if (!identityMatchesPreFix) {
413
+ return failedAutoloopPostFixReproduction("postfix_reproduction_trace_mismatch", {
414
+ status,
415
+ commitSha,
416
+ hasCloneEvidence: legacyHasCloneEvidence,
417
+ hasCriteriaEvidence: legacyHasCriteriaEvidence,
418
+ identityMatchesPreFix: false,
419
+ reproductionReverified: true
420
+ });
421
+ }
422
+ if (!commitSha && input.expectedCommitSha) {
423
+ return failedAutoloopPostFixReproduction("postfix_reproduction_commit_missing", {
424
+ status,
425
+ hasCloneEvidence: legacyHasCloneEvidence,
426
+ hasCriteriaEvidence: legacyHasCriteriaEvidence,
427
+ identityMatchesPreFix,
428
+ reproductionReverified: true
429
+ });
430
+ }
431
+ if (input.expectedCommitSha && commitSha?.toLowerCase() !== input.expectedCommitSha.toLowerCase()) {
432
+ return failedAutoloopPostFixReproduction("postfix_reproduction_commit_mismatch", {
433
+ status,
434
+ commitSha,
435
+ hasCloneEvidence: legacyHasCloneEvidence,
436
+ hasCriteriaEvidence: legacyHasCriteriaEvidence,
437
+ identityMatchesPreFix,
438
+ reproductionReverified: true
439
+ });
440
+ }
441
+ return {
442
+ passed: true,
443
+ reason: "postfix_reproduction_passed",
444
+ status,
445
+ commitSha,
446
+ hasCloneEvidence: legacyHasCloneEvidence,
447
+ hasCriteriaEvidence: legacyHasCriteriaEvidence,
448
+ identityMatchesPreFix,
449
+ reproductionReverified: true
450
+ };
451
+ }
452
+ const reason = autoloopFixPrEvidenceString(reproduction["reason"]);
453
+ return reason ? failedAutoloopPostFixReproduction(reason, { status, commitSha }) : null;
454
+ }
455
+ function failedAutoloopPostFixReproduction(reason, evidence = {}) {
456
+ return {
457
+ passed: false,
458
+ reason,
459
+ status: evidence.status ?? null,
460
+ commitSha: evidence.commitSha ?? null,
461
+ hasCloneEvidence: evidence.hasCloneEvidence ?? false,
462
+ hasCriteriaEvidence: evidence.hasCriteriaEvidence ?? false,
463
+ identityMatchesPreFix: evidence.identityMatchesPreFix ?? false,
464
+ reproductionReverified: evidence.reproductionReverified ?? false
465
+ };
466
+ }
467
+ function payloadFixQuality(payload) {
468
+ if (!isAutoloopFixPrEvidenceRecord(payload)) {
469
+ return failedFixQuality("fix_quality_evidence_missing");
470
+ }
471
+ const quality = payload["fixQuality"] ?? payload["fix_quality"];
472
+ if (!isAutoloopFixPrEvidenceRecord(quality)) {
473
+ return failedFixQuality("fix_quality_evidence_missing");
474
+ }
475
+ const changedFiles = autoloopFixPrEvidenceStringArray(
476
+ quality["changedFiles"] ?? quality["changed_files"]
477
+ );
478
+ const sourceFiles = autoloopFixPrEvidenceStringArray(
479
+ quality["sourceFiles"] ?? quality["source_files"]
480
+ );
481
+ const implementationFiles = autoloopFixPrEvidenceStringArray(
482
+ quality["implementationFiles"] ?? quality["implementation_files"]
483
+ );
484
+ const regressionEvidence = autoloopFixPrEvidenceStringArray(
485
+ quality["regressionEvidence"] ?? quality["regression_evidence"]
486
+ );
487
+ const runtimeEntrypointFiles = autoloopFixPrEvidenceStringArray(
488
+ quality["runtimeEntrypointFiles"] ?? quality["runtime_entrypoint_files"]
489
+ );
490
+ const prDetailsPresent = autoloopFixPrEvidenceBoolean(quality["prDetailsPresent"] ?? quality["pr_details_present"]) ?? true;
491
+ if (quality["status"] !== "passed") {
492
+ return {
493
+ status: "failed",
494
+ reason: autoloopFixPrEvidenceString(quality["reason"]) ?? "fix_quality_evidence_failed",
495
+ changedFiles,
496
+ sourceFiles,
497
+ implementationFiles,
498
+ regressionEvidence,
499
+ runtimeEntrypointFiles,
500
+ prDetailsPresent
501
+ };
502
+ }
503
+ if (changedFiles.length === 0) return failedFixQuality("fix_quality_changed_files_missing");
504
+ if (sourceFiles.length === 0) {
505
+ return failedFixQuality("fix_quality_cosmetic_only_patch", { changedFiles });
506
+ }
507
+ if (implementationFiles.length === 0) {
508
+ return failedFixQuality("fix_quality_meaningful_diff_missing", { changedFiles, sourceFiles });
509
+ }
510
+ if (isDisallowedAutoloopEvalHarnessOnlyPatch(implementationFiles, runtimeEntrypointFiles)) {
511
+ return failedFixQuality("fix_quality_eval_harness_only_patch", {
512
+ changedFiles,
513
+ sourceFiles,
514
+ implementationFiles,
515
+ runtimeEntrypointFiles
516
+ });
517
+ }
518
+ if (regressionEvidence.length === 0) {
519
+ return failedFixQuality("fix_quality_regression_evidence_missing", {
520
+ changedFiles,
521
+ sourceFiles,
522
+ implementationFiles,
523
+ runtimeEntrypointFiles
524
+ });
525
+ }
526
+ if (!prDetailsPresent) {
527
+ return failedFixQuality("fix_quality_pr_details_missing", {
528
+ changedFiles,
529
+ sourceFiles,
530
+ implementationFiles,
531
+ regressionEvidence,
532
+ runtimeEntrypointFiles,
533
+ prDetailsPresent
534
+ });
535
+ }
536
+ return {
537
+ status: "passed",
538
+ reason: "fix_quality_passed",
539
+ changedFiles,
540
+ sourceFiles,
541
+ implementationFiles,
542
+ regressionEvidence,
543
+ runtimeEntrypointFiles,
544
+ prDetailsPresent
545
+ };
546
+ }
547
+ function payloadPrBodyQuality(payload) {
548
+ if (!isAutoloopFixPrEvidenceRecord(payload)) return failedPrBody("pr_body_evidence_missing");
549
+ const quality = payload["prBodyQuality"] ?? payload["pr_body_quality"];
550
+ if (!isAutoloopFixPrEvidenceRecord(quality)) return failedPrBody("pr_body_evidence_missing");
551
+ const status = quality["status"];
552
+ const reason = autoloopFixPrEvidenceString(quality["reason"]) ?? (status === "passed" ? "pr_body_passed" : "pr_body_evidence_failed");
553
+ const textLength = autoloopFixPrEvidenceNumber(quality["textLength"] ?? quality["text_length"]);
554
+ const wordCount = autoloopFixPrEvidenceNumber(quality["wordCount"] ?? quality["word_count"]);
555
+ if (status !== "passed") return failedPrBody(reason, textLength, wordCount);
556
+ if (textLength <= 0 || wordCount < 20) {
557
+ return failedPrBody("pr_body_not_human_readable", textLength, wordCount);
558
+ }
559
+ return { status: "passed", reason: "pr_body_passed", textLength, wordCount };
560
+ }
561
+ function failedFixQuality(reason, evidence = {}) {
562
+ return {
563
+ status: "failed",
564
+ reason,
565
+ changedFiles: evidence.changedFiles ?? [],
566
+ sourceFiles: evidence.sourceFiles ?? [],
567
+ implementationFiles: evidence.implementationFiles ?? [],
568
+ regressionEvidence: evidence.regressionEvidence ?? [],
569
+ runtimeEntrypointFiles: evidence.runtimeEntrypointFiles ?? [],
570
+ prDetailsPresent: evidence.prDetailsPresent ?? false
571
+ };
572
+ }
573
+ function failedPrBody(reason, textLength = 0, wordCount = 0) {
574
+ return { status: "failed", reason, textLength, wordCount };
575
+ }
576
+ function autoloopFixPrEvidenceStringFromRecord(payload, camelCaseKey, snakeCaseKey) {
577
+ if (!isAutoloopFixPrEvidenceRecord(payload)) return null;
578
+ return autoloopFixPrEvidenceString(payload[camelCaseKey] ?? payload[snakeCaseKey]);
579
+ }
580
+ function autoloopFixPrEvidenceStringArray(value) {
581
+ if (!Array.isArray(value)) return [];
582
+ return value.filter((entry) => typeof entry === "string" && entry.length > 0);
583
+ }
584
+ function isAutoloopAttachEvalHarnessFile(file) {
585
+ return /(^|\/)archal(\/|$)/i.test(file) || /(^|\/)(evals?|evaluations?|harness)(\/|$)/i.test(file) || /(^|\/)run-[^/]*eval\.[cm]?[jt]s$/i.test(file) || /(^|\/)scripts\/.*(?:archal|eval|harness).*$/i.test(file);
586
+ }
587
+ function isDisallowedAutoloopEvalHarnessOnlyPatch(implementationFiles, runtimeEntrypointFiles) {
588
+ if (!implementationFiles.every(isAutoloopAttachEvalHarnessFile)) return false;
589
+ const runtimeEntrypoints = new Set(runtimeEntrypointFiles.map(normalizeAutoloopFixPrEvidencePath));
590
+ return !implementationFiles.some(
591
+ (file) => runtimeEntrypoints.has(normalizeAutoloopFixPrEvidencePath(file))
592
+ );
593
+ }
594
+ function normalizeAutoloopFixPrEvidencePath(file) {
595
+ return file.replace(/\\/g, "/").replace(/^\.\//, "").trim();
596
+ }
597
+ function autoloopFixPrEvidenceString(value) {
598
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
599
+ }
600
+ function autoloopFixPrEvidenceBoolean(value) {
601
+ return typeof value === "boolean" ? value : null;
602
+ }
603
+ function autoloopFixPrEvidenceNumber(value) {
604
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
605
+ }
606
+ function autoloopFixPrEvidenceSha(value) {
607
+ if (!value) return null;
608
+ return /^[a-f0-9]{6,40}$/i.test(value) ? value : null;
609
+ }
610
+ function isAutoloopFixPrEvidenceRecord(value) {
611
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
612
+ }
613
+
614
+ // ../packages/node-auth/src/constants.ts
615
+ var CREDENTIALS_FILE = "credentials.json";
616
+ var CREDENTIALS_KEY_FILE = "credentials.key";
617
+ var AUTH_TOKEN_ENV_VAR = "ARCHAL_TOKEN";
618
+ var TOKEN_ENCRYPTION_PREFIX = "enc-v1";
619
+ var CREDENTIALS_MASTER_KEY_ENV_VAR = "ARCHAL_CREDENTIALS_MASTER_KEY";
620
+ var KEYCHAIN_SERVICE = "archal-cli";
621
+ var KEYCHAIN_ACCOUNT = "credentials-master-key";
622
+ var ENV_TOKEN_FALLBACK_TTL_SECONDS = 24 * 60 * 60;
623
+
624
+ // ../packages/node-auth/src/types.ts
625
+ function isPlan(value) {
626
+ return value === "free" || value === "pro" || value === "enterprise";
627
+ }
628
+
629
+ // ../packages/node-auth/src/errors.ts
630
+ var ExpiredEnvTokenError = class extends Error {
631
+ constructor(envVar = AUTH_TOKEN_ENV_VAR) {
632
+ super(`${envVar} is expired. Remove it or replace it with a valid token.`);
633
+ this.name = "ExpiredEnvTokenError";
634
+ Object.setPrototypeOf(this, new.target.prototype);
635
+ }
636
+ };
637
+ function errorMessage(error) {
638
+ return error instanceof Error ? error.message : String(error);
639
+ }
640
+
641
+ // ../packages/node-auth/src/credential-store.ts
642
+ var import_node_child_process = require("child_process");
643
+ var import_node_crypto = require("crypto");
644
+ var import_node_fs = require("fs");
645
+ var import_node_os = require("os");
646
+ var import_node_path2 = require("path");
647
+
648
+ // ../packages/clone-catalog/src/generated-catalog.ts
649
+ var GENERATED_CLONE_CATALOG = [
650
+ {
651
+ id: "apify",
652
+ icon: "AP",
653
+ name: "Apify",
654
+ description: "Actors, runs, datasets, key-value stores, and request queues.",
655
+ stage: "preview",
656
+ toolCount: 59,
657
+ transport: "rest",
658
+ architectureClass: "domain-simulator",
659
+ domainPrimitives: [
660
+ "Apify upstream error and pagination envelopes",
661
+ "dataset, key-value store, and request-queue stateful projections",
662
+ "fixture-backed fallback semantics for uncovered REST paths"
663
+ ],
664
+ behaviorOwner: "src/upstream.ts",
665
+ opsCoverage: null
666
+ },
667
+ {
668
+ id: "calcom",
669
+ icon: "CC",
670
+ name: "Cal.com",
671
+ description: "Event types, schedules, availability slots, bookings, calendars, and webhooks.",
672
+ stage: "preview",
673
+ toolCount: 18,
674
+ transport: "both",
675
+ architectureClass: "domain-simulator",
676
+ domainPrimitives: [
677
+ "schedule and event-type availability projection",
678
+ "booking create, cancel, and reschedule lifecycle",
679
+ "host-wide busy interval and slot computation",
680
+ "webhook summary/detail lifecycle projection"
681
+ ],
682
+ behaviorOwner: "src/state/relationships.ts",
683
+ opsCoverage: null
684
+ },
685
+ {
686
+ id: "clickup",
687
+ icon: "CU",
688
+ name: "ClickUp",
689
+ description: "Teams, spaces, folders, lists, tasks, comments, tags, time tracking, and checklists.",
690
+ stage: "preview",
691
+ toolCount: 40,
692
+ transport: "both",
693
+ architectureClass: "standard-core",
694
+ domainPrimitives: [],
695
+ behaviorOwner: null,
696
+ opsCoverage: null
697
+ },
698
+ {
699
+ id: "customerio",
700
+ icon: "CI",
701
+ name: "Customer.io",
702
+ description: "Messaging automation across campaigns, broadcasts, transactional email, segments, customers, and message delivery.",
703
+ stage: "preview",
704
+ toolCount: 22,
705
+ transport: "rest",
706
+ architectureClass: "standard-core",
707
+ domainPrimitives: [],
708
+ behaviorOwner: null,
709
+ opsCoverage: null
710
+ },
711
+ {
712
+ id: "datadog",
713
+ icon: "DD",
714
+ name: "Datadog",
715
+ description: "Observability REST API \u2014 metrics, logs, monitors, dashboards, SLOs, incidents, teams, users, and service definitions.",
716
+ stage: "preview",
717
+ toolCount: 63,
718
+ transport: "rest",
719
+ architectureClass: "domain-simulator",
720
+ domainPrimitives: [
721
+ "time-series query windows",
722
+ "log query filtering",
723
+ "monitor evaluation and alert state"
724
+ ],
725
+ behaviorOwner: "src/domain/simulator.ts",
726
+ opsCoverage: null
727
+ },
728
+ {
729
+ id: "discord",
730
+ icon: "DC",
731
+ name: "Discord",
732
+ description: "Guilds, channels, messages, webhooks, threads, commands, and interaction responses.",
733
+ stage: "preview",
734
+ toolCount: 67,
735
+ transport: "both",
736
+ architectureClass: "domain-simulator",
737
+ domainPrimitives: [
738
+ "channel membership",
739
+ "message timeline ordering",
740
+ "thread and event delivery semantics"
741
+ ],
742
+ behaviorOwner: "src/domain/discord-simulator.ts",
743
+ opsCoverage: 14
744
+ },
745
+ {
746
+ id: "github",
747
+ icon: "GH",
748
+ name: "GitHub",
749
+ description: "Repos, issues, pull requests, branches, and commits.",
750
+ stage: "public",
751
+ toolCount: 26,
752
+ transport: "both",
753
+ architectureClass: "domain-simulator",
754
+ domainPrimitives: [
755
+ "repository branch, commit, tree, and diff projection",
756
+ "issue and pull-request lifecycle projection",
757
+ "review, comment, and status/check aggregation",
758
+ "permission-scoped reads and webhook event delivery"
759
+ ],
760
+ behaviorOwner: "src/state/transition-rules.ts",
761
+ opsCoverage: 96
762
+ },
763
+ {
764
+ id: "gitlab",
765
+ icon: "GL",
766
+ name: "GitLab",
767
+ description: "Projects, branches, commits, issues, merge requests, pipelines, labels, milestones, releases, and webhooks.",
768
+ stage: "preview",
769
+ toolCount: 46,
770
+ transport: "both",
771
+ architectureClass: "domain-simulator",
772
+ domainPrimitives: [
773
+ "issue and merge-request state transitions",
774
+ "note/comment ordering and count projection",
775
+ "repository branch, commit, merge, and diff projection",
776
+ "GitLab webhook subscription, payload, and header emission"
777
+ ],
778
+ behaviorOwner: "src/state/webhook-delivery-config.ts",
779
+ opsCoverage: null
780
+ },
781
+ {
782
+ id: "google-workspace",
783
+ icon: "GW",
784
+ name: "Google Workspace",
785
+ description: "Gmail, Calendar, Drive, Sheets, and Contacts.",
786
+ stage: "preview",
787
+ toolCount: 249,
788
+ transport: "both",
789
+ architectureClass: "domain-simulator",
790
+ domainPrimitives: [
791
+ "Gmail thread/history engine",
792
+ "Drive changes and permissions",
793
+ "Calendar recurrence and watch sync"
794
+ ],
795
+ behaviorOwner: "src/domain/google-workspace-simulator.ts",
796
+ opsCoverage: 64
797
+ },
798
+ {
799
+ id: "hubspot",
800
+ icon: "HS",
801
+ name: "HubSpot",
802
+ description: "CRM contacts, companies, deals, tickets, and engagements.",
803
+ stage: "preview",
804
+ toolCount: 41,
805
+ transport: "rest",
806
+ architectureClass: "replay-shell",
807
+ domainPrimitives: [
808
+ "CRM object state and associations",
809
+ "Pipeline and property schema state",
810
+ "Recording-backed REST/MCP aliases awaiting stateful lift"
811
+ ],
812
+ behaviorOwner: null,
813
+ opsCoverage: 99
814
+ },
815
+ {
816
+ id: "jira",
817
+ icon: "JR",
818
+ name: "Jira",
819
+ description: "Issues, projects, boards, sprints, and versions.",
820
+ stage: "preview",
821
+ toolCount: 49,
822
+ transport: "both",
823
+ architectureClass: "domain-simulator",
824
+ domainPrimitives: [
825
+ "issue workflow transitions and mutation history",
826
+ "JQL/search and issue field projection",
827
+ "sprint, board, version, and SLA time-based transitions",
828
+ "permission-scoped reads and Jira webhook event delivery"
829
+ ],
830
+ behaviorOwner: "src/state/transition-rules.ts",
831
+ opsCoverage: 80
832
+ },
833
+ {
834
+ id: "linear",
835
+ icon: "LN",
836
+ name: "Linear",
837
+ description: "Issues, projects, teams, cycles, and workflows.",
838
+ stage: "public",
839
+ toolCount: 50,
840
+ transport: "both",
841
+ architectureClass: "domain-simulator",
842
+ domainPrimitives: [
843
+ "GraphQL operation dispatch",
844
+ "issue workflow transitions",
845
+ "comment and history projection",
846
+ "cycle and project progress projection"
847
+ ],
848
+ behaviorOwner: "src/rest/graphql-dispatch.ts",
849
+ opsCoverage: 98
850
+ },
851
+ {
852
+ id: "ownerrez",
853
+ icon: "OR",
854
+ name: "OwnerRez",
855
+ description: "Vacation-rental PMS \u2014 properties, bookings, guests, quotes, financial reads, tags, fields, and webhook subscriptions.",
856
+ stage: "preview",
857
+ toolCount: 25,
858
+ transport: "rest",
859
+ architectureClass: "replay-shell",
860
+ domainPrimitives: [
861
+ "recording replay cursor",
862
+ "tag and guest stateful overlays",
863
+ "booking/payment read projections"
864
+ ],
865
+ behaviorOwner: null,
866
+ opsCoverage: 100
867
+ },
868
+ {
869
+ id: "pricelabs",
870
+ icon: "PL",
871
+ name: "PriceLabs",
872
+ description: "Dynamic pricing \u2014 listings, overrides, neighborhood data, rate plans, and reservations.",
873
+ stage: "preview",
874
+ toolCount: 11,
875
+ transport: "rest",
876
+ architectureClass: "replay-shell",
877
+ domainPrimitives: [
878
+ "recording replay cursor",
879
+ "listing settings overlay",
880
+ "pricing and reservation projections"
881
+ ],
882
+ behaviorOwner: null,
883
+ opsCoverage: 100
884
+ },
885
+ {
886
+ id: "ramp",
887
+ icon: "RP",
888
+ name: "Ramp",
889
+ description: "Cards, funds, expenses, reimbursements, bills, and travel.",
890
+ stage: "preview",
891
+ toolCount: 46,
892
+ transport: "mcp",
893
+ architectureClass: "replay-shell",
894
+ domainPrimitives: [
895
+ "checked-in Ramp CLI fixture corpus",
896
+ "CLI-native command routing",
897
+ "seeded approval and comment overlays"
898
+ ],
899
+ behaviorOwner: null,
900
+ opsCoverage: null
901
+ },
902
+ {
903
+ id: "sentry",
904
+ icon: "SN",
905
+ name: "Sentry",
906
+ description: "Error monitoring across organizations, projects, teams, issues, events, releases, and DSN keys.",
907
+ stage: "preview",
908
+ toolCount: 25,
909
+ transport: "rest",
910
+ architectureClass: "domain-simulator",
911
+ domainPrimitives: [
912
+ "event grouping",
913
+ "issue state transitions",
914
+ "release and time-window projections"
915
+ ],
916
+ behaviorOwner: "src/domain/sentry-simulator.ts",
917
+ opsCoverage: null
918
+ },
919
+ {
920
+ id: "slack",
921
+ icon: "SL",
922
+ name: "Slack",
923
+ description: "Channels, messages, threads, users, and reactions.",
924
+ stage: "public",
925
+ toolCount: 9,
926
+ transport: "both",
927
+ architectureClass: "domain-simulator",
928
+ domainPrimitives: [
929
+ "channel membership and visibility",
930
+ "message/thread ordering",
931
+ "event delivery semantics"
932
+ ],
933
+ behaviorOwner: "src/domain/slack-simulator.ts",
934
+ opsCoverage: 100
935
+ },
936
+ {
937
+ id: "stripe",
938
+ icon: "ST",
939
+ name: "Stripe",
940
+ description: "Customers, payments, subscriptions, invoices, and refunds.",
941
+ stage: "preview",
942
+ toolCount: 28,
943
+ transport: "both",
944
+ architectureClass: "domain-simulator",
945
+ domainPrimitives: [
946
+ "payment object lifecycle",
947
+ "balance and ledger projection",
948
+ "webhook/idempotency semantics"
949
+ ],
950
+ behaviorOwner: "src/domain/stripe-simulator.ts",
951
+ opsCoverage: null
952
+ },
953
+ {
954
+ id: "supabase",
955
+ icon: "SB",
956
+ name: "Supabase",
957
+ description: "SQL, migrations, logs, branches, and project metadata.",
958
+ stage: "public",
959
+ toolCount: 29,
960
+ transport: "both",
961
+ architectureClass: "domain-simulator",
962
+ domainPrimitives: [
963
+ "Postgres schema and SQL execution",
964
+ "RLS and API projections",
965
+ "realtime row changes"
966
+ ],
967
+ behaviorOwner: "src/pg-engine.ts",
968
+ opsCoverage: 100
969
+ },
970
+ {
971
+ id: "tavily",
972
+ icon: "TV",
973
+ name: "Tavily",
974
+ description: "Search, extract, crawl, map, research, usage, and API key operations.",
975
+ stage: "preview",
976
+ toolCount: 11,
977
+ transport: "rest",
978
+ architectureClass: "replay-shell",
979
+ domainPrimitives: [
980
+ "recording-backed REST/tool response replay",
981
+ "deterministic search/extract response helpers",
982
+ "research request state overlay"
983
+ ],
984
+ behaviorOwner: null,
985
+ opsCoverage: 100
986
+ },
987
+ {
988
+ id: "unipile",
989
+ icon: "UP",
990
+ name: "Unipile",
991
+ description: "LinkedIn and email messaging, accounts, and chats.",
992
+ stage: "preview",
993
+ toolCount: 31,
994
+ transport: "rest",
995
+ architectureClass: "replay-shell",
996
+ domainPrimitives: [
997
+ "authenticated account and chat reads",
998
+ "single WhatsApp send mutation",
999
+ "future account, chat, and webhook simulator"
1000
+ ],
1001
+ behaviorOwner: null,
1002
+ opsCoverage: 100
1003
+ },
1004
+ {
1005
+ id: "webflow",
1006
+ icon: "WF",
1007
+ name: "Webflow",
1008
+ description: "Sites, pages, CMS collections, items, assets, forms, and webhooks.",
1009
+ stage: "preview",
1010
+ toolCount: 19,
1011
+ transport: "rest",
1012
+ architectureClass: "replay-shell",
1013
+ domainPrimitives: [
1014
+ "recording replay cursor",
1015
+ "CMS collection/item overlays",
1016
+ "publish lifecycle captures"
1017
+ ],
1018
+ behaviorOwner: null,
1019
+ opsCoverage: 100
1020
+ }
1021
+ ];
1022
+ var GENERATED_STARTABLE_CLONE_IDS = [
1023
+ "apify",
1024
+ "calcom",
1025
+ "clickup",
1026
+ "customerio",
1027
+ "datadog",
1028
+ "discord",
1029
+ "github",
1030
+ "gitlab",
1031
+ "google-workspace",
1032
+ "hubspot",
1033
+ "jira",
1034
+ "linear",
1035
+ "ownerrez",
1036
+ "pricelabs",
1037
+ "ramp",
1038
+ "sentry",
1039
+ "slack",
1040
+ "stripe",
1041
+ "supabase",
1042
+ "tavily",
1043
+ "unipile",
1044
+ "webflow"
1045
+ ];
1046
+
1047
+ // ../clones/core/src/clone-architecture-values.mjs
1048
+ var CLONE_ARCHITECTURE_CLASSES = [
1049
+ "standard-core",
1050
+ "domain-simulator",
1051
+ "replay-shell",
1052
+ "redesign-before-expansion"
1053
+ ];
1054
+ var CLONE_ARCHITECTURE_PREVIEW_CLASSES = [
1055
+ "replay-shell",
1056
+ "redesign-before-expansion"
1057
+ ];
1058
+ var CLONE_ARCHITECTURE_CLASS_SET = new Set(CLONE_ARCHITECTURE_CLASSES);
1059
+ var CLONE_ARCHITECTURE_PREVIEW_CLASS_SET = new Set(CLONE_ARCHITECTURE_PREVIEW_CLASSES);
1060
+
1061
+ // ../clones/core/src/clone-architecture-field-policy.mjs
1062
+ var FIELD_POLICY = {
1063
+ behaviorOwner: {
1064
+ required: /* @__PURE__ */ new Set(["domain-simulator"]),
1065
+ allowed: /* @__PURE__ */ new Set(["domain-simulator"])
1066
+ },
1067
+ domainPrimitives: {
1068
+ required: /* @__PURE__ */ new Set(["domain-simulator", "replay-shell", "redesign-before-expansion"]),
1069
+ allowed: /* @__PURE__ */ new Set(["domain-simulator", "replay-shell", "redesign-before-expansion"])
1070
+ },
1071
+ promotionEvidence: {
1072
+ required: /* @__PURE__ */ new Set(["replay-shell"]),
1073
+ allowed: /* @__PURE__ */ new Set(["replay-shell"])
1074
+ },
1075
+ redesignContract: {
1076
+ required: /* @__PURE__ */ new Set(["redesign-before-expansion"]),
1077
+ allowed: /* @__PURE__ */ new Set(["redesign-before-expansion"])
1078
+ }
1079
+ };
1080
+ var CLONE_ARCHITECTURE_POLICY_FIELDS = Object.freeze(Object.keys(FIELD_POLICY));
1081
+ var CLONE_ARCHITECTURE_MANIFEST_FIELDS = Object.freeze([
1082
+ "class",
1083
+ "summary",
1084
+ ...CLONE_ARCHITECTURE_POLICY_FIELDS
1085
+ ]);
1086
+ var CLONE_ARCHITECTURE_MANIFEST_FIELD_SET = new Set(CLONE_ARCHITECTURE_MANIFEST_FIELDS);
1087
+
1088
+ // ../clones/core/src/clone-runtime-source-files.mjs
1089
+ var import_node_path = require("path");
1090
+ var CLONE_RUNTIME_SOURCE_EXTENSIONS = Object.freeze([
1091
+ ".cjs",
1092
+ ".cts",
1093
+ ".js",
1094
+ ".jsx",
1095
+ ".mjs",
1096
+ ".mts",
1097
+ ".ts",
1098
+ ".tsx"
1099
+ ]);
1100
+ var RUNTIME_SOURCE_EXTENSIONS = new Set(CLONE_RUNTIME_SOURCE_EXTENSIONS);
1101
+
1102
+ // ../clones/core/src/clone-launch-metadata-values.mjs
1103
+ var CLONE_STAGES = ["wip", "internal", "preview", "public", "retired"];
1104
+ var CLONE_TRANSPORTS = ["mcp", "rest", "both"];
1105
+ var CLONE_SMOKE_PROFILES = ["none", "health-and-seed", "clone-surface"];
1106
+ var STARTABLE_CLONE_STAGES = ["public", "preview"];
1107
+ var CATALOG_VISIBLE_CLONE_STAGES = ["public", "preview"];
1108
+ var CLONE_STAGE_SET = new Set(CLONE_STAGES);
1109
+ var CLONE_TRANSPORT_SET = new Set(CLONE_TRANSPORTS);
1110
+ var CLONE_SMOKE_PROFILE_SET = new Set(CLONE_SMOKE_PROFILES);
1111
+ var STARTABLE_CLONE_STAGE_SET = new Set(STARTABLE_CLONE_STAGES);
1112
+ var CATALOG_VISIBLE_CLONE_STAGE_SET = new Set(CATALOG_VISIBLE_CLONE_STAGES);
1113
+
1114
+ // ../packages/clone-catalog/src/index.ts
1115
+ var CLONE_CATALOG = GENERATED_CLONE_CATALOG;
1116
+ var ALL_CLONE_IDS = CLONE_CATALOG.map((entry) => entry.id);
1117
+ var ALL_STARTABLE_CLONE_IDS = [...GENERATED_STARTABLE_CLONE_IDS];
1118
+ var CLONE_ID_SET = new Set(ALL_CLONE_IDS);
1119
+ var STARTABLE_CLONE_ID_SET = new Set(ALL_STARTABLE_CLONE_IDS);
1120
+ var STARTABLE_CLONE_CATALOG = CLONE_CATALOG.filter(
1121
+ (entry) => STARTABLE_CLONE_ID_SET.has(entry.id)
1122
+ );
1123
+
1124
+ // ../packages/billing-constants/src/credit-catalog.ts
1125
+ var CREDIT_COGS_MARKUP = 3;
1126
+ var CREDIT_TARGET_GROSS_MARGIN_PERCENT = Math.round(
1127
+ (1 - 1 / CREDIT_COGS_MARKUP) * 100
1128
+ );
1129
+
1130
+ // ../packages/billing-constants/src/index.ts
1131
+ var PLAN_MONTHLY_TWIN_MINUTE_LIMITS = {
1132
+ free: 500,
1133
+ pro: 5e3,
1134
+ enterprise: null
1135
+ };
1136
+ var PLAN_CONCURRENT_SESSION_LIMITS = {
1137
+ free: 3,
1138
+ pro: 10,
1139
+ enterprise: 50
1140
+ };
1141
+ var FREE_WORKSPACE_MEMBER_LIMIT = 2;
1142
+ var PRO_PLAN_PRICE_USD = 199;
1143
+ function formatMinutesLabel(minutes) {
1144
+ return minutes.toLocaleString("en-US");
1145
+ }
1146
+ var FREE_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.free;
1147
+ var PRO_MINUTES = PLAN_MONTHLY_TWIN_MINUTE_LIMITS.pro;
1148
+ if (FREE_MINUTES == null || PRO_MINUTES == null) {
1149
+ throw new Error("PLAN_MONTHLY_TWIN_MINUTE_LIMITS: free and pro must be non-null");
1150
+ }
1151
+ var PRO_EVALS_PER_SEAT = 500;
1152
+ var PRO_SESSION_MINUTES_PER_SEAT = 5e3;
1153
+ var PRO_MAX_SEATS = 5;
1154
+ var FREE_EVALS_PER_MONTH = 100;
1155
+ var PLAN_DISPLAY = {
1156
+ free: {
1157
+ tag: "Free",
1158
+ priceLabel: "$0",
1159
+ periodLabel: "",
1160
+ included: [
1161
+ `${formatMinutesLabel(FREE_MINUTES)} session-minutes / account`,
1162
+ `${FREE_EVALS_PER_MONTH} evals / account`,
1163
+ `1 workspace (${FREE_WORKSPACE_MEMBER_LIMIT} users max)`,
1164
+ `${PLAN_CONCURRENT_SESSION_LIMITS.free} concurrent sessions / workspace`,
1165
+ "All clones included"
1166
+ ]
1167
+ },
1168
+ pro: {
1169
+ tag: "Pro",
1170
+ priceLabel: `$${PRO_PLAN_PRICE_USD}`,
1171
+ periodLabel: "/mo per seat",
1172
+ included: [
1173
+ `${formatMinutesLabel(PRO_SESSION_MINUTES_PER_SEAT)} session-minutes / seat / month`,
1174
+ `${PRO_EVALS_PER_SEAT} evals / seat / month`,
1175
+ "All clones included",
1176
+ `${PLAN_CONCURRENT_SESSION_LIMITS.pro} concurrent sessions / workspace`,
1177
+ `1 workspace, up to ${PRO_MAX_SEATS} seats with pooled usage`
1178
+ ]
1179
+ },
1180
+ enterprise: {
1181
+ tag: "Enterprise",
1182
+ priceLabel: "Contact us",
1183
+ periodLabel: "",
1184
+ included: [
1185
+ "Unlimited session-minutes",
1186
+ "Unlimited seats per workspace",
1187
+ "Unlimited workspaces",
1188
+ `${PLAN_CONCURRENT_SESSION_LIMITS.enterprise} concurrent sessions / workspace`,
1189
+ "SSO / SAML",
1190
+ "SOC 2 (in progress)",
1191
+ "Custom clones & eval support",
1192
+ "Dedicated onboarding & support"
1193
+ ]
1194
+ }
1195
+ };
1196
+ var PLAN_MAX_SESSION_TTL_SECONDS = {
1197
+ free: 30 * 60,
1198
+ // 30 minutes
1199
+ pro: 60 * 60,
1200
+ // 60 minutes
1201
+ enterprise: 90 * 60
1202
+ // 90 minutes
1203
+ };
1204
+ var MAX_ABSOLUTE_SESSION_LIFETIME_SECONDS = 4 * 60 * 60;
1205
+ var LIFETIME_PERIOD_RESETS_AT = new Date(Date.UTC(9999, 11, 31));
1206
+ var ALL_ENTITLED_CLONES = ALL_STARTABLE_CLONE_IDS;
1207
+ var SCENARIO_USAGE_WINDOW_DAYS = 7;
1208
+ var SCENARIO_USAGE_WINDOW_MS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
1209
+ var SCENARIO_USAGE_WINDOW_SECONDS = SCENARIO_USAGE_WINDOW_DAYS * 24 * 60 * 60;
1210
+ var LLM_PRICING_USD_PER_M_TOKENS = {
1211
+ // Google Gemini (verified 2026-05-05, standard tier <=200K input tokens)
1212
+ "gemini-2.5-pro": { input: 1.25, output: 10 },
1213
+ "gemini-2.5-flash": { input: 0.3, output: 2.5 },
1214
+ // OpenAI flagship text models (verified 2026-05-21, standard short-context tier)
1215
+ "gpt-5.5": { input: 5, output: 30 },
1216
+ "gpt-5.5-pro": { input: 30, output: 180 },
1217
+ "gpt-5.4": { input: 2.5, output: 15 },
1218
+ "gpt-5.4-mini": { input: 0.75, output: 4.5 },
1219
+ "gpt-5.4-nano": { input: 0.2, output: 1.25 },
1220
+ "gpt-5.4-pro": { input: 30, output: 180 },
1221
+ "gpt-4o-mini": { input: 0.15, output: 0.6 },
1222
+ "gpt-4o": { input: 2.5, output: 10 },
1223
+ "gpt-4.1-mini": { input: 0.4, output: 1.6 },
1224
+ "gpt-4.1-nano": { input: 0.1, output: 0.4 },
1225
+ "gpt-4.1": { input: 2, output: 8 },
1226
+ // DeepSeek (verified 2026-05-05; legacy names map to v4-flash per vendor)
1227
+ "deepseek-chat": { input: 0.14, output: 0.28 },
1228
+ "deepseek-reasoner": { input: 0.14, output: 0.28 },
1229
+ "deepseek-v4-flash": { input: 0.14, output: 0.28 }
1230
+ };
1231
+ var LLM_PRICING_FAMILY_RATES = [
1232
+ { match: /^gemini-2\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-pro"] },
1233
+ { match: /^gemini-2\.5-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gemini-2.5-flash"] },
1234
+ { match: /^gpt-5\.5-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5-pro"] },
1235
+ { match: /^gpt-5\.5/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.5"] },
1236
+ { match: /^gpt-5\.4-pro/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-pro"] },
1237
+ { match: /^gpt-5\.4-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-mini"] },
1238
+ { match: /^gpt-5\.4-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4-nano"] },
1239
+ { match: /^gpt-5\.4/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-5.4"] },
1240
+ { match: /^gpt-4o-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o-mini"] },
1241
+ { match: /^gpt-4o(?!-mini)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4o"] },
1242
+ { match: /^gpt-4\.1-mini/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-mini"] },
1243
+ { match: /^gpt-4\.1-nano/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1-nano"] },
1244
+ { match: /^gpt-4\.1(?!-mini|-nano)/i, rate: LLM_PRICING_USD_PER_M_TOKENS["gpt-4.1"] },
1245
+ // Anthropic Claude 4.x list prices (verified 2026): Opus $5/$25, Sonnet
1246
+ // $3/$15, Haiku 4.5 $1/$5 per 1M tokens (input/output).
1247
+ { match: /^claude-opus-/i, rate: { input: 5, output: 25 } },
1248
+ { match: /^claude-haiku-/i, rate: { input: 1, output: 5 } },
1249
+ { match: /^claude-sonnet-/i, rate: { input: 3, output: 15 } },
1250
+ { match: /^opus-/i, rate: { input: 5, output: 25 } },
1251
+ { match: /^haiku-/i, rate: { input: 1, output: 5 } },
1252
+ { match: /^sonnet-/i, rate: { input: 3, output: 15 } },
1253
+ { match: /^deepseek-chat/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-chat"] },
1254
+ { match: /^deepseek-reasoner/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-reasoner"] },
1255
+ { match: /^deepseek-v4-flash/i, rate: LLM_PRICING_USD_PER_M_TOKENS["deepseek-v4-flash"] }
1256
+ ];
1257
+
1258
+ // ../packages/node-auth/src/clone-entitlements.ts
1259
+ var ENTITLED_CLONE_SET = new Set(ALL_ENTITLED_CLONES);
1260
+ function normalizeEntitledCloneIds(cloneIds) {
1261
+ if (!cloneIds) {
1262
+ return [];
1263
+ }
1264
+ const normalized = /* @__PURE__ */ new Set();
1265
+ for (const cloneId of cloneIds) {
1266
+ if (typeof cloneId !== "string") {
1267
+ continue;
1268
+ }
1269
+ const trimmed = cloneId.trim();
1270
+ if (ENTITLED_CLONE_SET.has(trimmed)) {
1271
+ normalized.add(trimmed);
1272
+ }
1273
+ }
1274
+ return [...normalized];
1275
+ }
1276
+
1277
+ // ../packages/node-auth/src/credential-store.ts
1278
+ var KEYCHAIN_COMMAND_TIMEOUT_MS = 1500;
1279
+ var ARCHAL_DIR_NAME = ".archal";
1280
+ var TEST_SANDBOX_ID_ENV_VAR = "ARCHAL_TEST_SANDBOX_ID";
1281
+ var VITEST_CONFIG_ENV_VAR = "ARCHAL_VITEST_CONFIG";
1282
+ function debug(message) {
1283
+ if (process.env["ARCHAL_DEBUG"] !== "1") {
1284
+ return;
1285
+ }
1286
+ process.stderr.write(`[archal-node-auth] ${message}
1287
+ `);
1288
+ }
1289
+ function getWarn(options) {
1290
+ return options?.warn ?? console.warn;
1291
+ }
1292
+ function isExpired(expiresAt) {
1293
+ return expiresAt <= Math.floor(Date.now() / 1e3);
1294
+ }
1295
+ function isRunningUnderTests() {
1296
+ return process.env["VITEST"] === "true" || process.env["VITEST_WORKER_ID"] !== void 0 || process.env["JEST_WORKER_ID"] !== void 0 || process.env["NODE_TEST_CONTEXT"] !== void 0;
1297
+ }
1298
+ function getRealArchalDir() {
1299
+ return (0, import_node_path2.join)((0, import_node_os.homedir)(), ARCHAL_DIR_NAME);
1300
+ }
1301
+ function normalizeSandboxId(raw) {
1302
+ const trimmed = raw.trim();
1303
+ if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(trimmed)) {
1304
+ return trimmed;
1305
+ }
1306
+ return (0, import_node_crypto.createHash)("sha256").update(trimmed).digest("hex").slice(0, 16);
1307
+ }
1308
+ function getTestSandboxDir() {
1309
+ const sharedSandboxId = process.env[VITEST_CONFIG_ENV_VAR]?.trim() || process.env[TEST_SANDBOX_ID_ENV_VAR]?.trim();
1310
+ if (sharedSandboxId) {
1311
+ return (0, import_node_path2.join)((0, import_node_os.tmpdir)(), `archal-test-sandbox-${normalizeSandboxId(sharedSandboxId)}`);
1312
+ }
1313
+ const workerId = process.env["VITEST_WORKER_ID"] ?? process.env["JEST_WORKER_ID"] ?? String(process.pid);
1314
+ return (0, import_node_path2.join)((0, import_node_os.tmpdir)(), `archal-test-sandbox-${workerId}-${process.pid}`);
1315
+ }
1316
+ function getArchalDir() {
1317
+ const explicit = process.env["ARCHAL_HOME"];
1318
+ if (explicit) {
1319
+ return explicit;
1320
+ }
1321
+ if (isRunningUnderTests()) {
1322
+ return getTestSandboxDir();
1323
+ }
1324
+ return getRealArchalDir();
1325
+ }
1326
+ function getCredentialsPath() {
1327
+ return (0, import_node_path2.join)(getArchalDir(), CREDENTIALS_FILE);
1328
+ }
1329
+ function ensureDir(dir) {
1330
+ if (!(0, import_node_fs.existsSync)(dir)) {
1331
+ (0, import_node_fs.mkdirSync)(dir, { recursive: true });
1332
+ debug(`Created archal directory at ${dir}`);
1333
+ }
1334
+ return dir;
1335
+ }
1336
+ function getCredentialsKeyPathForDir(dir) {
1337
+ return (0, import_node_path2.join)(dir, CREDENTIALS_KEY_FILE);
1338
+ }
1339
+ function readCredentialsKeyFromEnv() {
1340
+ const raw = process.env[CREDENTIALS_MASTER_KEY_ENV_VAR]?.trim();
1341
+ if (!raw) {
1342
+ return null;
1343
+ }
1344
+ if (/^[a-fA-F0-9]{64}$/.test(raw)) {
1345
+ return Buffer.from(raw, "hex");
1346
+ }
1347
+ try {
1348
+ const decoded = Buffer.from(raw, "base64");
1349
+ if (decoded.length === 32) {
1350
+ return decoded;
1351
+ }
1352
+ } catch (err) {
1353
+ debug(`Base64 master key decode failed: ${errorMessage(err)}`);
1354
+ }
1355
+ return (0, import_node_crypto.createHash)("sha256").update(raw, "utf8").digest();
1356
+ }
1357
+ function readCredentialsKeyFromMacKeychain() {
1358
+ if (process.platform !== "darwin") return null;
1359
+ try {
1360
+ const result = (0, import_node_child_process.spawnSync)(
1361
+ "security",
1362
+ ["find-generic-password", "-s", KEYCHAIN_SERVICE, "-a", KEYCHAIN_ACCOUNT, "-w"],
1363
+ { encoding: "utf-8", timeout: KEYCHAIN_COMMAND_TIMEOUT_MS }
1364
+ );
1365
+ if (!result || result.error || result.status !== 0 || typeof result.stdout !== "string" || result.stdout.length === 0) {
1366
+ if (result?.error) {
1367
+ debug(`Keychain lookup failed: ${result.error.message}`);
1368
+ }
1369
+ return null;
1370
+ }
1371
+ const raw = result.stdout.trim();
1372
+ if (!/^[a-fA-F0-9]{64}$/.test(raw)) {
1373
+ return null;
1374
+ }
1375
+ return Buffer.from(raw, "hex");
1376
+ } catch (err) {
1377
+ debug(`Keychain lookup threw: ${errorMessage(err)}`);
1378
+ return null;
1379
+ }
1380
+ }
1381
+ function readCredentialsKeyFromFile(dir = getArchalDir()) {
1382
+ const keyPath = getCredentialsKeyPathForDir(dir);
1383
+ if (!(0, import_node_fs.existsSync)(keyPath)) {
1384
+ return null;
1385
+ }
1386
+ try {
1387
+ const raw = (0, import_node_fs.readFileSync)(keyPath, "utf-8").trim();
1388
+ const key = Buffer.from(raw, "hex");
1389
+ if (key.length === 32) {
1390
+ return key;
1391
+ }
1392
+ } catch (err) {
1393
+ debug(`Failed to read credentials key file: ${errorMessage(err)}`);
1394
+ }
1395
+ return null;
1396
+ }
1397
+ function collectCredentialKeysForDecrypt(dir = getArchalDir()) {
1398
+ const keys = [];
1399
+ for (const candidate of [
1400
+ readCredentialsKeyFromEnv(),
1401
+ readCredentialsKeyFromMacKeychain(),
1402
+ readCredentialsKeyFromFile(dir)
1403
+ ]) {
1404
+ if (!candidate) continue;
1405
+ if (!keys.some((entry) => entry.equals(candidate))) {
1406
+ keys.push(candidate);
1407
+ }
1408
+ }
1409
+ return keys;
1410
+ }
1411
+ function writeCredentialsKeyToMacKeychain(key) {
1412
+ if (process.platform !== "darwin") return false;
1413
+ try {
1414
+ const result = (0, import_node_child_process.spawnSync)(
1415
+ "security",
1416
+ [
1417
+ "add-generic-password",
1418
+ "-U",
1419
+ "-s",
1420
+ KEYCHAIN_SERVICE,
1421
+ "-a",
1422
+ KEYCHAIN_ACCOUNT,
1423
+ "-w",
1424
+ key.toString("hex")
1425
+ ],
1426
+ { encoding: "utf-8", timeout: KEYCHAIN_COMMAND_TIMEOUT_MS }
1427
+ );
1428
+ if (result?.error) {
1429
+ debug(`Keychain write failed: ${result.error.message}`);
1430
+ }
1431
+ return !!result && !result.error && result.status === 0;
1432
+ } catch (err) {
1433
+ debug(`Keychain write threw: ${errorMessage(err)}`);
1434
+ return false;
1435
+ }
1436
+ }
1437
+ function getOrCreateCredentialsKey(dir = getArchalDir()) {
1438
+ const envKey = readCredentialsKeyFromEnv();
1439
+ if (envKey) {
1440
+ return envKey;
1441
+ }
1442
+ const keychainKey = readCredentialsKeyFromMacKeychain();
1443
+ if (keychainKey) {
1444
+ return keychainKey;
1445
+ }
1446
+ const fileKey = readCredentialsKeyFromFile(dir);
1447
+ if (fileKey) {
1448
+ if (writeCredentialsKeyToMacKeychain(fileKey)) {
1449
+ try {
1450
+ (0, import_node_fs.unlinkSync)(getCredentialsKeyPathForDir(dir));
1451
+ } catch {
1452
+ }
1453
+ }
1454
+ return fileKey;
1455
+ }
1456
+ const generated = (0, import_node_crypto.randomBytes)(32);
1457
+ if (!writeCredentialsKeyToMacKeychain(generated)) {
1458
+ ensureDir(dir);
1459
+ (0, import_node_fs.writeFileSync)(getCredentialsKeyPathForDir(dir), `${generated.toString("hex")}
1460
+ `, {
1461
+ encoding: "utf-8",
1462
+ mode: 384
1463
+ });
1464
+ }
1465
+ return generated;
1466
+ }
1467
+ function encryptToken(token, dir = getArchalDir()) {
1468
+ const key = getOrCreateCredentialsKey(dir);
1469
+ const iv = (0, import_node_crypto.randomBytes)(12);
1470
+ const cipher = (0, import_node_crypto.createCipheriv)("aes-256-gcm", key, iv);
1471
+ const encrypted = Buffer.concat([cipher.update(token, "utf-8"), cipher.final()]);
1472
+ return `${TOKEN_ENCRYPTION_PREFIX}:${iv.toString("hex")}:${cipher.getAuthTag().toString("hex")}:${encrypted.toString("hex")}`;
1473
+ }
1474
+ function decryptToken(ciphertext, dir = getArchalDir()) {
1475
+ const parts = ciphertext.split(":");
1476
+ if (parts.length !== 4 || parts[0] !== TOKEN_ENCRYPTION_PREFIX) {
1477
+ return null;
1478
+ }
1479
+ const [, ivHex, tagHex, dataHex] = parts;
1480
+ if (!ivHex || !tagHex || !dataHex) {
1481
+ return null;
1482
+ }
1483
+ const iv = Buffer.from(ivHex, "hex");
1484
+ const tag = Buffer.from(tagHex, "hex");
1485
+ const data = Buffer.from(dataHex, "hex");
1486
+ const keys = collectCredentialKeysForDecrypt(dir);
1487
+ for (const key of keys) {
1488
+ try {
1489
+ const decipher = (0, import_node_crypto.createDecipheriv)("aes-256-gcm", key, iv);
1490
+ decipher.setAuthTag(tag);
1491
+ return Buffer.concat([decipher.update(data), decipher.final()]).toString("utf-8");
1492
+ } catch {
1493
+ }
1494
+ }
1495
+ debug("Token decryption failed with all available credential keys.");
1496
+ return null;
1497
+ }
1498
+ function decodeJwtPayload(token) {
1499
+ try {
1500
+ const payloadPart = token.split(".")[1];
1501
+ if (!payloadPart) return null;
1502
+ const normalized = payloadPart.replace(/-/g, "+").replace(/_/g, "/");
1503
+ const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
1504
+ return JSON.parse(Buffer.from(padded, "base64").toString("utf-8"));
1505
+ } catch (err) {
1506
+ debug(`JWT payload decode failed (expected for non-JWT tokens): ${errorMessage(err)}`);
1507
+ return null;
1508
+ }
1509
+ }
1510
+ function hasValidSelectedClones(value) {
1511
+ return value === void 0 || Array.isArray(value) && value.every((twin) => typeof twin === "string");
1512
+ }
1513
+ function resolveStoredToken(parsed, dir = getArchalDir()) {
1514
+ if (typeof parsed.token === "string") {
1515
+ const token = parsed.token.trim();
1516
+ return { token: token.length > 0 ? token : null, source: "legacy" };
1517
+ }
1518
+ if (typeof parsed.accessToken === "string") {
1519
+ const token = parsed.accessToken.trim();
1520
+ return { token: token.length > 0 ? token : null, source: "legacy" };
1521
+ }
1522
+ if (typeof parsed.tokenEncrypted === "string") {
1523
+ const token = decryptToken(parsed.tokenEncrypted, dir)?.trim() || null;
1524
+ return { token: token?.length ? token : null, source: "encrypted" };
1525
+ }
1526
+ return { token: null, source: "legacy" };
1527
+ }
1528
+ function resolveStoredRefreshToken(parsed, dir = getArchalDir()) {
1529
+ if (typeof parsed.refreshTokenEncrypted === "string") {
1530
+ const refreshToken = decryptToken(parsed.refreshTokenEncrypted, dir)?.trim() || null;
1531
+ if (refreshToken !== null) {
1532
+ return { refreshToken, source: "encrypted" };
1533
+ }
1534
+ if (typeof parsed.refreshToken === "string") {
1535
+ return { refreshToken: parsed.refreshToken.trim(), source: "legacy" };
1536
+ }
1537
+ return { refreshToken: null, source: "encrypted" };
1538
+ }
1539
+ if (typeof parsed.refreshToken === "string") {
1540
+ return { refreshToken: parsed.refreshToken.trim(), source: "legacy" };
1541
+ }
1542
+ return { refreshToken: "", source: "none" };
1543
+ }
1544
+ function buildStoredCredentials(parsed, path, warn2, options) {
1545
+ const dir = (0, import_node_path2.dirname)(path);
1546
+ const { token, source: tokenSource } = resolveStoredToken(parsed, dir);
1547
+ const { refreshToken, source: refreshTokenSource } = resolveStoredRefreshToken(parsed, dir);
1548
+ if (token === null || refreshToken === null || parsed.refreshToken !== void 0 && typeof parsed.refreshToken !== "string" || parsed.refreshTokenEncrypted !== void 0 && typeof parsed.refreshTokenEncrypted !== "string" || !hasValidSelectedClones(parsed.selectedCloneIds)) {
1549
+ warn2(
1550
+ `Credentials file at ${path} has missing or invalid fields. Run \`archal login\` to re-authenticate.`
1551
+ );
1552
+ return null;
1553
+ }
1554
+ const { email, plan, expiresAt } = parsed;
1555
+ if (typeof email !== "string" || !isPlan(plan) || typeof expiresAt !== "number") {
1556
+ warn2(
1557
+ `Credentials file at ${path} has missing or invalid fields. Run \`archal login\` to re-authenticate.`
1558
+ );
1559
+ return null;
1560
+ }
1561
+ const creds = {
1562
+ token,
1563
+ refreshToken,
1564
+ email,
1565
+ plan,
1566
+ selectedCloneIds: normalizeEntitledCloneIds(parsed.selectedCloneIds),
1567
+ expiresAt
1568
+ };
1569
+ if (options?.migrateLegacyCredentials && (tokenSource === "legacy" || refreshTokenSource === "legacy")) {
1570
+ try {
1571
+ writeCredentialsAtPath(path, creds);
1572
+ } catch (err) {
1573
+ debug(`Credential migration failed: ${errorMessage(err)}`);
1574
+ }
1575
+ }
1576
+ return creds;
1577
+ }
1578
+ function readCredentialsFileAtPath(path, options) {
1579
+ if (!(0, import_node_fs.existsSync)(path)) {
1580
+ return null;
1581
+ }
1582
+ try {
1583
+ const warn2 = getWarn(options);
1584
+ const parsed = JSON.parse((0, import_node_fs.readFileSync)(path, "utf-8"));
1585
+ return buildStoredCredentials(parsed, path, warn2, options);
1586
+ } catch {
1587
+ const warn2 = getWarn(options);
1588
+ warn2(
1589
+ `Credentials file at ${path} exists but could not be parsed. Delete it and run \`archal login\` to re-authenticate.`
1590
+ );
1591
+ return null;
1592
+ }
1593
+ }
1594
+ function readCredentialsFile(options) {
1595
+ return readCredentialsFileAtPath(getCredentialsPath(), options);
1596
+ }
1597
+ function isWorkspaceApiKey(token) {
1598
+ return token.startsWith("archal_ws_") || token.startsWith("archal_") && !token.includes(".");
1599
+ }
1600
+ function readCredentialsFromEnv(options) {
1601
+ const raw = process.env[AUTH_TOKEN_ENV_VAR];
1602
+ if (typeof raw !== "string") {
1603
+ return null;
1604
+ }
1605
+ const token = raw.trim();
1606
+ if (token.length === 0) {
1607
+ return null;
1608
+ }
1609
+ if (isWorkspaceApiKey(token)) {
1610
+ debug("ARCHAL_TOKEN is a workspace API key -- skipping JWT validation.");
1611
+ return {
1612
+ token,
1613
+ refreshToken: "",
1614
+ email: "(workspace-api-key)",
1615
+ // Local-only default; the server enforces the workspace's real plan.
1616
+ // Use 'pro' rather than 'enterprise' so the CLI never grants elevated
1617
+ // local entitlements that the workspace hasn't actually purchased.
1618
+ plan: "pro",
1619
+ selectedCloneIds: [],
1620
+ // Workspace keys have no local expiry -- the server enforces lifetime.
1621
+ // Use a far-future sentinel so the CLI never rejects the token locally.
1622
+ expiresAt: Math.floor(Date.now() / 1e3) + 365 * 24 * 60 * 60
1623
+ };
1624
+ }
1625
+ const claims = decodeJwtPayload(token);
1626
+ const nowSeconds = Math.floor(Date.now() / 1e3);
1627
+ if (claims === null) {
1628
+ getWarn(options)(
1629
+ "ARCHAL_TOKEN must be a JWT or a workspace API key (archal_ws_...). Ignoring environment token.\nFor CI, set ARCHAL_TOKEN to a workspace API key created via `archal workspace api-key create`."
1630
+ );
1631
+ return null;
1632
+ }
1633
+ const email = typeof claims["email"] === "string" ? claims["email"] : "(from ARCHAL_TOKEN)";
1634
+ if (!isPlan(claims["plan"])) {
1635
+ getWarn(options)("ARCHAL_TOKEN JWT does not contain a valid plan claim. Ignoring environment token.");
1636
+ return null;
1637
+ }
1638
+ const plan = claims["plan"];
1639
+ if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
1640
+ getWarn(options)("ARCHAL_TOKEN JWT does not contain a valid exp claim. Ignoring environment token.");
1641
+ return null;
1642
+ }
1643
+ const expiresAt = claims["exp"];
1644
+ if (expiresAt <= nowSeconds) {
1645
+ if (options?.onExpiredEnvToken === "throw") {
1646
+ throw new ExpiredEnvTokenError();
1647
+ }
1648
+ debug("Ignoring expired ARCHAL_TOKEN from environment.");
1649
+ return null;
1650
+ }
1651
+ return {
1652
+ token,
1653
+ refreshToken: "",
1654
+ email,
1655
+ plan,
1656
+ selectedCloneIds: [],
1657
+ expiresAt
1658
+ };
1659
+ }
1660
+ function getCredentials(options) {
1661
+ const envValue = process.env[AUTH_TOKEN_ENV_VAR];
1662
+ const hasExplicitEnvToken = String(envValue ?? "").trim().length > 0;
1663
+ const envCredentials = readCredentialsFromEnv(options);
1664
+ const creds = envCredentials ?? (hasExplicitEnvToken ? null : getStoredCredentials(options));
1665
+ if (!creds) {
1666
+ return null;
1667
+ }
1668
+ return isExpired(creds.expiresAt) ? null : creds;
1669
+ }
1670
+ function getStoredCredentials(options) {
1671
+ const creds = readCredentialsFile(options);
1672
+ if (!creds) {
1673
+ return null;
1674
+ }
1675
+ if (options?.includeExpired) {
1676
+ return creds;
1677
+ }
1678
+ return isExpired(creds.expiresAt) ? null : creds;
1679
+ }
1680
+ function writeCredentialsAtPath(path, creds) {
1681
+ const dir = (0, import_node_path2.dirname)(path);
1682
+ ensureDir(dir);
1683
+ const payload = {
1684
+ email: creds.email,
1685
+ plan: creds.plan,
1686
+ selectedCloneIds: normalizeEntitledCloneIds(creds.selectedCloneIds),
1687
+ expiresAt: creds.expiresAt,
1688
+ tokenEncrypted: encryptToken(creds.token.trim(), dir),
1689
+ refreshTokenEncrypted: creds.refreshToken.trim().length > 0 ? encryptToken(creds.refreshToken.trim(), dir) : void 0
1690
+ };
1691
+ const tmpPath = `${path}.${(0, import_node_crypto.randomBytes)(4).toString("hex")}.tmp`;
1692
+ (0, import_node_fs.writeFileSync)(tmpPath, `${JSON.stringify(payload, null, 2)}
1693
+ `, {
1694
+ encoding: "utf-8",
1695
+ mode: 384
1696
+ });
1697
+ (0, import_node_fs.renameSync)(tmpPath, path);
1698
+ }
1699
+
1700
+ // ../packages/node-auth/src/loopback.ts
1701
+ var import_node_net = require("net");
1702
+
1703
+ // ../packages/node-auth/src/secure-token.ts
1704
+ var import_node_crypto2 = require("crypto");
1705
+
1706
+ // ../packages/log/src/ansi.ts
1707
+ var NO_COLOR = "NO_COLOR" in process.env || process.env["TERM"] === "dumb";
1708
+ var RESET = NO_COLOR ? "" : "\x1B[0m";
1709
+ var BOLD = NO_COLOR ? "" : "\x1B[1m";
1710
+ var DIM = NO_COLOR ? "" : "\x1B[2m";
1711
+ var RED = NO_COLOR ? "" : "\x1B[31m";
1712
+ var YELLOW = NO_COLOR ? "" : "\x1B[33m";
1713
+ var CYAN = NO_COLOR ? "" : "\x1B[36m";
1714
+ var GRAY = NO_COLOR ? "" : "\x1B[90m";
1715
+
1716
+ // ../packages/log/src/logger.ts
1717
+ var LOG_LEVEL_PRIORITY = {
1718
+ debug: 0,
1719
+ info: 1,
1720
+ warn: 2,
1721
+ error: 3
1722
+ };
1723
+ var LOG_LEVEL_COLORS = {
1724
+ debug: GRAY,
1725
+ info: CYAN,
1726
+ warn: YELLOW,
1727
+ error: RED
1728
+ };
1729
+ var globalOptions = {
1730
+ level: "info",
1731
+ quiet: false,
1732
+ json: false,
1733
+ verbose: false
1734
+ };
1735
+ var ANSI_ESCAPE_RE = new RegExp(`${String.fromCodePoint(27)}\\[[0-9;]*m`, "g");
1736
+ function shouldLog(level) {
1737
+ if (globalOptions.quiet && level !== "error") {
1738
+ return false;
1739
+ }
1740
+ return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[globalOptions.level];
1741
+ }
1742
+ function formatTimestamp() {
1743
+ return (/* @__PURE__ */ new Date()).toISOString();
1744
+ }
1745
+ function formatLogEntry(entry) {
1746
+ if (globalOptions.json) {
1747
+ return JSON.stringify(entry);
1748
+ }
1749
+ const color = LOG_LEVEL_COLORS[entry.level];
1750
+ if (globalOptions.verbose || entry.level === "warn" || entry.level === "error") {
1751
+ const levelTag = `${color}${BOLD}${entry.level.toUpperCase().padEnd(5)}${RESET}`;
1752
+ const timestamp = `${DIM}${entry.timestamp}${RESET}`;
1753
+ let line = `${timestamp} ${levelTag} ${entry.message}`;
1754
+ if (entry.data && Object.keys(entry.data).length > 0) {
1755
+ const dataStr = Object.entries(entry.data).map(([k, v]) => `${DIM}${k}=${RESET}${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
1756
+ line += ` ${dataStr}`;
1757
+ }
1758
+ return line;
1759
+ }
1760
+ return `${DIM}${entry.message}${RESET}`;
1761
+ }
1762
+ function log(level, message, data) {
1763
+ if (!shouldLog(level)) {
1764
+ return;
1765
+ }
1766
+ const entry = {
1767
+ level,
1768
+ message,
1769
+ timestamp: formatTimestamp(),
1770
+ data
1771
+ };
1772
+ const formatted = formatLogEntry(entry);
1773
+ process.stderr.write(formatted + "\n");
1774
+ }
1775
+ function warn(message, data) {
1776
+ log("warn", message, data);
1777
+ }
1778
+
1779
+ // src/utils/version.ts
1780
+ var import_node_fs2 = require("fs");
1781
+ var import_node_path3 = require("path");
1782
+ var CLI_PACKAGE_NAMES = /* @__PURE__ */ new Set(["@archal/cli", "archal"]);
1783
+ function resolvePackageJsonCandidates() {
1784
+ const candidates = /* @__PURE__ */ new Set();
1785
+ if (typeof __dirname === "string") {
1786
+ candidates.add((0, import_node_path3.join)(__dirname, "..", "package.json"));
1787
+ candidates.add((0, import_node_path3.join)(__dirname, "..", "..", "package.json"));
1788
+ }
1789
+ return [...candidates];
1790
+ }
1791
+ function readPackageJson(path) {
1792
+ try {
1793
+ return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf-8"));
1794
+ } catch {
1795
+ return null;
1796
+ }
1797
+ }
1798
+ function loadVersion() {
1799
+ let fallbackVersion = null;
1800
+ for (const pkgPath of resolvePackageJsonCandidates()) {
1801
+ const pkg = readPackageJson(pkgPath);
1802
+ if (!pkg) {
1803
+ continue;
1804
+ }
1805
+ if (typeof pkg.name === "string" && CLI_PACKAGE_NAMES.has(pkg.name) && typeof pkg.version === "string") {
1806
+ return pkg.version;
1807
+ }
1808
+ if (fallbackVersion === null && typeof pkg.version === "string") {
1809
+ fallbackVersion = pkg.version;
1810
+ }
1811
+ }
1812
+ return fallbackVersion ?? "0.0.0";
1813
+ }
1814
+ var CLI_VERSION = loadVersion();
1815
+ var CLI_USER_AGENT = `archal-cli/${CLI_VERSION}`;
1816
+
1817
+ // src/auth/credential-store.ts
1818
+ var READ_OPTIONS = { onExpiredEnvToken: "throw", warn };
1819
+ var cachedEnvToken = null;
1820
+ var cachedEnvCredentials = null;
1821
+ var cachedEnvCredentialsResolved = false;
1822
+ function readExplicitEnvToken() {
1823
+ const raw = process.env["ARCHAL_TOKEN"];
1824
+ if (typeof raw !== "string") return null;
1825
+ const token = raw.trim();
1826
+ return token.length > 0 ? token : null;
1827
+ }
1828
+ function getCredentials2() {
1829
+ const envToken = readExplicitEnvToken();
1830
+ if (!envToken) {
1831
+ return getCredentials(READ_OPTIONS);
1832
+ }
1833
+ if (!cachedEnvCredentialsResolved || cachedEnvToken !== envToken) {
1834
+ cachedEnvToken = envToken;
1835
+ cachedEnvCredentials = getCredentials(READ_OPTIONS);
1836
+ cachedEnvCredentialsResolved = true;
1837
+ }
1838
+ return cachedEnvCredentials;
1839
+ }
1840
+
1841
+ // src/auth/require-auth.ts
1842
+ var import_node_child_process2 = require("child_process");
1843
+
1844
+ // src/telemetry/posthog.ts
1845
+ var import_node_fs4 = require("fs");
1846
+ var import_node_path4 = require("path");
1847
+ var import_node_crypto3 = require("crypto");
1848
+
1849
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/utils/type-utils.mjs
1850
+ var nativeIsArray = Array.isArray;
1851
+ var ObjProto = Object.prototype;
1852
+ var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
1853
+ var type_utils_toString = ObjProto.toString;
1854
+ var isArray = nativeIsArray || function(obj) {
1855
+ return "[object Array]" === type_utils_toString.call(obj);
1856
+ };
1857
+ var isObject = (x) => x === Object(x) && !isArray(x);
1858
+ var isUndefined = (x) => void 0 === x;
1859
+ var isString = (x) => "[object String]" == type_utils_toString.call(x);
1860
+ var isEmptyString = (x) => isString(x) && 0 === x.trim().length;
1861
+ var isNumber = (x) => "[object Number]" == type_utils_toString.call(x) && x === x;
1862
+ var isPlainError = (x) => x instanceof Error;
1863
+ function isPrimitive(value) {
1864
+ return null === value || "object" != typeof value;
1865
+ }
1866
+ function isBuiltin(candidate, className) {
1867
+ return Object.prototype.toString.call(candidate) === `[object ${className}]`;
1868
+ }
1869
+ function isErrorEvent(event) {
1870
+ return isBuiltin(event, "ErrorEvent");
1871
+ }
1872
+ function isEvent(candidate) {
1873
+ return "undefined" != typeof Event && isInstanceOf(candidate, Event);
1874
+ }
1875
+ function isInstanceOf(candidate, base) {
1876
+ try {
1877
+ return candidate instanceof base;
1878
+ } catch {
1879
+ return false;
1880
+ }
1881
+ }
1882
+
1883
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
1884
+ var MOBILE = "Mobile";
1885
+ var IOS = "iOS";
1886
+ var ANDROID = "Android";
1887
+ var TABLET = "Tablet";
1888
+ var ANDROID_TABLET = ANDROID + " " + TABLET;
1889
+ var APPLE = "Apple";
1890
+ var APPLE_WATCH = APPLE + " Watch";
1891
+ var SAFARI = "Safari";
1892
+ var BLACKBERRY = "BlackBerry";
1893
+ var SAMSUNG = "Samsung";
1894
+ var SAMSUNG_BROWSER = SAMSUNG + "Browser";
1895
+ var SAMSUNG_INTERNET = SAMSUNG + " Internet";
1896
+ var CHROME = "Chrome";
1897
+ var CHROME_OS = CHROME + " OS";
1898
+ var CHROME_IOS = CHROME + " " + IOS;
1899
+ var INTERNET_EXPLORER = "Internet Explorer";
1900
+ var INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + " " + MOBILE;
1901
+ var OPERA = "Opera";
1902
+ var OPERA_MINI = OPERA + " Mini";
1903
+ var EDGE = "Edge";
1904
+ var MICROSOFT_EDGE = "Microsoft " + EDGE;
1905
+ var FIREFOX = "Firefox";
1906
+ var FIREFOX_IOS = FIREFOX + " " + IOS;
1907
+ var NINTENDO = "Nintendo";
1908
+ var PLAYSTATION = "PlayStation";
1909
+ var XBOX = "Xbox";
1910
+ var ANDROID_MOBILE = ANDROID + " " + MOBILE;
1911
+ var MOBILE_SAFARI = MOBILE + " " + SAFARI;
1912
+ var WINDOWS = "Windows";
1913
+ var WINDOWS_PHONE = WINDOWS + " Phone";
1914
+ var GENERIC = "Generic";
1915
+ var GENERIC_MOBILE = GENERIC + " " + MOBILE.toLowerCase();
1916
+ var GENERIC_TABLET = GENERIC + " " + TABLET.toLowerCase();
1917
+ var KONQUEROR = "Konqueror";
1918
+ var OCULUS_BROWSER = "Oculus Browser";
1919
+ var VIVALDI = "Vivaldi";
1920
+ var YANDEX = "Yandex";
1921
+ var WHALE = "Whale";
1922
+ var DUCKDUCKGO = "DuckDuckGo";
1923
+ var PALE_MOON = "Pale Moon";
1924
+ var WATERFOX = "Waterfox";
1925
+ var BRAVE = "Brave";
1926
+ var GOOGLE_SEARCH_APP = "Google Search App";
1927
+ var BROWSER_VERSION_REGEX_SUFFIX = "(\\d+(\\.\\d+)?)";
1928
+ var DEFAULT_BROWSER_VERSION_REGEX = new RegExp("Version/" + BROWSER_VERSION_REGEX_SUFFIX);
1929
+ var XBOX_REGEX = new RegExp(XBOX, "i");
1930
+ var PLAYSTATION_REGEX = new RegExp(PLAYSTATION + " \\w+", "i");
1931
+ var NINTENDO_REGEX = new RegExp(NINTENDO + " \\w+", "i");
1932
+ var BLACKBERRY_REGEX = new RegExp(BLACKBERRY + "|PlayBook|BB10", "i");
1933
+ var windowsVersionMap = {
1934
+ "NT3.51": "NT 3.11",
1935
+ "NT4.0": "NT 4.0",
1936
+ "5.0": "2000",
1937
+ "5.1": "XP",
1938
+ "5.2": "XP",
1939
+ "6.0": "Vista",
1940
+ "6.1": "7",
1941
+ "6.2": "8",
1942
+ "6.3": "8.1",
1943
+ "6.4": "10",
1944
+ "10.0": "10"
1945
+ };
1946
+ var versionRegexes = {
1947
+ [INTERNET_EXPLORER_MOBILE]: [
1948
+ new RegExp("rv:" + BROWSER_VERSION_REGEX_SUFFIX)
1949
+ ],
1950
+ [MICROSOFT_EDGE]: [
1951
+ new RegExp(EDGE + "?\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1952
+ ],
1953
+ [CHROME]: [
1954
+ new RegExp("(" + CHROME + "|CrMo)\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1955
+ ],
1956
+ [CHROME_IOS]: [
1957
+ new RegExp("CriOS\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1958
+ ],
1959
+ "UC Browser": [
1960
+ new RegExp("(UCBrowser|UCWEB)\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1961
+ ],
1962
+ [SAFARI]: [
1963
+ DEFAULT_BROWSER_VERSION_REGEX
1964
+ ],
1965
+ [MOBILE_SAFARI]: [
1966
+ DEFAULT_BROWSER_VERSION_REGEX
1967
+ ],
1968
+ [OPERA]: [
1969
+ new RegExp("(" + OPERA + "|OPR)\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1970
+ ],
1971
+ [FIREFOX]: [
1972
+ new RegExp(FIREFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1973
+ ],
1974
+ [FIREFOX_IOS]: [
1975
+ new RegExp("FxiOS\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1976
+ ],
1977
+ [KONQUEROR]: [
1978
+ new RegExp("Konqueror[:/]?" + BROWSER_VERSION_REGEX_SUFFIX, "i")
1979
+ ],
1980
+ [BLACKBERRY]: [
1981
+ new RegExp(BLACKBERRY + " " + BROWSER_VERSION_REGEX_SUFFIX),
1982
+ DEFAULT_BROWSER_VERSION_REGEX
1983
+ ],
1984
+ [ANDROID_MOBILE]: [
1985
+ new RegExp("android\\s" + BROWSER_VERSION_REGEX_SUFFIX, "i")
1986
+ ],
1987
+ [SAMSUNG_INTERNET]: [
1988
+ new RegExp(SAMSUNG_BROWSER + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1989
+ ],
1990
+ [OCULUS_BROWSER]: [
1991
+ new RegExp("OculusBrowser\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1992
+ ],
1993
+ [VIVALDI]: [
1994
+ new RegExp(VIVALDI + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1995
+ ],
1996
+ [YANDEX]: [
1997
+ new RegExp("YaBrowser\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1998
+ ],
1999
+ [WHALE]: [
2000
+ new RegExp(WHALE + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2001
+ ],
2002
+ [BRAVE]: [
2003
+ new RegExp(BRAVE + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2004
+ ],
2005
+ [DUCKDUCKGO]: [
2006
+ new RegExp("(DuckDuckGo|Ddg)\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2007
+ ],
2008
+ [PALE_MOON]: [
2009
+ new RegExp("PaleMoon\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2010
+ ],
2011
+ [WATERFOX]: [
2012
+ new RegExp(WATERFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2013
+ ],
2014
+ [GOOGLE_SEARCH_APP]: [
2015
+ new RegExp("GSA\\/" + BROWSER_VERSION_REGEX_SUFFIX)
2016
+ ],
2017
+ [INTERNET_EXPLORER]: [
2018
+ new RegExp("(rv:|MSIE )" + BROWSER_VERSION_REGEX_SUFFIX)
2019
+ ],
2020
+ Mozilla: [
2021
+ new RegExp("rv:" + BROWSER_VERSION_REGEX_SUFFIX)
2022
+ ]
2023
+ };
2024
+ var osMatchers = [
2025
+ [
2026
+ new RegExp(XBOX + "; " + XBOX + " (.*?)[);]", "i"),
2027
+ (match) => [
2028
+ XBOX,
2029
+ match && match[1] || ""
2030
+ ]
2031
+ ],
2032
+ [
2033
+ new RegExp(NINTENDO, "i"),
2034
+ [
2035
+ NINTENDO,
2036
+ ""
2037
+ ]
2038
+ ],
2039
+ [
2040
+ new RegExp(PLAYSTATION, "i"),
2041
+ [
2042
+ PLAYSTATION,
2043
+ ""
2044
+ ]
2045
+ ],
2046
+ [
2047
+ BLACKBERRY_REGEX,
2048
+ [
2049
+ BLACKBERRY,
2050
+ ""
2051
+ ]
2052
+ ],
2053
+ [
2054
+ new RegExp(WINDOWS, "i"),
2055
+ (_, user_agent) => {
2056
+ if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [
2057
+ WINDOWS_PHONE,
2058
+ ""
2059
+ ];
2060
+ if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\b/.test(user_agent)) return [
2061
+ WINDOWS + " " + MOBILE,
2062
+ ""
2063
+ ];
2064
+ const match = /Windows NT ([0-9.]+)/i.exec(user_agent);
2065
+ if (match && match[1]) {
2066
+ const version2 = match[1];
2067
+ let osVersion = windowsVersionMap[version2] || "";
2068
+ if (/arm/i.test(user_agent)) osVersion = "RT";
2069
+ return [
2070
+ WINDOWS,
2071
+ osVersion
2072
+ ];
2073
+ }
2074
+ return [
2075
+ WINDOWS,
2076
+ ""
2077
+ ];
2078
+ }
2079
+ ],
2080
+ [
2081
+ /((iPhone|iPad|iPod).*?OS (\d+)_(\d+)_?(\d+)?|iPhone)/,
2082
+ (match) => {
2083
+ if (match && match[3]) {
2084
+ const versionParts = [
2085
+ match[3],
2086
+ match[4],
2087
+ match[5] || "0"
2088
+ ];
2089
+ return [
2090
+ IOS,
2091
+ versionParts.join(".")
2092
+ ];
2093
+ }
2094
+ return [
2095
+ IOS,
2096
+ ""
2097
+ ];
2098
+ }
2099
+ ],
2100
+ [
2101
+ /(watch.*\/(\d+\.\d+\.\d+)|watch os,(\d+\.\d+),)/i,
2102
+ (match) => {
2103
+ let version2 = "";
2104
+ if (match && match.length >= 3) version2 = isUndefined(match[2]) ? match[3] : match[2];
2105
+ return [
2106
+ "watchOS",
2107
+ version2
2108
+ ];
2109
+ }
2110
+ ],
2111
+ [
2112
+ new RegExp("(" + ANDROID + " (\\d+)\\.(\\d+)\\.?(\\d+)?|" + ANDROID + ")", "i"),
2113
+ (match) => {
2114
+ if (match && match[2]) {
2115
+ const versionParts = [
2116
+ match[2],
2117
+ match[3],
2118
+ match[4] || "0"
2119
+ ];
2120
+ return [
2121
+ ANDROID,
2122
+ versionParts.join(".")
2123
+ ];
2124
+ }
2125
+ return [
2126
+ ANDROID,
2127
+ ""
2128
+ ];
2129
+ }
2130
+ ],
2131
+ [
2132
+ /Mac OS X (\d+)[_.](\d+)[_.]?(\d+)?/i,
2133
+ (match) => {
2134
+ const result = [
2135
+ "Mac OS X",
2136
+ ""
2137
+ ];
2138
+ if (match && match[1]) {
2139
+ const versionParts = [
2140
+ match[1],
2141
+ match[2],
2142
+ match[3] || "0"
2143
+ ];
2144
+ result[1] = versionParts.join(".");
2145
+ }
2146
+ return result;
2147
+ }
2148
+ ],
2149
+ [
2150
+ /Mac/i,
2151
+ [
2152
+ "Mac OS X",
2153
+ ""
2154
+ ]
2155
+ ],
2156
+ [
2157
+ /CrOS/,
2158
+ [
2159
+ CHROME_OS,
2160
+ ""
2161
+ ]
2162
+ ],
2163
+ [
2164
+ /Linux|debian/i,
2165
+ [
2166
+ "Linux",
2167
+ ""
2168
+ ]
2169
+ ]
2170
+ ];
2171
+
2172
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/utils/index.mjs
2173
+ var isError = (x) => x instanceof Error;
2174
+
2175
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/logs/logs-utils.mjs
2176
+ var OTLP_SEVERITY_MAP = {
2177
+ trace: {
2178
+ text: "TRACE",
2179
+ number: 1
2180
+ },
2181
+ debug: {
2182
+ text: "DEBUG",
2183
+ number: 5
2184
+ },
2185
+ info: {
2186
+ text: "INFO",
2187
+ number: 9
2188
+ },
2189
+ warn: {
2190
+ text: "WARN",
2191
+ number: 13
2192
+ },
2193
+ error: {
2194
+ text: "ERROR",
2195
+ number: 17
2196
+ },
2197
+ fatal: {
2198
+ text: "FATAL",
2199
+ number: 21
2200
+ }
2201
+ };
2202
+ var DEFAULT_OTLP_SEVERITY = OTLP_SEVERITY_MAP.info;
2203
+
2204
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/index.mjs
2205
+ var error_tracking_exports = {};
2206
+ __export(error_tracking_exports, {
2207
+ DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG,
2208
+ DOMExceptionCoercer: () => DOMExceptionCoercer,
2209
+ EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2210
+ ErrorCoercer: () => ErrorCoercer,
2211
+ ErrorEventCoercer: () => ErrorEventCoercer,
2212
+ ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
2213
+ EventCoercer: () => EventCoercer,
2214
+ ExceptionStepsBuffer: () => ExceptionStepsBuffer,
2215
+ ObjectCoercer: () => ObjectCoercer,
2216
+ PrimitiveCoercer: () => PrimitiveCoercer,
2217
+ PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
2218
+ ReduceableCache: () => ReduceableCache,
2219
+ StringCoercer: () => StringCoercer,
2220
+ chromeStackLineParser: () => chromeStackLineParser,
2221
+ createDefaultStackParser: () => createDefaultStackParser,
2222
+ createStackParser: () => createStackParser,
2223
+ geckoStackLineParser: () => geckoStackLineParser,
2224
+ getUtf8ByteLength: () => getUtf8ByteLength,
2225
+ nodeStackLineParser: () => nodeStackLineParser,
2226
+ opera10StackLineParser: () => opera10StackLineParser,
2227
+ opera11StackLineParser: () => opera11StackLineParser,
2228
+ resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
2229
+ reverseAndStripFrames: () => reverseAndStripFrames,
2230
+ stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
2231
+ winjsStackLineParser: () => winjsStackLineParser
2232
+ });
2233
+
2234
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
2235
+ var parsedStackResults;
2236
+ var lastKeysCount;
2237
+ var cachedFilenameChunkIds;
2238
+ function getFilenameToChunkIdMap(stackParser) {
2239
+ const chunkIdMap = globalThis._posthogChunkIds;
2240
+ if (!chunkIdMap) return;
2241
+ const chunkIdKeys = Object.keys(chunkIdMap);
2242
+ if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;
2243
+ lastKeysCount = chunkIdKeys.length;
2244
+ cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey) => {
2245
+ if (!parsedStackResults) parsedStackResults = {};
2246
+ const result = parsedStackResults[stackKey];
2247
+ if (result) acc[result[0]] = result[1];
2248
+ else {
2249
+ const parsedStack = stackParser(stackKey);
2250
+ for (let i = parsedStack.length - 1; i >= 0; i--) {
2251
+ const stackFrame = parsedStack[i];
2252
+ const filename = stackFrame?.filename;
2253
+ const chunkId = chunkIdMap[stackKey];
2254
+ if (filename && chunkId) {
2255
+ acc[filename] = chunkId;
2256
+ parsedStackResults[stackKey] = [
2257
+ filename,
2258
+ chunkId
2259
+ ];
2260
+ break;
2261
+ }
2262
+ }
2263
+ }
2264
+ return acc;
2265
+ }, {});
2266
+ return cachedFilenameChunkIds;
2267
+ }
2268
+
2269
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
2270
+ var MAX_CAUSE_RECURSION = 4;
2271
+ var ErrorPropertiesBuilder = class {
2272
+ constructor(coercers, stackParser, modifiers = []) {
2273
+ this.coercers = coercers;
2274
+ this.stackParser = stackParser;
2275
+ this.modifiers = modifiers;
2276
+ }
2277
+ buildFromUnknown(input, hint = {}) {
2278
+ const providedMechanism = hint && hint.mechanism;
2279
+ const mechanism = providedMechanism || {
2280
+ handled: true,
2281
+ type: "generic"
2282
+ };
2283
+ const coercingContext = this.buildCoercingContext(mechanism, hint, 0);
2284
+ const exceptionWithCause = coercingContext.apply(input);
2285
+ const parsingContext = this.buildParsingContext(hint);
2286
+ const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);
2287
+ const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);
2288
+ return {
2289
+ $exception_list: exceptionList,
2290
+ $exception_level: "error"
2291
+ };
2292
+ }
2293
+ async modifyFrames(exceptionList) {
2294
+ for (const exc of exceptionList) if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);
2295
+ return exceptionList;
2296
+ }
2297
+ coerceFallback(ctx) {
2298
+ return {
2299
+ type: "Error",
2300
+ value: "Unknown error",
2301
+ stack: ctx.syntheticException?.stack,
2302
+ synthetic: true
2303
+ };
2304
+ }
2305
+ parseStacktrace(err, ctx) {
2306
+ let cause;
2307
+ if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);
2308
+ let stack;
2309
+ if ("" != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? ctx.skipFirstLines : 0), ctx.chunkIdMap);
2310
+ return {
2311
+ ...err,
2312
+ cause,
2313
+ stack
2314
+ };
2315
+ }
2316
+ applyChunkIds(frames, chunkIdMap) {
2317
+ return frames.map((frame) => {
2318
+ if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];
2319
+ return frame;
2320
+ });
2321
+ }
2322
+ applyCoercers(input, ctx) {
2323
+ for (const adapter of this.coercers) if (adapter.match(input)) return adapter.coerce(input, ctx);
2324
+ return this.coerceFallback(ctx);
2325
+ }
2326
+ async applyModifiers(frames) {
2327
+ let newFrames = frames;
2328
+ for (const modifier of this.modifiers) newFrames = await modifier(newFrames);
2329
+ return newFrames;
2330
+ }
2331
+ convertToExceptionList(exceptionWithStack, mechanism) {
2332
+ const currentException = {
2333
+ type: exceptionWithStack.type,
2334
+ value: exceptionWithStack.value,
2335
+ mechanism: {
2336
+ type: mechanism.type ?? "generic",
2337
+ handled: mechanism.handled ?? true,
2338
+ synthetic: exceptionWithStack.synthetic ?? false
2339
+ }
2340
+ };
2341
+ if (exceptionWithStack.stack) currentException.stacktrace = {
2342
+ type: "raw",
2343
+ frames: exceptionWithStack.stack
2344
+ };
2345
+ const exceptionList = [
2346
+ currentException
2347
+ ];
2348
+ if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {
2349
+ ...mechanism,
2350
+ handled: true
2351
+ }));
2352
+ return exceptionList;
2353
+ }
2354
+ buildParsingContext(hint) {
2355
+ const context = {
2356
+ chunkIdMap: getFilenameToChunkIdMap(this.stackParser),
2357
+ skipFirstLines: hint.skipFirstLines ?? 1
2358
+ };
2359
+ return context;
2360
+ }
2361
+ buildCoercingContext(mechanism, hint, depth = 0) {
2362
+ const coerce = (input, depth2) => {
2363
+ if (!(depth2 <= MAX_CAUSE_RECURSION)) return;
2364
+ {
2365
+ const ctx = this.buildCoercingContext(mechanism, hint, depth2);
2366
+ return this.applyCoercers(input, ctx);
2367
+ }
2368
+ };
2369
+ const context = {
2370
+ ...hint,
2371
+ syntheticException: 0 == depth ? hint.syntheticException : void 0,
2372
+ mechanism,
2373
+ apply: (input) => coerce(input, depth),
2374
+ next: (input) => coerce(input, depth + 1)
2375
+ };
2376
+ return context;
2377
+ }
2378
+ };
2379
+
2380
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
2381
+ var UNKNOWN_FUNCTION = "?";
2382
+ function createFrame(platform, filename, func, lineno, colno) {
2383
+ const frame = {
2384
+ platform,
2385
+ filename,
2386
+ function: "<anonymous>" === func ? UNKNOWN_FUNCTION : func,
2387
+ in_app: true
2388
+ };
2389
+ if (!isUndefined(lineno)) frame.lineno = lineno;
2390
+ if (!isUndefined(colno)) frame.colno = colno;
2391
+ return frame;
2392
+ }
2393
+
2394
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
2395
+ var extractSafariExtensionDetails = (func, filename) => {
2396
+ const isSafariExtension = -1 !== func.indexOf("safari-extension");
2397
+ const isSafariWebExtension = -1 !== func.indexOf("safari-web-extension");
2398
+ return isSafariExtension || isSafariWebExtension ? [
2399
+ -1 !== func.indexOf("@") ? func.split("@")[0] : UNKNOWN_FUNCTION,
2400
+ isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`
2401
+ ] : [
2402
+ func,
2403
+ filename
2404
+ ];
2405
+ };
2406
+
2407
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
2408
+ var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
2409
+ var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
2410
+ var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
2411
+ var chromeStackLineParser = (line, platform) => {
2412
+ const noFnParts = chromeRegexNoFnName.exec(line);
2413
+ if (noFnParts) {
2414
+ const [, filename, line2, col] = noFnParts;
2415
+ return createFrame(platform, filename, UNKNOWN_FUNCTION, +line2, +col);
2416
+ }
2417
+ const parts = chromeRegex.exec(line);
2418
+ if (parts) {
2419
+ const isEval = parts[2] && 0 === parts[2].indexOf("eval");
2420
+ if (isEval) {
2421
+ const subMatch = chromeEvalRegex.exec(parts[2]);
2422
+ if (subMatch) {
2423
+ parts[2] = subMatch[1];
2424
+ parts[3] = subMatch[2];
2425
+ parts[4] = subMatch[3];
2426
+ }
2427
+ }
2428
+ const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);
2429
+ return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);
2430
+ }
2431
+ };
2432
+
2433
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
2434
+ var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
2435
+ var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
2436
+ var geckoStackLineParser = (line, platform) => {
2437
+ const parts = geckoREgex.exec(line);
2438
+ if (parts) {
2439
+ const isEval = parts[3] && parts[3].indexOf(" > eval") > -1;
2440
+ if (isEval) {
2441
+ const subMatch = geckoEvalRegex.exec(parts[3]);
2442
+ if (subMatch) {
2443
+ parts[1] = parts[1] || "eval";
2444
+ parts[3] = subMatch[1];
2445
+ parts[4] = subMatch[2];
2446
+ parts[5] = "";
2447
+ }
2448
+ }
2449
+ let filename = parts[3];
2450
+ let func = parts[1] || UNKNOWN_FUNCTION;
2451
+ [func, filename] = extractSafariExtensionDetails(func, filename);
2452
+ return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);
2453
+ }
2454
+ };
2455
+
2456
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
2457
+ var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
2458
+ var winjsStackLineParser = (line, platform) => {
2459
+ const parts = winjsRegex.exec(line);
2460
+ return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : void 0) : void 0;
2461
+ };
2462
+
2463
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
2464
+ var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
2465
+ var opera10StackLineParser = (line, platform) => {
2466
+ const parts = opera10Regex.exec(line);
2467
+ return parts ? createFrame(platform, parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : void 0;
2468
+ };
2469
+ var opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\(.*\))? in (.*):\s*$/i;
2470
+ var opera11StackLineParser = (line, platform) => {
2471
+ const parts = opera11Regex.exec(line);
2472
+ return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : void 0;
2473
+ };
2474
+
2475
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
2476
+ var FILENAME_MATCH = /^\s*[-]{4,}$/;
2477
+ var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
2478
+ var nodeStackLineParser = (line, platform) => {
2479
+ const lineMatch = line.match(FULL_MATCH);
2480
+ if (lineMatch) {
2481
+ let object;
2482
+ let method;
2483
+ let functionName;
2484
+ let typeName;
2485
+ let methodName;
2486
+ if (lineMatch[1]) {
2487
+ functionName = lineMatch[1];
2488
+ let methodStart = functionName.lastIndexOf(".");
2489
+ if ("." === functionName[methodStart - 1]) methodStart--;
2490
+ if (methodStart > 0) {
2491
+ object = functionName.slice(0, methodStart);
2492
+ method = functionName.slice(methodStart + 1);
2493
+ const objectEnd = object.indexOf(".Module");
2494
+ if (objectEnd > 0) {
2495
+ functionName = functionName.slice(objectEnd + 1);
2496
+ object = object.slice(0, objectEnd);
2497
+ }
2498
+ }
2499
+ typeName = void 0;
2500
+ }
2501
+ if (method) {
2502
+ typeName = object;
2503
+ methodName = method;
2504
+ }
2505
+ if ("<anonymous>" === method) {
2506
+ methodName = void 0;
2507
+ functionName = void 0;
2508
+ }
2509
+ if (void 0 === functionName) {
2510
+ methodName = methodName || UNKNOWN_FUNCTION;
2511
+ functionName = typeName ? `${typeName}.${methodName}` : methodName;
2512
+ }
2513
+ let filename = lineMatch[2]?.startsWith("file://") ? lineMatch[2].slice(7) : lineMatch[2];
2514
+ const isNative = "native" === lineMatch[5];
2515
+ if (filename?.match(/\/[A-Z]:/)) filename = filename.slice(1);
2516
+ if (!filename && lineMatch[5] && !isNative) filename = lineMatch[5];
2517
+ return {
2518
+ filename: filename ? decodeURI(filename) : void 0,
2519
+ module: void 0,
2520
+ function: functionName,
2521
+ lineno: _parseIntOrUndefined(lineMatch[3]),
2522
+ colno: _parseIntOrUndefined(lineMatch[4]),
2523
+ in_app: filenameIsInApp(filename || "", isNative),
2524
+ platform
2525
+ };
2526
+ }
2527
+ if (line.match(FILENAME_MATCH)) return {
2528
+ filename: line,
2529
+ platform
2530
+ };
2531
+ };
2532
+ function filenameIsInApp(filename, isNative = false) {
2533
+ const isInternal = isNative || filename && !filename.startsWith("/") && !filename.match(/^[A-Z]:/) && !filename.startsWith(".") && !filename.match(/^[a-zA-Z]([a-zA-Z0-9.\-+])*:\/\//);
2534
+ return !isInternal && void 0 !== filename && !filename.includes("node_modules/");
2535
+ }
2536
+ function _parseIntOrUndefined(input) {
2537
+ return parseInt(input || "", 10) || void 0;
2538
+ }
2539
+
2540
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
2541
+ var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
2542
+ var STACKTRACE_FRAME_LIMIT = 50;
2543
+ function reverseAndStripFrames(stack) {
2544
+ if (!stack.length) return [];
2545
+ const localStack = Array.from(stack);
2546
+ localStack.reverse();
2547
+ return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame) => ({
2548
+ ...frame,
2549
+ filename: frame.filename || getLastStackFrame(localStack).filename,
2550
+ function: frame.function || UNKNOWN_FUNCTION
2551
+ }));
2552
+ }
2553
+ function getLastStackFrame(arr) {
2554
+ return arr[arr.length - 1] || {};
2555
+ }
2556
+ function createDefaultStackParser() {
2557
+ return createStackParser("web:javascript", chromeStackLineParser, geckoStackLineParser);
2558
+ }
2559
+ function createStackParser(platform, ...parsers) {
2560
+ return (stack, skipFirstLines = 0) => {
2561
+ const frames = [];
2562
+ const lines = stack.split("\n");
2563
+ for (let i = skipFirstLines; i < lines.length; i++) {
2564
+ const line = lines[i];
2565
+ if (line.length > 1024) continue;
2566
+ const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
2567
+ if (!cleanedLine.match(/\S*Error: /)) {
2568
+ for (const parser of parsers) {
2569
+ const frame = parser(cleanedLine, platform);
2570
+ if (frame) {
2571
+ frames.push(frame);
2572
+ break;
2573
+ }
2574
+ }
2575
+ if (frames.length >= STACKTRACE_FRAME_LIMIT) break;
2576
+ }
2577
+ }
2578
+ return reverseAndStripFrames(frames);
2579
+ };
2580
+ }
2581
+
2582
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
2583
+ var DOMExceptionCoercer = class {
2584
+ match(err) {
2585
+ return this.isDOMException(err) || this.isDOMError(err);
2586
+ }
2587
+ coerce(err, ctx) {
2588
+ const hasStack = isString(err.stack);
2589
+ return {
2590
+ type: this.getType(err),
2591
+ value: this.getValue(err),
2592
+ stack: hasStack ? err.stack : void 0,
2593
+ cause: err.cause ? ctx.next(err.cause) : void 0,
2594
+ synthetic: false
2595
+ };
2596
+ }
2597
+ getType(candidate) {
2598
+ return this.isDOMError(candidate) ? "DOMError" : "DOMException";
2599
+ }
2600
+ getValue(err) {
2601
+ const name = err.name || (this.isDOMError(err) ? "DOMError" : "DOMException");
2602
+ const message = err.message ? `${name}: ${err.message}` : name;
2603
+ return message;
2604
+ }
2605
+ isDOMException(err) {
2606
+ return isBuiltin(err, "DOMException");
2607
+ }
2608
+ isDOMError(err) {
2609
+ return isBuiltin(err, "DOMError");
2610
+ }
2611
+ };
2612
+
2613
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
2614
+ var ErrorCoercer = class {
2615
+ match(err) {
2616
+ return isPlainError(err);
2617
+ }
2618
+ coerce(err, ctx) {
2619
+ return {
2620
+ type: this.getType(err),
2621
+ value: this.getMessage(err, ctx),
2622
+ stack: this.getStack(err),
2623
+ cause: err.cause ? ctx.next(err.cause) : void 0,
2624
+ synthetic: false
2625
+ };
2626
+ }
2627
+ getType(err) {
2628
+ return err.name || err.constructor.name;
2629
+ }
2630
+ getMessage(err, _ctx) {
2631
+ const message = err.message;
2632
+ if (message.error && "string" == typeof message.error.message) return String(message.error.message);
2633
+ return String(message);
2634
+ }
2635
+ getStack(err) {
2636
+ return err.stacktrace || err.stack || void 0;
2637
+ }
2638
+ };
2639
+
2640
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2641
+ var ErrorEventCoercer = class {
2642
+ constructor() {
2643
+ }
2644
+ match(err) {
2645
+ return isErrorEvent(err) && void 0 != err.error;
2646
+ }
2647
+ coerce(err, ctx) {
2648
+ const exceptionLike = ctx.apply(err.error);
2649
+ if (!exceptionLike) return {
2650
+ type: "ErrorEvent",
2651
+ value: err.message,
2652
+ stack: ctx.syntheticException?.stack,
2653
+ synthetic: true
2654
+ };
2655
+ return exceptionLike;
2656
+ }
2657
+ };
2658
+
2659
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
2660
+ var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
2661
+ var StringCoercer = class {
2662
+ match(input) {
2663
+ return "string" == typeof input;
2664
+ }
2665
+ coerce(input, ctx) {
2666
+ const [type, value] = this.getInfos(input);
2667
+ return {
2668
+ type: type ?? "Error",
2669
+ value: value ?? input,
2670
+ stack: ctx.syntheticException?.stack,
2671
+ synthetic: true
2672
+ };
2673
+ }
2674
+ getInfos(candidate) {
2675
+ let type = "Error";
2676
+ let value = candidate;
2677
+ const groups = candidate.match(ERROR_TYPES_PATTERN);
2678
+ if (groups) {
2679
+ type = groups[1];
2680
+ value = groups[2];
2681
+ }
2682
+ return [
2683
+ type,
2684
+ value
2685
+ ];
2686
+ }
2687
+ };
2688
+
2689
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/types.mjs
2690
+ var severityLevels = [
2691
+ "fatal",
2692
+ "error",
2693
+ "warning",
2694
+ "log",
2695
+ "info",
2696
+ "debug"
2697
+ ];
2698
+
2699
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
2700
+ function extractExceptionKeysForMessage(err, maxLength = 40) {
2701
+ const keys = Object.keys(err);
2702
+ keys.sort();
2703
+ if (!keys.length) return "[object has no keys]";
2704
+ for (let i = keys.length; i > 0; i--) {
2705
+ const serialized = keys.slice(0, i).join(", ");
2706
+ if (!(serialized.length > maxLength)) {
2707
+ if (i === keys.length) return serialized;
2708
+ return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;
2709
+ }
2710
+ }
2711
+ return "";
2712
+ }
2713
+
2714
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
2715
+ var ObjectCoercer = class {
2716
+ match(candidate) {
2717
+ return "object" == typeof candidate && null !== candidate;
2718
+ }
2719
+ coerce(candidate, ctx) {
2720
+ const errorProperty = this.getErrorPropertyFromObject(candidate);
2721
+ if (errorProperty) return ctx.apply(errorProperty);
2722
+ return {
2723
+ type: this.getType(candidate),
2724
+ value: this.getValue(candidate),
2725
+ stack: ctx.syntheticException?.stack,
2726
+ level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
2727
+ synthetic: true
2728
+ };
2729
+ }
2730
+ getType(err) {
2731
+ return isEvent(err) ? err.constructor.name : "Error";
2732
+ }
2733
+ getValue(err) {
2734
+ if ("name" in err && "string" == typeof err.name) {
2735
+ let message = `'${err.name}' captured as exception`;
2736
+ if ("message" in err && "string" == typeof err.message) message += ` with message: '${err.message}'`;
2737
+ return message;
2738
+ }
2739
+ if ("message" in err && "string" == typeof err.message) return err.message;
2740
+ const className = this.getObjectClassName(err);
2741
+ const keys = extractExceptionKeysForMessage(err);
2742
+ return `${className && "Object" !== className ? `'${className}'` : "Object"} captured as exception with keys: ${keys}`;
2743
+ }
2744
+ isSeverityLevel(x) {
2745
+ return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
2746
+ }
2747
+ getErrorPropertyFromObject(obj) {
2748
+ for (const prop in obj) if (Object.prototype.hasOwnProperty.call(obj, prop)) {
2749
+ const value = obj[prop];
2750
+ if (isError(value)) return value;
2751
+ }
2752
+ }
2753
+ getObjectClassName(obj) {
2754
+ try {
2755
+ const prototype = Object.getPrototypeOf(obj);
2756
+ return prototype ? prototype.constructor.name : void 0;
2757
+ } catch (e) {
2758
+ return;
2759
+ }
2760
+ }
2761
+ };
2762
+
2763
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
2764
+ var EventCoercer = class {
2765
+ match(err) {
2766
+ return isEvent(err);
2767
+ }
2768
+ coerce(evt, ctx) {
2769
+ const constructorName = evt.constructor.name;
2770
+ return {
2771
+ type: constructorName,
2772
+ value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,
2773
+ stack: ctx.syntheticException?.stack,
2774
+ synthetic: true
2775
+ };
2776
+ }
2777
+ };
2778
+
2779
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
2780
+ var PrimitiveCoercer = class {
2781
+ match(candidate) {
2782
+ return isPrimitive(candidate);
2783
+ }
2784
+ coerce(value, ctx) {
2785
+ return {
2786
+ type: "Error",
2787
+ value: `Primitive value captured as exception: ${String(value)}`,
2788
+ stack: ctx.syntheticException?.stack,
2789
+ synthetic: true
2790
+ };
2791
+ }
2792
+ };
2793
+
2794
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
2795
+ var PromiseRejectionEventCoercer = class {
2796
+ match(err) {
2797
+ return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
2798
+ }
2799
+ isCustomEventWrappingRejection(err) {
2800
+ if (!isEvent(err)) return false;
2801
+ try {
2802
+ const detail = err.detail;
2803
+ return null != detail && "object" == typeof detail && "reason" in detail;
2804
+ } catch {
2805
+ return false;
2806
+ }
2807
+ }
2808
+ coerce(err, ctx) {
2809
+ const reason = this.getUnhandledRejectionReason(err);
2810
+ if (isPrimitive(reason)) return {
2811
+ type: "UnhandledRejection",
2812
+ value: `Non-Error promise rejection captured with value: ${String(reason)}`,
2813
+ stack: ctx.syntheticException?.stack,
2814
+ synthetic: true
2815
+ };
2816
+ return ctx.apply(reason);
2817
+ }
2818
+ getUnhandledRejectionReason(error) {
2819
+ try {
2820
+ if ("reason" in error) return error.reason;
2821
+ if ("detail" in error && null != error.detail && "object" == typeof error.detail && "reason" in error.detail) return error.detail.reason;
2822
+ } catch {
2823
+ }
2824
+ return error;
2825
+ }
2826
+ };
2827
+
2828
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/utils.mjs
2829
+ var ReduceableCache = class {
2830
+ constructor(_maxSize) {
2831
+ this._maxSize = _maxSize;
2832
+ this._cache = /* @__PURE__ */ new Map();
2833
+ }
2834
+ get(key) {
2835
+ const value = this._cache.get(key);
2836
+ if (void 0 === value) return;
2837
+ this._cache.delete(key);
2838
+ this._cache.set(key, value);
2839
+ return value;
2840
+ }
2841
+ set(key, value) {
2842
+ this._cache.set(key, value);
2843
+ }
2844
+ reduce() {
2845
+ while (this._cache.size >= this._maxSize) {
2846
+ const value = this._cache.keys().next().value;
2847
+ if (value) this._cache.delete(value);
2848
+ }
2849
+ }
2850
+ };
2851
+
2852
+ // ../node_modules/.pnpm/@posthog+core@1.31.1/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2853
+ var EXCEPTION_STEP_INTERNAL_FIELDS = {
2854
+ MESSAGE: "$message",
2855
+ TIMESTAMP: "$timestamp"
2856
+ };
2857
+ var RESERVED_EXCEPTION_STEP_KEYS = /* @__PURE__ */ new Set([
2858
+ EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE,
2859
+ EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP
2860
+ ]);
2861
+ var DEFAULT_EXCEPTION_STEPS_CONFIG = {
2862
+ enabled: true,
2863
+ max_bytes: 32768
2864
+ };
2865
+ function resolveExceptionStepsConfig(config) {
2866
+ if (!config) return {
2867
+ ...DEFAULT_EXCEPTION_STEPS_CONFIG
2868
+ };
2869
+ return {
2870
+ enabled: config.enabled ?? DEFAULT_EXCEPTION_STEPS_CONFIG.enabled,
2871
+ max_bytes: normalizePositiveInteger(config.max_bytes, DEFAULT_EXCEPTION_STEPS_CONFIG.max_bytes)
2872
+ };
2873
+ }
2874
+ function stripReservedExceptionStepFields(properties) {
2875
+ if (!properties) return {
2876
+ sanitizedProperties: {},
2877
+ droppedKeys: []
2878
+ };
2879
+ const droppedKeys = [];
2880
+ const sanitizedProperties = Object.keys(properties).reduce((acc, key) => {
2881
+ if (RESERVED_EXCEPTION_STEP_KEYS.has(key)) {
2882
+ droppedKeys.push(key);
2883
+ return acc;
2884
+ }
2885
+ acc[key] = properties[key];
2886
+ return acc;
2887
+ }, {});
2888
+ return {
2889
+ sanitizedProperties,
2890
+ droppedKeys
2891
+ };
2892
+ }
2893
+ var ExceptionStepsBuffer = class {
2894
+ constructor(config) {
2895
+ this._entries = [];
2896
+ this._totalBytes = 0;
2897
+ this._config = resolveExceptionStepsConfig(config);
2898
+ }
2899
+ setConfig(config) {
2900
+ this._config = resolveExceptionStepsConfig(config);
2901
+ this._trimToMaxBytes();
2902
+ }
2903
+ add(step) {
2904
+ const serialized = normalizeAndSerializeStep(step);
2905
+ if (!serialized) return;
2906
+ const bytes = getUtf8ByteLength(serialized.json);
2907
+ if (bytes > this._config.max_bytes) return;
2908
+ this._entries.push({
2909
+ step: serialized.step,
2910
+ bytes
2911
+ });
2912
+ this._totalBytes += bytes;
2913
+ this._trimToMaxBytes();
2914
+ }
2915
+ getAttachable() {
2916
+ return this._entries.map((e) => e.step);
2917
+ }
2918
+ clear() {
2919
+ this._entries = [];
2920
+ this._totalBytes = 0;
2921
+ }
2922
+ size() {
2923
+ return this._entries.length;
2924
+ }
2925
+ _trimToMaxBytes() {
2926
+ while (this._totalBytes > this._config.max_bytes && this._entries.length > 0) {
2927
+ const evicted = this._entries.shift();
2928
+ if (evicted) this._totalBytes -= evicted.bytes;
2929
+ }
2930
+ }
2931
+ };
2932
+ function normalizePositiveInteger(input, fallback) {
2933
+ if (!isNumber(input) || input === 1 / 0 || input === -1 / 0) return fallback;
2934
+ const normalized = Math.floor(input);
2935
+ if (normalized < 0) return fallback;
2936
+ return normalized;
2937
+ }
2938
+ function normalizeAndSerializeStep(step) {
2939
+ const json = safeStringify(step);
2940
+ if (!json) return;
2941
+ try {
2942
+ const parsed = JSON.parse(json);
2943
+ if (!isObject(parsed)) return;
2944
+ const parsedStep = parsed;
2945
+ const message = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE];
2946
+ const timestamp = parsedStep[EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP];
2947
+ if (!isString(message) || 0 === message.trim().length) return;
2948
+ if (!isString(timestamp) && !isNumber(timestamp)) return;
2949
+ return {
2950
+ step: parsedStep,
2951
+ json
2952
+ };
2953
+ } catch {
2954
+ return;
2955
+ }
2956
+ }
2957
+ function safeStringify(value) {
2958
+ const seen = /* @__PURE__ */ new WeakSet();
2959
+ try {
2960
+ return JSON.stringify(value, (_key, replacementValue) => {
2961
+ if ("bigint" == typeof replacementValue) return replacementValue.toString();
2962
+ if ("function" == typeof replacementValue || "symbol" == typeof replacementValue) return;
2963
+ if (replacementValue instanceof Date) return replacementValue.toISOString();
2964
+ if (replacementValue instanceof Error) return {
2965
+ name: replacementValue.name,
2966
+ message: replacementValue.message,
2967
+ stack: replacementValue.stack
2968
+ };
2969
+ if (replacementValue && "object" == typeof replacementValue) {
2970
+ if (seen.has(replacementValue)) return "[Circular]";
2971
+ seen.add(replacementValue);
2972
+ }
2973
+ return replacementValue;
2974
+ });
2975
+ } catch {
2976
+ return;
2977
+ }
2978
+ }
2979
+ function getUtf8ByteLength(value) {
2980
+ if ("undefined" != typeof TextEncoder) return new TextEncoder().encode(value).length;
2981
+ const encoded = encodeURIComponent(value);
2982
+ let byteLength = 0;
2983
+ for (let i = 0; i < encoded.length; i++) if ("%" === encoded[i]) {
2984
+ byteLength += 1;
2985
+ i += 2;
2986
+ } else byteLength += 1;
2987
+ return byteLength;
2988
+ }
2989
+
2990
+ // ../node_modules/.pnpm/posthog-node@5.36.10/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
2991
+ var import_node_fs3 = require("fs");
2992
+ var import_node_readline = require("readline");
2993
+ var LRU_FILE_CONTENTS_CACHE = new error_tracking_exports.ReduceableCache(25);
2994
+ var LRU_FILE_CONTENTS_FS_READ_FAILED = new error_tracking_exports.ReduceableCache(20);
2995
+
2996
+ // ../node_modules/.pnpm/posthog-node@5.36.10/node_modules/posthog-node/dist/extensions/context/context.mjs
2997
+ var import_node_async_hooks = require("async_hooks");
2998
+
2999
+ // ../node_modules/.pnpm/posthog-node@5.36.10/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
3000
+ var NAME = "posthog-node";
3001
+ function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
3002
+ "error"
3003
+ ], sendExceptionsToPostHog = true } = {}) {
3004
+ return (event) => {
3005
+ const shouldProcessLevel = "*" === severityAllowList || severityAllowList.includes(event.level);
3006
+ if (!shouldProcessLevel) return event;
3007
+ if (!event.tags) event.tags = {};
3008
+ const userId = event.tags[PostHogSentryIntegration.POSTHOG_ID_TAG];
3009
+ if (void 0 === userId) return event;
3010
+ const uiHost = _posthog.options.host ?? "https://us.i.posthog.com";
3011
+ const personUrl = new URL(`/project/${_posthog.apiKey}/person/${userId}`, uiHost).toString();
3012
+ event.tags["PostHog Person URL"] = personUrl;
3013
+ const exceptions = event.exception?.values || [];
3014
+ const exceptionList = exceptions.map((exception) => ({
3015
+ ...exception,
3016
+ stacktrace: exception.stacktrace ? {
3017
+ ...exception.stacktrace,
3018
+ type: "raw",
3019
+ frames: (exception.stacktrace.frames || []).map((frame) => ({
3020
+ ...frame,
3021
+ platform: "node:javascript"
3022
+ }))
3023
+ } : void 0
3024
+ }));
3025
+ const properties = {
3026
+ $exception_message: exceptions[0]?.value || event.message,
3027
+ $exception_type: exceptions[0]?.type,
3028
+ $exception_level: event.level,
3029
+ $exception_list: exceptionList,
3030
+ $sentry_event_id: event.event_id,
3031
+ $sentry_exception: event.exception,
3032
+ $sentry_exception_message: exceptions[0]?.value || event.message,
3033
+ $sentry_exception_type: exceptions[0]?.type,
3034
+ $sentry_tags: event.tags
3035
+ };
3036
+ if (organization && projectId) properties["$sentry_url"] = (prefix || "https://sentry.io/organizations/") + organization + "/issues/?project=" + projectId + "&query=" + event.event_id;
3037
+ if (sendExceptionsToPostHog) _posthog.capture({
3038
+ event: "$exception",
3039
+ distinctId: userId,
3040
+ properties
3041
+ });
3042
+ return event;
3043
+ };
3044
+ }
3045
+ var PostHogSentryIntegration = class {
3046
+ static #_ = this.POSTHOG_ID_TAG = "posthog_distinct_id";
3047
+ constructor(_posthog, organization, prefix, severityAllowList, sendExceptionsToPostHog) {
3048
+ this.name = NAME;
3049
+ this.name = NAME;
3050
+ this.setupOnce = function(addGlobalEventProcessor, getCurrentHub) {
3051
+ const projectId = getCurrentHub()?.getClient()?.getDsn()?.projectId;
3052
+ addGlobalEventProcessor(createEventProcessor(_posthog, {
3053
+ organization,
3054
+ projectId,
3055
+ prefix,
3056
+ severityAllowList,
3057
+ sendExceptionsToPostHog: sendExceptionsToPostHog ?? true
3058
+ }));
3059
+ };
3060
+ }
3061
+ };
3062
+
3063
+ // src/telemetry/posthog.ts
3064
+ var POSTHOG_KEY = process.env["ARCHAL_POSTHOG_KEY"] ?? "phc_OEdBZlIiJUhnj5dOBsCf9qyXQmbf6RGYIl7k5BcNKn4";
3065
+ var baseProperties = {
3066
+ cli_version: CLI_VERSION,
3067
+ os_platform: process.platform,
3068
+ node_version: process.version,
3069
+ source: "cli"
3070
+ };
3071
+
3072
+ // src/commands/autoloop-github-app.ts
3073
+ var import_node_crypto4 = require("crypto");
3074
+
3075
+ // src/trace-source/redaction.ts
3076
+ var TRACE_REDACTED = "[REDACTED]";
3077
+ var DEFAULT_SENSITIVE_TRACE_KEY_PARTS = [
3078
+ "token",
3079
+ "secret",
3080
+ "password",
3081
+ "authorization",
3082
+ "apikey",
3083
+ "api-key",
3084
+ "api_key",
3085
+ "credential",
3086
+ "cookie",
3087
+ "privatekey",
3088
+ "private-key",
3089
+ "private_key",
3090
+ "accesskey",
3091
+ "access-key",
3092
+ "access_key",
3093
+ "databaseurl",
3094
+ "database-url",
3095
+ "database_url",
3096
+ "dburl",
3097
+ "db-url",
3098
+ "db_url",
3099
+ "connectionstring",
3100
+ "connection-string",
3101
+ "connection_string",
3102
+ "dsn",
3103
+ "card",
3104
+ "cardnumber",
3105
+ "creditcard",
3106
+ "pan"
3107
+ ];
3108
+ var DEFAULT_SECRET_TRACE_STRING_PATTERNS = [
3109
+ {
3110
+ pattern: /\b(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}\b/gi,
3111
+ replacement: `$1${TRACE_REDACTED}`
3112
+ },
3113
+ {
3114
+ pattern: /\bgh[pousr]_[A-Za-z0-9]{16,}\b/g
3115
+ },
3116
+ {
3117
+ pattern: /\bgithub_pat_[A-Za-z0-9_]{16,}\b/g
3118
+ },
3119
+ {
3120
+ pattern: /\bsk_(?:live|test)_[A-Za-z0-9]{16,}\b/g
3121
+ },
3122
+ {
3123
+ pattern: /\bsk-proj-[A-Za-z0-9_-]{16,}\b/g
3124
+ },
3125
+ {
3126
+ pattern: /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g
3127
+ },
3128
+ {
3129
+ pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g
3130
+ },
3131
+ {
3132
+ pattern: /\b(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis|rediss):\/\/[^\s"'<>]+/gi,
3133
+ replacement: "[CONNECTION_URL_REDACTED]"
3134
+ },
3135
+ {
3136
+ pattern: /\b(https?:\/\/)[^/\s"'<>@]+@/gi,
3137
+ replacement: `$1${TRACE_REDACTED}@`
3138
+ },
3139
+ {
3140
+ pattern: /\bAIza[0-9A-Za-z_-]{12,}\b/g
3141
+ },
3142
+ {
3143
+ pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g
3144
+ },
3145
+ {
3146
+ pattern: /\bx(?:app|oxa|oxc|oxp|oxs)-[A-Za-z0-9-]{10,}\b/g
3147
+ },
3148
+ {
3149
+ pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g
3150
+ },
3151
+ {
3152
+ pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9._-]{10,}\.[A-Za-z0-9._-]{10,}\b/g
3153
+ },
3154
+ {
3155
+ pattern: /-----BEGIN(?:[ A-Z]+)?PRIVATE KEY-----[\s\S]*?-----END(?:[ A-Z]+)?PRIVATE KEY-----/g
3156
+ },
3157
+ {
3158
+ pattern: /(^|[?&])((?:token|access_token|refresh_token|client_secret|secret|api_key|apikey|password|signature|sig|x-amz-signature|x-goog-signature|awsaccesskeyid|sv|se|sp)=)[^&\s]+/gi,
3159
+ replacement: `$1$2${TRACE_REDACTED}`
3160
+ },
3161
+ {
3162
+ pattern: /\b((?:"?(?:authorization|token|access_token|refresh_token|client_secret|secret|api_key|apikey|password|private_key|privatekey|database_url|databaseurl|db_url|dburl|connection_string|connectionstring|dsn)"?\s*[:=]\s*)(?!\[[A-Za-z0-9_ -]+\]))(?:"[^"]+"|'[^']+'|Bearer\s+\[[A-Za-z0-9_ -]+\]|Bearer\s+[^\s,}\]]+|[^\s,}\]]+)/gi,
3163
+ replacement: `$1${TRACE_REDACTED}`
3164
+ },
3165
+ {
3166
+ pattern: /\b([A-Z0-9_]*(?:API_KEY|SECRET_KEY|ACCESS_KEY|ACCESS_TOKEN|REFRESH_TOKEN|AUTH_TOKEN|BEARER_TOKEN|TOKEN|PASSWORD|SECRET|PRIVATE_KEY)[A-Z0-9_]*\s*[:=]\s*)(?!\[[A-Za-z0-9_ -]+\])(?:"[^"]+"|'[^']+'|[^\s,}\]]+)/g,
3167
+ replacement: `$1${TRACE_REDACTED}`
3168
+ }
3169
+ ];
3170
+ var DEFAULT_TRACE_REDACTION_POLICY = {
3171
+ enabled: true,
3172
+ mode: "mask",
3173
+ replacement: TRACE_REDACTED,
3174
+ sensitiveKeyParts: DEFAULT_SENSITIVE_TRACE_KEY_PARTS,
3175
+ stringPatterns: DEFAULT_SECRET_TRACE_STRING_PATTERNS,
3176
+ maxDepth: 24
3177
+ };
3178
+ function normalizeTraceRedactionPolicy(policy) {
3179
+ return {
3180
+ ...DEFAULT_TRACE_REDACTION_POLICY,
3181
+ ...policy,
3182
+ sensitiveKeyParts: policy?.sensitiveKeyParts ?? DEFAULT_TRACE_REDACTION_POLICY.sensitiveKeyParts,
3183
+ stringPatterns: policy?.stringPatterns ?? DEFAULT_TRACE_REDACTION_POLICY.stringPatterns
3184
+ };
3185
+ }
3186
+ function redactTraceString(value, policy = DEFAULT_TRACE_REDACTION_POLICY) {
3187
+ const normalizedPolicy = normalizeTraceRedactionPolicy(policy);
3188
+ if (!normalizedPolicy.enabled) {
3189
+ return value;
3190
+ }
3191
+ let redacted = value;
3192
+ for (const { pattern, replacement } of normalizedPolicy.stringPatterns) {
3193
+ const effectiveReplacement = replacement ? replacement.replaceAll(TRACE_REDACTED, normalizedPolicy.replacement) : normalizedPolicy.replacement;
3194
+ redacted = redacted.replace(pattern, effectiveReplacement);
3195
+ }
3196
+ return redacted;
3197
+ }
3198
+
3199
+ // src/commands/github-rest.ts
3200
+ function normalizeRepositoryFullName(value) {
3201
+ const trimmed = value?.trim();
3202
+ if (!trimmed || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(trimmed)) return void 0;
3203
+ return trimmed;
3204
+ }
3205
+
3206
+ // src/commands/autoloop-github-app.ts
3207
+ var GITHUB_APP_INSTALLATION_PERMISSIONS = {
3208
+ actions: "read",
3209
+ checks: "read",
3210
+ contents: "write",
3211
+ issues: "write",
3212
+ metadata: "read",
3213
+ pull_requests: "write",
3214
+ statuses: "read"
3215
+ };
3216
+ var DEFAULT_GITHUB_APP_TOKEN_TIMEOUT_MS = 1e4;
3217
+ function isDirectGithubAppKeyAllowed(env = process.env) {
3218
+ return (env["ARCHAL_AUTOLOOP_ALLOW_DIRECT_GITHUB_APP_KEY"] ?? "").trim().toLowerCase() === "true";
3219
+ }
3220
+ async function resolveAutoloopInstallationToken(input, options = {}) {
3221
+ const resolution = await resolveAutoloopInstallationTokenWithDiagnostics(input, options);
3222
+ return resolution?.token;
3223
+ }
3224
+ async function resolveAutoloopInstallationTokenWithDiagnostics(input, options = {}) {
3225
+ const env = options.env ?? process.env;
3226
+ const explicitToken = env["GITHUB_INSTALLATION_TOKEN"]?.trim();
3227
+ if (explicitToken) return { token: explicitToken };
3228
+ const fetchImpl = withGithubAppTokenTimeout(options.fetchImpl ?? fetch, env);
3229
+ const archalToken = options.archalToken ?? env["ARCHAL_TOKEN"]?.trim();
3230
+ const archalBaseUrl = options.archalBaseUrl ?? env["ARCHAL_GITHUB_APP_BASE_URL"]?.trim() ?? env["ARCHAL_AUTH_BASE_URL"]?.trim() ?? env["ARCHAL_API_BASE_URL"]?.trim();
3231
+ const hosted = await resolveArchalGithubAppInstallationTokenWithDiagnostics({
3232
+ repository: input.repository,
3233
+ archalToken,
3234
+ archalBaseUrl,
3235
+ fetchImpl
3236
+ });
3237
+ if (hosted?.token) return hosted;
3238
+ if (isDirectGithubAppKeyAllowed(env)) {
3239
+ const direct = await resolveGithubAppInstallationToken({
3240
+ repository: input.repository,
3241
+ installationId: input.installationId,
3242
+ env,
3243
+ fetchImpl
3244
+ });
3245
+ if (direct?.token) return direct;
3246
+ }
3247
+ return hosted?.failure ? { failure: hosted.failure } : void 0;
3248
+ }
3249
+ async function resolveGithubAppInstallationToken(input) {
3250
+ const repository = normalizeRepositoryFullName(input.repository);
3251
+ if (!repository) return void 0;
3252
+ const env = input.env ?? process.env;
3253
+ const appId = env["ARCHAL_GITHUB_APP_ID"]?.trim();
3254
+ const privateKey = env["ARCHAL_GITHUB_APP_PRIVATE_KEY"]?.trim();
3255
+ if (!appId || !privateKey) return void 0;
3256
+ const installationId = input.installationId?.trim();
3257
+ if (!installationId || !/^\d+$/.test(installationId)) return void 0;
3258
+ const [, repo] = repository.split("/");
3259
+ const fetchImpl = withGithubAppTokenTimeout(input.fetchImpl ?? fetch, env);
3260
+ const jwt = buildGithubAppJwt({ appId, privateKey });
3261
+ const tokenResponse = await fetchImpl(
3262
+ `https://api.github.com/app/installations/${installationId}/access_tokens`,
3263
+ {
3264
+ method: "POST",
3265
+ headers: githubHeaders(jwt, { "content-type": "application/json" }),
3266
+ body: JSON.stringify({
3267
+ repositories: [repo],
3268
+ permissions: GITHUB_APP_INSTALLATION_PERMISSIONS
3269
+ })
3270
+ }
3271
+ );
3272
+ if (!tokenResponse.ok) return void 0;
3273
+ const payload = await tokenResponse.json().catch(() => ({}));
3274
+ const token = String(payload["token"] ?? "").trim();
3275
+ const expiresAt = String(payload["expires_at"] ?? "").trim();
3276
+ return token ? { token, expiresAt: expiresAt || void 0 } : void 0;
3277
+ }
3278
+ async function resolveArchalGithubAppInstallationTokenWithDiagnostics(input) {
3279
+ const repository = normalizeRepositoryFullName(input.repository);
3280
+ if (!repository || !input.archalToken || !input.archalBaseUrl) return void 0;
3281
+ const fetchImpl = withGithubAppTokenTimeout(input.fetchImpl ?? fetch);
3282
+ const response = await fetchImpl(
3283
+ new URL("/api/workspaces/current/integrations/github/installation-token", input.archalBaseUrl),
3284
+ {
3285
+ method: "POST",
3286
+ headers: { authorization: `Bearer ${input.archalToken}`, "content-type": "application/json" },
3287
+ body: JSON.stringify({ repository })
3288
+ }
3289
+ );
3290
+ const payload = await response.json().catch(() => ({}));
3291
+ const token = String(payload["token"] ?? "").trim();
3292
+ const expiresAt = String(payload["expiresAt"] ?? "").trim();
3293
+ if (response.ok && token) {
3294
+ return { token, expiresAt: expiresAt || void 0 };
3295
+ }
3296
+ return {
3297
+ failure: hostedGithubAppTokenFailure(response, payload)
3298
+ };
3299
+ }
3300
+ function withGithubAppTokenTimeout(fetchImpl, env = process.env) {
3301
+ return (async (input, init) => {
3302
+ const timeoutMs = resolveGithubAppTokenTimeoutMs(env);
3303
+ const controller = new AbortController();
3304
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
3305
+ timeout.unref?.();
3306
+ try {
3307
+ return await fetchImpl(input, { ...init, signal: controller.signal });
3308
+ } catch (error) {
3309
+ if (controller.signal.aborted) {
3310
+ throw new Error("autoloop_github_app_token_request_timeout");
3311
+ }
3312
+ throw error;
3313
+ } finally {
3314
+ clearTimeout(timeout);
3315
+ }
3316
+ });
3317
+ }
3318
+ function resolveGithubAppTokenTimeoutMs(env) {
3319
+ const raw = env["ARCHAL_AUTOLOOP_GITHUB_APP_TOKEN_TIMEOUT_MS"]?.trim();
3320
+ if (!raw) return DEFAULT_GITHUB_APP_TOKEN_TIMEOUT_MS;
3321
+ const timeoutMs = Number(raw);
3322
+ return Number.isInteger(timeoutMs) && timeoutMs >= 100 ? timeoutMs : DEFAULT_GITHUB_APP_TOKEN_TIMEOUT_MS;
3323
+ }
3324
+ function githubHeaders(jwt, extra = {}) {
3325
+ return {
3326
+ accept: "application/vnd.github+json",
3327
+ authorization: `Bearer ${jwt}`,
3328
+ "x-github-api-version": "2022-11-28",
3329
+ ...extra
3330
+ };
3331
+ }
3332
+ function hostedGithubAppTokenFailure(response, payload) {
3333
+ const record = isRecord(payload) ? payload : {};
3334
+ const code = safeHostedFailurePart(
3335
+ stringField(record, "error") ?? stringField(record, "code") ?? (response.ok ? "missing_token" : `http_${response.status}`),
3336
+ "unknown"
3337
+ );
3338
+ const message = safeHostedFailurePart(
3339
+ stringField(record, "detail") ?? stringField(record, "message") ?? (response.ok ? "hosted minter response did not include a token" : void 0),
3340
+ ""
3341
+ );
3342
+ return {
3343
+ source: "hosted",
3344
+ code,
3345
+ status: response.status,
3346
+ ...message ? { message } : {}
3347
+ };
3348
+ }
3349
+ function stringField(record, key) {
3350
+ const value = record[key];
3351
+ return typeof value === "string" && value.trim() ? value : void 0;
3352
+ }
3353
+ function safeHostedFailurePart(value, fallback) {
3354
+ const redacted = redactTraceString(value ?? "").replace(/\s+/g, " ").trim();
3355
+ if (!redacted) return fallback;
3356
+ return redacted.length > 220 ? `${redacted.slice(0, 217)}...` : redacted;
3357
+ }
3358
+ function isRecord(value) {
3359
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3360
+ }
3361
+ function buildGithubAppJwt(input) {
3362
+ const now = Math.floor(Date.now() / 1e3);
3363
+ const header = base64UrlJson({ alg: "RS256", typ: "JWT" });
3364
+ const payload = base64UrlJson({
3365
+ iat: now - 60,
3366
+ exp: now + 9 * 60,
3367
+ iss: input.appId
3368
+ });
3369
+ const signingInput = `${header}.${payload}`;
3370
+ const signature = (0, import_node_crypto4.createSign)("RSA-SHA256").update(signingInput).end().sign(normalizePem2(input.privateKey), "base64url");
3371
+ return `${signingInput}.${signature}`;
3372
+ }
3373
+ function base64UrlJson(value) {
3374
+ return Buffer.from(JSON.stringify(value)).toString("base64url");
3375
+ }
3376
+ function normalizePem2(value) {
3377
+ return value.replace(/\\n/g, "\n").replace(/\\\r?\n/g, "\n").replace(/\\/g, "\n");
3378
+ }
3379
+
3380
+ // src/shared/evidence-redaction.ts
3381
+ var import_node_crypto5 = require("crypto");
3382
+ var EVIDENCE_REDACTED = "[REDACTED]";
3383
+ var EVIDENCE_SENSITIVE_KEY_PARTS = /* @__PURE__ */ new Set([
3384
+ "token",
3385
+ "secret",
3386
+ "password",
3387
+ "authorization",
3388
+ "apikey",
3389
+ "api_key",
3390
+ "credential",
3391
+ "cookie",
3392
+ "privatekey",
3393
+ "private_key",
3394
+ "accesskey",
3395
+ "access_key",
3396
+ "databaseurl",
3397
+ "database_url",
3398
+ "dburl",
3399
+ "db_url",
3400
+ "redisurl",
3401
+ "redis_url",
3402
+ "mongodburi",
3403
+ "mongo_uri",
3404
+ "connectionstring",
3405
+ "connection_string",
3406
+ "dsn",
3407
+ "workspacekey",
3408
+ "workspace_key",
3409
+ "workspacetoken",
3410
+ "workspace_token",
3411
+ "secretref",
3412
+ "secret_ref",
3413
+ "secretname",
3414
+ "secret_name"
3415
+ ]);
3416
+ var EVIDENCE_SENSITIVE_ENV_KEY_PARTS = /* @__PURE__ */ new Set([
3417
+ ...EVIDENCE_SENSITIVE_KEY_PARTS,
3418
+ "apikey",
3419
+ "api_key",
3420
+ "secretkey",
3421
+ "secret_key",
3422
+ "accesstoken",
3423
+ "access_token",
3424
+ "refreshtoken",
3425
+ "refresh_token",
3426
+ "authtoken",
3427
+ "auth_token",
3428
+ "bearertoken",
3429
+ "bearer_token",
3430
+ "privatekey",
3431
+ "private_key",
3432
+ "databaseurl",
3433
+ "database_url",
3434
+ "dburl",
3435
+ "db_url",
3436
+ "redisurl",
3437
+ "redis_url",
3438
+ "mongodburi",
3439
+ "mongo_uri",
3440
+ "connectionstring",
3441
+ "connection_string",
3442
+ "dsn"
3443
+ ]);
3444
+ var EVIDENCE_SERVICE_STRING_PATTERNS = [
3445
+ {
3446
+ pattern: /https?:\/\/[^\s"'<>]+\/runtime\/session\/[^\s"'<>]*/gi,
3447
+ replacement: "[SERVICE_ENDPOINT_REDACTED]"
3448
+ },
3449
+ {
3450
+ pattern: /\/runtime\/session\/[^\s"'<>]*/gi,
3451
+ replacement: "[SERVICE_ENDPOINT_REDACTED]"
3452
+ },
3453
+ {
3454
+ pattern: /\bx-archal-[\w-]+(?::|=)\s*["']?[^"',\s}]+/gi,
3455
+ replacement: "[SERVICE_HEADER_REDACTED]"
3456
+ },
3457
+ {
3458
+ pattern: /\barchal_mcp_servers\b/gi,
3459
+ replacement: "service_tool_servers"
3460
+ },
3461
+ {
3462
+ pattern: /\bARCHAL_(?:CLONE_URLS_PATH|TWIN_URLS_PATH|PROXY_EVENTS_PATH|METRICS_FILE|AGENT_TRACE_FILE|ENABLE_PROVIDER_EGRESS_PROXY)\b/g,
3463
+ replacement: "[SERVICE_RUNTIME_CONFIG_REDACTED]"
3464
+ },
3465
+ {
3466
+ pattern: /\/archal-artifacts\/[^\s"'<>]*/gi,
3467
+ replacement: "[SERVICE_ARTIFACT_PATH_REDACTED]"
3468
+ },
3469
+ {
3470
+ pattern: /\b(?:host\.docker\.internal|localhost|127\.0\.0\.1):9100\b/gi,
3471
+ replacement: "[SERVICE_PROXY_ENDPOINT_REDACTED]"
3472
+ },
3473
+ {
3474
+ pattern: /\b(?:aws-secretsmanager:\/\/|arn:aws:secretsmanager:[^\s"'<>:]+:\d{12}:secret:)[^\s"'<>]+/gi,
3475
+ replacement: "[SECRET_REF_REDACTED]"
3476
+ },
3477
+ {
3478
+ pattern: /\benv:[A-Z0-9_]*(?:API_KEY|SECRET_KEY|SECRET_NAME|SECRET_REF|ACCESS_KEY|ACCESS_TOKEN|REFRESH_TOKEN|AUTH_TOKEN|BEARER_TOKEN|TOKEN|PASSWORD|SECRET|PRIVATE_KEY|DATABASE_URL|DB_URL|REDIS_URL|MONGO_URI|CONNECTION_STRING|DSN|WORKSPACE_TOKEN|WORKSPACE_KEY)[A-Z0-9_]*\b/g,
3479
+ replacement: "[SECRET_REF_REDACTED]"
3480
+ },
3481
+ {
3482
+ pattern: /(?:file:\/\/)?(?:\/Users\/[^/\s"'<>]+|\/home\/[^/\s"'<>]+|\/private\/tmp|\/tmp|\/var\/folders|\/workspace|\/workspaces)(?:\/[^\s"'<>]*)?/g,
3483
+ replacement: "[LOCAL_PATH_REDACTED]"
3484
+ },
3485
+ {
3486
+ pattern: /\b[A-Za-z]:\\Users\\[^\\\s"'<>]+(?:\\[^\s"'<>]*)?/g,
3487
+ replacement: "[LOCAL_PATH_REDACTED]"
3488
+ }
3489
+ ];
3490
+ var EVIDENCE_SECRET_LITERAL_STRING_PATTERNS = [
3491
+ {
3492
+ pattern: /\b(Bearer\s+)[A-Za-z0-9._~+/=-]+\b/gi,
3493
+ replacement: `$1${EVIDENCE_REDACTED}`
3494
+ },
3495
+ {
3496
+ pattern: /\b(gh[pousr]_[A-Za-z0-9]{16,})\b/g,
3497
+ replacement: EVIDENCE_REDACTED
3498
+ },
3499
+ {
3500
+ pattern: /\bgithub_pat_[A-Za-z0-9_]{16,}\b/g,
3501
+ replacement: EVIDENCE_REDACTED
3502
+ },
3503
+ {
3504
+ pattern: /\bsk_(?:live|test)_[A-Za-z0-9]{16,}\b/g,
3505
+ replacement: EVIDENCE_REDACTED
3506
+ },
3507
+ {
3508
+ pattern: /\bsk-proj-[A-Za-z0-9_-]{16,}\b/g,
3509
+ replacement: EVIDENCE_REDACTED
3510
+ },
3511
+ {
3512
+ pattern: /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
3513
+ replacement: EVIDENCE_REDACTED
3514
+ },
3515
+ {
3516
+ pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g,
3517
+ replacement: EVIDENCE_REDACTED
3518
+ },
3519
+ {
3520
+ pattern: /\barchal_(?:ws|workspace|token|key|pat|secret)_[A-Za-z0-9_.-]{8,}\b/gi,
3521
+ replacement: EVIDENCE_REDACTED
3522
+ },
3523
+ {
3524
+ pattern: /\bsb_(?:secret|publishable)_[A-Za-z0-9_-]{16,}\b/g,
3525
+ replacement: EVIDENCE_REDACTED
3526
+ },
3527
+ {
3528
+ pattern: /\bpostgres(?:ql)?:\/\/[^\s"'<>]+/gi,
3529
+ replacement: "[DATABASE_URL_REDACTED]"
3530
+ },
3531
+ {
3532
+ pattern: /\b(?:redis|rediss|mysql|mariadb|mongodb(?:\+srv)?|amqp|amqps):\/\/[^\s"'<>]+/gi,
3533
+ replacement: "[CONNECTION_STRING_REDACTED]"
3534
+ },
3535
+ {
3536
+ pattern: /\b[A-Za-z][A-Za-z0-9+.-]*:\/\/[^:\s/@]+:[^@\s/]+@[^\s"'<>]+/gi,
3537
+ replacement: "[BASIC_AUTH_URL_REDACTED]"
3538
+ },
3539
+ {
3540
+ pattern: /\bAIza[0-9A-Za-z_-]{12,}\b/g,
3541
+ replacement: EVIDENCE_REDACTED
3542
+ },
3543
+ {
3544
+ pattern: /\b(?:xox[baprs]-[A-Za-z0-9-]{10,})\b/g,
3545
+ replacement: EVIDENCE_REDACTED
3546
+ },
3547
+ {
3548
+ pattern: /\bx(?:app|oxa|oxc|oxp|oxs)-[A-Za-z0-9-]{10,}\b/g,
3549
+ replacement: EVIDENCE_REDACTED
3550
+ },
3551
+ {
3552
+ pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
3553
+ replacement: EVIDENCE_REDACTED
3554
+ },
3555
+ {
3556
+ pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9._-]{10,}\.[A-Za-z0-9._-]{10,}\b/g,
3557
+ replacement: EVIDENCE_REDACTED
3558
+ },
3559
+ {
3560
+ pattern: /-----BEGIN(?:[ A-Z]+)?PRIVATE KEY-----[\s\S]*?-----END(?:[ A-Z]+)?PRIVATE KEY-----/g,
3561
+ replacement: EVIDENCE_REDACTED
3562
+ },
3563
+ {
3564
+ pattern: /(^|[?&])((?:token|access_token|refresh_token|client_secret|secret|api_key|apikey|password)=)[^&\s]+/gi,
3565
+ replacement: `$1$2${EVIDENCE_REDACTED}`
3566
+ }
3567
+ ];
3568
+ var EVIDENCE_KEY_VALUE_STRING_PATTERNS = [
3569
+ {
3570
+ pattern: /\b((?:"?(?:authorization|token|access_token|refresh_token|client_secret|secret|secret_ref|secretref|secret_name|secretname|api_key|apikey|password|private_key|privatekey|database_url|databaseurl|db_url|dburl|redis_url|redisurl|mongo_uri|mongodburi|connection_string|connectionstring|dsn|workspace_token|workspacetoken|workspace_key|workspacekey)"?\s*[:=]\s*)(?!\[[A-Z0-9_]+\]))(?:"[^"]+"|'[^']+'|Bearer\s+\[REDACTED\]|Bearer\s+[^\s,}\]]+|[^\s,}\]]+)/gi,
3571
+ replacement: `$1${EVIDENCE_REDACTED}`
3572
+ },
3573
+ {
3574
+ pattern: /\b([A-Z0-9_]*(?:API_KEY|SECRET_KEY|SECRET_NAME|SECRET_REF|ACCESS_KEY|ACCESS_TOKEN|REFRESH_TOKEN|AUTH_TOKEN|BEARER_TOKEN|TOKEN|PASSWORD|SECRET|PRIVATE_KEY|DATABASE_URL|DB_URL|REDIS_URL|MONGO_URI|CONNECTION_STRING|DSN|WORKSPACE_TOKEN|WORKSPACE_KEY)[A-Z0-9_]*\s*[:=]\s*)(?!\[[A-Z0-9_]+\])(?:"[^"]+"|'[^']+'|[^\s,}\]]+)/g,
3575
+ replacement: `$1${EVIDENCE_REDACTED}`
3576
+ }
3577
+ ];
3578
+ var EVIDENCE_SECRET_NAME_STRING_PATTERNS = [
3579
+ {
3580
+ pattern: /(?<!\[)\b[A-Z0-9_]*(?:API_KEY|SECRET_KEY|SECRET_NAME|SECRET_REF|ACCESS_KEY|ACCESS_TOKEN|REFRESH_TOKEN|AUTH_TOKEN|BEARER_TOKEN|TOKEN|PASSWORD|SECRET|PRIVATE_KEY|DATABASE_URL|DB_URL|REDIS_URL|MONGO_URI|CONNECTION_STRING|DSN|WORKSPACE_TOKEN|WORKSPACE_KEY)[A-Z0-9_]*\b/g,
3581
+ replacement: "[SECRET_NAME_REDACTED]"
3582
+ }
3583
+ ];
3584
+ var EVIDENCE_STRING_PATTERNS = [
3585
+ ...EVIDENCE_SERVICE_STRING_PATTERNS,
3586
+ ...EVIDENCE_SECRET_LITERAL_STRING_PATTERNS,
3587
+ ...EVIDENCE_KEY_VALUE_STRING_PATTERNS,
3588
+ ...EVIDENCE_SECRET_NAME_STRING_PATTERNS
3589
+ ];
3590
+
3591
+ // src/commands/autoloop-fix-pr-quality.ts
3592
+ function assessFixPrPayload(payload, input = {}) {
3593
+ const assessment = assessAutoloopStoredFixPrEvidence(payload, {
3594
+ expectedCommitSha: input.prHeadSha ?? null
3595
+ });
3596
+ return {
3597
+ passed: assessment.passed,
3598
+ reason: assessment.reason,
3599
+ fixQuality: assessment.fixQuality,
3600
+ postFixReproduction: assessment.postFixReproduction,
3601
+ prBodyQuality: prBodyQualityWithIssues(assessment.prBodyQuality)
3602
+ };
3603
+ }
3604
+ function prBodyQualityWithIssues(evidence) {
3605
+ return {
3606
+ ...evidence,
3607
+ issues: evidence.status === "passed" ? [] : [evidence.reason]
3608
+ };
3609
+ }
3610
+
3611
+ // src/commands/autoloop-pr-verification.ts
3612
+ async function verifyFixResult(result, input) {
3613
+ if (!result.prUrl) return result;
3614
+ const pr = parseGithubPrUrl(result.prUrl);
3615
+ if (!pr || `${pr.owner}/${pr.repo}`.toLowerCase() !== input.repositoryFullName.toLowerCase()) {
3616
+ return {
3617
+ ...result,
3618
+ status: "blocked",
3619
+ prUrl: null,
3620
+ latestCheckState: "blocked",
3621
+ blockingReason: "reported_pr_repository_mismatch",
3622
+ summary: `${result.summary} Reported PR URL does not belong to ${input.repositoryFullName}.`
3623
+ };
3624
+ }
3625
+ if (result.status !== "checks_passing") {
3626
+ if (result.status === "pr_open") {
3627
+ const token2 = await resolveVerificationToken(input);
3628
+ const verdict = await confirmPrIsOpen(pr, token2);
3629
+ if (verdict.state === "not_open") {
3630
+ return {
3631
+ ...result,
3632
+ status: "blocked",
3633
+ prUrl: null,
3634
+ latestCheckState: "blocked",
3635
+ blockingReason: "reported_pr_not_found",
3636
+ summary: `${result.summary} Reported open PR could not be confirmed.`
3637
+ };
3638
+ }
3639
+ if (verdict.state === "unverifiable") {
3640
+ return {
3641
+ ...result,
3642
+ status: "blocked",
3643
+ prUrl: null,
3644
+ latestCheckState: "blocked",
3645
+ blockingReason: "reported_pr_unverifiable",
3646
+ summary: `${result.summary} Reported open PR could not be verified.`
3647
+ };
3648
+ }
3649
+ const postFixReproduction2 = autoloopPostFixReproductionEvidenceFromPayload(result.payload, {
3650
+ expectedCommitSha: verdict.headSha
3651
+ });
3652
+ if (!postFixReproduction2.passed) {
3653
+ return {
3654
+ ...result,
3655
+ status: "blocked",
3656
+ prUrl: null,
3657
+ latestCheckState: "blocked",
3658
+ blockingReason: postFixReproduction2.reason,
3659
+ summary: `${result.summary} PR not surfaced as post-fix clone reproduction evidence is insufficient: ${postFixReproduction2.reason}.`
3660
+ };
3661
+ }
3662
+ const mismatch2 = prReferenceMatchFailure(result, input.repositoryFullName, verdict, input);
3663
+ if (mismatch2) {
3664
+ return blockedFixResult(
3665
+ result,
3666
+ mismatch2,
3667
+ `Reported PR repository or branch is not verified: ${mismatch2}.`
3668
+ );
3669
+ }
3670
+ }
3671
+ return result;
3672
+ }
3673
+ const initialPostFixReproduction = autoloopPostFixReproductionEvidenceFromPayload(result.payload);
3674
+ if (!initialPostFixReproduction.passed) {
3675
+ return {
3676
+ ...result,
3677
+ status: "blocked",
3678
+ prUrl: null,
3679
+ latestCheckState: "blocked",
3680
+ blockingReason: initialPostFixReproduction.reason,
3681
+ summary: `${result.summary} Post-fix clone reproduction evidence is insufficient: ${initialPostFixReproduction.reason}.`
3682
+ };
3683
+ }
3684
+ const token = await resolveVerificationToken(input);
3685
+ const checks = token ? await fetchGithubPrChecks(pr, token).catch(() => unverifiedGithubPrChecks()) : unverifiedGithubPrChecks();
3686
+ if (checks.state === "unverified") {
3687
+ return {
3688
+ ...result,
3689
+ status: "pr_open",
3690
+ latestCheckState: "unknown",
3691
+ summary: `${result.summary} PR checks could not be verified yet.`
3692
+ };
3693
+ }
3694
+ if (checks.state === "not_open") {
3695
+ return blockedFixResult(result, "reported_pr_not_found", "Reported PR is not open.");
3696
+ }
3697
+ const postFixReproduction = autoloopPostFixReproductionEvidenceFromPayload(result.payload, {
3698
+ expectedCommitSha: checks.headSha
3699
+ });
3700
+ if (!postFixReproduction.passed) {
3701
+ return {
3702
+ ...result,
3703
+ status: "blocked",
3704
+ prUrl: null,
3705
+ latestCheckState: "blocked",
3706
+ blockingReason: postFixReproduction.reason,
3707
+ summary: `${result.summary} Post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
3708
+ };
3709
+ }
3710
+ const mismatch = prReferenceMatchFailure(result, input.repositoryFullName, checks, input);
3711
+ if (mismatch) {
3712
+ return blockedFixResult(
3713
+ result,
3714
+ mismatch,
3715
+ `Reported PR repository or branch is not verified: ${mismatch}.`
3716
+ );
3717
+ }
3718
+ if (checks.blockingReason) {
3719
+ return blockedFixResult(
3720
+ result,
3721
+ checks.blockingReason,
3722
+ `Reported PR required-check protection is not verified: ${checks.blockingReason}.`
3723
+ );
3724
+ }
3725
+ if (checks.passing) return verifiedQualityResult(result, checks);
3726
+ if (checks.state === "no_checks" && localValidationPassed(result.payload)) {
3727
+ const qualityResult = verifiedQualityResult(result, checks, "no_checks");
3728
+ if (qualityResult.status === "blocked") return qualityResult;
3729
+ return {
3730
+ ...qualityResult,
3731
+ status: "checks_passing",
3732
+ latestCheckState: "no_checks",
3733
+ summary: `${result.summary} No remote PR checks are configured; local validation and post-fix clone reproduction are verified.`
3734
+ };
3735
+ }
3736
+ return {
3737
+ ...result,
3738
+ status: "pr_open",
3739
+ latestCheckState: checks.state,
3740
+ summary: `${result.summary} PR checks are not verified green yet.`
3741
+ };
3742
+ }
3743
+ async function verifyOpenFixPrPoll(result, input) {
3744
+ if (result.status !== "pr_open" || !result.prUrl) return result;
3745
+ const pr = parseGithubPrUrl(result.prUrl);
3746
+ if (!pr || `${pr.owner}/${pr.repo}`.toLowerCase() !== input.repositoryFullName.toLowerCase()) {
3747
+ return blockedFixResult(
3748
+ { ...result, prUrl: null },
3749
+ "reported_pr_repository_mismatch",
3750
+ `Reported PR URL does not belong to ${input.repositoryFullName}.`
3751
+ );
3752
+ }
3753
+ const token = await resolveVerificationToken(input);
3754
+ if (!token) return { ...result, latestCheckState: "unknown" };
3755
+ const checks = await fetchGithubPrChecks(pr, token).catch(() => unverifiedGithubPrChecks());
3756
+ if (checks.state === "unverified") return { ...result, latestCheckState: "unknown" };
3757
+ if (checks.state === "not_open") {
3758
+ return blockedFixResult(result, "reported_pr_not_found", "Reported PR is not open.");
3759
+ }
3760
+ const postFixReproduction = autoloopPostFixReproductionEvidenceFromPayload(result.payload, {
3761
+ expectedCommitSha: checks.headSha
3762
+ });
3763
+ if (!postFixReproduction.passed) {
3764
+ return {
3765
+ ...result,
3766
+ status: "blocked",
3767
+ prUrl: null,
3768
+ latestCheckState: "blocked",
3769
+ blockingReason: postFixReproduction.reason,
3770
+ summary: `${result.summary} Open PR cannot become ready because post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
3771
+ };
3772
+ }
3773
+ const branchReason = prReferenceMatchFailure(result, input.repositoryFullName, checks, input);
3774
+ if (branchReason) {
3775
+ return blockedFixResult(
3776
+ result,
3777
+ branchReason,
3778
+ `Reported PR repository or branch is not verified: ${branchReason}.`
3779
+ );
3780
+ }
3781
+ if (checks.blockingReason) {
3782
+ return blockedFixResult(
3783
+ result,
3784
+ checks.blockingReason,
3785
+ `Reported PR required-check protection is not verified: ${checks.blockingReason}.`
3786
+ );
3787
+ }
3788
+ if (checks.passing) {
3789
+ const qualityResult = verifiedQualityResult(result, checks);
3790
+ if (qualityResult.status === "blocked") return qualityResult;
3791
+ return {
3792
+ ...qualityResult,
3793
+ status: "checks_passing",
3794
+ latestCheckState: "passing",
3795
+ summary: `${result.summary} PR checks are verified green.`
3796
+ };
3797
+ }
3798
+ if (checks.state === "no_checks" && localValidationPassed(result.payload)) {
3799
+ const qualityResult = verifiedQualityResult(result, checks, "no_checks");
3800
+ if (qualityResult.status === "blocked") return qualityResult;
3801
+ return {
3802
+ ...qualityResult,
3803
+ status: "checks_passing",
3804
+ latestCheckState: "no_checks",
3805
+ summary: `${result.summary} No remote PR checks are configured; local validation and post-fix clone reproduction are verified.`
3806
+ };
3807
+ }
3808
+ return {
3809
+ ...result,
3810
+ latestCheckState: checks.state,
3811
+ summary: `${result.summary} PR checks are not verified green yet.`
3812
+ };
3813
+ }
3814
+ function verifiedQualityResult(result, checks, latestCheckState = "passing") {
3815
+ const quality = assessFixPrPayload(result.payload, { prHeadSha: checks.headSha });
3816
+ if (quality.passed) return { ...result, latestCheckState };
3817
+ return blockedFixResult(
3818
+ result,
3819
+ quality.reason,
3820
+ `Generated PR evidence is insufficient: ${quality.reason}.`
3821
+ );
3822
+ }
3823
+ function localValidationPassed(payload) {
3824
+ return isRecord2(payload) && payload["localValidationStatus"] === "passed";
3825
+ }
3826
+ async function resolveVerificationToken(input) {
3827
+ if (input.githubToken?.trim()) return input.githubToken.trim();
3828
+ const token = await resolveAutoloopInstallationToken(
3829
+ { repository: input.repositoryFullName, installationId: input.githubInstallationId },
3830
+ {
3831
+ archalToken: process.env["ARCHAL_TOKEN"] ?? getCredentials2()?.token,
3832
+ archalBaseUrl: input.authBaseUrl
3833
+ }
3834
+ );
3835
+ return token ?? null;
3836
+ }
3837
+ async function confirmPrIsOpen(pr, token) {
3838
+ if (!token) return unverifiedGithubPrOpenResult();
3839
+ try {
3840
+ const response = await fetch(
3841
+ `https://api.github.com/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}`,
3842
+ {
3843
+ headers: {
3844
+ authorization: `Bearer ${token}`,
3845
+ accept: "application/vnd.github+json",
3846
+ "x-github-api-version": "2022-11-28"
3847
+ }
3848
+ }
3849
+ );
3850
+ if (response.status === 404)
3851
+ return notOpenGithubPrOpenResult();
3852
+ if (!response.ok) return unverifiedGithubPrOpenResult();
3853
+ const body = await response.json().catch(() => ({}));
3854
+ const head = isRecord2(body["head"]) ? body["head"] : {};
3855
+ const headRepo = isRecord2(head["repo"]) ? head["repo"] : {};
3856
+ const base = isRecord2(body["base"]) ? body["base"] : {};
3857
+ const baseRepo = isRecord2(base["repo"]) ? base["repo"] : {};
3858
+ return {
3859
+ state: body["state"] === "open" ? "open" : "not_open",
3860
+ headRefName: typeof head["ref"] === "string" ? head["ref"] : null,
3861
+ headSha: typeof head["sha"] === "string" ? head["sha"] : null,
3862
+ headRepoFullName: typeof headRepo["full_name"] === "string" ? headRepo["full_name"] : null,
3863
+ baseRefName: typeof base["ref"] === "string" ? base["ref"] : null,
3864
+ baseRepoFullName: typeof baseRepo["full_name"] === "string" ? baseRepo["full_name"] : null
3865
+ };
3866
+ } catch {
3867
+ return unverifiedGithubPrOpenResult();
3868
+ }
3869
+ }
3870
+ function unverifiedGithubPrOpenResult() {
3871
+ return {
3872
+ state: "unverifiable",
3873
+ headRefName: null,
3874
+ headSha: null,
3875
+ headRepoFullName: null,
3876
+ baseRefName: null,
3877
+ baseRepoFullName: null
3878
+ };
3879
+ }
3880
+ function notOpenGithubPrOpenResult() {
3881
+ return {
3882
+ state: "not_open",
3883
+ headRefName: null,
3884
+ headSha: null,
3885
+ headRepoFullName: null,
3886
+ baseRefName: null,
3887
+ baseRepoFullName: null
3888
+ };
3889
+ }
3890
+ function unverifiedGithubPrChecks() {
3891
+ return {
3892
+ passing: false,
3893
+ state: "unverified",
3894
+ headSha: null,
3895
+ headRefName: null,
3896
+ headRepoFullName: null,
3897
+ baseRefName: null,
3898
+ baseRepoFullName: null
3899
+ };
3900
+ }
3901
+ function parseGithubPrUrl(prUrl) {
3902
+ const match = prUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)$/);
3903
+ if (!match) return null;
3904
+ const owner = match[1];
3905
+ const repo = match[2];
3906
+ const number = match[3];
3907
+ if (!owner || !repo || !number) return null;
3908
+ return { owner, repo, number };
3909
+ }
3910
+ async function fetchGithubPrChecks(pr, token) {
3911
+ const headers = {
3912
+ authorization: `Bearer ${token}`,
3913
+ accept: "application/vnd.github+json",
3914
+ "x-github-api-version": "2022-11-28"
3915
+ };
3916
+ const pull = await githubJson(
3917
+ `https://api.github.com/repos/${pr.owner}/${pr.repo}/pulls/${pr.number}`,
3918
+ headers
3919
+ );
3920
+ const head = isRecord2(pull["head"]) ? pull["head"] : {};
3921
+ const headRepo = isRecord2(head["repo"]) ? head["repo"] : {};
3922
+ const baseRef = isRecord2(pull["base"]) ? pull["base"] : {};
3923
+ const baseRepo = isRecord2(baseRef["repo"]) ? baseRef["repo"] : {};
3924
+ const sha = typeof head["sha"] === "string" ? head["sha"] : null;
3925
+ const headRefName = typeof head["ref"] === "string" ? head["ref"] : null;
3926
+ const headRepoFullName = typeof headRepo["full_name"] === "string" ? headRepo["full_name"] : null;
3927
+ const base = {
3928
+ headSha: sha,
3929
+ headRefName,
3930
+ headRepoFullName,
3931
+ baseRefName: typeof baseRef["ref"] === "string" ? baseRef["ref"] : null,
3932
+ baseRepoFullName: typeof baseRepo["full_name"] === "string" ? baseRepo["full_name"] : null
3933
+ };
3934
+ if (pull["state"] !== "open") return { passing: false, state: "not_open", ...base };
3935
+ if (!sha) return { passing: false, state: "unknown", ...base };
3936
+ const status = await githubJson(
3937
+ `https://api.github.com/repos/${pr.owner}/${pr.repo}/commits/${sha}/status`,
3938
+ headers
3939
+ );
3940
+ const runs = await fetchGithubCheckRuns(
3941
+ `https://api.github.com/repos/${pr.owner}/${pr.repo}/commits/${sha}/check-runs`,
3942
+ headers
3943
+ );
3944
+ const state = githubCommitStatusState(status["state"]);
3945
+ const statuses = Array.isArray(status["statuses"]) ? status["statuses"] : [];
3946
+ const hasSignal = runs.length > 0 || statuses.length > 0;
3947
+ if (!hasSignal) return { passing: false, state: "no_checks", ...base };
3948
+ if (state === "failure" || state === "error" || runs.some(
3949
+ (run) => ["failure", "timed_out", "cancelled", "action_required"].includes(String(run["conclusion"]))
3950
+ )) {
3951
+ return { passing: false, state: "failing", ...base };
3952
+ }
3953
+ if (statuses.length > 0 && state === "pending" || runs.some((run) => run["status"] !== void 0 && String(run["status"]) !== "completed")) {
3954
+ return { passing: false, state: "pending", ...base };
3955
+ }
3956
+ const statusesPass = statuses.length === 0 || state === "success";
3957
+ const statusSuccessSignal = statuses.length > 0 && state === "success";
3958
+ const checkRunsPass = runs.length === 0 || runs.every((run) => ["success", "skipped", "neutral"].includes(String(run["conclusion"])));
3959
+ const checkRunSuccessSignal = runs.some((run) => String(run["conclusion"]) === "success");
3960
+ if (hasSignal && statusesPass && checkRunsPass && (statusSuccessSignal || checkRunSuccessSignal)) {
3961
+ const requiredChecks = await fetchGithubRequiredCheckContexts({
3962
+ owner: pr.owner,
3963
+ repo: pr.repo,
3964
+ baseRefName: base.baseRefName,
3965
+ token
3966
+ });
3967
+ const requiredBlocker = evaluateRequiredCheckProtection(requiredChecks, status, runs);
3968
+ if (requiredBlocker) {
3969
+ return { passing: false, state: "pending", blockingReason: requiredBlocker, ...base };
3970
+ }
3971
+ return { passing: true, state: "passing", ...base };
3972
+ }
3973
+ if (state === "unknown") return { passing: false, state: "unknown", ...base };
3974
+ return { passing: false, state: "pending", ...base };
3975
+ }
3976
+ function prReferenceMatchFailure(result, repositoryFullName, checks, input) {
3977
+ const branchName = result.branchName ?? payloadString(result.payload, "branchName", "branch_name", "branch");
3978
+ if (!branchName) return "reported_pr_branch_missing";
3979
+ if (!checks.headRefName) return "reported_pr_branch_missing";
3980
+ if (checks.headRefName !== branchName) return "reported_pr_branch_mismatch";
3981
+ if (!checks.headRepoFullName) return "reported_pr_head_repository_missing";
3982
+ if (checks.headRepoFullName.toLowerCase() !== repositoryFullName.toLowerCase()) {
3983
+ return "reported_pr_head_repository_mismatch";
3984
+ }
3985
+ if (!checks.baseRepoFullName) return "reported_pr_base_repository_missing";
3986
+ if (checks.baseRepoFullName.toLowerCase() !== repositoryFullName.toLowerCase()) {
3987
+ return "reported_pr_base_repository_mismatch";
3988
+ }
3989
+ const expectedBaseBranch = input.expectedBaseBranch ?? payloadString(result.payload, "baseBranch", "base_branch");
3990
+ if (!expectedBaseBranch) return "reported_pr_base_branch_missing";
3991
+ if (!checks.baseRefName) return "reported_pr_base_branch_missing";
3992
+ if (checks.baseRefName !== expectedBaseBranch) return "reported_pr_base_branch_mismatch";
3993
+ return null;
3994
+ }
3995
+ function blockedFixResult(result, reason, message) {
3996
+ return {
3997
+ ...result,
3998
+ status: "blocked",
3999
+ latestCheckState: "blocked",
4000
+ blockingReason: reason,
4001
+ summary: `${result.summary} ${message}`
4002
+ };
4003
+ }
4004
+ function githubCommitStatusState(value) {
4005
+ return value === "success" || value === "failure" || value === "error" || value === "pending" ? value : "unknown";
4006
+ }
4007
+ async function githubJson(url, headers) {
4008
+ const response = await fetch(url, { headers });
4009
+ if (!response.ok) throw new Error(`github_api_${response.status}`);
4010
+ return await response.json();
4011
+ }
4012
+ async function fetchGithubRequiredCheckContexts(input) {
4013
+ if (!input.baseRefName) {
4014
+ return { requiredContexts: [], blockingReason: "reported_pr_base_branch_missing" };
4015
+ }
4016
+ const source = { ...input, baseRefName: input.baseRefName };
4017
+ const branchProtection = await fetchGithubBranchProtectionRequiredCheckContexts(source).catch(
4018
+ () => ({
4019
+ requiredContexts: [],
4020
+ blockingReason: "reported_pr_required_checks_unverified"
4021
+ })
4022
+ );
4023
+ const ruleset = await fetchGithubRulesetRequiredCheckContexts(source).catch(() => ({
4024
+ requiredContexts: [],
4025
+ blockingReason: "reported_pr_required_checks_unverified"
4026
+ }));
4027
+ if (branchProtection.blockingReason === "reported_pr_required_checks_unverified") {
4028
+ return branchProtection;
4029
+ }
4030
+ if (ruleset.blockingReason === "reported_pr_required_checks_unverified") {
4031
+ return ruleset;
4032
+ }
4033
+ const requiredContexts = [.../* @__PURE__ */ new Set([...branchProtection.requiredContexts, ...ruleset.requiredContexts])];
4034
+ if (requiredContexts.length > 0) return { requiredContexts };
4035
+ return { requiredContexts };
4036
+ }
4037
+ async function fetchGithubBranchProtectionRequiredCheckContexts(input) {
4038
+ const response = await fetch("https://api.github.com/graphql", {
4039
+ method: "POST",
4040
+ headers: {
4041
+ authorization: `Bearer ${input.token}`,
4042
+ accept: "application/vnd.github+json",
4043
+ "content-type": "application/json"
4044
+ },
4045
+ body: JSON.stringify({
4046
+ query: `
4047
+ query ArchalRequiredChecks($owner: String!, $repo: String!, $ref: String!) {
4048
+ repository(owner: $owner, name: $repo) {
4049
+ ref(qualifiedName: $ref) {
4050
+ branchProtectionRule {
4051
+ requiresStatusChecks
4052
+ requiredStatusCheckContexts
4053
+ requiredStatusChecks {
4054
+ context
4055
+ }
4056
+ }
4057
+ }
4058
+ }
4059
+ }
4060
+ `,
4061
+ variables: {
4062
+ owner: input.owner,
4063
+ repo: input.repo,
4064
+ ref: input.baseRefName
4065
+ }
4066
+ })
4067
+ });
4068
+ if (!response.ok) throw new Error(`github_graphql_${response.status}`);
4069
+ const body = await response.json();
4070
+ if (Array.isArray(body["errors"]) && body["errors"].length > 0) {
4071
+ throw new Error("github_graphql_errors");
4072
+ }
4073
+ const data = isRecord2(body["data"]) ? body["data"] : {};
4074
+ const repository = isRecord2(data["repository"]) ? data["repository"] : {};
4075
+ const ref = isRecord2(repository["ref"]) ? repository["ref"] : {};
4076
+ const rule = isRecord2(ref["branchProtectionRule"]) ? ref["branchProtectionRule"] : null;
4077
+ if (!rule) {
4078
+ return { requiredContexts: [], blockingReason: "reported_pr_branch_protection_missing" };
4079
+ }
4080
+ if (rule["requiresStatusChecks"] !== true) {
4081
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_missing" };
4082
+ }
4083
+ const contexts = /* @__PURE__ */ new Set();
4084
+ const legacyContexts = rule["requiredStatusCheckContexts"];
4085
+ if (Array.isArray(legacyContexts)) {
4086
+ for (const context of legacyContexts) {
4087
+ if (typeof context === "string" && context.trim()) contexts.add(context.trim());
4088
+ }
4089
+ } else if (legacyContexts !== void 0) {
4090
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_unverified" };
4091
+ }
4092
+ const requiredStatusChecks = rule["requiredStatusChecks"];
4093
+ const nodes = Array.isArray(requiredStatusChecks) ? requiredStatusChecks : isRecord2(requiredStatusChecks) && Array.isArray(requiredStatusChecks["nodes"]) ? requiredStatusChecks["nodes"] : requiredStatusChecks === void 0 ? [] : null;
4094
+ if (!nodes) {
4095
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_unverified" };
4096
+ }
4097
+ for (const node of nodes) {
4098
+ if (!isRecord2(node)) continue;
4099
+ const context = node["context"];
4100
+ if (typeof context === "string" && context.trim()) contexts.add(context.trim());
4101
+ }
4102
+ const requiredContexts = [...contexts];
4103
+ if (requiredContexts.length === 0) {
4104
+ return { requiredContexts, blockingReason: "reported_pr_required_checks_missing" };
4105
+ }
4106
+ return { requiredContexts };
4107
+ }
4108
+ async function fetchGithubRulesetRequiredCheckContexts(input) {
4109
+ const branch = encodeURIComponent(input.baseRefName);
4110
+ const response = await fetch(
4111
+ `https://api.github.com/repos/${input.owner}/${input.repo}/rules/branches/${branch}?per_page=100`,
4112
+ {
4113
+ headers: {
4114
+ authorization: `Bearer ${input.token}`,
4115
+ accept: "application/vnd.github+json",
4116
+ "x-github-api-version": "2022-11-28"
4117
+ }
4118
+ }
4119
+ );
4120
+ if (response.status === 404) return { requiredContexts: [] };
4121
+ if (!response.ok) {
4122
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_unverified" };
4123
+ }
4124
+ const body = await response.json().catch(() => null);
4125
+ if (!Array.isArray(body)) {
4126
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_unverified" };
4127
+ }
4128
+ const contexts = /* @__PURE__ */ new Set();
4129
+ for (const item of body) {
4130
+ if (!isRecord2(item)) continue;
4131
+ const type = typeof item["type"] === "string" ? item["type"] : "";
4132
+ if (type === "required_workflows") continue;
4133
+ if (type !== "required_status_checks") continue;
4134
+ const parameters = isRecord2(item["parameters"]) ? item["parameters"] : {};
4135
+ const requiredStatusChecks = parameters["required_status_checks"] ?? parameters["requiredStatusChecks"];
4136
+ if (!Array.isArray(requiredStatusChecks)) {
4137
+ return { requiredContexts: [], blockingReason: "reported_pr_required_checks_unverified" };
4138
+ }
4139
+ for (const check of requiredStatusChecks) {
4140
+ if (typeof check === "string" && check.trim()) {
4141
+ contexts.add(check.trim());
4142
+ } else if (isRecord2(check)) {
4143
+ const context = check["context"];
4144
+ if (typeof context === "string" && context.trim()) contexts.add(context.trim());
4145
+ }
4146
+ }
4147
+ }
4148
+ return { requiredContexts: [...contexts] };
4149
+ }
4150
+ function evaluateRequiredCheckProtection(protection, status, runs) {
4151
+ if (protection.blockingReason) return protection.blockingReason;
4152
+ const required = protection.requiredContexts.map((context) => context.toLowerCase());
4153
+ const seen = /* @__PURE__ */ new Set();
4154
+ const statuses = Array.isArray(status["statuses"]) ? status["statuses"] : [];
4155
+ for (const item of statuses) {
4156
+ if (!isRecord2(item)) continue;
4157
+ const context = item["context"];
4158
+ if (typeof context !== "string" || !context.trim()) continue;
4159
+ seen.add(context.trim().toLowerCase());
4160
+ }
4161
+ for (const run of runs) {
4162
+ const name = run["name"];
4163
+ if (typeof name !== "string" || !name.trim()) continue;
4164
+ seen.add(name.trim().toLowerCase());
4165
+ }
4166
+ return required.every((context) => seen.has(context)) ? null : "reported_pr_required_checks_unverified";
4167
+ }
4168
+ async function fetchGithubCheckRuns(url, headers) {
4169
+ const runs = [];
4170
+ let nextUrl = url;
4171
+ for (let page = 0; nextUrl && page < 20; page += 1) {
4172
+ const response = await fetch(nextUrl, { headers });
4173
+ if (!response.ok) throw new Error(`github_api_${response.status}`);
4174
+ const body = await response.json();
4175
+ if (Array.isArray(body["check_runs"])) {
4176
+ runs.push(
4177
+ ...body["check_runs"].filter((run) => isRecord2(run))
4178
+ );
4179
+ }
4180
+ nextUrl = parseGithubNextLink(response.headers.get("link"));
4181
+ }
4182
+ if (nextUrl) throw new Error("github_check_runs_page_limit");
4183
+ return runs;
4184
+ }
4185
+ function parseGithubNextLink(linkHeader) {
4186
+ if (!linkHeader) return null;
4187
+ for (const part of linkHeader.split(",")) {
4188
+ const match = part.match(/<([^>]+)>;\s*rel="next"/);
4189
+ if (!match?.[1]) continue;
4190
+ try {
4191
+ const url = new URL(match[1]);
4192
+ return url.hostname === "api.github.com" ? url.toString() : null;
4193
+ } catch {
4194
+ return null;
4195
+ }
4196
+ }
4197
+ return null;
4198
+ }
4199
+ function isRecord2(value) {
4200
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
4201
+ }
4202
+ function payloadString(payload, ...keys) {
4203
+ if (!isRecord2(payload)) return null;
4204
+ for (const key of keys) {
4205
+ const value = payload[key];
4206
+ if (typeof value === "string" && value.trim().length > 0 && value.trim() === value)
4207
+ return value;
4208
+ }
4209
+ return null;
4210
+ }
4211
+ // Annotate the CommonJS export names for ESM import in node:
4212
+ 0 && (module.exports = {
4213
+ verifyFixResult,
4214
+ verifyOpenFixPrPoll
4215
+ });
4216
+ /*! Bundled license information:
4217
+
4218
+ @posthog/core/dist/vendor/uuidv7.mjs:
4219
+ (*! For license information please see uuidv7.mjs.LICENSE.txt *)
4220
+ (**
4221
+ * uuidv7: An experimental implementation of the proposed UUID Version 7
4222
+ *
4223
+ * @license Apache-2.0
4224
+ * @copyright 2021-2023 LiosK
4225
+ * @packageDocumentation
4226
+ *)
4227
+ */