paneltir 0.8.0 → 0.10.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/CLAUDE_MD_SNIPPET.md +34 -5
- package/INSTALL.md +68 -12
- package/README.md +1 -1
- package/bin/paneltir.mjs +304 -5
- package/dist/index.d.ts +327 -9
- package/dist/index.js +870 -417
- package/dist/style.css +122 -0
- package/fingerprint.json +5 -4
- package/package.json +50 -3
- package/template/.claude/skills/panel/SKILL.md +70 -0
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,17 @@ declare const PANELTIR_VERSION: string;
|
|
|
15
15
|
declare const PANELTIR_FINGERPRINT: string;
|
|
16
16
|
/** How many files that fingerprint covers. */
|
|
17
17
|
declare const PANELTIR_FILE_COUNT: number;
|
|
18
|
+
/**
|
|
19
|
+
* SHA-256 over `template/` alone — the gate, the seed board and the skill file.
|
|
20
|
+
*
|
|
21
|
+
* Separate from the fingerprint above because it answers a different question.
|
|
22
|
+
* The fingerprint says which build this is; this says whether the files a
|
|
23
|
+
* project *copied out of* the package are the ones it ships now. Most releases
|
|
24
|
+
* do not touch `template/`, so those two move at different rates, and a gate
|
|
25
|
+
* checked against the version number would be reported stale on every release
|
|
26
|
+
* and believed on none.
|
|
27
|
+
*/
|
|
28
|
+
declare const PANELTIR_TEMPLATE_HASH: string;
|
|
18
29
|
/**
|
|
19
30
|
* Everything needed to report the kit in a panel's own footer or settings
|
|
20
31
|
* sheet, and to check it against the released version without opening
|
|
@@ -24,6 +35,8 @@ declare const paneltirBuild: {
|
|
|
24
35
|
readonly version: string;
|
|
25
36
|
readonly fingerprint: string;
|
|
26
37
|
readonly fileCount: number;
|
|
38
|
+
/** What `init` stamps, and what a gate is compared against. */
|
|
39
|
+
readonly templateHash: string;
|
|
27
40
|
/** The tag this build came from, ready to compare or to link. */
|
|
28
41
|
readonly tag: `v${string}`;
|
|
29
42
|
/** Short form, for a footer that has one line to spare. */
|
|
@@ -388,7 +401,9 @@ interface GuideTourProps {
|
|
|
388
401
|
* durable. Leave it out and each reader's browser remembers, which is the
|
|
389
402
|
* right home for a fact about one browser — and the wrong one for a panel
|
|
390
403
|
* with a single owner, who would be told the same tour again on a new
|
|
391
|
-
* machine.
|
|
404
|
+
* machine. Passing it does not switch the browser off: a note dismissed
|
|
405
|
+
* here is written to both, because a caller whose store needs saving would
|
|
406
|
+
* otherwise lose the dismissal on reload.
|
|
392
407
|
*/
|
|
393
408
|
dismissed?: string[];
|
|
394
409
|
/** Told when a note is dismissed. Required for `dismissed` to mean anything. */
|
|
@@ -442,7 +457,11 @@ interface NotificationBellProps {
|
|
|
442
457
|
* make, not the component's, which is why both work.
|
|
443
458
|
*/
|
|
444
459
|
seen?: string[];
|
|
445
|
-
/**
|
|
460
|
+
/**
|
|
461
|
+
* Told which ids were just seen. Required for `seen` to mean anything —
|
|
462
|
+
* though the bell also remembers in localStorage either way, so a caller
|
|
463
|
+
* that has not saved yet does not show the same notifications again.
|
|
464
|
+
*/
|
|
446
465
|
onSeen?: (ids: string[]) => void;
|
|
447
466
|
}
|
|
448
467
|
declare function NotificationBell({ notifications, labels, seen: given, onSeen }: NotificationBellProps): React.JSX.Element | null;
|
|
@@ -517,6 +536,121 @@ interface SetupGuideProps {
|
|
|
517
536
|
}
|
|
518
537
|
declare function SetupGuide({ requirements, readyMessage, labels }: SetupGuideProps): React.JSX.Element;
|
|
519
538
|
|
|
539
|
+
/**
|
|
540
|
+
* The setup, walked one step at a time.
|
|
541
|
+
*
|
|
542
|
+
* `SetupGuide` is the list: the right shape for somebody auditing a panel that
|
|
543
|
+
* already works. This is the other reader — the one who installed it twenty
|
|
544
|
+
* minutes ago, has four things missing and no idea which to do first. A wall
|
|
545
|
+
* of four is not four times as useful as one; it is the thing people close.
|
|
546
|
+
*
|
|
547
|
+
* Two rules hold it honest. It **checks rather than asks**: every step ends in
|
|
548
|
+
* a button that re-reads the environment from the server, so the reader is
|
|
549
|
+
* told whether it worked instead of ticking a box themselves. And it **never
|
|
550
|
+
* claims what it cannot see**: a panel that could not reach its own endpoint
|
|
551
|
+
* says the check failed, never that a variable is missing, because telling
|
|
552
|
+
* somebody to add a token they already added is the worse of the two wrong
|
|
553
|
+
* answers.
|
|
554
|
+
*
|
|
555
|
+
* There is no copy of the values here and nothing is written: the panel cannot
|
|
556
|
+
* set an environment variable, and a button that appeared to would be the same
|
|
557
|
+
* fault as one that appeared to install an update.
|
|
558
|
+
*/
|
|
559
|
+
interface SetupWizardLabels {
|
|
560
|
+
title: string;
|
|
561
|
+
/** `(index, total)` — "Step 2 of 5". */
|
|
562
|
+
progress: (index: number, total: number) => string;
|
|
563
|
+
/** Shown above the one step in hand. */
|
|
564
|
+
nowDo: string;
|
|
565
|
+
/** The button that re-reads the environment. */
|
|
566
|
+
check: string;
|
|
567
|
+
checking: string;
|
|
568
|
+
/** Said when a check ran and the step is still not in place. */
|
|
569
|
+
stillMissing: string;
|
|
570
|
+
/** Said when the panel could not ask its own server. */
|
|
571
|
+
cannotTell: string;
|
|
572
|
+
/** The heading over the finished steps. */
|
|
573
|
+
doneTitle: string;
|
|
574
|
+
/** Shown in place of a step when every requirement is in place. */
|
|
575
|
+
readyTitle: string;
|
|
576
|
+
readyBody: string;
|
|
577
|
+
/** The two things to try before trusting the gate, as list items. */
|
|
578
|
+
verify: string[];
|
|
579
|
+
/** Closes the wizard. */
|
|
580
|
+
close: string;
|
|
581
|
+
/** The escape hatch: heading, explanation, and the prompt to copy. */
|
|
582
|
+
stuckTitle: string;
|
|
583
|
+
stuckBody: string;
|
|
584
|
+
stuckPrompt: string;
|
|
585
|
+
copy: string;
|
|
586
|
+
copied: string;
|
|
587
|
+
}
|
|
588
|
+
interface SetupWizardProps {
|
|
589
|
+
/** In the order they are to be done. The caller owns that order. */
|
|
590
|
+
requirements: SetupRequirement[];
|
|
591
|
+
labels: SetupWizardLabels;
|
|
592
|
+
/** Re-reads the environment. Resolves when the answer has been applied. */
|
|
593
|
+
onCheck: () => Promise<void> | void;
|
|
594
|
+
/** Told when the reader closes it. */
|
|
595
|
+
onClose?: () => void;
|
|
596
|
+
}
|
|
597
|
+
declare function SetupWizard({ requirements, labels, onCheck, onClose }: SetupWizardProps): React.JSX.Element;
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Where a reader is in the setup, as one answer instead of a list to read.
|
|
601
|
+
*
|
|
602
|
+
* `SetupGuide` draws every requirement at once, which is the right shape for
|
|
603
|
+
* somebody checking a panel that already works. It is the wrong shape for
|
|
604
|
+
* somebody who has just installed one: five things at once, four of them
|
|
605
|
+
* missing, and no order to do them in reads as a wall rather than as a first
|
|
606
|
+
* step. So the same requirements are walked one at a time, and this is the
|
|
607
|
+
* function that decides which one.
|
|
608
|
+
*
|
|
609
|
+
* The order the caller gives is the order they are done in — a token that
|
|
610
|
+
* cannot be scoped before the repository is named is a step in the wrong
|
|
611
|
+
* place, and that is the caller's knowledge, not this function's.
|
|
612
|
+
*/
|
|
613
|
+
interface WizardStep {
|
|
614
|
+
/** The requirement to show, or null when nothing is left to do. */
|
|
615
|
+
current: SetupRequirement | null;
|
|
616
|
+
/** 1-based, for "step 2 of 5". Zero when there is nothing left. */
|
|
617
|
+
index: number;
|
|
618
|
+
/** How many steps this setup has in total. */
|
|
619
|
+
total: number;
|
|
620
|
+
/** Every requirement that is in place, in the caller's order. */
|
|
621
|
+
done: SetupRequirement[];
|
|
622
|
+
/** True when every requirement is `ok`. */
|
|
623
|
+
ready: boolean;
|
|
624
|
+
/**
|
|
625
|
+
* True when the panel could not ask the server, so nothing is claimed.
|
|
626
|
+
*
|
|
627
|
+
* This is not "not ready": a panel that cannot reach its own endpoint knows
|
|
628
|
+
* nothing about the environment, and telling somebody to add a token they
|
|
629
|
+
* already added is worse than saying the check itself failed.
|
|
630
|
+
*/
|
|
631
|
+
unknown: boolean;
|
|
632
|
+
}
|
|
633
|
+
declare function wizardStep(requirements: SetupRequirement[]): WizardStep;
|
|
634
|
+
/**
|
|
635
|
+
* Whether this panel has never been worked, which is what "first install"
|
|
636
|
+
* means here.
|
|
637
|
+
*
|
|
638
|
+
* `paneltir init` writes a board with the columns already there and nothing
|
|
639
|
+
* on them, so a board carrying no cards and no runs is one nobody has used
|
|
640
|
+
* yet. That is a better signal than a version on disk: a project can install
|
|
641
|
+
* the package, never open the panel, and update three times before anyone
|
|
642
|
+
* sees it — and it is still that reader's first run.
|
|
643
|
+
*
|
|
644
|
+
* A panel that has been worked and then loses a variable is deliberately not
|
|
645
|
+
* this. It needs the same instructions and gets them from the same wizard,
|
|
646
|
+
* but it is told rather than taken over: somebody mid-sentence on a board
|
|
647
|
+
* they know does not want a walkthrough opening on top of it.
|
|
648
|
+
*/
|
|
649
|
+
declare function isFirstRun(board: {
|
|
650
|
+
cards?: unknown[];
|
|
651
|
+
runs?: unknown[];
|
|
652
|
+
}): boolean;
|
|
653
|
+
|
|
520
654
|
type Handler = (payload: Record<string, string>, event: MouseEvent) => void;
|
|
521
655
|
/**
|
|
522
656
|
* A single click listener on document that dispatches by data-* attributes,
|
|
@@ -1035,6 +1169,27 @@ interface PanelTheme {
|
|
|
1035
1169
|
type PanelThemes = Record<string, PanelTheme>;
|
|
1036
1170
|
/** Every preset the kit ships, as a panel would offer them. */
|
|
1037
1171
|
declare const PRESET_PANEL_THEMES: PanelThemes;
|
|
1172
|
+
/**
|
|
1173
|
+
* The identities a panel actually offers, given what its caller asked for.
|
|
1174
|
+
*
|
|
1175
|
+
* `themes` is the exact set: these and nothing else. `extraThemes` adds to the
|
|
1176
|
+
* presets, which is what a project installing the panel nearly always means —
|
|
1177
|
+
* it has one identity of its own and no reason to lose the four the kit ships.
|
|
1178
|
+
*
|
|
1179
|
+
* The distinction exists because the absence of it cost two real installs. A
|
|
1180
|
+
* default parameter is replaced, not merged, so a project passing its own
|
|
1181
|
+
* theme as `themes` silently deleted every preset and its settings sheet
|
|
1182
|
+
* offered exactly one row. `INSTALL.md` led there — it said to derive the
|
|
1183
|
+
* project's palette and then listed `themes` as the prop for identities — so
|
|
1184
|
+
* the reader followed the instructions and the API was the thing that was
|
|
1185
|
+
* wrong.
|
|
1186
|
+
*
|
|
1187
|
+
* Extras come first, because `defaultTheme` falls back to the first key: a
|
|
1188
|
+
* panel should open in the project's own identity, not in a preset that
|
|
1189
|
+
* happens to sort ahead of it. A key that collides with a preset belongs to
|
|
1190
|
+
* the caller — they named it, so they meant it.
|
|
1191
|
+
*/
|
|
1192
|
+
declare function offeredThemes(themes?: PanelThemes, extraThemes?: PanelThemes): PanelThemes;
|
|
1038
1193
|
|
|
1039
1194
|
/**
|
|
1040
1195
|
* What the panel shows for the dfklabs catalogue, and the three ways to
|
|
@@ -1136,6 +1291,12 @@ interface UiStrings {
|
|
|
1136
1291
|
updateAsOrder: string;
|
|
1137
1292
|
updateAsOrderHow: string;
|
|
1138
1293
|
notifUpdate: string;
|
|
1294
|
+
releaseTitle: (version: string) => string;
|
|
1295
|
+
releaseDate: (date: string) => string;
|
|
1296
|
+
releaseShape: Record<'breaking' | 'feature' | 'fix' | 'chore', string>;
|
|
1297
|
+
releaseKind: Record<'breaking' | 'feature' | 'fix' | 'chore', string>;
|
|
1298
|
+
releaseClose: string;
|
|
1299
|
+
releaseNone: string;
|
|
1139
1300
|
updateCardTitle: (version: string) => string;
|
|
1140
1301
|
updateCardBody: (version: string) => string;
|
|
1141
1302
|
cardDetail: string;
|
|
@@ -1213,11 +1374,33 @@ interface UiStrings {
|
|
|
1213
1374
|
needTokenEnables: string;
|
|
1214
1375
|
needRepo: string;
|
|
1215
1376
|
needRepoEnables: string;
|
|
1377
|
+
needGate: string;
|
|
1378
|
+
needGateEnables: string;
|
|
1379
|
+
fixGate: string;
|
|
1216
1380
|
fixTokenCreate: string;
|
|
1217
1381
|
fixTokenScope: string;
|
|
1218
1382
|
fixTokenPaste: string;
|
|
1219
1383
|
fixTokenRedeploy: string;
|
|
1220
1384
|
fixRepo: string;
|
|
1385
|
+
wizardTitle: string;
|
|
1386
|
+
wizardProgress: (index: number, total: number) => string;
|
|
1387
|
+
wizardNowDo: string;
|
|
1388
|
+
wizardCheck: string;
|
|
1389
|
+
wizardChecking: string;
|
|
1390
|
+
wizardStillMissing: string;
|
|
1391
|
+
wizardCannotTell: string;
|
|
1392
|
+
wizardDoneTitle: string;
|
|
1393
|
+
wizardReadyTitle: string;
|
|
1394
|
+
wizardReadyBody: string;
|
|
1395
|
+
wizardVerify: string[];
|
|
1396
|
+
wizardClose: string;
|
|
1397
|
+
wizardStuckTitle: string;
|
|
1398
|
+
wizardStuckBody: string;
|
|
1399
|
+
wizardStuckPrompt: string;
|
|
1400
|
+
wizardCopy: string;
|
|
1401
|
+
wizardCopied: string;
|
|
1402
|
+
wizardOpen: string;
|
|
1403
|
+
wizardBanner: string;
|
|
1221
1404
|
demoTourWelcomeTitle: string;
|
|
1222
1405
|
demoTourWelcomeBody: string;
|
|
1223
1406
|
demoTourBoardTitle: string;
|
|
@@ -1292,6 +1475,10 @@ interface UiStrings {
|
|
|
1292
1475
|
suggestionStatuses: Record<'new' | 'doing' | 'done' | 'dismissed', string>;
|
|
1293
1476
|
analysisSections: Record<AnalysisSection, string>;
|
|
1294
1477
|
analysisSectionHints: Record<AnalysisSection, string>;
|
|
1478
|
+
analysisRedo: string;
|
|
1479
|
+
analysisRedoAsked: string;
|
|
1480
|
+
analysisRedoTitle: Record<AnalysisSection, string>;
|
|
1481
|
+
analysisRedoBody: Record<AnalysisSection, string>;
|
|
1295
1482
|
analysisAnswered: (answered: number, total: number) => string;
|
|
1296
1483
|
analysisAllDecided: string;
|
|
1297
1484
|
choicesTitle: string;
|
|
@@ -1400,13 +1587,41 @@ interface Capability {
|
|
|
1400
1587
|
}
|
|
1401
1588
|
declare const CAPABILITIES: Capability[];
|
|
1402
1589
|
|
|
1590
|
+
type ThemeChoice = string;
|
|
1403
1591
|
interface PanelAppProps {
|
|
1404
1592
|
state: PanelState;
|
|
1405
1593
|
/**
|
|
1406
|
-
* The identities the settings sheet offers
|
|
1407
|
-
*
|
|
1594
|
+
* The exact identities the settings sheet offers: these and nothing else.
|
|
1595
|
+
*
|
|
1596
|
+
* Almost nobody wants this. A project with one identity of its own wants
|
|
1597
|
+
* `extraThemes`, which adds to the presets instead of replacing them — this
|
|
1598
|
+
* prop silently deleted all four for two real installs, whose settings sheet
|
|
1599
|
+
* then offered a single row.
|
|
1408
1600
|
*/
|
|
1409
1601
|
themes?: PanelThemes;
|
|
1602
|
+
/**
|
|
1603
|
+
* Identities of the caller's own, offered *alongside* the kit's presets.
|
|
1604
|
+
*
|
|
1605
|
+
* This is what a project installing the panel means. They come first, so the
|
|
1606
|
+
* panel opens in the project's identity rather than in a preset; a key that
|
|
1607
|
+
* collides with a preset replaces it, because the caller named it.
|
|
1608
|
+
*/
|
|
1609
|
+
extraThemes?: PanelThemes;
|
|
1610
|
+
/**
|
|
1611
|
+
* `.paneltir/gate.json` from this project, if the caller imports it.
|
|
1612
|
+
*
|
|
1613
|
+
* The gate is copied once and then belongs to the project, which means it is
|
|
1614
|
+
* the one part of this package that can never be told it is old — and that
|
|
1615
|
+
* has cost two releases already. Handing the stamp in lets the panel say so,
|
|
1616
|
+
* with no filesystem and no network, because both halves of the comparison
|
|
1617
|
+
* are already data: the stamp from the project and `templateHash` from the
|
|
1618
|
+
* installed package.
|
|
1619
|
+
*
|
|
1620
|
+
* Omitted, the panel says nothing about the gate rather than guessing. This
|
|
1621
|
+
* is a prop and not a fetch for the reason the Tools screen is a prop in the
|
|
1622
|
+
* demo: the kit does not decide what a caller's server can be asked.
|
|
1623
|
+
*/
|
|
1624
|
+
gate?: unknown;
|
|
1410
1625
|
/** Which one to draw before the board has said. Defaults to the first. */
|
|
1411
1626
|
defaultTheme?: string;
|
|
1412
1627
|
/**
|
|
@@ -1417,8 +1632,16 @@ interface PanelAppProps {
|
|
|
1417
1632
|
* business drawing anybody's mark, including its own.
|
|
1418
1633
|
*/
|
|
1419
1634
|
brand?: React.ReactNode;
|
|
1420
|
-
/**
|
|
1421
|
-
|
|
1635
|
+
/**
|
|
1636
|
+
* Rendered inside the theme provider, behind everything: a caller's screen
|
|
1637
|
+
* effects.
|
|
1638
|
+
*
|
|
1639
|
+
* It may be a function of the theme in force, because a decoration usually
|
|
1640
|
+
* belongs to one theme rather than to the panel. This project's scanlines
|
|
1641
|
+
* are Night City's and were drawn over every other theme until this existed
|
|
1642
|
+
* — a palette swapped underneath an effect that did not move with it.
|
|
1643
|
+
*/
|
|
1644
|
+
decoration?: React.ReactNode | ((theme: ThemeChoice) => React.ReactNode);
|
|
1422
1645
|
/** Put on the theme root, so a caller's stylesheet has something to hang on. */
|
|
1423
1646
|
className?: string;
|
|
1424
1647
|
/** Rendered under the panel. A caller's footer, or nothing. */
|
|
@@ -1465,7 +1688,94 @@ interface PanelAppProps {
|
|
|
1465
1688
|
fileCount: number;
|
|
1466
1689
|
};
|
|
1467
1690
|
}
|
|
1468
|
-
declare function PanelApp({ state: initialState, themes, defaultTheme, brand, decoration, className, footer, links, capabilities, extras, showLanguage, showHistory, checkForUpdates, saveEndpoint, marketplaceEndpoint, marketplaceReport, fingerprint, }: PanelAppProps): React.JSX.Element;
|
|
1691
|
+
declare function PanelApp({ state: initialState, themes: exactThemes, extraThemes, gate, defaultTheme, brand, decoration, className, footer, links, capabilities, extras, showLanguage, showHistory, checkForUpdates, saveEndpoint, marketplaceEndpoint, marketplaceReport, fingerprint, }: PanelAppProps): React.JSX.Element;
|
|
1692
|
+
|
|
1693
|
+
/**
|
|
1694
|
+
* Whether the gate a project is running is the gate this version ships.
|
|
1695
|
+
*
|
|
1696
|
+
* `template/` is the one thing here that leaves as *files a project keeps*.
|
|
1697
|
+
* The components arrive in `node_modules` and are replaced on every update;
|
|
1698
|
+
* the gate is copied once by `init` and is then that project's own — which is
|
|
1699
|
+
* the point, since it holds their password rule and points at their
|
|
1700
|
+
* repository, and a front door that moves when a library updates is not a
|
|
1701
|
+
* front door.
|
|
1702
|
+
*
|
|
1703
|
+
* The cost of that is a copy that can never be told it is old. It has already
|
|
1704
|
+
* been paid twice. The `HTTP 500` fix landed in `template/api/panel-state.ts`,
|
|
1705
|
+
* so every project installed before it still has a save that cannot work, and
|
|
1706
|
+
* nothing anywhere says so; `.claude/skills/panel/SKILL.md` is copied the same
|
|
1707
|
+
* way, so a rule learned upstream never reaches the Claude that reads it.
|
|
1708
|
+
* Upstream the copy is held honest by `test:auth` and `test:board`. Downstream
|
|
1709
|
+
* there was nothing at all.
|
|
1710
|
+
*
|
|
1711
|
+
* So `init` records what it copied and what it copied it from, and this says
|
|
1712
|
+
* what that record means. Two rules shape it:
|
|
1713
|
+
*
|
|
1714
|
+
* - **It compares hashes, not version numbers.** Most releases do not touch
|
|
1715
|
+
* `template/`, so "you are on 0.6.0 and 0.9.0 exists" would cry wolf for
|
|
1716
|
+
* every release and be ignored by the one that mattered. `templateHash`
|
|
1717
|
+
* ships inside `fingerprint.json`, so the comparison is exact.
|
|
1718
|
+
* - **It needs no filesystem and no network**, because the panel runs in a
|
|
1719
|
+
* browser and has neither. Everything it judges is data the caller already
|
|
1720
|
+
* holds: the stamp from the project, the hash from the installed package.
|
|
1721
|
+
*
|
|
1722
|
+
* It reports and never repairs. Replacing somebody's gate is `init --force`,
|
|
1723
|
+
* typed by a person who has read what changed.
|
|
1724
|
+
*/
|
|
1725
|
+
/**
|
|
1726
|
+
* What `init` wrote, and what it wrote it from.
|
|
1727
|
+
*
|
|
1728
|
+
* Lives at `.paneltir/gate.json` in the project. It is not a lockfile and
|
|
1729
|
+
* nothing resolves against it — it exists so a later session can tell "you
|
|
1730
|
+
* edited this" from "we changed this underneath you", which is the distinction
|
|
1731
|
+
* a bare diff cannot make.
|
|
1732
|
+
*/
|
|
1733
|
+
interface GateStamp {
|
|
1734
|
+
/** The kit version that copied these files. */
|
|
1735
|
+
version: string;
|
|
1736
|
+
/** `templateHash` from that version's `fingerprint.json`. */
|
|
1737
|
+
templateHash: string;
|
|
1738
|
+
/** When, so a reader can date it against their own git history. */
|
|
1739
|
+
copiedAt: string;
|
|
1740
|
+
/**
|
|
1741
|
+
* SHA-256 of each file as written, keyed by its path in the project.
|
|
1742
|
+
*
|
|
1743
|
+
* This is what separates a file the project edited from one the template
|
|
1744
|
+
* moved under. Absent for a file `init` left alone: we did not write it, so
|
|
1745
|
+
* we cannot claim to know where it came from.
|
|
1746
|
+
*/
|
|
1747
|
+
files: Record<string, string>;
|
|
1748
|
+
}
|
|
1749
|
+
type GateVerdict =
|
|
1750
|
+
/** The gate is the one this version ships. */
|
|
1751
|
+
'current'
|
|
1752
|
+
/** `template/` has changed since this gate was copied. */
|
|
1753
|
+
| 'behind'
|
|
1754
|
+
/**
|
|
1755
|
+
* No stamp. Every project installed before stamping existed is here, and it
|
|
1756
|
+
* is not a fault — it is the absence of an answer, which is why it is not
|
|
1757
|
+
* called one. `paneltir doctor` can still compare the files themselves.
|
|
1758
|
+
*/
|
|
1759
|
+
| 'unstamped';
|
|
1760
|
+
interface GateReading {
|
|
1761
|
+
verdict: GateVerdict;
|
|
1762
|
+
/** The version that copied the gate, when a stamp says so. */
|
|
1763
|
+
copiedFrom?: string;
|
|
1764
|
+
/** The version running now. */
|
|
1765
|
+
installed: string;
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* Reads a stamp against the installed package.
|
|
1769
|
+
*
|
|
1770
|
+
* Deliberately total: a malformed or absent stamp answers `unstamped` rather
|
|
1771
|
+
* than throwing. This is called while a panel is drawing, and a panel that
|
|
1772
|
+
* fails to open because it could not classify its own gate would be a worse
|
|
1773
|
+
* outcome than the drift it was looking for.
|
|
1774
|
+
*/
|
|
1775
|
+
declare function gateStatus(stamp: unknown, installed: {
|
|
1776
|
+
version: string;
|
|
1777
|
+
templateHash?: string;
|
|
1778
|
+
}): GateReading;
|
|
1469
1779
|
|
|
1470
1780
|
/**
|
|
1471
1781
|
* Applies a board move to the flat card list.
|
|
@@ -1490,8 +1800,16 @@ interface AnalysisViewProps {
|
|
|
1490
1800
|
onDecide: (section: AnalysisSection, choiceId: string, optionId: string | null) => void;
|
|
1491
1801
|
/** Opening the card a fact is about, so a number is never a dead end. */
|
|
1492
1802
|
onOpenCard?: (id: string) => void;
|
|
1803
|
+
/**
|
|
1804
|
+
* Asks for this screen's analysis to be worked again.
|
|
1805
|
+
*
|
|
1806
|
+
* The panel cannot run Claude, so it writes a card and says so. A button
|
|
1807
|
+
* that appeared to fetch a report and did not would be the exact fault the
|
|
1808
|
+
* derived theme's refresh already avoids. Omit it and no button is drawn.
|
|
1809
|
+
*/
|
|
1810
|
+
onRequestReport?: (section: AnalysisSection) => void;
|
|
1493
1811
|
}
|
|
1494
|
-
declare function AnalysisView({ analysis, cards, columns, today, lang, ui, onChooseStrategy, onSuggestionStatus, onDecide, onOpenCard, }: AnalysisViewProps): React.JSX.Element;
|
|
1812
|
+
declare function AnalysisView({ analysis, cards, columns, today, lang, ui, onChooseStrategy, onSuggestionStatus, onDecide, onOpenCard, onRequestReport, }: AnalysisViewProps): React.JSX.Element;
|
|
1495
1813
|
|
|
1496
1814
|
interface MarketplaceViewProps {
|
|
1497
1815
|
/** Null while the catalogue is still being asked for. */
|
|
@@ -1517,4 +1835,4 @@ interface CardSheetProps {
|
|
|
1517
1835
|
}
|
|
1518
1836
|
declare function CardSheet({ card, state, lang, ui, onChange, onDelete, onClose }: CardSheetProps): React.JSX.Element | null;
|
|
1519
1837
|
|
|
1520
|
-
export { ANALYSIS_SECTIONS, AlertBanner, type AlertBannerProps, type Analysis, type AnalysisSection, AnalysisView, BOARD_VERSION, Board, type BoardCardData, type BoardCheck, type BoardColumnData, type BoardFacts, type BoardMoveResult, type BoardProblem, type BoardProps, type BoardTag, CAPABILITIES, type Capability, Card$1 as Card, type CardProps, CardSheet, type Check, type Choice, type ChoiceOption, type ColumnDef, type Competitor, type Constraint, CopyBlock, type CopyBlockLabels, type CopyBlockProps, type Counts, DashboardHeader, type DashboardHeaderProps, type DashboardThemeForm, DashboardThemeProvider, type DashboardThemeTokens, DetailSection, type DetailSectionProps, DetailSheet, type DetailSheetProps, FilterChip, type FilterChipProps, FilterChipRow, type Goal, GuideNote, type GuideNoteProps, GuideTour, type GuideTourProps, type HealthFact, HealthPill, type HealthPillProps, HealthPillRow, type HealthStatus, INTENTS, INTENT_COPY, type ImportedTheme, type InstallState, type Intent, type IntentCopy, LANGS, LANG_LABELS, LEVELS, type Lang, type Level, MARKETPLACE_NAME, MARKETPLACE_URL, type Market, type MarketplaceReport, type MarketplaceTool, MarketplaceView, type Metric, type Note, NotificationBell, type NotificationBellProps, type NotificationLabels, type NotificationTone, OWNERS, type Owner, PANELTIR_FILE_COUNT, PANELTIR_FINGERPRINT, PANELTIR_VERSION, PRESET_PANEL_THEMES, PanelApp, type PanelAppProps, type Card as PanelCard, type PanelNotification, type PanelState, type PanelTheme, type PanelThemes, type Preferences, type Reading, type Run, SetupGuide, type SetupGuideProps, type SetupRequirement, type SetupStatus, type Severity, StatTile, StatTileGrid, type StatTileProps, type Strategy, type Suggestion, type SuggestionStatus, THEME_FORMS, THEME_PRESETS, type Text, type ThemeFormName, type ThemePresetName, type Trend, UI, type UiStrings, type Weight, applyMove, boardFacts, checkProgress, claimedWithoutStarting, claudeTheme, commandSnippet, countCards, cyberpunkTheme, decided, emptyCard, explainBoard, isCard, ledgerForm, midnightTheme, moveCardInColumns, newId, oldMoneyTheme, panelForm, paneltirBuild, paperForm, readBoard, readStoredLang, repositorySnippet, resetGuide, sparkPoints, stampForColumn, storeLang, text, today, trendOf, undecided, untranslated, useDashboardForm, useDashboardTheme, useDelegatedClick, useGuideNote, useMediaQuery, validateBoard, writeText };
|
|
1838
|
+
export { ANALYSIS_SECTIONS, AlertBanner, type AlertBannerProps, type Analysis, type AnalysisSection, AnalysisView, BOARD_VERSION, Board, type BoardCardData, type BoardCheck, type BoardColumnData, type BoardFacts, type BoardMoveResult, type BoardProblem, type BoardProps, type BoardTag, CAPABILITIES, type Capability, Card$1 as Card, type CardProps, CardSheet, type Check, type Choice, type ChoiceOption, type ColumnDef, type Competitor, type Constraint, CopyBlock, type CopyBlockLabels, type CopyBlockProps, type Counts, DashboardHeader, type DashboardHeaderProps, type DashboardThemeForm, DashboardThemeProvider, type DashboardThemeTokens, DetailSection, type DetailSectionProps, DetailSheet, type DetailSheetProps, FilterChip, type FilterChipProps, FilterChipRow, type GateReading, type GateStamp, type GateVerdict, type Goal, GuideNote, type GuideNoteProps, GuideTour, type GuideTourProps, type HealthFact, HealthPill, type HealthPillProps, HealthPillRow, type HealthStatus, INTENTS, INTENT_COPY, type ImportedTheme, type InstallState, type Intent, type IntentCopy, LANGS, LANG_LABELS, LEVELS, type Lang, type Level, MARKETPLACE_NAME, MARKETPLACE_URL, type Market, type MarketplaceReport, type MarketplaceTool, MarketplaceView, type Metric, type Note, NotificationBell, type NotificationBellProps, type NotificationLabels, type NotificationTone, OWNERS, type Owner, PANELTIR_FILE_COUNT, PANELTIR_FINGERPRINT, PANELTIR_TEMPLATE_HASH, PANELTIR_VERSION, PRESET_PANEL_THEMES, PanelApp, type PanelAppProps, type Card as PanelCard, type PanelNotification, type PanelState, type PanelTheme, type PanelThemes, type Preferences, type Reading, type Run, SetupGuide, type SetupGuideProps, type SetupRequirement, type SetupStatus, SetupWizard, type SetupWizardLabels, type SetupWizardProps, type Severity, StatTile, StatTileGrid, type StatTileProps, type Strategy, type Suggestion, type SuggestionStatus, THEME_FORMS, THEME_PRESETS, type Text, type ThemeFormName, type ThemePresetName, type Trend, UI, type UiStrings, type Weight, type WizardStep, applyMove, boardFacts, checkProgress, claimedWithoutStarting, claudeTheme, commandSnippet, countCards, cyberpunkTheme, decided, emptyCard, explainBoard, gateStatus, isCard, isFirstRun, ledgerForm, midnightTheme, moveCardInColumns, newId, offeredThemes, oldMoneyTheme, panelForm, paneltirBuild, paperForm, readBoard, readStoredLang, repositorySnippet, resetGuide, sparkPoints, stampForColumn, storeLang, text, today, trendOf, undecided, untranslated, useDashboardForm, useDashboardTheme, useDelegatedClick, useGuideNote, useMediaQuery, validateBoard, wizardStep, writeText };
|