archal 0.9.20 → 0.10.0
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.
- package/README.md +59 -159
- package/agents/openclaw/Dockerfile +2 -1
- package/agents/openclaw/README.md +10 -17
- package/agents/openclaw/drive.mjs +21 -31
- package/agents/openclaw/extract-openclaw-response-text.mjs +49 -0
- package/agents/openclaw/scenarios/acceptance/github-escalation-and-cleanup.md +43 -0
- package/agents/openclaw/scenarios/acceptance/jira-linear-release-triage.md +39 -0
- package/agents/openclaw/scenarios/acceptance/multi-clone-customer-risk-review.md +45 -0
- package/agents/openclaw/scenarios/acceptance/slack-incident-handoff.md +42 -0
- package/agents/openclaw/scenarios/acceptance/stripe-dunning-remediation.md +40 -0
- package/agents/openclaw/scenarios/close-stale-issues.md +35 -0
- package/agents/openclaw/workspace/TOOLS.md +19 -0
- package/clone-assets/calcom/tools.json +1705 -153
- package/clone-assets/clickup/tools.json +2528 -541
- package/clone-assets/customerio/tools.json +2108 -144
- package/clone-assets/github/tools.json +1 -2
- package/clone-assets/gitlab/tools.json +10087 -398
- package/clone-assets/hubspot/tools.json +198 -0
- package/clone-assets/linear/tools.json +41 -1
- package/clone-assets/sentry/tools.json +2264 -188
- package/clone-assets/stripe/tools.json +114 -0
- package/clone-assets/webflow/tools.json +1895 -125
- package/dist/{autoloop-worker-types-BEb_E44z.d.cts → autoloop-worker-types-CHaclqtD.d.cts} +23 -59
- package/dist/cli.cjs +107175 -126959
- package/dist/commands/{autoloop-hosted-worker.cjs → autoloop-hosted-control-plane-client.cjs} +25657 -42736
- package/dist/commands/{autoloop-hosted-worker.d.cts → autoloop-hosted-control-plane-client.d.cts} +32 -42
- package/dist/commands/autoloop-pr-verification.cjs +607 -522
- package/dist/commands/autoloop-pr-verification.d.cts +3 -1
- package/dist/commands/autoloop-result-parser.cjs +2474 -2373
- package/dist/commands/autoloop-result-parser.d.cts +159 -2
- package/dist/commands/autoloop-worker.cjs +14565 -12240
- package/dist/commands/autoloop-worker.d.cts +10 -5
- package/dist/eval-shim.mjs +216 -0
- package/dist/index.cjs +15 -2
- package/dist/index.d.cts +3 -1
- package/dist/layer-1-ziaLpfLr.d.cts +62 -0
- package/dist/metafile-cjs.json +1 -0
- package/dist/reporter-entry.js +3 -0
- package/dist/{replay.cjs → sdk/index.cjs} +42979 -40973
- package/dist/sdk/index.d.cts +626 -0
- package/dist/vitest/{chunk-6CBYFCFK.js → chunk-2PDHTPZC.js} +289 -89
- package/dist/vitest/{chunk-ARVS45PP.js → chunk-7L4BBB6M.js} +123 -274
- package/dist/vitest/index.cjs +500 -816
- package/dist/vitest/index.d.ts +16 -81
- package/dist/vitest/index.js +40 -409
- package/dist/vitest/runtime/hosted-session-reaper.cjs +143 -293
- package/dist/vitest/runtime/hosted-session-reaper.js +1 -1
- package/dist/vitest/runtime/setup-files.js +2 -2
- package/manifest.json +9 -0
- package/package.json +14 -13
- package/skills/archal-agent/SKILL.md +0 -1
- package/skills/autoloop/SKILL.md +288 -273
- package/skills/autoloop/references/hosted-sources.md +49 -17
- package/skills/autoloop/references/trace-schema-mapping.md +83 -52
- package/skills/eval/SKILL.md +16 -48
- package/skills/free-account/SKILL.md +103 -0
- package/skills/install-agent/SKILL.md +16 -35
- package/skills/onboard/SKILL.md +13 -70
- package/skills/scenario/SKILL.md +30 -27
- package/skills/seed/SKILL.md +7 -6
- package/skills/vitest/SKILL.md +3 -2
- package/agents/github-octokit/.archal.json +0 -8
- package/agents/github-octokit/Dockerfile +0 -8
- package/agents/github-octokit/README.md +0 -113
- package/agents/github-octokit/agent.mjs +0 -54
- package/agents/github-octokit/package.json +0 -9
- package/agents/github-octokit/scenarios/test-repo-access.md +0 -27
- package/agents/google-workspace-local-tools/Dockerfile +0 -6
- package/agents/google-workspace-local-tools/README.md +0 -58
- package/agents/google-workspace-local-tools/agent.mjs +0 -196
- package/agents/google-workspace-local-tools/archal-harness.json +0 -7
- package/agents/google-workspace-local-tools/run-input.yaml +0 -16
- package/agents/google-workspace-local-tools/scenario.md +0 -29
- package/agents/hermes/.archal.json +0 -8
- package/agents/hermes/Dockerfile +0 -46
- package/agents/hermes/README.md +0 -87
- package/agents/hermes/SOUL.md +0 -27
- package/agents/hermes/config.yaml +0 -34
- package/agents/hermes/drive.mjs +0 -113
- package/agents/hermes/scenarios/stripe-customers-read-only.md +0 -32
- package/agents/pagination-test/README.md +0 -24
- package/agents/pagination-test/scenario.md +0 -24
- package/agents/replay-capsule-harness/README.md +0 -29
- package/agents/replay-capsule-harness/observability-install-offline-e2e.mts +0 -1517
- package/agents/replay-capsule-harness/replay-capsule-e2e.mjs +0 -104
- package/dist/harness.cjs +0 -63
- package/dist/harness.d.cts +0 -20
- package/dist/replay.d.cts +0 -4625
- package/dist/scenarios.cjs +0 -80343
- package/dist/scenarios.d.cts +0 -562
|
@@ -152,8 +152,11 @@ var AUTOLOOP_INTERNAL_ONLY_EVENT_TYPES = [
|
|
|
152
152
|
"codex_session.recorded",
|
|
153
153
|
"source_snapshot.created",
|
|
154
154
|
"source_snapshot.updated",
|
|
155
|
+
"canonical_trace_ingest.rejected",
|
|
156
|
+
"canonical_trace_ingest.digest_conflict",
|
|
155
157
|
"autoloop_run.claimed",
|
|
156
158
|
"autoloop_run.retry_scheduled",
|
|
159
|
+
"operator.requeued",
|
|
157
160
|
...AGENT_STREAM_EVENT_TYPES
|
|
158
161
|
];
|
|
159
162
|
function autoloopRunCapabilitiesFromPostFixPayload(payload) {
|
|
@@ -171,6 +174,103 @@ var AUTOLOOP_EVENT_TYPES = [
|
|
|
171
174
|
...AUTOLOOP_INTERNAL_ONLY_EVENT_TYPES
|
|
172
175
|
];
|
|
173
176
|
|
|
177
|
+
// ../packages/contracts/src/autoloop/trace-source-capabilities.ts
|
|
178
|
+
var AUTOLOOP_TRACE_SOURCE_HOSTED_PROVIDER_CAPABILITIES = [
|
|
179
|
+
{
|
|
180
|
+
provider: "supabase",
|
|
181
|
+
tier: "supported",
|
|
182
|
+
ingestionMode: "hosted_poll",
|
|
183
|
+
hostedRegistration: "available",
|
|
184
|
+
hostedImport: "available",
|
|
185
|
+
summary: "Hosted workers can poll Supabase-hosted Postgres trace tables through a read-only database URL.",
|
|
186
|
+
nextStep: "Register with archal autoloop --source supabase and a read-only database URL secret reference."
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
provider: "postgres",
|
|
190
|
+
tier: "supported",
|
|
191
|
+
ingestionMode: "hosted_poll",
|
|
192
|
+
hostedRegistration: "available",
|
|
193
|
+
hostedImport: "available",
|
|
194
|
+
summary: "Hosted workers can poll Postgres trace tables or SQL views through a read-only database URL.",
|
|
195
|
+
nextStep: "Register with archal autoloop --source postgres and a read-only database URL secret reference."
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
provider: "http",
|
|
199
|
+
tier: "beta",
|
|
200
|
+
ingestionMode: "client_upload",
|
|
201
|
+
hostedRegistration: "available",
|
|
202
|
+
hostedImport: "available",
|
|
203
|
+
summary: "HTTP push traces can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
204
|
+
nextStep: "Push traces to the workspace dashboard OTLP ingest endpoint, then run archal autoloop ./traces --repository owner/repo."
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
provider: "otel",
|
|
208
|
+
tier: "beta",
|
|
209
|
+
ingestionMode: "client_upload",
|
|
210
|
+
hostedRegistration: "available",
|
|
211
|
+
hostedImport: "available",
|
|
212
|
+
summary: "OTel traces can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
213
|
+
nextStep: "Configure your OTel SDK to export to the workspace dashboard OTLP endpoint, then run archal autoloop ./traces --repository owner/repo."
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
provider: "langfuse",
|
|
217
|
+
tier: "import",
|
|
218
|
+
ingestionMode: "client_upload",
|
|
219
|
+
hostedRegistration: "available",
|
|
220
|
+
hostedImport: "available",
|
|
221
|
+
summary: "Langfuse exports can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
222
|
+
nextStep: "Export traces from Langfuse and import via the dashboard, or place normalized JSON in an autoloop watch directory."
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
provider: "braintrust",
|
|
226
|
+
tier: "import",
|
|
227
|
+
ingestionMode: "client_upload",
|
|
228
|
+
hostedRegistration: "available",
|
|
229
|
+
hostedImport: "available",
|
|
230
|
+
summary: "Braintrust exports can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
231
|
+
nextStep: "Export traces from Braintrust and import via the dashboard, or place normalized JSON in an autoloop watch directory."
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
provider: "s3",
|
|
235
|
+
tier: "import",
|
|
236
|
+
ingestionMode: "client_upload",
|
|
237
|
+
hostedRegistration: "available",
|
|
238
|
+
hostedImport: "available",
|
|
239
|
+
summary: "S3 trace exports can be mirrored locally and uploaded into hosted autoloop as autoloop runs.",
|
|
240
|
+
nextStep: "Configure bucket access from the dashboard Connect a trace database form, or drop normalized exports into a watch directory with archal autoloop ./traces --repository owner/repo."
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
provider: "gcs",
|
|
244
|
+
tier: "import",
|
|
245
|
+
ingestionMode: "client_upload",
|
|
246
|
+
hostedRegistration: "available",
|
|
247
|
+
hostedImport: "available",
|
|
248
|
+
summary: "GCS trace exports can be mirrored locally and uploaded into hosted autoloop as autoloop runs.",
|
|
249
|
+
nextStep: "Configure bucket access from the dashboard Connect a trace database form, or drop normalized exports into a watch directory with archal autoloop ./traces --repository owner/repo."
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
provider: "custom",
|
|
253
|
+
tier: "custom_contract",
|
|
254
|
+
ingestionMode: "client_upload",
|
|
255
|
+
hostedRegistration: "available",
|
|
256
|
+
hostedImport: "available",
|
|
257
|
+
summary: "Custom trace JSON can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
258
|
+
nextStep: "Place normalized trace JSON in a watch directory and run archal autoloop ./traces --repository owner/repo."
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
provider: "file",
|
|
262
|
+
tier: "local_only",
|
|
263
|
+
ingestionMode: "client_upload",
|
|
264
|
+
hostedRegistration: "available",
|
|
265
|
+
hostedImport: "available",
|
|
266
|
+
summary: "File-backed traces can be normalized locally and uploaded into hosted autoloop as autoloop runs.",
|
|
267
|
+
nextStep: "Place trace JSON files in a watch directory and run archal autoloop ./traces --repository owner/repo."
|
|
268
|
+
}
|
|
269
|
+
];
|
|
270
|
+
var AUTOLOOP_TRACE_SOURCE_HOSTED_PROVIDER_CAPABILITY_BY_PROVIDER = new Map(
|
|
271
|
+
AUTOLOOP_TRACE_SOURCE_HOSTED_PROVIDER_CAPABILITIES.map((cap) => [cap.provider, cap])
|
|
272
|
+
);
|
|
273
|
+
|
|
174
274
|
// ../packages/contracts/src/autoloop.ts
|
|
175
275
|
var AUTOLOOP_CUSTOMER_SAFE_CONTROL_PLANE_MESSAGE_SET = new Set(AUTOLOOP_CUSTOMER_SAFE_CONTROL_PLANE_MESSAGES);
|
|
176
276
|
var AUTOLOOP_CUSTOMER_VISIBLE_ARTIFACT_TYPE_SET = new Set(
|
|
@@ -393,6 +493,24 @@ function autoloopPostFixReproductionEvidenceFromPayload(payload, input = {}) {
|
|
|
393
493
|
{ status, commitSha }
|
|
394
494
|
);
|
|
395
495
|
}
|
|
496
|
+
function autoloopPostFixReproductionReason(input) {
|
|
497
|
+
if (input.hasInfrastructureFailure || input.evaluatorInfrastructureFailure) {
|
|
498
|
+
return "postfix_reproduction_infrastructure_failure";
|
|
499
|
+
}
|
|
500
|
+
if (input.status === "reproduced" || input.genuineFailureCount > 0) {
|
|
501
|
+
return "postfix_reproduction_still_failing";
|
|
502
|
+
}
|
|
503
|
+
if (input.status !== "not_reproduced") return "postfix_reproduction_not_verified";
|
|
504
|
+
if (input.requiresCloneEvidence !== false && !input.hasCloneEvidence) {
|
|
505
|
+
return "postfix_reproduction_clone_evidence_missing";
|
|
506
|
+
}
|
|
507
|
+
if (!input.hasCriteriaEvidence) return "postfix_reproduction_criteria_evidence_missing";
|
|
508
|
+
if (!input.identityMatchesPreFix) return "postfix_reproduction_trace_mismatch";
|
|
509
|
+
if (input.toolErrorCount > 0) return "postfix_reproduction_tool_errors";
|
|
510
|
+
if (input.inconclusiveCriteria > 0) return "postfix_reproduction_inconclusive";
|
|
511
|
+
if (input.satisfiedCriteria <= 0) return "postfix_reproduction_no_scored_criteria";
|
|
512
|
+
return "postfix_reproduction_passed";
|
|
513
|
+
}
|
|
396
514
|
function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatchesPreFix, commitSha, input) {
|
|
397
515
|
const reproduction = payload["postFixReproduction"] ?? payload["post_fix_reproduction"];
|
|
398
516
|
if (!isAutoloopFixPrEvidenceRecord(reproduction)) return null;
|
|
@@ -402,19 +520,30 @@ function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatc
|
|
|
402
520
|
const status = autoloopFixPrEvidenceString(reproduction["status"]);
|
|
403
521
|
const hasCloneEvidence = autoloopFixPrEvidenceBoolean(reproduction["hasCloneEvidence"]) === true;
|
|
404
522
|
const hasCriteriaEvidence = autoloopFixPrEvidenceBoolean(reproduction["hasCriteriaEvidence"]) === true;
|
|
523
|
+
const satisfiedCriteria = autoloopFixPrEvidenceNumber(reproduction["satisfiedCriteria"]);
|
|
524
|
+
const genuineFailureCount = Math.max(
|
|
525
|
+
autoloopFixPrEvidenceNumber(reproduction["genuineFailureCount"]),
|
|
526
|
+
autoloopFixPrEvidenceArray(reproduction["failedCriteria"]).length,
|
|
527
|
+
autoloopFixPrEvidenceStringArray(reproduction["failedCriterionIds"]).length
|
|
528
|
+
);
|
|
529
|
+
const inconclusiveCriteria = autoloopFixPrEvidenceNumber(reproduction["inconclusiveCriteria"]);
|
|
530
|
+
const toolErrorCount = Math.max(
|
|
531
|
+
autoloopFixPrEvidenceNumber(reproduction["toolErrorCount"]),
|
|
532
|
+
autoloopFixPrEvidenceArray(reproduction["toolErrors"]).length
|
|
533
|
+
);
|
|
534
|
+
const hasInfrastructureFailure = autoloopFixPrEvidenceBoolean(reproduction["hasInfrastructureFailure"]) === true;
|
|
535
|
+
const evaluatorInfrastructureFailure = autoloopFixPrEvidenceBoolean(reproduction["evaluatorInfrastructureFailure"]) === true;
|
|
405
536
|
const identityMatchesPreFix = autoloopFixPrEvidenceBoolean(
|
|
406
537
|
reproduction["replayIdentityMatchesPreFix"] ?? reproduction["identityMatchesPreFix"]
|
|
407
538
|
) ?? topLevelIdentityMatchesPreFix ?? false;
|
|
408
|
-
const
|
|
409
|
-
if (
|
|
410
|
-
const legacyHasCloneEvidence = status === "passed" ? true : hasCloneEvidence;
|
|
411
|
-
const legacyHasCriteriaEvidence = status === "passed" ? true : hasCriteriaEvidence;
|
|
539
|
+
const cleanPostFixCriteria = status === "not_reproduced" && hasCloneEvidence && hasCriteriaEvidence && satisfiedCriteria > 0 && genuineFailureCount === 0 && inconclusiveCriteria === 0 && toolErrorCount === 0 && !hasInfrastructureFailure && !evaluatorInfrastructureFailure;
|
|
540
|
+
if (cleanPostFixCriteria && hasEvidence) {
|
|
412
541
|
if (!identityMatchesPreFix) {
|
|
413
542
|
return failedAutoloopPostFixReproduction("postfix_reproduction_trace_mismatch", {
|
|
414
543
|
status,
|
|
415
544
|
commitSha,
|
|
416
|
-
hasCloneEvidence
|
|
417
|
-
hasCriteriaEvidence
|
|
545
|
+
hasCloneEvidence,
|
|
546
|
+
hasCriteriaEvidence,
|
|
418
547
|
identityMatchesPreFix: false,
|
|
419
548
|
reproductionReverified: true
|
|
420
549
|
});
|
|
@@ -422,8 +551,8 @@ function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatc
|
|
|
422
551
|
if (!commitSha && input.expectedCommitSha) {
|
|
423
552
|
return failedAutoloopPostFixReproduction("postfix_reproduction_commit_missing", {
|
|
424
553
|
status,
|
|
425
|
-
hasCloneEvidence
|
|
426
|
-
hasCriteriaEvidence
|
|
554
|
+
hasCloneEvidence,
|
|
555
|
+
hasCriteriaEvidence,
|
|
427
556
|
identityMatchesPreFix,
|
|
428
557
|
reproductionReverified: true
|
|
429
558
|
});
|
|
@@ -432,8 +561,8 @@ function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatc
|
|
|
432
561
|
return failedAutoloopPostFixReproduction("postfix_reproduction_commit_mismatch", {
|
|
433
562
|
status,
|
|
434
563
|
commitSha,
|
|
435
|
-
hasCloneEvidence
|
|
436
|
-
hasCriteriaEvidence
|
|
564
|
+
hasCloneEvidence,
|
|
565
|
+
hasCriteriaEvidence,
|
|
437
566
|
identityMatchesPreFix,
|
|
438
567
|
reproductionReverified: true
|
|
439
568
|
});
|
|
@@ -443,12 +572,36 @@ function nestedAutoloopPostFixReproductionEvidence(payload, topLevelIdentityMatc
|
|
|
443
572
|
reason: "postfix_reproduction_passed",
|
|
444
573
|
status,
|
|
445
574
|
commitSha,
|
|
446
|
-
hasCloneEvidence
|
|
447
|
-
hasCriteriaEvidence
|
|
575
|
+
hasCloneEvidence,
|
|
576
|
+
hasCriteriaEvidence,
|
|
448
577
|
identityMatchesPreFix,
|
|
449
578
|
reproductionReverified: true
|
|
450
579
|
};
|
|
451
580
|
}
|
|
581
|
+
if (status === "not_reproduced" && hasEvidence) {
|
|
582
|
+
return failedAutoloopPostFixReproduction(
|
|
583
|
+
autoloopPostFixReproductionReason({
|
|
584
|
+
status,
|
|
585
|
+
genuineFailureCount,
|
|
586
|
+
hasCloneEvidence,
|
|
587
|
+
hasCriteriaEvidence,
|
|
588
|
+
identityMatchesPreFix,
|
|
589
|
+
hasInfrastructureFailure,
|
|
590
|
+
evaluatorInfrastructureFailure,
|
|
591
|
+
toolErrorCount,
|
|
592
|
+
inconclusiveCriteria,
|
|
593
|
+
satisfiedCriteria
|
|
594
|
+
}),
|
|
595
|
+
{
|
|
596
|
+
status,
|
|
597
|
+
commitSha,
|
|
598
|
+
hasCloneEvidence,
|
|
599
|
+
hasCriteriaEvidence,
|
|
600
|
+
identityMatchesPreFix,
|
|
601
|
+
reproductionReverified: false
|
|
602
|
+
}
|
|
603
|
+
);
|
|
604
|
+
}
|
|
452
605
|
const reason = autoloopFixPrEvidenceString(reproduction["reason"]);
|
|
453
606
|
return reason ? failedAutoloopPostFixReproduction(reason, { status, commitSha }) : null;
|
|
454
607
|
}
|
|
@@ -581,18 +734,15 @@ function autoloopFixPrEvidenceStringArray(value) {
|
|
|
581
734
|
if (!Array.isArray(value)) return [];
|
|
582
735
|
return value.filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
583
736
|
}
|
|
737
|
+
function autoloopFixPrEvidenceArray(value) {
|
|
738
|
+
return Array.isArray(value) ? value : [];
|
|
739
|
+
}
|
|
584
740
|
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);
|
|
741
|
+
return /(^|\/)archal(\/|$)/i.test(file) || /(^|\/)(evals?|evaluations?|harness)(\/|$)/i.test(file) || /(^|\/)run-[^/]*eval\.[cm]?[jt]s$/i.test(file) || /(^|\/)scripts\/.*(?:archal|eval|harness|replay).*$/i.test(file) || /(^|\/)services\/ai\/labs\//i.test(file);
|
|
586
742
|
}
|
|
587
743
|
function isDisallowedAutoloopEvalHarnessOnlyPatch(implementationFiles, runtimeEntrypointFiles) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
return !implementationFiles.some(
|
|
591
|
-
(file) => runtimeEntrypoints.has(normalizeAutoloopFixPrEvidencePath(file))
|
|
592
|
-
);
|
|
593
|
-
}
|
|
594
|
-
function normalizeAutoloopFixPrEvidencePath(file) {
|
|
595
|
-
return file.replace(/\\/g, "/").replace(/^\.\//, "").trim();
|
|
744
|
+
void runtimeEntrypointFiles;
|
|
745
|
+
return implementationFiles.length > 0 && implementationFiles.every(isAutoloopAttachEvalHarnessFile);
|
|
596
746
|
}
|
|
597
747
|
function autoloopFixPrEvidenceString(value) {
|
|
598
748
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
@@ -619,6 +769,7 @@ var TOKEN_ENCRYPTION_PREFIX = "enc-v1";
|
|
|
619
769
|
var CREDENTIALS_MASTER_KEY_ENV_VAR = "ARCHAL_CREDENTIALS_MASTER_KEY";
|
|
620
770
|
var KEYCHAIN_SERVICE = "archal-cli";
|
|
621
771
|
var KEYCHAIN_ACCOUNT = "credentials-master-key";
|
|
772
|
+
var WORKSPACE_API_KEY_PREFIX = "archal_ws_";
|
|
622
773
|
var ENV_TOKEN_FALLBACK_TTL_SECONDS = 24 * 60 * 60;
|
|
623
774
|
|
|
624
775
|
// ../packages/node-auth/src/types.ts
|
|
@@ -626,18 +777,6 @@ function isPlan(value) {
|
|
|
626
777
|
return value === "free" || value === "pro" || value === "enterprise";
|
|
627
778
|
}
|
|
628
779
|
|
|
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
780
|
// ../packages/node-auth/src/credential-store.ts
|
|
642
781
|
var import_node_child_process = require("child_process");
|
|
643
782
|
var import_node_crypto = require("crypto");
|
|
@@ -670,7 +809,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
670
809
|
name: "Cal.com",
|
|
671
810
|
description: "Event types, schedules, availability slots, bookings, calendars, and webhooks.",
|
|
672
811
|
stage: "preview",
|
|
673
|
-
toolCount:
|
|
812
|
+
toolCount: 35,
|
|
674
813
|
transport: "both",
|
|
675
814
|
architectureClass: "domain-simulator",
|
|
676
815
|
domainPrimitives: [
|
|
@@ -688,7 +827,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
688
827
|
name: "ClickUp",
|
|
689
828
|
description: "Teams, spaces, folders, lists, tasks, comments, tags, time tracking, and checklists.",
|
|
690
829
|
stage: "preview",
|
|
691
|
-
toolCount:
|
|
830
|
+
toolCount: 123,
|
|
692
831
|
transport: "both",
|
|
693
832
|
architectureClass: "standard-core",
|
|
694
833
|
domainPrimitives: [],
|
|
@@ -701,7 +840,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
701
840
|
name: "Customer.io",
|
|
702
841
|
description: "Messaging automation across campaigns, broadcasts, transactional email, segments, customers, and message delivery.",
|
|
703
842
|
stage: "preview",
|
|
704
|
-
toolCount:
|
|
843
|
+
toolCount: 129,
|
|
705
844
|
transport: "rest",
|
|
706
845
|
architectureClass: "standard-core",
|
|
707
846
|
domainPrimitives: [],
|
|
@@ -766,7 +905,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
766
905
|
name: "GitLab",
|
|
767
906
|
description: "Projects, branches, commits, issues, merge requests, pipelines, labels, milestones, releases, and webhooks.",
|
|
768
907
|
stage: "preview",
|
|
769
|
-
toolCount:
|
|
908
|
+
toolCount: 559,
|
|
770
909
|
transport: "both",
|
|
771
910
|
architectureClass: "domain-simulator",
|
|
772
911
|
domainPrimitives: [
|
|
@@ -801,7 +940,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
801
940
|
name: "HubSpot",
|
|
802
941
|
description: "CRM contacts, companies, deals, tickets, and engagements.",
|
|
803
942
|
stage: "preview",
|
|
804
|
-
toolCount:
|
|
943
|
+
toolCount: 44,
|
|
805
944
|
transport: "rest",
|
|
806
945
|
architectureClass: "replay-shell",
|
|
807
946
|
domainPrimitives: [
|
|
@@ -836,7 +975,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
836
975
|
name: "Linear",
|
|
837
976
|
description: "Issues, projects, teams, cycles, and workflows.",
|
|
838
977
|
stage: "public",
|
|
839
|
-
toolCount:
|
|
978
|
+
toolCount: 53,
|
|
840
979
|
transport: "both",
|
|
841
980
|
architectureClass: "domain-simulator",
|
|
842
981
|
domainPrimitives: [
|
|
@@ -905,7 +1044,7 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
905
1044
|
name: "Sentry",
|
|
906
1045
|
description: "Error monitoring across organizations, projects, teams, issues, events, releases, and DSN keys.",
|
|
907
1046
|
stage: "preview",
|
|
908
|
-
toolCount:
|
|
1047
|
+
toolCount: 34,
|
|
909
1048
|
transport: "rest",
|
|
910
1049
|
architectureClass: "domain-simulator",
|
|
911
1050
|
domainPrimitives: [
|
|
@@ -1007,14 +1146,10 @@ var GENERATED_CLONE_CATALOG = [
|
|
|
1007
1146
|
name: "Webflow",
|
|
1008
1147
|
description: "Sites, pages, CMS collections, items, assets, forms, and webhooks.",
|
|
1009
1148
|
stage: "preview",
|
|
1010
|
-
toolCount:
|
|
1011
|
-
transport: "
|
|
1012
|
-
architectureClass: "
|
|
1013
|
-
domainPrimitives: [
|
|
1014
|
-
"recording replay cursor",
|
|
1015
|
-
"CMS collection/item overlays",
|
|
1016
|
-
"publish lifecycle captures"
|
|
1017
|
-
],
|
|
1149
|
+
toolCount: 104,
|
|
1150
|
+
transport: "both",
|
|
1151
|
+
architectureClass: "standard-core",
|
|
1152
|
+
domainPrimitives: [],
|
|
1018
1153
|
behaviorOwner: null,
|
|
1019
1154
|
opsCoverage: 100
|
|
1020
1155
|
}
|
|
@@ -1121,142 +1256,18 @@ var STARTABLE_CLONE_CATALOG = CLONE_CATALOG.filter(
|
|
|
1121
1256
|
(entry) => STARTABLE_CLONE_ID_SET.has(entry.id)
|
|
1122
1257
|
);
|
|
1123
1258
|
|
|
1124
|
-
// ../packages/
|
|
1125
|
-
var
|
|
1126
|
-
|
|
1127
|
-
|
|
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
|
-
]
|
|
1259
|
+
// ../packages/node-auth/src/credential-store.ts
|
|
1260
|
+
var ExpiredEnvTokenError = class extends Error {
|
|
1261
|
+
constructor(envVar = AUTH_TOKEN_ENV_VAR) {
|
|
1262
|
+
super(`${envVar} is expired. Remove it or replace it with a valid token.`);
|
|
1263
|
+
this.name = "ExpiredEnvTokenError";
|
|
1264
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
1194
1265
|
}
|
|
1195
1266
|
};
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
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);
|
|
1267
|
+
function errorMessage(error) {
|
|
1268
|
+
return error instanceof Error ? error.message : String(error);
|
|
1269
|
+
}
|
|
1270
|
+
var ENTITLED_CLONE_SET = new Set(ALL_STARTABLE_CLONE_IDS);
|
|
1260
1271
|
function normalizeEntitledCloneIds(cloneIds) {
|
|
1261
1272
|
if (!cloneIds) {
|
|
1262
1273
|
return [];
|
|
@@ -1273,8 +1284,6 @@ function normalizeEntitledCloneIds(cloneIds) {
|
|
|
1273
1284
|
}
|
|
1274
1285
|
return [...normalized];
|
|
1275
1286
|
}
|
|
1276
|
-
|
|
1277
|
-
// ../packages/node-auth/src/credential-store.ts
|
|
1278
1287
|
var KEYCHAIN_COMMAND_TIMEOUT_MS = 1500;
|
|
1279
1288
|
var ARCHAL_DIR_NAME = ".archal";
|
|
1280
1289
|
var TEST_SANDBOX_ID_ENV_VAR = "ARCHAL_TEST_SANDBOX_ID";
|
|
@@ -1314,7 +1323,7 @@ function getTestSandboxDir() {
|
|
|
1314
1323
|
return (0, import_node_path2.join)((0, import_node_os.tmpdir)(), `archal-test-sandbox-${workerId}-${process.pid}`);
|
|
1315
1324
|
}
|
|
1316
1325
|
function getArchalDir() {
|
|
1317
|
-
const explicit = process.env["ARCHAL_HOME"];
|
|
1326
|
+
const explicit = process.env["ARCHAL_HOME"]?.trim();
|
|
1318
1327
|
if (explicit) {
|
|
1319
1328
|
return explicit;
|
|
1320
1329
|
}
|
|
@@ -1595,7 +1604,66 @@ function readCredentialsFile(options) {
|
|
|
1595
1604
|
return readCredentialsFileAtPath(getCredentialsPath(), options);
|
|
1596
1605
|
}
|
|
1597
1606
|
function isWorkspaceApiKey(token) {
|
|
1598
|
-
return token.startsWith(
|
|
1607
|
+
return token.startsWith(WORKSPACE_API_KEY_PREFIX) || token.startsWith("archal_") && !token.includes(".");
|
|
1608
|
+
}
|
|
1609
|
+
var WORKSPACE_API_KEY_EXPIRES_SECONDS = 365 * 24 * 60 * 60;
|
|
1610
|
+
function parseEnvToken(token, envName = AUTH_TOKEN_ENV_VAR, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
1611
|
+
const trimmed = token.trim();
|
|
1612
|
+
if (!trimmed) {
|
|
1613
|
+
return { status: "invalid", message: `${envName} is empty.` };
|
|
1614
|
+
}
|
|
1615
|
+
if (isWorkspaceApiKey(trimmed)) {
|
|
1616
|
+
return {
|
|
1617
|
+
status: "ok",
|
|
1618
|
+
credentials: {
|
|
1619
|
+
token: trimmed,
|
|
1620
|
+
refreshToken: "",
|
|
1621
|
+
email: "(workspace-api-key)",
|
|
1622
|
+
plan: "pro",
|
|
1623
|
+
selectedCloneIds: [],
|
|
1624
|
+
expiresAt: nowSeconds + WORKSPACE_API_KEY_EXPIRES_SECONDS
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
const claims = decodeJwtPayload(trimmed);
|
|
1629
|
+
if (claims === null) {
|
|
1630
|
+
return {
|
|
1631
|
+
status: "invalid",
|
|
1632
|
+
message: `${envName} must be a JWT with valid plan and exp claims or a workspace API key (archal_ws_...).`
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
const email = typeof claims["email"] === "string" ? claims["email"] : `(from ${envName})`;
|
|
1636
|
+
if (!isPlan(claims["plan"])) {
|
|
1637
|
+
return {
|
|
1638
|
+
status: "invalid",
|
|
1639
|
+
message: `${envName} JWT does not contain a valid plan claim.`
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
const plan = claims["plan"];
|
|
1643
|
+
if (typeof claims["exp"] !== "number" || !Number.isFinite(claims["exp"])) {
|
|
1644
|
+
return {
|
|
1645
|
+
status: "invalid",
|
|
1646
|
+
message: `${envName} JWT does not contain a valid exp claim.`
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
const expiresAt = claims["exp"];
|
|
1650
|
+
if (expiresAt <= nowSeconds) {
|
|
1651
|
+
return {
|
|
1652
|
+
status: "expired",
|
|
1653
|
+
message: `${envName} is expired. Remove it or replace it with a valid token.`
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
return {
|
|
1657
|
+
status: "ok",
|
|
1658
|
+
credentials: {
|
|
1659
|
+
token: trimmed,
|
|
1660
|
+
refreshToken: "",
|
|
1661
|
+
email,
|
|
1662
|
+
plan,
|
|
1663
|
+
selectedCloneIds: [],
|
|
1664
|
+
expiresAt
|
|
1665
|
+
}
|
|
1666
|
+
};
|
|
1599
1667
|
}
|
|
1600
1668
|
function readCredentialsFromEnv(options) {
|
|
1601
1669
|
const raw = process.env[AUTH_TOKEN_ENV_VAR];
|
|
@@ -1606,56 +1674,28 @@ function readCredentialsFromEnv(options) {
|
|
|
1606
1674
|
if (token.length === 0) {
|
|
1607
1675
|
return null;
|
|
1608
1676
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
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
|
-
};
|
|
1677
|
+
const parsed = parseEnvToken(token);
|
|
1678
|
+
if (parsed.status === "ok") {
|
|
1679
|
+
if (isWorkspaceApiKey(token)) {
|
|
1680
|
+
debug("ARCHAL_TOKEN is a workspace API key -- skipping JWT validation.");
|
|
1681
|
+
}
|
|
1682
|
+
return parsed.credentials;
|
|
1624
1683
|
}
|
|
1625
|
-
|
|
1626
|
-
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
1627
|
-
if (claims === null) {
|
|
1684
|
+
if (parsed.message.startsWith("ARCHAL_TOKEN must be a JWT")) {
|
|
1628
1685
|
getWarn(options)(
|
|
1629
1686
|
"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
1687
|
);
|
|
1631
1688
|
return null;
|
|
1632
1689
|
}
|
|
1633
|
-
|
|
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) {
|
|
1690
|
+
if (parsed.status === "expired") {
|
|
1645
1691
|
if (options?.onExpiredEnvToken === "throw") {
|
|
1646
1692
|
throw new ExpiredEnvTokenError();
|
|
1647
1693
|
}
|
|
1648
1694
|
debug("Ignoring expired ARCHAL_TOKEN from environment.");
|
|
1649
1695
|
return null;
|
|
1650
1696
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
refreshToken: "",
|
|
1654
|
-
email,
|
|
1655
|
-
plan,
|
|
1656
|
-
selectedCloneIds: [],
|
|
1657
|
-
expiresAt
|
|
1658
|
-
};
|
|
1697
|
+
getWarn(options)(`${parsed.message} Ignoring environment token.`);
|
|
1698
|
+
return null;
|
|
1659
1699
|
}
|
|
1660
1700
|
function getCredentials(options) {
|
|
1661
1701
|
const envValue = process.env[AUTH_TOKEN_ENV_VAR];
|
|
@@ -1703,7 +1743,7 @@ var import_node_net = require("net");
|
|
|
1703
1743
|
// ../packages/node-auth/src/secure-token.ts
|
|
1704
1744
|
var import_node_crypto2 = require("crypto");
|
|
1705
1745
|
|
|
1706
|
-
// ../packages/
|
|
1746
|
+
// ../packages/evaluator/src/log/ansi.ts
|
|
1707
1747
|
var NO_COLOR = "NO_COLOR" in process.env || process.env["TERM"] === "dumb";
|
|
1708
1748
|
var RESET = NO_COLOR ? "" : "\x1B[0m";
|
|
1709
1749
|
var BOLD = NO_COLOR ? "" : "\x1B[1m";
|
|
@@ -1713,7 +1753,7 @@ var YELLOW = NO_COLOR ? "" : "\x1B[33m";
|
|
|
1713
1753
|
var CYAN = NO_COLOR ? "" : "\x1B[36m";
|
|
1714
1754
|
var GRAY = NO_COLOR ? "" : "\x1B[90m";
|
|
1715
1755
|
|
|
1716
|
-
// ../packages/
|
|
1756
|
+
// ../packages/evaluator/src/log/logger.ts
|
|
1717
1757
|
var LOG_LEVEL_PRIORITY = {
|
|
1718
1758
|
debug: 0,
|
|
1719
1759
|
info: 1,
|
|
@@ -1776,6 +1816,12 @@ function warn(message, data) {
|
|
|
1776
1816
|
log("warn", message, data);
|
|
1777
1817
|
}
|
|
1778
1818
|
|
|
1819
|
+
// src/auth/cli-read-options.ts
|
|
1820
|
+
var CLI_CREDENTIAL_READ_OPTIONS = {
|
|
1821
|
+
onExpiredEnvToken: "throw",
|
|
1822
|
+
warn
|
|
1823
|
+
};
|
|
1824
|
+
|
|
1779
1825
|
// src/utils/version.ts
|
|
1780
1826
|
var import_node_fs2 = require("fs");
|
|
1781
1827
|
var import_node_path3 = require("path");
|
|
@@ -1815,7 +1861,6 @@ var CLI_VERSION = loadVersion();
|
|
|
1815
1861
|
var CLI_USER_AGENT = `archal-cli/${CLI_VERSION}`;
|
|
1816
1862
|
|
|
1817
1863
|
// src/auth/credential-store.ts
|
|
1818
|
-
var READ_OPTIONS = { onExpiredEnvToken: "throw", warn };
|
|
1819
1864
|
var cachedEnvToken = null;
|
|
1820
1865
|
var cachedEnvCredentials = null;
|
|
1821
1866
|
var cachedEnvCredentialsResolved = false;
|
|
@@ -1828,11 +1873,11 @@ function readExplicitEnvToken() {
|
|
|
1828
1873
|
function getCredentials2() {
|
|
1829
1874
|
const envToken = readExplicitEnvToken();
|
|
1830
1875
|
if (!envToken) {
|
|
1831
|
-
return getCredentials(
|
|
1876
|
+
return getCredentials(CLI_CREDENTIAL_READ_OPTIONS);
|
|
1832
1877
|
}
|
|
1833
1878
|
if (!cachedEnvCredentialsResolved || cachedEnvToken !== envToken) {
|
|
1834
1879
|
cachedEnvToken = envToken;
|
|
1835
|
-
cachedEnvCredentials = getCredentials(
|
|
1880
|
+
cachedEnvCredentials = getCredentials(CLI_CREDENTIAL_READ_OPTIONS);
|
|
1836
1881
|
cachedEnvCredentialsResolved = true;
|
|
1837
1882
|
}
|
|
1838
1883
|
return cachedEnvCredentials;
|
|
@@ -3070,103 +3115,359 @@ var baseProperties = {
|
|
|
3070
3115
|
};
|
|
3071
3116
|
|
|
3072
3117
|
// src/commands/autoloop-github-app.ts
|
|
3073
|
-
var
|
|
3118
|
+
var import_node_crypto5 = require("crypto");
|
|
3074
3119
|
|
|
3075
|
-
// src/
|
|
3076
|
-
var
|
|
3077
|
-
var
|
|
3120
|
+
// ../packages/contracts/src/evidence-redaction.ts
|
|
3121
|
+
var import_node_crypto4 = require("crypto");
|
|
3122
|
+
var EVIDENCE_REDACTED = "[REDACTED]";
|
|
3123
|
+
var EVIDENCE_SENSITIVE_KEY_PARTS = /* @__PURE__ */ new Set([
|
|
3078
3124
|
"token",
|
|
3079
3125
|
"secret",
|
|
3080
3126
|
"password",
|
|
3081
3127
|
"authorization",
|
|
3082
3128
|
"apikey",
|
|
3083
|
-
"api-key",
|
|
3084
3129
|
"api_key",
|
|
3085
3130
|
"credential",
|
|
3131
|
+
"credentials",
|
|
3086
3132
|
"cookie",
|
|
3087
3133
|
"privatekey",
|
|
3088
|
-
"private-key",
|
|
3089
3134
|
"private_key",
|
|
3090
3135
|
"accesskey",
|
|
3091
|
-
"access-key",
|
|
3092
3136
|
"access_key",
|
|
3093
3137
|
"databaseurl",
|
|
3094
|
-
"database-url",
|
|
3095
3138
|
"database_url",
|
|
3096
3139
|
"dburl",
|
|
3097
|
-
"db-url",
|
|
3098
3140
|
"db_url",
|
|
3141
|
+
"redisurl",
|
|
3142
|
+
"redis_url",
|
|
3143
|
+
"mongodburi",
|
|
3144
|
+
"mongo_uri",
|
|
3099
3145
|
"connectionstring",
|
|
3100
|
-
"connection-string",
|
|
3101
3146
|
"connection_string",
|
|
3102
3147
|
"dsn",
|
|
3103
|
-
"
|
|
3104
|
-
"
|
|
3105
|
-
"
|
|
3106
|
-
"
|
|
3107
|
-
|
|
3108
|
-
|
|
3148
|
+
"workspacekey",
|
|
3149
|
+
"workspace_key",
|
|
3150
|
+
"workspacetoken",
|
|
3151
|
+
"workspace_token",
|
|
3152
|
+
"accesscode",
|
|
3153
|
+
"access_code",
|
|
3154
|
+
"lockboxcode",
|
|
3155
|
+
"lockbox_code",
|
|
3156
|
+
"doorcode",
|
|
3157
|
+
"door_code",
|
|
3158
|
+
"otp",
|
|
3159
|
+
"iban",
|
|
3160
|
+
"clabe",
|
|
3161
|
+
"swift",
|
|
3162
|
+
"bic",
|
|
3163
|
+
"secretref",
|
|
3164
|
+
"secret_ref",
|
|
3165
|
+
"secretname",
|
|
3166
|
+
"secret_name"
|
|
3167
|
+
]);
|
|
3168
|
+
var EVIDENCE_SENSITIVE_ENV_KEY_PARTS = /* @__PURE__ */ new Set([
|
|
3169
|
+
...EVIDENCE_SENSITIVE_KEY_PARTS,
|
|
3170
|
+
"apikey",
|
|
3171
|
+
"api_key",
|
|
3172
|
+
"secretkey",
|
|
3173
|
+
"secret_key",
|
|
3174
|
+
"accesstoken",
|
|
3175
|
+
"access_token",
|
|
3176
|
+
"refreshtoken",
|
|
3177
|
+
"refresh_token",
|
|
3178
|
+
"authtoken",
|
|
3179
|
+
"auth_token",
|
|
3180
|
+
"bearertoken",
|
|
3181
|
+
"bearer_token",
|
|
3182
|
+
"privatekey",
|
|
3183
|
+
"private_key",
|
|
3184
|
+
"databaseurl",
|
|
3185
|
+
"database_url",
|
|
3186
|
+
"dburl",
|
|
3187
|
+
"db_url",
|
|
3188
|
+
"redisurl",
|
|
3189
|
+
"redis_url",
|
|
3190
|
+
"mongodburi",
|
|
3191
|
+
"mongo_uri",
|
|
3192
|
+
"connectionstring",
|
|
3193
|
+
"connection_string",
|
|
3194
|
+
"dsn"
|
|
3195
|
+
]);
|
|
3196
|
+
var EVIDENCE_SERVICE_STRING_PATTERNS = [
|
|
3109
3197
|
{
|
|
3110
|
-
pattern:
|
|
3111
|
-
replacement:
|
|
3198
|
+
pattern: /https?:\/\/[^\s"'<>]+\/runtime\/session\/[^\s"'<>]*/gi,
|
|
3199
|
+
replacement: "[SERVICE_ENDPOINT_REDACTED]"
|
|
3112
3200
|
},
|
|
3113
3201
|
{
|
|
3114
|
-
pattern:
|
|
3202
|
+
pattern: /\/runtime\/session\/[^\s"'<>]*/gi,
|
|
3203
|
+
replacement: "[SERVICE_ENDPOINT_REDACTED]"
|
|
3115
3204
|
},
|
|
3116
3205
|
{
|
|
3117
|
-
pattern: /\
|
|
3206
|
+
pattern: /\bx-archal-[\w-]+(?::|=)\s*["']?[^"',\s}]+/gi,
|
|
3207
|
+
replacement: "[SERVICE_HEADER_REDACTED]"
|
|
3118
3208
|
},
|
|
3119
3209
|
{
|
|
3120
|
-
pattern: /\
|
|
3210
|
+
pattern: /\barchal_mcp_servers\b/gi,
|
|
3211
|
+
replacement: "service_tool_servers"
|
|
3121
3212
|
},
|
|
3122
3213
|
{
|
|
3123
|
-
pattern: /\
|
|
3214
|
+
pattern: /\bARCHAL_(?:CLONE_URLS_PATH|TWIN_URLS_PATH|PROXY_EVENTS_PATH|METRICS_FILE|AGENT_TRACE_FILE|ENABLE_PROVIDER_EGRESS_PROXY)\b/g,
|
|
3215
|
+
replacement: "[SERVICE_RUNTIME_CONFIG_REDACTED]"
|
|
3124
3216
|
},
|
|
3125
3217
|
{
|
|
3126
|
-
pattern:
|
|
3218
|
+
pattern: /\/archal-artifacts\/[^\s"'<>]*/gi,
|
|
3219
|
+
replacement: "[SERVICE_ARTIFACT_PATH_REDACTED]"
|
|
3127
3220
|
},
|
|
3128
3221
|
{
|
|
3129
|
-
pattern: /\
|
|
3222
|
+
pattern: /\b(?:host\.docker\.internal|localhost|127\.0\.0\.1):9100\b/gi,
|
|
3223
|
+
replacement: "[SERVICE_PROXY_ENDPOINT_REDACTED]"
|
|
3130
3224
|
},
|
|
3131
3225
|
{
|
|
3132
|
-
pattern: /\b(?:
|
|
3133
|
-
replacement: "[
|
|
3226
|
+
pattern: /\b(?:aws-secretsmanager:\/\/|arn:aws:secretsmanager:[^\s"'<>:]+:\d{12}:secret:)[^\s"'<>]+/gi,
|
|
3227
|
+
replacement: "[SECRET_REF_REDACTED]"
|
|
3134
3228
|
},
|
|
3135
3229
|
{
|
|
3136
|
-
pattern: /\
|
|
3137
|
-
replacement:
|
|
3230
|
+
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,
|
|
3231
|
+
replacement: "[SECRET_REF_REDACTED]"
|
|
3138
3232
|
},
|
|
3139
3233
|
{
|
|
3140
|
-
pattern:
|
|
3234
|
+
pattern: /(?:file:\/\/)?(?:\/Users\/[^/\s"'<>]+|\/home\/[^/\s"'<>]+|\/private\/tmp|\/tmp|\/var\/folders|\/workspace|\/workspaces)(?:\/[^\s"'<>]*)?/g,
|
|
3235
|
+
replacement: "[LOCAL_PATH_REDACTED]"
|
|
3141
3236
|
},
|
|
3142
3237
|
{
|
|
3143
|
-
pattern: /\
|
|
3144
|
-
|
|
3238
|
+
pattern: /\b[A-Za-z]:\\Users\\[^\\\s"'<>]+(?:\\[^\s"'<>]*)?/g,
|
|
3239
|
+
replacement: "[LOCAL_PATH_REDACTED]"
|
|
3240
|
+
}
|
|
3241
|
+
];
|
|
3242
|
+
var FINANCIAL_IDENTIFIER_CONTEXT = String.raw`(?:account|acct|bank|beneficiary|intermediary|payment|payout|recipient|routing|transfer|wire)`;
|
|
3243
|
+
var HIGH_ENTROPY_SECRET = String.raw`(?<![A-Za-z0-9_/-])(?=[A-Za-z0-9_-]{32,}(?![A-Za-z0-9_-]))(?=[A-Za-z0-9_-]*[A-Z])(?=[A-Za-z0-9_-]*[a-z])(?=[A-Za-z0-9_-]*\d)[A-Za-z0-9_-]+(?![A-Za-z0-9_/-])`;
|
|
3244
|
+
var EVIDENCE_SECRET_LITERAL_STRING_PATTERNS = [
|
|
3145
3245
|
{
|
|
3146
|
-
pattern: /\
|
|
3246
|
+
pattern: /\b(Bearer\s+)[A-Za-z0-9._~+/=-]+\b/gi,
|
|
3247
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3147
3248
|
},
|
|
3148
3249
|
{
|
|
3149
|
-
pattern: /\b(
|
|
3250
|
+
pattern: /\b(gh[pousr]_[A-Za-z0-9]{16,})\b/g,
|
|
3251
|
+
replacement: EVIDENCE_REDACTED
|
|
3150
3252
|
},
|
|
3151
3253
|
{
|
|
3152
|
-
pattern: /\
|
|
3254
|
+
pattern: /\bgithub_pat_[A-Za-z0-9_]{16,}\b/g,
|
|
3255
|
+
replacement: EVIDENCE_REDACTED
|
|
3153
3256
|
},
|
|
3154
3257
|
{
|
|
3155
|
-
pattern:
|
|
3258
|
+
pattern: /\b[srp]k_(?:live|test)_[A-Za-z0-9]{16,}\b/g,
|
|
3259
|
+
replacement: EVIDENCE_REDACTED
|
|
3156
3260
|
},
|
|
3157
3261
|
{
|
|
3158
|
-
pattern:
|
|
3159
|
-
replacement:
|
|
3262
|
+
pattern: /\bsk-proj-[A-Za-z0-9_-]{16,}\b/g,
|
|
3263
|
+
replacement: EVIDENCE_REDACTED
|
|
3160
3264
|
},
|
|
3161
3265
|
{
|
|
3162
|
-
pattern: /\
|
|
3163
|
-
replacement:
|
|
3164
|
-
},
|
|
3266
|
+
pattern: /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
|
|
3267
|
+
replacement: EVIDENCE_REDACTED
|
|
3268
|
+
},
|
|
3269
|
+
{
|
|
3270
|
+
pattern: /\bsk-[A-Za-z0-9_-]{16,}\b/g,
|
|
3271
|
+
replacement: EVIDENCE_REDACTED
|
|
3272
|
+
},
|
|
3273
|
+
{
|
|
3274
|
+
pattern: /\barchal_(?:ws|workspace|token|key|pat|secret)_[A-Za-z0-9_.-]{8,}\b/gi,
|
|
3275
|
+
replacement: EVIDENCE_REDACTED
|
|
3276
|
+
},
|
|
3277
|
+
{
|
|
3278
|
+
pattern: /\bsb_(?:secret|publishable)_[A-Za-z0-9_-]{16,}\b/g,
|
|
3279
|
+
replacement: EVIDENCE_REDACTED
|
|
3280
|
+
},
|
|
3281
|
+
{
|
|
3282
|
+
pattern: /\bpostgres(?:ql)?:\/\/[^\s"'<>]+/gi,
|
|
3283
|
+
replacement: "[DATABASE_URL_REDACTED]"
|
|
3284
|
+
},
|
|
3285
|
+
{
|
|
3286
|
+
pattern: /\b(?:redis|rediss|mysql|mariadb|mongodb(?:\+srv)?|amqp|amqps):\/\/[^\s"'<>]+/gi,
|
|
3287
|
+
replacement: "[CONNECTION_STRING_REDACTED]"
|
|
3288
|
+
},
|
|
3289
|
+
{
|
|
3290
|
+
pattern: /\b[A-Za-z][A-Za-z0-9+.-]*:\/\/[^:\s/@]+:[^@\s/]+@[^\s"'<>]+/gi,
|
|
3291
|
+
replacement: "[BASIC_AUTH_URL_REDACTED]"
|
|
3292
|
+
},
|
|
3165
3293
|
{
|
|
3166
|
-
pattern: /\
|
|
3167
|
-
replacement:
|
|
3294
|
+
pattern: /\bAIza[0-9A-Za-z_-]{12,}\b/g,
|
|
3295
|
+
replacement: EVIDENCE_REDACTED
|
|
3296
|
+
},
|
|
3297
|
+
{
|
|
3298
|
+
pattern: /\b(?:xox[baprs]-[A-Za-z0-9-]{10,})\b/g,
|
|
3299
|
+
replacement: EVIDENCE_REDACTED
|
|
3300
|
+
},
|
|
3301
|
+
{
|
|
3302
|
+
pattern: /\bx(?:app|oxa|oxc|oxp|oxs)-[A-Za-z0-9-]{10,}\b/g,
|
|
3303
|
+
replacement: EVIDENCE_REDACTED
|
|
3304
|
+
},
|
|
3305
|
+
{
|
|
3306
|
+
pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
3307
|
+
replacement: EVIDENCE_REDACTED
|
|
3308
|
+
},
|
|
3309
|
+
{
|
|
3310
|
+
pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9._-]{10,}\.[A-Za-z0-9._-]{10,}\b/g,
|
|
3311
|
+
replacement: EVIDENCE_REDACTED
|
|
3312
|
+
},
|
|
3313
|
+
{
|
|
3314
|
+
pattern: /-----BEGIN(?:[ A-Z]+)?PRIVATE KEY-----[\s\S]*?-----END(?:[ A-Z]+)?PRIVATE KEY-----/g,
|
|
3315
|
+
replacement: EVIDENCE_REDACTED
|
|
3316
|
+
},
|
|
3317
|
+
{
|
|
3318
|
+
pattern: /(^|[?&])((?:token|access_token|refresh_token|auth_token|bearer_token|client_secret|secret|api_key|apikey|password)=)[^&\s]+/gi,
|
|
3319
|
+
replacement: `$1$2${EVIDENCE_REDACTED}`
|
|
3320
|
+
},
|
|
3321
|
+
{
|
|
3322
|
+
pattern: /\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b/g,
|
|
3323
|
+
replacement: EVIDENCE_REDACTED
|
|
3324
|
+
},
|
|
3325
|
+
{
|
|
3326
|
+
pattern: new RegExp(String.raw`\b(${FINANCIAL_IDENTIFIER_CONTEXT}\s+)\d{18}\b`, "gi"),
|
|
3327
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3328
|
+
},
|
|
3329
|
+
{
|
|
3330
|
+
pattern: new RegExp(
|
|
3331
|
+
String.raw`\b(${FINANCIAL_IDENTIFIER_CONTEXT}\s+)(?!REDACTED\b)[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b`,
|
|
3332
|
+
"g"
|
|
3333
|
+
),
|
|
3334
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3335
|
+
},
|
|
3336
|
+
{
|
|
3337
|
+
pattern: new RegExp(HIGH_ENTROPY_SECRET, "g"),
|
|
3338
|
+
replacement: EVIDENCE_REDACTED
|
|
3168
3339
|
}
|
|
3169
3340
|
];
|
|
3341
|
+
var EVIDENCE_SENSITIVE_LABEL = String.raw`(?:authorization|token|access[_ -]?token|refresh[_ -]?token|id[_ -]?token|auth[_ -]?token|session[_ -]?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|access[_ -]?key|credential|credentials|access[_ -]?code|lockbox[_ -]?code|door[_ -]?code|otp|one[_ -]?time[_ -]?password|iban|clabe|swift|bic)`;
|
|
3342
|
+
var EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT = String.raw`(?:\*\*)?["']?${EVIDENCE_SENSITIVE_LABEL}["']?\s*[:=](?:\*\*)?\s*`;
|
|
3343
|
+
var EVIDENCE_SENSITIVE_LABEL_HINT = new RegExp(
|
|
3344
|
+
String.raw`\b${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT}`,
|
|
3345
|
+
"i"
|
|
3346
|
+
);
|
|
3347
|
+
var EVIDENCE_FINANCIAL_IDENTIFIER_HINT = new RegExp(
|
|
3348
|
+
String.raw`(\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b|\b${FINANCIAL_IDENTIFIER_CONTEXT}\s+\d{18}\b|\b${FINANCIAL_IDENTIFIER_CONTEXT}\s+(?!REDACTED\b)[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b)`,
|
|
3349
|
+
"i"
|
|
3350
|
+
);
|
|
3351
|
+
var EVIDENCE_HIGH_ENTROPY_SECRET_HINT = new RegExp(HIGH_ENTROPY_SECRET);
|
|
3352
|
+
var EVIDENCE_SECRET_REDACTION_MARKER = String.raw`(?:\[[A-Z0-9_]*REDACTED\]|\[FILTERED\]|\[MASKED\]|<redacted>)`;
|
|
3353
|
+
var EVIDENCE_KEY_VALUE_STRING_PATTERNS = [
|
|
3354
|
+
{
|
|
3355
|
+
pattern: new RegExp(
|
|
3356
|
+
String.raw`\b(${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT})(?!\s*(?:\[[A-Z0-9_]+\]|<redacted>))(?:"[^"\r\n]*"|'[^'\r\n]*'|Bearer\s+\[REDACTED\]|Bearer\s+.+?|.+?)(?=(?:\s+${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT})|[\r\n,}\]&]|$)`,
|
|
3357
|
+
"gi"
|
|
3358
|
+
),
|
|
3359
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3360
|
+
},
|
|
3361
|
+
{
|
|
3362
|
+
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,
|
|
3363
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3364
|
+
},
|
|
3365
|
+
{
|
|
3366
|
+
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,
|
|
3367
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3368
|
+
},
|
|
3369
|
+
{
|
|
3370
|
+
// Fail-open recovery. When a sensitive label's value was already replaced
|
|
3371
|
+
// with a redaction marker but a bare secret still trails it
|
|
3372
|
+
// (`password: [REDACTED] dGVzdA==`), the assignment patterns above skip the
|
|
3373
|
+
// match — their `(?!marker)` guard fires on the marker — and leave the tail
|
|
3374
|
+
// exposed. Redact the trailing token too. This fails closed but is
|
|
3375
|
+
// deliberately narrow to avoid mangling ordinary prose that follows a
|
|
3376
|
+
// redacted value (`token=[REDACTED] for /path`, `...=[REDACTED] rotated`):
|
|
3377
|
+
// - the marker must be a real secret marker (`[…REDACTED]`, `[FILTERED]`,
|
|
3378
|
+
// `[MASKED]`, `<redacted>`), NOT a semantic placeholder like `[url]` or
|
|
3379
|
+
// `[path]`, and a `[FILTERED]` producer is still covered;
|
|
3380
|
+
// - the recovered trailing token must be SECRET-SHAPED — quoted, or ≥6
|
|
3381
|
+
// chars containing at least one digit or base64/token symbol
|
|
3382
|
+
// (`0-9 + / = _ -`). base64 padding (`dGVzdA==`) qualifies; bare
|
|
3383
|
+
// dictionary words (`for`, `rotated`, `successfully`) do not, so prose is
|
|
3384
|
+
// left intact;
|
|
3385
|
+
// - the marker itself is skipped (idempotent) and a following sensitive
|
|
3386
|
+
// `key:`/`key=` assignment is deferred to the primary patterns, so this
|
|
3387
|
+
// does not gobble the next labeled field.
|
|
3388
|
+
pattern: new RegExp(
|
|
3389
|
+
String.raw`\b(${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT}${EVIDENCE_SECRET_REDACTION_MARKER}[ \t]+)(?!${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT})(?!${EVIDENCE_SECRET_REDACTION_MARKER})(?:"[^"\r\n]*"|'[^'\r\n]*'|(?=[^\s,}\]&]*[0-9+/=_-])[^\s,}\]&]{6,})`,
|
|
3390
|
+
"gi"
|
|
3391
|
+
),
|
|
3392
|
+
replacement: `$1${EVIDENCE_REDACTED}`
|
|
3393
|
+
}
|
|
3394
|
+
];
|
|
3395
|
+
var EVIDENCE_SECRET_NAME_STRING_PATTERNS = [
|
|
3396
|
+
{
|
|
3397
|
+
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(?!\s*[:=])/g,
|
|
3398
|
+
replacement: "[SECRET_NAME_REDACTED]"
|
|
3399
|
+
}
|
|
3400
|
+
];
|
|
3401
|
+
var EVIDENCE_STRING_PATTERNS = [
|
|
3402
|
+
...EVIDENCE_SERVICE_STRING_PATTERNS,
|
|
3403
|
+
...EVIDENCE_SECRET_LITERAL_STRING_PATTERNS,
|
|
3404
|
+
...EVIDENCE_KEY_VALUE_STRING_PATTERNS,
|
|
3405
|
+
...EVIDENCE_SECRET_NAME_STRING_PATTERNS
|
|
3406
|
+
];
|
|
3407
|
+
function getEvidenceSecretRedactionPatterns() {
|
|
3408
|
+
return [...EVIDENCE_SECRET_LITERAL_STRING_PATTERNS, ...EVIDENCE_KEY_VALUE_STRING_PATTERNS].map(
|
|
3409
|
+
({ pattern, replacement }) => ({
|
|
3410
|
+
pattern: new RegExp(pattern.source, pattern.flags),
|
|
3411
|
+
replacement
|
|
3412
|
+
})
|
|
3413
|
+
);
|
|
3414
|
+
}
|
|
3415
|
+
var EVIDENCE_STRING_REDACTION_HINT = new RegExp(
|
|
3416
|
+
String.raw`(\/runtime\/session\/|x-archal-|archal_mcp_servers|\bARCHAL_(?:CLONE_URLS_PATH|TWIN_URLS_PATH|PROXY_EVENTS_PATH|METRICS_FILE|AGENT_TRACE_FILE|ENABLE_PROVIDER_EGRESS_PROXY)\b|\/archal-artifacts\/|\b(?:host\.docker\.internal|localhost|127\.0\.0\.1):9100\b|\b(?:aws-secretsmanager:\/\/|arn:aws:secretsmanager:)|\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|(?:file:\/\/)?(?:\/Users\/|\/home\/|\/private\/tmp|\/tmp|\/var\/folders|\/workspace|\/workspaces)|\b[A-Za-z]:\\Users\\|bearer\s+|gh[pousr]_|github_pat_|[srp]k_(?:live|test)_|sk-proj-|sk-ant-|sk-|archal_(?:ws|workspace|token|key|pat|secret)_|sb_(?:secret|publishable)_|postgres(?:ql)?:\/\/|(?:redis|rediss|mysql|mariadb|mongodb(?:\+srv)?|amqp|amqps):\/\/|\b[A-Za-z][A-Za-z0-9+.-]*:\/\/[^:\s/@]+:[^@\s/]+@|AIza|xox[baprs]-|x(?:app|oxa|oxc|oxp|oxs)-|(?:AKIA|ASIA)|eyJ|\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b|\b${FINANCIAL_IDENTIFIER_CONTEXT}\s+\d{18}\b|\b${FINANCIAL_IDENTIFIER_CONTEXT}\s+(?!REDACTED\b)[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b|${HIGH_ENTROPY_SECRET}|private key|(?:^|[?&])(?:token|access_token|refresh_token|auth_token|bearer_token|client_secret|secret|api_key|apikey|password)=|\b${EVIDENCE_SENSITIVE_LABEL_ASSIGNMENT}|\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*[:=]|\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*[:=]|\b))`,
|
|
3417
|
+
"i"
|
|
3418
|
+
);
|
|
3419
|
+
|
|
3420
|
+
// ../packages/trace-normalize/src/redaction.ts
|
|
3421
|
+
var TRACE_REDACTED = "[REDACTED]";
|
|
3422
|
+
var DEFAULT_SENSITIVE_TRACE_KEY_PARTS = [
|
|
3423
|
+
"token",
|
|
3424
|
+
"secret",
|
|
3425
|
+
"password",
|
|
3426
|
+
"authorization",
|
|
3427
|
+
"apikey",
|
|
3428
|
+
"api-key",
|
|
3429
|
+
"api_key",
|
|
3430
|
+
"credential",
|
|
3431
|
+
"cookie",
|
|
3432
|
+
"privatekey",
|
|
3433
|
+
"private-key",
|
|
3434
|
+
"private_key",
|
|
3435
|
+
"accesskey",
|
|
3436
|
+
"access-key",
|
|
3437
|
+
"access_key",
|
|
3438
|
+
"databaseurl",
|
|
3439
|
+
"database-url",
|
|
3440
|
+
"database_url",
|
|
3441
|
+
"dburl",
|
|
3442
|
+
"db-url",
|
|
3443
|
+
"db_url",
|
|
3444
|
+
"connectionstring",
|
|
3445
|
+
"connection-string",
|
|
3446
|
+
"connection_string",
|
|
3447
|
+
"dsn",
|
|
3448
|
+
"card",
|
|
3449
|
+
"cardnumber",
|
|
3450
|
+
"creditcard",
|
|
3451
|
+
"pan"
|
|
3452
|
+
];
|
|
3453
|
+
var TRACE_SOURCE_URL_PATTERNS = [
|
|
3454
|
+
{
|
|
3455
|
+
pattern: /\b(?:postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis|rediss):\/\/[^\s"'<>]+/gi,
|
|
3456
|
+
replacement: "[CONNECTION_URL_REDACTED]"
|
|
3457
|
+
},
|
|
3458
|
+
{
|
|
3459
|
+
pattern: /\b(https?:\/\/)[^/\s"'<>@]+@/gi,
|
|
3460
|
+
replacement: `$1${TRACE_REDACTED}@`
|
|
3461
|
+
},
|
|
3462
|
+
{
|
|
3463
|
+
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,
|
|
3464
|
+
replacement: `$1$2${TRACE_REDACTED}`
|
|
3465
|
+
}
|
|
3466
|
+
];
|
|
3467
|
+
var DEFAULT_SECRET_TRACE_STRING_PATTERNS = [
|
|
3468
|
+
...TRACE_SOURCE_URL_PATTERNS,
|
|
3469
|
+
...getEvidenceSecretRedactionPatterns()
|
|
3470
|
+
];
|
|
3170
3471
|
var DEFAULT_TRACE_REDACTION_POLICY = {
|
|
3171
3472
|
enabled: true,
|
|
3172
3473
|
mode: "mask",
|
|
@@ -3196,7 +3497,7 @@ function redactTraceString(value, policy = DEFAULT_TRACE_REDACTION_POLICY) {
|
|
|
3196
3497
|
return redacted;
|
|
3197
3498
|
}
|
|
3198
3499
|
|
|
3199
|
-
// src/
|
|
3500
|
+
// src/github/github-rest.ts
|
|
3200
3501
|
function normalizeRepositoryFullName(value) {
|
|
3201
3502
|
const trimmed = value?.trim();
|
|
3202
3503
|
if (!trimmed || !/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(trimmed)) return void 0;
|
|
@@ -3208,7 +3509,6 @@ var GITHUB_APP_INSTALLATION_PERMISSIONS = {
|
|
|
3208
3509
|
actions: "read",
|
|
3209
3510
|
checks: "read",
|
|
3210
3511
|
contents: "write",
|
|
3211
|
-
issues: "write",
|
|
3212
3512
|
metadata: "read",
|
|
3213
3513
|
pull_requests: "write",
|
|
3214
3514
|
statuses: "read"
|
|
@@ -3367,7 +3667,7 @@ function buildGithubAppJwt(input) {
|
|
|
3367
3667
|
iss: input.appId
|
|
3368
3668
|
});
|
|
3369
3669
|
const signingInput = `${header}.${payload}`;
|
|
3370
|
-
const signature = (0,
|
|
3670
|
+
const signature = (0, import_node_crypto5.createSign)("RSA-SHA256").update(signingInput).end().sign(normalizePem2(input.privateKey), "base64url");
|
|
3371
3671
|
return `${signingInput}.${signature}`;
|
|
3372
3672
|
}
|
|
3373
3673
|
function base64UrlJson(value) {
|
|
@@ -3377,217 +3677,6 @@ function normalizePem2(value) {
|
|
|
3377
3677
|
return value.replace(/\\n/g, "\n").replace(/\\\r?\n/g, "\n").replace(/\\/g, "\n");
|
|
3378
3678
|
}
|
|
3379
3679
|
|
|
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
3680
|
// src/commands/autoloop-fix-pr-quality.ts
|
|
3592
3681
|
function assessFixPrPayload(payload, input = {}) {
|
|
3593
3682
|
const assessment = assessAutoloopStoredFixPrEvidence(payload, {
|
|
@@ -3639,25 +3728,21 @@ async function verifyFixResult(result, input) {
|
|
|
3639
3728
|
if (verdict.state === "unverifiable") {
|
|
3640
3729
|
return {
|
|
3641
3730
|
...result,
|
|
3642
|
-
status: "
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
summary: `${result.summary} Reported open PR could not be verified.`
|
|
3731
|
+
status: "pr_open",
|
|
3732
|
+
latestCheckState: "unknown",
|
|
3733
|
+
blockingReason: void 0,
|
|
3734
|
+
summary: `${result.summary} Reported open PR could not be verified yet.`
|
|
3647
3735
|
};
|
|
3648
3736
|
}
|
|
3649
3737
|
const postFixReproduction2 = autoloopPostFixReproductionEvidenceFromPayload(result.payload, {
|
|
3650
3738
|
expectedCommitSha: verdict.headSha
|
|
3651
3739
|
});
|
|
3652
3740
|
if (!postFixReproduction2.passed) {
|
|
3653
|
-
return
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
blockingReason: postFixReproduction2.reason,
|
|
3659
|
-
summary: `${result.summary} PR not surfaced as post-fix clone reproduction evidence is insufficient: ${postFixReproduction2.reason}.`
|
|
3660
|
-
};
|
|
3741
|
+
return blockedOpenPrResult(
|
|
3742
|
+
result,
|
|
3743
|
+
postFixReproduction2.reason,
|
|
3744
|
+
`PR not surfaced as ready because post-fix reproduction evidence is insufficient: ${postFixReproduction2.reason}.`
|
|
3745
|
+
);
|
|
3661
3746
|
}
|
|
3662
3747
|
const mismatch2 = prReferenceMatchFailure(result, input.repositoryFullName, verdict, input);
|
|
3663
3748
|
if (mismatch2) {
|
|
@@ -3672,14 +3757,11 @@ async function verifyFixResult(result, input) {
|
|
|
3672
3757
|
}
|
|
3673
3758
|
const initialPostFixReproduction = autoloopPostFixReproductionEvidenceFromPayload(result.payload);
|
|
3674
3759
|
if (!initialPostFixReproduction.passed) {
|
|
3675
|
-
return
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
blockingReason: initialPostFixReproduction.reason,
|
|
3681
|
-
summary: `${result.summary} Post-fix clone reproduction evidence is insufficient: ${initialPostFixReproduction.reason}.`
|
|
3682
|
-
};
|
|
3760
|
+
return blockedOpenPrResult(
|
|
3761
|
+
result,
|
|
3762
|
+
initialPostFixReproduction.reason,
|
|
3763
|
+
`Post-fix clone reproduction evidence is insufficient: ${initialPostFixReproduction.reason}.`
|
|
3764
|
+
);
|
|
3683
3765
|
}
|
|
3684
3766
|
const token = await resolveVerificationToken(input);
|
|
3685
3767
|
const checks = token ? await fetchGithubPrChecks(pr, token).catch(() => unverifiedGithubPrChecks()) : unverifiedGithubPrChecks();
|
|
@@ -3698,14 +3780,11 @@ async function verifyFixResult(result, input) {
|
|
|
3698
3780
|
expectedCommitSha: checks.headSha
|
|
3699
3781
|
});
|
|
3700
3782
|
if (!postFixReproduction.passed) {
|
|
3701
|
-
return
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
blockingReason: postFixReproduction.reason,
|
|
3707
|
-
summary: `${result.summary} Post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
|
|
3708
|
-
};
|
|
3783
|
+
return blockedOpenPrResult(
|
|
3784
|
+
result,
|
|
3785
|
+
postFixReproduction.reason,
|
|
3786
|
+
`Post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
|
|
3787
|
+
);
|
|
3709
3788
|
}
|
|
3710
3789
|
const mismatch = prReferenceMatchFailure(result, input.repositoryFullName, checks, input);
|
|
3711
3790
|
if (mismatch) {
|
|
@@ -3761,14 +3840,11 @@ async function verifyOpenFixPrPoll(result, input) {
|
|
|
3761
3840
|
expectedCommitSha: checks.headSha
|
|
3762
3841
|
});
|
|
3763
3842
|
if (!postFixReproduction.passed) {
|
|
3764
|
-
return
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
blockingReason: postFixReproduction.reason,
|
|
3770
|
-
summary: `${result.summary} Open PR cannot become ready because post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
|
|
3771
|
-
};
|
|
3843
|
+
return blockedOpenPrResult(
|
|
3844
|
+
result,
|
|
3845
|
+
postFixReproduction.reason,
|
|
3846
|
+
`Open PR cannot become ready because post-fix clone reproduction evidence is insufficient: ${postFixReproduction.reason}.`
|
|
3847
|
+
);
|
|
3772
3848
|
}
|
|
3773
3849
|
const branchReason = prReferenceMatchFailure(result, input.repositoryFullName, checks, input);
|
|
3774
3850
|
if (branchReason) {
|
|
@@ -3820,6 +3896,15 @@ function verifiedQualityResult(result, checks, latestCheckState = "passing") {
|
|
|
3820
3896
|
`Generated PR evidence is insufficient: ${quality.reason}.`
|
|
3821
3897
|
);
|
|
3822
3898
|
}
|
|
3899
|
+
function blockedOpenPrResult(result, blockingReason, summary) {
|
|
3900
|
+
return {
|
|
3901
|
+
...result,
|
|
3902
|
+
status: "blocked",
|
|
3903
|
+
latestCheckState: "blocked",
|
|
3904
|
+
blockingReason,
|
|
3905
|
+
summary: `${result.summary} ${summary}`
|
|
3906
|
+
};
|
|
3907
|
+
}
|
|
3823
3908
|
function localValidationPassed(payload) {
|
|
3824
3909
|
return isRecord2(payload) && payload["localValidationStatus"] === "passed";
|
|
3825
3910
|
}
|