firedrill-run 2.2.5 → 3.0.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.
Files changed (392) hide show
  1. package/README.md +178 -22
  2. package/bin/firedrill.mjs +29 -5
  3. package/dist/assembly.json +13 -0
  4. package/dist/cli/runtime/candidate_copy.py +395 -0
  5. package/dist/cli/runtime/source_snapshot.py +391 -0
  6. package/dist/cli/src/administration.js +295 -0
  7. package/dist/cli/src/agent-changes.js +496 -0
  8. package/dist/cli/src/assessment-requests.js +67 -0
  9. package/dist/cli/src/auth.js +465 -0
  10. package/dist/cli/src/billing-commerce-contracts.js +1 -0
  11. package/dist/cli/src/billing-usage.js +227 -0
  12. package/dist/cli/src/billing-wallet-contracts.js +1 -0
  13. package/dist/cli/src/billing.js +170 -0
  14. package/dist/cli/src/bootstrap-process-lock.js +136 -0
  15. package/dist/cli/src/browser-links.js +14 -0
  16. package/dist/cli/src/campaign-controls.js +122 -0
  17. package/dist/cli/src/campaign-diagnoses.js +118 -0
  18. package/dist/cli/src/campaign-reports.js +1215 -0
  19. package/dist/cli/src/campaign-world.js +156 -0
  20. package/dist/cli/src/candidate-copy.js +376 -0
  21. package/dist/cli/src/catalog-contracts.js +1 -0
  22. package/dist/cli/src/ci-access-contracts.js +1 -0
  23. package/dist/cli/src/ci-configuration-contracts.js +1 -0
  24. package/dist/cli/src/ci-coverage.js +64 -0
  25. package/dist/cli/src/ci-delivery-contracts.js +1 -0
  26. package/dist/cli/src/ci-result-contracts.js +1 -0
  27. package/dist/cli/src/ci-run-contracts.js +1 -0
  28. package/dist/cli/src/ci-setup-proposals.js +52 -0
  29. package/dist/cli/src/company-policies.js +229 -0
  30. package/dist/cli/src/completion.js +79 -0
  31. package/dist/cli/src/configuration-intents.js +277 -0
  32. package/dist/cli/src/configuration.js +369 -0
  33. package/dist/cli/src/continuous-simulation.js +277 -0
  34. package/dist/cli/src/coordinated-checkpoints.js +133 -0
  35. package/dist/cli/src/credential-mode.js +139 -0
  36. package/dist/cli/src/credentials.js +331 -0
  37. package/dist/cli/src/credit-format.js +8 -0
  38. package/dist/cli/src/dataset-contracts.js +1 -0
  39. package/dist/cli/src/dataset-export.js +154 -0
  40. package/dist/cli/src/dataset-reads.js +37 -0
  41. package/dist/cli/src/dependency-preparation.js +239 -0
  42. package/dist/cli/src/director-tool-setup.js +104 -0
  43. package/dist/cli/src/driver-review.js +225 -0
  44. package/dist/cli/src/evaluation-authoring.js +315 -0
  45. package/dist/cli/src/evidence-bundles.js +367 -0
  46. package/dist/cli/src/execution-proposals.js +36 -0
  47. package/dist/cli/src/http.js +302 -0
  48. package/dist/cli/src/local-container-boundary.js +38 -0
  49. package/dist/cli/src/local-container-policy.js +201 -0
  50. package/dist/cli/src/local-execution-setup.js +81 -0
  51. package/dist/cli/src/local-source-basis.js +73 -0
  52. package/dist/cli/src/local-source.js +66 -0
  53. package/dist/cli/src/local-value-store.js +91 -0
  54. package/dist/cli/src/local-values.js +163 -0
  55. package/dist/cli/src/login-organizations.js +70 -0
  56. package/dist/cli/src/main.js +1622 -0
  57. package/dist/cli/src/mcp-connection.js +109 -0
  58. package/dist/cli/src/native/bindings.js +137 -0
  59. package/dist/cli/src/native/canonical.js +370 -0
  60. package/dist/cli/src/native/cloud-resources.js +942 -0
  61. package/dist/cli/src/native/companion-channel.js +421 -0
  62. package/dist/cli/src/native/companion-ipc.js +473 -0
  63. package/dist/cli/src/native/contracts.js +218 -0
  64. package/dist/cli/src/native/control-plane.js +1354 -0
  65. package/dist/cli/src/native/credit-approval.js +15 -0
  66. package/dist/cli/src/native/dependency-proxy.js +1006 -0
  67. package/dist/cli/src/native/drill-cleanup.js +115 -0
  68. package/dist/cli/src/native/drill-runner.js +1562 -0
  69. package/dist/cli/src/native/drivers/action-trace.js +210 -0
  70. package/dist/cli/src/native/drivers/function-wrapper.js +152 -0
  71. package/dist/cli/src/native/drivers/http.js +442 -0
  72. package/dist/cli/src/native/drivers/index.js +47 -0
  73. package/dist/cli/src/native/drivers/jsonl-process.js +538 -0
  74. package/dist/cli/src/native/drivers/playwright.js +600 -0
  75. package/dist/cli/src/native/drivers/signed-event.js +244 -0
  76. package/dist/cli/src/native/drivers/types.js +578 -0
  77. package/dist/cli/src/native/evidence-filter.js +255 -0
  78. package/dist/cli/src/native/isolated-access.js +241 -0
  79. package/dist/cli/src/native/library-sharing.js +220 -0
  80. package/dist/cli/src/native/local-run.js +667 -0
  81. package/dist/cli/src/native/local-secrets.js +19 -0
  82. package/dist/cli/src/native/mcp-config.js +123 -0
  83. package/dist/cli/src/native/metadata-requests.js +120 -0
  84. package/dist/cli/src/native/observations.js +1159 -0
  85. package/dist/cli/src/native/owned-groups.js +46 -0
  86. package/dist/cli/src/native/plan.js +594 -0
  87. package/dist/cli/src/native/png.js +159 -0
  88. package/dist/cli/src/native/ports.js +43 -0
  89. package/dist/cli/src/native/readiness.js +139 -0
  90. package/dist/cli/src/native/reassessments.js +206 -0
  91. package/dist/cli/src/native/redaction.js +235 -0
  92. package/dist/cli/src/native/registration.js +155 -0
  93. package/dist/cli/src/native/roots.js +110 -0
  94. package/dist/cli/src/native/run-cleanup.js +199 -0
  95. package/dist/cli/src/native/scratch.js +117 -0
  96. package/dist/cli/src/native/screenshots.js +60 -0
  97. package/dist/cli/src/native/session.js +556 -0
  98. package/dist/cli/src/native/standalone-proxy.js +580 -0
  99. package/dist/cli/src/native/standalone-renewals.js +183 -0
  100. package/dist/cli/src/native/standalone-state.js +193 -0
  101. package/dist/cli/src/native/standalone-tools.js +187 -0
  102. package/dist/cli/src/native/supervisor.js +831 -0
  103. package/dist/cli/src/native/target-auth.js +161 -0
  104. package/dist/cli/src/native/target-state.js +330 -0
  105. package/dist/cli/src/native/tool-reuse.js +364 -0
  106. package/dist/cli/src/native/tool-setups.js +336 -0
  107. package/dist/cli/src/native/world-reuse.js +288 -0
  108. package/dist/cli/src/onboarding.js +23 -0
  109. package/dist/cli/src/priority-requests.js +70 -0
  110. package/dist/cli/src/priority.js +223 -0
  111. package/dist/cli/src/prompts.js +184 -0
  112. package/dist/cli/src/real-operations.js +221 -0
  113. package/dist/cli/src/recipe-intents.js +58 -0
  114. package/dist/cli/src/recorded-context-intents.js +59 -0
  115. package/dist/cli/src/recorded-context.js +248 -0
  116. package/dist/cli/src/recordings.js +69 -0
  117. package/dist/cli/src/registration-guide.js +39 -0
  118. package/dist/cli/src/report-exports.js +213 -0
  119. package/dist/cli/src/request-input.js +47 -0
  120. package/dist/cli/src/resource-lifecycle.js +141 -0
  121. package/dist/cli/src/revision-requests.js +55 -0
  122. package/dist/cli/src/runner-abandon.js +53 -0
  123. package/dist/cli/src/runner-campaign-controls.js +262 -0
  124. package/dist/cli/src/runner-claim-reads.js +36 -0
  125. package/dist/cli/src/runner-completion.js +65 -0
  126. package/dist/cli/src/runner-configuration.js +546 -0
  127. package/dist/cli/src/runner-container.js +794 -0
  128. package/dist/cli/src/runner-evidence-erasure.js +351 -0
  129. package/dist/cli/src/runner-evidence-privacy.js +37 -0
  130. package/dist/cli/src/runner-evidence-retention.js +161 -0
  131. package/dist/cli/src/runner-evidence.js +326 -0
  132. package/dist/cli/src/runner-execute.js +92 -0
  133. package/dist/cli/src/runner-execution-deadline.js +25 -0
  134. package/dist/cli/src/runner-grants.js +307 -0
  135. package/dist/cli/src/runner-identity.js +615 -0
  136. package/dist/cli/src/runner-inputs.js +308 -0
  137. package/dist/cli/src/runner-jobs.js +49 -0
  138. package/dist/cli/src/runner-model-transport.js +392 -0
  139. package/dist/cli/src/runner-ownership.js +332 -0
  140. package/dist/cli/src/runner-process-lock.js +175 -0
  141. package/dist/cli/src/runner-runtime.js +396 -0
  142. package/dist/cli/src/runner-session-channel.js +377 -0
  143. package/dist/cli/src/runner-trial-completion.js +34 -0
  144. package/dist/cli/src/runner-trial-journal.js +358 -0
  145. package/dist/cli/src/runner-trial-live.js +393 -0
  146. package/dist/cli/src/runner-trial-protocol.js +289 -0
  147. package/dist/cli/src/runner-trial-sync.js +110 -0
  148. package/dist/cli/src/runner-trial-transfer.js +107 -0
  149. package/dist/cli/src/runner-voice.js +40 -0
  150. package/dist/cli/src/runner-world-claim.js +21 -0
  151. package/dist/cli/src/runner-world-collector.js +159 -0
  152. package/dist/cli/src/runner-world-command-evidence.js +487 -0
  153. package/dist/cli/src/runner-world-commands.js +268 -0
  154. package/dist/cli/src/runner-world-completion.js +76 -0
  155. package/dist/cli/src/runner-world-erasure.js +95 -0
  156. package/dist/cli/src/runner-world-evidence-sync.js +91 -0
  157. package/dist/cli/src/runner-world-journal.js +510 -0
  158. package/dist/cli/src/runner-world-native-filters.js +134 -0
  159. package/dist/cli/src/runner-world-observations.js +50 -0
  160. package/dist/cli/src/runner-world-session-protocol.js +134 -0
  161. package/dist/cli/src/saved-records.js +40 -0
  162. package/dist/cli/src/scenario-authoring.js +212 -0
  163. package/dist/cli/src/scenario-discovery.js +216 -0
  164. package/dist/cli/src/scenario-paths.js +68 -0
  165. package/dist/cli/src/scenario-requests.js +4 -0
  166. package/dist/cli/src/service-receipts.js +105 -0
  167. package/dist/cli/src/simple/authoring.js +270 -0
  168. package/dist/cli/src/simple/credit-approval.js +16 -0
  169. package/dist/cli/src/simple/help.js +98 -0
  170. package/dist/cli/src/simple/init.js +61 -0
  171. package/dist/cli/src/simple/library-sharing.js +414 -0
  172. package/dist/cli/src/simple/metadata-requests.js +46 -0
  173. package/dist/cli/src/simple/native-report.js +841 -0
  174. package/dist/cli/src/simple/native-tools.js +780 -0
  175. package/dist/cli/src/simple/plan-apply.js +506 -0
  176. package/dist/cli/src/simple/reassessment.js +323 -0
  177. package/dist/cli/src/simple/register.js +123 -0
  178. package/dist/cli/src/simple/run.js +122 -0
  179. package/dist/cli/src/simple/status.js +49 -0
  180. package/dist/cli/src/simple/tool-renewal.js +308 -0
  181. package/dist/cli/src/simple/tool-reuse.js +526 -0
  182. package/dist/cli/src/simple/tool-start-catalog.js +100 -0
  183. package/dist/cli/src/simple/tool-state.js +426 -0
  184. package/dist/cli/src/simple/tools-author.js +222 -0
  185. package/dist/cli/src/simple/watch.js +28 -0
  186. package/dist/cli/src/simple/world-reuse.js +586 -0
  187. package/dist/cli/src/simulation-intents.js +406 -0
  188. package/dist/cli/src/simulation-run.js +1058 -0
  189. package/dist/cli/src/source-batch.js +322 -0
  190. package/dist/cli/src/source-connection.js +451 -0
  191. package/dist/cli/src/source-runtime.js +346 -0
  192. package/dist/cli/src/source-selection-intents.js +75 -0
  193. package/dist/cli/src/source-sets.js +214 -0
  194. package/dist/cli/src/target-models.js +109 -0
  195. package/dist/cli/src/tool-catalog.js +224 -0
  196. package/dist/cli/src/tool-command-contracts.js +1 -0
  197. package/dist/cli/src/tool-command-export.js +245 -0
  198. package/dist/cli/src/tool-connection-contracts.js +1 -0
  199. package/dist/cli/src/tool-connection-reads.js +23 -0
  200. package/dist/cli/src/tool-contributions.js +58 -0
  201. package/dist/cli/src/tool-data.js +116 -0
  202. package/dist/cli/src/tool-datasets.js +176 -0
  203. package/dist/cli/src/tool-group-contracts.js +1 -0
  204. package/dist/cli/src/tool-group-reads.js +26 -0
  205. package/dist/cli/src/tool-group-state.js +147 -0
  206. package/dist/cli/src/tool-groups.js +311 -0
  207. package/dist/cli/src/tool-instances.js +186 -0
  208. package/dist/cli/src/tool-lifecycle-contracts.js +1 -0
  209. package/dist/cli/src/tool-lifecycle-reads.js +30 -0
  210. package/dist/cli/src/tool-lifecycle.js +323 -0
  211. package/dist/cli/src/tool-package-contracts.js +1 -0
  212. package/dist/cli/src/tool-package-reads.js +41 -0
  213. package/dist/cli/src/tool-records.js +53 -0
  214. package/dist/cli/src/tool-runtime.js +96 -0
  215. package/dist/cli/src/tool-state-contracts.js +1 -0
  216. package/dist/cli/src/tool-state-reads.js +31 -0
  217. package/dist/cli/src/tools.js +306 -0
  218. package/dist/cli/src/trial-actions.js +93 -0
  219. package/dist/cli/src/trial-checkpoints.js +133 -0
  220. package/dist/cli/src/trial-checks.js +70 -0
  221. package/dist/cli/src/trial-state.js +197 -0
  222. package/dist/cli/src/vault.js +266 -0
  223. package/dist/cli/src/workspace-registration.js +383 -0
  224. package/dist/cli/src/workspace-team-contracts.js +1 -0
  225. package/dist/cli/src/world-access.js +231 -0
  226. package/dist/cli/src/world-agent.js +4 -0
  227. package/dist/cli/src/world-checkpoint-scopes.js +15 -0
  228. package/dist/cli/src/world-contracts.js +6 -0
  229. package/dist/cli/src/world-creation.js +201 -0
  230. package/dist/cli/src/world-datasets.js +207 -0
  231. package/dist/cli/src/world-inspection.js +257 -0
  232. package/dist/cli/src/world-recipes.js +103 -0
  233. package/dist/cli/src/world-requests.js +241 -0
  234. package/dist/cli/src/world-session-checkpoints.js +196 -0
  235. package/dist/cli/src/world-session-lifecycle.js +207 -0
  236. package/dist/cli/src/world-session-requests.js +215 -0
  237. package/dist/cli/src/world-session-state.js +145 -0
  238. package/dist/cli/src/world-session-voice.js +66 -0
  239. package/dist/cli/src/world-sessions.js +288 -0
  240. package/dist/cli/src/world-stream.js +99 -0
  241. package/dist/cli/src/world-time-report.js +58 -0
  242. package/dist/contracts/agent-change-contracts.js +75 -0
  243. package/dist/contracts/agent-execution-contracts.js +38 -0
  244. package/dist/contracts/application-state-contracts.js +26 -0
  245. package/dist/contracts/assessment-aggregate-contracts.js +15 -0
  246. package/dist/contracts/assessment-contracts.js +74 -0
  247. package/dist/contracts/billing-commerce-contracts.js +107 -0
  248. package/dist/contracts/billing-wallet-contracts.js +43 -0
  249. package/dist/contracts/campaign-lifecycle.js +1 -0
  250. package/dist/contracts/campaign-world-contracts.js +80 -0
  251. package/dist/contracts/catalog-contracts.js +73 -0
  252. package/dist/contracts/ci-access-contracts.js +68 -0
  253. package/dist/contracts/ci-configuration-contracts.js +88 -0
  254. package/dist/contracts/ci-coverage-contracts.js +65 -0
  255. package/dist/contracts/ci-coverage-labels.js +25 -0
  256. package/dist/contracts/ci-delivery-contracts.js +61 -0
  257. package/dist/contracts/ci-result-contracts.js +103 -0
  258. package/dist/contracts/ci-run-contracts.js +51 -0
  259. package/dist/contracts/ci-setup-contracts.js +88 -0
  260. package/dist/contracts/clip-contracts.js +32 -0
  261. package/dist/contracts/comparison-contracts.js +53 -0
  262. package/dist/contracts/composite-contracts.js +34 -0
  263. package/dist/contracts/context-contracts.js +76 -0
  264. package/dist/contracts/continuation-report-contracts.js +1 -0
  265. package/dist/contracts/continuity-requirements.js +8 -0
  266. package/dist/contracts/coordinated-checkpoint-contracts.js +34 -0
  267. package/dist/contracts/dataset-contracts.js +88 -0
  268. package/dist/contracts/dependency-decision-contracts.js +36 -0
  269. package/dist/contracts/dependency-protocol-contracts.js +43 -0
  270. package/dist/contracts/director-execution.js +51 -0
  271. package/dist/contracts/driver-review-contracts.js +99 -0
  272. package/dist/contracts/evidence-contracts.js +65 -0
  273. package/dist/contracts/evidence-coverage-contracts.js +10 -0
  274. package/dist/contracts/export-contracts.js +44 -0
  275. package/dist/contracts/github-directory-contracts.js +96 -0
  276. package/dist/contracts/insight-contracts.js +11 -0
  277. package/dist/contracts/inspection-contracts.js +1 -0
  278. package/dist/contracts/local-claim-contracts.js +39 -0
  279. package/dist/contracts/local-configuration-contracts.js +7 -0
  280. package/dist/contracts/local-evidence-contracts.js +32 -0
  281. package/dist/contracts/local-grant-contracts.js +83 -0
  282. package/dist/contracts/local-input-contracts.js +19 -0
  283. package/dist/contracts/local-runner-contracts.js +42 -0
  284. package/dist/contracts/local-trial-live-contracts.js +16 -0
  285. package/dist/contracts/local-value-source-contracts.js +92 -0
  286. package/dist/contracts/local-world-native-contracts.js +8 -0
  287. package/dist/contracts/mcp-contracts.js +42 -0
  288. package/dist/contracts/media-contracts.js +28 -0
  289. package/dist/contracts/native-check-contracts.js +31 -0
  290. package/dist/contracts/native-identity-contracts.js +52 -0
  291. package/dist/contracts/onboarding-contracts.js +32 -0
  292. package/dist/contracts/performance-contracts.js +85 -0
  293. package/dist/contracts/planning-contracts.js +81 -0
  294. package/dist/contracts/real-operation-contracts.js +30 -0
  295. package/dist/contracts/recommendation-contracts.js +54 -0
  296. package/dist/contracts/report-contracts.js +1 -0
  297. package/dist/contracts/resource-lifecycle-contracts.js +57 -0
  298. package/dist/contracts/revision-contracts.js +12 -0
  299. package/dist/contracts/revision-request-contracts.js +39 -0
  300. package/dist/contracts/saved-record-contracts.js +76 -0
  301. package/dist/contracts/scenario-draft-comparison.js +91 -0
  302. package/dist/contracts/scenario-world-contracts.js +14 -0
  303. package/dist/contracts/service-contracts.js +1 -0
  304. package/dist/contracts/session-command-contracts.js +56 -0
  305. package/dist/contracts/session-contracts.js +65 -0
  306. package/dist/contracts/session-state-contracts.js +67 -0
  307. package/dist/contracts/session-voice-contracts.js +45 -0
  308. package/dist/contracts/source-set-contracts.js +26 -0
  309. package/dist/contracts/source-upload-contracts.js +22 -0
  310. package/dist/contracts/tool-command-contracts.js +57 -0
  311. package/dist/contracts/tool-connection-contracts.js +87 -0
  312. package/dist/contracts/tool-contribution-contracts.js +35 -0
  313. package/dist/contracts/tool-group-contracts.js +53 -0
  314. package/dist/contracts/tool-group-state-contracts.js +63 -0
  315. package/dist/contracts/tool-lifecycle-contracts.js +94 -0
  316. package/dist/contracts/tool-package-contracts.js +91 -0
  317. package/dist/contracts/tool-protocol-contracts.js +71 -0
  318. package/dist/contracts/tool-runtime-billing-contracts.js +28 -0
  319. package/dist/contracts/tool-setup-proposal.js +59 -0
  320. package/dist/contracts/tool-state-contracts.js +79 -0
  321. package/dist/contracts/trial-state-contracts.js +30 -0
  322. package/dist/contracts/typescript/agent-change.js +1 -0
  323. package/dist/contracts/typescript/assessment-aggregate.js +1 -0
  324. package/dist/contracts/typescript/assessment.js +1 -0
  325. package/dist/contracts/typescript/billing-commerce.js +1 -0
  326. package/dist/contracts/typescript/campaigns.js +1 -0
  327. package/dist/contracts/typescript/catalog.js +1 -0
  328. package/dist/contracts/typescript/ci-access.js +1 -0
  329. package/dist/contracts/typescript/ci-configuration.js +1 -0
  330. package/dist/contracts/typescript/ci-delivery.js +1 -0
  331. package/dist/contracts/typescript/ci-result.js +1 -0
  332. package/dist/contracts/typescript/ci-runs.js +1 -0
  333. package/dist/contracts/typescript/clips.js +1 -0
  334. package/dist/contracts/typescript/comparison.js +1 -0
  335. package/dist/contracts/typescript/composite.js +1 -0
  336. package/dist/contracts/typescript/connections.js +1 -0
  337. package/dist/contracts/typescript/context.js +1 -0
  338. package/dist/contracts/typescript/datasets.js +1 -0
  339. package/dist/contracts/typescript/evidence-coverage.js +1 -0
  340. package/dist/contracts/typescript/export.js +1 -0
  341. package/dist/contracts/typescript/github-directory.js +1 -0
  342. package/dist/contracts/typescript/insight.js +1 -0
  343. package/dist/contracts/typescript/inspection.js +1 -0
  344. package/dist/contracts/typescript/intake.js +1 -0
  345. package/dist/contracts/typescript/local-claim.js +1 -0
  346. package/dist/contracts/typescript/local-configuration.js +1 -0
  347. package/dist/contracts/typescript/local-evidence.js +1 -0
  348. package/dist/contracts/typescript/local-grant.js +1 -0
  349. package/dist/contracts/typescript/local-input.js +1 -0
  350. package/dist/contracts/typescript/local-runner.js +1 -0
  351. package/dist/contracts/typescript/local-trial-live.js +1 -0
  352. package/dist/contracts/typescript/local-value-source.js +1 -0
  353. package/dist/contracts/typescript/local-world-native.js +1 -0
  354. package/dist/contracts/typescript/mcp.js +1 -0
  355. package/dist/contracts/typescript/media.js +1 -0
  356. package/dist/contracts/typescript/native-check.js +1 -0
  357. package/dist/contracts/typescript/native-identity.js +1 -0
  358. package/dist/contracts/typescript/onboarding.js +1 -0
  359. package/dist/contracts/typescript/performance.js +1 -0
  360. package/dist/contracts/typescript/planning.js +1 -0
  361. package/dist/contracts/typescript/preparation.js +1 -0
  362. package/dist/contracts/typescript/real-operation.js +1 -0
  363. package/dist/contracts/typescript/recommendation.js +1 -0
  364. package/dist/contracts/typescript/reports.js +1 -0
  365. package/dist/contracts/typescript/resource-lifecycle.js +1 -0
  366. package/dist/contracts/typescript/saved-record.js +1 -0
  367. package/dist/contracts/typescript/scenarios.js +1 -0
  368. package/dist/contracts/typescript/services.js +1 -0
  369. package/dist/contracts/typescript/session-command.js +1 -0
  370. package/dist/contracts/typescript/session-state.js +1 -0
  371. package/dist/contracts/typescript/session-voice.js +1 -0
  372. package/dist/contracts/typescript/session.js +1 -0
  373. package/dist/contracts/typescript/tool-command.js +1 -0
  374. package/dist/contracts/typescript/tool-connection.js +1 -0
  375. package/dist/contracts/typescript/tool-contribution.js +1 -0
  376. package/dist/contracts/typescript/tool-groups.js +1 -0
  377. package/dist/contracts/typescript/tool-lifecycle.js +1 -0
  378. package/dist/contracts/typescript/tool-package.js +1 -0
  379. package/dist/contracts/typescript/tool-state.js +1 -0
  380. package/dist/contracts/typescript/trial-state.js +1 -0
  381. package/dist/contracts/typescript/vault.js +1 -0
  382. package/dist/contracts/typescript/workspace-team.js +1 -0
  383. package/dist/contracts/typescript/world-stream.js +1 -0
  384. package/dist/contracts/workspace-team-contracts.js +55 -0
  385. package/dist/contracts/world-command.js +65 -0
  386. package/dist/contracts/world-lifetime-contracts.js +74 -0
  387. package/dist/contracts/world-recipe-contracts.js +27 -0
  388. package/dist/contracts/world-stream-contracts.js +27 -0
  389. package/dist/package.json +1 -0
  390. package/package.json +16 -16
  391. package/LICENSE.md +0 -23
  392. package/PACKAGING.json +0 -50
@@ -0,0 +1,295 @@
1
+ import { APP_ORIGIN } from './http.js';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { open } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { api, openBrowser } from './auth.js';
6
+ import { privateDirectory } from './credentials.js';
7
+ import { auth, choosePaged, interactive, line, query } from './configuration.js';
8
+ import { readMetadata, record } from './configuration-intents.js';
9
+ import { CliError } from './http.js';
10
+ import { selectMany, selectOne, terminalText } from './prompts.js';
11
+ import { selectedWorkspace } from './world-access.js';
12
+ import { identifier } from './world-contracts.js';
13
+ import { workspaceTeamRead, workspaceSettingsMatch, workspaceTeamMatch, workspaceInvitationsMatch, workspaceMemberDetailMatch, workspaceMemberChangeMatch, workspaceInvitationMatch, workspaceInvitationRequestMatch } from './workspace-team-contracts.js';
14
+ const roles = ['owner', 'admin', 'member', 'viewer'];
15
+ const email = (value) => typeof value === 'string' && value.length <= 254 && /^[^\s@]+@[^\s@]+$/.test(value);
16
+ const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
17
+ const invalid = () => new CliError('administration_input_invalid', 'Use the exact workspace, invitation or teammate details. No replacement request was submitted.', 2);
18
+ const inviteStates = { pending: 'Queued', sending: 'Sending', sent: 'Sent', uncertain: 'Delivery not confirmed',
19
+ revoked: 'Revoked', withdrawn: 'Request discarded', revoking: 'Revocation requested', revocation_uncertain: 'Revocation not confirmed',
20
+ accepted: 'Accepted', expired: 'Expired' };
21
+ const inviteState = (value) => inviteStates[value] ?? 'Status unavailable';
22
+ const invitationRecoveryHint = (state, workspace) => ['uncertain', 'revocation_uncertain'].includes(state)
23
+ ? `An organization owner can resolve the original invitation in team settings. No replacement email is sent.\nOpen: firedrill team open --workspace ${workspace}` : '';
24
+ function settingsData(value, scope) {
25
+ if (!workspaceSettingsMatch(value, scope.workspace, scope.owner))
26
+ throw invalid();
27
+ return value;
28
+ }
29
+ async function approve(options, title) {
30
+ if (options.approve)
31
+ return;
32
+ if (!interactive(options))
33
+ throw new CliError('approval_required', 'Review this change and pass --approve-change for automation. Nothing was submitted.', 2);
34
+ if (!await selectOne(title, [{ value: false, label: 'Cancel' }, { value: true, label: 'Confirm change' }], options.signal))
35
+ throw new CliError('canceled', 'No change was submitted.', 130);
36
+ }
37
+ async function settingsLink(scope, section, options, output) {
38
+ if (!['workspace', 'team', 'billing', 'account', 'operations'].includes(section))
39
+ throw invalid();
40
+ // Financial administration is browser-owned. Its route performs fresh
41
+ // operator authorization; a native bearer preflight is deliberately forbidden.
42
+ const url = new URL(`/settings/${section}`, APP_ORIGIN);
43
+ url.searchParams.set('workspace', scope.workspace);
44
+ output({ browser_url: url.href, workspace_id: scope.workspace }, `Open ${url.href}`);
45
+ if (interactive(options) && options.openBrowser)
46
+ await openBrowser(url.href);
47
+ }
48
+ export async function settingsCommand(args, options, output) {
49
+ if (args.length > 2 || options.request !== undefined || options.page !== undefined || options.search !== undefined
50
+ || args[0] !== 'update' && (options.file !== undefined || options.approve))
51
+ throw new CliError('arguments_invalid', 'Use settings show, update [--file <settings.json>] or open [workspace|team|billing|account|operations].', 2);
52
+ const scope = await selectedWorkspace({ ...options, interactive: interactive(options) });
53
+ const action = args[0] ?? (interactive(options) ? await selectOne('Settings', [
54
+ { value: 'show', label: 'View workspace settings' }, { value: 'update', label: 'Change workspace settings' },
55
+ { value: 'open', label: 'Open account and settings in the browser' }
56
+ ], options.signal) : 'show');
57
+ if (action === 'open') {
58
+ const section = args[1] ?? (interactive(options) ? await selectOne('Settings page', [
59
+ { value: 'workspace', label: 'Workspace and privacy' }, { value: 'team', label: 'Team and invitations' },
60
+ { value: 'billing', label: 'Billing' }, { value: 'account', label: 'Account, terminal access and preferences' }
61
+ ], options.signal) : 'workspace');
62
+ await settingsLink(scope, section, options, output);
63
+ return;
64
+ }
65
+ if (!['show', 'update'].includes(action) || args[1])
66
+ throw invalid();
67
+ const path = `/api/workspaces/${scope.workspace}/settings`, current = settingsData(await api(path, auth(scope, options)), scope);
68
+ if (action === 'show') {
69
+ output(current, [current.name, current.description, ...(current.simulation_context ? [`Simulation context:\n${current.simulation_context}`] : []), `Evidence retention: ${current.retention_days} days`,
70
+ `Mask browser form values in new plans: ${current.mask_sensitive_data ? 'Yes' : 'No'}`, current.can_manage ? 'Workspace administrator access' : 'Read-only settings'].filter(Boolean).map(terminalText).join('\n'));
71
+ return;
72
+ }
73
+ if (!current.can_manage)
74
+ throw new CliError('workspace_permission_required', 'A workspace administrator can change these settings.', 2);
75
+ let body;
76
+ if (options.file !== undefined) {
77
+ if (!options.file)
78
+ throw invalid();
79
+ body = await readMetadata(options.file);
80
+ }
81
+ else {
82
+ if (!interactive(options))
83
+ throw new CliError('file_required', 'Pass --file <settings.json> with name, description, simulation_context, retention_days or mask_sensitive_data and --approve-change.', 2);
84
+ const selected = await selectMany('Settings to change', [{ value: 'name', label: 'Workspace name' }, { value: 'description', label: 'Description' },
85
+ { value: 'simulation_context', label: 'Shared simulation background' },
86
+ { value: 'retention_days', label: 'Evidence retention' }, { value: 'mask_sensitive_data', label: 'Browser form-value masking' }], options.signal);
87
+ body = {};
88
+ if (selected.includes('name'))
89
+ body.name = await line('Workspace name', 120, options.signal);
90
+ if (selected.includes('description'))
91
+ body.description = await line('Description (blank clears it)', 2000, options.signal);
92
+ if (selected.includes('simulation_context'))
93
+ body.simulation_context = await line('Simulation background, not credentials, permissions or scoring rules (blank clears it)', 8000, options.signal);
94
+ if (selected.includes('retention_days')) {
95
+ body.retention_days = await selectOne('Retain evidence for', current.retention_options.map(value => ({ value, label: `${value} days` })), options.signal);
96
+ }
97
+ if (selected.includes('mask_sensitive_data'))
98
+ body.mask_sensitive_data = await selectOne('Browser form values in new simulation plans', [
99
+ { value: true, label: 'Mask form values', detail: 'Saved plans keep their policy. Other visible text may still appear.' },
100
+ { value: false, label: 'Allow visible form values', detail: 'Passwords, marked-private fields and embedded content stay masked.' }
101
+ ], options.signal);
102
+ }
103
+ if (!Object.keys(body).length || Object.keys(body).some(key => !['name', 'description', 'simulation_context', 'retention_days', 'mask_sensitive_data'].includes(key))
104
+ || body.name !== undefined && (typeof body.name !== 'string' || !body.name.trim() || body.name.length > 120)
105
+ || body.description !== undefined && (typeof body.description !== 'string' || body.description.length > 2000)
106
+ || body.simulation_context !== undefined && (typeof body.simulation_context !== 'string' || body.simulation_context.length > 8000)
107
+ || body.retention_days !== undefined && (!Number.isSafeInteger(body.retention_days) || !current.retention_options.includes(Number(body.retention_days)))
108
+ || body.mask_sensitive_data !== undefined && typeof body.mask_sensitive_data !== 'boolean')
109
+ throw invalid();
110
+ if (interactive(options))
111
+ process.stderr.write(JSON.stringify({ ...body,
112
+ ...(body.simulation_context !== undefined ? { simulation_context: `Provided simulation background (${String(body.simulation_context).length} characters; blank clears it)` } : {}) }, null, 2).split('\n').map(terminalText).join('\n') + '\n');
113
+ await approve(options, typeof body.retention_days === 'number' && body.retention_days < current.retention_days
114
+ ? 'Save shorter retention? Expired evidence may be permanently removed.' : 'Save these reviewed settings?');
115
+ const value = settingsData(await api(path, { ...auth(scope, options), method: 'PATCH', body: { ...body,
116
+ ...(body.simulation_context !== undefined ? { simulation_context_revision: current.simulation_context_revision } : {}) } }), scope);
117
+ if (Object.entries(body).some(([name, selected]) => value[name] !== (name === 'name' ? String(selected).trim() : selected)))
118
+ throw new CliError('settings_change_unconfirmed', 'The returned settings differ from this request. Read settings before retrying.');
119
+ const readback = settingsData(await api(path, auth(scope, options)), scope);
120
+ if (Object.entries(body).some(([name, selected]) => readback[name] !== (name === 'name' ? String(selected).trim() : selected)))
121
+ throw new CliError('settings_change_unconfirmed', 'Saved settings changed before readback. Read the current settings before retrying.');
122
+ output(readback, 'Workspace settings saved.');
123
+ }
124
+ const invitePath = async (scope, key) => join(await privateDirectory(), `invitation-${identifier(scope.owner)}-${identifier(scope.workspace)}-${identifier(key)}.json`);
125
+ async function retainedInvite(scope, key) {
126
+ const value = await readMetadata(await invitePath(scope, key), true);
127
+ if (Object.keys(value).sort().join(',') !== 'actor,email,key,role,schema,workspace' || value.schema !== 'firedrill.invitation-intent.v1'
128
+ || value.actor !== scope.owner || value.workspace !== scope.workspace || value.key !== identifier(key)
129
+ || typeof value.email !== 'string' || !email(value.email) || value.email !== value.email.trim().toLowerCase()
130
+ || typeof value.role !== 'string' || !['admin', 'member', 'viewer'].includes(value.role))
131
+ throw invalid();
132
+ return value;
133
+ }
134
+ async function rememberInvite(value, scope) {
135
+ try {
136
+ const file = await open(await invitePath(scope, value.key), 'wx', 0o600);
137
+ try {
138
+ await file.writeFile(JSON.stringify(value));
139
+ await file.sync();
140
+ }
141
+ finally {
142
+ await file.close();
143
+ }
144
+ }
145
+ catch (problem) {
146
+ if (!record(problem) || problem.code !== 'EEXIST')
147
+ throw problem;
148
+ const previous = await retainedInvite(scope, value.key);
149
+ if (previous.email !== value.email || previous.role !== value.role)
150
+ throw invalid();
151
+ }
152
+ }
153
+ function receipt(value, scope, key) {
154
+ if (!workspaceInvitationRequestMatch(value, scope.workspace, scope.owner, key))
155
+ throw invalid();
156
+ return value;
157
+ }
158
+ function showReceipt(value, output) {
159
+ output(value, [value.request_key, value.state === 'not_received' ? 'Not confirmed. The original request may still arrive.'
160
+ : value.state === 'withdrawn' ? 'Unsent invitation discarded. This key cannot send an invitation.'
161
+ : `${value.invitation.email} · ${value.invitation.role} · ${inviteState(value.invitation.state)}`,
162
+ ...(value.invitation ? [invitationRecoveryHint(value.invitation.state, value.workspace_id)] : [])].filter(Boolean).map(terminalText).join('\n'));
163
+ }
164
+ async function submitInvite(value, scope, options, output) {
165
+ const prefix = `/api/workspaces/${scope.workspace}/invitations`;
166
+ const original = receipt(await api(`${prefix}/requests/${value.key}`, auth(scope, options)), scope, value.key);
167
+ if (original.invitation && (original.invitation.email !== value.email || original.invitation.role !== value.role))
168
+ throw invalid();
169
+ if (original.state !== 'not_received') {
170
+ showReceipt(original, output);
171
+ return;
172
+ }
173
+ output({ phase: 'request_prepared', request_key: value.key, workspace_id: scope.workspace }, `Request: ${value.key}\nRecovery: firedrill team request ${value.key} --workspace ${scope.workspace}\nContinue: firedrill team resume ${value.key} --workspace ${scope.workspace} --approve-change`);
174
+ const saved = await api(prefix, { ...auth(scope, options), method: 'POST', idempotencyKey: value.key,
175
+ body: { email: value.email, role: value.role } });
176
+ if (!workspaceInvitationMatch(saved, scope.workspace, { actor: scope.owner, key: value.key, email: value.email, role: value.role }))
177
+ throw invalid();
178
+ const readback = receipt(await api(`${prefix}/requests/${value.key}`, auth(scope, options)), scope, value.key);
179
+ if (!workspaceInvitationRequestMatch(readback, scope.workspace, scope.owner, value.key, { id: saved.id, email: value.email, role: value.role }))
180
+ throw invalid();
181
+ showReceipt(readback, output);
182
+ }
183
+ export async function teamCommand(args, options, output) {
184
+ const isInteractive = interactive(options);
185
+ let action = args[0] ?? (isInteractive ? '' : 'list');
186
+ if (options.file !== undefined)
187
+ throw new CliError('arguments_invalid', 'Team commands take an email, role or saved ID, not a file.', 2);
188
+ const scope = await selectedWorkspace({ ...options, interactive: isInteractive });
189
+ if (!action)
190
+ action = await selectOne('Team', [{ value: 'list', label: 'View teammates' }, { value: 'invite', label: 'Invite a teammate' },
191
+ { value: 'invitations', label: 'View invitation history' }, { value: 'role', label: 'Change a role' }, { value: 'remove', label: 'Remove a teammate' },
192
+ { value: 'open', label: 'Open team settings in the browser' }], options.signal);
193
+ if (!['list', 'show', 'invite', 'invitations', 'request', 'resume', 'withdraw', 'revoke', 'role', 'remove', 'open'].includes(action)
194
+ || options.request !== undefined && action !== 'invite' || (options.page !== undefined || options.search !== undefined) && !['list', 'invitations'].includes(action)
195
+ || options.approve && !['invite', 'resume', 'withdraw', 'revoke', 'role', 'remove'].includes(action)
196
+ || args.length > (action === 'invite' || action === 'role' ? 3 : ['list', 'invitations', 'open'].includes(action) ? 1 : 2))
197
+ throw invalid();
198
+ const base = `/api/workspaces/${scope.workspace}`, access = auth(scope, options);
199
+ if (action === 'open') {
200
+ await settingsLink(scope, 'team', options, output);
201
+ return;
202
+ }
203
+ if (action === 'list' || action === 'invitations') {
204
+ const value = action === 'list' ? await api(`${base}/team?${query(options)}`, access)
205
+ : await api(`${base}/invitations?${query(options)}`, access);
206
+ workspaceTeamRead(value, 'can_manage' in value ? workspaceTeamMatch(value, scope.workspace, scope.owner, options.search ?? '', Number(options.page ?? 1))
207
+ : workspaceInvitationsMatch(value, scope.workspace, scope.owner, options.search ?? '', Number(options.page ?? 1)));
208
+ output(value, [...value.results.map(row => 'request_key' in row ? `${row.email} · ${row.role} · ${inviteState(row.state)}\n${row.id}\nRequest: ${row.request_key}`
209
+ : `${row.name || row.email} · ${row.email} · ${row.role}${row.is_self ? ' (you)' : ''}\n${row.id}`),
210
+ ...(!value.count ? ['No matching entries.'] : []), `Page ${value.page}; ${value.count.toLocaleString()} entries.`,
211
+ ...(value.results.some(row => 'request_key' in row && ['uncertain', 'revocation_uncertain'].includes(row.state))
212
+ ? [invitationRecoveryHint('uncertain', scope.workspace)] : []),
213
+ ...(value.next ? [`Continue: firedrill team ${action} --workspace ${scope.workspace} --page ${value.page + 1}${options.search ? ' --search ' + quote(options.search) : ''}${options.json ? ' --json' : ''}`] : [])].map(terminalText).join('\n\n'));
214
+ return;
215
+ }
216
+ if (['request', 'resume', 'withdraw'].includes(action)) {
217
+ const key = identifier(args[1] ?? '');
218
+ const path = `${base}/invitations/requests/${key}`, original = receipt(await api(path, access), scope, key);
219
+ if (action === 'request' || action === 'resume' && original.state !== 'not_received') {
220
+ showReceipt(original, output);
221
+ return;
222
+ }
223
+ const value = action === 'resume' || original.invitation === null ? await retainedInvite(scope, key) : null;
224
+ await approve(options, action === 'resume' ? 'Continue this exact original invitation request?' : 'Discard the unsent original request? An invitation already dispatched will not be canceled.');
225
+ if (action === 'resume')
226
+ await submitInvite(value, scope, options, output);
227
+ else
228
+ showReceipt(receipt(await api(path, { ...access, method: 'DELETE', body: {
229
+ email: value?.email ?? original.invitation.email, role: value?.role ?? original.invitation.role
230
+ } }), scope, key), output);
231
+ return;
232
+ }
233
+ if (action === 'invite') {
234
+ const team = await api(`${base}/team?page=1`, access);
235
+ workspaceTeamRead(team, workspaceTeamMatch(team, scope.workspace, scope.owner));
236
+ if (!team.can_manage)
237
+ throw new CliError('workspace_permission_required', 'A workspace administrator can invite teammates.', 2);
238
+ const recipient = (args[1] ?? (isInteractive ? await line('Email', 254, options.signal) : '')).trim().toLowerCase();
239
+ if (!email(recipient))
240
+ throw new CliError('email_required', 'Pass a valid invitation email, or run team invite in an interactive terminal.', 2);
241
+ const available = team.actor_role === 15 ? ['member', 'viewer', 'admin'] : ['member', 'viewer'];
242
+ const role = args[2] ?? (isInteractive ? await selectOne('Role', available.map(value => ({ value, label: value })), options.signal) : 'member');
243
+ if (!available.includes(role))
244
+ throw invalid();
245
+ const value = { schema: 'firedrill.invitation-intent.v1', actor: scope.owner, workspace: scope.workspace,
246
+ key: options.request !== undefined ? identifier(options.request) : randomUUID(), email: recipient, role };
247
+ await approve(options, `Invite ${terminalText(recipient)} as ${role}?`);
248
+ await rememberInvite(value, scope);
249
+ await submitInvite(value, scope, options, output);
250
+ return;
251
+ }
252
+ if (action === 'revoke') {
253
+ if (!args[1])
254
+ throw invalid();
255
+ const path = `${base}/invitations/${identifier(args[1])}`, current = await api(path, access);
256
+ workspaceTeamRead(current, workspaceInvitationMatch(current, scope.workspace, { id: args[1] }));
257
+ if (['withdrawn', 'revoked', 'accepted', 'expired'].includes(current.state)) {
258
+ output(current, `${current.email} · ${inviteState(current.state)}`);
259
+ return;
260
+ }
261
+ await approve(options, `Revoke the invitation for ${terminalText(current.email)} as ${current.role}? An accepted membership is not removed.`);
262
+ const value = await api(path, { ...access, method: 'DELETE' });
263
+ workspaceTeamRead(value, workspaceInvitationMatch(value, scope.workspace, { id: current.id, actor: current.actor_id, key: current.request_key, email: current.email, role: current.role }));
264
+ const readback = await api(path, access);
265
+ workspaceTeamRead(readback, workspaceInvitationMatch(readback, scope.workspace, { id: current.id, actor: current.actor_id, key: current.request_key, email: current.email, role: current.role }));
266
+ output(readback, [`${readback.email} · ${inviteState(readback.state)}`, invitationRecoveryHint(readback.state, scope.workspace)].filter(Boolean).map(terminalText).join('\n'));
267
+ return;
268
+ }
269
+ let member = args[1] ? identifier(args[1]) : undefined;
270
+ if (!member && isInteractive)
271
+ member = (await choosePaged('Teammate', `${base}/team`, scope, options, row => ({ label: row.name || row.email, detail: `${row.email} · ${row.role}` })))?.id;
272
+ if (!member)
273
+ throw new CliError('member_required', 'Choose a teammate ID with firedrill team list.', 2);
274
+ const current = await api(`${base}/team/${identifier(member)}`, access);
275
+ workspaceTeamRead(current, workspaceMemberDetailMatch(current, scope.workspace, scope.owner, member));
276
+ if (action === 'show') {
277
+ const state = { not_requested: '', searching: 'Checking organization owners. No change has been made.', witness: 'Owner check finished. Submit the reviewed change to apply it.',
278
+ no_owner: 'Add another owner before changing this owner.', attention_required: 'Owner access could not be confirmed. Repeat the reviewed request to check again.' }[current.owner_check];
279
+ output(current, [`${current.name || current.email}`, `${current.email} · ${current.role}`, state].filter(Boolean).map(terminalText).join('\n'));
280
+ return;
281
+ }
282
+ if (!current.can_manage || current.actor_role !== 15 && ['owner', 'admin'].includes(current.role))
283
+ throw new CliError('workspace_permission_required', 'An owner is required for this team change.', 2);
284
+ const available = current.actor_role === 15 ? roles : ['member', 'viewer'];
285
+ const role = action === 'role' ? args[2] ?? (isInteractive ? await selectOne('New role', available.map(value => ({ value, label: value })), options.signal) : '') : null;
286
+ if (action === 'role' && !available.includes(role))
287
+ throw new CliError('role_required', 'Pass an available role: owner, admin, member or viewer. The server checks grant permissions.', 2);
288
+ await approve(options, `${action === 'remove' ? 'Remove' : 'Change role for'} ${terminalText(current.email)}${role ? ' to ' + role : ''}? This affects the organization, not only this workspace.`);
289
+ const value = await api(`${base}/team/${identifier(member)}`, { ...access,
290
+ method: action === 'remove' ? 'DELETE' : 'PATCH', ...(role ? { body: { role } } : {}) });
291
+ workspaceTeamRead(value, workspaceMemberChangeMatch(value, scope.workspace, scope.owner, member));
292
+ output(value, value.state === 'completed' ? 'Team updated.' : value.state === 'checking_owners'
293
+ ? `Checking organization owners. No change has been made. Use firedrill team show ${member}, then repeat the reviewed change when the check finishes.`
294
+ : value.message ?? 'The change is being confirmed. Read the team list before retrying.');
295
+ }