@nhtio/adk 0.1.0-master-e6c58205 → 0.1.0-master-89b47bec
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 +94 -0
- package/__vite-browser-external-CU7uua8b.mjs +9 -0
- package/__vite-browser-external-CU7uua8b.mjs.map +1 -0
- package/__vite-browser-external-DAHxjh-D.js +13 -0
- package/__vite-browser-external-DAHxjh-D.js.map +1 -0
- package/batteries/embeddings/openai/adapter.cjs +1 -1
- package/batteries/embeddings/openai/adapter.mjs +1 -1
- package/batteries/embeddings/webllm/adapter.cjs +1 -1
- package/batteries/embeddings/webllm/adapter.mjs +1 -1
- package/batteries/llm/ollama/adapter.cjs +5 -5
- package/batteries/llm/ollama/adapter.mjs +5 -5
- package/batteries/llm/ollama/helpers.cjs +2 -2
- package/batteries/llm/ollama/helpers.mjs +2 -2
- package/batteries/llm/ollama/validation.cjs +1 -1
- package/batteries/llm/ollama/validation.mjs +1 -1
- package/batteries/llm/openai_chat_completions/adapter.cjs +5 -5
- package/batteries/llm/openai_chat_completions/adapter.mjs +5 -5
- package/batteries/llm/openai_chat_completions/helpers.cjs +2 -2
- package/batteries/llm/openai_chat_completions/helpers.mjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +5 -5
- package/batteries/llm/webllm_chat_completions/adapter.mjs +5 -5
- package/batteries/llm/webllm_chat_completions/validation.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +1 -1
- package/batteries/media/contracts.cjs +38 -8
- package/batteries/media/contracts.cjs.map +1 -1
- package/batteries/media/contracts.d.ts +86 -6
- package/batteries/media/contracts.mjs +37 -9
- package/batteries/media/contracts.mjs.map +1 -1
- package/batteries/media/engines/audio_decode.cjs +46 -6
- package/batteries/media/engines/audio_decode.cjs.map +1 -1
- package/batteries/media/engines/audio_decode.d.ts +9 -5
- package/batteries/media/engines/audio_decode.mjs +47 -7
- package/batteries/media/engines/audio_decode.mjs.map +1 -1
- package/batteries/media/engines/data.cjs +159 -0
- package/batteries/media/engines/data.cjs.map +1 -0
- package/batteries/media/engines/data.d.ts +36 -0
- package/batteries/media/engines/data.mjs +157 -0
- package/batteries/media/engines/data.mjs.map +1 -0
- package/batteries/media/engines/exceljs.cjs +290 -0
- package/batteries/media/engines/exceljs.cjs.map +1 -0
- package/batteries/media/engines/exceljs.d.ts +41 -0
- package/batteries/media/engines/exceljs.mjs +288 -0
- package/batteries/media/engines/exceljs.mjs.map +1 -0
- package/batteries/media/engines/execa_executor.cjs +1 -1
- package/batteries/media/engines/execa_executor.mjs +1 -1
- package/batteries/media/engines/fs_workspace.cjs +1 -1
- package/batteries/media/engines/fs_workspace.mjs +1 -1
- package/batteries/media/engines/jimp.cjs +24 -2
- package/batteries/media/engines/jimp.cjs.map +1 -1
- package/batteries/media/engines/jimp.d.ts +3 -1
- package/batteries/media/engines/jimp.mjs +24 -2
- package/batteries/media/engines/jimp.mjs.map +1 -1
- package/batteries/media/engines/sharp.cjs +37 -4
- package/batteries/media/engines/sharp.cjs.map +1 -1
- package/batteries/media/engines/sharp.d.ts +5 -3
- package/batteries/media/engines/sharp.mjs +37 -4
- package/batteries/media/engines/sharp.mjs.map +1 -1
- package/batteries/media/engines/sheetjs.cjs +438 -0
- package/batteries/media/engines/sheetjs.cjs.map +1 -0
- package/batteries/media/engines/sheetjs.d.ts +51 -0
- package/batteries/media/engines/sheetjs.mjs +436 -0
- package/batteries/media/engines/sheetjs.mjs.map +1 -0
- package/batteries/media/engines/soffice.cjs +37 -3
- package/batteries/media/engines/soffice.cjs.map +1 -1
- package/batteries/media/engines/soffice.mjs +38 -4
- package/batteries/media/engines/soffice.mjs.map +1 -1
- package/batteries/media/engines/tesseract_js.cjs +1 -1
- package/batteries/media/engines/tesseract_js.mjs +1 -1
- package/batteries/media/engines/transformers_asr.cjs +1 -1
- package/batteries/media/engines/transformers_asr.mjs +1 -1
- package/batteries/media/forge.cjs +89 -20
- package/batteries/media/forge.cjs.map +1 -1
- package/batteries/media/forge.mjs +89 -20
- package/batteries/media/forge.mjs.map +1 -1
- package/batteries/media/formats.d.ts +9 -0
- package/batteries/media/index.d.ts +8 -6
- package/batteries/media/lint.cjs +270 -58
- package/batteries/media/lint.cjs.map +1 -1
- package/batteries/media/lint.d.ts +45 -0
- package/batteries/media/lint.mjs +267 -58
- package/batteries/media/lint.mjs.map +1 -1
- package/batteries/media/registry.d.ts +11 -2
- package/batteries/media/steps/data.d.ts +26 -0
- package/batteries/media/steps/doc.d.ts +17 -7
- package/batteries/media/steps/patch.d.ts +90 -0
- package/batteries/media/steps/sheet.d.ts +10 -6
- package/batteries/media/steps/text.d.ts +4 -1
- package/batteries/media/validate.d.ts +5 -0
- package/batteries/media/verbs.d.ts +12 -1
- package/batteries/media.cjs +869 -448
- package/batteries/media.cjs.map +1 -1
- package/batteries/media.mjs +829 -409
- package/batteries/media.mjs.map +1 -1
- package/batteries/storage/flydrive.cjs +3 -6
- package/batteries/storage/flydrive.cjs.map +1 -1
- package/batteries/storage/flydrive.mjs +3 -6
- package/batteries/storage/flydrive.mjs.map +1 -1
- package/batteries/storage/in_memory.cjs +1 -1
- package/batteries/storage/in_memory.mjs +1 -1
- package/batteries/storage/opfs.cjs +1 -1
- package/batteries/storage/opfs.mjs +1 -1
- package/batteries/tools/_shared.cjs +2 -2
- package/batteries/tools/_shared.mjs +2 -2
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +3 -3
- package/batteries/tools/comparison.mjs +3 -3
- package/batteries/tools/data_structure.cjs +3 -3
- package/batteries/tools/data_structure.mjs +3 -3
- package/batteries/tools/datetime_extended.cjs +3 -3
- package/batteries/tools/datetime_extended.mjs +3 -3
- package/batteries/tools/datetime_math.cjs +3 -3
- package/batteries/tools/datetime_math.mjs +3 -3
- package/batteries/tools/encoding.cjs +3 -3
- package/batteries/tools/encoding.mjs +3 -3
- package/batteries/tools/formatting.cjs +3 -3
- package/batteries/tools/formatting.mjs +3 -3
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +3 -3
- package/batteries/tools/math.mjs +3 -3
- package/batteries/tools/memory.cjs +6 -6
- package/batteries/tools/memory.mjs +6 -6
- package/batteries/tools/parsing.cjs +4 -4
- package/batteries/tools/parsing.mjs +4 -4
- package/batteries/tools/retrievables.cjs +5 -5
- package/batteries/tools/retrievables.mjs +5 -5
- package/batteries/tools/scrapper.cjs +1 -1
- package/batteries/tools/scrapper.mjs +1 -1
- package/batteries/tools/searxng.cjs +1 -1
- package/batteries/tools/searxng.mjs +1 -1
- package/batteries/tools/standing_instructions.cjs +4 -4
- package/batteries/tools/standing_instructions.mjs +4 -4
- package/batteries/tools/statistics.cjs +4 -4
- package/batteries/tools/statistics.mjs +4 -4
- package/batteries/tools/string_processing.cjs +3 -3
- package/batteries/tools/string_processing.mjs +3 -3
- package/batteries/tools/structured_data.cjs +3 -3
- package/batteries/tools/structured_data.mjs +3 -3
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +3 -3
- package/batteries/tools/time.mjs +3 -3
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/tools/web_retrieval.cjs +1 -1
- package/batteries/tools/web_retrieval.mjs +1 -1
- package/batteries/tools.cjs +2 -2
- package/batteries/tools.mjs +2 -2
- package/batteries/vector/arangodb.cjs +1 -1
- package/batteries/vector/arangodb.mjs +1 -1
- package/batteries/vector/clickhouse.cjs +1 -1
- package/batteries/vector/clickhouse.mjs +1 -1
- package/batteries/vector/cloudflare.cjs +1 -1
- package/batteries/vector/cloudflare.mjs +1 -1
- package/batteries/vector/couchbase.cjs +1 -1
- package/batteries/vector/couchbase.mjs +1 -1
- package/batteries/vector/duckdb.cjs +1 -1
- package/batteries/vector/duckdb.mjs +1 -1
- package/batteries/vector/elasticsearch.cjs +1 -1
- package/batteries/vector/elasticsearch.mjs +1 -1
- package/batteries/vector/filters.cjs +1 -1
- package/batteries/vector/filters.mjs +1 -1
- package/batteries/vector/hnswlib.cjs +1 -1
- package/batteries/vector/hnswlib.mjs +1 -1
- package/batteries/vector/lancedb.cjs +1 -1
- package/batteries/vector/lancedb.mjs +1 -1
- package/batteries/vector/mariadb.cjs +1 -1
- package/batteries/vector/mariadb.mjs +1 -1
- package/batteries/vector/meilisearch.cjs +1 -1
- package/batteries/vector/meilisearch.mjs +1 -1
- package/batteries/vector/migrate.cjs +1 -1
- package/batteries/vector/migrate.mjs +1 -1
- package/batteries/vector/mongodb.cjs +1 -1
- package/batteries/vector/mongodb.mjs +1 -1
- package/batteries/vector/neo4j.cjs +1 -1
- package/batteries/vector/neo4j.mjs +1 -1
- package/batteries/vector/opensearch.cjs +1 -1
- package/batteries/vector/opensearch.mjs +1 -1
- package/batteries/vector/oracle23ai.cjs +1 -1
- package/batteries/vector/oracle23ai.mjs +1 -1
- package/batteries/vector/pinecone.cjs +1 -1
- package/batteries/vector/pinecone.mjs +1 -1
- package/batteries/vector/redis.cjs +1 -1
- package/batteries/vector/redis.mjs +1 -1
- package/batteries/vector/retrievable.cjs +1 -1
- package/batteries/vector/retrievable.mjs +1 -1
- package/batteries/vector/s3vectors.cjs +1 -1
- package/batteries/vector/s3vectors.mjs +1 -1
- package/batteries/vector/solr.cjs +1 -1
- package/batteries/vector/solr.mjs +1 -1
- package/batteries/vector/surrealdb.cjs +1 -1
- package/batteries/vector/surrealdb.mjs +1 -1
- package/batteries/vector/typesense.cjs +1 -1
- package/batteries/vector/typesense.mjs +1 -1
- package/batteries/vector/vespa.cjs +1 -1
- package/batteries/vector/vespa.mjs +1 -1
- package/batteries/vector/weaviate.cjs +1 -1
- package/batteries/vector/weaviate.mjs +1 -1
- package/batteries.cjs +2 -2
- package/batteries.mjs +2 -2
- package/bundled_xlsx.d.ts +1075 -0
- package/{common-BxoznqbX.mjs → common-BQoFv108.mjs} +7 -7
- package/{common-BxoznqbX.mjs.map → common-BQoFv108.mjs.map} +1 -1
- package/{common-BBK2e5ro.js → common-DmDn4Gfl.js} +7 -7
- package/{common-BBK2e5ro.js.map → common-DmDn4Gfl.js.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-Hn5idJYx.js → dispatch_runner-BwplbCPr.js} +3 -3
- package/{dispatch_runner-Hn5idJYx.js.map → dispatch_runner-BwplbCPr.js.map} +1 -1
- package/{dispatch_runner-DUrpj0xR.mjs → dispatch_runner-C1ar_D7W.mjs} +3 -3
- package/{dispatch_runner-DUrpj0xR.mjs.map → dispatch_runner-C1ar_D7W.mjs.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/eslint.cjs +1 -1
- package/eslint.mjs +1 -1
- package/forge.cjs +4 -4
- package/forge.mjs +4 -4
- package/formats-CCylUHZw.mjs +161 -0
- package/formats-CCylUHZw.mjs.map +1 -0
- package/formats-DZVuqZUN.js +196 -0
- package/formats-DZVuqZUN.js.map +1 -0
- package/guards.cjs +8 -8
- package/guards.mjs +8 -8
- package/index.cjs +11 -11
- package/index.mjs +11 -11
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +198 -182
- package/{scrapper-DLj_KkxK.mjs → scrapper-Dn2wXu0Y.mjs} +5 -5
- package/{scrapper-DLj_KkxK.mjs.map → scrapper-Dn2wXu0Y.mjs.map} +1 -1
- package/{scrapper-Cmf1CSA-.js → scrapper-mBZ0Odq7.js} +5 -5
- package/{scrapper-Cmf1CSA-.js.map → scrapper-mBZ0Odq7.js.map} +1 -1
- package/{searxng-BKs5s8Su.js → searxng-Dj-iP_Vz.js} +5 -5
- package/{searxng-BKs5s8Su.js.map → searxng-Dj-iP_Vz.js.map} +1 -1
- package/{searxng-BJ-aZcMz.mjs → searxng-DjFxtFf6.mjs} +5 -5
- package/{searxng-BJ-aZcMz.mjs.map → searxng-DjFxtFf6.mjs.map} +1 -1
- package/server.json +21 -0
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-BR0IhU9y.js → spooled_artifact-BCmPrxZS.js} +3 -3
- package/{spooled_artifact-BR0IhU9y.js.map → spooled_artifact-BCmPrxZS.js.map} +1 -1
- package/{spooled_artifact-nTE6ujM8.mjs → spooled_artifact-DL36jnqA.mjs} +3 -3
- package/{spooled_artifact-nTE6ujM8.mjs.map → spooled_artifact-DL36jnqA.mjs.map} +1 -1
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-Dj3fNowz.js → spooled_markdown_artifact-CD4PrrpV.js} +3 -3
- package/{spooled_markdown_artifact-Dj3fNowz.js.map → spooled_markdown_artifact-CD4PrrpV.js.map} +1 -1
- package/{spooled_markdown_artifact-DIYzbQv8.mjs → spooled_markdown_artifact-Da-Xnebh.mjs} +3 -3
- package/{spooled_markdown_artifact-DIYzbQv8.mjs.map → spooled_markdown_artifact-Da-Xnebh.mjs.map} +1 -1
- package/{thought-Cde2Y_GK.mjs → thought-CtOoZUSE.mjs} +3 -3
- package/{thought-Cde2Y_GK.mjs.map → thought-CtOoZUSE.mjs.map} +1 -1
- package/{thought-BFtsnUTU.js → thought-eka4iUHa.js} +3 -3
- package/{thought-BFtsnUTU.js.map → thought-eka4iUHa.js.map} +1 -1
- package/{tool-CcxYxA5X.mjs → tool-CITF20yJ.mjs} +3 -3
- package/{tool-CcxYxA5X.mjs.map → tool-CITF20yJ.mjs.map} +1 -1
- package/{tool-B2nnkwNU.js → tool-Dhjca7rC.js} +3 -3
- package/{tool-B2nnkwNU.js.map → tool-Dhjca7rC.js.map} +1 -1
- package/{tool_call-BxL3eU1k.js → tool_call-Cyi0hUUc.js} +4 -4
- package/{tool_call-BxL3eU1k.js.map → tool_call-Cyi0hUUc.js.map} +1 -1
- package/{tool_call-B3MOog2R.mjs → tool_call-D_k36aI4.mjs} +4 -4
- package/{tool_call-B3MOog2R.mjs.map → tool_call-D_k36aI4.mjs.map} +1 -1
- package/{tool_registry-BaLUIzWz.mjs → tool_registry-CZ55mIti.mjs} +152 -143
- package/tool_registry-CZ55mIti.mjs.map +1 -0
- package/{tool_registry-BdKlPuHS.js → tool_registry-DwZ6pzN4.js} +151 -142
- package/tool_registry-DwZ6pzN4.js.map +1 -0
- package/{turn_runner-M2I8G2ok.js → turn_runner-CCZcsoDU.js} +5 -5
- package/{turn_runner-M2I8G2ok.js.map → turn_runner-CCZcsoDU.js.map} +1 -1
- package/{turn_runner-BV4BaZK9.mjs → turn_runner-DRPpVvsd.mjs} +5 -5
- package/{turn_runner-BV4BaZK9.mjs.map → turn_runner-DRPpVvsd.mjs.map} +1 -1
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/{validate-JOHfh-BB.mjs → validate-C_hTnDBE.mjs} +95 -8
- package/validate-C_hTnDBE.mjs.map +1 -0
- package/{validate-DgDZkUKs.js → validate-gaSa9bsk.js} +95 -8
- package/validate-gaSa9bsk.js.map +1 -0
- package/xlsx-B0sTpEC2.js +30615 -0
- package/xlsx-B0sTpEC2.js.map +1 -0
- package/xlsx-DiMpn_Xv.mjs +30596 -0
- package/xlsx-DiMpn_Xv.mjs.map +1 -0
- package/xlsx.zahl-D2_Q-Xs4.mjs +6 -0
- package/xlsx.zahl-D2_Q-Xs4.mjs.map +1 -0
- package/xlsx.zahl-ZIcUQVv8.js +7 -0
- package/xlsx.zahl-ZIcUQVv8.js.map +1 -0
- package/tool_registry-BaLUIzWz.mjs.map +0 -1
- package/tool_registry-BdKlPuHS.js.map +0 -1
- package/validate-DgDZkUKs.js.map +0 -1
- package/validate-JOHfh-BB.mjs.map +0 -1
package/batteries/media.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.mjs","names":["#toks","#pos","#parseSegment","#peek","#next","#parseValue","#parseScalar","#ops","#exec","#with","#chain"],"sources":["../../src/batteries/media/pipe.ts","../../src/batteries/media/builder.ts","../../src/batteries/media/runtime.ts","../../src/batteries/media/formats.ts","../../src/batteries/media/steps/text.ts","../../src/batteries/media/steps/doc.ts","../../src/batteries/media/steps/sheet.ts","../../src/batteries/media/steps/slides.ts","../../src/batteries/media/steps/ingest.ts","../../src/batteries/media/registry.ts","../../src/batteries/media/steps/image_audio.ts","../../src/batteries/media/steps/pages.ts","../../src/batteries/media/index.ts"],"sourcesContent":["/**\n * The pipe-expression front-end: a moo lexer plus a hand-rolled recursive-descent parser that\n * compiles `select pages=2-5 | redact match=/…/ | convert to=pdf` into a {@link MediaPlan}.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The grammar is frozen in the\n * design doc (section 0):\n *\n * - `pipeline := segment ('|' segment)*` ; `segment := verb arg*` ; `arg := IDENT '=' value` —\n * named args only, no positionals (an IDENT followed by `=` is an arg; otherwise it is the\n * verb's second word — 2-token lookahead, no verb table needed at parse time).\n * - Verb matching is separator-insensitive (`extract_text` ≡ `extract text` ≡ `extract.text`).\n * - Values: bareword idents, ints/floats, `a-b` ranges, comma lists, `true`/`false`, quoted\n * strings (single or double), class-aware `/regex/flags` literals, `@id` media refs, and\n * quoted-JSON structured payloads (a quoted string that the verb's arg schema declares as\n * `json` is JSON-parsed).\n * - `#` line comments are tolerated (models add them; ignoring them is free robustness).\n * - Two error layers: syntactic ({@link E_MEDIA_PIPE_SYNTAX}, with line/col and a corrective\n * exemplar) and semantic ({@link E_MEDIA_UNKNOWN_VERB} etc., produced by the validator in\n * `validate.ts` — this module only parses to a raw AST and lowers to the plan).\n *\n * Parsing is deployment-independent: the full verb table drives folding, and engine narrowing\n * happens later in validation (frozen 0.3).\n */\n\nimport { foldVerb } from './verbs'\nimport { default as moo } from 'moo'\nimport { canonicalFlags } from './plan'\nimport { E_MEDIA_PIPE_SYNTAX } from './exceptions'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport type { MediaPlan, MediaStep, MediaArgValue, MediaArgScalar, SourceSpan } from './plan'\n\n// ── lexer ────────────────────────────────────────────────────────────────────\n\n/**\n * The moo ruleset. Order matters: first match wins, so `range` must precede `int`, `float`\n * precedes `int`, and `comment` precedes nothing it could shadow. String/regex bodies exclude\n * raw newlines (escape them); `ws` carries `lineBreaks` so spans stay accurate across lines.\n */\nconst lexer = moo.compile({\n ws: { match: /[ \\t\\r\\n]+/, lineBreaks: true },\n comment: /#[^\\n]*/,\n pipe: '|',\n eq: '=',\n comma: ',',\n ref: /@[A-Za-z0-9_-]+/,\n regex: /\\/(?:\\\\.|\\[(?:\\\\.|[^\\]\\\\\\n])*\\]|[^/\\\\[\\n])+\\/[a-z]*/,\n dstring: /\"(?:\\\\.|[^\"\\\\\\n])*\"/,\n sstring: /'(?:\\\\.|[^'\\\\\\n])*'/,\n range: /\\d+-\\d+/,\n float: /\\d+\\.\\d+/,\n int: /\\d+/,\n ident: /[A-Za-z_][A-Za-z0-9_.]*/,\n dash: '-',\n})\n\ninterface Tok {\n type: string\n value: string\n text: string\n offset: number\n line: number\n col: number\n}\n\n/** Tokenize, skipping ws/comments, surfacing lexer errors as syntax exceptions. */\nconst tokenize = (input: string): Tok[] => {\n lexer.reset(input)\n const out: Tok[] = []\n let tok: moo.Token | undefined\n try {\n while ((tok = lexer.next())) {\n if (tok.type === 'ws' || tok.type === 'comment') continue\n out.push({\n type: tok.type as string,\n value: tok.value,\n text: tok.text,\n offset: tok.offset,\n line: tok.line,\n col: tok.col,\n })\n }\n } catch (err) {\n const detail = isError(err) ? err.message.split('\\n')[0] : String(err)\n throw new E_MEDIA_PIPE_SYNTAX([\n `${detail}. Values containing special characters must be quoted — write it like: name=\"my-value\"`,\n ])\n }\n return out\n}\n\n// ── parser ───────────────────────────────────────────────────────────────────\n\n/** A parsed-but-unvalidated arg value, before the verb's arg schema refines it. */\nexport interface RawArgValue {\n /** The lowered value. Quoted strings stay strings here; schema may JSON-parse `json` args. */\n value: MediaArgValue\n /** Whether the source token was a quoted string (drives json-arg parsing + name/index rules). */\n quoted: boolean\n /** Source position of the value token. */\n span: SourceSpan\n}\n\n/** One parsed segment: verb words plus named args, all position-bearing. */\nexport interface RawSegment {\n /** Canonical verb id when fold-matching succeeded, else the raw folded text. */\n verb: string\n /** Whether `verb` resolved against the verb table. */\n known: boolean\n /** The parsed named args, in source order. */\n args: Map<string, RawArgValue>\n /** Source position of the verb token(s). */\n span: SourceSpan\n}\n\nconst spanOf = (tok: Tok, length?: number): SourceSpan => ({\n offset: tok.offset,\n line: tok.line,\n col: tok.col,\n length: length ?? tok.text.length,\n})\n\nconst unquote = (raw: string): string =>\n raw\n .slice(1, -1)\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([\"'\\\\/])/g, '$1')\n\nconst fail = (tok: Tok | undefined, message: string, exemplar: string): never => {\n const where = tok ? ` at line ${tok.line}, col ${tok.col}` : ' at end of input'\n throw new E_MEDIA_PIPE_SYNTAX([`${message}${where}. Write it like: ${exemplar}`])\n}\n\nclass Parser {\n #toks: Tok[]\n #pos = 0\n\n constructor(toks: Tok[]) {\n this.#toks = toks\n }\n\n #peek(ahead = 0): Tok | undefined {\n return this.#toks[this.#pos + ahead]\n }\n\n #next(): Tok | undefined {\n return this.#toks[this.#pos++]\n }\n\n parsePipeline(): RawSegment[] {\n const segments: RawSegment[] = []\n if (this.#toks.length === 0) {\n fail(undefined, 'empty pipe expression', 'extract text | chunk by=sentence')\n }\n segments.push(this.#parseSegment())\n while (this.#peek()?.type === 'pipe') {\n this.#next()\n segments.push(this.#parseSegment())\n }\n const trailing = this.#peek()\n if (trailing) {\n fail(\n trailing,\n `unexpected \"${trailing.text}\" after a complete segment`,\n 'segment | segment (segments are separated by |)'\n )\n }\n return segments\n }\n\n #parseSegment(): RawSegment {\n const first = this.#peek()\n if (!first || first.type !== 'ident') {\n fail(first, 'expected a verb to start the segment', 'convert to=pdf')\n }\n const head = this.#next() as Tok\n // Verb words: idents NOT followed by `=` (named-args-only makes this unambiguous), up to\n // the longest canonical verb (3 words, e.g. `sheet update cells`). When the greedy\n // collection over-reaches, back off to the longest prefix that fold-matches and rewind so\n // the leftover bareword surfaces as the args-must-be-named error. The fold uses the FULL\n // static verb table — deployment-independent (engine narrowing is a later validation pass).\n const collected = [head.value]\n const posAfterWord: number[] = [this.#pos]\n while (collected.length < 3) {\n const next = this.#peek()\n if (next?.type !== 'ident' || this.#peek(1)?.type === 'eq') break\n collected.push((this.#next() as Tok).value)\n posAfterWord.push(this.#pos)\n }\n let take = collected.length\n if (foldVerb(collected) === undefined) {\n // Back off to the longest prefix that folds; if none folds at any length, keep the full\n // sequence as the unknown verb so did-you-mean sees the model's whole attempt.\n let prefix = collected.length - 1\n while (prefix >= 1 && foldVerb(collected.slice(0, prefix)) === undefined) prefix -= 1\n if (prefix >= 1) take = prefix\n }\n const words = collected.slice(0, take)\n this.#pos = posAfterWord[take - 1]\n const folded = foldVerb(words)\n const verbText = words.join(' ')\n const args = new Map<string, RawArgValue>()\n for (;;) {\n const tok = this.#peek()\n if (!tok || tok.type === 'pipe') break\n if (tok.type === 'dash') {\n fail(\n tok,\n 'unexpected \"-\" — values containing dashes must be quoted',\n `${verbText} name=\"value-with-dashes\"`\n )\n }\n if (tok.type !== 'ident' || this.#peek(1)?.type !== 'eq') {\n fail(tok, `unexpected \"${tok.text}\" — args must be name=value`, `${verbText} name=value`)\n }\n const name = (this.#next() as Tok).value\n this.#next() // eq\n const value = this.#parseValue(verbText, name)\n if (args.has(name)) {\n fail(tok, `duplicate arg \"${name}\"`, `${verbText} ${name}=value (give each arg once)`)\n }\n args.set(name, value)\n }\n return {\n verb: folded ?? verbText,\n known: folded !== undefined,\n args,\n span: spanOf(head, verbText.length),\n }\n }\n\n #parseValue(verbText: string, argName: string): RawArgValue {\n const first = this.#parseScalar(verbText, argName)\n if (this.#peek()?.type !== 'comma') return first\n const items: MediaArgScalar[] = [...asScalarList(first, verbText, argName)]\n let quoted = first.quoted\n while (this.#peek()?.type === 'comma') {\n this.#next()\n const next = this.#parseScalar(verbText, argName)\n quoted = quoted || next.quoted\n items.push(...asScalarList(next, verbText, argName))\n }\n return { value: items, quoted, span: first.span }\n }\n\n #parseScalar(verbText: string, argName: string): RawArgValue {\n const tok = this.#peek()\n if (!tok) {\n fail(tok, `missing value for \"${argName}\"`, `${verbText} ${argName}=value`)\n }\n const t = tok as Tok\n switch (t.type) {\n case 'int':\n this.#next()\n return { value: Number(t.value), quoted: false, span: spanOf(t) }\n case 'float':\n this.#next()\n return { value: Number(t.value), quoted: false, span: spanOf(t) }\n case 'range': {\n this.#next()\n const [lo, hi] = t.value.split('-').map(Number)\n if (lo > hi) {\n fail(t, `range ${t.value} is descending (start must be ≤ end)`, `${argName}=${hi}-${lo}`)\n }\n const nums: number[] = []\n for (let n = lo; n <= hi; n++) nums.push(n)\n return { value: nums, quoted: false, span: spanOf(t) }\n }\n case 'ident': {\n this.#next()\n if (t.value === 'true') return { value: true, quoted: false, span: spanOf(t) }\n if (t.value === 'false') return { value: false, quoted: false, span: spanOf(t) }\n return { value: t.value, quoted: false, span: spanOf(t) }\n }\n case 'dstring':\n case 'sstring':\n this.#next()\n return { value: unquote(t.text), quoted: true, span: spanOf(t) }\n case 'regex': {\n this.#next()\n const lastSlash = t.text.lastIndexOf('/')\n const source = t.text.slice(1, lastSlash)\n const flags = canonicalFlags(t.text.slice(lastSlash + 1))\n try {\n // Validate the pattern compiles; the IR stores the serializable ref.\n void new RegExp(source, flags)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(t, `invalid regex ${t.text}: ${detail}`, `${argName}=/pattern/flags`)\n }\n return { value: { source, flags }, quoted: false, span: spanOf(t) }\n }\n case 'ref':\n this.#next()\n return {\n value: { kind: 'id', id: t.value.slice(1) },\n quoted: false,\n span: spanOf(t),\n }\n case 'dash':\n fail(\n t,\n 'unexpected \"-\" in a bare value',\n `${argName}=\"value-with-dashes\" (quote values containing dashes)`\n )\n break\n default:\n fail(t, `unexpected \"${t.text}\"`, `${verbText} ${argName}=value`)\n }\n /* unreachable */\n throw new E_MEDIA_PIPE_SYNTAX(['internal parser error'])\n }\n}\n\nconst asScalarList = (raw: RawArgValue, verbText: string, argName: string): MediaArgScalar[] => {\n if (Array.isArray(raw.value)) return raw.value as MediaArgScalar[]\n if (raw.value === null || typeof raw.value === 'object') {\n const v = raw.value as MediaArgValue\n if (isObject(v) && !Array.isArray(v) && !('source' in v) && !('kind' in v)) {\n throw new E_MEDIA_PIPE_SYNTAX([\n `structured values cannot appear in a comma list for \"${argName}\" on \"${verbText}\"`,\n ])\n }\n }\n return [raw.value as MediaArgScalar]\n}\n\n// ── public surface ───────────────────────────────────────────────────────────\n\n/**\n * Parse a pipe expression into raw, position-bearing segments.\n *\n * @remarks\n * Purely syntactic — verbs are fold-matched against the full verb table for canonicalization\n * but unknown verbs are NOT an error here (the validator reports them with did-you-mean and the\n * deployment's narrowed verb list). Pair with `validateSegments` for the validated path.\n *\n * @param input - The pipe expression.\n * @returns The raw segments.\n */\nexport const parsePipeRaw = (input: string): RawSegment[] => {\n return new Parser(tokenize(input)).parsePipeline()\n}\n\n/**\n * Lower raw segments to an (unvalidated) {@link MediaPlan}. Quoted-JSON arg parsing and\n * type/enum checks happen in the validator, which consumes the raw segments — this lowering\n * exists for tooling that wants the structural plan without validation.\n *\n * @param segments - Output of {@link parsePipeRaw}.\n * @returns The structural plan (args carried as parsed, json args still strings).\n */\nexport const lowerSegments = (segments: RawSegment[]): MediaPlan => ({\n steps: segments.map(\n (seg): MediaStep => ({\n verb: seg.verb,\n args: Object.fromEntries(Array.from(seg.args.entries(), ([k, v]) => [k, v.value])),\n span: seg.span,\n })\n ),\n})\n","/**\n * The chainable, thenable media builder — the implementor-facing front-end that compiles to\n * the same {@link MediaPlan} as the pipe string and JSON ops.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The knex lessons applied:\n * `mp(input)` opens a fresh immutable builder; every verb returns a new builder; awaiting the\n * builder executes the chain (no `.execute()`). Domain verbs hang off typed namespaces\n * (`.sheet`, `.slides`, `.image`, `.audio`); shared transforms live on the root.\n *\n * Each verb method appends an op and revalidates lazily — the full plan validates (verb table,\n * arg schemas, engine narrowing) when the chain executes, so building is cheap and the same\n * validator serves all three front-ends.\n */\n\nimport { toPipe } from './plan'\nimport type { PlanResult, StepPayload } from './runtime'\nimport type { MediaPlan, MediaOp, MediaArgValue, MediaArgJson, MediaRef } from './plan'\n\n/** The function a builder calls to execute its accumulated ops. Bound by the pipeline. */\nexport type ChainExecutor = (ops: MediaOp[]) => Promise<PlanResult>\n\n/** Options accepted by image resize. */\nexport interface ResizeOptions {\n /** Target width in pixels. */\n width?: number\n /** Target height in pixels. */\n height?: number\n /** Resize fit mode (default cover). */\n fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside'\n}\n\n/** A cell update for `sheet.updateCells`. */\nexport interface CellUpdate {\n /** A1-notation address, e.g. `B2`. Alternative to row/col. */\n address?: string\n /** One-based row index. Pair with `col`. */\n row?: number\n /** One-based column index, or a column letter. Pair with `row`. */\n col?: number | string\n /** The value to set. A leading `=` writes a formula. */\n value: string | number | boolean | null\n}\n\nconst refOf = (other: MediaChainRef): MediaRef =>\n typeof other === 'string' ? { kind: 'id', id: other } : { kind: 'id', id: other.mediaId }\n\n/** How other media are referenced from builder verbs: an id string or `{ mediaId }`. */\nexport type MediaChainRef = string | { mediaId: string }\n\n/**\n * The chainable builder. Immutable — every verb returns a new instance sharing the executor.\n * Thenable — `await` runs the chain and resolves to the terminal step's natural type.\n */\nexport class MediaChain implements PromiseLike<unknown> {\n readonly #ops: MediaOp[]\n readonly #exec: ChainExecutor\n\n constructor(exec: ChainExecutor, ops: MediaOp[] = []) {\n this.#exec = exec\n this.#ops = ops\n }\n\n #with(verb: string, args: Record<string, MediaArgValue>): MediaChain {\n return new MediaChain(this.#exec, [...this.#ops, { verb, args }])\n }\n\n // ── root transforms ─────────────────────────────────────────────────────────\n\n /** Convert to another format (requires a convert engine). */\n convert(to: string): MediaChain {\n return this.#with('convert', { to })\n }\n\n /** Keep only the listed 1-based pages. */\n select(options: { pages: number[] }): MediaChain {\n return this.#with('select', { pages: options.pages })\n }\n\n /** Split by page (optionally grouped `[[start,end], …]`). Terminal: resolves to media list. */\n split(options: { by?: 'page' | 'section'; ranges?: number[][] } = {}): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.by) args.by = options.by\n if (options.ranges) args.ranges = options.ranges as MediaArgJson\n return this.#with('split', args)\n }\n\n /** Merge other media into this one, in order. */\n merge(...others: MediaChainRef[]): MediaChain {\n return this.#with('merge', { with: others.map(refOf) })\n }\n\n /** Reorder pages by 1-based index. */\n reorder(order: number[]): MediaChain {\n return this.#with('reorder', { order })\n }\n\n /** Redact matching text (literals or RegExp). */\n redact(options: {\n match: Array<string | RegExp> | string | RegExp\n replace?: string\n }): MediaChain {\n const list = Array.isArray(options.match) ? options.match : [options.match]\n const match = list.map((m) =>\n typeof m === 'string' ? m : { source: m.source, flags: Array.from(m.flags).sort().join('') }\n )\n const args: Record<string, MediaArgValue> = { match }\n if (options.replace !== undefined) args.replace = options.replace\n return this.#with('redact', args)\n }\n\n /** Remove potentially unsafe embedded content. */\n sanitize(): MediaChain {\n return this.#with('sanitize', {})\n }\n\n /** Normalize structure/encoding. */\n normalize(): MediaChain {\n return this.#with('normalize', {})\n }\n\n /** Replace the first occurrence of anchor text. */\n updateText(anchor: string, replace: string): MediaChain {\n return this.#with('update_text', { anchor, replace })\n }\n\n /** Compare against another media. Terminal: resolves to a structured diff. */\n diff(other: MediaChainRef): MediaChain {\n return this.#with('diff', { with: refOf(other) })\n }\n\n /** Apply a unified-diff patch. */\n applyPatch(patch: string, options: { with?: MediaChainRef[] } = {}): MediaChain {\n const args: Record<string, MediaArgValue> = { patch }\n if (options.with) args.with = options.with.map(refOf)\n return this.#with('apply_patch', args)\n }\n\n /** Extract text (routes by format; OCR engine used when needed). Terminal: resolves to text. */\n extractText(\n options: {\n ocr?: 'off' | 'auto' | 'force'\n ocrOut?: 'txt' | 'hocr' | 'json'\n lang?: string[]\n } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.ocr) args.ocr = options.ocr\n if (options.ocrOut) args.ocr_out = options.ocrOut\n if (options.lang) args.lang = options.lang\n return this.#with('extract.text', args)\n }\n\n /** Extract metadata. Terminal: resolves to a metadata object. */\n extractMetadata(): MediaChain {\n return this.#with('extract.metadata', {})\n }\n\n /** Extract embedded assets. Terminal: resolves to a media list. */\n extractAssets(\n options: { types?: Array<'image' | 'font' | 'attachment' | 'all'> } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.types) args.types = options.types\n return this.#with('extract.assets', args)\n }\n\n /** Chunk extracted text. Terminal: resolves to a chunk array. */\n chunk(\n options: { strategy?: 'sentence' | 'paragraph' | 'fixed'; size?: number; overlap?: number } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.strategy) args.by = options.strategy\n if (options.size !== undefined) args.size = options.size\n if (options.overlap !== undefined) args.overlap = options.overlap\n return this.#with('chunk', args)\n }\n\n // ── domain namespaces ───────────────────────────────────────────────────────\n\n /** Spreadsheet mutations. */\n get sheet(): SheetNamespace {\n return new SheetNamespace(this)\n }\n\n /** Presentation mutations. */\n get slides(): SlidesNamespace {\n return new SlidesNamespace(this)\n }\n\n /** Image transforms. */\n get image(): ImageNamespace {\n return new ImageNamespace(this)\n }\n\n /** Audio operations. */\n get audio(): AudioNamespace {\n return new AudioNamespace(this)\n }\n\n // ── serialization + execution ───────────────────────────────────────────────\n\n /** The accumulated ops (a copy). */\n toOps(): MediaOp[] {\n return this.#ops.map((op) => ({ verb: op.verb, args: { ...op.args } }))\n }\n\n /** The canonical pipe form of the accumulated chain. */\n toPipe(): string {\n const plan: MediaPlan = { steps: this.#ops.map((op) => ({ verb: op.verb, args: op.args })) }\n return toPipe(plan)\n }\n\n /** Internal — used by namespaces to append. */\n withOp(verb: string, args: Record<string, MediaArgValue>): MediaChain {\n return this.#with(verb, args)\n }\n\n /** Thenable: awaiting the chain executes it. */\n then<TResult1 = unknown, TResult2 = never>(\n onfulfilled?: ((value: unknown) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): PromiseLike<TResult1 | TResult2> {\n return this.#exec(this.toOps()).then(unwrapResult).then(onfulfilled, onrejected)\n }\n\n /** Execute and return the raw {@link PlanResult} (no unwrapping). */\n async run(): Promise<PlanResult> {\n return this.#exec(this.toOps())\n }\n}\n\n/** Resolve a plan result to its natural awaited type. */\nconst unwrapResult = (result: PlanResult): unknown => {\n if (result.kind === 'media') return result.payload\n if (result.kind === 'media-list') return result.payloads\n return result.data\n}\n\n/** `sheet.*` verbs, mirrored from the verb table. */\nexport class SheetNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Insert rows. */\n addRows(\n rows: Array<Array<string | number | boolean | null>>,\n options: { sheet?: string | number; before?: number; after?: number } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'sheet.add_rows',\n compact({\n rows: rows as MediaArgJson,\n ...targetArgs(options),\n before: options.before,\n after: options.after,\n })\n )\n }\n /** Insert columns. */\n addColumns(options: {\n sheet?: string | number\n headers?: string[]\n columns?: Array<{ header: string; values?: Array<string | number | boolean | null> }>\n before?: number\n after?: number\n }): MediaChain {\n return this.#chain.withOp(\n 'sheet.add_columns',\n compact({\n ...targetArgs(options),\n headers: options.headers,\n columns: options.columns as MediaArgJson,\n before: options.before,\n after: options.after,\n })\n )\n }\n /** Update cells. */\n updateCells(updates: CellUpdate[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp(\n 'sheet.update_cells',\n compact({ updates: updates as unknown as MediaArgJson, ...targetArgs(options) })\n )\n }\n /** Delete rows by 1-based index. */\n deleteRows(rows: number[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp('sheet.delete_rows', compact({ rows, ...targetArgs(options) }))\n }\n /** Delete columns by 1-based index. */\n deleteColumns(columns: number[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp('sheet.delete_columns', compact({ columns, ...targetArgs(options) }))\n }\n /** Rename a worksheet (name-targeted). */\n renameSheet(sheet: string, to: string): MediaChain {\n return this.#chain.withOp('sheet.rename_sheet', { sheet, to })\n }\n /** Add a worksheet. */\n addSheet(name: string, options: { at?: number } = {}): MediaChain {\n return this.#chain.withOp('sheet.add_sheet', compact({ name, at: options.at }))\n }\n /** Remove a worksheet (name-targeted). */\n removeSheet(sheet: string): MediaChain {\n return this.#chain.withOp('sheet.remove_sheet', { sheet })\n }\n /** Reorder worksheets by names and/or 1-based indices. */\n reorderSheets(order: Array<string | number>): MediaChain {\n return this.#chain.withOp('sheet.reorder_sheets', { order: order as MediaArgJson })\n }\n /** Table transforms by header name. */\n transformTable(options: {\n sheet?: string | number\n headerRow?: number\n select?: string[]\n drop?: string[]\n rename?: Array<{ from: string; to: string }>\n }): MediaChain {\n return this.#chain.withOp(\n 'sheet.transform_table',\n compact({\n ...targetArgs(options),\n header_row: options.headerRow,\n select: options.select,\n drop: options.drop,\n rename: options.rename as MediaArgJson,\n })\n )\n }\n}\n\n/** `slides.*` verbs. */\nexport class SlidesNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Add a slide. */\n add(options: { at?: number; title?: string; layout?: string } = {}): MediaChain {\n return this.#chain.withOp(\n 'slides.add',\n compact({ at: options.at, title: options.title, layout: options.layout })\n )\n }\n /** Update text on a slide. */\n updateText(\n text: string,\n options: { slide?: string | number; placeholder?: string } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_text',\n compact({ text, slide: slideArg(options.slide), placeholder: options.placeholder })\n )\n }\n /** Update table cells on a slide. */\n updateTable(\n updates: Array<{ row: number; col: number; value: string }>,\n options: { slide?: string | number } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_table',\n compact({ updates: updates as unknown as MediaArgJson, slide: slideArg(options.slide) })\n )\n }\n /** Replace an image on a slide with another media. */\n updateImage(\n withMedia: MediaChainRef,\n options: { slide?: string | number; placeholder?: string } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_image',\n compact({\n with: refOf(withMedia),\n slide: slideArg(options.slide),\n placeholder: options.placeholder,\n })\n )\n }\n /** Update chart data on a slide. */\n updateChart(data: unknown[][], options: { slide?: string | number } = {}): MediaChain {\n return this.#chain.withOp(\n 'slides.update_chart',\n compact({ data: data as MediaArgJson, slide: slideArg(options.slide) })\n )\n }\n /** Delete slides by 1-based index. */\n delete(slides: number[]): MediaChain {\n return this.#chain.withOp('slides.delete', { slides })\n }\n /** Reorder slides. */\n reorder(order: number[]): MediaChain {\n return this.#chain.withOp('slides.reorder', { order })\n }\n /** Duplicate a slide. */\n duplicate(slide: number, options: { at?: number } = {}): MediaChain {\n return this.#chain.withOp('slides.duplicate', compact({ slide, at: options.at }))\n }\n}\n\n/** `image.*` verbs (the runtime fuses adjacent image steps into one engine pass). */\nexport class ImageNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Resize. */\n resize(options: ResizeOptions): MediaChain {\n return this.#chain.withOp(\n 'image.resize',\n compact({ width: options.width, height: options.height, fit: options.fit })\n )\n }\n /** Re-encode to another format. */\n format(to: string, options: { quality?: number; stripMetadata?: boolean } = {}): MediaChain {\n return this.#chain.withOp(\n 'image.format',\n compact({ to, quality: options.quality, strip_metadata: options.stripMetadata })\n )\n }\n /** Rotate clockwise. */\n rotate(deg: 90 | 180 | 270): MediaChain {\n return this.#chain.withOp('image.rotate', { deg: String(deg) })\n }\n /** Flip. */\n flip(axis: 'horizontal' | 'vertical' | 'both'): MediaChain {\n return this.#chain.withOp('image.flip', { axis })\n }\n /** Strip EXIF/ICC metadata. */\n stripMetadata(): MediaChain {\n return this.#chain.withOp('image.strip_metadata', {})\n }\n}\n\n/** `audio.*` verbs. */\nexport class AudioNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Transcribe speech. Terminal: resolves to text (or srt/vtt/json per `out`). */\n transcribe(\n options: { language?: string; out?: 'txt' | 'srt' | 'vtt' | 'json'; translate?: boolean } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'audio.transcribe',\n compact({ lang: options.language, out: options.out, translate: options.translate })\n )\n }\n}\n\nconst targetArgs = (options: { sheet?: string | number }): Record<string, MediaArgValue> =>\n options.sheet === undefined ? {} : { sheet: options.sheet }\n\nconst slideArg = (slide: string | number | undefined): string | number | undefined => slide\n\nconst compact = (\n args: Record<string, MediaArgValue | undefined>\n): Record<string, MediaArgValue> => {\n const out: Record<string, MediaArgValue> = {}\n for (const [k, v] of Object.entries(args)) {\n if (v !== undefined) out[k] = v\n }\n return out\n}\n\n/** The input shapes `mp(...)` accepts. */\nexport type ChainInput = StepPayload\n","/**\n * The step runtime: executes a validated {@link MediaPlan} as an `@nhtio/middleware` onion,\n * one stage per step, with consumer interceptors wrapping every step.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. A fresh `Runner` is minted per\n * execution (middleware runners are single-use), so the same compiled chain can be awaited\n * repeatedly. Each step stage:\n *\n * 1. runs the consumer's `use` interceptors (the documented seam for DLP/AV scanning, caching\n * via `shortCircuit(bytes)`, byte limits, and telemetry — the battery ships no built-in\n * scanner/cache/limiter: those are policies, this is the seam), then\n * 2. dispatches to the verb's registered {@link StepImpl}, validating the output at the step\n * boundary so a misbehaving engine produces a clear error instead of corrupt bytes.\n *\n * Steps stream bytes in memory; nothing touches disk except inside a binary engine's\n * `ScratchWorkspace`. Adjacent `image.*` steps are fused by the compiler before execution so\n * a resize→format→rotate chain costs a single decode/encode.\n */\n\nimport { VERB_INDEX } from './verbs'\nimport { Middleware } from '@nhtio/middleware'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED, E_MEDIA_STEP_UNAVAILABLE } from './exceptions'\nimport type { NextFn } from '@nhtio/middleware'\nimport type { EngineRegistry } from './registry'\nimport type { MediaPlan, MediaStep, MediaArgValue } from './plan'\n\n/** A single in-flight value travelling between steps. */\nexport interface StepPayload {\n /** The raw content bytes. */\n bytes: Uint8Array\n /** The content MIME type. */\n mimeType: string\n /** The filename (extension informs format dispatch). */\n filename: string\n}\n\n/**\n * What a step produces. `media` continues the chain (or terminates as bytes); `media-list`\n * and `data` are terminal-only shapes enforced by the plan compiler.\n */\nexport type StepResult =\n | { kind: 'media'; payload: StepPayload }\n | { kind: 'media-list'; payloads: StepPayload[] }\n | { kind: 'data'; data: unknown; asText?: string }\n\n/** The mutable execution context threaded through interceptors and step impls. */\nexport interface StepContext {\n /** The whole plan being executed. */\n readonly plan: MediaPlan\n /** Zero-based index of the current step. */\n readonly stepIndex: number\n /** The current step. */\n readonly step: MediaStep\n /** The input payload for this step. */\n payload: StepPayload\n /** Abort signal threaded from the caller. */\n readonly signal?: AbortSignal\n /** Scratchpad shared across the execution (interceptors may stash timings, hashes…). */\n readonly stash: Map<string, unknown>\n /**\n * Short-circuit this step: skip the implementation and continue the chain with `bytes`\n * (the cache idiom). Throws internally — call it, don't return it.\n */\n shortCircuit(payload: StepPayload): never\n /** The deployment's engine registry — ordered, capability-filtered dispatch. */\n readonly engines: EngineRegistry\n /**\n * Resolve another media participating in this step (merge/diff targets), by ref id.\n * Supplied by the pipeline from its configured media resolver.\n */\n resolveRef(id: string): Promise<StepPayload>\n}\n\n/** One verb's implementation. Registered into the runtime's step registry. */\nexport type StepImpl = (ctx: StepContext) => Promise<StepResult>\n\n/** Consumer step interceptor — the `use` seam. Same onion shape as the tool batteries. */\nexport type MediaStepMiddlewareFn = (ctx: StepContext, next: NextFn) => void | Promise<void>\n\n/** Internal sentinel for {@link StepContext.shortCircuit}. */\nconst SHORT_CIRCUIT = Symbol('adk.media.shortCircuit')\n\ninterface ShortCircuitSignal {\n [SHORT_CIRCUIT]: true\n payload: StepPayload\n}\n\nconst isShortCircuit = (value: unknown): value is ShortCircuitSignal =>\n isObject(value) && (value as Record<symbol, unknown>)[SHORT_CIRCUIT] === true\n\n/** Options for {@link executePlan}. */\nexport interface ExecutePlanOptions {\n /** The input payload the first step consumes. */\n input: StepPayload\n /** Verb id → implementation registry. */\n steps: ReadonlyMap<string, StepImpl>\n /** Consumer interceptors wrapping every step. */\n use: readonly MediaStepMiddlewareFn[]\n /** The deployment's engine registry. */\n engines: EngineRegistry\n /** Media-ref resolution for multi-input verbs. */\n resolveRef: StepContext['resolveRef']\n /** Abort signal. */\n signal?: AbortSignal\n}\n\n/** The settled result of executing a whole plan. */\nexport type PlanResult = StepResult\n\n/**\n * Execute a validated plan. Returns the final step's result; intermediate steps must produce\n * `media` results (the compiler guarantees non-terminal steps are media-shaped).\n *\n * @param plan - The validated plan.\n * @param options - Input payload, step registry, interceptors, engine access.\n * @returns The terminal step's result.\n */\nexport const executePlan = async (\n plan: MediaPlan,\n options: ExecutePlanOptions\n): Promise<PlanResult> => {\n const stash = new Map<string, unknown>()\n let payload = options.input\n let result: PlanResult = { kind: 'media', payload }\n\n for (let i = 0; i < plan.steps.length; i++) {\n const step = plan.steps[i]\n options.signal?.throwIfAborted()\n const impl = options.steps.get(step.verb)\n if (!impl) {\n throw new E_MEDIA_STEP_UNAVAILABLE([step.verb])\n }\n\n const ctx: StepContext = {\n plan,\n stepIndex: i,\n step,\n payload,\n signal: options.signal,\n stash,\n shortCircuit: (sc: StepPayload): never => {\n const signal: ShortCircuitSignal = { [SHORT_CIRCUIT]: true, payload: sc }\n throw signal\n },\n engines: options.engines,\n resolveRef: options.resolveRef,\n }\n\n try {\n result = await runStep(ctx, impl, options.use)\n } catch (err) {\n if (isShortCircuit(err)) {\n result = { kind: 'media', payload: err.payload }\n } else if (isError(err) && err.name.startsWith('E_MEDIA_')) {\n throw err\n } else {\n const detail = isError(err) ? err.message : String(err)\n throw new E_MEDIA_STEP_FAILED([step.verb, detail], { cause: err })\n }\n }\n\n if (result.kind === 'media') {\n payload = result.payload\n } else if (i < plan.steps.length - 1) {\n if (\n result.kind === 'data' &&\n typeof result.asText === 'string' &&\n VERB_INDEX.get(step.verb)?.output === 'text'\n ) {\n // R-step materialization (frozen 0.10): a non-terminal read step yields a text Media\n // into the chain, so `extract text | chunk` is type-sound.\n payload = {\n bytes: new TextEncoder().encode(result.asText),\n mimeType: 'text/plain',\n filename: materializedName(payload.filename),\n }\n result = { kind: 'media', payload }\n } else {\n throw new E_MEDIA_STEP_FAILED([\n step.verb,\n 'a non-terminal step produced a terminal result; only the last step may yield data or multiple media',\n ])\n }\n }\n }\n return result\n}\n\n/** Run one step: interceptor onion (fresh runner) terminating in the implementation. */\nconst runStep = async (\n ctx: StepContext,\n impl: StepImpl,\n use: readonly MediaStepMiddlewareFn[]\n): Promise<StepResult> => {\n if (use.length === 0) {\n return validated(ctx, await impl(ctx))\n }\n const mw = new Middleware<MediaStepMiddlewareFn>()\n for (const fn of use) mw.add(fn)\n\n let result: StepResult | undefined\n let caught: unknown\n await mw\n .runner()\n .errorHandler(async (error: unknown) => {\n caught = error\n })\n .finalHandler(async () => {\n result = validated(ctx, await impl(ctx))\n })\n .run((fn, next) => Promise.resolve(fn(ctx, next)))\n\n if (caught !== undefined) throw caught\n if (result === undefined) {\n throw new E_MEDIA_STEP_FAILED([\n ctx.step.verb,\n 'a step interceptor did not call next() and did not short-circuit',\n ])\n }\n return result\n}\n\n/** Validate a step implementation's output shape at the boundary. */\nconst validated = (ctx: StepContext, result: StepResult): StepResult => {\n const bad = (msg: string): never => {\n throw new E_MEDIA_STEP_FAILED([ctx.step.verb, `implementation returned ${msg}`])\n }\n const isBytes = (value: unknown): value is Uint8Array =>\n isInstanceOf(value, 'Uint8Array', Uint8Array)\n if (result.kind === 'media') {\n if (!isBytes(result.payload?.bytes)) bad('a media result without bytes')\n if (typeof result.payload.mimeType !== 'string') bad('a media result without a mimeType')\n return result\n }\n if (result.kind === 'media-list') {\n if (!Array.isArray(result.payloads) || result.payloads.some((p) => !isBytes(p.bytes))) {\n bad('a media-list result with invalid payloads')\n }\n return result\n }\n if (result.kind === 'data') return result\n return bad('an unknown result kind')\n}\n\n/** Filename for an R-step's materialized text payload. */\nconst materializedName = (filename: string): string => {\n const dot = filename.lastIndexOf('.')\n const base = dot > 0 ? filename.slice(0, dot) : filename\n return `${base}.txt`\n}\n\n/** Convenience: read a step arg with a typed cast (validation already ran). */\nexport const argOf = <T extends MediaArgValue>(step: MediaStep, name: string): T | undefined =>\n step.args[name] as T | undefined\n","/**\n * MIME tables and format-family classification for the media pipeline.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * `format_families.ts` support tiers, reshaped for the DSL's verb-applicability checks:\n *\n * - Tier 1 (full read + mutate): OOXML (docx/xlsx/pptx) and ODF (odt/ods/odp, via a normalize\n * engine), plus PDF for page-level operations.\n * - Tier 2 (extraction only): legacy Office (doc/xls/ppt) and Apple iWork — mutation verbs\n * reject these with a reason string rather than a throw, so callers can surface\n * model-actionable failures.\n * - Everything else classifies by top-level MIME family (image/audio/text).\n */\n\nimport type { FormatFamily } from './verbs'\n\n/** Well-known MIME constants used across the battery. */\nexport const MIME = {\n DOCX: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n XLSX: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n PPTX: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n ODT: 'application/vnd.oasis.opendocument.text',\n ODS: 'application/vnd.oasis.opendocument.spreadsheet',\n ODP: 'application/vnd.oasis.opendocument.presentation',\n PDF: 'application/pdf',\n DOC: 'application/msword',\n XLS: 'application/vnd.ms-excel',\n PPT: 'application/vnd.ms-powerpoint',\n PAGES: 'application/x-iwork-pages-sffpages',\n NUMBERS: 'application/x-iwork-numbers-sffnumbers',\n KEYNOTE: 'application/x-iwork-keynote-sffkey',\n TXT: 'text/plain',\n MD: 'text/markdown',\n CSV: 'text/csv',\n HTML: 'text/html',\n JSON: 'application/json',\n PNG: 'image/png',\n JPEG: 'image/jpeg',\n WEBP: 'image/webp',\n TIFF: 'image/tiff',\n AVIF: 'image/avif',\n WAV: 'audio/wav',\n MP3: 'audio/mpeg',\n} as const\n\n/** Legacy Office MIME types (extraction only — mutation is rejected). */\nexport const LEGACY_OFFICE_MIMES: ReadonlySet<string> = new Set([MIME.DOC, MIME.XLS, MIME.PPT])\n\n/** Apple iWork MIME types (extraction only — mutation is rejected). */\nexport const IWORK_MIMES: ReadonlySet<string> = new Set([MIME.PAGES, MIME.NUMBERS, MIME.KEYNOTE])\n\nconst SPREADSHEET_MIMES: ReadonlySet<string> = new Set([MIME.XLSX, MIME.ODS, MIME.XLS, MIME.CSV])\nconst PRESENTATION_MIMES: ReadonlySet<string> = new Set([\n MIME.PPTX,\n MIME.ODP,\n MIME.PPT,\n MIME.KEYNOTE,\n])\nconst DOCUMENT_MIMES: ReadonlySet<string> = new Set([\n MIME.PDF,\n MIME.DOCX,\n MIME.ODT,\n MIME.DOC,\n MIME.PAGES,\n MIME.TXT,\n MIME.MD,\n MIME.HTML,\n MIME.JSON,\n 'application/rtf',\n 'text/rtf',\n])\n\n/**\n * Classify a MIME type into the verb table's broad format family.\n *\n * @param mimeType - The media MIME type.\n * @returns The family used by verb-applicability checks.\n */\nexport const familyOf = (mimeType: string): FormatFamily => {\n const mime = mimeType.toLowerCase().split(';')[0].trim()\n if (SPREADSHEET_MIMES.has(mime)) return 'spreadsheet'\n if (PRESENTATION_MIMES.has(mime)) return 'presentation'\n if (DOCUMENT_MIMES.has(mime)) return 'document'\n if (mime.startsWith('image/')) return 'image'\n if (mime.startsWith('audio/')) return 'audio'\n if (mime.startsWith('text/')) return 'document'\n return 'document'\n}\n\n/**\n * Reason a mutation verb cannot run against this MIME type, or `undefined` when mutation is\n * allowed. Returns a reason string (not a throw) so callers compose model-actionable failures.\n *\n * @param mimeType - The media MIME type.\n * @returns A human-readable reason, or `undefined` when mutation is supported.\n */\nexport const unsupportedForMutationReason = (mimeType: string): string | undefined => {\n const mime = mimeType.toLowerCase().split(';')[0].trim()\n if (LEGACY_OFFICE_MIMES.has(mime)) {\n return `legacy Office format (${mime}) supports extraction only — convert it first (e.g. convert to=docx)`\n }\n if (IWORK_MIMES.has(mime)) {\n return `Apple iWork format (${mime}) supports extraction only`\n }\n return undefined\n}\n\n/** A small extension → MIME lookup for filenames produced by transforms. */\nexport const EXT_TO_MIME: Readonly<Record<string, string>> = {\n pdf: MIME.PDF,\n docx: MIME.DOCX,\n xlsx: MIME.XLSX,\n pptx: MIME.PPTX,\n odt: MIME.ODT,\n ods: MIME.ODS,\n odp: MIME.ODP,\n doc: MIME.DOC,\n xls: MIME.XLS,\n ppt: MIME.PPT,\n txt: MIME.TXT,\n md: MIME.MD,\n csv: MIME.CSV,\n html: MIME.HTML,\n json: MIME.JSON,\n rtf: 'application/rtf',\n png: MIME.PNG,\n jpg: MIME.JPEG,\n jpeg: MIME.JPEG,\n webp: MIME.WEBP,\n tiff: MIME.TIFF,\n avif: MIME.AVIF,\n wav: MIME.WAV,\n mp3: MIME.MP3,\n}\n\n/**\n * Replace (or add) a filename's extension.\n *\n * @param filename - The original filename.\n * @param ext - The new extension, without the dot.\n * @returns The filename with the new extension.\n */\nexport const replaceExtension = (filename: string, ext: string): string => {\n const dot = filename.lastIndexOf('.')\n const base = dot > 0 ? filename.slice(0, dot) : filename\n return `${base}.${ext}`\n}\n","/**\n * Pure text-shaped step implementations: chunking, plain-text extraction, text diff/patch,\n * and the text-mode redact/update_text paths.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The split functions are ported\n * verbatim from the source server's `chunk_text` adapter (its green unit suite ports with\n * them). All implementations here operate on in-memory bytes and run in any environment.\n */\n\nimport { argOf } from '../runtime'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { familyOf, replaceExtension, MIME } from '../formats'\nimport type { StepImpl, StepPayload } from '../runtime'\nimport type { RegExpRef, MediaRef, MediaArgScalar } from '../plan'\n\n/** One text chunk with its position in the source. */\nexport interface Chunk {\n index: number\n text: string\n char_start: number\n char_end: number\n}\n\n/** Split text on double-newline paragraph boundaries, with optional character overlap. */\nexport const splitParagraph = (text: string, overlap: number): Chunk[] => {\n const blocks = text\n .split(/\\n{2,}/)\n .map((b) => b.trim())\n .filter(Boolean)\n const chunks: Chunk[] = []\n let pos = 0\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i]\n const overlapText =\n i > 0 && overlap > 0\n ? blocks\n .slice(Math.max(0, i - 1), i)\n .join('\\n\\n')\n .slice(-overlap)\n : ''\n const chunkText = overlapText ? `${overlapText}\\n\\n${block}` : block\n chunks.push({ index: i, text: chunkText, char_start: pos, char_end: pos + block.length })\n pos += block.length + 2\n }\n return chunks\n}\n\n/** Split text on sentence-ending punctuation, with optional character overlap. */\nexport const splitSentence = (text: string, overlap: number): Chunk[] => {\n const sentences = text.match(/[^.!?]+[.!?](?:\\s|$)|[^.!?]+$/g) ?? [text]\n const chunks: Chunk[] = []\n let pos = 0\n for (let i = 0; i < sentences.length; i++) {\n const sentence = sentences[i].trim()\n if (!sentence) continue\n const overlapText =\n i > 0 && overlap > 0\n ? sentences\n .slice(Math.max(0, i - 1), i)\n .join(' ')\n .slice(-overlap)\n : ''\n const chunkText = overlapText ? `${overlapText} ${sentence}` : sentence\n chunks.push({\n index: chunks.length,\n text: chunkText,\n char_start: pos,\n char_end: pos + sentence.length,\n })\n pos += sentence.length + 1\n }\n return chunks\n}\n\n/** Split text into fixed-size character windows with optional overlap. */\nexport const splitFixed = (text: string, chunkSize: number, overlap: number): Chunk[] => {\n const chunks: Chunk[] = []\n const step = Math.max(1, chunkSize - overlap)\n let i = 0\n let idx = 0\n while (i < text.length) {\n const start = Math.max(0, i - overlap)\n const end = i + chunkSize\n chunks.push({\n index: idx++,\n text: text.slice(start, end),\n char_start: start,\n char_end: Math.min(end, text.length),\n })\n i += step\n }\n return chunks\n}\n\nconst decoder = new TextDecoder('utf-8', { fatal: false })\nconst encoder = new TextEncoder()\n\n/** Decode payload bytes as UTF-8 text (UTF-16 BOM aware). */\nexport const decodeText = (bytes: Uint8Array): string => {\n if (bytes.length >= 2) {\n if (bytes[0] === 0xff && bytes[1] === 0xfe) {\n return new TextDecoder('utf-16le').decode(bytes.subarray(2))\n }\n if (bytes[0] === 0xfe && bytes[1] === 0xff) {\n return new TextDecoder('utf-16be').decode(bytes.subarray(2))\n }\n }\n return decoder.decode(bytes).replace(/\\r\\n?/g, '\\n')\n}\n\nconst textPayload = (source: StepPayload, text: string, suffix: string): StepPayload => ({\n bytes: encoder.encode(text),\n mimeType: MIME.TXT,\n filename: replaceExtension(source.filename, suffix),\n})\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `chunk` — split text content into retrieval chunks (data result). */\nexport const chunkStep: StepImpl = async (ctx) => {\n const by = argOf<string>(ctx.step, 'by') ?? 'paragraph'\n const size = argOf<number>(ctx.step, 'size') ?? 1000\n const overlap = argOf<number>(ctx.step, 'overlap') ?? 0\n const text = decodeText(ctx.payload.bytes)\n const chunks =\n by === 'sentence'\n ? splitSentence(text, overlap)\n : by === 'fixed'\n ? splitFixed(text, size, overlap)\n : splitParagraph(text, overlap)\n return { kind: 'data', data: chunks, asText: JSON.stringify(chunks) }\n}\n\n/**\n * `extract.text` — Phase 0 covers the native-text path (txt/md/csv/json/html). Document\n * formats (pdf/docx/…) and OCR routes are added by later phases; until then they fail with a\n * clear reason.\n */\nexport const extractTextStep: StepImpl = async (ctx) => {\n const family = familyOf(ctx.payload.mimeType)\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const isNativeText =\n mime.startsWith('text/') || mime === MIME.JSON || mime === MIME.MD || mime === MIME.CSV\n if (!isNativeText) {\n throw new E_MEDIA_STEP_FAILED([\n 'extract.text',\n `extraction for ${family} media (${mime}) is not yet implemented in this build`,\n ])\n }\n const text = decodeText(ctx.payload.bytes)\n return {\n kind: 'data',\n data: text,\n asText: text,\n }\n}\n\n/** `extract.metadata` — Phase 0: size/MIME/filename basics (format-aware fields come later). */\nexport const extractMetadataStep: StepImpl = async (ctx) => {\n const meta = {\n filename: ctx.payload.filename,\n mime_type: ctx.payload.mimeType,\n size_bytes: ctx.payload.bytes.byteLength,\n family: familyOf(ctx.payload.mimeType),\n }\n return { kind: 'data', data: meta, asText: JSON.stringify(meta) }\n}\n\nconst toPattern = (value: MediaArgScalar): RegExp | string => {\n if (typeof value === 'string') return value\n const ref = value as RegExpRef\n return new RegExp(ref.source, ref.flags.includes('g') ? ref.flags : `${ref.flags}g`)\n}\n\nconst applyRedaction = (text: string, patterns: MediaArgScalar[], replacement: string): string => {\n let out = text\n for (const p of patterns) {\n const pattern = toPattern(p)\n out =\n typeof pattern === 'string'\n ? out.split(pattern).join(replacement)\n : out.replace(pattern, replacement)\n }\n return out\n}\n\n/** `redact` — Phase 0: the text-media path. Document-format in-place redaction lands later. */\nexport const redactStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase()\n if (!mime.startsWith('text/')) {\n throw new E_MEDIA_STEP_FAILED([\n 'redact',\n `redaction for ${ctx.payload.mimeType} is not yet implemented in this build`,\n ])\n }\n const raw = ctx.step.args.match\n const patterns = (Array.isArray(raw) ? raw : [raw]) as MediaArgScalar[]\n const replacement = argOf<string>(ctx.step, 'replace') ?? '█'\n const text = applyRedaction(decodeText(ctx.payload.bytes), patterns, replacement)\n return { kind: 'media', payload: textPayload(ctx.payload, text, 'txt') }\n}\n\n/** `update_text` — Phase 0: the text-media path. */\nexport const updateTextStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase()\n if (!mime.startsWith('text/')) {\n throw new E_MEDIA_STEP_FAILED([\n 'update_text',\n `text update for ${ctx.payload.mimeType} is not yet implemented in this build`,\n ])\n }\n const anchor = argOf<string>(ctx.step, 'anchor') as string\n const replace = argOf<string>(ctx.step, 'replace') ?? ''\n const text = decodeText(ctx.payload.bytes)\n if (!text.includes(anchor)) {\n throw new E_MEDIA_STEP_FAILED([\n 'update_text',\n `anchor text not found: \"${anchor.slice(0, 80)}\"`,\n ])\n }\n const updated = text.replace(anchor, replace)\n return { kind: 'media', payload: { ...ctx.payload, bytes: encoder.encode(updated) } }\n}\n\n/** Build a unified diff between two texts using the `diff` peer (lazy import). */\nconst unifiedDiff = async (aName: string, bName: string, a: string, b: string): Promise<string> => {\n const mod = await import('diff')\n return mod.createTwoFilesPatch(aName, bName, a, b)\n}\n\n/** `diff` — compare against another media (text-comparable formats in Phase 0). */\nexport const diffStep: StepImpl = async (ctx) => {\n const ref = ctx.step.args.with as MediaRef\n if (ref.kind !== 'id') {\n throw new E_MEDIA_STEP_FAILED(['diff', 'builder refs are not yet supported here'])\n }\n const other = await ctx.resolveRef(ref.id)\n const a = decodeText(ctx.payload.bytes)\n const b = decodeText(other.bytes)\n const patch = await unifiedDiff(ctx.payload.filename, other.filename, a, b)\n const mod = await import('diff')\n const structured = mod.diffLines(a, b).map((part) => ({\n added: part.added === true,\n removed: part.removed === true,\n count: part.count ?? 0,\n value: part.value,\n }))\n const data = { patch, changes: structured }\n return { kind: 'data', data, asText: patch }\n}\n\n/** `apply_patch` — apply a unified diff to the media text. */\nexport const applyPatchStep: StepImpl = async (ctx) => {\n const patch = argOf<string>(ctx.step, 'patch') as string\n const text = decodeText(ctx.payload.bytes)\n const mod = await import('diff')\n const result = mod.applyPatch(text, patch)\n if (result === false) {\n throw new E_MEDIA_STEP_FAILED([\n 'apply_patch',\n 'the patch does not apply to this media content (context mismatch)',\n ])\n }\n return { kind: 'media', payload: { ...ctx.payload, bytes: encoder.encode(result) } }\n}\n","/**\n * Doc-domain step extensions: format-preserving text mutation for DOCX/PPTX, asset\n * extraction from OOXML/ODF archives and PDFs, and format conversion via the convert engine.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * doc adapters; the format-dispatch contract follows the server's green e2e suite: DOCX and\n * PPTX redact/sanitize/normalize/update_text mutate text in place inside the container\n * (preserving the source format); text-like inputs mutate as text; PDF redact falls back to\n * text extraction (the server's PDF \"visual annotation\" path is content-stream-preserving and\n * out of scope here — the failure message says exactly that).\n */\n\nimport { MIME } from '../formats'\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { redactStep as textRedactStep, updateTextStep as textUpdateTextStep } from './text'\nimport type { default as JSZipNS } from 'jszip'\nimport type { RegExpRef, MediaArgScalar } from '../plan'\nimport type { StepImpl, StepContext, StepResult, StepPayload } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\nconst escapeXml = (value: string): string =>\n value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n\nconst unescapeXml = (value: string): string =>\n value\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n\n// ── OOXML text mutation (ported run-aggregation semantics) ───────────────────\n\n/**\n * Replace matches inside text nodes of OOXML, aggregating runs per paragraph so patterns\n * spanning split runs still match (Word splits text across `w:t` runs on formatting changes).\n */\nconst replaceInOoxml = (\n xml: string,\n paragraphTag: 'w:p' | 'a:p',\n textTag: 'w:t' | 'a:t',\n pattern: RegExp,\n replacement: string\n): { xml: string; matchCount: number } => {\n let totalMatches = 0\n const pRegex = new RegExp(`<${paragraphTag}\\\\b[^>]*>[\\\\s\\\\S]*?</${paragraphTag}>`, 'g')\n const result = xml.replace(pRegex, (pXml) => {\n const tElements: Array<{ start: number; end: number; content: string }> = []\n const tRegex = new RegExp(`<${textTag}(?:\\\\s[^>]*)?>([^<]*)</${textTag}>`, 'g')\n let tMatch: RegExpExecArray | null\n while ((tMatch = tRegex.exec(pXml))) {\n tElements.push({\n start: tMatch.index,\n end: tMatch.index + tMatch[0].length,\n content: unescapeXml(tMatch[1]),\n })\n }\n if (tElements.length === 0) return pXml\n const aggregated = tElements.map((t) => t.content).join('')\n const p = new RegExp(pattern.source, pattern.flags)\n const replaced = aggregated.replace(p, replacement)\n if (replaced === aggregated) return pXml\n const counter = new RegExp(pattern.source, pattern.flags)\n while (counter.exec(aggregated)) {\n totalMatches += 1\n if (!counter.global) break\n }\n let out = pXml\n for (let i = tElements.length - 1; i >= 0; i--) {\n const el = tElements[i]\n const space = textTag === 'w:t' && i === 0 ? ' xml:space=\"preserve\"' : ''\n const content = i === 0 ? escapeXml(replaced) : ''\n out =\n out.slice(0, el.start) + `<${textTag}${space}>${content}</${textTag}>` + out.slice(el.end)\n }\n return out\n })\n return { xml: result, matchCount: totalMatches }\n}\n\n/** Map text-node mutation over every relevant part of a DOCX or PPTX archive. */\nconst mutateOoxmlText = async (\n ctx: StepContext,\n verb: string,\n mutateXml: (xml: string, kind: 'docx' | 'pptx') => string\n): Promise<StepResult> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const kind = mime === MIME.DOCX ? 'docx' : 'pptx'\n const JSZip = await jszip()\n let zip: JSZipNS\n try {\n zip = await JSZip.loadAsync(ctx.payload.bytes)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the document container: ${detail}`)\n /* unreachable */ throw err\n }\n const parts =\n kind === 'docx'\n ? Object.keys(zip.files).filter((n) => /^word\\/(document|header\\d*|footer\\d*)\\.xml$/.test(n))\n : Object.keys(zip.files).filter((n) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n))\n if (parts.length === 0) fail(verb, 'the container has no text parts to mutate (corrupt file?)')\n for (const part of parts) {\n const xml = await zip.file(part)!.async('text')\n const next = mutateXml(xml, kind)\n if (next !== xml) zip.file(part, next)\n }\n const bytes = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE' })\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\nconst toGlobalRegex = (value: MediaArgScalar): RegExp => {\n if (typeof value === 'string') {\n const escaped = value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return new RegExp(escaped, 'g')\n }\n const ref = value as RegExpRef\n return new RegExp(ref.source, ref.flags.includes('g') ? ref.flags : `${ref.flags}g`)\n}\n\n// ── doc-aware step dispatch ──────────────────────────────────────────────────\n\n/** `redact` — format dispatch: text media → text path; DOCX/PPTX → in-place container edit. */\nexport const docRedactStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) return textRedactStep(ctx)\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n const raw = ctx.step.args.match\n const patterns = (Array.isArray(raw) ? raw : [raw]) as MediaArgScalar[]\n const replacement = argOf<string>(ctx.step, 'replace') ?? '█'\n return mutateOoxmlText(ctx, 'redact', (xml, kind) => {\n let out = xml\n for (const p of patterns) {\n out = replaceInOoxml(\n out,\n kind === 'docx' ? 'w:p' : 'a:p',\n kind === 'docx' ? 'w:t' : 'a:t',\n toGlobalRegex(p),\n replacement\n ).xml\n }\n return out\n })\n }\n fail(\n 'redact',\n `redaction for ${mime} is not supported in this build (text, DOCX, and PPTX are). For PDF, extract the text first: extract text | redact …`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst BLOCKED_CONTROL = (code: number): boolean =>\n (code >= 0 && code <= 8) ||\n code === 11 ||\n code === 12 ||\n (code >= 14 && code <= 31) ||\n code === 127\n\nconst stripControlChars = (text: string): string => {\n let out = ''\n for (const ch of text) {\n if (BLOCKED_CONTROL(ch.charCodeAt(0))) continue\n out += ch\n }\n return out\n}\n\nconst sanitizeTextNodes = (xml: string, textTag: 'w:t' | 'a:t'): string =>\n xml.replace(\n new RegExp(`<${textTag}(?:\\\\s[^>]*)?>([^<]*)</${textTag}>`, 'g'),\n (full, content: string) => {\n const cleaned = stripControlChars(unescapeXml(content))\n if (cleaned === unescapeXml(content)) return full\n return full.replace(content, escapeXml(cleaned))\n }\n )\n\n/** `sanitize` — strip blocked control characters from text nodes / text media. */\nexport const docSanitizeStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) {\n const text = new TextDecoder().decode(ctx.payload.bytes)\n const cleaned = stripControlChars(text)\n return { kind: 'media', payload: { ...ctx.payload, bytes: new TextEncoder().encode(cleaned) } }\n }\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n return mutateOoxmlText(ctx, 'sanitize', (xml, kind) =>\n sanitizeTextNodes(xml, kind === 'docx' ? 'w:t' : 'a:t')\n )\n }\n fail('sanitize', `sanitize for ${mime} is not supported in this build (text, DOCX, PPTX are)`)\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst normalizeText = (text: string): string =>\n text\n .replace(/\\r\\n/g, '\\n')\n .replace(/\\r/g, '\\n')\n .replace(/[\\t ]+$/gm, '')\n\n/** `normalize` — CRLF→LF + trailing-whitespace removal in text nodes / text media. */\nexport const docNormalizeStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) {\n const text = new TextDecoder().decode(ctx.payload.bytes)\n return {\n kind: 'media',\n payload: { ...ctx.payload, bytes: new TextEncoder().encode(normalizeText(text)) },\n }\n }\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n return mutateOoxmlText(ctx, 'normalize', (xml, kind) => {\n const tag = kind === 'docx' ? 'w:t' : 'a:t'\n return xml.replace(\n new RegExp(`<${tag}(?:\\\\s[^>]*)?>([^<]*)</${tag}>`, 'g'),\n (full, content: string) => {\n const normalized = normalizeText(unescapeXml(content))\n if (normalized === unescapeXml(content)) return full\n return full.replace(content, escapeXml(normalized))\n }\n )\n })\n }\n fail('normalize', `normalize for ${mime} is not supported in this build (text, DOCX, PPTX are)`)\n /* unreachable */ throw new Error('unreachable')\n}\n\n/** `update_text` — anchor replacement; DOCX/PPTX in-place, TARGET_NOT_FOUND when absent. */\nexport const docUpdateTextStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) return textUpdateTextStep(ctx)\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n const anchor = argOf<string>(ctx.step, 'anchor') as string\n const replace = argOf<string>(ctx.step, 'replace') ?? ''\n let found = 0\n const result = await mutateOoxmlText(ctx, 'update_text', (xml, kind) => {\n if (found > 0) return xml\n const escaped = anchor.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n const { xml: next, matchCount } = replaceInOoxml(\n xml,\n kind === 'docx' ? 'w:p' : 'a:p',\n kind === 'docx' ? 'w:t' : 'a:t',\n new RegExp(escaped),\n replace\n )\n found += matchCount\n return next\n })\n if (found === 0) {\n fail('update_text', `anchor text not found: \"${anchor.slice(0, 80)}\"`)\n }\n return result\n }\n fail(\n 'update_text',\n `text update for ${mime} is not supported (text, DOCX, PPTX are; PDF text is not reliably editable)`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\n// ── extract.assets ───────────────────────────────────────────────────────────\n\nconst ASSET_PATTERNS: Record<string, RegExp> = {\n image: /\\.(png|jpe?g|gif|bmp|tiff?|emf|wmf|svg|webp)$/i,\n font: /\\.(ttf|otf|woff2?|odttf)$/i,\n attachment: /\\.(bin|ole|docx?|xlsx?|pptx?|pdf|txt|csv)$/i,\n}\n\nconst EXT_MIME: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tif: 'image/tiff',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n emf: 'image/emf',\n wmf: 'image/wmf',\n ttf: 'font/ttf',\n otf: 'font/otf',\n woff: 'font/woff',\n woff2: 'font/woff2',\n}\n\n/**\n * `extract.assets` — enumerate embedded assets. OOXML/ODF archives are walked natively\n * (cross-env); PDF inputs use the pdfImages engine.\n */\nexport const extractAssetsStep: StepImpl = async (ctx) => {\n const verb = 'extract assets'\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const requested = (ctx.step.args.types as string[] | undefined) ?? ['all']\n const wantAll = requested.includes('all')\n const want = (kind: string): boolean => wantAll || requested.includes(kind)\n\n if (mime === MIME.PDF) {\n if (!want('image')) {\n fail(verb, 'PDF asset extraction currently supports images (types=image or all)')\n }\n if (!ctx.engines.hasConvert(mime, 'images')) {\n fail(\n verb,\n 'PDF asset extraction requires an engine that converts application/pdf to \"images\", and none is configured. Do not retry this verb on PDFs in this deployment.'\n )\n }\n const format = argOf<string>(ctx.step, 'format')\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'images',\n options: format ? { format } : undefined,\n signal: ctx.signal,\n })\n if (result.outputs.length === 0) fail(verb, 'no embedded images were found in the PDF')\n const wantedMime = format ? (EXT_MIME[format] ?? `image/${format}`) : undefined\n const payloads: StepPayload[] = []\n for (const [i, img] of result.outputs.entries()) {\n let bytes = img.bytes\n let mimeType = img.mimeType\n // Two-tier encoding: outputs already in the requested format pass through (native\n // collapse); the rest re-encode via an ordinary registry dispatch.\n if (wantedMime && mimeType.toLowerCase() !== wantedMime) {\n const reencoded = await ctx.engines.mutate({\n bytes,\n mimeType,\n format: { to: format! },\n signal: ctx.signal,\n })\n bytes = reencoded.bytes\n mimeType = reencoded.mimeType\n }\n payloads.push({\n bytes,\n mimeType,\n filename: `asset-${i + 1}.${mimeType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'bin'}`,\n })\n }\n return { kind: 'media-list', payloads }\n }\n\n // Archive formats: OOXML + ODF are zip containers.\n const isArchive = [MIME.DOCX, MIME.XLSX, MIME.PPTX, MIME.ODT, MIME.ODS, MIME.ODP].includes(\n mime as never\n )\n if (!isArchive) {\n fail(verb, `asset extraction for ${mime} is not supported (OOXML/ODF archives and PDF are)`)\n }\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const payloads: StepPayload[] = []\n for (const [name, entry] of Object.entries(zip.files)) {\n if (entry.dir) continue\n const basename = name.split('/').pop() ?? name\n const matchKind = Object.entries(ASSET_PATTERNS).find(([, re]) => re.test(basename))?.[0]\n if (!matchKind || !want(matchKind)) continue\n // Only media/embeddings/fonts directories carry real assets in these containers.\n if (!/(^|\\/)(media|embeddings|fonts|Pictures|ObjectReplacements)\\//i.test(name)) continue\n const ext = basename.split('.').pop()?.toLowerCase() ?? 'bin'\n payloads.push({\n bytes: await entry.async('uint8array'),\n mimeType: EXT_MIME[ext] ?? 'application/octet-stream',\n filename: basename,\n })\n }\n if (payloads.length === 0) fail(verb, 'no embedded assets matched the requested types')\n return { kind: 'media-list', payloads }\n}\n\n// ── convert ──────────────────────────────────────────────────────────────────\n\n/** `convert` — dispatch through the engine registry (direct edge or computed path). */\nexport const convertStep: StepImpl = async (ctx) => {\n const verb = 'convert'\n const to = argOf<string>(ctx.step, 'to') as string\n const supported = ctx.engines.convertTargets(ctx.payload.mimeType)\n if (!supported.includes(to)) {\n fail(\n verb,\n `no configured engine (or computed path) can produce \"${to}\" from ${ctx.payload.mimeType}; reachable targets: ${supported.join(', ') || '(none)'}`\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to,\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'the conversion produced no output')\n const dot = ctx.payload.filename.lastIndexOf('.')\n const base = dot > 0 ? ctx.payload.filename.slice(0, dot) : ctx.payload.filename\n return {\n kind: 'media',\n payload: { bytes: output!.bytes, mimeType: output!.mimeType, filename: `${base}.${to}` },\n }\n}\n\n/** The doc step registry fragment (overrides the Phase 0 text-only redact/update_text). */\nexport const DOC_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['redact', docRedactStep],\n ['sanitize', docSanitizeStep],\n ['normalize', docNormalizeStep],\n ['update_text', docUpdateTextStep],\n ['extract.assets', extractAssetsStep],\n ['convert', convertStep],\n]\n","/**\n * `sheet.*` step implementations: ExcelJS workbook mutations on in-memory bytes.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * sheet adapters (its green e2e suite informs the spec coverage). All ten mutations operate on\n * xlsx natively via ExcelJS (optional peer, lazily imported); ODS and legacy-xls inputs are\n * normalized to xlsx first through the configured `sheetNormalize` engine, degrading to a\n * readable failure when none is configured. Output is always xlsx.\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, replaceExtension, unsupportedForMutationReason } from '../formats'\nimport type { MediaArgJson } from '../plan'\nimport type { default as ExcelJSNS } from 'exceljs'\nimport type { StepImpl, StepContext, StepPayload } from '../runtime'\n\ntype ExcelJSModule = typeof ExcelJSNS\n\nlet excelPromise: Promise<ExcelJSModule> | undefined\nconst excel = (): Promise<ExcelJSModule> => {\n excelPromise ??= import('exceljs').then((m) => ('default' in m ? m.default : m) as ExcelJSModule)\n return excelPromise\n}\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n/** Acquire xlsx bytes for the step, converting ODS/xls to xlsx via the engine registry. */\nconst acquireXlsx = async (ctx: StepContext, verb: string): Promise<Uint8Array> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime === MIME.XLSX) return ctx.payload.bytes\n const mutationBlock = unsupportedForMutationReason(mime)\n if (mime === MIME.ODS || mime === MIME.XLS) {\n if (!ctx.engines.hasConvert(mime, 'xlsx')) {\n fail(\n verb,\n `this input is ${mime} — an engine that converts it to xlsx is required first, and none is configured. Do not retry this verb on this media in this deployment.`\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'xlsx',\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'normalizing the workbook to xlsx produced no output')\n return output!.bytes\n }\n if (mutationBlock) fail(verb, mutationBlock)\n fail(verb, `sheet operations expect a spreadsheet; the media is ${mime}`)\n /* unreachable */ throw new Error('unreachable')\n}\n\ninterface MutationSummary {\n added?: number\n removed?: number\n modified?: number\n warnings?: string[]\n}\n\n/** The shared open → mutate → write-back lifecycle every sheet verb uses. */\nconst withWorkbook = async (\n ctx: StepContext,\n verb: string,\n mutate: (wb: ExcelJSNS.Workbook) => MutationSummary | Promise<MutationSummary>\n): Promise<{ kind: 'media'; payload: StepPayload }> => {\n const xlsxBytes = await acquireXlsx(ctx, verb)\n const ExcelJS = await excel()\n const wb = new ExcelJS.Workbook()\n try {\n await wb.xlsx.load(\n xlsxBytes.buffer.slice(\n xlsxBytes.byteOffset,\n xlsxBytes.byteOffset + xlsxBytes.byteLength\n ) as ArrayBuffer\n )\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the spreadsheet: ${detail}`)\n }\n await mutate(wb)\n const out = new Uint8Array(await wb.xlsx.writeBuffer())\n return {\n kind: 'media',\n payload: {\n bytes: out,\n mimeType: MIME.XLSX,\n filename: replaceExtension(ctx.payload.filename, 'xlsx'),\n },\n }\n}\n\n/** Resolve the target worksheet from the frozen `sheet=` rule (bare number=index, string=name). */\nconst resolveSheet = (\n verb: string,\n wb: ExcelJSNS.Workbook,\n sheetArg: string | number | undefined\n): ExcelJSNS.Worksheet => {\n if (sheetArg === undefined) {\n const first = wb.worksheets[0]\n if (!first) fail(verb, 'the workbook has no worksheets')\n return first\n }\n // Frozen 0.11: bare number targets by 1-based index; quoted string targets by name.\n if (typeof sheetArg === 'number') {\n const byIndex = wb.worksheets[sheetArg - 1]\n if (byIndex) return byIndex\n const byName = wb.getWorksheet(String(sheetArg))\n if (byName) {\n fail(\n verb,\n `no sheet at index ${sheetArg}, but a sheet NAMED \"${sheetArg}\" exists — quote it: sheet=\"${sheetArg}\"`\n )\n }\n fail(\n verb,\n `sheet index ${sheetArg} is out of range (1-based; the workbook has ${wb.worksheets.length})`\n )\n }\n const ws = wb.getWorksheet(sheetArg as string)\n if (!ws) {\n const names = wb.worksheets.map((w) => `\"${w.name}\"`).join(', ')\n fail(verb, `no sheet named \"${sheetArg}\". Sheets: ${names}`)\n }\n return ws!\n}\n\nconst columnLetterToNumber = (col: string): number => {\n let n = 0\n for (const ch of col.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64)\n return n\n}\n\ntype CellValue = string | number | boolean | null\n\nconst asCellValue = (verb: string, value: unknown): ExcelJSNS.CellValue => {\n if (value === null) return null\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return value\n }\n fail(verb, `cell values must be string, number, boolean, or null; got ${typeof value}`)\n /* unreachable */ throw new Error('unreachable')\n}\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `sheet.add_rows` — insert rows before/after an index, or append. */\nexport const sheetAddRowsStep: StepImpl = async (ctx) => {\n const verb = 'sheet add_rows'\n const rows = ctx.step.args.rows as MediaArgJson\n if (!Array.isArray(rows) || rows.length === 0 || !rows.every(Array.isArray)) {\n fail(verb, `rows must be a non-empty JSON array of arrays, e.g. rows='[[\"a\",1]]'`)\n }\n const before = argOf<number>(ctx.step, 'before')\n const after = argOf<number>(ctx.step, 'after')\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n const insertAt =\n before !== undefined ? before : after !== undefined ? after + 1 : ws.rowCount + 1\n const cellRows = (rows as unknown[][]).map((r) => r.map((v) => asCellValue(verb, v)))\n ws.spliceRows(insertAt, 0, ...cellRows)\n return { added: cellRows.length }\n })\n}\n\n/** `sheet.add_columns` — insert columns with headers or full descriptors. */\nexport const sheetAddColumnsStep: StepImpl = async (ctx) => {\n const verb = 'sheet add_columns'\n const headers = ctx.step.args.headers as string[] | undefined\n const columnsJson = ctx.step.args.columns as MediaArgJson | undefined\n const columns: Array<{ header: string; values?: CellValue[] }> | undefined =\n (columnsJson as Array<{ header: string; values?: CellValue[] }> | undefined) ??\n headers?.map((header) => ({ header }) as { header: string; values?: CellValue[] })\n if (!Array.isArray(columns) || columns.length === 0) {\n fail(verb, `provide headers=a,b or columns='[{\"header\":\"X\",\"values\":[1]}]'`)\n }\n const before = argOf<number>(ctx.step, 'before')\n const after = argOf<number>(ctx.step, 'after')\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n const insertAt =\n before !== undefined ? before : after !== undefined ? after + 1 : ws.columnCount + 1\n for (const [i, col] of columns!.entries()) {\n if (typeof col?.header !== 'string') fail(verb, 'every column needs a string header')\n ws.spliceColumns(insertAt + i, 0, [\n col.header,\n ...(col.values ?? []).map((v) => asCellValue(verb, v)),\n ])\n }\n return { added: columns!.length }\n })\n}\n\n/** `sheet.update_cells` — set cells by A1 address or row/col. Leading `=` writes a formula. */\nexport const sheetUpdateCellsStep: StepImpl = async (ctx) => {\n const verb = 'sheet update_cells'\n const updates = ctx.step.args.updates as MediaArgJson\n if (!Array.isArray(updates) || updates.length === 0) {\n fail(\n verb,\n `updates must be a non-empty JSON array, e.g. updates='[{\"address\":\"B2\",\"value\":3}]'`\n )\n }\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n let modified = 0\n for (const raw of updates as Array<Record<string, unknown>>) {\n const address = raw.address as string | undefined\n const row = raw.row as number | undefined\n const col = raw.col as number | string | undefined\n let cell: ExcelJSNS.Cell\n if (address) {\n cell = ws.getCell(address)\n } else if (row !== undefined && col !== undefined) {\n cell =\n typeof col === 'string'\n ? ws.getCell(row, columnLetterToNumber(col))\n : ws.getCell(row, col)\n } else {\n fail(verb, 'each update needs address, or both row and col')\n continue\n }\n const value = raw.value\n if (typeof value === 'string' && value.startsWith('=')) {\n cell.value = { formula: value.slice(1) } as ExcelJSNS.CellValue\n } else {\n cell.value = asCellValue(verb, value)\n }\n modified += 1\n }\n return { modified }\n })\n}\n\n/** `sheet.delete_rows` — delete 1-based rows (bottom-up so indices stay valid). */\nexport const sheetDeleteRowsStep: StepImpl = async (ctx) => {\n const verb = 'sheet delete_rows'\n const rows = ctx.step.args.rows as number[]\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n for (const r of [...rows].sort((a, b) => b - a)) ws.spliceRows(r, 1)\n return { removed: rows.length }\n })\n}\n\n/** `sheet.delete_columns` — delete 1-based columns. */\nexport const sheetDeleteColumnsStep: StepImpl = async (ctx) => {\n const verb = 'sheet delete_columns'\n const columns = ctx.step.args.columns as number[]\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n for (const c of [...columns].sort((a, b) => b - a)) ws.spliceColumns(c, 1)\n return { removed: columns.length }\n })\n}\n\n/** `sheet.rename_sheet` — rename by NAME (the server contract; index targeting is rejected). */\nexport const sheetRenameSheetStep: StepImpl = async (ctx) => {\n const verb = 'sheet rename_sheet'\n const sheet = argOf<string | number>(ctx.step, 'sheet') as string\n const to = argOf<string>(ctx.step, 'to') as string\n return withWorkbook(ctx, verb, (wb) => {\n const ws = wb.getWorksheet(sheet)\n if (!ws) {\n const names = wb.worksheets.map((w) => `\"${w.name}\"`).join(', ')\n fail(verb, `rename targets a sheet NAME; no sheet named \"${sheet}\". Sheets: ${names}`)\n }\n ws!.name = to\n return { modified: 1 }\n })\n}\n\n/** `sheet.add_sheet` — add a worksheet, optionally at a 1-based position. */\nexport const sheetAddSheetStep: StepImpl = async (ctx) => {\n const verb = 'sheet add_sheet'\n const name = argOf<string>(ctx.step, 'name') as string\n const at = argOf<number>(ctx.step, 'at')\n return withWorkbook(ctx, verb, (wb) => {\n if (wb.getWorksheet(name)) fail(verb, `a sheet named \"${name}\" already exists`)\n const ws = wb.addWorksheet(name)\n if (at !== undefined) {\n const all = wb.worksheets\n const wsIdx = all.indexOf(ws)\n if (wsIdx !== at - 1) {\n all.forEach((w, i) => {\n ;(w as unknown as { orderNo: number }).orderNo =\n w === ws ? at : i + 1 >= at && i < wsIdx ? i + 2 : i + 1\n })\n }\n }\n return { added: 1 }\n })\n}\n\n/** `sheet.remove_sheet` — remove by NAME (the server contract). */\nexport const sheetRemoveSheetStep: StepImpl = async (ctx) => {\n const verb = 'sheet remove_sheet'\n const sheet = argOf<string | number>(ctx.step, 'sheet') as string\n return withWorkbook(ctx, verb, (wb) => {\n const ws = wb.getWorksheet(sheet)\n if (!ws) {\n const names = wb.worksheets.map((w) => `\"${w.name}\"`).join(', ')\n fail(verb, `remove targets a sheet NAME; no sheet named \"${sheet}\". Sheets: ${names}`)\n }\n wb.removeWorksheet(ws!.id)\n return { removed: 1 }\n })\n}\n\n/** `sheet.reorder_sheets` — every sheet exactly once, by name or 1-based index. */\nexport const sheetReorderSheetsStep: StepImpl = async (ctx) => {\n const verb = 'sheet reorder_sheets'\n const order = ctx.step.args.order as MediaArgJson\n if (!Array.isArray(order) || order.length === 0) {\n fail(verb, `order must be a JSON array of names/indices, e.g. order='[\"Summary\",2]'`)\n }\n return withWorkbook(ctx, verb, (wb) => {\n const refs = order as Array<string | number>\n if (refs.length !== wb.worksheets.length) {\n fail(\n verb,\n `order must include every worksheet exactly once (the workbook has ${wb.worksheets.length})`\n )\n }\n const reordered: ExcelJSNS.Worksheet[] = []\n const seen = new Set<number>()\n for (const ref of refs) {\n const ws = typeof ref === 'number' ? wb.worksheets[ref - 1] : wb.getWorksheet(ref)\n if (!ws) fail(verb, `sheet not found: ${String(ref)}`)\n if (seen.has(ws!.id)) fail(verb, `duplicate sheet reference: ${String(ref)}`)\n seen.add(ws!.id)\n reordered.push(ws!)\n }\n // ExcelJS serializes by orderNo; the worksheets getter returns a sorted clone.\n reordered.forEach((ws, i) => {\n ;(ws as unknown as { orderNo: number }).orderNo = i + 1\n })\n return { modified: reordered.length }\n })\n}\n\n/** `sheet.transform_table` — rename/select/drop columns by header name. */\nexport const sheetTransformTableStep: StepImpl = async (ctx) => {\n const verb = 'sheet transform_table'\n const headerRow = argOf<number>(ctx.step, 'header_row') ?? 1\n const rename = ctx.step.args.rename as Array<{ from: string; to: string }> | undefined\n const select = ctx.step.args.select as string[] | undefined\n const drop = ctx.step.args.drop as string[] | undefined\n return withWorkbook(ctx, verb, (wb) => {\n const ws = resolveSheet(verb, wb, argOf<string | number>(ctx.step, 'sheet'))\n let modified = 0\n const headerMap = new Map<string, number>()\n ws.getRow(headerRow).eachCell({ includeEmpty: false }, (cell, colNumber) => {\n if (typeof cell.value === 'string') headerMap.set(cell.value, colNumber)\n })\n if (rename) {\n for (const { from, to } of rename) {\n const colNum = headerMap.get(from)\n if (colNum !== undefined) {\n ws.getRow(headerRow).getCell(colNum).value = to\n headerMap.delete(from)\n headerMap.set(to, colNum)\n modified += 1\n }\n }\n }\n if (drop) {\n const cols = drop\n .map((name) => headerMap.get(name))\n .filter((n): n is number => n !== undefined)\n .sort((a, b) => b - a)\n for (const col of cols) {\n ws.spliceColumns(col, 1)\n modified += 1\n }\n }\n if (select) {\n const keep = new Set(select)\n const cols: number[] = []\n ws.getRow(headerRow).eachCell({ includeEmpty: false }, (cell, colNumber) => {\n if (typeof cell.value === 'string' && !keep.has(cell.value)) cols.push(colNumber)\n })\n cols.sort((a, b) => b - a)\n for (const col of cols) {\n ws.spliceColumns(col, 1)\n modified += 1\n }\n }\n return { modified }\n })\n}\n\n/** The sheet step registry fragment, keyed by canonical verb id. */\nexport const SHEET_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['sheet.add_rows', sheetAddRowsStep],\n ['sheet.add_columns', sheetAddColumnsStep],\n ['sheet.update_cells', sheetUpdateCellsStep],\n ['sheet.delete_rows', sheetDeleteRowsStep],\n ['sheet.delete_columns', sheetDeleteColumnsStep],\n ['sheet.rename_sheet', sheetRenameSheetStep],\n ['sheet.add_sheet', sheetAddSheetStep],\n ['sheet.remove_sheet', sheetRemoveSheetStep],\n ['sheet.reorder_sheets', sheetReorderSheetsStep],\n ['sheet.transform_table', sheetTransformTableStep],\n]\n","/**\n * `slides.*` step implementations: native PPTX container mutation via JSZip + targeted XML\n * edits, on in-memory bytes.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * slides adapters (regex-over-zip XML surgery — no XML parser dependency). PPTX is mutated\n * natively; ODP inputs are normalized to PPTX through the configured `convert` engine first,\n * degrading to a readable failure when none is configured. All implementations are\n * cross-environment (jszip operates on Uint8Array).\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, replaceExtension, unsupportedForMutationReason } from '../formats'\nimport type { default as JSZipNS } from 'jszip'\nimport type { MediaRef, MediaArgJson } from '../plan'\nimport type { StepImpl, StepContext, StepPayload } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst SLIDE_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n// ── XML helpers (ported verbatim semantics) ──────────────────────────────────\n\nconst escapeXml = (value: string): string =>\n value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n/** Pure posix-style path resolution for zip entries (no node:path). */\nconst resolveZipPath = (basePart: string, relTarget: string): string => {\n const baseDir = basePart.split('/').slice(0, -1)\n const parts = [...baseDir, ...relTarget.split('/')]\n const out: string[] = []\n for (const part of parts) {\n if (part === '' || part === '.') continue\n if (part === '..') out.pop()\n else out.push(part)\n }\n return out.join('/')\n}\n\ninterface SlideEntry {\n rid: string\n slideId: number\n sldIdTag: string\n target: string\n title?: string\n}\n\ninterface ParsedPresentation {\n presentationXml: string\n relsXml: string\n entries: SlideEntry[]\n}\n\nconst readZipText = async (verb: string, zip: JSZipNS, path: string): Promise<string> => {\n const file = zip.file(path)\n if (!file) fail(verb, `the presentation is missing an expected part: ${path}`)\n return file!.async('text')\n}\n\nconst parseRelationshipTarget = (relsXml: string, relId: string): string | null => {\n const re = new RegExp(\n `<Relationship\\\\b[^>]*Id=\"${escapeRegex(relId)}\"[^>]*Target=\"([^\"]+)\"[^>]*>`,\n 'i'\n )\n return relsXml.match(re)?.[1] ?? null\n}\n\nconst parsePresentation = async (verb: string, zip: JSZipNS): Promise<ParsedPresentation> => {\n const presentationXml = await readZipText(verb, zip, 'ppt/presentation.xml')\n const relsXml = await readZipText(verb, zip, 'ppt/_rels/presentation.xml.rels')\n const sldIdListMatch = presentationXml.match(/<p:sldIdLst>([\\s\\S]*?)<\\/p:sldIdLst>/)\n if (!sldIdListMatch) fail(verb, 'the presentation has no slide list (corrupt PPTX?)')\n const sldIdTags = sldIdListMatch![1].match(/<p:sldId\\b[^>]*\\/>/g) ?? []\n const entries: SlideEntry[] = []\n for (const tag of sldIdTags) {\n const rid = tag.match(/r:id=\"([^\"]+)\"/)?.[1]\n const idText = tag.match(/\\bid=\"(\\d+)\"/)?.[1]\n if (!rid || !idText) continue\n const target = parseRelationshipTarget(relsXml, rid)\n if (!target) continue\n const slidePath = resolveZipPath('ppt/presentation.xml', target)\n let title: string | undefined\n const slideFile = zip.file(slidePath)\n if (slideFile) {\n const slideXml = await slideFile.async('text')\n title = slideXml.match(/<p:cSld\\b[^>]*\\bname=\"([^\"]*)\"/)?.[1]\n }\n entries.push({ rid, slideId: Number(idText), sldIdTag: tag, target, title })\n }\n return { presentationXml, relsXml, entries }\n}\n\nconst replaceSlideIdList = (presentationXml: string, tags: string[]): string =>\n presentationXml.replace(\n /<p:sldIdLst>[\\s\\S]*?<\\/p:sldIdLst>/,\n `<p:sldIdLst>${tags.join('')}</p:sldIdLst>`\n )\n\n/** Resolve a slide by the frozen `slide=` rule: digits = 1-based index, otherwise title. */\nconst resolveSlide = (\n verb: string,\n entries: SlideEntry[],\n slideArg: string | number | undefined\n): SlideEntry => {\n if (slideArg === undefined) {\n const first = entries[0]\n if (!first) fail(verb, 'the presentation has no slides')\n return first\n }\n // Frozen 0.11: bare number targets by 1-based index; quoted string targets by title.\n if (typeof slideArg === 'number') {\n const found = entries[slideArg - 1]\n if (!found) {\n fail(verb, `slide index ${slideArg} is out of range (1-based; ${entries.length} slides)`)\n }\n return found!\n }\n const byTitle = entries.find((e) => e.title === slideArg)\n if (!byTitle) fail(verb, `no slide titled \"${slideArg}\"`)\n return byTitle!\n}\n\nconst getMaxRidNumber = (relsXml: string): number => {\n let max = 0\n for (const match of relsXml.matchAll(/\\bId=\"rId(\\d+)\"/g)) max = Math.max(max, Number(match[1]))\n return max\n}\n\nconst getMaxSlideNumber = (zip: JSZipNS): number => {\n let max = 0\n for (const name of Object.keys(zip.files)) {\n const match = name.match(/^ppt\\/slides\\/slide(\\d+)\\.xml$/)\n if (match) max = Math.max(max, Number(match[1]))\n }\n return max\n}\n\nconst getMaxSlideId = (entries: SlideEntry[]): number =>\n entries.reduce((max, e) => Math.max(max, e.slideId), 255)\n\nconst ensureSlideContentType = (contentTypesXml: string, slideNumber: number): string => {\n const partName = `/ppt/slides/slide${slideNumber}.xml`\n if (contentTypesXml.includes(`PartName=\"${partName}\"`)) return contentTypesXml\n const override =\n `<Override PartName=\"${partName}\" ` +\n `ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\"/>`\n return contentTypesXml.replace('</Types>', `${override}</Types>`)\n}\n\nconst setSlideTitle = (slideXml: string, title: string): string => {\n if (/<p:cSld\\b[^>]*\\bname=\"[^\"]*\"/.test(slideXml)) {\n return slideXml.replace(/(<p:cSld\\b[^>]*\\bname=\")[^\"]*(\")/, `$1${escapeXml(title)}$2`)\n }\n return slideXml\n}\n\n// ── lifecycle ────────────────────────────────────────────────────────────────\n\n/** Acquire pptx bytes, converting ODP to PPTX via the engine registry. */\nconst acquirePptx = async (ctx: StepContext, verb: string): Promise<Uint8Array> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime === MIME.PPTX) return ctx.payload.bytes\n if (mime === MIME.ODP) {\n if (!ctx.engines.hasConvert(mime, 'pptx')) {\n fail(\n verb,\n 'this input is ODP — an engine that converts it to PPTX is required first, and none is configured. Do not retry this verb on this media in this deployment.'\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'pptx',\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'normalizing the presentation to PPTX produced no output')\n return output!.bytes\n }\n const reason = unsupportedForMutationReason(mime)\n if (reason) fail(verb, reason)\n fail(verb, `slides operations expect a presentation; the media is ${mime}`)\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst withPresentation = async (\n ctx: StepContext,\n verb: string,\n mutate: (zip: JSZipNS, parsed: ParsedPresentation) => Promise<void>\n): Promise<{ kind: 'media'; payload: StepPayload }> => {\n const bytes = await acquirePptx(ctx, verb)\n const JSZip = await jszip()\n let zip: JSZipNS\n try {\n zip = await JSZip.loadAsync(bytes)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the presentation: ${detail}`)\n /* unreachable */ throw err\n }\n const parsed = await parsePresentation(verb, zip)\n await mutate(zip, parsed)\n const out = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE' })\n return {\n kind: 'media',\n payload: {\n bytes: out,\n mimeType: MIME.PPTX,\n filename: replaceExtension(ctx.payload.filename, 'pptx'),\n },\n }\n}\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `slides.add` — clone the last slide as a template, optionally retitle/position it. */\nexport const slidesAddStep: StepImpl = async (ctx) => {\n const verb = 'slides add'\n const at = argOf<number>(ctx.step, 'at')\n const title = argOf<string>(ctx.step, 'title')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (parsed.entries.length === 0) fail(verb, 'the presentation has no slides to clone from')\n const template = parsed.entries[parsed.entries.length - 1]\n const templatePath = resolveZipPath('ppt/presentation.xml', template.target)\n const templateXml = await readZipText(verb, zip, templatePath)\n const newSlideNumber = getMaxSlideNumber(zip) + 1\n const newSlidePath = `ppt/slides/slide${newSlideNumber}.xml`\n zip.file(newSlidePath, title ? setSlideTitle(templateXml, title) : templateXml)\n const templateNum = templatePath.match(/slide(\\d+)\\.xml$/)?.[1]\n const templateRels = templateNum\n ? zip.file(`ppt/slides/_rels/slide${templateNum}.xml.rels`)\n : null\n if (templateRels) {\n const relsXml = await templateRels.async('text')\n zip.file(\n `ppt/slides/_rels/slide${newSlideNumber}.xml.rels`,\n relsXml.replace(/<Relationship\\b[^>]*Type=\"[^\"]*notesSlide\"[^>]*\\/>/g, '')\n )\n }\n const newRid = `rId${getMaxRidNumber(parsed.relsXml) + 1}`\n const newSldTag = `<p:sldId id=\"${getMaxSlideId(parsed.entries) + 1}\" r:id=\"${newRid}\"/>`\n const relNode = `<Relationship Id=\"${newRid}\" Type=\"${SLIDE_REL_TYPE}\" Target=\"slides/slide${newSlideNumber}.xml\"/>`\n zip.file(\n 'ppt/_rels/presentation.xml.rels',\n parsed.relsXml.replace('</Relationships>', `${relNode}</Relationships>`)\n )\n const insertAt =\n at !== undefined\n ? Math.min(Math.max(1, at), parsed.entries.length + 1)\n : parsed.entries.length + 1\n const tags = parsed.entries.map((e) => e.sldIdTag)\n tags.splice(insertAt - 1, 0, newSldTag)\n zip.file('ppt/presentation.xml', replaceSlideIdList(parsed.presentationXml, tags))\n const contentTypes = await readZipText(verb, zip, '[Content_Types].xml')\n zip.file('[Content_Types].xml', ensureSlideContentType(contentTypes, newSlideNumber))\n })\n}\n\n/** `slides.update_text` — replace text in the first node or a named placeholder shape. */\nexport const slidesUpdateTextStep: StepImpl = async (ctx) => {\n const verb = 'slides update_text'\n const text = argOf<string>(ctx.step, 'text') as string\n const placeholder = argOf<string>(ctx.step, 'placeholder')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideXml = await readZipText(verb, zip, slidePath)\n let updated = slideXml\n let changed = false\n if (placeholder) {\n let placeholderFound = false\n updated = slideXml.replace(/<p:sp\\b[\\s\\S]*?<\\/p:sp>/g, (shapeXml) => {\n if (\n !new RegExp(`<p:cNvPr\\\\b[^>]*\\\\bname=\"${escapeRegex(placeholder)}\"[^>]*>`, 'i').test(\n shapeXml\n )\n ) {\n return shapeXml\n }\n placeholderFound = true\n return shapeXml.replace(/<a:t>[\\s\\S]*?<\\/a:t>/, () => {\n changed = true\n return `<a:t>${escapeXml(text)}</a:t>`\n })\n })\n if (!placeholderFound)\n fail(verb, `no placeholder named \"${placeholder}\" on the selected slide`)\n } else {\n updated = slideXml.replace(/<a:t>[\\s\\S]*?<\\/a:t>/, () => {\n changed = true\n return `<a:t>${escapeXml(text)}</a:t>`\n })\n }\n if (!changed) fail(verb, 'no text node found on the selected slide')\n zip.file(slidePath, updated)\n })\n}\n\n/** `slides.update_table` — set table cell text by 1-based row/col. */\nexport const slidesUpdateTableStep: StepImpl = async (ctx) => {\n const verb = 'slides update_table'\n const updates = ctx.step.args.updates as MediaArgJson\n if (!Array.isArray(updates) || updates.length === 0) {\n fail(verb, `updates must be a JSON array: updates='[{\"row\":1,\"col\":2,\"value\":\"x\"}]'`)\n }\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n let slideXml = await readZipText(verb, zip, slidePath)\n const tableMatch = slideXml.match(/<a:tbl>[\\s\\S]*?<\\/a:tbl>/)\n if (!tableMatch) fail(verb, 'no table found on the selected slide')\n let tableXml = tableMatch![0]\n const rowMatches = tableXml.match(/<a:tr\\b[\\s\\S]*?<\\/a:tr>/g) ?? []\n for (const raw of updates as Array<Record<string, unknown>>) {\n const row = Number(raw.row)\n const col = Number(raw.col)\n const value = String(raw.value ?? '')\n const rowIndex = row - 1\n const colIndex = col - 1\n if (rowIndex < 0 || colIndex < 0 || rowIndex >= rowMatches.length) {\n fail(verb, `table cell out of range: r${row}c${col} (1-based)`)\n }\n const rowXml = rowMatches[rowIndex]\n const cellMatches = rowXml.match(/<a:tc\\b[\\s\\S]*?<\\/a:tc>/g) ?? []\n if (colIndex >= cellMatches.length)\n fail(verb, `table cell out of range: r${row}c${col} (1-based)`)\n const cellXml = cellMatches[colIndex]\n if (!/<a:t>/.test(cellXml)) fail(verb, `cell r${row}c${col} has no text node`)\n cellMatches[colIndex] = cellXml.replace(\n /<a:t>[\\s\\S]*?<\\/a:t>/,\n `<a:t>${escapeXml(value)}</a:t>`\n )\n rowMatches[rowIndex] = rowXml.replace(/<a:tc\\b[\\s\\S]*?<\\/a:tc>/g, () => cellMatches.shift()!)\n }\n tableXml = tableXml.replace(/<a:tr\\b[\\s\\S]*?<\\/a:tr>/g, () => rowMatches.shift()!)\n slideXml = slideXml.replace(/<a:tbl>[\\s\\S]*?<\\/a:tbl>/, tableXml)\n zip.file(slidePath, slideXml)\n })\n}\n\n/** `slides.update_image` — replace an image part's bytes with another media (`with=@id`). */\nexport const slidesUpdateImageStep: StepImpl = async (ctx) => {\n const verb = 'slides update_image'\n const ref = ctx.step.args.with as MediaRef\n const placeholder = argOf<string>(ctx.step, 'placeholder')\n if (ref.kind !== 'id') fail(verb, 'builder refs are not supported here; use an @id ref')\n const replacement = await ctx.resolveRef((ref as { kind: 'id'; id: string }).id)\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideXml = await readZipText(verb, zip, slidePath)\n const slideNum = slidePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (!slideNum) fail(verb, 'unable to resolve the slide number (corrupt PPTX?)')\n const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`\n const relsXml = await readZipText(verb, zip, relsPath)\n let imagePartPath: string | null = null\n if (placeholder) {\n for (const picXml of slideXml.match(/<p:pic\\b[\\s\\S]*?<\\/p:pic>/g) ?? []) {\n if (\n !new RegExp(`<p:cNvPr\\\\b[^>]*\\\\bname=\"${escapeRegex(placeholder)}\"[^>]*>`, 'i').test(\n picXml\n )\n ) {\n continue\n }\n const rid = picXml.match(/<a:blip\\b[^>]*\\br:embed=\"([^\"]+)\"/i)?.[1]\n if (rid) {\n const relTarget = parseRelationshipTarget(relsXml, rid)\n if (relTarget) imagePartPath = resolveZipPath(relsPath, relTarget)\n }\n break\n }\n if (!imagePartPath)\n fail(verb, `no image placeholder named \"${placeholder}\" on the selected slide`)\n } else {\n const fallback = relsXml.match(\n /<Relationship\\b[^>]*Type=\"[^\"]*\\/image\"[^>]*Target=\"([^\"]+)\"[^>]*>/i\n )\n if (fallback) imagePartPath = resolveZipPath(relsPath, fallback[1])\n }\n if (!imagePartPath) fail(verb, 'no image relationship found on the selected slide')\n zip.file(imagePartPath!, replacement.bytes)\n })\n}\n\n/** `slides.update_chart` — overwrite the chart's cached values in document order. */\nexport const slidesUpdateChartStep: StepImpl = async (ctx) => {\n const verb = 'slides update_chart'\n const data = ctx.step.args.data as MediaArgJson\n if (!Array.isArray(data) || data.length === 0) {\n fail(verb, `data must be a non-empty JSON array of arrays: data='[[\"Q1\",10]]'`)\n }\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideNum = slidePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (!slideNum) fail(verb, 'unable to resolve the slide number (corrupt PPTX?)')\n const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`\n const relsXml = await readZipText(verb, zip, relsPath)\n const chartRel = relsXml.match(\n /<Relationship\\b[^>]*Type=\"[^\"]*\\/chart\"[^>]*Target=\"([^\"]+)\"[^>]*>/i\n )\n if (!chartRel) fail(verb, 'no chart found on the selected slide')\n const chartPath = resolveZipPath(relsPath, chartRel![1])\n let chartXml = await readZipText(verb, zip, chartPath)\n const values = (data as unknown[][]).flat().map((v) => String(v))\n let replaced = 0\n chartXml = chartXml.replace(/<c:v>[\\s\\S]*?<\\/c:v>/g, (full) => {\n if (replaced >= values.length) return full\n const next = `<c:v>${escapeXml(values[replaced])}</c:v>`\n replaced += 1\n return next\n })\n if (replaced === 0) fail(verb, 'the chart has no cached values to update')\n zip.file(chartPath, chartXml)\n })\n}\n\n/** `slides.delete` — remove slides by 1-based index (cannot remove all). */\nexport const slidesDeleteStep: StepImpl = async (ctx) => {\n const verb = 'slides delete'\n const slides = ctx.step.args.slides as number[]\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const unique = [...new Set(slides)]\n for (const index of unique) {\n if (!Number.isInteger(index) || index < 1 || index > parsed.entries.length) {\n fail(\n verb,\n `slide index ${index} is out of range (1-based; ${parsed.entries.length} slides)`\n )\n }\n }\n const toDelete = new Set(unique)\n const kept = parsed.entries.filter((_, idx) => !toDelete.has(idx + 1))\n if (kept.length === 0) fail(verb, 'cannot delete every slide in the presentation')\n zip.file(\n 'ppt/presentation.xml',\n replaceSlideIdList(\n parsed.presentationXml,\n kept.map((e) => e.sldIdTag)\n )\n )\n let relsXml = parsed.relsXml\n parsed.entries.forEach((entry, idx) => {\n if (!toDelete.has(idx + 1)) return\n const targetPath = resolveZipPath('ppt/presentation.xml', entry.target)\n zip.remove(targetPath)\n const slideNum = targetPath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (slideNum) zip.remove(`ppt/slides/_rels/slide${slideNum}.xml.rels`)\n relsXml = relsXml.replace(\n new RegExp(`<Relationship\\\\b[^>]*Id=\"${entry.rid}\"[^>]*/>`, 'g'),\n ''\n )\n })\n zip.file('ppt/_rels/presentation.xml.rels', relsXml)\n })\n}\n\n/** `slides.reorder` — every slide exactly once, by 1-based index. */\nexport const slidesReorderStep: StepImpl = async (ctx) => {\n const verb = 'slides reorder'\n const order = ctx.step.args.order as number[]\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (order.length !== parsed.entries.length) {\n fail(verb, `order must list all ${parsed.entries.length} slides exactly once`)\n }\n const seen = new Set<number>()\n const reordered: SlideEntry[] = []\n for (const index of order) {\n if (!Number.isInteger(index) || index < 1 || index > parsed.entries.length) {\n fail(verb, `slide index ${index} is out of range (1-based)`)\n }\n if (seen.has(index)) fail(verb, `duplicate slide index: ${index}`)\n seen.add(index)\n reordered.push(parsed.entries[index - 1])\n }\n zip.file(\n 'ppt/presentation.xml',\n replaceSlideIdList(\n parsed.presentationXml,\n reordered.map((e) => e.sldIdTag)\n )\n )\n })\n}\n\n/** `slides.duplicate` — copy a slide, optionally inserting at a position. */\nexport const slidesDuplicateStep: StepImpl = async (ctx) => {\n const verb = 'slides duplicate'\n const slide = argOf<number>(ctx.step, 'slide') as number\n const at = argOf<number>(ctx.step, 'at')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (!Number.isInteger(slide) || slide < 1 || slide > parsed.entries.length) {\n fail(verb, `slide index ${slide} is out of range (1-based; ${parsed.entries.length} slides)`)\n }\n const source = parsed.entries[slide - 1]\n const sourcePath = resolveZipPath('ppt/presentation.xml', source.target)\n const sourceXml = await readZipText(verb, zip, sourcePath)\n const newSlideNumber = getMaxSlideNumber(zip) + 1\n zip.file(`ppt/slides/slide${newSlideNumber}.xml`, sourceXml)\n const sourceNum = sourcePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (sourceNum) {\n const sourceRels = zip.file(`ppt/slides/_rels/slide${sourceNum}.xml.rels`)\n if (sourceRels) {\n const relsXml = await sourceRels.async('text')\n zip.file(\n `ppt/slides/_rels/slide${newSlideNumber}.xml.rels`,\n relsXml.replace(/<Relationship\\b[^>]*Type=\"[^\"]*notesSlide\"[^>]*\\/>/g, '')\n )\n }\n }\n const newRid = `rId${getMaxRidNumber(parsed.relsXml) + 1}`\n const newTag = `<p:sldId id=\"${getMaxSlideId(parsed.entries) + 1}\" r:id=\"${newRid}\"/>`\n const relNode = `<Relationship Id=\"${newRid}\" Type=\"${SLIDE_REL_TYPE}\" Target=\"slides/slide${newSlideNumber}.xml\"/>`\n zip.file(\n 'ppt/_rels/presentation.xml.rels',\n parsed.relsXml.replace('</Relationships>', `${relNode}</Relationships>`)\n )\n const targetPos =\n at !== undefined ? Math.min(Math.max(1, at), parsed.entries.length + 1) : slide + 1\n const tags = parsed.entries.map((e) => e.sldIdTag)\n tags.splice(targetPos - 1, 0, newTag)\n zip.file('ppt/presentation.xml', replaceSlideIdList(parsed.presentationXml, tags))\n const contentTypes = await readZipText(verb, zip, '[Content_Types].xml')\n zip.file('[Content_Types].xml', ensureSlideContentType(contentTypes, newSlideNumber))\n })\n}\n\n/** Count slides in pptx bytes — exported for spec assertions. */\nexport const countSlides = async (bytes: Uint8Array): Promise<number> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(bytes)\n const parsed = await parsePresentation('slides', zip)\n return parsed.entries.length\n}\n\n/** The slides step registry fragment, keyed by canonical verb id. */\nexport const SLIDES_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['slides.add', slidesAddStep],\n ['slides.update_text', slidesUpdateTextStep],\n ['slides.update_table', slidesUpdateTableStep],\n ['slides.update_image', slidesUpdateImageStep],\n ['slides.update_chart', slidesUpdateChartStep],\n ['slides.delete', slidesDeleteStep],\n ['slides.reorder', slidesReorderStep],\n ['slides.duplicate', slidesDuplicateStep],\n]\n","/**\n * Ingest-depth step extensions: the unified `extract.text` format dispatch (PDF text layer,\n * DOCX via mammoth, XLSX via ExcelJS, ODT/ODS via ODF XML, PPTX via slide XML, images via the\n * OCR engine) and format-aware `extract.metadata`.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * four extractors, collapsed into one verb that routes on the resolved media's format family\n * (the single biggest order-out-of-chaos win — the model says `extract text` and doesn't care\n * what the container is). OCR runs through the configured `ocr` engine when the input is an\n * image, or when a PDF has no text layer with `ocr=auto`, or always with `ocr=force`.\n */\n\nimport { argOf } from '../runtime'\nimport { decodeText } from './text'\nimport { isError } from '@nhtio/adk/guards'\nimport { MIME, familyOf } from '../formats'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport type { default as JSZipNS } from 'jszip'\nimport type { default as ExcelJSNS } from 'exceljs'\nimport type { StepImpl, StepContext } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\nconst VERB = 'extract text'\n\n// ── per-format extraction ────────────────────────────────────────────────────\n\nconst extractPdfText = async (ctx: StepContext): Promise<string> => {\n const { PDFParse } = await import('pdf-parse')\n try {\n const parser = new PDFParse({ data: ctx.payload.bytes })\n const result = await parser.getText()\n return result.text ?? ''\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(VERB, `could not read the PDF: ${detail}`)\n /* unreachable */ throw err\n }\n}\n\nconst extractDocxText = async (ctx: StepContext): Promise<string> => {\n const mod = await import('mammoth')\n const mammoth = ('extractRawText' in mod ? mod : (mod as { default: unknown }).default) as {\n extractRawText: (input: Record<string, unknown>) => Promise<{ value: string }>\n }\n const bytes = ctx.payload.bytes\n // mammoth's Node entry expects { buffer: Buffer }; its browser entry expects { arrayBuffer }.\n const input =\n typeof globalThis.Buffer !== 'undefined'\n ? { buffer: globalThis.Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength) }\n : {\n arrayBuffer: bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength\n ) as ArrayBuffer,\n }\n const result = await mammoth.extractRawText(input)\n return result.value\n}\n\nconst extractXlsxText = async (ctx: StepContext): Promise<string> => {\n const mod = await import('exceljs')\n const ExcelJS = ('default' in mod ? mod.default : mod) as typeof ExcelJSNS\n const wb = new ExcelJS.Workbook()\n await wb.xlsx.load(\n ctx.payload.bytes.buffer.slice(\n ctx.payload.bytes.byteOffset,\n ctx.payload.bytes.byteOffset + ctx.payload.bytes.byteLength\n ) as ArrayBuffer\n )\n const lines: string[] = []\n for (const ws of wb.worksheets) {\n lines.push(`# ${ws.name}`)\n ws.eachRow({ includeEmpty: false }, (row) => {\n const cells: string[] = []\n row.eachCell({ includeEmpty: false }, (cell) => {\n cells.push(String(cell.value ?? ''))\n })\n lines.push(cells.join('\\t'))\n })\n }\n return lines.join('\\n')\n}\n\n/** ODF content.xml → visible text (ported transformation order). */\nconst extractOdfXmlText = (xml: string): string =>\n xml\n .replace(/<\\/text:p>/g, '\\n')\n .replace(/<\\/text:h>/g, '\\n')\n .replace(/<\\/table:table-row>/g, '\\n')\n .replace(/<text:tab[^>]*\\/>/g, '\\t')\n .replace(/<text:line-break[^>]*\\/>/g, '\\n')\n .replace(/<[^>]+>/g, '')\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\nconst extractOdfText = async (ctx: StepContext): Promise<string> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const content = zip.file('content.xml')\n if (!content) fail(VERB, 'the ODF archive is missing content.xml (corrupt file?)')\n return extractOdfXmlText(await content!.async('text'))\n}\n\nconst extractPptxText = async (ctx: StepContext): Promise<string> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const slideNames = Object.keys(zip.files)\n .filter((n) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n))\n .sort((a, b) => {\n const na = Number(a.match(/slide(\\d+)/)?.[1] ?? 0)\n const nb = Number(b.match(/slide(\\d+)/)?.[1] ?? 0)\n return na - nb\n })\n if (slideNames.length === 0) fail(VERB, 'the presentation has no slides')\n const parts: string[] = []\n for (const name of slideNames) {\n const xml = await zip.file(name)!.async('text')\n const texts = (xml.match(/<a:t>([^<]*)<\\/a:t>/g) ?? []).map((t) =>\n t\n .replace(/<[^>]+>/g, '')\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n )\n parts.push(texts.join('\\n'))\n }\n return parts.join('\\n\\n')\n}\n\nconst runOcr = async (ctx: StepContext): Promise<string> => {\n const out = (argOf<string>(ctx.step, 'ocr_out') ?? 'txt') as 'txt' | 'hocr' | 'json'\n if (!ctx.engines.hasConvert(ctx.payload.mimeType, out)) {\n fail(\n VERB,\n `this input requires OCR, and no engine that converts ${ctx.payload.mimeType} to \"${out}\" is configured. Do not retry this verb on this media in this deployment.`\n )\n }\n const langArg = ctx.step.args.lang as string[] | string | undefined\n const languages = langArg === undefined ? undefined : Array.isArray(langArg) ? langArg : [langArg]\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to: out,\n options: { languages },\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(VERB, 'OCR produced no output')\n return new TextDecoder().decode(output!.bytes)\n}\n\n// ── the unified step ─────────────────────────────────────────────────────────\n\n/**\n * `extract.text` — full format dispatch. Routes by MIME, with OCR engine fallback for images\n * and force-OCR for any input via `ocr=force`.\n */\nexport const extractTextDeepStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const ocrMode = argOf<string>(ctx.step, 'ocr') ?? 'auto'\n\n const asData = (text: string): { kind: 'data'; data: string; asText: string } => ({\n kind: 'data',\n data: text,\n asText: text,\n })\n\n if (mime.startsWith('image/')) return asData(await runOcr(ctx))\n\n if (ocrMode === 'force') return asData(await runOcr(ctx))\n\n if (mime === MIME.PDF) {\n const text = await extractPdfText(ctx)\n if (text.trim().length === 0 && ocrMode === 'auto') {\n // Scanned PDF: no text layer. OCR-from-PDF is engine territory (the engine must accept\n // application/pdf); surface the actionable path instead of silently returning nothing.\n if (!ctx.engines.hasConvert(mime, 'txt')) {\n fail(\n VERB,\n 'this PDF has no text layer (scanned?). An engine that converts application/pdf to text (OCR) is required to read it, and none is configured. Do not retry this verb on this media in this deployment.'\n )\n }\n return asData(await runOcr(ctx))\n }\n return asData(text)\n }\n if (mime === MIME.DOCX || mime === MIME.DOC) return asData(await extractDocxText(ctx))\n if (mime === MIME.XLSX) return asData(await extractXlsxText(ctx))\n if (mime === MIME.ODT || mime === MIME.ODS || mime === MIME.ODP) {\n return asData(await extractOdfText(ctx))\n }\n if (mime === MIME.PPTX) return asData(await extractPptxText(ctx))\n if (mime.startsWith('text/') || mime === MIME.JSON) {\n return asData(decodeText(ctx.payload.bytes))\n }\n fail(\n VERB,\n `text extraction for ${mime} is not supported in this build. For PPT/legacy formats: convert to=pptx | extract text (requires a convert engine).`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\n/** `extract.metadata` — format-aware metadata (page counts, sheet/slide inventories). */\nexport const extractMetadataDeepStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const meta: Record<string, unknown> = {\n filename: ctx.payload.filename,\n mime_type: ctx.payload.mimeType,\n size_bytes: ctx.payload.bytes.byteLength,\n family: familyOf(ctx.payload.mimeType),\n }\n try {\n if (mime === MIME.PDF) {\n const { PDFDocument } = await import('pdf-lib')\n const doc = await PDFDocument.load(ctx.payload.bytes, { ignoreEncryption: true })\n meta.page_count = doc.getPageCount()\n meta.title = doc.getTitle() ?? undefined\n meta.author = doc.getAuthor() ?? undefined\n } else if (mime === MIME.XLSX) {\n const mod = await import('exceljs')\n const ExcelJS = ('default' in mod ? mod.default : mod) as typeof ExcelJSNS\n const wb = new ExcelJS.Workbook()\n await wb.xlsx.load(\n ctx.payload.bytes.buffer.slice(\n ctx.payload.bytes.byteOffset,\n ctx.payload.bytes.byteOffset + ctx.payload.bytes.byteLength\n ) as ArrayBuffer\n )\n meta.sheets = wb.worksheets.map((ws) => ({ name: ws.name, rows: ws.rowCount }))\n } else if (mime === MIME.PPTX) {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n meta.slide_count = Object.keys(zip.files).filter((n) =>\n /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n)\n ).length\n }\n } catch {\n // Metadata enrichment is best-effort; the basics above always report.\n }\n return { kind: 'data', data: meta, asText: JSON.stringify(meta) }\n}\n\n/** The ingest step registry fragment (overrides the Phase 0 native-text-only versions). */\nexport const INGEST_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['extract.text', extractTextDeepStep],\n ['extract.metadata', extractMetadataDeepStep],\n]\n","/**\n * The engine registry: capability-filtered, middleware-arbitrated, ordered dispatch over the\n * pipeline's engine array.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry (re-exported through the barrel).\n * One selection rule everywhere: gather every engine whose declarations match the request\n * (capability filter), run the consumer's selection onion (stages may exclude or reorder\n * candidates, never add), then the first survivor in supply order wins.\n *\n * Convert dispatch additionally computes multi-hop paths: when no single engine declares a\n * direct edge for the requested (input, target) pair, a breadth-first search over the format\n * graph finds the shortest chain of hops (capped at {@link MAX_HOPS}), with supply order\n * breaking ties at equal length. Pathfinding explores capability declarations only — cheap\n * and synchronous; the selection onion runs once per executed hop with real bytes in hand.\n */\n\nimport { EXT_TO_MIME } from './formats'\nimport { Middleware } from '@nhtio/middleware'\nimport type { NextFn } from '@nhtio/middleware'\nimport type { CapabilityProbe } from './validate'\nimport type {\n MediaEngine,\n ConvertRequest,\n ConvertResult,\n ConvertCapability,\n MutateRequest,\n MutateCapability,\n EngineBytesResult,\n} from './contracts'\n\n/** The maximum number of conversion hops a computed path may take. */\nconst MAX_HOPS = 3\n\n/**\n * Format tokens that are valid conversion endpoints but never intermediate path nodes.\n * Without this rule the pathfinder would happily route `docx → txt → …` (lossy garbage in,\n * garbage out) or auto-chain `audio → pcm → txt` (skipping the resample the transcription\n * step performs between those legs).\n */\nconst TERMINAL_TOKENS: ReadonlySet<string> = new Set([\n 'txt',\n 'json',\n 'hocr',\n 'srt',\n 'vtt',\n 'md',\n 'csv',\n 'pcm',\n 'images',\n])\n\n/** Normalize a MIME type for comparison (lowercase, parameters stripped). */\nconst normalizeMime = (mimeType: string): string => mimeType.toLowerCase().split(';')[0].trim()\n\n/** `true` when `mime` matches `pattern` (exact, or a `family/*` wildcard). */\nconst matchesMime = (pattern: string, mime: string): boolean => {\n const p = pattern.toLowerCase()\n if (p.endsWith('/*')) return mime.startsWith(p.slice(0, -1))\n return p === mime\n}\n\n/** `true` when any pattern in `patterns` matches `mime`. */\nconst matchesAny = (patterns: readonly string[], mime: string): boolean =>\n patterns.some((p) => matchesMime(p, mime))\n\n/**\n * The request summary a selection stage sees: enough to implement content- and\n * format-dependent rules without exposing dispatch internals.\n */\nexport interface EngineSelectionContext {\n /** Which capability is being dispatched. */\n kind: 'convert' | 'mutate'\n /** The dispatch request (for convert under multi-hop, the CURRENT hop's input/target). */\n request: {\n /** The input MIME type. */\n mimeType: string\n /** The input filename. */\n filename: string\n /** The input bytes — content-dependent rules (e.g. workbook complexity) need them. */\n bytes: Uint8Array\n /** The convert target token, or the mutate `format.to` when a re-encode was requested. */\n to?: string\n /** The requested mutate operations. */\n ops?: readonly string[]\n }\n /**\n * The capable engines, in supply order. Stages may exclude or reorder (mutate in place or\n * reassign); survivors are re-filtered against the original capable set, so a stage can\n * never add an engine the capability filter rejected.\n */\n candidates: MediaEngine[]\n}\n\n/**\n * A selection-middleware stage — the seam for quality heuristics and implementor overrides\n * when several engines can perform the same transform (e.g. route complex workbooks past a\n * pure-JS converter to LibreOffice). Same onion shape as the battery's `use` interceptors;\n * a fresh runner is minted per dispatch. Keep stages cheap or memoized: they run with bytes\n * in hand on every dispatch.\n */\nexport type EngineSelectionMiddlewareFn = (\n ctx: EngineSelectionContext,\n next: NextFn\n) => void | Promise<void>\n\n/** Ordered capability-filtered dispatch over the pipeline's engines. */\nexport interface EngineRegistry extends CapabilityProbe {\n /** The resolved engines, in supply order (inspection/debugging). */\n readonly engines: readonly MediaEngine[]\n /**\n * Every format token reachable from `fromMime` — directly or through a computed path of up\n * to three hops. Drives \"supported targets\" error messages.\n *\n * @param fromMime - The input MIME type.\n */\n convertTargets(fromMime: string): readonly string[]\n /**\n * Convert via the shortest capable path (direct edge = one hop). The selection rule picks\n * the engine for each executed hop; options are forwarded to every hop (engines ignore\n * keys they don't understand).\n *\n * @param request - The input bytes, target token, and options.\n * @returns The final hop's outputs.\n */\n convert(request: ConvertRequest): Promise<ConvertResult>\n /**\n * Apply a fused same-format transform. Candidates are engines whose `over` matches the\n * input, whose `ops` cover the requested operations, and — when a re-encode is requested —\n * whose `encodes` include the target.\n *\n * @param request - The fused operations and input bytes.\n * @returns The transformed bytes.\n */\n mutate(request: MutateRequest): Promise<EngineBytesResult>\n}\n\n/** One engine's matching capability group for a dispatch. */\ninterface ConvertCandidate {\n engine: MediaEngine\n capability: ConvertCapability\n}\ninterface MutateCandidate {\n engine: MediaEngine\n capability: MutateCapability\n}\n\n/** One hop of a computed conversion path. */\ninterface ConvertHop {\n /** The hop's input MIME. */\n fromMime: string\n /** The format token this hop produces. */\n to: string\n}\n\n/** The mutate operations requested by a fused request. */\nconst requestedOps = (request: MutateRequest): string[] => {\n const ops: string[] = []\n if (request.resize) ops.push('resize')\n if (request.rotate !== undefined) ops.push('rotate')\n if (request.flip) ops.push('flip')\n if (request.stripMetadata) ops.push('strip_metadata')\n return ops\n}\n\n/**\n * Build the registry over a resolved, validated engine array.\n *\n * @param engines - The engines, in supply (priority) order.\n * @param selection - Optional selection-middleware stages arbitrating multi-candidate dispatches.\n * @returns The registry.\n */\nexport const buildEngineRegistry = (\n engines: readonly MediaEngine[],\n selection: readonly EngineSelectionMiddlewareFn[] = []\n): EngineRegistry => {\n // ── capability filters (declaration-only, sync) ───────────────────────────\n const convertCandidates = (fromMime: string, to: string): ConvertCandidate[] => {\n const mime = normalizeMime(fromMime)\n const out: ConvertCandidate[] = []\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (capability.to.includes(to) && matchesAny(capability.from, mime)) {\n out.push({ engine, capability })\n break // one entry per engine; its first matching group serves the edge\n }\n }\n }\n return out\n }\n\n const mutateCandidates = (request: MutateRequest): MutateCandidate[] => {\n const mime = normalizeMime(request.mimeType)\n const ops = requestedOps(request)\n const out: MutateCandidate[] = []\n for (const engine of engines) {\n for (const capability of engine.mutates ?? []) {\n if (!matchesAny(capability.over, mime)) continue\n if (!ops.every((op) => capability.ops.includes(op))) continue\n if (request.format && !capability.encodes.includes(request.format.to)) continue\n out.push({ engine, capability })\n break\n }\n }\n return out\n }\n\n // ── the selection rule ─────────────────────────────────────────────────────\n const arbitrate = async <C extends { engine: MediaEngine }>(\n kind: 'convert' | 'mutate',\n request: EngineSelectionContext['request'],\n candidates: C[]\n ): Promise<C | undefined> => {\n if (candidates.length === 0) return undefined\n if (selection.length === 0 || candidates.length === 1) return candidates[0]\n const ctx: EngineSelectionContext = {\n kind,\n request,\n candidates: candidates.map((c) => c.engine),\n }\n const mw = new Middleware<EngineSelectionMiddlewareFn>()\n for (const fn of selection) mw.add(fn)\n let failed: unknown\n await mw\n .runner()\n .errorHandler(async (error: unknown) => {\n failed = error\n })\n .finalHandler(async () => {})\n .run((fn, next) => Promise.resolve(fn(ctx, next)))\n if (failed !== undefined) throw failed\n // Re-filter: stages narrow/reorder, never widen. First survivor in the stages' order wins.\n for (const engine of ctx.candidates) {\n const survivor = candidates.find((c) => c.engine === engine)\n if (survivor) return survivor\n }\n return undefined\n }\n\n // ── convert pathfinding (declarations only) ───────────────────────────────\n const findPath = (fromMime: string, target: string): ConvertHop[] | undefined => {\n const start = normalizeMime(fromMime)\n const queue: Array<{ mime: string; path: ConvertHop[] }> = [{ mime: start, path: [] }]\n const visited = new Set<string>([start])\n while (queue.length > 0) {\n const { mime, path } = queue.shift()!\n if (path.length >= MAX_HOPS) continue\n // Direct edge from this node?\n if (convertCandidates(mime, target).length > 0) {\n return [...path, { fromMime: mime, to: target }]\n }\n // Expand through non-terminal tokens.\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (!matchesAny(capability.from, mime)) continue\n for (const to of capability.to) {\n if (TERMINAL_TOKENS.has(to)) continue\n const nextMime = EXT_TO_MIME[to]\n if (!nextMime || visited.has(nextMime)) continue\n visited.add(nextMime)\n queue.push({ mime: nextMime, path: [...path, { fromMime: mime, to }] })\n }\n }\n }\n }\n return undefined\n }\n\n const hasConvert = (from?: string, to?: string): boolean => {\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (from !== undefined && !matchesAny(capability.from, normalizeMime(from))) continue\n if (to !== undefined && !capability.to.includes(to)) continue\n return true\n }\n }\n return false\n }\n\n const convertTargets = (fromMime: string): readonly string[] => {\n const reachable: string[] = []\n const seen = new Set<string>()\n let frontier = [normalizeMime(fromMime)]\n const visitedMimes = new Set<string>(frontier)\n for (let hop = 0; hop < MAX_HOPS && frontier.length > 0; hop++) {\n const next: string[] = []\n for (const mime of frontier) {\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (!matchesAny(capability.from, mime)) continue\n for (const to of capability.to) {\n if (!seen.has(to)) {\n seen.add(to)\n reachable.push(to)\n }\n if (TERMINAL_TOKENS.has(to)) continue\n const nextMime = EXT_TO_MIME[to]\n if (nextMime && !visitedMimes.has(nextMime)) {\n visitedMimes.add(nextMime)\n next.push(nextMime)\n }\n }\n }\n }\n }\n frontier = next\n }\n return reachable\n }\n\n const ids = (): string => engines.map((e) => e.id).join(', ') || '(none)'\n\n const convert = async (request: ConvertRequest): Promise<ConvertResult> => {\n const path = findPath(request.mimeType, request.to)\n if (!path) {\n const supported = convertTargets(request.mimeType)\n throw new Error(\n `no configured engine (or computed path) can convert ${request.mimeType} to \"${request.to}\"; reachable targets: ${supported.join(', ') || '(none)'} (engines: ${ids()})`\n )\n }\n let bytes = request.bytes\n let mimeType = request.mimeType\n let result: ConvertResult | undefined\n for (const hop of path) {\n const candidates = convertCandidates(mimeType, hop.to)\n const chosen = await arbitrate(\n 'convert',\n { mimeType, filename: request.filename, bytes, to: hop.to },\n candidates\n )\n if (!chosen) {\n throw new Error(\n `all engines capable of converting ${mimeType} to \"${hop.to}\" (${candidates.map((c) => c.engine.id).join(', ')}) were excluded by selection middleware`\n )\n }\n result = await chosen.capability.convert({\n bytes,\n mimeType,\n filename: request.filename,\n to: hop.to,\n options: request.options,\n signal: request.signal,\n })\n const first = result.outputs[0]\n if (!first) {\n throw new Error(\n `engine \"${chosen.engine.id}\" converted ${mimeType} to \"${hop.to}\" but produced no outputs`\n )\n }\n bytes = first.bytes\n mimeType = first.mimeType\n }\n return result!\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const candidates = mutateCandidates(request)\n if (candidates.length === 0) {\n const allOps = new Set<string>()\n const allEncodes = new Set<string>()\n for (const engine of engines) {\n for (const capability of engine.mutates ?? []) {\n for (const op of capability.ops) allOps.add(op)\n for (const enc of capability.encodes) allEncodes.add(enc)\n }\n }\n const wanted = requestedOps(request).join(', ') || '(none)'\n const encodeNote = request.format\n ? `; requested encoding \"${request.format.to}\" — declared encodings: ${[...allEncodes].join(', ') || '(none)'}. A different engine (e.g. sharp) may support it`\n : ''\n throw new Error(\n `no configured engine can mutate ${request.mimeType} with ops [${wanted}]${encodeNote} (engines: ${ids()})`\n )\n }\n const chosen = await arbitrate(\n 'mutate',\n {\n mimeType: request.mimeType,\n filename: '',\n bytes: request.bytes,\n to: request.format?.to,\n ops: requestedOps(request),\n },\n candidates\n )\n if (!chosen) {\n throw new Error(\n `all engines capable of this mutate (${candidates.map((c) => c.engine.id).join(', ')}) were excluded by selection middleware`\n )\n }\n return chosen.capability.mutate(request)\n }\n\n return {\n engines,\n hasConvert,\n hasMutate: () => engines.some((e) => (e.mutates ?? []).length > 0),\n convertTargets,\n convert,\n mutate,\n }\n}\n","/**\n * `image.*` and `audio.*` step implementations: fused raster transforms via the\n * imageTransform engine, and transcription via the audioDecode + asr engines.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The split image verbs\n * (`resize`/`format`/`rotate`/`flip`/`strip_metadata`) read pipe-naturally, and the runtime\n * fuses **adjacent** image steps into a single engine invocation so a resize→format→rotate\n * chain costs one decode/encode (frozen design 0.13). Fusion happens here at execution time:\n * each image step folds its args into a shared fused request stored on the execution stash;\n * the LAST image step in a run performs the engine call.\n *\n * Audio transcription composes two engines: `audioDecode` (container → mono PCM) and `asr`\n * (PCM → text/subtitles). A small pure resampler bridges arbitrary sample rates to the\n * 16 kHz mono Float32Array ASR engines expect.\n */\n\nimport { argOf } from '../runtime'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { PCM_MIME, pcmToBytes, bytesToPcm } from '../contracts'\nimport type { MutateRequest } from '../contracts'\nimport type { StepImpl, StepContext, StepResult } from '../runtime'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n// ── image fusion ─────────────────────────────────────────────────────────────\n\ntype FusedImageOps = Omit<MutateRequest, 'bytes' | 'mimeType' | 'signal'>\n\nconst IMAGE_VERBS = new Set([\n 'image.resize',\n 'image.format',\n 'image.rotate',\n 'image.flip',\n 'image.strip_metadata',\n])\n\nconst requireImage = (ctx: StepContext, verb: string): void => {\n if (!ctx.payload.mimeType.toLowerCase().startsWith('image/')) {\n fail(verb, `image operations expect an image; the media is ${ctx.payload.mimeType}`)\n }\n}\n\n/** Fold this step's args into the fused request. */\nconst foldImageStep = (ctx: StepContext, fused: FusedImageOps): FusedImageOps => {\n const args = ctx.step.args\n switch (ctx.step.verb) {\n case 'image.resize':\n return {\n ...fused,\n resize: {\n width: args.width as number | undefined,\n height: args.height as number | undefined,\n fit: args.fit as FusedImageOps['resize'] extends undefined\n ? never\n : NonNullable<FusedImageOps['resize']>['fit'],\n },\n }\n case 'image.format':\n return {\n ...fused,\n format: { to: args.to as string, quality: args.quality as number | undefined },\n ...(args.strip_metadata !== undefined\n ? { stripMetadata: args.strip_metadata as boolean }\n : {}),\n }\n case 'image.rotate': {\n const deg = Number(args.deg) as 90 | 180 | 270\n const total = (((fused.rotate ?? 0) + deg) % 360) as 0 | 90 | 180 | 270\n return { ...fused, rotate: total === 0 ? undefined : total }\n }\n case 'image.flip': {\n const axis = args.axis as 'horizontal' | 'vertical' | 'both'\n const flip = { ...(fused.flip ?? {}) }\n if (axis === 'horizontal' || axis === 'both') flip.horizontal = !flip.horizontal\n if (axis === 'vertical' || axis === 'both') flip.vertical = !flip.vertical\n return { ...fused, flip }\n }\n case 'image.strip_metadata':\n return { ...fused, stripMetadata: true }\n default:\n return fused\n }\n}\n\n/** `true` when the NEXT step in the plan is also an image verb (so we defer the engine call). */\nconst nextIsImageStep = (ctx: StepContext): boolean => {\n const next = ctx.plan.steps[ctx.stepIndex + 1]\n return next !== undefined && IMAGE_VERBS.has(next.verb)\n}\n\nconst FUSION_KEY = 'media.image.fused'\n\nconst imageStep: StepImpl = async (ctx) => {\n const verb = ctx.step.verb.replace(/\\./g, ' ')\n requireImage(ctx, verb)\n const prior = (ctx.stash.get(FUSION_KEY) as FusedImageOps | undefined) ?? {}\n const fused = foldImageStep(ctx, prior)\n if (nextIsImageStep(ctx)) {\n // Defer: pass the payload through untouched; the last image step executes the engine.\n ctx.stash.set(FUSION_KEY, fused)\n return { kind: 'media', payload: ctx.payload }\n }\n ctx.stash.delete(FUSION_KEY)\n if (!ctx.engines.hasMutate()) {\n fail(\n verb,\n 'no image-mutating engine is configured. Do not retry image verbs in this deployment.'\n )\n }\n const result = await ctx.engines.mutate({\n ...fused,\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n signal: ctx.signal,\n })\n const ext = result.mimeType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'bin'\n const dot = ctx.payload.filename.lastIndexOf('.')\n const base = dot > 0 ? ctx.payload.filename.slice(0, dot) : ctx.payload.filename\n return {\n kind: 'media',\n payload: { bytes: result.bytes, mimeType: result.mimeType, filename: `${base}.${ext}` },\n }\n}\n\n// ── audio ────────────────────────────────────────────────────────────────────\n\n/** Downmix to mono and linearly resample to the target rate. Pure, cross-env. */\nexport const resampleTo = (pcm: Float32Array, fromRate: number, toRate: number): Float32Array => {\n if (fromRate === toRate) return pcm\n const ratio = fromRate / toRate\n const outLength = Math.floor(pcm.length / ratio)\n const out = new Float32Array(outLength)\n for (let i = 0; i < outLength; i++) {\n const pos = i * ratio\n const left = Math.floor(pos)\n const right = Math.min(left + 1, pcm.length - 1)\n const frac = pos - left\n out[i] = pcm[left] * (1 - frac) + pcm[right] * frac\n }\n return out\n}\n\nconst ASR_SAMPLE_RATE = 16_000\n\n/**\n * `audio.transcribe` — an explicit two-stage composition: convert the container to PCM,\n * resample to 16 kHz mono, then convert the PCM to the requested text form. The registry\n * never auto-chains through PCM (it is a terminal token), precisely because this resample\n * leg must happen between the two converts.\n */\nconst audioTranscribeStep: StepImpl = async (ctx): Promise<StepResult> => {\n const verb = 'audio transcribe'\n if (!ctx.payload.mimeType.toLowerCase().startsWith('audio/')) {\n fail(verb, `transcription expects audio; the media is ${ctx.payload.mimeType}`)\n }\n const out = (argOf<string>(ctx.step, 'out') ?? 'txt') as 'txt' | 'srt' | 'vtt' | 'json'\n if (!ctx.engines.hasConvert(ctx.payload.mimeType, 'pcm')) {\n fail(\n verb,\n `no engine that decodes ${ctx.payload.mimeType} to PCM is configured. Do not retry this verb in this deployment.`\n )\n }\n if (!ctx.engines.hasConvert(PCM_MIME, out)) {\n fail(\n verb,\n `no engine that transcribes PCM to \"${out}\" is configured. Do not retry this verb in this deployment.`\n )\n }\n const decoded = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to: 'pcm',\n signal: ctx.signal,\n })\n const pcmOut = decoded.outputs[0]\n if (!pcmOut) fail(verb, 'audio decoding produced no output')\n const sourceRate = Number(pcmOut!.meta?.sampleRate)\n if (!Number.isFinite(sourceRate) || sourceRate <= 0) {\n fail(verb, 'the decode engine did not report meta.sampleRate on its PCM output')\n }\n const pcm = resampleTo(bytesToPcm(pcmOut!.bytes), sourceRate, ASR_SAMPLE_RATE)\n const result = await ctx.engines.convert({\n bytes: pcmToBytes(pcm),\n mimeType: PCM_MIME,\n filename: ctx.payload.filename,\n to: out,\n options: {\n lang: argOf<string>(ctx.step, 'lang'),\n translate: argOf<boolean>(ctx.step, 'translate'),\n },\n signal: ctx.signal,\n })\n const final = result.outputs[0]\n if (!final) fail(verb, 'transcription produced no output')\n const text = new TextDecoder().decode(final!.bytes)\n return { kind: 'data', data: text, asText: text }\n}\n\n/** The image + audio step registry fragment. */\nexport const IMAGE_AUDIO_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['image.resize', imageStep],\n ['image.format', imageStep],\n ['image.rotate', imageStep],\n ['image.flip', imageStep],\n ['image.strip_metadata', imageStep],\n ['audio.transcribe', audioTranscribeStep],\n]\n","/**\n * Pure page-operation step implementations for PDFs: select, split, merge, reorder.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Implemented with `pdf-lib`\n * (optional peer, lazily imported) on in-memory bytes — no binaries, cross-environment.\n * Phase 0 covers PDF inputs; PPTX slide operations and DOCX section operations join in the\n * sheet/slides/doc phases, sharing these verb ids with format dispatch.\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, replaceExtension } from '../formats'\nimport type { MediaRef } from '../plan'\nimport type * as PdfLibModule from 'pdf-lib'\nimport type { StepImpl, StepPayload } from '../runtime'\n\ntype PdfLib = typeof PdfLibModule\ntype PDFDocumentType = PdfLibModule.PDFDocument\n\nlet pdfLibPromise: Promise<PdfLib> | undefined\nconst pdfLib = (): Promise<PdfLib> => {\n pdfLibPromise ??= import('pdf-lib')\n return pdfLibPromise\n}\n\nconst requirePdf = (verb: string, payload: StepPayload): void => {\n if (payload.mimeType.toLowerCase().split(';')[0].trim() !== MIME.PDF) {\n throw new E_MEDIA_STEP_FAILED([\n verb,\n `page operations for ${payload.mimeType} are not yet implemented in this build (PDF is supported)`,\n ])\n }\n}\n\nconst loadPdf = async (verb: string, bytes: Uint8Array): Promise<PDFDocumentType> => {\n const { PDFDocument } = await pdfLib()\n try {\n return await PDFDocument.load(bytes, { ignoreEncryption: false })\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_MEDIA_STEP_FAILED([verb, `could not read the PDF: ${detail}`], { cause: err })\n }\n}\n\nconst checkIndices = (verb: string, indices: number[], pageCount: number): void => {\n for (const i of indices) {\n if (i < 1 || i > pageCount) {\n throw new E_MEDIA_STEP_FAILED([\n verb,\n `page ${i} is out of range — the document has ${pageCount} pages (pages are 1-based)`,\n ])\n }\n }\n}\n\n/** `select` — keep only the listed 1-based pages, producing one document. */\nexport const selectStep: StepImpl = async (ctx) => {\n requirePdf('select', ctx.payload)\n const pages = argOf<number[]>(ctx.step, 'pages') as number[]\n const source = await loadPdf('select', ctx.payload.bytes)\n checkIndices('select', pages, source.getPageCount())\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n pages.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = await out.save()\n return { kind: 'media', payload: { ...ctx.payload, bytes: new Uint8Array(bytes) } }\n}\n\n/** `split` — split into multiple documents by page (optionally grouped by JSON ranges). */\nexport const splitStep: StepImpl = async (ctx) => {\n requirePdf('split', ctx.payload)\n const by = argOf<string>(ctx.step, 'by') ?? 'page'\n if (by !== 'page') {\n throw new E_MEDIA_STEP_FAILED([\n 'split',\n `split by=${by} is not yet implemented in this build (page is supported)`,\n ])\n }\n const source = await loadPdf('split', ctx.payload.bytes)\n const pageCount = source.getPageCount()\n const rawRanges = ctx.step.args.ranges as number[][] | undefined\n const groups: number[][] =\n rawRanges !== undefined\n ? rawRanges.map((pair) => {\n if (!Array.isArray(pair) || pair.length !== 2) {\n throw new E_MEDIA_STEP_FAILED([\n 'split',\n `ranges must be [start,end] pairs, e.g. ranges='[[1,3],[5,7]]'`,\n ])\n }\n const [start, end] = pair\n const pages: number[] = []\n for (let p = start; p <= end; p++) pages.push(p)\n return pages\n })\n : Array.from({ length: pageCount }, (_, i) => [i + 1])\n const { PDFDocument } = await pdfLib()\n const payloads: StepPayload[] = []\n let part = 1\n for (const group of groups) {\n checkIndices('split', group, pageCount)\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n group.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = new Uint8Array(await out.save())\n payloads.push({\n bytes,\n mimeType: MIME.PDF,\n filename: replaceExtension(ctx.payload.filename, '').replace(/\\.$/, '') + `.part${part}.pdf`,\n })\n part += 1\n }\n return { kind: 'media-list', payloads }\n}\n\n/** `merge` — append the referenced media's pages, in order. */\nexport const mergeStep: StepImpl = async (ctx) => {\n requirePdf('merge', ctx.payload)\n const raw = ctx.step.args.with\n const refs = (Array.isArray(raw) ? raw : [raw]) as MediaRef[]\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const appendAll = async (doc: PDFDocumentType): Promise<void> => {\n const copied = await out.copyPages(doc, doc.getPageIndices())\n for (const page of copied) out.addPage(page)\n }\n await appendAll(await loadPdf('merge', ctx.payload.bytes))\n for (const ref of refs) {\n if (ref.kind !== 'id') {\n throw new E_MEDIA_STEP_FAILED(['merge', 'builder refs are not yet supported here'])\n }\n const other = await ctx.resolveRef(ref.id)\n requirePdf('merge', other)\n await appendAll(await loadPdf('merge', other.bytes))\n }\n const bytes = new Uint8Array(await out.save())\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\n/** `reorder` — rebuild the document with pages in the given 1-based order. */\nexport const reorderStep: StepImpl = async (ctx) => {\n requirePdf('reorder', ctx.payload)\n const order = argOf<number[]>(ctx.step, 'order') as number[]\n const source = await loadPdf('reorder', ctx.payload.bytes)\n const pageCount = source.getPageCount()\n checkIndices('reorder', order, pageCount)\n if (order.length !== pageCount) {\n throw new E_MEDIA_STEP_FAILED([\n 'reorder',\n `order lists ${order.length} pages but the document has ${pageCount} — list every page exactly once`,\n ])\n }\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n order.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = new Uint8Array(await out.save())\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n","/**\n * A knex-inspired local media pipeline: one declarative plan, three front-ends (chainable\n * builder, pipe string, JSON ops), engines as composable seams.\n *\n * @module @nhtio/adk/batteries/media\n *\n * @remarks\n * Most implementations give you two ways to process media — ship it to an external API, or\n * flood the model's context window with the bytes. This battery is the third option: **full\n * control of media — local processing, no external APIs by default, cross-environment where\n * possible.** Your data stays in your application and infrastructure unless you deliberately\n * wire an engine that sends it elsewhere.\n *\n * The entry point is {@link createMediaPipeline}:\n *\n * ```ts\n * import { createMediaPipeline } from '@nhtio/adk/batteries/media'\n *\n * const mp = await createMediaPipeline({\n * engines: [\n * // an ordered array of self-declaring engines; resolvers run eagerly at construction,\n * // but each engine's heavy peer dependency loads lazily on first actual use\n * () => import('@nhtio/adk/batteries/media/engines/jimp').then((m) => m.jimpEngine()),\n * ],\n * })\n *\n * // chainable builder (implementor DX)\n * const redacted = await mp(payload)\n * .select({ pages: [2, 3] })\n * .redact({ match: [/\\d{3}-\\d{2}-\\d{4}/] })\n *\n * // pipe string (the LLM-facing DSL — same plan underneath)\n * const result = await mp.query(payload, 'select pages=2-3 | redact match=/\\\\d{3}-\\\\d{2}-\\\\d{4}/')\n * ```\n *\n * Media pipelines have no standard — every tool invented its own grammar. LLMs don't share one\n * mental model of that chaos, so the pipe DSL projects every operation onto the one\n * transformation idiom every model already groks: shell pipes with `key=value` args. The verbs\n * a deployment advertises narrow to the engines it configured; everything else fails loud with\n * a model-actionable message.\n */\n\nimport { parsePipeRaw } from './pipe'\nimport { MediaChain } from './builder'\nimport { executePlan } from './runtime'\nimport { DOC_STEPS } from './steps/doc'\nimport { SHEET_STEPS } from './steps/sheet'\nimport { validator } from '@nhtio/validation'\nimport { SLIDES_STEPS } from './steps/slides'\nimport { INGEST_STEPS } from './steps/ingest'\nimport { buildEngineRegistry } from './registry'\nimport { implementsMediaEngine } from './contracts'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport { IMAGE_AUDIO_STEPS } from './steps/image_audio'\nimport { validateSegments, validateOps } from './validate'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from './exceptions'\nimport { selectStep, splitStep, mergeStep, reorderStep } from './steps/pages'\nimport {\n chunkStep,\n extractTextStep,\n extractMetadataStep,\n redactStep,\n updateTextStep,\n diffStep,\n applyPatchStep,\n} from './steps/text'\nimport type { MediaOp, MediaPlan } from './plan'\nimport type { CapabilityProbe } from './validate'\nimport type { EngineSelectionMiddlewareFn } from './registry'\nimport type { MediaEngine, EngineResolver } from './contracts'\nimport type { StepImpl, StepPayload, PlanResult, MediaStepMiddlewareFn } from './runtime'\n\nexport { MediaChain } from './builder'\nexport type {\n ChainExecutor,\n ChainInput,\n MediaChainRef,\n CellUpdate,\n ResizeOptions,\n SheetNamespace,\n SlidesNamespace,\n ImageNamespace,\n AudioNamespace,\n} from './builder'\nexport { toPipe, toOps, fromOps, isMediaRef, isRegExpRef } from './plan'\nexport type {\n MediaPlan,\n MediaStep,\n MediaOp,\n MediaArgValue,\n MediaArgScalar,\n MediaArgJson,\n MediaRef,\n RegExpRef,\n SourceSpan,\n} from './plan'\nexport { parsePipeRaw, lowerSegments } from './pipe'\nexport type { RawSegment, RawArgValue } from './pipe'\nexport { validateSegments, validateOps, availableVerbs } from './validate'\nexport type { ValidateOptions, CapabilityProbe } from './validate'\nexport { VERBS, VERB_INDEX, FOLDED_VERBS, foldVerb, suggestVerbs } from './verbs'\nexport type {\n VerbSpec,\n VerbArgSpec,\n VerbArgType,\n VerbOutput,\n VerbRequirement,\n FormatFamily,\n} from './verbs'\nexport { PCM_MIME, pcmToBytes, bytesToPcm, implementsMediaEngine } from './contracts'\nexport type {\n MediaEngine,\n EngineResolver,\n ConvertCapability,\n ConvertRequest,\n ConvertResult,\n ConvertOutput,\n ConvertOptions,\n OcrConvertOptions,\n AsrConvertOptions,\n ImagesConvertOptions,\n MutateCapability,\n MutateRequest,\n MimePattern,\n} from './contracts'\nexport { buildEngineRegistry } from './registry'\nexport type {\n EngineRegistry,\n EngineSelectionContext,\n EngineSelectionMiddlewareFn,\n} from './registry'\nexport type {\n StepPayload,\n StepResult,\n PlanResult,\n StepContext,\n StepImpl,\n MediaStepMiddlewareFn,\n} from './runtime'\nexport {\n MIME,\n familyOf,\n unsupportedForMutationReason,\n replaceExtension,\n EXT_TO_MIME,\n} from './formats'\nexport {\n E_INVALID_MEDIA_PIPELINE_CONFIG,\n E_MEDIA_PIPE_SYNTAX,\n E_MEDIA_UNKNOWN_VERB,\n E_MEDIA_UNKNOWN_ARG,\n E_MEDIA_BAD_ARG,\n E_MEDIA_MISSING_ARG,\n E_MEDIA_UNSUPPORTED_OP,\n E_MEDIA_ENGINE_REQUIRED,\n E_MEDIA_NOT_PIPE_EXPRESSIBLE,\n E_MEDIA_STEP_FAILED,\n E_MEDIA_STEP_UNAVAILABLE,\n} from './exceptions'\n\n/** Resolves a media-ref id to its payload — supplied by the consumer (or the agent forge). */\nexport type MediaRefResolver = (id: string) => StepPayload | Promise<StepPayload>\n\n/** Per-run options for `query`/`ops`. */\nexport interface RunOptions {\n /** Abort signal threaded into steps and engines. */\n signal?: AbortSignal\n /** Per-run media-ref resolution, overriding the construction-time resolver (the agent forge uses this to resolve `@id` refs against the current turn). */\n resolveRef?: MediaRefResolver\n}\n\n/** Configuration for {@link createMediaPipeline}. */\nexport interface MediaPipelineConfig {\n /**\n * The engine array, in priority order. Each entry is a {@link MediaEngine} instance or a\n * resolver returning one (async dynamic import is the canonical form). Engines self-declare\n * their capabilities; verbs whose capability has no provider are not advertised and fail\n * validation with a do-not-retry message if reached. Resolvers run eagerly at construction —\n * bundled engines stay cheap because their heavy peers lazy-load inside capability methods.\n */\n engines?: ReadonlyArray<EngineResolver<MediaEngine>>\n /**\n * Selection-middleware stages arbitrating dispatches where several engines can perform the\n * same transform. Stages may exclude or reorder candidates (quality heuristics, overrides);\n * array order among survivors always breaks the tie. Most deployments need none.\n */\n selection?: EngineSelectionMiddlewareFn[]\n /**\n * Consumer step interceptors wrapping every step — the documented seam for DLP/AV byte\n * scanning, caching (via `ctx.shortCircuit`), byte limits, and telemetry. The battery\n * ships no built-in scanner/cache/limiter.\n */\n use?: MediaStepMiddlewareFn[]\n /**\n * Resolves `@id` media refs (merge/diff/replace targets). Required only when chains use\n * multi-input verbs; the agent forge supplies a turn-state resolver automatically.\n */\n resolveRef?: MediaRefResolver\n}\n\n/**\n * The callable pipeline returned by {@link createMediaPipeline}: `mp(payload)` opens a\n * chainable builder; `mp.query(payload, q)` runs a pipe-string statement; `mp.ops(payload,\n * ops)` runs a JSON ops array. All three compile to the same plan and execute on the same\n * runtime.\n */\nexport interface MediaPipeline {\n /** Open a fresh chainable builder over `input`. */\n (input: StepPayload): MediaChain\n /** Parse, validate, and execute a pipe-string statement. */\n query(input: StepPayload, q: string, options?: RunOptions): Promise<PlanResult>\n /** Validate and execute a JSON ops array. */\n ops(input: StepPayload, ops: MediaOp[], options?: RunOptions): Promise<PlanResult>\n /** Validate a pipe string or ops array to a plan WITHOUT executing (dry-run/compile). */\n compile(statement: string | MediaOp[]): MediaPlan\n /** The deployment's capabilities (drives verb narrowing). */\n readonly capabilities: CapabilityProbe\n /** The resolved engines, in supply order — inspect ids and declared capabilities. */\n readonly engines: readonly MediaEngine[]\n}\n\nconst configSchema = validator\n .object({\n engines: validator\n .array()\n .items(validator.alternatives().try(validator.function(), validator.object().unknown(true)))\n .optional(),\n selection: validator.array().items(validator.function()).optional(),\n use: validator.array().items(validator.function()).optional(),\n resolveRef: validator.function().optional(),\n })\n .unknown(false)\n\n/** The Phase 0 step registry: pure steps available in every deployment. */\nconst PURE_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['select', selectStep],\n ['split', splitStep],\n ['merge', mergeStep],\n ['reorder', reorderStep],\n ['redact', redactStep],\n ['update_text', updateTextStep],\n ['diff', diffStep],\n ['apply_patch', applyPatchStep],\n ['extract.text', extractTextStep],\n ['extract.metadata', extractMetadataStep],\n ['chunk', chunkStep],\n ...SHEET_STEPS,\n ...SLIDES_STEPS,\n // DOC_STEPS + INGEST_STEPS override the Phase 0 text-only implementations with format dispatch.\n ...DOC_STEPS,\n ...INGEST_STEPS,\n ...IMAGE_AUDIO_STEPS,\n]\n\n/** Resolve one engine entry: invoke a resolver, unwrap `{default}`, guard-check the result. */\nconst resolveEngine = async (\n entry: EngineResolver<MediaEngine>,\n index: number\n): Promise<MediaEngine> => {\n let value: unknown = entry\n if (typeof value === 'function') {\n try {\n value = await (value as () => unknown)()\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`engines[${index}] resolver failed: ${detail}`])\n }\n if (isObject(value) && 'default' in value && !implementsMediaEngine(value)) {\n value = (value as { default: unknown }).default\n }\n }\n if (!implementsMediaEngine(value)) {\n const candidate = value as { id?: unknown } | undefined\n const id = isObject(value) && typeof candidate?.id === 'string' ? ` (\"${candidate.id}\")` : ''\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `engines[${index}]${id} does not implement the MediaEngine contract (a string id plus at least one well-formed converts/mutates capability entry)`,\n ])\n }\n return value\n}\n\n/**\n * Create a media pipeline.\n *\n * @remarks\n * Config is validated eagerly, and so are the engines: every resolver in the array runs at\n * construction (capability declarations drive verb narrowing, so they must be known up\n * front), each result is contract-checked, and failures throw\n * `E_INVALID_MEDIA_PIPELINE_CONFIG` naming the offending index. Construction stays cheap —\n * bundled engine modules import their heavy peer dependencies lazily inside capability\n * methods, on first actual use.\n *\n * @param config - Engines, selection stages, step interceptors, and the media-ref resolver.\n * @returns The callable {@link MediaPipeline}.\n */\nexport const createMediaPipeline = async (\n config: MediaPipelineConfig = {}\n): Promise<MediaPipeline> => {\n const { error } = configSchema.validate(config, { abortEarly: true })\n if (error) {\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([error.message])\n }\n const use = config.use ?? []\n const resolveRef: MediaRefResolver =\n config.resolveRef ??\n (() => {\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n 'this chain references another media (@id) but no resolveRef was configured',\n ])\n })\n\n const resolvedEngines = await Promise.all((config.engines ?? []).map(resolveEngine))\n const registry = buildEngineRegistry(resolvedEngines, config.selection ?? [])\n\n const steps = new Map<string, StepImpl>(PURE_STEPS)\n\n const run = async (\n input: StepPayload,\n plan: MediaPlan,\n options?: RunOptions\n ): Promise<PlanResult> => {\n const refResolver = options?.resolveRef ?? resolveRef\n return executePlan(plan, {\n input,\n steps,\n use,\n engines: registry,\n resolveRef: async (id) => refResolver(id),\n signal: options?.signal,\n })\n }\n\n const compile = (statement: string | MediaOp[]): MediaPlan =>\n typeof statement === 'string'\n ? validateSegments(parsePipeRaw(statement), { capabilities: registry })\n : validateOps(statement, { capabilities: registry })\n\n const callable = ((input: StepPayload): MediaChain => {\n return new MediaChain(async (ops) => {\n const plan = validateOps(ops, { capabilities: registry })\n return run(input, plan)\n })\n }) as MediaPipeline\n\n Object.defineProperties(callable, {\n query: {\n value: async (input: StepPayload, q: string, options?: RunOptions): Promise<PlanResult> => {\n const plan = validateSegments(parsePipeRaw(q), { capabilities: registry })\n return run(input, plan, options)\n },\n },\n ops: {\n value: async (\n input: StepPayload,\n ops: MediaOp[],\n options?: RunOptions\n ): Promise<PlanResult> => {\n const plan = validateOps(ops, { capabilities: registry })\n return run(input, plan, options)\n },\n },\n compile: { value: compile },\n capabilities: { value: registry },\n engines: { value: registry.engines },\n })\n\n return callable\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"media.mjs","names":["#toks","#pos","#parseSegment","#peek","#next","#parseValue","#parseScalar","#ops","#exec","#with","#chain"],"sources":["../../src/batteries/media/pipe.ts","../../src/batteries/media/builder.ts","../../src/batteries/media/runtime.ts","../../src/batteries/media/steps/patch.ts","../../src/batteries/media/steps/text.ts","../../src/batteries/media/steps/doc.ts","../../src/batteries/media/steps/data.ts","../../src/batteries/media/steps/sheet.ts","../../src/batteries/media/steps/slides.ts","../../src/batteries/media/steps/ingest.ts","../../src/batteries/media/registry.ts","../../src/batteries/media/steps/image_audio.ts","../../src/batteries/media/steps/pages.ts","../../src/batteries/media/index.ts"],"sourcesContent":["/**\n * The pipe-expression front-end: a moo lexer plus a hand-rolled recursive-descent parser that\n * compiles `select pages=2-5 | redact match=/…/ | convert to=pdf` into a {@link MediaPlan}.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The grammar is frozen in the\n * design doc (section 0):\n *\n * - `pipeline := segment ('|' segment)*` ; `segment := verb arg*` ; `arg := IDENT '=' value` —\n * named args only, no positionals (an IDENT followed by `=` is an arg; otherwise it is the\n * verb's second word — 2-token lookahead, no verb table needed at parse time).\n * - Verb matching is separator-insensitive (`extract_text` ≡ `extract text` ≡ `extract.text`).\n * - Values: bareword idents, ints/floats, `a-b` ranges, comma lists, `true`/`false`, quoted\n * strings (single or double), class-aware `/regex/flags` literals, `@id` media refs, and\n * quoted-JSON structured payloads (a quoted string that the verb's arg schema declares as\n * `json` is JSON-parsed).\n * - `#` line comments are tolerated (models add them; ignoring them is free robustness).\n * - Two error layers: syntactic ({@link E_MEDIA_PIPE_SYNTAX}, with line/col and a corrective\n * exemplar) and semantic ({@link E_MEDIA_UNKNOWN_VERB} etc., produced by the validator in\n * `validate.ts` — this module only parses to a raw AST and lowers to the plan).\n *\n * Parsing is deployment-independent: the full verb table drives folding, and engine narrowing\n * happens later in validation (frozen 0.3).\n */\n\nimport { foldVerb } from './verbs'\nimport { default as moo } from 'moo'\nimport { canonicalFlags } from './plan'\nimport { E_MEDIA_PIPE_SYNTAX } from './exceptions'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport type { MediaPlan, MediaStep, MediaArgValue, MediaArgScalar, SourceSpan } from './plan'\n\n// ── lexer ────────────────────────────────────────────────────────────────────\n\n/**\n * The moo ruleset. Order matters: first match wins, so `range` must precede `int`, `float`\n * precedes `int`, and `comment` precedes nothing it could shadow. String/regex bodies exclude\n * raw newlines (escape them); `ws` carries `lineBreaks` so spans stay accurate across lines.\n */\nconst lexer = moo.compile({\n ws: { match: /[ \\t\\r\\n]+/, lineBreaks: true },\n comment: /#[^\\n]*/,\n pipe: '|',\n eq: '=',\n comma: ',',\n // `:` admits the empty:<format> sentinel (UUIDs never contain it; was a guaranteed lex error).\n ref: /@[A-Za-z0-9:_-]+/,\n regex: /\\/(?:\\\\.|\\[(?:\\\\.|[^\\]\\\\\\n])*\\]|[^/\\\\[\\n])+\\/[a-z]*/,\n dstring: /\"(?:\\\\.|[^\"\\\\\\n])*\"/,\n sstring: /'(?:\\\\.|[^'\\\\\\n])*'/,\n range: /\\d+-\\d+/,\n float: /\\d+\\.\\d+/,\n int: /\\d+/,\n ident: /[A-Za-z_][A-Za-z0-9_.]*/,\n dash: '-',\n})\n\ninterface Tok {\n type: string\n value: string\n text: string\n offset: number\n line: number\n col: number\n}\n\n/** Tokenize, skipping ws/comments, surfacing lexer errors as syntax exceptions. */\nconst tokenize = (input: string): Tok[] => {\n lexer.reset(input)\n const out: Tok[] = []\n let tok: moo.Token | undefined\n try {\n while ((tok = lexer.next())) {\n if (tok.type === 'ws' || tok.type === 'comment') continue\n out.push({\n type: tok.type as string,\n value: tok.value,\n text: tok.text,\n offset: tok.offset,\n line: tok.line,\n col: tok.col,\n })\n }\n } catch (err) {\n const detail = isError(err) ? err.message.split('\\n')[0] : String(err)\n throw new E_MEDIA_PIPE_SYNTAX([\n `${detail}. Values containing special characters must be quoted — write it like: name=\"my-value\"`,\n ])\n }\n return out\n}\n\n// ── parser ───────────────────────────────────────────────────────────────────\n\n/** A parsed-but-unvalidated arg value, before the verb's arg schema refines it. */\nexport interface RawArgValue {\n /** The lowered value. Quoted strings stay strings here; schema may JSON-parse `json` args. */\n value: MediaArgValue\n /** Whether the source token was a quoted string (drives json-arg parsing + name/index rules). */\n quoted: boolean\n /** Source position of the value token. */\n span: SourceSpan\n}\n\n/** One parsed segment: verb words plus named args, all position-bearing. */\nexport interface RawSegment {\n /** Canonical verb id when fold-matching succeeded, else the raw folded text. */\n verb: string\n /** Whether `verb` resolved against the verb table. */\n known: boolean\n /** The parsed named args, in source order. */\n args: Map<string, RawArgValue>\n /** Source position of the verb token(s). */\n span: SourceSpan\n}\n\nconst spanOf = (tok: Tok, length?: number): SourceSpan => ({\n offset: tok.offset,\n line: tok.line,\n col: tok.col,\n length: length ?? tok.text.length,\n})\n\nconst unquote = (raw: string): string =>\n raw\n .slice(1, -1)\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([\"'\\\\/])/g, '$1')\n\nconst fail = (tok: Tok | undefined, message: string, exemplar: string): never => {\n const where = tok ? ` at line ${tok.line}, col ${tok.col}` : ' at end of input'\n throw new E_MEDIA_PIPE_SYNTAX([`${message}${where}. Write it like: ${exemplar}`])\n}\n\nclass Parser {\n #toks: Tok[]\n #pos = 0\n\n constructor(toks: Tok[]) {\n this.#toks = toks\n }\n\n #peek(ahead = 0): Tok | undefined {\n return this.#toks[this.#pos + ahead]\n }\n\n #next(): Tok | undefined {\n return this.#toks[this.#pos++]\n }\n\n parsePipeline(): RawSegment[] {\n const segments: RawSegment[] = []\n if (this.#toks.length === 0) {\n fail(undefined, 'empty pipe expression', 'extract text | chunk by=sentence')\n }\n segments.push(this.#parseSegment())\n while (this.#peek()?.type === 'pipe') {\n this.#next()\n segments.push(this.#parseSegment())\n }\n const trailing = this.#peek()\n if (trailing) {\n fail(\n trailing,\n `unexpected \"${trailing.text}\" after a complete segment`,\n 'segment | segment (segments are separated by |)'\n )\n }\n return segments\n }\n\n #parseSegment(): RawSegment {\n const first = this.#peek()\n if (!first || first.type !== 'ident') {\n fail(first, 'expected a verb to start the segment', 'convert to=pdf')\n }\n const head = this.#next() as Tok\n // Verb words: idents NOT followed by `=` (named-args-only makes this unambiguous), up to\n // the longest canonical verb (3 words, e.g. `sheet update cells`). When the greedy\n // collection over-reaches, back off to the longest prefix that fold-matches and rewind so\n // the leftover bareword surfaces as the args-must-be-named error. The fold uses the FULL\n // static verb table — deployment-independent (engine narrowing is a later validation pass).\n const collected = [head.value]\n const posAfterWord: number[] = [this.#pos]\n while (collected.length < 3) {\n const next = this.#peek()\n if (next?.type !== 'ident' || this.#peek(1)?.type === 'eq') break\n collected.push((this.#next() as Tok).value)\n posAfterWord.push(this.#pos)\n }\n let take = collected.length\n if (foldVerb(collected) === undefined) {\n // Back off to the longest prefix that folds; if none folds at any length, keep the full\n // sequence as the unknown verb so did-you-mean sees the model's whole attempt.\n let prefix = collected.length - 1\n while (prefix >= 1 && foldVerb(collected.slice(0, prefix)) === undefined) prefix -= 1\n if (prefix >= 1) take = prefix\n }\n const words = collected.slice(0, take)\n this.#pos = posAfterWord[take - 1]\n const folded = foldVerb(words)\n const verbText = words.join(' ')\n const args = new Map<string, RawArgValue>()\n for (;;) {\n const tok = this.#peek()\n if (!tok || tok.type === 'pipe') break\n if (tok.type === 'dash') {\n fail(\n tok,\n 'unexpected \"-\" — values containing dashes must be quoted',\n `${verbText} name=\"value-with-dashes\"`\n )\n }\n if (tok.type !== 'ident' || this.#peek(1)?.type !== 'eq') {\n fail(tok, `unexpected \"${tok.text}\" — args must be name=value`, `${verbText} name=value`)\n }\n const name = (this.#next() as Tok).value\n this.#next() // eq\n const value = this.#parseValue(verbText, name)\n if (args.has(name)) {\n fail(tok, `duplicate arg \"${name}\"`, `${verbText} ${name}=value (give each arg once)`)\n }\n args.set(name, value)\n }\n return {\n verb: folded ?? verbText,\n known: folded !== undefined,\n args,\n span: spanOf(head, verbText.length),\n }\n }\n\n #parseValue(verbText: string, argName: string): RawArgValue {\n const first = this.#parseScalar(verbText, argName)\n if (this.#peek()?.type !== 'comma') return first\n const items: MediaArgScalar[] = [...asScalarList(first, verbText, argName)]\n let quoted = first.quoted\n while (this.#peek()?.type === 'comma') {\n this.#next()\n const next = this.#parseScalar(verbText, argName)\n quoted = quoted || next.quoted\n items.push(...asScalarList(next, verbText, argName))\n }\n return { value: items, quoted, span: first.span }\n }\n\n #parseScalar(verbText: string, argName: string): RawArgValue {\n const tok = this.#peek()\n if (!tok) {\n fail(tok, `missing value for \"${argName}\"`, `${verbText} ${argName}=value`)\n }\n const t = tok as Tok\n switch (t.type) {\n case 'int':\n this.#next()\n return { value: Number(t.value), quoted: false, span: spanOf(t) }\n case 'float':\n this.#next()\n return { value: Number(t.value), quoted: false, span: spanOf(t) }\n case 'range': {\n this.#next()\n const [lo, hi] = t.value.split('-').map(Number)\n if (lo > hi) {\n fail(t, `range ${t.value} is descending (start must be ≤ end)`, `${argName}=${hi}-${lo}`)\n }\n const nums: number[] = []\n for (let n = lo; n <= hi; n++) nums.push(n)\n return { value: nums, quoted: false, span: spanOf(t) }\n }\n case 'ident': {\n this.#next()\n if (t.value === 'true') return { value: true, quoted: false, span: spanOf(t) }\n if (t.value === 'false') return { value: false, quoted: false, span: spanOf(t) }\n return { value: t.value, quoted: false, span: spanOf(t) }\n }\n case 'dstring':\n case 'sstring':\n this.#next()\n return { value: unquote(t.text), quoted: true, span: spanOf(t) }\n case 'regex': {\n this.#next()\n const lastSlash = t.text.lastIndexOf('/')\n const source = t.text.slice(1, lastSlash)\n const flags = canonicalFlags(t.text.slice(lastSlash + 1))\n try {\n // Validate the pattern compiles; the IR stores the serializable ref.\n void new RegExp(source, flags)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(t, `invalid regex ${t.text}: ${detail}`, `${argName}=/pattern/flags`)\n }\n return { value: { source, flags }, quoted: false, span: spanOf(t) }\n }\n case 'ref':\n this.#next()\n return {\n value: { kind: 'id', id: t.value.slice(1) },\n quoted: false,\n span: spanOf(t),\n }\n case 'dash':\n fail(\n t,\n 'unexpected \"-\" in a bare value',\n `${argName}=\"value-with-dashes\" (quote values containing dashes)`\n )\n break\n default:\n fail(t, `unexpected \"${t.text}\"`, `${verbText} ${argName}=value`)\n }\n /* unreachable */\n throw new E_MEDIA_PIPE_SYNTAX(['internal parser error'])\n }\n}\n\nconst asScalarList = (raw: RawArgValue, verbText: string, argName: string): MediaArgScalar[] => {\n if (Array.isArray(raw.value)) return raw.value as MediaArgScalar[]\n if (raw.value === null || typeof raw.value === 'object') {\n const v = raw.value as MediaArgValue\n if (isObject(v) && !Array.isArray(v) && !('source' in v) && !('kind' in v)) {\n throw new E_MEDIA_PIPE_SYNTAX([\n `structured values cannot appear in a comma list for \"${argName}\" on \"${verbText}\"`,\n ])\n }\n }\n return [raw.value as MediaArgScalar]\n}\n\n// ── public surface ───────────────────────────────────────────────────────────\n\n/**\n * Parse a pipe expression into raw, position-bearing segments.\n *\n * @remarks\n * Purely syntactic — verbs are fold-matched against the full verb table for canonicalization\n * but unknown verbs are NOT an error here (the validator reports them with did-you-mean and the\n * deployment's narrowed verb list). Pair with `validateSegments` for the validated path.\n *\n * @param input - The pipe expression.\n * @returns The raw segments.\n */\nexport const parsePipeRaw = (input: string): RawSegment[] => {\n return new Parser(tokenize(input)).parsePipeline()\n}\n\n/**\n * Lower raw segments to an (unvalidated) {@link MediaPlan}. Quoted-JSON arg parsing and\n * type/enum checks happen in the validator, which consumes the raw segments — this lowering\n * exists for tooling that wants the structural plan without validation.\n *\n * @param segments - Output of {@link parsePipeRaw}.\n * @returns The structural plan (args carried as parsed, json args still strings).\n */\nexport const lowerSegments = (segments: RawSegment[]): MediaPlan => ({\n steps: segments.map(\n (seg): MediaStep => ({\n verb: seg.verb,\n args: Object.fromEntries(Array.from(seg.args.entries(), ([k, v]) => [k, v.value])),\n span: seg.span,\n })\n ),\n})\n","/**\n * The chainable, thenable media builder — the implementor-facing front-end that compiles to\n * the same {@link MediaPlan} as the pipe string and JSON ops.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The knex lessons applied:\n * `mp(input)` opens a fresh immutable builder; every verb returns a new builder; awaiting the\n * builder executes the chain (no `.execute()`). Domain verbs hang off typed namespaces\n * (`.sheet`, `.slides`, `.image`, `.audio`); shared transforms live on the root.\n *\n * Each verb method appends an op and revalidates lazily — the full plan validates (verb table,\n * arg schemas, engine narrowing) when the chain executes, so building is cheap and the same\n * validator serves all three front-ends.\n */\n\nimport { toPipe } from './plan'\nimport type { PlanResult, StepPayload } from './runtime'\nimport type { MediaPlan, MediaOp, MediaArgValue, MediaArgJson, MediaRef } from './plan'\n\n/** The function a builder calls to execute its accumulated ops. Bound by the pipeline. */\nexport type ChainExecutor = (ops: MediaOp[]) => Promise<PlanResult>\n\n/** Options accepted by image resize. */\nexport interface ResizeOptions {\n /** Target width in pixels. */\n width?: number\n /** Target height in pixels. */\n height?: number\n /** Resize fit mode (default cover). */\n fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside'\n}\n\n/** A cell update for `sheet.updateCells`. */\nexport interface CellUpdate {\n /** A1-notation address, e.g. `B2`. Alternative to row/col. */\n address?: string\n /** One-based row index. Pair with `col`. */\n row?: number\n /** One-based column index, or a column letter. Pair with `row`. */\n col?: number | string\n /** The value to set. A leading `=` writes a formula. */\n value: string | number | boolean | null\n}\n\nconst refOf = (other: MediaChainRef): MediaRef =>\n typeof other === 'string' ? { kind: 'id', id: other } : { kind: 'id', id: other.mediaId }\n\n/** How other media are referenced from builder verbs: an id string or `{ mediaId }`. */\nexport type MediaChainRef = string | { mediaId: string }\n\n/**\n * The chainable builder. Immutable — every verb returns a new instance sharing the executor.\n * Thenable — `await` runs the chain and resolves to the terminal step's natural type.\n */\nexport class MediaChain implements PromiseLike<unknown> {\n readonly #ops: MediaOp[]\n readonly #exec: ChainExecutor\n\n constructor(exec: ChainExecutor, ops: MediaOp[] = []) {\n this.#exec = exec\n this.#ops = ops\n }\n\n #with(verb: string, args: Record<string, MediaArgValue>): MediaChain {\n return new MediaChain(this.#exec, [...this.#ops, { verb, args }])\n }\n\n // ── root transforms ─────────────────────────────────────────────────────────\n\n /** Convert to another format (requires a convert engine). */\n convert(to: string): MediaChain {\n return this.#with('convert', { to })\n }\n\n /** Keep only the listed 1-based pages. */\n select(options: { pages: number[] }): MediaChain {\n return this.#with('select', { pages: options.pages })\n }\n\n /** Split by page (optionally grouped `[[start,end], …]`). Terminal: resolves to media list. */\n split(options: { by?: 'page' | 'section'; ranges?: number[][] } = {}): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.by) args.by = options.by\n if (options.ranges) args.ranges = options.ranges as MediaArgJson\n return this.#with('split', args)\n }\n\n /** Merge other media into this one, in order. */\n merge(...others: MediaChainRef[]): MediaChain {\n return this.#with('merge', { with: others.map(refOf) })\n }\n\n /** Reorder pages by 1-based index. */\n reorder(order: number[]): MediaChain {\n return this.#with('reorder', { order })\n }\n\n /** Redact matching text (literals or RegExp). */\n redact(options: {\n match: Array<string | RegExp> | string | RegExp\n replace?: string\n }): MediaChain {\n const list = Array.isArray(options.match) ? options.match : [options.match]\n const match = list.map((m) =>\n typeof m === 'string' ? m : { source: m.source, flags: Array.from(m.flags).sort().join('') }\n )\n const args: Record<string, MediaArgValue> = { match }\n if (options.replace !== undefined) args.replace = options.replace\n return this.#with('redact', args)\n }\n\n /** Remove potentially unsafe embedded content. */\n sanitize(): MediaChain {\n return this.#with('sanitize', {})\n }\n\n /** Normalize structure/encoding. */\n normalize(): MediaChain {\n return this.#with('normalize', {})\n }\n\n /** Replace the first occurrence of anchor text. */\n updateText(anchor: string, replace: string): MediaChain {\n return this.#with('update_text', { anchor, replace })\n }\n\n /** Compare against another media. Terminal: resolves to a structured diff. */\n diff(other: MediaChainRef): MediaChain {\n return this.#with('diff', { with: refOf(other) })\n }\n\n /** Apply a unified-diff patch. */\n applyPatch(patch: string, options: { with?: MediaChainRef[] } = {}): MediaChain {\n const args: Record<string, MediaArgValue> = { patch }\n if (options.with) args.with = options.with.map(refOf)\n return this.#with('apply_patch', args)\n }\n\n /** Extract text (routes by format; OCR engine used when needed). Terminal: resolves to text. */\n extractText(\n options: {\n ocr?: 'off' | 'auto' | 'force'\n ocrOut?: 'txt' | 'hocr' | 'json'\n lang?: string[]\n } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.ocr) args.ocr = options.ocr\n if (options.ocrOut) args.ocr_out = options.ocrOut\n if (options.lang) args.lang = options.lang\n return this.#with('extract.text', args)\n }\n\n /** Extract metadata. Terminal: resolves to a metadata object. */\n extractMetadata(): MediaChain {\n return this.#with('extract.metadata', {})\n }\n\n /** Extract embedded assets. Terminal: resolves to a media list. */\n extractAssets(\n options: { types?: Array<'image' | 'font' | 'attachment' | 'all'> } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.types) args.types = options.types\n return this.#with('extract.assets', args)\n }\n\n /** Chunk extracted text. Terminal: resolves to a chunk array. */\n chunk(\n options: { strategy?: 'sentence' | 'paragraph' | 'fixed'; size?: number; overlap?: number } = {}\n ): MediaChain {\n const args: Record<string, MediaArgValue> = {}\n if (options.strategy) args.by = options.strategy\n if (options.size !== undefined) args.size = options.size\n if (options.overlap !== undefined) args.overlap = options.overlap\n return this.#with('chunk', args)\n }\n\n // ── domain namespaces ───────────────────────────────────────────────────────\n\n /** Spreadsheet mutations. */\n get sheet(): SheetNamespace {\n return new SheetNamespace(this)\n }\n\n /** Presentation mutations. */\n get slides(): SlidesNamespace {\n return new SlidesNamespace(this)\n }\n\n /** Image transforms. */\n get image(): ImageNamespace {\n return new ImageNamespace(this)\n }\n\n /** Audio operations. */\n get audio(): AudioNamespace {\n return new AudioNamespace(this)\n }\n\n // ── serialization + execution ───────────────────────────────────────────────\n\n /** The accumulated ops (a copy). */\n toOps(): MediaOp[] {\n return this.#ops.map((op) => ({ verb: op.verb, args: { ...op.args } }))\n }\n\n /** The canonical pipe form of the accumulated chain. */\n toPipe(): string {\n const plan: MediaPlan = { steps: this.#ops.map((op) => ({ verb: op.verb, args: op.args })) }\n return toPipe(plan)\n }\n\n /** Internal — used by namespaces to append. */\n withOp(verb: string, args: Record<string, MediaArgValue>): MediaChain {\n return this.#with(verb, args)\n }\n\n /** Thenable: awaiting the chain executes it. */\n then<TResult1 = unknown, TResult2 = never>(\n onfulfilled?: ((value: unknown) => TResult1 | PromiseLike<TResult1>) | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): PromiseLike<TResult1 | TResult2> {\n return this.#exec(this.toOps()).then(unwrapResult).then(onfulfilled, onrejected)\n }\n\n /** Execute and return the raw {@link PlanResult} (no unwrapping). */\n async run(): Promise<PlanResult> {\n return this.#exec(this.toOps())\n }\n}\n\n/** Resolve a plan result to its natural awaited type. */\nconst unwrapResult = (result: PlanResult): unknown => {\n if (result.kind === 'media') return result.payload\n if (result.kind === 'media-list') return result.payloads\n return result.data\n}\n\n/** `sheet.*` verbs, mirrored from the verb table. */\nexport class SheetNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Insert rows. */\n addRows(\n rows: Array<Array<string | number | boolean | null>>,\n options: { sheet?: string | number; before?: number; after?: number } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'sheet.add_rows',\n compact({\n rows: rows as MediaArgJson,\n ...targetArgs(options),\n before: options.before,\n after: options.after,\n })\n )\n }\n /** Insert columns. */\n addColumns(options: {\n sheet?: string | number\n headers?: string[]\n columns?: Array<{ header: string; values?: Array<string | number | boolean | null> }>\n before?: number\n after?: number\n }): MediaChain {\n return this.#chain.withOp(\n 'sheet.add_columns',\n compact({\n ...targetArgs(options),\n headers: options.headers,\n columns: options.columns as MediaArgJson,\n before: options.before,\n after: options.after,\n })\n )\n }\n /** Update cells. */\n updateCells(updates: CellUpdate[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp(\n 'sheet.update_cells',\n compact({ updates: updates as unknown as MediaArgJson, ...targetArgs(options) })\n )\n }\n /** Delete rows by 1-based index. */\n deleteRows(rows: number[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp('sheet.delete_rows', compact({ rows, ...targetArgs(options) }))\n }\n /** Delete columns by 1-based index. */\n deleteColumns(columns: number[], options: { sheet?: string | number } = {}): MediaChain {\n return this.#chain.withOp('sheet.delete_columns', compact({ columns, ...targetArgs(options) }))\n }\n /** Rename a worksheet (name-targeted). */\n renameSheet(sheet: string, to: string): MediaChain {\n return this.#chain.withOp('sheet.rename_sheet', { sheet, to })\n }\n /** Add a worksheet. */\n addSheet(name: string, options: { at?: number } = {}): MediaChain {\n return this.#chain.withOp('sheet.add_sheet', compact({ name, at: options.at }))\n }\n /** Remove a worksheet (name-targeted). */\n removeSheet(sheet: string): MediaChain {\n return this.#chain.withOp('sheet.remove_sheet', { sheet })\n }\n /** Reorder worksheets by names and/or 1-based indices. */\n reorderSheets(order: Array<string | number>): MediaChain {\n return this.#chain.withOp('sheet.reorder_sheets', { order: order as MediaArgJson })\n }\n /** Table transforms by header name. */\n transformTable(options: {\n sheet?: string | number\n headerRow?: number\n select?: string[]\n drop?: string[]\n rename?: Array<{ from: string; to: string }>\n }): MediaChain {\n return this.#chain.withOp(\n 'sheet.transform_table',\n compact({\n ...targetArgs(options),\n header_row: options.headerRow,\n select: options.select,\n drop: options.drop,\n rename: options.rename as MediaArgJson,\n })\n )\n }\n}\n\n/** `slides.*` verbs. */\nexport class SlidesNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Add a slide. */\n add(options: { at?: number; title?: string; layout?: string } = {}): MediaChain {\n return this.#chain.withOp(\n 'slides.add',\n compact({ at: options.at, title: options.title, layout: options.layout })\n )\n }\n /** Update text on a slide. */\n updateText(\n text: string,\n options: { slide?: string | number; placeholder?: string } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_text',\n compact({ text, slide: slideArg(options.slide), placeholder: options.placeholder })\n )\n }\n /** Update table cells on a slide. */\n updateTable(\n updates: Array<{ row: number; col: number; value: string }>,\n options: { slide?: string | number } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_table',\n compact({ updates: updates as unknown as MediaArgJson, slide: slideArg(options.slide) })\n )\n }\n /** Replace an image on a slide with another media. */\n updateImage(\n withMedia: MediaChainRef,\n options: { slide?: string | number; placeholder?: string } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'slides.update_image',\n compact({\n with: refOf(withMedia),\n slide: slideArg(options.slide),\n placeholder: options.placeholder,\n })\n )\n }\n /** Update chart data on a slide. */\n updateChart(data: unknown[][], options: { slide?: string | number } = {}): MediaChain {\n return this.#chain.withOp(\n 'slides.update_chart',\n compact({ data: data as MediaArgJson, slide: slideArg(options.slide) })\n )\n }\n /** Delete slides by 1-based index. */\n delete(slides: number[]): MediaChain {\n return this.#chain.withOp('slides.delete', { slides })\n }\n /** Reorder slides. */\n reorder(order: number[]): MediaChain {\n return this.#chain.withOp('slides.reorder', { order })\n }\n /** Duplicate a slide. */\n duplicate(slide: number, options: { at?: number } = {}): MediaChain {\n return this.#chain.withOp('slides.duplicate', compact({ slide, at: options.at }))\n }\n}\n\n/** `image.*` verbs (the runtime fuses adjacent image steps into one engine pass). */\nexport class ImageNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Resize. */\n resize(options: ResizeOptions): MediaChain {\n return this.#chain.withOp(\n 'image.resize',\n compact({ width: options.width, height: options.height, fit: options.fit })\n )\n }\n /** Re-encode to another format. */\n format(to: string, options: { quality?: number; stripMetadata?: boolean } = {}): MediaChain {\n return this.#chain.withOp(\n 'image.format',\n compact({ to, quality: options.quality, strip_metadata: options.stripMetadata })\n )\n }\n /** Rotate clockwise. */\n rotate(deg: 90 | 180 | 270): MediaChain {\n return this.#chain.withOp('image.rotate', { deg: String(deg) })\n }\n /** Flip. */\n flip(axis: 'horizontal' | 'vertical' | 'both'): MediaChain {\n return this.#chain.withOp('image.flip', { axis })\n }\n /** Strip EXIF/ICC metadata. */\n stripMetadata(): MediaChain {\n return this.#chain.withOp('image.strip_metadata', {})\n }\n}\n\n/** `audio.*` verbs. */\nexport class AudioNamespace {\n readonly #chain: MediaChain\n constructor(chain: MediaChain) {\n this.#chain = chain\n }\n /** Transcribe speech. Terminal: resolves to text (or srt/vtt/json per `out`). */\n transcribe(\n options: { language?: string; out?: 'txt' | 'srt' | 'vtt' | 'json'; translate?: boolean } = {}\n ): MediaChain {\n return this.#chain.withOp(\n 'audio.transcribe',\n compact({ lang: options.language, out: options.out, translate: options.translate })\n )\n }\n}\n\nconst targetArgs = (options: { sheet?: string | number }): Record<string, MediaArgValue> =>\n options.sheet === undefined ? {} : { sheet: options.sheet }\n\nconst slideArg = (slide: string | number | undefined): string | number | undefined => slide\n\nconst compact = (\n args: Record<string, MediaArgValue | undefined>\n): Record<string, MediaArgValue> => {\n const out: Record<string, MediaArgValue> = {}\n for (const [k, v] of Object.entries(args)) {\n if (v !== undefined) out[k] = v\n }\n return out\n}\n\n/** The input shapes `mp(...)` accepts. */\nexport type ChainInput = StepPayload\n","/**\n * The step runtime: executes a validated {@link MediaPlan} as an `@nhtio/middleware` onion,\n * one stage per step, with consumer interceptors wrapping every step.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. A fresh `Runner` is minted per\n * execution (middleware runners are single-use), so the same compiled chain can be awaited\n * repeatedly. Each step stage:\n *\n * 1. runs the consumer's `use` interceptors (the documented seam for DLP/AV scanning, caching\n * via `shortCircuit(bytes)`, byte limits, and telemetry — the battery ships no built-in\n * scanner/cache/limiter: those are policies, this is the seam), then\n * 2. dispatches to the verb's registered {@link StepImpl}, validating the output at the step\n * boundary so a misbehaving engine produces a clear error instead of corrupt bytes.\n *\n * Steps stream bytes in memory; nothing touches disk except inside a binary engine's\n * `ScratchWorkspace`. Adjacent `image.*` steps are fused by the compiler before execution so\n * a resize→format→rotate chain costs a single decode/encode.\n */\n\nimport { VERB_INDEX } from './verbs'\nimport { Middleware } from '@nhtio/middleware'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED, E_MEDIA_STEP_UNAVAILABLE } from './exceptions'\nimport type { NextFn } from '@nhtio/middleware'\nimport type { EngineRegistry } from './registry'\nimport type { MediaPlan, MediaStep, MediaArgValue } from './plan'\n\n/** A single in-flight value travelling between steps. */\nexport interface StepPayload {\n /** The raw content bytes. */\n bytes: Uint8Array\n /** The content MIME type. */\n mimeType: string\n /** The filename (extension informs format dispatch). */\n filename: string\n}\n\n/**\n * What a step produces. `media` continues the chain (or terminates as bytes); `media-list`\n * and `data` are terminal-only shapes enforced by the plan compiler.\n */\nexport type StepResult =\n | { kind: 'media'; payload: StepPayload }\n | { kind: 'media-list'; payloads: StepPayload[] }\n | { kind: 'data'; data: unknown; asText?: string }\n\n/** The mutable execution context threaded through interceptors and step impls. */\nexport interface StepContext {\n /** The whole plan being executed. */\n readonly plan: MediaPlan\n /** Zero-based index of the current step. */\n readonly stepIndex: number\n /** The current step. */\n readonly step: MediaStep\n /** The input payload for this step. */\n payload: StepPayload\n /** Abort signal threaded from the caller. */\n readonly signal?: AbortSignal\n /** Scratchpad shared across the execution (interceptors may stash timings, hashes…). */\n readonly stash: Map<string, unknown>\n /**\n * Short-circuit this step: skip the implementation and continue the chain with `bytes`\n * (the cache idiom). Throws internally — call it, don't return it.\n */\n shortCircuit(payload: StepPayload): never\n /** The deployment's engine registry — ordered, capability-filtered dispatch. */\n readonly engines: EngineRegistry\n /**\n * Resolve another media participating in this step (merge/diff targets), by ref id.\n * Supplied by the pipeline from its configured media resolver.\n */\n resolveRef(id: string): Promise<StepPayload>\n}\n\n/** One verb's implementation. Registered into the runtime's step registry. */\nexport type StepImpl = (ctx: StepContext) => Promise<StepResult>\n\n/** Consumer step interceptor — the `use` seam. Same onion shape as the tool batteries. */\nexport type MediaStepMiddlewareFn = (ctx: StepContext, next: NextFn) => void | Promise<void>\n\n/** Internal sentinel for {@link StepContext.shortCircuit}. */\nconst SHORT_CIRCUIT = Symbol('adk.media.shortCircuit')\n\ninterface ShortCircuitSignal {\n [SHORT_CIRCUIT]: true\n payload: StepPayload\n}\n\nconst isShortCircuit = (value: unknown): value is ShortCircuitSignal =>\n isObject(value) && (value as Record<symbol, unknown>)[SHORT_CIRCUIT] === true\n\n/** Options for {@link executePlan}. */\nexport interface ExecutePlanOptions {\n /** The input payload the first step consumes. */\n input: StepPayload\n /** Verb id → implementation registry. */\n steps: ReadonlyMap<string, StepImpl>\n /** Consumer interceptors wrapping every step. */\n use: readonly MediaStepMiddlewareFn[]\n /** The deployment's engine registry. */\n engines: EngineRegistry\n /** Media-ref resolution for multi-input verbs. */\n resolveRef: StepContext['resolveRef']\n /** Abort signal. */\n signal?: AbortSignal\n}\n\n/** The settled result of executing a whole plan. */\nexport type PlanResult = StepResult\n\n/**\n * Execute a validated plan. Returns the final step's result; intermediate steps must produce\n * `media` results (the compiler guarantees non-terminal steps are media-shaped).\n *\n * @param plan - The validated plan.\n * @param options - Input payload, step registry, interceptors, engine access.\n * @returns The terminal step's result.\n */\nexport const executePlan = async (\n plan: MediaPlan,\n options: ExecutePlanOptions\n): Promise<PlanResult> => {\n const stash = new Map<string, unknown>()\n let payload = options.input\n let result: PlanResult = { kind: 'media', payload }\n\n for (let i = 0; i < plan.steps.length; i++) {\n const step = plan.steps[i]\n options.signal?.throwIfAborted()\n const impl = options.steps.get(step.verb)\n if (!impl) {\n throw new E_MEDIA_STEP_UNAVAILABLE([step.verb])\n }\n\n const ctx: StepContext = {\n plan,\n stepIndex: i,\n step,\n payload,\n signal: options.signal,\n stash,\n shortCircuit: (sc: StepPayload): never => {\n const signal: ShortCircuitSignal = { [SHORT_CIRCUIT]: true, payload: sc }\n throw signal\n },\n engines: options.engines,\n resolveRef: options.resolveRef,\n }\n\n try {\n result = await runStep(ctx, impl, options.use)\n } catch (err) {\n if (isShortCircuit(err)) {\n result = { kind: 'media', payload: err.payload }\n } else if (isError(err) && err.name.startsWith('E_MEDIA_')) {\n throw err\n } else {\n const detail = isError(err) ? err.message : String(err)\n throw new E_MEDIA_STEP_FAILED([step.verb, detail], { cause: err })\n }\n }\n\n if (result.kind === 'media') {\n payload = result.payload\n } else if (i < plan.steps.length - 1) {\n if (\n result.kind === 'data' &&\n typeof result.asText === 'string' &&\n VERB_INDEX.get(step.verb)?.output === 'text'\n ) {\n // R-step materialization (frozen 0.10): a non-terminal read step yields a text Media\n // into the chain, so `extract text | chunk` is type-sound.\n payload = {\n bytes: new TextEncoder().encode(result.asText),\n mimeType: 'text/plain',\n filename: materializedName(payload.filename),\n }\n result = { kind: 'media', payload }\n } else {\n throw new E_MEDIA_STEP_FAILED([\n step.verb,\n 'a non-terminal step produced a terminal result; only the last step may yield data or multiple media',\n ])\n }\n }\n }\n return result\n}\n\n/** Run one step: interceptor onion (fresh runner) terminating in the implementation. */\nconst runStep = async (\n ctx: StepContext,\n impl: StepImpl,\n use: readonly MediaStepMiddlewareFn[]\n): Promise<StepResult> => {\n if (use.length === 0) {\n return validated(ctx, await impl(ctx))\n }\n const mw = new Middleware<MediaStepMiddlewareFn>()\n for (const fn of use) mw.add(fn)\n\n let result: StepResult | undefined\n let caught: unknown\n await mw\n .runner()\n .errorHandler(async (error: unknown) => {\n caught = error\n })\n .finalHandler(async () => {\n result = validated(ctx, await impl(ctx))\n })\n .run((fn, next) => Promise.resolve(fn(ctx, next)))\n\n if (caught !== undefined) throw caught\n if (result === undefined) {\n throw new E_MEDIA_STEP_FAILED([\n ctx.step.verb,\n 'a step interceptor did not call next() and did not short-circuit',\n ])\n }\n return result\n}\n\n/** Validate a step implementation's output shape at the boundary. */\nconst validated = (ctx: StepContext, result: StepResult): StepResult => {\n const bad = (msg: string): never => {\n throw new E_MEDIA_STEP_FAILED([ctx.step.verb, `implementation returned ${msg}`])\n }\n const isBytes = (value: unknown): value is Uint8Array =>\n isInstanceOf(value, 'Uint8Array', Uint8Array)\n if (result.kind === 'media') {\n if (!isBytes(result.payload?.bytes)) bad('a media result without bytes')\n if (typeof result.payload.mimeType !== 'string') bad('a media result without a mimeType')\n return result\n }\n if (result.kind === 'media-list') {\n if (!Array.isArray(result.payloads) || result.payloads.some((p) => !isBytes(p.bytes))) {\n bad('a media-list result with invalid payloads')\n }\n return result\n }\n if (result.kind === 'data') return result\n return bad('an unknown result kind')\n}\n\n/** Filename for an R-step's materialized text payload. */\nconst materializedName = (filename: string): string => {\n const dot = filename.lastIndexOf('.')\n const base = dot > 0 ? filename.slice(0, dot) : filename\n return `${base}.txt`\n}\n\n/** Convenience: read a step arg with a typed cast (validation already ran). */\nexport const argOf = <T extends MediaArgValue>(step: MediaStep, name: string): T | undefined =>\n step.args[name] as T | undefined\n","/**\n * The structured apply_patch envelope: parser and applier for the\n * `*** Begin Patch` multi-file dialect.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. This dialect derives from the\n * GitHub Copilot apply_patch format — one of the most robust and battle-tested patch formats\n * in production use, which is also why models already know how to write it. The grammar\n * (`*** Begin Patch` … `*** End Patch`, `*** Add File:` / `*** Delete File:` /\n * `*** Update File:` (+ `*** Move to:`), `@@` context hunks with `+`/`-`/space lines) is\n * preserved exactly — inventing a \"better\" variation would forfeit the pretraining. Ported\n * from the source server's `doc.apply_patch` adapter (its green e2e suite informs the spec\n * coverage); the context matcher rejects ambiguity (a hunk whose context matches more than\n * one location fails rather than guessing).\n */\n\n/** One parsed `@@` hunk: the context+removal lines and their replacement. */\nexport interface ParsedHunk {\n oldLines: string[]\n newLines: string[]\n added: number\n removed: number\n}\n\n/** `*** Add File:` — create a new file from `+` lines. */\nexport interface AddOperation {\n type: 'add'\n path: string\n content: string\n added: number\n}\n\n/** `*** Delete File:` — remove a file. */\nexport interface DeleteOperation {\n type: 'delete'\n path: string\n}\n\n/** `*** Update File:` (+ optional `*** Move to:`) — apply hunks, optionally rename. */\nexport interface UpdateOperation {\n type: 'update'\n path: string\n movePath?: string\n hunks: ParsedHunk[]\n added: number\n removed: number\n}\n\n/** Any one operation of a structured patch. */\nexport type PatchOperation = AddOperation | DeleteOperation | UpdateOperation\n\n/** The parsed envelope: ordered operations plus totals. */\nexport interface ParsedApplyPatch {\n operations: PatchOperation[]\n added: number\n removed: number\n}\n\nconst PATCH_PREFIX = '*** Begin Patch'\nconst PATCH_SUFFIX = '*** End Patch'\nconst ADD_FILE_PREFIX = '*** Add File:'\nconst DELETE_FILE_PREFIX = '*** Delete File:'\nconst UPDATE_FILE_PREFIX = '*** Update File:'\nconst MOVE_TO_PREFIX = '*** Move to:'\n\n/** `true` when `patch` is the structured envelope rather than a unified diff. */\nexport const isStructuredPatch = (patch: string): boolean =>\n patch.trimStart().startsWith(PATCH_PREFIX)\n\n/** Normalize a workspace path: relative, no `.`/`..`/empty segments, forward slashes. */\nexport const normalizeWorkspacePath = (path: string): string => {\n const normalized = path.replace(/\\\\/g, '/').trim()\n if (!normalized) {\n throw new Error('apply_patch path cannot be empty')\n }\n if (normalized.startsWith('/') || /^[A-Za-z]:/.test(normalized)) {\n throw new Error(`apply_patch path \"${path}\" must be relative to the workspace root`)\n }\n const segments = normalized.split('/')\n const sanitizedSegments: string[] = []\n for (const segment of segments) {\n if (!segment || segment === '.' || segment === '..') {\n throw new Error(\n `apply_patch path \"${path}\" contains invalid segment \"${segment || '(empty)'}\"`\n )\n }\n sanitizedSegments.push(segment)\n }\n return sanitizedSegments.join('/')\n}\n\n/**\n * Parse a structured `*** Begin Patch` envelope.\n *\n * @param patch - The raw patch text.\n * @returns The parsed operations.\n */\nexport const parseStructuredPatch = (patch: string): ParsedApplyPatch => {\n const lines = patch.replace(/\\r\\n/g, '\\n').split('\\n')\n const firstLine = lines[0]?.trim()\n if (firstLine !== PATCH_PREFIX) {\n throw new Error('a structured patch must start with \"*** Begin Patch\"')\n }\n\n const lastNonEmptyIndex = [...lines].reverse().findIndex((line) => line.trim() !== '')\n const endIndex = lastNonEmptyIndex === -1 ? -1 : lines.length - 1 - lastNonEmptyIndex\n if (endIndex < 0 || lines[endIndex]?.trim() !== PATCH_SUFFIX) {\n throw new Error('a structured patch must end with \"*** End Patch\"')\n }\n\n const body = lines.slice(1, endIndex)\n\n const operations: PatchOperation[] = []\n let totalAdded = 0\n let totalRemoved = 0\n let i = 0\n\n while (i < body.length) {\n const line = body[i] ?? ''\n\n if (line.trim() === '' || line.startsWith('*** End of File')) {\n i += 1\n continue\n }\n\n if (line.startsWith(ADD_FILE_PREFIX)) {\n const path = normalizeWorkspacePath(line.slice(ADD_FILE_PREFIX.length).trim())\n i += 1\n const contentLines: string[] = []\n while (i < body.length) {\n const next = body[i] ?? ''\n if (next.startsWith('*** ')) {\n break\n }\n if (!next.startsWith('+')) {\n throw new Error(`apply_patch add-file line must start with \"+\": \"${next}\"`)\n }\n contentLines.push(next.slice(1))\n i += 1\n }\n\n operations.push({\n type: 'add',\n path,\n content: contentLines.join('\\n'),\n added: contentLines.length,\n })\n totalAdded += contentLines.length\n continue\n }\n\n if (line.startsWith(DELETE_FILE_PREFIX)) {\n const path = normalizeWorkspacePath(line.slice(DELETE_FILE_PREFIX.length).trim())\n operations.push({ type: 'delete', path })\n i += 1\n continue\n }\n\n if (!line.startsWith(UPDATE_FILE_PREFIX)) {\n throw new Error(`apply_patch invalid structured patch header: \"${line}\"`)\n }\n\n const path = normalizeWorkspacePath(line.slice(UPDATE_FILE_PREFIX.length).trim())\n i += 1\n\n let movePath: string | undefined\n if ((body[i] ?? '').startsWith(MOVE_TO_PREFIX)) {\n movePath = normalizeWorkspacePath((body[i] ?? '').slice(MOVE_TO_PREFIX.length).trim())\n i += 1\n }\n\n const hunks: ParsedHunk[] = []\n let opAdded = 0\n let opRemoved = 0\n\n while (i < body.length && (body[i] ?? '').startsWith('@@')) {\n i += 1\n const hunkLines: string[] = []\n while (i < body.length) {\n const next = body[i] ?? ''\n if (next.startsWith('@@') || next.startsWith('*** ')) {\n break\n }\n hunkLines.push(next)\n i += 1\n }\n\n if (hunkLines.length === 0) {\n throw new Error('apply_patch contains an empty hunk')\n }\n\n const oldLines: string[] = []\n const newLines: string[] = []\n let added = 0\n let removed = 0\n\n for (const hunkLine of hunkLines) {\n if (hunkLine.startsWith('+')) {\n newLines.push(hunkLine.slice(1))\n added += 1\n } else if (hunkLine.startsWith('-')) {\n oldLines.push(hunkLine.slice(1))\n removed += 1\n } else if (hunkLine.startsWith(' ')) {\n const contextLine = hunkLine.slice(1)\n oldLines.push(contextLine)\n newLines.push(contextLine)\n } else {\n throw new Error(\n `apply_patch invalid hunk line (must start with +, -, or space): \"${hunkLine}\"`\n )\n }\n }\n\n if (added === 0 && removed === 0) {\n throw new Error('apply_patch hunk must contain at least one added or removed line')\n }\n\n opAdded += added\n opRemoved += removed\n hunks.push({ oldLines, newLines, added, removed })\n }\n\n if (hunks.length === 0) {\n throw new Error(`apply_patch update operation for \"${path}\" must contain at least one hunk`)\n }\n\n operations.push({ type: 'update', path, movePath, hunks, added: opAdded, removed: opRemoved })\n totalAdded += opAdded\n totalRemoved += opRemoved\n }\n\n if (operations.length === 0) {\n throw new Error('apply_patch contains no operations')\n }\n\n return {\n operations,\n added: totalAdded,\n removed: totalRemoved,\n }\n}\n\nconst countSequenceMatches = (haystack: string[], needle: string[], start: number): number => {\n if (needle.length === 0) {\n return 0\n }\n let matches = 0\n let i = start\n while (i <= haystack.length - needle.length) {\n let matched = true\n let j = 0\n while (j < needle.length) {\n if (haystack[i + j] !== needle[j]) {\n matched = false\n break\n }\n j += 1\n }\n if (matched) {\n matches += 1\n }\n i += 1\n }\n return matches\n}\n\nconst findExactSequence = (haystack: string[], needle: string[], start: number): number => {\n if (needle.length === 0) {\n return start\n }\n let i = start\n while (i <= haystack.length - needle.length) {\n let matched = true\n let j = 0\n while (j < needle.length) {\n if (haystack[i + j] !== needle[j]) {\n matched = false\n break\n }\n j += 1\n }\n if (matched) {\n return i\n }\n i += 1\n }\n return -1\n}\n\n/**\n * Apply an update operation's hunks to `inputText`. Context matching is exact and rejects\n * ambiguity: a hunk whose old-lines match more than one location past the cursor fails\n * rather than guessing.\n *\n * @param inputText - The file's current text.\n * @param hunks - The parsed hunks, in order.\n * @returns The patched text.\n */\nexport const applyUpdateHunks = (inputText: string, hunks: ParsedHunk[]): string => {\n const lines = inputText.replace(/\\r\\n/g, '\\n').split('\\n')\n let cursor = 0\n for (const hunk of hunks) {\n const matchCount = countSequenceMatches(lines, hunk.oldLines, cursor)\n if (matchCount > 1) {\n throw new Error('patch context is ambiguous and matches multiple locations')\n }\n const start = findExactSequence(lines, hunk.oldLines, cursor)\n if (start === -1) {\n throw new Error('the patch could not be applied cleanly to the source text')\n }\n lines.splice(start, hunk.oldLines.length, ...hunk.newLines)\n cursor = start + hunk.newLines.length\n }\n return lines.join('\\n')\n}\n\n/** One file in the virtual workspace a structured patch operates over. */\nexport interface WorkspaceFile {\n text: string\n mimeType: string\n}\n\n/**\n * Apply a parsed structured patch to a virtual workspace of files keyed by normalized path.\n *\n * @param files - The workspace (mutated in place).\n * @param patch - The parsed envelope.\n * @returns The workspace and the number of files touched.\n */\nexport const applyOperations = (\n files: Map<string, WorkspaceFile>,\n patch: ParsedApplyPatch\n): { files: Map<string, WorkspaceFile>; modifiedFiles: number } => {\n let modifiedFiles = 0\n\n for (const operation of patch.operations) {\n if (operation.type === 'add') {\n if (files.has(operation.path)) {\n throw new Error(`cannot add file \"${operation.path}\": the path already exists`)\n }\n files.set(operation.path, {\n text: operation.content,\n mimeType: inferTextMimeFromPath(operation.path),\n })\n modifiedFiles += 1\n continue\n }\n\n if (operation.type === 'delete') {\n if (!files.has(operation.path)) {\n throw new Error(`cannot delete file \"${operation.path}\": the path does not exist`)\n }\n files.delete(operation.path)\n modifiedFiles += 1\n continue\n }\n\n const current = files.get(operation.path)\n if (!current) {\n throw new Error(`cannot update file \"${operation.path}\": the path does not exist`)\n }\n\n const updatedText = applyUpdateHunks(current.text, operation.hunks)\n const targetPath = operation.movePath ?? operation.path\n\n if (operation.movePath && files.has(targetPath)) {\n throw new Error(\n `cannot move file \"${operation.path}\" to \"${targetPath}\": the target already exists`\n )\n }\n\n files.delete(operation.path)\n files.set(targetPath, {\n text: updatedText,\n mimeType: current.mimeType,\n })\n modifiedFiles += 1\n }\n\n return { files, modifiedFiles }\n}\n\n/** Infer a text MIME from a workspace path's extension (Add File outputs). */\nexport const inferTextMimeFromPath = (path: string): string => {\n const dot = path.lastIndexOf('.')\n const ext = dot > 0 ? path.slice(dot + 1).toLowerCase() : ''\n if (ext === 'json') return 'application/json'\n if (ext === 'md' || ext === 'markdown') return 'text/markdown'\n if (ext === 'csv') return 'text/csv'\n if (ext === 'yaml' || ext === 'yml') return 'application/yaml'\n if (ext === 'html' || ext === 'htm') return 'text/html'\n return 'text/plain'\n}\n","/**\n * Pure text-shaped step implementations: chunking, plain-text extraction, text diff/patch,\n * and the text-mode redact/update_text paths.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The split functions are ported\n * verbatim from the source server's `chunk_text` adapter (its green unit suite ports with\n * them). All implementations here operate on in-memory bytes and run in any environment.\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { familyOf, replaceExtension, MIME } from '../formats'\nimport {\n isStructuredPatch,\n parseStructuredPatch,\n applyOperations,\n normalizeWorkspacePath,\n} from './patch'\nimport type { ParsedApplyPatch, WorkspaceFile } from './patch'\nimport type { RegExpRef, MediaRef, MediaArgScalar } from '../plan'\nimport type { StepImpl, StepResult, StepPayload } from '../runtime'\n\n/** One text chunk with its position in the source. */\nexport interface Chunk {\n index: number\n text: string\n char_start: number\n char_end: number\n}\n\n/** Split text on double-newline paragraph boundaries, with optional character overlap. */\nexport const splitParagraph = (text: string, overlap: number): Chunk[] => {\n const blocks = text\n .split(/\\n{2,}/)\n .map((b) => b.trim())\n .filter(Boolean)\n const chunks: Chunk[] = []\n let pos = 0\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i]\n const overlapText =\n i > 0 && overlap > 0\n ? blocks\n .slice(Math.max(0, i - 1), i)\n .join('\\n\\n')\n .slice(-overlap)\n : ''\n const chunkText = overlapText ? `${overlapText}\\n\\n${block}` : block\n chunks.push({ index: i, text: chunkText, char_start: pos, char_end: pos + block.length })\n pos += block.length + 2\n }\n return chunks\n}\n\n/** Split text on sentence-ending punctuation, with optional character overlap. */\nexport const splitSentence = (text: string, overlap: number): Chunk[] => {\n const sentences = text.match(/[^.!?]+[.!?](?:\\s|$)|[^.!?]+$/g) ?? [text]\n const chunks: Chunk[] = []\n let pos = 0\n for (let i = 0; i < sentences.length; i++) {\n const sentence = sentences[i].trim()\n if (!sentence) continue\n const overlapText =\n i > 0 && overlap > 0\n ? sentences\n .slice(Math.max(0, i - 1), i)\n .join(' ')\n .slice(-overlap)\n : ''\n const chunkText = overlapText ? `${overlapText} ${sentence}` : sentence\n chunks.push({\n index: chunks.length,\n text: chunkText,\n char_start: pos,\n char_end: pos + sentence.length,\n })\n pos += sentence.length + 1\n }\n return chunks\n}\n\n/** Split text into fixed-size character windows with optional overlap. */\nexport const splitFixed = (text: string, chunkSize: number, overlap: number): Chunk[] => {\n const chunks: Chunk[] = []\n const step = Math.max(1, chunkSize - overlap)\n let i = 0\n let idx = 0\n while (i < text.length) {\n const start = Math.max(0, i - overlap)\n const end = i + chunkSize\n chunks.push({\n index: idx++,\n text: text.slice(start, end),\n char_start: start,\n char_end: Math.min(end, text.length),\n })\n i += step\n }\n return chunks\n}\n\nconst decoder = new TextDecoder('utf-8', { fatal: false })\nconst encoder = new TextEncoder()\n\n/** Decode payload bytes as UTF-8 text (UTF-16 BOM aware). */\nexport const decodeText = (bytes: Uint8Array): string => {\n if (bytes.length >= 2) {\n if (bytes[0] === 0xff && bytes[1] === 0xfe) {\n return new TextDecoder('utf-16le').decode(bytes.subarray(2))\n }\n if (bytes[0] === 0xfe && bytes[1] === 0xff) {\n return new TextDecoder('utf-16be').decode(bytes.subarray(2))\n }\n }\n return decoder.decode(bytes).replace(/\\r\\n?/g, '\\n')\n}\n\nconst textPayload = (source: StepPayload, text: string, suffix: string): StepPayload => ({\n bytes: encoder.encode(text),\n mimeType: MIME.TXT,\n filename: replaceExtension(source.filename, suffix),\n})\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `chunk` — split text content into retrieval chunks (data result). */\nexport const chunkStep: StepImpl = async (ctx) => {\n const by = argOf<string>(ctx.step, 'by') ?? 'paragraph'\n const size = argOf<number>(ctx.step, 'size') ?? 1000\n const overlap = argOf<number>(ctx.step, 'overlap') ?? 0\n const text = decodeText(ctx.payload.bytes)\n const chunks =\n by === 'sentence'\n ? splitSentence(text, overlap)\n : by === 'fixed'\n ? splitFixed(text, size, overlap)\n : splitParagraph(text, overlap)\n return { kind: 'data', data: chunks, asText: JSON.stringify(chunks) }\n}\n\n/**\n * `extract.text` — Phase 0 covers the native-text path (txt/md/csv/json/html). Document\n * formats (pdf/docx/…) and OCR routes are added by later phases; until then they fail with a\n * clear reason.\n */\nexport const extractTextStep: StepImpl = async (ctx) => {\n const family = familyOf(ctx.payload.mimeType)\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const isNativeText =\n mime.startsWith('text/') || mime === MIME.JSON || mime === MIME.MD || mime === MIME.CSV\n if (!isNativeText) {\n throw new E_MEDIA_STEP_FAILED([\n 'extract.text',\n `extraction for ${family} media (${mime}) is not yet implemented in this build`,\n ])\n }\n const text = decodeText(ctx.payload.bytes)\n return {\n kind: 'data',\n data: text,\n asText: text,\n }\n}\n\n/** `extract.metadata` — Phase 0: size/MIME/filename basics (format-aware fields come later). */\nexport const extractMetadataStep: StepImpl = async (ctx) => {\n const meta = {\n filename: ctx.payload.filename,\n mime_type: ctx.payload.mimeType,\n size_bytes: ctx.payload.bytes.byteLength,\n family: familyOf(ctx.payload.mimeType),\n }\n return { kind: 'data', data: meta, asText: JSON.stringify(meta) }\n}\n\nconst toPattern = (value: MediaArgScalar): RegExp | string => {\n if (typeof value === 'string') return value\n const ref = value as RegExpRef\n return new RegExp(ref.source, ref.flags.includes('g') ? ref.flags : `${ref.flags}g`)\n}\n\nconst applyRedaction = (text: string, patterns: MediaArgScalar[], replacement: string): string => {\n let out = text\n for (const p of patterns) {\n const pattern = toPattern(p)\n out =\n typeof pattern === 'string'\n ? out.split(pattern).join(replacement)\n : out.replace(pattern, replacement)\n }\n return out\n}\n\n/** `redact` — Phase 0: the text-media path. Document-format in-place redaction lands later. */\nexport const redactStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase()\n if (!mime.startsWith('text/')) {\n throw new E_MEDIA_STEP_FAILED([\n 'redact',\n `redaction for ${ctx.payload.mimeType} is not yet implemented in this build`,\n ])\n }\n const raw = ctx.step.args.match\n const patterns = (Array.isArray(raw) ? raw : [raw]) as MediaArgScalar[]\n const replacement = argOf<string>(ctx.step, 'replace') ?? '█'\n const text = applyRedaction(decodeText(ctx.payload.bytes), patterns, replacement)\n return { kind: 'media', payload: textPayload(ctx.payload, text, 'txt') }\n}\n\n/** `update_text` — Phase 0: the text-media path. */\nexport const updateTextStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase()\n if (!mime.startsWith('text/')) {\n throw new E_MEDIA_STEP_FAILED([\n 'update_text',\n `text update for ${ctx.payload.mimeType} is not yet implemented in this build`,\n ])\n }\n const anchor = argOf<string>(ctx.step, 'anchor') as string\n const replace = argOf<string>(ctx.step, 'replace') ?? ''\n const text = decodeText(ctx.payload.bytes)\n if (!text.includes(anchor)) {\n throw new E_MEDIA_STEP_FAILED([\n 'update_text',\n `anchor text not found: \"${anchor.slice(0, 80)}\"`,\n ])\n }\n const updated = text.replace(anchor, replace)\n return { kind: 'media', payload: { ...ctx.payload, bytes: encoder.encode(updated) } }\n}\n\n/** Build a unified diff between two texts using the `diff` peer (lazy import). */\nconst unifiedDiff = async (aName: string, bName: string, a: string, b: string): Promise<string> => {\n const mod = await import('diff')\n return mod.createTwoFilesPatch(aName, bName, a, b)\n}\n\n/** `diff` — compare against another media (text-comparable formats in Phase 0). */\nexport const diffStep: StepImpl = async (ctx) => {\n const ref = ctx.step.args.with as MediaRef\n if (ref.kind !== 'id') {\n throw new E_MEDIA_STEP_FAILED(['diff', 'builder refs are not yet supported here'])\n }\n const other = await ctx.resolveRef(ref.id)\n const a = decodeText(ctx.payload.bytes)\n const b = decodeText(other.bytes)\n const patch = await unifiedDiff(ctx.payload.filename, other.filename, a, b)\n const mod = await import('diff')\n const structured = mod.diffLines(a, b).map((part) => ({\n added: part.added === true,\n removed: part.removed === true,\n count: part.count ?? 0,\n value: part.value,\n }))\n const data = { patch, changes: structured }\n return { kind: 'data', data, asText: patch }\n}\n\n/**\n * `apply_patch` — apply a unified diff, or a structured `*** Begin Patch` envelope\n * (multi-file Add/Delete/Update/Move — the GitHub Copilot apply_patch dialect).\n */\nexport const applyPatchStep: StepImpl = async (ctx) => {\n const patch = argOf<string>(ctx.step, 'patch') as string\n if (isStructuredPatch(patch)) return applyStructuredPatch(ctx, patch)\n const text = decodeText(ctx.payload.bytes)\n const mod = await import('diff')\n const result = mod.applyPatch(text, patch)\n if (result === false) {\n throw new E_MEDIA_STEP_FAILED([\n 'apply_patch',\n 'the patch does not apply to this media content (context mismatch)',\n ])\n }\n return { kind: 'media', payload: { ...ctx.payload, bytes: encoder.encode(result) } }\n}\n\n/** The structured-envelope path: primary media + `with=@refs` form a virtual workspace. */\nconst applyStructuredPatch = async (\n ctx: Parameters<StepImpl>[0],\n patch: string\n): Promise<StepResult> => {\n const verb = 'apply_patch'\n const fail = (message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n }\n\n // Build the workspace: the primary media plus any @refs, keyed by normalized filename.\n const files = new Map<string, WorkspaceFile>()\n const addToWorkspace = (payload: StepPayload): void => {\n let path: string\n try {\n path = normalizeWorkspacePath(payload.filename)\n } catch (err) {\n fail(isError(err) ? err.message : String(err))\n /* unreachable */ throw err\n }\n if (files.has(path)) fail(`duplicate workspace path in inputs: \"${path}\"`)\n files.set(path, { text: decodeText(payload.bytes), mimeType: payload.mimeType })\n }\n addToWorkspace(ctx.payload)\n const raw = ctx.step.args.with\n if (raw !== undefined) {\n const refs = (Array.isArray(raw) ? raw : [raw]) as MediaRef[]\n for (const ref of refs) {\n if (ref.kind !== 'id') fail('builder refs are not yet supported here')\n addToWorkspace(await ctx.resolveRef((ref as { kind: 'id'; id: string }).id))\n }\n }\n\n let parsed: ParsedApplyPatch\n let applied: { files: Map<string, WorkspaceFile>; modifiedFiles: number }\n try {\n parsed = parseStructuredPatch(patch)\n applied = applyOperations(files, parsed)\n } catch (err) {\n fail(isError(err) ? err.message : String(err))\n /* unreachable */ throw err\n }\n\n const finalFiles = [...applied.files.entries()].sort(([a], [b]) => a.localeCompare(b))\n const payloads: StepPayload[] = finalFiles.map(([path, file]) => ({\n bytes: encoder.encode(file.text),\n mimeType: file.mimeType,\n filename: path,\n }))\n if (payloads.length === 0) fail('the patch deleted every file in the workspace')\n if (payloads.length === 1) return { kind: 'media', payload: payloads[0] }\n return { kind: 'media-list', payloads }\n}\n","/**\n * Doc-domain step extensions: format-preserving text mutation for DOCX/PPTX/ODF, PDF visual\n * redaction, asset extraction from OOXML/ODF archives and PDFs, and format conversion via the\n * convert engine.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * doc adapters; the format-dispatch contract follows the server's green e2e suite: DOCX and\n * PPTX redact/sanitize/normalize/update_text mutate text in place inside the container\n * (preserving the source format); ODT/ODS/ODP redact/update_text mutate `content.xml` the\n * same way; text-like inputs mutate as text. PDF redact is VISUAL (pdf-lib draw-over +\n * metadata strip — content streams keep the text); the result carries that warning verbatim\n * because it is a trust boundary, not a footnote.\n */\n\nimport { MIME } from '../formats'\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { redactStep as textRedactStep, updateTextStep as textUpdateTextStep } from './text'\nimport type { default as JSZipNS } from 'jszip'\nimport type { RegExpRef, MediaArgScalar } from '../plan'\nimport type { StepImpl, StepContext, StepResult, StepPayload } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\nconst escapeXml = (value: string): string =>\n value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n\nconst unescapeXml = (value: string): string =>\n value\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n\n// ── OOXML text mutation (ported run-aggregation semantics) ───────────────────\n\n/**\n * Replace matches inside text nodes of OOXML, aggregating runs per paragraph so patterns\n * spanning split runs still match (Word splits text across `w:t` runs on formatting changes).\n */\nconst replaceInOoxml = (\n xml: string,\n paragraphTag: 'w:p' | 'a:p',\n textTag: 'w:t' | 'a:t',\n pattern: RegExp,\n replacement: string\n): { xml: string; matchCount: number } => {\n let totalMatches = 0\n const pRegex = new RegExp(`<${paragraphTag}\\\\b[^>]*>[\\\\s\\\\S]*?</${paragraphTag}>`, 'g')\n const result = xml.replace(pRegex, (pXml) => {\n const tElements: Array<{ start: number; end: number; content: string }> = []\n const tRegex = new RegExp(`<${textTag}(?:\\\\s[^>]*)?>([^<]*)</${textTag}>`, 'g')\n let tMatch: RegExpExecArray | null\n while ((tMatch = tRegex.exec(pXml))) {\n tElements.push({\n start: tMatch.index,\n end: tMatch.index + tMatch[0].length,\n content: unescapeXml(tMatch[1]),\n })\n }\n if (tElements.length === 0) return pXml\n const aggregated = tElements.map((t) => t.content).join('')\n const p = new RegExp(pattern.source, pattern.flags)\n const replaced = aggregated.replace(p, replacement)\n if (replaced === aggregated) return pXml\n const counter = new RegExp(pattern.source, pattern.flags)\n while (counter.exec(aggregated)) {\n totalMatches += 1\n if (!counter.global) break\n }\n let out = pXml\n for (let i = tElements.length - 1; i >= 0; i--) {\n const el = tElements[i]\n const space = textTag === 'w:t' && i === 0 ? ' xml:space=\"preserve\"' : ''\n const content = i === 0 ? escapeXml(replaced) : ''\n out =\n out.slice(0, el.start) + `<${textTag}${space}>${content}</${textTag}>` + out.slice(el.end)\n }\n return out\n })\n return { xml: result, matchCount: totalMatches }\n}\n\n/** Map text-node mutation over every relevant part of a DOCX or PPTX archive. */\nconst mutateOoxmlText = async (\n ctx: StepContext,\n verb: string,\n mutateXml: (xml: string, kind: 'docx' | 'pptx') => string\n): Promise<StepResult> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const kind = mime === MIME.DOCX ? 'docx' : 'pptx'\n const JSZip = await jszip()\n let zip: JSZipNS\n try {\n zip = await JSZip.loadAsync(ctx.payload.bytes)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the document container: ${detail}`)\n /* unreachable */ throw err\n }\n const parts =\n kind === 'docx'\n ? Object.keys(zip.files).filter((n) => /^word\\/(document|header\\d*|footer\\d*)\\.xml$/.test(n))\n : Object.keys(zip.files).filter((n) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n))\n if (parts.length === 0) fail(verb, 'the container has no text parts to mutate (corrupt file?)')\n for (const part of parts) {\n const xml = await zip.file(part)!.async('text')\n const next = mutateXml(xml, kind)\n if (next !== xml) zip.file(part, next)\n }\n const bytes = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE' })\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\nconst toGlobalRegex = (value: MediaArgScalar): RegExp => {\n if (typeof value === 'string') {\n const escaped = value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return new RegExp(escaped, 'g')\n }\n const ref = value as RegExpRef\n return new RegExp(ref.source, ref.flags.includes('g') ? ref.flags : `${ref.flags}g`)\n}\n\n// ── ODF (content.xml) text mutation — ported from the server's odf_xml.ts ───\n\nconst ODF_MIMES: ReadonlySet<string> = new Set([MIME.ODT, MIME.ODS, MIME.ODP])\n\n/**\n * Replace matches inside the text nodes of ODF `content.xml`, aggregating per paragraph so\n * patterns spanning `<text:span>` formatting splits still match.\n */\nconst replaceTextInContentXml = (\n xml: string,\n pattern: RegExp,\n replacement: string\n): { xml: string; matchCount: number } => {\n let totalMatches = 0\n const result = xml.replace(/<text:(?:p|h)\\b[^>]*>[\\s\\S]*?<\\/text:(?:p|h)>/g, (paragraphXml) => {\n const textNodes: Array<{ content: string; start: number; end: number }> = []\n const textRegex = />([^<]+)</g\n let match: RegExpExecArray | null\n while ((match = textRegex.exec(paragraphXml))) {\n const content = unescapeXml(match[1])\n if (content.trim() === '') continue\n textNodes.push({ content, start: match.index, end: match.index + match[0].length })\n }\n if (textNodes.length === 0) return paragraphXml\n const aggregated = textNodes.map((n) => n.content).join('')\n const p = new RegExp(pattern.source, pattern.flags)\n const replaced = aggregated.replace(p, replacement)\n if (replaced === aggregated) return paragraphXml\n const counter = new RegExp(pattern.source, pattern.flags)\n while (counter.exec(aggregated)) {\n totalMatches += 1\n if (!counter.global) break\n }\n // Put all content in the first text node, empty the rest.\n let out = paragraphXml\n for (let i = textNodes.length - 1; i >= 0; i--) {\n const node = textNodes[i]\n const newContent = i === 0 ? escapeXml(replaced) : ''\n out = out.slice(0, node.start) + `>${newContent}<` + out.slice(node.end)\n }\n return out\n })\n return { xml: result, matchCount: totalMatches }\n}\n\n/** Map a `content.xml` mutation over an ODF container (ODT/ODS/ODP). */\nconst mutateOdfText = async (\n ctx: StepContext,\n verb: string,\n mutateXml: (xml: string) => string\n): Promise<StepResult> => {\n const JSZip = await jszip()\n let zip: JSZipNS\n try {\n zip = await JSZip.loadAsync(ctx.payload.bytes)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the document container: ${detail}`)\n /* unreachable */ throw err\n }\n const part = zip.file('content.xml')\n if (!part) fail(verb, 'the ODF container has no content.xml (corrupt file?)')\n const xml = await part!.async('text')\n const next = mutateXml(xml)\n if (next !== xml) zip.file('content.xml', next)\n const bytes = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE' })\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\n// ── PDF visual redaction — ported from the server's pdf_mutation.ts ─────────\n\n/**\n * The honest caveat every PDF redaction result must carry. Visual redaction draws over\n * matched pages and strips metadata; the content streams still contain the original text.\n */\nexport const PDF_REDACTION_WARNING =\n 'PDF redaction applies visual annotations. Content streams are not modified. For full content-level redaction, convert to text first.'\n\n/** Visual page-level redaction: draw-over banner on matching pages + metadata strip. */\nconst redactPdf = async (\n ctx: StepContext,\n verb: string,\n patterns: RegExp[]\n): Promise<StepResult> => {\n const { PDFDocument, PDFName, PDFString, rgb, StandardFonts } = await import('pdf-lib')\n let doc: Awaited<ReturnType<typeof PDFDocument.load>>\n try {\n doc = await PDFDocument.load(ctx.payload.bytes, { ignoreEncryption: true })\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not parse the PDF: ${detail}`)\n /* unreachable */ throw err\n }\n\n // Per-page text via the same extractor the ingest steps use.\n let pageTexts: string[] = []\n try {\n const { PDFParse } = await import('pdf-parse')\n const parser = new PDFParse({ data: ctx.payload.bytes })\n const result = await parser.getText()\n pageTexts = result.pages.map((p: { text?: string }) => p.text ?? '')\n } catch {\n pageTexts = []\n }\n\n const pages = doc.getPages()\n const font = await doc.embedFont(StandardFonts.Helvetica)\n let pagesRedacted = 0\n for (const [i, page] of pages.entries()) {\n const pageText = pageTexts[i] ?? ''\n const hasMatch = patterns.some((pattern) =>\n new RegExp(pattern.source, pattern.flags).test(pageText)\n )\n if (!hasMatch) continue\n const { width } = page.getSize()\n page.drawRectangle({ x: 0, y: 0, width, height: 14, color: rgb(1, 1, 0.9) })\n page.drawText(`[Page ${i + 1}: content redacted]`, {\n x: 4,\n y: 2,\n size: 8,\n font,\n color: rgb(0.5, 0, 0),\n })\n pagesRedacted += 1\n }\n\n // Metadata strip (sanitizePdfMetadata, ported): blank the Info fields + drop XMP.\n const metadataFields = ['Title', 'Author', 'Subject', 'Keywords', 'Creator', 'Producer']\n for (const field of metadataFields) {\n try {\n const infoDict = doc.context.lookup(doc.context.trailerInfo.Info) as\n | { get?: (n: unknown) => unknown; set?: (n: unknown, v: unknown) => void }\n | undefined\n if (infoDict && typeof infoDict.get === 'function' && typeof infoDict.set === 'function') {\n if (infoDict.get(PDFName.of(field))) infoDict.set(PDFName.of(field), PDFString.of(''))\n }\n } catch {\n // Field doesn't exist or can't be modified — skip.\n }\n }\n try {\n const catalog = doc.context.lookup(doc.context.trailerInfo.Root) as\n | { get?: (n: unknown) => unknown; delete?: (n: unknown) => void }\n | undefined\n if (catalog && typeof catalog.get === 'function' && typeof catalog.delete === 'function') {\n if (catalog.get(PDFName.of('Metadata'))) catalog.delete(PDFName.of('Metadata'))\n }\n } catch {\n // No metadata stream — skip.\n }\n\n if (pagesRedacted === 0) {\n fail(verb, 'no page text matched the redaction pattern(s) — nothing was redacted')\n }\n const bytes = new Uint8Array(await doc.save())\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\n// ── doc-aware step dispatch ──────────────────────────────────────────────────\n\n/**\n * `redact` — format dispatch: text media → text path; DOCX/PPTX/ODF → in-place container\n * edit; PDF → visual redaction (draw-over + metadata strip — see {@link PDF_REDACTION_WARNING}).\n */\nexport const docRedactStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) return textRedactStep(ctx)\n const raw = ctx.step.args.match\n const patterns = (Array.isArray(raw) ? raw : [raw]) as MediaArgScalar[]\n const replacement = argOf<string>(ctx.step, 'replace') ?? '█'\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n return mutateOoxmlText(ctx, 'redact', (xml, kind) => {\n let out = xml\n for (const p of patterns) {\n out = replaceInOoxml(\n out,\n kind === 'docx' ? 'w:p' : 'a:p',\n kind === 'docx' ? 'w:t' : 'a:t',\n toGlobalRegex(p),\n replacement\n ).xml\n }\n return out\n })\n }\n if (ODF_MIMES.has(mime)) {\n return mutateOdfText(ctx, 'redact', (xml) => {\n let out = xml\n for (const p of patterns) {\n out = replaceTextInContentXml(out, toGlobalRegex(p), replacement).xml\n }\n return out\n })\n }\n if (mime === MIME.PDF) {\n return redactPdf(ctx, 'redact', patterns.map(toGlobalRegex))\n }\n fail(\n 'redact',\n `redaction for ${mime} is not supported in this build (text, DOCX, PPTX, ODT/ODS/ODP, and PDF are).`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst BLOCKED_CONTROL = (code: number): boolean =>\n (code >= 0 && code <= 8) ||\n code === 11 ||\n code === 12 ||\n (code >= 14 && code <= 31) ||\n code === 127\n\nconst stripControlChars = (text: string): string => {\n let out = ''\n for (const ch of text) {\n if (BLOCKED_CONTROL(ch.charCodeAt(0))) continue\n out += ch\n }\n return out\n}\n\nconst sanitizeTextNodes = (xml: string, textTag: 'w:t' | 'a:t'): string =>\n xml.replace(\n new RegExp(`<${textTag}(?:\\\\s[^>]*)?>([^<]*)</${textTag}>`, 'g'),\n (full, content: string) => {\n const cleaned = stripControlChars(unescapeXml(content))\n if (cleaned === unescapeXml(content)) return full\n return full.replace(content, escapeXml(cleaned))\n }\n )\n\n/** `sanitize` — strip blocked control characters from text nodes / text media. */\nexport const docSanitizeStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) {\n const text = new TextDecoder().decode(ctx.payload.bytes)\n const cleaned = stripControlChars(text)\n return { kind: 'media', payload: { ...ctx.payload, bytes: new TextEncoder().encode(cleaned) } }\n }\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n return mutateOoxmlText(ctx, 'sanitize', (xml, kind) =>\n sanitizeTextNodes(xml, kind === 'docx' ? 'w:t' : 'a:t')\n )\n }\n fail('sanitize', `sanitize for ${mime} is not supported in this build (text, DOCX, PPTX are)`)\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst normalizeText = (text: string): string =>\n text\n .replace(/\\r\\n/g, '\\n')\n .replace(/\\r/g, '\\n')\n .replace(/[\\t ]+$/gm, '')\n\n/** `normalize` — CRLF→LF + trailing-whitespace removal in text nodes / text media. */\nexport const docNormalizeStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) {\n const text = new TextDecoder().decode(ctx.payload.bytes)\n return {\n kind: 'media',\n payload: { ...ctx.payload, bytes: new TextEncoder().encode(normalizeText(text)) },\n }\n }\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n return mutateOoxmlText(ctx, 'normalize', (xml, kind) => {\n const tag = kind === 'docx' ? 'w:t' : 'a:t'\n return xml.replace(\n new RegExp(`<${tag}(?:\\\\s[^>]*)?>([^<]*)</${tag}>`, 'g'),\n (full, content: string) => {\n const normalized = normalizeText(unescapeXml(content))\n if (normalized === unescapeXml(content)) return full\n return full.replace(content, escapeXml(normalized))\n }\n )\n })\n }\n fail('normalize', `normalize for ${mime} is not supported in this build (text, DOCX, PPTX are)`)\n /* unreachable */ throw new Error('unreachable')\n}\n\n/** `update_text` — anchor replacement; DOCX/PPTX/ODF in-place, TARGET_NOT_FOUND when absent. */\nexport const docUpdateTextStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime.startsWith('text/')) return textUpdateTextStep(ctx)\n const anchor = argOf<string>(ctx.step, 'anchor') as string\n const replace = argOf<string>(ctx.step, 'replace') ?? ''\n const escapedAnchor = anchor.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n if (mime === MIME.DOCX || mime === MIME.PPTX) {\n let found = 0\n const result = await mutateOoxmlText(ctx, 'update_text', (xml, kind) => {\n if (found > 0) return xml\n const { xml: next, matchCount } = replaceInOoxml(\n xml,\n kind === 'docx' ? 'w:p' : 'a:p',\n kind === 'docx' ? 'w:t' : 'a:t',\n new RegExp(escapedAnchor),\n replace\n )\n found += matchCount\n return next\n })\n if (found === 0) {\n fail('update_text', `anchor text not found: \"${anchor.slice(0, 80)}\"`)\n }\n return result\n }\n if (ODF_MIMES.has(mime)) {\n let found = 0\n const result = await mutateOdfText(ctx, 'update_text', (xml) => {\n const { xml: next, matchCount } = replaceTextInContentXml(\n xml,\n new RegExp(escapedAnchor),\n replace\n )\n found += matchCount\n return next\n })\n if (found === 0) {\n fail('update_text', `anchor text not found: \"${anchor.slice(0, 80)}\"`)\n }\n return result\n }\n fail(\n 'update_text',\n `text update for ${mime} is not supported (text, DOCX, PPTX, ODT/ODS/ODP are; PDF text is not reliably editable)`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\n// ── extract.assets ───────────────────────────────────────────────────────────\n\nconst ASSET_PATTERNS: Record<string, RegExp> = {\n image: /\\.(png|jpe?g|gif|bmp|tiff?|emf|wmf|svg|webp)$/i,\n font: /\\.(ttf|otf|woff2?|odttf)$/i,\n attachment: /\\.(bin|ole|docx?|xlsx?|pptx?|pdf|txt|csv)$/i,\n}\n\nconst EXT_MIME: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n bmp: 'image/bmp',\n tif: 'image/tiff',\n tiff: 'image/tiff',\n svg: 'image/svg+xml',\n webp: 'image/webp',\n emf: 'image/emf',\n wmf: 'image/wmf',\n ttf: 'font/ttf',\n otf: 'font/otf',\n woff: 'font/woff',\n woff2: 'font/woff2',\n}\n\n/**\n * `extract.assets` — enumerate embedded assets. OOXML/ODF archives are walked natively\n * (cross-env); PDF inputs use the pdfImages engine.\n */\nexport const extractAssetsStep: StepImpl = async (ctx) => {\n const verb = 'extract assets'\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const requested = (ctx.step.args.types as string[] | undefined) ?? ['all']\n const wantAll = requested.includes('all')\n const want = (kind: string): boolean => wantAll || requested.includes(kind)\n\n if (mime === MIME.PDF) {\n if (!want('image')) {\n fail(verb, 'PDF asset extraction currently supports images (types=image or all)')\n }\n if (!ctx.engines.hasConvert(mime, 'images')) {\n fail(\n verb,\n 'PDF asset extraction requires an engine that converts application/pdf to \"images\", and none is configured. Do not retry this verb on PDFs in this deployment.'\n )\n }\n const format = argOf<string>(ctx.step, 'format')\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'images',\n options: format ? { format } : undefined,\n signal: ctx.signal,\n })\n if (result.outputs.length === 0) fail(verb, 'no embedded images were found in the PDF')\n const wantedMime = format ? (EXT_MIME[format] ?? `image/${format}`) : undefined\n const payloads: StepPayload[] = []\n for (const [i, img] of result.outputs.entries()) {\n let bytes = img.bytes\n let mimeType = img.mimeType\n // Two-tier encoding: outputs already in the requested format pass through (native\n // collapse); the rest re-encode via an ordinary registry dispatch.\n if (wantedMime && mimeType.toLowerCase() !== wantedMime) {\n const reencoded = await ctx.engines.mutate({\n bytes,\n mimeType,\n format: { to: format! },\n signal: ctx.signal,\n })\n bytes = reencoded.bytes\n mimeType = reencoded.mimeType\n }\n payloads.push({\n bytes,\n mimeType,\n filename: `asset-${i + 1}.${mimeType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'bin'}`,\n })\n }\n return { kind: 'media-list', payloads }\n }\n\n // Archive formats: OOXML + ODF are zip containers.\n const isArchive = [MIME.DOCX, MIME.XLSX, MIME.PPTX, MIME.ODT, MIME.ODS, MIME.ODP].includes(\n mime as never\n )\n if (!isArchive) {\n fail(verb, `asset extraction for ${mime} is not supported (OOXML/ODF archives and PDF are)`)\n }\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const payloads: StepPayload[] = []\n for (const [name, entry] of Object.entries(zip.files)) {\n if (entry.dir) continue\n const basename = name.split('/').pop() ?? name\n const matchKind = Object.entries(ASSET_PATTERNS).find(([, re]) => re.test(basename))?.[0]\n if (!matchKind || !want(matchKind)) continue\n // Only media/embeddings/fonts directories carry real assets in these containers.\n if (!/(^|\\/)(media|embeddings|fonts|Pictures|ObjectReplacements)\\//i.test(name)) continue\n const ext = basename.split('.').pop()?.toLowerCase() ?? 'bin'\n payloads.push({\n bytes: await entry.async('uint8array'),\n mimeType: EXT_MIME[ext] ?? 'application/octet-stream',\n filename: basename,\n })\n }\n if (payloads.length === 0) fail(verb, 'no embedded assets matched the requested types')\n return { kind: 'media-list', payloads }\n}\n\n// ── convert ──────────────────────────────────────────────────────────────────\n\n/** `convert` — dispatch through the engine registry (direct edge or computed path). */\nexport const convertStep: StepImpl = async (ctx) => {\n const verb = 'convert'\n const to = argOf<string>(ctx.step, 'to') as string\n const supported = ctx.engines.convertTargets(ctx.payload.mimeType)\n if (!supported.includes(to)) {\n fail(\n verb,\n `no configured engine (or computed path) can produce \"${to}\" from ${ctx.payload.mimeType}; reachable targets: ${supported.join(', ') || '(none)'}`\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to,\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'the conversion produced no output')\n const dot = ctx.payload.filename.lastIndexOf('.')\n const base = dot > 0 ? ctx.payload.filename.slice(0, dot) : ctx.payload.filename\n return {\n kind: 'media',\n payload: { bytes: output!.bytes, mimeType: output!.mimeType, filename: `${base}.${to}` },\n }\n}\n\n/** The doc step registry fragment (overrides the Phase 0 text-only redact/update_text). */\nexport const DOC_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['redact', docRedactStep],\n ['sanitize', docSanitizeStep],\n ['normalize', docNormalizeStep],\n ['update_text', docUpdateTextStep],\n ['extract.assets', extractAssetsStep],\n ['convert', convertStep],\n]\n","/**\n * `append` and `data.*` step implementations: deterministic text/data mutations on in-memory\n * bytes — append a line, set/merge/delete at a JSON or YAML path.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Pure and cross-env: text ops\n * are string concatenation; structured ops parse (JSON natively, YAML via the `js-yaml`\n * dependency), mutate the value tree, and re-serialize **preserving the source format** —\n * `data.set` on a YAML file yields YAML, on a JSON file yields JSON. These are the verbs\n * that make the lossy text family first-class media: `empty:json | data set path=… value=…`\n * is a create-then-populate chain with no engine requirement at all.\n */\n\nimport { MIME } from '../formats'\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport type { StepImpl, StepPayload } from '../runtime'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder()\n\n/** MIME types the text-shaped verbs operate on. */\nconst TEXTUAL = (mime: string): boolean =>\n mime.startsWith('text/') || mime === MIME.JSON || mime === MIME.YAML\n\n/** `append` — append text to text-family media. */\nexport const appendStep: StepImpl = async (ctx) => {\n const verb = 'append'\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (!TEXTUAL(mime)) {\n fail(\n verb,\n `append expects text-family media (txt/md/csv/yaml/json-lines); the media is ${mime}`\n )\n }\n const text = argOf<string>(ctx.step, 'text') as string\n const newline = argOf<boolean>(ctx.step, 'newline') ?? true\n const current = decoder.decode(ctx.payload.bytes)\n const needsBreak = newline && current.length > 0 && !current.endsWith('\\n')\n const next = current + (needsBreak ? '\\n' : '') + text + (newline ? '\\n' : '')\n return { kind: 'media', payload: { ...ctx.payload, bytes: encoder.encode(next) } }\n}\n\n// ── structured (JSON/YAML) path ops ──────────────────────────────────────────\n\ntype Doc = { value: unknown; format: 'json' | 'yaml' }\n\nconst parseDoc = async (verb: string, payload: StepPayload): Promise<Doc> => {\n const mime = payload.mimeType.toLowerCase().split(';')[0].trim()\n const text = decoder.decode(payload.bytes)\n if (mime === MIME.JSON) {\n try {\n return { value: text.trim() === '' ? null : (JSON.parse(text) as unknown), format: 'json' }\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `the media is not valid JSON: ${detail}`)\n }\n }\n if (mime === MIME.YAML) {\n try {\n const { load } = await import('js-yaml')\n return { value: load(text) ?? null, format: 'yaml' }\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `the media is not valid YAML: ${detail}`)\n }\n }\n fail(verb, `data operations expect JSON or YAML media; the media is ${mime}`)\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst serializeDoc = async (doc: Doc, payload: StepPayload): Promise<StepPayload> => {\n if (doc.format === 'yaml') {\n const { dump } = await import('js-yaml')\n return { ...payload, bytes: encoder.encode(dump(doc.value)) }\n }\n return { ...payload, bytes: encoder.encode(JSON.stringify(doc.value, null, 2)) }\n}\n\n/** Parse a dot/bracket path (`a.b[2].c`) into segments. */\nconst parsePath = (verb: string, raw: string): Array<string | number> => {\n if (typeof raw !== 'string' || raw.trim() === '') fail(verb, 'path must be a non-empty string')\n const segments: Array<string | number> = []\n const re = /([^.[\\]]+)|\\[(\\d+)\\]/g\n let match: RegExpExecArray | null\n while ((match = re.exec(raw))) {\n if (match[2] !== undefined) segments.push(Number(match[2]))\n else segments.push(match[1])\n }\n if (segments.length === 0) fail(verb, `could not parse path \"${raw}\"`)\n return segments\n}\n\n/** Walk to the parent of the path target, creating containers when `create` is set. */\nconst walkToParent = (\n verb: string,\n root: unknown,\n segments: Array<string | number>,\n create: boolean\n): { parent: Record<string, unknown> | unknown[]; key: string | number } => {\n let node: unknown = root\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i]\n const isIndex = typeof seg === 'number'\n if (node === null || typeof node !== 'object') {\n fail(verb, `path segment \"${String(seg)}\" walks through a non-container value`)\n }\n const container = node as Record<string, unknown> & unknown[]\n let next: unknown = isIndex ? container[seg] : container[seg as string]\n if (next === undefined || next === null) {\n if (!create) {\n fail(verb, `path segment \"${String(seg)}\" does not exist`)\n }\n next = typeof segments[i + 1] === 'number' ? [] : {}\n if (isIndex) container[seg] = next\n else container[seg as string] = next\n }\n node = next\n }\n if (node === null || typeof node !== 'object') {\n fail(verb, 'the path target parent is not an object or array')\n }\n return { parent: node as Record<string, unknown> | unknown[], key: segments[segments.length - 1] }\n}\n\n/** `data.set` — set a value at a JSON/YAML path, creating intermediate containers. */\nexport const dataSetStep: StepImpl = async (ctx) => {\n const verb = 'data set'\n const path = argOf<string>(ctx.step, 'path') as string\n const rawValue = argOf<string>(ctx.step, 'value')\n if (rawValue === undefined) fail(verb, 'value is required (JSON-encoded scalar or structure)')\n let value: unknown\n try {\n value = JSON.parse(String(rawValue))\n } catch {\n // A bare unquoted string is a convenience the model will reach for; accept it.\n value = String(rawValue)\n }\n const doc = await parseDoc(verb, ctx.payload)\n const segments = parsePath(verb, path)\n if (doc.value === null || typeof doc.value !== 'object') {\n doc.value = typeof segments[0] === 'number' ? [] : {}\n }\n const { parent, key } = walkToParent(verb, doc.value, segments, true)\n if (Array.isArray(parent)) parent[Number(key)] = value\n else parent[String(key)] = value\n return { kind: 'media', payload: await serializeDoc(doc, ctx.payload) }\n}\n\n/** Deep merge `fragment` into `target` (objects merge recursively; everything else replaces). */\nconst deepMerge = (target: unknown, fragment: unknown): unknown => {\n if (\n target === null ||\n fragment === null ||\n typeof target !== 'object' ||\n typeof fragment !== 'object' ||\n Array.isArray(target) !== Array.isArray(fragment) ||\n Array.isArray(fragment)\n ) {\n return fragment\n }\n const out: Record<string, unknown> = { ...(target as Record<string, unknown>) }\n for (const [k, v] of Object.entries(fragment as Record<string, unknown>)) {\n out[k] = k in out ? deepMerge(out[k], v) : v\n }\n return out\n}\n\n/** `data.merge` — merge a JSON fragment into the document (deep by default). */\nexport const dataMergeStep: StepImpl = async (ctx) => {\n const verb = 'data merge'\n const rawFragment = argOf<string>(ctx.step, 'fragment') as string\n const strategy = argOf<string>(ctx.step, 'strategy') ?? 'deep'\n let fragment: unknown\n try {\n fragment = JSON.parse(String(rawFragment))\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `fragment must be valid JSON: ${detail}`)\n }\n if (fragment === null || typeof fragment !== 'object' || Array.isArray(fragment)) {\n fail(verb, 'fragment must be a JSON object')\n }\n const doc = await parseDoc(verb, ctx.payload)\n if (doc.value === null || typeof doc.value !== 'object' || Array.isArray(doc.value)) {\n fail(verb, 'merge requires the document root to be an object')\n }\n doc.value =\n strategy === 'shallow'\n ? { ...(doc.value as Record<string, unknown>), ...(fragment as Record<string, unknown>) }\n : deepMerge(doc.value, fragment)\n return { kind: 'media', payload: await serializeDoc(doc, ctx.payload) }\n}\n\n/** `data.delete` — remove a key/index at a JSON/YAML path. */\nexport const dataDeleteStep: StepImpl = async (ctx) => {\n const verb = 'data delete'\n const path = argOf<string>(ctx.step, 'path') as string\n const doc = await parseDoc(verb, ctx.payload)\n const segments = parsePath(verb, path)\n if (doc.value === null || typeof doc.value !== 'object') {\n fail(verb, 'the document has no structure to delete from')\n }\n const { parent, key } = walkToParent(verb, doc.value, segments, false)\n if (Array.isArray(parent)) {\n const idx = Number(key)\n if (idx < 0 || idx >= parent.length) fail(verb, `index ${idx} is out of range`)\n parent.splice(idx, 1)\n } else {\n if (!(String(key) in parent)) fail(verb, `key \"${String(key)}\" does not exist at that path`)\n delete parent[String(key)]\n }\n return { kind: 'media', payload: await serializeDoc(doc, ctx.payload) }\n}\n\n/** The data step registry fragment, keyed by canonical verb id. */\nexport const DATA_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['append', appendStep],\n ['data.set', dataSetStep],\n ['data.merge', dataMergeStep],\n ['data.delete', dataDeleteStep],\n]\n","/**\n * `sheet.*` step implementations: thin dispatchers into the engine registry's edit\n * capability.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The actual workbook surgery\n * lives in edit-capable engines (`engines/exceljs` preserves styling; `engines/sheetjs`\n * covers the wider read matrix but strips styling — SheetJS CE limitation). Each step here:\n * normalizes non-xlsx spreadsheet inputs to xlsx when the selected edit coverage requires it\n * (any spreadsheet-family MIME with a declared `hasConvert(mime, 'xlsx')` edge qualifies —\n * ODS/XLS via soffice or sheetjs, XLSB/FODS/SYLK/DIF/DBF/NUMBERS via sheetjs), dispatches the\n * op through `ctx.engines.edit`, and degrades to a model-actionable failure when no edit\n * engine is configured.\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, SPREADSHEET_MIMES, replaceExtension, unsupportedForMutationReason } from '../formats'\nimport type { StepImpl, StepContext, StepPayload } from '../runtime'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n/** Acquire bytes the edit dispatch can work on, normalizing to xlsx when necessary. */\nconst acquireEditable = async (\n ctx: StepContext,\n verb: string\n): Promise<{ bytes: Uint8Array; mimeType: string }> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n // An engine that edits this MIME directly (sheetjs edits its whole read matrix) wins.\n if (ctx.engines.hasEdit?.(mime)) return { bytes: ctx.payload.bytes, mimeType: mime }\n // Otherwise: any spreadsheet-family input with a declared path to xlsx normalizes first.\n if (SPREADSHEET_MIMES.has(mime) && mime !== MIME.XLSX) {\n if (!ctx.engines.hasConvert(mime, 'xlsx')) {\n const reason = unsupportedForMutationReason(mime)\n fail(\n verb,\n reason ??\n `this input is ${mime} — an engine that converts it to xlsx is required first, and none is configured. Do not retry this verb on this media in this deployment.`\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'xlsx',\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'normalizing the workbook to xlsx produced no output')\n return { bytes: output!.bytes, mimeType: MIME.XLSX }\n }\n if (mime !== MIME.XLSX) {\n const mutationBlock = unsupportedForMutationReason(mime)\n if (mutationBlock) fail(verb, mutationBlock)\n fail(verb, `sheet operations expect a spreadsheet; the media is ${mime}`)\n }\n return { bytes: ctx.payload.bytes, mimeType: MIME.XLSX }\n}\n\n/** Dispatch one `sheet.*` op through the registry's edit capability. */\nconst dispatchEdit = async (\n ctx: StepContext,\n verb: string,\n op: string\n): Promise<{ kind: 'media'; payload: StepPayload }> => {\n const { bytes, mimeType } = await acquireEditable(ctx, verb)\n if (!ctx.engines.hasEdit?.(mimeType, op)) {\n fail(\n verb,\n `no engine that edits spreadsheets is configured — add engines/exceljs (or engines/sheetjs) to the pipeline's engines array. Do not retry this verb in this deployment.`\n )\n }\n try {\n const result = await ctx.engines.edit({\n bytes,\n mimeType,\n op,\n args: ctx.step.args as Record<string, unknown>,\n signal: ctx.signal,\n })\n return {\n kind: 'media',\n payload: {\n bytes: result.bytes,\n mimeType: result.mimeType,\n filename: replaceExtension(ctx.payload.filename, 'xlsx'),\n },\n }\n } catch (err) {\n if (isError(err) && err.name.startsWith('E_MEDIA_')) throw err\n const detail = isError(err) ? err.message : String(err)\n fail(verb, detail)\n /* unreachable */ throw err\n }\n}\n\n/** Pre-dispatch arg validation: keep the historical readable failures for malformed args. */\nconst requireJsonArray = (verb: string, value: unknown, message: string): void => {\n if (!Array.isArray(value) || value.length === 0) fail(verb, message)\n}\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `sheet.add_rows` — insert rows before/after an index, or append. */\nexport const sheetAddRowsStep: StepImpl = async (ctx) => {\n const verb = 'sheet add_rows'\n const rows = ctx.step.args.rows\n if (!Array.isArray(rows) || rows.length === 0 || !rows.every(Array.isArray)) {\n fail(verb, `rows must be a non-empty JSON array of arrays, e.g. rows='[[\"a\",1]]'`)\n }\n return dispatchEdit(ctx, verb, 'sheet.add_rows')\n}\n\n/** `sheet.add_columns` — insert columns with headers or full descriptors. */\nexport const sheetAddColumnsStep: StepImpl = async (ctx) => {\n const verb = 'sheet add_columns'\n const headers = ctx.step.args.headers as string[] | undefined\n const columns = ctx.step.args.columns ?? headers\n requireJsonArray(verb, columns, `provide headers=a,b or columns='[{\"header\":\"X\",\"values\":[1]}]'`)\n return dispatchEdit(ctx, verb, 'sheet.add_columns')\n}\n\n/** `sheet.update_cells` — set cells by A1 address or row/col. Leading `=` writes a formula. */\nexport const sheetUpdateCellsStep: StepImpl = async (ctx) => {\n const verb = 'sheet update_cells'\n requireJsonArray(\n verb,\n ctx.step.args.updates,\n `updates must be a non-empty JSON array, e.g. updates='[{\"address\":\"B2\",\"value\":3}]'`\n )\n return dispatchEdit(ctx, verb, 'sheet.update_cells')\n}\n\n/** `sheet.delete_rows` — delete 1-based rows (bottom-up so indices stay valid). */\nexport const sheetDeleteRowsStep: StepImpl = async (ctx) =>\n dispatchEdit(ctx, 'sheet delete_rows', 'sheet.delete_rows')\n\n/** `sheet.delete_columns` — delete 1-based columns. */\nexport const sheetDeleteColumnsStep: StepImpl = async (ctx) =>\n dispatchEdit(ctx, 'sheet delete_columns', 'sheet.delete_columns')\n\n/** `sheet.rename_sheet` — rename by NAME (the server contract; index targeting is rejected). */\nexport const sheetRenameSheetStep: StepImpl = async (ctx) =>\n dispatchEdit(ctx, 'sheet rename_sheet', 'sheet.rename_sheet')\n\n/** `sheet.add_sheet` — add a worksheet, optionally at a 1-based position. */\nexport const sheetAddSheetStep: StepImpl = async (ctx) =>\n dispatchEdit(ctx, 'sheet add_sheet', 'sheet.add_sheet')\n\n/** `sheet.remove_sheet` — remove by NAME (the server contract). */\nexport const sheetRemoveSheetStep: StepImpl = async (ctx) =>\n dispatchEdit(ctx, 'sheet remove_sheet', 'sheet.remove_sheet')\n\n/** `sheet.reorder_sheets` — every sheet exactly once, by name or 1-based index. */\nexport const sheetReorderSheetsStep: StepImpl = async (ctx) => {\n const verb = 'sheet reorder_sheets'\n requireJsonArray(\n verb,\n ctx.step.args.order,\n `order must be a JSON array of names/indices, e.g. order='[\"Summary\",2]'`\n )\n return dispatchEdit(ctx, verb, 'sheet.reorder_sheets')\n}\n\n/** `sheet.transform_table` — rename/select/drop columns by header name. */\nexport const sheetTransformTableStep: StepImpl = async (ctx) => {\n const verb = 'sheet transform_table'\n // header_row defaults inside the engine; validate it is a number when present.\n const headerRow = argOf<number>(ctx.step, 'header_row')\n if (headerRow !== undefined && (!Number.isFinite(headerRow) || headerRow < 1)) {\n fail(verb, 'header_row must be a 1-based row number')\n }\n return dispatchEdit(ctx, verb, 'sheet.transform_table')\n}\n\n/** The sheet step registry fragment, keyed by canonical verb id. */\nexport const SHEET_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['sheet.add_rows', sheetAddRowsStep],\n ['sheet.add_columns', sheetAddColumnsStep],\n ['sheet.update_cells', sheetUpdateCellsStep],\n ['sheet.delete_rows', sheetDeleteRowsStep],\n ['sheet.delete_columns', sheetDeleteColumnsStep],\n ['sheet.rename_sheet', sheetRenameSheetStep],\n ['sheet.add_sheet', sheetAddSheetStep],\n ['sheet.remove_sheet', sheetRemoveSheetStep],\n ['sheet.reorder_sheets', sheetReorderSheetsStep],\n ['sheet.transform_table', sheetTransformTableStep],\n]\n","/**\n * `slides.*` step implementations: native PPTX container mutation via JSZip + targeted XML\n * edits, on in-memory bytes.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * slides adapters (regex-over-zip XML surgery — no XML parser dependency). PPTX is mutated\n * natively; ODP inputs are normalized to PPTX through the configured `convert` engine first,\n * degrading to a readable failure when none is configured. All implementations are\n * cross-environment (jszip operates on Uint8Array).\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, replaceExtension, unsupportedForMutationReason } from '../formats'\nimport type { default as JSZipNS } from 'jszip'\nimport type { MediaRef, MediaArgJson } from '../plan'\nimport type { StepImpl, StepContext, StepPayload } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst SLIDE_REL_TYPE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n// ── XML helpers (ported verbatim semantics) ──────────────────────────────────\n\nconst escapeXml = (value: string): string =>\n value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\n/** Pure posix-style path resolution for zip entries (no node:path). */\nconst resolveZipPath = (basePart: string, relTarget: string): string => {\n const baseDir = basePart.split('/').slice(0, -1)\n const parts = [...baseDir, ...relTarget.split('/')]\n const out: string[] = []\n for (const part of parts) {\n if (part === '' || part === '.') continue\n if (part === '..') out.pop()\n else out.push(part)\n }\n return out.join('/')\n}\n\ninterface SlideEntry {\n rid: string\n slideId: number\n sldIdTag: string\n target: string\n title?: string\n}\n\ninterface ParsedPresentation {\n presentationXml: string\n relsXml: string\n entries: SlideEntry[]\n}\n\nconst readZipText = async (verb: string, zip: JSZipNS, path: string): Promise<string> => {\n const file = zip.file(path)\n if (!file) fail(verb, `the presentation is missing an expected part: ${path}`)\n return file!.async('text')\n}\n\nconst parseRelationshipTarget = (relsXml: string, relId: string): string | null => {\n const re = new RegExp(\n `<Relationship\\\\b[^>]*Id=\"${escapeRegex(relId)}\"[^>]*Target=\"([^\"]+)\"[^>]*>`,\n 'i'\n )\n return relsXml.match(re)?.[1] ?? null\n}\n\nconst parsePresentation = async (verb: string, zip: JSZipNS): Promise<ParsedPresentation> => {\n const presentationXml = await readZipText(verb, zip, 'ppt/presentation.xml')\n const relsXml = await readZipText(verb, zip, 'ppt/_rels/presentation.xml.rels')\n const sldIdListMatch = presentationXml.match(/<p:sldIdLst>([\\s\\S]*?)<\\/p:sldIdLst>/)\n if (!sldIdListMatch) fail(verb, 'the presentation has no slide list (corrupt PPTX?)')\n const sldIdTags = sldIdListMatch![1].match(/<p:sldId\\b[^>]*\\/>/g) ?? []\n const entries: SlideEntry[] = []\n for (const tag of sldIdTags) {\n const rid = tag.match(/r:id=\"([^\"]+)\"/)?.[1]\n const idText = tag.match(/\\bid=\"(\\d+)\"/)?.[1]\n if (!rid || !idText) continue\n const target = parseRelationshipTarget(relsXml, rid)\n if (!target) continue\n const slidePath = resolveZipPath('ppt/presentation.xml', target)\n let title: string | undefined\n const slideFile = zip.file(slidePath)\n if (slideFile) {\n const slideXml = await slideFile.async('text')\n title = slideXml.match(/<p:cSld\\b[^>]*\\bname=\"([^\"]*)\"/)?.[1]\n }\n entries.push({ rid, slideId: Number(idText), sldIdTag: tag, target, title })\n }\n return { presentationXml, relsXml, entries }\n}\n\nconst replaceSlideIdList = (presentationXml: string, tags: string[]): string =>\n presentationXml.replace(\n /<p:sldIdLst>[\\s\\S]*?<\\/p:sldIdLst>/,\n `<p:sldIdLst>${tags.join('')}</p:sldIdLst>`\n )\n\n/** Resolve a slide by the frozen `slide=` rule: digits = 1-based index, otherwise title. */\nconst resolveSlide = (\n verb: string,\n entries: SlideEntry[],\n slideArg: string | number | undefined\n): SlideEntry => {\n if (slideArg === undefined) {\n const first = entries[0]\n if (!first) fail(verb, 'the presentation has no slides')\n return first\n }\n // Frozen 0.11: bare number targets by 1-based index; quoted string targets by title.\n if (typeof slideArg === 'number') {\n const found = entries[slideArg - 1]\n if (!found) {\n fail(verb, `slide index ${slideArg} is out of range (1-based; ${entries.length} slides)`)\n }\n return found!\n }\n const byTitle = entries.find((e) => e.title === slideArg)\n if (!byTitle) fail(verb, `no slide titled \"${slideArg}\"`)\n return byTitle!\n}\n\nconst getMaxRidNumber = (relsXml: string): number => {\n let max = 0\n for (const match of relsXml.matchAll(/\\bId=\"rId(\\d+)\"/g)) max = Math.max(max, Number(match[1]))\n return max\n}\n\nconst getMaxSlideNumber = (zip: JSZipNS): number => {\n let max = 0\n for (const name of Object.keys(zip.files)) {\n const match = name.match(/^ppt\\/slides\\/slide(\\d+)\\.xml$/)\n if (match) max = Math.max(max, Number(match[1]))\n }\n return max\n}\n\nconst getMaxSlideId = (entries: SlideEntry[]): number =>\n entries.reduce((max, e) => Math.max(max, e.slideId), 255)\n\nconst ensureSlideContentType = (contentTypesXml: string, slideNumber: number): string => {\n const partName = `/ppt/slides/slide${slideNumber}.xml`\n if (contentTypesXml.includes(`PartName=\"${partName}\"`)) return contentTypesXml\n const override =\n `<Override PartName=\"${partName}\" ` +\n `ContentType=\"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\"/>`\n return contentTypesXml.replace('</Types>', `${override}</Types>`)\n}\n\nconst setSlideTitle = (slideXml: string, title: string): string => {\n if (/<p:cSld\\b[^>]*\\bname=\"[^\"]*\"/.test(slideXml)) {\n return slideXml.replace(/(<p:cSld\\b[^>]*\\bname=\")[^\"]*(\")/, `$1${escapeXml(title)}$2`)\n }\n return slideXml\n}\n\n// ── lifecycle ────────────────────────────────────────────────────────────────\n\n/** Acquire pptx bytes, converting ODP to PPTX via the engine registry. */\nconst acquirePptx = async (ctx: StepContext, verb: string): Promise<Uint8Array> => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n if (mime === MIME.PPTX) return ctx.payload.bytes\n if (mime === MIME.ODP) {\n if (!ctx.engines.hasConvert(mime, 'pptx')) {\n fail(\n verb,\n 'this input is ODP — an engine that converts it to PPTX is required first, and none is configured. Do not retry this verb on this media in this deployment.'\n )\n }\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: mime,\n filename: ctx.payload.filename,\n to: 'pptx',\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(verb, 'normalizing the presentation to PPTX produced no output')\n return output!.bytes\n }\n const reason = unsupportedForMutationReason(mime)\n if (reason) fail(verb, reason)\n fail(verb, `slides operations expect a presentation; the media is ${mime}`)\n /* unreachable */ throw new Error('unreachable')\n}\n\nconst withPresentation = async (\n ctx: StepContext,\n verb: string,\n mutate: (zip: JSZipNS, parsed: ParsedPresentation) => Promise<void>\n): Promise<{ kind: 'media'; payload: StepPayload }> => {\n const bytes = await acquirePptx(ctx, verb)\n const JSZip = await jszip()\n let zip: JSZipNS\n try {\n zip = await JSZip.loadAsync(bytes)\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(verb, `could not open the presentation: ${detail}`)\n /* unreachable */ throw err\n }\n const parsed = await parsePresentation(verb, zip)\n await mutate(zip, parsed)\n const out = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE' })\n return {\n kind: 'media',\n payload: {\n bytes: out,\n mimeType: MIME.PPTX,\n filename: replaceExtension(ctx.payload.filename, 'pptx'),\n },\n }\n}\n\n// ── step implementations ─────────────────────────────────────────────────────\n\n/** `slides.add` — clone the last slide as a template, optionally retitle/position it. */\nexport const slidesAddStep: StepImpl = async (ctx) => {\n const verb = 'slides add'\n const at = argOf<number>(ctx.step, 'at')\n const title = argOf<string>(ctx.step, 'title')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (parsed.entries.length === 0) fail(verb, 'the presentation has no slides to clone from')\n const template = parsed.entries[parsed.entries.length - 1]\n const templatePath = resolveZipPath('ppt/presentation.xml', template.target)\n const templateXml = await readZipText(verb, zip, templatePath)\n const newSlideNumber = getMaxSlideNumber(zip) + 1\n const newSlidePath = `ppt/slides/slide${newSlideNumber}.xml`\n zip.file(newSlidePath, title ? setSlideTitle(templateXml, title) : templateXml)\n const templateNum = templatePath.match(/slide(\\d+)\\.xml$/)?.[1]\n const templateRels = templateNum\n ? zip.file(`ppt/slides/_rels/slide${templateNum}.xml.rels`)\n : null\n if (templateRels) {\n const relsXml = await templateRels.async('text')\n zip.file(\n `ppt/slides/_rels/slide${newSlideNumber}.xml.rels`,\n relsXml.replace(/<Relationship\\b[^>]*Type=\"[^\"]*notesSlide\"[^>]*\\/>/g, '')\n )\n }\n const newRid = `rId${getMaxRidNumber(parsed.relsXml) + 1}`\n const newSldTag = `<p:sldId id=\"${getMaxSlideId(parsed.entries) + 1}\" r:id=\"${newRid}\"/>`\n const relNode = `<Relationship Id=\"${newRid}\" Type=\"${SLIDE_REL_TYPE}\" Target=\"slides/slide${newSlideNumber}.xml\"/>`\n zip.file(\n 'ppt/_rels/presentation.xml.rels',\n parsed.relsXml.replace('</Relationships>', `${relNode}</Relationships>`)\n )\n const insertAt =\n at !== undefined\n ? Math.min(Math.max(1, at), parsed.entries.length + 1)\n : parsed.entries.length + 1\n const tags = parsed.entries.map((e) => e.sldIdTag)\n tags.splice(insertAt - 1, 0, newSldTag)\n zip.file('ppt/presentation.xml', replaceSlideIdList(parsed.presentationXml, tags))\n const contentTypes = await readZipText(verb, zip, '[Content_Types].xml')\n zip.file('[Content_Types].xml', ensureSlideContentType(contentTypes, newSlideNumber))\n })\n}\n\n/** `slides.update_text` — replace text in the first node or a named placeholder shape. */\nexport const slidesUpdateTextStep: StepImpl = async (ctx) => {\n const verb = 'slides update_text'\n const text = argOf<string>(ctx.step, 'text') as string\n const placeholder = argOf<string>(ctx.step, 'placeholder')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideXml = await readZipText(verb, zip, slidePath)\n let updated = slideXml\n let changed = false\n if (placeholder) {\n let placeholderFound = false\n updated = slideXml.replace(/<p:sp\\b[\\s\\S]*?<\\/p:sp>/g, (shapeXml) => {\n if (\n !new RegExp(`<p:cNvPr\\\\b[^>]*\\\\bname=\"${escapeRegex(placeholder)}\"[^>]*>`, 'i').test(\n shapeXml\n )\n ) {\n return shapeXml\n }\n placeholderFound = true\n return shapeXml.replace(/<a:t>[\\s\\S]*?<\\/a:t>/, () => {\n changed = true\n return `<a:t>${escapeXml(text)}</a:t>`\n })\n })\n if (!placeholderFound)\n fail(verb, `no placeholder named \"${placeholder}\" on the selected slide`)\n } else {\n updated = slideXml.replace(/<a:t>[\\s\\S]*?<\\/a:t>/, () => {\n changed = true\n return `<a:t>${escapeXml(text)}</a:t>`\n })\n }\n if (!changed) fail(verb, 'no text node found on the selected slide')\n zip.file(slidePath, updated)\n })\n}\n\n/** `slides.update_table` — set table cell text by 1-based row/col. */\nexport const slidesUpdateTableStep: StepImpl = async (ctx) => {\n const verb = 'slides update_table'\n const updates = ctx.step.args.updates as MediaArgJson\n if (!Array.isArray(updates) || updates.length === 0) {\n fail(verb, `updates must be a JSON array: updates='[{\"row\":1,\"col\":2,\"value\":\"x\"}]'`)\n }\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n let slideXml = await readZipText(verb, zip, slidePath)\n const tableMatch = slideXml.match(/<a:tbl>[\\s\\S]*?<\\/a:tbl>/)\n if (!tableMatch) fail(verb, 'no table found on the selected slide')\n let tableXml = tableMatch![0]\n const rowMatches = tableXml.match(/<a:tr\\b[\\s\\S]*?<\\/a:tr>/g) ?? []\n for (const raw of updates as Array<Record<string, unknown>>) {\n const row = Number(raw.row)\n const col = Number(raw.col)\n const value = String(raw.value ?? '')\n const rowIndex = row - 1\n const colIndex = col - 1\n if (rowIndex < 0 || colIndex < 0 || rowIndex >= rowMatches.length) {\n fail(verb, `table cell out of range: r${row}c${col} (1-based)`)\n }\n const rowXml = rowMatches[rowIndex]\n const cellMatches = rowXml.match(/<a:tc\\b[\\s\\S]*?<\\/a:tc>/g) ?? []\n if (colIndex >= cellMatches.length)\n fail(verb, `table cell out of range: r${row}c${col} (1-based)`)\n const cellXml = cellMatches[colIndex]\n if (!/<a:t>/.test(cellXml)) fail(verb, `cell r${row}c${col} has no text node`)\n cellMatches[colIndex] = cellXml.replace(\n /<a:t>[\\s\\S]*?<\\/a:t>/,\n `<a:t>${escapeXml(value)}</a:t>`\n )\n rowMatches[rowIndex] = rowXml.replace(/<a:tc\\b[\\s\\S]*?<\\/a:tc>/g, () => cellMatches.shift()!)\n }\n tableXml = tableXml.replace(/<a:tr\\b[\\s\\S]*?<\\/a:tr>/g, () => rowMatches.shift()!)\n slideXml = slideXml.replace(/<a:tbl>[\\s\\S]*?<\\/a:tbl>/, tableXml)\n zip.file(slidePath, slideXml)\n })\n}\n\n/** `slides.update_image` — replace an image part's bytes with another media (`with=@id`). */\nexport const slidesUpdateImageStep: StepImpl = async (ctx) => {\n const verb = 'slides update_image'\n const ref = ctx.step.args.with as MediaRef\n const placeholder = argOf<string>(ctx.step, 'placeholder')\n if (ref.kind !== 'id') fail(verb, 'builder refs are not supported here; use an @id ref')\n const replacement = await ctx.resolveRef((ref as { kind: 'id'; id: string }).id)\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideXml = await readZipText(verb, zip, slidePath)\n const slideNum = slidePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (!slideNum) fail(verb, 'unable to resolve the slide number (corrupt PPTX?)')\n const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`\n const relsXml = await readZipText(verb, zip, relsPath)\n let imagePartPath: string | null = null\n if (placeholder) {\n for (const picXml of slideXml.match(/<p:pic\\b[\\s\\S]*?<\\/p:pic>/g) ?? []) {\n if (\n !new RegExp(`<p:cNvPr\\\\b[^>]*\\\\bname=\"${escapeRegex(placeholder)}\"[^>]*>`, 'i').test(\n picXml\n )\n ) {\n continue\n }\n const rid = picXml.match(/<a:blip\\b[^>]*\\br:embed=\"([^\"]+)\"/i)?.[1]\n if (rid) {\n const relTarget = parseRelationshipTarget(relsXml, rid)\n if (relTarget) imagePartPath = resolveZipPath(relsPath, relTarget)\n }\n break\n }\n if (!imagePartPath)\n fail(verb, `no image placeholder named \"${placeholder}\" on the selected slide`)\n } else {\n const fallback = relsXml.match(\n /<Relationship\\b[^>]*Type=\"[^\"]*\\/image\"[^>]*Target=\"([^\"]+)\"[^>]*>/i\n )\n if (fallback) imagePartPath = resolveZipPath(relsPath, fallback[1])\n }\n if (!imagePartPath) fail(verb, 'no image relationship found on the selected slide')\n zip.file(imagePartPath!, replacement.bytes)\n })\n}\n\n/** `slides.update_chart` — overwrite the chart's cached values in document order. */\nexport const slidesUpdateChartStep: StepImpl = async (ctx) => {\n const verb = 'slides update_chart'\n const data = ctx.step.args.data as MediaArgJson\n if (!Array.isArray(data) || data.length === 0) {\n fail(verb, `data must be a non-empty JSON array of arrays: data='[[\"Q1\",10]]'`)\n }\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const target = resolveSlide(verb, parsed.entries, argOf<string | number>(ctx.step, 'slide'))\n const slidePath = resolveZipPath('ppt/presentation.xml', target.target)\n const slideNum = slidePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (!slideNum) fail(verb, 'unable to resolve the slide number (corrupt PPTX?)')\n const relsPath = `ppt/slides/_rels/slide${slideNum}.xml.rels`\n const relsXml = await readZipText(verb, zip, relsPath)\n const chartRel = relsXml.match(\n /<Relationship\\b[^>]*Type=\"[^\"]*\\/chart\"[^>]*Target=\"([^\"]+)\"[^>]*>/i\n )\n if (!chartRel) fail(verb, 'no chart found on the selected slide')\n const chartPath = resolveZipPath(relsPath, chartRel![1])\n let chartXml = await readZipText(verb, zip, chartPath)\n const values = (data as unknown[][]).flat().map((v) => String(v))\n let replaced = 0\n chartXml = chartXml.replace(/<c:v>[\\s\\S]*?<\\/c:v>/g, (full) => {\n if (replaced >= values.length) return full\n const next = `<c:v>${escapeXml(values[replaced])}</c:v>`\n replaced += 1\n return next\n })\n if (replaced === 0) fail(verb, 'the chart has no cached values to update')\n zip.file(chartPath, chartXml)\n })\n}\n\n/** `slides.delete` — remove slides by 1-based index (cannot remove all). */\nexport const slidesDeleteStep: StepImpl = async (ctx) => {\n const verb = 'slides delete'\n const slides = ctx.step.args.slides as number[]\n return withPresentation(ctx, verb, async (zip, parsed) => {\n const unique = [...new Set(slides)]\n for (const index of unique) {\n if (!Number.isInteger(index) || index < 1 || index > parsed.entries.length) {\n fail(\n verb,\n `slide index ${index} is out of range (1-based; ${parsed.entries.length} slides)`\n )\n }\n }\n const toDelete = new Set(unique)\n const kept = parsed.entries.filter((_, idx) => !toDelete.has(idx + 1))\n if (kept.length === 0) fail(verb, 'cannot delete every slide in the presentation')\n zip.file(\n 'ppt/presentation.xml',\n replaceSlideIdList(\n parsed.presentationXml,\n kept.map((e) => e.sldIdTag)\n )\n )\n let relsXml = parsed.relsXml\n parsed.entries.forEach((entry, idx) => {\n if (!toDelete.has(idx + 1)) return\n const targetPath = resolveZipPath('ppt/presentation.xml', entry.target)\n zip.remove(targetPath)\n const slideNum = targetPath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (slideNum) zip.remove(`ppt/slides/_rels/slide${slideNum}.xml.rels`)\n relsXml = relsXml.replace(\n new RegExp(`<Relationship\\\\b[^>]*Id=\"${entry.rid}\"[^>]*/>`, 'g'),\n ''\n )\n })\n zip.file('ppt/_rels/presentation.xml.rels', relsXml)\n })\n}\n\n/** `slides.reorder` — every slide exactly once, by 1-based index. */\nexport const slidesReorderStep: StepImpl = async (ctx) => {\n const verb = 'slides reorder'\n const order = ctx.step.args.order as number[]\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (order.length !== parsed.entries.length) {\n fail(verb, `order must list all ${parsed.entries.length} slides exactly once`)\n }\n const seen = new Set<number>()\n const reordered: SlideEntry[] = []\n for (const index of order) {\n if (!Number.isInteger(index) || index < 1 || index > parsed.entries.length) {\n fail(verb, `slide index ${index} is out of range (1-based)`)\n }\n if (seen.has(index)) fail(verb, `duplicate slide index: ${index}`)\n seen.add(index)\n reordered.push(parsed.entries[index - 1])\n }\n zip.file(\n 'ppt/presentation.xml',\n replaceSlideIdList(\n parsed.presentationXml,\n reordered.map((e) => e.sldIdTag)\n )\n )\n })\n}\n\n/** `slides.duplicate` — copy a slide, optionally inserting at a position. */\nexport const slidesDuplicateStep: StepImpl = async (ctx) => {\n const verb = 'slides duplicate'\n const slide = argOf<number>(ctx.step, 'slide') as number\n const at = argOf<number>(ctx.step, 'at')\n return withPresentation(ctx, verb, async (zip, parsed) => {\n if (!Number.isInteger(slide) || slide < 1 || slide > parsed.entries.length) {\n fail(verb, `slide index ${slide} is out of range (1-based; ${parsed.entries.length} slides)`)\n }\n const source = parsed.entries[slide - 1]\n const sourcePath = resolveZipPath('ppt/presentation.xml', source.target)\n const sourceXml = await readZipText(verb, zip, sourcePath)\n const newSlideNumber = getMaxSlideNumber(zip) + 1\n zip.file(`ppt/slides/slide${newSlideNumber}.xml`, sourceXml)\n const sourceNum = sourcePath.match(/slide(\\d+)\\.xml$/)?.[1]\n if (sourceNum) {\n const sourceRels = zip.file(`ppt/slides/_rels/slide${sourceNum}.xml.rels`)\n if (sourceRels) {\n const relsXml = await sourceRels.async('text')\n zip.file(\n `ppt/slides/_rels/slide${newSlideNumber}.xml.rels`,\n relsXml.replace(/<Relationship\\b[^>]*Type=\"[^\"]*notesSlide\"[^>]*\\/>/g, '')\n )\n }\n }\n const newRid = `rId${getMaxRidNumber(parsed.relsXml) + 1}`\n const newTag = `<p:sldId id=\"${getMaxSlideId(parsed.entries) + 1}\" r:id=\"${newRid}\"/>`\n const relNode = `<Relationship Id=\"${newRid}\" Type=\"${SLIDE_REL_TYPE}\" Target=\"slides/slide${newSlideNumber}.xml\"/>`\n zip.file(\n 'ppt/_rels/presentation.xml.rels',\n parsed.relsXml.replace('</Relationships>', `${relNode}</Relationships>`)\n )\n const targetPos =\n at !== undefined ? Math.min(Math.max(1, at), parsed.entries.length + 1) : slide + 1\n const tags = parsed.entries.map((e) => e.sldIdTag)\n tags.splice(targetPos - 1, 0, newTag)\n zip.file('ppt/presentation.xml', replaceSlideIdList(parsed.presentationXml, tags))\n const contentTypes = await readZipText(verb, zip, '[Content_Types].xml')\n zip.file('[Content_Types].xml', ensureSlideContentType(contentTypes, newSlideNumber))\n })\n}\n\n/** Count slides in pptx bytes — exported for spec assertions. */\nexport const countSlides = async (bytes: Uint8Array): Promise<number> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(bytes)\n const parsed = await parsePresentation('slides', zip)\n return parsed.entries.length\n}\n\n/** The slides step registry fragment, keyed by canonical verb id. */\nexport const SLIDES_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['slides.add', slidesAddStep],\n ['slides.update_text', slidesUpdateTextStep],\n ['slides.update_table', slidesUpdateTableStep],\n ['slides.update_image', slidesUpdateImageStep],\n ['slides.update_chart', slidesUpdateChartStep],\n ['slides.delete', slidesDeleteStep],\n ['slides.reorder', slidesReorderStep],\n ['slides.duplicate', slidesDuplicateStep],\n]\n","/**\n * Ingest-depth step extensions: the unified `extract.text` format dispatch (PDF text layer,\n * DOCX via mammoth, XLSX via ExcelJS, ODT/ODS via ODF XML, PPTX via slide XML, images via the\n * OCR engine) and format-aware `extract.metadata`.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Ported from the source server's\n * four extractors, collapsed into one verb that routes on the resolved media's format family\n * (the single biggest order-out-of-chaos win — the model says `extract text` and doesn't care\n * what the container is). OCR runs through the configured `ocr` engine when the input is an\n * image, or when a PDF has no text layer with `ocr=auto`, or always with `ocr=force`.\n */\n\nimport { argOf } from '../runtime'\nimport { decodeText } from './text'\nimport { isError } from '@nhtio/adk/guards'\nimport { MIME, familyOf } from '../formats'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport type { default as JSZipNS } from 'jszip'\nimport type { default as ExcelJSNS } from 'exceljs'\nimport type { StepImpl, StepContext } from '../runtime'\n\ntype JSZipModule = typeof JSZipNS\n\nlet zipPromise: Promise<JSZipModule> | undefined\nconst jszip = (): Promise<JSZipModule> => {\n zipPromise ??= import('jszip').then((m) => ('default' in m ? m.default : m) as JSZipModule)\n return zipPromise\n}\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\nconst VERB = 'extract text'\n\n// ── per-format extraction ────────────────────────────────────────────────────\n\nconst extractPdfText = async (ctx: StepContext): Promise<string> => {\n const { PDFParse } = await import('pdf-parse')\n try {\n const parser = new PDFParse({ data: ctx.payload.bytes })\n const result = await parser.getText()\n return result.text ?? ''\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n fail(VERB, `could not read the PDF: ${detail}`)\n /* unreachable */ throw err\n }\n}\n\nconst extractDocxText = async (ctx: StepContext): Promise<string> => {\n const mod = await import('mammoth')\n const mammoth = ('extractRawText' in mod ? mod : (mod as { default: unknown }).default) as {\n extractRawText: (input: Record<string, unknown>) => Promise<{ value: string }>\n }\n const bytes = ctx.payload.bytes\n // mammoth's Node entry expects { buffer: Buffer }; its browser entry expects { arrayBuffer }.\n const input =\n typeof globalThis.Buffer !== 'undefined'\n ? { buffer: globalThis.Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength) }\n : {\n arrayBuffer: bytes.buffer.slice(\n bytes.byteOffset,\n bytes.byteOffset + bytes.byteLength\n ) as ArrayBuffer,\n }\n const result = await mammoth.extractRawText(input)\n return result.value\n}\n\nconst extractXlsxText = async (ctx: StepContext): Promise<string> => {\n const mod = await import('exceljs')\n const ExcelJS = ('default' in mod ? mod.default : mod) as typeof ExcelJSNS\n const wb = new ExcelJS.Workbook()\n await wb.xlsx.load(\n ctx.payload.bytes.buffer.slice(\n ctx.payload.bytes.byteOffset,\n ctx.payload.bytes.byteOffset + ctx.payload.bytes.byteLength\n ) as ArrayBuffer\n )\n const lines: string[] = []\n for (const ws of wb.worksheets) {\n lines.push(`# ${ws.name}`)\n ws.eachRow({ includeEmpty: false }, (row) => {\n const cells: string[] = []\n row.eachCell({ includeEmpty: false }, (cell) => {\n cells.push(String(cell.value ?? ''))\n })\n lines.push(cells.join('\\t'))\n })\n }\n return lines.join('\\n')\n}\n\n/** ODF content.xml → visible text (ported transformation order). */\nconst extractOdfXmlText = (xml: string): string =>\n xml\n .replace(/<\\/text:p>/g, '\\n')\n .replace(/<\\/text:h>/g, '\\n')\n .replace(/<\\/table:table-row>/g, '\\n')\n .replace(/<text:tab[^>]*\\/>/g, '\\t')\n .replace(/<text:line-break[^>]*\\/>/g, '\\n')\n .replace(/<[^>]+>/g, '')\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\nconst extractOdfText = async (ctx: StepContext): Promise<string> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const content = zip.file('content.xml')\n if (!content) fail(VERB, 'the ODF archive is missing content.xml (corrupt file?)')\n return extractOdfXmlText(await content!.async('text'))\n}\n\nconst extractPptxText = async (ctx: StepContext): Promise<string> => {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n const slideNames = Object.keys(zip.files)\n .filter((n) => /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n))\n .sort((a, b) => {\n const na = Number(a.match(/slide(\\d+)/)?.[1] ?? 0)\n const nb = Number(b.match(/slide(\\d+)/)?.[1] ?? 0)\n return na - nb\n })\n if (slideNames.length === 0) fail(VERB, 'the presentation has no slides')\n const parts: string[] = []\n for (const name of slideNames) {\n const xml = await zip.file(name)!.async('text')\n const texts = (xml.match(/<a:t>([^<]*)<\\/a:t>/g) ?? []).map((t) =>\n t\n .replace(/<[^>]+>/g, '')\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/>/g, '>')\n .replace(/</g, '<')\n .replace(/&/g, '&')\n )\n parts.push(texts.join('\\n'))\n }\n return parts.join('\\n\\n')\n}\n\nconst runOcr = async (ctx: StepContext): Promise<string> => {\n const out = (argOf<string>(ctx.step, 'ocr_out') ?? 'txt') as 'txt' | 'hocr' | 'json'\n if (!ctx.engines.hasConvert(ctx.payload.mimeType, out)) {\n fail(\n VERB,\n `this input requires OCR, and no engine that converts ${ctx.payload.mimeType} to \"${out}\" is configured. Do not retry this verb on this media in this deployment.`\n )\n }\n const langArg = ctx.step.args.lang as string[] | string | undefined\n const languages = langArg === undefined ? undefined : Array.isArray(langArg) ? langArg : [langArg]\n const result = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to: out,\n options: { languages },\n signal: ctx.signal,\n })\n const output = result.outputs[0]\n if (!output) fail(VERB, 'OCR produced no output')\n return new TextDecoder().decode(output!.bytes)\n}\n\n// ── the unified step ─────────────────────────────────────────────────────────\n\n/**\n * `extract.text` — full format dispatch. Routes by MIME, with OCR engine fallback for images\n * and force-OCR for any input via `ocr=force`.\n */\nexport const extractTextDeepStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const ocrMode = argOf<string>(ctx.step, 'ocr') ?? 'auto'\n\n const asData = (text: string): { kind: 'data'; data: string; asText: string } => ({\n kind: 'data',\n data: text,\n asText: text,\n })\n\n if (mime.startsWith('image/')) return asData(await runOcr(ctx))\n\n if (ocrMode === 'force') return asData(await runOcr(ctx))\n\n if (mime === MIME.PDF) {\n const text = await extractPdfText(ctx)\n if (text.trim().length === 0 && ocrMode === 'auto') {\n // Scanned PDF: no text layer. OCR-from-PDF is engine territory (the engine must accept\n // application/pdf); surface the actionable path instead of silently returning nothing.\n if (!ctx.engines.hasConvert(mime, 'txt')) {\n fail(\n VERB,\n 'this PDF has no text layer (scanned?). An engine that converts application/pdf to text (OCR) is required to read it, and none is configured. Do not retry this verb on this media in this deployment.'\n )\n }\n return asData(await runOcr(ctx))\n }\n return asData(text)\n }\n if (mime === MIME.DOCX || mime === MIME.DOC) return asData(await extractDocxText(ctx))\n if (mime === MIME.XLSX) return asData(await extractXlsxText(ctx))\n if (mime === MIME.ODT || mime === MIME.ODS || mime === MIME.ODP) {\n return asData(await extractOdfText(ctx))\n }\n if (mime === MIME.PPTX) return asData(await extractPptxText(ctx))\n if (mime.startsWith('text/') || mime === MIME.JSON) {\n return asData(decodeText(ctx.payload.bytes))\n }\n fail(\n VERB,\n `text extraction for ${mime} is not supported in this build. For PPT/legacy formats: convert to=pptx | extract text (requires a convert engine).`\n )\n /* unreachable */ throw new Error('unreachable')\n}\n\n/** `extract.metadata` — format-aware metadata (page counts, sheet/slide inventories). */\nexport const extractMetadataDeepStep: StepImpl = async (ctx) => {\n const mime = ctx.payload.mimeType.toLowerCase().split(';')[0].trim()\n const meta: Record<string, unknown> = {\n filename: ctx.payload.filename,\n mime_type: ctx.payload.mimeType,\n size_bytes: ctx.payload.bytes.byteLength,\n family: familyOf(ctx.payload.mimeType),\n }\n try {\n if (mime === MIME.PDF) {\n const { PDFDocument } = await import('pdf-lib')\n const doc = await PDFDocument.load(ctx.payload.bytes, { ignoreEncryption: true })\n meta.page_count = doc.getPageCount()\n meta.title = doc.getTitle() ?? undefined\n meta.author = doc.getAuthor() ?? undefined\n } else if (mime === MIME.XLSX) {\n const mod = await import('exceljs')\n const ExcelJS = ('default' in mod ? mod.default : mod) as typeof ExcelJSNS\n const wb = new ExcelJS.Workbook()\n await wb.xlsx.load(\n ctx.payload.bytes.buffer.slice(\n ctx.payload.bytes.byteOffset,\n ctx.payload.bytes.byteOffset + ctx.payload.bytes.byteLength\n ) as ArrayBuffer\n )\n meta.sheets = wb.worksheets.map((ws) => ({ name: ws.name, rows: ws.rowCount }))\n } else if (mime === MIME.PPTX) {\n const JSZip = await jszip()\n const zip = await JSZip.loadAsync(ctx.payload.bytes)\n meta.slide_count = Object.keys(zip.files).filter((n) =>\n /^ppt\\/slides\\/slide\\d+\\.xml$/.test(n)\n ).length\n }\n } catch {\n // Metadata enrichment is best-effort; the basics above always report.\n }\n return { kind: 'data', data: meta, asText: JSON.stringify(meta) }\n}\n\n/** The ingest step registry fragment (overrides the Phase 0 native-text-only versions). */\nexport const INGEST_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['extract.text', extractTextDeepStep],\n ['extract.metadata', extractMetadataDeepStep],\n]\n","/**\n * The engine registry: capability-filtered, middleware-arbitrated, ordered dispatch over the\n * pipeline's engine array.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry (re-exported through the barrel).\n * One selection rule everywhere: gather every engine whose declarations match the request\n * (capability filter), run the consumer's selection onion (stages may exclude or reorder\n * candidates, never add), then the first survivor in supply order wins.\n *\n * Convert dispatch additionally computes multi-hop paths: when no single engine declares a\n * direct edge for the requested (input, target) pair, a breadth-first search over the format\n * graph finds the shortest chain of hops (capped at {@link MAX_HOPS}), with supply order\n * breaking ties at equal length. Pathfinding explores capability declarations only — cheap\n * and synchronous; the selection onion runs once per executed hop with real bytes in hand.\n */\n\nimport { EXT_TO_MIME } from './formats'\nimport { Middleware } from '@nhtio/middleware'\nimport type { NextFn } from '@nhtio/middleware'\nimport type { CapabilityProbe } from './validate'\nimport type {\n MediaEngine,\n ConvertRequest,\n ConvertResult,\n ConvertCapability,\n MutateRequest,\n MutateCapability,\n EditRequest,\n EditResult,\n EditCapability,\n EngineBytesResult,\n} from './contracts'\n\n/** The maximum number of conversion hops a computed path may take. */\nconst MAX_HOPS = 3\n\n/**\n * The no-lossy-intermediates ROUTING rule — and nothing else. These format tokens are valid\n * conversion endpoints but never intermediate path nodes: without this rule the pathfinder\n * would happily route `docx → txt → …` (lossy garbage in, garbage out) or auto-chain\n * `audio → pcm → txt` (skipping the resample the transcription step performs between those\n * legs).\n *\n * This set does NOT gate mutation, creation, or advertising. A lossy format as the *desired\n * output* is still valid media: `txt` can be created (`empty:txt`), appended to, patched,\n * diffed, and targeted by `convert to=txt` — terminality only forbids silently routing\n * *through* it on the way to somewhere else.\n */\nconst TERMINAL_TOKENS: ReadonlySet<string> = new Set([\n 'txt',\n 'json',\n 'hocr',\n 'srt',\n 'vtt',\n 'md',\n 'csv',\n 'pcm',\n 'images',\n])\n\n/** Normalize a MIME type for comparison (lowercase, parameters stripped). */\nconst normalizeMime = (mimeType: string): string => mimeType.toLowerCase().split(';')[0].trim()\n\n/** `true` when `mime` matches `pattern` (exact, or a `family/*` wildcard). */\nconst matchesMime = (pattern: string, mime: string): boolean => {\n const p = pattern.toLowerCase()\n if (p.endsWith('/*')) return mime.startsWith(p.slice(0, -1))\n return p === mime\n}\n\n/** `true` when any pattern in `patterns` matches `mime`. */\nconst matchesAny = (patterns: readonly string[], mime: string): boolean =>\n patterns.some((p) => matchesMime(p, mime))\n\n/**\n * The request summary a selection stage sees: enough to implement content- and\n * format-dependent rules without exposing dispatch internals.\n */\nexport interface EngineSelectionContext {\n /** Which capability is being dispatched. */\n kind: 'convert' | 'mutate' | 'edit'\n /** The dispatch request (for convert under multi-hop, the CURRENT hop's input/target). */\n request: {\n /** The input MIME type. */\n mimeType: string\n /** The input filename. */\n filename: string\n /** The input bytes — content-dependent rules (e.g. workbook complexity) need them. */\n bytes: Uint8Array\n /** The convert target token, or the mutate `format.to` when a re-encode was requested. */\n to?: string\n /** The requested mutate operations. */\n ops?: readonly string[]\n }\n /**\n * The capable engines, in supply order. Stages may exclude or reorder (mutate in place or\n * reassign); survivors are re-filtered against the original capable set, so a stage can\n * never add an engine the capability filter rejected.\n */\n candidates: MediaEngine[]\n}\n\n/**\n * A selection-middleware stage — the seam for quality heuristics and implementor overrides\n * when several engines can perform the same transform (e.g. route complex workbooks past a\n * pure-JS converter to LibreOffice). Same onion shape as the battery's `use` interceptors;\n * a fresh runner is minted per dispatch. Keep stages cheap or memoized: they run with bytes\n * in hand on every dispatch.\n */\nexport type EngineSelectionMiddlewareFn = (\n ctx: EngineSelectionContext,\n next: NextFn\n) => void | Promise<void>\n\n/** Ordered capability-filtered dispatch over the pipeline's engines. */\nexport interface EngineRegistry extends CapabilityProbe {\n /** The resolved engines, in supply order (inspection/debugging). */\n readonly engines: readonly MediaEngine[]\n /**\n * Every format token reachable from `fromMime` — directly or through a computed path of up\n * to three hops. Drives \"supported targets\" error messages.\n *\n * @param fromMime - The input MIME type.\n */\n convertTargets(fromMime: string): readonly string[]\n /**\n * Convert via the shortest capable path (direct edge = one hop). The selection rule picks\n * the engine for each executed hop; options are forwarded to every hop (engines ignore\n * keys they don't understand).\n *\n * @param request - The input bytes, target token, and options.\n * @returns The final hop's outputs.\n */\n convert(request: ConvertRequest): Promise<ConvertResult>\n /**\n * Apply a fused same-format transform. Candidates are engines whose `over` matches the\n * input, whose `ops` cover the requested operations, and — when a re-encode is requested —\n * whose `encodes` include the target.\n *\n * @param request - The fused operations and input bytes.\n * @returns The transformed bytes.\n */\n mutate(request: MutateRequest): Promise<EngineBytesResult>\n /**\n * Apply one structural document operation. Candidates are engines whose `over` matches the\n * input and whose `ops` include the requested op; the selection rule arbitrates between\n * engines of differing fidelity (supply order wins by default).\n *\n * @param request - The op, its args, and the input bytes.\n * @returns The restructured bytes plus optional change counts.\n */\n edit(request: EditRequest): Promise<EditResult>\n}\n\n/** One engine's matching capability group for a dispatch. */\ninterface ConvertCandidate {\n engine: MediaEngine\n capability: ConvertCapability\n}\ninterface MutateCandidate {\n engine: MediaEngine\n capability: MutateCapability\n}\ninterface EditCandidate {\n engine: MediaEngine\n capability: EditCapability\n}\n\n/** One hop of a computed conversion path. */\ninterface ConvertHop {\n /** The hop's input MIME. */\n fromMime: string\n /** The format token this hop produces. */\n to: string\n}\n\n/** The mutate operations requested by a fused request. */\nconst requestedOps = (request: MutateRequest): string[] => {\n const ops: string[] = []\n if (request.resize) ops.push('resize')\n if (request.rotate !== undefined) ops.push('rotate')\n if (request.flip) ops.push('flip')\n if (request.stripMetadata) ops.push('strip_metadata')\n return ops\n}\n\n/**\n * Build the registry over a resolved, validated engine array.\n *\n * @param engines - The engines, in supply (priority) order.\n * @param selection - Optional selection-middleware stages arbitrating multi-candidate dispatches.\n * @returns The registry.\n */\nexport const buildEngineRegistry = (\n engines: readonly MediaEngine[],\n selection: readonly EngineSelectionMiddlewareFn[] = []\n): EngineRegistry => {\n // ── capability filters (declaration-only, sync) ───────────────────────────\n const convertCandidates = (fromMime: string, to: string): ConvertCandidate[] => {\n const mime = normalizeMime(fromMime)\n const out: ConvertCandidate[] = []\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (capability.to.includes(to) && matchesAny(capability.from, mime)) {\n out.push({ engine, capability })\n break // one entry per engine; its first matching group serves the edge\n }\n }\n }\n return out\n }\n\n const mutateCandidates = (request: MutateRequest): MutateCandidate[] => {\n const mime = normalizeMime(request.mimeType)\n const ops = requestedOps(request)\n const out: MutateCandidate[] = []\n for (const engine of engines) {\n for (const capability of engine.mutates ?? []) {\n if (!matchesAny(capability.over, mime)) continue\n if (!ops.every((op) => capability.ops.includes(op))) continue\n if (request.format && !capability.encodes.includes(request.format.to)) continue\n out.push({ engine, capability })\n break\n }\n }\n return out\n }\n\n const editCandidates = (mimeType: string, op: string): EditCandidate[] => {\n const mime = normalizeMime(mimeType)\n const out: EditCandidate[] = []\n for (const engine of engines) {\n for (const capability of engine.edits ?? []) {\n if (!matchesAny(capability.over, mime)) continue\n if (!capability.ops.includes(op)) continue\n out.push({ engine, capability })\n break\n }\n }\n return out\n }\n\n // ── the selection rule ─────────────────────────────────────────────────────\n const arbitrate = async <C extends { engine: MediaEngine }>(\n kind: 'convert' | 'mutate' | 'edit',\n request: EngineSelectionContext['request'],\n candidates: C[]\n ): Promise<C | undefined> => {\n if (candidates.length === 0) return undefined\n if (selection.length === 0 || candidates.length === 1) return candidates[0]\n const ctx: EngineSelectionContext = {\n kind,\n request,\n candidates: candidates.map((c) => c.engine),\n }\n const mw = new Middleware<EngineSelectionMiddlewareFn>()\n for (const fn of selection) mw.add(fn)\n let failed: unknown\n await mw\n .runner()\n .errorHandler(async (error: unknown) => {\n failed = error\n })\n .finalHandler(async () => {})\n .run((fn, next) => Promise.resolve(fn(ctx, next)))\n if (failed !== undefined) throw failed\n // Re-filter: stages narrow/reorder, never widen. First survivor in the stages' order wins.\n for (const engine of ctx.candidates) {\n const survivor = candidates.find((c) => c.engine === engine)\n if (survivor) return survivor\n }\n return undefined\n }\n\n // ── convert pathfinding (declarations only) ───────────────────────────────\n const findPath = (fromMime: string, target: string): ConvertHop[] | undefined => {\n const start = normalizeMime(fromMime)\n const queue: Array<{ mime: string; path: ConvertHop[] }> = [{ mime: start, path: [] }]\n const visited = new Set<string>([start])\n while (queue.length > 0) {\n const { mime, path } = queue.shift()!\n if (path.length >= MAX_HOPS) continue\n // Direct edge from this node?\n if (convertCandidates(mime, target).length > 0) {\n return [...path, { fromMime: mime, to: target }]\n }\n // Expand through non-terminal tokens.\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (!matchesAny(capability.from, mime)) continue\n for (const to of capability.to) {\n if (TERMINAL_TOKENS.has(to)) continue\n const nextMime = EXT_TO_MIME[to]\n if (!nextMime || visited.has(nextMime)) continue\n visited.add(nextMime)\n queue.push({ mime: nextMime, path: [...path, { fromMime: mime, to }] })\n }\n }\n }\n }\n return undefined\n }\n\n const hasConvert = (from?: string, to?: string): boolean => {\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (from !== undefined && !matchesAny(capability.from, normalizeMime(from))) continue\n if (to !== undefined && !capability.to.includes(to)) continue\n return true\n }\n }\n return false\n }\n\n const convertTargets = (fromMime: string): readonly string[] => {\n const reachable: string[] = []\n const seen = new Set<string>()\n let frontier = [normalizeMime(fromMime)]\n const visitedMimes = new Set<string>(frontier)\n for (let hop = 0; hop < MAX_HOPS && frontier.length > 0; hop++) {\n const next: string[] = []\n for (const mime of frontier) {\n for (const engine of engines) {\n for (const capability of engine.converts ?? []) {\n if (!matchesAny(capability.from, mime)) continue\n for (const to of capability.to) {\n if (!seen.has(to)) {\n seen.add(to)\n reachable.push(to)\n }\n if (TERMINAL_TOKENS.has(to)) continue\n const nextMime = EXT_TO_MIME[to]\n if (nextMime && !visitedMimes.has(nextMime)) {\n visitedMimes.add(nextMime)\n next.push(nextMime)\n }\n }\n }\n }\n }\n frontier = next\n }\n return reachable\n }\n\n const ids = (): string => engines.map((e) => e.id).join(', ') || '(none)'\n\n const convert = async (request: ConvertRequest): Promise<ConvertResult> => {\n const path = findPath(request.mimeType, request.to)\n if (!path) {\n const supported = convertTargets(request.mimeType)\n throw new Error(\n `no configured engine (or computed path) can convert ${request.mimeType} to \"${request.to}\"; reachable targets: ${supported.join(', ') || '(none)'} (engines: ${ids()})`\n )\n }\n let bytes = request.bytes\n let mimeType = request.mimeType\n let result: ConvertResult | undefined\n for (const hop of path) {\n const candidates = convertCandidates(mimeType, hop.to)\n const chosen = await arbitrate(\n 'convert',\n { mimeType, filename: request.filename, bytes, to: hop.to },\n candidates\n )\n if (!chosen) {\n throw new Error(\n `all engines capable of converting ${mimeType} to \"${hop.to}\" (${candidates.map((c) => c.engine.id).join(', ')}) were excluded by selection middleware`\n )\n }\n result = await chosen.capability.convert({\n bytes,\n mimeType,\n filename: request.filename,\n to: hop.to,\n options: request.options,\n signal: request.signal,\n })\n const first = result.outputs[0]\n if (!first) {\n throw new Error(\n `engine \"${chosen.engine.id}\" converted ${mimeType} to \"${hop.to}\" but produced no outputs`\n )\n }\n bytes = first.bytes\n mimeType = first.mimeType\n }\n return result!\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const candidates = mutateCandidates(request)\n if (candidates.length === 0) {\n const allOps = new Set<string>()\n const allEncodes = new Set<string>()\n for (const engine of engines) {\n for (const capability of engine.mutates ?? []) {\n for (const op of capability.ops) allOps.add(op)\n for (const enc of capability.encodes) allEncodes.add(enc)\n }\n }\n const wanted = requestedOps(request).join(', ') || '(none)'\n const encodeNote = request.format\n ? `; requested encoding \"${request.format.to}\" — declared encodings: ${[...allEncodes].join(', ') || '(none)'}. A different engine (e.g. sharp) may support it`\n : ''\n throw new Error(\n `no configured engine can mutate ${request.mimeType} with ops [${wanted}]${encodeNote} (engines: ${ids()})`\n )\n }\n const chosen = await arbitrate(\n 'mutate',\n {\n mimeType: request.mimeType,\n filename: '',\n bytes: request.bytes,\n to: request.format?.to,\n ops: requestedOps(request),\n },\n candidates\n )\n if (!chosen) {\n throw new Error(\n `all engines capable of this mutate (${candidates.map((c) => c.engine.id).join(', ')}) were excluded by selection middleware`\n )\n }\n return chosen.capability.mutate(request)\n }\n\n const edit = async (request: EditRequest): Promise<EditResult> => {\n const candidates = editCandidates(request.mimeType, request.op)\n if (candidates.length === 0) {\n const allOps = new Set<string>()\n for (const engine of engines) {\n for (const capability of engine.edits ?? []) {\n for (const op of capability.ops) allOps.add(op)\n }\n }\n throw new Error(\n `no configured engine can apply \"${request.op}\" to ${request.mimeType}; declared edit ops: ${[...allOps].join(', ') || '(none)'} (engines: ${ids()})`\n )\n }\n const chosen = await arbitrate(\n 'edit',\n {\n mimeType: request.mimeType,\n filename: '',\n bytes: request.bytes,\n ops: [request.op],\n },\n candidates\n )\n if (!chosen) {\n throw new Error(\n `all engines capable of \"${request.op}\" (${candidates.map((c) => c.engine.id).join(', ')}) were excluded by selection middleware`\n )\n }\n return chosen.capability.edit(request)\n }\n\n return {\n engines,\n hasConvert,\n hasMutate: () => engines.some((e) => (e.mutates ?? []).length > 0),\n hasEdit: (mime?: string, op?: string): boolean => {\n for (const engine of engines) {\n for (const capability of engine.edits ?? []) {\n if (mime !== undefined && !matchesAny(capability.over, normalizeMime(mime))) continue\n if (op !== undefined && !capability.ops.includes(op)) continue\n return true\n }\n }\n return false\n },\n convertTargets,\n convert,\n mutate,\n edit,\n }\n}\n","/**\n * `image.*` and `audio.*` step implementations: fused raster transforms via the\n * imageTransform engine, and transcription via the audioDecode + asr engines.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. The split image verbs\n * (`resize`/`format`/`rotate`/`flip`/`strip_metadata`) read pipe-naturally, and the runtime\n * fuses **adjacent** image steps into a single engine invocation so a resize→format→rotate\n * chain costs one decode/encode (frozen design 0.13). Fusion happens here at execution time:\n * each image step folds its args into a shared fused request stored on the execution stash;\n * the LAST image step in a run performs the engine call.\n *\n * Audio transcription composes two engines: `audioDecode` (container → mono PCM) and `asr`\n * (PCM → text/subtitles). A small pure resampler bridges arbitrary sample rates to the\n * 16 kHz mono Float32Array ASR engines expect.\n */\n\nimport { argOf } from '../runtime'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { PCM_MIME, pcmToBytes, bytesToPcm } from '../contracts'\nimport type { MutateRequest } from '../contracts'\nimport type { StepImpl, StepContext, StepResult } from '../runtime'\n\nconst fail = (verb: string, message: string): never => {\n throw new E_MEDIA_STEP_FAILED([verb, message])\n}\n\n// ── image fusion ─────────────────────────────────────────────────────────────\n\ntype FusedImageOps = Omit<MutateRequest, 'bytes' | 'mimeType' | 'signal'>\n\nconst IMAGE_VERBS = new Set([\n 'image.resize',\n 'image.format',\n 'image.rotate',\n 'image.flip',\n 'image.strip_metadata',\n])\n\nconst requireImage = (ctx: StepContext, verb: string): void => {\n if (!ctx.payload.mimeType.toLowerCase().startsWith('image/')) {\n fail(verb, `image operations expect an image; the media is ${ctx.payload.mimeType}`)\n }\n}\n\n/** Fold this step's args into the fused request. */\nconst foldImageStep = (ctx: StepContext, fused: FusedImageOps): FusedImageOps => {\n const args = ctx.step.args\n switch (ctx.step.verb) {\n case 'image.resize':\n return {\n ...fused,\n resize: {\n width: args.width as number | undefined,\n height: args.height as number | undefined,\n fit: args.fit as FusedImageOps['resize'] extends undefined\n ? never\n : NonNullable<FusedImageOps['resize']>['fit'],\n },\n }\n case 'image.format':\n return {\n ...fused,\n format: { to: args.to as string, quality: args.quality as number | undefined },\n ...(args.strip_metadata !== undefined\n ? { stripMetadata: args.strip_metadata as boolean }\n : {}),\n }\n case 'image.rotate': {\n const deg = Number(args.deg) as 90 | 180 | 270\n const total = (((fused.rotate ?? 0) + deg) % 360) as 0 | 90 | 180 | 270\n return { ...fused, rotate: total === 0 ? undefined : total }\n }\n case 'image.flip': {\n const axis = args.axis as 'horizontal' | 'vertical' | 'both'\n const flip = { ...(fused.flip ?? {}) }\n if (axis === 'horizontal' || axis === 'both') flip.horizontal = !flip.horizontal\n if (axis === 'vertical' || axis === 'both') flip.vertical = !flip.vertical\n return { ...fused, flip }\n }\n case 'image.strip_metadata':\n return { ...fused, stripMetadata: true }\n default:\n return fused\n }\n}\n\n/** `true` when the NEXT step in the plan is also an image verb (so we defer the engine call). */\nconst nextIsImageStep = (ctx: StepContext): boolean => {\n const next = ctx.plan.steps[ctx.stepIndex + 1]\n return next !== undefined && IMAGE_VERBS.has(next.verb)\n}\n\nconst FUSION_KEY = 'media.image.fused'\n\nconst imageStep: StepImpl = async (ctx) => {\n const verb = ctx.step.verb.replace(/\\./g, ' ')\n requireImage(ctx, verb)\n const prior = (ctx.stash.get(FUSION_KEY) as FusedImageOps | undefined) ?? {}\n const fused = foldImageStep(ctx, prior)\n if (nextIsImageStep(ctx)) {\n // Defer: pass the payload through untouched; the last image step executes the engine.\n ctx.stash.set(FUSION_KEY, fused)\n return { kind: 'media', payload: ctx.payload }\n }\n ctx.stash.delete(FUSION_KEY)\n if (!ctx.engines.hasMutate()) {\n fail(\n verb,\n 'no image-mutating engine is configured. Do not retry image verbs in this deployment.'\n )\n }\n const result = await ctx.engines.mutate({\n ...fused,\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n signal: ctx.signal,\n })\n const ext = result.mimeType.split('/')[1]?.replace('jpeg', 'jpg') ?? 'bin'\n const dot = ctx.payload.filename.lastIndexOf('.')\n const base = dot > 0 ? ctx.payload.filename.slice(0, dot) : ctx.payload.filename\n return {\n kind: 'media',\n payload: { bytes: result.bytes, mimeType: result.mimeType, filename: `${base}.${ext}` },\n }\n}\n\n// ── audio ────────────────────────────────────────────────────────────────────\n\n/** Downmix to mono and linearly resample to the target rate. Pure, cross-env. */\nexport const resampleTo = (pcm: Float32Array, fromRate: number, toRate: number): Float32Array => {\n if (fromRate === toRate) return pcm\n const ratio = fromRate / toRate\n const outLength = Math.floor(pcm.length / ratio)\n const out = new Float32Array(outLength)\n for (let i = 0; i < outLength; i++) {\n const pos = i * ratio\n const left = Math.floor(pos)\n const right = Math.min(left + 1, pcm.length - 1)\n const frac = pos - left\n out[i] = pcm[left] * (1 - frac) + pcm[right] * frac\n }\n return out\n}\n\nconst ASR_SAMPLE_RATE = 16_000\n\n/**\n * `audio.transcribe` — an explicit two-stage composition: convert the container to PCM,\n * resample to 16 kHz mono, then convert the PCM to the requested text form. The registry\n * never auto-chains through PCM (it is a terminal token), precisely because this resample\n * leg must happen between the two converts.\n */\nconst audioTranscribeStep: StepImpl = async (ctx): Promise<StepResult> => {\n const verb = 'audio transcribe'\n if (!ctx.payload.mimeType.toLowerCase().startsWith('audio/')) {\n fail(verb, `transcription expects audio; the media is ${ctx.payload.mimeType}`)\n }\n const out = (argOf<string>(ctx.step, 'out') ?? 'txt') as 'txt' | 'srt' | 'vtt' | 'json'\n if (!ctx.engines.hasConvert(ctx.payload.mimeType, 'pcm')) {\n fail(\n verb,\n `no engine that decodes ${ctx.payload.mimeType} to PCM is configured. Do not retry this verb in this deployment.`\n )\n }\n if (!ctx.engines.hasConvert(PCM_MIME, out)) {\n fail(\n verb,\n `no engine that transcribes PCM to \"${out}\" is configured. Do not retry this verb in this deployment.`\n )\n }\n const decoded = await ctx.engines.convert({\n bytes: ctx.payload.bytes,\n mimeType: ctx.payload.mimeType,\n filename: ctx.payload.filename,\n to: 'pcm',\n signal: ctx.signal,\n })\n const pcmOut = decoded.outputs[0]\n if (!pcmOut) fail(verb, 'audio decoding produced no output')\n const sourceRate = Number(pcmOut!.meta?.sampleRate)\n if (!Number.isFinite(sourceRate) || sourceRate <= 0) {\n fail(verb, 'the decode engine did not report meta.sampleRate on its PCM output')\n }\n const pcm = resampleTo(bytesToPcm(pcmOut!.bytes), sourceRate, ASR_SAMPLE_RATE)\n const result = await ctx.engines.convert({\n bytes: pcmToBytes(pcm),\n mimeType: PCM_MIME,\n filename: ctx.payload.filename,\n to: out,\n options: {\n lang: argOf<string>(ctx.step, 'lang'),\n translate: argOf<boolean>(ctx.step, 'translate'),\n },\n signal: ctx.signal,\n })\n const final = result.outputs[0]\n if (!final) fail(verb, 'transcription produced no output')\n const text = new TextDecoder().decode(final!.bytes)\n return { kind: 'data', data: text, asText: text }\n}\n\n/** The image + audio step registry fragment. */\nexport const IMAGE_AUDIO_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['image.resize', imageStep],\n ['image.format', imageStep],\n ['image.rotate', imageStep],\n ['image.flip', imageStep],\n ['image.strip_metadata', imageStep],\n ['audio.transcribe', audioTranscribeStep],\n]\n","/**\n * Pure page-operation step implementations for PDFs: select, split, merge, reorder.\n *\n * @remarks\n * Internal sibling of the `@nhtio/adk/batteries/media` entry. Implemented with `pdf-lib`\n * (optional peer, lazily imported) on in-memory bytes — no binaries, cross-environment.\n * Phase 0 covers PDF inputs; PPTX slide operations and DOCX section operations join in the\n * sheet/slides/doc phases, sharing these verb ids with format dispatch.\n */\n\nimport { argOf } from '../runtime'\nimport { isError } from '@nhtio/adk/guards'\nimport { E_MEDIA_STEP_FAILED } from '../exceptions'\nimport { MIME, replaceExtension } from '../formats'\nimport type { MediaRef } from '../plan'\nimport type * as PdfLibModule from 'pdf-lib'\nimport type { StepImpl, StepPayload } from '../runtime'\n\ntype PdfLib = typeof PdfLibModule\ntype PDFDocumentType = PdfLibModule.PDFDocument\n\nlet pdfLibPromise: Promise<PdfLib> | undefined\nconst pdfLib = (): Promise<PdfLib> => {\n pdfLibPromise ??= import('pdf-lib')\n return pdfLibPromise\n}\n\nconst requirePdf = (verb: string, payload: StepPayload): void => {\n if (payload.mimeType.toLowerCase().split(';')[0].trim() !== MIME.PDF) {\n throw new E_MEDIA_STEP_FAILED([\n verb,\n `page operations for ${payload.mimeType} are not yet implemented in this build (PDF is supported)`,\n ])\n }\n}\n\nconst loadPdf = async (verb: string, bytes: Uint8Array): Promise<PDFDocumentType> => {\n const { PDFDocument } = await pdfLib()\n try {\n return await PDFDocument.load(bytes, { ignoreEncryption: false })\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_MEDIA_STEP_FAILED([verb, `could not read the PDF: ${detail}`], { cause: err })\n }\n}\n\nconst checkIndices = (verb: string, indices: number[], pageCount: number): void => {\n for (const i of indices) {\n if (i < 1 || i > pageCount) {\n throw new E_MEDIA_STEP_FAILED([\n verb,\n `page ${i} is out of range — the document has ${pageCount} pages (pages are 1-based)`,\n ])\n }\n }\n}\n\n/** `select` — keep only the listed 1-based pages, producing one document. */\nexport const selectStep: StepImpl = async (ctx) => {\n requirePdf('select', ctx.payload)\n const pages = argOf<number[]>(ctx.step, 'pages') as number[]\n const source = await loadPdf('select', ctx.payload.bytes)\n checkIndices('select', pages, source.getPageCount())\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n pages.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = await out.save()\n return { kind: 'media', payload: { ...ctx.payload, bytes: new Uint8Array(bytes) } }\n}\n\n/** `split` — split into multiple documents by page (optionally grouped by JSON ranges). */\nexport const splitStep: StepImpl = async (ctx) => {\n requirePdf('split', ctx.payload)\n const by = argOf<string>(ctx.step, 'by') ?? 'page'\n if (by !== 'page') {\n throw new E_MEDIA_STEP_FAILED([\n 'split',\n `split by=${by} is not yet implemented in this build (page is supported)`,\n ])\n }\n const source = await loadPdf('split', ctx.payload.bytes)\n const pageCount = source.getPageCount()\n const rawRanges = ctx.step.args.ranges as number[][] | undefined\n const groups: number[][] =\n rawRanges !== undefined\n ? rawRanges.map((pair) => {\n if (!Array.isArray(pair) || pair.length !== 2) {\n throw new E_MEDIA_STEP_FAILED([\n 'split',\n `ranges must be [start,end] pairs, e.g. ranges='[[1,3],[5,7]]'`,\n ])\n }\n const [start, end] = pair\n const pages: number[] = []\n for (let p = start; p <= end; p++) pages.push(p)\n return pages\n })\n : Array.from({ length: pageCount }, (_, i) => [i + 1])\n const { PDFDocument } = await pdfLib()\n const payloads: StepPayload[] = []\n let part = 1\n for (const group of groups) {\n checkIndices('split', group, pageCount)\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n group.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = new Uint8Array(await out.save())\n payloads.push({\n bytes,\n mimeType: MIME.PDF,\n filename: replaceExtension(ctx.payload.filename, '').replace(/\\.$/, '') + `.part${part}.pdf`,\n })\n part += 1\n }\n return { kind: 'media-list', payloads }\n}\n\n/** `merge` — append the referenced media's pages, in order. */\nexport const mergeStep: StepImpl = async (ctx) => {\n requirePdf('merge', ctx.payload)\n const raw = ctx.step.args.with\n const refs = (Array.isArray(raw) ? raw : [raw]) as MediaRef[]\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const appendAll = async (doc: PDFDocumentType): Promise<void> => {\n const copied = await out.copyPages(doc, doc.getPageIndices())\n for (const page of copied) out.addPage(page)\n }\n await appendAll(await loadPdf('merge', ctx.payload.bytes))\n for (const ref of refs) {\n if (ref.kind !== 'id') {\n throw new E_MEDIA_STEP_FAILED(['merge', 'builder refs are not yet supported here'])\n }\n const other = await ctx.resolveRef(ref.id)\n requirePdf('merge', other)\n await appendAll(await loadPdf('merge', other.bytes))\n }\n const bytes = new Uint8Array(await out.save())\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n\n/** `reorder` — rebuild the document with pages in the given 1-based order. */\nexport const reorderStep: StepImpl = async (ctx) => {\n requirePdf('reorder', ctx.payload)\n const order = argOf<number[]>(ctx.step, 'order') as number[]\n const source = await loadPdf('reorder', ctx.payload.bytes)\n const pageCount = source.getPageCount()\n checkIndices('reorder', order, pageCount)\n if (order.length !== pageCount) {\n throw new E_MEDIA_STEP_FAILED([\n 'reorder',\n `order lists ${order.length} pages but the document has ${pageCount} — list every page exactly once`,\n ])\n }\n const { PDFDocument } = await pdfLib()\n const out = await PDFDocument.create()\n const copied = await out.copyPages(\n source,\n order.map((p) => p - 1)\n )\n for (const page of copied) out.addPage(page)\n const bytes = new Uint8Array(await out.save())\n return { kind: 'media', payload: { ...ctx.payload, bytes } }\n}\n","/**\n * A knex-inspired local media pipeline: one declarative plan, three front-ends (chainable\n * builder, pipe string, JSON ops), engines as composable seams.\n *\n * @module @nhtio/adk/batteries/media\n *\n * @remarks\n * Most implementations give you two ways to process media — ship it to an external API, or\n * flood the model's context window with the bytes. This battery is the third option: **full\n * control of media — local processing, no external APIs by default, cross-environment where\n * possible.** Your data stays in your application and infrastructure unless you deliberately\n * wire an engine that sends it elsewhere.\n *\n * The entry point is {@link createMediaPipeline}:\n *\n * ```ts\n * import { createMediaPipeline } from '@nhtio/adk/batteries/media'\n *\n * const mp = await createMediaPipeline({\n * engines: [\n * // an ordered array of self-declaring engines; resolvers run eagerly at construction,\n * // but each engine's heavy peer dependency loads lazily on first actual use\n * () => import('@nhtio/adk/batteries/media/engines/jimp').then((m) => m.jimpEngine()),\n * ],\n * })\n *\n * // chainable builder (implementor DX)\n * const redacted = await mp(payload)\n * .select({ pages: [2, 3] })\n * .redact({ match: [/\\d{3}-\\d{2}-\\d{4}/] })\n *\n * // pipe string (the LLM-facing DSL — same plan underneath)\n * const result = await mp.query(payload, 'select pages=2-3 | redact match=/\\\\d{3}-\\\\d{2}-\\\\d{4}/')\n * ```\n *\n * Media pipelines have no standard — every tool invented its own grammar. LLMs don't share one\n * mental model of that chaos, so the pipe DSL projects every operation onto the one\n * transformation idiom every model already groks: shell pipes with `key=value` args. The verbs\n * a deployment advertises narrow to the engines it configured; everything else fails loud with\n * a model-actionable message.\n */\n\nimport { parsePipeRaw } from './pipe'\nimport { MediaChain } from './builder'\nimport { executePlan } from './runtime'\nimport { DOC_STEPS } from './steps/doc'\nimport { DATA_STEPS } from './steps/data'\nimport { SHEET_STEPS } from './steps/sheet'\nimport { validator } from '@nhtio/validation'\nimport { SLIDES_STEPS } from './steps/slides'\nimport { INGEST_STEPS } from './steps/ingest'\nimport { buildEngineRegistry } from './registry'\nimport { implementsMediaEngine } from './contracts'\nimport { isError, isObject } from '@nhtio/adk/guards'\nimport { IMAGE_AUDIO_STEPS } from './steps/image_audio'\nimport { validateSegments, validateOps } from './validate'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from './exceptions'\nimport { selectStep, splitStep, mergeStep, reorderStep } from './steps/pages'\nimport {\n chunkStep,\n extractTextStep,\n extractMetadataStep,\n redactStep,\n updateTextStep,\n diffStep,\n applyPatchStep,\n} from './steps/text'\nimport type { MediaOp, MediaPlan } from './plan'\nimport type { MediaEngine, EngineResolver } from './contracts'\nimport type { EngineRegistry, EngineSelectionMiddlewareFn } from './registry'\nimport type { StepImpl, StepPayload, PlanResult, MediaStepMiddlewareFn } from './runtime'\n\nexport { MediaChain } from './builder'\nexport type {\n ChainExecutor,\n ChainInput,\n MediaChainRef,\n CellUpdate,\n ResizeOptions,\n SheetNamespace,\n SlidesNamespace,\n ImageNamespace,\n AudioNamespace,\n} from './builder'\nexport { toPipe, toOps, fromOps, isMediaRef, isRegExpRef } from './plan'\nexport type {\n MediaPlan,\n MediaStep,\n MediaOp,\n MediaArgValue,\n MediaArgScalar,\n MediaArgJson,\n MediaRef,\n RegExpRef,\n SourceSpan,\n} from './plan'\nexport { parsePipeRaw, lowerSegments } from './pipe'\nexport type { RawSegment, RawArgValue } from './pipe'\nexport { validateSegments, validateOps, availableVerbs } from './validate'\nexport type { ValidateOptions, CapabilityProbe } from './validate'\nexport { VERBS, VERB_INDEX, FOLDED_VERBS, foldVerb, suggestVerbs } from './verbs'\nexport type {\n VerbSpec,\n VerbArgSpec,\n VerbArgType,\n VerbOutput,\n VerbRequirement,\n FormatFamily,\n} from './verbs'\nexport { PCM_MIME, EMPTY_MIME, pcmToBytes, bytesToPcm, implementsMediaEngine } from './contracts'\nexport type {\n MediaEngine,\n EngineResolver,\n ConvertCapability,\n ConvertRequest,\n ConvertResult,\n ConvertOutput,\n ConvertOptions,\n OcrConvertOptions,\n AsrConvertOptions,\n ImagesConvertOptions,\n MutateCapability,\n MutateRequest,\n EditCapability,\n EditRequest,\n EditResult,\n EditSummary,\n MimePattern,\n} from './contracts'\nexport { buildEngineRegistry } from './registry'\nexport type {\n EngineRegistry,\n EngineSelectionContext,\n EngineSelectionMiddlewareFn,\n} from './registry'\nexport type {\n StepPayload,\n StepResult,\n PlanResult,\n StepContext,\n StepImpl,\n MediaStepMiddlewareFn,\n} from './runtime'\nexport {\n MIME,\n familyOf,\n unsupportedForMutationReason,\n replaceExtension,\n EXT_TO_MIME,\n} from './formats'\nexport {\n E_INVALID_MEDIA_PIPELINE_CONFIG,\n E_MEDIA_PIPE_SYNTAX,\n E_MEDIA_UNKNOWN_VERB,\n E_MEDIA_UNKNOWN_ARG,\n E_MEDIA_BAD_ARG,\n E_MEDIA_MISSING_ARG,\n E_MEDIA_UNSUPPORTED_OP,\n E_MEDIA_ENGINE_REQUIRED,\n E_MEDIA_NOT_PIPE_EXPRESSIBLE,\n E_MEDIA_STEP_FAILED,\n E_MEDIA_STEP_UNAVAILABLE,\n} from './exceptions'\n\n/** Resolves a media-ref id to its payload — supplied by the consumer (or the agent forge). */\nexport type MediaRefResolver = (id: string) => StepPayload | Promise<StepPayload>\n\n/** Per-run options for `query`/`ops`. */\nexport interface RunOptions {\n /** Abort signal threaded into steps and engines. */\n signal?: AbortSignal\n /** Per-run media-ref resolution, overriding the construction-time resolver (the agent forge uses this to resolve `@id` refs against the current turn). */\n resolveRef?: MediaRefResolver\n}\n\n/** Configuration for {@link createMediaPipeline}. */\nexport interface MediaPipelineConfig {\n /**\n * The engine array, in priority order. Each entry is a {@link MediaEngine} instance or a\n * resolver returning one (async dynamic import is the canonical form). Engines self-declare\n * their capabilities; verbs whose capability has no provider are not advertised and fail\n * validation with a do-not-retry message if reached. Resolvers run eagerly at construction —\n * bundled engines stay cheap because their heavy peers lazy-load inside capability methods.\n */\n engines?: ReadonlyArray<EngineResolver<MediaEngine>>\n /**\n * Selection-middleware stages arbitrating dispatches where several engines can perform the\n * same transform. Stages may exclude or reorder candidates (quality heuristics, overrides);\n * array order among survivors always breaks the tie. Most deployments need none.\n */\n selection?: EngineSelectionMiddlewareFn[]\n /**\n * Consumer step interceptors wrapping every step — the documented seam for DLP/AV byte\n * scanning, caching (via `ctx.shortCircuit`), byte limits, and telemetry. The battery\n * ships no built-in scanner/cache/limiter.\n */\n use?: MediaStepMiddlewareFn[]\n /**\n * Resolves `@id` media refs (merge/diff/replace targets). Required only when chains use\n * multi-input verbs; the agent forge supplies a turn-state resolver automatically.\n */\n resolveRef?: MediaRefResolver\n}\n\n/**\n * The callable pipeline returned by {@link createMediaPipeline}: `mp(payload)` opens a\n * chainable builder; `mp.query(payload, q)` runs a pipe-string statement; `mp.ops(payload,\n * ops)` runs a JSON ops array. All three compile to the same plan and execute on the same\n * runtime.\n */\nexport interface MediaPipeline {\n /** Open a fresh chainable builder over `input`. */\n (input: StepPayload): MediaChain\n /** Parse, validate, and execute a pipe-string statement. */\n query(input: StepPayload, q: string, options?: RunOptions): Promise<PlanResult>\n /** Validate and execute a JSON ops array. */\n ops(input: StepPayload, ops: MediaOp[], options?: RunOptions): Promise<PlanResult>\n /** Validate a pipe string or ops array to a plan WITHOUT executing (dry-run/compile). */\n compile(statement: string | MediaOp[]): MediaPlan\n /**\n * The deployment's engine registry (drives verb narrowing AND generation/edit dispatch —\n * the runtime value has always been the registry; the declared type now says so).\n */\n readonly capabilities: EngineRegistry\n /** The resolved engines, in supply order — inspect ids and declared capabilities. */\n readonly engines: readonly MediaEngine[]\n}\n\nconst configSchema = validator\n .object({\n engines: validator\n .array()\n .items(validator.alternatives().try(validator.function(), validator.object().unknown(true)))\n .optional(),\n selection: validator.array().items(validator.function()).optional(),\n use: validator.array().items(validator.function()).optional(),\n resolveRef: validator.function().optional(),\n })\n .unknown(false)\n\n/** The Phase 0 step registry: pure steps available in every deployment. */\nconst PURE_STEPS: ReadonlyArray<[string, StepImpl]> = [\n ['select', selectStep],\n ['split', splitStep],\n ['merge', mergeStep],\n ['reorder', reorderStep],\n ['redact', redactStep],\n ['update_text', updateTextStep],\n ['diff', diffStep],\n ['apply_patch', applyPatchStep],\n ['extract.text', extractTextStep],\n ['extract.metadata', extractMetadataStep],\n ['chunk', chunkStep],\n ...DATA_STEPS,\n ...SHEET_STEPS,\n ...SLIDES_STEPS,\n // DOC_STEPS + INGEST_STEPS override the Phase 0 text-only implementations with format dispatch.\n ...DOC_STEPS,\n ...INGEST_STEPS,\n ...IMAGE_AUDIO_STEPS,\n]\n\n/** Resolve one engine entry: invoke a resolver, unwrap `{default}`, guard-check the result. */\nconst resolveEngine = async (\n entry: EngineResolver<MediaEngine>,\n index: number\n): Promise<MediaEngine> => {\n let value: unknown = entry\n if (typeof value === 'function') {\n try {\n value = await (value as () => unknown)()\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`engines[${index}] resolver failed: ${detail}`])\n }\n if (isObject(value) && 'default' in value && !implementsMediaEngine(value)) {\n value = (value as { default: unknown }).default\n }\n }\n if (!implementsMediaEngine(value)) {\n const candidate = value as { id?: unknown } | undefined\n const id = isObject(value) && typeof candidate?.id === 'string' ? ` (\"${candidate.id}\")` : ''\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `engines[${index}]${id} does not implement the MediaEngine contract (a string id plus at least one well-formed converts/mutates capability entry)`,\n ])\n }\n return value\n}\n\n/**\n * Create a media pipeline.\n *\n * @remarks\n * Config is validated eagerly, and so are the engines: every resolver in the array runs at\n * construction (capability declarations drive verb narrowing, so they must be known up\n * front), each result is contract-checked, and failures throw\n * `E_INVALID_MEDIA_PIPELINE_CONFIG` naming the offending index. Construction stays cheap —\n * bundled engine modules import their heavy peer dependencies lazily inside capability\n * methods, on first actual use.\n *\n * @param config - Engines, selection stages, step interceptors, and the media-ref resolver.\n * @returns The callable {@link MediaPipeline}.\n */\nexport const createMediaPipeline = async (\n config: MediaPipelineConfig = {}\n): Promise<MediaPipeline> => {\n const { error } = configSchema.validate(config, { abortEarly: true })\n if (error) {\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([error.message])\n }\n const use = config.use ?? []\n const resolveRef: MediaRefResolver =\n config.resolveRef ??\n (() => {\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n 'this chain references another media (@id) but no resolveRef was configured',\n ])\n })\n\n const resolvedEngines = await Promise.all((config.engines ?? []).map(resolveEngine))\n const registry = buildEngineRegistry(resolvedEngines, config.selection ?? [])\n\n const steps = new Map<string, StepImpl>(PURE_STEPS)\n\n const run = async (\n input: StepPayload,\n plan: MediaPlan,\n options?: RunOptions\n ): Promise<PlanResult> => {\n const refResolver = options?.resolveRef ?? resolveRef\n return executePlan(plan, {\n input,\n steps,\n use,\n engines: registry,\n resolveRef: async (id) => refResolver(id),\n signal: options?.signal,\n })\n }\n\n const compile = (statement: string | MediaOp[]): MediaPlan =>\n typeof statement === 'string'\n ? validateSegments(parsePipeRaw(statement), { capabilities: registry })\n : validateOps(statement, { capabilities: registry })\n\n const callable = ((input: StepPayload): MediaChain => {\n return new MediaChain(async (ops) => {\n const plan = validateOps(ops, { capabilities: registry })\n return run(input, plan)\n })\n }) as MediaPipeline\n\n Object.defineProperties(callable, {\n query: {\n value: async (input: StepPayload, q: string, options?: RunOptions): Promise<PlanResult> => {\n const plan = validateSegments(parsePipeRaw(q), { capabilities: registry })\n return run(input, plan, options)\n },\n },\n ops: {\n value: async (\n input: StepPayload,\n ops: MediaOp[],\n options?: RunOptions\n ): Promise<PlanResult> => {\n const plan = validateOps(ops, { capabilities: registry })\n return run(input, plan, options)\n },\n },\n compile: { value: compile },\n capabilities: { value: registry },\n engines: { value: registry.engines },\n })\n\n return callable\n}\n"],"mappings":"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"}
|