@taskforcehq/taskforce 0.3.304 → 0.3.305
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/README.md +140 -247
- package/dist/TaskforceCore.js +165 -70
- package/dist/TaskforceCore.test.js +799 -90
- package/dist/compat/workspaceSyncCompat.js +6 -0
- package/dist/components/features/DocumentIndex.d.ts +1 -1
- package/dist/components/features/DocumentIndex.js +1 -1
- package/dist/components/features/DocumentViewer.d.ts +1 -1
- package/dist/components/features/DocumentViewer.js +32 -9
- package/dist/components/features/DocumentWorkspace.d.ts +5 -22
- package/dist/components/features/DocumentWorkspace.js +12 -155
- package/dist/components/features/DocumentWorkspace.test.js +193 -6
- package/dist/components/features/TaskSettings.js +29 -3
- package/dist/components/features/TaskSettings.test.js +42 -1
- package/dist/components/features/documentWorkspaceModel.d.ts +24 -0
- package/dist/components/features/documentWorkspaceModel.js +57 -0
- package/dist/components/features/useDocumentWorkspaceController.d.ts +34 -0
- package/dist/components/features/useDocumentWorkspaceController.js +113 -0
- package/dist/components/task/TaskForm.d.ts +8 -8
- package/dist/components/task/TaskForm.js +358 -221
- package/dist/components/task/TaskForm.test.js +456 -381
- package/dist/components/task/TaskKanban.js +2 -1
- package/dist/components/views/PlanComparisonPage.js +5 -8
- package/dist/components/views/PlanComparisonPage.test.js +51 -41
- package/dist/components/views/PlansPage.js +126 -84
- package/dist/components/views/PlansPage.test.js +308 -39
- package/dist/components/views/StandaloneLayout.js +28 -22
- package/dist/components/views/panels/FilterToolbar.test.js +6 -4
- package/dist/components/views/standalone/modals/AccountHubModal.d.ts +2 -14
- package/dist/components/views/standalone/modals/AccountHubModal.js +12 -14
- package/dist/components/views/standalone/modals/AccountHubModal.test.js +24 -1
- package/dist/config/envSchema.js +1 -1
- package/dist/core/AiProfileService.d.ts +6 -1
- package/dist/core/AiProfileService.js +161 -16
- package/dist/core/AiProfileService.test.js +3 -1
- package/dist/core/AiProfiles.test.js +200 -0
- package/dist/core/AuthTokenService.test.d.ts +1 -0
- package/dist/core/AuthTokenService.test.js +78 -0
- package/dist/core/EntitlementsPolicy.test.js +75 -13
- package/dist/core/PlanEntitlementService.d.ts +7 -1
- package/dist/core/PlanEntitlementService.js +117 -42
- package/dist/core/PlanVersionPolicy.test.js +19 -26
- package/dist/core/SignupMonetizationSettings.test.js +46 -21
- package/dist/core/SystemAdmin.test.js +212 -56
- package/dist/core/TaskTaxonomyValidation.test.js +53 -0
- package/dist/core/Taskforce.d.ts +3 -0
- package/dist/core/Taskforce.js +50 -10
- package/dist/core/WorkspacePlanMode.test.js +12 -12
- package/dist/core/shared.d.ts +2 -0
- package/dist/core/shared.js +11 -0
- package/dist/hooks/sync/auth.js +3 -1
- package/dist/hooks/sync/transfers.d.ts +2 -1
- package/dist/hooks/sync/transfers.js +8 -4
- package/dist/hooks/useSyncOrchestrator.d.ts +7 -4
- package/dist/hooks/useSyncOrchestrator.js +75 -7
- package/dist/hooks/useSyncOrchestrator.retry-closure.test.js +80 -10
- package/dist/hooks/useTaskMutations.d.ts +2 -1
- package/dist/hooks/useTaskMutations.js +12 -1
- package/dist/hooks/useTaskMutations.test.js +30 -1
- package/dist/hooks/useTaskforce.d.ts +5 -2
- package/dist/hooks/useTaskforce.js +17 -5
- package/dist/hooks/useTaskforce.sync-behavior.test.js +78 -0
- package/dist/hooks/useWorkspaceSyncController.d.ts +3 -1
- package/dist/hooks/useWorkspaceSyncController.js +11 -1
- package/dist/hooks/useWorkspaceSyncController.test.js +1 -0
- package/dist/mcp/adminWorkspaceRegistrar.d.ts +2 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +154 -0
- package/dist/mcp/collaborationRegistrar.d.ts +2 -0
- package/dist/mcp/collaborationRegistrar.js +71 -0
- package/dist/mcp/documentAssetRegistrar.d.ts +2 -0
- package/dist/mcp/documentAssetRegistrar.js +346 -0
- package/dist/mcp/runtime.js +2362 -3530
- package/dist/mcp/runtime.test.js +159 -0
- package/dist/mcp/taskPlanningRegistrar.d.ts +2 -0
- package/dist/mcp/taskPlanningRegistrar.js +418 -0
- package/dist/mcp/toolCatalog.d.ts +35 -0
- package/dist/mcp/toolCatalog.js +3 -0
- package/dist/server/routes/admin.d.ts +1 -5
- package/dist/server/routes/admin.js +138 -61
- package/dist/server/routes/annotatedAttachments.d.ts +1 -1
- package/dist/server/routes/annotatedAttachments.js +1 -1
- package/dist/server/routes/auth.d.ts +1 -4
- package/dist/server/routes/auth.js +23 -63
- package/dist/server/routes/authSupport.d.ts +30 -0
- package/dist/server/routes/authSupport.js +81 -0
- package/dist/server/routes/billing.d.ts +1 -1
- package/dist/server/routes/billing.js +104 -188
- package/dist/server/routes/billing.test.js +214 -86
- package/dist/server/routes/documentReviews.d.ts +1 -1
- package/dist/server/routes/documentReviews.js +1 -1
- package/dist/server/routes/documents.d.ts +4 -2
- package/dist/server/routes/documents.js +73 -7
- package/dist/server/routes/primitives.d.ts +11 -0
- package/dist/server/routes/primitives.js +73 -0
- package/dist/server/routes/resources.d.ts +1 -1
- package/dist/server/routes/resources.js +1 -1
- package/dist/server/routes/shared.d.ts +1 -1
- package/dist/server/routes/sync.d.ts +1 -1
- package/dist/server/routes/sync.js +1 -1
- package/dist/server/routes/tasks.d.ts +1 -1
- package/dist/server/routes/tasks.js +1 -1
- package/dist/server/routes/workspaces.d.ts +1 -1
- package/dist/server/routes/workspaces.js +1 -1
- package/dist/server/routes.d.ts +2 -9
- package/dist/server/routes.js +76 -162
- package/dist/server/routes.test.js +672 -30
- package/dist/sync/contentSyncState.js +16 -7
- package/dist/sync/syncApplyHandlers.test.js +2 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +8 -0
- package/dist/sync/syncService.test.js +14 -0
- package/dist/sync/workspaceSyncModel.d.ts +3 -0
- package/dist/sync/workspaceSyncModel.js +12 -3
- package/dist/sync/workspaceSyncModel.test.js +34 -0
- package/dist/sync/workspaceSyncState.d.ts +2 -0
- package/dist/sync/workspaceSyncState.js +1 -0
- package/dist/ui/assets/{AgentsModule-BLWVbuKP.js → AgentsModule-N2MnQBZk.js} +1 -1
- package/dist/ui/assets/{AnnotatedAttachmentWorkspace-BlS-cqnl.js → AnnotatedAttachmentWorkspace-BG6P_GVW.js} +1 -1
- package/dist/ui/assets/DocumentWorkspace-B3nV_Gc5.css +1 -0
- package/dist/ui/assets/DocumentWorkspace-DRbDMwh8.js +252 -0
- package/dist/ui/assets/{InitiativesModule-BjR6iBf9.js → InitiativesModule-Dhm7M8e7.js} +1 -1
- package/dist/ui/assets/PlansPage-Cq0zXj3I.js +1 -0
- package/dist/ui/assets/TaskSettings-ln0aF7xc.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-DnFqdUME.js → WorkflowsModule-BcS4afRn.js} +1 -1
- package/dist/ui/assets/{index-Ii0B0rTO.css → index-C2-OXZV7.css} +1 -1
- package/dist/ui/assets/index-DcSI5F86.js +6 -0
- package/dist/ui/assets/{vendor-icons-I7ZwG1z_.js → vendor-icons-BSUaRwF8.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/commercialLifecyclePresentation.d.ts +19 -0
- package/dist/utils/commercialLifecyclePresentation.js +196 -0
- package/package.json +8 -1
- package/scripts/check-cloud-mcp.mjs +83 -0
- package/scripts/playwright-auth.sh +5 -1
- package/scripts/run-billing-performance-smoke.sh +24 -0
- package/dist/ui/assets/DocumentWorkspace-BH_6DF6x.js +0 -250
- package/dist/ui/assets/DocumentWorkspace-C_8T8oz-.css +0 -1
- package/dist/ui/assets/PlansPage-CSDQ4sLa.js +0 -1
- package/dist/ui/assets/TaskSettings-CEDy34Jo.js +0 -9
- package/dist/ui/assets/index-DXUdtH1B.js +0 -6
|
@@ -533,15 +533,25 @@ export async function loadWorkspaceSyncDocumentPayload(deps, basePath, workspace
|
|
|
533
533
|
const absolutePath = path.resolve(path.join(root, normalizedPath));
|
|
534
534
|
if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`))
|
|
535
535
|
return null;
|
|
536
|
+
const objectStorageClient = deps.getObjectStorageClient();
|
|
537
|
+
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(normalizedPath, workspaceId);
|
|
536
538
|
let content = '';
|
|
537
539
|
let stat = null;
|
|
538
540
|
try {
|
|
539
|
-
if (
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
541
|
+
if (canonicalAsset?.kind === 'document' && canonicalAsset.storageProvider === 'r2' && objectStorageClient) {
|
|
542
|
+
const object = await objectStorageClient.getObject(normalizedPath);
|
|
543
|
+
if (!object?.body)
|
|
544
|
+
return null;
|
|
545
|
+
content = object.body.toString('utf8');
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
if (!fs.existsSync(absolutePath))
|
|
549
|
+
return null;
|
|
550
|
+
stat = fs.statSync(absolutePath);
|
|
551
|
+
if (!stat.isFile())
|
|
552
|
+
return null;
|
|
553
|
+
content = fs.readFileSync(absolutePath, 'utf8');
|
|
554
|
+
}
|
|
545
555
|
}
|
|
546
556
|
catch (error) {
|
|
547
557
|
deps.recordSyncDiagnostic(workspaceId, 'pull', 'Failed to load targeted sync document payload.', {
|
|
@@ -558,7 +568,6 @@ export async function loadWorkspaceSyncDocumentPayload(deps, basePath, workspace
|
|
|
558
568
|
return next;
|
|
559
569
|
})();
|
|
560
570
|
const cached = workspaceCache.get(normalizedPath);
|
|
561
|
-
const canonicalAsset = deps.workspaceAssetStore?.getByStorageKey(normalizedPath, workspaceId);
|
|
562
571
|
let updatedAt = '';
|
|
563
572
|
if (canonicalAsset?.kind === 'document') {
|
|
564
573
|
updatedAt = resolveCanonicalAssetSyncLinkState(deps, canonicalAsset, workspaceId).effectiveUpdatedAt;
|
|
@@ -76,10 +76,12 @@ describe('syncApplyHandlers', () => {
|
|
|
76
76
|
{
|
|
77
77
|
op: 'delete',
|
|
78
78
|
taskId: 'task-1',
|
|
79
|
+
deletedAt: '2026-04-10T11:00:00.000Z',
|
|
79
80
|
},
|
|
80
81
|
{
|
|
81
82
|
op: 'delete',
|
|
82
83
|
taskId: 'task-stale',
|
|
84
|
+
deletedAt: '2026-04-10T08:00:00.000Z',
|
|
83
85
|
},
|
|
84
86
|
],
|
|
85
87
|
normalizeWorkspaceSyncDocumentPath: (rawPath) => typeof rawPath === 'string' ? rawPath : null,
|
package/dist/sync/syncService.js
CHANGED
|
@@ -45,6 +45,14 @@ export async function ensureCloudWorkspaceReadyForSyncService(input) {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
if (handshakeResult.status === 409 && data.code === 'WORKSPACE_ID_MISMATCH') {
|
|
48
|
+
if (input.allowProvisionOnMismatch === false) {
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
statusCode: 409,
|
|
52
|
+
transient: false,
|
|
53
|
+
error: String(data.error || 'Selected cloud workspace could not be attached to this local workspace.')
|
|
54
|
+
};
|
|
55
|
+
}
|
|
48
56
|
const provisionResult = await provisionWorkspace(input.resolveCloudAuthUrl, {
|
|
49
57
|
workspaceId: input.workspaceId,
|
|
50
58
|
name: input.workspaceName || input.workspaceId
|
|
@@ -743,6 +743,20 @@ describe('syncService', () => {
|
|
|
743
743
|
expect(res.error).toContain('already linked to another cloud account');
|
|
744
744
|
expect(res.error).toContain('grant you access');
|
|
745
745
|
});
|
|
746
|
+
it('does not provision a new cloud workspace during attach-cloud mismatch handling', async () => {
|
|
747
|
+
vi.mocked(handshakeWorkspace).mockResolvedValueOnce({
|
|
748
|
+
ok: false,
|
|
749
|
+
status: 409,
|
|
750
|
+
data: { code: 'WORKSPACE_ID_MISMATCH', error: 'Workspace mismatch' }
|
|
751
|
+
});
|
|
752
|
+
const res = await ensureCloudWorkspaceReadyForSyncService({
|
|
753
|
+
...baseHandshakeInput,
|
|
754
|
+
allowProvisionOnMismatch: false
|
|
755
|
+
});
|
|
756
|
+
expect(res.success).toBe(false);
|
|
757
|
+
expect(res.statusCode).toBe(409);
|
|
758
|
+
expect(provisionWorkspace).not.toHaveBeenCalled();
|
|
759
|
+
});
|
|
746
760
|
});
|
|
747
761
|
describe('syncUserGlobalSettingsService transient metadata', () => {
|
|
748
762
|
beforeEach(() => {
|
|
@@ -118,6 +118,8 @@ export type WorkspaceSyncChange = {
|
|
|
118
118
|
} | {
|
|
119
119
|
op: 'delete';
|
|
120
120
|
taskId: string;
|
|
121
|
+
deletedAt?: string;
|
|
122
|
+
watermark?: string;
|
|
121
123
|
} | {
|
|
122
124
|
op: 'initiative-upsert';
|
|
123
125
|
initiative: WorkspaceSyncInitiativeSnapshot;
|
|
@@ -258,6 +260,7 @@ export declare function buildWorkspaceSyncPayloadModel(input: {
|
|
|
258
260
|
archivedTasks: TaskItem[];
|
|
259
261
|
lastPushedTaskIds: Set<string>;
|
|
260
262
|
pendingDeletedTaskIds: Set<string>;
|
|
263
|
+
pendingDeletedTaskWatermarks?: Map<string, string>;
|
|
261
264
|
initiatives?: InitiativeItem[];
|
|
262
265
|
workstreams?: WorkstreamItem[];
|
|
263
266
|
taxonomies?: unknown[];
|
|
@@ -25,6 +25,9 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
25
25
|
const pendingDeleteIds = new Set(Array.from(input.pendingDeletedTaskIds)
|
|
26
26
|
.map((taskId) => String(taskId || '').trim())
|
|
27
27
|
.filter((taskId) => taskId.length > 0));
|
|
28
|
+
const pendingDeleteWatermarks = new Map(Array.from(input.pendingDeletedTaskWatermarks || new Map())
|
|
29
|
+
.map(([taskId, deletedAt]) => [String(taskId || '').trim(), String(deletedAt || '').trim()])
|
|
30
|
+
.filter(([taskId, deletedAt]) => taskId.length > 0 && Number.isFinite(Date.parse(deletedAt))));
|
|
28
31
|
const lastWatermarks = input.lastPushedWatermarks;
|
|
29
32
|
const isDirty = (task) => {
|
|
30
33
|
if ((task?.referenceNumber === undefined || task?.referenceNumber === null) && Number.isFinite(Number(task?.localReferenceNumber))) {
|
|
@@ -74,12 +77,14 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
74
77
|
.filter((taskId) => !currentTaskIds.has(taskId))
|
|
75
78
|
.map((taskId) => ({
|
|
76
79
|
op: 'delete',
|
|
77
|
-
taskId
|
|
80
|
+
taskId,
|
|
81
|
+
deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
|
|
78
82
|
}));
|
|
79
83
|
const queuedDeleteChanges = Array.from(pendingDeleteIds)
|
|
80
84
|
.map((taskId) => ({
|
|
81
85
|
op: 'delete',
|
|
82
|
-
taskId
|
|
86
|
+
taskId,
|
|
87
|
+
deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
|
|
83
88
|
}));
|
|
84
89
|
const deleteTaskIds = new Set([
|
|
85
90
|
...deleteChanges.map((change) => String(change.taskId)),
|
|
@@ -489,7 +494,11 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
489
494
|
...taskEventUpsertChanges,
|
|
490
495
|
...activeChanges,
|
|
491
496
|
...archivedChanges,
|
|
492
|
-
...Array.from(deleteTaskIds).map((taskId) => ({
|
|
497
|
+
...Array.from(deleteTaskIds).map((taskId) => ({
|
|
498
|
+
op: 'delete',
|
|
499
|
+
taskId,
|
|
500
|
+
deletedAt: pendingDeleteWatermarks.get(taskId) || payloadBuiltAt
|
|
501
|
+
}))
|
|
493
502
|
];
|
|
494
503
|
return {
|
|
495
504
|
changes,
|
|
@@ -196,6 +196,40 @@ describe('workspaceSyncModel', () => {
|
|
|
196
196
|
})
|
|
197
197
|
]));
|
|
198
198
|
});
|
|
199
|
+
it('emits timestamped task deletes for previously pushed tasks that are now missing', () => {
|
|
200
|
+
const payload = buildWorkspaceSyncPayloadModel({
|
|
201
|
+
tasks: [],
|
|
202
|
+
archivedTasks: [],
|
|
203
|
+
lastPushedTaskIds: new Set(['task-delete-1']),
|
|
204
|
+
pendingDeletedTaskIds: new Set()
|
|
205
|
+
});
|
|
206
|
+
expect(payload.deleteTaskIds).toEqual(new Set(['task-delete-1']));
|
|
207
|
+
expect(payload.changes).toEqual(expect.arrayContaining([
|
|
208
|
+
expect.objectContaining({
|
|
209
|
+
op: 'delete',
|
|
210
|
+
taskId: 'task-delete-1',
|
|
211
|
+
deletedAt: expect.any(String)
|
|
212
|
+
})
|
|
213
|
+
]));
|
|
214
|
+
});
|
|
215
|
+
it('preserves stored task delete watermarks on pending delete changes', () => {
|
|
216
|
+
const payload = buildWorkspaceSyncPayloadModel({
|
|
217
|
+
tasks: [],
|
|
218
|
+
archivedTasks: [],
|
|
219
|
+
lastPushedTaskIds: new Set(),
|
|
220
|
+
pendingDeletedTaskIds: new Set(['task-delete-2']),
|
|
221
|
+
pendingDeletedTaskWatermarks: new Map([
|
|
222
|
+
['task-delete-2', '2026-04-10T11:00:00.000Z']
|
|
223
|
+
])
|
|
224
|
+
});
|
|
225
|
+
expect(payload.changes).toEqual(expect.arrayContaining([
|
|
226
|
+
expect.objectContaining({
|
|
227
|
+
op: 'delete',
|
|
228
|
+
taskId: 'task-delete-2',
|
|
229
|
+
deletedAt: '2026-04-10T11:00:00.000Z'
|
|
230
|
+
})
|
|
231
|
+
]));
|
|
232
|
+
});
|
|
199
233
|
it('orders task upserts deterministically by task id', () => {
|
|
200
234
|
const payload = buildWorkspaceSyncPayloadModel({
|
|
201
235
|
tasks: [
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export type WorkspaceSyncPhase = 'idle' | 'provision-local' | 'attach-cloud' | 'active' | 'error';
|
|
2
|
+
export type WorkspaceSyncSetupIntent = 'attach-cloud-import' | null;
|
|
2
3
|
export interface WorkspaceSyncStateV2 {
|
|
3
4
|
version: 2;
|
|
4
5
|
enabled: boolean;
|
|
5
6
|
phase: WorkspaceSyncPhase;
|
|
7
|
+
setupIntent?: WorkspaceSyncSetupIntent;
|
|
6
8
|
pullCursor: string | null;
|
|
7
9
|
lastPullAt: string | null;
|
|
8
10
|
lastPushAt: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as n,j as e}from"./vendor-react-CKJs5o3c.js";import{p as T,u as C,v as w,w as S,t as s,x as M}from"./index-
|
|
1
|
+
import{r as n,j as e}from"./vendor-react-CKJs5o3c.js";import{p as T,u as C,v as w,w as S,t as s,x as M}from"./index-DcSI5F86.js";import{h as L,B as A,k as I,aa as B,aI as H,aJ as D,b as R}from"./vendor-icons-BSUaRwF8.js";import"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";function F({workspaceId:h}){const[x,k]=n.useState([]),[j,y]=n.useState(!1),[c,P]=n.useState(null),[p,m]=n.useState(null),[d,g]=n.useState(null),N=n.useCallback(async()=>{if(h){y(!0);try{const a=await(await fetch(`/api/taskforce/workspace/assignee-options?workspaceId=${encodeURIComponent(h)}`,{credentials:"include"})).json().catch(()=>({})),t=Array.isArray(a?.assignees)?a.assignees.filter(i=>i.kind==="agent").map(i=>({id:String(i.value||""),name:String(i.label||i.value||"Unknown Agent"),username:String(i.username||i.value||""),icon:String(i.icon||"Bot"),color:String(i.color||"#6B7280"),kind:String(i.kind||"agent"),description:typeof i.description=="string"?i.description:null,role:typeof i.role=="string"?i.role:null,provider:typeof i.provider=="string"?i.provider:null,model:typeof i.model=="string"?i.model:null,surfaceType:T(i.surfaceType),createdAt:String(i.createdAt||""),updatedAt:String(i.updatedAt||i.createdAt||""),lastActiveAt:typeof i.lastActiveAt=="string"?i.lastActiveAt:null})):[];k(t)}finally{y(!1)}}},[h]);n.useEffect(()=>{N()},[N]);const f=n.useMemo(()=>{const r=new Map;for(const a of x){const t=C(a.surfaceType);r.has(t)||r.set(t,new Map);const i=r.get(t),v=a.name.toLowerCase();i.has(v)||i.set(v,[]),i.get(v).push(a)}return w.map(a=>({section:a,label:S(a),groups:Array.from(r.get(a)?.entries()||[]).map(([t,i])=>({groupId:`${a}:${t}`,section:a,sectionLabel:S(a),profiles:i,primaryProfile:i[0]}))})).filter(a=>a.groups.length>0)},[x]),o=n.useMemo(()=>f.flatMap(r=>r.groups),[f]),l=n.useMemo(()=>o.find(r=>r.groupId===d)||o[0]||null,[o,d]);n.useEffect(()=>{if(!o.length){d!==null&&g(null);return}(!d||!o.some(r=>r.groupId===d))&&g(o[0].groupId)},[o,d]);const b=async(r,a)=>{m(null);try{const t=await fetch("/api/taskforce/workspace/ai-profiles/merge",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({keepId:r,mergeId:a})}),i=await t.json().catch(()=>({}));if(!t.ok){m({type:"error",message:String(i?.error||"Failed to merge AI profiles.")});return}P(null),m({type:"success",message:"AI profiles merged."}),await N()}catch{m({type:"error",message:"Failed to merge AI profiles."})}},u=r=>{const a=String(r||"").trim();if(!a)return"Unknown";const t=Date.parse(a);return Number.isFinite(t)?new Date(t).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"}):a};return e.jsx("div",{className:`${s.standalonePage} ${s.standaloneContent}`,style:{overflow:"auto"},children:e.jsx("div",{className:s.settingsContent,style:{maxWidth:1080,margin:"0 auto",width:"100%"},children:e.jsx("div",{className:s.settingGroup,children:e.jsxs("div",{children:[e.jsx("h4",{className:s.settingSubTitle,children:"Registered AI Profiles"}),e.jsx("p",{className:`${s.settingsHint} ${s.marginBottom12}`,children:"AI agents register profiles when connecting via MCP. Merge duplicates created when a token was lost."}),j&&e.jsxs("div",{className:s.settingsHint,children:[e.jsx(L,{size:13,className:s.spinner})," Loading profiles…"]}),!j&&x.length===0&&e.jsx("div",{className:s.settingsHint,children:"No AI profiles registered yet."}),!j&&f.length>0&&e.jsxs("div",{className:s.aiProfilesExplorer,children:[e.jsx("div",{className:s.aiProfilesListPane,children:e.jsx("div",{className:s.aiProfilesList,children:f.map(r=>e.jsxs("div",{className:s.aiProfilesSection,children:[e.jsx("div",{className:s.aiProfilesSectionHeader,children:r.label}),r.groups.map(a=>{const t=l?.groupId===a.groupId,i=a.primaryProfile;return e.jsxs("button",{type:"button",className:`${s.aiProfileGroup} ${a.profiles.length>1?s.aiProfileGroupDuplicate:""} ${t?s.aiProfileGroupSelected:""}`,onClick:()=>g(a.groupId),"aria-pressed":t,children:[e.jsxs("div",{className:s.aiProfileGroupHeader,children:[e.jsx(A,{size:13,style:{color:i.color}}),e.jsx("span",{className:s.aiProfileName,children:i.name}),a.profiles.length>1&&e.jsxs("span",{className:s.aiProfileDuplicateBadge,children:[e.jsx(I,{size:11})," ",a.profiles.length," duplicates"]})]}),e.jsxs("div",{className:s.settingsHint,style:{marginTop:6},children:["@",i.username]}),(i.surfaceType||i.role||i.provider||i.model)&&e.jsxs("div",{className:s.aiProfileMetaRow,children:[i.surfaceType&&e.jsx("span",{className:s.aiProfileSurfaceBadge,children:M(i.surfaceType)}),i.role&&e.jsx("span",{children:i.role}),i.provider&&e.jsx("span",{children:i.provider}),i.model&&e.jsx("span",{children:i.model})]}),i.description&&e.jsx("div",{className:s.settingsHint,style:{marginTop:4},children:i.description})]},a.groupId)})]},r.section))})}),l&&e.jsx("div",{className:s.aiProfileDetailPane,children:e.jsxs("div",{className:s.aiProfileDetailCard,children:[e.jsxs("div",{className:s.aiProfileDetailHero,children:[e.jsx("div",{className:s.aiProfileDetailIcon,style:{color:l.primaryProfile.color},children:e.jsx(A,{size:18})}),e.jsxs("div",{className:s.aiProfileDetailHeading,children:[e.jsx("div",{className:s.aiProfileDetailTitleRow,children:e.jsx("h5",{className:s.aiProfileDetailTitle,children:l.primaryProfile.name})}),e.jsxs("div",{className:s.aiProfileDetailMetaRow,children:[e.jsxs("span",{className:s.aiProfileDetailHandle,children:["@",l.primaryProfile.username]}),e.jsx("span",{className:s.aiProfileDetailSectionBadge,children:l.sectionLabel}),l.profiles.length>1&&e.jsxs("span",{className:s.aiProfileDetailLinkedCount,children:[l.profiles.length," linked"]})]})]})]}),l.primaryProfile.description&&e.jsx("div",{className:s.aiProfileDetailDescription,children:l.primaryProfile.description}),e.jsxs("div",{className:s.aiProfileDetailGrid,children:[e.jsxs("div",{className:s.aiProfileDetailStat,children:[e.jsxs("span",{className:s.aiProfileDetailStatLabel,children:[e.jsx(B,{size:12})," Role"]}),e.jsx("span",{className:s.aiProfileDetailStatValue,children:l.primaryProfile.role||"Not set"})]}),e.jsxs("div",{className:s.aiProfileDetailStat,children:[e.jsxs("span",{className:s.aiProfileDetailStatLabel,children:[e.jsx(H,{size:12})," Provider"]}),e.jsx("span",{className:s.aiProfileDetailStatValue,children:[l.primaryProfile.provider,l.primaryProfile.model].filter(Boolean).join(" · ")||"Not set"})]}),e.jsxs("div",{className:s.aiProfileDetailStat,children:[e.jsxs("span",{className:s.aiProfileDetailStatLabel,children:[e.jsx(D,{size:12})," Last active"]}),e.jsx("span",{className:s.aiProfileDetailStatValue,children:u(l.primaryProfile.lastActiveAt)})]}),e.jsxs("div",{className:s.aiProfileDetailStat,children:[e.jsxs("span",{className:s.aiProfileDetailStatLabel,children:[e.jsx(D,{size:12})," Updated"]}),e.jsx("span",{className:s.aiProfileDetailStatValue,children:u(l.primaryProfile.updatedAt)})]})]}),e.jsxs("div",{className:s.aiProfileInstanceSection,children:[e.jsxs("div",{className:s.aiProfileInstanceSectionHeader,children:[e.jsx("span",{children:"Profile instances"}),e.jsx("span",{className:s.settingsHint,children:"Choose a keeper here if duplicates need to be merged."})]}),e.jsx("div",{className:s.aiProfileInstanceList,children:l.profiles.map(r=>e.jsxs("div",{className:s.aiProfileInstanceCard,children:[e.jsxs("div",{className:s.aiProfileInstanceTopRow,children:[e.jsxs("div",{children:[e.jsxs("div",{className:s.aiProfileInstanceName,children:["@",r.username]}),e.jsx("div",{className:s.aiProfileIdChip,children:r.id})]}),l.profiles.length>1&&c?.keepId===r.id&&e.jsx("span",{className:s.aiProfileKeepBadge,children:"Keeping"})]}),e.jsxs("div",{className:s.aiProfileInstanceMeta,children:[e.jsxs("span",{children:["Created ",u(r.createdAt)]}),e.jsxs("span",{children:["Updated ",u(r.updatedAt)]})]}),l.profiles.length>1&&c?.keepId!==r.id&&e.jsx("button",{className:s.secondaryHeaderBtn,title:"Keep this profile, merge others into it",onClick:()=>{const a=l.profiles.find(t=>t.id!==r.id)?.id;a&&P({keepId:r.id,mergeId:a})},children:"Keep this"})]},r.id))}),c&&l.profiles.some(r=>r.id===c.keepId)&&e.jsxs("div",{className:s.aiProfileMergeActions,children:[e.jsx("button",{className:s.dangerBtn,onClick:()=>{b(c.keepId,c.mergeId)},children:"Merge duplicates"}),e.jsx("button",{className:s.secondaryHeaderBtn,onClick:()=>P(null),children:"Cancel"})]})]})]})})]}),p&&e.jsxs("div",{className:`${p.type==="success"?s.successMessage:s.errorMessage} ${s.marginTop12}`,children:[p.type==="success"?e.jsx(R,{size:14}):e.jsx(I,{size:14}),p.message]})]})})})})}export{F as AgentsModule};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{j as t,r as a,R as qt}from"./vendor-react-CKJs5o3c.js";import{R as xs,f as Ce,e as Ct,g as vs,t as Bn,M as Jt}from"./index-DXUdtH1B.js";import{q as _s,m as js,c as Zt,T as Tn,s as ks,a3 as ws,h as An,ak as Cs,R as Is,al as Ss,am as Ns,an as $s,ao as tn,C as nn,ap as Rs,aq as Dn,ar as zn,as as Un,at as Gn,g as Ps,f as Bs,b as sn}from"./vendor-icons-I7ZwG1z_.js";import"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";function Ts({copied:o,disabled:l=!1,label:m,onClick:g,title:w="Copy image reference",ariaLabel:y,className:M=""}){return t.jsx(xs,{copied:o,disabled:l,label:"",onClick:g,title:w,ariaLabel:y,className:M,children:m})}const As="_shell_sf7jc_1",Es="_panel_sf7jc_16",Ms="_sessionPanel_sf7jc_22",Ls="_detailPanel_sf7jc_23",Fs="_sessionContextBar_sf7jc_29",Hs="_sessionContextLeft_sf7jc_40",Os="_sessionContextRight_sf7jc_41",Ds="_sessionContextLabel_sf7jc_56",zs="_sessionContextSpacer_sf7jc_62",Us="_canvasPanel_sf7jc_67",Gs="_canvasWorkspace_sf7jc_74",Ys="_canvasMain_sf7jc_81",Ks="_panelHeader_sf7jc_88",Ws="_panelHeaderText_sf7jc_97",Xs="_panelTitle_sf7jc_101",Vs="_canvasHeading_sf7jc_105",qs="_sessionActions_sf7jc_109",Js="_sessionList_sf7jc_117",Zs="_annotationList_sf7jc_118",Qs="_markerHelpModalBody_sf7jc_133",ea="_openImageModalBody_sf7jc_139",ta="_openImageField_sf7jc_145",na="_openImageActions_sf7jc_149",sa="_markerHelpItem_sf7jc_155",aa="_markerHelpHeader_sf7jc_163",oa="_markerHelpExample_sf7jc_175",ra="_sessionCard_sf7jc_179",ia="_annotationCard_sf7jc_180",la="_sessionEmptyState_sf7jc_197",ca="_sessionCardButton_sf7jc_204",da="_annotationCardButton_sf7jc_214",ua="_sessionCardBody_sf7jc_224",fa="_sessionCardActive_sf7jc_230",ma="_annotationCardActive_sf7jc_231",pa="_annotationMeta_sf7jc_241",ha="_annotationInstructionPreview_sf7jc_248",ba="_annotationPreviewFooter_sf7jc_256",ga="_annotationInstructionEditor_sf7jc_263",ya="_annotationTypeField_sf7jc_269",xa="_annotationInstructionButton_sf7jc_275",va="_annotationInstructionField_sf7jc_284",_a="_sessionMeta_sf7jc_288",ja="_sessionTitle_sf7jc_295",ka="_annotationTitle_sf7jc_296",wa="_sessionTimestamp_sf7jc_302",Ca="_annotationKind_sf7jc_303",Ia="_annotationInstructionTypeIcon_sf7jc_307",Sa="_sessionInstructionPreview_sf7jc_313",Na="_sessionInstructionEditor_sf7jc_321",$a="_sessionCardFooter_sf7jc_327",Ra="_toolRail_sf7jc_334",Pa="_canvasToolRail_sf7jc_343",Ba="_toolbarCluster_sf7jc_364",Ta="_toolbarViewportCluster_sf7jc_371",Aa="_toolbarSeparator_sf7jc_375",Ea="_toolBtn_sf7jc_381",Ma="_toolRailButton_sf7jc_385",La="_toolbarButton_sf7jc_395",Fa="_toolBtnActive_sf7jc_400",Ha="_toolbarActions_sf7jc_407",Oa="_toolbarSelectionActions_sf7jc_416",Da="_toolbarColorPicker_sf7jc_424",za="_colorPickerButton_sf7jc_428",Ua="_colorPickerSwatch_sf7jc_433",Ga="_colorPickerPopover_sf7jc_441",Ya="_colorOption_sf7jc_456",Ka="_colorOptionActive_sf7jc_466",Wa="_toolbarUtilities_sf7jc_473",Xa="_toolbarGeometryFields_sf7jc_481",Va="_toolbarGeometryField_sf7jc_481",qa="_toolbarGeometryLabel_sf7jc_494",Ja="_toolbarGeometryInput_sf7jc_500",Za="_iconButton_sf7jc_505",Qa="_ghostBtn_sf7jc_510",eo="_payloadBtn_sf7jc_511",to="_backToTaskBtn_sf7jc_512",no="_canvasScroller_sf7jc_532",so="_canvasFrame_sf7jc_548",ao="_canvasMedia_sf7jc_555",oo="_canvasStatusOverlay_sf7jc_563",ro="_canvasStatusCard_sf7jc_575",io="_canvasImage_sf7jc_588",lo="_overlay_sf7jc_595",co="_overlaySelect_sf7jc_601",uo="_overlayPan_sf7jc_605",fo="_overlaySvg_sf7jc_609",mo="_overlayHitLayer_sf7jc_618",po="_arrowHitArea_sf7jc_627",ho="_canvasHandleHit_sf7jc_634",bo="_canvasResizeHandleHit_sf7jc_641",go="_canvasHandleVisible_sf7jc_645",yo="_pin_sf7jc_662",xo="_note_sf7jc_663",vo="_annotationNumberBadge_sf7jc_680",_o="_box_sf7jc_705",jo="_boxNumberBadge_sf7jc_714",ko="_arrowNumberBadge_sf7jc_720",wo="_boxSurface_sf7jc_724",Co="_selected_sf7jc_737",Io="_textInput_sf7jc_754",So="_textArea_sf7jc_755",No="_select_sf7jc_737",$o="_sessionTitleInput_sf7jc_762",Ro="_sessionInstructionField_sf7jc_767",Po="_detailEmpty_sf7jc_776",Bo="_emptyState_sf7jc_777",To="_payloadModalBody_sf7jc_789",Ao="_payloadModalToolbar_sf7jc_796",Eo="_payloadViewToggle_sf7jc_803",Mo="_payloadModalActions_sf7jc_804",Lo="_payloadModalPreview_sf7jc_811",Fo="_statusBar_sf7jc_826",Ho="_annotationSummary_sf7jc_838",s={shell:As,panel:Es,sessionPanel:Ms,detailPanel:Ls,sessionContextBar:Fs,sessionContextLeft:Hs,sessionContextRight:Os,sessionContextLabel:Ds,sessionContextSpacer:zs,canvasPanel:Us,canvasWorkspace:Gs,canvasMain:Ys,panelHeader:Ks,panelHeaderText:Ws,panelTitle:Xs,canvasHeading:Vs,sessionActions:qs,sessionList:Js,annotationList:Zs,markerHelpModalBody:Qs,openImageModalBody:ea,openImageField:ta,openImageActions:na,markerHelpItem:sa,markerHelpHeader:aa,markerHelpExample:oa,sessionCard:ra,annotationCard:ia,sessionEmptyState:la,sessionCardButton:ca,annotationCardButton:da,sessionCardBody:ua,sessionCardActive:fa,annotationCardActive:ma,annotationMeta:pa,annotationInstructionPreview:ha,annotationPreviewFooter:ba,annotationInstructionEditor:ga,annotationTypeField:ya,annotationInstructionButton:xa,annotationInstructionField:va,sessionMeta:_a,sessionTitle:ja,annotationTitle:ka,sessionTimestamp:wa,annotationKind:Ca,annotationInstructionTypeIcon:Ia,sessionInstructionPreview:Sa,sessionInstructionEditor:Na,sessionCardFooter:$a,toolRail:Ra,canvasToolRail:Pa,toolbarCluster:Ba,toolbarViewportCluster:Ta,toolbarSeparator:Aa,toolBtn:Ea,toolRailButton:Ma,toolbarButton:La,toolBtnActive:Fa,toolbarActions:Ha,toolbarSelectionActions:Oa,toolbarColorPicker:Da,colorPickerButton:za,colorPickerSwatch:Ua,colorPickerPopover:Ga,colorOption:Ya,colorOptionActive:Ka,toolbarUtilities:Wa,toolbarGeometryFields:Xa,toolbarGeometryField:Va,toolbarGeometryLabel:qa,toolbarGeometryInput:Ja,iconButton:Za,ghostBtn:Qa,payloadBtn:eo,backToTaskBtn:to,canvasScroller:no,canvasFrame:so,canvasMedia:ao,canvasStatusOverlay:oo,canvasStatusCard:ro,canvasImage:io,overlay:lo,overlaySelect:co,overlayPan:uo,overlaySvg:fo,overlayHitLayer:mo,arrowHitArea:po,canvasHandleHit:ho,canvasResizeHandleHit:bo,canvasHandleVisible:go,pin:yo,note:xo,annotationNumberBadge:vo,box:_o,boxNumberBadge:jo,arrowNumberBadge:ko,boxSurface:wo,selected:Co,textInput:Io,textArea:So,select:No,sessionTitleInput:$o,sessionInstructionField:Ro,detailEmpty:Po,emptyState:Bo,payloadModalBody:To,payloadModalToolbar:Ao,payloadViewToggle:Eo,payloadModalActions:Mo,payloadModalPreview:Lo,statusBar:Fo,annotationSummary:Ho},En=[{value:"review",label:"Review"},{value:"change",label:"Change"},{value:"question",label:"Question"}],Mn=[{value:"select",label:"Select",icon:Rs},{value:"pin",label:"Pin",icon:Dn},{value:"box",label:"Box",icon:zn},{value:"arrow",label:"Arrow",icon:Un},{value:"text-note",label:"Note",icon:Gn}],Oo={pin:Dn,box:zn,arrow:Un,"text-note":Gn},Do={pin:"Pin",box:"Box",arrow:"Arrow","text-note":"Note"},zo={review:tn,change:sn,question:nn,issue:nn,idea:tn},It={select:{short:"Select and edit existing markers.",detail:"Use Select to click, drag, reorder, resize, and update markers that are already on the image.",example:"Example: move an existing marker after the screenshot changes."},pin:{short:"Mark a precise spot.",detail:"Use Pin when feedback points to one exact location instead of a broader area.",example:'Example: "This icon is misaligned by 2px."'},box:{short:"Mark an area or component.",detail:"Use Box when the feedback applies to a whole region, card, panel, or bounded UI block.",example:'Example: "This whole card needs tighter padding and a stronger border."'},arrow:{short:"Show direction or relationship.",detail:"Use Arrow when you need to show movement, attachment, flow, or source-to-target intent.",example:'Example: "This tooltip should anchor to this button, not the panel."'},"text-note":{short:"Add a comment-style point marker.",detail:"Use Note when you want a point marker that reads more like a comment or open question.",example:'Example: "Ask design whether this badge should stay."'}},it={question:"#0f766e",change:"#2563eb",issue:"#dc2626",idea:"#d97706",review:"#7c3aed"},Uo=["#7c3aed","#2563eb","#0f766e","#dc2626","#d97706","#111827"],re="review";function ze(o){const l=String(o.displayName||"").trim();return l?`${l} review`:"Annotated session"}function Yn(){return`annotation-${Math.random().toString(36).slice(2,10)}`}function _(o){return!Number.isFinite(o)||o<=0?0:o>=1?1:o}function Se(o){return _(Math.max(.02,o))}function rt(o){return o?[String(o.taskId||"").trim(),String(o.assetId||"").trim(),String(o.path||"").trim()].join("::"):""}function Go(o){if(!(o instanceof HTMLElement))return!1;const l=o.tagName.toLowerCase();return o.isContentEditable?!0:l==="input"||l==="textarea"||l==="select"}function Ie(o){return o.map((l,m)=>({...l,order:m}))}function Qt(o){if(!o)return"Unsaved";const l=new Date(o);return Number.isNaN(l.getTime())?"Unsaved":l.toLocaleString()}function St(o){const l=String(o.createdByActor?.label||"").trim();return l||null}function Yo(o){const l=String(o||"").trim().replace(/\s+/g," ");return l?l.length>110?`${l.slice(0,107)}...`:l:""}function Ln(o,l,m,g=it[re]){const w={id:Yn(),order:0,instruction:"",markerType:re,color:g};if(o==="pin")return{...w,kind:o,x:l.x,y:l.y};if(o==="text-note")return{...w,kind:o,x:l.x,y:l.y};if(o==="box"){const M=m||l;return{...w,kind:o,x:_(Math.min(l.x,M.x)),y:_(Math.min(l.y,M.y)),width:Se(Math.abs(M.x-l.x)),height:Se(Math.abs(M.y-l.y))}}const y=m||l;return{...w,kind:"arrow",x:l.x,y:l.y,x2:y.x,y2:y.y}}function en(o){return o.color?o.color:it[o.markerType||re]}function Ko(o,l){const m=Math.max(l.width,1),g=Math.max(l.height,1),w=o.x*m,y=o.y*g,M=o.x2*m,ne=o.y2*g,Ue=M-w,Ge=ne-y,me=Math.hypot(Ue,Ge)||1,ie=Ue/me,Ye=Ge/me,Ne=Math.max(10,Math.min(16,me-2)),T=Ne*.62,Ke=M-ie*Ne,pe=ne-Ye*Ne,he=-Ye,se=ie;return{shaftX1:w,shaftY1:y,shaftX2:Ke,shaftY2:pe,headPoints:[`${M},${ne}`,`${Ke+he*T},${pe+se*T}`,`${Ke-he*T},${pe-se*T}`].join(" ")}}function Wo(o,l){return{...o,markerType:l,color:o.color||it[l]}}function Xo(o,l){return{...o,id:Yn(),order:l}}function Vo(o,l){const m=String(o||"").trim()||(l?ze(l):"Annotated session");return/\bcopy$/i.test(m)?`${m} 2`:`${m} copy`}function qo(o,l,m){if(l===m||l<0||m<0||l>=o.length||m>=o.length)return o;const g=[...o],[w]=g.splice(l,1);return w?(g.splice(m,0,w),Ie(g)):o}function te(o){return String(Math.round(_(o)*1e3)/10)}function Jo(o){const l=Number.parseFloat(o);return Number.isFinite(l)?_(l/100):null}function Zo(o,l,m){return o.kind==="pin"||o.kind==="text-note"?l==="x"||l==="y"?{...o,[l]:_(m)}:o:o.kind==="box"?l==="x"||l==="y"?{...o,[l]:_(m)}:l==="width"||l==="height"?{...o,[l]:Se(m)}:o:l==="x"||l==="y"||l==="x2"||l==="y2"?{...o,[l]:_(m)}:o}function Qo(o){return o.kind==="pin"||o.kind==="text-note"?[{key:"x",label:"X",value:te(o.x)},{key:"y",label:"Y",value:te(o.y)}]:o.kind==="box"?[{key:"x",label:"X",value:te(o.x)},{key:"y",label:"Y",value:te(o.y)},{key:"width",label:"Width",value:te(o.width)},{key:"height",label:"Height",value:te(o.height)}]:[{key:"x",label:"Start X",value:te(o.x)},{key:"y",label:"Start Y",value:te(o.y)},{key:"x2",label:"End X",value:te(o.x2)},{key:"y2",label:"End Y",value:te(o.y2)}]}function er(o){if(!o)return null;const l=Math.round(o.x*100),m=Math.round(o.y*100),g=Math.round(o.width*100),w=Math.round(o.height*100);return`crop ${l}%, ${m}% size ${g}% x ${w}%`}function tr(o){return Number.isFinite(o)?Math.min(4,Math.max(.25,Number(o.toFixed(2)))):1}function Fn(o){const l=[`Annotated attachment: ${o.title||o.image.displayName}`,`Image: ${o.image.displayName}`,`Image Reference: ${o.image.referenceLabel||o.image.assetId}`,`Task ID: ${o.taskId}`,o.globalInstruction?`Global instruction: ${o.globalInstruction}`:"Global instruction: None provided.","Markers:"];return o.annotations.length===0?(l.push("0. No markers."),l.join(`
|
|
1
|
+
import{j as t,r as a,R as qt}from"./vendor-react-CKJs5o3c.js";import{R as xs,f as Ce,e as Ct,g as vs,t as Bn,M as Jt}from"./index-DcSI5F86.js";import{q as _s,n as js,c as Zt,T as Tn,s as ks,a3 as ws,h as An,ak as Cs,R as Is,al as Ss,am as Ns,an as $s,ao as tn,C as nn,ap as Rs,aq as Dn,ar as zn,as as Un,at as Gn,g as Ps,f as Bs,b as sn}from"./vendor-icons-BSUaRwF8.js";import"./vendor-markdown-BUxTU7dS.js";import"./vendor-dnd-DRzYolkg.js";import"./vendor-router-BbWMxlnO.js";function Ts({copied:o,disabled:l=!1,label:m,onClick:g,title:w="Copy image reference",ariaLabel:y,className:M=""}){return t.jsx(xs,{copied:o,disabled:l,label:"",onClick:g,title:w,ariaLabel:y,className:M,children:m})}const As="_shell_sf7jc_1",Es="_panel_sf7jc_16",Ms="_sessionPanel_sf7jc_22",Ls="_detailPanel_sf7jc_23",Fs="_sessionContextBar_sf7jc_29",Hs="_sessionContextLeft_sf7jc_40",Os="_sessionContextRight_sf7jc_41",Ds="_sessionContextLabel_sf7jc_56",zs="_sessionContextSpacer_sf7jc_62",Us="_canvasPanel_sf7jc_67",Gs="_canvasWorkspace_sf7jc_74",Ys="_canvasMain_sf7jc_81",Ks="_panelHeader_sf7jc_88",Ws="_panelHeaderText_sf7jc_97",Xs="_panelTitle_sf7jc_101",Vs="_canvasHeading_sf7jc_105",qs="_sessionActions_sf7jc_109",Js="_sessionList_sf7jc_117",Zs="_annotationList_sf7jc_118",Qs="_markerHelpModalBody_sf7jc_133",ea="_openImageModalBody_sf7jc_139",ta="_openImageField_sf7jc_145",na="_openImageActions_sf7jc_149",sa="_markerHelpItem_sf7jc_155",aa="_markerHelpHeader_sf7jc_163",oa="_markerHelpExample_sf7jc_175",ra="_sessionCard_sf7jc_179",ia="_annotationCard_sf7jc_180",la="_sessionEmptyState_sf7jc_197",ca="_sessionCardButton_sf7jc_204",da="_annotationCardButton_sf7jc_214",ua="_sessionCardBody_sf7jc_224",fa="_sessionCardActive_sf7jc_230",ma="_annotationCardActive_sf7jc_231",pa="_annotationMeta_sf7jc_241",ha="_annotationInstructionPreview_sf7jc_248",ba="_annotationPreviewFooter_sf7jc_256",ga="_annotationInstructionEditor_sf7jc_263",ya="_annotationTypeField_sf7jc_269",xa="_annotationInstructionButton_sf7jc_275",va="_annotationInstructionField_sf7jc_284",_a="_sessionMeta_sf7jc_288",ja="_sessionTitle_sf7jc_295",ka="_annotationTitle_sf7jc_296",wa="_sessionTimestamp_sf7jc_302",Ca="_annotationKind_sf7jc_303",Ia="_annotationInstructionTypeIcon_sf7jc_307",Sa="_sessionInstructionPreview_sf7jc_313",Na="_sessionInstructionEditor_sf7jc_321",$a="_sessionCardFooter_sf7jc_327",Ra="_toolRail_sf7jc_334",Pa="_canvasToolRail_sf7jc_343",Ba="_toolbarCluster_sf7jc_364",Ta="_toolbarViewportCluster_sf7jc_371",Aa="_toolbarSeparator_sf7jc_375",Ea="_toolBtn_sf7jc_381",Ma="_toolRailButton_sf7jc_385",La="_toolbarButton_sf7jc_395",Fa="_toolBtnActive_sf7jc_400",Ha="_toolbarActions_sf7jc_407",Oa="_toolbarSelectionActions_sf7jc_416",Da="_toolbarColorPicker_sf7jc_424",za="_colorPickerButton_sf7jc_428",Ua="_colorPickerSwatch_sf7jc_433",Ga="_colorPickerPopover_sf7jc_441",Ya="_colorOption_sf7jc_456",Ka="_colorOptionActive_sf7jc_466",Wa="_toolbarUtilities_sf7jc_473",Xa="_toolbarGeometryFields_sf7jc_481",Va="_toolbarGeometryField_sf7jc_481",qa="_toolbarGeometryLabel_sf7jc_494",Ja="_toolbarGeometryInput_sf7jc_500",Za="_iconButton_sf7jc_505",Qa="_ghostBtn_sf7jc_510",eo="_payloadBtn_sf7jc_511",to="_backToTaskBtn_sf7jc_512",no="_canvasScroller_sf7jc_532",so="_canvasFrame_sf7jc_548",ao="_canvasMedia_sf7jc_555",oo="_canvasStatusOverlay_sf7jc_563",ro="_canvasStatusCard_sf7jc_575",io="_canvasImage_sf7jc_588",lo="_overlay_sf7jc_595",co="_overlaySelect_sf7jc_601",uo="_overlayPan_sf7jc_605",fo="_overlaySvg_sf7jc_609",mo="_overlayHitLayer_sf7jc_618",po="_arrowHitArea_sf7jc_627",ho="_canvasHandleHit_sf7jc_634",bo="_canvasResizeHandleHit_sf7jc_641",go="_canvasHandleVisible_sf7jc_645",yo="_pin_sf7jc_662",xo="_note_sf7jc_663",vo="_annotationNumberBadge_sf7jc_680",_o="_box_sf7jc_705",jo="_boxNumberBadge_sf7jc_714",ko="_arrowNumberBadge_sf7jc_720",wo="_boxSurface_sf7jc_724",Co="_selected_sf7jc_737",Io="_textInput_sf7jc_754",So="_textArea_sf7jc_755",No="_select_sf7jc_737",$o="_sessionTitleInput_sf7jc_762",Ro="_sessionInstructionField_sf7jc_767",Po="_detailEmpty_sf7jc_776",Bo="_emptyState_sf7jc_777",To="_payloadModalBody_sf7jc_789",Ao="_payloadModalToolbar_sf7jc_796",Eo="_payloadViewToggle_sf7jc_803",Mo="_payloadModalActions_sf7jc_804",Lo="_payloadModalPreview_sf7jc_811",Fo="_statusBar_sf7jc_826",Ho="_annotationSummary_sf7jc_838",s={shell:As,panel:Es,sessionPanel:Ms,detailPanel:Ls,sessionContextBar:Fs,sessionContextLeft:Hs,sessionContextRight:Os,sessionContextLabel:Ds,sessionContextSpacer:zs,canvasPanel:Us,canvasWorkspace:Gs,canvasMain:Ys,panelHeader:Ks,panelHeaderText:Ws,panelTitle:Xs,canvasHeading:Vs,sessionActions:qs,sessionList:Js,annotationList:Zs,markerHelpModalBody:Qs,openImageModalBody:ea,openImageField:ta,openImageActions:na,markerHelpItem:sa,markerHelpHeader:aa,markerHelpExample:oa,sessionCard:ra,annotationCard:ia,sessionEmptyState:la,sessionCardButton:ca,annotationCardButton:da,sessionCardBody:ua,sessionCardActive:fa,annotationCardActive:ma,annotationMeta:pa,annotationInstructionPreview:ha,annotationPreviewFooter:ba,annotationInstructionEditor:ga,annotationTypeField:ya,annotationInstructionButton:xa,annotationInstructionField:va,sessionMeta:_a,sessionTitle:ja,annotationTitle:ka,sessionTimestamp:wa,annotationKind:Ca,annotationInstructionTypeIcon:Ia,sessionInstructionPreview:Sa,sessionInstructionEditor:Na,sessionCardFooter:$a,toolRail:Ra,canvasToolRail:Pa,toolbarCluster:Ba,toolbarViewportCluster:Ta,toolbarSeparator:Aa,toolBtn:Ea,toolRailButton:Ma,toolbarButton:La,toolBtnActive:Fa,toolbarActions:Ha,toolbarSelectionActions:Oa,toolbarColorPicker:Da,colorPickerButton:za,colorPickerSwatch:Ua,colorPickerPopover:Ga,colorOption:Ya,colorOptionActive:Ka,toolbarUtilities:Wa,toolbarGeometryFields:Xa,toolbarGeometryField:Va,toolbarGeometryLabel:qa,toolbarGeometryInput:Ja,iconButton:Za,ghostBtn:Qa,payloadBtn:eo,backToTaskBtn:to,canvasScroller:no,canvasFrame:so,canvasMedia:ao,canvasStatusOverlay:oo,canvasStatusCard:ro,canvasImage:io,overlay:lo,overlaySelect:co,overlayPan:uo,overlaySvg:fo,overlayHitLayer:mo,arrowHitArea:po,canvasHandleHit:ho,canvasResizeHandleHit:bo,canvasHandleVisible:go,pin:yo,note:xo,annotationNumberBadge:vo,box:_o,boxNumberBadge:jo,arrowNumberBadge:ko,boxSurface:wo,selected:Co,textInput:Io,textArea:So,select:No,sessionTitleInput:$o,sessionInstructionField:Ro,detailEmpty:Po,emptyState:Bo,payloadModalBody:To,payloadModalToolbar:Ao,payloadViewToggle:Eo,payloadModalActions:Mo,payloadModalPreview:Lo,statusBar:Fo,annotationSummary:Ho},En=[{value:"review",label:"Review"},{value:"change",label:"Change"},{value:"question",label:"Question"}],Mn=[{value:"select",label:"Select",icon:Rs},{value:"pin",label:"Pin",icon:Dn},{value:"box",label:"Box",icon:zn},{value:"arrow",label:"Arrow",icon:Un},{value:"text-note",label:"Note",icon:Gn}],Oo={pin:Dn,box:zn,arrow:Un,"text-note":Gn},Do={pin:"Pin",box:"Box",arrow:"Arrow","text-note":"Note"},zo={review:tn,change:sn,question:nn,issue:nn,idea:tn},It={select:{short:"Select and edit existing markers.",detail:"Use Select to click, drag, reorder, resize, and update markers that are already on the image.",example:"Example: move an existing marker after the screenshot changes."},pin:{short:"Mark a precise spot.",detail:"Use Pin when feedback points to one exact location instead of a broader area.",example:'Example: "This icon is misaligned by 2px."'},box:{short:"Mark an area or component.",detail:"Use Box when the feedback applies to a whole region, card, panel, or bounded UI block.",example:'Example: "This whole card needs tighter padding and a stronger border."'},arrow:{short:"Show direction or relationship.",detail:"Use Arrow when you need to show movement, attachment, flow, or source-to-target intent.",example:'Example: "This tooltip should anchor to this button, not the panel."'},"text-note":{short:"Add a comment-style point marker.",detail:"Use Note when you want a point marker that reads more like a comment or open question.",example:'Example: "Ask design whether this badge should stay."'}},it={question:"#0f766e",change:"#2563eb",issue:"#dc2626",idea:"#d97706",review:"#7c3aed"},Uo=["#7c3aed","#2563eb","#0f766e","#dc2626","#d97706","#111827"],re="review";function ze(o){const l=String(o.displayName||"").trim();return l?`${l} review`:"Annotated session"}function Yn(){return`annotation-${Math.random().toString(36).slice(2,10)}`}function _(o){return!Number.isFinite(o)||o<=0?0:o>=1?1:o}function Se(o){return _(Math.max(.02,o))}function rt(o){return o?[String(o.taskId||"").trim(),String(o.assetId||"").trim(),String(o.path||"").trim()].join("::"):""}function Go(o){if(!(o instanceof HTMLElement))return!1;const l=o.tagName.toLowerCase();return o.isContentEditable?!0:l==="input"||l==="textarea"||l==="select"}function Ie(o){return o.map((l,m)=>({...l,order:m}))}function Qt(o){if(!o)return"Unsaved";const l=new Date(o);return Number.isNaN(l.getTime())?"Unsaved":l.toLocaleString()}function St(o){const l=String(o.createdByActor?.label||"").trim();return l||null}function Yo(o){const l=String(o||"").trim().replace(/\s+/g," ");return l?l.length>110?`${l.slice(0,107)}...`:l:""}function Ln(o,l,m,g=it[re]){const w={id:Yn(),order:0,instruction:"",markerType:re,color:g};if(o==="pin")return{...w,kind:o,x:l.x,y:l.y};if(o==="text-note")return{...w,kind:o,x:l.x,y:l.y};if(o==="box"){const M=m||l;return{...w,kind:o,x:_(Math.min(l.x,M.x)),y:_(Math.min(l.y,M.y)),width:Se(Math.abs(M.x-l.x)),height:Se(Math.abs(M.y-l.y))}}const y=m||l;return{...w,kind:"arrow",x:l.x,y:l.y,x2:y.x,y2:y.y}}function en(o){return o.color?o.color:it[o.markerType||re]}function Ko(o,l){const m=Math.max(l.width,1),g=Math.max(l.height,1),w=o.x*m,y=o.y*g,M=o.x2*m,ne=o.y2*g,Ue=M-w,Ge=ne-y,me=Math.hypot(Ue,Ge)||1,ie=Ue/me,Ye=Ge/me,Ne=Math.max(10,Math.min(16,me-2)),T=Ne*.62,Ke=M-ie*Ne,pe=ne-Ye*Ne,he=-Ye,se=ie;return{shaftX1:w,shaftY1:y,shaftX2:Ke,shaftY2:pe,headPoints:[`${M},${ne}`,`${Ke+he*T},${pe+se*T}`,`${Ke-he*T},${pe-se*T}`].join(" ")}}function Wo(o,l){return{...o,markerType:l,color:o.color||it[l]}}function Xo(o,l){return{...o,id:Yn(),order:l}}function Vo(o,l){const m=String(o||"").trim()||(l?ze(l):"Annotated session");return/\bcopy$/i.test(m)?`${m} 2`:`${m} copy`}function qo(o,l,m){if(l===m||l<0||m<0||l>=o.length||m>=o.length)return o;const g=[...o],[w]=g.splice(l,1);return w?(g.splice(m,0,w),Ie(g)):o}function te(o){return String(Math.round(_(o)*1e3)/10)}function Jo(o){const l=Number.parseFloat(o);return Number.isFinite(l)?_(l/100):null}function Zo(o,l,m){return o.kind==="pin"||o.kind==="text-note"?l==="x"||l==="y"?{...o,[l]:_(m)}:o:o.kind==="box"?l==="x"||l==="y"?{...o,[l]:_(m)}:l==="width"||l==="height"?{...o,[l]:Se(m)}:o:l==="x"||l==="y"||l==="x2"||l==="y2"?{...o,[l]:_(m)}:o}function Qo(o){return o.kind==="pin"||o.kind==="text-note"?[{key:"x",label:"X",value:te(o.x)},{key:"y",label:"Y",value:te(o.y)}]:o.kind==="box"?[{key:"x",label:"X",value:te(o.x)},{key:"y",label:"Y",value:te(o.y)},{key:"width",label:"Width",value:te(o.width)},{key:"height",label:"Height",value:te(o.height)}]:[{key:"x",label:"Start X",value:te(o.x)},{key:"y",label:"Start Y",value:te(o.y)},{key:"x2",label:"End X",value:te(o.x2)},{key:"y2",label:"End Y",value:te(o.y2)}]}function er(o){if(!o)return null;const l=Math.round(o.x*100),m=Math.round(o.y*100),g=Math.round(o.width*100),w=Math.round(o.height*100);return`crop ${l}%, ${m}% size ${g}% x ${w}%`}function tr(o){return Number.isFinite(o)?Math.min(4,Math.max(.25,Number(o.toFixed(2)))):1}function Fn(o){const l=[`Annotated attachment: ${o.title||o.image.displayName}`,`Image: ${o.image.displayName}`,`Image Reference: ${o.image.referenceLabel||o.image.assetId}`,`Task ID: ${o.taskId}`,o.globalInstruction?`Global instruction: ${o.globalInstruction}`:"Global instruction: None provided.","Markers:"];return o.annotations.length===0?(l.push("0. No markers."),l.join(`
|
|
2
2
|
`)):(o.annotations.forEach((m,g)=>{const w=m.markerType||re,y=er(m.cropHint);l.push(`${g+1}. ${m.kind} (${w})`),l.push(`Instruction: ${m.instruction||"No marker instruction."}`),y&&l.push(`Region: ${y}`)}),l.join(`
|
|
3
3
|
`))}function Nt(o){return{title:o.title,globalInstruction:o.globalInstruction,annotations:Ie(o.annotations)}}function Hn(o){return JSON.stringify(Nt(o))}function On(o){const l=JSON.parse(o);return Nt({title:String(l?.title||""),globalInstruction:String(l?.globalInstruction||""),annotations:Array.isArray(l?.annotations)?l.annotations:[]})}function nr(o,l){return Nt({title:o?.title||l,globalInstruction:o?.globalInstruction||"",annotations:o?.annotations||[]})}function dr({runtimeMode:o="local",apiBaseUrl:l="",cloudAuthBaseUrl:m="",workspaceId:g="default",sessionLoadReady:w=!0,requestedTarget:y=null,requestedSessionId:M=null,requestedOpenVersion:ne=0,resolveTaskReferenceLabel:Ue,resolveImageReferenceLabel:Ge,onRequestedTargetHandled:me,onOpenTarget:ie,onContextChange:Ye,onBackToTask:Ne}){const T=o==="cloud"&&(m||l)||"",[Ke,pe]=a.useState(y),[he,se]=a.useState([]),[x,$e]=a.useState(null),[$t,We]=a.useState(!1),[Re,Xe]=a.useState(""),[Pe,Ve]=a.useState(""),[N,ae]=a.useState([]),[C,L]=a.useState(null),[lt,an]=a.useState(it[re]),[ct,dt]=a.useState(!1),[$,Be]=a.useState("select"),[Kn,be]=a.useState(!1),[ut,on]=a.useState(!1),[W,X]=a.useState(!1),[rn,h]=a.useState(null),[U,R]=a.useState("saved"),[sr,D]=a.useState(null),[ft,ln]=a.useState(!1),[oe,Rt]=a.useState(null),[le,Pt]=a.useState(!1),[Wn,Bt]=a.useState(!1),[Tt,cn]=a.useState("json"),[mt,At]=a.useState(!1),[pt,Et]=a.useState(!1),[Xn,dn]=a.useState(!1),[Vn,ht]=a.useState(!1),[Mt,bt]=a.useState(""),[qe,un]=a.useState(!1),[ce,Je]=a.useState(!1),[Lt,Ze]=a.useState(!1),[P,Ft]=a.useState(1),[G,Qe]=a.useState(!1),[gt,fn]=a.useState(!1),[yt,et]=a.useState({width:0,height:0}),mn=a.useRef(null),Te=a.useRef(null),Ht=a.useRef(null),pn=a.useRef(null),ge=a.useRef(M),ye=a.useRef(""),xt=a.useRef(0),Ot=a.useRef(""),xe=a.useRef(0),vt=a.useRef(null),hn=a.useRef(0),de=a.useRef(!1),tt=a.useRef(null),Dt=a.useRef(null),ve=a.useRef(null),F=a.useRef(""),A=a.useRef(""),_t=a.useRef(null),V=a.useRef(null),Ae=a.useRef(!1),jt=a.useRef(null),nt=a.useRef(null),st=a.useRef(null),_e=a.useRef(null),Ee=a.useRef(null),Me=a.useRef(null),Le=a.useRef(null),ue=a.useRef(null),q=a.useRef(null),bn=a.useRef(null),gn=a.useRef(null),B=a.useMemo(()=>he.find(e=>e.id===x)||null,[x,he]),J=a.useMemo(()=>`workspaceId=${encodeURIComponent(String(g||"default").trim()||"default")}`,[g]),E=a.useMemo(()=>({"x-taskforce-workspace-id":String(g||"default").trim()||"default"}),[g]),z=a.useMemo(()=>N.find(e=>e.id===C)||null,[N,C]),Z=a.useMemo(()=>rt(y),[y]),je=typeof ie=="function",d=je?y:Ke,kt=a.useMemo(()=>{const e=String(d?.taskId||"").trim();if(!e)return"";const n=Ue?.(e).trim()||"";if(n)return n;const r=String(d?.taskReferenceLabel||"").trim();return r&&r!==e?r:n||e},[d?.taskId,d?.taskReferenceLabel,Ue]),at=a.useMemo(()=>{const e=String(d?.assetId||"").trim();if(!e)return"";const n=Ge?.(e).trim()||"";return n||String(d?.imageReferenceLabel||"").trim()},[d?.assetId,d?.imageReferenceLabel,Ge]),zt=a.useMemo(()=>N.findIndex(e=>e.id===C),[N,C]),Ut=z?.color||lt,yn=a.useMemo(()=>Nt({title:Re,globalInstruction:Pe,annotations:N}),[N,Pe,Re]),Fe=a.useMemo(()=>Hn(yn),[yn]),xn=Fe!==A.current,b=a.useMemo(()=>({width:Math.max(yt.width*P,0),height:Math.max(yt.height*P,0)}),[yt.height,yt.width,P]),He=a.useMemo(()=>({visibleRadius:7,hitRadius:11}),[]),Gt=a.useMemo(()=>`0 0 ${Math.max(b.width,1)} ${Math.max(b.height,1)}`,[b.height,b.width]),ke=a.useMemo(()=>{const e=Te.current;return e?P>1||b.width>e.clientWidth+1||b.height>e.clientHeight+1:P>1},[b.height,b.width,P]),Yt=`${Math.round(P*100)}%`,Kt=a.useMemo(()=>{const e=new Map;return N.forEach((n,r)=>{e.set(n.id,r+1)}),e},[N]);a.useEffect(()=>{ge.current=M},[M]),a.useEffect(()=>{const e=pn.current;if(!e||!C)return;e.focus();const n=e.value.length;e.setSelectionRange(n,n)},[C]),a.useEffect(()=>{ve.current=x},[x]),a.useEffect(()=>{We(!1)},[x]),a.useEffect(()=>{if(!z){dt(!1);return}an(z.color||it[z.markerType||re])},[z]);const wt=a.useCallback(async e=>{const n=typeof performance<"u"?performance.now():Date.now(),r=await Ce(`/api/taskforce/annotated-attachments/sessions?${J}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...E},body:JSON.stringify({taskId:e.taskId,baseImageAssetId:e.assetId,title:ze(e),globalInstruction:"",annotations:[]})},T),i=await r.json().catch(()=>({}));if(!r.ok)throw new Error(String(i?.error||"Failed to create session."));const c=i?.session;if(!c?.id)throw new Error("Failed to create session.");return Ct("annotated_session_create_completed",{assetId:e.assetId,taskId:e.taskId||null,sessionId:c.id,durationMs:Math.round((typeof performance<"u"?performance.now():Date.now())-n),debugTimings:i?.debugTimings||null,serverTiming:typeof r.headers?.get=="function"&&r.headers.get("server-timing")||null}),c},[E,T,J]),vn=a.useCallback(e=>new Promise((n,r)=>{const i=new FileReader;i.onload=()=>n(typeof i.result=="string"?i.result:""),i.onerror=()=>r(i.error||new Error("Failed to read clipboard image.")),i.readAsDataURL(e)}),[]),I=a.useCallback(()=>{tt.current!==null&&(window.clearTimeout(tt.current),tt.current=null),st.current!==null&&(window.clearTimeout(st.current),st.current=null)},[]),Oe=a.useCallback(e=>{Xe(e.title),Ve(e.globalInstruction),ae(e.annotations),L(n=>n&&e.annotations.some(r=>r.id===n)?n:e.annotations[0]?.id||null)},[]),fe=a.useCallback((e,n)=>{const r=ze(n||d||{assetId:e.baseImageAssetId,displayName:"Annotated session"}),i=nr(e,r),c=Hn(i);de.current=!0,I(),Oe(i),A.current=c,F.current=c,_t.current=null,Ae.current=!1,jt.current=null,nt.current=null,D(null),R("saved"),X(!1)},[d,Oe,I]),Wt=a.useCallback(e=>{de.current=!0,I(),se([]),$e(null),be(!1),We(!1),Xe(ze(e)),Ve(""),ae([]),L(null),A.current="",F.current="",_t.current=null,Ae.current=!1,jt.current=null,nt.current=null,Rt(null),Bt(!1),D(null),R("saved"),X(!1)},[I]),we=a.useCallback(async(e,n,r)=>{const i=ve.current;if(!i)return!0;if(e===A.current)return V.current||(D(null),R("saved")),!0;if(V.current){if(Ae.current=!0,!r?.waitForInFlight||!await V.current)return!1;const f=F.current;return f===A.current?!0:we(f,n,r)}I();const c=On(e);jt.current=i,_t.current=e,X(!0),h(null),D(null),R("saving");const p=(async()=>{try{const u=await Ce(`/api/taskforce/annotated-attachments/sessions/${encodeURIComponent(i)}?${J}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json",...E},body:JSON.stringify(c)},T),f=await u.json().catch(()=>({}));if(!u.ok)throw new Error(String(f?.error||"Failed to save session."));const v=f?.session;if(!v?.id)throw new Error("Failed to save session.");se(Vt=>{const Rn=Vt.findIndex(ys=>ys.id===v.id);if(Rn===-1)return[v,...Vt];const Pn=[...Vt];return Pn[Rn]=v,Pn}),A.current=e,nt.current=null,D(null);const k=ve.current===v.id,S=F.current,K=S!==e,ot=Ae.current||K;return Ae.current=!1,k&&!ot?(de.current=!0,Oe(c),R("saved")):!ot&&S===A.current?R("saved"):R("pending"),!0}catch(u){const f=u instanceof Error?u.message:"Failed to save session.";return h(f),D(f),R("error"),nt.current!==e&&ve.current===i&&F.current===e&&(nt.current=e,st.current=window.setTimeout(()=>{st.current=null,!(ve.current!==i||F.current!==e)&&we(e,n,{waitForInFlight:!0})},1500)),!1}finally{_t.current=null,V.current=null,jt.current=null,X(!1)}})();V.current=p;const j=await p;if(j){const u=F.current;if(u!==A.current)return we(u,n,r)}return j},[Oe,I,E,T,J]),_n=a.useCallback(e=>{if(ve.current){if(F.current===A.current){D(null),V.current||R("saved");return}U!=="saving"&&R("pending"),I(),tt.current=window.setTimeout(()=>{tt.current=null,we(F.current,"structure")},e)}},[I,we,U]),Y=a.useCallback(e=>{Dt.current=e},[]),H=a.useCallback(async e=>{I();const n=F.current;return!ve.current||n===A.current?(D(null),V.current||R("saved"),!0):we(n,e,{waitForInFlight:!0})},[I,we]),qn=a.useCallback(()=>{const e=A.current;e&&(I(),de.current=!0,Oe(On(e)),D(null),R("saved"),h(null))},[Oe,I]),Q=a.useCallback(async(e,n)=>{const r=typeof performance<"u"?performance.now():Date.now(),i=JSON.stringify({targetKey:rt(e),requestedSessionId:n?.requestedSessionId??null,autoCreateIfEmpty:n?.autoCreateIfEmpty===!0});if(vt.current===i)return;const c=xe.current+1;xe.current=c,vt.current=i,on(!0),h(null);try{const p=new URLSearchParams;g&&p.set("workspaceId",g),e.taskId&&p.set("taskId",e.taskId),p.set("imageAssetId",e.assetId);const j=await Ce(`/api/taskforce/annotated-attachments/sessions?${p.toString()}`,{credentials:"include",headers:E,cache:"no-store"},T),u=await j.json().catch(()=>({}));if(!j.ok)throw new Error(String(u?.error||"Failed to load annotated attachment sessions."));const f=Array.isArray(u?.sessions)?u.sessions:[];if(Ct("annotated_sessions_loaded",{assetId:e.assetId,taskId:e.taskId||null,requestedSessionId:n?.requestedSessionId??null,autoCreateIfEmpty:n?.autoCreateIfEmpty===!0,sessionCount:f.length,durationMs:Math.round((typeof performance<"u"?performance.now():Date.now())-r),serverTiming:typeof j.headers?.get=="function"&&j.headers.get("server-timing")||null}),f.length===0&&n?.autoCreateIfEmpty&&String(e.assetId||"").trim()){const S=n?.requestedSessionId??ge.current;if(ge.current=null,S&&h("The previously selected annotation session could not be restored."),xe.current!==c)return;const K=await wt(e);if(Ct("annotated_sessions_auto_created_after_empty_load",{assetId:e.assetId,taskId:e.taskId||null,sessionId:K.id,totalDurationMs:Math.round((typeof performance<"u"?performance.now():Date.now())-r)}),xe.current!==c)return;se([K]),$e(K.id),be(!1),fe(K,e);return}if(xe.current!==c)return;se(f),be(f.length===0);const v=n?.requestedSessionId??ge.current;ge.current=null;const k=f.find(S=>S.id===v)||f[0]||null;v&&!k&&h("The previously selected annotation session could not be restored."),$e(k?.id||null),k?fe(k,e):(de.current=!0,I(),Xe(ze(e)),Ve(""),ae([]),L(null),A.current="",F.current="",D(null),R("saved"))}catch(p){if(xe.current!==c)return;h(p instanceof Error?p.message:"Failed to load sessions.")}finally{vt.current===i&&(vt.current=null),xe.current===c&&on(!1)}},[I,wt,E,T,fe,g]),Jn=a.useCallback(async()=>{if(typeof navigator>"u"||!navigator.clipboard||typeof navigator.clipboard.read!="function"){h("Clipboard image paste is not supported in this environment.");return}fn(!0),h(null),hn.current=Date.now()+2e3;try{const n=(await navigator.clipboard.read()).find(v=>v.types.some(k=>k.startsWith("image/"))),r=n?.types.find(v=>v.startsWith("image/"))||"";if(!n||!r)throw new Error("No image found on the clipboard.");const i=await n.getType(r),c=await vn(i);if(!c)throw new Error("Failed to read clipboard image.");const p=r==="image/jpeg"?"jpg":r==="image/webp"?"webp":r==="image/gif"?"gif":"png",j=await fetch("/api/taskforce/context-upload",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...E},body:JSON.stringify({file:c,originalName:`pasted-image.${p}`,workspaceId:String(g||"default").trim()||"default"})}),u=await j.json().catch(()=>({}));if(!j.ok||!u?.success||typeof u?.assetId!="string"||typeof u?.path!="string")throw new Error(String(u?.error||"Failed to paste image into Image Notes."));const f={assetId:u.assetId,imageReferenceLabel:typeof u?.referenceLabel=="string"?u.referenceLabel:void 0,path:u.path,displayName:typeof u?.displayName=="string"&&u.displayName.trim().length>0?u.displayName.trim():"Pasted image"};ge.current=null,je?(ye.current="",ie?.(f,{sessionId:null})):(pe(f),ye.current=rt(f),Q(f,{autoCreateIfEmpty:!0}))}catch(e){h(e instanceof Error?e.message:"Failed to paste image.")}finally{fn(!1)}},[je,Q,ie,vn,E,g]),Zn=a.useCallback(async()=>{const e=Mt.trim();if(!e){h("Enter an image reference to open.");return}un(!0),h(null);try{const n=new URLSearchParams({workspaceId:String(g||"default").trim()||"default"}),r=await Ce(`/api/taskforce/annotated-attachments/images/${encodeURIComponent(e)}?${n.toString()}`,{method:"GET",credentials:"include",headers:E}),i=await r.json().catch(()=>({}));if(!r.ok||!i?.target||typeof i.target.assetId!="string"||typeof i.target.path!="string")throw new Error(String(i?.error||"Failed to open image reference."));const c={assetId:i.target.assetId,path:i.target.path,displayName:typeof i.target.displayName=="string"&&i.target.displayName.trim().length>0?i.target.displayName.trim():"Image attachment",taskId:typeof i.target.taskId=="string"&&i.target.taskId.trim().length>0?i.target.taskId.trim():void 0,taskReferenceLabel:typeof i.target.taskReferenceLabel=="string"&&i.target.taskReferenceLabel.trim().length>0?i.target.taskReferenceLabel.trim():void 0,imageReferenceLabel:typeof i.target.imageReferenceLabel=="string"&&i.target.imageReferenceLabel.trim().length>0?i.target.imageReferenceLabel.trim():void 0};ge.current=null,ht(!1),bt(""),je?(ye.current="",ie?.(c,{sessionId:null})):(pe(c),ye.current=rt(c),Q(c,{autoCreateIfEmpty:!0}))}catch(n){h(n instanceof Error?n.message:"Failed to open image reference.")}finally{un(!1)}},[je,Q,ie,Mt,E,g]),jn=a.useCallback(e=>{se(n=>{const r=n.findIndex(c=>c.id===e.id);if(r===-1)return[e,...n];const i=[...n];return i[r]=e,i}),$e(e.id),fe(e,d)},[d,fe]),kn=a.useCallback(e=>{se(n=>{const r=n.filter(c=>c.id!==e),i=r[0]||null;return $e(i?.id||null),i?fe(i,d):(de.current=!0,I(),Xe(ze(d||{displayName:"Annotated session"})),Ve(""),ae([]),L(null),A.current="",F.current="",D(null),R("saved")),r})},[d,I,fe]);a.useEffect(()=>{if(!y)return;if(je||pe(n=>n&&rt(n)===Z&&n.taskReferenceLabel===y.taskReferenceLabel&&n.imageReferenceLabel===y.imageReferenceLabel&&n.displayName===y.displayName?n:y),!w){Z&&(Z!==ye.current||ne!==xt.current)&&Z!==Ot.current&&(Wt(y),Ot.current=Z,xt.current=ne,Ct("annotated_sessions_load_deferred",{assetId:y.assetId,taskId:y.taskId||null,requestedTargetKey:Z})),me?.();return}Z&&(Z!==ye.current||ne!==xt.current)&&(Wt(y),ye.current=Z,xt.current=ne,Ot.current="",Q(y,{autoCreateIfEmpty:!0})),me?.()},[je,Q,me,ne,y,Z,Wt,M,w]),a.useEffect(()=>{d&&Ye?.({target:d,sessionId:x})},[d,Ye,x]),a.useEffect(()=>{if(!d||typeof document>"u"||!w)return;const e=()=>{Date.now()<hn.current||F.current!==A.current||W||ut||Q(d,{requestedSessionId:x})},n=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",n),()=>{document.removeEventListener("visibilitychange",n)}},[d,Q,ut,W,x,w]),a.useEffect(()=>{if(!d?.path){Je(!1),Ze(!1),et({width:0,height:0});return}Je(!0),Ze(!1),et({width:0,height:0}),Ft(1),Qe(!1)},[d?.path]),a.useEffect(()=>{if(!ce)return;const e=Ht.current;!e||!e.complete||e.naturalWidth<=0||e.naturalHeight<=0||(et({width:e.naturalWidth,height:e.naturalHeight}),Je(!1),Ze(!1))},[d?.path,ce]),a.useEffect(()=>{ke||Qe(!1)},[ke]),a.useEffect(()=>{Rt(null)},[x]),a.useEffect(()=>{if(F.current=Fe,de.current){de.current=!1;return}if(!x){I(),D(null),R("saved");return}if(Fe===A.current){I(),V.current||(D(null),R("saved"));return}const e=Dt.current;if(Dt.current=null,U==="error"&&e===null)return;const n=e??600;if(V.current){Ae.current=!0,R("pending");return}_n(n)},[I,Fe,U,_n,x]),a.useEffect(()=>{x&&(V.current||Fe===A.current&&U!=="error"&&U!=="saved"&&(D(null),R("saved")))},[Fe,U,x]),a.useEffect(()=>{if(typeof window>"u")return;const e=n=>{F.current!==A.current&&(n.preventDefault(),n.returnValue="")};return window.addEventListener("beforeunload",e),()=>window.removeEventListener("beforeunload",e)},[]),a.useEffect(()=>{if(typeof document>"u")return;const e=()=>{document.visibilityState==="hidden"&&H("visibility-hidden")};return document.addEventListener("visibilitychange",e),()=>document.removeEventListener("visibilitychange",e)},[H]),a.useEffect(()=>{if(!ct||typeof document>"u")return;const e=n=>{const r=n.target;r instanceof Node&&(bn.current?.contains(r)||dt(!1))};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[ct]),a.useEffect(()=>{if(!$t||typeof document>"u")return;const e=n=>{const r=n.target;r instanceof Node&&(gn.current?.contains(r)||We(!1))};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[$t]),a.useEffect(()=>()=>{I()},[I]),a.useEffect(()=>{if(!le)return;const e=window.setTimeout(()=>Pt(!1),2e3);return()=>window.clearTimeout(e)},[le]),a.useEffect(()=>{if(!mt)return;const e=window.setTimeout(()=>At(!1),2e3);return()=>window.clearTimeout(e)},[mt]),a.useEffect(()=>{if(!pt)return;const e=window.setTimeout(()=>Et(!1),2e3);return()=>window.clearTimeout(e)},[pt]);const ee=a.useCallback((e,n,r=300)=>{ae(i=>Ie(i.map(c=>c.id===e?n(c):c))),Y(r)},[Y]),Qn=a.useCallback(e=>{z&&(ee(z.id,n=>({...n,color:e})),an(e),dt(!1))},[z,ee]),wn=a.useCallback(async()=>{if(!(!d||!await H("session-switch"))){X(!0),h(null);try{const n=await wt(d);be(!1),await Q(d,{requestedSessionId:n.id,autoCreateIfEmpty:!1}),Be("select")}catch(n){h(n instanceof Error?n.message:"Failed to create session."),be(!0)}finally{X(!1)}}},[d,wt,H,Q]),es=a.useCallback(e=>{if(e!=="select"&&!B){Qe(!1),h("No session exists for this image yet."),be(!0);return}h(null),be(!1),Qe(!1),Be(e)},[B]),ts=a.useCallback(async()=>{if(!(!d||!B||!await H("duplicate"))){X(!0),h(null);try{const n=Ie(N.map((p,j)=>Xo(p,j))),r=await Ce(`/api/taskforce/annotated-attachments/sessions?${J}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...E},body:JSON.stringify({taskId:d.taskId,baseImageAssetId:d.assetId,title:Vo(Re||B.title,d),globalInstruction:Pe,annotations:n})},T),i=await r.json().catch(()=>({}));if(!r.ok)throw new Error(String(i?.error||"Failed to duplicate session."));const c=i?.session;if(!c?.id)throw new Error("Failed to duplicate session.");jn(c),Be("select")}catch(n){h(n instanceof Error?n.message:"Failed to duplicate session.")}finally{X(!1)}}},[d,N,Pe,Re,jn,H,E,T,B,J]),ns=a.useCallback(async()=>H("manual"),[H]),Cn=a.useCallback(async()=>{if(x){ln(!0),h(null);try{const e=await Ce(`/api/taskforce/annotated-attachments/sessions/${encodeURIComponent(x)}/payload?${J}`,{credentials:"include",headers:E},T),n=await e.json().catch(()=>({}));if(!e.ok)throw new Error(String(n?.error||"Failed to load payload preview."));Rt(n?.payload||null)}catch(e){h(e instanceof Error?e.message:"Failed to load payload preview.")}finally{ln(!1)}}},[E,T,x,J]),ss=a.useCallback(()=>{x&&H("payload-preview").then(e=>{e&&(Bt(!0),Cn())})},[H,Cn,x]),In=a.useCallback(async e=>{if(!oe||!navigator.clipboard||typeof navigator.clipboard.writeText!="function"){h("Clipboard copy is not available in this browser.");return}try{const n=e==="json"?JSON.stringify(oe,null,2):Fn(oe);await navigator.clipboard.writeText(n),Pt(e)}catch(n){h(n instanceof Error?n.message:"Failed to copy payload content."),Pt(!1)}},[oe]),as=a.useCallback(async()=>{if(!kt||!navigator.clipboard||typeof navigator.clipboard.writeText!="function"){h("Clipboard copy is not available in this browser.");return}try{await navigator.clipboard.writeText(kt),At(!0)}catch(e){h(e instanceof Error?e.message:"Failed to copy task id."),At(!1)}},[kt]),os=a.useCallback(async()=>{if(!at||!navigator.clipboard||typeof navigator.clipboard.writeText!="function"){h("Clipboard copy is not available in this browser.");return}try{await navigator.clipboard.writeText(at),Et(!0)}catch(e){h(e instanceof Error?e.message:"Failed to copy image reference."),Et(!1)}},[at]),rs=a.useCallback(async()=>{if(!x||!await H("delete-session"))return;const n=(B?.title||"Untitled session").trim()||"Untitled session";if(window.confirm(`Delete the annotated attachment session "${n}"?`)){X(!0),h(null);try{const r=await Ce(`/api/taskforce/annotated-attachments/sessions/${encodeURIComponent(x)}?${J}`,{method:"DELETE",credentials:"include",headers:E},T),i=await r.json().catch(()=>({}));if(!r.ok)throw new Error(String(i?.error||"Failed to delete session."));kn(x),Be("select")}catch(r){h(r instanceof Error?r.message:"Failed to delete session.")}finally{X(!1)}}},[H,kn,E,T,B,x,J]),Xt=a.useCallback(()=>{C&&(ae(e=>Ie(e.filter(n=>n.id!==C))),L(null),Y(300))},[Y,C]),De=a.useCallback(e=>{const n=tr(e),r=Te.current;if(!r||n===P){Ft(n);return}const i=(r.scrollLeft+r.clientWidth/2)*(n/P)-r.clientWidth/2,c=(r.scrollTop+r.clientHeight/2)*(n/P)-r.clientHeight/2;Ft(n),window.requestAnimationFrame(()=>{r.scrollLeft=Math.max(0,i),r.scrollTop=Math.max(0,c)})},[P]),is=a.useCallback(()=>{De(P+.25)},[De,P]),ls=a.useCallback(()=>{De(P-.25)},[De,P]),cs=a.useCallback(()=>{De(1);const e=Te.current;e&&window.requestAnimationFrame(()=>{e.scrollLeft=0,e.scrollTop=0})},[De]),Sn=a.useCallback(e=>{C&&ae(n=>{const r=n.findIndex(c=>c.id===C);if(r===-1)return n;const i=e==="up"?r-1:r+1;return i<0||i>=n.length?n:(Y(300),qo(n,r,i))})},[Y,C]);a.useEffect(()=>{if(!C)return;const e=n=>{n.key==="Delete"&&(Go(n.target)||(n.preventDefault(),Xt()))};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[Xt,C]);const O=a.useCallback(e=>{const n=mn.current?.getBoundingClientRect();return!n||n.width<=0||n.height<=0?null:{x:_((e.clientX-n.left)/n.width),y:_((e.clientY-n.top)/n.height)}},[]),ds=a.useCallback(e=>{if(G&&ke){const i=Te.current;if(!i)return;q.current={pointerId:e.pointerId,startX:e.clientX,startY:e.clientY,scrollLeft:i.scrollLeft,scrollTop:i.scrollTop},e.currentTarget.setPointerCapture(e.pointerId),e.preventDefault();return}if(!x)return;if($==="select"){L(null);return}const n=O(e);if(!n)return;if($==="pin"||$==="text-note"){const i=Ln($,n,n,lt);ae(c=>Ie([...c,i])),L(i.id),Y(300),Be("select");return}_e.current=n;const r=Ln($,n,n,lt);ue.current={annotationId:r.id,kind:$},e.currentTarget.setPointerCapture?.(e.pointerId),ae(i=>Ie([...i,r])),L(r.id),Y(300)},[ke,lt,Y,G,O,x,$]),us=a.useCallback(e=>{if(q.current?.pointerId===e.pointerId){e.currentTarget.releasePointerCapture?.(e.pointerId);return}if(!_e.current||!ue.current||$!=="box"&&$!=="arrow")return;const n=O(e);_e.current=null,ue.current=null,e.currentTarget.releasePointerCapture?.(e.pointerId),n&&Be("select")},[O,$]),Nn=a.useCallback((e,n)=>{if($!=="select"||G)return;const r=O(e);r&&(Ee.current={annotationId:n.id,originPointer:r,originAnnotation:n},L(n.id),e.stopPropagation())},[G,O,$]),fs=a.useCallback(e=>{if(q.current?.pointerId===e.pointerId){const u=Te.current;if(!u)return;const f=e.clientX-q.current.startX,v=e.clientY-q.current.startY;u.scrollLeft=q.current.scrollLeft-f,u.scrollTop=q.current.scrollTop-v;return}if(ue.current&&_e.current){const u=O(e);if(!u)return;const{annotationId:f,kind:v}=ue.current,k=_e.current;ee(f,S=>v==="box"&&S.kind==="box"?{...S,x:_(Math.min(k.x,u.x)),y:_(Math.min(k.y,u.y)),width:Se(Math.abs(u.x-k.x)),height:Se(Math.abs(u.y-k.y))}:v==="arrow"&&S.kind==="arrow"?{...S,x:k.x,y:k.y,x2:u.x,y2:u.y}:S);return}if(Me.current){const u=O(e);if(!u)return;const{annotationId:f,originPointer:v,originAnnotation:k}=Me.current,S=u.x-v.x,K=u.y-v.y;ee(f,()=>({...k,width:Se(k.width+S),height:Se(k.height+K)}));return}if(Le.current){const u=O(e);if(!u)return;const{annotationId:f,endpoint:v,originPointer:k,originAnnotation:S}=Le.current,K=u.x-k.x,ot=u.y-k.y;ee(f,()=>v==="tail"?{...S,x:_(S.x+K),y:_(S.y+ot)}:{...S,x2:_(S.x2+K),y2:_(S.y2+ot)});return}if(!Ee.current)return;const n=O(e);if(!n)return;const{annotationId:r,originPointer:i,originAnnotation:c}=Ee.current,p=n.x-i.x,j=n.y-i.y;ee(r,()=>c.kind==="pin"||c.kind==="text-note"?{...c,x:_(c.x+p),y:_(c.y+j)}:c.kind==="box"?{...c,x:_(c.x+p),y:_(c.y+j)}:{...c,x:_(c.x+p),y:_(c.y+j),x2:_(c.x2+p),y2:_(c.y2+j)})},[O,ee]),ms=a.useCallback(()=>{_e.current=null,Ee.current=null,Me.current=null,Le.current=null,ue.current=null,q.current=null},[]),ps=a.useCallback(()=>{_e.current=null,Ee.current=null,Me.current=null,Le.current=null,ue.current=null,q.current=null},[]),hs=a.useCallback(()=>{Ee.current=null,Me.current=null,Le.current=null,ue.current=null,q.current=null},[]),bs=a.useCallback((e,n)=>{if($!=="select"||G)return;const r=O(e);r&&(Me.current={annotationId:n.id,originPointer:r,originAnnotation:n},L(n.id),e.stopPropagation())},[G,O,$]),$n=a.useCallback((e,n,r)=>{if($!=="select"||G)return;const i=O(e);i&&(Le.current={annotationId:n.id,originPointer:i,originAnnotation:n,endpoint:r},L(n.id),e.stopPropagation())},[G,O,$]),gs=B?.updatedAt?Qt(B.updatedAt):"Not saved yet";return t.jsxs("div",{className:s.shell,children:[t.jsxs("section",{className:`tf-surface-panel ${s.panel} ${s.sessionPanel}`,children:[t.jsx("div",{className:s.sessionContextBar,children:d?.taskId?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:s.sessionContextLeft,children:Ne?t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.backToTaskBtn}`,onClick:()=>{H("back-to-task").then(e=>{e&&d.taskId&&Ne(d.taskId)})},"aria-label":"Back to task",title:"Back to task",children:t.jsx(_s,{size:16})}):t.jsx("div",{className:s.sessionContextSpacer,"aria-hidden":"true"})}),t.jsx("div",{className:s.sessionContextRight,children:t.jsx(vs,{copied:mt,onClick:()=>{as()},title:"Copy task id",ariaLabel:mt?"Copied task id":"Copy task id",label:kt})})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:s.sessionContextLeft,children:t.jsx("span",{className:`tf-label-micro ${s.sessionContextLabel}`,children:"Unattached Image"})}),t.jsx("div",{className:s.sessionContextRight,children:t.jsx("div",{className:s.sessionContextSpacer,"aria-hidden":"true"})})]})}),t.jsxs("div",{className:s.panelHeader,children:[t.jsxs("div",{className:s.panelHeaderText,children:[t.jsx("div",{className:`tf-heading-card ${s.panelTitle}`,children:"Sessions"}),d?null:t.jsx("div",{className:"tf-text-secondary",children:"Open an image attachment to begin"})]}),t.jsx("div",{className:s.sessionActions,children:t.jsx("button",{type:"button",className:`tf-control-icon ${s.iconButton}`,onClick:()=>{wn()},disabled:!d||W,"aria-label":"Create session",title:"Create session",children:t.jsx(js,{size:16})})})]}),d?ut?t.jsx("div",{className:s.emptyState,children:t.jsx("p",{className:"tf-empty-copy",children:"Loading sessions…"})}):t.jsx("div",{className:`tf-scrollbar ${s.sessionList}`,children:he.length===0?t.jsxs("div",{className:s.sessionEmptyState,children:[t.jsx("div",{className:`tf-heading-card ${s.sessionTitle}`,children:"No sessions yet"}),t.jsx("div",{className:`tf-text-secondary ${s.annotationSummary}`,children:"Create the first annotation session for this image."})]}):he.map(e=>{const n=x===e.id,r=n&&$t,i=Yo(n?Pe:e.globalInstruction),c=(n?Re:e.title)||"Untitled session";return t.jsxs("div",{className:`tf-surface-elevated ${s.sessionCard} ${n?s.sessionCardActive:""}`,ref:n?gn:void 0,onBlur:r?p=>{const j=p.relatedTarget;j instanceof Node&&p.currentTarget.contains(j)||We(!1)}:void 0,children:[r?t.jsxs("div",{className:s.sessionCardBody,children:[t.jsxs("div",{className:s.sessionMeta,children:[t.jsx("label",{className:"tf-field-label",htmlFor:"annotated-session-title",children:"Session title"}),t.jsx("input",{id:"annotated-session-title",className:`tf-field-shell ${s.textInput} ${s.sessionTitleInput}`,value:Re,onChange:p=>{Xe(p.target.value),Y(600)},placeholder:"Session title"}),t.jsx("span",{className:`tf-text-meta ${s.sessionTimestamp}`,children:Qt(e.updatedAt)})]}),St(e)?t.jsxs("div",{className:`tf-text-secondary ${s.sessionCreator}`,children:["Created by ",St(e)]}):null,t.jsxs("div",{className:s.sessionInstructionEditor,children:[t.jsx("label",{className:"tf-field-label",htmlFor:"annotated-session-instruction",children:"Session instruction"}),t.jsx("textarea",{id:"annotated-session-instruction",className:`tf-field-shell ${s.textArea} ${s.sessionInstructionField}`,value:Pe,onChange:p=>{Ve(p.target.value),Y(600)},placeholder:"Add overall instructions, context, or framing for this session."})]}),t.jsxs("div",{className:`tf-text-secondary ${s.annotationSummary}`,children:[e.annotations.length," annotation",e.annotations.length===1?"":"s"]})]}):t.jsxs("button",{type:"button",className:s.sessionCardButton,onClick:()=>{if(n){We(!0);return}H("session-switch").then(p=>{p&&($e(e.id),fe(e,d))})},"aria-pressed":n,children:[t.jsxs("div",{className:s.sessionMeta,children:[t.jsx("span",{className:`tf-heading-card ${s.sessionTitle}`,children:c}),t.jsx("span",{className:`tf-text-meta ${s.sessionTimestamp}`,children:Qt(e.updatedAt)})]}),St(e)?t.jsxs("div",{className:`tf-text-secondary ${s.sessionCreator}`,children:["Created by ",St(e)]}):null,i?t.jsx("div",{className:`tf-text-secondary ${s.sessionInstructionPreview}`,children:i}):null,t.jsxs("div",{className:`tf-text-secondary ${s.annotationSummary}`,children:[e.annotations.length," annotation",e.annotations.length===1?"":"s"]})]}),n?t.jsx("div",{className:s.sessionCardFooter,children:t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button",className:`tf-button-ghost ${s.toolRailButton} ${s.iconButton}`,onClick:()=>{ts()},disabled:W,"aria-label":"Duplicate session",title:`Duplicate session "${c}"`,children:t.jsx(Zt,{size:16})}),t.jsx("button",{type:"button",className:`tf-button-ghost ${s.toolRailButton} ${s.iconButton}`,onClick:()=>{rs()},disabled:W,"aria-label":"Delete session",title:`Delete session "${c}"`,children:t.jsx(Tn,{size:16})})]})}):null]},e.id)})}):t.jsxs("div",{className:s.emptyState,children:[t.jsx("strong",{className:"tf-empty-title",children:"No image selected"}),t.jsx("p",{className:"tf-empty-copy",children:"Open an image attachment from a task to start an annotated session."})]})]}),t.jsxs("section",{className:`tf-surface-panel ${s.panel} ${s.canvasPanel}`,children:[t.jsxs("div",{className:s.panelHeader,children:[t.jsxs("div",{className:s.canvasHeading,children:[t.jsx("div",{className:"tf-heading-card",children:d?.displayName||"Annotated attachment"}),t.jsx("div",{className:"tf-text-secondary",children:B?`${N.length} markers · ${gs}`:"Pick or create a session"})]}),at?t.jsx(Ts,{copied:pt,onClick:()=>{os()},title:"Copy image reference",ariaLabel:pt?"Copied image reference":"Copy image reference",label:at}):null]}),t.jsxs("div",{className:s.toolRail,children:[t.jsxs("div",{className:`${s.toolbarCluster} ${s.toolbarViewportCluster}`,children:[t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>{ns()},disabled:!B||W||!xn&&U!=="error","aria-label":W?"Saving session":"Save session",title:W?"Saving session":"Save session",children:t.jsx(ks,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>ht(!0),disabled:qe,"aria-label":"Open image",title:"Open image",children:t.jsx(ws,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>{Jn()},disabled:gt,"aria-label":gt?"Pasting image":"Paste image",title:gt?"Pasting image":"Paste image",children:gt?t.jsx(An,{size:18,className:Bn.spin}):t.jsx(Cs,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>{B&&qn()},disabled:!B||!xn,"aria-label":"Reset unsaved changes",title:"Reset unsaved changes",children:t.jsx(Is,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost ${s.toolRailButton} ${s.iconButton}`,onClick:ls,disabled:!d||ce||P<=.25,"aria-label":"Zoom out",children:t.jsx(Ss,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:cs,disabled:!d||ce||P===1,"aria-label":`Reset zoom to 100 percent (currently ${Yt})`,title:`Reset zoom to 100% (currently ${Yt})`,children:t.jsx("span",{children:Yt})}),t.jsx("button",{type:"button",className:`tf-button-ghost ${s.toolRailButton} ${s.iconButton}`,onClick:is,disabled:!d||ce||P>=4,"aria-label":"Zoom in",children:t.jsx(Ns,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.toolBtn} ${s.toolbarButton} ${G?s.toolBtnActive:""}`,onClick:()=>Qe(e=>!e),disabled:!d||ce||!ke,"aria-label":"Pan canvas",title:"Pan canvas",children:t.jsx($s,{size:18})})]}),t.jsx("span",{className:s.toolbarSeparator,"aria-hidden":"true"}),t.jsxs("div",{className:s.toolbarActions,children:[t.jsx("div",{className:s.toolbarSelectionActions,children:z?t.jsxs(t.Fragment,{children:[t.jsxs("div",{ref:bn,className:s.toolbarColorPicker,children:[t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton} ${s.colorPickerButton}`,onClick:()=>dt(e=>!e),"aria-label":"Marker color","aria-expanded":ct,title:"Marker color",children:t.jsx("span",{className:s.colorPickerSwatch,style:{backgroundColor:Ut},"aria-hidden":"true"})}),ct?t.jsx("div",{className:s.colorPickerPopover,role:"menu","aria-label":"Marker color options",children:Uo.map(e=>t.jsx("button",{type:"button",className:`${s.colorOption} ${Ut===e?s.colorOptionActive:""}`,style:{backgroundColor:e},onClick:()=>Qn(e),"aria-label":`Use marker color ${e}`,"aria-pressed":Ut===e},e))}):null]}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:Xt,"aria-label":"Delete marker",title:"Delete selected marker",children:t.jsx(Tn,{size:18})}),t.jsx("div",{className:s.toolbarGeometryFields,"aria-label":"Marker geometry percent controls",children:Qo(z).map(e=>t.jsxs("label",{className:s.toolbarGeometryField,children:[t.jsx("span",{className:`tf-text-meta ${s.toolbarGeometryLabel}`,children:e.label}),t.jsx("input",{className:`tf-field-shell ${s.toolbarGeometryInput}`,type:"number",min:0,max:100,step:.1,value:e.value,onChange:n=>{const r=Jo(n.target.value);r!==null&&ee(z.id,i=>Zo(i,e.key,r))},"aria-label":`${e.label} percent`})]},e.key))})]}):null}),t.jsxs("div",{className:s.toolbarUtilities,children:[t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.payloadBtn} ${s.toolbarButton}`,onClick:ss,disabled:!B||ft,"aria-label":ft?"Loading payload preview":"Preview payload",title:ft?"Loading payload preview":"Preview payload",children:t.jsx(tn,{size:18})}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>dn(!0),"aria-label":"How to use marker tools",title:"How to use marker tools",children:t.jsx(nn,{size:18})})]})]})]}),t.jsxs("div",{className:s.canvasWorkspace,children:[t.jsx("div",{className:s.canvasToolRail,"aria-label":"Annotation tools",children:Mn.map(e=>{const n=e.icon;return t.jsx("button",{type:"button",className:`tf-button-ghost ${s.toolRailButton} ${$===e.value?s.toolBtnActive:""}`,onClick:()=>es(e.value),disabled:!d,title:e.label,"aria-label":`${e.label} tool. ${It[e.value].short}`,children:t.jsx(n,{size:18})},e.value)})}),t.jsx("div",{className:s.canvasMain,children:t.jsx("div",{ref:Te,className:`tf-scrollbar ${s.canvasScroller}`,children:d?t.jsxs(t.Fragment,{children:[ce&&!Lt?t.jsx("div",{className:s.canvasStatusOverlay,"aria-live":"polite",children:t.jsxs("div",{className:s.canvasStatusCard,children:[t.jsx(An,{size:20,className:Bn.spinner}),t.jsx("span",{children:"Loading image…"})]})}):null,Lt?t.jsx("div",{className:s.canvasStatusOverlay,"aria-live":"polite",children:t.jsx("div",{className:s.canvasStatusCard,children:t.jsx("span",{children:"Image failed to load."})})}):null,t.jsx("div",{className:s.canvasFrame,children:t.jsxs("div",{className:s.canvasMedia,style:{width:b.width?`${b.width}px`:void 0,height:b.height?`${b.height}px`:void 0},children:[t.jsx("img",{ref:Ht,src:d.path,alt:d.displayName,className:s.canvasImage,onLoad:()=>{const e=Ht.current;et({width:e?.naturalWidth||0,height:e?.naturalHeight||0}),Je(!1),Ze(!1)},onError:()=>{et({width:0,height:0}),Je(!1),Ze(!0)}}),!ce&&!Lt&&B?t.jsxs("div",{ref:mn,className:`${s.overlay} ${$==="select"?s.overlaySelect:""} ${G&&ke?s.overlayPan:""}`,onPointerDown:ds,onPointerMove:fs,onPointerUp:e=>{us(e),hs()},"data-testid":"annotated-attachment-overlay",onPointerLeave:ms,onPointerCancel:ps,children:[t.jsx("svg",{className:s.overlaySvg,viewBox:Gt,preserveAspectRatio:"none","aria-hidden":"true",children:N.filter(e=>e.kind==="arrow").map(e=>{const n=Ko(e,b),r=en(e),i=C===e.id;return t.jsxs(qt.Fragment,{children:[i?t.jsxs(t.Fragment,{children:[t.jsx("line",{x1:n.shaftX1,y1:n.shaftY1,x2:n.shaftX2,y2:n.shaftY2,stroke:"color-mix(in srgb, var(--surface-elevated) 92%, transparent)",strokeWidth:14,strokeLinecap:"round"}),t.jsx("polygon",{points:n.headPoints,fill:r,stroke:"color-mix(in srgb, var(--surface-elevated) 92%, transparent)",strokeWidth:4,strokeLinejoin:"round"})]}):null,t.jsx("line",{x1:n.shaftX1,y1:n.shaftY1,x2:n.shaftX2,y2:n.shaftY2,stroke:r,strokeWidth:i?10:6,strokeLinecap:"round"}),t.jsx("polygon",{points:n.headPoints,fill:r})]},e.id)})}),t.jsx("svg",{className:s.overlayHitLayer,viewBox:Gt,preserveAspectRatio:"none",children:N.filter(e=>e.kind==="arrow").map(e=>t.jsxs(qt.Fragment,{children:[t.jsx("line",{x1:e.x*b.width,y1:e.y*b.height,x2:e.x2*b.width,y2:e.y2*b.height,className:s.arrowHitArea,"data-testid":`annotated-arrow-hit-${e.id}`,"aria-label":`Arrow marker ${Kt.get(e.id)||0}`,onPointerDown:n=>Nn(n,e),onClick:n=>{n.stopPropagation(),L(e.id)}}),C===e.id?t.jsxs(t.Fragment,{children:[t.jsx("circle",{cx:e.x*b.width,cy:e.y*b.height,r:He.hitRadius,className:s.canvasHandleHit,role:"button",tabIndex:0,"aria-label":"Move arrow tail",onPointerDown:n=>$n(n,e,"tail")}),t.jsx("circle",{cx:e.x*b.width,cy:e.y*b.height,r:He.visibleRadius,className:s.canvasHandleVisible,"aria-hidden":"true"}),t.jsx("circle",{cx:e.x2*b.width,cy:e.y2*b.height,r:He.hitRadius,className:s.canvasHandleHit,role:"button",tabIndex:0,"aria-label":"Move arrow tip",onPointerDown:n=>$n(n,e,"tip")}),t.jsx("circle",{cx:e.x2*b.width,cy:e.y2*b.height,r:He.visibleRadius,className:s.canvasHandleVisible,"aria-hidden":"true"})]}):null]},`hit-${e.id}`))}),N.filter(e=>e.kind==="arrow").map(e=>t.jsx("div",{className:`${s.annotationNumberBadge} ${s.arrowNumberBadge}`,style:{left:`${(e.x+e.x2)/2*100}%`,top:`${(e.y+e.y2)/2*100}%`,backgroundColor:en(e)},"aria-hidden":"true",children:Kt.get(e.id)||0},`arrow-number-${e.id}`)),N.filter(e=>e.kind!=="arrow").map(e=>{const n=en(e),r=Kt.get(e.id)||0,i={onPointerDown:c=>Nn(c,e),onClick:c=>{c.stopPropagation(),L(e.id)}};return e.kind==="pin"?t.jsx("button",{type:"button",...i,className:`${s.pin} ${C===e.id?s.selected:""}`,style:{left:`${e.x*100}%`,top:`${e.y*100}%`,backgroundColor:n},children:r},e.id):e.kind==="text-note"?t.jsx("button",{type:"button",...i,className:`${s.note} ${C===e.id?s.selected:""}`,style:{left:`${e.x*100}%`,top:`${e.y*100}%`,backgroundColor:n},children:r},e.id):t.jsxs("div",{className:`${s.box} ${C===e.id?s.selected:""}`,style:{left:`${e.x*100}%`,top:`${e.y*100}%`,width:`${e.width*100}%`,height:`${e.height*100}%`,borderColor:n},children:[t.jsx("span",{className:`${s.annotationNumberBadge} ${s.boxNumberBadge}`,style:{backgroundColor:n},"aria-hidden":"true",children:r}),t.jsx("button",{type:"button",...i,className:s.boxSurface,"aria-label":`Box marker ${r}`})]},e.id)}),t.jsx("svg",{className:s.overlaySvg,viewBox:Gt,preserveAspectRatio:"none",children:N.filter(e=>e.kind==="box"&&C===e.id).map(e=>t.jsxs(qt.Fragment,{children:[t.jsx("circle",{cx:(e.x+e.width)*b.width,cy:(e.y+e.height)*b.height,r:He.hitRadius,className:`${s.canvasHandleHit} ${s.canvasResizeHandleHit}`,role:"button",tabIndex:0,"aria-label":"Resize box marker",onPointerDown:n=>bs(n,e)}),t.jsx("circle",{cx:(e.x+e.width)*b.width,cy:(e.y+e.height)*b.height,r:He.visibleRadius,className:s.canvasHandleVisible,"aria-hidden":"true"})]},`box-handle-${e.id}`))})]}):null]})})]}):t.jsx("div",{className:s.emptyState,children:t.jsx("p",{className:"tf-empty-copy",children:"Select an image attachment to annotate."})})})})]}),t.jsxs("div",{className:s.statusBar,children:[t.jsx("span",{children:U==="error"?"Save failed. Retry now.":U==="saving"||U==="pending"?"Saving…":"Saved"}),rn?t.jsx("span",{children:rn}):t.jsx("span",{children:B?G&&ke?"Drag on the image to pan.":$==="select"?"Select a marker to edit it.":`Click on the image to place a ${$}.`:"Create a session to begin placing markers on this image."}),d&&!B&&Kn?t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn} ${s.toolbarButton}`,onClick:()=>{wn()},disabled:W||ut,children:W?"Creating…":"Create one now"}):null]})]}),t.jsx("section",{className:`tf-surface-panel ${s.panel} ${s.detailPanel}`,children:B?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:s.panelHeader,children:[t.jsxs("div",{className:s.panelHeaderText,children:[t.jsx("div",{className:`tf-heading-card ${s.panelTitle}`,children:"Markers"}),t.jsxs("div",{className:"tf-text-secondary",children:[N.length," in this session"]})]}),t.jsxs("div",{className:s.sessionActions,children:[t.jsx("button",{type:"button",className:`tf-control-icon ${s.iconButton}`,onClick:()=>Sn("up"),disabled:!z||zt<=0,"aria-label":"Move marker up",children:t.jsx(Ps,{size:16})}),t.jsx("button",{type:"button",className:`tf-control-icon ${s.iconButton}`,onClick:()=>Sn("down"),disabled:!z||zt===-1||zt>=N.length-1,"aria-label":"Move marker down",children:t.jsx(Bs,{size:16})})]})]}),t.jsx("div",{className:`tf-scrollbar ${s.annotationList}`,children:N.length===0?t.jsx("div",{className:s.detailEmpty,children:t.jsx("p",{className:"tf-empty-copy",children:"Add a marker on the image to begin."})}):N.map((e,n)=>{const r=Oo[e.kind],i=Do[e.kind],c=`${i} ${n+1}`,p=zo[e.markerType||re],j=En.find(f=>f.value===(e.markerType||re))?.label||"Review",u=C===e.id;return t.jsxs("div",{className:`tf-surface-elevated ${s.annotationCard} ${u?s.annotationCardActive:""}`,children:[t.jsx("button",{type:"button",className:s.annotationCardButton,onClick:()=>L(e.id),"aria-label":i,children:t.jsxs("div",{className:s.annotationMeta,children:[t.jsx("span",{className:`tf-heading-card ${s.annotationTitle}`,children:c}),t.jsx("span",{className:`tf-text-meta ${s.annotationKind}`,"aria-hidden":"true",children:t.jsx(r,{size:16})})]})}),u?t.jsxs("div",{className:s.annotationInstructionEditor,children:[t.jsx("label",{className:"tf-field-label",htmlFor:"annotated-marker-instruction",children:"Marker instruction"}),t.jsx("textarea",{id:"annotated-marker-instruction",ref:u?pn:null,className:`tf-field-shell ${s.textArea} ${s.annotationInstructionField}`,value:e.instruction,onChange:f=>{ee(e.id,v=>({...v,instruction:f.target.value}),600)},onBlur:()=>{H("text")},placeholder:"What should the AI focus on for this marker?"}),t.jsxs("div",{className:s.annotationTypeField,children:[t.jsx("label",{className:"tf-field-label",htmlFor:"annotated-marker-type",children:"Instruction type"}),t.jsx("select",{id:"annotated-marker-type",className:`tf-field-shell ${s.select}`,value:e.markerType||re,onChange:f=>{ee(e.id,v=>Wo(v,f.target.value))},children:En.map(f=>t.jsx("option",{value:f.value,children:f.label},f.value))})]})]}):t.jsx("button",{type:"button",className:s.annotationInstructionButton,onClick:()=>L(e.id),"aria-label":`Edit ${i} instruction`,children:t.jsxs("div",{className:s.annotationInstructionEditor,children:[t.jsx("div",{className:`tf-text-secondary ${s.annotationInstructionPreview}`,children:e.instruction.trim()||"No marker instruction yet."}),t.jsx("div",{className:s.annotationPreviewFooter,children:t.jsx("span",{className:`tf-text-meta ${s.annotationInstructionTypeIcon}`,"aria-label":`Instruction type: ${j}`,title:j,children:t.jsx(p,{size:16})})})]})})]},e.id)})})]}):t.jsxs("div",{className:s.emptyState,children:[t.jsx("strong",{className:"tf-empty-title",children:"No active session"}),t.jsx("p",{className:"tf-empty-copy",children:"Create or select a session to edit annotations."})]})}),t.jsx(Jt,{isOpen:Vn,onClose:()=>{qe||(ht(!1),bt(""))},title:"Open Image",size:"sm",children:t.jsxs("form",{className:s.openImageModalBody,onSubmit:e=>{e.preventDefault(),Zn()},children:[t.jsx("label",{className:"tf-field-label",htmlFor:"annotated-open-image-reference",children:"Image reference number"}),t.jsx("input",{id:"annotated-open-image-reference",className:`tf-field-shell ${s.textInput} ${s.openImageField}`,value:Mt,onChange:e=>bt(e.target.value),placeholder:"I-24",autoFocus:!0}),t.jsxs("div",{className:s.openImageActions,children:[t.jsx("button",{type:"button",className:"tf-button-ghost tf-button-compact",onClick:()=>{ht(!1),bt("")},disabled:qe,children:"Cancel"}),t.jsx("button",{type:"submit",className:"tf-button-primary tf-button-compact",disabled:qe,children:qe?"Opening…":"Open"})]})]})}),t.jsx(Jt,{isOpen:Xn,onClose:()=>dn(!1),title:"How To Use Markers",size:"md",children:t.jsx("div",{className:s.markerHelpModalBody,children:Mn.filter(e=>e.value!=="select").map(e=>t.jsxs("div",{className:`tf-surface-inset ${s.markerHelpItem}`,children:[t.jsxs("div",{className:s.markerHelpHeader,children:[t.jsx("strong",{className:"tf-heading-card",children:e.label}),t.jsx("span",{className:"tf-text-meta",children:It[e.value].short})]}),t.jsx("p",{className:"tf-text-secondary",children:It[e.value].detail}),t.jsx("p",{className:`tf-text-body ${s.markerHelpExample}`,children:It[e.value].example})]},e.value))})}),t.jsx(Jt,{isOpen:Wn,onClose:()=>Bt(!1),title:"AI Payload",size:"lg",children:t.jsxs("div",{className:s.payloadModalBody,children:[t.jsxs("div",{className:s.payloadModalToolbar,children:[t.jsxs("div",{className:s.payloadViewToggle,children:[t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.toolBtn} ${Tt==="json"?s.toolBtnActive:""}`,onClick:()=>cn("json"),children:"JSON"}),t.jsx("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.toolBtn} ${Tt==="brief"?s.toolBtnActive:""}`,onClick:()=>cn("brief"),children:"AI Brief"})]}),t.jsxs("div",{className:s.payloadModalActions,children:[t.jsxs("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn}`,onClick:()=>{In("json")},disabled:!oe,"aria-label":le==="json"?"Copied JSON":"Copy JSON",title:le==="json"?"Copied JSON":"Copy JSON",children:[le==="json"?t.jsx(sn,{size:16}):t.jsx(Zt,{size:16}),t.jsx("span",{children:"JSON"})]}),t.jsxs("button",{type:"button",className:`tf-button-ghost tf-button-compact ${s.ghostBtn}`,onClick:()=>{In("brief")},disabled:!oe,"aria-label":le==="brief"?"Copied AI Brief":"Copy AI Brief",title:le==="brief"?"Copied AI Brief":"Copy AI Brief",children:[le==="brief"?t.jsx(sn,{size:16}):t.jsx(Zt,{size:16}),t.jsx("span",{children:"AI Brief"})]})]})]}),ft?t.jsx("div",{className:s.detailEmpty,children:t.jsx("p",{className:"tf-empty-copy",children:"Loading payload…"})}):oe?t.jsx("pre",{className:`tf-surface-inset tf-scrollbar ${s.payloadModalPreview}`,children:Tt==="json"?JSON.stringify(oe,null,2):Fn(oe)}):t.jsx("div",{className:s.detailEmpty,children:t.jsx("p",{className:"tf-empty-copy",children:"Load a payload preview to inspect the current session contract."})})]})})]})}export{dr as AnnotatedAttachmentWorkspaceShell};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._index_18mna_1{display:flex;flex-direction:column;height:100%;min-height:0}._header_18mna_8{display:flex;align-items:center;justify-content:space-between;padding:14px 12px 10px;border-bottom:1px solid var(--border-subtle);flex-shrink:0}._title_18mna_17{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:var(--text-primary)}._refreshBtn_18mna_26{background:transparent;border:none;color:var(--text-muted);cursor:pointer;padding:4px;border-radius:4px;display:flex;align-items:center;transition:color .15s,background .15s}._refreshBtn_18mna_26:hover{color:var(--text-primary);background:var(--bg-hover)}._refreshBtn_18mna_26:disabled{opacity:.5;cursor:not-allowed}._search_18mna_48{position:relative;padding:8px 10px;flex-shrink:0}._searchIcon_18mna_54{position:absolute;left:18px;top:50%;transform:translateY(-50%);color:var(--text-muted);pointer-events:none}._searchInput_18mna_63{width:100%;padding:6px 8px 6px 28px;background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:6px;color:var(--text-primary);font-size:12px;font-family:inherit;outline:none;box-sizing:border-box}._searchInput_18mna_63:focus{border-color:var(--brand-primary)}._list_18mna_80{flex:1;overflow-y:auto;min-height:0;padding:4px 0;scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}._state_18mna_89{padding:24px 16px;font-size:12px;color:var(--text-muted);text-align:center;line-height:1.5}._stateError_18mna_97{padding:16px;font-size:12px;color:var(--status-error);text-align:center}._item_18mna_104{width:100%;display:flex;align-items:flex-start;gap:8px;padding:8px 12px;background:transparent;border:none;cursor:pointer;text-align:left;transition:background .12s;font-family:inherit;color:var(--text-primary);min-width:0}._item_18mna_104:hover{background:var(--bg-hover, rgba(255, 255, 255, .04))}._itemActive_18mna_124{background:var(--brand-primary-soft)}._itemActive_18mna_124:hover{background:color-mix(in srgb,var(--brand-primary) 18%,transparent)}._itemIcon_18mna_132{color:var(--text-muted);padding-top:1px;flex-shrink:0}._itemActive_18mna_124 ._itemIcon_18mna_132{color:var(--brand-primary-strong)}._itemBody_18mna_142{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}._itemTitle_18mna_150{display:block;max-width:100%;font-size:12px;font-weight:500;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-transform:capitalize}._itemTask_18mna_162{display:block;max-width:100%;font-size:11px;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._itemBadge_18mna_172{display:inline-flex;align-items:center;width:fit-content;padding:2px 6px;border-radius:999px;border:1px solid color-mix(in srgb,var(--status-warning) 28%,transparent);background:color-mix(in srgb,var(--status-warning) 12%,transparent);color:color-mix(in srgb,var(--status-warning) 70%,white);font-size:10px;font-weight:600}._itemMeta_18mna_185{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;font-size:10px;color:var(--text-muted)}._itemMetaDetails_18mna_195{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._itemMetaReference_18mna_202{flex-shrink:0;font-size:10px;font-weight:600;color:var(--text-secondary)}._viewer_9t0y6_1{flex:1;display:flex;flex-direction:column;overflow:hidden;min-height:0;height:100%}._viewerMonochrome_9t0y6_10 ._metaDocumentName_9t0y6_10{color:#111!important}._viewerEditMode_9t0y6_14{background:var(--bg-primary)}._meta_9t0y6_10{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 20px;border-bottom:1px solid var(--border-subtle);background:var(--bg-secondary);flex-shrink:0;flex-wrap:wrap}._metaLeft_9t0y6_30{display:flex;align-items:center;gap:12px;flex-wrap:wrap}._metaDocumentName_9t0y6_10{font-size:14px;font-weight:700;color:var(--text-primary);max-width:min(26ch,100%);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.015em;cursor:text}._metaRenameRow_9t0y6_49{display:inline-flex;align-items:center;gap:8px;min-width:min(420px,100%)}._typeBadge_9t0y6_56{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;background:var(--brand-primary-soft);color:var(--brand-primary-strong);border:1px solid color-mix(in srgb,var(--brand-primary) 25%,transparent);text-transform:uppercase;letter-spacing:.3px}._typeBadgeImplementationPlan_9t0y6_71{background:color-mix(in srgb,var(--status-info) 15%,transparent);color:color-mix(in srgb,var(--status-info) 55%,white);border-color:color-mix(in srgb,var(--status-info) 25%,transparent)}._typeBadgeReview_9t0y6_77{background:color-mix(in srgb,var(--status-warning) 15%,transparent);color:color-mix(in srgb,var(--status-warning) 68%,white);border-color:color-mix(in srgb,var(--status-warning) 25%,transparent)}._typeBadgeWalkthrough_9t0y6_83{background:color-mix(in srgb,var(--status-success) 15%,transparent);color:color-mix(in srgb,var(--status-success) 60%,white);border-color:color-mix(in srgb,var(--status-success) 25%,transparent)}._metaTaskName_9t0y6_89{font-size:11px;color:var(--text-secondary);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._statusBadge_9t0y6_98{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;border:1px solid color-mix(in srgb,var(--status-warning) 28%,transparent);background:color-mix(in srgb,var(--status-warning) 12%,transparent);color:color-mix(in srgb,var(--status-warning) 68%,white);font-size:10px;font-weight:600;letter-spacing:.2px;text-transform:uppercase}._metaDate_9t0y6_113,._metaSize_9t0y6_114{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--text-muted)}._actions_9t0y6_122{display:flex;align-items:center;gap:6px;flex-shrink:0}._actionBtn_9t0y6_129{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:6px;border:1px solid var(--border-subtle);background:transparent;color:var(--text-secondary);font-size:11px;font-family:inherit;cursor:pointer;transition:all .15s;white-space:nowrap}._actionBtn_9t0y6_129:hover{background:var(--bg-hover);color:var(--text-primary);border-color:var(--border-primary)}._actionBtn_9t0y6_129:disabled{opacity:.6;cursor:not-allowed}._dangerBtn_9t0y6_156{border-color:color-mix(in srgb,var(--status-error) 35%,transparent)!important;color:color-mix(in srgb,var(--status-error) 45%,white)!important}._dangerBtn_9t0y6_156:hover:not(:disabled){background:color-mix(in srgb,var(--status-error) 12%,transparent)!important;border-color:color-mix(in srgb,var(--status-error) 50%,transparent)!important;color:color-mix(in srgb,var(--status-error) 30%,white)!important}._generateBtn_9t0y6_167{background:var(--brand-primary-soft)!important;border-color:var(--brand-primary-border)!important;color:var(--brand-primary-strong)!important}._generateBtn_9t0y6_167:hover{background:color-mix(in srgb,var(--brand-primary) 24%,transparent)!important;color:color-mix(in srgb,var(--brand-primary-strong) 72%,white)!important}._editBtn_9t0y6_178{color:var(--text-primary)!important;border-color:var(--border-primary)!important}._editBtn_9t0y6_178:hover{background:color-mix(in srgb,var(--brand-primary) 10%,transparent)!important;border-color:var(--brand-primary-border)!important;color:var(--brand-primary-strong)!important}._saveBtn_9t0y6_189{background:color-mix(in srgb,var(--brand-primary) 15%,transparent)!important;border-color:var(--brand-primary-border)!important;color:var(--brand-primary-strong)!important}._saveBtn_9t0y6_189:hover:not(:disabled){background:color-mix(in srgb,var(--brand-primary) 25%,transparent)!important;color:color-mix(in srgb,var(--brand-primary-strong) 72%,white)!important}._saveBtn_9t0y6_189:disabled{opacity:.4!important;cursor:not-allowed!important}._layoutToggle_9t0y6_205{display:flex;background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:6px;overflow:hidden}._layoutBtn_9t0y6_213{padding:5px 8px;background:transparent;border:none;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;transition:all .12s}._layoutBtn_9t0y6_213:hover{color:var(--text-primary);background:var(--bg-hover)}._layoutBtnActive_9t0y6_229{color:var(--brand-primary-strong);background:var(--brand-primary-soft)}._saveStatus_9t0y6_234{display:inline-flex;align-items:center;gap:4px;font-size:11px}._saveStatusSaved_9t0y6_241{color:var(--status-success)}._saveStatusError_9t0y6_245{color:var(--status-error);cursor:help}._unsaved_9t0y6_250{font-size:11px;color:color-mix(in srgb,var(--status-warning) 70%,white);font-style:italic}._viewerContent_9t0y6_256{flex:1;overflow-y:auto;padding:16px 24px 40px;min-height:0;scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}._viewerBody_9t0y6_265{flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) 360px;align-items:stretch}._viewerBodyFullWidth_9t0y6_273{grid-template-columns:minmax(0,1fr)}._viewerMain_9t0y6_277{border-right:1px solid var(--border-subtle)}._viewerBodyFullWidth_9t0y6_273 ._viewerMain_9t0y6_277{border-right:none}._reviewRail_9t0y6_285{min-height:0;overflow:hidden;background:color-mix(in srgb,var(--bg-secondary) 78%,transparent)}._printHint_9t0y6_291{padding:0 24px 18px;color:var(--text-muted);font-size:11px;line-height:1.45}._reviewSection_9t0y6_298{height:100%;min-height:0;padding:18px 18px 18px 16px;display:flex;flex-direction:column;gap:12px}._reviewHeader_9t0y6_307{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;flex-wrap:wrap}._reviewTitle_9t0y6_315{display:inline-flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:var(--text-primary)}._reviewSubtitle_9t0y6_324{margin:4px 0 0;color:var(--text-muted);font-size:11px;line-height:1.45}._reviewControls_9t0y6_331{display:flex;align-items:center;gap:8px;flex-wrap:wrap}._reviewSelect_9t0y6_338{min-width:180px}._reviewSessionMeta_9t0y6_342{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:11px}._reviewStatusResolved_9t0y6_350{border-color:color-mix(in srgb,var(--status-success) 30%,transparent);background:color-mix(in srgb,var(--status-success) 12%,transparent);color:color-mix(in srgb,var(--status-success) 66%,white)}._reviewSessionLabel_9t0y6_356{color:var(--text-secondary);font-weight:600}._reviewTitleEditRow_9t0y6_361{display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}._reviewSessionTimestamp_9t0y6_368{color:var(--text-muted)}._reviewAnchorLabel_9t0y6_372{color:var(--text-muted);font-size:11px;padding:0 4px}._reviewComposer_9t0y6_378{flex:1;display:flex;flex-direction:column;gap:8px}._reviewAnchorChip_9t0y6_385{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 10px;border:1px solid var(--border-subtle);border-radius:10px;background:var(--bg-secondary);color:var(--text-secondary);font-size:11px}._reviewAnchorSnippet_9t0y6_398{color:var(--text-primary);font-style:italic}._reviewAnchorClear_9t0y6_403{border:none;background:transparent;color:var(--brand-primary-strong);font:inherit;cursor:pointer;padding:0}._reviewAnchorClear_9t0y6_403:hover{text-decoration:underline}._reviewCommentActions_9t0y6_416{display:inline-flex;align-items:center;gap:6px;margin-left:auto}._reviewCommentAction_9t0y6_416{border:none;background:transparent;color:var(--text-muted);font:inherit;cursor:pointer;padding:0}._reviewCommentAction_9t0y6_416:hover{color:var(--text-primary);text-decoration:underline}._reviewCommentEditor_9t0y6_437{display:flex;flex-direction:column;gap:8px}._viewerState_9t0y6_443{padding:40px;text-align:center;color:var(--text-muted);font-size:13px}._viewerStateError_9t0y6_450{padding:40px;text-align:center;color:var(--status-error);font-size:13px}._editorArea_9t0y6_457{flex:1;display:flex;min-height:0;overflow:hidden}._editorPane_9t0y6_464{flex:1;display:flex;flex-direction:column;min-width:0;border-right:1px solid var(--border-subtle)}._editorLayoutSplit_9t0y6_472 ._editorPane_9t0y6_464,._editorLayoutSplit_9t0y6_472 ._previewPane_9t0y6_473,._editorLayoutEditor_9t0y6_477 ._editorPane_9t0y6_464,._editorLayoutPreview_9t0y6_478 ._previewPane_9t0y6_473{flex:1}._editorPaneLabel_9t0y6_482{padding:6px 12px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;border-bottom:1px solid var(--border-subtle);background:var(--bg-secondary);flex-shrink:0}._editorTextarea_9t0y6_494{flex:1;width:100%;resize:none;background:var(--bg-primary);color:var(--text-primary);border:none;outline:none;padding:16px;font-family:Fira Code,Cascadia Code,JetBrains Mono,monospace;font-size:13px;line-height:1.65;tab-size:2;caret-color:var(--brand-primary-strong);scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);min-height:0;box-sizing:border-box}._editorTextarea_9t0y6_494::selection{background:color-mix(in srgb,var(--brand-primary) 30%,transparent)}._previewPane_9t0y6_473{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}._previewPane_9t0y6_473 .docMarkdown{flex:1;overflow-y:auto;padding:16px 24px 40px;min-height:0;max-width:none;scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track)}._markdownSurface_9t0y6_536{color:var(--text-body);font-size:14px;line-height:1.7;max-width:800px}._markdownSurface_9t0y6_536 h1,._markdownSurface_9t0y6_536 h2,._markdownSurface_9t0y6_536 h3,._markdownSurface_9t0y6_536 h4{color:var(--text-primary);font-weight:700;margin:1.5em 0 .5em;line-height:1.3}._markdownSurface_9t0y6_536 h1{font-size:1.6em}._markdownSurface_9t0y6_536 h2{font-size:1.25em;border-bottom:1px solid var(--border-subtle);padding-bottom:.3em}._markdownSurface_9t0y6_536 h3{font-size:1.1em}._markdownSurface_9t0y6_536 p{margin:.8em 0}._markdownSurface_9t0y6_536 a{color:var(--brand-primary-strong);text-decoration:underline;text-underline-offset:2px}._markdownSurface_9t0y6_536 a:hover{color:color-mix(in srgb,var(--brand-primary-strong) 72%,white)}._markdownSurface_9t0y6_536 code{font-family:Fira Code,Cascadia Code,monospace;font-size:.875em;background:var(--brand-primary-soft);padding:2px 5px;border-radius:4px;color:var(--code-inline-text, var(--brand-primary-strong))}._markdownSurface_9t0y6_536 pre{background:var(--bg-primary);border:1px solid var(--border-subtle);border-radius:8px;padding:16px;overflow-x:auto;margin:1em 0}._markdownSurface_9t0y6_536 pre code{background:none;padding:0;font-size:13px;color:var(--code-block-text, var(--text-body))}._markdownSurface_9t0y6_536 blockquote{border-left:3px solid color-mix(in srgb,var(--brand-primary) 50%,transparent);padding-left:16px;margin:1em 0;color:var(--text-secondary);font-style:italic}._markdownSurface_9t0y6_536 table{border-collapse:collapse;width:100%;margin:1em 0;font-size:13px}._markdownSurface_9t0y6_536 th,._markdownSurface_9t0y6_536 td{border:1px solid var(--border-subtle);padding:8px 12px;text-align:left}._markdownSurface_9t0y6_536 th{background:var(--bg-secondary);font-weight:600;color:var(--text-secondary);font-size:11px;text-transform:uppercase;letter-spacing:.4px}._markdownSurface_9t0y6_536 ul,._markdownSurface_9t0y6_536 ol{padding-left:1.5em;margin:.5em 0}._markdownSurface_9t0y6_536 li{margin:.3em 0}._markdownSurface_9t0y6_536 li._task-list-item_9t0y6_647,._markdownSurface_9t0y6_536 li[data-task-item=true]{list-style:none}._markdownSurface_9t0y6_536 li:has(input[type=checkbox]){list-style:none!important;list-style-type:none!important}._markdownSurface_9t0y6_536 ul._contains-task-list_9t0y6_657,._markdownSurface_9t0y6_536 ol._contains-task-list_9t0y6_657{padding-left:.25em}._markdownSurface_9t0y6_536 ul:has(li input[type=checkbox]),._markdownSurface_9t0y6_536 ol:has(li input[type=checkbox]){padding-left:1.25em!important}._markdownSurface_9t0y6_536 li._task-list-item_9t0y6_647>input[type=checkbox],._markdownSurface_9t0y6_536 li[data-task-item=true]>input[type=checkbox]{margin-right:.45em;cursor:pointer;accent-color:var(--brand-primary-strong)}._markdownSurface_9t0y6_536 hr{border:none;border-top:1px solid var(--border-subtle);margin:1.5em 0}._markdownSurface_9t0y6_536 img{max-width:100%;border-radius:8px}._viewerMonochrome_9t0y6_10 ._viewerContent_9t0y6_256,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536{background:#fff!important}@media(max-width:1100px){._viewerBody_9t0y6_265{grid-template-columns:minmax(0,1fr)}._viewerMain_9t0y6_277{border-right:none;border-bottom:1px solid var(--border-subtle)}._reviewRail_9t0y6_285{max-height:480px}._reviewSection_9t0y6_298{padding:16px 24px 18px}}._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 h1,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 h2,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 h3,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 h4,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 p,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 li,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 blockquote,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 th,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 td,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 a{color:#111!important}._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 code{color:#111!important;background:#f2f2f2!important}._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 pre{background:#f7f7f7!important;border-color:#d7d7d7!important}._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 pre code,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 code,._viewerMonochrome_9t0y6_10 ._markdownSurface_9t0y6_536 a,._viewerMonochrome_9t0y6_10 ._metaTaskName_9t0y6_89,._viewerMonochrome_9t0y6_10 ._metaDate_9t0y6_113,._viewerMonochrome_9t0y6_10 ._metaSize_9t0y6_114{color:#111!important}._overlay_1unik_1{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#0000008c;z-index:2000;padding:1rem}._modal_1unik_12{width:min(720px,100%)}._header_1unik_16{align-items:flex-start}._title_1unik_20{font-size:1rem}._docName_1unik_24{font-size:.75rem;color:var(--text-secondary);max-width:14rem;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._body_1unik_34{padding:.75rem 1rem 1rem;display:flex;flex-direction:column;gap:.75rem}._state_1unik_41{min-height:10rem;display:flex;align-items:center;justify-content:center;gap:.5rem;font-size:.875rem;color:var(--text-secondary);text-align:center}._stateError_1unik_52{min-height:10rem;display:flex;align-items:center;justify-content:center;gap:.5rem;font-size:.875rem;color:var(--status-error);text-align:center}._stateDone_1unik_63{min-height:10rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;text-align:center}._stateDone_1unik_63 strong{color:var(--text-primary);font-size:1rem}._stateDone_1unik_63 p{margin:0;font-size:.8125rem;color:var(--text-secondary)}._toolbar_1unik_84{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.625rem .75rem;border:1px solid var(--border-default);border-radius:var(--radius-md);background:var(--surface-inset)}._toolbarCount_1unik_95{font-size:.75rem;color:var(--text-secondary)}._toolbarActions_1unik_100{display:flex;gap:.5rem}._tree_1unik_105{display:flex;flex-direction:column;gap:.125rem;max-height:22rem;overflow-y:auto}._taskRow_1unik_113{display:flex;align-items:center;gap:.375rem;padding:.4375rem .75rem;min-height:2.125rem;transition:background .1s}._taskRow_1unik_113:hover{background:#ffffff08}._taskRowDimmed_1unik_126{opacity:.4}._taskCheck_1unik_130{background:transparent;border:none;cursor:pointer;display:flex;padding:0;flex-shrink:0}._taskExpandBtn_1unik_139{background:transparent;border:none;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;padding:0;flex-shrink:0;transition:color .1s}._taskExpandBtn_1unik_139:hover{color:var(--text-primary)}._taskExpandSpacer_1unik_155{width:12px;flex-shrink:0}._taskTitle_1unik_160{flex:1;font-size:.8125rem;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._taskBadge_1unik_169{font-size:.625rem;padding:.125rem .375rem;border-radius:var(--radius-sm);border:1px solid currentColor;opacity:.85;white-space:nowrap;flex-shrink:0}._footer_1unik_179{display:flex;align-items:center;justify-content:flex-end;gap:.625rem;padding:0 1rem 1rem}
|