clitrigger 0.2.8 → 0.2.9

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 (71) hide show
  1. package/dist/client/assets/{index-BjSdQnnM.css → index-BwUXJf1U.css} +1 -1
  2. package/dist/client/assets/index-DI7n7r9n.js +748 -0
  3. package/dist/client/index.html +2 -2
  4. package/dist/server/db/queries.d.ts +15 -1
  5. package/dist/server/db/queries.d.ts.map +1 -1
  6. package/dist/server/db/queries.js +51 -0
  7. package/dist/server/db/queries.js.map +1 -1
  8. package/dist/server/db/schema.d.ts.map +1 -1
  9. package/dist/server/db/schema.js +11 -0
  10. package/dist/server/db/schema.js.map +1 -1
  11. package/dist/server/index.d.ts.map +1 -1
  12. package/dist/server/index.js +4 -0
  13. package/dist/server/index.js.map +1 -1
  14. package/dist/server/routes/files.d.ts.map +1 -1
  15. package/dist/server/routes/files.js +122 -0
  16. package/dist/server/routes/files.js.map +1 -1
  17. package/dist/server/routes/logs.d.ts.map +1 -1
  18. package/dist/server/routes/logs.js +4 -5
  19. package/dist/server/routes/logs.js.map +1 -1
  20. package/dist/server/routes/projects.js +2 -2
  21. package/dist/server/routes/projects.js.map +1 -1
  22. package/dist/server/routes/session-aliases.d.ts +3 -0
  23. package/dist/server/routes/session-aliases.d.ts.map +1 -0
  24. package/dist/server/routes/session-aliases.js +88 -0
  25. package/dist/server/routes/session-aliases.js.map +1 -0
  26. package/dist/server/routes/sessions.d.ts.map +1 -1
  27. package/dist/server/routes/sessions.js +4 -0
  28. package/dist/server/routes/sessions.js.map +1 -1
  29. package/dist/server/routes/vault.d.ts +3 -0
  30. package/dist/server/routes/vault.d.ts.map +1 -0
  31. package/dist/server/routes/vault.js +184 -0
  32. package/dist/server/routes/vault.js.map +1 -0
  33. package/dist/server/services/cli-adapters.d.ts +1 -1
  34. package/dist/server/services/cli-adapters.d.ts.map +1 -1
  35. package/dist/server/services/cli-adapters.js +31 -0
  36. package/dist/server/services/cli-adapters.js.map +1 -1
  37. package/dist/server/services/discussion-orchestrator.d.ts.map +1 -1
  38. package/dist/server/services/discussion-orchestrator.js +29 -13
  39. package/dist/server/services/discussion-orchestrator.js.map +1 -1
  40. package/dist/server/services/file-scanner.d.ts +26 -0
  41. package/dist/server/services/file-scanner.d.ts.map +1 -0
  42. package/dist/server/services/file-scanner.js +244 -0
  43. package/dist/server/services/file-scanner.js.map +1 -0
  44. package/dist/server/services/memory-inject-hook.d.ts +3 -1
  45. package/dist/server/services/memory-inject-hook.d.ts.map +1 -1
  46. package/dist/server/services/memory-inject-hook.js +49 -0
  47. package/dist/server/services/memory-inject-hook.js.map +1 -1
  48. package/dist/server/services/orchestrator.d.ts +2 -0
  49. package/dist/server/services/orchestrator.d.ts.map +1 -1
  50. package/dist/server/services/orchestrator.js +5 -10
  51. package/dist/server/services/orchestrator.js.map +1 -1
  52. package/dist/server/services/project-status.d.ts +10 -0
  53. package/dist/server/services/project-status.d.ts.map +1 -0
  54. package/dist/server/services/project-status.js +34 -0
  55. package/dist/server/services/project-status.js.map +1 -0
  56. package/dist/server/services/session-manager.d.ts.map +1 -1
  57. package/dist/server/services/session-manager.js +19 -2
  58. package/dist/server/services/session-manager.js.map +1 -1
  59. package/dist/server/services/vault-injector.d.ts +14 -0
  60. package/dist/server/services/vault-injector.d.ts.map +1 -0
  61. package/dist/server/services/vault-injector.js +106 -0
  62. package/dist/server/services/vault-injector.js.map +1 -0
  63. package/dist/server/services/vault-retriever.d.ts +7 -0
  64. package/dist/server/services/vault-retriever.d.ts.map +1 -0
  65. package/dist/server/services/vault-retriever.js +108 -0
  66. package/dist/server/services/vault-retriever.js.map +1 -0
  67. package/dist/server/websocket/events.d.ts +2 -0
  68. package/dist/server/websocket/events.d.ts.map +1 -1
  69. package/electron/main.cjs +74 -8
  70. package/package.json +1 -1
  71. package/dist/client/assets/index-CCQfo9GC.js +0 -735
@@ -0,0 +1,108 @@
1
+ import * as queries from '../db/queries.js';
2
+ import { scanVault } from './file-scanner.js';
3
+ import { runHeadless, resolveCliTool } from './memory-ingest.js';
4
+ const RETRIEVAL_MAX_FILES = 10;
5
+ const RETRIEVAL_TIMEOUT_MS = 60_000;
6
+ const FILE_LIST_BUDGET_CHARS = 7000;
7
+ const TASK_QUERY_MAX_CHARS = 4000;
8
+ function firstSentence(text, maxLen = 140) {
9
+ const flat = text.replace(/\s+/g, ' ').trim();
10
+ if (!flat)
11
+ return '';
12
+ const cut = flat.slice(0, maxLen);
13
+ return cut.length < flat.length ? `${cut}…` : cut;
14
+ }
15
+ function buildCandidatePool(files) {
16
+ const sorted = [...files].sort((a, b) => (b.mtime ?? '').localeCompare(a.mtime ?? ''));
17
+ const lines = [];
18
+ const pathSet = new Set();
19
+ let used = 0;
20
+ for (const f of sorted) {
21
+ const tagStr = f.tags.length > 0 ? ` [${f.tags.join(', ')}]` : '';
22
+ const summary = firstSentence(f.bodyPreview);
23
+ const line = `- path="${f.relativePath}" title="${f.title}"${tagStr}${summary ? ` — ${summary}` : ''}`;
24
+ if (used + line.length > FILE_LIST_BUDGET_CHARS && lines.length > 0)
25
+ break;
26
+ lines.push(line);
27
+ pathSet.add(f.relativePath);
28
+ used += line.length + 1;
29
+ }
30
+ return { lines, pathSet };
31
+ }
32
+ const RETRIEVAL_PROMPT_HEADER = `You are selecting the most relevant wiki files for an upcoming task. The selected files will be injected into the task prompt as long-term context.
33
+
34
+ # Task
35
+ {TASK}
36
+
37
+ # Available wiki files
38
+ {ENTRIES}
39
+
40
+ ---
41
+
42
+ Output ONLY a JSON array of file paths (no prose, no code fences):
43
+ ["path/to/file1.md", "path/to/file2.md"]
44
+
45
+ Rules:
46
+ - Pick at most ${RETRIEVAL_MAX_FILES} files directly relevant to the task.
47
+ - Prefer fewer high-relevance files over many tangential ones.
48
+ - Return [] if nothing is meaningfully relevant — do not pad.`;
49
+ function safeParsePathArray(raw, validPaths) {
50
+ const cleaned = raw.trim().replace(/^```(?:json)?\s*/, '').replace(/\s*```\s*$/, '');
51
+ let parsed;
52
+ try {
53
+ parsed = JSON.parse(cleaned);
54
+ }
55
+ catch {
56
+ const m = cleaned.match(/\[[\s\S]*\]/);
57
+ if (!m)
58
+ return [];
59
+ try {
60
+ parsed = JSON.parse(m[0]);
61
+ }
62
+ catch {
63
+ return [];
64
+ }
65
+ }
66
+ if (!Array.isArray(parsed))
67
+ return [];
68
+ const paths = [];
69
+ for (const item of parsed) {
70
+ const p = String(item);
71
+ if (validPaths.has(p) && !paths.includes(p))
72
+ paths.push(p);
73
+ if (paths.length >= RETRIEVAL_MAX_FILES)
74
+ break;
75
+ }
76
+ return paths;
77
+ }
78
+ export async function selectRelevantFiles(projectId, projectRoot, taskQuery, excludePatterns) {
79
+ const project = queries.getProjectById(projectId);
80
+ if (!project)
81
+ return { selectedPaths: [], candidateCount: 0, reason: 'no-candidates' };
82
+ const trimmedQuery = (taskQuery || '').trim();
83
+ if (!trimmedQuery)
84
+ return { selectedPaths: [], candidateCount: 0, reason: 'no-query' };
85
+ const candidates = scanVault(projectRoot, excludePatterns);
86
+ if (candidates.length === 0)
87
+ return { selectedPaths: [], candidateCount: 0, reason: 'no-candidates' };
88
+ const { lines, pathSet } = buildCandidatePool(candidates);
89
+ if (lines.length === 0)
90
+ return { selectedPaths: [], candidateCount: 0, reason: 'no-candidates' };
91
+ const prompt = RETRIEVAL_PROMPT_HEADER
92
+ .replace('{TASK}', trimmedQuery.slice(0, TASK_QUERY_MAX_CHARS))
93
+ .replace('{ENTRIES}', lines.join('\n'));
94
+ const cliTool = resolveCliTool(project.cli_tool);
95
+ let raw;
96
+ try {
97
+ raw = await runHeadless(cliTool, prompt, RETRIEVAL_TIMEOUT_MS);
98
+ }
99
+ catch (err) {
100
+ console.warn('[vault-retriever] runHeadless failed:', err instanceof Error ? err.message : err);
101
+ return { selectedPaths: [], candidateCount: candidates.length, reason: 'cli-error' };
102
+ }
103
+ const paths = safeParsePathArray(raw, pathSet);
104
+ return paths.length === 0
105
+ ? { selectedPaths: [], candidateCount: candidates.length, reason: 'no-match' }
106
+ : { selectedPaths: paths, candidateCount: candidates.length };
107
+ }
108
+ //# sourceMappingURL=vault-retriever.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-retriever.js","sourceRoot":"","sources":["../../../src/server/services/vault-retriever.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAkB,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEjE,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AACpC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAQlC,SAAS,aAAa,CAAC,IAAY,EAAE,MAAM,GAAG,GAAG;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AACpD,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAkB;IAC5C,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACtC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,YAAY,YAAY,CAAC,CAAC,KAAK,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACvG,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,sBAAsB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM;QAC3E,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC5B,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;iBAcf,mBAAmB;;8DAE0B,CAAC;AAE/D,SAAS,kBAAkB,CAAC,GAAW,EAAE,UAAuB;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACrF,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QAClB,IAAI,CAAC;YAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,EAAE,CAAC;QAAC,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,KAAK,CAAC,MAAM,IAAI,mBAAmB;YAAE,MAAM;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,WAAmB,EACnB,SAAiB,EACjB,eAA0B;IAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAEvF,MAAM,YAAY,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAEvF,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAEtG,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAEjG,MAAM,MAAM,GAAG,uBAAuB;SACnC,OAAO,CAAC,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;SAC9D,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,uCAAuC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChG,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACvF,CAAC;IAED,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;QACvB,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,cAAc,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE;QAC9E,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AAClE,CAAC"}
@@ -16,6 +16,8 @@ export type WSEvent = {
16
16
  running: number;
17
17
  completed: number;
18
18
  total: number;
19
+ running_sessions?: number;
20
+ running_discussions?: number;
19
21
  } | {
20
22
  type: 'todo:commit';
21
23
  todoId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/server/websocket/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/server/websocket/events.ts"],"names":[],"mappings":"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"}
package/electron/main.cjs CHANGED
@@ -125,15 +125,78 @@ function createWindow(port) {
125
125
  `http://127.0.0.1:${port}`,
126
126
  `http://localhost:${port}`,
127
127
  ];
128
- mainWindow.webContents.setWindowOpenHandler(({ url }) => {
128
+ // Parse a `features` CSV string like "popup,width=800,height=540,left=120,top=80"
129
+ // into numeric x/y/width/height we can forward into Electron's
130
+ // overrideBrowserWindowOptions. Electron drops the features-derived sizing
131
+ // when override is returned, so this re-forwards what the renderer asked
132
+ // for; without it the popout would spawn at Electron's default cascade
133
+ // position instead of under the user's cursor (drag-out is unusable).
134
+ const parseFeatures = (features) => {
135
+ const out = {};
136
+ if (typeof features !== 'string') return out;
137
+ for (const part of features.split(',')) {
138
+ const eq = part.indexOf('=');
139
+ if (eq < 0) continue;
140
+ const key = part.slice(0, eq).trim().toLowerCase();
141
+ const val = Number(part.slice(eq + 1).trim());
142
+ if (!Number.isFinite(val)) continue;
143
+ if (key === 'width') out.width = val;
144
+ else if (key === 'height') out.height = val;
145
+ else if (key === 'left') out.x = val;
146
+ else if (key === 'top') out.y = val;
147
+ }
148
+ return out;
149
+ };
150
+
151
+ mainWindow.webContents.setWindowOpenHandler(({ url, features }) => {
129
152
  const isLocal = localOrigins.some((o) => url.startsWith(o));
130
153
  if (!isLocal) {
131
154
  shell.openExternal(url);
132
155
  return { action: 'deny' };
133
156
  }
157
+ // Session pop-out windows: open as a real OS child window with the same
158
+ // preload + isolation as the main window. Without overrideBrowserWindowOptions
159
+ // Electron uses small defaults and doesn't apply the preload, which
160
+ // breaks IME reset + auto-updater bridges the popout may also call.
161
+ let popoutPath;
162
+ try { popoutPath = new URL(url).pathname; } catch { popoutPath = ''; }
163
+ if (popoutPath.startsWith('/popout/')) {
164
+ const feat = parseFeatures(features);
165
+ return {
166
+ action: 'allow',
167
+ overrideBrowserWindowOptions: {
168
+ width: feat.width || 800,
169
+ height: feat.height || 540,
170
+ // x/y intentionally only forwarded when supplied — Electron treats
171
+ // an absent x/y as "let the OS place the window" which is the right
172
+ // default for the button-click path.
173
+ ...(typeof feat.x === 'number' ? { x: feat.x } : {}),
174
+ ...(typeof feat.y === 'number' ? { y: feat.y } : {}),
175
+ minWidth: 360,
176
+ minHeight: 240,
177
+ backgroundColor: nativeTheme.shouldUseDarkColors ? '#0f0f0f' : '#ffffff',
178
+ webPreferences: {
179
+ preload: path.join(__dirname, 'preload.cjs'),
180
+ contextIsolation: true,
181
+ nodeIntegration: false,
182
+ sandbox: false,
183
+ },
184
+ },
185
+ };
186
+ }
134
187
  return { action: 'allow' };
135
188
  });
136
189
 
190
+ // Newly-created child windows (popouts) inherit the main window's
191
+ // setWindowOpenHandler but not the lock-screen focus-recovery handler.
192
+ // Attach the same focus → webContents.focus() bridge so xterm typing
193
+ // doesn't go dead after resume.
194
+ mainWindow.webContents.on('did-create-window', (childWin) => {
195
+ childWin.on('focus', () => {
196
+ if (!childWin.isDestroyed()) childWin.webContents.focus();
197
+ });
198
+ });
199
+
137
200
  mainWindow.loadURL(`http://127.0.0.1:${port}`);
138
201
 
139
202
  if (!app.isPackaged) {
@@ -152,7 +215,16 @@ function createWindow(port) {
152
215
  });
153
216
  }
154
217
 
155
- ipcMain.on('ime:reset', () => {
218
+ ipcMain.on('ime:reset', (event) => {
219
+ // Route the focus call to the sender's webContents so popout child
220
+ // windows reclaim their own keyboard focus, not the main window's.
221
+ // Falls back to mainWindow only if the sender is gone (race during
222
+ // teardown).
223
+ const sender = event && event.sender;
224
+ if (sender && !sender.isDestroyed()) {
225
+ sender.focus();
226
+ return;
227
+ }
156
228
  if (mainWindow && !mainWindow.isDestroyed()) {
157
229
  mainWindow.webContents.focus();
158
230
  }
@@ -230,12 +302,6 @@ function setupAutoUpdater() {
230
302
  setTimeout(() => checkForUpdates({ silent: true }), 5000);
231
303
  }
232
304
 
233
- ipcMain.on('ime:reset', () => {
234
- if (mainWindow && !mainWindow.isDestroyed()) {
235
- mainWindow.webContents.focus();
236
- }
237
- });
238
-
239
305
  function buildMenu() {
240
306
  const isMac = process.platform === 'darwin';
241
307
  const template = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clitrigger",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Spawn isolated git worktrees and orchestrate Claude/Gemini/Codex CLI tasks in parallel from a web UI.",
5
5
  "keywords": [
6
6
  "claude",