toolroll 0.5.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/LICENSE +21 -0
- package/README.md +1113 -0
- package/THIRD_PARTY_NOTICES.md +449 -0
- package/dist/accent-colors.d.ts +48 -0
- package/dist/accent-colors.js +122 -0
- package/dist/action-ledger.d.ts +26 -0
- package/dist/action-ledger.js +75 -0
- package/dist/agent-fence.d.ts +42 -0
- package/dist/agent-fence.js +183 -0
- package/dist/agentconfig.d.ts +216 -0
- package/dist/agentconfig.js +454 -0
- package/dist/api-tokens.d.ts +16 -0
- package/dist/api-tokens.js +27 -0
- package/dist/approval-policy.d.ts +69 -0
- package/dist/approval-policy.js +137 -0
- package/dist/approval-rules-ui.d.ts +25 -0
- package/dist/approval-rules-ui.js +39 -0
- package/dist/assignment-adapters.d.ts +180 -0
- package/dist/assignment-adapters.js +239 -0
- package/dist/assignment-brief.d.ts +71 -0
- package/dist/assignment-brief.js +129 -0
- package/dist/assignment-delivery.d.ts +56 -0
- package/dist/assignment-delivery.js +160 -0
- package/dist/assignment-presentation.d.ts +26 -0
- package/dist/assignment-presentation.js +80 -0
- package/dist/assignment-status.d.ts +62 -0
- package/dist/assignment-status.js +152 -0
- package/dist/assignment-ui.d.ts +71 -0
- package/dist/assignment-ui.js +103 -0
- package/dist/assignment.d.ts +222 -0
- package/dist/assignment.js +399 -0
- package/dist/attest.d.ts +56 -0
- package/dist/attest.js +153 -0
- package/dist/backend.d.ts +97 -0
- package/dist/backend.js +166 -0
- package/dist/backup-ui.d.ts +22 -0
- package/dist/backup-ui.js +59 -0
- package/dist/backup.d.ts +84 -0
- package/dist/backup.js +421 -0
- package/dist/beads.d.ts +34 -0
- package/dist/beads.js +135 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +22 -0
- package/dist/board.d.ts +150 -0
- package/dist/board.js +210 -0
- package/dist/boot-identity.d.ts +63 -0
- package/dist/boot-identity.js +99 -0
- package/dist/browser/THIRD_PARTY_NOTICES.txt +2295 -0
- package/dist/browser/workspace.css +4 -0
- package/dist/browser/workspace.js +225 -0
- package/dist/browser-crew.d.ts +11 -0
- package/dist/browser-crew.js +50 -0
- package/dist/browser-shell.d.ts +8 -0
- package/dist/browser-shell.js +60 -0
- package/dist/browser-workspace.d.ts +780 -0
- package/dist/browser-workspace.js +47 -0
- package/dist/budget-alerts.d.ts +19 -0
- package/dist/budget-alerts.js +46 -0
- package/dist/builder.d.ts +370 -0
- package/dist/builder.js +3262 -0
- package/dist/capscan.d.ts +35 -0
- package/dist/capscan.js +113 -0
- package/dist/chat-acceptance.d.ts +71 -0
- package/dist/chat-acceptance.js +120 -0
- package/dist/chat-actions.d.ts +265 -0
- package/dist/chat-actions.js +1273 -0
- package/dist/chat-channel.d.ts +109 -0
- package/dist/chat-channel.js +652 -0
- package/dist/chat-continuity.d.ts +32 -0
- package/dist/chat-continuity.js +317 -0
- package/dist/chat-controls.d.ts +113 -0
- package/dist/chat-controls.js +53 -0
- package/dist/chat-delivery-state.d.ts +159 -0
- package/dist/chat-delivery-state.js +309 -0
- package/dist/chat-delivery.d.ts +38 -0
- package/dist/chat-delivery.js +693 -0
- package/dist/chat-display.d.ts +1 -0
- package/dist/chat-display.js +18 -0
- package/dist/chat-evidence.d.ts +123 -0
- package/dist/chat-evidence.js +207 -0
- package/dist/chat-flow.d.ts +44 -0
- package/dist/chat-flow.js +215 -0
- package/dist/chat-inbox.d.ts +57 -0
- package/dist/chat-inbox.js +123 -0
- package/dist/chat-polish.d.ts +16 -0
- package/dist/chat-polish.js +135 -0
- package/dist/chat-review.d.ts +46 -0
- package/dist/chat-review.js +98 -0
- package/dist/chat-rooms.d.ts +123 -0
- package/dist/chat-rooms.js +216 -0
- package/dist/chat-task-actions.d.ts +44 -0
- package/dist/chat-task-actions.js +79 -0
- package/dist/check-progress.d.ts +51 -0
- package/dist/check-progress.js +290 -0
- package/dist/child-database.d.ts +12 -0
- package/dist/child-database.js +30 -0
- package/dist/claim.d.ts +688 -0
- package/dist/claim.js +1740 -0
- package/dist/cli.d.ts +137 -0
- package/dist/cli.js +1461 -0
- package/dist/codex-limits.d.ts +15 -0
- package/dist/codex-limits.js +145 -0
- package/dist/coding-context.d.ts +55 -0
- package/dist/coding-context.js +92 -0
- package/dist/coding-handoff.d.ts +57 -0
- package/dist/coding-handoff.js +277 -0
- package/dist/coding-provider.d.ts +72 -0
- package/dist/coding-provider.js +424 -0
- package/dist/coding-shipping-ui.d.ts +4 -0
- package/dist/coding-shipping-ui.js +12 -0
- package/dist/coding-types.d.ts +62 -0
- package/dist/coding-types.js +1 -0
- package/dist/coding-ui.d.ts +17 -0
- package/dist/coding-ui.js +364 -0
- package/dist/coding-update.d.ts +15 -0
- package/dist/coding-update.js +149 -0
- package/dist/coding-workspace.d.ts +124 -0
- package/dist/coding-workspace.js +768 -0
- package/dist/container-state.d.ts +5 -0
- package/dist/container-state.js +62 -0
- package/dist/containment.d.ts +197 -0
- package/dist/containment.js +559 -0
- package/dist/contest.d.ts +318 -0
- package/dist/contest.js +753 -0
- package/dist/control-setup.d.ts +35 -0
- package/dist/control-setup.js +40 -0
- package/dist/control-ui.d.ts +29 -0
- package/dist/control-ui.js +53 -0
- package/dist/controller-service.d.ts +1 -0
- package/dist/controller-service.js +19 -0
- package/dist/controller-supervisor.d.ts +30 -0
- package/dist/controller-supervisor.js +104 -0
- package/dist/converse.d.ts +304 -0
- package/dist/converse.js +849 -0
- package/dist/coordinator-proposals.d.ts +29 -0
- package/dist/coordinator-proposals.js +137 -0
- package/dist/coordinator.d.ts +186 -0
- package/dist/coordinator.js +447 -0
- package/dist/credentials-ui.d.ts +25 -0
- package/dist/credentials-ui.js +48 -0
- package/dist/daemon.d.ts +209 -0
- package/dist/daemon.js +604 -0
- package/dist/decision.d.ts +120 -0
- package/dist/decision.js +388 -0
- package/dist/demo.d.ts +55 -0
- package/dist/demo.js +992 -0
- package/dist/desktop-access.d.ts +28 -0
- package/dist/desktop-access.js +88 -0
- package/dist/desktop-bundle.d.ts +16 -0
- package/dist/desktop-bundle.js +74 -0
- package/dist/desktop-host.d.ts +54 -0
- package/dist/desktop-host.js +508 -0
- package/dist/desktop-update-gate.d.ts +12 -0
- package/dist/desktop-update-gate.js +91 -0
- package/dist/desktop-update-recovery.d.ts +14 -0
- package/dist/desktop-update-recovery.js +243 -0
- package/dist/desktop-update.d.ts +110 -0
- package/dist/desktop-update.js +740 -0
- package/dist/discord-api.d.ts +20 -0
- package/dist/discord-api.js +138 -0
- package/dist/discord-chat.d.ts +16 -0
- package/dist/discord-chat.js +381 -0
- package/dist/discord-settings.d.ts +7 -0
- package/dist/discord-settings.js +75 -0
- package/dist/discord.d.ts +10 -0
- package/dist/discord.js +169 -0
- package/dist/discover.d.ts +75 -0
- package/dist/discover.js +150 -0
- package/dist/dispatch.d.ts +100 -0
- package/dist/dispatch.js +311 -0
- package/dist/dispose.d.ts +161 -0
- package/dist/dispose.js +803 -0
- package/dist/email-settings.d.ts +34 -0
- package/dist/email-settings.js +50 -0
- package/dist/envelope.d.ts +47 -0
- package/dist/envelope.js +105 -0
- package/dist/evidence-pack.d.ts +185 -0
- package/dist/evidence-pack.js +258 -0
- package/dist/evidence.d.ts +345 -0
- package/dist/evidence.js +782 -0
- package/dist/exec.d.ts +285 -0
- package/dist/exec.js +1841 -0
- package/dist/exhaustion.d.ts +85 -0
- package/dist/exhaustion.js +141 -0
- package/dist/export-ui.d.ts +4 -0
- package/dist/export-ui.js +17 -0
- package/dist/export.d.ts +48 -0
- package/dist/export.js +305 -0
- package/dist/flow-actions.d.ts +77 -0
- package/dist/flow-actions.js +203 -0
- package/dist/flow-code.d.ts +50 -0
- package/dist/flow-code.js +159 -0
- package/dist/flow-draft.d.ts +38 -0
- package/dist/flow-draft.js +80 -0
- package/dist/flow-engine.d.ts +66 -0
- package/dist/flow-engine.js +416 -0
- package/dist/flow-insights.d.ts +95 -0
- package/dist/flow-insights.js +149 -0
- package/dist/flow-live.d.ts +24 -0
- package/dist/flow-live.js +150 -0
- package/dist/flow-people.d.ts +24 -0
- package/dist/flow-people.js +91 -0
- package/dist/flow-replies.d.ts +48 -0
- package/dist/flow-replies.js +113 -0
- package/dist/flow-scripts.d.ts +38 -0
- package/dist/flow-scripts.js +73 -0
- package/dist/flow-secrets.d.ts +13 -0
- package/dist/flow-secrets.js +45 -0
- package/dist/flow-sort.d.ts +82 -0
- package/dist/flow-sort.js +153 -0
- package/dist/flow-steps.d.ts +40 -0
- package/dist/flow-steps.js +408 -0
- package/dist/flow-triggers.d.ts +244 -0
- package/dist/flow-triggers.js +959 -0
- package/dist/flows-ui.d.ts +20 -0
- package/dist/flows-ui.js +175 -0
- package/dist/flows.d.ts +229 -0
- package/dist/flows.js +968 -0
- package/dist/fonts.d.ts +19 -0
- package/dist/fonts.js +19 -0
- package/dist/gaps.d.ts +35 -0
- package/dist/gaps.js +101 -0
- package/dist/gate-failure.d.ts +40 -0
- package/dist/gate-failure.js +66 -0
- package/dist/git.d.ts +54 -0
- package/dist/git.js +94 -0
- package/dist/google-mail.d.ts +58 -0
- package/dist/google-mail.js +151 -0
- package/dist/grant.d.ts +136 -0
- package/dist/grant.js +238 -0
- package/dist/graph.d.ts +164 -0
- package/dist/graph.js +383 -0
- package/dist/guides.d.ts +22 -0
- package/dist/guides.js +363 -0
- package/dist/held.d.ts +150 -0
- package/dist/held.js +799 -0
- package/dist/invoke.d.ts +112 -0
- package/dist/invoke.js +780 -0
- package/dist/issues.d.ts +41 -0
- package/dist/issues.js +131 -0
- package/dist/job-object-helper.ps1 +252 -0
- package/dist/jsonl-discriminants.d.ts +11 -0
- package/dist/jsonl-discriminants.js +93 -0
- package/dist/keys.d.ts +104 -0
- package/dist/keys.js +229 -0
- package/dist/kits-ui.d.ts +17 -0
- package/dist/kits-ui.js +46 -0
- package/dist/kits.d.ts +86 -0
- package/dist/kits.js +215 -0
- package/dist/knowledge-cli.d.ts +101 -0
- package/dist/knowledge-cli.js +92 -0
- package/dist/knowledge-ui.d.ts +24 -0
- package/dist/knowledge-ui.js +40 -0
- package/dist/lead-context.d.ts +8 -0
- package/dist/lead-context.js +56 -0
- package/dist/lead-follow.d.ts +22 -0
- package/dist/lead-follow.js +167 -0
- package/dist/lead-status.d.ts +75 -0
- package/dist/lead-status.js +285 -0
- package/dist/ledger-chain.d.ts +46 -0
- package/dist/ledger-chain.js +187 -0
- package/dist/ledger-csv.d.ts +4 -0
- package/dist/ledger-csv.js +11 -0
- package/dist/ledger-view.d.ts +24 -0
- package/dist/ledger-view.js +58 -0
- package/dist/limits-ui.d.ts +26 -0
- package/dist/limits-ui.js +67 -0
- package/dist/link.d.ts +72 -0
- package/dist/link.js +217 -0
- package/dist/live.d.ts +96 -0
- package/dist/live.js +366 -0
- package/dist/liveness.d.ts +30 -0
- package/dist/liveness.js +42 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +25 -0
- package/dist/mailbox.d.ts +57 -0
- package/dist/mailbox.js +150 -0
- package/dist/maintenance.d.ts +11 -0
- package/dist/maintenance.js +35 -0
- package/dist/mate-cli.d.ts +52 -0
- package/dist/mate-cli.js +345 -0
- package/dist/mate-contract.d.ts +10 -0
- package/dist/mate-contract.js +30 -0
- package/dist/mate-doors.d.ts +69 -0
- package/dist/mate-doors.js +548 -0
- package/dist/mate-progress.d.ts +29 -0
- package/dist/mate-progress.js +121 -0
- package/dist/mate-tools.d.ts +94 -0
- package/dist/mate-tools.js +1878 -0
- package/dist/mate.d.ts +92 -0
- package/dist/mate.js +435 -0
- package/dist/mcp-connect.d.ts +103 -0
- package/dist/mcp-connect.js +252 -0
- package/dist/mcp.d.ts +27 -0
- package/dist/mcp.js +651 -0
- package/dist/memory-cli.d.ts +466 -0
- package/dist/memory-cli.js +111 -0
- package/dist/memory-pass.d.ts +160 -0
- package/dist/memory-pass.js +409 -0
- package/dist/metrics.d.ts +3 -0
- package/dist/metrics.js +56 -0
- package/dist/mobile-viewport.d.ts +3 -0
- package/dist/mobile-viewport.js +37 -0
- package/dist/model-catalog.d.ts +118 -0
- package/dist/model-catalog.js +376 -0
- package/dist/models-cli.d.ts +102 -0
- package/dist/models-cli.js +66 -0
- package/dist/models-ui.d.ts +34 -0
- package/dist/models-ui.js +68 -0
- package/dist/modes.d.ts +80 -0
- package/dist/modes.js +182 -0
- package/dist/monitoring-settings.d.ts +44 -0
- package/dist/monitoring-settings.js +173 -0
- package/dist/monitoring-ui.d.ts +20 -0
- package/dist/monitoring-ui.js +51 -0
- package/dist/monitoring.d.ts +34 -0
- package/dist/monitoring.js +221 -0
- package/dist/names.d.ts +67 -0
- package/dist/names.js +102 -0
- package/dist/observations.d.ts +40 -0
- package/dist/observations.js +211 -0
- package/dist/oidc.d.ts +71 -0
- package/dist/oidc.js +182 -0
- package/dist/onboard.d.ts +108 -0
- package/dist/onboard.js +325 -0
- package/dist/openrouter-models.d.ts +30 -0
- package/dist/openrouter-models.js +120 -0
- package/dist/operate.d.ts +118 -0
- package/dist/operate.js +11321 -0
- package/dist/peek-cli.d.ts +97 -0
- package/dist/peek-cli.js +215 -0
- package/dist/peek.d.ts +134 -0
- package/dist/peek.js +578 -0
- package/dist/phase-routing.d.ts +307 -0
- package/dist/phase-routing.js +658 -0
- package/dist/plan-auto.d.ts +14 -0
- package/dist/plan-auto.js +92 -0
- package/dist/plan.d.ts +186 -0
- package/dist/plan.js +401 -0
- package/dist/planner-source.d.ts +251 -0
- package/dist/planner-source.js +460 -0
- package/dist/planner.d.ts +75 -0
- package/dist/planner.js +992 -0
- package/dist/policy-ui.d.ts +20 -0
- package/dist/policy-ui.js +41 -0
- package/dist/policy.d.ts +111 -0
- package/dist/policy.js +231 -0
- package/dist/prepared-evidence.d.ts +16 -0
- package/dist/prepared-evidence.js +96 -0
- package/dist/pricing.d.ts +45 -0
- package/dist/pricing.js +77 -0
- package/dist/principal.d.ts +42 -0
- package/dist/principal.js +82 -0
- package/dist/probe.d.ts +46 -0
- package/dist/probe.js +79 -0
- package/dist/process-custody.d.ts +17 -0
- package/dist/process-custody.js +91 -0
- package/dist/process-liveness.d.ts +10 -0
- package/dist/process-liveness.js +81 -0
- package/dist/process-recovery-anchor.d.ts +75 -0
- package/dist/process-recovery-anchor.js +188 -0
- package/dist/process-recovery-coalition.d.ts +25 -0
- package/dist/process-recovery-coalition.js +105 -0
- package/dist/process-recovery-eligibility.d.ts +178 -0
- package/dist/process-recovery-eligibility.js +170 -0
- package/dist/process-recovery-native.d.ts +172 -0
- package/dist/process-recovery-native.js +592 -0
- package/dist/process-recovery-provenance.d.ts +163 -0
- package/dist/process-recovery-provenance.js +292 -0
- package/dist/process-recovery-services.d.ts +56 -0
- package/dist/process-recovery-services.js +191 -0
- package/dist/process-recovery-settlement.d.ts +32 -0
- package/dist/process-recovery-settlement.js +132 -0
- package/dist/process-recovery.d.ts +41 -0
- package/dist/process-recovery.js +91 -0
- package/dist/process-tree.d.ts +41 -0
- package/dist/process-tree.js +264 -0
- package/dist/project-access.d.ts +14 -0
- package/dist/project-access.js +34 -0
- package/dist/project-cli.d.ts +18 -0
- package/dist/project-cli.js +104 -0
- package/dist/project-delete-ui.d.ts +22 -0
- package/dist/project-delete-ui.js +48 -0
- package/dist/project-delete.d.ts +55 -0
- package/dist/project-delete.js +413 -0
- package/dist/project-knowledge.d.ts +111 -0
- package/dist/project-knowledge.js +241 -0
- package/dist/project-learning.d.ts +100 -0
- package/dist/project-learning.js +438 -0
- package/dist/project-memory.d.ts +81 -0
- package/dist/project-memory.js +264 -0
- package/dist/project-skills.d.ts +152 -0
- package/dist/project-skills.js +660 -0
- package/dist/project-tools.d.ts +219 -0
- package/dist/project-tools.js +796 -0
- package/dist/project.d.ts +61 -0
- package/dist/project.js +125 -0
- package/dist/prompt.d.ts +22 -0
- package/dist/prompt.js +72 -0
- package/dist/proof.d.ts +513 -0
- package/dist/proof.js +1140 -0
- package/dist/proposal.d.ts +82 -0
- package/dist/proposal.js +210 -0
- package/dist/provider-connection.d.ts +22 -0
- package/dist/provider-connection.js +98 -0
- package/dist/provider-limits.d.ts +35 -0
- package/dist/provider-limits.js +95 -0
- package/dist/provider.d.ts +279 -0
- package/dist/provider.js +935 -0
- package/dist/publish.d.ts +107 -0
- package/dist/publish.js +650 -0
- package/dist/pulls.d.ts +118 -0
- package/dist/pulls.js +240 -0
- package/dist/push.d.ts +95 -0
- package/dist/push.js +353 -0
- package/dist/quality.d.ts +8 -0
- package/dist/quality.js +6 -0
- package/dist/recipe-ui.d.ts +18 -0
- package/dist/recipe-ui.js +152 -0
- package/dist/recipes.d.ts +81 -0
- package/dist/recipes.js +332 -0
- package/dist/remote.d.ts +67 -0
- package/dist/remote.js +122 -0
- package/dist/render.d.ts +64 -0
- package/dist/render.js +587 -0
- package/dist/report-summary.d.ts +13 -0
- package/dist/report-summary.js +15 -0
- package/dist/repos.d.ts +65 -0
- package/dist/repos.js +277 -0
- package/dist/repository-context-ui.d.ts +2 -0
- package/dist/repository-context-ui.js +10 -0
- package/dist/repository-context.d.ts +67 -0
- package/dist/repository-context.js +376 -0
- package/dist/restart-certification.d.ts +134 -0
- package/dist/restart-certification.js +226 -0
- package/dist/result-actions.d.ts +28 -0
- package/dist/result-actions.js +270 -0
- package/dist/result-completion.d.ts +18 -0
- package/dist/result-completion.js +66 -0
- package/dist/result-review.d.ts +213 -0
- package/dist/result-review.js +430 -0
- package/dist/retention-ui.d.ts +12 -0
- package/dist/retention-ui.js +39 -0
- package/dist/retention.d.ts +72 -0
- package/dist/retention.js +288 -0
- package/dist/review-context.d.ts +243 -0
- package/dist/review-context.js +1043 -0
- package/dist/review-evidence.d.ts +33 -0
- package/dist/review-evidence.js +56 -0
- package/dist/reviewer.d.ts +97 -0
- package/dist/reviewer.js +202 -0
- package/dist/routine.d.ts +228 -0
- package/dist/routine.js +764 -0
- package/dist/runner.d.ts +266 -0
- package/dist/runner.js +399 -0
- package/dist/scan.d.ts +32 -0
- package/dist/scan.js +92 -0
- package/dist/scope.d.ts +695 -0
- package/dist/scope.js +1176 -0
- package/dist/scout-report.d.ts +42 -0
- package/dist/scout-report.js +108 -0
- package/dist/scout.d.ts +69 -0
- package/dist/scout.js +351 -0
- package/dist/serve.d.ts +313 -0
- package/dist/serve.js +21776 -0
- package/dist/session-brief.d.ts +8 -0
- package/dist/session-brief.js +24 -0
- package/dist/session-cli.d.ts +13 -0
- package/dist/session-cli.js +284 -0
- package/dist/session-contract.d.ts +183 -0
- package/dist/session-contract.js +122 -0
- package/dist/session-http.d.ts +19 -0
- package/dist/session-http.js +154 -0
- package/dist/session-server.d.ts +12 -0
- package/dist/session-server.js +37 -0
- package/dist/session-service.d.ts +22 -0
- package/dist/session-service.js +157 -0
- package/dist/setup-guide.d.ts +39 -0
- package/dist/setup-guide.js +93 -0
- package/dist/sign-in-guard.d.ts +45 -0
- package/dist/sign-in-guard.js +74 -0
- package/dist/skills-ui.d.ts +11 -0
- package/dist/skills-ui.js +58 -0
- package/dist/skills.d.ts +97 -0
- package/dist/skills.js +276 -0
- package/dist/slack-api.d.ts +55 -0
- package/dist/slack-api.js +229 -0
- package/dist/slack-chat.d.ts +28 -0
- package/dist/slack-chat.js +413 -0
- package/dist/slack-settings.d.ts +7 -0
- package/dist/slack-settings.js +75 -0
- package/dist/slack-state.d.ts +13 -0
- package/dist/slack-state.js +9 -0
- package/dist/slack.d.ts +13 -0
- package/dist/slack.js +167 -0
- package/dist/spend-ui.d.ts +28 -0
- package/dist/spend-ui.js +95 -0
- package/dist/spend.d.ts +142 -0
- package/dist/spend.js +313 -0
- package/dist/sqlite-runtime.d.ts +3 -0
- package/dist/sqlite-runtime.js +6 -0
- package/dist/sso-settings.d.ts +33 -0
- package/dist/sso-settings.js +103 -0
- package/dist/sso-ui.d.ts +22 -0
- package/dist/sso-ui.js +39 -0
- package/dist/storage.d.ts +15 -0
- package/dist/storage.js +84 -0
- package/dist/store.d.ts +7754 -0
- package/dist/store.js +23279 -0
- package/dist/structured-output.d.ts +58 -0
- package/dist/structured-output.js +103 -0
- package/dist/style-asset.d.ts +7 -0
- package/dist/style-asset.js +41 -0
- package/dist/subscription-chat.d.ts +46 -0
- package/dist/subscription-chat.js +275 -0
- package/dist/summary.d.ts +33 -0
- package/dist/summary.js +71 -0
- package/dist/supervisor.mjs +297 -0
- package/dist/surface.d.ts +63 -0
- package/dist/surface.js +352 -0
- package/dist/sync.d.ts +94 -0
- package/dist/sync.js +279 -0
- package/dist/task-composer.d.ts +13 -0
- package/dist/task-composer.js +52 -0
- package/dist/task-control.d.ts +165 -0
- package/dist/task-control.js +214 -0
- package/dist/task-outcome-cli.d.ts +10 -0
- package/dist/task-outcome-cli.js +92 -0
- package/dist/task-text.d.ts +30 -0
- package/dist/task-text.js +41 -0
- package/dist/team-cli.d.ts +15 -0
- package/dist/team-cli.js +618 -0
- package/dist/team-contract.d.ts +92 -0
- package/dist/team-contract.js +1 -0
- package/dist/team-http.d.ts +17 -0
- package/dist/team-http.js +144 -0
- package/dist/team-leads.d.ts +81 -0
- package/dist/team-leads.js +565 -0
- package/dist/team-runtime.d.ts +27 -0
- package/dist/team-runtime.js +264 -0
- package/dist/team-ui.d.ts +3 -0
- package/dist/team-ui.js +9 -0
- package/dist/team-updates.d.ts +8 -0
- package/dist/team-updates.js +57 -0
- package/dist/teammate-admin.d.ts +53 -0
- package/dist/teammate-admin.js +111 -0
- package/dist/teammate-desk.d.ts +60 -0
- package/dist/teammate-desk.js +154 -0
- package/dist/teammate-memory.d.ts +64 -0
- package/dist/teammate-memory.js +196 -0
- package/dist/teammate-question.d.ts +59 -0
- package/dist/teammate-question.js +175 -0
- package/dist/teammate-tools.d.ts +108 -0
- package/dist/teammate-tools.js +271 -0
- package/dist/teammate-week.d.ts +68 -0
- package/dist/teammate-week.js +132 -0
- package/dist/teammate-work.d.ts +76 -0
- package/dist/teammate-work.js +280 -0
- package/dist/teammates-ui.d.ts +20 -0
- package/dist/teammates-ui.js +166 -0
- package/dist/teammates.d.ts +180 -0
- package/dist/teammates.js +253 -0
- package/dist/teams-api.d.ts +33 -0
- package/dist/teams-api.js +204 -0
- package/dist/teams-chat.d.ts +26 -0
- package/dist/teams-chat.js +215 -0
- package/dist/teams-settings.d.ts +12 -0
- package/dist/teams-settings.js +57 -0
- package/dist/teams.d.ts +21 -0
- package/dist/teams.js +124 -0
- package/dist/telegram-flow.d.ts +49 -0
- package/dist/telegram-flow.js +110 -0
- package/dist/telegram-mate.d.ts +137 -0
- package/dist/telegram-mate.js +707 -0
- package/dist/telegram-progress.d.ts +14 -0
- package/dist/telegram-progress.js +129 -0
- package/dist/telegram-settings.d.ts +9 -0
- package/dist/telegram-settings.js +36 -0
- package/dist/telegram-status.d.ts +75 -0
- package/dist/telegram-status.js +265 -0
- package/dist/telegram-team.d.ts +85 -0
- package/dist/telegram-team.js +359 -0
- package/dist/telegram.d.ts +230 -0
- package/dist/telegram.js +1931 -0
- package/dist/templates.d.ts +65 -0
- package/dist/templates.js +118 -0
- package/dist/tool-launcher.d.ts +1 -0
- package/dist/tool-launcher.js +101 -0
- package/dist/tools-ui.d.ts +30 -0
- package/dist/tools-ui.js +40 -0
- package/dist/transitions-recipes.d.ts +1 -0
- package/dist/transitions-recipes.js +203 -0
- package/dist/tree-proof.d.ts +34 -0
- package/dist/tree-proof.js +58 -0
- package/dist/verification-evidence.d.ts +44 -0
- package/dist/verification-evidence.js +238 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/dist/webhooks.d.ts +91 -0
- package/dist/webhooks.js +283 -0
- package/dist/work-index.d.ts +68 -0
- package/dist/work-index.js +384 -0
- package/dist/work-summary.d.ts +57 -0
- package/dist/work-summary.js +116 -0
- package/dist/workspace-motion.d.ts +4 -0
- package/dist/workspace-motion.js +133 -0
- package/dist/workspace-revision.d.ts +19 -0
- package/dist/workspace-revision.js +92 -0
- package/dist/workspace-ui.d.ts +204 -0
- package/dist/workspace-ui.js +411 -0
- package/dist/worktree-notices.d.ts +13 -0
- package/dist/worktree-notices.js +17 -0
- package/dist/worktree.d.ts +249 -0
- package/dist/worktree.js +720 -0
- package/package.json +122 -0
- package/scripts/canary-assertions.mjs +42 -0
- package/scripts/crash-canary.mjs +253 -0
- package/scripts/fixtures/crash-process.mjs +74 -0
- package/scripts/fixtures/pilot-scenarios.mjs +85 -0
- package/scripts/fixtures/restart-service.mjs +27 -0
- package/scripts/launchd-certification.mjs +143 -0
- package/scripts/pilot.mjs +121 -0
- package/scripts/proof-preflight.mjs +140 -0
- package/scripts/provider-canary.mjs +379 -0
- package/scripts/recovery-canary.mjs +135 -0
- package/scripts/restart-certification.mjs +98 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { release } from "node:os";
|
|
5
|
+
import { normalizeBootId } from "./boot-identity.js";
|
|
6
|
+
import { changedDarwinProcessIdentities, collectDarwinCoalitionSnapshot } from "./process-recovery-native.js";
|
|
7
|
+
const label = "com.apple.speech.SpeechSynthesisServerXPC";
|
|
8
|
+
const bundle = "/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/XPCServices/SpeechSynthesisServerXPC.xpc";
|
|
9
|
+
export const APP_SERVICE_EXECUTABLE = `${bundle}/Contents/MacOS/SpeechSynthesisServerXPC`;
|
|
10
|
+
const executable = APP_SERVICE_EXECUTABLE;
|
|
11
|
+
const chrome = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome";
|
|
12
|
+
const clonePathSha256 = "0e92ba8224883b668b6becb0f2768fdca1912630e176ded161b6786822ec2a73";
|
|
13
|
+
const cloneSha256 = "fe21b4086d7f035b17ce4c8ff9d1ceef88eb9510252a5b311d7a5aa48c352b32";
|
|
14
|
+
const cloneCdHash = "fab09b6e6ce70ffb18f6f672564b1215c8a7c75f";
|
|
15
|
+
export const APP_SERVICE_PLATFORM = Object.freeze({ osRelease: "25.5.0", osBuild: "25F84", serviceType: "Application", label,
|
|
16
|
+
codesignSha256: "214d455584d19abc0d74d02b9cbc7d3da6bdcb0596c235e6156dd9ed2f4e1ba7", clonePathSha256, cloneSha256, cloneCdHash,
|
|
17
|
+
launchctlSha256: "b1f2b90f349938cc4c3c9234f11cefd05545f7b4bfe9b1751ac01f1cb27d3714",
|
|
18
|
+
plistSha256: "c26cec3d7afe55cb33c360018c04d0c848df45dbe1ea3c3c50c9dd3b9d483aee",
|
|
19
|
+
executableSha256: "0be2afc6ec7bce4c06e14cdfe7e5155b394f98a689189f069a6ca8611fd7911d" });
|
|
20
|
+
const env = { PATH: "/usr/bin:/bin:/usr/sbin:/sbin", LC_ALL: "C", TZ: "UTC" };
|
|
21
|
+
const command = (file, args) => execFileSync(file, args, { encoding: "utf8", env, timeout: 10_000, killSignal: "SIGKILL", maxBuffer: 1024 * 1024 });
|
|
22
|
+
const digest = (data) => createHash("sha256").update(data).digest("hex");
|
|
23
|
+
const hash = (path) => digest(readFileSync(path));
|
|
24
|
+
const isChrome = (path) => path !== null && (path === chrome || digest(path) === clonePathSha256);
|
|
25
|
+
function platformMatches() {
|
|
26
|
+
return process.platform === "darwin" && release() === APP_SERVICE_PLATFORM.osRelease && command("/usr/bin/sw_vers", ["-buildVersion"]).trim() === APP_SERVICE_PLATFORM.osBuild &&
|
|
27
|
+
hash("/usr/bin/codesign") === APP_SERVICE_PLATFORM.codesignSha256 && hash("/bin/launchctl") === APP_SERVICE_PLATFORM.launchctlSha256 && hash(`${bundle}/Contents/Info.plist`) === APP_SERVICE_PLATFORM.plistSha256 && hash(executable) === APP_SERVICE_PLATFORM.executableSha256;
|
|
28
|
+
}
|
|
29
|
+
const id = (s) => typeof s === "string" && /^[1-9][0-9]{0,19}$/.test(s) && BigInt(s) <= 0xffffffffffffffffn;
|
|
30
|
+
function requireFact(ok) { if (!ok)
|
|
31
|
+
throw Error("unrecognized-app-service-fact"); }
|
|
32
|
+
/** launchctl explicitly promises no stable print API. This parser is restricted
|
|
33
|
+
* to the inspected tool/OS hashes, entire balanced records and singleton fields.
|
|
34
|
+
* Environment continuations cannot create identity fields or hide duplicates. */
|
|
35
|
+
function record(text, header) {
|
|
36
|
+
requireFact(!/[^\x09\x0a\x20-\x7e]/.test(text));
|
|
37
|
+
const lines = text.trimEnd().split("\n");
|
|
38
|
+
requireFact(lines.shift() === `${header} = {` && lines.pop() === "}");
|
|
39
|
+
const fields = new Map(), sections = new Map();
|
|
40
|
+
const stack = [], seen = new Set();
|
|
41
|
+
const allowed = new Set(["security context", "environment", "inherited environment", "default environment", "services", "service stubs", "unmanaged processes", "endpoints", "task-special ports", "resource coalition", "jetsam coalition"]);
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
if (line === "")
|
|
44
|
+
continue;
|
|
45
|
+
const m = /^(\t*)([^\t].*)$/.exec(line);
|
|
46
|
+
requireFact(m);
|
|
47
|
+
const depth = m[1].length, value = m[2];
|
|
48
|
+
if (value === "}") {
|
|
49
|
+
requireFact(stack.length && depth === stack.length);
|
|
50
|
+
stack.pop();
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (stack.length === 1 && stack[0] === "task-special ports") {
|
|
54
|
+
requireFact(depth === 3 && /^ *0x[0-9a-f]+ +[0-9]+ +[a-z-]+ +\([^{}=\t]*\)$/.test(value));
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
requireFact(depth === stack.length + 1);
|
|
58
|
+
const open = /^([^{}]+) = \{$/.exec(value);
|
|
59
|
+
if (open) {
|
|
60
|
+
const key = open[1], path = [...stack, key].join("/");
|
|
61
|
+
requireFact(!seen.has(path) && !fields.has(key) && (stack.length === 0 ? allowed.has(key) : stack.length === 1 && stack[0] === "endpoints" && /^"?[A-Za-z0-9._-]+"?$/.test(key)));
|
|
62
|
+
seen.add(path);
|
|
63
|
+
stack.push(key);
|
|
64
|
+
if (stack.length === 1)
|
|
65
|
+
sections.set(key, []);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
requireFact(!/[{}]/.test(value));
|
|
69
|
+
if (stack.length) {
|
|
70
|
+
if (stack[0].endsWith("environment"))
|
|
71
|
+
requireFact(stack.length === 1 && /^[A-Za-z_][A-Za-z0-9_]* => [^\t]*$/.test(value));
|
|
72
|
+
else
|
|
73
|
+
requireFact(!/^(?:pid|uniqueid|handle|creator|domain|program|path|bundle id) = /.test(value));
|
|
74
|
+
sections.get(stack[0]).push(line);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const field = /^([^=]+) = ([^\t]*)$/.exec(value);
|
|
78
|
+
requireFact(field);
|
|
79
|
+
requireFact(!fields.has(field[1]) && !seen.has(field[1]));
|
|
80
|
+
fields.set(field[1], field[2]);
|
|
81
|
+
}
|
|
82
|
+
requireFact(!stack.length);
|
|
83
|
+
return { fields, sections };
|
|
84
|
+
}
|
|
85
|
+
function sealed(s, anchorPids, bound) {
|
|
86
|
+
const a = s.anchors.find(p => p.pid === bound.pid), counters = s.counterBefore;
|
|
87
|
+
return s.schema === 1 && s.complete && s.stable && s.kernelTableRead && s.countersStable && s.unreadableMembershipCount === 0 &&
|
|
88
|
+
!s.errors.length && !s.identityChanges.length && !s.anchorIdentityChanges.length && !!normalizeBootId(s.bootId ?? "") &&
|
|
89
|
+
s.osRelease === APP_SERVICE_PLATFORM.osRelease && s.anchorPids.length === anchorPids.length && anchorPids.every(pid => s.anchorPids.includes(pid)) &&
|
|
90
|
+
a?.uniqueId === bound.uniqueId && a.traced === false && s.collector?.exited === true &&
|
|
91
|
+
s.processes.some(p => p.pid === s.collector.pid && p.uniqueId === s.collector.uniqueId) &&
|
|
92
|
+
!!counters && id(counters.tasksStarted) && /^(0|[1-9][0-9]*)$/.test(counters.tasksExited) &&
|
|
93
|
+
counters.tasksStarted === s.counterAfter?.tasksStarted && counters.tasksExited === s.counterAfter?.tasksExited &&
|
|
94
|
+
BigInt(counters.tasksStarted) - BigInt(counters.tasksExited) === BigInt(s.processes.length) &&
|
|
95
|
+
new Set(s.processes.map(p => p.pid)).size === s.processes.length && new Set(s.processes.map(p => p.uniqueId)).size === s.processes.length &&
|
|
96
|
+
s.processes.every(p => Number.isSafeInteger(p.pid) && p.pid > 1 && p.pid <= 0x7fffffff && id(p.uniqueId) && p.resourceCoalitionId === s.resourceCoalitionId);
|
|
97
|
+
}
|
|
98
|
+
function signing(pid, path, phase) {
|
|
99
|
+
if (path === chrome)
|
|
100
|
+
return null;
|
|
101
|
+
phase("owner-signature-bytes");
|
|
102
|
+
requireFact(digest(path) === clonePathSha256 && hash(path) === cloneSha256);
|
|
103
|
+
// Dynamic PID verification checks the running code. A display alone is not
|
|
104
|
+
// validation; the inspected clone's static resource-metadata check refused.
|
|
105
|
+
const run = (args) => {
|
|
106
|
+
const r = spawnSync("/usr/bin/codesign", args, { encoding: "utf8", env, timeout: 10_000, killSignal: "SIGKILL", maxBuffer: 65536, stdio: "pipe" });
|
|
107
|
+
requireFact(!r.error && r.status === 0 && r.signal === null && r.stdout === "");
|
|
108
|
+
return r.stderr;
|
|
109
|
+
};
|
|
110
|
+
phase("owner-signature-verify");
|
|
111
|
+
run(["--verify", "--strict", `+${pid}`]);
|
|
112
|
+
phase("owner-signature-display");
|
|
113
|
+
const display = run(["--display", "--verbose=4", `+${pid}`]);
|
|
114
|
+
// codesign localizes its non-authoritative timestamp with a narrow no-break
|
|
115
|
+
// space even under LC_ALL=C. Identity lines remain exact ASCII singletons.
|
|
116
|
+
requireFact(display.split("\n").every(line => !/[^\x20-\x7e]/.test(line) || /^Timestamp=[\x20-\x7e]*\u202f(?:AM|PM)$/.test(line)));
|
|
117
|
+
const value = (key) => { const all = display.split("\n").filter(l => l.startsWith(`${key}=`)); requireFact(all.length === 1); return all[0].slice(key.length + 1); };
|
|
118
|
+
requireFact(value("Executable") === path && value("Identifier") === "com.google.Chrome" && value("TeamIdentifier") === "EQHXZ8M8AV" && value("CDHash") === cloneCdHash);
|
|
119
|
+
return { identifier: "com.google.Chrome", teamId: "EQHXZ8M8AV", cdHash: cloneCdHash, dynamicallyVerified: true };
|
|
120
|
+
}
|
|
121
|
+
function bindings(s, ownerPids, bound, phase) {
|
|
122
|
+
const result = [];
|
|
123
|
+
for (const ownerPid of ownerPids) {
|
|
124
|
+
phase("owner-identity");
|
|
125
|
+
const owner = s.processes.find(p => p.pid === ownerPid);
|
|
126
|
+
requireFact(owner && id(owner.uniqueId) && BigInt(owner.uniqueId) <= BigInt(bound.uniqueId) && owner.traced === false && isChrome(owner.executable) && owner.uid !== null && Number.isInteger(owner.pidVersion) && owner.pidVersion > 0);
|
|
127
|
+
phase("owner-domain");
|
|
128
|
+
const domain = `pid/${ownerPid}`, d = record(command("/bin/launchctl", ["print", domain]), domain);
|
|
129
|
+
requireFact(d.fields.get("type") === "pid" && d.fields.get("handle") === String(ownerPid) && d.fields.get("uniqueid") === owner.uniqueId &&
|
|
130
|
+
d.fields.get("creator") === `Google Chrome[${ownerPid}]` && d.fields.get("creator euid") === String(owner.uid) && d.fields.get("originator") === "/Applications/Google Chrome.app");
|
|
131
|
+
const rows = d.sections.get("services");
|
|
132
|
+
requireFact(rows);
|
|
133
|
+
const entries = rows.map(line => { const m = /^\t\t\s*(0|[1-9][0-9]*|-)\s+([-A-Za-z0-9?()]+)\s+([A-Za-z0-9._-]+)$/.exec(line); requireFact(m); return { pid: m[1], label: m[3] }; });
|
|
134
|
+
requireFact(new Set(entries.map(e => e.label)).size === entries.length);
|
|
135
|
+
// A pending job supplies no live identity or exit evidence. Any unmatched
|
|
136
|
+
// process in the final native census still needs its own exclusion proof.
|
|
137
|
+
const entry = entries.find(e => e.label === label);
|
|
138
|
+
if (!entry || entry.pid === "-" || entry.pid === "0")
|
|
139
|
+
continue;
|
|
140
|
+
phase("service-job");
|
|
141
|
+
const pid = Number(entry.pid), process = s.processes.find(p => p.pid === pid);
|
|
142
|
+
requireFact(process && id(process.uniqueId) && process.traced === false && process.uid === owner.uid && process.executable === executable && process.resourceCoalitionId === owner.resourceCoalitionId);
|
|
143
|
+
const job = record(command("/bin/launchctl", ["print", `${domain}/${label}`]), `${domain}/${label}`).fields;
|
|
144
|
+
requireFact(job.get("type") === "XPCService" && job.get("state") === "running" && job.get("domain") === `${domain} [Google Chrome]` &&
|
|
145
|
+
job.get("pid") === String(pid) && job.get("path") === bundle && job.get("program") === executable && job.get("bundle id") === label && job.get("forks") === "0" && job.get("execs") === "1");
|
|
146
|
+
requireFact(!result.some(p => p.pid === pid));
|
|
147
|
+
const ownerSigning = signing(ownerPid, owner.executable, phase);
|
|
148
|
+
result.push({ pid, uniqueId: process.uniqueId, ownerPid, ownerUniqueId: owner.uniqueId, ownerExecutable: owner.executable, ownerPidVersion: owner.pidVersion, ownerSigning, uid: owner.uid, resourceCoalitionId: owner.resourceCoalitionId, executable, domain, platform: APP_SERVICE_PLATFORM });
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
/** Read-only observations, not exit/custody authority. Caller must authenticate
|
|
153
|
+
* upperBound historically and consume these facts inside its existing proof. */
|
|
154
|
+
export async function collectPreexistingAppServices(args) {
|
|
155
|
+
let phase = "platform";
|
|
156
|
+
const at = (value) => { phase = value; };
|
|
157
|
+
try {
|
|
158
|
+
if (!platformMatches())
|
|
159
|
+
return { ok: false, reason: "app-service-platform-unrecognized" };
|
|
160
|
+
const native = { ...args.native };
|
|
161
|
+
const initial = structuredClone(args.snapshot), bound = { ...args.upperBound }, anchorPids = [...args.anchorPids];
|
|
162
|
+
at("initial-census");
|
|
163
|
+
requireFact(id(bound.uniqueId) && anchorPids.includes(bound.pid) && new Set(anchorPids).size === anchorPids.length && sealed(initial, anchorPids, bound));
|
|
164
|
+
requireFact(initial.nativeSourceSha256 === native.sourceSha256 && initial.nativeExecutableSha256 === native.executableSha256);
|
|
165
|
+
const owners = initial.processes.filter(p => isChrome(p.executable) && p.traced === false && id(p.uniqueId) && BigInt(p.uniqueId) <= BigInt(bound.uniqueId)).map(p => p.pid).sort((a, b) => a - b);
|
|
166
|
+
const first = bindings(initial, owners, bound, at);
|
|
167
|
+
const collect = () => collectDarwinCoalitionSnapshot({ native, resourceCoalitionId: initial.resourceCoalitionId, anchorPids, maxAttempts: 1 });
|
|
168
|
+
const validate = (next) => {
|
|
169
|
+
requireFact(sealed(next, anchorPids, bound) && normalizeBootId(next.bootId ?? "") === normalizeBootId(initial.bootId ?? "") && next.host === initial.host && next.resourceCoalitionId === initial.resourceCoalitionId && next.nativeSourceSha256 === initial.nativeSourceSha256 && next.nativeExecutableSha256 === initial.nativeExecutableSha256);
|
|
170
|
+
const pids = new Set([...owners, ...first.map(p => p.pid)]);
|
|
171
|
+
requireFact(!changedDarwinProcessIdentities(initial.processes.filter(p => pids.has(p.pid)), next.processes.filter(p => pids.has(p.pid))).length &&
|
|
172
|
+
!changedDarwinProcessIdentities(initial.anchors, next.anchors).length);
|
|
173
|
+
};
|
|
174
|
+
at("middle-census");
|
|
175
|
+
const middle = await collect();
|
|
176
|
+
validate(middle);
|
|
177
|
+
const repeated = bindings(middle, owners, bound, at);
|
|
178
|
+
at("repeated-binding");
|
|
179
|
+
requireFact(JSON.stringify(first) === JSON.stringify(repeated));
|
|
180
|
+
at("platform");
|
|
181
|
+
if (!platformMatches())
|
|
182
|
+
return { ok: false, reason: "app-service-platform-unrecognized" };
|
|
183
|
+
at("final-census");
|
|
184
|
+
const final = await collect();
|
|
185
|
+
validate(final);
|
|
186
|
+
return { ok: true, snapshot: final, services: first };
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return { ok: false, reason: "app-service-observation-refused", diagnostic: { phase } };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Store } from "./store.js";
|
|
2
|
+
/** A one-shot legacy repair, never a force-clear API. It recollects its own
|
|
3
|
+
* pinned historical and current OS facts. Serialized successful reports are
|
|
4
|
+
* deliberately not inputs. Inspection is the default and never writes custody.
|
|
5
|
+
* The caller opens the compatible Store; this function never migrates it. */
|
|
6
|
+
export declare function recoverPreparedObserverGap(store: Store, input: {
|
|
7
|
+
profilePath: string;
|
|
8
|
+
compilationDirectory: string;
|
|
9
|
+
evidenceRoot: string;
|
|
10
|
+
mode: "inspect" | "record";
|
|
11
|
+
}): Promise<{
|
|
12
|
+
ok: false;
|
|
13
|
+
reason: string;
|
|
14
|
+
} | {
|
|
15
|
+
runId: number;
|
|
16
|
+
witnessIds: number[];
|
|
17
|
+
certificateDigest: string;
|
|
18
|
+
observedAt: string;
|
|
19
|
+
assumptions: string[];
|
|
20
|
+
ok: true;
|
|
21
|
+
recorded: false;
|
|
22
|
+
} | {
|
|
23
|
+
runId: number;
|
|
24
|
+
witnessIds: number[];
|
|
25
|
+
certificateDigest: string;
|
|
26
|
+
observedAt: string;
|
|
27
|
+
assumptions: string[];
|
|
28
|
+
ok: true;
|
|
29
|
+
recorded: true;
|
|
30
|
+
actionId: number;
|
|
31
|
+
certificatePath: string;
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { closeSync, constants, fstatSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { currentBootId } from "./boot-identity.js";
|
|
6
|
+
import { assessDarwinCoalitionRecovery } from "./process-recovery-coalition.js";
|
|
7
|
+
import { preparedCandidateObserverGapEligibility } from "./process-recovery-eligibility.js";
|
|
8
|
+
import { collectLegacySourceProvenance, collectedLegacyProvenanceOf } from "./process-recovery-provenance.js";
|
|
9
|
+
const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
10
|
+
/** A one-shot legacy repair, never a force-clear API. It recollects its own
|
|
11
|
+
* pinned historical and current OS facts. Serialized successful reports are
|
|
12
|
+
* deliberately not inputs. Inspection is the default and never writes custody.
|
|
13
|
+
* The caller opens the compatible Store; this function never migrates it. */
|
|
14
|
+
export async function recoverPreparedObserverGap(store, input) {
|
|
15
|
+
const refuse = (reason) => ({ ok: false, reason });
|
|
16
|
+
if (input.mode !== "inspect" && input.mode !== "record")
|
|
17
|
+
return refuse("invalid-recovery-mode");
|
|
18
|
+
const collected = await collectLegacySourceProvenance(store.handle, input);
|
|
19
|
+
// The collector exposes only fixed diagnostic codes. Preserve the failed
|
|
20
|
+
// phase so an operator can distinguish an unreadable anchor from a later
|
|
21
|
+
// source or service observation without exposing subprocess output.
|
|
22
|
+
if (!collected.ok)
|
|
23
|
+
return collected;
|
|
24
|
+
const live = collectedLegacyProvenanceOf(collected.proof);
|
|
25
|
+
if (!live)
|
|
26
|
+
return refuse("uncollected-process-evidence");
|
|
27
|
+
const { receipt, snapshot, anchor } = live;
|
|
28
|
+
const now = new Date();
|
|
29
|
+
const context = { runId: receipt.targetRun, evidenceRoot: input.evidenceRoot, now,
|
|
30
|
+
host: hostname(), bootId: currentBootId() };
|
|
31
|
+
let matchingRoot = false;
|
|
32
|
+
try {
|
|
33
|
+
matchingRoot = realpathSync(input.evidenceRoot) === join(dirname(anchor.databasePath), "evidence");
|
|
34
|
+
}
|
|
35
|
+
catch { /* Refuse an unreadable evidence root. */ }
|
|
36
|
+
if (context.host !== receipt.host || context.bootId !== receipt.bootId || !matchingRoot ||
|
|
37
|
+
![snapshot.startedAt, snapshot.finishedAt].every(value => Number.isFinite(Date.parse(value))) || Date.parse(snapshot.finishedAt) > now.getTime() ||
|
|
38
|
+
Date.parse(snapshot.startedAt) > Date.parse(snapshot.finishedAt))
|
|
39
|
+
return refuse("recovery-context-changed");
|
|
40
|
+
const eligible = preparedCandidateObserverGapEligibility(store, context);
|
|
41
|
+
if (!eligible.ok)
|
|
42
|
+
return refuse(eligible.reason);
|
|
43
|
+
if (eligible.binding.run.head !== receipt.head || eligible.binding.scope.digest !== receipt.scopeDigest ||
|
|
44
|
+
Date.parse(snapshot.startedAt) <= Date.parse(eligible.binding.run.finishedAt) ||
|
|
45
|
+
snapshot.nativeSourceSha256 !== anchor.nativeSourceSha256 || snapshot.nativeExecutableSha256 !== anchor.nativeExecutableSha256 ||
|
|
46
|
+
sha256(JSON.stringify(snapshot)) !== receipt.snapshotDigest)
|
|
47
|
+
return refuse("recovery-source-mismatch");
|
|
48
|
+
const assessed = assessDarwinCoalitionRecovery({ host: context.host, bootId: receipt.bootId,
|
|
49
|
+
resourceCoalitionId: receipt.resourceCoalitionId, sourceRoot: receipt.sourceRoot,
|
|
50
|
+
preRunUpperBound: receipt.preRunUpperBound, snapshot, preexistingAppServices: receipt.preexistingAppServices });
|
|
51
|
+
if (!assessed.ok)
|
|
52
|
+
return refuse("surviving-processes-not-excluded");
|
|
53
|
+
const certificate = { schema: 1, kind: "prepared-observer-gap-absence", collectedAt: now.toISOString(),
|
|
54
|
+
eligibility: eligible, provenance: receipt, anchor, inventory: snapshot, assessment: assessed,
|
|
55
|
+
statement: "Positive current absence of direct and ordinary-fork descendants under the recorded audited first-party path and trusted execution assumptions. This observation alone is not a database settlement; a matching committed action-ledger entry records application." };
|
|
56
|
+
const bytes = Buffer.from(JSON.stringify(certificate) + "\n"), digest = sha256(bytes);
|
|
57
|
+
const result = { runId: receipt.targetRun, witnessIds: [...eligible.binding.unknownWitnessIds],
|
|
58
|
+
certificateDigest: digest, observedAt: snapshot.finishedAt, assumptions: receipt.assumptions };
|
|
59
|
+
if (input.mode === "inspect")
|
|
60
|
+
return { ok: true, recorded: false, ...result };
|
|
61
|
+
// Preserve the entire pre-mutation row inventory and OS observations first.
|
|
62
|
+
// Exclusive, owned files remain as observations if a later transaction fails.
|
|
63
|
+
const directory = join(dirname(anchor.databasePath), "process-recovery");
|
|
64
|
+
let certificatePath;
|
|
65
|
+
try {
|
|
66
|
+
mkdirSync(directory, { mode: 0o700 });
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error.code !== "EEXIST")
|
|
70
|
+
return refuse("recovery-audit-unavailable");
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const stat = lstatSync(directory);
|
|
74
|
+
if (!stat.isDirectory() || stat.isSymbolicLink() || stat.uid !== process.getuid?.() || (stat.mode & 0o077) !== 0 || realpathSync(directory) !== directory)
|
|
75
|
+
return refuse("recovery-audit-unavailable");
|
|
76
|
+
certificatePath = join(directory, digest + ".json");
|
|
77
|
+
const fd = openSync(certificatePath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
78
|
+
try {
|
|
79
|
+
writeFileSync(fd, bytes);
|
|
80
|
+
fsyncSync(fd);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
closeSync(fd);
|
|
84
|
+
}
|
|
85
|
+
const parent = openSync(directory, constants.O_RDONLY);
|
|
86
|
+
try {
|
|
87
|
+
fsyncSync(parent);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
closeSync(parent);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return refuse("recovery-audit-unavailable");
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
return store.transact(() => store.savepoint(() => {
|
|
98
|
+
if (hostname() !== context.host || currentBootId() !== context.bootId)
|
|
99
|
+
throw Error("recovery-context-changed");
|
|
100
|
+
const current = preparedCandidateObserverGapEligibility(store, { ...context, now: new Date() });
|
|
101
|
+
if (!current.ok || current.digest !== eligible.digest)
|
|
102
|
+
throw Error("recovery-custody-changed");
|
|
103
|
+
const fd = openSync(certificatePath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
104
|
+
try {
|
|
105
|
+
const stat = fstatSync(fd);
|
|
106
|
+
if (!stat.isFile() || stat.uid !== process.getuid?.() || (stat.mode & 0o777) !== 0o600 || sha256(readFileSync(fd)) !== digest)
|
|
107
|
+
throw Error("recovery-audit-changed");
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
closeSync(fd);
|
|
111
|
+
}
|
|
112
|
+
for (const row of current.binding.witnesses.filter(row => current.binding.unknownWitnessIds.includes(row.id))) {
|
|
113
|
+
const update = store.handle.prepare(`UPDATE run_process SET exited_at = ?
|
|
114
|
+
WHERE id = ? AND run = ? AND pid IS ? AND host = ? AND process_group = ?
|
|
115
|
+
AND observed_at = ? AND exited_at IS NULL AND boot_id IS ? AND containment IS ?
|
|
116
|
+
AND container IS ? AND container_identity IS ? AND container_empty_at IS ?`)
|
|
117
|
+
.run(snapshot.finishedAt, row.id, row.run, row.pid, row.host, row.process_group, row.observed_at, row.boot_id, row.containment, row.container, row.container_identity, row.container_empty_at);
|
|
118
|
+
if (Number(update.changes) !== 1)
|
|
119
|
+
throw Error("recovery-custody-changed");
|
|
120
|
+
}
|
|
121
|
+
if (store.stopQuiescenceProblem(receipt.targetRun) !== null)
|
|
122
|
+
throw Error("run-still-not-quiescent");
|
|
123
|
+
const actionId = store.recordAction({ at: new Date().toISOString(), actor: "system", repo: current.binding.run.repo,
|
|
124
|
+
taskId: current.binding.run.taskId, runId: receipt.targetRun, action: "process absence recovered",
|
|
125
|
+
outcome: digest, source: "work" });
|
|
126
|
+
return { ok: true, recorded: true, ...result, actionId, certificatePath };
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return refuse("recovery-not-recorded");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { DarwinProcessRecoverySnapshot } from "./process-recovery-native.js";
|
|
2
|
+
export type ProcessRecoveryAssessment = {
|
|
3
|
+
ok: true;
|
|
4
|
+
observedAt: string;
|
|
5
|
+
external: {
|
|
6
|
+
pid: number;
|
|
7
|
+
basis: "predates-run" | "managed-service" | "pre-existing-app-service" | "ancestry" | "owned-probe";
|
|
8
|
+
anchor: number;
|
|
9
|
+
}[];
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
problems: string[];
|
|
13
|
+
unresolved: number[];
|
|
14
|
+
};
|
|
15
|
+
export type ProcessRecoveryAnchor = {
|
|
16
|
+
pid: number;
|
|
17
|
+
uniqueId: string;
|
|
18
|
+
};
|
|
19
|
+
/** Read-only assessment of a COMPLETE, stable OS census. The caller must
|
|
20
|
+
* separately prove that the missing record is an observation gap, every
|
|
21
|
+
* actual spawn is accounted for, every recorded owned process has positive
|
|
22
|
+
* exit evidence, and the terminal run cannot launch more work, including
|
|
23
|
+
* outstanding delegated launches.
|
|
24
|
+
* preRunIdentities must come from authenticated observations on this host/boot
|
|
25
|
+
* before the earliest possible task spawn, not from current wall-clock birth
|
|
26
|
+
* times. Trusted managed identities require independent proof that the job
|
|
27
|
+
* is external to the task, including jobs the task could delegate to launchd.
|
|
28
|
+
* A launchd service listing alone establishes no such independence. This
|
|
29
|
+
* pure function checks identity binding, not the provenance of these inputs.
|
|
30
|
+
* A missing spawn cannot be recovered by following its old worker's ancestry.
|
|
31
|
+
* Numeric PIDs, process names and 32-bit original-parent versions authorize
|
|
32
|
+
* nothing. In particular, reparenting to launchd is never exit evidence. */
|
|
33
|
+
export declare function assessDarwinObserverRecovery(args: {
|
|
34
|
+
host: string;
|
|
35
|
+
bootId: string;
|
|
36
|
+
boundary: string;
|
|
37
|
+
runFinishedAt: string;
|
|
38
|
+
preRunIdentities: readonly ProcessRecoveryAnchor[];
|
|
39
|
+
trustedExternalManagedServiceIdentities: readonly ProcessRecoveryAnchor[];
|
|
40
|
+
snapshot: DarwinProcessRecoverySnapshot;
|
|
41
|
+
}): ProcessRecoveryAssessment;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { normalizeBootId } from "./boot-identity.js";
|
|
2
|
+
const iso = (value) => {
|
|
3
|
+
const time = Date.parse(value);
|
|
4
|
+
return Number.isFinite(time) && new Date(time).toISOString() === value ? time : null;
|
|
5
|
+
};
|
|
6
|
+
const identity = (value) => typeof value === "string" && /^[1-9][0-9]{0,19}$/.test(value) && BigInt(value) <= 0xffffffffffffffffn;
|
|
7
|
+
/** Read-only assessment of a COMPLETE, stable OS census. The caller must
|
|
8
|
+
* separately prove that the missing record is an observation gap, every
|
|
9
|
+
* actual spawn is accounted for, every recorded owned process has positive
|
|
10
|
+
* exit evidence, and the terminal run cannot launch more work, including
|
|
11
|
+
* outstanding delegated launches.
|
|
12
|
+
* preRunIdentities must come from authenticated observations on this host/boot
|
|
13
|
+
* before the earliest possible task spawn, not from current wall-clock birth
|
|
14
|
+
* times. Trusted managed identities require independent proof that the job
|
|
15
|
+
* is external to the task, including jobs the task could delegate to launchd.
|
|
16
|
+
* A launchd service listing alone establishes no such independence. This
|
|
17
|
+
* pure function checks identity binding, not the provenance of these inputs.
|
|
18
|
+
* A missing spawn cannot be recovered by following its old worker's ancestry.
|
|
19
|
+
* Numeric PIDs, process names and 32-bit original-parent versions authorize
|
|
20
|
+
* nothing. In particular, reparenting to launchd is never exit evidence. */
|
|
21
|
+
export function assessDarwinObserverRecovery(args) {
|
|
22
|
+
const { snapshot } = args;
|
|
23
|
+
const refuse = (...problems) => ({ ok: false, problems, unresolved: [] });
|
|
24
|
+
const boundary = iso(args.boundary), ended = iso(args.runFinishedAt);
|
|
25
|
+
const began = iso(snapshot.startedAt), finished = iso(snapshot.finishedAt);
|
|
26
|
+
const boot = normalizeBootId(args.bootId);
|
|
27
|
+
if (boot === null || snapshot.bootId === null || normalizeBootId(snapshot.bootId) !== boot || snapshot.host !== args.host)
|
|
28
|
+
return refuse("The process census belongs to a different or unreadable host/boot.");
|
|
29
|
+
if (boundary === null || ended === null || began === null || finished === null || boundary > ended || ended > began || began > finished)
|
|
30
|
+
return refuse("The run and process census timestamps do not establish a recovery interval.");
|
|
31
|
+
if (snapshot.schema !== 1 || !snapshot.complete || !snapshot.stable || snapshot.errors.length || snapshot.identityChanges.length)
|
|
32
|
+
return refuse("The complete process census could not be read and revalidated without changes.");
|
|
33
|
+
const rows = new Map(snapshot.processes.map(row => [row.pid, row]));
|
|
34
|
+
if (rows.size === 0 || rows.size !== snapshot.processes.length || !rows.has(1) ||
|
|
35
|
+
snapshot.processes.some(row => !Number.isSafeInteger(row.pid) || row.pid <= 0 || !identity(row.uniqueId)) ||
|
|
36
|
+
new Set(snapshot.processes.map(row => row.uniqueId)).size !== rows.size)
|
|
37
|
+
return refuse("The process census has missing or ambiguous kernel identities.");
|
|
38
|
+
const anchorsValid = (anchors) => Array.isArray(anchors) &&
|
|
39
|
+
anchors.every(anchor => Number.isSafeInteger(anchor.pid) && anchor.pid > 0 && identity(anchor.uniqueId)) &&
|
|
40
|
+
new Set(anchors.map(anchor => anchor.pid)).size === anchors.length &&
|
|
41
|
+
new Set(anchors.map(anchor => anchor.uniqueId)).size === anchors.length;
|
|
42
|
+
if (!anchorsValid(args.preRunIdentities) || !anchorsValid(args.trustedExternalManagedServiceIdentities))
|
|
43
|
+
return refuse("The authenticated external process identities are malformed or ambiguous.");
|
|
44
|
+
const preRun = new Map(args.preRunIdentities.map(anchor => [anchor.pid, anchor.uniqueId]));
|
|
45
|
+
const trustedManaged = new Map(args.trustedExternalManagedServiceIdentities.map(anchor => [anchor.pid, anchor.uniqueId]));
|
|
46
|
+
const probes = new Set(snapshot.collectorPids);
|
|
47
|
+
if ([...probes].some(pid => !Number.isSafeInteger(pid) || pid <= 1))
|
|
48
|
+
return refuse("The owned diagnostic process inventory is malformed.");
|
|
49
|
+
const managed = new Set(snapshot.managedServices.filter(service => {
|
|
50
|
+
const row = rows.get(service.pid);
|
|
51
|
+
return service.identityBound && identity(service.uniqueId) && row?.uniqueId === service.uniqueId &&
|
|
52
|
+
trustedManaged.get(service.pid) === service.uniqueId &&
|
|
53
|
+
service.beforeUniqueId === service.uniqueId && service.afterUniqueId === service.uniqueId &&
|
|
54
|
+
/^(system|gui\/[0-9]+|user\/[0-9]+|pid\/[0-9]+)$/.test(service.domain) && service.label.length > 0;
|
|
55
|
+
}).map(service => service.pid));
|
|
56
|
+
const external = new Map();
|
|
57
|
+
const visiting = new Set();
|
|
58
|
+
const visit = (pid) => {
|
|
59
|
+
if (external.has(pid))
|
|
60
|
+
return true;
|
|
61
|
+
if (visiting.has(pid))
|
|
62
|
+
return false;
|
|
63
|
+
const row = rows.get(pid);
|
|
64
|
+
if (!row || row.traced !== false)
|
|
65
|
+
return false;
|
|
66
|
+
const accept = (basis, anchor = pid) => { external.set(pid, { pid, basis, anchor }); return true; };
|
|
67
|
+
if (probes.has(pid))
|
|
68
|
+
return accept("owned-probe");
|
|
69
|
+
if (preRun.get(pid) === row.uniqueId)
|
|
70
|
+
return accept("predates-run");
|
|
71
|
+
if (managed.has(pid))
|
|
72
|
+
return accept("managed-service");
|
|
73
|
+
// An orphan may exec and acquire launchd's parentUniqueId. Even a launchd
|
|
74
|
+
// service record needs independent caller provenance; there is no PID1
|
|
75
|
+
// ancestry shortcut. Wall birth times cannot establish age after a
|
|
76
|
+
// clock adjustment. Kernel fork identities must increase along each edge,
|
|
77
|
+
// also refusing reparenting to a later process after historical tracing.
|
|
78
|
+
if (row.ppid === null || row.ppid <= 1 || row.ppid === pid || !identity(row.parentUniqueId))
|
|
79
|
+
return false;
|
|
80
|
+
const parent = rows.get(row.ppid);
|
|
81
|
+
if (!parent || parent.uniqueId !== row.parentUniqueId || BigInt(parent.uniqueId) >= BigInt(row.uniqueId))
|
|
82
|
+
return false;
|
|
83
|
+
visiting.add(pid);
|
|
84
|
+
const gone = visit(parent.pid);
|
|
85
|
+
visiting.delete(pid);
|
|
86
|
+
return gone ? accept("ancestry", external.get(parent.pid).anchor) : false;
|
|
87
|
+
};
|
|
88
|
+
const unresolved = snapshot.processes.filter(row => !visit(row.pid)).map(row => row.pid).sort((a, b) => a - b);
|
|
89
|
+
return unresolved.length ? { ok: false, problems: ["Some current processes cannot be distinguished from unobserved descendants."], unresolved }
|
|
90
|
+
: { ok: true, observedAt: snapshot.finishedAt, external: [...external.values()].sort((a, b) => a.pid - b.pid) };
|
|
91
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export type ObservedProcess = {
|
|
3
|
+
pid: number;
|
|
4
|
+
group: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type ProcessObservationFailure = {
|
|
7
|
+
phase: "sample" | "periodic" | "final-exit" | "stop" | "supervisor";
|
|
8
|
+
operation: "snapshot" | "descendant-write" | "exit-write" | "signal" | "diagnostic-read";
|
|
9
|
+
code: string;
|
|
10
|
+
rootPid: number | null;
|
|
11
|
+
at: string;
|
|
12
|
+
identityUnknown: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type ProcessTreeObserver = {
|
|
15
|
+
onDescendant?: (pid: number, group: boolean) => void;
|
|
16
|
+
/** A dedicated durable fallback for the exact identities already observed.
|
|
17
|
+
* Return true only after preserving every row. Never replay arbitrary callbacks. */
|
|
18
|
+
onDescendantWriteFailure?: (rows: readonly ObservedProcess[]) => boolean;
|
|
19
|
+
/** An observed PID (and its group, when recorded) is now proven absent.
|
|
20
|
+
* This never follows merely from reparenting or the root's exit. */
|
|
21
|
+
onDescendantExit?: (pid: number, group: boolean) => void;
|
|
22
|
+
/** Diagnostics never establish exit or erase a custody witness. */
|
|
23
|
+
onObservationFailure?: (failure: ProcessObservationFailure) => void;
|
|
24
|
+
onUnknown?: () => void;
|
|
25
|
+
};
|
|
26
|
+
/** Private supervisor pipe input. Keep only validated identifier diagnostics. */
|
|
27
|
+
export declare function readProcessObservationFailure(value: unknown): ProcessObservationFailure | null;
|
|
28
|
+
/** Capture current descendants before asking an owned process to exit.
|
|
29
|
+
* A cooperative root may exit before the next periodic observation; even
|
|
30
|
+
* a killed tool can retain its PID briefly after its process group is gone. */
|
|
31
|
+
export declare function sampleProcessTree(child: ChildProcess): void;
|
|
32
|
+
/** Observe escaped process groups while their ancestry is still provable.
|
|
33
|
+
* Durable witnesses prevent recovery from mistaking a dead harness for a dead
|
|
34
|
+
* shell. They never grant permission to send a signal after worker recovery. */
|
|
35
|
+
export declare function observeProcessTree(child: ChildProcess, observer: ProcessTreeObserver): void;
|
|
36
|
+
/** Freeze the owned handle, then its live descendants before killing them.
|
|
37
|
+
* Claude's tool shells create new process groups, so killing only -rootPid
|
|
38
|
+
* leaves writers behind. Re-scan after freezing parents to catch a child born
|
|
39
|
+
* during the previous scan. Every target comes from current ancestry of the
|
|
40
|
+
* still-owned handle, never from a saved PID. Unknown ancestry stays blocked. */
|
|
41
|
+
export declare function stopProcessTree(child: ChildProcess): boolean;
|