@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
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Owns portable command-template parsing, expansion, risk checks, retries, timeouts, and direct execution.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
8
|
-
import {
|
|
7
|
+
import { spawn, spawnSync, type ChildProcess } from "node:child_process";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { accessSync, appendFileSync, constants, lstatSync, mkdirSync, mkdtempSync, statSync, writeFileSync } from "node:fs";
|
|
9
10
|
import { homedir, tmpdir } from "node:os";
|
|
10
11
|
import { basename, delimiter, extname, isAbsolute, join, resolve as resolvePath } from "node:path";
|
|
11
12
|
|
|
@@ -56,6 +57,12 @@ export interface CommandTemplateInvocation {
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
export interface CommandTemplateExecOptions {
|
|
60
|
+
/** Kernel-only synchronous admission around each native spawn, including retries. */
|
|
61
|
+
admitSpawn?: (start: () => ChildProcess) => ChildProcess;
|
|
62
|
+
/** Kernel-only fresh handle after capture/exit management, inside synchronous spawn admission. Not birth proof. */
|
|
63
|
+
onAttemptManaged?: (context: CommandTemplateManagedAttempt) => void;
|
|
64
|
+
/** Kernel observation of settled attempts only; no receipt exists for a denied spawn. */
|
|
65
|
+
onAttemptComplete?: (receipt: CommandTemplateAttemptReceipt) => void;
|
|
59
66
|
cwd?: string;
|
|
60
67
|
timeout?: number;
|
|
61
68
|
signal?: AbortSignal;
|
|
@@ -77,6 +84,68 @@ export interface CommandTemplateExecResult {
|
|
|
77
84
|
stderrFile?: string;
|
|
78
85
|
stdoutTruncated?: boolean;
|
|
79
86
|
stderrTruncated?: boolean;
|
|
87
|
+
stdoutCaptureIncomplete?: true;
|
|
88
|
+
stderrCaptureIncomplete?: true;
|
|
89
|
+
stdoutFileBytes?: number;
|
|
90
|
+
stderrFileBytes?: number;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface CommandTemplateManagedAttempt {
|
|
94
|
+
readonly attempt: number;
|
|
95
|
+
readonly process: ChildProcess;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface CommandTemplateSpawnAdmission { readonly attempt: number; }
|
|
99
|
+
|
|
100
|
+
let pendingSpawnAdmission: CommandTemplateSpawnAdmission | undefined;
|
|
101
|
+
const freshManagedAttempts = new WeakMap<CommandTemplateManagedAttempt, { process: ChildProcess; pid: number | undefined; admission: CommandTemplateSpawnAdmission }>();
|
|
102
|
+
|
|
103
|
+
/** Available only before this synchronous admission invokes its factory; never retroactively adopt a born process. */
|
|
104
|
+
export function readPendingCommandSpawnAdmission(): CommandTemplateSpawnAdmission | undefined {
|
|
105
|
+
return pendingSpawnAdmission;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Kernel-only launch observation capability; copies and references retained past the callback are not authority. */
|
|
109
|
+
export function requireFreshManagedCommandAttempt(context: CommandTemplateManagedAttempt, admission?: CommandTemplateSpawnAdmission): CommandTemplateManagedAttempt {
|
|
110
|
+
const actual = freshManagedAttempts.get(context);
|
|
111
|
+
if (!actual || (admission !== undefined && actual.admission !== admission) || context.process !== actual.process || actual.process.pid !== actual.pid) {
|
|
112
|
+
throw new Error("Native process observation requires a fresh managed attempt from this runtime.");
|
|
113
|
+
}
|
|
114
|
+
return context;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface CommandTemplateAttemptReceipt {
|
|
118
|
+
readonly attempt: number;
|
|
119
|
+
/** Kernel-only digest of observed stdout bytes after complete capture persistence; not exposure/native authority. */
|
|
120
|
+
readonly stdoutSha256?: string;
|
|
121
|
+
readonly result: Readonly<CommandTemplateExecResult>;
|
|
122
|
+
readonly nativeExitCode?: number | null;
|
|
123
|
+
readonly nativeSignal?: NodeJS.Signals | null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface CommandTemplateNativeClose {
|
|
127
|
+
readonly pid: number;
|
|
128
|
+
readonly nativeExitCode: number | null;
|
|
129
|
+
readonly nativeSignal: NodeJS.Signals | null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const nativeCloseReceipts = new WeakMap<CommandTemplateAttemptReceipt, {
|
|
133
|
+
admission: CommandTemplateSpawnAdmission;
|
|
134
|
+
process: ChildProcess;
|
|
135
|
+
close: CommandTemplateNativeClose;
|
|
136
|
+
}>();
|
|
137
|
+
|
|
138
|
+
/** Exact retained process close during its synchronous receipt callback, never a serialized terminal claim. */
|
|
139
|
+
export function requireNativeCommandAttemptClose(
|
|
140
|
+
receipt: CommandTemplateAttemptReceipt,
|
|
141
|
+
admission: CommandTemplateSpawnAdmission,
|
|
142
|
+
child: ChildProcess,
|
|
143
|
+
): CommandTemplateNativeClose {
|
|
144
|
+
const actual = nativeCloseReceipts.get(receipt);
|
|
145
|
+
if (!actual || actual.admission !== admission || actual.process !== child || child.pid !== actual.close.pid) {
|
|
146
|
+
throw new Error("Native settlement requires its exact runtime-local process-close receipt.");
|
|
147
|
+
}
|
|
148
|
+
return actual.close;
|
|
80
149
|
}
|
|
81
150
|
|
|
82
151
|
export type CommandTemplateRiskLabel =
|
|
@@ -901,7 +970,7 @@ export async function execCommandTemplate(
|
|
|
901
970
|
),
|
|
902
971
|
}
|
|
903
972
|
: options;
|
|
904
|
-
const result = await execCommandTemplateOnce(command, args, attemptOptions);
|
|
973
|
+
const result = await execCommandTemplateOnce(command, args, attemptOptions, attempt);
|
|
905
974
|
if (result.code === 0) return result;
|
|
906
975
|
lastResult = result;
|
|
907
976
|
}
|
|
@@ -914,6 +983,9 @@ interface BoundedCommandCapture {
|
|
|
914
983
|
bytes: number;
|
|
915
984
|
content: string;
|
|
916
985
|
file?: string;
|
|
986
|
+
fileBytes?: number;
|
|
987
|
+
incomplete?: boolean;
|
|
988
|
+
sha256?: string;
|
|
917
989
|
truncated: boolean;
|
|
918
990
|
};
|
|
919
991
|
}
|
|
@@ -930,39 +1002,54 @@ function createBoundedCommandCapture(
|
|
|
930
1002
|
limit: number,
|
|
931
1003
|
getCaptureDir: () => string,
|
|
932
1004
|
persistCompleteStream: boolean,
|
|
1005
|
+
onFailure: (error: unknown) => void,
|
|
933
1006
|
): BoundedCommandCapture {
|
|
934
1007
|
let bytes = 0;
|
|
1008
|
+
const digest = stream === "stdout" && persistCompleteStream ? createHash("sha256") : undefined;
|
|
935
1009
|
let content: Buffer = Buffer.alloc(0);
|
|
936
1010
|
let file = persistCompleteStream
|
|
937
1011
|
? join(getCaptureDir(), `${stream}.log`)
|
|
938
1012
|
: undefined;
|
|
939
1013
|
if (file) writeFileSync(file, Buffer.alloc(0));
|
|
940
1014
|
let truncated = false;
|
|
1015
|
+
let incomplete = false;
|
|
941
1016
|
return {
|
|
942
1017
|
append(value) {
|
|
943
1018
|
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
944
1019
|
bytes += chunk.length;
|
|
1020
|
+
digest?.update(chunk);
|
|
945
1021
|
if (bytes > limit) truncated = true;
|
|
946
|
-
|
|
947
|
-
content = Buffer.concat([content, chunk]);
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
if (!file) {
|
|
951
|
-
file = join(getCaptureDir(), `${stream}.log`);
|
|
952
|
-
writeFileSync(file, content);
|
|
953
|
-
}
|
|
954
|
-
appendFileSync(file, chunk);
|
|
1022
|
+
const previous = content;
|
|
955
1023
|
content = trimCaptureTail(Buffer.concat([content, chunk]), limit);
|
|
1024
|
+
if (!file && bytes <= limit) return;
|
|
1025
|
+
if (incomplete) return;
|
|
1026
|
+
try {
|
|
1027
|
+
if (!file) {
|
|
1028
|
+
file = join(getCaptureDir(), `${stream}.log`);
|
|
1029
|
+
writeFileSync(file, previous);
|
|
1030
|
+
}
|
|
1031
|
+
appendFileSync(file, chunk);
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
incomplete = true;
|
|
1034
|
+
onFailure(error);
|
|
1035
|
+
}
|
|
956
1036
|
},
|
|
957
1037
|
result() {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1038
|
+
let retainedFile = file;
|
|
1039
|
+
let fileBytes: number | undefined;
|
|
1040
|
+
if (incomplete && file) {
|
|
1041
|
+
try {
|
|
1042
|
+
const stat = lstatSync(file);
|
|
1043
|
+
if (stat.isFile()) fileBytes = stat.size;
|
|
1044
|
+
else retainedFile = undefined;
|
|
1045
|
+
} catch { retainedFile = undefined; }
|
|
961
1046
|
}
|
|
962
1047
|
return {
|
|
963
1048
|
bytes,
|
|
964
1049
|
content: content.toString("utf8"),
|
|
965
|
-
...(
|
|
1050
|
+
...(retainedFile ? { file: retainedFile } : {}),
|
|
1051
|
+
...(digest && !incomplete && retainedFile ? { sha256: digest.digest("hex") } : {}),
|
|
1052
|
+
...(incomplete ? { incomplete: true, ...(fileBytes === undefined ? {} : { fileBytes }) } : {}),
|
|
966
1053
|
truncated,
|
|
967
1054
|
};
|
|
968
1055
|
},
|
|
@@ -972,134 +1059,196 @@ function createBoundedCommandCapture(
|
|
|
972
1059
|
function execCommandTemplateOnce(
|
|
973
1060
|
command: string,
|
|
974
1061
|
args: string[],
|
|
975
|
-
options: CommandTemplateExecOptions
|
|
1062
|
+
options: CommandTemplateExecOptions,
|
|
1063
|
+
attempt: number,
|
|
976
1064
|
): Promise<CommandTemplateExecResult> {
|
|
977
|
-
return new Promise((resolve) => {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
});
|
|
983
|
-
const
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
return;
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
children
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1065
|
+
return new Promise((resolve, reject) => {
|
|
1066
|
+
let failure: { error: unknown } | undefined;
|
|
1067
|
+
let managed: ChildProcess | undefined;
|
|
1068
|
+
let invoked = false;
|
|
1069
|
+
let admissionOpen = true;
|
|
1070
|
+
const spawnAdmission = Object.freeze({ attempt });
|
|
1071
|
+
const rememberFailure = (error: unknown): void => { failure ??= { error }; };
|
|
1072
|
+
const start = (): ChildProcess => {
|
|
1073
|
+
if (!admissionOpen) throw new Error("Native spawn admission window is closed.");
|
|
1074
|
+
if (invoked) throw new Error("Native spawn factory may be invoked only once per attempt.");
|
|
1075
|
+
invoked = true;
|
|
1076
|
+
pendingSpawnAdmission = undefined;
|
|
1077
|
+
const captureLimit = Math.max(
|
|
1078
|
+
1,
|
|
1079
|
+
options.captureLimitBytes ?? DEFAULT_COMMAND_CAPTURE_LIMIT_BYTES,
|
|
1080
|
+
);
|
|
1081
|
+
let captureDir: string | undefined;
|
|
1082
|
+
const getCaptureDir = (): string => {
|
|
1083
|
+
if (captureDir) return captureDir;
|
|
1084
|
+
captureDir = options.captureDir
|
|
1085
|
+
? resolvePath(options.captureDir)
|
|
1086
|
+
: mkdtempSync(join(tmpdir(), "pi-actors-command-"));
|
|
1087
|
+
mkdirSync(captureDir, { recursive: true });
|
|
1088
|
+
return captureDir;
|
|
1089
|
+
};
|
|
1090
|
+
const persistCompleteStreams = options.captureDir !== undefined;
|
|
1091
|
+
const stdoutCapture = createBoundedCommandCapture(
|
|
1092
|
+
"stdout",
|
|
1093
|
+
captureLimit,
|
|
1094
|
+
getCaptureDir,
|
|
1095
|
+
persistCompleteStreams,
|
|
1096
|
+
rememberFailure,
|
|
1097
|
+
);
|
|
1098
|
+
const stderrCapture = createBoundedCommandCapture(
|
|
1099
|
+
"stderr",
|
|
1100
|
+
captureLimit,
|
|
1101
|
+
getCaptureDir,
|
|
1102
|
+
persistCompleteStreams,
|
|
1103
|
+
rememberFailure,
|
|
1104
|
+
);
|
|
1105
|
+
let killed = false;
|
|
1106
|
+
let settled = false;
|
|
1107
|
+
let timeoutId: NodeJS.Timeout | undefined;
|
|
1108
|
+
let killTimeoutId: NodeJS.Timeout | undefined;
|
|
1109
|
+
const signalProcessTree = (signal: NodeJS.Signals): void => {
|
|
1110
|
+
if (proc.pid === undefined) return;
|
|
1111
|
+
if (process.platform === "win32") {
|
|
1112
|
+
spawnSync("taskkill", [
|
|
1113
|
+
"/PID",
|
|
1114
|
+
String(proc.pid),
|
|
1115
|
+
"/T",
|
|
1116
|
+
...(signal === "SIGKILL" ? ["/F"] : []),
|
|
1117
|
+
]);
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
const snapshot = spawnSync("ps", ["-eo", "pid=,ppid="], { encoding: "utf8" });
|
|
1121
|
+
const children = new Map<number, number[]>();
|
|
1122
|
+
for (const line of snapshot.stdout?.split(/\r?\n/u) ?? []) {
|
|
1123
|
+
const [pidText, parentText] = line.trim().split(/\s+/u);
|
|
1124
|
+
const pid = Number(pidText);
|
|
1125
|
+
const parent = Number(parentText);
|
|
1126
|
+
if (!Number.isSafeInteger(pid) || !Number.isSafeInteger(parent)) continue;
|
|
1127
|
+
const siblings = children.get(parent) ?? [];
|
|
1128
|
+
siblings.push(pid);
|
|
1129
|
+
children.set(parent, siblings);
|
|
1130
|
+
}
|
|
1131
|
+
const descendants: number[] = [];
|
|
1132
|
+
const collect = (parent: number): void => {
|
|
1133
|
+
for (const child of children.get(parent) ?? []) {
|
|
1134
|
+
collect(child);
|
|
1135
|
+
descendants.push(child);
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
collect(proc.pid);
|
|
1139
|
+
for (const pid of [...descendants, proc.pid]) {
|
|
1140
|
+
try {
|
|
1141
|
+
process.kill(pid, signal);
|
|
1142
|
+
} catch (error) {
|
|
1143
|
+
if ((error as NodeJS.ErrnoException).code !== "ESRCH") throw error;
|
|
1144
|
+
}
|
|
1040
1145
|
}
|
|
1041
1146
|
};
|
|
1042
|
-
|
|
1043
|
-
|
|
1147
|
+
const killProcess = (): void => {
|
|
1148
|
+
if (killed) return;
|
|
1149
|
+
killed = true;
|
|
1150
|
+
signalProcessTree("SIGTERM");
|
|
1151
|
+
killTimeoutId = setTimeout(() => {
|
|
1152
|
+
if (!settled) signalProcessTree("SIGKILL");
|
|
1153
|
+
}, options.killGrace ?? 5000);
|
|
1154
|
+
};
|
|
1155
|
+
const settle = (code: number, nativeExitCode?: number | null, nativeSignal?: NodeJS.Signals | null): void => {
|
|
1156
|
+
if (settled) return;
|
|
1157
|
+
settled = true;
|
|
1158
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1159
|
+
if (killTimeoutId) clearTimeout(killTimeoutId);
|
|
1160
|
+
if (options.signal)
|
|
1161
|
+
options.signal.removeEventListener("abort", killProcess);
|
|
1162
|
+
const stdout = stdoutCapture.result();
|
|
1163
|
+
const stderr = stderrCapture.result();
|
|
1164
|
+
const result = {
|
|
1165
|
+
stdout: stdout.content,
|
|
1166
|
+
stderr: stderr.content,
|
|
1167
|
+
code,
|
|
1168
|
+
killed,
|
|
1169
|
+
stdoutBytes: stdout.bytes,
|
|
1170
|
+
stderrBytes: stderr.bytes,
|
|
1171
|
+
...(stdout.file ? { stdoutFile: stdout.file } : {}),
|
|
1172
|
+
...(stderr.file ? { stderrFile: stderr.file } : {}),
|
|
1173
|
+
...(stdout.truncated ? { stdoutTruncated: true } : {}),
|
|
1174
|
+
...(stderr.truncated ? { stderrTruncated: true } : {}),
|
|
1175
|
+
...(stdout.incomplete ? { stdoutCaptureIncomplete: true as const, ...(stdout.fileBytes === undefined ? {} : { stdoutFileBytes: stdout.fileBytes }) } : {}),
|
|
1176
|
+
...(stderr.incomplete ? { stderrCaptureIncomplete: true as const, ...(stderr.fileBytes === undefined ? {} : { stderrFileBytes: stderr.fileBytes }) } : {}),
|
|
1177
|
+
};
|
|
1044
1178
|
try {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1179
|
+
if (options.onAttemptComplete) {
|
|
1180
|
+
const receipt = Object.freeze({
|
|
1181
|
+
attempt, result: Object.freeze({ ...result }),
|
|
1182
|
+
...(stdout.sha256 ? { stdoutSha256: stdout.sha256 } : {}),
|
|
1183
|
+
...(nativeExitCode !== undefined ? { nativeExitCode } : {}),
|
|
1184
|
+
...(nativeSignal !== undefined ? { nativeSignal } : {}),
|
|
1185
|
+
});
|
|
1186
|
+
const exitObserved = (Number.isSafeInteger(nativeExitCode) && nativeSignal === null) ||
|
|
1187
|
+
(nativeExitCode === null && typeof nativeSignal === "string" && /^SIG[A-Z0-9]+$/.exec(nativeSignal)?.[0] === nativeSignal);
|
|
1188
|
+
if (exitObserved && Number.isSafeInteger(proc.pid) && Number(proc.pid) > 0 &&
|
|
1189
|
+
proc.exitCode === nativeExitCode && proc.signalCode === nativeSignal) {
|
|
1190
|
+
nativeCloseReceipts.set(receipt, {
|
|
1191
|
+
admission: spawnAdmission, process: proc,
|
|
1192
|
+
close: Object.freeze({ pid: proc.pid!, nativeExitCode: nativeExitCode!, nativeSignal: nativeSignal! }),
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
try { options.onAttemptComplete(receipt); }
|
|
1196
|
+
finally { nativeCloseReceipts.delete(receipt); }
|
|
1197
|
+
}
|
|
1198
|
+
} catch (error) { rememberFailure(error); }
|
|
1199
|
+
if (failure) reject(failure.error);
|
|
1200
|
+
else resolve(result);
|
|
1201
|
+
};
|
|
1202
|
+
const proc = spawn(command, args, {
|
|
1203
|
+
cwd: options.cwd,
|
|
1204
|
+
shell: false,
|
|
1205
|
+
stdio: [options.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
1206
|
+
});
|
|
1207
|
+
proc.stdout?.on("data", (data: Buffer) => {
|
|
1208
|
+
stdoutCapture.append(data);
|
|
1209
|
+
});
|
|
1210
|
+
proc.stderr?.on("data", (data: Buffer) => {
|
|
1211
|
+
stderrCapture.append(data);
|
|
1212
|
+
});
|
|
1213
|
+
proc.stdin?.on("error", () => {});
|
|
1214
|
+
proc.on("error", (error) => {
|
|
1215
|
+
const liveHandle = Number.isSafeInteger(proc.pid) && Number(proc.pid) > 0;
|
|
1216
|
+
if (liveHandle) rememberFailure(error);
|
|
1217
|
+
stderrCapture.append(error instanceof Error ? error.message : String(error));
|
|
1218
|
+
if (!liveHandle) settle(1);
|
|
1079
1219
|
});
|
|
1220
|
+
proc.on("close", (code, signal) => {
|
|
1221
|
+
settle(code ?? 1, code, signal);
|
|
1222
|
+
});
|
|
1223
|
+
managed = proc;
|
|
1224
|
+
try {
|
|
1225
|
+
if (options.signal) {
|
|
1226
|
+
if (options.signal.aborted) killProcess();
|
|
1227
|
+
else
|
|
1228
|
+
options.signal.addEventListener("abort", killProcess, { once: true });
|
|
1229
|
+
}
|
|
1230
|
+
if (options.timeout !== undefined && options.timeout > 0)
|
|
1231
|
+
timeoutId = setTimeout(killProcess, options.timeout);
|
|
1232
|
+
if (options.stdin !== undefined) proc.stdin?.end(options.stdin);
|
|
1233
|
+
if (options.onAttemptManaged) {
|
|
1234
|
+
const context = Object.freeze({ attempt, process: proc });
|
|
1235
|
+
freshManagedAttempts.set(context, { process: proc, pid: proc.pid, admission: spawnAdmission });
|
|
1236
|
+
try { options.onAttemptManaged(context); }
|
|
1237
|
+
finally { freshManagedAttempts.delete(context); }
|
|
1238
|
+
}
|
|
1239
|
+
} catch (error) { rememberFailure(error); }
|
|
1240
|
+
return proc;
|
|
1080
1241
|
};
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
}
|
|
1091
|
-
proc.stderr?.on("data", (data: Buffer) => {
|
|
1092
|
-
stderrCapture.append(data);
|
|
1093
|
-
});
|
|
1094
|
-
proc.stdin?.on("error", () => {});
|
|
1095
|
-
if (options.stdin !== undefined) proc.stdin?.end(options.stdin);
|
|
1096
|
-
proc.on("error", (error) => {
|
|
1097
|
-
stderrCapture.append(error instanceof Error ? error.message : String(error));
|
|
1098
|
-
settle(1);
|
|
1099
|
-
});
|
|
1100
|
-
proc.on("close", (code) => {
|
|
1101
|
-
settle(code ?? (killed ? 1 : 0));
|
|
1102
|
-
});
|
|
1242
|
+
const parentAdmission = pendingSpawnAdmission;
|
|
1243
|
+
try {
|
|
1244
|
+
pendingSpawnAdmission = spawnAdmission;
|
|
1245
|
+
const proc = options.admitSpawn ? options.admitSpawn(start) : start();
|
|
1246
|
+
if (!managed) throw new Error("Native spawn admission must invoke its managed factory.");
|
|
1247
|
+
if (proc !== managed) throw new Error("Native spawn admission must return its managed process.");
|
|
1248
|
+
} catch (error) {
|
|
1249
|
+
if (managed) rememberFailure(error);
|
|
1250
|
+
else reject(error);
|
|
1251
|
+
} finally { admissionOpen = false; pendingSpawnAdmission = parentAdmission; }
|
|
1103
1252
|
});
|
|
1104
1253
|
}
|
|
1105
1254
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution-file layout and metadata observation beneath a caller-admitted Run state root.
|
|
3
|
+
* Owns: capture/session/canonical-runner stream layout, metadata and bounded strict text inputs through a checked descriptor.
|
|
4
|
+
* Excludes: Run/generation admission, unrestricted body exposure, discovery, privacy projection, historical-content or native authority.
|
|
5
|
+
*/
|
|
6
|
+
import { closeSync, constants, fstatSync, lstatSync, openSync, readSync, realpathSync, type BigIntStats } from "node:fs";
|
|
7
|
+
import { isAbsolute, join, resolve, win32 } from "node:path";
|
|
8
|
+
import { SESSION_EVIDENCE_MAX_BYTES } from "./limits.ts";
|
|
9
|
+
|
|
10
|
+
export type ExecutionFileReferenceReading =
|
|
11
|
+
| { readonly availability: "available"; readonly path: string; readonly local_path: string;
|
|
12
|
+
readonly bytes_total: number; readonly mutable: true; readonly unchanged: () => boolean }
|
|
13
|
+
| { readonly availability: "unavailable"; readonly reason: "invalid_reference" | "reference_missing" |
|
|
14
|
+
"reference_unavailable" | "reference_changed" | "reference_size_unrepresentable" };
|
|
15
|
+
export const RUN_STREAM_SOURCE_MAX_BYTES = 4 * 1024 * 1024;
|
|
16
|
+
export type ExecutionTextReading =
|
|
17
|
+
| { readonly availability: "available"; readonly reference: Extract<ExecutionFileReferenceReading, { availability: "available" }>; readonly text: string }
|
|
18
|
+
| { readonly availability: "unavailable"; readonly reason: Extract<ExecutionFileReferenceReading, { availability: "unavailable" }>["reason"] |
|
|
19
|
+
"reference_too_large" | "reference_invalid_text" };
|
|
20
|
+
type Unavailable = Extract<ExecutionFileReferenceReading, { availability: "unavailable" }>;
|
|
21
|
+
function unavailable(reason: Unavailable["reason"]): Readonly<Unavailable> { return Object.freeze({ availability: "unavailable", reason }); }
|
|
22
|
+
function sameObject(left: BigIntStats, right: BigIntStats): boolean { return left.dev === right.dev && left.ino === right.ino; }
|
|
23
|
+
function sameFile(left: BigIntStats, right: BigIntStats): boolean {
|
|
24
|
+
return right.isFile() && sameObject(left, right) && left.size === right.size && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs;
|
|
25
|
+
}
|
|
26
|
+
function referencePath(request: unknown): string | undefined {
|
|
27
|
+
if (!request || typeof request !== "object" || Array.isArray(request)) return undefined;
|
|
28
|
+
const kind = Object.getOwnPropertyDescriptor(request, "kind")?.value;
|
|
29
|
+
const path = Object.getOwnPropertyDescriptor(request, "path")?.value;
|
|
30
|
+
if ((kind !== "session" && kind !== "capture" && kind !== "runner_stream") || typeof path !== "string" || !path || isAbsolute(path) || win32.isAbsolute(path) ||
|
|
31
|
+
/[\\\u0000-\u001f\u007f]/u.test(path) || (process.platform === "win32" && path.includes(":"))) return undefined;
|
|
32
|
+
const parts = path.split("/");
|
|
33
|
+
if (parts.some(part => !part || part === "." || part === "..")) return undefined;
|
|
34
|
+
if (kind === "runner_stream") return path === "stdout.log" || path === "stderr.log" ? path : undefined;
|
|
35
|
+
if (kind === "session") return parts[0] === "sessions" && parts.length >= 2 && parts.at(-1)!.endsWith(".jsonl") ? path : undefined;
|
|
36
|
+
const capture = /^captures\/command-([0-9]{3,})\/attempt-([0-9]{3,})\/(stdout|stderr)\.log$/u.exec(path);
|
|
37
|
+
return capture && capture.slice(1, 3).every(number => Number.isSafeInteger(Number(number)) && Number(number) > 0) ? path : undefined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function inspectExecutionFile(stateDir: string, request: unknown): Readonly<ExecutionFileReferenceReading>;
|
|
41
|
+
function inspectExecutionFile(stateDir: string, request: unknown, maxTextBytes: number): Readonly<ExecutionTextReading>;
|
|
42
|
+
function inspectExecutionFile(stateDir: string, request: unknown, maxTextBytes?: number): Readonly<ExecutionFileReferenceReading | ExecutionTextReading> {
|
|
43
|
+
const relative = referencePath(request);
|
|
44
|
+
if (!relative) return unavailable("invalid_reference");
|
|
45
|
+
try {
|
|
46
|
+
const requestedRoot = resolve(stateDir);
|
|
47
|
+
const root = lstatSync(requestedRoot, { bigint: true });
|
|
48
|
+
if (!root.isDirectory() || root.isSymbolicLink()) return unavailable("reference_unavailable");
|
|
49
|
+
const canonicalRoot = realpathSync(requestedRoot);
|
|
50
|
+
const canonical = lstatSync(canonicalRoot, { bigint: true });
|
|
51
|
+
if (!canonical.isDirectory() || !sameObject(root, canonical)) return unavailable("reference_changed");
|
|
52
|
+
const directories = [{ path: requestedRoot, stamp: root }, { path: canonicalRoot, stamp: canonical }];
|
|
53
|
+
const parts = relative.split("/");
|
|
54
|
+
let directory = canonicalRoot;
|
|
55
|
+
for (const part of parts.slice(0, -1)) {
|
|
56
|
+
directory = join(directory, part);
|
|
57
|
+
const stamp = lstatSync(directory, { bigint: true });
|
|
58
|
+
if (!stamp.isDirectory() || stamp.isSymbolicLink()) return unavailable("reference_unavailable");
|
|
59
|
+
directories.push({ path: directory, stamp });
|
|
60
|
+
}
|
|
61
|
+
const path = join(canonicalRoot, ...parts);
|
|
62
|
+
const before = lstatSync(path, { bigint: true });
|
|
63
|
+
if (!before.isFile()) return unavailable("reference_unavailable");
|
|
64
|
+
if (before.size < 0n || before.size > BigInt(Number.MAX_SAFE_INTEGER)) return unavailable("reference_size_unrepresentable");
|
|
65
|
+
if (maxTextBytes !== undefined && before.size > BigInt(maxTextBytes)) return Object.freeze({ availability: "unavailable", reason: "reference_too_large" });
|
|
66
|
+
// Nonblocking/nofollow flags avoid waiting on a leaf replaced with a FIFO or following a leaf alias when supported.
|
|
67
|
+
const fd = openSync(path, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
|
|
68
|
+
try {
|
|
69
|
+
const opened = fstatSync(fd, { bigint: true });
|
|
70
|
+
if (!sameFile(before, opened)) return unavailable("reference_changed");
|
|
71
|
+
const unchanged = (): boolean => {
|
|
72
|
+
try {
|
|
73
|
+
return directories.every(directory => {
|
|
74
|
+
const current = lstatSync(directory.path, { bigint: true });
|
|
75
|
+
return current.isDirectory() && sameObject(directory.stamp, current);
|
|
76
|
+
}) && sameFile(opened, lstatSync(path, { bigint: true }));
|
|
77
|
+
} catch { return false; }
|
|
78
|
+
};
|
|
79
|
+
let text: string | undefined;
|
|
80
|
+
if (maxTextBytes !== undefined) {
|
|
81
|
+
const bytes = Buffer.alloc(Number(opened.size)); let offset = 0;
|
|
82
|
+
while (offset < bytes.length) {
|
|
83
|
+
const count = readSync(fd, bytes, offset, bytes.length - offset, offset);
|
|
84
|
+
if (!count) return unavailable("reference_changed");
|
|
85
|
+
offset += count;
|
|
86
|
+
}
|
|
87
|
+
try { text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: !relative.startsWith("sessions/") }).decode(bytes); }
|
|
88
|
+
catch { return Object.freeze({ availability: "unavailable", reason: "reference_invalid_text" }); }
|
|
89
|
+
}
|
|
90
|
+
if (!sameFile(opened, fstatSync(fd, { bigint: true })) || !unchanged()) return unavailable("reference_changed");
|
|
91
|
+
const reference = Object.freeze({ availability: "available" as const, path: relative, local_path: path, bytes_total: Number(opened.size), mutable: true as const, unchanged });
|
|
92
|
+
return text === undefined ? reference : Object.freeze({ availability: "available", reference, text });
|
|
93
|
+
} finally { closeSync(fd); }
|
|
94
|
+
} catch (error) {
|
|
95
|
+
return unavailable((error as NodeJS.ErrnoException).code === "ENOENT" ? "reference_missing" : "reference_unavailable");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Metadata-only: never reads body bytes, regardless of file size. */
|
|
100
|
+
export function observeExecutionFileReference(stateDir: string, request: unknown): Readonly<ExecutionFileReferenceReading> {
|
|
101
|
+
return inspectExecutionFile(stateDir, request);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Raw text is kernel-local input to an authorized projection, never a tool/model result. */
|
|
105
|
+
export function readExecutionSessionText(stateDir: string, path: string): Readonly<ExecutionTextReading> {
|
|
106
|
+
return inspectExecutionFile(stateDir, { kind: "session", path }, SESSION_EVIDENCE_MAX_BYTES);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Explicit command capture input only; neither this read nor its path authorizes publication. */
|
|
110
|
+
export function readExecutionCaptureText(stateDir: string, path: string): Readonly<ExecutionTextReading> {
|
|
111
|
+
return inspectExecutionFile(stateDir, { kind: "capture", path }, RUN_STREAM_SOURCE_MAX_BYTES);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Canonical runner text is kernel-local input, not complete command capture or a model-visible privacy projection. */
|
|
115
|
+
export function readExecutionRunnerStreamText(stateDir: string, stream: unknown): Readonly<ExecutionTextReading> {
|
|
116
|
+
if (stream !== "stdout" && stream !== "stderr") return unavailable("invalid_reference");
|
|
117
|
+
return inspectExecutionFile(stateDir, { kind: "runner_stream", path: `${stream}.log` }, RUN_STREAM_SOURCE_MAX_BYTES);
|
|
118
|
+
}
|
|
@@ -50,10 +50,10 @@ export function byteLength(value: string): number {
|
|
|
50
50
|
export function trimToTailBytes(value: string, maxBytes: number): string {
|
|
51
51
|
const buffer = Buffer.from(value, "utf8");
|
|
52
52
|
if (buffer.length <= maxBytes) return value;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
let start = Math.ceil(buffer.length - maxBytes);
|
|
54
|
+
// Skip only the cut code point's continuation bytes, not genuine U+FFFD text.
|
|
55
|
+
while (start < buffer.length && (buffer[start] & 0xc0) === 0x80) start++;
|
|
56
|
+
return buffer.subarray(start).toString("utf8");
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export function truncateTailContent(content: string): {
|