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,19 @@
|
|
|
1
|
+
import { CliError } from '../http.js';
|
|
2
|
+
import { SecretValue } from './contracts.js';
|
|
3
|
+
/** Resolve only names from an already-approved plan, without logging their values. */
|
|
4
|
+
export function localSecretBindings(service, existing = {}) {
|
|
5
|
+
const entries = [];
|
|
6
|
+
const secrets = [];
|
|
7
|
+
const occupied = new Set(Object.keys(existing).map(name => name.toUpperCase()));
|
|
8
|
+
for (const name of service.local_secret_env ?? []) {
|
|
9
|
+
if (occupied.has(name.toUpperCase()))
|
|
10
|
+
throw new CliError('native_local_secret_conflict', 'A local secret conflicts with a drill binding. Change the local plan and approve it again.', 2);
|
|
11
|
+
const value = process.env[name];
|
|
12
|
+
if (!value || value.includes('\0') || Buffer.byteLength(value, 'utf8') > 16_384) {
|
|
13
|
+
throw new CliError('native_local_secret_required', `Set ${name} in the local runner environment before starting. Its value must not be placed in the plan.`, 2);
|
|
14
|
+
}
|
|
15
|
+
entries.push([name, value]);
|
|
16
|
+
secrets.push(new SecretValue(value, 'local-configuration'));
|
|
17
|
+
}
|
|
18
|
+
return { env: { ...existing, ...Object.fromEntries(entries) }, secrets };
|
|
19
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drill-scoped MCP client configuration for simulated MCP dependencies (Plan20
|
|
3
|
+
* FIR-490).
|
|
4
|
+
*
|
|
5
|
+
* For every routed `mcp` dependency this writes one remote server entry into a
|
|
6
|
+
* generic MCP client JSON file, pointing at the companion's per-drill loopback
|
|
7
|
+
* proxy (dependency-proxy.ts). It carries no credential: root's token stays in
|
|
8
|
+
* companion memory, and the URL's path capability is the only secret in the file.
|
|
9
|
+
*
|
|
10
|
+
* { "mcpServers": { "<dependency alias>": { "type": "http", "url": "http://127.0.0.1:<port>/<cap>/<alias>/mcp",
|
|
11
|
+
* "headers": {} } } }
|
|
12
|
+
*
|
|
13
|
+
* The file lives in a fresh private directory (0700) under the run scratch
|
|
14
|
+
* directory, is created exclusively (0600, O_EXCL, O_NOFOLLOW where the platform
|
|
15
|
+
* has it) and is removed by the returned cleanup. The target is pointed at it by
|
|
16
|
+
* the caller adding `env` (one variable, named by the approved plan, holding the
|
|
17
|
+
* absolute file path) to the target service environment.
|
|
18
|
+
*
|
|
19
|
+
* This module never reads, edits or creates any user-level or global agent/client
|
|
20
|
+
* configuration, never installs anything, and never touches proxy, CA, TLS or DNS
|
|
21
|
+
* settings. On Windows, POSIX modes are not enforced by the OS; the file still
|
|
22
|
+
* sits in a fresh per-run directory under the private scratch, and `permissions`
|
|
23
|
+
* reports `platform-default` so the caller can disclose that limitation.
|
|
24
|
+
*/
|
|
25
|
+
import { constants } from 'node:fs';
|
|
26
|
+
import { lstat, mkdtemp, open, rm, chmod } from 'node:fs/promises';
|
|
27
|
+
import { join, isAbsolute } from 'node:path';
|
|
28
|
+
import { CliError } from '../http.js';
|
|
29
|
+
import { nativeError } from './contracts.js';
|
|
30
|
+
import { ENV_NAME, isReservedEnvName } from './bindings.js';
|
|
31
|
+
const MCP_SERVER_NAME = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/;
|
|
32
|
+
/** Only the companion's own loopback proxy may appear in the file. */
|
|
33
|
+
const PROXY_URL = /^http:\/\/127\.0\.0\.1:\d{1,5}\/[A-Za-z0-9_-]{43}\/[a-z][a-z0-9_-]{0,63}\/mcp$/;
|
|
34
|
+
const MAX_CONFIG_BYTES = 256 * 1024;
|
|
35
|
+
/**
|
|
36
|
+
* Write the MCP client configuration for one service's routed MCP dependencies.
|
|
37
|
+
* Returns null when there are none (nothing is created). Server names and URLs
|
|
38
|
+
* are re-checked here because this is an injection point.
|
|
39
|
+
*/
|
|
40
|
+
export async function writeMcpConfig(entries, scratchDir, options) {
|
|
41
|
+
const format = options.format ?? 'mcp-servers.http';
|
|
42
|
+
if (format !== 'mcp-servers.http') {
|
|
43
|
+
throw new CliError('native_mcp_config_unsupported', 'The MCP client configuration was not written: only the generic remote HTTP format is supported.');
|
|
44
|
+
}
|
|
45
|
+
if (!ENV_NAME.test(options.envName) || isReservedEnvName(options.envName)) {
|
|
46
|
+
throw nativeError('binding_invalid', 'The MCP client configuration was not written: the plan names an invalid or reserved environment variable for it.');
|
|
47
|
+
}
|
|
48
|
+
if (entries.length === 0)
|
|
49
|
+
return null;
|
|
50
|
+
const servers = {};
|
|
51
|
+
const secrets = [];
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
if (!MCP_SERVER_NAME.test(entry.name) || Object.prototype.hasOwnProperty.call(servers, entry.name)) {
|
|
54
|
+
throw nativeError('binding_invalid', `The MCP client configuration was not written: server "${entry.name}" is malformed or listed twice.`);
|
|
55
|
+
}
|
|
56
|
+
// Injection point: the URL (with its path capability) is revealed only into the private file.
|
|
57
|
+
const url = entry.url.reveal();
|
|
58
|
+
if (!PROXY_URL.test(url)) {
|
|
59
|
+
throw nativeError('binding_invalid', `The MCP client configuration was not written: server "${entry.name}" does not point at the companion's loopback proxy.`);
|
|
60
|
+
}
|
|
61
|
+
servers[entry.name] = { type: 'http', url, headers: {} };
|
|
62
|
+
secrets.push(entry.url);
|
|
63
|
+
}
|
|
64
|
+
const body = `${JSON.stringify({ mcpServers: servers }, null, 2)}\n`;
|
|
65
|
+
if (Buffer.byteLength(body, 'utf8') > MAX_CONFIG_BYTES) {
|
|
66
|
+
throw nativeError('binding_invalid', 'The MCP client configuration was not written: it exceeds the size limit.');
|
|
67
|
+
}
|
|
68
|
+
if (!isAbsolute(scratchDir)) {
|
|
69
|
+
throw new CliError('native_scratch_invalid', 'The MCP client configuration was not written: the run scratch directory is not an absolute path.');
|
|
70
|
+
}
|
|
71
|
+
let scratch;
|
|
72
|
+
try {
|
|
73
|
+
scratch = await lstat(scratchDir);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new CliError('native_scratch_invalid', 'The MCP client configuration was not written: the run scratch directory is unavailable.');
|
|
77
|
+
}
|
|
78
|
+
if (scratch.isSymbolicLink() || !scratch.isDirectory()) {
|
|
79
|
+
throw new CliError('native_scratch_invalid', 'The MCP client configuration was not written: the run scratch path is not a real directory.');
|
|
80
|
+
}
|
|
81
|
+
const posix = process.platform !== 'win32';
|
|
82
|
+
if (posix && typeof process.getuid === 'function' && scratch.uid !== process.getuid()) {
|
|
83
|
+
throw new CliError('native_scratch_invalid', 'The MCP client configuration was not written: the run scratch directory is not owned by the current user.');
|
|
84
|
+
}
|
|
85
|
+
if (posix && (scratch.mode & 0o022) !== 0) {
|
|
86
|
+
throw new CliError('native_scratch_invalid', 'The MCP client configuration was not written: the run scratch directory is writable by other users.');
|
|
87
|
+
}
|
|
88
|
+
// mkdtemp creates the directory with mode 0700 and a random suffix.
|
|
89
|
+
const directory = await mkdtemp(join(scratchDir, 'mcp-'));
|
|
90
|
+
let removed = false;
|
|
91
|
+
const cleanup = async () => {
|
|
92
|
+
if (removed)
|
|
93
|
+
return;
|
|
94
|
+
removed = true;
|
|
95
|
+
await rm(directory, { recursive: true, force: true });
|
|
96
|
+
};
|
|
97
|
+
const path = join(directory, 'mcp.json');
|
|
98
|
+
try {
|
|
99
|
+
if (posix)
|
|
100
|
+
await chmod(directory, 0o700);
|
|
101
|
+
const noFollow = typeof constants.O_NOFOLLOW === 'number' ? constants.O_NOFOLLOW : 0;
|
|
102
|
+
const handle = await open(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollow, 0o600);
|
|
103
|
+
try {
|
|
104
|
+
await handle.writeFile(body, 'utf8');
|
|
105
|
+
await handle.sync();
|
|
106
|
+
if (posix)
|
|
107
|
+
await handle.chmod(0o600);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
await handle.close();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
await cleanup().catch(() => undefined);
|
|
115
|
+
if (error instanceof CliError)
|
|
116
|
+
throw error;
|
|
117
|
+
throw new CliError('native_mcp_config_unwritten', 'The MCP client configuration was not written to the private run directory. The drill was not started.');
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
path, directory, env: { [options.envName]: path }, secrets, servers: Object.keys(servers),
|
|
121
|
+
permissions: posix ? 'posix-0600' : 'platform-default', cleanup,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Original native metadata writes, recovered or withdrawn by their request key.
|
|
3
|
+
*
|
|
4
|
+
* Root (`native_metadata_requests.py`, `native_metadata_withdrawal.py` and the
|
|
5
|
+
* library's own request view), for this person in the current workspace:
|
|
6
|
+
* - `GET .../native-library/requests/{key}`, `.../native-agents/requests/{key}`
|
|
7
|
+
* (the registration receipt), `.../agents/{agent}/native-descriptors/requests/{key}`
|
|
8
|
+
* and `.../native-worlds/requests/{key}` return the original committed write.
|
|
9
|
+
* 404: not committed, and it may still be in flight, so it is never a reason
|
|
10
|
+
* to send a replacement under a new key. 410: the original was removed. 409
|
|
11
|
+
* `native_metadata_request_withdrawn`: it was withdrawn.
|
|
12
|
+
* - `DELETE` on the same path with exactly `{withdraw_consent: true}` fences
|
|
13
|
+
* the key: `{state: "withdrawn", receipt: null}` when nothing was committed
|
|
14
|
+
* (a delayed original can then never land), or `{state: "committed",
|
|
15
|
+
* receipt}` when it already was (nothing is deleted).
|
|
16
|
+
*
|
|
17
|
+
* A pointer to an uncertain original is cleared only after a confirmed
|
|
18
|
+
* withdrawal, or replaced by the committed receipt.
|
|
19
|
+
*/
|
|
20
|
+
import { api } from '../auth.js';
|
|
21
|
+
import { CliError } from '../http.js';
|
|
22
|
+
import { isTransient } from './control-plane.js';
|
|
23
|
+
import { libraryRow, worldRow } from './cloud-resources.js';
|
|
24
|
+
import { descriptorRevisionRow, registrationReceiptRow } from './registration.js';
|
|
25
|
+
export const METADATA_KINDS = ['library', 'agent', 'descriptor', 'world'];
|
|
26
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
27
|
+
const RESPONSE_LIMIT = 4 * 1024 * 1024;
|
|
28
|
+
/** Own time to read an original back after its answer was lost. */
|
|
29
|
+
const RECOVERY_MS = 15_000;
|
|
30
|
+
const NOUN = { library: 'library change', agent: 'agent registration', descriptor: 'descriptor revision', world: 'world change' };
|
|
31
|
+
const unconfirmed = (kind) => new CliError('native_response_unconfirmed', `The original ${NOUN[kind]} could not be confirmed. Nothing else was sent.`, 2);
|
|
32
|
+
const object = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
33
|
+
function pathOf(scope, target) {
|
|
34
|
+
if (!UUID.test(target.requestKey))
|
|
35
|
+
throw new CliError('native_request_key_invalid', 'Use the request key printed by the original attempt.', 2);
|
|
36
|
+
const key = target.requestKey.toLowerCase();
|
|
37
|
+
if ((target.kind === 'descriptor') !== (target.agentId !== undefined) || (target.agentId !== undefined && !UUID.test(target.agentId)))
|
|
38
|
+
throw new CliError('arguments_invalid', 'A descriptor revision request needs its agent (--agent <id>); other requests take none.', 2);
|
|
39
|
+
const base = `/api/workspaces/${scope.workspace}`;
|
|
40
|
+
switch (target.kind) {
|
|
41
|
+
case 'library': return `${base}/native-library/requests/${key}`;
|
|
42
|
+
case 'agent': return `${base}/native-agents/requests/${key}`;
|
|
43
|
+
case 'world': return `${base}/native-worlds/requests/${key}`;
|
|
44
|
+
default: return `${base}/agents/${target.agentId.toLowerCase()}/native-descriptors/requests/${key}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function receiptOf(target, raw) {
|
|
48
|
+
try {
|
|
49
|
+
switch (target.kind) {
|
|
50
|
+
case 'library': return libraryRow(true)(raw);
|
|
51
|
+
case 'world': return worldRow(true)(raw);
|
|
52
|
+
case 'agent': return registrationReceiptRow(raw, null);
|
|
53
|
+
default: {
|
|
54
|
+
const row = descriptorRevisionRow(raw, null, true);
|
|
55
|
+
if (row.agent_id !== target.agentId.toLowerCase())
|
|
56
|
+
throw new Error();
|
|
57
|
+
return row;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
throw unconfirmed(target.kind);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** The original write as root holds it now. Never sends it again. */
|
|
66
|
+
export async function recoverMetadataRequest(scope, target, signal) {
|
|
67
|
+
const path = pathOf(scope, target);
|
|
68
|
+
let raw;
|
|
69
|
+
try {
|
|
70
|
+
raw = await api(path, { actor: scope.owner, workspace: scope.workspace, signal, maximumResponseBytes: RESPONSE_LIMIT });
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (!(error instanceof CliError))
|
|
74
|
+
throw error;
|
|
75
|
+
if (error.httpStatus === 404)
|
|
76
|
+
return { state: 'not_found' };
|
|
77
|
+
if (error.httpStatus === 410)
|
|
78
|
+
return { state: 'removed' };
|
|
79
|
+
if (error.code === 'native_metadata_request_withdrawn')
|
|
80
|
+
return { state: 'withdrawn' };
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
return { state: 'committed', receipt: receiptOf(target, raw) };
|
|
84
|
+
}
|
|
85
|
+
/** Withdraw an original that was never committed, after the human approved it. A committed one is returned, not deleted. */
|
|
86
|
+
export async function withdrawMetadataRequest(scope, target, signal) {
|
|
87
|
+
const raw = await api(pathOf(scope, target), { method: 'DELETE', body: { withdraw_consent: true },
|
|
88
|
+
actor: scope.owner, workspace: scope.workspace, signal, maximumResponseBytes: RESPONSE_LIMIT });
|
|
89
|
+
if (!object(raw) || Object.keys(raw).length !== 2 || !('receipt' in raw))
|
|
90
|
+
throw unconfirmed(target.kind);
|
|
91
|
+
if (raw.state === 'withdrawn' && raw.receipt === null)
|
|
92
|
+
return { state: 'withdrawn' };
|
|
93
|
+
if (raw.state === 'committed' && raw.receipt !== null)
|
|
94
|
+
return { state: 'committed', receipt: receiptOf(target, raw.receipt) };
|
|
95
|
+
throw unconfirmed(target.kind);
|
|
96
|
+
}
|
|
97
|
+
/** Answers that arrived but could not be confirmed as this write's receipt. */
|
|
98
|
+
const UNCONFIRMED = new Set(['native_response_unconfirmed', 'native_registration_unconfirmed']);
|
|
99
|
+
/** True when a write got no definitive answer, so it may or may not have been committed. Local refusals before sending are not. */
|
|
100
|
+
export function answerLost(error) {
|
|
101
|
+
return isTransient(error) || (error instanceof CliError && UNCONFIRMED.has(error.code));
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* After a write whose answer was lost: its committed receipt, read back by its
|
|
105
|
+
* key on the recovery's own time. Otherwise an error that names the key and the
|
|
106
|
+
* only safe next steps (replay the same request, or withdraw it); never a
|
|
107
|
+
* replacement under a new key.
|
|
108
|
+
*/
|
|
109
|
+
export async function recoverLostWrite(scope, target, commands) {
|
|
110
|
+
const original = await recoverMetadataRequest(scope, target, AbortSignal.timeout(RECOVERY_MS)).catch(() => null);
|
|
111
|
+
if (original?.state === 'committed')
|
|
112
|
+
return original.receipt;
|
|
113
|
+
if (original?.state === 'withdrawn')
|
|
114
|
+
throw new CliError('native_metadata_request_withdrawn', `This ${NOUN[target.kind]} (request ${target.requestKey}) was withdrawn, so it will not land. Make a new change only if the human still wants it.`, 2);
|
|
115
|
+
if (original?.state === 'removed')
|
|
116
|
+
throw new CliError('native_metadata_removed', `This ${NOUN[target.kind]} (request ${target.requestKey}) was saved and has since been removed.`, 2);
|
|
117
|
+
throw new CliError('native_request_unconfirmed', `The answer was lost, so this ${NOUN[target.kind]} is not confirmed (request ${target.requestKey}). It may still land. `
|
|
118
|
+
+ `Replay the same request with: ${commands.replay}. Or, before making a different change, withdraw it: ${commands.withdraw}. Never send it again under a new key.`, 2);
|
|
119
|
+
}
|
|
120
|
+
export function metadataNoun(kind) { return NOUN[kind]; }
|