tabctl 0.1.4 → 0.2.1
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/{cli → dist/cli}/lib/commands/index.js +4 -2
- package/dist/cli/lib/commands/meta.js +226 -0
- package/dist/cli/lib/commands/params-groups.js +40 -0
- package/dist/cli/lib/commands/params-move.js +44 -0
- package/{cli → dist/cli}/lib/commands/params.js +61 -125
- package/{cli/lib/commands/meta.js → dist/cli/lib/commands/setup.js} +26 -222
- package/{cli/lib/options.js → dist/cli/lib/options-commands.js} +3 -155
- package/dist/cli/lib/options-groups.js +41 -0
- package/dist/cli/lib/options.js +125 -0
- package/{cli → dist/cli}/lib/output.js +5 -4
- package/dist/cli/lib/policy-filter.js +202 -0
- package/dist/cli/lib/response.js +235 -0
- package/{cli → dist/cli}/lib/scope.js +3 -31
- package/dist/cli/tabctl.js +463 -0
- package/dist/extension/background.js +3398 -0
- package/dist/extension/lib/archive.js +444 -0
- package/dist/extension/lib/content.js +320 -0
- package/dist/extension/lib/deps.js +4 -0
- package/dist/extension/lib/groups.js +443 -0
- package/dist/extension/lib/inspect.js +316 -0
- package/dist/extension/lib/move.js +342 -0
- package/dist/extension/lib/screenshot.js +367 -0
- package/dist/extension/lib/tabs.js +395 -0
- package/dist/extension/lib/undo-handlers.js +439 -0
- package/{extension → dist/extension}/manifest.json +2 -2
- package/dist/host/host.js +124 -0
- package/{host/host.js → dist/host/lib/handlers.js} +84 -187
- package/{shared → dist/shared}/version.js +2 -2
- package/package.json +12 -10
- package/cli/tabctl.js +0 -841
- package/extension/background.js +0 -3372
- package/extension/manifest.template.json +0 -22
- /package/{cli → dist/cli}/lib/args.js +0 -0
- /package/{cli → dist/cli}/lib/client.js +0 -0
- /package/{cli → dist/cli}/lib/commands/list.js +0 -0
- /package/{cli → dist/cli}/lib/commands/profile.js +0 -0
- /package/{cli → dist/cli}/lib/constants.js +0 -0
- /package/{cli → dist/cli}/lib/help.js +0 -0
- /package/{cli → dist/cli}/lib/pagination.js +0 -0
- /package/{cli → dist/cli}/lib/policy.js +0 -0
- /package/{cli → dist/cli}/lib/report.js +0 -0
- /package/{cli → dist/cli}/lib/snapshot.js +0 -0
- /package/{cli → dist/cli}/lib/types.js +0 -0
- /package/{host → dist/host}/host.sh +0 -0
- /package/{host → dist/host}/lib/undo.js +0 -0
- /package/{shared → dist/shared}/config.js +0 -0
- /package/{shared → dist/shared}/extension-sync.js +0 -0
- /package/{shared → dist/shared}/profiles.js +0 -0
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const policy_1 = require("./lib/policy");
|
|
5
|
+
const constants_1 = require("./lib/constants");
|
|
6
|
+
const output_1 = require("./lib/output");
|
|
7
|
+
const args_1 = require("./lib/args");
|
|
8
|
+
const client_1 = require("./lib/client");
|
|
9
|
+
const help_1 = require("./lib/help");
|
|
10
|
+
const response_1 = require("./lib/response");
|
|
11
|
+
const policy_filter_1 = require("./lib/policy-filter");
|
|
12
|
+
const commands_1 = require("./lib/commands");
|
|
13
|
+
const commands_2 = require("./lib/commands");
|
|
14
|
+
const createId = client_1.createRequestId;
|
|
15
|
+
async function main() {
|
|
16
|
+
(0, output_1.setupStdoutErrorHandling)();
|
|
17
|
+
let { command, options, warnings } = (0, args_1.parseArgs)(process.argv.slice(2));
|
|
18
|
+
if (typeof options.profile === "string" && options.profile) {
|
|
19
|
+
process.env.TABCTL_PROFILE = options.profile;
|
|
20
|
+
}
|
|
21
|
+
if (command === "dedupe" && options.close) {
|
|
22
|
+
(0, output_1.errorOut)("dedupe does not support --close; use --confirm or close --apply <analysisId>.");
|
|
23
|
+
}
|
|
24
|
+
const prettyOutput = options.pretty !== false;
|
|
25
|
+
if (command === "groups" || command === "group") {
|
|
26
|
+
command = "group-list";
|
|
27
|
+
}
|
|
28
|
+
if (command === "profile" || command === "profiles") {
|
|
29
|
+
command = "profile-list";
|
|
30
|
+
}
|
|
31
|
+
if (command === "list" && options.groups === true) {
|
|
32
|
+
command = "group-list";
|
|
33
|
+
}
|
|
34
|
+
if (options.format && command !== "report" && command !== "screenshot") {
|
|
35
|
+
(0, output_1.errorOut)("Unknown option: --format");
|
|
36
|
+
}
|
|
37
|
+
if (Object.prototype.hasOwnProperty.call(options, "policy")) {
|
|
38
|
+
(0, output_1.errorOut)("Custom policy path is not supported. Use XDG_CONFIG_HOME/tabctl/policy.json.");
|
|
39
|
+
}
|
|
40
|
+
if (command === "refresh") {
|
|
41
|
+
const tabValues = Array.isArray(options.tab)
|
|
42
|
+
? options.tab.map((value) => String(value).trim()).filter(Boolean)
|
|
43
|
+
: [];
|
|
44
|
+
if (tabValues.length === 0) {
|
|
45
|
+
(0, output_1.errorOut)("refresh requires --tab");
|
|
46
|
+
}
|
|
47
|
+
if (tabValues.length > 1) {
|
|
48
|
+
(0, output_1.errorOut)("refresh requires a single --tab");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (command === "open" && options.color && !options.group) {
|
|
52
|
+
(0, output_1.errorOut)("--color requires --group");
|
|
53
|
+
}
|
|
54
|
+
if (command === "undo") {
|
|
55
|
+
if (options.txid && options._.length > 0) {
|
|
56
|
+
(0, output_1.errorOut)("undo requires a single txid (use positional arg or --txid)");
|
|
57
|
+
}
|
|
58
|
+
if (options.latest === true && options._.length > 0) {
|
|
59
|
+
(0, output_1.errorOut)("undo --latest cannot be combined with a txid");
|
|
60
|
+
}
|
|
61
|
+
if (options.latest === true && options.txid) {
|
|
62
|
+
(0, output_1.errorOut)("undo --latest cannot be combined with --txid");
|
|
63
|
+
}
|
|
64
|
+
if (options.txid && options._.length === 0) {
|
|
65
|
+
options._ = [String(options.txid)];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (command === "inspect") {
|
|
69
|
+
const selectorCount = Array.isArray(options.selector) ? options.selector.length : 0;
|
|
70
|
+
if (selectorCount > 0) {
|
|
71
|
+
const signalList = (0, args_1.normalizeSignals)(options.signal);
|
|
72
|
+
if (!signalList.includes("selector")) {
|
|
73
|
+
signalList.push("selector");
|
|
74
|
+
}
|
|
75
|
+
options.signal = signalList;
|
|
76
|
+
}
|
|
77
|
+
const signalList = (0, args_1.normalizeSignals)(options.signal);
|
|
78
|
+
if (signalList.length > 0) {
|
|
79
|
+
(0, args_1.validateSignals)(signalList);
|
|
80
|
+
options.signal = signalList;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (command === "screenshot") {
|
|
84
|
+
const mode = options.mode != null ? String(options.mode).trim().toLowerCase() : "viewport";
|
|
85
|
+
const format = options.format != null ? String(options.format).trim().toLowerCase() : "png";
|
|
86
|
+
if (mode !== "viewport" && mode !== "full") {
|
|
87
|
+
(0, output_1.errorOut)("Invalid --mode value (use viewport or full)");
|
|
88
|
+
}
|
|
89
|
+
if (format !== "png" && format !== "jpeg") {
|
|
90
|
+
(0, output_1.errorOut)("Invalid --format value (use png or jpeg)");
|
|
91
|
+
}
|
|
92
|
+
if (format === "jpeg" && options.quality == null) {
|
|
93
|
+
options.quality = 80;
|
|
94
|
+
}
|
|
95
|
+
const qualityRaw = options.quality != null ? Number(options.quality) : null;
|
|
96
|
+
if (qualityRaw != null && (!Number.isFinite(qualityRaw) || qualityRaw < 0 || qualityRaw > 100)) {
|
|
97
|
+
(0, output_1.errorOut)("Invalid --quality value (use 0-100)");
|
|
98
|
+
}
|
|
99
|
+
if (qualityRaw != null && format !== "jpeg") {
|
|
100
|
+
(0, output_1.errorOut)("--quality requires --format jpeg");
|
|
101
|
+
}
|
|
102
|
+
const tileMaxDimRaw = options["tile-max-dim"] != null ? Number(options["tile-max-dim"]) : null;
|
|
103
|
+
if (tileMaxDimRaw != null && (!Number.isFinite(tileMaxDimRaw) || tileMaxDimRaw <= 0)) {
|
|
104
|
+
(0, output_1.errorOut)("Invalid --tile-max-dim value");
|
|
105
|
+
}
|
|
106
|
+
const maxBytesRaw = options["max-bytes"] != null ? Number(options["max-bytes"]) : null;
|
|
107
|
+
if (maxBytesRaw != null && (!Number.isFinite(maxBytesRaw) || maxBytesRaw <= 0)) {
|
|
108
|
+
(0, output_1.errorOut)("Invalid --max-bytes value");
|
|
109
|
+
}
|
|
110
|
+
if (mode === "viewport" && options["tile-max-dim"] != null) {
|
|
111
|
+
(0, output_1.errorOut)("--tile-max-dim requires --mode full");
|
|
112
|
+
}
|
|
113
|
+
if (mode === "viewport" && options["max-bytes"] != null) {
|
|
114
|
+
(0, output_1.errorOut)("--max-bytes requires --mode full");
|
|
115
|
+
}
|
|
116
|
+
if (options.mode == null) {
|
|
117
|
+
options.mode = "viewport";
|
|
118
|
+
}
|
|
119
|
+
if (options.format == null) {
|
|
120
|
+
options.format = "png";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const policyContext = (0, policy_1.loadPolicy)();
|
|
124
|
+
const policySummary = (0, policy_1.summarizePolicy)(policyContext.policy, policyContext.path);
|
|
125
|
+
const policyEnabled = policyContext.policy !== null;
|
|
126
|
+
const enforcePolicy = policyEnabled;
|
|
127
|
+
const includeWindowTitle = options["window-title"] === true;
|
|
128
|
+
const includeStale = options["include-stale"] === true;
|
|
129
|
+
let policySnapshot = null;
|
|
130
|
+
const getPolicySnapshot = async () => {
|
|
131
|
+
if (!policySnapshot) {
|
|
132
|
+
policySnapshot = await (0, client_1.fetchSnapshot)();
|
|
133
|
+
}
|
|
134
|
+
return policySnapshot;
|
|
135
|
+
};
|
|
136
|
+
if (!command || command === "help" || options.help) {
|
|
137
|
+
const helpTarget = command === "help"
|
|
138
|
+
? (options._.length > 0 ? String(options._[0]) : undefined)
|
|
139
|
+
: command;
|
|
140
|
+
(0, help_1.printHelp)(options.json === true, helpTarget);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (warnings.length > 0) {
|
|
144
|
+
for (const warning of warnings) {
|
|
145
|
+
process.stderr.write(`[tabctl] warning: ${warning}\n`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (command === "skill") {
|
|
149
|
+
(0, commands_1.runSkillInstall)(options, prettyOutput);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (command === "setup") {
|
|
153
|
+
await (0, commands_1.runSetup)(options, prettyOutput);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (command === "version") {
|
|
157
|
+
(0, commands_1.runVersion)(prettyOutput);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (command === "policy") {
|
|
161
|
+
(0, commands_1.runPolicy)(options, policyContext, prettyOutput);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (command === "ping") {
|
|
165
|
+
await (0, commands_1.runPing)(prettyOutput);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (command === "history") {
|
|
169
|
+
await (0, commands_1.runHistory)(options, prettyOutput);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (command === "undo") {
|
|
173
|
+
await (0, commands_1.runUndo)(options, prettyOutput);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (command === "profile-list") {
|
|
177
|
+
(0, commands_1.runProfileList)(options, prettyOutput);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (command === "profile-show") {
|
|
181
|
+
(0, commands_1.runProfileShow)(options, prettyOutput);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (command === "profile-switch") {
|
|
185
|
+
(0, commands_1.runProfileSwitch)(options, prettyOutput);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (command === "profile-remove") {
|
|
189
|
+
(0, commands_1.runProfileRemove)(options, prettyOutput);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (command === "list") {
|
|
193
|
+
await (0, commands_1.runList)(options, policyContext, policySummary, prettyOutput);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (command === "group-list") {
|
|
197
|
+
await (0, commands_1.runGroupList)(options, policyContext, policySummary, prettyOutput);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
let dedupeMode = false;
|
|
201
|
+
if (command === "close" && options["dry-run"]) {
|
|
202
|
+
command = "analyze";
|
|
203
|
+
}
|
|
204
|
+
if (command === "dedupe") {
|
|
205
|
+
dedupeMode = true;
|
|
206
|
+
command = "analyze";
|
|
207
|
+
}
|
|
208
|
+
let action = command;
|
|
209
|
+
let params = {};
|
|
210
|
+
let policyInfo = null;
|
|
211
|
+
let earlyResponse = null;
|
|
212
|
+
switch (command) {
|
|
213
|
+
case "analyze":
|
|
214
|
+
action = "analyze";
|
|
215
|
+
params = (0, commands_2.buildAnalyzeParams)(options);
|
|
216
|
+
break;
|
|
217
|
+
case "inspect":
|
|
218
|
+
action = "inspect";
|
|
219
|
+
params = (0, commands_2.buildInspectParams)(options);
|
|
220
|
+
break;
|
|
221
|
+
case "focus":
|
|
222
|
+
action = "focus";
|
|
223
|
+
params = (0, commands_2.buildFocusParams)(options);
|
|
224
|
+
break;
|
|
225
|
+
case "refresh":
|
|
226
|
+
action = "refresh";
|
|
227
|
+
params = (0, commands_2.buildRefreshParams)(options);
|
|
228
|
+
break;
|
|
229
|
+
case "open":
|
|
230
|
+
action = "open";
|
|
231
|
+
params = (0, commands_2.buildOpenParams)(options);
|
|
232
|
+
break;
|
|
233
|
+
case "group-update":
|
|
234
|
+
action = "group-update";
|
|
235
|
+
params = (0, commands_2.buildGroupUpdateParams)(options);
|
|
236
|
+
break;
|
|
237
|
+
case "group-ungroup":
|
|
238
|
+
action = "group-ungroup";
|
|
239
|
+
params = (0, commands_2.buildGroupUngroupParams)(options);
|
|
240
|
+
break;
|
|
241
|
+
case "group-assign":
|
|
242
|
+
action = "group-assign";
|
|
243
|
+
params = (0, commands_2.buildGroupAssignParams)(options);
|
|
244
|
+
break;
|
|
245
|
+
case "move-tab":
|
|
246
|
+
action = "move-tab";
|
|
247
|
+
params = (0, commands_2.buildMoveTabParams)(options);
|
|
248
|
+
break;
|
|
249
|
+
case "move-group":
|
|
250
|
+
action = "move-group";
|
|
251
|
+
params = (0, commands_2.buildMoveGroupParams)(options);
|
|
252
|
+
break;
|
|
253
|
+
case "merge-window":
|
|
254
|
+
action = "merge-window";
|
|
255
|
+
params = (0, commands_2.buildMergeWindowParams)(options);
|
|
256
|
+
break;
|
|
257
|
+
case "archive":
|
|
258
|
+
action = "archive";
|
|
259
|
+
params = (0, commands_2.buildArchiveParams)(options);
|
|
260
|
+
break;
|
|
261
|
+
case "close":
|
|
262
|
+
action = "close";
|
|
263
|
+
params = (0, commands_2.buildCloseParams)(options);
|
|
264
|
+
break;
|
|
265
|
+
case "report":
|
|
266
|
+
action = "report";
|
|
267
|
+
params = (0, commands_2.buildReportParams)(options);
|
|
268
|
+
break;
|
|
269
|
+
case "screenshot":
|
|
270
|
+
action = "screenshot";
|
|
271
|
+
params = (0, commands_2.buildScreenshotParams)(options);
|
|
272
|
+
break;
|
|
273
|
+
default:
|
|
274
|
+
(0, output_1.errorOut)(`Unknown command: ${command}`);
|
|
275
|
+
}
|
|
276
|
+
if (command === "analyze") {
|
|
277
|
+
const tabIds = params.tabIds;
|
|
278
|
+
const windowId = params.windowId;
|
|
279
|
+
const hasScope = (Array.isArray(tabIds) && tabIds.length > 0)
|
|
280
|
+
|| Boolean(params.groupTitle)
|
|
281
|
+
|| Number.isFinite(params.groupId)
|
|
282
|
+
|| (typeof windowId === "number" && Number.isFinite(windowId))
|
|
283
|
+
|| (typeof windowId === "string" && windowId.length > 0)
|
|
284
|
+
|| params.all === true;
|
|
285
|
+
if (!hasScope) {
|
|
286
|
+
params = { ...params, all: true };
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (command === "merge-window") {
|
|
290
|
+
const fromWindowId = params.fromWindowId;
|
|
291
|
+
const toWindowId = params.toWindowId;
|
|
292
|
+
if (!Number.isFinite(fromWindowId) || !Number.isFinite(toWindowId)) {
|
|
293
|
+
(0, output_1.errorOut)("merge-window requires --from and --to window ids");
|
|
294
|
+
}
|
|
295
|
+
if (fromWindowId === toWindowId) {
|
|
296
|
+
(0, output_1.errorOut)("merge-window --from and --to cannot be the same window");
|
|
297
|
+
}
|
|
298
|
+
if (params.closeSource && !params.confirmed) {
|
|
299
|
+
(0, output_1.errorOut)("merge-window --close-source requires --confirm");
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (enforcePolicy && ["analyze", "inspect", "report", "screenshot", "close", "archive", "focus", "refresh", "move-tab", "move-group", "group-assign", "group-update", "group-ungroup", "merge-window"].includes(command)) {
|
|
303
|
+
if (command === "close" && options.apply) {
|
|
304
|
+
(0, output_1.errorOut)("Policy blocks close --apply; use explicit tab targets.");
|
|
305
|
+
}
|
|
306
|
+
const snapshot = await getPolicySnapshot();
|
|
307
|
+
if (!snapshot) {
|
|
308
|
+
(0, output_1.errorOut)("Failed to load tabs for policy evaluation");
|
|
309
|
+
}
|
|
310
|
+
const filterResult = (0, policy_filter_1.applyPolicyFilter)(command, params, snapshot, policyContext, policySummary);
|
|
311
|
+
if (filterResult.earlyResponse && !filterResult.earlyResponse.ok) {
|
|
312
|
+
(0, output_1.printJson)(filterResult.earlyResponse, prettyOutput);
|
|
313
|
+
process.exit(1);
|
|
314
|
+
}
|
|
315
|
+
params = filterResult.params;
|
|
316
|
+
policyInfo = filterResult.policyInfo;
|
|
317
|
+
earlyResponse = filterResult.earlyResponse;
|
|
318
|
+
}
|
|
319
|
+
const request = {
|
|
320
|
+
id: createId(),
|
|
321
|
+
action,
|
|
322
|
+
params,
|
|
323
|
+
client: {
|
|
324
|
+
component: "cli",
|
|
325
|
+
version: constants_1.VERSION,
|
|
326
|
+
baseVersion: constants_1.BASE_VERSION,
|
|
327
|
+
gitSha: constants_1.GIT_SHA,
|
|
328
|
+
dirty: constants_1.DIRTY,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
let response;
|
|
332
|
+
const showProgress = options.progress === true;
|
|
333
|
+
const startedAt = Date.now();
|
|
334
|
+
let progressTimer = null;
|
|
335
|
+
if (showProgress) {
|
|
336
|
+
progressTimer = setInterval(() => {
|
|
337
|
+
const elapsed = Math.round((Date.now() - startedAt) / 1000);
|
|
338
|
+
process.stderr.write(`[tabctl] waiting ${elapsed}s...\n`);
|
|
339
|
+
}, 2000);
|
|
340
|
+
}
|
|
341
|
+
const onProgress = showProgress
|
|
342
|
+
? (message) => {
|
|
343
|
+
const data = message.data;
|
|
344
|
+
if (data?.phase === "github") {
|
|
345
|
+
const processed = data.processed;
|
|
346
|
+
const total = data.total;
|
|
347
|
+
const matched = data.matched;
|
|
348
|
+
process.stderr.write(`[tabctl] github ${processed}/${total} (matched ${matched})\n`);
|
|
349
|
+
}
|
|
350
|
+
if (data?.phase === "inspect") {
|
|
351
|
+
const processed = data.processed;
|
|
352
|
+
const total = data.total;
|
|
353
|
+
const signalId = data.signalId;
|
|
354
|
+
process.stderr.write(`[tabctl] inspect ${processed}/${total} (${signalId})\n`);
|
|
355
|
+
}
|
|
356
|
+
if (data?.phase === "screenshot") {
|
|
357
|
+
const processed = data.processed;
|
|
358
|
+
const total = data.total;
|
|
359
|
+
process.stderr.write(`[tabctl] screenshot ${processed}/${total}\n`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
: undefined;
|
|
363
|
+
if (earlyResponse) {
|
|
364
|
+
response = earlyResponse;
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
try {
|
|
368
|
+
response = await (0, client_1.sendRequest)(request, onProgress);
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
if (progressTimer) {
|
|
372
|
+
clearInterval(progressTimer);
|
|
373
|
+
}
|
|
374
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
375
|
+
(0, output_1.errorOut)(`Failed to connect to host: ${message}`);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
finally {
|
|
379
|
+
if (progressTimer) {
|
|
380
|
+
clearInterval(progressTimer);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (progressTimer) {
|
|
385
|
+
clearInterval(progressTimer);
|
|
386
|
+
}
|
|
387
|
+
if (!response) {
|
|
388
|
+
(0, output_1.errorOut)("No response received");
|
|
389
|
+
}
|
|
390
|
+
if (!response.ok) {
|
|
391
|
+
(0, output_1.printJson)(response, prettyOutput);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
394
|
+
if (response.data && typeof response.data === "object") {
|
|
395
|
+
const data = response.data;
|
|
396
|
+
if ((command === "inspect" || command === "report" || command === "screenshot") && Array.isArray(data.entries)) {
|
|
397
|
+
let snapshot = null;
|
|
398
|
+
if (policyEnabled) {
|
|
399
|
+
snapshot = await getPolicySnapshot();
|
|
400
|
+
}
|
|
401
|
+
(0, response_1.annotateEntries)(data, options, command, policyEnabled, policyContext.policy, snapshot);
|
|
402
|
+
}
|
|
403
|
+
if (command === "analyze" && Array.isArray(data.candidates)) {
|
|
404
|
+
let snapshot = null;
|
|
405
|
+
if (policyEnabled || includeWindowTitle) {
|
|
406
|
+
snapshot = await getPolicySnapshot();
|
|
407
|
+
}
|
|
408
|
+
(0, response_1.annotateCandidates)(data, policyContext.policy, includeWindowTitle, snapshot);
|
|
409
|
+
}
|
|
410
|
+
data.policy = policySummary;
|
|
411
|
+
if (policyInfo) {
|
|
412
|
+
data.policyInfo = policyInfo;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
else if (response.ok) {
|
|
416
|
+
response.policy = policySummary;
|
|
417
|
+
}
|
|
418
|
+
if (dedupeMode) {
|
|
419
|
+
if (!response.ok) {
|
|
420
|
+
(0, output_1.printJson)(response, prettyOutput);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const { planTabIds, expectedUrls } = (0, response_1.extractDedupePlan)(response, includeStale);
|
|
424
|
+
let closeData = null;
|
|
425
|
+
if (options.confirm === true && planTabIds.length > 0) {
|
|
426
|
+
const closeResponse = await (0, client_1.sendRequest)({
|
|
427
|
+
id: createId(),
|
|
428
|
+
action: "close",
|
|
429
|
+
params: {
|
|
430
|
+
mode: "direct",
|
|
431
|
+
confirmed: true,
|
|
432
|
+
tabIds: planTabIds,
|
|
433
|
+
expectedUrls,
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
if (!closeResponse.ok) {
|
|
437
|
+
(0, output_1.printJson)(closeResponse, prettyOutput);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
closeData = closeResponse.data || {};
|
|
441
|
+
closeData.policy = policySummary;
|
|
442
|
+
if (policyInfo) {
|
|
443
|
+
closeData.policyInfo = policyInfo;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
const output = (0, response_1.buildDedupeOutput)(response, includeStale, closeData, options.confirm === true);
|
|
447
|
+
(0, output_1.printJson)(output, prettyOutput);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (command === "report") {
|
|
451
|
+
(0, response_1.formatReport)(response, options, prettyOutput);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (command === "screenshot") {
|
|
455
|
+
(0, response_1.writeScreenshots)(response, options, prettyOutput);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
(0, output_1.emitVersionWarnings)(response, command);
|
|
459
|
+
(0, output_1.printJson)(response, prettyOutput);
|
|
460
|
+
}
|
|
461
|
+
main().catch((error) => {
|
|
462
|
+
(0, output_1.errorOut)(error.message || "Unknown error");
|
|
463
|
+
});
|