omkit 0.8.14 → 0.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -189,7 +189,7 @@ Every action's output, events, asserts, snapshots, and lifecycle land on **one t
189
189
  - `raw.jsonl` — every entry, machine-readable.
190
190
  - `main.log` + one `.log` per action — the human-readable timelines.
191
191
  - `events.log` / `asserts.log` / `snapshots.log` / `artifacts.log` — cross-cutting rollups.
192
- - `report.html` — the whole run as one self-contained page: a timeline of every action with its events, a flame graph, a flow graph of the tree, per-action details, logs, assertions, the run's snapshots and images, and each action's source (the `<>` button next to a block). Everything is inlined (data, base64 images, d3), so it opens straight from disk and survives being zipped or attached.
192
+ - `report.html` — the whole run as one self-contained page: a timeline of every action with its events, a flame graph, a flow graph of the tree, per-action details, logs, assertions, the run's snapshots and images, each action's source (the `<>` button next to a block), and an Errors tab that collects failures, failed assertions and error output, and can highlight the actions they came from in every graph. Everything is inlined (data, base64 images, d3), so it opens straight from disk and survives being zipped or attached.
193
193
 
194
194
  `ctx` also gives each action `assert(cond, msg)` (tallies into the run's verdict), `snapshot(name, value)` (captures JSON state to the run folder), and `artifact(name, file, opts?)` (labels a file the action wrote — name, optional description, MIME inferred from the extension — and returns its absolute path) — so a run is an inspectable artifact, not just an exit code. Write the files you label under `ctx.artifactsFolder`, the run's own output folder.
195
195
 
@@ -417,6 +417,7 @@ export class ExecutionTree {
417
417
  ...(meta.description === undefined ? {} : { description: { ...meta.description } }),
418
418
  ...(meta.mcp === undefined ? {} : { mcp: { ...meta.mcp } }),
419
419
  ...(inputSchema === undefined ? {} : { inputSchema }),
420
+ ...("inline" in meta && meta.inline ? { kind: "step" } : {}),
420
421
  };
421
422
  }
422
423
  /** Test seam: the projected run view (same object written to result.json). */
package/dist/core/step.js CHANGED
@@ -18,6 +18,7 @@ export function step(name, fn) {
18
18
  body: fn,
19
19
  definedAt: site,
20
20
  calledAt: site,
21
+ meta: { inline: true },
21
22
  };
22
23
  // `.result` already resolves the value and rejects on failure/cancel — exactly step's contract.
23
24
  return ExecutionTree.require().launch(spec).result;
@@ -254,4 +254,6 @@ export interface ActionMeta {
254
254
  readonly mcp?: ResolvedMcpExposure;
255
255
  /** Converts the declared args schema; called once, at finalize. */
256
256
  readonly describeArgs?: () => DescribedArgs;
257
+ /** Launched by `step(…)` — an inline action with no reusable definition. */
258
+ readonly inline?: boolean;
257
259
  }
@@ -170,10 +170,18 @@ button { font: inherit; color: inherit; }
170
170
  .axis line, .axis path { stroke: var(--line); }
171
171
 
172
172
  .flow-view, .flame-view { position: absolute; inset: 0; }
173
+ .flame-view { overflow-y: auto; overflow-x: hidden; }
173
174
  .flow-view svg, .flame-view svg { width: 100%; height: 100%; display: block; cursor: grab; }
174
175
  .flow-card rect.box { fill: var(--raise); stroke: var(--line); rx: 8; }
175
176
  .flow-card.selected rect.box { stroke: var(--accent); stroke-width: 2; }
176
177
  .flow-card text { fill: var(--text); font-size: 12px; }
178
+ .flow-card text.nm { font-weight: 600; }
179
+ .flow-card .flow-icon { pointer-events: none; }
180
+ .flow-seq { fill: none; stroke: var(--text-3); stroke-width: 1.4; stroke-dasharray: 5 4; }
181
+ .flow-seq.parallel { stroke-dasharray: 1 4; stroke-linecap: round; stroke-width: 2; opacity: 0.8; }
182
+ .flow-arrowhead { fill: var(--text-3); }
183
+ .flow-par { fill: var(--text-3); font-size: 10px; font-style: italic; }
184
+ .flow-shot-t { fill: var(--text-3); font-size: 10.5px; pointer-events: none; }
177
185
  .flow-card text.sub { fill: var(--text-3); font-size: 11px; }
178
186
  .flow-link { fill: none; stroke: var(--text-3); stroke-width: 1.3; }
179
187
  .flame-rect { cursor: pointer; stroke: var(--panel); stroke-width: 1; }
@@ -368,6 +376,55 @@ a.icon-btn { text-decoration: none; }
368
376
  .code-box .ln { color: var(--text-3); text-align: right; padding-right: 12px; user-select: none; }
369
377
  .code-box .lc { padding-right: 14px; }
370
378
 
379
+ /* ── errors ────────────────────────────────────────────── */
380
+ .tab-count { display: inline-block; min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--raise); color: var(--text-2); font-size: 11px; text-align: center; }
381
+ .tab-count.bad { background: rgba(239, 68, 68, 0.16); color: var(--fail); font-weight: 700; }
382
+ .linkish { border: 0; background: none; padding: 0; cursor: pointer; font: inherit; color: var(--accent); }
383
+ .linkish.bad { color: var(--fail); }
384
+ .linkish.warn { color: var(--cancel); }
385
+ .tab-count.warn { background: rgba(245, 158, 11, 0.16); color: var(--cancel); font-weight: 700; }
386
+ .linkish:hover { text-decoration: underline; }
387
+ .err-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
388
+ .segs { display: flex; border: 1px solid var(--line); border-radius: 7px; overflow: hidden; }
389
+ .seg { border: 0; background: var(--panel); padding: 4px 10px; cursor: pointer; color: var(--text-2); font-size: 12px; }
390
+ .seg + .seg { border-left: 1px solid var(--line); }
391
+ .seg.active { background: var(--accent-soft); color: var(--text); font-weight: 600; }
392
+ .btn.small.active { background: rgba(239, 68, 68, 0.14); color: var(--fail); border-color: var(--fail); }
393
+ .err-sec { margin-bottom: 10px; }
394
+ .err-sec-h { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 12px; color: var(--text-2); margin: 6px 0 4px; }
395
+ .err-sec-h svg { width: 13px; height: 13px; color: var(--fail); }
396
+ .err-entry { border: 1px solid var(--line-soft); border-left: 3px solid var(--fail); border-radius: 6px; margin-bottom: 4px; background: var(--panel); }
397
+ .err-entry.output { border-left-color: var(--cancel); }
398
+ .err-entry.assert { border-left-color: #f97316; }
399
+ .err-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; cursor: pointer; min-width: 0; font-size: 12px; }
400
+ .err-row:hover { background: var(--raise); }
401
+ .err-row .twist { width: 14px; height: 14px; display: grid; place-items: center; color: var(--text-3); flex: none; }
402
+ .err-row .twist svg { width: 11px; height: 11px; transition: transform 0.12s; }
403
+ .err-row .twist.open svg { transform: rotate(90deg); }
404
+ .err-row .t { color: var(--text-2); font-variant-numeric: tabular-nums; flex: none; min-width: 44px; }
405
+ .err-row .who { color: var(--text); font-weight: 600; flex: none; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
406
+ .err-row .err-src { color: var(--text-3); font-family: var(--mono); font-size: 11px; flex: none; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
407
+ .err-row .msg { flex: 1; min-width: 0; font-family: var(--mono); color: var(--fail); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
408
+ .err-entry.output .err-row .msg { color: var(--text-2); }
409
+ .err-row .err-n { color: var(--text-3); font-size: 11px; flex: none; }
410
+ .err-row .icon-btn { width: 22px; height: 20px; }
411
+ .err-text { margin: 0 8px 8px 28px; max-height: 260px; }
412
+ .err-kind { color: var(--fail); }
413
+ .errbadge { flex: none; min-width: 16px; height: 16px; padding: 0 5px; border-radius: 999px; background: var(--fail); color: #fff; font-size: 10px; font-weight: 700; display: inline-grid; place-items: center; }
414
+ /* highlight mode — errored nodes in red, the path to them marked, the rest dimmed */
415
+ #app.hl-on .chart g.r:not(.err):not(.err-path),
416
+ #app.hl-on .flame-view g.cell:not(.err):not(.err-path),
417
+ #app.hl-on .flow-card:not(.err):not(.err-path) { opacity: 0.22; }
418
+ #app.hl-on .tree .row:not(.err):not(.err-path) { opacity: 0.4; }
419
+ #app.hl-on .chart g.r.err rect.bar,
420
+ #app.hl-on .flame-view g.cell.err rect { stroke: var(--fail); stroke-width: 2.5; filter: drop-shadow(0 0 5px rgba(239, 68, 68, 0.75)); }
421
+ #app.hl-on .flow-card.err rect.box { stroke: var(--fail); stroke-width: 2.5; filter: drop-shadow(0 0 5px rgba(239, 68, 68, 0.6)); }
422
+ #app.hl-on .chart g.r.err-path rect.bar,
423
+ #app.hl-on .flame-view g.cell.err-path rect,
424
+ #app.hl-on .flow-card.err-path rect.box { stroke: var(--fail); stroke-width: 1.2; stroke-dasharray: 4 3; }
425
+ #app.hl-on .tree .row.err { background: rgba(239, 68, 68, 0.1); }
426
+ .chart g.r, .flame-view g.cell, .flow-card, .tree .row { transition: opacity 0.15s; }
427
+
371
428
  @media (max-width: 1100px) {
372
429
  .bottom { grid-template-columns: minmax(0, 1fr); }
373
430
  .legend, .overview { display: none; }