@wenathlan/devthink 2.0.13 → 2.0.15

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 (444) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/accounts.ts +2087 -0
  3. package/agent.ts +2331 -0
  4. package/antigravity.ts +2139 -0
  5. package/apifreeze.ts +4146 -0
  6. package/auth.ts +642 -0
  7. package/background.ts +16837 -0
  8. package/bridge.ts +2080 -0
  9. package/build.ts +54 -0
  10. package/bun.ts +26 -0
  11. package/capture.ts +1614 -0
  12. package/checksecrets.ts +72 -0
  13. package/cjs.ts +9 -0
  14. package/cli.ts +3500 -0
  15. package/commands.ts +1101 -0
  16. package/companion.ts +450 -0
  17. package/compatibility.ts +37 -0
  18. package/config.ts +3137 -0
  19. package/constants.ts +943 -0
  20. package/core.ts +1473 -0
  21. package/crossbrowser.ts +1359 -0
  22. package/dashdone.ts +605 -0
  23. package/data.ts +943 -0
  24. package/database.ts +133 -0
  25. package/debug.ts +850 -0
  26. package/deno.ts +27 -0
  27. package/devthink.ts +707 -0
  28. package/dist/accounts.d.ts +409 -0
  29. package/dist/agent.d.ts +837 -0
  30. package/dist/antigravity.d.ts +380 -0
  31. package/dist/apifreeze.d.ts +113 -0
  32. package/dist/auth.d.ts +224 -0
  33. package/{bridge.d.ts → dist/bridge.d.ts} +1 -1
  34. package/dist/capture.d.ts +595 -0
  35. package/dist/cjs.d.ts +6 -0
  36. package/{cli.js → dist/cli.js} +2 -2
  37. package/dist/commands.d.ts +310 -0
  38. package/dist/compatibility.d.ts +17 -0
  39. package/dist/config.d.ts +1853 -0
  40. package/dist/constants.d.ts +637 -0
  41. package/dist/core.d.ts +361 -0
  42. package/dist/data.d.ts +330 -0
  43. package/dist/database.d.ts +24 -0
  44. package/dist/debug.d.ts +270 -0
  45. package/dist/engine.d.ts +74 -0
  46. package/dist/environments.d.ts +244 -0
  47. package/dist/evidence.d.ts +277 -0
  48. package/dist/export.d.ts +311 -0
  49. package/dist/fingerprint.d.ts +594 -0
  50. package/dist/flow.d.ts +300 -0
  51. package/dist/gates.d.ts +103 -0
  52. package/dist/identity.d.ts +51 -0
  53. package/dist/ids.d.ts +7 -0
  54. package/dist/llm.d.ts +652 -0
  55. package/dist/models.d.ts +1807 -0
  56. package/dist/net.d.ts +325 -0
  57. package/dist/neutral.d.ts +41 -0
  58. package/dist/oauth.d.ts +703 -0
  59. package/dist/page.d.ts +1166 -0
  60. package/dist/perf.d.ts +481 -0
  61. package/dist/plan.d.ts +134 -0
  62. package/dist/project.d.ts +395 -0
  63. package/dist/providers.d.ts +37 -0
  64. package/dist/quota.d.ts +453 -0
  65. package/dist/recovery.d.ts +621 -0
  66. package/dist/request.d.ts +1492 -0
  67. package/dist/run.d.ts +779 -0
  68. package/dist/runtime.d.ts +212 -0
  69. package/dist/search.d.ts +375 -0
  70. package/dist/security.d.ts +534 -0
  71. package/dist/serve.d.ts +136 -0
  72. package/dist/session.d.ts +296 -0
  73. package/dist/storage.d.ts +53 -0
  74. package/dist/streaming.d.ts +1119 -0
  75. package/dist/swarm.d.ts +328 -0
  76. package/dist/tools.d.ts +170 -0
  77. package/dist/types.d.ts +8357 -0
  78. package/dist/utils.d.ts +82 -0
  79. package/dist/version.d.ts +7 -0
  80. package/dist/versionregistry.d.ts +406 -0
  81. package/dist/views.d.ts +579 -0
  82. package/dist/workbenchsession.d.ts +69 -0
  83. package/dist/workflow.d.ts +649 -0
  84. package/docs/readme.md +92 -0
  85. package/docs/schemas/antigravity.json +192 -0
  86. package/engine.ts +1524 -0
  87. package/environments.ts +1005 -0
  88. package/evidence.ts +643 -0
  89. package/export.ts +889 -0
  90. package/fingerprint.ts +1458 -0
  91. package/flow.ts +1190 -0
  92. package/gates.ts +307 -0
  93. package/gateway.ts +34 -0
  94. package/hardening.ts +191 -0
  95. package/headless.ts +369 -0
  96. package/http.ts +2110 -0
  97. package/identity.ts +246 -0
  98. package/ids.ts +26 -0
  99. package/index.ts +369 -0
  100. package/llm.ts +2682 -0
  101. package/mcp.ts +1835 -0
  102. package/{memory.js → memory.ts} +3834 -2310
  103. package/models.ts +3805 -0
  104. package/modes.ts +43 -0
  105. package/net.ts +1214 -0
  106. package/neutral.ts +362 -0
  107. package/node.ts +26 -0
  108. package/oauth.ts +2216 -0
  109. package/offscreen.ts +170 -0
  110. package/pack.ts +956 -0
  111. package/package.json +175 -82
  112. package/page.ts +7824 -0
  113. package/pagebridge.ts +1116 -0
  114. package/perf.ts +957 -0
  115. package/plan.ts +672 -0
  116. package/plugin.ts +76 -0
  117. package/{policy.js → policy.ts} +5073 -4679
  118. package/prisma.config.ts +27 -0
  119. package/progress.ts +1308 -0
  120. package/project.ts +1291 -0
  121. package/protocol.ts +4187 -0
  122. package/providers.ts +246 -0
  123. package/quota.ts +1887 -0
  124. package/recovery.ts +2433 -0
  125. package/request.ts +4482 -0
  126. package/run.ts +2135 -0
  127. package/runtime.ts +526 -0
  128. package/search.ts +1760 -0
  129. package/security.ts +1673 -0
  130. package/serve.ts +419 -0
  131. package/server.ts +5538 -0
  132. package/session.ts +1162 -0
  133. package/storage.ts +182 -0
  134. package/streaming.ts +4101 -0
  135. package/swarm.ts +884 -0
  136. package/sync.ts +56 -0
  137. package/tests/agentcert.test.ts +128 -0
  138. package/tests/agentfleet.test.ts +214 -0
  139. package/tests/agentreview.test.ts +241 -0
  140. package/tests/agentstream.test.ts +335 -0
  141. package/tests/agentwork.test.ts +356 -0
  142. package/tests/apifreeze.test.ts +290 -0
  143. package/tests/apimap.test.ts +112 -0
  144. package/tests/approvalgate.test.ts +175 -0
  145. package/tests/artifactmanifest.test.ts +204 -0
  146. package/tests/attentionfeed.test.ts +163 -0
  147. package/tests/backgroundruns.test.ts +100 -0
  148. package/tests/batchscheduling.test.ts +131 -0
  149. package/tests/blackboard.test.ts +238 -0
  150. package/tests/bridge.test.ts +1088 -0
  151. package/tests/browsercoverage.test.ts +134 -0
  152. package/tests/browserpolyfills.test.ts +124 -0
  153. package/tests/build.mjs +1260 -0
  154. package/tests/clientauth.test.ts +223 -0
  155. package/tests/clitools.test.ts +578 -0
  156. package/tests/confirmgates.test.ts +190 -0
  157. package/tests/containerpack.test.ts +143 -0
  158. package/tests/controlflow.test.ts +2120 -0
  159. package/tests/coordination.test.ts +345 -0
  160. package/tests/copyscreen.test.ts +139 -0
  161. package/tests/core.test.ts +417 -0
  162. package/tests/costcert.test.ts +95 -0
  163. package/tests/crossbrowser.test.ts +115 -0
  164. package/tests/cspaudit.test.ts +79 -0
  165. package/tests/dashdone.test.ts +615 -0
  166. package/tests/datagrid.test.ts +137 -0
  167. package/tests/doccheck.test.ts +107 -0
  168. package/tests/dombatch.test.ts +109 -0
  169. package/tests/emulation.test.ts +282 -0
  170. package/tests/environments.test.ts +259 -0
  171. package/tests/evidenceviews.test.ts +88 -0
  172. package/tests/exporttools.test.ts +185 -0
  173. package/tests/firefoxprep.test.ts +134 -0
  174. package/tests/flowlibrary.test.ts +242 -0
  175. package/tests/flowrun.test.ts +303 -0
  176. package/tests/forensics.test.ts +439 -0
  177. package/tests/gateway.test.ts +939 -0
  178. package/tests/headlesslib.test.ts +171 -0
  179. package/tests/httpstream.test.ts +277 -0
  180. package/tests/immutablelog.test.ts +157 -0
  181. package/tests/inboundguard.test.ts +177 -0
  182. package/tests/lazyload.test.ts +72 -0
  183. package/tests/librarymodes.test.ts +623 -0
  184. package/tests/llm.test.ts +696 -0
  185. package/tests/manifest.test.ts +226 -0
  186. package/tests/maskinputs.test.ts +150 -0
  187. package/tests/matrixverify.test.ts +111 -0
  188. package/tests/mavenpack.test.ts +75 -0
  189. package/tests/mcpserver.test.ts +704 -0
  190. package/tests/memory.test.ts +4155 -0
  191. package/tests/memorycare.test.ts +230 -0
  192. package/tests/migrateplan.test.ts +349 -0
  193. package/tests/minimization.test.ts +414 -0
  194. package/tests/modelroute.test.ts +112 -0
  195. package/tests/multiagent.test.ts +440 -0
  196. package/tests/nativebridge.test.ts +807 -0
  197. package/tests/navigation.test.ts +284 -0
  198. package/tests/nugetpack.test.ts +83 -0
  199. package/tests/orchestration.test.ts +449 -0
  200. package/tests/originpolicy.test.ts +405 -0
  201. package/tests/outputcompare.test.ts +97 -0
  202. package/tests/package.test.ts +91 -0
  203. package/tests/pagebridge.test.ts +5909 -0
  204. package/tests/pentest.test.ts +75 -0
  205. package/tests/perfrecords.test.ts +257 -0
  206. package/tests/permdiff.test.ts +85 -0
  207. package/tests/phishguard.test.ts +128 -0
  208. package/tests/pickerviews.test.ts +155 -0
  209. package/tests/pipelines.test.ts +381 -0
  210. package/tests/planlint.test.ts +240 -0
  211. package/tests/planreview.test.ts +383 -0
  212. package/tests/platformtargets.test.ts +56 -0
  213. package/tests/policy.test.ts +8284 -0
  214. package/tests/portability.test.ts +96 -0
  215. package/tests/progress.test.ts +1036 -0
  216. package/tests/promptlibrary.test.ts +116 -0
  217. package/tests/protocol.test.ts +4793 -0
  218. package/tests/publishingpipeline.test.ts +314 -0
  219. package/tests/quickactions.test.ts +164 -0
  220. package/tests/readiness.test.ts +78 -0
  221. package/tests/recipes.test.ts +163 -0
  222. package/tests/redactshots.test.ts +216 -0
  223. package/tests/registernvidiakeys.ts +51 -0
  224. package/tests/relayserve.test.ts +304 -0
  225. package/tests/releasenotes.test.ts +276 -0
  226. package/tests/resilience.test.ts +467 -0
  227. package/tests/resourceaware.test.ts +187 -0
  228. package/tests/runbudget.test.ts +125 -0
  229. package/tests/runhistory.test.ts +299 -0
  230. package/tests/runreplay.test.ts +113 -0
  231. package/tests/runresume.test.ts +184 -0
  232. package/tests/runstate.test.ts +288 -0
  233. package/tests/runtimeadapters.test.ts +251 -0
  234. package/tests/safariskeleton.test.ts +115 -0
  235. package/tests/sandboxframe.test.ts +196 -0
  236. package/tests/sbom.test.ts +105 -0
  237. package/tests/secretvault.test.ts +188 -0
  238. package/tests/selcache.test.ts +111 -0
  239. package/tests/sessioninterface.test.ts +791 -0
  240. package/tests/sessions.test.ts +591 -0
  241. package/tests/siteprefs.test.ts +228 -0
  242. package/tests/snapshotdelta.test.ts +165 -0
  243. package/tests/statusviews.test.ts +237 -0
  244. package/tests/stepmeter.test.ts +200 -0
  245. package/tests/streamparse.test.ts +163 -0
  246. package/tests/stylepruning.test.ts +90 -0
  247. package/tests/surfaces.test.ts +282 -0
  248. package/tests/sweep.test.ts +78 -0
  249. package/tests/syncbridge.test.ts +164 -0
  250. package/tests/taskqueue.test.ts +206 -0
  251. package/tests/toolcalls.test.ts +336 -0
  252. package/tests/toolcatalog.test.ts +201 -0
  253. package/tests/torture-agent.test.ts +706 -0
  254. package/tests/torture-auth.test.ts +461 -0
  255. package/tests/torture-commands.test.ts +895 -0
  256. package/tests/torture-data.test.ts +923 -0
  257. package/tests/torture-environments.test.ts +285 -0
  258. package/tests/torture-export.test.ts +263 -0
  259. package/tests/torture-http.test.ts +1379 -0
  260. package/tests/torture-llm.test.ts +808 -0
  261. package/tests/torture-memory.test.ts +1084 -0
  262. package/tests/torture-plan.test.ts +829 -0
  263. package/tests/torture-run.test.ts +626 -0
  264. package/tests/torture-session.test.ts +928 -0
  265. package/tests/torture-swarm.test.ts +1245 -0
  266. package/tests/torture-tools.test.ts +964 -0
  267. package/tests/torture-workflow.test.ts +2354 -0
  268. package/tests/tourviews.test.ts +52 -0
  269. package/tests/transparency.test.ts +147 -0
  270. package/tests/trigger.test.ts +941 -0
  271. package/tests/v1sunset.test.ts +428 -0
  272. package/tests/virtlist.test.ts +94 -0
  273. package/tests/vision.test.ts +540 -0
  274. package/tests/vsixpack.test.ts +145 -0
  275. package/tests/webapi.test.ts +523 -0
  276. package/tests/workflow.test.ts +1785 -0
  277. package/tests/workfloweditor.test.ts +759 -0
  278. package/tests/xpipack.test.ts +128 -0
  279. package/tools.ts +734 -0
  280. package/types.ts +9908 -0
  281. package/umd.ts +9 -0
  282. package/utils.ts +249 -0
  283. package/version.ts +8 -0
  284. package/versionregistry.ts +1310 -0
  285. package/views.ts +2153 -0
  286. package/vitest.config.ts +12 -0
  287. package/web/App.tsx +78 -0
  288. package/web/README.md +47 -0
  289. package/web/capacitor.config.ts +46 -0
  290. package/web/const.ts +19 -0
  291. package/web/control.shell.tsx +66 -0
  292. package/web/dashboardpage.ts +554 -0
  293. package/web/db.ts +493 -0
  294. package/web/design.html +541 -0
  295. package/web/gatewayview/Gateway.tsx +345 -0
  296. package/web/gatewayview/config.ts +1042 -0
  297. package/web/gatewayview/definition.ts +174 -0
  298. package/web/icons.ts +15 -0
  299. package/{manifest.json → web/manifest.json} +1 -1
  300. package/web/optionspage.ts +691 -0
  301. package/web/popup.ts +1651 -0
  302. package/web/schema.prisma +176 -0
  303. package/web/sidepanel.ts +7941 -0
  304. package/web/sitemanifest.json +13 -0
  305. package/web/terminal-ui.tsx +622 -0
  306. package/web/transparencypage.ts +541 -0
  307. package/web/vite.config.ts +39 -0
  308. package/web/workspace.ts +23 -0
  309. package/workbenchmemory.ts +104 -0
  310. package/workbenchsession.ts +304 -0
  311. package/workflow.ts +4495 -0
  312. package/bridge.d.ts.map +0 -1
  313. package/bridge.js +0 -1877
  314. package/bun.d.ts.map +0 -1
  315. package/bun.js +0 -52329
  316. package/caps/background.json +0 -712
  317. package/caps/cli.json +0 -360
  318. package/caps/library.json +0 -3611
  319. package/caps/mcp.json +0 -126
  320. package/caps/pagebridge.json +0 -377
  321. package/caps/popup.json +0 -51
  322. package/caps/sidepanel.json +0 -522
  323. package/checksums.txt +0 -142
  324. package/cli.d.ts.map +0 -1
  325. package/companion.d.ts.map +0 -1
  326. package/companion.js +0 -389
  327. package/crossbrowser.d.ts.map +0 -1
  328. package/crossbrowser.js +0 -1191
  329. package/dashdone.d.ts.map +0 -1
  330. package/dashdone.js +0 -368
  331. package/deno.d.ts.map +0 -1
  332. package/deno.js +0 -52325
  333. package/devthink.umd.js +0 -52346
  334. package/fixtures/bun.ts +0 -7
  335. package/fixtures/cjs.js +0 -6
  336. package/fixtures/deno.ts +0 -6
  337. package/fixtures/example-org-pagestate.json +0 -22
  338. package/fixtures/importers/automa-workflow.json +0 -18
  339. package/fixtures/importers/selenium-side.json +0 -20
  340. package/fixtures/importers/tabular-plan.csv +0 -7
  341. package/fixtures/importers/uivision-macro.json +0 -10
  342. package/fixtures/importers/v1-plan.json +0 -13
  343. package/fixtures/mcp-client.mjs +0 -14
  344. package/fixtures/pages/checkout.html +0 -192
  345. package/fixtures/pages/dashboard.html +0 -110
  346. package/fixtures/pages/feed.html +0 -113
  347. package/fixtures/pages/product-grid.html +0 -150
  348. package/fixtures/plans/form-inventory-plan.json +0 -11
  349. package/fixtures/plans/release-notes-plan.json +0 -11
  350. package/fixtures/recipes/agentscompete.json +0 -11
  351. package/fixtures/recipes/agentsforms.json +0 -11
  352. package/fixtures/recipes/agentsmonitor.json +0 -11
  353. package/fixtures/recipes/agentsreview.json +0 -29
  354. package/fixtures/recipes/agentswarm.json +0 -11
  355. package/fixtures/recipes/fillcalendar.json +0 -12
  356. package/fixtures/recipes/fillcheckout.json +0 -13
  357. package/fixtures/recipes/filldependentdropdowns.json +0 -12
  358. package/fixtures/recipes/fillfromcsv.json +0 -13
  359. package/fixtures/recipes/fillloginform.json +0 -12
  360. package/fixtures/recipes/fillmultistepwizard.json +0 -13
  361. package/fixtures/recipes/fillregistration.json +0 -12
  362. package/fixtures/recipes/fillsearchfilters.json +0 -12
  363. package/fixtures/recipes/filltypeahead.json +0 -11
  364. package/fixtures/recipes/monitoralerts.json +0 -12
  365. package/fixtures/recipes/monitoravailability.json +0 -11
  366. package/fixtures/recipes/monitornetworkquiet.json +0 -12
  367. package/fixtures/recipes/monitorpagechanges.json +0 -11
  368. package/fixtures/recipes/monitorpricechange.json +0 -11
  369. package/fixtures/recipes/monitorschedule.json +0 -12
  370. package/fixtures/recipes/scrapedynamicprices.json +0 -13
  371. package/fixtures/recipes/scrapeimagegallery.json +0 -12
  372. package/fixtures/recipes/scrapeinfinitefeed.json +0 -13
  373. package/fixtures/recipes/scrapenestedlists.json +0 -12
  374. package/fixtures/recipes/scrapeproductgrid.json +0 -12
  375. package/fixtures/recipes/scrapereviews.json +0 -12
  376. package/fixtures/recipes/scrapesearchresults.json +0 -12
  377. package/fixtures/recipes/scrapetablepagination.json +0 -12
  378. package/fixtures/recipes/testaccessibility.json +0 -34
  379. package/fixtures/recipes/testconsoleerrors.json +0 -12
  380. package/fixtures/recipes/testdeeplinks.json +0 -12
  381. package/fixtures/recipes/testformvalidation.json +0 -13
  382. package/fixtures/recipes/testlayoutshift.json +0 -12
  383. package/fixtures/recipes/testlinkcheck.json +0 -12
  384. package/fixtures/recipes/testloadtiming.json +0 -12
  385. package/fixtures/recipes/testvisualdiff.json +0 -12
  386. package/fixtures/workflows/changelog-digest-workflow.json +0 -13
  387. package/fixtures/workflows/form-survey-workflow.json +0 -13
  388. package/gallery.json +0 -706
  389. package/hardening.d.ts.map +0 -1
  390. package/hardening.js +0 -188
  391. package/headless.d.ts.map +0 -1
  392. package/headless.js +0 -11522
  393. package/http.d.ts.map +0 -1
  394. package/http.js +0 -2165
  395. package/index.cjs +0 -54682
  396. package/index.d.ts.map +0 -1
  397. package/index.js +0 -52310
  398. package/index.neutral.js +0 -46343
  399. package/mcp.d.ts.map +0 -1
  400. package/mcp.js +0 -20515
  401. package/memory.d.ts.map +0 -1
  402. package/nativehost.template.json +0 -10
  403. package/node.cjs +0 -54686
  404. package/node.d.ts.map +0 -1
  405. package/pack.d.ts.map +0 -1
  406. package/pack.js +0 -805
  407. package/policy.d.ts.map +0 -1
  408. package/progress.d.ts.map +0 -1
  409. package/progress.js +0 -645
  410. package/protocol.d.ts.map +0 -1
  411. package/protocol.js +0 -8334
  412. package/schemas/audit.schema.json +0 -226
  413. package/schemas/capability.schema.json +0 -113
  414. package/schemas/envelope.schema.json +0 -162
  415. package/schemas/memory.schema.json +0 -51
  416. package/schemas/observation.schema.json +0 -113
  417. package/schemas/plan.schema.json +0 -208
  418. package/schemas/progress.schema.json +0 -126
  419. package/schemas/proposal.schema.json +0 -68
  420. package/schemas/session.schema.json +0 -82
  421. package/schemas/tool.schema.json +0 -94
  422. package/server.d.ts.map +0 -1
  423. package/server.js +0 -28877
  424. package/umd-example.html +0 -18
  425. package/umd.d.ts.map +0 -1
  426. /package/{bun.d.ts → dist/bun.d.ts} +0 -0
  427. /package/{cli.d.ts → dist/cli.d.ts} +0 -0
  428. /package/{companion.d.ts → dist/companion.d.ts} +0 -0
  429. /package/{crossbrowser.d.ts → dist/crossbrowser.d.ts} +0 -0
  430. /package/{dashdone.d.ts → dist/dashdone.d.ts} +0 -0
  431. /package/{deno.d.ts → dist/deno.d.ts} +0 -0
  432. /package/{hardening.d.ts → dist/hardening.d.ts} +0 -0
  433. /package/{headless.d.ts → dist/headless.d.ts} +0 -0
  434. /package/{http.d.ts → dist/http.d.ts} +0 -0
  435. /package/{index.d.ts → dist/index.d.ts} +0 -0
  436. /package/{mcp.d.ts → dist/mcp.d.ts} +0 -0
  437. /package/{memory.d.ts → dist/memory.d.ts} +0 -0
  438. /package/{node.d.ts → dist/node.d.ts} +0 -0
  439. /package/{pack.d.ts → dist/pack.d.ts} +0 -0
  440. /package/{policy.d.ts → dist/policy.d.ts} +0 -0
  441. /package/{progress.d.ts → dist/progress.d.ts} +0 -0
  442. /package/{protocol.d.ts → dist/protocol.d.ts} +0 -0
  443. /package/{server.d.ts → dist/server.d.ts} +0 -0
  444. /package/{umd.d.ts → dist/umd.d.ts} +0 -0
@@ -0,0 +1,190 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ credspayload,
4
+ deletepayload,
5
+ gateforstep,
6
+ gatekindfor,
7
+ gateprompttext,
8
+ gatestateof,
9
+ nobatchresolution,
10
+ opengate,
11
+ paypayload,
12
+ resolvegate,
13
+ } from "../gates.js";
14
+
15
+ const now = 1_800_000_000_000;
16
+
17
+ describe("confirmgates", () => {
18
+ it("maps the sensitive classes to their gated families", () => {
19
+ expect(gatekindfor(["payment"])).toBe("confirmpay");
20
+ expect(gatekindfor(["delete"])).toBe("confirmdelete");
21
+ expect(gatekindfor(["credential"])).toBe("confirmcreds");
22
+ expect(gatekindfor(["publish"])).toBeUndefined();
23
+ expect(gatekindfor([])).toBeUndefined();
24
+ });
25
+
26
+ it("shows the amount, payee origin and target element on confirmpay gates", () => {
27
+ const payload = paypayload({ amount: "49.90", payeeorigin: "https://shop.example", target: "#pay" });
28
+ expect(payload).toEqual({ amount: "49.90", payeeorigin: "https://shop.example", target: "#pay" });
29
+ const minimal = paypayload({ payeeorigin: "https://shop.example" });
30
+ expect(minimal).toEqual({ payeeorigin: "https://shop.example" });
31
+ const gate = opengate({
32
+ kind: "confirmpay",
33
+ stepid: "step",
34
+ runid: "run",
35
+ origin: "https://shop.example",
36
+ payload,
37
+ now,
38
+ });
39
+ expect(gate.state).toBe("open");
40
+ expect(gateprompttext(gate)).toMatch(/49\.90/);
41
+ expect(gateprompttext(gate)).toMatch(/https:\/\/shop\.example/);
42
+ expect(gateprompttext(gate)).toMatch(/distinct human action/);
43
+ });
44
+
45
+ it("shows the target, scope and irreversibility on confirmdelete gates", () => {
46
+ const gate = opengate({
47
+ kind: "confirmdelete",
48
+ stepid: "step",
49
+ runid: "run",
50
+ origin: "https://shop.example",
51
+ payload: deletepayload({
52
+ target: "#orders",
53
+ scope: "the order history",
54
+ irreversibility: "The deletion destroys the order history the site cannot restore.",
55
+ }),
56
+ now,
57
+ });
58
+ expect(gateprompttext(gate)).toMatch(/#orders/);
59
+ expect(gateprompttext(gate)).toMatch(/order history/);
60
+ expect(gateprompttext(gate)).toMatch(/cannot restore/);
61
+ });
62
+
63
+ it("shows the credential label only on confirmcreds gates and never the value", () => {
64
+ const payload = credspayload("Bank login");
65
+ expect(payload).toEqual({ label: "Bank login" });
66
+ expect(() => credspayload(" ")).toThrow(/label/);
67
+ const gate = opengate({
68
+ kind: "confirmcreds",
69
+ stepid: "step",
70
+ runid: "run",
71
+ origin: "https://bank.example",
72
+ payload,
73
+ now,
74
+ });
75
+ expect(gateprompttext(gate)).toMatch(/Bank login/);
76
+ expect(gateprompttext(gate)).toMatch(/value stays behind the vault/);
77
+ expect(gateprompttext(gate)).not.toMatch(/hunter2/);
78
+ });
79
+
80
+ it("resolves exactly one open gate through one explicit human action and stays terminal", () => {
81
+ const gate = opengate({
82
+ kind: "confirmpay",
83
+ stepid: "step",
84
+ runid: "run",
85
+ origin: "https://shop.example",
86
+ payload: paypayload({ payeeorigin: "https://shop.example" }),
87
+ now,
88
+ });
89
+ const resolved = resolvegate({
90
+ gates: [gate],
91
+ gateid: gate.gateid,
92
+ decision: "resolved",
93
+ actor: "user",
94
+ now: now + 1200,
95
+ });
96
+ expect(resolved.resolution?.decision).toBe("resolved");
97
+ expect(resolved.resolution?.actor).toBe("user");
98
+ const updated = resolved.gates?.[0];
99
+ expect(updated?.state).toBe("resolved");
100
+ expect(updated?.resolvedat).toBe(now + 1200);
101
+ const again = resolvegate({
102
+ gates: resolved.gates ?? [],
103
+ gateid: gate.gateid,
104
+ decision: "refused",
105
+ actor: "user",
106
+ now: now + 1500,
107
+ });
108
+ expect(again.resolution).toBeUndefined();
109
+ expect(again.gates?.[0]?.state).toBe("resolved");
110
+ });
111
+
112
+ it("refuses resolutions without an acting user and batch approvals", () => {
113
+ const gate = opengate({
114
+ kind: "confirmdelete",
115
+ stepid: "step",
116
+ runid: "run",
117
+ origin: "https://shop.example",
118
+ payload: deletepayload({ scope: "history", irreversibility: "gone" }),
119
+ now,
120
+ });
121
+ expect(() => resolvegate({ gates: [gate], gateid: gate.gateid, decision: "resolved", actor: "", now })).toThrow(
122
+ /acting user/,
123
+ );
124
+ expect(nobatchresolution(["one"]).allowed).toBe(true);
125
+ expect(nobatchresolution(["one", "two"]).allowed).toBe(false);
126
+ expect(nobatchresolution(["one", "two"]).reason).toMatch(/no batch approval/);
127
+ expect(nobatchresolution([]).allowed).toBe(false);
128
+ });
129
+
130
+ it("reads the gate state of one step: none, open, resolved or refused", () => {
131
+ expect(gatestateof([], "step").state).toBe("none");
132
+ const gate = opengate({
133
+ kind: "confirmpay",
134
+ stepid: "step",
135
+ runid: "run",
136
+ origin: "https://shop.example",
137
+ payload: paypayload({ payeeorigin: "https://shop.example" }),
138
+ now,
139
+ });
140
+ expect(gatestateof([gate], "step").state).toBe("open");
141
+ const resolved = resolvegate({ gates: [gate], gateid: gate.gateid, decision: "refused", actor: "user", now });
142
+ expect(gatestateof(resolved.gates ?? [], "step").state).toBe("refused");
143
+ expect(gatestateof(resolved.gates ?? [], "other").state).toBe("none");
144
+ });
145
+
146
+ it("builds the gate of one gated step from its reviewed shape", () => {
147
+ const paystep = {
148
+ id: "pay",
149
+ kind: "fillcard" as const,
150
+ target: "#card",
151
+ options: JSON.stringify({ amount: "12.00", payeeorigin: "https://shop.example" }),
152
+ };
153
+ const paygate = gateforstep({
154
+ step: paystep,
155
+ classes: ["payment"],
156
+ runid: "run",
157
+ origin: "https://shop.example",
158
+ now,
159
+ });
160
+ expect(paygate?.kind).toBe("confirmpay");
161
+ expect(paygate?.payload.amount).toBe("12.00");
162
+ expect(paygate?.payload.payeeorigin).toBe("https://shop.example");
163
+ const deletestep = { id: "del", kind: "discardtab" as const, target: "#orders" };
164
+ const deletegate = gateforstep({
165
+ step: deletestep,
166
+ classes: ["delete"],
167
+ runid: "run",
168
+ origin: "https://shop.example",
169
+ now,
170
+ });
171
+ expect(deletegate?.kind).toBe("confirmdelete");
172
+ expect(deletegate?.payload.scope).toBe("https://shop.example");
173
+ const credstep = { id: "cred", kind: "consentpassword" as const, target: "#login" };
174
+ const credgate = gateforstep({
175
+ step: credstep,
176
+ classes: ["credential"],
177
+ runid: "run",
178
+ origin: "https://bank.example",
179
+ credentiallabel: "Bank login",
180
+ now,
181
+ });
182
+ expect(credgate?.payload).toEqual({ label: "Bank login" });
183
+ expect(
184
+ gateforstep({ step: credstep, classes: ["credential"], runid: "run", origin: "https://bank.example", now }),
185
+ ).toBeUndefined();
186
+ expect(
187
+ gateforstep({ step: paystep, classes: ["publish"], runid: "run", origin: "https://shop.example", now }),
188
+ ).toBeUndefined();
189
+ });
190
+ });
@@ -0,0 +1,143 @@
1
+ import { access, constants, readFile } from "node:fs/promises";
2
+ import { describe, expect, it } from "vitest";
3
+ import { containerexposedsurfaces, containerrunnerentry } from "../pack.js";
4
+
5
+ describe("containerpack", () => {
6
+ it("keeps THE Dockerfile and retires the compose stack and every second container script", async () => {
7
+ const dockerfile = await readFile("Dockerfile", "utf8");
8
+ expect(dockerfile.length).toBeGreaterThan(0);
9
+ await expect(access("compose.yml", constants.F_OK)).rejects.toThrow();
10
+ await expect(access("containerfile", constants.F_OK)).rejects.toThrow();
11
+ });
12
+
13
+ it("builds the multi stage image with the dependency layer, the validated builder, the lean runtime and the folded binary target", async () => {
14
+ const dockerfile = await readFile("Dockerfile", "utf8");
15
+ /* the build stages pin to the native build platform (the saddle
16
+ container doctrine: the toolchain installs native and the library build
17
+ runs at native speed — the prisma dmmf json corrupts under the qemu
18
+ emulation of the emulated legs) while the runtime stages stay per leg. */
19
+ expect(dockerfile).toContain("FROM --platform=$BUILDPLATFORM ${NODE_IMAGE} AS deps");
20
+ expect(dockerfile).toContain("FROM --platform=$BUILDPLATFORM ${NODE_IMAGE} AS builder");
21
+ expect(dockerfile).toContain("COPY --from=builder /work /work");
22
+ expect(dockerfile).toContain("FROM --platform=$BUILDPLATFORM ${NODE_IMAGE} AS binary-builder");
23
+ expect(dockerfile).toContain("FROM gcr.io/distroless/cc-debian12:nonroot AS binary-runtime");
24
+ /* the runtime base is its own arg: the four-arch family surface rides
25
+ the trixie slim line (the only 26.8.x tag whose manifest answers amd64,
26
+ arm64, ppc64le and s390x) while the build stages keep the toolchain
27
+ line pinned to the engines floor. */
28
+ expect(dockerfile).toContain('ARG NODE_RUNTIME_IMAGE="node:26.8.1-trixie-slim"');
29
+ expect(dockerfile).toContain("FROM ${NODE_RUNTIME_IMAGE} AS runtime");
30
+ /* the runner stage closes the file: it stays the default build target
31
+ (a plain docker build and the publish lanes build the runner image, the
32
+ single-binary surface stays behind its own --target) */
33
+ const fromLines = [...dockerfile.matchAll(/^FROM .*$/gm)].map((match) => match[0]);
34
+ expect(fromLines.at(-1)).toBe("FROM ${NODE_RUNTIME_IMAGE} AS runtime");
35
+ });
36
+
37
+ it("resolves the compiled binary target from TARGETARCH so the arm64 image never carries an x64 binary", async () => {
38
+ const dockerfile = await readFile("Dockerfile", "utf8");
39
+ expect(dockerfile).toContain("ARG TARGETARCH");
40
+ expect(dockerfile).toContain('arm64|aarch64) buntarget="bun-linux-arm64"');
41
+ expect(dockerfile).toContain('buntarget="bun-linux-x64"');
42
+ expect(dockerfile).not.toContain("--target=bun-linux-x64");
43
+ });
44
+
45
+ it("runs the library build and the deterministic build checks in the builder before the runtime ships", async () => {
46
+ const dockerfile = await readFile("Dockerfile", "utf8");
47
+ expect(dockerfile).toContain("RUN node tests/build.mjs");
48
+ expect(dockerfile).toContain("RUN node dist/cli.js manifest");
49
+ expect(dockerfile).toContain(
50
+ "RUN node dist/cli.js headless dist/fixtures/plans/release-notes-plan.json --fixtures dist/fixtures",
51
+ );
52
+ expect(dockerfile).toContain("RUN node tests/nativesmoke.mjs");
53
+ expect(dockerfile).toContain("RUN node tests/packageextension.mjs");
54
+ expect(dockerfile).toContain("web/manifest.json");
55
+ });
56
+
57
+ it("runs the vitest suite in the builder with the qemu scaled timeouts before the runtime ships", async () => {
58
+ const dockerfile = await readFile("Dockerfile", "utf8");
59
+ expect(dockerfile).toContain(
60
+ 'RUN if [ "$(uname -m)" = "aarch64" ]; then export DEVTHINK_TEST_TIMEOUT_MS=120000 DEVTHINK_TEST_BUDGET_MS=10000; fi',
61
+ );
62
+ const vitestconfig = await readFile("vitest.config.ts", "utf8");
63
+ expect(vitestconfig).toContain("Number(process.env.DEVTHINK_TEST_TIMEOUT_MS ?? 5000)");
64
+ });
65
+
66
+ it("scales the smoke boot budget for the emulated legs so the four-arch build never flakes on qemu", async () => {
67
+ const dockerfile = await readFile("Dockerfile", "utf8");
68
+ expect(dockerfile).toContain("node container.mjs --check & runnerpid=$!");
69
+ expect(dockerfile).toContain("the container runner died during the smoke boot");
70
+ expect(dockerfile).toContain('case "${TARGETARCH}" in ppc64le|s390x) smokebudget=90 ;; esac');
71
+ expect(dockerfile).toContain("the container runner never answered /healthz within ${smokebudget}s");
72
+ expect(dockerfile).toContain('wait "${runnerpid}"');
73
+ });
74
+
75
+ it("exposes the static site, the socket relay and the mcp server behind the operator chosen environment", async () => {
76
+ const dockerfile = await readFile("Dockerfile", "utf8");
77
+ for (const surface of containerexposedsurfaces()) {
78
+ expect(dockerfile).toContain(surface.bindenv);
79
+ expect(dockerfile).toContain(surface.portenv);
80
+ }
81
+ expect(containerrunnerentry()).toBe("node container.mjs");
82
+ expect(dockerfile).toContain("DEVTHINK_RELAY_PATH=/relay");
83
+ expect(dockerfile).toContain("DEVTHINK_MCP_BIND=127.0.0.1");
84
+ expect(dockerfile).toContain("EXPOSE 8080 7436");
85
+ expect(dockerfile).toContain('ENTRYPOINT ["node", "container.mjs"]');
86
+ expect(dockerfile).toContain("COPY --from=builder --chown=10000:10000 /work/dist/site /app/dist/site");
87
+ expect(dockerfile).toContain("COPY --from=builder --chown=10000:10000 /work/dist/cli.js /app/dist/cli.js");
88
+ expect(dockerfile).toContain("COPY --from=builder --chown=10000:10000 /work/dist/http.js /app/dist/http.js");
89
+ });
90
+
91
+ it("absorbs the retired compose behaviors into the one container file", async () => {
92
+ const dockerfile = await readFile("Dockerfile", "utf8");
93
+ for (const flag of [
94
+ "--read-only",
95
+ "--cap-drop ALL",
96
+ "no-new-privileges:true",
97
+ "--pids-limit 512",
98
+ "--network none",
99
+ "--tmpfs /tmp:size=2g,mode=1777",
100
+ ]) {
101
+ expect(dockerfile).toContain(flag);
102
+ }
103
+ expect(dockerfile).toContain("DEVTHINK_MEMORY_ENGINE=ram");
104
+ expect(dockerfile).toContain('DEVTHINK_PLATFORM=""');
105
+ expect(dockerfile).toContain('DEVTHINK_CDN_URL=""');
106
+ });
107
+
108
+ it("runs the image as the non root devthink user with a live healthcheck and the OCI labels of the DevThink identity", async () => {
109
+ const dockerfile = await readFile("Dockerfile", "utf8");
110
+ expect(dockerfile).toContain("groupadd --gid 10000 devthink");
111
+ expect(dockerfile).toContain("useradd --uid 10000 --gid 10000");
112
+ expect(dockerfile).toMatch(/HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3/);
113
+ expect(dockerfile).toContain("/healthz");
114
+ expect(dockerfile).toContain('org.opencontainers.image.version="${DEVTHINK_VERSION}"');
115
+ expect(dockerfile).toContain('org.opencontainers.image.source="https://github.com/wenathlan/devthink"');
116
+ expect(dockerfile).not.toMatch(/:latest\b/);
117
+ });
118
+
119
+ it("publishes the image with version tags only, the registry buildcache and the four architecture family surface", async () => {
120
+ const publish = await readFile(".github/workflows/publishghcr.yml", "utf8");
121
+ expect(publish).not.toContain(":latest");
122
+ expect(publish).toContain("target: runtime");
123
+ expect(publish).toContain("devthink-buildcache");
124
+ expect(publish).toContain("type=gha");
125
+ expect(publish).toContain("mode=max");
126
+ /* the four-arch family union the saddle publish lane established
127
+ (amd64, arm64, ppc64le, s390x) with the qemu pin for the emulated
128
+ legs and the index assertion that fixes the published surface. */
129
+ expect(publish).toContain("platforms: linux/arm64,linux/ppc64le,linux/s390x");
130
+ expect(publish).toContain("platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/s390x");
131
+ expect(publish).toContain('. == ["amd64", "arm64", "ppc64le", "s390x"]');
132
+ expect(publish).toContain("provenance: mode=max");
133
+ expect(publish).toContain("sbom: true");
134
+ expect(publish).toContain("aquasecurity/trivy-action@v0.36.0");
135
+ });
136
+
137
+ it("builds the release container archive from THE Dockerfile", async () => {
138
+ const container = await readFile(".github/workflows/container.yml", "utf8");
139
+ expect(container).toContain("docker build");
140
+ expect(container).toContain("--build-arg DEVTHINK_VERSION=");
141
+ expect(container).toContain("docker save");
142
+ });
143
+ });