specrails-desktop 2.49.2 → 2.51.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.
- package/client/dist/assets/ActivityFeedPage-Bu6_Fxfa.js +1 -0
- package/client/dist/assets/{AgentBrowserCapture-DBGaKW4u.js → AgentBrowserCapture-ChIVaQ4N.js} +1 -1
- package/client/dist/assets/AgentModeAnalyticsPane-Dq59o2ZO.js +2 -0
- package/client/dist/assets/AgentModeCodePane-VjaDQOAZ.js +2 -0
- package/client/dist/assets/{AgentModeJobsPane-DkhcBtoZ.js → AgentModeJobsPane-DQST3Y8L.js} +1 -1
- package/client/dist/assets/AgentsPage-9ajYQTPV.js +87 -0
- package/client/dist/assets/{AnalyticsPage-DisrtBr7.js → AnalyticsPage-DgHAcKnO.js} +1 -1
- package/client/dist/assets/CodePage-tDBdWNkc.js +3 -0
- package/client/dist/assets/{DesktopAnalyticsPage-BFB-Pn-D.js → DesktopAnalyticsPage-fxggfmsY.js} +1 -1
- package/client/dist/assets/{DocsDialog-BwiFrwEJ.js → DocsDialog-0J6gUakl.js} +1 -1
- package/client/dist/assets/{DocsPage-ByS0ZCco.js → DocsPage-bQ6h2xx0.js} +1 -1
- package/client/dist/assets/{ExportDropdown-IPutNYvD.js → ExportDropdown-y2k4CoRJ.js} +1 -1
- package/client/dist/assets/InteractiveJobComposer-BI-y4fFH.js +19 -0
- package/client/dist/assets/{JobDetailModal-BnO_V8KR.js → JobDetailModal-B4cur32x.js} +1 -1
- package/client/dist/assets/JobDetailPage--VZYZ76E.js +1 -0
- package/client/dist/assets/JobsPage-K4wj2mXV.js +1 -0
- package/client/dist/assets/{LoopBuilderPage-WmqNpDw2.js → LoopBuilderPage-Cu9bNaZf.js} +2 -2
- package/client/dist/assets/{LoopPreviewModal-BY5dDezY.js → LoopPreviewModal-DmwboMLZ.js} +1 -1
- package/client/dist/assets/{LoopsPage-BcegqJyY.js → LoopsPage-Db8wSZSW.js} +1 -1
- package/client/dist/assets/{MinimizedChatsContext-CX1i2kQ8.js → MinimizedChatsContext-CoRyZxu4.js} +1 -1
- package/client/dist/assets/{PluginsPage-BhG3qPda.js → PluginsPage-A4dSzbGE.js} +2 -2
- package/client/dist/assets/{ProjectSettingsDialog-JQdLwCy2.js → ProjectSettingsDialog-DLrka37M.js} +1 -1
- package/client/dist/assets/{RepositoryDeliveries-DqmlG0Zs.js → RepositoryDeliveries-FYr8nbCo.js} +1 -1
- package/client/dist/assets/{RepositoryScopeSelector-DG8KKPrm.js → RepositoryScopeSelector-CBkDsqpz.js} +1 -1
- package/client/dist/assets/ReviewPacketPage-BGsesCFL.js +4 -0
- package/client/dist/assets/{TemplatePreviewModal-1AVv-hu4.js → TemplatePreviewModal-uGbE-mTU.js} +1 -1
- package/client/dist/assets/TicketDetailModalContext-lmkauO0-.js +16 -0
- package/client/dist/assets/{Trans-BLljsfHR.js → Trans-92vqs9mz.js} +1 -1
- package/client/dist/assets/{agent-BII69Nc0.js → agent-BaG10AN6.js} +1 -1
- package/client/dist/assets/{agent-CYFBDwFD.js → agent-CH4aJ884.js} +1 -1
- package/client/dist/assets/{agent-CVeMLIu4.js → agent-CLc9fA7v.js} +1 -1
- package/client/dist/assets/{agent-B76BhAyE.js → agent-DHh9-AdL.js} +1 -1
- package/client/dist/assets/{agent-DSrflYFL.js → agent-DkKnd6Wv.js} +1 -1
- package/client/dist/assets/{agent-BIO4q6b0.js → agent-aiVhqFW1.js} +1 -1
- package/client/dist/assets/{agent-ButS6kwl.js → agent-dbznD3eO.js} +1 -1
- package/client/dist/assets/{agent-D3jkMipn.js → agent-sMVFcPwL.js} +1 -1
- package/client/dist/assets/{formatDistanceToNow-CbQZkD8M.js → formatDistanceToNow-Cuoagaiu.js} +1 -1
- package/client/dist/assets/{getTimezoneOffsetInMilliseconds-pBVK3rJC.js → getTimezoneOffsetInMilliseconds-BLaUfsdD.js} +1 -1
- package/client/dist/assets/index-BAtqmAZR.css +2 -0
- package/client/dist/assets/index-Cxdhikml.js +80 -0
- package/client/dist/assets/{jira-api-f-sYCIuX.js → jira-api-DqYxW5BY.js} +1 -1
- package/client/dist/assets/layers-eDMjG41I.js +1 -0
- package/client/dist/assets/{packet-DQ_GnT2b.js → packet-CjS_478C.js} +1 -1
- package/client/dist/assets/{packet-r7J14m89.js → packet-D69dKsHN.js} +1 -1
- package/client/dist/assets/{packet-DF-iwqqY.js → packet-D9rU6Oxo.js} +1 -1
- package/client/dist/assets/{packet-Nb8BLI5h.js → packet-DMDFoamg.js} +1 -1
- package/client/dist/assets/{packet-C0pcMd6x.js → packet-Dd2RMs1h.js} +1 -1
- package/client/dist/assets/{packet-BsRimSfZ.js → packet-DjC9OibC.js} +1 -1
- package/client/dist/assets/packet-DwPtJoDz.js +1 -0
- package/client/dist/assets/{packet-C8qzvgrZ.js → packet-ceahDg8_.js} +1 -1
- package/client/dist/assets/{project-repositories-DAjJbFhm.js → project-repositories-DbVfkVQJ.js} +1 -1
- package/client/dist/assets/rotate-ccw-Wh4id13q.js +1 -0
- package/client/dist/assets/specs-Bqvtz2kz.js +1 -0
- package/client/dist/assets/specs-CKes-kz6.js +1 -0
- package/client/dist/assets/specs-CfXxPDNB.js +1 -0
- package/client/dist/assets/specs-CyF9HuTI.js +1 -0
- package/client/dist/assets/specs-DMj035Mt.js +1 -0
- package/client/dist/assets/specs-DfIdoU5L.js +1 -0
- package/client/dist/assets/specs-j5pGLQeU.js +1 -0
- package/client/dist/assets/specs-xW5pkkB7.js +1 -0
- package/client/dist/assets/{spending-DJBbdJyD.js → spending-ul_XBA3M.js} +1 -1
- package/client/dist/assets/{tickets-Bc71ce1C.js → tickets--tiSOCcn.js} +1 -1
- package/client/dist/assets/{tickets-CLg7VTJ8.js → tickets-BUJ3DMWU.js} +1 -1
- package/client/dist/assets/{tickets-CZNBiHbq.js → tickets-C1WNPODq.js} +1 -1
- package/client/dist/assets/{tickets-DlX2mEkD.js → tickets-CDjhWmiE.js} +1 -1
- package/client/dist/assets/{tickets-B4rjuSYi.js → tickets-CLgPC3uO.js} +1 -1
- package/client/dist/assets/tickets-D41ZMQpf.js +1 -0
- package/client/dist/assets/{tickets-CP9U1GJt.js → tickets-DEaQC06P.js} +1 -1
- package/client/dist/assets/{tickets-_yKvCt4Y.js → tickets-kcMzbLCp.js} +1 -1
- package/client/dist/assets/{useDesktop-BJ8IRBRt.js → useDesktop-BC_4XGnf.js} +1 -1
- package/client/dist/assets/{useRuntimeRuns-Ch1KUc7k.js → useRuntimeRuns-B_YsBTsN.js} +1 -1
- package/client/dist/assets/{useSharedWebSocket-BN3Lmehi.js → useSharedWebSocket-8NyZpT6v.js} +2 -2
- package/client/dist/assets/zap-CUOlvtT1.js +1 -0
- package/client/dist/index.html +22 -20
- package/docs/creating-specs.md +31 -0
- package/docs/guide/de/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/en/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/es/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/fr/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/it/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/ja/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/pt/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/guide/zh/specs/1-specs-and-the-backlog.md +4 -0
- package/docs/internals/safe-pr-review-flow.md +80 -0
- package/docs/internals/spec-addenda.md +166 -0
- package/docs/mcp.md +1 -1
- package/package.json +1 -1
- package/server/dist/agent-context-resolver.js +5 -0
- package/server/dist/agent-operator-prompt.js +41 -1
- package/server/dist/db.js +22 -0
- package/server/dist/jira/jira-materializer.js +3 -0
- package/server/dist/loop-run-manager.js +6 -1
- package/server/dist/mcp/guide.js +10 -0
- package/server/dist/mcp/tools/rails.js +24 -0
- package/server/dist/mcp/tools/specs.js +68 -3
- package/server/dist/multi-repo-delivery.js +4 -0
- package/server/dist/pr-follow-up-scope.js +224 -0
- package/server/dist/pr-follow-up.js +75 -0
- package/server/dist/project-registry.js +43 -0
- package/server/dist/project-router-tickets.js +223 -0
- package/server/dist/queue-manager.js +34 -1
- package/server/dist/rail-isolated-launch.js +16 -0
- package/server/dist/rail-launch-parser.js +12 -0
- package/server/dist/rail-pr-decision.js +20 -3
- package/server/dist/rail-pr-store.js +40 -3
- package/server/dist/rail-pr-ticket-effects.js +21 -0
- package/server/dist/rails-router.js +63 -3
- package/server/dist/review-packet.js +45 -0
- package/server/dist/spec-addenda-core.js +281 -0
- package/server/dist/spec-addenda.js +338 -0
- package/server/dist/ticket-store.js +5 -1
- package/client/dist/assets/ActivityFeedPage-CyOxof-U.js +0 -1
- package/client/dist/assets/AgentModeAnalyticsPane-WZpPaNMa.js +0 -2
- package/client/dist/assets/AgentModeCodePane-nHYnJUdP.js +0 -2
- package/client/dist/assets/AgentsPage-CX90q-nY.js +0 -87
- package/client/dist/assets/CodePage-ixqxftCT.js +0 -3
- package/client/dist/assets/InteractiveJobComposer-BEok7ntM.js +0 -19
- package/client/dist/assets/JobDetailPage-BnS8aHKD.js +0 -1
- package/client/dist/assets/JobsPage-BC0mq-MF.js +0 -1
- package/client/dist/assets/ReviewPacketPage-DSSi3x16.js +0 -4
- package/client/dist/assets/TicketDetailModalContext-D2MEhRwJ.js +0 -14
- package/client/dist/assets/index-DEqG4WdV.js +0 -80
- package/client/dist/assets/index-UDzndadF.css +0 -2
- package/client/dist/assets/packet-BTRySHoQ.js +0 -1
- package/client/dist/assets/specs-BcyxaCwf.js +0 -1
- package/client/dist/assets/specs-C1q9geAi.js +0 -1
- package/client/dist/assets/specs-CLZKysq-.js +0 -1
- package/client/dist/assets/specs-DII0C8gw.js +0 -1
- package/client/dist/assets/specs-DZMS9o54.js +0 -1
- package/client/dist/assets/specs-Dm6zUI-R.js +0 -1
- package/client/dist/assets/specs-V3TvhKLX.js +0 -1
- package/client/dist/assets/specs-dV3Mq5Mu.js +0 -1
- package/client/dist/assets/tickets-W6pBmbrX.js +0 -1
- package/client/dist/assets/zap-CHo3aCD1.js +0 -1
|
@@ -0,0 +1,338 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.NO_SPEC_ADDENDA = void 0;
|
|
18
|
+
exports.specAddendumHash = specAddendumHash;
|
|
19
|
+
exports.ticketStorePathForProject = ticketStorePathForProject;
|
|
20
|
+
exports.buildSpecAddendum = buildSpecAddendum;
|
|
21
|
+
exports.appendSpecAddendum = appendSpecAddendum;
|
|
22
|
+
exports.editSpecAddendum = editSpecAddendum;
|
|
23
|
+
exports.setSpecAddendumStatus = setSpecAddendumStatus;
|
|
24
|
+
exports.removeSpecAddendum = removeSpecAddendum;
|
|
25
|
+
exports.planSpecAddenda = planSpecAddenda;
|
|
26
|
+
exports.planSpecAddendaAt = planSpecAddendaAt;
|
|
27
|
+
exports.claimSpecAddenda = claimSpecAddenda;
|
|
28
|
+
exports.claimSpecAddendaForRun = claimSpecAddendaForRun;
|
|
29
|
+
exports.settleSpecAddenda = settleSpecAddenda;
|
|
30
|
+
exports.settleSpecAddendaAt = settleSpecAddendaAt;
|
|
31
|
+
exports.reopenSpecAddenda = reopenSpecAddenda;
|
|
32
|
+
exports.broadcastSpecAddendaChange = broadcastSpecAddendaChange;
|
|
33
|
+
// ─── Spec addenda — the Node half (ids, hashing, ticket-store lifecycle) ─────
|
|
34
|
+
// See server/spec-addenda-core.ts for the contract and the WHY. This module
|
|
35
|
+
// owns everything that touches the ticket store: creating/editing addenda on a
|
|
36
|
+
// ticket, CLAIMING them for a launch (open → in_flight), SETTLING them when the
|
|
37
|
+
// job/run ends (in_flight → applied, or back to open on failure/cancel) and
|
|
38
|
+
// REOPENING them when a delivery is discarded. Every mutation goes through
|
|
39
|
+
// `mutateStore` (advisory lock + atomic rename) and never touches any other
|
|
40
|
+
// ticket field — in particular never `description`.
|
|
41
|
+
const crypto_1 = require("crypto");
|
|
42
|
+
const ids_1 = require("./ids");
|
|
43
|
+
const ticket_store_1 = require("./ticket-store");
|
|
44
|
+
const workspace_resolution_1 = require("./workspace-resolution");
|
|
45
|
+
const spec_addenda_core_1 = require("./spec-addenda-core");
|
|
46
|
+
__exportStar(require("./spec-addenda-core"), exports);
|
|
47
|
+
function specAddendumHash(input) {
|
|
48
|
+
return (0, crypto_1.createHash)('sha256').update((0, spec_addenda_core_1.addendumCanonicalContent)(input)).digest('hex');
|
|
49
|
+
}
|
|
50
|
+
/** The ticket store a project's addenda live in (workspace when relocated, else the repo). */
|
|
51
|
+
function ticketStorePathForProject(project) {
|
|
52
|
+
const exec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: project.slug, path: project.path });
|
|
53
|
+
return exec.relocated ? exec.ticketsPath : (0, ticket_store_1.resolveTicketStoragePath)(project.path);
|
|
54
|
+
}
|
|
55
|
+
function buildSpecAddendum(input, meta) {
|
|
56
|
+
const now = meta.now ?? new Date().toISOString();
|
|
57
|
+
return {
|
|
58
|
+
id: (0, ids_1.newId)(),
|
|
59
|
+
version: 1,
|
|
60
|
+
kind: input.kind,
|
|
61
|
+
title: input.title,
|
|
62
|
+
body: input.body,
|
|
63
|
+
status: 'open',
|
|
64
|
+
hash: specAddendumHash(input),
|
|
65
|
+
created_at: now,
|
|
66
|
+
updated_at: now,
|
|
67
|
+
created_by: meta.createdBy,
|
|
68
|
+
origin_conversation_id: meta.originConversationId ?? null,
|
|
69
|
+
run_id: null,
|
|
70
|
+
applied_at: null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** Append an addendum to a ticket inside an open store mutation. Throws the typed cap error. */
|
|
74
|
+
function appendSpecAddendum(ticket, addendum) {
|
|
75
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
76
|
+
if (addenda.length >= spec_addenda_core_1.SPEC_ADDENDA_MAX_PER_TICKET) {
|
|
77
|
+
throw new spec_addenda_core_1.SpecAddendumValidationError('too_many_addenda', `a spec carries at most ${spec_addenda_core_1.SPEC_ADDENDA_MAX_PER_TICKET} addenda`);
|
|
78
|
+
}
|
|
79
|
+
addenda.push(addendum);
|
|
80
|
+
ticket.addenda = addenda;
|
|
81
|
+
ticket.updated_at = addendum.updated_at;
|
|
82
|
+
return addendum;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Edit an addendum's content (kind/title/body) in place. Only `open` and
|
|
86
|
+
* `dismissed` addenda are editable: an in-flight one is frozen inside a running
|
|
87
|
+
* generation and an applied one is history — the hash proves what a run got.
|
|
88
|
+
*/
|
|
89
|
+
function editSpecAddendum(ticket, addendumId, input, now = new Date().toISOString()) {
|
|
90
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
91
|
+
const target = addenda.find((a) => a.id === addendumId);
|
|
92
|
+
if (!target)
|
|
93
|
+
return 'not_found';
|
|
94
|
+
if (target.status === 'in_flight')
|
|
95
|
+
return 'in_flight';
|
|
96
|
+
if (target.status === 'applied')
|
|
97
|
+
return 'applied';
|
|
98
|
+
target.kind = input.kind;
|
|
99
|
+
target.title = input.title;
|
|
100
|
+
target.body = input.body;
|
|
101
|
+
target.hash = specAddendumHash(input);
|
|
102
|
+
target.updated_at = now;
|
|
103
|
+
ticket.addenda = addenda;
|
|
104
|
+
ticket.updated_at = now;
|
|
105
|
+
return target;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* User-driven status moves: dismiss an open/applied addendum, or reopen a
|
|
109
|
+
* dismissed/applied one so the next launch carries it again. An in-flight
|
|
110
|
+
* addendum belongs to its run until that run settles.
|
|
111
|
+
*/
|
|
112
|
+
function setSpecAddendumStatus(ticket, addendumId, status, now = new Date().toISOString(), opts) {
|
|
113
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
114
|
+
const target = addenda.find((a) => a.id === addendumId);
|
|
115
|
+
if (!target)
|
|
116
|
+
return 'not_found';
|
|
117
|
+
// `force` is the user's escape hatch for a run that vanished without a
|
|
118
|
+
// terminal callback (a purged job, a lost process): it releases the claim.
|
|
119
|
+
// Never taken by the automatic paths — only an explicit PATCH { force }.
|
|
120
|
+
if (target.status === 'in_flight' && !opts?.force)
|
|
121
|
+
return 'in_flight';
|
|
122
|
+
if (target.status !== status) {
|
|
123
|
+
target.status = status;
|
|
124
|
+
if (status === 'open') {
|
|
125
|
+
target.run_id = null;
|
|
126
|
+
target.applied_at = null;
|
|
127
|
+
}
|
|
128
|
+
target.updated_at = now;
|
|
129
|
+
ticket.updated_at = now;
|
|
130
|
+
}
|
|
131
|
+
ticket.addenda = addenda;
|
|
132
|
+
return target;
|
|
133
|
+
}
|
|
134
|
+
function removeSpecAddendum(ticket, addendumId, now = new Date().toISOString()) {
|
|
135
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
136
|
+
const target = addenda.find((a) => a.id === addendumId);
|
|
137
|
+
if (!target)
|
|
138
|
+
return 'not_found';
|
|
139
|
+
if (target.status === 'in_flight')
|
|
140
|
+
return 'in_flight';
|
|
141
|
+
ticket.addenda = addenda.filter((a) => a.id !== addendumId);
|
|
142
|
+
ticket.updated_at = now;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
// ─── Launch-time plan / claim ────────────────────────────────────────────────
|
|
146
|
+
/** Read (no mutation) the addenda a launch of these tickets would carry. */
|
|
147
|
+
function planSpecAddenda(store, ticketIds, runId) {
|
|
148
|
+
const entries = [];
|
|
149
|
+
for (const ticketId of ticketIds) {
|
|
150
|
+
const ticket = store.tickets[String(ticketId)];
|
|
151
|
+
if (!ticket)
|
|
152
|
+
continue;
|
|
153
|
+
const addenda = (0, spec_addenda_core_1.injectableAddenda)((0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda), runId);
|
|
154
|
+
if (addenda.length === 0)
|
|
155
|
+
continue;
|
|
156
|
+
entries.push({ ticketId, title: ticket.title ?? null, status: ticket.status ?? null, addenda: addenda.map((a) => ({ ...a })) });
|
|
157
|
+
}
|
|
158
|
+
return entries;
|
|
159
|
+
}
|
|
160
|
+
function planSpecAddendaAt(storePath, ticketIds, runId) {
|
|
161
|
+
try {
|
|
162
|
+
return planSpecAddenda((0, ticket_store_1.readStore)(storePath), ticketIds, runId);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Claim the planned addenda for a run inside an open store mutation: open →
|
|
170
|
+
* in_flight with `run_id`. Idempotent for the same run (a resume re-claims its
|
|
171
|
+
* own). Returns the ticket ids whose addenda changed (for broadcasts).
|
|
172
|
+
*/
|
|
173
|
+
function claimSpecAddenda(store, entries, runId, now = new Date().toISOString()) {
|
|
174
|
+
const changed = [];
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
const ticket = store.tickets[String(entry.ticketId)];
|
|
177
|
+
if (!ticket)
|
|
178
|
+
continue;
|
|
179
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
180
|
+
const wanted = new Set(entry.addenda.map((a) => a.id));
|
|
181
|
+
let touched = false;
|
|
182
|
+
for (const a of addenda) {
|
|
183
|
+
if (!wanted.has(a.id))
|
|
184
|
+
continue;
|
|
185
|
+
if (a.status === 'in_flight' && a.run_id === runId)
|
|
186
|
+
continue;
|
|
187
|
+
if (a.status !== 'open' && a.status !== 'in_flight')
|
|
188
|
+
continue;
|
|
189
|
+
a.status = 'in_flight';
|
|
190
|
+
a.run_id = runId;
|
|
191
|
+
a.updated_at = now;
|
|
192
|
+
touched = true;
|
|
193
|
+
}
|
|
194
|
+
if (touched) {
|
|
195
|
+
ticket.addenda = addenda;
|
|
196
|
+
ticket.updated_at = now;
|
|
197
|
+
changed.push(entry.ticketId);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return changed;
|
|
201
|
+
}
|
|
202
|
+
exports.NO_SPEC_ADDENDA = { entries: [], snapshot: [], briefing: '', changedTicketIds: [], store: null };
|
|
203
|
+
function claimSpecAddendaForRun(storePath, ticketIds, runId, opts) {
|
|
204
|
+
if (ticketIds.length === 0)
|
|
205
|
+
return exports.NO_SPEC_ADDENDA;
|
|
206
|
+
let entries = [];
|
|
207
|
+
let changedTicketIds = [];
|
|
208
|
+
let store = null;
|
|
209
|
+
try {
|
|
210
|
+
// A quick read first: most launches carry no addenda and must not take the
|
|
211
|
+
// store lock or rewrite the file for nothing.
|
|
212
|
+
const preview = opts?.plan ?? planSpecAddendaAt(storePath, ticketIds, runId);
|
|
213
|
+
if (preview.length === 0)
|
|
214
|
+
return exports.NO_SPEC_ADDENDA;
|
|
215
|
+
store = (0, ticket_store_1.mutateStore)(storePath, (s) => {
|
|
216
|
+
// Re-plan under the lock so a concurrent edit between read and claim can
|
|
217
|
+
// neither inject a stale body nor leave an addendum half-claimed. An
|
|
218
|
+
// explicit plan (a launch that froze the set earlier) is honoured as-is.
|
|
219
|
+
entries = opts?.plan
|
|
220
|
+
? opts.plan.filter((e) => Boolean(s.tickets[String(e.ticketId)]))
|
|
221
|
+
: planSpecAddenda(s, ticketIds, runId);
|
|
222
|
+
changedTicketIds = claimSpecAddenda(s, entries, runId, opts?.now);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
console.warn(`[spec-addenda] claim failed for run ${runId}: ${err.message}`);
|
|
227
|
+
return exports.NO_SPEC_ADDENDA;
|
|
228
|
+
}
|
|
229
|
+
if (entries.length === 0)
|
|
230
|
+
return exports.NO_SPEC_ADDENDA;
|
|
231
|
+
return { entries, snapshot: (0, spec_addenda_core_1.snapshotSpecAddenda)(entries), briefing: (0, spec_addenda_core_1.renderSpecAddendaBriefing)(entries), changedTicketIds, store };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Settle the addenda a run claimed, inside an open store mutation. The run id
|
|
235
|
+
* is the causal key: only addenda that are in_flight FOR THIS RUN move —
|
|
236
|
+
* `completed` ⇒ applied, anything else ⇒ back to open so the next launch
|
|
237
|
+
* carries them again. Returns the ticket ids that changed.
|
|
238
|
+
*/
|
|
239
|
+
function settleSpecAddenda(store, ticketIds, runId, outcome, now = new Date().toISOString()) {
|
|
240
|
+
const changed = [];
|
|
241
|
+
for (const ticketId of ticketIds) {
|
|
242
|
+
const ticket = store.tickets[String(ticketId)];
|
|
243
|
+
if (!ticket)
|
|
244
|
+
continue;
|
|
245
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
246
|
+
let touched = false;
|
|
247
|
+
for (const a of addenda) {
|
|
248
|
+
if (a.status !== 'in_flight' || a.run_id !== runId)
|
|
249
|
+
continue;
|
|
250
|
+
if (outcome === 'completed') {
|
|
251
|
+
a.status = 'applied';
|
|
252
|
+
a.applied_at = now;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
a.status = 'open';
|
|
256
|
+
a.run_id = null;
|
|
257
|
+
}
|
|
258
|
+
a.updated_at = now;
|
|
259
|
+
touched = true;
|
|
260
|
+
}
|
|
261
|
+
if (touched) {
|
|
262
|
+
ticket.addenda = addenda;
|
|
263
|
+
ticket.updated_at = now;
|
|
264
|
+
changed.push(ticketId);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return changed;
|
|
268
|
+
}
|
|
269
|
+
function settleSpecAddendaAt(storePath, ticketIds, runId, outcome) {
|
|
270
|
+
if (ticketIds.length === 0)
|
|
271
|
+
return { changedTicketIds: [], store: null };
|
|
272
|
+
try {
|
|
273
|
+
// Read-only probe first: settling a run whose specs never carried addenda
|
|
274
|
+
// must not take the lock or rewrite the store.
|
|
275
|
+
const probe = (0, ticket_store_1.readStore)(storePath);
|
|
276
|
+
const pending = ticketIds.some((id) => (0, spec_addenda_core_1.readSpecAddenda)(probe.tickets[String(id)]?.addenda).some((a) => a.status === 'in_flight' && a.run_id === runId));
|
|
277
|
+
if (!pending)
|
|
278
|
+
return { changedTicketIds: [], store: null };
|
|
279
|
+
let changedTicketIds = [];
|
|
280
|
+
const store = (0, ticket_store_1.mutateStore)(storePath, (s) => { changedTicketIds = settleSpecAddenda(s, ticketIds, runId, outcome); });
|
|
281
|
+
return { changedTicketIds, store };
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
console.warn(`[spec-addenda] settle failed for run ${runId}: ${err.message}`);
|
|
285
|
+
return { changedTicketIds: [], store: null };
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A discarded delivery destroyed the work its addenda were applied by: reopen
|
|
290
|
+
* exactly those (by id, from the delivery's frozen snapshot) so the next launch
|
|
291
|
+
* carries them again. Inside an open store mutation. Returns changed ticket ids.
|
|
292
|
+
*/
|
|
293
|
+
function reopenSpecAddenda(store, snapshot, now = new Date().toISOString()) {
|
|
294
|
+
const changed = [];
|
|
295
|
+
const byTicket = new Map();
|
|
296
|
+
for (const entry of snapshot) {
|
|
297
|
+
const set = byTicket.get(entry.ticketId) ?? new Set();
|
|
298
|
+
set.add(entry.id);
|
|
299
|
+
byTicket.set(entry.ticketId, set);
|
|
300
|
+
}
|
|
301
|
+
for (const [ticketId, ids] of byTicket) {
|
|
302
|
+
const ticket = store.tickets[String(ticketId)];
|
|
303
|
+
if (!ticket)
|
|
304
|
+
continue;
|
|
305
|
+
const addenda = (0, spec_addenda_core_1.readSpecAddenda)(ticket.addenda);
|
|
306
|
+
let touched = false;
|
|
307
|
+
for (const a of addenda) {
|
|
308
|
+
if (!ids.has(a.id) || a.status !== 'applied')
|
|
309
|
+
continue;
|
|
310
|
+
a.status = 'open';
|
|
311
|
+
a.run_id = null;
|
|
312
|
+
a.applied_at = null;
|
|
313
|
+
a.updated_at = now;
|
|
314
|
+
touched = true;
|
|
315
|
+
}
|
|
316
|
+
if (touched) {
|
|
317
|
+
ticket.addenda = addenda;
|
|
318
|
+
ticket.updated_at = now;
|
|
319
|
+
changed.push(ticketId);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return changed;
|
|
323
|
+
}
|
|
324
|
+
// ─── Broadcast ──────────────────────────────────────────────────────────────
|
|
325
|
+
/** Re-broadcast every ticket whose addenda a claim/settle moved (best-effort). */
|
|
326
|
+
function broadcastSpecAddendaChange(broadcast, projectId, result) {
|
|
327
|
+
if (!result.store)
|
|
328
|
+
return;
|
|
329
|
+
for (const tid of result.changedTicketIds) {
|
|
330
|
+
const ticket = result.store.tickets[String(tid)];
|
|
331
|
+
if (!ticket)
|
|
332
|
+
continue;
|
|
333
|
+
try {
|
|
334
|
+
broadcast({ type: 'ticket_updated', ticket, projectId, timestamp: ticket.updated_at });
|
|
335
|
+
}
|
|
336
|
+
catch { /* the file mutation is authoritative */ }
|
|
337
|
+
}
|
|
338
|
+
}
|
|
@@ -19,9 +19,10 @@ exports.isValidPriority = isValidPriority;
|
|
|
19
19
|
exports.validatePriorityForStatus = validatePriorityForStatus;
|
|
20
20
|
const fs_1 = __importDefault(require("fs"));
|
|
21
21
|
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const spec_addenda_core_1 = require("./spec-addenda-core");
|
|
22
23
|
const VALID_STATUSES = new Set(['draft', 'todo', 'in_progress', 'on_review', 'done', 'cancelled']);
|
|
23
24
|
const VALID_PRIORITIES = new Set(['critical', 'high', 'medium', 'low']);
|
|
24
|
-
exports.CURRENT_SCHEMA_VERSION = '1.
|
|
25
|
+
exports.CURRENT_SCHEMA_VERSION = '1.4';
|
|
25
26
|
exports.SHORT_SUMMARY_MAX_LEN = 240;
|
|
26
27
|
/**
|
|
27
28
|
* Sanitize a `shortSummary` value coming from an AI response or external input.
|
|
@@ -218,6 +219,9 @@ function normalizeTicket(t) {
|
|
|
218
219
|
if (!('short_summary' in t) || t.short_summary === undefined) {
|
|
219
220
|
t.short_summary = null;
|
|
220
221
|
}
|
|
222
|
+
// Schema 1.4 field: spec addenda. Absent ⇒ [], and a malformed entry is
|
|
223
|
+
// dropped rather than crashing the whole store read.
|
|
224
|
+
t.addenda = (0, spec_addenda_core_1.readSpecAddenda)(t.addenda);
|
|
221
225
|
return t;
|
|
222
226
|
}
|
|
223
227
|
/**
|
|
@@ -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{h as r,r as i}from"./useSharedWebSocket-BN3Lmehi.js";import{n as a}from"./createLucideIcon-Bjbbp_KS.js";import{a as o,r as s}from"./useDesktop-BJ8IRBRt.js";import{t as c}from"./circle-x-CMYsN4ZH.js";import{t as l}from"./loader-circle-DcygOQpC.js";import{t as u}from"./zap-CHo3aCD1.js";import{Gt as d,It as f,qt as p}from"./index-DEqG4WdV.js";var m=e(t(),1);function h(e){let t=new Set;return e.filter(e=>{let n=`${e.type}:${e.jobId}`;return t.has(n)?!1:(t.add(n),!0)})}function g({activeProjectId:e,limit:t=50}){let[n,a]=(0,m.useState)([]),[s,c]=(0,m.useState)(!1),[l,u]=(0,m.useState)(!0),d=(0,m.useRef)(e);(0,m.useEffect)(()=>{d.current=e},[e]);let{registerHandler:f,unregisterHandler:p}=i();(0,m.useEffect)(()=>{if(!e){a([]),u(!0);return}let n=!1;c(!0),a([]),u(!0);async function r(){let e=o();try{let r=await fetch(`${e}/activity?limit=${t}`);if(!r.ok||n)return;let i=await r.json();if(n)return;a(i),u(i.length===t)}catch{}finally{n||c(!1)}}return r(),()=>{n=!0}},[e,t]);let g=(0,m.useCallback)(async()=>{if(s||!l)return;c(!0);let e=o(),n=d.current;try{a(r=>{let i=r[r.length-1];if(!i)return r;let o=encodeURIComponent(i.timestamp);return fetch(`${e}/activity?limit=${t}&before=${o}`).then(e=>e.json()).then(e=>{if(d.current!==n){c(!1);return}a(t=>h([...t,...e])),u(e.length===t),c(!1)}).catch(()=>c(!1)),r})}catch{c(!1)}},[s,l,t]),_=(0,m.useCallback)(e=>{let t=e,n=d.current;if(!(!t||typeof t.type!=`string`)&&!(t.projectId&&t.projectId!==n)){if(t.type===`queue`&&Array.isArray(t.jobs)){let e=[];for(let n of t.jobs){let t=n.status===`completed`?`job_completed`:n.status===`failed`?`job_failed`:n.status===`canceled`?`job_canceled`:`job_started`;e.push({id:`${t}:${n.id}`,type:t,jobId:n.id,jobCommand:n.command??``,timestamp:n.startedAt??new Date().toISOString(),summary:`${t.replace(`_`,` `)}: ${n.command??``}`,costUsd:null})}e.length>0&&a(t=>h([...e,...t]))}if(t.type===`phase`&&t.phase&&t.state&&t.timestamp){let e={id:`phase:${t.phase}:${t.state}:${t.timestamp}`,type:`job_started`,jobId:`phase-${t.phase}`,jobCommand:r.t(`activity:feed.phaseCommand`,{phase:t.phase,state:t.state}),timestamp:t.timestamp,summary:`Phase ${t.phase} is ${t.state}`,costUsd:null};a(t=>h([e,...t]))}}},[]);return(0,m.useLayoutEffect)(()=>(f(`activity`,_),()=>p(`activity`)),[_,f,p]),{items:n,loading:s,hasMore:l,loadMore:g}}var _=n();function v(e,t){let n=Date.now()-new Date(e).getTime(),r=Math.floor(n/1e3);if(r<60)return t(`feed.relativeTime.seconds`,{value:r});let i=Math.floor(r/60);if(i<60)return t(`feed.relativeTime.minutes`,{value:i});let a=Math.floor(i/60);return a<24?t(`feed.relativeTime.hours`,{value:a}):t(`feed.relativeTime.days`,{value:Math.floor(a/24)})}function y({type:e}){switch(e){case`job_completed`:return(0,_.jsx)(f,{className:`w-4 h-4 text-green-500 aurora-light:text-accent-success flex-shrink-0`});case`job_failed`:return(0,_.jsx)(c,{className:`w-4 h-4 text-red-500 aurora-light:text-destructive flex-shrink-0`});case`job_canceled`:return(0,_.jsx)(d,{className:`w-4 h-4 text-muted-foreground flex-shrink-0`});default:return(0,_.jsx)(u,{className:`w-4 h-4 text-blue-500 aurora-light:text-accent-info flex-shrink-0`})}}function b(e,t){switch(e){case`job_completed`:return t(`common:status.completed`);case`job_failed`:return t(`common:status.failed`);case`job_canceled`:return t(`common:status.canceled`);default:return t(`feed.typeStarted`)}}function x(e){switch(e){case`job_completed`:return`text-green-500 aurora-light:text-accent-success`;case`job_failed`:return`text-red-500 aurora-light:text-destructive`;case`job_canceled`:return`text-muted-foreground`;default:return`text-blue-500 aurora-light:text-accent-info`}}function S(){let{t:e}=a(`activity`),{activeProjectId:t}=s(),{items:n,loading:r,hasMore:i,loadMore:o}=g({activeProjectId:t}),c=(0,m.useRef)(null);return(0,m.useEffect)(()=>{let e=c.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&i&&!r&&o()},{threshold:.1});return t.observe(e),()=>t.disconnect()},[i,r,o]),(0,_.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2 px-4 py-3 border-b border-border bg-background/50`,children:[(0,_.jsx)(p,{className:`w-4 h-4 text-muted-foreground`}),(0,_.jsx)(`h1`,{className:`text-sm font-medium`,children:e(`feed.title`)})]}),(0,_.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[r&&n.length===0?(0,_.jsx)(`div`,{className:`flex items-center justify-center h-32`,children:(0,_.jsx)(l,{className:`w-4 h-4 animate-spin text-muted-foreground`})}):n.length===0?(0,_.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-48 gap-2 text-muted-foreground`,children:[(0,_.jsx)(p,{className:`w-8 h-8 opacity-40`}),(0,_.jsx)(`p`,{className:`text-sm`,children:e(`feed.emptyTitle`)}),(0,_.jsx)(`p`,{className:`text-xs opacity-70`,children:e(`feed.emptyHint`)})]}):(0,_.jsx)(`ul`,{className:`divide-y divide-border/50`,children:n.map(t=>(0,_.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-2.5 hover:bg-accent/30 transition-colors`,children:[(0,_.jsx)(y,{type:t.type}),(0,_.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,_.jsx)(`p`,{className:`text-xs text-foreground truncate`,title:t.jobCommand,children:t.jobCommand}),(0,_.jsxs)(`div`,{className:`flex items-center gap-2 mt-0.5`,children:[(0,_.jsx)(`span`,{className:`text-xs font-medium ${x(t.type)}`,children:b(t.type,e)}),t.costUsd!=null&&(0,_.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`$`,t.costUsd.toFixed(4)]})]})]}),(0,_.jsx)(`span`,{className:`text-xs text-muted-foreground flex-shrink-0 tabular-nums`,children:v(t.timestamp,e)})]},`${t.type}:${t.jobId}`))}),(0,_.jsx)(`div`,{ref:c,className:`h-1`}),r&&n.length>0&&(0,_.jsx)(`div`,{className:`flex justify-center py-3`,children:(0,_.jsx)(l,{className:`w-4 h-4 animate-spin text-muted-foreground`})}),!i&&n.length>0&&(0,_.jsx)(`p`,{className:`text-center text-xs text-muted-foreground py-3`,children:e(`feed.allLoaded`)})]})]})}export{S as default};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AnalyticsPage-DisrtBr7.js","assets/rolldown-runtime-CNC7AqOf.js","assets/jsx-runtime-zu2_FqZY.js","assets/chunk-KS7C4IRE-DEKu087k.js","assets/preload-helper-Czpn1I53.js","assets/useSharedWebSocket-BN3Lmehi.js","assets/activity-DiyjsgQV.js","assets/addspec-BOvgmcgk.js","assets/agent-BIO4q6b0.js","assets/agentRuntime-bAAjw1vw.js","assets/agents-CTwbx-fb.js","assets/agentstudio-CN2pokQu.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BlypLLR6.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-DBAP2_SQ.js","assets/explore-DgBACn39.js","assets/integrations-mB-7zoyT.js","assets/jira-CKJg3HZd.js","assets/jobs-C9j2PuwW.js","assets/loops-B7YpGizO.js","assets/mcp-CUAN6ORK.js","assets/narration-n3hOA7LY.js","assets/nav-Ch-zHBG5.js","assets/packet-BTRySHoQ.js","assets/settings-HZSu-K4l.js","assets/setup-DpqzaEEA.js","assets/specs-DII0C8gw.js","assets/terminal-BAzpHtpY.js","assets/tickets-W6pBmbrX.js","assets/createLucideIcon-Bjbbp_KS.js","assets/Trans-BLljsfHR.js","assets/useDesktop-BJ8IRBRt.js","assets/react-dom-DiWzBDP9.js","assets/provider-capabilities-Vi1ZGvAK.js","assets/spending-DJBbdJyD.js","assets/clsx-CjueKrWZ.js","assets/formatDistanceToNow-CbQZkD8M.js","assets/getTimezoneOffsetInMilliseconds-pBVK3rJC.js","assets/index-DEqG4WdV.js","assets/TicketDetailModalContext-D2MEhRwJ.js","assets/save-B6wGWwBR.js","assets/MinimizedChatsContext-CX1i2kQ8.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/file-text-CFT-xXKN.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/wrench-BfmNO9Vw.js","assets/zap-CHo3aCD1.js","assets/dialog-xXB2q5HJ.js","assets/utils-BC4DHlz2.js","assets/lib-CGdyxIWg.js","assets/button-Ccc9Dc-D.js","assets/jira-api-f-sYCIuX.js","assets/RepositoryScopeSelector-DG8KKPrm.js","assets/project-repositories-DAjJbFhm.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-DqmlG0Zs.js","assets/useRuntimeRuns-Ch1KUc7k.js","assets/event-Bt7f3wXe.js","assets/index-UDzndadF.css","assets/ExportDropdown-IPutNYvD.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{St as c,U as l,xt as u}from"./index-DEqG4WdV.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./AnalyticsPage-DisrtBr7.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,77,78]))),m=420,h=560;function g(){let{t:e}=i(`agent`),{closeAnalyticsPane:t}=l(),[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)(u,{className:`h-4 w-4`}):(0,f.jsx)(c,{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-ixqxftCT.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-D2MEhRwJ.js","assets/useSharedWebSocket-BN3Lmehi.js","assets/activity-DiyjsgQV.js","assets/addspec-BOvgmcgk.js","assets/agent-BIO4q6b0.js","assets/agentRuntime-bAAjw1vw.js","assets/agents-CTwbx-fb.js","assets/agentstudio-CN2pokQu.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BlypLLR6.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-DBAP2_SQ.js","assets/explore-DgBACn39.js","assets/integrations-mB-7zoyT.js","assets/jira-CKJg3HZd.js","assets/jobs-C9j2PuwW.js","assets/loops-B7YpGizO.js","assets/mcp-CUAN6ORK.js","assets/narration-n3hOA7LY.js","assets/nav-Ch-zHBG5.js","assets/packet-BTRySHoQ.js","assets/settings-HZSu-K4l.js","assets/setup-DpqzaEEA.js","assets/specs-DII0C8gw.js","assets/terminal-BAzpHtpY.js","assets/tickets-W6pBmbrX.js","assets/createLucideIcon-Bjbbp_KS.js","assets/Trans-BLljsfHR.js","assets/useDesktop-BJ8IRBRt.js","assets/provider-capabilities-Vi1ZGvAK.js","assets/save-B6wGWwBR.js","assets/spending-DJBbdJyD.js","assets/MinimizedChatsContext-CX1i2kQ8.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/file-text-CFT-xXKN.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/wrench-BfmNO9Vw.js","assets/zap-CHo3aCD1.js","assets/dialog-xXB2q5HJ.js","assets/utils-BC4DHlz2.js","assets/clsx-CjueKrWZ.js","assets/lib-CGdyxIWg.js","assets/formatDistanceToNow-CbQZkD8M.js","assets/getTimezoneOffsetInMilliseconds-pBVK3rJC.js","assets/button-Ccc9Dc-D.js","assets/jira-api-f-sYCIuX.js","assets/RepositoryScopeSelector-DG8KKPrm.js","assets/project-repositories-DAjJbFhm.js","assets/index-DEqG4WdV.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-DqmlG0Zs.js","assets/useRuntimeRuns-Ch1KUc7k.js","assets/event-Bt7f3wXe.js","assets/index-UDzndadF.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{St as o,U as s,nt as c,tt as l,xt as u}from"./index-DEqG4WdV.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./CodePage-ixqxftCT.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]))),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=>{c(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)(u,{className:`h-4 w-4`}):(0,f.jsx)(o,{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:l(e,t).repositoryId,onRepositoryChange:n=>c(e,t,{repositoryId:n}),initialPath:l(e,t).path,onSelectedPathChange:k},O)})})]},O)}export{g as AgentModeCodePane};
|