@wenathlan/devthink 2.0.12 → 2.0.14
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/CHANGELOG.md +20 -0
- package/accounts.ts +2087 -0
- package/agent.ts +2331 -0
- package/antigravity.ts +2139 -0
- package/apifreeze.ts +4146 -0
- package/auth.ts +642 -0
- package/background.ts +16837 -0
- package/bridge.ts +2080 -0
- package/build.ts +54 -0
- package/bun.ts +26 -0
- package/capture.ts +1614 -0
- package/checksecrets.ts +72 -0
- package/cjs.ts +9 -0
- package/cli.ts +3500 -0
- package/commands.ts +1101 -0
- package/companion.ts +450 -0
- package/compatibility.ts +37 -0
- package/config.ts +3137 -0
- package/constants.ts +943 -0
- package/core.ts +1473 -0
- package/crossbrowser.ts +1359 -0
- package/dashdone.ts +605 -0
- package/data.ts +943 -0
- package/database.ts +133 -0
- package/debug.ts +850 -0
- package/deno.ts +27 -0
- package/devthink.ts +707 -0
- package/dist/accounts.d.ts +409 -0
- package/dist/agent.d.ts +837 -0
- package/dist/antigravity.d.ts +380 -0
- package/dist/apifreeze.d.ts +113 -0
- package/dist/auth.d.ts +224 -0
- package/{bridge.d.ts → dist/bridge.d.ts} +1 -1
- package/dist/capture.d.ts +595 -0
- package/dist/cjs.d.ts +6 -0
- package/{cli.js → dist/cli.js} +2 -2
- package/dist/commands.d.ts +310 -0
- package/dist/compatibility.d.ts +17 -0
- package/dist/config.d.ts +1853 -0
- package/dist/constants.d.ts +637 -0
- package/dist/core.d.ts +361 -0
- package/dist/data.d.ts +330 -0
- package/dist/database.d.ts +24 -0
- package/dist/debug.d.ts +270 -0
- package/dist/engine.d.ts +74 -0
- package/dist/environments.d.ts +244 -0
- package/dist/evidence.d.ts +277 -0
- package/dist/export.d.ts +311 -0
- package/dist/fingerprint.d.ts +594 -0
- package/dist/flow.d.ts +300 -0
- package/dist/gates.d.ts +103 -0
- package/dist/identity.d.ts +51 -0
- package/dist/ids.d.ts +7 -0
- package/dist/llm.d.ts +652 -0
- package/dist/models.d.ts +1807 -0
- package/dist/net.d.ts +325 -0
- package/dist/neutral.d.ts +41 -0
- package/dist/oauth.d.ts +703 -0
- package/dist/page.d.ts +1166 -0
- package/dist/perf.d.ts +481 -0
- package/dist/plan.d.ts +134 -0
- package/dist/project.d.ts +395 -0
- package/dist/providers.d.ts +37 -0
- package/dist/quota.d.ts +453 -0
- package/dist/recovery.d.ts +621 -0
- package/dist/request.d.ts +1492 -0
- package/dist/run.d.ts +779 -0
- package/dist/runtime.d.ts +212 -0
- package/dist/search.d.ts +375 -0
- package/dist/security.d.ts +534 -0
- package/dist/serve.d.ts +136 -0
- package/dist/session.d.ts +296 -0
- package/dist/storage.d.ts +53 -0
- package/dist/streaming.d.ts +1119 -0
- package/dist/swarm.d.ts +328 -0
- package/dist/tools.d.ts +170 -0
- package/dist/types.d.ts +8357 -0
- package/dist/utils.d.ts +82 -0
- package/dist/version.d.ts +7 -0
- package/dist/versionregistry.d.ts +406 -0
- package/dist/views.d.ts +579 -0
- package/dist/workbenchsession.d.ts +69 -0
- package/dist/workflow.d.ts +649 -0
- package/docs/readme.md +92 -0
- package/docs/schemas/antigravity.json +192 -0
- package/engine.ts +1524 -0
- package/environments.ts +1005 -0
- package/evidence.ts +643 -0
- package/export.ts +889 -0
- package/fingerprint.ts +1458 -0
- package/flow.ts +1190 -0
- package/gates.ts +307 -0
- package/gateway.ts +34 -0
- package/hardening.ts +191 -0
- package/headless.ts +369 -0
- package/http.ts +2110 -0
- package/identity.ts +246 -0
- package/ids.ts +26 -0
- package/index.ts +369 -0
- package/llm.ts +2682 -0
- package/mcp.ts +1835 -0
- package/{memory.js → memory.ts} +3834 -2310
- package/models.ts +3805 -0
- package/modes.ts +43 -0
- package/net.ts +1214 -0
- package/neutral.ts +362 -0
- package/node.ts +26 -0
- package/oauth.ts +2216 -0
- package/offscreen.ts +170 -0
- package/pack.ts +956 -0
- package/package.json +175 -82
- package/page.ts +7824 -0
- package/pagebridge.ts +1116 -0
- package/perf.ts +957 -0
- package/plan.ts +672 -0
- package/plugin.ts +76 -0
- package/{policy.js → policy.ts} +5073 -4679
- package/prisma.config.ts +27 -0
- package/progress.ts +1308 -0
- package/project.ts +1291 -0
- package/protocol.ts +4187 -0
- package/providers.ts +246 -0
- package/quota.ts +1887 -0
- package/recovery.ts +2433 -0
- package/request.ts +4482 -0
- package/run.ts +2135 -0
- package/runtime.ts +526 -0
- package/search.ts +1760 -0
- package/security.ts +1673 -0
- package/serve.ts +419 -0
- package/server.ts +5538 -0
- package/session.ts +1162 -0
- package/storage.ts +182 -0
- package/streaming.ts +4101 -0
- package/swarm.ts +884 -0
- package/sync.ts +56 -0
- package/tests/agentcert.test.ts +128 -0
- package/tests/agentfleet.test.ts +214 -0
- package/tests/agentreview.test.ts +241 -0
- package/tests/agentstream.test.ts +335 -0
- package/tests/agentwork.test.ts +356 -0
- package/tests/apifreeze.test.ts +290 -0
- package/tests/apimap.test.ts +112 -0
- package/tests/approvalgate.test.ts +175 -0
- package/tests/artifactmanifest.test.ts +204 -0
- package/tests/attentionfeed.test.ts +163 -0
- package/tests/backgroundruns.test.ts +100 -0
- package/tests/batchscheduling.test.ts +131 -0
- package/tests/blackboard.test.ts +238 -0
- package/tests/bridge.test.ts +1088 -0
- package/tests/browsercoverage.test.ts +134 -0
- package/tests/browserpolyfills.test.ts +124 -0
- package/tests/build.mjs +1260 -0
- package/tests/clientauth.test.ts +223 -0
- package/tests/clitools.test.ts +578 -0
- package/tests/confirmgates.test.ts +190 -0
- package/tests/containerpack.test.ts +143 -0
- package/tests/controlflow.test.ts +2120 -0
- package/tests/coordination.test.ts +345 -0
- package/tests/copyscreen.test.ts +139 -0
- package/tests/core.test.ts +417 -0
- package/tests/costcert.test.ts +95 -0
- package/tests/crossbrowser.test.ts +115 -0
- package/tests/cspaudit.test.ts +79 -0
- package/tests/dashdone.test.ts +615 -0
- package/tests/datagrid.test.ts +137 -0
- package/tests/doccheck.test.ts +107 -0
- package/tests/dombatch.test.ts +109 -0
- package/tests/emulation.test.ts +282 -0
- package/tests/environments.test.ts +259 -0
- package/tests/evidenceviews.test.ts +88 -0
- package/tests/exporttools.test.ts +185 -0
- package/tests/firefoxprep.test.ts +134 -0
- package/tests/flowlibrary.test.ts +242 -0
- package/tests/flowrun.test.ts +303 -0
- package/tests/forensics.test.ts +439 -0
- package/tests/gateway.test.ts +939 -0
- package/tests/headlesslib.test.ts +171 -0
- package/tests/httpstream.test.ts +277 -0
- package/tests/immutablelog.test.ts +157 -0
- package/tests/inboundguard.test.ts +177 -0
- package/tests/lazyload.test.ts +72 -0
- package/tests/librarymodes.test.ts +623 -0
- package/tests/llm.test.ts +696 -0
- package/tests/manifest.test.ts +226 -0
- package/tests/maskinputs.test.ts +150 -0
- package/tests/matrixverify.test.ts +111 -0
- package/tests/mavenpack.test.ts +75 -0
- package/tests/mcpserver.test.ts +704 -0
- package/tests/memory.test.ts +4155 -0
- package/tests/memorycare.test.ts +230 -0
- package/tests/migrateplan.test.ts +349 -0
- package/tests/minimization.test.ts +414 -0
- package/tests/modelroute.test.ts +112 -0
- package/tests/multiagent.test.ts +440 -0
- package/tests/nativebridge.test.ts +807 -0
- package/tests/navigation.test.ts +284 -0
- package/tests/nugetpack.test.ts +83 -0
- package/tests/orchestration.test.ts +449 -0
- package/tests/originpolicy.test.ts +405 -0
- package/tests/outputcompare.test.ts +97 -0
- package/tests/package.test.ts +91 -0
- package/tests/pagebridge.test.ts +5909 -0
- package/tests/pentest.test.ts +75 -0
- package/tests/perfrecords.test.ts +257 -0
- package/tests/permdiff.test.ts +85 -0
- package/tests/phishguard.test.ts +128 -0
- package/tests/pickerviews.test.ts +155 -0
- package/tests/pipelines.test.ts +381 -0
- package/tests/planlint.test.ts +240 -0
- package/tests/planreview.test.ts +383 -0
- package/tests/platformtargets.test.ts +56 -0
- package/tests/policy.test.ts +8284 -0
- package/tests/portability.test.ts +96 -0
- package/tests/progress.test.ts +1036 -0
- package/tests/promptlibrary.test.ts +116 -0
- package/tests/protocol.test.ts +4793 -0
- package/tests/publishingpipeline.test.ts +314 -0
- package/tests/quickactions.test.ts +164 -0
- package/tests/readiness.test.ts +78 -0
- package/tests/recipes.test.ts +163 -0
- package/tests/redactshots.test.ts +216 -0
- package/tests/registernvidiakeys.ts +51 -0
- package/tests/relayserve.test.ts +304 -0
- package/tests/releasenotes.test.ts +276 -0
- package/tests/resilience.test.ts +467 -0
- package/tests/resourceaware.test.ts +187 -0
- package/tests/runbudget.test.ts +125 -0
- package/tests/runhistory.test.ts +299 -0
- package/tests/runreplay.test.ts +113 -0
- package/tests/runresume.test.ts +184 -0
- package/tests/runstate.test.ts +288 -0
- package/tests/runtimeadapters.test.ts +251 -0
- package/tests/safariskeleton.test.ts +115 -0
- package/tests/sandboxframe.test.ts +196 -0
- package/tests/sbom.test.ts +105 -0
- package/tests/secretvault.test.ts +188 -0
- package/tests/selcache.test.ts +111 -0
- package/tests/sessioninterface.test.ts +791 -0
- package/tests/sessions.test.ts +591 -0
- package/tests/siteprefs.test.ts +228 -0
- package/tests/snapshotdelta.test.ts +165 -0
- package/tests/statusviews.test.ts +237 -0
- package/tests/stepmeter.test.ts +200 -0
- package/tests/streamparse.test.ts +163 -0
- package/tests/stylepruning.test.ts +90 -0
- package/tests/surfaces.test.ts +282 -0
- package/tests/sweep.test.ts +78 -0
- package/tests/syncbridge.test.ts +164 -0
- package/tests/taskqueue.test.ts +206 -0
- package/tests/toolcalls.test.ts +336 -0
- package/tests/toolcatalog.test.ts +201 -0
- package/tests/torture-agent.test.ts +706 -0
- package/tests/torture-auth.test.ts +461 -0
- package/tests/torture-commands.test.ts +895 -0
- package/tests/torture-data.test.ts +923 -0
- package/tests/torture-environments.test.ts +285 -0
- package/tests/torture-export.test.ts +263 -0
- package/tests/torture-http.test.ts +1379 -0
- package/tests/torture-llm.test.ts +808 -0
- package/tests/torture-memory.test.ts +1084 -0
- package/tests/torture-plan.test.ts +829 -0
- package/tests/torture-run.test.ts +626 -0
- package/tests/torture-session.test.ts +928 -0
- package/tests/torture-swarm.test.ts +1245 -0
- package/tests/torture-tools.test.ts +964 -0
- package/tests/torture-workflow.test.ts +2354 -0
- package/tests/tourviews.test.ts +52 -0
- package/tests/transparency.test.ts +147 -0
- package/tests/trigger.test.ts +941 -0
- package/tests/v1sunset.test.ts +428 -0
- package/tests/virtlist.test.ts +94 -0
- package/tests/vision.test.ts +540 -0
- package/tests/vsixpack.test.ts +145 -0
- package/tests/webapi.test.ts +523 -0
- package/tests/workflow.test.ts +1785 -0
- package/tests/workfloweditor.test.ts +759 -0
- package/tests/xpipack.test.ts +128 -0
- package/tools.ts +734 -0
- package/types.ts +9908 -0
- package/umd.ts +9 -0
- package/utils.ts +249 -0
- package/version.ts +8 -0
- package/versionregistry.ts +1310 -0
- package/views.ts +2153 -0
- package/vitest.config.ts +12 -0
- package/web/App.tsx +78 -0
- package/web/README.md +47 -0
- package/web/capacitor.config.ts +46 -0
- package/web/const.ts +19 -0
- package/web/control.shell.tsx +66 -0
- package/web/dashboardpage.ts +554 -0
- package/web/db.ts +493 -0
- package/web/design.html +541 -0
- package/web/gatewayview/Gateway.tsx +345 -0
- package/web/gatewayview/config.ts +1042 -0
- package/web/gatewayview/definition.ts +174 -0
- package/web/icons.ts +15 -0
- package/{manifest.json → web/manifest.json} +1 -1
- package/web/optionspage.ts +691 -0
- package/web/popup.ts +1651 -0
- package/web/schema.prisma +176 -0
- package/web/sidepanel.ts +7941 -0
- package/web/sitemanifest.json +13 -0
- package/web/terminal-ui.tsx +622 -0
- package/web/transparencypage.ts +541 -0
- package/web/vite.config.ts +39 -0
- package/web/workspace.ts +23 -0
- package/workbenchmemory.ts +104 -0
- package/workbenchsession.ts +304 -0
- package/workflow.ts +4495 -0
- package/bridge.d.ts.map +0 -1
- package/bridge.js +0 -1877
- package/bun.d.ts.map +0 -1
- package/bun.js +0 -52329
- package/caps/background.json +0 -712
- package/caps/cli.json +0 -360
- package/caps/library.json +0 -3611
- package/caps/mcp.json +0 -126
- package/caps/pagebridge.json +0 -377
- package/caps/popup.json +0 -51
- package/caps/sidepanel.json +0 -522
- package/checksums.txt +0 -142
- package/cli.d.ts.map +0 -1
- package/companion.d.ts.map +0 -1
- package/companion.js +0 -389
- package/crossbrowser.d.ts.map +0 -1
- package/crossbrowser.js +0 -1191
- package/dashdone.d.ts.map +0 -1
- package/dashdone.js +0 -368
- package/deno.d.ts.map +0 -1
- package/deno.js +0 -52325
- package/devthink.umd.js +0 -52346
- package/fixtures/bun.ts +0 -7
- package/fixtures/cjs.js +0 -6
- package/fixtures/deno.ts +0 -6
- package/fixtures/example-org-pagestate.json +0 -22
- package/fixtures/importers/automa-workflow.json +0 -18
- package/fixtures/importers/selenium-side.json +0 -20
- package/fixtures/importers/tabular-plan.csv +0 -7
- package/fixtures/importers/uivision-macro.json +0 -10
- package/fixtures/importers/v1-plan.json +0 -13
- package/fixtures/mcp-client.mjs +0 -14
- package/fixtures/pages/checkout.html +0 -192
- package/fixtures/pages/dashboard.html +0 -110
- package/fixtures/pages/feed.html +0 -113
- package/fixtures/pages/product-grid.html +0 -150
- package/fixtures/plans/form-inventory-plan.json +0 -11
- package/fixtures/plans/release-notes-plan.json +0 -11
- package/fixtures/recipes/agentscompete.json +0 -11
- package/fixtures/recipes/agentsforms.json +0 -11
- package/fixtures/recipes/agentsmonitor.json +0 -11
- package/fixtures/recipes/agentsreview.json +0 -29
- package/fixtures/recipes/agentswarm.json +0 -11
- package/fixtures/recipes/fillcalendar.json +0 -12
- package/fixtures/recipes/fillcheckout.json +0 -13
- package/fixtures/recipes/filldependentdropdowns.json +0 -12
- package/fixtures/recipes/fillfromcsv.json +0 -13
- package/fixtures/recipes/fillloginform.json +0 -12
- package/fixtures/recipes/fillmultistepwizard.json +0 -13
- package/fixtures/recipes/fillregistration.json +0 -12
- package/fixtures/recipes/fillsearchfilters.json +0 -12
- package/fixtures/recipes/filltypeahead.json +0 -11
- package/fixtures/recipes/monitoralerts.json +0 -12
- package/fixtures/recipes/monitoravailability.json +0 -11
- package/fixtures/recipes/monitornetworkquiet.json +0 -12
- package/fixtures/recipes/monitorpagechanges.json +0 -11
- package/fixtures/recipes/monitorpricechange.json +0 -11
- package/fixtures/recipes/monitorschedule.json +0 -12
- package/fixtures/recipes/scrapedynamicprices.json +0 -13
- package/fixtures/recipes/scrapeimagegallery.json +0 -12
- package/fixtures/recipes/scrapeinfinitefeed.json +0 -13
- package/fixtures/recipes/scrapenestedlists.json +0 -12
- package/fixtures/recipes/scrapeproductgrid.json +0 -12
- package/fixtures/recipes/scrapereviews.json +0 -12
- package/fixtures/recipes/scrapesearchresults.json +0 -12
- package/fixtures/recipes/scrapetablepagination.json +0 -12
- package/fixtures/recipes/testaccessibility.json +0 -34
- package/fixtures/recipes/testconsoleerrors.json +0 -12
- package/fixtures/recipes/testdeeplinks.json +0 -12
- package/fixtures/recipes/testformvalidation.json +0 -13
- package/fixtures/recipes/testlayoutshift.json +0 -12
- package/fixtures/recipes/testlinkcheck.json +0 -12
- package/fixtures/recipes/testloadtiming.json +0 -12
- package/fixtures/recipes/testvisualdiff.json +0 -12
- package/fixtures/workflows/changelog-digest-workflow.json +0 -13
- package/fixtures/workflows/form-survey-workflow.json +0 -13
- package/gallery.json +0 -706
- package/hardening.d.ts.map +0 -1
- package/hardening.js +0 -188
- package/headless.d.ts.map +0 -1
- package/headless.js +0 -11522
- package/http.d.ts.map +0 -1
- package/http.js +0 -2165
- package/index.cjs +0 -54682
- package/index.d.ts.map +0 -1
- package/index.js +0 -52310
- package/index.neutral.js +0 -46343
- package/mcp.d.ts.map +0 -1
- package/mcp.js +0 -20515
- package/memory.d.ts.map +0 -1
- package/nativehost.template.json +0 -10
- package/node.cjs +0 -54686
- package/node.d.ts.map +0 -1
- package/pack.d.ts.map +0 -1
- package/pack.js +0 -805
- package/policy.d.ts.map +0 -1
- package/progress.d.ts.map +0 -1
- package/progress.js +0 -645
- package/protocol.d.ts.map +0 -1
- package/protocol.js +0 -8334
- package/schemas/audit.schema.json +0 -226
- package/schemas/capability.schema.json +0 -113
- package/schemas/envelope.schema.json +0 -162
- package/schemas/memory.schema.json +0 -51
- package/schemas/observation.schema.json +0 -113
- package/schemas/plan.schema.json +0 -208
- package/schemas/progress.schema.json +0 -126
- package/schemas/proposal.schema.json +0 -68
- package/schemas/session.schema.json +0 -82
- package/schemas/tool.schema.json +0 -94
- package/server.d.ts.map +0 -1
- package/server.js +0 -28877
- package/umd-example.html +0 -18
- package/umd.d.ts.map +0 -1
- /package/{bun.d.ts → dist/bun.d.ts} +0 -0
- /package/{cli.d.ts → dist/cli.d.ts} +0 -0
- /package/{companion.d.ts → dist/companion.d.ts} +0 -0
- /package/{crossbrowser.d.ts → dist/crossbrowser.d.ts} +0 -0
- /package/{dashdone.d.ts → dist/dashdone.d.ts} +0 -0
- /package/{deno.d.ts → dist/deno.d.ts} +0 -0
- /package/{hardening.d.ts → dist/hardening.d.ts} +0 -0
- /package/{headless.d.ts → dist/headless.d.ts} +0 -0
- /package/{http.d.ts → dist/http.d.ts} +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{mcp.d.ts → dist/mcp.d.ts} +0 -0
- /package/{memory.d.ts → dist/memory.d.ts} +0 -0
- /package/{node.d.ts → dist/node.d.ts} +0 -0
- /package/{pack.d.ts → dist/pack.d.ts} +0 -0
- /package/{policy.d.ts → dist/policy.d.ts} +0 -0
- /package/{progress.d.ts → dist/progress.d.ts} +0 -0
- /package/{protocol.d.ts → dist/protocol.d.ts} +0 -0
- /package/{server.d.ts → dist/server.d.ts} +0 -0
- /package/{umd.d.ts → dist/umd.d.ts} +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { runrecipessuite } from "./recipes.mjs";
|
|
8
|
+
import type { recipereport } from "./recipes.mjs";
|
|
9
|
+
|
|
10
|
+
const execute = promisify(execFile);
|
|
11
|
+
const gallerypath = "tests/code/recipes/gallery.json";
|
|
12
|
+
const recipesdirectory = "tests/code/recipes";
|
|
13
|
+
const pagesdirectory = "tests/code/pages";
|
|
14
|
+
const artifactpath = "tests/artifacts/recipes.json";
|
|
15
|
+
const expectedcategories = { scraping: 8, forms: 9, testing: 8, monitoring: 6, agents: 5 };
|
|
16
|
+
|
|
17
|
+
/** One gallery index entry with the metadata the runner validates. */
|
|
18
|
+
interface galleryentry {
|
|
19
|
+
id: string;
|
|
20
|
+
category: string;
|
|
21
|
+
difficulty: string;
|
|
22
|
+
description: string;
|
|
23
|
+
fixture: string;
|
|
24
|
+
origin: string;
|
|
25
|
+
expecteddurationms: number;
|
|
26
|
+
capabilities: string[];
|
|
27
|
+
consentclasses: string[];
|
|
28
|
+
kinds: string[];
|
|
29
|
+
exportformat?: string;
|
|
30
|
+
schedule?: string;
|
|
31
|
+
topology?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The gallery index of the 36 recipes: the index metadata beside the fixture page declarations. */
|
|
35
|
+
interface galleryindex {
|
|
36
|
+
version: string;
|
|
37
|
+
fixturepages: Array<{ name: string; origin: string; features: string[] }>;
|
|
38
|
+
entries: galleryentry[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** One recipe plan document the directory carries: the origin and the steps the grammar and lint checks read. */
|
|
42
|
+
interface recipedocument {
|
|
43
|
+
origin: string;
|
|
44
|
+
grants?: string[];
|
|
45
|
+
steps: Array<{ id: string; kind: string; options?: string }>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Collects every action kind one recipe names: the top level step kinds beside the child kinds nested in the control payloads of the options (the parallel branches, the loop bodies and the branch paths), so the grammar check reads the same surface the runner reads. */
|
|
49
|
+
function kindswithin(recipe: recipedocument): string[] {
|
|
50
|
+
const kinds: string[] = [];
|
|
51
|
+
const walk = (value: unknown) => {
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
for (const item of value) walk(item);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (value === null || typeof value !== "object") return;
|
|
57
|
+
const candidate = value as Record<string, unknown>;
|
|
58
|
+
if (typeof candidate.kind === "string") kinds.push(candidate.kind);
|
|
59
|
+
for (const child of Object.values(candidate)) walk(child);
|
|
60
|
+
};
|
|
61
|
+
for (const step of recipe.steps) {
|
|
62
|
+
kinds.push(step.kind);
|
|
63
|
+
if (step.options !== undefined) {
|
|
64
|
+
try {
|
|
65
|
+
walk(JSON.parse(step.options));
|
|
66
|
+
} catch {
|
|
67
|
+
/* the option grammar check of the runner reports the malformed payload */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return [...new Set(kinds)];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* ── The 2.0.0 example gallery coverage: the source grammar pass, the suite run over the built tree and the recorded artifact. ── */
|
|
75
|
+
|
|
76
|
+
describe("the example gallery of the 2.0.0 release", () => {
|
|
77
|
+
it("parses every recipe with the lowercase kind grammar and the category metadata the index declares", async () => {
|
|
78
|
+
const gallery = JSON.parse(await readFile(gallerypath, "utf8")) as galleryindex;
|
|
79
|
+
expect(gallery.entries.length).toBe(36);
|
|
80
|
+
/* no gallery entry id duplicates: the index names every recipe exactly once */
|
|
81
|
+
expect(new Set(gallery.entries.map((entry) => entry.id)).size).toBe(36);
|
|
82
|
+
/* every recipe file of the directory other than the index joins the index, and every index entry names its file */
|
|
83
|
+
const recipefiles = (await readdir(recipesdirectory))
|
|
84
|
+
.filter((file) => file.endsWith(".json") && file !== "gallery.json")
|
|
85
|
+
.sort();
|
|
86
|
+
expect(recipefiles.length).toBe(36);
|
|
87
|
+
const recipes = new Map<string, recipedocument>();
|
|
88
|
+
for (const file of recipefiles) {
|
|
89
|
+
const parsed = JSON.parse(await readFile(join(recipesdirectory, file), "utf8")) as recipedocument;
|
|
90
|
+
recipes.set(file.replace(".json", ""), parsed);
|
|
91
|
+
}
|
|
92
|
+
expect(new Set([...recipes.keys(), ...gallery.entries.map((entry) => entry.id)]).size).toBe(36);
|
|
93
|
+
/* every step kind stays lowercase letter only: the workflow step grammar rejects digits (the a11ytree incident), so the gallery ships no kind the compose engine would refuse */
|
|
94
|
+
const digitkinds = [...recipes].flatMap(([id, recipe]) =>
|
|
95
|
+
kindswithin(recipe)
|
|
96
|
+
.filter((kind) => !/^[a-z]+$/.test(kind))
|
|
97
|
+
.map((kind) => `${id} carries ${kind}`),
|
|
98
|
+
);
|
|
99
|
+
expect(digitkinds).toEqual([]);
|
|
100
|
+
/* the monitoring entries declare their five field cron schedules, the agent entries their topologies and the scraping entries their export formats */
|
|
101
|
+
for (const entry of gallery.entries) {
|
|
102
|
+
if (entry.category === "monitoring")
|
|
103
|
+
expect(entry.schedule).toMatch(/^(\*|\d+)(\/\d+)? (\*|\d+) (\*|\d+) (\*|\d+) (\*|\d+)$/);
|
|
104
|
+
if (entry.category !== "monitoring") expect(entry.schedule).toBeUndefined();
|
|
105
|
+
if (entry.category === "agents")
|
|
106
|
+
expect(["swarm", "review", "parallel", "monitor", "compete"]).toContain(entry.topology);
|
|
107
|
+
if (entry.category !== "agents") expect(entry.topology).toBeUndefined();
|
|
108
|
+
if (entry.category === "scraping") expect(["csv", "json", "excel"]).toContain(entry.exportformat);
|
|
109
|
+
if (entry.category !== "scraping") expect(entry.exportformat).toBeUndefined();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("runs the gallery suite green over the built tree", { timeout: 120_000 }, async () => {
|
|
114
|
+
const built = existsSync("dist/gallery.json");
|
|
115
|
+
/* the suite needs the built fixture copies the packages ship, so a lane without a build asserts the source pass only */
|
|
116
|
+
if (!built) return;
|
|
117
|
+
const report = await runrecipessuite();
|
|
118
|
+
expect(report.gallery.entries).toBe(36);
|
|
119
|
+
expect(report.gallery.fixtures).toBe(4);
|
|
120
|
+
expect(report.gallery.categories).toEqual(expectedcategories);
|
|
121
|
+
expect(report.summary.entries).toBe(36);
|
|
122
|
+
expect(report.summary.passed).toBe(36);
|
|
123
|
+
expect(report.summary.failed).toBe(0);
|
|
124
|
+
expect(report.summary.checksok).toBe(report.summary.checks);
|
|
125
|
+
expect(report.checks.every((check) => check.ok)).toBe(true);
|
|
126
|
+
expect(report.entries.length).toBe(36);
|
|
127
|
+
expect(report.entries.every((entry) => entry.outcome === "pass")).toBe(true);
|
|
128
|
+
expect(report.entries.every((entry) => entry.durationms >= 0)).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("covers every gallery entry of the index in the recorded artifact", { timeout: Number(process.env.DEVTHINK_TEST_TIMEOUT_MS ?? 120000) }, async () => {
|
|
132
|
+
const built = existsSync("dist/gallery.json");
|
|
133
|
+
const packagejson = JSON.parse(await readFile("package.json", "utf8")) as { version: string };
|
|
134
|
+
/* a built tree runs the gate itself when no fresh artifact of this release exists, so every lane that builds before the suite verifies the gallery artifact without depending on gate ordering */
|
|
135
|
+
if (built && !existsSync(artifactpath)) await execute("node", ["tests/recipes.mjs"]);
|
|
136
|
+
if (built && existsSync(artifactpath)) {
|
|
137
|
+
const stored = JSON.parse(await readFile(artifactpath, "utf8")) as { release: string };
|
|
138
|
+
if (stored.release !== packagejson.version) await execute("node", ["tests/recipes.mjs"]);
|
|
139
|
+
}
|
|
140
|
+
const stored = existsSync(artifactpath);
|
|
141
|
+
if (built) expect(stored).toBe(true);
|
|
142
|
+
if (!stored) return;
|
|
143
|
+
const gallery = JSON.parse(await readFile(gallerypath, "utf8")) as galleryindex;
|
|
144
|
+
const report = JSON.parse(await readFile(artifactpath, "utf8")) as recipereport;
|
|
145
|
+
/* the artifact answers the current release with every entry passing and every check ok */
|
|
146
|
+
expect(report.release).toBe(packagejson.version);
|
|
147
|
+
expect(report.gallery.entries).toBe(36);
|
|
148
|
+
expect(report.gallery.categories).toEqual(expectedcategories);
|
|
149
|
+
expect(report.summary.failed).toBe(0);
|
|
150
|
+
expect(report.summary.passed).toBe(report.summary.entries);
|
|
151
|
+
expect(report.summary.checksok).toBe(report.summary.checks);
|
|
152
|
+
/* the recorded entries cover every entry of the gallery index exactly, each with a passing outcome and a recorded duration */
|
|
153
|
+
expect(report.entries.map((entry) => entry.id).sort()).toEqual(gallery.entries.map((entry) => entry.id).sort());
|
|
154
|
+
expect(report.entries.every((entry) => entry.outcome === "pass")).toBe(true);
|
|
155
|
+
expect(report.entries.every((entry) => entry.durationms >= 0)).toBe(true);
|
|
156
|
+
/* the four fixture pages ship beside the recipes in the sources and in the built fixture set the packages carry */
|
|
157
|
+
const sourcepages = new Set((await readdir(pagesdirectory)).filter((file) => file.endsWith(".html")));
|
|
158
|
+
for (const page of gallery.fixturepages) {
|
|
159
|
+
expect(sourcepages.has(page.name)).toBe(true);
|
|
160
|
+
if (built) expect(existsSync(join("dist", "fixtures", "pages", page.name))).toBe(true);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
capturesurfaceof,
|
|
4
|
+
fieldshaperegions,
|
|
5
|
+
mergeregions,
|
|
6
|
+
redactedshot,
|
|
7
|
+
redactionsummary,
|
|
8
|
+
regionof,
|
|
9
|
+
regionvalid,
|
|
10
|
+
regionsfor,
|
|
11
|
+
templateof,
|
|
12
|
+
} from "../capture.js";
|
|
13
|
+
|
|
14
|
+
const now = 1_800_000_000_000;
|
|
15
|
+
|
|
16
|
+
describe("redactshots", () => {
|
|
17
|
+
it("builds regions with finite positive geometry and a plain language reason", () => {
|
|
18
|
+
const region = regionof({
|
|
19
|
+
origin: "https://bank.example",
|
|
20
|
+
template: "login",
|
|
21
|
+
x: 10,
|
|
22
|
+
y: 20,
|
|
23
|
+
width: 200,
|
|
24
|
+
height: 40,
|
|
25
|
+
reason: "The card number field the user masked.",
|
|
26
|
+
source: "userdrawn",
|
|
27
|
+
now,
|
|
28
|
+
});
|
|
29
|
+
expect(region.id).not.toBe("");
|
|
30
|
+
expect(region.x).toBe(10);
|
|
31
|
+
expect(region.source).toBe("userdrawn");
|
|
32
|
+
expect(regionvalid(region)).toBe(true);
|
|
33
|
+
expect(() =>
|
|
34
|
+
regionof({
|
|
35
|
+
origin: "https://bank.example",
|
|
36
|
+
template: "login",
|
|
37
|
+
x: -1,
|
|
38
|
+
y: 0,
|
|
39
|
+
width: 10,
|
|
40
|
+
height: 10,
|
|
41
|
+
reason: "r",
|
|
42
|
+
source: "userdrawn",
|
|
43
|
+
now,
|
|
44
|
+
}),
|
|
45
|
+
).toThrow(/non-negative/);
|
|
46
|
+
expect(() =>
|
|
47
|
+
regionof({
|
|
48
|
+
origin: "https://bank.example",
|
|
49
|
+
template: "login",
|
|
50
|
+
x: 0,
|
|
51
|
+
y: 0,
|
|
52
|
+
width: 0,
|
|
53
|
+
height: 10,
|
|
54
|
+
reason: "r",
|
|
55
|
+
source: "userdrawn",
|
|
56
|
+
now,
|
|
57
|
+
}),
|
|
58
|
+
).toThrow(/positive width/);
|
|
59
|
+
expect(() =>
|
|
60
|
+
regionof({
|
|
61
|
+
origin: "",
|
|
62
|
+
template: "login",
|
|
63
|
+
x: 0,
|
|
64
|
+
y: 0,
|
|
65
|
+
width: 10,
|
|
66
|
+
height: 10,
|
|
67
|
+
reason: "r",
|
|
68
|
+
source: "userdrawn",
|
|
69
|
+
now,
|
|
70
|
+
}),
|
|
71
|
+
).toThrow(/origin/);
|
|
72
|
+
expect(() =>
|
|
73
|
+
regionof({
|
|
74
|
+
origin: "https://bank.example",
|
|
75
|
+
template: "login",
|
|
76
|
+
x: 0,
|
|
77
|
+
y: 0,
|
|
78
|
+
width: 10,
|
|
79
|
+
height: 10,
|
|
80
|
+
reason: " ",
|
|
81
|
+
source: "userdrawn",
|
|
82
|
+
now,
|
|
83
|
+
}),
|
|
84
|
+
).toThrow(/reason/);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("derives regions from the sensitive field shapes of a form layout", () => {
|
|
88
|
+
const regions = fieldshaperegions({
|
|
89
|
+
origin: "https://bank.example",
|
|
90
|
+
template: "login",
|
|
91
|
+
fields: [
|
|
92
|
+
{ name: "username", rect: { x: 0, y: 0, width: 100, height: 20 } },
|
|
93
|
+
{ name: "password", rect: { x: 0, y: 30, width: 100, height: 20 } },
|
|
94
|
+
{ name: "cardnumber", rect: { x: 0, y: 60, width: 100, height: 20 } },
|
|
95
|
+
],
|
|
96
|
+
now,
|
|
97
|
+
});
|
|
98
|
+
expect(regions).toHaveLength(2);
|
|
99
|
+
expect(regions.every((region) => region.source === "fieldshape")).toBe(true);
|
|
100
|
+
expect(regions[0]?.reason).toMatch(/password field carries a sensitive field shape/);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("scopes the regions of one origin and one page template only", () => {
|
|
104
|
+
const region = regionof({
|
|
105
|
+
origin: "https://bank.example",
|
|
106
|
+
template: "login",
|
|
107
|
+
x: 0,
|
|
108
|
+
y: 0,
|
|
109
|
+
width: 10,
|
|
110
|
+
height: 10,
|
|
111
|
+
reason: "masked",
|
|
112
|
+
source: "userdrawn",
|
|
113
|
+
now,
|
|
114
|
+
});
|
|
115
|
+
expect(regionsfor([region], "https://bank.example", "login")).toHaveLength(1);
|
|
116
|
+
expect(regionsfor([region], "https://bank.example", "checkout")).toHaveLength(0);
|
|
117
|
+
expect(regionsfor([region], "https://other.example", "login")).toHaveLength(0);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("merges drawn regions while keeping one record per geometry", () => {
|
|
121
|
+
const one = regionof({
|
|
122
|
+
origin: "https://bank.example",
|
|
123
|
+
template: "login",
|
|
124
|
+
x: 0,
|
|
125
|
+
y: 0,
|
|
126
|
+
width: 10,
|
|
127
|
+
height: 10,
|
|
128
|
+
reason: "first",
|
|
129
|
+
source: "userdrawn",
|
|
130
|
+
now,
|
|
131
|
+
});
|
|
132
|
+
const same = regionof({
|
|
133
|
+
origin: "https://bank.example",
|
|
134
|
+
template: "login",
|
|
135
|
+
x: 0,
|
|
136
|
+
y: 0,
|
|
137
|
+
width: 10,
|
|
138
|
+
height: 10,
|
|
139
|
+
reason: "duplicate",
|
|
140
|
+
source: "userdrawn",
|
|
141
|
+
now,
|
|
142
|
+
});
|
|
143
|
+
const other = regionof({
|
|
144
|
+
origin: "https://bank.example",
|
|
145
|
+
template: "login",
|
|
146
|
+
x: 50,
|
|
147
|
+
y: 50,
|
|
148
|
+
width: 10,
|
|
149
|
+
height: 10,
|
|
150
|
+
reason: "second",
|
|
151
|
+
source: "userdrawn",
|
|
152
|
+
now,
|
|
153
|
+
});
|
|
154
|
+
expect(mergeregions([one], [same, other])).toHaveLength(2);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it("covers viewport, element and stitched captures alike", () => {
|
|
158
|
+
expect(capturesurfaceof("shotview")).toBe("viewport");
|
|
159
|
+
expect(capturesurfaceof("element")).toBe("element");
|
|
160
|
+
expect(capturesurfaceof("shotfullpage")).toBe("stitched");
|
|
161
|
+
expect(capturesurfaceof("contactsheet")).toBe("stitched");
|
|
162
|
+
expect(capturesurfaceof("recordscreen")).toBe("stitched");
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("reads the template of a capture step from its reviewed options", () => {
|
|
166
|
+
expect(templateof({ kind: "shotview", options: JSON.stringify({ template: "checkout" }) })).toBe("checkout");
|
|
167
|
+
expect(templateof({ kind: "shotview" })).toBe("shotview");
|
|
168
|
+
expect(templateof({ kind: "shotview", options: "not json" })).toBe("shotview");
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("marks stored captures with their redaction evidence before storage", () => {
|
|
172
|
+
const record = { id: "shot", kind: "shotview", bytes: "data:image/png;base64,AAA" };
|
|
173
|
+
expect(redactedshot(record, [])).toEqual(record);
|
|
174
|
+
const masked = redactedshot(record, [
|
|
175
|
+
regionof({
|
|
176
|
+
origin: "https://bank.example",
|
|
177
|
+
template: "login",
|
|
178
|
+
x: 0,
|
|
179
|
+
y: 0,
|
|
180
|
+
width: 10,
|
|
181
|
+
height: 10,
|
|
182
|
+
reason: "masked",
|
|
183
|
+
source: "userdrawn",
|
|
184
|
+
now,
|
|
185
|
+
}),
|
|
186
|
+
]);
|
|
187
|
+
expect(masked.redacted).toBe(true);
|
|
188
|
+
expect(masked.redactedregions).toBe(1);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("summarises the redaction evidence for the audit trail", () => {
|
|
192
|
+
const regions = [
|
|
193
|
+
regionof({
|
|
194
|
+
origin: "https://bank.example",
|
|
195
|
+
template: "login",
|
|
196
|
+
x: 0,
|
|
197
|
+
y: 0,
|
|
198
|
+
width: 10,
|
|
199
|
+
height: 10,
|
|
200
|
+
reason: "the card field",
|
|
201
|
+
source: "userdrawn",
|
|
202
|
+
now,
|
|
203
|
+
}),
|
|
204
|
+
...fieldshaperegions({
|
|
205
|
+
origin: "https://bank.example",
|
|
206
|
+
template: "login",
|
|
207
|
+
fields: [{ name: "password", rect: { x: 0, y: 20, width: 10, height: 10 } }],
|
|
208
|
+
now,
|
|
209
|
+
}),
|
|
210
|
+
];
|
|
211
|
+
const summary = redactionsummary(regions);
|
|
212
|
+
expect(summary).toMatch(/2 redact regions/);
|
|
213
|
+
expect(summary).toMatch(/1 derived from sensitive field shapes and 1 drawn by the user/);
|
|
214
|
+
expect(redactionsummary([])).toMatch(/No redact region/);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* register-nvidia-keys.ts
|
|
3
|
+
* registers 22 nvidia api keys into the db nvidiaKey table
|
|
4
|
+
* source: extracted from git blobs in the original gateway repo
|
|
5
|
+
* run with: bun run scripts/register-nvidia-keys.ts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { db } from "../database";
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
console.log("[register-nvidia-keys] starting...");
|
|
14
|
+
|
|
15
|
+
const keysFile = join(process.cwd(), "scripts", "nvidia-keys.json");
|
|
16
|
+
const keysRaw = readFileSync(keysFile, "utf8");
|
|
17
|
+
const keys = JSON.parse(keysRaw) as Array<{ label: string; key: string }>;
|
|
18
|
+
|
|
19
|
+
console.log("[register-nvidia-keys] loaded", keys.length, "keys from", keysFile);
|
|
20
|
+
|
|
21
|
+
/** clear existing keys */
|
|
22
|
+
console.log("[register-nvidia-keys] clearing existing keys...");
|
|
23
|
+
await db.nvidiaKey.deleteMany({});
|
|
24
|
+
|
|
25
|
+
/** register the 22 keys */
|
|
26
|
+
console.log("[register-nvidia-keys] registering", keys.length, "keys...");
|
|
27
|
+
for (const k of keys) {
|
|
28
|
+
await db.nvidiaKey.create({
|
|
29
|
+
data: {
|
|
30
|
+
keyValue: k.key,
|
|
31
|
+
label: k.label,
|
|
32
|
+
active: true,
|
|
33
|
+
status: "active",
|
|
34
|
+
errorCount: 0,
|
|
35
|
+
successCount: 0,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
console.log("[register-nvidia-keys] registered:", k.label);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** verify */
|
|
42
|
+
const count = await db.nvidiaKey.count({ where: { active: true, status: "active" } });
|
|
43
|
+
console.log("[register-nvidia-keys] SUCCESS - total active keys:", count);
|
|
44
|
+
|
|
45
|
+
await db.$disconnect();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
main().catch((err) => {
|
|
49
|
+
console.error("[register-nvidia-keys] ERROR:", err.message);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
});
|