tabctl 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +261 -0
- package/cli/lib/args.js +141 -0
- package/cli/lib/client.js +62 -0
- package/cli/lib/commands/index.js +45 -0
- package/cli/lib/commands/list.js +159 -0
- package/cli/lib/commands/meta.js +493 -0
- package/cli/lib/commands/params.js +378 -0
- package/cli/lib/commands/profile.js +91 -0
- package/cli/lib/constants.js +30 -0
- package/cli/lib/help.js +205 -0
- package/cli/lib/options.js +408 -0
- package/cli/lib/output.js +64 -0
- package/cli/lib/pagination.js +55 -0
- package/cli/lib/policy.js +91 -0
- package/cli/lib/report.js +61 -0
- package/cli/lib/scope.js +278 -0
- package/cli/lib/snapshot.js +216 -0
- package/cli/lib/types.js +2 -0
- package/cli/tabctl.js +841 -0
- package/extension/background.js +3372 -0
- package/extension/manifest.json +23 -0
- package/extension/manifest.template.json +22 -0
- package/host/host.js +428 -0
- package/host/host.sh +5 -0
- package/host/lib/undo.js +60 -0
- package/package.json +43 -0
- package/shared/config.js +111 -0
- package/shared/extension-sync.js +70 -0
- package/shared/profiles.js +78 -0
- package/shared/version.js +7 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.EXTENSION_DIR_NAME = void 0;
|
|
7
|
+
exports.resolveBundledExtensionDir = resolveBundledExtensionDir;
|
|
8
|
+
exports.resolveInstalledExtensionDir = resolveInstalledExtensionDir;
|
|
9
|
+
exports.readExtensionVersion = readExtensionVersion;
|
|
10
|
+
exports.syncExtension = syncExtension;
|
|
11
|
+
exports.checkExtensionSync = checkExtensionSync;
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const config_1 = require("./config");
|
|
15
|
+
exports.EXTENSION_DIR_NAME = "extension";
|
|
16
|
+
function resolveBundledExtensionDir() {
|
|
17
|
+
const dir = path_1.default.resolve(__dirname, "../extension");
|
|
18
|
+
const manifest = path_1.default.join(dir, "manifest.json");
|
|
19
|
+
if (!fs_1.default.existsSync(dir) || !fs_1.default.existsSync(manifest)) {
|
|
20
|
+
throw new Error(`Bundled extension not found at ${dir}`);
|
|
21
|
+
}
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
function resolveInstalledExtensionDir(dataDir) {
|
|
25
|
+
const dir = dataDir ?? (0, config_1.resolveConfig)().dataDir;
|
|
26
|
+
return path_1.default.join(dir, exports.EXTENSION_DIR_NAME);
|
|
27
|
+
}
|
|
28
|
+
function readExtensionVersion(extensionDir) {
|
|
29
|
+
try {
|
|
30
|
+
const raw = fs_1.default.readFileSync(path_1.default.join(extensionDir, "manifest.json"), "utf-8");
|
|
31
|
+
const manifest = JSON.parse(raw);
|
|
32
|
+
return typeof manifest.version === "string" ? manifest.version : null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function syncExtension(dataDir) {
|
|
39
|
+
const bundledDir = resolveBundledExtensionDir();
|
|
40
|
+
const installedDir = resolveInstalledExtensionDir(dataDir);
|
|
41
|
+
const bundledVersion = readExtensionVersion(bundledDir);
|
|
42
|
+
const installedVersion = readExtensionVersion(installedDir);
|
|
43
|
+
const needsCopy = !fs_1.default.existsSync(installedDir) || bundledVersion !== installedVersion;
|
|
44
|
+
if (needsCopy) {
|
|
45
|
+
fs_1.default.mkdirSync(installedDir, { recursive: true });
|
|
46
|
+
fs_1.default.cpSync(bundledDir, installedDir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
synced: needsCopy,
|
|
50
|
+
bundledVersion,
|
|
51
|
+
installedVersion,
|
|
52
|
+
extensionDir: installedDir,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function checkExtensionSync(dataDir) {
|
|
56
|
+
const bundledDir = resolveBundledExtensionDir();
|
|
57
|
+
const installedDir = resolveInstalledExtensionDir(dataDir);
|
|
58
|
+
const bundledVersion = readExtensionVersion(bundledDir);
|
|
59
|
+
const installedVersion = readExtensionVersion(installedDir);
|
|
60
|
+
const exists = fs_1.default.existsSync(installedDir) && installedVersion !== null;
|
|
61
|
+
const needsSync = !exists || bundledVersion !== installedVersion;
|
|
62
|
+
const needsReload = exists && bundledVersion !== installedVersion;
|
|
63
|
+
return {
|
|
64
|
+
needsSync,
|
|
65
|
+
needsReload,
|
|
66
|
+
bundledVersion,
|
|
67
|
+
installedVersion,
|
|
68
|
+
extensionDir: installedDir,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PROFILES_FILE = exports.PROFILE_NAME_PATTERN = void 0;
|
|
7
|
+
exports.validateProfileName = validateProfileName;
|
|
8
|
+
exports.loadProfiles = loadProfiles;
|
|
9
|
+
exports.saveProfiles = saveProfiles;
|
|
10
|
+
exports.addProfile = addProfile;
|
|
11
|
+
exports.removeProfile = removeProfile;
|
|
12
|
+
exports.getActiveProfile = getActiveProfile;
|
|
13
|
+
exports.listProfiles = listProfiles;
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const config_1 = require("./config");
|
|
17
|
+
exports.PROFILE_NAME_PATTERN = /^[a-z0-9-]+$/;
|
|
18
|
+
exports.PROFILES_FILE = "profiles.json";
|
|
19
|
+
function validateProfileName(name) {
|
|
20
|
+
if (!exports.PROFILE_NAME_PATTERN.test(name)) {
|
|
21
|
+
throw new Error(`Invalid profile name "${name}": only lowercase letters, digits, and hyphens are allowed`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function loadProfiles(configDir) {
|
|
25
|
+
const dir = configDir ?? (0, config_1.resolveConfig)().configDir;
|
|
26
|
+
try {
|
|
27
|
+
const raw = fs_1.default.readFileSync(path_1.default.join(dir, exports.PROFILES_FILE), "utf-8");
|
|
28
|
+
return JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return { default: null, profiles: {} };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function saveProfiles(registry, configDir) {
|
|
35
|
+
const dir = configDir ?? (0, config_1.resolveConfig)().configDir;
|
|
36
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
37
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, exports.PROFILES_FILE), JSON.stringify(registry, null, 2) + "\n");
|
|
38
|
+
}
|
|
39
|
+
function addProfile(name, entry, configDir) {
|
|
40
|
+
validateProfileName(name);
|
|
41
|
+
const registry = loadProfiles(configDir);
|
|
42
|
+
const isFirst = Object.keys(registry.profiles).length === 0;
|
|
43
|
+
registry.profiles[name] = entry;
|
|
44
|
+
if (isFirst) {
|
|
45
|
+
registry.default = name;
|
|
46
|
+
}
|
|
47
|
+
saveProfiles(registry, configDir);
|
|
48
|
+
return registry;
|
|
49
|
+
}
|
|
50
|
+
function removeProfile(name, configDir) {
|
|
51
|
+
const registry = loadProfiles(configDir);
|
|
52
|
+
if (!(name in registry.profiles)) {
|
|
53
|
+
throw new Error(`Profile "${name}" does not exist`);
|
|
54
|
+
}
|
|
55
|
+
delete registry.profiles[name];
|
|
56
|
+
if (registry.default === name) {
|
|
57
|
+
const remaining = Object.keys(registry.profiles);
|
|
58
|
+
registry.default = remaining.length > 0 ? remaining[0] : null;
|
|
59
|
+
}
|
|
60
|
+
saveProfiles(registry, configDir);
|
|
61
|
+
return registry;
|
|
62
|
+
}
|
|
63
|
+
function getActiveProfile(overrideName, configDir) {
|
|
64
|
+
const registry = loadProfiles(configDir);
|
|
65
|
+
const name = overrideName ?? process.env.TABCTL_PROFILE ?? registry.default;
|
|
66
|
+
if (!name || !(name in registry.profiles)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return { name, profile: registry.profiles[name] };
|
|
70
|
+
}
|
|
71
|
+
function listProfiles(configDir) {
|
|
72
|
+
const registry = loadProfiles(configDir);
|
|
73
|
+
return Object.entries(registry.profiles).map(([name, profile]) => ({
|
|
74
|
+
name,
|
|
75
|
+
profile,
|
|
76
|
+
isDefault: name === registry.default,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DIRTY = exports.GIT_SHA = exports.VERSION = exports.BASE_VERSION = void 0;
|
|
4
|
+
exports.BASE_VERSION = "0.1.0";
|
|
5
|
+
exports.VERSION = "0.1.0-dev.0022fa28.dirty";
|
|
6
|
+
exports.GIT_SHA = "0022fa28";
|
|
7
|
+
exports.DIRTY = true;
|