octomux 1.0.13 → 1.0.23
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/LICENSE +21 -0
- package/bin/octomux.js +99 -32
- package/cli/dist/client.js +24 -0
- package/cli/dist/commands/create-skill.js +19 -0
- package/cli/dist/commands/create-task.js +2 -0
- package/cli/dist/commands/default-branch.js +17 -0
- package/cli/dist/commands/delete-skill.js +16 -0
- package/cli/dist/commands/get-skill.js +18 -0
- package/cli/dist/commands/list-skills.js +25 -0
- package/cli/dist/commands/recent-repos.js +25 -0
- package/cli/dist/commands/stop-agent.js +17 -0
- package/cli/dist/index.js +14 -0
- package/dist/assets/{OrchestratorPage-D8ClBh3e.js → OrchestratorPage-CTm31XJk.js} +1 -1
- package/dist/assets/SettingsPage-oiudpquX.js +5 -0
- package/dist/assets/SkillEditor-CeW8ug-Z.js +1 -0
- package/dist/assets/{TaskDetail-Dj6uvT-Z.js → TaskDetail-B4fR-Glk.js} +1 -1
- package/dist/assets/index-CO9v-WdW.css +1 -0
- package/dist/assets/index-DrfVrJzN.js +2 -0
- package/dist/index.html +2 -2
- package/dist-server/index.js +22 -22
- package/dist-server/startup.js +1 -0
- package/package.json +6 -5
- package/scripts/verify-build.js +33 -0
- package/skills/{octomux-create-pr → create-pr}/SKILL.md +8 -6
- package/skills/{octomux-create-task → create-task}/SKILL.md +30 -9
- package/dist/assets/SettingsPage-TBFhdDov.js +0 -1
- package/dist/assets/index-Bi3y4EjD.css +0 -1
- package/dist/assets/index-CcrRBTAX.js +0 -2
- package/dist-server/orchestrator-prompt.md +0 -132
- package/scripts/setup-nvim.sh +0 -53
- package/skills/octomux-create-commit/SKILL.md +0 -78
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shrey Paharia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/bin/octomux.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execFileSync, exec as execCb } from 'child_process';
|
|
4
|
-
import { readFileSync, existsSync, mkdirSync, readdirSync, cpSync } from 'fs';
|
|
4
|
+
import { readFileSync, existsSync, mkdirSync, readdirSync, cpSync, rmSync } from 'fs';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import os from 'os';
|
|
@@ -43,48 +43,41 @@ async function runStart(startArgs) {
|
|
|
43
43
|
// Welcome banner
|
|
44
44
|
console.log(`\n\uD83D\uDC19 octomux v${version}\n`);
|
|
45
45
|
|
|
46
|
-
// Install bundled skills
|
|
46
|
+
// Install bundled skills and configs
|
|
47
47
|
installSkills();
|
|
48
|
+
installLazygitConfig();
|
|
49
|
+
|
|
50
|
+
// Ensure cli/ dependencies are installed
|
|
51
|
+
ensureCliDeps();
|
|
52
|
+
|
|
53
|
+
// Fix node-pty spawn-helper permissions (may have been missed if postinstall didn't run)
|
|
54
|
+
fixNodePtyPermissions();
|
|
55
|
+
|
|
56
|
+
// Preflight: ensure all required binaries are installed
|
|
57
|
+
const { ensureBinary, checkNeovimVersion, syncLazyVimPlugins } =
|
|
58
|
+
await import('../dist-server/startup.js');
|
|
48
59
|
|
|
49
|
-
// Preflight checks
|
|
50
60
|
const required = [
|
|
51
|
-
{
|
|
52
|
-
|
|
53
|
-
args: ['-V'],
|
|
54
|
-
name: 'tmux',
|
|
55
|
-
hint: 'Install with: brew install tmux',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
cmd: 'git',
|
|
59
|
-
args: ['--version'],
|
|
60
|
-
name: 'git',
|
|
61
|
-
hint: 'Install with: brew install git',
|
|
62
|
-
},
|
|
61
|
+
{ cmd: 'tmux', checkArgs: ['-V'], brewPkg: 'tmux' },
|
|
62
|
+
{ cmd: 'git', checkArgs: ['--version'], brewPkg: 'git' },
|
|
63
63
|
{
|
|
64
64
|
cmd: 'claude',
|
|
65
|
-
|
|
65
|
+
checkArgs: ['--version'],
|
|
66
66
|
name: 'Claude Code CLI',
|
|
67
|
-
|
|
67
|
+
installUrl: 'https://docs.anthropic.com/en/docs/claude-code',
|
|
68
68
|
},
|
|
69
|
+
{ cmd: 'nvim', checkArgs: ['--version'], brewPkg: 'neovim', name: 'neovim' },
|
|
70
|
+
{ cmd: 'lazygit', checkArgs: ['--version'], brewPkg: 'lazygit' },
|
|
69
71
|
];
|
|
70
72
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
execFileSync(cmd, checkArgs, { stdio: 'ignore' });
|
|
75
|
-
} catch {
|
|
76
|
-
missing.push({ name, hint });
|
|
77
|
-
}
|
|
73
|
+
for (const dep of required) {
|
|
74
|
+
ensureBinary(dep);
|
|
78
75
|
}
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
console.error(` ${hint}\n`);
|
|
85
|
-
}
|
|
86
|
-
process.exit(1);
|
|
87
|
-
}
|
|
77
|
+
// Neovim-specific: version check + LazyVim plugin sync
|
|
78
|
+
const repoRoot = path.resolve(__dirname, '..');
|
|
79
|
+
checkNeovimVersion();
|
|
80
|
+
syncLazyVimPlugins(repoRoot);
|
|
88
81
|
|
|
89
82
|
// Start server
|
|
90
83
|
process.env.NODE_ENV = 'production';
|
|
@@ -110,14 +103,88 @@ async function runStart(startArgs) {
|
|
|
110
103
|
}
|
|
111
104
|
}
|
|
112
105
|
|
|
106
|
+
// ─── cli dependency installer ────────────────────────────────────────────────
|
|
107
|
+
|
|
108
|
+
function ensureCliDeps() {
|
|
109
|
+
const cliDir = path.join(__dirname, '..', 'cli');
|
|
110
|
+
const cliPkg = path.join(cliDir, 'package.json');
|
|
111
|
+
if (!existsSync(cliPkg)) return;
|
|
112
|
+
|
|
113
|
+
// Check if cli has dependencies that need installing
|
|
114
|
+
const pkg = JSON.parse(readFileSync(cliPkg, 'utf8'));
|
|
115
|
+
const hasDeps =
|
|
116
|
+
(pkg.dependencies && Object.keys(pkg.dependencies).length > 0) ||
|
|
117
|
+
(pkg.devDependencies && Object.keys(pkg.devDependencies).length > 0);
|
|
118
|
+
if (!hasDeps) return;
|
|
119
|
+
|
|
120
|
+
const cliModules = path.join(cliDir, 'node_modules');
|
|
121
|
+
if (existsSync(cliModules)) return;
|
|
122
|
+
|
|
123
|
+
console.log('Installing cli/ dependencies...');
|
|
124
|
+
try {
|
|
125
|
+
execFileSync('npm', ['install', '--ignore-scripts'], { cwd: cliDir, stdio: 'ignore' });
|
|
126
|
+
} catch {
|
|
127
|
+
console.warn('⚠ Could not install cli/ dependencies. Run manually: cd cli && npm install');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ─── node-pty permissions fix ────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
function fixNodePtyPermissions() {
|
|
134
|
+
try {
|
|
135
|
+
const nodePtyDir = path.join(__dirname, '..', 'node_modules', 'node-pty', 'prebuilds');
|
|
136
|
+
if (!existsSync(nodePtyDir)) return;
|
|
137
|
+
const entries = readdirSync(nodePtyDir).filter((e) => e.startsWith('darwin-'));
|
|
138
|
+
for (const entry of entries) {
|
|
139
|
+
const helper = path.join(nodePtyDir, entry, 'spawn-helper');
|
|
140
|
+
if (existsSync(helper)) {
|
|
141
|
+
execFileSync('chmod', ['+x', helper], { stdio: 'ignore' });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
// Non-critical — node-pty may still work without this
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
113
149
|
// ─── skill installer ─────────────────────────────────────────────────────────
|
|
114
150
|
|
|
151
|
+
function installLazygitConfig() {
|
|
152
|
+
const source = path.join(__dirname, '..', '.config', 'lazygit', 'config.yml');
|
|
153
|
+
if (!existsSync(source)) return;
|
|
154
|
+
|
|
155
|
+
const configDir =
|
|
156
|
+
process.platform === 'darwin'
|
|
157
|
+
? path.join(os.homedir(), 'Library', 'Application Support', 'lazygit')
|
|
158
|
+
: path.join(os.homedir(), '.config', 'lazygit');
|
|
159
|
+
const target = path.join(configDir, 'config.yml');
|
|
160
|
+
|
|
161
|
+
if (existsSync(target)) return;
|
|
162
|
+
|
|
163
|
+
mkdirSync(configDir, { recursive: true });
|
|
164
|
+
cpSync(source, target);
|
|
165
|
+
console.log('Installed lazygit config');
|
|
166
|
+
}
|
|
167
|
+
|
|
115
168
|
function installSkills() {
|
|
116
169
|
const skillsSource = path.join(__dirname, '..', 'skills');
|
|
117
170
|
const skillsTarget = path.join(os.homedir(), '.claude', 'skills');
|
|
118
171
|
|
|
119
172
|
if (!existsSync(skillsSource)) return;
|
|
120
173
|
|
|
174
|
+
// Remove old-named skills that have been renamed
|
|
175
|
+
const deprecated = [
|
|
176
|
+
'octomux-create-pr',
|
|
177
|
+
'octomux-create-task',
|
|
178
|
+
'octomux-create-commit',
|
|
179
|
+
'octomux-executing-plans',
|
|
180
|
+
];
|
|
181
|
+
for (const name of deprecated) {
|
|
182
|
+
const old = path.join(skillsTarget, name);
|
|
183
|
+
if (existsSync(old)) {
|
|
184
|
+
rmSync(old, { recursive: true });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
121
188
|
let installed = false;
|
|
122
189
|
for (const skill of readdirSync(skillsSource)) {
|
|
123
190
|
const target = path.join(skillsTarget, skill);
|
package/cli/dist/client.js
CHANGED
|
@@ -49,8 +49,32 @@ export function createClient(serverUrl) {
|
|
|
49
49
|
body: JSON.stringify(data || {}),
|
|
50
50
|
});
|
|
51
51
|
},
|
|
52
|
+
stopAgent(taskId, agentId) {
|
|
53
|
+
return request(baseUrl, `/tasks/${encodeURIComponent(taskId)}/agents/${encodeURIComponent(agentId)}`, { method: 'DELETE' });
|
|
54
|
+
},
|
|
52
55
|
sendMessage(taskId, agentId, message) {
|
|
53
56
|
return request(baseUrl, `/tasks/${encodeURIComponent(taskId)}/agents/${encodeURIComponent(agentId)}/message`, { method: 'POST', body: JSON.stringify({ message }) });
|
|
54
57
|
},
|
|
58
|
+
listSkills() {
|
|
59
|
+
return request(baseUrl, '/skills');
|
|
60
|
+
},
|
|
61
|
+
getSkill(name) {
|
|
62
|
+
return request(baseUrl, `/skills/${encodeURIComponent(name)}`);
|
|
63
|
+
},
|
|
64
|
+
createSkill(data) {
|
|
65
|
+
return request(baseUrl, '/skills', {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
body: JSON.stringify(data),
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
deleteSkill(name) {
|
|
71
|
+
return request(baseUrl, `/skills/${encodeURIComponent(name)}`, { method: 'DELETE' });
|
|
72
|
+
},
|
|
73
|
+
recentRepos() {
|
|
74
|
+
return request(baseUrl, '/recent-repos');
|
|
75
|
+
},
|
|
76
|
+
defaultBranch(repoPath) {
|
|
77
|
+
return request(baseUrl, `/default-branch?repo_path=${encodeURIComponent(repoPath)}`);
|
|
78
|
+
},
|
|
55
79
|
};
|
|
56
80
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { isJsonMode, outputJson, success } from '../format.js';
|
|
2
|
+
export function registerCreateSkill(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('create-skill')
|
|
5
|
+
.description('Create a new skill')
|
|
6
|
+
.requiredOption('-n, --name <name>', 'skill name (lowercase, hyphens)')
|
|
7
|
+
.option('-c, --content <content>', 'initial content', '')
|
|
8
|
+
.action(async (opts, cmd) => {
|
|
9
|
+
const globals = cmd.optsWithGlobals();
|
|
10
|
+
const client = globals._client;
|
|
11
|
+
const content = opts.content || `---\nname: ${opts.name}\ndescription: \n---\n\n`;
|
|
12
|
+
const skill = await client.createSkill({ name: opts.name, content });
|
|
13
|
+
if (isJsonMode(globals.json)) {
|
|
14
|
+
outputJson(skill);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
success(`Created skill "${skill.name}"`);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -10,6 +10,7 @@ export function registerCreateTask(program) {
|
|
|
10
10
|
.option('-b, --branch <name>', 'branch name')
|
|
11
11
|
.option('--base-branch <name>', 'base branch name')
|
|
12
12
|
.option('--draft', 'create as draft without starting')
|
|
13
|
+
.option('--no-worktree', 'run agent in the repo directory without creating a worktree')
|
|
13
14
|
.action(async (opts, cmd) => {
|
|
14
15
|
const globals = cmd.optsWithGlobals();
|
|
15
16
|
const client = globals._client;
|
|
@@ -21,6 +22,7 @@ export function registerCreateTask(program) {
|
|
|
21
22
|
branch: opts.branch,
|
|
22
23
|
base_branch: opts.baseBranch,
|
|
23
24
|
draft: opts.draft,
|
|
25
|
+
no_worktree: opts.noWorktree,
|
|
24
26
|
});
|
|
25
27
|
if (isJsonMode(globals.json)) {
|
|
26
28
|
outputJson(task);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isJsonMode, outputJson } from '../format.js';
|
|
2
|
+
export function registerDefaultBranch(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('default-branch')
|
|
5
|
+
.description('Get default branch for a repository')
|
|
6
|
+
.requiredOption('-r, --repo-path <path>', 'path to the git repository')
|
|
7
|
+
.action(async (opts, cmd) => {
|
|
8
|
+
const globals = cmd.optsWithGlobals();
|
|
9
|
+
const client = globals._client;
|
|
10
|
+
const result = await client.defaultBranch(opts.repoPath);
|
|
11
|
+
if (isJsonMode(globals.json)) {
|
|
12
|
+
outputJson(result);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
console.log(result.branch);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { isJsonMode, success } from '../format.js';
|
|
2
|
+
export function registerDeleteSkill(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('delete-skill <name>')
|
|
5
|
+
.description('Delete a skill')
|
|
6
|
+
.action(async (name, _opts, cmd) => {
|
|
7
|
+
const globals = cmd.optsWithGlobals();
|
|
8
|
+
const client = globals._client;
|
|
9
|
+
await client.deleteSkill(name);
|
|
10
|
+
if (isJsonMode(globals.json)) {
|
|
11
|
+
console.log(JSON.stringify({ deleted: name }));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
success(`Deleted skill "${name}"`);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isJsonMode, outputJson, heading } from '../format.js';
|
|
2
|
+
export function registerGetSkill(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('get-skill <name>')
|
|
5
|
+
.description('Get skill content')
|
|
6
|
+
.action(async (name, _opts, cmd) => {
|
|
7
|
+
const globals = cmd.optsWithGlobals();
|
|
8
|
+
const client = globals._client;
|
|
9
|
+
const skill = await client.getSkill(name);
|
|
10
|
+
if (isJsonMode(globals.json)) {
|
|
11
|
+
outputJson(skill);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
heading(`Skill: ${skill.name}`);
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log(skill.content);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { isJsonMode, outputJson, heading } from '../format.js';
|
|
3
|
+
export function registerListSkills(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('list-skills')
|
|
6
|
+
.description('List all installed skills')
|
|
7
|
+
.action(async (_opts, cmd) => {
|
|
8
|
+
const globals = cmd.optsWithGlobals();
|
|
9
|
+
const client = globals._client;
|
|
10
|
+
const skills = await client.listSkills();
|
|
11
|
+
if (isJsonMode(globals.json)) {
|
|
12
|
+
outputJson(skills);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (skills.length === 0) {
|
|
16
|
+
console.log('No skills installed.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
heading(`${'NAME'.padEnd(30)}DESCRIPTION`);
|
|
20
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
21
|
+
for (const s of skills) {
|
|
22
|
+
console.log(`${s.name.padEnd(30)}${chalk.dim(s.description || '—')}`);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { isJsonMode, outputJson, heading } from '../format.js';
|
|
3
|
+
export function registerRecentRepos(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('recent-repos')
|
|
6
|
+
.description('List recently used repositories')
|
|
7
|
+
.action(async (_opts, cmd) => {
|
|
8
|
+
const globals = cmd.optsWithGlobals();
|
|
9
|
+
const client = globals._client;
|
|
10
|
+
const repos = await client.recentRepos();
|
|
11
|
+
if (isJsonMode(globals.json)) {
|
|
12
|
+
outputJson(repos);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (repos.length === 0) {
|
|
16
|
+
console.log('No recent repos.');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
heading(`${'REPO PATH'.padEnd(50)}LAST USED`);
|
|
20
|
+
console.log(chalk.dim('─'.repeat(70)));
|
|
21
|
+
for (const r of repos) {
|
|
22
|
+
console.log(`${r.repo_path.padEnd(50)}${chalk.dim(r.last_used)}`);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isJsonMode, success } from '../format.js';
|
|
2
|
+
export function registerStopAgent(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('stop-agent <agent-id>')
|
|
5
|
+
.description('Stop a specific agent on a task')
|
|
6
|
+
.requiredOption('-t, --task <task-id>', 'task ID')
|
|
7
|
+
.action(async (agentId, opts, cmd) => {
|
|
8
|
+
const globals = cmd.optsWithGlobals();
|
|
9
|
+
const client = globals._client;
|
|
10
|
+
await client.stopAgent(opts.task, agentId);
|
|
11
|
+
if (isJsonMode(globals.json)) {
|
|
12
|
+
console.log(JSON.stringify({ stopped: agentId, task: opts.task }));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
success(`Stopped agent ${agentId} on task ${opts.task}`);
|
|
16
|
+
});
|
|
17
|
+
}
|
package/cli/dist/index.js
CHANGED
|
@@ -9,7 +9,14 @@ import { registerCloseTask } from './commands/close-task.js';
|
|
|
9
9
|
import { registerDeleteTask } from './commands/delete-task.js';
|
|
10
10
|
import { registerResumeTask } from './commands/resume-task.js';
|
|
11
11
|
import { registerAddAgent } from './commands/add-agent.js';
|
|
12
|
+
import { registerStopAgent } from './commands/stop-agent.js';
|
|
12
13
|
import { registerSendMessage } from './commands/send-message.js';
|
|
14
|
+
import { registerListSkills } from './commands/list-skills.js';
|
|
15
|
+
import { registerGetSkill } from './commands/get-skill.js';
|
|
16
|
+
import { registerCreateSkill } from './commands/create-skill.js';
|
|
17
|
+
import { registerDeleteSkill } from './commands/delete-skill.js';
|
|
18
|
+
import { registerRecentRepos } from './commands/recent-repos.js';
|
|
19
|
+
import { registerDefaultBranch } from './commands/default-branch.js';
|
|
13
20
|
const program = new Command();
|
|
14
21
|
program
|
|
15
22
|
.name('octomux')
|
|
@@ -24,7 +31,14 @@ registerCloseTask(program);
|
|
|
24
31
|
registerDeleteTask(program);
|
|
25
32
|
registerResumeTask(program);
|
|
26
33
|
registerAddAgent(program);
|
|
34
|
+
registerStopAgent(program);
|
|
27
35
|
registerSendMessage(program);
|
|
36
|
+
registerListSkills(program);
|
|
37
|
+
registerGetSkill(program);
|
|
38
|
+
registerCreateSkill(program);
|
|
39
|
+
registerDeleteSkill(program);
|
|
40
|
+
registerRecentRepos(program);
|
|
41
|
+
registerDefaultBranch(program);
|
|
28
42
|
program.hook('preAction', (thisCommand) => {
|
|
29
43
|
const opts = thisCommand.optsWithGlobals();
|
|
30
44
|
const client = createClient(opts.serverUrl);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/TerminalView-CguHyqU9.js","assets/vendor-react-BZ8ItZjw.js","assets/vendor-xterm-DvXGiZvM.js","assets/vendor-xterm-DYP7pi_n.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{f as N,P as O,g as E,h as D,I as S,B as y,L as P,i as R,R as A,T as M,j as L,E as F,_ as B}from"./index-CcrRBTAX.js";import{r as n,j as e}from"./vendor-react-BZ8ItZjw.js";import"./vendor-router-DAafhmjl.js";import"./vendor-ui-BEZHWVRx.js";const T=[{slash:"/create-task",chipLabel:"+ Create Task",description:"Create a task for an autonomous agent",fields:[{name:"title",label:"Title",type:"text",required:!0,placeholder:"Fix login bug"},{name:"repo",label:"Repository",type:"repo-picker",required:!0},{name:"baseBranch",label:"Base Branch",type:"branch-picker",dependsOn:"repo"},{name:"description",label:"Description",type:"textarea",placeholder:"Describe what needs to be done..."},{name:"prompt",label:"Initial Prompt",type:"textarea",placeholder:"Tell the agent what to do..."},{name:"draft",label:"Save as draft (start later)",type:"checkbox"}],buildMessage:s=>`Create a task titled "${s.title}" in repo ${s.repo}${s.baseBranch?` with base branch ${s.baseBranch}`:""}${s.description?`. Description: ${s.description}`:""}${s.prompt?`. Prompt: ${s.prompt}`:""}${s.draft==="true"?". Create it as a draft — do not start it yet.":""}`},{slash:"/list-tasks",chipLabel:"List Tasks",description:"Show all running tasks",buildMessage:()=>"Show me all running tasks"},{slash:"/status",chipLabel:"Task Status",description:"Check status of a specific task",fields:[{name:"task",label:"Task",type:"task-picker",required:!0}],buildMessage:s=>`What is the status of task ${s.task}?`},{slash:"/create-pr",chipLabel:"Create PR",description:"Create a PR for a completed task",fields:[{name:"task",label:"Task",type:"task-picker",required:!0}],buildMessage:s=>`Create a PR for task ${s.task}`}];function K(s){const d=s.toLowerCase();return T.filter(i=>i.slash.slice(1).startsWith(d))}const $=new Set(["running","closed"]);function I({value:s,onChange:d}){const[i,p]=n.useState([]),[u,x]=n.useState(!0),[j,f]=n.useState(!1),[c,g]=n.useState("");n.useEffect(()=>{N.listTasks().then(r=>p(r.filter(k=>$.has(k.status)))).catch(()=>p([])).finally(()=>x(!1))},[]);const b=i.filter(r=>r.title.toLowerCase().includes(c.toLowerCase())),m=i.find(r=>r.id===s);return e.jsxs(O,{open:j,onOpenChange:f,children:[e.jsx(E,{render:e.jsxs("button",{type:"button",className:"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs",children:[e.jsx("span",{className:m?"":"text-muted-foreground",children:m?m.title:"Select task..."}),e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"ml-2 shrink-0 text-muted-foreground",children:e.jsx("path",{d:"m6 9 6 6 6-6"})})]})}),e.jsx(D,{align:"start",side:"bottom",sideOffset:4,className:"w-[var(--popover-trigger-width)] p-0",children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("div",{className:"p-2 border-b border-border",children:e.jsx(S,{placeholder:"Search tasks...",value:c,onChange:r=>g(r.target.value),className:"h-8 text-sm"})}),e.jsxs("div",{className:"max-h-[220px] overflow-y-auto",children:[u&&e.jsx("div",{className:"px-3 py-4 text-center text-sm text-muted-foreground",children:"Loading..."}),!u&&b.length===0&&e.jsx("div",{className:"px-3 py-4 text-center text-sm text-muted-foreground",children:"No tasks found"}),!u&&b.map(r=>e.jsxs("button",{type:"button",className:"flex w-full flex-col items-start px-3 py-2 text-left hover:bg-muted transition-colors",onClick:()=>{d(r.id),f(!1)},children:[e.jsx("span",{className:"text-sm font-semibold",children:r.title}),e.jsx("span",{className:"text-xs text-muted-foreground",children:r.id.slice(0,6)})]},r.id))]})]})})]})}function W({command:s,onSubmit:d,onClose:i,sending:p}){var w;const[u,x]=n.useState({}),[j,f]=n.useState("idle"),c=n.useCallback((t,h)=>{x(l=>{const a={...l,[t]:h};if(s.fields)for(const o of s.fields)o.dependsOn===t&&(a[o.name]="");return a})},[s.fields]),b=(!s.fields||s.fields.filter(t=>t.required).every(t=>(u[t.name]||"").trim()!==""))&&!p,m=()=>{if(!b)return;const t=s.buildMessage(u);d(t)},r=t=>{if(t.key==="Escape"){t.stopPropagation(),i();return}if((t.metaKey||t.ctrlKey)&&t.key==="Enter"){t.preventDefault(),m();return}},k=t=>{r(t),t.key==="Enter"&&!t.shiftKey&&!t.metaKey&&!t.ctrlKey&&(t.preventDefault(),m())},v=t=>{const h=u[t.name]||"";switch(t.type){case"text":return e.jsx(S,{value:h,onChange:l=>c(t.name,l.target.value),placeholder:t.placeholder,onKeyDown:k});case"textarea":return e.jsx(M,{value:h,onChange:l=>c(t.name,l.target.value),placeholder:t.placeholder,onKeyDown:r,rows:3});case"repo-picker":return e.jsx(A,{value:h,onChange:l=>c(t.name,l),onValidationChange:f});case"branch-picker":return e.jsx(R,{repoPath:t.dependsOn&&u[t.dependsOn]||"",value:h,onChange:l=>c(t.name,l),disabled:t.dependsOn?!u[t.dependsOn]:!1});case"task-picker":return e.jsx(I,{value:h,onChange:l=>c(t.name,l)});case"checkbox":return e.jsxs("label",{className:"flex items-center gap-2 text-sm text-muted-foreground cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:h==="true",onChange:l=>c(t.name,l.target.checked?"true":""),className:"rounded border-border"}),t.label]});default:return null}};return e.jsxs("div",{className:"flex flex-col gap-3 p-3",onKeyDown:r,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"font-mono text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:s.chipLabel}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{variant:"ghost",size:"sm",onClick:i,"aria-label":"Close",className:"h-7 text-[#8a8a8a] hover:text-white",children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"m6 6 12 12"})]})}),e.jsx(y,{size:"sm",disabled:!b,onClick:m,"aria-label":"Send",className:"h-7 font-mono text-xs font-bold uppercase tracking-wider",children:"SEND"})]})]}),(w=s.fields)==null?void 0:w.map(t=>e.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.type!=="checkbox"&&e.jsxs(P,{htmlFor:t.name,className:"font-mono text-[10px] uppercase tracking-wider text-[#8a8a8a]",children:[t.label,t.required&&e.jsx("span",{className:"text-[#EF4444] ml-0.5",children:"*"})]}),v(t)]},t.name))]})}function _(){const[s,d]=n.useState(""),[i,p]=n.useState(!1),[u,x]=n.useState(!1),[j,f]=n.useState(0),[c,g]=n.useState(null),b=n.useRef(null),{refresh:m}=L(),r=s.startsWith("/")?K(s.slice(1)):[],k=async a=>{if(!(!a.trim()||i)){p(!0);try{await N.orchestratorSend(a),d(""),m()}catch(o){console.error("Failed to send to orchestrator:",o)}finally{p(!1)}}},v=()=>k(s.trim()),w=u&&s.startsWith("/")&&r.length>0,t=a=>{if(w){if(a.key==="ArrowDown"){a.preventDefault(),f(o=>(o+1)%r.length);return}if(a.key==="ArrowUp"){a.preventDefault(),f(o=>(o-1+r.length)%r.length);return}if(a.key==="Enter"){a.preventDefault(),h(r[j]),x(!1);return}if(a.key==="Escape"){a.stopPropagation(),x(!1);return}}a.key==="Enter"&&!a.shiftKey&&(a.preventDefault(),v()),a.key==="Escape"&&(a.stopPropagation(),c?g(null):d(""))},h=a=>{if(a.fields){g(a),x(!1),d("");return}g(null),k(a.buildMessage({}))},l=a=>{const o=a.target.value;d(o),o.startsWith("/")?(x(!0),f(0)):x(!1);const C=a.target;C.style.height="auto",C.style.height=`${Math.min(C.scrollHeight,80)}px`};return e.jsxs("div",{className:"relative mb-4 border border-[#2f2f2f] bg-[#0A0A0A]",children:[c?e.jsx(W,{command:c,onSubmit:async a=>{p(!0);try{await N.orchestratorType(a),m(),g(null)}catch(o){console.error("Failed to type to orchestrator:",o)}finally{p(!1)}},onClose:()=>g(null),sending:i}):e.jsxs("div",{className:"flex items-end gap-2 p-3",children:[e.jsx("span",{className:"shrink-0 select-none font-mono text-sm text-[#8a8a8a]",children:">"}),e.jsx("textarea",{ref:b,value:s,onChange:l,onKeyDown:t,placeholder:"Ask the orchestrator anything...",rows:1,className:"flex-1 resize-none bg-transparent font-mono text-sm outline-none placeholder:text-[#6a6a6a]"}),e.jsx(y,{size:"sm",disabled:!s.trim()||i,onClick:v,"aria-label":"Send",className:"shrink-0",children:i?e.jsx(z,{className:"h-4 w-4 animate-spin"}):e.jsx(q,{className:"h-4 w-4"})})]}),e.jsx("div",{className:"flex flex-wrap gap-1.5 border-t border-[#2f2f2f] px-3 py-2",children:T.map(a=>e.jsx("button",{onClick:()=>h(a),className:"border border-[#2f2f2f] bg-transparent px-2.5 py-1 text-xs text-[#8a8a8a] transition-colors hover:border-[#4a4a4a] hover:text-white",children:a.chipLabel},a.slash))}),w&&e.jsx("div",{className:"absolute top-full left-0 z-50 mt-1 w-72 border border-[#2f2f2f] bg-[#0A0A0A] p-1 shadow-md",children:r.map((a,o)=>e.jsxs("button",{onClick:()=>{h(a),x(!1)},className:`flex w-full flex-col items-start px-3 py-2 text-left text-sm ${o===j?"bg-[#1a1a1a]":""}`,children:[e.jsx("span",{className:"font-mono font-semibold text-white",children:a.slash}),e.jsx("span",{className:"text-xs text-[#8a8a8a]",children:a.description})]},a.slash))})]})}function q({className:s}){return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:s,children:[e.jsx("path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}),e.jsx("path",{d:"m21.854 2.147-10.94 10.939"})]})}function z({className:s}){return e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:s,children:e.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})})}const V=n.lazy(()=>B(()=>import("./TerminalView-CguHyqU9.js"),__vite__mapDeps([0,1,2,3])).then(s=>({default:s.TerminalView})));function Q(){const{running:s,loading:d,start:i,stop:p}=L();return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-border px-6 py-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-[10px] font-bold uppercase tracking-wider text-[#6a6a6a]",children:"// ORCHESTRATOR"}),s&&e.jsx("span",{className:"h-2 w-2 animate-pulse bg-[#22C55E]"})]}),s&&e.jsx(y,{variant:"ghost",size:"sm",className:"text-destructive uppercase text-xs tracking-wider font-bold",onClick:p,children:"STOP"})]}),e.jsx("div",{className:"min-h-0 flex-1",children:d?e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading..."}):s?e.jsx(n.Suspense,{fallback:e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading terminal..."}),children:e.jsx(V,{wsUrl:"/ws/terminal/orchestrator",visible:!0})}):e.jsx(F,{icon:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("polyline",{points:"4 17 10 11 4 5"}),e.jsx("line",{x1:"12",x2:"20",y1:"19",y2:"19"})]}),heading:"ORCHESTRATOR STOPPED",subtext:"Start the orchestrator to manage tasks autonomously",action:e.jsx(y,{onClick:i,children:"START ORCHESTRATOR"}),className:"h-full"})}),s&&e.jsx("div",{className:"border-t border-border",children:e.jsx(_,{})})]})}export{Q as default};
|
|
2
|
+
import{f as N,P as O,g as P,h as E,I as S,B as y,L as R,i as D,R as A,T as M,j as T,E as F,_ as B}from"./index-DrfVrJzN.js";import{r as n,j as e}from"./vendor-react-BZ8ItZjw.js";import"./vendor-router-DAafhmjl.js";import"./vendor-ui-BEZHWVRx.js";const L=[{slash:"/create-task",chipLabel:"+ Create Task",description:"Create a task for an autonomous agent",fields:[{name:"title",label:"Title",type:"text",required:!0,placeholder:"Fix login bug"},{name:"repo",label:"Repository",type:"repo-picker",required:!0},{name:"baseBranch",label:"Base Branch",type:"branch-picker",dependsOn:"repo"},{name:"description",label:"Description",type:"textarea",placeholder:"Describe what needs to be done..."},{name:"prompt",label:"Initial Prompt",type:"textarea",placeholder:"Tell the agent what to do..."},{name:"draft",label:"Save as draft (start later)",type:"checkbox"}],buildMessage:s=>`Create a task titled "${s.title}" in repo ${s.repo}${s.baseBranch?` with base branch ${s.baseBranch}`:""}${s.description?`. Description: ${s.description}`:""}${s.prompt?`. Prompt: ${s.prompt}`:""}${s.draft==="true"?". Create it as a draft — do not start it yet.":""}`},{slash:"/list-tasks",chipLabel:"List Tasks",description:"Show all running tasks",buildMessage:()=>"Show me all running tasks"},{slash:"/status",chipLabel:"Task Status",description:"Check status of a specific task",fields:[{name:"task",label:"Task",type:"task-picker",required:!0}],buildMessage:s=>`What is the status of task ${s.task}?`},{slash:"/create-pr",chipLabel:"Create PR",description:"Create a PR for a completed task",fields:[{name:"task",label:"Task",type:"task-picker",required:!0}],buildMessage:s=>`Create a PR for task ${s.task}`}];function K(s){const h=s.toLowerCase();return L.filter(i=>i.slash.slice(1).startsWith(h))}const W=new Set(["running","closed"]);function $({value:s,onChange:h}){const[i,u]=n.useState([]),[c,x]=n.useState(!0),[j,f]=n.useState(!1),[d,g]=n.useState("");n.useEffect(()=>{N.listTasks().then(r=>u(r.filter(k=>W.has(k.status)))).catch(()=>u([])).finally(()=>x(!1))},[]);const b=i.filter(r=>r.title.toLowerCase().includes(d.toLowerCase())),m=i.find(r=>r.id===s);return e.jsxs(O,{open:j,onOpenChange:f,children:[e.jsx(P,{render:e.jsxs("button",{type:"button",className:"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs",children:[e.jsx("span",{className:m?"":"text-muted-foreground",children:m?m.title:"Select task..."}),e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:"ml-2 shrink-0 text-muted-foreground",children:e.jsx("path",{d:"m6 9 6 6 6-6"})})]})}),e.jsx(E,{align:"start",side:"bottom",sideOffset:4,className:"w-[var(--popover-trigger-width)] p-0",children:e.jsxs("div",{className:"flex flex-col",children:[e.jsx("div",{className:"p-2 border-b border-border",children:e.jsx(S,{placeholder:"Search tasks...",value:d,onChange:r=>g(r.target.value),className:"h-8 text-sm"})}),e.jsxs("div",{className:"max-h-[220px] overflow-y-auto",children:[c&&e.jsx("div",{className:"px-3 py-4 text-center text-sm text-muted-foreground",children:"Loading..."}),!c&&b.length===0&&e.jsx("div",{className:"px-3 py-4 text-center text-sm text-muted-foreground",children:"No tasks found"}),!c&&b.map(r=>e.jsxs("button",{type:"button",className:"flex w-full flex-col items-start px-3 py-2 text-left hover:bg-muted transition-colors",onClick:()=>{h(r.id),f(!1)},children:[e.jsx("span",{className:"text-sm font-semibold",children:r.title}),e.jsx("span",{className:"text-xs text-muted-foreground",children:r.id.slice(0,6)})]},r.id))]})]})})]})}function I({command:s,onSubmit:h,onClose:i,sending:u}){var w;const[c,x]=n.useState({}),[j,f]=n.useState("idle"),d=n.useCallback((t,p)=>{x(l=>{const a={...l,[t]:p};if(s.fields)for(const o of s.fields)o.dependsOn===t&&(a[o.name]="");return a})},[s.fields]),b=(!s.fields||s.fields.filter(t=>t.required).every(t=>(c[t.name]||"").trim()!==""))&&!u,m=()=>{if(!b)return;const t=s.buildMessage(c);h(t)},r=t=>{if(t.key==="Escape"){t.stopPropagation(),i();return}if((t.metaKey||t.ctrlKey)&&t.key==="Enter"){t.preventDefault(),m();return}},k=t=>{r(t),t.key==="Enter"&&!t.shiftKey&&!t.metaKey&&!t.ctrlKey&&(t.preventDefault(),m())},v=t=>{const p=c[t.name]||"";switch(t.type){case"text":return e.jsx(S,{value:p,onChange:l=>d(t.name,l.target.value),placeholder:t.placeholder,onKeyDown:k});case"textarea":return e.jsx(M,{value:p,onChange:l=>d(t.name,l.target.value),placeholder:t.placeholder,onKeyDown:r,rows:3});case"repo-picker":return e.jsx(A,{value:p,onChange:l=>d(t.name,l),onValidationChange:f});case"branch-picker":return e.jsx(D,{repoPath:t.dependsOn&&c[t.dependsOn]||"",value:p,onChange:l=>d(t.name,l),disabled:t.dependsOn?!c[t.dependsOn]:!1});case"task-picker":return e.jsx($,{value:p,onChange:l=>d(t.name,l)});case"checkbox":return e.jsxs("label",{className:"flex items-center gap-2 text-sm text-muted-foreground cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:p==="true",onChange:l=>d(t.name,l.target.checked?"true":""),className:"rounded border-border"}),t.label]});default:return null}};return e.jsxs("div",{className:"flex flex-col gap-3 p-3",onKeyDown:r,children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"font-mono text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:s.chipLabel}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{variant:"ghost",size:"sm",onClick:i,"aria-label":"Close",className:"h-7 text-[#8a8a8a] hover:text-white",children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"m6 6 12 12"})]})}),e.jsx(y,{size:"sm",disabled:!b,onClick:m,"aria-label":"Send",className:"h-7 font-mono text-xs font-bold uppercase tracking-wider",children:"SEND"})]})]}),(w=s.fields)==null?void 0:w.map(t=>e.jsxs("div",{className:"flex flex-col gap-1.5",children:[t.type!=="checkbox"&&e.jsxs(R,{htmlFor:t.name,className:"font-mono text-[10px] uppercase tracking-wider text-[#8a8a8a]",children:[t.label,t.required&&e.jsx("span",{className:"text-[#EF4444] ml-0.5",children:"*"})]}),v(t)]},t.name))]})}function _(){const[s,h]=n.useState(""),[i,u]=n.useState(!1),[c,x]=n.useState(!1),[j,f]=n.useState(0),[d,g]=n.useState(null),b=n.useRef(null),{refresh:m}=T(),r=s.startsWith("/")?K(s.slice(1)):[],k=async a=>{if(!(!a.trim()||i)){u(!0);try{await N.orchestratorSend(a),h(""),m()}catch(o){console.error("Failed to send to orchestrator:",o)}finally{u(!1)}}},v=()=>k(s.trim()),w=c&&s.startsWith("/")&&r.length>0,t=a=>{if(w){if(a.key==="ArrowDown"){a.preventDefault(),f(o=>(o+1)%r.length);return}if(a.key==="ArrowUp"){a.preventDefault(),f(o=>(o-1+r.length)%r.length);return}if(a.key==="Enter"){a.preventDefault(),p(r[j]),x(!1);return}if(a.key==="Escape"){a.stopPropagation(),x(!1);return}}a.key==="Enter"&&!a.shiftKey&&(a.preventDefault(),v()),a.key==="Escape"&&(a.stopPropagation(),d?g(null):h(""))},p=a=>{if(a.fields){g(a),x(!1),h("");return}g(null),k(a.buildMessage({}))},l=a=>{const o=a.target.value;h(o),o.startsWith("/")?(x(!0),f(0)):x(!1);const C=a.target;C.style.height="auto",C.style.height=`${Math.min(C.scrollHeight,80)}px`};return e.jsxs("div",{className:"relative mb-4 border border-[#2f2f2f] bg-[#0A0A0A]",children:[d?e.jsx(I,{command:d,onSubmit:async a=>{u(!0);try{await N.orchestratorType(a),m(),g(null)}catch(o){console.error("Failed to type to orchestrator:",o)}finally{u(!1)}},onClose:()=>g(null),sending:i}):e.jsxs("div",{className:"flex items-end gap-2 p-3",children:[e.jsx("span",{className:"shrink-0 select-none font-mono text-sm text-[#8a8a8a]",children:">"}),e.jsx("textarea",{ref:b,value:s,onChange:l,onKeyDown:t,placeholder:"Ask the orchestrator anything...",rows:1,className:"flex-1 resize-none bg-transparent font-mono text-sm outline-none placeholder:text-[#6a6a6a]"}),e.jsx(y,{size:"sm",disabled:!s.trim()||i,onClick:v,"aria-label":"Send",className:"shrink-0",children:i?e.jsx(z,{className:"h-4 w-4 animate-spin"}):e.jsx(q,{className:"h-4 w-4"})})]}),e.jsx("div",{className:"flex flex-wrap gap-1.5 border-t border-[#2f2f2f] px-3 py-2",children:L.map(a=>e.jsx("button",{onClick:()=>p(a),className:"border border-[#2f2f2f] bg-transparent px-2.5 py-1 text-xs text-[#8a8a8a] transition-colors hover:border-[#4a4a4a] hover:text-white",children:a.chipLabel},a.slash))}),w&&e.jsx("div",{className:"absolute top-full left-0 z-50 mt-1 w-72 border border-[#2f2f2f] bg-[#0A0A0A] p-1 shadow-md",children:r.map((a,o)=>e.jsxs("button",{onClick:()=>{p(a),x(!1)},className:`flex w-full flex-col items-start px-3 py-2 text-left text-sm ${o===j?"bg-[#1a1a1a]":""}`,children:[e.jsx("span",{className:"font-mono font-semibold text-white",children:a.slash}),e.jsx("span",{className:"text-xs text-[#8a8a8a]",children:a.description})]},a.slash))})]})}function q({className:s}){return e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:s,children:[e.jsx("path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}),e.jsx("path",{d:"m21.854 2.147-10.94 10.939"})]})}function z({className:s}){return e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:s,children:e.jsx("path",{d:"M21 12a9 9 0 1 1-6.219-8.56"})})}const V=n.lazy(()=>B(()=>import("./TerminalView-CguHyqU9.js"),__vite__mapDeps([0,1,2,3])).then(s=>({default:s.TerminalView})));function Q(){const{running:s,loading:h,start:i,stop:u}=T(),[c,x]=n.useState(!1);return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-border px-6 py-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-[10px] font-bold uppercase tracking-wider text-[#6a6a6a]",children:"// ORCHESTRATOR"}),s&&e.jsx("span",{className:"h-2 w-2 animate-pulse bg-[#22C55E]"}),e.jsxs("div",{className:"relative",children:[e.jsx("button",{onClick:()=>x(!c),className:"flex h-5 w-5 items-center justify-center text-[10px] text-[#6a6a6a] hover:text-white","aria-label":"Orchestrator help",children:"?"}),c&&e.jsxs("div",{className:"absolute left-0 top-7 z-50 w-80 border border-[#2f2f2f] bg-[#1a1a1a] p-4 text-xs shadow-lg",children:[e.jsx("p",{className:"mb-2 font-bold text-white",children:"What can the orchestrator do?"}),e.jsxs("ul",{className:"mb-3 space-y-1 text-[#8a8a8a]",children:[e.jsx("li",{children:"Create tasks to dispatch autonomous Claude Code agents"}),e.jsx("li",{children:"Monitor running tasks and their agents"}),e.jsx("li",{children:"Close or resume tasks as needed"}),e.jsx("li",{children:"Add agents to running tasks for parallel work"}),e.jsx("li",{children:"Generate PR previews and create PRs for completed work"}),e.jsx("li",{children:"Check status and troubleshoot errors"})]}),e.jsx("p",{className:"mb-1 font-bold text-white",children:"Try something like:"}),e.jsxs("ul",{className:"space-y-1 text-[#8a8a8a]",children:[e.jsx("li",{children:'"Create a task to fix the login bug in the auth service"'}),e.jsx("li",{children:'"Show me all running tasks"'}),e.jsx("li",{children:'"What is the status of task abc123?"'})]})]})]})]}),s&&e.jsx(y,{variant:"ghost",size:"sm",className:"text-destructive uppercase text-xs tracking-wider font-bold",onClick:u,children:"STOP"})]}),e.jsx("div",{className:"min-h-0 flex-1",children:h?e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading..."}):s?e.jsx(n.Suspense,{fallback:e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading terminal..."}),children:e.jsx(V,{wsUrl:"/ws/terminal/orchestrator",visible:!0})}):e.jsx(F,{icon:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("polyline",{points:"4 17 10 11 4 5"}),e.jsx("line",{x1:"12",x2:"20",y1:"19",y2:"19"})]}),heading:"ORCHESTRATOR STOPPED",subtext:"Start the orchestrator to manage tasks autonomously",action:e.jsx(y,{onClick:i,children:"START ORCHESTRATOR"}),className:"h-full"})}),s&&e.jsx("div",{className:"border-t border-border",children:e.jsx(_,{})})]})}export{Q as default};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{r,j as e}from"./vendor-react-BZ8ItZjw.js";import{f as h,t as i,k}from"./index-DrfVrJzN.js";import{a as A}from"./vendor-router-DAafhmjl.js";import"./vendor-ui-BEZHWVRx.js";function y({checked:a,onChange:o}){return e.jsx("button",{type:"button",role:"switch","aria-checked":a,className:`relative h-5 w-9 transition-colors ${a?"bg-primary":"bg-[#2f2f2f]"}`,onClick:()=>o(!a),children:e.jsx("span",{className:`absolute top-0.5 left-0.5 h-4 w-4 bg-white transition-transform ${a?"translate-x-4":""}`})})}function g({label:a}){return e.jsxs("h2",{className:"mb-4 text-[10px] font-bold uppercase tracking-wider text-[#6a6a6a]",children:["// ",a]})}function j({label:a,description:o,children:n}){return e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] py-3",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm",children:a}),o&&e.jsx("p",{className:"text-xs text-[#6a6a6a]",children:o})]}),n]})}function E(){const{skills:a,loading:o,error:n,refresh:x}=k(),l=A(),[N,d]=r.useState(!1),[c,u]=r.useState(""),[f,b]=r.useState(!1),[m,t]=r.useState(null),[p,w]=r.useState(!1),S=r.useCallback(async()=>{if(c.trim()){b(!0);try{const s=`---
|
|
2
|
+
name: ${c.trim()}
|
|
3
|
+
description:
|
|
4
|
+
---
|
|
5
|
+
`;await h.createSkill({name:c.trim(),content:s}),i.success(`Skill "${c.trim()}" created`),d(!1),u(""),l(`/skills/${encodeURIComponent(c.trim())}`)}catch(s){i.error(s.message)}finally{b(!1)}}},[c,l]),v=r.useCallback(async()=>{if(m){w(!0);try{await h.deleteSkill(m),i.success(`Skill "${m}" deleted`),t(null),x()}catch(s){i.error(s.message)}finally{w(!1)}}},[m,x]);return e.jsxs("section",{className:"mb-8",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(g,{label:"SKILLS"}),e.jsx("button",{className:"mb-4 text-xs text-[#3B82F6] hover:text-[#60a5fa]",onClick:()=>d(!0),children:"+ New Skill"})]}),o&&e.jsx("div",{className:"space-y-3",children:[1,2,3].map(s=>e.jsx("div",{className:"h-12 animate-pulse rounded bg-[#141414] border border-[#2f2f2f]"},s))}),n&&e.jsxs("div",{className:"flex items-center gap-3 rounded border border-red-400/30 bg-red-400/5 px-4 py-3",children:[e.jsx("span",{className:"text-sm text-red-400",children:n}),e.jsx("button",{className:"text-xs text-[#3B82F6] hover:text-[#60a5fa]",onClick:x,children:"Retry"})]}),!o&&!n&&a.length===0&&e.jsxs("div",{className:"py-8 text-center text-sm text-[#6a6a6a]",children:["No skills installed."," ",e.jsx("button",{className:"text-[#3B82F6] hover:text-[#60a5fa]",onClick:()=>d(!0),children:"Create your first skill"})]}),!o&&!n&&a.length>0&&e.jsx("div",{className:"space-y-0",children:a.map(s=>e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] py-3 cursor-pointer hover:bg-[#141414]",onClick:()=>l(`/skills/${encodeURIComponent(s.name)}`),children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-mono",children:s.name}),s.description&&e.jsx("p",{className:"text-xs text-[#8a8a8a]",children:s.description})]}),e.jsx("button",{className:"text-xs text-[#6a6a6a] hover:text-red-400",onClick:C=>{C.stopPropagation(),t(s.name)},children:"Delete"})]},s.name))}),N&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:()=>d(!1),children:e.jsxs("div",{className:"w-full max-w-md rounded border border-[#2f2f2f] bg-[#0A0A0A] p-6",onClick:s=>s.stopPropagation(),children:[e.jsx("h3",{className:"mb-4 text-sm font-bold",children:"Create Skill"}),e.jsx("input",{type:"text",placeholder:"Skill name",value:c,onChange:s=>u(s.target.value),onKeyDown:s=>s.key==="Enter"&&S(),className:"mb-4 w-full rounded border border-[#2f2f2f] bg-[#141414] px-3 py-2 font-mono text-sm text-white outline-none focus:border-[#3B82F6]",autoFocus:!0}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{className:"rounded px-3 py-1.5 text-xs text-[#8a8a8a] hover:text-white",onClick:()=>d(!1),children:"Cancel"}),e.jsx("button",{className:"rounded bg-[#3B82F6] px-3 py-1.5 text-xs text-white hover:bg-[#2563eb] disabled:opacity-50",onClick:S,disabled:f||!c.trim(),children:f?"Creating…":"Create"})]})]})}),m&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/50",onClick:()=>t(null),children:e.jsxs("div",{className:"w-full max-w-sm rounded border border-[#2f2f2f] bg-[#0A0A0A] p-6",onClick:s=>s.stopPropagation(),children:[e.jsx("h3",{className:"mb-2 text-sm font-bold",children:"Delete Skill"}),e.jsxs("p",{className:"mb-4 text-xs text-[#8a8a8a]",children:["Are you sure you want to delete"," ",e.jsx("span",{className:"font-mono text-white",children:m}),"? This cannot be undone."]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{className:"rounded px-3 py-1.5 text-xs text-[#8a8a8a] hover:text-white",onClick:()=>t(null),children:"Cancel"}),e.jsx("button",{className:"rounded bg-red-600 px-3 py-1.5 text-xs text-white hover:bg-red-700 disabled:opacity-50",onClick:v,disabled:p,children:p?"Deleting…":"Delete"})]})]})})]})}function F(){const[a,o]=r.useState(null),[n,x]=r.useState(""),[l,N]=r.useState(!0),[d,c]=r.useState(!1),u=r.useRef(""),f=n!==u.current;r.useEffect(()=>{h.getOrchestratorPrompt().then(t=>{o(t),x(t.content),u.current=t.content}).catch(t=>i.error(t.message)).finally(()=>N(!1))},[]);const b=r.useCallback(async()=>{if(!(!f||d)){c(!0);try{await h.updateOrchestratorPrompt(n),u.current=n,o(t=>t&&{...t,content:n,isCustom:!0}),i.success("Prompt saved. Orchestrator restarted.")}catch(t){i.error(t instanceof Error?t.message:"Failed to save prompt")}finally{c(!1)}}},[n,f,d]),m=r.useCallback(async()=>{if(window.confirm("Reset orchestrator prompt to default? This cannot be undone."))try{await h.resetOrchestratorPrompt();const t=await h.getOrchestratorPrompt();o(t),x(t.content),u.current=t.content,i.success("Prompt reset to default. Orchestrator restarted.")}catch(t){i.error(t instanceof Error?t.message:"Failed to reset prompt")}},[]);return r.useEffect(()=>{const t=p=>{(p.metaKey||p.ctrlKey)&&p.key==="s"&&(p.preventDefault(),b())};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[b]),l?e.jsx("p",{className:"py-3 text-xs text-[#6a6a6a]",children:"Loading prompt..."}):e.jsxs(e.Fragment,{children:[e.jsx(j,{label:"Orchestrator Prompt",description:"Customize the orchestrator's system prompt",children:e.jsxs("div",{className:"flex items-center gap-2",children:[f&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"}),e.jsx("button",{onClick:b,disabled:!f||d,className:"bg-[#3B82F6] px-3 py-1 text-xs text-white disabled:opacity-50",children:d?"Saving...":"Save"})]})}),e.jsxs("div",{className:"border-b border-[#2f2f2f] pb-4",children:[e.jsx("textarea",{value:n,onChange:t=>x(t.target.value),className:"mt-2 h-64 w-full resize-y border border-[#2f2f2f] bg-[#0A0A0A] p-3 font-mono text-xs leading-relaxed text-white outline-none focus:border-[#3B82F6]",spellCheck:!1}),e.jsx("div",{className:"mt-2 flex items-center gap-3",children:(a==null?void 0:a.isCustom)&&e.jsx("button",{onClick:m,className:"text-xs text-red-400 hover:text-red-300",children:"Reset to Default"})})]})]})}function T(){const[a,o]=r.useState(()=>localStorage.getItem("octomux-notifications")!=="false"),[n,x]=r.useState(()=>localStorage.getItem("octomux-sidebar-collapsed")==="true");return e.jsx("div",{className:"h-full overflow-auto",children:e.jsxs("div",{className:"mx-auto max-w-2xl px-6 py-6",children:[e.jsx("h1",{className:"mb-8 font-display text-2xl font-bold",children:"SETTINGS"}),e.jsxs("section",{className:"mb-8",children:[e.jsx(g,{label:"GENERAL"}),e.jsx(j,{label:"Notifications",description:"Show toast notifications for task events",children:e.jsx(y,{checked:a,onChange:l=>{o(l),localStorage.setItem("octomux-notifications",String(l))}})}),e.jsx(j,{label:"Sidebar collapsed by default",children:e.jsx(y,{checked:n,onChange:l=>{x(l),localStorage.setItem("octomux-sidebar-collapsed",String(l))}})})]}),e.jsxs("section",{className:"mb-8",children:[e.jsx(g,{label:"TASK DEFAULTS"}),e.jsx(j,{label:"Default base branch",description:"Branch used as default when creating tasks",children:e.jsx("span",{className:"text-xs text-[#8a8a8a]",children:"main"})})]}),e.jsxs("section",{className:"mb-8",children:[e.jsx(g,{label:"ORCHESTRATOR"}),e.jsx(j,{label:"Auto-start orchestrator",description:"Start orchestrator when dashboard loads",children:e.jsx(y,{checked:!1,onChange:()=>{}})}),e.jsx(F,{}),e.jsx(j,{label:"Restart Orchestrator",description:"Stop and restart the orchestrator process",children:e.jsx("button",{onClick:async()=>{try{await h.orchestratorStop(),await h.orchestratorStart(),i.success("Orchestrator restarted")}catch(l){i.error(l instanceof Error?l.message:"Failed to restart")}},className:"bg-[#2f2f2f] px-3 py-1 text-xs text-white hover:bg-[#3f3f3f]",children:"Restart"})})]}),e.jsx(E,{})]})})}export{T as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as s,j as t}from"./vendor-react-BZ8ItZjw.js";import{f as m,t as h}from"./index-DrfVrJzN.js";import{c as j,a as w}from"./vendor-router-DAafhmjl.js";import"./vendor-ui-BEZHWVRx.js";function S(){const{name:a}=j(),o=w(),[l,f]=s.useState(""),[v,p]=s.useState(!0),[u,g]=s.useState(null),[i,x]=s.useState(!1),c=s.useRef(""),n=l!==c.current;s.useEffect(()=>{a&&m.getSkill(a).then(e=>{f(e.content),c.current=e.content}).catch(e=>g(e.message)).finally(()=>p(!1))},[a]);const d=s.useCallback(async()=>{if(!(!a||!n||i)){x(!0);try{await m.updateSkill(a,{content:l}),c.current=l,h.success("Skill saved")}catch(e){h.error(e instanceof Error?e.message:"Failed to save skill")}finally{x(!1)}}},[a,l,n,i]);s.useEffect(()=>{const e=r=>{(r.metaKey||r.ctrlKey)&&r.key==="s"&&(r.preventDefault(),d())};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[d]);const b=s.useCallback(()=>{n&&!window.confirm("You have unsaved changes. Discard them?")||o("/settings")},[n,o]);return s.useEffect(()=>{const e=r=>{n&&r.preventDefault()};return window.addEventListener("beforeunload",e),()=>window.removeEventListener("beforeunload",e)},[n]),v?t.jsx("div",{className:"flex h-full items-center justify-center",children:t.jsx("span",{className:"text-[#6a6a6a]",children:"Loading..."})}):u?t.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3",children:[t.jsx("p",{className:"text-red-400",children:u}),t.jsx("button",{onClick:()=>o("/settings"),className:"text-xs text-[#3B82F6] hover:underline",children:"Back to Settings"})]}):t.jsxs("div",{className:"flex h-full flex-col",children:[t.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] px-6 py-4",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("button",{onClick:b,className:"text-sm text-[#6a6a6a] hover:text-white",children:"←"}),t.jsx("span",{className:"font-mono text-lg font-bold",children:a}),n&&t.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"})]}),t.jsx("button",{onClick:d,disabled:!n||i,className:"bg-[#3B82F6] px-4 py-2 text-xs text-white disabled:opacity-50",children:i?"Saving...":"Save"})]}),t.jsx("div",{className:"flex-1 p-6",children:t.jsx("textarea",{value:l,onChange:e=>f(e.target.value),className:"h-full min-h-[500px] w-full resize-none border border-[#2f2f2f] bg-[#0A0A0A] p-4 font-mono text-sm leading-relaxed text-white outline-none focus:border-[#3B82F6]",spellCheck:!1})})]})}export{S as default};
|