specrails-desktop 2.45.0 → 2.46.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 (122) hide show
  1. package/client/dist/assets/{ActivityFeedPage-D3SQklu5.js → ActivityFeedPage-CsHQPpvl.js} +1 -1
  2. package/client/dist/assets/{AgentBrowserCapture-DNGxE33d.js → AgentBrowserCapture-BVcCK7x0.js} +1 -1
  3. package/client/dist/assets/AgentModeAnalyticsPane-C5F3m29G.js +2 -0
  4. package/client/dist/assets/AgentModeCodePane-C5QuKsu0.js +2 -0
  5. package/client/dist/assets/AgentModeJobsPane-rnD-EPMd.js +1 -0
  6. package/client/dist/assets/AgentsPage-DiyJWZcU.js +87 -0
  7. package/client/dist/assets/{AnalyticsPage-BqV6mM2O.js → AnalyticsPage-Dkmb0dnd.js} +1 -1
  8. package/client/dist/assets/CodePage-C0dH99-t.js +3 -0
  9. package/client/dist/assets/{DesktopAnalyticsPage-D6WNax3K.js → DesktopAnalyticsPage-DuTjr2n8.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-68jKUH9f.js → DocsDialog-BVZJZHVR.js} +1 -1
  11. package/client/dist/assets/{DocsPage-BoGJgRpm.js → DocsPage-D6KHTv8V.js} +1 -1
  12. package/client/dist/assets/{ExportDropdown-B2C_XLGp.js → ExportDropdown-pWZGYCv3.js} +1 -1
  13. package/client/dist/assets/InteractiveJobComposer-Ck3PQxjN.js +19 -0
  14. package/client/dist/assets/JobDetailModal-DkoMH3ie.js +1 -0
  15. package/client/dist/assets/JobDetailPage-CBVivcl2.js +1 -0
  16. package/client/dist/assets/JobsPage-CzxEeca9.js +1 -0
  17. package/client/dist/assets/{LoopBuilderPage-D21GxFmL.js → LoopBuilderPage-CtmOE4-b.js} +2 -2
  18. package/client/dist/assets/{LoopPreviewModal-Bo3fYFxN.js → LoopPreviewModal-BYeLjQbr.js} +1 -1
  19. package/client/dist/assets/{LoopsPage-BcrBw1cg.js → LoopsPage-6iW7g25k.js} +1 -1
  20. package/client/dist/assets/{MinimizedChatsContext-Dsv2eHf_.js → MinimizedChatsContext-B6wVevPq.js} +1 -1
  21. package/client/dist/assets/{PluginsPage-BbyTmSLx.js → PluginsPage-Bf1z3WPF.js} +2 -2
  22. package/client/dist/assets/{ProjectSettingsDialog-B3lEXLv7.js → ProjectSettingsDialog-DsCRIc4v.js} +1 -1
  23. package/client/dist/assets/{RepositoryDeliveries-ok_Wo65C.js → RepositoryDeliveries-BQm_3TO8.js} +1 -1
  24. package/client/dist/assets/{RepositoryScopeSelector-DU6QwNaS.js → RepositoryScopeSelector-DnAFtjTz.js} +1 -1
  25. package/client/dist/assets/{ReviewPacketPage-BBCeHtgd.js → ReviewPacketPage-CaXAwtR7.js} +1 -1
  26. package/client/dist/assets/{TemplatePreviewModal-CfNmxS6O.js → TemplatePreviewModal-9aRFpJ_J.js} +1 -1
  27. package/client/dist/assets/{TicketDetailModalContext-DW3eQ0I7.js → TicketDetailModalContext-B1X5glzV.js} +1 -1
  28. package/client/dist/assets/{Trans-BHPMWkOw.js → Trans-BwLgX6n7.js} +1 -1
  29. package/client/dist/assets/agentRuntime-BUagD2I_.js +1 -0
  30. package/client/dist/assets/agentRuntime-BkL70WtX.js +1 -0
  31. package/client/dist/assets/agentRuntime-CWXVqgqE.js +1 -0
  32. package/client/dist/assets/agentRuntime-CvNBdUAe.js +1 -0
  33. package/client/dist/assets/agentRuntime-D4RmeuNY.js +1 -0
  34. package/client/dist/assets/agentRuntime-DTidBWKg.js +1 -0
  35. package/client/dist/assets/agentRuntime-DhKYfyaU.js +1 -0
  36. package/client/dist/assets/agentRuntime-LL8_GLx9.js +1 -0
  37. package/client/dist/assets/format-duration-NJVPOPBG.js +1 -0
  38. package/client/dist/assets/{formatDistanceToNow-Bq8iptrG.js → formatDistanceToNow-CeZv93iR.js} +1 -1
  39. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BVFky3l_.js → getTimezoneOffsetInMilliseconds-DxAkjvJb.js} +1 -1
  40. package/client/dist/assets/index-Cfh9aaep.css +2 -0
  41. package/client/dist/assets/index-DYoyDWim.js +76 -0
  42. package/client/dist/assets/{jira-api-zrRdZFBB.js → jira-api-ChjVGJx_.js} +1 -1
  43. package/client/dist/assets/narration-4OSg0b5-.js +1 -0
  44. package/client/dist/assets/narration-BPMOQPFe.js +1 -0
  45. package/client/dist/assets/narration-BSldQfjd.js +1 -0
  46. package/client/dist/assets/narration-CvQdWdR5.js +1 -0
  47. package/client/dist/assets/narration-D-e9ssxA.js +1 -0
  48. package/client/dist/assets/narration-DKLjXIFI.js +1 -0
  49. package/client/dist/assets/narration-DnrKC3mF.js +1 -0
  50. package/client/dist/assets/narration-Dypjxeel.js +1 -0
  51. package/client/dist/assets/{project-repositories-CFRaB9UB.js → project-repositories-BvBj9XH9.js} +1 -1
  52. package/client/dist/assets/{provider-capabilities-B-wOHfLP.js → provider-capabilities-CXipwrXJ.js} +1 -1
  53. package/client/dist/assets/{settings-OOyDrZQo.js → settings-B3rWEwOx.js} +1 -1
  54. package/client/dist/assets/{settings-CNiERE-R.js → settings-BcVoiMyw.js} +1 -1
  55. package/client/dist/assets/settings-BlYvaQ7w.js +1 -0
  56. package/client/dist/assets/{settings-DJ2jl3hJ.js → settings-CD5uEBiL.js} +1 -1
  57. package/client/dist/assets/{settings-a7NIODme.js → settings-CyhS0DLJ.js} +1 -1
  58. package/client/dist/assets/{settings-DVRVybR_.js → settings-DCMFUGDs.js} +1 -1
  59. package/client/dist/assets/{settings-CrtCs5-B.js → settings-DEgcA0jd.js} +1 -1
  60. package/client/dist/assets/{settings-ChOCVjX_.js → settings-DmbYKyMJ.js} +1 -1
  61. package/client/dist/assets/{spending-lTZ-bm_y.js → spending-DNM6NAoA.js} +1 -1
  62. package/client/dist/assets/{useDesktop-Duv5ddAa.js → useDesktop-mxHVQOdx.js} +1 -1
  63. package/client/dist/assets/{useSharedWebSocket-5mj2SMKn.js → useSharedWebSocket-DnxHj8jP.js} +2 -2
  64. package/client/dist/index.html +19 -18
  65. package/docs/internals/programmatic-agent-runtime.md +19 -8
  66. package/package.json +1 -1
  67. package/server/dist/agent-mcp-config.js +5 -0
  68. package/server/dist/agent-operator-prompt.js +2 -2
  69. package/server/dist/agent-runtime-bridge.js +62 -14
  70. package/server/dist/agent-runtime-controls-router.js +42 -0
  71. package/server/dist/agent-runtime-controls.js +68 -4
  72. package/server/dist/agent-runtime-loader.js +6 -0
  73. package/server/dist/agent-runtime-metrics.js +46 -0
  74. package/server/dist/agent-runtime-repositories.js +37 -0
  75. package/server/dist/agent-runtime-settings-router.js +5 -3
  76. package/server/dist/agent-runtime-settings.js +125 -21
  77. package/server/dist/agent-runtime-settlement.js +133 -0
  78. package/server/dist/contract-refine-runner.js +7 -7
  79. package/server/dist/core-completion.js +8 -5
  80. package/server/dist/desktop-router.js +26 -0
  81. package/server/dist/job-listing.js +7 -3
  82. package/server/dist/loop-command-catalog.js +2 -2
  83. package/server/dist/loop-executors.js +5 -3
  84. package/server/dist/loop-run-manager.js +2 -2
  85. package/server/dist/mcp/tools/specs.js +7 -4
  86. package/server/dist/multi-repo-execution.js +1 -0
  87. package/server/dist/project-router-jobs.js +8 -2
  88. package/server/dist/project-router-tickets.js +4 -4
  89. package/server/dist/providers/runtime.js +6 -0
  90. package/server/dist/rail-isolated-launch.js +1 -1
  91. package/server/dist/rails-router.js +3 -1
  92. package/server/dist/runtime-role-prompts-router.js +25 -0
  93. package/server/dist/schemas/agent-runtime.schema.json +7 -2
  94. package/server/dist/worktree-overlay.js +32 -1
  95. package/client/dist/assets/AgentModeAnalyticsPane-BUvZNoj0.js +0 -2
  96. package/client/dist/assets/AgentModeCodePane-YW717UvJ.js +0 -2
  97. package/client/dist/assets/AgentModeJobsPane-Cxg_eNmd.js +0 -1
  98. package/client/dist/assets/AgentsPage-B_DCByok.js +0 -87
  99. package/client/dist/assets/CodePage-PyZKCj1B.js +0 -3
  100. package/client/dist/assets/InteractiveJobComposer-l8q-r5Yy.js +0 -19
  101. package/client/dist/assets/JobDetailModal-C-X2GI9j.js +0 -1
  102. package/client/dist/assets/JobDetailPage-C6Jdm7S9.js +0 -1
  103. package/client/dist/assets/JobsPage-DycM6Vgp.js +0 -1
  104. package/client/dist/assets/agentRuntime-14faDjWM.js +0 -1
  105. package/client/dist/assets/agentRuntime-BIokojkJ.js +0 -1
  106. package/client/dist/assets/agentRuntime-Bu4xEcRw.js +0 -1
  107. package/client/dist/assets/agentRuntime-Cz0ASixB.js +0 -1
  108. package/client/dist/assets/agentRuntime-DESdGXLV.js +0 -1
  109. package/client/dist/assets/agentRuntime-DhX5Xy5S.js +0 -1
  110. package/client/dist/assets/agentRuntime-Dpbh_gLp.js +0 -1
  111. package/client/dist/assets/agentRuntime-jS2lplFm.js +0 -1
  112. package/client/dist/assets/index-CBLYwPw6.css +0 -2
  113. package/client/dist/assets/index-DOKftX7y.js +0 -76
  114. package/client/dist/assets/narration-BA8Yw5ZL.js +0 -1
  115. package/client/dist/assets/narration-BuMFUS7Q.js +0 -1
  116. package/client/dist/assets/narration-Bv_iQQG5.js +0 -1
  117. package/client/dist/assets/narration-C6Ost9nL.js +0 -1
  118. package/client/dist/assets/narration-CIbjo2pA.js +0 -1
  119. package/client/dist/assets/narration-CNJ2-2-a.js +0 -1
  120. package/client/dist/assets/narration-OzsPJCXM.js +0 -1
  121. package/client/dist/assets/narration-zCdgiuSU.js +0 -1
  122. package/client/dist/assets/settings-DzXZCb1h.js +0 -1
@@ -59,7 +59,8 @@ function specsTools() {
59
59
  '— pass contractRefine: false to skip it, e.g. when the user declined it), ' +
60
60
  'generate (same as create but takes a pre-formed idea string; both accept contextScope/attachments/createLocal), ' +
61
61
  'ai_edit (ai-spawn, AI-edit a ticket title+description), ' +
62
- 'cancel_ai_edit (abort an in-flight ai-edit), contract_refine (ai-spawn, append/re-fire a Contract Layer — Claude-only; ' +
62
+ 'cancel_ai_edit (abort an in-flight ai-edit), contract_refine (ai-spawn, append/re-fire a Contract Layer — Claude or Codex; ' +
63
+ 'pass numeric id, not ticketId; optional aiEngine selects the provider for origin-less specs, while Explore specs retain their origin provider; ' +
63
64
  'works on Explore-origin AND agent-authored/Quick specs), ' +
64
65
  'smash (ai-spawn, decompose a spec into N child sub-specs under an epic — Claude-only), ' +
65
66
  'smash_undo (destructive, reverse a prior SMASH), delete_epic_children (destructive, delete all children of an epic), ' +
@@ -150,7 +151,7 @@ function specsTools() {
150
151
  aiEngine: zod_1.z
151
152
  .string()
152
153
  .optional()
153
- .describe('create/generate: provider/engine override (must be an installed provider; defaults to primary)'),
154
+ .describe('create/generate/contract_refine: provider/engine override (must be installed; contract_refine cannot switch an Explore-origin provider)'),
154
155
  contextScope: zod_1.z
155
156
  .record(zod_1.z.unknown())
156
157
  .optional()
@@ -158,7 +159,7 @@ function specsTools() {
158
159
  contractRefine: zod_1.z
159
160
  .boolean()
160
161
  .optional()
161
- .describe('create/generate/commit_draft: enrich the spec with a Contract Layer post-persist (Claude-only). DEFAULTS TO TRUE — pass false to opt out (e.g. the user asked for no contract layer)'),
162
+ .describe('create/generate/commit_draft: enrich the spec with a Contract Layer post-persist (Claude or Codex). DEFAULTS TO TRUE — pass false to opt out (e.g. the user asked for no contract layer)'),
162
163
  attachmentIds: zod_1.z.array(zod_1.z.string()).optional().describe('create/generate/ai_edit: attachment ids (create/generate require pendingSpecId)'),
163
164
  // ── ai_edit ──────────────────────────────────────────────────────
164
165
  instructions: zod_1.z.string().optional().describe('ai_edit: natural-language editing instructions (required)'),
@@ -428,7 +429,9 @@ function specsTools() {
428
429
  return { ...r, hint: WATCH_HINT };
429
430
  }
430
431
  case 'contract_refine': {
431
- const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/tickets/${requireId()}/contract-refine`);
432
+ const r = await (0, types_1.apiCall)(ctx, 'POST', `${base}/tickets/${requireId()}/contract-refine`, {
433
+ aiEngine: args.aiEngine,
434
+ });
432
435
  return { ...r, hint: CONTRACT_REFINE_HINT };
433
436
  }
434
437
  case 'smash': {
@@ -353,6 +353,7 @@ async function launchMultiRepositoryRail(input, io = {}) {
353
353
  };
354
354
  await (0, rail_isolated_launch_1.launchIsolatedRail)({
355
355
  ...input, ctx: childCtx, scope: effectiveScope, loopGraph: graph,
356
+ runtimeStateProject: ctx.project,
356
357
  revision: input.revision && previous ? { ...input.revision, ofDeliveryId: previous.id, decision: previous.decision } : undefined,
357
358
  requiredPrContinuation: continuation,
358
359
  explicitPrTarget: continuation?.prNumber ? { prNumber: continuation.prNumber } : input.explicitPrTarget,
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerJobsRoutes = registerJobsRoutes;
4
+ const agent_runtime_controls_router_1 = require("./agent-runtime-controls-router");
4
5
  const ids_1 = require("./ids");
5
6
  const db_1 = require("./db");
6
7
  const queue_manager_1 = require("./queue-manager");
@@ -229,6 +230,10 @@ function registerJobsRoutes(deps) {
229
230
  router.post('/:projectId/jobs/:id/cancel', (req, res) => {
230
231
  const id = req.params.id;
231
232
  const c = ctx(req);
233
+ if ((0, agent_runtime_controls_router_1.cancelRuntimeContinuation)(c, id)) {
234
+ res.json({ ok: true, status: 'canceling' });
235
+ return;
236
+ }
232
237
  // A loop run is backed by a job row but is NOT a QueueManager job — it is
233
238
  // driven by the LoopRunManager. Cancel it through the engine (which settles
234
239
  // it 'stopped' → finishJob('canceled') + releases the rail's tickets).
@@ -409,12 +414,13 @@ function registerJobsRoutes(deps) {
409
414
  const from = req.query.from;
410
415
  const to = req.query.to;
411
416
  const { db } = ctx(req);
412
- const result = (0, job_listing_1.listUnifiedJobs)(db, { limit, offset, status, from, to });
417
+ const result = (0, job_listing_1.listUnifiedJobs)(db, { limit, offset, status, from, to, activeRuntimeIds: (0, agent_runtime_controls_router_1.activeRuntimeContinuationIds)(ctx(req)) });
413
418
  // Annotate each job with hasTelemetry so the client can show the
414
419
  // Export diagnostic button without an extra round trip.
415
420
  const jobsWithTelemetry = (0, db_1.getJobsWithTelemetry)(db);
416
421
  const annotatedJobs = result.jobs.map((j) => ({
417
422
  ...j,
423
+ ...((0, agent_runtime_controls_router_1.isRuntimeContinuationActive)(ctx(req), j.id) ? { status: 'running', finished_at: null } : {}),
418
424
  hasTelemetry: jobsWithTelemetry.has(j.id),
419
425
  }));
420
426
  res.json({ jobs: annotatedJobs, total: result.total });
@@ -593,7 +599,7 @@ function registerJobsRoutes(deps) {
593
599
  interactiveAcceptingTurns = qmMode !== null || loopStepActive || loopPaused;
594
600
  interactiveSettleMode = qmMode ?? ((loopStepActive || loopPaused || loopRun) ? 'auto' : null);
595
601
  }
596
- const annotated = { ...job, hasTelemetry: (0, db_1.hasJobTelemetry)(db, jobId), tickets, interactiveSettleMode, interactiveAcceptingTurns, loopPaused, loopPauseReason };
602
+ const annotated = { ...job, ...((0, agent_runtime_controls_router_1.isRuntimeContinuationActive)(c, jobId) ? { status: 'running', finished_at: null } : {}), hasTelemetry: (0, db_1.hasJobTelemetry)(db, jobId), tickets, interactiveSettleMode, interactiveAcceptingTurns, loopPaused, loopPauseReason };
597
603
  res.json({ job: annotated, events, phaseDefinitions });
598
604
  });
599
605
  router.delete('/:projectId/jobs', (req, res) => {
@@ -271,7 +271,7 @@ function registerTicketsRoutes(deps) {
271
271
  const rawScope = req.body?.contextScope;
272
272
  // Contract Layer is available only when the selected adapter advertises a
273
273
  // safe structured-action implementation.
274
- const quickContractRefine = (0, providers_1.getAdapter)(provider).capabilities.structuredActions !== true
274
+ const quickContractRefine = !(0, runtime_1.supportsContractRefine)((0, providers_1.getAdapter)(provider))
275
275
  ? false
276
276
  : typeof req.body?.contractRefine === 'boolean'
277
277
  ? req.body.contractRefine
@@ -1057,7 +1057,7 @@ function registerTicketsRoutes(deps) {
1057
1057
  if (conversationId &&
1058
1058
  created &&
1059
1059
  convoProvider &&
1060
- (0, providers_1.getAdapter)(convoProvider).capabilities.structuredActions === true) {
1060
+ (0, runtime_1.supportsContractRefine)((0, providers_1.getAdapter)(convoProvider))) {
1061
1061
  const createdTicketId = created.id;
1062
1062
  const convoId = conversationId;
1063
1063
  console.log(`[project-router] from-draft hook: scheduling refine ticket=${createdTicketId} conv=${convoId}`);
@@ -1093,7 +1093,7 @@ function registerTicketsRoutes(deps) {
1093
1093
  const requestedAgentProvider = typeof body.agentProvider === 'string' ? body.agentProvider : null;
1094
1094
  const providerCheck = (0, provider_selection_1.validateRequestedProvider)(project, requestedAgentProvider);
1095
1095
  const refineProvider = providerCheck.ok ? providerCheck.provider : null;
1096
- if (refineProvider && (0, providers_1.getAdapter)(refineProvider).capabilities.structuredActions === true) {
1096
+ if (refineProvider && (0, runtime_1.supportsContractRefine)((0, providers_1.getAdapter)(refineProvider))) {
1097
1097
  const refineTicketId = created.id;
1098
1098
  const refineTitle = created.title;
1099
1099
  const refineDescription = created.description;
@@ -1262,7 +1262,7 @@ function registerTicketsRoutes(deps) {
1262
1262
  return;
1263
1263
  }
1264
1264
  const refineProvider = refineProviderCheck.provider;
1265
- if ((0, providers_1.getAdapter)(refineProvider).capabilities.structuredActions !== true) {
1265
+ if (!(0, runtime_1.supportsContractRefine)((0, providers_1.getAdapter)(refineProvider))) {
1266
1266
  res.status(409).json({ error: `contract_refine_unsupported_for_${refineProvider}` });
1267
1267
  return;
1268
1268
  }
@@ -5,6 +5,7 @@ exports.isSafeCustomModelAlias = isSafeCustomModelAlias;
5
5
  exports.isModelAvailableForAdapter = isModelAvailableForAdapter;
6
6
  exports.supportsToolPolicy = supportsToolPolicy;
7
7
  exports.pureOutputToolPolicy = pureOutputToolPolicy;
8
+ exports.supportsContractRefine = supportsContractRefine;
8
9
  exports.requireToolPolicy = requireToolPolicy;
9
10
  exports.reasoningEffortsForModel = reasoningEffortsForModel;
10
11
  exports.defaultReasoningEffortForModel = defaultReasoningEffortForModel;
@@ -61,6 +62,11 @@ function pureOutputToolPolicy(adapter) {
61
62
  return 'read-only';
62
63
  return null;
63
64
  }
65
+ /** Contract extraction also supports Codex's enforced read-only transform. */
66
+ function supportsContractRefine(adapter) {
67
+ return adapter.capabilities.structuredActions === true
68
+ || (adapter.id === 'codex' && pureOutputToolPolicy(adapter) !== null);
69
+ }
64
70
  /** Throw a stable, provider-identifying error for an unsupported boundary. */
65
71
  function requireToolPolicy(adapter, policy) {
66
72
  if (!supportsToolPolicy(adapter, policy)) {
@@ -1019,7 +1019,7 @@ async function launchIsolatedRail(input, io = {}) {
1019
1019
  // A paused/interrupted programmatic workflow owns unfinished changes and
1020
1020
  // verification evidence in this exact mount. Keep them available for
1021
1021
  // explicit Core recovery, including a currently clean worktree.
1022
- if (implementationOutcome === 'failed' && (0, agent_runtime_paths_1.hasAgentRuntimeRequest)(ctx.project, a.runId)) {
1022
+ if (implementationOutcome === 'failed' && (0, agent_runtime_paths_1.hasAgentRuntimeRequest)(input.runtimeStateProject ?? ctx.project, a.runId)) {
1023
1023
  markWorktree(a, 'needs-review');
1024
1024
  return {
1025
1025
  run: a, implementationOutcome, deliveryOutcome: 'blocked',
@@ -1211,7 +1211,8 @@ function createRailsRouter() {
1211
1211
  // (so we deliberately do NOT delete railLoopRuns here).
1212
1212
  for (const runId of targetLoopRunIds) {
1213
1213
  try {
1214
- c.loopRunManager.cancel(runId);
1214
+ if (!(0, agent_runtime_controls_router_1.cancelRuntimeContinuation)(c, runId))
1215
+ c.loopRunManager.cancel(runId);
1215
1216
  canceledCount++;
1216
1217
  }
1217
1218
  catch (err) {
@@ -1534,3 +1535,4 @@ function createRailsRouter() {
1534
1535
  });
1535
1536
  return router;
1536
1537
  }
1538
+ const agent_runtime_controls_router_1 = require("./agent-runtime-controls-router");
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerRuntimeRolePromptRoutes = registerRuntimeRolePromptRoutes;
4
+ const agent_runtime_settings_1 = require("./agent-runtime-settings");
5
+ const agent_runtime_loader_1 = require("./agent-runtime-loader");
6
+ function registerRuntimeRolePromptRoutes(router) {
7
+ router.get('/runtime-role-prompts', async (_req, res) => {
8
+ try {
9
+ const defaults = (await (0, agent_runtime_loader_1.loadCoreAgentRuntime)()).rolePromptDefaults();
10
+ res.json({ defaults, overrides: (0, agent_runtime_settings_1.loadRuntimeRolePrompts)() });
11
+ }
12
+ catch (error) {
13
+ res.status(422).json({ message: error.message });
14
+ }
15
+ });
16
+ router.put('/runtime-role-prompts', async (req, res) => {
17
+ try {
18
+ const defaults = (await (0, agent_runtime_loader_1.loadCoreAgentRuntime)()).rolePromptDefaults();
19
+ res.json({ defaults, overrides: (0, agent_runtime_settings_1.saveRuntimeRolePrompts)(req.body.overrides) });
20
+ }
21
+ catch (error) {
22
+ res.status(error instanceof agent_runtime_settings_1.AgentRuntimeConfigError ? 400 : 500).json({ message: error.message });
23
+ }
24
+ });
25
+ }
@@ -4,10 +4,15 @@
4
4
  "title": "Specrails programmatic agent runtime",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": ["schemaVersion", "enabled", "providers", "agents", "verification"],
7
+ "required": ["schemaVersion", "providers", "agents", "verification"],
8
8
  "properties": {
9
9
  "schemaVersion": { "const": 1 },
10
- "enabled": { "type": "boolean" },
10
+ "rolePrompts": { "type": "object", "additionalProperties": false, "properties": {
11
+ "architect": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" },
12
+ "developer": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" },
13
+ "reviewer": { "type": "string", "minLength": 1, "maxLength": 20000, "pattern": "\\S" }
14
+ } },
15
+ "enabled": { "type": "boolean", "deprecated": true, "description": "Accepted for saved configuration compatibility; implementation always uses the agent runtime." },
11
16
  "providers": { "type": "array", "items": { "oneOf": [
12
17
  { "type": "object", "additionalProperties": false, "required": ["id", "kind", "cli"], "properties": {
13
18
  "id": { "$ref": "#/definitions/id" }, "kind": { "const": "cli" }, "cli": { "enum": ["claude", "codex", "gemini", "kimi"] }
@@ -243,7 +243,19 @@ function captureOverlayCleanupEvidence(input, candidates, includeManifest = fals
243
243
  const destinationDigest = dereferencedDigest(destination);
244
244
  if (!destinationDigest)
245
245
  continue;
246
- if (!sources.some((source) => dereferencedDigest(source) === destinationDigest))
246
+ if (!sources.some((source) => {
247
+ if (dereferencedDigest(source) === destinationDigest)
248
+ return true;
249
+ // A bootstrap refresh is still an exact, reproducible source copy.
250
+ if (rel !== input.instructionsFilename || !destinationStat.isFile())
251
+ return false;
252
+ try {
253
+ return fs_1.default.readFileSync(destination, 'utf8') === refreshLegacyInstructions(fs_1.default.readFileSync(source, 'utf8'));
254
+ }
255
+ catch {
256
+ return false;
257
+ }
258
+ }))
247
259
  continue;
248
260
  }
249
261
  const fingerprint = fingerprintOverlayCleanupPath(destination);
@@ -495,6 +507,13 @@ function mergeChildren(dirSrcs, dest, rel, created, warnings, priorOwned, conver
495
507
  mergeLink(childSrcs, path_1.default.join(dest, name), `${rel}/${name}`, created, warnings, priorOwned, converted);
496
508
  }
497
509
  }
510
+ function refreshLegacyInstructions(text) {
511
+ return text.replace(/<!-- specrails-managed:start -->[\s\S]*?<!-- specrails-managed:end -->/g, block => {
512
+ if (!block.includes('skills/sr-*'))
513
+ return block;
514
+ return '<!-- specrails-managed:start -->\n\n# Specrails agent runtime\n\nFollow the frozen repository scope and official OpenSpec workflow supplied for your role. The host coordinates architect, developer, verification and reviewer; do not launch nested implement or batch-implement orchestration. Read project README, manifests, contracts and relevant nested instructions. Report incomplete tasks and permission blockers with their repository and path.\n\n<!-- specrails-managed:end -->';
515
+ });
516
+ }
498
517
  /** Copy `src` → `dest` only when `dest` does not exist. Records `rel`. */
499
518
  function copyIfAbsent(src, dest, rel, created, warnings) {
500
519
  if (!fs_1.default.existsSync(src))
@@ -591,6 +610,18 @@ function applyWorktreeOverlay(input) {
591
610
  if (instructionsSrc) {
592
611
  copyIfAbsent(instructionsSrc, path_1.default.join(worktreePath, instructionsFilename), instructionsFilename, created, warnings);
593
612
  }
613
+ // Refresh only overlay-owned legacy bootstrap blocks. Project-authored
614
+ // instructions and text outside the managed block remain untouched.
615
+ if (created.includes(instructionsFilename) || priorOwned.has(instructionsFilename)) {
616
+ const dest = path_1.default.join(worktreePath, instructionsFilename);
617
+ const stat = lstatSafe(dest);
618
+ if (stat?.isFile() && !stat.isSymbolicLink()) {
619
+ const text = fs_1.default.readFileSync(dest, 'utf8');
620
+ const next = refreshLegacyInstructions(text);
621
+ if (next !== text)
622
+ fs_1.default.writeFileSync(dest, next);
623
+ }
624
+ }
594
625
  }
595
626
  catch (err) {
596
627
  warnings.push(`overlay failed: ${errMsg(err)}`);
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AnalyticsPage-BqV6mM2O.js","assets/rolldown-runtime-CNC7AqOf.js","assets/jsx-runtime-zu2_FqZY.js","assets/chunk-KS7C4IRE-DEKu087k.js","assets/preload-helper-Czpn1I53.js","assets/useSharedWebSocket-5mj2SMKn.js","assets/activity-DiyjsgQV.js","assets/addspec-D2YIQ0GU.js","assets/agent-Bh9K7iEt.js","assets/agentRuntime-Bu4xEcRw.js","assets/agents-ms7TwG16.js","assets/agentstudio-CN2pokQu.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BMzCvrCU.js","assets/attachments-B53PG733.js","assets/browser-CG0PE1j_.js","assets/builder-BTiGnPT0.js","assets/chat-BGD7MXAy.js","assets/code-DaZ-ZwCT.js","assets/commands-BAWSYHjQ.js","assets/common-BrlwEnL7.js","assets/dashboard-BfBir_6o.js","assets/explore-DgBACn39.js","assets/integrations-mB-7zoyT.js","assets/jira-CKJg3HZd.js","assets/jobs-DMPU64ms.js","assets/loops-B7YpGizO.js","assets/mcp-CUAN6ORK.js","assets/narration-C6Ost9nL.js","assets/nav-Ch-zHBG5.js","assets/packet-Cx-zRuWn.js","assets/settings-DzXZCb1h.js","assets/setup-Ba11l2JA.js","assets/specs-DII0C8gw.js","assets/terminal-BAzpHtpY.js","assets/tickets-W6pBmbrX.js","assets/createLucideIcon-Bjbbp_KS.js","assets/Trans-BHPMWkOw.js","assets/useDesktop-Duv5ddAa.js","assets/react-dom-DiWzBDP9.js","assets/spending-lTZ-bm_y.js","assets/clsx-CjueKrWZ.js","assets/formatDistanceToNow-Bq8iptrG.js","assets/getTimezoneOffsetInMilliseconds-BVFky3l_.js","assets/provider-capabilities-B-wOHfLP.js","assets/index-DOKftX7y.js","assets/TicketDetailModalContext-DW3eQ0I7.js","assets/save-B6wGWwBR.js","assets/MinimizedChatsContext-Dsv2eHf_.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/file-text-BcLCfcWZ.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/git-branch-BRM0F5GN.js","assets/loader-circle-DcygOQpC.js","assets/pencil-C9RkrIPZ.js","assets/square-Ci-PFcFe.js","assets/plus-CsnjfkmX.js","assets/search-Cq_gE3Ik.js","assets/trash-2-BOU3WdZZ.js","assets/triangle-alert-H9T4jAmh.js","assets/jira-api-zrRdZFBB.js","assets/zap-CHo3aCD1.js","assets/dialog-xXB2q5HJ.js","assets/utils-BC4DHlz2.js","assets/lib-CGdyxIWg.js","assets/button-Ccc9Dc-D.js","assets/RepositoryScopeSelector-DU6QwNaS.js","assets/project-repositories-CFRaB9UB.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-ok_Wo65C.js","assets/event-Bt7f3wXe.js","assets/index-CBLYwPw6.css","assets/ExportDropdown-B2C_XLGp.js","assets/BarChart-nBOMNfiy.js","assets/value-s-gzBeyF.js"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./preload-helper-Czpn1I53.js";import{n as i}from"./createLucideIcon-Bjbbp_KS.js";import{t as a}from"./loader-circle-DcygOQpC.js";import{t as o}from"./x-CBMI9ejn.js";import{t as s}from"./utils-BC4DHlz2.js";import{G as c,_t as l,vt as u}from"./index-DOKftX7y.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./AnalyticsPage-BqV6mM2O.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76]))),m=420,h=560;function g(){let{t:e}=i(`agent`),{closeAnalyticsPane:t}=c(),[n,r]=(0,d.useState)(h),[g,_]=(0,d.useState)(!1),v=(0,d.useCallback)(e=>{let t=e.clientX,i=n,a=window.innerWidth-m;try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}let o=e=>{let n=Math.min(Math.max(i+(t-e.clientX),m),a);r(n)},s=()=>{window.removeEventListener(`pointermove`,o),window.removeEventListener(`pointerup`,s),window.removeEventListener(`pointercancel`,s)};window.addEventListener(`pointermove`,o),window.addEventListener(`pointerup`,s),window.addEventListener(`pointercancel`,s)},[n]);return(0,f.jsxs)(`div`,{className:s(`flex h-full flex-col overflow-hidden border-l border-border bg-background`,g&&`absolute inset-0 z-30 border-l-0`),style:g?void 0:{width:n,flexShrink:0},"data-testid":`agent-analytics-pane`,children:[(0,f.jsx)(`div`,{className:`relative flex items-center`,children:!g&&(0,f.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:v,className:`absolute left-0 top-0 h-full w-1.5 -translate-x-full cursor-col-resize select-none touch-none hover:bg-accent-primary/20`,title:e(`workspace.resizeAnalytics`)})}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,f.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:e(`workspace.analytics`)}),(0,f.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:()=>_(e=>!e),"aria-label":e(g?`restore`:`maximize`),title:e(g?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:g?(0,f.jsx)(l,{className:`h-4 w-4`}):(0,f.jsx)(u,{className:`h-4 w-4`})}),(0,f.jsx)(`button`,{type:`button`,onClick:t,"aria-label":e(`workspace.closeAnalytics`),title:e(`workspace.closeAnalytics`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,f.jsx)(o,{className:`h-4 w-4`})})]})]}),(0,f.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:(0,f.jsx)(d.Suspense,{fallback:(0,f.jsx)(`div`,{className:`flex h-24 items-center justify-center text-muted-foreground`,children:(0,f.jsx)(a,{className:`h-4 w-4 animate-spin`})}),children:(0,f.jsx)(p,{})})})]})}export{g as AgentModeAnalyticsPane};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodePage-PyZKCj1B.js","assets/rolldown-runtime-CNC7AqOf.js","assets/jsx-runtime-zu2_FqZY.js","assets/react-dom-DiWzBDP9.js","assets/preload-helper-Czpn1I53.js","assets/chunk-KS7C4IRE-DEKu087k.js","assets/TicketDetailModalContext-DW3eQ0I7.js","assets/useSharedWebSocket-5mj2SMKn.js","assets/activity-DiyjsgQV.js","assets/addspec-D2YIQ0GU.js","assets/agent-Bh9K7iEt.js","assets/agentRuntime-Bu4xEcRw.js","assets/agents-ms7TwG16.js","assets/agentstudio-CN2pokQu.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BMzCvrCU.js","assets/attachments-B53PG733.js","assets/browser-CG0PE1j_.js","assets/builder-BTiGnPT0.js","assets/chat-BGD7MXAy.js","assets/code-DaZ-ZwCT.js","assets/commands-BAWSYHjQ.js","assets/common-BrlwEnL7.js","assets/dashboard-BfBir_6o.js","assets/explore-DgBACn39.js","assets/integrations-mB-7zoyT.js","assets/jira-CKJg3HZd.js","assets/jobs-DMPU64ms.js","assets/loops-B7YpGizO.js","assets/mcp-CUAN6ORK.js","assets/narration-C6Ost9nL.js","assets/nav-Ch-zHBG5.js","assets/packet-Cx-zRuWn.js","assets/settings-DzXZCb1h.js","assets/setup-Ba11l2JA.js","assets/specs-DII0C8gw.js","assets/terminal-BAzpHtpY.js","assets/tickets-W6pBmbrX.js","assets/createLucideIcon-Bjbbp_KS.js","assets/Trans-BHPMWkOw.js","assets/useDesktop-Duv5ddAa.js","assets/save-B6wGWwBR.js","assets/spending-lTZ-bm_y.js","assets/MinimizedChatsContext-Dsv2eHf_.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/file-text-BcLCfcWZ.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/git-branch-BRM0F5GN.js","assets/loader-circle-DcygOQpC.js","assets/pencil-C9RkrIPZ.js","assets/square-Ci-PFcFe.js","assets/plus-CsnjfkmX.js","assets/search-Cq_gE3Ik.js","assets/trash-2-BOU3WdZZ.js","assets/triangle-alert-H9T4jAmh.js","assets/jira-api-zrRdZFBB.js","assets/zap-CHo3aCD1.js","assets/dialog-xXB2q5HJ.js","assets/utils-BC4DHlz2.js","assets/clsx-CjueKrWZ.js","assets/lib-CGdyxIWg.js","assets/formatDistanceToNow-Bq8iptrG.js","assets/getTimezoneOffsetInMilliseconds-BVFky3l_.js","assets/button-Ccc9Dc-D.js","assets/RepositoryScopeSelector-DU6QwNaS.js","assets/project-repositories-CFRaB9UB.js","assets/provider-capabilities-B-wOHfLP.js","assets/index-DOKftX7y.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-ok_Wo65C.js","assets/event-Bt7f3wXe.js","assets/index-CBLYwPw6.css"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./preload-helper-Czpn1I53.js";import{n as i}from"./createLucideIcon-Bjbbp_KS.js";import{t as a}from"./x-CBMI9ejn.js";import{$ as o,G as s,Q as c,_t as l,vt as u}from"./index-DOKftX7y.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./CodePage-PyZKCj1B.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73]))),m=420,h=560;function g({projectId:e,conversationId:t}){let{t:n}=i(`agent`),{closeCodePane:r}=s(),[g,_]=(0,d.useState)(h),[v,y]=(0,d.useState)(()=>window.innerWidth),[b,x]=(0,d.useState)(!1),S=(0,d.useRef)(null),C=(0,d.useRef)(null),w=Math.max(0,v-Math.min(m,v/2)),T=Math.min(m,w),E=Math.min(w,Math.max(T,g)),D=(0,d.useCallback)(e=>Math.min(w,Math.max(T,e)),[w,T]),O=`${e}:${t}`,k=(0,d.useCallback)(n=>{o(e,t,{path:n})},[e,t]);(0,d.useLayoutEffect)(()=>{let e=S.current,t=e?.parentElement;if(!e||!t)return;let n=()=>{let n=t.getBoundingClientRect().width||t.clientWidth||window.innerWidth,r=0;for(let n of t.children){if(n===e||!(n instanceof HTMLElement))continue;let t=getComputedStyle(n);t.display===`none`||t.position===`absolute`||t.position===`fixed`||Number(t.flexGrow)>0||(r+=n.getBoundingClientRect().width)}y(Math.max(0,n-r))},r=new ResizeObserver(n),i=()=>{r.disconnect(),r.observe(t);for(let n of t.children)n!==e&&r.observe(n);n()},a=new MutationObserver(i);return a.observe(t,{childList:!0}),i(),window.addEventListener(`resize`,n),()=>{r.disconnect(),a.disconnect(),window.removeEventListener(`resize`,n)}},[O]),(0,d.useEffect)(()=>()=>{C.current?.()},[O,b,w]);let A=(0,d.useCallback)(e=>{if(e.button!==0)return;e.preventDefault(),C.current?.();let t=e.clientX,n=E,r=e.pointerId,i=e.currentTarget;try{i.setPointerCapture(r)}catch{}let a=e=>{e.pointerId===r&&_(D(n+t-e.clientX))},o=()=>{window.removeEventListener(`pointermove`,a),window.removeEventListener(`pointerup`,s),window.removeEventListener(`pointercancel`,s),window.removeEventListener(`blur`,o),i.removeEventListener(`lostpointercapture`,o);try{i.hasPointerCapture(r)&&i.releasePointerCapture(r)}catch{}C.current=null},s=e=>{e.pointerId===r&&o()};C.current=o,window.addEventListener(`pointermove`,a),window.addEventListener(`pointerup`,s),window.addEventListener(`pointercancel`,s),window.addEventListener(`blur`,o),i.addEventListener(`lostpointercapture`,o)},[E,D]);return(0,f.jsxs)(`div`,{ref:S,className:`flex h-full min-w-0 flex-col overflow-hidden border-l border-border bg-background${b?` absolute inset-0 z-30 border-l-0`:` relative`}`,style:b?void 0:{width:E,maxWidth:`100%`,flexShrink:0},"data-testid":`agent-code-pane`,children:[!b&&(0,f.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:A,tabIndex:0,"aria-label":n(`workspace.resizeCode`),"aria-valuemin":Math.round(T),"aria-valuemax":Math.round(w),"aria-valuenow":Math.round(E),onKeyDown:e=>{let t=e.key===`ArrowLeft`?E+32:e.key===`ArrowRight`?E-32:e.key===`Home`?T:e.key===`End`?w:null;t!==null&&(e.preventDefault(),_(D(t)))},className:`absolute inset-y-0 left-0 z-20 w-1.5 cursor-col-resize select-none touch-none hover:bg-accent-primary/20 focus-visible:bg-accent-primary/30 focus-visible:outline-none`,title:n(`workspace.resizeCode`)}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,f.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:n(`workspace.files`)}),(0,f.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:()=>{C.current?.(),x(e=>!e)},"aria-label":n(b?`restore`:`maximize`),title:n(b?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:b?(0,f.jsx)(l,{className:`h-4 w-4`}):(0,f.jsx)(u,{className:`h-4 w-4`})}),(0,f.jsx)(`button`,{type:`button`,onClick:()=>{C.current?.(),r()},"aria-label":n(`workspace.closeFiles`),title:n(`workspace.closeFiles`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,f.jsx)(a,{className:`h-4 w-4`})})]})]}),(0,f.jsx)(`div`,{className:`min-h-0 flex-1 overflow-hidden`,children:(0,f.jsx)(d.Suspense,{fallback:(0,f.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`…`}),children:(0,f.jsx)(p,{embedded:!0,initialRepositoryId:c(e,t).repositoryId,onRepositoryChange:n=>o(e,t,{repositoryId:n}),initialPath:c(e,t).path,onSelectedPathChange:k},O)})})]},O)}export{g as AgentModeCodePane};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{m as r,r as i}from"./useSharedWebSocket-5mj2SMKn.js";import{n as a}from"./createLucideIcon-Bjbbp_KS.js";import{a as o,i as s,r as c}from"./useDesktop-Duv5ddAa.js";import{t as l}from"./loader-circle-DcygOQpC.js";import{t as u}from"./x-CBMI9ejn.js";import{t as d}from"./utils-BC4DHlz2.js";import{t as f}from"./formatDistanceToNow-Bq8iptrG.js";import{Ft as p,G as m,S as h,_t as g,vt as _}from"./index-DOKftX7y.js";import{n as v,t as y}from"./job-time-BCL7wee9.js";import{JobDetailModal as b}from"./JobDetailModal-C-X2GI9j.js";import{t as x}from"./format-command-C0D9IPmV.js";var S=e(t(),1),C=n(),w=360,T=480,E={running:`running`,completed:`success`,failed:`failed`,canceled:`canceled`,queued:`queued`};function D({projectId:e}){let{t}=a(`agent`),{t:n}=a(`jobs`),{closeJobsPane:D}=m(),{projects:O}=c(),k=O.find(t=>t.id===e)?.provider,[A,j]=(0,S.useState)(T),[M,N]=(0,S.useState)(!1),[P,F]=(0,S.useState)(null),{data:I,isFirstLoad:L,refresh:R}=s({namespace:`agent-jobs`,projectId:e,initialValue:[],fetcher:async()=>{let e=await fetch(`${o()}/jobs?limit=50`);return e.ok?(await e.json()).jobs:[]},pollInterval:5e3}),{registerHandler:z,unregisterHandler:B}=i(),V=(0,S.useRef)(e);V.current=e;let H=(0,S.useRef)(R);H.current=R,(0,S.useEffect)(()=>(z(`agent-jobs-pane`,e=>{let t=e;t.type===`queue`&&(t.projectId&&t.projectId!==V.current||H.current())}),()=>B(`agent-jobs-pane`)),[z,B]);let U=(0,S.useCallback)(e=>{let t=e.clientX,n=A,r=window.innerWidth-w;try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}let i=e=>{let i=Math.min(Math.max(n+(t-e.clientX),w),r);j(i)},a=()=>{window.removeEventListener(`pointermove`,i),window.removeEventListener(`pointerup`,a),window.removeEventListener(`pointercancel`,a)};window.addEventListener(`pointermove`,i),window.addEventListener(`pointerup`,a),window.addEventListener(`pointercancel`,a)},[A]);return(0,C.jsxs)(`div`,{className:d(`flex h-full flex-col overflow-hidden border-l border-border bg-background`,M&&`absolute inset-0 z-30 border-l-0`),style:M?void 0:{width:A,flexShrink:0},children:[(0,C.jsx)(`div`,{className:`relative flex items-center`,children:!M&&(0,C.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:U,className:`absolute left-0 top-0 h-full w-1.5 -translate-x-full cursor-col-resize select-none touch-none hover:bg-accent-primary/20`,title:t(`workspace.resizeJobs`)})}),(0,C.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,C.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:t(`workspace.jobs`)}),(0,C.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,C.jsx)(`button`,{type:`button`,onClick:()=>N(e=>!e),"aria-label":t(M?`restore`:`maximize`),title:t(M?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:M?(0,C.jsx)(g,{className:`h-4 w-4`}):(0,C.jsx)(_,{className:`h-4 w-4`})}),(0,C.jsx)(`button`,{type:`button`,onClick:D,"aria-label":t(`workspace.closeJobs`),title:t(`workspace.closeJobs`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,C.jsx)(u,{className:`h-4 w-4`})})]})]}),(0,C.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-2`,children:L?(0,C.jsx)(`div`,{className:`flex h-24 items-center justify-center text-muted-foreground`,children:(0,C.jsx)(l,{className:`h-4 w-4 animate-spin`})}):I.length===0?(0,C.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-2 text-center text-muted-foreground`,children:[(0,C.jsx)(p,{className:`h-6 w-6 opacity-40`}),(0,C.jsx)(`p`,{className:`text-xs`,children:t(`workspace.noJobs`)})]}):(0,C.jsx)(`ul`,{className:`space-y-1`,children:I.map(e=>(0,C.jsx)(`li`,{children:(0,C.jsxs)(`button`,{type:`button`,onClick:()=>F(e.id),className:d(`flex w-full flex-col gap-1 rounded-lg border border-border/50 bg-surface/30 px-2.5 py-2 text-left transition-colors`,`hover:border-accent-primary/40 hover:bg-surface/60`),children:[(0,C.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,C.jsx)(h,{variant:E[e.status]??`queued`,children:n(`statusLabel.${e.status in E?e.status:`queued`}`)}),e.status===`running`&&(0,C.jsx)(l,{className:`h-3 w-3 animate-spin text-accent-primary`}),(0,C.jsx)(`span`,{className:`ml-auto text-[10px] text-muted-foreground`,children:(()=>{let t=v(y(e));return t?f(t,{addSuffix:!0,locale:r()}):`—`})()})]}),(0,C.jsx)(`code`,{className:`truncate font-mono text-xs text-foreground/85`,children:x(e.command,k)})]})},e.id))})}),P&&(0,C.jsx)(b,{jobId:P,onClose:()=>F(null)})]})}export{D as AgentModeJobsPane};