@llblab/pi-kit 0.38.3 → 0.39.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/CHANGELOG.md +10 -0
- package/README.md +2 -2
- package/node_modules/@llblab/pi-actors/AGENTS.md +108 -20
- package/node_modules/@llblab/pi-actors/BACKLOG.md +207 -4
- package/node_modules/@llblab/pi-actors/CHANGELOG.md +13 -0
- package/node_modules/@llblab/pi-actors/README.md +31 -1
- package/node_modules/@llblab/pi-actors/dist/index.js +1 -1
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +131 -62
- package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.js +3 -2
- package/node_modules/@llblab/pi-actors/dist/lib/command-templates.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +263 -129
- package/node_modules/@llblab/pi-actors/dist/lib/execution-files.d.ts +32 -0
- package/node_modules/@llblab/pi-actors/dist/lib/execution-files.js +128 -0
- package/node_modules/@llblab/pi-actors/dist/lib/execution-output.js +5 -4
- package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.d.ts +19 -1
- package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.js +62 -26
- package/node_modules/@llblab/pi-actors/dist/lib/execution.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/execution.js +6 -1
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.d.ts +9 -2
- package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +92 -14
- package/node_modules/@llblab/pi-actors/dist/lib/file-state.js +21 -2
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-command.js +2 -2
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.d.ts +25 -7
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.js +562 -262
- package/node_modules/@llblab/pi-actors/dist/lib/inspector.d.ts +20 -10
- package/node_modules/@llblab/pi-actors/dist/lib/inspector.js +80 -91
- package/node_modules/@llblab/pi-actors/dist/lib/limits.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/limits.js +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +15 -1
- package/node_modules/@llblab/pi-actors/dist/lib/observability.js +216 -99
- package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +5 -4
- package/node_modules/@llblab/pi-actors/dist/lib/pi.js +64 -10
- package/node_modules/@llblab/pi-actors/dist/lib/recipe-projection.d.ts +18 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipe-projection.js +220 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.js +30 -6
- package/node_modules/@llblab/pi-actors/dist/lib/registry.js +270 -36
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.d.ts +213 -5
- package/node_modules/@llblab/pi-actors/dist/lib/run-delivery.js +1909 -40
- package/node_modules/@llblab/pi-actors/dist/lib/run-supervision.d.ts +107 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-supervision.js +412 -0
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.d.ts +9 -2
- package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +283 -60
- package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.d.ts +26 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.js +68 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-exports.d.ts +451 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-exports.js +2315 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-index.d.ts +97 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-context-index.js +368 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control-delivery.js +46 -7
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control.d.ts +78 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-control.js +334 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-controls.js +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-descendant-launches.d.ts +80 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-descendant-launches.js +287 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-execution-evidence.d.ts +110 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-execution-evidence.js +282 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-index.d.ts +66 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-index.js +349 -13
- package/node_modules/@llblab/pi-actors/dist/lib/runs-native-launches.d.ts +73 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-native-launches.js +227 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-outcomes.d.ts +141 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-outcomes.js +292 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.d.ts +10 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.js +36 -4
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process-windows-mi.d.ts +46 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process-windows-mi.js +114 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process.d.ts +34 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-process.js +158 -26
- package/node_modules/@llblab/pi-actors/dist/lib/runs-results.d.ts +116 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-results.js +518 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.d.ts +15 -2
- package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.js +148 -9
- package/node_modules/@llblab/pi-actors/dist/lib/runs-session-exports.d.ts +95 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-session-exports.js +470 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-snapshot.d.ts +58 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-snapshot.js +92 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-start.d.ts +2 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-start.js +44 -3
- package/node_modules/@llblab/pi-actors/dist/lib/runs-status.d.ts +15 -1
- package/node_modules/@llblab/pi-actors/dist/lib/runs-status.js +337 -13
- package/node_modules/@llblab/pi-actors/dist/lib/runs-supervision.d.ts +105 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-supervision.js +501 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.js +14 -3
- package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +22 -3
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.d.ts +37 -0
- package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.js +59 -3
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/state-readers.js +14 -8
- package/node_modules/@llblab/pi-actors/dist/lib/temp.d.ts +2 -4
- package/node_modules/@llblab/pi-actors/dist/lib/temp.js +4 -56
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-access.js +13 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.d.ts +1 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.js +110 -43
- package/node_modules/@llblab/pi-actors/dist/lib/tools-local.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-local.js +18 -6
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.d.ts +4 -1
- package/node_modules/@llblab/pi-actors/dist/lib/tools-message.js +126 -31
- package/node_modules/@llblab/pi-actors/dist/lib/tools-response.d.ts +31 -3
- package/node_modules/@llblab/pi-actors/dist/lib/tools-response.js +311 -47
- package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.d.ts +3 -0
- package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.js +29 -7
- package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.d.ts +20 -0
- package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.js +192 -43
- package/node_modules/@llblab/pi-actors/dist/scripts/async-runner.mjs +272 -194
- package/node_modules/@llblab/pi-actors/dist/scripts/conformance.mjs +14 -2
- package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +46 -2
- package/node_modules/@llblab/pi-actors/dist/skills/actors/references/diagnostics.md +40 -0
- package/node_modules/@llblab/pi-actors/dist/skills/actors/references/runs.md +55 -1
- package/node_modules/@llblab/pi-actors/docs/README.md +9 -1
- package/node_modules/@llblab/pi-actors/docs/actor-inspector.md +84 -15
- package/node_modules/@llblab/pi-actors/docs/agent-experience.md +216 -0
- package/node_modules/@llblab/pi-actors/docs/async-runs.md +18 -2
- package/node_modules/@llblab/pi-actors/docs/composition-transport.md +103 -0
- package/node_modules/@llblab/pi-actors/docs/coordinator-delivery.md +204 -4
- package/node_modules/@llblab/pi-actors/docs/inspection.md +38 -2
- package/node_modules/@llblab/pi-actors/docs/output-projection-map.md +130 -0
- package/node_modules/@llblab/pi-actors/docs/releasing.md +19 -2
- package/node_modules/@llblab/pi-actors/docs/run-supervision.md +1622 -0
- package/node_modules/@llblab/pi-actors/docs/template-recipes.md +4 -0
- package/node_modules/@llblab/pi-actors/docs/windows-process-observation.md +248 -0
- package/node_modules/@llblab/pi-actors/index.ts +1 -1
- package/node_modules/@llblab/pi-actors/lib/async-runs.ts +164 -73
- package/node_modules/@llblab/pi-actors/lib/automatic-review-runtime.ts +4 -2
- package/node_modules/@llblab/pi-actors/lib/command-templates.ts +287 -138
- package/node_modules/@llblab/pi-actors/lib/execution-files.ts +118 -0
- package/node_modules/@llblab/pi-actors/lib/execution-output.ts +4 -4
- package/node_modules/@llblab/pi-actors/lib/execution-sessions.ts +57 -27
- package/node_modules/@llblab/pi-actors/lib/execution.ts +8 -0
- package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +102 -12
- package/node_modules/@llblab/pi-actors/lib/file-state.ts +16 -2
- package/node_modules/@llblab/pi-actors/lib/inspector-command.ts +2 -2
- package/node_modules/@llblab/pi-actors/lib/inspector-overlay.ts +524 -261
- package/node_modules/@llblab/pi-actors/lib/inspector.ts +101 -130
- package/node_modules/@llblab/pi-actors/lib/limits.ts +1 -0
- package/node_modules/@llblab/pi-actors/lib/observability.ts +235 -116
- package/node_modules/@llblab/pi-actors/lib/pi.ts +59 -11
- package/node_modules/@llblab/pi-actors/lib/recipe-projection.ts +232 -0
- package/node_modules/@llblab/pi-actors/lib/recipes-context.ts +27 -6
- package/node_modules/@llblab/pi-actors/lib/registry.ts +266 -36
- package/node_modules/@llblab/pi-actors/lib/run-delivery.ts +1737 -49
- package/node_modules/@llblab/pi-actors/lib/run-supervision.ts +411 -0
- package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +237 -73
- package/node_modules/@llblab/pi-actors/lib/runs-artifacts.ts +73 -1
- package/node_modules/@llblab/pi-actors/lib/runs-context-exports.ts +1871 -0
- package/node_modules/@llblab/pi-actors/lib/runs-context-index.ts +372 -0
- package/node_modules/@llblab/pi-actors/lib/runs-control-delivery.ts +36 -18
- package/node_modules/@llblab/pi-actors/lib/runs-control.ts +297 -1
- package/node_modules/@llblab/pi-actors/lib/runs-controls.ts +3 -1
- package/node_modules/@llblab/pi-actors/lib/runs-descendant-launches.ts +338 -0
- package/node_modules/@llblab/pi-actors/lib/runs-execution-evidence.ts +302 -0
- package/node_modules/@llblab/pi-actors/lib/runs-index.ts +345 -17
- package/node_modules/@llblab/pi-actors/lib/runs-native-launches.ts +270 -0
- package/node_modules/@llblab/pi-actors/lib/runs-outcomes.ts +377 -0
- package/node_modules/@llblab/pi-actors/lib/runs-ownership.ts +37 -4
- package/node_modules/@llblab/pi-actors/lib/runs-process-windows-mi.ts +113 -0
- package/node_modules/@llblab/pi-actors/lib/runs-process.ts +210 -34
- package/node_modules/@llblab/pi-actors/lib/runs-results.ts +601 -0
- package/node_modules/@llblab/pi-actors/lib/runs-retention.ts +134 -10
- package/node_modules/@llblab/pi-actors/lib/runs-session-exports.ts +406 -0
- package/node_modules/@llblab/pi-actors/lib/runs-snapshot.ts +143 -0
- package/node_modules/@llblab/pi-actors/lib/runs-start.ts +44 -2
- package/node_modules/@llblab/pi-actors/lib/runs-status.ts +252 -10
- package/node_modules/@llblab/pi-actors/lib/runs-supervision.ts +394 -0
- package/node_modules/@llblab/pi-actors/lib/runs-trace.ts +14 -3
- package/node_modules/@llblab/pi-actors/lib/runtime.ts +22 -3
- package/node_modules/@llblab/pi-actors/lib/session-evidence.ts +76 -4
- package/node_modules/@llblab/pi-actors/lib/state-readers.ts +16 -7
- package/node_modules/@llblab/pi-actors/lib/temp.ts +3 -56
- package/node_modules/@llblab/pi-actors/lib/tools-access.ts +13 -0
- package/node_modules/@llblab/pi-actors/lib/tools-inspect.ts +110 -51
- package/node_modules/@llblab/pi-actors/lib/tools-local.ts +37 -24
- package/node_modules/@llblab/pi-actors/lib/tools-message.ts +120 -37
- package/node_modules/@llblab/pi-actors/lib/tools-response.ts +273 -50
- package/node_modules/@llblab/pi-actors/lib/tools-spawn.ts +31 -10
- package/node_modules/@llblab/pi-actors/lib/trace-projection.ts +165 -42
- package/node_modules/@llblab/pi-actors/package.json +10 -6
- package/node_modules/@llblab/pi-actors/scripts/async-runner.mjs +272 -194
- package/node_modules/@llblab/pi-actors/scripts/conformance.mjs +14 -2
- package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +46 -2
- package/node_modules/@llblab/pi-actors/skills/actors/references/diagnostics.md +40 -0
- package/node_modules/@llblab/pi-actors/skills/actors/references/runs.md +55 -1
- package/node_modules/@llblab/pi-codex-usage/AGENTS.md +2 -2
- package/node_modules/@llblab/pi-codex-usage/CHANGELOG.md +6 -0
- package/node_modules/@llblab/pi-codex-usage/README.md +9 -5
- package/node_modules/@llblab/pi-codex-usage/lib/query.ts +229 -50
- package/node_modules/@llblab/pi-codex-usage/lib/usage.ts +9 -1
- package/node_modules/@llblab/pi-codex-usage/package.json +1 -1
- package/node_modules/yaml/LICENSE +13 -0
- package/node_modules/yaml/README.md +172 -0
- package/node_modules/yaml/bin.mjs +11 -0
- package/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
- package/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
- package/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
- package/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
- package/node_modules/yaml/browser/dist/compose/composer.js +219 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
- package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
- package/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
- package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +225 -0
- package/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
- package/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
- package/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
- package/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
- package/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
- package/node_modules/yaml/browser/dist/doc/Document.js +335 -0
- package/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
- package/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
- package/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
- package/node_modules/yaml/browser/dist/doc/directives.js +176 -0
- package/node_modules/yaml/browser/dist/errors.js +57 -0
- package/node_modules/yaml/browser/dist/index.js +17 -0
- package/node_modules/yaml/browser/dist/log.js +11 -0
- package/node_modules/yaml/browser/dist/nodes/Alias.js +116 -0
- package/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
- package/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
- package/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
- package/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
- package/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
- package/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
- package/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
- package/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
- package/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
- package/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
- package/node_modules/yaml/browser/dist/parse/cst.js +98 -0
- package/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
- package/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
- package/node_modules/yaml/browser/dist/parse/parser.js +975 -0
- package/node_modules/yaml/browser/dist/public-api.js +102 -0
- package/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
- package/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
- package/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
- package/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
- package/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
- package/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
- package/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
- package/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
- package/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
- package/node_modules/yaml/browser/dist/schema/tags.js +96 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
- package/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
- package/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
- package/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
- package/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
- package/node_modules/yaml/browser/dist/util.js +11 -0
- package/node_modules/yaml/browser/dist/visit.js +233 -0
- package/node_modules/yaml/browser/index.js +5 -0
- package/node_modules/yaml/browser/package.json +3 -0
- package/node_modules/yaml/dist/cli.d.ts +8 -0
- package/node_modules/yaml/dist/cli.mjs +201 -0
- package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
- package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
- package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
- package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
- package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
- package/node_modules/yaml/dist/compose/compose-node.js +112 -0
- package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
- package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
- package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
- package/node_modules/yaml/dist/compose/composer.js +224 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
- package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
- package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
- package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
- package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
- package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
- package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
- package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
- package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
- package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
- package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
- package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
- package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
- package/node_modules/yaml/dist/doc/Document.js +337 -0
- package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
- package/node_modules/yaml/dist/doc/anchors.js +76 -0
- package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
- package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
- package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
- package/node_modules/yaml/dist/doc/createNode.js +90 -0
- package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
- package/node_modules/yaml/dist/doc/directives.js +178 -0
- package/node_modules/yaml/dist/errors.d.ts +21 -0
- package/node_modules/yaml/dist/errors.js +62 -0
- package/node_modules/yaml/dist/index.d.ts +25 -0
- package/node_modules/yaml/dist/index.js +50 -0
- package/node_modules/yaml/dist/log.d.ts +3 -0
- package/node_modules/yaml/dist/log.js +19 -0
- package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/Alias.js +118 -0
- package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
- package/node_modules/yaml/dist/nodes/Collection.js +151 -0
- package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/Node.js +40 -0
- package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
- package/node_modules/yaml/dist/nodes/Pair.js +39 -0
- package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
- package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
- package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
- package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
- package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
- package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
- package/node_modules/yaml/dist/nodes/identity.js +53 -0
- package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
- package/node_modules/yaml/dist/nodes/toJS.js +39 -0
- package/node_modules/yaml/dist/options.d.ts +350 -0
- package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
- package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
- package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
- package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
- package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
- package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
- package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
- package/node_modules/yaml/dist/parse/cst.js +112 -0
- package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
- package/node_modules/yaml/dist/parse/lexer.js +723 -0
- package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
- package/node_modules/yaml/dist/parse/line-counter.js +41 -0
- package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
- package/node_modules/yaml/dist/parse/parser.js +980 -0
- package/node_modules/yaml/dist/public-api.d.ts +44 -0
- package/node_modules/yaml/dist/public-api.js +107 -0
- package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
- package/node_modules/yaml/dist/schema/Schema.js +39 -0
- package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/map.js +19 -0
- package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
- package/node_modules/yaml/dist/schema/common/null.js +17 -0
- package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/seq.js +19 -0
- package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
- package/node_modules/yaml/dist/schema/common/string.js +16 -0
- package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/bool.js +21 -0
- package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/float.js +47 -0
- package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
- package/node_modules/yaml/dist/schema/core/int.js +42 -0
- package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/core/schema.js +25 -0
- package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
- package/node_modules/yaml/dist/schema/json/schema.js +64 -0
- package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
- package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
- package/node_modules/yaml/dist/schema/tags.js +99 -0
- package/node_modules/yaml/dist/schema/types.d.ts +92 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
- package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
- package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
- package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
- package/node_modules/yaml/dist/stringify/stringify.js +132 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
- package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
- package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
- package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
- package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
- package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
- package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
- package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
- package/node_modules/yaml/dist/test-events.d.ts +4 -0
- package/node_modules/yaml/dist/test-events.js +134 -0
- package/node_modules/yaml/dist/util.d.ts +16 -0
- package/node_modules/yaml/dist/util.js +28 -0
- package/node_modules/yaml/dist/visit.d.ts +102 -0
- package/node_modules/yaml/dist/visit.js +236 -0
- package/node_modules/yaml/package.json +97 -0
- package/node_modules/yaml/util.js +2 -0
- package/package.json +3 -3
- package/node_modules/@llblab/pi-actors/banner.jpg +0 -0
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.d.ts +0 -16
- package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.js +0 -57
- package/node_modules/@llblab/pi-actors/lib/inspector-actions.ts +0 -79
|
@@ -5,15 +5,18 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync, statSync } from "node:fs";
|
|
7
7
|
import * as path from "node:path";
|
|
8
|
-
import {
|
|
8
|
+
import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { Document, isScalar, visit } from "yaml";
|
|
10
|
+
import { matchesKey, Markdown, sliceByColumn, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
9
11
|
import * as ActorInspector from "./inspector.js";
|
|
10
12
|
import * as ControlProjection from "./control-projection.js";
|
|
11
13
|
import * as RunsControls from "./runs-controls.js";
|
|
12
14
|
import * as RunControlDelivery from "./runs-control-delivery.js";
|
|
13
15
|
import * as RunsTrace from "./runs-trace.js";
|
|
14
16
|
import * as Limits from "./limits.js";
|
|
15
|
-
import { computeRunControlCapacity } from "./run-evidence-policy.js";
|
|
17
|
+
import { computeRunControlCapacity, runControlStatusTimestamp } from "./run-evidence-policy.js";
|
|
16
18
|
import * as RuntimeTriage from "./runtime-triage.js";
|
|
19
|
+
import { normalizeRecipeControl } from "./recipe-control.js";
|
|
17
20
|
import * as TraceProjection from "./trace-projection.js";
|
|
18
21
|
const TABS = ["recipe", "trace", "control"];
|
|
19
22
|
const TRACE_SOURCES = [
|
|
@@ -40,12 +43,20 @@ export class ActorInspectorOverlay {
|
|
|
40
43
|
documentScroll = 0;
|
|
41
44
|
detailScroll = 0;
|
|
42
45
|
feedback;
|
|
46
|
+
feedbackFromAction = false;
|
|
47
|
+
feedbackScroll = 0;
|
|
48
|
+
feedbackPageRows = 1;
|
|
49
|
+
inspectorFrame;
|
|
43
50
|
focus = "runs";
|
|
44
51
|
killConfirmation;
|
|
45
52
|
killDialogChoice = "cancel";
|
|
53
|
+
killDialogScroll = 0;
|
|
54
|
+
killDialogPageRows = 1;
|
|
46
55
|
rowIndex = 0;
|
|
47
56
|
runCache;
|
|
48
57
|
selectedTraceId;
|
|
58
|
+
controlCache;
|
|
59
|
+
controlSelection;
|
|
49
60
|
runIndex = 0;
|
|
50
61
|
selectorIndex = 0;
|
|
51
62
|
selectorMode;
|
|
@@ -74,10 +85,9 @@ export class ActorInspectorOverlay {
|
|
|
74
85
|
invalidate() {
|
|
75
86
|
this.runCache = undefined;
|
|
76
87
|
this.traceCache = undefined;
|
|
88
|
+
this.controlCache = undefined;
|
|
77
89
|
}
|
|
78
90
|
handleInput(data) {
|
|
79
|
-
const runs = this.runs();
|
|
80
|
-
this.runIndex = Math.min(this.runIndex, Math.max(0, runs.length - 1));
|
|
81
91
|
if (matchesKey(data, "ctrl+c")) {
|
|
82
92
|
this.done();
|
|
83
93
|
return;
|
|
@@ -87,11 +97,35 @@ export class ActorInspectorOverlay {
|
|
|
87
97
|
this.tui.requestRender();
|
|
88
98
|
return;
|
|
89
99
|
}
|
|
100
|
+
if (this.feedback) {
|
|
101
|
+
if (matchesKey(data, "escape")) {
|
|
102
|
+
this.feedback = undefined;
|
|
103
|
+
this.feedbackFromAction = false;
|
|
104
|
+
this.feedbackScroll = 0;
|
|
105
|
+
}
|
|
106
|
+
else if (matchesKey(data, "up"))
|
|
107
|
+
this.feedbackScroll = Math.max(0, this.feedbackScroll - 1);
|
|
108
|
+
else if (matchesKey(data, "down"))
|
|
109
|
+
this.feedbackScroll++;
|
|
110
|
+
else if (matchesKey(data, "pageUp"))
|
|
111
|
+
this.feedbackScroll = Math.max(0, this.feedbackScroll - this.feedbackPageRows);
|
|
112
|
+
else if (matchesKey(data, "pageDown"))
|
|
113
|
+
this.feedbackScroll += this.feedbackPageRows;
|
|
114
|
+
this.tui.requestRender();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const runs = this.runs();
|
|
118
|
+
this.runIndex = Math.min(this.runIndex, Math.max(0, runs.length - 1));
|
|
90
119
|
if (data.toLowerCase() === "k") {
|
|
91
120
|
this.requestKill(runs[this.runIndex]);
|
|
92
121
|
this.tui.requestRender();
|
|
93
122
|
return;
|
|
94
123
|
}
|
|
124
|
+
if (this.tab === "control" && (this.focus === "list" || this.focus === "detail")) {
|
|
125
|
+
this.handleControlInput(data, runs[this.runIndex]);
|
|
126
|
+
this.tui.requestRender();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
95
129
|
if (matchesKey(data, "escape")) {
|
|
96
130
|
if (this.focus === "select") {
|
|
97
131
|
this.selectorMode = undefined;
|
|
@@ -125,7 +159,9 @@ export class ActorInspectorOverlay {
|
|
|
125
159
|
return;
|
|
126
160
|
}
|
|
127
161
|
if (this.focus === "document") {
|
|
128
|
-
if (matchesKey(data, "
|
|
162
|
+
if (this.tab === "control" && matchesKey(data, "return"))
|
|
163
|
+
this.openControlList(runs[this.runIndex]);
|
|
164
|
+
else if (matchesKey(data, "left"))
|
|
129
165
|
this.focus = "tabs";
|
|
130
166
|
else if (matchesKey(data, "up") && this.documentScroll === 0)
|
|
131
167
|
this.focus = "tabs";
|
|
@@ -167,6 +203,8 @@ export class ActorInspectorOverlay {
|
|
|
167
203
|
else if (matchesKey(data, "return")) {
|
|
168
204
|
if (this.tab === "trace")
|
|
169
205
|
this.openSourceSelector(runs[this.runIndex]);
|
|
206
|
+
else if (this.tab === "control")
|
|
207
|
+
this.openControlList(runs[this.runIndex]);
|
|
170
208
|
else
|
|
171
209
|
this.focus = "document";
|
|
172
210
|
}
|
|
@@ -213,29 +251,28 @@ export class ActorInspectorOverlay {
|
|
|
213
251
|
}
|
|
214
252
|
render(width) {
|
|
215
253
|
const safeWidth = Math.max(24, width);
|
|
254
|
+
const modal = !!(this.killConfirmation || this.feedback);
|
|
255
|
+
if (!modal || !this.inspectorFrame)
|
|
256
|
+
this.inspectorFrame = { width: safeWidth, lines: this.renderInspector(safeWidth) };
|
|
257
|
+
const lines = this.modalUnderlay(safeWidth);
|
|
258
|
+
if (this.killConfirmation)
|
|
259
|
+
this.compositePopup(lines, this.renderKillDialog(safeWidth - 2, lines.length), safeWidth);
|
|
260
|
+
else if (this.feedback)
|
|
261
|
+
this.compositePopup(lines, this.renderFeedbackPopup(safeWidth, lines.length), safeWidth);
|
|
262
|
+
return lines;
|
|
263
|
+
}
|
|
264
|
+
renderInspector(safeWidth) {
|
|
216
265
|
const innerWidth = safeWidth - 2;
|
|
217
266
|
const runs = this.runs();
|
|
218
267
|
this.runIndex = Math.min(this.runIndex, Math.max(0, runs.length - 1));
|
|
219
268
|
const run = runs[this.runIndex];
|
|
220
|
-
if (this.killConfirmation)
|
|
221
|
-
return this.renderKillDialog(innerWidth);
|
|
222
269
|
const lines = [this.border("╭", " Actor Inspector ", "╮", innerWidth)];
|
|
223
|
-
lines.push(this.row(this.renderRunControl(run, runs.length - this.runIndex - 1), innerWidth));
|
|
270
|
+
lines.push(this.row(this.renderRunControl(run, runs.length - this.runIndex - 1, innerWidth), innerWidth));
|
|
224
271
|
lines.push(this.row(this.renderTabs(run), innerWidth));
|
|
225
272
|
lines.push(this.border("├", "", "┤", innerWidth));
|
|
226
273
|
this.contentSelectedRows.clear();
|
|
227
274
|
this.contentStripeIndices = [];
|
|
228
275
|
let content = this.renderContent(run, innerWidth);
|
|
229
|
-
if (this.feedback) {
|
|
230
|
-
const color = this.feedback.ok
|
|
231
|
-
? "success"
|
|
232
|
-
: /^Kill (failed|rejected)/u.test(this.feedback.message)
|
|
233
|
-
? "error"
|
|
234
|
-
: "warning";
|
|
235
|
-
content = [this.theme.fg(color, ` ${this.feedback.message}`), ...content];
|
|
236
|
-
this.contentSelectedRows = new Set([...this.contentSelectedRows].map((index) => index + 1));
|
|
237
|
-
this.contentStripeIndices = [0, ...this.contentStripeIndices];
|
|
238
|
-
}
|
|
239
276
|
const viewportRows = this.contentViewportRows();
|
|
240
277
|
content = content.slice(0, viewportRows);
|
|
241
278
|
for (let index = 0; index < viewportRows; index += 1) {
|
|
@@ -245,9 +282,9 @@ export class ActorInspectorOverlay {
|
|
|
245
282
|
if (this.focus === "select") {
|
|
246
283
|
const runSelector = this.selectorMode === "run";
|
|
247
284
|
const startRow = runSelector ? 2 : 3;
|
|
248
|
-
const horizontalOffset = runSelector ?
|
|
285
|
+
const horizontalOffset = runSelector ? 5 : 12;
|
|
249
286
|
const availableRows = Math.max(3, lines.length - startRow - 1);
|
|
250
|
-
const menu = this.renderSelector(run, availableRows);
|
|
287
|
+
const menu = this.renderSelector(run, availableRows, innerWidth);
|
|
251
288
|
for (const [offset, menuLine] of menu.entries()) {
|
|
252
289
|
const target = startRow + offset;
|
|
253
290
|
if (target >= lines.length - 1)
|
|
@@ -286,15 +323,16 @@ export class ActorInspectorOverlay {
|
|
|
286
323
|
}
|
|
287
324
|
handleScrollableInput(data, target) {
|
|
288
325
|
const key = target === "detail" ? "detailScroll" : "documentScroll";
|
|
326
|
+
const pageRows = () => this.contentViewportRows();
|
|
289
327
|
if (matchesKey(data, "up"))
|
|
290
328
|
this[key] = Math.max(0, this[key] - 1);
|
|
291
329
|
else if (matchesKey(data, "down"))
|
|
292
330
|
this[key] += 1;
|
|
293
331
|
else if (matchesKey(data, "pageUp")) {
|
|
294
|
-
this[key] = Math.max(0, this[key] -
|
|
332
|
+
this[key] = Math.max(0, this[key] - pageRows());
|
|
295
333
|
}
|
|
296
334
|
else if (matchesKey(data, "pageDown")) {
|
|
297
|
-
this[key] +=
|
|
335
|
+
this[key] += pageRows();
|
|
298
336
|
}
|
|
299
337
|
else if (matchesKey(data, "left") && target === "detail") {
|
|
300
338
|
this.selectedTraceId = this.traceDetail?.id;
|
|
@@ -343,6 +381,8 @@ export class ActorInspectorOverlay {
|
|
|
343
381
|
}
|
|
344
382
|
requestKill(run) {
|
|
345
383
|
this.feedback = undefined;
|
|
384
|
+
this.feedbackFromAction = false;
|
|
385
|
+
this.feedbackScroll = 0;
|
|
346
386
|
if (this.focus !== "runs") {
|
|
347
387
|
this.feedback = { ok: false, message: "Focus Run before using Kill." };
|
|
348
388
|
return;
|
|
@@ -369,11 +409,18 @@ export class ActorInspectorOverlay {
|
|
|
369
409
|
status: run.status,
|
|
370
410
|
};
|
|
371
411
|
this.killDialogChoice = "cancel";
|
|
412
|
+
this.killDialogScroll = 0;
|
|
372
413
|
}
|
|
373
414
|
handleKillInput(data) {
|
|
374
415
|
const key = data.toLowerCase();
|
|
375
|
-
if (matchesKey(data, "
|
|
376
|
-
this.
|
|
416
|
+
if (matchesKey(data, "pageUp")) {
|
|
417
|
+
this.killDialogScroll = Math.max(0, this.killDialogScroll - this.killDialogPageRows);
|
|
418
|
+
}
|
|
419
|
+
else if (matchesKey(data, "pageDown")) {
|
|
420
|
+
this.killDialogScroll += this.killDialogPageRows;
|
|
421
|
+
}
|
|
422
|
+
else if (matchesKey(data, "escape") || key === "n") {
|
|
423
|
+
this.feedback = undefined;
|
|
377
424
|
this.killConfirmation = undefined;
|
|
378
425
|
this.killDialogChoice = "cancel";
|
|
379
426
|
}
|
|
@@ -387,7 +434,7 @@ export class ActorInspectorOverlay {
|
|
|
387
434
|
if (this.killDialogChoice === "kill")
|
|
388
435
|
this.confirmKill();
|
|
389
436
|
else {
|
|
390
|
-
this.feedback =
|
|
437
|
+
this.feedback = undefined;
|
|
391
438
|
this.killConfirmation = undefined;
|
|
392
439
|
}
|
|
393
440
|
}
|
|
@@ -398,6 +445,7 @@ export class ActorInspectorOverlay {
|
|
|
398
445
|
this.killDialogChoice = "cancel";
|
|
399
446
|
if (!confirmation || !this.killRun)
|
|
400
447
|
return;
|
|
448
|
+
this.feedbackFromAction = true;
|
|
401
449
|
try {
|
|
402
450
|
const result = this.killRun(confirmation.run, confirmation.runInstanceId);
|
|
403
451
|
this.feedback = result.ok ? undefined : result;
|
|
@@ -406,44 +454,52 @@ export class ActorInspectorOverlay {
|
|
|
406
454
|
}
|
|
407
455
|
catch (error) {
|
|
408
456
|
const message = error instanceof Error ? error.message : String(error);
|
|
457
|
+
const normalized = message.replaceAll(/\s+/g, " ");
|
|
458
|
+
let selected = normalized.slice(0, 160);
|
|
459
|
+
const clipped = typeof normalized === "string" && normalized.length > 160;
|
|
460
|
+
if (clipped && typeof selected === "string" && /[\uD800-\uDBFF]/u.test(selected.at(-1) ?? "") && /[\uDC00-\uDFFF]/u.test(normalized[160]))
|
|
461
|
+
selected = selected.slice(0, -1);
|
|
409
462
|
this.feedback = {
|
|
410
463
|
ok: false,
|
|
411
|
-
message:
|
|
464
|
+
message: ActorInspector.formatActorInspectorKillFeedback("failed", `${selected}`, { clipped }),
|
|
412
465
|
};
|
|
413
466
|
}
|
|
414
467
|
}
|
|
415
|
-
renderKillDialog(
|
|
468
|
+
renderKillDialog(width, maxRows) {
|
|
469
|
+
const innerWidth = Math.min(width, 70), textWidth = innerWidth - 2;
|
|
416
470
|
const confirmation = this.killConfirmation;
|
|
417
471
|
const cancel = this.killDialogChoice === "cancel"
|
|
418
|
-
? this.theme.bg("selectedBg", this.theme.fg("accent", "
|
|
419
|
-
: this.theme.fg("muted", "
|
|
472
|
+
? this.theme.bg("selectedBg", this.theme.fg("accent", " Cancel "))
|
|
473
|
+
: this.theme.fg("muted", " Cancel ");
|
|
420
474
|
const kill = this.killDialogChoice === "kill"
|
|
421
|
-
? this.theme.bg("selectedBg", this.theme.fg("error", "
|
|
422
|
-
: this.theme.fg("error", "
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
"",
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
this.
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
475
|
+
? this.theme.bg("selectedBg", this.theme.fg("error", " Kill actor "))
|
|
476
|
+
: this.theme.fg("error", " Kill actor ");
|
|
477
|
+
const details = this.documentProjection({
|
|
478
|
+
run: confirmation.run,
|
|
479
|
+
state: confirmation.status,
|
|
480
|
+
action: "generation-fenced runtime kill",
|
|
481
|
+
}, textWidth).lines;
|
|
482
|
+
const safety = this.closureWarning(textWidth).map(line => this.theme.fg("warning", line));
|
|
483
|
+
const choices = visibleWidth(cancel) + 2 + visibleWidth(kill) <= textWidth
|
|
484
|
+
? [this.center(`${cancel} ${kill}`, textWidth)]
|
|
485
|
+
: [this.center(cancel, textWidth), this.center(kill, textWidth)];
|
|
486
|
+
const layout = this.popupLayout(maxRows, safety.length + 1 + choices.length, details.length);
|
|
487
|
+
this.killDialogPageRows = layout.pageRows;
|
|
488
|
+
this.killDialogScroll = Math.min(this.killDialogScroll, Math.max(0, details.length - this.killDialogPageRows));
|
|
489
|
+
const visible = details.slice(this.killDialogScroll, this.killDialogScroll + this.killDialogPageRows);
|
|
490
|
+
const hints = innerWidth < 30 ? this.keyHints(["↵", "pick"], ["esc", "back"])
|
|
491
|
+
: innerWidth < 60 ? this.keyHints(["←→/tab", "choose"], ["↵", "pick"], ["esc", "back"]) : this.renderKeyHints(true);
|
|
492
|
+
return [
|
|
493
|
+
this.border("╭", " Confirm Actor Kill ", "╮", innerWidth),
|
|
494
|
+
...(layout.top ? [this.row("", innerWidth)] : []),
|
|
495
|
+
...visible.map(line => this.row(" " + line, innerWidth)),
|
|
496
|
+
...(layout.paged ? [this.row(" " + this.theme.fg("muted", `${this.killDialogScroll + 1}-${this.killDialogScroll + visible.length}/${details.length} pgup/pgdn`), innerWidth)] : []),
|
|
497
|
+
...[...safety, "", ...choices].map(line => this.row(" " + line, innerWidth)),
|
|
498
|
+
...(layout.bottom ? [this.row("", innerWidth)] : []),
|
|
499
|
+
this.footerBorder(hints, innerWidth),
|
|
434
500
|
];
|
|
435
|
-
const lines = [this.border("╭", " Confirm Actor Kill ", "╮", innerWidth)];
|
|
436
|
-
const availableRows = this.contentViewportRows() + 3;
|
|
437
|
-
const topPadding = Math.max(0, Math.floor((availableRows - body.length) / 2));
|
|
438
|
-
const rows = [...Array.from({ length: topPadding }, () => ""), ...body].slice(0, availableRows);
|
|
439
|
-
while (rows.length < availableRows)
|
|
440
|
-
rows.push("");
|
|
441
|
-
for (const line of rows)
|
|
442
|
-
lines.push(this.row(this.center(line, innerWidth), innerWidth));
|
|
443
|
-
lines.push(this.footerBorder(this.renderKeyHints(), innerWidth));
|
|
444
|
-
return lines;
|
|
445
501
|
}
|
|
446
|
-
renderRunControl(run, sequence) {
|
|
502
|
+
renderRunControl(run, sequence, width) {
|
|
447
503
|
const active = this.focus === "runs" || (this.focus === "select" && this.selectorMode === "run");
|
|
448
504
|
const prefix = active ? this.theme.fg("accent", " ← ") : " ";
|
|
449
505
|
const suffix = active ? this.theme.fg("accent", " → ") : " ";
|
|
@@ -452,10 +508,11 @@ export class ActorInspectorOverlay {
|
|
|
452
508
|
return active ? this.theme.bg("selectedBg", empty) : empty;
|
|
453
509
|
}
|
|
454
510
|
const value = `${prefix}${this.theme.fg("muted", "Run: ")}${this.theme.fg("text", `#${sequence}`)} ${this.theme.fg("accent", run.run)} ${this.theme.fg(this.statusColor(run.status), run.status)}${suffix}`;
|
|
455
|
-
|
|
511
|
+
const bounded = truncateToWidth(value, width, "…");
|
|
512
|
+
return active ? this.theme.bg("selectedBg", bounded) : bounded;
|
|
456
513
|
}
|
|
457
514
|
renderTabs(run) {
|
|
458
|
-
const source = this.traceSource(run);
|
|
515
|
+
const source = this.tab === "trace" ? this.traceSource(run) : "all";
|
|
459
516
|
return TABS.map((tab, index) => {
|
|
460
517
|
const base = `${tab[0].toUpperCase()}${tab.slice(1)}`;
|
|
461
518
|
const label = tab === "trace" && source !== "all" ? `${base}: ${source}` : base;
|
|
@@ -479,39 +536,112 @@ export class ActorInspectorOverlay {
|
|
|
479
536
|
renderContent(run, width) {
|
|
480
537
|
if (!run)
|
|
481
538
|
return [this.theme.fg("muted", " No owned actor runs")];
|
|
539
|
+
if (this.tab === "control" && (this.focus === "list" || this.focus === "detail"))
|
|
540
|
+
return this.renderControlContent(run, width);
|
|
482
541
|
if (this.focus === "detail")
|
|
483
542
|
return this.renderTraceDetail(width);
|
|
484
543
|
if (this.tab === "trace")
|
|
485
|
-
return this.renderTraceList(run);
|
|
486
|
-
const
|
|
544
|
+
return this.renderTraceList(run, width);
|
|
545
|
+
const selectedRun = run.run;
|
|
546
|
+
const stateDir = path.join(this.stateRoot, selectedRun);
|
|
487
547
|
const value = this.tab === "recipe"
|
|
488
548
|
? ActorInspector.readActorInspectorRecipe(stateDir)
|
|
489
549
|
: this.controlDocument(run, stateDir);
|
|
490
|
-
const
|
|
550
|
+
const body = this.documentProjection(value, width);
|
|
551
|
+
const identity = this.documentProjection({ selected_run_id: selectedRun }, width);
|
|
552
|
+
const projection = {
|
|
553
|
+
lines: [...identity.lines, ...body.lines],
|
|
554
|
+
stripes: [...identity.stripes, ...body.stripes.map(index => index + 1)],
|
|
555
|
+
};
|
|
491
556
|
const maxStart = Math.max(0, projection.lines.length - this.contentViewportRows());
|
|
492
557
|
this.documentScroll = Math.min(this.documentScroll, maxStart);
|
|
493
558
|
this.contentStripeIndices = projection.stripes.slice(this.documentScroll, this.documentScroll + this.contentViewportRows());
|
|
494
559
|
return projection.lines.slice(this.documentScroll, this.documentScroll + this.contentViewportRows());
|
|
495
560
|
}
|
|
496
|
-
|
|
561
|
+
modalUnderlay(width) {
|
|
562
|
+
const frame = this.inspectorFrame;
|
|
563
|
+
const height = this.contentViewportRows() + 5;
|
|
564
|
+
if (frame.width === width && frame.lines.length === height)
|
|
565
|
+
return frame.lines.slice();
|
|
566
|
+
// Resize the frozen underlay without refreshing evidence behind an open modal.
|
|
567
|
+
const innerWidth = width - 2;
|
|
568
|
+
const content = (index) => sliceByColumn(frame.lines[index] ?? "", 1, frame.width - 2, true);
|
|
569
|
+
return [
|
|
570
|
+
this.border("╭", " Actor Inspector ", "╮", innerWidth),
|
|
571
|
+
this.row(content(1), innerWidth),
|
|
572
|
+
this.row(content(2), innerWidth),
|
|
573
|
+
this.border("├", "", "┤", innerWidth),
|
|
574
|
+
...Array.from({ length: height - 5 }, (_, index) => this.row(index < frame.lines.length - 5 ? content(index + 4) : "", innerWidth)),
|
|
575
|
+
this.footerBorder(content(frame.lines.length - 1), innerWidth),
|
|
576
|
+
];
|
|
577
|
+
}
|
|
578
|
+
compositePopup(lines, popup, width) {
|
|
579
|
+
const popupWidth = visibleWidth(popup[0]);
|
|
580
|
+
const left = Math.floor((width - popupWidth) / 2);
|
|
581
|
+
const top = Math.floor((lines.length - popup.length) / 2);
|
|
582
|
+
for (const [offset, line] of popup.entries()) {
|
|
583
|
+
const base = lines[top + offset];
|
|
584
|
+
const right = left + popupWidth;
|
|
585
|
+
// Terminal-default background masks underlying stripes; selected buttons keep their own fill.
|
|
586
|
+
lines[top + offset] = `${sliceByColumn(base, 0, left, true)}\u001b[49m${line}\u001b[49m${sliceByColumn(base, right, width - right, true)}`;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
popupLayout(maxRows, fixedRows, detailRows) {
|
|
590
|
+
// Reserve readable text, pinned safety and choices before decorative blank rows.
|
|
591
|
+
const minimum = 2 + fixedRows + Math.min(2, detailRows);
|
|
592
|
+
const paddingRows = Math.min(2, Math.max(0, maxRows - minimum));
|
|
593
|
+
const height = Math.min(maxRows, Math.max(maxRows - 2, minimum + paddingRows));
|
|
594
|
+
const slots = height - 2 - fixedRows - paddingRows;
|
|
595
|
+
const paged = detailRows > slots;
|
|
596
|
+
return { top: paddingRows > 0, bottom: paddingRows > 1, pageRows: Math.min(detailRows, slots - Number(paged)), paged };
|
|
597
|
+
}
|
|
598
|
+
renderFeedbackPopup(width, maxRows) {
|
|
599
|
+
const feedback = this.feedback;
|
|
600
|
+
const innerWidth = Math.min(70, width - 2), textWidth = innerWidth - 2;
|
|
601
|
+
const color = feedback.ok
|
|
602
|
+
? "success"
|
|
603
|
+
: /^(?:Kill (?:failed|rejected)|- action: kill\n- result: (?:failed|rejected)\n)/u.test(feedback.message) ? "error" : "warning";
|
|
604
|
+
const message = `${feedback.message}`;
|
|
605
|
+
const details = this.wrapDocument(message.split(/\r\n|\r|\n/u).map(text => ({ text })), textWidth).map(line => line.text);
|
|
606
|
+
const safety = this.feedbackFromAction ? [...this.closureWarning(textWidth), "No automatic retry."] : [];
|
|
607
|
+
const layout = this.popupLayout(maxRows, safety.length, details.length);
|
|
608
|
+
this.feedbackPageRows = layout.pageRows;
|
|
609
|
+
this.feedbackScroll = Math.min(this.feedbackScroll, Math.max(0, details.length - this.feedbackPageRows));
|
|
610
|
+
const visible = details.slice(this.feedbackScroll, this.feedbackScroll + this.feedbackPageRows);
|
|
611
|
+
return [
|
|
612
|
+
this.border("╭", " Notice ", "╮", innerWidth),
|
|
613
|
+
...(layout.top ? [this.row("", innerWidth)] : []),
|
|
614
|
+
...visible.map(line => this.row(" " + this.theme.fg(color, line), innerWidth)),
|
|
615
|
+
...(layout.paged ? [this.row(" " + this.theme.fg("muted", `${this.feedbackScroll + 1}-${this.feedbackScroll + visible.length}/${details.length} ↑↓ pgup/pgdn`), innerWidth)] : []),
|
|
616
|
+
...safety.map(line => this.row(" " + this.theme.fg("warning", line), innerWidth)),
|
|
617
|
+
...(layout.bottom ? [this.row("", innerWidth)] : []),
|
|
618
|
+
this.footerBorder(this.keyHints(["esc", "close"]), innerWidth),
|
|
619
|
+
];
|
|
620
|
+
}
|
|
621
|
+
closureWarning(width) {
|
|
622
|
+
return width >= visibleWidth("- closure: unconfirmed")
|
|
623
|
+
? ["- closure: unconfirmed"] : ["- closure:", " unconfirmed"];
|
|
624
|
+
}
|
|
625
|
+
renderSelector(run, availableRows, width) {
|
|
626
|
+
// Run menu reserves five offset columns, two markers, two borders and one right-padding column.
|
|
497
627
|
const options = this.selectorMode === "run"
|
|
498
|
-
? this.runSelectorOptions()
|
|
628
|
+
? this.runSelectorOptions(Math.max(0, width - 10))
|
|
499
629
|
: this.traceSources(run).map((source) => ({
|
|
500
630
|
content: `${this.theme.fg("accent", "Trace:")} ${this.theme.fg("text", source)}`,
|
|
501
631
|
preserveColors: true,
|
|
502
632
|
}));
|
|
503
633
|
return this.renderMenuBox(options, this.selectorIndex, availableRows);
|
|
504
634
|
}
|
|
505
|
-
runSelectorOptions() {
|
|
635
|
+
runSelectorOptions(width) {
|
|
506
636
|
const runs = this.runs();
|
|
507
637
|
const sequenceWidth = Math.max(2, ...runs.map((_item, index) => `#${runs.length - index - 1}`.length));
|
|
508
638
|
const runWidth = Math.max(1, ...runs.map((item) => visibleWidth(item.run)));
|
|
509
639
|
return runs.map((item, index) => ({
|
|
510
|
-
content: [
|
|
640
|
+
content: truncateToWidth([
|
|
511
641
|
this.theme.fg("text", this.fit(`#${runs.length - index - 1}`, sequenceWidth)),
|
|
512
642
|
this.theme.fg("accent", this.fit(item.run, runWidth)),
|
|
513
643
|
this.theme.fg(this.statusColor(item.status), item.status),
|
|
514
|
-
].join(" "),
|
|
644
|
+
].join(" "), width, "…"),
|
|
515
645
|
preserveColors: true,
|
|
516
646
|
}));
|
|
517
647
|
}
|
|
@@ -522,29 +652,40 @@ export class ActorInspectorOverlay {
|
|
|
522
652
|
const maxStart = Math.max(0, options.length - visibleLimit);
|
|
523
653
|
const start = Math.max(0, Math.min(focusedIndex - Math.floor(visibleLimit / 2), maxStart));
|
|
524
654
|
const visible = options.slice(start, start + visibleLimit);
|
|
525
|
-
const
|
|
526
|
-
const
|
|
655
|
+
const runMenu = this.selectorMode === "run";
|
|
656
|
+
const width = Math.max(8, ...options.map((option) => visibleWidth(option.content) + (runMenu ? 3 : 4)));
|
|
657
|
+
// Reset both menu edges so sliced document backgrounds cannot bleed through.
|
|
658
|
+
const ownBackground = (line) => runMenu ? `\u001b[49m${line}\u001b[49m` : line;
|
|
659
|
+
const border = (left, right, marker = "") => ownBackground(this.theme.fg("borderAccent", `${left}${marker}${"─".repeat(Math.max(0, width - visibleWidth(marker)))}${right}`));
|
|
527
660
|
return [
|
|
528
661
|
border("╭", "╮", start > 0 ? "↑" : ""),
|
|
529
662
|
...visible.map((option, offset) => {
|
|
530
663
|
const index = start + offset;
|
|
531
664
|
const marker = index === focusedIndex
|
|
532
|
-
? this.theme.fg("accent", " ▶ ")
|
|
533
|
-
: " ";
|
|
534
|
-
const row = this.fit(`${marker}${option.content}`, width);
|
|
665
|
+
? this.theme.fg("accent", runMenu ? "▶ " : " ▶ ")
|
|
666
|
+
: runMenu ? " " : " ";
|
|
667
|
+
const row = this.fit(`${marker}${option.content}`, width - Number(runMenu)) + (runMenu ? " " : "");
|
|
535
668
|
const colored = index === focusedIndex && !option.preserveColors
|
|
536
669
|
? this.theme.fg("accent", row)
|
|
537
670
|
: row;
|
|
538
|
-
const
|
|
539
|
-
|
|
671
|
+
const background = index === focusedIndex ? "selectedBg" : runMenu && index % 2 ? "customMessageBg" : undefined;
|
|
672
|
+
// Native truncation emits full SGR resets; repaint each resulting segment.
|
|
673
|
+
const styled = background === undefined ? colored : runMenu
|
|
674
|
+
? colored.split("\u001b[0m").map(part => this.theme.bg(background, part)).join("\u001b[0m")
|
|
675
|
+
: this.theme.bg(background, colored);
|
|
676
|
+
return ownBackground(`${this.theme.fg("borderAccent", "│")}${styled}${this.theme.fg("borderAccent", "│")}`);
|
|
540
677
|
}),
|
|
541
678
|
border("╰", "╯", start + visible.length < options.length ? "↓" : ""),
|
|
542
679
|
];
|
|
543
680
|
}
|
|
544
|
-
|
|
681
|
+
traceTableLine(text, width) {
|
|
682
|
+
const [first = "", ...rest] = text.split(/\r\n|\r|\n/u);
|
|
683
|
+
return truncateToWidth(first + (rest.length ? "…" : ""), width, "…");
|
|
684
|
+
}
|
|
685
|
+
renderTraceList(run, width) {
|
|
545
686
|
const items = this.traceItems(run);
|
|
546
|
-
const summary = RunsTrace.summarizeRunTraceJournal(RunsTrace.readRunTraceJournal(path.join(this.stateRoot, run.run)));
|
|
547
|
-
const banner = summary.history_complete ? [] : [this.theme.fg("warning", ` ! Trace history incomplete: ${summary.compacted ? `${summary.compactions_total} compaction(s), ` : ""}${summary.dropped_event_count_exact ? summary.dropped_events : "unknown"} dropped event(s), ${summary.dropped_bytes} bytes
|
|
687
|
+
const summary = this.traceCache.journalSummary ??= RunsTrace.summarizeRunTraceJournal(RunsTrace.readRunTraceJournal(path.join(this.stateRoot, run.run)));
|
|
688
|
+
const banner = summary.history_complete ? [] : [this.theme.fg("warning", width < visibleWidth(" ! Trace history incomplete:") ? " ! Trace incomplete…" : this.traceTableLine(` ! Trace history incomplete: ${summary.compacted ? `${summary.compactions_total} compaction(s), ` : ""}${summary.dropped_event_count_exact ? summary.dropped_events : "unknown"} dropped event(s), ${summary.dropped_bytes} bytes`, width))];
|
|
548
689
|
if (items.length === 0)
|
|
549
690
|
return [...banner, this.theme.fg("muted", " No Trace evidence")];
|
|
550
691
|
if (this.selectedTraceId) {
|
|
@@ -575,59 +716,315 @@ export class ActorInspectorOverlay {
|
|
|
575
716
|
const detail = item.detail && typeof item.detail === "object"
|
|
576
717
|
? item.detail
|
|
577
718
|
: {};
|
|
578
|
-
const
|
|
579
|
-
? this.theme.fg("
|
|
580
|
-
:
|
|
581
|
-
? this.theme.fg("warning", "A")
|
|
582
|
-
: " ";
|
|
719
|
+
const attention = item.level !== "error" && detail.attention
|
|
720
|
+
? this.theme.fg("warning", "A") + " "
|
|
721
|
+
: "";
|
|
583
722
|
const prefix = this.focus === "list" && index === this.rowIndex
|
|
584
|
-
? this.theme.fg("accent", "
|
|
585
|
-
: "
|
|
586
|
-
const
|
|
587
|
-
const
|
|
723
|
+
? this.theme.fg("accent", "▶ ")
|
|
724
|
+
: " ";
|
|
725
|
+
const chronology = item[TraceProjection.TRACE_ITEM_CHRONOLOGY];
|
|
726
|
+
const sequence = chronology?.state === "available" ? chronology.ordinal : "?";
|
|
727
|
+
const row = `${prefix}${this.theme.fg("text", `#${sequence}`)} ${attention}${this.theme.fg("muted", item.source)}/${this.theme.fg(item.level === "error" ? "error" : "accent", item.kind)} ${this.theme.fg("text", item.summary)}`;
|
|
728
|
+
const preview = this.traceTableLine(row, width);
|
|
588
729
|
return this.focus === "list" && index === this.rowIndex
|
|
589
|
-
? this.theme.fg("accent",
|
|
590
|
-
:
|
|
730
|
+
? this.theme.fg("accent", preview)
|
|
731
|
+
: preview;
|
|
591
732
|
})];
|
|
592
733
|
}
|
|
593
734
|
renderTraceDetail(width) {
|
|
594
735
|
if (!this.traceDetail)
|
|
595
736
|
return [this.theme.fg("warning", " Trace row is no longer available")];
|
|
596
|
-
const
|
|
737
|
+
const sequence = this.traceDetail[TraceProjection.TRACE_ITEM_SEQUENCE];
|
|
738
|
+
const value = {
|
|
739
|
+
...(sequence !== undefined ? { projection_sequence: sequence } : {}),
|
|
740
|
+
...this.traceDetail,
|
|
741
|
+
chronology: this.traceDetail[TraceProjection.TRACE_ITEM_CHRONOLOGY] ?? { state: "unavailable", reason: "metadata_unavailable" },
|
|
742
|
+
};
|
|
743
|
+
const projection = this.traceDetail.source === "agent" && this.traceDetail.kind === "agent.turn"
|
|
744
|
+
? this.agentDetailProjection(value, width) : this.documentProjection(value, width);
|
|
597
745
|
const maxStart = Math.max(0, projection.lines.length - this.contentViewportRows());
|
|
598
746
|
this.detailScroll = Math.min(this.detailScroll, maxStart);
|
|
599
747
|
this.contentStripeIndices = projection.stripes.slice(this.detailScroll, this.detailScroll + this.contentViewportRows());
|
|
600
748
|
return projection.lines.slice(this.detailScroll, this.detailScroll + this.contentViewportRows());
|
|
601
749
|
}
|
|
750
|
+
agentDetailSegments(value) {
|
|
751
|
+
const extractedBody = Symbol("extracted-body");
|
|
752
|
+
const bodies = [];
|
|
753
|
+
// Only typed SessionEvidenceTurn slots are bodies. Never inspect authored text for framing.
|
|
754
|
+
const select = (item, field) => {
|
|
755
|
+
if (typeof item === "string") {
|
|
756
|
+
bodies.push({ field, text: item });
|
|
757
|
+
return extractedBody;
|
|
758
|
+
}
|
|
759
|
+
return item;
|
|
760
|
+
};
|
|
761
|
+
const record = value;
|
|
762
|
+
const detail = record.detail;
|
|
763
|
+
let metadata = value;
|
|
764
|
+
if (detail && typeof detail === "object" && !Array.isArray(detail)) {
|
|
765
|
+
const retained = Object.fromEntries(Object.entries(detail).map(([key, item]) => {
|
|
766
|
+
if (["assistantText", "userText", "thinking"].includes(key) && typeof item === "string") {
|
|
767
|
+
return [key, select(item, ["detail", key])];
|
|
768
|
+
}
|
|
769
|
+
if (key !== "toolCalls" || !Array.isArray(item))
|
|
770
|
+
return [key, item];
|
|
771
|
+
return [key, item.map((call, callIndex) => {
|
|
772
|
+
if (!call || typeof call !== "object" || Array.isArray(call))
|
|
773
|
+
return call;
|
|
774
|
+
// Action-first display order only; retained tool-call data and body rendering stay unchanged.
|
|
775
|
+
const rank = (key) => key === "name" ? 0 : key === "arguments" ? 1 : key === "result" ? 3 : 2;
|
|
776
|
+
return Object.fromEntries(Object.entries(call).sort(([left], [right]) => rank(left) - rank(right)).map(([name, result]) => {
|
|
777
|
+
if (name !== "result")
|
|
778
|
+
return [name, result];
|
|
779
|
+
const field = ["detail", key, callIndex, name];
|
|
780
|
+
if (typeof result === "string")
|
|
781
|
+
return [name, select(result, field)];
|
|
782
|
+
if (!Array.isArray(result))
|
|
783
|
+
return [name, result];
|
|
784
|
+
return [name, result.map((block, blockIndex) => {
|
|
785
|
+
if (!block || typeof block !== "object" || block.type !== "text" || typeof block.text !== "string")
|
|
786
|
+
return block;
|
|
787
|
+
select(block.text, [...field, blockIndex, "text"]);
|
|
788
|
+
return Object.fromEntries(Object.entries(block).filter(([slot]) => slot !== "text"));
|
|
789
|
+
})];
|
|
790
|
+
}).filter(([, item]) => item !== extractedBody));
|
|
791
|
+
})];
|
|
792
|
+
}).filter(([, item]) => item !== extractedBody));
|
|
793
|
+
metadata = { ...record, detail: retained };
|
|
794
|
+
}
|
|
795
|
+
return [{ kind: "metadata", value: metadata }, ...bodies.flatMap(({ field, text }) => [
|
|
796
|
+
{ kind: "metadata", value: { field } }, { kind: "body", text },
|
|
797
|
+
])];
|
|
798
|
+
}
|
|
799
|
+
metadataText(value) {
|
|
800
|
+
// Copy own selected data, so the library cannot invoke an object's toJSON hook.
|
|
801
|
+
const copy = (item) => {
|
|
802
|
+
// UI-only value state: keep an own undefined slot visible, distinct from null or literal text.
|
|
803
|
+
if (item === undefined)
|
|
804
|
+
return { value_state: "undefined" };
|
|
805
|
+
if (typeof item === "function")
|
|
806
|
+
throw new TypeError("Inspector metadata must be selected own data");
|
|
807
|
+
if (!item || typeof item !== "object")
|
|
808
|
+
return item;
|
|
809
|
+
if (Array.isArray(item))
|
|
810
|
+
return Array.from({ length: item.length }, (_, index) => {
|
|
811
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, String(index));
|
|
812
|
+
if (descriptor && !Object.hasOwn(descriptor, "value"))
|
|
813
|
+
throw new TypeError("Inspector metadata must be selected own data");
|
|
814
|
+
return copy(descriptor?.value);
|
|
815
|
+
});
|
|
816
|
+
const result = Object.create(null);
|
|
817
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(item))) {
|
|
818
|
+
if (!descriptor.enumerable)
|
|
819
|
+
continue;
|
|
820
|
+
if (!Object.hasOwn(descriptor, "value"))
|
|
821
|
+
throw new TypeError("Inspector metadata must be selected own data");
|
|
822
|
+
result[key] = copy(descriptor.value);
|
|
823
|
+
}
|
|
824
|
+
return result;
|
|
825
|
+
};
|
|
826
|
+
const document = new Document(copy(value), { version: "1.2", schema: "core", aliasDuplicateObjects: false });
|
|
827
|
+
visit(document, { Pair(_key, pair) {
|
|
828
|
+
if (isScalar(pair.key) && typeof pair.key.value === "string" && pair.key.value.includes("\uFEFF"))
|
|
829
|
+
pair.key.type = "QUOTE_DOUBLE";
|
|
830
|
+
} });
|
|
831
|
+
return document.toString({ collectionStyle: "block", indent: 2, lineWidth: 0, directives: false,
|
|
832
|
+
defaultStringType: "PLAIN", doubleQuotedAsJSON: true });
|
|
833
|
+
}
|
|
834
|
+
agentDetailProjection(value, width) {
|
|
835
|
+
const segments = this.agentDetailSegments(value);
|
|
836
|
+
const lines = [], stripes = [];
|
|
837
|
+
const markdownTheme = { ...getMarkdownTheme(), codeBlockIndent: "" };
|
|
838
|
+
const detailStripe = Object.keys(value).indexOf("detail");
|
|
839
|
+
const append = (rendered, stripe) => {
|
|
840
|
+
lines.push(...rendered);
|
|
841
|
+
stripes.push(...rendered.map(() => stripe));
|
|
842
|
+
};
|
|
843
|
+
const metadata = (selected, stripe) => {
|
|
844
|
+
// yaml's standard serializer has no completion-wire budget/depth ceiling. Data is already admitted upstream.
|
|
845
|
+
const yaml = this.metadataText(selected).replace(/\n$/u, "");
|
|
846
|
+
append(this.wrapDocument(yaml.split("\n").map(text => ({ text })), width).map(line => this.theme.fg("muted", line.text)), stripe);
|
|
847
|
+
};
|
|
848
|
+
segments.forEach((segment, index) => {
|
|
849
|
+
if (index)
|
|
850
|
+
append([""], detailStripe);
|
|
851
|
+
if (segment.kind === "body") {
|
|
852
|
+
append(new Markdown(segment.text, 0, 0, markdownTheme, { color: text => this.theme.fg("text", text) }).render(width), detailStripe);
|
|
853
|
+
}
|
|
854
|
+
else if (index === 0) {
|
|
855
|
+
// Serialize root entries separately to retain root-field stripe provenance without parsing YAML rows.
|
|
856
|
+
Object.entries(segment.value).forEach(([key, item], stripe) => metadata({ [key]: item }, stripe));
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
if (segments[index + 1]?.kind === "body")
|
|
860
|
+
append([this.theme.fg("muted", "---")], detailStripe);
|
|
861
|
+
metadata(segment.value, detailStripe);
|
|
862
|
+
if (segments[index + 1]?.kind === "body")
|
|
863
|
+
append([this.theme.fg("muted", "---")], detailStripe);
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
return { lines, stripes };
|
|
867
|
+
}
|
|
602
868
|
controlDocument(run, stateDir) {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
869
|
+
return this.controlObservation(run, stateDir).document;
|
|
870
|
+
}
|
|
871
|
+
controlObservation(run, stateDir = path.join(this.stateRoot, run.run)) {
|
|
872
|
+
if (this.controlCache?.run === run.run && this.controlCache.generation === run.runInstanceId)
|
|
873
|
+
return this.controlCache;
|
|
606
874
|
const meta = this.readRunMeta(stateDir);
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
const
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
journal_bytes: (() => { try {
|
|
617
|
-
return statSync(RunsControls.runControlsFile(stateDir)).size;
|
|
875
|
+
const bound = Boolean(meta && !Array.isArray(meta) && run.runInstanceId && meta.run === run.run
|
|
876
|
+
&& meta.run_instance_id === run.runInstanceId && meta.ownerId === this.ownerId);
|
|
877
|
+
const diagnostics = [];
|
|
878
|
+
let actions = [];
|
|
879
|
+
if (!bound)
|
|
880
|
+
diagnostics.push({ reason: "metadata_binding_unavailable" });
|
|
881
|
+
else {
|
|
882
|
+
try {
|
|
883
|
+
actions = normalizeRecipeControl(meta.control) ?? [];
|
|
618
884
|
}
|
|
619
885
|
catch {
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
886
|
+
diagnostics.push({ reason: "invalid_action_declarations" });
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
const endpoint = bound ? RunControlDelivery.readRunControlEndpoint(stateDir, run.runInstanceId) : undefined;
|
|
890
|
+
const journal = bound ? RunsControls.readRunControlJournalFromStateDir(stateDir) : { records: [], diagnostics: [] };
|
|
891
|
+
diagnostics.push(...journal.diagnostics.map(item => item.line === undefined
|
|
892
|
+
? { reason: "unreadable_control_journal" } : { reason: "invalid_control_json", line: item.line }));
|
|
893
|
+
const now = Date.now();
|
|
894
|
+
const ids = new Map();
|
|
895
|
+
for (const value of journal.records) {
|
|
896
|
+
if (value && typeof value === "object" && typeof value.id === "string") {
|
|
897
|
+
const id = value.id;
|
|
898
|
+
ids.set(id, (ids.get(id) ?? 0) + 1);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
const accepted = [];
|
|
902
|
+
for (const [parsedIndex, value] of journal.records.entries()) {
|
|
903
|
+
const classification = RuntimeTriage.classifyRuntimeControl(run, value, now);
|
|
904
|
+
if (classification.diagnostic) {
|
|
905
|
+
diagnostics.push({ reason: classification.diagnostic.reason });
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
const record = value;
|
|
909
|
+
if (record.run_instance_id !== run.runInstanceId) {
|
|
910
|
+
diagnostics.push({ reason: "foreign_generation" });
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
if (ids.get(record.id) !== 1) {
|
|
914
|
+
diagnostics.push({ reason: "duplicate_control_id" });
|
|
915
|
+
continue;
|
|
916
|
+
}
|
|
917
|
+
if (["queued_at", "delivered_at", "claimed_at", "handled_at", "failed_at"].some(field => {
|
|
918
|
+
const timestamp = record[field];
|
|
919
|
+
return (field === "queued_at" || timestamp !== undefined) && (typeof timestamp !== "string" || !Number.isFinite(Date.parse(timestamp)));
|
|
920
|
+
})) {
|
|
921
|
+
diagnostics.push({ reason: "invalid_record_timestamp" });
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
accepted.push({ id: record.id, value: ControlProjection.projectRunControl(record), parsedIndex,
|
|
925
|
+
age: Math.max(0, now - Date.parse(runControlStatusTimestamp(record, record.status))),
|
|
926
|
+
reason: classification.stale?.reason });
|
|
927
|
+
}
|
|
928
|
+
const capacity = computeRunControlCapacity(journal.records);
|
|
929
|
+
const partial = diagnostics.length > 0;
|
|
930
|
+
const rows = accepted.filter(row => row.parsedIndex >= journal.records.length - 20).reverse();
|
|
931
|
+
const readiness = partial ? "data_unavailable" : run.status !== "running" ? "not_ready"
|
|
932
|
+
: !actions.length ? "unsupported" : capacity.backpressured ? "backpressure" : endpoint ? "ready_recorded_endpoint" : "not_ready";
|
|
933
|
+
const reason = partial ? "partial_observation" : run.status !== "running" ? "run_terminal"
|
|
934
|
+
: !actions.length ? "no_declared_actor_actions" : capacity.backpressured ? "pending_limit_reached"
|
|
935
|
+
: endpoint ? "recorded_endpoint_only_not_connection_proof" : "recorded_endpoint_unavailable";
|
|
936
|
+
this.controlCache = { run: run.run, generation: run.runInstanceId, rows, document: {
|
|
937
|
+
actor_control_readiness: readiness, reason, actor_actions: actions,
|
|
938
|
+
data_state: partial ? "partial" : "available", pending: bound ? capacity.pending : null,
|
|
939
|
+
pending_limit: capacity.limit, available: partial ? null : capacity.available,
|
|
940
|
+
backpressured: bound ? capacity.backpressured : null,
|
|
941
|
+
runtime_actions: bound ? run.status === "running" ? this.killRun && run.runInstanceId ? ["kill"] : [] : ["archive", "prune"] : [],
|
|
942
|
+
runtime_actions_note: "API capabilities; only existing Run-focus Kill is interactive",
|
|
943
|
+
request_history: { shown: rows.length, retained: journal.records.length, parsed_suffix_limit: 20,
|
|
944
|
+
partial: partial || journal.records.length > 20, coverage: "recent parsed journal records; malformed-line coverage unavailable; not complete lifetime history" },
|
|
945
|
+
request_navigation: "Enter opens requests; Down scrolls overview",
|
|
946
|
+
evidence: "Saved non-atomic observation; delivered != handled; handled != Run completion; stale never expires requests",
|
|
947
|
+
status: run.status, run_instance_id: run.runInstanceId,
|
|
948
|
+
journal_bytes: (() => { try {
|
|
949
|
+
return statSync(RunsControls.runControlsFile(stateDir)).size;
|
|
950
|
+
}
|
|
951
|
+
catch {
|
|
952
|
+
return null;
|
|
953
|
+
} })(),
|
|
954
|
+
journal_limit: Limits.RUN_CONTROL_JOURNAL_MAX_BYTES,
|
|
955
|
+
stale_pending: accepted.filter(row => row.reason).length, diagnostics,
|
|
956
|
+
endpoint, recent_controls: rows.map(row => row.value),
|
|
957
|
+
} };
|
|
958
|
+
return this.controlCache;
|
|
959
|
+
}
|
|
960
|
+
selectedControl(observation) {
|
|
961
|
+
const selection = this.controlSelection;
|
|
962
|
+
return selection?.run === observation.run && selection.generation === observation.generation
|
|
963
|
+
? observation.rows.find(row => row.id === selection.id) : undefined;
|
|
964
|
+
}
|
|
965
|
+
openControlList(run) {
|
|
966
|
+
this.focus = "list";
|
|
967
|
+
this.rowIndex = 0;
|
|
968
|
+
const observation = run ? this.controlObservation(run) : undefined;
|
|
969
|
+
const first = observation?.rows[0];
|
|
970
|
+
this.controlSelection = first ? { run: observation.run, generation: observation.generation, id: first.id } : undefined;
|
|
971
|
+
}
|
|
972
|
+
handleControlInput(data, run) {
|
|
973
|
+
if (matchesKey(data, "escape") || matchesKey(data, "left")) {
|
|
974
|
+
this.focus = this.focus === "detail" ? "list" : "tabs";
|
|
975
|
+
this.detailScroll = 0;
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
if (!run)
|
|
979
|
+
return;
|
|
980
|
+
const observation = this.controlObservation(run);
|
|
981
|
+
const selected = this.selectedControl(observation);
|
|
982
|
+
if (this.focus === "detail") {
|
|
983
|
+
this.handleScrollableInput(data, "detail");
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
const index = selected ? observation.rows.indexOf(selected) : -1;
|
|
987
|
+
let next = index;
|
|
988
|
+
if (matchesKey(data, "up"))
|
|
989
|
+
next = Math.max(0, index - 1);
|
|
990
|
+
else if (matchesKey(data, "down"))
|
|
991
|
+
next = Math.min(observation.rows.length - 1, index + 1);
|
|
992
|
+
else if (matchesKey(data, "pageUp"))
|
|
993
|
+
next = Math.max(0, index - this.contentViewportRows());
|
|
994
|
+
else if (matchesKey(data, "pageDown"))
|
|
995
|
+
next = Math.min(observation.rows.length - 1, index + this.contentViewportRows());
|
|
996
|
+
else if ((matchesKey(data, "return") || matchesKey(data, "right")) && selected) {
|
|
997
|
+
this.focus = "detail";
|
|
998
|
+
this.detailScroll = 0;
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
if (next !== index && observation.rows[next])
|
|
1002
|
+
this.controlSelection = {
|
|
1003
|
+
run: observation.run, generation: observation.generation, id: observation.rows[next].id,
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
renderControlContent(run, width) {
|
|
1007
|
+
const observation = this.controlObservation(run);
|
|
1008
|
+
const selected = this.selectedControl(observation);
|
|
1009
|
+
if (this.focus === "detail") {
|
|
1010
|
+
const projection = this.documentProjection(selected ? selected.value : { request: "unavailable", reason: "selected Run/generation/id no longer available" }, width);
|
|
1011
|
+
this.detailScroll = Math.min(this.detailScroll, Math.max(0, projection.lines.length - this.contentViewportRows()));
|
|
1012
|
+
this.contentStripeIndices = projection.stripes.slice(this.detailScroll, this.detailScroll + this.contentViewportRows());
|
|
1013
|
+
return projection.lines.slice(this.detailScroll, this.detailScroll + this.contentViewportRows());
|
|
1014
|
+
}
|
|
1015
|
+
const coverage = observation.document.request_history;
|
|
1016
|
+
const banner = this.traceTableLine(` Requests ${coverage.shown}/${coverage.retained} parsed; recent20${coverage.partial ? "; partial" : ""}`, width);
|
|
1017
|
+
if (!observation.rows.length)
|
|
1018
|
+
return [banner, " No requests", this.traceTableLine(" Saved observation; history may be partial", width)];
|
|
1019
|
+
const index = selected ? observation.rows.indexOf(selected) : -1;
|
|
1020
|
+
const count = Math.max(1, this.contentViewportRows() - 2);
|
|
1021
|
+
const start = Math.max(0, index - Math.floor(count / 2));
|
|
1022
|
+
const rows = observation.rows.slice(start, start + count);
|
|
1023
|
+
this.contentStripeIndices = [0, 0, ...rows.map((_row, offset) => start + offset + 1)];
|
|
1024
|
+
if (index >= start)
|
|
1025
|
+
this.contentSelectedRows.add(index - start + 2);
|
|
1026
|
+
return [banner, this.traceTableLine(index < 0 ? " Selection unavailable; arrows select a request" : " Status | action | status age | error/stale", width),
|
|
1027
|
+
...rows.map(row => this.traceTableLine(`${row === selected ? "▶" : " "} ${row.value.status} | ${row.value.action} | ${Math.floor(row.age / 1000)}s | ${row.value.error ?? row.reason ?? ""}`, width))];
|
|
631
1028
|
}
|
|
632
1029
|
allTraceItems(run) {
|
|
633
1030
|
if (!run)
|
|
@@ -666,178 +1063,81 @@ export class ActorInspectorOverlay {
|
|
|
666
1063
|
}
|
|
667
1064
|
}
|
|
668
1065
|
documentProjection(value, width) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1066
|
+
// Copy before enumerating roots: accessors and hooks must never run during projection.
|
|
1067
|
+
const selected = this.metadataText(value);
|
|
1068
|
+
const descriptors = value && typeof value === "object" && !Array.isArray(value)
|
|
1069
|
+
? Object.entries(Object.getOwnPropertyDescriptors(value)).filter(([, descriptor]) => descriptor.enumerable) : [];
|
|
1070
|
+
const sections = descriptors.length
|
|
1071
|
+
? descriptors.map(([key, descriptor]) => this.metadataText({ [key]: descriptor.value }))
|
|
1072
|
+
: [selected];
|
|
672
1073
|
const lines = [];
|
|
673
1074
|
const stripes = [];
|
|
674
1075
|
sections.forEach((section, sectionIndex) => {
|
|
675
|
-
const wrapped = this.wrapDocument(section, width);
|
|
676
|
-
lines.push(...wrapped.map((line) => this.
|
|
1076
|
+
const wrapped = this.wrapDocument(section.replace(/\n$/u, "").split("\n").map(text => ({ text })), width);
|
|
1077
|
+
lines.push(...wrapped.map((line) => this.theme.fg("muted", line.text)));
|
|
677
1078
|
stripes.push(...wrapped.map(() => sectionIndex));
|
|
678
1079
|
});
|
|
679
1080
|
return { lines, stripes };
|
|
680
1081
|
}
|
|
681
|
-
inlineDocumentValue(value) {
|
|
682
|
-
if (Array.isArray(value)) {
|
|
683
|
-
if (value.length === 0)
|
|
684
|
-
return "[]";
|
|
685
|
-
if (value.every((item) => (item === null || typeof item !== "object") &&
|
|
686
|
-
!(typeof item === "string" && /[\r\n]/u.test(item)))) {
|
|
687
|
-
return `[${value.map((item) => String(item ?? "none")).join(", ")}]`;
|
|
688
|
-
}
|
|
689
|
-
return undefined;
|
|
690
|
-
}
|
|
691
|
-
if (value && typeof value === "object") {
|
|
692
|
-
if (Object.keys(value).length === 0)
|
|
693
|
-
return "{}";
|
|
694
|
-
}
|
|
695
|
-
return undefined;
|
|
696
|
-
}
|
|
697
|
-
labeledDocumentLines(key, value, depth = 0) {
|
|
698
|
-
const inline = this.inlineDocumentValue(value);
|
|
699
|
-
if (inline !== undefined)
|
|
700
|
-
return [`${" ".repeat(depth)}${key}: ${inline}`];
|
|
701
|
-
if (value && typeof value === "object") {
|
|
702
|
-
const indent = " ".repeat(depth);
|
|
703
|
-
const nested = this.document(value, depth);
|
|
704
|
-
return [`${indent}${key}: ${nested[0].slice(indent.length)}`, ...nested.slice(1)];
|
|
705
|
-
}
|
|
706
|
-
return this.labeledScalarLines(key, value, depth);
|
|
707
|
-
}
|
|
708
|
-
labeledScalarLines(key, value, depth = 0) {
|
|
709
|
-
const indent = " ".repeat(depth);
|
|
710
|
-
const [first = "", ...rest] = String(value ?? "none").split(/\r?\n/u);
|
|
711
|
-
return [
|
|
712
|
-
`${indent}${key}: ${first}`,
|
|
713
|
-
...rest.map((line) => `${indent} ${line}`),
|
|
714
|
-
];
|
|
715
|
-
}
|
|
716
|
-
document(value, depth = 0) {
|
|
717
|
-
if (value === null || value === undefined)
|
|
718
|
-
return [`${" ".repeat(depth)}none`];
|
|
719
|
-
const inline = this.inlineDocumentValue(value);
|
|
720
|
-
if (inline !== undefined)
|
|
721
|
-
return [`${" ".repeat(depth)}${inline}`];
|
|
722
|
-
if (Array.isArray(value)) {
|
|
723
|
-
const indent = " ".repeat(depth);
|
|
724
|
-
return [
|
|
725
|
-
`${indent}[`,
|
|
726
|
-
...value.flatMap((item, index) => {
|
|
727
|
-
const itemDepth = depth + 1;
|
|
728
|
-
const itemIndent = " ".repeat(itemDepth);
|
|
729
|
-
const marker = `#${index}`;
|
|
730
|
-
const itemInline = this.inlineDocumentValue(item);
|
|
731
|
-
let lines;
|
|
732
|
-
if (itemInline !== undefined) {
|
|
733
|
-
lines = [`${itemIndent}${marker}: ${itemInline}`];
|
|
734
|
-
}
|
|
735
|
-
else if (item && typeof item === "object") {
|
|
736
|
-
const nested = this.document(item, itemDepth);
|
|
737
|
-
lines = [
|
|
738
|
-
`${itemIndent}${marker}: ${nested[0].slice(itemIndent.length)}`,
|
|
739
|
-
...nested.slice(1),
|
|
740
|
-
];
|
|
741
|
-
}
|
|
742
|
-
else {
|
|
743
|
-
lines = this.labeledScalarLines(marker, item, itemDepth);
|
|
744
|
-
}
|
|
745
|
-
if (index < value.length - 1)
|
|
746
|
-
lines[lines.length - 1] += ",";
|
|
747
|
-
return lines;
|
|
748
|
-
}),
|
|
749
|
-
`${indent}]`,
|
|
750
|
-
];
|
|
751
|
-
}
|
|
752
|
-
if (typeof value === "object") {
|
|
753
|
-
const indent = " ".repeat(depth);
|
|
754
|
-
const entries = Object.entries(value);
|
|
755
|
-
return [
|
|
756
|
-
`${indent}{`,
|
|
757
|
-
...entries.flatMap(([key, item], index) => {
|
|
758
|
-
const lines = this.labeledDocumentLines(key, item, depth + 1);
|
|
759
|
-
if (index < entries.length - 1)
|
|
760
|
-
lines[lines.length - 1] += ",";
|
|
761
|
-
return lines;
|
|
762
|
-
}),
|
|
763
|
-
`${indent}}`,
|
|
764
|
-
];
|
|
765
|
-
}
|
|
766
|
-
return String(value)
|
|
767
|
-
.split(/\r?\n/u)
|
|
768
|
-
.map((line) => `${" ".repeat(depth)}${line}`);
|
|
769
|
-
}
|
|
770
1082
|
wrapDocument(lines, width) {
|
|
771
1083
|
return lines.flatMap((line) => {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
1084
|
+
// Keep the existing terminal tab display policy; never alter the source value.
|
|
1085
|
+
const text = line.text.replaceAll("\t", " ");
|
|
1086
|
+
const label = line.label?.replaceAll("\t", " ");
|
|
1087
|
+
if (visibleWidth(text) <= width)
|
|
1088
|
+
return [{ text, label }];
|
|
1089
|
+
const leading = text.match(/^ */u)?.[0] ?? "";
|
|
1090
|
+
const hanging = label === undefined ? leading : `${leading} `;
|
|
1091
|
+
const continuation = hanging.length <= width - 2 ? hanging : "";
|
|
777
1092
|
const wrapped = [];
|
|
778
|
-
|
|
779
|
-
let
|
|
780
|
-
while (
|
|
781
|
-
const
|
|
782
|
-
const
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
wrapped.push(
|
|
1093
|
+
const columns = visibleWidth(text);
|
|
1094
|
+
let offset = 0;
|
|
1095
|
+
while (offset < columns) {
|
|
1096
|
+
const prefix = offset === 0 ? "" : continuation;
|
|
1097
|
+
const available = width - visibleWidth(prefix);
|
|
1098
|
+
// Native cell slicing keeps graphemes; retain separators instead of trimming authored spaces.
|
|
1099
|
+
let part = sliceByColumn(text, offset, available, true);
|
|
1100
|
+
const preferred = Math.max(part.lastIndexOf(" "), part.lastIndexOf("/"), part.lastIndexOf(","));
|
|
1101
|
+
if (offset + visibleWidth(part) < columns && preferred >= Math.floor(part.length * 0.6)) {
|
|
1102
|
+
part = sliceByColumn(text, offset, visibleWidth(part.slice(0, preferred + 1)), true);
|
|
1103
|
+
}
|
|
1104
|
+
const consumed = visibleWidth(part);
|
|
1105
|
+
const labelPart = label === undefined ? "" : sliceByColumn(label, offset, consumed, true);
|
|
1106
|
+
wrapped.push({ text: prefix + part, ...(labelPart ? { label: prefix + labelPart } : {}) });
|
|
1107
|
+
offset += consumed;
|
|
1108
|
+
}
|
|
792
1109
|
return wrapped;
|
|
793
1110
|
});
|
|
794
1111
|
}
|
|
795
|
-
|
|
796
|
-
const indent = line.match(/^ */u)?.[0] ?? "";
|
|
797
|
-
const content = line.slice(indent.length);
|
|
798
|
-
if (content.endsWith(":")) {
|
|
799
|
-
return `${indent}${this.theme.fg("accent", content)}`;
|
|
800
|
-
}
|
|
801
|
-
const indexed = /^(#\d+:)(.*)$/u.exec(content);
|
|
802
|
-
if (indexed) {
|
|
803
|
-
return `${indent}${this.theme.fg("accent", indexed[1])}${this.theme.fg("text", indexed[2])}`;
|
|
804
|
-
}
|
|
805
|
-
const labeled = /^([^:]+:)(.*)$/u.exec(content);
|
|
806
|
-
if (labeled) {
|
|
807
|
-
return `${indent}${this.theme.fg("muted", labeled[1])}${this.theme.fg("text", labeled[2])}`;
|
|
808
|
-
}
|
|
809
|
-
return `${indent}${this.theme.fg(content === "none" || content === "[]" ? "muted" : "text", content)}`;
|
|
810
|
-
}
|
|
811
|
-
visiblePrefix(value, width) {
|
|
812
|
-
let consumed = 0;
|
|
813
|
-
let result = "";
|
|
814
|
-
for (const character of value) {
|
|
815
|
-
const characterWidth = visibleWidth(character);
|
|
816
|
-
if (consumed + characterWidth > width)
|
|
817
|
-
break;
|
|
818
|
-
result += character;
|
|
819
|
-
consumed += characterWidth;
|
|
820
|
-
}
|
|
821
|
-
return result;
|
|
822
|
-
}
|
|
823
|
-
renderKeyHints() {
|
|
1112
|
+
keyHints(...items) {
|
|
824
1113
|
const hint = (keys, description) => `${this.theme.fg("accent", keys)}${this.theme.fg("borderAccent", ` ${description}`)}`;
|
|
825
1114
|
const divider = this.theme.fg("borderAccent", " ─ ");
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1115
|
+
return items.map(([keys, description]) => hint(keys, description)).join(divider);
|
|
1116
|
+
}
|
|
1117
|
+
renderKeyHints(killConfirmation = false) {
|
|
1118
|
+
if (killConfirmation) {
|
|
1119
|
+
return this.keyHints(["←→/tab", "choose"], ["enter", "pick"], ["y", "kill"], ["esc/n", "cancel"]);
|
|
829
1120
|
}
|
|
830
1121
|
if (this.focus === "select") {
|
|
831
|
-
return
|
|
1122
|
+
return this.keyHints(["↑↓", "option"], ["enter/→", "apply"], ["←/esc", "back"]);
|
|
832
1123
|
}
|
|
833
1124
|
if (this.focus === "detail") {
|
|
834
|
-
return
|
|
1125
|
+
return this.keyHints(["↑↓/pgup/pgdn", "scroll"], ["←/esc", "back"]);
|
|
1126
|
+
}
|
|
1127
|
+
if (this.tab === "control" && this.focus === "document") {
|
|
1128
|
+
return this.keyHints(["↑↓/pgup/pgdn", "scroll"], ["enter", "requests"], ["←/esc", "tabs"]);
|
|
1129
|
+
}
|
|
1130
|
+
if (this.tab === "control" && this.focus === "list") {
|
|
1131
|
+
return this.keyHints(["↑↓/pgup/pgdn", "row"], ["→/enter", "YAML"], ["←/esc", "tabs"]);
|
|
1132
|
+
}
|
|
1133
|
+
if (this.tab === "control" && this.focus === "tabs") {
|
|
1134
|
+
return this.keyHints(["←→", "tabs"], ["↓", "overview"], ["enter", "requests"], ["esc", "close"]);
|
|
835
1135
|
}
|
|
836
1136
|
if (this.focus === "document") {
|
|
837
|
-
return
|
|
1137
|
+
return this.keyHints(["↑↓/pgup/pgdn", "scroll"], ["↑ at top", "tabs"], ["←/esc", "tabs"]);
|
|
838
1138
|
}
|
|
839
1139
|
if (this.focus === "list") {
|
|
840
|
-
return
|
|
1140
|
+
return this.keyHints(["↑↓/pgup/pgdn", "row"], ["→/enter", "open"], ["←", "tabs"], ["esc", "close"]);
|
|
841
1141
|
}
|
|
842
1142
|
if (this.focus === "runs") {
|
|
843
1143
|
const items = [["←→", "run"], ["↓", "tabs"], ["enter", "list"]];
|
|
@@ -845,11 +1145,11 @@ export class ActorInspectorOverlay {
|
|
|
845
1145
|
if (this.killRun && run?.status === "running" && run.runInstanceId)
|
|
846
1146
|
items.push(["k", "kill"]);
|
|
847
1147
|
items.push(["esc", "close"]);
|
|
848
|
-
return
|
|
1148
|
+
return this.keyHints(...items);
|
|
849
1149
|
}
|
|
850
1150
|
return this.tab === "trace"
|
|
851
|
-
?
|
|
852
|
-
:
|
|
1151
|
+
? this.keyHints(["←→", "tabs"], ["↑↓", "focus"], ["enter/f", "source"], ["esc", "close"])
|
|
1152
|
+
: this.keyHints(["←→", "tabs"], ["↑↓", "focus"], ["enter", "open"], ["esc", "close"]);
|
|
853
1153
|
}
|
|
854
1154
|
statusColor(status) {
|
|
855
1155
|
if (status === "failed")
|