@arbidocs/blocks 0.5.65 → 0.5.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/{ConnectedCallDock-GJAGY75U.cjs → ConnectedCallDock-FFIDDYGH.cjs} +6 -6
- package/dist/{ConnectedCallDock-GJAGY75U.cjs.map → ConnectedCallDock-FFIDDYGH.cjs.map} +1 -1
- package/dist/{ConnectedCallDock-DEAEFUUD.js → ConnectedCallDock-VMEBH4LG.js} +6 -6
- package/dist/{ConnectedCallDock-DEAEFUUD.js.map → ConnectedCallDock-VMEBH4LG.js.map} +1 -1
- package/dist/{ConnectedCallRoom-DI7UYRHE.js → ConnectedCallRoom-2FNSX2VG.js} +6 -6
- package/dist/{ConnectedCallRoom-DI7UYRHE.js.map → ConnectedCallRoom-2FNSX2VG.js.map} +1 -1
- package/dist/{ConnectedCallRoom-KLE2PCMQ.cjs → ConnectedCallRoom-HYRLJUIV.cjs} +6 -6
- package/dist/{ConnectedCallRoom-KLE2PCMQ.cjs.map → ConnectedCallRoom-HYRLJUIV.cjs.map} +1 -1
- package/dist/{ConnectedDocumentViewer-YSZWOVGN.cjs → ConnectedDocumentViewer-IQHDCAZ5.cjs} +12 -12
- package/dist/{ConnectedDocumentViewer-YSZWOVGN.cjs.map → ConnectedDocumentViewer-IQHDCAZ5.cjs.map} +1 -1
- package/dist/{ConnectedDocumentViewer-HKIBNGGG.js → ConnectedDocumentViewer-NIZBKBJN.js} +11 -11
- package/dist/{ConnectedDocumentViewer-HKIBNGGG.js.map → ConnectedDocumentViewer-NIZBKBJN.js.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-PSAP3Q7D.js → ConnectedNativeDocxComparison-FPW3BNBN.js} +6 -6
- package/dist/ConnectedNativeDocxComparison-FPW3BNBN.js.map +1 -0
- package/dist/{ConnectedNativeDocxComparison-L3R3ROPZ.cjs → ConnectedNativeDocxComparison-HJ4FTVH6.cjs} +7 -7
- package/dist/ConnectedNativeDocxComparison-HJ4FTVH6.cjs.map +1 -0
- package/dist/{ConnectedNativeDocxEditor-VDBC4XRT.cjs → ConnectedNativeDocxEditor-PF46MU5H.cjs} +7 -7
- package/dist/ConnectedNativeDocxEditor-PF46MU5H.cjs.map +1 -0
- package/dist/{ConnectedNativeDocxEditor-PI6QTPXZ.js → ConnectedNativeDocxEditor-S7NJMDSU.js} +5 -5
- package/dist/ConnectedNativeDocxEditor-S7NJMDSU.js.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-V4MTKVNE.js → ConnectedStreamedWordArtifact-5MHLV24V.js} +6 -6
- package/dist/ConnectedStreamedWordArtifact-5MHLV24V.js.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-YSW6D7AG.cjs → ConnectedStreamedWordArtifact-LNGW7YGV.cjs} +7 -7
- package/dist/ConnectedStreamedWordArtifact-LNGW7YGV.cjs.map +1 -0
- package/dist/{DocumentReviewCard-TQQADJ36.js → DocumentReviewCard-5U3TGJZA.js} +6 -6
- package/dist/{DocumentReviewCard-TQQADJ36.js.map → DocumentReviewCard-5U3TGJZA.js.map} +1 -1
- package/dist/{DocumentReviewCard-BQ6ZD5MD.cjs → DocumentReviewCard-VFNMJSK7.cjs} +6 -6
- package/dist/{DocumentReviewCard-BQ6ZD5MD.cjs.map → DocumentReviewCard-VFNMJSK7.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-GKMVTECZ.cjs → WorkspaceTableView-DHMCJRC6.cjs} +6 -6
- package/dist/{WorkspaceTableView-GKMVTECZ.cjs.map → WorkspaceTableView-DHMCJRC6.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-YFLVFRJL.js → WorkspaceTableView-EH5CEB44.js} +4 -4
- package/dist/{WorkspaceTableView-YFLVFRJL.js.map → WorkspaceTableView-EH5CEB44.js.map} +1 -1
- package/dist/agents/index.cjs +283 -283
- package/dist/agents/index.js +5 -5
- package/dist/calls/index.cjs +2 -2
- package/dist/calls/index.js +2 -2
- package/dist/chat/index.cjs +57 -57
- package/dist/chat/index.js +4 -4
- package/dist/{chunk-D27BBGUF.cjs → chunk-23ACBETH.cjs} +4 -4
- package/dist/{chunk-D27BBGUF.cjs.map → chunk-23ACBETH.cjs.map} +1 -1
- package/dist/{chunk-4CI42DCG.js → chunk-323R76RZ.js} +50 -5
- package/dist/chunk-323R76RZ.js.map +1 -0
- package/dist/{chunk-DJE2E7YH.cjs → chunk-3VFQYKB5.cjs} +3 -3
- package/dist/{chunk-DJE2E7YH.cjs.map → chunk-3VFQYKB5.cjs.map} +1 -1
- package/dist/{chunk-JSHBC47B.cjs → chunk-45Y7ASBC.cjs} +53 -47
- package/dist/chunk-45Y7ASBC.cjs.map +1 -0
- package/dist/{chunk-TVHTXO6V.cjs → chunk-56WWEK6I.cjs} +4 -4
- package/dist/{chunk-TVHTXO6V.cjs.map → chunk-56WWEK6I.cjs.map} +1 -1
- package/dist/{chunk-CGCTODPC.cjs → chunk-6PGTH2HD.cjs} +4 -4
- package/dist/{chunk-CGCTODPC.cjs.map → chunk-6PGTH2HD.cjs.map} +1 -1
- package/dist/{chunk-PBIFISDD.js → chunk-7P24MJQN.js} +3 -3
- package/dist/{chunk-PBIFISDD.js.map → chunk-7P24MJQN.js.map} +1 -1
- package/dist/{chunk-6QZ35CTZ.js → chunk-AD76WTGR.js} +3 -3
- package/dist/{chunk-6QZ35CTZ.js.map → chunk-AD76WTGR.js.map} +1 -1
- package/dist/{chunk-ROWJU4SK.cjs → chunk-AKGV6JUC.cjs} +12 -128
- package/dist/chunk-AKGV6JUC.cjs.map +1 -0
- package/dist/{chunk-UIUWCTIZ.js → chunk-APXW5XGA.js} +165 -4
- package/dist/chunk-APXW5XGA.js.map +1 -0
- package/dist/{chunk-SEVFIBF3.cjs → chunk-BFIHXDO6.cjs} +4 -4
- package/dist/{chunk-SEVFIBF3.cjs.map → chunk-BFIHXDO6.cjs.map} +1 -1
- package/dist/{chunk-6OMIIF76.js → chunk-BWWND4Y7.js} +3 -3
- package/dist/{chunk-6OMIIF76.js.map → chunk-BWWND4Y7.js.map} +1 -1
- package/dist/{chunk-EG3BB32W.cjs → chunk-CCSF7RI4.cjs} +3 -3
- package/dist/{chunk-EG3BB32W.cjs.map → chunk-CCSF7RI4.cjs.map} +1 -1
- package/dist/{chunk-QK546T4C.cjs → chunk-CKNUL4LM.cjs} +3 -3
- package/dist/{chunk-QK546T4C.cjs.map → chunk-CKNUL4LM.cjs.map} +1 -1
- package/dist/{chunk-TJ7QEGVP.cjs → chunk-COZDIUG7.cjs} +18 -18
- package/dist/{chunk-TJ7QEGVP.cjs.map → chunk-COZDIUG7.cjs.map} +1 -1
- package/dist/{chunk-YQEXBJVO.js → chunk-DF5X27QX.js} +42 -5
- package/dist/chunk-DF5X27QX.js.map +1 -0
- package/dist/{chunk-B3CRSCLK.cjs → chunk-EOIJ5JYP.cjs} +4 -4
- package/dist/{chunk-B3CRSCLK.cjs.map → chunk-EOIJ5JYP.cjs.map} +1 -1
- package/dist/{chunk-GPYLXEZO.js → chunk-FCOK73I3.js} +6 -120
- package/dist/chunk-FCOK73I3.js.map +1 -0
- package/dist/{chunk-CJF7B5A7.cjs → chunk-FHXXDPNU.cjs} +12 -12
- package/dist/{chunk-CJF7B5A7.cjs.map → chunk-FHXXDPNU.cjs.map} +1 -1
- package/dist/{chunk-ITRI47DF.cjs → chunk-GMGEAWFX.cjs} +41 -4
- package/dist/chunk-GMGEAWFX.cjs.map +1 -0
- package/dist/{chunk-LNH6NYG4.js → chunk-I3VBVP6R.js} +121 -6
- package/dist/chunk-I3VBVP6R.js.map +1 -0
- package/dist/{chunk-ZZHMJXM5.cjs → chunk-IXZCXK6Q.cjs} +122 -5
- package/dist/chunk-IXZCXK6Q.cjs.map +1 -0
- package/dist/{chunk-SBAM3UZX.js → chunk-JWRTUYLC.js} +3 -3
- package/dist/{chunk-SBAM3UZX.js.map → chunk-JWRTUYLC.js.map} +1 -1
- package/dist/{chunk-PLEMVK2W.js → chunk-KQLUMK56.js} +3 -3
- package/dist/{chunk-PLEMVK2W.js.map → chunk-KQLUMK56.js.map} +1 -1
- package/dist/{chunk-PNZVUH46.cjs → chunk-LAQ3Y5JP.cjs} +6 -6
- package/dist/{chunk-PNZVUH46.cjs.map → chunk-LAQ3Y5JP.cjs.map} +1 -1
- package/dist/{chunk-AESJLGMC.cjs → chunk-LEW4GUFW.cjs} +7 -7
- package/dist/{chunk-AESJLGMC.cjs.map → chunk-LEW4GUFW.cjs.map} +1 -1
- package/dist/{chunk-2LUA7UDE.js → chunk-NDVLCOWS.js} +7 -7
- package/dist/{chunk-2LUA7UDE.js.map → chunk-NDVLCOWS.js.map} +1 -1
- package/dist/{chunk-43IVRSFX.js → chunk-NVXNTHL4.js} +3 -3
- package/dist/{chunk-43IVRSFX.js.map → chunk-NVXNTHL4.js.map} +1 -1
- package/dist/{chunk-IRXPUQFP.js → chunk-OZL5ABLF.js} +3 -3
- package/dist/{chunk-IRXPUQFP.js.map → chunk-OZL5ABLF.js.map} +1 -1
- package/dist/{chunk-5EGTGHBW.js → chunk-PGKZBAJB.js} +12 -6
- package/dist/chunk-PGKZBAJB.js.map +1 -0
- package/dist/{chunk-KNOSLLTC.js → chunk-PKDPQS6Z.js} +3 -3
- package/dist/{chunk-KNOSLLTC.js.map → chunk-PKDPQS6Z.js.map} +1 -1
- package/dist/{chunk-VWM3J6ES.js → chunk-PVPGD6QR.js} +3 -3
- package/dist/{chunk-VWM3J6ES.js.map → chunk-PVPGD6QR.js.map} +1 -1
- package/dist/{chunk-C2S246BV.js → chunk-RAGITH2N.js} +4 -4
- package/dist/{chunk-C2S246BV.js.map → chunk-RAGITH2N.js.map} +1 -1
- package/dist/{chunk-4Q7ON335.js → chunk-RFKAE6WS.js} +5 -5
- package/dist/{chunk-4Q7ON335.js.map → chunk-RFKAE6WS.js.map} +1 -1
- package/dist/{chunk-2C4YUIVX.js → chunk-T2VGD4X6.js} +3 -3
- package/dist/{chunk-2C4YUIVX.js.map → chunk-T2VGD4X6.js.map} +1 -1
- package/dist/{chunk-CEKOZAGO.js → chunk-TAI23FCY.js} +3 -3
- package/dist/{chunk-CEKOZAGO.js.map → chunk-TAI23FCY.js.map} +1 -1
- package/dist/{chunk-WBLCPCWR.cjs → chunk-UDMII47W.cjs} +7 -7
- package/dist/{chunk-WBLCPCWR.cjs.map → chunk-UDMII47W.cjs.map} +1 -1
- package/dist/{chunk-SFTQO3TU.js → chunk-UO3FS6ZF.js} +3 -3
- package/dist/{chunk-SFTQO3TU.js.map → chunk-UO3FS6ZF.js.map} +1 -1
- package/dist/{chunk-BELZ2WD2.js → chunk-W5D5GFP2.js} +3 -3
- package/dist/{chunk-BELZ2WD2.js.map → chunk-W5D5GFP2.js.map} +1 -1
- package/dist/{chunk-LFS6UWSJ.cjs → chunk-XWUGPV7H.cjs} +5 -5
- package/dist/{chunk-LFS6UWSJ.cjs.map → chunk-XWUGPV7H.cjs.map} +1 -1
- package/dist/{chunk-K26RLK2Y.cjs → chunk-Y6ZNWC7E.cjs} +3 -3
- package/dist/{chunk-K26RLK2Y.cjs.map → chunk-Y6ZNWC7E.cjs.map} +1 -1
- package/dist/{chunk-F777MGVA.cjs → chunk-YBVBDVQX.cjs} +18 -18
- package/dist/{chunk-F777MGVA.cjs.map → chunk-YBVBDVQX.cjs.map} +1 -1
- package/dist/{chunk-OM5IVNEW.cjs → chunk-Z4KXF7WS.cjs} +165 -2
- package/dist/chunk-Z4KXF7WS.cjs.map +1 -0
- package/dist/{chunk-7MOQO6NO.cjs → chunk-ZIQGSFHG.cjs} +53 -5
- package/dist/chunk-ZIQGSFHG.cjs.map +1 -0
- package/dist/connect/docx.cjs +11 -11
- package/dist/connect/docx.js +7 -7
- package/dist/connect/index.cjs +1723 -1149
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.ts +3 -0
- package/dist/connect/index.js +1191 -633
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/viewer.cjs +10 -10
- package/dist/connect/viewer.js +9 -9
- package/dist/connection/billing/index.d.ts +1 -0
- package/dist/connection/billing/payment-required.d.ts +45 -0
- package/dist/connection/runtime/ConnectedAppRuntime.d.ts +1 -1
- package/dist/connection/runtime/index.d.ts +1 -1
- package/dist/connection/runtime/requests.d.ts +8 -0
- package/dist/connection/runtime/useWelcomeDialog.d.ts +3 -0
- package/dist/connection/settings-page/ConnectedModelConnectionsSettings.d.ts +1 -0
- package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +3 -0
- package/dist/connection/settings-page/index.d.ts +2 -1
- package/dist/connection/tips/ConnectedGettingStarted.d.ts +20 -0
- package/dist/connection/tips/ConnectedTipBar.d.ts +49 -0
- package/dist/connection/tips/useGettingStarted.d.ts +51 -0
- package/dist/connection/workflows/useWorkflowsPageState.d.ts +1 -1
- package/dist/dashboards/index.cjs +1 -1
- package/dist/dashboards/index.js +1 -1
- package/dist/document-tools/index.cjs +17 -17
- package/dist/document-tools/index.js +2 -2
- package/dist/embed/index.cjs +9 -9
- package/dist/embed/index.js +6 -6
- package/dist/facts/index.cjs +1 -1
- package/dist/facts/index.js +1 -1
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/home/index.cjs +23 -178
- package/dist/home/index.cjs.map +1 -1
- package/dist/home/index.js +3 -164
- package/dist/home/index.js.map +1 -1
- package/dist/index.cjs +606 -634
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +23 -62
- package/dist/index.js.map +1 -1
- package/dist/shell/index.cjs +73 -73
- package/dist/shell/index.js +4 -4
- package/dist/site/index.cjs +17 -17
- package/dist/site/index.js +1 -1
- package/dist/studio/index.cjs +10 -10
- package/dist/studio/index.js +7 -7
- package/dist/tips/index.d.ts +1 -1
- package/dist/tips/visibility.d.ts +7 -0
- package/dist/workflow-canvas/index.cjs +27 -27
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +12 -12
- package/dist/workflow-canvas/index.js.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ConnectedNativeDocxComparison-L3R3ROPZ.cjs.map +0 -1
- package/dist/ConnectedNativeDocxComparison-PSAP3Q7D.js.map +0 -1
- package/dist/ConnectedNativeDocxEditor-PI6QTPXZ.js.map +0 -1
- package/dist/ConnectedNativeDocxEditor-VDBC4XRT.cjs.map +0 -1
- package/dist/ConnectedStreamedWordArtifact-V4MTKVNE.js.map +0 -1
- package/dist/ConnectedStreamedWordArtifact-YSW6D7AG.cjs.map +0 -1
- package/dist/chunk-4CI42DCG.js.map +0 -1
- package/dist/chunk-5EGTGHBW.js.map +0 -1
- package/dist/chunk-7MOQO6NO.cjs.map +0 -1
- package/dist/chunk-GPYLXEZO.js.map +0 -1
- package/dist/chunk-ITRI47DF.cjs.map +0 -1
- package/dist/chunk-JSHBC47B.cjs.map +0 -1
- package/dist/chunk-LNH6NYG4.js.map +0 -1
- package/dist/chunk-OM5IVNEW.cjs.map +0 -1
- package/dist/chunk-ROWJU4SK.cjs.map +0 -1
- package/dist/chunk-UIUWCTIZ.js.map +0 -1
- package/dist/chunk-YQEXBJVO.js.map +0 -1
- package/dist/chunk-ZZHMJXM5.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/home/HomeLayout.tsx","../src/home/CreateTile.tsx","../src/home/DashboardParts.tsx","../src/home/FactsStrip.tsx","../src/home/RecentList.tsx","../src/home/GettingStartedStrip.tsx"],"names":["cn","jsx","jsxs"],"mappings":"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","file":"chunk-APXW5XGA.js","sourcesContent":["import type { ReactNode } from 'react'\nimport { cn } from '@arbidocs/react/ui'\nimport { Callout } from '../components/Callout'\n\n/** Column of the home page: greeting header, then the content. */\nexport function HomeFrame({\n testId = 'home-page',\n children,\n}: {\n testId?: string\n children: ReactNode\n}) {\n return (\n <div data-slot=\"home-frame\" data-testid={testId} className=\"flex h-full flex-col\">\n {children}\n </div>\n )\n}\n\n/** Content area under the header; the pages inside own their scrolling. */\nexport function HomeMain({ children }: { children: ReactNode }) {\n return (\n <main\n data-slot=\"home-main\"\n className=\"min-h-0 min-w-sidebar flex-1 overflow-hidden bg-background\"\n >\n {children}\n </main>\n )\n}\n\n/**\n * Scroll container that spans the full width (so its scrollbar rides the window edge) with the\n * content centred in a bounded column.\n */\nexport function HomeCenteredScroll({ children }: { children: ReactNode }) {\n return (\n <div data-slot=\"home-scroll\" className=\"h-full overflow-y-auto\">\n <div className=\"mx-auto max-w-6xl\">{children}</div>\n </div>\n )\n}\n\n/** Bounded, centred column for a full-height child (the workspaces table). */\nexport function HomeCenteredColumn({\n className,\n children,\n}: {\n className?: string\n children: ReactNode\n}) {\n return (\n <div\n data-slot=\"home-column\"\n className={cn('mx-auto h-full max-w-6xl px-4 pb-4 sm:px-8', className)}\n >\n {children}\n </div>\n )\n}\n\n/** Centred error notice for a page that could not load. */\nexport function HomeLoadError({\n title,\n body,\n testId,\n}: {\n title: string\n body: string\n testId?: string\n}) {\n return (\n <div\n data-slot=\"home-load-error\"\n className=\"flex h-full flex-col items-center justify-center p-8\"\n >\n <div className=\"w-full max-w-md\">\n <Callout variant=\"danger\" title={title} body={body} testId={testId} />\n </div>\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { Plus } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\n\nexport interface CreateTileProps {\n /** Visible label, e.g. \"New workspace\". */\n label: string\n /** Accessible name; defaults to `label`. */\n ariaLabel?: string\n onSelect?: () => void\n /** One line explaining what is being created (first-run empty state). */\n help?: ReactNode\n /** When set, the tile is disabled and shows this explanation instead of `help`. */\n disabledReason?: string\n className?: string\n testId?: string\n}\n\n/**\n * The \"create\" tile. Sits in the grid beside the workspace tiles at the same\n * height, in the same tonal family: no dashed outline, no shadow.\n */\nexport function CreateTile({\n label,\n ariaLabel,\n onSelect,\n help,\n disabledReason,\n className,\n testId,\n}: CreateTileProps) {\n const disabled = !!disabledReason\n const select = disabled ? undefined : onSelect\n return (\n <div\n className={cn(\n 'flex min-h-40 w-full flex-col items-center justify-center gap-1 rounded-lg p-4 text-muted-foreground border border-border bg-card shadow-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n disabled\n ? 'cursor-not-allowed opacity-60'\n : 'cursor-pointer hover:border-ring/50 hover:bg-accent/40 hover:text-foreground',\n className\n )}\n onClick={select}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n select?.()\n }\n }}\n role=\"button\"\n tabIndex={0}\n aria-disabled={disabled || undefined}\n title={disabledReason}\n aria-label={ariaLabel ?? label}\n data-slot=\"create-tile\"\n data-testid={testId}\n >\n <span className=\"inline-flex flex-col items-center gap-2 text-sm font-medium\">\n <Plus className=\"size-6\" aria-hidden=\"true\" />\n {label}\n </span>\n {(disabledReason ?? help) && (\n <p className=\"max-w-64 px-4 text-center text-xs leading-snug text-muted-foreground\">\n {disabledReason ?? help}\n </p>\n )}\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { Button, cn } from '@arbidocs/react/ui'\n\n/** A section's quiet header action: ghost, small, still 44px on touch. */\nexport const DASHBOARD_QUIET_ACTION_CLASS =\n 'h-8 gap-1.5 px-2 text-sm bg-transparent text-muted-foreground hover:bg-muted hover:text-foreground pointer-coarse:h-11'\n\n/** Column of the workspace dashboard's bands. A container, so children can use `@2xl:` queries. */\nexport function DashboardRoot({\n testId,\n className,\n children,\n}: {\n testId?: string\n className?: string\n children: ReactNode\n}) {\n return (\n <div\n data-slot=\"dashboard\"\n data-testid={testId}\n className={cn('flex flex-col gap-6', className)}\n >\n {children}\n </div>\n )\n}\n\n/** A dashboard band: `start` is the tiles under the identity bar, `recent` the lists with an eyebrow. */\nexport function DashboardBand({\n kind,\n children,\n}: {\n kind: 'start' | 'recent'\n children: ReactNode\n}) {\n return (\n <div\n data-slot=\"dashboard-band\"\n data-kind={kind}\n className={kind === 'start' ? 'mt-2' : 'mt-4 flex flex-col gap-3'}\n >\n {children}\n </div>\n )\n}\n\n/** Two equal columns from the `@2xl` container width, one below it. */\nexport function DashboardColumns({ children }: { children: ReactNode }) {\n return (\n <div data-slot=\"dashboard-columns\" className=\"grid gap-8 @2xl:grid-cols-2\">\n {children}\n </div>\n )\n}\n\n/** A fact row's mark: a quiet dot. */\nexport function FactMark() {\n return (\n <span\n data-slot=\"fact-mark\"\n className=\"mx-1 size-1.5 shrink-0 rounded-full bg-muted-foreground/40\"\n aria-hidden\n />\n )\n}\n\nexport interface DashboardActionProps {\n /** `primary` is the page's one filled action; `quiet` the ghost header actions. */\n emphasis: 'primary' | 'quiet'\n icon: ReactNode\n label: string\n onClick: () => void\n testId?: string\n}\n\n/** Header action of a dashboard section (\"New chat\", \"New fact\"). */\nexport function DashboardAction({ emphasis, icon, label, onClick, testId }: DashboardActionProps) {\n return (\n <Button\n variant={emphasis === 'primary' ? 'default' : 'ghost'}\n size=\"sm\"\n className={\n emphasis === 'primary'\n ? 'h-8 gap-1.5 px-3 text-sm pointer-coarse:h-11'\n : DASHBOARD_QUIET_ACTION_CLASS\n }\n onClick={onClick}\n data-testid={testId}\n >\n {icon}\n {label}\n </Button>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { EmptyStrip, SectionHeader } from './sections'\n\nexport interface FactsStripRow {\n id: string\n leading?: ReactNode\n title: string\n /** Right-aligned stamp: a date or a time. */\n time?: string\n onSelect?: () => void\n}\n\nexport interface FactsStripGroup {\n /** Captions the group (\"Upcoming\", \"Created\"); an empty group is not rendered. */\n caption: string\n rows: FactsStripRow[]\n /** Test id of every row in this group. Defaults to `${testId}-row`. */\n rowTestId?: string\n}\n\nexport interface FactsStripEmpty {\n icon: LucideIcon\n label: ReactNode\n description?: ReactNode\n onSelect?: () => void\n testId?: string\n}\n\nexport interface FactsStripProps {\n icon?: LucideIcon\n title: string\n count?: number\n onOpen?: () => void\n action?: ReactNode\n groups: FactsStripGroup[]\n empty?: FactsStripEmpty\n className?: string\n /** Root test id; the title button gets `${testId}-open`. */\n testId?: string\n}\n\n/**\n * A glanceable band of captioned groups (facts: upcoming, recently created).\n * Not a third list page: callers hand it a few rows per group.\n */\nexport function FactsStrip({\n icon,\n title,\n count,\n onOpen,\n action,\n groups,\n empty,\n className,\n testId,\n}: FactsStripProps) {\n const filled = groups.filter((g) => g.rows.length > 0)\n return (\n <section\n className={cn('flex min-w-0 flex-col gap-1', className)}\n data-slot=\"facts-strip\"\n data-testid={testId}\n >\n <SectionHeader\n icon={icon}\n title={title}\n count={count}\n onOpen={onOpen}\n openTestId={testId && `${testId}-open`}\n action={action}\n />\n {filled.length === 0\n ? empty && (\n <EmptyStrip\n icon={empty.icon}\n label={empty.label}\n description={empty.description}\n onSelect={empty.onSelect}\n testId={empty.testId}\n />\n )\n : filled.map((group) => (\n <div key={group.caption} className=\"min-w-0\">\n <p className=\"px-3 pb-1 pt-1 text-right text-xs text-muted-foreground\">\n {group.caption}\n </p>\n <ul>\n {group.rows.map((row) => (\n <li key={row.id}>\n <button\n type=\"button\"\n onClick={row.onSelect}\n title={row.title}\n className=\"flex w-full min-w-0 items-center gap-3 rounded-md px-3 py-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&:hover]:bg-muted pointer-coarse:min-h-11\"\n data-testid={group.rowTestId ?? (testId && `${testId}-row`)}\n >\n {row.leading}\n <span className=\"min-w-0 flex-1 truncate text-sm text-foreground\">\n {row.title}\n </span>\n {row.time && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {row.time}\n </span>\n )}\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </section>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../components/ActionLink'\nimport { EmptyStrip, SectionHeader } from './sections'\n\n/** One listed item. Source-agnostic: a chat, a file. */\nexport interface RecentRow {\n id: string\n /** Bare entity mark (an icon carries its own identity; no tinted box). */\n leading?: ReactNode\n title: string\n subtitle?: string\n /** Pinned right on the title line, like a message time. Hidden when `trailing` is set. */\n time?: string\n onSelect?: () => void\n /** Real link target; `onSelect` still fires on a plain click (see `ActionLink`). */\n href?: string\n /** A control rendered beside the row, outside its button. */\n trailing?: ReactNode\n}\n\nexport interface RecentListEmpty {\n icon?: LucideIcon\n label: ReactNode\n description?: ReactNode\n /** Makes the empty strip an invitation button. */\n onSelect?: () => void\n}\n\nexport interface RecentListProps {\n icon?: LucideIcon\n title: string\n count?: number\n /** Opens the full list; makes the header title a button. */\n onOpen?: () => void\n /** Real link target of the header title (with `onOpen`, plain clicks call `onOpen`). */\n openHref?: string\n /** The section's one quiet header action. */\n action?: ReactNode\n rows: RecentRow[]\n /** Names the right-hand column (\"Added\", \"Messaged\"). */\n caption?: string\n /** What an empty section says. A plain muted line unless `onSelect` is set. */\n empty?: RecentListEmpty\n className?: string\n /** Root test id; derived ids: `-open`, `-caption`, `-row`, `-empty-action`. */\n testId?: string\n}\n\n/**\n * A titled list of recent items (files, chats): plain rows under a quiet\n * header. An empty list is one tonal strip that invites the first item.\n */\nexport function RecentList({\n icon,\n title,\n count,\n onOpen,\n openHref,\n action,\n rows,\n caption,\n empty,\n className,\n testId,\n}: RecentListProps) {\n return (\n <section\n className={cn('flex min-w-0 flex-col gap-1', className)}\n data-slot=\"recent-list\"\n data-testid={testId}\n >\n <SectionHeader\n icon={icon}\n title={title}\n count={count}\n onOpen={onOpen}\n openHref={openHref}\n openTestId={testId && `${testId}-open`}\n action={action}\n />\n {rows.length === 0 ? (\n empty?.onSelect ? (\n <EmptyStrip\n icon={empty.icon}\n label={empty.label}\n description={empty.description}\n onSelect={empty.onSelect}\n testId={testId && `${testId}-empty-action`}\n />\n ) : (\n <p className=\"px-1 py-3 text-sm text-muted-foreground\">\n {empty?.description ?? empty?.label}\n </p>\n )\n ) : (\n <>\n {caption && (\n <p className=\"sr-only\" data-testid={testId && `${testId}-caption`}>\n {caption}\n </p>\n )}\n <ul>\n {rows.map((row) => (\n <li\n key={row.id}\n className=\"relative flex items-center rounded-md transition-colors [&:hover]:bg-muted has-[:focus-visible]:bg-muted\"\n data-slot=\"recent-row\"\n >\n <ActionLink\n href={row.href}\n onSelect={row.onSelect}\n title={row.title}\n className={cn(\n 'flex min-w-0 flex-1 items-start gap-3 rounded-md px-3 py-2 text-left focus-visible:outline-none',\n row.onSelect && 'cursor-pointer',\n 'pointer-coarse:min-h-11'\n )}\n data-testid={testId && `${testId}-row`}\n >\n {row.leading}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\">\n {row.title}\n </span>\n {!row.trailing && row.time && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {row.time}\n </span>\n )}\n </div>\n {row.subtitle && (\n <p className=\"mt-0.5 truncate text-xs text-muted-foreground\">\n {row.subtitle}\n </p>\n )}\n </div>\n </ActionLink>\n {row.trailing ? <div className=\"shrink-0 pr-3\">{row.trailing}</div> : null}\n </li>\n ))}\n </ul>\n </>\n )}\n </section>\n )\n}\n","import type { ReactNode } from 'react'\nimport { PartyPopper, X } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { prefixedTestId, testIdOr } from '../chat/test-id'\n\n/** Fixed strings of the strip. */\nexport interface GettingStartedStripLabels {\n /** The close banner's headline. */\n allSet: (firstName?: string) => string\n /** The close banner's second line. */\n finished: (stepCount: number) => string\n done: string\n welcome: (firstName: string) => string\n getStarted: string\n replayDone: string\n almostThere: string\n dismiss: string\n}\n\nexport const DEFAULT_GETTING_STARTED_STRIP_LABELS: GettingStartedStripLabels = {\n allSet: (firstName) => `You’re all set${firstName ? `, ${firstName}` : ''}!`,\n finished: (stepCount) => `You’ve finished the ${stepCount} getting-started steps — explore away.`,\n done: 'Done',\n welcome: (firstName) => `Welcome, ${firstName}`,\n getStarted: 'Get started with ARBI',\n replayDone: 'Nicely done — that’s the tour again',\n almostThere: 'Almost there',\n dismiss: 'Dismiss getting started',\n}\n\nexport interface JourneyStep {\n id: string\n title: string\n /** The instruction shown beside the CURRENT step. */\n description: string\n done: boolean\n}\n\nexport interface GettingStartedStripProps {\n /** The core steps, in order. Numbers are their position. */\n steps: JourneyStep[]\n /** The first step not yet done; undefined when all are. */\n currentStepId?: string\n firstName?: string\n /** Replaying the tour: the finished banner is skipped and copy says so. */\n isReplay?: boolean\n /** Every core step is done (and this is not a replay): show the close banner. */\n isComplete?: boolean\n onDismiss: () => void\n /** Brand mark before the greeting. */\n logo?: ReactNode\n labels?: Partial<GettingStartedStripLabels>\n className?: string\n /** Root test id (default `getting-started`). */\n testId?: string\n /** Sub-element ids; defaults are the current ids. The per-step id is `<stepper>-<step id>`. */\n testIds?: Partial<Record<'stepper' | 'complete' | 'done' | 'dismiss', string>>\n}\n\n// Full literal class strings per state so Tailwind's scanner sees every class.\n// Navy = progress/selection; cyan is reserved for \"this is ARBI/AI\".\nfunction circleClasses(done: boolean, isCurrent: boolean): string {\n if (done) return 'border-primary bg-primary text-primary-foreground'\n if (isCurrent) return 'border-primary bg-accent text-accent-foreground'\n return 'border-border text-muted-foreground'\n}\n\n/**\n * The numbered journey. A step's number never turns into a check: a filled\n * circle plus a struck-through title says \"done\", so status and identity both\n * stay legible without a second glyph. The current step also carries its\n * instruction, the one thing this row tells you to go do.\n */\nfunction Journey({\n steps,\n currentStepId,\n testId,\n}: {\n steps: JourneyStep[]\n currentStepId?: string\n testId?: string\n}) {\n return (\n <ol\n className=\"hidden min-w-0 shrink items-center overflow-x-auto sm:flex\"\n data-slot=\"journey\"\n data-testid={testIdOr(testId, { testId: 'getting-started-stepper' })}\n >\n {steps.map((step, i) => {\n const isCurrent = step.id === currentStepId\n return (\n <li\n key={step.id}\n className=\"flex shrink-0 items-center\"\n data-testid={prefixedTestId(testId, step.id, {\n testId: `getting-started-stepper-${step.id}`,\n })}\n data-done={step.done}\n data-current={isCurrent}\n >\n {i > 0 && (\n <span\n className={cn(\n 'h-0 w-3 shrink-0 border-t-2 border-solid transition-colors duration-500',\n steps[i - 1].done ? 'border-primary' : 'border-border'\n )}\n />\n )}\n <span className=\"flex items-center gap-1.5\">\n <span\n className={cn(\n 'flex size-6 shrink-0 items-center justify-center rounded-full border-2 text-xs font-semibold tabular-nums transition-colors',\n circleClasses(step.done, isCurrent)\n )}\n >\n {i + 1}\n </span>\n <span\n className={cn(\n 'text-sm font-medium',\n step.done\n ? 'text-muted-foreground line-through'\n : isCurrent\n ? 'text-foreground'\n : 'text-muted-foreground'\n )}\n >\n {step.title}\n </span>\n {isCurrent && !step.done && (\n <span className=\"text-muted-foreground\">— {step.description}</span>\n )}\n </span>\n </li>\n )\n })}\n </ol>\n )\n}\n\n/**\n * First-run activation row: greeting, the numbered journey and the current\n * step's instruction, all in ONE bare row (no container, no border), so it can\n * live in a topbar slot. A guide, not a shortcut: it says WHERE to go and the\n * host detects completion itself.\n */\nexport function GettingStartedStrip({\n steps,\n currentStepId,\n firstName,\n isReplay = false,\n isComplete = false,\n onDismiss,\n logo,\n labels,\n className,\n testId,\n testIds,\n}: GettingStartedStripProps) {\n const l = { ...DEFAULT_GETTING_STARTED_STRIP_LABELS, ...labels }\n if (isComplete && !isReplay) {\n return (\n <div\n className={cn('flex min-w-0 items-center gap-3', className)}\n data-slot=\"getting-started-strip\"\n data-testid={testIdOr(testId, { testId: 'getting-started' })}\n >\n <PartyPopper className=\"size-5 shrink-0 text-primary\" aria-hidden=\"true\" />\n <p\n className=\"min-w-0 shrink truncate text-base\"\n data-testid={testIdOr(testIds?.complete, { testId: 'getting-started-complete' })}\n >\n <span className=\"font-semibold text-foreground\">{l.allSet(firstName)}</span>\n <span className=\"mx-1.5 text-muted-foreground\">·</span>\n <span className=\"text-muted-foreground\">{l.finished(steps.length)}</span>\n </p>\n <Journey steps={steps} currentStepId={currentStepId} testId={testIds?.stepper} />\n <div className=\"flex-1\" />\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"shrink-0 rounded-md bg-muted px-3 py-1.5 text-sm font-medium text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11\"\n data-testid={testIdOr(testIds?.done, { testId: 'getting-started-done' })}\n >\n {l.done}\n </button>\n </div>\n )\n }\n\n const greeting = firstName ? l.welcome(firstName) : l.getStarted\n\n return (\n <div\n className={cn('flex min-w-0 items-center gap-3', className)}\n data-slot=\"getting-started-strip\"\n data-testid={testIdOr(testId, { testId: 'getting-started' })}\n >\n {logo}\n <span className=\"shrink-0 text-base font-semibold text-foreground\">{greeting}</span>\n\n <Journey steps={steps} currentStepId={currentStepId} testId={testIds?.stepper} />\n\n {/* Reachable two ways: everything is done but not yet acknowledged (a\n brief instant before the banner takes over), or during a replay you\n have redone all the steps again. */}\n {!currentStepId && (\n <span className=\"min-w-0 flex-1 truncate text-sm text-muted-foreground\">\n {isReplay ? l.replayDone : l.almostThere}\n </span>\n )}\n <div className=\"flex-1\" />\n\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:p-3\"\n aria-label={l.dismiss}\n data-testid={testIdOr(testIds?.dismiss, { testId: 'getting-started-dismiss' })}\n >\n <X className=\"size-4\" />\n </button>\n </div>\n )\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkKGAYUFXD_cjs = require('./chunk-KGAYUFXD.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunkLAQ3Y5JP_cjs = require('./chunk-LAQ3Y5JP.cjs');
|
|
6
6
|
var react$1 = require('react');
|
|
7
7
|
var react = require('@arbidocs/react');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -58,7 +58,7 @@ function ConnectedAssistantDock(props) {
|
|
|
58
58
|
}
|
|
59
59
|
function ScopedAssistantDock(props) {
|
|
60
60
|
const chat = useConnectedChat();
|
|
61
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkLAQ3Y5JP_cjs.AssistantDock, { ...props, chat });
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
Object.defineProperty(exports, "redlineStats", {
|
|
@@ -78,5 +78,5 @@ exports.useConnectedAiTask = useConnectedAiTask;
|
|
|
78
78
|
exports.useConnectedChat = useConnectedChat;
|
|
79
79
|
exports.useSemanticSearch = useSemanticSearch;
|
|
80
80
|
exports.useWorkspaceDocs = useWorkspaceDocs;
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-BFIHXDO6.cjs.map
|
|
82
|
+
//# sourceMappingURL=chunk-BFIHXDO6.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection/ai.tsx"],"names":["useConnection","useKitAiTask","useCallback","useKitWorkspaceDocs","useKitSemanticSearch","useWorkspaceUsers","buildMentionCandidates","useConversation","ConversationScope","jsx","AssistantDock"],"mappings":";;;;;;;;AAkCO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAIA,+BAAA,EAAc;AAC1C,EAAA,MAAM,OAAOC,eAAA,EAAa;AAC1B,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA;AACpB,EAAA,MAAM,GAAA,GAAMC,mBAAA;AAAA,IACV,CAAC,QAAA,EAAkB,MAAA,EAAkB,IAAA,KACnC,OAAO,QAAA,EAAU,MAAA,EAAQ,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,KAAA,IAAS,iBAAiB,CAAA;AAAA,IAC7E,CAAC,QAAQ,eAAe;AAAA,GAC1B;AACA,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAA,EAAI;AACxB;AAGO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,EAAE,WAAA,EAAa,mBAAA,EAAoB,GAAIF,+BAAA,EAAc;AAC3D,EAAA,OAAOG,sBAAA,CAAoB,eAAe,mBAAmB,CAAA;AAC/D;AAGO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAIH,+BAAA,EAAc;AAC1C,EAAA,OAAOI,wBAAqB,EAAC,EAAG,EAAE,KAAA,EAAO,iBAAiB,CAAA;AAC5D;AAQO,SAAS,iBACd,OAAA,EAC8D;AAC9D,EAAA,MAAM,EAAE,aAAa,mBAAA,EAAqB,eAAA,EAAiB,MAAM,MAAA,EAAQ,mBAAA,KACvEJ,+BAAA,EAAc;AAChB,EAAA,MAAM,OAAO,WAAA,IAAe,mBAAA;AAC5B,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,GAAU,EAAC,EAAE,GAAIK,wBAAkB,IAAA,EAAM;AAAA,IACrD,OAAA,EAAS,MAAA,KAAW,eAAA,IAAmB,CAAC,CAAC,IAAA;AAAA,IACzC,WAAA,EAAa;AAAA,GACd,CAAA;AAED,EAAA,MAAM,iBAAA,GAAoBC,4BAAA;AAAA,IACxB,MAAA,KAAW,eAAA,GAAkB,OAAA,GAAU,EAAC;AAAA,IACxC,IAAA,EAAM;AAAA,GACR;AACA,EAAA,MAAM,OAAOC,qBAAA,CAAgB;AAAA,IAC3B,GAAG,OAAA;AAAA,IACH,WAAA,EAAa,IAAA;AAAA,IACb,KAAA,EAAO,SAAS,KAAA,IAAS;AAAA,GAC1B,CAAA;AACD,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,iBAAA;AAAA,IACA,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,MACxC,GAAG,OAAA;AAAA,MACH,GAAI,QAAQ,QAAA,GACR;AAAA,QACE,WAAW,CAAC,CAAC,MAAM,UAAA,IAAc,OAAA,CAAQ,aAAa,IAAA,CAAK,UAAA;AAAA,QAC3D,YACE,OAAA,CAAQ,QAAA,KAAa,IAAA,EAAM,UAAA,GACvB,MAAM,IAAA,IAAQ,IAAA,EAAM,KAAA,GACpB,iBAAA,CAAkB,KAAK,CAAC,SAAA,KAAc,UAAU,EAAA,KAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAAA,UAElF;AAAC,KACP,CAAE;AAAA,GACJ;AACF;AAOO,SAAS,uBAAuB,KAAA,EAAyC;AAC9E,EAAA,sCACGC,uBAAA,EAAA,EACC,QAAA,kBAAAC,cAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,OAAO,CAAA,EAClC,CAAA;AAEJ;AAEA,SAAS,oBAAoB,KAAA,EAAyC;AACpE,EAAA,MAAM,OAAO,gBAAA,EAAiB;AAC9B,EAAA,uBAAOA,cAAA,CAACC,+BAAA,EAAA,EAAe,GAAG,KAAA,EAAO,IAAA,EAAY,CAAA;AAC/C","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/connection/ai.tsx"],"names":["useConnection","useKitAiTask","useCallback","useKitWorkspaceDocs","useKitSemanticSearch","useWorkspaceUsers","buildMentionCandidates","useConversation","ConversationScope","jsx","AssistantDock"],"mappings":";;;;;;;;AAkCO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAIA,+BAAA,EAAc;AAC1C,EAAA,MAAM,OAAOC,eAAA,EAAa;AAC1B,EAAA,MAAM,SAAS,IAAA,CAAK,GAAA;AACpB,EAAA,MAAM,GAAA,GAAMC,mBAAA;AAAA,IACV,CAAC,QAAA,EAAkB,MAAA,EAAkB,IAAA,KACnC,OAAO,QAAA,EAAU,MAAA,EAAQ,EAAE,GAAG,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,KAAA,IAAS,iBAAiB,CAAA;AAAA,IAC7E,CAAC,QAAQ,eAAe;AAAA,GAC1B;AACA,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,GAAA,EAAI;AACxB;AAGO,SAAS,gBAAA,GAAmB;AACjC,EAAA,MAAM,EAAE,WAAA,EAAa,mBAAA,EAAoB,GAAIF,+BAAA,EAAc;AAC3D,EAAA,OAAOG,sBAAA,CAAoB,eAAe,mBAAmB,CAAA;AAC/D;AAGO,SAAS,iBAAA,GAAoB;AAClC,EAAA,MAAM,EAAE,eAAA,EAAgB,GAAIH,+BAAA,EAAc;AAC1C,EAAA,OAAOI,wBAAqB,EAAC,EAAG,EAAE,KAAA,EAAO,iBAAiB,CAAA;AAC5D;AAQO,SAAS,iBACd,OAAA,EAC8D;AAC9D,EAAA,MAAM,EAAE,aAAa,mBAAA,EAAqB,eAAA,EAAiB,MAAM,MAAA,EAAQ,mBAAA,KACvEJ,+BAAA,EAAc;AAChB,EAAA,MAAM,OAAO,WAAA,IAAe,mBAAA;AAC5B,EAAA,MAAM,EAAE,IAAA,EAAM,OAAA,GAAU,EAAC,EAAE,GAAIK,wBAAkB,IAAA,EAAM;AAAA,IACrD,OAAA,EAAS,MAAA,KAAW,eAAA,IAAmB,CAAC,CAAC,IAAA;AAAA,IACzC,WAAA,EAAa;AAAA,GACd,CAAA;AAED,EAAA,MAAM,iBAAA,GAAoBC,4BAAA;AAAA,IACxB,MAAA,KAAW,eAAA,GAAkB,OAAA,GAAU,EAAC;AAAA,IACxC,IAAA,EAAM;AAAA,GACR;AACA,EAAA,MAAM,OAAOC,qBAAA,CAAgB;AAAA,IAC3B,GAAG,OAAA;AAAA,IACH,WAAA,EAAa,IAAA;AAAA,IACb,KAAA,EAAO,SAAS,KAAA,IAAS;AAAA,GAC1B,CAAA;AACD,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,iBAAA;AAAA,IACA,QAAA,EAAU,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,MACxC,GAAG,OAAA;AAAA,MACH,GAAI,QAAQ,QAAA,GACR;AAAA,QACE,WAAW,CAAC,CAAC,MAAM,UAAA,IAAc,OAAA,CAAQ,aAAa,IAAA,CAAK,UAAA;AAAA,QAC3D,YACE,OAAA,CAAQ,QAAA,KAAa,IAAA,EAAM,UAAA,GACvB,MAAM,IAAA,IAAQ,IAAA,EAAM,KAAA,GACpB,iBAAA,CAAkB,KAAK,CAAC,SAAA,KAAc,UAAU,EAAA,KAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAAA,UAElF;AAAC,KACP,CAAE;AAAA,GACJ;AACF;AAOO,SAAS,uBAAuB,KAAA,EAAyC;AAC9E,EAAA,sCACGC,uBAAA,EAAA,EACC,QAAA,kBAAAC,cAAA,CAAC,mBAAA,EAAA,EAAqB,GAAG,OAAO,CAAA,EAClC,CAAA;AAEJ;AAEA,SAAS,oBAAoB,KAAA,EAAyC;AACpE,EAAA,MAAM,OAAO,gBAAA,EAAiB;AAC9B,EAAA,uBAAOA,cAAA,CAACC,+BAAA,EAAA,EAAe,GAAG,KAAA,EAAO,IAAA,EAAY,CAAA;AAC/C","file":"chunk-BFIHXDO6.cjs","sourcesContent":["/**\n * The connected agent hooks — thin adapters over the reusable AI kit in\n * `@arbidocs/react`. The streaming/accumulation/search plumbing lives once in\n * the SDK; these hooks only bind the *workspace source* (from the connection\n * context, falling back to the configured workspace) and inject the host's\n * default assistant *configuration* so call sites needn't know the config\n * ext_id. An explicit `opts.model` still wins.\n */\nimport { useCallback } from 'react'\nimport {\n useAiTask as useKitAiTask,\n useWorkspaceDocs as useKitWorkspaceDocs,\n useSemanticSearch as useKitSemanticSearch,\n useConversation,\n useWorkspaceUsers,\n buildMentionCandidates,\n ConversationScope,\n type ArbiConversation,\n type UseConversationOptions,\n type AiRunOptions,\n} from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport { AssistantDock, type AssistantDockProps } from '../chat/AssistantDock'\nimport type { MentionCandidate } from '@arbidocs/react/shell'\n\nexport type { AiTaskStatus, AiRunOptions, SearchChunk, ArtifactEvent } from '@arbidocs/react'\n\n/** Client-side redlining, re-exported so a host app has one import surface. */\nexport { toRedlineMarkdown, redlineStats, textToArtifact } from '@arbidocs/react'\n\n/**\n * The kit's `useAiTask` with the host's default assistant configuration\n * injected, so call sites needn't know the config ext_id.\n */\nexport function useConnectedAiTask() {\n const { assistantConfig } = useConnection()\n const task = useKitAiTask()\n const kitRun = task.run\n const run = useCallback(\n (question: string, docIds: string[], opts?: AiRunOptions) =>\n kitRun(question, docIds, { ...opts, model: opts?.model ?? assistantConfig }),\n [kitRun, assistantConfig]\n )\n return { ...task, run }\n}\n\n/** Resolve the active workspace + its document ids (what we ground the agent on). */\nexport function useWorkspaceDocs() {\n const { workspaceId, fallbackWorkspaceId } = useConnection()\n return useKitWorkspaceDocs(workspaceId ?? fallbackWorkspaceId)\n}\n\n/** Search the active workspace's documents (all of them) and return the top matching passages. */\nexport function useSemanticSearch() {\n const { assistantConfig } = useConnection()\n return useKitSemanticSearch([], { model: assistantConfig })\n}\n\n/**\n * The chat engine for `ChatPage` bound to the connection: the active workspace and the host's\n * default assistant configuration are injected, so a host writes\n * `<ChatPage chat={useConnectedChat()} />`. It works on the open conversation of the session in\n * scope (wrap a second chat on the page in `ConversationScope`).\n */\nexport function useConnectedChat(\n options?: Omit<UseConversationOptions, 'workspaceId'>\n): ArbiConversation & { mentionCandidates: MentionCandidate[] } {\n const { workspaceId, fallbackWorkspaceId, assistantConfig, user, status, ensureWorkspaceOpen } =\n useConnection()\n const wsId = workspaceId ?? fallbackWorkspaceId\n const { data: members = [] } = useWorkspaceUsers(wsId, {\n enabled: status === 'authenticated' && !!wsId,\n beforeFetch: ensureWorkspaceOpen,\n })\n // The engine's own candidates: what the composer inserts is what a send routes on.\n const mentionCandidates = buildMentionCandidates(\n status === 'authenticated' ? members : [],\n user?.externalId\n )\n const chat = useConversation({\n ...options,\n workspaceId: wsId,\n model: options?.model ?? assistantConfig,\n })\n return {\n ...chat,\n mentionCandidates,\n messages: chat.messages.map((message) => ({\n ...message,\n ...(message.authorId\n ? {\n fromOther: !!user?.externalId && message.authorId !== user.externalId,\n senderName:\n message.authorId === user?.externalId\n ? user?.name || user?.email\n : mentionCandidates.find((candidate) => candidate.id === message.authorId)?.label,\n }\n : {}),\n })),\n }\n}\n\n/**\n * The assistant dock bound to the connection: mount it once in the layout (`Shell.Root`'s `aside`)\n * and put `AssistantDockToggle` in the topbar. Its chat keeps its own open conversation (and\n * survives closing the dock).\n */\nexport function ConnectedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n return (\n <ConversationScope>\n <ScopedAssistantDock {...props} />\n </ConversationScope>\n )\n}\n\nfunction ScopedAssistantDock(props: Omit<AssistantDockProps, 'chat'>) {\n const chat = useConnectedChat()\n return <AssistantDock {...props} chat={chat} />\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useWorkflowView, SkillTypeBadge, SkillGlobalBadge, SkillActionButton, activateOnKey } from './chunk-
|
|
2
|
+
import { useWorkflowView, SkillTypeBadge, SkillGlobalBadge, SkillActionButton, activateOnKey } from './chunk-RFKAE6WS.js';
|
|
3
3
|
import { ActionLink } from './chunk-ELT2V4NB.js';
|
|
4
4
|
import { workflowSteps, initialRunInputs, stepPhase, composeStepPrompt } from './chunk-3D7SX5ZS.js';
|
|
5
5
|
import { testIdOr } from './chunk-7F6CBP3Z.js';
|
|
@@ -254,5 +254,5 @@ function SkillRow({
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
export { DEFAULT_SKILL_CARD_LABELS, DEFAULT_SKILL_ROW_LABELS, SkillCard, SkillRow, useWorkflowPreview };
|
|
257
|
-
//# sourceMappingURL=chunk-
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
257
|
+
//# sourceMappingURL=chunk-BWWND4Y7.js.map
|
|
258
|
+
//# sourceMappingURL=chunk-BWWND4Y7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agents/workflows/useWorkflowPreview.ts","../src/agents/skills/SkillCard.tsx","../src/agents/skills/SkillRow.tsx"],"names":["jsxs","cn","jsx","Eye","Pencil","Lock","Globe"],"mappings":";;;;;;;;;AAwBO,SAAS,kBAAA,CACd,QAAA,EACA,EAAE,MAAA,GAAS,UAAA,EAAY,OAAA,GAAU,GAAA,EAAK,eAAA,EAAiB,OAAA,EAAQ,GAA+B,EAAC,EAC9E;AACjB,EAAA,MAAM,KAAA,GAAQ,cAAc,QAAQ,CAAA;AACpC,EAAA,MAAM,CAAC,QAAQ,SAAS,CAAA,GAAI,SAAyB,MAAM,gBAAA,CAAiB,QAAQ,CAAC,CAAA;AACrF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAA4C,EAAE,CAAA;AAC1E,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,EAAY,KAAA,KAA6B,UAAU,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,CAAC,EAAE,GAAG,OAAM,CAAE,CAAA;AAI9F,EAAA,MAAM,MAAA,GAAS,MAAA,iBAAO,IAAI,GAAA,EAA4C,CAAA;AACtE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,MAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,EAAO,eAAgB,CAAC,CAAA;AAChD,MAAA,OAAA,CAAQ,KAAA,EAAM;AACd,MAAA,SAAA;AAAA,QAAU,CAAC,MACT,MAAA,CAAO,WAAA;AAAA,UACL,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAE,IAAI,CAAC,CAAC,EAAA,EAAI,CAAC,CAAA,KAAM;AAAA,YACjC,EAAA;AAAA,YACA,EAAE,MAAA,KAAW,SAAA,GAAY,EAAE,MAAA,EAAQ,WAAU,GAAI;AAAA,WAClD;AAAA;AACH,OACF;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,EAAG;AAE/D,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAAA,MACjB,CAAC,CAAA,KAAA,CACE,CAAA,CAAE,IAAA,KAAS,OAAA,IAAW,CAAA,CAAE,IAAA,KAAS,QAAA,KAAa,SAAA,CAAU,KAAA,EAAO,MAAA,EAAQ,CAAA,CAAE,EAAE,CAAA,KAAM;AAAA,KACtF;AACA,IAAA,IAAI,CAAC,IAAA,IAAS,IAAA,CAAK,SAAS,OAAA,IAAW,IAAA,CAAK,SAAS,QAAA,EAAW;AAChE,IAAA,MAAM,MAAA,GACJ,IAAA,CAAK,IAAA,KAAS,OAAA,GACV,iBAAA,CAAkB,QAAA,EAAU,IAAA,EAAM,MAAA,EAAQ,EAAE,eAAA,EAAiB,OAAA,EAAS,CAAA,GACtE,EAAA;AACN,IAAA,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,EAAE,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AACvE,IAAA,MAAA,CAAO,OAAA,CAAQ,GAAA;AAAA,MACb,IAAA,CAAK,EAAA;AAAA,MACL,WAAW,MAAM;AACf,QAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAC7B,QAAA,GAAA;AAAA,UACE,IAAA,CAAK,EAAA;AAAA,UACL,IAAA,CAAK,IAAA,KAAS,OAAA,GACV,EAAE,QAAQ,MAAA,EAAQ,IAAA,EAAM,MAAA,CAAO,OAAA,CAAQ,YAAY,MAAM,CAAA,EAAE,GAC3D,EAAE,QAAQ,MAAA;AAAO,SACvB;AAAA,MACF,GAAG,OAAO;AAAA,KACZ;AAAA,EAGF,CAAA,EAAG,CAAC,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAC,CAAA;AAE5B,EAAA,OAAO,eAAA,CAAgB;AAAA,IACrB,KAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,IAAA,EAAM,KAAA,KAAU,UAAU,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,CAAC,IAAI,GAAG,OAAM,CAAE,CAAA;AAAA,IACrE,QAAA,EAAU,OAAO,IAAA,KAAS,GAAA,CAAI,KAAK,EAAA,EAAI,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA,IACzD,IAAA,EAAM,OAAO,EAAA,KAAO,GAAA,CAAI,IAAI,EAAE,MAAA,EAAQ,WAAW,CAAA;AAAA,IACjD,KAAA,EAAO,OAAO,EAAA,KAAO,GAAA,CAAI,IAAI,EAAE,MAAA,EAAQ,WAAW,CAAA;AAAA,IAClD,UAAU,CAAC,EAAA,KAAO,MAAA,CAAO,EAAE,GAAG,MAAA,KAAW;AAAA,GAC1C,CAAA;AACH;ACtEO,IAAM,yBAAA,GAA6C;AAAA,EACxD,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,yCAAA;AAAA,EACb,OAAA,EAAS,eAAA;AAAA,EACT,IAAA,EAAM,YAAA;AAAA,EACN,MAAA,EAAQ,cAAA;AAAA,EACR,WAAA,EAAa,cAAA;AAAA,EACb,kBAAA,EAAoB,0BAAA;AAAA,EACpB,OAAA,EAAS;AACX;AAwCO,SAAS,SAAA,CAAU;AAAA,EACxB,IAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA,GAAa,MAAA;AAAA,EACb,OAAA,GAAU,IAAA;AAAA,EACV,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA4F;AAC1F,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,yBAAA,EAA2B,GAAG,MAAA,EAAO;AACpD,EAAA,MAAM,WAAW,UAAA,KAAe,QAAA;AAChC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2MAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,OAAA;AAAA,MACA,SAAA,EAAW,cAAc,OAAO,CAAA;AAAA,MAChC,iBAAA,EAAiB,IAAA;AAAA,MACjB,aAAA,EAAa,SAAS,MAAA,IAAU,OAAA,EAAS,MAAM,EAAE,MAAA,EAAQ,cAAc,CAAA;AAAA,MACvE,WAAA,EAAU,YAAA;AAAA,MAET,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sCAAA,EAAwC,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QACrE,IAAA;AAAA;AAAA,8BAEE,MAAA,EAAA,EAAK,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,iBAAgB,EACtC,QAAA,kBAAA,IAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,IAAA;AAAA,cACA,QAAA,EAAU,OAAA;AAAA,cACV,SAAA,EAAU,iDAAA;AAAA,cACX,QAAA,EAAA;AAAA,gBAAA,GAAA;AAAA,gBACG;AAAA;AAAA;AAAA,WACJ,EACF;AAAA,4BAEA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,UAAE;AAAA,SAAA,EAAK,CAAA;AAAA,QAE1E,IAAA,IAAQ,IAAA,KAAS,UAAA,oBAAc,GAAA,CAAC,kBAAe,IAAA,EAAY,CAAA;AAAA,QAC3D,QAAA,oBAAY,GAAA,CAAC,gBAAA,EAAA,EAAiB,MAAA,EAAQ,CAAA,EAAG,CAAA;AAAA,wBAC1C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iHAAA,EACb,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,wBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA2C,aAAU,oBAAA,EACnE,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,OAAA;AAAA,cACT,OAAA,EAAS,SAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,SAAS,EAAE,MAAA,EAAQ,wBAAwB,CAAA;AAAA,cAErE,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WAChD;AAAA,0BACA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,IAAA;AAAA,cACT,OAAA,EAAS,MAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,MAAM,EAAE,MAAA,EAAQ,qBAAqB,CAAA;AAAA,cAE/D,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WACnD;AAAA,0BACA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,MAAA;AAAA,cACT,OAAA,EAAS,QAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,QAAQ,EAAE,MAAA,EAAQ,uBAAuB,CAAA;AAAA,cAEnE,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WACrD;AAAA,UACC,WAAW,kBAAA,oBACV,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,QAAA,GAAW,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,OAAA;AAAA,cACpC,OAAA,EAAS,QAAA,GAAW,CAAA,CAAE,kBAAA,GAAqB,CAAA,CAAE,OAAA;AAAA,cAC7C,OAAA,EAAS,kBAAA;AAAA,cACT,MAAA,EAAQ,QAAA,CAAS,OAAA,EAAS,gBAAA,EAAkB;AAAA,gBAC1C,MAAA,EAAQ;AAAA,eACT,CAAA;AAAA,cAEA,QAAA,EAAA,QAAA,uBACE,IAAA,EAAA,EAAK,SAAA,EAAU,gCAA+B,CAAA,mBAE/C,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,qBAAA,EAAsB;AAAA;AAAA;AAE3C,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ;ACjJO,IAAM,wBAAA,GAA2C;AAAA,EACtD,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,yCAAA;AAAA,EACb,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM,MAAA;AAAA,EACN,WAAA,EAAa,cAAA;AAAA,EACb,OAAA,EAAS,wBAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,CAAC,IAAA,KAAS,CAAA,QAAA,EAAW,IAAI,CAAA,cAAA;AACxC;AAwBO,SAAS,QAAA,CAAS;AAAA,EACvB,IAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,IAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA0F;AACxF,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,wBAAA,EAA0B,GAAG,MAAA,EAAO;AACnD,EAAA,uBACEA,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,SAAA,EAAWC,EAAAA;AAAA,QACT,sKAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW,cAAc,QAAQ,CAAA;AAAA,MACjC,aAAA,EAAa,SAAS,MAAA,EAAQ,EAAE,QAAQ,CAAA,iBAAA,EAAoB,IAAI,IAAI,CAAA;AAAA,MACpE,WAAA,EAAU,WAAA;AAAA,MACV,KAAA,EAAO,CAAA,CAAE,WAAA,CAAY,IAAI,CAAA;AAAA,MAExB,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAwC,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACtEF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,YAAA,IAAA;AAAA;AAAA,8BAECE,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,SAAA,EAAU,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB,EAC1D,0BAAAF,IAAAA,CAAC,UAAA,EAAA,EAAW,MAAY,QAAA,EAAU,QAAA,EAAU,WAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,gBAAA,GAAA;AAAA,gBAC/E;AAAA,eAAA,EACJ,CAAA,EACF;AAAA,gCAEAA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,cAAA,GAAA;AAAA,cAAE;AAAA,aAAA,EAAK,CAAA;AAAA,YAErD,QAAQ,IAAA,KAAS,UAAA,oBAAcE,GAAAA,CAAC,kBAAe,IAAA,EAAY,CAAA;AAAA,YAC3D,QAAA,oBAAYA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,QAAQ,CAAA,EAAG;AAAA,WAAA,EAC5C,CAAA;AAAA,UACC,+BAAeA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAA0C,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EACvF,CAAA;AAAA,wBACAF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,0BAAAE,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,CAAA,CAAE,SAAS,OAAA,EAAS,MAAM,SAAA,EAAU,EAC5D,0BAAAA,GAAAA,CAACC,GAAAA,EAAA,EAAI,SAAA,EAAU,UAAS,CAAA,EAC1B,CAAA;AAAA,UACC,0BACCD,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,MAAA,IAC/C,QAAA,kBAAAA,GAAAA,CAACE,QAAA,EAAO,SAAA,EAAU,UAAS,CAAA,EAC7B,CAAA;AAAA,UAED,mCACCF,GAAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,QAAA,GAAW,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,OAAA;AAAA,cACpC,OAAA,EAAS,MAAM,eAAA,EAAgB;AAAA,cAE9B,QAAA,EAAA,QAAA,mBAAWA,GAAAA,CAACG,IAAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA,mBAAKH,GAAAA,CAACI,KAAAA,EAAA,EAAM,WAAU,qBAAA,EAAsB;AAAA;AAAA,WACnF;AAAA,UAED,4BACCJ,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAM,QAAA,IACjD,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,2BAA0B,CAAA,EAC9C;AAAA,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-6OMIIF76.js","sourcesContent":["/**\n * A stepped workflow run on screen only (the builder's preview): agent steps run one at a time,\n * the way the server does, and answer with the prompt they would send; action steps just finish.\n * No thread, no agent.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport {\n composeStepPrompt,\n initialRunInputs,\n stepPhase,\n workflowSteps,\n type StepComposeOptions,\n} from './run'\nimport type { WorkflowDefinition, WorkflowInputs, WorkflowStepState } from './types'\nimport { useWorkflowView, type WorkflowRunView } from './useWorkflowView'\n\nexport interface UseWorkflowPreviewOptions extends StepComposeOptions {\n /** What a stand-in agent step answers; `{prompt}` is replaced with the prompt it would send. */\n answer?: string\n /** How long a stand-in step takes. */\n delayMs?: number\n}\n\nexport function useWorkflowPreview(\n workflow: WorkflowDefinition,\n { answer = '{prompt}', delayMs = 400, resolveWorkflow, compose }: UseWorkflowPreviewOptions = {}\n): WorkflowRunView {\n const steps = workflowSteps(workflow)\n const [inputs, setInputs] = useState<WorkflowInputs>(() => initialRunInputs(workflow))\n const [states, setStates] = useState<Record<string, WorkflowStepState>>({})\n const set = (id: string, state: WorkflowStepState) => setStates((s) => ({ ...s, [id]: state }))\n\n // A stand-in step's timer outlives the re-render its start causes; it is cleared on unmount, and\n // a step it cut short starts again (StrictMode mounts twice).\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n useEffect(() => {\n const pending = timers.current\n return () => {\n for (const t of pending.values()) clearTimeout(t)\n pending.clear()\n setStates((s) =>\n Object.fromEntries(\n Object.entries(s).map(([id, v]) => [\n id,\n v.status === 'running' ? { status: 'pending' } : v,\n ])\n )\n )\n }\n }, [])\n\n // One turn at a time: start the first ready agent step when nothing is running.\n useEffect(() => {\n if (Object.values(states).some((s) => s.status === 'running')) return\n // An action step (a signature, an email, a review) stands in the same way, with no answer.\n const next = steps.find(\n (s) =>\n (s.kind === 'agent' || s.kind === 'action') && stepPhase(steps, states, s.id) === 'ready'\n )\n if (!next || (next.kind !== 'agent' && next.kind !== 'action')) return\n const prompt =\n next.kind === 'agent'\n ? composeStepPrompt(workflow, next, inputs, { resolveWorkflow, compose })\n : ''\n set(next.id, { status: 'running', startedAt: new Date().toISOString() })\n timers.current.set(\n next.id,\n setTimeout(() => {\n timers.current.delete(next.id)\n set(\n next.id,\n next.kind === 'agent'\n ? { status: 'done', text: answer.replace('{prompt}', prompt) }\n : { status: 'done' }\n )\n }, delayMs)\n )\n // `inputs` are read when a step starts, not watched.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [states, steps, workflow])\n\n return useWorkflowView({\n steps,\n states,\n inputs,\n setInput: (name, value) => setInputs((i) => ({ ...i, [name]: value })),\n complete: async (step) => set(step.id, { status: 'done' }),\n skip: async (id) => set(id, { status: 'skipped' }),\n retry: async (id) => set(id, { status: 'pending' }),\n isLocked: (id) => states[id]?.status === 'done',\n })\n}\n","import type { HTMLAttributes, MouseEvent, ReactNode } from 'react'\nimport { Download, Eye, Globe, Lock, Pencil } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../../components/ActionLink'\nimport { testIdOr } from '../../chat/test-id'\nimport {\n SkillActionButton,\n SkillGlobalBadge,\n SkillTypeBadge,\n activateOnKey,\n type SkillGlobalBadgeLabels,\n} from './SkillParts'\n\nexport interface SkillCardLabels extends SkillGlobalBadgeLabels {\n preview: string\n edit: string\n export: string\n makePrivate: string\n makePrivateTooltip: string\n publish: string\n}\n\nexport const DEFAULT_SKILL_CARD_LABELS: SkillCardLabels = {\n global: 'Global',\n globalTitle: 'Shared with everyone in the marketplace',\n preview: 'Preview skill',\n edit: 'Edit skill',\n export: 'Export skill',\n makePrivate: 'Make private',\n makePrivateTooltip: 'Make private (unpublish)',\n publish: 'Publish to marketplace',\n}\n\nexport interface SkillCardTestIds {\n root: string\n preview: string\n edit: string\n export: string\n toggleVisibility: string\n}\n\nexport interface SkillCardProps {\n name: string\n description: string\n /** Skill type; a small badge is shown when not `markdown`. */\n type?: string\n /** `global` shows a badge and drives the publish toggle. */\n visibility?: 'mine' | 'global'\n /** Only owners see the publish toggle. */\n isOwner?: boolean\n /** Leading icon (the app supplies its skill entity icon). */\n icon?: ReactNode\n /** Invoke the skill (row click / Enter / Space). */\n onClick: () => void\n onPreview: (e: MouseEvent) => void\n onEdit: (e: MouseEvent) => void\n onExport: (e: MouseEvent) => void\n /** Publish / unpublish. Owner-only; omit to hide. */\n onToggleVisibility?: (e: MouseEvent) => void\n /** Destination of the skill; the name becomes a real link (modified clicks go to the browser). */\n href?: string\n labels?: Partial<SkillCardLabels>\n testId?: string\n testIds?: Partial<SkillCardTestIds>\n className?: string\n}\n\n/**\n * Horizontal skill row: icon + `/name` + badges + description, with preview / edit / export /\n * publish actions. All actions are always visible (nothing is hover-only).\n */\nexport function SkillCard({\n name,\n description,\n type,\n visibility = 'mine',\n isOwner = true,\n icon,\n onClick,\n onPreview,\n onEdit,\n onExport,\n onToggleVisibility,\n href,\n labels,\n testId,\n testIds,\n className,\n ...rest\n}: SkillCardProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SkillCardProps | 'onClick'>) {\n const l = { ...DEFAULT_SKILL_CARD_LABELS, ...labels }\n const isGlobal = visibility === 'global'\n return (\n <div\n {...rest}\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex w-full cursor-pointer flex-wrap items-center gap-x-3 gap-y-1 rounded-lg bg-muted px-4 py-3 transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n className\n )}\n onClick={onClick}\n onKeyDown={activateOnKey(onClick)}\n data-skill-name={name}\n data-testid={testIdOr(testId ?? testIds?.root, { testId: 'skill-card' })}\n data-slot=\"skill-card\"\n >\n {icon && <span className=\"shrink-0 text-primary [&>svg]:size-5\">{icon}</span>}\n {href ? (\n // The link owns plain + modified clicks; stop the row handler from double-firing.\n <span onClick={(e) => e.stopPropagation()}>\n <ActionLink\n href={href}\n onSelect={onClick}\n className=\"whitespace-nowrap font-mono text-sm font-medium\"\n >\n /{name}\n </ActionLink>\n </span>\n ) : (\n <span className=\"whitespace-nowrap font-mono text-sm font-medium\">/{name}</span>\n )}\n {type && type !== 'markdown' && <SkillTypeBadge type={type} />}\n {isGlobal && <SkillGlobalBadge labels={l} />}\n <span className=\"min-w-0 text-sm text-muted-foreground max-sm:order-last max-sm:w-full max-sm:line-clamp-2 sm:flex-1 sm:truncate\">\n {description}\n </span>\n <span className=\"ml-auto flex shrink-0 items-center gap-1\" data-slot=\"skill-card-actions\">\n <SkillActionButton\n label={l.preview}\n onClick={onPreview}\n testId={testIdOr(testIds?.preview, { testId: 'preview-skill-button' })}\n >\n <Eye className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n <SkillActionButton\n label={l.edit}\n onClick={onEdit}\n testId={testIdOr(testIds?.edit, { testId: 'edit-skill-button' })}\n >\n <Pencil className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n <SkillActionButton\n label={l.export}\n onClick={onExport}\n testId={testIdOr(testIds?.export, { testId: 'export-skill-button' })}\n >\n <Download className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n {isOwner && onToggleVisibility && (\n <SkillActionButton\n label={isGlobal ? l.makePrivate : l.publish}\n tooltip={isGlobal ? l.makePrivateTooltip : l.publish}\n onClick={onToggleVisibility}\n testId={testIdOr(testIds?.toggleVisibility, {\n testId: 'toggle-skill-visibility-button',\n })}\n >\n {isGlobal ? (\n <Lock className=\"size-4 text-muted-foreground\" />\n ) : (\n <Globe className=\"size-4 text-primary\" />\n )}\n </SkillActionButton>\n )}\n </span>\n </div>\n )\n}\n","import type { HTMLAttributes, ReactNode } from 'react'\nimport { Eye, Globe, Lock, Pencil, Trash2 } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../../components/ActionLink'\nimport { testIdOr } from '../../chat/test-id'\nimport {\n SkillActionButton,\n SkillGlobalBadge,\n SkillTypeBadge,\n activateOnKey,\n type SkillGlobalBadgeLabels,\n} from './SkillParts'\n\nexport interface SkillRowLabels extends SkillGlobalBadgeLabels {\n preview: string\n edit: string\n makePrivate: string\n publish: string\n delete: string\n /** Row tooltip; receives the skill name. */\n insertTitle: (name: string) => string\n}\n\nexport const DEFAULT_SKILL_ROW_LABELS: SkillRowLabels = {\n global: 'Global',\n globalTitle: 'Shared with everyone in the marketplace',\n preview: 'Preview',\n edit: 'Edit',\n makePrivate: 'Make private',\n publish: 'Publish to marketplace',\n delete: 'Delete',\n insertTitle: (name) => `Insert /${name} into the chat`,\n}\n\nexport interface SkillRowProps {\n name: string\n description?: string\n type?: string\n isGlobal?: boolean\n icon?: ReactNode\n /** Invoke the skill (inserts `/name` into the chat). */\n onInvoke: () => void\n onPreview: () => void\n /** Owner-only actions: omit to hide. */\n onEdit?: () => void\n onTogglePublish?: () => void\n onDelete?: () => void\n /** Destination of the skill; the name becomes a real link (modified clicks go to the browser). */\n href?: string\n labels?: Partial<SkillRowLabels>\n /** Overrides the default `skills-panel-row-{name}` id. */\n testId?: string\n className?: string\n}\n\n/** Compact two-line skill row for side panels. Actions are always visible. */\nexport function SkillRow({\n name,\n description,\n type,\n isGlobal = false,\n icon,\n onInvoke,\n onPreview,\n onEdit,\n onTogglePublish,\n onDelete,\n href,\n labels,\n testId,\n className,\n ...rest\n}: SkillRowProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SkillRowProps | 'onClick'>) {\n const l = { ...DEFAULT_SKILL_ROW_LABELS, ...labels }\n return (\n <div\n {...rest}\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex cursor-pointer items-center gap-2 px-4 py-2 hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',\n className\n )}\n onClick={onInvoke}\n onKeyDown={activateOnKey(onInvoke)}\n data-testid={testIdOr(testId, { testId: `skills-panel-row-${name}` })}\n data-slot=\"skill-row\"\n title={l.insertTitle(name)}\n >\n {icon && <span className=\"shrink-0 text-primary [&>svg]:size-4\">{icon}</span>}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n {href ? (\n // The link owns plain + modified clicks; stop the row handler from double-firing.\n <span className=\"min-w-0\" onClick={(e) => e.stopPropagation()}>\n <ActionLink href={href} onSelect={onInvoke} className=\"truncate font-mono text-sm\">\n /{name}\n </ActionLink>\n </span>\n ) : (\n <span className=\"truncate font-mono text-sm\">/{name}</span>\n )}\n {type && type !== 'markdown' && <SkillTypeBadge type={type} />}\n {isGlobal && <SkillGlobalBadge labels={l} />}\n </div>\n {description && <div className=\"truncate text-xs text-muted-foreground\">{description}</div>}\n </div>\n <div className=\"flex shrink-0 items-center gap-0.5\">\n <SkillActionButton label={l.preview} onClick={() => onPreview()}>\n <Eye className=\"size-4\" />\n </SkillActionButton>\n {onEdit && (\n <SkillActionButton label={l.edit} onClick={() => onEdit()}>\n <Pencil className=\"size-4\" />\n </SkillActionButton>\n )}\n {onTogglePublish && (\n <SkillActionButton\n label={isGlobal ? l.makePrivate : l.publish}\n onClick={() => onTogglePublish()}\n >\n {isGlobal ? <Lock className=\"size-4\" /> : <Globe className=\"size-4 text-primary\" />}\n </SkillActionButton>\n )}\n {onDelete && (\n <SkillActionButton label={l.delete} onClick={() => onDelete()}>\n <Trash2 className=\"size-4 text-destructive\" />\n </SkillActionButton>\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/agents/workflows/useWorkflowPreview.ts","../src/agents/skills/SkillCard.tsx","../src/agents/skills/SkillRow.tsx"],"names":["jsxs","cn","jsx","Eye","Pencil","Lock","Globe"],"mappings":";;;;;;;;;AAwBO,SAAS,kBAAA,CACd,QAAA,EACA,EAAE,MAAA,GAAS,UAAA,EAAY,OAAA,GAAU,GAAA,EAAK,eAAA,EAAiB,OAAA,EAAQ,GAA+B,EAAC,EAC9E;AACjB,EAAA,MAAM,KAAA,GAAQ,cAAc,QAAQ,CAAA;AACpC,EAAA,MAAM,CAAC,QAAQ,SAAS,CAAA,GAAI,SAAyB,MAAM,gBAAA,CAAiB,QAAQ,CAAC,CAAA;AACrF,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAA4C,EAAE,CAAA;AAC1E,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,EAAY,KAAA,KAA6B,UAAU,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,CAAC,EAAE,GAAG,OAAM,CAAE,CAAA;AAI9F,EAAA,MAAM,MAAA,GAAS,MAAA,iBAAO,IAAI,GAAA,EAA4C,CAAA;AACtE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,MAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,EAAO,eAAgB,CAAC,CAAA;AAChD,MAAA,OAAA,CAAQ,KAAA,EAAM;AACd,MAAA,SAAA;AAAA,QAAU,CAAC,MACT,MAAA,CAAO,WAAA;AAAA,UACL,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAE,IAAI,CAAC,CAAC,EAAA,EAAI,CAAC,CAAA,KAAM;AAAA,YACjC,EAAA;AAAA,YACA,EAAE,MAAA,KAAW,SAAA,GAAY,EAAE,MAAA,EAAQ,WAAU,GAAI;AAAA,WAClD;AAAA;AACH,OACF;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,SAAS,CAAA,EAAG;AAE/D,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AAAA,MACjB,CAAC,CAAA,KAAA,CACE,CAAA,CAAE,IAAA,KAAS,OAAA,IAAW,CAAA,CAAE,IAAA,KAAS,QAAA,KAAa,SAAA,CAAU,KAAA,EAAO,MAAA,EAAQ,CAAA,CAAE,EAAE,CAAA,KAAM;AAAA,KACtF;AACA,IAAA,IAAI,CAAC,IAAA,IAAS,IAAA,CAAK,SAAS,OAAA,IAAW,IAAA,CAAK,SAAS,QAAA,EAAW;AAChE,IAAA,MAAM,MAAA,GACJ,IAAA,CAAK,IAAA,KAAS,OAAA,GACV,iBAAA,CAAkB,QAAA,EAAU,IAAA,EAAM,MAAA,EAAQ,EAAE,eAAA,EAAiB,OAAA,EAAS,CAAA,GACtE,EAAA;AACN,IAAA,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,EAAE,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAA,iBAAW,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY,EAAG,CAAA;AACvE,IAAA,MAAA,CAAO,OAAA,CAAQ,GAAA;AAAA,MACb,IAAA,CAAK,EAAA;AAAA,MACL,WAAW,MAAM;AACf,QAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAC7B,QAAA,GAAA;AAAA,UACE,IAAA,CAAK,EAAA;AAAA,UACL,IAAA,CAAK,IAAA,KAAS,OAAA,GACV,EAAE,QAAQ,MAAA,EAAQ,IAAA,EAAM,MAAA,CAAO,OAAA,CAAQ,YAAY,MAAM,CAAA,EAAE,GAC3D,EAAE,QAAQ,MAAA;AAAO,SACvB;AAAA,MACF,GAAG,OAAO;AAAA,KACZ;AAAA,EAGF,CAAA,EAAG,CAAC,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAC,CAAA;AAE5B,EAAA,OAAO,eAAA,CAAgB;AAAA,IACrB,KAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA,EAAU,CAAC,IAAA,EAAM,KAAA,KAAU,UAAU,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,CAAC,IAAI,GAAG,OAAM,CAAE,CAAA;AAAA,IACrE,QAAA,EAAU,OAAO,IAAA,KAAS,GAAA,CAAI,KAAK,EAAA,EAAI,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA,IACzD,IAAA,EAAM,OAAO,EAAA,KAAO,GAAA,CAAI,IAAI,EAAE,MAAA,EAAQ,WAAW,CAAA;AAAA,IACjD,KAAA,EAAO,OAAO,EAAA,KAAO,GAAA,CAAI,IAAI,EAAE,MAAA,EAAQ,WAAW,CAAA;AAAA,IAClD,UAAU,CAAC,EAAA,KAAO,MAAA,CAAO,EAAE,GAAG,MAAA,KAAW;AAAA,GAC1C,CAAA;AACH;ACtEO,IAAM,yBAAA,GAA6C;AAAA,EACxD,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,yCAAA;AAAA,EACb,OAAA,EAAS,eAAA;AAAA,EACT,IAAA,EAAM,YAAA;AAAA,EACN,MAAA,EAAQ,cAAA;AAAA,EACR,WAAA,EAAa,cAAA;AAAA,EACb,kBAAA,EAAoB,0BAAA;AAAA,EACpB,OAAA,EAAS;AACX;AAwCO,SAAS,SAAA,CAAU;AAAA,EACxB,IAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,UAAA,GAAa,MAAA;AAAA,EACb,OAAA,GAAU,IAAA;AAAA,EACV,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,kBAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA4F;AAC1F,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,yBAAA,EAA2B,GAAG,MAAA,EAAO;AACpD,EAAA,MAAM,WAAW,UAAA,KAAe,QAAA;AAChC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2MAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,OAAA;AAAA,MACA,SAAA,EAAW,cAAc,OAAO,CAAA;AAAA,MAChC,iBAAA,EAAiB,IAAA;AAAA,MACjB,aAAA,EAAa,SAAS,MAAA,IAAU,OAAA,EAAS,MAAM,EAAE,MAAA,EAAQ,cAAc,CAAA;AAAA,MACvE,WAAA,EAAU,YAAA;AAAA,MAET,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sCAAA,EAAwC,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QACrE,IAAA;AAAA;AAAA,8BAEE,MAAA,EAAA,EAAK,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,iBAAgB,EACtC,QAAA,kBAAA,IAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,IAAA;AAAA,cACA,QAAA,EAAU,OAAA;AAAA,cACV,SAAA,EAAU,iDAAA;AAAA,cACX,QAAA,EAAA;AAAA,gBAAA,GAAA;AAAA,gBACG;AAAA;AAAA;AAAA,WACJ,EACF;AAAA,4BAEA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,UAAE;AAAA,SAAA,EAAK,CAAA;AAAA,QAE1E,IAAA,IAAQ,IAAA,KAAS,UAAA,oBAAc,GAAA,CAAC,kBAAe,IAAA,EAAY,CAAA;AAAA,QAC3D,QAAA,oBAAY,GAAA,CAAC,gBAAA,EAAA,EAAiB,MAAA,EAAQ,CAAA,EAAG,CAAA;AAAA,wBAC1C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iHAAA,EACb,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,wBACA,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EAA2C,aAAU,oBAAA,EACnE,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,OAAA;AAAA,cACT,OAAA,EAAS,SAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,SAAS,EAAE,MAAA,EAAQ,wBAAwB,CAAA;AAAA,cAErE,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WAChD;AAAA,0BACA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,IAAA;AAAA,cACT,OAAA,EAAS,MAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,MAAM,EAAE,MAAA,EAAQ,qBAAqB,CAAA;AAAA,cAE/D,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WACnD;AAAA,0BACA,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,OAAO,CAAA,CAAE,MAAA;AAAA,cACT,OAAA,EAAS,QAAA;AAAA,cACT,QAAQ,QAAA,CAAS,OAAA,EAAS,QAAQ,EAAE,MAAA,EAAQ,uBAAuB,CAAA;AAAA,cAEnE,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,8BAAA,EAA+B;AAAA;AAAA,WACrD;AAAA,UACC,WAAW,kBAAA,oBACV,GAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,QAAA,GAAW,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,OAAA;AAAA,cACpC,OAAA,EAAS,QAAA,GAAW,CAAA,CAAE,kBAAA,GAAqB,CAAA,CAAE,OAAA;AAAA,cAC7C,OAAA,EAAS,kBAAA;AAAA,cACT,MAAA,EAAQ,QAAA,CAAS,OAAA,EAAS,gBAAA,EAAkB;AAAA,gBAC1C,MAAA,EAAQ;AAAA,eACT,CAAA;AAAA,cAEA,QAAA,EAAA,QAAA,uBACE,IAAA,EAAA,EAAK,SAAA,EAAU,gCAA+B,CAAA,mBAE/C,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,qBAAA,EAAsB;AAAA;AAAA;AAE3C,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ;ACjJO,IAAM,wBAAA,GAA2C;AAAA,EACtD,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,yCAAA;AAAA,EACb,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM,MAAA;AAAA,EACN,WAAA,EAAa,cAAA;AAAA,EACb,OAAA,EAAS,wBAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,CAAC,IAAA,KAAS,CAAA,QAAA,EAAW,IAAI,CAAA,cAAA;AACxC;AAwBO,SAAS,QAAA,CAAS;AAAA,EACvB,IAAA;AAAA,EACA,WAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,IAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA0F;AACxF,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,wBAAA,EAA0B,GAAG,MAAA,EAAO;AACnD,EAAA,uBACEA,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,SAAA,EAAWC,EAAAA;AAAA,QACT,sKAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW,cAAc,QAAQ,CAAA;AAAA,MACjC,aAAA,EAAa,SAAS,MAAA,EAAQ,EAAE,QAAQ,CAAA,iBAAA,EAAoB,IAAI,IAAI,CAAA;AAAA,MACpE,WAAA,EAAU,WAAA;AAAA,MACV,KAAA,EAAO,CAAA,CAAE,WAAA,CAAY,IAAI,CAAA;AAAA,MAExB,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wCAAwC,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACtEF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA;AAAA,YAAA,IAAA;AAAA;AAAA,8BAECE,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,SAAA,EAAU,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA,EAAgB,EAC1D,0BAAAF,IAAAA,CAAC,UAAA,EAAA,EAAW,MAAY,QAAA,EAAU,QAAA,EAAU,WAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,gBAAA,GAAA;AAAA,gBAC/E;AAAA,eAAA,EACJ,CAAA,EACF;AAAA,gCAEAA,IAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,QAAA,EAAA;AAAA,cAAA,GAAA;AAAA,cAAE;AAAA,aAAA,EAAK,CAAA;AAAA,YAErD,QAAQ,IAAA,KAAS,UAAA,oBAAcE,GAAAA,CAAC,kBAAe,IAAA,EAAY,CAAA;AAAA,YAC3D,QAAA,oBAAYA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,QAAQ,CAAA,EAAG;AAAA,WAAA,EAC5C,CAAA;AAAA,UACC,+BAAeA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0CAA0C,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EACvF,CAAA;AAAA,wBACAF,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,0BAAAE,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,CAAA,CAAE,SAAS,OAAA,EAAS,MAAM,SAAA,EAAU,EAC5D,0BAAAA,GAAAA,CAACC,GAAAA,EAAA,EAAI,SAAA,EAAU,UAAS,CAAA,EAC1B,CAAA;AAAA,UACC,0BACCD,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,MAAA,IAC/C,QAAA,kBAAAA,GAAAA,CAACE,QAAA,EAAO,SAAA,EAAU,UAAS,CAAA,EAC7B,CAAA;AAAA,UAED,mCACCF,GAAAA;AAAA,YAAC,iBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,QAAA,GAAW,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,OAAA;AAAA,cACpC,OAAA,EAAS,MAAM,eAAA,EAAgB;AAAA,cAE9B,QAAA,EAAA,QAAA,mBAAWA,GAAAA,CAACG,IAAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,CAAA,mBAAKH,GAAAA,CAACI,KAAAA,EAAA,EAAM,WAAU,qBAAA,EAAsB;AAAA;AAAA,WACnF;AAAA,UAED,4BACCJ,GAAAA,CAAC,iBAAA,EAAA,EAAkB,KAAA,EAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAM,QAAA,IACjD,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,2BAA0B,CAAA,EAC9C;AAAA,SAAA,EAEJ;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-BWWND4Y7.js","sourcesContent":["/**\n * A stepped workflow run on screen only (the builder's preview): agent steps run one at a time,\n * the way the server does, and answer with the prompt they would send; action steps just finish.\n * No thread, no agent.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport {\n composeStepPrompt,\n initialRunInputs,\n stepPhase,\n workflowSteps,\n type StepComposeOptions,\n} from './run'\nimport type { WorkflowDefinition, WorkflowInputs, WorkflowStepState } from './types'\nimport { useWorkflowView, type WorkflowRunView } from './useWorkflowView'\n\nexport interface UseWorkflowPreviewOptions extends StepComposeOptions {\n /** What a stand-in agent step answers; `{prompt}` is replaced with the prompt it would send. */\n answer?: string\n /** How long a stand-in step takes. */\n delayMs?: number\n}\n\nexport function useWorkflowPreview(\n workflow: WorkflowDefinition,\n { answer = '{prompt}', delayMs = 400, resolveWorkflow, compose }: UseWorkflowPreviewOptions = {}\n): WorkflowRunView {\n const steps = workflowSteps(workflow)\n const [inputs, setInputs] = useState<WorkflowInputs>(() => initialRunInputs(workflow))\n const [states, setStates] = useState<Record<string, WorkflowStepState>>({})\n const set = (id: string, state: WorkflowStepState) => setStates((s) => ({ ...s, [id]: state }))\n\n // A stand-in step's timer outlives the re-render its start causes; it is cleared on unmount, and\n // a step it cut short starts again (StrictMode mounts twice).\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>())\n useEffect(() => {\n const pending = timers.current\n return () => {\n for (const t of pending.values()) clearTimeout(t)\n pending.clear()\n setStates((s) =>\n Object.fromEntries(\n Object.entries(s).map(([id, v]) => [\n id,\n v.status === 'running' ? { status: 'pending' } : v,\n ])\n )\n )\n }\n }, [])\n\n // One turn at a time: start the first ready agent step when nothing is running.\n useEffect(() => {\n if (Object.values(states).some((s) => s.status === 'running')) return\n // An action step (a signature, an email, a review) stands in the same way, with no answer.\n const next = steps.find(\n (s) =>\n (s.kind === 'agent' || s.kind === 'action') && stepPhase(steps, states, s.id) === 'ready'\n )\n if (!next || (next.kind !== 'agent' && next.kind !== 'action')) return\n const prompt =\n next.kind === 'agent'\n ? composeStepPrompt(workflow, next, inputs, { resolveWorkflow, compose })\n : ''\n set(next.id, { status: 'running', startedAt: new Date().toISOString() })\n timers.current.set(\n next.id,\n setTimeout(() => {\n timers.current.delete(next.id)\n set(\n next.id,\n next.kind === 'agent'\n ? { status: 'done', text: answer.replace('{prompt}', prompt) }\n : { status: 'done' }\n )\n }, delayMs)\n )\n // `inputs` are read when a step starts, not watched.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [states, steps, workflow])\n\n return useWorkflowView({\n steps,\n states,\n inputs,\n setInput: (name, value) => setInputs((i) => ({ ...i, [name]: value })),\n complete: async (step) => set(step.id, { status: 'done' }),\n skip: async (id) => set(id, { status: 'skipped' }),\n retry: async (id) => set(id, { status: 'pending' }),\n isLocked: (id) => states[id]?.status === 'done',\n })\n}\n","import type { HTMLAttributes, MouseEvent, ReactNode } from 'react'\nimport { Download, Eye, Globe, Lock, Pencil } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../../components/ActionLink'\nimport { testIdOr } from '../../chat/test-id'\nimport {\n SkillActionButton,\n SkillGlobalBadge,\n SkillTypeBadge,\n activateOnKey,\n type SkillGlobalBadgeLabels,\n} from './SkillParts'\n\nexport interface SkillCardLabels extends SkillGlobalBadgeLabels {\n preview: string\n edit: string\n export: string\n makePrivate: string\n makePrivateTooltip: string\n publish: string\n}\n\nexport const DEFAULT_SKILL_CARD_LABELS: SkillCardLabels = {\n global: 'Global',\n globalTitle: 'Shared with everyone in the marketplace',\n preview: 'Preview skill',\n edit: 'Edit skill',\n export: 'Export skill',\n makePrivate: 'Make private',\n makePrivateTooltip: 'Make private (unpublish)',\n publish: 'Publish to marketplace',\n}\n\nexport interface SkillCardTestIds {\n root: string\n preview: string\n edit: string\n export: string\n toggleVisibility: string\n}\n\nexport interface SkillCardProps {\n name: string\n description: string\n /** Skill type; a small badge is shown when not `markdown`. */\n type?: string\n /** `global` shows a badge and drives the publish toggle. */\n visibility?: 'mine' | 'global'\n /** Only owners see the publish toggle. */\n isOwner?: boolean\n /** Leading icon (the app supplies its skill entity icon). */\n icon?: ReactNode\n /** Invoke the skill (row click / Enter / Space). */\n onClick: () => void\n onPreview: (e: MouseEvent) => void\n onEdit: (e: MouseEvent) => void\n onExport: (e: MouseEvent) => void\n /** Publish / unpublish. Owner-only; omit to hide. */\n onToggleVisibility?: (e: MouseEvent) => void\n /** Destination of the skill; the name becomes a real link (modified clicks go to the browser). */\n href?: string\n labels?: Partial<SkillCardLabels>\n testId?: string\n testIds?: Partial<SkillCardTestIds>\n className?: string\n}\n\n/**\n * Horizontal skill row: icon + `/name` + badges + description, with preview / edit / export /\n * publish actions. All actions are always visible (nothing is hover-only).\n */\nexport function SkillCard({\n name,\n description,\n type,\n visibility = 'mine',\n isOwner = true,\n icon,\n onClick,\n onPreview,\n onEdit,\n onExport,\n onToggleVisibility,\n href,\n labels,\n testId,\n testIds,\n className,\n ...rest\n}: SkillCardProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SkillCardProps | 'onClick'>) {\n const l = { ...DEFAULT_SKILL_CARD_LABELS, ...labels }\n const isGlobal = visibility === 'global'\n return (\n <div\n {...rest}\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex w-full cursor-pointer flex-wrap items-center gap-x-3 gap-y-1 rounded-lg bg-muted px-4 py-3 transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n className\n )}\n onClick={onClick}\n onKeyDown={activateOnKey(onClick)}\n data-skill-name={name}\n data-testid={testIdOr(testId ?? testIds?.root, { testId: 'skill-card' })}\n data-slot=\"skill-card\"\n >\n {icon && <span className=\"shrink-0 text-primary [&>svg]:size-5\">{icon}</span>}\n {href ? (\n // The link owns plain + modified clicks; stop the row handler from double-firing.\n <span onClick={(e) => e.stopPropagation()}>\n <ActionLink\n href={href}\n onSelect={onClick}\n className=\"whitespace-nowrap font-mono text-sm font-medium\"\n >\n /{name}\n </ActionLink>\n </span>\n ) : (\n <span className=\"whitespace-nowrap font-mono text-sm font-medium\">/{name}</span>\n )}\n {type && type !== 'markdown' && <SkillTypeBadge type={type} />}\n {isGlobal && <SkillGlobalBadge labels={l} />}\n <span className=\"min-w-0 text-sm text-muted-foreground max-sm:order-last max-sm:w-full max-sm:line-clamp-2 sm:flex-1 sm:truncate\">\n {description}\n </span>\n <span className=\"ml-auto flex shrink-0 items-center gap-1\" data-slot=\"skill-card-actions\">\n <SkillActionButton\n label={l.preview}\n onClick={onPreview}\n testId={testIdOr(testIds?.preview, { testId: 'preview-skill-button' })}\n >\n <Eye className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n <SkillActionButton\n label={l.edit}\n onClick={onEdit}\n testId={testIdOr(testIds?.edit, { testId: 'edit-skill-button' })}\n >\n <Pencil className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n <SkillActionButton\n label={l.export}\n onClick={onExport}\n testId={testIdOr(testIds?.export, { testId: 'export-skill-button' })}\n >\n <Download className=\"size-4 text-muted-foreground\" />\n </SkillActionButton>\n {isOwner && onToggleVisibility && (\n <SkillActionButton\n label={isGlobal ? l.makePrivate : l.publish}\n tooltip={isGlobal ? l.makePrivateTooltip : l.publish}\n onClick={onToggleVisibility}\n testId={testIdOr(testIds?.toggleVisibility, {\n testId: 'toggle-skill-visibility-button',\n })}\n >\n {isGlobal ? (\n <Lock className=\"size-4 text-muted-foreground\" />\n ) : (\n <Globe className=\"size-4 text-primary\" />\n )}\n </SkillActionButton>\n )}\n </span>\n </div>\n )\n}\n","import type { HTMLAttributes, ReactNode } from 'react'\nimport { Eye, Globe, Lock, Pencil, Trash2 } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../../components/ActionLink'\nimport { testIdOr } from '../../chat/test-id'\nimport {\n SkillActionButton,\n SkillGlobalBadge,\n SkillTypeBadge,\n activateOnKey,\n type SkillGlobalBadgeLabels,\n} from './SkillParts'\n\nexport interface SkillRowLabels extends SkillGlobalBadgeLabels {\n preview: string\n edit: string\n makePrivate: string\n publish: string\n delete: string\n /** Row tooltip; receives the skill name. */\n insertTitle: (name: string) => string\n}\n\nexport const DEFAULT_SKILL_ROW_LABELS: SkillRowLabels = {\n global: 'Global',\n globalTitle: 'Shared with everyone in the marketplace',\n preview: 'Preview',\n edit: 'Edit',\n makePrivate: 'Make private',\n publish: 'Publish to marketplace',\n delete: 'Delete',\n insertTitle: (name) => `Insert /${name} into the chat`,\n}\n\nexport interface SkillRowProps {\n name: string\n description?: string\n type?: string\n isGlobal?: boolean\n icon?: ReactNode\n /** Invoke the skill (inserts `/name` into the chat). */\n onInvoke: () => void\n onPreview: () => void\n /** Owner-only actions: omit to hide. */\n onEdit?: () => void\n onTogglePublish?: () => void\n onDelete?: () => void\n /** Destination of the skill; the name becomes a real link (modified clicks go to the browser). */\n href?: string\n labels?: Partial<SkillRowLabels>\n /** Overrides the default `skills-panel-row-{name}` id. */\n testId?: string\n className?: string\n}\n\n/** Compact two-line skill row for side panels. Actions are always visible. */\nexport function SkillRow({\n name,\n description,\n type,\n isGlobal = false,\n icon,\n onInvoke,\n onPreview,\n onEdit,\n onTogglePublish,\n onDelete,\n href,\n labels,\n testId,\n className,\n ...rest\n}: SkillRowProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SkillRowProps | 'onClick'>) {\n const l = { ...DEFAULT_SKILL_ROW_LABELS, ...labels }\n return (\n <div\n {...rest}\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'flex cursor-pointer items-center gap-2 px-4 py-2 hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',\n className\n )}\n onClick={onInvoke}\n onKeyDown={activateOnKey(onInvoke)}\n data-testid={testIdOr(testId, { testId: `skills-panel-row-${name}` })}\n data-slot=\"skill-row\"\n title={l.insertTitle(name)}\n >\n {icon && <span className=\"shrink-0 text-primary [&>svg]:size-4\">{icon}</span>}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n {href ? (\n // The link owns plain + modified clicks; stop the row handler from double-firing.\n <span className=\"min-w-0\" onClick={(e) => e.stopPropagation()}>\n <ActionLink href={href} onSelect={onInvoke} className=\"truncate font-mono text-sm\">\n /{name}\n </ActionLink>\n </span>\n ) : (\n <span className=\"truncate font-mono text-sm\">/{name}</span>\n )}\n {type && type !== 'markdown' && <SkillTypeBadge type={type} />}\n {isGlobal && <SkillGlobalBadge labels={l} />}\n </div>\n {description && <div className=\"truncate text-xs text-muted-foreground\">{description}</div>}\n </div>\n <div className=\"flex shrink-0 items-center gap-0.5\">\n <SkillActionButton label={l.preview} onClick={() => onPreview()}>\n <Eye className=\"size-4\" />\n </SkillActionButton>\n {onEdit && (\n <SkillActionButton label={l.edit} onClick={() => onEdit()}>\n <Pencil className=\"size-4\" />\n </SkillActionButton>\n )}\n {onTogglePublish && (\n <SkillActionButton\n label={isGlobal ? l.makePrivate : l.publish}\n onClick={() => onTogglePublish()}\n >\n {isGlobal ? <Lock className=\"size-4\" /> : <Globe className=\"size-4 text-primary\" />}\n </SkillActionButton>\n )}\n {onDelete && (\n <SkillActionButton label={l.delete} onClick={() => onDelete()}>\n <Trash2 className=\"size-4 text-destructive\" />\n </SkillActionButton>\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var chunkJBL4PPEE_cjs = require('./chunk-JBL4PPEE.cjs');
|
|
5
4
|
var chunkOU3RGQFX_cjs = require('./chunk-OU3RGQFX.cjs');
|
|
5
|
+
var chunkJBL4PPEE_cjs = require('./chunk-JBL4PPEE.cjs');
|
|
6
6
|
var chunkQZTNTP75_cjs = require('./chunk-QZTNTP75.cjs');
|
|
7
7
|
var chunkEFS3XXZS_cjs = require('./chunk-EFS3XXZS.cjs');
|
|
8
8
|
var react = require('@arbidocs/react');
|
|
@@ -485,5 +485,5 @@ exports.totalWithTaxWord = totalWithTaxWord;
|
|
|
485
485
|
exports.useBillingSupport = useBillingSupport;
|
|
486
486
|
exports.useRewardBalance = useRewardBalance;
|
|
487
487
|
exports.useSelfExtId = useSelfExtId;
|
|
488
|
-
//# sourceMappingURL=chunk-
|
|
489
|
-
//# sourceMappingURL=chunk-
|
|
488
|
+
//# sourceMappingURL=chunk-CCSF7RI4.cjs.map
|
|
489
|
+
//# sourceMappingURL=chunk-CCSF7RI4.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection/billing/support.ts","../src/connection/billing/reward-balance.ts","../src/connection/billing/addon-pricing.ts","../src/connection/billing/plan-constants.ts","../src/connection/billing/quota-items.ts","../src/connection/billing/api-error.ts","../src/connection/billing/tax-quote.ts","../src/connection/billing/plan-pricing.ts","../src/connection/billing/plan-badge.ts","../src/connection/workspace-list/projectBilling.tsx"],"names":["useHost","useArbi","useUserSettings","formatGbp","PoundSterling","HardDrive","Users","gbp","jsx","PlanBadge","ProjectReadout","QuotaMeter","ProjectBreakdown","UsageMeter"],"mappings":"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","file":"chunk-EG3BB32W.cjs","sourcesContent":["/**\n * What a host adds to the billing kit. Selling plans needs Stripe, which stays the host's: whether\n * this deployment sells plans (a publishable key is configured), and its embedded checkout. It is the\n * host configuration's `billing`; without it nothing is for sale: projects show their limits and\n * usage only.\n */\nimport type { ReactNode } from 'react'\nimport { useArbi } from '@arbidocs/react'\nimport { useHost } from '../../provider/host'\n\nexport interface BillingCheckoutSupport {\n /** Load the host's Stripe (lazily, when a checkout opens); `null` when it cannot. */\n load(): Promise<unknown> | null\n /** Stripe's embedded checkout for a session, on the loaded Stripe. */\n render(stripe: unknown, session: { clientSecret: string; onComplete: () => void }): ReactNode\n}\n\nexport interface BillingSupport {\n /** This deployment sells plans (Stripe is configured). */\n stripeEnabled: boolean\n checkout?: BillingCheckoutSupport\n}\n\nconst NOT_FOR_SALE: BillingSupport = { stripeEnabled: false }\n\nexport function useBillingSupport(): BillingSupport {\n return useHost().billing ?? NOT_FOR_SALE\n}\n\n/** The signed-in user's id (`usr-…`), to tell the projects they own from the others. */\nexport function useSelfExtId(): string | undefined {\n const arbi = useArbi()\n return arbi.isLoggedIn ? (arbi.user.identity()?.externalId ?? undefined) : undefined\n}\n","/**\n * Reward-balance logic (hook + money formatter).\n *\n * A user's reward balance is their available account balance — a single GLOBAL per-user\n * number, the Stripe customer account balance mirrored read-only into\n * `settings.extra_discount`. It auto-applies to the user's NEXT invoice.\n *\n * \"Rewards\" is the broad concept: the balance can be fed by several sources (referral\n * reward is just one). The referral pricing surfaces of the billing kit\n * speak to the referral source specifically; this module owns the balance itself.\n */\n\nimport { useUserSettings } from '@arbidocs/react'\n\nexport interface RewardBalance {\n amount: number // minor units (e.g. pennies) of available account balance\n currency: string\n}\n\n/** The user's available reward balance (all sources), or null if none. */\nexport function useRewardBalance(): RewardBalance | null {\n const { data } = useUserSettings()\n // Backend mirrors this read-only as { amount, currency }; schema types it as a loose object.\n const ed = data?.extra_discount as { amount?: number; currency?: string } | null | undefined\n if (!ed || !ed.amount || ed.amount <= 0) return null\n return { amount: ed.amount, currency: ed.currency || 'gbp' }\n}\n\n/** Format minor units as a localized money string, e.g. `£20` (whole) or `£29.99`. */\nexport function formatMoney(cents: number, currency = 'gbp'): string {\n const value = cents / 100\n const isWhole = Number.isInteger(value)\n const c = currency.toLowerCase()\n const symbol =\n c === 'usd' ? '$' : c === 'gbp' ? '£' : c === 'eur' ? '€' : currency.toUpperCase() + ' '\n return `${symbol}${value.toLocaleString('en-US', {\n minimumFractionDigits: isWhole ? 0 : 2,\n maximumFractionDigits: isWhole ? 0 : 2,\n })}`\n}\n","/** Add-on block price helpers (VAT-inclusive pence from `project.addons`). */\n\nimport { formatGbp } from '@arbidocs/react'\nimport type { components } from '@arbidocs/client'\nimport type { AddonKind } from './useAddonPurchase'\nimport { formatMoney } from './reward-balance'\n\ntype ProjectAddons = components['schemas']['ProjectAddons']\n\nconst gbp = (pence: number) => formatMoney(pence, 'gbp')\n\n/** \"3 Nov 2026\". */\nexport function formatPeriodEnd(unix: number | null | undefined): string | null {\n if (!unix) return null\n return new Date(unix * 1000).toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n })\n}\n\n/** What one more block of this kind costs right now, incl. UK VAT. */\nexport function addonPricePence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage' ? addons.ai_block_price_pence : addons.storage_block_price_pence\n}\n\n/** The same price ex VAT. */\nfunction addonPriceExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_price_ex_vat_pence\n : addons.storage_block_price_ex_vat_pence\n}\n\n/**\n * The PUT /addons/settings body (the monthly usage cap and the automatic add-on trigger) from the current add-on\n * state with the given changes applied.\n */\nexport function addonSettingsBody(\n addons: ProjectAddons,\n change: Partial<{\n spend_cap_pence: number | null\n auto_topup_threshold_gbp: number\n }> = {}\n) {\n return {\n spend_cap_pence: addons.spend_cap_pence ?? null,\n auto_topup_threshold_gbp: addons.auto_topup_threshold_gbp,\n ...change,\n }\n}\n\n/**\n * Of `count` blocks of a kind, how many are on an earlier catalogue's price (legacy, at their old size: £10 of AI\n * usage or 10 GB) and how many on today's. A reduction removes today's blocks first, so the legacy ones are the\n * last kept.\n */\nexport function splitBlocks(\n kind: AddonKind,\n count: number,\n addons: ProjectAddons\n): { legacy: number; current: number } {\n const granted =\n (kind === 'ai_usage' ? addons.legacy_ai_blocks : addons.legacy_storage_blocks) ?? 0\n const legacy = Math.max(0, Math.min(granted, count))\n return { legacy, current: count - legacy }\n}\n\n/** One block's size: \"£25 of AI usage\" / \"25 GB\" (legacy: \"£10\" / \"10 GB\"). */\nfunction blockSize(kind: AddonKind, addons: ProjectAddons, legacy: boolean): string {\n if (kind === 'ai_usage') {\n return formatGbp(legacy ? (addons.legacy_block_ai_gbp ?? 10) : addons.block_ai_gbp)\n }\n return `${legacy ? (addons.legacy_block_storage_gb ?? 10) : addons.block_storage_gb} GB`\n}\n\n/**\n * \"2 × £25 of AI usage\", \"1 × £10 + 1 × £25 of AI usage\", \"1 × 10 GB + 2 × 25 GB\": `count` blocks of a kind, the\n * legacy ones (kept last on a reduction) at their old size.\n */\nexport function blocksLabel(kind: AddonKind, count: number, addons: ProjectAddons): string {\n const { legacy, current } = splitBlocks(kind, count, addons)\n const parts = [\n ...(legacy > 0 ? [`${legacy} × ${blockSize(kind, addons, true)}`] : []),\n ...(current > 0 || legacy === 0 ? [`${current} × ${blockSize(kind, addons, false)}`] : []),\n ]\n return `${parts.join(' + ')}${kind === 'ai_usage' ? ' of AI usage' : ''}`\n}\n\n/**\n * Bounds for \"Reduce from next period\": keep `min`..`current` blocks. `next` is what renews\n * now (a pending reduction, or the current count). Storage can't go below what usage needs.\n */\nexport function reduceBounds(\n kind: AddonKind,\n addons: ProjectAddons\n): { min: number; current: number; next: number } {\n const current = kind === 'ai_usage' ? addons.ai_blocks : addons.storage_blocks\n const pending = kind === 'ai_usage' ? addons.ai_blocks_next : addons.storage_blocks_next\n const min = kind === 'ai_usage' ? 0 : Math.min(addons.storage_blocks_min, current)\n return { min, current, next: pending ?? current }\n}\n\n/** One block's monthly-equivalent price ex VAT: AI usage and storage are priced separately. */\nfunction blockMonthlyExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_monthly_ex_vat_pence\n : addons.storage_block_monthly_ex_vat_pence\n}\n\n/** What one block renews at per billing period, ex VAT (annual: 12 × the monthly price). */\nfunction blockPeriodExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_period_ex_vat_pence\n : addons.storage_block_period_ex_vat_pence\n}\n\n/** What one add-on renews at: \"£25/month + VAT\" or \"£225/year + VAT\". */\nfunction blockRenewalShort(kind: AddonKind, addons: ProjectAddons, isAnnual: boolean): string {\n return `${gbp(blockPeriodExVatPence(kind, addons))}/${isAnnual ? 'year' : 'month'} + VAT`\n}\n\n/** The extra line annual plans show beside an AI usage add-on or upgrade price. */\nexport const ANNUAL_PREMIUM_AI_NOTE = 'No markup on Premium AI on annual plans'\n\n/** The confirm dialog's figures: charged now (incl. / ex VAT), what it covers until, then what renews. */\nexport function addonCharge(\n kind: AddonKind,\n addons: ProjectAddons,\n isAnnual: boolean,\n periodEnd: number | null | undefined\n): { now: string; nowExVat: string; nowVat: string; until: string | null; then: string } {\n return {\n now: gbp(addonPricePence(kind, addons)),\n nowExVat: gbp(addonPriceExVatPence(kind, addons)),\n nowVat: gbp(addonPricePence(kind, addons) - addonPriceExVatPence(kind, addons)),\n until: isAnnual ? formatPeriodEnd(periodEnd) : null,\n then: blockRenewalShort(kind, addons, isAnnual),\n }\n}\n\n/** Why automatic top-ups stopped (one line; the price of a step is on the Add button). */\nexport const CAP_REACHED_MESSAGE = 'Usage cap reached: no more automatic top-ups this month.'\n\n/** The £0 usage cap: no automatic top-ups (adding by hand still works). */\nexport const ZERO_BUDGET_MESSAGE = 'Automatic top-ups are off (£0 usage cap).'\n\n/** The usage cap's heading wherever it is edited or shown. */\nexport const USAGE_CAP_LABEL = 'Usage cap'\n\n/** What the usage cap means (in \"More info\"): £0 and \"No limit\" explained. */\nexport const USAGE_CAP_HELP =\n 'The most automatic top-ups (AI usage added when it runs low, storage added when an upload needs it) may ' +\n 'cost in a month. Adding or removing by hand is never limited by it; the plan and renewals are not counted. ' +\n '£0 = no automatic top-ups: AI usage and uploads stop at your allowance unless you add more. ' +\n 'No limit = no cap.'\n\n/** A £0 cap turns automatic top-ups off (manual adds still work). */\nexport function isAddonBudgetZero(addons: Pick<ProjectAddons, 'spend_cap_pence'>): boolean {\n return addons.spend_cap_pence === 0\n}\n\n/**\n * How much more of a resource automatic top-ups may add this month before the usage cap stops them, in the\n * resource's unit (£ of AI usage / GB): the whole blocks the cap left pays for at today's ex-VAT price. `null` =\n * no limit; 0 with a £0 cap or when not even one block fits.\n */\nexport function autoRoom(kind: AddonKind, addons: ProjectAddons): number | null {\n const left = addons.cap_left_pence\n if (left == null) return addons.spend_cap_pence === 0 ? 0 : null\n const price = addonPriceExVatPence(kind, addons)\n if (price <= 0) return 0\n const blocks = Math.floor(left / price)\n return blocks * (kind === 'ai_usage' ? addons.block_ai_gbp : addons.block_storage_gb)\n}\n\n/** The size of the block a one-step reduction removes from what renews (today's blocks go first). */\nexport function nextRemovedBlockSize(kind: AddonKind, addons: ProjectAddons): number {\n const { next } = reduceBounds(kind, addons)\n const { current } = splitBlocks(kind, next, addons)\n if (kind === 'ai_usage') {\n return current > 0 ? addons.block_ai_gbp : (addons.legacy_block_ai_gbp ?? 10)\n }\n return current > 0 ? addons.block_storage_gb : (addons.legacy_block_storage_gb ?? 10)\n}\n\n/**\n * Pounds typed into a usage cap field → pence. '' → the default (null); invalid → undefined.\n * Equal to the default is also sent as null (\"keep the default\").\n */\nexport function parseBudgetPounds(value: string): number | null | undefined {\n if (value.trim() === '') return null\n const n = Number(value)\n if (!Number.isFinite(n) || n < 0) return undefined\n return Math.round(n * 100)\n}\n\n/** Toast after saving the usage cap. */\nexport function budgetSavedMessage(capPence: number | null): string {\n if (capPence == null) return 'Usage cap: no limit'\n if (capPence === 0) return 'Usage cap: £0 (no automatic top-ups)'\n return `Usage cap: ${gbp(capPence)} a month`\n}\n\nconst gbText = (n: number) => `${Math.round(n * 10) / 10} GB`\n\n/** \"£25 of AI usage\" / \"25 GB\". */\nexport function stepLabel(kind: AddonKind, size: number): string {\n return kind === 'ai_usage' ? `${formatGbp(size)} of AI usage` : gbText(size)\n}\n\n/** The PUT /addons/next-period body that renews `keep` blocks of `kind` (the other kind unchanged). */\nexport function nextPeriodBody(kind: AddonKind, keep: number) {\n return kind === 'ai_usage'\n ? { ai_blocks: keep, storage_blocks: null }\n : { ai_blocks: null, storage_blocks: keep }\n}\n\n/**\n * The \"+\" step's price line, ex VAT: \"£25/month · today £25\" (annual: \"£18.75/month · today £150\");\n * storage, charged for the rest of the period: \"£25/month · prorated today £8.33\".\n */\nexport function addStepCaption(kind: AddonKind, addons: ProjectAddons): string {\n const now = gbp(addonPriceExVatPence(kind, addons))\n const today = kind === 'storage' ? `prorated today ${now}` : `today ${now}`\n return `${gbp(blockMonthlyExVatPence(kind, addons))}/month · ${today}`\n}\n","/** Pro's allowance per month (one licence) — must match the backend. Legacy multi-pack plans get it per pack.\n * The live numbers for an existing project come from `project.addons`; these are only for\n * describing the plan before a project exists (new-project dialog, upgrade picker). */\nexport const PRO_AI_GBP = 10\nexport const PRO_STORAGE_GB = 5\n\n/**\n * Add-on block sizes (£25 of AI usage or 25 GB), the same on every plan. Their prices come from the\n * products API (`addon_prices`) before a project exists, and from `project.addons` after.\n */\nexport const ADDON_BLOCK_AI_GBP = 25\nexport const STORAGE_BLOCK_GB = 25\n\n/** Default monthly usage cap for a new Pro project (pence); it limits automatic top-ups only. 0 = no automatic\n * top-ups, null = no limit. */\nexport const DEFAULT_SPEND_CAP_PENCE = 10000\n\n/** The automatic add-on triggers when less than this much AI usage (£) remains; the backend minimum. */\nexport const MIN_AUTO_TOPUP_THRESHOLD_GBP = 1\n\n/** Free-tier quotas — must match backend FREE_* constants in src/constants.py\n * (FREE_AI_GBP=1, FREE_STORAGE_GB=0.05 → 50 MB, FREE_COLLABORATORS=0). */\nexport const FREE_AI_GBP = 1\nexport const FREE_STORAGE_MB = 50\nexport const FREE_COLLABORATORS = 0\n\n/** Collaborator limits at or above this are \"unlimited\" (the backend reports 999 for Pro/dev). */\nexport const UNLIMITED_COLLABORATORS = 999\n\n/**\n * Suggested initial daily per-user AI usage cap (£), pre-filled when creating\n * a new project. The user can clear it to create a project with no cap.\n * Backend treats null as \"no enforcement\" — there is no server-side default.\n */\nexport const SUGGESTED_DAILY_CAP_PER_USER = 10\n","/**\n * Quota display — single source of truth.\n *\n * Builds the icon / label / formatted used-of-limit strings for a project's\n * quotas (AI usage in £, storage, collaborators). Shared by QuotaBadges and the\n * project tooltip so the numbers and units can never disagree (storage in GB on\n * plans of 1 GB or more, MB below).\n */\n\nimport { HardDrive, PoundSterling, Users } from 'lucide-react'\nimport { formatGbp } from '@arbidocs/react'\nimport type { QuotaMeterItem } from '../../settings'\nimport type { components } from '@arbidocs/client'\nimport { UNLIMITED_COLLABORATORS } from './plan-constants'\n\ntype Quotas = components['schemas']['ProjectResponse']['quotas']\n\nconst fmt = (v: number) => Math.round(v).toLocaleString('en-US')\n\n/** \"May 31, 2025\" — the one format every AI-usage-reset mention uses. */\nexport function formatResetDate(unixTimestamp: number | null | undefined): string | null {\n if (!unixTimestamp) return null\n const date = new Date(unixTimestamp * 1000)\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })\n}\n\n/**\n * When the project's AI usage allowance next resets, as a unix timestamp.\n * Pro projects report it directly (`addons.ai_usage_reset_at` — monthly, even on an\n * annual plan); monthly subscriptions otherwise reset with the billing period\n * (`current_period_end`); free projects reset on the backend-stamped signup\n * anniversary (`quotas.budget_reset_at`). Only a FUTURE date is returned — a stale\n * past stamp would read as a bug, not a promise.\n */\nexport function aiUsageResetTimestamp(project: {\n quotas?: { budget_reset_at?: number | null } | null\n current_period_end?: number | null\n plan_interval?: string | null\n addons?: { ai_usage_reset_at?: number | null } | null\n}): number | null {\n // An annual period end is a year away — never a monthly AI usage reset.\n const periodEnd = project.plan_interval === 'year' ? null : project.current_period_end\n const ts =\n project.addons?.ai_usage_reset_at ?? periodEnd ?? project.quotas?.budget_reset_at ?? null\n return ts && ts * 1000 > Date.now() ? ts : null\n}\n\n// Defensive: a quota field may be missing on partial/empty payloads — treat it\n// as 0 / 0 rather than crashing the whole row.\nconst quota = (q?: { used?: number; limit?: number }) => ({\n used: q?.used ?? 0,\n limit: q?.limit ?? 0,\n})\n/** GB from 1 GB plans up (\"2.4 GB\", \"5 GB\"), MB below (\"50 MB\"); `unit: false` drops the unit. */\nfunction storageText(gbValue: number, limitGb: number, unit = true): string {\n if (limitGb >= 1) {\n const n = Math.round(gbValue * 10) / 10\n return `${n.toLocaleString('en-US')}${unit ? ' GB' : ''}`\n }\n return `${fmt(gbValue * 1000)}${unit ? ' MB' : ''}`\n}\nconst pctOf = (used: number, limit: number) => (limit > 0 ? (used / limit) * 100 : 0)\n\nexport function getQuotaItems(quotas: Quotas): QuotaMeterItem[] {\n const aiUsage = quota(quotas?.ai_usage)\n const storage = quota(quotas?.storage_gb)\n const collaborators = quota(quotas?.collaborators)\n const unlimitedCollaborators = collaborators.limit >= UNLIMITED_COLLABORATORS\n return [\n {\n key: 'ai-usage',\n icon: PoundSterling,\n label: 'AI usage',\n used: formatGbp(aiUsage.used),\n usedOfLimit: `${formatGbp(aiUsage.used)} / ${formatGbp(aiUsage.limit)}`,\n pct: pctOf(aiUsage.used, aiUsage.limit),\n },\n {\n key: 'storage',\n icon: HardDrive,\n label: 'Storage',\n used: storageText(storage.used, storage.limit),\n usedOfLimit: `${storageText(storage.used, storage.limit, false)} / ${storageText(\n storage.limit,\n storage.limit\n )}`,\n pct: pctOf(storage.used, storage.limit),\n },\n {\n key: 'collaborators',\n icon: Users,\n label: 'Collaborators',\n used: fmt(collaborators.used),\n usedOfLimit: unlimitedCollaborators\n ? `${fmt(collaborators.used)} / Unlimited`\n : `${fmt(collaborators.used)} / ${fmt(collaborators.limit)}`,\n // Zero seats (Free) IS the cap: 0 / 0 shows a full destructive bar,\n // because you can't add anyone — the truth the upgrade door answers.\n // (Only when the quota is actually present; a missing field on a\n // partial payload stays an empty bar, not a false alarm.)\n pct: unlimitedCollaborators\n ? 0\n : quotas?.collaborators && collaborators.limit === 0\n ? 100\n : pctOf(collaborators.used, collaborators.limit),\n },\n ]\n}\n","/**\n * The `detail` of a refused billing call: the response body's `detail` (a string, or the\n * `{code, message}` of a payment refusal), whether the error is an SDK `ArbiApiError` (body in\n * `apiError`) or the body itself.\n */\nexport function apiErrorDetail(error: unknown): unknown {\n const body = (error as { apiError?: unknown } | null)?.apiError ?? error\n return (body as { detail?: unknown } | null)?.detail\n}\n","/**\n * Tax-inclusive totals from the backend's Stripe Tax quotes (`TaxQuoteResponse`, plan-change\n * previews, add-on quotes): \"£48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\", \"£40.00 · no VAT\n * (reverse charge)\", \"£40.00 · no tax\".\n */\n\nimport type { components } from '@arbidocs/client'\nimport { apiErrorDetail } from './api-error'\n\nexport type TaxQuote = components['schemas']['TaxQuoteResponse']\n\n/** Countries whose tax depends on the postcode: the field is shown up front. */\nexport const POSTCODE_COUNTRIES: readonly string[] = ['US', 'CA']\n\n/** The quote error that asks for a ZIP / postal code. */\nexport const TAX_LOCATION_INVALID = 'TAX_LOCATION_INVALID'\n\n/** \"£42.00\" — always pence, so the parts of a total add up on screen. */\nexport function money2(pence: number, currency = 'gbp'): string {\n const symbol = { gbp: '£', usd: '$', eur: '€' }[currency.toLowerCase()] ?? `${currency} `\n return `${symbol}${(pence / 100).toLocaleString('en-GB', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`\n}\n\nexport interface TaxParts {\n subtotal: number\n tax: number\n total: number\n /** \"VAT 20%\"; null when no tax is due. */\n label?: string | null\n reverseCharge?: boolean\n}\n\n/** \"VAT\" for a VAT label, else \"tax\". */\nfunction taxKind(label: string | null | undefined): string {\n return /^vat\\b/i.test(label ?? '') ? 'VAT' : 'tax'\n}\n\n/** What follows the total: \"incl. VAT (£40.00 + £8.00 VAT 20%)\", \"· no VAT (reverse charge)\", \"· no tax\". */\nexport function taxDetail({ subtotal, tax, label, reverseCharge }: TaxParts): string {\n if (reverseCharge) return '· no VAT (reverse charge)'\n if (tax <= 0) return '· no tax'\n return `incl. ${taxKind(label)} (${money2(subtotal)} + ${money2(tax)} ${label ?? 'tax'})`\n}\n\n/** \"£48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\", \"£40.00 · no VAT (reverse charge)\", \"£40.00 · no tax\". */\nexport function taxSummary(parts: TaxParts): string {\n return `${money2(parts.total)} ${taxDetail(parts)}`\n}\n\n/** \"£21.00 incl. VAT\" / \"£17.50\" — a total with only the word for its tax. */\nexport function totalWithTaxWord({ total, tax, label }: TaxParts): string {\n return tax > 0 ? `${money2(total)} incl. ${taxKind(label)}` : money2(total)\n}\n\n/** The parts of a quote response. */\nexport function quoteParts(quote: TaxQuote): TaxParts {\n return {\n subtotal: quote.subtotal_pence,\n tax: quote.tax_pence,\n total: quote.total_pence,\n label: quote.tax_label,\n reverseCharge: quote.reverse_charge,\n }\n}\n\n/** \"Total today £48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\". */\nexport function quoteTotalLine(quote: TaxQuote): string {\n return `Total today ${taxSummary(quoteParts(quote))}`\n}\n\n/** The API error code (`detail.code`) and message, if any. */\nexport function quoteError(error: unknown): { code?: string; message?: string } {\n const detail = apiErrorDetail(error)\n if (detail && typeof detail === 'object') {\n const { code, message } = detail as { code?: unknown; message?: unknown }\n return {\n code: typeof code === 'string' ? code : undefined,\n message: typeof message === 'string' ? message : undefined,\n }\n }\n return { message: typeof detail === 'string' ? detail : undefined }\n}\n","/**\n * Pro plan price helpers. Prices come from Stripe via GET /v1/user/products (source of truth).\n * One plan is sold: Pro, one licence (£10 of AI usage + 5 GB a month). Each price lists\n * `pack_prices` for that one licence — `amount` incl. UK VAT and `amount_ex_vat` — and\n * `addon_prices` (one add-on block on that interval). Display them as-is.\n * Legacy subscriptions with several packs keep working; their name and price come from the project.\n */\n\nimport type { components } from '@arbidocs/client'\nimport { formatGbp } from '@arbidocs/react'\nimport { formatMoney } from './reward-balance'\nimport { formatPeriodEnd } from './addon-pricing'\nimport { taxSummary } from './tax-quote'\nimport { ADDON_BLOCK_AI_GBP, STORAGE_BLOCK_GB } from './plan-constants'\n\ntype PlanChangePreview = components['schemas']['PlanChangePreview']\ntype ProductPrice = components['schemas']['ProductPrice']\ntype ProductResponse = components['schemas']['ProductResponse']\ntype PackPrice = components['schemas']['PackPrice']\ntype AddonPrice = components['schemas']['AddonPrice']\n\nexport type PlanInterval = 'month' | 'year'\n\nconst gbp = (pence: number) => formatMoney(pence, 'gbp')\n\n/** The headline price: \"£40 + VAT\". */\nexport function plusVat(exVatPence: number, currency = 'gbp'): string {\n return `${formatMoney(exVatPence, currency)} + VAT`\n}\n\n/** The one licence Pro sells. Other pack counts exist only on legacy subscriptions (displayed, not sold). */\nexport const PRO_PACKS = 1\n\n/** A plan the pickers offer. */\nexport type PlanChoice = 'free' | 'pro'\n\n/** Packs per plan choice (0 = Free). */\nexport const PLAN_CHOICE_PACKS: Record<PlanChoice, number> = {\n free: 0,\n pro: PRO_PACKS,\n}\n\n/** \"Free\" (0), \"Pro\" (1), otherwise \"Pro ×N\" (a legacy multi-pack plan; the API's own name wins). */\nexport function planNameForPacks(packs: number | null | undefined): string {\n const n = packs ?? 0\n if (n <= 0) return 'Free'\n if (n === PRO_PACKS) return 'Pro'\n return `Pro ×${n}`\n}\n\n/** The plan-change panel's fixed lines, each with a test id. */\nexport interface PlanChangeLine {\n id: 'pay-today' | 'from' | 'current-until' | 'no-change' | 'awaiting-bank'\n text: string\n}\n\n/**\n * What a plan change costs, from the backend's Stripe invoice preview (taxed for the customer's\n * address), as fixed lines:\n * - \"Pay today £42.00 incl. VAT (£35.00 + £7.00 VAT 20%)\" (\"Pay today £0\" for a change that waits)\n * - \"From 16 Nov 2026: £210.00 incl. VAT (£175.00 + £35.00 VAT 20%) a month\"\n * - \"Current plan until 16 Nov 2026\" for a change that waits for the period end.\n * \"No change\" when the selection is what the project already has; \"Waiting for your bank\" while\n * an earlier upgrade payment awaits 3-D Secure.\n */\nexport function planPreviewLines(preview: PlanChangePreview): PlanChangeLine[] {\n if (preview.unchanged) return [{ id: 'no-change', text: 'No change' }]\n const date = formatPeriodEnd(preview.next_renewal_at)\n const cadence = preview.interval === 'year' ? 'year' : 'month'\n const lines: PlanChangeLine[] = [\n preview.awaiting_confirmation\n ? { id: 'awaiting-bank', text: 'Waiting for your bank' }\n : {\n id: 'pay-today',\n text: preview.effective_now\n ? `Pay today ${taxSummary({\n subtotal: preview.due_now_ex_vat_pence,\n tax: preview.due_now_tax_pence,\n total: preview.due_now_pence,\n label: preview.tax_label,\n })}`\n : `Pay today ${gbp(0)}`,\n },\n {\n id: 'from',\n text: `${date ? `From ${date}` : 'From renewal'}: ${taxSummary({\n subtotal: preview.next_renewal_ex_vat_pence,\n tax: preview.next_renewal_tax_pence,\n total: preview.next_renewal_pence,\n label: preview.tax_label,\n })} a ${cadence}`,\n },\n ]\n if (!preview.effective_now) {\n lines.push({ id: 'current-until', text: `Current plan until ${date ?? 'renewal'}` })\n }\n return lines\n}\n\n/** Stand-in for \"Pay today\" when the preview failed for an upgrade. */\nexport const PAY_TODAY_UNPRICED = 'Pay today: the difference for the rest of this period'\n\n/** One add-on block's price on this interval's plan price (`addon_prices`), if listed. */\nexport function addonPrice(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage' = 'ai_usage'\n): AddonPrice | undefined {\n return price?.addon_prices?.find((p) => p.kind === kind)\n}\n\n/** Per add-on block of `kind` per month, ex VAT (annual plans: the monthly equivalent). */\nexport function addonMonthlyExVat(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage' = 'ai_usage'\n): number | undefined {\n return addonPrice(price, kind)?.monthly_ex_vat\n}\n\n/** What a checkout buys: \"Pro\", \"Pro + 2 × £25 of AI usage + 1 × 25 GB\". */\nexport function checkoutItemsLabel(aiBlocks: number, storageBlocks: number): string {\n return [\n 'Pro',\n aiBlocks > 0 && `${aiBlocks} × ${formatGbp(ADDON_BLOCK_AI_GBP)} of AI usage`,\n storageBlocks > 0 && `${storageBlocks} × ${STORAGE_BLOCK_GB} GB`,\n ]\n .filter(Boolean)\n .join(' + ')\n}\n\n/** The price of `packs` packs on this interval's price, if Stripe lists it (only one licence is listed). */\nexport function packPrice(\n price: ProductPrice | undefined,\n packs: number = PRO_PACKS\n): PackPrice | undefined {\n return price?.pack_prices?.find((p) => p.packs === packs)\n}\n\nexport interface ProPrices {\n monthly?: ProductPrice\n annual?: ProductPrice\n}\n\n/** The Pro product's monthly and annual prices (default price per interval wins). */\nexport function findProPrices(products: ProductResponse[] | undefined): ProPrices {\n const prices = products?.[0]?.prices ?? []\n const pick = (interval: PlanInterval) =>\n prices.find((p) => p.interval === interval && p.default_price) ??\n prices.find((p) => p.interval === interval)\n return { monthly: pick('month'), annual: pick('year') }\n}\n\n/** Annual savings vs 12 × monthly, as a whole percent (e.g. £360 vs £480 → 25). */\nexport function calcSavingsPercent(\n monthlyPrice: ProductPrice | undefined,\n annualPrice: ProductPrice | undefined\n): number | null {\n const monthly = packPrice(monthlyPrice)?.amount ?? monthlyPrice?.amount\n const annual = packPrice(annualPrice)?.amount ?? annualPrice?.amount\n if (monthly == null || annual == null || monthly === 0) return null\n const savings = Math.round(((monthly * 12 - annual) / (monthly * 12)) * 100)\n return savings > 0 ? savings : null\n}\n\n/** Most add-on blocks of each kind a checkout may include (the backend's limit). */\nexport const MAX_CHECKOUT_BLOCKS = 100\n\n/** \"£25/month + VAT each\", annual: \"£225/year + VAT each\": one block on the chosen interval. */\nexport function checkoutBlockPriceText(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage'\n): string | null {\n const block = addonPrice(price, kind)\n if (!block) return null\n const currency = price?.currency ?? 'gbp'\n return price?.interval === 'year'\n ? `${formatMoney(block.amount_ex_vat, currency)}/year + VAT each`\n : `${formatMoney(block.amount_ex_vat, currency)}/month + VAT each`\n}\n","import type { PlanBadgeProps } from '../../settings'\nimport type { components } from '@arbidocs/client'\nimport { planNameForPacks } from './plan-pricing'\n\ntype ProjectBillingFields = Pick<\n components['schemas']['ProjectResponse'],\n 'subscription' | 'plan_interval'\n> &\n Partial<Pick<components['schemas']['ProjectResponse'], 'packs' | 'addons'>>\n\n/** A project is on Pro when it has a billing interval (null = Free or checkout pending). */\nexport function isProProject(project: Pick<ProjectBillingFields, 'plan_interval'>): boolean {\n return project.plan_interval != null\n}\n\n/** \"Pro\", or a legacy multi-pack plan's name (\"Pro ×N\") — the API's name when it sends one (owner view). */\nexport function proTierName(project: ProjectBillingFields): string {\n return project.addons?.plan_name || planNameForPacks(Math.max(project.packs ?? 1, 1))\n}\n\n/** \"Free\", \"Pro monthly\", \"Pro annual\", \"Pro ×3 monthly\" (legacy) or \"Dev\" — the full plan name. */\nexport function planName(project: ProjectBillingFields): string {\n if (project.subscription === 'dev') return 'Dev'\n if (!isProProject(project)) return 'Free'\n return `${proTierName(project)} ${project.plan_interval === 'year' ? 'annual' : 'monthly'}`\n}\n\n/**\n * Maps a project's billing state to the `PlanBadge` block's label + tone.\n * Pro reads as accent, Free/dev as neutral, payment trouble or cancelling as pending.\n */\nexport function planBadgeView(\n project: ProjectBillingFields\n): Pick<PlanBadgeProps, 'label' | 'tone'> {\n const { subscription } = project\n const label =\n subscription === 'canceled'\n ? 'Cancelling'\n : subscription === 'dev'\n ? 'Dev'\n : isProProject(project)\n ? proTierName(project)\n : 'Free'\n\n const tone =\n subscription === 'dev'\n ? 'dev'\n : subscription === 'canceled' || subscription === 'past_due'\n ? 'pending'\n : isProProject(project)\n ? 'paid'\n : 'free'\n\n return { label, tone }\n}\n","/**\n * What a project's group in the workspace list says about the project itself: its plan badge (own\n * projects, where plans are sold), the usage readout beside its name, and the plan and limits\n * breakdown behind the name. One source for the cards' bands and the table's headings.\n */\nimport type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\nimport { UsageMeter } from '../../components/UsageMeter'\nimport { PlanBadge, QuotaMeter } from '../../settings'\nimport { ProjectBreakdown, ProjectReadout } from '../../home/ProjectBandParts'\nimport { planBadgeView } from '../billing/plan-badge'\nimport { getQuotaItems } from '../billing/quota-items'\n\ntype Project = components['schemas']['ProjectResponse']\n\nexport interface ProjectGroupBilling {\n /** The plan badge: own projects only, where plans are sold. */\n planBadge?: ReactNode\n /** Plan and usage, right after the name (projects with quotas). */\n readout?: ReactNode\n /** The plan and limits panel behind the name; meters for own projects only. */\n breakdown?: ReactNode\n}\n\nexport function projectGroupBilling(\n project: Project | undefined,\n { isOwned, stripeEnabled }: { isOwned: boolean; stripeEnabled: boolean }\n): ProjectGroupBilling {\n if (!project) return {}\n const planBadge = isOwned && stripeEnabled ? <PlanBadge {...planBadgeView(project)} /> : undefined\n const quotaItems = project.quotas ? getQuotaItems(project.quotas) : []\n const readout = project.quotas ? (\n <ProjectReadout\n plan={\n planBadge ? { badge: planBadge, testId: `project-tier-${project.external_id}` } : undefined\n }\n usage={{\n testId: `project-usage-${project.external_id}`,\n // Bare numbers without plans for sale: a glance beside the name, not the Plan & Usage detail.\n node: (\n <QuotaMeter\n items={quotaItems}\n size=\"sm\"\n showTooltips={false}\n showBars={stripeEnabled}\n showPercent={false}\n />\n ),\n }}\n />\n ) : (\n planBadge\n )\n const breakdown = (\n <ProjectBreakdown\n name={project.name}\n badge={planBadge}\n meters={\n isOwned\n ? quotaItems.map(({ key, icon, label, usedOfLimit, pct }) => (\n <UsageMeter\n key={key}\n icon={icon as LucideIcon}\n label={label}\n value={usedOfLimit}\n pct={pct}\n />\n ))\n : undefined\n }\n dailyCap={{\n label: 'Daily cap',\n value:\n project.daily_cap_per_user == null\n ? 'No limit'\n : project.daily_cap_per_user.toLocaleString('en-US'),\n }}\n />\n )\n return { planBadge, readout, breakdown }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/connection/billing/support.ts","../src/connection/billing/reward-balance.ts","../src/connection/billing/addon-pricing.ts","../src/connection/billing/plan-constants.ts","../src/connection/billing/quota-items.ts","../src/connection/billing/api-error.ts","../src/connection/billing/tax-quote.ts","../src/connection/billing/plan-pricing.ts","../src/connection/billing/plan-badge.ts","../src/connection/workspace-list/projectBilling.tsx"],"names":["useHost","useArbi","useUserSettings","formatGbp","PoundSterling","HardDrive","Users","gbp","jsx","PlanBadge","ProjectReadout","QuotaMeter","ProjectBreakdown","UsageMeter"],"mappings":"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","file":"chunk-CCSF7RI4.cjs","sourcesContent":["/**\n * What a host adds to the billing kit. Selling plans needs Stripe, which stays the host's: whether\n * this deployment sells plans (a publishable key is configured), and its embedded checkout. It is the\n * host configuration's `billing`; without it nothing is for sale: projects show their limits and\n * usage only.\n */\nimport type { ReactNode } from 'react'\nimport { useArbi } from '@arbidocs/react'\nimport { useHost } from '../../provider/host'\n\nexport interface BillingCheckoutSupport {\n /** Load the host's Stripe (lazily, when a checkout opens); `null` when it cannot. */\n load(): Promise<unknown> | null\n /** Stripe's embedded checkout for a session, on the loaded Stripe. */\n render(stripe: unknown, session: { clientSecret: string; onComplete: () => void }): ReactNode\n}\n\nexport interface BillingSupport {\n /** This deployment sells plans (Stripe is configured). */\n stripeEnabled: boolean\n checkout?: BillingCheckoutSupport\n}\n\nconst NOT_FOR_SALE: BillingSupport = { stripeEnabled: false }\n\nexport function useBillingSupport(): BillingSupport {\n return useHost().billing ?? NOT_FOR_SALE\n}\n\n/** The signed-in user's id (`usr-…`), to tell the projects they own from the others. */\nexport function useSelfExtId(): string | undefined {\n const arbi = useArbi()\n return arbi.isLoggedIn ? (arbi.user.identity()?.externalId ?? undefined) : undefined\n}\n","/**\n * Reward-balance logic (hook + money formatter).\n *\n * A user's reward balance is their available account balance — a single GLOBAL per-user\n * number, the Stripe customer account balance mirrored read-only into\n * `settings.extra_discount`. It auto-applies to the user's NEXT invoice.\n *\n * \"Rewards\" is the broad concept: the balance can be fed by several sources (referral\n * reward is just one). The referral pricing surfaces of the billing kit\n * speak to the referral source specifically; this module owns the balance itself.\n */\n\nimport { useUserSettings } from '@arbidocs/react'\n\nexport interface RewardBalance {\n amount: number // minor units (e.g. pennies) of available account balance\n currency: string\n}\n\n/** The user's available reward balance (all sources), or null if none. */\nexport function useRewardBalance(): RewardBalance | null {\n const { data } = useUserSettings()\n // Backend mirrors this read-only as { amount, currency }; schema types it as a loose object.\n const ed = data?.extra_discount as { amount?: number; currency?: string } | null | undefined\n if (!ed || !ed.amount || ed.amount <= 0) return null\n return { amount: ed.amount, currency: ed.currency || 'gbp' }\n}\n\n/** Format minor units as a localized money string, e.g. `£20` (whole) or `£29.99`. */\nexport function formatMoney(cents: number, currency = 'gbp'): string {\n const value = cents / 100\n const isWhole = Number.isInteger(value)\n const c = currency.toLowerCase()\n const symbol =\n c === 'usd' ? '$' : c === 'gbp' ? '£' : c === 'eur' ? '€' : currency.toUpperCase() + ' '\n return `${symbol}${value.toLocaleString('en-US', {\n minimumFractionDigits: isWhole ? 0 : 2,\n maximumFractionDigits: isWhole ? 0 : 2,\n })}`\n}\n","/** Add-on block price helpers (VAT-inclusive pence from `project.addons`). */\n\nimport { formatGbp } from '@arbidocs/react'\nimport type { components } from '@arbidocs/client'\nimport type { AddonKind } from './useAddonPurchase'\nimport { formatMoney } from './reward-balance'\n\ntype ProjectAddons = components['schemas']['ProjectAddons']\n\nconst gbp = (pence: number) => formatMoney(pence, 'gbp')\n\n/** \"3 Nov 2026\". */\nexport function formatPeriodEnd(unix: number | null | undefined): string | null {\n if (!unix) return null\n return new Date(unix * 1000).toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n })\n}\n\n/** What one more block of this kind costs right now, incl. UK VAT. */\nexport function addonPricePence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage' ? addons.ai_block_price_pence : addons.storage_block_price_pence\n}\n\n/** The same price ex VAT. */\nfunction addonPriceExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_price_ex_vat_pence\n : addons.storage_block_price_ex_vat_pence\n}\n\n/**\n * The PUT /addons/settings body (the monthly usage cap and the automatic add-on trigger) from the current add-on\n * state with the given changes applied.\n */\nexport function addonSettingsBody(\n addons: ProjectAddons,\n change: Partial<{\n spend_cap_pence: number | null\n auto_topup_threshold_gbp: number\n }> = {}\n) {\n return {\n spend_cap_pence: addons.spend_cap_pence ?? null,\n auto_topup_threshold_gbp: addons.auto_topup_threshold_gbp,\n ...change,\n }\n}\n\n/**\n * Of `count` blocks of a kind, how many are on an earlier catalogue's price (legacy, at their old size: £10 of AI\n * usage or 10 GB) and how many on today's. A reduction removes today's blocks first, so the legacy ones are the\n * last kept.\n */\nexport function splitBlocks(\n kind: AddonKind,\n count: number,\n addons: ProjectAddons\n): { legacy: number; current: number } {\n const granted =\n (kind === 'ai_usage' ? addons.legacy_ai_blocks : addons.legacy_storage_blocks) ?? 0\n const legacy = Math.max(0, Math.min(granted, count))\n return { legacy, current: count - legacy }\n}\n\n/** One block's size: \"£25 of AI usage\" / \"25 GB\" (legacy: \"£10\" / \"10 GB\"). */\nfunction blockSize(kind: AddonKind, addons: ProjectAddons, legacy: boolean): string {\n if (kind === 'ai_usage') {\n return formatGbp(legacy ? (addons.legacy_block_ai_gbp ?? 10) : addons.block_ai_gbp)\n }\n return `${legacy ? (addons.legacy_block_storage_gb ?? 10) : addons.block_storage_gb} GB`\n}\n\n/**\n * \"2 × £25 of AI usage\", \"1 × £10 + 1 × £25 of AI usage\", \"1 × 10 GB + 2 × 25 GB\": `count` blocks of a kind, the\n * legacy ones (kept last on a reduction) at their old size.\n */\nexport function blocksLabel(kind: AddonKind, count: number, addons: ProjectAddons): string {\n const { legacy, current } = splitBlocks(kind, count, addons)\n const parts = [\n ...(legacy > 0 ? [`${legacy} × ${blockSize(kind, addons, true)}`] : []),\n ...(current > 0 || legacy === 0 ? [`${current} × ${blockSize(kind, addons, false)}`] : []),\n ]\n return `${parts.join(' + ')}${kind === 'ai_usage' ? ' of AI usage' : ''}`\n}\n\n/**\n * Bounds for \"Reduce from next period\": keep `min`..`current` blocks. `next` is what renews\n * now (a pending reduction, or the current count). Storage can't go below what usage needs.\n */\nexport function reduceBounds(\n kind: AddonKind,\n addons: ProjectAddons\n): { min: number; current: number; next: number } {\n const current = kind === 'ai_usage' ? addons.ai_blocks : addons.storage_blocks\n const pending = kind === 'ai_usage' ? addons.ai_blocks_next : addons.storage_blocks_next\n const min = kind === 'ai_usage' ? 0 : Math.min(addons.storage_blocks_min, current)\n return { min, current, next: pending ?? current }\n}\n\n/** One block's monthly-equivalent price ex VAT: AI usage and storage are priced separately. */\nfunction blockMonthlyExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_monthly_ex_vat_pence\n : addons.storage_block_monthly_ex_vat_pence\n}\n\n/** What one block renews at per billing period, ex VAT (annual: 12 × the monthly price). */\nfunction blockPeriodExVatPence(kind: AddonKind, addons: ProjectAddons): number {\n return kind === 'ai_usage'\n ? addons.ai_block_period_ex_vat_pence\n : addons.storage_block_period_ex_vat_pence\n}\n\n/** What one add-on renews at: \"£25/month + VAT\" or \"£225/year + VAT\". */\nfunction blockRenewalShort(kind: AddonKind, addons: ProjectAddons, isAnnual: boolean): string {\n return `${gbp(blockPeriodExVatPence(kind, addons))}/${isAnnual ? 'year' : 'month'} + VAT`\n}\n\n/** The extra line annual plans show beside an AI usage add-on or upgrade price. */\nexport const ANNUAL_PREMIUM_AI_NOTE = 'No markup on Premium AI on annual plans'\n\n/** The confirm dialog's figures: charged now (incl. / ex VAT), what it covers until, then what renews. */\nexport function addonCharge(\n kind: AddonKind,\n addons: ProjectAddons,\n isAnnual: boolean,\n periodEnd: number | null | undefined\n): { now: string; nowExVat: string; nowVat: string; until: string | null; then: string } {\n return {\n now: gbp(addonPricePence(kind, addons)),\n nowExVat: gbp(addonPriceExVatPence(kind, addons)),\n nowVat: gbp(addonPricePence(kind, addons) - addonPriceExVatPence(kind, addons)),\n until: isAnnual ? formatPeriodEnd(periodEnd) : null,\n then: blockRenewalShort(kind, addons, isAnnual),\n }\n}\n\n/** Why automatic top-ups stopped (one line; the price of a step is on the Add button). */\nexport const CAP_REACHED_MESSAGE = 'Usage cap reached: no more automatic top-ups this month.'\n\n/** The £0 usage cap: no automatic top-ups (adding by hand still works). */\nexport const ZERO_BUDGET_MESSAGE = 'Automatic top-ups are off (£0 usage cap).'\n\n/** The usage cap's heading wherever it is edited or shown. */\nexport const USAGE_CAP_LABEL = 'Usage cap'\n\n/** What the usage cap means (in \"More info\"): £0 and \"No limit\" explained. */\nexport const USAGE_CAP_HELP =\n 'The most automatic top-ups (AI usage added when it runs low, storage added when an upload needs it) may ' +\n 'cost in a month. Adding or removing by hand is never limited by it; the plan and renewals are not counted. ' +\n '£0 = no automatic top-ups: AI usage and uploads stop at your allowance unless you add more. ' +\n 'No limit = no cap.'\n\n/** A £0 cap turns automatic top-ups off (manual adds still work). */\nexport function isAddonBudgetZero(addons: Pick<ProjectAddons, 'spend_cap_pence'>): boolean {\n return addons.spend_cap_pence === 0\n}\n\n/**\n * How much more of a resource automatic top-ups may add this month before the usage cap stops them, in the\n * resource's unit (£ of AI usage / GB): the whole blocks the cap left pays for at today's ex-VAT price. `null` =\n * no limit; 0 with a £0 cap or when not even one block fits.\n */\nexport function autoRoom(kind: AddonKind, addons: ProjectAddons): number | null {\n const left = addons.cap_left_pence\n if (left == null) return addons.spend_cap_pence === 0 ? 0 : null\n const price = addonPriceExVatPence(kind, addons)\n if (price <= 0) return 0\n const blocks = Math.floor(left / price)\n return blocks * (kind === 'ai_usage' ? addons.block_ai_gbp : addons.block_storage_gb)\n}\n\n/** The size of the block a one-step reduction removes from what renews (today's blocks go first). */\nexport function nextRemovedBlockSize(kind: AddonKind, addons: ProjectAddons): number {\n const { next } = reduceBounds(kind, addons)\n const { current } = splitBlocks(kind, next, addons)\n if (kind === 'ai_usage') {\n return current > 0 ? addons.block_ai_gbp : (addons.legacy_block_ai_gbp ?? 10)\n }\n return current > 0 ? addons.block_storage_gb : (addons.legacy_block_storage_gb ?? 10)\n}\n\n/**\n * Pounds typed into a usage cap field → pence. '' → the default (null); invalid → undefined.\n * Equal to the default is also sent as null (\"keep the default\").\n */\nexport function parseBudgetPounds(value: string): number | null | undefined {\n if (value.trim() === '') return null\n const n = Number(value)\n if (!Number.isFinite(n) || n < 0) return undefined\n return Math.round(n * 100)\n}\n\n/** Toast after saving the usage cap. */\nexport function budgetSavedMessage(capPence: number | null): string {\n if (capPence == null) return 'Usage cap: no limit'\n if (capPence === 0) return 'Usage cap: £0 (no automatic top-ups)'\n return `Usage cap: ${gbp(capPence)} a month`\n}\n\nconst gbText = (n: number) => `${Math.round(n * 10) / 10} GB`\n\n/** \"£25 of AI usage\" / \"25 GB\". */\nexport function stepLabel(kind: AddonKind, size: number): string {\n return kind === 'ai_usage' ? `${formatGbp(size)} of AI usage` : gbText(size)\n}\n\n/** The PUT /addons/next-period body that renews `keep` blocks of `kind` (the other kind unchanged). */\nexport function nextPeriodBody(kind: AddonKind, keep: number) {\n return kind === 'ai_usage'\n ? { ai_blocks: keep, storage_blocks: null }\n : { ai_blocks: null, storage_blocks: keep }\n}\n\n/**\n * The \"+\" step's price line, ex VAT: \"£25/month · today £25\" (annual: \"£18.75/month · today £150\");\n * storage, charged for the rest of the period: \"£25/month · prorated today £8.33\".\n */\nexport function addStepCaption(kind: AddonKind, addons: ProjectAddons): string {\n const now = gbp(addonPriceExVatPence(kind, addons))\n const today = kind === 'storage' ? `prorated today ${now}` : `today ${now}`\n return `${gbp(blockMonthlyExVatPence(kind, addons))}/month · ${today}`\n}\n","/** Pro's allowance per month (one licence) — must match the backend. Legacy multi-pack plans get it per pack.\n * The live numbers for an existing project come from `project.addons`; these are only for\n * describing the plan before a project exists (new-project dialog, upgrade picker). */\nexport const PRO_AI_GBP = 10\nexport const PRO_STORAGE_GB = 5\n\n/**\n * Add-on block sizes (£25 of AI usage or 25 GB), the same on every plan. Their prices come from the\n * products API (`addon_prices`) before a project exists, and from `project.addons` after.\n */\nexport const ADDON_BLOCK_AI_GBP = 25\nexport const STORAGE_BLOCK_GB = 25\n\n/** Default monthly usage cap for a new Pro project (pence); it limits automatic top-ups only. 0 = no automatic\n * top-ups, null = no limit. */\nexport const DEFAULT_SPEND_CAP_PENCE = 10000\n\n/** The automatic add-on triggers when less than this much AI usage (£) remains; the backend minimum. */\nexport const MIN_AUTO_TOPUP_THRESHOLD_GBP = 1\n\n/** Free-tier quotas — must match backend FREE_* constants in src/constants.py\n * (FREE_AI_GBP=1, FREE_STORAGE_GB=0.05 → 50 MB, FREE_COLLABORATORS=0). */\nexport const FREE_AI_GBP = 1\nexport const FREE_STORAGE_MB = 50\nexport const FREE_COLLABORATORS = 0\n\n/** Collaborator limits at or above this are \"unlimited\" (the backend reports 999 for Pro/dev). */\nexport const UNLIMITED_COLLABORATORS = 999\n\n/**\n * Suggested initial daily per-user AI usage cap (£), pre-filled when creating\n * a new project. The user can clear it to create a project with no cap.\n * Backend treats null as \"no enforcement\" — there is no server-side default.\n */\nexport const SUGGESTED_DAILY_CAP_PER_USER = 10\n","/**\n * Quota display — single source of truth.\n *\n * Builds the icon / label / formatted used-of-limit strings for a project's\n * quotas (AI usage in £, storage, collaborators). Shared by QuotaBadges and the\n * project tooltip so the numbers and units can never disagree (storage in GB on\n * plans of 1 GB or more, MB below).\n */\n\nimport { HardDrive, PoundSterling, Users } from 'lucide-react'\nimport { formatGbp } from '@arbidocs/react'\nimport type { QuotaMeterItem } from '../../settings'\nimport type { components } from '@arbidocs/client'\nimport { UNLIMITED_COLLABORATORS } from './plan-constants'\n\ntype Quotas = components['schemas']['ProjectResponse']['quotas']\n\nconst fmt = (v: number) => Math.round(v).toLocaleString('en-US')\n\n/** \"May 31, 2025\" — the one format every AI-usage-reset mention uses. */\nexport function formatResetDate(unixTimestamp: number | null | undefined): string | null {\n if (!unixTimestamp) return null\n const date = new Date(unixTimestamp * 1000)\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })\n}\n\n/**\n * When the project's AI usage allowance next resets, as a unix timestamp.\n * Pro projects report it directly (`addons.ai_usage_reset_at` — monthly, even on an\n * annual plan); monthly subscriptions otherwise reset with the billing period\n * (`current_period_end`); free projects reset on the backend-stamped signup\n * anniversary (`quotas.budget_reset_at`). Only a FUTURE date is returned — a stale\n * past stamp would read as a bug, not a promise.\n */\nexport function aiUsageResetTimestamp(project: {\n quotas?: { budget_reset_at?: number | null } | null\n current_period_end?: number | null\n plan_interval?: string | null\n addons?: { ai_usage_reset_at?: number | null } | null\n}): number | null {\n // An annual period end is a year away — never a monthly AI usage reset.\n const periodEnd = project.plan_interval === 'year' ? null : project.current_period_end\n const ts =\n project.addons?.ai_usage_reset_at ?? periodEnd ?? project.quotas?.budget_reset_at ?? null\n return ts && ts * 1000 > Date.now() ? ts : null\n}\n\n// Defensive: a quota field may be missing on partial/empty payloads — treat it\n// as 0 / 0 rather than crashing the whole row.\nconst quota = (q?: { used?: number; limit?: number }) => ({\n used: q?.used ?? 0,\n limit: q?.limit ?? 0,\n})\n/** GB from 1 GB plans up (\"2.4 GB\", \"5 GB\"), MB below (\"50 MB\"); `unit: false` drops the unit. */\nfunction storageText(gbValue: number, limitGb: number, unit = true): string {\n if (limitGb >= 1) {\n const n = Math.round(gbValue * 10) / 10\n return `${n.toLocaleString('en-US')}${unit ? ' GB' : ''}`\n }\n return `${fmt(gbValue * 1000)}${unit ? ' MB' : ''}`\n}\nconst pctOf = (used: number, limit: number) => (limit > 0 ? (used / limit) * 100 : 0)\n\nexport function getQuotaItems(quotas: Quotas): QuotaMeterItem[] {\n const aiUsage = quota(quotas?.ai_usage)\n const storage = quota(quotas?.storage_gb)\n const collaborators = quota(quotas?.collaborators)\n const unlimitedCollaborators = collaborators.limit >= UNLIMITED_COLLABORATORS\n return [\n {\n key: 'ai-usage',\n icon: PoundSterling,\n label: 'AI usage',\n used: formatGbp(aiUsage.used),\n usedOfLimit: `${formatGbp(aiUsage.used)} / ${formatGbp(aiUsage.limit)}`,\n pct: pctOf(aiUsage.used, aiUsage.limit),\n },\n {\n key: 'storage',\n icon: HardDrive,\n label: 'Storage',\n used: storageText(storage.used, storage.limit),\n usedOfLimit: `${storageText(storage.used, storage.limit, false)} / ${storageText(\n storage.limit,\n storage.limit\n )}`,\n pct: pctOf(storage.used, storage.limit),\n },\n {\n key: 'collaborators',\n icon: Users,\n label: 'Collaborators',\n used: fmt(collaborators.used),\n usedOfLimit: unlimitedCollaborators\n ? `${fmt(collaborators.used)} / Unlimited`\n : `${fmt(collaborators.used)} / ${fmt(collaborators.limit)}`,\n // Zero seats (Free) IS the cap: 0 / 0 shows a full destructive bar,\n // because you can't add anyone — the truth the upgrade door answers.\n // (Only when the quota is actually present; a missing field on a\n // partial payload stays an empty bar, not a false alarm.)\n pct: unlimitedCollaborators\n ? 0\n : quotas?.collaborators && collaborators.limit === 0\n ? 100\n : pctOf(collaborators.used, collaborators.limit),\n },\n ]\n}\n","/**\n * The `detail` of a refused billing call: the response body's `detail` (a string, or the\n * `{code, message}` of a payment refusal), whether the error is an SDK `ArbiApiError` (body in\n * `apiError`) or the body itself.\n */\nexport function apiErrorDetail(error: unknown): unknown {\n const body = (error as { apiError?: unknown } | null)?.apiError ?? error\n return (body as { detail?: unknown } | null)?.detail\n}\n","/**\n * Tax-inclusive totals from the backend's Stripe Tax quotes (`TaxQuoteResponse`, plan-change\n * previews, add-on quotes): \"£48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\", \"£40.00 · no VAT\n * (reverse charge)\", \"£40.00 · no tax\".\n */\n\nimport type { components } from '@arbidocs/client'\nimport { apiErrorDetail } from './api-error'\n\nexport type TaxQuote = components['schemas']['TaxQuoteResponse']\n\n/** Countries whose tax depends on the postcode: the field is shown up front. */\nexport const POSTCODE_COUNTRIES: readonly string[] = ['US', 'CA']\n\n/** The quote error that asks for a ZIP / postal code. */\nexport const TAX_LOCATION_INVALID = 'TAX_LOCATION_INVALID'\n\n/** \"£42.00\" — always pence, so the parts of a total add up on screen. */\nexport function money2(pence: number, currency = 'gbp'): string {\n const symbol = { gbp: '£', usd: '$', eur: '€' }[currency.toLowerCase()] ?? `${currency} `\n return `${symbol}${(pence / 100).toLocaleString('en-GB', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}`\n}\n\nexport interface TaxParts {\n subtotal: number\n tax: number\n total: number\n /** \"VAT 20%\"; null when no tax is due. */\n label?: string | null\n reverseCharge?: boolean\n}\n\n/** \"VAT\" for a VAT label, else \"tax\". */\nfunction taxKind(label: string | null | undefined): string {\n return /^vat\\b/i.test(label ?? '') ? 'VAT' : 'tax'\n}\n\n/** What follows the total: \"incl. VAT (£40.00 + £8.00 VAT 20%)\", \"· no VAT (reverse charge)\", \"· no tax\". */\nexport function taxDetail({ subtotal, tax, label, reverseCharge }: TaxParts): string {\n if (reverseCharge) return '· no VAT (reverse charge)'\n if (tax <= 0) return '· no tax'\n return `incl. ${taxKind(label)} (${money2(subtotal)} + ${money2(tax)} ${label ?? 'tax'})`\n}\n\n/** \"£48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\", \"£40.00 · no VAT (reverse charge)\", \"£40.00 · no tax\". */\nexport function taxSummary(parts: TaxParts): string {\n return `${money2(parts.total)} ${taxDetail(parts)}`\n}\n\n/** \"£21.00 incl. VAT\" / \"£17.50\" — a total with only the word for its tax. */\nexport function totalWithTaxWord({ total, tax, label }: TaxParts): string {\n return tax > 0 ? `${money2(total)} incl. ${taxKind(label)}` : money2(total)\n}\n\n/** The parts of a quote response. */\nexport function quoteParts(quote: TaxQuote): TaxParts {\n return {\n subtotal: quote.subtotal_pence,\n tax: quote.tax_pence,\n total: quote.total_pence,\n label: quote.tax_label,\n reverseCharge: quote.reverse_charge,\n }\n}\n\n/** \"Total today £48.00 incl. VAT (£40.00 + £8.00 VAT 20%)\". */\nexport function quoteTotalLine(quote: TaxQuote): string {\n return `Total today ${taxSummary(quoteParts(quote))}`\n}\n\n/** The API error code (`detail.code`) and message, if any. */\nexport function quoteError(error: unknown): { code?: string; message?: string } {\n const detail = apiErrorDetail(error)\n if (detail && typeof detail === 'object') {\n const { code, message } = detail as { code?: unknown; message?: unknown }\n return {\n code: typeof code === 'string' ? code : undefined,\n message: typeof message === 'string' ? message : undefined,\n }\n }\n return { message: typeof detail === 'string' ? detail : undefined }\n}\n","/**\n * Pro plan price helpers. Prices come from Stripe via GET /v1/user/products (source of truth).\n * One plan is sold: Pro, one licence (£10 of AI usage + 5 GB a month). Each price lists\n * `pack_prices` for that one licence — `amount` incl. UK VAT and `amount_ex_vat` — and\n * `addon_prices` (one add-on block on that interval). Display them as-is.\n * Legacy subscriptions with several packs keep working; their name and price come from the project.\n */\n\nimport type { components } from '@arbidocs/client'\nimport { formatGbp } from '@arbidocs/react'\nimport { formatMoney } from './reward-balance'\nimport { formatPeriodEnd } from './addon-pricing'\nimport { taxSummary } from './tax-quote'\nimport { ADDON_BLOCK_AI_GBP, STORAGE_BLOCK_GB } from './plan-constants'\n\ntype PlanChangePreview = components['schemas']['PlanChangePreview']\ntype ProductPrice = components['schemas']['ProductPrice']\ntype ProductResponse = components['schemas']['ProductResponse']\ntype PackPrice = components['schemas']['PackPrice']\ntype AddonPrice = components['schemas']['AddonPrice']\n\nexport type PlanInterval = 'month' | 'year'\n\nconst gbp = (pence: number) => formatMoney(pence, 'gbp')\n\n/** The headline price: \"£40 + VAT\". */\nexport function plusVat(exVatPence: number, currency = 'gbp'): string {\n return `${formatMoney(exVatPence, currency)} + VAT`\n}\n\n/** The one licence Pro sells. Other pack counts exist only on legacy subscriptions (displayed, not sold). */\nexport const PRO_PACKS = 1\n\n/** A plan the pickers offer. */\nexport type PlanChoice = 'free' | 'pro'\n\n/** Packs per plan choice (0 = Free). */\nexport const PLAN_CHOICE_PACKS: Record<PlanChoice, number> = {\n free: 0,\n pro: PRO_PACKS,\n}\n\n/** \"Free\" (0), \"Pro\" (1), otherwise \"Pro ×N\" (a legacy multi-pack plan; the API's own name wins). */\nexport function planNameForPacks(packs: number | null | undefined): string {\n const n = packs ?? 0\n if (n <= 0) return 'Free'\n if (n === PRO_PACKS) return 'Pro'\n return `Pro ×${n}`\n}\n\n/** The plan-change panel's fixed lines, each with a test id. */\nexport interface PlanChangeLine {\n id: 'pay-today' | 'from' | 'current-until' | 'no-change' | 'awaiting-bank'\n text: string\n}\n\n/**\n * What a plan change costs, from the backend's Stripe invoice preview (taxed for the customer's\n * address), as fixed lines:\n * - \"Pay today £42.00 incl. VAT (£35.00 + £7.00 VAT 20%)\" (\"Pay today £0\" for a change that waits)\n * - \"From 16 Nov 2026: £210.00 incl. VAT (£175.00 + £35.00 VAT 20%) a month\"\n * - \"Current plan until 16 Nov 2026\" for a change that waits for the period end.\n * \"No change\" when the selection is what the project already has; \"Waiting for your bank\" while\n * an earlier upgrade payment awaits 3-D Secure.\n */\nexport function planPreviewLines(preview: PlanChangePreview): PlanChangeLine[] {\n if (preview.unchanged) return [{ id: 'no-change', text: 'No change' }]\n const date = formatPeriodEnd(preview.next_renewal_at)\n const cadence = preview.interval === 'year' ? 'year' : 'month'\n const lines: PlanChangeLine[] = [\n preview.awaiting_confirmation\n ? { id: 'awaiting-bank', text: 'Waiting for your bank' }\n : {\n id: 'pay-today',\n text: preview.effective_now\n ? `Pay today ${taxSummary({\n subtotal: preview.due_now_ex_vat_pence,\n tax: preview.due_now_tax_pence,\n total: preview.due_now_pence,\n label: preview.tax_label,\n })}`\n : `Pay today ${gbp(0)}`,\n },\n {\n id: 'from',\n text: `${date ? `From ${date}` : 'From renewal'}: ${taxSummary({\n subtotal: preview.next_renewal_ex_vat_pence,\n tax: preview.next_renewal_tax_pence,\n total: preview.next_renewal_pence,\n label: preview.tax_label,\n })} a ${cadence}`,\n },\n ]\n if (!preview.effective_now) {\n lines.push({ id: 'current-until', text: `Current plan until ${date ?? 'renewal'}` })\n }\n return lines\n}\n\n/** Stand-in for \"Pay today\" when the preview failed for an upgrade. */\nexport const PAY_TODAY_UNPRICED = 'Pay today: the difference for the rest of this period'\n\n/** One add-on block's price on this interval's plan price (`addon_prices`), if listed. */\nexport function addonPrice(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage' = 'ai_usage'\n): AddonPrice | undefined {\n return price?.addon_prices?.find((p) => p.kind === kind)\n}\n\n/** Per add-on block of `kind` per month, ex VAT (annual plans: the monthly equivalent). */\nexport function addonMonthlyExVat(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage' = 'ai_usage'\n): number | undefined {\n return addonPrice(price, kind)?.monthly_ex_vat\n}\n\n/** What a checkout buys: \"Pro\", \"Pro + 2 × £25 of AI usage + 1 × 25 GB\". */\nexport function checkoutItemsLabel(aiBlocks: number, storageBlocks: number): string {\n return [\n 'Pro',\n aiBlocks > 0 && `${aiBlocks} × ${formatGbp(ADDON_BLOCK_AI_GBP)} of AI usage`,\n storageBlocks > 0 && `${storageBlocks} × ${STORAGE_BLOCK_GB} GB`,\n ]\n .filter(Boolean)\n .join(' + ')\n}\n\n/** The price of `packs` packs on this interval's price, if Stripe lists it (only one licence is listed). */\nexport function packPrice(\n price: ProductPrice | undefined,\n packs: number = PRO_PACKS\n): PackPrice | undefined {\n return price?.pack_prices?.find((p) => p.packs === packs)\n}\n\nexport interface ProPrices {\n monthly?: ProductPrice\n annual?: ProductPrice\n}\n\n/** The Pro product's monthly and annual prices (default price per interval wins). */\nexport function findProPrices(products: ProductResponse[] | undefined): ProPrices {\n const prices = products?.[0]?.prices ?? []\n const pick = (interval: PlanInterval) =>\n prices.find((p) => p.interval === interval && p.default_price) ??\n prices.find((p) => p.interval === interval)\n return { monthly: pick('month'), annual: pick('year') }\n}\n\n/** Annual savings vs 12 × monthly, as a whole percent (e.g. £360 vs £480 → 25). */\nexport function calcSavingsPercent(\n monthlyPrice: ProductPrice | undefined,\n annualPrice: ProductPrice | undefined\n): number | null {\n const monthly = packPrice(monthlyPrice)?.amount ?? monthlyPrice?.amount\n const annual = packPrice(annualPrice)?.amount ?? annualPrice?.amount\n if (monthly == null || annual == null || monthly === 0) return null\n const savings = Math.round(((monthly * 12 - annual) / (monthly * 12)) * 100)\n return savings > 0 ? savings : null\n}\n\n/** Most add-on blocks of each kind a checkout may include (the backend's limit). */\nexport const MAX_CHECKOUT_BLOCKS = 100\n\n/** \"£25/month + VAT each\", annual: \"£225/year + VAT each\": one block on the chosen interval. */\nexport function checkoutBlockPriceText(\n price: ProductPrice | undefined,\n kind: 'ai_usage' | 'storage'\n): string | null {\n const block = addonPrice(price, kind)\n if (!block) return null\n const currency = price?.currency ?? 'gbp'\n return price?.interval === 'year'\n ? `${formatMoney(block.amount_ex_vat, currency)}/year + VAT each`\n : `${formatMoney(block.amount_ex_vat, currency)}/month + VAT each`\n}\n","import type { PlanBadgeProps } from '../../settings'\nimport type { components } from '@arbidocs/client'\nimport { planNameForPacks } from './plan-pricing'\n\ntype ProjectBillingFields = Pick<\n components['schemas']['ProjectResponse'],\n 'subscription' | 'plan_interval'\n> &\n Partial<Pick<components['schemas']['ProjectResponse'], 'packs' | 'addons'>>\n\n/** A project is on Pro when it has a billing interval (null = Free or checkout pending). */\nexport function isProProject(project: Pick<ProjectBillingFields, 'plan_interval'>): boolean {\n return project.plan_interval != null\n}\n\n/** \"Pro\", or a legacy multi-pack plan's name (\"Pro ×N\") — the API's name when it sends one (owner view). */\nexport function proTierName(project: ProjectBillingFields): string {\n return project.addons?.plan_name || planNameForPacks(Math.max(project.packs ?? 1, 1))\n}\n\n/** \"Free\", \"Pro monthly\", \"Pro annual\", \"Pro ×3 monthly\" (legacy) or \"Dev\" — the full plan name. */\nexport function planName(project: ProjectBillingFields): string {\n if (project.subscription === 'dev') return 'Dev'\n if (!isProProject(project)) return 'Free'\n return `${proTierName(project)} ${project.plan_interval === 'year' ? 'annual' : 'monthly'}`\n}\n\n/**\n * Maps a project's billing state to the `PlanBadge` block's label + tone.\n * Pro reads as accent, Free/dev as neutral, payment trouble or cancelling as pending.\n */\nexport function planBadgeView(\n project: ProjectBillingFields\n): Pick<PlanBadgeProps, 'label' | 'tone'> {\n const { subscription } = project\n const label =\n subscription === 'canceled'\n ? 'Cancelling'\n : subscription === 'dev'\n ? 'Dev'\n : isProProject(project)\n ? proTierName(project)\n : 'Free'\n\n const tone =\n subscription === 'dev'\n ? 'dev'\n : subscription === 'canceled' || subscription === 'past_due'\n ? 'pending'\n : isProProject(project)\n ? 'paid'\n : 'free'\n\n return { label, tone }\n}\n","/**\n * What a project's group in the workspace list says about the project itself: its plan badge (own\n * projects, where plans are sold), the usage readout beside its name, and the plan and limits\n * breakdown behind the name. One source for the cards' bands and the table's headings.\n */\nimport type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport type { components } from '@arbidocs/client'\nimport { UsageMeter } from '../../components/UsageMeter'\nimport { PlanBadge, QuotaMeter } from '../../settings'\nimport { ProjectBreakdown, ProjectReadout } from '../../home/ProjectBandParts'\nimport { planBadgeView } from '../billing/plan-badge'\nimport { getQuotaItems } from '../billing/quota-items'\n\ntype Project = components['schemas']['ProjectResponse']\n\nexport interface ProjectGroupBilling {\n /** The plan badge: own projects only, where plans are sold. */\n planBadge?: ReactNode\n /** Plan and usage, right after the name (projects with quotas). */\n readout?: ReactNode\n /** The plan and limits panel behind the name; meters for own projects only. */\n breakdown?: ReactNode\n}\n\nexport function projectGroupBilling(\n project: Project | undefined,\n { isOwned, stripeEnabled }: { isOwned: boolean; stripeEnabled: boolean }\n): ProjectGroupBilling {\n if (!project) return {}\n const planBadge = isOwned && stripeEnabled ? <PlanBadge {...planBadgeView(project)} /> : undefined\n const quotaItems = project.quotas ? getQuotaItems(project.quotas) : []\n const readout = project.quotas ? (\n <ProjectReadout\n plan={\n planBadge ? { badge: planBadge, testId: `project-tier-${project.external_id}` } : undefined\n }\n usage={{\n testId: `project-usage-${project.external_id}`,\n // Bare numbers without plans for sale: a glance beside the name, not the Plan & Usage detail.\n node: (\n <QuotaMeter\n items={quotaItems}\n size=\"sm\"\n showTooltips={false}\n showBars={stripeEnabled}\n showPercent={false}\n />\n ),\n }}\n />\n ) : (\n planBadge\n )\n const breakdown = (\n <ProjectBreakdown\n name={project.name}\n badge={planBadge}\n meters={\n isOwned\n ? quotaItems.map(({ key, icon, label, usedOfLimit, pct }) => (\n <UsageMeter\n key={key}\n icon={icon as LucideIcon}\n label={label}\n value={usedOfLimit}\n pct={pct}\n />\n ))\n : undefined\n }\n dailyCap={{\n label: 'Daily cap',\n value:\n project.daily_cap_per_user == null\n ? 'No limit'\n : project.daily_cap_per_user.toLocaleString('en-US'),\n }}\n />\n )\n return { planBadge, readout, breakdown }\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var chunkIRY63R4L_cjs = require('./chunk-IRY63R4L.cjs');
|
|
5
4
|
var chunkUWIILWDI_cjs = require('./chunk-UWIILWDI.cjs');
|
|
5
|
+
var chunkIRY63R4L_cjs = require('./chunk-IRY63R4L.cjs');
|
|
6
6
|
var chunkZESMRGDV_cjs = require('./chunk-ZESMRGDV.cjs');
|
|
7
7
|
var chunkGMM3RBIB_cjs = require('./chunk-GMM3RBIB.cjs');
|
|
8
8
|
var chunkULWRNGGE_cjs = require('./chunk-ULWRNGGE.cjs');
|
|
@@ -763,5 +763,5 @@ exports.SignButton = SignButton;
|
|
|
763
763
|
exports.SignatureRequestBanner = SignatureRequestBanner;
|
|
764
764
|
exports.SignedEditNote = SignedEditNote;
|
|
765
765
|
exports.VersionSnapshotBar = VersionSnapshotBar;
|
|
766
|
-
//# sourceMappingURL=chunk-
|
|
767
|
-
//# sourceMappingURL=chunk-
|
|
766
|
+
//# sourceMappingURL=chunk-CKNUL4LM.cjs.map
|
|
767
|
+
//# sourceMappingURL=chunk-CKNUL4LM.cjs.map
|