@zenalexa/unicli 0.225.0 → 0.225.2
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/AGENTS.md +5 -5
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/adapters/_electron/desktop-shared.d.ts.map +1 -1
- package/dist/adapters/_electron/desktop-shared.js +2 -1
- package/dist/adapters/_electron/desktop-shared.js.map +1 -1
- package/dist/adapters/_electron/shared.d.ts +6 -0
- package/dist/adapters/_electron/shared.d.ts.map +1 -1
- package/dist/adapters/_electron/shared.js +9 -0
- package/dist/adapters/_electron/shared.js.map +1 -1
- package/dist/adapters/antigravity/extra.js +4 -1
- package/dist/adapters/antigravity/extra.js.map +1 -1
- package/dist/adapters/chatwise/extra.js +4 -1
- package/dist/adapters/chatwise/extra.js.map +1 -1
- package/dist/adapters/codex/codex.js +3 -1
- package/dist/adapters/codex/codex.js.map +1 -1
- package/dist/adapters/codex/extra.js +4 -1
- package/dist/adapters/codex/extra.js.map +1 -1
- package/dist/adapters/codex/projects.d.ts.map +1 -1
- package/dist/adapters/codex/projects.js +3 -1
- package/dist/adapters/codex/projects.js.map +1 -1
- package/dist/adapters/cursor/cursor.js +6 -1
- package/dist/adapters/cursor/cursor.js.map +1 -1
- package/dist/adapters/discord-app/discord-app.js +10 -1
- package/dist/adapters/discord-app/discord-app.js.map +1 -1
- package/dist/adapters/notion-app/notion-app.js +11 -1
- package/dist/adapters/notion-app/notion-app.js.map +1 -1
- package/dist/adapters/spotify/api.js +36 -6
- package/dist/adapters/spotify/api.js.map +1 -1
- package/dist/adapters/xiaohongshu/browser-state.d.ts +2 -1
- package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -1
- package/dist/adapters/xiaohongshu/browser-state.js +56 -2
- package/dist/adapters/xiaohongshu/browser-state.js.map +1 -1
- package/dist/adapters/xiaohongshu/feed.d.ts +24 -0
- package/dist/adapters/xiaohongshu/feed.d.ts.map +1 -0
- package/dist/adapters/xiaohongshu/feed.js +82 -0
- package/dist/adapters/xiaohongshu/feed.js.map +1 -0
- package/dist/browser/cdp-client.d.ts +5 -1
- package/dist/browser/cdp-client.d.ts.map +1 -1
- package/dist/browser/cdp-client.js +24 -16
- package/dist/browser/cdp-client.js.map +1 -1
- package/dist/browser/daemon.js +29 -7
- package/dist/browser/daemon.js.map +1 -1
- package/dist/browser/launcher.d.ts.map +1 -1
- package/dist/browser/launcher.js +22 -8
- package/dist/browser/launcher.js.map +1 -1
- package/dist/browser/local-profiles.d.ts +2 -0
- package/dist/browser/local-profiles.d.ts.map +1 -1
- package/dist/browser/local-profiles.js +42 -2
- package/dist/browser/local-profiles.js.map +1 -1
- package/dist/browser/page.d.ts +2 -2
- package/dist/browser/page.d.ts.map +1 -1
- package/dist/browser/page.js +2 -2
- package/dist/browser/page.js.map +1 -1
- package/dist/browser/protocol.d.ts +13 -1
- package/dist/browser/protocol.d.ts.map +1 -1
- package/dist/browser/protocol.js +5 -0
- package/dist/browser/protocol.js.map +1 -1
- package/dist/commands/browser/actions.d.ts.map +1 -1
- package/dist/commands/browser/actions.js +428 -5
- package/dist/commands/browser/actions.js.map +1 -1
- package/dist/commands/browser/index.d.ts.map +1 -1
- package/dist/commands/browser/index.js +26 -4
- package/dist/commands/browser/index.js.map +1 -1
- package/dist/commands/compute.js +12 -1
- package/dist/commands/compute.js.map +1 -1
- package/dist/commands/do.d.ts +15 -13
- package/dist/commands/do.d.ts.map +1 -1
- package/dist/commands/do.js +36 -21
- package/dist/commands/do.js.map +1 -1
- package/dist/commands/schema.d.ts.map +1 -1
- package/dist/commands/schema.js +22 -0
- package/dist/commands/schema.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +14 -3
- package/dist/commands/search.js.map +1 -1
- package/dist/compute/contracts.d.ts +55 -0
- package/dist/compute/contracts.d.ts.map +1 -0
- package/dist/compute/contracts.js +487 -0
- package/dist/compute/contracts.js.map +1 -0
- package/dist/discovery/aliases.d.ts +8 -1
- package/dist/discovery/aliases.d.ts.map +1 -1
- package/dist/discovery/aliases.js +151 -20
- package/dist/discovery/aliases.js.map +1 -1
- package/dist/discovery/core-catalog.d.ts.map +1 -1
- package/dist/discovery/core-catalog.js +39 -67
- package/dist/discovery/core-catalog.js.map +1 -1
- package/dist/discovery/intents.d.ts +32 -4
- package/dist/discovery/intents.d.ts.map +1 -1
- package/dist/discovery/intents.js +192 -3
- package/dist/discovery/intents.js.map +1 -1
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +3 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/discovery/macos-dynamic.d.ts +1 -0
- package/dist/discovery/macos-dynamic.d.ts.map +1 -1
- package/dist/discovery/macos-dynamic.js +20 -1
- package/dist/discovery/macos-dynamic.js.map +1 -1
- package/dist/discovery/search.d.ts.map +1 -1
- package/dist/discovery/search.js +21 -5
- package/dist/discovery/search.js.map +1 -1
- package/dist/engine/browser/evidence.d.ts +34 -1
- package/dist/engine/browser/evidence.d.ts.map +1 -1
- package/dist/engine/browser/evidence.js +141 -6
- package/dist/engine/browser/evidence.js.map +1 -1
- package/dist/engine/kernel/stages.d.ts.map +1 -1
- package/dist/engine/kernel/stages.js +14 -4
- package/dist/engine/kernel/stages.js.map +1 -1
- package/dist/engine/objective/catalog.d.ts +23 -0
- package/dist/engine/objective/catalog.d.ts.map +1 -0
- package/dist/engine/objective/catalog.js +42 -0
- package/dist/engine/objective/catalog.js.map +1 -0
- package/dist/engine/objective/delivery.d.ts +18 -0
- package/dist/engine/objective/delivery.d.ts.map +1 -0
- package/dist/engine/objective/delivery.js +64 -0
- package/dist/engine/objective/delivery.js.map +1 -0
- package/dist/engine/objective/index.d.ts +20 -0
- package/dist/engine/objective/index.d.ts.map +1 -0
- package/dist/engine/objective/index.js +20 -0
- package/dist/engine/objective/index.js.map +1 -0
- package/dist/engine/objective/media-playback.d.ts +17 -0
- package/dist/engine/objective/media-playback.d.ts.map +1 -0
- package/dist/engine/objective/media-playback.js +186 -0
- package/dist/engine/objective/media-playback.js.map +1 -0
- package/dist/engine/objective/output.d.ts +20 -0
- package/dist/engine/objective/output.d.ts.map +1 -0
- package/dist/engine/objective/output.js +88 -0
- package/dist/engine/objective/output.js.map +1 -0
- package/dist/engine/objective/planner.d.ts +17 -0
- package/dist/engine/objective/planner.d.ts.map +1 -0
- package/dist/engine/objective/planner.js +60 -0
- package/dist/engine/objective/planner.js.map +1 -0
- package/dist/engine/objective/types.d.ts +66 -0
- package/dist/engine/objective/types.d.ts.map +1 -0
- package/dist/engine/objective/types.js +16 -0
- package/dist/engine/objective/types.js.map +1 -0
- package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
- package/dist/engine/steps/browser-helpers.js +34 -0
- package/dist/engine/steps/browser-helpers.js.map +1 -1
- package/dist/engine/steps/fetch-text.d.ts.map +1 -1
- package/dist/engine/steps/fetch-text.js +2 -2
- package/dist/engine/steps/fetch-text.js.map +1 -1
- package/dist/engine/steps/fetch.d.ts +1 -0
- package/dist/engine/steps/fetch.d.ts.map +1 -1
- package/dist/engine/steps/fetch.js +24 -4
- package/dist/engine/steps/fetch.js.map +1 -1
- package/dist/fast-path/handlers/discovery.d.ts +5 -5
- package/dist/fast-path/handlers/discovery.d.ts.map +1 -1
- package/dist/fast-path/handlers/discovery.js +61 -8
- package/dist/fast-path/handlers/discovery.js.map +1 -1
- package/dist/fast-path/render.d.ts +2 -0
- package/dist/fast-path/render.d.ts.map +1 -1
- package/dist/fast-path/render.js +9 -0
- package/dist/fast-path/render.js.map +1 -1
- package/dist/manifest-compact.txt +3 -2
- package/dist/manifest.json +215 -17
- package/dist/mcp/handler.d.ts +2 -16
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js.map +1 -1
- package/dist/mcp/http-transport.d.ts +7 -1
- package/dist/mcp/http-transport.d.ts.map +1 -1
- package/dist/mcp/http-transport.js +20 -1
- package/dist/mcp/http-transport.js.map +1 -1
- package/dist/mcp/jsonrpc.d.ts +27 -0
- package/dist/mcp/jsonrpc.d.ts.map +1 -0
- package/dist/mcp/jsonrpc.js +12 -0
- package/dist/mcp/jsonrpc.js.map +1 -0
- package/dist/mcp/origin-guard.d.ts +26 -0
- package/dist/mcp/origin-guard.d.ts.map +1 -0
- package/dist/mcp/origin-guard.js +42 -0
- package/dist/mcp/origin-guard.js.map +1 -0
- package/dist/mcp/profiles/computer-use.d.ts.map +1 -1
- package/dist/mcp/profiles/computer-use.js +30 -270
- package/dist/mcp/profiles/computer-use.js.map +1 -1
- package/dist/mcp/streamable-http/session.d.ts +4 -22
- package/dist/mcp/streamable-http/session.d.ts.map +1 -1
- package/dist/mcp/streamable-http/session.js +4 -24
- package/dist/mcp/streamable-http/session.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +74 -54
- package/dist/mcp/tools.js.map +1 -1
- package/dist/output/envelope.d.ts +2 -0
- package/dist/output/envelope.d.ts.map +1 -1
- package/dist/output/envelope.js.map +1 -1
- package/dist/output/error-map.d.ts +14 -0
- package/dist/output/error-map.d.ts.map +1 -1
- package/dist/output/error-map.js +20 -0
- package/dist/output/error-map.js.map +1 -1
- package/dist/transport/cascade.d.ts.map +1 -1
- package/dist/transport/cascade.js +77 -5
- package/dist/transport/cascade.js.map +1 -1
- package/dist/transport/refs.d.ts +33 -1
- package/dist/transport/refs.d.ts.map +1 -1
- package/dist/transport/refs.js +40 -1
- package/dist/transport/refs.js.map +1 -1
- package/package.json +3 -1
- package/server.json +2 -2
- package/skills/unicli/SKILL.md +1 -1
- package/skills/unicli-claude-code/SKILL.md +1 -1
- package/skills/unicli-hermes/SKILL.md +1 -1
- package/src/adapters/_electron/desktop-shared.ts +5 -1
- package/src/adapters/_electron/shared.ts +15 -0
- package/src/adapters/antigravity/extra.ts +10 -1
- package/src/adapters/chatwise/extra.ts +10 -1
- package/src/adapters/codex/codex.ts +6 -0
- package/src/adapters/codex/extra.ts +10 -1
- package/src/adapters/codex/projects.ts +9 -1
- package/src/adapters/cursor/cursor.ts +9 -0
- package/src/adapters/defuddle/read.yaml +30 -0
- package/src/adapters/discord-app/discord-app.ts +16 -1
- package/src/adapters/jina/read.yaml +30 -0
- package/src/adapters/macos/brightness.yaml +6 -3
- package/src/adapters/macos/calendar-list.yaml +9 -11
- package/src/adapters/macos/calendar-today.yaml +1 -1
- package/src/adapters/macos/safari-url.yaml +8 -4
- package/src/adapters/maoyan/hot.yaml +1 -1
- package/src/adapters/markdown-new/read.yaml +50 -0
- package/src/adapters/notion-app/notion-app.ts +17 -1
- package/src/adapters/ollama-cloud/fetch.yaml +39 -0
- package/src/adapters/ollama-cloud/search.yaml +43 -0
- package/src/adapters/spotify/api.ts +54 -8
- package/src/adapters/weibo/trending.yaml +2 -0
- package/src/adapters/xiaohongshu/browser-state.ts +59 -2
- package/src/adapters/xiaohongshu/feed.ts +103 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/browser/protocol.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/browser/protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/browser/protocol.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
export const DAEMON_PORT = 19825;
|
|
7
7
|
export const DAEMON_PORT_CANDIDATES = [19825, 19826, 19827, 19828, 19829];
|
|
8
8
|
export const DAEMON_HOST = "127.0.0.1";
|
|
9
|
+
export const DAEMON_PRODUCT = "unicli";
|
|
10
|
+
export const DAEMON_PROTOCOL = "unicli-browser-bridge";
|
|
9
11
|
export const DAEMON_IDLE_TIMEOUT = 4 * 60 * 60 * 1000; // 4 hours default
|
|
10
12
|
export const DAEMON_WS_PATH = "/ext";
|
|
11
13
|
export const DAEMON_COMMAND_TIMEOUT = 120_000; // 2 min per command
|
|
@@ -16,4 +18,7 @@ export const WS_RECONNECT_MAX_DELAY = 5000;
|
|
|
16
18
|
export const MAX_EAGER_RECONNECT_ATTEMPTS = 6;
|
|
17
19
|
export const HEARTBEAT_INTERVAL = 15_000; // 15s ping interval
|
|
18
20
|
export const MAX_MISSED_PONGS = 2;
|
|
21
|
+
export function isCompatibleExtensionHello(value) {
|
|
22
|
+
return value.product === DAEMON_PRODUCT && value.protocol === DAEMON_PROTOCOL;
|
|
23
|
+
}
|
|
19
24
|
//# sourceMappingURL=protocol.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/browser/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uEAAuE;AAEvE,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,kBAAkB;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,CAAC,oBAAoB;AACnE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,kBAAkB;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,CAAC,kBAAkB;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAC9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,CAAC,oBAAoB;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/browser/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,uEAAuE;AAEvE,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AACvD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,kBAAkB;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,CAAC,oBAAoB;AACnE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,kBAAkB;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,CAAC,kBAAkB;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAC9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,CAAC,oBAAoB;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAkGlC,MAAM,UAAU,0BAA0B,CAAC,KAAqB;IAC9D,OAAO,KAAK,CAAC,OAAO,KAAK,cAAc,IAAI,KAAK,CAAC,QAAQ,KAAK,eAAe,CAAC;AAChF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/actions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/actions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EAUL,sBAAsB,EACvB,MAAM,cAAc,CAAC;AA0BtB,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAYlC,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4BtE;AA6jBD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B,IAAI,CA8wBN"}
|
|
@@ -6,20 +6,21 @@
|
|
|
6
6
|
* @breaks Action, lease, daemon, and evidence failures propagate as command errors or evidence envelopes. No fallback.
|
|
7
7
|
*/
|
|
8
8
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
9
|
-
import { dirname as pathDirname, join } from "node:path";
|
|
9
|
+
import { basename as pathBasename, dirname as pathDirname, join, } from "node:path";
|
|
10
10
|
import chalk from "chalk";
|
|
11
11
|
import { userHome } from "../../engine/user-home.js";
|
|
12
12
|
import { FINGERPRINT_PERSIST_JS, verifyRef, } from "../../browser/snapshot-identity.js";
|
|
13
13
|
import { rankCandidates } from "../../browser/observe.js";
|
|
14
14
|
import { buildExtractJs, buildFindJs, ensureNetworkCapture, getOperatorPage, operatorAction, readFrames, resolveAllowedUploadPath, resolveWorkspace, validateRef, withBrowserOperatorEnv, } from "./runtime.js";
|
|
15
|
-
import { sendCommand } from "../../browser/daemon-client.js";
|
|
15
|
+
import { listSessions, sendCommand } from "../../browser/daemon-client.js";
|
|
16
16
|
import { registerBrowserAuthoringSubcommands } from "./authoring.js";
|
|
17
|
-
import { captureBrowserEvidencePacket, captureRenderAwareBrowserEvidence, installBrowserEvidenceHooks, } from "../../engine/browser/evidence.js";
|
|
17
|
+
import { captureBrowserEvidencePacket, captureRenderAwareBrowserEvidence, installBrowserEvidenceHooks, readBrowserConsole, } from "../../engine/browser/evidence.js";
|
|
18
18
|
import { assertBrowserSessionLeaseUrlGuard, createBrowserSessionLease, } from "../../engine/browser/session-lease.js";
|
|
19
19
|
import { assertBrowserSessionLeaseTargetCurrent, enrichBrowserSessionLease, } from "../../engine/browser/session-runtime.js";
|
|
20
20
|
import { isBrowserActionEvidenceEnabled, withBrowserActionEvidence, } from "../../engine/browser/action-evidence.js";
|
|
21
21
|
import { withBrowserSessionLeaseLock } from "../../engine/browser/session-lock.js";
|
|
22
22
|
export { withBrowserOperatorEnv };
|
|
23
|
+
const BROWSER_DOM_QUERY_RESULT_MAX_CHARS = 20_000;
|
|
23
24
|
export function applyBrowserOperatorRootOptions(command) {
|
|
24
25
|
command
|
|
25
26
|
.option("--workspace <name>", "Reuse a named automation workspace instead of the default shared session")
|
|
@@ -91,6 +92,330 @@ function browserActionWatchdogMode(value) {
|
|
|
91
92
|
return "off";
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
const BROWSER_CDP_READ_ONLY_METHODS = new Set([
|
|
96
|
+
"Page.getFrameTree",
|
|
97
|
+
"Target.getTargetInfo",
|
|
98
|
+
]);
|
|
99
|
+
const BROWSER_CDP_RESULT_MAX_CHARS = 20_000;
|
|
100
|
+
async function closeAllBrowserSessions() {
|
|
101
|
+
const sessions = await listSessions();
|
|
102
|
+
const reports = [];
|
|
103
|
+
for (const session of sessions) {
|
|
104
|
+
await sendCommand("close-window", { workspace: session.workspace });
|
|
105
|
+
reports.push({
|
|
106
|
+
workspace: session.workspace,
|
|
107
|
+
action: closeActionForSession(session),
|
|
108
|
+
status: "completed",
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
ok: true,
|
|
113
|
+
scope: "all_managed_sessions",
|
|
114
|
+
session_count: sessions.length,
|
|
115
|
+
closed_count: reports.filter((report) => report.action === "closed_window")
|
|
116
|
+
.length,
|
|
117
|
+
released_count: reports.filter((report) => report.action === "released_binding").length,
|
|
118
|
+
failed_count: 0,
|
|
119
|
+
sessions: reports,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function closeActionForSession(session) {
|
|
123
|
+
return session.owned === false ? "released_binding" : "closed_window";
|
|
124
|
+
}
|
|
125
|
+
function normalizeBrowserDialogProviderResult(result, workspace) {
|
|
126
|
+
if (!isRecord(result) ||
|
|
127
|
+
result.evidence_type !== "browser-dialog-supervision" ||
|
|
128
|
+
result.supervision !== "active") {
|
|
129
|
+
throw new Error("Browser dialog supervisor returned an invalid payload.");
|
|
130
|
+
}
|
|
131
|
+
const respondedDialog = readDialogEntries([result.responded_dialog])[0];
|
|
132
|
+
return {
|
|
133
|
+
ok: true,
|
|
134
|
+
evidence_type: "browser-dialog-supervision",
|
|
135
|
+
workspace,
|
|
136
|
+
captured_at: readString(result.captured_at) ?? new Date().toISOString(),
|
|
137
|
+
supervision: "active",
|
|
138
|
+
pending_count: readNonNegativeInteger(result.pending_count),
|
|
139
|
+
recent_count: readNonNegativeInteger(result.recent_count),
|
|
140
|
+
pending_dialogs: readDialogEntries(result.pending_dialogs),
|
|
141
|
+
recent_dialogs: readDialogRecords(result.recent_dialogs),
|
|
142
|
+
...(respondedDialog === undefined
|
|
143
|
+
? {}
|
|
144
|
+
: { responded_dialog: respondedDialog }),
|
|
145
|
+
...(readString(result.url) === undefined
|
|
146
|
+
? {}
|
|
147
|
+
: { url: readString(result.url) }),
|
|
148
|
+
...(readString(result.title) === undefined
|
|
149
|
+
? {}
|
|
150
|
+
: { title: readString(result.title) }),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function normalizeBrowserDownloadsProviderResult(result, workspace, limit) {
|
|
154
|
+
if (!isRecord(result) || result.evidence_type !== "browser-downloads") {
|
|
155
|
+
throw new Error("Browser downloads provider returned an invalid payload.");
|
|
156
|
+
}
|
|
157
|
+
const downloads = readDownloadEntries(result.downloads);
|
|
158
|
+
return {
|
|
159
|
+
ok: true,
|
|
160
|
+
evidence_type: "browser-downloads",
|
|
161
|
+
workspace,
|
|
162
|
+
captured_at: readString(result.captured_at) ?? new Date().toISOString(),
|
|
163
|
+
limit,
|
|
164
|
+
count: downloads.length,
|
|
165
|
+
downloads,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function parseBrowserDialogAction(action) {
|
|
169
|
+
if (action === "accept" || action === "dismiss")
|
|
170
|
+
return action;
|
|
171
|
+
throw new Error("Browser dialog action must be accept or dismiss.");
|
|
172
|
+
}
|
|
173
|
+
function parseBrowserDomQueryKind(rawKind) {
|
|
174
|
+
if (rawKind === undefined || rawKind === "text")
|
|
175
|
+
return "text";
|
|
176
|
+
if (rawKind === "value" || rawKind === "attributes")
|
|
177
|
+
return rawKind;
|
|
178
|
+
throw new Error("Browser query kind must be text, value, or attributes.");
|
|
179
|
+
}
|
|
180
|
+
function buildBrowserDomQueryJs(ref, kind) {
|
|
181
|
+
const refJson = JSON.stringify(ref);
|
|
182
|
+
const kindJson = JSON.stringify(kind);
|
|
183
|
+
return `(() => {
|
|
184
|
+
const __unicli_dom_query = true;
|
|
185
|
+
const ref = ${refJson};
|
|
186
|
+
const kind = ${kindJson};
|
|
187
|
+
const el = document.querySelector('[data-unicli-ref="' + ref + '"]');
|
|
188
|
+
if (!el) throw new Error('Ref not found: ' + ref);
|
|
189
|
+
const readText = () => {
|
|
190
|
+
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
|
|
191
|
+
return String(el.value || '');
|
|
192
|
+
}
|
|
193
|
+
const text = 'innerText' in el ? el.innerText : el.textContent;
|
|
194
|
+
return String(text || '').trim();
|
|
195
|
+
};
|
|
196
|
+
if (kind === 'text') {
|
|
197
|
+
const value = readText();
|
|
198
|
+
return { value, original_length: value.length, truncated: false };
|
|
199
|
+
}
|
|
200
|
+
if (kind === 'value') {
|
|
201
|
+
const value = 'value' in el ? String(el.value || '') : String(el.getAttribute('value') || '');
|
|
202
|
+
return { value, original_length: value.length, truncated: false };
|
|
203
|
+
}
|
|
204
|
+
const allowed = new Set(['href', 'src', 'alt', 'title', 'aria-label', 'role', 'name', 'placeholder', 'type']);
|
|
205
|
+
const attrs = {};
|
|
206
|
+
for (const attr of Array.from(el.attributes || [])) {
|
|
207
|
+
const name = attr.name.toLowerCase();
|
|
208
|
+
if (name === 'data-unicli-ref') continue;
|
|
209
|
+
if (!allowed.has(name) && !name.startsWith('aria-')) continue;
|
|
210
|
+
attrs[name] = String(attr.value || '').slice(0, 500);
|
|
211
|
+
}
|
|
212
|
+
const value = JSON.stringify(attrs);
|
|
213
|
+
return { value, original_length: value.length, truncated: false };
|
|
214
|
+
})()`;
|
|
215
|
+
}
|
|
216
|
+
function normalizeBrowserDomQueryResult({ kind, rawResult, ref, url, }) {
|
|
217
|
+
if (!isRecord(rawResult)) {
|
|
218
|
+
throw new Error("Browser query provider returned an invalid payload.");
|
|
219
|
+
}
|
|
220
|
+
const value = readStringAllowEmpty(rawResult.value);
|
|
221
|
+
if (value === undefined) {
|
|
222
|
+
throw new Error("Browser query provider returned no result value.");
|
|
223
|
+
}
|
|
224
|
+
const originalLength = readNonNegativeInteger(rawResult.original_length) || value.length;
|
|
225
|
+
const truncatedValue = value.length <= BROWSER_DOM_QUERY_RESULT_MAX_CHARS
|
|
226
|
+
? value
|
|
227
|
+
: value.slice(0, BROWSER_DOM_QUERY_RESULT_MAX_CHARS);
|
|
228
|
+
return {
|
|
229
|
+
ok: true,
|
|
230
|
+
evidence_type: "browser-dom-query",
|
|
231
|
+
authority: "ref_read_only",
|
|
232
|
+
kind,
|
|
233
|
+
ref,
|
|
234
|
+
result: truncatedValue,
|
|
235
|
+
result_chars: Math.max(originalLength, value.length),
|
|
236
|
+
result_truncated: rawResult.truncated === true ||
|
|
237
|
+
value.length > BROWSER_DOM_QUERY_RESULT_MAX_CHARS,
|
|
238
|
+
url,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function readDialogEntries(value) {
|
|
242
|
+
if (!Array.isArray(value))
|
|
243
|
+
return [];
|
|
244
|
+
return value.flatMap((entry) => {
|
|
245
|
+
if (!isRecord(entry))
|
|
246
|
+
return [];
|
|
247
|
+
const id = readString(entry.id);
|
|
248
|
+
const type = readString(entry.type);
|
|
249
|
+
const message = readString(entry.message);
|
|
250
|
+
const openedAt = readString(entry.opened_at);
|
|
251
|
+
if (id === undefined ||
|
|
252
|
+
type === undefined ||
|
|
253
|
+
message === undefined ||
|
|
254
|
+
openedAt === undefined) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
const url = readString(entry.url);
|
|
258
|
+
const defaultPrompt = readString(entry.default_prompt);
|
|
259
|
+
return [
|
|
260
|
+
{
|
|
261
|
+
id: id.slice(0, 120),
|
|
262
|
+
type: type.slice(0, 40),
|
|
263
|
+
message: message.slice(0, 1_000),
|
|
264
|
+
opened_at: openedAt,
|
|
265
|
+
...(url === undefined ? {} : { url: url.slice(0, 2_000) }),
|
|
266
|
+
...(defaultPrompt === undefined
|
|
267
|
+
? {}
|
|
268
|
+
: { default_prompt: defaultPrompt.slice(0, 1_000) }),
|
|
269
|
+
},
|
|
270
|
+
];
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
function readDialogRecords(value) {
|
|
274
|
+
if (!Array.isArray(value))
|
|
275
|
+
return [];
|
|
276
|
+
return value.flatMap((record) => {
|
|
277
|
+
if (!isRecord(record))
|
|
278
|
+
return [];
|
|
279
|
+
const entry = readDialogEntries([record])[0];
|
|
280
|
+
const closedAt = readString(record.closed_at);
|
|
281
|
+
const closedBy = readString(record.closed_by);
|
|
282
|
+
if (entry === undefined ||
|
|
283
|
+
closedAt === undefined ||
|
|
284
|
+
(closedBy !== "agent" &&
|
|
285
|
+
closedBy !== "remote" &&
|
|
286
|
+
closedBy !== "tab_closed")) {
|
|
287
|
+
return [];
|
|
288
|
+
}
|
|
289
|
+
return [
|
|
290
|
+
{
|
|
291
|
+
...entry,
|
|
292
|
+
closed_at: closedAt,
|
|
293
|
+
closed_by: closedBy,
|
|
294
|
+
...(record.action === "accept" || record.action === "dismiss"
|
|
295
|
+
? { action: record.action }
|
|
296
|
+
: {}),
|
|
297
|
+
},
|
|
298
|
+
];
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function readDownloadEntries(value) {
|
|
302
|
+
if (!Array.isArray(value))
|
|
303
|
+
return [];
|
|
304
|
+
return value.slice(0, 50).flatMap((entry) => {
|
|
305
|
+
if (!isRecord(entry))
|
|
306
|
+
return [];
|
|
307
|
+
const id = readNonNegativeInteger(entry.id);
|
|
308
|
+
const state = readString(entry.state);
|
|
309
|
+
const danger = readString(entry.danger);
|
|
310
|
+
const filenameBasename = readString(entry.filename_basename);
|
|
311
|
+
if (state === undefined ||
|
|
312
|
+
danger === undefined ||
|
|
313
|
+
filenameBasename === undefined) {
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
return [
|
|
317
|
+
{
|
|
318
|
+
id,
|
|
319
|
+
state: state.slice(0, 40),
|
|
320
|
+
danger: danger.slice(0, 80),
|
|
321
|
+
exists: entry.exists === true,
|
|
322
|
+
paused: entry.paused === true,
|
|
323
|
+
incognito: entry.incognito === true,
|
|
324
|
+
bytes_received: readNonNegativeInteger(entry.bytes_received),
|
|
325
|
+
total_bytes: readNonNegativeInteger(entry.total_bytes),
|
|
326
|
+
file_size: readNonNegativeInteger(entry.file_size),
|
|
327
|
+
filename_basename: pathBasename(filenameBasename).slice(0, 240),
|
|
328
|
+
...(readString(entry.mime) === undefined
|
|
329
|
+
? {}
|
|
330
|
+
: { mime: readString(entry.mime).slice(0, 160) }),
|
|
331
|
+
...(readString(entry.url) === undefined
|
|
332
|
+
? {}
|
|
333
|
+
: { url: readString(entry.url).slice(0, 2_000) }),
|
|
334
|
+
...(readString(entry.final_url) === undefined
|
|
335
|
+
? {}
|
|
336
|
+
: { final_url: readString(entry.final_url).slice(0, 2_000) }),
|
|
337
|
+
...(readString(entry.started_at) === undefined
|
|
338
|
+
? {}
|
|
339
|
+
: { started_at: readString(entry.started_at) }),
|
|
340
|
+
...(readString(entry.ended_at) === undefined
|
|
341
|
+
? {}
|
|
342
|
+
: { ended_at: readString(entry.ended_at) }),
|
|
343
|
+
...(readString(entry.error) === undefined
|
|
344
|
+
? {}
|
|
345
|
+
: { error: readString(entry.error).slice(0, 160) }),
|
|
346
|
+
},
|
|
347
|
+
];
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function parseDownloadLimit(rawLimit) {
|
|
351
|
+
const parsed = Number.parseInt(rawLimit ?? "20", 10);
|
|
352
|
+
if (!Number.isFinite(parsed))
|
|
353
|
+
return 20;
|
|
354
|
+
return Math.max(1, Math.min(50, Math.trunc(parsed)));
|
|
355
|
+
}
|
|
356
|
+
function readNonNegativeInteger(value) {
|
|
357
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
358
|
+
? Math.trunc(value)
|
|
359
|
+
: 0;
|
|
360
|
+
}
|
|
361
|
+
function readString(value) {
|
|
362
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
363
|
+
}
|
|
364
|
+
function readStringAllowEmpty(value) {
|
|
365
|
+
return typeof value === "string" ? value : undefined;
|
|
366
|
+
}
|
|
367
|
+
function isRecord(value) {
|
|
368
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
369
|
+
}
|
|
370
|
+
function parseBrowserCdpParams(rawParams) {
|
|
371
|
+
if (rawParams === undefined)
|
|
372
|
+
return {};
|
|
373
|
+
let parsed;
|
|
374
|
+
try {
|
|
375
|
+
parsed = JSON.parse(rawParams);
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
throw new Error("CDP params must be a JSON object.");
|
|
379
|
+
}
|
|
380
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
381
|
+
throw new Error("CDP params must be a JSON object.");
|
|
382
|
+
}
|
|
383
|
+
return parsed;
|
|
384
|
+
}
|
|
385
|
+
function assertBrowserCdpReadOnlyMethod(method) {
|
|
386
|
+
if (BROWSER_CDP_READ_ONLY_METHODS.has(method))
|
|
387
|
+
return;
|
|
388
|
+
throw new Error(`CDP method ${method} is not in the read-only allowlist. Supported methods: ${[
|
|
389
|
+
...BROWSER_CDP_READ_ONLY_METHODS,
|
|
390
|
+
].join(", ")}`);
|
|
391
|
+
}
|
|
392
|
+
function createBrowserCdpReadOnlyResult(input) {
|
|
393
|
+
const resultJson = JSON.stringify(input.result ?? null);
|
|
394
|
+
if (resultJson.length <= BROWSER_CDP_RESULT_MAX_CHARS) {
|
|
395
|
+
return {
|
|
396
|
+
ok: true,
|
|
397
|
+
evidence_type: "browser-cdp-readonly",
|
|
398
|
+
workspace: input.workspace,
|
|
399
|
+
method: input.method,
|
|
400
|
+
authority: "read_only_allowlist",
|
|
401
|
+
params_keys: Object.keys(input.params).sort(),
|
|
402
|
+
result_json_chars: resultJson.length,
|
|
403
|
+
result_truncated: false,
|
|
404
|
+
result: input.result,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
return {
|
|
408
|
+
ok: true,
|
|
409
|
+
evidence_type: "browser-cdp-readonly",
|
|
410
|
+
workspace: input.workspace,
|
|
411
|
+
method: input.method,
|
|
412
|
+
authority: "read_only_allowlist",
|
|
413
|
+
params_keys: Object.keys(input.params).sort(),
|
|
414
|
+
result_json_chars: resultJson.length,
|
|
415
|
+
result_truncated: true,
|
|
416
|
+
result_preview: resultJson.slice(0, BROWSER_CDP_RESULT_MAX_CHARS),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
94
419
|
export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
95
420
|
root
|
|
96
421
|
.command("open <url>")
|
|
@@ -136,6 +461,27 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
136
461
|
return { url, snapshot };
|
|
137
462
|
});
|
|
138
463
|
}));
|
|
464
|
+
root
|
|
465
|
+
.command("query <ref>")
|
|
466
|
+
.description("Read bounded DOM data from a verified snapshot ref")
|
|
467
|
+
.option("--kind <kind>", "Query kind: text, value, or attributes", "text")
|
|
468
|
+
.action((ref, opts) => operatorAction(program, root, namespace, "query", async () => {
|
|
469
|
+
validateRef(ref);
|
|
470
|
+
const kind = parseBrowserDomQueryKind(opts.kind);
|
|
471
|
+
const page = await getOperatorPage(root, namespace);
|
|
472
|
+
const selector = `[data-unicli-ref="${ref}"]`;
|
|
473
|
+
return await withRecordedBrowserAction(program, root, namespace, "query", page, { ref, kind }, async () => {
|
|
474
|
+
await verifyRef(page, selector);
|
|
475
|
+
const url = await page.url();
|
|
476
|
+
const rawResult = await page.evaluate(buildBrowserDomQueryJs(ref, kind));
|
|
477
|
+
return normalizeBrowserDomQueryResult({
|
|
478
|
+
kind,
|
|
479
|
+
rawResult,
|
|
480
|
+
ref,
|
|
481
|
+
url,
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}));
|
|
139
485
|
root
|
|
140
486
|
.command("screenshot [path]")
|
|
141
487
|
.description("Capture page screenshot")
|
|
@@ -192,6 +538,62 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
192
538
|
screenshotDir,
|
|
193
539
|
});
|
|
194
540
|
}));
|
|
541
|
+
root
|
|
542
|
+
.command("console")
|
|
543
|
+
.description("Read bounded browser console messages and page errors")
|
|
544
|
+
.option("--clear", "Clear captured console entries after reading")
|
|
545
|
+
.option("--max <n>", "Maximum console entries to return", "50")
|
|
546
|
+
.option("--text-max <n>", "Maximum text characters per entry", "1000")
|
|
547
|
+
.action((opts) => operatorAction(program, root, namespace, "console", async () => {
|
|
548
|
+
const page = await getOperatorPage(root, namespace);
|
|
549
|
+
return await readBrowserConsole(page, {
|
|
550
|
+
clear: opts.clear === true,
|
|
551
|
+
maxEntries: parseInt(opts.max, 10),
|
|
552
|
+
maxTextChars: parseInt(opts.textMax, 10),
|
|
553
|
+
});
|
|
554
|
+
}));
|
|
555
|
+
root
|
|
556
|
+
.command("cdp <method> [params]")
|
|
557
|
+
.description("Run a read-only allowlisted Chrome DevTools Protocol command")
|
|
558
|
+
.action((method, paramsJson) => operatorAction(program, root, namespace, "cdp", async () => {
|
|
559
|
+
assertBrowserCdpReadOnlyMethod(method);
|
|
560
|
+
const params = parseBrowserCdpParams(paramsJson);
|
|
561
|
+
const page = await getOperatorPage(root, namespace);
|
|
562
|
+
const result = await page.sendCDP(method, params);
|
|
563
|
+
return createBrowserCdpReadOnlyResult({
|
|
564
|
+
workspace: resolveWorkspace(root, namespace),
|
|
565
|
+
method,
|
|
566
|
+
params,
|
|
567
|
+
result,
|
|
568
|
+
});
|
|
569
|
+
}));
|
|
570
|
+
root
|
|
571
|
+
.command("dialogs")
|
|
572
|
+
.description("Start and read provider-owned browser dialog supervision")
|
|
573
|
+
.option("--clear-recent", "Clear recent dialog records after reading")
|
|
574
|
+
.action((opts) => operatorAction(program, root, namespace, "dialogs", async () => {
|
|
575
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
576
|
+
const result = await sendCommand("dialog-read", {
|
|
577
|
+
workspace,
|
|
578
|
+
clearRecent: opts.clearRecent === true,
|
|
579
|
+
});
|
|
580
|
+
return normalizeBrowserDialogProviderResult(result, workspace);
|
|
581
|
+
}));
|
|
582
|
+
root
|
|
583
|
+
.command("dialog <action> [dialogId]")
|
|
584
|
+
.description("Respond to a pending browser JavaScript dialog")
|
|
585
|
+
.option("--prompt <text>", "Prompt text for prompt() dialogs")
|
|
586
|
+
.action((actionRaw, dialogId, opts) => operatorAction(program, root, namespace, "dialog", async () => {
|
|
587
|
+
const action = parseBrowserDialogAction(actionRaw);
|
|
588
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
589
|
+
const result = await sendCommand("dialog-respond", {
|
|
590
|
+
workspace,
|
|
591
|
+
dialogAction: action,
|
|
592
|
+
...(dialogId === undefined ? {} : { dialogId }),
|
|
593
|
+
...(opts.prompt === undefined ? {} : { promptText: opts.prompt }),
|
|
594
|
+
});
|
|
595
|
+
return normalizeBrowserDialogProviderResult(result, workspace);
|
|
596
|
+
}));
|
|
195
597
|
root
|
|
196
598
|
.command("click <ref>")
|
|
197
599
|
.description("Click element by ref number from state")
|
|
@@ -456,6 +858,19 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
456
858
|
const page = await getOperatorPage(root, namespace);
|
|
457
859
|
return await readFrames(page);
|
|
458
860
|
}));
|
|
861
|
+
root
|
|
862
|
+
.command("downloads")
|
|
863
|
+
.description("List recent browser downloads without exposing local file paths")
|
|
864
|
+
.option("--limit <n>", "Maximum download records to return", "20")
|
|
865
|
+
.action((opts) => operatorAction(program, root, namespace, "downloads", async () => {
|
|
866
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
867
|
+
const limit = parseDownloadLimit(opts.limit);
|
|
868
|
+
const result = await sendCommand("downloads-read", {
|
|
869
|
+
workspace,
|
|
870
|
+
downloadLimit: limit,
|
|
871
|
+
});
|
|
872
|
+
return normalizeBrowserDownloadsProviderResult(result, workspace, limit);
|
|
873
|
+
}));
|
|
459
874
|
root
|
|
460
875
|
.command("extract")
|
|
461
876
|
.description("Extract long-form page text with chunked pagination")
|
|
@@ -516,10 +931,18 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
516
931
|
root
|
|
517
932
|
.command("close")
|
|
518
933
|
.description("Close the automation browser window")
|
|
519
|
-
.
|
|
934
|
+
.option("--all", "Close or release all managed browser sessions")
|
|
935
|
+
.action((opts) => operatorAction(program, root, namespace, "close", async () => {
|
|
936
|
+
if (opts.all === true) {
|
|
937
|
+
return await closeAllBrowserSessions();
|
|
938
|
+
}
|
|
520
939
|
const page = await getOperatorPage(root, namespace);
|
|
521
940
|
await page.closeWindow();
|
|
522
|
-
return {
|
|
941
|
+
return {
|
|
942
|
+
ok: true,
|
|
943
|
+
scope: "current_managed_session",
|
|
944
|
+
workspace: resolveWorkspace(root, namespace),
|
|
945
|
+
};
|
|
523
946
|
}));
|
|
524
947
|
}
|
|
525
948
|
//# sourceMappingURL=actions.js.map
|