@xenosystem/blocks 0.13.18 → 0.13.20
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/ops/index.d.ts +163 -13
- package/dist/ops/index.js +362 -283
- package/package.json +3 -3
package/dist/ops/index.d.ts
CHANGED
|
@@ -607,7 +607,7 @@ interface ConsoleViewOptions {
|
|
|
607
607
|
declare function consoleViewState(c: ConsoleController, options?: ConsoleViewOptions): ConsoleViewModel;
|
|
608
608
|
declare function applyConsoleUi(c: ConsoleController, intent: ConsoleUiIntent): void;
|
|
609
609
|
declare const consoleViewManifest: PanelManifest;
|
|
610
|
-
declare const BEHAVIOURS$
|
|
610
|
+
declare const BEHAVIOURS$2: {
|
|
611
611
|
'ops/consolePanelView': (inputs: Record<string, unknown>) => ConsoleViewModel;
|
|
612
612
|
};
|
|
613
613
|
/** The runtime-bound unit: the scroller the virtualizer measures and follow-mode pins. */
|
|
@@ -1518,7 +1518,7 @@ interface RunsViewOptions {
|
|
|
1518
1518
|
declare function runsViewState(c: RunsController, options?: RunsViewOptions): RunsViewModel;
|
|
1519
1519
|
declare function applyRunsUi(c: RunsController, intent: RunsUiIntent): void;
|
|
1520
1520
|
declare const runsViewManifest: PanelManifest;
|
|
1521
|
-
declare const BEHAVIOURS: {
|
|
1521
|
+
declare const BEHAVIOURS$1: {
|
|
1522
1522
|
'ops/runsPanelView': (inputs: Record<string, unknown>) => RunsViewModel;
|
|
1523
1523
|
};
|
|
1524
1524
|
declare const RUNS_RUNTIME_UNITS: readonly [];
|
|
@@ -2424,24 +2424,174 @@ declare const DIFF_PANEL_ID = "xeno.core.diff";
|
|
|
2424
2424
|
declare const diffManifest: PanelManifest;
|
|
2425
2425
|
|
|
2426
2426
|
/**
|
|
2427
|
-
* The Diff panel
|
|
2427
|
+
* The Diff panel AS A DECLARATION — the twentieth block written the §8d way.
|
|
2428
2428
|
*
|
|
2429
|
-
*
|
|
2430
|
-
*
|
|
2431
|
-
*
|
|
2432
|
-
* `RowList` — those rows are variable-height and this grid's correctness depends on them not being.
|
|
2429
|
+
* Presentation contract: input `view` (a {@link DiffViewModel} the runtime derives from the
|
|
2430
|
+
* controller on every draw — the status decided, every file, hunk and line as DATA), output `ui`
|
|
2431
|
+
* (a {@link DiffUiIntent}) applied by the runtime to the controller's own methods.
|
|
2433
2432
|
*
|
|
2434
|
-
*
|
|
2433
|
+
* A file is a `chrome/Section` (collapsible, the path as a case-keeping `Text` title, the status as its
|
|
2434
|
+
* badge, the counts as its actions); a
|
|
2435
|
+
* hunk is a `chrome/Hunk` (focused by the cursor, settled once applied, the range and the decision
|
|
2436
|
+
* chip in its header, the review actions at its end); a line is a `chrome/DiffLine` whose text is
|
|
2437
|
+
* RUNS — the host's word-level marks when it computed them (they carry more information than a
|
|
2438
|
+
* token colour, and a prose diff has no tokens at all), else the highlighter's tokens, else plain —
|
|
2439
|
+
* with whitespace made visible here, in the model, when asked. Split view pairs lines in a
|
|
2440
|
+
* `chrome/DiffSplitRow` with a blank side. No runtime-bound unit.
|
|
2441
|
+
*
|
|
2442
|
+
* Three facts the model keeps distinct because a reviewer reads them differently: a comparison that
|
|
2443
|
+
* FAILED has established nothing (never "no changes"); a file OMITTED (binary, too large) was not
|
|
2444
|
+
* compared (never an empty body); a decision in CONFLICT is not one that failed (the file moved, so
|
|
2445
|
+
* it must be made again).
|
|
2435
2446
|
*/
|
|
2436
2447
|
|
|
2437
|
-
/**
|
|
2438
|
-
interface
|
|
2439
|
-
controller: DiffController;
|
|
2448
|
+
/** The half of a renderer's config the view reads. */
|
|
2449
|
+
interface DiffViewOptions {
|
|
2440
2450
|
/** Optional syntax seam. No highlighter means plain text, never a missing panel. */
|
|
2441
2451
|
highlighter?: XenoDiffHighlighter;
|
|
2452
|
+
/** Show the review actions. */
|
|
2442
2453
|
review?: boolean;
|
|
2443
2454
|
}
|
|
2455
|
+
interface DiffViewRun {
|
|
2456
|
+
text: string;
|
|
2457
|
+
mark?: 'insert' | 'delete';
|
|
2458
|
+
token?: string;
|
|
2459
|
+
}
|
|
2460
|
+
interface DiffViewLine {
|
|
2461
|
+
key: string;
|
|
2462
|
+
kind: 'added' | 'removed' | 'context' | 'blank';
|
|
2463
|
+
gutter: (number | string)[];
|
|
2464
|
+
sigil?: string;
|
|
2465
|
+
runs: DiffViewRun[];
|
|
2466
|
+
}
|
|
2467
|
+
interface DiffViewSplitRow {
|
|
2468
|
+
key: string;
|
|
2469
|
+
left: DiffViewLine;
|
|
2470
|
+
right: DiffViewLine;
|
|
2471
|
+
}
|
|
2472
|
+
interface DiffViewHunk {
|
|
2473
|
+
key: string;
|
|
2474
|
+
path: string;
|
|
2475
|
+
id: string;
|
|
2476
|
+
header: string;
|
|
2477
|
+
focused: boolean;
|
|
2478
|
+
settled: boolean;
|
|
2479
|
+
chipPending: boolean;
|
|
2480
|
+
chipConflict: boolean;
|
|
2481
|
+
conflictTitle: string;
|
|
2482
|
+
chipFailed: boolean;
|
|
2483
|
+
failedTitle?: string;
|
|
2484
|
+
chipApplied: boolean;
|
|
2485
|
+
appliedText: string;
|
|
2486
|
+
/** Review actions shown; `attention` swaps accept/reject for re-review. */
|
|
2487
|
+
review: boolean;
|
|
2488
|
+
attention: boolean;
|
|
2489
|
+
deciding: boolean;
|
|
2490
|
+
unified: boolean;
|
|
2491
|
+
split: boolean;
|
|
2492
|
+
lines: DiffViewLine[];
|
|
2493
|
+
rows: DiffViewSplitRow[];
|
|
2494
|
+
}
|
|
2495
|
+
interface DiffViewFile {
|
|
2496
|
+
key: string;
|
|
2497
|
+
path: string;
|
|
2498
|
+
title: string;
|
|
2499
|
+
status: string;
|
|
2500
|
+
counts: string;
|
|
2501
|
+
collapsed: boolean;
|
|
2502
|
+
omitted: boolean;
|
|
2503
|
+
omission: string;
|
|
2504
|
+
hunks: DiffViewHunk[];
|
|
2505
|
+
}
|
|
2506
|
+
interface DiffViewModel {
|
|
2507
|
+
idle: boolean;
|
|
2508
|
+
computing: boolean;
|
|
2509
|
+
failed: boolean;
|
|
2510
|
+
failedHint: string;
|
|
2511
|
+
identical: boolean;
|
|
2512
|
+
active: boolean;
|
|
2513
|
+
view: XenoDiffView;
|
|
2514
|
+
views: {
|
|
2515
|
+
label: string;
|
|
2516
|
+
value: XenoDiffView;
|
|
2517
|
+
}[];
|
|
2518
|
+
wrap: boolean;
|
|
2519
|
+
wrapLabel: string;
|
|
2520
|
+
whitespaceLabel: string;
|
|
2521
|
+
conflictNotice?: string;
|
|
2522
|
+
files: DiffViewFile[];
|
|
2523
|
+
countLabel: string;
|
|
2524
|
+
rightLabel: string;
|
|
2525
|
+
}
|
|
2526
|
+
type DiffUiIntent = {
|
|
2527
|
+
kind: 'view';
|
|
2528
|
+
view: XenoDiffView;
|
|
2529
|
+
} | {
|
|
2530
|
+
kind: 'toggleWrap';
|
|
2531
|
+
} | {
|
|
2532
|
+
kind: 'toggleWhitespace';
|
|
2533
|
+
} | {
|
|
2534
|
+
kind: 'prev';
|
|
2535
|
+
} | {
|
|
2536
|
+
kind: 'next';
|
|
2537
|
+
} | {
|
|
2538
|
+
kind: 'collapse';
|
|
2539
|
+
path: string;
|
|
2540
|
+
collapsed: boolean;
|
|
2541
|
+
} | {
|
|
2542
|
+
kind: 'contextMenu';
|
|
2543
|
+
path: string;
|
|
2544
|
+
id: string;
|
|
2545
|
+
x: number;
|
|
2546
|
+
y: number;
|
|
2547
|
+
} | {
|
|
2548
|
+
kind: 'decide';
|
|
2549
|
+
path: string;
|
|
2550
|
+
id: string;
|
|
2551
|
+
action: 'accept' | 'reject';
|
|
2552
|
+
} | {
|
|
2553
|
+
kind: 'reReview';
|
|
2554
|
+
path: string;
|
|
2555
|
+
id: string;
|
|
2556
|
+
};
|
|
2557
|
+
/** Derive the view model from the live controller — the runtime calls this on every draw. */
|
|
2558
|
+
declare function diffViewState(c: DiffController, options?: DiffViewOptions): DiffViewModel;
|
|
2559
|
+
/** Apply a `ui` intent to the controller — the runtime's half of the contract. */
|
|
2560
|
+
declare function applyDiffUi(c: DiffController, intent: DiffUiIntent): void;
|
|
2561
|
+
declare const diffViewManifest: PanelManifest;
|
|
2562
|
+
declare const BEHAVIOURS: {
|
|
2563
|
+
'ops/diffPanelView': (inputs: Record<string, unknown>) => DiffViewModel;
|
|
2564
|
+
};
|
|
2565
|
+
declare const DIFF_DECLARATION: BlockDeclaration;
|
|
2566
|
+
|
|
2567
|
+
/**
|
|
2568
|
+
* The Diff panel view — the CODE VIEW of `DIFF_DECLARATION`, drawing the same {@link DiffViewModel}
|
|
2569
|
+
* byte-identical (the equivalence suite holds the two together). No runtime-bound unit; every
|
|
2570
|
+
* intent goes through `applyDiffUi`.
|
|
2571
|
+
*
|
|
2572
|
+
* Composes `@xenosystem/components/chrome` — a file is a `Section`, a hunk a `Hunk`, a line a
|
|
2573
|
+
* `DiffLine` of runs; the host must ensure `@xenosystem/workbench/primitives.css` is present.
|
|
2574
|
+
*
|
|
2575
|
+
* @module
|
|
2576
|
+
*/
|
|
2577
|
+
|
|
2578
|
+
/** Props for {@link DiffPanelView}. */
|
|
2579
|
+
interface DiffPanelViewProps extends DiffViewOptions {
|
|
2580
|
+
controller: DiffController;
|
|
2581
|
+
}
|
|
2444
2582
|
/** The Diff panel view. */
|
|
2445
|
-
declare function DiffPanelView({ controller,
|
|
2583
|
+
declare function DiffPanelView({ controller, ...options }: DiffPanelViewProps): ReactNode;
|
|
2584
|
+
|
|
2585
|
+
/**
|
|
2586
|
+
* `@xenosystem/blocks/ops` — the canonical XENO Diff panel (`xeno.core.diff`).
|
|
2587
|
+
*
|
|
2588
|
+
* Renders a **host-computed** comparison and emits hunk decisions as intents. Bundles no diff
|
|
2589
|
+
* engine and no editor.
|
|
2590
|
+
*
|
|
2591
|
+
* @packageDocumentation
|
|
2592
|
+
*/
|
|
2593
|
+
|
|
2594
|
+
/** The unit names the runtime supplies for this block — none; every unit is a chrome unit. */
|
|
2595
|
+
declare const DIFF_RUNTIME_UNITS: readonly [];
|
|
2446
2596
|
|
|
2447
|
-
export { ALL_STATUSES, BEHAVIOURS$
|
|
2597
|
+
export { ALL_STATUSES, BEHAVIOURS$2 as CONSOLE_BEHAVIOURS, CONSOLE_DECLARATION, CONSOLE_PANEL_ID, CONSOLE_RUNTIME_UNITS, ConsoleController, type ConsoleControllerOptions, type ConsoleHostBridge, type ConsolePanelState, ConsolePanelView, type ConsolePanelViewProps, type ConsoleRenderContext, ConsoleScroller, type ConsoleUiIntent, type ConsoleViewModel, type ConsoleViewOptions, type ConsoleViewRow, type ConsoleViewSource, type ConsoleViewState, type CreateConsolePanelOptions, type CreateDiffPanelOptions, type CreateRunsPanelOptions, type CreateTerminalPanelOptions, DEFAULT_MAX_STEP_DEPTH, BEHAVIOURS as DIFF_BEHAVIOURS, DIFF_DECLARATION, DIFF_PANEL_ID, DIFF_RUNTIME_UNITS, DiffController, type DiffControllerOptions, type DiffFileView, type DiffHostBridge, type DiffPanelState, DiffPanelView, type DiffPanelViewProps, type DiffRenderContext, type DiffUiIntent, type DiffViewFile, type DiffViewHunk, type DiffViewLine, type DiffViewModel, type DiffViewOptions, type DiffViewRun, type DiffViewSplitRow, type DiffViewState, type FlattenOptions, LEVEL_ORDER, MESSAGE_ELISION, REDACTION_CARRY, BEHAVIOURS$1 as RUNS_BEHAVIOURS, RUNS_DECLARATION, RUNS_PANEL_ID, RUNS_RUNTIME_UNITS, RUN_PATH_SEPARATOR, RUN_STATUSES, RunsController, type RunsControllerOptions, type RunsHostBridge, type RunsPanelState, RunsPanelView, type RunsPanelViewProps, type RunsRenderContext, type RunsUiIntent, type RunsViewChip, type RunsViewModel, type RunsViewOptions, type RunsViewRow, type RunsViewState, TERMINAL_PANEL_ID, TERMINAL_STATUSES, TerminalController, type TerminalControllerOptions, type TerminalHostBridge, type TerminalInstanceView, type TerminalPanelState, TerminalPanelView, type TerminalPanelViewProps, type TerminalRenderContext, type TerminalViewState, XENO_TERMINAL_THEME_KEYS, type XenoDiffAction, type XenoDiffDecision, type XenoDiffDecisionIntent, type XenoDiffDecisionState, type XenoDiffFile, type XenoDiffFileOmission, type XenoDiffHighlighter, type XenoDiffHunk, type XenoDiffLine, type XenoDiffLineKind, type XenoDiffModel, type XenoDiffNavigate, type XenoDiffSegment, type XenoDiffStatus, type XenoDiffView, type XenoLogActivate, type XenoLogDelta, type XenoLogFilter, type XenoLogLevel, type XenoLogPatch, type XenoLogRecord, type XenoLogSource, type XenoRun, type XenoRunAction, type XenoRunActivate, type XenoRunDelta, type XenoRunError, type XenoRunFilter, type XenoRunLifecycle, type XenoRunPath, type XenoRunRow, type XenoRunRunRow, type XenoRunStats, type XenoRunStatus, type XenoRunStep, type XenoRunStepAppend, type XenoRunStepPatch, type XenoRunStepRow, type XenoRunTruncation, type XenoTerminalData, type XenoTerminalEmulator, type XenoTerminalId, type XenoTerminalIntent, type XenoTerminalSession, type XenoTerminalStatus, type XenoTerminalTheme, appendStepsAtPath, applyConsoleUi, applyDiffUi, applyRunsUi, canCancel, canRetry, collapseAdjacent, computeStats, consoleManifest, consolePanel, consoleRuntimeComponents, consoleViewManifest, consoleViewState, countChanges, createConsolePanel, createDiffPanel, createRunsPanel, createTerminalPanel, decodeRunPath, diffManifest, diffPanel, diffViewManifest, diffViewState, durationOf, encodeRunPath, flattenHunks, flattenRunRows, formatDuration, formatRecord, isActive, isLive, isSettled, isTerminal, isWaiting, lifecycleOf, matchesSearch as matchesRunSearch, matchesSearch$1 as matchesSearch, measuredSize, meetsLevel, needsAttention, omissionLabel, patchStepAtPath, queueDurationOf, readTerminalTheme, resolveStepPath, runsManifest, runsPanel, runsViewManifest, runsViewState, safeJson, spliceRedactedAppend, splitRows, statusLabel, terminalManifest, terminalPanel, terminalThemeVar, toneOf, truncateLogMessage };
|
package/dist/ops/index.js
CHANGED
|
@@ -60,10 +60,10 @@ function spliceRedactedAppend(existing, addition, redact, carry = REDACTION_CARR
|
|
|
60
60
|
const tail = existing.slice(cut);
|
|
61
61
|
return head + redact(tail + addition);
|
|
62
62
|
}
|
|
63
|
-
function truncateLogMessage(
|
|
64
|
-
if (max <= 0 ||
|
|
65
|
-
if (max <= MESSAGE_ELISION.length) return
|
|
66
|
-
return MESSAGE_ELISION +
|
|
63
|
+
function truncateLogMessage(text4, max) {
|
|
64
|
+
if (max <= 0 || text4.length <= max) return text4;
|
|
65
|
+
if (max <= MESSAGE_ELISION.length) return text4.slice(text4.length - max);
|
|
66
|
+
return MESSAGE_ELISION + text4.slice(text4.length - (max - MESSAGE_ELISION.length));
|
|
67
67
|
}
|
|
68
68
|
function formatRecord(record) {
|
|
69
69
|
const time = new Date(record.ts).toISOString();
|
|
@@ -240,7 +240,7 @@ var ConsoleController = class {
|
|
|
240
240
|
*/
|
|
241
241
|
merge(existing, patch) {
|
|
242
242
|
const secrets = [...this.host.getSecrets?.() ?? []];
|
|
243
|
-
const redact = (
|
|
243
|
+
const redact = (text4) => redactForLog(text4, secrets);
|
|
244
244
|
let message = existing.message;
|
|
245
245
|
if (typeof patch.message === "string") message = redact(patch.message);
|
|
246
246
|
if (typeof patch.appendMessage === "string" && patch.appendMessage.length > 0) {
|
|
@@ -870,24 +870,24 @@ function consoleRuntimeComponents(controller, rowHeight) {
|
|
|
870
870
|
function ConsolePanelView({ controller, ...options }) {
|
|
871
871
|
useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
|
|
872
872
|
const view = consoleViewState(controller, options);
|
|
873
|
-
const
|
|
873
|
+
const ui4 = (intent) => applyConsoleUi(controller, intent);
|
|
874
874
|
return /* @__PURE__ */ jsxs(Column, { children: [
|
|
875
875
|
/* @__PURE__ */ jsx(
|
|
876
876
|
Toolbar,
|
|
877
877
|
{
|
|
878
878
|
left: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
879
|
-
/* @__PURE__ */ jsx(SearchField, { value: view.search, placeholder: "Filter\u2026", onChange: (value) =>
|
|
880
|
-
/* @__PURE__ */ jsx(SegmentedControl, { size: "sm", label: "Minimum level", options: view.levels, value: view.level, onChange: (level) =>
|
|
879
|
+
/* @__PURE__ */ jsx(SearchField, { value: view.search, placeholder: "Filter\u2026", onChange: (value) => ui4({ kind: "search", value }) }),
|
|
880
|
+
/* @__PURE__ */ jsx(SegmentedControl, { size: "sm", label: "Minimum level", options: view.levels, value: view.level, onChange: (level) => ui4({ kind: "level", level }) })
|
|
881
881
|
] }),
|
|
882
882
|
right: /* @__PURE__ */ jsxs(ToolbarGroup, { end: true, children: [
|
|
883
883
|
view.errors ? /* @__PURE__ */ jsx(Badge, { tone: "error", children: view.errors }) : null,
|
|
884
884
|
view.warns ? /* @__PURE__ */ jsx(Badge, { tone: "warning", children: view.warns }) : null,
|
|
885
|
-
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CopyGlyph, {}), label: "Copy visible", onClick: () =>
|
|
886
|
-
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(ClearGlyph, {}), label: "Clear", onClick: () =>
|
|
885
|
+
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CopyGlyph, {}), label: "Copy visible", onClick: () => ui4({ kind: "copyVisible" }) }),
|
|
886
|
+
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(ClearGlyph, {}), label: "Clear", onClick: () => ui4({ kind: "clear" }) })
|
|
887
887
|
] })
|
|
888
888
|
}
|
|
889
889
|
),
|
|
890
|
-
view.multiSource ? /* @__PURE__ */ jsx(Stack, { direction: "row", gap: 4, pad: "inset", children: view.sources.map((source) => /* @__PURE__ */ jsx(FilterChip, { on: source.on, title: source.title, onChange: (on) =>
|
|
890
|
+
view.multiSource ? /* @__PURE__ */ jsx(Stack, { direction: "row", gap: 4, pad: "inset", children: view.sources.map((source) => /* @__PURE__ */ jsx(FilterChip, { on: source.on, title: source.title, onChange: (on) => ui4({ kind: "source", id: source.id, on }), children: source.label }, source.id)) }) : null,
|
|
891
891
|
view.empty ? /* @__PURE__ */ jsx(EmptyState, { title: view.emptyTitle, hint: view.emptyHint }) : null,
|
|
892
892
|
view.listed ? /* @__PURE__ */ jsx(ConsoleScroller, { controller, rowHeight: view.rowHeight, children: /* @__PURE__ */ jsx(VirtualWindow, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: /* @__PURE__ */ jsx(RowList, { role: "log", children: view.rows.map((row) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
893
893
|
/* @__PURE__ */ jsx(
|
|
@@ -902,8 +902,8 @@ function ConsolePanelView({ controller, ...options }) {
|
|
|
902
902
|
/* @__PURE__ */ jsx(Text, { children: row.message })
|
|
903
903
|
] }),
|
|
904
904
|
trailing: row.repeat ? /* @__PURE__ */ jsx(Badge, { title: "Repeated consecutively", children: row.repeat }) : null,
|
|
905
|
-
onClick: () =>
|
|
906
|
-
onContextMenuAt: (x, y) =>
|
|
905
|
+
onClick: () => ui4({ kind: "row", id: row.id }),
|
|
906
|
+
onContextMenuAt: (x, y) => ui4({ kind: "contextMenu", id: row.id, x, y })
|
|
907
907
|
},
|
|
908
908
|
row.id
|
|
909
909
|
),
|
|
@@ -2085,19 +2085,19 @@ var RetryGlyph = ICONS["icons/Retry"];
|
|
|
2085
2085
|
function RunsPanelView({ controller, ...options }) {
|
|
2086
2086
|
useSyncExternalStore2(controller.subscribe, controller.getState, controller.getState);
|
|
2087
2087
|
const view = runsViewState(controller, options);
|
|
2088
|
-
const
|
|
2088
|
+
const ui4 = (intent) => applyRunsUi(controller, intent);
|
|
2089
2089
|
const chip2 = (c, onChange) => /* @__PURE__ */ jsx2(FilterChip2, { on: c.on, title: c.title, onChange, children: /* @__PURE__ */ jsx2(Badge2, { tone: c.tone, children: c.label }) }, c.id);
|
|
2090
2090
|
return /* @__PURE__ */ jsxs2(Column2, { children: [
|
|
2091
2091
|
/* @__PURE__ */ jsx2(
|
|
2092
2092
|
Toolbar2,
|
|
2093
2093
|
{
|
|
2094
|
-
left: /* @__PURE__ */ jsx2(SearchField2, { value: view.search, placeholder: "Filter runs\u2026", onChange: (value) =>
|
|
2095
|
-
right: /* @__PURE__ */ jsx2(ToolbarGroup2, { end: true, children: /* @__PURE__ */ jsx2(TextButton, { onClick: () =>
|
|
2094
|
+
left: /* @__PURE__ */ jsx2(SearchField2, { value: view.search, placeholder: "Filter runs\u2026", onChange: (value) => ui4({ kind: "search", value }) }),
|
|
2095
|
+
right: /* @__PURE__ */ jsx2(ToolbarGroup2, { end: true, children: /* @__PURE__ */ jsx2(TextButton, { onClick: () => ui4({ kind: "clearTerminal" }), children: "Clear finished" }) })
|
|
2096
2096
|
}
|
|
2097
2097
|
),
|
|
2098
2098
|
view.hasChips ? /* @__PURE__ */ jsxs2(Stack2, { direction: "row", gap: 4, pad: "inset", children: [
|
|
2099
|
-
view.statuses.map((c) => chip2(c, (on) =>
|
|
2100
|
-
view.sources.map((c) => chip2(c, (on) =>
|
|
2099
|
+
view.statuses.map((c) => chip2(c, (on) => ui4({ kind: "status", status: c.id, on }))),
|
|
2100
|
+
view.sources.map((c) => chip2(c, (on) => ui4({ kind: "source", id: c.id, on })))
|
|
2101
2101
|
] }) : null,
|
|
2102
2102
|
view.empty ? /* @__PURE__ */ jsx2(EmptyState2, { title: view.emptyTitle, hint: view.emptyHint }) : null,
|
|
2103
2103
|
view.listed ? /* @__PURE__ */ jsx2(ScrollArea2, { children: /* @__PURE__ */ jsx2(RowList2, { children: view.rows.map((row) => /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
@@ -2119,11 +2119,11 @@ function RunsPanelView({ controller, ...options }) {
|
|
|
2119
2119
|
row.duration ? /* @__PURE__ */ jsx2(Text2, { role: "number", children: row.duration }) : null
|
|
2120
2120
|
] }),
|
|
2121
2121
|
trailing: /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2122
|
-
row.canCancel ? /* @__PURE__ */ jsx2(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx2(CancelGlyph, {}), label: row.cancelLabel, onClick: () =>
|
|
2123
|
-
row.canRetry ? /* @__PURE__ */ jsx2(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx2(RetryGlyph, {}), label: row.retryLabel, onClick: () =>
|
|
2122
|
+
row.canCancel ? /* @__PURE__ */ jsx2(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx2(CancelGlyph, {}), label: row.cancelLabel, onClick: () => ui4({ kind: "cancel", runId: row.runId }) }) : null,
|
|
2123
|
+
row.canRetry ? /* @__PURE__ */ jsx2(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx2(RetryGlyph, {}), label: row.retryLabel, onClick: () => ui4({ kind: "retry", runId: row.runId }) }) : null
|
|
2124
2124
|
] }),
|
|
2125
|
-
onClick: () =>
|
|
2126
|
-
onContextMenuAt: (x, y) =>
|
|
2125
|
+
onClick: () => ui4({ kind: "row", runId: row.runId, stepPath: row.stepPath }),
|
|
2126
|
+
onContextMenuAt: (x, y) => ui4({ kind: "contextMenu", runId: row.runId, x, y })
|
|
2127
2127
|
},
|
|
2128
2128
|
row.key
|
|
2129
2129
|
),
|
|
@@ -3433,291 +3433,361 @@ var diffManifest = {
|
|
|
3433
3433
|
import { useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
3434
3434
|
import {
|
|
3435
3435
|
Badge as Badge4,
|
|
3436
|
+
Column as Column3,
|
|
3437
|
+
DiffLine,
|
|
3438
|
+
DiffSplitRow,
|
|
3436
3439
|
EmptyState as EmptyState4,
|
|
3440
|
+
Hunk,
|
|
3441
|
+
Note as Note2,
|
|
3437
3442
|
ScrollArea as ScrollArea3,
|
|
3443
|
+
Section,
|
|
3438
3444
|
SegmentedControl as SegmentedControl2,
|
|
3439
3445
|
StatusBar as StatusBar4,
|
|
3446
|
+
Text as Text3,
|
|
3440
3447
|
TextButton as TextButton3,
|
|
3441
3448
|
Toolbar as Toolbar4,
|
|
3442
3449
|
ToolbarGroup as ToolbarGroup4
|
|
3443
3450
|
} from "@xenosystem/components/chrome";
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
context: {}
|
|
3449
|
-
};
|
|
3450
|
-
var SIGIL = { added: "+", removed: "-", context: " " };
|
|
3451
|
-
function visible(text3, show) {
|
|
3452
|
-
return show ? text3.replace(/\t/g, "\u2192 ").replace(/ /g, "\xB7") : text3;
|
|
3453
|
-
}
|
|
3454
|
-
function LineText({
|
|
3455
|
-
line,
|
|
3456
|
-
language,
|
|
3457
|
-
highlighter,
|
|
3458
|
-
showWhitespace
|
|
3459
|
-
}) {
|
|
3451
|
+
|
|
3452
|
+
// src/ops/diff/declaration.ts
|
|
3453
|
+
var visible = (text4, show) => show ? text4.replace(/\t/g, "\u2192 ").replace(/ /g, "\xB7") : text4;
|
|
3454
|
+
var runsOf = (line, language, highlighter, showWhitespace) => {
|
|
3460
3455
|
if (line.segments?.length) {
|
|
3461
|
-
return
|
|
3462
|
-
"span",
|
|
3463
|
-
{
|
|
3464
|
-
style: segment.kind === "equal" ? void 0 : {
|
|
3465
|
-
background: "var(--xeno-border)",
|
|
3466
|
-
borderRadius: 2,
|
|
3467
|
-
textDecoration: segment.kind === "delete" ? "line-through" : void 0
|
|
3468
|
-
},
|
|
3469
|
-
children: visible(segment.text, showWhitespace)
|
|
3470
|
-
},
|
|
3471
|
-
i
|
|
3472
|
-
)) });
|
|
3456
|
+
return line.segments.map((s) => s.kind === "equal" ? { text: visible(s.text, showWhitespace) } : { text: visible(s.text, showWhitespace), mark: s.kind });
|
|
3473
3457
|
}
|
|
3474
3458
|
const tokens = highlighter?.highlight(line.text, language) ?? null;
|
|
3475
|
-
if (tokens) {
|
|
3476
|
-
|
|
3477
|
-
}
|
|
3478
|
-
return /* @__PURE__ */ jsx4(Fragment3, { children: visible(line.text, showWhitespace) });
|
|
3479
|
-
}
|
|
3480
|
-
var GUTTER = {
|
|
3481
|
-
display: "inline-block",
|
|
3482
|
-
width: 40,
|
|
3483
|
-
textAlign: "right",
|
|
3484
|
-
paddingRight: 6,
|
|
3485
|
-
opacity: 0.35,
|
|
3486
|
-
fontVariantNumeric: "tabular-nums",
|
|
3487
|
-
userSelect: "none"
|
|
3459
|
+
if (tokens) return tokens.map((t) => t.token ? { text: visible(t.text, showWhitespace), token: t.token } : { text: visible(t.text, showWhitespace) });
|
|
3460
|
+
return [{ text: visible(line.text, showWhitespace) }];
|
|
3488
3461
|
};
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3462
|
+
var SIGIL = { added: "+", removed: "-", context: " " };
|
|
3463
|
+
function diffViewState(c, options = {}) {
|
|
3464
|
+
const { highlighter, review = false } = options;
|
|
3465
|
+
const state = c.getState();
|
|
3466
|
+
const idle = state.status === "idle";
|
|
3467
|
+
const computing = state.status === "computing";
|
|
3468
|
+
const failed = state.status === "failed";
|
|
3469
|
+
const identical = !idle && !computing && !failed && state.identical;
|
|
3470
|
+
const active = !idle && !computing && !failed && !identical;
|
|
3471
|
+
const unified = state.view === "unified";
|
|
3472
|
+
const cell = (line, side, language, key) => line ? { key, kind: line.kind, gutter: [(side === "l" ? line.oldLineNumber : line.newLineNumber) ?? ""], runs: runsOf(line, language, highlighter, state.showWhitespace) } : { key, kind: "blank", gutter: [""], runs: [] };
|
|
3473
|
+
const files = active ? state.files.map((f) => ({
|
|
3474
|
+
key: f.file.path,
|
|
3475
|
+
path: f.file.path,
|
|
3476
|
+
title: f.file.oldPath && f.file.oldPath !== f.file.path ? `${f.file.oldPath} \u2192 ${f.file.path}` : f.file.path,
|
|
3477
|
+
status: f.file.status,
|
|
3478
|
+
counts: `+${f.additions} \u2212${f.deletions}`,
|
|
3479
|
+
collapsed: f.collapsed,
|
|
3480
|
+
omitted: !f.collapsed && f.file.omitted !== void 0,
|
|
3481
|
+
omission: f.file.omitted ? omissionLabel(f.file.omitted) : "",
|
|
3482
|
+
hunks: f.collapsed || f.file.omitted ? [] : f.file.hunks.map((h) => {
|
|
3483
|
+
const decision = f.decisions[h.id];
|
|
3484
|
+
const ds = decision?.state ?? "undecided";
|
|
3485
|
+
const attention = needsAttention(ds);
|
|
3486
|
+
return {
|
|
3487
|
+
key: h.id,
|
|
3488
|
+
path: f.file.path,
|
|
3489
|
+
id: h.id,
|
|
3490
|
+
header: h.header ?? `@@ -${h.oldStart},${h.oldLines} +${h.newStart},${h.newLines} @@`,
|
|
3491
|
+
focused: state.cursor?.path === f.file.path && state.cursor.hunkId === h.id,
|
|
3492
|
+
settled: isSettled(ds),
|
|
3493
|
+
chipPending: ds === "pending",
|
|
3494
|
+
chipConflict: ds === "conflict",
|
|
3495
|
+
conflictTitle: decision?.message ?? "The file changed since this was reviewed.",
|
|
3496
|
+
chipFailed: ds === "failed",
|
|
3497
|
+
failedTitle: decision?.message ?? void 0,
|
|
3498
|
+
chipApplied: isSettled(ds),
|
|
3499
|
+
appliedText: decision?.action === "accept" ? "accepted" : "rejected",
|
|
3500
|
+
review,
|
|
3501
|
+
attention,
|
|
3502
|
+
deciding: ds === "pending",
|
|
3503
|
+
unified,
|
|
3504
|
+
split: !unified,
|
|
3505
|
+
lines: unified ? h.lines.map((line, i) => ({
|
|
3506
|
+
key: `${h.id}-${i}`,
|
|
3507
|
+
kind: line.kind,
|
|
3508
|
+
gutter: [line.oldLineNumber ?? "", line.newLineNumber ?? ""],
|
|
3509
|
+
sigil: SIGIL[line.kind],
|
|
3510
|
+
runs: runsOf(line, f.file.language, highlighter, state.showWhitespace)
|
|
3511
|
+
})) : [],
|
|
3512
|
+
rows: unified ? [] : splitRows(h).map((row, i) => ({
|
|
3513
|
+
key: `${h.id}-s${i}`,
|
|
3514
|
+
left: cell(row.left, "l", f.file.language, `${h.id}-s${i}-l`),
|
|
3515
|
+
right: cell(row.right, "r", f.file.language, `${h.id}-s${i}-r`)
|
|
3516
|
+
}))
|
|
3517
|
+
};
|
|
3518
|
+
})
|
|
3519
|
+
})) : [];
|
|
3520
|
+
const conflicts = state.review?.conflicts ?? 0;
|
|
3521
|
+
return {
|
|
3522
|
+
idle,
|
|
3523
|
+
computing,
|
|
3524
|
+
failed,
|
|
3525
|
+
// NOT "no changes". A comparison that could not run has established nothing about the content.
|
|
3526
|
+
failedHint: state.message ?? "The host could not compute the differences.",
|
|
3527
|
+
identical,
|
|
3528
|
+
active,
|
|
3529
|
+
view: state.view,
|
|
3530
|
+
views: [{ label: "Unified", value: "unified" }, { label: "Split", value: "split" }],
|
|
3531
|
+
wrap: state.wrap,
|
|
3532
|
+
wrapLabel: state.wrap ? "No wrap" : "Wrap",
|
|
3533
|
+
whitespaceLabel: state.showWhitespace ? "Hide \u2423" : "Show \u2423",
|
|
3534
|
+
conflictNotice: conflicts > 0 ? `${conflicts} conflict${conflicts === 1 ? "" : "s"} \u2014 the file changed since review` : void 0,
|
|
3535
|
+
files,
|
|
3536
|
+
countLabel: `${state.totals.files} file${state.totals.files === 1 ? "" : "s"} \xB7 +${state.totals.additions} \u2212${state.totals.deletions}`,
|
|
3537
|
+
rightLabel: state.review ? `${state.review.decided}/${state.review.total} reviewed` : `${state.oldLabel} \u2192 ${state.newLabel}`
|
|
3538
|
+
};
|
|
3502
3539
|
}
|
|
3503
|
-
function
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3540
|
+
function applyDiffUi(c, intent) {
|
|
3541
|
+
switch (intent.kind) {
|
|
3542
|
+
case "view":
|
|
3543
|
+
c.setView(intent.view);
|
|
3544
|
+
break;
|
|
3545
|
+
case "toggleWrap":
|
|
3546
|
+
c.setWrap(!c.getState().wrap);
|
|
3547
|
+
break;
|
|
3548
|
+
case "toggleWhitespace":
|
|
3549
|
+
c.setShowWhitespace(!c.getState().showWhitespace);
|
|
3550
|
+
break;
|
|
3551
|
+
case "prev":
|
|
3552
|
+
c.previousHunk();
|
|
3553
|
+
break;
|
|
3554
|
+
case "next":
|
|
3555
|
+
c.nextHunk();
|
|
3556
|
+
break;
|
|
3557
|
+
case "collapse":
|
|
3558
|
+
c.setCollapsed(intent.path, intent.collapsed);
|
|
3559
|
+
break;
|
|
3560
|
+
case "contextMenu":
|
|
3561
|
+
c.requestContextMenu(intent.path, intent.id, intent.x, intent.y);
|
|
3562
|
+
break;
|
|
3563
|
+
case "decide":
|
|
3564
|
+
c.decide(intent.path, intent.id, intent.action);
|
|
3565
|
+
break;
|
|
3566
|
+
case "reReview":
|
|
3567
|
+
c.clearDecision(intent.path, intent.id);
|
|
3568
|
+
break;
|
|
3522
3569
|
}
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
{
|
|
3572
|
-
line,
|
|
3573
|
-
language: file.file.language,
|
|
3574
|
-
highlighter,
|
|
3575
|
-
showWhitespace: state.showWhitespace
|
|
3576
|
-
}
|
|
3577
|
-
) : null
|
|
3578
|
-
]
|
|
3579
|
-
}
|
|
3580
|
-
);
|
|
3581
|
-
return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
|
|
3582
|
-
/* @__PURE__ */ jsx4(
|
|
3583
|
-
Toolbar4,
|
|
3570
|
+
}
|
|
3571
|
+
var diffViewManifest = {
|
|
3572
|
+
id: diffManifest.id,
|
|
3573
|
+
version: "1.0.0",
|
|
3574
|
+
title: "Diff",
|
|
3575
|
+
category: "ops",
|
|
3576
|
+
layout: { slot: "center" },
|
|
3577
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The DiffViewModel the runtime derives from the controller on every draw." }],
|
|
3578
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, view?, path?, id?, collapsed?, action?, x?, y? } \u2014 applied by the runtime to the controller." }],
|
|
3579
|
+
commands: []
|
|
3580
|
+
};
|
|
3581
|
+
var EMPTY4 = {
|
|
3582
|
+
idle: true,
|
|
3583
|
+
computing: false,
|
|
3584
|
+
failed: false,
|
|
3585
|
+
failedHint: "",
|
|
3586
|
+
identical: false,
|
|
3587
|
+
active: false,
|
|
3588
|
+
view: "unified",
|
|
3589
|
+
views: [{ label: "Unified", value: "unified" }, { label: "Split", value: "split" }],
|
|
3590
|
+
wrap: false,
|
|
3591
|
+
wrapLabel: "Wrap",
|
|
3592
|
+
whitespaceLabel: "Show \u2423",
|
|
3593
|
+
files: [],
|
|
3594
|
+
countLabel: "0 files \xB7 +0 \u22120",
|
|
3595
|
+
rightLabel: ""
|
|
3596
|
+
};
|
|
3597
|
+
var BEHAVIOURS3 = {
|
|
3598
|
+
"ops/diffPanelView": (inputs) => inputs.view ?? EMPTY4
|
|
3599
|
+
};
|
|
3600
|
+
var text3 = (b) => ({ component: "text", props: { text: b } });
|
|
3601
|
+
var ui3 = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
3602
|
+
var LINE = (kindKey) => ({
|
|
3603
|
+
component: "chrome/DiffLine",
|
|
3604
|
+
each: { item: kindKey, key: "key" },
|
|
3605
|
+
props: { kind: { item: "kind" }, gutter: { item: "gutter" }, sigil: { item: "sigil" }, wrap: { input: "view.wrap" }, runs: { item: "runs" } }
|
|
3606
|
+
});
|
|
3607
|
+
var DIFF_DECLARATION = {
|
|
3608
|
+
format: "xeno.block@1",
|
|
3609
|
+
manifest: diffViewManifest,
|
|
3610
|
+
behaviour: "ops/diffPanelView",
|
|
3611
|
+
composition: {
|
|
3612
|
+
component: "fragment",
|
|
3613
|
+
children: [
|
|
3614
|
+
{ component: "chrome/EmptyState", when: { input: "view.idle" }, props: { title: { value: "Diff" }, hint: { value: "Nothing to compare yet." } } },
|
|
3615
|
+
{ component: "chrome/EmptyState", when: { input: "view.computing" }, props: { title: { value: "Comparing\u2026" }, hint: { value: "The host is computing the differences." } } },
|
|
3616
|
+
{ component: "chrome/EmptyState", when: { input: "view.failed" }, props: { title: { value: "Comparison failed" }, hint: { input: "view.failedHint" } } },
|
|
3617
|
+
{ component: "chrome/EmptyState", when: { input: "view.identical" }, props: { title: { value: "No changes" }, hint: { value: "The two sides are identical." } } },
|
|
3584
3618
|
{
|
|
3585
|
-
|
|
3586
|
-
|
|
3619
|
+
component: "chrome/Column",
|
|
3620
|
+
when: { input: "view.active" },
|
|
3621
|
+
children: [
|
|
3587
3622
|
{
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
),
|
|
3605
|
-
state.review && state.review.conflicts > 0 ? /* @__PURE__ */ jsx4("div", { style: { padding: "2px 8px", fontSize: 9 }, children: /* @__PURE__ */ jsxs4(Badge4, { tone: "error", children: [
|
|
3606
|
-
state.review.conflicts,
|
|
3607
|
-
" conflict",
|
|
3608
|
-
state.review.conflicts === 1 ? "" : "s",
|
|
3609
|
-
" \u2014 the file changed since review"
|
|
3610
|
-
] }) }) : null,
|
|
3611
|
-
/* @__PURE__ */ jsx4(ScrollArea3, { children: state.files.map((file) => /* @__PURE__ */ jsxs4("div", { style: { borderBottom: "1px solid var(--xeno-border-subtle)" }, children: [
|
|
3612
|
-
/* @__PURE__ */ jsxs4(
|
|
3613
|
-
"div",
|
|
3614
|
-
{
|
|
3615
|
-
style: {
|
|
3616
|
-
display: "flex",
|
|
3617
|
-
alignItems: "center",
|
|
3618
|
-
gap: 6,
|
|
3619
|
-
padding: "3px 8px",
|
|
3620
|
-
position: "sticky",
|
|
3621
|
-
top: 0,
|
|
3622
|
-
background: "var(--xeno-surface)",
|
|
3623
|
-
zIndex: 1
|
|
3623
|
+
component: "chrome/Toolbar",
|
|
3624
|
+
props: {
|
|
3625
|
+
left: { node: { component: "chrome/SegmentedControl", props: { label: { value: "View" }, value: { input: "view.view" }, options: { input: "view.views" } }, on: { onChange: ui3("view", { view: { arg: "" } }) } } },
|
|
3626
|
+
right: {
|
|
3627
|
+
node: {
|
|
3628
|
+
component: "chrome/ToolbarGroup",
|
|
3629
|
+
props: { end: { value: true } },
|
|
3630
|
+
children: [
|
|
3631
|
+
{ component: "chrome/TextButton", children: [text3({ input: "view.wrapLabel" })], on: { onClick: ui3("toggleWrap") } },
|
|
3632
|
+
{ component: "chrome/TextButton", children: [text3({ input: "view.whitespaceLabel" })], on: { onClick: ui3("toggleWhitespace") } },
|
|
3633
|
+
{ component: "chrome/TextButton", children: [text3({ value: "Prev" })], on: { onClick: ui3("prev") } },
|
|
3634
|
+
{ component: "chrome/TextButton", children: [text3({ value: "Next" })], on: { onClick: ui3("next") } }
|
|
3635
|
+
]
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3624
3639
|
},
|
|
3625
|
-
children: [
|
|
3626
|
-
/* @__PURE__ */ jsx4(TextButton3, { onClick: () => controller.setCollapsed(file.file.path, !file.collapsed), children: file.collapsed ? "\u25B8" : "\u25BE" }),
|
|
3627
|
-
/* @__PURE__ */ jsx4("span", { style: { fontSize: 11, fontWeight: 600 }, children: file.file.oldPath && file.file.oldPath !== file.file.path ? `${file.file.oldPath} \u2192 ${file.file.path}` : file.file.path }),
|
|
3628
|
-
/* @__PURE__ */ jsx4(Badge4, { children: file.file.status }),
|
|
3629
|
-
/* @__PURE__ */ jsxs4("span", { style: { fontSize: 10, fontVariantNumeric: "tabular-nums", opacity: 0.6 }, children: [
|
|
3630
|
-
"+",
|
|
3631
|
-
file.additions,
|
|
3632
|
-
" \u2212",
|
|
3633
|
-
file.deletions
|
|
3634
|
-
] })
|
|
3635
|
-
]
|
|
3636
|
-
}
|
|
3637
|
-
),
|
|
3638
|
-
file.collapsed ? null : file.file.omitted ? (
|
|
3639
|
-
// 🔴 Never an empty body. "Binary — not compared" and "no changes" are different
|
|
3640
|
-
// facts, and a reviewer who reads the first as the second approves something nobody
|
|
3641
|
-
// looked at.
|
|
3642
|
-
/* @__PURE__ */ jsx4("div", { style: { padding: "6px 12px", fontSize: 10, opacity: 0.6 }, children: omissionLabel(file.file.omitted) })
|
|
3643
|
-
) : file.file.hunks.map((hunk) => {
|
|
3644
|
-
const decision = file.decisions[hunk.id];
|
|
3645
|
-
const focused = state.cursor?.path === file.file.path && state.cursor.hunkId === hunk.id;
|
|
3646
|
-
return /* @__PURE__ */ jsxs4(
|
|
3647
|
-
"div",
|
|
3640
|
+
{ component: "chrome/Note", when: { input: "view.conflictNotice" }, children: [{ component: "chrome/Badge", props: { tone: { value: "error" } }, children: [text3({ input: "view.conflictNotice" })] }] },
|
|
3648
3641
|
{
|
|
3649
|
-
|
|
3650
|
-
event.preventDefault();
|
|
3651
|
-
controller.requestContextMenu(
|
|
3652
|
-
file.file.path,
|
|
3653
|
-
hunk.id,
|
|
3654
|
-
event.clientX,
|
|
3655
|
-
event.clientY
|
|
3656
|
-
);
|
|
3657
|
-
},
|
|
3658
|
-
style: {
|
|
3659
|
-
borderLeft: focused ? "2px solid var(--xeno-active)" : "2px solid transparent",
|
|
3660
|
-
opacity: isSettled(decision?.state ?? "undecided") ? 0.55 : 1
|
|
3661
|
-
},
|
|
3642
|
+
component: "chrome/ScrollArea",
|
|
3662
3643
|
children: [
|
|
3663
|
-
|
|
3664
|
-
"
|
|
3665
|
-
{
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
}
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3644
|
+
{
|
|
3645
|
+
component: "chrome/Section",
|
|
3646
|
+
each: { input: "view.files", key: "key" },
|
|
3647
|
+
props: {
|
|
3648
|
+
title: { node: { component: "chrome/Text", children: [text3({ item: "title" })] } },
|
|
3649
|
+
badge: { node: { component: "chrome/Badge", children: [text3({ item: "status" })] } },
|
|
3650
|
+
actions: { node: { component: "chrome/Text", props: { role: { value: "number" } }, children: [text3({ item: "counts" })] } },
|
|
3651
|
+
collapsible: { value: true },
|
|
3652
|
+
collapsed: { item: "collapsed" },
|
|
3653
|
+
flush: { value: true }
|
|
3654
|
+
},
|
|
3655
|
+
on: { onCollapsedChange: ui3("collapse", { path: { item: "path" }, collapsed: { arg: "" } }) },
|
|
3656
|
+
children: [
|
|
3657
|
+
// 🔴 Never an empty body. "Binary — not compared" and "no changes" are different facts.
|
|
3658
|
+
{ component: "chrome/Text", when: { item: "omitted" }, props: { role: { value: "meta" } }, children: [text3({ item: "omission" })] },
|
|
3659
|
+
{
|
|
3660
|
+
component: "chrome/Hunk",
|
|
3661
|
+
each: { item: "hunks", key: "key" },
|
|
3662
|
+
props: {
|
|
3663
|
+
focused: { item: "focused" },
|
|
3664
|
+
settled: { item: "settled" },
|
|
3665
|
+
header: {
|
|
3666
|
+
node: {
|
|
3667
|
+
component: "fragment",
|
|
3668
|
+
children: [
|
|
3669
|
+
text3({ item: "header" }),
|
|
3670
|
+
{ component: "chrome/Badge", when: { item: "chipPending" }, children: [text3({ value: "deciding\u2026" })] },
|
|
3671
|
+
{ component: "chrome/Badge", when: { item: "chipConflict" }, props: { tone: { value: "error" }, title: { item: "conflictTitle" } }, children: [text3({ value: "conflict \u2014 re-review" })] },
|
|
3672
|
+
{ component: "chrome/Badge", when: { item: "chipFailed" }, props: { tone: { value: "error" }, title: { item: "failedTitle" } }, children: [text3({ value: "failed" })] },
|
|
3673
|
+
{ component: "chrome/Badge", when: { item: "chipApplied" }, props: { tone: { value: "success" } }, children: [text3({ item: "appliedText" })] }
|
|
3674
|
+
]
|
|
3690
3675
|
}
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3676
|
+
},
|
|
3677
|
+
actions: {
|
|
3678
|
+
node: {
|
|
3679
|
+
component: "fragment",
|
|
3680
|
+
when: { item: "review" },
|
|
3681
|
+
children: [
|
|
3682
|
+
{ component: "chrome/TextButton", when: { item: "attention" }, children: [text3({ value: "Re-review" })], on: { onClick: ui3("reReview", { path: { item: "path" }, id: { item: "id" } }) } },
|
|
3683
|
+
{ component: "chrome/TextButton", when: { not: { item: "attention" } }, props: { disabled: { item: "deciding" } }, children: [text3({ value: "Accept" })], on: { onClick: ui3("decide", { path: { item: "path" }, id: { item: "id" }, action: { value: "accept" } }) } },
|
|
3684
|
+
{ component: "chrome/TextButton", when: { not: { item: "attention" } }, props: { disabled: { item: "deciding" } }, children: [text3({ value: "Reject" })], on: { onClick: ui3("decide", { path: { item: "path" }, id: { item: "id" }, action: { value: "reject" } }) } }
|
|
3685
|
+
]
|
|
3698
3686
|
}
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3687
|
+
}
|
|
3688
|
+
},
|
|
3689
|
+
on: { onContextMenuAt: ui3("contextMenu", { path: { item: "path" }, id: { item: "id" }, x: { arg: "" }, y: { arg: "", index: 1 } }) },
|
|
3690
|
+
children: [
|
|
3691
|
+
LINE("lines"),
|
|
3692
|
+
{
|
|
3693
|
+
component: "chrome/DiffSplitRow",
|
|
3694
|
+
each: { item: "rows", key: "key" },
|
|
3695
|
+
children: [
|
|
3696
|
+
{ component: "chrome/DiffLine", props: { kind: { item: "left.kind" }, gutter: { item: "left.gutter" }, wrap: { input: "view.wrap" }, runs: { item: "left.runs" } } },
|
|
3697
|
+
{ component: "chrome/DiffLine", props: { kind: { item: "right.kind" }, gutter: { item: "right.gutter" }, wrap: { input: "view.wrap" }, runs: { item: "right.runs" } } }
|
|
3698
|
+
]
|
|
3699
|
+
}
|
|
3700
|
+
]
|
|
3701
|
+
}
|
|
3702
|
+
]
|
|
3703
|
+
}
|
|
3708
3704
|
]
|
|
3709
3705
|
},
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
right: state.review ? `${state.review.decided}/${state.review.total} reviewed` : `${state.oldLabel} \u2192 ${state.newLabel}`
|
|
3706
|
+
{
|
|
3707
|
+
component: "chrome/StatusBar",
|
|
3708
|
+
props: {
|
|
3709
|
+
left: { node: { component: "chrome/Text", props: { role: { value: "number" } }, children: [text3({ input: "view.countLabel" })] } },
|
|
3710
|
+
right: { node: { component: "chrome/Text", props: { role: { value: "meta" } }, children: [text3({ input: "view.rightLabel" })] } }
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
]
|
|
3719
3714
|
}
|
|
3720
|
-
|
|
3715
|
+
]
|
|
3716
|
+
}
|
|
3717
|
+
};
|
|
3718
|
+
|
|
3719
|
+
// src/ops/diff/react/DiffPanelView.tsx
|
|
3720
|
+
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3721
|
+
function DiffPanelView({ controller, ...options }) {
|
|
3722
|
+
useSyncExternalStore4(controller.subscribe, controller.getState, controller.getState);
|
|
3723
|
+
const view = diffViewState(controller, options);
|
|
3724
|
+
const ui4 = (intent) => applyDiffUi(controller, intent);
|
|
3725
|
+
const hunk = (h) => /* @__PURE__ */ jsxs4(
|
|
3726
|
+
Hunk,
|
|
3727
|
+
{
|
|
3728
|
+
focused: h.focused,
|
|
3729
|
+
settled: h.settled,
|
|
3730
|
+
header: /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
3731
|
+
h.header,
|
|
3732
|
+
h.chipPending ? /* @__PURE__ */ jsx4(Badge4, { children: "deciding\u2026" }) : null,
|
|
3733
|
+
h.chipConflict ? /* @__PURE__ */ jsx4(Badge4, { tone: "error", title: h.conflictTitle, children: "conflict \u2014 re-review" }) : null,
|
|
3734
|
+
h.chipFailed ? /* @__PURE__ */ jsx4(Badge4, { tone: "error", title: h.failedTitle, children: "failed" }) : null,
|
|
3735
|
+
h.chipApplied ? /* @__PURE__ */ jsx4(Badge4, { tone: "success", children: h.appliedText }) : null
|
|
3736
|
+
] }),
|
|
3737
|
+
actions: h.review ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
3738
|
+
h.attention ? /* @__PURE__ */ jsx4(TextButton3, { onClick: () => ui4({ kind: "reReview", path: h.path, id: h.id }), children: "Re-review" }) : null,
|
|
3739
|
+
!h.attention ? /* @__PURE__ */ jsx4(TextButton3, { disabled: h.deciding, onClick: () => ui4({ kind: "decide", path: h.path, id: h.id, action: "accept" }), children: "Accept" }) : null,
|
|
3740
|
+
!h.attention ? /* @__PURE__ */ jsx4(TextButton3, { disabled: h.deciding, onClick: () => ui4({ kind: "decide", path: h.path, id: h.id, action: "reject" }), children: "Reject" }) : null
|
|
3741
|
+
] }) : null,
|
|
3742
|
+
onContextMenuAt: (x, y) => ui4({ kind: "contextMenu", path: h.path, id: h.id, x, y }),
|
|
3743
|
+
children: [
|
|
3744
|
+
h.lines.map((l) => /* @__PURE__ */ jsx4(DiffLine, { kind: l.kind, gutter: l.gutter, sigil: l.sigil, wrap: view.wrap, runs: l.runs }, l.key)),
|
|
3745
|
+
h.rows.map((r) => /* @__PURE__ */ jsxs4(DiffSplitRow, { children: [
|
|
3746
|
+
/* @__PURE__ */ jsx4(DiffLine, { kind: r.left.kind, gutter: r.left.gutter, wrap: view.wrap, runs: r.left.runs }),
|
|
3747
|
+
/* @__PURE__ */ jsx4(DiffLine, { kind: r.right.kind, gutter: r.right.gutter, wrap: view.wrap, runs: r.right.runs })
|
|
3748
|
+
] }, r.key))
|
|
3749
|
+
]
|
|
3750
|
+
},
|
|
3751
|
+
h.key
|
|
3752
|
+
);
|
|
3753
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
3754
|
+
view.idle ? /* @__PURE__ */ jsx4(EmptyState4, { title: "Diff", hint: "Nothing to compare yet." }) : null,
|
|
3755
|
+
view.computing ? /* @__PURE__ */ jsx4(EmptyState4, { title: "Comparing\u2026", hint: "The host is computing the differences." }) : null,
|
|
3756
|
+
view.failed ? /* @__PURE__ */ jsx4(EmptyState4, { title: "Comparison failed", hint: view.failedHint }) : null,
|
|
3757
|
+
view.identical ? /* @__PURE__ */ jsx4(EmptyState4, { title: "No changes", hint: "The two sides are identical." }) : null,
|
|
3758
|
+
view.active ? /* @__PURE__ */ jsxs4(Column3, { children: [
|
|
3759
|
+
/* @__PURE__ */ jsx4(
|
|
3760
|
+
Toolbar4,
|
|
3761
|
+
{
|
|
3762
|
+
left: /* @__PURE__ */ jsx4(SegmentedControl2, { label: "View", value: view.view, options: view.views, onChange: (value) => ui4({ kind: "view", view: value }) }),
|
|
3763
|
+
right: /* @__PURE__ */ jsxs4(ToolbarGroup4, { end: true, children: [
|
|
3764
|
+
/* @__PURE__ */ jsx4(TextButton3, { onClick: () => ui4({ kind: "toggleWrap" }), children: view.wrapLabel }),
|
|
3765
|
+
/* @__PURE__ */ jsx4(TextButton3, { onClick: () => ui4({ kind: "toggleWhitespace" }), children: view.whitespaceLabel }),
|
|
3766
|
+
/* @__PURE__ */ jsx4(TextButton3, { onClick: () => ui4({ kind: "prev" }), children: "Prev" }),
|
|
3767
|
+
/* @__PURE__ */ jsx4(TextButton3, { onClick: () => ui4({ kind: "next" }), children: "Next" })
|
|
3768
|
+
] })
|
|
3769
|
+
}
|
|
3770
|
+
),
|
|
3771
|
+
view.conflictNotice ? /* @__PURE__ */ jsx4(Note2, { children: /* @__PURE__ */ jsx4(Badge4, { tone: "error", children: view.conflictNotice }) }) : null,
|
|
3772
|
+
/* @__PURE__ */ jsx4(ScrollArea3, { children: view.files.map((f) => /* @__PURE__ */ jsxs4(
|
|
3773
|
+
Section,
|
|
3774
|
+
{
|
|
3775
|
+
title: /* @__PURE__ */ jsx4(Text3, { children: f.title }),
|
|
3776
|
+
badge: /* @__PURE__ */ jsx4(Badge4, { children: f.status }),
|
|
3777
|
+
actions: /* @__PURE__ */ jsx4(Text3, { role: "number", children: f.counts }),
|
|
3778
|
+
collapsible: true,
|
|
3779
|
+
collapsed: f.collapsed,
|
|
3780
|
+
flush: true,
|
|
3781
|
+
onCollapsedChange: (collapsed) => ui4({ kind: "collapse", path: f.path, collapsed }),
|
|
3782
|
+
children: [
|
|
3783
|
+
f.omitted ? /* @__PURE__ */ jsx4(Text3, { role: "meta", children: f.omission }) : null,
|
|
3784
|
+
f.hunks.map(hunk)
|
|
3785
|
+
]
|
|
3786
|
+
},
|
|
3787
|
+
f.key
|
|
3788
|
+
)) }),
|
|
3789
|
+
/* @__PURE__ */ jsx4(StatusBar4, { left: /* @__PURE__ */ jsx4(Text3, { role: "number", children: view.countLabel }), right: /* @__PURE__ */ jsx4(Text3, { role: "meta", children: view.rightLabel }) })
|
|
3790
|
+
] }) : null
|
|
3721
3791
|
] });
|
|
3722
3792
|
}
|
|
3723
3793
|
|
|
@@ -3830,6 +3900,9 @@ function createDiffPanel(options = {}) {
|
|
|
3830
3900
|
};
|
|
3831
3901
|
}
|
|
3832
3902
|
var diffPanel = createDiffPanel();
|
|
3903
|
+
|
|
3904
|
+
// src/ops/diff/index.ts
|
|
3905
|
+
var DIFF_RUNTIME_UNITS = [];
|
|
3833
3906
|
export {
|
|
3834
3907
|
ALL_STATUSES,
|
|
3835
3908
|
BEHAVIOURS as CONSOLE_BEHAVIOURS,
|
|
@@ -3840,7 +3913,10 @@ export {
|
|
|
3840
3913
|
ConsolePanelView,
|
|
3841
3914
|
ConsoleScroller,
|
|
3842
3915
|
DEFAULT_MAX_STEP_DEPTH,
|
|
3916
|
+
BEHAVIOURS3 as DIFF_BEHAVIOURS,
|
|
3917
|
+
DIFF_DECLARATION,
|
|
3843
3918
|
DIFF_PANEL_ID,
|
|
3919
|
+
DIFF_RUNTIME_UNITS,
|
|
3844
3920
|
DiffController,
|
|
3845
3921
|
DiffPanelView,
|
|
3846
3922
|
LEVEL_ORDER,
|
|
@@ -3861,6 +3937,7 @@ export {
|
|
|
3861
3937
|
XENO_TERMINAL_THEME_KEYS,
|
|
3862
3938
|
appendStepsAtPath,
|
|
3863
3939
|
applyConsoleUi,
|
|
3940
|
+
applyDiffUi,
|
|
3864
3941
|
applyRunsUi,
|
|
3865
3942
|
canCancel,
|
|
3866
3943
|
canRetry,
|
|
@@ -3879,6 +3956,8 @@ export {
|
|
|
3879
3956
|
decodeRunPath,
|
|
3880
3957
|
diffManifest,
|
|
3881
3958
|
diffPanel,
|
|
3959
|
+
diffViewManifest,
|
|
3960
|
+
diffViewState,
|
|
3882
3961
|
durationOf,
|
|
3883
3962
|
encodeRunPath,
|
|
3884
3963
|
flattenHunks,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.20",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
66
66
|
"@xenosystem/block-sdk": ">=0.3.4 <1",
|
|
67
|
-
"@xenosystem/components": ">=0.
|
|
67
|
+
"@xenosystem/components": ">=0.28.0 <1",
|
|
68
68
|
"@xenosystem/data-core": "^0.1.0",
|
|
69
69
|
"@xenosystem/elements": ">=0.0.1",
|
|
70
70
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react": "^19.0.0",
|
|
82
82
|
"@types/react-dom": "^19.0.0",
|
|
83
83
|
"@xenosystem/block-sdk": "^0.3.4",
|
|
84
|
-
"@xenosystem/components": "^0.
|
|
84
|
+
"@xenosystem/components": "^0.28.0",
|
|
85
85
|
"@xenosystem/data-core": "^0.1.0",
|
|
86
86
|
"@xenosystem/elements": "0.0.1",
|
|
87
87
|
"@xenosystem/elements-react": "0.0.1",
|