tabctl 0.5.3 → 0.6.0-alpha.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.
Files changed (42) hide show
  1. package/README.md +88 -20
  2. package/dist/extension/background.js +2 -0
  3. package/dist/extension/manifest.json +2 -2
  4. package/package.json +13 -5
  5. package/dist/cli/lib/args.js +0 -141
  6. package/dist/cli/lib/client.js +0 -83
  7. package/dist/cli/lib/commands/doctor.js +0 -134
  8. package/dist/cli/lib/commands/index.js +0 -51
  9. package/dist/cli/lib/commands/list.js +0 -159
  10. package/dist/cli/lib/commands/meta.js +0 -229
  11. package/dist/cli/lib/commands/params-groups.js +0 -48
  12. package/dist/cli/lib/commands/params-move.js +0 -44
  13. package/dist/cli/lib/commands/params.js +0 -314
  14. package/dist/cli/lib/commands/profile.js +0 -91
  15. package/dist/cli/lib/commands/setup.js +0 -294
  16. package/dist/cli/lib/constants.js +0 -30
  17. package/dist/cli/lib/help.js +0 -205
  18. package/dist/cli/lib/options-commands.js +0 -274
  19. package/dist/cli/lib/options-groups.js +0 -41
  20. package/dist/cli/lib/options.js +0 -125
  21. package/dist/cli/lib/output.js +0 -147
  22. package/dist/cli/lib/pagination.js +0 -55
  23. package/dist/cli/lib/policy-filter.js +0 -202
  24. package/dist/cli/lib/policy.js +0 -91
  25. package/dist/cli/lib/report.js +0 -61
  26. package/dist/cli/lib/response.js +0 -235
  27. package/dist/cli/lib/scope.js +0 -250
  28. package/dist/cli/lib/snapshot.js +0 -216
  29. package/dist/cli/lib/types.js +0 -2
  30. package/dist/cli/tabctl.js +0 -475
  31. package/dist/host/host.bundle.js +0 -670
  32. package/dist/host/host.js +0 -143
  33. package/dist/host/host.sh +0 -5
  34. package/dist/host/launcher/go.mod +0 -3
  35. package/dist/host/launcher/main.go +0 -109
  36. package/dist/host/lib/handlers.js +0 -327
  37. package/dist/host/lib/undo.js +0 -60
  38. package/dist/shared/config.js +0 -134
  39. package/dist/shared/extension-sync.js +0 -170
  40. package/dist/shared/profiles.js +0 -78
  41. package/dist/shared/version.js +0 -8
  42. package/dist/shared/wrapper-health.js +0 -132
@@ -1,314 +0,0 @@
1
- "use strict";
2
- /**
3
- * Command parameter builders.
4
- * These functions extract and validate command parameters from CLI options.
5
- */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.buildMergeWindowParams = exports.buildMoveGroupParams = exports.buildMoveTabParams = exports.buildGroupGatherParams = exports.buildGroupUngroupParams = exports.buildGroupAssignParams = exports.buildGroupUpdateParams = void 0;
11
- exports.buildAnalyzeParams = buildAnalyzeParams;
12
- exports.buildInspectParams = buildInspectParams;
13
- exports.buildFocusParams = buildFocusParams;
14
- exports.buildRefreshParams = buildRefreshParams;
15
- exports.buildOpenParams = buildOpenParams;
16
- exports.buildArchiveParams = buildArchiveParams;
17
- exports.buildCloseParams = buildCloseParams;
18
- exports.buildReportParams = buildReportParams;
19
- exports.buildScreenshotParams = buildScreenshotParams;
20
- exports.parseWindowScope = parseWindowScope;
21
- exports.buildHistoryParams = buildHistoryParams;
22
- exports.buildUndoParams = buildUndoParams;
23
- const node_fs_1 = __importDefault(require("node:fs"));
24
- const output_1 = require("../output");
25
- const args_1 = require("../args");
26
- // ============================================================================
27
- // Shared Scope Builder
28
- // ============================================================================
29
- function buildScopeFromOptions(options, { allowNew } = { allowNew: false }) {
30
- if (options.ungrouped && options["group-id"]) {
31
- (0, output_1.errorOut)("--ungrouped cannot be combined with --group-id");
32
- }
33
- const windowId = parseWindowScope(options.window, { allowNew });
34
- return {
35
- tabIds: options.tab ? options.tab.map(Number) : undefined,
36
- groupTitle: options.group,
37
- groupId: options.ungrouped ? -1 : (options["group-id"] ? Number(options["group-id"]) : undefined),
38
- windowId,
39
- all: Boolean(options.all),
40
- };
41
- }
42
- // ============================================================================
43
- // Analyze Command Parameters
44
- // ============================================================================
45
- function buildAnalyzeParams(options) {
46
- const { tabIds, groupTitle, groupId, windowId, all } = buildScopeFromOptions(options);
47
- return {
48
- staleDays: options["stale-days"] ? Number(options["stale-days"]) : undefined,
49
- tabIds,
50
- groupTitle,
51
- groupId,
52
- windowId,
53
- all,
54
- progress: Boolean(options.progress),
55
- };
56
- }
57
- // ============================================================================
58
- // Inspect Command Parameters
59
- // ============================================================================
60
- function buildInspectParams(options) {
61
- const { tabIds, groupTitle, groupId, windowId, all } = buildScopeFromOptions(options);
62
- const selectorAttr = options["selector-attr"] ? String(options["selector-attr"]).trim() : "";
63
- const allowedSelectorAttrs = new Set(["text", "href", "src", "href-url", "src-url"]);
64
- if (options["selector-attr"] && (!selectorAttr || !allowedSelectorAttrs.has(selectorAttr))) {
65
- (0, output_1.errorOut)("Invalid --selector-attr value (use text|href|src|href-url|src-url)");
66
- }
67
- let selectorSpecs;
68
- if (options.selector) {
69
- selectorSpecs = options.selector.map((value) => {
70
- const trimmed = value.trim();
71
- if (trimmed.startsWith("{")) {
72
- try {
73
- const parsed = JSON.parse(trimmed);
74
- if (parsed && typeof parsed.selector === "string" && parsed.selector.includes(":contains(")) {
75
- (0, output_1.errorOut)("Selector :contains() is not supported; use text filters instead.");
76
- }
77
- if (selectorAttr && parsed && typeof parsed === "object" && !Object.prototype.hasOwnProperty.call(parsed, "attr")) {
78
- return { ...parsed, attr: selectorAttr };
79
- }
80
- return parsed;
81
- }
82
- catch {
83
- (0, output_1.errorOut)(`Invalid selector JSON: ${trimmed}`);
84
- }
85
- }
86
- if (trimmed.includes(":contains(")) {
87
- (0, output_1.errorOut)("Selector :contains() is not supported; use text filters instead.");
88
- }
89
- if (trimmed.includes("=")) {
90
- const [name, selector] = trimmed.split(/=(.+)/);
91
- return selectorAttr ? { name, selector, attr: selectorAttr } : { name, selector };
92
- }
93
- return selectorAttr ? { selector: trimmed, attr: selectorAttr } : { selector: trimmed };
94
- }).filter(Boolean);
95
- }
96
- let signalConfig;
97
- if (options["signal-config"]) {
98
- try {
99
- const configRaw = node_fs_1.default.readFileSync(String(options["signal-config"]), "utf8");
100
- signalConfig = JSON.parse(configRaw);
101
- }
102
- catch {
103
- (0, output_1.errorOut)("Failed to read --signal-config file");
104
- }
105
- }
106
- return {
107
- all,
108
- windowId,
109
- groupTitle,
110
- groupId,
111
- tabIds,
112
- signals: options.signal ? options.signal : undefined,
113
- selectorSpecs,
114
- signalConfig,
115
- signalConcurrency: options["signal-concurrency"] ? Number(options["signal-concurrency"]) : undefined,
116
- signalTimeoutMs: options["signal-timeout-ms"] ? Number(options["signal-timeout-ms"]) : undefined,
117
- waitFor: parseWaitFor(options["wait-for"]),
118
- waitTimeoutMs: parseWaitTimeout(options["wait-timeout-ms"]),
119
- progress: Boolean(options.progress),
120
- };
121
- }
122
- // ============================================================================
123
- // Focus/Refresh Command Parameters
124
- // ============================================================================
125
- function buildFocusParams(options) {
126
- return {
127
- tabId: options.tab ? Number(options.tab[0]) : undefined,
128
- tabIds: options.tab ? options.tab.map(Number) : undefined,
129
- };
130
- }
131
- function buildRefreshParams(options) {
132
- return {
133
- tabId: options.tab ? Number(options.tab[0]) : undefined,
134
- tabIds: options.tab ? options.tab.map(Number) : undefined,
135
- };
136
- }
137
- // ============================================================================
138
- // Open Command Parameters
139
- // ============================================================================
140
- function buildOpenParams(options) {
141
- const windowValue = parseWindowScope(options.window, { allowNew: true });
142
- const openNewWindow = options["new-window"] === true || windowValue === "new";
143
- if (options["before-tab"] != null && !Number.isFinite(Number(options["before-tab"]))) {
144
- (0, output_1.errorOut)("Invalid --before-tab value");
145
- }
146
- if (options["after-tab"] != null && !Number.isFinite(Number(options["after-tab"]))) {
147
- (0, output_1.errorOut)("Invalid --after-tab value");
148
- }
149
- if (options["before-tab"] != null && options["after-tab"] != null) {
150
- (0, output_1.errorOut)("Only one target position is allowed");
151
- }
152
- return {
153
- urls: options.url ? options.url.map(String) : undefined,
154
- groupTitle: options.group,
155
- color: (0, args_1.normalizeGroupColor)(options.color),
156
- afterGroupTitle: options["after-group"],
157
- beforeTabId: options["before-tab"] ? Number(options["before-tab"]) : undefined,
158
- afterTabId: options["after-tab"] ? Number(options["after-tab"]) : undefined,
159
- windowId: windowValue === "new" ? undefined : windowValue,
160
- newWindow: openNewWindow,
161
- windowGroupTitle: options["window-group"],
162
- windowTabId: options["window-tab"] ? Number(options["window-tab"]) : undefined,
163
- windowUrl: options["window-url"],
164
- newGroup: options["new-group"] === true,
165
- allowDuplicates: options["allow-duplicates"] === true,
166
- };
167
- }
168
- // ============================================================================
169
- // Group Command Parameters (re-exported from params-groups.ts)
170
- // ============================================================================
171
- var params_groups_1 = require("./params-groups");
172
- Object.defineProperty(exports, "buildGroupUpdateParams", { enumerable: true, get: function () { return params_groups_1.buildGroupUpdateParams; } });
173
- Object.defineProperty(exports, "buildGroupAssignParams", { enumerable: true, get: function () { return params_groups_1.buildGroupAssignParams; } });
174
- Object.defineProperty(exports, "buildGroupUngroupParams", { enumerable: true, get: function () { return params_groups_1.buildGroupUngroupParams; } });
175
- Object.defineProperty(exports, "buildGroupGatherParams", { enumerable: true, get: function () { return params_groups_1.buildGroupGatherParams; } });
176
- // ============================================================================
177
- // Move Command Parameters (re-exported from params-move.ts)
178
- // ============================================================================
179
- var params_move_1 = require("./params-move");
180
- Object.defineProperty(exports, "buildMoveTabParams", { enumerable: true, get: function () { return params_move_1.buildMoveTabParams; } });
181
- Object.defineProperty(exports, "buildMoveGroupParams", { enumerable: true, get: function () { return params_move_1.buildMoveGroupParams; } });
182
- Object.defineProperty(exports, "buildMergeWindowParams", { enumerable: true, get: function () { return params_move_1.buildMergeWindowParams; } });
183
- // ============================================================================
184
- // Archive/Close Command Parameters
185
- // ============================================================================
186
- function buildArchiveParams(options) {
187
- const { tabIds, groupTitle, groupId, windowId, all } = buildScopeFromOptions(options);
188
- return {
189
- all,
190
- windowId,
191
- groupTitle,
192
- groupId,
193
- tabIds,
194
- };
195
- }
196
- function buildCloseParams(options) {
197
- const { tabIds, groupTitle, groupId, windowId } = buildScopeFromOptions(options);
198
- if (options.apply) {
199
- return { mode: "apply", analysisId: options.apply };
200
- }
201
- if (!options.confirm) {
202
- (0, output_1.errorOut)("Direct close requires --confirm");
203
- }
204
- return {
205
- mode: "direct",
206
- confirmed: true,
207
- windowId,
208
- groupTitle,
209
- groupId,
210
- tabIds,
211
- };
212
- }
213
- // ============================================================================
214
- // Report Command Parameters
215
- // ============================================================================
216
- function buildReportParams(options) {
217
- const { tabIds, groupTitle, groupId, windowId, all } = buildScopeFromOptions(options);
218
- return {
219
- all,
220
- windowId,
221
- groupTitle,
222
- groupId,
223
- tabIds,
224
- };
225
- }
226
- // ============================================================================
227
- // Screenshot Command Parameters
228
- // ============================================================================
229
- function buildScreenshotParams(options) {
230
- const { tabIds, groupTitle, groupId, windowId, all } = buildScopeFromOptions(options);
231
- const outDir = options.out != null ? String(options.out).trim() : "";
232
- if (options.out && !outDir) {
233
- (0, output_1.errorOut)("--out requires a directory path");
234
- }
235
- return {
236
- all,
237
- windowId,
238
- groupTitle,
239
- groupId,
240
- tabIds,
241
- mode: options.mode,
242
- format: options.format,
243
- quality: options.quality != null ? Number(options.quality) : undefined,
244
- tileMaxDim: options["tile-max-dim"] != null ? Number(options["tile-max-dim"]) : undefined,
245
- maxBytes: options["max-bytes"] != null ? Number(options["max-bytes"]) : undefined,
246
- waitFor: parseWaitFor(options["wait-for"]),
247
- waitTimeoutMs: parseWaitTimeout(options["wait-timeout-ms"]),
248
- outDir: outDir || undefined,
249
- progress: Boolean(options.progress),
250
- };
251
- }
252
- const VALID_WAIT_FOR = ["load", "dom", "settle", "none"];
253
- function parseWaitFor(value) {
254
- if (value == null) {
255
- return undefined;
256
- }
257
- const normalized = String(value).trim().toLowerCase();
258
- if (!normalized) {
259
- return undefined;
260
- }
261
- if (!VALID_WAIT_FOR.includes(normalized)) {
262
- (0, output_1.errorOut)(`Invalid --wait-for value (use ${VALID_WAIT_FOR.join("|")})`);
263
- }
264
- return normalized;
265
- }
266
- function parseWaitTimeout(value) {
267
- if (value == null) {
268
- return undefined;
269
- }
270
- const parsed = Number(value);
271
- if (!Number.isFinite(parsed) || parsed <= 0) {
272
- (0, output_1.errorOut)("Invalid --wait-timeout-ms value");
273
- }
274
- return Math.floor(parsed);
275
- }
276
- function parseWindowScope(value, { allowNew }) {
277
- if (value == null) {
278
- return undefined;
279
- }
280
- if (typeof value === "string") {
281
- const trimmed = value.trim().toLowerCase();
282
- if (!trimmed) {
283
- return undefined;
284
- }
285
- if (trimmed === "active" || trimmed === "last-focused") {
286
- return trimmed;
287
- }
288
- if (trimmed === "new") {
289
- if (!allowNew) {
290
- (0, output_1.errorOut)("--window new is only supported by open");
291
- }
292
- return trimmed;
293
- }
294
- }
295
- const numeric = Number(value);
296
- if (!Number.isFinite(numeric)) {
297
- (0, output_1.errorOut)("Invalid --window value");
298
- }
299
- return numeric;
300
- }
301
- // ============================================================================
302
- // History/Undo Command Parameters
303
- // ============================================================================
304
- function buildHistoryParams(options) {
305
- return {
306
- limit: options.limit ? Number(options.limit) : undefined,
307
- };
308
- }
309
- function buildUndoParams(options) {
310
- return {
311
- txid: options._[0] || options.txid,
312
- latest: options.latest === true,
313
- };
314
- }
@@ -1,91 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runProfileList = runProfileList;
4
- exports.runProfileShow = runProfileShow;
5
- exports.runProfileSwitch = runProfileSwitch;
6
- exports.runProfileRemove = runProfileRemove;
7
- const constants_1 = require("../constants");
8
- const output_1 = require("../output");
9
- const profiles_1 = require("../../../shared/profiles");
10
- function runProfileList(options, prettyOutput) {
11
- const profiles = (0, profiles_1.listProfiles)();
12
- (0, output_1.printJson)({
13
- ok: true,
14
- action: "profile-list",
15
- data: {
16
- profiles: profiles.map(({ name, profile, isDefault }) => ({
17
- name,
18
- browser: profile.browser,
19
- dataDir: profile.dataDir,
20
- isDefault,
21
- })),
22
- },
23
- }, prettyOutput);
24
- }
25
- function runProfileShow(options, prettyOutput) {
26
- const config = (0, constants_1.resolveConfig)();
27
- const active = (0, profiles_1.getActiveProfile)();
28
- if (!active) {
29
- (0, output_1.printJson)({
30
- ok: true,
31
- action: "profile-show",
32
- data: {
33
- mode: "legacy",
34
- message: "No profiles configured. Run tabctl setup to create one.",
35
- dataDir: config.dataDir,
36
- socketPath: config.socketPath,
37
- policyPath: config.policyPath,
38
- },
39
- }, prettyOutput);
40
- return;
41
- }
42
- const registry = (0, profiles_1.loadProfiles)();
43
- (0, output_1.printJson)({
44
- ok: true,
45
- action: "profile-show",
46
- data: {
47
- name: active.name,
48
- browser: active.profile.browser,
49
- extensionId: active.profile.extensionId,
50
- dataDir: active.profile.dataDir,
51
- ...(active.profile.userDataDir ? { userDataDir: active.profile.userDataDir } : {}),
52
- socketPath: config.socketPath,
53
- policyPath: config.policyPath,
54
- isDefault: active.name === registry.default,
55
- },
56
- }, prettyOutput);
57
- }
58
- function runProfileSwitch(options, prettyOutput) {
59
- const name = options._[0];
60
- if (!name) {
61
- (0, output_1.errorOut)("Usage: tabctl profile-switch <name>");
62
- }
63
- const registry = (0, profiles_1.loadProfiles)();
64
- if (!(name in registry.profiles)) {
65
- (0, output_1.errorOut)(`Profile "${name}" not found`);
66
- }
67
- registry.default = name;
68
- (0, profiles_1.saveProfiles)(registry);
69
- (0, output_1.printJson)({
70
- ok: true,
71
- action: "profile-switch",
72
- data: { name, message: `Default profile set to "${name}"` },
73
- }, prettyOutput);
74
- }
75
- function runProfileRemove(options, prettyOutput) {
76
- const name = options._[0];
77
- if (!name) {
78
- (0, output_1.errorOut)("Usage: tabctl profile-remove <name>");
79
- }
80
- try {
81
- const registry = (0, profiles_1.removeProfile)(name);
82
- (0, output_1.printJson)({
83
- ok: true,
84
- action: "profile-remove",
85
- data: { name, newDefault: registry.default, message: `Profile "${name}" removed` },
86
- }, prettyOutput);
87
- }
88
- catch (err) {
89
- (0, output_1.errorOut)(err.message);
90
- }
91
- }