@juspay/shooter 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/.claude/hooks/codex-hooks.example.json +75 -0
  2. package/.claude/hooks/notifier.cjs +158 -8
  3. package/build/client/_app/immutable/assets/{0.DEfoFaGR.css → 0.B0O0vCnX.css} +1 -1
  4. package/build/client/_app/immutable/assets/0.B0O0vCnX.css.br +0 -0
  5. package/build/client/_app/immutable/assets/0.B0O0vCnX.css.gz +0 -0
  6. package/build/client/_app/immutable/chunks/BctvtE4d.js +1 -0
  7. package/build/client/_app/immutable/chunks/BctvtE4d.js.br +0 -0
  8. package/build/client/_app/immutable/chunks/BctvtE4d.js.gz +0 -0
  9. package/build/client/_app/immutable/chunks/BxFShcQO.js +1 -0
  10. package/build/client/_app/immutable/chunks/BxFShcQO.js.br +0 -0
  11. package/build/client/_app/immutable/chunks/BxFShcQO.js.gz +0 -0
  12. package/build/client/_app/immutable/chunks/{DOHhmtDH.js → ByzqAuXw.js} +1 -1
  13. package/build/client/_app/immutable/chunks/ByzqAuXw.js.br +0 -0
  14. package/build/client/_app/immutable/chunks/ByzqAuXw.js.gz +0 -0
  15. package/build/client/_app/immutable/chunks/{DlS3abGJ.js → CjfxuHdN.js} +1 -1
  16. package/build/client/_app/immutable/chunks/CjfxuHdN.js.br +0 -0
  17. package/build/client/_app/immutable/chunks/CjfxuHdN.js.gz +0 -0
  18. package/build/client/_app/immutable/entry/{app.CSJG7N9H.js → app.CNaTe-zm.js} +2 -2
  19. package/build/client/_app/immutable/entry/app.CNaTe-zm.js.br +0 -0
  20. package/build/client/_app/immutable/entry/app.CNaTe-zm.js.gz +0 -0
  21. package/build/client/_app/immutable/entry/start.hxYnjcDu.js +1 -0
  22. package/build/client/_app/immutable/entry/start.hxYnjcDu.js.br +0 -0
  23. package/build/client/_app/immutable/entry/start.hxYnjcDu.js.gz +0 -0
  24. package/build/client/_app/immutable/nodes/{0.qOL7xtFn.js → 0.C3ELOf4c.js} +1 -1
  25. package/build/client/_app/immutable/nodes/0.C3ELOf4c.js.br +0 -0
  26. package/build/client/_app/immutable/nodes/0.C3ELOf4c.js.gz +0 -0
  27. package/build/client/_app/immutable/nodes/{1.Di708Ago.js → 1.Fqso94b3.js} +1 -1
  28. package/build/client/_app/immutable/nodes/1.Fqso94b3.js.br +0 -0
  29. package/build/client/_app/immutable/nodes/1.Fqso94b3.js.gz +0 -0
  30. package/build/client/_app/immutable/nodes/{2.DSM1znqa.js → 2.BusCVJWk.js} +1 -1
  31. package/build/client/_app/immutable/nodes/2.BusCVJWk.js.br +0 -0
  32. package/build/client/_app/immutable/nodes/2.BusCVJWk.js.gz +0 -0
  33. package/build/client/_app/immutable/nodes/{3.BPa5fh75.js → 3.DUlpocIc.js} +1 -1
  34. package/build/client/_app/immutable/nodes/3.DUlpocIc.js.br +0 -0
  35. package/build/client/_app/immutable/nodes/3.DUlpocIc.js.gz +0 -0
  36. package/build/client/_app/immutable/nodes/6.CG4eKRH0.js +1 -0
  37. package/build/client/_app/immutable/nodes/6.CG4eKRH0.js.br +0 -0
  38. package/build/client/_app/immutable/nodes/6.CG4eKRH0.js.gz +0 -0
  39. package/build/client/_app/immutable/nodes/{7.B7UJd8GQ.js → 7.DHilxD1o.js} +3 -3
  40. package/build/client/_app/immutable/nodes/7.DHilxD1o.js.br +0 -0
  41. package/build/client/_app/immutable/nodes/7.DHilxD1o.js.gz +0 -0
  42. package/build/client/_app/immutable/nodes/8.BjKgvSie.js +2 -0
  43. package/build/client/_app/immutable/nodes/8.BjKgvSie.js.br +0 -0
  44. package/build/client/_app/immutable/nodes/8.BjKgvSie.js.gz +0 -0
  45. package/build/client/_app/immutable/nodes/9.BRT6HOXB.js +2 -0
  46. package/build/client/_app/immutable/nodes/9.BRT6HOXB.js.br +0 -0
  47. package/build/client/_app/immutable/nodes/9.BRT6HOXB.js.gz +0 -0
  48. package/build/client/_app/version.json +1 -1
  49. package/build/client/_app/version.json.br +0 -0
  50. package/build/client/_app/version.json.gz +0 -0
  51. package/build/server/chunks/{0-D8uPamNd.js → 0-BWFSL107.js} +3 -3
  52. package/build/server/chunks/{0-D8uPamNd.js.map → 0-BWFSL107.js.map} +1 -1
  53. package/build/server/chunks/{1-DhtioHbs.js → 1-Bw5KlAjL.js} +2 -2
  54. package/build/server/chunks/{1-DhtioHbs.js.map → 1-Bw5KlAjL.js.map} +1 -1
  55. package/build/server/chunks/{2-Cgh7ZFgE.js → 2-CQ3yYSVK.js} +2 -2
  56. package/build/server/chunks/{2-Cgh7ZFgE.js.map → 2-CQ3yYSVK.js.map} +1 -1
  57. package/build/server/chunks/{3-I6hnjssH.js → 3-DZ4H9hPs.js} +2 -2
  58. package/build/server/chunks/{3-I6hnjssH.js.map → 3-DZ4H9hPs.js.map} +1 -1
  59. package/build/server/chunks/{6-bPDbH1_W.js → 6-BZ0enR6b.js} +2 -2
  60. package/build/server/chunks/6-BZ0enR6b.js.map +1 -0
  61. package/build/server/chunks/{7-CpBrOkxQ.js → 7-Lg8imTZn.js} +2 -2
  62. package/build/server/chunks/7-Lg8imTZn.js.map +1 -0
  63. package/build/server/chunks/{8-BRGAVfze.js → 8-DKs4yOL7.js} +2 -2
  64. package/build/server/chunks/8-DKs4yOL7.js.map +1 -0
  65. package/build/server/chunks/{9-C6xuAb_Y.js → 9-UNmpUWDY.js} +2 -2
  66. package/build/server/chunks/9-UNmpUWDY.js.map +1 -0
  67. package/build/server/chunks/{_server.ts-C6xbNz6d.js → _server.ts-5wx4ZppI.js} +3 -3
  68. package/build/server/chunks/{_server.ts-C6xbNz6d.js.map → _server.ts-5wx4ZppI.js.map} +1 -1
  69. package/build/server/chunks/{_server.ts-BrRZXr-8.js → _server.ts-B1z0q6qZ.js} +10 -9
  70. package/build/server/chunks/_server.ts-B1z0q6qZ.js.map +1 -0
  71. package/build/server/chunks/_server.ts-BMMTS86y.js +82 -0
  72. package/build/server/chunks/_server.ts-BMMTS86y.js.map +1 -0
  73. package/build/server/chunks/{_server.ts-CjK0g9dO.js → _server.ts-Bt7EAfjo.js} +34 -2
  74. package/build/server/chunks/_server.ts-Bt7EAfjo.js.map +1 -0
  75. package/build/server/chunks/{_server.ts-Cq9_scaV.js → _server.ts-CKXVBbwb.js} +16 -16
  76. package/build/server/chunks/_server.ts-CKXVBbwb.js.map +1 -0
  77. package/build/server/chunks/{_server.ts-Dekgb6Hx.js → _server.ts-CgHc1Zpx.js} +3 -3
  78. package/build/server/chunks/{_server.ts-Dekgb6Hx.js.map → _server.ts-CgHc1Zpx.js.map} +1 -1
  79. package/build/server/chunks/{_server.ts-CFX-S_8q.js → _server.ts-DZ5naqSL.js} +2 -2
  80. package/build/server/chunks/{_server.ts-CFX-S_8q.js.map → _server.ts-DZ5naqSL.js.map} +1 -1
  81. package/build/server/chunks/{opencode-db-path-CRgzBK5U.js → opencode-db-path-BwaPufWf.js} +41 -32
  82. package/build/server/chunks/opencode-db-path-BwaPufWf.js.map +1 -0
  83. package/build/server/chunks/{pty-manager-aFpChJah.js → pty-manager-RmhVe2Ez.js} +2 -2
  84. package/build/server/chunks/{pty-manager-aFpChJah.js.map → pty-manager-RmhVe2Ez.js.map} +1 -1
  85. package/build/server/chunks/qwen-reader-2fTFuC_D.js +622 -0
  86. package/build/server/chunks/qwen-reader-2fTFuC_D.js.map +1 -0
  87. package/build/server/chunks/{_server.ts-D--_NXt2.js → registry-DzJj2E6I.js} +89 -95
  88. package/build/server/chunks/registry-DzJj2E6I.js.map +1 -0
  89. package/build/server/index.js +1 -1
  90. package/build/server/index.js.map +1 -1
  91. package/build/server/manifest.js +16 -16
  92. package/build/server/manifest.js.map +1 -1
  93. package/package.json +1 -1
  94. package/src/lib/modules/client/common/index.ts +1 -1
  95. package/src/lib/modules/client/common/provider.ts +13 -0
  96. package/src/lib/modules/client/terminal/LaunchSheet.svelte +1 -0
  97. package/src/lib/modules/server/sessions/codex-reader.ts +34 -33
  98. package/src/lib/modules/server/sessions/gemini-reader.ts +571 -0
  99. package/src/lib/modules/server/sessions/opencode-db-path.ts +19 -10
  100. package/src/lib/modules/server/sessions/process-detector.ts +44 -0
  101. package/src/lib/modules/server/sessions/qwen-reader.ts +310 -0
  102. package/src/lib/modules/server/sessions/registry.ts +137 -0
  103. package/src/lib/modules/server/terminal/codex-watcher.ts +4 -1
  104. package/src/lib/modules/server/ws/session-handler.ts +23 -19
  105. package/src/lib/theme.css +33 -0
  106. package/src/lib/types/gemini.ts +100 -0
  107. package/src/lib/types/generated/Sessions.ts +20 -1
  108. package/src/lib/types/index.ts +1 -0
  109. package/src/lib/types/sessions.ts +23 -2
  110. package/src/routes/api/sessions/+server.ts +5 -52
  111. package/src/routes/api/sessions/connect/+server.ts +13 -10
  112. package/src/routes/api/terminals/+server.ts +7 -5
  113. package/src/routes/terminals/+page.svelte +7 -2
  114. package/src/routes/terminals/[id]/+page.svelte +1 -2
  115. package/build/client/_app/immutable/assets/0.DEfoFaGR.css.br +0 -0
  116. package/build/client/_app/immutable/assets/0.DEfoFaGR.css.gz +0 -0
  117. package/build/client/_app/immutable/chunks/Bkqjn62J.js +0 -1
  118. package/build/client/_app/immutable/chunks/Bkqjn62J.js.br +0 -1
  119. package/build/client/_app/immutable/chunks/Bkqjn62J.js.gz +0 -0
  120. package/build/client/_app/immutable/chunks/DOHhmtDH.js.br +0 -0
  121. package/build/client/_app/immutable/chunks/DOHhmtDH.js.gz +0 -0
  122. package/build/client/_app/immutable/chunks/DlS3abGJ.js.br +0 -0
  123. package/build/client/_app/immutable/chunks/DlS3abGJ.js.gz +0 -0
  124. package/build/client/_app/immutable/entry/app.CSJG7N9H.js.br +0 -0
  125. package/build/client/_app/immutable/entry/app.CSJG7N9H.js.gz +0 -0
  126. package/build/client/_app/immutable/entry/start.CTt1901T.js +0 -1
  127. package/build/client/_app/immutable/entry/start.CTt1901T.js.br +0 -2
  128. package/build/client/_app/immutable/entry/start.CTt1901T.js.gz +0 -0
  129. package/build/client/_app/immutable/nodes/0.qOL7xtFn.js.br +0 -0
  130. package/build/client/_app/immutable/nodes/0.qOL7xtFn.js.gz +0 -0
  131. package/build/client/_app/immutable/nodes/1.Di708Ago.js.br +0 -0
  132. package/build/client/_app/immutable/nodes/1.Di708Ago.js.gz +0 -0
  133. package/build/client/_app/immutable/nodes/2.DSM1znqa.js.br +0 -0
  134. package/build/client/_app/immutable/nodes/2.DSM1znqa.js.gz +0 -0
  135. package/build/client/_app/immutable/nodes/3.BPa5fh75.js.br +0 -0
  136. package/build/client/_app/immutable/nodes/3.BPa5fh75.js.gz +0 -0
  137. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js +0 -1
  138. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js.br +0 -0
  139. package/build/client/_app/immutable/nodes/6.B1LwwEF-.js.gz +0 -0
  140. package/build/client/_app/immutable/nodes/7.B7UJd8GQ.js.br +0 -0
  141. package/build/client/_app/immutable/nodes/7.B7UJd8GQ.js.gz +0 -0
  142. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js +0 -2
  143. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js.br +0 -0
  144. package/build/client/_app/immutable/nodes/8.CG0mrgBU.js.gz +0 -0
  145. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js +0 -2
  146. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js.br +0 -0
  147. package/build/client/_app/immutable/nodes/9.KwzWaMHj.js.gz +0 -0
  148. package/build/server/chunks/6-bPDbH1_W.js.map +0 -1
  149. package/build/server/chunks/7-CpBrOkxQ.js.map +0 -1
  150. package/build/server/chunks/8-BRGAVfze.js.map +0 -1
  151. package/build/server/chunks/9-C6xuAb_Y.js.map +0 -1
  152. package/build/server/chunks/_server.ts-BrRZXr-8.js.map +0 -1
  153. package/build/server/chunks/_server.ts-CjK0g9dO.js.map +0 -1
  154. package/build/server/chunks/_server.ts-Cq9_scaV.js.map +0 -1
  155. package/build/server/chunks/_server.ts-D--_NXt2.js.map +0 -1
  156. package/build/server/chunks/opencode-db-path-CRgzBK5U.js.map +0 -1
@@ -14,7 +14,16 @@ import {
14
14
  * @type { SessionSource }
15
15
  * @description Source tool that produced the session
16
16
  */
17
- export type SessionSource = 'claude-code' | 'opencode' | 'codex' | 'gemini';
17
+ export type SessionSource =
18
+ | 'claude-code'
19
+ | 'opencode'
20
+ | 'codex'
21
+ | 'gemini'
22
+ | 'qwen'
23
+ | 'cursor'
24
+ | 'copilot'
25
+ | 'amp'
26
+ | 'iflow';
18
27
 
19
28
  export function decodeSessionSource(rawInput: unknown): SessionSource | null {
20
29
  switch (rawInput) {
@@ -22,6 +31,11 @@ export function decodeSessionSource(rawInput: unknown): SessionSource | null {
22
31
  case 'opencode':
23
32
  case 'codex':
24
33
  case 'gemini':
34
+ case 'qwen':
35
+ case 'cursor':
36
+ case 'copilot':
37
+ case 'amp':
38
+ case 'iflow':
25
39
  return rawInput;
26
40
  }
27
41
  return null;
@@ -33,6 +47,11 @@ export function _decodeSessionSource(rawInput: unknown): SessionSource | undefin
33
47
  case 'opencode':
34
48
  case 'codex':
35
49
  case 'gemini':
50
+ case 'qwen':
51
+ case 'cursor':
52
+ case 'copilot':
53
+ case 'amp':
54
+ case 'iflow':
36
55
  return rawInput;
37
56
  }
38
57
  return;
@@ -8,6 +8,7 @@ export type * from './codex';
8
8
  export type * from './common';
9
9
  export type * from './dashboard';
10
10
  export * from './decision';
11
+ export type * from './gemini';
11
12
  export * from './generated';
12
13
  export type * from './neurolink';
13
14
  export type * from './server';
@@ -3,7 +3,7 @@
3
3
  // classes and `type: string` instead of the string-literal discriminated unions
4
4
  // required at runtime.
5
5
 
6
- import type { MessageRole } from './generated';
6
+ import type { MessageRole, ProjectGroup, SessionSource } from './generated';
7
7
 
8
8
  /** Internal structure from ~/.claude/sessions/<PID>.json */
9
9
  export interface ClaudeSessionFile {
@@ -23,7 +23,16 @@ export interface ConversationMessage {
23
23
  }
24
24
 
25
25
  export interface DetectedProcess {
26
- command: 'claude' | 'codex' | 'gemini' | 'opencode';
26
+ command:
27
+ | 'amp'
28
+ | 'claude'
29
+ | 'codex'
30
+ | 'copilot'
31
+ | 'cursor-agent'
32
+ | 'gemini'
33
+ | 'iflow'
34
+ | 'opencode'
35
+ | 'qwen';
27
36
  cwd: string;
28
37
  kind: string;
29
38
  pid: number;
@@ -34,6 +43,18 @@ export interface DetectedProcess {
34
43
 
35
44
  export type MessagePart = TextPart | ThinkingPart | ToolResultPart | ToolUsePart;
36
45
 
46
+ /** A registered AI-agent provider (see server/sessions/registry.ts). */
47
+ export interface ProviderDef {
48
+ command: string;
49
+ getConversation: (sessionId: string, offset: number, limit: number) => ConversationMessage[];
50
+ isAI: boolean;
51
+ label: string;
52
+ listProjects: () => ProjectGroup[];
53
+ nameSuffix?: string;
54
+ resumeArgs: (sessionId: string) => string[];
55
+ source: SessionSource;
56
+ }
57
+
37
58
  export interface TextPart {
38
59
  content: string;
39
60
  type: 'text';
@@ -1,15 +1,10 @@
1
1
  import type { ProjectGroup } from '$lib/types';
2
2
 
3
3
  import { validateAuth } from '$lib/modules/server/auth';
4
- import { getCodexConversation, listCodexProjects } from '$lib/modules/server/sessions/codex-reader';
5
4
  import {
6
- getSessionConversation,
7
- listProjectsWithSessions,
8
- } from '$lib/modules/server/sessions/jsonl-reader';
9
- import {
10
- getOpenCodeConversation,
11
- listOpenCodeProjects,
12
- } from '$lib/modules/server/sessions/opencode-reader';
5
+ getProviderConversation,
6
+ listAllProviderProjects,
7
+ } from '$lib/modules/server/sessions/registry';
13
8
  import { json } from '@sveltejs/kit';
14
9
 
15
10
  import type { RequestHandler } from './$types';
@@ -25,41 +20,7 @@ function getMergedProjects(): ProjectGroup[] {
25
20
  return cachedProjects;
26
21
  }
27
22
 
28
- const claudeProjects = listProjectsWithSessions();
29
- const openCodeProjects = listOpenCodeProjects();
30
- const codexProjects = listCodexProjects();
31
- const projectsByPath = new Map<string, ProjectGroup>();
32
-
33
- for (const p of claudeProjects) {
34
- projectsByPath.set(p.fullPath, { ...p });
35
- }
36
-
37
- // Merge a provider's projects into the map, deduplicating by absolute path so
38
- // sessions from different agents in the same directory group under one project.
39
- const mergeProvider = (incoming: ProjectGroup[], stripSuffix?: string): void => {
40
- for (const group of incoming) {
41
- const cleanName = stripSuffix ? group.name.replace(stripSuffix, '') : group.name;
42
- const existing = projectsByPath.get(group.fullPath);
43
- if (existing) {
44
- existing.sessions.push(...group.sessions);
45
- existing.sessions.sort(
46
- (a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime()
47
- );
48
- existing.sessionCount = existing.sessions.length;
49
- existing.lastModified = existing.sessions[0]?.modified || existing.lastModified;
50
- existing.name = existing.name.replace(stripSuffix ?? '', '');
51
- } else {
52
- projectsByPath.set(group.fullPath, { ...group, name: cleanName });
53
- }
54
- }
55
- };
56
-
57
- mergeProvider(openCodeProjects, ' (OpenCode)');
58
- mergeProvider(codexProjects);
59
-
60
- cachedProjects = [...projectsByPath.values()].sort(
61
- (a, b) => new Date(b.lastModified).getTime() - new Date(a.lastModified).getTime()
62
- );
23
+ cachedProjects = listAllProviderProjects();
63
24
  cacheTimestamp = now;
64
25
  return cachedProjects;
65
26
  }
@@ -95,15 +56,7 @@ export const GET: RequestHandler = ({ request, url }) => {
95
56
  const claudeProjectDir = matchedProject
96
57
  ? matchedProject.fullPath.replace(/\//g, '-')
97
58
  : undefined;
98
- let messages = getSessionConversation(sessionId, offset, limit, claudeProjectDir);
99
-
100
- // If Claude Code reader found nothing, try OpenCode, then Codex.
101
- if (messages.length === 0) {
102
- messages = getOpenCodeConversation(sessionId, offset, limit);
103
- }
104
- if (messages.length === 0) {
105
- messages = getCodexConversation(sessionId, offset, limit);
106
- }
59
+ const messages = getProviderConversation(sessionId, offset, limit, claudeProjectDir);
107
60
 
108
61
  // Find session info — short-circuit when project is already resolved
109
62
  let sessionInfo = matchedProject?.sessions.find((s) => s.id === sessionId) ?? null;
@@ -1,4 +1,5 @@
1
1
  import { validateAuth } from '$lib/modules/server/auth';
2
+ import { PROVIDER_COMMANDS, resumeArgsForCommand } from '$lib/modules/server/sessions/registry';
2
3
  import { ptyManager } from '$lib/modules/server/terminal/pty-manager';
3
4
  import { toErrorMessage } from '$lib/modules/server/utils/error';
4
5
  import { json } from '@sveltejs/kit';
@@ -34,13 +35,21 @@ export const POST: RequestHandler = async ({ request }) => {
34
35
  return json({ error: 'sessionId is required (string)' }, { status: 400 });
35
36
  }
36
37
 
38
+ // sessionId becomes a process argument (e.g. `codex resume <id>`); restrict it
39
+ // to safe identifier characters to prevent argument/path injection.
40
+ if (!/^[A-Za-z0-9_-]+$/.test(sessionId)) {
41
+ return json({ error: 'Invalid sessionId format' }, { status: 400 });
42
+ }
43
+
37
44
  if (!cwd || typeof cwd !== 'string') {
38
45
  return json({ error: 'cwd is required (string)' }, { status: 400 });
39
46
  }
40
47
 
41
- const VALID_COMMANDS = ['claude', 'opencode', 'codex', 'gemini'];
42
- if (!command || !VALID_COMMANDS.includes(command)) {
43
- return json({ error: `command must be one of: ${VALID_COMMANDS.join(', ')}` }, { status: 400 });
48
+ if (!command || !PROVIDER_COMMANDS.includes(command)) {
49
+ return json(
50
+ { error: `command must be one of: ${PROVIDER_COMMANDS.join(', ')}` },
51
+ { status: 400 }
52
+ );
44
53
  }
45
54
 
46
55
  // --- Validate cwd (same checks as POST /api/terminals) ---
@@ -98,13 +107,7 @@ export const POST: RequestHandler = async ({ request }) => {
98
107
 
99
108
  // --- Build args based on command (resume convention differs per agent CLI) ---
100
109
 
101
- const resumeArgs: Record<string, string[]> = {
102
- claude: ['--resume', sessionId],
103
- codex: ['resume', sessionId],
104
- gemini: [], // Gemini CLI has no session-resume flag; launch fresh in the cwd.
105
- opencode: ['--session', sessionId],
106
- };
107
- const args: string[] = resumeArgs[command] ?? [];
110
+ const args: string[] = resumeArgsForCommand(command, sessionId);
108
111
 
109
112
  try {
110
113
  const terminal = await ptyManager.create(command, args, realCwd, 120, 40);
@@ -1,13 +1,15 @@
1
1
  import { validateAuth } from '$lib/modules/server/auth';
2
+ import { PROVIDER_COMMANDS } from '$lib/modules/server/sessions/registry';
2
3
  import { ptyManager } from '$lib/modules/server/terminal/pty-manager';
3
4
  import { toErrorMessage } from '$lib/modules/server/utils/error';
4
5
  import { json } from '@sveltejs/kit';
5
6
  import { realpathSync, statSync } from 'fs';
6
- import { basename, isAbsolute, relative } from 'path';
7
+ import { isAbsolute, relative } from 'path';
7
8
 
8
9
  import type { RequestHandler } from './$types';
9
10
 
10
- const ALLOWED_COMMANDS = ['zsh', 'bash', 'sh', 'fish', 'claude', 'opencode', 'codex', 'gemini'];
11
+ // Plain shells + every registered AI-agent binary.
12
+ const ALLOWED_COMMANDS = ['zsh', 'bash', 'sh', 'fish', ...PROVIDER_COMMANDS];
11
13
 
12
14
  /** Extract the last non-empty line from a scrollback string. */
13
15
  function lastScrollbackLine(scrollback: string): null | string {
@@ -86,9 +88,9 @@ export const POST: RequestHandler = async ({ request }) => {
86
88
  return json({ error: 'command is required' }, { status: 400 });
87
89
  }
88
90
 
89
- // Issue 4: Command allowlist — only allow known safe commands
90
- const commandBasename = basename(command);
91
- if (!ALLOWED_COMMANDS.includes(commandBasename)) {
91
+ // Command allowlist — only bare allowlisted binary names. Reject any path
92
+ // component so an absolute path like "/tmp/bash" (basename "bash") can't slip through.
93
+ if (command.includes('/') || command.includes('\\') || !ALLOWED_COMMANDS.includes(command)) {
92
94
  return json(
93
95
  { error: `Command not allowed. Allowed: ${ALLOWED_COMMANDS.join(', ')}` },
94
96
  { status: 400 }
@@ -5,7 +5,13 @@
5
5
  import RefreshSvg from '$lib/assets/icons/refresh.svg?raw';
6
6
  import SettingsSvg from '$lib/assets/icons/settings.svg?raw';
7
7
  import TerminalSvg from '$lib/assets/icons/terminal.svg?raw';
8
- import { clearCache, getCached, isShooterConfig, setCache } from '$lib/modules/client/common';
8
+ import {
9
+ AI_COMMANDS,
10
+ clearCache,
11
+ getCached,
12
+ isShooterConfig,
13
+ setCache,
14
+ } from '$lib/modules/client/common';
9
15
  import LaunchSheet from '$lib/modules/client/terminal/LaunchSheet.svelte';
10
16
  import {
11
17
  Banner,
@@ -21,7 +27,6 @@
21
27
 
22
28
  const POLL_INTERVAL_MS = 10_000;
23
29
  const CACHE_KEY = 'shooter_terminals';
24
- const AI_COMMANDS = ['claude', 'opencode', 'codex', 'gemini'];
25
30
  const SHELL_COMMANDS = ['zsh', 'bash', 'sh', 'fish'];
26
31
 
27
32
  let terminals = $state<TerminalListItem[]>([]);
@@ -11,6 +11,7 @@
11
11
  import { goto } from '$app/navigation';
12
12
  import { page } from '$app/stores';
13
13
  import AlertTriangleSvg from '$lib/assets/icons/alert-triangle.svg?raw';
14
+ import { AI_COMMANDS } from '$lib/modules/client/common';
14
15
  import ChatView from '$lib/modules/client/terminal/ChatView.svelte';
15
16
  import CommandPalette from '$lib/modules/client/terminal/CommandPalette.svelte';
16
17
  import ConnectionStatus from '$lib/modules/client/terminal/ConnectionStatus.svelte';
@@ -30,8 +31,6 @@
30
31
 
31
32
  // ------- Constants -------
32
33
 
33
- const AI_COMMANDS = ['claude', 'opencode', 'codex', 'gemini'];
34
-
35
34
  // ------- Reactive state -------
36
35
 
37
36
  let terminal = $state<null | TerminalDetailView>(null);
@@ -1 +0,0 @@
1
- import{s as c,p as o}from"./DOHhmtDH.js";const a={"claude-code":"claude",codex:"codex",gemini:"gemini",opencode:"opencode"},d={"claude-code":"Claude Code",codex:"Codex",gemini:"Gemini",opencode:"OpenCode"};function s(e){return d[e]??"Claude Code"}function u(e){return a[e]??"claude"}const n={get params(){return o.params},get url(){return o.url}};c.updated.check;const t=n;export{s as a,t as p,u as s};
@@ -1 +0,0 @@
1
- � ds9�F������<�6�w&o�>�!�������4�RH� �PGt-Y��^�����B(L{�0�_ g��F��.�V*��R�6��Wi��D,��A�lt�jfK�pW�Z,a<��ç�8%���-|�l�¤��S?���{�e+��*NĝC�Vv3K$�0ܪ<l9�WJֆ��ӈ�Rn�����{������
@@ -1 +0,0 @@
1
- import{l as o,a as r}from"../chunks/DOHhmtDH.js";export{o as load_css,r as start};
@@ -1,2 +0,0 @@
1
- )�import{l as o,a as r}from"../chunks/DOHhmtDH.js";export{o as load_css,r as start};
2
- 
@@ -1 +0,0 @@
1
- import{i as w,a as p,f as m,s as $}from"../chunks/Cg3dlX05.js";import{p as Qe,s as k,q as We,v as Xe,y as Ye,w as et,z as tt,g as e,b as c,$ as st,c as o,d as l,r as a,x as u,A as K,B as Z,t as Q}from"../chunks/DYuMZGL5.js";import{b as rt,e as ve,i as at,B as N,c as W,P as X,d as ot}from"../chunks/DZvnhU_8.js";import{h as nt}from"../chunks/DZQMsHM5.js";import{g as it}from"../chunks/DOHhmtDH.js";import{p as ct,s as ue,a as lt}from"../chunks/Bkqjn62J.js";import{A as dt}from"../chunks/DzuS5Nbr.js";import{B as vt}from"../chunks/Bn-6X1BO.js";import{S as fe,R as ut}from"../chunks/BRqaaL5D.js";import{g as ft,s as pt,c as mt}from"../chunks/xs1Xl3_e.js";import{i as ht}from"../chunks/gQJcRhou.js";import"../chunks/BDcFu3l7.js";import{f as _t}from"../chunks/BLszSzTT.js";import{E as pe}from"../chunks/C5VOyQCG.js";var gt=m('<meta name="description" content="Project sessions sorted by latest update"/>'),yt=m('<div class="loading-container"><!> <!></div>'),bt=m('<div class="project-back-row svelte-urn6fi"><a href="/" class="back-link"><span class="back-arrow">&larr;</span> Back to Projects</a></div> <!>',1),$t=m("<!> Refresh",1),jt=m('<div class="session-card-subtitle"> </div>'),St=m('<span class="connect-dot svelte-urn6fi"></span> Connect',1),Pt=m('<a class="session-card"><div class="session-card-header"><div><h3 class="session-card-title"> </h3> <!></div> <div class="session-card-actions svelte-urn6fi"><!> <!></div></div> <div class="session-stats"><span><strong> </strong> messages</span> <!> <!></div> <div class="session-meta-row svelte-urn6fi"><span class="session-modified svelte-urn6fi"> </span> <span class="session-duration svelte-urn6fi"> </span></div></a>'),xt=m('<div style="text-align: center; padding: 1rem;"><!></div>'),wt=m('<div class="sessions-container svelte-urn6fi"></div> <!>',1),kt=m('<div class="chat-session-header"><div class="chat-session-header-top svelte-urn6fi"><a href="/" class="back-link">&#8592; Back to Projects</a> <!></div> <h1 class="chat-session-title"> </h1> <div class="chat-session-meta"><span class="session-card-subtitle"> </span> <span> </span></div></div> <!>',1),Bt=m('<main class="main"><!> <!></main>');function Jt(me,he){Qe(he,!0);const _e=15e3,D=20;let i=k(null),g=k(!0),h=k(null),L=k(null),R=null,B=k(D),Y=k(We([])),j=k(null);const S=u(()=>ct.url.searchParams.get("id")||""),ge=u(()=>e(i)?e(i).sessions.slice(0,e(B)):[]),ye=u(()=>e(i)?e(B)<e(i).sessions.length:!1),be=u(()=>new Set(e(Y).map(t=>t.sessionId).filter(t=>typeof t=="string")));Xe(()=>{$e();const t=ft(`shooter_project_${e(S)}`);t&&(c(i,t,!0),c(g,!1)),setTimeout(()=>{M(),z()},50),R=setInterval(()=>{e(h)?.apiKey&&e(S)&&(M(),z())},_e)}),Ye(()=>{R&&(clearInterval(R),R=null)});function $e(){try{const t=localStorage.getItem("shooter_config");if(t){const s=JSON.parse(t);ht(s)?c(h,s,!0):(localStorage.removeItem("shooter_config"),c(h,null))}}catch{}}async function M(t=!1){if(!e(h)?.apiKey||!e(S)){c(g,!1);return}e(i)||c(g,!0);try{const d=await fetch(t?"/api/sessions?refresh=true":"/api/sessions",{headers:{Authorization:`Bearer ${e(h).apiKey}`}});if(!d.ok){c(L,`Failed to load project (HTTP ${d.status})`),c(g,!1);return}c(L,null);const f=(await d.json()).projects.find(T=>T.id===e(S))||null;c(i,f,!0),f&&pt(`shooter_project_${e(S)}`,f)}catch(s){console.error("Failed to fetch project:",s)}finally{c(g,!1)}}async function z(){if(e(h)?.apiKey)try{const t=await fetch("/api/sessions/detect",{headers:{Authorization:`Bearer ${e(h).apiKey}`}});if(t.ok){const s=await t.json();c(Y,s.processes,!0)}}catch{}}async function ee(t,s,d){if(t.preventDefault(),t.stopPropagation(),!(!e(h)?.apiKey||!e(i)||e(j))){c(j,s,!0);try{const v=await fetch("/api/sessions/connect",{body:JSON.stringify({command:d,cwd:e(i).fullPath,sessionId:s}),headers:{Authorization:`Bearer ${e(h).apiKey}`,"Content-Type":"application/json"},method:"POST"});if(v.ok){const f=await v.json();it(`/terminals/${f.terminalId}`)}}catch(v){console.error("Failed to connect to session:",v)}finally{c(j,null)}}}async function je(){c(g,!0),c(i,null),c(B,D),mt(`shooter_project_${e(S)}`),await M(!0),await z()}function Se(){c(B,e(B)+D)}function te(t){if(!t)return"";const s=new Date(t);return isNaN(s.getTime())?"":s.toLocaleDateString("en-US",{day:"numeric",hour:"2-digit",minute:"2-digit",month:"short"})}function Pe(t,s){return t.length<=s?t:`${t.slice(0,s).trimEnd()}...`}var F=Bt();nt("urn6fi",t=>{var s=gt();tt(()=>{st.title=`${(e(i)?.name||"Project")??""} - Shooter`}),p(t,s)});var se=o(F);{var xe=t=>{rt(t,{get text(){return e(L)},classes:"banner-error"})};w(se,t=>{e(L)&&t(xe)})}var we=l(se,2);{var ke=t=>{var s=yt(),d=o(s);fe(d,{classes:"shimmer-header"});var v=l(d,2);ve(v,16,()=>Array(4),at,(f,T)=>{fe(f,{classes:"shimmer-card"})}),a(s),p(t,s)},Be=t=>{var s=bt(),d=l(K(s),2);pe(d,{title:"Project Not Found",description:"The requested project could not be found.",icon:f=>{W(f,{get svg(){return dt},classes:"icon-24"})}}),p(t,s)},Te=t=>{var s=kt(),d=K(s),v=o(d),f=l(o(v),2);N(f,{classes:"btn-secondary",onclick:je,get disabled(){return e(g)},children:(y,E)=>{var b=$t(),q=K(b);W(q,{get svg(){return ut},classes:"icon-14"}),Z(),p(y,b)},$$slots:{default:!0}}),a(v);var T=l(v,2),Ce=o(T,!0);a(T);var re=l(T,2),O=o(re),Ie=o(O,!0);a(O);var ae=l(O,2),Ae=o(ae);a(ae),a(re),a(d);var Le=l(d,2);{var Re=y=>{pe(y,{title:"No sessions yet",description:"Sessions for this project will appear here",icon:b=>{W(b,{get svg(){return vt},classes:"icon-24"})}})},Ee=y=>{var E=wt(),b=K(E);ve(b,21,()=>e(ge),P=>P.id,(P,r)=>{var C=Pt(),I=o(C),J=o(I),G=o(J),Ne=o(G,!0);a(G);var De=l(G,2);{var Me=n=>{var _=jt(),A=o(_,!0);a(_),Q(x=>$(A,x),[()=>Pe(e(r).summary,80)]),p(n,_)};w(De,n=>{e(r).summary&&n(Me)})}a(J);var oe=l(J,2),ne=o(oe);{let n=u(()=>_t(e(r).modified));X(ne,{get text(){return e(n)},classes:"pill-session-time"})}var ze=l(ne,2);{var Fe=n=>{{let _=u(()=>e(j)===e(r).id),A=u(()=>e(j)===e(r).id);N(n,{classes:"btn-connect btn-xs",onclick:x=>{ee(x,e(r).id,ue(e(r).source))},get disabled(){return e(_)},get showLoader(){return e(A)},children:(x,Tt)=>{var Ze=St();Z(),p(x,Ze)},$$slots:{default:!0}})}},Oe=u(()=>e(be).has(e(r).id)),qe=n=>{{let _=u(()=>e(j)===e(r).id),A=u(()=>e(j)===e(r).id);N(n,{classes:"btn-resume btn-xs",onclick:x=>{ee(x,e(r).id,ue(e(r).source))},get disabled(){return e(_)},get showLoader(){return e(A)},text:"Resume"})}};w(ze,n=>{e(Oe)?n(Fe):n(qe,-1)})}a(oe),a(I);var H=l(I,2),U=o(H),ie=o(U),Je=o(ie,!0);a(ie),Z(),a(U);var ce=l(U,2);{var Ge=n=>{X(n,{get text(){return`🌿 ${e(r).gitBranch??""}`},classes:"pill-git-branch"})};w(ce,n=>{e(r).gitBranch&&n(Ge)})}var He=l(ce,2);{let n=u(()=>lt(e(r).source));X(He,{get text(){return e(n)},get classes(){return`pill-source-${e(r).source??""}`}})}a(H);var le=l(H,2),V=o(le),Ue=o(V);a(V);var de=l(V,2),Ve=o(de);a(de),a(le),a(C),Q((n,_)=>{ot(C,"href",`/session/${e(r).id??""}?project=${e(S)??""}`),$(Ne,e(r).title),$(Je,e(r).messageCount),$(Ue,`Last updated ${n??""}`),$(Ve,`Created ${_??""}`)},[()=>te(e(r).modified),()=>te(e(r).created)]),p(P,C)}),a(b);var q=l(b,2);{var Ke=P=>{var r=xt(),C=o(r);{let I=u(()=>`Load More (${e(i).sessions.length-e(B)} remaining)`);N(C,{classes:"btn-secondary",onclick:Se,get text(){return e(I)}})}a(r),p(P,r)};w(q,P=>{e(ye)&&P(Ke)})}p(y,E)};w(Le,y=>{e(i).sessions.length===0?y(Re):y(Ee,-1)})}Q(()=>{$(Ce,e(i).name),$(Ie,e(i).fullPath),$(Ae,`${e(i).sessionCount??""} sessions`)}),p(t,s)};w(we,t=>{e(g)&&!e(i)?t(ke):e(i)?t(Te,-1):t(Be,1)})}a(F),p(me,F),et()}export{Jt as component};
@@ -1,2 +0,0 @@
1
- import{p as fe,j as We,i as H,a as h,s as D,f as w,t as Ye}from"../chunks/Cg3dlX05.js";import{p as ke,v as $e,A as _e,w as Me,b as o,c as n,r as s,t as K,g as e,s as k,x as y,q as Ke,d as c,B as he,y as Ue,N as Xe,$ as et}from"../chunks/DYuMZGL5.js";import{T as Ae,s as Le,d as ne,S as tt,e as ge,C as at,f as st,I as rt,B as re,b as Be,c as Ie,i as nt,P as Pe,g as it}from"../chunks/DZvnhU_8.js";import{h as lt}from"../chunks/DZQMsHM5.js";import{g as De}from"../chunks/DOHhmtDH.js";import{R as ot,S as ct}from"../chunks/BRqaaL5D.js";import{S as dt}from"../chunks/CG453M9q.js";import{T as ut}from"../chunks/CSjf4fBs.js";import{c as vt,s as Ee,g as mt}from"../chunks/xs1Xl3_e.js";import{i as pt}from"../chunks/gQJcRhou.js";import"../chunks/BDcFu3l7.js";import{E as Ne}from"../chunks/C5VOyQCG.js";var ft=w("<time> </time>"),ht=w("<time> </time>");function je(ie,d){ke(d,!0);let U=fe(d,"format",3,"long"),$=fe(d,"updateInterval",3,6e4),B=fe(d,"tooltip",3,!1),S=y(()=>d.date instanceof Date?d.date:new Date(d.date)),p=y(()=>e(S).toISOString()),A=y(()=>e(S).toLocaleString(d.locale,{dateStyle:"full",timeStyle:"short"})),T=k("");function C(){const _=Date.now(),g=e(S).getTime()-_,i=Math.abs(g),f=Math.round(i/1e3),q=Math.round(i/6e4),R=Math.round(i/36e5),J=Math.round(i/864e5),z=Math.round(i/6048e5),Z=Math.round(i/2592e6),X=Math.round(i/31536e6),ee=new Intl.RelativeTimeFormat(d.locale,{style:U()});let I,u;f<60?(I="second",u=f):q<60?(I="minute",u=q):R<24?(I="hour",u=R):J<7?(I="day",u=J):z<4?(I="week",u=z):Z<12?(I="month",u=Z):(I="year",u=X);const F=g<0?-1:1;return ee.format(F*u,I)}function x(){o(T,C(),!0)}$e(()=>{if(x(),$()>0){const _=setInterval(x,$());return()=>clearInterval(_)}});var E=We(),le=_e(E);{var oe=_=>{Ae(_,{get text(){return e(A)},children:(v,g)=>{var i=ft(),f=n(i,!0);s(i),K(()=>{Le(i,1,`relative-time ${d.classes??""??""}`,"svelte-o98vko"),ne(i,"datetime",e(p)),ne(i,"data-pw",typeof d.testId=="string"?d.testId:null),D(f,e(T))}),h(v,i)},$$slots:{default:!0}})},ce=_=>{var v=ht(),g=n(v,!0);s(v),K(()=>{Le(v,1,`relative-time ${d.classes??""??""}`,"svelte-o98vko"),ne(v,"datetime",e(p)),ne(v,"data-pw",typeof d.testId=="string"?d.testId:null),D(g,e(T))}),h(_,v)};H(le,_=>{B()?_(oe):_(ce,-1)})}h(ie,E),Me()}var gt=w('<div class="section svelte-plslui"><span class="section-label svelte-plslui">Quick Launch</span> <div class="preset-grid svelte-plslui"></div></div> <div class="section svelte-plslui"><span class="section-label svelte-plslui">Working Directory</span> <!> <div class="custom-cwd-group svelte-plslui"><!></div></div> <!> <!>',1);function _t(ie,d){ke(d,!0);let U=fe(d,"open",15,!1);const $=[{args:[],command:"claude",label:"Claude Code"},{args:[],command:"codex",label:"Codex"},{args:[],command:"gemini",label:"Gemini"},{args:[],command:"opencode",label:"OpenCode"},{args:[],command:"zsh",label:"Shell / zsh"},{args:[],command:"bash",label:"Bash"}];let B=k(0),S=k(Ke([])),p=k(""),A=k(""),T=k(!1),C=k("");$e(()=>{x()});async function x(){try{const v=await fetch("/api/sessions?limit=50&offset=0",{headers:{Authorization:`Bearer ${d.apiKey}`}});if(!v.ok)return;const i=(await v.json()).projects.map(f=>f.fullPath).filter(f=>typeof f=="string"&&f.length>0);o(S,[...new Set(i)],!0),e(S).length>0&&!e(p)&&o(p,e(S)[0],!0)}catch{}}function E(v){o(B,v,!0)}function le(){return $[e(B)].command}function oe(){return $[e(B)].args}function ce(){const v=e(A).trim();return v||(e(p)?e(p):"/tmp")}async function _(){const v=le();if(v){o(T,!0),o(C,"");try{const g=await fetch("/api/terminals",{body:JSON.stringify({args:oe(),command:v,cwd:ce()||void 0}),headers:{Authorization:`Bearer ${d.apiKey}`,"Content-Type":"application/json"},method:"POST"});if(!g.ok){const f=await g.json().catch(()=>({}));o(C,(typeof f.error=="string"?f.error:"")||`Failed to launch (${g.status})`,!0);return}const i=await g.json();d.onLaunch(i)}catch{o(C,"Network error — is the server running?")}finally{o(T,!1)}}}tt(ie,{side:"bottom",title:"New Terminal",get onclose(){return d.onClose},classes:"launch-sheet",get open(){return U()},set open(g){U(g)},content:g=>{var i=gt(),f=_e(i),q=c(n(f),2);ge(q,23,()=>$,u=>u.label,(u,F,M)=>{{let de=y(()=>e(B)===e(M));at(u,{mode:"radio",get selected(){return e(de)},onclick:()=>{E(e(M))},classes:"preset-choice",children:(ve,we)=>{he();var ue=Ye();K(()=>D(ue,e(F).label)),h(ve,ue)},$$slots:{default:!0}})}}),s(q),s(f);var R=c(f,2),J=c(n(R),2);{let u=y(()=>e(S).length>0?e(S).map(M=>({id:M,label:M})):[{id:"",label:"No recent projects"}]),F=y(()=>e(p)?[e(p)]:e(S).length>0?[e(S)[0]]:[""]);st(J,{get items(){return e(u)},get value(){return e(F)},placeholder:"Select a project",onchange:M=>{o(p,M[0]||"",!0)},classes:"launch-select"})}var z=c(J,2),Z=n(z);rt(Z,{label:"Or enter a custom path",dataType:"text",placeholder:"/path/to/project",classes:"input-mono launch-input",get value(){return e(A)},set value(u){o(A,u,!0)}}),s(z),s(R);var X=c(R,2);{let u=y(()=>e(T)?"Launching...":"Launch Terminal");re(X,{classes:"btn-launch",get disabled(){return e(T)},onclick:_,get showLoader(){return e(T)},get text(){return e(u)}})}var ee=c(X,2);{var I=u=>{Be(u,{get text(){return e(C)},classes:"banner-error launch-error-banner"})};H(ee,u=>{e(C)&&u(I)})}h(g,i)},$$slots:{content:!0}}),Me()}var wt=w('<meta name="description" content="Active terminal sessions on this machine"/>'),xt=w("<!> Refresh",1),bt=w('<span class="plus-icon svelte-1ewpmn2">+</span> New Terminal',1),yt=w('<div class="loading-container"></div>'),St=w('<span class="plus-icon svelte-1ewpmn2">+</span> New Terminal',1),Tt=w('<span class="terminal-cwd svelte-1ewpmn2"> </span>'),Ct=w('<div class="terminal-preview svelte-1ewpmn2"><span class="terminal-preview-text svelte-1ewpmn2"> </span></div>'),It=w('<a class="terminal-card svelte-1ewpmn2"><div class="terminal-card-header svelte-1ewpmn2"><div class="terminal-card-left svelte-1ewpmn2"><span class="status-indicator status-running svelte-1ewpmn2"><span></span></span> <span class="terminal-command svelte-1ewpmn2"> </span> <!></div> <!></div> <div class="terminal-card-meta svelte-1ewpmn2"><!> <span class="terminal-pid svelte-1ewpmn2"> </span></div> <!></a>'),Pt=w('<span class="terminal-cwd svelte-1ewpmn2"> </span>'),At=w('<div class="terminal-preview svelte-1ewpmn2"><span class="terminal-preview-text svelte-1ewpmn2"> </span></div>'),Lt=w('<a class="terminal-card terminal-card-exited svelte-1ewpmn2"><div class="terminal-card-header svelte-1ewpmn2"><div class="terminal-card-left svelte-1ewpmn2"><span class="status-indicator status-exited svelte-1ewpmn2"><span class="status-dot-static"></span></span> <span class="terminal-command svelte-1ewpmn2"> </span> <!> <!></div> <div class="terminal-card-right svelte-1ewpmn2"><!> <!></div></div> <div class="terminal-card-meta svelte-1ewpmn2"><!></div> <!></a>'),kt=w('<div class="terminals-container svelte-1ewpmn2"><!> <!></div>'),$t=w('<main class="main"><div class="page-header"><div class="page-header-content"><div><h1 class="page-title">Terminals</h1> <p class="page-description">Active terminal sessions on this machine</p></div> <div class="page-actions"><!> <!></div></div></div> <!> <!></main> <!>',1);function qt(ie,d){ke(d,!0);const U=1e4,$="shooter_terminals",B=["claude","opencode","codex","gemini"],S=["zsh","bash","sh","fish"];let p=k(Ke([])),A=k(!1),T=!1,C=k(null),x=k(null),E=null;const le=y(()=>e(p).filter(t=>t.status==="running")),oe=y(()=>e(p).filter(t=>t.status==="exited"));$e(()=>{ce();const t=mt($,1e4);t&&(o(p,t,!0),o(A,!1)),_(),E=setInterval(()=>{e(x)?.apiKey&&_()},U)}),Ue(()=>{E&&(clearInterval(E),E=null)});function ce(){try{const t=localStorage.getItem("shooter_config");if(t){const a=JSON.parse(t);pt(a)?o(x,a,!0):(localStorage.removeItem("shooter_config"),o(x,null))}}catch{}}async function _(){if(!(!e(x)?.apiKey||T)){T=!0,e(p).length===0&&o(A,!0);try{const a=await fetch("/api/terminals",{headers:{Authorization:`Bearer ${e(x).apiKey}`}});if(!a.ok){o(C,`Failed to load terminals (HTTP ${a.status})`);return}o(C,null);const r=await a.json();o(p,r.terminals.map(b=>({...b,lastOutput:b.lastOutput??null})),!0),Ee($,e(p))}catch(t){o(C,"Failed to load terminals"),console.error("Failed to fetch terminals:",t)}finally{o(A,!1),T=!1}}}async function v(){o(A,!0),vt($),await _()}function g(){De("/config")}let i=k(!1);function f(){o(i,!0)}function q(){o(i,!1)}function R(t){o(i,!1),De(`/terminals/${t.id}`)}function J(t){const a=t.split("/").pop()||t;return B.includes(a)?"ai":(S.includes(a),"shell")}function z(t){return t.status==="exited"?{class:"pill-badge-ended",label:"ENDED"}:J(t.command)==="ai"?{class:"pill-badge-ai",label:"AI"}:{class:"pill-badge-shell",label:"SHELL"}}function Z(t,a=40){if(t.length<=a)return t;const r=t.split("/");return r.length<=3?t:`${r[0]}/.../${r.slice(-2).join("/")}`}function X(t){return t.replace(/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b\[[\?]?[0-9;]*[a-zA-Z]|\x1b/g,"").replace(/[\x00-\x1f]/g,"").trim()}function ee(t,a=80){if(!t)return"";const r=t.split(`
2
- `).map(P=>X(P)).filter(P=>P.trim()),b=r[r.length-1]||"";return b.length<=a?b:`${b.slice(0,a)}...`}function I(t){return t.split("/").pop()||t}async function u(t,a){if(t.preventDefault(),t.stopPropagation(),!!e(x)?.apiKey)try{(await fetch(`/api/terminals/${a}`,{headers:{Authorization:`Bearer ${e(x).apiKey}`},method:"DELETE"})).ok&&(o(p,e(p).filter(b=>b.id!==a),!0),Ee($,e(p)))}catch(r){console.error("Failed to remove terminal:",r)}}var F=$t();lt("1ewpmn2",t=>{var a=wt();Xe(()=>{et.title="Terminals - Shooter"}),h(t,a)});var M=_e(F),de=n(M),ve=n(de),we=c(n(ve),2),ue=n(we);re(ue,{classes:"btn-secondary",onclick:v,get disabled(){return e(A)},children:(t,a)=>{var r=xt(),b=_e(r);Ie(b,{get svg(){return ot},classes:"icon-14"}),he(),h(t,r)},$$slots:{default:!0}});var Re=c(ue,2);re(Re,{classes:"btn-primary",onclick:f,children:(t,a)=>{var r=bt();he(),h(t,r)},$$slots:{default:!0}}),s(we),s(ve),s(de);var Oe=c(de,2);{var ze=t=>{Be(t,{get text(){return e(C)},classes:"banner-error"})};H(Oe,t=>{e(C)&&t(ze)})}var Fe=c(Oe,2);{var He=t=>{var a=yt();ge(a,20,()=>Array(4),nt,(r,b)=>{ct(r,{classes:"shimmer-card"})}),s(a),h(t,a)},qe=t=>{Ne(t,{title:"Configuration Required",description:"Set up your API credentials to view terminal sessions",icon:r=>{Ie(r,{get svg(){return dt},classes:"icon-24"})},children:(r,b)=>{re(r,{classes:"btn-primary",onclick:g,text:"Configure Settings"})}})},Je=t=>{Ne(t,{title:"No terminals",description:"Launch a new terminal session to get started. Terminal sessions will appear here once created.",icon:r=>{Ie(r,{get svg(){return ut},classes:"icon-24"})},children:(r,b)=>{re(r,{classes:"btn-primary",onclick:f,children:(P,l)=>{var G=St();he(),h(P,G)},$$slots:{default:!0}})}})},Ze=t=>{var a=kt(),r=n(a);ge(r,17,()=>e(le),P=>P.id,(P,l)=>{const G=y(()=>z(e(l)));var N=It(),Q=n(N),V=n(Q),W=n(V),xe=n(W);s(W);var te=c(W,2),be=n(te,!0);s(te);var ye=c(te,2);Pe(ye,{get text(){return e(G).label},get classes(){return e(G).class}}),s(V);var me=c(V,2);je(me,{get date(){return e(l).createdAt},format:"narrow",classes:"terminal-time"}),s(Q);var ae=c(Q,2),pe=n(ae);{let m=y(()=>e(l).currentCwd||e(l).cwd);Ae(pe,{get text(){return e(m)},position:"bottom",children:(L,O)=>{var j=Tt(),Y=n(j,!0);s(j),K(Ve=>D(Y,Ve),[()=>Z(e(l).currentCwd||e(l).cwd)]),h(L,j)},$$slots:{default:!0}})}var se=c(pe,2),Se=n(se);s(se),s(ae);var Te=c(ae,2);{var Ce=m=>{var L=Ct(),O=n(L),j=n(O,!0);s(O),s(L),K(Y=>D(j,Y),[()=>ee(e(l).lastOutput)]),h(m,L)};H(Te,m=>{e(l).lastOutput&&m(Ce)})}s(N),K(m=>{ne(N,"href",`/terminals/${e(l).id??""}`),Le(xe,1,it(e(l).isActive?"status-dot-active":"status-dot-idle")),D(be,m),D(Se,`PID ${e(l).pid??""}`)},[()=>I(e(l).command)]),h(P,N)});var b=c(r,2);ge(b,17,()=>e(oe),P=>P.id,(P,l)=>{const G=y(()=>z(e(l)));var N=Lt(),Q=n(N),V=n(Q),W=c(n(V),2),xe=n(W,!0);s(W);var te=c(W,2);Pe(te,{get text(){return e(G).label},get classes(){return e(G).class}});var be=c(te,2);{var ye=m=>{{let L=y(()=>e(l).exitCode!==0?"pill-exit-error":"pill-exit-ok");Pe(m,{get text(){return`exit ${e(l).exitCode??""}`},get classes(){return e(L)}})}};H(be,m=>{e(l).exitCode!==null&&m(ye)})}s(V);var me=c(V,2),ae=n(me);{let m=y(()=>e(l).exitedAt||e(l).createdAt);je(ae,{get date(){return e(m)},format:"narrow",classes:"terminal-time"})}var pe=c(ae,2);re(pe,{classes:"btn-ghost btn-sm btn-remove",onclick:m=>{u(m,e(l).id)},text:"×"}),s(me),s(Q);var se=c(Q,2),Se=n(se);Ae(Se,{get text(){return e(l).cwd},position:"bottom",children:(m,L)=>{var O=Pt(),j=n(O,!0);s(O),K(Y=>D(j,Y),[()=>Z(e(l).cwd)]),h(m,O)},$$slots:{default:!0}}),s(se);var Te=c(se,2);{var Ce=m=>{var L=At(),O=n(L),j=n(O,!0);s(O),s(L),K(Y=>D(j,Y),[()=>ee(e(l).lastOutput)]),h(m,L)};H(Te,m=>{e(l).lastOutput&&m(Ce)})}s(N),K(m=>{ne(N,"href",`/terminals/${e(l).id??""}`),D(xe,m)},[()=>I(e(l).command)]),h(P,N)}),s(a),h(t,a)};H(Fe,t=>{e(A)&&e(p).length===0?t(He):e(x)?.apiKey?e(p).length===0?t(Je,2):t(Ze,-1):t(qe,1)})}s(M);var Ge=c(M,2);{var Qe=t=>{_t(t,{get apiKey(){return e(x).apiKey},onClose:q,onLaunch:R,get open(){return e(i)},set open(a){o(i,a,!0)}})};H(Ge,t=>{e(x)?.apiKey&&t(Qe)})}h(ie,F),Me()}export{qt as component};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../chunks/CR6bkGJW.js","../chunks/PPVm8Dsz.js"])))=>i.map(i=>d[i]);
2
- import{_ as ke}from"../chunks/PPVm8Dsz.js";import{p as Se,i as q,s as rt,a as S,f as C,j as xe,c as Ce,e as Ie,g as Nt}from"../chunks/Cg3dlX05.js";import{p as ot,w as it,g as t,x as h,c as k,d as c,r as g,t as H,A as Ft,s as m,q as Te,v as Ee,y as je,z as Ke,b as n,$ as Me}from"../chunks/DYuMZGL5.js";import{h as qe}from"../chunks/DZQMsHM5.js";import{m as Ae,s as ft,d as zt,B as U,e as Bt,M as De,K as Pe,P as Ot,k as Rt,c as $e,T as Lt,n as Ne,I as Oe}from"../chunks/DZvnhU_8.js";import{g as tt}from"../chunks/DOHhmtDH.js";import{p as Re}from"../chunks/DlS3abGJ.js";import{A as Le}from"../chunks/DzuS5Nbr.js";import{C as We}from"../chunks/Pw0jDB7M.js";import{E as Fe}from"../chunks/C5VOyQCG.js";function ze(y,o){ot(o,!0);let b=Se(o,"open",15,!1);const u=h(()=>o.commands.map((w,a)=>({label:w.label,value:String(a)})));function T(w){const a=parseInt(w.value,10);o.commands[a]&&o.commands[a].action()}Ae(y,{get items(){return t(u)},placeholder:"Type a command...",emptyText:"No matching commands",onselect:T,get onclose(){return o.onClose},classes:"command-palette",get open(){return b()},set open(w){b(w)}}),it()}var Be=C('<div><span></span> <span class="status-label svelte-1cg9pai"> </span> <!></div>');function He(y,o){const b=h(()=>o.status==="connected"?"Connected":o.status==="reconnecting"?"Reconnecting...":"Disconnected");var u=Be();let T;var w=k(u),a=c(w,2),O=k(a,!0);g(a);var A=c(a,2);{var E=x=>{U(x,{classes:"btn-ghost btn-sm btn-retry",get onclick(){return o.onretry},text:"Retry"})};q(A,x=>{o.status==="disconnected"&&o.onretry&&x(E)})}g(u),H(()=>{T=ft(u,1,"connection-status svelte-1cg9pai",null,T,{reconnecting:o.status==="reconnecting",disconnected:o.status==="disconnected",connected:o.status==="connected"}),zt(u,"aria-label",`Connection: ${o.status??""}`),ft(w,1,`conn-dot ${o.status??""}`,"svelte-1cg9pai"),rt(O,t(b))}),S(y,u)}const Ht=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.userAgent),Wt=Ht?"⌘":"Ctrl";function Ue(y){function o(b){if((Ht?b.metaKey:b.ctrlKey)&&!Ge()&&b.key==="/"){b.preventDefault(),b.stopPropagation(),y.onHelp();return}}return window.addEventListener("keydown",o,!0),{destroy(){window.removeEventListener("keydown",o,!0)}}}function Je(){return[{description:"Command palette",keys:`${Wt}+K`},{description:"Keyboard shortcuts",keys:`${Wt}+/`}]}function Ge(){const y=document.activeElement;if(!y)return!1;const o=y.tagName;return!!(o==="INPUT"||o==="TEXTAREA"||y.isContentEditable||y.closest(".xterm"))}var Ve=C('<div class="quick-keys svelte-64qat5" role="toolbar" aria-label="Quick terminal keys"></div>');function Qe(y,o){ot(o,!0);const b=[{escape:"",label:"Ctrl+C"},{escape:" ",label:"Tab"},{escape:"\x1B[A",label:"↑"},{escape:"\x1B[B",label:"↓"},{escape:"\x1B",label:"Esc"},{escape:"",label:"Ctrl+D"},{escape:"",label:"Ctrl+Z"}];var u=Ve();Bt(u,21,()=>b,T=>T.label,(T,w)=>{U(T,{classes:"btn-quick-key",onclick:()=>{o.onKey(t(w).escape)},get text(){return t(w).label}})}),g(u),S(y,u),it()}var Xe=C('<div class="shortcut-row svelte-1u7lstk"><span class="shortcut-desc svelte-1u7lstk"> </span> <!></div>'),Ze=C('<div class="shortcuts-list svelte-1u7lstk"></div>');function Ye(y,o){ot(o,!0);const b=Je();var u=xe(),T=Ft(u);{var w=a=>{De(a,{header:{text:"Keyboard Shortcuts"},get onoverlayClick(){return o.onClose},classes:"shortcuts-modal",content:A=>{var E=Ze();Bt(E,21,()=>b,x=>x.keys,(x,F)=>{var R=Xe(),d=k(R),j=k(d,!0);g(d);var P=c(d,2);Pe(P,{get keys(){return t(F).keys},classes:"shortcut-kbd"}),g(R),H(()=>rt(j,t(F).description)),S(x,R)}),g(E),S(A,E)},$$slots:{content:!0}})};q(T,a=>{o.open&&a(w)})}S(y,u),it()}var tn=C('<meta name="description" content="Interactive terminal session"/>'),en=C('<div class="term-page svelte-1tubujq"><div class="term-topbar svelte-1tubujq"><div class="skeleton" style="width: 120px; height: 20px;"></div></div> <div class="term-body-loading svelte-1tubujq"><div class="skeleton" style="width: 100%; height: 100%;"></div></div></div>'),nn=C('<main class="main"><div class="session-back-row"><a href="/terminals" class="back-link"><span class="back-arrow">&larr;</span> Terminals</a></div> <!></main>'),sn=C("<span></span>"),an=C('<span class="term-cwd svelte-1tubujq"> </span>'),rn=C('<a class="term-session-link svelte-1tubujq" title="View session history">Session</a>'),on=C('<div class="term-input-area svelte-1tubujq"><!> <div class="term-input-bar svelte-1tubujq"><!> <!></div></div>'),ln=C('<div class="term-exited-bar svelte-1tubujq"><span>Process exited</span> <!></div>'),cn=C('<div class="term-page svelte-1tubujq"><div class="term-topbar svelte-1tubujq"><div class="term-topbar-left svelte-1tubujq"><a href="/terminals" class="term-back svelte-1tubujq" aria-label="Back to terminals">&larr;</a> <span class="term-command-name svelte-1tubujq"> </span> <!> <!> <!> <!> <!></div> <div class="term-topbar-right svelte-1tubujq"><!> <!> <!></div></div> <div class="term-body svelte-1tubujq"></div> <!> <div class="term-chat-body svelte-1tubujq"><!></div> <!></div>'),un=C("<!> <!> <!>",1);function _n(y,o){ot(o,!0);const b=()=>Ie(Re,"$page",u),[u,T]=Ce(),w=["claude","opencode","codex","gemini"];let a=m(null),O=m(!0),A=m(null),E=m(!1),x=m(!1),F=m(!1),R=m(null),d=m("raw"),j=m("disconnected"),P=m("disconnected"),z=m(""),D=m(Te([])),vt=m(!1),J=m(null),lt=m(null),$=null,pt=null,L=m(!1),ct=m(!1),f=null,W=null,v=!1;const G=h(()=>b().params.id),V=h(()=>t(a)?w.includes((t(a).command.split("/").pop()||"").toLowerCase()):!1),B=h(()=>t(a)?.status==="running"),mt=h(()=>t(a)?.command.split("/").pop()||"terminal"),Ut=h(()=>t(V)?"AI":"SHELL"),Jt=h(()=>t(V)?"pill-badge-ai":"pill-badge-shell"),Gt=["Raw","Chat"],ht=h(()=>t(d)==="raw"?t(j):t(P)),Vt=h(()=>t(d)==="raw"?0:1),gt=h(()=>Xt(t(R)||t(a)?.cwd||"")),Qt=h(()=>{const e=[{action:()=>{tt("/")},label:"Go to Home"},{action:()=>{tt("/terminals")},label:"Go to Terminals"},{action:()=>{tt("/config")},label:"Go to Settings"},{action:()=>{n(L,!0)},label:"Show keyboard shortcuts"}];return t(B)&&e.push({action:()=>{bt()},label:"Kill terminal"}),e});function Xt(e){if(!e)return"";const s="";let r=e;if(typeof navigator<"u"){const l=e.split("/");l.length>=3&&l[1]==="Users"?r=`~/${l.slice(3).join("/")}`:l.length>=3&&l[1]==="home"&&(r=`~/${l.slice(3).join("/")}`)}if(r.length>30){const l=r.split("/");if(l.length>2)return`.../${l.slice(-2).join("/")}`}return r||s}function Q(){try{const e=localStorage.getItem("shooter_config");if(!e)return null;const s=JSON.parse(e);return typeof s?.apiKey=="string"&&s.apiKey?s:null}catch{return null}}async function Zt(){const e=Q();if(!e){n(A,"No configuration found. Please configure settings first."),n(O,!1);return}try{const s=await fetch(`/api/terminals/${t(G)}`,{headers:{Authorization:`Bearer ${e.apiKey}`}});if(!s.ok){n(A,s.status===404?"Terminal not found":"Failed to load terminal",!0),n(O,!1);return}n(a,await s.json(),!0)}catch{n(A,"Failed to connect to server")}n(O,!1)}async function yt(){const e=Q();if(!e)return null;try{const s=await fetch("/api/ws-ticket",{headers:{Authorization:`Bearer ${e.apiKey}`},method:"POST"});return s.ok?(await s.json()).ticket:null}catch{return null}}async function bt(){if(!t(a)||t(E))return;const e=Q();if(e){n(E,!0);try{(await fetch(`/api/terminals/${t(G)}`,{headers:{Authorization:`Bearer ${e.apiKey}`},method:"DELETE"})).ok?tt("/terminals"):n(E,!1)}catch{n(E,!1)}}}async function Yt(){if(!t(a)||t(x))return;const e=Q();if(e){n(x,!0);try{(await fetch(`/api/terminals/${t(G)}`,{headers:{Authorization:`Bearer ${e.apiKey}`},method:"DELETE"})).ok?tt("/terminals"):n(x,!1)}catch{n(x,!1)}}}async function ut(){if(!t(J)||!t(a)||v)return;const s=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}${t(a).ws}`,r=async()=>{const l=await yt();if(!l)throw new Error("Failed to obtain WebSocket ticket");return l};try{const{createTerminal:l}=await ke(async()=>{const{createTerminal:K}=await import("../chunks/CR6bkGJW.js");return{createTerminal:K}},__vite__mapDeps([0,1]),import.meta.url);if(v||!t(J))return;const p=await l({apiKey:Q()?.apiKey,container:t(J),fontSize:window.innerWidth<768?12:14,getTicket:r,onActivity:K=>{v||n(F,K,!0)},onCwd:K=>{v||n(R,K,!0)},onDisconnect:()=>{v||n(j,"reconnecting")},onExit:K=>{!v&&t(a)&&(n(a,{...t(a),exitCode:K,exitedAt:new Date().toISOString(),status:"exited"},!0),n(j,"disconnected"))},onReconnect:()=>{v||n(j,"connected")},terminalId:t(G),wsUrl:s});if(v){p.dispose();return}$=p,n(j,"connected")}catch(l){console.error("Failed to initialize terminal:",l),n(j,"disconnected")}}function wt(){$&&($.dispose(),$=null)}async function et(){if(!t(a)||v||f&&(f.readyState===WebSocket.OPEN||f.readyState===WebSocket.CONNECTING))return;const e=await yt();if(!e||v||!t(a)){n(P,"disconnected");return}const r=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}${t(a).sessionWs}?ticket=${e}`;f=new WebSocket(r),f.onopen=()=>{v||(n(P,"connected"),f?.send(JSON.stringify({sessionId:t(G),type:"subscribe"})))},f.onmessage=l=>{if(!v)try{const p=JSON.parse(l.data);te(p)}catch{}},f.onclose=()=>{!v&&t(a)?.status==="running"&&(n(P,"reconnecting"),W&&clearTimeout(W),W=setTimeout(()=>{W=null,!v&&t(a)?.status==="running"&&et()},2e3))},f.onerror=()=>{v||n(P,"disconnected")}}function X(){return t(D)}function te(e){if(e.type==="history"){const s=e.messages||[];n(D,s.map(r=>({id:r.id,parts:r.content,role:r.role,timestamp:r.timestamp})),!0)}else if(e.type==="message"){const s=typeof e.role=="string"?e.role:"assistant",r=s==="user"?"user":s==="system"?"system":"assistant",l={id:`msg-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,parts:e.content||[],role:r,timestamp:(typeof e.timestamp=="string"?e.timestamp:"")||new Date().toISOString()};n(D,X().concat(l),!0)}else if(e.type==="tool-use"){const s={id:e.id||`tool-${Date.now()}`,input:e.input||{},toolName:e.name,type:"tool_use"},r={id:`tool-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,parts:[s],role:"assistant",timestamp:new Date().toISOString()};n(D,X().concat(r),!0)}else if(e.type==="tool-result"){const s={isError:e.isError||!1,output:e.output||"",toolUseId:e.id,type:"tool_result"},r={id:`result-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,parts:[s],role:"system",timestamp:new Date().toISOString()};n(D,X().concat(r),!0)}else if(e.type==="thinking"){const s={content:e.text||"",type:"thinking"},r=X(),l=r.length-1;if(l>=0&&r[l].role==="assistant"){const p=r[l],K={id:p.id,parts:p.parts.concat(s),role:p.role,timestamp:p.timestamp};n(D,[...r.slice(0,l),K],!0)}else{const p={id:`think-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,parts:[s],role:"assistant",timestamp:new Date().toISOString()};n(D,r.concat(p),!0)}}else if(e.type==="error"){const s={content:e.message||"Unknown error",type:"text"},r={id:`err-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,parts:[s],role:"system",timestamp:new Date().toISOString()};n(D,X().concat(r),!0)}else e.type==="session-end"&&(n(vt,!0),t(a)&&n(a,{...t(a),status:"exited"},!0))}function _t(){W&&(clearTimeout(W),W=null),f&&(f.onclose=null,f.close(),f=null)}function kt(){t(z).trim()&&($&&t(j)==="connected"&&$.sendInput(`${t(z)}\r`),n(z,""),t(lt)?.focus())}function ee(e){!e.trim()||f?.readyState!==WebSocket.OPEN||f.send(JSON.stringify({text:e,type:"send-input"}))}function St(){f?.readyState===WebSocket.OPEN&&f.send(JSON.stringify({type:"cancel"}))}function ne(e){t(d)==="raw"?$&&t(j)==="connected"&&$.sendInput(e):t(d)==="chat"&&e===""&&St()}function se(e){e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),kt())}let nt=!1,st=!1;function ae(e){e!==t(d)&&(n(d,e,!0),e==="raw"&&!nt?(requestAnimationFrame(()=>{ut()}),nt=!0):e==="chat"&&!st&&(et(),st=!0))}function re(){t(d)==="raw"?(wt(),n(j,"reconnecting"),ut(),nt=!0):(_t(),n(P,"reconnecting"),et(),st=!0)}Ee(async()=>{await Zt(),!v&&(pt=Ue({onHelp:()=>{n(L,!t(L))}}),!(!t(a)||t(A))&&(t(V)&&window.innerWidth<768?n(d,"chat"):n(d,"raw"),t(d)==="raw"?(requestAnimationFrame(()=>{ut()}),nt=!0):(et(),st=!0)))}),je(()=>{v=!0,wt(),_t(),pt?.destroy()});var xt=un();qe("1tubujq",e=>{var s=tn();Ke(()=>{Me.title=`${t(mt)??""} - Terminal - Shooter`}),S(e,s)});var Ct=Ft(xt);{var oe=e=>{var s=en();S(e,s)},ie=e=>{var s=nn(),r=c(k(s),2);Fe(r,{title:"Error",get description(){return t(A)},icon:p=>{$e(p,{get svg(){return Le},classes:"icon-24"})}}),g(s),S(e,s)},le=e=>{var s=cn(),r=k(s),l=k(r),p=c(k(l),2),K=k(p,!0);g(p);var Tt=c(p,2);Ot(Tt,{get text(){return t(Ut)},get classes(){return t(Jt)}});var Et=c(Tt,2);{var ue=i=>{{let _=h(()=>t(F)?"Active":"Idle");Lt(i,{get text(){return t(_)},position:"bottom",children:(M,N)=>{var I=sn();H(()=>ft(I,1,`activity-dot ${t(F)?"activity-active":"activity-idle"}`,"svelte-1tubujq")),S(M,I)},$$slots:{default:!0}})}};q(Et,i=>{t(B)&&i(ue)})}var jt=c(Et,2);{var de=i=>{{let _=h(()=>t(R)||t(a)?.cwd||"");Lt(i,{get text(){return t(_)},position:"bottom",children:(M,N)=>{var I=an(),Z=k(I,!0);g(I),H(()=>rt(Z,t(gt))),S(M,I)},$$slots:{default:!0}})}};q(jt,i=>{t(gt)&&i(de)})}var Kt=c(jt,2);He(Kt,{get status(){return t(ht)},onretry:re});var fe=c(Kt,2);{var ve=i=>{const _=h(()=>t(a).sessionFile??"");var M=rn();H(N=>zt(M,"href",`/session/${N??""}`),[()=>t(_).split(/[\\/]/).pop()?.replace(".jsonl","")||""]),S(i,M)};q(fe,i=>{t(V)&&t(a)?.sessionFile&&i(ve)})}g(l);var Mt=c(l,2),qt=k(Mt);{var pe=i=>{Ne(i,{get items(){return Gt},get activeIndex(){return t(Vt)},onchange:_=>{ae(_===0?"raw":"chat")},classes:"term-tabs"})};q(qt,i=>{t(V)&&i(pe)})}var At=c(qt,2);U(At,{classes:"term-shortcuts-btn",onclick:()=>{n(L,!t(L))},text:"?",ariaLabel:"Keyboard shortcuts"});var me=c(At,2);{var he=i=>{U(i,{classes:"btn-danger btn-sm",onclick:bt,get disabled(){return t(E)},get showLoader(){return t(E)},text:"Kill"})},ge=i=>{U(i,{classes:"btn-secondary btn-sm",onclick:Yt,get disabled(){return t(x)},get showLoader(){return t(x)},text:"Remove"})};q(me,i=>{t(B)?i(he):i(ge,-1)})}g(Mt),g(r);var dt=c(r,2);let Dt;Nt(dt,i=>n(J,i),()=>t(J));var Pt=c(dt,2);{var ye=i=>{var _=on(),M=k(_);Qe(M,{onKey:ne});var N=c(M,2),I=k(N);Nt(Oe(I,{dataType:"text",useTextArea:!0,placeholder:"Type command... (Shift+Enter for new line)",classes:"input-mono term-input-field",onKeyDown:se,get value(){return t(z)},set value(Y){n(z,Y,!0)}}),Y=>n(lt,Y,!0),()=>t(lt));var Z=c(I,2);{let Y=h(()=>!t(z).trim());U(Z,{classes:"btn-primary btn-send",onclick:kt,get disabled(){return t(Y)},text:"↵"})}g(N),g(_),S(i,_)};q(Pt,i=>{t(B)&&t(d)==="raw"&&i(ye)})}var at=c(Pt,2);let $t;var be=k(at);We(be,{get messages(){return t(D)},get connectionState(){return t(ht)},get sessionEnded(){return t(vt)},get showInput(){return t(B)},onSendInput:ee,onCancel:St}),g(at);var we=c(at,2);{var _e=i=>{var _=ln(),M=c(k(_),2);{var N=I=>{{let Z=h(()=>t(a).exitCode!==0?"pill-exit-error":"pill-exit-ok");Ot(I,{get text(){return`code ${t(a).exitCode??""}`},get classes(){return t(Z)}})}};q(M,I=>{t(a).exitCode!==null&&I(N)})}g(_),S(i,_)};q(we,i=>{t(B)||i(_e)})}g(s),H(()=>{rt(K,t(mt)),Dt=Rt(dt,"",Dt,{display:t(d)==="raw"?"flex":"none"}),$t=Rt(at,"",$t,{display:t(d)==="chat"?"flex":"none"})}),S(e,s)};q(Ct,e=>{t(O)?e(oe):t(A)?e(ie,1):t(a)&&e(le,2)})}var It=c(Ct,2);Ye(It,{get open(){return t(L)},onClose:()=>{n(L,!1)}});var ce=c(It,2);ze(ce,{get commands(){return t(Qt)},onClose:()=>{n(ct,!1)},get open(){return t(ct)},set open(e){n(ct,e,!0)}}),S(y,xt),it(),T()}export{_n as component};
@@ -1 +0,0 @@
1
- {"version":3,"file":"6-bPDbH1_W.js","sources":["../../../.svelte-kit/adapter-node/nodes/6.js"],"sourcesContent":["\n\nexport const index = 6;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/project/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/6.B1LwwEF-.js\",\"_app/immutable/chunks/Cg3dlX05.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/DZvnhU_8.js\",\"_app/immutable/chunks/DZQMsHM5.js\",\"_app/immutable/chunks/DOHhmtDH.js\",\"_app/immutable/chunks/Bkqjn62J.js\",\"_app/immutable/chunks/DzuS5Nbr.js\",\"_app/immutable/chunks/Bn-6X1BO.js\",\"_app/immutable/chunks/BRqaaL5D.js\",\"_app/immutable/chunks/xs1Xl3_e.js\",\"_app/immutable/chunks/gQJcRhou.js\",\"_app/immutable/chunks/BDcFu3l7.js\",\"_app/immutable/chunks/BLszSzTT.js\",\"_app/immutable/chunks/C5VOyQCG.js\"];\nexport const stylesheets = [\"_app/immutable/assets/ColorPicker.CV4IKef4.css\",\"_app/immutable/assets/6.DzV0p3l-.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,4BAA0C,CAAC,EAAE;AACxG,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AACxiB,MAAC,WAAW,GAAG,CAAC,gDAAgD,CAAC,sCAAsC;AACvG,MAAC,KAAK,GAAG;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"7-CpBrOkxQ.js","sources":["../../../.svelte-kit/adapter-node/nodes/7.js"],"sourcesContent":["\n\nexport const index = 7;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/session/_id_/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/7.B7UJd8GQ.js\",\"_app/immutable/chunks/Cg3dlX05.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/DZQMsHM5.js\",\"_app/immutable/chunks/DZvnhU_8.js\",\"_app/immutable/chunks/Bkqjn62J.js\",\"_app/immutable/chunks/DOHhmtDH.js\",\"_app/immutable/chunks/xs1Xl3_e.js\",\"_app/immutable/chunks/BDcFu3l7.js\",\"_app/immutable/chunks/Pw0jDB7M.js\",\"_app/immutable/chunks/C_9BZILB.js\"];\nexport const stylesheets = [\"_app/immutable/assets/ColorPicker.CV4IKef4.css\",\"_app/immutable/assets/ChatView.Bnlg-oAF.css\",\"_app/immutable/assets/7.CEbRAOOf.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,4BAA+C,CAAC,EAAE;AAC7G,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AACxZ,MAAC,WAAW,GAAG,CAAC,gDAAgD,CAAC,6CAA6C,CAAC,sCAAsC;AACrJ,MAAC,KAAK,GAAG;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"8-BRGAVfze.js","sources":["../../../.svelte-kit/adapter-node/nodes/8.js"],"sourcesContent":["\n\nexport const index = 8;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/terminals/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/8.CG0mrgBU.js\",\"_app/immutable/chunks/Cg3dlX05.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/DZvnhU_8.js\",\"_app/immutable/chunks/DZQMsHM5.js\",\"_app/immutable/chunks/DOHhmtDH.js\",\"_app/immutable/chunks/BRqaaL5D.js\",\"_app/immutable/chunks/CG453M9q.js\",\"_app/immutable/chunks/CSjf4fBs.js\",\"_app/immutable/chunks/xs1Xl3_e.js\",\"_app/immutable/chunks/gQJcRhou.js\",\"_app/immutable/chunks/BDcFu3l7.js\",\"_app/immutable/chunks/C5VOyQCG.js\"];\nexport const stylesheets = [\"_app/immutable/assets/ColorPicker.CV4IKef4.css\",\"_app/immutable/assets/8.BhoBXADL.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,4BAA4C,CAAC,EAAE;AAC1G,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChe,MAAC,WAAW,GAAG,CAAC,gDAAgD,CAAC,sCAAsC;AACvG,MAAC,KAAK,GAAG;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"9-C6xuAb_Y.js","sources":["../../../.svelte-kit/adapter-node/nodes/9.js"],"sourcesContent":["\n\nexport const index = 9;\nlet component_cache;\nexport const component = async () => component_cache ??= (await import('../entries/pages/terminals/_id_/_page.svelte.js')).default;\nexport const imports = [\"_app/immutable/nodes/9.KwzWaMHj.js\",\"_app/immutable/chunks/PPVm8Dsz.js\",\"_app/immutable/chunks/Cg3dlX05.js\",\"_app/immutable/chunks/DYuMZGL5.js\",\"_app/immutable/chunks/DZQMsHM5.js\",\"_app/immutable/chunks/DZvnhU_8.js\",\"_app/immutable/chunks/DOHhmtDH.js\",\"_app/immutable/chunks/DlS3abGJ.js\",\"_app/immutable/chunks/DzuS5Nbr.js\",\"_app/immutable/chunks/Pw0jDB7M.js\",\"_app/immutable/chunks/BDcFu3l7.js\",\"_app/immutable/chunks/C_9BZILB.js\",\"_app/immutable/chunks/C5VOyQCG.js\"];\nexport const stylesheets = [\"_app/immutable/assets/ColorPicker.CV4IKef4.css\",\"_app/immutable/assets/ChatView.Bnlg-oAF.css\",\"_app/immutable/assets/9.v5KA95xm.css\"];\nexport const fonts = [];\n"],"names":[],"mappings":"AAEY,MAAC,KAAK,GAAG;AACrB,IAAI,eAAe;AACP,MAAC,SAAS,GAAG,YAAY,eAAe,KAAK,CAAC,MAAM,OAAO,4BAAiD,CAAC,EAAE;AAC/G,MAAC,OAAO,GAAG,CAAC,oCAAoC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC,CAAC,mCAAmC;AAChe,MAAC,WAAW,GAAG,CAAC,gDAAgD,CAAC,6CAA6C,CAAC,sCAAsC;AACrJ,MAAC,KAAK,GAAG;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_server.ts-BrRZXr-8.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/terminals/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { p as ptyManager } from \"../../../../chunks/pty-manager.js\";\nimport { t as toErrorMessage } from \"../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nimport { realpathSync, statSync } from \"fs\";\nimport { basename, relative, isAbsolute } from \"path\";\nconst ALLOWED_COMMANDS = [\"zsh\", \"bash\", \"sh\", \"fish\", \"claude\", \"opencode\", \"codex\", \"gemini\"];\nfunction lastScrollbackLine(scrollback) {\n if (!scrollback) {\n return null;\n }\n const lines = scrollback.trimEnd().split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n if (line) {\n return line.slice(0, 200);\n }\n }\n return null;\n}\nconst GET = ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n try {\n const terminals = ptyManager.list().map((t) => ({\n args: t.args,\n clientCount: t.clients.size,\n command: t.command,\n createdAt: t.createdAt.toISOString(),\n currentCwd: t.currentCwd,\n cwd: t.cwd,\n exitCode: t.exitCode,\n exitedAt: t.exitedAt?.toISOString() ?? null,\n id: t.id,\n isActive: t.isActive,\n lastOutput: lastScrollbackLine(t.scrollback),\n pid: t.pid,\n status: t.status\n }));\n return json({\n count: terminals.length,\n terminals,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"[terminals] Failed to list terminals:\", toErrorMessage(error));\n return json({ error: \"Failed to list terminals\" }, { status: 500 });\n }\n};\nconst POST = async ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON in request body\" }, { status: 400 });\n }\n try {\n const { args, cols, command, cwd, rows } = body;\n if (!command) {\n return json({ error: \"command is required\" }, { status: 400 });\n }\n const commandBasename = basename(command);\n if (!ALLOWED_COMMANDS.includes(commandBasename)) {\n return json(\n { error: `Command not allowed. Allowed: ${ALLOWED_COMMANDS.join(\", \")}` },\n { status: 400 }\n );\n }\n if (!cwd) {\n return json({ error: \"cwd is required\" }, { status: 400 });\n }\n let realCwd;\n try {\n realCwd = realpathSync(cwd);\n if (!statSync(realCwd).isDirectory()) {\n return json({ error: \"cwd must be a directory\" }, { status: 400 });\n }\n } catch {\n return json({ error: \"cwd must be a directory\" }, { status: 400 });\n }\n const home = process.env.HOME || \"\";\n if (home) {\n const rel = relative(home, realCwd);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n return json({ error: \"Working directory must be under home directory\" }, { status: 400 });\n }\n }\n if (args !== void 0 && !Array.isArray(args)) {\n return json({ error: \"args must be an array of strings\" }, { status: 400 });\n }\n if (args && !args.every((a) => typeof a === \"string\")) {\n return json({ error: \"All args must be strings\" }, { status: 400 });\n }\n if (cols !== void 0 && (typeof cols !== \"number\" || cols < 1)) {\n return json({ error: \"cols must be a positive number\" }, { status: 400 });\n }\n if (rows !== void 0 && (typeof rows !== \"number\" || rows < 1)) {\n return json({ error: \"rows must be a positive number\" }, { status: 400 });\n }\n const terminal = await ptyManager.create(command, args ?? [], realCwd, cols ?? 80, rows ?? 24);\n console.log(\n `[terminals] Created terminal ${terminal.id} (pid=${terminal.pid}, command=${command})`\n );\n return json(\n {\n command: terminal.command,\n createdAt: terminal.createdAt instanceof Date ? terminal.createdAt.toISOString() : terminal.createdAt,\n cwd: terminal.cwd,\n id: terminal.id,\n pid: terminal.pid,\n sessionWs: `/ws/session/${terminal.id}`,\n ws: `/ws/terminal/${terminal.id}`\n },\n { status: 201 }\n );\n } catch (error) {\n console.error(\"[terminals] Failed to create terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to create terminal\" }, { status: 500 });\n }\n};\nexport {\n GET,\n POST\n};\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_server.ts-CjK0g9dO.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/sessions/detect/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../../chunks/auth.js\";\nimport { r as resolveOpenCodeDbPath, d as detectActiveCodexSessions } from \"../../../../../chunks/opencode-db-path.js\";\nimport Database from \"better-sqlite3\";\nimport { execSync } from \"child_process\";\nimport { readdirSync, readFileSync, existsSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { t as toErrorMessage } from \"../../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nfunction cwdToProjectPath(cwd) {\n return cwd.replace(/\\//g, \"-\");\n}\nfunction isOpenCodeRunning() {\n try {\n execSync(\"pgrep -x opencode\", { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\nfunction isProcessAlive(pid) {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\nconst CLAUDE_SESSIONS_DIR = join(homedir(), \".claude\", \"sessions\");\nconst OPENCODE_ACTIVE_THRESHOLD_MS = 3 * 6e4;\nconst CODEX_ACTIVE_THRESHOLD_MS = 3 * 6e4;\nfunction detectRunningAISessions() {\n const results = [];\n try {\n const files = readdirSync(CLAUDE_SESSIONS_DIR).filter((f) => f.endsWith(\".json\"));\n for (const file of files) {\n try {\n const raw = readFileSync(join(CLAUDE_SESSIONS_DIR, file), \"utf-8\");\n const data = JSON.parse(raw);\n if (!data.pid || !data.sessionId || !data.cwd) {\n continue;\n }\n if (!isProcessAlive(data.pid)) {\n continue;\n }\n results.push({\n command: \"claude\",\n cwd: data.cwd,\n kind: data.kind || \"interactive\",\n pid: data.pid,\n projectPath: cwdToProjectPath(data.cwd),\n sessionId: data.sessionId,\n startedAt: data.startedAt || 0\n });\n } catch {\n }\n }\n } catch {\n }\n if (isOpenCodeRunning()) {\n try {\n const dbPath = resolveOpenCodeDbPath();\n if (existsSync(dbPath)) {\n const db = new Database(dbPath, { readonly: true });\n try {\n const cutoff = Date.now() - OPENCODE_ACTIVE_THRESHOLD_MS;\n const cutoffSec = Math.floor(cutoff / 1e3);\n const rows = db.prepare(\n `SELECT id, directory, time_created, time_updated\n FROM session\n WHERE (time_archived IS NULL OR time_archived = 0)\n AND (\n (time_updated >= 1e12 AND time_updated > ?)\n OR (time_updated < 1e12 AND time_updated > ?)\n )\n ORDER BY time_updated DESC\n LIMIT 20`\n ).all(cutoff, cutoffSec);\n for (const row of rows) {\n const startMs = row.time_created >= 1e12 ? row.time_created : row.time_created * 1e3;\n results.push({\n command: \"opencode\",\n cwd: row.directory || \"\",\n kind: \"interactive\",\n pid: 0,\n // OpenCode doesn't expose per-session PIDs\n projectPath: cwdToProjectPath(row.directory || \"\"),\n sessionId: row.id,\n startedAt: startMs\n });\n }\n } finally {\n db.close();\n }\n }\n } catch {\n }\n }\n try {\n for (const s of detectActiveCodexSessions(CODEX_ACTIVE_THRESHOLD_MS)) {\n results.push({\n command: \"codex\",\n cwd: s.cwd,\n kind: \"interactive\",\n pid: 0,\n // Codex doesn't expose a per-session PID\n projectPath: cwdToProjectPath(s.cwd),\n sessionId: s.id,\n startedAt: s.startedAt\n });\n }\n } catch {\n }\n results.sort((a, b) => b.startedAt - a.startedAt);\n return results;\n}\nconst GET = ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n try {\n const processes = detectRunningAISessions();\n return json({\n count: processes.length,\n processes,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"[sessions/detect] Failed to detect running sessions:\", toErrorMessage(error));\n return json({ error: \"Failed to detect running sessions\" }, { status: 500 });\n }\n};\nexport {\n GET\n};\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_server.ts-Cq9_scaV.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/sessions/connect/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../../chunks/auth.js\";\nimport { p as ptyManager } from \"../../../../../chunks/pty-manager.js\";\nimport { t as toErrorMessage } from \"../../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nimport { realpathSync, statSync } from \"fs\";\nimport { relative, isAbsolute } from \"path\";\nconst POST = async ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON in request body\" }, { status: 400 });\n }\n const { command, cwd, noCreate, sessionId } = body;\n if (!sessionId || typeof sessionId !== \"string\") {\n return json({ error: \"sessionId is required (string)\" }, { status: 400 });\n }\n if (!cwd || typeof cwd !== \"string\") {\n return json({ error: \"cwd is required (string)\" }, { status: 400 });\n }\n const VALID_COMMANDS = [\"claude\", \"opencode\", \"codex\", \"gemini\"];\n if (!command || !VALID_COMMANDS.includes(command)) {\n return json({ error: `command must be one of: ${VALID_COMMANDS.join(\", \")}` }, { status: 400 });\n }\n let realCwd;\n try {\n realCwd = realpathSync(cwd);\n if (!statSync(realCwd).isDirectory()) {\n return json({ error: \"Invalid working directory\" }, { status: 400 });\n }\n } catch {\n return json({ error: \"Invalid working directory\" }, { status: 400 });\n }\n const home = process.env.HOME || \"\";\n if (home) {\n const rel = relative(home, realCwd);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n return json({ error: \"Working directory must be under home directory\" }, { status: 400 });\n }\n }\n const existing = ptyManager.list().find(\n (t) => t.status === \"running\" && // Claude: <id>.jsonl ; Codex rollout: rollout-<ts>-<id>.jsonl ; OpenCode: session id\n (t.sessionFile?.endsWith(`/${sessionId}.jsonl`) || t.sessionFile?.endsWith(`-${sessionId}.jsonl`) || t.openCodeSessionId === sessionId)\n );\n if (existing) {\n console.log(\n `[sessions/connect] Reusing terminal ${existing.id} for ${command} session ${sessionId}`\n );\n return json({\n command: existing.command,\n createdAt: existing.createdAt.toISOString(),\n cwd: existing.cwd,\n id: existing.id,\n pid: existing.pid,\n reused: true,\n sessionId,\n sessionWs: `/ws/session/${existing.id}`,\n terminalId: existing.id,\n ws: `/ws/terminal/${existing.id}`\n });\n }\n if (noCreate) {\n return json({ error: \"No existing terminal for this session\" }, { status: 404 });\n }\n const resumeArgs = {\n claude: [\"--resume\", sessionId],\n codex: [\"resume\", sessionId],\n gemini: [],\n // Gemini CLI has no session-resume flag; launch fresh in the cwd.\n opencode: [\"--session\", sessionId]\n };\n const args = resumeArgs[command] ?? [];\n try {\n const terminal = await ptyManager.create(command, args, realCwd, 120, 40);\n console.log(\n `[sessions/connect] Created terminal ${terminal.id} for ${command} session ${sessionId} (pid=${terminal.pid})`\n );\n return json(\n {\n command: terminal.command,\n createdAt: terminal.createdAt instanceof Date ? terminal.createdAt.toISOString() : terminal.createdAt,\n cwd: terminal.cwd,\n id: terminal.id,\n pid: terminal.pid,\n sessionId,\n sessionWs: `/ws/session/${terminal.id}`,\n terminalId: terminal.id,\n ws: `/ws/terminal/${terminal.id}`\n },\n { status: 201 }\n );\n } catch (error) {\n console.error(\"[sessions/connect] Failed to create terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to create terminal for session\" }, { status: 500 });\n }\n};\nexport {\n POST\n};\n"],"names":[],"mappings":"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"}