firedrill-run 2.2.5 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -22
- package/bin/firedrill.mjs +29 -5
- package/dist/assembly.json +13 -0
- package/dist/cli/runtime/candidate_copy.py +395 -0
- package/dist/cli/runtime/source_snapshot.py +391 -0
- package/dist/cli/src/administration.js +295 -0
- package/dist/cli/src/agent-changes.js +496 -0
- package/dist/cli/src/assessment-requests.js +67 -0
- package/dist/cli/src/auth.js +506 -0
- package/dist/cli/src/billing-commerce-contracts.js +1 -0
- package/dist/cli/src/billing-usage.js +227 -0
- package/dist/cli/src/billing-wallet-contracts.js +1 -0
- package/dist/cli/src/billing.js +170 -0
- package/dist/cli/src/bootstrap-process-lock.js +136 -0
- package/dist/cli/src/browser-links.js +14 -0
- package/dist/cli/src/campaign-controls.js +122 -0
- package/dist/cli/src/campaign-diagnoses.js +118 -0
- package/dist/cli/src/campaign-reports.js +1215 -0
- package/dist/cli/src/campaign-world.js +156 -0
- package/dist/cli/src/candidate-copy.js +376 -0
- package/dist/cli/src/catalog-contracts.js +1 -0
- package/dist/cli/src/ci-access-contracts.js +1 -0
- package/dist/cli/src/ci-configuration-contracts.js +1 -0
- package/dist/cli/src/ci-coverage.js +64 -0
- package/dist/cli/src/ci-delivery-contracts.js +1 -0
- package/dist/cli/src/ci-result-contracts.js +1 -0
- package/dist/cli/src/ci-run-contracts.js +1 -0
- package/dist/cli/src/ci-setup-proposals.js +52 -0
- package/dist/cli/src/company-policies.js +229 -0
- package/dist/cli/src/completion.js +79 -0
- package/dist/cli/src/configuration-intents.js +277 -0
- package/dist/cli/src/configuration.js +369 -0
- package/dist/cli/src/continuous-simulation.js +277 -0
- package/dist/cli/src/coordinated-checkpoints.js +133 -0
- package/dist/cli/src/credential-mode.js +139 -0
- package/dist/cli/src/credentials.js +331 -0
- package/dist/cli/src/credit-format.js +8 -0
- package/dist/cli/src/dataset-contracts.js +1 -0
- package/dist/cli/src/dataset-export.js +154 -0
- package/dist/cli/src/dataset-reads.js +37 -0
- package/dist/cli/src/dependency-preparation.js +239 -0
- package/dist/cli/src/director-tool-setup.js +104 -0
- package/dist/cli/src/driver-review.js +225 -0
- package/dist/cli/src/evaluation-authoring.js +315 -0
- package/dist/cli/src/evidence-bundles.js +367 -0
- package/dist/cli/src/execution-proposals.js +36 -0
- package/dist/cli/src/http.js +302 -0
- package/dist/cli/src/local-container-boundary.js +38 -0
- package/dist/cli/src/local-container-policy.js +201 -0
- package/dist/cli/src/local-execution-setup.js +81 -0
- package/dist/cli/src/local-source-basis.js +73 -0
- package/dist/cli/src/local-source.js +66 -0
- package/dist/cli/src/local-value-store.js +91 -0
- package/dist/cli/src/local-values.js +163 -0
- package/dist/cli/src/login-organizations.js +70 -0
- package/dist/cli/src/main.js +1627 -0
- package/dist/cli/src/mcp-connection.js +109 -0
- package/dist/cli/src/native/bindings.js +137 -0
- package/dist/cli/src/native/canonical.js +370 -0
- package/dist/cli/src/native/cloud-resources.js +942 -0
- package/dist/cli/src/native/companion-channel.js +421 -0
- package/dist/cli/src/native/companion-ipc.js +473 -0
- package/dist/cli/src/native/contracts.js +218 -0
- package/dist/cli/src/native/control-plane.js +1354 -0
- package/dist/cli/src/native/credit-approval.js +15 -0
- package/dist/cli/src/native/dependency-proxy.js +1006 -0
- package/dist/cli/src/native/drill-cleanup.js +115 -0
- package/dist/cli/src/native/drill-runner.js +1562 -0
- package/dist/cli/src/native/drivers/action-trace.js +210 -0
- package/dist/cli/src/native/drivers/function-wrapper.js +152 -0
- package/dist/cli/src/native/drivers/http.js +442 -0
- package/dist/cli/src/native/drivers/index.js +47 -0
- package/dist/cli/src/native/drivers/jsonl-process.js +538 -0
- package/dist/cli/src/native/drivers/playwright.js +600 -0
- package/dist/cli/src/native/drivers/signed-event.js +244 -0
- package/dist/cli/src/native/drivers/types.js +578 -0
- package/dist/cli/src/native/evidence-filter.js +255 -0
- package/dist/cli/src/native/isolated-access.js +241 -0
- package/dist/cli/src/native/library-sharing.js +220 -0
- package/dist/cli/src/native/local-run.js +667 -0
- package/dist/cli/src/native/local-secrets.js +19 -0
- package/dist/cli/src/native/mcp-config.js +123 -0
- package/dist/cli/src/native/metadata-requests.js +120 -0
- package/dist/cli/src/native/observations.js +1159 -0
- package/dist/cli/src/native/owned-groups.js +46 -0
- package/dist/cli/src/native/plan.js +594 -0
- package/dist/cli/src/native/png.js +159 -0
- package/dist/cli/src/native/ports.js +43 -0
- package/dist/cli/src/native/readiness.js +139 -0
- package/dist/cli/src/native/reassessments.js +206 -0
- package/dist/cli/src/native/redaction.js +235 -0
- package/dist/cli/src/native/registration.js +155 -0
- package/dist/cli/src/native/roots.js +110 -0
- package/dist/cli/src/native/run-cleanup.js +199 -0
- package/dist/cli/src/native/scratch.js +117 -0
- package/dist/cli/src/native/screenshots.js +60 -0
- package/dist/cli/src/native/session.js +556 -0
- package/dist/cli/src/native/standalone-proxy.js +580 -0
- package/dist/cli/src/native/standalone-renewals.js +183 -0
- package/dist/cli/src/native/standalone-state.js +193 -0
- package/dist/cli/src/native/standalone-tools.js +187 -0
- package/dist/cli/src/native/supervisor.js +831 -0
- package/dist/cli/src/native/target-auth.js +161 -0
- package/dist/cli/src/native/target-state.js +330 -0
- package/dist/cli/src/native/tool-reuse.js +364 -0
- package/dist/cli/src/native/tool-setups.js +336 -0
- package/dist/cli/src/native/world-reuse.js +288 -0
- package/dist/cli/src/onboarding.js +23 -0
- package/dist/cli/src/priority-requests.js +70 -0
- package/dist/cli/src/priority.js +223 -0
- package/dist/cli/src/prompts.js +184 -0
- package/dist/cli/src/real-operations.js +221 -0
- package/dist/cli/src/recipe-intents.js +58 -0
- package/dist/cli/src/recorded-context-intents.js +59 -0
- package/dist/cli/src/recorded-context.js +248 -0
- package/dist/cli/src/recordings.js +69 -0
- package/dist/cli/src/registration-guide.js +39 -0
- package/dist/cli/src/report-exports.js +213 -0
- package/dist/cli/src/request-input.js +47 -0
- package/dist/cli/src/resource-lifecycle.js +141 -0
- package/dist/cli/src/revision-requests.js +55 -0
- package/dist/cli/src/runner-abandon.js +53 -0
- package/dist/cli/src/runner-campaign-controls.js +262 -0
- package/dist/cli/src/runner-claim-reads.js +36 -0
- package/dist/cli/src/runner-completion.js +65 -0
- package/dist/cli/src/runner-configuration.js +546 -0
- package/dist/cli/src/runner-container.js +794 -0
- package/dist/cli/src/runner-evidence-erasure.js +351 -0
- package/dist/cli/src/runner-evidence-privacy.js +37 -0
- package/dist/cli/src/runner-evidence-retention.js +161 -0
- package/dist/cli/src/runner-evidence.js +326 -0
- package/dist/cli/src/runner-execute.js +92 -0
- package/dist/cli/src/runner-execution-deadline.js +25 -0
- package/dist/cli/src/runner-grants.js +307 -0
- package/dist/cli/src/runner-identity.js +615 -0
- package/dist/cli/src/runner-inputs.js +308 -0
- package/dist/cli/src/runner-jobs.js +49 -0
- package/dist/cli/src/runner-model-transport.js +392 -0
- package/dist/cli/src/runner-ownership.js +332 -0
- package/dist/cli/src/runner-process-lock.js +175 -0
- package/dist/cli/src/runner-runtime.js +396 -0
- package/dist/cli/src/runner-session-channel.js +377 -0
- package/dist/cli/src/runner-trial-completion.js +34 -0
- package/dist/cli/src/runner-trial-journal.js +358 -0
- package/dist/cli/src/runner-trial-live.js +393 -0
- package/dist/cli/src/runner-trial-protocol.js +289 -0
- package/dist/cli/src/runner-trial-sync.js +110 -0
- package/dist/cli/src/runner-trial-transfer.js +107 -0
- package/dist/cli/src/runner-voice.js +40 -0
- package/dist/cli/src/runner-world-claim.js +21 -0
- package/dist/cli/src/runner-world-collector.js +159 -0
- package/dist/cli/src/runner-world-command-evidence.js +487 -0
- package/dist/cli/src/runner-world-commands.js +268 -0
- package/dist/cli/src/runner-world-completion.js +76 -0
- package/dist/cli/src/runner-world-erasure.js +95 -0
- package/dist/cli/src/runner-world-evidence-sync.js +91 -0
- package/dist/cli/src/runner-world-journal.js +510 -0
- package/dist/cli/src/runner-world-native-filters.js +134 -0
- package/dist/cli/src/runner-world-observations.js +50 -0
- package/dist/cli/src/runner-world-session-protocol.js +134 -0
- package/dist/cli/src/saved-records.js +40 -0
- package/dist/cli/src/scenario-authoring.js +212 -0
- package/dist/cli/src/scenario-discovery.js +216 -0
- package/dist/cli/src/scenario-paths.js +68 -0
- package/dist/cli/src/scenario-requests.js +4 -0
- package/dist/cli/src/service-receipts.js +105 -0
- package/dist/cli/src/simple/authoring.js +270 -0
- package/dist/cli/src/simple/credit-approval.js +16 -0
- package/dist/cli/src/simple/help.js +98 -0
- package/dist/cli/src/simple/init.js +96 -0
- package/dist/cli/src/simple/library-sharing.js +414 -0
- package/dist/cli/src/simple/metadata-requests.js +46 -0
- package/dist/cli/src/simple/native-report.js +841 -0
- package/dist/cli/src/simple/native-tools.js +780 -0
- package/dist/cli/src/simple/plan-apply.js +506 -0
- package/dist/cli/src/simple/reassessment.js +323 -0
- package/dist/cli/src/simple/register.js +123 -0
- package/dist/cli/src/simple/run.js +122 -0
- package/dist/cli/src/simple/status.js +49 -0
- package/dist/cli/src/simple/tool-renewal.js +308 -0
- package/dist/cli/src/simple/tool-reuse.js +526 -0
- package/dist/cli/src/simple/tool-start-catalog.js +100 -0
- package/dist/cli/src/simple/tool-state.js +426 -0
- package/dist/cli/src/simple/tools-author.js +222 -0
- package/dist/cli/src/simple/watch.js +28 -0
- package/dist/cli/src/simple/world-reuse.js +586 -0
- package/dist/cli/src/simulation-intents.js +406 -0
- package/dist/cli/src/simulation-run.js +1058 -0
- package/dist/cli/src/source-batch.js +322 -0
- package/dist/cli/src/source-connection.js +451 -0
- package/dist/cli/src/source-runtime.js +346 -0
- package/dist/cli/src/source-selection-intents.js +75 -0
- package/dist/cli/src/source-sets.js +214 -0
- package/dist/cli/src/target-models.js +109 -0
- package/dist/cli/src/tool-catalog.js +224 -0
- package/dist/cli/src/tool-command-contracts.js +1 -0
- package/dist/cli/src/tool-command-export.js +245 -0
- package/dist/cli/src/tool-connection-contracts.js +1 -0
- package/dist/cli/src/tool-connection-reads.js +23 -0
- package/dist/cli/src/tool-contributions.js +58 -0
- package/dist/cli/src/tool-data.js +116 -0
- package/dist/cli/src/tool-datasets.js +176 -0
- package/dist/cli/src/tool-group-contracts.js +1 -0
- package/dist/cli/src/tool-group-reads.js +26 -0
- package/dist/cli/src/tool-group-state.js +147 -0
- package/dist/cli/src/tool-groups.js +311 -0
- package/dist/cli/src/tool-instances.js +186 -0
- package/dist/cli/src/tool-lifecycle-contracts.js +1 -0
- package/dist/cli/src/tool-lifecycle-reads.js +30 -0
- package/dist/cli/src/tool-lifecycle.js +323 -0
- package/dist/cli/src/tool-package-contracts.js +1 -0
- package/dist/cli/src/tool-package-reads.js +41 -0
- package/dist/cli/src/tool-records.js +53 -0
- package/dist/cli/src/tool-runtime.js +96 -0
- package/dist/cli/src/tool-state-contracts.js +1 -0
- package/dist/cli/src/tool-state-reads.js +31 -0
- package/dist/cli/src/tools.js +306 -0
- package/dist/cli/src/trial-actions.js +93 -0
- package/dist/cli/src/trial-checkpoints.js +133 -0
- package/dist/cli/src/trial-checks.js +70 -0
- package/dist/cli/src/trial-state.js +197 -0
- package/dist/cli/src/vault.js +266 -0
- package/dist/cli/src/workspace-registration.js +383 -0
- package/dist/cli/src/workspace-team-contracts.js +1 -0
- package/dist/cli/src/world-access.js +231 -0
- package/dist/cli/src/world-agent.js +4 -0
- package/dist/cli/src/world-checkpoint-scopes.js +15 -0
- package/dist/cli/src/world-contracts.js +6 -0
- package/dist/cli/src/world-creation.js +201 -0
- package/dist/cli/src/world-datasets.js +207 -0
- package/dist/cli/src/world-inspection.js +257 -0
- package/dist/cli/src/world-recipes.js +103 -0
- package/dist/cli/src/world-requests.js +241 -0
- package/dist/cli/src/world-session-checkpoints.js +196 -0
- package/dist/cli/src/world-session-lifecycle.js +207 -0
- package/dist/cli/src/world-session-requests.js +215 -0
- package/dist/cli/src/world-session-state.js +145 -0
- package/dist/cli/src/world-session-voice.js +66 -0
- package/dist/cli/src/world-sessions.js +288 -0
- package/dist/cli/src/world-stream.js +99 -0
- package/dist/cli/src/world-time-report.js +58 -0
- package/dist/contracts/agent-change-contracts.js +75 -0
- package/dist/contracts/agent-execution-contracts.js +38 -0
- package/dist/contracts/application-state-contracts.js +26 -0
- package/dist/contracts/assessment-aggregate-contracts.js +15 -0
- package/dist/contracts/assessment-contracts.js +74 -0
- package/dist/contracts/billing-commerce-contracts.js +107 -0
- package/dist/contracts/billing-wallet-contracts.js +43 -0
- package/dist/contracts/campaign-lifecycle.js +1 -0
- package/dist/contracts/campaign-world-contracts.js +80 -0
- package/dist/contracts/catalog-contracts.js +73 -0
- package/dist/contracts/ci-access-contracts.js +68 -0
- package/dist/contracts/ci-configuration-contracts.js +88 -0
- package/dist/contracts/ci-coverage-contracts.js +65 -0
- package/dist/contracts/ci-coverage-labels.js +25 -0
- package/dist/contracts/ci-delivery-contracts.js +61 -0
- package/dist/contracts/ci-result-contracts.js +103 -0
- package/dist/contracts/ci-run-contracts.js +51 -0
- package/dist/contracts/ci-setup-contracts.js +88 -0
- package/dist/contracts/clip-contracts.js +32 -0
- package/dist/contracts/comparison-contracts.js +53 -0
- package/dist/contracts/composite-contracts.js +34 -0
- package/dist/contracts/context-contracts.js +76 -0
- package/dist/contracts/continuation-report-contracts.js +1 -0
- package/dist/contracts/continuity-requirements.js +8 -0
- package/dist/contracts/coordinated-checkpoint-contracts.js +34 -0
- package/dist/contracts/dataset-contracts.js +88 -0
- package/dist/contracts/dependency-decision-contracts.js +36 -0
- package/dist/contracts/dependency-protocol-contracts.js +43 -0
- package/dist/contracts/director-execution.js +51 -0
- package/dist/contracts/driver-review-contracts.js +99 -0
- package/dist/contracts/evidence-contracts.js +65 -0
- package/dist/contracts/evidence-coverage-contracts.js +10 -0
- package/dist/contracts/export-contracts.js +44 -0
- package/dist/contracts/github-directory-contracts.js +96 -0
- package/dist/contracts/insight-contracts.js +11 -0
- package/dist/contracts/inspection-contracts.js +1 -0
- package/dist/contracts/local-claim-contracts.js +39 -0
- package/dist/contracts/local-configuration-contracts.js +7 -0
- package/dist/contracts/local-evidence-contracts.js +32 -0
- package/dist/contracts/local-grant-contracts.js +83 -0
- package/dist/contracts/local-input-contracts.js +19 -0
- package/dist/contracts/local-runner-contracts.js +42 -0
- package/dist/contracts/local-trial-live-contracts.js +16 -0
- package/dist/contracts/local-value-source-contracts.js +92 -0
- package/dist/contracts/local-world-native-contracts.js +8 -0
- package/dist/contracts/mcp-contracts.js +42 -0
- package/dist/contracts/media-contracts.js +28 -0
- package/dist/contracts/native-check-contracts.js +31 -0
- package/dist/contracts/native-identity-contracts.js +52 -0
- package/dist/contracts/onboarding-contracts.js +32 -0
- package/dist/contracts/performance-contracts.js +85 -0
- package/dist/contracts/planning-contracts.js +81 -0
- package/dist/contracts/real-operation-contracts.js +30 -0
- package/dist/contracts/recommendation-contracts.js +54 -0
- package/dist/contracts/report-contracts.js +1 -0
- package/dist/contracts/resource-lifecycle-contracts.js +57 -0
- package/dist/contracts/revision-contracts.js +12 -0
- package/dist/contracts/revision-request-contracts.js +39 -0
- package/dist/contracts/saved-record-contracts.js +76 -0
- package/dist/contracts/scenario-draft-comparison.js +91 -0
- package/dist/contracts/scenario-world-contracts.js +14 -0
- package/dist/contracts/service-contracts.js +1 -0
- package/dist/contracts/session-command-contracts.js +56 -0
- package/dist/contracts/session-contracts.js +65 -0
- package/dist/contracts/session-state-contracts.js +67 -0
- package/dist/contracts/session-voice-contracts.js +45 -0
- package/dist/contracts/source-set-contracts.js +26 -0
- package/dist/contracts/source-upload-contracts.js +22 -0
- package/dist/contracts/tool-command-contracts.js +57 -0
- package/dist/contracts/tool-connection-contracts.js +87 -0
- package/dist/contracts/tool-contribution-contracts.js +35 -0
- package/dist/contracts/tool-group-contracts.js +53 -0
- package/dist/contracts/tool-group-state-contracts.js +63 -0
- package/dist/contracts/tool-lifecycle-contracts.js +94 -0
- package/dist/contracts/tool-package-contracts.js +91 -0
- package/dist/contracts/tool-protocol-contracts.js +71 -0
- package/dist/contracts/tool-runtime-billing-contracts.js +28 -0
- package/dist/contracts/tool-setup-proposal.js +59 -0
- package/dist/contracts/tool-state-contracts.js +79 -0
- package/dist/contracts/trial-state-contracts.js +30 -0
- package/dist/contracts/typescript/agent-change.js +1 -0
- package/dist/contracts/typescript/assessment-aggregate.js +1 -0
- package/dist/contracts/typescript/assessment.js +1 -0
- package/dist/contracts/typescript/billing-commerce.js +1 -0
- package/dist/contracts/typescript/campaigns.js +1 -0
- package/dist/contracts/typescript/catalog.js +1 -0
- package/dist/contracts/typescript/ci-access.js +1 -0
- package/dist/contracts/typescript/ci-configuration.js +1 -0
- package/dist/contracts/typescript/ci-delivery.js +1 -0
- package/dist/contracts/typescript/ci-result.js +1 -0
- package/dist/contracts/typescript/ci-runs.js +1 -0
- package/dist/contracts/typescript/clips.js +1 -0
- package/dist/contracts/typescript/comparison.js +1 -0
- package/dist/contracts/typescript/composite.js +1 -0
- package/dist/contracts/typescript/connections.js +1 -0
- package/dist/contracts/typescript/context.js +1 -0
- package/dist/contracts/typescript/datasets.js +1 -0
- package/dist/contracts/typescript/evidence-coverage.js +1 -0
- package/dist/contracts/typescript/export.js +1 -0
- package/dist/contracts/typescript/github-directory.js +1 -0
- package/dist/contracts/typescript/insight.js +1 -0
- package/dist/contracts/typescript/inspection.js +1 -0
- package/dist/contracts/typescript/intake.js +1 -0
- package/dist/contracts/typescript/local-claim.js +1 -0
- package/dist/contracts/typescript/local-configuration.js +1 -0
- package/dist/contracts/typescript/local-evidence.js +1 -0
- package/dist/contracts/typescript/local-grant.js +1 -0
- package/dist/contracts/typescript/local-input.js +1 -0
- package/dist/contracts/typescript/local-runner.js +1 -0
- package/dist/contracts/typescript/local-trial-live.js +1 -0
- package/dist/contracts/typescript/local-value-source.js +1 -0
- package/dist/contracts/typescript/local-world-native.js +1 -0
- package/dist/contracts/typescript/mcp.js +1 -0
- package/dist/contracts/typescript/media.js +1 -0
- package/dist/contracts/typescript/native-check.js +1 -0
- package/dist/contracts/typescript/native-identity.js +1 -0
- package/dist/contracts/typescript/onboarding.js +1 -0
- package/dist/contracts/typescript/performance.js +1 -0
- package/dist/contracts/typescript/planning.js +1 -0
- package/dist/contracts/typescript/preparation.js +1 -0
- package/dist/contracts/typescript/real-operation.js +1 -0
- package/dist/contracts/typescript/recommendation.js +1 -0
- package/dist/contracts/typescript/reports.js +1 -0
- package/dist/contracts/typescript/resource-lifecycle.js +1 -0
- package/dist/contracts/typescript/saved-record.js +1 -0
- package/dist/contracts/typescript/scenarios.js +1 -0
- package/dist/contracts/typescript/services.js +1 -0
- package/dist/contracts/typescript/session-command.js +1 -0
- package/dist/contracts/typescript/session-state.js +1 -0
- package/dist/contracts/typescript/session-voice.js +1 -0
- package/dist/contracts/typescript/session.js +1 -0
- package/dist/contracts/typescript/tool-command.js +1 -0
- package/dist/contracts/typescript/tool-connection.js +1 -0
- package/dist/contracts/typescript/tool-contribution.js +1 -0
- package/dist/contracts/typescript/tool-groups.js +1 -0
- package/dist/contracts/typescript/tool-lifecycle.js +1 -0
- package/dist/contracts/typescript/tool-package.js +1 -0
- package/dist/contracts/typescript/tool-state.js +1 -0
- package/dist/contracts/typescript/trial-state.js +1 -0
- package/dist/contracts/typescript/vault.js +1 -0
- package/dist/contracts/typescript/workspace-team.js +1 -0
- package/dist/contracts/typescript/world-stream.js +1 -0
- package/dist/contracts/workspace-team-contracts.js +55 -0
- package/dist/contracts/world-command.js +65 -0
- package/dist/contracts/world-lifetime-contracts.js +74 -0
- package/dist/contracts/world-recipe-contracts.js +27 -0
- package/dist/contracts/world-stream-contracts.js +27 -0
- package/dist/package.json +1 -0
- package/package.json +16 -16
- package/LICENSE.md +0 -23
- package/PACKAGING.json +0 -50
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitized browser action trace for the playwright.v1 driver (Plan20 FIR-493;
|
|
3
|
+
* root `firedrill.native-trace-segment.v1`, profile `sanitized-actions-v1`,
|
|
4
|
+
* agreed with root 2026-11-10).
|
|
5
|
+
*
|
|
6
|
+
* On only when the approved plan sets `trace: "sanitized-actions"`. The flow
|
|
7
|
+
* then gets its page through a recording view. Every call still runs on the
|
|
8
|
+
* real Playwright object with the same arguments and the same result, so the
|
|
9
|
+
* flow behaves as before. Each traced call records only which kind of
|
|
10
|
+
* operation it was, how it ended and when it ended. Nothing else is read or
|
|
11
|
+
* kept: never selectors, addresses, typed values, page text, arguments, return
|
|
12
|
+
* values or errors.
|
|
13
|
+
*
|
|
14
|
+
* Recorded: calls on the page and on the frames, locators, element handles,
|
|
15
|
+
* keyboard, mouse and touchscreen reached from it (including pages that its
|
|
16
|
+
* methods return), when the method is one of the operations below. Not
|
|
17
|
+
* recorded: other calls (hover, evaluate, drag, route and the like), objects
|
|
18
|
+
* handed to event handlers, and anything reached through the browser context.
|
|
19
|
+
* Assertions from a test library run inside Playwright, so `assert` is never
|
|
20
|
+
* recorded. This is not a Playwright trace, HAR or video.
|
|
21
|
+
*
|
|
22
|
+
* Each browser session is one capture (`capture_id`) whose events are numbered
|
|
23
|
+
* from 1 without gaps. A segment is cut when a step ends, after login or a
|
|
24
|
+
* reset, and at 256 events. The session's last segment carries the terminal
|
|
25
|
+
* coverage: `complete`, or `partial` with the reason.
|
|
26
|
+
*/
|
|
27
|
+
import { randomUUID } from 'node:crypto';
|
|
28
|
+
import { TRACE_SEGMENT_MAX_EVENTS } from '../contracts.js';
|
|
29
|
+
/** Operations recorded per browser session at most; past this the capture is partial (`limit_reached`). */
|
|
30
|
+
export const TRACE_MAX_EVENTS_PER_SESSION = 4_096;
|
|
31
|
+
/** Playwright methods and the operation each one is. `setChecked` is `check` or `uncheck` by its first argument. */
|
|
32
|
+
const OPERATIONS = new Map(Object.entries({
|
|
33
|
+
goto: 'navigate', reload: 'navigate', goBack: 'navigate', goForward: 'navigate', setContent: 'navigate',
|
|
34
|
+
click: 'click', dblclick: 'click', tap: 'click',
|
|
35
|
+
fill: 'fill', type: 'fill', pressSequentially: 'fill', insertText: 'fill', clear: 'fill', setInputFiles: 'fill',
|
|
36
|
+
press: 'press',
|
|
37
|
+
selectOption: 'select', selectText: 'select',
|
|
38
|
+
check: 'check', uncheck: 'uncheck',
|
|
39
|
+
waitFor: 'wait', waitForSelector: 'wait', waitForLoadState: 'wait', waitForURL: 'wait', waitForNavigation: 'wait',
|
|
40
|
+
waitForTimeout: 'wait', waitForFunction: 'wait', waitForResponse: 'wait', waitForRequest: 'wait', waitForEvent: 'wait',
|
|
41
|
+
waitForElementState: 'wait',
|
|
42
|
+
textContent: 'observe', innerText: 'observe', innerHTML: 'observe', inputValue: 'observe', getAttribute: 'observe',
|
|
43
|
+
isVisible: 'observe', isHidden: 'observe', isEnabled: 'observe', isDisabled: 'observe', isChecked: 'observe',
|
|
44
|
+
isEditable: 'observe', count: 'observe', allTextContents: 'observe', allInnerTexts: 'observe', content: 'observe',
|
|
45
|
+
title: 'observe', boundingBox: 'observe', ariaSnapshot: 'observe',
|
|
46
|
+
}));
|
|
47
|
+
/** Members that mark a page, frame, locator, element handle or input device: objects the view records through. */
|
|
48
|
+
const MARKERS = ['click', 'locator', 'press', 'tap'];
|
|
49
|
+
function thenable(value) {
|
|
50
|
+
return value !== null && (typeof value === 'object' || typeof value === 'function')
|
|
51
|
+
&& typeof value.then === 'function';
|
|
52
|
+
}
|
|
53
|
+
export class ActionTrace {
|
|
54
|
+
captureId = randomUUID();
|
|
55
|
+
#clock;
|
|
56
|
+
/** Latest time read: the trace's times never go back, so its events and segments stay in order. */
|
|
57
|
+
#latest;
|
|
58
|
+
#defaultSink;
|
|
59
|
+
#sink;
|
|
60
|
+
/** Set while a step runs: a call that fails after it aborted ended `cancelled`, not `failed`. */
|
|
61
|
+
#stop = null;
|
|
62
|
+
#events = [];
|
|
63
|
+
#sequence = 0;
|
|
64
|
+
#segmentIndex = 0;
|
|
65
|
+
#segmentStart;
|
|
66
|
+
#partial = null;
|
|
67
|
+
#ended = false;
|
|
68
|
+
#views = new WeakMap();
|
|
69
|
+
#targets = new WeakMap();
|
|
70
|
+
/** `now` is the observation clock; `sink` receives segments cut outside a step. */
|
|
71
|
+
constructor(now, sink) {
|
|
72
|
+
this.#clock = now;
|
|
73
|
+
this.#latest = now();
|
|
74
|
+
this.#defaultSink = sink;
|
|
75
|
+
this.#sink = sink;
|
|
76
|
+
this.#segmentStart = this.#latest;
|
|
77
|
+
}
|
|
78
|
+
/** The flow's view of a Playwright object: the same behavior, recorded. */
|
|
79
|
+
view(target) {
|
|
80
|
+
return this.#wrap(target);
|
|
81
|
+
}
|
|
82
|
+
/** Segments cut from now on go to `sink` (the running step's records); `stop` is the step's abort signal. */
|
|
83
|
+
attach(sink, stop) {
|
|
84
|
+
this.#sink = sink;
|
|
85
|
+
this.#stop = stop;
|
|
86
|
+
}
|
|
87
|
+
detach() {
|
|
88
|
+
this.#sink = this.#defaultSink;
|
|
89
|
+
this.#stop = null;
|
|
90
|
+
}
|
|
91
|
+
/** Cut a segment of the operations recorded since the last one (nothing when there are none). */
|
|
92
|
+
cut() {
|
|
93
|
+
if (!this.#ended && this.#events.length)
|
|
94
|
+
this.#emit(null);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* End the capture with its last segment and terminal coverage: complete, or
|
|
98
|
+
* partial for the first reason that applied (a limit, a lost segment, or `reason`).
|
|
99
|
+
*/
|
|
100
|
+
end(reason = null) {
|
|
101
|
+
if (this.#ended)
|
|
102
|
+
return;
|
|
103
|
+
const partial = this.#partial ?? reason;
|
|
104
|
+
this.#ended = true;
|
|
105
|
+
this.#emit(partial ? { coverage: 'partial', reason: partial } : { coverage: 'complete', reason: null });
|
|
106
|
+
}
|
|
107
|
+
#record(operation, outcome) {
|
|
108
|
+
if (this.#ended)
|
|
109
|
+
return;
|
|
110
|
+
if (this.#sequence >= TRACE_MAX_EVENTS_PER_SESSION) {
|
|
111
|
+
this.#partial ??= 'limit_reached';
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.#events.push({ sequence: ++this.#sequence, at_ms: this.#now(), operation, outcome });
|
|
115
|
+
if (this.#events.length >= TRACE_SEGMENT_MAX_EVENTS)
|
|
116
|
+
this.#emit(null);
|
|
117
|
+
}
|
|
118
|
+
#emit(terminal) {
|
|
119
|
+
const end = this.#now();
|
|
120
|
+
const segment = {
|
|
121
|
+
capture_id: this.captureId, segment_index: this.#segmentIndex++, start_at_ms: this.#segmentStart, end_at_ms: end,
|
|
122
|
+
events: this.#events, terminal,
|
|
123
|
+
};
|
|
124
|
+
this.#events = [];
|
|
125
|
+
this.#segmentStart = end;
|
|
126
|
+
let kept = false;
|
|
127
|
+
try {
|
|
128
|
+
kept = this.#sink(segment);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
kept = false;
|
|
132
|
+
}
|
|
133
|
+
if (!kept)
|
|
134
|
+
this.#partial ??= 'capture_failed';
|
|
135
|
+
}
|
|
136
|
+
#now() {
|
|
137
|
+
const time = this.#clock();
|
|
138
|
+
if (typeof time === 'number' && Number.isFinite(time) && time > this.#latest)
|
|
139
|
+
this.#latest = time;
|
|
140
|
+
return this.#latest;
|
|
141
|
+
}
|
|
142
|
+
#failure() {
|
|
143
|
+
return this.#stop?.aborted ? 'cancelled' : 'failed';
|
|
144
|
+
}
|
|
145
|
+
#wrap(target) {
|
|
146
|
+
const known = this.#views.get(target);
|
|
147
|
+
if (known)
|
|
148
|
+
return known;
|
|
149
|
+
const methods = new Map();
|
|
150
|
+
const view = new Proxy(target, {
|
|
151
|
+
get: (object, property) => {
|
|
152
|
+
const value = Reflect.get(object, property, object);
|
|
153
|
+
const own = Object.getOwnPropertyDescriptor(object, property);
|
|
154
|
+
// Proxy invariant: a fixed data property reads as itself.
|
|
155
|
+
if (property === 'constructor' || (own && !own.configurable && own.writable === false))
|
|
156
|
+
return value;
|
|
157
|
+
// Symbols and underscored members are Playwright's own plumbing: run on the real object, never recorded.
|
|
158
|
+
const internal = typeof property !== 'string' || property.startsWith('_');
|
|
159
|
+
if (typeof value === 'function') {
|
|
160
|
+
const cached = methods.get(property);
|
|
161
|
+
if (cached?.source === value)
|
|
162
|
+
return cached.method;
|
|
163
|
+
const method = internal ? value.bind(object) : this.#method(object, property, value);
|
|
164
|
+
methods.set(property, { source: value, method });
|
|
165
|
+
return method;
|
|
166
|
+
}
|
|
167
|
+
return internal ? value : this.#result(value);
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
this.#views.set(target, view);
|
|
171
|
+
this.#targets.set(view, target);
|
|
172
|
+
return view;
|
|
173
|
+
}
|
|
174
|
+
#method(object, name, method) {
|
|
175
|
+
return (...args) => {
|
|
176
|
+
// The real objects go to Playwright; only the method's name (and setChecked's flag) picks the operation.
|
|
177
|
+
const real = args.map((arg) => (arg !== null && typeof arg === 'object' ? this.#targets.get(arg) ?? arg : arg));
|
|
178
|
+
const operation = name === 'setChecked' ? (real[0] ? 'check' : 'uncheck') : OPERATIONS.get(name);
|
|
179
|
+
let result;
|
|
180
|
+
try {
|
|
181
|
+
result = Reflect.apply(method, object, real);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
if (operation)
|
|
185
|
+
this.#record(operation, this.#failure());
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
if (!thenable(result)) {
|
|
189
|
+
if (operation)
|
|
190
|
+
this.#record(operation, 'completed');
|
|
191
|
+
return this.#result(result);
|
|
192
|
+
}
|
|
193
|
+
return Promise.resolve(result).then((value) => { if (operation)
|
|
194
|
+
this.#record(operation, 'completed'); return this.#result(value); }, (error) => { if (operation)
|
|
195
|
+
this.#record(operation, this.#failure()); throw error; });
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/** A returned page, frame, locator, element handle or input device (or a list of them) comes back recorded too. */
|
|
199
|
+
#result(value) {
|
|
200
|
+
if (Array.isArray(value))
|
|
201
|
+
return value.some((item) => this.#recordable(item)) ? value.map((item) => this.#result(item)) : value;
|
|
202
|
+
return this.#recordable(value) ? this.#wrap(value) : value;
|
|
203
|
+
}
|
|
204
|
+
#recordable(value) {
|
|
205
|
+
if (value === null || typeof value !== 'object' || this.#targets.has(value))
|
|
206
|
+
return false;
|
|
207
|
+
const record = value;
|
|
208
|
+
return MARKERS.some((name) => typeof record[name] === 'function');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* function-wrapper.v1 driver (Plan20 spec 3.3).
|
|
3
|
+
*
|
|
4
|
+
* The coding agent writes a small wrapper file inside an approved root that
|
|
5
|
+
* imports the customer's function and speaks the jsonl-process.v1 protocol on
|
|
6
|
+
* stdin/stdout. The user approves it; its sha256 is pinned as the descriptor's
|
|
7
|
+
* `adapter_sha256` (ctx.adapterSha256).
|
|
8
|
+
*
|
|
9
|
+
* Launch: argv = [...runtime.args, <absolute wrapper path>] with
|
|
10
|
+
* `runtime.executable`, shell:false, cwd = the wrapper's root, env = ctx.env.
|
|
11
|
+
* Before EVERY launch (first launch and each bounded relaunch after the wrapper
|
|
12
|
+
* process exits) the wrapper file is re-read and re-hashed; a mismatch is
|
|
13
|
+
* `native_plan_changed` and nothing is run.
|
|
14
|
+
*
|
|
15
|
+
* Residual: the runtime re-reads the wrapper after the hash check (time-of-check
|
|
16
|
+
* to time-of-use). Copying it elsewhere would break its relative imports, so the
|
|
17
|
+
* file is run in place; native mode is trusted local execution, not a sandbox.
|
|
18
|
+
*
|
|
19
|
+
* A step in flight when the wrapper exits is never replayed (unknown outcome for
|
|
20
|
+
* non-idempotent steps); only the next step triggers a relaunch.
|
|
21
|
+
*
|
|
22
|
+
* Import handshake: after importing the customer's function, and before reading
|
|
23
|
+
* any request, the wrapper prints one stdout line containing WRAPPER_READY. Only
|
|
24
|
+
* then is it started; readiness additionally requires it still running.
|
|
25
|
+
*/
|
|
26
|
+
import { CliError } from '../../http.js';
|
|
27
|
+
import { nativeError } from '../contracts.js';
|
|
28
|
+
import { insideRoot } from '../roots.js';
|
|
29
|
+
import { JsonLinesProcess, JsonLinesSession } from './jsonl-process.js';
|
|
30
|
+
import { DRIVER_ERRORS, OwnDigest, driverBounds, driverPlanFor, emit, planError, readPinned, rootPath, unattested } from './types.js';
|
|
31
|
+
/** The line a wrapper prints once the customer's function imported (bounded by the driver's setup time). */
|
|
32
|
+
export const WRAPPER_READY = 'firedrill-wrapper-ready';
|
|
33
|
+
export class FunctionWrapperDriver {
|
|
34
|
+
profile = 'function-wrapper.v1';
|
|
35
|
+
prepared = null;
|
|
36
|
+
process = null;
|
|
37
|
+
launching = null;
|
|
38
|
+
relaunches = 0;
|
|
39
|
+
disposed = false;
|
|
40
|
+
sessions = new Set();
|
|
41
|
+
launches = [];
|
|
42
|
+
/** SHA-256 of the wrapper module verified against the approved adapter digest before its runtime loaded it. */
|
|
43
|
+
importSha256 = null;
|
|
44
|
+
async describe() {
|
|
45
|
+
return { available: true, reason: null };
|
|
46
|
+
}
|
|
47
|
+
async prepare(ctx) {
|
|
48
|
+
const plan = driverPlanFor(ctx, 'function-wrapper.v1');
|
|
49
|
+
if (this.prepared)
|
|
50
|
+
throw planError('The function wrapper driver is already prepared; nothing else was started.');
|
|
51
|
+
if (!plan.runtime || typeof plan.runtime.executable !== 'string' || !plan.runtime.executable || !Array.isArray(plan.runtime.args))
|
|
52
|
+
throw planError('The approved wrapper runtime has no executable, so the wrapper was not started.');
|
|
53
|
+
const root = rootPath(ctx, plan.root_alias);
|
|
54
|
+
const wrapper = await insideRoot(root, plan.wrapper);
|
|
55
|
+
if (this.disposed)
|
|
56
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The function wrapper driver was stopped, so the wrapper was not started.');
|
|
57
|
+
this.prepared = { ctx, root, wrapper, executable: plan.runtime.executable, args: [...plan.runtime.args] };
|
|
58
|
+
this.launching = this.launch();
|
|
59
|
+
try {
|
|
60
|
+
this.process = await this.launching;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
this.launching = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Re-hash the wrapper, then start it. */
|
|
67
|
+
async launch() {
|
|
68
|
+
const prepared = this.prepared;
|
|
69
|
+
if (!prepared || this.disposed)
|
|
70
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The function wrapper driver is not prepared, so the wrapper was not started.');
|
|
71
|
+
const { ctx } = prepared;
|
|
72
|
+
const pinned = await readPinned(prepared.wrapper, ctx.adapterSha256);
|
|
73
|
+
if (this.disposed || ctx.signal.aborted)
|
|
74
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The function wrapper was stopped before launch, so it was not started.');
|
|
75
|
+
this.importSha256 = pinned.sha256;
|
|
76
|
+
emit(ctx, 'state.observed', { type: 'adapter.verified', profile: this.profile, adapter_sha256: new OwnDigest(pinned.sha256) });
|
|
77
|
+
// The wrapper prints WRAPPER_READY once the user's function imported: a wrapper that
|
|
78
|
+
// fails to import exits or stays silent and is never reported ready.
|
|
79
|
+
return await JsonLinesProcess.start(ctx, {
|
|
80
|
+
label: 'function wrapper',
|
|
81
|
+
executable: prepared.executable, args: [...prepared.args, prepared.wrapper], cwd: prepared.root, env: ctx.env,
|
|
82
|
+
readiness: { kind: 'stdout', pattern: WRAPPER_READY }, readinessTimeoutMs: driverBounds(ctx).flowSetupMs,
|
|
83
|
+
stopTimeoutMs: driverBounds(ctx).stopTimeoutMs,
|
|
84
|
+
onSpawned: (channel) => { this.launches.push(channel); },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/** Current wrapper process; relaunches (re-hashed, bounded) only between steps. */
|
|
88
|
+
async channel() {
|
|
89
|
+
if (this.process && !this.process.exited)
|
|
90
|
+
return this.process;
|
|
91
|
+
if (this.launching)
|
|
92
|
+
return await this.launching;
|
|
93
|
+
const prepared = this.prepared;
|
|
94
|
+
if (!prepared)
|
|
95
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The function wrapper driver is not prepared, so the step was not sent.');
|
|
96
|
+
if (this.relaunches >= driverBounds(prepared.ctx).maxWrapperRelaunches)
|
|
97
|
+
throw nativeError('process_exited', 'The function wrapper exited too many times, so it was not started again and the step was not sent.');
|
|
98
|
+
this.relaunches += 1;
|
|
99
|
+
// Release the dead wrapper's pipes before replacing it (its group was swept on exit).
|
|
100
|
+
if (this.process) {
|
|
101
|
+
await this.process.stop().catch(() => undefined);
|
|
102
|
+
this.process = null;
|
|
103
|
+
}
|
|
104
|
+
emit(prepared.ctx, 'action.observed', { type: 'adapter.relaunch', profile: this.profile, relaunch: this.relaunches });
|
|
105
|
+
this.launching = this.launch();
|
|
106
|
+
try {
|
|
107
|
+
this.process = await this.launching;
|
|
108
|
+
return this.process;
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
this.launching = null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async openSession(ctx, sessionKey) {
|
|
115
|
+
if (!this.prepared)
|
|
116
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The function wrapper driver was not prepared, so no session was opened.');
|
|
117
|
+
if (!sessionKey)
|
|
118
|
+
throw new CliError(DRIVER_ERRORS.session_failed, 'The session key is empty, so no session was opened.');
|
|
119
|
+
const session = new JsonLinesSession(ctx, sessionKey, () => this.channel(), () => this.sessions.delete(session));
|
|
120
|
+
this.sessions.add(session);
|
|
121
|
+
emit(ctx, 'action.observed', { type: 'session.opened', profile: this.profile, session_key: sessionKey });
|
|
122
|
+
return session;
|
|
123
|
+
}
|
|
124
|
+
/** The digest of the wrapper module the runtime imported, verified against the approved adapter digest. */
|
|
125
|
+
async readinessProbe(_ctx) {
|
|
126
|
+
// Started (its import-ready line seen) and still running: hashing alone is not readiness.
|
|
127
|
+
if (!this.process || this.process.exited || !this.importSha256) {
|
|
128
|
+
throw unattested('The function wrapper is not running after importing the function, so its import cannot be attested. Nothing was claimed.');
|
|
129
|
+
}
|
|
130
|
+
return { kind: 'function_import', response_sha256: this.importSha256 };
|
|
131
|
+
}
|
|
132
|
+
async dispose() {
|
|
133
|
+
this.disposed = true;
|
|
134
|
+
for (const session of [...this.sessions])
|
|
135
|
+
await session.close();
|
|
136
|
+
const launching = this.launching;
|
|
137
|
+
if (launching)
|
|
138
|
+
await launching.then((proc) => proc.stop(), () => undefined);
|
|
139
|
+
const current = this.process;
|
|
140
|
+
this.process = null;
|
|
141
|
+
this.prepared = null;
|
|
142
|
+
await current?.stop();
|
|
143
|
+
// Includes failed readiness and earlier relaunches, not only the last
|
|
144
|
+
// successfully prepared process. Keep receipts after disposal.
|
|
145
|
+
for (const channel of this.launches)
|
|
146
|
+
await channel.stop();
|
|
147
|
+
}
|
|
148
|
+
ownedProcesses() {
|
|
149
|
+
// Driver-only identity, not an assertion that this is a declared service.
|
|
150
|
+
return this.launches.map((channel) => ({ alias: '@function-wrapper', launch_id: channel.launchId, exit: channel.exit }));
|
|
151
|
+
}
|
|
152
|
+
}
|