brainctl 0.1.6 → 0.1.7

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 (37) hide show
  1. package/README.md +26 -0
  2. package/dist/executor/resolver.js +1 -38
  3. package/dist/mcp/server.js +34 -0
  4. package/dist/services/agent-config-service.d.ts +16 -1
  5. package/dist/services/agent-config-service.js +35 -2
  6. package/dist/services/mcp-preflight-service.d.ts +25 -0
  7. package/dist/services/mcp-preflight-service.js +84 -0
  8. package/dist/services/plugin-install-service.d.ts +92 -0
  9. package/dist/services/plugin-install-service.js +243 -0
  10. package/dist/services/profile-export-service.js +5 -5
  11. package/dist/services/profile-import-service.js +1 -1
  12. package/dist/services/profile-service.d.ts +1 -0
  13. package/dist/services/profile-service.js +117 -32
  14. package/dist/services/skill-paths.d.ts +2 -0
  15. package/dist/services/skill-paths.js +12 -0
  16. package/dist/services/skill-preflight-service.d.ts +23 -0
  17. package/dist/services/skill-preflight-service.js +40 -0
  18. package/dist/services/sync/agent-reader.d.ts +5 -0
  19. package/dist/services/sync/agent-reader.js +26 -15
  20. package/dist/services/sync/claude-writer.js +4 -1
  21. package/dist/services/sync/codex-writer.js +6 -2
  22. package/dist/services/sync/gemini-writer.js +4 -1
  23. package/dist/services/sync/managed-plugin-registry.d.ts +17 -0
  24. package/dist/services/sync/managed-plugin-registry.js +75 -0
  25. package/dist/services/sync/plugin-skill-reader.d.ts +2 -0
  26. package/dist/services/sync/plugin-skill-reader.js +33 -0
  27. package/dist/services/sync-service.js +5 -0
  28. package/dist/system/executables.d.ts +1 -0
  29. package/dist/system/executables.js +38 -0
  30. package/dist/types.d.ts +15 -5
  31. package/dist/ui/routes.js +264 -6
  32. package/dist/web/assets/index-BCkorugl.css +1 -0
  33. package/dist/web/assets/index-sGnTMhkX.js +16 -0
  34. package/dist/web/index.html +2 -2
  35. package/package.json +5 -1
  36. package/dist/web/assets/index-364NYWPA.css +0 -1
  37. package/dist/web/assets/index-BmfE7rus.js +0 -16
package/dist/types.d.ts CHANGED
@@ -55,20 +55,30 @@ export interface DiagnosticCheck {
55
55
  status: DiagnosticStatus;
56
56
  message: string;
57
57
  }
58
- export interface NpmMcpServerConfig {
59
- type: 'npm';
58
+ export interface LocalNpmMcpServerConfig {
59
+ kind: 'local';
60
+ source: 'npm';
60
61
  package: string;
61
62
  env?: Record<string, string>;
62
63
  }
63
- export interface BundledMcpServerConfig {
64
- type: 'bundled';
64
+ export interface LocalBundledMcpServerConfig {
65
+ kind: 'local';
66
+ source: 'bundled';
65
67
  path: string;
66
68
  install?: string;
67
69
  command: string;
68
70
  args?: string[];
69
71
  env?: Record<string, string>;
70
72
  }
71
- export type McpServerConfig = NpmMcpServerConfig | BundledMcpServerConfig;
73
+ export interface RemoteMcpServerConfig {
74
+ kind: 'remote';
75
+ transport: 'http' | 'sse';
76
+ url: string;
77
+ headers?: Record<string, string>;
78
+ env?: Record<string, string>;
79
+ }
80
+ export type LocalMcpServerConfig = LocalNpmMcpServerConfig | LocalBundledMcpServerConfig;
81
+ export type McpServerConfig = LocalMcpServerConfig | RemoteMcpServerConfig;
72
82
  export interface ProfileConfig {
73
83
  name: string;
74
84
  description?: string;
package/dist/ui/routes.js CHANGED
@@ -2,12 +2,17 @@ import { existsSync } from 'node:fs';
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { loadConfig } from '../config.js';
4
4
  import { parseConfigPayload } from '../config.js';
5
- import { ProfileError, ProfileNotFoundError } from '../errors.js';
5
+ import { BrainctlError, ProfileError, ProfileNotFoundError, ValidationError } from '../errors.js';
6
6
  import { loadMemory } from '../context/memory.js';
7
7
  import { createAgentConfigService } from '../services/agent-config-service.js';
8
8
  import { createConfigWriteService } from '../services/config-write-service.js';
9
+ import { createMcpPreflightService } from '../services/mcp-preflight-service.js';
10
+ import { createPluginInstallService } from '../services/plugin-install-service.js';
11
+ import { createProfileExportService } from '../services/profile-export-service.js';
12
+ import { createProfileImportService } from '../services/profile-import-service.js';
9
13
  import { createProfileService } from '../services/profile-service.js';
10
14
  import { createRunService } from '../services/run-service.js';
15
+ import { createSkillPreflightService } from '../services/skill-preflight-service.js';
11
16
  import { createStatusService } from '../services/status-service.js';
12
17
  import { createSyncService } from '../services/sync-service.js';
13
18
  import { startSseStream, writeSseEvent } from './streaming.js';
@@ -19,8 +24,13 @@ export function createUiRouteHandler(dependencies) {
19
24
  const runService = dependencies.runService ?? createRunService();
20
25
  const configWriteService = createConfigWriteService();
21
26
  const profileService = createProfileService();
27
+ const profileExportService = createProfileExportService({ profileService });
28
+ const profileImportService = createProfileImportService();
22
29
  const syncService = createSyncService({ profileService });
23
30
  const agentConfigService = createAgentConfigService();
31
+ const mcpPreflightService = createMcpPreflightService();
32
+ const pluginInstallService = createPluginInstallService();
33
+ const skillPreflightService = createSkillPreflightService();
24
34
  return async (request, response) => {
25
35
  const url = new URL(request.url ?? '/', 'http://localhost');
26
36
  switch (url.pathname) {
@@ -135,6 +145,56 @@ export function createUiRouteHandler(dependencies) {
135
145
  }
136
146
  return sendJson(response, 405, { error: 'Method not allowed' });
137
147
  }
148
+ case '/api/profiles/export': {
149
+ if (request.method !== 'POST') {
150
+ return sendJson(response, 405, { error: 'Method not allowed' });
151
+ }
152
+ const body = await readJsonBody(request);
153
+ if (!body.ok) {
154
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
155
+ }
156
+ const data = body.value;
157
+ if (!data.name || data.name.trim().length === 0) {
158
+ return sendJson(response, 400, { error: 'Missing profile name' });
159
+ }
160
+ try {
161
+ const result = await profileExportService.execute({
162
+ cwd: dependencies.cwd,
163
+ name: data.name.trim(),
164
+ outputPath: typeof data.outputPath === 'string' && data.outputPath.trim().length > 0
165
+ ? data.outputPath.trim()
166
+ : undefined,
167
+ });
168
+ return sendJson(response, 200, result);
169
+ }
170
+ catch (error) {
171
+ return sendProfileError(response, error);
172
+ }
173
+ }
174
+ case '/api/profiles/import': {
175
+ if (request.method !== 'POST') {
176
+ return sendJson(response, 405, { error: 'Method not allowed' });
177
+ }
178
+ const body = await readJsonBody(request);
179
+ if (!body.ok) {
180
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
181
+ }
182
+ const data = body.value;
183
+ if (!data.archivePath || data.archivePath.trim().length === 0) {
184
+ return sendJson(response, 400, { error: 'Missing archivePath' });
185
+ }
186
+ try {
187
+ const result = await profileImportService.execute({
188
+ cwd: dependencies.cwd,
189
+ archivePath: data.archivePath.trim(),
190
+ force: data.force === true,
191
+ });
192
+ return sendJson(response, 200, result);
193
+ }
194
+ catch (error) {
195
+ return sendProfileError(response, error);
196
+ }
197
+ }
138
198
  case '/api/sync': {
139
199
  if (request.method !== 'POST') {
140
200
  return sendJson(response, 405, { error: 'Method not allowed' });
@@ -151,6 +211,28 @@ export function createUiRouteHandler(dependencies) {
151
211
  }
152
212
  default: {
153
213
  // Agent MCP routes: /api/agents/:name/mcps(/:key)
214
+ const agentMcpCheckMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/mcps\/check$/);
215
+ if (agentMcpCheckMatch) {
216
+ const agentName = agentMcpCheckMatch[1];
217
+ if (request.method !== 'POST') {
218
+ return sendJson(response, 405, { error: 'Method not allowed' });
219
+ }
220
+ const body = await readJsonBody(request);
221
+ if (!body.ok) {
222
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
223
+ }
224
+ const data = body.value;
225
+ if (!data.key || !data.entry?.command) {
226
+ return sendJson(response, 400, { error: 'Missing key or entry.command' });
227
+ }
228
+ const result = await mcpPreflightService.execute({
229
+ cwd: dependencies.cwd,
230
+ agent: agentName,
231
+ key: data.key,
232
+ entry: data.entry,
233
+ });
234
+ return sendJson(response, 200, result);
235
+ }
154
236
  const agentMcpMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/mcps(?:\/(.+))?$/);
155
237
  if (agentMcpMatch) {
156
238
  const agentName = agentMcpMatch[1];
@@ -174,9 +256,7 @@ export function createUiRouteHandler(dependencies) {
174
256
  return sendJson(response, 200, { ok: true });
175
257
  }
176
258
  catch (error) {
177
- return sendJson(response, 500, {
178
- error: error instanceof Error ? error.message : 'Failed to add MCP',
179
- });
259
+ return sendHandledError(response, error, 'Failed to add MCP');
180
260
  }
181
261
  }
182
262
  if (request.method === 'DELETE' && mcpKey) {
@@ -189,9 +269,169 @@ export function createUiRouteHandler(dependencies) {
189
269
  return sendJson(response, 200, { ok: true });
190
270
  }
191
271
  catch (error) {
192
- return sendJson(response, 500, {
193
- error: error instanceof Error ? error.message : 'Failed to remove MCP',
272
+ return sendHandledError(response, error, 'Failed to remove MCP');
273
+ }
274
+ }
275
+ return sendJson(response, 405, { error: 'Method not allowed' });
276
+ }
277
+ // Agent skill routes: /api/agents/:name/skills(/:key)
278
+ const agentSkillCheckMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/skills\/check$/);
279
+ if (agentSkillCheckMatch) {
280
+ const agentName = agentSkillCheckMatch[1];
281
+ if (request.method !== 'POST') {
282
+ return sendJson(response, 405, { error: 'Method not allowed' });
283
+ }
284
+ const body = await readJsonBody(request);
285
+ if (!body.ok) {
286
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
287
+ }
288
+ const data = body.value;
289
+ if (!data.name || !data.sourceAgent) {
290
+ return sendJson(response, 400, { error: 'Missing name or sourceAgent' });
291
+ }
292
+ const result = await skillPreflightService.execute({
293
+ sourceAgent: data.sourceAgent,
294
+ targetAgent: agentName,
295
+ skillName: data.name,
296
+ source: typeof data.source === 'string' ? data.source : undefined,
297
+ });
298
+ return sendJson(response, 200, result);
299
+ }
300
+ const agentSkillMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/skills(?:\/(.+))?$/);
301
+ if (agentSkillMatch) {
302
+ const agentName = agentSkillMatch[1];
303
+ const skillKey = agentSkillMatch[2] ? decodeURIComponent(agentSkillMatch[2]) : null;
304
+ if (request.method === 'POST' && !skillKey) {
305
+ const body = await readJsonBody(request);
306
+ if (!body.ok) {
307
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
308
+ }
309
+ const data = body.value;
310
+ if (!data.name || !data.sourceAgent) {
311
+ return sendJson(response, 400, { error: 'Missing name or sourceAgent' });
312
+ }
313
+ try {
314
+ const preflight = await skillPreflightService.execute({
315
+ sourceAgent: data.sourceAgent,
316
+ targetAgent: agentName,
317
+ skillName: data.name,
318
+ source: typeof data.source === 'string' ? data.source : undefined,
319
+ });
320
+ const firstError = preflight.checks.find((check) => check.status === 'error');
321
+ if (firstError) {
322
+ throw new ValidationError(`Skill "${data.name}" cannot be copied from ${data.sourceAgent} to ${agentName}: ${firstError.message}`);
323
+ }
324
+ await agentConfigService.copySkill({
325
+ sourceAgent: data.sourceAgent,
326
+ targetAgent: agentName,
327
+ skillName: data.name,
194
328
  });
329
+ return sendJson(response, 200, { ok: true });
330
+ }
331
+ catch (error) {
332
+ return sendHandledError(response, error, 'Failed to copy skill');
333
+ }
334
+ }
335
+ if (request.method === 'DELETE' && skillKey) {
336
+ try {
337
+ await agentConfigService.removeSkill({
338
+ agent: agentName,
339
+ skillName: skillKey,
340
+ });
341
+ return sendJson(response, 200, { ok: true });
342
+ }
343
+ catch (error) {
344
+ return sendHandledError(response, error, 'Failed to remove skill');
345
+ }
346
+ }
347
+ return sendJson(response, 405, { error: 'Method not allowed' });
348
+ }
349
+ const agentPluginCheckMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/plugins\/check$/);
350
+ if (agentPluginCheckMatch) {
351
+ const agentName = agentPluginCheckMatch[1];
352
+ if (request.method !== 'POST') {
353
+ return sendJson(response, 405, { error: 'Method not allowed' });
354
+ }
355
+ const body = await readJsonBody(request);
356
+ if (!body.ok) {
357
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
358
+ }
359
+ const data = body.value;
360
+ if (!data.name || !data.sourceAgent) {
361
+ return sendJson(response, 400, { error: 'Missing name or sourceAgent' });
362
+ }
363
+ const sourcePlugin = await resolveSourcePlugin(agentConfigService, dependencies.cwd, {
364
+ sourceAgent: data.sourceAgent,
365
+ name: data.name,
366
+ });
367
+ if (!sourcePlugin) {
368
+ return sendJson(response, 400, {
369
+ error: `Plugin "${data.name}" was not found in ${data.sourceAgent}.`,
370
+ });
371
+ }
372
+ const result = await pluginInstallService.plan({
373
+ cwd: dependencies.cwd,
374
+ targetAgent: agentName,
375
+ sourceAgent: data.sourceAgent,
376
+ plugin: sourcePlugin,
377
+ });
378
+ return sendJson(response, 200, result);
379
+ }
380
+ const agentPluginMatch = url.pathname.match(/^\/api\/agents\/(claude|codex|gemini)\/plugins(?:\/(.+))?$/);
381
+ if (agentPluginMatch) {
382
+ const agentName = agentPluginMatch[1];
383
+ const pluginName = agentPluginMatch[2] ? decodeURIComponent(agentPluginMatch[2]) : null;
384
+ if (request.method === 'POST' && !pluginName) {
385
+ const body = await readJsonBody(request);
386
+ if (!body.ok) {
387
+ return sendJson(response, 400, { error: 'Invalid JSON body' });
388
+ }
389
+ const data = body.value;
390
+ if (!data.name || !data.sourceAgent) {
391
+ return sendJson(response, 400, { error: 'Missing name or sourceAgent' });
392
+ }
393
+ const sourcePlugin = await resolveSourcePlugin(agentConfigService, dependencies.cwd, {
394
+ sourceAgent: data.sourceAgent,
395
+ name: data.name,
396
+ });
397
+ if (!sourcePlugin) {
398
+ return sendJson(response, 400, {
399
+ error: `Plugin "${data.name}" was not found in ${data.sourceAgent}.`,
400
+ });
401
+ }
402
+ try {
403
+ const result = await pluginInstallService.execute({
404
+ cwd: dependencies.cwd,
405
+ targetAgent: agentName,
406
+ sourceAgent: data.sourceAgent,
407
+ plugin: sourcePlugin,
408
+ });
409
+ return sendJson(response, 200, result);
410
+ }
411
+ catch (error) {
412
+ return sendHandledError(response, error, 'Failed to install plugin');
413
+ }
414
+ }
415
+ if (request.method === 'DELETE' && pluginName) {
416
+ const targetPlugin = await resolveTargetPlugin(agentConfigService, dependencies.cwd, {
417
+ targetAgent: agentName,
418
+ name: pluginName,
419
+ });
420
+ if (!targetPlugin) {
421
+ return sendJson(response, 404, {
422
+ error: `Plugin "${pluginName}" was not found in ${agentName}.`,
423
+ });
424
+ }
425
+ try {
426
+ const result = await pluginInstallService.remove({
427
+ cwd: dependencies.cwd,
428
+ targetAgent: agentName,
429
+ plugin: targetPlugin,
430
+ });
431
+ return sendJson(response, 200, result);
432
+ }
433
+ catch (error) {
434
+ return sendHandledError(response, error, 'Failed to remove plugin');
195
435
  }
196
436
  }
197
437
  return sendJson(response, 405, { error: 'Method not allowed' });
@@ -260,6 +500,24 @@ export function createUiRouteHandler(dependencies) {
260
500
  }
261
501
  };
262
502
  }
503
+ async function resolveSourcePlugin(agentConfigService, cwd, options) {
504
+ const configs = await agentConfigService.readAll({ cwd });
505
+ const sourceConfig = configs.find((config) => config.agent === options.sourceAgent);
506
+ const plugin = sourceConfig?.skills.find((entry) => entry.kind === 'plugin' && entry.name === options.name);
507
+ return plugin ?? null;
508
+ }
509
+ async function resolveTargetPlugin(agentConfigService, cwd, options) {
510
+ const configs = await agentConfigService.readAll({ cwd });
511
+ const targetConfig = configs.find((config) => config.agent === options.targetAgent);
512
+ const plugin = targetConfig?.skills.find((entry) => entry.kind === 'plugin' && entry.name === options.name);
513
+ return plugin ?? null;
514
+ }
515
+ function sendHandledError(response, error, fallbackMessage) {
516
+ const isUserError = error instanceof BrainctlError && error.category === 'user';
517
+ sendJson(response, isUserError ? 400 : 500, {
518
+ error: error instanceof Error ? error.message : fallbackMessage,
519
+ });
520
+ }
263
521
  async function readJsonBody(request) {
264
522
  const chunks = [];
265
523
  for await (const chunk of request) {
@@ -0,0 +1 @@
1
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-700:oklch(50.8% .118 165.612);--color-rose-50:oklch(96.9% .015 12.422);--color-rose-200:oklch(89.2% .058 10.001);--color-rose-700:oklch(51.4% .222 16.935);--color-zinc-50:oklch(98.5% 0 0);--color-zinc-200:oklch(92% .004 286.32);--color-zinc-300:oklch(87.1% .006 286.286);--color-zinc-400:oklch(70.5% .015 286.067);--color-zinc-500:oklch(55.2% .016 285.938);--color-zinc-600:oklch(44.2% .017 285.786);--color-zinc-700:oklch(37% .013 285.805);--color-zinc-800:oklch(27.4% .006 286.033);--color-zinc-900:oklch(21% .006 285.885);--color-zinc-950:oklch(14.1% .005 285.823);--color-white:#fff;--spacing:.25rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.absolute{position:absolute}.static{position:static}.start{inset-inline-start:var(--spacing)}.mx-auto{margin-inline:auto}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-\[18px\]{width:18px;height:18px}.size-full{width:100%;height:100%}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-screen{min-height:100vh}.w-full{width:100%}.max-w-\[1420px\]{max-width:1420px}.min-w-0{min-width:calc(var(--spacing) * 0)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-3xl{border-radius:var(--radius-3xl)}.rounded-\[28px\]{border-radius:28px}.rounded-\[32px\]{border-radius:32px}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-emerald-200{border-color:var(--color-emerald-200)}.border-rose-200{border-color:var(--color-rose-200)}.border-zinc-200{border-color:var(--color-zinc-200)}.border-zinc-300{border-color:var(--color-zinc-300)}.border-zinc-900{border-color:var(--color-zinc-900)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-rose-50{background-color:var(--color-rose-50)}.bg-white{background-color:var(--color-white)}.bg-zinc-50{background-color:var(--color-zinc-50)}.bg-zinc-900{background-color:var(--color-zinc-900)}.bg-zinc-950{background-color:var(--color-zinc-950)}.object-contain{object-fit:contain}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-\[11px\]{font-size:11px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.03em\]{--tw-tracking:-.03em;letter-spacing:-.03em}.tracking-\[-0\.04em\]{--tw-tracking:-.04em;letter-spacing:-.04em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.text-emerald-700{color:var(--color-emerald-700)}.text-rose-700{color:var(--color-rose-700)}.text-white{color:var(--color-white)}.text-zinc-500{color:var(--color-zinc-500)}.text-zinc-600{color:var(--color-zinc-600)}.text-zinc-700{color:var(--color-zinc-700)}.text-zinc-800{color:var(--color-zinc-800)}.text-zinc-900{color:var(--color-zinc-900)}.text-zinc-950{color:var(--color-zinc-950)}.uppercase{text-transform:uppercase}.shadow-\[0_18px_50px_rgba\(0\,0\,0\,0\.04\)\]{--tw-shadow:0 18px 50px var(--tw-shadow-color,#0000000a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_20px_60px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow:0 20px 60px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_22px_60px_rgba\(0\,0\,0\,0\.06\)\]{--tw-shadow:0 22px 60px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){.hover\:border-zinc-300:hover{border-color:var(--color-zinc-300)}.hover\:bg-zinc-800:hover{background-color:var(--color-zinc-800)}.hover\:text-zinc-900:hover{color:var(--color-zinc-900)}}.focus\:border-zinc-400:focus{border-color:var(--color-zinc-400)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-zinc-300:disabled{background-color:var(--color-zinc-300)}@media(min-width:40rem){.sm\:p-5{padding:calc(var(--spacing) * 5)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media(min-width:64rem){.lg\:grid-cols-\[minmax\(0\,0\.9fr\)_minmax\(0\,1\.1fr\)\]{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr)}.lg\:grid-cols-\[minmax\(0\,1\.15fr\)_minmax\(260px\,0\.85fr\)\]{grid-template-columns:minmax(0,1.15fr) minmax(260px,.85fr)}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:justify-center{justify-content:center}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}}:root{color-scheme:light;--background:#fff;--foreground:#171717;--card:#fffffff5;--muted:#6b6b6b;--muted-bg:#fafafa;--accent:#f1f1ef;--border:#e4e4e1;--border-strong:#bcbcb7;--primary:#151515;--primary-foreground:#fff;--destructive:#c94f42;--destructive-bg:#fff0ed;--success:#14855f;--success-bg:#ecfbf4;--radius-lg:1rem;--radius-md:.5rem;--radius-sm:.375rem;background:var(--background);color:var(--foreground);font-family:Avenir Next,Helvetica Neue,Segoe UI,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,sans-serif}*{box-sizing:border-box}html,body,#root{min-height:100%;margin:0}body{min-height:100vh;color:var(--foreground);background:#fff}body,button,input,select,textarea{font:inherit}button{cursor:pointer}button:disabled{cursor:not-allowed}code{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.875em}#root{min-height:100vh}.app-shell{min-height:100vh;padding:18px 24px 24px}.shell{gap:24px;width:min(1400px,100%);margin:0 auto;display:grid}.shell.shell-compact{width:min(1220px,100%)}.shell.shell-board{gap:10px;width:min(1420px,100%)}.panel,.panel-inner,.metric-card,.config-card,.config-empty-state,.run-summary-tile,.run-empty-state,.empty-state,.agent-row,.memory-file-button,.profile-card,.profile-card-overlay,.pending-change-item{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);box-shadow:0 18px 44px #0000000d}.panel,.nav-card,.workspace-card{padding:24px}.panel-inner,.metric-card,.config-card,.config-empty-state,.run-summary-tile,.run-empty-state,.empty-state,.pending-changes-bar{padding:20px}.topbar{justify-content:space-between;align-items:center;gap:16px;display:flex}.brand-block{align-items:center;gap:12px;min-width:0;display:flex}.brand-mark{border:1px solid var(--border);border-radius:var(--radius-md);width:40px;height:40px;color:var(--foreground);background:linear-gradient(#fff,#f6f6f4);place-items:center;display:grid}.eyebrow{color:var(--muted);letter-spacing:.04em;text-transform:uppercase;margin:0 0 4px;font-size:.75rem;font-weight:600}.brand-block h1,.hero-panel h1,.workspace-header h2,.panel-heading h2,.section-header h3,.empty-state h2,.feature-card h3,.install-step h4{letter-spacing:-.02em;margin:0;font-family:Avenir Next,Helvetica Neue,Segoe UI,ui-sans-serif,system-ui,sans-serif;font-size:1.5rem;font-weight:700;line-height:1.2}.workspace-header h2,.panel-heading h2,.section-header h3{font-size:1.125rem}.status-strip,.workspace-header-meta,.chip-row,.pending-changes-actions{flex-wrap:wrap;gap:8px;display:flex}.status-chip,.muted-pill,.skill-chip,.agent-command{border:1px solid var(--border);border-radius:var(--radius-md);min-height:32px;color:var(--foreground);background:#ffffffe0;align-items:center;gap:6px;padding:0 10px;font-size:.875rem;display:inline-flex}.muted-pill{color:var(--muted)}.panel-heading,.workspace-header,.section-header,.metric-card-header,.agent-row,.agent-row-meta,.config-card-header,.profile-column-header,.pending-changes-header{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.mission-banner{gap:28px;display:grid;position:relative;overflow:hidden}.mission-banner:before{content:"";pointer-events:none;background:linear-gradient(135deg,#00000009,#0000 40%),radial-gradient(circle at 100% 0,#fff6,#0000 28%),radial-gradient(circle at 12% 88%,#e8e8e447,#0000 28%);position:absolute;inset:0}.mission-layout,.mode-switcher{z-index:1;position:relative}.mission-layout{grid-template-columns:minmax(0,1.35fr) minmax(300px,.85fr);align-items:end;gap:24px;display:grid}.mission-copy-block{gap:14px;display:grid}.mission-copy{max-width:760px;color:var(--muted);margin:0;font-size:1.02rem;line-height:1.8}.signal-board{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;display:grid}.signal-tile{border:1px solid var(--border);border-radius:calc(var(--radius-lg) + 2px);background:#ffffffd1;gap:6px;padding:16px;display:grid}.signal-tile span,.signal-tile small{color:var(--muted)}.signal-tile strong{letter-spacing:-.04em;font-size:1.85rem;line-height:1}.mode-switcher{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;display:grid}.mode-tab{border:1px solid var(--border);border-radius:calc(var(--radius-lg) + 2px);color:var(--foreground);text-align:left;background:#ffffffdb;align-items:flex-start;gap:14px;padding:18px;transition:transform .18s,border-color .18s,background .18s,box-shadow .18s;display:flex}.mode-tab:hover:not(:disabled){border-color:var(--border-strong);background:#fff;transform:translateY(-2px);box-shadow:0 14px 30px #0000000f}.mode-tab.is-active{background:linear-gradient(#fff,#f2f2f0);border-color:#0000002e;box-shadow:inset 0 1px #ffffffb3}.mode-tab:disabled{opacity:.55}.mode-tab-index,.mode-tab-icon,.ribbon-card-icon{flex:none}.mode-tab-index{min-width:2.2rem;color:var(--muted);letter-spacing:.08em;text-transform:uppercase;font-size:.76rem;font-weight:700}.mode-tab-icon,.ribbon-card-icon{border:1px solid var(--border);border-radius:var(--radius-md);width:36px;height:36px;color:var(--primary);background:linear-gradient(#fff,#f6f6f4);place-items:center;display:grid}.mode-tab-copy,.feature-hero-copy,.feature-hero-side,.ribbon-card,.ribbon-card div{gap:4px;display:grid}.mode-tab-copy{min-width:0}.mode-tab-copy strong{font-size:1.02rem}.mode-tab-copy span{color:var(--muted);font-size:.84rem}.mode-tab-kicker{letter-spacing:.08em;text-transform:uppercase;font-size:.72rem;font-weight:700}.panel-heading{margin-bottom:16px}.workspace-card{gap:24px;min-width:0;display:grid}.board-surface{padding-top:14px}.product-topbar{justify-content:space-between;align-items:center;gap:14px;padding:2px 2px 4px;display:flex}.product-topbar-copy{gap:2px;display:grid}.product-topbar-copy h1{letter-spacing:-.03em;margin:0;font-size:1.15rem}.product-agent-rail{flex-wrap:wrap;flex:1;justify-content:center;gap:8px;display:flex}.product-agent-chip{border:1px solid var(--border);min-height:34px;color:var(--foreground);background:#ffffffc7;border-radius:999px;align-items:center;gap:8px;padding:0 12px;font-size:.82rem;font-weight:600;display:inline-flex}.product-agent-logo{width:18px;height:18px;color:var(--foreground);place-items:center;display:grid;overflow:hidden}.product-agent-logo svg,.product-agent-logo img,.profile-agent-logo,.profile-agent-logo svg,.profile-agent-logo img,img.profile-agent-logo{object-fit:contain;width:100%;height:100%;display:block}.product-topbar-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.product-action-button{background:#fff;min-height:38px;padding-inline:12px}.product-action-badge{border:1px solid var(--border);background:var(--accent);min-height:20px;color:var(--muted);letter-spacing:.05em;text-transform:uppercase;border-radius:999px;align-items:center;padding:0 8px;font-size:.68rem;font-weight:700;display:inline-flex}.stage-shell{overflow:hidden}.section-nav,.view-stack,.config-panel,.config-list,.run-form,.agent-list,.memory-file-list,.profile-columns,.profile-column,.pending-changes-list{gap:16px;display:grid}.feature-stage,.package-stage{gap:18px;display:grid}.feature-hero,.scope-card,.install-step{border:1px solid var(--border);border-radius:var(--radius-lg);background:#ffffffe0}.feature-hero,.scope-card{padding:22px}.feature-hero{grid-template-columns:minmax(0,1.2fr) minmax(260px,.8fr);align-items:start;gap:18px;display:grid}.feature-hero-copy h2{letter-spacing:-.04em;margin:0;font-size:2rem;line-height:1.05}.feature-hero-copy p:last-child{color:var(--muted);margin:0;font-size:.92rem;line-height:1.5}.feature-hero-side{align-content:start}.stage-fact{border-bottom:1px solid #00000014;justify-content:space-between;align-items:baseline;gap:12px;padding:12px 0;display:flex}.stage-fact:last-child{border-bottom:0}.stage-fact span{color:var(--muted);text-transform:uppercase;letter-spacing:.06em;font-size:.82rem}.stage-fact strong{letter-spacing:-.02em;font-size:1rem}.feature-ribbon,.install-step-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.flow-lane{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;display:grid}.flow-node{border:1px solid var(--border);border-radius:var(--radius-lg);background:#ffffffeb;gap:8px;padding:16px;display:grid;position:relative}.flow-node strong{font-size:.95rem;line-height:1.2}.flow-node span:last-child{color:var(--muted);font-size:.78rem;line-height:1.35}.flow-node-icon{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--muted-bg);place-items:center;width:32px;height:32px;display:grid}.pack-flow-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-top:18px;display:grid}.ribbon-card{border:1px solid var(--border);border-radius:var(--radius-lg);background:#ffffffe0;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:14px;padding:16px 18px}.ribbon-card strong{font-size:.98rem}.ribbon-card p{color:var(--muted);margin:0;line-height:1.6}.flow-step-card{border:1px solid var(--border);border-radius:var(--radius-lg);background:#ffffffeb;gap:10px;padding:18px;display:grid}.flow-step-badge{background:var(--accent);min-height:24px;color:var(--muted);letter-spacing:.06em;border-radius:999px;justify-content:center;justify-self:start;align-items:center;padding:0 8px;font-size:.72rem;font-weight:700;display:inline-flex}.flow-step-card h4{margin:0;font-size:1rem;line-height:1.35}.flow-step-card p{color:var(--muted);margin:0;line-height:1.35}.install-outline{gap:18px;display:grid}.install-step-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.install-step{grid-template-columns:auto minmax(0,1fr);align-items:start;gap:14px;padding:18px;display:grid}.install-step-number{width:32px;height:32px;color:var(--primary-foreground);background:linear-gradient(#2f2f2f,#151515);border-radius:999px;place-items:center;font-size:.8rem;font-weight:700;display:grid}.install-step h4{margin-bottom:6px;font-size:1rem}.install-step p{color:var(--muted);margin:0;line-height:1.55}.section-button{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--card);width:100%;color:var(--foreground);text-align:left;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;display:grid}.section-button:hover:not(:disabled){background:var(--muted-bg);border-color:var(--border-strong)}.section-button.is-active{background:var(--accent);border-color:var(--border-strong)}.section-button:disabled{opacity:.6}.section-button-icon,.metric-card-icon,.run-summary-tile-icon,.empty-state-icon{border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--muted-bg);width:32px;height:32px;color:var(--foreground);flex:none;place-items:center;display:grid}.section-button-label{gap:2px;min-width:0;display:grid}.section-button-label span:first-child{font-weight:600}.section-button-subtitle,.section-button-chevron,.metric-card-label,.field-help,.run-summary-tile-label,.metric-card-note{color:var(--muted)}.muted-copy{color:var(--muted);word-break:break-word;margin:8px 0 0;line-height:1.5}.metrics-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;display:grid}.metric-card{gap:12px;min-width:0;display:grid}.metric-card.is-wide{grid-column:1/-1}.metric-card-header{justify-content:flex-start;align-items:center}.metric-card-value{word-break:break-word;font-size:1rem;font-weight:600;line-height:1.5;display:block}.metric-card-note{margin:0;line-height:1.5}.skill-chip{min-height:28px}.agent-list,.memory-file-list{gap:12px}.agent-row{align-items:center;padding:14px 16px}.agent-row-meta{justify-content:flex-start;align-items:center;min-width:0}.agent-row-meta strong{text-transform:capitalize;display:block}.agent-row-meta p{color:var(--muted);margin:4px 0 0}.agent-status-dot{background:var(--border-strong);border-radius:999px;flex:none;width:10px;height:10px}.agent-status-dot.is-online{background:var(--success)}.agent-status-dot.is-offline{background:#94a3b8}.memory-layout,.run-detail-grid{gap:16px;min-width:0;display:grid}.memory-layout{grid-template-columns:280px minmax(0,1fr)}.memory-list,.memory-preview,.run-output-panel,.run-summary-panel{min-width:0}.memory-preview,.run-panel,.config-panel{gap:16px;display:grid}.memory-file-button{text-align:left;gap:4px;padding:14px 16px;display:grid}.memory-file-button:hover{background:var(--muted-bg);border-color:var(--border-strong)}.memory-file-button.is-selected{background:var(--accent);border-color:var(--border-strong)}.memory-file-button strong,.memory-file-button span{text-overflow:ellipsis;min-width:0;overflow:hidden}.memory-file-button span{color:var(--muted);font-size:.8125rem}.field{gap:8px;display:grid}.field-label{font-size:.875rem;font-weight:600}.field-control,.memory-editor,.run-output{border:1px solid var(--border);border-radius:var(--radius-md);width:100%;min-width:0;color:var(--foreground);background:#fffffff5;padding:10px 12px}.field-control:focus,.memory-editor:focus,.run-output:focus{outline-offset:2px;border-color:var(--border-strong);outline:2px solid #0000001a}.field-control:disabled{opacity:.7}.field-help{margin:0;font-size:.8125rem;line-height:1.5}.memory-editor,.run-output,.editor-textarea,.editor-code,.agent-config-path{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Monaco,Consolas,Liberation Mono,monospace}.memory-editor{resize:vertical;min-height:420px;line-height:1.6}.config-toolbar,.run-actions{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;display:flex}.config-field-grid,.run-agent-grid,.run-summary-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.secondary-button,.danger-button,.run-button{border-radius:var(--radius-md);border:1px solid var(--border);justify-content:center;align-items:center;gap:8px;min-height:40px;padding:0 14px;font-weight:500;display:inline-flex}.secondary-button{color:var(--foreground);background:#fffffff0}.secondary-button:hover:not(:disabled){background:#fff}.run-button{color:var(--primary-foreground);background:linear-gradient(#2f2f2f,#151515);border-color:#232323}.run-button:hover:not(:disabled){opacity:.92}.danger-button{background:var(--destructive-bg);color:#b91c1c;border-color:#fecaca}.danger-button:hover:not(:disabled){background:#fee2e2}.secondary-button:disabled,.danger-button:disabled,.run-button:disabled{opacity:.55}.config-card{gap:16px}.config-card-header h4,.config-empty-state strong{margin:0;font-size:1rem;font-weight:600;line-height:1.4}.config-empty-state p{color:var(--muted);margin:8px 0 0;line-height:1.5}.editor-textarea{resize:vertical;min-height:180px;line-height:1.6}.save-feedback{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--muted-bg);align-items:center;gap:8px;padding:12px 14px;display:inline-flex}.save-feedback.saved{background:var(--success-bg);border-color:#bbf7d0}.save-feedback.error,.save-feedback.is-error{background:var(--destructive-bg);color:#b91c1c;border-color:#fecaca}.run-view,.config-view{gap:16px}.run-state{white-space:nowrap}.status-chip.run-state.running{background:var(--accent)}.status-chip.run-state.success{background:var(--success-bg);border-color:#bbf7d0}.status-chip.run-state.error{background:var(--destructive-bg);border-color:#fecaca}.run-button-spinner,.run-state-spinner,.spinner{animation:1s linear infinite spin}.run-detail-grid{grid-template-columns:minmax(0,1.3fr) minmax(300px,.9fr);align-items:start}.run-output{resize:vertical;min-height:360px;line-height:1.6}.run-summary-tile{gap:8px;display:grid}.run-summary-tile-value{word-break:break-word;font-size:.9375rem;line-height:1.5}.run-empty-state{grid-template-columns:auto minmax(0,1fr);align-items:start;gap:12px;min-height:220px;display:grid}.run-empty-state.is-error{background:var(--destructive-bg);border-color:#fecaca}.run-empty-state strong{margin-bottom:6px;display:block}.run-empty-state p,.empty-state p{color:var(--muted);margin:0;line-height:1.6}.empty-state{align-content:start;gap:12px;min-height:240px;display:grid}.profile-columns{grid-template-columns:repeat(3,minmax(0,1fr));align-items:start;gap:14px}.profile-column{border:1px solid var(--border);border-radius:calc(var(--radius-lg) + 2px);background:linear-gradient(#fffffffa,#f8f8f6f5);align-content:start;box-shadow:0 20px 34px #00000009}.profile-column-title{align-items:center;gap:12px;display:flex}.profile-agent-mark{border:1px solid var(--border);background:linear-gradient(#fff,#f2f2ef);border-radius:12px;place-items:center;width:38px;height:38px;font-size:.9rem;font-weight:700;display:grid}.profile-column-claude .profile-agent-mark{background:linear-gradient(#fff,#f5f1ed)}.profile-column-codex .profile-agent-mark{background:linear-gradient(#fff,#f1f3f6)}.profile-column-gemini .profile-agent-mark{background:linear-gradient(#fff,#f5f5f2)}.profile-agent-stats{flex-wrap:wrap;gap:6px;display:flex}.profile-agent-logo{width:20px;height:20px;overflow:hidden}.profile-stat-chip,.profile-stage-pill,.profile-count-pill{border:1px solid var(--border);min-height:26px;color:var(--muted);background:#ffffffeb;border-radius:999px;align-items:center;gap:6px;padding:0 9px;font-size:.72rem;font-weight:600;display:inline-flex}.profile-active-badge{background:var(--primary);border-color:var(--primary);color:var(--primary-foreground)}.profile-stage-header{border-bottom:1px solid #0000000f;justify-content:space-between;align-items:center;gap:16px;padding-bottom:2px;display:flex}.profile-stage-copy{gap:3px;display:grid}.profile-stage-copy h3{font-size:1rem}.profile-stage-copy .muted-copy{margin-top:0;font-size:.82rem}.profile-stage-toolbar{flex-wrap:wrap;justify-content:flex-end;gap:6px;display:flex}.profile-drop-zone{border:1px solid var(--border);border-radius:calc(var(--radius-md) + 2px);background:linear-gradient(#ffffffeb,#f7f7f4eb);gap:6px;min-height:88px;padding:10px;display:grid;box-shadow:inset 0 1px #fffc}.profile-drop-zone.is-over{border-color:var(--primary);background:linear-gradient(#fff,#efefec);transform:translateY(-1px)}.profile-drop-zone-header{justify-content:space-between;align-items:center;gap:12px;display:flex}.profile-drop-zone-title{align-items:center;gap:8px;display:flex}.profile-drop-zone-title .eyebrow{margin-bottom:0}.profile-drop-zone-icon,.profile-card-kind{border:1px solid var(--border);width:24px;height:24px;color:var(--foreground);background:#fff;border-radius:8px;flex:none;place-items:center;display:grid}.profile-count-pill{min-width:32px;color:var(--foreground);justify-content:center}.profile-card,.profile-card-overlay{padding:10px}.profile-card{touch-action:none;border:1px solid var(--border);background:#fff;border-radius:14px;transition:border-color .16s,background .16s,box-shadow .16s,transform .16s}.profile-card.is-editable{cursor:grab}.profile-card.is-editable:hover{border-color:var(--border-strong);box-shadow:0 8px 20px #0000000d}.profile-card.is-editable:active{cursor:grabbing}.profile-card.is-dragging{opacity:.45}.profile-card-overlay{box-shadow:0 10px 30px #0f172a1f}.profile-card-row{align-items:flex-start;gap:7px;display:flex}.profile-card-content{gap:1px;min-width:0;display:grid}.profile-card-content strong{font-size:.84rem;font-weight:650}.profile-card-content .muted-copy{text-overflow:ellipsis;white-space:nowrap;max-width:100%;margin-top:0;font-size:.71rem;overflow:hidden}.profile-card-remove,.profile-card-toggle,.pending-change-undo{color:var(--muted);border-radius:var(--radius-sm);background:0 0;border:0;flex-shrink:0;place-items:center;padding:4px;display:grid}.profile-card-remove:hover,.profile-card-toggle:hover,.pending-change-undo:hover{background:var(--accent);color:var(--foreground)}.profile-card-details{padding-bottom:.1rem;padding-left:1.95rem}.profile-card-details .muted-copy{text-overflow:clip;white-space:normal;max-width:none;line-height:1.45;overflow:visible}.profile-card.is-pending-add{background:var(--success-bg);border-color:#bbf7d0}.profile-card.is-pending-remove{background:var(--destructive-bg);opacity:.75;border-color:#fecaca;text-decoration:line-through}.pending-badge{border-radius:var(--radius-sm);min-height:20px;color:var(--muted);background:#f1f1efeb;flex-shrink:0;justify-content:center;align-items:center;padding:0 6px;font-size:.6875rem;font-weight:700;line-height:1;display:inline-flex}.pending-badge.is-add{background:var(--success-bg);color:var(--success)}.pending-badge.is-remove{background:var(--destructive-bg);color:#b91c1c}.pending-changes-bar{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card);z-index:12;gap:12px;display:grid;position:sticky;top:12px;box-shadow:0 16px 34px #0000000f}.profile-edit-button.is-active{background:var(--primary);border-color:var(--primary);color:var(--primary-foreground)}.pending-change-item{align-items:center;gap:8px;padding:10px 12px;font-size:.875rem;display:flex}.pending-change-item.is-add{background:var(--success-bg);border-color:#bbf7d0}.pending-change-item.is-remove{background:var(--destructive-bg);border-color:#fecaca}.pending-change-icon{flex-shrink:0;place-items:center;display:grid}.pending-change-item.is-add .pending-change-icon{color:var(--success)}.pending-change-item.is-remove .pending-change-icon{color:#b91c1c}.pending-change-text{flex:1;min-width:0}.pending-change-text strong{font-weight:600}.profile-loading{color:var(--muted);align-items:center;gap:10px;padding:12px 0;display:flex}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:1100px){.mission-layout,.mode-switcher,.signal-board,.feature-hero,.feature-ribbon,.flow-lane,.pack-flow-grid,.metrics-grid,.memory-layout,.run-detail-grid,.profile-columns,.config-field-grid,.run-agent-grid,.run-summary-grid,.install-step-grid{grid-template-columns:1fr}.profile-stage-header{flex-direction:column;align-items:stretch}.profile-stage-toolbar{justify-content:flex-start}}@media(max-width:720px){.app-shell{padding:14px}.panel,.nav-card,.workspace-card,.panel-inner,.metric-card,.config-card,.config-empty-state,.run-summary-tile,.run-empty-state,.empty-state,.pending-changes-bar{padding:16px}.topbar,.product-topbar,.mission-layout,.workspace-header,.config-toolbar,.config-card-header,.run-actions,.pending-changes-header{flex-direction:column;align-items:stretch}.secondary-button,.danger-button,.run-button,.product-action-button{width:100%}.memory-editor,.run-output{min-height:280px}.product-agent-rail{justify-content:flex-start}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}