@crouton-kit/crouter 0.3.28 → 0.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-root.d.ts +15 -7
- package/dist/build-root.js +48 -34
- package/dist/builtin-memory/crouter-development/marketplaces.md +7 -6
- package/dist/builtin-memory/crouter-development/personas/base-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas/orchestrator-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas.md +1 -1
- package/dist/builtin-memory/crouter-development/plugins.md +20 -18
- package/dist/builtin-memory/design.md +1 -1
- package/dist/builtin-memory/development.md +1 -1
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/planning.md +1 -1
- package/dist/builtin-memory/spec.md +6 -4
- package/dist/builtin-personas/orchestration-kernel.md +4 -5
- package/dist/builtin-personas/runtime-base.md +5 -4
- package/dist/builtin-personas/spec/PERSONA.md +8 -4
- package/dist/builtin-personas/spec/orchestrator.md +5 -3
- package/dist/builtin-personas/spec/requirements/PERSONA.md +10 -0
- package/dist/builtin-views/canvas/core.mjs +586 -0
- package/dist/builtin-views/canvas/text.mjs +58 -0
- package/dist/builtin-views/canvas/tui.mjs +165 -0
- package/dist/builtin-views/canvas/web.jsx +120 -0
- package/dist/builtin-views/git-pr/core.mjs +673 -0
- package/dist/builtin-views/git-pr/text.mjs +84 -0
- package/dist/builtin-views/git-pr/tui.mjs +302 -0
- package/dist/builtin-views/git-pr/web.jsx +216 -0
- package/dist/builtin-views/inbox/_lib/render.mjs +1 -3
- package/dist/builtin-views/inbox/core.mjs +1273 -0
- package/dist/builtin-views/inbox/text.mjs +73 -0
- package/dist/builtin-views/inbox/tui.mjs +312 -0
- package/dist/builtin-views/inbox/web.jsx +188 -0
- package/dist/builtin-views/linkedin/core.mjs +906 -0
- package/dist/builtin-views/linkedin/text.mjs +69 -0
- package/dist/builtin-views/linkedin/tui.mjs +427 -0
- package/dist/builtin-views/linkedin/web.jsx +206 -0
- package/dist/builtin-views/workspace-sidebar/core.mjs +621 -0
- package/dist/builtin-views/workspace-sidebar/text.mjs +53 -0
- package/dist/builtin-views/workspace-sidebar/tui.mjs +142 -0
- package/dist/builtin-views/workspace-sidebar/web.jsx +109 -0
- package/dist/cli.js +22 -17
- package/dist/clients/attach/__tests__/action-parity.test.js +48 -0
- package/dist/clients/attach/__tests__/clipboard-image.test.js +76 -0
- package/dist/clients/attach/__tests__/editor-newline.test.js +57 -0
- package/dist/clients/attach/__tests__/git-info.test.js +31 -0
- package/dist/clients/attach/__tests__/onrequest-wired.test.js +20 -0
- package/dist/clients/attach/__tests__/slash-quit-copy.test.js +42 -0
- package/dist/clients/attach/__tests__/titled-editor.test.js +39 -0
- package/dist/clients/attach/attach-cmd.js +282 -46
- package/dist/clients/attach/auth-pickers.d.ts +9 -0
- package/dist/clients/attach/auth-pickers.js +194 -0
- package/dist/clients/attach/canvas-panels.d.ts +4 -2
- package/dist/clients/attach/canvas-panels.js +45 -17
- package/dist/clients/attach/chat-view.d.ts +27 -2
- package/dist/clients/attach/chat-view.js +98 -9
- package/dist/clients/attach/clipboard-image.d.ts +47 -8
- package/dist/clients/attach/clipboard-image.js +150 -26
- package/dist/clients/attach/clipboard-text.d.ts +3 -0
- package/dist/clients/attach/clipboard-text.js +39 -0
- package/dist/clients/attach/config-load.d.ts +54 -7
- package/dist/clients/attach/config-load.js +99 -3
- package/dist/clients/attach/context-message.d.ts +12 -0
- package/dist/clients/attach/context-message.js +72 -0
- package/dist/clients/attach/git-info.d.ts +20 -0
- package/dist/clients/attach/git-info.js +44 -0
- package/dist/clients/attach/graph-overlay.d.ts +13 -4
- package/dist/clients/attach/graph-overlay.js +59 -19
- package/dist/clients/attach/input-controller.d.ts +75 -13
- package/dist/clients/attach/input-controller.js +305 -67
- package/dist/clients/attach/pickers.d.ts +58 -0
- package/dist/clients/attach/pickers.js +171 -0
- package/dist/clients/attach/slash-commands.d.ts +22 -0
- package/dist/clients/attach/slash-commands.js +91 -25
- package/dist/clients/attach/titled-editor.d.ts +33 -0
- package/dist/clients/attach/titled-editor.js +84 -0
- package/dist/clients/attach/view-socket.d.ts +18 -1
- package/dist/clients/attach/view-socket.js +70 -1
- package/dist/clients/web/dev-server.d.ts +7 -0
- package/dist/clients/web/dev-server.js +59 -0
- package/dist/clients/web/events.d.ts +14 -0
- package/dist/clients/web/events.js +151 -0
- package/dist/clients/web/server.d.ts +18 -0
- package/dist/clients/web/server.js +450 -0
- package/dist/clients/web/web-cmd.d.ts +2 -0
- package/dist/clients/web/web-cmd.js +120 -0
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/chord.js +4 -25
- package/dist/commands/dashboard.js +5 -1
- package/dist/commands/memory/__tests__/lint-schema.test.js +6 -6
- package/dist/commands/memory/lint.js +14 -2
- package/dist/commands/memory/read.js +2 -2
- package/dist/commands/memory/shared.d.ts +7 -1
- package/dist/commands/memory/shared.js +18 -3
- package/dist/commands/memory/write.js +8 -4
- package/dist/commands/memory.js +4 -4
- package/dist/commands/node.d.ts +1 -1
- package/dist/commands/node.js +64 -65
- package/dist/commands/pkg.js +1 -2
- package/dist/commands/revive.js +11 -3
- package/dist/commands/sys/sync.d.ts +1 -0
- package/dist/commands/sys/sync.js +187 -0
- package/dist/commands/sys.js +3 -2
- package/dist/commands/view-cycle.js +2 -2
- package/dist/commands/view-list.js +8 -8
- package/dist/commands/view-new.js +21 -17
- package/dist/commands/view-pick.js +1 -1
- package/dist/commands/view-run.js +35 -14
- package/dist/commands/view.js +8 -6
- package/dist/commands/workspace.d.ts +2 -0
- package/dist/commands/workspace.js +161 -0
- package/dist/core/__tests__/broker-double-spawn.test.d.ts +1 -0
- package/dist/core/__tests__/broker-double-spawn.test.js +143 -0
- package/dist/core/__tests__/broker-fork-seam.test.d.ts +1 -0
- package/dist/core/__tests__/broker-fork-seam.test.js +102 -0
- package/dist/core/__tests__/broker-sdk-wiring.test.js +2 -0
- package/dist/core/__tests__/child-death-wake.test.js +56 -111
- package/dist/core/__tests__/close.test.js +14 -20
- package/dist/core/__tests__/context-intro.test.js +19 -19
- package/dist/core/__tests__/daemon-boot.test.js +30 -23
- package/dist/core/__tests__/draw-style.test.js +1 -1
- package/dist/core/__tests__/error-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/error-stall-recycle.test.js +141 -0
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +17 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +22 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +25 -13
- package/dist/core/__tests__/fork.test.js +22 -5
- package/dist/core/__tests__/full/broker-control-preempt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-control-preempt.test.js +61 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +57 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +80 -0
- package/dist/core/__tests__/full/broker-pane-resolution.test.js +90 -0
- package/dist/core/__tests__/full/cascade-close.test.js +22 -8
- package/dist/core/__tests__/full/detach-focus.test.js +66 -169
- package/dist/core/__tests__/helpers/harness.d.ts +6 -9
- package/dist/core/__tests__/helpers/harness.js +19 -36
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +1 -0
- package/dist/core/__tests__/human-node-not-supervised.test.js +83 -0
- package/dist/core/__tests__/lifecycle.test.js +1 -19
- package/dist/core/__tests__/listing-completeness.test.js +2 -2
- package/dist/core/__tests__/live-mutation-verbs.test.js +5 -5
- package/dist/core/__tests__/memory-resolver.test.js +1 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -2
- package/dist/core/__tests__/refresh-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/refresh-stall-recycle.test.js +88 -0
- package/dist/core/__tests__/relaunch-root.test.d.ts +1 -0
- package/dist/core/__tests__/relaunch-root.test.js +114 -0
- package/dist/core/__tests__/reset.test.js +19 -79
- package/dist/core/__tests__/steer-note.test.js +9 -7
- package/dist/core/__tests__/tmux-surface.test.js +13 -7
- package/dist/core/bootstrap.d.ts +0 -3
- package/dist/core/bootstrap.js +1 -143
- package/dist/core/canvas/browse/__tests__/model.test.js +86 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +2 -1
- package/dist/core/canvas/browse/app.js +131 -8
- package/dist/core/canvas/browse/model.d.ts +23 -5
- package/dist/core/canvas/browse/model.js +68 -13
- package/dist/core/canvas/browse/render.d.ts +7 -1
- package/dist/core/canvas/browse/render.js +178 -47
- package/dist/core/canvas/canvas.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -4
- package/dist/core/canvas/focuses.js +7 -7
- package/dist/core/canvas/nav-model.js +8 -7
- package/dist/core/canvas/render.d.ts +68 -9
- package/dist/core/canvas/render.js +195 -61
- package/dist/core/canvas/types.d.ts +16 -23
- package/dist/core/config.js +1 -4
- package/dist/core/memory-resolver.js +43 -5
- package/dist/core/runtime/bearings.d.ts +1 -1
- package/dist/core/runtime/bearings.js +8 -8
- package/dist/core/runtime/branded-host.d.ts +16 -0
- package/dist/core/runtime/branded-host.js +127 -0
- package/dist/core/runtime/broker-protocol.d.ts +212 -6
- package/dist/core/runtime/broker.d.ts +4 -1
- package/dist/core/runtime/broker.js +494 -58
- package/dist/core/runtime/close.d.ts +12 -2
- package/dist/core/runtime/close.js +37 -16
- package/dist/core/runtime/front-door.js +6 -14
- package/dist/core/runtime/host.d.ts +14 -34
- package/dist/core/runtime/host.js +14 -50
- package/dist/core/runtime/launch.d.ts +12 -9
- package/dist/core/runtime/launch.js +27 -15
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +15 -19
- package/dist/core/runtime/nodes.d.ts +0 -55
- package/dist/core/runtime/nodes.js +6 -74
- package/dist/core/runtime/placement.d.ts +91 -335
- package/dist/core/runtime/placement.js +291 -858
- package/dist/core/runtime/promote.d.ts +2 -0
- package/dist/core/runtime/promote.js +24 -6
- package/dist/core/runtime/recap.d.ts +8 -0
- package/dist/core/runtime/recap.js +107 -0
- package/dist/core/runtime/recycle.js +25 -61
- package/dist/core/runtime/reset.d.ts +43 -37
- package/dist/core/runtime/reset.js +131 -218
- package/dist/core/runtime/revive.d.ts +9 -29
- package/dist/core/runtime/revive.js +40 -139
- package/dist/core/runtime/spawn.d.ts +15 -16
- package/dist/core/runtime/spawn.js +165 -194
- package/dist/core/runtime/surface-bg.d.ts +11 -0
- package/dist/core/runtime/surface-bg.js +68 -0
- package/dist/core/runtime/tmux.d.ts +15 -52
- package/dist/core/runtime/tmux.js +35 -99
- package/dist/core/scope.d.ts +1 -2
- package/dist/core/scope.js +1 -5
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.d.ts +1 -0
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.js +57 -0
- package/dist/core/skill-sync/builtins.d.ts +42 -0
- package/dist/core/skill-sync/builtins.js +112 -0
- package/dist/core/skill-sync/claude-plugins.d.ts +23 -0
- package/dist/core/skill-sync/claude-plugins.js +71 -0
- package/dist/core/skill-sync/engine.d.ts +42 -0
- package/dist/core/skill-sync/engine.js +633 -0
- package/dist/core/skill-sync/export.d.ts +23 -0
- package/dist/core/skill-sync/export.js +86 -0
- package/dist/core/skill-sync/manifest.d.ts +64 -0
- package/dist/core/skill-sync/manifest.js +181 -0
- package/dist/core/skill-sync/profile.d.ts +76 -0
- package/dist/core/skill-sync/profile.js +173 -0
- package/dist/core/skill-sync/snapshot.d.ts +57 -0
- package/dist/core/skill-sync/snapshot.js +120 -0
- package/dist/core/substrate/index.d.ts +1 -1
- package/dist/core/substrate/index.js +1 -1
- package/dist/core/substrate/injected-store.js +3 -3
- package/dist/core/substrate/on-read.js +68 -6
- package/dist/core/substrate/render.d.ts +8 -11
- package/dist/core/substrate/render.js +29 -43
- package/dist/core/substrate/schema.d.ts +10 -3
- package/dist/core/substrate/schema.js +6 -3
- package/dist/core/tui/host.d.ts +12 -4
- package/dist/core/tui/host.js +280 -149
- package/dist/core/view/bridge.d.ts +10 -0
- package/dist/core/view/bridge.js +31 -0
- package/dist/core/view/chrome.d.ts +9 -0
- package/dist/core/view/chrome.js +22 -0
- package/dist/core/view/contract.d.ts +171 -0
- package/dist/core/view/contract.js +23 -0
- package/dist/core/view/loader.d.ts +31 -0
- package/dist/core/view/loader.js +188 -0
- package/dist/core/view/transport-local.d.ts +7 -0
- package/dist/core/view/transport-local.js +70 -0
- package/dist/core/view/transport.d.ts +4 -0
- package/dist/core/view/transport.js +15 -0
- package/dist/daemon/crtrd.d.ts +38 -27
- package/dist/daemon/crtrd.js +303 -376
- package/dist/daemon/manage.js +6 -1
- package/dist/index.js +1 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +28 -20
- package/dist/pi-extensions/canvas-context-intro.js +4 -4
- package/dist/pi-extensions/canvas-doc-substrate.js +16 -16
- package/dist/pi-extensions/canvas-nav.js +5 -0
- package/dist/pi-extensions/canvas-recap.d.ts +37 -0
- package/dist/pi-extensions/canvas-recap.js +236 -0
- package/dist/pi-extensions/canvas-resume.js +2 -1
- package/dist/pi-extensions/canvas-stophook.d.ts +14 -12
- package/dist/pi-extensions/canvas-stophook.js +87 -101
- package/dist/pi-extensions/canvas-view.js +2 -1
- package/dist/pi-extensions/widget-order-bus.d.ts +6 -0
- package/dist/pi-extensions/widget-order-bus.js +34 -0
- package/dist/prompts/view.d.ts +2 -2
- package/dist/prompts/view.js +145 -73
- package/dist/types.d.ts +1 -6
- package/dist/types.js +1 -3
- package/dist/web/ViewChrome.d.ts +7 -0
- package/dist/web/ViewChrome.js +28 -0
- package/dist/web/ViewPane.d.ts +39 -0
- package/dist/web/ViewPane.js +48 -0
- package/dist/web/index.d.ts +6 -0
- package/dist/web/index.js +16 -0
- package/dist/web/runtime.d.ts +39 -0
- package/dist/web/runtime.js +133 -0
- package/dist/web/states.d.ts +24 -0
- package/dist/web/states.js +24 -0
- package/dist/web/transport-http.d.ts +5 -0
- package/dist/web/transport-http.js +28 -0
- package/dist/web-client/assets/index-BUvQb4hR.css +2 -0
- package/dist/web-client/assets/index-ClLQXYAE.js +10 -0
- package/dist/web-client/index.html +13 -0
- package/package.json +20 -6
- package/dist/builtin-views/canvas/client.mjs +0 -303
- package/dist/builtin-views/canvas/view.mjs +0 -576
- package/dist/builtin-views/git-pr/client.mjs +0 -440
- package/dist/builtin-views/git-pr/view.mjs +0 -675
- package/dist/builtin-views/inbox/sources/gmail.mjs +0 -965
- package/dist/builtin-views/inbox/sources/linkedin.mjs +0 -427
- package/dist/builtin-views/inbox/view.mjs +0 -889
- package/dist/builtin-views/linkedin/client.mjs +0 -610
- package/dist/builtin-views/linkedin/view.mjs +0 -1171
- package/dist/commands/pkg/bridge.d.ts +0 -1
- package/dist/commands/pkg/bridge.js +0 -137
- package/dist/commands/skill/author.d.ts +0 -3
- package/dist/commands/skill/author.js +0 -140
- package/dist/commands/skill/shared.d.ts +0 -3
- package/dist/commands/skill/shared.js +0 -19
- package/dist/commands/skill.d.ts +0 -2
- package/dist/commands/skill.js +0 -21
- package/dist/commands/tmux-spread.d.ts +0 -2
- package/dist/commands/tmux-spread.js +0 -144
- package/dist/core/__tests__/full/daemon-liveness-pane.full.test.js +0 -292
- package/dist/core/__tests__/full/placement-focus.test.js +0 -309
- package/dist/core/__tests__/full/placement-reconcile.test.js +0 -212
- package/dist/core/__tests__/full/placement-revive.test.js +0 -238
- package/dist/core/__tests__/full/placement-teardown.test.js +0 -297
- package/dist/core/__tests__/home-session.test.js +0 -186
- package/dist/core/__tests__/relaunch.test.js +0 -335
- package/dist/core/bridge-map.d.ts +0 -19
- package/dist/core/bridge-map.js +0 -73
- package/dist/core/tui/contract.d.ts +0 -83
- package/dist/core/tui/contract.js +0 -8
- package/dist/core/tui/loader.d.ts +0 -16
- package/dist/core/tui/loader.js +0 -94
- package/dist/prompts/skill.d.ts +0 -2
- package/dist/prompts/skill.js +0 -650
- /package/dist/{core/__tests__/full/daemon-liveness-pane.full.test.d.ts → clients/attach/__tests__/action-parity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-focus.test.d.ts → clients/attach/__tests__/clipboard-image.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-reconcile.test.d.ts → clients/attach/__tests__/editor-newline.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-revive.test.d.ts → clients/attach/__tests__/git-info.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-teardown.test.d.ts → clients/attach/__tests__/onrequest-wired.test.d.ts} +0 -0
- /package/dist/{core/__tests__/home-session.test.d.ts → clients/attach/__tests__/slash-quit-copy.test.d.ts} +0 -0
- /package/dist/{core/__tests__/relaunch.test.d.ts → clients/attach/__tests__/titled-editor.test.d.ts} +0 -0
package/dist/types.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export interface PluginManifest {
|
|
|
20
20
|
source?: string;
|
|
21
21
|
owner?: OwnerRef;
|
|
22
22
|
kinds?: string[];
|
|
23
|
-
generator?: 'claude-bridge';
|
|
24
23
|
}
|
|
25
24
|
export interface MarketplacePluginEntry {
|
|
26
25
|
name: string;
|
|
@@ -80,10 +79,6 @@ export interface ScopeConfig {
|
|
|
80
79
|
auto_update: AutoUpdateConfig;
|
|
81
80
|
max_panes_per_window: number;
|
|
82
81
|
canvasNav: CanvasNavConfig;
|
|
83
|
-
/** Default to spawning nodes on the headless broker host instead of a tmux
|
|
84
|
-
* pane. Off by default (tmux stays the default); `--headless` overrides it
|
|
85
|
-
* per-spawn. Read at spawn via `readConfig('user').headless`. */
|
|
86
|
-
headless?: boolean;
|
|
87
82
|
}
|
|
88
83
|
export interface ScopeState {
|
|
89
84
|
marketplaces: Record<string, {
|
|
@@ -155,7 +150,7 @@ export declare const AGENTS_DIR = "agents";
|
|
|
155
150
|
export declare const DEFAULT_MAX_PANES_PER_WINDOW = 3;
|
|
156
151
|
export declare function defaultScopeConfig(): ScopeConfig;
|
|
157
152
|
/** Built-in canvas-nav binds so an absent config still gives the intended UX.
|
|
158
|
-
* prefixBinds: g→GRAPH toggle (sentinel), m→focus manager
|
|
153
|
+
* prefixBinds: g→GRAPH toggle (sentinel), m→focus manager.
|
|
159
154
|
* 1..9 (focus report N) are generated by the menu layer, not literal entries.
|
|
160
155
|
* graphBinds: empty — built-in GRAPH keys are reserved, custom keys add on. */
|
|
161
156
|
export declare function defaultCanvasNavConfig(): CanvasNavConfig;
|
package/dist/types.js
CHANGED
|
@@ -32,11 +32,10 @@ export function defaultScopeConfig() {
|
|
|
32
32
|
auto_update: { crtr: 'notify', content: 'notify', interval_hours: 24 },
|
|
33
33
|
max_panes_per_window: DEFAULT_MAX_PANES_PER_WINDOW,
|
|
34
34
|
canvasNav: defaultCanvasNavConfig(),
|
|
35
|
-
headless: false,
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
/** Built-in canvas-nav binds so an absent config still gives the intended UX.
|
|
39
|
-
* prefixBinds: g→GRAPH toggle (sentinel), m→focus manager
|
|
38
|
+
* prefixBinds: g→GRAPH toggle (sentinel), m→focus manager.
|
|
40
39
|
* 1..9 (focus report N) are generated by the menu layer, not literal entries.
|
|
41
40
|
* graphBinds: empty — built-in GRAPH keys are reserved, custom keys add on. */
|
|
42
41
|
export function defaultCanvasNavConfig() {
|
|
@@ -45,7 +44,6 @@ export function defaultCanvasNavConfig() {
|
|
|
45
44
|
prefixBinds: {
|
|
46
45
|
g: { run: '__graph__', desc: 'graph view' },
|
|
47
46
|
m: { run: 'node focus {manager}', desc: 'focus manager' },
|
|
48
|
-
e: { run: 'canvas tmux-spread {self}', desc: 'expand to tmux' },
|
|
49
47
|
},
|
|
50
48
|
graphBinds: {},
|
|
51
49
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { deriveState } from '../core/view/chrome.js';
|
|
3
|
+
const CHIP_LABEL = {
|
|
4
|
+
working: 'working',
|
|
5
|
+
blocked: 'blocked',
|
|
6
|
+
attention: 'attention',
|
|
7
|
+
ready: 'ready',
|
|
8
|
+
idle: 'idle',
|
|
9
|
+
};
|
|
10
|
+
const CHIP_DOT = {
|
|
11
|
+
working: 'bg-blue-500',
|
|
12
|
+
blocked: 'bg-red-500',
|
|
13
|
+
attention: 'bg-amber-500',
|
|
14
|
+
ready: 'bg-green-500',
|
|
15
|
+
idle: 'bg-slate-400',
|
|
16
|
+
};
|
|
17
|
+
const BANNER_BAR = {
|
|
18
|
+
info: 'bg-slate-100 text-slate-800 border-slate-300',
|
|
19
|
+
action: 'bg-amber-100 text-amber-900 border-amber-300',
|
|
20
|
+
error: 'bg-red-100 text-red-900 border-red-300',
|
|
21
|
+
};
|
|
22
|
+
export function ViewChrome({ chrome, title, children }) {
|
|
23
|
+
// deriveState's contract: an explicit interaction mode overrides the derived
|
|
24
|
+
// chip, and each target's renderer applies that precedence. Web keeps the mode
|
|
25
|
+
// as its own header pill (the §4.1 web idiom) AND lets it win the chip.
|
|
26
|
+
const chip = chrome.mode ? 'attention' : deriveState(chrome);
|
|
27
|
+
return (_jsxs("div", { className: "min-h-screen bg-white text-slate-900", children: [_jsxs("header", { className: "flex items-center gap-3 border-b border-slate-200 px-4 py-2", children: [_jsx("h1", { className: "font-mono text-sm font-semibold", children: title }), chrome.subtitle ? (_jsxs("span", { className: "font-mono text-xs text-slate-400", children: ["\u00B7 ", chrome.subtitle] })) : null, chrome.mode ? (_jsx("span", { className: "rounded-full bg-slate-800 px-2 py-0.5 text-xs text-white", children: chrome.mode })) : null, _jsxs("span", { className: "ml-auto flex items-center gap-2 text-xs text-slate-500", children: [chrome.busy ? (_jsx("span", { className: "inline-block h-3 w-3 animate-spin rounded-full border-2 border-slate-300 border-t-slate-600" })) : null, _jsx("span", { className: `inline-block h-2 w-2 rounded-full ${CHIP_DOT[chip]}` }), _jsx("span", { children: CHIP_LABEL[chip] })] })] }), chrome.banner ? (_jsx("div", { className: `border-b px-4 py-1.5 font-mono text-xs ${BANNER_BAR[chrome.banner.level]}`, children: chrome.banner.msg })) : null, _jsx("main", { className: "px-4 py-3", children: children }), chrome.status ? (_jsx("footer", { className: "border-t border-slate-200 px-4 py-1.5 font-mono text-xs text-slate-500", children: chrome.status })) : null] }));
|
|
28
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { JSX, FunctionComponent } from 'react';
|
|
2
|
+
import type { ViewCore, ChromeState } from '../core/view/contract.js';
|
|
3
|
+
import { type IntentTap } from './runtime.js';
|
|
4
|
+
type ViewPropsWeb = {
|
|
5
|
+
state: unknown;
|
|
6
|
+
dispatch: (intent: string, payload?: unknown) => void;
|
|
7
|
+
chrome: ChromeState;
|
|
8
|
+
};
|
|
9
|
+
type WebComponent = FunctionComponent<ViewPropsWeb>;
|
|
10
|
+
export interface UseViewCoreOptions {
|
|
11
|
+
/** Frozen options map handed to core.init. */
|
|
12
|
+
options?: Record<string, string>;
|
|
13
|
+
/** Bridge endpoint for the HTTP transport; defaults to /__crtr/source. */
|
|
14
|
+
endpoint?: string;
|
|
15
|
+
/** The host TAP (§5): observe/intercept dispatched intents. */
|
|
16
|
+
onIntent?: IntentTap;
|
|
17
|
+
}
|
|
18
|
+
export interface ViewCoreHandle {
|
|
19
|
+
state: unknown;
|
|
20
|
+
chrome: ChromeState;
|
|
21
|
+
dispatch: (intent: string, payload?: unknown) => void;
|
|
22
|
+
/** Force an immediate refresh — the seam the shell calls on an SSE
|
|
23
|
+
* invalidation (Wave 3). */
|
|
24
|
+
refresh: () => void;
|
|
25
|
+
}
|
|
26
|
+
/** Run a view core client-side and bind it to React. Returns the live state +
|
|
27
|
+
* chrome + a dispatch (and a refresh seam). The onIntent tap is read fresh on
|
|
28
|
+
* every render, so a parent can change it without tearing down the view. */
|
|
29
|
+
export declare function useViewCore(core: ViewCore, opts?: UseViewCoreOptions): ViewCoreHandle;
|
|
30
|
+
/** Host any dual-target view as a React component: its web component wrapped in
|
|
31
|
+
* <ViewChrome>, driven by useViewCore. Pass onIntent to tap its intents. */
|
|
32
|
+
export declare function ViewPane({ core, View, options, endpoint, onIntent }: {
|
|
33
|
+
core: ViewCore;
|
|
34
|
+
View: WebComponent;
|
|
35
|
+
options?: Record<string, string>;
|
|
36
|
+
endpoint?: string;
|
|
37
|
+
onIntent?: IntentTap;
|
|
38
|
+
}): JSX.Element;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// ViewPane.tsx — the React surface for a dual-target view. <ViewPane> and its
|
|
3
|
+
// useViewCore hook are the composable replacement for the deleted imperative
|
|
4
|
+
// mount(): the shell hosts many views as ordinary React components instead of
|
|
5
|
+
// imperative createRoot calls.
|
|
6
|
+
//
|
|
7
|
+
// useViewCore wraps a createViewStore (runtime.tsx) — the framework-free dispatch
|
|
8
|
+
// loop — with the React lifecycle: it creates the store once (a ref), keeps the
|
|
9
|
+
// onIntent TAP fresh per render WITHOUT restarting, re-renders off the store's
|
|
10
|
+
// external-store surface (useSyncExternalStore), and starts/stops the auto-poll
|
|
11
|
+
// on mount/unmount.
|
|
12
|
+
//
|
|
13
|
+
// <ViewPane> = useViewCore + <ViewChrome> + the view's web component. When
|
|
14
|
+
// onIntent is undefined a ViewPane is byte-identical to the old standalone mount
|
|
15
|
+
// — the hosted view never knows it is in a shell.
|
|
16
|
+
import { createElement, useEffect, useRef, useSyncExternalStore } from 'react';
|
|
17
|
+
import { ViewChrome } from './ViewChrome.js';
|
|
18
|
+
import { createViewStore } from './runtime.js';
|
|
19
|
+
/** Run a view core client-side and bind it to React. Returns the live state +
|
|
20
|
+
* chrome + a dispatch (and a refresh seam). The onIntent tap is read fresh on
|
|
21
|
+
* every render, so a parent can change it without tearing down the view. */
|
|
22
|
+
export function useViewCore(core, opts = {}) {
|
|
23
|
+
const storeRef = useRef(null);
|
|
24
|
+
if (storeRef.current === null) {
|
|
25
|
+
storeRef.current = createViewStore(core, { options: opts.options, endpoint: opts.endpoint });
|
|
26
|
+
}
|
|
27
|
+
const store = storeRef.current;
|
|
28
|
+
// Keep the TAP fresh without recreating the store (which would restart the
|
|
29
|
+
// dispatch loop and lose state).
|
|
30
|
+
store.onIntent = opts.onIntent;
|
|
31
|
+
useSyncExternalStore(store.subscribe, store.getVersion, store.getVersion);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
store.start();
|
|
34
|
+
return () => store.stop();
|
|
35
|
+
}, [store]);
|
|
36
|
+
return {
|
|
37
|
+
state: store.getState(),
|
|
38
|
+
chrome: store.getChrome(),
|
|
39
|
+
dispatch: store.dispatch,
|
|
40
|
+
refresh: store.refresh,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Host any dual-target view as a React component: its web component wrapped in
|
|
44
|
+
* <ViewChrome>, driven by useViewCore. Pass onIntent to tap its intents. */
|
|
45
|
+
export function ViewPane({ core, View, options, endpoint, onIntent }) {
|
|
46
|
+
const { state, chrome, dispatch } = useViewCore(core, { options, endpoint, onIntent });
|
|
47
|
+
return (_jsx(ViewChrome, { chrome: chrome, title: core.manifest.title, children: createElement(View, { state, dispatch, chrome }) }));
|
|
48
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ViewPane, useViewCore } from './ViewPane.js';
|
|
2
|
+
export type { UseViewCoreOptions, ViewCoreHandle } from './ViewPane.js';
|
|
3
|
+
export { createViewStore } from './runtime.js';
|
|
4
|
+
export type { ViewStore, ViewStoreOptions, IntentTap } from './runtime.js';
|
|
5
|
+
export { ViewChrome } from './ViewChrome.js';
|
|
6
|
+
export { Loading, Empty, ErrorState, NotReady } from './states.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// index.ts — the public barrel for crtr's web runtime, published as the package
|
|
2
|
+
// `exports` subpath `@crouton-kit/crouter/web` (→ ./dist/web/index.js).
|
|
3
|
+
//
|
|
4
|
+
// A dual-target view's `web.jsx` imports the shared four-state vocabulary +
|
|
5
|
+
// (if it needs them) the chrome wrapper from here, via that stable specifier —
|
|
6
|
+
// NOT a relative path from builtin-views, which would break for user/project
|
|
7
|
+
// views living outside the package tree. The shell + dev Vite resolve this
|
|
8
|
+
// subpath against crouter's own built barrel.
|
|
9
|
+
//
|
|
10
|
+
// The web shell composes views via <ViewPane>/useViewCore (the React surface)
|
|
11
|
+
// over createViewStore (the framework-free dispatch loop + the onIntent tap +
|
|
12
|
+
// the refresh() SSE seam).
|
|
13
|
+
export { ViewPane, useViewCore } from './ViewPane.js';
|
|
14
|
+
export { createViewStore } from './runtime.js';
|
|
15
|
+
export { ViewChrome } from './ViewChrome.js';
|
|
16
|
+
export { Loading, Empty, ErrorState, NotReady } from './states.js';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ViewCore, ChromeState } from '../core/view/contract.js';
|
|
2
|
+
/** Host-level pre-dispatch hook: observes every dispatched intent + its payload
|
|
3
|
+
* against a snapshot of state, before the view's own handler runs. The shell
|
|
4
|
+
* taps the small documented shell-intent vocabulary (`activate`, `open`) and
|
|
5
|
+
* lets everything else pass through untouched. */
|
|
6
|
+
export type IntentTap = (name: string, payload: unknown, state: unknown) => void;
|
|
7
|
+
export interface ViewStoreOptions {
|
|
8
|
+
/** Frozen options map handed to core.init (e.g. forwarded --target). */
|
|
9
|
+
options?: Record<string, string>;
|
|
10
|
+
/** Bridge endpoint for the HTTP transport; defaults to /__crtr/source. */
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/** The host TAP (§5). Omit ⇒ standalone, byte-identical to no shell. */
|
|
13
|
+
onIntent?: IntentTap;
|
|
14
|
+
}
|
|
15
|
+
export interface ViewStore {
|
|
16
|
+
/** Snapshot of the current view state (read after a subscribe fires). */
|
|
17
|
+
getState(): unknown;
|
|
18
|
+
/** Snapshot of the current chrome record. */
|
|
19
|
+
getChrome(): ChromeState;
|
|
20
|
+
/** Dispatch a named intent — runs the TAP, then the core handler. */
|
|
21
|
+
dispatch(intent: string, payload?: unknown): Promise<void>;
|
|
22
|
+
/** Force an immediate, busy-guarded refresh (auto-poll cb + the SSE seam). */
|
|
23
|
+
refresh(): void;
|
|
24
|
+
/** External-store subscribe (for useSyncExternalStore). */
|
|
25
|
+
subscribe(listener: () => void): () => void;
|
|
26
|
+
/** Monotonic version the external store snapshots on. */
|
|
27
|
+
getVersion(): number;
|
|
28
|
+
/** Run the first refresh + start the refreshMs auto-poll. Idempotent. */
|
|
29
|
+
start(): void;
|
|
30
|
+
/** Stop the auto-poll. Idempotent. */
|
|
31
|
+
stop(): void;
|
|
32
|
+
/** The host TAP — mutable so the React layer keeps it fresh per render
|
|
33
|
+
* WITHOUT restarting the store. */
|
|
34
|
+
onIntent?: IntentTap;
|
|
35
|
+
}
|
|
36
|
+
/** Build the running store for one view (its core + the HTTP transport). The
|
|
37
|
+
* React layer (useViewCore) owns lifecycle (start on mount, stop on unmount)
|
|
38
|
+
* and re-renders off subscribe/getVersion; this factory is React-free. */
|
|
39
|
+
export declare function createViewStore(core: ViewCore, opts?: ViewStoreOptions): ViewStore;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// runtime.tsx — the framework-agnostic dispatch-loop STORE for a dual-target
|
|
2
|
+
// view. It is what <ViewPane>/useViewCore (ViewPane.tsx) are built from.
|
|
3
|
+
//
|
|
4
|
+
// createViewStore() seeds state from core.init, builds the IntentCtx
|
|
5
|
+
// (set/resolve/execute/signal/dispatch) over the HTTP transport (→ the local
|
|
6
|
+
// bridge), runs the dispatch loop with the busy-guarded refreshMs auto-poll, and
|
|
7
|
+
// exposes a tiny external-store surface (subscribe/getVersion) the React layer
|
|
8
|
+
// binds via useSyncExternalStore. The core it drives is byte-identical to the
|
|
9
|
+
// TUI's; only the injected Transport differs.
|
|
10
|
+
//
|
|
11
|
+
// THE TAP: dispatch calls `onIntent(name, payload, state)` BEFORE delegating to
|
|
12
|
+
// core.intents[name]. This is the host-level pre-dispatch hook the shell uses to
|
|
13
|
+
// observe/intercept semantic intents (e.g. canvas `activate` → open a
|
|
14
|
+
// conversation). When onIntent is undefined the loop is byte-identical to the
|
|
15
|
+
// pre-shell behavior — a view in a ViewPane is unaware it is in a shell.
|
|
16
|
+
//
|
|
17
|
+
// THE SEAM (Wave 3): store.refresh() forces an immediate, busy-guarded refresh.
|
|
18
|
+
// It is both the auto-poll callback AND the entry point the shell calls when an
|
|
19
|
+
// SSE `/__crtr/events` invalidation arrives — event-driven refresh with no
|
|
20
|
+
// contract change (the view still just runs its `refresh` intent).
|
|
21
|
+
import { initialChrome } from '../core/view/chrome.js';
|
|
22
|
+
import { createHttpTransport } from './transport-http.js';
|
|
23
|
+
/** Build the running store for one view (its core + the HTTP transport). The
|
|
24
|
+
* React layer (useViewCore) owns lifecycle (start on mount, stop on unmount)
|
|
25
|
+
* and re-renders off subscribe/getVersion; this factory is React-free. */
|
|
26
|
+
export function createViewStore(core, opts = {}) {
|
|
27
|
+
const transport = createHttpTransport(opts.endpoint);
|
|
28
|
+
let state = core.init(Object.freeze({ ...(opts.options ?? {}) }));
|
|
29
|
+
let chrome = initialChrome();
|
|
30
|
+
let onIntentTap = opts.onIntent;
|
|
31
|
+
// External store: a version counter the React tree subscribes to. state and
|
|
32
|
+
// chrome are read via the getters on each render; bumping `version` re-renders.
|
|
33
|
+
let version = 0;
|
|
34
|
+
const listeners = new Set();
|
|
35
|
+
const emit = () => { version += 1; for (const l of listeners)
|
|
36
|
+
l(); };
|
|
37
|
+
const subscribe = (l) => { listeners.add(l); return () => { listeners.delete(l); }; };
|
|
38
|
+
const setChrome = (patch) => { chrome = { ...chrome, ...patch }; emit(); };
|
|
39
|
+
const signal = {
|
|
40
|
+
setStatus: (msg) => setChrome({ status: msg }),
|
|
41
|
+
setBanner: (msg, level) => setChrome({ banner: { msg, level } }),
|
|
42
|
+
clearBanner: () => setChrome({ banner: null }),
|
|
43
|
+
setSubtitle: (s) => setChrome({ subtitle: s }),
|
|
44
|
+
setMode: (mode) => setChrome({ mode }),
|
|
45
|
+
// Web has no pane to leave; closing the tab is up to the user. No-op.
|
|
46
|
+
quit: () => { },
|
|
47
|
+
};
|
|
48
|
+
const makeCtx = () => ({
|
|
49
|
+
get state() { return state; },
|
|
50
|
+
set(next) {
|
|
51
|
+
state = typeof next === 'function' ? next(state) : next;
|
|
52
|
+
emit();
|
|
53
|
+
},
|
|
54
|
+
async resolve(source, args) {
|
|
55
|
+
const raw = await transport.send(source.request(args));
|
|
56
|
+
return source.parse(raw);
|
|
57
|
+
},
|
|
58
|
+
async execute(command, args) {
|
|
59
|
+
const raw = await transport.send(command.request(args));
|
|
60
|
+
return command.parse(raw);
|
|
61
|
+
},
|
|
62
|
+
signal,
|
|
63
|
+
dispatch,
|
|
64
|
+
});
|
|
65
|
+
// busyDepth counts in-flight async intents — it drives the "working" chip /
|
|
66
|
+
// spinner. It is NOT itself the single-flight lane; the auto-poll guards on it
|
|
67
|
+
// (refresh() below) so a bridge slower than refreshMs can never stack
|
|
68
|
+
// overlapping refreshes that race on ctx.set. The first completed *refresh*
|
|
69
|
+
// marks the view loaded (ready vs idle in deriveState) — a non-refresh async
|
|
70
|
+
// intent before that must not flip the chip to ready.
|
|
71
|
+
let busyDepth = 0;
|
|
72
|
+
async function dispatch(intent, payload) {
|
|
73
|
+
// THE TAP — the shell observes (and may act on) every intent against a
|
|
74
|
+
// snapshot of state BEFORE the view's own handler runs. Standalone (no tap)
|
|
75
|
+
// this is a no-op and the loop is byte-identical to the pre-shell behavior.
|
|
76
|
+
onIntentTap?.(intent, payload, state);
|
|
77
|
+
const fn = core.intents[intent];
|
|
78
|
+
if (!fn) {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.warn(`[crtr view] unknown intent: ${intent}`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const result = fn(makeCtx(), payload);
|
|
84
|
+
if (result instanceof Promise) {
|
|
85
|
+
busyDepth += 1;
|
|
86
|
+
setChrome({ busy: true });
|
|
87
|
+
try {
|
|
88
|
+
await result;
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
busyDepth -= 1;
|
|
92
|
+
const loaded = chrome.loaded || intent === 'refresh';
|
|
93
|
+
chrome = { ...chrome, busy: busyDepth > 0, loaded, lastRefresh: Date.now() };
|
|
94
|
+
emit();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Auto-poll cadence guard AND the shell's invalidate seam: skip while any
|
|
99
|
+
// async intent is still in flight so refreshes never stack.
|
|
100
|
+
const refresh = () => { if (busyDepth === 0)
|
|
101
|
+
void dispatch('refresh'); };
|
|
102
|
+
let started = false;
|
|
103
|
+
let timer = null;
|
|
104
|
+
function start() {
|
|
105
|
+
if (started)
|
|
106
|
+
return;
|
|
107
|
+
started = true;
|
|
108
|
+
// init → render (the React layer) → first refresh, then optional auto-poll.
|
|
109
|
+
void dispatch('refresh');
|
|
110
|
+
const cadence = core.manifest.refreshMs;
|
|
111
|
+
if (typeof cadence === 'number' && cadence > 0)
|
|
112
|
+
timer = setInterval(refresh, cadence);
|
|
113
|
+
}
|
|
114
|
+
function stop() {
|
|
115
|
+
started = false;
|
|
116
|
+
if (timer) {
|
|
117
|
+
clearInterval(timer);
|
|
118
|
+
timer = null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
getState: () => state,
|
|
123
|
+
getChrome: () => chrome,
|
|
124
|
+
dispatch,
|
|
125
|
+
refresh,
|
|
126
|
+
subscribe,
|
|
127
|
+
getVersion: () => version,
|
|
128
|
+
start,
|
|
129
|
+
stop,
|
|
130
|
+
get onIntent() { return onIntentTap; },
|
|
131
|
+
set onIntent(v) { onIntentTap = v; },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
/** Initial load, before the first source resolves. */
|
|
3
|
+
export declare function Loading({ label }: {
|
|
4
|
+
label?: string;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
/** Resolved, but nothing to show. */
|
|
7
|
+
export declare function Empty({ label }: {
|
|
8
|
+
label?: string;
|
|
9
|
+
}): JSX.Element;
|
|
10
|
+
/** A non-blocking-or-blocking failure — renders a SourceError.display verbatim. */
|
|
11
|
+
export declare function ErrorState({ headline, explanation, nextStep, onRetry }: {
|
|
12
|
+
headline: string;
|
|
13
|
+
explanation?: string;
|
|
14
|
+
nextStep?: string;
|
|
15
|
+
onRetry?: () => void;
|
|
16
|
+
}): JSX.Element;
|
|
17
|
+
/** A precondition isn't met (e.g. not a repo / unauthed) — same shape as
|
|
18
|
+
* ErrorState but named for the "not ready to run here" case. */
|
|
19
|
+
export declare function NotReady({ headline, explanation, nextStep, onRetry }: {
|
|
20
|
+
headline?: string;
|
|
21
|
+
explanation?: string;
|
|
22
|
+
nextStep?: string;
|
|
23
|
+
onRetry?: () => void;
|
|
24
|
+
}): JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function Center({ children }) {
|
|
3
|
+
return (_jsx("div", { className: "flex min-h-[40vh] flex-col items-center justify-center gap-2 p-8 text-center font-mono text-sm text-slate-600", children: children }));
|
|
4
|
+
}
|
|
5
|
+
/** Initial load, before the first source resolves. */
|
|
6
|
+
export function Loading({ label = 'Loading…' }) {
|
|
7
|
+
return (_jsxs(Center, { children: [_jsx("span", { className: "inline-block h-3 w-3 animate-spin rounded-full border-2 border-slate-300 border-t-slate-600" }), _jsx("span", { children: label })] }));
|
|
8
|
+
}
|
|
9
|
+
/** Resolved, but nothing to show. */
|
|
10
|
+
export function Empty({ label = 'Nothing here yet.' }) {
|
|
11
|
+
return (_jsx(Center, { children: _jsx("span", { className: "text-slate-400", children: label }) }));
|
|
12
|
+
}
|
|
13
|
+
/** A non-blocking-or-blocking failure — renders a SourceError.display verbatim. */
|
|
14
|
+
export function ErrorState({ headline, explanation, nextStep, onRetry }) {
|
|
15
|
+
return (_jsxs(Center, { children: [_jsx("div", { className: "font-semibold text-red-700", children: headline }), explanation ? _jsx("div", { className: "text-slate-600", children: explanation }) : null, nextStep ? _jsx("div", { className: "text-slate-500", children: nextStep }) : null, onRetry ? _jsx(RetryButton, { onRetry: onRetry }) : null] }));
|
|
16
|
+
}
|
|
17
|
+
/** A precondition isn't met (e.g. not a repo / unauthed) — same shape as
|
|
18
|
+
* ErrorState but named for the "not ready to run here" case. */
|
|
19
|
+
export function NotReady({ headline = 'Not ready', explanation, nextStep, onRetry }) {
|
|
20
|
+
return (_jsxs(Center, { children: [_jsx("div", { className: "font-semibold text-amber-700", children: headline }), explanation ? _jsx("div", { className: "text-slate-600", children: explanation }) : null, nextStep ? _jsx("div", { className: "text-slate-500", children: nextStep }) : null, onRetry ? _jsx(RetryButton, { onRetry: onRetry }) : null] }));
|
|
21
|
+
}
|
|
22
|
+
function RetryButton({ onRetry }) {
|
|
23
|
+
return (_jsx("button", { type: "button", onClick: onRetry, className: "mt-2 rounded border border-slate-300 px-3 py-1 text-slate-700 hover:bg-slate-100", children: "Retry" }));
|
|
24
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Transport } from '../core/view/transport.js';
|
|
2
|
+
/** Browser Transport → POST <endpoint> {SourceRequest} → RawResponse. Never
|
|
3
|
+
* throws: a network/bridge failure becomes a transport-level RawResponse
|
|
4
|
+
* (ok:false + stderr), exactly like the local transport's spawn failures. */
|
|
5
|
+
export declare function createHttpTransport(endpoint?: string): Transport;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// transport-http.ts — the browser-side Transport. Posts a view's declarative
|
|
2
|
+
// SourceRequest to the local bridge server (`crtr view serve`'s /__crtr/source)
|
|
3
|
+
// and returns the RawResponse the bridge ran on its behalf. This is the ONE
|
|
4
|
+
// seam a cloud deploy swaps: point the endpoint at a real backend and the same
|
|
5
|
+
// browser bundle resolves sources against it, no core change.
|
|
6
|
+
/** Browser Transport → POST <endpoint> {SourceRequest} → RawResponse. Never
|
|
7
|
+
* throws: a network/bridge failure becomes a transport-level RawResponse
|
|
8
|
+
* (ok:false + stderr), exactly like the local transport's spawn failures. */
|
|
9
|
+
export function createHttpTransport(endpoint = '/__crtr/source') {
|
|
10
|
+
return {
|
|
11
|
+
async send(req) {
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetch(endpoint, {
|
|
14
|
+
method: 'POST',
|
|
15
|
+
headers: { 'content-type': 'application/json' },
|
|
16
|
+
body: JSON.stringify(req),
|
|
17
|
+
});
|
|
18
|
+
if (!res.ok) {
|
|
19
|
+
return { ok: false, stdout: '', stderr: `bridge ${res.status} ${res.statusText}` };
|
|
20
|
+
}
|
|
21
|
+
return (await res.json());
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
return { ok: false, stdout: '', stderr: e instanceof Error ? e.message : String(e) };
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-900:oklch(39.6% .141 25.723);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-900:oklch(41.4% .112 45.904);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-600:oklch(60.9% .126 221.723);--color-cyan-700:oklch(52% .105 223.128);--color-sky-50:oklch(97.7% .013 236.62);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-600:oklch(58.8% .158 241.966);--color-sky-700:oklch(50% .134 242.749);--color-blue-500:oklch(62.3% .214 259.815);--color-violet-600:oklch(54.1% .281 293.009);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.inset-0{inset:0}.top-full{top:100%}.right-0{right:0}.bottom-20{bottom:calc(var(--spacing) * 20)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.my-1{margin-block:var(--spacing)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-px{margin-top:1px}.mr-3{margin-right:calc(var(--spacing) * 3)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:var(--spacing)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-full{height:100%}.h-screen{height:100vh}.max-h-64{max-height:calc(var(--spacing) * 64)}.min-h-0{min-height:0}.min-h-\[40vh\]{min-height:40vh}.min-h-screen{min-height:100vh}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-2\/5{width:40%}.w-3{width:calc(var(--spacing) * 3)}.w-44{width:calc(var(--spacing) * 44)}.w-full{width:100%}.w-screen{width:100vw}.max-w-\[14rem\]{max-width:14rem}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}:where(.divide-slate-200>:not(:last-child)){border-color:var(--color-slate-200)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-amber-300{border-color:var(--color-amber-300)}.border-cyan-500{border-color:var(--color-cyan-500)}.border-green-500{border-color:var(--color-green-500)}.border-green-600{border-color:var(--color-green-600)}.border-red-200{border-color:var(--color-red-200)}.border-red-300{border-color:var(--color-red-300)}.border-sky-200{border-color:var(--color-sky-200)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-transparent{border-color:#0000}.border-t-slate-600{border-top-color:var(--color-slate-600)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-amber-400{background-color:var(--color-amber-400)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-600\/90{background-color:#dd7400e6}@supports (color:color-mix(in lab, red, red)){.bg-amber-600\/90{background-color:color-mix(in oklab, var(--color-amber-600) 90%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-green-500{background-color:var(--color-green-500)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-sky-50{background-color:var(--color-sky-50)}.bg-sky-600{background-color:var(--color-sky-600)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-400{background-color:var(--color-slate-400)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-800{background-color:var(--color-slate-800)}.bg-slate-900\/40{background-color:#0f172b66}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/40{background-color:color-mix(in oklab, var(--color-slate-900) 40%, transparent)}}.bg-white{background-color:var(--color-white)}.bg-white\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-white\/85{background-color:color-mix(in oklab, var(--color-white) 85%, transparent)}}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-500{color:var(--color-amber-500)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-amber-900{color:var(--color-amber-900)}.text-cyan-600{color:var(--color-cyan-600)}.text-cyan-700{color:var(--color-cyan-700)}.text-emerald-600{color:var(--color-emerald-600)}.text-green-600{color:var(--color-green-600)}.text-green-700{color:var(--color-green-700)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-900{color:var(--color-red-900)}.text-sky-500{color:var(--color-sky-500)}.text-sky-600{color:var(--color-sky-600)}.text-sky-700{color:var(--color-sky-700)}.text-slate-400{color:var(--color-slate-400)}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-transparent{color:#0000}.text-violet-600{color:var(--color-violet-600)}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.uppercase{text-transform:uppercase}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:border-sky-600:hover{border-color:var(--color-sky-600)}.hover\:bg-red-500:hover{background-color:var(--color-red-500)}.hover\:bg-sky-500:hover{background-color:var(--color-sky-500)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-100:hover{background-color:var(--color-slate-100)}.hover\:bg-slate-200:hover{background-color:var(--color-slate-200)}.hover\:bg-slate-800:hover{background-color:var(--color-slate-800)}.hover\:bg-white:hover{background-color:var(--color-white)}.hover\:bg-white\/60:hover{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/60:hover{background-color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.hover\:text-slate-600:hover{color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}}.focus\:border-amber-500:focus{border-color:var(--color-amber-500)}.focus\:border-sky-500:focus{border-color:var(--color-sky-500)}.focus\:border-slate-500:focus{border-color:var(--color-slate-500)}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}
|