@imdeadpool/guardex 7.0.41 → 7.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 +94 -13
- package/package.json +3 -1
- package/skills/gitguardex/SKILL.md +13 -0
- package/skills/guardex-merge-skills-to-dev/SKILL.md +59 -0
- package/skills/gx-act/SKILL.md +82 -0
- package/src/agents/cleanup-sessions.js +126 -0
- package/src/agents/finish.js +172 -0
- package/src/agents/inspect.js +202 -0
- package/src/agents/launch.js +249 -0
- package/src/agents/registry.js +133 -0
- package/src/agents/selection-panel.js +571 -0
- package/src/agents/sessions.js +151 -0
- package/src/agents/start.js +591 -0
- package/src/agents/status.js +146 -0
- package/src/agents/terminal.js +152 -0
- package/src/budget/index.js +344 -0
- package/src/ci-init/index.js +265 -0
- package/src/cli/args.js +357 -3
- package/src/cli/commands/agents.js +364 -0
- package/src/cli/commands/bootstrap.js +92 -0
- package/src/cli/commands/branch.js +127 -0
- package/src/cli/commands/claude.js +674 -0
- package/src/cli/commands/doctor.js +268 -0
- package/src/cli/commands/finish.js +26 -0
- package/src/cli/commands/mcp.js +122 -0
- package/src/cli/commands/misc.js +304 -0
- package/src/cli/commands/pr.js +439 -0
- package/src/cli/commands/prompt.js +92 -0
- package/src/cli/commands/release.js +305 -0
- package/src/cli/commands/report.js +244 -0
- package/src/cli/commands/review.js +32 -0
- package/src/cli/commands/setup.js +242 -0
- package/src/cli/commands/status.js +338 -0
- package/src/cli/commands/watch.js +234 -0
- package/src/cli/main.js +85 -3613
- package/src/cli/shared/repo-env.js +161 -0
- package/src/cli/shared/sandbox.js +417 -0
- package/src/cli/shared/scaffolding.js +535 -0
- package/src/cli/shared/toolchain-shims.js +420 -0
- package/src/cockpit/action-runner.js +3 -0
- package/src/cockpit/actions.js +80 -0
- package/src/cockpit/control.js +1121 -0
- package/src/cockpit/index.js +426 -0
- package/src/cockpit/kitty-layout.js +549 -0
- package/src/cockpit/kitty-tree.js +144 -0
- package/src/cockpit/logs-reader.js +182 -0
- package/src/cockpit/menu.js +204 -0
- package/src/cockpit/pane-actions.js +597 -0
- package/src/cockpit/pane-menu.js +387 -0
- package/src/cockpit/projects-finder.js +178 -0
- package/src/cockpit/render.js +215 -0
- package/src/cockpit/settings-render.js +128 -0
- package/src/cockpit/settings.js +124 -0
- package/src/cockpit/shortcuts.js +24 -0
- package/src/cockpit/sidebar.js +311 -0
- package/src/cockpit/state.js +72 -0
- package/src/cockpit/theme.js +128 -0
- package/src/cockpit/welcome.js +266 -0
- package/src/context.js +304 -43
- package/src/core/runtime.js +6 -1
- package/src/doctor/index.js +45 -15
- package/src/finish/index.js +186 -7
- package/src/finish/preflight.js +177 -0
- package/src/finish/review-gate.js +182 -0
- package/src/git/index.js +511 -4
- package/src/hooks/index.js +0 -64
- package/src/kitty/command.js +101 -0
- package/src/kitty/runtime.js +250 -0
- package/src/mcp/collect.js +370 -0
- package/src/mcp/server.js +157 -0
- package/src/output/index.js +68 -2
- package/src/pr-review.js +264 -0
- package/src/pr.js +381 -0
- package/src/sandbox/index.js +13 -2
- package/src/scaffold/agent-worktree-prep.js +213 -0
- package/src/scaffold/index.js +127 -10
- package/src/speckit/index.js +226 -0
- package/src/submodule/index.js +288 -0
- package/src/terminal/index.js +45 -0
- package/src/terminal/kitty.js +622 -0
- package/src/terminal/tmux.js +125 -0
- package/src/tmux/command.js +27 -0
- package/src/tmux/session.js +89 -0
- package/src/toolchain/index.js +20 -0
- package/templates/AGENTS.monorepo-apps.md +26 -0
- package/templates/AGENTS.multiagent-safety.md +63 -323
- package/templates/AGENTS.multiagent-safety.min.md +11 -0
- package/templates/codex/skills/gitguardex/SKILL.md +2 -0
- package/templates/codex/skills/gx-act/SKILL.md +82 -0
- package/templates/githooks/pre-commit +44 -20
- package/templates/github/workflows/README.md +87 -0
- package/templates/github/workflows/ci-full.yml +55 -0
- package/templates/github/workflows/ci.yml +56 -0
- package/templates/github/workflows/cr.yml +20 -1
- package/templates/scripts/agent-branch-finish.sh +519 -23
- package/templates/scripts/agent-branch-merge.sh +4 -1
- package/templates/scripts/agent-branch-start.sh +176 -24
- package/templates/scripts/agent-preflight.sh +115 -0
- package/templates/scripts/agent-worktree-prune.sh +96 -5
- package/templates/scripts/codex-agent.sh +41 -97
- package/templates/scripts/openspec/init-plan-workspace.sh +43 -0
- package/templates/scripts/review-bot-watch.sh +31 -2
- package/templates/scripts/agent-session-state.js +0 -171
- package/templates/scripts/install-vscode-active-agents-extension.js +0 -135
- package/templates/vscode/guardex-active-agents/README.md +0 -34
- package/templates/vscode/guardex-active-agents/extension.js +0 -3782
- package/templates/vscode/guardex-active-agents/fileicons/gitguardex-fileicons.json +0 -54
- package/templates/vscode/guardex-active-agents/fileicons/icons/agent.svg +0 -5
- package/templates/vscode/guardex-active-agents/fileicons/icons/branch.svg +0 -7
- package/templates/vscode/guardex-active-agents/fileicons/icons/config.svg +0 -4
- package/templates/vscode/guardex-active-agents/fileicons/icons/hook.svg +0 -4
- package/templates/vscode/guardex-active-agents/fileicons/icons/openspec.svg +0 -5
- package/templates/vscode/guardex-active-agents/fileicons/icons/plan.svg +0 -4
- package/templates/vscode/guardex-active-agents/fileicons/icons/spec.svg +0 -5
- package/templates/vscode/guardex-active-agents/icon.png +0 -0
- package/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg +0 -14
- package/templates/vscode/guardex-active-agents/package.json +0 -169
- package/templates/vscode/guardex-active-agents/session-schema.js +0 -1348
package/src/hooks/index.js
CHANGED
|
@@ -1,39 +1,5 @@
|
|
|
1
1
|
const path = require('node:path');
|
|
2
2
|
|
|
3
|
-
function requireFlagValue(rawArgs, index, flagName) {
|
|
4
|
-
const value = rawArgs[index + 1];
|
|
5
|
-
if (!value || value.startsWith('--')) {
|
|
6
|
-
throw new Error(`${flagName} requires a value`);
|
|
7
|
-
}
|
|
8
|
-
return value;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function parseHeartbeatArgs(rawArgs) {
|
|
12
|
-
let branch = '';
|
|
13
|
-
let state = '';
|
|
14
|
-
|
|
15
|
-
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
16
|
-
const arg = rawArgs[index];
|
|
17
|
-
if (arg === '--branch') {
|
|
18
|
-
branch = requireFlagValue(rawArgs, index, '--branch');
|
|
19
|
-
index += 1;
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if (arg === '--state') {
|
|
23
|
-
state = requireFlagValue(rawArgs, index, '--state');
|
|
24
|
-
index += 1;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
throw new Error(`Unknown heartbeat option: ${arg}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!branch) {
|
|
31
|
-
throw new Error('heartbeat requires --branch <agent/...>');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return { branch, state };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
3
|
function hook(rawArgs, deps) {
|
|
38
4
|
const {
|
|
39
5
|
extractTargetedArgs,
|
|
@@ -89,36 +55,6 @@ function internal(rawArgs, deps) {
|
|
|
89
55
|
} = deps;
|
|
90
56
|
|
|
91
57
|
const [subcommand, assetKey, ...rest] = rawArgs;
|
|
92
|
-
if (subcommand === 'heartbeat') {
|
|
93
|
-
const { target, passthrough } = extractTargetedArgs([assetKey, ...rest].filter(Boolean));
|
|
94
|
-
const repoRoot = resolveRepoRoot(target);
|
|
95
|
-
const options = parseHeartbeatArgs(passthrough);
|
|
96
|
-
const heartbeatArgs = ['heartbeat', '--repo', repoRoot, '--branch', options.branch];
|
|
97
|
-
if (options.state) {
|
|
98
|
-
heartbeatArgs.push('--state', options.state);
|
|
99
|
-
}
|
|
100
|
-
const result = runPackageAsset('sessionState', heartbeatArgs, { cwd: repoRoot });
|
|
101
|
-
if (result.stdout) process.stdout.write(result.stdout);
|
|
102
|
-
if (result.stderr) process.stderr.write(result.stderr);
|
|
103
|
-
process.exitCode = result.status;
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (subcommand === 'stop-session') {
|
|
107
|
-
const { target, passthrough } = extractTargetedArgs([assetKey, ...rest].filter(Boolean));
|
|
108
|
-
const repoRoot = resolveRepoRoot(target);
|
|
109
|
-
const options = parseHeartbeatArgs(passthrough);
|
|
110
|
-
const result = runPackageAsset('sessionState', [
|
|
111
|
-
'terminate',
|
|
112
|
-
'--repo',
|
|
113
|
-
repoRoot,
|
|
114
|
-
'--branch',
|
|
115
|
-
options.branch,
|
|
116
|
-
], { cwd: repoRoot });
|
|
117
|
-
if (result.stdout) process.stdout.write(result.stdout);
|
|
118
|
-
if (result.stderr) process.stderr.write(result.stderr);
|
|
119
|
-
process.exitCode = result.status;
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
58
|
if (subcommand !== 'run-shell') {
|
|
123
59
|
throw new Error(`Unknown internal command: ${subcommand || '(missing)'}`);
|
|
124
60
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const cp = require('node:child_process');
|
|
4
|
+
|
|
5
|
+
const DEFAULT_KITTY_BIN = 'kitty';
|
|
6
|
+
|
|
7
|
+
function text(value, fallback = '') {
|
|
8
|
+
if (typeof value === 'string') return value.trim() || fallback;
|
|
9
|
+
if (value === null || value === undefined) return fallback;
|
|
10
|
+
return String(value).trim() || fallback;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function resolveKittyBin(options = {}) {
|
|
14
|
+
return text(options.kittyBin || options.bin || process.env.GUARDEX_KITTY_BIN, DEFAULT_KITTY_BIN);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function assertArgs(args) {
|
|
18
|
+
if (!Array.isArray(args)) {
|
|
19
|
+
throw new TypeError('kitty args must be an array');
|
|
20
|
+
}
|
|
21
|
+
for (const arg of args) {
|
|
22
|
+
if (typeof arg !== 'string') {
|
|
23
|
+
throw new TypeError('kitty args must contain only strings');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function commandShape(cmd, args, options = {}) {
|
|
29
|
+
const command = {
|
|
30
|
+
cmd,
|
|
31
|
+
args: [...args],
|
|
32
|
+
};
|
|
33
|
+
if (Object.prototype.hasOwnProperty.call(options, 'input')) {
|
|
34
|
+
command.input = options.input === undefined || options.input === null ? '' : String(options.input);
|
|
35
|
+
}
|
|
36
|
+
return command;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function runnerOptions(options = {}) {
|
|
40
|
+
return {
|
|
41
|
+
cwd: options.cwd,
|
|
42
|
+
env: options.env ? { ...process.env, ...options.env } : process.env,
|
|
43
|
+
encoding: 'utf8',
|
|
44
|
+
input: options.input,
|
|
45
|
+
stdio: options.stdio || 'pipe',
|
|
46
|
+
timeout: options.timeout,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function defaultRunner(cmd, args, options = {}) {
|
|
51
|
+
return cp.spawnSync(cmd, args, runnerOptions(options));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function runnerFor(options = {}) {
|
|
55
|
+
if (typeof options.runner === 'function') return options.runner;
|
|
56
|
+
if (options.runtime && typeof options.runtime.run === 'function') return options.runtime.run;
|
|
57
|
+
return defaultRunner;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function dryRunOptions(options = {}) {
|
|
61
|
+
const result = {};
|
|
62
|
+
for (const key of ['cwd', 'env', 'input', 'stdio', 'timeout']) {
|
|
63
|
+
if (Object.prototype.hasOwnProperty.call(options, key) && options[key] !== undefined) {
|
|
64
|
+
result[key] = options[key];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function runKitty(args, options = {}) {
|
|
71
|
+
assertArgs(args);
|
|
72
|
+
const cmd = resolveKittyBin(options);
|
|
73
|
+
const command = commandShape(cmd, args, options);
|
|
74
|
+
|
|
75
|
+
if (options.dryRun) {
|
|
76
|
+
const result = {
|
|
77
|
+
dryRun: true,
|
|
78
|
+
commands: [command],
|
|
79
|
+
};
|
|
80
|
+
const optionsForReport = dryRunOptions(options);
|
|
81
|
+
if (optionsForReport) result.options = optionsForReport;
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return runnerFor(options)(cmd, [...args], runnerOptions(options));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function isKittyAvailable(options = {}) {
|
|
89
|
+
const result = runKitty(['@', 'ls'], {
|
|
90
|
+
...options,
|
|
91
|
+
stdio: 'pipe',
|
|
92
|
+
});
|
|
93
|
+
if (result && result.dryRun) return result;
|
|
94
|
+
return Boolean(result && result.status === 0 && !result.error);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
isKittyAvailable,
|
|
99
|
+
runKitty,
|
|
100
|
+
resolveKittyBin,
|
|
101
|
+
};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
isKittyAvailable,
|
|
5
|
+
resolveKittyBin,
|
|
6
|
+
runKitty,
|
|
7
|
+
} = require('./command');
|
|
8
|
+
|
|
9
|
+
function text(value, fallback = '') {
|
|
10
|
+
if (typeof value === 'string') return value.trim() || fallback;
|
|
11
|
+
if (value === null || value === undefined) return fallback;
|
|
12
|
+
return String(value).trim() || fallback;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function requireText(value, name) {
|
|
16
|
+
const normalized = text(value);
|
|
17
|
+
if (!normalized) {
|
|
18
|
+
throw new TypeError(`${name} must be a non-empty string`);
|
|
19
|
+
}
|
|
20
|
+
return normalized;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function appendOption(args, flag, value) {
|
|
24
|
+
const normalized = text(value);
|
|
25
|
+
if (normalized) args.push(flag, normalized);
|
|
26
|
+
return args;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizeEnvEntries(env = {}) {
|
|
30
|
+
if (!env) return [];
|
|
31
|
+
if (Array.isArray(env)) {
|
|
32
|
+
return env.map((entry) => {
|
|
33
|
+
if (Array.isArray(entry)) {
|
|
34
|
+
const key = requireText(entry[0], 'kitty env key');
|
|
35
|
+
const value = entry.length > 1 && entry[1] !== undefined && entry[1] !== null ? String(entry[1]) : '';
|
|
36
|
+
return `${key}=${value}`;
|
|
37
|
+
}
|
|
38
|
+
return requireText(entry, 'kitty env');
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (typeof env !== 'object') {
|
|
42
|
+
throw new TypeError('kitty env must be an object, array, or undefined');
|
|
43
|
+
}
|
|
44
|
+
return Object.keys(env)
|
|
45
|
+
.sort()
|
|
46
|
+
.map((key) => `${requireText(key, 'kitty env key')}=${env[key] === undefined || env[key] === null ? '' : String(env[key])}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function appendEnv(args, env) {
|
|
50
|
+
for (const entry of normalizeEnvEntries(env)) {
|
|
51
|
+
args.push('--env', entry);
|
|
52
|
+
}
|
|
53
|
+
return args;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function normalizeCommandArgv(options = {}) {
|
|
57
|
+
if (options.argv === undefined && options.commandArgv === undefined && Object.prototype.hasOwnProperty.call(options, 'command') && !Array.isArray(options.command)) {
|
|
58
|
+
throw new TypeError('kitty command argv must be an array');
|
|
59
|
+
}
|
|
60
|
+
const commandArgv = options.argv || options.commandArgv || (Array.isArray(options.command) ? options.command : undefined);
|
|
61
|
+
if (commandArgv === undefined || commandArgv === null) return [];
|
|
62
|
+
if (!Array.isArray(commandArgv)) {
|
|
63
|
+
throw new TypeError('kitty command argv must be an array');
|
|
64
|
+
}
|
|
65
|
+
return commandArgv.map((arg) => {
|
|
66
|
+
if (arg === undefined || arg === null) {
|
|
67
|
+
throw new TypeError('kitty command argv values must be strings');
|
|
68
|
+
}
|
|
69
|
+
return String(arg);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function appendCommandArgv(args, options = {}) {
|
|
74
|
+
const commandArgv = normalizeCommandArgv(options);
|
|
75
|
+
if (commandArgv.length > 0) args.push('--', ...commandArgv);
|
|
76
|
+
return args;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function commandShape(args, options = {}) {
|
|
80
|
+
const command = {
|
|
81
|
+
cmd: resolveKittyBin(options),
|
|
82
|
+
args,
|
|
83
|
+
};
|
|
84
|
+
if (Object.prototype.hasOwnProperty.call(options, 'input')) {
|
|
85
|
+
command.input = options.input === undefined || options.input === null ? '' : String(options.input);
|
|
86
|
+
}
|
|
87
|
+
return command;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function buildKittyLaunchCommand(options = {}) {
|
|
91
|
+
const args = ['@', 'launch'];
|
|
92
|
+
appendOption(args, '--type', text(options.type, 'window'));
|
|
93
|
+
appendOption(args, '--location', options.location);
|
|
94
|
+
appendOption(args, '--cwd', options.cwd);
|
|
95
|
+
appendOption(args, '--title', options.title);
|
|
96
|
+
appendEnv(args, options.env);
|
|
97
|
+
appendCommandArgv(args, options);
|
|
98
|
+
return commandShape(args, options);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function runCommand(command, action, options = {}) {
|
|
102
|
+
const runOptions = {
|
|
103
|
+
...options,
|
|
104
|
+
kittyBin: command.cmd,
|
|
105
|
+
action,
|
|
106
|
+
};
|
|
107
|
+
if (Object.prototype.hasOwnProperty.call(command, 'input')) {
|
|
108
|
+
runOptions.input = command.input;
|
|
109
|
+
} else if (Object.prototype.hasOwnProperty.call(options, 'input')) {
|
|
110
|
+
runOptions.input = options.input;
|
|
111
|
+
}
|
|
112
|
+
return runKitty(command.args, runOptions);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function cloneCommand(command) {
|
|
116
|
+
if (!command || typeof command !== 'object' || !Array.isArray(command.args)) {
|
|
117
|
+
throw new TypeError('kitty cockpit command must include args');
|
|
118
|
+
}
|
|
119
|
+
const clone = {
|
|
120
|
+
cmd: requireText(command.cmd, 'kitty cockpit command cmd'),
|
|
121
|
+
args: command.args.map((arg) => {
|
|
122
|
+
if (arg === undefined || arg === null) {
|
|
123
|
+
throw new TypeError('kitty cockpit command args must be strings');
|
|
124
|
+
}
|
|
125
|
+
return String(arg);
|
|
126
|
+
}),
|
|
127
|
+
};
|
|
128
|
+
if (Object.prototype.hasOwnProperty.call(command, 'input')) {
|
|
129
|
+
clone.input = command.input === undefined || command.input === null ? '' : String(command.input);
|
|
130
|
+
}
|
|
131
|
+
return clone;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function cockpitCommands(plan = {}) {
|
|
135
|
+
if (!plan || typeof plan !== 'object') {
|
|
136
|
+
throw new TypeError('kitty cockpit plan must be an object');
|
|
137
|
+
}
|
|
138
|
+
const commands = Array.isArray(plan.commands)
|
|
139
|
+
? plan.commands
|
|
140
|
+
: Array.isArray(plan.steps)
|
|
141
|
+
? plan.steps.map((step) => step && step.command).filter(Boolean)
|
|
142
|
+
: [];
|
|
143
|
+
return commands.map(cloneCommand);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function assertCommandResult(command, result) {
|
|
147
|
+
if (result && result.error) throw result.error;
|
|
148
|
+
if (!result || result.status === 0) return result;
|
|
149
|
+
const detail = String(result.stderr || result.stdout || '').trim();
|
|
150
|
+
throw new Error(`kitty cockpit command failed: ${command.cmd} ${command.args.join(' ')}${detail ? `: ${detail}` : ''}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function openKittyCockpit(options = {}) {
|
|
154
|
+
const plan = options.plan && typeof options.plan === 'object' ? options.plan : options;
|
|
155
|
+
const commands = cockpitCommands(plan);
|
|
156
|
+
const dryRun = Boolean(options.dryRun || plan.dryRun);
|
|
157
|
+
|
|
158
|
+
if (dryRun) {
|
|
159
|
+
return {
|
|
160
|
+
dryRun: true,
|
|
161
|
+
action: 'open-kitty-cockpit',
|
|
162
|
+
commands,
|
|
163
|
+
plan,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const results = commands.map((command) => (
|
|
168
|
+
assertCommandResult(command, runCommand(command, 'open-kitty-cockpit', options))
|
|
169
|
+
));
|
|
170
|
+
return {
|
|
171
|
+
action: 'open-kitty-cockpit',
|
|
172
|
+
commands,
|
|
173
|
+
results,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function launchKittyWindow(options = {}) {
|
|
178
|
+
return runCommand(
|
|
179
|
+
buildKittyLaunchCommand({
|
|
180
|
+
...options,
|
|
181
|
+
type: text(options.type, 'window'),
|
|
182
|
+
}),
|
|
183
|
+
'launch-window',
|
|
184
|
+
options,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function launchKittyTab(options = {}) {
|
|
189
|
+
return runCommand(
|
|
190
|
+
buildKittyLaunchCommand({
|
|
191
|
+
...options,
|
|
192
|
+
type: 'tab',
|
|
193
|
+
}),
|
|
194
|
+
'launch-tab',
|
|
195
|
+
options,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function launchKittyPane(options = {}) {
|
|
200
|
+
return runCommand(
|
|
201
|
+
buildKittyLaunchCommand({
|
|
202
|
+
...options,
|
|
203
|
+
type: 'window',
|
|
204
|
+
location: text(options.location, 'vsplit'),
|
|
205
|
+
}),
|
|
206
|
+
'launch-pane',
|
|
207
|
+
options,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function targetMatch(target) {
|
|
212
|
+
if (target && typeof target === 'object') {
|
|
213
|
+
const explicit = text(target.match || target.kittyMatch);
|
|
214
|
+
if (explicit) return explicit;
|
|
215
|
+
|
|
216
|
+
const id = text(target.id || target.windowId || target.kittyWindowId || target.paneId || target.target);
|
|
217
|
+
if (id) return `id:${id}`;
|
|
218
|
+
|
|
219
|
+
const title = text(target.title || target.windowTitle || target.kittyTitle);
|
|
220
|
+
if (title) return `title:${title}`;
|
|
221
|
+
} else {
|
|
222
|
+
const id = text(target);
|
|
223
|
+
if (id) return `id:${id}`;
|
|
224
|
+
}
|
|
225
|
+
throw new TypeError('kitty target must include id, title, or match');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function sendTextToKitty(target, value, options = {}) {
|
|
229
|
+
return runKitty(['@', 'send-text', '--match', targetMatch(target), '--stdin'], {
|
|
230
|
+
...options,
|
|
231
|
+
input: value === undefined || value === null ? '' : String(value),
|
|
232
|
+
stdio: options.stdio || 'pipe',
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function setKittyWindowTitle(target, title, options = {}) {
|
|
237
|
+
return runKitty(['@', 'set-window-title', '--match', targetMatch(target), requireText(title, 'kitty window title')], options);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
module.exports = {
|
|
241
|
+
isKittyAvailable,
|
|
242
|
+
runKitty,
|
|
243
|
+
buildKittyLaunchCommand,
|
|
244
|
+
launchKittyWindow,
|
|
245
|
+
launchKittyTab,
|
|
246
|
+
launchKittyPane,
|
|
247
|
+
openKittyCockpit,
|
|
248
|
+
sendTextToKitty,
|
|
249
|
+
setKittyWindowTitle,
|
|
250
|
+
};
|