@agent-plan/pi-adapter 0.2.19-next.15 → 0.2.19-next.16

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAmvBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAwmG9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAmvBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAqnG9D"}
package/dist/index.js CHANGED
@@ -3018,10 +3018,15 @@ export default function planPiExtension(pi) {
3018
3018
  const st = await requirePlan(ctx);
3019
3019
  if (!st)
3020
3020
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3021
+ const features = (await st.loadFeatures()).features;
3022
+ const resolvedFeature = features.find((feat) => formatFeatureRef(feat.number).toLowerCase() === params.featureId.trim().toLowerCase() || feat.shortId === params.featureId.trim() || feat.id === params.featureId.trim() || feat.name.toLowerCase() === params.featureId.trim().toLowerCase());
3023
+ if (!resolvedFeature)
3024
+ return { content: [{ type: "text", text: `Feature not found: ${params.featureId}` }], details: {} };
3025
+ const featureId = resolvedFeature.id;
3021
3026
  let foundDoc;
3022
3027
  try {
3023
3028
  foundDoc = await st.updateFeatures((doc) => {
3024
- const feature = doc.features.find((f) => f.id === params.featureId);
3029
+ const feature = doc.features.find((f) => f.id === featureId);
3025
3030
  if (!feature)
3026
3031
  return doc; // not found: no-op, handled below
3027
3032
  if (params.name !== undefined)
@@ -3059,7 +3064,7 @@ export default function planPiExtension(pi) {
3059
3064
  catch (e) {
3060
3065
  return { content: [{ type: "text", text: `Update failed: ${e}` }], details: {} };
3061
3066
  }
3062
- const feature = foundDoc?.features.find((f) => f.id === params.featureId);
3067
+ const feature = foundDoc?.features.find((f) => f.id === featureId);
3063
3068
  if (!feature)
3064
3069
  return { content: [{ type: "text", text: `Feature not found: ${params.featureId}` }], details: {} };
3065
3070
  await st.writeGenerated();
@@ -3078,21 +3083,23 @@ export default function planPiExtension(pi) {
3078
3083
  const st = await requirePlan(ctx);
3079
3084
  if (!st)
3080
3085
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3086
+ const features = (await st.loadFeatures()).features;
3087
+ const resolvedFeature = features.find((feat) => formatFeatureRef(feat.number).toLowerCase() === params.featureId.trim().toLowerCase() || feat.shortId === params.featureId.trim() || feat.id === params.featureId.trim() || feat.name.toLowerCase() === params.featureId.trim().toLowerCase());
3088
+ if (!resolvedFeature)
3089
+ return { content: [{ type: "text", text: `Feature not found: ${params.featureId}` }], details: {} };
3090
+ const featureId = resolvedFeature.id;
3081
3091
  let deleted = false;
3082
3092
  await st.updateFeatures((doc) => {
3083
3093
  const before = doc.features.length;
3084
- doc.features = doc.features.filter((f) => f.id !== params.featureId);
3094
+ doc.features = doc.features.filter((f) => f.id !== featureId);
3085
3095
  if (doc.features.length !== before)
3086
3096
  deleted = true;
3087
3097
  return doc;
3088
3098
  });
3089
- if (!deleted) {
3090
- return { content: [{ type: "text", text: `Feature not found: ${params.featureId}` }], details: {} };
3091
- }
3092
3099
  let cascadeCount = 0;
3093
3100
  if (params.cascade) {
3094
3101
  const phases = await st.loadAllPhases();
3095
- for (const phase of phases.filter((p) => p.featureId === params.featureId)) {
3102
+ for (const phase of phases.filter((p) => p.featureId === featureId)) {
3096
3103
  await st.deletePhase(phase.id);
3097
3104
  cascadeCount += 1;
3098
3105
  }
@@ -3245,9 +3252,14 @@ export default function planPiExtension(pi) {
3245
3252
  const st = await requirePlan(ctx);
3246
3253
  if (!st)
3247
3254
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3255
+ const features = (await st.loadFeatures()).features;
3256
+ const resolvedPhase = findPhaseByRef(await st.loadAllPhases(), features, params.phaseId.trim());
3257
+ if (!resolvedPhase)
3258
+ return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
3259
+ const phaseId = resolvedPhase.id;
3248
3260
  let phase;
3249
3261
  try {
3250
- phase = await st.loadPhase(params.phaseId);
3262
+ phase = await st.loadPhase(phaseId);
3251
3263
  }
3252
3264
  catch {
3253
3265
  return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
@@ -3314,19 +3326,24 @@ export default function planPiExtension(pi) {
3314
3326
  const st = await requirePlan(ctx);
3315
3327
  if (!st)
3316
3328
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3329
+ const features = (await st.loadFeatures()).features;
3330
+ const resolvedPhase = findPhaseByRef(await st.loadAllPhases(), features, params.phaseId.trim());
3331
+ if (!resolvedPhase)
3332
+ return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
3333
+ const phaseId = resolvedPhase.id;
3317
3334
  let phase;
3318
3335
  try {
3319
- phase = await st.loadPhase(params.phaseId);
3336
+ phase = await st.loadPhase(phaseId);
3320
3337
  }
3321
3338
  catch {
3322
3339
  return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
3323
3340
  }
3324
- await st.deletePhase(params.phaseId);
3341
+ await st.deletePhase(phaseId);
3325
3342
  if (phase.featureId) {
3326
3343
  await st.updateFeatures((doc) => {
3327
3344
  const feature = doc.features.find((f) => f.id === phase.featureId);
3328
3345
  if (feature) {
3329
- feature.phaseIds = feature.phaseIds.filter((pid) => pid !== params.phaseId);
3346
+ feature.phaseIds = feature.phaseIds.filter((pid) => pid !== phaseId);
3330
3347
  feature.updatedAt = nowISO();
3331
3348
  }
3332
3349
  return doc;
@@ -3416,22 +3433,21 @@ export default function planPiExtension(pi) {
3416
3433
  const st = await requirePlan(ctx);
3417
3434
  if (!st)
3418
3435
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3419
- // Verify phase exists first (fast-fail before generating an id).
3420
- try {
3421
- await st.loadPhase(params.phaseId);
3422
- }
3423
- catch {
3436
+ // Resolve the phase ref (accepts F00x/P00x, bare P00x, shortId, UUID, title).
3437
+ const features = (await st.loadFeatures()).features;
3438
+ const resolvedPhase = findPhaseByRef(await st.loadAllPhases(), features, params.phaseId.trim());
3439
+ if (!resolvedPhase)
3424
3440
  return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
3425
- }
3441
+ const phaseId = resolvedPhase.id;
3426
3442
  const shortName = clampSlug(params.shortName ?? params.title, 30, `task-${Date.now().toString(36)}`); // clamp+strip trailing dash; never empty
3427
3443
  const taskId = createTaskId();
3428
3444
  const shortId = createShortId(await st.assignedShortIds());
3429
- const priority = await st.nextPriority("task", params.phaseId);
3445
+ const priority = await st.nextPriority("task", phaseId);
3430
3446
  const now = nowISO();
3431
3447
  const initialStatus = params.status ?? "planned";
3432
- const existingPhase = await st.loadPhase(params.phaseId);
3448
+ const existingPhase = await st.loadPhase(phaseId);
3433
3449
  const task = {
3434
- id: taskId, phaseId: params.phaseId, number: await st.allocTaskNumber(), shortId, priority, shortName,
3450
+ id: taskId, phaseId, number: await st.allocTaskNumber(), shortId, priority, shortName,
3435
3451
  title: params.title,
3436
3452
  status: initialStatus,
3437
3453
  description: params.description ?? "",
@@ -3450,7 +3466,7 @@ export default function planPiExtension(pi) {
3450
3466
  };
3451
3467
  // Atomic read-modify-write on the phase file: serializes concurrent
3452
3468
  // task_create calls on the SAME phaseId (batch) so tasks don't get lost.
3453
- await st.updatePhase(params.phaseId, (phase) => {
3469
+ await st.updatePhase(phaseId, (phase) => {
3454
3470
  phase.tasks.push(task);
3455
3471
  phase.taskIds.push(taskId);
3456
3472
  phase.updatedAt = now;
@@ -3488,15 +3504,16 @@ export default function planPiExtension(pi) {
3488
3504
  if (!st)
3489
3505
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3490
3506
  // Find the phase hosting this task first.
3491
- const allPhases = await st.loadAllPhases();
3492
- const hostPhase = allPhases.find((p) => p.tasks.some((t) => t.id === params.taskId));
3493
- if (!hostPhase)
3507
+ const features = (await st.loadFeatures()).features;
3508
+ const found = findTaskByRef(await st.loadAllPhases(), features, params.taskId.trim());
3509
+ if (!found)
3494
3510
  return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
3511
+ const hostPhase = found.phase;
3495
3512
  const now = nowISO();
3496
3513
  let updatedTask;
3497
3514
  try {
3498
3515
  const updatedPhase = await st.updatePhase(hostPhase.id, (phase) => {
3499
- const task = phase.tasks.find((t) => t.id === params.taskId);
3516
+ const task = phase.tasks.find((t) => t.id === found.task.id);
3500
3517
  if (!task)
3501
3518
  return phase;
3502
3519
  if (params.title !== undefined)
@@ -3559,13 +3576,13 @@ export default function planPiExtension(pi) {
3559
3576
  const st = await requirePlan(ctx);
3560
3577
  if (!st)
3561
3578
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3562
- const phases = await st.loadAllPhases();
3563
- const hostPhase = phases.find((p) => p.tasks.some((t) => t.id === params.taskId));
3564
- if (!hostPhase)
3579
+ const features = (await st.loadFeatures()).features;
3580
+ const found = findTaskByRef(await st.loadAllPhases(), features, params.taskId.trim());
3581
+ if (!found)
3565
3582
  return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
3566
- await st.updatePhase(hostPhase.id, (phase) => {
3567
- phase.tasks = phase.tasks.filter((t) => t.id !== params.taskId);
3568
- phase.taskIds = phase.taskIds.filter((id) => id !== params.taskId);
3583
+ await st.updatePhase(found.phase.id, (phase) => {
3584
+ phase.tasks = phase.tasks.filter((t) => t.id !== found.task.id);
3585
+ phase.taskIds = phase.taskIds.filter((id) => id !== found.task.id);
3569
3586
  phase.updatedAt = nowISO();
3570
3587
  return phase;
3571
3588
  });
@@ -3585,19 +3602,19 @@ export default function planPiExtension(pi) {
3585
3602
  const st = await requirePlan(ctx);
3586
3603
  if (!st)
3587
3604
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3588
- const phases = await st.loadAllPhases();
3589
- const hostPhase = phases.find((p) => p.tasks.some((t) => t.id === params.taskId));
3590
- const task = hostPhase?.tasks.find((t) => t.id === params.taskId);
3591
- if (!task || !hostPhase)
3605
+ const features = (await st.loadFeatures()).features;
3606
+ const found = findTaskByRef(await st.loadAllPhases(), features, params.taskId.trim());
3607
+ if (!found)
3592
3608
  return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
3609
+ const task = found.task;
3593
3610
  if (task.status === "in-progress")
3594
3611
  return { content: [{ type: "text", text: `Task ${task.id} is already in-progress.` }], details: task };
3595
3612
  if (task.status === "done")
3596
3613
  return { content: [{ type: "text", text: `Task ${task.id} is done. Use task_update to reopen.` }], details: task };
3597
3614
  const now = nowISO();
3598
3615
  let startedTask;
3599
- await st.updatePhase(hostPhase.id, (phase) => {
3600
- const t = phase.tasks.find((x) => x.id === params.taskId);
3616
+ await st.updatePhase(found.phase.id, (phase) => {
3617
+ const t = phase.tasks.find((x) => x.id === found.task.id);
3601
3618
  if (!t)
3602
3619
  return phase;
3603
3620
  applyTaskLifecycleDates(t, "in-progress", now);
@@ -3625,11 +3642,11 @@ export default function planPiExtension(pi) {
3625
3642
  const st = await requirePlan(ctx);
3626
3643
  if (!st)
3627
3644
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3628
- const phases = await st.loadAllPhases();
3629
- const hostPhase = phases.find((p) => p.tasks.some((t) => t.id === params.taskId));
3630
- const task = hostPhase?.tasks.find((t) => t.id === params.taskId);
3631
- if (!task || !hostPhase)
3645
+ const features = (await st.loadFeatures()).features;
3646
+ const found = findTaskByRef(await st.loadAllPhases(), features, params.taskId.trim());
3647
+ if (!found)
3632
3648
  return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
3649
+ const task = found.task;
3633
3650
  if (task.status === "done")
3634
3651
  return { content: [{ type: "text", text: `Task ${task.id} is already done.` }], details: task };
3635
3652
  const unchecked = task.checklist.filter((item) => !item.checked);
@@ -3641,8 +3658,8 @@ export default function planPiExtension(pi) {
3641
3658
  }
3642
3659
  const now = nowISO();
3643
3660
  let completedTask;
3644
- await st.updatePhase(hostPhase.id, (phase) => {
3645
- const t = phase.tasks.find((x) => x.id === params.taskId);
3661
+ await st.updatePhase(found.phase.id, (phase) => {
3662
+ const t = phase.tasks.find((x) => x.id === found.task.id);
3646
3663
  if (!t)
3647
3664
  return phase;
3648
3665
  applyTaskLifecycleDates(t, "done", now);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-plan/pi-adapter",
3
- "version": "0.2.19-next.15",
3
+ "version": "0.2.19-next.16",
4
4
  "private": false,
5
5
  "description": "Pi agent extension for Agent Plan — structured project planning in .planner/",
6
6
  "keywords": [
@@ -28,8 +28,8 @@
28
28
  "dependencies": {
29
29
  "typebox": "^1.1.24",
30
30
  "zod": "^3.24.0",
31
- "@agent-plan/core": "0.2.19-next.15",
32
- "@agent-plan/server": "0.2.19-next.15"
31
+ "@agent-plan/core": "0.2.19-next.16",
32
+ "@agent-plan/server": "0.2.19-next.16"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "^0.74.0",
@@ -255,7 +255,7 @@ ${cT(vc(t.expression,a+1,l,i,u),a+1,i)}
255
255
  ${o})`;return t.boost!=null&&(f+=`^${t.boost}`),f}case"FieldGroup":{let f=`${t.field}:(${Sr(t.expression,u)})`;return t.boost!=null&&(f+=`^${t.boost}`),f}case"Not":{const{op:f,sep:m}=Jb(t,u);return`${f}${m}${vc(t.expression,a,l,i,u)}`}default:return Sr(t,u)}}function cT(t,a,l){const i=l.repeat(a);return t.split(`
256
256
  `).map(u=>u.startsWith(i)?u:i+u).join(`
257
257
  `)}function dT(t){return t?xu(t):[]}function px(t){return t.type==="BooleanExpr"}function xu(t){switch(t.type){case"BooleanExpr":return zh(t);case"Group":{const a=[],l=t.expression;return px(l)?(a.push({start:t.start,end:t.end}),a.push(...xu(l)),a.push({start:t.start,end:t.end})):a.push({start:t.start,end:t.end}),a}case"FieldGroup":{const a=[];a.push({start:t.start,end:t.end});const l=t.expression;return px(l)&&a.push(...xu(l)),a}case"Not":{const a=[];return a.push({start:t.start,end:t.end}),a.push(...xu(t.expression)),a}case"FieldValue":case"BareTerm":case"SavedSearch":case"HistoryRef":case"Regex":case"Range":case"Error":return[{start:t.start,end:t.end}]}}function zh(t){return t.type==="BooleanExpr"?[...zh(t.left),...zh(t.right)]:xu(t)}function fT(t,a,l,i){if(t.length===0)return null;if(a>=0&&a<t.length){const u=i==="forward"?a+1:a-1;return u>=0&&u<t.length?{stop:t[u],index:u}:null}if(i==="forward"){for(let u=0;u<t.length;u++)if(t[u].start>=l)return{stop:t[u],index:u};return{stop:t[t.length-1],index:t.length-1}}else{for(let u=t.length-1;u>=0;u--)if(t[u].end<=l)return{stop:t[u],index:u};return{stop:t[0],index:0}}}var hT=class{constructor(t=100){pn(this,"stack",[]);pn(this,"index",-1);pn(this,"maxSize");this.maxSize=t}push(t){if(this.index>=0&&this.stack[this.index].value===t.value){this.stack[this.index].cursorPos=t.cursorPos;return}this.stack=this.stack.slice(0,this.index+1),this.stack.push(t),this.stack.length>this.maxSize&&this.stack.shift(),this.index=this.stack.length-1}replaceCurrent(t){this.index>=0?this.stack[this.index]=t:this.push(t)}undo(){return this.index<=0?null:(this.index--,this.stack[this.index])}redo(){return this.index>=this.stack.length-1?null:(this.index++,this.stack[this.index])}canUndo(){return this.index>0}canRedo(){return this.index<this.stack.length-1}current(){return this.index>=0?this.stack[this.index]:null}clear(){this.stack=[],this.index=-1}get length(){return this.stack.length}};function mT(t,a){const l=i=>(a==null?void 0:a(i))??Sj(i);if(t.type==="RANGE"&&t.token){const i=t.token.value,u=(i.endsWith("]")||i.endsWith("}")?i.slice(1,-1):i.slice(1)).match(/^(.*?)\s+[Tt][Oo]\s+(.*)$/);if(u)return{mode:"range",start:l(u[1].trim()),end:l(u[2].trim())}}if(t.type==="FIELD_VALUE"&&t.partial){const i=l(t.partial);if(i)return{mode:"single",start:i,end:null}}return null}function pT(t,a){var l,i,u,o;return((t==null?void 0:t.mode)??"single")!==((a==null?void 0:a.mode)??"single")||(((l=t==null?void 0:t.start)==null?void 0:l.getTime())??0)!==(((i=a==null?void 0:a.start)==null?void 0:i.getTime())??0)?!0:(((u=t==null?void 0:t.end)==null?void 0:u.getTime())??0)!==(((o=a==null?void 0:a.end)==null?void 0:o.getTime())??0)}function gT({position:t,colors:a,onSelect:l,colorConfig:i,styleConfig:u,datePickerInit:o,fixedWidth:f,datePresets:m,datePickerClassName:p}){const g=v.useRef(null),[x,b]=v.useState(!1);if(v.useEffect(()=>{const N=document.createElement("div");return document.body.appendChild(N),g.current=N,b(!0),()=>{document.body.removeChild(N),g.current=null}},[]),!x||!g.current)return null;const w=$u(u),S={position:"absolute",zIndex:w.dropdownZIndex,...Qb(a,w),top:`${t.top}px`,left:`${t.left}px`,maxHeight:"none",overflowY:"visible",...f!=null?{width:`${f}px`,minWidth:"unset",maxWidth:"unset"}:{}};return Jr.createPortal(v.createElement("div",{className:"ei-datepicker-portal",style:S,onMouseDown:N=>N.preventDefault()},v.createElement(Vj,{onSelect:l,colors:i,styles:u,initialMode:o==null?void 0:o.mode,initialStart:o==null?void 0:o.start,initialEnd:o==null?void 0:o.end,presets:m,className:p})),g.current)}function vT(t){const{fields:a,onSearch:l,onChange:i,onValidationChange:u,value:o,defaultValue:f,savedSearches:m,searchHistory:p,fetchSuggestions:g,colors:x,styles:b,placeholder:w,className:S,classNames:N,style:A,dropdown:j,features:L,inputRef:I,datePresets:Y,onKeyDown:P,onFocus:K,onBlur:W,onTab:U,validateValue:T,parseDate:oe,plainModeLength:me,interceptPaste:ye,defaultField:Re,trailingSpaceOnAccept:ee=!0,collapseOnBlur:be=!1}=t,Ee=typeof Re=="string"?{name:Re,showFieldSuggestions:!1}:Re?{showFieldSuggestions:!1,...Re}:void 0,z=Ee==null?void 0:Ee.name,H=(j==null?void 0:j.open)??(j==null?void 0:j.mode)??"always",ie=typeof H=="function",ce=ie?null:H,pe=(j==null?void 0:j.alignToInput)??!1,D=j==null?void 0:j.maxSuggestions,$=D||10,ne=j==null?void 0:j.suggestDebounceMs,de=parseInt((b==null?void 0:b.dropdownMaxHeight)||"300",10)||300,je=(L==null?void 0:L.savedSearches)??!!m,Ne=(L==null?void 0:L.historySearch)??!!p,Ue=(j==null?void 0:j.showSavedSearchHint)??je,it=(j==null?void 0:j.showHistoryHint)??Ne,Ge=(j==null?void 0:j.showOperators)!==!1,nt=(ie||ce!=="input")&&(j==null?void 0:j.onNavigation)!==!1,vn=(j==null?void 0:j.navigationDelay)??0,Rt=(j==null?void 0:j.loadingDelay)??0,ut=j==null?void 0:j.renderFieldHint,le=j==null?void 0:j.renderHistoryItem,Ye=j==null?void 0:j.renderSavedSearchItem,Ie=j==null?void 0:j.renderHeader,Gt=j==null?void 0:j.renderNoResults,An=j==null?void 0:j.renderType,fn=(j==null?void 0:j.autoSelect)??!1,Lt=(j==null?void 0:j.homeEndKeys)??!1,Wt=(L==null?void 0:L.multiline)!==!1,Yn=(L==null?void 0:L.smartSelectAll)??!1,Vn=(L==null?void 0:L.expandSelection)??!1,fe=(L==null?void 0:L.wildcardWrap)??!1,Le=(L==null?void 0:L.clauseNavigation)??!1,Me=L==null?void 0:L.formatQuery,qe=!!Me,Ze=typeof Me=="object"?Me:void 0,pt=v.useMemo(()=>({savedSearches:je,historySearch:Ne}),[je,Ne]),Xt=Array.isArray(a)?a:[],[rn,Bn]=v.useState(Xt);v.useEffect(()=>{if(Array.isArray(a)){Bn(a);return}let R=!1;return a().then(G=>{R||Bn(G)}),()=>{R=!0}},[a]);const un=v.useMemo(()=>{const R=new Map;for(const G of rn)if(R.set(G.name.toLowerCase(),G.type),G.aliases)for(const Se of G.aliases)R.set(Se.toLowerCase(),G.type);return R},[rn]),se=v.useRef(null),[St,Mt]=v.useState(null),Jn=v.useCallback(R=>{se.current=R,Mt(R)},[]),Wn=v.useRef(null),jr=v.useRef(null),Be=v.useRef(o||f||""),Pt=v.useRef(null),Yt=v.useRef(!1),yt=v.useRef(!1),zt=v.useRef(new hT),jt=v.useRef(null),en=v.useRef(new Set),Qt=v.useRef(null),Ut=v.useRef(null),ft=v.useRef(null),Je=v.useRef(null),wn=v.useRef(!1),On=v.useRef(null),C=v.useRef(null),k=v.useRef(null),q=v.useRef("input"),Z=v.useRef(null),ae=v.useRef(-1),Te=v.useRef(()=>{}),ge=v.useRef(new vh(Xt,[],[],D||10,{showSavedSearchHint:Ue,showHistoryHint:it,hasSavedSearchProvider:typeof m=="function",hasHistoryProvider:typeof p=="function"}));ge.current.setDefaultField(Ee);const De=v.useRef(new sx(Xt)),we=v.useRef(T);we.current=T;const[Oe,_e]=v.useState([]),[Xe,Ce]=v.useState(null),[Ke,$e]=v.useState([]),[Ht,We]=v.useState(-1),[ot,lt]=v.useState(!1),[ct,Kt]=v.useState(!1),[Fn,En]=v.useState(null),[Mn,kn]=v.useState([]),[In,fa]=v.useState(!1),[tl,ea]=v.useState(!Be.current),[ur,Pe]=v.useState(me!=null&&Be.current.length>=me),[wt,Zt]=v.useState(0),[ta,_n]=v.useState(0),[Tr,Et]=v.useState(""),[wa,Gn]=v.useState(null),[Ul,hi]=v.useState(null),Tt=v.useRef({tokens:Oe,ast:Xe,suggestions:Ke,selectedSuggestionIndex:Ht,showDropdown:ot,showDatePicker:ct,cursorOffset:wt,selectionEnd:ta,autocompleteContext:Tr,validationErrors:Mn,cursorContext:wa});Tt.current={tokens:Oe,ast:Xe,suggestions:Ke,selectedSuggestionIndex:Ht,showDropdown:ot,showDatePicker:ct,cursorOffset:wt,selectionEnd:ta,autocompleteContext:Tr,validationErrors:Mn,cursorContext:wa};const or=v.useCallback((R,G)=>{if(pe&&Wn.current){const ve=Wn.current.getBoundingClientRect();return{top:ve.bottom+window.scrollY+4,left:ve.left+window.scrollX}}const Se=wh();return Se?Eh(Se,R,G):null},[pe]),Yu=v.useCallback(()=>{if(!(!pe||!Wn.current))return Wn.current.getBoundingClientRect().width},[pe]),Ja=v.useCallback((R,G,Se="dropdown")=>{const ve=Se==="datePicker"?R:mx(R,de);if(pe&&Se!=="datePicker"){lt(!0),En(or(ve,G));return}const Fe=requestAnimationFrame(()=>{en.current.delete(Fe),Se==="datePicker"?Kt(!0):lt(!0);const ue=wh();En(ue?Eh(ue,ve,G):null)});en.current.add(Fe)},[pe,or,de]),nl=80,Qc=60,ds=v.useCallback((R,G)=>{if(!se.current)return;const Se=Gs(R,x,{cursorOffset:G,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=Se,document.activeElement===se.current&&Zr(se.current,G)},[x]),ha=v.useCallback((R,G)=>{const Se=me!=null&&R.length>=me;if(Pe(Se),Se){if(_e([]),Ce(null),kn([]),ea(R.length===0),$e([]),Tt.current.tokens=[],lt(!1),Kt(!1),se.current){const xe=jl(se.current);se.current.querySelector("span")&&(se.current.textContent=R,Zr(se.current,xe)),Zt(xe),_n(xe)}i&&i(R,null),u&&u([]);return}const ve=new Js(R,pt).tokenize(),Fe=new ss(ve),ue=Fe.parse(),he=uc([...Fe.getErrors().map(xe=>({message:xe.message,start:xe.start,end:xe.end,type:"SYNTAX_ERROR"})),...De.current.validate(ue,we.current,oe,z)]);if(se.current){const xe=jl(se.current);G&&ve.length>nl?(Ut.current&&clearTimeout(Ut.current),Ut.current=setTimeout(()=>{Ut.current=null,se.current&&ds(ve,jl(se.current))},Qc)):(Ut.current&&(clearTimeout(Ut.current),Ut.current=null),ds(ve,xe)),_e(ve),Ce(ue),kn(he),ea(R.length===0),Zt(xe),_n(xe),Tt.current.tokens=ve,G&&Te.current(ve,xe)}else _e(ve),Ce(ue),kn(he),ea(R.length===0),Tt.current.tokens=ve;i&&i(R,ue),u&&u(he)},[x,i,u,ds,me]),Hl=v.useCallback((R,G)=>{if(!ut||G.type!=="FIELD_VALUE"||!G.fieldName)return R;const Se=ge.current.resolveField(G.fieldName);if(!Se)return R;const ve=ut(Se,G.partial);return ve==null?R:R.some(Fe=>Fe.type==="hint")?R.map(Fe=>Fe.type==="hint"?{...Fe,customContent:ve}:Fe):[{text:"",label:"",type:"hint",customContent:ve,replaceStart:G.start??0,replaceEnd:G.end??0},...R]},[ut]),fs=v.useCallback(R=>{if(!Gt)return!1;const G=Gt({cursorContext:R,partial:R.partial});return G==null?!1:($e([{text:"",label:"",type:"noResults",customContent:G,replaceStart:0,replaceEnd:0}]),We(-1),Kt(!1),Ja(32,300),!0)},[Gt]),ma=v.useCallback((R,G,Se)=>{var xe,Qe,at;const ve=ge.current.getSuggestions(R,G);Ge||(ve.suggestions=ve.suggestions.filter(ze=>ze.type!=="operator"));const Fe=ve.context.type;if(Gn(ve.context),ie){if(H({trigger:q.current,context:ve.context,suggestions:ve.suggestions,isOpen:Tt.current.showDropdown||Tt.current.showDatePicker,value:Be.current,selectionStart:G,selectionEnd:Se??G})===!1){lt(!1),Kt(!1),$e([]);return}}else{if(ce==="never"){lt(!1),Kt(!1),$e([]);return}if(ce==="manual"){if(k.current&&k.current!==Fe){k.current=null,lt(!1),Kt(!1),$e([]);return}if(!k.current){lt(!1),Kt(!1),$e([]);return}}if(ce==="input"&&q.current!=="input"&&q.current!=="ctrlSpace"){lt(!1),Kt(!1),$e([]);return}if(ce==="always"&&R.some(ze=>(ze.type===M.AND||ze.type===M.OR||ze.type===M.NOT||ze.type===M.TILDE||ze.type===M.BOOST)&&G>=ze.start&&G<=ze.end)){lt(!1),Kt(!1),$e([]);return}}const ue=ve.context.fieldName?ge.current.resolveField(ve.context.fieldName):void 0,he=!!(g&&ve.context.type==="FIELD_VALUE"&&ve.context.fieldName&&(ue==null?void 0:ue.type)!=="boolean"&&(ue==null?void 0:ue.suggestions)!==!1)||typeof m=="function"&&ve.context.type==="SAVED_SEARCH"||typeof p=="function"&&ve.context.type==="HISTORY_REF";if(ve.showDatePicker){wn.current=!1,(xe=Qt.current)==null||xe.abort(),Pt.current&&clearTimeout(Pt.current),Je.current&&(clearTimeout(Je.current),Je.current=null);const ze=mT(ve.context,oe),Nn=On.current;On.current=ze,hi(ze);const kt=ve.context.token;kt&&(kt.type==="COLON"||kt.type==="COMPARISON_OP")?C.current={start:kt.end,end:kt.end}:kt?C.current={start:kt.start,end:kt.end}:C.current={start:G,end:G},Tt.current.showDatePicker&&pT(Nn,ze)&&Kt(!1),$e([]),pe||lt(!1),Et(Fe),Ja(350,300,"datePicker");return}if(he){const ze=ve.context.token,Nn=ze?ze.start:G,kt=ze?ze.end:G,ra=()=>{Je.current=null,$e([{text:"",label:"Searching...",type:"loading",replaceStart:Nn,replaceEnd:kt}]),pe||lt(!1),Kt(!1),We(-1),Ja(32,300)};Je.current&&clearTimeout(Je.current),Rt>0?Je.current=setTimeout(ra,Rt):ra(),Et(Fe)}else{wn.current=!1,(Qe=Qt.current)==null||Qe.abort(),Pt.current&&clearTimeout(Pt.current),Je.current&&(clearTimeout(Je.current),Je.current=null);const ze=Hl(ve.suggestions,ve.context);ze.length>0?($e(ze),pe||lt(!1),Kt(!1),We(ve.context.partial||fn?0:-1),Et(Fe),Ja(ze.length*32,300)):(Et(Fe),fs(ve.context)||(lt(!1),Kt(!1),$e([])))}if(he){const ze=ve.context.partial,Nn=ne||200;wn.current=!0,Pt.current&&clearTimeout(Pt.current),(at=Qt.current)==null||at.abort();const kt=new AbortController;Qt.current=kt,Pt.current=setTimeout(async()=>{const ra=ve.context.token,la=ra?ra.start:G,pa=ra?ra.end:G;try{let Rn;if(ve.context.type==="SAVED_SEARCH"&&typeof m=="function"){const on=await m(ze);if(kt.signal.aborted)return;Rn=on.map(_t=>({text:_t.query,label:_t.label||_t.query,description:_t.description,type:"savedSearch",replaceStart:la,replaceEnd:pa,matchPartial:ze,sourceData:_t}))}else if(ve.context.type==="HISTORY_REF"&&typeof p=="function"){const on=await p(ze);if(kt.signal.aborted)return;Rn=on.map(_t=>({text:vh.wrapHistoryQuery(_t.query),label:_t.label||_t.query,description:_t.description,type:"history",replaceStart:la,replaceEnd:pa,matchPartial:ze,sourceData:_t}))}else{const on=ve.context.fieldName,_t=ge.current.resolveField(on),Yl=await g(_t?_t.name:on,ze);if(kt.signal.aborted)return;Rn=Yl.map(fr=>({text:fr.text,label:fr.label||fr.text,description:fr.description,type:fr.type,replaceStart:la,replaceEnd:pa,matchPartial:ze}))}if(Je.current&&(clearTimeout(Je.current),Je.current=null),Rn=Rn.slice(0,$),Rn.length>0){if(Ee!=null&&Ee.showFieldSuggestions){const on=ge.current.getFieldSuggestions(ze,la,pa);Rn=[...Rn,...on].slice(0,$)}$e(Rn),We(ze||fn?0:-1),Ja(Rn.length*32,300)}else{const on=ge.current.getSuggestions(Tt.current.tokens,Tt.current.cursorOffset);if(!(ze&&fs(on.context))){const _t=Hl(on.suggestions.filter(Yl=>Yl.type==="hint"),on.context);_t.length>0?($e(_t),We(on.context.partial||fn?0:-1),Ja(_t.length*32,300)):fs(on.context)||(lt(!1),$e([]))}}}catch(Rn){Je.current&&(clearTimeout(Je.current),Je.current=null),kt.signal.aborted||($e([{text:"",label:Rn instanceof Error?Rn.message:"Error loading suggestions",type:"error",replaceStart:la,replaceEnd:pa}]),We(-1),Ja(32,300),wn.current=!1)}},Nn)}},[g,m,p,ne,Hl,or,Ja,pe,H,ie,ce,Ge,$,Rt,fn,fs]);Te.current=ma;const tn=v.useCallback(()=>{var R;lt(!1),Kt(!1),hi(null),On.current=null,C.current=null,$e([]),We(-1),wn.current=!1,(R=Qt.current)==null||R.abort(),Pt.current&&(clearTimeout(Pt.current),Pt.current=null),ft.current&&(clearTimeout(ft.current),ft.current=null),k.current=null},[]),na=v.useCallback((R,G,Se)=>{if(ft.current&&(clearTimeout(ft.current),ft.current=null),!nt){(Tt.current.showDropdown||Tt.current.showDatePicker)&&tn();return}q.current="navigation",vn>0?ft.current=setTimeout(()=>{ft.current=null,ma(R,G,Se)},vn):ma(R,G,Se)},[nt,vn,ma,tn]),Ea=v.useCallback((R,G,Se)=>{Be.current=R,jt.current&&(clearTimeout(jt.current),jt.current=null),zt.current.push({value:R,cursorPos:G});const ve=new Js(R,pt).tokenize(),Fe=new ss(ve),ue=Fe.parse(),he=uc([...Fe.getErrors().map(xe=>({message:xe.message,start:xe.start,end:xe.end,type:"SYNTAX_ERROR"})),...De.current.validate(ue,we.current,oe,z)]);if(se.current){const xe=Gs(ve,x,{cursorOffset:G,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=xe,Zr(se.current,G)}if(_e(ve),Ce(ue),kn(he),ea(R.length===0),Zt(G),_n(G),lt(!1),Kt(!1),i&&i(R,ue),u&&u(he),Se){const xe=requestAnimationFrame(()=>{en.current.delete(xe),Se(ve,ue)});en.current.add(xe)}},[x,i,u]),Dr=v.useCallback((R,G="Enter",Se,ve)=>{if(!R)return;const Fe=Tt.current,ue=Fe.autocompleteContext,he=ue==="FIELD_VALUE"||ue==="SAVED_SEARCH"||ue==="HISTORY_REF";if(he&&(q.current="navigation"),R.type==="hint"&&(R.text==="#"||R.text==="!")){const on=R.text,_t=R.replaceStart,Yl=Math.max(R.replaceEnd,Fe.selectionEnd),fr=Be.current.slice(0,_t),Zc=Be.current.slice(Yl),Gu=fr+on+Zc,Xu=fr.length+on.length;Ea(Gu,Xu,(Jc,Wc)=>{Se?Se(Gu,Wc):ma(Jc,Xu)});return}if(R.type==="hint")return;const xe=Fe.autocompleteContext==="FIELD_VALUE",Qe=Math.min(R.replaceStart,Fe.cursorOffset),at=Math.max(R.replaceEnd,Fe.selectionEnd),ze=Be.current.slice(0,Qe),Nn=Be.current.slice(at);let kt="",ra=Nn;he&&ee&&(Nn.length===0?kt=" ":/^[ \t\r\n]+$/.test(Nn)&&!Nn.startsWith("\\ ")&&(kt=" ",ra=""));const la=ze+R.text+kt+ra,pa=ze.length+R.text.length+kt.length,Rn=G==="Enter"&&xe;Ea(la,pa,(on,_t)=>{Se?Se(la,_t):Rn?l&&l(la,_t,ve):ma(on,pa)})},[Ea,ma,l,ee]);v.useEffect(()=>{Array.isArray(m)&&ge.current.updateSavedSearches(m),Array.isArray(p)&&ge.current.updateSearchHistory(p)},[m,p]),v.useEffect(()=>{ge.current=new vh(rn,[],[],D||10,{showSavedSearchHint:Ue,showHistoryHint:it,hasSavedSearchProvider:typeof m=="function",hasHistoryProvider:typeof p=="function"}),ge.current.setDefaultField(Ee),De.current=new sx(rn),Array.isArray(m)&&ge.current.updateSavedSearches(m),Array.isArray(p)&&ge.current.updateSearchHistory(p),Be.current&&ha(Be.current,!1)},[rn,D,Ue,it]),v.useEffect(()=>{I&&I({getValue:()=>Be.current,setValue:R=>{Be.current=R,ha(R,!1)},focus:()=>{var R;return(R=se.current)==null?void 0:R.focus()},blur:()=>{var R;return(R=se.current)==null?void 0:R.blur()},getAST:()=>Tt.current.ast,getValidationErrors:()=>Tt.current.validationErrors,setSelection:(R,G)=>{se.current&&(se.current.focus(),Kr(se.current,R,G),Zt(R),_n(G))}})},[I,ha]),v.useEffect(()=>{const R=Be.current;zt.current.push({value:R,cursorPos:R.length}),R&&ha(R,!1)},[]),v.useEffect(()=>{o!==void 0&&o!==Be.current&&(Be.current=o,ha(o,!1))},[o,ha]),v.useEffect(()=>()=>{var R;Pt.current&&clearTimeout(Pt.current),Ut.current&&clearTimeout(Ut.current),ft.current&&clearTimeout(ft.current),Je.current&&clearTimeout(Je.current),en.current.forEach(G=>cancelAnimationFrame(G)),en.current.clear(),(R=Qt.current)==null||R.abort()},[]),v.useEffect(()=>{if(ie){const R=Tt.current;R.cursorContext&&H({trigger:"modeChange",context:R.cursorContext,suggestions:R.suggestions,isOpen:R.showDropdown||R.showDatePicker,value:Be.current,selectionStart:R.cursorOffset,selectionEnd:R.selectionEnd})===!1&&(lt(!1),Kt(!1),$e([]))}else ce==="never"&&(lt(!1),Kt(!1),$e([]));k.current=null},[H]);const cr=v.useRef(!1);v.useLayoutEffect(()=>{if(cr.current){cr.current=!1;return}const R=jr.current;if(!R||!Fn)return;const G=R.getBoundingClientRect(),Se=window.innerWidth;if(G.right>Se-8){const ve=G.right-Se+8;cr.current=!0,En(Fe=>Fe&&{...Fe,left:Math.max(8,Fe.left-ve)})}},[Fn,ot,ct,Ke]),v.useEffect(()=>{const R=()=>{const G=Tt.current;if(!(!G.showDropdown&&!G.showDatePicker))if(G.showDropdown&&pe&&Wn.current){const Se=Wn.current.getBoundingClientRect();En({top:Se.bottom+window.scrollY+4,left:Se.left+window.scrollX})}else{const Se=wh();Se&&En(Eh(Se,G.showDatePicker?350:mx(G.suggestions.length*32,de),300))}};return window.addEventListener("resize",R),window.addEventListener("scroll",R,!0),()=>{window.removeEventListener("resize",R),window.removeEventListener("scroll",R,!0)}},[pe,de]),v.useEffect(()=>{const R=se.current;if(!R)return;const G=()=>{(Tt.current.showDropdown||Tt.current.showDatePicker)&&tn()};return R.addEventListener("scroll",G),()=>R.removeEventListener("scroll",G)},[tn]);const Cr=v.useRef(null),mi=v.useRef(x);v.useEffect(()=>{if(!se.current)return;const R=Tt.current.tokens;if(R.length===0||In&&ta!==wt)return;const G=In?wt:-1,Se=x!==mi.current;mi.current=x;const ve=Kb(R,G),Fe=ve?`${ve.openStart},${ve.closeStart}`:null;if(Fe===Cr.current&&!Se)return;Cr.current=Fe;const ue=In?jl(se.current):-1,he=Gs(R,x,{cursorOffset:G,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=he,In&&ue>=0&&Zr(se.current,ue)},[wt,ta,In,x]);const dr=be&&!In,pi=v.useRef(dr);v.useEffect(()=>{if(!se.current)return;const R=pi.current;if(pi.current=dr,R!==dr)if(dr)se.current.innerHTML=se.current.innerHTML.replace(/<br\s*\/?>/gi," ");else{const G=Tt.current.tokens;if(G.length>0){const Se=In?jl(se.current):-1,ve=Gs(G,x,{cursorOffset:Se,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=ve,In&&Se>=0&&Zr(se.current,Se)}}},[dr,x]);const La=v.useCallback(()=>{if(Yt.current||!se.current)return;Z.current=null,ae.current=-1,ft.current&&(clearTimeout(ft.current),ft.current=null);let R=vj(se.current);if(R===Be.current)return;let G=jl(se.current);const Se=tx(R);Se!==R&&(R=Se,G=Math.min(G,R.length)),Be.current=R;const ve=zt.current,Fe=ve.current();if(Fe&&Math.abs(R.length-Fe.value.length)<=2&&jt.current?ve.replaceCurrent({value:R,cursorPos:G}):ve.push({value:R,cursorPos:G}),jt.current&&clearTimeout(jt.current),jt.current=setTimeout(()=>{jt.current=null},300),q.current="input",!ie&&ce==="input"){const ue=G>0?R[G-1]:"";if(!ue||ue.trim()===""){ha(R,!1),tn(),se.current&&oc(se.current);return}}ha(R,!0),se.current&&oc(se.current)},[ha,ie,ce,tn]),Wa=v.useCallback(()=>{Yt.current=!0},[]),gi=v.useCallback(()=>{Yt.current=!1,La()},[La]),Ar=v.useCallback(R=>{if(!R)return;Be.current=R.value;const G=new Js(R.value,pt).tokenize(),Se=new ss(G),ve=Se.parse(),Fe=uc([...Se.getErrors().map(he=>({message:he.message,start:he.start,end:he.end,type:"SYNTAX_ERROR"})),...De.current.validate(ve,we.current,oe,z)]),ue=R.selStart!=null&&R.selStart!==R.cursorPos;if(se.current){const he=Gs(G,x,{cursorOffset:R.cursorPos,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=he,ue?Kr(se.current,R.selStart,R.cursorPos):Zr(se.current,R.cursorPos)}_e(G),Ce(ve),kn(Fe),ea(R.value.length===0),Zt(ue?R.selStart:R.cursorPos),_n(R.cursorPos),tn(),i&&i(R.value,ve),u&&u(Fe)},[x,i,u,tn]),za=v.useCallback(()=>{const R=jr.current;if(!R)return 10;const G=R.clientHeight,Se=R.querySelectorAll(".ei-dropdown-item")[0];if(!Se)return 10;const ve=Se.offsetHeight;return ve<=0?10:Math.max(1,Math.floor(G/ve))},[]),vi=v.useCallback(R=>{var ve,Fe;if(P&&P(R),R.defaultPrevented)return;const G=Tt.current,Se=R.nativeEvent.code;if(qe&&Se==="KeyF"&&R.altKey&&R.shiftKey&&!R.ctrlKey&&!R.metaKey){R.preventDefault();const ue=lT(Be.current,Ze);ue!==Be.current&&Ea(ue,ue.length);return}if(se.current&&se.current.childNodes.length>40){const ue=window.getSelection();if(ue!=null&&!ue.isCollapsed){const he=xr(se.current);if(he.end-he.start>20){const xe=R.key==="Backspace"||R.key==="Delete"||R.key==="x"&&(R.ctrlKey||R.metaKey),Qe=!R.ctrlKey&&!R.metaKey&&!R.altKey&&R.key.length===1;(xe||Qe)&&(se.current.textContent=Be.current,Kr(se.current,he.start,he.end))}}}{let ue=null,he=null;if(nx[R.key])ue=R.key,he=nx[R.key];else if(fe&&R.key==="*"&&se.current){const xe=xr(se.current);if(xe.start!==xe.end){const[Qe,at]=ax(G.tokens,xe.start,xe.end);if(Qe>=0&&Qe===at){const ze=G.tokens[Qe];(ze.type===M.VALUE||ze.type===M.WILDCARD)&&(ue="*",he="*")}}}if(ue&&he&&se.current){const xe=xr(se.current);if(xe.start!==xe.end){R.preventDefault();const{newValue:Qe,newSelStart:at,newSelEnd:ze}=gj(Be.current,xe.start,xe.end,ue,he),Nn=zt.current,kt=Nn.current();kt&&kt.value===Be.current&&(kt.selStart=xe.start,kt.cursorPos=xe.end),Be.current=Qe,jt.current&&(clearTimeout(jt.current),jt.current=null),Nn.push({value:Qe,cursorPos:ze,selStart:at});const ra=new Js(Qe,pt).tokenize(),la=new ss(ra),pa=la.parse(),Rn=uc([...la.getErrors().map(_t=>({message:_t.message,start:_t.start,end:_t.end,type:"SYNTAX_ERROR"})),...De.current.validate(pa,we.current,oe,z)]),on=Gs(ra,x,{cursorOffset:ze,tokenClassName:N==null?void 0:N.token,fieldTypeMap:un});se.current.innerHTML=on,Kr(se.current,at,ze),_e(ra),Ce(pa),kn(Rn),ea(!1),Zt(at),_n(ze),tn(),i&&i(Qe,pa),u&&u(Rn);return}}}if(R.key==="z"&&(R.ctrlKey||R.metaKey)&&!R.shiftKey){R.preventDefault(),Ar(zt.current.undo());return}if(R.key==="y"&&(R.ctrlKey||R.metaKey)||R.key==="z"&&(R.ctrlKey||R.metaKey)&&R.shiftKey){R.preventDefault(),Ar(zt.current.redo());return}if(R.key==="a"&&(R.ctrlKey||R.metaKey)&&Yn&&se.current){const ue=xr(se.current),he=Wj(G.tokens,ue.start,ue.end);if(he){R.preventDefault(),Kr(se.current,he.start,he.end),Zt(he.start),_n(he.end);return}}if(Vn&&R.altKey&&R.shiftKey&&(Se==="ArrowRight"||Se==="ArrowLeft")&&se.current){const ue=Se==="ArrowRight";let he=Z.current;if(!he){const Qe=xr(se.current),at=tT(G.ast,G.tokens,Qe.start);if(at.length===0)return;he={ranges:at,level:-1},Z.current=he}const xe=ue?Math.min(he.level+1,he.ranges.length-1):Math.max(he.level-1,-1);if(xe===he.level)return;if(he.level=xe,xe<0){const Qe=xr(se.current);Zr(se.current,Qe.start),Z.current=null}else{R.preventDefault();const Qe=he.ranges[xe];Kr(se.current,Qe.start,Qe.end),Zt(Qe.start),_n(Qe.end)}return}if(Z.current=null,Le&&R.ctrlKey&&R.altKey&&(Se==="ArrowRight"||Se==="ArrowLeft")&&se.current){R.preventDefault();const ue=Se==="ArrowRight"?"forward":"backward",he=dT(G.ast),xe=xr(se.current),Qe=ue==="forward"?xe.end:xe.start,at=fT(he,ae.current,Qe,ue);at&&(ae.current=at.index,Kr(se.current,at.stop.start,at.stop.end),Zt(at.stop.start),_n(at.stop.end));return}if(ae.current=-1,R.key===" "&&(R.ctrlKey||R.metaKey)){R.preventDefault(),q.current="ctrlSpace",!ie&&ce==="manual"&&(k.current=ge.current.getSuggestions(G.tokens,G.cursorOffset).context.type),ma(G.tokens,G.cursorOffset);return}if(R.key==="Enter"&&(R.ctrlKey||R.metaKey)){R.preventDefault(),tn(),l&&l(Be.current,G.ast,R);return}if(R.key==="Enter"&&R.shiftKey&&Wt){R.preventDefault(),Zj();const ue=se.current?jl(se.current):Be.current.length+1,he=Be.current,xe=he.slice(0,ue-1)+`
258
- `+he.slice(ue-1);Be.current=xe,Z.current=null,ft.current&&(clearTimeout(ft.current),ft.current=null),q.current="input",zt.current.push({value:xe,cursorPos:ue}),ha(xe,!0),se.current&&oc(se.current);return}if((R.key==="Backspace"||R.key==="Delete")&&se.current&&!se.current.textContent){const ue=Be.current;if(!ue)return;const{start:he,end:xe}=xr(se.current);let Qe,at;if(he!==xe)Qe=ue.slice(0,he)+ue.slice(xe),at=he;else if(R.key==="Backspace"&&he>0)Qe=ue.slice(0,he-1)+ue.slice(he),at=he-1;else if(R.key==="Delete"&&he<ue.length)Qe=ue.slice(0,he)+ue.slice(he+1),at=he;else return;R.preventDefault(),Be.current=Qe,Z.current=null,ft.current&&(clearTimeout(ft.current),ft.current=null),q.current="input",zt.current.push({value:Qe,cursorPos:at}),Zr(se.current,at),ha(Qe,!0),se.current&&oc(se.current);return}if(yt.current=!1,G.showDropdown&&G.suggestions.length>0)switch(R.key){case"ArrowDown":R.preventDefault(),yt.current=!0,We(ue=>ue>=G.suggestions.length-1?0:ue+1);return;case"ArrowUp":R.preventDefault(),yt.current=!0,We(ue=>ue<=0?G.suggestions.length-1:ue-1);return;case"PageDown":{R.preventDefault(),yt.current=!0;const ue=za();We(he=>Math.min(he+ue,G.suggestions.length-1));return}case"PageUp":{R.preventDefault(),yt.current=!0;const ue=za();We(he=>Math.max(he-ue,0));return}case"Home":if(Lt&&G.selectedSuggestionIndex>=0){R.preventDefault(),yt.current=!0,We(0);return}break;case"End":if(Lt&&G.selectedSuggestionIndex>=0){R.preventDefault(),yt.current=!0,We(G.suggestions.length-1);return}break;case"Enter":if(G.selectedSuggestionIndex>=0){const ue=G.suggestions[G.selectedSuggestionIndex];if(ue.type==="loading"||ue.type==="error"){R.preventDefault(),tn(),l&&l(Be.current,G.ast,R);return}if(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!"){R.preventDefault(),tn();const he=Be.current,xe=G.cursorOffset;if(xe<=he.length&&he[xe]!==" "){const Qe=he.slice(0,xe),at=he.slice(xe),ze=Qe+" "+at;Ea(ze,xe+1,()=>{l&&l(ze,G.ast,R)})}else l&&l(he,G.ast,R);return}R.preventDefault(),Dr(ue,"Enter",void 0,R);return}R.preventDefault(),tn(),l&&l(Be.current,G.ast,R);return;case"Tab":if(U){R.preventDefault();const ue=G.selectedSuggestionIndex>=0?G.suggestions[G.selectedSuggestionIndex]:null,he=ue&&ue.type!=="loading"&&ue.type!=="error"&&!(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!")?ue:null,xe=U({suggestion:he,cursorContext:G.cursorContext||{type:"EMPTY",partial:""},query:Be.current});xe.accept&&he?Dr(he,"Tab",(Qe,at)=>{var ze;xe.submit&&l&&l(Qe,at,R),xe.blur&&((ze=se.current)==null||ze.blur())},R):(tn(),xe.submit&&l&&l(Be.current,G.ast,R),xe.blur&&((ve=se.current)==null||ve.blur()));return}if(G.selectedSuggestionIndex>=0){const ue=G.suggestions[G.selectedSuggestionIndex];if(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!"){R.preventDefault(),tn();const he=Be.current,xe=G.cursorOffset;if(xe<=he.length&&he[xe]!==" "){const Qe=he.slice(0,xe),at=he.slice(xe),ze=Qe+" "+at,Nn=xe+1;Ea(ze,Nn,kt=>{ma(kt,Nn)})}return}R.preventDefault(),Dr(ue,"Tab",void 0,R);return}break;case"Escape":R.preventDefault(),tn();return}if(R.key==="Tab"&&U){R.preventDefault();const ue=U({suggestion:null,cursorContext:G.cursorContext||{type:"EMPTY",partial:""},query:Be.current});ue.submit&&l&&l(Be.current,G.ast,R),ue.blur&&((Fe=se.current)==null||Fe.blur());return}if(G.showDatePicker&&R.key==="Escape"){R.preventDefault(),tn();return}if(R.key==="Enter"&&!G.showDropdown&&!G.showDatePicker){R.preventDefault(),l&&l(Be.current,G.ast,R);return}},[l,tn,Dr,Ea,Ar,Wt,ie,ce,ma,P,U,Yn,Vn,Le,Lt,za,qe]),hs=v.useCallback(R=>{if(yt.current){yt.current=!1;return}if(["ArrowLeft","ArrowRight","Home","End","PageUp","PageDown"].includes(R.key)){if(!se.current)return;const G=xr(se.current);Zt(G.start),_n(G.end),na(Tt.current.tokens,G.start,G.end)}},[na]),Vu=v.useCallback(()=>{fa(!0),K==null||K();const R=requestAnimationFrame(()=>{if(en.current.delete(R),se.current){const G=Tt.current.tokens,Se=G.length>0?jl(se.current):0;Zt(Se),_n(Se),na(G,Se)}});en.current.add(R)},[La,na,K]),ms=v.useCallback(()=>{var R;fa(!1),lt(!1),Kt(!1),$e([]),wn.current=!1,(R=Qt.current)==null||R.abort(),Pt.current&&(clearTimeout(Pt.current),Pt.current=null),Je.current&&(clearTimeout(Je.current),Je.current=null),Zt(-1),W==null||W()},[W]),Or=v.useRef(!1),Fu=v.useCallback(R=>{if(!se.current||R.detail!==2&&R.detail!==3)return;if(R.detail===3){if(!Tt.current.ast)return;const xe=document.caretRangeFromPoint(R.clientX,R.clientY);if(!xe)return;const Qe=Nu(se.current,xe.startContainer,xe.startOffset),at=fj(Tt.current.ast,Be.current,Qe);if(!at||at.start>=at.end)return;R.preventDefault(),Or.current=!0,Kr(se.current,at.start,at.end);return}R.preventDefault(),Or.current=!0;const G=document.caretRangeFromPoint(R.clientX,R.clientY);if(!G)return;const Se=Nu(se.current,G.startContainer,G.startOffset),ve=Be.current,Fe=xe=>!/[\s:()[\]{}"<>!,;|&=~^+\-*/\\]/.test(xe);let ue=Se;for(;ue>0&&Fe(ve[ue-1]);)ue--;let he=Se;for(;he<ve.length&&Fe(ve[he]);)he++;ue<he&&Kr(se.current,ue,he)},[]),aa=v.useCallback(R=>{Or.current&&(R.preventDefault(),Or.current=!1)},[]),Mr=v.useCallback(()=>{if(!se.current)return;const R=xr(se.current);if(Zt(R.start),_n(R.end),R.start!==R.end){const[G,Se]=ax(Tt.current.tokens,R.start,R.end);if(G!==Se){tn();return}}na(Tt.current.tokens,R.start,R.end)},[na,tn]),kr=v.useCallback(R=>{jt.current&&(clearTimeout(jt.current),jt.current=null),Kj(R),La()},[La]),Bl=v.useCallback(R=>{R.preventDefault();const G=tx(R.clipboardData.getData("text/plain"));if(ye){const Se=ye(G,R);Se!=null&&typeof(Se==null?void 0:Se.then)=="function"?Se.then(ve=>{ve!=null&&kr(ve)}).catch(()=>{}):Se!=null&&kr(Se)}else kr(G)},[ye,kr]),Kc=v.useCallback(R=>{q.current="navigation";const G=Tt.current,Se=C.current,ve=Se?Se.start:G.cursorOffset,Fe=Se?Se.end:G.cursorOffset,ue=Be.current.slice(0,ve),he=Be.current.slice(Fe);let xe="",Qe=he;ee&&R.length>0&&(he.length===0?xe=" ":/^[ \t\r\n]+$/.test(he)&&!he.startsWith("\\ ")&&(xe=" ",Qe=""));const at=ue+R+xe+Qe,ze=ue.length+R.length+xe.length;Ea(at,ze,Nn=>{se.current&&se.current.focus(),ma(Nn,ze)})},[Ea,ma,ee]),al=Bu(x),$l=$u(b),ql=Rj(al,A),_r={...jj(al,$l),...In?Tj($l):{}};dr&&(_r.whiteSpace="nowrap",_r.overflow="hidden",_r.textOverflow="ellipsis");const Iu=Dj(al,$l);return v.createElement("div",{ref:Wn,style:ql,className:Ma("ei-container",S,N==null?void 0:N.container)},v.createElement("div",{ref:Jn,contentEditable:!0,suppressContentEditableWarning:!0,className:Ma("ei-editor",N==null?void 0:N.editor),style:_r,onInput:La,onKeyDown:vi,onKeyUp:hs,onMouseDown:Fu,onMouseUp:aa,onFocus:Vu,onBlur:ms,onClick:Mr,onPaste:Bl,onCompositionStart:Wa,onCompositionEnd:gi,spellCheck:!1}),tl&&!In?v.createElement("div",{className:Ma("ei-placeholder",N==null?void 0:N.placeholder),style:Iu},w):null,v.createElement(Qj,{errors:Mn,editorRef:St,cursorOffset:wt,colors:x,styles:b,containerRef:Wn.current,classNames:N?{squiggly:N.squiggly,tooltip:N.tooltip}:void 0}),v.createElement(qj,{suggestions:Ke,selectedIndex:Ht,onSelect:R=>Dr(R,"Tab"),position:Fn,colors:x,styles:b,visible:ot,fixedWidth:Yu(),renderHistoryItem:le,renderSavedSearchItem:Ye,renderDropdownHeader:Ie,cursorContext:wa,listRefCallback:R=>{jr.current=R},renderType:An,classNames:N?{dropdown:N.dropdown,dropdownHeader:N.dropdownHeader,dropdownItem:N.dropdownItem}:void 0}),ct&&Fn?v.createElement(gT,{position:Fn,colors:al,onSelect:Kc,colorConfig:x,styleConfig:b,datePickerInit:Ul,fixedWidth:void 0,datePresets:Y,datePickerClassName:N==null?void 0:N.datePicker}):null)}const yT=["planned","in-progress","done","blocked","canceled","rejected","deferred","waiting"];function gx(t){var u;const a=window.getSelection();if(!a||a.rangeCount===0)return((u=t.textContent)==null?void 0:u.length)??0;const l=a.getRangeAt(0),i=l.cloneRange();return i.selectNodeContents(t),i.setEnd(l.endContainer,l.endOffset),i.toString().length}function xT(t){return a=>{if(!(a.ctrlKey&&!a.metaKey&&!a.altKey))return;const l=a.key.toLowerCase(),i=a.currentTarget,u=i.isContentEditable?i:i.querySelector("[contenteditable='true'], [contenteditable]")??i,o=t.current;if(l==="h"&&o){a.preventDefault();const m=o.getValue();let p=gx(u);(p<0||p>m.length)&&(p=m.length),p>0&&(o.setValue(m.slice(0,p-1)+m.slice(p)),o.setSelection(p-1,p-1));return}if(l==="u"&&o){a.preventDefault();const m=o.getValue();let p=gx(u);if((p<0||p>m.length)&&(p=m.length),p===0)return;let g=p;for(;g>0&&/\s/.test(m[g-1]??"");)g--;if(g===p)for(;g>0&&!/\s/.test(m[g-1]??"");)g--;g<p&&(o.setValue(m.slice(0,g)+m.slice(p)),o.setSelection(g,g));return}const f=l==="j"?"ArrowDown":l==="k"?"ArrowUp":null;f&&(a.preventDefault(),u.dispatchEvent(new KeyboardEvent("keydown",{key:f,bubbles:!0,cancelable:!0})))}}function Nh(t){return String(t>0?t:0).padStart(3,"0")}function bT({features:t,phases:a,query:l,onQuery:i}){const u=v.useRef(null),o=xT(u),f=[{name:"feature",label:"Feature",type:"number",description:"Feature number, e.g. 1 (F001)"},{name:"phase",label:"Phase",type:"number",description:"Phase number, e.g. 2 (P002)"},{name:"task",label:"Task",type:"number",description:"Task number, e.g. 10 (T010). Comma-list supported."},{name:"id",label:"Short ID",type:"string",description:"Global 5-char short id, e.g. UUXD1"},{name:"status",label:"Status",type:"string",description:"Task status"},{name:"feature-status",label:"Feature status",type:"string",description:"Status of the feature"},{name:"phase-status",label:"Phase status",type:"string",description:"Status of the phase"},{name:"title",label:"Title",type:"string",description:"Substring match on title"}],m=v.useMemo(()=>{const g=[...new Set(t.map(N=>N.number))].sort((N,A)=>N-A),x=[...new Set(a.map(N=>N.number))].sort((N,A)=>N-A),b=[...new Set(a.flatMap(N=>N.tasks.map(A=>A.number)))].sort((N,A)=>N-A),w=[...new Set([...t.map(N=>N.shortId),...a.flatMap(N=>[N.shortId,...N.tasks.map(A=>A.shortId)])].filter(Boolean))],S=[...new Set(a.flatMap(N=>N.tasks.map(A=>A.title)))];return{featureNums:g,phaseNums:x,taskNums:b,shortIds:w,titles:S}},[t,a]);async function p(g,x){const b=x.toLowerCase();return g==="feature"?m.featureNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`F${Nh(w)}`})):g==="phase"?m.phaseNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`P${Nh(w)}`})):g==="task"?m.taskNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`T${Nh(w)}`})):g==="id"?m.shortIds.filter(w=>w.toLowerCase().startsWith(b)).slice(0,20).map(w=>({text:w,label:w})):g==="status"||g==="feature-status"||g==="phase-status"?yT.filter(w=>w.startsWith(b)).map(w=>({text:w,label:w})):g==="title"?m.titles.filter(w=>w.toLowerCase().includes(b)).slice(0,20).map(w=>({text:w,label:w.length>44?w.slice(0,44)+"…":w})):[]}return d.jsx("div",{className:"search-bar",children:d.jsx(vT,{fields:f,value:l,onChange:g=>i(g),onSearch:g=>i(g),fetchSuggestions:p,onKeyDown:o,inputRef:g=>{u.current=g},placeholder:"Search Work Tree… e.g. feature:1 id:UUXD1 title:auth status:in-progress"})})}function ST(t,a){if(Object.keys(a).length===0)return t;const l=o=>{const f=a[o];return f?new Map(f.map((m,p)=>[m,p])):null},i=l("__features__");return(i?[...t].sort((o,f)=>(i.get(o.feature.id)??1/0)-(i.get(f.feature.id)??1/0)):t).map(o=>{const f=l(`phase-scope:${o.feature.id}`),m=f?[...o.allPhases].sort((p,g)=>(f.get(p.phase.id)??1/0)-(f.get(g.phase.id)??1/0)):o.allPhases;return{...o,allPhases:m.map(p=>{const g=l(`task-scope:${p.phase.id}`),x=g?[...p.allTasks].sort((b,w)=>(g.get(b.id)??1/0)-(g.get(w.id)??1/0)):p.allTasks;return{...p,allTasks:x}})}})}function wT({features:t,phases:a,activeTasks:l,projectStorageScope:i}){const u=ij({features:t,phases:a,projectStorageScope:i}),[o,f]=v.useState({});v.useEffect(()=>{f({})},[u.displayedWorkTree]);const m=v.useMemo(()=>ST(u.displayedWorkTree,o),[u.displayedWorkTree,o]),[p,g]=v.useState(!1),[x,b]=v.useState(null),[w,S]=v.useState(null),N=ee=>S(String(ee.active.id)),[A,j]=v.useState(0);v.useEffect(()=>{const ee=document.querySelector("header");if(!ee)return;const be=()=>j(ee.offsetHeight);be();const Ee=new ResizeObserver(be);return Ee.observe(ee),window.addEventListener("resize",be),()=>{Ee.disconnect(),window.removeEventListener("resize",be)}},[]),v.useEffect(()=>{const ee=window.setTimeout(()=>{const be=document.querySelector(".ap-search-sticky"),Ee=document.querySelector("header");if(!be||!Ee)return;const z=be.getBoundingClientRect();if(z.top<0){const H=z.top+window.scrollY-Ee.offsetHeight;window.scrollTo({top:Math.max(0,H),behavior:"smooth"})}},60);return()=>window.clearTimeout(ee)},[u.searchQuery,u.hideDone,u.hidePlanned,u.onlyActiveBranches]);const L=NR(ER(om,{activationConstraint:{distance:5}})),I=async ee=>{const{active:be,over:Ee}=ee;if(S(null),!Ee||be.id===Ee.id)return;const z=String(be.id),H=String(Ee.id),ie=m.map(ce=>ce.feature.id);if(ie.includes(z)&&ie.includes(H)){const ce=yu(ie,ie.indexOf(z),ie.indexOf(H)),pe=ce.indexOf(z),D=pe>0?ce[pe-1]??null:null,$=pe<ce.length-1?ce[pe+1]??null:null;f(ne=>({...ne,__features__:ce})),await ih("feature",z,D,$).catch(()=>{});return}for(const ce of m){const pe=ce.allPhases.map(D=>D.phase.id);if(pe.includes(z)&&pe.includes(H)){const D=yu(pe,pe.indexOf(z),pe.indexOf(H)),$=D.indexOf(z),ne=$>0?D[$-1]??null:null,de=$<D.length-1?D[$+1]??null:null;f(je=>({...je,[`phase-scope:${ce.feature.id}`]:D})),await ih("phase",z,ne,de).catch(()=>{});return}}for(const ce of m)for(const pe of ce.allPhases){const D=pe.allTasks.map($=>$.id);if(D.includes(z)&&D.includes(H)){const $=yu(D,D.indexOf(z),D.indexOf(H)),ne=$.indexOf(z),de=ne>0?$[ne-1]??null:null,je=ne<$.length-1?$[ne+1]??null:null;f(Ne=>({...Ne,[`task-scope:${pe.phase.id}`]:$})),await ih("task",z,de,je).catch(()=>{});return}}},Y=ee=>u.expandedPhaseIds.includes(ee),P=ee=>u.recentPhaseIds.includes(ee),K=ee=>u.recentTaskIds.includes(ee),[W,U]=Lc(),[T,oe]=v.useState(null),me=W.get("locate"),ye=me?parseInt(me.replace(/^T/i,""),10):null;v.useEffect(()=>{if(ye==null||Number.isNaN(ye))return;const ee=a.flatMap(H=>H.tasks.map(ie=>({t:ie,p:H}))).find(({t:H})=>H.number===ye);if(!ee){U(H=>(H.delete("locate"),H),{replace:!0});return}const{t:be,p:Ee}=ee;if(u.onlyActiveBranches&&u.setOnlyActiveBranches(!1),u.hideDone&&u.setHideDone(!1),u.searchQuery&&u.setSearchQuery(""),u.setTreeOpenMode("all"),Ee.featureId){const H=Ee.featureId;u.expandedFeatureIds.includes(H)||u.setExpandedFeatureIds(ie=>ie.includes(H)?ie:[...ie,H])}u.expandedPhaseIds.includes(Ee.id)||u.setExpandedPhaseIds(H=>H.includes(Ee.id)?H:[...H,Ee.id]);const z=document.getElementById(`task-row-${ye}`);if(z){const H=document.querySelector("header"),ie=document.querySelector(".ap-search-sticky"),ce=((H==null?void 0:H.offsetHeight)??0)+((ie==null?void 0:ie.offsetHeight)??0)+12,pe=z.getBoundingClientRect().top+window.scrollY-ce;window.scrollTo({top:Math.max(0,pe),behavior:"smooth"}),oe(be.id);const D=window.setTimeout(()=>oe(null),2500);return U($=>($.delete("locate"),$),{replace:!0}),()=>window.clearTimeout(D)}},[ye,a,u.expandedFeatureIds,u.expandedPhaseIds,u.onlyActiveBranches,u.hideDone,u.searchQuery,u.treeOpenMode]);const Re=()=>{if(!w)return null;for(const ee of m){if(ee.feature.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number}),d.jsx(Sa,{status:ee.feature.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:ee.feature.name})]});for(const be of ee.allPhases){if(be.phase.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number,phaseNum:be.phase.number}),d.jsx(Sa,{status:be.phase.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:be.phase.title})]});for(const Ee of be.allTasks)if(Ee.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number,phaseNum:be.phase.number,taskNum:Ee.number}),d.jsx(Sa,{status:Ee.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:Ee.title})]})}}return null};return d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"flex flex-col gap-3 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{children:[d.jsx("h2",{className:"text-lg font-bold text-[var(--text)]",children:"Work Tree"}),d.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:"Collapsible feature → phase → task tree. Click a feature or phase row to collapse/expand."})]}),d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(bt,{type:"button",variant:"secondary",onClick:()=>u.expandAll(),children:"Expand all"}),d.jsx(bt,{type:"button",variant:"secondary",onClick:()=>u.setTreeOpenMode("none"),children:"Collapse all"})]})]}),d.jsxs("div",{className:"ap-search-sticky z-20",style:{top:A},children:[d.jsx(bT,{features:t,phases:a,query:u.searchQuery,onQuery:u.setSearchQuery}),u.searchActive?d.jsxs("p",{className:"text-xs text-[var(--text-muted)]",children:[u.matchedTaskIds.size," match",u.matchedTaskIds.size===1?"":"es"," — clear the box to reset."]}):null,d.jsx("div",{className:"grid grid-cols-1 gap-2 rounded-[14px] border border-[var(--border)] bg-[var(--surface-card)] px-3 py-2 sm:rounded-[18px] sm:px-4 sm:py-3",children:d.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 sm:gap-2",children:[d.jsx("button",{type:"button",onClick:()=>u.setHideDone(ee=>!ee),className:`status-chip transition ${u.hideDone?"status-done":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Hide done"}),d.jsx("button",{type:"button",onClick:()=>u.setHidePlanned(ee=>!ee),className:`status-chip transition ${u.hidePlanned?"status-planned":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Hide planned"}),d.jsx("button",{type:"button",onClick:()=>u.setOnlyActiveBranches(ee=>!ee),className:`status-chip transition ${u.onlyActiveBranches?"status-in-progress":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Only active"}),d.jsx(bt,{type:"button",variant:"secondary",className:"!min-h-9 !px-3 !py-1 !text-xs sm:!min-h-11 sm:!px-4 sm:!py-2 sm:!text-sm",onClick:u.resetFilters,children:"Reset"}),d.jsx(bt,{type:"button",variant:"secondary",className:"!min-h-9 !px-3 !py-1 !text-xs sm:!min-h-11 sm:!px-4 sm:!py-2 sm:!text-sm",disabled:p,onClick:async()=>{g(!0),b(null);try{const ee=await jN(),be=ee.migrated,Ee=ee.integrity.duplicatePhaseIds.length,z=ee.integrity.danglingPhaseIds.length;b(`Repair done: renamed ${be.renamed}, repaired ${be.repaired} refs, inferred ${be.inferred}. Integrity: ${Ee} duplicate, ${z} dangling.`)}catch(ee){b(`Repair failed: ${ee instanceof Error?ee.message:String(ee)}`)}finally{g(!1)}},children:p?"Repairing…":"Repair"}),x?d.jsx("span",{className:"hidden text-xs text-[var(--text-muted)] sm:inline sm:truncate",children:x}):null]})})]}),d.jsx("div",{className:"grid gap-3",children:m.length>0?d.jsxs(N2,{sensors:L,collisionDetection:AR,onDragStart:N,onDragEnd:I,children:[d.jsx(fm,{items:m.map(ee=>ee.feature.id),strategy:dm,children:m.map(ee=>d.jsx(hm,{id:ee.feature.id,children:d.jsx(oj,{entry:ee,expanded:u.expandedFeatureIds.includes(ee.feature.id),recentlyChanged:u.recentFeatureIds.includes(ee.feature.id),onToggle:()=>u.toggleExpandedFeature(ee.feature.id),isPhaseExpanded:Y,onTogglePhase:u.toggleExpandedPhase,isPhaseRecentlyChanged:P,isTaskRecentlyChanged:K,highlightedTaskIds:(()=>{const be=u.searchActive?u.matchedTaskIds:void 0;if(!T)return be;const Ee=new Set(be??[]);return Ee.add(T),Ee})()})},ee.feature.id))}),d.jsx(V2,{dropAnimation:{duration:150,easing:"ease"},children:Re()})]}):l.length>0?l.map(ee=>{const be=ee.featureId?`/features/${ee.featureId}/phases/${ee.phaseId}/tasks/${ee.id}`:"/features";return d.jsxs(dt,{to:be,className:"surface-card grid gap-1 px-4 py-3 transition hover:border-[var(--accent)] hover:bg-[var(--accent-soft)]",children:[d.jsxs("div",{className:"flex items-center justify-between gap-2",children:[d.jsxs("span",{className:"inline-flex min-w-0 items-center gap-2 truncate text-sm font-semibold text-[var(--text)]",children:[ee.status==="in-progress"?d.jsx("span",{"aria-hidden":"true",className:"ap-progress-dot"}):null,d.jsxs("span",{className:"truncate",children:["T",sR(ee.number)," — ",ee.title]})]}),d.jsx(Sa,{status:ee.status})]}),d.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-muted)]",children:ee.phaseId})]},ee.id)}):d.jsx("p",{className:"py-4 text-center text-sm text-[var(--text-muted)]",children:"No work items match the current filters."})})]})}function ET(){const{features:t,phases:a,activeTasks:l}=cs(),{project:i}=Ou("root"),u=el(),o=()=>u("/project/edit");Zn("edit",o);const f=i.projectRoot||i.planRoot||i.name||"default";return d.jsxs("div",{className:"grid grid-cols-1 gap-8",children:[d.jsx(gn,{className:"grid grid-cols-1 gap-4",children:d.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{children:[d.jsx("h2",{className:"text-lg font-bold text-[var(--text)]",children:"Project Goal"}),i.goal?d.jsx(Hn,{text:i.goal,className:"mt-2 max-w-4xl"}):d.jsx("p",{className:"mt-2 max-w-4xl text-sm text-[var(--text-muted)]",children:"Add a project goal to define the main objective."})]}),d.jsxs(bt,{type:"button",shortcut:"edit",onClick:o,className:"self-start",children:[d.jsx(us,{className:"h-4 w-4"}),"Edit project"]})]})}),d.jsx(JN,{project:i}),d.jsx(uR,{features:t,phases:a}),d.jsx(wT,{features:t,phases:a,activeTasks:l,projectStorageScope:f}),d.jsx(eR,{features:t,phases:a}),d.jsx(nR,{features:t,phases:a})]})}async function NT(){const[t,a]=await Promise.all([hb(),tm()]);return{features:t,phases:a}}function Ru(){return{active:0,planned:0,done:0,blocked:0,canceled:0}}function Tc(t){const a=[];return t.active&&a.push(`${t.active} active`),t.planned&&a.push(`${t.planned} planned`),t.done&&a.push(`${t.done} done`),t.blocked&&a.push(`${t.blocked} blocked`),t.canceled&&a.push(`${t.canceled} canceled`),a.join(" · ")}function RT(t){const a=Ru();for(const l of t){if(l.status==="in-progress"||l.status==="discovery"){a.active+=1;continue}if(l.status==="planned"||l.status==="draft"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function Wb(t){const a=Ru();for(const l of t){if(l.status==="in-progress"){a.active+=1;continue}if(l.status==="planned"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function jT(t){const a=Ru();for(const l of t){if(l.status==="in-progress"){a.active+=1;continue}if(l.status==="planned"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function TT({feature:t,phasesCount:a,tasksCount:l,phaseSummary:i,taskSummary:u,activity:o}){var A;const f=is(),m=is(),g=((A=f.formData)==null?void 0:A.get("status"))??t.status,x=f.state!=="idle",b=m.state!=="idle",w=Tc(i),S=Tc(u),N=t.description||(o?`${o.doneTasks}/${l} done · ${o.remainingTasks} left${o.blockedTasks?` · ${o.blockedTasks} blocked`:""}`:"");return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 xl:grid-cols-[minmax(0,1fr)_minmax(0,132px)_minmax(0,152px)_124px_44px_44px] xl:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 xl:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"feature",number:t.number}),d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:g})})]}),d.jsx(dt,{to:`/features/${t.id}`,className:"entity-link--feature min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:t.name})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end xl:hidden",children:[d.jsx(dt,{to:`/features/${t.id}/edit`,"aria-label":`Edit feature ${t.name}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(m.Form,{method:"post",action:`/features/${t.id}/delete`,onSubmit:j=>{window.confirm(`Delete feature “${t.name}”? This cannot be undone.`)||j.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:b||x,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete feature ${t.name}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[a," phases"]}),w?d.jsx("div",{className:"mt-0.5 break-words",children:w}):null]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l," tasks"]}),S?d.jsx("div",{className:"mt-0.5 break-words",children:S}):null]}),d.jsx(f.Form,{method:"post",action:`/features/${t.id}/status`,className:"w-full xl:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:g,disabled:x||b,"aria-busy":x,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:j=>f.submit(j.currentTarget.form),children:Xc.map(j=>d.jsx("option",{value:j.value,children:j.label},j.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t.id}/edit`,"aria-label":`Edit feature ${t.name}`,className:"hidden xl:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(m.Form,{method:"post",action:`/features/${t.id}/delete`,className:"hidden xl:block",onSubmit:j=>{window.confirm(`Delete feature “${t.name}”? This cannot be undone.`)||j.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:b||x,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete feature ${t.name}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),N?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:N}):null]})}const DT={feature:{label:"Feature",Icon:bc},phase:{label:"Phase",Icon:YE},task:{label:"Task",Icon:em}};function CT({kind:t,label:a}){const{Icon:l,label:i}=DT[t];return d.jsxs("span",{className:`entity-badge entity-badge--${t}`,children:[d.jsx(l,{className:"h-3.5 w-3.5"}),d.jsx("span",{children:a??i})]})}function Pa({className:t="",...a}){return d.jsx("input",{className:`field-control ${t}`,...a})}function qu({className:t="",...a}){return d.jsx("select",{className:`field-control ${t}`,...a})}function gm({query:t,status:a,statusOptions:l,placeholder:i,clearTo:u,resultsLabel:o}){const f=Wh();return d.jsxs(_a,{method:"get",className:"surface-card grid gap-3 p-3 md:grid-cols-[minmax(0,1fr)_200px_auto_auto] md:items-end sm:p-4",children:[d.jsxs("div",{children:[d.jsx("label",{htmlFor:"list-filter-query",className:"mb-1 block text-xs font-semibold uppercase tracking-[0.18em] text-[var(--text-subtle)]",children:"Name"}),d.jsx(Pa,{id:"list-filter-query",name:"q",defaultValue:t,placeholder:i,className:"min-h-9 py-2 sm:min-h-11 sm:py-2.5",onChange:m=>f(m.currentTarget.form)})]}),d.jsxs("div",{children:[d.jsx("label",{htmlFor:"list-filter-status",className:"mb-1 block text-xs font-semibold uppercase tracking-[0.18em] text-[var(--text-subtle)]",children:"Status"}),d.jsxs("div",{className:"relative",children:[d.jsxs(qu,{id:"list-filter-status",name:"status",defaultValue:a,className:"min-h-9 appearance-none py-2 sm:min-h-11 sm:py-2.5 pr-8",children:[d.jsx("option",{value:"",children:"All statuses"}),l.map(m=>d.jsx("option",{value:m.value,children:m.label},m.value))]}),d.jsx(_l,{className:"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--text-muted)]"})]})]}),d.jsx(bt,{type:"submit",variant:"secondary",children:"Apply filters"}),d.jsx(dt,{to:u,className:"inline-flex min-h-9 items-center justify-center rounded-[12px] px-3 text-sm font-semibold text-[var(--text-muted)] transition hover:bg-[var(--accent-soft)] hover:text-[var(--text)] sm:min-h-11 sm:rounded-[14px]",children:"Clear"}),d.jsx("div",{className:"text-sm text-[var(--text-muted)] md:col-span-4",children:o})]})}function vm(t,a){const l=t.trim().toLowerCase();return l?a.some(i=>i==null?void 0:i.toLowerCase().includes(l)):!0}function AT(t){const a=new Map,l=new Map,i=new Map,u=new Map,o=new Map;for(const f of t)f.featureId&&o.set(f.featureId,[...o.get(f.featureId)??[],f]);for(const[f,m]of o)a.set(f,m.length),l.set(f,m.reduce((p,g)=>p+g.tasks.length,0)),i.set(f,RT(m)),u.set(f,Wb(m.flatMap(p=>p.tasks)));return{phasesByFeature:a,tasksByFeature:l,phaseSummaryByFeature:i,taskSummaryByFeature:u}}function OT(){var w,S;const{features:t,phases:a}=cs(),{phasesByFeature:l,tasksByFeature:i,phaseSummaryByFeature:u,taskSummaryByFeature:o}=AT(a),f=el(),[m]=Lc(),p=((w=m.get("q"))==null?void 0:w.trim())??"",g=((S=m.get("status"))==null?void 0:S.trim())??"",x=v.useCallback(()=>f("new"),[f]);Zn("create",x);const b=v.useMemo(()=>t.filter(N=>(!g||N.status===g)&&vm(p,[N.name,N.id,N.description])),[t,p,g]);return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(gn,{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[d.jsxs("div",{children:[d.jsx(CT,{kind:"feature",label:"Features"}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter by name or status, then inspect child phases and tasks directly from the rows."})]}),d.jsx(dt,{to:"new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create feature"})})]}),d.jsx(gm,{query:p,status:g,statusOptions:Xc,placeholder:"Search feature name, id, or description",clearTo:"/features",resultsLabel:b.length===t.length?`${t.length} features`:`${b.length} of ${t.length} features`}),d.jsx("div",{className:"grid gap-3",children:t.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No features yet. ",d.jsx(dt,{to:"/features/new",className:"font-semibold text-[var(--accent)] hover:underline",children:"Create your first feature"})]}):b.length>0?b.map(N=>d.jsx(TT,{feature:N,phasesCount:l.get(N.id)??0,tasksCount:i.get(N.id)??0,phaseSummary:u.get(N.id)??Ru(),taskSummary:o.get(N.id)??Ru()},N.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No features match the current filters."})})]}),d.jsx(Mu,{})]})}async function MT({params:t}){const a=t.featureId;if(!a)throw new Response("featureId required",{status:400});const[l,i]=await Promise.all([ku(a),tm(a)]);return{feature:l,phases:i}}function kT({featureId:t,feature:a,phase:l}){var x;const i=is(),u=is(),f=((x=i.formData)==null?void 0:x.get("status"))??l.status,m=i.state!=="idle",p=u.state!=="idle",g=Tc(Wb(l.tasks));return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 lg:grid-cols-[minmax(0,1fr)_minmax(0,150px)_124px_44px_44px] lg:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"phase",number:l.number}),d.jsx(ai,{type:"phase",featureNum:a.number}),l.handoff?d.jsx(am,{phaseId:l.id,updatedAt:l.handoffUpdatedAt}):null,d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:f})})]}),d.jsx(dt,{to:`/features/${t}/phases/${l.id}`,className:"entity-link--phase min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:l.title})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end lg:hidden",children:[d.jsx(dt,{to:`/features/${t}/phases/${l.id}/edit`,"aria-label":`Edit phase ${l.title}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${l.id}/delete`,onSubmit:b=>{window.confirm(`Delete phase “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete phase ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l.tasks.length," tasks"]}),g?d.jsx("div",{className:"mt-0.5 break-words",children:g}):null]}),d.jsx(i.Form,{method:"post",action:`/features/${t}/phases/${l.id}/status`,className:"w-full lg:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:f,disabled:m||p,"aria-busy":m,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:b=>i.submit(b.currentTarget.form),children:Pc.map(b=>d.jsx("option",{value:b.value,children:b.label},b.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t}/phases/${l.id}/edit`,"aria-label":`Edit phase ${l.title}`,className:"hidden lg:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${l.id}/delete`,className:"hidden lg:block",onSubmit:b=>{window.confirm(`Delete phase “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete phase ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),l.summary?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:l.summary}):null]})}function ym({items:t,className:a="",stacked:l=!1}){return l?d.jsx("nav",{"aria-label":"Breadcrumb",className:`grid gap-1 text-sm ${a}`,children:t.map((i,u)=>{const o=u===t.length-1,f=i.to&&!o?d.jsx(dt,{to:i.to,className:"font-semibold text-[var(--accent)] hover:underline break-words min-w-0",children:i.label}):d.jsx("span",{className:`break-words min-w-0 ${o?"text-[var(--text)] font-semibold":"text-[var(--text-muted)]"}`,children:i.label});return d.jsxs("div",{className:"flex items-baseline gap-2 min-w-0",children:[i.kind?d.jsxs("span",{className:"shrink-0 text-[var(--text-subtle)] font-medium",children:[i.kind,":"]}):null,d.jsx("span",{className:"min-w-0",children:f})]},`${i.label}-${u}`)})}):d.jsx("nav",{"aria-label":"Breadcrumb",className:`flex flex-wrap items-center gap-2 text-sm ${a}`,children:t.map((i,u)=>{const o=u===t.length-1,f=i.to&&!o?d.jsx(dt,{to:i.to,className:"font-semibold text-[var(--accent)] hover:underline",children:i.label}):d.jsx("span",{className:o?"text-[var(--text)]":"text-[var(--text-muted)]",children:i.label});return d.jsxs("span",{className:"inline-flex min-w-0 items-center gap-2",children:[u>0?d.jsx("span",{className:"text-[var(--text-subtle)]",children:"/"}):null,d.jsx("span",{className:"min-w-0 break-words",children:f})]},`${i.label}-${u}`)})})}function bn({className:t="",children:a,...l}){return d.jsx("div",{className:`surface-card p-4 ${t}`,...l,children:a})}function Dc({title:t,actions:a,defaultOpen:l=!0,count:i,children:u}){return d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",open:l,children:[d.jsxs("summary",{className:"flex items-center justify-between gap-2 p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsxs("span",{className:"flex items-center gap-2 text-sm",children:[t,i!==void 0?d.jsxs("span",{className:"text-[var(--text-subtle)]",children:["(",i,")"]}):null]}),d.jsxs("span",{className:"flex items-center gap-2",children:[a,d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)]",children:u})]})}function xm({decisions:t}){return t.length===0?null:d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex cursor-pointer select-none items-center gap-2 font-semibold text-[var(--text)]",children:d.jsxs("span",{children:["Accepted decisions (",t.length,")"]})}),d.jsx("div",{className:"mt-2 grid gap-3",children:t.map(a=>d.jsxs("div",{className:"surface-card px-4 py-3",children:[d.jsx("p",{className:"text-sm font-semibold text-[var(--text)]",children:a.title}),a.decision?d.jsxs("div",{className:"mt-2 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Decision:"}),d.jsx(Hn,{text:a.decision,className:"mt-1"})]}):null,a.rationale?d.jsxs("div",{className:"mt-1 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Rationale:"}),d.jsx(Hn,{text:a.rationale,className:"mt-1"})]}):null,a.implementationNotes?d.jsxs("div",{className:"mt-1 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Implementation:"}),d.jsx(Hn,{text:a.implementationNotes,className:"mt-1"})]}):null]},a.id))})]})}const _T={draft:CE,discovery:lN,planned:em,"in-progress":LE,done:ob,blocked:eN,waiting:kE,deferred:oN,canceled:SE,rejected:OE};function Rh(t){return t.split(/[-\s]+/).filter(Boolean).map(a=>a==="and"?"and":a.charAt(0).toUpperCase()+a.slice(1)).join(" ")}function vx(t){if(!t)return"";try{return new Intl.DateTimeFormat(void 0,{dateStyle:"short",timeStyle:"short"}).format(new Date(t))}catch{return t}}const LT=new Set(["canceled","rejected"]);function bm({statusLog:t,currentStatus:a,backbone:l,createdAt:i,updatedAt:u,startedAt:o,completedAt:f}){const m=[];if(t.length===0){const S=l.indexOf(a);if(S>=0)for(let N=0;N<=S;N++)m.push(l[N]);else m.push(a)}else{const S=t[0];S&&m.push(S.fromStatus);for(const N of t)m[m.length-1]!==N.toStatus&&m.push(N.toStatus)}m[m.length-1]!==a&&m.push(a);const p=new Set(m),g=a==="done"||LT.has(a),x=[...m];if(!g){const S=l.indexOf(a);if(S>=0&&S+1<l.length){const N=l[S+1];p.has(N)||x.push(N)}}const b=S=>p.has(S)?S===a&&!g?"current":"completed":"pending",w=S=>{var A,j;if(t.length>0){if(S===((A=t[0])==null?void 0:A.fromStatus))return((j=t[0])==null?void 0:j.date)??"";for(const L of t)if(L.toStatus===S)return L.date;return""}const N=l[0];return S===N?i??"":S==="in-progress"?o??u??"":S==="done"?f??u??"":""};return d.jsx("ol",{className:"status-stepper",role:"list","aria-label":"Status progress",children:x.map((S,N)=>{const A=b(S),j=_T[S]??UE,L=p.has(S),I=w(S),Y=I?`${Rh(S)} — ${vx(I)}`:Rh(S),P=N===0?null:L?"traveled":"pending";return d.jsxs("li",{className:`status-step status-step--${A}`,role:"listitem","aria-current":A==="current"?"step":void 0,style:{"--step-color":`var(--color-status-${S})`},children:[P?d.jsx("span",{className:`status-connector status-connector--${P}`,"aria-hidden":"true"}):null,d.jsx("span",{className:"status-node",title:Y,children:d.jsx(j,{className:"status-node-icon"})}),d.jsx("span",{className:"status-step-label",children:Rh(S)}),I?d.jsx("span",{className:"status-step-date",children:vx(I)}):null]},`${S}-${N}`)})})}function yx(t){return t.split(/[-\s]+/).filter(Boolean).map(a=>a==="and"?"and":a.charAt(0).toUpperCase()+a.slice(1)).join(" ")}function zT(t){if(!t)return"";try{return new Intl.DateTimeFormat(void 0,{dateStyle:"short",timeStyle:"short"}).format(new Date(t))}catch{return t}}function UT(t,a,l,i,u){if(t.length>0)return t.map(m=>({date:m.date,fromStatus:m.fromStatus,toStatus:m.toStatus,inferred:!1}));const o=l.indexOf(a);if(o<0)return[];const f=[];for(let m=1;m<=o;m++){const p=l[m-1],g=l[m],x=g==="in-progress"?i??"":g==="done"?u??"":"";f.push({date:x,fromStatus:p,toStatus:g,inferred:!0})}return f}function Sm({statusLog:t,currentStatus:a,backbone:l,startedAt:i,completedAt:u}){const o=UT(t??[],a??"",l??[],i,u),f=o.length>0;return d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",open:f,children:[d.jsxs("summary",{className:"flex items-center justify-between p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsxs("span",{className:"text-sm",children:["Status history (",o.length,")"]}),d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)] grid gap-2.5",children:o.length===0?d.jsx("p",{className:"text-sm text-[var(--text-muted)] italic",children:"No status changes recorded."}):o.map((m,p)=>d.jsxs("div",{className:"text-sm flex flex-wrap items-center gap-2",children:[d.jsx("span",{className:"text-xs font-mono text-[var(--text-subtle)]",children:zT(m.date)}),d.jsx("span",{className:"font-semibold text-[var(--text-muted)]",children:yx(m.fromStatus)}),d.jsx("span",{className:"text-[var(--text-subtle)]",children:"→"}),d.jsx("span",{className:"font-semibold text-[var(--text)]",children:yx(m.toStatus)})]},p))})]})}function HT(t){return t.reduce((a,l)=>a+l.tasks.length,0)}function BT(t){let a=0,l=0,i=0,u=0;for(const o of t)for(const f of o.tasks)f.status==="in-progress"&&(a+=1),f.status==="done"&&(l+=1),f.status==="blocked"&&(i+=1),["done","canceled"].includes(f.status)||(u+=1);return{inProgress:a,done:l,blocked:i,remaining:u}}function $T(t){return t.find(a=>["in-progress","discovery","planned","draft"].includes(a.status))}function qT(){var A,j;const{feature:t,phases:a}=cs(),l=t.acceptedDecisions??[],i=HT(a),u=BT(a),o=$T(a),[f]=Lc(),m=((A=f.get("q"))==null?void 0:A.trim())??"",p=((j=f.get("status"))==null?void 0:j.trim())??"",g=v.useMemo(()=>a.filter(L=>(!p||L.status===p)&&vm(m,[L.title,L.id,L.summary,L.description])),[a,m,p]),x=el(),b=v.useRef(null),w=v.useCallback(()=>x("edit"),[x]),S=v.useCallback(()=>x("phases/new"),[x]),N=v.useCallback(()=>{var L;(L=b.current)==null||L.requestSubmit()},[]);return Zn("edit",w),Zn("create",S),Zn("delete",N),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:"/features",className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to features"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,kind:"Feature"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number}),children:d.jsx(Wr,{featureNum:t.number})}),t.shortId?d.jsx(ii,{shortId:t.shortId}):null,d.jsx(Sa,{status:t.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:t.name}),t.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:t.description,className:"plan-description max-w-4xl"})}):null,d.jsx("div",{className:"mt-4",children:d.jsx(bm,{statusLog:t.statusLog??[],currentStatus:t.status,backbone:["planned","in-progress","done"],createdAt:t.createdAt,updatedAt:t.updatedAt})}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit feature"})}),d.jsx(_a,{ref:b,method:"post",action:`/features/${t.id}/delete`,className:"inline-flex",onSubmit:L=>{window.confirm(`Delete feature "${t.name}"?`)||L.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete feature"})})]})]}),d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Current phase"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:(o==null?void 0:o.title)||"No active phase"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Phases"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:a.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Tasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:i})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Window"}),d.jsxs("p",{className:"mt-2 text-sm font-semibold text-[var(--text)]",children:[t.startDate||"Not set"," → ",t.endDate||"Not set"]})]})]}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"In progress"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.inProgress})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Remaining"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.remaining})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Done"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.done})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Blocked"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.blocked})]})]}),t.workDone||t.workRemaining?d.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[t.workDone?d.jsxs("div",{children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Work done:"}),d.jsx(Hn,{text:t.workDone,className:"mt-2"})]}):null,t.workRemaining?d.jsxs("div",{children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Work remaining:"}),d.jsx(Hn,{text:t.workRemaining,className:"mt-2"})]}):null]}):null,l.length>0?d.jsx(xm,{decisions:l}):null,d.jsx(Sm,{statusLog:t.statusLog??[],currentStatus:t.status,backbone:["planned","in-progress","done"]})]}),d.jsxs(gn,{className:"grid gap-5",children:[d.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[d.jsx(Ll,{type:"phase",number:0}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter this feature's phases by name or status."})]}),d.jsx(dt,{to:"phases/new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create phase"})})]}),d.jsx(gm,{query:m,status:p,statusOptions:Pc,placeholder:"Search phase title, id, or summary",clearTo:`/features/${t.id}`,resultsLabel:g.length===a.length?`${a.length} phases`:`${g.length} of ${a.length} phases`}),d.jsx("div",{className:"grid gap-3",children:a.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No phases yet. ",d.jsx(dt,{to:`/features/${t.id}/phases/new`,className:"font-semibold text-[var(--accent)] hover:underline",children:"Add a phase"})]}):g.length>0?g.map(L=>d.jsx(kT,{featureId:t.id,feature:t,phase:L},L.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No phases match the current filters."})})]}),d.jsx(Mu,{})]})}async function YT({params:t}){const{featureId:a,phaseId:l}=t;if(!a||!l)throw new Response("featureId and phaseId required",{status:400});const[i,u]=await Promise.all([ku(a),$c(l)]);return{feature:i,phase:u}}function xx(t){try{return new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(new Date(t))}catch{return t}}function VT({featureId:t,phaseId:a,task:l}){var x;const i=is(),u=is(),f=((x=i.formData)==null?void 0:x.get("status"))??l.status,m=i.state!=="idle",p=u.state!=="idle",g=Tc(jT(l.subtasks));return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 lg:grid-cols-[minmax(0,1fr)_minmax(0,168px)_124px_44px_44px] lg:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"task",number:l.number}),d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:f})})]}),d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}`,className:"entity-link--task min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:l.title})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end lg:hidden",children:[d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}/edit`,"aria-label":`Edit task ${l.title}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/delete`,onSubmit:b=>{window.confirm(`Delete task “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete task ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l.subtasks.length," subtasks · ",l.checklist.length," checklist"]}),g?d.jsx("div",{className:"mt-0.5 break-words",children:g}):d.jsx("div",{className:"mt-0.5 break-words",children:"No subtask statuses yet"})]}),d.jsx(i.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/status`,className:"w-full lg:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:f,disabled:m||p,"aria-busy":m,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:b=>i.submit(b.currentTarget.form),children:Hu.map(b=>d.jsx("option",{value:b.value,children:b.label},b.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}/edit`,"aria-label":`Edit task ${l.title}`,className:"hidden lg:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/delete`,className:"hidden lg:block",onSubmit:b=>{window.confirm(`Delete task “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete task ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),d.jsxs("div",{className:"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-[var(--text-subtle)]",children:[l.startedAt?d.jsxs("span",{children:["Started ",xx(l.startedAt)]}):null,l.completedAt?d.jsxs("span",{children:["Completed ",xx(l.completedAt)]}):null]}),l.description?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:l.description}):null]})}function FT(t){let a=0,l=0,i=0,u=0;for(const o of t.tasks)o.status==="in-progress"&&(a+=1),o.status==="done"&&(l+=1),o.status==="blocked"&&(i+=1),["done","canceled"].includes(o.status)||(u+=1);return{inProgress:a,done:l,blocked:i,remaining:u}}function IT(){var Y,P;const{feature:t,phase:a}=cs(),l=a.decisions??[],i=a.acceptedDecisions??[],u=FT(a),[o]=Lc(),f=((Y=o.get("q"))==null?void 0:Y.trim())??"",m=((P=o.get("status"))==null?void 0:P.trim())??"",p=v.useMemo(()=>a.tasks.filter(K=>(!m||K.status===m)&&vm(f,[K.title,K.id,K.description,K.shortName])),[a.tasks,f,m]),g=el(),x=v.useRef(null),[b,w]=v.useState(a.handoff??""),[S,N]=v.useState(!1),A=v.useCallback(()=>g("edit"),[g]),j=v.useCallback(()=>g("tasks/new"),[g]),L=v.useCallback(()=>{var K;(K=x.current)==null||K.requestSubmit()},[]),I=v.useCallback(async()=>{if(window.confirm("Clear this phase's handoff?")){N(!0);try{await NN(a.id),w("")}catch{}finally{N(!1)}}},[a.id]);return Zn("edit",A),Zn("create",j),Zn("delete",L),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:`/features/${t.id}`,className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to feature"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,to:`/features/${t.id}`,kind:"Feature"},{label:a.title,kind:"Phase"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number,phaseNum:a.number}),children:d.jsx(Wr,{featureNum:t.number,phaseNum:a.number})}),a.shortId?d.jsx(ii,{shortId:a.shortId}):null,b?d.jsx(am,{phaseId:a.id,updatedAt:a.handoffUpdatedAt}):null,d.jsx(Sa,{status:a.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:a.title}),a.summary?d.jsx(Hn,{text:a.summary,className:"mt-3 max-w-4xl"}):null,d.jsx(bm,{statusLog:a.statusLog??[],currentStatus:a.status,backbone:["draft","discovery","planned","in-progress","done"],createdAt:a.createdAt,updatedAt:a.updatedAt}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit phase"})}),d.jsx(dt,{to:"tasks/new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create task"})}),d.jsx(_a,{ref:x,method:"post",action:`/features/${t.id}/phases/${a.id}/delete`,className:"inline-flex",onSubmit:K=>{window.confirm(`Delete phase "${a.title}"?`)||K.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete phase"})})]})]}),d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Tasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:a.tasks.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"In progress"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.inProgress})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Remaining"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.remaining})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Done"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.done})]})]}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Blocked"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.blocked})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Goals"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.goals.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Dependencies"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.dependencies.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Completion criteria"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.completionCriteria.length})]})]}),a.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:a.description,className:"plan-description"})}):null,l.length>0?d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex items-center gap-2 cursor-pointer font-semibold text-[var(--text)] select-none",children:d.jsxs("span",{children:["Decisions (",l.length,")"]})}),d.jsx("div",{className:"mt-2 ml-4 space-y-2 border-l-2 border-[var(--border)] pl-4",children:l.map((K,W)=>d.jsx("div",{className:"text-sm text-[var(--text-muted)]",children:d.jsx(Hn,{text:K})},W))})]}):null,i.length>0?d.jsx(xm,{decisions:i}):null,d.jsx(Sm,{statusLog:a.statusLog??[],currentStatus:a.status,backbone:["draft","discovery","planned","in-progress","done"]})]}),b?d.jsx(gn,{className:"grid gap-4",children:d.jsx(Dc,{title:"Handoff",actions:d.jsx("button",{type:"button",onClick:I,disabled:S,className:"rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm text-[var(--text-muted)] hover:bg-[var(--surface-card)] disabled:opacity-60",children:S?"Clearing…":"Clear handoff"}),children:d.jsx("div",{className:"rounded-[18px] border border-[var(--border)] bg-[var(--surface-card)] px-5 py-5",children:d.jsx(Hn,{text:b,className:"formatted-text max-w-none"})})})}):null,d.jsxs(gn,{className:"grid gap-5",children:[d.jsxs("div",{children:[d.jsx(Ll,{type:"task",number:0}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter this phase's tasks by name or status."})]}),d.jsx(gm,{query:f,status:m,statusOptions:Hu,placeholder:"Search task title, id, or description",clearTo:`/features/${t.id}/phases/${a.id}`,resultsLabel:p.length===a.tasks.length?`${a.tasks.length} tasks`:`${p.length} of ${a.tasks.length} tasks`}),d.jsx("div",{className:"grid gap-3",children:a.tasks.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No tasks yet. ",d.jsx(dt,{to:"tasks/new",className:"font-semibold text-[var(--accent)] hover:underline",children:"Add a task"})]}):p.length>0?p.map(K=>d.jsx(VT,{featureId:t.id,phaseId:a.id,task:K},K.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No tasks match the current filters."})})]}),d.jsx(Mu,{})]})}async function GT({params:t}){const{featureId:a,phaseId:l,taskId:i}=t;if(!a||!l||!i)throw new Response("featureId, phaseId and taskId required",{status:400});const[u,o,f]=await Promise.all([ku(a),$c(l),qc(i)]);return{feature:u,phase:o,task:f}}function bx(t){try{return new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(new Date(t))}catch{return t}}function XT({featureId:t,phaseId:a,taskId:l,item:i}){const u=is(),o=u.formData?u.formData.get("checked")==="true":i.checked,f=u.state!=="idle";return d.jsxs("div",{className:"surface-card flex items-start gap-3 px-4 py-3",children:[d.jsx("input",{type:"checkbox",checked:o,onChange:()=>u.submit({checked:i.checked?"false":"true"},{method:"post",action:`/features/${t}/phases/${a}/tasks/${l}/checklist/${i.id}/toggle`}),disabled:f,className:"mt-0.5 h-4 w-4 shrink-0 accent-[var(--accent)]","aria-label":`Toggle checklist item ${i.title}`}),d.jsxs("div",{className:"min-w-0",children:[d.jsx("span",{className:"checklist-num",children:i.number})," ",d.jsx("span",{className:`text-sm ${o?"text-[var(--text-muted)] line-through":"font-medium text-[var(--text)]"}`,children:i.title})]})]})}function PT(){var x,b;const{feature:t,phase:a,task:l}=cs(),i=l.decisions??[],u=l.acceptedDecisions??[],o=l.checklist??[],f=el(),m=v.useRef(null),p=v.useCallback(()=>f("edit"),[f]),g=v.useCallback(()=>{var w;(w=m.current)==null||w.requestSubmit()},[]);return Zn("edit",p),Zn("delete",g),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:`/features/${t.id}/phases/${a.id}`,className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to phase"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,to:`/features/${t.id}`,kind:"Feature"},{label:a.title,to:`/features/${t.id}/phases/${a.id}`,kind:"Phase"},{label:l.title,kind:"Task"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number,phaseNum:a.number,taskNum:l.number}),children:d.jsx(Wr,{featureNum:t.number,phaseNum:a.number,taskNum:l.number})}),l.shortId?d.jsx(ii,{shortId:l.shortId}):null,d.jsx(Sa,{status:l.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:l.title}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit task"})}),d.jsx(_a,{ref:m,method:"post",action:`/features/${t.id}/phases/${a.id}/tasks/${l.id}/delete`,className:"inline-flex",onSubmit:w=>{window.confirm(`Delete task "${l.title}"?`)||w.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete task"})})]})]}),d.jsx(bm,{statusLog:l.statusLog??[],currentStatus:l.status,backbone:["planned","in-progress","done"],createdAt:l.createdAt,updatedAt:l.updatedAt,startedAt:l.startedAt,completedAt:l.completedAt}),d.jsxs(gn,{className:"grid gap-4",children:[l.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:l.description,className:"plan-description"})}):null,l.notes?d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",children:[d.jsxs("summary",{className:"flex items-center justify-between p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsx("div",{className:"flex items-center gap-2",children:d.jsx("span",{className:"text-sm",children:"Notes"})}),d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)]",children:d.jsx(Hn,{text:l.notes})})]}):d.jsx("p",{className:"mt-4 text-sm text-[var(--text-muted)]",children:"No notes"}),d.jsx(Sm,{statusLog:l.statusLog??[],currentStatus:l.status,backbone:["planned","in-progress","done"],startedAt:l.startedAt,completedAt:l.completedAt}),i.length>0?d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex items-center gap-2 cursor-pointer font-semibold text-[var(--text)] select-none",children:d.jsxs("span",{children:["Decisions (",i.length,")"]})}),d.jsx("div",{className:"mt-2 ml-4 space-y-2 border-l-2 border-[var(--border)] pl-4",children:i.map((w,S)=>d.jsx("div",{className:"text-sm text-[var(--text-muted)]",children:d.jsx(Hn,{text:w})},S))})]}):null,u.length>0?d.jsx(xm,{decisions:u}):null,d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-5",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Checklist items"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:o.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Subtasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:((x=l.subtasks)==null?void 0:x.length)??0})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Started"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:l.startedAt?bx(l.startedAt):"—"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Completed"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:l.completedAt?bx(l.completedAt):"—"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Phase"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:a.title})]})]}),d.jsxs("div",{className:"grid gap-3",children:[d.jsxs("div",{children:[d.jsxs("h3",{className:"text-sm font-bold text-[var(--text)]",children:["Steps (",o.length,")"]}),d.jsx("p",{className:"mt-1 text-xs text-[var(--text-muted)]",children:"Per-task checklist — agents tick steps via planner-task-checklist-toggle (C1/C2 or title), not by writing DONE in titles."})]}),o.length?d.jsx("div",{className:"grid gap-2",children:o.map(w=>d.jsx(XT,{featureId:t.id,phaseId:a.id,taskId:l.id,item:w},w.id))}):d.jsxs("p",{className:"text-sm text-[var(--text-muted)] italic",children:["No steps. Add implementation steps via ",d.jsx("code",{className:"text-[var(--text)]",children:"/planner task update"})," (checklist) so they can be ticked individually."]})]}),(b=l.subtasks)!=null&&b.length?d.jsxs("details",{className:"surface-card px-4 py-4",children:[d.jsx("summary",{className:"cursor-pointer list-none text-sm font-bold text-[var(--text)]",children:"Subtasks"}),d.jsx("div",{className:"mt-3 grid gap-2",children:l.subtasks.map(w=>d.jsxs("div",{className:"surface-card flex items-center justify-between gap-4 px-4 py-3",children:[d.jsxs("div",{children:[d.jsx("p",{className:"text-sm font-semibold text-[var(--text)]",children:w.title}),d.jsx("p",{className:"mt-1 text-xs text-[var(--text-muted)]",children:w.id})]}),d.jsx(Sa,{status:w.status})]},w.id))})]}):null]}),d.jsx(Mu,{})]})}const QT=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","[tabindex]:not([tabindex='-1'])"].join(",");function di({title:t,description:a,children:l}){const i=el(),u=v.useRef(null),o=v.useRef(null);return v.useEffect(()=>{var g;const f=u.current;if(!f)return;const m=document.activeElement;(g=o.current)==null||g.focus();const p=x=>{if(x.key==="Escape"){x.preventDefault(),i(-1);return}if(x.key!=="Tab")return;const b=Array.from(f.querySelectorAll(QT)).filter(A=>A.offsetParent!==null);if(b.length===0){x.preventDefault(),f.focus();return}const w=b[0],S=b[b.length-1],N=document.activeElement;x.shiftKey?(N===w||!f.contains(N))&&(x.preventDefault(),S.focus()):N===S&&(x.preventDefault(),w.focus())};return window.addEventListener("keydown",p),()=>{var x;window.removeEventListener("keydown",p),(x=m==null?void 0:m.focus)==null||x.call(m)}},[i]),d.jsxs("div",{className:"fixed inset-0 z-50 overflow-y-auto p-4 md:p-6",children:[d.jsx("button",{type:"button",className:"absolute inset-0 bg-black/50 backdrop-blur-sm",onClick:()=>i(-1),"aria-label":"Close modal",tabIndex:-1}),d.jsx("div",{className:"relative z-10 flex min-h-full items-start justify-center",children:d.jsxs("div",{ref:u,role:"dialog","aria-modal":"true","aria-label":t,tabIndex:-1,className:"surface-panel flex max-h-[calc(100vh-2rem)] w-full max-w-2xl flex-col overflow-hidden p-6 outline-none md:max-h-[calc(100vh-3rem)] md:p-8",children:[d.jsxs("div",{className:"mb-6 flex shrink-0 items-start justify-between gap-4",children:[d.jsxs("div",{children:[d.jsx("h3",{className:"text-xl font-black tracking-tight text-[var(--text)]",children:t}),a?d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:a}):null]}),d.jsx("button",{ref:o,type:"button",onClick:()=>i(-1),className:"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-[14px] border border-[var(--border-strong)] text-[var(--text-muted)] transition hover:text-[var(--text)]","aria-label":"Close modal",children:d.jsx(fN,{className:"h-4 w-4"})})]}),d.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto pr-1",children:l})]})})]})}function fi({className:t="",children:a,...l}){return d.jsx("div",{className:`sticky bottom-0 mt-2 flex justify-end gap-3 border-t border-[var(--border)] bg-[var(--surface)] px-1 pt-4 pb-1 backdrop-blur-xl ${t}`,...l,children:a})}function Nt({label:t,children:a}){return d.jsxs("label",{className:"grid gap-2",children:[d.jsx("span",{className:"text-sm font-semibold text-[var(--text-muted)]",children:t}),a]})}function zn(t){return d.jsx("textarea",{className:"field-control field-textarea",...t})}function KT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var u;return(u=l.current)==null?void 0:u.requestSubmit()},[]);return Zn("submit",i,{allowInEditable:!0}),d.jsx(di,{title:"Create feature",description:"Top-level container for phases and tasks.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Feature name",children:d.jsx(Pa,{name:"name",placeholder:"Products page implementation",required:!0})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",placeholder:"Short context for the feature"})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Creating…":"Create feature"})})]})})}function ZT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var f;return(f=l.current)==null?void 0:f.requestSubmit()},[]);Zn("submit",i,{allowInEditable:!0});const o=Ou("feature-detail").feature;return d.jsx(di,{title:"Edit feature",description:"Update metadata, planning notes and timeline.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Name",children:d.jsx(Pa,{name:"name",defaultValue:o.name,required:!0})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",defaultValue:o.description})}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[d.jsx(Nt,{label:"Start date",children:d.jsx(Pa,{type:"date",name:"startDate",defaultValue:o.startDate})}),d.jsx(Nt,{label:"End date",children:d.jsx(Pa,{type:"date",name:"endDate",defaultValue:o.endDate})})]}),d.jsx(Nt,{label:"Status",children:d.jsx(qu,{name:"status",defaultValue:o.status,children:Xc.map(f=>d.jsx("option",{value:f.value,children:f.label},f.value))})}),d.jsx(Nt,{label:"Priority",children:d.jsx(Pa,{type:"number",name:"priority",defaultValue:o.priority??0,min:0})}),d.jsx(Nt,{label:"Work done",children:d.jsx(zn,{name:"workDone",defaultValue:o.workDone})}),d.jsx(Nt,{label:"Work remaining",children:d.jsx(zn,{name:"workRemaining",defaultValue:o.workRemaining})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Saving…":"Save feature"})})]})})}function JT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var u;return(u=l.current)==null?void 0:u.requestSubmit()},[]);return Zn("submit",i,{allowInEditable:!0}),d.jsx(di,{title:"Create phase",description:"A phase belongs to the current feature.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Phase title",children:d.jsx(Pa,{name:"title",placeholder:"API creation",required:!0})}),d.jsx(Nt,{label:"Summary",children:d.jsx(zn,{name:"summary",placeholder:"Brief phase summary"})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",placeholder:"Initial implementation notes"})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Creating…":"Create phase"})})]})})}function Xs(t){return t.join(`
258
+ `+he.slice(ue-1);Be.current=xe,Z.current=null,ft.current&&(clearTimeout(ft.current),ft.current=null),q.current="input",zt.current.push({value:xe,cursorPos:ue}),ha(xe,!0),se.current&&oc(se.current);return}if((R.key==="Backspace"||R.key==="Delete")&&se.current&&!se.current.textContent){const ue=Be.current;if(!ue)return;const{start:he,end:xe}=xr(se.current);let Qe,at;if(he!==xe)Qe=ue.slice(0,he)+ue.slice(xe),at=he;else if(R.key==="Backspace"&&he>0)Qe=ue.slice(0,he-1)+ue.slice(he),at=he-1;else if(R.key==="Delete"&&he<ue.length)Qe=ue.slice(0,he)+ue.slice(he+1),at=he;else return;R.preventDefault(),Be.current=Qe,Z.current=null,ft.current&&(clearTimeout(ft.current),ft.current=null),q.current="input",zt.current.push({value:Qe,cursorPos:at}),Zr(se.current,at),ha(Qe,!0),se.current&&oc(se.current);return}if(yt.current=!1,G.showDropdown&&G.suggestions.length>0)switch(R.key){case"ArrowDown":R.preventDefault(),yt.current=!0,We(ue=>ue>=G.suggestions.length-1?0:ue+1);return;case"ArrowUp":R.preventDefault(),yt.current=!0,We(ue=>ue<=0?G.suggestions.length-1:ue-1);return;case"PageDown":{R.preventDefault(),yt.current=!0;const ue=za();We(he=>Math.min(he+ue,G.suggestions.length-1));return}case"PageUp":{R.preventDefault(),yt.current=!0;const ue=za();We(he=>Math.max(he-ue,0));return}case"Home":if(Lt&&G.selectedSuggestionIndex>=0){R.preventDefault(),yt.current=!0,We(0);return}break;case"End":if(Lt&&G.selectedSuggestionIndex>=0){R.preventDefault(),yt.current=!0,We(G.suggestions.length-1);return}break;case"Enter":if(G.selectedSuggestionIndex>=0){const ue=G.suggestions[G.selectedSuggestionIndex];if(ue.type==="loading"||ue.type==="error"){R.preventDefault(),tn(),l&&l(Be.current,G.ast,R);return}if(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!"){R.preventDefault(),tn();const he=Be.current,xe=G.cursorOffset;if(xe<=he.length&&he[xe]!==" "){const Qe=he.slice(0,xe),at=he.slice(xe),ze=Qe+" "+at;Ea(ze,xe+1,()=>{l&&l(ze,G.ast,R)})}else l&&l(he,G.ast,R);return}R.preventDefault(),Dr(ue,"Enter",void 0,R);return}R.preventDefault(),tn(),l&&l(Be.current,G.ast,R);return;case"Tab":if(U){R.preventDefault();const ue=G.selectedSuggestionIndex>=0?G.suggestions[G.selectedSuggestionIndex]:null,he=ue&&ue.type!=="loading"&&ue.type!=="error"&&!(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!")?ue:null,xe=U({suggestion:he,cursorContext:G.cursorContext||{type:"EMPTY",partial:""},query:Be.current});xe.accept&&he?Dr(he,"Tab",(Qe,at)=>{var ze;xe.submit&&l&&l(Qe,at,R),xe.blur&&((ze=se.current)==null||ze.blur())},R):(tn(),xe.submit&&l&&l(Be.current,G.ast,R),xe.blur&&((ve=se.current)==null||ve.blur()));return}if(G.selectedSuggestionIndex>=0){const ue=G.suggestions[G.selectedSuggestionIndex];if(ue.type==="hint"&&ue.text!=="#"&&ue.text!=="!"){R.preventDefault(),tn();const he=Be.current,xe=G.cursorOffset;if(xe<=he.length&&he[xe]!==" "){const Qe=he.slice(0,xe),at=he.slice(xe),ze=Qe+" "+at,Nn=xe+1;Ea(ze,Nn,kt=>{ma(kt,Nn)})}return}R.preventDefault(),Dr(ue,"Tab",void 0,R);return}break;case"Escape":R.preventDefault(),tn();return}if(R.key==="Tab"&&U){R.preventDefault();const ue=U({suggestion:null,cursorContext:G.cursorContext||{type:"EMPTY",partial:""},query:Be.current});ue.submit&&l&&l(Be.current,G.ast,R),ue.blur&&((Fe=se.current)==null||Fe.blur());return}if(G.showDatePicker&&R.key==="Escape"){R.preventDefault(),tn();return}if(R.key==="Enter"&&!G.showDropdown&&!G.showDatePicker){R.preventDefault(),l&&l(Be.current,G.ast,R);return}},[l,tn,Dr,Ea,Ar,Wt,ie,ce,ma,P,U,Yn,Vn,Le,Lt,za,qe]),hs=v.useCallback(R=>{if(yt.current){yt.current=!1;return}if(["ArrowLeft","ArrowRight","Home","End","PageUp","PageDown"].includes(R.key)){if(!se.current)return;const G=xr(se.current);Zt(G.start),_n(G.end),na(Tt.current.tokens,G.start,G.end)}},[na]),Vu=v.useCallback(()=>{fa(!0),K==null||K();const R=requestAnimationFrame(()=>{if(en.current.delete(R),se.current){const G=Tt.current.tokens,Se=G.length>0?jl(se.current):0;Zt(Se),_n(Se),na(G,Se)}});en.current.add(R)},[La,na,K]),ms=v.useCallback(()=>{var R;fa(!1),lt(!1),Kt(!1),$e([]),wn.current=!1,(R=Qt.current)==null||R.abort(),Pt.current&&(clearTimeout(Pt.current),Pt.current=null),Je.current&&(clearTimeout(Je.current),Je.current=null),Zt(-1),W==null||W()},[W]),Or=v.useRef(!1),Fu=v.useCallback(R=>{if(!se.current||R.detail!==2&&R.detail!==3)return;if(R.detail===3){if(!Tt.current.ast)return;const xe=document.caretRangeFromPoint(R.clientX,R.clientY);if(!xe)return;const Qe=Nu(se.current,xe.startContainer,xe.startOffset),at=fj(Tt.current.ast,Be.current,Qe);if(!at||at.start>=at.end)return;R.preventDefault(),Or.current=!0,Kr(se.current,at.start,at.end);return}R.preventDefault(),Or.current=!0;const G=document.caretRangeFromPoint(R.clientX,R.clientY);if(!G)return;const Se=Nu(se.current,G.startContainer,G.startOffset),ve=Be.current,Fe=xe=>!/[\s:()[\]{}"<>!,;|&=~^+\-*/\\]/.test(xe);let ue=Se;for(;ue>0&&Fe(ve[ue-1]);)ue--;let he=Se;for(;he<ve.length&&Fe(ve[he]);)he++;ue<he&&Kr(se.current,ue,he)},[]),aa=v.useCallback(R=>{Or.current&&(R.preventDefault(),Or.current=!1)},[]),Mr=v.useCallback(()=>{if(!se.current)return;const R=xr(se.current);if(Zt(R.start),_n(R.end),R.start!==R.end){const[G,Se]=ax(Tt.current.tokens,R.start,R.end);if(G!==Se){tn();return}}na(Tt.current.tokens,R.start,R.end)},[na,tn]),kr=v.useCallback(R=>{jt.current&&(clearTimeout(jt.current),jt.current=null),Kj(R),La()},[La]),Bl=v.useCallback(R=>{R.preventDefault();const G=tx(R.clipboardData.getData("text/plain"));if(ye){const Se=ye(G,R);Se!=null&&typeof(Se==null?void 0:Se.then)=="function"?Se.then(ve=>{ve!=null&&kr(ve)}).catch(()=>{}):Se!=null&&kr(Se)}else kr(G)},[ye,kr]),Kc=v.useCallback(R=>{q.current="navigation";const G=Tt.current,Se=C.current,ve=Se?Se.start:G.cursorOffset,Fe=Se?Se.end:G.cursorOffset,ue=Be.current.slice(0,ve),he=Be.current.slice(Fe);let xe="",Qe=he;ee&&R.length>0&&(he.length===0?xe=" ":/^[ \t\r\n]+$/.test(he)&&!he.startsWith("\\ ")&&(xe=" ",Qe=""));const at=ue+R+xe+Qe,ze=ue.length+R.length+xe.length;Ea(at,ze,Nn=>{se.current&&se.current.focus(),ma(Nn,ze)})},[Ea,ma,ee]),al=Bu(x),$l=$u(b),ql=Rj(al,A),_r={...jj(al,$l),...In?Tj($l):{}};dr&&(_r.whiteSpace="nowrap",_r.overflow="hidden",_r.textOverflow="ellipsis");const Iu=Dj(al,$l);return v.createElement("div",{ref:Wn,style:ql,className:Ma("ei-container",S,N==null?void 0:N.container)},v.createElement("div",{ref:Jn,contentEditable:!0,suppressContentEditableWarning:!0,className:Ma("ei-editor",N==null?void 0:N.editor),style:_r,onInput:La,onKeyDown:vi,onKeyUp:hs,onMouseDown:Fu,onMouseUp:aa,onFocus:Vu,onBlur:ms,onClick:Mr,onPaste:Bl,onCompositionStart:Wa,onCompositionEnd:gi,spellCheck:!1}),tl&&!In?v.createElement("div",{className:Ma("ei-placeholder",N==null?void 0:N.placeholder),style:Iu},w):null,v.createElement(Qj,{errors:Mn,editorRef:St,cursorOffset:wt,colors:x,styles:b,containerRef:Wn.current,classNames:N?{squiggly:N.squiggly,tooltip:N.tooltip}:void 0}),v.createElement(qj,{suggestions:Ke,selectedIndex:Ht,onSelect:R=>Dr(R,"Tab"),position:Fn,colors:x,styles:b,visible:ot,fixedWidth:Yu(),renderHistoryItem:le,renderSavedSearchItem:Ye,renderDropdownHeader:Ie,cursorContext:wa,listRefCallback:R=>{jr.current=R},renderType:An,classNames:N?{dropdown:N.dropdown,dropdownHeader:N.dropdownHeader,dropdownItem:N.dropdownItem}:void 0}),ct&&Fn?v.createElement(gT,{position:Fn,colors:al,onSelect:Kc,colorConfig:x,styleConfig:b,datePickerInit:Ul,fixedWidth:void 0,datePresets:Y,datePickerClassName:N==null?void 0:N.datePicker}):null)}const yT=["planned","in-progress","done","blocked","canceled","rejected","deferred","waiting"];function gx(t){var u;const a=window.getSelection();if(!a||a.rangeCount===0)return((u=t.textContent)==null?void 0:u.length)??0;const l=a.getRangeAt(0),i=l.cloneRange();return i.selectNodeContents(t),i.setEnd(l.endContainer,l.endOffset),i.toString().length}function xT(t){return a=>{if(!(a.ctrlKey&&!a.metaKey&&!a.altKey))return;const l=a.key.toLowerCase(),i=a.currentTarget,u=i.isContentEditable?i:i.querySelector("[contenteditable='true'], [contenteditable]")??i,o=t.current;if(l==="h"&&o){a.preventDefault();const m=o.getValue();let p=gx(u);(p<0||p>m.length)&&(p=m.length),p>0&&(o.setValue(m.slice(0,p-1)+m.slice(p)),o.setSelection(p-1,p-1));return}if(l==="u"&&o){a.preventDefault();const m=o.getValue();let p=gx(u);if((p<0||p>m.length)&&(p=m.length),p===0)return;let g=p;for(;g>0&&/\s/.test(m[g-1]??"");)g--;if(g===p)for(;g>0&&!/\s/.test(m[g-1]??"");)g--;g<p&&(o.setValue(m.slice(0,g)+m.slice(p)),o.setSelection(g,g));return}const f=l==="j"?"ArrowDown":l==="k"?"ArrowUp":null;f&&(a.preventDefault(),u.dispatchEvent(new KeyboardEvent("keydown",{key:f,bubbles:!0,cancelable:!0})))}}function Nh(t){return String(t>0?t:0).padStart(3,"0")}function bT({features:t,phases:a,query:l,onQuery:i}){const u=v.useRef(null),o=xT(u),f=[{name:"feature",label:"Feature",type:"number",description:"Feature number, e.g. 1 (F001)"},{name:"phase",label:"Phase",type:"number",description:"Phase number, e.g. 2 (P002)"},{name:"task",label:"Task",type:"number",description:"Task number, e.g. 10 (T010). Comma-list supported."},{name:"id",label:"Short ID",type:"string",description:"Global 5-char short id, e.g. UUXD1"},{name:"status",label:"Status",type:"string",description:"Task status"},{name:"feature-status",label:"Feature status",type:"string",description:"Status of the feature"},{name:"phase-status",label:"Phase status",type:"string",description:"Status of the phase"},{name:"title",label:"Title",type:"string",description:"Substring match on title"}],m=v.useMemo(()=>{const g=[...new Set(t.map(N=>N.number))].sort((N,A)=>N-A),x=[...new Set(a.map(N=>N.number))].sort((N,A)=>N-A),b=[...new Set(a.flatMap(N=>N.tasks.map(A=>A.number)))].sort((N,A)=>N-A),w=[...new Set([...t.map(N=>N.shortId),...a.flatMap(N=>[N.shortId,...N.tasks.map(A=>A.shortId)])].filter(Boolean))],S=[...new Set(a.flatMap(N=>N.tasks.map(A=>A.title)))];return{featureNums:g,phaseNums:x,taskNums:b,shortIds:w,titles:S}},[t,a]);async function p(g,x){const b=x.toLowerCase();return g==="feature"?m.featureNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`F${Nh(w)}`})):g==="phase"?m.phaseNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`P${Nh(w)}`})):g==="task"?m.taskNums.filter(w=>String(w).startsWith(x)).slice(0,20).map(w=>({text:String(w),label:`T${Nh(w)}`})):g==="id"?m.shortIds.filter(w=>w.toLowerCase().startsWith(b)).slice(0,20).map(w=>({text:w,label:w})):g==="status"||g==="feature-status"||g==="phase-status"?yT.filter(w=>w.startsWith(b)).map(w=>({text:w,label:w})):g==="title"?m.titles.filter(w=>w.toLowerCase().includes(b)).slice(0,20).map(w=>({text:w,label:w.length>44?w.slice(0,44)+"…":w})):[]}return d.jsx("div",{className:"search-bar",children:d.jsx(vT,{fields:f,value:l,onChange:g=>i(g),onSearch:g=>i(g),fetchSuggestions:p,onKeyDown:o,inputRef:g=>{u.current=g},placeholder:"Search Work Tree… e.g. feature:1 id:UUXD1 title:auth status:in-progress"})})}function ST(t,a){if(Object.keys(a).length===0)return t;const l=o=>{const f=a[o];return f?new Map(f.map((m,p)=>[m,p])):null},i=l("__features__");return(i?[...t].sort((o,f)=>(i.get(o.feature.id)??1/0)-(i.get(f.feature.id)??1/0)):t).map(o=>{const f=l(`phase-scope:${o.feature.id}`),m=f?[...o.allPhases].sort((p,g)=>(f.get(p.phase.id)??1/0)-(f.get(g.phase.id)??1/0)):o.allPhases;return{...o,allPhases:m.map(p=>{const g=l(`task-scope:${p.phase.id}`),x=g?[...p.allTasks].sort((b,w)=>(g.get(b.id)??1/0)-(g.get(w.id)??1/0)):p.allTasks;return{...p,allTasks:x}})}})}function wT({features:t,phases:a,activeTasks:l,projectStorageScope:i}){const u=ij({features:t,phases:a,projectStorageScope:i}),[o,f]=v.useState({});v.useEffect(()=>{f({})},[u.displayedWorkTree]);const m=v.useMemo(()=>ST(u.displayedWorkTree,o),[u.displayedWorkTree,o]),[p,g]=v.useState(!1),[x,b]=v.useState(null),[w,S]=v.useState(null),N=ee=>S(String(ee.active.id)),[A,j]=v.useState(0);v.useEffect(()=>{const ee=document.querySelector("header");if(!ee)return;const be=()=>j(ee.offsetHeight);be();const Ee=new ResizeObserver(be);return Ee.observe(ee),window.addEventListener("resize",be),()=>{Ee.disconnect(),window.removeEventListener("resize",be)}},[]),v.useEffect(()=>{const ee=window.setTimeout(()=>{const be=document.querySelector(".ap-search-sticky"),Ee=document.querySelector("header");if(!be||!Ee)return;const z=be.getBoundingClientRect();if(z.top<0){const H=z.top+window.scrollY-Ee.offsetHeight;window.scrollTo({top:Math.max(0,H),behavior:"smooth"})}},60);return()=>window.clearTimeout(ee)},[u.searchQuery,u.hideDone,u.hidePlanned,u.onlyActiveBranches]);const L=NR(ER(om,{activationConstraint:{distance:5}})),I=async ee=>{const{active:be,over:Ee}=ee;if(S(null),!Ee||be.id===Ee.id)return;const z=String(be.id),H=String(Ee.id),ie=m.map(ce=>ce.feature.id);if(ie.includes(z)&&ie.includes(H)){const ce=yu(ie,ie.indexOf(z),ie.indexOf(H)),pe=ce.indexOf(z),D=pe>0?ce[pe-1]??null:null,$=pe<ce.length-1?ce[pe+1]??null:null;f(ne=>({...ne,__features__:ce})),await ih("feature",z,D,$).catch(()=>{});return}for(const ce of m){const pe=ce.allPhases.map(D=>D.phase.id);if(pe.includes(z)&&pe.includes(H)){const D=yu(pe,pe.indexOf(z),pe.indexOf(H)),$=D.indexOf(z),ne=$>0?D[$-1]??null:null,de=$<D.length-1?D[$+1]??null:null;f(je=>({...je,[`phase-scope:${ce.feature.id}`]:D})),await ih("phase",z,ne,de).catch(()=>{});return}}for(const ce of m)for(const pe of ce.allPhases){const D=pe.allTasks.map($=>$.id);if(D.includes(z)&&D.includes(H)){const $=yu(D,D.indexOf(z),D.indexOf(H)),ne=$.indexOf(z),de=ne>0?$[ne-1]??null:null,je=ne<$.length-1?$[ne+1]??null:null;f(Ne=>({...Ne,[`task-scope:${pe.phase.id}`]:$})),await ih("task",z,de,je).catch(()=>{});return}}},Y=ee=>u.expandedPhaseIds.includes(ee),P=ee=>u.recentPhaseIds.includes(ee),K=ee=>u.recentTaskIds.includes(ee),[W,U]=Lc(),[T,oe]=v.useState(null),me=W.get("locate"),ye=me?parseInt(me.replace(/^T/i,""),10):null;v.useEffect(()=>{if(ye==null||Number.isNaN(ye))return;const ee=a.flatMap(H=>H.tasks.map(ie=>({t:ie,p:H}))).find(({t:H})=>H.number===ye);if(!ee){U(H=>(H.delete("locate"),H),{replace:!0});return}const{t:be,p:Ee}=ee;if(u.onlyActiveBranches&&u.setOnlyActiveBranches(!1),u.hideDone&&u.setHideDone(!1),u.searchQuery&&u.setSearchQuery(""),u.setTreeOpenMode("all"),Ee.featureId){const H=Ee.featureId;u.expandedFeatureIds.includes(H)||u.setExpandedFeatureIds(ie=>ie.includes(H)?ie:[...ie,H])}u.expandedPhaseIds.includes(Ee.id)||u.setExpandedPhaseIds(H=>H.includes(Ee.id)?H:[...H,Ee.id]);const z=document.getElementById(`task-row-${ye}`);if(z){const H=document.querySelector("header"),ie=document.querySelector(".ap-search-sticky"),ce=((H==null?void 0:H.offsetHeight)??0)+((ie==null?void 0:ie.offsetHeight)??0)+12,pe=z.getBoundingClientRect().top+window.scrollY-ce;window.scrollTo({top:Math.max(0,pe),behavior:"smooth"}),oe(be.id);const D=window.setTimeout(()=>oe(null),2500);return U($=>($.delete("locate"),$),{replace:!0}),()=>window.clearTimeout(D)}},[ye,a,u.expandedFeatureIds,u.expandedPhaseIds,u.onlyActiveBranches,u.hideDone,u.searchQuery,u.treeOpenMode]);const Re=()=>{if(!w)return null;for(const ee of m){if(ee.feature.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number}),d.jsx(Sa,{status:ee.feature.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:ee.feature.name})]});for(const be of ee.allPhases){if(be.phase.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number,phaseNum:be.phase.number}),d.jsx(Sa,{status:be.phase.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:be.phase.title})]});for(const Ee of be.allTasks)if(Ee.id===w)return d.jsxs("div",{className:"ap-drag-overlay surface-card min-w-0 max-w-md px-3 py-2",children:[d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(Wr,{featureNum:ee.feature.number,phaseNum:be.phase.number,taskNum:Ee.number}),d.jsx(Sa,{status:Ee.status})]}),d.jsx("div",{className:"mt-1 break-words font-mono text-sm font-semibold [overflow-wrap:anywhere]",children:Ee.title})]})}}return null};return d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"flex flex-col gap-3 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{children:[d.jsx("h2",{className:"text-lg font-bold text-[var(--text)]",children:"Work Tree"}),d.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:"Collapsible feature → phase → task tree. Click a feature or phase row to collapse/expand."})]}),d.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[d.jsx(bt,{type:"button",variant:"secondary",onClick:()=>u.expandAll(),children:"Expand all"}),d.jsx(bt,{type:"button",variant:"secondary",onClick:()=>u.setTreeOpenMode("none"),children:"Collapse all"})]})]}),d.jsxs("div",{className:"ap-search-sticky z-20",style:{top:A},children:[d.jsx(bT,{features:t,phases:a,query:u.searchQuery,onQuery:u.setSearchQuery}),u.searchActive?d.jsxs("p",{className:"text-xs text-[var(--text-muted)]",children:[u.matchedTaskIds.size," match",u.matchedTaskIds.size===1?"":"es"," — clear the box to reset."]}):null,d.jsx("div",{className:"grid grid-cols-1 gap-2 rounded-[14px] border border-[var(--border)] bg-[var(--surface-card)] px-3 py-2 sm:rounded-[18px] sm:px-4 sm:py-3",children:d.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 sm:gap-2",children:[d.jsx("button",{type:"button",onClick:()=>u.setHideDone(ee=>!ee),className:`status-chip transition ${u.hideDone?"status-done":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Hide done"}),d.jsx("button",{type:"button",onClick:()=>u.setHidePlanned(ee=>!ee),className:`status-chip transition ${u.hidePlanned?"status-planned":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Hide planned"}),d.jsx("button",{type:"button",onClick:()=>u.setOnlyActiveBranches(ee=>!ee),className:`status-chip transition ${u.onlyActiveBranches?"status-in-progress":"border border-[var(--border)] bg-transparent text-[var(--text-muted)]"}`,children:"Only active"}),d.jsx(bt,{type:"button",variant:"secondary",className:"!min-h-9 !px-3 !py-1 !text-xs sm:!min-h-11 sm:!px-4 sm:!py-2 sm:!text-sm",onClick:u.resetFilters,children:"Reset"}),d.jsx(bt,{type:"button",variant:"secondary",className:"!min-h-9 !px-3 !py-1 !text-xs sm:!min-h-11 sm:!px-4 sm:!py-2 sm:!text-sm",disabled:p,onClick:async()=>{g(!0),b(null);try{const ee=await jN(),be=ee.migrated,Ee=ee.integrity.duplicatePhaseIds.length,z=ee.integrity.danglingPhaseIds.length;b(`Repair done: renamed ${be.renamed}, repaired ${be.repaired} refs, inferred ${be.inferred}. Integrity: ${Ee} duplicate, ${z} dangling.`)}catch(ee){b(`Repair failed: ${ee instanceof Error?ee.message:String(ee)}`)}finally{g(!1)}},children:p?"Repairing…":"Repair"}),x?d.jsx("span",{className:"hidden text-xs text-[var(--text-muted)] sm:inline sm:truncate",children:x}):null]})})]}),d.jsx("div",{className:"grid gap-3",children:m.length>0?d.jsxs(N2,{sensors:L,collisionDetection:AR,onDragStart:N,onDragEnd:I,children:[d.jsx(fm,{items:m.map(ee=>ee.feature.id),strategy:dm,children:m.map(ee=>d.jsx(hm,{id:ee.feature.id,children:d.jsx(oj,{entry:ee,expanded:u.expandedFeatureIds.includes(ee.feature.id),recentlyChanged:u.recentFeatureIds.includes(ee.feature.id),onToggle:()=>u.toggleExpandedFeature(ee.feature.id),isPhaseExpanded:Y,onTogglePhase:u.toggleExpandedPhase,isPhaseRecentlyChanged:P,isTaskRecentlyChanged:K,highlightedTaskIds:(()=>{const be=u.searchActive?u.matchedTaskIds:void 0;if(!T)return be;const Ee=new Set(be??[]);return Ee.add(T),Ee})()})},ee.feature.id))}),d.jsx(V2,{dropAnimation:{duration:150,easing:"ease"},children:Re()})]}):l.length>0?l.map(ee=>{const be=ee.featureId?`/features/${ee.featureId}/phases/${ee.phaseId}/tasks/${ee.id}`:"/features";return d.jsxs(dt,{to:be,className:"surface-card grid gap-1 px-4 py-3 transition hover:border-[var(--accent)] hover:bg-[var(--accent-soft)]",children:[d.jsxs("div",{className:"flex items-center justify-between gap-2",children:[d.jsxs("span",{className:"inline-flex min-w-0 items-center gap-2 truncate text-sm font-semibold text-[var(--text)]",children:[ee.status==="in-progress"?d.jsx("span",{"aria-hidden":"true",className:"ap-progress-dot"}):null,d.jsxs("span",{className:"truncate",children:["T",sR(ee.number)," — ",ee.title]})]}),d.jsx(Sa,{status:ee.status})]}),d.jsx("div",{className:"text-[10px] uppercase tracking-wider text-[var(--text-muted)]",children:ee.phaseId})]},ee.id)}):d.jsx("p",{className:"py-4 text-center text-sm text-[var(--text-muted)]",children:"No work items match the current filters."})})]})}function ET(){const{features:t,phases:a,activeTasks:l}=cs(),{project:i}=Ou("root"),u=el(),o=()=>u("/project/edit");Zn("edit",o);const f=i.projectRoot||i.planRoot||i.name||"default";return d.jsxs("div",{className:"grid grid-cols-1 gap-8",children:[d.jsx(gn,{className:"grid grid-cols-1 gap-4",children:d.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{children:[d.jsx("h2",{className:"text-lg font-bold text-[var(--text)]",children:"Project Goal"}),i.goal?d.jsx(Hn,{text:i.goal,className:"mt-2 max-w-4xl"}):d.jsx("p",{className:"mt-2 max-w-4xl text-sm text-[var(--text-muted)]",children:"Add a project goal to define the main objective."})]}),d.jsxs(bt,{type:"button",shortcut:"edit",onClick:o,className:"self-start",children:[d.jsx(us,{className:"h-4 w-4"}),"Edit project"]})]})}),d.jsx(JN,{project:i}),d.jsx(uR,{features:t,phases:a}),d.jsx(wT,{features:t,phases:a,activeTasks:l,projectStorageScope:f}),d.jsx(eR,{features:t,phases:a}),d.jsx(nR,{features:t,phases:a})]})}async function NT(){const[t,a]=await Promise.all([hb(),tm()]);return{features:t,phases:a}}function Ru(){return{active:0,planned:0,done:0,blocked:0,canceled:0}}function Tc(t){const a=[];return t.active&&a.push(`${t.active} active`),t.planned&&a.push(`${t.planned} planned`),t.done&&a.push(`${t.done} done`),t.blocked&&a.push(`${t.blocked} blocked`),t.canceled&&a.push(`${t.canceled} canceled`),a.join(" · ")}function RT(t){const a=Ru();for(const l of t){if(l.status==="in-progress"||l.status==="discovery"){a.active+=1;continue}if(l.status==="planned"||l.status==="draft"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function Wb(t){const a=Ru();for(const l of t){if(l.status==="in-progress"){a.active+=1;continue}if(l.status==="planned"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function jT(t){const a=Ru();for(const l of t){if(l.status==="in-progress"){a.active+=1;continue}if(l.status==="planned"){a.planned+=1;continue}if(l.status==="done"){a.done+=1;continue}if(l.status==="blocked"){a.blocked+=1;continue}l.status==="canceled"&&(a.canceled+=1)}return a}function TT({feature:t,phasesCount:a,tasksCount:l,phaseSummary:i,taskSummary:u,activity:o}){var A;const f=is(),m=is(),g=((A=f.formData)==null?void 0:A.get("status"))??t.status,x=f.state!=="idle",b=m.state!=="idle",w=Tc(i),S=Tc(u),N=t.description||(o?`${o.doneTasks}/${l} done · ${o.remainingTasks} left${o.blockedTasks?` · ${o.blockedTasks} blocked`:""}`:"");return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 xl:grid-cols-[minmax(0,1fr)_minmax(0,132px)_minmax(0,152px)_124px_44px_44px] xl:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 xl:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"feature",number:t.number}),d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:g})})]}),d.jsx(dt,{to:`/features/${t.id}`,className:"entity-link--feature min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:t.name})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end xl:hidden",children:[d.jsx(dt,{to:`/features/${t.id}/edit`,"aria-label":`Edit feature ${t.name}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(m.Form,{method:"post",action:`/features/${t.id}/delete`,onSubmit:j=>{window.confirm(`Delete feature “${t.name}”? This cannot be undone.`)||j.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:b||x,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete feature ${t.name}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[a," phases"]}),w?d.jsx("div",{className:"mt-0.5 break-words",children:w}):null]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l," tasks"]}),S?d.jsx("div",{className:"mt-0.5 break-words",children:S}):null]}),d.jsx(f.Form,{method:"post",action:`/features/${t.id}/status`,className:"w-full xl:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:g,disabled:x||b,"aria-busy":x,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:j=>f.submit(j.currentTarget.form),children:Xc.map(j=>d.jsx("option",{value:j.value,children:j.label},j.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t.id}/edit`,"aria-label":`Edit feature ${t.name}`,className:"hidden xl:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(m.Form,{method:"post",action:`/features/${t.id}/delete`,className:"hidden xl:block",onSubmit:j=>{window.confirm(`Delete feature “${t.name}”? This cannot be undone.`)||j.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:b||x,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete feature ${t.name}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),N?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:N}):null]})}const DT={feature:{label:"Feature",Icon:bc},phase:{label:"Phase",Icon:YE},task:{label:"Task",Icon:em}};function CT({kind:t,label:a}){const{Icon:l,label:i}=DT[t];return d.jsxs("span",{className:`entity-badge entity-badge--${t}`,children:[d.jsx(l,{className:"h-3.5 w-3.5"}),d.jsx("span",{children:a??i})]})}function Pa({className:t="",...a}){return d.jsx("input",{className:`field-control ${t}`,...a})}function qu({className:t="",...a}){return d.jsx("select",{className:`field-control ${t}`,...a})}function gm({query:t,status:a,statusOptions:l,placeholder:i,clearTo:u,resultsLabel:o}){const f=Wh();return d.jsxs(_a,{method:"get",className:"surface-card grid gap-3 p-3 md:grid-cols-[minmax(0,1fr)_200px_auto_auto] md:items-end sm:p-4",children:[d.jsxs("div",{children:[d.jsx("label",{htmlFor:"list-filter-query",className:"mb-1 block text-xs font-semibold uppercase tracking-[0.18em] text-[var(--text-subtle)]",children:"Name"}),d.jsx(Pa,{id:"list-filter-query",name:"q",defaultValue:t,placeholder:i,className:"min-h-9 py-2 sm:min-h-11 sm:py-2.5",onChange:m=>f(m.currentTarget.form)})]}),d.jsxs("div",{children:[d.jsx("label",{htmlFor:"list-filter-status",className:"mb-1 block text-xs font-semibold uppercase tracking-[0.18em] text-[var(--text-subtle)]",children:"Status"}),d.jsxs("div",{className:"relative",children:[d.jsxs(qu,{id:"list-filter-status",name:"status",defaultValue:a,className:"min-h-9 appearance-none py-2 sm:min-h-11 sm:py-2.5 pr-8",children:[d.jsx("option",{value:"",children:"All statuses"}),l.map(m=>d.jsx("option",{value:m.value,children:m.label},m.value))]}),d.jsx(_l,{className:"pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--text-muted)]"})]})]}),d.jsx(bt,{type:"submit",variant:"secondary",children:"Apply filters"}),d.jsx(dt,{to:u,className:"inline-flex min-h-9 items-center justify-center rounded-[12px] px-3 text-sm font-semibold text-[var(--text-muted)] transition hover:bg-[var(--accent-soft)] hover:text-[var(--text)] sm:min-h-11 sm:rounded-[14px]",children:"Clear"}),d.jsx("div",{className:"text-sm text-[var(--text-muted)] md:col-span-4",children:o})]})}function vm(t,a){const l=t.trim().toLowerCase();return l?a.some(i=>i==null?void 0:i.toLowerCase().includes(l)):!0}function AT(t){const a=new Map,l=new Map,i=new Map,u=new Map,o=new Map;for(const f of t)f.featureId&&o.set(f.featureId,[...o.get(f.featureId)??[],f]);for(const[f,m]of o)a.set(f,m.length),l.set(f,m.reduce((p,g)=>p+g.tasks.length,0)),i.set(f,RT(m)),u.set(f,Wb(m.flatMap(p=>p.tasks)));return{phasesByFeature:a,tasksByFeature:l,phaseSummaryByFeature:i,taskSummaryByFeature:u}}function OT(){var w,S;const{features:t,phases:a}=cs(),{phasesByFeature:l,tasksByFeature:i,phaseSummaryByFeature:u,taskSummaryByFeature:o}=AT(a),f=el(),[m]=Lc(),p=((w=m.get("q"))==null?void 0:w.trim())??"",g=((S=m.get("status"))==null?void 0:S.trim())??"",x=v.useCallback(()=>f("new"),[f]);Zn("create",x);const b=v.useMemo(()=>t.filter(N=>(!g||N.status===g)&&vm(p,[N.name,N.id,N.description])),[t,p,g]);return d.jsxs(d.Fragment,{children:[d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(gn,{className:"flex flex-col gap-4 md:flex-row md:items-center md:justify-between",children:[d.jsxs("div",{children:[d.jsx(CT,{kind:"feature",label:"Features"}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter by name or status, then inspect child phases and tasks directly from the rows."})]}),d.jsx(dt,{to:"new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create feature"})})]}),d.jsx(gm,{query:p,status:g,statusOptions:Xc,placeholder:"Search feature name, id, or description",clearTo:"/features",resultsLabel:b.length===t.length?`${t.length} features`:`${b.length} of ${t.length} features`}),d.jsx("div",{className:"grid gap-3",children:t.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No features yet. ",d.jsx(dt,{to:"/features/new",className:"font-semibold text-[var(--accent)] hover:underline",children:"Create your first feature"})]}):b.length>0?b.map(N=>d.jsx(TT,{feature:N,phasesCount:l.get(N.id)??0,tasksCount:i.get(N.id)??0,phaseSummary:u.get(N.id)??Ru(),taskSummary:o.get(N.id)??Ru()},N.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No features match the current filters."})})]}),d.jsx(Mu,{})]})}async function MT({params:t}){const a=t.featureId;if(!a)throw new Response("featureId required",{status:400});const[l,i]=await Promise.all([ku(a),tm(a)]);return{feature:l,phases:i}}function kT({featureId:t,feature:a,phase:l}){var x;const i=is(),u=is(),f=((x=i.formData)==null?void 0:x.get("status"))??l.status,m=i.state!=="idle",p=u.state!=="idle",g=Tc(Wb(l.tasks));return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 lg:grid-cols-[minmax(0,1fr)_minmax(0,150px)_124px_44px_44px] lg:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"phase",number:l.number}),d.jsx(ai,{type:"phase",featureNum:a.number}),l.handoff?d.jsx(am,{phaseId:l.id,updatedAt:l.handoffUpdatedAt}):null,d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:f})})]}),d.jsx(dt,{to:`/features/${t}/phases/${l.id}`,className:"entity-link--phase min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:l.title})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end lg:hidden",children:[d.jsx(dt,{to:`/features/${t}/phases/${l.id}/edit`,"aria-label":`Edit phase ${l.title}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${l.id}/delete`,onSubmit:b=>{window.confirm(`Delete phase “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete phase ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l.tasks.length," tasks"]}),g?d.jsx("div",{className:"mt-0.5 break-words",children:g}):null]}),d.jsx(i.Form,{method:"post",action:`/features/${t}/phases/${l.id}/status`,className:"w-full lg:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:f,disabled:m||p,"aria-busy":m,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:b=>i.submit(b.currentTarget.form),children:Pc.map(b=>d.jsx("option",{value:b.value,children:b.label},b.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t}/phases/${l.id}/edit`,"aria-label":`Edit phase ${l.title}`,className:"hidden lg:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${l.id}/delete`,className:"hidden lg:block",onSubmit:b=>{window.confirm(`Delete phase “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete phase ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),l.summary?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:l.summary}):null]})}function ym({items:t,className:a="",stacked:l=!1}){return l?d.jsx("nav",{"aria-label":"Breadcrumb",className:`grid gap-1 text-sm ${a}`,children:t.map((i,u)=>{const o=u===t.length-1,f=i.to&&!o?d.jsx(dt,{to:i.to,className:"font-semibold text-[var(--accent)] hover:underline break-words min-w-0",children:i.label}):d.jsx("span",{className:`break-words min-w-0 ${o?"text-[var(--text)] font-semibold":"text-[var(--text-muted)]"}`,children:i.label});return d.jsxs("div",{className:"flex items-baseline gap-2 min-w-0",children:[i.kind?d.jsxs("span",{className:"shrink-0 text-[var(--text-subtle)] font-medium",children:[i.kind,":"]}):null,d.jsx("span",{className:"min-w-0",children:f})]},`${i.label}-${u}`)})}):d.jsx("nav",{"aria-label":"Breadcrumb",className:`flex flex-wrap items-center gap-2 text-sm ${a}`,children:t.map((i,u)=>{const o=u===t.length-1,f=i.to&&!o?d.jsx(dt,{to:i.to,className:"font-semibold text-[var(--accent)] hover:underline",children:i.label}):d.jsx("span",{className:o?"text-[var(--text)]":"text-[var(--text-muted)]",children:i.label});return d.jsxs("span",{className:"inline-flex min-w-0 items-center gap-2",children:[u>0?d.jsx("span",{className:"text-[var(--text-subtle)]",children:"/"}):null,d.jsx("span",{className:"min-w-0 break-words",children:f})]},`${i.label}-${u}`)})})}function bn({className:t="",children:a,...l}){return d.jsx("div",{className:`surface-card p-4 ${t}`,...l,children:a})}function Dc({title:t,actions:a,defaultOpen:l=!0,count:i,children:u}){return d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",open:l,children:[d.jsxs("summary",{className:"flex items-center justify-between gap-2 p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsxs("span",{className:"flex items-center gap-2 text-sm",children:[t,i!==void 0?d.jsxs("span",{className:"text-[var(--text-subtle)]",children:["(",i,")"]}):null]}),d.jsxs("span",{className:"flex items-center gap-2",children:[a,d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)]",children:u})]})}function xm({decisions:t}){return t.length===0?null:d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex cursor-pointer select-none items-center gap-2 font-semibold text-[var(--text)]",children:d.jsxs("span",{children:["Accepted decisions (",t.length,")"]})}),d.jsx("div",{className:"mt-2 grid gap-3",children:t.map(a=>d.jsxs("div",{className:"surface-card px-4 py-3",children:[d.jsx("p",{className:"text-sm font-semibold text-[var(--text)]",children:a.title}),a.decision?d.jsxs("div",{className:"mt-2 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Decision:"}),d.jsx(Hn,{text:a.decision,className:"mt-1"})]}):null,a.rationale?d.jsxs("div",{className:"mt-1 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Rationale:"}),d.jsx(Hn,{text:a.rationale,className:"mt-1"})]}):null,a.implementationNotes?d.jsxs("div",{className:"mt-1 text-sm text-[var(--text-muted)]",children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Implementation:"}),d.jsx(Hn,{text:a.implementationNotes,className:"mt-1"})]}):null]},a.id))})]})}const _T={draft:CE,discovery:lN,planned:em,"in-progress":LE,done:ob,blocked:eN,waiting:kE,deferred:oN,canceled:SE,rejected:OE};function Rh(t){return t.split(/[-\s]+/).filter(Boolean).map(a=>a==="and"?"and":a.charAt(0).toUpperCase()+a.slice(1)).join(" ")}function vx(t){if(!t)return"";try{return new Intl.DateTimeFormat(void 0,{dateStyle:"short",timeStyle:"short"}).format(new Date(t))}catch{return t}}const LT=new Set(["canceled","rejected"]);function bm({statusLog:t,currentStatus:a,backbone:l,createdAt:i,updatedAt:u,startedAt:o,completedAt:f}){const m=[];if(t.length===0){const S=l.indexOf(a);if(S>=0)for(let N=0;N<=S;N++)m.push(l[N]);else m.push(a)}else{const S=t[0];S&&m.push(S.fromStatus);for(const N of t)m[m.length-1]!==N.toStatus&&m.push(N.toStatus)}m[m.length-1]!==a&&m.push(a);const p=new Set(m),g=a==="done"||LT.has(a),x=[...m];if(!g){const S=l.indexOf(a);if(S>=0&&S+1<l.length){const N=l[S+1];p.has(N)||x.push(N)}}const b=S=>p.has(S)?S===a&&!g?"current":"completed":"pending",w=S=>{var A,j;if(t.length>0){if(S===((A=t[0])==null?void 0:A.fromStatus))return((j=t[0])==null?void 0:j.date)??"";for(const L of t)if(L.toStatus===S)return L.date;return""}const N=l[0];return S===N?i??"":S==="in-progress"?o??u??"":S==="done"?f??u??"":""};return d.jsx("ol",{className:"status-stepper",role:"list","aria-label":"Status progress",children:x.map((S,N)=>{const A=b(S),j=_T[S]??UE,L=p.has(S),I=w(S),Y=I?`${Rh(S)} — ${vx(I)}`:Rh(S),P=N===0?null:L?"traveled":"pending";return d.jsxs("li",{className:`status-step status-step--${A}`,role:"listitem","aria-current":A==="current"?"step":void 0,style:{"--step-color":`var(--color-status-${S})`},children:[P?d.jsx("span",{className:`status-connector status-connector--${P}`,"aria-hidden":"true"}):null,d.jsx("span",{className:"status-node",title:Y,children:d.jsx(j,{className:"status-node-icon"})}),d.jsx("span",{className:"status-step-label",children:Rh(S)}),I?d.jsx("span",{className:"status-step-date",children:vx(I)}):null]},`${S}-${N}`)})})}function yx(t){return t.split(/[-\s]+/).filter(Boolean).map(a=>a==="and"?"and":a.charAt(0).toUpperCase()+a.slice(1)).join(" ")}function zT(t){if(!t)return"";try{return new Intl.DateTimeFormat(void 0,{dateStyle:"short",timeStyle:"short"}).format(new Date(t))}catch{return t}}function UT(t,a,l,i,u){if(t.length>0)return t.map(m=>({date:m.date,fromStatus:m.fromStatus,toStatus:m.toStatus,inferred:!1}));const o=l.indexOf(a);if(o<0)return[];const f=[];for(let m=1;m<=o;m++){const p=l[m-1],g=l[m],x=g==="in-progress"?i??"":g==="done"?u??"":"";f.push({date:x,fromStatus:p,toStatus:g,inferred:!0})}return f}function Sm({statusLog:t,currentStatus:a,backbone:l,startedAt:i,completedAt:u}){const o=UT(t??[],a??"",l??[],i,u),f=o.length>0;return d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",open:f,children:[d.jsxs("summary",{className:"flex items-center justify-between p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsxs("span",{className:"text-sm",children:["Status history (",o.length,")"]}),d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)] grid gap-2.5",children:o.length===0?d.jsx("p",{className:"text-sm text-[var(--text-muted)] italic",children:"No status changes recorded."}):o.map((m,p)=>d.jsxs("div",{className:"text-sm flex flex-wrap items-center gap-2",children:[d.jsx("span",{className:"text-xs font-mono text-[var(--text-subtle)]",children:zT(m.date)}),d.jsx("span",{className:"font-semibold text-[var(--text-muted)]",children:yx(m.fromStatus)}),d.jsx("span",{className:"text-[var(--text-subtle)]",children:"→"}),d.jsx("span",{className:"font-semibold text-[var(--text)]",children:yx(m.toStatus)})]},p))})]})}function HT(t){return t.reduce((a,l)=>a+l.tasks.length,0)}function BT(t){let a=0,l=0,i=0,u=0;for(const o of t)for(const f of o.tasks)f.status==="in-progress"&&(a+=1),f.status==="done"&&(l+=1),f.status==="blocked"&&(i+=1),["done","canceled"].includes(f.status)||(u+=1);return{inProgress:a,done:l,blocked:i,remaining:u}}function $T(t){return t.find(a=>["in-progress","discovery","planned","draft"].includes(a.status))}function qT(){var A,j;const{feature:t,phases:a}=cs(),l=t.acceptedDecisions??[],i=HT(a),u=BT(a),o=$T(a),[f]=Lc(),m=((A=f.get("q"))==null?void 0:A.trim())??"",p=((j=f.get("status"))==null?void 0:j.trim())??"",g=v.useMemo(()=>a.filter(L=>(!p||L.status===p)&&vm(m,[L.title,L.id,L.summary,L.description])),[a,m,p]),x=el(),b=v.useRef(null),w=v.useCallback(()=>x("edit"),[x]),S=v.useCallback(()=>x("phases/new"),[x]),N=v.useCallback(()=>{var L;(L=b.current)==null||L.requestSubmit()},[]);return Zn("edit",w),Zn("create",S),Zn("delete",N),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:"/features",className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to features"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,kind:"Feature"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number}),children:d.jsx(Wr,{featureNum:t.number})}),t.shortId?d.jsx(ii,{shortId:t.shortId}):null,d.jsx(Sa,{status:t.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:t.name}),t.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:t.description,className:"plan-description max-w-4xl"})}):null,d.jsx("div",{className:"mt-4",children:d.jsx(bm,{statusLog:t.statusLog??[],currentStatus:t.status,backbone:["planned","in-progress","done"],createdAt:t.createdAt,updatedAt:t.updatedAt})}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit feature"})}),d.jsx(_a,{ref:b,method:"post",action:`/features/${t.id}/delete`,className:"inline-flex",onSubmit:L=>{window.confirm(`Delete feature "${t.name}"?`)||L.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete feature"})})]})]}),d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Current phase"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:(o==null?void 0:o.title)||"No active phase"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Phases"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:a.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Tasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:i})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Window"}),d.jsxs("p",{className:"mt-2 text-sm font-semibold text-[var(--text)]",children:[t.startDate||"Not set"," → ",t.endDate||"Not set"]})]})]}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"In progress"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.inProgress})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Remaining"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.remaining})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Done"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.done})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Blocked"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.blocked})]})]}),t.workDone||t.workRemaining?d.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[t.workDone?d.jsxs("div",{children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Work done:"}),d.jsx(Hn,{text:t.workDone,className:"mt-2"})]}):null,t.workRemaining?d.jsxs("div",{children:[d.jsx("span",{className:"font-semibold text-[var(--text)]",children:"Work remaining:"}),d.jsx(Hn,{text:t.workRemaining,className:"mt-2"})]}):null]}):null,l.length>0?d.jsx(xm,{decisions:l}):null,d.jsx(Sm,{statusLog:t.statusLog??[],currentStatus:t.status,backbone:["planned","in-progress","done"]})]}),d.jsxs(gn,{className:"grid gap-5",children:[d.jsxs("div",{className:"flex flex-col gap-4 md:flex-row md:items-start md:justify-between",children:[d.jsxs("div",{className:"mt-2 flex items-center gap-2",children:[d.jsx(Ll,{type:"phase",number:0}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter this feature's phases by name or status."})]}),d.jsx(dt,{to:"phases/new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create phase"})})]}),d.jsx(gm,{query:m,status:p,statusOptions:Pc,placeholder:"Search phase title, id, or summary",clearTo:`/features/${t.id}`,resultsLabel:g.length===a.length?`${a.length} phases`:`${g.length} of ${a.length} phases`}),d.jsx("div",{className:"grid gap-3",children:a.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No phases yet. ",d.jsx(dt,{to:`/features/${t.id}/phases/new`,className:"font-semibold text-[var(--accent)] hover:underline",children:"Add a phase"})]}):g.length>0?g.map(L=>d.jsx(kT,{featureId:t.id,feature:t,phase:L},L.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No phases match the current filters."})})]}),d.jsx(Mu,{})]})}async function YT({params:t}){const{featureId:a,phaseId:l}=t;if(!a||!l)throw new Response("featureId and phaseId required",{status:400});const[i,u]=await Promise.all([ku(a),$c(l)]);return{feature:i,phase:u}}function xx(t){try{return new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(new Date(t))}catch{return t}}function VT({featureId:t,phaseId:a,task:l}){var x;const i=is(),u=is(),f=((x=i.formData)==null?void 0:x.get("status"))??l.status,m=i.state!=="idle",p=u.state!=="idle",g=Tc(jT(l.subtasks));return d.jsxs("div",{className:"surface-card px-4 py-2",children:[d.jsxs("div",{className:"grid gap-2 lg:grid-cols-[minmax(0,1fr)_minmax(0,168px)_124px_44px_44px] lg:items-center",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:contents",children:[d.jsxs("div",{className:"flex min-w-0 flex-col items-start gap-1 lg:flex-row lg:items-center lg:gap-2",children:[d.jsxs("div",{className:"flex items-center gap-2",children:[d.jsx(Ll,{type:"task",number:l.number}),d.jsx("span",{className:"shrink-0",children:d.jsx(Sa,{status:f})})]}),d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}`,className:"entity-link--task min-w-0 w-full break-words text-sm font-semibold underline-offset-4 hover:underline lg:w-auto lg:truncate",children:l.title})]}),d.jsxs("div",{className:"flex items-center gap-2 self-end lg:hidden",children:[d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}/edit`,"aria-label":`Edit task ${l.title}`,children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/delete`,onSubmit:b=>{window.confirm(`Delete task “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete task ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]})]}),d.jsxs("div",{className:"text-[11px] text-[var(--text-muted)]",children:[d.jsxs("div",{className:"font-semibold text-[var(--text)]",children:[l.subtasks.length," subtasks · ",l.checklist.length," checklist"]}),g?d.jsx("div",{className:"mt-0.5 break-words",children:g}):d.jsx("div",{className:"mt-0.5 break-words",children:"No subtask statuses yet"})]}),d.jsx(i.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/status`,className:"w-full lg:w-auto",children:d.jsxs("div",{className:"relative",children:[d.jsx("select",{name:"status",value:f,disabled:m||p,"aria-busy":m,className:"field-control min-h-8 appearance-none py-1 pr-8 text-[11px]",onChange:b=>i.submit(b.currentTarget.form),children:Hu.map(b=>d.jsx("option",{value:b.value,children:b.label},b.value))}),d.jsx(_l,{className:"pointer-events-none absolute right-2.5 top-1/2 h-3 w-3 -translate-y-1/2 text-[var(--text-muted)]"})]})}),d.jsx(dt,{to:`/features/${t}/phases/${a}/tasks/${l.id}/edit`,"aria-label":`Edit task ${l.title}`,className:"hidden lg:block",children:d.jsx(bt,{type:"button",variant:"secondary",className:"min-h-8 w-8 rounded-[10px] px-0 text-[var(--text-muted)] hover:text-[var(--text)]",children:d.jsx(us,{className:"h-3.5 w-3.5"})})}),d.jsx(u.Form,{method:"post",action:`/features/${t}/phases/${a}/tasks/${l.id}/delete`,className:"hidden lg:block",onSubmit:b=>{window.confirm(`Delete task “${l.title}”? This cannot be undone.`)||b.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",disabled:p||m,className:"min-h-8 w-8 rounded-[10px] px-0","aria-label":`Delete task ${l.title}`,children:d.jsx(ni,{className:"h-4 w-4"})})})]}),d.jsxs("div",{className:"mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-[var(--text-subtle)]",children:[l.startedAt?d.jsxs("span",{children:["Started ",xx(l.startedAt)]}):null,l.completedAt?d.jsxs("span",{children:["Completed ",xx(l.completedAt)]}):null]}),l.description?d.jsx("div",{className:"mt-1 min-w-0 break-words line-clamp-2 text-[11px] text-[var(--text-muted)]",children:l.description}):null]})}function FT(t){let a=0,l=0,i=0,u=0;for(const o of t.tasks)o.status==="in-progress"&&(a+=1),o.status==="done"&&(l+=1),o.status==="blocked"&&(i+=1),["done","canceled"].includes(o.status)||(u+=1);return{inProgress:a,done:l,blocked:i,remaining:u}}function IT(){var Y,P;const{feature:t,phase:a}=cs(),l=a.decisions??[],i=a.acceptedDecisions??[],u=FT(a),[o]=Lc(),f=((Y=o.get("q"))==null?void 0:Y.trim())??"",m=((P=o.get("status"))==null?void 0:P.trim())??"",p=v.useMemo(()=>a.tasks.filter(K=>(!m||K.status===m)&&vm(f,[K.title,K.id,K.description,K.shortName])),[a.tasks,f,m]),g=el(),x=v.useRef(null),[b,w]=v.useState(a.handoff??""),[S,N]=v.useState(!1),A=v.useCallback(()=>g("edit"),[g]),j=v.useCallback(()=>g("tasks/new"),[g]),L=v.useCallback(()=>{var K;(K=x.current)==null||K.requestSubmit()},[]),I=v.useCallback(async()=>{if(window.confirm("Clear this phase's handoff?")){N(!0);try{await NN(a.id),w("")}catch{}finally{N(!1)}}},[a.id]);return Zn("edit",A),Zn("create",j),Zn("delete",L),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:`/features/${t.id}`,className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to feature"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,to:`/features/${t.id}`,kind:"Feature"},{label:a.title,kind:"Phase"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number,phaseNum:a.number}),children:d.jsx(Wr,{featureNum:t.number,phaseNum:a.number})}),a.shortId?d.jsx(ii,{shortId:a.shortId}):null,b?d.jsx(am,{phaseId:a.id,updatedAt:a.handoffUpdatedAt}):null,d.jsx(Sa,{status:a.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:a.title}),a.summary?d.jsx(Hn,{text:a.summary,className:"mt-3 max-w-4xl"}):null,d.jsx(bm,{statusLog:a.statusLog??[],currentStatus:a.status,backbone:["draft","discovery","planned","in-progress","done"],createdAt:a.createdAt,updatedAt:a.updatedAt}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit phase"})}),d.jsx(dt,{to:"tasks/new",children:d.jsx(bt,{type:"button",variant:"primary",shortcut:"create",children:"Create task"})}),d.jsx(_a,{ref:x,method:"post",action:`/features/${t.id}/phases/${a.id}/delete`,className:"inline-flex",onSubmit:K=>{window.confirm(`Delete phase "${a.title}"?`)||K.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete phase"})})]})]}),d.jsxs(gn,{className:"grid gap-4",children:[d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Tasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:a.tasks.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"In progress"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.inProgress})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Remaining"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.remaining})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Done"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.done})]})]}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-4",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Blocked"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:u.blocked})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Goals"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.goals.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Dependencies"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.dependencies.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Completion criteria"}),d.jsx("p",{className:"mt-2 text-2xl font-black text-[var(--text)]",children:a.completionCriteria.length})]})]}),a.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:a.description,className:"plan-description"})}):null,l.length>0?d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex items-center gap-2 cursor-pointer font-semibold text-[var(--text)] select-none",children:d.jsxs("span",{children:["Decisions (",l.length,")"]})}),d.jsx("div",{className:"mt-2 ml-4 space-y-2 border-l-2 border-[var(--border)] pl-4",children:l.map((K,W)=>d.jsx("div",{className:"text-sm text-[var(--text-muted)]",children:d.jsx(Hn,{text:K})},W))})]}):null,i.length>0?d.jsx(xm,{decisions:i}):null,d.jsx(Sm,{statusLog:a.statusLog??[],currentStatus:a.status,backbone:["draft","discovery","planned","in-progress","done"]})]}),b?d.jsx(gn,{className:"grid gap-4",children:d.jsx(Dc,{title:"Handoff",actions:d.jsx("button",{type:"button",onClick:I,disabled:S,className:"rounded-lg border border-[var(--border)] px-3 py-1.5 text-sm text-[var(--text-muted)] hover:bg-[var(--surface-card)] disabled:opacity-60",children:S?"Clearing…":"Clear handoff"}),children:d.jsx("div",{className:"rounded-[18px] border border-[var(--border)] bg-[var(--surface-card)] px-5 py-5",children:d.jsx(Hn,{text:b,className:"formatted-text max-w-none"})})})}):null,d.jsxs(gn,{className:"grid gap-5",children:[d.jsxs("div",{children:[d.jsx(Ll,{type:"task",number:0}),d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:"Filter this phase's tasks by name or status."})]}),d.jsx(gm,{query:f,status:m,statusOptions:Hu,placeholder:"Search task title, id, or description",clearTo:`/features/${t.id}/phases/${a.id}`,resultsLabel:p.length===a.tasks.length?`${a.tasks.length} tasks`:`${p.length} of ${a.tasks.length} tasks`}),d.jsx("div",{className:"grid gap-3",children:a.tasks.length===0?d.jsxs(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:["No tasks yet. ",d.jsx(dt,{to:"tasks/new",className:"font-semibold text-[var(--accent)] hover:underline",children:"Add a task"})]}):p.length>0?p.map(K=>d.jsx(VT,{featureId:t.id,phaseId:a.id,task:K},K.id)):d.jsx(gn,{className:"p-4 text-sm text-[var(--text-muted)]",children:"No tasks match the current filters."})})]}),d.jsx(Mu,{})]})}async function GT({params:t}){const{featureId:a,phaseId:l,taskId:i}=t;if(!a||!l||!i)throw new Response("featureId, phaseId and taskId required",{status:400});const[u,o,f]=await Promise.all([ku(a),$c(l),qc(i)]);return{feature:u,phase:o,task:f}}function bx(t){try{return new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(new Date(t))}catch{return t}}function XT({featureId:t,phaseId:a,taskId:l,item:i}){const u=is(),o=u.formData?u.formData.get("checked")==="true":i.checked,f=u.state!=="idle";return d.jsxs("div",{className:"surface-card flex items-start gap-3 px-4 py-3",children:[d.jsx("input",{type:"checkbox",checked:o,onChange:()=>u.submit({checked:i.checked?"false":"true"},{method:"post",action:`/features/${t}/phases/${a}/tasks/${l}/checklist/${i.id}/toggle`}),disabled:f,className:"mt-0.5 h-4 w-4 shrink-0 accent-[var(--accent)]","aria-label":`Toggle checklist item ${i.title}`}),d.jsxs("div",{className:"min-w-0",children:[d.jsx("span",{className:"checklist-num",children:i.number})," ",d.jsx("span",{className:`text-sm ${o?"text-[var(--text-muted)] line-through":"font-medium text-[var(--text)]"}`,children:i.title})]})]})}function PT(){var x,b;const{feature:t,phase:a,task:l}=cs(),i=l.decisions??[],u=l.acceptedDecisions??[],o=l.checklist??[],f=el(),m=v.useRef(null),p=v.useCallback(()=>f("edit"),[f]),g=v.useCallback(()=>{var w;(w=m.current)==null||w.requestSubmit()},[]);return Zn("edit",p),Zn("delete",g),d.jsxs("div",{className:"grid gap-8",children:[d.jsxs(dt,{to:`/features/${t.id}/phases/${a.id}`,className:"inline-flex items-center gap-2 text-sm font-semibold text-[var(--accent)] hover:underline",children:[d.jsx(zc,{className:"h-4 w-4"})," Back to phase"]}),d.jsxs("div",{className:"min-w-0",children:[d.jsx(ym,{stacked:!0,items:[{label:t.name,to:`/features/${t.id}`,kind:"Feature"},{label:a.title,to:`/features/${t.id}/phases/${a.id}`,kind:"Phase"},{label:l.title,kind:"Task"}]}),d.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-2",children:[d.jsx(zl,{id:si({featureNum:t.number,phaseNum:a.number,taskNum:l.number}),children:d.jsx(Wr,{featureNum:t.number,phaseNum:a.number,taskNum:l.number})}),l.shortId?d.jsx(ii,{shortId:l.shortId}):null,d.jsx(Sa,{status:l.status})]}),d.jsx("h2",{className:"mt-2 text-2xl font-black tracking-tight text-[var(--text)] min-w-0 break-words [overflow-wrap:anywhere] sm:text-3xl",children:l.title}),d.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-2",children:[d.jsx(dt,{to:"edit",children:d.jsx(bt,{type:"button",shortcut:"edit",children:"Edit task"})}),d.jsx(_a,{ref:m,method:"post",action:`/features/${t.id}/phases/${a.id}/tasks/${l.id}/delete`,className:"inline-flex",onSubmit:w=>{window.confirm(`Delete task "${l.title}"?`)||w.preventDefault()},children:d.jsx(bt,{type:"submit",variant:"danger",shortcut:"delete",children:"Delete task"})})]})]}),d.jsx(bm,{statusLog:l.statusLog??[],currentStatus:l.status,backbone:["planned","in-progress","done"],createdAt:l.createdAt,updatedAt:l.updatedAt,startedAt:l.startedAt,completedAt:l.completedAt}),d.jsxs(gn,{className:"grid gap-4",children:[l.description?d.jsx(Dc,{title:"Description",children:d.jsx(Hn,{text:l.description,className:"plan-description"})}):null,l.notes?d.jsxs("details",{className:"group mt-4 border border-[var(--border)] rounded-lg overflow-hidden",children:[d.jsxs("summary",{className:"flex items-center justify-between p-3 cursor-pointer font-semibold text-[var(--text)] bg-[var(--surface-elevated)] hover:bg-[var(--surface-strong)] transition-colors select-none",children:[d.jsx("div",{className:"flex items-center gap-2",children:d.jsx("span",{className:"text-sm",children:"Notes"})}),d.jsx(_l,{className:"h-4 w-4 transition-transform group-open:rotate-180 text-[var(--text-muted)]"})]}),d.jsx("div",{className:"p-3 border-t border-[var(--border)] bg-[var(--surface)]",children:d.jsx(Hn,{text:l.notes})})]}):d.jsx("p",{className:"mt-4 text-sm text-[var(--text-muted)]",children:"No notes"}),d.jsx(Sm,{statusLog:l.statusLog??[],currentStatus:l.status,backbone:["planned","in-progress","done"],startedAt:l.startedAt,completedAt:l.completedAt}),i.length>0?d.jsxs("details",{className:"group mt-4",children:[d.jsx("summary",{className:"flex items-center gap-2 cursor-pointer font-semibold text-[var(--text)] select-none",children:d.jsxs("span",{children:["Decisions (",i.length,")"]})}),d.jsx("div",{className:"mt-2 ml-4 space-y-2 border-l-2 border-[var(--border)] pl-4",children:i.map((w,S)=>d.jsx("div",{className:"text-sm text-[var(--text-muted)]",children:d.jsx(Hn,{text:w})},S))})]}):null,u.length>0?d.jsx(xm,{decisions:u}):null,d.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-5",children:[d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Checklist items"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:o.length})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Subtasks"}),d.jsx("p",{className:"mt-2 text-3xl font-black text-[var(--text)]",children:((x=l.subtasks)==null?void 0:x.length)??0})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Started"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:l.startedAt?bx(l.startedAt):"—"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Completed"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:l.completedAt?bx(l.completedAt):"—"})]}),d.jsxs(bn,{children:[d.jsx("p",{className:"text-xs font-semibold uppercase tracking-[0.22em] text-[var(--text-subtle)]",children:"Phase"}),d.jsx("p",{className:"mt-2 text-sm font-semibold text-[var(--text)] break-words",children:a.title})]})]}),d.jsxs("div",{className:"grid gap-3",children:[d.jsx("div",{children:d.jsxs("h3",{className:"text-sm font-bold text-[var(--text)]",children:["Steps (",o.length,")"]})}),o.length?d.jsx("div",{className:"grid gap-2",children:o.map(w=>d.jsx(XT,{featureId:t.id,phaseId:a.id,taskId:l.id,item:w},w.id))}):d.jsx("p",{className:"text-sm text-[var(--text-muted)] italic",children:"No steps defined."})]}),(b=l.subtasks)!=null&&b.length?d.jsxs("details",{className:"surface-card px-4 py-4",children:[d.jsx("summary",{className:"cursor-pointer list-none text-sm font-bold text-[var(--text)]",children:"Subtasks"}),d.jsx("div",{className:"mt-3 grid gap-2",children:l.subtasks.map(w=>d.jsxs("div",{className:"surface-card flex items-center justify-between gap-4 px-4 py-3",children:[d.jsxs("div",{children:[d.jsx("p",{className:"text-sm font-semibold text-[var(--text)]",children:w.title}),d.jsx("p",{className:"mt-1 text-xs text-[var(--text-muted)]",children:w.id})]}),d.jsx(Sa,{status:w.status})]},w.id))})]}):null]}),d.jsx(Mu,{})]})}const QT=["a[href]","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","[tabindex]:not([tabindex='-1'])"].join(",");function di({title:t,description:a,children:l}){const i=el(),u=v.useRef(null),o=v.useRef(null);return v.useEffect(()=>{var g;const f=u.current;if(!f)return;const m=document.activeElement;(g=o.current)==null||g.focus();const p=x=>{if(x.key==="Escape"){x.preventDefault(),i(-1);return}if(x.key!=="Tab")return;const b=Array.from(f.querySelectorAll(QT)).filter(A=>A.offsetParent!==null);if(b.length===0){x.preventDefault(),f.focus();return}const w=b[0],S=b[b.length-1],N=document.activeElement;x.shiftKey?(N===w||!f.contains(N))&&(x.preventDefault(),S.focus()):N===S&&(x.preventDefault(),w.focus())};return window.addEventListener("keydown",p),()=>{var x;window.removeEventListener("keydown",p),(x=m==null?void 0:m.focus)==null||x.call(m)}},[i]),d.jsxs("div",{className:"fixed inset-0 z-50 overflow-y-auto p-4 md:p-6",children:[d.jsx("button",{type:"button",className:"absolute inset-0 bg-black/50 backdrop-blur-sm",onClick:()=>i(-1),"aria-label":"Close modal",tabIndex:-1}),d.jsx("div",{className:"relative z-10 flex min-h-full items-start justify-center",children:d.jsxs("div",{ref:u,role:"dialog","aria-modal":"true","aria-label":t,tabIndex:-1,className:"surface-panel flex max-h-[calc(100vh-2rem)] w-full max-w-2xl flex-col overflow-hidden p-6 outline-none md:max-h-[calc(100vh-3rem)] md:p-8",children:[d.jsxs("div",{className:"mb-6 flex shrink-0 items-start justify-between gap-4",children:[d.jsxs("div",{children:[d.jsx("h3",{className:"text-xl font-black tracking-tight text-[var(--text)]",children:t}),a?d.jsx("p",{className:"mt-2 text-sm text-[var(--text-muted)]",children:a}):null]}),d.jsx("button",{ref:o,type:"button",onClick:()=>i(-1),className:"inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-[14px] border border-[var(--border-strong)] text-[var(--text-muted)] transition hover:text-[var(--text)]","aria-label":"Close modal",children:d.jsx(fN,{className:"h-4 w-4"})})]}),d.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto pr-1",children:l})]})})]})}function fi({className:t="",children:a,...l}){return d.jsx("div",{className:`sticky bottom-0 mt-2 flex justify-end gap-3 border-t border-[var(--border)] bg-[var(--surface)] px-1 pt-4 pb-1 backdrop-blur-xl ${t}`,...l,children:a})}function Nt({label:t,children:a}){return d.jsxs("label",{className:"grid gap-2",children:[d.jsx("span",{className:"text-sm font-semibold text-[var(--text-muted)]",children:t}),a]})}function zn(t){return d.jsx("textarea",{className:"field-control field-textarea",...t})}function KT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var u;return(u=l.current)==null?void 0:u.requestSubmit()},[]);return Zn("submit",i,{allowInEditable:!0}),d.jsx(di,{title:"Create feature",description:"Top-level container for phases and tasks.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Feature name",children:d.jsx(Pa,{name:"name",placeholder:"Products page implementation",required:!0})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",placeholder:"Short context for the feature"})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Creating…":"Create feature"})})]})})}function ZT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var f;return(f=l.current)==null?void 0:f.requestSubmit()},[]);Zn("submit",i,{allowInEditable:!0});const o=Ou("feature-detail").feature;return d.jsx(di,{title:"Edit feature",description:"Update metadata, planning notes and timeline.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Name",children:d.jsx(Pa,{name:"name",defaultValue:o.name,required:!0})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",defaultValue:o.description})}),d.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[d.jsx(Nt,{label:"Start date",children:d.jsx(Pa,{type:"date",name:"startDate",defaultValue:o.startDate})}),d.jsx(Nt,{label:"End date",children:d.jsx(Pa,{type:"date",name:"endDate",defaultValue:o.endDate})})]}),d.jsx(Nt,{label:"Status",children:d.jsx(qu,{name:"status",defaultValue:o.status,children:Xc.map(f=>d.jsx("option",{value:f.value,children:f.label},f.value))})}),d.jsx(Nt,{label:"Priority",children:d.jsx(Pa,{type:"number",name:"priority",defaultValue:o.priority??0,min:0})}),d.jsx(Nt,{label:"Work done",children:d.jsx(zn,{name:"workDone",defaultValue:o.workDone})}),d.jsx(Nt,{label:"Work remaining",children:d.jsx(zn,{name:"workRemaining",defaultValue:o.workRemaining})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Saving…":"Save feature"})})]})})}function JT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var u;return(u=l.current)==null?void 0:u.requestSubmit()},[]);return Zn("submit",i,{allowInEditable:!0}),d.jsx(di,{title:"Create phase",description:"A phase belongs to the current feature.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Phase title",children:d.jsx(Pa,{name:"title",placeholder:"API creation",required:!0})}),d.jsx(Nt,{label:"Summary",children:d.jsx(zn,{name:"summary",placeholder:"Brief phase summary"})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",placeholder:"Initial implementation notes"})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Creating…":"Create phase"})})]})})}function Xs(t){return t.join(`
259
259
  `)}function WT(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var f;return(f=l.current)==null?void 0:f.requestSubmit()},[]);Zn("submit",i,{allowInEditable:!0});const o=Ou("phase-detail").phase;return d.jsx(di,{title:"Edit phase",description:"Update scope, constraints and delivery criteria.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Title",children:d.jsx(Pa,{name:"title",defaultValue:o.title,required:!0})}),d.jsx(Nt,{label:"Status",children:d.jsx(qu,{name:"status",defaultValue:o.status,children:Pc.map(f=>d.jsx("option",{value:f.value,children:f.label},f.value))})}),d.jsx(Nt,{label:"Priority",children:d.jsx(Pa,{type:"number",name:"priority",defaultValue:o.priority??0,min:0})}),d.jsx(Nt,{label:"Summary",children:d.jsx(zn,{name:"summary",defaultValue:o.summary})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",defaultValue:o.description})}),d.jsx(Nt,{label:"Goals (one per line)",children:d.jsx(zn,{name:"goals",defaultValue:Xs(o.goals)})}),d.jsx(Nt,{label:"Non-goals (one per line)",children:d.jsx(zn,{name:"nonGoals",defaultValue:Xs(o.nonGoals)})}),d.jsx(Nt,{label:"Dependencies (one per line)",children:d.jsx(zn,{name:"dependencies",defaultValue:Xs(o.dependencies)})}),d.jsx(Nt,{label:"Risks (one per line)",children:d.jsx(zn,{name:"risks",defaultValue:Xs(o.risks)})}),d.jsx(Nt,{label:"Open questions (one per line)",children:d.jsx(zn,{name:"openQuestions",defaultValue:Xs(o.openQuestions)})}),d.jsx(Nt,{label:"Completion criteria (one per line)",children:d.jsx(zn,{name:"completionCriteria",defaultValue:Xs(o.completionCriteria)})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Saving…":"Save phase"})})]})})}function eD(){const a=kl().state!=="idle",l=v.useRef(null),i=v.useCallback(()=>{var u;return(u=l.current)==null?void 0:u.requestSubmit()},[]);return Zn("submit",i,{allowInEditable:!0}),d.jsx(di,{title:"Create task",description:"A task belongs to the current phase.",children:d.jsxs(_a,{ref:l,method:"post",className:"grid gap-4",children:[d.jsx(Nt,{label:"Task title",children:d.jsx(Pa,{name:"title",placeholder:"Custom fetcher integration",required:!0})}),d.jsx(Nt,{label:"Description",children:d.jsx(zn,{name:"description",placeholder:"Initial task context"})}),d.jsx(Nt,{label:"Checklist (one per line)",children:d.jsx(zn,{name:"checklist",placeholder:`Step one
260
260
  Step two
261
261
  Step three`})}),d.jsx(Nt,{label:"Status",children:d.jsx(qu,{name:"status",defaultValue:"planned",children:Hu.map(u=>d.jsx("option",{value:u.value,children:u.label},u.value))})}),d.jsx(fi,{children:d.jsx(bt,{type:"submit",variant:"primary",disabled:a,shortcut:"submit",children:a?"Creating…":"Create task"})})]})})}function tD(t){return t.map(a=>a.title).join(`
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Agent Plan</title>
7
- <script type="module" crossorigin src="/assets/index-DNjqMsl7.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CZs-bw22.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-zZFIH6DD.css">
9
9
  </head>
10
10
  <body>