paneltir 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/version.ts
2
- var PANELTIR_VERSION = "0.7.0";
3
- var PANELTIR_FINGERPRINT = "sha256:406af8c690cfa9b2452360712afff3f3fe9605a7bb0aa834238e5187acfc37c0";
4
- var PANELTIR_FILE_COUNT = 151;
2
+ var PANELTIR_VERSION = "0.9.0";
3
+ var PANELTIR_FINGERPRINT = "sha256:f65d491a7350ddce22f6981dbcb91531f5e88fc66b7f9f8f83115d802773064f";
4
+ var PANELTIR_FILE_COUNT = 161;
5
5
  var paneltirBuild = {
6
6
  version: PANELTIR_VERSION,
7
7
  fingerprint: PANELTIR_FINGERPRINT,
@@ -667,9 +667,9 @@ function GuideTour({ notes, dismissed, onDismiss }) {
667
667
  useEffect4(() => {
668
668
  setReady(true);
669
669
  }, []);
670
- if (!ready && !controlled) return null;
670
+ if (!ready) return null;
671
671
  void version;
672
- const isDone = controlled ? (id) => dismissed.includes(id) : (id) => readDismissed(id);
672
+ const isDone = controlled ? (id) => dismissed.includes(id) || readDismissed(id) : (id) => readDismissed(id);
673
673
  const remaining = notes.filter((note) => !isDone(note.id));
674
674
  const current = remaining[0];
675
675
  if (!current) return null;
@@ -679,7 +679,7 @@ function GuideTour({ notes, dismissed, onDismiss }) {
679
679
  ...current,
680
680
  key: current.id,
681
681
  step: { index: notes.length - remaining.length + 1, total: notes.length },
682
- remember: !controlled,
682
+ remember: true,
683
683
  onDismissed: () => {
684
684
  onDismiss?.(current.id);
685
685
  setVersion((v) => v + 1);
@@ -720,9 +720,9 @@ function NotificationBell({ notifications, labels, seen: given, onSeen }) {
720
720
  const [open, setOpen] = useState3(false);
721
721
  const root = useRef4(null);
722
722
  useEffect5(() => {
723
- if (!controlled) setStored(readSeen());
724
- }, [controlled]);
725
- const seen = controlled ? new Set(given) : stored;
723
+ setStored(readSeen());
724
+ }, []);
725
+ const seen = stored === null ? controlled ? new Set(given) : null : controlled ? /* @__PURE__ */ new Set([...given, ...stored]) : stored;
726
726
  useEffect5(() => {
727
727
  if (!open) return;
728
728
  const onDown = (e) => {
@@ -740,10 +740,7 @@ function NotificationBell({ notifications, labels, seen: given, onSeen }) {
740
740
  }, [open]);
741
741
  const markSeen = useCallback3(
742
742
  (ids) => {
743
- if (controlled) {
744
- onSeen?.(ids);
745
- return;
746
- }
743
+ if (controlled) onSeen?.(ids);
747
744
  setStored((current) => {
748
745
  const next = new Set(current ?? []);
749
746
  for (const id of ids) next.add(id);
@@ -913,6 +910,89 @@ function SetupGuide({ requirements, readyMessage, labels }) {
913
910
  ] });
914
911
  }
915
912
 
913
+ // src/components/Setup/SetupWizard.tsx
914
+ import { useState as useState5 } from "react";
915
+
916
+ // src/components/Setup/wizard.ts
917
+ function wizardStep(requirements) {
918
+ const total = requirements.length;
919
+ const done = requirements.filter((requirement) => requirement.status === "ok");
920
+ const unknown = requirements.some((requirement) => requirement.status === "unknown");
921
+ const at = requirements.findIndex((requirement) => requirement.status !== "ok");
922
+ if (at === -1) {
923
+ return { current: null, index: 0, total, done, ready: total > 0, unknown: false };
924
+ }
925
+ return {
926
+ current: requirements[at],
927
+ index: at + 1,
928
+ total,
929
+ done,
930
+ ready: false,
931
+ unknown
932
+ };
933
+ }
934
+ function isFirstRun(board) {
935
+ return (board.cards?.length ?? 0) === 0 && (board.runs?.length ?? 0) === 0;
936
+ }
937
+
938
+ // src/components/Setup/SetupWizard.tsx
939
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
940
+ function SetupWizard({ requirements, labels, onCheck, onClose }) {
941
+ const step = wizardStep(requirements);
942
+ const [checking, setChecking] = useState5(false);
943
+ const [checked, setChecked] = useState5(false);
944
+ const [copied, setCopied] = useState5(false);
945
+ async function check() {
946
+ setChecking(true);
947
+ try {
948
+ await onCheck();
949
+ setChecked(true);
950
+ } finally {
951
+ setChecking(false);
952
+ }
953
+ }
954
+ async function copyPrompt() {
955
+ try {
956
+ await navigator.clipboard.writeText(labels.stuckPrompt);
957
+ setCopied(true);
958
+ window.setTimeout(() => setCopied(false), 2e3);
959
+ } catch {
960
+ }
961
+ }
962
+ return /* @__PURE__ */ jsxs14("section", { className: "pt-wizard", "aria-labelledby": "pt-wizard-title", children: [
963
+ /* @__PURE__ */ jsxs14("header", { className: "pt-wizard__head", children: [
964
+ /* @__PURE__ */ jsx16("h2", { className: "pt-h2", id: "pt-wizard-title", children: labels.title }),
965
+ step.current && /* @__PURE__ */ jsx16("p", { className: "pt-wizard__progress", children: labels.progress(step.index, step.total) })
966
+ ] }),
967
+ step.current ? /* @__PURE__ */ jsxs14("div", { className: "pt-wizard__step", children: [
968
+ /* @__PURE__ */ jsx16("p", { className: "pt-wizard__now", children: labels.nowDo }),
969
+ /* @__PURE__ */ jsx16("h3", { className: "pt-wizard__label", children: step.current.label }),
970
+ step.current.variable && /* @__PURE__ */ jsx16("p", { className: "pt-wizard__var", children: step.current.variable }),
971
+ step.current.enables && /* @__PURE__ */ jsx16("p", { className: "pt-wizard__enables", children: step.current.enables }),
972
+ step.current.fix && /* @__PURE__ */ jsx16("div", { className: "pt-wizard__fix", children: step.current.fix }),
973
+ /* @__PURE__ */ jsxs14("div", { className: "pt-wizard__actions", children: [
974
+ /* @__PURE__ */ jsx16("button", { type: "button", className: "pt-btn pt-btn--primary", onClick: check, disabled: checking, children: checking ? labels.checking : labels.check }),
975
+ checked && !checking && /* @__PURE__ */ jsx16("p", { className: "pt-wizard__said", children: step.unknown ? labels.cannotTell : labels.stillMissing })
976
+ ] })
977
+ ] }) : /* @__PURE__ */ jsxs14("div", { className: "pt-wizard__step pt-wizard__step--done", children: [
978
+ /* @__PURE__ */ jsx16("h3", { className: "pt-wizard__label", children: labels.readyTitle }),
979
+ /* @__PURE__ */ jsx16("p", { className: "pt-wizard__enables", children: labels.readyBody }),
980
+ /* @__PURE__ */ jsx16("ol", { className: "pt-wizard__verify", children: labels.verify.map((line) => /* @__PURE__ */ jsx16("li", { children: line }, line)) })
981
+ ] }),
982
+ step.done.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "pt-wizard__done", children: [
983
+ /* @__PURE__ */ jsx16("p", { className: "pt-wizard__done-title", children: labels.doneTitle }),
984
+ /* @__PURE__ */ jsx16("ul", { children: step.done.map((requirement) => /* @__PURE__ */ jsx16("li", { children: requirement.label }, requirement.id)) })
985
+ ] }),
986
+ /* @__PURE__ */ jsxs14("div", { className: "pt-wizard__stuck", children: [
987
+ /* @__PURE__ */ jsx16("p", { className: "pt-wizard__done-title", children: labels.stuckTitle }),
988
+ /* @__PURE__ */ jsx16("p", { className: "pt-wizard__enables", children: labels.stuckBody }),
989
+ /* @__PURE__ */ jsx16("pre", { className: "pt-wizard__prompt", children: labels.stuckPrompt }),
990
+ /* @__PURE__ */ jsx16("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: copyPrompt, children: copied ? labels.copied : labels.copy })
991
+ ] }),
992
+ onClose && /* @__PURE__ */ jsx16("div", { className: "pt-wizard__actions", children: /* @__PURE__ */ jsx16("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: onClose, children: labels.close }) })
993
+ ] });
994
+ }
995
+
916
996
  // src/hooks/useDelegatedClick.ts
917
997
  import { useEffect as useEffect7 } from "react";
918
998
  function useDelegatedClick(attribute, handler) {
@@ -932,9 +1012,9 @@ function useDelegatedClick(attribute, handler) {
932
1012
  }
933
1013
 
934
1014
  // src/hooks/useMediaQuery.ts
935
- import { useEffect as useEffect8, useState as useState5 } from "react";
1015
+ import { useEffect as useEffect8, useState as useState6 } from "react";
936
1016
  function useMediaQuery(query) {
937
- const [matches, setMatches] = useState5(() => typeof window !== "undefined" ? window.matchMedia(query).matches : false);
1017
+ const [matches, setMatches] = useState6(() => typeof window !== "undefined" ? window.matchMedia(query).matches : false);
938
1018
  useEffect8(() => {
939
1019
  const mql = window.matchMedia(query);
940
1020
  const handler = () => setMatches(mql.matches);
@@ -1300,7 +1380,62 @@ function isCard(value) {
1300
1380
  }
1301
1381
 
1302
1382
  // src/panel/PanelApp.tsx
1303
- import React12, { useCallback as useCallback5, useEffect as useEffect9, useMemo as useMemo5, useState as useState9 } from "react";
1383
+ import React13, { useCallback as useCallback5, useEffect as useEffect9, useMemo as useMemo5, useState as useState10 } from "react";
1384
+
1385
+ // src/panel/updates.ts
1386
+ var REGISTRY_URL = "https://registry.npmjs.org/paneltir/latest";
1387
+ function readNotes(value) {
1388
+ if (typeof value !== "object" || value === null) return void 0;
1389
+ const candidate = value;
1390
+ if (typeof candidate.version !== "string" || typeof candidate.date !== "string") return void 0;
1391
+ if (!Array.isArray(candidate.entries) || candidate.entries.length === 0) return void 0;
1392
+ const kinds = /* @__PURE__ */ new Set(["breaking", "feature", "fix", "chore"]);
1393
+ const entries = [];
1394
+ for (const raw of candidate.entries) {
1395
+ if (typeof raw !== "object" || raw === null) return void 0;
1396
+ const item = raw;
1397
+ const text2 = item.text;
1398
+ if (typeof item.kind !== "string" || !kinds.has(item.kind)) return void 0;
1399
+ if (typeof text2?.en !== "string" || typeof text2?.es !== "string") return void 0;
1400
+ entries.push({ kind: item.kind, text: { en: text2.en, es: text2.es } });
1401
+ }
1402
+ return { version: candidate.version, date: candidate.date, entries };
1403
+ }
1404
+ function releaseShape(notes) {
1405
+ if (!notes?.entries.length) return null;
1406
+ for (const kind of ["breaking", "feature", "fix", "chore"]) {
1407
+ if (notes.entries.some((entry) => entry.kind === kind)) return kind;
1408
+ }
1409
+ return null;
1410
+ }
1411
+ function isNewer(candidate, current) {
1412
+ const parts = (value) => value.trim().replace(/^v/, "").split(/[-+]/)[0].split(".").map((piece) => Number.parseInt(piece, 10));
1413
+ const left = parts(candidate);
1414
+ const right = parts(current);
1415
+ if (left.some(Number.isNaN) || right.some(Number.isNaN)) return false;
1416
+ for (let i = 0; i < 3; i += 1) {
1417
+ const a = left[i] ?? 0;
1418
+ const b = right[i] ?? 0;
1419
+ if (a !== b) return a > b;
1420
+ }
1421
+ return false;
1422
+ }
1423
+ async function checkForUpdate(current, fetchImpl = fetch) {
1424
+ try {
1425
+ const response = await fetchImpl(REGISTRY_URL, { headers: { accept: "application/json" } });
1426
+ if (!response.ok) return null;
1427
+ const body = await response.json();
1428
+ const latest = typeof body.version === "string" ? body.version : null;
1429
+ if (!latest) return null;
1430
+ return { current, latest, behind: isNewer(latest, current), notes: readNotes(body.paneltirRelease) };
1431
+ } catch {
1432
+ return null;
1433
+ }
1434
+ }
1435
+ function updateCardId(version) {
1436
+ const found = /\d+\.\d+\.\d+/.exec(version);
1437
+ return `paneltir-update-${found ? found[0] : "unknown"}`;
1438
+ }
1304
1439
 
1305
1440
  // src/panel/themes.ts
1306
1441
  var PRESET_FORM = {
@@ -1327,9 +1462,18 @@ var PRESET_PANEL_THEMES = Object.fromEntries(
1327
1462
  { label: PRESET_LABEL[name], tokens: THEME_PRESETS[name], form: PRESET_FORM[name], note: PRESET_NOTE[name] }
1328
1463
  ])
1329
1464
  );
1465
+ function offeredThemes(themes, extraThemes) {
1466
+ if (themes) return themes;
1467
+ if (!extraThemes) return PRESET_PANEL_THEMES;
1468
+ const offered = { ...extraThemes };
1469
+ for (const [name, preset] of Object.entries(PRESET_PANEL_THEMES)) {
1470
+ if (!(name in offered)) offered[name] = preset;
1471
+ }
1472
+ return offered;
1473
+ }
1330
1474
 
1331
1475
  // src/panel/AnalysisView.tsx
1332
- import { useMemo as useMemo3, useState as useState6 } from "react";
1476
+ import { useMemo as useMemo3, useState as useState7 } from "react";
1333
1477
 
1334
1478
  // src/panel/i18n.ts
1335
1479
  var STORAGE_KEY = "paneltir:lang";
@@ -1356,6 +1500,30 @@ var UI = {
1356
1500
  board: "Board",
1357
1501
  analysis: "Analysis",
1358
1502
  history: "Revisions",
1503
+ updateTitle: "The kit this panel runs on",
1504
+ updateSubtitle: "What is installed, and what has been published since.",
1505
+ updateCurrent: (version) => `Installed: v${version}`,
1506
+ updateAvailable: (version) => `v${version} has been published.`,
1507
+ updateUpToDate: "This is the newest published version.",
1508
+ updateUnknown: "The registry could not be reached, so there is nothing to report either way.",
1509
+ updateCreateCard: "Add a card asking for it",
1510
+ updateCardExists: "The board already carries a card for this version.",
1511
+ updateAsOrder: "Write it as an order, not a suggestion",
1512
+ updateAsOrderHow: "This does not update anything on its own \u2014 the panel cannot run npm. It decides whether the card it writes asks for the update or instructs it.",
1513
+ notifUpdate: "A newer Paneltir has been published",
1514
+ releaseTitle: (version) => `What v${version} changes`,
1515
+ releaseDate: (date) => `Published ${date}`,
1516
+ releaseShape: {
1517
+ breaking: "Contains a change that can break things",
1518
+ feature: "New things, and fixes",
1519
+ fix: "Small fixes",
1520
+ chore: "Housekeeping"
1521
+ },
1522
+ releaseKind: { breaking: "Breaking", feature: "New", fix: "Fix", chore: "Chore" },
1523
+ releaseClose: "Close",
1524
+ releaseNone: "This version was published without notes.",
1525
+ updateCardTitle: (version) => `Update Paneltir to v${version}`,
1526
+ updateCardBody: (version) => `Run \`npm install paneltir@${version}\` in this project, then check the panel still builds and renders. The version in use is reported by \`paneltirBuild\`, so it can be confirmed rather than assumed.`,
1359
1527
  cardDetail: "Card",
1360
1528
  panelSettings: "Panel settings",
1361
1529
  title: "Title",
@@ -1436,6 +1604,28 @@ var UI = {
1436
1604
  fixTokenPaste: "Paste it into the hosting project as GH_TOKEN. Never into the repository: a token in a commit is a token to revoke.",
1437
1605
  fixTokenRedeploy: "Redeploy. Environment variables are read at deploy time, so a running deployment will not see a new one.",
1438
1606
  fixRepo: "Set PANEL_REPO in the hosting project to this project\u2019s owner/repo, then redeploy.",
1607
+ wizardTitle: "Setting this panel up",
1608
+ wizardProgress: (index, total) => `Step ${index} of ${total}`,
1609
+ wizardNowDo: "Do this next",
1610
+ wizardCheck: "Check it now",
1611
+ wizardChecking: "Asking the server\u2026",
1612
+ wizardStillMissing: "Still not there. If you have just added it, redeploy \u2014 a running deployment does not see a new variable.",
1613
+ wizardCannotTell: "The panel could not ask its own server, so it cannot say either way. That is a different problem from a missing variable, and worth fixing first.",
1614
+ wizardDoneTitle: "Already in place",
1615
+ wizardReadyTitle: "That is everything.",
1616
+ wizardReadyBody: "Saves will commit to the repository from now on. Two things are worth trying before you trust the door:",
1617
+ wizardVerify: [
1618
+ "Open /admin signed out. It should land on the sign-in screen, not on the panel.",
1619
+ "Signed out, ask for the panel\u2019s own JavaScript bundle. It should answer 401. A page that is protected while its bundle is not leaves the board readable by anyone who opens the HTML."
1620
+ ],
1621
+ wizardClose: "Close",
1622
+ wizardStuckTitle: "If any of this is unclear",
1623
+ wizardStuckBody: "This project has a Claude of its own, and `paneltir init` wrote it a guide covering exactly this. Paste the line below into a session in this repository and it will walk you through it, in whatever detail you need.",
1624
+ wizardStuckPrompt: "Read .claude/skills/panel/SKILL.md and set up the Paneltir panel with me: tell me each environment variable it needs, what it is for, where in this project to put it, and check the ones already set.",
1625
+ wizardCopy: "Copy the prompt",
1626
+ wizardCopied: "Copied",
1627
+ wizardOpen: "Walk me through it",
1628
+ wizardBanner: "This panel is not finished being set up: saving will fail until it is.",
1439
1629
  demoTourWelcomeTitle: "A real panel, and nothing is saved yet",
1440
1630
  demoTourWelcomeBody: "Everything here works. Move things, open things, break things \u2014 nothing is written anywhere yet, so nothing you do can damage anything.",
1441
1631
  demoTourBoardTitle: "Drag a card, then open one",
@@ -1510,6 +1700,20 @@ var UI = {
1510
1700
  strategy: "The paths open to it, the one chosen, and what is worth doing next.",
1511
1701
  market: "Who this is for, and who else is already there."
1512
1702
  },
1703
+ analysisRedo: "Ask for this again",
1704
+ analysisRedoAsked: "Asked for. It lands as a card, and the next session does the work.",
1705
+ analysisRedoTitle: {
1706
+ board: "Read the board again and say what it adds up to",
1707
+ project: "Revisit what this is for and how it is measured",
1708
+ strategy: "Work the strategy again and propose what is next",
1709
+ market: "A fresh market report"
1710
+ },
1711
+ analysisRedoBody: {
1712
+ board: "The board has moved since this was last read. Go through the cards, say what they now add up to, and write the questions worth asking that nobody has asked yet.",
1713
+ project: "Look again at the goals, the constraints and the metrics. Say which no longer match what the project has become, and propose the change rather than making it.",
1714
+ strategy: "Look at the strategies on record, whether the chosen one is still the right one, and what is worth doing next. Propose; the choice stays the owner\u2019s.",
1715
+ market: "Research the market again: who this is for, who else is there now, and what has changed since the last report. Write it into the Market screen."
1716
+ },
1513
1717
  analysisAnswered: (answered, total) => `${answered} of ${total} answered`,
1514
1718
  analysisAllDecided: "Every question on this screen has an answer.",
1515
1719
  choicesTitle: "Standing answers",
@@ -1617,6 +1821,30 @@ var UI = {
1617
1821
  board: "Tablero",
1618
1822
  analysis: "An\xE1lisis",
1619
1823
  history: "Revisiones",
1824
+ updateTitle: "El kit sobre el que corre este panel",
1825
+ updateSubtitle: "Qu\xE9 hay instalado, y qu\xE9 se ha publicado desde entonces.",
1826
+ updateCurrent: (version) => `Instalada: v${version}`,
1827
+ updateAvailable: (version) => `Se ha publicado la v${version}.`,
1828
+ updateUpToDate: "Esta es la versi\xF3n publicada m\xE1s reciente.",
1829
+ updateUnknown: "No se pudo consultar el registro, as\xED que no hay nada que decir en ning\xFAn sentido.",
1830
+ updateCreateCard: "A\xF1adir una tarjeta pidi\xE9ndolo",
1831
+ updateCardExists: "El tablero ya lleva una tarjeta para esta versi\xF3n.",
1832
+ updateAsOrder: "Escribirla como orden, no como sugerencia",
1833
+ updateAsOrderHow: "Esto no actualiza nada por su cuenta \u2014 el panel no puede ejecutar npm. Decide si la tarjeta que escribe pide la actualizaci\xF3n o la manda.",
1834
+ notifUpdate: "Se ha publicado un Paneltir m\xE1s nuevo",
1835
+ releaseTitle: (version) => `Qu\xE9 cambia la v${version}`,
1836
+ releaseDate: (date) => `Publicada el ${date}`,
1837
+ releaseShape: {
1838
+ breaking: "Trae un cambio que puede romper cosas",
1839
+ feature: "Novedades, y correcciones",
1840
+ fix: "Correcciones menores",
1841
+ chore: "Mantenimiento"
1842
+ },
1843
+ releaseKind: { breaking: "Rompe", feature: "Nuevo", fix: "Arreglo", chore: "Interno" },
1844
+ releaseClose: "Cerrar",
1845
+ releaseNone: "Esta versi\xF3n se public\xF3 sin notas.",
1846
+ updateCardTitle: (version) => `Actualizar Paneltir a la v${version}`,
1847
+ updateCardBody: (version) => `Ejecuta \`npm install paneltir@${version}\` en este proyecto y comprueba que el panel sigue construy\xE9ndose y dibuj\xE1ndose. La versi\xF3n en uso la reporta \`paneltirBuild\`, as\xED que se puede confirmar en vez de darla por hecha.`,
1620
1848
  cardDetail: "Tarjeta",
1621
1849
  panelSettings: "Ajustes del panel",
1622
1850
  title: "T\xEDtulo",
@@ -1697,6 +1925,28 @@ var UI = {
1697
1925
  fixTokenPaste: "P\xE9galo en el proyecto de hosting como GH_TOKEN. Nunca en el repositorio: un token en un commit es un token que hay que revocar.",
1698
1926
  fixTokenRedeploy: "Vuelve a desplegar. Las variables de entorno se leen al desplegar, as\xED que un despliegue en marcha no ver\xE1 una nueva.",
1699
1927
  fixRepo: "Pon PANEL_REPO en el proyecto de hosting con el owner/repo de este proyecto, y vuelve a desplegar.",
1928
+ wizardTitle: "Poniendo en marcha este panel",
1929
+ wizardProgress: (index, total) => `Paso ${index} de ${total}`,
1930
+ wizardNowDo: "Haz esto ahora",
1931
+ wizardCheck: "Compru\xE9balo ya",
1932
+ wizardChecking: "Preguntando al servidor\u2026",
1933
+ wizardStillMissing: "Sigue sin estar. Si acabas de ponerlo, vuelve a desplegar \u2014 un despliegue en marcha no ve una variable nueva.",
1934
+ wizardCannotTell: "El panel no pudo preguntarle a su propio servidor, as\xED que no puede decir ni que s\xED ni que no. \xC9se es otro problema distinto a que falte una variable, y merece arreglarse antes.",
1935
+ wizardDoneTitle: "Ya est\xE1 puesto",
1936
+ wizardReadyTitle: "Eso es todo.",
1937
+ wizardReadyBody: "A partir de ahora los guardados se confirman en el repositorio. Dos cosas merecen probarse antes de fiarte de la puerta:",
1938
+ wizardVerify: [
1939
+ "Abre /admin sin sesi\xF3n. Debe llevarte a la pantalla de entrada, no al panel.",
1940
+ "Sin sesi\xF3n, pide el bundle de JavaScript del propio panel. Debe responder 401. Una p\xE1gina protegida cuyo bundle no lo est\xE1 deja el tablero legible para cualquiera que abra el HTML."
1941
+ ],
1942
+ wizardClose: "Cerrar",
1943
+ wizardStuckTitle: "Si algo de esto no queda claro",
1944
+ wizardStuckBody: "Este proyecto tiene su propio Claude, y `paneltir init` le dej\xF3 escrita una gu\xEDa que cubre justo esto. Pega la l\xEDnea de abajo en una sesi\xF3n dentro de este repositorio y te lo ir\xE1 explicando con el detalle que necesites.",
1945
+ wizardStuckPrompt: "Lee .claude/skills/panel/SKILL.md y pon en marcha conmigo el panel de Paneltir: dime cada variable de entorno que necesita, para qu\xE9 sirve, d\xF3nde ponerla en este proyecto, y comprueba las que ya est\xE1n.",
1946
+ wizardCopy: "Copiar el texto",
1947
+ wizardCopied: "Copiado",
1948
+ wizardOpen: "Gu\xEDame paso a paso",
1949
+ wizardBanner: "A este panel le falta terminar de configurarse: guardar fallar\xE1 hasta que lo est\xE9.",
1700
1950
  demoTourWelcomeTitle: "Un panel de verdad, y a\xFAn no se guarda nada",
1701
1951
  demoTourWelcomeBody: "Aqu\xED funciona todo: la empresa de transporte es inventada, el panel no. Mueve cosas, abre cosas, r\xF3mpelas \u2014 no puedes estropear nada.",
1702
1952
  demoTourBoardTitle: "Arrastra una tarjeta, y luego abre una",
@@ -1771,6 +2021,20 @@ var UI = {
1771
2021
  strategy: "Los caminos abiertos, el elegido, y lo que merece la pena hacer ahora.",
1772
2022
  market: "Para qui\xE9n es esto, y qui\xE9n m\xE1s est\xE1 ya ah\xED."
1773
2023
  },
2024
+ analysisRedo: "Pedirlo otra vez",
2025
+ analysisRedoAsked: "Pedido. Cae como tarjeta, y la siguiente sesi\xF3n hace el trabajo.",
2026
+ analysisRedoTitle: {
2027
+ board: "Leer el tablero otra vez y decir qu\xE9 suma",
2028
+ project: "Revisar para qu\xE9 es esto y c\xF3mo se mide",
2029
+ strategy: "Trabajar la estrategia otra vez y proponer qu\xE9 sigue",
2030
+ market: "Un informe de mercado nuevo"
2031
+ },
2032
+ analysisRedoBody: {
2033
+ board: "El tablero se ha movido desde la \xFAltima lectura. Repasa las tarjetas, di qu\xE9 suman ahora, y escribe las preguntas que merecen respuesta y nadie ha hecho.",
2034
+ project: "Mira otra vez los objetivos, las restricciones y las m\xE9tricas. Di cu\xE1les ya no encajan con lo que el proyecto ha llegado a ser, y prop\xF3n el cambio en vez de hacerlo.",
2035
+ strategy: "Mira las estrategias registradas, si la elegida sigue siendo la buena, y qu\xE9 merece la pena hacer ahora. Prop\xF3n; la elecci\xF3n sigue siendo del due\xF1o.",
2036
+ market: "Investiga el mercado otra vez: para qui\xE9n es esto, qui\xE9n m\xE1s est\xE1 ahora, y qu\xE9 ha cambiado desde el \xFAltimo informe. Escr\xEDbelo en la pantalla de Mercado."
2037
+ },
1774
2038
  analysisAnswered: (answered, total) => `${answered} de ${total} contestadas`,
1775
2039
  analysisAllDecided: "Todas las preguntas de esta pantalla tienen respuesta.",
1776
2040
  choicesTitle: "Respuestas fijas",
@@ -1873,7 +2137,7 @@ var UI = {
1873
2137
  };
1874
2138
 
1875
2139
  // src/panel/AnalysisView.tsx
1876
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2140
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1877
2141
  var SUGGESTION_STATUSES = ["new", "doing", "done", "dismissed"];
1878
2142
  function MetricTile({ metric, lang, ui }) {
1879
2143
  const { latest, delta, against } = trendOf(metric);
@@ -1882,23 +2146,23 @@ function MetricTile({ metric, lang, ui }) {
1882
2146
  const height = 34;
1883
2147
  const path = points.map((point) => `${(point.x * width).toFixed(1)},${(point.y * (height - 6) + 3).toFixed(1)}`);
1884
2148
  const last = points[points.length - 1];
1885
- return /* @__PURE__ */ jsxs14("article", { className: "pt-metric", children: [
1886
- /* @__PURE__ */ jsx16("p", { className: "pt-metric__label", children: text(metric.label, lang) }),
1887
- /* @__PURE__ */ jsxs14("p", { className: "pt-metric__value", children: [
2149
+ return /* @__PURE__ */ jsxs15("article", { className: "pt-metric", children: [
2150
+ /* @__PURE__ */ jsx17("p", { className: "pt-metric__label", children: text(metric.label, lang) }),
2151
+ /* @__PURE__ */ jsxs15("p", { className: "pt-metric__value", children: [
1888
2152
  latest ? latest.value : "\u2014",
1889
- /* @__PURE__ */ jsx16("span", { className: "pt-metric__unit", children: metric.unit })
2153
+ /* @__PURE__ */ jsx17("span", { className: "pt-metric__unit", children: metric.unit })
1890
2154
  ] }),
1891
- delta !== null && /* @__PURE__ */ jsxs14("p", { className: `pt-metric__delta${against ? " is-against" : " is-with"}`, children: [
2155
+ delta !== null && /* @__PURE__ */ jsxs15("p", { className: `pt-metric__delta${against ? " is-against" : " is-with"}`, children: [
1892
2156
  delta > 0 ? "\u25B2" : delta < 0 ? "\u25BC" : "\u25A0",
1893
2157
  " ",
1894
2158
  delta > 0 ? "+" : "",
1895
2159
  delta,
1896
- /* @__PURE__ */ jsxs14("span", { className: "pt-metric__since", children: [
2160
+ /* @__PURE__ */ jsxs15("span", { className: "pt-metric__since", children: [
1897
2161
  " \xB7 ",
1898
2162
  against ? ui.metricAgainst : ui.metricWith
1899
2163
  ] })
1900
2164
  ] }),
1901
- points.length > 1 && /* @__PURE__ */ jsxs14(
2165
+ points.length > 1 && /* @__PURE__ */ jsxs15(
1902
2166
  "svg",
1903
2167
  {
1904
2168
  className: "pt-metric__spark",
@@ -1908,12 +2172,12 @@ function MetricTile({ metric, lang, ui }) {
1908
2172
  role: "img",
1909
2173
  "aria-label": `${text(metric.label, lang)}: ${metric.readings.map((r) => `${r.date} ${r.value}`).join(", ")}`,
1910
2174
  children: [
1911
- /* @__PURE__ */ jsx16("polyline", { points: path.join(" "), fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
1912
- last && /* @__PURE__ */ jsx16("circle", { cx: last.x * width, cy: last.y * (height - 6) + 3, r: "3.5", className: "pt-metric__point" })
2175
+ /* @__PURE__ */ jsx17("polyline", { points: path.join(" "), fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
2176
+ last && /* @__PURE__ */ jsx17("circle", { cx: last.x * width, cy: last.y * (height - 6) + 3, r: "3.5", className: "pt-metric__point" })
1913
2177
  ]
1914
2178
  }
1915
2179
  ),
1916
- latest?.note && /* @__PURE__ */ jsx16("p", { className: "pt-metric__note", children: text(latest.note, lang) })
2180
+ latest?.note && /* @__PURE__ */ jsx17("p", { className: "pt-metric__note", children: text(latest.note, lang) })
1917
2181
  ] });
1918
2182
  }
1919
2183
  function ChoiceCard({
@@ -1924,11 +2188,11 @@ function ChoiceCard({
1924
2188
  onDecide
1925
2189
  }) {
1926
2190
  const answered = choice.options.find((option) => option.id === choice.value);
1927
- return /* @__PURE__ */ jsxs14("article", { className: `pt-choice${answered ? " is-decided" : ""}`, children: [
1928
- /* @__PURE__ */ jsx16("p", { className: "pt-choice__state", children: answered ? ui.choiceDecidedAt(choice.decidedAt ?? "") : ui.choiceOpen }),
1929
- /* @__PURE__ */ jsx16("p", { className: "pt-choice__question", children: text(choice.question, lang) }),
1930
- choice.why && /* @__PURE__ */ jsx16("p", { className: "pt-choice__why", children: text(choice.why, lang) }),
1931
- /* @__PURE__ */ jsx16("div", { className: "pt-panel-row pt-choice__options", children: choice.options.map((option) => /* @__PURE__ */ jsx16(
2191
+ return /* @__PURE__ */ jsxs15("article", { className: `pt-choice${answered ? " is-decided" : ""}`, children: [
2192
+ /* @__PURE__ */ jsx17("p", { className: "pt-choice__state", children: answered ? ui.choiceDecidedAt(choice.decidedAt ?? "") : ui.choiceOpen }),
2193
+ /* @__PURE__ */ jsx17("p", { className: "pt-choice__question", children: text(choice.question, lang) }),
2194
+ choice.why && /* @__PURE__ */ jsx17("p", { className: "pt-choice__why", children: text(choice.why, lang) }),
2195
+ /* @__PURE__ */ jsx17("div", { className: "pt-panel-row pt-choice__options", children: choice.options.map((option) => /* @__PURE__ */ jsx17(
1932
2196
  FilterChip,
1933
2197
  {
1934
2198
  label: text(option.label, lang),
@@ -1937,8 +2201,8 @@ function ChoiceCard({
1937
2201
  },
1938
2202
  option.id
1939
2203
  )) }),
1940
- answered?.detail && /* @__PURE__ */ jsx16("p", { className: "pt-choice__detail", children: text(answered.detail, lang) }),
1941
- answered && /* @__PURE__ */ jsx16(
2204
+ answered?.detail && /* @__PURE__ */ jsx17("p", { className: "pt-choice__detail", children: text(answered.detail, lang) }),
2205
+ answered && /* @__PURE__ */ jsx17(
1942
2206
  "button",
1943
2207
  {
1944
2208
  type: "button",
@@ -1957,10 +2221,10 @@ function Choices({
1957
2221
  onDecide
1958
2222
  }) {
1959
2223
  const choices = analysis.choices?.[section] ?? [];
1960
- return /* @__PURE__ */ jsxs14("section", { children: [
1961
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.choicesTitle }),
1962
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.choicesIntro }),
1963
- choices.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "pt-analysis__empty", children: ui.choicesNone }) : /* @__PURE__ */ jsx16("div", { className: "pt-choice-grid", children: choices.map((choice) => /* @__PURE__ */ jsx16(
2224
+ return /* @__PURE__ */ jsxs15("section", { children: [
2225
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.choicesTitle }),
2226
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.choicesIntro }),
2227
+ choices.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "pt-analysis__empty", children: ui.choicesNone }) : /* @__PURE__ */ jsx17("div", { className: "pt-choice-grid", children: choices.map((choice) => /* @__PURE__ */ jsx17(
1964
2228
  ChoiceCard,
1965
2229
  {
1966
2230
  section,
@@ -1983,26 +2247,28 @@ function AnalysisView({
1983
2247
  onChooseStrategy,
1984
2248
  onSuggestionStatus,
1985
2249
  onDecide,
1986
- onOpenCard
2250
+ onOpenCard,
2251
+ onRequestReport
1987
2252
  }) {
1988
2253
  const t = (value) => text(value, lang);
1989
- const [section, setSection] = useState6("board");
2254
+ const [section, setSection] = useState7("board");
1990
2255
  const facts = useMemo3(() => boardFacts(cards, columns, today2), [cards, columns, today2]);
1991
2256
  const answers = useMemo3(() => decided(analysis), [analysis]);
1992
2257
  const open = useMemo3(() => undecided(analysis), [analysis]);
1993
2258
  const total = answers.length + open.length;
1994
2259
  const here = analysis.choices?.[section] ?? [];
1995
2260
  const answeredHere = here.filter((choice) => choice.options.some((option) => option.id === choice.value)).length;
1996
- return /* @__PURE__ */ jsxs14("div", { className: "pt-panel-page pt-panel-section pt-analysis", children: [
1997
- /* @__PURE__ */ jsxs14("section", { children: [
1998
- /* @__PURE__ */ jsx16("p", { className: "pt-eyebrow", children: ui.analysisEyebrow }),
1999
- /* @__PURE__ */ jsx16("h2", { className: "pt-h2", children: ui.analysisSections[section] }),
2000
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.analysisSectionHints[section] }),
2001
- /* @__PURE__ */ jsx16("nav", { className: "pt-analysis__nav", "aria-label": ui.analysis, children: ANALYSIS_SECTIONS.map((id) => {
2261
+ return /* @__PURE__ */ jsxs15("div", { className: "pt-panel-page pt-panel-section pt-analysis", children: [
2262
+ /* @__PURE__ */ jsxs15("section", { children: [
2263
+ /* @__PURE__ */ jsx17("p", { className: "pt-eyebrow", children: ui.analysisEyebrow }),
2264
+ /* @__PURE__ */ jsx17("h2", { className: "pt-h2", children: ui.analysisSections[section] }),
2265
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.analysisSectionHints[section] }),
2266
+ onRequestReport && /* @__PURE__ */ jsx17("p", { className: "pt-panel-row", children: /* @__PURE__ */ jsx17("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: () => onRequestReport(section), children: ui.analysisRedo }) }),
2267
+ /* @__PURE__ */ jsx17("nav", { className: "pt-analysis__nav", "aria-label": ui.analysis, children: ANALYSIS_SECTIONS.map((id) => {
2002
2268
  const count = (analysis.choices?.[id] ?? []).filter(
2003
2269
  (choice) => !choice.options.some((option) => option.id === choice.value)
2004
2270
  ).length;
2005
- return /* @__PURE__ */ jsxs14(
2271
+ return /* @__PURE__ */ jsxs15(
2006
2272
  "button",
2007
2273
  {
2008
2274
  type: "button",
@@ -2011,110 +2277,110 @@ function AnalysisView({
2011
2277
  onClick: () => setSection(id),
2012
2278
  children: [
2013
2279
  ui.analysisSections[id],
2014
- count > 0 && /* @__PURE__ */ jsx16("span", { className: "pt-analysis__open", "aria-hidden": "true", children: count })
2280
+ count > 0 && /* @__PURE__ */ jsx17("span", { className: "pt-analysis__open", "aria-hidden": "true", children: count })
2015
2281
  ]
2016
2282
  },
2017
2283
  id
2018
2284
  );
2019
2285
  }) }),
2020
- here.length > 0 && /* @__PURE__ */ jsxs14("p", { className: "pt-analysis__stage", children: [
2286
+ here.length > 0 && /* @__PURE__ */ jsxs15("p", { className: "pt-analysis__stage", children: [
2021
2287
  ui.analysisAnswered(answeredHere, here.length),
2022
- answeredHere === here.length && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2288
+ answeredHere === here.length && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2023
2289
  " \xB7 ",
2024
2290
  ui.analysisAllDecided
2025
2291
  ] })
2026
2292
  ] })
2027
2293
  ] }),
2028
- section === "board" && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2029
- /* @__PURE__ */ jsxs14("section", { children: [
2030
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.boardFactsTitle }),
2031
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.boardFactsIntro }),
2032
- /* @__PURE__ */ jsx16("div", { className: "pt-fact-grid", children: [
2294
+ section === "board" && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2295
+ /* @__PURE__ */ jsxs15("section", { children: [
2296
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.boardFactsTitle }),
2297
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.boardFactsIntro }),
2298
+ /* @__PURE__ */ jsx17("div", { className: "pt-fact-grid", children: [
2033
2299
  [ui.factOpen, String(facts.open)],
2034
2300
  [ui.factWaiting, String(facts.waitingOnOwner)],
2035
2301
  [ui.factOrders, String(facts.orders)],
2036
2302
  [ui.factHighRisk, String(facts.highRisk)]
2037
- ].map(([label, value]) => /* @__PURE__ */ jsxs14("article", { className: "pt-fact", children: [
2038
- /* @__PURE__ */ jsx16("p", { className: "pt-fact__label", children: label }),
2039
- /* @__PURE__ */ jsx16("p", { className: "pt-fact__value", children: value })
2303
+ ].map(([label, value]) => /* @__PURE__ */ jsxs15("article", { className: "pt-fact", children: [
2304
+ /* @__PURE__ */ jsx17("p", { className: "pt-fact__label", children: label }),
2305
+ /* @__PURE__ */ jsx17("p", { className: "pt-fact__value", children: value })
2040
2306
  ] }, label)) }),
2041
- /* @__PURE__ */ jsx16("h4", { className: "pt-analysis__minor", children: ui.factColumnsTitle }),
2042
- /* @__PURE__ */ jsx16("ul", { className: "pt-analysis__list", children: facts.byColumn.map((column) => /* @__PURE__ */ jsxs14("li", { className: "pt-analysis__goal", children: [
2043
- /* @__PURE__ */ jsx16("span", { children: t(column.title) }),
2044
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: column.count })
2307
+ /* @__PURE__ */ jsx17("h4", { className: "pt-analysis__minor", children: ui.factColumnsTitle }),
2308
+ /* @__PURE__ */ jsx17("ul", { className: "pt-analysis__list", children: facts.byColumn.map((column) => /* @__PURE__ */ jsxs15("li", { className: "pt-analysis__goal", children: [
2309
+ /* @__PURE__ */ jsx17("span", { children: t(column.title) }),
2310
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: column.count })
2045
2311
  ] }, column.id)) }),
2046
- facts.oldestOpen && facts.oldestOpenDays !== null && /* @__PURE__ */ jsxs14("p", { className: "pt-analysis__stage", children: [
2312
+ facts.oldestOpen && facts.oldestOpenDays !== null && /* @__PURE__ */ jsxs15("p", { className: "pt-analysis__stage", children: [
2047
2313
  ui.factOldest,
2048
2314
  ": ",
2049
- /* @__PURE__ */ jsx16("strong", { children: ui.factDays(facts.oldestOpenDays) }),
2315
+ /* @__PURE__ */ jsx17("strong", { children: ui.factDays(facts.oldestOpenDays) }),
2050
2316
  " \xB7 ",
2051
2317
  t(facts.oldestOpen.title)
2052
2318
  ] })
2053
2319
  ] }),
2054
- /* @__PURE__ */ jsxs14("section", { children: [
2055
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.factClaimedTitle }),
2056
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.factClaimedIntro }),
2057
- facts.claimed.length === 0 ? /* @__PURE__ */ jsx16("p", { className: "pt-analysis__empty", children: ui.factClaimedNone }) : /* @__PURE__ */ jsx16("ul", { className: "pt-analysis__list", children: facts.claimed.map((card) => /* @__PURE__ */ jsxs14("li", { className: "pt-analysis__goal", children: [
2058
- /* @__PURE__ */ jsx16("button", { type: "button", className: "pt-analysis__link", onClick: () => onOpenCard?.(card.id), children: t(card.title) || ui.untitled }),
2059
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: ui.neverStarted })
2320
+ /* @__PURE__ */ jsxs15("section", { children: [
2321
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.factClaimedTitle }),
2322
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.factClaimedIntro }),
2323
+ facts.claimed.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "pt-analysis__empty", children: ui.factClaimedNone }) : /* @__PURE__ */ jsx17("ul", { className: "pt-analysis__list", children: facts.claimed.map((card) => /* @__PURE__ */ jsxs15("li", { className: "pt-analysis__goal", children: [
2324
+ /* @__PURE__ */ jsx17("button", { type: "button", className: "pt-analysis__link", onClick: () => onOpenCard?.(card.id), children: t(card.title) || ui.untitled }),
2325
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: ui.neverStarted })
2060
2326
  ] }, card.id)) })
2061
2327
  ] })
2062
2328
  ] }),
2063
- section === "project" && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2064
- /* @__PURE__ */ jsxs14("section", { children: [
2065
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.briefTitle }),
2066
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: t(analysis.brief) }),
2067
- /* @__PURE__ */ jsxs14("p", { className: "pt-analysis__stage", children: [
2329
+ section === "project" && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2330
+ /* @__PURE__ */ jsxs15("section", { children: [
2331
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.briefTitle }),
2332
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: t(analysis.brief) }),
2333
+ /* @__PURE__ */ jsxs15("p", { className: "pt-analysis__stage", children: [
2068
2334
  ui.stage,
2069
2335
  ": ",
2070
- /* @__PURE__ */ jsx16("strong", { children: analysis.stage })
2336
+ /* @__PURE__ */ jsx17("strong", { children: analysis.stage })
2071
2337
  ] })
2072
2338
  ] }),
2073
- /* @__PURE__ */ jsxs14("section", { className: "pt-analysis__split", children: [
2074
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2075
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.goalsTitle }),
2076
- /* @__PURE__ */ jsx16("ul", { className: "pt-analysis__list", children: analysis.goals.map((goal) => /* @__PURE__ */ jsxs14("li", { className: `pt-analysis__goal is-${goal.weight}`, children: [
2077
- /* @__PURE__ */ jsx16("span", { children: t(goal.label) }),
2078
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: ui.weights[goal.weight] })
2339
+ /* @__PURE__ */ jsxs15("section", { className: "pt-analysis__split", children: [
2340
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2341
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.goalsTitle }),
2342
+ /* @__PURE__ */ jsx17("ul", { className: "pt-analysis__list", children: analysis.goals.map((goal) => /* @__PURE__ */ jsxs15("li", { className: `pt-analysis__goal is-${goal.weight}`, children: [
2343
+ /* @__PURE__ */ jsx17("span", { children: t(goal.label) }),
2344
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: ui.weights[goal.weight] })
2079
2345
  ] }, goal.id)) })
2080
2346
  ] }),
2081
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2082
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.constraintsTitle }),
2083
- /* @__PURE__ */ jsx16("ul", { className: "pt-analysis__list", children: analysis.constraints.map((constraint) => /* @__PURE__ */ jsxs14("li", { className: `pt-analysis__goal${constraint.on ? "" : " is-off"}`, children: [
2084
- /* @__PURE__ */ jsx16("span", { children: t(constraint.label) }),
2085
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: constraint.on ? ui.constraintOn : ui.constraintOff })
2347
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2348
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.constraintsTitle }),
2349
+ /* @__PURE__ */ jsx17("ul", { className: "pt-analysis__list", children: analysis.constraints.map((constraint) => /* @__PURE__ */ jsxs15("li", { className: `pt-analysis__goal${constraint.on ? "" : " is-off"}`, children: [
2350
+ /* @__PURE__ */ jsx17("span", { children: t(constraint.label) }),
2351
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: constraint.on ? ui.constraintOn : ui.constraintOff })
2086
2352
  ] }, constraint.id)) })
2087
2353
  ] })
2088
2354
  ] }),
2089
- /* @__PURE__ */ jsxs14("section", { children: [
2090
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.metricsTitle }),
2091
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.metricsIntro }),
2092
- /* @__PURE__ */ jsx16("div", { className: "pt-metric-grid", children: analysis.metrics.map((metric) => /* @__PURE__ */ jsx16(MetricTile, { metric, lang, ui }, metric.id)) })
2355
+ /* @__PURE__ */ jsxs15("section", { children: [
2356
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.metricsTitle }),
2357
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.metricsIntro }),
2358
+ /* @__PURE__ */ jsx17("div", { className: "pt-metric-grid", children: analysis.metrics.map((metric) => /* @__PURE__ */ jsx17(MetricTile, { metric, lang, ui }, metric.id)) })
2093
2359
  ] })
2094
2360
  ] }),
2095
- section === "strategy" && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2096
- /* @__PURE__ */ jsxs14("section", { children: [
2097
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.strategiesTitle }),
2098
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: analysis.chosen ? ui.strategyChosenHint : ui.strategyOpenHint }),
2099
- /* @__PURE__ */ jsx16("div", { className: "pt-strategy-grid", children: analysis.strategies.map((strategy) => {
2361
+ section === "strategy" && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2362
+ /* @__PURE__ */ jsxs15("section", { children: [
2363
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.strategiesTitle }),
2364
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: analysis.chosen ? ui.strategyChosenHint : ui.strategyOpenHint }),
2365
+ /* @__PURE__ */ jsx17("div", { className: "pt-strategy-grid", children: analysis.strategies.map((strategy) => {
2100
2366
  const chosen = analysis.chosen === strategy.id;
2101
- return /* @__PURE__ */ jsxs14("article", { className: `pt-strategy pt-hud${chosen ? " is-chosen" : ""}`, children: [
2102
- /* @__PURE__ */ jsx16("h4", { className: "pt-strategy__title", children: t(strategy.title) }),
2103
- /* @__PURE__ */ jsx16("p", { className: "pt-panel-text", children: t(strategy.thesis) }),
2104
- /* @__PURE__ */ jsx16("dl", { className: "pt-strategy__meters", children: [
2367
+ return /* @__PURE__ */ jsxs15("article", { className: `pt-strategy pt-hud${chosen ? " is-chosen" : ""}`, children: [
2368
+ /* @__PURE__ */ jsx17("h4", { className: "pt-strategy__title", children: t(strategy.title) }),
2369
+ /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: t(strategy.thesis) }),
2370
+ /* @__PURE__ */ jsx17("dl", { className: "pt-strategy__meters", children: [
2105
2371
  [ui.effort, strategy.effort],
2106
2372
  [ui.riskShort, strategy.risk],
2107
2373
  [ui.upside, strategy.upside]
2108
- ].map(([label, value]) => /* @__PURE__ */ jsxs14("div", { children: [
2109
- /* @__PURE__ */ jsx16("dt", { children: label }),
2110
- /* @__PURE__ */ jsxs14("dd", { children: [
2111
- /* @__PURE__ */ jsx16("span", { className: "pt-strategy__track", children: /* @__PURE__ */ jsx16("span", { className: "pt-strategy__fill", style: { width: `${value * 10}%` } }) }),
2112
- /* @__PURE__ */ jsx16("b", { children: value })
2374
+ ].map(([label, value]) => /* @__PURE__ */ jsxs15("div", { children: [
2375
+ /* @__PURE__ */ jsx17("dt", { children: label }),
2376
+ /* @__PURE__ */ jsxs15("dd", { children: [
2377
+ /* @__PURE__ */ jsx17("span", { className: "pt-strategy__track", children: /* @__PURE__ */ jsx17("span", { className: "pt-strategy__fill", style: { width: `${value * 10}%` } }) }),
2378
+ /* @__PURE__ */ jsx17("b", { children: value })
2113
2379
  ] })
2114
2380
  ] }, label)) }),
2115
- /* @__PURE__ */ jsx16("p", { className: "pt-strategy__horizon", children: t(strategy.horizon) }),
2116
- /* @__PURE__ */ jsx16("ul", { className: "pt-cap__list", children: strategy.moves.map((move) => /* @__PURE__ */ jsx16("li", { children: t(move) }, t(move))) }),
2117
- /* @__PURE__ */ jsx16(
2381
+ /* @__PURE__ */ jsx17("p", { className: "pt-strategy__horizon", children: t(strategy.horizon) }),
2382
+ /* @__PURE__ */ jsx17("ul", { className: "pt-cap__list", children: strategy.moves.map((move) => /* @__PURE__ */ jsx17("li", { children: t(move) }, t(move))) }),
2383
+ /* @__PURE__ */ jsx17(
2118
2384
  FilterChip,
2119
2385
  {
2120
2386
  label: chosen ? ui.strategyChosen : ui.strategyChoose,
@@ -2125,19 +2391,19 @@ function AnalysisView({
2125
2391
  ] }, strategy.id);
2126
2392
  }) })
2127
2393
  ] }),
2128
- /* @__PURE__ */ jsxs14("section", { children: [
2129
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.suggestionsTitle }),
2130
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.suggestionsIntro }),
2131
- /* @__PURE__ */ jsx16("ul", { className: "pt-analysis__suggestions", children: analysis.suggestions.map((suggestion) => /* @__PURE__ */ jsxs14("li", { className: `pt-suggestion pt-hud is-${suggestion.severity}`, children: [
2132
- /* @__PURE__ */ jsxs14("p", { className: "pt-suggestion__meta", children: [
2394
+ /* @__PURE__ */ jsxs15("section", { children: [
2395
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.suggestionsTitle }),
2396
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.suggestionsIntro }),
2397
+ /* @__PURE__ */ jsx17("ul", { className: "pt-analysis__suggestions", children: analysis.suggestions.map((suggestion) => /* @__PURE__ */ jsxs15("li", { className: `pt-suggestion pt-hud is-${suggestion.severity}`, children: [
2398
+ /* @__PURE__ */ jsxs15("p", { className: "pt-suggestion__meta", children: [
2133
2399
  suggestion.area,
2134
2400
  " \xB7 ",
2135
2401
  ui.severities[suggestion.severity],
2136
2402
  " \xB7 ",
2137
2403
  suggestion.date
2138
2404
  ] }),
2139
- /* @__PURE__ */ jsx16("p", { className: "pt-panel-text", children: t(suggestion.text) }),
2140
- /* @__PURE__ */ jsx16("div", { className: "pt-panel-row", children: SUGGESTION_STATUSES.map((status) => /* @__PURE__ */ jsx16(
2405
+ /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: t(suggestion.text) }),
2406
+ /* @__PURE__ */ jsx17("div", { className: "pt-panel-row", children: SUGGESTION_STATUSES.map((status) => /* @__PURE__ */ jsx17(
2141
2407
  FilterChip,
2142
2408
  {
2143
2409
  label: ui.suggestionStatuses[status],
@@ -2149,67 +2415,67 @@ function AnalysisView({
2149
2415
  ] }, suggestion.id)) })
2150
2416
  ] })
2151
2417
  ] }),
2152
- section === "market" && /* @__PURE__ */ jsx16("section", { children: analysis.market ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
2153
- /* @__PURE__ */ jsxs14("div", { className: "pt-analysis__split", children: [
2154
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2155
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.audienceTitle }),
2156
- /* @__PURE__ */ jsx16("p", { className: "pt-panel-text", children: t(analysis.market.audience) })
2418
+ section === "market" && /* @__PURE__ */ jsx17("section", { children: analysis.market ? /* @__PURE__ */ jsxs15(Fragment3, { children: [
2419
+ /* @__PURE__ */ jsxs15("div", { className: "pt-analysis__split", children: [
2420
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2421
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.audienceTitle }),
2422
+ /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: t(analysis.market.audience) })
2157
2423
  ] }),
2158
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2159
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.positioningTitle }),
2160
- /* @__PURE__ */ jsx16("p", { className: "pt-panel-text", children: t(analysis.market.positioning) })
2424
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2425
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.positioningTitle }),
2426
+ /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: t(analysis.market.positioning) })
2161
2427
  ] })
2162
2428
  ] }),
2163
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.competitorsTitle }),
2164
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.marketIntro }),
2165
- /* @__PURE__ */ jsx16("div", { className: "pt-rival-grid", children: analysis.market.competitors.map((rival) => /* @__PURE__ */ jsxs14("article", { className: "pt-rival pt-hud", children: [
2166
- /* @__PURE__ */ jsx16("h4", { className: "pt-rival__name", children: rival.name }),
2167
- /* @__PURE__ */ jsxs14("p", { className: "pt-rival__line", children: [
2168
- /* @__PURE__ */ jsx16("span", { className: "pt-rival__tag", children: ui.competitorStrength }),
2429
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.competitorsTitle }),
2430
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.marketIntro }),
2431
+ /* @__PURE__ */ jsx17("div", { className: "pt-rival-grid", children: analysis.market.competitors.map((rival) => /* @__PURE__ */ jsxs15("article", { className: "pt-rival pt-hud", children: [
2432
+ /* @__PURE__ */ jsx17("h4", { className: "pt-rival__name", children: rival.name }),
2433
+ /* @__PURE__ */ jsxs15("p", { className: "pt-rival__line", children: [
2434
+ /* @__PURE__ */ jsx17("span", { className: "pt-rival__tag", children: ui.competitorStrength }),
2169
2435
  t(rival.strength)
2170
2436
  ] }),
2171
- /* @__PURE__ */ jsxs14("p", { className: "pt-rival__line is-gap", children: [
2172
- /* @__PURE__ */ jsx16("span", { className: "pt-rival__tag", children: ui.competitorGap }),
2437
+ /* @__PURE__ */ jsxs15("p", { className: "pt-rival__line is-gap", children: [
2438
+ /* @__PURE__ */ jsx17("span", { className: "pt-rival__tag", children: ui.competitorGap }),
2173
2439
  t(rival.gap)
2174
2440
  ] })
2175
2441
  ] }, rival.id)) }),
2176
- analysis.market.pricing && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2177
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.pricingTitle }),
2178
- /* @__PURE__ */ jsx16("p", { className: "pt-panel-text", children: t(analysis.market.pricing) })
2442
+ analysis.market.pricing && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2443
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.pricingTitle }),
2444
+ /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: t(analysis.market.pricing) })
2179
2445
  ] }),
2180
- analysis.market.notes && analysis.market.notes.length > 0 && /* @__PURE__ */ jsxs14(Fragment3, { children: [
2181
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.marketNotesTitle }),
2182
- /* @__PURE__ */ jsx16("ul", { className: "pt-cap__list", children: analysis.market.notes.map((note) => /* @__PURE__ */ jsx16("li", { children: t(note) }, t(note))) })
2446
+ analysis.market.notes && analysis.market.notes.length > 0 && /* @__PURE__ */ jsxs15(Fragment3, { children: [
2447
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title pt-analysis__minor", children: ui.marketNotesTitle }),
2448
+ /* @__PURE__ */ jsx17("ul", { className: "pt-cap__list", children: analysis.market.notes.map((note) => /* @__PURE__ */ jsx17("li", { children: t(note) }, t(note))) })
2183
2449
  ] })
2184
- ] }) : /* @__PURE__ */ jsx16("p", { className: "pt-analysis__empty", children: ui.marketEmpty }) }),
2185
- /* @__PURE__ */ jsx16(Choices, { section, analysis, lang, ui, onDecide }),
2186
- total > 0 && /* @__PURE__ */ jsxs14("section", { className: "pt-analysis__split", children: [
2187
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2188
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.claudeReadsTitle }),
2189
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.claudeReadsIntro }),
2190
- /* @__PURE__ */ jsxs14("ul", { className: "pt-analysis__list", children: [
2191
- answers.map(({ section: from, choice, option }) => /* @__PURE__ */ jsxs14("li", { className: "pt-analysis__goal is-primary", children: [
2192
- /* @__PURE__ */ jsxs14("span", { children: [
2193
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__from", children: ui.analysisSections[from] }),
2450
+ ] }) : /* @__PURE__ */ jsx17("p", { className: "pt-analysis__empty", children: ui.marketEmpty }) }),
2451
+ /* @__PURE__ */ jsx17(Choices, { section, analysis, lang, ui, onDecide }),
2452
+ total > 0 && /* @__PURE__ */ jsxs15("section", { className: "pt-analysis__split", children: [
2453
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2454
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.claudeReadsTitle }),
2455
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.claudeReadsIntro }),
2456
+ /* @__PURE__ */ jsxs15("ul", { className: "pt-analysis__list", children: [
2457
+ answers.map(({ section: from, choice, option }) => /* @__PURE__ */ jsxs15("li", { className: "pt-analysis__goal is-primary", children: [
2458
+ /* @__PURE__ */ jsxs15("span", { children: [
2459
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__from", children: ui.analysisSections[from] }),
2194
2460
  t(choice.question)
2195
2461
  ] }),
2196
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: t(option.label) })
2462
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: t(option.label) })
2197
2463
  ] }, choice.id)),
2198
- answers.length === 0 && /* @__PURE__ */ jsx16("li", { className: "pt-analysis__goal is-off", children: ui.choicesNone })
2464
+ answers.length === 0 && /* @__PURE__ */ jsx17("li", { className: "pt-analysis__goal is-off", children: ui.choicesNone })
2199
2465
  ] })
2200
2466
  ] }),
2201
- /* @__PURE__ */ jsxs14("div", { className: "pt-cap pt-hud", children: [
2202
- /* @__PURE__ */ jsx16("h3", { className: "pt-cap__title", children: ui.claudeOpenTitle }),
2203
- /* @__PURE__ */ jsx16("p", { className: "pt-sub", children: ui.claudeOpenIntro }),
2204
- /* @__PURE__ */ jsxs14("ul", { className: "pt-analysis__list", children: [
2205
- open.map(({ section: from, choice }) => /* @__PURE__ */ jsxs14("li", { className: "pt-analysis__goal", children: [
2206
- /* @__PURE__ */ jsxs14("button", { type: "button", className: "pt-analysis__link", onClick: () => setSection(from), children: [
2207
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__from", children: ui.analysisSections[from] }),
2467
+ /* @__PURE__ */ jsxs15("div", { className: "pt-cap pt-hud", children: [
2468
+ /* @__PURE__ */ jsx17("h3", { className: "pt-cap__title", children: ui.claudeOpenTitle }),
2469
+ /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.claudeOpenIntro }),
2470
+ /* @__PURE__ */ jsxs15("ul", { className: "pt-analysis__list", children: [
2471
+ open.map(({ section: from, choice }) => /* @__PURE__ */ jsxs15("li", { className: "pt-analysis__goal", children: [
2472
+ /* @__PURE__ */ jsxs15("button", { type: "button", className: "pt-analysis__link", onClick: () => setSection(from), children: [
2473
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__from", children: ui.analysisSections[from] }),
2208
2474
  t(choice.question)
2209
2475
  ] }),
2210
- /* @__PURE__ */ jsx16("span", { className: "pt-analysis__weight", children: ui.choiceOpen })
2476
+ /* @__PURE__ */ jsx17("span", { className: "pt-analysis__weight", children: ui.choiceOpen })
2211
2477
  ] }, choice.id)),
2212
- open.length === 0 && /* @__PURE__ */ jsx16("li", { className: "pt-analysis__goal is-off", children: ui.analysisAllDecided })
2478
+ open.length === 0 && /* @__PURE__ */ jsx17("li", { className: "pt-analysis__goal is-off", children: ui.analysisAllDecided })
2213
2479
  ] })
2214
2480
  ] })
2215
2481
  ] })
@@ -2217,7 +2483,7 @@ function AnalysisView({
2217
2483
  }
2218
2484
 
2219
2485
  // src/panel/MarketplaceView.tsx
2220
- import { useMemo as useMemo4, useState as useState7 } from "react";
2486
+ import { useMemo as useMemo4, useState as useState8 } from "react";
2221
2487
 
2222
2488
  // src/panel/marketplace.ts
2223
2489
  var MARKETPLACE_NAME = "dfklabs";
@@ -2260,39 +2526,39 @@ function ageInWords(seconds, lang) {
2260
2526
  }
2261
2527
 
2262
2528
  // src/panel/MarketplaceView.tsx
2263
- import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2529
+ import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2264
2530
  function ToolRow({
2265
2531
  tool,
2266
2532
  lang,
2267
2533
  ui,
2268
2534
  onInstall
2269
2535
  }) {
2270
- return /* @__PURE__ */ jsxs15("article", { className: `pt-tool${tool.state ? ` is-${tool.state}` : " is-command"}`, children: [
2271
- /* @__PURE__ */ jsxs15("div", { className: "pt-tool__head", children: [
2272
- /* @__PURE__ */ jsx17("h3", { className: "pt-tool__name", children: tool.name }),
2273
- /* @__PURE__ */ jsx17("span", { className: "pt-tool__state", children: tool.state ? ui.installStates[tool.state] : ui.toolCommandOnly })
2536
+ return /* @__PURE__ */ jsxs16("article", { className: `pt-tool${tool.state ? ` is-${tool.state}` : " is-command"}`, children: [
2537
+ /* @__PURE__ */ jsxs16("div", { className: "pt-tool__head", children: [
2538
+ /* @__PURE__ */ jsx18("h3", { className: "pt-tool__name", children: tool.name }),
2539
+ /* @__PURE__ */ jsx18("span", { className: "pt-tool__state", children: tool.state ? ui.installStates[tool.state] : ui.toolCommandOnly })
2274
2540
  ] }),
2275
- tool.summary && /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: tool.summary }),
2276
- /* @__PURE__ */ jsxs15("p", { className: "pt-tool__meta", children: [
2277
- /* @__PURE__ */ jsx17("span", { className: "pt-tool__id", children: tool.id }),
2278
- tool.claudePlugin && /* @__PURE__ */ jsxs15(Fragment4, { children: [
2541
+ tool.summary && /* @__PURE__ */ jsx18("p", { className: "pt-panel-text", children: tool.summary }),
2542
+ /* @__PURE__ */ jsxs16("p", { className: "pt-tool__meta", children: [
2543
+ /* @__PURE__ */ jsx18("span", { className: "pt-tool__id", children: tool.id }),
2544
+ tool.claudePlugin && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2279
2545
  " \xB7 ",
2280
- tool.version ? /* @__PURE__ */ jsxs15("span", { className: "pt-tool__version", children: [
2546
+ tool.version ? /* @__PURE__ */ jsxs16("span", { className: "pt-tool__version", children: [
2281
2547
  "v",
2282
2548
  tool.version
2283
2549
  ] }) : (
2284
2550
  // Never a version we made up. A blank here is the plugin's own
2285
2551
  // manifest failing to answer, and it says so on hover.
2286
- /* @__PURE__ */ jsx17("span", { className: "pt-tool__version is-unknown", title: tool.versionError ?? void 0, children: ui.versionUnknown })
2552
+ /* @__PURE__ */ jsx18("span", { className: "pt-tool__version is-unknown", title: tool.versionError ?? void 0, children: ui.versionUnknown })
2287
2553
  )
2288
2554
  ] }),
2289
- tool.repo && /* @__PURE__ */ jsxs15(Fragment4, { children: [
2555
+ tool.repo && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2290
2556
  " \xB7 ",
2291
- /* @__PURE__ */ jsx17("a", { className: "pt-tool__repo", href: `https://github.com/${tool.repo}`, target: "_blank", rel: "noreferrer", children: tool.repo })
2557
+ /* @__PURE__ */ jsx18("a", { className: "pt-tool__repo", href: `https://github.com/${tool.repo}`, target: "_blank", rel: "noreferrer", children: tool.repo })
2292
2558
  ] })
2293
2559
  ] }),
2294
- tool.tags.length > 0 && /* @__PURE__ */ jsx17("p", { className: "pt-tool__tags", children: tool.tags.map((tag) => /* @__PURE__ */ jsx17("span", { className: "pt-tool__tag", children: tag }, tag)) }),
2295
- !tool.claudePlugin && tool.standaloneCommand && /* @__PURE__ */ jsx17(
2560
+ tool.tags.length > 0 && /* @__PURE__ */ jsx18("p", { className: "pt-tool__tags", children: tool.tags.map((tag) => /* @__PURE__ */ jsx18("span", { className: "pt-tool__tag", children: tag }, tag)) }),
2561
+ !tool.claudePlugin && tool.standaloneCommand && /* @__PURE__ */ jsx18(
2296
2562
  CopyBlock,
2297
2563
  {
2298
2564
  text: tool.standaloneCommand,
@@ -2300,16 +2566,16 @@ function ToolRow({
2300
2566
  labels: { copy: ui.copy, copied: ui.copied, selected: ui.copySelected }
2301
2567
  }
2302
2568
  ),
2303
- /* @__PURE__ */ jsxs15("div", { className: "pt-panel-row pt-tool__actions", children: [
2304
- /* @__PURE__ */ jsx17("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: () => onInstall(tool), children: tool.claudePlugin ? ui.install : ui.howToRun }),
2305
- tool.homepage && /* @__PURE__ */ jsx17("a", { className: "pt-btn pt-btn--sm", href: tool.homepage, target: "_blank", rel: "noreferrer", children: ui.learnMore })
2569
+ /* @__PURE__ */ jsxs16("div", { className: "pt-panel-row pt-tool__actions", children: [
2570
+ /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: () => onInstall(tool), children: tool.claudePlugin ? ui.install : ui.howToRun }),
2571
+ tool.homepage && /* @__PURE__ */ jsx18("a", { className: "pt-btn pt-btn--sm", href: tool.homepage, target: "_blank", rel: "noreferrer", children: ui.learnMore })
2306
2572
  ] }),
2307
- tool.state === "misconfigured" && /* @__PURE__ */ jsx17("p", { className: "pt-warn", children: ui.stateMisconfiguredWhy })
2573
+ tool.state === "misconfigured" && /* @__PURE__ */ jsx18("p", { className: "pt-warn", children: ui.stateMisconfiguredWhy })
2308
2574
  ] });
2309
2575
  }
2310
2576
  function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2311
- const [filter, setFilter] = useState7("all");
2312
- const [open, setOpen] = useState7(null);
2577
+ const [filter, setFilter] = useState8("all");
2578
+ const [open, setOpen] = useState8(null);
2313
2579
  const tools = report?.tools ?? [];
2314
2580
  const shown = useMemo4(() => {
2315
2581
  if (filter === "plugins") return tools.filter((tool) => tool.claudePlugin);
@@ -2326,39 +2592,39 @@ function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2326
2592
  }),
2327
2593
  [tools]
2328
2594
  );
2329
- return /* @__PURE__ */ jsxs15("div", { className: "pt-panel-page pt-panel-section pt-marketplace", children: [
2330
- /* @__PURE__ */ jsxs15("section", { children: [
2331
- /* @__PURE__ */ jsx17("p", { className: "pt-eyebrow", children: report?.marketplace.name ?? ui.marketplaceEyebrow }),
2332
- /* @__PURE__ */ jsx17("h2", { className: "pt-h2", children: ui.marketplaceTitle }),
2333
- /* @__PURE__ */ jsx17("p", { className: "pt-sub", children: ui.marketplaceIntro }),
2334
- /* @__PURE__ */ jsxs15("div", { className: "pt-panel-row pt-marketplace__status", children: [
2335
- onRefresh && /* @__PURE__ */ jsx17("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: onRefresh, disabled: loading, children: loading ? ui.refreshing : ui.refresh }),
2336
- report && onRefresh && /* @__PURE__ */ jsx17("span", { className: "pt-marketplace__age", children: ui.readAt(ageInWords(report.ageSeconds, lang)) })
2595
+ return /* @__PURE__ */ jsxs16("div", { className: "pt-panel-page pt-panel-section pt-marketplace", children: [
2596
+ /* @__PURE__ */ jsxs16("section", { children: [
2597
+ /* @__PURE__ */ jsx18("p", { className: "pt-eyebrow", children: report?.marketplace.name ?? ui.marketplaceEyebrow }),
2598
+ /* @__PURE__ */ jsx18("h2", { className: "pt-h2", children: ui.marketplaceTitle }),
2599
+ /* @__PURE__ */ jsx18("p", { className: "pt-sub", children: ui.marketplaceIntro }),
2600
+ /* @__PURE__ */ jsxs16("div", { className: "pt-panel-row pt-marketplace__status", children: [
2601
+ onRefresh && /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: onRefresh, disabled: loading, children: loading ? ui.refreshing : ui.refresh }),
2602
+ report && onRefresh && /* @__PURE__ */ jsx18("span", { className: "pt-marketplace__age", children: ui.readAt(ageInWords(report.ageSeconds, lang)) })
2337
2603
  ] }),
2338
- report?.stale && !report.unavailable && /* @__PURE__ */ jsx17("p", { className: "pt-warn", children: ui.catalogueStale(ageInWords(report.ageSeconds, lang)) }),
2339
- report?.unavailable && /* @__PURE__ */ jsx17("p", { className: "pt-warn", children: ui.catalogueUnavailable }),
2340
- failure && /* @__PURE__ */ jsx17("p", { className: "pt-warn", children: ui.catalogueFailed })
2604
+ report?.stale && !report.unavailable && /* @__PURE__ */ jsx18("p", { className: "pt-warn", children: ui.catalogueStale(ageInWords(report.ageSeconds, lang)) }),
2605
+ report?.unavailable && /* @__PURE__ */ jsx18("p", { className: "pt-warn", children: ui.catalogueUnavailable }),
2606
+ failure && /* @__PURE__ */ jsx18("p", { className: "pt-warn", children: ui.catalogueFailed })
2341
2607
  ] }),
2342
- report && /* @__PURE__ */ jsxs15("section", { children: [
2343
- /* @__PURE__ */ jsxs15("p", { className: "pt-marketplace__project", children: [
2608
+ report && /* @__PURE__ */ jsxs16("section", { children: [
2609
+ /* @__PURE__ */ jsxs16("p", { className: "pt-marketplace__project", children: [
2344
2610
  ui.stateFrom(report.project.repo, SETTINGS_PATH),
2345
- report.project.settingsStatus === "absent" && /* @__PURE__ */ jsxs15(Fragment4, { children: [
2611
+ report.project.settingsStatus === "absent" && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2346
2612
  " \xB7 ",
2347
2613
  ui.settingsAbsent
2348
2614
  ] }),
2349
- report.project.settingsStatus === "unreadable" && /* @__PURE__ */ jsxs15(Fragment4, { children: [
2615
+ report.project.settingsStatus === "unreadable" && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2350
2616
  " \xB7 ",
2351
2617
  ui.settingsUnreadable
2352
2618
  ] }),
2353
- report.project.settingsStatus === "unparseable" && /* @__PURE__ */ jsxs15(Fragment4, { children: [
2619
+ report.project.settingsStatus === "unparseable" && /* @__PURE__ */ jsxs16(Fragment4, { children: [
2354
2620
  " \xB7 ",
2355
2621
  ui.settingsUnparseable
2356
2622
  ] })
2357
2623
  ] }),
2358
- report.project.detail && /* @__PURE__ */ jsx17("p", { className: "pt-marketplace__detail", children: report.project.detail }),
2359
- /* @__PURE__ */ jsxs15("div", { className: "pt-panel-row pt-marketplace__filters", children: [
2360
- /* @__PURE__ */ jsx17(FilterChip, { label: ui.all, count: counts.all, active: filter === "all", onClick: () => setFilter("all") }),
2361
- /* @__PURE__ */ jsx17(
2624
+ report.project.detail && /* @__PURE__ */ jsx18("p", { className: "pt-marketplace__detail", children: report.project.detail }),
2625
+ /* @__PURE__ */ jsxs16("div", { className: "pt-panel-row pt-marketplace__filters", children: [
2626
+ /* @__PURE__ */ jsx18(FilterChip, { label: ui.all, count: counts.all, active: filter === "all", onClick: () => setFilter("all") }),
2627
+ /* @__PURE__ */ jsx18(
2362
2628
  FilterChip,
2363
2629
  {
2364
2630
  label: ui.filterPlugins,
@@ -2367,7 +2633,7 @@ function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2367
2633
  onClick: () => setFilter("plugins")
2368
2634
  }
2369
2635
  ),
2370
- /* @__PURE__ */ jsx17(
2636
+ /* @__PURE__ */ jsx18(
2371
2637
  FilterChip,
2372
2638
  {
2373
2639
  label: ui.filterActive,
@@ -2376,7 +2642,7 @@ function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2376
2642
  onClick: () => setFilter("active")
2377
2643
  }
2378
2644
  ),
2379
- /* @__PURE__ */ jsx17(
2645
+ /* @__PURE__ */ jsx18(
2380
2646
  FilterChip,
2381
2647
  {
2382
2648
  label: ui.filterStandalone,
@@ -2386,12 +2652,12 @@ function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2386
2652
  }
2387
2653
  )
2388
2654
  ] }),
2389
- loading && tools.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "pt-analysis__empty", children: ui.catalogueLoading }) : shown.length === 0 ? /* @__PURE__ */ jsx17("p", { className: "pt-analysis__empty", children: ui.catalogueEmpty }) : /* @__PURE__ */ jsx17("div", { className: "pt-tool-grid", children: shown.map((tool) => /* @__PURE__ */ jsx17(ToolRow, { tool, lang, ui, onInstall: setOpen }, tool.id)) })
2655
+ loading && tools.length === 0 ? /* @__PURE__ */ jsx18("p", { className: "pt-analysis__empty", children: ui.catalogueLoading }) : shown.length === 0 ? /* @__PURE__ */ jsx18("p", { className: "pt-analysis__empty", children: ui.catalogueEmpty }) : /* @__PURE__ */ jsx18("div", { className: "pt-tool-grid", children: shown.map((tool) => /* @__PURE__ */ jsx18(ToolRow, { tool, lang, ui, onInstall: setOpen }, tool.id)) })
2390
2656
  ] }),
2391
- open && /* @__PURE__ */ jsxs15(DetailSheet, { open: true, onClose: () => setOpen(null), ariaLabel: `${ui.installTitle} \u2014 ${open.name}`, children: [
2392
- /* @__PURE__ */ jsx17("p", { className: "pt-eyebrow", children: ui.installTitle }),
2393
- /* @__PURE__ */ jsx17("h2", { className: "pt-h2", children: open.name }),
2394
- /* @__PURE__ */ jsx17(
2657
+ open && /* @__PURE__ */ jsxs16(DetailSheet, { open: true, onClose: () => setOpen(null), ariaLabel: `${ui.installTitle} \u2014 ${open.name}`, children: [
2658
+ /* @__PURE__ */ jsx18("p", { className: "pt-eyebrow", children: ui.installTitle }),
2659
+ /* @__PURE__ */ jsx18("h2", { className: "pt-h2", children: open.name }),
2660
+ /* @__PURE__ */ jsx18(
2395
2661
  InstallSheet,
2396
2662
  {
2397
2663
  tool: open,
@@ -2400,7 +2666,7 @@ function MarketplaceView({ report, loading, failure, lang, ui, onRefresh }) {
2400
2666
  registered: report?.project.marketplaceRegistered ?? false
2401
2667
  }
2402
2668
  ),
2403
- /* @__PURE__ */ jsx17("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: () => setOpen(null), children: ui.close })
2669
+ /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: () => setOpen(null), children: ui.close })
2404
2670
  ] })
2405
2671
  ] });
2406
2672
  }
@@ -2411,9 +2677,9 @@ function InstallSheet({
2411
2677
  registered
2412
2678
  }) {
2413
2679
  const copy = { copy: ui.copy, copied: ui.copied, selected: ui.copySelected };
2414
- return /* @__PURE__ */ jsxs15(Fragment4, { children: [
2415
- tool.claudePlugin ? /* @__PURE__ */ jsxs15(Fragment4, { children: [
2416
- /* @__PURE__ */ jsx17(DetailSection, { title: ui.installRepoTitle, subtitle: ui.installRepoHint, children: /* @__PURE__ */ jsx17(
2680
+ return /* @__PURE__ */ jsxs16(Fragment4, { children: [
2681
+ tool.claudePlugin ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
2682
+ /* @__PURE__ */ jsx18(DetailSection, { title: ui.installRepoTitle, subtitle: ui.installRepoHint, children: /* @__PURE__ */ jsx18(
2417
2683
  CopyBlock,
2418
2684
  {
2419
2685
  text: repositorySnippet(tool.id, marketplace),
@@ -2422,24 +2688,24 @@ function InstallSheet({
2422
2688
  labels: copy
2423
2689
  }
2424
2690
  ) }),
2425
- /* @__PURE__ */ jsx17(DetailSection, { title: ui.installCliTitle, subtitle: ui.installCliHint, children: /* @__PURE__ */ jsx17(CopyBlock, { text: commandSnippet(tool.id, marketplace), labels: copy }) })
2426
- ] }) : /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: ui.installNoPlugin }),
2427
- tool.standaloneCommand ? /* @__PURE__ */ jsx17(DetailSection, { title: ui.installStandaloneTitle, subtitle: ui.installStandaloneHint, children: /* @__PURE__ */ jsx17(CopyBlock, { text: tool.standaloneCommand, labels: copy }) }) : /* @__PURE__ */ jsx17(DetailSection, { title: ui.installStandaloneTitle, children: /* @__PURE__ */ jsx17("p", { className: "pt-panel-text", children: ui.installNoStandalone }) }),
2428
- /* @__PURE__ */ jsx17("p", { className: "pt-marketplace__source", children: ui.marketplaceSource(marketplace.url) })
2691
+ /* @__PURE__ */ jsx18(DetailSection, { title: ui.installCliTitle, subtitle: ui.installCliHint, children: /* @__PURE__ */ jsx18(CopyBlock, { text: commandSnippet(tool.id, marketplace), labels: copy }) })
2692
+ ] }) : /* @__PURE__ */ jsx18("p", { className: "pt-panel-text", children: ui.installNoPlugin }),
2693
+ tool.standaloneCommand ? /* @__PURE__ */ jsx18(DetailSection, { title: ui.installStandaloneTitle, subtitle: ui.installStandaloneHint, children: /* @__PURE__ */ jsx18(CopyBlock, { text: tool.standaloneCommand, labels: copy }) }) : /* @__PURE__ */ jsx18(DetailSection, { title: ui.installStandaloneTitle, children: /* @__PURE__ */ jsx18("p", { className: "pt-panel-text", children: ui.installNoStandalone }) }),
2694
+ /* @__PURE__ */ jsx18("p", { className: "pt-marketplace__source", children: ui.marketplaceSource(marketplace.url) })
2429
2695
  ] });
2430
2696
  }
2431
2697
 
2432
2698
  // src/panel/CardSheet.tsx
2433
- import { useState as useState8 } from "react";
2434
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2699
+ import { useState as useState9 } from "react";
2700
+ import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
2435
2701
  var LEVEL_LABEL = (ui) => ({
2436
2702
  high: ui.levelHigh,
2437
2703
  medium: ui.levelMedium,
2438
2704
  low: ui.levelLow
2439
2705
  });
2440
2706
  function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2441
- const [step, setStep] = useState8("");
2442
- const [note, setNote] = useState8("");
2707
+ const [step, setStep] = useState9("");
2708
+ const [note, setNote] = useState9("");
2443
2709
  if (!card) return null;
2444
2710
  const patch = (changes) => onChange({ ...card, ...changes, updatedAt: today() });
2445
2711
  const levelLabel = LEVEL_LABEL(ui);
@@ -2458,9 +2724,9 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2458
2724
  });
2459
2725
  setNote("");
2460
2726
  }
2461
- return /* @__PURE__ */ jsxs16(DetailSheet, { open: true, onClose, ariaLabel: ui.cardDetail, children: [
2462
- /* @__PURE__ */ jsxs16(DetailSection, { title: ui.title, children: [
2463
- /* @__PURE__ */ jsx18(
2727
+ return /* @__PURE__ */ jsxs17(DetailSheet, { open: true, onClose, ariaLabel: ui.cardDetail, children: [
2728
+ /* @__PURE__ */ jsxs17(DetailSection, { title: ui.title, children: [
2729
+ /* @__PURE__ */ jsx19(
2464
2730
  "input",
2465
2731
  {
2466
2732
  className: "pt-input",
@@ -2469,9 +2735,9 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2469
2735
  onChange: (event) => patch({ title: writeText(lang, event.target.value) })
2470
2736
  }
2471
2737
  ),
2472
- untranslated(card.title) && /* @__PURE__ */ jsx18("span", { className: "pt-flag", children: ui.untranslatedBadge })
2738
+ untranslated(card.title) && /* @__PURE__ */ jsx19("span", { className: "pt-flag", children: ui.untranslatedBadge })
2473
2739
  ] }),
2474
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.detail, children: /* @__PURE__ */ jsx18(
2740
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.detail, children: /* @__PURE__ */ jsx19(
2475
2741
  "textarea",
2476
2742
  {
2477
2743
  className: "pt-textarea",
@@ -2481,7 +2747,7 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2481
2747
  onChange: (event) => patch({ body: writeText(lang, event.target.value) })
2482
2748
  }
2483
2749
  ) }),
2484
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.areaLabel, children: /* @__PURE__ */ jsx18("div", { className: "pt-panel-row", children: state.areas.map((area) => /* @__PURE__ */ jsx18(
2750
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.areaLabel, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: state.areas.map((area) => /* @__PURE__ */ jsx19(
2485
2751
  FilterChip,
2486
2752
  {
2487
2753
  label: text(area.label, lang),
@@ -2490,7 +2756,7 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2490
2756
  },
2491
2757
  area.id
2492
2758
  )) }) }),
2493
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.priority, children: /* @__PURE__ */ jsx18("div", { className: "pt-panel-row", children: LEVELS.map((level) => /* @__PURE__ */ jsx18(
2759
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.priority, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: LEVELS.map((level) => /* @__PURE__ */ jsx19(
2494
2760
  FilterChip,
2495
2761
  {
2496
2762
  label: levelLabel[level],
@@ -2499,7 +2765,7 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2499
2765
  },
2500
2766
  level
2501
2767
  )) }) }),
2502
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.risk, subtitle: ui.riskHint, children: /* @__PURE__ */ jsx18("div", { className: "pt-panel-row", children: LEVELS.map((level) => /* @__PURE__ */ jsx18(
2768
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.risk, subtitle: ui.riskHint, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: LEVELS.map((level) => /* @__PURE__ */ jsx19(
2503
2769
  FilterChip,
2504
2770
  {
2505
2771
  label: levelLabel[level],
@@ -2508,7 +2774,7 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2508
2774
  },
2509
2775
  level
2510
2776
  )) }) }),
2511
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.dependsOn, children: /* @__PURE__ */ jsx18("div", { className: "pt-panel-row", children: OWNERS.map((owner) => /* @__PURE__ */ jsx18(
2777
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.dependsOn, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: OWNERS.map((owner) => /* @__PURE__ */ jsx19(
2512
2778
  FilterChip,
2513
2779
  {
2514
2780
  label: ownerLabel[owner],
@@ -2517,14 +2783,14 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2517
2783
  },
2518
2784
  owner
2519
2785
  )) }) }),
2520
- /* @__PURE__ */ jsx18(DetailSection, { title: ui.orderTitle, children: /* @__PURE__ */ jsxs16("div", { className: "pt-panel-row", children: [
2521
- /* @__PURE__ */ jsx18(FilterChip, { label: `\u26A1 ${ui.orderOn}`, active: card.order, onClick: () => patch({ order: true }) }),
2522
- /* @__PURE__ */ jsx18(FilterChip, { label: ui.orderOff, active: !card.order, onClick: () => patch({ order: false }) })
2786
+ /* @__PURE__ */ jsx19(DetailSection, { title: ui.orderTitle, children: /* @__PURE__ */ jsxs17("div", { className: "pt-panel-row", children: [
2787
+ /* @__PURE__ */ jsx19(FilterChip, { label: `\u26A1 ${ui.orderOn}`, active: card.order, onClick: () => patch({ order: true }) }),
2788
+ /* @__PURE__ */ jsx19(FilterChip, { label: ui.orderOff, active: !card.order, onClick: () => patch({ order: false }) })
2523
2789
  ] }) }),
2524
- /* @__PURE__ */ jsxs16(DetailSection, { title: ui.intentTitle, subtitle: ui.intentHint, children: [
2525
- /* @__PURE__ */ jsxs16("div", { className: "pt-panel-row", children: [
2526
- /* @__PURE__ */ jsx18(FilterChip, { label: ui.intentNone, active: card.intent === null, onClick: () => patch({ intent: null }) }),
2527
- INTENTS.map((intent) => /* @__PURE__ */ jsx18(
2790
+ /* @__PURE__ */ jsxs17(DetailSection, { title: ui.intentTitle, subtitle: ui.intentHint, children: [
2791
+ /* @__PURE__ */ jsxs17("div", { className: "pt-panel-row", children: [
2792
+ /* @__PURE__ */ jsx19(FilterChip, { label: ui.intentNone, active: card.intent === null, onClick: () => patch({ intent: null }) }),
2793
+ INTENTS.map((intent) => /* @__PURE__ */ jsx19(
2528
2794
  FilterChip,
2529
2795
  {
2530
2796
  label: INTENT_COPY[intent].label[lang],
@@ -2534,12 +2800,12 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2534
2800
  intent
2535
2801
  ))
2536
2802
  ] }),
2537
- card.intent && /* @__PURE__ */ jsx18("p", { className: "pt-panel-text pt-meaning", children: INTENT_COPY[card.intent].meaning[lang] })
2803
+ card.intent && /* @__PURE__ */ jsx19("p", { className: "pt-panel-text pt-meaning", children: INTENT_COPY[card.intent].meaning[lang] })
2538
2804
  ] }),
2539
- /* @__PURE__ */ jsxs16(DetailSection, { title: ui.checklist, children: [
2540
- card.checks.length > 0 && /* @__PURE__ */ jsx18("ul", { className: "pt-checks", children: card.checks.map((check) => /* @__PURE__ */ jsxs16("li", { children: [
2541
- /* @__PURE__ */ jsxs16("label", { children: [
2542
- /* @__PURE__ */ jsx18(
2805
+ /* @__PURE__ */ jsxs17(DetailSection, { title: ui.checklist, children: [
2806
+ card.checks.length > 0 && /* @__PURE__ */ jsx19("ul", { className: "pt-checks", children: card.checks.map((check) => /* @__PURE__ */ jsxs17("li", { children: [
2807
+ /* @__PURE__ */ jsxs17("label", { children: [
2808
+ /* @__PURE__ */ jsx19(
2543
2809
  "input",
2544
2810
  {
2545
2811
  type: "checkbox",
@@ -2551,9 +2817,9 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2551
2817
  })
2552
2818
  }
2553
2819
  ),
2554
- /* @__PURE__ */ jsx18("span", { className: check.done ? "is-done" : void 0, children: text(check.text, lang) })
2820
+ /* @__PURE__ */ jsx19("span", { className: check.done ? "is-done" : void 0, children: text(check.text, lang) })
2555
2821
  ] }),
2556
- /* @__PURE__ */ jsx18(
2822
+ /* @__PURE__ */ jsx19(
2557
2823
  "button",
2558
2824
  {
2559
2825
  type: "button",
@@ -2564,8 +2830,8 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2564
2830
  }
2565
2831
  )
2566
2832
  ] }, check.id)) }),
2567
- /* @__PURE__ */ jsxs16("div", { className: "pt-compose", children: [
2568
- /* @__PURE__ */ jsx18(
2833
+ /* @__PURE__ */ jsxs17("div", { className: "pt-compose", children: [
2834
+ /* @__PURE__ */ jsx19(
2569
2835
  "input",
2570
2836
  {
2571
2837
  className: "pt-input",
@@ -2580,19 +2846,19 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2580
2846
  }
2581
2847
  }
2582
2848
  ),
2583
- /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm pt-btn--primary", onClick: addStep, children: ui.addStep })
2849
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-btn pt-btn--sm pt-btn--primary", onClick: addStep, children: ui.addStep })
2584
2850
  ] })
2585
2851
  ] }),
2586
- /* @__PURE__ */ jsxs16(DetailSection, { title: ui.notes, children: [
2587
- card.notes.map((entry) => /* @__PURE__ */ jsxs16("div", { className: "pt-note", children: [
2588
- /* @__PURE__ */ jsxs16("p", { className: "pt-note__meta", children: [
2852
+ /* @__PURE__ */ jsxs17(DetailSection, { title: ui.notes, children: [
2853
+ card.notes.map((entry) => /* @__PURE__ */ jsxs17("div", { className: "pt-note", children: [
2854
+ /* @__PURE__ */ jsxs17("p", { className: "pt-note__meta", children: [
2589
2855
  entry.by === "claude" ? "Claude" : ui.ownerYou,
2590
2856
  " \xB7 ",
2591
2857
  entry.date
2592
2858
  ] }),
2593
- /* @__PURE__ */ jsx18("p", { className: "pt-panel-text", children: text(entry.text, lang) })
2859
+ /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: text(entry.text, lang) })
2594
2860
  ] }, entry.id)),
2595
- /* @__PURE__ */ jsx18(
2861
+ /* @__PURE__ */ jsx19(
2596
2862
  "textarea",
2597
2863
  {
2598
2864
  className: "pt-textarea",
@@ -2602,10 +2868,10 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2602
2868
  onChange: (event) => setNote(event.target.value)
2603
2869
  }
2604
2870
  ),
2605
- /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm pt-btn--primary", onClick: addNote, children: ui.leaveNote })
2871
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-btn pt-btn--sm pt-btn--primary", onClick: addNote, children: ui.leaveNote })
2606
2872
  ] }),
2607
- /* @__PURE__ */ jsxs16(DetailSection, { title: ui.columnTitle, children: [
2608
- /* @__PURE__ */ jsx18("div", { className: "pt-panel-row", children: state.columns.map((column) => /* @__PURE__ */ jsx18(
2873
+ /* @__PURE__ */ jsxs17(DetailSection, { title: ui.columnTitle, children: [
2874
+ /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: state.columns.map((column) => /* @__PURE__ */ jsx19(
2609
2875
  FilterChip,
2610
2876
  {
2611
2877
  label: text(column.title, lang),
@@ -2616,16 +2882,16 @@ function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }) {
2616
2882
  },
2617
2883
  column.id
2618
2884
  )) }),
2619
- (card.startedAt || card.completedAt) && /* @__PURE__ */ jsxs16("p", { className: "pt-panel-text pt-stamps", children: [
2885
+ (card.startedAt || card.completedAt) && /* @__PURE__ */ jsxs17("p", { className: "pt-panel-text pt-stamps", children: [
2620
2886
  card.startedAt && `${ui.started}: ${card.startedAt}`,
2621
2887
  card.startedAt && card.completedAt && " \xB7 ",
2622
2888
  card.completedAt && `${ui.completed}: ${card.completedAt}`
2623
2889
  ] }),
2624
- claimedWithoutStarting(card) && /* @__PURE__ */ jsx18("p", { className: "pt-warn", children: ui.neverStarted })
2890
+ claimedWithoutStarting(card) && /* @__PURE__ */ jsx19("p", { className: "pt-warn", children: ui.neverStarted })
2625
2891
  ] }),
2626
- /* @__PURE__ */ jsxs16("div", { className: "pt-sheet-actions", children: [
2627
- /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: onClose, children: ui.close }),
2628
- /* @__PURE__ */ jsx18("button", { type: "button", className: "pt-btn pt-btn--sm pt-danger", onClick: () => onDelete(card.id), children: ui.deleteCard })
2892
+ /* @__PURE__ */ jsxs17("div", { className: "pt-sheet-actions", children: [
2893
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: onClose, children: ui.close }),
2894
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-btn pt-btn--sm pt-danger", onClick: () => onDelete(card.id), children: ui.deleteCard })
2629
2895
  ] })
2630
2896
  ] });
2631
2897
  }
@@ -2649,10 +2915,45 @@ function applyMove(cards, move, visible) {
2649
2915
  const at = rest.findIndex((card) => card.id === anchor.id);
2650
2916
  return [...rest.slice(0, at), moved, ...rest.slice(at)];
2651
2917
  }
2918
+ function resolveTheme(saved, stored, themes, hasImported, fallback) {
2919
+ for (const name of [saved, stored]) {
2920
+ if (name === "imported" && hasImported) return "imported";
2921
+ if (name && name in themes) return name;
2922
+ }
2923
+ return fallback ?? Object.keys(themes)[0];
2924
+ }
2652
2925
 
2653
2926
  // src/panel/PanelApp.tsx
2654
- import { Fragment as Fragment5, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
2927
+ import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
2655
2928
  var IMPORTED = "imported";
2929
+ var WIZARD_KEY = "paneltir:setup-done";
2930
+ var THEME_KEY = "paneltir:theme";
2931
+ function readStoredTheme() {
2932
+ try {
2933
+ return window.localStorage.getItem(THEME_KEY);
2934
+ } catch {
2935
+ return null;
2936
+ }
2937
+ }
2938
+ function storeTheme(name) {
2939
+ try {
2940
+ window.localStorage.setItem(THEME_KEY, name);
2941
+ } catch {
2942
+ }
2943
+ }
2944
+ function wizardClosed() {
2945
+ try {
2946
+ return window.localStorage.getItem(WIZARD_KEY) === "closed";
2947
+ } catch {
2948
+ return false;
2949
+ }
2950
+ }
2951
+ function closeWizard() {
2952
+ try {
2953
+ window.localStorage.setItem(WIZARD_KEY, "closed");
2954
+ } catch {
2955
+ }
2956
+ }
2656
2957
  function parseJson(body) {
2657
2958
  try {
2658
2959
  const parsed = JSON.parse(body);
@@ -2674,7 +2975,8 @@ var PRIORITY_TONE = {
2674
2975
  };
2675
2976
  function PanelApp({
2676
2977
  state: initialState,
2677
- themes = PRESET_PANEL_THEMES,
2978
+ themes: exactThemes,
2979
+ extraThemes,
2678
2980
  defaultTheme,
2679
2981
  brand,
2680
2982
  decoration,
@@ -2685,39 +2987,47 @@ function PanelApp({
2685
2987
  extras,
2686
2988
  showLanguage,
2687
2989
  showHistory,
2990
+ checkForUpdates,
2688
2991
  saveEndpoint,
2689
2992
  marketplaceEndpoint,
2690
2993
  marketplaceReport,
2691
2994
  fingerprint
2692
2995
  }) {
2693
- const [themeName, setThemeName] = useState9(() => {
2694
- const saved = initialState.preferences?.theme;
2695
- if (saved === IMPORTED && initialState.importedTheme) return IMPORTED;
2696
- return saved && saved in themes ? saved : defaultTheme ?? Object.keys(themes)[0];
2697
- });
2698
- const [lang, setLang] = useState9(
2996
+ const themes = useMemo5(() => offeredThemes(exactThemes, extraThemes), [exactThemes, extraThemes]);
2997
+ const [themeName, setThemeName] = useState10(
2998
+ () => resolveTheme(
2999
+ initialState.preferences?.theme,
3000
+ readStoredTheme(),
3001
+ themes,
3002
+ Boolean(initialState.importedTheme),
3003
+ defaultTheme
3004
+ )
3005
+ );
3006
+ const [lang, setLang] = useState10(
2699
3007
  () => initialState.preferences?.lang ?? (showLanguage ? readStoredLang() : "en")
2700
3008
  );
2701
- const [state, setState] = useState9(initialState);
2702
- const [filter, setFilter] = useState9("all");
2703
- const [openCardId, setOpenCardId] = useState9(null);
2704
- const [settingsOpen, setSettingsOpen] = useState9(false);
2705
- const [helpOpen, setHelpOpen] = useState9(false);
2706
- const [setup, setSetup] = useState9(null);
2707
- const [signOut, setSignOut] = useState9("idle");
2708
- const [view, setView] = useState9("board");
2709
- const [market, setMarket] = useState9(marketplaceReport ?? null);
2710
- const [marketLoading, setMarketLoading] = useState9(false);
2711
- const [marketFailure, setMarketFailure] = useState9(null);
2712
- const [marketAsked, setMarketAsked] = useState9(false);
2713
- const [noticeVisible, setNoticeVisible] = useState9(Boolean(initialState.notice));
2714
- const [savedSnapshot, setSavedSnapshot] = useState9(() => JSON.stringify(initialState));
2715
- const [save, setSave] = useState9({ status: "idle" });
3009
+ const [state, setState] = useState10(initialState);
3010
+ const [filter, setFilter] = useState10("all");
3011
+ const [openCardId, setOpenCardId] = useState10(null);
3012
+ const [settingsOpen, setSettingsOpen] = useState10(false);
3013
+ const [update, setUpdate] = useState10(null);
3014
+ const [releaseOpen, setReleaseOpen] = useState10(false);
3015
+ const [helpOpen, setHelpOpen] = useState10(false);
3016
+ const [wizardOpen, setWizardOpen] = useState10(false);
3017
+ const [setup, setSetup] = useState10(null);
3018
+ const [signOut, setSignOut] = useState10("idle");
3019
+ const [view, setView] = useState10("board");
3020
+ const [market, setMarket] = useState10(marketplaceReport ?? null);
3021
+ const [marketLoading, setMarketLoading] = useState10(false);
3022
+ const [marketFailure, setMarketFailure] = useState10(null);
3023
+ const [marketAsked, setMarketAsked] = useState10(false);
3024
+ const [noticeVisible, setNoticeVisible] = useState10(Boolean(initialState.notice));
3025
+ const [savedSnapshot, setSavedSnapshot] = useState10(() => JSON.stringify(initialState));
3026
+ const [save, setSave] = useState10({ status: "idle" });
2716
3027
  const imported = themeName === IMPORTED ? state.importedTheme : void 0;
2717
- const preset = themeName === IMPORTED ? "nightCity" : themeName;
2718
- const chosen = themes[preset] ?? Object.values(themes)[0];
3028
+ const chosen = themes[themeName] ?? Object.values(themes)[0];
2719
3029
  const theme = imported?.tokens ?? chosen.tokens;
2720
- const form = imported?.form ?? chosen.form;
3030
+ const form = imported?.form ?? (imported ? THEME_FORMS.panel : chosen.form);
2721
3031
  const ui = UI[lang];
2722
3032
  const t = useCallback5((value) => text(value, lang), [lang]);
2723
3033
  const dirty = JSON.stringify(state) !== savedSnapshot;
@@ -2741,11 +3051,11 @@ function PanelApp({
2741
3051
  status: state_("GH_TOKEN"),
2742
3052
  variable: "GH_TOKEN",
2743
3053
  enables: ui.needTokenEnables,
2744
- fix: /* @__PURE__ */ jsxs17("ol", { children: [
2745
- /* @__PURE__ */ jsx19("li", { children: ui.fixTokenCreate }),
2746
- /* @__PURE__ */ jsx19("li", { children: ui.fixTokenScope }),
2747
- /* @__PURE__ */ jsx19("li", { children: ui.fixTokenPaste }),
2748
- /* @__PURE__ */ jsx19("li", { children: ui.fixTokenRedeploy })
3054
+ fix: /* @__PURE__ */ jsxs18("ol", { children: [
3055
+ /* @__PURE__ */ jsx20("li", { children: ui.fixTokenCreate }),
3056
+ /* @__PURE__ */ jsx20("li", { children: ui.fixTokenScope }),
3057
+ /* @__PURE__ */ jsx20("li", { children: ui.fixTokenPaste }),
3058
+ /* @__PURE__ */ jsx20("li", { children: ui.fixTokenRedeploy })
2749
3059
  ] })
2750
3060
  },
2751
3061
  {
@@ -2754,7 +3064,7 @@ function PanelApp({
2754
3064
  status: state_("PANEL_REPO"),
2755
3065
  variable: "PANEL_REPO",
2756
3066
  enables: ui.needRepoEnables,
2757
- fix: /* @__PURE__ */ jsx19("p", { children: ui.fixRepo })
3067
+ fix: /* @__PURE__ */ jsx20("p", { children: ui.fixRepo })
2758
3068
  }
2759
3069
  ];
2760
3070
  }, [setup, ui]);
@@ -2810,6 +3120,15 @@ function PanelApp({
2810
3120
  onOpen: () => setOpenCardId(card.id)
2811
3121
  });
2812
3122
  }
3123
+ if (update?.behind && !state.cards.some((card) => card.id === updateCardId(update.latest))) {
3124
+ items.push({
3125
+ id: `paneltir-update:${update.latest}`,
3126
+ tone: "info",
3127
+ title: ui.notifUpdate,
3128
+ detail: ui.updateAvailable(update.latest),
3129
+ onOpen: () => setSettingsOpen(true)
3130
+ });
3131
+ }
2813
3132
  if (state.importedTheme?.refreshRequested) {
2814
3133
  items.push({
2815
3134
  id: `theme-refresh:${state.importedTheme.refreshRequested}`,
@@ -2889,6 +3208,46 @@ function PanelApp({
2889
3208
  },
2890
3209
  [state.areas]
2891
3210
  );
3211
+ const addUpdateCard = useCallback5(() => {
3212
+ if (!update?.behind) return;
3213
+ const id = updateCardId(update.latest);
3214
+ if (state.cards.some((card2) => card2.id === id)) return;
3215
+ const card = {
3216
+ ...emptyCard("next", state.areas[0]?.id ?? "general"),
3217
+ id,
3218
+ title: { en: UI.en.updateCardTitle(update.latest), es: UI.es.updateCardTitle(update.latest) },
3219
+ body: { en: UI.en.updateCardBody(update.latest), es: UI.es.updateCardBody(update.latest) },
3220
+ priority: "medium",
3221
+ risk: "low",
3222
+ owner: "claude",
3223
+ order: state.preferences?.updateAsOrder === true
3224
+ };
3225
+ setState((current) => ({ ...current, updatedAt: today(), cards: [...current.cards, card] }));
3226
+ setOpenCardId(id);
3227
+ }, [update, state.cards, state.areas, state.preferences?.updateAsOrder]);
3228
+ const requestReport = useCallback5(
3229
+ (section) => {
3230
+ const id = `report-${section}-${today()}`;
3231
+ if (state.cards.some((card2) => card2.id === id)) {
3232
+ setOpenCardId(id);
3233
+ return;
3234
+ }
3235
+ const card = {
3236
+ ...emptyCard("next", state.areas[0]?.id ?? "general"),
3237
+ id,
3238
+ title: { en: UI.en.analysisRedoTitle[section], es: UI.es.analysisRedoTitle[section] },
3239
+ body: { en: UI.en.analysisRedoBody[section], es: UI.es.analysisRedoBody[section] },
3240
+ priority: "medium",
3241
+ risk: "low",
3242
+ owner: "claude",
3243
+ order: true,
3244
+ intent: "do"
3245
+ };
3246
+ setState((current) => ({ ...current, updatedAt: today(), cards: [...current.cards, card] }));
3247
+ setOpenCardId(id);
3248
+ },
3249
+ [state.cards, state.areas]
3250
+ );
2892
3251
  const moveCard = useCallback5(
2893
3252
  (move) => {
2894
3253
  setState((current) => {
@@ -2924,6 +3283,7 @@ function PanelApp({
2924
3283
  const chooseTheme = useCallback5(
2925
3284
  (name) => {
2926
3285
  setThemeName(name);
3286
+ storeTheme(name);
2927
3287
  setPreference("theme", name);
2928
3288
  },
2929
3289
  [setPreference]
@@ -3009,17 +3369,48 @@ function PanelApp({
3009
3369
  loadMarketplace(false);
3010
3370
  }, [view, marketAsked, marketplaceEndpoint, loadMarketplace]);
3011
3371
  useEffect9(() => {
3012
- if (!helpOpen || !saveEndpoint || setup) return;
3372
+ if (!checkForUpdates || !fingerprint?.version) return;
3013
3373
  let cancelled = false;
3014
- fetch(saveEndpoint, { headers: { accept: "application/json" } }).then((response) => response.ok ? response.json() : Promise.reject(new Error(String(response.status)))).then((body) => {
3015
- if (!cancelled) setSetup(body);
3016
- }).catch(() => {
3017
- if (!cancelled) setSetup({ ready: false, missing: [], repo: null, branch: "", file: "", unknown: true });
3374
+ void checkForUpdate(fingerprint.version).then((status2) => {
3375
+ if (cancelled) return;
3376
+ setUpdate(status2);
3377
+ if (!status2?.behind) return;
3378
+ try {
3379
+ const key = "pt_release_seen";
3380
+ if (window.localStorage.getItem(key) !== status2.latest) {
3381
+ window.localStorage.setItem(key, status2.latest);
3382
+ setReleaseOpen(true);
3383
+ }
3384
+ } catch {
3385
+ setReleaseOpen(true);
3386
+ }
3018
3387
  });
3019
3388
  return () => {
3020
3389
  cancelled = true;
3021
3390
  };
3022
- }, [helpOpen, saveEndpoint, setup]);
3391
+ }, [checkForUpdates, fingerprint?.version]);
3392
+ const readSetup = useCallback5(async () => {
3393
+ if (!saveEndpoint) return;
3394
+ try {
3395
+ const response = await fetch(saveEndpoint, { headers: { accept: "application/json" } });
3396
+ if (!response.ok) throw new Error(String(response.status));
3397
+ setSetup(await response.json());
3398
+ } catch {
3399
+ setSetup({ ready: false, missing: [], repo: null, branch: "", file: "", unknown: true });
3400
+ }
3401
+ }, [saveEndpoint]);
3402
+ useEffect9(() => {
3403
+ if (!helpOpen || !saveEndpoint || setup) return;
3404
+ void readSetup();
3405
+ }, [helpOpen, saveEndpoint, setup, readSetup]);
3406
+ useEffect9(() => {
3407
+ if (!saveEndpoint || setup || !isFirstRun(initialState)) return;
3408
+ void readSetup();
3409
+ }, [saveEndpoint, setup, initialState, readSetup]);
3410
+ useEffect9(() => {
3411
+ if (!setup || setup.ready || !isFirstRun(initialState) || wizardClosed()) return;
3412
+ setWizardOpen(true);
3413
+ }, [setup, initialState]);
3023
3414
  const endSession = useCallback5(async () => {
3024
3415
  setSignOut("working");
3025
3416
  try {
@@ -3047,7 +3438,8 @@ function PanelApp({
3047
3438
  const conflict = response.status === 409;
3048
3439
  throw Object.assign(new Error(saveError(response.status, data, body)), { conflict });
3049
3440
  }
3050
- setSavedSnapshot(JSON.stringify(state));
3441
+ setSavedSnapshot(JSON.stringify(next));
3442
+ setState(next);
3051
3443
  setSave({
3052
3444
  status: "saved",
3053
3445
  at: (/* @__PURE__ */ new Date()).toLocaleTimeString(lang === "es" ? "es-ES" : "en-GB", {
@@ -3082,21 +3474,21 @@ function PanelApp({
3082
3474
  state.updatedAt,
3083
3475
  save.status === "saved" ? ui.savedAt(save.at) : dirty ? ui.unsaved : ""
3084
3476
  ].filter(Boolean).join(" \xB7 ");
3085
- return /* @__PURE__ */ jsxs17(DashboardThemeProvider, { tokens: theme, form, className, children: [
3086
- decoration,
3087
- /* @__PURE__ */ jsx19(
3477
+ return /* @__PURE__ */ jsxs18(DashboardThemeProvider, { tokens: theme, form, className, children: [
3478
+ typeof decoration === "function" ? decoration(themeName) : decoration,
3479
+ /* @__PURE__ */ jsx20(
3088
3480
  DashboardHeader,
3089
3481
  {
3090
3482
  wordmark: (
3091
3483
  /* A board belongs to a project, so its name is what goes here. A
3092
3484
  caller with a mark of its own passes `brand`; drawing one here
3093
3485
  would be the kit deciding what somebody else's panel is called. */
3094
- brand ?? /* @__PURE__ */ jsx19("span", { className: "pt-panel-brand", children: state.project })
3486
+ brand ?? /* @__PURE__ */ jsx20("span", { className: "pt-panel-brand", children: state.project })
3095
3487
  ),
3096
3488
  status,
3097
- controls: /* @__PURE__ */ jsxs17(Fragment5, { children: [
3098
- (initialState.analysis || hasMarketplace || showHistory) && /* @__PURE__ */ jsxs17("span", { className: "pt-views", children: [
3099
- /* @__PURE__ */ jsx19(
3489
+ controls: /* @__PURE__ */ jsxs18(Fragment5, { children: [
3490
+ (initialState.analysis || hasMarketplace || showHistory) && /* @__PURE__ */ jsxs18("span", { className: "pt-views", children: [
3491
+ /* @__PURE__ */ jsx20(
3100
3492
  "button",
3101
3493
  {
3102
3494
  type: "button",
@@ -3106,7 +3498,7 @@ function PanelApp({
3106
3498
  children: ui.board
3107
3499
  }
3108
3500
  ),
3109
- initialState.analysis && /* @__PURE__ */ jsx19(
3501
+ initialState.analysis && /* @__PURE__ */ jsx20(
3110
3502
  "button",
3111
3503
  {
3112
3504
  type: "button",
@@ -3116,7 +3508,7 @@ function PanelApp({
3116
3508
  children: ui.analysis
3117
3509
  }
3118
3510
  ),
3119
- hasMarketplace && /* @__PURE__ */ jsx19(
3511
+ hasMarketplace && /* @__PURE__ */ jsx20(
3120
3512
  "button",
3121
3513
  {
3122
3514
  type: "button",
@@ -3126,7 +3518,7 @@ function PanelApp({
3126
3518
  children: ui.marketplace
3127
3519
  }
3128
3520
  ),
3129
- showHistory && /* @__PURE__ */ jsx19(
3521
+ showHistory && /* @__PURE__ */ jsx20(
3130
3522
  "button",
3131
3523
  {
3132
3524
  type: "button",
@@ -3137,7 +3529,7 @@ function PanelApp({
3137
3529
  }
3138
3530
  )
3139
3531
  ] }),
3140
- showLanguage && LANGS.map((code) => /* @__PURE__ */ jsx19(
3532
+ showLanguage && LANGS.map((code) => /* @__PURE__ */ jsx20(
3141
3533
  "button",
3142
3534
  {
3143
3535
  type: "button",
@@ -3148,7 +3540,7 @@ function PanelApp({
3148
3540
  },
3149
3541
  code
3150
3542
  )),
3151
- /* @__PURE__ */ jsx19(
3543
+ /* @__PURE__ */ jsx20(
3152
3544
  NotificationBell,
3153
3545
  {
3154
3546
  notifications,
@@ -3162,8 +3554,8 @@ function PanelApp({
3162
3554
  }
3163
3555
  }
3164
3556
  ),
3165
- saveEndpoint && /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-lang", onClick: () => setHelpOpen(true), children: ui.help }),
3166
- saveEndpoint && (dirty || save.status === "saving") && /* @__PURE__ */ jsx19(
3557
+ saveEndpoint && /* @__PURE__ */ jsx20("button", { type: "button", className: "pt-lang", onClick: () => setHelpOpen(true), children: ui.help }),
3558
+ saveEndpoint && (dirty || save.status === "saving") && /* @__PURE__ */ jsx20(
3167
3559
  "button",
3168
3560
  {
3169
3561
  type: "button",
@@ -3178,7 +3570,7 @@ function PanelApp({
3178
3570
  onLinkClick: () => setSettingsOpen(true)
3179
3571
  }
3180
3572
  ),
3181
- state.notice && /* @__PURE__ */ jsx19(
3573
+ state.notice && /* @__PURE__ */ jsx20(
3182
3574
  AlertBanner,
3183
3575
  {
3184
3576
  visible: noticeVisible,
@@ -3187,8 +3579,17 @@ function PanelApp({
3187
3579
  onAction: () => setNoticeVisible(false)
3188
3580
  }
3189
3581
  ),
3190
- save.status === "error" && /* @__PURE__ */ jsx19(AlertBanner, { visible: true, message: `${ui.saveFailed}: ${save.message}` }),
3191
- view === "board" && !saveEndpoint && /* @__PURE__ */ jsx19(
3582
+ save.status === "error" && /* @__PURE__ */ jsx20(AlertBanner, { visible: true, message: `${ui.saveFailed}: ${save.message}` }),
3583
+ saveEndpoint && setup && !setup.ready && !setup.unknown && !wizardOpen && /* @__PURE__ */ jsx20(
3584
+ AlertBanner,
3585
+ {
3586
+ visible: true,
3587
+ message: ui.wizardBanner,
3588
+ actionLabel: ui.wizardOpen,
3589
+ onAction: () => setWizardOpen(true)
3590
+ }
3591
+ ),
3592
+ view === "board" && !saveEndpoint && /* @__PURE__ */ jsx20(
3192
3593
  GuideTour,
3193
3594
  {
3194
3595
  dismissed: state.preferences?.guideDismissed,
@@ -3197,32 +3598,32 @@ function PanelApp({
3197
3598
  {
3198
3599
  id: "demo-welcome",
3199
3600
  title: ui.demoTourWelcomeTitle,
3200
- children: /* @__PURE__ */ jsx19("p", { children: ui.demoTourWelcomeBody }),
3601
+ children: /* @__PURE__ */ jsx20("p", { children: ui.demoTourWelcomeBody }),
3201
3602
  dismissLabel: ui.gotIt
3202
3603
  },
3203
3604
  {
3204
3605
  id: "demo-board",
3205
3606
  title: ui.demoTourBoardTitle,
3206
- children: /* @__PURE__ */ jsx19("p", { children: ui.demoTourBoardBody }),
3607
+ children: /* @__PURE__ */ jsx20("p", { children: ui.demoTourBoardBody }),
3207
3608
  dismissLabel: ui.gotIt
3208
3609
  },
3209
3610
  {
3210
3611
  id: "demo-theme",
3211
3612
  title: ui.demoTourThemeTitle,
3212
- children: /* @__PURE__ */ jsx19("p", { children: ui.demoTourThemeBody }),
3613
+ children: /* @__PURE__ */ jsx20("p", { children: ui.demoTourThemeBody }),
3213
3614
  dismissLabel: ui.gotIt,
3214
3615
  action: { label: ui.settings, onClick: () => setSettingsOpen(true) }
3215
3616
  },
3216
3617
  {
3217
3618
  id: "demo-keep",
3218
3619
  title: ui.demoTourKeepTitle,
3219
- children: /* @__PURE__ */ jsx19("p", { children: ui.demoTourKeepBody }),
3620
+ children: /* @__PURE__ */ jsx20("p", { children: ui.demoTourKeepBody }),
3220
3621
  dismissLabel: ui.gotIt
3221
3622
  }
3222
3623
  ]
3223
3624
  }
3224
3625
  ),
3225
- view === "board" && saveEndpoint && /* @__PURE__ */ jsx19(
3626
+ view === "board" && saveEndpoint && /* @__PURE__ */ jsx20(
3226
3627
  GuideTour,
3227
3628
  {
3228
3629
  dismissed: state.preferences?.guideDismissed,
@@ -3231,38 +3632,38 @@ function PanelApp({
3231
3632
  {
3232
3633
  id: "welcome",
3233
3634
  title: ui.tourWelcomeTitle,
3234
- children: /* @__PURE__ */ jsx19("p", { children: ui.tourWelcomeBody }),
3635
+ children: /* @__PURE__ */ jsx20("p", { children: ui.tourWelcomeBody }),
3235
3636
  dismissLabel: ui.gotIt
3236
3637
  },
3237
3638
  {
3238
3639
  id: "board",
3239
3640
  title: ui.tourBoardTitle,
3240
- children: /* @__PURE__ */ jsx19("p", { children: ui.tourBoardBody }),
3641
+ children: /* @__PURE__ */ jsx20("p", { children: ui.tourBoardBody }),
3241
3642
  dismissLabel: ui.gotIt
3242
3643
  },
3243
3644
  {
3244
3645
  id: "orders",
3245
3646
  title: ui.tourOrdersTitle,
3246
- children: /* @__PURE__ */ jsx19("p", { children: ui.tourOrdersBody }),
3647
+ children: /* @__PURE__ */ jsx20("p", { children: ui.tourOrdersBody }),
3247
3648
  dismissLabel: ui.gotIt
3248
3649
  },
3249
3650
  {
3250
3651
  id: "save",
3251
3652
  title: ui.tourSaveTitle,
3252
- children: /* @__PURE__ */ jsx19("p", { children: ui.tourSaveBody }),
3653
+ children: /* @__PURE__ */ jsx20("p", { children: ui.tourSaveBody }),
3253
3654
  dismissLabel: ui.gotIt
3254
3655
  },
3255
3656
  {
3256
3657
  id: "theme",
3257
3658
  title: ui.tourThemeTitle,
3258
- children: /* @__PURE__ */ jsx19("p", { children: ui.tourThemeBody }),
3659
+ children: /* @__PURE__ */ jsx20("p", { children: ui.tourThemeBody }),
3259
3660
  dismissLabel: ui.gotIt,
3260
3661
  action: { label: ui.settings, onClick: () => setSettingsOpen(true) }
3261
3662
  }
3262
3663
  ]
3263
3664
  }
3264
3665
  ),
3265
- view === "marketplace" && hasMarketplace && /* @__PURE__ */ jsx19(
3666
+ view === "marketplace" && hasMarketplace && /* @__PURE__ */ jsx20(
3266
3667
  MarketplaceView,
3267
3668
  {
3268
3669
  report: market,
@@ -3273,9 +3674,10 @@ function PanelApp({
3273
3674
  onRefresh: marketplaceEndpoint ? () => loadMarketplace(true) : void 0
3274
3675
  }
3275
3676
  ),
3276
- view === "analysis" && state.analysis && /* @__PURE__ */ jsx19(
3677
+ view === "analysis" && state.analysis && /* @__PURE__ */ jsx20(
3277
3678
  AnalysisView,
3278
3679
  {
3680
+ onRequestReport: saveEndpoint ? requestReport : void 0,
3279
3681
  analysis: state.analysis,
3280
3682
  cards: state.cards,
3281
3683
  columns: state.columns,
@@ -3288,20 +3690,20 @@ function PanelApp({
3288
3690
  onOpenCard: setOpenCardId
3289
3691
  }
3290
3692
  ),
3291
- view === "board" && /* @__PURE__ */ jsxs17(Fragment5, { children: [
3292
- /* @__PURE__ */ jsxs17("div", { className: "pt-panel-page", children: [
3293
- /* @__PURE__ */ jsxs17(StatTileGrid, { children: [
3294
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statOpen, value: counts.open, isZero: counts.open === 0 }),
3295
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statOrders, value: counts.orders, tone: "warning", isZero: counts.orders === 0 }),
3296
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statYours, value: counts.yours, tone: "danger", isZero: counts.yours === 0 }),
3297
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statDecisions, value: counts.decisions, tone: "warning", isZero: counts.decisions === 0 }),
3298
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statHighRisk, value: counts.highRisk, tone: "danger", isZero: counts.highRisk === 0 }),
3299
- /* @__PURE__ */ jsx19(StatTile, { label: ui.statDone, value: counts.done, tone: "success", isZero: counts.done === 0 })
3693
+ view === "board" && /* @__PURE__ */ jsxs18(Fragment5, { children: [
3694
+ /* @__PURE__ */ jsxs18("div", { className: "pt-panel-page", children: [
3695
+ /* @__PURE__ */ jsxs18(StatTileGrid, { children: [
3696
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statOpen, value: counts.open, isZero: counts.open === 0 }),
3697
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statOrders, value: counts.orders, tone: "warning", isZero: counts.orders === 0 }),
3698
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statYours, value: counts.yours, tone: "danger", isZero: counts.yours === 0 }),
3699
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statDecisions, value: counts.decisions, tone: "warning", isZero: counts.decisions === 0 }),
3700
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statHighRisk, value: counts.highRisk, tone: "danger", isZero: counts.highRisk === 0 }),
3701
+ /* @__PURE__ */ jsx20(StatTile, { label: ui.statDone, value: counts.done, tone: "success", isZero: counts.done === 0 })
3300
3702
  ] }),
3301
- /* @__PURE__ */ jsx19(HealthPillRow, { children: state.health.map((pill) => /* @__PURE__ */ jsx19(HealthPill, { label: t(pill.label), value: t(pill.value), status: pill.status }, t(pill.label))) }),
3302
- /* @__PURE__ */ jsxs17(FilterChipRow, { children: [
3303
- /* @__PURE__ */ jsx19(FilterChip, { label: ui.all, count: state.cards.length, active: filter === "all", onClick: () => setFilter("all") }),
3304
- /* @__PURE__ */ jsx19(
3703
+ /* @__PURE__ */ jsx20(HealthPillRow, { children: state.health.map((pill) => /* @__PURE__ */ jsx20(HealthPill, { label: t(pill.label), value: t(pill.value), status: pill.status }, t(pill.label))) }),
3704
+ /* @__PURE__ */ jsxs18(FilterChipRow, { children: [
3705
+ /* @__PURE__ */ jsx20(FilterChip, { label: ui.all, count: state.cards.length, active: filter === "all", onClick: () => setFilter("all") }),
3706
+ /* @__PURE__ */ jsx20(
3305
3707
  FilterChip,
3306
3708
  {
3307
3709
  label: `\u26A1 ${ui.filterForClaude}`,
@@ -3310,7 +3712,7 @@ function PanelApp({
3310
3712
  onClick: () => setFilter("orders")
3311
3713
  }
3312
3714
  ),
3313
- /* @__PURE__ */ jsx19(
3715
+ /* @__PURE__ */ jsx20(
3314
3716
  FilterChip,
3315
3717
  {
3316
3718
  label: ui.filterYours,
@@ -3319,7 +3721,7 @@ function PanelApp({
3319
3721
  onClick: () => setFilter("yours")
3320
3722
  }
3321
3723
  ),
3322
- /* @__PURE__ */ jsx19(
3724
+ /* @__PURE__ */ jsx20(
3323
3725
  FilterChip,
3324
3726
  {
3325
3727
  label: ui.filterHighRisk,
@@ -3328,7 +3730,7 @@ function PanelApp({
3328
3730
  onClick: () => setFilter("risk")
3329
3731
  }
3330
3732
  ),
3331
- state.areas.map((area) => /* @__PURE__ */ jsx19(
3733
+ state.areas.map((area) => /* @__PURE__ */ jsx20(
3332
3734
  FilterChip,
3333
3735
  {
3334
3736
  label: t(area.label),
@@ -3340,13 +3742,13 @@ function PanelApp({
3340
3742
  ))
3341
3743
  ] })
3342
3744
  ] }),
3343
- /* @__PURE__ */ jsx19(
3745
+ /* @__PURE__ */ jsx20(
3344
3746
  Board,
3345
3747
  {
3346
3748
  columns: boardColumns,
3347
3749
  onMove: moveCard,
3348
3750
  onAddCard: addCard,
3349
- renderCard: (card, index, columnId) => /* @__PURE__ */ jsx19(
3751
+ renderCard: (card, index, columnId) => /* @__PURE__ */ jsx20(
3350
3752
  Card,
3351
3753
  {
3352
3754
  cardId: card.id,
@@ -3363,39 +3765,39 @@ function PanelApp({
3363
3765
  }
3364
3766
  ),
3365
3767
  extras,
3366
- capabilities && capabilities.length > 0 && /* @__PURE__ */ jsxs17("section", { className: "pt-panel-page pt-panel-section", id: "functions", children: [
3367
- /* @__PURE__ */ jsxs17("div", { children: [
3368
- /* @__PURE__ */ jsx19("p", { className: "pt-eyebrow", children: ui.functionsEyebrow }),
3369
- /* @__PURE__ */ jsx19("h2", { className: "pt-h2", children: ui.functionsTitle }),
3370
- /* @__PURE__ */ jsx19("p", { className: "pt-sub", children: ui.functionsIntro })
3768
+ capabilities && capabilities.length > 0 && /* @__PURE__ */ jsxs18("section", { className: "pt-panel-page pt-panel-section", id: "functions", children: [
3769
+ /* @__PURE__ */ jsxs18("div", { children: [
3770
+ /* @__PURE__ */ jsx20("p", { className: "pt-eyebrow", children: ui.functionsEyebrow }),
3771
+ /* @__PURE__ */ jsx20("h2", { className: "pt-h2", children: ui.functionsTitle }),
3772
+ /* @__PURE__ */ jsx20("p", { className: "pt-sub", children: ui.functionsIntro })
3371
3773
  ] }),
3372
- /* @__PURE__ */ jsx19("div", { className: "pt-cap-list", children: capabilities.map((capability) => /* @__PURE__ */ jsxs17("article", { className: "pt-cap pt-hud", children: [
3373
- /* @__PURE__ */ jsx19("h3", { className: "pt-cap__title", children: t(capability.title) }),
3374
- /* @__PURE__ */ jsx19("p", { className: "pt-cap__summary", children: t(capability.summary) }),
3375
- /* @__PURE__ */ jsx19("ul", { className: "pt-cap__list", children: capability.points.map((point) => /* @__PURE__ */ jsx19("li", { children: t(point) }, t(point))) }),
3376
- capability.code && /* @__PURE__ */ jsxs17("div", { className: "pt-cap__code", children: [
3377
- /* @__PURE__ */ jsx19("p", { className: "pt-cap__caption", children: t(capability.code.caption) }),
3378
- /* @__PURE__ */ jsx19("pre", { children: /* @__PURE__ */ jsx19("code", { children: capability.code.body }) })
3774
+ /* @__PURE__ */ jsx20("div", { className: "pt-cap-list", children: capabilities.map((capability) => /* @__PURE__ */ jsxs18("article", { className: "pt-cap pt-hud", children: [
3775
+ /* @__PURE__ */ jsx20("h3", { className: "pt-cap__title", children: t(capability.title) }),
3776
+ /* @__PURE__ */ jsx20("p", { className: "pt-cap__summary", children: t(capability.summary) }),
3777
+ /* @__PURE__ */ jsx20("ul", { className: "pt-cap__list", children: capability.points.map((point) => /* @__PURE__ */ jsx20("li", { children: t(point) }, t(point))) }),
3778
+ capability.code && /* @__PURE__ */ jsxs18("div", { className: "pt-cap__code", children: [
3779
+ /* @__PURE__ */ jsx20("p", { className: "pt-cap__caption", children: t(capability.code.caption) }),
3780
+ /* @__PURE__ */ jsx20("pre", { children: /* @__PURE__ */ jsx20("code", { children: capability.code.body }) })
3379
3781
  ] })
3380
3782
  ] }, capability.id)) })
3381
3783
  ] })
3382
3784
  ] }),
3383
- view === "history" && showHistory && /* @__PURE__ */ jsxs17("section", { className: "pt-panel-page pt-panel-section", id: "revisions", children: [
3384
- /* @__PURE__ */ jsxs17("div", { children: [
3385
- /* @__PURE__ */ jsx19("p", { className: "pt-eyebrow", children: ui.historyEyebrow }),
3386
- /* @__PURE__ */ jsx19("h2", { className: "pt-h2", children: ui.historyTitle }),
3387
- /* @__PURE__ */ jsx19("p", { className: "pt-sub", children: ui.historyIntro })
3785
+ view === "history" && showHistory && /* @__PURE__ */ jsxs18("section", { className: "pt-panel-page pt-panel-section", id: "revisions", children: [
3786
+ /* @__PURE__ */ jsxs18("div", { children: [
3787
+ /* @__PURE__ */ jsx20("p", { className: "pt-eyebrow", children: ui.historyEyebrow }),
3788
+ /* @__PURE__ */ jsx20("h2", { className: "pt-h2", children: ui.historyTitle }),
3789
+ /* @__PURE__ */ jsx20("p", { className: "pt-sub", children: ui.historyIntro })
3388
3790
  ] }),
3389
- state.runs.length === 0 ? /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: ui.historyEmpty }) : /* @__PURE__ */ jsx19("ol", { className: "pt-runs", children: [...state.runs].reverse().map((run) => /* @__PURE__ */ jsxs17("li", { className: "pt-run pt-hud", children: [
3390
- /* @__PURE__ */ jsxs17("p", { className: "pt-run__meta", children: [
3791
+ state.runs.length === 0 ? /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.historyEmpty }) : /* @__PURE__ */ jsx20("ol", { className: "pt-runs", children: [...state.runs].reverse().map((run) => /* @__PURE__ */ jsxs18("li", { className: "pt-run pt-hud", children: [
3792
+ /* @__PURE__ */ jsxs18("p", { className: "pt-run__meta", children: [
3391
3793
  run.date,
3392
3794
  " \xB7 ",
3393
3795
  run.by === "claude" ? "Claude" : ui.ownerYou,
3394
3796
  run.fingerprint ? ` \xB7 ${run.fingerprint.replace("sha256:", "").slice(0, 12)}` : ""
3395
3797
  ] }),
3396
- /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: t(run.summary) }),
3397
- run.cards.length > 0 && /* @__PURE__ */ jsxs17("p", { className: "pt-run__cards", children: [
3398
- /* @__PURE__ */ jsxs17("span", { children: [
3798
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: t(run.summary) }),
3799
+ run.cards.length > 0 && /* @__PURE__ */ jsxs18("p", { className: "pt-run__cards", children: [
3800
+ /* @__PURE__ */ jsxs18("span", { children: [
3399
3801
  ui.historyTouched,
3400
3802
  ":"
3401
3803
  ] }),
@@ -3407,7 +3809,7 @@ function PanelApp({
3407
3809
  ] })
3408
3810
  ] }, run.id)) })
3409
3811
  ] }),
3410
- /* @__PURE__ */ jsx19(
3812
+ /* @__PURE__ */ jsx20(
3411
3813
  CardSheet,
3412
3814
  {
3413
3815
  card: openCard,
@@ -3419,9 +3821,50 @@ function PanelApp({
3419
3821
  onClose: () => setOpenCardId(null)
3420
3822
  }
3421
3823
  ),
3422
- /* @__PURE__ */ jsxs17(DetailSheet, { open: helpOpen, onClose: () => setHelpOpen(false), ariaLabel: ui.helpTitle, children: [
3423
- /* @__PURE__ */ jsx19(DetailSection, { title: ui.helpTitle, children: !setup ? /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: ui.setupChecking }) : /* @__PURE__ */ jsxs17(Fragment5, { children: [
3424
- /* @__PURE__ */ jsx19(
3824
+ /* @__PURE__ */ jsx20(
3825
+ DetailSheet,
3826
+ {
3827
+ open: wizardOpen,
3828
+ onClose: () => {
3829
+ closeWizard();
3830
+ setWizardOpen(false);
3831
+ },
3832
+ ariaLabel: ui.wizardTitle,
3833
+ children: /* @__PURE__ */ jsx20(
3834
+ SetupWizard,
3835
+ {
3836
+ requirements,
3837
+ onCheck: readSetup,
3838
+ onClose: () => {
3839
+ closeWizard();
3840
+ setWizardOpen(false);
3841
+ },
3842
+ labels: {
3843
+ title: ui.wizardTitle,
3844
+ progress: ui.wizardProgress,
3845
+ nowDo: ui.wizardNowDo,
3846
+ check: ui.wizardCheck,
3847
+ checking: ui.wizardChecking,
3848
+ stillMissing: ui.wizardStillMissing,
3849
+ cannotTell: ui.wizardCannotTell,
3850
+ doneTitle: ui.wizardDoneTitle,
3851
+ readyTitle: ui.wizardReadyTitle,
3852
+ readyBody: ui.wizardReadyBody,
3853
+ verify: ui.wizardVerify,
3854
+ close: ui.wizardClose,
3855
+ stuckTitle: ui.wizardStuckTitle,
3856
+ stuckBody: ui.wizardStuckBody,
3857
+ stuckPrompt: ui.wizardStuckPrompt,
3858
+ copy: ui.wizardCopy,
3859
+ copied: ui.wizardCopied
3860
+ }
3861
+ }
3862
+ )
3863
+ }
3864
+ ),
3865
+ /* @__PURE__ */ jsxs18(DetailSheet, { open: helpOpen, onClose: () => setHelpOpen(false), ariaLabel: ui.helpTitle, children: [
3866
+ /* @__PURE__ */ jsx20(DetailSection, { title: ui.helpTitle, children: !setup ? /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.setupChecking }) : /* @__PURE__ */ jsxs18(Fragment5, { children: [
3867
+ /* @__PURE__ */ jsx20(
3425
3868
  SetupGuide,
3426
3869
  {
3427
3870
  requirements,
@@ -3434,9 +3877,21 @@ function PanelApp({
3434
3877
  }
3435
3878
  }
3436
3879
  ),
3437
- setup.repo && /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", style: { marginTop: 12 }, children: ui.setupWriteTarget(setup.repo, setup.branch, setup.file) })
3880
+ setup.repo && /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 12 }, children: ui.setupWriteTarget(setup.repo, setup.branch, setup.file) }),
3881
+ !setup.ready && /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", style: { marginTop: 12 }, children: /* @__PURE__ */ jsx20(
3882
+ "button",
3883
+ {
3884
+ type: "button",
3885
+ className: "pt-btn pt-btn--sm pt-btn--primary",
3886
+ onClick: () => {
3887
+ setHelpOpen(false);
3888
+ setWizardOpen(true);
3889
+ },
3890
+ children: ui.wizardOpen
3891
+ }
3892
+ ) })
3438
3893
  ] }) }),
3439
- /* @__PURE__ */ jsx19(DetailSection, { title: ui.guideSection, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx19(
3894
+ /* @__PURE__ */ jsx20(DetailSection, { title: ui.guideSection, children: /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx20(
3440
3895
  "button",
3441
3896
  {
3442
3897
  type: "button",
@@ -3454,9 +3909,43 @@ function PanelApp({
3454
3909
  }
3455
3910
  ) }) })
3456
3911
  ] }),
3457
- /* @__PURE__ */ jsxs17(DetailSheet, { open: settingsOpen, onClose: () => setSettingsOpen(false), ariaLabel: ui.panelSettings, children: [
3458
- saveEndpoint ? /* @__PURE__ */ jsxs17(DetailSection, { title: ui.saveSection, subtitle: ui.saveSubtitle, children: [
3459
- /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx19(
3912
+ update?.behind && /* @__PURE__ */ jsxs18(
3913
+ DetailSheet,
3914
+ {
3915
+ open: releaseOpen,
3916
+ onClose: () => setReleaseOpen(false),
3917
+ ariaLabel: ui.releaseTitle(update.latest),
3918
+ children: [
3919
+ /* @__PURE__ */ jsxs18("div", { children: [
3920
+ /* @__PURE__ */ jsx20("p", { className: "pt-eyebrow", children: releaseShape(update.notes) ? ui.releaseShape[releaseShape(update.notes)] : "" }),
3921
+ /* @__PURE__ */ jsx20("h2", { className: "pt-h2", children: ui.releaseTitle(update.latest) }),
3922
+ update.notes?.date && /* @__PURE__ */ jsx20("p", { className: "pt-sub", children: ui.releaseDate(update.notes.date) })
3923
+ ] }),
3924
+ update.notes ? /* @__PURE__ */ jsx20("ul", { className: "pt-runs", children: update.notes.entries.map((item, index) => /* @__PURE__ */ jsxs18("li", { className: "pt-run pt-hud", children: [
3925
+ /* @__PURE__ */ jsx20("p", { className: "pt-run__meta", children: ui.releaseKind[item.kind] }),
3926
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: item.text[lang] })
3927
+ ] }, index)) }) : /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.releaseNone }),
3928
+ /* @__PURE__ */ jsxs18("div", { className: "pt-panel-row", style: { marginTop: 16 }, children: [
3929
+ /* @__PURE__ */ jsx20(
3930
+ "button",
3931
+ {
3932
+ type: "button",
3933
+ className: "pt-btn",
3934
+ onClick: () => {
3935
+ setReleaseOpen(false);
3936
+ setSettingsOpen(true);
3937
+ },
3938
+ children: ui.updateCreateCard
3939
+ }
3940
+ ),
3941
+ /* @__PURE__ */ jsx20("button", { type: "button", className: "pt-btn", onClick: () => setReleaseOpen(false), children: ui.releaseClose })
3942
+ ] })
3943
+ ]
3944
+ }
3945
+ ),
3946
+ /* @__PURE__ */ jsxs18(DetailSheet, { open: settingsOpen, onClose: () => setSettingsOpen(false), ariaLabel: ui.panelSettings, children: [
3947
+ saveEndpoint ? /* @__PURE__ */ jsxs18(DetailSection, { title: ui.saveSection, subtitle: ui.saveSubtitle, children: [
3948
+ /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx20(
3460
3949
  "button",
3461
3950
  {
3462
3951
  type: "button",
@@ -3466,15 +3955,15 @@ function PanelApp({
3466
3955
  children: save.status === "saving" ? ui.saving : ui.save
3467
3956
  }
3468
3957
  ) }),
3469
- /* @__PURE__ */ jsxs17("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: [
3958
+ /* @__PURE__ */ jsxs18("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: [
3470
3959
  save.status === "error" ? `${ui.saveFailed}: ${save.message}` : save.status === "saved" ? ui.savedWithCommit : dirty ? ui.saveHelp : ui.upToDate,
3471
- save.status === "saved" && save.url && /* @__PURE__ */ jsxs17(Fragment5, { children: [
3960
+ save.status === "saved" && save.url && /* @__PURE__ */ jsxs18(Fragment5, { children: [
3472
3961
  " ",
3473
- /* @__PURE__ */ jsx19("a", { href: save.url, children: "commit" })
3962
+ /* @__PURE__ */ jsx20("a", { href: save.url, children: "commit" })
3474
3963
  ] })
3475
3964
  ] })
3476
- ] }) : /* @__PURE__ */ jsx19(DetailSection, { title: ui.saveSection, subtitle: ui.saveSubtitle, children: /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: ui.demoNotice }) }),
3477
- showLanguage && /* @__PURE__ */ jsx19(DetailSection, { title: ui.language, subtitle: ui.languageSubtitle, children: /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: LANGS.map((code) => /* @__PURE__ */ jsx19(
3965
+ ] }) : /* @__PURE__ */ jsx20(DetailSection, { title: ui.saveSection, subtitle: ui.saveSubtitle, children: /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.demoNotice }) }),
3966
+ showLanguage && /* @__PURE__ */ jsx20(DetailSection, { title: ui.language, subtitle: ui.languageSubtitle, children: /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", children: LANGS.map((code) => /* @__PURE__ */ jsx20(
3478
3967
  FilterChip,
3479
3968
  {
3480
3969
  label: LANG_LABELS[code],
@@ -3483,9 +3972,9 @@ function PanelApp({
3483
3972
  },
3484
3973
  code
3485
3974
  )) }) }),
3486
- /* @__PURE__ */ jsxs17(DetailSection, { title: ui.theme, subtitle: ui.themeSubtitle, children: [
3487
- /* @__PURE__ */ jsxs17("div", { className: "pt-panel-row", children: [
3488
- Object.entries(themes).map(([name, entry]) => /* @__PURE__ */ jsx19(
3975
+ /* @__PURE__ */ jsxs18(DetailSection, { title: ui.theme, subtitle: ui.themeSubtitle, children: [
3976
+ /* @__PURE__ */ jsxs18("div", { className: "pt-panel-row", children: [
3977
+ Object.entries(themes).map(([name, entry]) => /* @__PURE__ */ jsx20(
3489
3978
  FilterChip,
3490
3979
  {
3491
3980
  label: entry.label,
@@ -3494,7 +3983,7 @@ function PanelApp({
3494
3983
  },
3495
3984
  name
3496
3985
  )),
3497
- state.importedTheme && /* @__PURE__ */ jsx19(
3986
+ state.importedTheme && /* @__PURE__ */ jsx20(
3498
3987
  FilterChip,
3499
3988
  {
3500
3989
  label: t(state.importedTheme.label),
@@ -3503,21 +3992,38 @@ function PanelApp({
3503
3992
  }
3504
3993
  )
3505
3994
  ] }),
3506
- /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: themeName === IMPORTED ? t(imported?.from.reasoning) : [chosen.note, ui.themeNote].filter(Boolean).join(". ") }),
3507
- state.importedTheme && /* @__PURE__ */ jsxs17("div", { className: "pt-cap pt-hud", style: { marginTop: 14 }, children: [
3508
- /* @__PURE__ */ jsx19("h3", { className: "pt-cap__title", children: ui.importedTheme }),
3509
- /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: ui.importedFrom(state.importedTheme.importedAt, state.importedTheme.from.files.join(", ")) }),
3510
- state.importedTheme.from.colours.length > 0 && /* @__PURE__ */ jsx19("p", { className: "pt-tool__tags", children: state.importedTheme.from.colours.map((colour) => /* @__PURE__ */ jsx19("span", { className: "pt-tool__tag", children: colour }, colour)) }),
3511
- state.importedTheme.refreshRequested ? /* @__PURE__ */ jsx19("p", { className: "pt-warn", children: ui.importedRefreshAsked(state.importedTheme.refreshRequested) }) : /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", style: { marginTop: 10 }, children: /* @__PURE__ */ jsx19("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: requestThemeRefresh, children: ui.importedRefresh }) }),
3512
- /* @__PURE__ */ jsx19("p", { className: "pt-marketplace__detail", children: ui.importedRefreshHow })
3995
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: themeName === IMPORTED ? t(imported?.from.reasoning) : [chosen.note, ui.themeNote].filter(Boolean).join(". ") }),
3996
+ state.importedTheme && /* @__PURE__ */ jsxs18("div", { className: "pt-cap pt-hud", style: { marginTop: 14 }, children: [
3997
+ /* @__PURE__ */ jsx20("h3", { className: "pt-cap__title", children: ui.importedTheme }),
3998
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.importedFrom(state.importedTheme.importedAt, state.importedTheme.from.files.join(", ")) }),
3999
+ state.importedTheme.from.colours.length > 0 && /* @__PURE__ */ jsx20("p", { className: "pt-tool__tags", children: state.importedTheme.from.colours.map((colour) => /* @__PURE__ */ jsx20("span", { className: "pt-tool__tag", children: colour }, colour)) }),
4000
+ state.importedTheme.refreshRequested ? /* @__PURE__ */ jsx20("p", { className: "pt-warn", children: ui.importedRefreshAsked(state.importedTheme.refreshRequested) }) : /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", style: { marginTop: 10 }, children: /* @__PURE__ */ jsx20("button", { type: "button", className: "pt-btn pt-btn--sm", onClick: requestThemeRefresh, children: ui.importedRefresh }) }),
4001
+ /* @__PURE__ */ jsx20("p", { className: "pt-marketplace__detail", children: ui.importedRefreshHow })
3513
4002
  ] })
3514
4003
  ] }),
3515
- fingerprint && /* @__PURE__ */ jsxs17(DetailSection, { title: ui.fingerprint, subtitle: ui.fingerprintSubtitle, children: [
3516
- /* @__PURE__ */ jsx19("p", { className: "pt-panel-mono", children: fingerprint.hash }),
3517
- /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", style: { marginTop: 8 }, children: ui.trackedFiles(fingerprint.fileCount, fingerprint.version) })
4004
+ checkForUpdates && fingerprint?.version && /* @__PURE__ */ jsxs18(DetailSection, { title: ui.updateTitle, subtitle: ui.updateSubtitle, children: [
4005
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: ui.updateCurrent(fingerprint.version) }),
4006
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 8 }, children: !update ? ui.updateUnknown : update.behind ? ui.updateAvailable(update.latest) : ui.updateUpToDate }),
4007
+ update?.behind && (state.cards.some((card) => card.id === updateCardId(update.latest)) ? /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 8 }, children: ui.updateCardExists }) : /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", style: { marginTop: 12 }, children: /* @__PURE__ */ jsx20("button", { type: "button", className: "pt-btn", onClick: addUpdateCard, children: ui.updateCreateCard }) })),
4008
+ /* @__PURE__ */ jsxs18("label", { className: "pt-panel-row", style: { marginTop: 12 }, children: [
4009
+ /* @__PURE__ */ jsx20(
4010
+ "input",
4011
+ {
4012
+ type: "checkbox",
4013
+ checked: state.preferences?.updateAsOrder === true,
4014
+ onChange: (event) => setPreference("updateAsOrder", event.target.checked)
4015
+ }
4016
+ ),
4017
+ /* @__PURE__ */ jsx20("span", { className: "pt-panel-text", children: ui.updateAsOrder })
4018
+ ] }),
4019
+ /* @__PURE__ */ jsx20("p", { className: "pt-marketplace__detail", children: ui.updateAsOrderHow })
4020
+ ] }),
4021
+ fingerprint && /* @__PURE__ */ jsxs18(DetailSection, { title: ui.fingerprint, subtitle: ui.fingerprintSubtitle, children: [
4022
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-mono", children: fingerprint.hash }),
4023
+ /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 8 }, children: ui.trackedFiles(fingerprint.fileCount, fingerprint.version) })
3518
4024
  ] }),
3519
- saveEndpoint && /* @__PURE__ */ jsxs17(DetailSection, { title: ui.session, subtitle: ui.sessionSubtitle, children: [
3520
- /* @__PURE__ */ jsx19("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx19(
4025
+ saveEndpoint && /* @__PURE__ */ jsxs18(DetailSection, { title: ui.session, subtitle: ui.sessionSubtitle, children: [
4026
+ /* @__PURE__ */ jsx20("div", { className: "pt-panel-row", children: /* @__PURE__ */ jsx20(
3521
4027
  "button",
3522
4028
  {
3523
4029
  type: "button",
@@ -3527,11 +4033,11 @@ function PanelApp({
3527
4033
  children: signOut === "working" ? ui.signingOut : ui.signOut
3528
4034
  }
3529
4035
  ) }),
3530
- signOut === "failed" && /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: ui.signOutFailed })
4036
+ signOut === "failed" && /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", style: { marginTop: 10 }, children: ui.signOutFailed })
3531
4037
  ] }),
3532
- links && links.length > 0 && /* @__PURE__ */ jsx19(DetailSection, { title: ui.links, children: /* @__PURE__ */ jsx19("p", { className: "pt-panel-text", children: links.map((link, index) => /* @__PURE__ */ jsxs17(React12.Fragment, { children: [
4038
+ links && links.length > 0 && /* @__PURE__ */ jsx20(DetailSection, { title: ui.links, children: /* @__PURE__ */ jsx20("p", { className: "pt-panel-text", children: links.map((link, index) => /* @__PURE__ */ jsxs18(React13.Fragment, { children: [
3533
4039
  index > 0 && " \xB7 ",
3534
- /* @__PURE__ */ jsx19("a", { href: link.href, children: link.label })
4040
+ /* @__PURE__ */ jsx20("a", { href: link.href, children: link.label })
3535
4041
  ] }, link.href)) }) })
3536
4042
  ] }),
3537
4043
  footer
@@ -3734,6 +4240,7 @@ export {
3734
4240
  PRESET_PANEL_THEMES,
3735
4241
  PanelApp,
3736
4242
  SetupGuide,
4243
+ SetupWizard,
3737
4244
  StatTile,
3738
4245
  StatTileGrid,
3739
4246
  THEME_FORMS,
@@ -3751,10 +4258,12 @@ export {
3751
4258
  emptyCard,
3752
4259
  explainBoard,
3753
4260
  isCard,
4261
+ isFirstRun,
3754
4262
  ledgerForm,
3755
4263
  midnightTheme,
3756
4264
  moveCardInColumns,
3757
4265
  newId,
4266
+ offeredThemes,
3758
4267
  oldMoneyTheme,
3759
4268
  panelForm,
3760
4269
  paneltirBuild,
@@ -3777,5 +4286,6 @@ export {
3777
4286
  useGuideNote,
3778
4287
  useMediaQuery,
3779
4288
  validateBoard,
4289
+ wizardStep,
3780
4290
  writeText
3781
4291
  };