octomux 1.0.28 → 1.0.30

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 (49) hide show
  1. package/bin/octomux.js +48 -9
  2. package/cli/dist/client.js +3 -0
  3. package/cli/dist/commands/hooks-install.js +17 -23
  4. package/cli/dist/commands/init.js +1 -0
  5. package/cli/dist/commands/list-integrations.js +46 -0
  6. package/cli/dist/commands/task-ref-add.js +19 -1
  7. package/cli/dist/index.js +2 -0
  8. package/dist/assets/{AgentEditor-DycLX5gc.js → AgentEditor-C-55HShP.js} +1 -1
  9. package/dist/assets/{ChatPage-BX3TyXOz.js → ChatPage-2n4U1InI.js} +2 -2
  10. package/dist/assets/IntegrationsPage-ChleYO1n.js +1 -0
  11. package/dist/assets/ReviewDetailPage-DgrEGANy.js +1 -0
  12. package/dist/assets/SetupPage-Cdr8AEDl.js +1 -0
  13. package/dist/assets/{SkillEditor-BLHi9Jym.js → SkillEditor-Br3LMps4.js} +1 -1
  14. package/dist/assets/{WorkspaceDetailPage-DwACtQeu.js → WorkspaceDetailPage-BA4KkTu6.js} +1 -1
  15. package/dist/assets/{WorkspacesPage-Dwp5ejqw.js → WorkspacesPage-CEmv-ObL.js} +1 -1
  16. package/dist/assets/index-CghBwA2d.js +35 -0
  17. package/dist/assets/index-D1KcUNra.css +1 -0
  18. package/dist/assets/{vendor-monaco-8w_IdZy_.js → vendor-monaco-CdNyTACs.js} +3 -3
  19. package/dist/assets/{vendor-react-DVZ9vYhU.js → vendor-react-Dd26lTa7.js} +1 -1
  20. package/dist/assets/{vendor-router-BNSfXSMI.js → vendor-router-yJbofmar.js} +1 -1
  21. package/dist/assets/{vendor-ui-vLFv-L6M.js → vendor-ui-ChI1tM4e.js} +1 -1
  22. package/dist/index.html +6 -6
  23. package/dist-server/chunk-5TX2AE6V.js +2 -0
  24. package/dist-server/{chunk-QYDQSULJ.js → chunk-6RXAD73K.js} +60 -16
  25. package/dist-server/chunk-GBD6IX6H.js +1 -0
  26. package/dist-server/chunk-L74QMQAV.js +1 -0
  27. package/dist-server/chunk-PE6WB7WG.js +36 -0
  28. package/dist-server/chunk-RGKFIAYK.js +2 -0
  29. package/dist-server/{chunk-CQGZWR4R.js → chunk-WFZH7745.js} +1 -1
  30. package/dist-server/hooks-install-KIDJPWBY.js +1 -0
  31. package/dist-server/index.js +189 -118
  32. package/dist-server/prefill-3FPWBCW4.js +14 -0
  33. package/dist-server/{preflight-SPZ34KHK.js → preflight-7M4CZVOF.js} +1 -1
  34. package/dist-server/publish-review-7GG3AEZI.js +7 -0
  35. package/dist-server/settings-EYM2VUM7.js +1 -0
  36. package/dist-server/setup-status-SRJSWBUH.js +1 -0
  37. package/dist-server/startup.js +1 -1
  38. package/dist-server/store-6VCU4ZDL.js +1 -0
  39. package/package.json +2 -2
  40. package/skills/create-task/SKILL.md +50 -2
  41. package/skills/review-orchestrator/SKILL.md +192 -0
  42. package/skills/update-task-status/SKILL.md +10 -2
  43. package/dist/assets/IntegrationsPage-DKzQcc9w.js +0 -1
  44. package/dist/assets/SettingsPage-B_civ8AA.js +0 -9
  45. package/dist/assets/TasksPage-C59OCX7K.js +0 -5
  46. package/dist/assets/index-Cuel_jco.js +0 -18
  47. package/dist/assets/index-Dkw-hNxU.css +0 -1
  48. package/dist/assets/switch-C09mhZ7e.js +0 -1
  49. package/dist-server/store-AIK32B2H.js +0 -1
package/bin/octomux.js CHANGED
@@ -19,6 +19,8 @@ const command = args[0];
19
19
 
20
20
  if (command === 'start') {
21
21
  await runStart(args.slice(1));
22
+ } else if (command === 'review') {
23
+ await runReview(args.slice(1));
22
24
  } else {
23
25
  // Delegate to CLI (commander-based) for all other commands
24
26
  await import('../cli/dist/index.js');
@@ -53,11 +55,10 @@ async function runStart(startArgs) {
53
55
  // Fix node-pty spawn-helper permissions (may have been missed if postinstall didn't run)
54
56
  fixNodePtyPermissions();
55
57
 
56
- // Preflight: ensure all required binaries are installed
57
- const { ensureBinary, checkNeovimVersion, syncLazyVimPlugins } =
58
- await import('../dist-server/startup.js');
58
+ // Preflight: warn about missing tools (install from dashboard Setup — no blocking exit)
59
+ const { warnBinary, checkNeovimVersion } = await import('../dist-server/startup.js');
59
60
 
60
- const required = [
61
+ const preflight = [
61
62
  { cmd: 'tmux', checkArgs: ['-V'], brewPkg: 'tmux' },
62
63
  { cmd: 'git', checkArgs: ['--version'], brewPkg: 'git' },
63
64
  {
@@ -66,18 +67,22 @@ async function runStart(startArgs) {
66
67
  name: 'Claude Code CLI',
67
68
  installUrl: 'https://docs.anthropic.com/en/docs/claude-code',
68
69
  },
70
+ {
71
+ cmd: 'cursor-agent',
72
+ checkArgs: ['--version'],
73
+ name: 'Cursor CLI',
74
+ installUrl: 'https://cursor.com/docs/cli',
75
+ },
69
76
  { cmd: 'nvim', checkArgs: ['--version'], brewPkg: 'neovim', name: 'neovim' },
70
77
  { cmd: 'lazygit', checkArgs: ['--version'], brewPkg: 'lazygit' },
71
78
  ];
72
79
 
73
- for (const dep of required) {
74
- ensureBinary(dep);
80
+ for (const dep of preflight) {
81
+ warnBinary(dep);
75
82
  }
76
83
 
77
- // Neovim-specific: version check + LazyVim plugin sync
78
- const repoRoot = path.resolve(__dirname, '..');
79
84
  checkNeovimVersion();
80
- syncLazyVimPlugins(repoRoot);
85
+ console.log('Open Setup in the dashboard to install dependencies and configure defaults.\n');
81
86
 
82
87
  // Start server
83
88
  process.env.NODE_ENV = 'production';
@@ -103,6 +108,40 @@ async function runStart(startArgs) {
103
108
  }
104
109
  }
105
110
 
111
+ // ─── review subcommand ───────────────────────────────────────────────────────
112
+
113
+ async function runReview(reviewArgs) {
114
+ // Prefer the compiled dist build when present; fall back to running the
115
+ // TypeScript source directly via tsx in dev. tsx is a project devDependency.
116
+ const distEntry = path.join(__dirname, '..', 'dist-server', 'cli-review.js');
117
+ if (existsSync(distEntry)) {
118
+ const { runReview: handler } = await import(distEntry);
119
+ await handler(reviewArgs);
120
+ return;
121
+ }
122
+
123
+ // Dev path: locate tsx (local node_modules first, then walk up for git worktrees
124
+ // sharing a parent install, then fall back to `npx tsx` which respects PATH).
125
+ const entry = path.join(__dirname, '..', 'cli', 'review', 'index.ts');
126
+ const candidates = [path.join(__dirname, '..', 'node_modules', '.bin', 'tsx')];
127
+ let dir = path.resolve(__dirname, '..', '..');
128
+ for (let i = 0; i < 5; i++) {
129
+ candidates.push(path.join(dir, 'node_modules', '.bin', 'tsx'));
130
+ dir = path.dirname(dir);
131
+ }
132
+ const tsxBin = candidates.find((p) => existsSync(p));
133
+ try {
134
+ if (tsxBin) {
135
+ execFileSync(tsxBin, [entry, ...reviewArgs], { stdio: 'inherit' });
136
+ } else {
137
+ execFileSync('npx', ['--yes', 'tsx', entry, ...reviewArgs], { stdio: 'inherit' });
138
+ }
139
+ } catch (err) {
140
+ // Propagate the child's exit code without dumping a stack trace.
141
+ process.exit(typeof err.status === 'number' ? err.status : 1);
142
+ }
143
+ }
144
+
106
145
  // ─── cli dependency installer ────────────────────────────────────────────────
107
146
 
108
147
  function ensureCliDeps() {
@@ -30,6 +30,9 @@ async function request(baseUrl, path, options) {
30
30
  export function createClient(serverUrl) {
31
31
  const baseUrl = serverUrl.replace(/\/$/, '') + '/api';
32
32
  return {
33
+ listIntegrations() {
34
+ return request(baseUrl, '/integrations');
35
+ },
33
36
  createTask(data) {
34
37
  return request(baseUrl, '/tasks', { method: 'POST', body: JSON.stringify(data) });
35
38
  },
@@ -5,9 +5,6 @@ import os from 'os';
5
5
  import chalk from 'chalk';
6
6
  import { success, errorMessage } from '../format.js';
7
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
- // Resolve the templates directory relative to this file.
9
- // In dev: cli/src/commands/ → ../../templates (monorepo root)
10
- // In dist: cli/dist/commands/ → ../../../templates (monorepo root)
11
8
  function resolveTemplateDir() {
12
9
  const candidates = [
13
10
  path.resolve(__dirname, '..', '..', '..', '..', 'templates', 'hooks'),
@@ -19,9 +16,25 @@ function resolveTemplateDir() {
19
16
  if (fs.existsSync(c))
20
17
  return c;
21
18
  }
22
- // Fallback — may throw later with a clear error.
23
19
  return candidates[0];
24
20
  }
21
+ function listAvailableTemplates(templatesBase) {
22
+ try {
23
+ if (!fs.existsSync(templatesBase))
24
+ return [];
25
+ return fs.readdirSync(templatesBase).filter((f) => {
26
+ try {
27
+ return fs.statSync(path.join(templatesBase, f)).isDirectory();
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ });
33
+ }
34
+ catch {
35
+ return [];
36
+ }
37
+ }
25
38
  export function registerHooksInstall(program) {
26
39
  program
27
40
  .command('hooks-install <template>')
@@ -62,7 +75,6 @@ export function registerHooksInstall(program) {
62
75
  process.exit(1);
63
76
  }
64
77
  fs.copyFileSync(src, dest);
65
- // Make scripts executable (files without .json extension)
66
78
  if (!fileName.endsWith('.json')) {
67
79
  fs.chmodSync(dest, 0o755);
68
80
  }
@@ -75,7 +87,6 @@ export function registerHooksInstall(program) {
75
87
  for (const f of installed) {
76
88
  console.log(' ' + chalk.cyan(f));
77
89
  }
78
- // Print next steps for jira-status template.
79
90
  if (template === 'jira-status') {
80
91
  console.log('');
81
92
  console.log(chalk.bold('Next steps:'));
@@ -96,20 +107,3 @@ export function registerHooksInstall(program) {
96
107
  console.log('');
97
108
  });
98
109
  }
99
- function listAvailableTemplates(templatesBase) {
100
- try {
101
- if (!fs.existsSync(templatesBase))
102
- return [];
103
- return fs.readdirSync(templatesBase).filter((f) => {
104
- try {
105
- return fs.statSync(path.join(templatesBase, f)).isDirectory();
106
- }
107
- catch {
108
- return false;
109
- }
110
- });
111
- }
112
- catch {
113
- return [];
114
- }
115
- }
@@ -137,6 +137,7 @@ export function registerInit(program) {
137
137
  console.log(' • Start the dashboard:');
138
138
  console.log(' ' + chalk.yellow('octomux start'));
139
139
  console.log('');
140
+ console.log(chalk.dim('Finish setup in the dashboard: Settings → Setup (or /setup).'));
140
141
  console.log(chalk.dim('See ONBOARDING.md for the full walkthrough.'));
141
142
  console.log('');
142
143
  });
@@ -0,0 +1,46 @@
1
+ import { getContext } from '../action.js';
2
+ import { outputJson, printTable } from '../format.js';
3
+ export function toTrackerDefaults(row) {
4
+ const cfg = row.config ?? {};
5
+ const str = (v) => typeof v === 'string' && v.length > 0 ? v : undefined;
6
+ return {
7
+ id: row.id,
8
+ kind: row.kind,
9
+ name: row.name,
10
+ enabled: row.enabled,
11
+ base_url: str(cfg.base_url),
12
+ default_project: str(cfg.default_project),
13
+ default_team_key: str(cfg.default_team_key),
14
+ };
15
+ }
16
+ export function registerListIntegrations(program) {
17
+ program
18
+ .command('list-integrations')
19
+ .description('List configured integrations with their tracker defaults (secrets masked). ' +
20
+ 'Use this to resolve the default Jira project / Linear team for a task.')
21
+ .option('--enabled', 'only show enabled integrations')
22
+ .action(async (opts, cmd) => {
23
+ const { client, json } = getContext(cmd);
24
+ let rows = await client.listIntegrations();
25
+ if (opts.enabled)
26
+ rows = rows.filter((r) => r.enabled);
27
+ const defaults = rows.map(toTrackerDefaults);
28
+ if (json) {
29
+ outputJson(defaults);
30
+ return;
31
+ }
32
+ if (defaults.length === 0) {
33
+ console.log('No integrations configured.');
34
+ return;
35
+ }
36
+ printTable([
37
+ { header: 'KIND', width: 10, get: (r) => r.kind },
38
+ { header: 'NAME', width: 22, get: (r) => r.name },
39
+ { header: 'ENABLED', width: 9, get: (r) => (r.enabled ? 'yes' : 'no') },
40
+ {
41
+ header: 'DEFAULT',
42
+ get: (r) => r.default_project ?? r.default_team_key ?? '—',
43
+ },
44
+ ], defaults);
45
+ });
46
+ }
@@ -1,18 +1,36 @@
1
1
  import { getContext } from '../action.js';
2
2
  import { outputJson, success, label } from '../format.js';
3
+ function parseMetadata(raw) {
4
+ if (raw === undefined)
5
+ return undefined;
6
+ let parsed;
7
+ try {
8
+ parsed = JSON.parse(raw);
9
+ }
10
+ catch {
11
+ throw new Error('--metadata is invalid JSON');
12
+ }
13
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
14
+ throw new Error('--metadata must be a JSON object');
15
+ }
16
+ return parsed;
17
+ }
3
18
  export function registerTaskRefAdd(program) {
4
19
  program
5
20
  .command('task-ref-add <id> <integration> <external_id>')
6
- .description('Link an external reference (e.g. Jira ticket) to a task')
21
+ .description('Link an external reference (e.g. Jira ticket, Linear issue) to a task')
7
22
  .option('-u, --url <url>', 'URL for the external item')
8
23
  .option('-t, --title <title>', 'display title for the external item')
24
+ .option('-m, --metadata <json>', 'JSON object with integration-specific metadata')
9
25
  .action(async (id, integration, externalId, opts, cmd) => {
10
26
  const { client, json } = getContext(cmd);
27
+ const metadata = parseMetadata(opts.metadata);
11
28
  const ref = await client.addTaskRef(id, {
12
29
  integration,
13
30
  external_id: externalId,
14
31
  url: opts.url,
15
32
  title: opts.title,
33
+ ...(metadata !== undefined ? { metadata } : {}),
16
34
  });
17
35
  if (json) {
18
36
  outputJson(ref);
package/cli/dist/index.js CHANGED
@@ -26,6 +26,7 @@ import { registerTaskRefRm } from './commands/task-ref-rm.js';
26
26
  import { registerTaskUpdates } from './commands/task-updates.js';
27
27
  import { registerHooksInstall } from './commands/hooks-install.js';
28
28
  import { registerHooksList } from './commands/hooks-list.js';
29
+ import { registerListIntegrations } from './commands/list-integrations.js';
29
30
  import { registerInit } from './commands/init.js';
30
31
  const program = new Command();
31
32
  program
@@ -58,6 +59,7 @@ registerTaskRefRm(program);
58
59
  registerTaskUpdates(program);
59
60
  registerHooksInstall(program);
60
61
  registerHooksList(program);
62
+ registerListIntegrations(program);
61
63
  registerInit(program);
62
64
  program.hook('preAction', (thisCommand) => {
63
65
  const opts = thisCommand.optsWithGlobals();
@@ -1 +1 @@
1
- import{d as a,j as e}from"./vendor-react-DVZ9vYhU.js";import{k as m,s as f}from"./index-Cuel_jco.js";import{c as E,b as R}from"./vendor-router-BNSfXSMI.js";import"./vendor-ui-vLFv-L6M.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-8w_IdZy_.js";function $(){const{name:t}=E(),u=R(),[l,d]=a.useState(""),[c,v]=a.useState(""),[h,x]=a.useState(!1),[j,b]=a.useState(!0),[p,N]=a.useState(null),[o,g]=a.useState(!1),i=a.useRef(""),n=l!==i.current;a.useEffect(()=>{if(!t)return;let s=!1;return m.getAgent(t).then(r=>{s||(d(r.content),v(r.defaultContent),x(r.isCustom),i.current=r.content)}).catch(r=>{s||N(r.message)}).finally(()=>{s||b(!1)}),()=>{s=!0}},[t]);const C=a.useCallback(async()=>{if(!(!t||!n||o)){g(!0);try{await m.saveAgent(t,l),i.current=l,x(!0),f("success","SAVED",`Agent "${t}" saved`)}catch(s){f("error","ERROR",s instanceof Error?s.message:"Failed to save")}finally{g(!1)}}},[t,l,n,o]),y=a.useCallback(async()=>{if(t&&window.confirm(`Reset "${t}" to default? Your customizations will be lost.`))try{await m.resetAgent(t),d(c),i.current=c,x(!1),f("success","RESET",`Agent "${t}" reset to default`)}catch(s){f("error","ERROR",s instanceof Error?s.message:"Failed to reset")}},[t,c]),w=a.useCallback(()=>{n&&!window.confirm("You have unsaved changes. Discard them?")||u("/settings")},[n,u]);return j?e.jsx("div",{className:"flex h-full items-center justify-center",children:e.jsx("span",{className:"text-[#6a6a6a]",children:"Loading..."})}):p?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3",children:[e.jsx("p",{className:"text-red-400",children:p}),e.jsx("button",{onClick:()=>u("/settings"),className:"text-xs text-[#3B82F6] hover:underline",children:"Back to Settings"})]}):e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] px-6 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:w,className:"text-sm text-[#6a6a6a] hover:text-white",children:"←"}),e.jsx("span",{className:"font-mono text-lg font-bold",children:t}),h&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"custom"}),n&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[h&&c&&e.jsx("button",{onClick:y,className:"px-3 py-2 text-xs text-red-400 hover:text-red-300",children:"Reset to Default"}),e.jsx("button",{onClick:C,disabled:!n||o,className:"bg-[#3B82F6] px-4 py-2 text-xs text-white disabled:opacity-50",children:o?"Saving...":"Save"})]})]}),e.jsx("div",{className:"flex-1 p-6",children:e.jsx("textarea",{value:l,onChange:s=>d(s.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{$ as default};
1
+ import{b as a,j as e}from"./vendor-react-Dd26lTa7.js";import{j as m,s as f}from"./index-CghBwA2d.js";import{c as E,b as R}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";function $(){const{name:t}=E(),u=R(),[l,d]=a.useState(""),[c,v]=a.useState(""),[h,x]=a.useState(!1),[j,b]=a.useState(!0),[p,N]=a.useState(null),[o,g]=a.useState(!1),i=a.useRef(""),n=l!==i.current;a.useEffect(()=>{if(!t)return;let s=!1;return m.getAgent(t).then(r=>{s||(d(r.content),v(r.defaultContent),x(r.isCustom),i.current=r.content)}).catch(r=>{s||N(r.message)}).finally(()=>{s||b(!1)}),()=>{s=!0}},[t]);const C=a.useCallback(async()=>{if(!(!t||!n||o)){g(!0);try{await m.saveAgent(t,l),i.current=l,x(!0),f("success","SAVED",`Agent "${t}" saved`)}catch(s){f("error","ERROR",s instanceof Error?s.message:"Failed to save")}finally{g(!1)}}},[t,l,n,o]),y=a.useCallback(async()=>{if(t&&window.confirm(`Reset "${t}" to default? Your customizations will be lost.`))try{await m.resetAgent(t),d(c),i.current=c,x(!1),f("success","RESET",`Agent "${t}" reset to default`)}catch(s){f("error","ERROR",s instanceof Error?s.message:"Failed to reset")}},[t,c]),w=a.useCallback(()=>{n&&!window.confirm("You have unsaved changes. Discard them?")||u("/settings")},[n,u]);return j?e.jsx("div",{className:"flex h-full items-center justify-center",children:e.jsx("span",{className:"text-[#6a6a6a]",children:"Loading..."})}):p?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3",children:[e.jsx("p",{className:"text-red-400",children:p}),e.jsx("button",{onClick:()=>u("/settings"),className:"text-xs text-[#3B82F6] hover:underline",children:"Back to Settings"})]}):e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] px-6 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:w,className:"text-sm text-[#6a6a6a] hover:text-white",children:"←"}),e.jsx("span",{className:"font-mono text-lg font-bold",children:t}),h&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"custom"}),n&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[h&&c&&e.jsx("button",{onClick:y,className:"px-3 py-2 text-xs text-red-400 hover:text-red-300",children:"Reset to Default"}),e.jsx("button",{onClick:C,disabled:!n||o,className:"bg-[#3B82F6] px-4 py-2 text-xs text-white disabled:opacity-50",children:o?"Saving...":"Save"})]})]}),e.jsx("div",{className:"flex-1 p-6",children:e.jsx("textarea",{value:l,onChange:s=>d(s.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{$ as default};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-Cuel_jco.js","assets/vendor-react-DVZ9vYhU.js","assets/vendor-router-BNSfXSMI.js","assets/vendor-ui-vLFv-L6M.js","assets/vendor-xterm-DvXGiZvM.js","assets/vendor-xterm-DYP7pi_n.css","assets/vendor-monaco-8w_IdZy_.js","assets/index-Dkw-hNxU.css"])))=>i.map(i=>d[i]);
2
- import{_ as o}from"./index-Cuel_jco.js";import{d as r,j as e}from"./vendor-react-DVZ9vYhU.js";import{c as m}from"./vendor-router-BNSfXSMI.js";import"./vendor-ui-vLFv-L6M.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-8w_IdZy_.js";const d=r.lazy(()=>o(()=>import("./index-Cuel_jco.js").then(t=>t.T),__vite__mapDeps([0,1,2,3,4,5,6,7])).then(t=>({default:t.TerminalView})));function g(){const{id:t}=m(),[a,i]=r.useState(null),[l,c]=r.useState(null);return r.useEffect(()=>{if(!t)return;let n=!1;return fetch(`/api/chats/${t}`).then(s=>s.ok?s.json():Promise.reject(new Error(`${s.status}`))).then(s=>{n||i(s)}).catch(s=>{n||c(s.message)}),()=>{n=!0}},[t]),l?e.jsxs("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:["Chat not found (",l,")"]}):a?e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center gap-3 border-b border-border px-6 py-3",children:[e.jsx("span",{className:"text-[10px] font-bold uppercase tracking-wider text-[#6a6a6a]",children:"// CHAT"}),e.jsx("span",{className:"text-sm font-medium text-white",children:a.label}),a.agent&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-mono",style:{backgroundColor:"rgba(245, 158, 11, 0.12)",borderColor:"rgba(245, 158, 11, 0.4)",color:"#F59E0B"},title:`Running as agent: ${a.agent}`,children:["🤖 ",a.agent]}),a.status==="running"&&e.jsx("span",{className:"h-2 w-2 animate-pulse bg-[#22C55E]"})]}),e.jsx("div",{className:"min-h-0 flex-1",children:e.jsx(r.Suspense,{fallback:e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading terminal..."}),children:e.jsx(d,{wsUrl:`/ws/terminal/chat/${a.id}`,visible:!0})})})]}):e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading..."})}export{g as default};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-CghBwA2d.js","assets/vendor-react-Dd26lTa7.js","assets/vendor-router-yJbofmar.js","assets/vendor-ui-ChI1tM4e.js","assets/vendor-xterm-DvXGiZvM.js","assets/vendor-xterm-DYP7pi_n.css","assets/vendor-monaco-CdNyTACs.js","assets/index-D1KcUNra.css"])))=>i.map(i=>d[i]);
2
+ import{_ as o}from"./index-CghBwA2d.js";import{b as r,j as e}from"./vendor-react-Dd26lTa7.js";import{c as m}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";const d=r.lazy(()=>o(()=>import("./index-CghBwA2d.js").then(t=>t.i),__vite__mapDeps([0,1,2,3,4,5,6,7])).then(t=>({default:t.TerminalView})));function g(){const{id:t}=m(),[a,i]=r.useState(null),[l,c]=r.useState(null);return r.useEffect(()=>{if(!t)return;let n=!1;return fetch(`/api/chats/${t}`).then(s=>s.ok?s.json():Promise.reject(new Error(`${s.status}`))).then(s=>{n||i(s)}).catch(s=>{n||c(s.message)}),()=>{n=!0}},[t]),l?e.jsxs("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:["Chat not found (",l,")"]}):a?e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center gap-3 border-b border-border px-6 py-3",children:[e.jsx("span",{className:"text-[10px] font-bold uppercase tracking-wider text-[#6a6a6a]",children:"// CHAT"}),e.jsx("span",{className:"text-sm font-medium text-white",children:a.label}),a.agent&&e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[10px] font-mono",style:{backgroundColor:"rgba(245, 158, 11, 0.12)",borderColor:"rgba(245, 158, 11, 0.4)",color:"#F59E0B"},title:`Running as agent: ${a.agent}`,children:["🤖 ",a.agent]}),a.status==="running"&&e.jsx("span",{className:"h-2 w-2 animate-pulse bg-[#22C55E]"})]}),e.jsx("div",{className:"min-h-0 flex-1",children:e.jsx(r.Suspense,{fallback:e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading terminal..."}),children:e.jsx(d,{wsUrl:`/ws/terminal/chat/${a.id}`,visible:!0})})})]}):e.jsx("div",{className:"flex h-full items-center justify-center text-[#6a6a6a]",children:"Loading..."})}export{g as default};
@@ -0,0 +1 @@
1
+ import{b as r,j as e}from"./vendor-react-Dd26lTa7.js";import{a as B,j as u,g as $,S as J,R as H,s as O,h as X}from"./index-CghBwA2d.js";import"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";function Z({content:s,label:o="More information",className:m}){const x=r.useId(),[g,c]=r.useState(!1);return e.jsxs("span",{className:`relative inline-flex ${m??""}`,children:[e.jsx("button",{type:"button","aria-label":o,"aria-describedby":g?x:void 0,className:"focus-ring flex size-4 items-center justify-center rounded-full border border-glass-edge text-[10px] font-semibold leading-none text-[#8a8a8a] transition-colors hover:border-[#60a5fa] hover:text-[#60a5fa]",onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),onFocus:()=>c(!0),onBlur:()=>c(!1),children:"i"}),g&&e.jsx("span",{role:"tooltip",id:x,className:"absolute left-1/2 top-full z-50 mt-1.5 w-64 -translate-x-1/2 rounded-md border border-glass-edge bg-popover px-3 py-2 text-xs leading-relaxed text-[#d4d4dc] shadow-lg",children:s})]})}const ee=[{key:"backlog",label:"Backlog"},{key:"planned",label:"Planned"},{key:"in_progress",label:"In Progress"},{key:"human_review",label:"Human Review"},{key:"pr",label:"PR"},{key:"done",label:"Done"}],F={background:"rgba(255,255,255,0.06)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:6,color:"#e2e2e7",fontSize:13,padding:"6px 10px",width:"100%",outline:"none"},A={display:"block",fontSize:11,fontWeight:600,color:"#8a8a8a",textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:4};function q({initial:s,onSubmit:o,onCancel:m,submitLabel:x="Save",nameInitial:g=""}){const[c,i]=r.useState(g),[d,h]=r.useState((s==null?void 0:s.base_url)??""),[b,N]=r.useState((s==null?void 0:s.email)??""),[y,P]=r.useState((s==null?void 0:s.api_token)??""),[C,w]=r.useState((s==null?void 0:s.default_project)??""),[R,I]=r.useState((s==null?void 0:s.status_map)??{}),[p,E]=r.useState(!1),[_,f]=r.useState(null);async function L(l){if(l.preventDefault(),f(null),!c.trim()){f("Name is required");return}if(!d.trim()){f("Base URL is required");return}if(!b.trim()){f("Email is required");return}if(!y.trim()){f("API token is required");return}E(!0);try{await o({base_url:d.trim(),email:b.trim(),api_token:y,default_project:C.trim()||void 0,status_map:R},c.trim())}catch(T){f(T instanceof Error?T.message:"Failed to save")}finally{E(!1)}}return e.jsxs("form",{onSubmit:L,style:{display:"flex",flexDirection:"column",gap:16},children:[e.jsxs("div",{children:[e.jsx("label",{style:A,children:"Instance name"}),e.jsx("input",{style:F,value:c,onChange:l=>i(l.target.value),placeholder:"e.g. My Jira",required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{style:A,children:"Base URL"}),e.jsx("input",{style:F,type:"url",value:d,onChange:l=>h(l.target.value),placeholder:"https://acme.atlassian.net",required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{style:A,children:"Email"}),e.jsx("input",{style:F,type:"email",value:b,onChange:l=>N(l.target.value),placeholder:"you@company.com",required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{style:A,children:"API Token"}),e.jsx("input",{style:F,type:"password",value:y,onChange:l=>P(l.target.value),placeholder:y==="••••"?"Leave as-is to keep stored token":"Atlassian API token",autoComplete:"off"}),e.jsxs("p",{style:{fontSize:11,color:"#8a8a8a",marginTop:4},children:["Generate at Atlassian account settings → Security → API tokens. Use"," ",e.jsxs("code",{style:{fontFamily:"monospace"},children:["$","{env:MY_VAR}"]})," to read from an environment variable."]})]}),e.jsxs("div",{children:[e.jsx("label",{style:A,children:"Default project key (optional)"}),e.jsx("input",{style:F,value:C,onChange:l=>w(l.target.value),placeholder:"e.g. PROJ"})]}),e.jsxs("div",{children:[e.jsx("label",{style:{...A,marginBottom:8},children:"Workflow → Jira transition ID map"}),e.jsx("p",{style:{fontSize:11,color:"#8a8a8a",marginBottom:8},children:"Map each octomux workflow status to a Jira transition ID (numeric). Leave blank to skip."}),e.jsx("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8},children:ee.map(({key:l,label:T})=>e.jsxs("div",{children:[e.jsx("label",{style:{...A,marginBottom:2},children:T}),e.jsx("input",{style:F,value:R[l]??"",onChange:D=>I(n=>{const j={...n};return D.target.value?j[l]=D.target.value:delete j[l],j}),placeholder:"Transition ID"})]},l))})]}),_&&e.jsx("p",{style:{fontSize:12,color:"#f87171",margin:0},children:_}),e.jsxs("div",{style:{display:"flex",gap:8,justifyContent:"flex-end",paddingTop:4},children:[e.jsx("button",{type:"button",onClick:m,disabled:p,style:{padding:"6px 14px",borderRadius:6,border:"1px solid rgba(255,255,255,0.15)",background:"transparent",color:"#b5b5bd",fontSize:13,cursor:"pointer"},children:"Cancel"}),e.jsx("button",{type:"submit",disabled:p,style:{padding:"6px 14px",borderRadius:6,border:"none",background:p?"rgba(59,130,246,0.5)":"#3b82f6",color:"white",fontSize:13,cursor:p?"not-allowed":"pointer"},children:p?"Saving…":x})]})]})}function te(s){const o=s.config;return{base_url:String(o.base_url??""),email:String(o.email??""),api_token:String(o.api_token??""),default_project:o.default_project?String(o.default_project):void 0,status_map:o.status_map??{}}}const se=[{key:"backlog",label:"Backlog"},{key:"planned",label:"Planned"},{key:"in_progress",label:"In Progress"},{key:"human_review",label:"Human Review"},{key:"pr",label:"PR"},{key:"done",label:"Done"}];function G({initial:s,prefillTeams:o,onSubmit:m,onCancel:x,submitLabel:g="Save",nameInitial:c=""}){const[i,d]=r.useState(c),[h,b]=r.useState((s==null?void 0:s.api_key)??""),[N,y]=r.useState((s==null?void 0:s.default_team_key)??""),[P,C]=r.useState((s==null?void 0:s.status_map_by_team)??{}),[w,R]=r.useState(o??[]),[I,p]=r.useState(!1),[E,_]=r.useState(null),[f,L]=r.useState(!1);async function l(){_(null),p(!0);try{const n=await u.prefillLinear(h);R(n.teams),C(n.status_map_by_team),!N&&n.default_team_suggestion&&y(n.default_team_suggestion)}catch(n){_(n.message)}finally{p(!1)}}function T(n,j,k){C(v=>{const z={...v[n]??{}};return k?z[j]=k:delete z[j],{...v,[n]:z}})}async function D(n){n.preventDefault(),L(!0);try{await m({api_key:h.trim(),default_team_key:N.trim()||void 0,status_map_by_team:P},i.trim()||"Linear")}finally{L(!1)}}return e.jsxs("form",{onSubmit:D,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"linear-name",className:"mb-1 block text-xs text-[#b5b5bd]",children:"Integration name"}),e.jsx("input",{id:"linear-name",type:"text",value:i,onChange:n=>d(n.target.value),placeholder:"Linear",className:"w-full border border-glass-edge bg-[#0B0C0F] px-3 py-2 text-sm text-white outline-none focus:border-[#3B82F6]"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"linear-api-key",className:"mb-1 block text-xs text-[#b5b5bd]",children:"API key"}),e.jsx("input",{id:"linear-api-key",type:"password",value:h,onChange:n=>b(n.target.value),placeholder:"lin_api_...",className:"w-full border border-glass-edge bg-[#0B0C0F] px-3 py-2 font-mono text-sm text-white outline-none focus:border-[#3B82F6]"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(B,{type:"button",size:"sm",variant:"outline",disabled:!h||I,onClick:l,children:I?"Connecting…":"Connect & auto-detect teams"}),E&&e.jsx("span",{className:"text-xs text-red-400",children:E})]}),w.length>0&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-xs text-[#b5b5bd]",children:"Default team"}),e.jsx("select",{value:N,onChange:n=>y(n.target.value),className:"w-full border border-glass-edge bg-[#0B0C0F] px-3 py-2 text-sm text-white outline-none focus:border-[#3B82F6]",children:w.map(n=>e.jsxs("option",{value:n.key,children:[n.name," (",n.key,")"]},n.key))})]}),w.map(n=>{const j=P[n.key]??{};return e.jsxs("details",{open:n.key===N,children:[e.jsxs("summary",{className:"cursor-pointer py-1 text-sm text-white",children:[n.name," (",n.key,")"]}),e.jsx("div",{className:"mt-2 space-y-2 pl-3",children:se.map(k=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"w-32 text-xs text-[#b5b5bd]",children:k.label}),e.jsxs("select",{value:j[k.key]??"",onChange:v=>T(n.key,k.key,v.target.value||void 0),className:"flex-1 border border-glass-edge bg-[#0B0C0F] px-2 py-1 text-xs text-white outline-none focus:border-[#3B82F6]",children:[e.jsx("option",{value:"",children:"— unmapped —"}),n.states.map(v=>e.jsx("option",{value:v.id,children:v.name},v.id))]})]},k.key))})]},n.key)})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(B,{type:"button",size:"sm",variant:"outline",onClick:x,children:"Cancel"}),e.jsx(B,{type:"submit",size:"sm",disabled:f||!h,children:f?"Saving…":g})]})]})}function ae(s){return s.config}function Y(s){return s==="jira"?"J":s==="linear"?"L":s.charAt(0).toUpperCase()}const K={"jira-status":{label:"jira-status hook",tooltip:"Runs when a task’s workflow column changes and transitions the linked Jira issue via the status→transition-ID map in ~/.octomux/hooks. Needs JIRA_BASE_URL, JIRA_EMAIL and JIRA_TOKEN. This is an alternative to the Jira API integration’s automatic transitions — use one or the other to avoid double-firing."}};function U(s){var o;return((o=K[s])==null?void 0:o.label)??s}function ne({integration:s,onEdit:o,onDelete:m,onToggle:x,onTest:g,testResult:c,testing:i}){return e.jsxs("div",{className:"flex items-center justify-between py-3",style:H,"data-testid":`integration-row-${s.id}`,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"flex size-8 items-center justify-center rounded-lg bg-primary/20 text-sm font-bold text-primary",children:Y(s.kind)}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:s.name}),e.jsx("p",{className:"text-xs capitalize text-muted-soft",children:s.kind})]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[c&&e.jsxs("span",{className:"text-xs",style:{color:c.ok?"var(--color-success)":"var(--destructive)"},children:[c.ok?"✓":"✗"," ",c.message]}),e.jsx("button",{type:"button",className:"focus-ring text-xs text-muted-soft transition-colors hover:text-foreground",onClick:g,disabled:i,children:i?"Testing…":"Test"}),e.jsx("button",{type:"button",className:"focus-ring text-xs text-muted-soft transition-colors hover:text-foreground",onClick:o,children:"Edit"}),e.jsx("button",{type:"button",className:"focus-ring text-xs text-destructive transition-colors hover:text-destructive/80",onClick:m,children:"Delete"}),e.jsx(X,{checked:s.enabled,onChange:x})]})]})}function M({title:s,onClose:o,children:m}){return e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:x=>{x.target===x.currentTarget&&o()},children:e.jsxs("div",{className:"relative max-h-[90vh] w-full max-w-lg overflow-y-auto rounded-2xl border border-glass-edge bg-popover p-6",children:[e.jsxs("div",{className:"mb-5 flex items-center justify-between",children:[e.jsx("h2",{className:"text-sm font-semibold text-foreground",children:s}),e.jsx("button",{type:"button",onClick:o,className:"text-muted-soft hover:text-foreground","aria-label":"Close",children:"✕"})]}),m]})})}function ue(){const[s,o]=r.useState([]),[m,x]=r.useState([]),[g,c]=r.useState(!0),[i,d]=r.useState(null),[h,b]=r.useState(null),[N,y]=r.useState({}),[P,C]=r.useState({}),[w,R]=r.useState([]),[I,p]=r.useState(null),[E,_]=r.useState(""),[f,L]=r.useState(!1),l=r.useCallback(async()=>{try{const[t,a,S,W]=await Promise.all([u.listProviders(),u.listIntegrations(),u.listHookTemplates().catch(()=>[]),u.getSettings().catch(()=>null)]);o(t),x(a),R(S),W&&_(W.defaultTracker??"")}catch{}finally{c(!1)}},[]);async function T(t){p(t);try{await u.installHookTemplate(t),O("success","HOOKS",`Installed ${U(t)}`),l()}catch(a){O("error","HOOKS",a instanceof Error?a.message:"Install failed")}finally{p(null)}}async function D(t){_(t),L(!0);try{await u.updateSettings({defaultTracker:t||void 0}),O("success","INTEGRATIONS","Primary tracker saved")}catch(a){O("error","INTEGRATIONS",a instanceof Error?a.message:"Save failed")}finally{L(!1)}}r.useEffect(()=>{l()},[l]);async function n(t,a){await u.createIntegration("jira",a,t),d(null),l()}async function j(t,a,S){await u.updateIntegration(t,{name:S,config:a}),d(null),l()}async function k(t,a){await u.createIntegration("linear",a,t),d(null),l()}async function v(t,a,S){await u.updateIntegration(t,{name:S,config:a}),d(null),l()}async function z(t){await u.deleteIntegration(t),b(null),l()}async function V(t,a){await u.updateIntegration(t,{enabled:a}),l()}async function Q(t){C(a=>({...a,[t]:!0}));try{const a=await u.testIntegration(t);y(S=>({...S,[t]:a}))}catch(a){y(S=>({...S,[t]:{ok:!1,message:a instanceof Error?a.message:"Test failed"}}))}finally{C(a=>({...a,[t]:!1}))}}return g?e.jsx($,{title:"Integrations",description:"Connect Octomux to external systems",children:e.jsx("p",{className:"text-sm text-muted-soft",children:"Loading integrations…"})}):e.jsxs(e.Fragment,{children:[e.jsxs($,{title:"Integrations",description:"Workflow column changes fire to enabled integrations",children:[e.jsx(J,{id:"providers",title:"Available providers",children:s.length===0?e.jsx("p",{className:"py-2 text-xs text-muted-soft",children:"No providers registered."}):s.map(t=>e.jsxs("div",{className:"flex items-center justify-between py-3",style:H,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"flex size-8 items-center justify-center rounded-lg bg-primary/20 text-sm font-bold text-primary",children:Y(t.kind)}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:t.displayName}),e.jsxs("p",{className:"text-xs text-muted-soft",children:["Events: ",t.events.join(", ")]})]})]}),e.jsxs(B,{size:"sm",onClick:()=>{t.kind==="jira"?d({kind:"create-jira"}):t.kind==="linear"&&d({kind:"create-linear"})},children:["Add ",t.displayName]})]},t.kind))}),e.jsx(J,{id:"configured",title:"Configured",count:m.length,children:m.length===0?e.jsx("p",{className:"py-2 text-xs text-muted-soft",children:"No integrations configured. Add one above."}):m.map(t=>e.jsx(ne,{integration:t,onEdit:()=>{t.kind==="jira"?d({kind:"edit-jira",integration:t}):t.kind==="linear"&&d({kind:"edit-linear",integration:t})},onDelete:()=>b(t.id),onToggle:a=>void V(t.id,a),onTest:()=>void Q(t.id),testResult:N[t.id]??null,testing:P[t.id]??!1},t.id))}),e.jsx(J,{id:"primary-tracker",title:"Primary tracker",children:e.jsxs("div",{className:"flex items-center justify-between py-3",style:H,"data-testid":"primary-tracker-row",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:"Default tracker for new tasks"}),e.jsx("p",{className:"text-xs text-muted-soft",children:"Used by the create-task flow when more than one tracker is configured."})]}),e.jsxs("select",{value:E,disabled:f,onChange:t=>void D(t.target.value),className:"border border-glass-edge bg-[#0B0C0F] px-3 py-2 text-sm text-white outline-none focus:border-[#3B82F6]","data-testid":"primary-tracker-select","aria-label":"Primary tracker",children:[e.jsx("option",{value:"",children:"— none —"}),e.jsx("option",{value:"linear",children:"Linear"}),e.jsx("option",{value:"jira",children:"Jira"})]})]})}),e.jsx(J,{id:"workflow-hooks",title:"Workflow hooks",children:w.length===0?e.jsx("p",{className:"py-2 text-xs text-muted-soft",children:"No hook templates available."}):w.map(t=>{var a;return e.jsxs("div",{className:"flex items-center justify-between py-3",style:H,"data-testid":`hook-template-${t.id}`,children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:U(t.id)}),((a=K[t.id])==null?void 0:a.tooltip)&&e.jsx(Z,{content:K[t.id].tooltip,label:`About ${U(t.id)}`})]}),t.installed?e.jsx("span",{className:"text-xs font-medium text-[#22C55E]",children:"Installed"}):e.jsx(B,{size:"sm",variant:"outline",disabled:I===t.id,onClick:()=>void T(t.id),"data-testid":`hook-install-${t.id}`,children:I===t.id?"Installing…":"Install"})]},t.id)})})]}),(i==null?void 0:i.kind)==="create-jira"&&e.jsx(M,{title:"Add Jira integration",onClose:()=>d(null),children:e.jsx(q,{onSubmit:n,onCancel:()=>d(null),submitLabel:"Create"})}),(i==null?void 0:i.kind)==="edit-jira"&&e.jsx(M,{title:"Edit Jira integration",onClose:()=>d(null),children:e.jsx(q,{initial:te(i.integration),nameInitial:i.integration.name,onSubmit:(t,a)=>j(i.integration.id,t,a),onCancel:()=>d(null),submitLabel:"Save changes"})}),(i==null?void 0:i.kind)==="create-linear"&&e.jsx(M,{title:"Add Linear integration",onClose:()=>d(null),children:e.jsx(G,{onSubmit:k,onCancel:()=>d(null),submitLabel:"Create"})}),(i==null?void 0:i.kind)==="edit-linear"&&e.jsx(M,{title:"Edit Linear integration",onClose:()=>d(null),children:e.jsx(G,{initial:ae(i.integration),nameInitial:i.integration.name,onSubmit:(t,a)=>v(i.integration.id,t,a),onCancel:()=>d(null),submitLabel:"Save changes"})}),h&&e.jsxs(M,{title:"Delete integration",onClose:()=>b(null),children:[e.jsx("p",{className:"mb-4 text-sm text-muted-foreground",children:"Are you sure you want to delete this integration? This action cannot be undone."}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(B,{variant:"outline",size:"sm",onClick:()=>b(null),children:"Cancel"}),e.jsx(B,{variant:"destructive",size:"sm",onClick:()=>void z(h),children:"Delete"})]})]})]})}export{ue as default};
@@ -0,0 +1 @@
1
+ import{j as s,b as r}from"./vendor-react-Dd26lTa7.js";import{C as U,k as T,B as V,c as q,e as J,d as K,a as $,j as P,t as _,l as O,u as W,T as Q,D as Y,b as X}from"./index-CghBwA2d.js";import{c as Z}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";function ee(t){const e=t.match(/^(.+?[.!?])(\s|$)/);return e?e[1]:t}function te({children:t}){return s.jsxs("span",{className:"shrink-0 text-[11px] opacity-70",children:["· ",t]})}function se({walkthrough:t}){const e=t.global??{},n=[];if(e.risk&&n.push(`risk: ${e.risk}`),e.effort!==void 0&&n.push(`effort ${e.effort}/5`),e.relevant_tests&&n.push(`tests: ${e.relevant_tests}`),e.security_concerns&&n.push(`security: ${e.security_concerns}`),e.key_review_points&&e.key_review_points.length>0&&n.push(`${e.key_review_points.length} key points`),e.ticket_compliance&&e.ticket_compliance.length>0)for(const o of e.ticket_compliance)n.push(`${o.ticket} ${o.status==="compliant"?"✓":o.status==="partially"?"~":"✗"}`);return e.summary||n.length>0||e.type?s.jsx("section",{"data-testid":"walkthrough-header",className:"border-b border-glass-edge bg-glass-l1 px-4 py-1.5",children:s.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[s.jsx("span",{className:"shrink-0 font-medium",children:"Walkthrough"}),e.summary&&s.jsxs("span",{className:"min-w-0 flex-1 truncate",title:e.summary,children:["· ",ee(e.summary)]}),n.length>0&&s.jsx(te,{children:n.join(" · ")})]})}):null}const ne="Other";function A(t,e){const n=new Set(t),i=new Set,o=[];for(const c of(e==null?void 0:e.groups)??[]){const x=(c.files??[]).filter(d=>n.has(d.path));if(x.length!==0){for(const d of x)i.add(d.path);o.push({name:c.name,summary:c.summary,files:x})}}const h=t.filter(c=>!i.has(c));return h.length>0&&o.push({name:ne,files:h.map(c=>({path:c}))}),o}function ae(t){return t.flatMap(e=>e.files.map(n=>n.path))}function re(t){const e=new Map;for(const n of t){const i=e.get(n.file_path)??{open:0,stale:0,hasSerious:!1};n.status==="stale"?i.stale+=1:n.status!=="rejected"&&n.status!=="published"&&!n.auto_resolved_at&&(i.open+=1,(n.severity==="critical"||n.severity==="issue")&&(i.hasSerious=!0)),e.set(n.file_path,i)}return e}function le(t){const e=t.lastIndexOf("/");return e===-1?t:t.slice(e+1)}function ie({file:t,selected:e,counts:n,reviewedFiles:i,onToggleReviewed:o,onSelect:h}){const c=(n==null?void 0:n.open)??0,x=(n==null?void 0:n.stale)??0,d=!!(n!=null&&n.hasSerious),u=i.has(t.path);return s.jsxs("li",{"data-testid":`review-file-row-${t.path}`,"data-selected":e?"true":void 0,"data-reviewed":u?"true":"false",className:T("flex items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-glass-l2/40",e&&"bg-glass-l2/60","data-[reviewed=true]:opacity-60"),role:"treeitem","aria-selected":e,children:[s.jsx("input",{type:"checkbox",checked:u,"data-testid":`review-toggle-${t.path}`,"aria-label":u?`Unmark ${t.path} reviewed`:`Mark ${t.path} reviewed`,onClick:g=>g.stopPropagation(),onChange:g=>{g.stopPropagation(),o(t.path,u)},className:"h-3.5 w-3.5 shrink-0 cursor-pointer"}),s.jsxs("button",{type:"button",onClick:()=>h(t.path),className:"flex min-w-0 flex-1 items-center gap-2 text-left",tabIndex:e?0:-1,children:[s.jsx("code",{className:"min-w-0 flex-1 truncate font-mono text-foreground",title:t.path,children:le(t.path)}),t.label&&s.jsx(V,{variant:"outline",className:"shrink-0 px-1 text-[10px]",children:t.label})]}),t.summary&&s.jsxs(q,{children:[s.jsx(J,{render:s.jsx("span",{}),nativeButton:!1,"aria-label":`Summary for ${t.path}`,className:"shrink-0 text-[10px] text-muted-foreground hover:text-foreground",onClick:g=>g.stopPropagation(),children:"info"}),s.jsx(K,{className:"w-72 text-xs",children:t.summary})]}),s.jsxs("div",{className:"flex shrink-0 flex-col items-end gap-1",children:[c>0&&s.jsx("span",{"data-testid":`comment-count-${t.path}`,"data-tone":d?"serious":"muted",className:T("inline-flex min-w-[1.25rem] items-center justify-center rounded-full px-1.5 py-0.5 text-[10px] font-medium",d?"bg-destructive/20 text-destructive":"bg-glass-l2 text-muted-foreground"),children:c}),x>0&&s.jsxs("span",{"data-testid":`stale-count-${t.path}`,className:"inline-flex items-center rounded-full bg-warning/15 px-1.5 py-0.5 text-[10px] font-medium text-warning",children:["stale: ",x]})]})]})}function oe({files:t,walkthrough:e,comments:n,selectedPath:i,reviewedFiles:o,onToggleReviewed:h,onSelect:c}){const x=r.useMemo(()=>A(t,e),[t,e]),d=r.useMemo(()=>re(n),[n]),[u,g]=r.useState(new Set);function k(l){g(p=>{const m=new Set(p);return m.has(l)?m.delete(l):m.add(l),m})}const v=r.useCallback(l=>{if(!["ArrowDown","ArrowUp","j","k"].includes(l.key))return;const p=x.flatMap(C=>C.files.map(b=>b.path));if(p.length===0)return;const m=i?p.indexOf(i):-1,R=l.key==="ArrowDown"||l.key==="j"?1:-1,N=m===-1?0:(m+R+p.length)%p.length,S=p[N];S&&(l.preventDefault(),c(S))},[x,i,c]);return x.length===0?s.jsx("div",{className:"p-4 text-xs text-muted-foreground","data-testid":"review-file-tree-empty",children:"No files in diff"}):s.jsx("nav",{"data-testid":"review-file-tree",role:"tree",className:"flex h-full min-h-0 flex-col overflow-y-auto",onKeyDown:v,children:x.map(l=>{const p=!u.has(l.name);return s.jsxs("section",{role:"group","data-testid":`review-file-group-${l.name}`,className:"border-b border-glass-edge/60",children:[s.jsxs("button",{type:"button",onClick:()=>k(l.name),className:"flex w-full items-center gap-2 overflow-hidden px-3 py-2 text-left text-xs font-semibold hover:bg-glass-l2/40","aria-expanded":p,role:"treeitem",title:l.name,children:[s.jsx(U,{"aria-hidden":!0,className:T("shrink-0",p?"transition-transform":"-rotate-90 transition-transform")}),s.jsx("span",{className:"min-w-0 flex-1 truncate",children:l.name}),s.jsx("span",{className:"shrink-0 text-[10px] font-normal text-muted-foreground",children:l.files.length})]}),p&&l.summary&&s.jsx("div",{className:"line-clamp-1 px-3 pb-1 text-[11px] text-muted-foreground",title:l.summary,children:l.summary}),p&&s.jsx("ul",{children:l.files.map(m=>s.jsx(ie,{file:m,selected:i===m.path,counts:d.get(m.path),reviewedFiles:o,onToggleReviewed:h,onSelect:c},m.path))})]},l.name)})})}const ce=[{value:"COMMENT",label:"Comment"},{value:"APPROVE",label:"Approve"},{value:"REQUEST_CHANGES",label:"Request changes"}];function de({taskId:t,prTitle:e,prNumber:n,prUrl:i,acceptedCount:o,draftCount:h,staleCount:c,reviewedDone:x,reviewedTotal:d,totalCommentsCount:u,showCommentsPanel:g,onToggleCommentsPanel:k,isRunning:v,onPublished:l,onReRun:p}){const[m,R]=r.useState("COMMENT"),[N,S]=r.useState(!1),[C,b]=r.useState(!1);async function I(){if(o!==0){S(!0);try{await P.publishReview(t,{verdict:m}),_.success("Review published to GitHub"),l()}catch(w){_.error(`Publish failed: ${w.message}`)}finally{S(!1)}}}async function E(){b(!0);try{await P.requestReReview(t),_.success("Re-review started"),p()}catch(w){_.error(`Re-run failed: ${w.message}`)}finally{b(!1)}}return s.jsxs("div",{className:"sticky top-0 z-10 flex items-center gap-3 border-b border-glass-edge bg-glass-l2 px-6 py-2 backdrop-blur-sm",children:[s.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[s.jsx("span",{className:"truncate text-sm font-semibold",title:e,children:e}),s.jsxs("span",{className:"shrink-0 text-xs text-muted-foreground",children:["#",n]}),i&&s.jsx("a",{href:i,target:"_blank",rel:"noreferrer",className:"shrink-0 text-xs text-blue-400 hover:underline",children:"GitHub"})]}),s.jsxs("span",{className:"text-xs text-muted-foreground",children:[o," accepted · ",h," drafts",c>0&&` · ${c} stale`]}),d>0&&s.jsxs("span",{"data-testid":"pr-review-progress",className:"shrink-0 text-xs text-muted-foreground","aria-label":`${x} of ${d} files reviewed`,children:[x,"/",d," reviewed"]}),s.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[s.jsxs($,{variant:"outline",size:"sm","data-testid":"comments-toggle","data-active":g?"true":void 0,className:g?"border-primary/40 bg-primary/15 text-primary":void 0,onClick:k,children:["Comments (",u,")"]}),s.jsx($,{variant:"outline",size:"sm",onClick:E,disabled:v||C,children:C?"Starting…":v?"Running…":"Re-run review"}),s.jsx("select",{value:m,onChange:w=>R(w.target.value),className:"h-7 rounded-md border border-glass-edge bg-glass-l1 px-2 text-xs text-foreground outline-none focus:border-ring","aria-label":"Review verdict",children:ce.map(w=>s.jsx("option",{value:w.value,children:w.label},w.value))}),s.jsx($,{size:"sm",onClick:I,disabled:o===0||N,children:N?"Publishing…":"Publish review"})]})]})}function ue({taskId:t,currentSha:e,onRefresh:n}){const[i,o]=r.useState(null),[h,c]=r.useState(!1);if(r.useEffect(()=>O(d=>{const u=d;!u.payload.taskId||u.payload.taskId!==t||(u.type==="review:head-advanced"&&u.payload.newHeadSha&&o(u.payload.newHeadSha),u.type==="review:drafts-ready"&&(o(null),n()))}),[t,n]),r.useEffect(()=>{i&&i===e&&o(null)},[i,e]),!i)return null;async function x(){c(!0);try{await P.requestReReview(t),_.success("Incremental re-review started")}catch(d){_.error(`Re-run failed: ${d.message}`)}finally{c(!1)}}return s.jsxs("div",{className:"flex items-center gap-3 bg-yellow-900/30 border-b border-yellow-600 px-6 py-2 text-sm text-yellow-300",children:[s.jsxs("span",{children:["PR head advanced to ",s.jsx("code",{className:"font-mono text-xs",children:i.slice(0,8)})]}),s.jsx($,{variant:"outline",size:"xs",onClick:x,disabled:h,className:"border-yellow-600 text-yellow-300 hover:bg-yellow-900/50",children:h?"Starting…":"Re-run incremental review"}),s.jsx($,{variant:"ghost",size:"xs",onClick:()=>o(null),className:"ml-auto text-yellow-400",children:"Dismiss"})]})}const H="octomux:review:comments-panel-open";function me(){if(typeof window>"u")return!1;try{const t=localStorage.getItem(H);if(t!==null)return t==="true"}catch{}return window.innerWidth>=1440}function we(){var M;const{id:t}=Z(),[e,n]=r.useState(null),[i,o]=r.useState(null),[h,c]=r.useState([]),[x,d]=r.useState(null),[u,g]=r.useState(me),k=r.useRef(null);r.useEffect(()=>{try{localStorage.setItem(H,String(u))}catch{}},[u]);const v=r.useCallback(()=>{t&&P.getReviewDetail(t).then(n).catch(a=>o(a.message))},[t]);r.useEffect(()=>{v()},[v]),r.useEffect(()=>{if(t)return O(a=>{const f=a;!("taskId"in f.payload)||f.payload.taskId!==t||(f.type==="review:drafts-ready"||f.type==="review:published")&&v()})},[t,v]);const l=W(t),[p,m]=r.useState(new Set),R=r.useCallback(async(a,f)=>{m(j=>{const y=new Set(j);return f?y.delete(a):y.add(a),y});try{f?await P.unmarkReviewed(t,a):await P.markReviewed(t,a)}catch{m(j=>{const y=new Set(j);return f?y.add(a):y.delete(a),y})}},[t]),N=r.useRef(!1),S=r.useCallback(a=>{if(N.current)return;N.current=!0;const f=new Set;for(const j of a.files)j.reviewed&&f.add(j.path);m(f)},[]),C=r.useMemo(()=>new Set(h),[h]),b=r.useMemo(()=>{var f;const a=(f=e==null?void 0:e.latest_run)==null?void 0:f.walkthrough;if(!a)return null;try{return JSON.parse(a)}catch{return null}},[e]),I=r.useMemo(()=>A(h,b),[h,b]),E=r.useMemo(()=>ae(I),[I]),w=r.useCallback(a=>{var f;d(a),(f=k.current)==null||f.scrollToFile(a)},[]),z=r.useCallback((a,f,j,y)=>{var F;d(a),(F=k.current)==null||F.revealLineInFile(a,f,j),l.setFocusedId(y),window.setTimeout(()=>{l.focusedId===y&&l.setFocusedId(null)},1600)},[l]);if(i)return s.jsx("div",{className:"p-6 text-red-500",children:i});if(!e)return s.jsx("div",{className:"p-6 text-sm text-muted-foreground",children:"Loading…"});const B=e.comments.filter(a=>a.status==="draft").length,G=e.comments.filter(a=>a.status==="accepted").length,L=e.comments.filter(a=>a.status==="stale").length,D=((M=e.latest_run)==null?void 0:M.status)==="running"||e.all_runs.some(a=>a.status==="running");return s.jsx(Q.Provider,{value:l,children:s.jsxs("div",{className:"flex h-full min-h-0 flex-col",children:[s.jsx(ue,{taskId:t,currentSha:e.task.pr_head_sha,onRefresh:v}),s.jsx(de,{taskId:t,prTitle:e.task.title,prNumber:e.task.pr_number,prUrl:e.task.pr_url??void 0,acceptedCount:G,draftCount:B,staleCount:L,reviewedDone:p.size,reviewedTotal:h.length,totalCommentsCount:l.byId.size,showCommentsPanel:u,onToggleCommentsPanel:()=>g(a=>!a),isRunning:D,onPublished:v,onReRun:v}),b&&s.jsx(se,{walkthrough:b}),s.jsxs("div",{className:"flex min-h-0 flex-1",children:[s.jsx("aside",{"data-testid":"review-file-tree-pane",className:"glass-chrome flex w-[300px] shrink-0 flex-col overflow-hidden border-r border-glass-edge",children:s.jsx(oe,{files:h,walkthrough:b,comments:e.comments,selectedPath:x,reviewedFiles:p,onToggleReviewed:R,onSelect:w})}),s.jsx("div",{className:"flex min-h-0 min-w-0 flex-1 flex-col",children:s.jsx(Y,{taskId:t,isRunning:D,range:{kind:"base"},listRef:k,enableComments:!0,onFilesChange:c,onSelectionChange:d,onSummaryLoaded:S,onToggleReviewed:R,hideFileTree:!0,fileOrder:E,groups:I})}),u&&s.jsx(X,{agents:[],filesInDiff:C,rangeIsBase:!0,onJumpTo:z,onClose:()=>g(!1)})]})]})})}export{we as default};
@@ -0,0 +1 @@
1
+ import{b as r,j as e}from"./vendor-react-Dd26lTa7.js";import{j as u,P as C,a as g,S,f as B,s as l,R as E}from"./index-CghBwA2d.js";import{L as b}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";const F=["required","recommended","optional"],D={required:"Required",recommended:"Recommended",optional:"Optional"};function O(s){switch(s){case"ok":return"Ready";case"missing":return"Missing";case"outdated":return"Outdated";case"unconfigured":return"Not configured";case"optional_missing":return"Optional";default:return s}}function A(s){switch(s){case"ok":return"text-[#22C55E]";case"missing":case"outdated":return"text-red-400";case"unconfigured":return"text-[#FFB800]";default:return"text-[#8a8a8a]"}}function I({item:s,installing:x,onInstall:i}){const d=x===s.id;return e.jsxs("div",{className:"flex flex-col gap-2 py-3 sm:flex-row sm:items-start sm:justify-between",style:E,children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-white",children:s.label}),e.jsx("span",{className:`text-xs font-medium ${A(s.status)}`,children:O(s.status)}),s.version&&e.jsx("span",{className:"truncate font-mono text-xs text-[#8a8a8a]",children:s.version})]}),s.detail&&e.jsx("p",{className:"mt-1 text-xs text-[#b5b5bd]",children:s.detail})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center gap-2",children:[s.install&&s.status!=="ok"&&e.jsx(g,{type:"button",size:"sm",variant:"outline",disabled:d,onClick:()=>i(s.install.id),"data-testid":`setup-install-${s.id}`,children:d?"Installing…":s.install.label}),s.configureUrl&&e.jsx(b,{to:s.configureUrl,className:"focus-ring rounded-md border border-glass-edge px-3 py-1.5 text-xs text-[#60a5fa] hover:bg-glass-l1",children:"Configure"}),s.docsUrl&&e.jsx("a",{href:s.docsUrl,target:"_blank",rel:"noreferrer",className:"focus-ring rounded-md px-2 py-1.5 text-xs text-[#8a8a8a] hover:text-white",children:"Docs"})]})]})}function T({initial:s,onSaved:x}){const[i,d]=r.useState(s.defaultBaseBranch??""),[m,f]=r.useState(s.deleteGraceHours??6),[c,p]=r.useState(!1),h=async()=>{p(!0);try{await u.updateSettings({defaultBaseBranch:i.trim()||void 0,deleteGraceHours:m}),l("success","DEFAULTS","Task defaults saved"),x()}catch(n){l("error","ERROR",n.message)}finally{p(!1)}};return e.jsxs("div",{className:"space-y-3 pt-2",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"setup-default-branch",className:"mb-1 block text-xs text-[#b5b5bd]",children:"Default base branch"}),e.jsx("input",{id:"setup-default-branch",type:"text",value:i,onChange:n=>d(n.target.value),placeholder:"main",className:"w-full border border-glass-edge bg-[#0B0C0F] px-3 py-2 font-mono text-sm text-white outline-none focus:border-[#3B82F6]","data-testid":"setup-default-branch"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"mb-1 block text-xs text-[#b5b5bd]",children:"Hours before deleted tasks are permanently removed"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"number",min:0,step:1,value:m,onChange:n=>f(Math.max(0,Number(n.target.value)||0)),className:"w-32 border border-glass-edge bg-[#0B0C0F] px-3 py-2 font-mono text-sm text-white outline-none focus:border-[#3B82F6]","data-testid":"setup-delete-grace-hours"}),e.jsx("span",{className:"text-xs text-[#8a8a8a]",children:"default 6"})]})]}),e.jsx("div",{className:"flex justify-end",children:e.jsx(g,{type:"button",size:"sm",disabled:c,onClick:h,"data-testid":"setup-save-defaults",children:c?"Saving…":"Save defaults"})})]})}function q(){const[s,x]=r.useState(null),[i,d]=r.useState(null),[m,f]=r.useState(!0),[c,p]=r.useState(null),[h,n]=r.useState(null),[y,j]=r.useState(!1),o=r.useCallback(async()=>{f(!0),p(null);try{const[t,a]=await Promise.all([u.getSettings(),u.getSetupStatus()]);d(t),x(a)}catch(t){p(t.message)}finally{f(!1)}},[]);r.useEffect(()=>{o()},[o]);const w=async t=>{n(t);try{const a=await u.setupInstall(t);l(a.ok?"success":"error","SETUP",a.message),await o()}catch(a){l("error","SETUP",a.message)}finally{n(null)}},N=async()=>{j(!0);try{const t=await u.applyRecommendedDefaults();d(t),l("success","DEFAULTS","Applied recommended defaults"),await o()}catch(t){l("error","ERROR",t.message)}finally{j(!1)}},R=async()=>{try{await u.updateSettings({onboardingCompletedAt:new Date().toISOString()}),l("success","SETUP","Setup reminder dismissed"),await o()}catch(t){l("error","ERROR",t.message)}},k=t=>(s==null?void 0:s.items.filter(a=>a.category===t&&a.id!=="defaults"))??[];return e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsx(C,{variant:"glass",title:"Setup",description:"Install dependencies, configure defaults, and connect integrations",actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(g,{type:"button",size:"sm",variant:"outline",disabled:y,onClick:N,"data-testid":"setup-apply-recommended",children:y?"Applying…":"Apply recommended defaults"}),e.jsx(g,{type:"button",size:"sm",variant:"ghost",onClick:R,children:"Dismiss reminders"})]})}),e.jsx("div",{className:"min-h-0 flex-1 overflow-auto px-6 py-6",children:e.jsxs("div",{className:"mx-auto max-w-3xl space-y-6",children:[m&&e.jsx("div",{className:"space-y-2",children:[1,2,3].map(t=>e.jsx("div",{className:"h-14 animate-pulse border border-glass-edge bg-glass-l1"},t))}),c&&e.jsxs("div",{className:"border border-red-400/30 bg-red-400/5 px-4 py-3 text-sm text-red-400",children:[c,e.jsx("button",{type:"button",className:"ml-3 text-[#3B82F6]",onClick:o,children:"Retry"})]}),!m&&!c&&s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{"data-testid":"setup-summary",className:s.summary.ready?"border border-[#22C55E]/30 bg-[#22C55E]/5 px-4 py-3 text-sm text-[#22C55E]":"border border-[#FFB800]/30 bg-[#FFB800]/5 px-4 py-3 text-sm text-[#FFB800]",children:[s.summary.ready?"Core dependencies are ready. Optional items can be configured below.":`${s.summary.blockerCount} required item(s) still need attention before tasks can run reliably.`,s.hasBrew&&s.platform==="darwin"&&e.jsx("span",{className:"mt-1 block text-xs opacity-80",children:"Homebrew installs are available from this page."})]}),F.map(t=>{const a=k(t);return a.length===0?null:e.jsx(S,{id:`setup-${t}`,title:D[t],children:a.map(v=>e.jsx(I,{item:v,installing:h,onInstall:w},v.id))},t)}),e.jsxs(S,{id:"setup-defaults",title:"Task defaults",children:[e.jsx(B,{label:"Defaults for new tasks",description:"Base branch and trash retention for new tasks",lastRow:!0,children:e.jsx("span",{})}),i&&e.jsx(T,{initial:i,onSaved:o})]}),e.jsxs("p",{className:"text-center text-xs text-[#8a8a8a]",children:["More options in"," ",e.jsx(b,{to:"/settings",className:"text-[#60a5fa] hover:underline",children:"Settings"})," ","and"," ",e.jsx(b,{to:"/integrations",className:"text-[#60a5fa] hover:underline",children:"Integrations"}),"."]})]})]})})]})}export{q as default};
@@ -1 +1 @@
1
- import{d as s,j as e}from"./vendor-react-DVZ9vYhU.js";import{k as x,n as u}from"./index-Cuel_jco.js";import{c as j,b}from"./vendor-router-BNSfXSMI.js";import"./vendor-ui-vLFv-L6M.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-8w_IdZy_.js";function B(){const{name:a}=j(),i=b(),[r,o]=s.useState(""),[m,h]=s.useState(!0),[f,p]=s.useState(null),[l,d]=s.useState(!1),c=s.useRef(""),n=r!==c.current;s.useEffect(()=>{a&&x.getSkill(a).then(t=>{o(t.content),c.current=t.content}).catch(t=>p(t.message)).finally(()=>h(!1))},[a]);const g=s.useCallback(async()=>{if(!(!a||!n||l)){d(!0);try{await x.updateSkill(a,{content:r}),c.current=r,u.success("Skill saved")}catch(t){u.error(t instanceof Error?t.message:"Failed to save skill")}finally{d(!1)}}},[a,r,n,l]),v=s.useCallback(()=>{n&&!window.confirm("You have unsaved changes. Discard them?")||i("/settings")},[n,i]);return m?e.jsx("div",{className:"flex h-full items-center justify-center",children:e.jsx("span",{className:"text-[#6a6a6a]",children:"Loading..."})}):f?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3",children:[e.jsx("p",{className:"text-red-400",children:f}),e.jsx("button",{onClick:()=>i("/settings"),className:"text-xs text-[#3B82F6] hover:underline",children:"Back to Settings"})]}):e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] px-6 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:v,className:"text-sm text-[#6a6a6a] hover:text-white",children:"←"}),e.jsx("span",{className:"font-mono text-lg font-bold",children:a}),n&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"})]}),e.jsx("button",{onClick:g,disabled:!n||l,className:"bg-[#3B82F6] px-4 py-2 text-xs text-white disabled:opacity-50",children:l?"Saving...":"Save"})]}),e.jsx("div",{className:"flex-1 p-6",children:e.jsx("textarea",{value:r,onChange:t=>o(t.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{B as default};
1
+ import{b as s,j as e}from"./vendor-react-Dd26lTa7.js";import{j as x,t as u}from"./index-CghBwA2d.js";import{c as j,b}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";function B(){const{name:a}=j(),i=b(),[r,o]=s.useState(""),[m,h]=s.useState(!0),[f,p]=s.useState(null),[l,d]=s.useState(!1),c=s.useRef(""),n=r!==c.current;s.useEffect(()=>{a&&x.getSkill(a).then(t=>{o(t.content),c.current=t.content}).catch(t=>p(t.message)).finally(()=>h(!1))},[a]);const g=s.useCallback(async()=>{if(!(!a||!n||l)){d(!0);try{await x.updateSkill(a,{content:r}),c.current=r,u.success("Skill saved")}catch(t){u.error(t instanceof Error?t.message:"Failed to save skill")}finally{d(!1)}}},[a,r,n,l]),v=s.useCallback(()=>{n&&!window.confirm("You have unsaved changes. Discard them?")||i("/settings")},[n,i]);return m?e.jsx("div",{className:"flex h-full items-center justify-center",children:e.jsx("span",{className:"text-[#6a6a6a]",children:"Loading..."})}):f?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-3",children:[e.jsx("p",{className:"text-red-400",children:f}),e.jsx("button",{onClick:()=>i("/settings"),className:"text-xs text-[#3B82F6] hover:underline",children:"Back to Settings"})]}):e.jsxs("div",{className:"flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-[#2f2f2f] px-6 py-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{onClick:v,className:"text-sm text-[#6a6a6a] hover:text-white",children:"←"}),e.jsx("span",{className:"font-mono text-lg font-bold",children:a}),n&&e.jsx("span",{className:"text-xs text-[#FFB800]",children:"unsaved"})]}),e.jsx("button",{onClick:g,disabled:!n||l,className:"bg-[#3B82F6] px-4 py-2 text-xs text-white disabled:opacity-50",children:l?"Saving...":"Save"})]}),e.jsx("div",{className:"flex-1 p-6",children:e.jsx("textarea",{value:r,onChange:t=>o(t.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{B as default};
@@ -1 +1 @@
1
- import{d as n,j as e}from"./vendor-react-DVZ9vYhU.js";import{k as x,B as m}from"./index-Cuel_jco.js";import{c as N,b as y}from"./vendor-router-BNSfXSMI.js";import"./vendor-ui-vLFv-L6M.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-8w_IdZy_.js";const _={new:"new",existing:"existing",none:"none",scratch:"scratch"};function C(s){if(!s)return"—";const a=s.split("/").filter(Boolean);return a[a.length-1]||s}function u(s){if(!s)return"—";const a=new Date(s.replace(" ","T")+"Z");return Number.isNaN(a.getTime())?s:a.toLocaleString()}function O(){const{id:s}=N(),a=y(),[t,h]=n.useState(null),[i,c]=n.useState(null),[f,l]=n.useState(!1),d=n.useCallback(async()=>{if(s){c(null);try{const o=await x.getWorktree(s);h(o)}catch(o){c(o.message)}}},[s]);n.useEffect(()=>{d()},[d]);const k=n.useCallback(()=>{if(!t)return;const o=new URLSearchParams;t.worktree.repo_path&&o.set("repo",t.worktree.repo_path),o.set("mode","existing"),t.worktree.path&&o.set("worktree_path",t.worktree.path),a(`/?${o.toString()}`)},[t,a]),w=n.useCallback(async()=>{if(!t)return;const g=t.worktree.mode==="existing"||t.worktree.mode==="none"?"Forget this workspace? The filesystem directory will be left untouched; only the Octomux record is removed.":"Remove this workspace? This deletes the worktree directory and branch from disk.";if(window.confirm(g)){l(!0);try{await x.deleteWorktree(t.worktree.id),a("/workspaces")}catch(j){c(j.message),l(!1)}}},[t,a]);if(i&&!t)return e.jsx("div",{className:"h-full overflow-auto",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 text-sm text-destructive",children:["Failed to load workspace: ",i]})});if(!t)return e.jsx("div",{className:"h-full overflow-auto",children:e.jsx("div",{className:"mx-auto max-w-4xl px-4 py-6 text-sm text-[#8a8a8a]",children:"Loading…"})});const r=t.worktree,v=r.status==="available"&&t.active_task===null&&!f,b=r.mode==="existing"||r.mode==="none";return e.jsx("div",{className:"h-full overflow-auto",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6",children:[e.jsx("button",{onClick:()=>a("/workspaces"),className:"mb-3 text-xs text-[#8a8a8a] hover:text-foreground",children:"← All workspaces"}),e.jsxs("div",{className:"mb-6 flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex flex-col gap-1.5",children:[e.jsxs("h1",{className:"font-display text-[28px] font-bold leading-tight",children:[C(r.repo_path),r.branch?e.jsx("span",{className:"ml-3 font-mono text-lg text-[#a0a0a0]",children:r.branch}):null]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-[#8a8a8a]",children:[e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5",style:{fontSize:10,background:"#1a1a1a",border:"1px solid #2f2f2f",color:"#a0a0a0"},children:_[r.mode]}),e.jsx("span",{className:r.status==="in_use"?"text-[#22C55E]":"",children:r.status})]}),e.jsx("div",{className:"mt-1 break-all font-mono text-xs text-[#8a8a8a]",children:r.path})]}),e.jsxs("div",{className:"flex shrink-0 flex-col items-end gap-2",children:[r.status==="available"&&e.jsx(m,{size:"sm",onClick:k,"data-testid":"new-task-on-workspace",children:"New task on this workspace"}),v&&e.jsx(m,{size:"sm",variant:"outline",onClick:w,"data-testid":"remove-workspace",children:b?"Forget workspace":"Remove workspace"})]})]}),i&&e.jsx("div",{className:"mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:i}),e.jsxs("section",{className:"mb-6",children:[e.jsx("h2",{className:"mb-2 text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:"Active task"}),t.active_task?e.jsx(p,{task:t.active_task,onClick:()=>a(`/tasks/${t.active_task.id}`)}):e.jsx("div",{className:"rounded-md border border-border bg-card p-4 text-sm text-[#8a8a8a]",children:"No active task."})]}),e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:["History (",t.history.length,")"]}),t.history.length===0?e.jsx("div",{className:"rounded-md border border-border bg-card p-4 text-sm text-[#8a8a8a]",children:"No past tasks."}):e.jsx("div",{className:"flex flex-col gap-2",children:t.history.map(o=>e.jsx(p,{task:o,onClick:()=>a(`/tasks/${o.id}`)},o.id))})]}),e.jsxs("div",{className:"mt-6 text-[10px] text-[#6a6a6a]",children:["Created ",u(r.created_at)," · Last used ",u(r.last_used_at)]})]})})}function p({task:s,onClick:a}){return e.jsxs("button",{type:"button",onClick:a,"data-testid":`workspace-task-${s.id}`,className:"flex w-full items-center justify-between gap-3 rounded-md border border-border bg-card px-3 py-2 text-left hover:bg-[#141414]",children:[e.jsx("div",{className:"min-w-0 flex-1 truncate text-sm text-foreground",children:s.title}),e.jsx("div",{className:"shrink-0 text-xs text-[#8a8a8a]",children:s.runtime_state})]})}export{O as default};
1
+ import{b as n,j as e}from"./vendor-react-Dd26lTa7.js";import{j as x,a as m}from"./index-CghBwA2d.js";import{c as N,b as y}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";const _={new:"new",existing:"existing",none:"none",scratch:"scratch"};function C(s){if(!s)return"—";const a=s.split("/").filter(Boolean);return a[a.length-1]||s}function u(s){if(!s)return"—";const a=new Date(s.replace(" ","T")+"Z");return Number.isNaN(a.getTime())?s:a.toLocaleString()}function O(){const{id:s}=N(),a=y(),[t,h]=n.useState(null),[i,c]=n.useState(null),[f,l]=n.useState(!1),d=n.useCallback(async()=>{if(s){c(null);try{const o=await x.getWorktree(s);h(o)}catch(o){c(o.message)}}},[s]);n.useEffect(()=>{d()},[d]);const k=n.useCallback(()=>{if(!t)return;const o=new URLSearchParams;t.worktree.repo_path&&o.set("repo",t.worktree.repo_path),o.set("mode","existing"),t.worktree.path&&o.set("worktree_path",t.worktree.path),a(`/?${o.toString()}`)},[t,a]),w=n.useCallback(async()=>{if(!t)return;const g=t.worktree.mode==="existing"||t.worktree.mode==="none"?"Forget this workspace? The filesystem directory will be left untouched; only the Octomux record is removed.":"Remove this workspace? This deletes the worktree directory and branch from disk.";if(window.confirm(g)){l(!0);try{await x.deleteWorktree(t.worktree.id),a("/workspaces")}catch(j){c(j.message),l(!1)}}},[t,a]);if(i&&!t)return e.jsx("div",{className:"h-full overflow-auto",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6 text-sm text-destructive",children:["Failed to load workspace: ",i]})});if(!t)return e.jsx("div",{className:"h-full overflow-auto",children:e.jsx("div",{className:"mx-auto max-w-4xl px-4 py-6 text-sm text-[#8a8a8a]",children:"Loading…"})});const r=t.worktree,v=r.status==="available"&&t.active_task===null&&!f,b=r.mode==="existing"||r.mode==="none";return e.jsx("div",{className:"h-full overflow-auto",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 py-6",children:[e.jsx("button",{onClick:()=>a("/workspaces"),className:"mb-3 text-xs text-[#8a8a8a] hover:text-foreground",children:"← All workspaces"}),e.jsxs("div",{className:"mb-6 flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex flex-col gap-1.5",children:[e.jsxs("h1",{className:"font-display text-[28px] font-bold leading-tight",children:[C(r.repo_path),r.branch?e.jsx("span",{className:"ml-3 font-mono text-lg text-[#a0a0a0]",children:r.branch}):null]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-[#8a8a8a]",children:[e.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5",style:{fontSize:10,background:"#1a1a1a",border:"1px solid #2f2f2f",color:"#a0a0a0"},children:_[r.mode]}),e.jsx("span",{className:r.status==="in_use"?"text-[#22C55E]":"",children:r.status})]}),e.jsx("div",{className:"mt-1 break-all font-mono text-xs text-[#8a8a8a]",children:r.path})]}),e.jsxs("div",{className:"flex shrink-0 flex-col items-end gap-2",children:[r.status==="available"&&e.jsx(m,{size:"sm",onClick:k,"data-testid":"new-task-on-workspace",children:"New task on this workspace"}),v&&e.jsx(m,{size:"sm",variant:"outline",onClick:w,"data-testid":"remove-workspace",children:b?"Forget workspace":"Remove workspace"})]})]}),i&&e.jsx("div",{className:"mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:i}),e.jsxs("section",{className:"mb-6",children:[e.jsx("h2",{className:"mb-2 text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:"Active task"}),t.active_task?e.jsx(p,{task:t.active_task,onClick:()=>a(`/tasks/${t.active_task.id}`)}):e.jsx("div",{className:"rounded-md border border-border bg-card p-4 text-sm text-[#8a8a8a]",children:"No active task."})]}),e.jsxs("section",{children:[e.jsxs("h2",{className:"mb-2 text-xs font-bold uppercase tracking-wider text-[#8a8a8a]",children:["History (",t.history.length,")"]}),t.history.length===0?e.jsx("div",{className:"rounded-md border border-border bg-card p-4 text-sm text-[#8a8a8a]",children:"No past tasks."}):e.jsx("div",{className:"flex flex-col gap-2",children:t.history.map(o=>e.jsx(p,{task:o,onClick:()=>a(`/tasks/${o.id}`)},o.id))})]}),e.jsxs("div",{className:"mt-6 text-[10px] text-[#6a6a6a]",children:["Created ",u(r.created_at)," · Last used ",u(r.last_used_at)]})]})})}function p({task:s,onClick:a}){return e.jsxs("button",{type:"button",onClick:a,"data-testid":`workspace-task-${s.id}`,className:"flex w-full items-center justify-between gap-3 rounded-md border border-border bg-card px-3 py-2 text-left hover:bg-[#141414]",children:[e.jsx("div",{className:"min-w-0 flex-1 truncate text-sm text-foreground",children:s.title}),e.jsx("div",{className:"shrink-0 text-xs text-[#8a8a8a]",children:s.runtime_state})]})}export{O as default};
@@ -1 +1 @@
1
- import{d as o,j as e}from"./vendor-react-DVZ9vYhU.js";import{P as N,G as u,k as y}from"./index-Cuel_jco.js";import{b}from"./vendor-router-BNSfXSMI.js";import"./vendor-ui-vLFv-L6M.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-8w_IdZy_.js";function h(r){if(!r)return"—";const s=r.split("/").filter(Boolean);return s[s.length-1]||r}function v(r,s=48){return r?r.length<=s?r:"…"+r.slice(r.length-(s-1)):"—"}function k(r){if(!r)return"—";const s=new Date(r.replace(" ","T")+"Z").getTime();if(Number.isNaN(s))return r;const d=Date.now()-s,l=Math.floor(d/6e4);if(l<1)return"just now";if(l<60)return`${l}m ago`;const n=Math.floor(l/60);if(n<24)return`${n}h ago`;const a=Math.floor(n/24);return a<30?`${a}d ago`:`${Math.floor(a/30)}mo ago`}const f={new:"new",existing:"existing",none:"none",scratch:"scratch"};function $(){const r=b(),[s,d]=o.useState(null),[l,n]=o.useState(null),[a,p]=o.useState("all"),[c,g]=o.useState("all");o.useEffect(()=>{let t=!1;async function i(){try{const x=await y.listWorktrees();t||d(x)}catch(x){t||n(x.message)}}return i(),()=>{t=!0}},[]);const j=o.useMemo(()=>{if(!s)return[];const t=new Set;for(const i of s)i.repo_path&&t.add(i.repo_path);return[...t].sort()},[s]),m=o.useMemo(()=>s?s.filter(t=>!(a!=="all"&&t.repo_path!==a||c!=="all"&&t.mode!==c)):[],[s,a,c]);return l?e.jsx("div",{className:"h-full overflow-auto px-6 py-6",children:e.jsxs("p",{className:"text-sm text-destructive",children:["Failed to load workspaces: ",l]})}):e.jsxs("div",{className:"flex h-full flex-col overflow-auto",children:[e.jsx(N,{variant:"glass",eyebrow:"Workspaces",title:"Workspaces",description:"Git worktrees and scratch directories used by tasks",className:"shrink-0"}),e.jsxs("div",{className:"mx-auto w-full max-w-6xl flex-1 px-6 py-6",children:[e.jsxs(u,{level:1,specular:!0,className:"mb-4 flex flex-wrap items-center gap-4 rounded-2xl px-4 py-3","data-testid":"workspace-filters",children:[e.jsxs("label",{className:"text-xs text-muted-soft",children:["Repo",e.jsxs("select",{"aria-label":"Filter by repo",value:a,onChange:t=>p(t.target.value),className:"focus-ring ml-2 rounded-lg border border-input bg-secondary px-2 py-1 text-xs text-foreground",children:[e.jsx("option",{value:"all",children:"All"}),j.map(t=>e.jsx("option",{value:t,children:h(t)},t))]})]}),e.jsxs("label",{className:"text-xs text-muted-soft",children:["Mode",e.jsxs("select",{"aria-label":"Filter by mode",value:c,onChange:t=>g(t.target.value),className:"focus-ring ml-2 rounded-lg border border-input bg-secondary px-2 py-1 text-xs text-foreground",children:[e.jsx("option",{value:"all",children:"All"}),["new","existing","none","scratch"].map(t=>e.jsx("option",{value:t,children:f[t]},t))]})]})]}),s===null?e.jsx("p",{className:"text-sm text-muted-soft",children:"Loading…"}):m.length===0?e.jsx(u,{level:2,className:"rounded-2xl p-8 text-center text-sm text-muted-soft",children:s.length===0?"No workspaces yet. They're created automatically when you start a task.":"No workspaces match these filters."}):e.jsx(u,{level:2,className:"overflow-hidden rounded-2xl",children:e.jsxs("table",{className:"w-full text-left text-sm",children:[e.jsx("thead",{className:"border-b border-glass-edge bg-glass-l1 text-xs font-medium text-muted-soft",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2.5",children:"Repo"}),e.jsx("th",{className:"px-4 py-2.5",children:"Branch"}),e.jsx("th",{className:"px-4 py-2.5",children:"Mode"}),e.jsx("th",{className:"px-4 py-2.5",children:"Path"}),e.jsx("th",{className:"px-4 py-2.5",children:"Status"}),e.jsx("th",{className:"px-4 py-2.5",children:"Tasks"}),e.jsx("th",{className:"px-4 py-2.5",children:"Last used"})]})}),e.jsx("tbody",{children:m.map(t=>e.jsxs("tr",{"data-testid":`workspace-row-${t.id}`,onClick:()=>r(`/workspaces/${t.id}`),className:"cursor-pointer border-t border-glass-edge transition-colors hover:bg-glass-l1",children:[e.jsx("td",{className:"px-4 py-2.5 text-foreground",children:h(t.repo_path)}),e.jsx("td",{className:"px-4 py-2.5 font-mono text-xs text-muted-foreground",children:t.branch??"—"}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("span",{className:"inline-flex rounded-md border border-input bg-secondary px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground",children:f[t.mode]})}),e.jsx("td",{className:"max-w-[200px] truncate px-4 py-2.5 font-mono text-xs text-muted-soft",title:t.path,children:v(t.path)}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("span",{className:t.status==="in_use"?"text-success":"text-muted-soft",children:t.status})}),e.jsx("td",{className:"px-4 py-2.5 text-muted-foreground",children:t.task_count}),e.jsx("td",{className:"px-4 py-2.5 text-muted-soft",children:k(t.last_used_at)})]},t.id))})]})})]})]})}export{$ as default};
1
+ import{b as o,j as e}from"./vendor-react-Dd26lTa7.js";import{P as N,G as u,j as y}from"./index-CghBwA2d.js";import{b}from"./vendor-router-yJbofmar.js";import"./vendor-ui-ChI1tM4e.js";import"./vendor-xterm-DvXGiZvM.js";import"./vendor-monaco-CdNyTACs.js";function h(r){if(!r)return"—";const s=r.split("/").filter(Boolean);return s[s.length-1]||r}function v(r,s=48){return r?r.length<=s?r:"…"+r.slice(r.length-(s-1)):"—"}function k(r){if(!r)return"—";const s=new Date(r.replace(" ","T")+"Z").getTime();if(Number.isNaN(s))return r;const d=Date.now()-s,l=Math.floor(d/6e4);if(l<1)return"just now";if(l<60)return`${l}m ago`;const n=Math.floor(l/60);if(n<24)return`${n}h ago`;const a=Math.floor(n/24);return a<30?`${a}d ago`:`${Math.floor(a/30)}mo ago`}const f={new:"new",existing:"existing",none:"none",scratch:"scratch"};function $(){const r=b(),[s,d]=o.useState(null),[l,n]=o.useState(null),[a,p]=o.useState("all"),[c,g]=o.useState("all");o.useEffect(()=>{let t=!1;async function i(){try{const x=await y.listWorktrees();t||d(x)}catch(x){t||n(x.message)}}return i(),()=>{t=!0}},[]);const j=o.useMemo(()=>{if(!s)return[];const t=new Set;for(const i of s)i.repo_path&&t.add(i.repo_path);return[...t].sort()},[s]),m=o.useMemo(()=>s?s.filter(t=>!(a!=="all"&&t.repo_path!==a||c!=="all"&&t.mode!==c)):[],[s,a,c]);return l?e.jsx("div",{className:"h-full overflow-auto px-6 py-6",children:e.jsxs("p",{className:"text-sm text-destructive",children:["Failed to load workspaces: ",l]})}):e.jsxs("div",{className:"flex h-full flex-col overflow-auto",children:[e.jsx(N,{variant:"glass",eyebrow:"Workspaces",title:"Workspaces",description:"Git worktrees and scratch directories used by tasks",className:"shrink-0"}),e.jsxs("div",{className:"mx-auto w-full max-w-6xl flex-1 px-6 py-6",children:[e.jsxs(u,{level:1,specular:!0,className:"mb-4 flex flex-wrap items-center gap-4 rounded-2xl px-4 py-3","data-testid":"workspace-filters",children:[e.jsxs("label",{className:"text-xs text-muted-soft",children:["Repo",e.jsxs("select",{"aria-label":"Filter by repo",value:a,onChange:t=>p(t.target.value),className:"focus-ring ml-2 rounded-lg border border-input bg-secondary px-2 py-1 text-xs text-foreground",children:[e.jsx("option",{value:"all",children:"All"}),j.map(t=>e.jsx("option",{value:t,children:h(t)},t))]})]}),e.jsxs("label",{className:"text-xs text-muted-soft",children:["Mode",e.jsxs("select",{"aria-label":"Filter by mode",value:c,onChange:t=>g(t.target.value),className:"focus-ring ml-2 rounded-lg border border-input bg-secondary px-2 py-1 text-xs text-foreground",children:[e.jsx("option",{value:"all",children:"All"}),["new","existing","none","scratch"].map(t=>e.jsx("option",{value:t,children:f[t]},t))]})]})]}),s===null?e.jsx("p",{className:"text-sm text-muted-soft",children:"Loading…"}):m.length===0?e.jsx(u,{level:2,className:"rounded-2xl p-8 text-center text-sm text-muted-soft",children:s.length===0?"No workspaces yet. They're created automatically when you start a task.":"No workspaces match these filters."}):e.jsx(u,{level:2,className:"overflow-hidden rounded-2xl",children:e.jsxs("table",{className:"w-full text-left text-sm",children:[e.jsx("thead",{className:"border-b border-glass-edge bg-glass-l1 text-xs font-medium text-muted-soft",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-2.5",children:"Repo"}),e.jsx("th",{className:"px-4 py-2.5",children:"Branch"}),e.jsx("th",{className:"px-4 py-2.5",children:"Mode"}),e.jsx("th",{className:"px-4 py-2.5",children:"Path"}),e.jsx("th",{className:"px-4 py-2.5",children:"Status"}),e.jsx("th",{className:"px-4 py-2.5",children:"Tasks"}),e.jsx("th",{className:"px-4 py-2.5",children:"Last used"})]})}),e.jsx("tbody",{children:m.map(t=>e.jsxs("tr",{"data-testid":`workspace-row-${t.id}`,onClick:()=>r(`/workspaces/${t.id}`),className:"cursor-pointer border-t border-glass-edge transition-colors hover:bg-glass-l1",children:[e.jsx("td",{className:"px-4 py-2.5 text-foreground",children:h(t.repo_path)}),e.jsx("td",{className:"px-4 py-2.5 font-mono text-xs text-muted-foreground",children:t.branch??"—"}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("span",{className:"inline-flex rounded-md border border-input bg-secondary px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground",children:f[t.mode]})}),e.jsx("td",{className:"max-w-[200px] truncate px-4 py-2.5 font-mono text-xs text-muted-soft",title:t.path,children:v(t.path)}),e.jsx("td",{className:"px-4 py-2.5",children:e.jsx("span",{className:t.status==="in_use"?"text-success":"text-muted-soft",children:t.status})}),e.jsx("td",{className:"px-4 py-2.5 text-muted-foreground",children:t.task_count}),e.jsx("td",{className:"px-4 py-2.5 text-muted-soft",children:k(t.last_used_at)})]},t.id))})]})})]})]})}export{$ as default};