forge-openclaw-plugin 0.3.16 → 0.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{action-bar-DgrmzFrI.js → action-bar-BAZevCEA.js} +1 -1
- package/dist/assets/{activity-page-CF451ueg.js → activity-page-CnT_hnCU.js} +1 -1
- package/dist/assets/{ai-surface-workspace-DtwybxJB.js → ai-surface-workspace-GPZzIIut.js} +1 -1
- package/dist/assets/artifacts-page-Bqjp0L-L.js +2 -0
- package/dist/assets/{atlas-panel-CB3uYk_K.js → atlas-panel-B95nrYpZ.js} +1 -1
- package/dist/assets/{board-CuxQRKPJ.js → board-CGgOvBP9.js} +1 -1
- package/dist/assets/{calendar-page-BYsDuLnh.js → calendar-page-mlr94wIS.js} +1 -1
- package/dist/assets/{calendar-rules-DXuOv2J-.js → calendar-rules-DdxPmBZJ.js} +1 -1
- package/dist/assets/{calendar-week-toolbar-8PJmiUE_.js → calendar-week-toolbar-Cu8V6zv1.js} +1 -1
- package/dist/assets/{charts-BzT4pUPg.js → charts-Cdtn55ol.js} +1 -1
- package/dist/assets/{companion-sync-lab-page-DzWNOaBh.js → companion-sync-lab-page-CJI5jf8W.js} +1 -1
- package/dist/assets/{daily-metrics-dashboard-CHcYxDhs.js → daily-metrics-dashboard-CXESx7bU.js} +1 -1
- package/dist/assets/{define-workbench-box-DcI0_QKW.js → define-workbench-box-Dbl9W7oE.js} +1 -1
- package/dist/assets/{entity-link-multiselect-C--AiCMb.js → entity-link-multiselect-DZ_jAjs4.js} +1 -1
- package/dist/assets/{entity-note-count-link-xne6mshj.js → entity-note-count-link-FOK_qhcC.js} +1 -1
- package/dist/assets/{entity-notes-surface-jy6Psist.js → entity-notes-surface-Dq9dFKjD.js} +1 -1
- package/dist/assets/execution-board-D9hkXKC2.js +1 -0
- package/dist/assets/{faceted-token-search-BMQ1Wwzt.js → faceted-token-search-BeShxjkc.js} +1 -1
- package/dist/assets/{flagship-signal-deck-DjcskRwF.js → flagship-signal-deck-DZx_HEH9.js} +1 -1
- package/dist/assets/{floating-action-menu-cGhbJ2tc.js → floating-action-menu-CFrgvQJi.js} +1 -1
- package/dist/assets/{forms-D1qJ3oOP.js → forms-DhEGHkFR.js} +1 -1
- package/dist/assets/{generic-node-view-DNVwfqqq.js → generic-node-view-C1kLClIm.js} +1 -1
- package/dist/assets/{goal-detail-page-dAbyCilO.js → goal-detail-page-BhMrnVQs.js} +1 -1
- package/dist/assets/{goal-dialog-DH50D0tP.js → goal-dialog-BlZHh3dw.js} +1 -1
- package/dist/assets/goals-page-CesC8IkZ.js +1 -0
- package/dist/assets/{graph-BF4IsheG.js → graph-U1J6VkbG.js} +1 -1
- package/dist/assets/habits-page-DHxZSThT.js +1 -0
- package/dist/assets/{health-boxes-BPTgGM6G.js → health-boxes-BZjIqiiG.js} +1 -1
- package/dist/assets/index-CHbe1sy1.css +1 -0
- package/dist/assets/index-Dj8q65se.js +2 -0
- package/dist/assets/{inline-note-fields-D4mCM1gO.js → inline-note-fields-DpmCMAJf.js} +1 -1
- package/dist/assets/{insight-flow-dialog-Btp6bkbV.js → insight-flow-dialog-DNIe0sts.js} +1 -1
- package/dist/assets/{insights-page-1qM4mxjS.js → insights-page-D_N_MWGu.js} +3 -3
- package/dist/assets/{kanban-boxes-u_A-UJG-.js → kanban-boxes-DTDG5UEJ.js} +1 -1
- package/dist/assets/{kanban-page-CKCa_3Qb.js → kanban-page-DEvIY5IW.js} +1 -1
- package/dist/assets/knowledge-graph-page-CvXSnnG5.js +1 -0
- package/dist/assets/{life-force-page-BZlyA144.js → life-force-page-CgvUrqQb.js} +1 -1
- package/dist/assets/{life-force-workspace-CtAWZXNw.js → life-force-workspace-BNeMbRHf.js} +1 -1
- package/dist/assets/{maps-BTVHALP8.js → maps-Dk9tZqTA.js} +1 -1
- package/dist/assets/{metric-tile-Bkx2btO2.js → metric-tile-DAhX60rg.js} +1 -1
- package/dist/assets/{motion-DcgUnXhY.js → motion-DeJZhOSA.js} +1 -1
- package/dist/assets/{movement-boxes-QZ2EIS9q.js → movement-boxes-BOqU18NH.js} +1 -1
- package/dist/assets/{movement-page-B-3ihggI.js → movement-page-DCDeUynh.js} +1 -1
- package/dist/assets/{note-markdown-BWedRE3c.js → note-markdown-Cxj84-0j.js} +1 -1
- package/dist/assets/{note-tags-input-DZkCqI1w.js → note-tags-input-CP0-EPpE.js} +1 -1
- package/dist/assets/{notes-boxes-DGFmt7Dp.js → notes-boxes-C7WPT7mf.js} +1 -1
- package/dist/assets/notes-page-Dll8PIks.js +1 -0
- package/dist/assets/{open-in-graph-button-CjvkEj1P.js → open-in-graph-button-BHl16hJP.js} +1 -1
- package/dist/assets/{orbit-map-CRHSPenk.js → orbit-map-De0qpMpY.js} +1 -1
- package/dist/assets/overview-page-C1RX7dcq.js +1 -0
- package/dist/assets/page-hero-DYmFM6-q.js +1 -0
- package/dist/assets/pill-cluster-ClkmFVFT.js +1 -0
- package/dist/assets/{preference-entity-handoff-button-CfCQl3cW.js → preference-entity-handoff-button-1XXtBsUF.js} +1 -1
- package/dist/assets/{preferences-page-OltGdsQ2.js → preferences-page-OwfPIQwe.js} +1 -1
- package/dist/assets/{project-collections-FfBIVwXu.js → project-collections-DfmkBk9d.js} +1 -1
- package/dist/assets/project-detail-page-BC_MNaca.js +1 -0
- package/dist/assets/{project-dialog-B_J1ESMk.js → project-dialog-BuZdXECa.js} +1 -1
- package/dist/assets/project-management-hierarchy-page-AhEHe60K.js +1 -0
- package/dist/assets/{project-management-section-nav-DBNHt9p5.js → project-management-section-nav-CnaseOqL.js} +1 -1
- package/dist/assets/{projects-boxes-BvlVsO5q.js → projects-boxes-D0zM8PfY.js} +1 -1
- package/dist/assets/projects-page-ltrWfLrA.js +1 -0
- package/dist/assets/psyche-behaviors-page-CPurgDg6.js +5 -0
- package/dist/assets/{psyche-flashcards-page-05606-97.js → psyche-flashcards-page-DnUSe-bb.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-Cw-aqS3Y.js → psyche-goal-map-page-uWocO7kZ.js} +1 -1
- package/dist/assets/{psyche-graph-0E22QHPe.js → psyche-graph-BDszV3UN.js} +1 -1
- package/dist/assets/{psyche-metrics-page-DBFVPeMa.js → psyche-metrics-page-CIJLJTPy.js} +1 -1
- package/dist/assets/psyche-mode-guide-page-uC8L4WvH.js +1 -0
- package/dist/assets/psyche-modes-page-CtBeRA_3.js +1 -0
- package/dist/assets/psyche-page-Ds3QDsin.js +1 -0
- package/dist/assets/psyche-patterns-page-Cvq5WshW.js +5 -0
- package/dist/assets/{psyche-questionnaire-builder-page-DEt0UDsz.js → psyche-questionnaire-builder-page-Cg5Upe6z.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-BXQbOE6A.js → psyche-questionnaire-detail-page-D4jEnNoh.js} +1 -1
- package/dist/assets/psyche-questionnaire-run-detail-page-CWoZEY31.js +1 -0
- package/dist/assets/{psyche-questionnaire-run-page-D_EokOQm.js → psyche-questionnaire-run-page-Yg_VG2vq.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-D1Ov2L4n.js → psyche-questionnaires-page-BqeOJRj7.js} +1 -1
- package/dist/assets/{psyche-report-detail-page-9HyPr8BJ.js → psyche-report-detail-page-BtcMQ7mk.js} +3 -3
- package/dist/assets/psyche-reports-page-tagvW0To.js +1 -0
- package/dist/assets/{psyche-schemas-DDol0j-g.js → psyche-schemas-CvRSkI_u.js} +1 -1
- package/dist/assets/psyche-schemas-beliefs-page-4NL3415v.js +9 -0
- package/dist/assets/{psyche-screen-time-page-DJMDR5oo.js → psyche-screen-time-page-Bc5AwZHQ.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-DFKXG1Yv.js → psyche-self-observation-page-CUrUYbQ_.js} +1 -1
- package/dist/assets/{psyche-values-page-TWKth89J.js → psyche-values-page-BshT2sXE.js} +2 -2
- package/dist/assets/{question-flow-dialog-D-_EvoAt.js → question-flow-dialog-CPyXCqA-.js} +2 -2
- package/dist/assets/{report-chain-fields-Dy-jBQDn.js → report-chain-fields-C0UMLpze.js} +1 -1
- package/dist/assets/rewards-page-D9BzsNPW.js +1 -0
- package/dist/assets/{scheduling-rules-editor-CAd290IE.js → scheduling-rules-editor-DiA6KkQ4.js} +1 -1
- package/dist/assets/{schema-badge-BLaVI1D7.js → schema-badge-DURw2eYH.js} +1 -1
- package/dist/assets/{schemas-B0Pa-V-A.js → schemas-D_z2C8l1.js} +1 -1
- package/dist/assets/{select-menu-DcS4Ukjf.js → select-menu-BUB8__Nx.js} +1 -1
- package/dist/assets/{settings-agents-page-Bt38HhEJ.js → settings-agents-page-Kk98Whcf.js} +1 -1
- package/dist/assets/settings-bin-page-BnJ-mgy2.js +1 -0
- package/dist/assets/{settings-calendar-page-DPSSZV3s.js → settings-calendar-page-CdhlUnUW.js} +3 -3
- package/dist/assets/{settings-data-page-BdHsD1C_.js → settings-data-page-BvvuZNbb.js} +1 -1
- package/dist/assets/{settings-logs-page-D9OnWoFq.js → settings-logs-page-CrzkXxtZ.js} +1 -1
- package/dist/assets/{settings-mobile-page-DFpsXA4M.js → settings-mobile-page-Dl582NK6.js} +1 -1
- package/dist/assets/settings-models-page-COoBw28S.js +1 -0
- package/dist/assets/{settings-page-m_3iYPwU.js → settings-page-DqnlOCgo.js} +1 -1
- package/dist/assets/{settings-rewards-page-B2aBm-dA.js → settings-rewards-page-Cw5QSTjy.js} +1 -1
- package/dist/assets/{settings-section-nav-CMeU19Rx.js → settings-section-nav-C1NcWveT.js} +1 -1
- package/dist/assets/{settings-users-page-D8jyewJl.js → settings-users-page-0opvepcM.js} +1 -1
- package/dist/assets/{settings-wiki-page-DjOgQJAh.js → settings-wiki-page-CkpnUkiZ.js} +1 -1
- package/dist/assets/{sleep-page-D8-dA4bE.js → sleep-page-DrS1zs3B.js} +1 -1
- package/dist/assets/{sports-page-CK3PgPKB.js → sports-page-EVnB_zjB.js} +1 -1
- package/dist/assets/{state-Bpe5dF3T.js → state-DWw8Jay_.js} +1 -1
- package/dist/assets/{strategies-page-aFpJath-.js → strategies-page-COhyv_SH.js} +1 -1
- package/dist/assets/{strategy-detail-page-CobF5qLv.js → strategy-detail-page-BaCVkvIu.js} +1 -1
- package/dist/assets/{strategy-dialog-Fgoaoob5.js → strategy-dialog-DvlPo9WV.js} +1 -1
- package/dist/assets/{surface-D0dqgX-k.js → surface-Dg5fauKP.js} +1 -1
- package/dist/assets/{table-U7otr5go.js → table-CWVROEBP.js} +1 -1
- package/dist/assets/task-detail-page-3IeMYIXl.js +1 -0
- package/dist/assets/{task-dialog-eCDTF8xe.js → task-dialog-B7ZT4KE5.js} +5 -5
- package/dist/assets/timebox-planning-dialog-DoZzpEBp.js +1 -0
- package/dist/assets/{today-boxes-CYfskVrM.js → today-boxes-BbUNpb16.js} +1 -1
- package/dist/assets/today-page-adKXN2g1.js +1 -0
- package/dist/assets/training-load-page-DTYbu9f0.js +1 -0
- package/dist/assets/{ui-B9TWEtCx.js → ui-CdEDMtXF.js} +1 -1
- package/dist/assets/{use-anchored-overlay-position-BY4kNzPj.js → use-anchored-overlay-position-Cracjgo6.js} +1 -1
- package/dist/assets/{use-psyche-focus-target-BhNedCZB.js → use-psyche-focus-target-DvRgu-94.js} +1 -1
- package/dist/assets/{user-badge-MEZuJiir.js → user-badge-B8hYK6NU.js} +1 -1
- package/dist/assets/{user-select-field-fx129Uh6.js → user-select-field-akGHK-2t.js} +1 -1
- package/dist/assets/{utility-widgets-h5eG2jvc.js → utility-widgets-D4KsKxLT.js} +2 -2
- package/dist/assets/{vendor-BwL6m4SE.js → vendor-y_uz1Wft.js} +222 -212
- package/dist/assets/{vitals-page-eoFnQ3XL.js → vitals-page-Cjcxh-kO.js} +1 -1
- package/dist/assets/{weekly-review-page-C7BU1gkK.js → weekly-review-page-CR57efzH.js} +1 -1
- package/dist/assets/{weight-loss-page-Cc7Do3XY.js → weight-loss-page-Bk7YkB7b.js} +1 -1
- package/dist/assets/{wiki-article-markdown-CCKoSptz.js → wiki-article-markdown-um6gpmGQ.js} +2 -2
- package/dist/assets/{wiki-editor-page-BpbxZrgz.js → wiki-editor-page-DdP5hvjZ.js} +5 -5
- package/dist/assets/{wiki-ingest-history-page-D5Wfr8pc.js → wiki-ingest-history-page-DSTndduq.js} +1 -1
- package/dist/assets/{wiki-ingest-modal-DhRVsEwC.js → wiki-ingest-modal-PNW3CJ-o.js} +1 -1
- package/dist/assets/wiki-page-CsJlPyQ6.js +1 -0
- package/dist/assets/{workbench-flow-page-y9FxDbKO.js → workbench-flow-page-DFtIKgNe.js} +3 -3
- package/dist/assets/{workbench-page-Da16AZvN.js → workbench-page-DEpKjMEv.js} +1 -1
- package/dist/assets/workout-detail-page-BwfEhxA_.js +2 -0
- package/dist/index.html +8 -8
- package/dist/openclaw/parity.d.ts +1 -1
- package/dist/openclaw/parity.js +10 -0
- package/dist/openclaw/routes.js +78 -0
- package/dist/openclaw/tools.js +42 -0
- package/dist/server/apps/api/migrations/072_artifact_store.sql +106 -0
- package/dist/server/apps/api/migrations/073_artifact_entity_links_repair.sql +24 -0
- package/dist/server/apps/api/src/app.js +364 -3
- package/dist/server/apps/api/src/openapi.js +570 -1
- package/dist/server/apps/api/src/repositories/entity-links.js +66 -0
- package/dist/server/apps/api/src/services/artifacts.js +1059 -0
- package/dist/server/apps/api/src/services/entity-crud.js +22 -0
- package/dist/server/apps/api/src/services/knowledge-graph.js +45 -0
- package/dist/server/apps/api/src/services/psyche-observation-calendar.js +1 -0
- package/dist/server/apps/api/src/types.js +2 -0
- package/dist/server/apps/web/src/lib/api.js +69 -0
- package/dist/server/apps/web/src/lib/entity-visuals.js +10 -1
- package/dist/server/apps/web/src/lib/knowledge-graph-types.js +9 -0
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
- package/server/migrations/072_artifact_store.sql +106 -0
- package/server/migrations/073_artifact_entity_links_repair.sql +24 -0
- package/skills/forge-openclaw/SKILL.md +57 -4
- package/skills/forge-openclaw/entity_conversation_playbooks.md +215 -14
- package/skills/forge-openclaw/psyche_entity_playbooks.md +20 -0
- package/dist/assets/execution-board-BSUZCIIx.js +0 -1
- package/dist/assets/goals-page-DkMy9mPD.js +0 -1
- package/dist/assets/habits-page-CCQR8rg6.js +0 -1
- package/dist/assets/index-VzCGTBS_.css +0 -1
- package/dist/assets/index-izRKx6JK.js +0 -2
- package/dist/assets/knowledge-graph-page-BZOxRv19.js +0 -1
- package/dist/assets/notes-page-DYkn04tz.js +0 -1
- package/dist/assets/overview-page-D6LsjPWe.js +0 -1
- package/dist/assets/page-hero-BLhM8FF3.js +0 -1
- package/dist/assets/pill-cluster-B5bYs_e2.js +0 -1
- package/dist/assets/project-detail-page-CCm3iZPQ.js +0 -1
- package/dist/assets/project-management-hierarchy-page-BNzvtNZj.js +0 -1
- package/dist/assets/projects-page-BUf7KV-_.js +0 -1
- package/dist/assets/psyche-behaviors-page-jtyhdpJ1.js +0 -5
- package/dist/assets/psyche-mode-guide-page-DI-LNEDT.js +0 -1
- package/dist/assets/psyche-modes-page-CaMupyfi.js +0 -1
- package/dist/assets/psyche-page-CFBq0YKf.js +0 -1
- package/dist/assets/psyche-patterns-page-sp4ikoef.js +0 -5
- package/dist/assets/psyche-questionnaire-run-detail-page-Cd3ClsSK.js +0 -1
- package/dist/assets/psyche-reports-page-BeyJg5fb.js +0 -1
- package/dist/assets/psyche-schemas-beliefs-page-DNmf-Vma.js +0 -9
- package/dist/assets/rewards-page-D3ymEd2X.js +0 -1
- package/dist/assets/settings-bin-page-DqyVI1i1.js +0 -1
- package/dist/assets/settings-models-page-DaFXLp-O.js +0 -1
- package/dist/assets/task-detail-page-CDK79bzk.js +0 -1
- package/dist/assets/timebox-planning-dialog-CNZIGSpd.js +0 -1
- package/dist/assets/today-page-Bnh8wopq.js +0 -1
- package/dist/assets/training-load-page-C7lq-jqy.js +0 -1
- package/dist/assets/wiki-page-1vf-HErs.js +0 -1
- package/dist/assets/workout-detail-page-Cq0YamXF.js +0 -2
|
@@ -49,11 +49,8 @@ Forge correctly, and gather only the structure that still matters.
|
|
|
49
49
|
feels important to keep true before you ask for labels, dates, or taxonomy.
|
|
50
50
|
- When the user is clear, say what the record seems to be becoming and move straight to
|
|
51
51
|
the last missing structural detail.
|
|
52
|
-
- For straightforward logistical entities such as tasks, calendar events, work
|
|
53
|
-
timeboxes, and task runs, use a fast path:
|
|
54
|
-
one brief confirming sentence -> one operational question.
|
|
55
|
-
- For logistical records such as tasks, calendar events, work blocks, timeboxes, and
|
|
56
|
-
task runs, use a fast path:
|
|
52
|
+
- For straightforward logistical entities such as tasks, calendar events, work
|
|
53
|
+
blocks, timeboxes, and task runs, use a fast path:
|
|
57
54
|
one brief confirming sentence -> one operational question.
|
|
58
55
|
- For action-heavy flows such as work adjustments, preference judgments, preference
|
|
59
56
|
signals, and Movement, Life Force, or Workbench work, first
|
|
@@ -142,11 +139,34 @@ With the user, say the human thing:
|
|
|
142
139
|
- "Movement timeline", "place", "trip", "missing block", or "time window"
|
|
143
140
|
- "Energy model", "weekday pattern", or "fatigue signal"
|
|
144
141
|
- "Workbench flow", "run", "published output", or "node result"
|
|
145
|
-
- "Wiki page", "
|
|
142
|
+
- "Wiki page", "artifact file", "provenance", "note", "trigger report",
|
|
143
|
+
"behavior pattern", "belief", or "mode"
|
|
146
144
|
|
|
147
145
|
The API path still matters, but it should not leak into the question unless the user
|
|
148
146
|
is explicitly asking about implementation.
|
|
149
147
|
|
|
148
|
+
## User-facing wording guard
|
|
149
|
+
|
|
150
|
+
Use this guard after the opening question too. Later turns, read summaries, and
|
|
151
|
+
confirmations should stay as concrete as the first question.
|
|
152
|
+
|
|
153
|
+
- Do not say "that sounds important" unless you name the stake: what the user is
|
|
154
|
+
trying to protect, recover, decide, remember, repair, schedule, or publish.
|
|
155
|
+
- Do not ask "what would you like to do with this?" after the user's verb, the read
|
|
156
|
+
result, or the selected route lane already makes one next action visible. Name the
|
|
157
|
+
next action and ask only for the missing product detail, or close cleanly.
|
|
158
|
+
- Replace implementation words with product nouns before the sentence reaches the
|
|
159
|
+
user. Say missing stay, place boundary, weekday energy curve, saved flow, failed
|
|
160
|
+
run, node output, belief sentence, pattern, flashcard, wiki page, calendar
|
|
161
|
+
connection, artifact file, provenance, generic entity link, or task run instead of
|
|
162
|
+
endpoint, payload, mutation, batch route, or route key.
|
|
163
|
+
- If the only honest next sentence would be a generic reflection or a route-shaped
|
|
164
|
+
question, pause and identify the product noun internally. If you still cannot name
|
|
165
|
+
it, ask one grounding question about the real moment, span, object, or decision.
|
|
166
|
+
- After a read or write, never add a conversational tail just to sound warm. If no
|
|
167
|
+
answer-changing uncertainty remains, summarize the result in product language and
|
|
168
|
+
stop.
|
|
169
|
+
|
|
150
170
|
## Internal action trace, external wording
|
|
151
171
|
|
|
152
172
|
Before you ask or act, keep a private action trace: intent, entity or dedicated
|
|
@@ -165,6 +185,33 @@ missing detail that would change the action. Do not narrate that trace to the us
|
|
|
165
185
|
- This is especially important after mixed-intent requests. The user should feel a
|
|
166
186
|
coherent sequence, not see your internal routing table.
|
|
167
187
|
|
|
188
|
+
## Known-target fast path
|
|
189
|
+
|
|
190
|
+
Use this when the user's words already name the object, action, and likely route lane.
|
|
191
|
+
The agent should not make the user pass through the general opener again.
|
|
192
|
+
|
|
193
|
+
- For normal stored entities, if the user gave the accepted wording and the intended
|
|
194
|
+
operation, ask only for the parent, owner, or duplicate-disambiguation detail that
|
|
195
|
+
would change the write. If none would change it, summarize and save.
|
|
196
|
+
- For task hierarchy work, if the user already says issue, task, or subtask, keep that
|
|
197
|
+
level and ask only for the missing project, issue, or parent task that would change
|
|
198
|
+
placement.
|
|
199
|
+
- For Movement, if the user already names the missing span, saved overlay, place,
|
|
200
|
+
stay, trip, or trip point, ask only for the missing interval, boundary, saved
|
|
201
|
+
object, or confirmation that is still missing; do not ask whether this is day,
|
|
202
|
+
timeline, or repair work.
|
|
203
|
+
- For Life Force, if the user already names a weekday pattern, profile assumption, or
|
|
204
|
+
right-now fatigue state, ask only for the weekday/time shape, profile field, signal
|
|
205
|
+
intensity, or planning effect that would change the dedicated write.
|
|
206
|
+
- For Workbench, if the user already names a flow, run, node, latest output, or
|
|
207
|
+
published result, ask only for the missing flow, run, node, input, output, or
|
|
208
|
+
preservation choice. Do not reopen flow-creation or flow-edit intake before reading
|
|
209
|
+
the requested artifact.
|
|
210
|
+
- For direct Psyche saves, if the belief sentence, functional loop, part voice,
|
|
211
|
+
trigger episode, value phrase, event kind, emotion signature, or flashcard message
|
|
212
|
+
is already usable, move to one accuracy or consent question instead of restarting
|
|
213
|
+
exploration.
|
|
214
|
+
|
|
168
215
|
## Dedicated surface lane translation
|
|
169
216
|
|
|
170
217
|
Use this when Movement, Life Force, or Workbench work needs a route choice. The route
|
|
@@ -372,6 +419,10 @@ to the stronger container:
|
|
|
372
419
|
label will improve future trigger reports.
|
|
373
420
|
- Use `wiki_page` when the user wants durable memory, a book/article/source summary,
|
|
374
421
|
a reference page, a concept page, or a reusable personal manual.
|
|
422
|
+
- Use `artifact` when the user wants Forge to store a trusted file for human
|
|
423
|
+
retrieval, audit, provenance, or evidence. Link it to other Forge records through
|
|
424
|
+
the general entity-link model; do not create an artifact-specific relationship
|
|
425
|
+
system.
|
|
375
426
|
- Use a linked `note` when nuance should be preserved without pretending it is the
|
|
376
427
|
whole structured model.
|
|
377
428
|
|
|
@@ -591,9 +642,12 @@ Use this quick split before the conversation gets too detailed.
|
|
|
591
642
|
- Every normal entity section below inherits that batch-route default unless its own
|
|
592
643
|
route note says otherwise. Do not invent one-off entity endpoints for ordinary
|
|
593
644
|
stored records.
|
|
594
|
-
- `wiki_page` and `
|
|
595
|
-
page routes
|
|
596
|
-
are simple batch records.
|
|
645
|
+
- `wiki_page`, `calendar_connection`, and `artifact` are specialized CRUD areas. Use
|
|
646
|
+
the wiki page routes, calendar connection setup or sync routes, and artifact routes
|
|
647
|
+
instead of pretending they are simple batch records. Batch CRUD may search, update,
|
|
648
|
+
delete, and restore artifact metadata, but file upload, scan, enrichment, trust,
|
|
649
|
+
versions, audit, and generic entity-link replacement stay on the Artifact Store
|
|
650
|
+
route family.
|
|
597
651
|
- `task_run`, `work_adjustment`, `questionnaire_run`, `preference_judgment`,
|
|
598
652
|
`preference_signal`, and `self_observation` are action workflows. Start from what
|
|
599
653
|
the user is trying to do, then use the dedicated action tool or note-backed write
|
|
@@ -615,6 +669,48 @@ Use this quick split before the conversation gets too detailed.
|
|
|
615
669
|
- If the tool schema and live onboarding disagree about a specialized route key or
|
|
616
670
|
path, treat that as a contract mismatch to fix. Do not guess a nearby route.
|
|
617
671
|
|
|
672
|
+
## Route execution handoff
|
|
673
|
+
|
|
674
|
+
Use this after the conversation has enough information and before any read, write,
|
|
675
|
+
run, repair, or publish call. This is an internal checklist; do not turn it into a
|
|
676
|
+
user-facing API explanation.
|
|
677
|
+
|
|
678
|
+
1. Freeze the accepted user-facing formulation or target object: title, belief
|
|
679
|
+
sentence, movement span, weekday, flow, run, node, or published result.
|
|
680
|
+
2. Choose exactly one execution lane: shared batch CRUD, specialized CRUD, action
|
|
681
|
+
workflow, read-model route, or specialized domain route.
|
|
682
|
+
3. For shared batch CRUD, use the catalog `entityType` exactly and the batch
|
|
683
|
+
create/update/delete/restore/search routes. Search or read first for update,
|
|
684
|
+
delete, restore, link, duplicate-disambiguation, or review work.
|
|
685
|
+
4. For specialized CRUD or action workflows, use the named tool or documented route
|
|
686
|
+
for wiki pages, calendar connections, artifacts, task runs, work adjustments,
|
|
687
|
+
questionnaire runs, preference judgments/signals, and self-observation notes.
|
|
688
|
+
5. For Movement, Life Force, and Workbench, verify the `routeKey`, method, path, and
|
|
689
|
+
every placeholder in `methodRoutes`; fill `pathParams` by placeholder name before
|
|
690
|
+
the call. Do not put IDs into `routeKey`, hide placeholders in `query` or `body`,
|
|
691
|
+
or use nearby guessed paths.
|
|
692
|
+
6. After the call, confirm the product result in the user's language and run the
|
|
693
|
+
verification read only when it proves a repair, explains impact, or grounds the
|
|
694
|
+
next decision.
|
|
695
|
+
|
|
696
|
+
## Read-Model Alias Handling
|
|
697
|
+
|
|
698
|
+
Live onboarding publishes several read-model surfaces with both camelCase and
|
|
699
|
+
entity-style aliases. Treat each pair as the same user-facing flow and normalize it
|
|
700
|
+
internally before asking questions:
|
|
701
|
+
|
|
702
|
+
- `operatorOverview` and `operator_overview`
|
|
703
|
+
- `operatorContext` and `operator_context`
|
|
704
|
+
- `calendarOverview` and `calendar_overview`
|
|
705
|
+
- `sleepOverview` and `sleep_overview`
|
|
706
|
+
- `sportsOverview` and `sports_overview`
|
|
707
|
+
- `trainingLoad` and `training_load`
|
|
708
|
+
- `weightLoss` and `weight_loss`
|
|
709
|
+
- `selfObservation` and `self_observation`
|
|
710
|
+
|
|
711
|
+
Do not ask the user which alias they mean. Ask the practical question the read should
|
|
712
|
+
answer, then use the published read route for that alias pair.
|
|
713
|
+
|
|
618
714
|
## Full Route Posture Matrix
|
|
619
715
|
|
|
620
716
|
Use this as an internal checklist when simulating or handling an entity flow. Do not
|
|
@@ -645,6 +741,11 @@ still knowing the exact write/read family before it acts.
|
|
|
645
741
|
- `calendar_connection`: specialized CRUD. Use provider discovery, connection CRUD,
|
|
646
742
|
selected-calendar rediscovery, sync, and delete routes rather than batch entity
|
|
647
743
|
tools.
|
|
744
|
+
- `artifact`: specialized CRUD. Use `/api/v1/artifacts` for trusted file upload,
|
|
745
|
+
metadata reads and updates, static rescan, optional LLM metadata enrichment,
|
|
746
|
+
trust-state decisions, version and audit reads, and replacement of general
|
|
747
|
+
`entity_links`. Do not download, open, execute, preview, or transform file bytes as
|
|
748
|
+
an agent; download is a human-operator-only action.
|
|
648
749
|
- `operator_overview`: read-model-only operator surface. Use
|
|
649
750
|
`forge_get_operator_overview` or `/api/v1/operator/overview` when the user wants
|
|
650
751
|
the current Forge picture, attention cues, or broad status before choosing a
|
|
@@ -728,6 +829,31 @@ Update record:
|
|
|
728
829
|
|
|
729
830
|
- "Before I change it, what feels newly true now, and what should stay intact?"
|
|
730
831
|
|
|
832
|
+
## Active-listening turn contract
|
|
833
|
+
|
|
834
|
+
Use this before deepening any create, update, review, or guide flow. The turn should
|
|
835
|
+
prove that the agent heard the user and knows what the next answer would change.
|
|
836
|
+
|
|
837
|
+
1. Reflect the specific stake, working shape, or product object in one sentence.
|
|
838
|
+
Avoid generic warmth such as "that sounds important".
|
|
839
|
+
2. Classify the next useful move internally: wording, boundary, placement, timing,
|
|
840
|
+
route scope, support action, verification read, preservation choice, or consent.
|
|
841
|
+
3. Ask one question whose answer would change that move.
|
|
842
|
+
4. If the answer would only add polish, optional metadata, or therapist-like color,
|
|
843
|
+
do not ask it.
|
|
844
|
+
|
|
845
|
+
For Psyche-adjacent material, the reflection should name a felt stake, protection,
|
|
846
|
+
prediction, payoff, cost, or value conflict. If a functional loop or belief sentence
|
|
847
|
+
is already visible, move toward one tentative formulation instead of mirroring again.
|
|
848
|
+
|
|
849
|
+
For logistical entities, keep the reflection short and route to the operational
|
|
850
|
+
detail: parent, owner, time, recurrence, run target, comparison item, or save
|
|
851
|
+
confirmation.
|
|
852
|
+
|
|
853
|
+
For Movement, Life Force, and Workbench, reflect the product object first:
|
|
854
|
+
movement span, place boundary, weekday curve, fatigue signal, flow, run, node output,
|
|
855
|
+
or published result. Then ask only for the missing route-selecting detail.
|
|
856
|
+
|
|
731
857
|
## Turn shapes
|
|
732
858
|
|
|
733
859
|
Use these as small conversation molds when you need the next turn to feel guided
|
|
@@ -1251,6 +1377,22 @@ Arc:
|
|
|
1251
1377
|
5. Ask what would make it easier to do: due date, priority, owner, human/bot
|
|
1252
1378
|
assignees, acceptance criteria, or one line of context.
|
|
1253
1379
|
|
|
1380
|
+
Level-specific handling:
|
|
1381
|
+
|
|
1382
|
+
- For `issue`, ask what vertical slice of the project should become true and whether
|
|
1383
|
+
it is AFK or HITL before asking for one-session execution instructions.
|
|
1384
|
+
- For `task`, ask what one focused session should finish and which issue it belongs
|
|
1385
|
+
under when the hierarchy matters.
|
|
1386
|
+
- For `subtask`, ask which parent task it breaks down and what small child step it
|
|
1387
|
+
names. Do not inflate a subtask into a full task or issue unless the described work
|
|
1388
|
+
no longer fits as a lightweight child step.
|
|
1389
|
+
- When the user already says issue, task, or subtask, keep that word in the
|
|
1390
|
+
user-facing reflection and confirmation. Do not collapse all three into "task" just
|
|
1391
|
+
because the API entity type is `task`.
|
|
1392
|
+
- All three levels still use the shared batch entity route with `entityType: "task"`
|
|
1393
|
+
and the appropriate `level`. The level distinction is product meaning, not a
|
|
1394
|
+
separate route family.
|
|
1395
|
+
|
|
1254
1396
|
Helpful follow-up lanes:
|
|
1255
1397
|
|
|
1256
1398
|
- turn vague intent into an actionable verb
|
|
@@ -1405,6 +1547,65 @@ Preferred opening question:
|
|
|
1405
1547
|
|
|
1406
1548
|
- "What do you want this wiki page to help you remember or reuse later?"
|
|
1407
1549
|
|
|
1550
|
+
## Artifact
|
|
1551
|
+
|
|
1552
|
+
Aim: store a trusted file so a human can find it, understand what it is, trace where
|
|
1553
|
+
it came from, and download it later without letting agents run or inspect the file
|
|
1554
|
+
bytes.
|
|
1555
|
+
|
|
1556
|
+
Arc:
|
|
1557
|
+
|
|
1558
|
+
1. Ask what the file or file set should help the human retrieve, prove, review, or preserve later.
|
|
1559
|
+
2. If there are several files, treat them as a queue: get a quick short description per file,
|
|
1560
|
+
then open per-file details only where title, provenance, links, metadata JSON, or LLM enrichment
|
|
1561
|
+
choices need more care.
|
|
1562
|
+
3. Ask for the human-readable title, short description, provenance, and source path
|
|
1563
|
+
only when the user has not already supplied them.
|
|
1564
|
+
4. Ask which Forge record the artifact should be linked to only when that link will
|
|
1565
|
+
improve retrieval or context. Use Forge's general entity-to-entity link model.
|
|
1566
|
+
5. Ask whether optional LLM enrichment should fill missing description/provenance
|
|
1567
|
+
fields and produce a danger summary when an LLM connection exists.
|
|
1568
|
+
6. Keep trust explicit: only a trusted human/operator or trusted agent may add file
|
|
1569
|
+
bytes, and the agent must not download, open, execute, preview, or transform the
|
|
1570
|
+
stored file.
|
|
1571
|
+
7. After upload, summarize the stored artifact metadata, scan result, danger score,
|
|
1572
|
+
and linked Forge records in product language.
|
|
1573
|
+
|
|
1574
|
+
Helpful follow-up lanes:
|
|
1575
|
+
|
|
1576
|
+
- what the file should help someone retrieve, prove, review, or preserve
|
|
1577
|
+
- missing title, short description, provenance, source path, or owner
|
|
1578
|
+
- whether the artifact belongs with a project, task, wiki page, note, Psyche record,
|
|
1579
|
+
or other Forge entity through a general `entity_links` relationship
|
|
1580
|
+
- whether to request LLM metadata enrichment when descriptions are missing
|
|
1581
|
+
- whether the static scan or danger score requires quarantine, rejection, or a human
|
|
1582
|
+
trust decision
|
|
1583
|
+
|
|
1584
|
+
Routing rule:
|
|
1585
|
+
|
|
1586
|
+
- `artifact` is a specialized CRUD surface. Use the Artifact Store route family for
|
|
1587
|
+
trusted file upload, metadata reads and updates, static scan, LLM enrichment,
|
|
1588
|
+
trust-state changes, versions, audit reads, and replacement of general
|
|
1589
|
+
`entity_links`.
|
|
1590
|
+
- Do not create or use artifact-specific links. Artifact relationships are normal
|
|
1591
|
+
Forge entity-to-entity links with `sourceEntityType`, `sourceEntityId`,
|
|
1592
|
+
`targetEntityType`, `targetEntityId`, optional `relationship`, and optional
|
|
1593
|
+
`anchorKey`.
|
|
1594
|
+
- Agents may list and update artifact metadata when authorized, but they must not
|
|
1595
|
+
download, open, execute, preview, transform, or autonomously process stored file
|
|
1596
|
+
bytes.
|
|
1597
|
+
|
|
1598
|
+
Ready to save when:
|
|
1599
|
+
|
|
1600
|
+
- the file is present and the actor is trusted to upload it
|
|
1601
|
+
- title or filename, provenance or source path, and basic purpose are clear enough
|
|
1602
|
+
- the desired generic Forge entity links are known or intentionally absent
|
|
1603
|
+
- the user has chosen whether missing metadata should be filled by LLM enrichment
|
|
1604
|
+
|
|
1605
|
+
Preferred opening question:
|
|
1606
|
+
|
|
1607
|
+
- "What should this file help you find, prove, review, or preserve later?"
|
|
1608
|
+
|
|
1408
1609
|
## Insight
|
|
1409
1610
|
|
|
1410
1611
|
Aim: capture one grounded observation or recommendation clearly enough that it stays
|
|
@@ -2132,9 +2333,9 @@ Arc:
|
|
|
2132
2333
|
9. If the truth of one uncertain span is still unclear, read the timeline or saved-box
|
|
2133
2334
|
detail before you mutate it.
|
|
2134
2335
|
10. Skip the meta lane question when the user already named the exact correction or
|
|
2135
|
-
|
|
2336
|
+
review target and only one ambiguity remains.
|
|
2136
2337
|
11. Use the dedicated movement route once you know whether the user needs timeline
|
|
2137
|
-
|
|
2338
|
+
review, overlay, place or trip detail, selection summary, settings, or repair.
|
|
2138
2339
|
|
|
2139
2340
|
Direct action rules:
|
|
2140
2341
|
|
|
@@ -2355,10 +2556,10 @@ Arc:
|
|
|
2355
2556
|
9. If the user already named the flow and action clearly, skip the meta lane
|
|
2356
2557
|
question and ask only for the missing run, node, or output scope.
|
|
2357
2558
|
10. If the user wants a stable public input contract or published output, prefer those
|
|
2358
|
-
|
|
2559
|
+
dedicated reads instead of detouring through run history first.
|
|
2359
2560
|
11. If the user is debugging one failed run, ask whether the useful artifact is the run
|
|
2360
|
-
|
|
2361
|
-
|
|
2561
|
+
summary, one node result, the latest node output, or the published output before
|
|
2562
|
+
you start asking for edits.
|
|
2362
2563
|
12. Route to the dedicated workbench route family once the execution lane is clear.
|
|
2363
2564
|
|
|
2364
2565
|
Helpful follow-up lanes:
|
|
@@ -182,6 +182,26 @@ Connect:
|
|
|
182
182
|
- when another record is clearly present, ask whether the user wants to link it now,
|
|
183
183
|
save it separately later, or just keep it in the note/context for now
|
|
184
184
|
|
|
185
|
+
## Psyche active-listening turn contract
|
|
186
|
+
|
|
187
|
+
Use this before every deeper Psyche follow-up. The goal is to help the user feel
|
|
188
|
+
accurately understood while still moving toward a saveable formulation.
|
|
189
|
+
|
|
190
|
+
1. Reflect the specific felt stake or protective move you heard: danger, shame,
|
|
191
|
+
pressure, grief, longing, protection, relief, cost, or value conflict.
|
|
192
|
+
2. Decide internally which Psyche lane the next answer would change: belief sentence,
|
|
193
|
+
functional loop, behavior move, mode voice, trigger sequence, value phrase, event
|
|
194
|
+
kind, emotion signature, flashcard cue, link, or consent.
|
|
195
|
+
3. Ask one question that changes that lane.
|
|
196
|
+
4. If a concrete example already supports a functional interpretation, offer one
|
|
197
|
+
tentative hypothesis and one fit-or-correction question instead of asking another
|
|
198
|
+
broad exploratory question.
|
|
199
|
+
5. If the user accepts or corrects the formulation, bridge toward the nearest
|
|
200
|
+
saveable record rather than reopening origin, evidence, or repair.
|
|
201
|
+
|
|
202
|
+
This is active listening, not just mirroring. A strong turn names what seems at stake,
|
|
203
|
+
keeps the hypothesis correctable, and reduces the user's burden of wording.
|
|
204
|
+
|
|
185
205
|
## Interpretive Hypotheses
|
|
186
206
|
|
|
187
207
|
Use hypotheses when reflection alone would leave the user circling around the same
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as N,b3 as Je,c8 as Fe,c5 as Qe,cq as he,j as t,c1 as je,b2 as pt,c4 as Xe,cr as Ye,cs as Ze,bC as xt,b9 as gt,c3 as bt,aO as ht,aP as ve,bD as Ue,ct as vt}from"./vendor-BwL6m4SE.js";import{u as wt,a as jt,D as yt,S as Pe,v as qe,e as Nt,p as kt,f as St,P as It,g as Te,b as et,C as tt}from"./board-CuxQRKPJ.js";import{u as ye,C as it,B as Ve,c as W,R as Ct,a as rt,b as le,k as S,E as at}from"./index-izRKx6JK.js";import{U as we}from"./user-badge-MEZuJiir.js";import{E as zt}from"./entity-note-count-link-xne6mshj.js";import{F as Dt}from"./floating-action-menu-cGhbJ2tc.js";function $t(e){if(typeof e=="number"&&Number.isInteger(e)&&e>0)return e;if(typeof e=="string"){const r=e.match(/(\d+)/);if(r){const l=Number.parseInt(r[1]??"",10);return Number.isInteger(l)&&l>0?l:null}}return null}function Ge(e){return e.split(/\r?\n/).map(r=>r.trim()).reduce((r,l)=>{const o=l.match(/^[-*+]\s+\[([ xX])\]\s+(.+)$/);if(o)return r.push({label:o[2].trim(),completed:o[1].toLowerCase()==="x"}),r;const c=l.match(/^(?:[-*+]|\d+\.)\s+(.+)$/);return c&&r.push({label:c[1].trim(),completed:null}),r},[]).filter(r=>r.label.length>0)}function _t(e){if(e.acceptanceCriteria.length>0)return{total:e.acceptanceCriteria.length,completed:e.status==="done"?e.acceptanceCriteria.length:0,source:"acceptance_criteria",items:e.acceptanceCriteria};const r=Ge(e.aiInstructions);if(r.length>0){const o=e.status==="done"?r.length:r.filter(c=>c.completed===!0).length;return{total:r.length,completed:o,source:"ai_instructions",items:r.map(c=>c.label)}}const l=Ge(e.description);if(l.length>0){const o=e.status==="done"?l.length:l.filter(c=>c.completed===!0).length;return{total:l.length,completed:o,source:"description",items:l.map(c=>c.label)}}return null}function He(e,r){return e.find(l=>l.refType===r)??null}function nt(e,r=null){var f,x,w,D,k,C,$,U,_,B,R;const l=new Set(((f=e.completionReport)==null?void 0:f.linkedGitRefIds)??[]),o=He(e.gitRefs,"branch"),c=He(e.gitRefs,"pull_request"),u=(r==null?void 0:r.gitContext)??null,m=(u==null?void 0:u.pullRequestNumber)??$t((c==null?void 0:c.refValue)??(c==null?void 0:c.displayTitle)??null);return{actor:(r==null?void 0:r.actor)??null,activeRun:r,stepSummary:_t(e),changedFileCount:((x=e.completionReport)==null?void 0:x.modifiedFiles.length)??0,changedFilesPreview:(((w=e.completionReport)==null?void 0:w.modifiedFiles)??[]).slice(0,2),git:{provider:((D=u==null?void 0:u.provider)==null?void 0:D.trim())||((k=o==null?void 0:o.provider)==null?void 0:k.trim())||((C=c==null?void 0:c.provider)==null?void 0:C.trim())||null,repository:(($=u==null?void 0:u.repository)==null?void 0:$.trim())||((U=o==null?void 0:o.repository)==null?void 0:U.trim())||((_=c==null?void 0:c.repository)==null?void 0:_.trim())||null,branch:((B=u==null?void 0:u.branch)==null?void 0:B.trim())||((R=o==null?void 0:o.refValue)==null?void 0:R.trim())||null,branchUrl:(u==null?void 0:u.branchUrl)??(o==null?void 0:o.url)??null,pullRequestNumber:m,pullRequestUrl:(u==null?void 0:u.pullRequestUrl)??(c==null?void 0:c.url)??null,compareUrl:(u==null?void 0:u.compareUrl)??null,linkedRefCount:l.size}}}const I=["backlog","focus","in_progress","blocked","done"];function Bt(e){if(!e)return null;const r=Date.parse(e);return Number.isNaN(r)?null:new Date(r).toISOString().slice(0,10)}function Mt({task:e,onOpenTask:r,onEditTask:l,onLinkTask:o,onCreateTaskForIssue:c,onCreateSubtaskForTask:u,onMove:m,onDeleteTask:f,deletePendingTaskId:x,onRequestDelete:w}){const D=e.level==="issue"?{id:"create-task",label:"Create task",description:"Add a focused execution task under this issue.",icon:he,onSelect:()=>c==null?void 0:c(e.id)}:e.level==="task"?{id:"create-subtask",label:"Create subtask",description:"Add a granular child step under this task.",icon:he,onSelect:()=>u==null?void 0:u(e.id)}:null;return[{id:"open-task",label:"Open",description:"Jump to the work-item detail view.",icon:Je,onSelect:()=>r==null?void 0:r(e.id)},{id:"edit-task",label:"Edit",description:"Open the guided work-item editor.",icon:Fe,onSelect:()=>l==null?void 0:l(e.id)},{id:"link-task",label:"Link",description:"Open the placement step to relink this work item.",icon:Qe,onSelect:()=>o==null?void 0:o(e.id)},...D?[D]:[],{id:"delete-task",label:e.level==="issue"?"Delete issue":e.level==="subtask"?"Delete subtask":"Delete task",description:"Remove this work item directly from the board menu.",icon:je,tone:"danger",disabled:!f||x===e.id,onSelect:()=>w(e)},...I.filter(k=>k!==e.status).map(k=>({id:`move-task-${k}`,label:`Move to ${k.replaceAll("_"," ")}`,description:"Update the workflow lane for this work item.",onSelect:()=>void m(e.id,k)}))]}function st(e){return e.startsWith("lane:")||e.includes(":lane:")}function At(e){var r,l;return((l=(r=e.data)==null?void 0:r.current)==null?void 0:l.type)==="lane"||st(String(e.id))}function Lt(e){var r,l;return((l=(r=e.data)==null?void 0:r.current)==null?void 0:l.type)==="trash"}function Et(e,r){const l=Math.max(0,Math.min(e.right,r.right)-Math.max(e.left,r.left)),o=Math.max(0,Math.min(e.bottom,r.bottom)-Math.max(e.top,r.top));return l*o}const Rt=e=>{const r=kt(e),l=r.find(m=>{const f=e.droppableContainers.find(x=>x.id===m.id);return f?Lt(f):!1});if(l)return[l];const o=r.find(m=>st(String(m.id)));if(o)return[o];const u=e.droppableContainers.filter(m=>At(m)).map(m=>{const f=e.droppableRects.get(m.id);if(!f)return null;const x=Et(e.collisionRect,f);return x<=0?null:{id:m.id,data:{droppableContainer:m,value:x}}}).filter(Boolean).sort((m,f)=>{var x,w;return(((x=f==null?void 0:f.data)==null?void 0:x.value)??0)-(((w=m==null?void 0:m.data)==null?void 0:w.value)??0)});return u.length>0?u:r.length>0?r:St(e)};function Ot(e,r){return r&&r.trim().length>0?r:e!=null&&e.actor?`${e.actor} session`:"Active work"}function Ut(e,r){return[(e==null?void 0:e.actor)??null,r].filter(Boolean).join(" · ")}function Ke(e){e.preventDefault(),e.stopPropagation()}function lt({task:e,goal:r,tags:l,activeRun:o,isSelected:c,isDragging:u=!1,isOverlay:m=!1,style:f,setNodeRef:x,dragAttributes:w,dragListeners:D,isMobile:k=!1,onSelect:C,onStartTask:$,onStopTask:U,onQuickReopen:_,onStepTask:B,onSplitTask:R,onOpenMenu:P,notesSummaryByEntity:q}){var X;const{t:M,formatDate:ae}=ye(),j=nt(e,o??null),z=j.stepSummary,h=I[I.indexOf(e.status)-1]??null,A=I[I.indexOf(e.status)+1]??null,oe=Ct(q,"task",e.id).count,L=e.level==="issue"?"issue":"task",ce=rt(L),te=e.level==="subtask"?"136,146,255":ce.colorToken.rgb.join(", "),V=e.dueDate&&!Number.isNaN(Date.parse(e.dueDate))?ae(e.dueDate):"No due date",J=z&&z.total>0?Math.max(8,Math.round(z.completed/z.total*100)):null,b=j.git.branch,F=j.git.branchUrl,G=j.git.pullRequestNumber?`PR #${j.git.pullRequestNumber}`:null,Q=j.git.pullRequestUrl;return t.jsxs("article",{ref:x,style:{...f,"--board-card-accent":te},className:W("w-full max-w-full min-w-0 overflow-hidden rounded-[18px] p-3 shadow-[inset_0_0_0_1px_rgba(var(--board-card-accent),0.12)] transition cursor-grab active:cursor-grabbing",k&&"touch-none select-none",m&&"rotate-[0.5deg] bg-[linear-gradient(180deg,rgba(var(--board-card-accent),0.22),rgba(var(--board-card-accent),0.08))] shadow-[var(--ui-shadow-floating)]",u&&!m&&"opacity-35 shadow-[inset_0_0_0_1px_rgba(var(--board-card-accent),0.08)]",c?"bg-[linear-gradient(180deg,rgba(var(--board-card-accent),0.18),rgba(var(--board-card-accent),0.06))] shadow-[var(--ui-shadow-soft)]":"bg-[linear-gradient(180deg,rgba(var(--board-card-accent),0.08),color-mix(in_srgb,var(--ui-surface-1)_72%,transparent))]"),"data-dragging":u?"true":"false","data-testid":`task-card-${e.id}`,onClick:()=>C(e.id),...w,...D,children:[t.jsx("div",{className:"mb-3 h-px w-full rounded-full",style:{background:`linear-gradient(90deg, rgba(${te}, 0.96), rgba(${te}, 0.18))`}}),t.jsxs("div",{className:"mb-3 flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:[t.jsx(le,{kind:L,label:e.level,compact:!0,size:"xs",gradient:!1,className:"shrink-0"}),t.jsx(S,{size:"xs",className:"shrink-0 text-[10px] text-[var(--tertiary)]",children:e.priority}),j.actor?t.jsxs(S,{size:"xs",className:"shrink-0 bg-cyan-400/12 text-[var(--info)]",children:[t.jsx(pt,{className:"mr-1 size-3"}),j.actor]}):null]}),t.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-1.5",children:[P?t.jsx("button",{type:"button","aria-label":`Open ${e.title} actions`,className:"inline-flex size-8 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)]",onClick:g=>{g.preventDefault(),g.stopPropagation(),P(g,e)},children:t.jsx(Xe,{className:"size-3.5"})}):null,k?t.jsxs("div",{className:"flex items-center gap-1",onClick:g=>g.stopPropagation(),children:[t.jsx("button",{type:"button","aria-label":`Move ${e.title} to the previous lane`,className:"inline-flex size-7 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)] disabled:opacity-35",disabled:!h,onClick:()=>{h&&(B==null||B(e.id,"previous"))},children:t.jsx(Ye,{className:"size-3.5"})}),t.jsx("button",{type:"button","aria-label":`Move ${e.title} to the next lane`,className:"inline-flex size-7 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)] disabled:opacity-35",disabled:!A,onClick:()=>{A&&(B==null||B(e.id,"next"))},children:t.jsx(Ze,{className:"size-3.5"})})]}):null,o?t.jsx("button",{type:"button","aria-label":`Stop work on ${e.title}`,className:"inline-flex size-8 items-center justify-center rounded-full bg-rose-500/16 text-[var(--danger)] transition hover:bg-rose-500/24",onClick:g=>{g.preventDefault(),g.stopPropagation(),U==null||U(o)},children:t.jsx(xt,{className:"size-3.5 fill-current"})}):e.status!=="done"?t.jsx("button",{type:"button","aria-label":`Start work on ${e.title}`,className:"inline-flex size-8 items-center justify-center rounded-full bg-[var(--primary)]/16 text-[var(--primary)] transition hover:bg-[var(--primary)]/24",onClick:g=>{g.preventDefault(),g.stopPropagation(),$==null||$(e.id)},children:t.jsx(gt,{className:"size-4 fill-current"})}):null,(X=e.splitSuggestion)!=null&&X.shouldSplit&&R?t.jsxs("button",{type:"button","aria-label":`Split ${e.title}`,className:"inline-flex items-center gap-1 rounded-full bg-amber-400/12 px-2.5 py-1 text-[10px] font-medium tracking-[0.14em] text-[var(--warning)] transition hover:bg-amber-400/18",onClick:g=>{g.preventDefault(),g.stopPropagation(),R(e.id)},children:[t.jsx(bt,{className:"size-3.5"}),"Split it"]}):null,t.jsxs("span",{className:"shrink-0 text-[11px] text-[var(--ui-ink-faint)]",children:[e.points," xp"]})]})]}),t.jsx(at,{kind:L,label:e.title,className:"max-w-full",lines:3,labelClassName:"[overflow-wrap:anywhere]"}),t.jsx("p",{className:"mt-1.5 line-clamp-3 [overflow-wrap:anywhere] text-[12px] leading-5 text-[var(--ui-ink-soft)]",children:e.description||M("common.executionBoard.noExecutionNote")}),z?t.jsxs("div",{className:"mt-3 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-3",children:[t.jsxs("div",{className:"flex items-center justify-between gap-3 text-[11px] text-[var(--ui-ink-soft)]",children:[t.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[t.jsx(ht,{className:"size-3.5 text-[var(--info)]"}),z.total," step",z.total===1?"":"s"]}),t.jsxs("span",{className:"tabular-nums text-[var(--ui-ink-soft)]",children:[z.completed,"/",z.total]})]}),t.jsx("div",{className:"mt-2 h-1.5 overflow-hidden rounded-full bg-[var(--ui-surface-2)]",children:t.jsx("div",{className:"h-full rounded-full bg-[linear-gradient(90deg,rgba(56,189,248,0.96),rgba(125,211,252,0.62))]",style:{width:`${J??0}%`}})}),t.jsx("div",{className:"mt-2 grid gap-1.5",children:z.items.slice(0,2).map(g=>t.jsx("div",{className:"truncate text-[11px] text-[var(--ui-ink-soft)]",children:g},`${e.id}-${g}`))})]}):null,t.jsxs("div",{className:"mt-2.5 flex min-w-0 flex-wrap gap-1.5",children:[b?F?t.jsxs("a",{href:F,target:"_blank",rel:"noreferrer",className:"inline-flex min-w-0 max-w-full items-center gap-1 rounded-full border border-sky-300/18 bg-sky-400/12 px-2.5 py-1 text-[11px] text-[var(--info)] transition hover:bg-sky-400/18",onClick:Ke,children:[t.jsx(ve,{className:"size-3.5 shrink-0"}),t.jsx("span",{className:"truncate",children:b})]}):t.jsxs(S,{size:"xs",className:"min-w-0 max-w-full bg-sky-400/12 text-[var(--info)]",children:[t.jsx(ve,{className:"mr-1 size-3"}),t.jsx("span",{className:"truncate",children:b})]}):null,G?Q?t.jsxs("a",{href:Q,target:"_blank",rel:"noreferrer",className:"inline-flex min-w-0 max-w-full items-center gap-1 rounded-full border border-fuchsia-300/18 bg-fuchsia-400/12 px-2.5 py-1 text-[11px] text-[var(--primary)] transition hover:bg-fuchsia-400/18",onClick:Ke,children:[t.jsx(Ue,{className:"size-3.5 shrink-0"}),t.jsx("span",{className:"truncate",children:G})]}):t.jsxs(S,{size:"xs",className:"bg-fuchsia-400/12 text-[var(--primary)]",children:[t.jsx(Ue,{className:"mr-1 size-3"}),G]}):null,j.changedFileCount>0?t.jsxs(S,{size:"xs",className:"bg-amber-400/12 text-[var(--warning)]",children:[t.jsx(vt,{className:"mr-1 size-3"}),j.changedFileCount," file",j.changedFileCount===1?"":"s"]}):null,j.git.repository?t.jsx(S,{size:"xs",className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:j.git.repository}):null]}),j.changedFilesPreview.length>0?t.jsx("div",{className:"mt-2 flex min-w-0 flex-wrap gap-1.5",children:j.changedFilesPreview.map(g=>t.jsx(S,{size:"xs",wrap:!0,className:"min-w-0 max-w-full bg-[var(--ui-surface-2)] font-mono text-[10px] text-[var(--ui-ink-soft)]",children:g},g))}):null,t.jsxs("div",{className:"mt-2.5 flex min-w-0 flex-wrap gap-1.5",children:[r?t.jsx(le,{kind:"goal",label:r.title,compact:!0,size:"xs",wrap:!0,className:"min-w-0 max-w-full"}):null,t.jsx(we,{user:e.user,compact:!0,size:"xs"}),t.jsx(zt,{entityType:"task",entityId:e.id,count:oe,compact:!0}),e.actionPointSummary?t.jsxs(S,{size:"xs",className:"bg-[var(--primary)]/12 text-[var(--primary)]",children:[Math.round(e.actionPointSummary.totalCostAp)," AP"]}):null,e.actionPointSummary?t.jsx(S,{size:"xs",className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:e.actionPointSummary.costBand}):null,e.actionPointSummary?t.jsxs(S,{size:"xs",className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:[Math.round(e.actionPointSummary.expectedDurationSeconds/3600)," ","h target"]}):null,e.time.totalCreditedSeconds>0?t.jsxs(S,{size:"xs",className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:[Math.floor(e.time.totalCreditedSeconds/60)," min"]}):null,e.time.activeRunCount>0?t.jsxs(S,{size:"xs",className:"bg-emerald-500/12 text-[var(--success)]",children:[e.time.activeRunCount," live"]}):null,l.slice(0,2).map(g=>t.jsx(S,{size:"xs",className:"bg-[var(--ui-surface-2)]",style:{color:g.color},children:g.name},g.id))]}),t.jsxs("div",{className:"mt-2.5 flex min-w-0 items-center justify-between gap-2 text-[11px] text-[var(--ui-ink-faint)]",children:[t.jsxs("span",{className:"min-w-0 truncate",children:[e.effort," / ",e.energy]}),t.jsxs("div",{className:"flex min-w-0 shrink-0 items-center gap-2 text-right",children:[e.status==="done"&&_?t.jsx("button",{type:"button",className:"rounded-full bg-[var(--ui-surface-2)] px-3 py-1 text-[10px] tracking-[0.16em] text-[var(--ui-ink-strong)] transition hover:bg-[var(--ui-surface-3)]",onClick:g=>{g.preventDefault(),g.stopPropagation(),_(e.id)},children:M("common.executionBoard.reopen")}):null,t.jsx("span",{children:V})]})]})]})}function ge(e){const{task:r,sortableId:l}=e,{attributes:o,listeners:c,setNodeRef:u,transform:m,transition:f,isDragging:x}=et({id:l,data:{type:"task",taskId:r.id,status:r.status}});return t.jsx(lt,{...e,setNodeRef:u,dragAttributes:o,dragListeners:c,isDragging:x,isMobile:e.isMobile,onStartTask:e.onStartTask,onStopTask:e.onStopTask,onStepTask:e.onStepTask,onSplitTask:e.onSplitTask,notesSummaryByEntity:e.notesSummaryByEntity,style:{transform:tt.Transform.toString(m),transition:f}})}function ot({project:e,goal:r,isDragging:l=!1,isOverlay:o=!1,style:c,setNodeRef:u,dragAttributes:m,dragListeners:f,isMobile:x=!1,onStepProject:w,onOpenMenu:D}){const{formatDate:k}=ye(),C=I[I.indexOf(e.workflowStatus)-1]??null,$=I[I.indexOf(e.workflowStatus)+1]??null,_=rt("project").colorToken.rgb.join(", "),B=e.workflowStatus.replaceAll("_"," "),R=e.status.replaceAll("_"," "),P=Bt(e.updatedAt),q=P?k(P):"No recent update";return t.jsxs("article",{ref:u,style:{...c,"--board-card-accent":_},className:W("w-full max-w-full min-w-0 overflow-hidden rounded-[18px] p-3 shadow-[inset_0_0_0_1px_rgba(var(--board-card-accent),0.12)] transition cursor-grab active:cursor-grabbing",x&&"touch-none select-none",o&&"rotate-[0.5deg] bg-[linear-gradient(180deg,rgba(var(--board-card-accent),0.22),rgba(var(--board-card-accent),0.08))] shadow-[var(--ui-shadow-floating)]",l&&!o&&"opacity-35 shadow-[inset_0_0_0_1px_rgba(var(--board-card-accent),0.08)]",!l&&!o&&"bg-[linear-gradient(180deg,rgba(var(--board-card-accent),0.08),color-mix(in_srgb,var(--ui-surface-1)_72%,transparent))]"),"data-testid":`project-card-${e.id}`,...m,...f,children:[t.jsx("div",{className:"mb-3 h-px w-full rounded-full",style:{background:`linear-gradient(90deg, rgba(${_}, 0.96), rgba(${_}, 0.18))`}}),t.jsxs("div",{className:"mb-3 flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:[t.jsx(le,{kind:"project",label:"project",compact:!0,size:"xs",gradient:!1,className:"shrink-0"}),t.jsx(S,{size:"xs",className:"shrink-0 bg-[var(--primary)]/12 text-[var(--primary)]",children:B}),t.jsx(S,{size:"xs",className:"shrink-0 bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:R})]}),t.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-1.5",children:[D?t.jsx("button",{type:"button","aria-label":`Open ${e.title} actions`,className:"inline-flex size-8 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)]",onClick:M=>{M.preventDefault(),M.stopPropagation(),D(M,e)},children:t.jsx(Xe,{className:"size-3.5"})}):null,x?t.jsxs("div",{className:"flex items-center gap-1",onClick:M=>M.stopPropagation(),children:[t.jsx("button",{type:"button","aria-label":`Move ${e.title} to the previous lane`,className:"inline-flex size-7 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)] disabled:opacity-35",disabled:!C,onClick:()=>{C&&(w==null||w(e.id,"previous"))},children:t.jsx(Ye,{className:"size-3.5"})}),t.jsx("button",{type:"button","aria-label":`Move ${e.title} to the next lane`,className:"inline-flex size-7 items-center justify-center rounded-full bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)] disabled:opacity-35",disabled:!$,onClick:()=>{$&&(w==null||w(e.id,"next"))},children:t.jsx(Ze,{className:"size-3.5"})})]}):null]})]}),t.jsx(at,{kind:"project",label:e.title,className:"max-w-full",lines:3,labelClassName:"[overflow-wrap:anywhere]"}),t.jsx("p",{className:"mt-1.5 line-clamp-3 [overflow-wrap:anywhere] text-[12px] leading-5 text-[var(--ui-ink-soft)]",children:e.description||"PRD-backed initiative spanning multiple work items."}),t.jsxs("div",{className:"mt-2.5 flex min-w-0 flex-wrap gap-1.5",children:[r?t.jsx(le,{kind:"goal",label:r.title,compact:!0,size:"xs",wrap:!0,className:"min-w-0 max-w-full"}):null,t.jsx(we,{user:e.user,compact:!0,size:"xs"}),(e.assignees??[]).slice(0,2).map(M=>t.jsx(we,{user:M,compact:!0,size:"xs"},M.id)),t.jsxs(S,{size:"xs",className:"bg-[var(--primary)]/12 text-[var(--primary)]",children:[e.progress,"% progress"]}),t.jsxs(S,{size:"xs",className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:[e.totalTasks," linked tasks"]})]}),t.jsxs("div",{className:"mt-2.5 flex min-w-0 items-center justify-between gap-2 text-[11px] text-[var(--ui-ink-faint)]",children:[t.jsx("span",{className:"min-w-0 truncate",children:e.goalTitle}),t.jsx("span",{children:q})]})]})}function be(e){const{project:r,sortableId:l}=e,{attributes:o,listeners:c,setNodeRef:u,transform:m,transition:f,isDragging:x}=et({id:l,data:{type:"project",projectId:r.id,status:r.workflowStatus}});return t.jsx(ot,{...e,setNodeRef:u,dragAttributes:o,dragListeners:c,isDragging:x,style:{transform:tt.Transform.toString(m),transition:f}})}function We({droppableId:e,status:r,title:l,detail:o,count:c,dragging:u,children:m}){const{setNodeRef:f,isOver:x}=Te({id:e,data:{type:"lane",status:r}});return t.jsx("div",{ref:f,className:W("w-full max-w-full min-w-0 overflow-hidden rounded-[24px] transition",x&&"scale-[1.005]"),"data-lane-id":r,"data-testid":`kanban-lane-${r}`,"data-lane-hover":x?"true":"false",children:t.jsxs(it,{className:W("h-full w-full max-w-full min-w-0 overflow-hidden p-3 transition-[background-color,box-shadow,border-color,transform]",u&&"border border-[var(--ui-border-subtle)]",x?"border border-[color-mix(in_srgb,var(--info)_38%,transparent)] bg-[var(--ui-info-soft)] shadow-[var(--ui-shadow-soft)]":"border border-transparent"),children:[t.jsxs("div",{className:"mb-3 flex items-start justify-between gap-3",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"type-label text-[var(--ui-ink-faint)]",children:o}),t.jsx("h3",{className:"mt-1 break-words text-[1.45rem] leading-[1] text-[var(--ui-ink-strong)]",children:l})]}),t.jsx("div",{className:"shrink-0 font-display text-[1.45rem] text-[var(--primary)]",children:c})]}),t.jsx("div",{className:W("grid w-full max-w-full min-w-0 min-h-48 content-start gap-2 rounded-[18px] p-2 transition",x?"bg-[var(--ui-info-soft)]":"bg-[var(--ui-surface-1)]"),children:m})]})})}function Pt({title:e,detail:r,children:l}){return t.jsxs("div",{className:"rounded-[20px] border border-[color-mix(in_srgb,var(--info)_24%,transparent)] bg-[var(--ui-info-soft)] p-2.5 shadow-[inset_0_0_0_1px_var(--ui-border-subtle)]",children:[t.jsx("div",{className:"mb-2 flex items-start justify-between gap-3 px-1",children:t.jsxs("div",{className:"min-w-0",children:[t.jsxs("div",{className:"inline-flex items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-[var(--info)]/86",children:[t.jsx(ve,{className:"size-3.5"}),t.jsx("span",{className:"truncate",children:e})]}),r?t.jsx("div",{className:"mt-1 text-[11px] text-[var(--ui-ink-faint)]",children:r}):null]})}),t.jsx("div",{className:"grid gap-2",children:l})]})}function qt({droppableId:e,title:r,detail:l}){const{setNodeRef:o,isOver:c}=Te({id:e,data:{type:"trash"}});return t.jsx("div",{ref:o,className:W("pointer-events-auto fixed right-4 top-4 z-50 w-[min(18rem,calc(100vw-2rem))] rounded-[28px] border px-5 py-4 shadow-[var(--ui-shadow-floating)] backdrop-blur-2xl transition lg:right-6 lg:top-6",c?"border-[color-mix(in_srgb,var(--danger)_38%,transparent)] bg-[var(--ui-danger-soft)] text-[var(--ui-ink-strong)] scale-[1.02]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-popover)] text-[var(--ui-ink-medium)]"),"data-testid":"kanban-trash-dropzone","data-trash-hover":c?"true":"false",children:t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx("div",{className:W("flex size-12 items-center justify-center rounded-full border transition",c?"border-[var(--ui-border-strong)] bg-[var(--ui-surface-3)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]"),children:t.jsx(je,{className:"size-5"})}),t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.2em] text-[var(--ui-ink-soft)]",children:"Bin"}),t.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:r}),t.jsx("div",{className:"mt-1 text-sm leading-5 text-[var(--ui-ink-soft)]",children:l})]})]})})}function Ft({tasks:e,projects:r=[],activeRuns:l=[],goals:o,tags:c,selectedTaskId:u,onMove:m,onMoveProject:f,onSelectTask:x,onStartTask:w,onStopTask:D,onQuickReopenTask:k,onDeleteTask:C,onOpenProject:$,onOpenTask:U,onEditProject:_,onEditTask:B,onLinkProject:R,onLinkTask:P,onCreateIssueForProject:q,onCreateTaskForIssue:M,onCreateSubtaskForTask:ae,onSplitTask:j,notesSummaryByEntity:z}){var _e,Be;const{t:h}=ye(),A=N.useId(),oe=`${A}:trash`,[L,ce]=N.useState(()=>typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(max-width: 1023px)").matches),te=wt(jt(It,{activationConstraint:{distance:6}})),[V,J]=N.useState(null),[b,F]=N.useState(null),[G,Q]=N.useState(null),[X,g]=N.useState(null),[Ne,ct]=N.useState(()=>typeof window>"u"?!1:window.localStorage.getItem("forge.kanban-skip-delete-confirmation")==="true"),[ke,ne]=N.useState(!1),[Se,Y]=N.useState({}),[Ie,ie]=N.useState({}),se={backlog:{title:h("common.executionBoard.laneBacklogTitle"),detail:h("common.executionBoard.laneBacklogDetail")},focus:{title:h("common.executionBoard.laneFocusTitle"),detail:h("common.executionBoard.laneFocusDetail")},in_progress:{title:h("common.executionBoard.laneProgressTitle"),detail:h("common.executionBoard.laneProgressDetail")},blocked:{title:h("common.executionBoard.laneBlockedTitle"),detail:h("common.executionBoard.laneBlockedDetail")},done:{title:h("common.executionBoard.laneDoneTitle"),detail:h("common.executionBoard.laneDoneDetail")}},Z=N.useMemo(()=>e.map(i=>{const a=Se[i.id];return a?{...i,status:a}:i}),[Se,e]),T=N.useMemo(()=>r.map(i=>{const a=Ie[i.id];return a?{...i,workflowStatus:a}:i}),[Ie,r]),Ce=N.useMemo(()=>{const i=new Map;for(const a of l){if(a.status!=="active")continue;const n=i.get(a.taskId);(!n||a.isCurrent||a.updatedAt>n.updatedAt)&&i.set(a.taskId,a)}return i},[l]),K=N.useMemo(()=>[...T.map(i=>({kind:"project",id:i.id,status:i.workflowStatus,project:i,goal:o.find(a=>a.id===i.goalId)})),...Z.map(i=>({kind:"task",id:i.id,status:i.status,task:i,goal:o.find(a=>a.id===i.goalId),tags:i.tagIds.map(a=>c.find(n=>n.id===a)).filter(Boolean),activeRun:Ce.get(i.id)??null}))],[Ce,T,Z,o,c]),O=V?K.find(i=>i.id===V)??null:null,dt=N.useMemo(()=>{if(!b)return[];if(b.kind==="project"){const a=T.find(n=>n.id===b.entityId);return a?[{id:"open-project",label:"Open",description:"Jump to the project detail view.",icon:Je,onSelect:()=>$==null?void 0:$(a.id)},{id:"edit-project",label:"Edit",description:"Open the guided project editor.",icon:Fe,onSelect:()=>_==null?void 0:_(a.id)},{id:"link-project",label:"Link",description:"Open the anchor step to relink the project to its goal.",icon:Qe,onSelect:()=>R==null?void 0:R(a.id)},{id:"create-issue",label:"Create issue",description:"Break this project into a new vertical slice issue.",icon:he,onSelect:()=>q==null?void 0:q(a.id)},...I.filter(n=>n!==a.workflowStatus).map(n=>({id:`move-project-${n}`,label:`Move to ${n.replaceAll("_"," ")}`,description:"Update the project workflow lane without leaving the board.",onSelect:()=>void(f==null?void 0:f(a.id,n))}))]:[]}const i=Z.find(a=>a.id===b.entityId);return i?Mt({task:i,onOpenTask:U,onEditTask:B,onLinkTask:P,onCreateTaskForIssue:M,onCreateSubtaskForTask:ae,onMove:m,onDeleteTask:C,deletePendingTaskId:X,onRequestDelete:$e}):[]},[T,Z,b,q,ae,M,_,B,R,P,m,f,C,$,U,X,Ne]);function ze(i){var n;if(i.length===0)return t.jsx("div",{className:"w-full max-w-full rounded-[18px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-8 text-center text-sm text-[var(--ui-ink-faint)]",children:h("common.executionBoard.emptyLane")});if(((n=i[0])==null?void 0:n.status)!=="in_progress")return i.map(d=>d.kind==="task"?t.jsx(ge,{sortableId:`${A}:task:${d.task.id}`,task:d.task,goal:d.goal,tags:d.tags,activeRun:d.activeRun,isSelected:u===d.task.id,isMobile:L,onSelect:x,onStartTask:w,onStopTask:D,onQuickReopen:k,onStepTask:de,onOpenMenu:me,onSplitTask:j,notesSummaryByEntity:z},d.task.id):t.jsx(be,{sortableId:`${A}:project:${d.project.id}`,project:d.project,goal:d.goal,isMobile:L,onStepProject:ue,onOpenMenu:fe},d.project.id));const a=new Map;for(const d of i){if(d.kind!=="task"||!d.activeRun){const E=a.get("ungrouped");E?E.items.push(d):a.set("ungrouped",{title:"Active work",detail:"Tasks in progress without a tracked branch",items:[d]});continue}const p=nt(d.task,d.activeRun),s=[d.activeRun.actor,p.git.repository??"",p.git.branch??""].join("::"),v=a.get(s);if(v){v.items.push(d);continue}a.set(s,{title:Ot(d.activeRun,p.git.branch),detail:Ut(d.activeRun,p.git.repository),items:[d]})}return Array.from(a.entries()).map(([d,p])=>d==="ungrouped"?p.items.map(s=>s.kind==="task"?t.jsx(ge,{sortableId:`${A}:task:${s.task.id}`,task:s.task,goal:s.goal,tags:s.tags,activeRun:s.activeRun,isSelected:u===s.task.id,isMobile:L,onSelect:x,onStartTask:w,onStopTask:D,onQuickReopen:k,onStepTask:de,onOpenMenu:me,onSplitTask:j,notesSummaryByEntity:z},s.task.id):t.jsx(be,{sortableId:`${A}:project:${s.project.id}`,project:s.project,goal:s.goal,isMobile:L,onStepProject:ue,onOpenMenu:fe},s.project.id)):t.jsx(Pt,{title:p.title,detail:p.detail,children:p.items.map(s=>s.kind==="task"?t.jsx(ge,{sortableId:`${A}:task:${s.task.id}`,task:s.task,goal:s.goal,tags:s.tags,activeRun:s.activeRun,isSelected:u===s.task.id,isMobile:L,onSelect:x,onStartTask:w,onStopTask:D,onQuickReopen:k,onStepTask:de,onOpenMenu:me,onSplitTask:j,notesSummaryByEntity:z},s.task.id):t.jsx(be,{sortableId:`${A}:project:${s.project.id}`,project:s.project,goal:s.goal,isMobile:L,onStepProject:ue,onOpenMenu:fe},s.project.id))},d))}N.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const i=window.matchMedia("(max-width: 1023px)"),a=n=>{ce(n?n.matches:i.matches)};return a(),typeof i.addEventListener=="function"?(i.addEventListener("change",a),()=>i.removeEventListener("change",a)):(i.addListener(a),()=>i.removeListener(a))},[]),N.useEffect(()=>{if(!V){document.body.style.cursor="";return}return document.body.style.cursor="grabbing",()=>{document.body.style.cursor=""}},[V]),N.useEffect(()=>{Y(i=>{const a=new Set(e.map(p=>p.id));let n=!1;const d={};for(const[p,s]of Object.entries(i)){const v=e.find(E=>E.id===p);if(!a.has(p)||!v||v.status===s){n=!0;continue}d[p]=s}return n?d:i})},[e]),N.useEffect(()=>{ie(i=>{const a=new Set(r.map(p=>p.id));let n=!1;const d={};for(const[p,s]of Object.entries(i)){const v=r.find(E=>E.id===p);if(!a.has(p)||!v||v.workflowStatus===s){n=!0;continue}d[p]=s}return n?d:i})},[r]);function ut(i){var d,p;const a=(d=i.active.data.current)==null?void 0:d.taskId,n=(p=i.active.data.current)==null?void 0:p.projectId;typeof a=="string"?J(a):typeof n=="string"&&J(n)}const mt=i=>{ct(i),typeof window<"u"&&window.localStorage.setItem("forge.kanban-skip-delete-confirmation","true")},De=async(i,a)=>{if(C){g(i.id);try{a&&mt(!0),await C(i.id),Q(null),ne(!1),Y(n=>{const d={...n};return delete d[i.id],d})}finally{g(null)}}};function $e(i){if(C){if(Ne){De(i,!1);return}ne(!1),Q(i)}}async function ft(i){var Me,Ae,Le,Ee,Re,Oe;const{active:a,over:n}=i;if(J(null),!n||a.id===n.id)return;const d=typeof((Me=a.data.current)==null?void 0:Me.taskId)=="string"?a.data.current.taskId:null,p=typeof((Ae=a.data.current)==null?void 0:Ae.projectId)=="string"?a.data.current.projectId:null,s=(d?K.find(y=>y.kind==="task"&&y.id===d):null)??(p?K.find(y=>y.kind==="project"&&y.id===p):null);if(!s)return;if(((Le=n.data.current)==null?void 0:Le.type)==="trash"){if(s.kind!=="task"||!C)return;$e(s.task);return}const v=typeof((Ee=n.data.current)==null?void 0:Ee.status)=="string"?n.data.current.status:null,E=typeof((Re=n.data.current)==null?void 0:Re.taskId)=="string"?n.data.current.taskId:null,H=typeof((Oe=n.data.current)==null?void 0:Oe.projectId)=="string"?n.data.current.projectId:null,pe=(E?K.find(y=>y.kind==="task"&&y.id===E):null)??(H?K.find(y=>y.kind==="project"&&y.id===H):null),ee=v??(pe==null?void 0:pe.status)??s.status;if(!(ee===s.status||!I.includes(ee))){if(s.kind==="task"){Y(y=>({...y,[s.task.id]:ee}));try{await m(s.task.id,ee)}catch(y){throw Y(xe=>{const re={...xe};return delete re[s.task.id],re}),y}return}if(f){ie(y=>({...y,[s.project.id]:ee}));try{await f(s.project.id,ee)}catch(y){throw ie(xe=>{const re={...xe};return delete re[s.project.id],re}),y}}}}async function de(i,a){const n=Z.find(v=>v.id===i);if(!n)return;const d=I.indexOf(n.status),p=a==="previous"?d-1:d+1,s=I[p]??null;if(!(!s||s===n.status)){Y(v=>({...v,[n.id]:s}));try{await m(n.id,s)}catch(v){throw Y(E=>{const H={...E};return delete H[n.id],H}),v}}}async function ue(i,a){const n=T.find(v=>v.id===i);if(!n||!f)return;const d=I.indexOf(n.workflowStatus),p=a==="previous"?d-1:d+1,s=I[p]??null;if(!(!s||s===n.workflowStatus)){ie(v=>({...v,[n.id]:s}));try{await f(n.id,s)}catch(v){throw ie(E=>{const H={...E};return delete H[n.id],H}),v}}}function me(i,a){const n=i.currentTarget.getBoundingClientRect();F({kind:"task",entityId:a.id,position:{x:n.right-8,y:n.bottom+8}})}function fe(i,a){const n=i.currentTarget.getBoundingClientRect();F({kind:"project",entityId:a.id,position:{x:n.right-8,y:n.bottom+8}})}return t.jsxs(yt,{sensors:te,collisionDetection:Rt,onDragStart:ut,onDragCancel:()=>J(null),onDragEnd:i=>void ft(i),children:[(O==null?void 0:O.kind)==="task"&&C?t.jsx(qt,{droppableId:oe,title:h("common.executionBoard.deleteDropTitle"),detail:h("common.executionBoard.deleteDropDetail")}):null,t.jsx("div",{className:"w-full max-w-full min-w-0 pb-2",children:L?t.jsx("div",{className:"grid w-full max-w-full min-w-0 gap-2",children:I.map(i=>{const a=K.filter(n=>n.status===i);return t.jsx(Pe,{items:a.map(n=>`${A}:${n.kind}:${n.id}`),strategy:qe,children:t.jsx(We,{droppableId:`${A}:lane:${i}`,status:i,title:se[i].title,detail:se[i].detail,count:a.length,dragging:V!==null,children:ze(a)})},i)})}):t.jsx("div",{className:"grid w-full min-w-0 gap-0.5 xl:grid-cols-[repeat(5,minmax(0,1fr))]",children:I.map(i=>{const a=K.filter(n=>n.status===i);return t.jsx(Pe,{items:a.map(n=>`${A}:${n.kind}:${n.id}`),strategy:qe,children:t.jsx(We,{droppableId:`${A}:lane:${i}`,status:i,title:se[i].title,detail:se[i].detail,count:a.length,dragging:V!==null,children:ze(a)})},i)})})}),t.jsx(Nt,{adjustScale:!1,dropAnimation:null,children:O?t.jsx("div",{className:"w-[20rem] max-w-[calc(100vw-2rem)]",children:O.kind==="task"?t.jsx(lt,{task:O.task,goal:O.goal,tags:O.tags,activeRun:O.activeRun,isSelected:u===O.task.id,isDragging:!0,isOverlay:!0,isMobile:L,onSelect:()=>{},onStartTask:w,onSplitTask:j,notesSummaryByEntity:z}):t.jsx(ot,{project:O.project,goal:O.goal,isDragging:!0,isOverlay:!0,isMobile:L})}):null}),t.jsx(Dt,{open:b!==null,title:(b==null?void 0:b.kind)==="project"?((_e=T.find(i=>i.id===b.entityId))==null?void 0:_e.title)??"Project actions":((Be=Z.find(i=>i.id===(b==null?void 0:b.entityId)))==null?void 0:Be.title)??"Work item actions",subtitle:(b==null?void 0:b.kind)==="project"?"Edit, relink, move, or break this project into issues.":"Edit, relink, move, or create the next child work item.",items:dt,position:(b==null?void 0:b.position)??null,onClose:()=>F(null)}),G?t.jsx("div",{className:"surface-overlay fixed inset-0 z-[60] flex items-center justify-center p-4 backdrop-blur-xl",children:t.jsxs(it,{className:"surface-modal-panel w-full max-w-md",children:[t.jsxs("div",{className:"flex items-start gap-3",children:[t.jsx("div",{className:"mt-1 flex size-11 shrink-0 items-center justify-center rounded-full bg-[var(--ui-danger-soft)] text-[var(--danger)]",children:t.jsx(je,{className:"size-5"})}),t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"font-display text-[1.35rem] leading-tight text-[var(--ui-ink-strong)]",children:h("common.executionBoard.deleteConfirmTitle")}),t.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:h("common.executionBoard.deleteConfirmDescription",{title:G.title})})]})]}),t.jsxs("label",{className:"mt-5 flex items-center gap-3 rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:[t.jsx("input",{type:"checkbox",checked:ke,onChange:i=>ne(i.target.checked),className:"size-4 rounded border-[var(--ui-border-strong)] bg-transparent text-[var(--primary)]"}),t.jsx("span",{children:h("common.executionBoard.deleteConfirmCheckbox")})]}),t.jsxs("div",{className:"mt-5 flex flex-wrap justify-end gap-3",children:[t.jsx(Ve,{variant:"secondary",onClick:()=>{Q(null),ne(!1)},children:h("common.executionBoard.deleteConfirmCancel")}),t.jsx(Ve,{className:"bg-[var(--ui-danger-soft)] text-[var(--danger)] shadow-[var(--ui-shadow-soft)]",pending:X===G.id,pendingLabel:h("common.executionBoard.deletingTask"),onClick:()=>void De(G,ke),children:h("common.executionBoard.deleteConfirmSubmit")})]})]})}):null]})}export{Ft as E};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as p,j as e,aC as b,b_ as P,bW as C}from"./vendor-BwL6m4SE.js";import{P as S}from"./page-hero-BLhM8FF3.js";import{E as G}from"./entity-note-count-link-xne6mshj.js";import{C as k,B as y,b as w,E as h,k as l,c as N,d as E,h as z,R as L,P as T}from"./index-izRKx6JK.js";import{GoalDialog as B}from"./goal-dialog-DH50D0tP.js";import{P as I}from"./pill-cluster-B5bYs_e2.js";import{b as R,f as D,P as F}from"./project-collections-FfBIVwXu.js";import{U}from"./user-badge-MEZuJiir.js";import{g as M}from"./user-ownership-DJGl4rAj.js";import"./state-Bpe5dF3T.js";import"./motion-DcgUnXhY.js";import"./ui-B9TWEtCx.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";import"./question-flow-dialog-D-_EvoAt.js";import"./inline-note-fields-D4mCM1gO.js";import"./user-select-field-fx129Uh6.js";import"./schemas-B0Pa-V-A.js";function O({goals:t,tags:r,users:o,defaultUserId:d=null,pending:c=!1,onCreate:n,onUpdate:v}){const[f,m]=p.useState(!1),[g,u]=p.useState(null),a=t.find(s=>s.id===g)??null;return e.jsxs(e.Fragment,{children:[e.jsxs(k,{children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Goal arcs"}),e.jsx("h3",{className:"mt-2 font-display text-3xl text-[var(--ui-ink-strong)]",children:"Strategic arcs before tickets"}),e.jsx("p",{className:"mt-3 max-w-3xl text-sm leading-7 text-[var(--ui-ink-soft)]",children:"This is the long-horizon map. Each arc shows why it matters, how much ground has been covered, and which project should move next."})]}),e.jsx(y,{onClick:()=>{u(null),m(!0)},children:"Create goal"})]}),e.jsxs("div",{className:"mt-5 grid gap-3 xl:grid-cols-2",children:[t.length===0?e.jsx("div",{className:"rounded-[24px] bg-[var(--ui-surface-2)] p-5 text-sm leading-7 text-[var(--ui-ink-soft)] xl:col-span-2",children:"Start with a life goal. Once the destination is clear, you can attach projects and then fill those projects with tasks."}):null,t.map(s=>{const x=`${Math.max(6,Math.min(100,s.progress))}%`;return e.jsxs(b,{to:`/goals/${s.id}`,className:"rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 transition hover:bg-[var(--ui-surface-hover)]",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx(w,{kind:"goal",compact:!0,gradient:!1}),e.jsx("div",{className:"mt-2",children:e.jsx(h,{kind:"goal",label:s.title,variant:"heading",size:"lg",showKind:!1,lines:2})}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:s.description||"No strategic note attached yet."})]}),e.jsx("button",{className:"rounded-full bg-[var(--ui-surface-2)] p-2 text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",type:"button",onClick:i=>{i.preventDefault(),i.stopPropagation(),u(s.id),m(!0)},children:e.jsx(P,{className:"size-4"})})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx(l,{className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:s.horizon}),e.jsx(l,{className:s.status==="active"?"text-[var(--success)]":s.status==="paused"?"text-[var(--warning)]":"text-[var(--tertiary)]",children:s.status}),e.jsxs(l,{className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:[s.earnedPoints," / ",s.targetPoints," xp"]}),e.jsxs(l,{className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:[s.totalTasks," tasks"]})]}),e.jsx("div",{className:"mt-4 h-1.5 rounded-full bg-[var(--ui-surface-2)]",children:e.jsx("div",{className:"h-full rounded-full bg-[var(--primary)]",style:{width:x}})}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:s.tags.map(i=>e.jsx(l,{className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:i.name},i.id))}),e.jsxs("div",{className:"mt-3 flex items-center justify-between gap-3 text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:[e.jsx("span",{className:"min-w-0 flex-1 truncate",children:s.momentumLabel}),e.jsxs("span",{className:"inline-flex shrink-0 items-center gap-2",style:{color:s.themeColor},children:["Open arc",e.jsx(C,{className:"size-3.5"})]})]})]},s.id)})]})]}),e.jsx(B,{open:f,pending:c,editingGoal:a,tags:r,users:o,defaultUserId:d,onOpenChange:s=>{m(s),s||u(null)},onSubmit:async(s,x)=>{if(x){await v(x,s);return}await n(s)}})]})}function $({eyebrow:t,title:r,description:o,meta:d,actions:c,className:n}){return e.jsxs("div",{className:N("flex flex-wrap items-start justify-between gap-3",n),children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[t?e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:t}):null,e.jsxs("div",{className:N("min-w-0",t&&"mt-2"),children:[e.jsx("div",{className:"min-w-0 text-lg text-[var(--ui-ink-strong)]",children:r}),o?e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:o}):null]})]}),d||c?e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-2",children:[d,c]}):null]})}function ne(){const t=E(),[r,o]=p.useState("active"),[d,c]=p.useState(null),n=t.snapshot.dashboard.goals.length>0,v=R(t.snapshot.dashboard.projects),f=D(t.snapshot.dashboard.projects,r),m=M(t.selectedUserIds),g=new Map(t.snapshot.dashboard.goals.map(a=>[a.id,f.filter(s=>s.goalId===a.id)])),u=async a=>{c(a);try{await t.patchProject(a,{status:"active"})}finally{c(null)}};return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(S,{entityKind:"goal",title:e.jsx(h,{kind:"goal",label:"Life Goals",variant:"heading",size:"lg"}),titleText:"Life Goals",description:"Life goals are the destinations you care about over the long run. Each one can hold several projects, and those projects turn direction into real work.",badge:`${t.snapshot.dashboard.goals.length} active goals`,actions:n?e.jsxs("div",{className:"inline-flex min-h-10 items-center rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-2 text-sm whitespace-nowrap text-[var(--ui-ink-soft)]",children:[t.snapshot.dashboard.projects.length," live project",t.snapshot.dashboard.projects.length===1?"":"s"," ","attached"]}):null}),e.jsx(O,{goals:t.snapshot.dashboard.goals,tags:t.snapshot.tags,users:t.snapshot.users,defaultUserId:m,onCreate:t.createGoal,onUpdate:t.patchGoal}),n?e.jsx(F,{value:r,counts:v,onChange:o}):null,n?null:e.jsx(z,{eyebrow:"Life goals",title:"No life goals yet",description:"Define the first long-horizon direction above so Forge can attach projects, tasks, momentum, and evidence to something meaningful."}),n?e.jsx("div",{className:"grid gap-4",children:t.snapshot.dashboard.goals.map(a=>{const s=g.get(a.id)??[],x=L(t.snapshot.dashboard.notesSummaryByEntity,"goal",a.id);return e.jsx(b,{to:`/goals/${a.id}`,className:"min-w-0 overflow-hidden rounded-[28px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 transition hover:bg-[var(--ui-surface-hover)] sm:p-5",children:e.jsxs("div",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)] xl:gap-5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs(I,{children:[a.tags.slice(0,3).map(i=>e.jsx(l,{className:"bg-[var(--ui-surface-2)]",style:{color:i.color},children:i.name},i.id)),e.jsx(l,{className:"bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",children:a.horizon}),e.jsx(U,{user:a.user,compact:!0})]}),e.jsx("div",{className:"mt-4",children:e.jsx(h,{kind:"goal",label:a.title,variant:"heading",size:"xl",lines:2})}),e.jsx("p",{className:"mt-3 max-w-2xl text-sm leading-7 text-[var(--ui-ink-soft)]",children:a.description}),e.jsxs("div",{className:"mt-4 grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-3.5 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:"Progress"}),e.jsxs("div",{className:"mt-2 text-xl text-[var(--ui-ink-strong)]",children:[a.progress,"%"]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-3.5 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:"Tasks done"}),e.jsxs("div",{className:"mt-2 text-xl text-[var(--ui-ink-strong)]",children:[a.completedTasks,"/",Math.max(a.totalTasks,1)]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-3.5 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:"XP banked"}),e.jsx("div",{className:"mt-2 text-xl text-[var(--ui-ink-strong)]",children:a.earnedPoints})]})]}),e.jsx("div",{className:"mt-4",children:e.jsx(T,{value:a.progress})}),e.jsx("div",{className:"mt-4",children:e.jsx(G,{entityType:"goal",entityId:a.id,count:x.count})})]}),e.jsxs("div",{className:"min-w-0 rounded-[24px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx($,{title:"Projects carrying this direction",meta:e.jsx("div",{className:"shrink-0 text-sm text-[var(--ui-ink-faint)]",children:s.length}),className:"gap-2"}),s.length===0?e.jsx("div",{className:"mt-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:r==="active"?"No active project is attached yet. Create one so this direction starts producing visible work.":"No projects in this lifecycle view are attached yet. Switch filters or restart one to bring it back into active motion."}):e.jsx("div",{className:"mt-4 grid gap-3",children:s.slice(0,3).map(i=>e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-hover)] px-4 py-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 items-center gap-2",children:[e.jsx(w,{kind:"project",compact:!0,gradient:!1}),e.jsx(h,{kind:"project",label:i.title,className:"min-w-0",showIcon:!1,lines:2})]}),e.jsx(l,{className:"shrink-0",children:i.status})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:i.description}),e.jsxs("div",{className:"mt-3 text-sm text-[var(--ui-ink-faint)]",children:["Next move:"," ",i.nextTaskTitle??"Define the first attached task"]}),r!=="active"&&i.status!=="active"?e.jsx("div",{className:"mt-4 flex justify-end",children:e.jsx(y,{variant:"secondary",size:"sm",pending:d===i.id,pendingLabel:"Restarting…",onClick:j=>{j.preventDefault(),j.stopPropagation(),u(i.id)},children:"Restart"})}):null]},i.id))})]})]})},a.id)})}):e.jsx(k,{children:e.jsx("div",{className:"rounded-[20px] bg-[var(--ui-surface-2)] p-4 text-sm text-[var(--ui-ink-soft)]",children:"Goal cards will appear here once the first long-horizon direction is created."})})]})}export{ne as GoalsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as p,j as e,bY as Ye,aG as Ze,c7 as Je,aV as Ve,c8 as es,c1 as ss,b$ as Ce,bF as Ie,c9 as Pe,ca as as,aK as De,cb as ts,cc as rs,cd as is,ce as ns}from"./vendor-BwL6m4SE.js";import{R as Le,P as Se,O as Te,C as He,T as Ee,D as Ae,a as Be}from"./ui-B9TWEtCx.js";import{j as ls,i as me,k as ge}from"./state-Bpe5dF3T.js";import{E as os}from"./entity-note-count-link-xne6mshj.js";import{N as ds}from"./note-markdown-BWedRE3c.js";import{I as q,T as ve,b as F,d as cs,U as xe,V as us,B as L,E as Fe,C as A,n as U,m as Me,h as ms,R as gs,c as P,k as v,W as xs,X as hs,Y as Ke,Z as bs,_ as vs,$ as ps,a0 as fs,a1 as ks,a2 as ys,O as js}from"./index-izRKx6JK.js";import{u as ws,p as _s}from"./use-psyche-focus-target-BhNedCZB.js";import{P as Ns}from"./page-hero-BLhM8FF3.js";import{Q as Cs,F as b,a as oe}from"./question-flow-dialog-D-_EvoAt.js";import{U as Is}from"./user-select-field-fx129Uh6.js";import{a as Ps,c as Ds,g as Ls}from"./user-ownership-DJGl4rAj.js";import{h as Ss}from"./schemas-B0Pa-V-A.js";import{S as Ts}from"./select-menu-DcS4Ukjf.js";import{U as Hs}from"./user-badge-MEZuJiir.js";import{f as Es}from"./date-keys-BnZV4PNO.js";import"./motion-DcgUnXhY.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const he={title:"",description:"",status:"active",userId:null,polarity:"positive",frequency:"daily",targetCount:1,weekDays:[],linkedGoalIds:[],linkedProjectIds:[],linkedTaskIds:[],linkedValueIds:[],linkedPatternIds:[],linkedBehaviorIds:[],linkedBeliefIds:[],linkedModeIds:[],linkedReportIds:[],linkedBehaviorId:"",rewardXp:12,penaltyXp:8,generatedHealthEventTemplate:{enabled:!1,workoutType:"workout",title:"",durationMinutes:45,xpReward:0,tags:[],links:[],notesTemplate:""}},As=[{value:1,label:"Mon"},{value:2,label:"Tue"},{value:3,label:"Wed"},{value:4,label:"Thu"},{value:5,label:"Fri"},{value:6,label:"Sat"},{value:0,label:"Sun"}];function Bs(s){return{title:s.title,description:s.description,status:s.status,userId:s.userId??null,polarity:s.polarity,frequency:s.frequency,targetCount:s.targetCount,weekDays:s.weekDays,linkedGoalIds:s.linkedGoalIds,linkedProjectIds:s.linkedProjectIds,linkedTaskIds:s.linkedTaskIds,linkedValueIds:s.linkedValueIds,linkedPatternIds:s.linkedPatternIds,linkedBehaviorIds:s.linkedBehaviorIds,linkedBeliefIds:s.linkedBeliefIds,linkedModeIds:s.linkedModeIds,linkedReportIds:s.linkedReportIds,linkedBehaviorId:s.linkedBehaviorId??"",rewardXp:s.rewardXp,penaltyXp:s.penaltyXp,generatedHealthEventTemplate:s.generatedHealthEventTemplate}}function Fs({open:s,pending:o=!1,editingHabit:d,values:f,patterns:k,behaviors:T,beliefs:c,modes:y,reports:m,goals:j,projects:H,tasks:D,users:M,defaultUserId:w=null,onOpenChange:N,onSubmit:E}){const[R,S]=p.useState(he),[te,K]=p.useState(null),[C,Z]=p.useState({});p.useEffect(()=>{s&&(S(d?Bs(d):{...he,userId:w}),K(null),Z({}))},[w,d,s]);const O=M.find(r=>r.id===w)??null,$=p.useMemo(()=>T.slice().sort((r,i)=>r.title.localeCompare(i.title)),[T]),I=r=>({linkedBehaviorIds:r,linkedBehaviorId:r[0]??""}),_=(r,i)=>r.includes(i)?r.filter(t=>t!==i):[...r,i],G=[{id:"intent",eyebrow:"Habit",title:"Name the recurring move",description:"Use habits for recurring commitments and recurring slips. Keep the title concrete so the daily check-in never needs interpretation.",render:(r,i)=>e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Title",error:C.title??null,children:e.jsx(q,{value:r.title,onChange:t=>i({title:t.target.value}),placeholder:"Train lower body"})}),e.jsx(b,{label:"Description",children:e.jsx(ve,{value:r.description,onChange:t=>i({description:t.target.value}),placeholder:"Write the habit description in Markdown. Define what counts, edge cases, and examples."})}),e.jsx(Is,{value:r.userId,users:M,onChange:t=>i({userId:t}),label:"Owner user",defaultLabel:Ps(O),help:"Habits can be owned by humans or bots. When one scoped user is active, Forge uses that as the default."})]})},{id:"shape",eyebrow:"Shape",title:"Set direction and cadence",description:"Forge uses polarity to decide whether doing the habit is good or bad, and cadence to know when it should show up.",render:(r,i)=>e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Polarity",children:e.jsx(oe,{value:r.polarity,onChange:t=>i({polarity:t}),options:[{value:"positive",label:"Positive",description:"Doing it is aligned and should award XP."},{value:"negative",label:"Negative",description:"Doing it is a slip and should cost XP."}],columns:2})}),e.jsx(b,{label:"Frequency",children:e.jsx(oe,{value:r.frequency,onChange:t=>i({frequency:t}),options:[{value:"daily",label:"Daily",description:"Track against each day."},{value:"weekly",label:"Weekly",description:"Track only on the selected weekdays."}],columns:2})}),r.frequency==="weekly"?e.jsx(b,{label:"Weekdays",error:C.weekDays??null,children:e.jsx("div",{className:"flex flex-wrap gap-2",children:As.map(t=>{const n=r.weekDays.includes(t.value);return e.jsx("button",{type:"button",className:`rounded-full border px-3 py-2 text-sm transition ${n?"border-[color-mix(in_srgb,var(--primary)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]"}`,onClick:()=>i({weekDays:n?r.weekDays.filter(J=>J!==t.value):[...r.weekDays,t.value].sort()}),children:t.label},t.value)})})}):null,e.jsx(b,{label:"Status",children:e.jsx(oe,{value:r.status,onChange:t=>i({status:t}),options:[{value:"active",label:"Active",description:"Show it in the daily operating flow."},{value:"paused",label:"Paused",description:"Keep it visible but not currently due."},{value:"archived",label:"Archived",description:"Keep the record but retire it from active work."}]})})]})},{id:"generation",eyebrow:"Generation",title:"Decide whether this habit should create a workout record",description:"Use this when a completed habit should generate a structured sports or recovery session in Forge, then reconcile with HealthKit later if the same session gets imported.",render:(r,i)=>e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Generate workout record",children:e.jsx(oe,{value:r.generatedHealthEventTemplate.enabled?"enabled":"disabled",onChange:t=>i({generatedHealthEventTemplate:{...r.generatedHealthEventTemplate,enabled:t==="enabled"}}),options:[{value:"disabled",label:"Disabled",description:"This habit only affects the habit ledger."},{value:"enabled",label:"Enabled",description:"A completed check-in creates a workout or recovery session."}],columns:2})}),r.generatedHealthEventTemplate.enabled?e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Workout type",children:e.jsx(q,{value:r.generatedHealthEventTemplate.workoutType,onChange:t=>i({generatedHealthEventTemplate:{...r.generatedHealthEventTemplate,workoutType:t.target.value}}),placeholder:"mobility, walk, strength, recovery"})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(b,{label:"Duration (minutes)",children:e.jsx(q,{type:"number",min:1,max:1440,value:r.generatedHealthEventTemplate.durationMinutes,onChange:t=>i({generatedHealthEventTemplate:{...r.generatedHealthEventTemplate,durationMinutes:Number(t.target.value)||45}})})}),e.jsx(b,{label:"Workout XP",children:e.jsx(q,{type:"number",min:0,max:500,value:r.generatedHealthEventTemplate.xpReward,onChange:t=>i({generatedHealthEventTemplate:{...r.generatedHealthEventTemplate,xpReward:Number(t.target.value)||0}})})})]}),e.jsx(b,{label:"Generated session note",children:e.jsx(ve,{value:r.generatedHealthEventTemplate.notesTemplate,onChange:t=>i({generatedHealthEventTemplate:{...r.generatedHealthEventTemplate,notesTemplate:t.target.value}}),placeholder:"Morning routine session generated from habit completion."})})]}):null]})},{id:"links",eyebrow:"Links",title:"Connect the habit to real Forge work",description:"Link habits to the goals, projects, and tasks they support so they stay anchored in the same operating graph as everything else.",render:(r,i)=>e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Goals",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:j.map(t=>{const n=r.linkedGoalIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedGoalIds:_(r.linkedGoalIds,t.id)}),children:e.jsx(F,{kind:"goal",label:t.title,gradient:n,className:n?"":"opacity-75"})},t.id)})})}),e.jsx(b,{label:"Projects",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:H.map(t=>{const n=r.linkedProjectIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedProjectIds:_(r.linkedProjectIds,t.id)}),children:e.jsx(F,{kind:"project",label:t.title,gradient:n,className:n?"":"opacity-75"})},t.id)})})}),e.jsx(b,{label:"Tasks",children:e.jsx("div",{className:"flex max-h-48 flex-wrap gap-2 overflow-y-auto",children:D.map(t=>{const n=r.linkedTaskIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedTaskIds:_(r.linkedTaskIds,t.id)}),children:e.jsx(F,{kind:"task",label:t.title,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})}),e.jsx(b,{label:"Values",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:f.map(t=>{const n=r.linkedValueIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedValueIds:_(r.linkedValueIds,t.id)}),children:e.jsx(F,{kind:"value",label:t.title,gradient:n,className:n?"":"opacity-75"})},t.id)})})}),e.jsx(b,{label:"Patterns",children:e.jsx("div",{className:"flex max-h-44 flex-wrap gap-2 overflow-y-auto",children:k.map(t=>{const n=r.linkedPatternIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedPatternIds:_(r.linkedPatternIds,t.id)}),children:e.jsx(F,{kind:"pattern",label:t.title,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})})]})},{id:"reward",eyebrow:"Reward",title:"Link the behavior and XP logic",description:"Habits can point back to a Psyche behavior. Reward XP is granted for aligned outcomes; penalty XP is applied for misaligned ones.",render:(r,i)=>e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"Linked behavior",children:e.jsx("div",{className:"flex max-h-44 flex-wrap gap-2 overflow-y-auto",children:$.map(t=>{const n=r.linkedBehaviorIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i(I(_(r.linkedBehaviorIds,t.id))),children:e.jsx(F,{kind:"behavior",label:t.title,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})}),e.jsx(b,{label:"Beliefs",children:e.jsx("div",{className:"flex max-h-44 flex-wrap gap-2 overflow-y-auto",children:c.map(t=>{const n=r.linkedBeliefIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedBeliefIds:_(r.linkedBeliefIds,t.id)}),children:e.jsx(F,{kind:"belief",label:t.statement,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})}),e.jsx(b,{label:"Modes",children:e.jsx("div",{className:"flex max-h-44 flex-wrap gap-2 overflow-y-auto",children:y.map(t=>{const n=r.linkedModeIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedModeIds:_(r.linkedModeIds,t.id)}),children:e.jsx(F,{kind:"mode",label:t.title,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})}),e.jsx(b,{label:"Reports",children:e.jsx("div",{className:"flex max-h-44 flex-wrap gap-2 overflow-y-auto",children:m.map(t=>{const n=r.linkedReportIds.includes(t.id);return e.jsx("button",{type:"button",onClick:()=>i({linkedReportIds:_(r.linkedReportIds,t.id)}),children:e.jsx(F,{kind:"report",label:t.title,gradient:n,className:n?"":"opacity-75",wrap:!0})},t.id)})})}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-3",children:[e.jsx(b,{label:"Target count",error:C.targetCount??null,children:e.jsx(q,{type:"number",value:r.targetCount,onChange:t=>i({targetCount:Number(t.target.value)||1})})}),e.jsx(b,{label:"Reward XP",error:C.rewardXp??null,children:e.jsx(q,{type:"number",value:r.rewardXp,onChange:t=>i({rewardXp:Number(t.target.value)||1})})}),e.jsx(b,{label:"Penalty XP",error:C.penaltyXp??null,children:e.jsx(q,{type:"number",value:r.penaltyXp,onChange:t=>i({penaltyXp:Number(t.target.value)||1})})})]})]})}];return e.jsx(Cs,{open:s,onOpenChange:N,eyebrow:"Habit",title:d?"Edit habit":"Create habit",description:"Habits are recurring commitments or recurring slips with explicit XP consequences.",value:R,onChange:S,draftPersistenceKey:d?`habit.${d.id}`:"habit.new",steps:G,pending:o,pendingLabel:d?"Save habit":"Create habit",submitLabel:d?"Save habit":"Create habit",error:te,onSubmit:async()=>{K(null);const r=Ss.safeParse(R);if(!r.success){Z(Object.fromEntries(Object.entries(r.error.flatten().fieldErrors).map(([i,t])=>[i,t==null?void 0:t[0]]))),K("Some habit fields still need attention.");return}Z({});try{await E(r.data,d==null?void 0:d.id),S(he),N(!1)}catch(i){K(i instanceof Error?i.message:"Habit update failed.")}}})}const Ms=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Ks=["S","M","T","W","T","F","S"],Xs=[{value:"name",label:"Name A-Z",description:"Keep the list stable alphabetically."},{value:"needs_attention",label:"Needs attention",description:"Bubble up habits still waiting on today."},{value:"streak",label:"Longest streak",description:"Put the strongest current streaks first."},{value:"created_at",label:"Newest created",description:"Show the most recently created habits first."},{value:"updated_at",label:"Recently updated",description:"Sort by the most recently changed habits."}];function Rs(s){return s.frequency==="daily"?`${s.targetCount}x daily`:`${s.targetCount}x weekly · ${s.weekDays.map(o=>Ms[o]).join(", ")}`}function W(s){return Es(s)}function $e(s){const[o,d,f]=s.split("-").map(Number);return new Date(o,d-1,f)}function ze(s){return new Date(s.getFullYear(),s.getMonth(),s.getDate())}function de(s,o){const d=new Date(s);return d.setDate(d.getDate()+o),d}function Xe(s){const o=ze(s),d=(o.getDay()+6)%7;return o.setDate(o.getDate()-d),o}function ee(s){const o=typeof s=="string"?$e(s):s;return new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric"}).format(o)}function ue(s,o){return s.polarity==="positive"&&o==="done"||s.polarity==="negative"&&o==="missed"}function pe(s,o){return s.polarity==="positive"?o==="done"?"Done":"Missed":o==="done"?"Performed":"Resisted"}function qe(s){const o=W(new Date),d=s.checkIns.find(f=>f.dateKey===o)??null;return s.dueToday?{tone:"pending",label:s.frequency==="daily"?"Waiting for today":"Awaiting this week's check-in",cardClass:"border-[color-mix(in_srgb,var(--warning)_28%,var(--ui-border-subtle)_72%)] shadow-[var(--ui-shadow-soft)]",overlayClass:"bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--warning)_18%,transparent),transparent_44%)]",pillClass:"border border-[color-mix(in_srgb,var(--warning)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]"}:d?ue(s,d.status)?{tone:"aligned",label:`${pe(s,d.status)} today`,cardClass:"border-[color-mix(in_srgb,var(--success)_24%,var(--ui-border-subtle)_76%)] shadow-[var(--ui-shadow-soft)]",overlayClass:"bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--success)_16%,transparent),transparent_44%)]",pillClass:"border border-[color-mix(in_srgb,var(--success)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]"}:{tone:"unaligned",label:`${pe(s,d.status)} today`,cardClass:"border-[color-mix(in_srgb,var(--danger)_24%,var(--ui-border-subtle)_76%)] shadow-[var(--ui-shadow-soft)]",overlayClass:"bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--danger)_16%,transparent),transparent_44%)]",pillClass:"border border-[color-mix(in_srgb,var(--danger)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]"}:s.polarity==="positive"?{tone:"neutral",label:"No update due right now",cardClass:"",overlayClass:"bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--success)_9%,transparent),transparent_40%)]",pillClass:"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]"}:{tone:"neutral",label:"No update due right now",cardClass:"",overlayClass:"bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--danger)_9%,transparent),transparent_40%)]",pillClass:"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]"}}function Os(s){return s>=10?{Icon:ts,className:"border border-[color-mix(in_srgb,var(--warning)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)] shadow-[var(--ui-shadow-soft)]",iconClass:"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",valueClass:"text-[var(--ui-ink-strong)]",label:"Celebration pace"}:s>=5?{Icon:rs,className:"border border-[color-mix(in_srgb,var(--success)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)]",iconClass:"text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]",valueClass:"text-[var(--ui-ink-strong)]",label:"Locked in"}:s>=1?{Icon:is,className:"border border-[color-mix(in_srgb,var(--info)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-info-soft)] text-[color-mix(in_srgb,var(--info)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)]",iconClass:"text-[color-mix(in_srgb,var(--info)_76%,var(--ui-ink-strong)_24%)]",valueClass:"text-[var(--ui-ink-strong)]",label:"Building rhythm"}:{Icon:ns,className:"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] shadow-[var(--ui-shadow-soft)]",iconClass:"text-[var(--ui-ink-soft)]",valueClass:"text-[var(--ui-ink-strong)]",label:"Cold start"}}function $s(s){return s>=80?"border-[color-mix(in_srgb,var(--success)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":s>=50?"border-[color-mix(in_srgb,var(--warning)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]":"border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]"}const se="border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-medium)]",Re="border-[color-mix(in_srgb,var(--success)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]",Oe="border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]",ce="border-[color-mix(in_srgb,var(--warning)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",be="border-[color-mix(in_srgb,var(--info)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-info-soft)] text-[color-mix(in_srgb,var(--info)_76%,var(--ui-ink-strong)_24%)]",ae="border-[color-mix(in_srgb,var(--primary)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-accent-soft)] text-[color-mix(in_srgb,var(--primary)_72%,var(--ui-ink-strong)_28%)]";function zs(s){var T;const o=new Date;if(s.frequency==="daily"){const c=ze(o),y=[];for(let m=-6;m<=0;m+=1){const j=de(c,m),H=W(j),D=s.checkIns.find(N=>N.dateKey===H)??null,M=Ks[j.getDay()],w=m===0;y.push({id:H,label:M,current:w,actionDateKey:H,actionLabel:ee(j),state:D?ue(s,D.status)?"aligned":"unaligned":"unknown",title:`${ee(j)} · ${D?pe(s,D.status):"Not informed"}`})}return{caption:"7-day rhythm",rangeLabel:"Past 7 days",showLabels:!0,startLabel:"",endLabel:"",cells:y}}const d=Xe(o),f=new Map;for(const c of s.checkIns){const y=W(Xe($e(c.dateKey))),m=f.get(y)??[];m.push(c),f.set(y,m)}const k=[];for(let c=-6;c<=0;c+=1){const y=de(d,c*7),m=W(y),j=f.get(m)??[],H=s.weekDays.length>0?[...s.weekDays].sort((E,R)=>R-E)[0]:0,D=W(de(y,H)),M=((T=j[0])==null?void 0:T.dateKey)??D,w=j.filter(E=>ue(s,E.status)).length,N=j.length-w;k.push({id:m,label:"",current:c===0,actionDateKey:M,actionLabel:`Week of ${ee(y)}`,state:j.length===0?"unknown":w>=N?"aligned":"unaligned",title:`${ee(y)} week · ${j.length===0?"Not informed":w>=N?"Mostly aligned":"Mostly off track"}`})}return{caption:"7-week rhythm",rangeLabel:"Past 7 weeks",showLabels:!1,startLabel:ee(de(d,-42)),endLabel:"This week",cells:k}}function qs(s,o){return P("h-8 w-full rounded-[10px] border transition",s==="aligned"&&"border-[color-mix(in_srgb,var(--success)_30%,var(--ui-border-subtle)_70%)] bg-[color-mix(in_srgb,var(--success)_58%,var(--ui-surface-1)_42%)] shadow-[var(--ui-shadow-soft)]",s==="unaligned"&&"border-[color-mix(in_srgb,var(--danger)_30%,var(--ui-border-subtle)_70%)] bg-[color-mix(in_srgb,var(--danger)_54%,var(--ui-surface-1)_46%)] shadow-[var(--ui-shadow-soft)]",s==="unknown"&&"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]",o&&"ring-1 ring-[color-mix(in_srgb,var(--primary)_34%,transparent)]")}function Ws({habit:s,onSelectCell:o}){const d=zs(s),f=qe(s);return e.jsxs("div",{className:"w-full rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-2.5 shadow-[var(--ui-shadow-soft)]",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"shrink-0",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.16em] text-[var(--ui-ink-muted)]",children:d.caption}),e.jsx("div",{className:"text-[11px] text-[var(--ui-ink-soft)]",children:d.rangeLabel})]}),e.jsx("div",{className:"flex min-w-0 flex-1 items-center gap-1.5",children:d.cells.map(k=>e.jsxs("button",{type:"button",className:"group flex min-w-0 flex-1 items-center gap-1 rounded-[10px] transition hover:bg-[var(--ui-surface-hover)]",onClick:()=>o(s,k),title:`Log check-in for ${k.actionLabel}`,"aria-label":`Log check-in for ${k.actionLabel}`,children:[e.jsx("div",{className:P(qs(k.state,k.current),"h-6 min-w-0 flex-1 rounded-[8px] transition duration-150 group-hover:-translate-y-0.5 group-hover:shadow-[var(--ui-shadow-soft)]")}),d.showLabels?e.jsx("span",{className:"hidden text-[9px] uppercase tracking-[0.14em] text-[var(--ui-ink-muted)] transition group-hover:text-[var(--ui-ink-medium)] sm:inline",children:k.label}):null]},k.id))}),e.jsx("div",{className:P("shrink-0 rounded-full px-2.5 py-1 text-[10px] font-medium",f.pillClass),children:f.label})]}),d.showLabels?null:e.jsxs("div",{className:"mt-1 text-right text-[10px] uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:[d.startLabel," - ",d.endLabel]})]})}function Gs(s){return s.polarity==="positive"?{alignedLabel:"Done",alignedDescription:"Log that the intended habit happened.",unalignedLabel:"Missed",unalignedDescription:"Log that the habit did not happen."}:{alignedLabel:"Resisted",alignedDescription:"Log that the unwanted behavior was resisted.",unalignedLabel:"Performed",unalignedDescription:"Log that the unwanted behavior happened."}}function Q(s,o){return s.polarity==="positive"?o==="aligned"?"done":"missed":o==="aligned"?"missed":"done"}function Y(s,o){return ue(s,o)?"aligned":"unaligned"}function ma(){var ke,ye,je,we,_e,Ne;const s=cs(),o=ls(),[d,f]=Ye(),[k,T]=p.useState(null),[c,y]=p.useState(null),[m,j]=p.useState(null),[H,D]=p.useState(""),[M,w]=p.useState(!1),[N,E]=p.useState(null),[R,S]=p.useState(null),te=d.get("focus"),K=d.get("orderBy")??"name",C=Ds(s.selectedUserIds),Z=Ls(C),O=["forge-habits",K,...C];ws(te);const $=me({queryKey:O,queryFn:async()=>(await ks({userIds:C,orderBy:K})).habits}),I=me({queryKey:["forge-psyche-overview",...C],queryFn:async()=>(await ys(C)).overview}),_=me({queryKey:["forge-life-force",...C],queryFn:async()=>(await js(C)).lifeForce});p.useEffect(()=>{d.get("create")==="1"&&(T(null),w(!0),f(a=>{const h=new URLSearchParams(a);return h.delete("create"),h},{replace:!0}))},[d,f]);const G=async()=>{await o.invalidateQueries({queryKey:["forge-habits"]}),await s.refresh()},r=ge({mutationFn:async({input:a,habitId:h})=>h?(await bs(h,a)).habit:(await vs(a)).habit,onSuccess:async()=>{S(null),await G()},onError:a=>{S(a instanceof Error?a.message:"Habit save failed.")}}),i=ge({mutationFn:async({habitId:a,status:h,dateKey:u,note:z})=>fs(a,{status:h,dateKey:u,note:z}),onSuccess:async()=>{S(null),await G()},onError:a=>{S(a instanceof Error?a.message:"Habit check-in failed.")}}),t=ge({mutationFn:async a=>ps(a),onMutate:async a=>{await o.cancelQueries({queryKey:O});const h=o.getQueryData(O);return o.setQueryData(O,u=>(u==null?void 0:u.filter(z=>z.id!==a))??[]),{previousHabits:h}},onSuccess:async()=>{S(null),E(null),await G()},onError:(a,h,u)=>{u!=null&&u.previousHabits&&o.setQueryData(O,u.previousHabits),S(a instanceof Error?a.message:"Habit delete failed.")}}),n=p.useMemo(()=>($.data??[]).filter(a=>a.status!=="archived"),[$.data]),J=p.useMemo(()=>n.filter(a=>a.dueToday),[n]),We=p.useMemo(()=>J.reduce((a,h)=>{var re;const u=Ke().totalAp,z=((re=xe(h))==null?void 0:re.totalAp)??0;return a+u+z},0),[J]),Ge=p.useMemo(()=>n.reduce((a,h)=>{var u;return a+(((u=xe(h))==null?void 0:u.totalAp)??0)},0),[n]),X=p.useMemo(()=>c?c.habit.checkIns.find(a=>a.dateKey===c.cell.actionDateKey)??null:null,[c]);if(p.useEffect(()=>{if(!c){j(null),D("");return}j((X==null?void 0:X.status)??null),D((X==null?void 0:X.note)??"")},[c,X]),$.error)throw $.error;const Ue=a=>{f(h=>{const u=new URLSearchParams(h);return a==="name"?u.delete("orderBy"):u.set("orderBy",a),u},{replace:!0})},V=c?Gs(c.habit):null,fe=m==="done"||m==="missed"||X!==null;return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(Ns,{entityKind:"habit",title:e.jsx(Fe,{kind:"habit",label:"Habits",variant:"heading",size:"lg"}),titleText:"Habits",description:"Habits track recurring commitments and recurring slips with explicit daily consequences, linked behaviors, and real XP movement.",badge:`${n.length} habits`,actions:e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-2",children:[e.jsx(us,{metrics:s.snapshot.metrics}),e.jsxs(L,{onClick:()=>{T(null),w(!0)},children:[e.jsx(Ze,{className:"size-4"}),"New habit"]})]})}),R?e.jsx(A,{className:"border-[color-mix(in_srgb,var(--danger)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Je,{className:"mt-0.5 size-4 shrink-0"}),e.jsx("div",{children:R})]})}):null,e.jsxs("section",{className:"grid gap-4 lg:grid-cols-4",children:[e.jsxs(A,{className:"border-[color-mix(in_srgb,var(--warning)_22%,var(--ui-border-subtle)_78%)] shadow-[var(--ui-shadow-soft)]",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Due today"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--primary)]",children:J.length}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Habits that still need a check-in today."})]}),e.jsxs(A,{className:"border-[color-mix(in_srgb,var(--primary)_22%,var(--ui-border-subtle)_78%)] shadow-[var(--ui-shadow-soft)]",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Habit AP due"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[var(--primary)]",children:U(We)}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Default Action Point load if every due habit is logged today."})]}),e.jsxs(A,{className:"border-[color-mix(in_srgb,var(--success)_22%,var(--ui-border-subtle)_78%)] shadow-[var(--ui-shadow-soft)]",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Best streak"}),e.jsx("div",{className:"mt-3 font-display text-4xl text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]",children:Math.max(0,...n.map(a=>a.streakCount))}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Longest current aligned streak across active habits."})]}),e.jsxs(A,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Average alignment"}),e.jsxs("div",{className:"mt-3 font-display text-4xl text-[var(--ui-ink-strong)]",children:[n.length>0?Math.round(n.reduce((a,h)=>a+h.completionRate,0)/n.length):0,"%"]}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Share of recent habit check-ins that matched the intended direction."})]})]}),e.jsxs("section",{className:"grid gap-4 xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)]",children:[e.jsxs(A,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Life Force sync"}),e.jsx("div",{className:"mt-3 text-2xl font-display text-[var(--ui-ink-strong)]",children:_.data?`${U(_.data.spentTodayAp)} / ${U(_.data.dailyBudgetAp)}`:"Loading..."}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Habit check-ins debit the same Action Point ledger as work, notes, movement, and workouts."})]}),e.jsxs(A,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Instant headroom"}),e.jsx("div",{className:"mt-3 text-2xl font-display text-[var(--ui-ink-strong)]",children:_.data?Me(_.data.instantFreeApPerHour):"Loading..."}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Use this to tell whether now is a good moment for heavier habits or just a light check-in."})]}),e.jsxs(A,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Workout-linked load"}),e.jsx("div",{className:"mt-3 text-2xl font-display text-[var(--ui-ink-strong)]",children:U(Ge)}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-soft)]",children:"Habit-generated workout templates stay visible as Action Point cost instead of hiding behind the XP reward."})]})]}),$.isLoading?e.jsx(A,{children:"Loading habits..."}):n.length===0?e.jsx(ms,{eyebrow:"Habits",title:"No recurring habits yet",description:"Create the recurring commitments or recurring slips you want Forge to track explicitly. Positive habits pay out when completed. Negative habits invert that logic.",action:e.jsx(L,{onClick:()=>{T(null),w(!0)},children:"Create habit"})}):e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"flex flex-col gap-3 rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4 shadow-[var(--ui-shadow-soft)] sm:flex-row sm:items-end sm:justify-between",children:[e.jsxs("div",{className:"max-w-xl",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Habit list order"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-soft)]",children:"Choose a stable ordering so the list does not reshuffle while you are logging check-ins."})]}),e.jsx(Ts,{label:"Order by",value:K,options:Xs,onChange:Ue,className:"w-full sm:w-[19rem]"})]}),e.jsx("div",{className:"grid gap-4 xl:grid-cols-2",children:n.map(a=>{const h=qe(a),u=Os(a.streakCount),z=u.Icon,re=Ke(),ie=xe(a),Qe=gs(s.snapshot.dashboard.notesSummaryByEntity,"habit",a.id).count,ne=a.polarity==="positive"?{label:"Done",status:Q(a,"aligned"),Icon:Ie,className:"border-[color-mix(in_srgb,var(--success)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)] hover:bg-[color-mix(in_srgb,var(--success)_24%,var(--ui-surface-hover)_76%)]"}:{label:"Resisted",status:Q(a,"aligned"),Icon:Ce,className:"border-[color-mix(in_srgb,var(--success)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)] hover:bg-[color-mix(in_srgb,var(--success)_24%,var(--ui-surface-hover)_76%)]"},le=a.polarity==="positive"?{label:"Missed",status:Q(a,"unaligned"),Icon:Pe,className:"border-[color-mix(in_srgb,var(--danger)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)] hover:bg-[color-mix(in_srgb,var(--danger)_22%,var(--ui-surface-hover)_78%)]"}:{label:"Performed",status:Q(a,"unaligned"),Icon:as,className:"border-[color-mix(in_srgb,var(--danger)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)] hover:bg-[color-mix(in_srgb,var(--danger)_22%,var(--ui-surface-hover)_78%)]"};return e.jsxs(A,{className:P("relative flex h-full flex-col overflow-hidden",h.cardClass,_s(te===a.id)),"data-psyche-focus-id":a.id,children:[e.jsx("div",{className:P("pointer-events-none absolute inset-0 opacity-100",h.overlayClass)}),e.jsxs("div",{className:"relative z-10 flex h-full flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Fe,{kind:"habit",label:a.title,variant:"heading",size:"sm"}),e.jsx(Hs,{user:a.user,compact:!0}),e.jsx(v,{className:se,children:a.status}),e.jsxs(v,{className:se,children:[e.jsx(Ve,{className:"mr-1 size-3.5"}),Rs(a)]}),e.jsx(v,{className:a.polarity==="positive"?Re:Oe,children:a.polarity==="positive"?"Positive":"Negative"}),a.dueToday?e.jsx(v,{className:ce,children:"Needs check-in"}):null,a.linkedGoalIds.slice(0,1).map(g=>{const l=s.snapshot.goals.find(x=>x.id===g);return l?e.jsxs(v,{className:ce,children:["Goal · ",l.title]},l.id):null}),a.linkedProjectIds.slice(0,1).map(g=>{const l=s.snapshot.dashboard.projects.find(x=>x.id===g);return l?e.jsxs(v,{className:be,children:["Project · ",l.title]},l.id):null}),a.linkedTaskIds.slice(0,1).map(g=>{const l=s.snapshot.tasks.find(x=>x.id===g);return l?e.jsxs(v,{className:ae,children:["Task · ",l.title]},l.id):null})]}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:a.description?e.jsx(ds,{markdown:a.description,className:"[&>p]:text-sm [&>p]:leading-6 [&>blockquote]:text-sm [&>ul]:text-sm [&>ol]:text-sm"}):"No extra notes yet."})]}),e.jsxs("div",{className:"ml-auto inline-flex shrink-0 flex-col items-end gap-2 self-start text-right",children:[e.jsxs("div",{className:P("inline-flex flex-col self-end rounded-[20px] px-3 py-2.5 text-right",u.className),children:[e.jsxs("div",{className:"flex items-center justify-end gap-1.5 text-[10px] uppercase tracking-[0.16em]",children:[e.jsx("span",{children:"Streak"}),e.jsx(z,{className:P("size-3.5 shrink-0",u.iconClass)})]}),e.jsx("div",{className:P("mt-1.5 font-display text-[2.75rem] leading-none",u.valueClass),children:a.streakCount}),e.jsx("div",{className:"mt-1 text-[11px] leading-tight text-[var(--ui-ink-soft)]",children:u.label})]}),e.jsxs("div",{className:"ml-auto grid grid-cols-2 gap-1.5",children:[e.jsx(L,{variant:"ghost",size:"sm",className:"h-7 min-w-0 rounded-[11px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",disabled:r.isPending,onClick:()=>{T(a),w(!0)},"aria-label":`Edit ${a.title}`,title:"Edit habit",children:e.jsx(es,{className:"size-4"})}),e.jsx(L,{variant:"ghost",size:"sm",className:"h-7 min-w-0 rounded-[11px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",disabled:t.isPending,onClick:()=>E(a),"aria-label":`Delete ${a.title}`,title:"Delete habit",children:e.jsx(ss,{className:"size-4"})})]})]})]}),e.jsxs("div",{className:"mt-auto grid gap-4 pt-5",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(v,{className:P("",$s(a.completionRate)),children:["Alignment ",a.completionRate,"%"]}),e.jsx(v,{className:se,children:a.polarity==="positive"?`+${a.rewardXp} XP done`:`+${a.rewardXp} XP resisted`}),e.jsx(v,{className:se,children:a.polarity==="positive"?`-${a.penaltyXp} XP missed`:`-${a.penaltyXp} XP performed`}),e.jsxs(v,{className:ae,children:[U(re.totalAp)," check-in"]}),ie?e.jsxs(v,{className:ce,children:[U(ie.totalAp)," ","workout"]}):null,ie?e.jsx(v,{className:se,children:Me(ie.rateApPerHour)}):null,e.jsx(os,{entityType:"habit",entityId:a.id,count:Qe,className:"min-h-8 rounded-full border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-1.5 text-[12px] text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)]"}),a.linkedBehaviorTitles.slice(0,2).map(g=>e.jsxs(v,{className:ce,children:[e.jsx(Ce,{className:"mr-1 size-3.5"}),g]},g)),a.linkedProjectIds.slice(1,2).map(g=>{const l=s.snapshot.dashboard.projects.find(x=>x.id===g);return l?e.jsxs(v,{className:be,children:["Project · ",l.title]},l.id):null}),a.linkedTaskIds.slice(1,2).map(g=>{const l=s.snapshot.tasks.find(x=>x.id===g);return l?e.jsxs(v,{className:ae,children:["Task · ",l.title]},l.id):null}),a.linkedValueIds.slice(0,2).map(g=>{var x;const l=(x=I.data)==null?void 0:x.values.find(B=>B.id===g);return l?e.jsxs(v,{className:Re,children:["Value · ",l.title]},l.id):null}),a.linkedPatternIds.slice(0,2).map(g=>{var x;const l=(x=I.data)==null?void 0:x.patterns.find(B=>B.id===g);return l?e.jsxs(v,{className:be,children:["Pattern · ",l.title]},l.id):null}),a.linkedBeliefIds.slice(0,2).map(g=>{var x;const l=(x=I.data)==null?void 0:x.beliefs.find(B=>B.id===g);return l?e.jsxs(v,{className:Oe,children:["Belief · ",l.statement]},l.id):null}),a.linkedModeIds.slice(0,2).map(g=>{var x;const l=(x=I.data)==null?void 0:x.modes.find(B=>B.id===g);return l?e.jsxs(v,{className:ae,children:["Mode · ",l.title]},l.id):null}),a.linkedReportIds.slice(0,2).map(g=>{var x;const l=(x=I.data)==null?void 0:x.reports.find(B=>B.id===g);return l?e.jsxs(v,{className:ae,children:["Report · ",l.title]},l.id):null})]}),e.jsx("div",{className:"grid gap-4",children:e.jsx(Ws,{habit:a,onSelectCell:(g,l)=>{y({habit:g,cell:l}),S(null)}})}),e.jsxs("div",{className:"grid gap-2 sm:grid-cols-2",children:[e.jsxs(L,{variant:"secondary",className:P("h-11 rounded-[16px] border",ne.className),disabled:i.isPending,onClick:()=>void i.mutateAsync({habitId:a.id,status:ne.status,dateKey:W(new Date)}),children:[e.jsx(ne.Icon,{className:"size-4"}),ne.label]}),e.jsxs(L,{variant:"secondary",className:P("h-11 rounded-[16px] border",le.className),disabled:i.isPending,onClick:()=>void i.mutateAsync({habitId:a.id,status:le.status,dateKey:W(new Date)}),children:[e.jsx(le.Icon,{className:"size-4"}),le.label]})]})]})]})]},a.id)})})]}),e.jsx(Fs,{open:M,pending:r.isPending,editingHabit:k,values:((ke=I.data)==null?void 0:ke.values)??[],patterns:((ye=I.data)==null?void 0:ye.patterns)??[],behaviors:((je=I.data)==null?void 0:je.behaviors)??[],beliefs:((we=I.data)==null?void 0:we.beliefs)??[],modes:((_e=I.data)==null?void 0:_e.modes)??[],reports:((Ne=I.data)==null?void 0:Ne.reports)??[],goals:s.snapshot.dashboard.goals,projects:s.snapshot.dashboard.projects,tasks:s.snapshot.tasks,users:s.snapshot.users,defaultUserId:(k==null?void 0:k.userId)??Z,onOpenChange:w,onSubmit:async(a,h)=>{try{await r.mutateAsync({input:a,habitId:h})}catch(u){throw u instanceof xs,u}}}),e.jsx(Le,{open:N!==null,onOpenChange:a=>{!a&&!t.isPending&&E(null)},children:e.jsxs(Se,{children:[e.jsx(Te,{className:"surface-overlay fixed inset-0 z-40 backdrop-blur-xl"}),e.jsxs(He,{className:"surface-modal-panel fixed inset-x-4 top-1/2 z-50 mx-auto w-[min(30rem,calc(100vw-2rem))] max-w-[30rem] -translate-y-1/2 overflow-hidden rounded-[30px] border",children:[e.jsx("div",{className:"border-b border-[var(--ui-border-subtle)] px-5 py-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Delete habit"}),e.jsx(Ee,{className:"mt-2 text-lg font-semibold text-[var(--ui-ink-strong)]",children:(N==null?void 0:N.title)??"Delete this habit?"}),e.jsx(Ae,{className:"mt-3 text-sm text-[var(--ui-ink-soft)]",children:"Remove this habit from Forge. The habit card disappears immediately after delete succeeds."})]}),e.jsx(Be,{asChild:!0,children:e.jsx(L,{variant:"ghost",size:"sm",className:"h-10 w-10 rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-0 text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]","aria-label":"Close delete habit modal",title:"Close",disabled:t.isPending,children:e.jsx(De,{className:"size-4"})})})]})}),e.jsxs("div",{className:"grid gap-4 p-5",children:[e.jsx("div",{className:"rounded-[20px] border border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] px-4 py-3 text-sm leading-6 text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]",children:"This removes the habit and its check-in history from the habits page."}),e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-3",children:[e.jsx(L,{variant:"secondary",onClick:()=>E(null),disabled:t.isPending,children:"Cancel"}),e.jsx(L,{className:"border border-[color-mix(in_srgb,var(--danger)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)] hover:bg-[color-mix(in_srgb,var(--danger)_22%,var(--ui-surface-hover)_78%)]",pending:t.isPending,pendingLabel:"Deleting",onClick:()=>{N&&t.mutateAsync(N.id)},children:"Delete habit"})]})]})]})]})}),e.jsx(Le,{open:c!==null,onOpenChange:a=>{a||y(null)},children:e.jsxs(Se,{children:[e.jsx(Te,{className:"surface-overlay fixed inset-0 z-40 backdrop-blur-xl"}),e.jsxs(He,{className:"surface-modal-panel fixed inset-x-4 top-1/2 z-50 mx-auto w-[min(42rem,calc(100vw-2rem))] max-w-[42rem] -translate-y-1/2 overflow-hidden rounded-[30px] border",children:[e.jsx(Ee,{className:"sr-only",children:"Habit history"}),e.jsx(Ae,{className:"sr-only",children:"Log or revise a habit check-in for a selected history point."}),c&&V?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"border-b border-[var(--ui-border-subtle)] px-5 py-4",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Habit history"}),e.jsxs("div",{className:"mt-2 flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-lg font-semibold text-[var(--ui-ink-strong)]",children:c.habit.title}),e.jsx(v,{children:c.cell.actionLabel})]}),e.jsx("div",{className:"mt-3 text-sm text-[var(--ui-ink-soft)]",children:c.habit.frequency==="daily"?"Log or revise the check-in for this specific day.":"Log or revise the representative check-in for this week."})]}),e.jsx(Be,{asChild:!0,children:e.jsx(L,{variant:"ghost",size:"sm",className:"h-10 w-10 rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-0 text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]","aria-label":"Close history modal",title:"Close",children:e.jsx(De,{className:"size-4"})})})]})}),e.jsxs("div",{className:"grid gap-4 p-5",children:[e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("button",{type:"button","aria-pressed":m!==null&&Y(c.habit,m)==="aligned",className:P("rounded-[22px] border px-4 py-4 text-left transition",m!==null&&Y(c.habit,m)==="aligned"?"border-[color-mix(in_srgb,var(--success)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)]"),onClick:()=>j(a=>a!==null&&Y(c.habit,a)==="aligned"?null:Q(c.habit,"aligned")),children:[e.jsxs("div",{className:"flex items-center gap-2 text-base font-medium",children:[e.jsx(Ie,{className:"size-4"}),V.alignedLabel]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:V.alignedDescription})]}),e.jsxs("button",{type:"button","aria-pressed":m!==null&&Y(c.habit,m)==="unaligned",className:P("rounded-[22px] border px-4 py-4 text-left transition",m!==null&&Y(c.habit,m)==="unaligned"?"border-[color-mix(in_srgb,var(--danger)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-danger-soft)] text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-medium)] hover:bg-[var(--ui-surface-hover)]"),onClick:()=>j(a=>a!==null&&Y(c.habit,a)==="unaligned"?null:Q(c.habit,"unaligned")),children:[e.jsxs("div",{className:"flex items-center gap-2 text-base font-medium",children:[e.jsx(Pe,{className:"size-4"}),V.unalignedLabel]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:V.unalignedDescription})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Optional note"}),e.jsx(ve,{value:H,onChange:a=>D(a.target.value),placeholder:"Add context for what happened on this day or week.",className:"min-h-24"})]}),e.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-3",children:[e.jsx(L,{variant:"secondary",onClick:()=>y(null),disabled:i.isPending,children:"Cancel"}),e.jsx(L,{disabled:i.isPending||!fe,pending:i.isPending,pendingLabel:"Saving",onClick:async()=>{fe&&(m===null?(await hs(c.habit.id,c.cell.actionDateKey),await G()):await i.mutateAsync({habitId:c.habit.id,status:m,dateKey:c.cell.actionDateKey,note:H.trim()||void 0}),y(null))},children:"Save check-in"})]})]})]}):null]})]})})]})}export{ma as HabitsPage};
|