specrails-desktop 2.31.2 → 2.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/client/dist/assets/{ActivityFeedPage-Cdccp1kl.js → ActivityFeedPage-DaBTALGY.js} +1 -1
  2. package/client/dist/assets/{AgentBrowserCapture-DUwwfVOf.js → AgentBrowserCapture-SxwVNrUs.js} +1 -1
  3. package/client/dist/assets/{AgentModeCodePane-B1Fu0f_G.js → AgentModeCodePane-CmLgIoDw.js} +2 -2
  4. package/client/dist/assets/{AgentModeJobsPane-DA6wQKKt.js → AgentModeJobsPane-BvP_T32M.js} +1 -1
  5. package/client/dist/assets/{AgentsPage-CR72XsPj.js → AgentsPage-Bz7uDqvI.js} +1 -1
  6. package/client/dist/assets/{AnalyticsPage-CPnl0xkM.js → AnalyticsPage-DrNHMTed.js} +1 -1
  7. package/client/dist/assets/{CodePage-BYY7EF1b.js → CodePage-DZtAK2Ac.js} +1 -1
  8. package/client/dist/assets/{DesktopAnalyticsPage-9PUjsD8C.js → DesktopAnalyticsPage-DrvNiDb0.js} +1 -1
  9. package/client/dist/assets/{DocsDialog-zngqdI-4.js → DocsDialog-BEQpGC1o.js} +1 -1
  10. package/client/dist/assets/{DocsPage-CDJH_q9M.js → DocsPage-Btso3Viq.js} +1 -1
  11. package/client/dist/assets/{InteractiveJobComposer-drUo56r7.js → InteractiveJobComposer-Ca9-_4VF.js} +1 -1
  12. package/client/dist/assets/{JobDetailModal-CWmzaRXG.js → JobDetailModal-Brk7fL5A.js} +1 -1
  13. package/client/dist/assets/{JobDetailPage-xlzBYZEJ.js → JobDetailPage-DiQVcvW7.js} +1 -1
  14. package/client/dist/assets/{JobsPage-Dcnol1Y6.js → JobsPage-1SvirYQm.js} +1 -1
  15. package/client/dist/assets/{LoopBuilderPage-D3q7EoNM.js → LoopBuilderPage-X_YwJ-Ik.js} +1 -1
  16. package/client/dist/assets/{LoopPreviewModal-Q8osegkj.js → LoopPreviewModal-BeW-cr7A.js} +1 -1
  17. package/client/dist/assets/{LoopsPage-CATnNd1X.js → LoopsPage-Na9vDt4p.js} +1 -1
  18. package/client/dist/assets/{MinimizedChatsContext-DIsnQMVz.js → MinimizedChatsContext-BQQohTp2.js} +1 -1
  19. package/client/dist/assets/{PluginsPage-BOh6z0zK.js → PluginsPage-B-NLA93L.js} +1 -1
  20. package/client/dist/assets/{ProjectSettingsDialog-CNcANqEL.js → ProjectSettingsDialog-CQlq1Mf7.js} +1 -1
  21. package/client/dist/assets/{TemplatePreviewModal-4EpqyErX.js → TemplatePreviewModal-CPz1o3fP.js} +1 -1
  22. package/client/dist/assets/{TicketDetailModal-BfV4tnvr.js → TicketDetailModal-DEoAJOuD.js} +3 -3
  23. package/client/dist/assets/{Trans-cWtExGkC.js → Trans-CpUoGvNy.js} +1 -1
  24. package/client/dist/assets/agentstudio-BNUth0uj.js +1 -0
  25. package/client/dist/assets/agentstudio-BNdB5hkr.js +1 -0
  26. package/client/dist/assets/agentstudio-C7-bt8FO.js +1 -0
  27. package/client/dist/assets/agentstudio-C8uNchpV.js +1 -0
  28. package/client/dist/assets/agentstudio-CKabyMlg.js +1 -0
  29. package/client/dist/assets/agentstudio-CN2pokQu.js +1 -0
  30. package/client/dist/assets/agentstudio-DR7doNBV.js +1 -0
  31. package/client/dist/assets/agentstudio-y2dVDXeM.js +1 -0
  32. package/client/dist/assets/{dist-js-Cn09PP3z.js → dist-js-1QRck05T.js} +1 -1
  33. package/client/dist/assets/{dist-js-mq5XA-4f.js → dist-js-K9AsZWxz.js} +1 -1
  34. package/client/dist/assets/{formatDistanceToNow-DUyzS4rr.js → formatDistanceToNow-2bGOYubE.js} +1 -1
  35. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BCIwmmTj.js → getTimezoneOffsetInMilliseconds-B_N-0uSl.js} +1 -1
  36. package/client/dist/assets/{i18n-D21Pr8Sj.js → i18n-B2SaZsf2.js} +2 -2
  37. package/client/dist/assets/{index-CzNyrRn5.js → index-Bpzm94S9.js} +17 -17
  38. package/client/dist/assets/index-ChIuonbC.css +2 -0
  39. package/client/dist/assets/loops-B2_97D26.js +1 -0
  40. package/client/dist/assets/loops-BISOkuCu.js +1 -0
  41. package/client/dist/assets/loops-Bo6w_peZ.js +1 -0
  42. package/client/dist/assets/loops-BwxCndZk.js +1 -0
  43. package/client/dist/assets/loops-CD19kEzq.js +1 -0
  44. package/client/dist/assets/loops-CMMQOw2P.js +1 -0
  45. package/client/dist/assets/loops-CnxqL8IL.js +1 -0
  46. package/client/dist/assets/loops-aEb4RxN2.js +1 -0
  47. package/client/dist/assets/setup-CA9J5hck.js +1 -0
  48. package/client/dist/assets/setup-CK8IKkeD.js +1 -0
  49. package/client/dist/assets/setup-Cas_jrnl.js +1 -0
  50. package/client/dist/assets/setup-ClcYC8KP.js +1 -0
  51. package/client/dist/assets/setup-CtfFTXdf.js +1 -0
  52. package/client/dist/assets/setup-D73npsqO.js +1 -0
  53. package/client/dist/assets/setup-DXw1UgZB.js +1 -0
  54. package/client/dist/assets/setup-DsKIBie0.js +1 -0
  55. package/client/dist/assets/{spending-BCyUxoOI.js → spending-B20-uFLQ.js} +1 -1
  56. package/client/dist/assets/{useBrowserCaptureSession-CkVCDzer.js → useBrowserCaptureSession-DACautTD.js} +1 -1
  57. package/client/dist/assets/{useDesktop-DCP_MHp9.js → useDesktop-Cwyis9DX.js} +1 -1
  58. package/client/dist/index.html +14 -14
  59. package/package.json +1 -1
  60. package/server/dist/ai-invocations.js +35 -0
  61. package/server/dist/job-phase-breakdown.js +132 -0
  62. package/server/dist/loop-executors.js +10 -3
  63. package/server/dist/loop-factory.js +7 -5
  64. package/server/dist/loop-graph.js +4 -3
  65. package/server/dist/loop-run-manager.js +7 -3
  66. package/server/dist/loop-templates.js +4 -3
  67. package/server/dist/pr-body.js +13 -0
  68. package/server/dist/profiles-router.js +24 -1
  69. package/server/dist/project-router-jobs.js +16 -0
  70. package/server/dist/queue-manager.js +4 -0
  71. package/server/dist/rail-isolated-launch.js +15 -0
  72. package/server/dist/rail-pr-decision.js +10 -0
  73. package/server/dist/repo-map.js +293 -0
  74. package/server/dist/spawn-lifecycle.js +1 -1
  75. package/server/dist/worktree-node-modules.js +158 -0
  76. package/client/dist/assets/agentstudio-8TQqBenW.js +0 -1
  77. package/client/dist/assets/agentstudio-B8Z_mmEX.js +0 -1
  78. package/client/dist/assets/agentstudio-BZR9YmLs.js +0 -1
  79. package/client/dist/assets/agentstudio-Bge9pAWb.js +0 -1
  80. package/client/dist/assets/agentstudio-Bz169Vzt.js +0 -1
  81. package/client/dist/assets/agentstudio-D6L2jpNi.js +0 -1
  82. package/client/dist/assets/agentstudio-K2-Z7CL0.js +0 -1
  83. package/client/dist/assets/agentstudio-Zmgzthv8.js +0 -1
  84. package/client/dist/assets/index-Bz0TeGRs.css +0 -2
  85. package/client/dist/assets/loops-BzfXWEwO.js +0 -1
  86. package/client/dist/assets/loops-CPpgMapU.js +0 -1
  87. package/client/dist/assets/loops-CWWbKuVL.js +0 -1
  88. package/client/dist/assets/loops-Crc9It8o.js +0 -1
  89. package/client/dist/assets/loops-DH2hZcbK.js +0 -1
  90. package/client/dist/assets/loops-DS5TmvIU.js +0 -1
  91. package/client/dist/assets/loops-P2f0cN8-.js +0 -1
  92. package/client/dist/assets/loops-fJV-9hH7.js +0 -1
  93. package/client/dist/assets/setup-BBiHEO7h.js +0 -1
  94. package/client/dist/assets/setup-BlTWhNIQ.js +0 -1
  95. package/client/dist/assets/setup-Bp2L_oiP.js +0 -1
  96. package/client/dist/assets/setup-CInYXp1-.js +0 -1
  97. package/client/dist/assets/setup-CYH3bP6K.js +0 -1
  98. package/client/dist/assets/setup-DwcQ921P.js +0 -1
  99. package/client/dist/assets/setup-PBLjuDSs.js +0 -1
  100. package/client/dist/assets/setup-bx6FtoBp.js +0 -1
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildRepoMap = buildRepoMap;
37
+ exports.formatRepoMap = formatRepoMap;
38
+ exports.isRepoMapEnabled = isRepoMapEnabled;
39
+ exports.ensureRepoMapFile = ensureRepoMapFile;
40
+ exports.injectRepoMapEnv = injectRepoMapEnv;
41
+ exports._clearRepoMapCache = _clearRepoMapCache;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const crypto = __importStar(require("crypto"));
45
+ const artifact_registry_1 = require("./artifact-registry");
46
+ const SKIP_DIRS = new Set([
47
+ 'node_modules', 'vendor', 'dist', 'build', 'out', 'coverage', 'target',
48
+ '__pycache__', 'venv', '.venv', 'Pods', 'DerivedData',
49
+ ]);
50
+ /** Manifest filename → ecosystem label. First match wins (iteration order). */
51
+ const MANIFESTS = [
52
+ ['package.json', 'node'],
53
+ ['pyproject.toml', 'python'],
54
+ ['setup.py', 'python'],
55
+ ['requirements.txt', 'python'],
56
+ ['go.mod', 'go'],
57
+ ['Cargo.toml', 'rust'],
58
+ ['pom.xml', 'jvm'],
59
+ ['build.gradle', 'jvm'],
60
+ ['build.gradle.kts', 'jvm'],
61
+ ['Package.swift', 'swift'],
62
+ ['Gemfile', 'ruby'],
63
+ ['composer.json', 'php'],
64
+ ];
65
+ const MAX_SERVICES = 40;
66
+ const README_MAX_LINES = 12;
67
+ const README_MAX_CHARS = 800;
68
+ /** File-count scan caps — the bucket is a rough size label, not a census. */
69
+ const SCAN_MAX_DEPTH = 2;
70
+ const SCAN_MAX_ENTRIES = 500;
71
+ function buildRepoMap(repoDir) {
72
+ const services = [];
73
+ const seen = new Set();
74
+ const addService = (relDir) => {
75
+ if (seen.has(relDir) || services.length >= MAX_SERVICES + 1)
76
+ return;
77
+ const abs = relDir === '' ? repoDir : path.join(repoDir, relDir);
78
+ const eco = detectEcosystem(abs);
79
+ if (!eco)
80
+ return;
81
+ seen.add(relDir);
82
+ services.push({
83
+ dir: relDir,
84
+ name: packageName(abs) ?? (relDir === '' ? path.basename(repoDir) : path.basename(relDir)),
85
+ ecosystem: eco,
86
+ sizeBucket: sizeBucket(abs),
87
+ hasReadme: readmePath(abs) !== null,
88
+ });
89
+ };
90
+ addService('');
91
+ for (const entry of listDirs(repoDir)) {
92
+ addService(entry);
93
+ }
94
+ // npm/yarn workspaces can nest packages one level below the top-level scan.
95
+ for (const rel of resolveNpmWorkspaces(repoDir)) {
96
+ addService(rel);
97
+ }
98
+ const truncated = services.length > MAX_SERVICES;
99
+ return {
100
+ readmeExcerpt: readReadmeExcerpt(repoDir),
101
+ services: services.slice(0, MAX_SERVICES),
102
+ truncated,
103
+ };
104
+ }
105
+ function formatRepoMap(map) {
106
+ const lines = ['# Repository map (deterministic — generated by Specrails, no AI)', ''];
107
+ if (map.readmeExcerpt) {
108
+ lines.push('## README excerpt', '', map.readmeExcerpt, '');
109
+ }
110
+ lines.push('## Packages');
111
+ if (map.services.length === 0) {
112
+ lines.push('- (no recognized package manifests found)');
113
+ }
114
+ for (const s of map.services) {
115
+ const dirLabel = s.dir === '' ? './' : `${s.dir}/`;
116
+ const readme = s.hasReadme ? 'has README' : 'no README';
117
+ lines.push(`- \`${dirLabel}\` — ${s.name} (${s.ecosystem}, ${s.sizeBucket}, ${readme})`);
118
+ }
119
+ if (map.truncated) {
120
+ lines.push(`- … more packages omitted (cap ${MAX_SERVICES})`);
121
+ }
122
+ lines.push('', 'Use this map to orient exploration without spending turns on top-level discovery.', '');
123
+ return lines.join('\n');
124
+ }
125
+ const cache = new Map();
126
+ const CACHE_TTL_MS = 60_000;
127
+ function isRepoMapEnabled() {
128
+ return process.env.SPECRAILS_REPO_MAP !== 'false';
129
+ }
130
+ /**
131
+ * Build (or reuse, 60s TTL) the on-disk map for a repo/worktree. Returns the
132
+ * file path, or null on any failure — the map is an accelerator, never a
133
+ * spawn blocker.
134
+ */
135
+ function ensureRepoMapFile(repoDir) {
136
+ try {
137
+ const real = fs.realpathSync(repoDir);
138
+ const hit = cache.get(real);
139
+ if (hit && Date.now() - hit.at < CACHE_TTL_MS && fs.existsSync(hit.filePath)) {
140
+ return hit.filePath;
141
+ }
142
+ const content = formatRepoMap(buildRepoMap(real));
143
+ const dir = path.join((0, artifact_registry_1.resolveHome)(), '.specrails', 'repo-maps');
144
+ fs.mkdirSync(dir, { recursive: true });
145
+ const filePath = path.join(dir, `${sha1(real)}.md`);
146
+ const tmp = `${filePath}.tmp-${process.pid}`;
147
+ fs.writeFileSync(tmp, content, 'utf8');
148
+ fs.renameSync(tmp, filePath);
149
+ cache.set(real, { filePath, at: Date.now() });
150
+ return filePath;
151
+ }
152
+ catch {
153
+ return null;
154
+ }
155
+ }
156
+ /** Add `SPECRAILS_REPO_MAP_PATH` to a spawn env. Never throws, never blocks. */
157
+ function injectRepoMapEnv(env, repoDir) {
158
+ if (!repoDir || !isRepoMapEnabled())
159
+ return env;
160
+ const filePath = ensureRepoMapFile(repoDir);
161
+ return filePath ? { ...env, SPECRAILS_REPO_MAP_PATH: filePath } : env;
162
+ }
163
+ /** Test hook — clears the TTL cache. */
164
+ function _clearRepoMapCache() {
165
+ cache.clear();
166
+ }
167
+ // ─── Internals ────────────────────────────────────────────────────────────────
168
+ function sha1(value) {
169
+ return crypto.createHash('sha1').update(value).digest('hex');
170
+ }
171
+ function listDirs(dir) {
172
+ let entries;
173
+ try {
174
+ entries = fs.readdirSync(dir, { withFileTypes: true });
175
+ }
176
+ catch {
177
+ return [];
178
+ }
179
+ return entries
180
+ .filter((e) => e.isDirectory() && !e.name.startsWith('.') && !SKIP_DIRS.has(e.name))
181
+ .map((e) => e.name)
182
+ .sort();
183
+ }
184
+ function detectEcosystem(dir) {
185
+ for (const [manifest, eco] of MANIFESTS) {
186
+ if (fs.existsSync(path.join(dir, manifest)))
187
+ return eco;
188
+ }
189
+ return null;
190
+ }
191
+ function packageName(dir) {
192
+ try {
193
+ const raw = fs.readFileSync(path.join(dir, 'package.json'), 'utf8');
194
+ const parsed = JSON.parse(raw);
195
+ return typeof parsed.name === 'string' && parsed.name.trim() ? parsed.name.trim() : null;
196
+ }
197
+ catch {
198
+ return null;
199
+ }
200
+ }
201
+ function readmePath(dir) {
202
+ for (const name of ['README.md', 'readme.md', 'README.txt', 'README']) {
203
+ const p = path.join(dir, name);
204
+ if (fs.existsSync(p))
205
+ return p;
206
+ }
207
+ return null;
208
+ }
209
+ function readReadmeExcerpt(repoDir) {
210
+ const p = readmePath(repoDir);
211
+ if (!p)
212
+ return null;
213
+ try {
214
+ const lines = fs.readFileSync(p, 'utf8').split('\n').slice(0, README_MAX_LINES);
215
+ const text = lines.join('\n').trim();
216
+ if (!text)
217
+ return null;
218
+ return text.length > README_MAX_CHARS ? `${text.slice(0, README_MAX_CHARS)}…` : text;
219
+ }
220
+ catch {
221
+ return null;
222
+ }
223
+ }
224
+ /** Rough size label from a capped, shallow file count. */
225
+ function sizeBucket(dir) {
226
+ let count = 0;
227
+ const walk = (d, depth) => {
228
+ if (depth > SCAN_MAX_DEPTH || count > SCAN_MAX_ENTRIES)
229
+ return;
230
+ let entries;
231
+ try {
232
+ entries = fs.readdirSync(d, { withFileTypes: true });
233
+ }
234
+ catch {
235
+ return;
236
+ }
237
+ for (const e of entries) {
238
+ if (count > SCAN_MAX_ENTRIES)
239
+ return;
240
+ if (e.name.startsWith('.') || SKIP_DIRS.has(e.name))
241
+ continue;
242
+ if (e.isDirectory()) {
243
+ walk(path.join(d, e.name), depth + 1);
244
+ }
245
+ else {
246
+ count++;
247
+ }
248
+ }
249
+ };
250
+ walk(dir, 0);
251
+ if (count < 20)
252
+ return 'small';
253
+ if (count < 150)
254
+ return 'medium';
255
+ return 'large';
256
+ }
257
+ /**
258
+ * Resolve npm/yarn `workspaces` from the root package.json. Literal paths and
259
+ * trailing `/*` globs only — deliberately no glob library; anything fancier
260
+ * falls back to the top-level scan.
261
+ */
262
+ function resolveNpmWorkspaces(repoDir) {
263
+ let patterns = [];
264
+ try {
265
+ const raw = fs.readFileSync(path.join(repoDir, 'package.json'), 'utf8');
266
+ const parsed = JSON.parse(raw);
267
+ const ws = parsed.workspaces;
268
+ if (Array.isArray(ws)) {
269
+ patterns = ws.filter((w) => typeof w === 'string');
270
+ }
271
+ else if (ws && typeof ws === 'object' && Array.isArray(ws.packages)) {
272
+ patterns = (ws.packages).filter((w) => typeof w === 'string');
273
+ }
274
+ }
275
+ catch {
276
+ return [];
277
+ }
278
+ const out = [];
279
+ for (const pattern of patterns) {
280
+ const clean = pattern.replace(/^\.\//, '');
281
+ if (clean.endsWith('/*')) {
282
+ const base = clean.slice(0, -2);
283
+ const abs = path.join(repoDir, base);
284
+ for (const child of listDirs(abs)) {
285
+ out.push(path.join(base, child));
286
+ }
287
+ }
288
+ else if (!clean.includes('*')) {
289
+ out.push(clean);
290
+ }
291
+ }
292
+ return out;
293
+ }
@@ -66,7 +66,7 @@ function runAiCliInvocation(hooks) {
66
66
  return;
67
67
  }
68
68
  hooks.onSpawn?.(child);
69
- if (hooks.timeoutMs != null) {
69
+ if (hooks.timeoutMs != null && hooks.timeoutMs > 0) {
70
70
  timer = setTimeout(() => {
71
71
  hooks.onTimeout?.();
72
72
  // treeKill the whole subtree (a bare child.kill leaves grandchildren),
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isWorktreeNodeModulesEnabled = isWorktreeNodeModulesEnabled;
37
+ exports.linkNodeModulesIntoWorktree = linkNodeModulesIntoWorktree;
38
+ /**
39
+ * Warm-dependency reuse for isolated rail worktrees.
40
+ *
41
+ * `git worktree add` materializes only TRACKED files, so a fresh worktree has
42
+ * no `node_modules` — every isolated run used to pay a cold `npm install`
43
+ * (root + nested packages) plus cold build caches before doing any real work.
44
+ * This module links the base checkout's existing install into the worktree so
45
+ * the run starts warm.
46
+ *
47
+ * Mechanics:
48
+ * - DISCOVER: every directory that holds a `package.json` in the base repo at
49
+ * depth ≤ `MAX_DEPTH` (root plus shallow sub-packages like `client/`),
50
+ * skipping dot-dirs and anything inside a `node_modules` tree.
51
+ * - LINK: for each discovered package dir whose base checkout actually has a
52
+ * `node_modules`, create the same relative path in the worktree as a
53
+ * SYMLINK (junction on Windows). No copy fallback on purpose — copying a
54
+ * multi-GB dependency tree would be slower than the `npm install` it
55
+ * replaces; a failed link simply degrades to the legacy cold start.
56
+ * - NEVER overwrite: an existing entry at the destination (a real dir, a
57
+ * prior link, anything) is left untouched, so resume passes are idempotent
58
+ * and an agent-made install is never clobbered.
59
+ *
60
+ * The returned `linked` paths are appended to the launch's overlay-exclusion
61
+ * list, so a linked `node_modules` inherits the same commit-time guarantees as
62
+ * overlay scaffolding (excluded pathspecs + index audit) even if the repo's
63
+ * `.gitignore` were ever missing the entry.
64
+ *
65
+ * Honest caveat (documented, accepted): the link SHARES the dependency tree
66
+ * with the base checkout. Reads (tests, builds) are safe under concurrency; an
67
+ * in-worktree `npm install` would write through to the shared tree — the same
68
+ * mutation it would make in the user's checkout after merge.
69
+ *
70
+ * Kill switch: `SPECRAILS_WORKTREE_NODE_MODULES=false` restores the byte-
71
+ * identical cold-worktree behaviour.
72
+ */
73
+ const fs = __importStar(require("fs"));
74
+ const path = __importStar(require("path"));
75
+ /** Package-dir discovery depth: 0 = repo root, 1 = `client/`-style children. */
76
+ const MAX_DEPTH = 2;
77
+ function isWorktreeNodeModulesEnabled() {
78
+ return (process.env.SPECRAILS_WORKTREE_NODE_MODULES ?? '').toLowerCase() !== 'false';
79
+ }
80
+ function isDir(p) {
81
+ try {
82
+ return fs.statSync(p).isDirectory();
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ function exists(p) {
89
+ try {
90
+ fs.lstatSync(p);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ }
97
+ function errMsg(err) {
98
+ return err instanceof Error ? err.message : String(err);
99
+ }
100
+ /** Relative POSIX paths of package dirs (containing package.json) at depth ≤ MAX_DEPTH. */
101
+ function discoverPackageDirs(baseRepo) {
102
+ const found = [];
103
+ const walk = (rel, depth) => {
104
+ const abs = rel === '' ? baseRepo : path.join(baseRepo, rel);
105
+ if (exists(path.join(abs, 'package.json')))
106
+ found.push(rel);
107
+ if (depth >= MAX_DEPTH)
108
+ return;
109
+ let names;
110
+ try {
111
+ names = fs.readdirSync(abs);
112
+ }
113
+ catch {
114
+ return;
115
+ }
116
+ for (const name of names) {
117
+ // Dot-dirs (.git, .specrails, provider dirs) and dependency trees never
118
+ // hold linkable first-party packages.
119
+ if (name.startsWith('.') || name === 'node_modules')
120
+ continue;
121
+ const childAbs = path.join(abs, name);
122
+ if (!isDir(childAbs))
123
+ continue;
124
+ walk(rel === '' ? name : `${rel}/${name}`, depth + 1);
125
+ }
126
+ };
127
+ walk('', 0);
128
+ return found;
129
+ }
130
+ /**
131
+ * Link the base checkout's installed `node_modules` trees into a fresh
132
+ * worktree. Best-effort and side-effect-transparent: never throws, never
133
+ * overwrites, returns what it created so the caller can exclude those paths
134
+ * from commits.
135
+ */
136
+ function linkNodeModulesIntoWorktree(baseRepo, worktreePath) {
137
+ const result = { linked: [], warnings: [] };
138
+ if (!isWorktreeNodeModulesEnabled())
139
+ return result;
140
+ for (const pkgRel of discoverPackageDirs(baseRepo)) {
141
+ const rel = pkgRel === '' ? 'node_modules' : `${pkgRel}/node_modules`;
142
+ const src = path.join(baseRepo, ...rel.split('/'));
143
+ if (!isDir(src))
144
+ continue;
145
+ const dest = path.join(worktreePath, ...rel.split('/'));
146
+ if (exists(dest))
147
+ continue;
148
+ try {
149
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
150
+ fs.symlinkSync(src, dest, process.platform === 'win32' ? 'junction' : undefined);
151
+ result.linked.push(rel);
152
+ }
153
+ catch (err) {
154
+ result.warnings.push(`failed to link ${rel}: ${errMsg(err)}`);
155
+ }
156
+ }
157
+ return result;
158
+ }
@@ -1 +0,0 @@
1
- var e={loadingAgent:`正在加载 Agent…`,modeCreate:`新建自定义 Agent`,modeEdit:`编辑自定义 Agent`,create:`创建`,unsaved:`● 未保存`,resumeAiEdit:`继续 AI 编辑`,resumeAiEditTitle:`将此草稿交还给 AI 编辑浮层`,loadingAiDraft:`正在加载 AI 草稿…`,testButton:`测试`,testButtonTitle:`用示例任务测试此 Agent`,historyButton:`历史`,historyButtonTitle:`版本历史`,deleteConfirm:{title:`删除 Agent“{{agentId}}”?`,description:`这会从磁盘上删除该 .md 文件。版本历史仍保留在数据库中——若日后需要恢复内容,可新建一个自定义 Agent。`},errors:{loadDraftFailed:`加载草稿失败:{{status}}`,loadFailed:`加载失败:{{status}}`,saveFailed:`保存失败:{{status}}`,deleteFailed:`删除失败:{{status}}`,testFailed:`测试失败:{{status}}`},toasts:{agentCreated:`Agent 已创建`,agentSaved:`Agent 已保存`,agentDeleted:`Agent 已删除`,createFailed:`创建 Agent 失败`,saveFailed:`保存 Agent 失败`,deleteFailed:`删除 Agent 失败`},validation:{namePattern:`名称必须以 <code>custom-</code> 开头,且只能包含小写字母、数字和连字符。`,missingFrontmatter:`缺少 YAML frontmatter(第一行需要起始的 <code>---</code>)。`},sampleTasks:{pick:`—— 选择一个示例任务 ——`,terraform:`Terraform:公开的 S3 存储桶`,sqlInjection:`代码评审:SQL 注入`,accessibility:`前端:无障碍`,schemaChange:`数据:schema 变更`,slowQuery:`性能:慢查询`},testPane:{header:`测试 Agent`,sampleTaskLabel:`示例任务`,placeholder:`描述该 Agent 应该做什么,或在上方选择一个示例。`,run:`运行`,running:`运行中…`,sandboxNote:`沙箱运行;不写入任何文件。`,tokens_one:`<mono>{{count}}</mono> 个 token`,tokens_other:`<mono>{{count}}</mono> 个 token`,tokensUnavailable:`Token 用量不可用`,emptyHint:`针对当前草稿运行一个示例任务,输出会显示在这里。`},versions:{header:`版本历史`,empty:`此 Agent 暂无历史版本记录。`,restoreHint:`点击某个版本可将其内容恢复到编辑器中(仍需手动保存)。`}},t={eyebrow:`AI 编辑`,headline:`优化你的 Agent`,streamingHeadline:`正在优化你的 Agent…`,placeholderInitial:`描述如何优化此 Agent…`,placeholderFollowUp:`发送后续优化指令…`,viewCurrentBody:`查看当前 Agent 正文`,appliedAsVersion:`已应用为版本 {{version}}。`,openInStudio:`在 Studio 中打开草稿进行手动编辑`,chips:{tightenTools:`收紧工具列表`,stricterPersonality:`让人格设定更严格`,workflowSection:`添加 Workflow 协议章节`,sharpenDescription:`精简并锐化描述`,matchDeveloperStyle:`对齐 sr-developer 的风格`}},n={validation:{missingBaseline:`缺少必需的基线 Agent:{{agent}}`,multipleDefaultRules:`路由最多只能有一条默认规则(发现 {{found}} 条)`,defaultRuleNotLast:`默认路由规则必须是最后一条`,unknownRoutingAgent:`路由引用了不在链中的 Agent:{{agent}}`,invalidTags:`路由规则 {{agent}} 包含无效标签:{{tags}}(请使用小写 kebab-case)`},validationSummary_one:`{{count}} 个校验问题`,validationSummary_other:`{{count}} 个校验问题`,nameLabel:`名称`,descriptionLabel:`描述`,descriptionPlaceholder:`这个 Profile 用来做什么?`,orchestrator:{heading:`编排器`,description:`两个命令共用的顶层模型。batch-implement 会按 feature 委派给 implement,因此它启动的每条 rail 都会继承此 Profile 的 Agent 链。`},agentChain:{heading:`Agent 链({{n}})`,addTitle:`从目录中添加 Agent`,addDisabledTitle:`目录中的所有 Agent 都已在链中`,pickFromCatalog:`从目录选择({{n}} 个可用)`,emptyCatalog:`目录中没有更多 Agent。请在 Agent 目录标签页中添加自定义 Agent。`,kind:{upstream:`上游`,custom:`自定义`}},routing:{heading:`路由({{n}})`,addDefault:`添加默认规则`,addRule:`添加规则`,needAgentsTitle:`请先添加至少一个 Agent,再创建路由规则`,explainer:`首条匹配的规则生效。规则可编辑、可删除;存在默认兜底规则时它始终位于最后。如果路由留空,流水线会回退到链中第一个开发者类型的 Agent。`,untargetedTitle:`链中存在未被路由指向的 Agent`,untargetedDetail:`没有路由规则指向:<mono>{{agents}}</mono>。如需让它们运行,请添加标签规则或调整默认规则的目标。`},agentRow:{dragTitle:`拖动以重新排序`,dragHandleAria:`拖动手柄`,pinnedFirst:`首位`,pinnedFirstTitle:`固定在首位——流水线始终从 sr-architect 开始`,pinnedLast:`末位`,pinnedLastTitle:`固定在末位——合并阶段始终最后运行`,required:`必需`,requiredRemoveTitle:`必需的基线 Agent——流水线依赖此行`},routingRow:{everythingElse:`其余所有`,defaultTargetAria:`默认路由目标(核心,只读)`,defaultTargetTitle:`核心兜底——不可编辑`,targetAria:`规则 {{ordinal}} 的路由目标`,editTitle:`编辑规则`,editAria:`编辑规则 {{ordinal}}`,moveDown:`下移`,moveUp:`上移`,coreDefaultBadge:`核心 · 默认`,coreDefaultTitle:`核心兜底——流水线的最终兜底规则,固定指向 sr-developer`}},r={selectedCount:`已选择 {{selected}} / {{total}} 个 Agent`,selectAll:`全选`,coreBadge:`核心`,categories:{architecture:`架构`,development:`开发`,review:`评审`,product:`产品`,utilities:`工具`},agents:{"sr-architect":{name:`架构师`,description:`架构设计、变更 spec、实现规划`},"sr-developer":{name:`开发者`,description:`覆盖所有层的全栈实现`},"sr-frontend-developer":{name:`前端开发`,description:`前端实现(React、Vue、Angular 等)`},"sr-backend-developer":{name:`后端开发`,description:`后端专精(API、数据库、服务)`},"sr-reviewer":{name:`评审员`,description:`通用代码评审——最终质量门禁`},"sr-frontend-reviewer":{name:`前端评审`,description:`前端评审(UI、无障碍、性能)`},"sr-backend-reviewer":{name:`后端评审`,description:`后端评审(API、安全、可扩展性)`},"sr-security-reviewer":{name:`安全评审`,description:`安全分析——OWASP、漏洞、安全加固`},"sr-performance-reviewer":{name:`性能评审`,description:`性能分析——性能剖析、瓶颈、优化`},"sr-product-manager":{name:`产品经理`,description:`产品探索、VPC 用户画像、backlog 管理`},"sr-product-analyst":{name:`产品分析师`,description:`Backlog 分析、spec 缺口分析、报告`},"sr-test-writer":{name:`测试编写者`,description:`全面的测试生成(单元、集成、E2E)`},"sr-doc-sync":{name:`文档同步`,description:`文档同步——保持文档与代码一致`},"sr-merge-resolver":{name:`合并冲突解决器`,description:`具备上下文感知的合并冲突解决`}}},i={"security-reviewer":{label:`安全评审员`,blurb:`在 diff 交付前发现认证、注入与数据泄露问题。`},"performance-profiler":{label:`性能剖析师`,blurb:`发现热点路径、N+1 查询、无界循环、bundle 膨胀。`},"data-engineer":{label:`数据工程师`,blurb:`Schema 迁移、ETL 流水线、数据转换。`},"ui-ux-polisher":{label:`UI / UX 打磨师`,blurb:`无障碍、间距、空状态、错误处理。`},"api-designer":{label:`API 设计师`,blurb:`版本管理、分页、错误结构、向后兼容。`},"database-architect":{label:`数据库架构师`,blurb:`索引、规范化与反规范化、查询模式。`},"devops-sre":{label:`DevOps / SRE`,blurb:`CI/CD、可观测性、事故响应准备、运维手册。`},"mobile-engineer":{label:`移动端工程师`,blurb:`iOS + Android 模式、离线优先、电量友好。`},"ml-engineer":{label:`机器学习工程师`,blurb:`流水线、评估、可复现性、漂移监控。`},"accessibility-auditor":{label:`无障碍审计员`,blurb:`WCAG 2.2 评审:对比度、焦点、ARIA、键盘。`},"qa-test-strategist":{label:`QA 测试策略师`,blurb:`测试计划:单元 / 集成 / E2E 划分、覆盖率缺口。`},"load-tester":{label:`负载 / 压力测试员`,blurb:`容量规划、k6 / Locust 场景、瓶颈排查。`},"integration-tester":{label:`集成测试员`,blurb:`跨服务契约、测试夹具、减少偶发失败。`},"regression-hunter":{label:`回归猎手`,blurb:`二分定位、复现问题、先写出会失败的测试。`},"data-analyst":{label:`数据分析师`,blurb:`把模糊的问题变成查询和可读的结论。`},"etl-reviewer":{label:`ETL 流水线评审`,blurb:`幂等性、数据回填、迟到数据。`},"dashboard-designer":{label:`仪表盘设计师`,blurb:`一眼看懂的仪表盘、诚实的坐标轴、每张图对应一个行动。`},"iac-reviewer":{label:`IaC / 云评审`,blurb:`Terraform / CloudFormation:IAM、公网暴露、成本。`},"compliance-reviewer":{label:`合规评审`,blurb:`针对数据流的 GDPR / SOC2 / HIPAA 相关检查。`},"threat-modeler":{label:`威胁建模师`,blurb:`对架构图进行 STRIDE / LINDDUN 分析。`},"product-manager":{label:`产品经理`,blurb:`问题界定、PRD、优先级排序。`},"ux-researcher":{label:`UX 研究员`,blurb:`访谈脚本、可用性测试计划、结果综合。`},"technical-writer":{label:`技术写作者`,blurb:`真正有人读的文档——教程、参考、更新日志。`},"design-reviewer":{label:`设计系统评审`,blurb:`Token 漂移、组件误用、跨流程一致性。`},"financial-analyst":{label:`财务分析师`,blurb:`单位经济模型、同期群模型、情景分析。`},"pricing-strategist":{label:`定价策略师`,blurb:`分层、打包、支付意愿研究。`},"market-researcher":{label:`市场研究员`,blurb:`TAM/SAM/SOM、竞争格局图、客户细分。`},"ops-optimizer":{label:`运营优化师`,blurb:`周期时间、瓶颈定位、自动化候选项。`},"seo-auditor":{label:`SEO 审计员`,blurb:`技术 + 内容 SEO:可索引性、信息架构、意图匹配。`},"growth-hacker":{label:`增长实验师`,blurb:`漏斗诊断、提升实验、激活闭环。`},"social-strategist":{label:`社交媒体策略师`,blurb:`适配渠道的内容、编辑日历、语调一致性。`},"literature-reviewer":{label:`文献综述员`,blurb:`系统性综述摘要、引用图谱、矛盾发现。`},"experiment-designer":{label:`实验设计师`,blurb:`假设、对照、样本量、预注册。`},"statistical-analyst":{label:`统计分析师`,blurb:`选对检验方法,报告效应量而不只是 p 值。`},"scientific-writer":{label:`科学写作者`,blurb:`IMRaD 结构、坦诚的局限性、可读的摘要。`},"curriculum-designer":{label:`课程设计师`,blurb:`学习目标 → 教学活动 → 评估。`},"assessment-author":{label:`测评编写者`,blurb:`衡量理解而非记忆的题目。`},"tutor-explainer":{label:`导师 / 讲解者`,blurb:`费曼式的简明讲解,配有完整例题。`},"clinical-guideline-reviewer":{label:`临床指南评审`,blurb:`将临床实践与最新循证指南对照。`},"medical-summarizer":{label:`医学文献摘要员`,blurb:`面向临床医生的摘要:变化点与证据质量。`},"protocol-designer":{label:`方案设计师`,blurb:`临床方案:终点指标、入组标准、安全性。`},"contract-reviewer":{label:`合同评审`,blurb:`标记高风险条款,并解释其实际含义。`},"privacy-counsel":{label:`隐私顾问`,blurb:`将 GDPR / CCPA / LGPD 应用到具体流程。`},"copy-editor":{label:`文字编辑`,blurb:`逐行润色:语气、节奏,删减 30% 而不失原意。`},"brand-voice-guardian":{label:`品牌语调守护者`,blurb:`执行语调规则,捕捉偏离品牌的措辞。`},"creative-brainstormer":{label:`创意头脑风暴师`,blurb:`先发散后收敛,礼貌地挑战固有观念。`},"hiring-interviewer":{label:`招聘面试官`,blurb:`结构化面试,聚焦信号,规避偏见。`},"strategic-planner":{label:`战略规划师`,blurb:`目标 → 押注 → 指标;剔除个人偏好项目。`},"coach-1on1":{label:`1:1 教练`,blurb:`帮助组织反馈、规划职业成长、应对艰难对话。`},"meeting-facilitator":{label:`会议主持人`,blurb:`产出决策而非汇报的会议议程。`}},a={studio:e,refine:t,profileEditor:n,agentSelector:r,templates:i};export{r as agentSelector,a as default,n as profileEditor,t as refine,e as studio,i as templates};
@@ -1 +0,0 @@
1
- var e={loadingAgent:`Cargando agente…`,modeCreate:`Nuevo agente personalizado`,modeEdit:`Editar agente personalizado`,create:`Crear`,unsaved:`● sin guardar`,resumeAiEdit:`Reanudar AI Edit`,resumeAiEditTitle:`Devolver este borrador al panel de AI Edit`,loadingAiDraft:`cargando borrador de IA…`,testButton:`Probar`,testButtonTitle:`Probar este agente con una tarea de ejemplo`,historyButton:`Historial`,historyButtonTitle:`Historial de versiones`,deleteConfirm:{title:`¿Eliminar el agente "{{agentId}}"?`,description:`Esto elimina el .md del disco. El historial de versiones se conserva en la BD — usa un nuevo agente personalizado si quieres recuperar el cuerpo más adelante.`},errors:{loadDraftFailed:`Error al cargar el borrador: {{status}}`,loadFailed:`Error al cargar: {{status}}`,saveFailed:`Error al guardar: {{status}}`,deleteFailed:`Error al eliminar: {{status}}`,testFailed:`Error en la prueba: {{status}}`},toasts:{agentCreated:`Agente creado`,agentSaved:`Agente guardado`,agentDeleted:`Agente eliminado`,createFailed:`No se pudo crear el agente`,saveFailed:`No se pudo guardar el agente`,deleteFailed:`No se pudo eliminar el agente`},validation:{namePattern:`El nombre debe empezar por <code>custom-</code> y contener solo minúsculas, dígitos y guiones.`,missingFrontmatter:`Falta el frontmatter YAML (necesita un <code>---</code> de apertura en la primera línea).`},sampleTasks:{pick:`— elige una tarea de ejemplo —`,terraform:`Terraform: bucket S3 público`,sqlInjection:`Revisión de código: inyección SQL`,accessibility:`Frontend: accesibilidad`,schemaChange:`Datos: cambio de esquema`,slowQuery:`Rendimiento: consulta lenta`},testPane:{header:`Probar agente`,sampleTaskLabel:`Tarea de ejemplo`,placeholder:`Describe qué debe hacer el agente o elige un ejemplo arriba.`,run:`Ejecutar`,running:`Ejecutando…`,sandboxNote:`En sandbox; no se escriben archivos.`,tokens_one:`<mono>{{count}}</mono> token`,tokens_other:`<mono>{{count}}</mono> tokens`,tokensUnavailable:`Uso de tokens no disponible`,emptyHint:`Ejecuta una tarea de ejemplo contra el borrador actual. El resultado aparece aquí.`},versions:{header:`Historial de versiones`,empty:`No hay versiones anteriores registradas para este agente.`,restoreHint:`Haz clic en una versión para restaurar su cuerpo en el editor (aún tendrás que guardar).`}},t={eyebrow:`AI Edit`,headline:`Refina tu agente`,streamingHeadline:`Refinando tu agente…`,placeholderInitial:`Describe cómo refinar este agente…`,placeholderFollowUp:`Envía un refinamiento adicional…`,viewCurrentBody:`Ver el cuerpo actual del agente`,appliedAsVersion:`Aplicado como versión {{version}}.`,openInStudio:`Abrir el borrador en Studio para editarlo manualmente`,chips:{tightenTools:`Acota la lista de herramientas`,stricterPersonality:`Haz la personalidad más estricta`,workflowSection:`Añade una sección de protocolo de workflow`,sharpenDescription:`Acorta y afina la descripción`,matchDeveloperStyle:`Imita el estilo de sr-developer`}},n={validation:{missingBaseline:`Falta el agente base obligatorio: {{agent}}`,multipleDefaultRules:`El enrutado solo puede tener una regla por defecto (se encontraron {{found}})`,defaultRuleNotLast:`La regla de enrutado por defecto debe ser la última entrada`,unknownRoutingAgent:`El enrutado referencia un agente que no está en la cadena: {{agent}}`,invalidTags:`La regla de enrutado {{agent}} tiene tags no válidos: {{tags}} (usa kebab-case en minúsculas)`},validationSummary_one:`{{count}} problema de validación`,validationSummary_other:`{{count}} problemas de validación`,nameLabel:`Nombre`,descriptionLabel:`Descripción`,descriptionPlaceholder:`¿Para qué sirve este perfil?`,orchestrator:{heading:`Orquestador`,description:`Modelo de nivel superior para ambos comandos. batch-implement delega en implement por cada feature, así que cada rail que lanza hereda la cadena de agentes de este perfil.`},agentChain:{heading:`Cadena de agentes ({{n}})`,addTitle:`Añadir un agente del catálogo`,addDisabledTitle:`Todos los agentes del catálogo ya están en la cadena`,pickFromCatalog:`Elegir del catálogo ({{n}} disponibles)`,emptyCatalog:`No quedan agentes en el catálogo. Añade agentes personalizados desde la pestaña Catálogo de agentes.`,kind:{upstream:`upstream`,custom:`personalizado`}},routing:{heading:`Enrutado ({{n}})`,addDefault:`Añadir por defecto`,addRule:`Añadir regla`,needAgentsTitle:`Añade al menos un agente antes de crear reglas de enrutado`,explainer:`Gana la primera regla que coincida. Las reglas se pueden editar y eliminar, y la regla por defecto se mantiene en último lugar cuando existe. Si dejas el enrutado vacío, el pipeline recurre al primer agente de tipo developer de la cadena.`,untargetedTitle:`Agentes de la cadena sin regla`,untargetedDetail:`Ninguna regla de enrutado apunta a: <mono>{{agents}}</mono>. Añade una regla de tags o redirige la regla por defecto si quieres que se ejecuten.`},agentRow:{dragTitle:`Arrastra para reordenar`,dragHandleAria:`Asa de arrastre`,pinnedFirst:`primero`,pinnedFirstTitle:`Fijado en primera posición — el pipeline siempre empieza con sr-architect`,pinnedLast:`último`,pinnedLastTitle:`Fijado en última posición — la fase de merge siempre se ejecuta al final`,required:`obligatorio`,requiredRemoveTitle:`Agente base obligatorio — el pipeline depende de esta fila`},routingRow:{everythingElse:`todo lo demás`,defaultTargetAria:`Destino de enrutado por defecto (core, solo lectura)`,defaultTargetTitle:`Fallback del core — no editable`,targetAria:`Destino de enrutado para la regla {{ordinal}}`,editTitle:`Editar regla`,editAria:`Editar regla {{ordinal}}`,moveDown:`Bajar`,moveUp:`Subir`,coreDefaultBadge:`core · por defecto`,coreDefaultTitle:`Fallback del core — la regla de último recurso del pipeline, fijada a sr-developer`}},r={selectedCount:`{{selected}} / {{total}} agentes seleccionados`,selectAll:`Seleccionar todo`,coreBadge:`core`,categories:{architecture:`Arquitectura`,development:`Desarrollo`,review:`Revisión`,product:`Producto`,utilities:`Utilidades`},agents:{"sr-architect":{name:`Arquitecto`,description:`Diseño de arquitectura, specs de cambios, planificación de la implementación`},"sr-developer":{name:`Desarrollador`,description:`Implementación full-stack en todas las capas`},"sr-frontend-developer":{name:`Dev frontend`,description:`Implementación de frontend (React, Vue, Angular, etc.)`},"sr-backend-developer":{name:`Dev backend`,description:`Especialización en backend (APIs, bases de datos, servicios)`},"sr-reviewer":{name:`Revisor`,description:`Revisión general de código — el último control de calidad`},"sr-frontend-reviewer":{name:`Revisor frontend`,description:`Revisión de frontend (UI, accesibilidad, rendimiento)`},"sr-backend-reviewer":{name:`Revisor backend`,description:`Revisión de backend (APIs, seguridad, escalabilidad)`},"sr-security-reviewer":{name:`Revisor de seguridad`,description:`Análisis de seguridad — OWASP, vulnerabilidades, hardening`},"sr-performance-reviewer":{name:`Revisor de rendimiento`,description:`Análisis de rendimiento — profiling, cuellos de botella, optimización`},"sr-product-manager":{name:`Product Manager`,description:`Descubrimiento de producto, personas VPC, gestión del backlog`},"sr-product-analyst":{name:`Analista de producto`,description:`Análisis del backlog, detección de huecos en las specs, informes`},"sr-test-writer":{name:`Redactor de tests`,description:`Generación completa de tests (unitarios, integración, E2E)`},"sr-doc-sync":{name:`Sincronizador de docs`,description:`Sincronización de documentación — mantiene los docs alineados con el código`},"sr-merge-resolver":{name:`Resolutor de merges`,description:`Resolución de conflictos de merge teniendo en cuenta el contexto`}}},i={"security-reviewer":{label:`Revisor de seguridad`,blurb:`Encuentra bugs de autenticación, inyección y exposición de datos en un diff antes de publicarlo.`},"performance-profiler":{label:`Perfilador de rendimiento`,blurb:`Encuentra hot paths, consultas N+1, bucles sin límite y bundles hinchados.`},"data-engineer":{label:`Ingeniero de datos`,blurb:`Migraciones de esquema, pipelines ETL, transformaciones de datos.`},"ui-ux-polisher":{label:`Pulidor de UI / UX`,blurb:`Accesibilidad, espaciado, estados vacíos, gestión de errores.`},"api-designer":{label:`Diseñador de APIs`,blurb:`Versionado, paginación, formatos de error, retrocompatibilidad.`},"database-architect":{label:`Arquitecto de bases de datos`,blurb:`Índices, normalización frente a desnormalización, patrones de consulta.`},"devops-sre":{label:`DevOps / SRE`,blurb:`CI/CD, observabilidad, preparación ante incidentes, runbooks.`},"mobile-engineer":{label:`Ingeniero móvil`,blurb:`Patrones de iOS y Android, offline-first, cuidado con la batería.`},"ml-engineer":{label:`Ingeniero de ML`,blurb:`Pipelines, evaluación, reproducibilidad, monitorización de drift.`},"accessibility-auditor":{label:`Auditor de accesibilidad`,blurb:`Revisión WCAG 2.2: contraste, foco, ARIA, teclado.`},"qa-test-strategist":{label:`Estratega de tests QA`,blurb:`Planes de test: reparto unitarios / integración / E2E, huecos de cobertura.`},"load-tester":{label:`Tester de carga / estrés`,blurb:`Planificación de capacidad, escenarios k6 / Locust, caza de cuellos de botella.`},"integration-tester":{label:`Tester de integración`,blurb:`Contratos entre servicios, fixtures, reducción de tests flaky.`},"regression-hunter":{label:`Cazador de regresiones`,blurb:`Biseca, reproduce y escribe primero el test que falla.`},"data-analyst":{label:`Analista de datos`,blurb:`Convierte preguntas vagas en consultas + conclusiones legibles.`},"etl-reviewer":{label:`Revisor de pipelines ETL`,blurb:`Idempotencia, backfills, datos que llegan tarde.`},"dashboard-designer":{label:`Diseñador de dashboards`,blurb:`Dashboards de un vistazo, ejes honestos, una acción por gráfico.`},"iac-reviewer":{label:`Revisor de IaC / cloud`,blurb:`Terraform / CloudFormation: IAM, exposición pública, costes.`},"compliance-reviewer":{label:`Revisor de cumplimiento`,blurb:`Comprobaciones cercanas a RGPD / SOC2 / HIPAA sobre flujos de datos.`},"threat-modeler":{label:`Modelador de amenazas`,blurb:`STRIDE / LINDDUN sobre diagramas de arquitectura.`},"product-manager":{label:`Product Manager`,blurb:`Encuadre de problemas, PRDs, priorización.`},"ux-researcher":{label:`Investigador UX`,blurb:`Guiones de entrevista, planes de test de usabilidad, síntesis.`},"technical-writer":{label:`Redactor técnico`,blurb:`Docs que de verdad se leen — tutoriales, referencias, changelogs.`},"design-reviewer":{label:`Revisor de design system`,blurb:`Deriva de tokens, mal uso de componentes, consistencia entre flujos.`},"financial-analyst":{label:`Analista financiero`,blurb:`Unit economics, modelos de cohortes, análisis de escenarios.`},"pricing-strategist":{label:`Estratega de precios`,blurb:`Niveles, empaquetado, estudios de disposición a pagar.`},"market-researcher":{label:`Investigador de mercado`,blurb:`TAM/SAM/SOM, mapas competitivos, segmentos de clientes.`},"ops-optimizer":{label:`Optimizador de operaciones`,blurb:`Tiempos de ciclo, detección de cuellos de botella, candidatos a automatización.`},"seo-auditor":{label:`Auditor SEO`,blurb:`SEO técnico y de contenido: indexabilidad, arquitectura de la información, ajuste a la intención.`},"growth-hacker":{label:`Experimentador de growth`,blurb:`Diagnóstico de funnels, experimentos de mejora, bucles de activación.`},"social-strategist":{label:`Estratega de redes sociales`,blurb:`Contenido adaptado al canal, calendario editorial, consistencia de voz.`},"literature-reviewer":{label:`Revisor de literatura`,blurb:`Resúmenes de revisión sistemática, grafos de citas, conflictos.`},"experiment-designer":{label:`Diseñador de experimentos`,blurb:`Hipótesis, controles, tamaño muestral, prerregistro.`},"statistical-analyst":{label:`Analista estadístico`,blurb:`Elige el test correcto e informa tamaños de efecto, no solo p-valores.`},"scientific-writer":{label:`Redactor científico`,blurb:`Estructura IMRaD, límites honestos, abstracts legibles.`},"curriculum-designer":{label:`Diseñador curricular`,blurb:`Resultados de aprendizaje → actividades → evaluación.`},"assessment-author":{label:`Autor de evaluaciones`,blurb:`Ítems que miden comprensión, no memorización.`},"tutor-explainer":{label:`Tutor / explicador`,blurb:`Explicaciones sencillas al estilo Feynman con ejemplos resueltos.`},"clinical-guideline-reviewer":{label:`Revisor de guías clínicas`,blurb:`Contrasta la práctica con las últimas guías basadas en la evidencia.`},"medical-summarizer":{label:`Resumidor de literatura médica`,blurb:`Abstracts para clínicos: qué ha cambiado, calidad de la evidencia.`},"protocol-designer":{label:`Diseñador de protocolos`,blurb:`Protocolos clínicos: endpoints, criterios de inclusión, seguridad.`},"contract-reviewer":{label:`Revisor de contratos`,blurb:`Señala cláusulas de riesgo y explica qué significan en realidad.`},"privacy-counsel":{label:`Asesor de privacidad`,blurb:`RGPD / CCPA / LGPD aplicados a flujos concretos.`},"copy-editor":{label:`Editor de estilo`,blurb:`Ediciones línea a línea: voz, cadencia, recortar un 30 % sin perder significado.`},"brand-voice-guardian":{label:`Guardián de la voz de marca`,blurb:`Aplica las reglas de voz; caza frases fuera de marca.`},"creative-brainstormer":{label:`Brainstormer creativo`,blurb:`Diverge y luego converge; mata vacas sagradas con educación.`},"hiring-interviewer":{label:`Entrevistador de contratación`,blurb:`Entrevistas estructuradas, centradas en la señal, conscientes del sesgo.`},"strategic-planner":{label:`Planificador estratégico`,blurb:`Objetivos → apuestas → métricas; poda los proyectos capricho.`},"coach-1on1":{label:`Coach de 1:1`,blurb:`Ayuda a enmarcar el feedback, el crecimiento profesional y las conversaciones difíciles.`},"meeting-facilitator":{label:`Facilitador de reuniones`,blurb:`Agendas que producen decisiones, no actualizaciones.`}},a={studio:e,refine:t,profileEditor:n,agentSelector:r,templates:i};export{r as agentSelector,a as default,n as profileEditor,t as refine,e as studio,i as templates};
@@ -1 +0,0 @@
1
- var e={loadingAgent:`Caricamento agente…`,modeCreate:`Nuovo agente personalizzato`,modeEdit:`Modifica agente personalizzato`,create:`Crea`,unsaved:`● non salvato`,resumeAiEdit:`Riprendi AI Edit`,resumeAiEditTitle:`Riconsegna questa bozza all'overlay AI Edit`,loadingAiDraft:`caricamento bozza AI…`,testButton:`Test`,testButtonTitle:`Testa questo agente su un task di esempio`,historyButton:`Cronologia`,historyButtonTitle:`Cronologia versioni`,deleteConfirm:{title:`Eliminare l'agente "{{agentId}}"?`,description:`Rimuove il file .md dal disco. La cronologia versioni resta nel DB — usa un nuovo agente personalizzato se in seguito vuoi recuperare il corpo.`},errors:{loadDraftFailed:`Caricamento bozza non riuscito: {{status}}`,loadFailed:`Caricamento non riuscito: {{status}}`,saveFailed:`Salvataggio non riuscito: {{status}}`,deleteFailed:`Eliminazione non riuscita: {{status}}`,testFailed:`Test non riuscito: {{status}}`},toasts:{agentCreated:`Agente creato`,agentSaved:`Agente salvato`,agentDeleted:`Agente eliminato`,createFailed:`Creazione dell'agente non riuscita`,saveFailed:`Salvataggio dell'agente non riuscito`,deleteFailed:`Eliminazione dell'agente non riuscita`},validation:{namePattern:`Il nome deve iniziare con <code>custom-</code> e contenere solo lettere minuscole, cifre e trattini.`,missingFrontmatter:`Frontmatter YAML mancante (serve <code>---</code> di apertura sulla prima riga).`},sampleTasks:{pick:`— scegli un task di esempio —`,terraform:`Terraform: bucket S3 pubblico`,sqlInjection:`Code review: SQL injection`,accessibility:`Frontend: accessibilità`,schemaChange:`Dati: modifica dello schema`,slowQuery:`Performance: query lenta`},testPane:{header:`Testa l'agente`,sampleTaskLabel:`Task di esempio`,placeholder:`Descrivi cosa deve fare l'agente, oppure scegli un esempio qui sopra.`,run:`Esegui`,running:`In esecuzione…`,sandboxNote:`In sandbox; nessun file scritto.`,tokens_one:`<mono>{{count}}</mono> token`,tokens_other:`<mono>{{count}}</mono> token`,tokensUnavailable:`Utilizzo dei token non disponibile`,emptyHint:`Esegui un task di esempio sulla bozza corrente. L'output appare qui.`},versions:{header:`Cronologia versioni`,empty:`Nessuna versione precedente registrata per questo agente.`,restoreHint:`Clicca una versione per ripristinarne il corpo nell'editor (devi comunque salvare).`}},t={eyebrow:`AI Edit`,headline:`Rifinisci il tuo agente`,streamingHeadline:`Rifinitura dell'agente in corso…`,placeholderInitial:`Descrivi come rifinire questo agente…`,placeholderFollowUp:`Invia un'ulteriore rifinitura…`,viewCurrentBody:`Vedi il corpo attuale dell'agente`,appliedAsVersion:`Applicato come versione {{version}}.`,openInStudio:`Apri la bozza nello Studio per la modifica manuale`,chips:{tightenTools:`Restringi l'elenco dei tool`,stricterPersonality:`Rendi la personalità più rigorosa`,workflowSection:`Aggiungi una sezione di protocollo Workflow`,sharpenDescription:`Accorcia e affina la descrizione`,matchDeveloperStyle:`Allinea allo stile di sr-developer`}},n={validation:{missingBaseline:`Agente baseline obbligatorio mancante: {{agent}}`,multipleDefaultRules:`Il routing può avere al massimo una regola di default (trovate {{found}})`,defaultRuleNotLast:`La regola di routing di default deve essere l'ultima voce`,unknownRoutingAgent:`Il routing fa riferimento a un agente non presente nella catena: {{agent}}`,invalidTags:`La regola di routing {{agent}} ha tag non validi: {{tags}} (usa kebab-case minuscolo)`},validationSummary_one:`{{count}} problema di validazione`,validationSummary_other:`{{count}} problemi di validazione`,nameLabel:`Nome`,descriptionLabel:`Descrizione`,descriptionPlaceholder:`A cosa serve questo profilo?`,orchestrator:{heading:`Orchestratore`,description:`Modello di primo livello per entrambi i comandi. batch-implement delega a implement per ogni feature, quindi ogni rail che genera eredita la catena di agenti di questo profilo.`},agentChain:{heading:`Catena di agenti ({{n}})`,addTitle:`Aggiungi un agente dal catalogo`,addDisabledTitle:`Tutti gli agenti del catalogo sono già nella catena`,pickFromCatalog:`Scegli dal catalogo ({{n}} disponibili)`,emptyCatalog:`Nessun altro agente nel catalogo. Aggiungi agenti personalizzati dalla scheda Catalogo agenti.`,kind:{upstream:`upstream`,custom:`personalizzato`}},routing:{heading:`Routing ({{n}})`,addDefault:`Aggiungi default`,addRule:`Aggiungi regola`,needAgentsTitle:`Aggiungi almeno un agente prima di creare regole di routing`,explainer:`Vince la prima regola corrispondente. Le regole sono modificabili e rimovibili, e il catch-all di default resta ultimo quando presente. Se lasci il routing vuoto, la pipeline ricade sul primo agente di tipo developer nella catena.`,untargetedTitle:`Agenti senza target nella catena`,untargetedDetail:`Nessuna regola di routing punta a: <mono>{{agents}}</mono>. Aggiungi una regola con tag o cambia il target della regola di default se vuoi che vengano eseguiti.`},agentRow:{dragTitle:`Trascina per riordinare`,dragHandleAria:`Maniglia di trascinamento`,pinnedFirst:`primo`,pinnedFirstTitle:`Bloccato in prima posizione — la pipeline inizia sempre con sr-architect`,pinnedLast:`ultimo`,pinnedLastTitle:`Bloccato in ultima posizione — la fase di merge viene sempre eseguita per ultima`,required:`obbligatorio`,requiredRemoveTitle:`Agente baseline obbligatorio — la pipeline dipende da questa riga`},routingRow:{everythingElse:`tutto il resto`,defaultTargetAria:`Target di routing di default (core, sola lettura)`,defaultTargetTitle:`Fallback core — non modificabile`,targetAria:`Target di routing per la regola {{ordinal}}`,editTitle:`Modifica regola`,editAria:`Modifica regola {{ordinal}}`,moveDown:`Sposta giù`,moveUp:`Sposta su`,coreDefaultBadge:`core · default`,coreDefaultTitle:`Fallback core — la regola di ultima istanza della pipeline, fissata su sr-developer`}},r={selectedCount:`{{selected}} / {{total}} agenti selezionati`,selectAll:`Seleziona tutto`,coreBadge:`core`,categories:{architecture:`Architettura`,development:`Sviluppo`,review:`Review`,product:`Prodotto`,utilities:`Utilità`},agents:{"sr-architect":{name:`Architetto`,description:`Progettazione dell'architettura, spec di modifica, pianificazione dell'implementazione`},"sr-developer":{name:`Developer`,description:`Implementazione full-stack su tutti i layer`},"sr-frontend-developer":{name:`Dev Frontend`,description:`Implementazione frontend (React, Vue, Angular, ecc.)`},"sr-backend-developer":{name:`Dev Backend`,description:`Specializzazione backend (API, database, servizi)`},"sr-reviewer":{name:`Reviewer`,description:`Code review generale — l'ultimo quality gate`},"sr-frontend-reviewer":{name:`Reviewer Frontend`,description:`Review frontend (UI, accessibilità, performance)`},"sr-backend-reviewer":{name:`Reviewer Backend`,description:`Review backend (API, sicurezza, scalabilità)`},"sr-security-reviewer":{name:`Security Reviewer`,description:`Analisi di sicurezza — OWASP, vulnerabilità, hardening`},"sr-performance-reviewer":{name:`Perf Reviewer`,description:`Analisi delle performance — profiling, colli di bottiglia, ottimizzazione`},"sr-product-manager":{name:`Product Manager`,description:`Product discovery, persona VPC, gestione del backlog`},"sr-product-analyst":{name:`Product Analyst`,description:`Analisi del backlog, gap analysis delle spec, reportistica`},"sr-test-writer":{name:`Test Writer`,description:`Generazione completa di test (unit, integration, E2E)`},"sr-doc-sync":{name:`Doc Sync`,description:`Sincronizzazione della documentazione — mantiene i doc allineati al codice`},"sr-merge-resolver":{name:`Merge Resolver`,description:`Risoluzione dei conflitti di merge con consapevolezza del contesto`}}},i={"security-reviewer":{label:`Security Reviewer`,blurb:`Trova bug di auth, injection ed esposizione di dati in un diff prima della release.`},"performance-profiler":{label:`Performance Profiler`,blurb:`Trova hot path, query N+1, loop senza limiti, bundle gonfiati.`},"data-engineer":{label:`Data Engineer`,blurb:`Migrazioni di schema, pipeline ETL, trasformazioni di dati.`},"ui-ux-polisher":{label:`Rifinitore UI / UX`,blurb:`Accessibilità, spaziature, stati vuoti, gestione degli errori.`},"api-designer":{label:`API Designer`,blurb:`Versioning, paginazione, formati di errore, retrocompatibilità.`},"database-architect":{label:`Architetto Database`,blurb:`Indici, normalizzazione vs denormalizzazione, forma delle query.`},"devops-sre":{label:`DevOps / SRE`,blurb:`CI/CD, observability, preparazione agli incident, runbook.`},"mobile-engineer":{label:`Mobile Engineer`,blurb:`Pattern iOS + Android, offline-first, attenzione alla batteria.`},"ml-engineer":{label:`ML Engineer`,blurb:`Pipeline, eval, riproducibilità, monitoraggio del drift.`},"accessibility-auditor":{label:`Auditor Accessibilità`,blurb:`Review WCAG 2.2: contrasto, focus, ARIA, tastiera.`},"qa-test-strategist":{label:`Stratega Test QA`,blurb:`Piani di test: suddivisione unit / integration / E2E, lacune di copertura.`},"load-tester":{label:`Load / Stress Tester`,blurb:`Capacity planning, scenari k6 / Locust, caccia ai colli di bottiglia.`},"integration-tester":{label:`Tester di Integrazione`,blurb:`Contratti tra servizi, fixture, riduzione dei test flaky.`},"regression-hunter":{label:`Cacciatore di Regressioni`,blurb:`Biseca, riproduce, scrive prima il test che fallisce.`},"data-analyst":{label:`Data Analyst`,blurb:`Trasforma domande vaghe in query + risultati leggibili.`},"etl-reviewer":{label:`Reviewer Pipeline ETL`,blurb:`Idempotenza, backfill, dati che arrivano in ritardo.`},"dashboard-designer":{label:`Dashboard Designer`,blurb:`Dashboard a colpo d'occhio, assi onesti, un'azione per grafico.`},"iac-reviewer":{label:`Reviewer IaC / Cloud`,blurb:`Terraform / CloudFormation: IAM, esposizione pubblica, costi.`},"compliance-reviewer":{label:`Compliance Reviewer`,blurb:`Controlli in ambito GDPR / SOC2 / HIPAA sui flussi di dati.`},"threat-modeler":{label:`Threat Modeler`,blurb:`STRIDE / LINDDUN sui diagrammi di architettura.`},"product-manager":{label:`Product Manager`,blurb:`Inquadramento del problema, PRD, prioritizzazione.`},"ux-researcher":{label:`UX Researcher`,blurb:`Script per interviste, piani di test di usabilità, sintesi.`},"technical-writer":{label:`Technical Writer`,blurb:`Doc che vengono letti davvero — tutorial, riferimenti, changelog.`},"design-reviewer":{label:`Reviewer Design System`,blurb:`Drift dei token, uso improprio dei componenti, coerenza tra i flussi.`},"financial-analyst":{label:`Analista Finanziario`,blurb:`Unit economics, modelli di coorte, analisi di scenario.`},"pricing-strategist":{label:`Stratega di Pricing`,blurb:`Tier, packaging, studi sulla disponibilità a pagare.`},"market-researcher":{label:`Ricercatore di Mercato`,blurb:`TAM/SAM/SOM, mappe competitive, segmenti di clientela.`},"ops-optimizer":{label:`Ottimizzatore di Operations`,blurb:`Tempi di ciclo, individuazione dei colli di bottiglia, candidati all'automazione.`},"seo-auditor":{label:`SEO Auditor`,blurb:`SEO tecnica + di contenuto: indicizzabilità, IA, match con l'intento.`},"growth-hacker":{label:`Sperimentatore di Growth`,blurb:`Diagnosi del funnel, esperimenti di lift, loop di attivazione.`},"social-strategist":{label:`Stratega Social Media`,blurb:`Contenuti adatti al canale, calendario editoriale, coerenza di voce.`},"literature-reviewer":{label:`Revisore di Letteratura`,blurb:`Sintesi di revisioni sistematiche, grafi di citazioni, conflitti.`},"experiment-designer":{label:`Progettista di Esperimenti`,blurb:`Ipotesi, controlli, dimensione del campione, pre-registrazione.`},"statistical-analyst":{label:`Analista Statistico`,blurb:`Sceglie il test giusto, riporta gli effect size, non solo i p-value.`},"scientific-writer":{label:`Redattore Scientifico`,blurb:`Struttura IMRaD, limiti onesti, abstract leggibili.`},"curriculum-designer":{label:`Progettista di Curriculum`,blurb:`Obiettivi di apprendimento → attività → valutazione.`},"assessment-author":{label:`Autore di Valutazioni`,blurb:`Item che misurano la comprensione, non la memoria.`},"tutor-explainer":{label:`Tutor / Divulgatore`,blurb:`Spiegazioni semplici in stile Feynman con esempi svolti.`},"clinical-guideline-reviewer":{label:`Revisore di Linee Guida Cliniche`,blurb:`Confronta la pratica con le ultime linee guida evidence-based.`},"medical-summarizer":{label:`Sintetizzatore di Letteratura Medica`,blurb:`Abstract per i clinici: cosa è cambiato, qualità dell'evidenza.`},"protocol-designer":{label:`Progettista di Protocolli`,blurb:`Protocolli clinici: endpoint, criteri di inclusione, sicurezza.`},"contract-reviewer":{label:`Revisore di Contratti`,blurb:`Segnala le clausole rischiose; spiega cosa significano davvero.`},"privacy-counsel":{label:`Consulente Privacy`,blurb:`GDPR / CCPA / LGPD applicati a flussi concreti.`},"copy-editor":{label:`Copy Editor`,blurb:`Editing riga per riga: voce, ritmo, taglia il 30% senza perdere significato.`},"brand-voice-guardian":{label:`Guardiano della Brand Voice`,blurb:`Fa rispettare le regole di voce; intercetta le frasi off-brand.`},"creative-brainstormer":{label:`Brainstormer Creativo`,blurb:`Prima divergente, poi convergente; abbatte i tabù con garbo.`},"hiring-interviewer":{label:`Intervistatore di Selezione`,blurb:`Colloqui strutturati, focalizzati sul segnale, attenti ai bias.`},"strategic-planner":{label:`Pianificatore Strategico`,blurb:`Obiettivi → scommesse → metriche; sfoltisce i pet project.`},"coach-1on1":{label:`Coach 1:1`,blurb:`Aiuta a impostare feedback, crescita professionale, conversazioni difficili.`},"meeting-facilitator":{label:`Facilitatore di Riunioni`,blurb:`Agende che producono decisioni, non aggiornamenti.`}},a={studio:e,refine:t,profileEditor:n,agentSelector:r,templates:i};export{r as agentSelector,a as default,n as profileEditor,t as refine,e as studio,i as templates};
@@ -1 +0,0 @@
1
- var e={loadingAgent:`Chargement de l'agent…`,modeCreate:`Nouvel agent personnalisé`,modeEdit:`Modifier l'agent personnalisé`,create:`Créer`,unsaved:`● non enregistré`,resumeAiEdit:`Reprendre l'Édition IA`,resumeAiEditTitle:`Renvoyer ce brouillon vers l'overlay Édition IA`,loadingAiDraft:`chargement du brouillon IA…`,testButton:`Tester`,testButtonTitle:`Tester cet agent sur une tâche d'exemple`,historyButton:`Historique`,historyButtonTitle:`Historique des versions`,deleteConfirm:{title:`Supprimer l'agent « {{agentId}} » ?`,description:`Supprime le fichier .md du disque. L'historique des versions reste en base — créez un nouvel agent personnalisé si vous voulez récupérer le corps plus tard.`},errors:{loadDraftFailed:`Échec du chargement du brouillon : {{status}}`,loadFailed:`Échec du chargement : {{status}}`,saveFailed:`Échec de l'enregistrement : {{status}}`,deleteFailed:`Échec de la suppression : {{status}}`,testFailed:`Échec du test : {{status}}`},toasts:{agentCreated:`Agent créé`,agentSaved:`Agent enregistré`,agentDeleted:`Agent supprimé`,createFailed:`Échec de la création de l'agent`,saveFailed:`Échec de l'enregistrement de l'agent`,deleteFailed:`Échec de la suppression de l'agent`},validation:{namePattern:`Le nom doit commencer par <code>custom-</code> et ne contenir que des lettres minuscules, des chiffres et des tirets.`,missingFrontmatter:`Frontmatter YAML manquant (il faut un <code>---</code> d'ouverture sur la première ligne).`},sampleTasks:{pick:`— choisir une tâche d'exemple —`,terraform:`Terraform : bucket S3 public`,sqlInjection:`Revue de code : injection SQL`,accessibility:`Frontend : accessibilité`,schemaChange:`Données : changement de schéma`,slowQuery:`Performance : requête lente`},testPane:{header:`Tester l'agent`,sampleTaskLabel:`Tâche d'exemple`,placeholder:`Décrivez ce que l'agent doit faire, ou choisissez un exemple ci-dessus.`,run:`Exécuter`,running:`Exécution…`,sandboxNote:`Exécution en sandbox ; aucun fichier écrit.`,tokens_one:`<mono>{{count}}</mono> token`,tokens_other:`<mono>{{count}}</mono> tokens`,tokensUnavailable:`Utilisation des tokens indisponible`,emptyHint:`Exécutez une tâche d'exemple sur le brouillon actuel. La sortie s'affiche ici.`},versions:{header:`Historique des versions`,empty:`Aucune version antérieure enregistrée pour cet agent.`,restoreHint:`Cliquez sur une version pour restaurer son corps dans l'éditeur (il faudra ensuite Enregistrer).`}},t={eyebrow:`Édition IA`,headline:`Affinez votre agent`,streamingHeadline:`Affinage de votre agent…`,placeholderInitial:`Décrivez comment affiner cet agent…`,placeholderFollowUp:`Envoyez un affinage complémentaire…`,viewCurrentBody:`Voir le corps actuel de l'agent`,appliedAsVersion:`Appliqué comme version {{version}}.`,openInStudio:`Ouvrir le brouillon dans le Studio pour l'éditer manuellement`,chips:{tightenTools:`Resserrer la liste d'outils`,stricterPersonality:`Rendre la personnalité plus stricte`,workflowSection:`Ajouter une section de protocole Workflow`,sharpenDescription:`Raccourcir et affûter la description`,matchDeveloperStyle:`S'aligner sur le style de sr-developer`}},n={validation:{missingBaseline:`Agent de base requis manquant : {{agent}}`,multipleDefaultRules:`Le routage admet au plus une règle par défaut ({{found}} trouvées)`,defaultRuleNotLast:`La règle de routage par défaut doit être la dernière entrée`,unknownRoutingAgent:`Le routage référence un agent absent de la chaîne : {{agent}}`,invalidTags:`La règle de routage {{agent}} a des tags invalides : {{tags}} (utilisez du kebab-case en minuscules)`},validationSummary_one:`{{count}} problème de validation`,validationSummary_other:`{{count}} problèmes de validation`,nameLabel:`Nom`,descriptionLabel:`Description`,descriptionPlaceholder:`À quoi sert ce profil ?`,orchestrator:{heading:`Orchestrateur`,description:`Modèle de premier niveau pour les deux commandes. batch-implement délègue à implement pour chaque fonctionnalité, donc chaque rail qu'il lance hérite de la chaîne d'agents de ce profil.`},agentChain:{heading:`Chaîne d'agents ({{n}})`,addTitle:`Ajouter un agent depuis le catalogue`,addDisabledTitle:`Tous les agents du catalogue sont déjà dans la chaîne`,pickFromCatalog:`Choisir dans le catalogue ({{n}} disponibles)`,emptyCatalog:`Plus aucun agent dans le catalogue. Ajoutez des agents personnalisés depuis l'onglet Catalogue d'agents.`,kind:{upstream:`upstream`,custom:`personnalisé`}},routing:{heading:`Routage ({{n}})`,addDefault:`Ajouter la règle par défaut`,addRule:`Ajouter une règle`,needAgentsTitle:`Ajoutez au moins un agent avant de créer des règles de routage`,explainer:`La première règle correspondante l'emporte. Les règles sont modifiables et supprimables, et la règle fourre-tout par défaut reste en dernier quand elle existe. Si le routage est vide, le pipeline se rabat sur le premier agent de type développeur de la chaîne.`,untargetedTitle:`Agents non ciblés dans la chaîne`,untargetedDetail:`Aucune règle de routage ne pointe vers : <mono>{{agents}}</mono>. Ajoutez une règle de tag ou reciblez la règle par défaut si vous voulez qu'ils s'exécutent.`},agentRow:{dragTitle:`Glisser pour réordonner`,dragHandleAria:`Poignée de glissement`,pinnedFirst:`premier`,pinnedFirstTitle:`Épinglé en première position — le pipeline commence toujours par sr-architect`,pinnedLast:`dernier`,pinnedLastTitle:`Épinglé en dernière position — la phase de merge s'exécute toujours en dernier`,required:`requis`,requiredRemoveTitle:`Agent de base requis — le pipeline dépend de cette ligne`},routingRow:{everythingElse:`tout le reste`,defaultTargetAria:`Cible de routage par défaut (core, lecture seule)`,defaultTargetTitle:`Repli core — non modifiable`,targetAria:`Cible de routage pour la règle {{ordinal}}`,editTitle:`Modifier la règle`,editAria:`Modifier la règle {{ordinal}}`,moveDown:`Descendre`,moveUp:`Monter`,coreDefaultBadge:`core · défaut`,coreDefaultTitle:`Repli core — la règle de dernier recours du pipeline, épinglée sur sr-developer`}},r={selectedCount:`{{selected}} / {{total}} agents sélectionnés`,selectAll:`Tout sélectionner`,coreBadge:`core`,categories:{architecture:`Architecture`,development:`Développement`,review:`Revue`,product:`Produit`,utilities:`Utilitaires`},agents:{"sr-architect":{name:`Architecte`,description:`Conception d'architecture, specs de changement, planification d'implémentation`},"sr-developer":{name:`Développeur`,description:`Implémentation full-stack sur toutes les couches`},"sr-frontend-developer":{name:`Dév Frontend`,description:`Implémentation frontend (React, Vue, Angular, etc.)`},"sr-backend-developer":{name:`Dév Backend`,description:`Spécialisation backend (API, bases de données, services)`},"sr-reviewer":{name:`Relecteur`,description:`Revue de code générale — l'ultime contrôle qualité`},"sr-frontend-reviewer":{name:`Relecteur Frontend`,description:`Revue frontend (UI, accessibilité, performance)`},"sr-backend-reviewer":{name:`Relecteur Backend`,description:`Revue backend (API, sécurité, scalabilité)`},"sr-security-reviewer":{name:`Relecteur Sécurité`,description:`Analyse de sécurité — OWASP, vulnérabilités, durcissement`},"sr-performance-reviewer":{name:`Relecteur Perf`,description:`Analyse de performance — profiling, goulots d'étranglement, optimisation`},"sr-product-manager":{name:`Product Manager`,description:`Découverte produit, personas VPC, gestion du backlog`},"sr-product-analyst":{name:`Analyste Produit`,description:`Analyse du backlog, analyse des écarts de spec, reporting`},"sr-test-writer":{name:`Rédacteur de tests`,description:`Génération complète de tests (unitaires, intégration, E2E)`},"sr-doc-sync":{name:`Doc Sync`,description:`Synchronisation de la documentation — garde les docs alignées avec le code`},"sr-merge-resolver":{name:`Résolveur de merge`,description:`Résolution des conflits de merge avec prise en compte du contexte`}}},i={"security-reviewer":{label:`Relecteur Sécurité`,blurb:`Détecte les bugs d'authentification, d'injection et d'exposition de données dans un diff avant livraison.`},"performance-profiler":{label:`Profileur de performance`,blurb:`Repère les hot paths, les requêtes N+1, les boucles non bornées, le gonflement du bundle.`},"data-engineer":{label:`Data Engineer`,blurb:`Migrations de schéma, pipelines ETL, transformations de données.`},"ui-ux-polisher":{label:`Polisseur UI / UX`,blurb:`Accessibilité, espacement, états vides, gestion des erreurs.`},"api-designer":{label:`Concepteur d'API`,blurb:`Versionnage, pagination, formats d'erreur, rétrocompatibilité.`},"database-architect":{label:`Architecte base de données`,blurb:`Index, normalisation vs dénormalisation, formes de requêtes.`},"devops-sre":{label:`DevOps / SRE`,blurb:`CI/CD, observabilité, préparation aux incidents, runbooks.`},"mobile-engineer":{label:`Ingénieur Mobile`,blurb:`Patterns iOS + Android, offline-first, sobriété batterie.`},"ml-engineer":{label:`Ingénieur ML`,blurb:`Pipelines, éval, reproductibilité, surveillance du drift.`},"accessibility-auditor":{label:`Auditeur Accessibilité`,blurb:`Revue WCAG 2.2 : contraste, focus, ARIA, clavier.`},"qa-test-strategist":{label:`Stratège de tests QA`,blurb:`Plans de test : répartition unitaires / intégration / E2E, lacunes de couverture.`},"load-tester":{label:`Testeur de charge / stress`,blurb:`Planification de capacité, scénarios k6 / Locust, chasse aux goulots d'étranglement.`},"integration-tester":{label:`Testeur d'intégration`,blurb:`Contrats inter-services, fixtures, réduction des tests flaky.`},"regression-hunter":{label:`Chasseur de régressions`,blurb:`Bisecte, reproduit, écrit d'abord le test qui échoue.`},"data-analyst":{label:`Data Analyst`,blurb:`Transforme des questions vagues en requêtes + conclusions lisibles.`},"etl-reviewer":{label:`Relecteur de pipeline ETL`,blurb:`Idempotence, backfills, données tardives.`},"dashboard-designer":{label:`Concepteur de dashboards`,blurb:`Dashboards lisibles d'un coup d'œil, axes honnêtes, une action par graphique.`},"iac-reviewer":{label:`Relecteur IaC / Cloud`,blurb:`Terraform / CloudFormation : IAM, exposition publique, coûts.`},"compliance-reviewer":{label:`Relecteur Conformité`,blurb:`Contrôles type RGPD / SOC2 / HIPAA sur les flux de données.`},"threat-modeler":{label:`Modélisateur de menaces`,blurb:`STRIDE / LINDDUN sur les diagrammes d'architecture.`},"product-manager":{label:`Product Manager`,blurb:`Cadrage du problème, PRD, priorisation.`},"ux-researcher":{label:`Chercheur UX`,blurb:`Scripts d'entretien, plans de tests d'utilisabilité, synthèse.`},"technical-writer":{label:`Rédacteur technique`,blurb:`Des docs qu'on lit vraiment — tutoriels, références, changelogs.`},"design-reviewer":{label:`Relecteur Design System`,blurb:`Dérive des tokens, mauvais usage des composants, cohérence entre les flux.`},"financial-analyst":{label:`Analyste financier`,blurb:`Unit economics, modèles de cohortes, analyse de scénarios.`},"pricing-strategist":{label:`Stratège Pricing`,blurb:`Paliers, packaging, études de disposition à payer.`},"market-researcher":{label:`Chargé d'études de marché`,blurb:`TAM/SAM/SOM, cartographies concurrentielles, segments clients.`},"ops-optimizer":{label:`Optimiseur des opérations`,blurb:`Temps de cycle, détection des goulots, candidats à l'automatisation.`},"seo-auditor":{label:`Auditeur SEO`,blurb:`SEO technique + contenu : indexabilité, architecture de l'information, adéquation à l'intention.`},"growth-hacker":{label:`Expérimentateur Growth`,blurb:`Diagnostic de funnel, expériences d'uplift, boucles d'activation.`},"social-strategist":{label:`Stratège réseaux sociaux`,blurb:`Contenu adapté au canal, calendrier éditorial, cohérence de la voix.`},"literature-reviewer":{label:`Relecteur de littérature`,blurb:`Synthèses de revues systématiques, graphes de citations, conflits.`},"experiment-designer":{label:`Concepteur d'expériences`,blurb:`Hypothèses, contrôles, taille d'échantillon, préenregistrement.`},"statistical-analyst":{label:`Analyste statistique`,blurb:`Choisit le bon test, rapporte les tailles d'effet, pas seulement les p-values.`},"scientific-writer":{label:`Rédacteur scientifique`,blurb:`Structure IMRaD, limites honnêtes, abstracts lisibles.`},"curriculum-designer":{label:`Concepteur de cursus`,blurb:`Objectifs d'apprentissage → activités → évaluation.`},"assessment-author":{label:`Auteur d'évaluations`,blurb:`Des questions qui mesurent la compréhension, pas la mémorisation.`},"tutor-explainer":{label:`Tuteur / Vulgarisateur`,blurb:`Explications simples façon Feynman, avec exemples corrigés.`},"clinical-guideline-reviewer":{label:`Relecteur de recommandations cliniques`,blurb:`Confronte la pratique aux dernières recommandations fondées sur les preuves.`},"medical-summarizer":{label:`Synthétiseur de littérature médicale`,blurb:`Des abstracts pour les cliniciens : ce qui change, qualité des preuves.`},"protocol-designer":{label:`Concepteur de protocoles`,blurb:`Protocoles cliniques : critères de jugement, critères d'inclusion, sécurité.`},"contract-reviewer":{label:`Relecteur de contrats`,blurb:`Signale les clauses à risque ; explique ce qu'elles veulent vraiment dire.`},"privacy-counsel":{label:`Conseil en confidentialité`,blurb:`RGPD / CCPA / LGPD appliqués à des flux concrets.`},"copy-editor":{label:`Réviseur éditorial`,blurb:`Corrections fines : voix, rythme, couper 30 % sans perdre le sens.`},"brand-voice-guardian":{label:`Gardien de la voix de marque`,blurb:`Fait respecter les règles de ton ; repère les formulations hors marque.`},"creative-brainstormer":{label:`Brainstormer créatif`,blurb:`Divergent puis convergent ; tue les vaches sacrées avec tact.`},"hiring-interviewer":{label:`Intervieweur de recrutement`,blurb:`Entretiens structurés, axés sur le signal, attentifs aux biais.`},"strategic-planner":{label:`Planificateur stratégique`,blurb:`Objectifs → paris → métriques ; élague les projets fétiches.`},"coach-1on1":{label:`Coach 1:1`,blurb:`Aide à cadrer le feedback, l'évolution de carrière, les conversations difficiles.`},"meeting-facilitator":{label:`Facilitateur de réunions`,blurb:`Des ordres du jour qui produisent des décisions, pas des points d'étape.`}},a={studio:e,refine:t,profileEditor:n,agentSelector:r,templates:i};export{r as agentSelector,a as default,n as profileEditor,t as refine,e as studio,i as templates};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-CNC7AqOf.js";var t=e({agentSelector:()=>a,default:()=>s,profileEditor:()=>i,refine:()=>r,studio:()=>n,templates:()=>o}),n={loadingAgent:`Loading agent…`,modeCreate:`New custom agent`,modeEdit:`Edit custom agent`,create:`Create`,unsaved:`● unsaved`,resumeAiEdit:`Resume AI Edit`,resumeAiEditTitle:`Hand this draft back to the AI Edit overlay`,loadingAiDraft:`loading AI draft…`,testButton:`Test`,testButtonTitle:`Test this agent against a sample task`,historyButton:`History`,historyButtonTitle:`Version history`,deleteConfirm:{title:`Delete agent "{{agentId}}"?`,description:`This removes the .md from disk. Version history stays in the DB — use a fresh custom agent if you want to recover the body later.`},errors:{loadDraftFailed:`Load draft failed: {{status}}`,loadFailed:`Load failed: {{status}}`,saveFailed:`Save failed: {{status}}`,deleteFailed:`Delete failed: {{status}}`,testFailed:`Test failed: {{status}}`},toasts:{agentCreated:`Agent created`,agentSaved:`Agent saved`,agentDeleted:`Agent deleted`,createFailed:`Failed to create agent`,saveFailed:`Failed to save agent`,deleteFailed:`Failed to delete agent`},validation:{namePattern:`Name must start with <code>custom-</code> and contain only lowercase letters, digits, and hyphens.`,missingFrontmatter:`Missing YAML frontmatter (needs opening <code>---</code> on the first line).`},sampleTasks:{pick:`— pick a sample task —`,terraform:`Terraform: public S3 bucket`,sqlInjection:`Code review: SQL injection`,accessibility:`Frontend: accessibility`,schemaChange:`Data: schema change`,slowQuery:`Performance: slow query`},testPane:{header:`Test agent`,sampleTaskLabel:`Sample task`,placeholder:`Describe what the agent should do, or pick a sample above.`,run:`Run`,running:`Running…`,sandboxNote:`Sandboxed; no files written.`,tokens_one:`<mono>{{count}}</mono> token`,tokens_other:`<mono>{{count}}</mono> tokens`,tokensUnavailable:`Token usage unavailable`,emptyHint:`Run a sample task against the current draft. Output appears here.`},versions:{header:`Version history`,empty:`No prior versions recorded for this agent.`,restoreHint:`Click a version to restore its body into the editor (you still need to Save).`}},r={eyebrow:`AI Edit`,headline:`Refine your agent`,streamingHeadline:`Refining your agent…`,placeholderInitial:`Describe how to refine this agent…`,placeholderFollowUp:`Send a follow-up refinement…`,viewCurrentBody:`View current agent body`,appliedAsVersion:`Applied as version {{version}}.`,openInStudio:`Open draft in Studio for manual editing`,chips:{tightenTools:`Tighten the tool list`,stricterPersonality:`Make the personality stricter`,workflowSection:`Add a Workflow protocol section`,sharpenDescription:`Shorten and sharpen the description`,matchDeveloperStyle:`Match the sr-developer style`}},i={validation:{missingBaseline:`Missing required baseline agent: {{agent}}`,multipleDefaultRules:`Routing may have at most one default rule (found {{found}})`,defaultRuleNotLast:`The default routing rule must be the last entry`,unknownRoutingAgent:`Routing references agent not in the chain: {{agent}}`,invalidTags:`Routing rule {{agent}} has invalid tags: {{tags}} (use lowercase kebab-case)`},validationSummary_one:`{{count}} validation issue`,validationSummary_other:`{{count}} validation issues`,nameLabel:`Name`,descriptionLabel:`Description`,descriptionPlaceholder:`What is this profile for?`,orchestrator:{heading:`Orchestrator`,description:`Top-level model for both commands. batch-implement delegates to implement per feature, so every rail it spawns inherits this profile's agent chain.`},agentChain:{heading:`Agent chain ({{n}})`,addTitle:`Add an agent from the catalog`,addDisabledTitle:`All catalog agents are already in the chain`,pickFromCatalog:`Pick from catalog ({{n}} available)`,emptyCatalog:`No more agents in the catalog. Add custom agents from the Agents Catalog tab.`,kind:{upstream:`upstream`,custom:`custom`}},routing:{heading:`Routing ({{n}})`,addDefault:`Add default`,addRule:`Add rule`,needAgentsTitle:`Add at least one agent before creating routing rules`,explainer:`First matching rule wins. Rules are editable and removable, and the default catch-all stays last when present. If you leave routing empty, the pipeline falls back to the first developer-shaped agent in the chain.`,untargetedTitle:`Untargeted agents in the chain`,untargetedDetail:`No routing rule points to: <mono>{{agents}}</mono>. Add a tag rule or retarget the default rule if you want them to run.`},agentRow:{dragTitle:`Drag to reorder`,dragHandleAria:`Drag handle`,pinnedFirst:`first`,pinnedFirstTitle:`Pinned to first position — pipeline always starts with sr-architect`,pinnedLast:`last`,pinnedLastTitle:`Pinned to last position — merge phase always runs last`,required:`required`,requiredRemoveTitle:`Required baseline agent — the pipeline depends on this row`},routingRow:{everythingElse:`everything else`,defaultTargetAria:`Default routing target (core, read-only)`,defaultTargetTitle:`Core fallback — not editable`,targetAria:`Routing target for rule {{ordinal}}`,editTitle:`Edit rule`,editAria:`Edit rule {{ordinal}}`,moveDown:`Move down`,moveUp:`Move up`,coreDefaultBadge:`core · default`,coreDefaultTitle:`Core fallback — the pipeline's last-resort rule, pinned to sr-developer`}},a={selectedCount:`{{selected}} / {{total}} agents selected`,selectAll:`Select all`,coreBadge:`core`,categories:{architecture:`Architecture`,development:`Development`,review:`Review`,product:`Product`,utilities:`Utilities`},agents:{"sr-architect":{name:`Architect`,description:`Architecture design, change specs, implementation planning`},"sr-developer":{name:`Developer`,description:`Full-stack implementation across all layers`},"sr-frontend-developer":{name:`Frontend Dev`,description:`Frontend implementation (React, Vue, Angular, etc.)`},"sr-backend-developer":{name:`Backend Dev`,description:`Backend specialization (APIs, databases, services)`},"sr-reviewer":{name:`Reviewer`,description:`General code review — the final quality gate`},"sr-frontend-reviewer":{name:`Frontend Reviewer`,description:`Frontend review (UI, accessibility, performance)`},"sr-backend-reviewer":{name:`Backend Reviewer`,description:`Backend review (APIs, security, scalability)`},"sr-security-reviewer":{name:`Security Reviewer`,description:`Security analysis — OWASP, vulnerabilities, hardening`},"sr-performance-reviewer":{name:`Perf Reviewer`,description:`Performance analysis — profiling, bottlenecks, optimization`},"sr-product-manager":{name:`Product Manager`,description:`Product discovery, VPC personas, backlog management`},"sr-product-analyst":{name:`Product Analyst`,description:`Backlog analysis, spec gap analysis, reporting`},"sr-test-writer":{name:`Test Writer`,description:`Comprehensive test generation (unit, integration, E2E)`},"sr-doc-sync":{name:`Doc Sync`,description:`Documentation sync — keeps docs aligned with code`},"sr-merge-resolver":{name:`Merge Resolver`,description:`Merge conflict resolution with context awareness`}}},o={"security-reviewer":{label:`Security Reviewer`,blurb:`Finds auth, injection, and data-exposure bugs in a diff before it ships.`},"performance-profiler":{label:`Performance Profiler`,blurb:`Finds hot paths, N+1 queries, unbounded loops, bundle bloat.`},"data-engineer":{label:`Data Engineer`,blurb:`Schema migrations, ETL pipelines, data transformations.`},"ui-ux-polisher":{label:`UI / UX Polisher`,blurb:`Accessibility, spacing, empty states, error handling.`},"api-designer":{label:`API Designer`,blurb:`Versioning, pagination, error shapes, backward compatibility.`},"database-architect":{label:`Database Architect`,blurb:`Indexes, normalization vs denormalization, query shapes.`},"devops-sre":{label:`DevOps / SRE`,blurb:`CI/CD, observability, incident-readiness, runbooks.`},"mobile-engineer":{label:`Mobile Engineer`,blurb:`iOS + Android patterns, offline-first, battery-aware.`},"ml-engineer":{label:`ML Engineer`,blurb:`Pipelines, eval, reproducibility, drift monitoring.`},"accessibility-auditor":{label:`Accessibility Auditor`,blurb:`WCAG 2.2 review: contrast, focus, ARIA, keyboard.`},"qa-test-strategist":{label:`QA Test Strategist`,blurb:`Test plans: unit / integration / E2E split, coverage gaps.`},"load-tester":{label:`Load / Stress Tester`,blurb:`Capacity planning, k6 / Locust scenarios, bottleneck hunting.`},"integration-tester":{label:`Integration Tester`,blurb:`Cross-service contracts, fixtures, flake reduction.`},"regression-hunter":{label:`Regression Hunter`,blurb:`Bisects, repros, writes the failing test first.`},"data-analyst":{label:`Data Analyst`,blurb:`Turns vague questions into queries + readable findings.`},"etl-reviewer":{label:`ETL Pipeline Reviewer`,blurb:`Idempotency, backfills, late-arriving data.`},"dashboard-designer":{label:`Dashboard Designer`,blurb:`One-glance dashboards, honest axes, action-per-chart.`},"iac-reviewer":{label:`IaC / Cloud Reviewer`,blurb:`Terraform / CloudFormation: IAM, public exposure, costs.`},"compliance-reviewer":{label:`Compliance Reviewer`,blurb:`GDPR / SOC2 / HIPAA-adjacent checks on data flows.`},"threat-modeler":{label:`Threat Modeler`,blurb:`STRIDE / LINDDUN over architecture diagrams.`},"product-manager":{label:`Product Manager`,blurb:`Problem framing, PRDs, prioritization.`},"ux-researcher":{label:`UX Researcher`,blurb:`Interview scripts, usability test plans, synthesis.`},"technical-writer":{label:`Technical Writer`,blurb:`Docs that are actually read — tutorials, references, changelogs.`},"design-reviewer":{label:`Design System Reviewer`,blurb:`Token drift, component misuse, consistency across flows.`},"financial-analyst":{label:`Financial Analyst`,blurb:`Unit economics, cohort models, scenario analysis.`},"pricing-strategist":{label:`Pricing Strategist`,blurb:`Tiering, packaging, willingness-to-pay studies.`},"market-researcher":{label:`Market Researcher`,blurb:`TAM/SAM/SOM, competitive maps, customer segments.`},"ops-optimizer":{label:`Operations Optimizer`,blurb:`Cycle-time, bottleneck-finding, automation candidates.`},"seo-auditor":{label:`SEO Auditor`,blurb:`Technical + content SEO: indexability, IA, intent match.`},"growth-hacker":{label:`Growth Experimenter`,blurb:`Funnel diagnosis, lift experiments, activation loops.`},"social-strategist":{label:`Social Media Strategist`,blurb:`Channel-fit content, editorial calendar, voice consistency.`},"literature-reviewer":{label:`Literature Reviewer`,blurb:`Systematic review summaries, citation graphs, conflicts.`},"experiment-designer":{label:`Experiment Designer`,blurb:`Hypotheses, controls, sample size, pre-registration.`},"statistical-analyst":{label:`Statistical Analyst`,blurb:`Chooses the right test, reports effect sizes, not just p-values.`},"scientific-writer":{label:`Scientific Writer`,blurb:`IMRaD structure, honest limits, readable abstracts.`},"curriculum-designer":{label:`Curriculum Designer`,blurb:`Learning outcomes → activities → assessment.`},"assessment-author":{label:`Assessment Author`,blurb:`Items that measure understanding, not recall.`},"tutor-explainer":{label:`Tutor / Explainer`,blurb:`Feynman-style simple explanations with worked examples.`},"clinical-guideline-reviewer":{label:`Clinical Guideline Reviewer`,blurb:`Map practice against latest evidence-based guidelines.`},"medical-summarizer":{label:`Medical Literature Summarizer`,blurb:`Abstracts to clinicians: what changed, evidence quality.`},"protocol-designer":{label:`Protocol Designer`,blurb:`Clinical protocols: endpoints, inclusion criteria, safety.`},"contract-reviewer":{label:`Contract Reviewer`,blurb:`Flags risky clauses; explains what they actually mean.`},"privacy-counsel":{label:`Privacy Counsel`,blurb:`GDPR / CCPA / LGPD applied to concrete flows.`},"copy-editor":{label:`Copy Editor`,blurb:`Line edits: voice, cadence, cut 30% without losing meaning.`},"brand-voice-guardian":{label:`Brand Voice Guardian`,blurb:`Enforces voice rules; catches off-brand phrasing.`},"creative-brainstormer":{label:`Creative Brainstormer`,blurb:`Divergent then convergent; kills sacred cows politely.`},"hiring-interviewer":{label:`Hiring Interviewer`,blurb:`Structured interviews, signal-focused, bias-aware.`},"strategic-planner":{label:`Strategic Planner`,blurb:`Goals → bets → metrics; prunes pet projects.`},"coach-1on1":{label:`1:1 Coach`,blurb:`Helps frame feedback, career growth, difficult conversations.`},"meeting-facilitator":{label:`Meeting Facilitator`,blurb:`Agendas that produce decisions, not updates.`}},s={studio:n,refine:r,profileEditor:i,agentSelector:a,templates:o};export{t};