@contraagent/ui 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -2
- package/custom-elements.json +7286 -0
- package/dist/adapters/check-rows.d.ts +20 -0
- package/dist/adapters/check-rows.d.ts.map +1 -0
- package/dist/adapters/check-rows.js +77 -0
- package/dist/adapters/check-rows.js.map +1 -0
- package/dist/adapters/filters.d.ts +29 -0
- package/dist/adapters/filters.d.ts.map +1 -0
- package/dist/adapters/filters.js +74 -0
- package/dist/adapters/filters.js.map +1 -0
- package/dist/adapters/graph/compound.d.ts +93 -0
- package/dist/adapters/graph/compound.d.ts.map +1 -0
- package/dist/adapters/graph/compound.js +322 -0
- package/dist/adapters/graph/compound.js.map +1 -0
- package/dist/adapters/graph/flow-index.d.ts +54 -0
- package/dist/adapters/graph/flow-index.d.ts.map +1 -0
- package/dist/adapters/graph/flow-index.js +129 -0
- package/dist/adapters/graph/flow-index.js.map +1 -0
- package/dist/adapters/graph/highlight.d.ts +14 -0
- package/dist/adapters/graph/highlight.d.ts.map +1 -0
- package/dist/adapters/graph/highlight.js +33 -0
- package/dist/adapters/graph/highlight.js.map +1 -0
- package/dist/adapters/graph/input.d.ts +50 -0
- package/dist/adapters/graph/input.d.ts.map +1 -0
- package/dist/adapters/graph/input.js +201 -0
- package/dist/adapters/graph/input.js.map +1 -0
- package/dist/adapters/graph/layer.d.ts +33 -0
- package/dist/adapters/graph/layer.d.ts.map +1 -0
- package/dist/adapters/graph/layer.js +94 -0
- package/dist/adapters/graph/layer.js.map +1 -0
- package/dist/adapters/graph/matrix.d.ts +62 -0
- package/dist/adapters/graph/matrix.d.ts.map +1 -0
- package/dist/adapters/graph/matrix.js +96 -0
- package/dist/adapters/graph/matrix.js.map +1 -0
- package/dist/adapters/graph/project.d.ts +49 -0
- package/dist/adapters/graph/project.d.ts.map +1 -0
- package/dist/adapters/graph/project.js +319 -0
- package/dist/adapters/graph/project.js.map +1 -0
- package/dist/adapters/graph/selection.d.ts +31 -0
- package/dist/adapters/graph/selection.d.ts.map +1 -0
- package/dist/adapters/graph/selection.js +48 -0
- package/dist/adapters/graph/selection.js.map +1 -0
- package/dist/adapters/graph/states.d.ts +6 -0
- package/dist/adapters/graph/states.d.ts.map +1 -0
- package/dist/adapters/graph/states.js +5 -0
- package/dist/adapters/graph/states.js.map +1 -0
- package/dist/adapters/graph/types.d.ts +141 -0
- package/dist/adapters/graph/types.d.ts.map +1 -0
- package/dist/adapters/graph/types.js +3 -0
- package/dist/adapters/graph/types.js.map +1 -0
- package/dist/adapters/graph/words.d.ts +48 -0
- package/dist/adapters/graph/words.d.ts.map +1 -0
- package/dist/adapters/graph/words.js +128 -0
- package/dist/adapters/graph/words.js.map +1 -0
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +23 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/journal-columns.d.ts +21 -0
- package/dist/adapters/journal-columns.d.ts.map +1 -0
- package/dist/adapters/journal-columns.js +179 -0
- package/dist/adapters/journal-columns.js.map +1 -0
- package/dist/adapters/kpi-tiles.d.ts +47 -0
- package/dist/adapters/kpi-tiles.d.ts.map +1 -0
- package/dist/adapters/kpi-tiles.js +173 -0
- package/dist/adapters/kpi-tiles.js.map +1 -0
- package/dist/adapters/lanes.d.ts +31 -0
- package/dist/adapters/lanes.d.ts.map +1 -0
- package/dist/adapters/lanes.js +75 -0
- package/dist/adapters/lanes.js.map +1 -0
- package/dist/adapters/model-shares.d.ts +27 -0
- package/dist/adapters/model-shares.d.ts.map +1 -0
- package/dist/adapters/model-shares.js +52 -0
- package/dist/adapters/model-shares.js.map +1 -0
- package/dist/adapters/panel-body.d.ts +34 -0
- package/dist/adapters/panel-body.d.ts.map +1 -0
- package/dist/adapters/panel-body.js +90 -0
- package/dist/adapters/panel-body.js.map +1 -0
- package/dist/adapters/preflight.d.ts +12 -0
- package/dist/adapters/preflight.d.ts.map +1 -0
- package/dist/adapters/preflight.js +15 -0
- package/dist/adapters/preflight.js.map +1 -0
- package/dist/adapters/task-columns.d.ts +19 -0
- package/dist/adapters/task-columns.d.ts.map +1 -0
- package/dist/adapters/task-columns.js +107 -0
- package/dist/adapters/task-columns.js.map +1 -0
- package/dist/adapters/transcript/index.d.ts +6 -0
- package/dist/adapters/transcript/index.d.ts.map +1 -0
- package/dist/adapters/transcript/index.js +8 -0
- package/dist/adapters/transcript/index.js.map +1 -0
- package/dist/adapters/transcript/model.d.ts +42 -0
- package/dist/adapters/transcript/model.d.ts.map +1 -0
- package/dist/adapters/transcript/model.js +128 -0
- package/dist/adapters/transcript/model.js.map +1 -0
- package/dist/adapters/transcript/rounds.d.ts +15 -0
- package/dist/adapters/transcript/rounds.d.ts.map +1 -0
- package/dist/adapters/transcript/rounds.js +74 -0
- package/dist/adapters/transcript/rounds.js.map +1 -0
- package/dist/adapters/transcript/sections.d.ts +18 -0
- package/dist/adapters/transcript/sections.d.ts.map +1 -0
- package/dist/adapters/transcript/sections.js +69 -0
- package/dist/adapters/transcript/sections.js.map +1 -0
- package/dist/adapters/transcript/web.d.ts +12 -0
- package/dist/adapters/transcript/web.d.ts.map +1 -0
- package/dist/adapters/transcript/web.js +39 -0
- package/dist/adapters/transcript/web.js.map +1 -0
- package/dist/adapters/transcript/who.d.ts +15 -0
- package/dist/adapters/transcript/who.d.ts.map +1 -0
- package/dist/adapters/transcript/who.js +42 -0
- package/dist/adapters/transcript/who.js.map +1 -0
- package/dist/adapters/trends.d.ts +11 -0
- package/dist/adapters/trends.d.ts.map +1 -0
- package/dist/adapters/trends.js +316 -0
- package/dist/adapters/trends.js.map +1 -0
- package/dist/contraagent-ui.js +1028 -0
- package/dist/controllers/locale.d.ts +25 -0
- package/dist/controllers/locale.d.ts.map +1 -0
- package/dist/controllers/locale.js +33 -0
- package/dist/controllers/locale.js.map +1 -0
- package/dist/controllers/shortcuts.d.ts +29 -0
- package/dist/controllers/shortcuts.d.ts.map +1 -0
- package/dist/controllers/shortcuts.js +51 -0
- package/dist/controllers/shortcuts.js.map +1 -0
- package/dist/controllers/stream.d.ts +41 -0
- package/dist/controllers/stream.d.ts.map +1 -0
- package/dist/controllers/stream.js +90 -0
- package/dist/controllers/stream.js.map +1 -0
- package/dist/controllers/task-detail.d.ts +22 -0
- package/dist/controllers/task-detail.d.ts.map +1 -0
- package/dist/controllers/task-detail.js +50 -0
- package/dist/controllers/task-detail.js.map +1 -0
- package/dist/controllers/theme.d.ts +32 -0
- package/dist/controllers/theme.d.ts.map +1 -0
- package/dist/controllers/theme.js +56 -0
- package/dist/controllers/theme.js.map +1 -0
- package/dist/core/events.d.ts +107 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +5 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/i18n.d.ts +21 -0
- package/dist/core/i18n.d.ts.map +1 -0
- package/dist/core/i18n.js +71 -0
- package/dist/core/i18n.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/memory.d.ts +51 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +174 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/scroll.d.ts +21 -0
- package/dist/core/scroll.d.ts.map +1 -0
- package/dist/core/scroll.js +74 -0
- package/dist/core/scroll.js.map +1 -0
- package/dist/core/view-route.d.ts +62 -0
- package/dist/core/view-route.d.ts.map +1 -0
- package/dist/core/view-route.js +143 -0
- package/dist/core/view-route.js.map +1 -0
- package/dist/core/view-router.d.ts +27 -0
- package/dist/core/view-router.d.ts.map +1 -0
- package/dist/core/view-router.js +57 -0
- package/dist/core/view-router.js.map +1 -0
- package/dist/define/all.d.ts +13 -0
- package/dist/define/all.d.ts.map +1 -0
- package/dist/define/all.js +14 -0
- package/dist/define/all.js.map +1 -0
- package/dist/define/contracts.d.ts +2 -0
- package/dist/define/contracts.d.ts.map +1 -0
- package/dist/define/contracts.js +3 -0
- package/dist/define/contracts.js.map +1 -0
- package/dist/define/definitions.d.ts +3 -0
- package/dist/define/definitions.d.ts.map +1 -0
- package/dist/define/definitions.js +4 -0
- package/dist/define/definitions.js.map +1 -0
- package/dist/define/journal-table.d.ts +2 -0
- package/dist/define/journal-table.d.ts.map +1 -0
- package/dist/define/journal-table.js +3 -0
- package/dist/define/journal-table.js.map +1 -0
- package/dist/define/kpis.d.ts +2 -0
- package/dist/define/kpis.d.ts.map +1 -0
- package/dist/define/kpis.js +3 -0
- package/dist/define/kpis.js.map +1 -0
- package/dist/define/monitor.d.ts +2 -0
- package/dist/define/monitor.d.ts.map +1 -0
- package/dist/define/monitor.js +3 -0
- package/dist/define/monitor.js.map +1 -0
- package/dist/define/overview.d.ts +2 -0
- package/dist/define/overview.d.ts.map +1 -0
- package/dist/define/overview.js +3 -0
- package/dist/define/overview.js.map +1 -0
- package/dist/define/pipeline-graph.d.ts +2 -0
- package/dist/define/pipeline-graph.d.ts.map +1 -0
- package/dist/define/pipeline-graph.js +3 -0
- package/dist/define/pipeline-graph.js.map +1 -0
- package/dist/define/procs.d.ts +3 -0
- package/dist/define/procs.d.ts.map +1 -0
- package/dist/define/procs.js +4 -0
- package/dist/define/procs.js.map +1 -0
- package/dist/define/task-table.d.ts +2 -0
- package/dist/define/task-table.d.ts.map +1 -0
- package/dist/define/task-table.js +3 -0
- package/dist/define/task-table.js.map +1 -0
- package/dist/define/task-view.d.ts +2 -0
- package/dist/define/task-view.d.ts.map +1 -0
- package/dist/define/task-view.js +3 -0
- package/dist/define/task-view.js.map +1 -0
- package/dist/define/timeline.d.ts +2 -0
- package/dist/define/timeline.d.ts.map +1 -0
- package/dist/define/timeline.js +3 -0
- package/dist/define/timeline.js.map +1 -0
- package/dist/define/transcript.d.ts +2 -0
- package/dist/define/transcript.d.ts.map +1 -0
- package/dist/define/transcript.js +3 -0
- package/dist/define/transcript.js.map +1 -0
- package/dist/elements/lists/ca-contracts.d.ts +46 -0
- package/dist/elements/lists/ca-contracts.d.ts.map +1 -0
- package/dist/elements/lists/ca-contracts.js +199 -0
- package/dist/elements/lists/ca-contracts.js.map +1 -0
- package/dist/elements/lists/ca-definitions.d.ts +41 -0
- package/dist/elements/lists/ca-definitions.d.ts.map +1 -0
- package/dist/elements/lists/ca-definitions.js +182 -0
- package/dist/elements/lists/ca-definitions.js.map +1 -0
- package/dist/elements/lists/ca-journal-table.d.ts +37 -0
- package/dist/elements/lists/ca-journal-table.d.ts.map +1 -0
- package/dist/elements/lists/ca-journal-table.js +170 -0
- package/dist/elements/lists/ca-journal-table.js.map +1 -0
- package/dist/elements/lists/ca-panel-body.d.ts +42 -0
- package/dist/elements/lists/ca-panel-body.d.ts.map +1 -0
- package/dist/elements/lists/ca-panel-body.js +210 -0
- package/dist/elements/lists/ca-panel-body.js.map +1 -0
- package/dist/elements/lists/ca-panel-view.d.ts +21 -0
- package/dist/elements/lists/ca-panel-view.d.ts.map +1 -0
- package/dist/elements/lists/ca-panel-view.js +59 -0
- package/dist/elements/lists/ca-panel-view.js.map +1 -0
- package/dist/elements/lists/ca-proc-tree.d.ts +16 -0
- package/dist/elements/lists/ca-proc-tree.d.ts.map +1 -0
- package/dist/elements/lists/ca-proc-tree.js +63 -0
- package/dist/elements/lists/ca-proc-tree.js.map +1 -0
- package/dist/elements/lists/ca-procs-view.d.ts +27 -0
- package/dist/elements/lists/ca-procs-view.d.ts.map +1 -0
- package/dist/elements/lists/ca-procs-view.js +91 -0
- package/dist/elements/lists/ca-procs-view.js.map +1 -0
- package/dist/elements/lists/ca-task-table.d.ts +33 -0
- package/dist/elements/lists/ca-task-table.d.ts.map +1 -0
- package/dist/elements/lists/ca-task-table.js +115 -0
- package/dist/elements/lists/ca-task-table.js.map +1 -0
- package/dist/elements/lists/index.d.ts +9 -0
- package/dist/elements/lists/index.d.ts.map +1 -0
- package/dist/elements/lists/index.js +9 -0
- package/dist/elements/lists/index.js.map +1 -0
- package/dist/elements/overview/ca-kpis.d.ts +32 -0
- package/dist/elements/overview/ca-kpis.d.ts.map +1 -0
- package/dist/elements/overview/ca-kpis.js +62 -0
- package/dist/elements/overview/ca-kpis.js.map +1 -0
- package/dist/elements/overview/ca-model-usage.d.ts +25 -0
- package/dist/elements/overview/ca-model-usage.d.ts.map +1 -0
- package/dist/elements/overview/ca-model-usage.js +118 -0
- package/dist/elements/overview/ca-model-usage.js.map +1 -0
- package/dist/elements/overview/ca-overview.d.ts +67 -0
- package/dist/elements/overview/ca-overview.d.ts.map +1 -0
- package/dist/elements/overview/ca-overview.js +463 -0
- package/dist/elements/overview/ca-overview.js.map +1 -0
- package/dist/elements/overview/ca-pipeline-graph.d.ts +211 -0
- package/dist/elements/overview/ca-pipeline-graph.d.ts.map +1 -0
- package/dist/elements/overview/ca-pipeline-graph.js +616 -0
- package/dist/elements/overview/ca-pipeline-graph.js.map +1 -0
- package/dist/elements/overview/ca-quota.d.ts +42 -0
- package/dist/elements/overview/ca-quota.d.ts.map +1 -0
- package/dist/elements/overview/ca-quota.js +179 -0
- package/dist/elements/overview/ca-quota.js.map +1 -0
- package/dist/elements/overview/ca-run-driver.d.ts +33 -0
- package/dist/elements/overview/ca-run-driver.d.ts.map +1 -0
- package/dist/elements/overview/ca-run-driver.js +146 -0
- package/dist/elements/overview/ca-run-driver.js.map +1 -0
- package/dist/elements/overview/ca-services.d.ts +25 -0
- package/dist/elements/overview/ca-services.d.ts.map +1 -0
- package/dist/elements/overview/ca-services.js +77 -0
- package/dist/elements/overview/ca-services.js.map +1 -0
- package/dist/elements/overview/ca-spend-breakdown.d.ts +24 -0
- package/dist/elements/overview/ca-spend-breakdown.d.ts.map +1 -0
- package/dist/elements/overview/ca-spend-breakdown.js +108 -0
- package/dist/elements/overview/ca-spend-breakdown.js.map +1 -0
- package/dist/elements/overview/ca-timeline.d.ts +28 -0
- package/dist/elements/overview/ca-timeline.d.ts.map +1 -0
- package/dist/elements/overview/ca-timeline.js +72 -0
- package/dist/elements/overview/ca-timeline.js.map +1 -0
- package/dist/elements/overview/ca-workers.d.ts +23 -0
- package/dist/elements/overview/ca-workers.d.ts.map +1 -0
- package/dist/elements/overview/ca-workers.js +86 -0
- package/dist/elements/overview/ca-workers.js.map +1 -0
- package/dist/elements/overview/index.d.ts +11 -0
- package/dist/elements/overview/index.d.ts.map +1 -0
- package/dist/elements/overview/index.js +11 -0
- package/dist/elements/overview/index.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/actions.d.ts +16 -0
- package/dist/elements/overview/pipeline-graph/actions.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/actions.js +42 -0
- package/dist/elements/overview/pipeline-graph/actions.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/crumbs.d.ts +15 -0
- package/dist/elements/overview/pipeline-graph/crumbs.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/crumbs.js +70 -0
- package/dist/elements/overview/pipeline-graph/crumbs.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/host.d.ts +24 -0
- package/dist/elements/overview/pipeline-graph/host.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/host.js +2 -0
- package/dist/elements/overview/pipeline-graph/host.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/inspector.d.ts +5 -0
- package/dist/elements/overview/pipeline-graph/inspector.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/inspector.js +100 -0
- package/dist/elements/overview/pipeline-graph/inspector.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/outline.d.ts +53 -0
- package/dist/elements/overview/pipeline-graph/outline.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/outline.js +111 -0
- package/dist/elements/overview/pipeline-graph/outline.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/strings.d.ts +11 -0
- package/dist/elements/overview/pipeline-graph/strings.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/strings.js +49 -0
- package/dist/elements/overview/pipeline-graph/strings.js.map +1 -0
- package/dist/elements/overview/pipeline-graph/styles.d.ts +4 -0
- package/dist/elements/overview/pipeline-graph/styles.d.ts.map +1 -0
- package/dist/elements/overview/pipeline-graph/styles.js +96 -0
- package/dist/elements/overview/pipeline-graph/styles.js.map +1 -0
- package/dist/elements/shared/ca-definition.d.ts +26 -0
- package/dist/elements/shared/ca-definition.d.ts.map +1 -0
- package/dist/elements/shared/ca-definition.js +202 -0
- package/dist/elements/shared/ca-definition.js.map +1 -0
- package/dist/elements/shared/contract-parts.d.ts +35 -0
- package/dist/elements/shared/contract-parts.d.ts.map +1 -0
- package/dist/elements/shared/contract-parts.js +167 -0
- package/dist/elements/shared/contract-parts.js.map +1 -0
- package/dist/elements/shared/file-card.d.ts +17 -0
- package/dist/elements/shared/file-card.d.ts.map +1 -0
- package/dist/elements/shared/file-card.js +37 -0
- package/dist/elements/shared/file-card.js.map +1 -0
- package/dist/elements/shared/prompt-text.d.ts +5 -0
- package/dist/elements/shared/prompt-text.d.ts.map +1 -0
- package/dist/elements/shared/prompt-text.js +13 -0
- package/dist/elements/shared/prompt-text.js.map +1 -0
- package/dist/elements/shared/task-chip.d.ts +10 -0
- package/dist/elements/shared/task-chip.d.ts.map +1 -0
- package/dist/elements/shared/task-chip.js +19 -0
- package/dist/elements/shared/task-chip.js.map +1 -0
- package/dist/elements/shell/ca-clock.d.ts +13 -0
- package/dist/elements/shell/ca-clock.d.ts.map +1 -0
- package/dist/elements/shell/ca-clock.js +30 -0
- package/dist/elements/shell/ca-clock.js.map +1 -0
- package/dist/elements/shell/ca-hosts.d.ts +21 -0
- package/dist/elements/shell/ca-hosts.d.ts.map +1 -0
- package/dist/elements/shell/ca-hosts.js +97 -0
- package/dist/elements/shell/ca-hosts.js.map +1 -0
- package/dist/elements/shell/ca-monitor.d.ts +182 -0
- package/dist/elements/shell/ca-monitor.d.ts.map +1 -0
- package/dist/elements/shell/ca-monitor.js +549 -0
- package/dist/elements/shell/ca-monitor.js.map +1 -0
- package/dist/elements/shell/ca-run-picker.d.ts +71 -0
- package/dist/elements/shell/ca-run-picker.d.ts.map +1 -0
- package/dist/elements/shell/ca-run-picker.js +313 -0
- package/dist/elements/shell/ca-run-picker.js.map +1 -0
- package/dist/elements/shell/ca-theme-switch.d.ts +36 -0
- package/dist/elements/shell/ca-theme-switch.d.ts.map +1 -0
- package/dist/elements/shell/ca-theme-switch.js +186 -0
- package/dist/elements/shell/ca-theme-switch.js.map +1 -0
- package/dist/elements/shell/ca-toasts.d.ts +23 -0
- package/dist/elements/shell/ca-toasts.d.ts.map +1 -0
- package/dist/elements/shell/ca-toasts.js +88 -0
- package/dist/elements/shell/ca-toasts.js.map +1 -0
- package/dist/elements/shell/header.d.ts +13 -0
- package/dist/elements/shell/header.d.ts.map +1 -0
- package/dist/elements/shell/header.js +38 -0
- package/dist/elements/shell/header.js.map +1 -0
- package/dist/elements/shell/styles.d.ts +2 -0
- package/dist/elements/shell/styles.d.ts.map +1 -0
- package/dist/elements/shell/styles.js +72 -0
- package/dist/elements/shell/styles.js.map +1 -0
- package/dist/elements/shell/tabs.d.ts +32 -0
- package/dist/elements/shell/tabs.d.ts.map +1 -0
- package/dist/elements/shell/tabs.js +125 -0
- package/dist/elements/shell/tabs.js.map +1 -0
- package/dist/elements/shell/views.d.ts +27 -0
- package/dist/elements/shell/views.d.ts.map +1 -0
- package/dist/elements/shell/views.js +55 -0
- package/dist/elements/shell/views.js.map +1 -0
- package/dist/elements/task/ca-task-view.d.ts +55 -0
- package/dist/elements/task/ca-task-view.d.ts.map +1 -0
- package/dist/elements/task/ca-task-view.js +199 -0
- package/dist/elements/task/ca-task-view.js.map +1 -0
- package/dist/elements/task/ca-transcript.d.ts +74 -0
- package/dist/elements/task/ca-transcript.d.ts.map +1 -0
- package/dist/elements/task/ca-transcript.js +241 -0
- package/dist/elements/task/ca-transcript.js.map +1 -0
- package/dist/elements/task/context.d.ts +57 -0
- package/dist/elements/task/context.d.ts.map +1 -0
- package/dist/elements/task/context.js +61 -0
- package/dist/elements/task/context.js.map +1 -0
- package/dist/elements/task/header.d.ts +9 -0
- package/dist/elements/task/header.d.ts.map +1 -0
- package/dist/elements/task/header.js +291 -0
- package/dist/elements/task/header.js.map +1 -0
- package/dist/elements/task/index.d.ts +3 -0
- package/dist/elements/task/index.d.ts.map +1 -0
- package/dist/elements/task/index.js +3 -0
- package/dist/elements/task/index.js.map +1 -0
- package/dist/elements/task/inputs.d.ts +28 -0
- package/dist/elements/task/inputs.d.ts.map +1 -0
- package/dist/elements/task/inputs.js +27 -0
- package/dist/elements/task/inputs.js.map +1 -0
- package/dist/elements/task/panes/definition.d.ts +5 -0
- package/dist/elements/task/panes/definition.d.ts.map +1 -0
- package/dist/elements/task/panes/definition.js +5 -0
- package/dist/elements/task/panes/definition.js.map +1 -0
- package/dist/elements/task/panes/io.d.ts +8 -0
- package/dist/elements/task/panes/io.d.ts.map +1 -0
- package/dist/elements/task/panes/io.js +184 -0
- package/dist/elements/task/panes/io.js.map +1 -0
- package/dist/elements/task/panes/transcript.d.ts +5 -0
- package/dist/elements/task/panes/transcript.d.ts.map +1 -0
- package/dist/elements/task/panes/transcript.js +29 -0
- package/dist/elements/task/panes/transcript.js.map +1 -0
- package/dist/elements/task/styles.d.ts +2 -0
- package/dist/elements/task/styles.d.ts.map +1 -0
- package/dist/elements/task/styles.js +66 -0
- package/dist/elements/task/styles.js.map +1 -0
- package/dist/elements/trends/ca-trends.d.ts +55 -0
- package/dist/elements/trends/ca-trends.d.ts.map +1 -0
- package/dist/elements/trends/ca-trends.js +213 -0
- package/dist/elements/trends/ca-trends.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/tone.d.ts +29 -0
- package/dist/lib/tone.d.ts.map +1 -0
- package/dist/lib/tone.js +97 -0
- package/dist/lib/tone.js.map +1 -0
- package/dist/lib/trends.d.ts +15 -0
- package/dist/lib/trends.d.ts.map +1 -0
- package/dist/lib/trends.js +36 -0
- package/dist/lib/trends.js.map +1 -0
- package/dist/locales/codes.d.ts +14 -0
- package/dist/locales/codes.d.ts.map +1 -0
- package/dist/locales/codes.js +21 -0
- package/dist/locales/codes.js.map +1 -0
- package/dist/locales/ja.d.ts +785 -0
- package/dist/locales/ja.d.ts.map +1 -0
- package/dist/locales/ja.js +791 -0
- package/dist/locales/ja.js.map +1 -0
- package/dist/words/api-error.d.ts +4 -0
- package/dist/words/api-error.d.ts.map +1 -0
- package/dist/words/api-error.js +13 -0
- package/dist/words/api-error.js.map +1 -0
- package/dist/words/attempts.d.ts +17 -0
- package/dist/words/attempts.d.ts.map +1 -0
- package/dist/words/attempts.js +26 -0
- package/dist/words/attempts.js.map +1 -0
- package/dist/words/causes.d.ts +33 -0
- package/dist/words/causes.d.ts.map +1 -0
- package/dist/words/causes.js +58 -0
- package/dist/words/causes.js.map +1 -0
- package/dist/words/changes.d.ts +9 -0
- package/dist/words/changes.d.ts.map +1 -0
- package/dist/words/changes.js +23 -0
- package/dist/words/changes.js.map +1 -0
- package/dist/words/claims.d.ts +9 -0
- package/dist/words/claims.d.ts.map +1 -0
- package/dist/words/claims.js +12 -0
- package/dist/words/claims.js.map +1 -0
- package/dist/words/context.d.ts +18 -0
- package/dist/words/context.d.ts.map +1 -0
- package/dist/words/context.js +39 -0
- package/dist/words/context.js.map +1 -0
- package/dist/words/contract.d.ts +25 -0
- package/dist/words/contract.d.ts.map +1 -0
- package/dist/words/contract.js +52 -0
- package/dist/words/contract.js.map +1 -0
- package/dist/words/credential.d.ts +5 -0
- package/dist/words/credential.d.ts.map +1 -0
- package/dist/words/credential.js +7 -0
- package/dist/words/credential.js.map +1 -0
- package/dist/words/executor.d.ts +12 -0
- package/dist/words/executor.d.ts.map +1 -0
- package/dist/words/executor.js +20 -0
- package/dist/words/executor.js.map +1 -0
- package/dist/words/export.d.ts +8 -0
- package/dist/words/export.d.ts.map +1 -0
- package/dist/words/export.js +17 -0
- package/dist/words/export.js.map +1 -0
- package/dist/words/format.d.ts +36 -0
- package/dist/words/format.d.ts.map +1 -0
- package/dist/words/format.js +109 -0
- package/dist/words/format.js.map +1 -0
- package/dist/words/hops.d.ts +12 -0
- package/dist/words/hops.d.ts.map +1 -0
- package/dist/words/hops.js +27 -0
- package/dist/words/hops.js.map +1 -0
- package/dist/words/hosts.d.ts +18 -0
- package/dist/words/hosts.d.ts.map +1 -0
- package/dist/words/hosts.js +22 -0
- package/dist/words/hosts.js.map +1 -0
- package/dist/words/index.d.ts +28 -0
- package/dist/words/index.d.ts.map +1 -0
- package/dist/words/index.js +32 -0
- package/dist/words/index.js.map +1 -0
- package/dist/words/models.d.ts +10 -0
- package/dist/words/models.d.ts.map +1 -0
- package/dist/words/models.js +45 -0
- package/dist/words/models.js.map +1 -0
- package/dist/words/outcome.d.ts +14 -0
- package/dist/words/outcome.d.ts.map +1 -0
- package/dist/words/outcome.js +58 -0
- package/dist/words/outcome.js.map +1 -0
- package/dist/words/panels.d.ts +17 -0
- package/dist/words/panels.d.ts.map +1 -0
- package/dist/words/panels.js +63 -0
- package/dist/words/panels.js.map +1 -0
- package/dist/words/passes.d.ts +11 -0
- package/dist/words/passes.d.ts.map +1 -0
- package/dist/words/passes.js +13 -0
- package/dist/words/passes.js.map +1 -0
- package/dist/words/preflight.d.ts +28 -0
- package/dist/words/preflight.d.ts.map +1 -0
- package/dist/words/preflight.js +30 -0
- package/dist/words/preflight.js.map +1 -0
- package/dist/words/priority.d.ts +5 -0
- package/dist/words/priority.d.ts.map +1 -0
- package/dist/words/priority.js +7 -0
- package/dist/words/priority.js.map +1 -0
- package/dist/words/prompt.d.ts +10 -0
- package/dist/words/prompt.d.ts.map +1 -0
- package/dist/words/prompt.js +17 -0
- package/dist/words/prompt.js.map +1 -0
- package/dist/words/quota.d.ts +35 -0
- package/dist/words/quota.d.ts.map +1 -0
- package/dist/words/quota.js +102 -0
- package/dist/words/quota.js.map +1 -0
- package/dist/words/rests.d.ts +26 -0
- package/dist/words/rests.d.ts.map +1 -0
- package/dist/words/rests.js +77 -0
- package/dist/words/rests.js.map +1 -0
- package/dist/words/rounds.d.ts +14 -0
- package/dist/words/rounds.d.ts.map +1 -0
- package/dist/words/rounds.js +60 -0
- package/dist/words/rounds.js.map +1 -0
- package/dist/words/row-extras.d.ts +7 -0
- package/dist/words/row-extras.d.ts.map +1 -0
- package/dist/words/row-extras.js +26 -0
- package/dist/words/row-extras.js.map +1 -0
- package/dist/words/run-line.d.ts +40 -0
- package/dist/words/run-line.d.ts.map +1 -0
- package/dist/words/run-line.js +66 -0
- package/dist/words/run-line.js.map +1 -0
- package/dist/words/services.d.ts +16 -0
- package/dist/words/services.d.ts.map +1 -0
- package/dist/words/services.js +45 -0
- package/dist/words/services.js.map +1 -0
- package/dist/words/stop.d.ts +6 -0
- package/dist/words/stop.d.ts.map +1 -0
- package/dist/words/stop.js +69 -0
- package/dist/words/stop.js.map +1 -0
- package/dist/words/table.d.ts +4 -0
- package/dist/words/table.d.ts.map +1 -0
- package/dist/words/table.js +8 -0
- package/dist/words/table.js.map +1 -0
- package/dist/words/task-definition.d.ts +23 -0
- package/dist/words/task-definition.d.ts.map +1 -0
- package/dist/words/task-definition.js +27 -0
- package/dist/words/task-definition.js.map +1 -0
- package/dist/words/time-box.d.ts +8 -0
- package/dist/words/time-box.d.ts.map +1 -0
- package/dist/words/time-box.js +12 -0
- package/dist/words/time-box.js.map +1 -0
- package/dist/words/trends.d.ts +86 -0
- package/dist/words/trends.d.ts.map +1 -0
- package/dist/words/trends.js +104 -0
- package/dist/words/trends.js.map +1 -0
- package/docs/embed.md +121 -0
- package/docs/events.md +38 -0
- package/docs/examples/embed.html +31 -0
- package/docs/examples/journal.ts +32 -0
- package/docs/examples/live-transcript.ts +22 -0
- package/docs/examples/vite/index.html +30 -0
- package/docs/examples/vite/main.ts +23 -0
- package/docs/languages.md +48 -0
- package/docs/live-data.md +17 -0
- package/docs/theming.md +21 -0
- package/docs/tsconfig.json +14 -0
- package/package.json +131 -4
- package/src/adapters/check-rows.ts +81 -0
- package/src/adapters/filters.ts +76 -0
- package/src/adapters/graph/compound.ts +359 -0
- package/src/adapters/graph/flow-index.ts +154 -0
- package/src/adapters/graph/highlight.ts +40 -0
- package/src/adapters/graph/input.ts +236 -0
- package/src/adapters/graph/layer.ts +92 -0
- package/src/adapters/graph/matrix.ts +133 -0
- package/src/adapters/graph/plans.fixture.ts +194 -0
- package/src/adapters/graph/project.ts +358 -0
- package/src/adapters/graph/selection.ts +54 -0
- package/src/adapters/graph/states.ts +10 -0
- package/src/adapters/graph/types.ts +148 -0
- package/src/adapters/graph/words.ts +146 -0
- package/src/adapters/index.ts +22 -0
- package/src/adapters/journal-columns.ts +200 -0
- package/src/adapters/kpi-tiles.ts +211 -0
- package/src/adapters/lanes.ts +98 -0
- package/src/adapters/model-shares.ts +62 -0
- package/src/adapters/panel-body.ts +112 -0
- package/src/adapters/preflight.ts +27 -0
- package/src/adapters/task-columns.ts +120 -0
- package/src/adapters/transcript/index.ts +14 -0
- package/src/adapters/transcript/model.ts +156 -0
- package/src/adapters/transcript/rounds.ts +86 -0
- package/src/adapters/transcript/sections.ts +82 -0
- package/src/adapters/transcript/web.ts +40 -0
- package/src/adapters/transcript/who.ts +53 -0
- package/src/adapters/trends.ts +337 -0
- package/src/controllers/locale.ts +47 -0
- package/src/controllers/shortcuts.ts +69 -0
- package/src/controllers/stream.ts +103 -0
- package/src/controllers/task-detail.ts +54 -0
- package/src/controllers/theme.ts +73 -0
- package/src/core/events.ts +120 -0
- package/src/core/i18n.ts +76 -0
- package/src/core/index.ts +6 -0
- package/src/core/memory.ts +177 -0
- package/src/core/scroll.ts +73 -0
- package/src/core/view-route.ts +177 -0
- package/src/core/view-router.ts +66 -0
- package/src/define/all.ts +13 -0
- package/src/define/contracts.ts +2 -0
- package/src/define/definitions.ts +3 -0
- package/src/define/journal-table.ts +2 -0
- package/src/define/kpis.ts +2 -0
- package/src/define/monitor.ts +2 -0
- package/src/define/overview.ts +2 -0
- package/src/define/pipeline-graph.ts +2 -0
- package/src/define/procs.ts +3 -0
- package/src/define/task-table.ts +2 -0
- package/src/define/task-view.ts +2 -0
- package/src/define/timeline.ts +2 -0
- package/src/define/transcript.ts +2 -0
- package/src/elements/lists/ca-contracts.ts +204 -0
- package/src/elements/lists/ca-definitions.ts +170 -0
- package/src/elements/lists/ca-journal-table.ts +141 -0
- package/src/elements/lists/ca-panel-body.ts +200 -0
- package/src/elements/lists/ca-panel-view.ts +50 -0
- package/src/elements/lists/ca-proc-tree.ts +57 -0
- package/src/elements/lists/ca-procs-view.ts +89 -0
- package/src/elements/lists/ca-task-table.ts +94 -0
- package/src/elements/lists/index.ts +8 -0
- package/src/elements/overview/ca-kpis.ts +51 -0
- package/src/elements/overview/ca-model-usage.ts +113 -0
- package/src/elements/overview/ca-overview.ts +499 -0
- package/src/elements/overview/ca-pipeline-graph.ts +617 -0
- package/src/elements/overview/ca-quota.ts +164 -0
- package/src/elements/overview/ca-run-driver.ts +140 -0
- package/src/elements/overview/ca-services.ts +66 -0
- package/src/elements/overview/ca-spend-breakdown.ts +107 -0
- package/src/elements/overview/ca-timeline.ts +57 -0
- package/src/elements/overview/ca-workers.ts +82 -0
- package/src/elements/overview/index.ts +10 -0
- package/src/elements/overview/pipeline-graph/actions.ts +45 -0
- package/src/elements/overview/pipeline-graph/crumbs.ts +75 -0
- package/src/elements/overview/pipeline-graph/host.ts +26 -0
- package/src/elements/overview/pipeline-graph/inspector.ts +104 -0
- package/src/elements/overview/pipeline-graph/outline.ts +150 -0
- package/src/elements/overview/pipeline-graph/strings.ts +53 -0
- package/src/elements/overview/pipeline-graph/styles.ts +97 -0
- package/src/elements/shared/ca-definition.ts +206 -0
- package/src/elements/shared/contract-parts.ts +174 -0
- package/src/elements/shared/file-card.ts +49 -0
- package/src/elements/shared/prompt-text.ts +13 -0
- package/src/elements/shared/task-chip.ts +18 -0
- package/src/elements/shell/ca-clock.ts +27 -0
- package/src/elements/shell/ca-hosts.ts +93 -0
- package/src/elements/shell/ca-monitor.ts +528 -0
- package/src/elements/shell/ca-run-picker.ts +284 -0
- package/src/elements/shell/ca-theme-switch.ts +170 -0
- package/src/elements/shell/ca-toasts.ts +100 -0
- package/src/elements/shell/header.ts +45 -0
- package/src/elements/shell/styles.ts +72 -0
- package/src/elements/shell/tabs.ts +143 -0
- package/src/elements/shell/views.ts +67 -0
- package/src/elements/task/ca-task-view.ts +157 -0
- package/src/elements/task/ca-transcript.ts +214 -0
- package/src/elements/task/context.ts +105 -0
- package/src/elements/task/header.ts +296 -0
- package/src/elements/task/index.ts +2 -0
- package/src/elements/task/inputs.ts +46 -0
- package/src/elements/task/panes/definition.ts +7 -0
- package/src/elements/task/panes/io.ts +190 -0
- package/src/elements/task/panes/transcript.ts +29 -0
- package/src/elements/task/styles.ts +66 -0
- package/src/elements/trends/ca-trends.ts +204 -0
- package/src/index.ts +23 -0
- package/src/lib/tone.ts +109 -0
- package/src/lib/trends.ts +44 -0
- package/src/locales/codes.ts +23 -0
- package/src/locales/ja.ts +795 -0
- package/src/words/api-error.ts +17 -0
- package/src/words/attempts.ts +28 -0
- package/src/words/causes.ts +67 -0
- package/src/words/changes.ts +29 -0
- package/src/words/claims.ts +16 -0
- package/src/words/context.ts +47 -0
- package/src/words/contract.ts +63 -0
- package/src/words/credential.ts +8 -0
- package/src/words/executor.ts +22 -0
- package/src/words/export.ts +22 -0
- package/src/words/format.ts +107 -0
- package/src/words/hops.ts +30 -0
- package/src/words/hosts.ts +37 -0
- package/src/words/index.ts +31 -0
- package/src/words/models.ts +50 -0
- package/src/words/outcome.ts +61 -0
- package/src/words/panels.ts +71 -0
- package/src/words/passes.ts +18 -0
- package/src/words/preflight.ts +53 -0
- package/src/words/priority.ts +8 -0
- package/src/words/prompt.ts +20 -0
- package/src/words/quota.ts +108 -0
- package/src/words/rests.ts +96 -0
- package/src/words/rounds.ts +56 -0
- package/src/words/row-extras.ts +24 -0
- package/src/words/run-line.ts +77 -0
- package/src/words/services.ts +57 -0
- package/src/words/stop.ts +65 -0
- package/src/words/table.ts +10 -0
- package/src/words/task-definition.ts +37 -0
- package/src/words/time-box.ts +21 -0
- package/src/words/trends.ts +118 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// A layer of the run's flow as `<cae-layered-graph>` takes it, and a loop's passes
|
|
2
|
+
// as `<cae-mark-matrix>` takes them: the pipeline graph's words on the generic model.
|
|
3
|
+
import { deriveRun, type JournalRow, type Plan } from '@contraagent/api';
|
|
4
|
+
import type { GraphClusterInput, GraphInput, GraphMark, GraphNodeInput, GraphOrder } from '@contraagent/elements/graph';
|
|
5
|
+
import type { MarkMatrixInput, MatrixHeadCell, MatrixMark } from '@contraagent/elements/matrix';
|
|
6
|
+
import type { Fact } from '@contraagent/elements/primitives';
|
|
7
|
+
import { msg, str } from '@lit/localize';
|
|
8
|
+
import { facts, listText } from '../../words/format.js';
|
|
9
|
+
import { loopLabel, notStartedCause, passCount, passLabel, passSpread } from '../../words/index.js';
|
|
10
|
+
import type { TaskLinks } from './highlight.js';
|
|
11
|
+
import { passMatrix, sortRows, type MatrixSort, type PassMatrix } from './matrix.js';
|
|
12
|
+
import { edgeStyle, project, type Projection } from './project.js';
|
|
13
|
+
import { markSel } from './selection.js';
|
|
14
|
+
import type { GraphNode, LayerMark, LayerModel, LoopBox } from './types.js';
|
|
15
|
+
import { doneOf, exceptions, executorWord, markText, nodeLabel, nodeTip, where, type ExceptionClass, type MarkContext } from './words.js';
|
|
16
|
+
|
|
17
|
+
/** What the words of the marks read: the run's tasks, why a task did not start, and the run being live. */
|
|
18
|
+
export interface GraphWordsContext {
|
|
19
|
+
plan: Plan;
|
|
20
|
+
journal: readonly JournalRow[];
|
|
21
|
+
/** The run id: paths in a cause are shown relative to it. */
|
|
22
|
+
run: string;
|
|
23
|
+
live: boolean;
|
|
24
|
+
links: TaskLinks;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A note's tone by the class of a node's fact. */
|
|
28
|
+
const NOTE_TONE: Record<ExceptionClass, Fact['tone']> = { err: 'failed', warn: 'attention', live: 'running', mut: 'muted' };
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/** Why a task did not start, in words ('' when it is not known). */
|
|
32
|
+
export function causeOf(x: Pick<GraphWordsContext, 'plan' | 'journal' | 'run'>): (key: string) => string {
|
|
33
|
+
return (key) => {
|
|
34
|
+
const { outcomes } = deriveRun(x.journal, x.plan);
|
|
35
|
+
const t = outcomes.get(key);
|
|
36
|
+
return t ? notStartedCause(t, outcomes, x.run) : '';
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const markContext = (x: GraphWordsContext): ((m: LayerMark) => MarkContext) => {
|
|
41
|
+
const cause = causeOf(x);
|
|
42
|
+
return (m) => ({ task: x.links.byKey.get(m.key), causeOf: cause, live: x.live });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** Where a loop is, as its box and its passes name it: "Loop at flow.py:12". */
|
|
46
|
+
const loopAt = (b: Pick<LoopBox, 'loop' | 'file'>): string => msg(str`Loop at ${where(b.loop, b.file)}`);
|
|
47
|
+
|
|
48
|
+
/** The executors' icons, as `executorIcon` draws them: `agent`, `python`. */
|
|
49
|
+
const iconsOf = (n: GraphNode): string[] => (n.executor === 'mixed' ? ['agent', 'python'] : n.executor ? [n.executor] : []);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The layer as the generic graph takes it: a node per kind or function (an agent
|
|
53
|
+
* task's node with an accent, a function node with an inner view), a cluster per
|
|
54
|
+
* loop box (it cycles: its return is the loop's next pass), a solid edge per
|
|
55
|
+
* `after` and a dashed one per `created_from`, and the units as the series. Its
|
|
56
|
+
* nodes are in the plan's order, as `arrange` reads them. With `open`, a function node
|
|
57
|
+
* can be drawn open (`toggle`), and each function drawn open (`LayerModel.fns`) is a
|
|
58
|
+
* cluster named by its path, each part a link to its own layer.
|
|
59
|
+
*/
|
|
60
|
+
export function graphInput(m: LayerModel, x: GraphWordsContext, open = false): GraphInput {
|
|
61
|
+
const ctx = markContext(x);
|
|
62
|
+
const mark = (n: GraphNode, mk: LayerMark): GraphMark => {
|
|
63
|
+
const { name, parts } = markText(n.label, mk, ctx(mk));
|
|
64
|
+
return {
|
|
65
|
+
id: markSel(n.id, mk),
|
|
66
|
+
state: mk.state,
|
|
67
|
+
label: facts(name, ...parts),
|
|
68
|
+
tip: [name, parts[0] ?? ''].filter(Boolean).join('\n'),
|
|
69
|
+
...(mk.passes ? { badge: String(mk.passes) } : {}),
|
|
70
|
+
name: mk.unit || mk.key,
|
|
71
|
+
drill: !!mk.flow,
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const nodes = m.nodes.map((n): GraphNodeInput => {
|
|
75
|
+
const c = n.counts;
|
|
76
|
+
return {
|
|
77
|
+
id: n.id,
|
|
78
|
+
label: n.label,
|
|
79
|
+
tip: nodeTip(n),
|
|
80
|
+
summary: nodeLabel(n, m, x.live),
|
|
81
|
+
cluster: n.box,
|
|
82
|
+
icons: iconsOf(n),
|
|
83
|
+
accent: n.executor === 'agent',
|
|
84
|
+
drill: n.type === 'flow',
|
|
85
|
+
marks: n.units.map((mk) => mk && mark(n, mk)),
|
|
86
|
+
loose: n.single.map((mk) => mark(n, mk)),
|
|
87
|
+
counts: c,
|
|
88
|
+
progress: { done: c.done, total: c.total, label: doneOf(c) },
|
|
89
|
+
notes: exceptions(n, x.live).map(([cls, text]) => ({ text, tone: NOTE_TONE[cls] })),
|
|
90
|
+
// Finished (done and skipped) only sets the frame's look; the count is of the tasks done.
|
|
91
|
+
look: c.failed || n.errors ? 'failed' : c.running ? 'running' : c.done + c.skipped === c.total ? 'done' : undefined,
|
|
92
|
+
// A function can be drawn open, where the layer is drawn with its functions (not in a loop's passes).
|
|
93
|
+
...(n.type === 'flow' && open ? { toggle: 'closed' as const } : {}),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
// A function drawn open: a cluster named by its path, its count and what is not done under its name.
|
|
97
|
+
const fns = m.fns.map((f): GraphClusterInput => {
|
|
98
|
+
const first = (f.parts[0] as (typeof f.parts)[number]).node;
|
|
99
|
+
const label = f.parts.map((p) => p.node.label).join(' › ');
|
|
100
|
+
const c = first.counts;
|
|
101
|
+
const notes = exceptions(first, x.live).map(([, text]) => text);
|
|
102
|
+
return {
|
|
103
|
+
id: f.id,
|
|
104
|
+
parent: f.parent,
|
|
105
|
+
label,
|
|
106
|
+
tip: first.name,
|
|
107
|
+
note: `${c.done}/${c.total}`,
|
|
108
|
+
...(notes.length ? { detail: facts(...notes) } : {}),
|
|
109
|
+
summary: facts(label, nodeLabel(first, m, x.live)),
|
|
110
|
+
chipLabel: msg(str`Inside ${label}`),
|
|
111
|
+
chipTip: facts(msg('Function'), label),
|
|
112
|
+
drill: true,
|
|
113
|
+
cycle: false,
|
|
114
|
+
toggle: 'open',
|
|
115
|
+
path: f.parts.map((p) => ({ id: p.id, label: p.node.label, tip: p.node.name })),
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
const clusters = m.boxes.map((b): GraphClusterInput => {
|
|
119
|
+
const at = loopAt(b);
|
|
120
|
+
const spread = b.spread.length > 1 ? passSpread(b.spread) : '';
|
|
121
|
+
const passes = passCount(b.passes);
|
|
122
|
+
return {
|
|
123
|
+
id: b.id,
|
|
124
|
+
parent: b.parent,
|
|
125
|
+
label: loopLabel(),
|
|
126
|
+
tip: facts(loopLabel(), at),
|
|
127
|
+
note: passes,
|
|
128
|
+
...(spread ? { detail: spread, detailTip: msg('Units by number of passes') } : {}),
|
|
129
|
+
summary: facts(at, passes, spread),
|
|
130
|
+
chipLabel: facts(msg(str`Passes of the loop at ${where(b.loop, b.file)}`), passes),
|
|
131
|
+
chipTip: facts(at, passes),
|
|
132
|
+
drill: true,
|
|
133
|
+
cycle: true,
|
|
134
|
+
};
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
series: m.units,
|
|
138
|
+
nodes,
|
|
139
|
+
clusters: [...clusters, ...fns],
|
|
140
|
+
edges: m.edges.map((e) => ({ from: e.from, to: e.to, style: edgeStyle(e.type), weight: e.tasks, ranks: e.samePass })),
|
|
141
|
+
stubs: m.stubs.map((s) => ({ id: s.id, label: s.label, to: s.to, style: edgeStyle(s.type), weight: s.tasks })),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** The layer `path` of the plan, as the generic graph takes it, and its projection (for the card's facts and a loop's passes). */
|
|
146
|
+
export function graphFromPlan(plan: Plan, path: readonly string[], x: Omit<GraphWordsContext, 'plan'>): { input: GraphInput; proj: Projection } {
|
|
147
|
+
const proj = project(plan, path);
|
|
148
|
+
return { input: graphInput(proj.model, { ...x, plan }), proj };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** How a loop's units can be sorted, and the words for each. */
|
|
152
|
+
export const matrixSorts = (): { id: MatrixSort; label: string }[] => [
|
|
153
|
+
{ id: 'order', label: msg('Scheduled order') },
|
|
154
|
+
{ id: 'passes', label: msg('Number of passes') },
|
|
155
|
+
{ id: 'state', label: msg('Status', { id: 'status', desc: 'The status of a task: done, failed, not started' }) },
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* A loop's passes as the generic mark matrix takes them: a row per unit (sorted by
|
|
160
|
+
* `sort`), a column per node and pass under a group per pass (a nested loop's passes
|
|
161
|
+
* as groups inside each pass of the outer one).
|
|
162
|
+
*/
|
|
163
|
+
export function matrixInput(mx: PassMatrix, sort: MatrixSort, x: GraphWordsContext): MarkMatrixInput {
|
|
164
|
+
const ctx = markContext(x);
|
|
165
|
+
const box = mx.box;
|
|
166
|
+
const caption = loopAt(box);
|
|
167
|
+
const units = mx.rows.filter((r) => r.unit).length;
|
|
168
|
+
const cell = (ci: number, mk: LayerMark): MatrixMark => {
|
|
169
|
+
const col = mx.columns[ci];
|
|
170
|
+
const label = col?.node.label ?? '';
|
|
171
|
+
const passes = col?.passes ?? [];
|
|
172
|
+
const { name, parts } = markText(label, mk, ctx(mk), listText(passes.map(passLabel)));
|
|
173
|
+
return { id: markSel(col?.node.id ?? '', mk, passes), state: mk.state, label: facts(name, ...parts), tip: [name, parts[0] ?? ''].filter(Boolean).join('\n'), drill: !!mk.flow };
|
|
174
|
+
};
|
|
175
|
+
const head = mx.head.map((row) =>
|
|
176
|
+
row.map((hd): MatrixHeadCell => {
|
|
177
|
+
if (hd.type === 'pass')
|
|
178
|
+
return {
|
|
179
|
+
id: `${hd.box.id}|${hd.pass}`,
|
|
180
|
+
label: passLabel(hd.pass),
|
|
181
|
+
tip: hd.box.id === box.id ? loopAt(hd.box) : msg(str`Nested loop at ${where(hd.box.loop, hd.box.file)}`),
|
|
182
|
+
span: hd.span,
|
|
183
|
+
rows: hd.rows,
|
|
184
|
+
type: 'group',
|
|
185
|
+
};
|
|
186
|
+
if (hd.type === 'loop')
|
|
187
|
+
return { id: hd.box.id, label: loopLabel(), tip: msg(str`Nested loop at ${where(hd.box.loop, hd.box.file)}`), code: true, span: hd.span, rows: hd.rows, type: 'group' };
|
|
188
|
+
const n = hd.node;
|
|
189
|
+
const flow = n.type === 'flow';
|
|
190
|
+
return {
|
|
191
|
+
id: `${n.id}|${hd.passes.join('.')}`,
|
|
192
|
+
label: n.label,
|
|
193
|
+
tip: flow ? msg(str`Function ${n.name}`) : facts(n.label, executorWord(n)),
|
|
194
|
+
summary: flow ? n.label : facts(n.label, executorWord(n)),
|
|
195
|
+
icons: n.executor && n.executor !== 'mixed' ? [n.executor] : [],
|
|
196
|
+
span: hd.span,
|
|
197
|
+
rows: hd.rows,
|
|
198
|
+
type: 'column',
|
|
199
|
+
};
|
|
200
|
+
}),
|
|
201
|
+
);
|
|
202
|
+
return {
|
|
203
|
+
caption,
|
|
204
|
+
...(box.file ? { captionTip: `${box.file}:${box.loop}` } : {}),
|
|
205
|
+
label: facts(caption, passCount(box.passes)),
|
|
206
|
+
facts: [passCount(box.passes), box.spread.length > 1 ? passSpread(box.spread) : '', units === 1 ? msg('1 unit') : msg(str`${units} units`)].filter(Boolean),
|
|
207
|
+
head,
|
|
208
|
+
columns: mx.columns.map((c) => ({ id: `${c.node.id}|${c.passes.join('.')}`, groups: c.passes.map((_, k) => c.passes.slice(0, k + 1).join('.')) })),
|
|
209
|
+
rows: sortRows(mx.rows, sort).map((r) => ({
|
|
210
|
+
id: r.unit,
|
|
211
|
+
label: r.unit || msg('No unit'),
|
|
212
|
+
tip: r.unit || msg('Tasks that run once per run, not once per unit'),
|
|
213
|
+
muted: !r.unit,
|
|
214
|
+
value: r.passes,
|
|
215
|
+
strong: r.passes > 1,
|
|
216
|
+
cells: r.cells.map((mk, ci) => mk && cell(ci, mk)),
|
|
217
|
+
})),
|
|
218
|
+
value: { label: msg('Passes'), tip: msg('Passes of this loop') },
|
|
219
|
+
sorts: matrixSorts(),
|
|
220
|
+
sort,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** The loop box `box` of layer `path` with its passes unrolled (`passMatrix`), as the generic mark matrix takes it; null when the layer has no such box. */
|
|
225
|
+
export function matrixFromPlan(
|
|
226
|
+
plan: Plan,
|
|
227
|
+
path: readonly string[],
|
|
228
|
+
box: string,
|
|
229
|
+
prev: GraphOrder | undefined,
|
|
230
|
+
sort: MatrixSort,
|
|
231
|
+
x: Omit<GraphWordsContext, 'plan'>,
|
|
232
|
+
proj?: Projection,
|
|
233
|
+
): { input: MarkMatrixInput; matrix: PassMatrix } | null {
|
|
234
|
+
const matrix = passMatrix(plan, path, box, prev, proj);
|
|
235
|
+
return matrix && { input: matrixInput(matrix, sort, { ...x, plan }), matrix };
|
|
236
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// The layers of the run's flow: the graph of one, the one the graph opens on, and
|
|
2
|
+
// the layer a view route's segments name.
|
|
3
|
+
import type { Plan } from '@contraagent/api';
|
|
4
|
+
import { arrange, type GraphOrder } from '@contraagent/elements/graph';
|
|
5
|
+
import { indexOf, instanceOf, placeOf, shortName, startsWith, type FlowTask } from './flow-index.js';
|
|
6
|
+
import { arranged, project, shapeOf } from './project.js';
|
|
7
|
+
import { LOOP_SEGMENT, type LayerGraph } from './types.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The layer `path` of the plan's flow. Pass the `order` of the last graph of this layer as
|
|
11
|
+
* `prev` to keep its nodes in place; `down` lays out the edge paths for a drawing top to bottom
|
|
12
|
+
* (a box's label is then on the side its edges come in).
|
|
13
|
+
*/
|
|
14
|
+
export function layerGraph(plan: Plan, path: readonly string[] = [], prev?: GraphOrder, down = false): LayerGraph {
|
|
15
|
+
const { model } = project(plan, path);
|
|
16
|
+
return arranged(model, arrange(shapeOf(model), prev, down));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The layer the graph opens on: from the top, down while a layer has a single
|
|
21
|
+
* node and it is a function's. It stops at a single function node whose flow call
|
|
22
|
+
* raised or was closed, so a run that failed inside a flow opens on the node that
|
|
23
|
+
* shows it, not inside it. A failed or not started task does not stop it: the layer
|
|
24
|
+
* below shows that task's own mark. A static flow lands on its kinds.
|
|
25
|
+
*/
|
|
26
|
+
export function autoLayer(plan: Plan): string[] {
|
|
27
|
+
const ix = indexOf(plan);
|
|
28
|
+
const path: string[] = [];
|
|
29
|
+
// The failure sites: flow calls that raised or were closed with no raised descendant.
|
|
30
|
+
// The graph stops on the node that shows one, not inside it. A plan with no flow calls
|
|
31
|
+
// cannot tell its failure sites, so it descends as if there were none.
|
|
32
|
+
const raised = new Set<string>();
|
|
33
|
+
if (ix.calls) for (const c of ix.calls.values()) if (c.state === 'raised' || c.state === 'closed') raised.add(c.id);
|
|
34
|
+
const isSite = (id: string): boolean => raised.has(id) && ![...raised].some((r) => r !== id && r.startsWith(`${id}.`));
|
|
35
|
+
for (;;) {
|
|
36
|
+
let only: { id: string; name: string } | null = null;
|
|
37
|
+
let one = true;
|
|
38
|
+
const mine: FlowTask[] = [];
|
|
39
|
+
for (const t of ix.tasks) {
|
|
40
|
+
if (!startsWith(t.path, path)) continue;
|
|
41
|
+
const p = placeOf(t, path.length);
|
|
42
|
+
if (p.type === 'kind' || (only && only.id !== p.id)) {
|
|
43
|
+
one = false;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
only = p;
|
|
47
|
+
mine.push(t);
|
|
48
|
+
}
|
|
49
|
+
// Stop before entering a single function node that is itself a failure site.
|
|
50
|
+
const atSite = mine.some((t) => isSite(instanceOf(t, path.length, ix.calls).id));
|
|
51
|
+
if (!one || !only || atSite) return path;
|
|
52
|
+
path.push(only.name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** A layer's segments: its path, and the loop box entered at its end (null when none). */
|
|
57
|
+
export function splitLayer(segments: readonly string[]): { path: string[]; loop: string | null } {
|
|
58
|
+
const last = segments[segments.length - 1];
|
|
59
|
+
return last?.startsWith(LOOP_SEGMENT) ? { path: segments.slice(0, -1), loop: last } : { path: [...segments], loop: null };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The layer `segments` names, as the plan has it: the segments themselves when the
|
|
64
|
+
* plan has that layer (a prefix of a task's flow path, and the loop box after it);
|
|
65
|
+
* else, when the last function is named by its `module.qualname` (or, failing that,
|
|
66
|
+
* its name) and the plan reaches it by one flow path only, that flow path, with the
|
|
67
|
+
* loop box when the layer there has it. Null when the plan has no such layer.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveLayer(plan: Plan, segments: readonly string[]): string[] | null {
|
|
70
|
+
const { path, loop } = splitLayer(segments);
|
|
71
|
+
const ix = indexOf(plan);
|
|
72
|
+
const hasLoop = (p: readonly string[]) => !loop || project(plan, p).model.boxes.some((b) => b.id === loop);
|
|
73
|
+
if (ix.tasks.some((t) => startsWith(t.path, path))) return hasLoop(path) ? [...segments] : null;
|
|
74
|
+
const name = path[path.length - 1];
|
|
75
|
+
if (name === undefined) return null;
|
|
76
|
+
const found = (match: (fn: string) => boolean): string[][] => {
|
|
77
|
+
const by = new Map<string, string[]>();
|
|
78
|
+
for (const t of ix.tasks) t.path.forEach((fn, i) => match(fn) && by.set(t.path.slice(0, i + 1).join('/'), t.path.slice(0, i + 1)));
|
|
79
|
+
return [...by.values()];
|
|
80
|
+
};
|
|
81
|
+
const exact = found((fn) => fn === name);
|
|
82
|
+
const named = exact.length ? exact : found((fn) => shortName(fn) === name);
|
|
83
|
+
const only = named.length === 1 ? (named[0] as string[]) : null;
|
|
84
|
+
return only && hasLoop(only) ? (loop ? [...only, loop] : only) : null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** One level up from `segments`: null at the top (the layer the graph opens on, `auto`), [] for that layer. */
|
|
88
|
+
export function parentLayer(segments: readonly string[], auto: readonly string[]): string[] | null {
|
|
89
|
+
if (segments.length <= auto.length) return null;
|
|
90
|
+
const up = segments.slice(0, -1);
|
|
91
|
+
return up.length <= auto.length ? [] : up;
|
|
92
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// A loop's passes: a loop box unrolled into units by (node, pass).
|
|
2
|
+
import type { Plan, TaskState } from '@contraagent/api';
|
|
3
|
+
import { arrange, type GraphOrder } from '@contraagent/elements/graph';
|
|
4
|
+
import { cmpPasses, passesAt, push, type FlowTask } from './flow-index.js';
|
|
5
|
+
import { arranged, flowMarks, project, shapeOf, taskMark, type Draft, type Projection } from './project.js';
|
|
6
|
+
import { SEVERITY, worstOf } from './states.js';
|
|
7
|
+
import { LOOP_SEGMENT, type LayerMark, type GraphNode, type LoopBox } from './types.js';
|
|
8
|
+
|
|
9
|
+
/** A column of a loop's passes: one node, in one pass of each loop from the unrolled box down to the node's own box. */
|
|
10
|
+
export interface MatrixColumn {
|
|
11
|
+
node: GraphNode;
|
|
12
|
+
/** The passes, the unrolled box's loop first. */
|
|
13
|
+
passes: number[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** A header cell over the columns: a pass of a loop, a nested loop, or a node. */
|
|
17
|
+
export type MatrixHead =
|
|
18
|
+
| { type: 'pass'; box: LoopBox; pass: number; span: number; rows: number }
|
|
19
|
+
| { type: 'loop'; box: LoopBox; span: number; rows: number }
|
|
20
|
+
| { type: 'node'; node: GraphNode; passes: number[]; span: number; rows: number };
|
|
21
|
+
|
|
22
|
+
export interface MatrixRow {
|
|
23
|
+
/** The unit, or '' for the tasks without one. */
|
|
24
|
+
unit: string;
|
|
25
|
+
/** How many passes of the unrolled loop it ran (in every run of the loop). */
|
|
26
|
+
passes: number;
|
|
27
|
+
/** The most severe state of its marks. */
|
|
28
|
+
state: TaskState;
|
|
29
|
+
/** One per column: its mark, or null where it has none. */
|
|
30
|
+
cells: (LayerMark | null)[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A loop box with its passes unrolled: a row per unit, a column per (node, pass), nested loops as nested column groups. */
|
|
34
|
+
export interface PassMatrix {
|
|
35
|
+
box: LoopBox;
|
|
36
|
+
columns: MatrixColumn[];
|
|
37
|
+
/** The header rows, outermost first; a node's cell spans down to the last. */
|
|
38
|
+
head: MatrixHead[][];
|
|
39
|
+
/** The units that have a task in the box, in the layer's order; the tasks without a unit last. */
|
|
40
|
+
rows: MatrixRow[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type ColTree = { type: 'pass'; box: LoopBox; pass: number; kids: ColTree[] } | { type: 'loop'; box: LoopBox; kids: ColTree[] } | { type: 'node'; node: GraphNode; passes: number[] };
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The loop box `box` of layer `path` with its passes unrolled; null when the layer has
|
|
47
|
+
* no such box. Each task is in the column of its node and of its passes of the box's
|
|
48
|
+
* loop and of every loop nested in it, so an inner loop's passes are counted within
|
|
49
|
+
* each pass of the outer one. A column no task reached is left out. The columns
|
|
50
|
+
* follow the order of the layer drawn left to right with `prev` (its graph's order);
|
|
51
|
+
* `proj` is the layer's projection when the caller has it.
|
|
52
|
+
*/
|
|
53
|
+
export function passMatrix(plan: Plan, path: readonly string[], box: string, prev?: GraphOrder, proj: Projection = project(plan, path)): PassMatrix | null {
|
|
54
|
+
const { drafts, ix } = proj;
|
|
55
|
+
const graph = arranged(proj.model, arrange(shapeOf(proj.model), prev, false));
|
|
56
|
+
const b = graph.boxes.find((x) => x.id === box);
|
|
57
|
+
if (!b) return null;
|
|
58
|
+
const d = path.length;
|
|
59
|
+
const i0 = b.id.slice(LOOP_SEGMENT.length).split('.').length - 1;
|
|
60
|
+
const byBox = new Map(graph.boxes.map((x) => [x.id, x]));
|
|
61
|
+
const byNode = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
62
|
+
const rel = (t: FlowTask) => passesAt(t, d).slice(i0);
|
|
63
|
+
const leaves = (x: LoopBox): string[] => x.layers.flat().flatMap((id) => (byBox.has(id) ? leaves(byBox.get(id) as LoopBox) : [id]));
|
|
64
|
+
const tasksOf = (x: LoopBox): FlowTask[] => leaves(x).flatMap((id) => drafts.get(id)?.tasks ?? []);
|
|
65
|
+
const same = (a: readonly number[], p: readonly number[]) => a.length === p.length && cmpPasses(a, p) === 0;
|
|
66
|
+
const build = (x: LoopBox, prefix: number[]): ColTree[] => {
|
|
67
|
+
const k = prefix.length;
|
|
68
|
+
const passes = [...new Set(tasksOf(x).map(rel).filter((v) => v.length > k && cmpPasses(v.slice(0, k), prefix) === 0).map((v) => v[k] as number))].sort((a, c) => a - c);
|
|
69
|
+
return passes.flatMap((p): ColTree[] => {
|
|
70
|
+
const at = [...prefix, p];
|
|
71
|
+
const kids = x.layers.flat().flatMap((id): ColTree[] => {
|
|
72
|
+
const inner = byBox.get(id);
|
|
73
|
+
if (inner) {
|
|
74
|
+
const sub = build(inner, at);
|
|
75
|
+
return sub.length ? [{ type: 'loop', box: inner, kids: sub }] : [];
|
|
76
|
+
}
|
|
77
|
+
const node = byNode.get(id);
|
|
78
|
+
return node && drafts.get(id)?.tasks.some((t) => same(rel(t), at)) ? [{ type: 'node', node, passes: at }] : [];
|
|
79
|
+
});
|
|
80
|
+
return kids.length ? [{ type: 'pass', box: x, pass: p, kids }] : [];
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
const tree = build(b, []);
|
|
84
|
+
const columns: MatrixColumn[] = [];
|
|
85
|
+
const width = (t: ColTree): number => (t.type === 'node' ? 1 : t.kids.reduce((a, k) => a + width(k), 0));
|
|
86
|
+
const depthOf = (t: ColTree): number => (t.type === 'node' ? 1 : 1 + Math.max(0, ...t.kids.map(depthOf)));
|
|
87
|
+
const rowsN = Math.max(1, ...tree.map(depthOf));
|
|
88
|
+
const head: MatrixHead[][] = Array.from({ length: rowsN }, () => []);
|
|
89
|
+
const walk = (t: ColTree, level: number): void => {
|
|
90
|
+
const row = head[level] as MatrixHead[];
|
|
91
|
+
if (t.type === 'node') {
|
|
92
|
+
row.push({ type: 'node', node: t.node, passes: t.passes, span: 1, rows: rowsN - level });
|
|
93
|
+
columns.push({ node: t.node, passes: t.passes });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
row.push(t.type === 'pass' ? { type: 'pass', box: t.box, pass: t.pass, span: width(t), rows: 1 } : { type: 'loop', box: t.box, span: width(t), rows: 1 });
|
|
97
|
+
for (const k of t.kids) walk(k, level + 1);
|
|
98
|
+
};
|
|
99
|
+
for (const t of tree) walk(t, 0);
|
|
100
|
+
|
|
101
|
+
const mine = tasksOf(b);
|
|
102
|
+
const unitsIn = new Set(mine.map((t) => t.n.unit || ''));
|
|
103
|
+
const rowUnits = [...graph.units.filter((u) => unitsIn.has(u)), ...(unitsIn.has('') ? [''] : [])];
|
|
104
|
+
const cellTasks = new Map<string, FlowTask[]>(); // `${column}\0${unit}`
|
|
105
|
+
columns.forEach((c, ci) => {
|
|
106
|
+
for (const t of drafts.get(c.node.id)?.tasks ?? []) if (same(rel(t), c.passes)) push(cellTasks, `${ci}\u0000${t.n.unit || ''}`, t);
|
|
107
|
+
});
|
|
108
|
+
const markOf = (c: MatrixColumn, ts: readonly FlowTask[], unit: string): LayerMark | null => {
|
|
109
|
+
const x = drafts.get(c.node.id) as Draft;
|
|
110
|
+
if (x.type === 'kind') return taskMark(ts, unit);
|
|
111
|
+
const m = flowMarks(ts, d, x.name, ix.calls);
|
|
112
|
+
return unit ? (m.byUnit.get(unit) ?? m.single[0] ?? null) : (m.single[0] ?? null);
|
|
113
|
+
};
|
|
114
|
+
const rows = rowUnits.map((unit): MatrixRow => {
|
|
115
|
+
const cells = columns.map((c, ci) => {
|
|
116
|
+
const ts = cellTasks.get(`${ci}\u0000${unit}`);
|
|
117
|
+
return ts?.length ? markOf(c, ts, unit) : null;
|
|
118
|
+
});
|
|
119
|
+
const passes = new Set(mine.filter((t) => (t.n.unit || '') === unit).map((t) => passesAt(t, d).slice(0, i0 + 1).join('.'))).size;
|
|
120
|
+
return { unit, passes, state: worstOf(cells.filter((m): m is LayerMark => m !== null).map((m) => m.state)), cells };
|
|
121
|
+
});
|
|
122
|
+
return { box: b, columns, head, rows };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** How a loop's units are sorted: as scheduled, most passes first, or the most severe state first. */
|
|
126
|
+
export type MatrixSort = 'order' | 'passes' | 'state';
|
|
127
|
+
|
|
128
|
+
/** `rows` sorted by `by`; a tie keeps the scheduled order. */
|
|
129
|
+
export function sortRows(rows: readonly MatrixRow[], by: MatrixSort): MatrixRow[] {
|
|
130
|
+
const ix = new Map(rows.map((r, i) => [r, i]));
|
|
131
|
+
const key = (r: MatrixRow) => (by === 'passes' ? -r.passes : by === 'state' ? -SEVERITY[r.state] : 0);
|
|
132
|
+
return [...rows].sort((a, b) => key(a) - key(b) || (ix.get(a) ?? 0) - (ix.get(b) ?? 0));
|
|
133
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Synthetic plans for the graph's tests, as a run writes them: a task's flow path
|
|
2
|
+
// (outermost first) with the loops around each call site, what its flow call had
|
|
3
|
+
// received when it was created, and its flow call. Test code only: the build leaves
|
|
4
|
+
// `*.fixture.ts` out.
|
|
5
|
+
import type { FlowCallNode, Frame, Plan, PlanNode } from '@contraagent/api';
|
|
6
|
+
|
|
7
|
+
export const node = (key: string, unit: string, group: string, state: PlanNode['state'], extra: Partial<PlanNode> = {}): PlanNode => ({
|
|
8
|
+
key, kind: group, unit, group, state, level: 0, ...extra,
|
|
9
|
+
});
|
|
10
|
+
export const group = (id: string, counts: Partial<Plan['groups'][number]> = {}): Plan['groups'][number] => ({
|
|
11
|
+
id, label: id, total: 0, done: 0, partial: 0, failed: 0, running: 0, pending: 0, skipped: 0, blocked: 0, ...counts,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/** A frame of a flow path, with the loops around its call site (each at pass 1). */
|
|
15
|
+
export const F = (fn: string, ...loops: number[]): Frame => ({ function: fn, file: 'flow.py', line: 1, loops: loops.map((line) => ({ line, pass: 1 })) });
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A task created by a flow. `pass` is the pass of the innermost loop around the
|
|
19
|
+
* task's own call site; `passes`, one pass per loop around it, outermost first.
|
|
20
|
+
*/
|
|
21
|
+
export const ft = (
|
|
22
|
+
key: string,
|
|
23
|
+
unit: string,
|
|
24
|
+
kind: string,
|
|
25
|
+
state: PlanNode['state'],
|
|
26
|
+
flow: Frame[],
|
|
27
|
+
{ pass = 1, passes, ...extra }: Partial<PlanNode> & { pass?: number; passes?: number[] } = {},
|
|
28
|
+
): PlanNode => {
|
|
29
|
+
const last = flow[flow.length - 1];
|
|
30
|
+
const loops = last?.loops ?? [];
|
|
31
|
+
const at = (i: number) => passes?.[i] ?? (i === loops.length - 1 ? pass : 1);
|
|
32
|
+
const own = last && loops.length ? [...flow.slice(0, -1), { ...last, loops: loops.map((l, i) => ({ ...l, pass: at(i) })) }] : flow;
|
|
33
|
+
return node(key, unit, kind, state, { flow: own, flow_call: '0', created_from: [], ...extra });
|
|
34
|
+
};
|
|
35
|
+
export const planOf = (nodes: PlanNode[], flow_calls?: FlowCallNode[]): Plan => {
|
|
36
|
+
const groups = [...new Set(nodes.map((n) => n.group))].map((g) => group(g));
|
|
37
|
+
return flow_calls ? { nodes, groups, flow_calls } : { nodes, groups };
|
|
38
|
+
};
|
|
39
|
+
export const call = (id: string, fn: string, state: FlowCallNode['state'] = 'returned'): FlowCallNode => ({
|
|
40
|
+
id, parent: id.includes('.') ? id.slice(0, id.lastIndexOf('.')) : null, function: fn, flow: [], state,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const RUN = 'flows.run_all';
|
|
44
|
+
export const LOOP = 'flows.review_loop';
|
|
45
|
+
export const AT = 7; // the line of review_loop's `while`
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* run_all: prepare each unit (Python), then review_loop(u) for every unit as one batch,
|
|
49
|
+
* then report on what they returned. review_loop: summarize, check, and while the review
|
|
50
|
+
* is not ok: fix, score (Python), check. `passes[u]` is how many times u went round.
|
|
51
|
+
*/
|
|
52
|
+
export function reviewRun(passes: Record<string, number>, opts: { calls?: boolean; failed?: string } = {}): Plan {
|
|
53
|
+
const nodes: PlanNode[] = [];
|
|
54
|
+
const top = [F(RUN)];
|
|
55
|
+
const inLoop = [F(RUN), F(LOOP)];
|
|
56
|
+
const looped = [F(RUN), F(LOOP, AT)];
|
|
57
|
+
const finals: string[] = [];
|
|
58
|
+
const lastChecks: string[] = [];
|
|
59
|
+
Object.entries(passes).forEach(([u, n], i) => {
|
|
60
|
+
const c = `0.${i + 1}`;
|
|
61
|
+
const bad = opts.failed === u;
|
|
62
|
+
nodes.push(ft(`prepare-${u}`, u, 'prepare', 'done', top, { executor: 'python' }));
|
|
63
|
+
nodes.push(ft(`summarize-${u}`, u, 'summarize', 'done', inLoop, { flow_call: c, after: [`prepare-${u}`], created_from: [`prepare-${u}`] }));
|
|
64
|
+
let summary = `summarize-${u}`;
|
|
65
|
+
let check = `check-${u}`;
|
|
66
|
+
nodes.push(ft(check, u, 'check', 'done', inLoop, { flow_call: c, after: [summary], created_from: [summary] }));
|
|
67
|
+
for (let p = 1; p <= n; p++) {
|
|
68
|
+
const sfx = p === 1 ? '' : `~${p}`;
|
|
69
|
+
const fix = `fix-${u}${sfx}`;
|
|
70
|
+
const score = `score-${u}${sfx}`;
|
|
71
|
+
const last = p === n;
|
|
72
|
+
nodes.push(ft(fix, u, 'fix', bad && last ? 'failed' : 'done', looped, { flow_call: c, pass: p, after: [summary, check], created_from: [check] }));
|
|
73
|
+
if (bad && last) break;
|
|
74
|
+
nodes.push(ft(score, u, 'score', 'done', looped, { flow_call: c, pass: p, executor: 'python', after: [fix], created_from: [fix] }));
|
|
75
|
+
const next = `check-${u}~${p + 1}`;
|
|
76
|
+
nodes.push(ft(next, u, 'check', 'done', looped, { flow_call: c, pass: p, after: [fix], created_from: [score] }));
|
|
77
|
+
summary = fix;
|
|
78
|
+
check = next;
|
|
79
|
+
}
|
|
80
|
+
finals.push(summary);
|
|
81
|
+
lastChecks.push(check);
|
|
82
|
+
});
|
|
83
|
+
const failed = opts.failed !== undefined;
|
|
84
|
+
if (!failed) nodes.push(ft('report', '', 'report', 'done', top, { after: finals, created_from: lastChecks }));
|
|
85
|
+
const units = Object.keys(passes);
|
|
86
|
+
const calls = [call('0', RUN, failed ? 'raised' : 'returned'), ...units.map((u, i) => call(`0.${i + 1}`, LOOP, opts.failed === u ? 'raised' : 'returned'))];
|
|
87
|
+
return planOf(nodes, opts.calls ? calls : undefined);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const UNITS = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta'];
|
|
91
|
+
|
|
92
|
+
/** The demo as a static flow: prepare -> summarize -> { review, write_note }, review -> report (one task, no unit). */
|
|
93
|
+
export function staticDemo(stateOf: (key: string) => PlanNode['state'] = (k) => (k.endsWith('zeta') ? 'blocked' : 'done'), flow?: Frame[]): Plan {
|
|
94
|
+
const extra = (x: Partial<PlanNode>): Partial<PlanNode> => (flow ? { ...x, flow, flow_call: '0' } : x);
|
|
95
|
+
const nodes: PlanNode[] = [];
|
|
96
|
+
for (const u of UNITS) {
|
|
97
|
+
nodes.push(node(`prepare-${u}`, u, 'prepare', u === 'zeta' ? 'failed' : stateOf(`prepare-${u}`), extra({})));
|
|
98
|
+
nodes.push(node(`summarize-${u}`, u, 'summarize', stateOf(`summarize-${u}`), extra({ after: [`prepare-${u}`] })));
|
|
99
|
+
nodes.push(node(`review-${u}`, u, 'review', stateOf(`review-${u}`), extra({ after: [`summarize-${u}`] })));
|
|
100
|
+
nodes.push(node(`write_note-${u}`, u, 'write_note', stateOf(`write_note-${u}`), extra({ after: [`summarize-${u}`] })));
|
|
101
|
+
}
|
|
102
|
+
nodes.push(node('report', '', 'report', 'blocked', extra({ after: UNITS.map((u) => `review-${u}`) })));
|
|
103
|
+
return { groups: ['prepare', 'summarize', 'review', 'write_note', 'report'].map((g) => group(g)), nodes };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** scan(u): for each column (the outer `for`, line 30), propose it, then while not ok verify and refine it (the inner `while`, line 33). */
|
|
107
|
+
export const SCAN = 'flows.scan';
|
|
108
|
+
export function nestedLoops(): Plan {
|
|
109
|
+
const outer = 30;
|
|
110
|
+
const inner = 33;
|
|
111
|
+
const at = (loops: number[]) => [F(RUN), F(SCAN, ...loops)];
|
|
112
|
+
return planOf(
|
|
113
|
+
[
|
|
114
|
+
ft('propose-a', 'a', 'propose', 'done', at([outer]), { flow_call: '0.1', passes: [1] }),
|
|
115
|
+
ft('verify-a', 'a', 'verify', 'done', at([outer, inner]), { flow_call: '0.1', passes: [1, 1], executor: 'python', after: ['propose-a'] }),
|
|
116
|
+
ft('refine-a', 'a', 'refine', 'done', at([outer, inner]), { flow_call: '0.1', passes: [1, 1], after: ['verify-a'] }),
|
|
117
|
+
ft('verify-a~2', 'a', 'verify', 'done', at([outer, inner]), { flow_call: '0.1', passes: [1, 2], executor: 'python', after: ['refine-a'] }),
|
|
118
|
+
ft('propose-a~2', 'a', 'propose', 'done', at([outer]), { flow_call: '0.1', passes: [2] }),
|
|
119
|
+
ft('verify-a~3', 'a', 'verify', 'failed', at([outer, inner]), { flow_call: '0.1', passes: [2, 1], executor: 'python', after: ['propose-a~2'] }),
|
|
120
|
+
ft('propose-b', 'b', 'propose', 'done', at([outer]), { flow_call: '0.2', passes: [1] }),
|
|
121
|
+
ft('verify-b', 'b', 'verify', 'done', at([outer, inner]), { flow_call: '0.2', passes: [1, 1], executor: 'python', after: ['propose-b'] }),
|
|
122
|
+
],
|
|
123
|
+
[call('0', RUN), call('0.1', SCAN), call('0.2', SCAN)],
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Plans of every shape the graph draws, by name: the input of the graph's order snapshot. */
|
|
128
|
+
export function shapes(): Record<string, Plan> {
|
|
129
|
+
const L = [F(RUN), F(LOOP, AT)];
|
|
130
|
+
const inRL = [F(RUN), F(LOOP)];
|
|
131
|
+
const REFINE = 'flows.refine';
|
|
132
|
+
const POLISH = 'flows.polish';
|
|
133
|
+
const deep = [
|
|
134
|
+
ft('draft-a', 'a', 'draft', 'done', [F(RUN), F(LOOP), F(REFINE)], { flow_call: '0.1' }),
|
|
135
|
+
ft('tune-a', 'a', 'tune', 'running', [F(RUN), F(LOOP), F(REFINE), F(POLISH)], { flow_call: '0.1.1', after: ['draft-a'] }),
|
|
136
|
+
ft('report', '', 'report', 'pending', [F(RUN)], { after: ['tune-a'] }),
|
|
137
|
+
];
|
|
138
|
+
const at = (loops: number[]) => [F(RUN), F(SCAN, ...loops)];
|
|
139
|
+
return {
|
|
140
|
+
'static demo': staticDemo(),
|
|
141
|
+
'static demo, running': staticDemo((k) => (k.startsWith('review') ? 'running' : 'pending')),
|
|
142
|
+
'static demo under one function': staticDemo(undefined, [F('flows.pipeline')]),
|
|
143
|
+
'cycle and waits inside a node': planOf([
|
|
144
|
+
node('a1', 'u', 'a', 'done'),
|
|
145
|
+
node('a2', 'v', 'a', 'done', { after: ['a1', 'not-yet'] }),
|
|
146
|
+
node('b1', 'u', 'b', 'done', { after: ['c1'] }),
|
|
147
|
+
node('c1', 'u', 'c', 'done', { after: ['b1'] }),
|
|
148
|
+
]),
|
|
149
|
+
'long edge': planOf([node('a-u', 'u', 'a', 'done'), node('b-u', 'u', 'b', 'done', { after: ['a-u'] }), node('c-u', 'u', 'c', 'done', { after: ['b-u'] }), node('d-u', 'u', 'd', 'done', { after: ['c-u', 'a-u'] })]),
|
|
150
|
+
crossing: planOf([
|
|
151
|
+
node('x1-u', 'u', 'x1', 'done'), node('x2-u', 'u', 'x2', 'done'),
|
|
152
|
+
node('y1-u', 'u', 'y1', 'done', { after: ['x2-u'] }), node('y2-u', 'u', 'y2', 'done', { after: ['x1-u'] }),
|
|
153
|
+
]),
|
|
154
|
+
'review loop, calls': reviewRun({ a: 0, b: 1 }, { calls: true }),
|
|
155
|
+
'review loop, 2 passes': reviewRun({ a: 1, b: 2 }),
|
|
156
|
+
'review loop, spread': reviewRun({ a: 1, b: 3, c: 0, d: 1, e: 2 }),
|
|
157
|
+
'review loop, failed': reviewRun({ a: 1, b: 3, c: 0, d: 2 }, { failed: 'd' }),
|
|
158
|
+
'review loop, calls, failed': reviewRun({ a: 0, b: 1, c: 2 }, { calls: true, failed: 'c' }),
|
|
159
|
+
branch: planOf([
|
|
160
|
+
ft('check-a', 'a', 'check', 'done', inRL, { flow_call: '0.1' }),
|
|
161
|
+
ft('check-b', 'b', 'check', 'done', inRL, { flow_call: '0.2' }),
|
|
162
|
+
ft('publish-a', 'a', 'publish', 'done', inRL, { flow_call: '0.1', created_from: ['check-a'] }),
|
|
163
|
+
ft('escalate-b', 'b', 'escalate', 'running', inRL, { flow_call: '0.2', created_from: ['check-b'] }),
|
|
164
|
+
]),
|
|
165
|
+
'fan-out': planOf(
|
|
166
|
+
[
|
|
167
|
+
ft('part-a/1', 'a/1', 'part', 'done', inRL, { flow_call: '0.1' }),
|
|
168
|
+
ft('part-a/2', 'a/2', 'part', 'failed', inRL, { flow_call: '0.1' }),
|
|
169
|
+
ft('part-b/1', 'b/1', 'part', 'done', inRL, { flow_call: '0.2' }),
|
|
170
|
+
ft('part-b/2', 'b/2', 'part', 'done', inRL, { flow_call: '0.2' }),
|
|
171
|
+
ft('merge', '', 'merge', 'blocked', [F(RUN)], { after: ['part-a/1', 'part-a/2', 'part-b/1', 'part-b/2'] }),
|
|
172
|
+
],
|
|
173
|
+
[call('0', RUN, 'running'), call('0.1', LOOP, 'raised'), call('0.2', LOOP)],
|
|
174
|
+
),
|
|
175
|
+
'deep, calls': planOf(deep, [call('0', RUN, 'running'), call('0.1', LOOP, 'running'), call('0.1.1', POLISH, 'running')]),
|
|
176
|
+
'deep, no calls': planOf(deep),
|
|
177
|
+
'nested loops': nestedLoops(),
|
|
178
|
+
'nested boxes': planOf([
|
|
179
|
+
ft('rank-a', 'a', 'rank', 'done', at([])),
|
|
180
|
+
ft('propose-a', 'a', 'propose', 'done', at([30]), { created_from: ['rank-a'] }),
|
|
181
|
+
ft('verify-a', 'a', 'verify', 'done', at([30, 33]), { after: ['propose-a'] }),
|
|
182
|
+
ft('refine-a', 'a', 'refine', 'done', at([30, 33]), { after: ['verify-a', 'propose-a'] }),
|
|
183
|
+
ft('report-a', 'a', 'report', 'done', at([]), { after: ['refine-a'] }),
|
|
184
|
+
]),
|
|
185
|
+
'into and out of a box': planOf([
|
|
186
|
+
ft('s-u', 'u', 's', 'done', inRL),
|
|
187
|
+
ft('a-u', 'u', 'a', 'done', L, { after: ['s-u'] }),
|
|
188
|
+
ft('b-u', 'u', 'b', 'done', L, { after: ['a-u'] }),
|
|
189
|
+
ft('c-u', 'u', 'c', 'done', L, { after: ['b-u', 's-u'] }),
|
|
190
|
+
ft('w-u', 'u', 'w', 'done', inRL, { after: ['b-u', 's-u', 'c-u'] }),
|
|
191
|
+
]),
|
|
192
|
+
'loop of one layer': planOf([ft('a-u', 'u', 'a', 'done', L), ft('a-u~2', 'u', 'a', 'done', L, { pass: 2 })]),
|
|
193
|
+
};
|
|
194
|
+
}
|