@zenalexa/unicli 0.225.1 → 0.225.3
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 +3 -3
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/adapters/acl-anthology/papers.d.ts +16 -9
- package/dist/adapters/acl-anthology/papers.d.ts.map +1 -1
- package/dist/adapters/acl-anthology/papers.js +322 -58
- package/dist/adapters/acl-anthology/papers.js.map +1 -1
- package/dist/adapters/arxiv/papers.d.ts +22 -4
- package/dist/adapters/arxiv/papers.d.ts.map +1 -1
- package/dist/adapters/arxiv/papers.js +202 -4
- package/dist/adapters/arxiv/papers.js.map +1 -1
- package/dist/adapters/baidu-scholar/search.d.ts +15 -1
- package/dist/adapters/baidu-scholar/search.d.ts.map +1 -1
- package/dist/adapters/baidu-scholar/search.js +72 -8
- package/dist/adapters/baidu-scholar/search.js.map +1 -1
- package/dist/adapters/biorxiv/preprints.d.ts +9 -0
- package/dist/adapters/biorxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/biorxiv/preprints.js +78 -0
- package/dist/adapters/biorxiv/preprints.js.map +1 -0
- package/dist/adapters/cnki/search.d.ts +82 -0
- package/dist/adapters/cnki/search.d.ts.map +1 -0
- package/dist/adapters/cnki/search.js +236 -0
- package/dist/adapters/cnki/search.js.map +1 -0
- package/dist/adapters/cvf/papers.d.ts +12 -7
- package/dist/adapters/cvf/papers.d.ts.map +1 -1
- package/dist/adapters/cvf/papers.js +210 -27
- package/dist/adapters/cvf/papers.js.map +1 -1
- package/dist/adapters/dblp/publications.d.ts +12 -5
- package/dist/adapters/dblp/publications.d.ts.map +1 -1
- package/dist/adapters/dblp/publications.js +31 -8
- package/dist/adapters/dblp/publications.js.map +1 -1
- package/dist/adapters/google-scholar/search.d.ts +22 -1
- package/dist/adapters/google-scholar/search.d.ts.map +1 -1
- package/dist/adapters/google-scholar/search.js +129 -14
- package/dist/adapters/google-scholar/search.js.map +1 -1
- package/dist/adapters/hf/paper.d.ts +12 -3
- package/dist/adapters/hf/paper.d.ts.map +1 -1
- package/dist/adapters/hf/paper.js +65 -5
- package/dist/adapters/hf/paper.js.map +1 -1
- package/dist/adapters/medrxiv/preprints.d.ts +9 -0
- package/dist/adapters/medrxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/medrxiv/preprints.js +78 -0
- package/dist/adapters/medrxiv/preprints.js.map +1 -0
- package/dist/adapters/neurips/proceedings.d.ts +8 -7
- package/dist/adapters/neurips/proceedings.d.ts.map +1 -1
- package/dist/adapters/neurips/proceedings.js +209 -21
- package/dist/adapters/neurips/proceedings.js.map +1 -1
- package/dist/adapters/openalex/works.d.ts +21 -5
- package/dist/adapters/openalex/works.d.ts.map +1 -1
- package/dist/adapters/openalex/works.js +108 -8
- package/dist/adapters/openalex/works.js.map +1 -1
- package/dist/adapters/openreview/papers.d.ts +10 -4
- package/dist/adapters/openreview/papers.d.ts.map +1 -1
- package/dist/adapters/openreview/papers.js +351 -24
- package/dist/adapters/openreview/papers.js.map +1 -1
- package/dist/adapters/pmlr/proceedings.d.ts +6 -6
- package/dist/adapters/pmlr/proceedings.d.ts.map +1 -1
- package/dist/adapters/pmlr/proceedings.js +92 -12
- package/dist/adapters/pmlr/proceedings.js.map +1 -1
- package/dist/adapters/pubmed/articles.d.ts +8 -4
- package/dist/adapters/pubmed/articles.d.ts.map +1 -1
- package/dist/adapters/pubmed/articles.js +272 -39
- package/dist/adapters/pubmed/articles.js.map +1 -1
- package/dist/adapters/rxiv/preprints.d.ts +75 -0
- package/dist/adapters/rxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/rxiv/preprints.js +651 -0
- package/dist/adapters/rxiv/preprints.js.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf-read.d.ts +49 -0
- package/dist/adapters/scholar-artifacts/pdf-read.d.ts.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf-read.js +204 -0
- package/dist/adapters/scholar-artifacts/pdf-read.js.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf.d.ts +16 -0
- package/dist/adapters/scholar-artifacts/pdf.d.ts.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf.js +122 -0
- package/dist/adapters/scholar-artifacts/pdf.js.map +1 -0
- package/dist/adapters/semantic-scholar/papers.d.ts +6 -6
- package/dist/adapters/semantic-scholar/papers.d.ts.map +1 -1
- package/dist/adapters/semantic-scholar/papers.js +80 -6
- package/dist/adapters/semantic-scholar/papers.js.map +1 -1
- package/dist/adapters/unpaywall/works.d.ts +7 -7
- package/dist/adapters/unpaywall/works.d.ts.map +1 -1
- package/dist/adapters/unpaywall/works.js +104 -12
- package/dist/adapters/unpaywall/works.js.map +1 -1
- package/dist/adapters/wanfang/search.d.ts +14 -0
- package/dist/adapters/wanfang/search.d.ts.map +1 -1
- package/dist/adapters/wanfang/search.js +56 -7
- package/dist/adapters/wanfang/search.js.map +1 -1
- package/dist/browser/page.d.ts +2 -0
- package/dist/browser/page.d.ts.map +1 -1
- package/dist/browser/page.js +12 -0
- package/dist/browser/page.js.map +1 -1
- package/dist/browser/protocol.d.ts +6 -1
- package/dist/browser/protocol.d.ts.map +1 -1
- package/dist/browser/protocol.js.map +1 -1
- package/dist/commands/browser/actions.d.ts.map +1 -1
- package/dist/commands/browser/actions.js +487 -8
- package/dist/commands/browser/actions.js.map +1 -1
- package/dist/commands/compute.js +12 -1
- package/dist/commands/compute.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/scholar.d.ts +77 -5
- package/dist/commands/scholar.d.ts.map +1 -1
- package/dist/commands/scholar.js +2945 -83
- package/dist/commands/scholar.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/core/command-contract.d.ts.map +1 -1
- package/dist/core/command-contract.js +5 -0
- package/dist/core/command-contract.js.map +1 -1
- package/dist/core/schema-v2.d.ts +1 -0
- package/dist/core/schema-v2.d.ts.map +1 -1
- package/dist/core/schema-v2.js +1 -0
- package/dist/core/schema-v2.js.map +1 -1
- package/dist/discovery/aliases.d.ts +8 -1
- package/dist/discovery/aliases.d.ts.map +1 -1
- package/dist/discovery/aliases.js +333 -20
- package/dist/discovery/aliases.js.map +1 -1
- package/dist/discovery/core-catalog.d.ts +2 -0
- package/dist/discovery/core-catalog.d.ts.map +1 -1
- package/dist/discovery/core-catalog.js +525 -66
- package/dist/discovery/core-catalog.js.map +1 -1
- package/dist/discovery/intents.d.ts +1 -0
- package/dist/discovery/intents.d.ts.map +1 -1
- package/dist/discovery/intents.js +299 -2
- 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 +12 -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/capability-policy.d.ts.map +1 -1
- package/dist/engine/capability-policy.js +30 -4
- package/dist/engine/capability-policy.js.map +1 -1
- package/dist/engine/kernel/stages.d.ts.map +1 -1
- package/dist/engine/kernel/stages.js +3 -0
- package/dist/engine/kernel/stages.js.map +1 -1
- package/dist/engine/operation-policy.d.ts +4 -1
- package/dist/engine/operation-policy.d.ts.map +1 -1
- package/dist/engine/operation-policy.js +23 -0
- package/dist/engine/operation-policy.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/manifest.d.ts +3 -0
- package/dist/fast-path/manifest.d.ts.map +1 -1
- package/dist/fast-path/manifest.js.map +1 -1
- package/dist/fast-path/policy.d.ts.map +1 -1
- package/dist/fast-path/policy.js +3 -0
- package/dist/fast-path/policy.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 +2 -2
- package/dist/manifest.json +6977 -1002
- 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/registry.d.ts +2 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +1 -0
- package/dist/registry.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/dist/types/scholarly.d.ts +19 -4
- package/dist/types/scholarly.d.ts.map +1 -1
- package/dist/types/scholarly.js +4 -4
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -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/acl-anthology/papers.test.ts +111 -0
- package/src/adapters/acl-anthology/papers.ts +379 -71
- package/src/adapters/arxiv/papers.test.ts +46 -0
- package/src/adapters/arxiv/papers.ts +251 -4
- package/src/adapters/baidu-scholar/search.ts +74 -11
- package/src/adapters/biorxiv/preprints.ts +112 -0
- package/src/adapters/cnki/search.ts +357 -0
- package/src/adapters/cvf/papers.ts +260 -27
- package/src/adapters/dblp/publications.test.ts +9 -0
- package/src/adapters/dblp/publications.ts +31 -8
- package/src/adapters/defuddle/read.yaml +30 -0
- package/src/adapters/google-scholar/search.ts +165 -17
- package/src/adapters/hf/paper.test.ts +23 -0
- package/src/adapters/hf/paper.ts +89 -5
- package/src/adapters/hf/top.yaml +34 -2
- package/src/adapters/huggingface-papers/daily.yaml +37 -3
- package/src/adapters/huggingface-papers/search.yaml +43 -9
- package/src/adapters/jina/read.yaml +30 -0
- package/src/adapters/markdown-new/read.yaml +50 -0
- package/src/adapters/medrxiv/preprints.ts +112 -0
- package/src/adapters/neurips/proceedings.ts +266 -22
- package/src/adapters/ollama-cloud/fetch.yaml +39 -0
- package/src/adapters/ollama-cloud/search.yaml +43 -0
- package/src/adapters/openalex/works.test.ts +15 -4
- package/src/adapters/openalex/works.ts +136 -8
- package/src/adapters/openreview/papers.test.ts +31 -0
- package/src/adapters/openreview/papers.ts +407 -29
- package/src/adapters/pmlr/proceedings.ts +102 -12
- package/src/adapters/pubmed/articles.test.ts +88 -1
- package/src/adapters/pubmed/articles.ts +343 -44
- package/src/adapters/rxiv/preprints.test.ts +233 -0
- package/src/adapters/rxiv/preprints.ts +849 -0
- package/src/adapters/scholar-artifacts/pdf-read.ts +277 -0
- package/src/adapters/scholar-artifacts/pdf.ts +133 -0
- package/src/adapters/semantic-scholar/papers.ts +98 -6
- package/src/adapters/unpaywall/works.ts +141 -12
- package/src/adapters/wanfang/search.ts +57 -7
- package/src/adapters/cnki/search.yaml +0 -49
|
@@ -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,371 @@ function browserActionWatchdogMode(value) {
|
|
|
91
92
|
return "off";
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
async function readBrowserConnectionTargetEvidence(page, finalUrl) {
|
|
96
|
+
const requests = await page.networkRequests();
|
|
97
|
+
return selectBrowserConnectionTargetEvidence(finalUrl, requests);
|
|
98
|
+
}
|
|
99
|
+
function selectBrowserConnectionTargetEvidence(finalUrl, requests) {
|
|
100
|
+
for (let index = requests.length - 1; index >= 0; index -= 1) {
|
|
101
|
+
const request = requests[index];
|
|
102
|
+
if (!request?.remoteIPAddress)
|
|
103
|
+
continue;
|
|
104
|
+
if (!isSameBrowserDocumentUrl(finalUrl, request.url))
|
|
105
|
+
continue;
|
|
106
|
+
return {
|
|
107
|
+
source: "cdp_network_response",
|
|
108
|
+
url: request.url,
|
|
109
|
+
remote_ip_address: request.remoteIPAddress,
|
|
110
|
+
...(request.remotePort !== undefined
|
|
111
|
+
? { remote_port: request.remotePort }
|
|
112
|
+
: {}),
|
|
113
|
+
status: request.status,
|
|
114
|
+
resource_type: request.type,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
function isSameBrowserDocumentUrl(left, right) {
|
|
120
|
+
if (left === right)
|
|
121
|
+
return true;
|
|
122
|
+
const normalizedLeft = normalizeBrowserUrlForDocumentMatch(left);
|
|
123
|
+
const normalizedRight = normalizeBrowserUrlForDocumentMatch(right);
|
|
124
|
+
return normalizedLeft !== undefined && normalizedLeft === normalizedRight;
|
|
125
|
+
}
|
|
126
|
+
function normalizeBrowserUrlForDocumentMatch(rawUrl) {
|
|
127
|
+
try {
|
|
128
|
+
const url = new URL(rawUrl);
|
|
129
|
+
url.hash = "";
|
|
130
|
+
return url.href;
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const BROWSER_CDP_READ_ONLY_METHODS = new Set([
|
|
137
|
+
"Page.getFrameTree",
|
|
138
|
+
"Target.getTargetInfo",
|
|
139
|
+
]);
|
|
140
|
+
const BROWSER_CDP_RESULT_MAX_CHARS = 20_000;
|
|
141
|
+
async function closeAllBrowserSessions() {
|
|
142
|
+
const sessions = await listSessions();
|
|
143
|
+
const reports = [];
|
|
144
|
+
for (const session of sessions) {
|
|
145
|
+
await sendCommand("close-window", { workspace: session.workspace });
|
|
146
|
+
reports.push({
|
|
147
|
+
workspace: session.workspace,
|
|
148
|
+
action: closeActionForSession(session),
|
|
149
|
+
status: "completed",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
scope: "all_managed_sessions",
|
|
155
|
+
session_count: sessions.length,
|
|
156
|
+
closed_count: reports.filter((report) => report.action === "closed_window")
|
|
157
|
+
.length,
|
|
158
|
+
released_count: reports.filter((report) => report.action === "released_binding").length,
|
|
159
|
+
failed_count: 0,
|
|
160
|
+
sessions: reports,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function closeActionForSession(session) {
|
|
164
|
+
return session.owned === false ? "released_binding" : "closed_window";
|
|
165
|
+
}
|
|
166
|
+
function normalizeBrowserDialogProviderResult(result, workspace) {
|
|
167
|
+
if (!isRecord(result) ||
|
|
168
|
+
result.evidence_type !== "browser-dialog-supervision" ||
|
|
169
|
+
result.supervision !== "active") {
|
|
170
|
+
throw new Error("Browser dialog supervisor returned an invalid payload.");
|
|
171
|
+
}
|
|
172
|
+
const respondedDialog = readDialogEntries([result.responded_dialog])[0];
|
|
173
|
+
return {
|
|
174
|
+
ok: true,
|
|
175
|
+
evidence_type: "browser-dialog-supervision",
|
|
176
|
+
workspace,
|
|
177
|
+
captured_at: readString(result.captured_at) ?? new Date().toISOString(),
|
|
178
|
+
supervision: "active",
|
|
179
|
+
pending_count: readNonNegativeInteger(result.pending_count),
|
|
180
|
+
recent_count: readNonNegativeInteger(result.recent_count),
|
|
181
|
+
pending_dialogs: readDialogEntries(result.pending_dialogs),
|
|
182
|
+
recent_dialogs: readDialogRecords(result.recent_dialogs),
|
|
183
|
+
...(respondedDialog === undefined
|
|
184
|
+
? {}
|
|
185
|
+
: { responded_dialog: respondedDialog }),
|
|
186
|
+
...(readString(result.url) === undefined
|
|
187
|
+
? {}
|
|
188
|
+
: { url: readString(result.url) }),
|
|
189
|
+
...(readString(result.title) === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: { title: readString(result.title) }),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function normalizeBrowserDownloadsProviderResult(result, workspace, limit) {
|
|
195
|
+
if (!isRecord(result) || result.evidence_type !== "browser-downloads") {
|
|
196
|
+
throw new Error("Browser downloads provider returned an invalid payload.");
|
|
197
|
+
}
|
|
198
|
+
const downloads = readDownloadEntries(result.downloads);
|
|
199
|
+
return {
|
|
200
|
+
ok: true,
|
|
201
|
+
evidence_type: "browser-downloads",
|
|
202
|
+
workspace,
|
|
203
|
+
captured_at: readString(result.captured_at) ?? new Date().toISOString(),
|
|
204
|
+
limit,
|
|
205
|
+
count: downloads.length,
|
|
206
|
+
downloads,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function parseBrowserDialogAction(action) {
|
|
210
|
+
if (action === "accept" || action === "dismiss")
|
|
211
|
+
return action;
|
|
212
|
+
throw new Error("Browser dialog action must be accept or dismiss.");
|
|
213
|
+
}
|
|
214
|
+
function parseBrowserDomQueryKind(rawKind) {
|
|
215
|
+
if (rawKind === undefined || rawKind === "text")
|
|
216
|
+
return "text";
|
|
217
|
+
if (rawKind === "value" || rawKind === "attributes")
|
|
218
|
+
return rawKind;
|
|
219
|
+
throw new Error("Browser query kind must be text, value, or attributes.");
|
|
220
|
+
}
|
|
221
|
+
function buildBrowserDomQueryJs(ref, kind) {
|
|
222
|
+
const refJson = JSON.stringify(ref);
|
|
223
|
+
const kindJson = JSON.stringify(kind);
|
|
224
|
+
return `(() => {
|
|
225
|
+
const __unicli_dom_query = true;
|
|
226
|
+
const ref = ${refJson};
|
|
227
|
+
const kind = ${kindJson};
|
|
228
|
+
const el = document.querySelector('[data-unicli-ref="' + ref + '"]');
|
|
229
|
+
if (!el) throw new Error('Ref not found: ' + ref);
|
|
230
|
+
const readText = () => {
|
|
231
|
+
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
|
|
232
|
+
return String(el.value || '');
|
|
233
|
+
}
|
|
234
|
+
const text = 'innerText' in el ? el.innerText : el.textContent;
|
|
235
|
+
return String(text || '').trim();
|
|
236
|
+
};
|
|
237
|
+
if (kind === 'text') {
|
|
238
|
+
const value = readText();
|
|
239
|
+
return { value, original_length: value.length, truncated: false };
|
|
240
|
+
}
|
|
241
|
+
if (kind === 'value') {
|
|
242
|
+
const value = 'value' in el ? String(el.value || '') : String(el.getAttribute('value') || '');
|
|
243
|
+
return { value, original_length: value.length, truncated: false };
|
|
244
|
+
}
|
|
245
|
+
const allowed = new Set(['href', 'src', 'alt', 'title', 'aria-label', 'role', 'name', 'placeholder', 'type']);
|
|
246
|
+
const attrs = {};
|
|
247
|
+
for (const attr of Array.from(el.attributes || [])) {
|
|
248
|
+
const name = attr.name.toLowerCase();
|
|
249
|
+
if (name === 'data-unicli-ref') continue;
|
|
250
|
+
if (!allowed.has(name) && !name.startsWith('aria-')) continue;
|
|
251
|
+
attrs[name] = String(attr.value || '').slice(0, 500);
|
|
252
|
+
}
|
|
253
|
+
const value = JSON.stringify(attrs);
|
|
254
|
+
return { value, original_length: value.length, truncated: false };
|
|
255
|
+
})()`;
|
|
256
|
+
}
|
|
257
|
+
function normalizeBrowserDomQueryResult({ kind, rawResult, ref, url, }) {
|
|
258
|
+
if (!isRecord(rawResult)) {
|
|
259
|
+
throw new Error("Browser query provider returned an invalid payload.");
|
|
260
|
+
}
|
|
261
|
+
const value = readStringAllowEmpty(rawResult.value);
|
|
262
|
+
if (value === undefined) {
|
|
263
|
+
throw new Error("Browser query provider returned no result value.");
|
|
264
|
+
}
|
|
265
|
+
const originalLength = readNonNegativeInteger(rawResult.original_length) || value.length;
|
|
266
|
+
const truncatedValue = value.length <= BROWSER_DOM_QUERY_RESULT_MAX_CHARS
|
|
267
|
+
? value
|
|
268
|
+
: value.slice(0, BROWSER_DOM_QUERY_RESULT_MAX_CHARS);
|
|
269
|
+
return {
|
|
270
|
+
ok: true,
|
|
271
|
+
evidence_type: "browser-dom-query",
|
|
272
|
+
authority: "ref_read_only",
|
|
273
|
+
kind,
|
|
274
|
+
ref,
|
|
275
|
+
result: truncatedValue,
|
|
276
|
+
result_chars: Math.max(originalLength, value.length),
|
|
277
|
+
result_truncated: rawResult.truncated === true ||
|
|
278
|
+
value.length > BROWSER_DOM_QUERY_RESULT_MAX_CHARS,
|
|
279
|
+
url,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function readDialogEntries(value) {
|
|
283
|
+
if (!Array.isArray(value))
|
|
284
|
+
return [];
|
|
285
|
+
return value.flatMap((entry) => {
|
|
286
|
+
if (!isRecord(entry))
|
|
287
|
+
return [];
|
|
288
|
+
const id = readString(entry.id);
|
|
289
|
+
const type = readString(entry.type);
|
|
290
|
+
const message = readString(entry.message);
|
|
291
|
+
const openedAt = readString(entry.opened_at);
|
|
292
|
+
if (id === undefined ||
|
|
293
|
+
type === undefined ||
|
|
294
|
+
message === undefined ||
|
|
295
|
+
openedAt === undefined) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
const url = readString(entry.url);
|
|
299
|
+
const defaultPrompt = readString(entry.default_prompt);
|
|
300
|
+
return [
|
|
301
|
+
{
|
|
302
|
+
id: id.slice(0, 120),
|
|
303
|
+
type: type.slice(0, 40),
|
|
304
|
+
message: message.slice(0, 1_000),
|
|
305
|
+
opened_at: openedAt,
|
|
306
|
+
...(url === undefined ? {} : { url: url.slice(0, 2_000) }),
|
|
307
|
+
...(defaultPrompt === undefined
|
|
308
|
+
? {}
|
|
309
|
+
: { default_prompt: defaultPrompt.slice(0, 1_000) }),
|
|
310
|
+
},
|
|
311
|
+
];
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function readDialogRecords(value) {
|
|
315
|
+
if (!Array.isArray(value))
|
|
316
|
+
return [];
|
|
317
|
+
return value.flatMap((record) => {
|
|
318
|
+
if (!isRecord(record))
|
|
319
|
+
return [];
|
|
320
|
+
const entry = readDialogEntries([record])[0];
|
|
321
|
+
const closedAt = readString(record.closed_at);
|
|
322
|
+
const closedBy = readString(record.closed_by);
|
|
323
|
+
if (entry === undefined ||
|
|
324
|
+
closedAt === undefined ||
|
|
325
|
+
(closedBy !== "agent" &&
|
|
326
|
+
closedBy !== "remote" &&
|
|
327
|
+
closedBy !== "tab_closed")) {
|
|
328
|
+
return [];
|
|
329
|
+
}
|
|
330
|
+
return [
|
|
331
|
+
{
|
|
332
|
+
...entry,
|
|
333
|
+
closed_at: closedAt,
|
|
334
|
+
closed_by: closedBy,
|
|
335
|
+
...(record.action === "accept" || record.action === "dismiss"
|
|
336
|
+
? { action: record.action }
|
|
337
|
+
: {}),
|
|
338
|
+
},
|
|
339
|
+
];
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
function readDownloadEntries(value) {
|
|
343
|
+
if (!Array.isArray(value))
|
|
344
|
+
return [];
|
|
345
|
+
return value.slice(0, 50).flatMap((entry) => {
|
|
346
|
+
if (!isRecord(entry))
|
|
347
|
+
return [];
|
|
348
|
+
const id = readNonNegativeInteger(entry.id);
|
|
349
|
+
const state = readString(entry.state);
|
|
350
|
+
const danger = readString(entry.danger);
|
|
351
|
+
const filenameBasename = readString(entry.filename_basename);
|
|
352
|
+
if (state === undefined ||
|
|
353
|
+
danger === undefined ||
|
|
354
|
+
filenameBasename === undefined) {
|
|
355
|
+
return [];
|
|
356
|
+
}
|
|
357
|
+
return [
|
|
358
|
+
{
|
|
359
|
+
id,
|
|
360
|
+
state: state.slice(0, 40),
|
|
361
|
+
danger: danger.slice(0, 80),
|
|
362
|
+
exists: entry.exists === true,
|
|
363
|
+
paused: entry.paused === true,
|
|
364
|
+
incognito: entry.incognito === true,
|
|
365
|
+
bytes_received: readNonNegativeInteger(entry.bytes_received),
|
|
366
|
+
total_bytes: readNonNegativeInteger(entry.total_bytes),
|
|
367
|
+
file_size: readNonNegativeInteger(entry.file_size),
|
|
368
|
+
filename_basename: pathBasename(filenameBasename).slice(0, 240),
|
|
369
|
+
...(readString(entry.mime) === undefined
|
|
370
|
+
? {}
|
|
371
|
+
: { mime: readString(entry.mime).slice(0, 160) }),
|
|
372
|
+
...(readString(entry.url) === undefined
|
|
373
|
+
? {}
|
|
374
|
+
: { url: readString(entry.url).slice(0, 2_000) }),
|
|
375
|
+
...(readString(entry.final_url) === undefined
|
|
376
|
+
? {}
|
|
377
|
+
: { final_url: readString(entry.final_url).slice(0, 2_000) }),
|
|
378
|
+
...(readString(entry.started_at) === undefined
|
|
379
|
+
? {}
|
|
380
|
+
: { started_at: readString(entry.started_at) }),
|
|
381
|
+
...(readString(entry.ended_at) === undefined
|
|
382
|
+
? {}
|
|
383
|
+
: { ended_at: readString(entry.ended_at) }),
|
|
384
|
+
...(readString(entry.error) === undefined
|
|
385
|
+
? {}
|
|
386
|
+
: { error: readString(entry.error).slice(0, 160) }),
|
|
387
|
+
},
|
|
388
|
+
];
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
function parseDownloadLimit(rawLimit) {
|
|
392
|
+
const parsed = Number.parseInt(rawLimit ?? "20", 10);
|
|
393
|
+
if (!Number.isFinite(parsed))
|
|
394
|
+
return 20;
|
|
395
|
+
return Math.max(1, Math.min(50, Math.trunc(parsed)));
|
|
396
|
+
}
|
|
397
|
+
function readNonNegativeInteger(value) {
|
|
398
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0
|
|
399
|
+
? Math.trunc(value)
|
|
400
|
+
: 0;
|
|
401
|
+
}
|
|
402
|
+
function readString(value) {
|
|
403
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
404
|
+
}
|
|
405
|
+
function readStringAllowEmpty(value) {
|
|
406
|
+
return typeof value === "string" ? value : undefined;
|
|
407
|
+
}
|
|
408
|
+
function isRecord(value) {
|
|
409
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
410
|
+
}
|
|
411
|
+
function parseBrowserCdpParams(rawParams) {
|
|
412
|
+
if (rawParams === undefined)
|
|
413
|
+
return {};
|
|
414
|
+
let parsed;
|
|
415
|
+
try {
|
|
416
|
+
parsed = JSON.parse(rawParams);
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
throw new Error("CDP params must be a JSON object.");
|
|
420
|
+
}
|
|
421
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
422
|
+
throw new Error("CDP params must be a JSON object.");
|
|
423
|
+
}
|
|
424
|
+
return parsed;
|
|
425
|
+
}
|
|
426
|
+
function assertBrowserCdpReadOnlyMethod(method) {
|
|
427
|
+
if (BROWSER_CDP_READ_ONLY_METHODS.has(method))
|
|
428
|
+
return;
|
|
429
|
+
throw new Error(`CDP method ${method} is not in the read-only allowlist. Supported methods: ${[
|
|
430
|
+
...BROWSER_CDP_READ_ONLY_METHODS,
|
|
431
|
+
].join(", ")}`);
|
|
432
|
+
}
|
|
433
|
+
function createBrowserCdpReadOnlyResult(input) {
|
|
434
|
+
const resultJson = JSON.stringify(input.result ?? null);
|
|
435
|
+
if (resultJson.length <= BROWSER_CDP_RESULT_MAX_CHARS) {
|
|
436
|
+
return {
|
|
437
|
+
ok: true,
|
|
438
|
+
evidence_type: "browser-cdp-readonly",
|
|
439
|
+
workspace: input.workspace,
|
|
440
|
+
method: input.method,
|
|
441
|
+
authority: "read_only_allowlist",
|
|
442
|
+
params_keys: Object.keys(input.params).sort(),
|
|
443
|
+
result_json_chars: resultJson.length,
|
|
444
|
+
result_truncated: false,
|
|
445
|
+
result: input.result,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
return {
|
|
449
|
+
ok: true,
|
|
450
|
+
evidence_type: "browser-cdp-readonly",
|
|
451
|
+
workspace: input.workspace,
|
|
452
|
+
method: input.method,
|
|
453
|
+
authority: "read_only_allowlist",
|
|
454
|
+
params_keys: Object.keys(input.params).sort(),
|
|
455
|
+
result_json_chars: resultJson.length,
|
|
456
|
+
result_truncated: true,
|
|
457
|
+
result_preview: resultJson.slice(0, BROWSER_CDP_RESULT_MAX_CHARS),
|
|
458
|
+
};
|
|
459
|
+
}
|
|
94
460
|
export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
95
461
|
root
|
|
96
462
|
.command("open <url>")
|
|
@@ -99,12 +465,20 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
99
465
|
const page = await getOperatorPage(root, namespace);
|
|
100
466
|
await ensureNetworkCapture(page);
|
|
101
467
|
await page.goto(url, { settleMs: 2000 });
|
|
102
|
-
const
|
|
468
|
+
const finalUrl = await page.url();
|
|
469
|
+
const [title, connectionTargetEvidence] = await Promise.all([
|
|
470
|
+
page.title(),
|
|
471
|
+
readBrowserConnectionTargetEvidence(page, finalUrl),
|
|
472
|
+
]);
|
|
103
473
|
return {
|
|
104
474
|
ok: true,
|
|
105
|
-
url,
|
|
475
|
+
requested_url: url,
|
|
476
|
+
url: finalUrl,
|
|
106
477
|
title,
|
|
107
478
|
workspace: resolveWorkspace(root, namespace),
|
|
479
|
+
...(connectionTargetEvidence
|
|
480
|
+
? { connection_target_evidence: connectionTargetEvidence }
|
|
481
|
+
: {}),
|
|
108
482
|
};
|
|
109
483
|
}));
|
|
110
484
|
root
|
|
@@ -136,6 +510,27 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
136
510
|
return { url, snapshot };
|
|
137
511
|
});
|
|
138
512
|
}));
|
|
513
|
+
root
|
|
514
|
+
.command("query <ref>")
|
|
515
|
+
.description("Read bounded DOM data from a verified snapshot ref")
|
|
516
|
+
.option("--kind <kind>", "Query kind: text, value, or attributes", "text")
|
|
517
|
+
.action((ref, opts) => operatorAction(program, root, namespace, "query", async () => {
|
|
518
|
+
validateRef(ref);
|
|
519
|
+
const kind = parseBrowserDomQueryKind(opts.kind);
|
|
520
|
+
const page = await getOperatorPage(root, namespace);
|
|
521
|
+
const selector = `[data-unicli-ref="${ref}"]`;
|
|
522
|
+
return await withRecordedBrowserAction(program, root, namespace, "query", page, { ref, kind }, async () => {
|
|
523
|
+
await verifyRef(page, selector);
|
|
524
|
+
const url = await page.url();
|
|
525
|
+
const rawResult = await page.evaluate(buildBrowserDomQueryJs(ref, kind));
|
|
526
|
+
return normalizeBrowserDomQueryResult({
|
|
527
|
+
kind,
|
|
528
|
+
rawResult,
|
|
529
|
+
ref,
|
|
530
|
+
url,
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
}));
|
|
139
534
|
root
|
|
140
535
|
.command("screenshot [path]")
|
|
141
536
|
.description("Capture page screenshot")
|
|
@@ -192,6 +587,62 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
192
587
|
screenshotDir,
|
|
193
588
|
});
|
|
194
589
|
}));
|
|
590
|
+
root
|
|
591
|
+
.command("console")
|
|
592
|
+
.description("Read bounded browser console messages and page errors")
|
|
593
|
+
.option("--clear", "Clear captured console entries after reading")
|
|
594
|
+
.option("--max <n>", "Maximum console entries to return", "50")
|
|
595
|
+
.option("--text-max <n>", "Maximum text characters per entry", "1000")
|
|
596
|
+
.action((opts) => operatorAction(program, root, namespace, "console", async () => {
|
|
597
|
+
const page = await getOperatorPage(root, namespace);
|
|
598
|
+
return await readBrowserConsole(page, {
|
|
599
|
+
clear: opts.clear === true,
|
|
600
|
+
maxEntries: parseInt(opts.max, 10),
|
|
601
|
+
maxTextChars: parseInt(opts.textMax, 10),
|
|
602
|
+
});
|
|
603
|
+
}));
|
|
604
|
+
root
|
|
605
|
+
.command("cdp <method> [params]")
|
|
606
|
+
.description("Run a read-only allowlisted Chrome DevTools Protocol command")
|
|
607
|
+
.action((method, paramsJson) => operatorAction(program, root, namespace, "cdp", async () => {
|
|
608
|
+
assertBrowserCdpReadOnlyMethod(method);
|
|
609
|
+
const params = parseBrowserCdpParams(paramsJson);
|
|
610
|
+
const page = await getOperatorPage(root, namespace);
|
|
611
|
+
const result = await page.sendCDP(method, params);
|
|
612
|
+
return createBrowserCdpReadOnlyResult({
|
|
613
|
+
workspace: resolveWorkspace(root, namespace),
|
|
614
|
+
method,
|
|
615
|
+
params,
|
|
616
|
+
result,
|
|
617
|
+
});
|
|
618
|
+
}));
|
|
619
|
+
root
|
|
620
|
+
.command("dialogs")
|
|
621
|
+
.description("Start and read provider-owned browser dialog supervision")
|
|
622
|
+
.option("--clear-recent", "Clear recent dialog records after reading")
|
|
623
|
+
.action((opts) => operatorAction(program, root, namespace, "dialogs", async () => {
|
|
624
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
625
|
+
const result = await sendCommand("dialog-read", {
|
|
626
|
+
workspace,
|
|
627
|
+
clearRecent: opts.clearRecent === true,
|
|
628
|
+
});
|
|
629
|
+
return normalizeBrowserDialogProviderResult(result, workspace);
|
|
630
|
+
}));
|
|
631
|
+
root
|
|
632
|
+
.command("dialog <action> [dialogId]")
|
|
633
|
+
.description("Respond to a pending browser JavaScript dialog")
|
|
634
|
+
.option("--prompt <text>", "Prompt text for prompt() dialogs")
|
|
635
|
+
.action((actionRaw, dialogId, opts) => operatorAction(program, root, namespace, "dialog", async () => {
|
|
636
|
+
const action = parseBrowserDialogAction(actionRaw);
|
|
637
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
638
|
+
const result = await sendCommand("dialog-respond", {
|
|
639
|
+
workspace,
|
|
640
|
+
dialogAction: action,
|
|
641
|
+
...(dialogId === undefined ? {} : { dialogId }),
|
|
642
|
+
...(opts.prompt === undefined ? {} : { promptText: opts.prompt }),
|
|
643
|
+
});
|
|
644
|
+
return normalizeBrowserDialogProviderResult(result, workspace);
|
|
645
|
+
}));
|
|
195
646
|
root
|
|
196
647
|
.command("click <ref>")
|
|
197
648
|
.description("Click element by ref number from state")
|
|
@@ -268,7 +719,14 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
268
719
|
.description("Get current URL")
|
|
269
720
|
.action(() => operatorAction(program, root, namespace, "get url", async () => {
|
|
270
721
|
const page = await getOperatorPage(root, namespace);
|
|
271
|
-
|
|
722
|
+
const url = await page.url();
|
|
723
|
+
const connectionTargetEvidence = await readBrowserConnectionTargetEvidence(page, url);
|
|
724
|
+
return {
|
|
725
|
+
value: url,
|
|
726
|
+
...(connectionTargetEvidence
|
|
727
|
+
? { connection_target_evidence: connectionTargetEvidence }
|
|
728
|
+
: {}),
|
|
729
|
+
};
|
|
272
730
|
}));
|
|
273
731
|
get
|
|
274
732
|
.command("text <ref>")
|
|
@@ -456,6 +914,19 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
456
914
|
const page = await getOperatorPage(root, namespace);
|
|
457
915
|
return await readFrames(page);
|
|
458
916
|
}));
|
|
917
|
+
root
|
|
918
|
+
.command("downloads")
|
|
919
|
+
.description("List recent browser downloads without exposing local file paths")
|
|
920
|
+
.option("--limit <n>", "Maximum download records to return", "20")
|
|
921
|
+
.action((opts) => operatorAction(program, root, namespace, "downloads", async () => {
|
|
922
|
+
const workspace = resolveWorkspace(root, namespace);
|
|
923
|
+
const limit = parseDownloadLimit(opts.limit);
|
|
924
|
+
const result = await sendCommand("downloads-read", {
|
|
925
|
+
workspace,
|
|
926
|
+
downloadLimit: limit,
|
|
927
|
+
});
|
|
928
|
+
return normalizeBrowserDownloadsProviderResult(result, workspace, limit);
|
|
929
|
+
}));
|
|
459
930
|
root
|
|
460
931
|
.command("extract")
|
|
461
932
|
.description("Extract long-form page text with chunked pagination")
|
|
@@ -516,10 +987,18 @@ export function registerBrowserOperatorSubcommands(root, program, namespace) {
|
|
|
516
987
|
root
|
|
517
988
|
.command("close")
|
|
518
989
|
.description("Close the automation browser window")
|
|
519
|
-
.
|
|
990
|
+
.option("--all", "Close or release all managed browser sessions")
|
|
991
|
+
.action((opts) => operatorAction(program, root, namespace, "close", async () => {
|
|
992
|
+
if (opts.all === true) {
|
|
993
|
+
return await closeAllBrowserSessions();
|
|
994
|
+
}
|
|
520
995
|
const page = await getOperatorPage(root, namespace);
|
|
521
996
|
await page.closeWindow();
|
|
522
|
-
return {
|
|
997
|
+
return {
|
|
998
|
+
ok: true,
|
|
999
|
+
scope: "current_managed_session",
|
|
1000
|
+
workspace: resolveWorkspace(root, namespace),
|
|
1001
|
+
};
|
|
523
1002
|
}));
|
|
524
1003
|
}
|
|
525
1004
|
//# sourceMappingURL=actions.js.map
|