onbuzz 4.9.13 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node_modules/glob/README.md +31 -5
- package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
- package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/glob.js +2 -1
- package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.min.js +3 -3
- package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
- package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/pattern.js +4 -0
- package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
- package/node_modules/glob/dist/esm/glob.d.ts +8 -0
- package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/glob.js +2 -1
- package/node_modules/glob/dist/esm/glob.js.map +1 -1
- package/node_modules/glob/dist/esm/index.min.js +3 -3
- package/node_modules/glob/dist/esm/index.min.js.map +4 -4
- package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
- package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/pattern.js +4 -0
- package/node_modules/glob/dist/esm/pattern.js.map +1 -1
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/README.md +7 -10
- package/node_modules/{@isaacs → glob/node_modules}/balanced-match/package.json +7 -18
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/README.md +3 -6
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.js +6 -4
- package/node_modules/glob/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
- package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/package.json +11 -7
- package/node_modules/glob/node_modules/minimatch/README.md +76 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +4 -2
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +309 -55
- package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +2 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +4 -4
- package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +81 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +232 -134
- package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -1
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +8 -8
- package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
- package/node_modules/glob/node_modules/minimatch/package.json +17 -11
- package/node_modules/glob/package.json +10 -13
- package/node_modules/minipass/LICENSE.md +55 -0
- package/node_modules/minipass/dist/commonjs/index.d.ts +12 -16
- package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/commonjs/index.js +13 -3
- package/node_modules/minipass/dist/commonjs/index.js.map +1 -1
- package/node_modules/minipass/dist/esm/index.d.ts +12 -16
- package/node_modules/minipass/dist/esm/index.d.ts.map +1 -1
- package/node_modules/minipass/dist/esm/index.js +3 -1
- package/node_modules/minipass/dist/esm/index.js.map +1 -1
- package/node_modules/minipass/package.json +9 -14
- package/node_modules/path-scurry/node_modules/lru-cache/README.md +96 -10
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +334 -197
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +109 -32
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +333 -196
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +1 -1
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
- package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
- package/node_modules/path-scurry/node_modules/lru-cache/package.json +71 -18
- package/node_modules/path-scurry/package.json +8 -24
- package/package.json +1 -1
- package/scripts/debug-balance-probe.mjs +35 -35
- package/scripts/push-image.sh +43 -43
- package/scripts/setup-acr.sh +65 -65
- package/scripts/verify-optional-deps.js +96 -1
- package/src/__tests__/composioCliFlags.test.js +239 -239
- package/src/analyzers/CSSAnalyzer.js +298 -297
- package/src/analyzers/ConfigValidator.js +691 -690
- package/src/analyzers/ESLintAnalyzer.js +320 -320
- package/src/analyzers/JavaScriptAnalyzer.js +260 -261
- package/src/analyzers/PrettierFormatter.js +246 -247
- package/src/analyzers/PythonAnalyzer.js +283 -283
- package/src/analyzers/SecurityAnalyzer.js +729 -729
- package/src/analyzers/SparrowAnalyzer.js +341 -341
- package/src/analyzers/TypeScriptAnalyzer.js +247 -247
- package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -41
- package/src/analyzers/__tests__/ConfigValidator.test.js +362 -362
- package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -40
- package/src/analyzers/__tests__/PythonAnalyzer.test.js +205 -208
- package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -303
- package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -187
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -344
- package/src/analyzers/codeCloneDetector/detector.js +250 -250
- package/src/analyzers/codeCloneDetector/index.js +194 -192
- package/src/analyzers/codeCloneDetector/parser.js +199 -199
- package/src/core/__tests__/agentPool.test.js +866 -866
- package/src/core/__tests__/agentPoolAutoResume.test.js +209 -209
- package/src/core/__tests__/agentPoolWakeOnMessage.test.js +315 -315
- package/src/core/__tests__/agentScheduler.emptyResponseChatStall.test.js +213 -213
- package/src/core/__tests__/agentScheduler.errorCategorisation.test.js +246 -246
- package/src/core/__tests__/agentScheduler.firstChunkTimeout.test.js +138 -138
- package/src/core/__tests__/agentScheduler.modeTransitions.test.js +233 -233
- package/src/core/__tests__/agentScheduler.nativePromptPick.test.js +319 -319
- package/src/core/__tests__/agentScheduler.taskLifecycleInstruction.test.js +78 -78
- package/src/core/__tests__/agentScheduler.visualizer.test.js +258 -258
- package/src/core/__tests__/flowCheckpointStore.test.js +140 -140
- package/src/core/__tests__/flowEndToEnd.test.js +565 -565
- package/src/core/__tests__/flowFieldMapping.test.js +188 -189
- package/src/core/__tests__/flowLintClientMirror.test.js +96 -98
- package/src/core/__tests__/flowSavePayload.test.js +170 -169
- package/src/core/__tests__/flowTemplates.test.js +311 -311
- package/src/core/__tests__/flowVersionStore.test.js +123 -123
- package/src/core/__tests__/messageProcessor.test.js +669 -669
- package/src/core/__tests__/stateManager.test.js +0 -1
- package/src/core/agentPool.js +2474 -2475
- package/src/core/agentScheduler.js +1 -4
- package/src/core/contextManager.js +708 -708
- package/src/core/flowExecutor.js +1510 -1510
- package/src/core/flowFieldMapping.js +136 -138
- package/src/core/messageProcessor.js +953 -954
- package/src/core/orchestrator.js +593 -595
- package/src/core/stateManager.js +1765 -1752
- package/src/index.js +1221 -1221
- package/src/interfaces/__tests__/archivedAgentDelete.test.js +207 -207
- package/src/interfaces/__tests__/bulkAgentRoute.test.js +361 -361
- package/src/interfaces/__tests__/imageServing.test.js +228 -228
- package/src/interfaces/__tests__/remoteSessionAuth.test.js +308 -308
- package/src/interfaces/__tests__/videoJobsRoutes.test.js +178 -179
- package/src/interfaces/__tests__/webServer.marketplace.test.js +629 -629
- package/src/interfaces/schedulerRoutes.js +50 -50
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +341 -350
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -156
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +325 -330
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +385 -388
- package/src/interfaces/terminal/api/session.js +265 -266
- package/src/interfaces/terminal/api/websocket.js +496 -497
- package/src/interfaces/terminal/components/AgentCreator.js +691 -705
- package/src/interfaces/terminal/components/AgentEditor.js +676 -678
- package/src/interfaces/terminal/components/AgentSwitcher.js +331 -330
- package/src/interfaces/terminal/components/ErrorPanel.js +263 -264
- package/src/interfaces/terminal/components/Header.js +28 -28
- package/src/interfaces/terminal/components/Layout.js +598 -603
- package/src/interfaces/terminal/components/MessageList.js +280 -281
- package/src/interfaces/terminal/components/SettingsPanel.js +410 -415
- package/src/interfaces/terminal/components/StatusBar.js +2 -0
- package/src/interfaces/terminal/index.js +168 -168
- package/src/interfaces/terminal/state/useAgentControl.js +496 -496
- package/src/interfaces/terminal/state/useAgents.js +537 -537
- package/src/interfaces/terminal/state/useMessages.js +629 -630
- package/src/interfaces/terminal/state/useTools.js +554 -554
- package/src/interfaces/terminal/utils/debugLogger.js +44 -44
- package/src/interfaces/terminal/utils/settingsStorage.js +232 -232
- package/src/interfaces/webServer.js +7578 -7579
- package/src/interfaces/webServer.js.bak +7046 -7046
- package/src/modules/fileExplorer/__tests__/zipDownload.test.js +237 -237
- package/src/modules/fileExplorer/controller.js +470 -469
- package/src/modules/fileExplorer/routes.js +285 -286
- package/src/modules/widget/__tests__/isDisabled.test.js +41 -41
- package/src/modules/widget/__tests__/routes.test.js +677 -678
- package/src/modules/widget/__tests__/runtime.test.js +401 -401
- package/src/modules/widget/__tests__/versioning.test.js +309 -309
- package/src/modules/widget/__tests__/webComponentRuntime.test.js +565 -565
- package/src/modules/widget/__tests__/widgetTool.test.js +316 -316
- package/src/modules/widget/routes.js +435 -435
- package/src/modules/widget/runtime/bundle.js +640 -640
- package/src/modules/widget/runtime/webComponentBundle.js +470 -470
- package/src/modules/widget/schema.js +182 -181
- package/src/modules/widget/widgetTool.js +1389 -1389
- package/src/services/__tests__/agentActivityService.test.js +401 -402
- package/src/services/__tests__/benchmarkService.test.js +184 -184
- package/src/services/__tests__/contextInjectionService.test.js +246 -246
- package/src/services/__tests__/conversationQuery.test.js +721 -723
- package/src/services/__tests__/credentialVault.test.js +469 -469
- package/src/services/__tests__/discordService.integration.test.js +638 -639
- package/src/services/__tests__/flowContextService.test.js +590 -590
- package/src/services/__tests__/memoryService.test.js +1 -1
- package/src/services/__tests__/messageSource.test.js +380 -380
- package/src/services/__tests__/modelRouterNaming.test.js +111 -111
- package/src/services/__tests__/projectDetector.test.js +34 -34
- package/src/services/__tests__/promptService.test.js +242 -242
- package/src/services/__tests__/telegramService.test.js +941 -941
- package/src/services/__tests__/tokenCountingService.test.js +48 -48
- package/src/services/agentActivityService.js +419 -420
- package/src/services/aiService.js +2997 -3001
- package/src/services/apiKeyManager.js +359 -359
- package/src/services/benchmarkService.js +196 -196
- package/src/services/codebaseKnowledgeService.js +2 -2
- package/src/services/composioService.js +738 -738
- package/src/services/conversationCompactionService.js +1258 -1257
- package/src/services/credentialVault.js +685 -685
- package/src/services/discordService.js +792 -793
- package/src/services/embeddings/__tests__/azureCustomProvider.test.js +232 -232
- package/src/services/embeddings/__tests__/embeddingService.test.js +417 -417
- package/src/services/embeddings/__tests__/localProvider.test.js +263 -263
- package/src/services/embeddings/autoRecall.js +218 -219
- package/src/services/embeddings/indexers/__tests__/agentIndexer.test.js +232 -232
- package/src/services/embeddings/indexers/__tests__/memoryIndexer.test.js +418 -418
- package/src/services/embeddings/indexers/__tests__/reminisceIndexer.test.js +356 -357
- package/src/services/embeddings/indexers/__tests__/skillsIndexer.test.js +145 -145
- package/src/services/embeddings/indexers/__tests__/taskIndexer.test.js +146 -146
- package/src/services/embeddings/indexers/composioIndexer.js +279 -279
- package/src/services/embeddings/providerInterface.js +206 -206
- package/src/services/embeddings/providers/localProvider.js +11 -7
- package/src/services/embeddings/providers/openaiProvider.js +101 -101
- package/src/services/embeddings/vectorStore/inMemoryJsonStore.js +356 -356
- package/src/services/errorHandler.js +809 -809
- package/src/services/flowContextService.js +586 -586
- package/src/services/grounding/MockAdapter.js +125 -125
- package/src/services/modelRouterService.js +26 -31
- package/src/services/modelsService.js +322 -322
- package/src/services/ollamaService.js +452 -452
- package/src/services/projectDetector.js +403 -404
- package/src/services/promptService.js +418 -418
- package/src/services/qualityInspector.js +795 -795
- package/src/services/scheduleService.js +726 -726
- package/src/services/serviceRegistry.js +386 -386
- package/src/services/telegrafBot.js +174 -174
- package/src/services/telegramService.js +1972 -1972
- package/src/services/visualEditorBridge.js +1033 -1033
- package/src/services/visualEditorServer.js +1769 -1774
- package/src/services/whatsappService.js +667 -668
- package/src/tools/__tests__/agentCommunicationTool.findAgent.test.js +226 -226
- package/src/tools/__tests__/agentCommunicationTool.test.js +3 -3
- package/src/tools/__tests__/agentDelayTool.test.js +342 -342
- package/src/tools/__tests__/baseTool.test.js +3 -3
- package/src/tools/__tests__/codeMapTool.test.js +915 -915
- package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -309
- package/src/tools/__tests__/fileTreeTool.test.js +274 -274
- package/src/tools/__tests__/filesystemTool.test.js +815 -815
- package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -252
- package/src/tools/__tests__/imageTool.validator.test.js +194 -194
- package/src/tools/__tests__/jobDoneTool.test.js +580 -581
- package/src/tools/__tests__/memoryTool.forgetStale.test.js +272 -272
- package/src/tools/__tests__/memoryTool.reminisce.test.js +2 -2
- package/src/tools/__tests__/memoryTool.reminisceSemanticSearch.test.js +301 -301
- package/src/tools/__tests__/memoryTool.semanticSearch.test.js +405 -405
- package/src/tools/__tests__/memoryTool.teamPool.test.js +293 -293
- package/src/tools/__tests__/memoryTool.test.js +1 -1
- package/src/tools/__tests__/seekTool.test.js +282 -282
- package/src/tools/__tests__/skillsTool.search.test.js +164 -164
- package/src/tools/__tests__/skillsTool.test.js +226 -226
- package/src/tools/__tests__/staticAnalysisTool.test.js +509 -509
- package/src/tools/__tests__/taskManagerTool.discipline.test.js +137 -137
- package/src/tools/__tests__/taskManagerTool.search.test.js +143 -143
- package/src/tools/__tests__/taskManagerTool.test.js +866 -866
- package/src/tools/__tests__/terminalTool.test.js +448 -448
- package/src/tools/__tests__/toolShapeForgiveness.test.js +259 -260
- package/src/tools/__tests__/userPromptTool.test.js +297 -297
- package/src/tools/__tests__/videoTool.jobs.test.js +147 -147
- package/src/tools/__tests__/webTool.e2e.test.js +609 -603
- package/src/tools/__tests__/webTool.unit.test.js +195 -195
- package/src/tools/__tests__/webTool.visionModel.test.js +75 -75
- package/src/tools/agentCommunicationTool.js +8 -10
- package/src/tools/agentDelayTool.js +496 -497
- package/src/tools/asyncToolManager.js +602 -603
- package/src/tools/baseTool.js +12 -11
- package/src/tools/cloneDetectionTool.js +576 -581
- package/src/tools/codeMapTool.js +0 -6
- package/src/tools/composioTool.js +617 -617
- package/src/tools/dependencyResolverTool.js +1211 -1212
- package/src/tools/desktop/DesktopTool.js +629 -638
- package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -306
- package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -507
- package/src/tools/desktop/__tests__/osController.test.js +364 -364
- package/src/tools/desktop/osController.js +491 -491
- package/src/tools/docxTool.js +623 -623
- package/src/tools/excelTool.js +636 -636
- package/src/tools/fileContentReplaceTool.js +5 -7
- package/src/tools/fileSystemTool.js +12 -19
- package/src/tools/fileTreeTool.js +840 -840
- package/src/tools/foundryWebSearchTool.js +273 -273
- package/src/tools/helpTool.js +198 -198
- package/src/tools/imageTool.js +1397 -1397
- package/src/tools/importAnalyzerTool.js +1056 -1056
- package/src/tools/jobDoneTool.js +495 -495
- package/src/tools/memoryTool.js +1 -1
- package/src/tools/office/pres/__tests__/presSystem.test.js +365 -365
- package/src/tools/office/pres/archetypes/agenda.js +61 -61
- package/src/tools/office/pres/archetypes/bentoGrid.js +218 -219
- package/src/tools/office/pres/archetypes/bigStat.js +140 -142
- package/src/tools/office/pres/archetypes/closing.js +70 -70
- package/src/tools/office/pres/archetypes/hero.js +70 -70
- package/src/tools/office/pres/archetypes/productHero.js +93 -94
- package/src/tools/office/pres/archetypes/table.js +73 -74
- package/src/tools/office/pres/backgrounds/orb.js +66 -66
- package/src/tools/office/pres/components.js +422 -423
- package/src/tools/officeTool.js +441 -441
- package/src/tools/pdfTool.js +625 -627
- package/src/tools/platformControlTool.js +1081 -1081
- package/src/tools/seekTool.js +917 -918
- package/src/tools/skillsTool.js +1 -1
- package/src/tools/staticAnalysisTool.js +2143 -2146
- package/src/tools/taskManagerTool.js +3324 -3324
- package/src/tools/terminalTool.js +2615 -2618
- package/src/tools/videoTool.js +1303 -1303
- package/src/tools/visionTool.js +508 -508
- package/src/tools/visualEditorTool.js +1289 -1290
- package/src/tools/webTool.js +3368 -3368
- package/src/tools/whatsappTool.js +464 -464
- package/src/types/__tests__/agent.test.js +499 -499
- package/src/types/__tests__/contextReference.test.js +606 -606
- package/src/types/__tests__/conversation.test.js +555 -555
- package/src/types/__tests__/toolCommand.test.js +584 -584
- package/src/types/contextReference.js +974 -971
- package/src/types/conversation.js +729 -729
- package/src/types/toolCommand.js +746 -746
- package/src/utilities/__tests__/attachmentValidator.test.js +80 -80
- package/src/utilities/__tests__/auditReport.test.js +328 -328
- package/src/utilities/__tests__/directoryAccessManager.test.js +388 -388
- package/src/utilities/__tests__/jsonRepair.test.js +103 -104
- package/src/utilities/__tests__/modeTransitionReasons.test.js +105 -105
- package/src/utilities/__tests__/platformUtils.test.js +80 -87
- package/src/utilities/__tests__/structuredFileValidator.test.js +261 -263
- package/src/utilities/__tests__/toolConstants.test.js +92 -94
- package/src/utilities/__tests__/useIsTouchDevice.detect.test.js +114 -114
- package/src/utilities/__tests__/webUiUtilSync.test.js +117 -117
- package/src/utilities/attachmentValidator.js +284 -288
- package/src/utilities/authCache.js.backup-1779570472481 +121 -121
- package/src/utilities/browserStealth.js +631 -630
- package/src/utilities/configManager.js +616 -617
- package/src/utilities/directoryAccessManager.js +564 -565
- package/src/utilities/fileProcessor.js +308 -307
- package/src/utilities/humanBehavior.js +454 -453
- package/src/utilities/logger.js +479 -479
- package/src/utilities/structuredFileValidator.js +696 -699
- package/src/utilities/tagParser.js +5 -10
- package/src/utilities/userDataDir.js +308 -308
- package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +0 -1
- package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +0 -1
- package/node_modules/minipass/LICENSE +0 -15
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/LICENSE.md +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/LICENSE +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/package.json +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts.map +0 -0
- /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/package.json +0 -0
|
@@ -1,309 +1,309 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Widget versioning — every render appends a new version to the widget's
|
|
3
|
-
* history; the agent (and the user via the artifacts panel) can list
|
|
4
|
-
* versions, pick a specific one as 'main', or fetch a version's content.
|
|
5
|
-
*
|
|
6
|
-
* Backward compatibility: the widget record's TOP-LEVEL fields
|
|
7
|
-
* (.content, .kind, .props, .phishingHits, .size) mirror the active
|
|
8
|
-
* (main) version. Existing consumers keep reading those fields and
|
|
9
|
-
* see whatever's currently main.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, test, expect
|
|
13
|
-
import { WidgetTool } from '../widgetTool.js';
|
|
14
|
-
import { WIDGET_LIMITS } from '../schema.js';
|
|
15
|
-
|
|
16
|
-
const LOGGER = { info() {}, warn() {}, error() {}, debug() {} };
|
|
17
|
-
const ctx = (agentId = 'a') => ({ agentId, toolConfig: { allowCustomCode: true } });
|
|
18
|
-
|
|
19
|
-
function makeTool() { return new WidgetTool({}, LOGGER); }
|
|
20
|
-
|
|
21
|
-
async function render(tool, agentId, widgetId, content, kind = 'html') {
|
|
22
|
-
return tool.execute(
|
|
23
|
-
{ action: 'render', widgetId, kind, content },
|
|
24
|
-
ctx(agentId)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
29
|
-
// Shape: render appends; first render seeds versions[0]
|
|
30
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
31
|
-
|
|
32
|
-
describe('render appends a new version', () => {
|
|
33
|
-
test('first render: versions has length 1, mainVersionId points at it', async () => {
|
|
34
|
-
const tool = makeTool();
|
|
35
|
-
const r = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
36
|
-
expect(r.success).toBe(true);
|
|
37
|
-
expect(r.widget.versions).toHaveLength(1);
|
|
38
|
-
expect(r.widget.mainVersionId).toBe(r.widget.versions[0].versionId);
|
|
39
|
-
expect(r.versionId).toBe(r.widget.versions[0].versionId);
|
|
40
|
-
expect(r.versionCount).toBe(1);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('subsequent renders APPEND, not overwrite — versions grows', async () => {
|
|
44
|
-
const tool = makeTool();
|
|
45
|
-
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
46
|
-
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
47
|
-
const r = await render(tool, 'a', 'w', '<p>v3</p>');
|
|
48
|
-
expect(r.widget.versions).toHaveLength(3);
|
|
49
|
-
expect(r.widget.versions.map(v => v.content)).toEqual(['<p>v1</p>', '<p>v2</p>', '<p>v3</p>']);
|
|
50
|
-
// mainVersion follows the latest by default
|
|
51
|
-
expect(r.widget.mainVersionId).toBe(r.widget.versions[2].versionId);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('mirrored top-level fields reflect the ACTIVE version after each render', async () => {
|
|
55
|
-
const tool = makeTool();
|
|
56
|
-
await render(tool, 'a', 'w', '<p>old</p>', 'html');
|
|
57
|
-
const r = await render(tool, 'a', 'w', '<p>fresh</p>', 'html');
|
|
58
|
-
expect(r.widget.content).toBe('<p>fresh</p>');
|
|
59
|
-
expect(r.widget.kind).toBe('html');
|
|
60
|
-
// size matches the active version's content length in UTF-8 bytes
|
|
61
|
-
expect(r.widget.size).toBe(Buffer.byteLength('<p>fresh</p>', 'utf8'));
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('versionCount stays accurate as versions grow', async () => {
|
|
65
|
-
const tool = makeTool();
|
|
66
|
-
for (let i = 0; i < 5; i++) {
|
|
67
|
-
const r = await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
68
|
-
expect(r.versionCount).toBe(i + 1);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('per-version createdAt is recorded; widget.createdAt stays at v1\'s time', async () => {
|
|
73
|
-
const tool = makeTool();
|
|
74
|
-
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
75
|
-
const t1 = r1.widget.createdAt;
|
|
76
|
-
// Tiny delay to ensure timestamps differ
|
|
77
|
-
await new Promise(r => setTimeout(r, 5));
|
|
78
|
-
const r2 = await render(tool, 'a', 'w', '<p>v2</p>');
|
|
79
|
-
expect(r2.widget.createdAt).toBe(t1); // first-render time, immutable
|
|
80
|
-
expect(r2.widget.versions[0].createdAt).toBe(t1);
|
|
81
|
-
expect(r2.widget.versions[1].createdAt).not.toBe(t1); // v2 has its own time
|
|
82
|
-
// updatedAt mirrors the ACTIVE version's createdAt — useful as
|
|
83
|
-
// "effective-since" timestamp when set-main is used.
|
|
84
|
-
expect(r2.widget.updatedAt).toBe(r2.widget.versions[1].createdAt);
|
|
85
|
-
// lastRenderedAt is always the newest version's time
|
|
86
|
-
expect(r2.widget.lastRenderedAt).toBe(r2.widget.versions[1].createdAt);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
91
|
-
// MAX_VERSIONS_PER_WIDGET cap
|
|
92
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
93
|
-
|
|
94
|
-
describe('version history cap', () => {
|
|
95
|
-
test('beyond MAX_VERSIONS_PER_WIDGET, oldest is evicted; latest stays', async () => {
|
|
96
|
-
const tool = makeTool();
|
|
97
|
-
const cap = WIDGET_LIMITS.MAX_VERSIONS_PER_WIDGET;
|
|
98
|
-
let r;
|
|
99
|
-
for (let i = 0; i < cap + 3; i++) {
|
|
100
|
-
r = await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
101
|
-
}
|
|
102
|
-
expect(r.widget.versions).toHaveLength(cap);
|
|
103
|
-
// Oldest evicted, newest still there
|
|
104
|
-
expect(r.widget.versions[0].content).toBe(`<p>3</p>`);
|
|
105
|
-
expect(r.widget.versions[cap - 1].content).toBe(`<p>${cap + 2}</p>`);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
test('eviction never leaves a dangling mainVersionId', async () => {
|
|
109
|
-
const tool = makeTool();
|
|
110
|
-
const cap = WIDGET_LIMITS.MAX_VERSIONS_PER_WIDGET;
|
|
111
|
-
// Fill to cap, then pin v0 as main, then push more — v0 will be evicted
|
|
112
|
-
await render(tool, 'a', 'w', '<p>v0</p>');
|
|
113
|
-
const list1 = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
114
|
-
const v0Id = list1.versions[0].versionId;
|
|
115
|
-
for (let i = 1; i < cap; i++) await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
116
|
-
await tool.execute({ action: 'set-main', widgetId: 'w', versionId: v0Id }, ctx('a'));
|
|
117
|
-
// Push enough more renders to evict v0
|
|
118
|
-
for (let i = 0; i < 3; i++) await render(tool, 'a', 'w', `<p>extra-${i}</p>`);
|
|
119
|
-
const list2 = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
120
|
-
// mainVersionId no longer references v0; it now points at oldest remaining
|
|
121
|
-
expect(list2.versions.map(v => v.versionId)).not.toContain(v0Id);
|
|
122
|
-
expect(list2.versions.map(v => v.versionId)).toContain(list2.mainVersionId);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
127
|
-
// list-versions
|
|
128
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
129
|
-
|
|
130
|
-
describe('list-versions', () => {
|
|
131
|
-
test('returns version metadata in chronological order, no content', async () => {
|
|
132
|
-
const tool = makeTool();
|
|
133
|
-
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
134
|
-
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
135
|
-
const r = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
136
|
-
expect(r.success).toBe(true);
|
|
137
|
-
expect(r.versions).toHaveLength(2);
|
|
138
|
-
expect(r.versions[0].versionId).toBeTruthy();
|
|
139
|
-
expect(r.versions[0].kind).toBe('html');
|
|
140
|
-
expect(r.versions[0].size).toBeGreaterThan(0);
|
|
141
|
-
// Critical: content is OMITTED so the agent doesn't pay token cost
|
|
142
|
-
// just to enumerate versions
|
|
143
|
-
expect(r.versions[0]).not.toHaveProperty('content');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test('rejects missing widgetId with a NAMED error', async () => {
|
|
147
|
-
const r = await makeTool().execute({ action: 'list-versions' }, ctx('a'));
|
|
148
|
-
expect(r.success).toBe(false);
|
|
149
|
-
expect(r.error).toMatch(/widgetId/);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test('rejects unknown widget with a NAMED error', async () => {
|
|
153
|
-
const r = await makeTool().execute(
|
|
154
|
-
{ action: 'list-versions', widgetId: 'nope' },
|
|
155
|
-
ctx('a')
|
|
156
|
-
);
|
|
157
|
-
expect(r.success).toBe(false);
|
|
158
|
-
expect(r.error).toMatch(/Widget not found/);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
163
|
-
// get-version
|
|
164
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
165
|
-
|
|
166
|
-
describe('get-version', () => {
|
|
167
|
-
test('returns the requested version with content', async () => {
|
|
168
|
-
const tool = makeTool();
|
|
169
|
-
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
170
|
-
const r2 = await render(tool, 'a', 'w', '<p>v2</p>');
|
|
171
|
-
const v1Id = r1.versionId;
|
|
172
|
-
const v2Id = r2.versionId;
|
|
173
|
-
const got = await tool.execute(
|
|
174
|
-
{ action: 'get-version', widgetId: 'w', versionId: v1Id },
|
|
175
|
-
ctx('a')
|
|
176
|
-
);
|
|
177
|
-
expect(got.success).toBe(true);
|
|
178
|
-
expect(got.version.content).toBe('<p>v1</p>');
|
|
179
|
-
expect(got.version.versionId).toBe(v1Id);
|
|
180
|
-
// Get the OTHER version too — they're independent snapshots
|
|
181
|
-
const got2 = await tool.execute(
|
|
182
|
-
{ action: 'get-version', widgetId: 'w', versionId: v2Id },
|
|
183
|
-
ctx('a')
|
|
184
|
-
);
|
|
185
|
-
expect(got2.version.content).toBe('<p>v2</p>');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test('rejects unknown versionId with a NAMED error listing what IS available', async () => {
|
|
189
|
-
const tool = makeTool();
|
|
190
|
-
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
191
|
-
const r = await tool.execute(
|
|
192
|
-
{ action: 'get-version', widgetId: 'w', versionId: 'fake' },
|
|
193
|
-
ctx('a')
|
|
194
|
-
);
|
|
195
|
-
expect(r.success).toBe(false);
|
|
196
|
-
expect(r.error).toMatch(/Version not found/);
|
|
197
|
-
expect(r.error).toMatch(/Available:/);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
test('rejects missing versionId', async () => {
|
|
201
|
-
const tool = makeTool();
|
|
202
|
-
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
203
|
-
const r = await tool.execute(
|
|
204
|
-
{ action: 'get-version', widgetId: 'w' },
|
|
205
|
-
ctx('a')
|
|
206
|
-
);
|
|
207
|
-
expect(r.success).toBe(false);
|
|
208
|
-
expect(r.error).toMatch(/versionId is required/);
|
|
209
|
-
});
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
213
|
-
// set-main — promote a version, mirrored fields update accordingly
|
|
214
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
215
|
-
|
|
216
|
-
describe('set-main', () => {
|
|
217
|
-
test('promoting v1 changes mirrored content + kind back to v1\'s', async () => {
|
|
218
|
-
const tool = makeTool();
|
|
219
|
-
const r1 = await render(tool, 'a', 'w', '<p>v1-content</p>');
|
|
220
|
-
await render(tool, 'a', 'w', '<p>v2-content</p>');
|
|
221
|
-
const v1Id = r1.versionId;
|
|
222
|
-
const r = await tool.execute(
|
|
223
|
-
{ action: 'set-main', widgetId: 'w', versionId: v1Id },
|
|
224
|
-
ctx('a')
|
|
225
|
-
);
|
|
226
|
-
expect(r.success).toBe(true);
|
|
227
|
-
expect(r.widget.mainVersionId).toBe(v1Id);
|
|
228
|
-
expect(r.widget.content).toBe('<p>v1-content</p>'); // mirrored to active
|
|
229
|
-
// Mirrored .updatedAt now reflects v1's createdAt (not v2's)
|
|
230
|
-
expect(r.widget.updatedAt).toBe(r.widget.versions[0].createdAt);
|
|
231
|
-
// But lastRenderedAt is still v2's createdAt (v2 was the most-recent
|
|
232
|
-
// RENDER even though v1 is now MAIN)
|
|
233
|
-
expect(r.widget.lastRenderedAt).toBe(r.widget.versions[1].createdAt);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
test('rejects unknown versionId', async () => {
|
|
237
|
-
const tool = makeTool();
|
|
238
|
-
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
239
|
-
const r = await tool.execute(
|
|
240
|
-
{ action: 'set-main', widgetId: 'w', versionId: 'nope' },
|
|
241
|
-
ctx('a')
|
|
242
|
-
);
|
|
243
|
-
expect(r.success).toBe(false);
|
|
244
|
-
expect(r.error).toMatch(/Version not found/);
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
test('after set-main, subsequent list reports the chosen mainVersionId', async () => {
|
|
248
|
-
const tool = makeTool();
|
|
249
|
-
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
250
|
-
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
251
|
-
await tool.execute(
|
|
252
|
-
{ action: 'set-main', widgetId: 'w', versionId: r1.versionId },
|
|
253
|
-
ctx('a')
|
|
254
|
-
);
|
|
255
|
-
const list = await tool.execute({ action: 'list' }, ctx('a'));
|
|
256
|
-
expect(list.widgets[0].mainVersionId).toBe(r1.versionId);
|
|
257
|
-
expect(list.widgets[0].versionCount).toBe(2);
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
262
|
-
// Backward compatibility: existing top-level reads keep working
|
|
263
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
264
|
-
|
|
265
|
-
describe('backward-compat shape (top-level fields mirror main version)', () => {
|
|
266
|
-
test('widget.content / kind / props / phishingHits / size all read off active version', async () => {
|
|
267
|
-
const tool = makeTool();
|
|
268
|
-
const r = await render(tool, 'a', 'w', '<p>password please</p>');
|
|
269
|
-
expect(r.widget.content).toBe('<p>password please</p>');
|
|
270
|
-
expect(r.widget.kind).toBe('html');
|
|
271
|
-
expect(r.widget.props).toEqual({});
|
|
272
|
-
expect(r.widget.phishingHits).toEqual(expect.arrayContaining(['password']));
|
|
273
|
-
expect(r.widget.size).toBe(Buffer.byteLength('<p>password please</p>', 'utf8'));
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
test('list response carries new fields (versionCount, mainVersionId, gallery linkage) without breaking shape', async () => {
|
|
277
|
-
const tool = makeTool();
|
|
278
|
-
await render(tool, 'a', 'w', '<p>x</p>');
|
|
279
|
-
const r = await tool.execute({ action: 'list' }, ctx('a'));
|
|
280
|
-
expect(r.widgets[0]).toEqual(expect.objectContaining({
|
|
281
|
-
widgetId: 'w',
|
|
282
|
-
kind: 'html',
|
|
283
|
-
versionCount: 1,
|
|
284
|
-
mainVersionId: expect.any(String),
|
|
285
|
-
// Phase 4 fields default safely
|
|
286
|
-
linkedGalleryTemplateId: null,
|
|
287
|
-
linkedGalleryVersion: null,
|
|
288
|
-
divergedFromGallery: false,
|
|
289
|
-
}));
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
294
|
-
// Per-agent isolation — versions don't leak across agents
|
|
295
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
296
|
-
|
|
297
|
-
describe('per-agent isolation', () => {
|
|
298
|
-
test('agent-A\'s widgetId "w" does not see agent-B\'s version history', async () => {
|
|
299
|
-
const tool = makeTool();
|
|
300
|
-
await render(tool, 'a', 'w', '<p>a-v1</p>');
|
|
301
|
-
await render(tool, 'a', 'w', '<p>a-v2</p>');
|
|
302
|
-
await render(tool, 'b', 'w', '<p>b-v1</p>');
|
|
303
|
-
|
|
304
|
-
const a = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
305
|
-
const b = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('b'));
|
|
306
|
-
expect(a.versions).toHaveLength(2);
|
|
307
|
-
expect(b.versions).toHaveLength(1);
|
|
308
|
-
});
|
|
309
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Widget versioning — every render appends a new version to the widget's
|
|
3
|
+
* history; the agent (and the user via the artifacts panel) can list
|
|
4
|
+
* versions, pick a specific one as 'main', or fetch a version's content.
|
|
5
|
+
*
|
|
6
|
+
* Backward compatibility: the widget record's TOP-LEVEL fields
|
|
7
|
+
* (.content, .kind, .props, .phishingHits, .size) mirror the active
|
|
8
|
+
* (main) version. Existing consumers keep reading those fields and
|
|
9
|
+
* see whatever's currently main.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { describe, test, expect } from '@jest/globals';
|
|
13
|
+
import { WidgetTool } from '../widgetTool.js';
|
|
14
|
+
import { WIDGET_LIMITS } from '../schema.js';
|
|
15
|
+
|
|
16
|
+
const LOGGER = { info() {}, warn() {}, error() {}, debug() {} };
|
|
17
|
+
const ctx = (agentId = 'a') => ({ agentId, toolConfig: { allowCustomCode: true } });
|
|
18
|
+
|
|
19
|
+
function makeTool() { return new WidgetTool({}, LOGGER); }
|
|
20
|
+
|
|
21
|
+
async function render(tool, agentId, widgetId, content, kind = 'html') {
|
|
22
|
+
return tool.execute(
|
|
23
|
+
{ action: 'render', widgetId, kind, content },
|
|
24
|
+
ctx(agentId)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
29
|
+
// Shape: render appends; first render seeds versions[0]
|
|
30
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
describe('render appends a new version', () => {
|
|
33
|
+
test('first render: versions has length 1, mainVersionId points at it', async () => {
|
|
34
|
+
const tool = makeTool();
|
|
35
|
+
const r = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
36
|
+
expect(r.success).toBe(true);
|
|
37
|
+
expect(r.widget.versions).toHaveLength(1);
|
|
38
|
+
expect(r.widget.mainVersionId).toBe(r.widget.versions[0].versionId);
|
|
39
|
+
expect(r.versionId).toBe(r.widget.versions[0].versionId);
|
|
40
|
+
expect(r.versionCount).toBe(1);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('subsequent renders APPEND, not overwrite — versions grows', async () => {
|
|
44
|
+
const tool = makeTool();
|
|
45
|
+
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
46
|
+
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
47
|
+
const r = await render(tool, 'a', 'w', '<p>v3</p>');
|
|
48
|
+
expect(r.widget.versions).toHaveLength(3);
|
|
49
|
+
expect(r.widget.versions.map(v => v.content)).toEqual(['<p>v1</p>', '<p>v2</p>', '<p>v3</p>']);
|
|
50
|
+
// mainVersion follows the latest by default
|
|
51
|
+
expect(r.widget.mainVersionId).toBe(r.widget.versions[2].versionId);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('mirrored top-level fields reflect the ACTIVE version after each render', async () => {
|
|
55
|
+
const tool = makeTool();
|
|
56
|
+
await render(tool, 'a', 'w', '<p>old</p>', 'html');
|
|
57
|
+
const r = await render(tool, 'a', 'w', '<p>fresh</p>', 'html');
|
|
58
|
+
expect(r.widget.content).toBe('<p>fresh</p>');
|
|
59
|
+
expect(r.widget.kind).toBe('html');
|
|
60
|
+
// size matches the active version's content length in UTF-8 bytes
|
|
61
|
+
expect(r.widget.size).toBe(Buffer.byteLength('<p>fresh</p>', 'utf8'));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('versionCount stays accurate as versions grow', async () => {
|
|
65
|
+
const tool = makeTool();
|
|
66
|
+
for (let i = 0; i < 5; i++) {
|
|
67
|
+
const r = await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
68
|
+
expect(r.versionCount).toBe(i + 1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('per-version createdAt is recorded; widget.createdAt stays at v1\'s time', async () => {
|
|
73
|
+
const tool = makeTool();
|
|
74
|
+
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
75
|
+
const t1 = r1.widget.createdAt;
|
|
76
|
+
// Tiny delay to ensure timestamps differ
|
|
77
|
+
await new Promise(r => setTimeout(r, 5));
|
|
78
|
+
const r2 = await render(tool, 'a', 'w', '<p>v2</p>');
|
|
79
|
+
expect(r2.widget.createdAt).toBe(t1); // first-render time, immutable
|
|
80
|
+
expect(r2.widget.versions[0].createdAt).toBe(t1);
|
|
81
|
+
expect(r2.widget.versions[1].createdAt).not.toBe(t1); // v2 has its own time
|
|
82
|
+
// updatedAt mirrors the ACTIVE version's createdAt — useful as
|
|
83
|
+
// "effective-since" timestamp when set-main is used.
|
|
84
|
+
expect(r2.widget.updatedAt).toBe(r2.widget.versions[1].createdAt);
|
|
85
|
+
// lastRenderedAt is always the newest version's time
|
|
86
|
+
expect(r2.widget.lastRenderedAt).toBe(r2.widget.versions[1].createdAt);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
91
|
+
// MAX_VERSIONS_PER_WIDGET cap
|
|
92
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
describe('version history cap', () => {
|
|
95
|
+
test('beyond MAX_VERSIONS_PER_WIDGET, oldest is evicted; latest stays', async () => {
|
|
96
|
+
const tool = makeTool();
|
|
97
|
+
const cap = WIDGET_LIMITS.MAX_VERSIONS_PER_WIDGET;
|
|
98
|
+
let r;
|
|
99
|
+
for (let i = 0; i < cap + 3; i++) {
|
|
100
|
+
r = await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
101
|
+
}
|
|
102
|
+
expect(r.widget.versions).toHaveLength(cap);
|
|
103
|
+
// Oldest evicted, newest still there
|
|
104
|
+
expect(r.widget.versions[0].content).toBe(`<p>3</p>`);
|
|
105
|
+
expect(r.widget.versions[cap - 1].content).toBe(`<p>${cap + 2}</p>`);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('eviction never leaves a dangling mainVersionId', async () => {
|
|
109
|
+
const tool = makeTool();
|
|
110
|
+
const cap = WIDGET_LIMITS.MAX_VERSIONS_PER_WIDGET;
|
|
111
|
+
// Fill to cap, then pin v0 as main, then push more — v0 will be evicted
|
|
112
|
+
await render(tool, 'a', 'w', '<p>v0</p>');
|
|
113
|
+
const list1 = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
114
|
+
const v0Id = list1.versions[0].versionId;
|
|
115
|
+
for (let i = 1; i < cap; i++) await render(tool, 'a', 'w', `<p>${i}</p>`);
|
|
116
|
+
await tool.execute({ action: 'set-main', widgetId: 'w', versionId: v0Id }, ctx('a'));
|
|
117
|
+
// Push enough more renders to evict v0
|
|
118
|
+
for (let i = 0; i < 3; i++) await render(tool, 'a', 'w', `<p>extra-${i}</p>`);
|
|
119
|
+
const list2 = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
120
|
+
// mainVersionId no longer references v0; it now points at oldest remaining
|
|
121
|
+
expect(list2.versions.map(v => v.versionId)).not.toContain(v0Id);
|
|
122
|
+
expect(list2.versions.map(v => v.versionId)).toContain(list2.mainVersionId);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
127
|
+
// list-versions
|
|
128
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
describe('list-versions', () => {
|
|
131
|
+
test('returns version metadata in chronological order, no content', async () => {
|
|
132
|
+
const tool = makeTool();
|
|
133
|
+
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
134
|
+
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
135
|
+
const r = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
136
|
+
expect(r.success).toBe(true);
|
|
137
|
+
expect(r.versions).toHaveLength(2);
|
|
138
|
+
expect(r.versions[0].versionId).toBeTruthy();
|
|
139
|
+
expect(r.versions[0].kind).toBe('html');
|
|
140
|
+
expect(r.versions[0].size).toBeGreaterThan(0);
|
|
141
|
+
// Critical: content is OMITTED so the agent doesn't pay token cost
|
|
142
|
+
// just to enumerate versions
|
|
143
|
+
expect(r.versions[0]).not.toHaveProperty('content');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test('rejects missing widgetId with a NAMED error', async () => {
|
|
147
|
+
const r = await makeTool().execute({ action: 'list-versions' }, ctx('a'));
|
|
148
|
+
expect(r.success).toBe(false);
|
|
149
|
+
expect(r.error).toMatch(/widgetId/);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('rejects unknown widget with a NAMED error', async () => {
|
|
153
|
+
const r = await makeTool().execute(
|
|
154
|
+
{ action: 'list-versions', widgetId: 'nope' },
|
|
155
|
+
ctx('a')
|
|
156
|
+
);
|
|
157
|
+
expect(r.success).toBe(false);
|
|
158
|
+
expect(r.error).toMatch(/Widget not found/);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
163
|
+
// get-version
|
|
164
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
165
|
+
|
|
166
|
+
describe('get-version', () => {
|
|
167
|
+
test('returns the requested version with content', async () => {
|
|
168
|
+
const tool = makeTool();
|
|
169
|
+
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
170
|
+
const r2 = await render(tool, 'a', 'w', '<p>v2</p>');
|
|
171
|
+
const v1Id = r1.versionId;
|
|
172
|
+
const v2Id = r2.versionId;
|
|
173
|
+
const got = await tool.execute(
|
|
174
|
+
{ action: 'get-version', widgetId: 'w', versionId: v1Id },
|
|
175
|
+
ctx('a')
|
|
176
|
+
);
|
|
177
|
+
expect(got.success).toBe(true);
|
|
178
|
+
expect(got.version.content).toBe('<p>v1</p>');
|
|
179
|
+
expect(got.version.versionId).toBe(v1Id);
|
|
180
|
+
// Get the OTHER version too — they're independent snapshots
|
|
181
|
+
const got2 = await tool.execute(
|
|
182
|
+
{ action: 'get-version', widgetId: 'w', versionId: v2Id },
|
|
183
|
+
ctx('a')
|
|
184
|
+
);
|
|
185
|
+
expect(got2.version.content).toBe('<p>v2</p>');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('rejects unknown versionId with a NAMED error listing what IS available', async () => {
|
|
189
|
+
const tool = makeTool();
|
|
190
|
+
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
191
|
+
const r = await tool.execute(
|
|
192
|
+
{ action: 'get-version', widgetId: 'w', versionId: 'fake' },
|
|
193
|
+
ctx('a')
|
|
194
|
+
);
|
|
195
|
+
expect(r.success).toBe(false);
|
|
196
|
+
expect(r.error).toMatch(/Version not found/);
|
|
197
|
+
expect(r.error).toMatch(/Available:/);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test('rejects missing versionId', async () => {
|
|
201
|
+
const tool = makeTool();
|
|
202
|
+
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
203
|
+
const r = await tool.execute(
|
|
204
|
+
{ action: 'get-version', widgetId: 'w' },
|
|
205
|
+
ctx('a')
|
|
206
|
+
);
|
|
207
|
+
expect(r.success).toBe(false);
|
|
208
|
+
expect(r.error).toMatch(/versionId is required/);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
213
|
+
// set-main — promote a version, mirrored fields update accordingly
|
|
214
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
describe('set-main', () => {
|
|
217
|
+
test('promoting v1 changes mirrored content + kind back to v1\'s', async () => {
|
|
218
|
+
const tool = makeTool();
|
|
219
|
+
const r1 = await render(tool, 'a', 'w', '<p>v1-content</p>');
|
|
220
|
+
await render(tool, 'a', 'w', '<p>v2-content</p>');
|
|
221
|
+
const v1Id = r1.versionId;
|
|
222
|
+
const r = await tool.execute(
|
|
223
|
+
{ action: 'set-main', widgetId: 'w', versionId: v1Id },
|
|
224
|
+
ctx('a')
|
|
225
|
+
);
|
|
226
|
+
expect(r.success).toBe(true);
|
|
227
|
+
expect(r.widget.mainVersionId).toBe(v1Id);
|
|
228
|
+
expect(r.widget.content).toBe('<p>v1-content</p>'); // mirrored to active
|
|
229
|
+
// Mirrored .updatedAt now reflects v1's createdAt (not v2's)
|
|
230
|
+
expect(r.widget.updatedAt).toBe(r.widget.versions[0].createdAt);
|
|
231
|
+
// But lastRenderedAt is still v2's createdAt (v2 was the most-recent
|
|
232
|
+
// RENDER even though v1 is now MAIN)
|
|
233
|
+
expect(r.widget.lastRenderedAt).toBe(r.widget.versions[1].createdAt);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('rejects unknown versionId', async () => {
|
|
237
|
+
const tool = makeTool();
|
|
238
|
+
await render(tool, 'a', 'w', '<p>v1</p>');
|
|
239
|
+
const r = await tool.execute(
|
|
240
|
+
{ action: 'set-main', widgetId: 'w', versionId: 'nope' },
|
|
241
|
+
ctx('a')
|
|
242
|
+
);
|
|
243
|
+
expect(r.success).toBe(false);
|
|
244
|
+
expect(r.error).toMatch(/Version not found/);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test('after set-main, subsequent list reports the chosen mainVersionId', async () => {
|
|
248
|
+
const tool = makeTool();
|
|
249
|
+
const r1 = await render(tool, 'a', 'w', '<p>v1</p>');
|
|
250
|
+
await render(tool, 'a', 'w', '<p>v2</p>');
|
|
251
|
+
await tool.execute(
|
|
252
|
+
{ action: 'set-main', widgetId: 'w', versionId: r1.versionId },
|
|
253
|
+
ctx('a')
|
|
254
|
+
);
|
|
255
|
+
const list = await tool.execute({ action: 'list' }, ctx('a'));
|
|
256
|
+
expect(list.widgets[0].mainVersionId).toBe(r1.versionId);
|
|
257
|
+
expect(list.widgets[0].versionCount).toBe(2);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
262
|
+
// Backward compatibility: existing top-level reads keep working
|
|
263
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
264
|
+
|
|
265
|
+
describe('backward-compat shape (top-level fields mirror main version)', () => {
|
|
266
|
+
test('widget.content / kind / props / phishingHits / size all read off active version', async () => {
|
|
267
|
+
const tool = makeTool();
|
|
268
|
+
const r = await render(tool, 'a', 'w', '<p>password please</p>');
|
|
269
|
+
expect(r.widget.content).toBe('<p>password please</p>');
|
|
270
|
+
expect(r.widget.kind).toBe('html');
|
|
271
|
+
expect(r.widget.props).toEqual({});
|
|
272
|
+
expect(r.widget.phishingHits).toEqual(expect.arrayContaining(['password']));
|
|
273
|
+
expect(r.widget.size).toBe(Buffer.byteLength('<p>password please</p>', 'utf8'));
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test('list response carries new fields (versionCount, mainVersionId, gallery linkage) without breaking shape', async () => {
|
|
277
|
+
const tool = makeTool();
|
|
278
|
+
await render(tool, 'a', 'w', '<p>x</p>');
|
|
279
|
+
const r = await tool.execute({ action: 'list' }, ctx('a'));
|
|
280
|
+
expect(r.widgets[0]).toEqual(expect.objectContaining({
|
|
281
|
+
widgetId: 'w',
|
|
282
|
+
kind: 'html',
|
|
283
|
+
versionCount: 1,
|
|
284
|
+
mainVersionId: expect.any(String),
|
|
285
|
+
// Phase 4 fields default safely
|
|
286
|
+
linkedGalleryTemplateId: null,
|
|
287
|
+
linkedGalleryVersion: null,
|
|
288
|
+
divergedFromGallery: false,
|
|
289
|
+
}));
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
294
|
+
// Per-agent isolation — versions don't leak across agents
|
|
295
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
296
|
+
|
|
297
|
+
describe('per-agent isolation', () => {
|
|
298
|
+
test('agent-A\'s widgetId "w" does not see agent-B\'s version history', async () => {
|
|
299
|
+
const tool = makeTool();
|
|
300
|
+
await render(tool, 'a', 'w', '<p>a-v1</p>');
|
|
301
|
+
await render(tool, 'a', 'w', '<p>a-v2</p>');
|
|
302
|
+
await render(tool, 'b', 'w', '<p>b-v1</p>');
|
|
303
|
+
|
|
304
|
+
const a = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('a'));
|
|
305
|
+
const b = await tool.execute({ action: 'list-versions', widgetId: 'w' }, ctx('b'));
|
|
306
|
+
expect(a.versions).toHaveLength(2);
|
|
307
|
+
expect(b.versions).toHaveLength(1);
|
|
308
|
+
});
|
|
309
|
+
});
|