@ngandu/ulicode 0.0.6

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 (59) hide show
  1. package/CHANGELOG.md +1081 -0
  2. package/README.md +312 -0
  3. package/dist/agents/definitions/ask.agent.md +53 -0
  4. package/dist/agents/definitions/audit-tests.agent.md +138 -0
  5. package/dist/agents/definitions/build.agent.md +111 -0
  6. package/dist/agents/definitions/execute.agent.md +99 -0
  7. package/dist/agents/definitions/explore.agent.md +57 -0
  8. package/dist/agents/definitions/fast.agent.md +48 -0
  9. package/dist/agents/definitions/plan-mode.agent.md +102 -0
  10. package/dist/agents/definitions/planner.agent.md +59 -0
  11. package/dist/chunk-3YYDXNUH.js +854 -0
  12. package/dist/chunk-3YYDXNUH.js.map +1 -0
  13. package/dist/chunk-IEV2IT3O.cjs +873 -0
  14. package/dist/chunk-IEV2IT3O.cjs.map +1 -0
  15. package/dist/chunk-MBWGSXBT.js +11927 -0
  16. package/dist/chunk-MBWGSXBT.js.map +1 -0
  17. package/dist/chunk-MS5RYNRK.js +137 -0
  18. package/dist/chunk-MS5RYNRK.js.map +1 -0
  19. package/dist/chunk-OXFO76JC.js +2633 -0
  20. package/dist/chunk-OXFO76JC.js.map +1 -0
  21. package/dist/chunk-PKRLG6A4.js +1756 -0
  22. package/dist/chunk-PKRLG6A4.js.map +1 -0
  23. package/dist/chunk-PUVEPQQ3.cjs +1805 -0
  24. package/dist/chunk-PUVEPQQ3.cjs.map +1 -0
  25. package/dist/chunk-R6JK3DE3.cjs +148 -0
  26. package/dist/chunk-R6JK3DE3.cjs.map +1 -0
  27. package/dist/chunk-Y3HWP75B.cjs +11974 -0
  28. package/dist/chunk-Y3HWP75B.cjs.map +1 -0
  29. package/dist/chunk-Y5PO67TG.cjs +2659 -0
  30. package/dist/chunk-Y5PO67TG.cjs.map +1 -0
  31. package/dist/cli.cjs +372 -0
  32. package/dist/cli.cjs.map +1 -0
  33. package/dist/cli.d.cts +1 -0
  34. package/dist/cli.d.ts +1 -0
  35. package/dist/cli.js +370 -0
  36. package/dist/cli.js.map +1 -0
  37. package/dist/index.cjs +16 -0
  38. package/dist/index.cjs.map +1 -0
  39. package/dist/index.d.cts +165 -0
  40. package/dist/index.d.ts +165 -0
  41. package/dist/index.js +3 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/permissions-NRD36MYI.cjs +40 -0
  44. package/dist/permissions-NRD36MYI.cjs.map +1 -0
  45. package/dist/permissions-RC7CYR5H.js +3 -0
  46. package/dist/permissions-RC7CYR5H.js.map +1 -0
  47. package/dist/project-q9WpahUs.d.cts +329 -0
  48. package/dist/project-q9WpahUs.d.ts +329 -0
  49. package/dist/storage-6P53PQBL.cjs +24 -0
  50. package/dist/storage-6P53PQBL.cjs.map +1 -0
  51. package/dist/storage-QELMNBZ2.js +3 -0
  52. package/dist/storage-QELMNBZ2.js.map +1 -0
  53. package/dist/tui.cjs +76 -0
  54. package/dist/tui.cjs.map +1 -0
  55. package/dist/tui.d.cts +1013 -0
  56. package/dist/tui.d.ts +1013 -0
  57. package/dist/tui.js +3 -0
  58. package/dist/tui.js.map +1 -0
  59. package/package.json +107 -0
@@ -0,0 +1,1805 @@
1
+ 'use strict';
2
+
3
+ var chunkIEV2IT3O_cjs = require('./chunk-IEV2IT3O.cjs');
4
+ var chunkR6JK3DE3_cjs = require('./chunk-R6JK3DE3.cjs');
5
+ var fs2 = require('fs');
6
+ var os = require('os');
7
+ var path4 = require('path');
8
+ var url = require('url');
9
+ var harness = require('@mastra/core/harness');
10
+ var yaml = require('js-yaml');
11
+ var node_js = require('vscode-jsonrpc/node.js');
12
+ var vscodeLanguageserverProtocol = require('vscode-languageserver-protocol');
13
+ var child_process = require('child_process');
14
+ var module$1 = require('module');
15
+
16
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
+ function _interopNamespace(e) {
18
+ if (e && e.__esModule) return e;
19
+ var n = Object.create(null);
20
+ if (e) {
21
+ Object.keys(e).forEach(function (k) {
22
+ if (k !== 'default') {
23
+ var d = Object.getOwnPropertyDescriptor(e, k);
24
+ Object.defineProperty(n, k, d.get ? d : {
25
+ enumerable: true,
26
+ get: function () { return e[k]; }
27
+ });
28
+ }
29
+ });
30
+ }
31
+ n.default = e;
32
+ return Object.freeze(n);
33
+ }
34
+
35
+ var fs2__namespace = /*#__PURE__*/_interopNamespace(fs2);
36
+ var path4__namespace = /*#__PURE__*/_interopNamespace(path4);
37
+ var yaml__namespace = /*#__PURE__*/_interopNamespace(yaml);
38
+
39
+ var MODE_INDICATOR_FIELDS = /* @__PURE__ */ new Set([
40
+ "subagents",
41
+ "default",
42
+ "defaultModelId",
43
+ "color"
44
+ ]);
45
+ function idFromFilename(filePath) {
46
+ return path4.basename(filePath).replace(/\.agent\.md$/i, "");
47
+ }
48
+ function descriptionFromBody(body) {
49
+ const lines = body.split(/\r?\n/);
50
+ for (const line of lines) {
51
+ const trimmed = line.trim();
52
+ if (!trimmed || trimmed.startsWith("#")) continue;
53
+ const sentence = trimmed.match(/^[^.!?]+[.!?]?/)?.[0] ?? trimmed;
54
+ return sentence.length > 120 ? sentence.slice(0, 117) + "..." : sentence;
55
+ }
56
+ return "";
57
+ }
58
+ function inferKind(frontmatter) {
59
+ for (const key of Object.keys(frontmatter)) {
60
+ if (MODE_INDICATOR_FIELDS.has(key)) return "mode";
61
+ }
62
+ return "subagent";
63
+ }
64
+ var BUILTIN_DEFINITIONS_DIR = path4.join(path4.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-PUVEPQQ3.cjs', document.baseURI).href)))), "definitions");
65
+ var GLOBAL_AGENT_LOCATIONS = [
66
+ ".claude/agents",
67
+ ".ulicode/agents",
68
+ ".uli-cli/agents",
69
+ ".pulse/agents",
70
+ ".mastracode/agents",
71
+ ".config/claude/agents",
72
+ ".config/ulicode/agents",
73
+ ".config/uli-cli/agents",
74
+ ".config/pulse/agents",
75
+ ".config/mastracode/agents"
76
+ ];
77
+ var PROJECT_AGENT_LOCATIONS = [
78
+ ".claude/agents",
79
+ ".ulicode/agents",
80
+ ".uli-cli/agents",
81
+ ".pulse/agents",
82
+ ".mastracode/agents"
83
+ ];
84
+ var WORKSPACE_TOOL_IDS = new Set(Object.values(chunkR6JK3DE3_cjs.MC_TOOLS));
85
+ var DIRECT_SUBAGENT_TOOLS = {
86
+ task_write: harness.taskWriteTool,
87
+ task_check: harness.taskCheckTool
88
+ };
89
+ var agentDefinitionCache = /* @__PURE__ */ new Map();
90
+ function pushDiagnostic(diagnostics, severity, scope, sourcePath, message) {
91
+ diagnostics.push({ severity, scope, sourcePath, message });
92
+ }
93
+ function titleCaseId(id) {
94
+ return id.split(/[-_\s]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
95
+ }
96
+ function parseFrontmatter(content) {
97
+ const normalized = content.replace(/^\uFEFF/, "");
98
+ const match = normalized.match(/^---\r?\n([\s\S]*?)(?:\r?\n)?---\r?\n?([\s\S]*)$/);
99
+ if (!match) {
100
+ return null;
101
+ }
102
+ const frontmatter = yaml__namespace.load(match[1]) ?? {};
103
+ return { frontmatter, body: match[2].trim() };
104
+ }
105
+ function scanAgentDirectory(dirPath) {
106
+ if (!fs2.existsSync(dirPath)) {
107
+ return [];
108
+ }
109
+ const results = [];
110
+ for (const entry of fs2.readdirSync(dirPath, { withFileTypes: true })) {
111
+ const fullPath = path4.join(dirPath, entry.name);
112
+ if (entry.isDirectory()) {
113
+ results.push(...scanAgentDirectory(fullPath));
114
+ continue;
115
+ }
116
+ if (entry.isFile() && entry.name.endsWith(".agent.md")) {
117
+ results.push(fullPath);
118
+ }
119
+ }
120
+ return results.sort((left, right) => left.localeCompare(right));
121
+ }
122
+ function normalizeModeDefinition(filePath, scope, frontmatter, instructions, diagnostics) {
123
+ const id = (frontmatter.id ?? idFromFilename(filePath)).trim();
124
+ if (!id) {
125
+ pushDiagnostic(diagnostics, "error", scope, filePath, "could not derive `id` for mode definition");
126
+ return null;
127
+ }
128
+ const name = typeof frontmatter.name === "string" && frontmatter.name.trim() ? frontmatter.name.trim() : titleCaseId(id);
129
+ const description = typeof frontmatter.description === "string" && frontmatter.description.trim() ? frontmatter.description.trim() : descriptionFromBody(instructions);
130
+ if (frontmatter.subagents !== void 0 && !Array.isArray(frontmatter.subagents)) {
131
+ pushDiagnostic(diagnostics, "error", scope, filePath, `mode \`${id}\` must declare \`subagents\` as an array`);
132
+ return null;
133
+ }
134
+ if (Array.isArray(frontmatter.subagents) && frontmatter.subagents.some((entry) => typeof entry !== "string" || entry.trim().length === 0)) {
135
+ pushDiagnostic(
136
+ diagnostics,
137
+ "error",
138
+ scope,
139
+ filePath,
140
+ `mode \`${id}\` has invalid \`subagents\` entries; expected non-empty string ids`
141
+ );
142
+ return null;
143
+ }
144
+ const subagents = Array.isArray(frontmatter.subagents) ? frontmatter.subagents.map((entry) => entry.trim()) : [];
145
+ return {
146
+ id,
147
+ name,
148
+ kind: "mode",
149
+ description,
150
+ instructions,
151
+ sourcePath: filePath,
152
+ scope,
153
+ hidden: frontmatter.hidden === true,
154
+ default: frontmatter.default === true,
155
+ defaultModelId: typeof frontmatter.defaultModelId === "string" ? frontmatter.defaultModelId.trim() : void 0,
156
+ color: typeof frontmatter.color === "string" ? frontmatter.color.trim() : void 0,
157
+ subagents
158
+ };
159
+ }
160
+ function normalizeSubagentDefinition(filePath, scope, frontmatter, instructions, diagnostics) {
161
+ const id = (frontmatter.id ?? idFromFilename(filePath)).trim();
162
+ if (!id) {
163
+ pushDiagnostic(diagnostics, "error", scope, filePath, "could not derive `id` for subagent definition");
164
+ return null;
165
+ }
166
+ const name = typeof frontmatter.name === "string" && frontmatter.name.trim() ? frontmatter.name.trim() : titleCaseId(id);
167
+ const description = typeof frontmatter.description === "string" && frontmatter.description.trim() ? frontmatter.description.trim() : descriptionFromBody(instructions);
168
+ if (frontmatter.allowedWorkspaceTools && frontmatter.workspaceTools) {
169
+ pushDiagnostic(
170
+ diagnostics,
171
+ "error",
172
+ scope,
173
+ filePath,
174
+ `subagent \`${id}\` cannot declare both \`allowedWorkspaceTools\` and \`workspaceTools\``
175
+ );
176
+ return null;
177
+ }
178
+ if (frontmatter.tools && typeof frontmatter.tools !== "string" && (!Array.isArray(frontmatter.tools) || frontmatter.tools.some((entry) => typeof entry !== "string"))) {
179
+ pushDiagnostic(diagnostics, "error", scope, filePath, `subagent \`${id}\` must declare \`tools\` as an array of strings or "all"`);
180
+ return null;
181
+ }
182
+ const useAllTools = frontmatter.tools === "all" || Array.isArray(frontmatter.tools) && frontmatter.tools.length === 1 && frontmatter.tools[0] === "all";
183
+ const tools = useAllTools ? Object.keys(DIRECT_SUBAGENT_TOOLS) : Array.isArray(frontmatter.tools) ? frontmatter.tools.map((entry) => entry.trim()) : [];
184
+ const rawWorkspaceTools = frontmatter.allowedWorkspaceTools ?? frontmatter.workspaceTools;
185
+ const useAllWorkspaceTools = rawWorkspaceTools === "all" || Array.isArray(rawWorkspaceTools) && rawWorkspaceTools.length === 1 && rawWorkspaceTools[0] === "all";
186
+ let allowedWorkspaceTools;
187
+ if (useAllWorkspaceTools) {
188
+ allowedWorkspaceTools = void 0;
189
+ } else if (Array.isArray(rawWorkspaceTools)) {
190
+ allowedWorkspaceTools = rawWorkspaceTools.filter(
191
+ (entry) => typeof entry === "string" && entry.trim().length > 0
192
+ );
193
+ } else if (typeof rawWorkspaceTools === "string") {
194
+ pushDiagnostic(diagnostics, "warning", scope, filePath, `subagent \`${id}\` has unrecognized \`allowedWorkspaceTools\` value "${rawWorkspaceTools}"; expected array or "all"`);
195
+ allowedWorkspaceTools = void 0;
196
+ } else {
197
+ allowedWorkspaceTools = void 0;
198
+ }
199
+ const unknownDirectTools = tools.filter((toolId) => !(toolId in DIRECT_SUBAGENT_TOOLS));
200
+ if (unknownDirectTools.length > 0) {
201
+ pushDiagnostic(diagnostics, "warning", scope, filePath, `subagent \`${id}\` declares unknown direct tools (ignored at runtime): ${unknownDirectTools.join(", ")}`);
202
+ }
203
+ const unknownWorkspaceTools = (allowedWorkspaceTools ?? []).filter((toolId) => !WORKSPACE_TOOL_IDS.has(toolId));
204
+ if (unknownWorkspaceTools.length > 0) {
205
+ pushDiagnostic(diagnostics, "warning", scope, filePath, `subagent \`${id}\` declares unknown workspace tools (ignored at runtime): ${unknownWorkspaceTools.join(", ")}`);
206
+ }
207
+ return {
208
+ id,
209
+ name,
210
+ kind: "subagent",
211
+ description,
212
+ instructions,
213
+ sourcePath: filePath,
214
+ scope,
215
+ hidden: frontmatter.hidden === true,
216
+ tools,
217
+ allowedWorkspaceTools,
218
+ defaultModelFromMode: typeof frontmatter.defaultModelFromMode === "string" ? frontmatter.defaultModelFromMode.trim() : typeof frontmatter.modeId === "string" ? frontmatter.modeId.trim() : void 0
219
+ };
220
+ }
221
+ function parseAgentDefinitionFile(filePath, scope, diagnostics) {
222
+ try {
223
+ const content = fs2.readFileSync(filePath, "utf-8");
224
+ const parsed = parseFrontmatter(content);
225
+ if (!parsed) {
226
+ pushDiagnostic(diagnostics, "error", scope, filePath, "missing valid YAML frontmatter");
227
+ return null;
228
+ }
229
+ const instructions = parsed.body.trim();
230
+ if (!instructions) {
231
+ pushDiagnostic(diagnostics, "error", scope, filePath, "missing markdown instruction body");
232
+ return null;
233
+ }
234
+ const kind = parsed.frontmatter.kind ?? inferKind(parsed.frontmatter);
235
+ if (kind === "mode") {
236
+ return normalizeModeDefinition(filePath, scope, parsed.frontmatter, instructions, diagnostics);
237
+ }
238
+ if (kind === "subagent") {
239
+ return normalizeSubagentDefinition(filePath, scope, parsed.frontmatter, instructions, diagnostics);
240
+ }
241
+ pushDiagnostic(diagnostics, "error", scope, filePath, `unsupported \`kind\`: ${String(parsed.frontmatter.kind)}; expected \`mode\` or \`subagent\``);
242
+ return null;
243
+ } catch (error) {
244
+ pushDiagnostic(
245
+ diagnostics,
246
+ "error",
247
+ scope,
248
+ filePath,
249
+ `failed to parse agent definition: ${error instanceof Error ? error.message : String(error)}`
250
+ );
251
+ return null;
252
+ }
253
+ }
254
+ function validateRegistry(registry, diagnostics) {
255
+ const modeIds = new Set(registry.modes.map((mode) => mode.id));
256
+ const subagentIds = new Set(registry.subagents.map((subagent) => subagent.id));
257
+ for (const mode of registry.modes) {
258
+ const seen = /* @__PURE__ */ new Set();
259
+ for (const subagentId of mode.subagents) {
260
+ if (seen.has(subagentId)) {
261
+ pushDiagnostic(diagnostics, "warning", mode.scope, mode.sourcePath, `mode \`${mode.id}\` lists duplicate subagent \`${subagentId}\``);
262
+ continue;
263
+ }
264
+ seen.add(subagentId);
265
+ if (!subagentIds.has(subagentId)) {
266
+ pushDiagnostic(
267
+ diagnostics,
268
+ "error",
269
+ mode.scope,
270
+ mode.sourcePath,
271
+ `mode \`${mode.id}\` references unknown subagent \`${subagentId}\` in \`subagents\``
272
+ );
273
+ }
274
+ }
275
+ }
276
+ for (const subagent of registry.subagents) {
277
+ if (subagent.defaultModelFromMode && !modeIds.has(subagent.defaultModelFromMode)) {
278
+ pushDiagnostic(
279
+ diagnostics,
280
+ "error",
281
+ subagent.scope,
282
+ subagent.sourcePath,
283
+ `subagent \`${subagent.id}\` references unknown mode \`${subagent.defaultModelFromMode}\` in \`defaultModelFromMode\``
284
+ );
285
+ }
286
+ const ownerCount = registry.modes.filter((mode) => mode.subagents.includes(subagent.id)).length;
287
+ if (ownerCount === 0) {
288
+ pushDiagnostic(
289
+ diagnostics,
290
+ "warning",
291
+ subagent.scope,
292
+ subagent.sourcePath,
293
+ `subagent \`${subagent.id}\` is not referenced by any top-level mode \`subagents\` list`
294
+ );
295
+ }
296
+ }
297
+ const defaultModes = registry.modes.filter((mode) => mode.default);
298
+ if (defaultModes.length === 0) {
299
+ pushDiagnostic(diagnostics, "warning", "builtin", BUILTIN_DEFINITIONS_DIR, "no default top-level mode is defined");
300
+ } else if (defaultModes.length > 1) {
301
+ pushDiagnostic(
302
+ diagnostics,
303
+ "error",
304
+ "builtin",
305
+ BUILTIN_DEFINITIONS_DIR,
306
+ `multiple default top-level modes found: ${defaultModes.map((mode) => mode.id).join(", ")}`
307
+ );
308
+ }
309
+ }
310
+ function mergeDefinitions(entries) {
311
+ const modeMap = /* @__PURE__ */ new Map();
312
+ const subagentMap = /* @__PURE__ */ new Map();
313
+ const diagnostics = [];
314
+ const subagentModeClaims = /* @__PURE__ */ new Map();
315
+ for (const entry of entries) {
316
+ for (const filePath of scanAgentDirectory(entry.dirPath)) {
317
+ const content = fs2.readFileSync(filePath, "utf-8");
318
+ const parsed = parseFrontmatter(content);
319
+ const rawModes = parsed?.frontmatter?.modes;
320
+ const definition = parseAgentDefinitionFile(filePath, entry.scope, diagnostics);
321
+ if (!definition) {
322
+ continue;
323
+ }
324
+ if (definition.kind === "mode") {
325
+ modeMap.set(definition.id, definition);
326
+ } else {
327
+ subagentMap.set(definition.id, definition);
328
+ if (Array.isArray(rawModes) && rawModes.length > 0) {
329
+ subagentModeClaims.set(
330
+ definition.id,
331
+ rawModes.filter((m) => typeof m === "string" && m.trim().length > 0).map((m) => m.trim())
332
+ );
333
+ }
334
+ }
335
+ }
336
+ }
337
+ for (const [subagentId, claimedModeIds] of subagentModeClaims) {
338
+ for (const modeId of claimedModeIds) {
339
+ const mode = modeMap.get(modeId);
340
+ if (mode && !mode.subagents.includes(subagentId)) {
341
+ mode.subagents.push(subagentId);
342
+ }
343
+ }
344
+ }
345
+ const defaultMode = Array.from(modeMap.values()).find((m) => m.default);
346
+ if (defaultMode) {
347
+ for (const [subagentId] of subagentMap) {
348
+ if (subagentModeClaims.has(subagentId)) continue;
349
+ const isReferenced = Array.from(modeMap.values()).some((m) => m.subagents.includes(subagentId));
350
+ if (!isReferenced) {
351
+ defaultMode.subagents.push(subagentId);
352
+ }
353
+ }
354
+ }
355
+ const registry = {
356
+ modes: Array.from(modeMap.values()),
357
+ subagents: Array.from(subagentMap.values()),
358
+ diagnostics
359
+ };
360
+ validateRegistry(registry, diagnostics);
361
+ return registry;
362
+ }
363
+ function loadAgentDefinitions(projectPath) {
364
+ const entries = [{ dirPath: BUILTIN_DEFINITIONS_DIR, scope: "builtin" }];
365
+ const home = os.homedir();
366
+ for (const location of GLOBAL_AGENT_LOCATIONS) {
367
+ entries.push({ dirPath: path4.join(home, location), scope: "user" });
368
+ }
369
+ for (const location of PROJECT_AGENT_LOCATIONS) {
370
+ entries.push({ dirPath: path4.join(projectPath, location), scope: "project" });
371
+ }
372
+ return mergeDefinitions(entries);
373
+ }
374
+ function loadAgentDefinitionsCached(projectPath) {
375
+ const cached = agentDefinitionCache.get(projectPath);
376
+ if (cached) {
377
+ return {
378
+ modes: cached.modes.map((mode) => ({ ...mode, subagents: [...mode.subagents] })),
379
+ subagents: cached.subagents.map((subagent) => ({
380
+ ...subagent,
381
+ tools: [...subagent.tools],
382
+ allowedWorkspaceTools: subagent.allowedWorkspaceTools ? [...subagent.allowedWorkspaceTools] : void 0
383
+ })),
384
+ diagnostics: cached.diagnostics.map((diagnostic) => ({ ...diagnostic }))
385
+ };
386
+ }
387
+ const loaded = loadAgentDefinitions(projectPath);
388
+ agentDefinitionCache.set(projectPath, loaded);
389
+ return loadAgentDefinitionsCached(projectPath);
390
+ }
391
+ function getModeDefinition(projectPath, modeId) {
392
+ return loadAgentDefinitionsCached(projectPath).modes.find((mode) => mode.id === modeId);
393
+ }
394
+ function formatAgentDefinitionDiagnostics(diagnostics, maxItems = 5) {
395
+ if (diagnostics.length === 0) {
396
+ return null;
397
+ }
398
+ const errors = diagnostics.filter((diagnostic) => diagnostic.severity === "error");
399
+ const warnings = diagnostics.filter((diagnostic) => diagnostic.severity === "warning");
400
+ const headlineParts = [];
401
+ if (errors.length > 0) {
402
+ headlineParts.push(`${errors.length} error${errors.length === 1 ? "" : "s"}`);
403
+ }
404
+ if (warnings.length > 0) {
405
+ headlineParts.push(`${warnings.length} warning${warnings.length === 1 ? "" : "s"}`);
406
+ }
407
+ const visible = diagnostics.slice(0, maxItems);
408
+ const lines = visible.map((diagnostic) => {
409
+ const prefix = diagnostic.severity === "error" ? "error" : "warning";
410
+ return `- ${prefix}: ${diagnostic.sourcePath} \u2014 ${diagnostic.message}`;
411
+ });
412
+ if (diagnostics.length > maxItems) {
413
+ lines.push(`- ... ${diagnostics.length - maxItems} more`);
414
+ }
415
+ return `Ignored invalid custom agent definitions (${headlineParts.join(", ")}):
416
+ ${lines.join("\n")}`;
417
+ }
418
+ function getSubagentOwnerModes(registry, subagentId) {
419
+ return registry.modes.filter((mode) => mode.subagents.includes(subagentId));
420
+ }
421
+ function getAllowedSubagentIdsForMode(registry, modeId) {
422
+ return registry.modes.find((mode) => mode.id === modeId)?.subagents ?? [];
423
+ }
424
+ function getSubagentModeMap(registry) {
425
+ const mapping = {};
426
+ for (const subagent of registry.subagents) {
427
+ if (subagent.defaultModelFromMode) {
428
+ mapping[subagent.id] = subagent.defaultModelFromMode;
429
+ continue;
430
+ }
431
+ const ownerMode = registry.modes.find((mode) => mode.subagents.includes(subagent.id));
432
+ if (ownerMode) {
433
+ mapping[subagent.id] = ownerMode.id;
434
+ }
435
+ }
436
+ return mapping;
437
+ }
438
+ function createHarnessModesFromDefinitions(registry, codeAgent) {
439
+ return registry.modes.map((mode) => ({
440
+ id: mode.id,
441
+ name: mode.name,
442
+ default: mode.default,
443
+ defaultModelId: mode.defaultModelId,
444
+ color: mode.color,
445
+ agent: codeAgent
446
+ }));
447
+ }
448
+ function createHarnessSubagentsFromDefinitions(registry, disabledTools) {
449
+ return registry.subagents.map((subagent) => {
450
+ const directTools = Object.fromEntries(
451
+ subagent.tools.filter((toolId) => !disabledTools?.includes(toolId) && toolId in DIRECT_SUBAGENT_TOOLS).map((toolId) => [toolId, DIRECT_SUBAGENT_TOOLS[toolId]])
452
+ );
453
+ const allowedWorkspaceTools = subagent.allowedWorkspaceTools?.filter((toolId) => !disabledTools?.includes(toolId));
454
+ return {
455
+ id: subagent.id,
456
+ name: subagent.name,
457
+ description: subagent.description,
458
+ instructions: subagent.instructions,
459
+ defaultModelId: void 0,
460
+ allowedWorkspaceTools,
461
+ ...Object.keys(directTools).length > 0 ? { tools: directTools } : {}
462
+ };
463
+ });
464
+ }
465
+ var MAX_LOG_SIZE = 5 * 1024 * 1024;
466
+ var KEEP_SIZE = 4 * 1024 * 1024;
467
+ function formatLogArg(a) {
468
+ if (typeof a === "string") return a;
469
+ if (a instanceof Error) return a.stack ?? `${a.name}: ${a.message}`;
470
+ try {
471
+ return JSON.stringify(a);
472
+ } catch {
473
+ return String(a);
474
+ }
475
+ }
476
+ function getDebugLogFile() {
477
+ return path4__namespace.join(chunkIEV2IT3O_cjs.getAppDataDir(), "debug.log");
478
+ }
479
+ function appendDebugLogLine(level, message) {
480
+ const logFile = getDebugLogFile();
481
+ const logDir = path4__namespace.dirname(logFile);
482
+ if (!fs2__namespace.existsSync(logDir)) {
483
+ fs2__namespace.mkdirSync(logDir, { recursive: true });
484
+ }
485
+ truncateLogFile(logFile);
486
+ fs2__namespace.appendFileSync(logFile, `[${level}] ${(/* @__PURE__ */ new Date()).toISOString()} ${message}
487
+ `);
488
+ }
489
+ function truncateLogFile(logFile) {
490
+ try {
491
+ const stat = fs2__namespace.statSync(logFile);
492
+ if (stat.size > MAX_LOG_SIZE) {
493
+ const buf = Buffer.alloc(KEEP_SIZE);
494
+ const fd = fs2__namespace.openSync(logFile, "r");
495
+ fs2__namespace.readSync(fd, buf, 0, KEEP_SIZE, stat.size - KEEP_SIZE);
496
+ fs2__namespace.closeSync(fd);
497
+ const firstNewline = buf.indexOf(10);
498
+ const trimmed = firstNewline >= 0 ? buf.subarray(firstNewline + 1) : buf;
499
+ fs2__namespace.writeFileSync(logFile, trimmed);
500
+ }
501
+ } catch {
502
+ }
503
+ }
504
+ function setupDebugLogging() {
505
+ const debugEnabled = ["true", "1"].includes(process.env.MASTRA_DEBUG ?? "");
506
+ if (debugEnabled) {
507
+ const logFile = getDebugLogFile();
508
+ truncateLogFile(logFile);
509
+ const logStream = fs2__namespace.createWriteStream(logFile, { flags: "a" });
510
+ console.error = (...args) => {
511
+ logStream.write(`[ERROR] ${(/* @__PURE__ */ new Date()).toISOString()} ${args.map(formatLogArg).join(" ")}
512
+ `);
513
+ };
514
+ console.warn = (...args) => {
515
+ logStream.write(`[WARN] ${(/* @__PURE__ */ new Date()).toISOString()} ${args.map(formatLogArg).join(" ")}
516
+ `);
517
+ };
518
+ } else {
519
+ const noop = () => {
520
+ };
521
+ console.error = noop;
522
+ console.warn = noop;
523
+ }
524
+ }
525
+ function logRuntimeProfile(event, durationMs, details) {
526
+ const profileEnabled = ["true", "1"].includes(process.env.MASTRA_PROFILE ?? "");
527
+ if (!profileEnabled) return;
528
+ const payload = details ? `${event} durationMs=${durationMs.toFixed(2)} ${formatLogArg(details)}` : `${event} durationMs=${durationMs.toFixed(2)}`;
529
+ appendDebugLogLine("PROFILE", payload);
530
+ }
531
+ var STORAGE_DEFAULTS = {
532
+ backend: "libsql",
533
+ libsql: {},
534
+ pg: {}
535
+ };
536
+ var DEFAULTS = {
537
+ onboarding: {
538
+ completedAt: null,
539
+ skippedAt: null,
540
+ version: 0,
541
+ modePackId: null,
542
+ omPackId: null,
543
+ claudeMaxOAuthWarningAcknowledgedAt: null
544
+ },
545
+ models: {
546
+ activeModelPackId: null,
547
+ modeDefaults: {},
548
+ activeOmPackId: null,
549
+ omModelOverride: null,
550
+ subagentModels: {}
551
+ },
552
+ preferences: {
553
+ yolo: null,
554
+ theme: "auto",
555
+ thinkingLevel: "off",
556
+ quietMode: false
557
+ },
558
+ storage: { ...STORAGE_DEFAULTS },
559
+ customModelPacks: [],
560
+ customProviders: [],
561
+ modelUseCounts: {},
562
+ updateDismissedVersion: null,
563
+ lsp: {}
564
+ };
565
+ var THINKING_LEVEL_VALUES = ["off", "low", "medium", "high", "xhigh"];
566
+ var settingsCache = /* @__PURE__ */ new Map();
567
+ function cloneSettings(settings) {
568
+ return structuredClone(settings);
569
+ }
570
+ function parseThinkingLevel(value) {
571
+ return typeof value === "string" && THINKING_LEVEL_VALUES.includes(value) ? value : DEFAULTS.preferences.thinkingLevel;
572
+ }
573
+ function parsePreferences(rawPreferences) {
574
+ const raw = rawPreferences && typeof rawPreferences === "object" ? rawPreferences : {};
575
+ return {
576
+ ...DEFAULTS.preferences,
577
+ ...raw,
578
+ thinkingLevel: parseThinkingLevel(raw.thinkingLevel)
579
+ };
580
+ }
581
+ function getSettingsPath() {
582
+ return path4.join(chunkIEV2IT3O_cjs.getAppDataDir(), "settings.json");
583
+ }
584
+ function getCustomProviderId(name) {
585
+ const slug = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
586
+ return slug || "provider";
587
+ }
588
+ function toCustomProviderModelId(providerName, modelName) {
589
+ const providerId = getCustomProviderId(providerName);
590
+ const trimmedModelName = modelName.trim();
591
+ const providerPrefix = `${providerId}/`;
592
+ if (trimmedModelName.startsWith(providerPrefix)) {
593
+ return trimmedModelName;
594
+ }
595
+ return `${providerId}/${trimmedModelName}`;
596
+ }
597
+ function parseCustomProviders(rawProviders) {
598
+ if (!Array.isArray(rawProviders)) return [];
599
+ const parsedProviders = [];
600
+ for (const rawProvider of rawProviders) {
601
+ if (!rawProvider || typeof rawProvider !== "object") continue;
602
+ const candidate = rawProvider;
603
+ const name = typeof candidate.name === "string" ? candidate.name.trim() : "";
604
+ const url = typeof candidate.url === "string" ? candidate.url.trim() : "";
605
+ if (!name || !url) continue;
606
+ const providerId = getCustomProviderId(name);
607
+ const models = Array.isArray(candidate.models) ? [
608
+ ...new Set(
609
+ candidate.models.filter((model) => typeof model === "string").map((model) => model.trim()).map((model) => {
610
+ const providerPrefix = `${providerId}/`;
611
+ if (model.startsWith(providerPrefix)) {
612
+ return model.slice(providerPrefix.length);
613
+ }
614
+ return model;
615
+ })
616
+ )
617
+ ].filter((model) => model.length > 0) : [];
618
+ const apiKey = typeof candidate.apiKey === "string" && candidate.apiKey.trim().length > 0 ? candidate.apiKey.trim() : void 0;
619
+ parsedProviders.push({
620
+ name,
621
+ url,
622
+ ...apiKey ? { apiKey } : {},
623
+ models
624
+ });
625
+ }
626
+ return parsedProviders;
627
+ }
628
+ function migrateFromAuth(settingsPath) {
629
+ const authPath = path4.join(chunkIEV2IT3O_cjs.getAppDataDir(), "auth.json");
630
+ if (!fs2.existsSync(authPath)) return false;
631
+ let authData;
632
+ try {
633
+ authData = JSON.parse(fs2.readFileSync(authPath, "utf-8"));
634
+ } catch {
635
+ return false;
636
+ }
637
+ const modelKeys = Object.keys(authData).filter((k) => k.startsWith("_"));
638
+ if (modelKeys.length === 0) return false;
639
+ let settings;
640
+ if (fs2.existsSync(settingsPath)) {
641
+ try {
642
+ const raw = JSON.parse(fs2.readFileSync(settingsPath, "utf-8"));
643
+ settings = {
644
+ onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },
645
+ models: { ...DEFAULTS.models, ...raw.models },
646
+ preferences: parsePreferences(raw.preferences),
647
+ storage: {
648
+ ...STORAGE_DEFAULTS,
649
+ ...raw.storage,
650
+ libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },
651
+ pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg }
652
+ },
653
+ customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],
654
+ customProviders: parseCustomProviders(raw.customProviders),
655
+ modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === "object" ? raw.modelUseCounts : {},
656
+ updateDismissedVersion: typeof raw.updateDismissedVersion === "string" ? raw.updateDismissedVersion : null,
657
+ lsp: raw.lsp && typeof raw.lsp === "object" ? raw.lsp : void 0
658
+ };
659
+ } catch {
660
+ settings = structuredClone(DEFAULTS);
661
+ }
662
+ } else {
663
+ settings = structuredClone(DEFAULTS);
664
+ }
665
+ if (authData._modelRanks && typeof authData._modelRanks === "object") {
666
+ settings.modelUseCounts = { ...authData._modelRanks, ...settings.modelUseCounts };
667
+ }
668
+ for (const key of modelKeys) {
669
+ const modeMatch = key.match(/^_modeModelId_(.+)$/);
670
+ if (modeMatch?.[1] && typeof authData[key] === "string" && !settings.models.modeDefaults[modeMatch[1]]) {
671
+ settings.models.modeDefaults[modeMatch[1]] = authData[key];
672
+ }
673
+ }
674
+ for (const key of modelKeys) {
675
+ if (key === "_subagentModelId" && typeof authData[key] === "string" && !settings.models.subagentModels["default"]) {
676
+ settings.models.subagentModels["default"] = authData[key];
677
+ }
678
+ const saMatch = key.match(/^_subagentModelId_(.+)$/);
679
+ if (saMatch?.[1] && typeof authData[key] === "string" && !settings.models.subagentModels[saMatch[1]]) {
680
+ settings.models.subagentModels[saMatch[1]] = authData[key];
681
+ }
682
+ }
683
+ saveSettings(settings, settingsPath);
684
+ for (const key of modelKeys) {
685
+ delete authData[key];
686
+ }
687
+ try {
688
+ fs2.writeFileSync(authPath, JSON.stringify(authData, null, 2), "utf-8");
689
+ } catch {
690
+ }
691
+ return true;
692
+ }
693
+ var LEGACY_VARIED_MODELS = {
694
+ plan: "openai/gpt-5.3-codex",
695
+ build: "anthropic/claude-sonnet-4-5",
696
+ fast: "anthropic/claude-haiku-4-5"
697
+ };
698
+ function migrateLegacyVariedPack(settings) {
699
+ const legacyPackId = "varied";
700
+ const customPackId = "custom:varied";
701
+ const hasLegacyReference = settings.models.activeModelPackId === legacyPackId || settings.onboarding.modePackId === legacyPackId;
702
+ if (!hasLegacyReference) return false;
703
+ const existingIdx = settings.customModelPacks.findIndex((p) => p.name === "varied");
704
+ if (existingIdx >= 0) {
705
+ const existing = settings.customModelPacks[existingIdx];
706
+ const modelsMatch = Object.entries(LEGACY_VARIED_MODELS).every(([k, v]) => existing.models[k] === v);
707
+ if (!modelsMatch) {
708
+ existing.models = { ...LEGACY_VARIED_MODELS };
709
+ }
710
+ } else {
711
+ settings.customModelPacks.push({
712
+ name: "varied",
713
+ models: { ...LEGACY_VARIED_MODELS },
714
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
715
+ });
716
+ }
717
+ if (settings.models.activeModelPackId === legacyPackId) {
718
+ settings.models.activeModelPackId = customPackId;
719
+ if (Object.keys(settings.models.modeDefaults).length === 0) {
720
+ settings.models.modeDefaults = { ...LEGACY_VARIED_MODELS };
721
+ }
722
+ }
723
+ if (settings.onboarding.modePackId === legacyPackId) {
724
+ settings.onboarding.modePackId = customPackId;
725
+ }
726
+ return true;
727
+ }
728
+ function loadSettings(filePath = getSettingsPath()) {
729
+ migrateFromAuth(filePath);
730
+ if (!fs2.existsSync(filePath)) return structuredClone(DEFAULTS);
731
+ try {
732
+ const raw = JSON.parse(fs2.readFileSync(filePath, "utf-8"));
733
+ const settings = {
734
+ ...raw,
735
+ onboarding: { ...DEFAULTS.onboarding, ...raw.onboarding },
736
+ models: { ...DEFAULTS.models, ...raw.models },
737
+ preferences: parsePreferences(raw.preferences),
738
+ storage: {
739
+ ...STORAGE_DEFAULTS,
740
+ ...raw.storage,
741
+ libsql: { ...STORAGE_DEFAULTS.libsql, ...raw.storage?.libsql },
742
+ pg: { ...STORAGE_DEFAULTS.pg, ...raw.storage?.pg }
743
+ },
744
+ customModelPacks: Array.isArray(raw.customModelPacks) ? raw.customModelPacks : [],
745
+ customProviders: parseCustomProviders(raw.customProviders),
746
+ modelUseCounts: raw.modelUseCounts && typeof raw.modelUseCounts === "object" ? raw.modelUseCounts : {},
747
+ updateDismissedVersion: typeof raw.updateDismissedVersion === "string" ? raw.updateDismissedVersion : null,
748
+ lsp: raw.lsp && typeof raw.lsp === "object" ? raw.lsp : void 0
749
+ };
750
+ let settingsChanged = false;
751
+ if (raw.models?.omModelId && !settings.models.omModelOverride) {
752
+ settings.models.omModelOverride = raw.models.omModelId;
753
+ settingsChanged = true;
754
+ }
755
+ if (migrateLegacyVariedPack(settings)) {
756
+ settingsChanged = true;
757
+ }
758
+ if (settingsChanged) {
759
+ saveSettings(settings, filePath);
760
+ }
761
+ return settings;
762
+ } catch {
763
+ return structuredClone(DEFAULTS);
764
+ }
765
+ }
766
+ function loadSettingsCached(filePath = getSettingsPath()) {
767
+ const cached = settingsCache.get(filePath);
768
+ if (cached) {
769
+ return cloneSettings(cached);
770
+ }
771
+ const settings = loadSettings(filePath);
772
+ settingsCache.set(filePath, cloneSettings(settings));
773
+ return cloneSettings(settings);
774
+ }
775
+ var THREAD_ACTIVE_MODEL_PACK_ID_KEY = "activeModelPackId";
776
+ function parseThreadSettings(metadata) {
777
+ const modeModelIds = {};
778
+ for (const [key, value] of Object.entries(metadata ?? {})) {
779
+ const modeMatch = key.match(/^modeModelId_(.+)$/);
780
+ if (modeMatch?.[1] && typeof value === "string" && value.length > 0) {
781
+ modeModelIds[modeMatch[1]] = value;
782
+ }
783
+ }
784
+ const rawPackId = metadata?.[THREAD_ACTIVE_MODEL_PACK_ID_KEY];
785
+ const activeModelPackId = typeof rawPackId === "string" && rawPackId.length > 0 ? rawPackId : null;
786
+ return {
787
+ activeModelPackId,
788
+ modeModelIds
789
+ };
790
+ }
791
+ function resolveThreadActiveModelPackId(settings, builtinPacks, metadata) {
792
+ const threadSettings = parseThreadSettings(metadata);
793
+ const isKnownPack = (packId) => {
794
+ if (packId.startsWith("custom:")) {
795
+ const name = packId.slice("custom:".length);
796
+ return settings.customModelPacks.some((p) => p.name === name);
797
+ }
798
+ return builtinPacks.some((p) => p.id === packId);
799
+ };
800
+ if (threadSettings.activeModelPackId && isKnownPack(threadSettings.activeModelPackId)) {
801
+ return threadSettings.activeModelPackId;
802
+ }
803
+ const allPacks = [
804
+ ...builtinPacks,
805
+ ...settings.customModelPacks.map((p) => ({ id: `custom:${p.name}`, models: p.models }))
806
+ ];
807
+ for (const pack of allPacks) {
808
+ const packEntries = Object.entries(pack.models);
809
+ const threadEntries = Object.keys(threadSettings.modeModelIds);
810
+ const matches = packEntries.length === threadEntries.length && packEntries.every(([modeId, modelId]) => threadSettings.modeModelIds[modeId] === modelId);
811
+ if (matches) return pack.id;
812
+ }
813
+ if (settings.models.activeModelPackId && isKnownPack(settings.models.activeModelPackId)) {
814
+ return settings.models.activeModelPackId;
815
+ }
816
+ return null;
817
+ }
818
+ function resolveModelDefaults(settings, builtinPacks) {
819
+ const { activeModelPackId, modeDefaults } = settings.models;
820
+ if (!activeModelPackId) return modeDefaults;
821
+ if (activeModelPackId.startsWith("custom:")) {
822
+ const name = activeModelPackId.slice("custom:".length);
823
+ const pack = settings.customModelPacks.find((p) => p.name === name);
824
+ if (pack) return pack.models;
825
+ return modeDefaults;
826
+ }
827
+ const builtin = builtinPacks.find((p) => p.id === activeModelPackId);
828
+ if (builtin) return builtin.models;
829
+ return modeDefaults;
830
+ }
831
+ function resolveOmModel(settings, builtinOmPacks) {
832
+ const { activeOmPackId, omModelOverride } = settings.models;
833
+ if (!activeOmPackId) return omModelOverride;
834
+ if (activeOmPackId === "custom") return omModelOverride;
835
+ const pack = builtinOmPacks.find((p) => p.id === activeOmPackId);
836
+ if (pack) return pack.modelId;
837
+ return omModelOverride;
838
+ }
839
+ function saveSettings(settings, filePath = getSettingsPath()) {
840
+ const dir = path4.dirname(filePath);
841
+ if (!fs2.existsSync(dir)) {
842
+ fs2.mkdirSync(dir, { recursive: true });
843
+ }
844
+ fs2.writeFileSync(filePath, JSON.stringify(settings, null, 2), "utf-8");
845
+ settingsCache.set(filePath, cloneSettings(settings));
846
+ }
847
+ var LSPClient = class {
848
+ connection = null;
849
+ process = null;
850
+ serverInfo;
851
+ workspaceRoot;
852
+ diagnostics = /* @__PURE__ */ new Map();
853
+ initializationOptions = null;
854
+ constructor(serverInfo, workspaceRoot) {
855
+ this.serverInfo = serverInfo;
856
+ this.workspaceRoot = workspaceRoot;
857
+ }
858
+ /**
859
+ * Initialize the LSP connection
860
+ */
861
+ async initialize() {
862
+ const spawnResult = await this.serverInfo.spawn(this.workspaceRoot);
863
+ if (!spawnResult) {
864
+ throw new Error("Failed to spawn LSP server");
865
+ }
866
+ let initializationOptions = void 0;
867
+ if ("process" in spawnResult) {
868
+ this.process = spawnResult.process;
869
+ initializationOptions = spawnResult.initialization;
870
+ } else {
871
+ this.process = spawnResult;
872
+ }
873
+ if (!this.process.stdin || !this.process.stdout) {
874
+ throw new Error("Failed to create LSP process with proper stdio");
875
+ }
876
+ const reader = new node_js.StreamMessageReader(this.process.stdout);
877
+ const writer = new node_js.StreamMessageWriter(this.process.stdin);
878
+ this.connection = node_js.createMessageConnection(reader, writer);
879
+ this.connection.onError((error) => {
880
+ });
881
+ this.connection.onNotification("textDocument/publishDiagnostics", (params) => {
882
+ this.diagnostics.set(params.uri, params.diagnostics);
883
+ });
884
+ this.connection.onNotification((_method, _params) => {
885
+ });
886
+ this.connection.listen();
887
+ if (this.process.stderr) {
888
+ this.process.stderr.on("data", (_data) => {
889
+ });
890
+ }
891
+ this.process.on("error", (_error) => {
892
+ });
893
+ this.process.on("exit", (_code, _signal) => {
894
+ });
895
+ const initParams = {
896
+ processId: process.pid,
897
+ rootUri: `file://${this.workspaceRoot}`,
898
+ workspaceFolders: [
899
+ {
900
+ name: "workspace",
901
+ uri: `file://${this.workspaceRoot}`
902
+ }
903
+ ],
904
+ capabilities: {
905
+ window: {
906
+ workDoneProgress: true
907
+ },
908
+ workspace: {
909
+ configuration: true
910
+ },
911
+ textDocument: {
912
+ publishDiagnostics: {
913
+ relatedInformation: true,
914
+ tagSupport: {
915
+ valueSet: [1, 2]
916
+ },
917
+ versionSupport: false
918
+ },
919
+ synchronization: {
920
+ didOpen: true,
921
+ didChange: true,
922
+ dynamicRegistration: false,
923
+ willSave: false,
924
+ willSaveWaitUntil: false,
925
+ didSave: false
926
+ },
927
+ completion: {
928
+ dynamicRegistration: false,
929
+ completionItem: {
930
+ snippetSupport: false,
931
+ commitCharactersSupport: false,
932
+ documentationFormat: ["markdown", "plaintext"],
933
+ deprecatedSupport: false,
934
+ preselectSupport: false
935
+ }
936
+ },
937
+ definition: {
938
+ dynamicRegistration: false,
939
+ linkSupport: true
940
+ },
941
+ typeDefinition: {
942
+ dynamicRegistration: false,
943
+ linkSupport: true
944
+ },
945
+ implementation: {
946
+ dynamicRegistration: false,
947
+ linkSupport: true
948
+ },
949
+ references: {
950
+ dynamicRegistration: false
951
+ },
952
+ documentHighlight: {
953
+ dynamicRegistration: false
954
+ },
955
+ documentSymbol: {
956
+ dynamicRegistration: false,
957
+ hierarchicalDocumentSymbolSupport: true
958
+ },
959
+ codeAction: {
960
+ dynamicRegistration: false,
961
+ codeActionLiteralSupport: {
962
+ codeActionKind: {
963
+ valueSet: [
964
+ "quickfix",
965
+ "refactor",
966
+ "refactor.extract",
967
+ "refactor.inline",
968
+ "refactor.rewrite",
969
+ "source",
970
+ "source.organizeImports"
971
+ ]
972
+ }
973
+ }
974
+ },
975
+ hover: {
976
+ dynamicRegistration: false,
977
+ contentFormat: ["markdown", "plaintext"]
978
+ }
979
+ }
980
+ }
981
+ };
982
+ if (initializationOptions) {
983
+ initParams.initializationOptions = initializationOptions;
984
+ this.initializationOptions = initializationOptions;
985
+ }
986
+ this.connection.onRequest("workspace/configuration", (params) => {
987
+ return params.items?.map(() => ({})) || [];
988
+ });
989
+ this.connection.onRequest("window/workDoneProgress/create", (_params) => {
990
+ return null;
991
+ });
992
+ await Promise.race([
993
+ this.connection.sendRequest("initialize", initParams),
994
+ new Promise((_, reject) => setTimeout(() => reject(new Error("LSP initialize request timed out")), 1e4))
995
+ ]);
996
+ try {
997
+ this.connection.sendNotification("initialized", {});
998
+ } catch {
999
+ return;
1000
+ }
1001
+ try {
1002
+ if (this.initializationOptions) {
1003
+ this.connection.sendNotification("workspace/didChangeConfiguration", {
1004
+ settings: this.initializationOptions
1005
+ });
1006
+ } else {
1007
+ this.connection.sendNotification("workspace/didChangeConfiguration", {
1008
+ settings: {}
1009
+ });
1010
+ }
1011
+ } catch {
1012
+ }
1013
+ }
1014
+ /**
1015
+ * Notify the server that a document has been opened
1016
+ */
1017
+ notifyOpen(filePath, content, languageId) {
1018
+ if (!this.connection) return;
1019
+ const uri = `file://${filePath}`;
1020
+ this.diagnostics.delete(uri);
1021
+ this.connection.sendNotification("textDocument/didOpen", {
1022
+ textDocument: {
1023
+ uri,
1024
+ languageId,
1025
+ version: 0,
1026
+ text: content
1027
+ }
1028
+ });
1029
+ }
1030
+ /**
1031
+ * Notify the server that a document has changed
1032
+ */
1033
+ notifyChange(filePath, content, version) {
1034
+ if (!this.connection) return;
1035
+ this.connection.sendNotification("textDocument/didChange", {
1036
+ textDocument: {
1037
+ uri: `file://${filePath}`,
1038
+ version
1039
+ },
1040
+ contentChanges: [{ text: content }]
1041
+ });
1042
+ }
1043
+ /**
1044
+ * Wait for diagnostics to be available for a specific file
1045
+ * @param waitForChange If true, waits for diagnostics to change from their initial state
1046
+ */
1047
+ async waitForDiagnostics(filePath, timeoutMs = 5e3, waitForChange = false) {
1048
+ if (!this.connection) return [];
1049
+ const uri = `file://${filePath}`;
1050
+ const startTime = Date.now();
1051
+ const initialDiagnostics = this.diagnostics.get(uri);
1052
+ const initialCount = initialDiagnostics?.length || 0;
1053
+ while (Date.now() - startTime < timeoutMs) {
1054
+ const currentDiagnostics = this.diagnostics.get(uri);
1055
+ const currentCount = currentDiagnostics?.length || 0;
1056
+ if (waitForChange) {
1057
+ if (currentDiagnostics !== void 0 && currentCount !== initialCount) {
1058
+ return currentDiagnostics;
1059
+ }
1060
+ } else {
1061
+ if (currentDiagnostics !== void 0) {
1062
+ return currentDiagnostics;
1063
+ }
1064
+ }
1065
+ await new Promise((resolve) => setTimeout(resolve, 100));
1066
+ }
1067
+ return waitForChange ? initialDiagnostics || [] : [];
1068
+ }
1069
+ /**
1070
+ * Get hover information for a position
1071
+ */
1072
+ async getHover(filePath, line, character) {
1073
+ if (!this.connection) return null;
1074
+ try {
1075
+ return await this.connection.sendRequest("textDocument/hover", {
1076
+ textDocument: vscodeLanguageserverProtocol.TextDocumentIdentifier.create(`file://${filePath}`),
1077
+ position: vscodeLanguageserverProtocol.Position.create(line, character)
1078
+ });
1079
+ } catch {
1080
+ return null;
1081
+ }
1082
+ }
1083
+ /**
1084
+ * Get diagnostics for a specific file
1085
+ */
1086
+ getDiagnostics(filePath) {
1087
+ const uri = `file://${filePath}`;
1088
+ return this.diagnostics.get(uri) || [];
1089
+ }
1090
+ /**
1091
+ * Get all diagnostics from all files
1092
+ */
1093
+ getAllDiagnostics() {
1094
+ const allDiagnostics = [];
1095
+ for (const diagnostics of this.diagnostics.values()) {
1096
+ allDiagnostics.push(...diagnostics);
1097
+ }
1098
+ return allDiagnostics;
1099
+ }
1100
+ /**
1101
+ * Notify server that a file was closed
1102
+ */
1103
+ notifyClose(filePath) {
1104
+ if (!this.connection) return;
1105
+ const uri = `file://${filePath}`;
1106
+ this.diagnostics.delete(uri);
1107
+ this.connection.sendNotification("textDocument/didClose", {
1108
+ textDocument: vscodeLanguageserverProtocol.TextDocumentIdentifier.create(uri)
1109
+ });
1110
+ }
1111
+ /**
1112
+ * Restart the LSP client
1113
+ */
1114
+ async restart() {
1115
+ await this.shutdown();
1116
+ await this.initialize();
1117
+ }
1118
+ /**
1119
+ * Shutdown the connection
1120
+ */
1121
+ async shutdown() {
1122
+ if (this.connection) {
1123
+ try {
1124
+ const processAlive = this.process && !this.process.killed;
1125
+ if (processAlive) {
1126
+ await Promise.race([
1127
+ this.connection.sendRequest("shutdown"),
1128
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Shutdown request timed out")), 1e3))
1129
+ ]);
1130
+ this.connection.sendNotification("exit");
1131
+ }
1132
+ } catch {
1133
+ }
1134
+ try {
1135
+ this.connection.dispose();
1136
+ } catch {
1137
+ }
1138
+ this.connection = null;
1139
+ }
1140
+ if (this.process) {
1141
+ try {
1142
+ if (!this.process.killed) {
1143
+ this.process.kill();
1144
+ }
1145
+ } catch {
1146
+ }
1147
+ this.process = null;
1148
+ }
1149
+ this.diagnostics = /* @__PURE__ */ new Map();
1150
+ }
1151
+ };
1152
+
1153
+ // src/lsp/language.ts
1154
+ var LANGUAGE_EXTENSIONS = {
1155
+ // TypeScript/JavaScript
1156
+ ".ts": "typescript",
1157
+ ".tsx": "typescriptreact",
1158
+ ".js": "javascript",
1159
+ ".jsx": "javascriptreact",
1160
+ ".mjs": "javascript",
1161
+ ".cjs": "javascript",
1162
+ // Python
1163
+ ".py": "python",
1164
+ ".pyi": "python",
1165
+ // Go
1166
+ ".go": "go",
1167
+ // Rust
1168
+ ".rs": "rust",
1169
+ // C/C++
1170
+ ".c": "c",
1171
+ ".cpp": "cpp",
1172
+ ".cc": "cpp",
1173
+ ".cxx": "cpp",
1174
+ ".h": "c",
1175
+ ".hpp": "cpp",
1176
+ // Java
1177
+ ".java": "java",
1178
+ // JSON
1179
+ ".json": "json",
1180
+ ".jsonc": "jsonc",
1181
+ // YAML
1182
+ ".yaml": "yaml",
1183
+ ".yml": "yaml",
1184
+ // Markdown
1185
+ ".md": "markdown",
1186
+ // HTML/CSS
1187
+ ".html": "html",
1188
+ ".css": "css",
1189
+ ".scss": "scss",
1190
+ ".sass": "sass",
1191
+ ".less": "less"
1192
+ };
1193
+ function getLanguageId(filePath) {
1194
+ const ext = filePath.substring(filePath.lastIndexOf("."));
1195
+ return LANGUAGE_EXTENSIONS[ext];
1196
+ }
1197
+
1198
+ // src/lsp/server.ts
1199
+ function resolveLocalBin(binName, baseDir = process.cwd()) {
1200
+ const binDir = path4.join(baseDir, "node_modules", ".bin");
1201
+ const windowsPath = path4.join(binDir, `${binName}.cmd`);
1202
+ const defaultPath = path4.join(binDir, binName);
1203
+ if (process.platform === "win32" && fs2.existsSync(windowsPath)) {
1204
+ return windowsPath;
1205
+ }
1206
+ return defaultPath;
1207
+ }
1208
+ function findNearestRoot(cwd, markers) {
1209
+ let current = cwd;
1210
+ while (current !== "/") {
1211
+ for (const marker of markers) {
1212
+ if (fs2.existsSync(path4.join(current, marker))) {
1213
+ return current;
1214
+ }
1215
+ }
1216
+ const parent = path4.join(current, "..");
1217
+ if (parent === current) break;
1218
+ current = parent;
1219
+ }
1220
+ return null;
1221
+ }
1222
+ var BUILTIN_SERVERS = {
1223
+ typescript: {
1224
+ id: "typescript",
1225
+ name: "TypeScript Language Server",
1226
+ languageIds: ["typescript", "typescriptreact", "javascript", "javascriptreact"],
1227
+ installHint: "Install typescript-language-server for TypeScript LSP support",
1228
+ root: (cwd) => findNearestRoot(cwd, ["tsconfig.json", "package.json"]),
1229
+ spawn: async (root) => {
1230
+ const requireFromRoot = module$1.createRequire(url.pathToFileURL(path4__namespace.default.join(root, "package.json")));
1231
+ let tsserver;
1232
+ try {
1233
+ tsserver = requireFromRoot.resolve("typescript/lib/tsserver.js");
1234
+ } catch {
1235
+ tsserver = void 0;
1236
+ }
1237
+ if (!tsserver) {
1238
+ return void 0;
1239
+ }
1240
+ const localBin = resolveLocalBin("typescript-language-server", root);
1241
+ const cwdBin = resolveLocalBin("typescript-language-server");
1242
+ let tslsBinary;
1243
+ if (fs2.existsSync(localBin)) {
1244
+ tslsBinary = localBin;
1245
+ } else if (fs2.existsSync(cwdBin)) {
1246
+ tslsBinary = cwdBin;
1247
+ }
1248
+ if (!tslsBinary) {
1249
+ return void 0;
1250
+ }
1251
+ const proc = child_process.spawn(tslsBinary, ["--stdio"], {
1252
+ cwd: root,
1253
+ stdio: ["pipe", "pipe", "pipe"]
1254
+ });
1255
+ return {
1256
+ process: proc,
1257
+ initialization: {
1258
+ tsserver: {
1259
+ path: tsserver,
1260
+ logVerbosity: "off"
1261
+ }
1262
+ }
1263
+ };
1264
+ }
1265
+ },
1266
+ eslint: {
1267
+ id: "eslint",
1268
+ name: "ESLint Language Server",
1269
+ languageIds: ["typescript", "typescriptreact", "javascript", "javascriptreact"],
1270
+ installHint: "Install eslint-lsp for ESLint diagnostics",
1271
+ root: (cwd) => findNearestRoot(cwd, ["package.json", ".eslintrc.js", ".eslintrc.json", ".eslintrc.yml", ".eslintrc.yaml"]),
1272
+ spawn: (root) => {
1273
+ const binaryPath = resolveLocalBin("eslint-lsp");
1274
+ return child_process.spawn(binaryPath, ["--stdio"], {
1275
+ cwd: root,
1276
+ stdio: ["pipe", "pipe", "pipe"]
1277
+ });
1278
+ }
1279
+ },
1280
+ python: {
1281
+ id: "python",
1282
+ name: "Python Language Server (Pyright)",
1283
+ languageIds: ["python"],
1284
+ installHint: "Install pyright for Python LSP support",
1285
+ root: (cwd) => findNearestRoot(cwd, ["pyproject.toml", "setup.py", "requirements.txt", ".git"]),
1286
+ spawn: (root) => {
1287
+ const localPath = resolveLocalBin("pyright-langserver");
1288
+ const binaryPath = fs2.existsSync(localPath) ? localPath : "pyright-langserver";
1289
+ return child_process.spawn(binaryPath, ["--stdio"], {
1290
+ cwd: root,
1291
+ stdio: ["pipe", "pipe", "pipe"]
1292
+ });
1293
+ }
1294
+ },
1295
+ go: {
1296
+ id: "go",
1297
+ name: "Go Language Server (gopls)",
1298
+ languageIds: ["go"],
1299
+ installHint: "Install gopls for Go LSP support",
1300
+ root: (cwd) => findNearestRoot(cwd, ["go.mod", ".git"]),
1301
+ spawn: (root) => {
1302
+ return child_process.spawn("gopls", ["serve"], {
1303
+ cwd: root,
1304
+ stdio: ["pipe", "pipe", "pipe"]
1305
+ });
1306
+ }
1307
+ },
1308
+ rust: {
1309
+ id: "rust",
1310
+ name: "Rust Language Server (rust-analyzer)",
1311
+ languageIds: ["rust"],
1312
+ installHint: "Install rust-analyzer for Rust LSP support",
1313
+ root: (cwd) => findNearestRoot(cwd, ["Cargo.toml", ".git"]),
1314
+ spawn: (root) => {
1315
+ return child_process.spawn("rust-analyzer", ["--stdio"], {
1316
+ cwd: root,
1317
+ stdio: ["pipe", "pipe", "pipe"]
1318
+ });
1319
+ }
1320
+ }
1321
+ };
1322
+ function getServersForFile(filePath, cwd) {
1323
+ const languageId = getLanguageId(filePath);
1324
+ if (!languageId) return [];
1325
+ return Object.values(BUILTIN_SERVERS).filter(
1326
+ (server) => server.languageIds.includes(languageId) && server.root(cwd) !== null
1327
+ );
1328
+ }
1329
+ var LSP_INIT_TIMEOUT_MS = 15e3;
1330
+ var LSP_FAILURE_COOLDOWN_MS = 3e4;
1331
+ var LSPManager = class {
1332
+ clients = /* @__PURE__ */ new Map();
1333
+ initializationPromises = /* @__PURE__ */ new Map();
1334
+ clientStatuses = /* @__PURE__ */ new Map();
1335
+ unavailableServers = /* @__PURE__ */ new Map();
1336
+ statusListeners = /* @__PURE__ */ new Set();
1337
+ emitStatusChange() {
1338
+ for (const listener of this.statusListeners) {
1339
+ listener();
1340
+ }
1341
+ }
1342
+ setClientStatus(key, status) {
1343
+ this.clientStatuses.set(key, status);
1344
+ this.emitStatusChange();
1345
+ }
1346
+ getClientKey(filePath, workspaceRoot) {
1347
+ const servers = getServersForFile(filePath, workspaceRoot);
1348
+ if (servers.length === 0) {
1349
+ return { key: "" };
1350
+ }
1351
+ const serverInfo = servers.find(
1352
+ (s) => s.languageIds.includes("typescript") || s.languageIds.includes("javascript") || s.languageIds.includes("python") || s.languageIds.includes("go")
1353
+ ) || servers[0];
1354
+ if (!serverInfo) {
1355
+ return { key: "" };
1356
+ }
1357
+ return {
1358
+ key: `${serverInfo.name}:${workspaceRoot}`,
1359
+ serverInfo
1360
+ };
1361
+ }
1362
+ isInFailureCooldown(key) {
1363
+ const status = this.clientStatuses.get(key);
1364
+ return status?.state === "failed" && Date.now() - status.failedAt < LSP_FAILURE_COOLDOWN_MS;
1365
+ }
1366
+ async initializeClient(key, serverInfo, workspaceRoot) {
1367
+ const startedAt = Date.now();
1368
+ this.unavailableServers.delete(key);
1369
+ this.setClientStatus(key, { state: "initializing", startedAt });
1370
+ const initPromise = (async () => {
1371
+ const client = new LSPClient(serverInfo, workspaceRoot);
1372
+ await client.initialize();
1373
+ this.clients.set(key, client);
1374
+ })();
1375
+ this.initializationPromises.set(key, initPromise);
1376
+ try {
1377
+ await Promise.race([
1378
+ initPromise,
1379
+ new Promise(
1380
+ (_, reject) => setTimeout(() => reject(new Error("LSP client initialization timed out")), LSP_INIT_TIMEOUT_MS)
1381
+ )
1382
+ ]);
1383
+ const durationMs = Date.now() - startedAt;
1384
+ this.setClientStatus(key, { state: "ready", readyAt: Date.now(), durationMs });
1385
+ logRuntimeProfile("lsp.initialize", durationMs, {
1386
+ key,
1387
+ status: "ready"
1388
+ });
1389
+ } catch (error) {
1390
+ const durationMs = Date.now() - startedAt;
1391
+ const message = error instanceof Error ? error.message : String(error);
1392
+ this.clients.delete(key);
1393
+ if (message === "Failed to spawn LSP server") {
1394
+ this.clientStatuses.delete(key);
1395
+ this.unavailableServers.set(key, {
1396
+ serverName: serverInfo.name,
1397
+ installHint: serverInfo.installHint
1398
+ });
1399
+ this.emitStatusChange();
1400
+ logRuntimeProfile("lsp.initialize", durationMs, {
1401
+ key,
1402
+ status: "unavailable"
1403
+ });
1404
+ return;
1405
+ }
1406
+ this.setClientStatus(key, {
1407
+ state: "failed",
1408
+ failedAt: Date.now(),
1409
+ durationMs,
1410
+ error: message
1411
+ });
1412
+ logRuntimeProfile("lsp.initialize", durationMs, {
1413
+ key,
1414
+ status: "failed",
1415
+ error: message
1416
+ });
1417
+ throw error;
1418
+ } finally {
1419
+ this.initializationPromises.delete(key);
1420
+ }
1421
+ }
1422
+ /**
1423
+ * Get or create an LSP client for a file
1424
+ * Returns null if no LSP server is available for the file
1425
+ */
1426
+ async getClient(filePath, workspaceRoot) {
1427
+ const { key, serverInfo } = this.getClientKey(filePath, workspaceRoot);
1428
+ if (!serverInfo || !key) {
1429
+ return null;
1430
+ }
1431
+ if (this.clients.has(key)) {
1432
+ return this.clients.get(key);
1433
+ }
1434
+ if (this.isInFailureCooldown(key)) {
1435
+ return null;
1436
+ }
1437
+ if (this.initializationPromises.has(key)) {
1438
+ await this.initializationPromises.get(key);
1439
+ return this.clients.get(key) || null;
1440
+ }
1441
+ try {
1442
+ await this.initializeClient(key, serverInfo, workspaceRoot);
1443
+ return this.clients.get(key) || null;
1444
+ } catch {
1445
+ return null;
1446
+ }
1447
+ }
1448
+ prewarmClient(filePath, workspaceRoot) {
1449
+ const { key, serverInfo } = this.getClientKey(filePath, workspaceRoot);
1450
+ if (!serverInfo || !key || this.clients.has(key) || this.initializationPromises.has(key) || this.isInFailureCooldown(key)) {
1451
+ return;
1452
+ }
1453
+ void this.initializeClient(key, serverInfo, workspaceRoot).catch(() => {
1454
+ });
1455
+ }
1456
+ getClientStatus(filePath, workspaceRoot) {
1457
+ const { key } = this.getClientKey(filePath, workspaceRoot);
1458
+ if (!key) return { state: "idle" };
1459
+ return this.clientStatuses.get(key) ?? { state: "idle" };
1460
+ }
1461
+ getInitializingClientCount() {
1462
+ let count = 0;
1463
+ for (const status of this.clientStatuses.values()) {
1464
+ if (status.state === "initializing") {
1465
+ count += 1;
1466
+ }
1467
+ }
1468
+ return count;
1469
+ }
1470
+ getUnavailableClientCount() {
1471
+ return this.unavailableServers.size;
1472
+ }
1473
+ getUnavailableStatusHint() {
1474
+ const unavailable = Array.from(this.unavailableServers.values());
1475
+ if (unavailable.length === 0) {
1476
+ return null;
1477
+ }
1478
+ const first = unavailable[0];
1479
+ if (unavailable.length === 1) {
1480
+ return first?.installHint ?? `${first?.serverName} unavailable`;
1481
+ }
1482
+ return `${first?.installHint ?? `${first?.serverName} unavailable`} (+${unavailable.length - 1} more)`;
1483
+ }
1484
+ subscribeStatusChange(listener) {
1485
+ this.statusListeners.add(listener);
1486
+ return () => {
1487
+ this.statusListeners.delete(listener);
1488
+ };
1489
+ }
1490
+ prewarmWorkspace(workspaceRoot) {
1491
+ const candidates = ["index.ts", "index.js", "main.py", "main.go", "main.rs"];
1492
+ for (const candidate of candidates) {
1493
+ const filePath = path4__namespace.default.join(workspaceRoot, candidate);
1494
+ const { serverInfo } = this.getClientKey(filePath, workspaceRoot);
1495
+ if (serverInfo) {
1496
+ this.prewarmClient(filePath, workspaceRoot);
1497
+ return;
1498
+ }
1499
+ }
1500
+ }
1501
+ /**
1502
+ * Shutdown a specific client
1503
+ */
1504
+ async shutdownClient(workspaceRoot, serverName) {
1505
+ const keysToRemove = [];
1506
+ for (const [key, client] of this.clients.entries()) {
1507
+ if (key.includes(workspaceRoot) && (!serverName || key.startsWith(serverName))) {
1508
+ await client.shutdown();
1509
+ keysToRemove.push(key);
1510
+ }
1511
+ }
1512
+ for (const key of keysToRemove) {
1513
+ this.clients.delete(key);
1514
+ this.clientStatuses.delete(key);
1515
+ this.unavailableServers.delete(key);
1516
+ this.emitStatusChange();
1517
+ }
1518
+ }
1519
+ /**
1520
+ * Shutdown all clients
1521
+ */
1522
+ async shutdownAll() {
1523
+ const shutdownPromises = Array.from(this.clients.values()).map((client) => client.shutdown());
1524
+ await Promise.all(shutdownPromises);
1525
+ this.clients.clear();
1526
+ this.initializationPromises.clear();
1527
+ this.clientStatuses.clear();
1528
+ this.unavailableServers.clear();
1529
+ this.emitStatusChange();
1530
+ }
1531
+ /**
1532
+ * Get the number of active clients
1533
+ */
1534
+ getActiveClientCount() {
1535
+ return this.clients.size;
1536
+ }
1537
+ /**
1538
+ * Close a document in all active clients
1539
+ * This is useful for tests that reuse the same file path
1540
+ */
1541
+ closeDocument(filePath) {
1542
+ for (const client of this.clients.values()) {
1543
+ try {
1544
+ client.notifyClose(filePath);
1545
+ } catch {
1546
+ }
1547
+ }
1548
+ }
1549
+ };
1550
+ var lspManager = new LSPManager();
1551
+
1552
+ // src/onboarding/packs.ts
1553
+ var DEFAULT_PACK_MODE_IDS = ["plan", "build", "fast"];
1554
+ var MODE_PRIORITY = ["plan", "build", "fast", "ask"];
1555
+ function sortModeIds(modeIds) {
1556
+ return [...modeIds].sort((left, right) => {
1557
+ const leftPriority = MODE_PRIORITY.indexOf(left);
1558
+ const rightPriority = MODE_PRIORITY.indexOf(right);
1559
+ const leftRank = leftPriority === -1 ? Number.MAX_SAFE_INTEGER : leftPriority;
1560
+ const rightRank = rightPriority === -1 ? Number.MAX_SAFE_INTEGER : rightPriority;
1561
+ if (leftRank !== rightRank) return leftRank - rightRank;
1562
+ return left.localeCompare(right);
1563
+ });
1564
+ }
1565
+ function getModePackOptions(modeDefinitions = []) {
1566
+ if (modeDefinitions.length === 0) {
1567
+ return DEFAULT_PACK_MODE_IDS.map((id) => ({ id, label: id }));
1568
+ }
1569
+ const seen = /* @__PURE__ */ new Set();
1570
+ const modes = modeDefinitions.map((definition) => ({
1571
+ id: definition.id.trim(),
1572
+ label: definition.name?.trim() || definition.id.trim(),
1573
+ color: definition.color?.trim()
1574
+ })).filter((mode) => {
1575
+ if (!mode.id || seen.has(mode.id)) return false;
1576
+ seen.add(mode.id);
1577
+ return true;
1578
+ });
1579
+ return sortModeIds(modes.map((mode) => mode.id)).map((id) => modes.find((mode) => mode.id === id)).filter(Boolean);
1580
+ }
1581
+ function firstAssignedModel(models) {
1582
+ for (const modeId of MODE_PRIORITY) {
1583
+ const modelId = models[modeId];
1584
+ if (modelId) return modelId;
1585
+ }
1586
+ for (const modelId of Object.values(models)) {
1587
+ if (modelId) return modelId;
1588
+ }
1589
+ return "";
1590
+ }
1591
+ function getFallbackModelForMode(modeId, models) {
1592
+ const candidatesByMode = {
1593
+ ask: ["ask", "fast", "plan", "build"],
1594
+ fast: ["fast", "ask", "plan", "build"],
1595
+ plan: ["plan", "build", "fast", "ask"],
1596
+ build: ["build", "plan", "fast", "ask"]
1597
+ };
1598
+ for (const candidate of candidatesByMode[modeId] ?? [modeId, "fast", "ask", "plan", "build"]) {
1599
+ const modelId = models[candidate];
1600
+ if (modelId) return modelId;
1601
+ }
1602
+ return firstAssignedModel(models);
1603
+ }
1604
+ function expandPackModels(models, modeIds, options) {
1605
+ const expanded = { ...models };
1606
+ for (const modeId of modeIds) {
1607
+ if (expanded[modeId]) continue;
1608
+ expanded[modeId] = options?.fillMissing ? getFallbackModelForMode(modeId, expanded) : "";
1609
+ }
1610
+ return expanded;
1611
+ }
1612
+ function getAvailableModePacks(access, savedCustomPacks = [], modeDefinitions = []) {
1613
+ const packs = [];
1614
+ const modeIds = getModePackOptions(modeDefinitions).map((mode) => mode.id);
1615
+ const openaiCodex = "openai/gpt-5.3-codex";
1616
+ const anthropicBuild = access.anthropic === "oauth" ? "anthropic/claude-opus-4-6" : "anthropic/claude-sonnet-4-5";
1617
+ if (access.anthropic) {
1618
+ packs.push({
1619
+ id: "anthropic",
1620
+ name: "Anthropic",
1621
+ description: access.anthropic === "oauth" ? "All Anthropic models via Max subscription" : "All Anthropic models via API key",
1622
+ models: expandPackModels({
1623
+ build: anthropicBuild,
1624
+ plan: anthropicBuild,
1625
+ fast: "anthropic/claude-haiku-4-5"
1626
+ }, modeIds, { fillMissing: true })
1627
+ });
1628
+ }
1629
+ if (access.openai) {
1630
+ packs.push({
1631
+ id: "openai",
1632
+ name: "OpenAI",
1633
+ description: access.openai === "oauth" ? "All OpenAI models via Codex subscription" : "All OpenAI models via API key",
1634
+ models: expandPackModels({
1635
+ build: openaiCodex,
1636
+ plan: openaiCodex,
1637
+ fast: "openai/gpt-5.1-codex-mini"
1638
+ }, modeIds, { fillMissing: true })
1639
+ });
1640
+ }
1641
+ for (const cp of savedCustomPacks) {
1642
+ packs.push({
1643
+ id: `custom:${cp.name}`,
1644
+ name: cp.name,
1645
+ description: "Saved custom pack",
1646
+ models: expandPackModels(cp.models, modeIds, { fillMissing: true })
1647
+ });
1648
+ }
1649
+ const hasCustom = savedCustomPacks.length > 0;
1650
+ packs.push({
1651
+ id: "custom",
1652
+ name: hasCustom ? "New Custom" : "Custom",
1653
+ description: "Choose a model for each mode",
1654
+ models: expandPackModels({}, modeIds)
1655
+ });
1656
+ return packs;
1657
+ }
1658
+ function getAvailableOmPacks(access) {
1659
+ const packs = [];
1660
+ if (access.google) {
1661
+ packs.push({
1662
+ id: "gemini",
1663
+ name: "Gemini Flash",
1664
+ description: access.google === "oauth" ? "Via Google OAuth" : "Via Google API key",
1665
+ modelId: "google/gemini-2.5-flash"
1666
+ });
1667
+ }
1668
+ if (access.anthropic) {
1669
+ packs.push({
1670
+ id: "anthropic",
1671
+ name: "Claude Haiku",
1672
+ description: access.anthropic === "oauth" ? "Via Max subscription" : "Via Anthropic API key",
1673
+ modelId: "anthropic/claude-haiku-4-5"
1674
+ });
1675
+ }
1676
+ if (access.openai) {
1677
+ packs.push({
1678
+ id: "openai",
1679
+ name: "Codex Mini",
1680
+ description: access.openai === "oauth" ? "Via Codex subscription" : "Via OpenAI API key",
1681
+ modelId: "openai/gpt-5.1-codex-mini"
1682
+ });
1683
+ }
1684
+ if (access.deepseek) {
1685
+ packs.push({
1686
+ id: "deepseek",
1687
+ name: "DeepSeek",
1688
+ description: "Via DeepSeek API key",
1689
+ modelId: "deepseek/deepseek-chat"
1690
+ });
1691
+ }
1692
+ packs.push({
1693
+ id: "custom",
1694
+ name: "Custom",
1695
+ description: "Choose any available model",
1696
+ modelId: ""
1697
+ });
1698
+ return packs;
1699
+ }
1700
+ var ONBOARDING_VERSION = 1;
1701
+ var ThreadLockError = class extends Error {
1702
+ constructor(threadId, ownerPid) {
1703
+ super(`Thread ${threadId} is locked by another process (PID ${ownerPid})`);
1704
+ this.threadId = threadId;
1705
+ this.ownerPid = ownerPid;
1706
+ this.name = "ThreadLockError";
1707
+ }
1708
+ };
1709
+ function getLocksDir() {
1710
+ const dir = path4__namespace.join(chunkIEV2IT3O_cjs.getAppDataDir(), "locks");
1711
+ if (!fs2__namespace.existsSync(dir)) {
1712
+ fs2__namespace.mkdirSync(dir, { recursive: true });
1713
+ }
1714
+ return dir;
1715
+ }
1716
+ function getLockPath(threadId) {
1717
+ const safeId = threadId.replace(/[^a-zA-Z0-9_-]/g, "_");
1718
+ return path4__namespace.join(getLocksDir(), `${safeId}.lock`);
1719
+ }
1720
+ function isProcessAlive(pid) {
1721
+ try {
1722
+ process.kill(pid, 0);
1723
+ return true;
1724
+ } catch {
1725
+ return false;
1726
+ }
1727
+ }
1728
+ function acquireThreadLock(threadId) {
1729
+ const lockPath = getLockPath(threadId);
1730
+ const myPid = process.pid;
1731
+ if (fs2__namespace.existsSync(lockPath)) {
1732
+ try {
1733
+ const content = fs2__namespace.readFileSync(lockPath, "utf-8").trim();
1734
+ const ownerPid = parseInt(content, 10);
1735
+ if (!isNaN(ownerPid) && ownerPid !== myPid && isProcessAlive(ownerPid)) {
1736
+ throw new ThreadLockError(threadId, ownerPid);
1737
+ }
1738
+ } catch (error) {
1739
+ if (error instanceof ThreadLockError) throw error;
1740
+ }
1741
+ }
1742
+ fs2__namespace.writeFileSync(lockPath, String(myPid), { mode: 420 });
1743
+ }
1744
+ function releaseThreadLock(threadId) {
1745
+ const lockPath = getLockPath(threadId);
1746
+ const myPid = process.pid;
1747
+ try {
1748
+ if (!fs2__namespace.existsSync(lockPath)) return;
1749
+ const content = fs2__namespace.readFileSync(lockPath, "utf-8").trim();
1750
+ const ownerPid = parseInt(content, 10);
1751
+ if (ownerPid === myPid) {
1752
+ fs2__namespace.unlinkSync(lockPath);
1753
+ }
1754
+ } catch {
1755
+ }
1756
+ }
1757
+ function releaseAllThreadLocks() {
1758
+ try {
1759
+ const locksDir = getLocksDir();
1760
+ const files = fs2__namespace.readdirSync(locksDir);
1761
+ const myPid = String(process.pid);
1762
+ for (const file of files) {
1763
+ if (!file.endsWith(".lock")) continue;
1764
+ const lockPath = path4__namespace.join(locksDir, file);
1765
+ try {
1766
+ const content = fs2__namespace.readFileSync(lockPath, "utf-8").trim();
1767
+ if (content === myPid) {
1768
+ fs2__namespace.unlinkSync(lockPath);
1769
+ }
1770
+ } catch {
1771
+ }
1772
+ }
1773
+ } catch {
1774
+ }
1775
+ }
1776
+
1777
+ exports.ONBOARDING_VERSION = ONBOARDING_VERSION;
1778
+ exports.THREAD_ACTIVE_MODEL_PACK_ID_KEY = THREAD_ACTIVE_MODEL_PACK_ID_KEY;
1779
+ exports.ThreadLockError = ThreadLockError;
1780
+ exports.acquireThreadLock = acquireThreadLock;
1781
+ exports.createHarnessModesFromDefinitions = createHarnessModesFromDefinitions;
1782
+ exports.createHarnessSubagentsFromDefinitions = createHarnessSubagentsFromDefinitions;
1783
+ exports.formatAgentDefinitionDiagnostics = formatAgentDefinitionDiagnostics;
1784
+ exports.getAllowedSubagentIdsForMode = getAllowedSubagentIdsForMode;
1785
+ exports.getAvailableModePacks = getAvailableModePacks;
1786
+ exports.getAvailableOmPacks = getAvailableOmPacks;
1787
+ exports.getCustomProviderId = getCustomProviderId;
1788
+ exports.getModeDefinition = getModeDefinition;
1789
+ exports.getModePackOptions = getModePackOptions;
1790
+ exports.getSubagentModeMap = getSubagentModeMap;
1791
+ exports.getSubagentOwnerModes = getSubagentOwnerModes;
1792
+ exports.loadAgentDefinitionsCached = loadAgentDefinitionsCached;
1793
+ exports.loadSettingsCached = loadSettingsCached;
1794
+ exports.logRuntimeProfile = logRuntimeProfile;
1795
+ exports.lspManager = lspManager;
1796
+ exports.releaseAllThreadLocks = releaseAllThreadLocks;
1797
+ exports.releaseThreadLock = releaseThreadLock;
1798
+ exports.resolveModelDefaults = resolveModelDefaults;
1799
+ exports.resolveOmModel = resolveOmModel;
1800
+ exports.resolveThreadActiveModelPackId = resolveThreadActiveModelPackId;
1801
+ exports.saveSettings = saveSettings;
1802
+ exports.setupDebugLogging = setupDebugLogging;
1803
+ exports.toCustomProviderModelId = toCustomProviderModelId;
1804
+ //# sourceMappingURL=chunk-PUVEPQQ3.cjs.map
1805
+ //# sourceMappingURL=chunk-PUVEPQQ3.cjs.map