@yadsh/dsh-qa-surface 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +194 -9
- package/compatibility.json +10 -1
- package/cordis.patch.yml +9 -0
- package/lib/account-remotes.js +10 -0
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/file.js.map +1 -1
- package/lib/accounts/store.js +22 -0
- package/lib/accounts/store.js.map +1 -1
- package/lib/client/QaAccountsController.js +29 -0
- package/lib/client/QaAccountsController.js.map +1 -1
- package/lib/client/QaSessionController.js +168 -48
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +125 -56
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/QaSurfaceGuard.js +96 -0
- package/lib/client/QaSurfaceGuard.js.map +1 -0
- package/lib/client/QaTranscriptAdapter.js +11 -5
- package/lib/client/QaTranscriptAdapter.js.map +1 -1
- package/lib/client/components/QaChangelog.js +31 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/components/QaComposer.js +1 -1
- package/lib/client/components/QaComposer.js.map +1 -1
- package/lib/client/components/QaHeader.js +2 -8
- package/lib/client/components/QaHeader.js.map +1 -1
- package/lib/client/components/QaMessage.js +20 -7
- package/lib/client/components/QaMessage.js.map +1 -1
- package/lib/client/components/QaModal.js +24 -6
- package/lib/client/components/QaModal.js.map +1 -1
- package/lib/client/components/QaSidebar.js +2 -6
- package/lib/client/components/QaSidebar.js.map +1 -1
- package/lib/client/components/QaSourcesPanel.js +6 -5
- package/lib/client/components/QaSourcesPanel.js.map +1 -1
- package/lib/client/components/QaWidthHandle.js +21 -1
- package/lib/client/components/QaWidthHandle.js.map +1 -1
- package/lib/client/components/surface-utils.js +2 -0
- package/lib/client/components/surface-utils.js.map +1 -1
- package/lib/client/index.js +72 -24
- package/lib/client/index.js.map +1 -1
- package/lib/client/panels/PanelHost.js +209 -0
- package/lib/client/panels/PanelHost.js.map +1 -0
- package/lib/client/panels/PanelLauncher.js +39 -0
- package/lib/client/panels/PanelLauncher.js.map +1 -0
- package/lib/client/panels/contract.js +2 -0
- package/lib/client/panels/contract.js.map +1 -0
- package/lib/client/panels/index.js +2 -0
- package/lib/client/panels/index.js.map +1 -0
- package/lib/client/panels/registry.js +171 -0
- package/lib/client/panels/registry.js.map +1 -0
- package/lib/client/project-session-state.js +3 -0
- package/lib/client/project-session-state.js.map +1 -1
- package/lib/client/settings/card.js +2 -2
- package/lib/client/settings/card.js.map +1 -1
- package/lib/client/settings/sections/accounts.js +3 -1
- package/lib/client/settings/sections/accounts.js.map +1 -1
- package/lib/client/settings/sections/documents.js +88 -0
- package/lib/client/settings/sections/documents.js.map +1 -0
- package/lib/client/settings/sections/interface.js +2 -0
- package/lib/client/settings/sections/interface.js.map +1 -1
- package/lib/client/settings/sections.js +1 -0
- package/lib/client/settings/sections.js.map +1 -1
- package/lib/client/settings-extensions/contract.js +2 -0
- package/lib/client/settings-extensions/contract.js.map +1 -0
- package/lib/client/settings-extensions/index.js +2 -0
- package/lib/client/settings-extensions/index.js.map +1 -0
- package/lib/client/settings-extensions/registry.js +63 -0
- package/lib/client/settings-extensions/registry.js.map +1 -0
- package/lib/client/settlement.js +51 -5
- package/lib/client/settlement.js.map +1 -1
- package/lib/client/source-preview.js +24 -0
- package/lib/client/source-preview.js.map +1 -0
- package/lib/client/styles.js +157 -32
- package/lib/client/styles.js.map +1 -1
- package/lib/client/subagent-codenames.js +109 -0
- package/lib/client/subagent-codenames.js.map +1 -0
- package/lib/client/types.js +1 -0
- package/lib/client/types.js.map +1 -1
- package/lib/client/user-settings/GeneralSettingsPage.js +13 -0
- package/lib/client/user-settings/GeneralSettingsPage.js.map +1 -0
- package/lib/client/user-settings/ProfileSettingsPage.js +59 -0
- package/lib/client/user-settings/ProfileSettingsPage.js.map +1 -0
- package/lib/client/user-settings/SkillCatalog.js +23 -0
- package/lib/client/user-settings/SkillCatalog.js.map +1 -0
- package/lib/client/user-settings/SkillEditor.js +89 -0
- package/lib/client/user-settings/SkillEditor.js.map +1 -0
- package/lib/client/user-settings/SkillToolPicker.js +58 -0
- package/lib/client/user-settings/SkillToolPicker.js.map +1 -0
- package/lib/client/user-settings/SkillsSettingsPage.js +171 -0
- package/lib/client/user-settings/SkillsSettingsPage.js.map +1 -0
- package/lib/client/user-settings/StartersSettingsPage.js +78 -0
- package/lib/client/user-settings/StartersSettingsPage.js.map +1 -0
- package/lib/client/user-settings/UserSettingsDialog.js +50 -0
- package/lib/client/user-settings/UserSettingsDialog.js.map +1 -0
- package/lib/client/user-settings/copy.js +84 -0
- package/lib/client/user-settings/copy.js.map +1 -0
- package/lib/client/user-settings/draft.js +127 -0
- package/lib/client/user-settings/draft.js.map +1 -0
- package/lib/client/user-settings/fields.js +24 -0
- package/lib/client/user-settings/fields.js.map +1 -0
- package/lib/client.js +5467 -1379
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/accounts.js +30 -0
- package/lib/config-resolvers/accounts.js.map +1 -1
- package/lib/config-resolvers/defaults.js +23 -0
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/tools.js +37 -0
- package/lib/config-resolvers/tools.js.map +1 -0
- package/lib/config-resolvers/ui.js +2 -0
- package/lib/config-resolvers/ui.js.map +1 -1
- package/lib/config.js +288 -0
- package/lib/config.js.map +1 -1
- package/lib/documents/artifacts/ids.js +43 -0
- package/lib/documents/artifacts/ids.js.map +1 -0
- package/lib/documents/artifacts/manifest.js +66 -0
- package/lib/documents/artifacts/manifest.js.map +1 -0
- package/lib/documents/artifacts/store.js +169 -0
- package/lib/documents/artifacts/store.js.map +1 -0
- package/lib/documents/capabilities.js +93 -0
- package/lib/documents/capabilities.js.map +1 -0
- package/lib/documents/config.js +302 -0
- package/lib/documents/config.js.map +1 -0
- package/lib/documents/defaults.js +78 -0
- package/lib/documents/defaults.js.map +1 -0
- package/lib/documents/errors.js +101 -0
- package/lib/documents/errors.js.map +1 -0
- package/lib/documents/index.js +80 -0
- package/lib/documents/index.js.map +1 -0
- package/lib/documents/inspect/facts.js +161 -0
- package/lib/documents/inspect/facts.js.map +1 -0
- package/lib/documents/inspect/zip.js +108 -0
- package/lib/documents/inspect/zip.js.map +1 -0
- package/lib/documents/markdown/directives.js +135 -0
- package/lib/documents/markdown/directives.js.map +1 -0
- package/lib/documents/markdown/frontmatter.js +35 -0
- package/lib/documents/markdown/frontmatter.js.map +1 -0
- package/lib/documents/markdown/normalize.js +113 -0
- package/lib/documents/markdown/normalize.js.map +1 -0
- package/lib/documents/orchestrator/assets.js +243 -0
- package/lib/documents/orchestrator/assets.js.map +1 -0
- package/lib/documents/orchestrator/convert-document.js +186 -0
- package/lib/documents/orchestrator/convert-document.js.map +1 -0
- package/lib/documents/orchestrator/create-document.js +292 -0
- package/lib/documents/orchestrator/create-document.js.map +1 -0
- package/lib/documents/orchestrator/extract-document.js +162 -0
- package/lib/documents/orchestrator/extract-document.js.map +1 -0
- package/lib/documents/orchestrator/inspect-document.js +89 -0
- package/lib/documents/orchestrator/inspect-document.js.map +1 -0
- package/lib/documents/orchestrator/runtime-deps.js +59 -0
- package/lib/documents/orchestrator/runtime-deps.js.map +1 -0
- package/lib/documents/orchestrator/scope.js +132 -0
- package/lib/documents/orchestrator/scope.js.map +1 -0
- package/lib/documents/providers/docling.js +247 -0
- package/lib/documents/providers/docling.js.map +1 -0
- package/lib/documents/providers/libreoffice.js +130 -0
- package/lib/documents/providers/libreoffice.js.map +1 -0
- package/lib/documents/providers/markitdown.js +89 -0
- package/lib/documents/providers/markitdown.js.map +1 -0
- package/lib/documents/providers/pandoc.js +161 -0
- package/lib/documents/providers/pandoc.js.map +1 -0
- package/lib/documents/providers/process.js +164 -0
- package/lib/documents/providers/process.js.map +1 -0
- package/lib/documents/providers/registry.js +152 -0
- package/lib/documents/providers/registry.js.map +1 -0
- package/lib/documents/providers/shared.js +75 -0
- package/lib/documents/providers/shared.js.map +1 -0
- package/lib/documents/runtime.js +114 -0
- package/lib/documents/runtime.js.map +1 -0
- package/lib/documents/security/file-types.js +188 -0
- package/lib/documents/security/file-types.js.map +1 -0
- package/lib/documents/security/limits.js +78 -0
- package/lib/documents/security/limits.js.map +1 -0
- package/lib/documents/security/mime.js +43 -0
- package/lib/documents/security/mime.js.map +1 -0
- package/lib/documents/security/paths.js +133 -0
- package/lib/documents/security/paths.js.map +1 -0
- package/lib/documents/templates/registry.js +147 -0
- package/lib/documents/templates/registry.js.map +1 -0
- package/lib/documents/templates/resolver.js +59 -0
- package/lib/documents/templates/resolver.js.map +1 -0
- package/lib/documents/tools/convert.js +125 -0
- package/lib/documents/tools/convert.js.map +1 -0
- package/lib/documents/tools/create.js +187 -0
- package/lib/documents/tools/create.js.map +1 -0
- package/lib/documents/tools/index.js +41 -0
- package/lib/documents/tools/index.js.map +1 -0
- package/lib/documents/tools/inspect.js +135 -0
- package/lib/documents/tools/inspect.js.map +1 -0
- package/lib/documents/tools/shared.js +88 -0
- package/lib/documents/tools/shared.js.map +1 -0
- package/lib/documents/tools/to-markdown.js +125 -0
- package/lib/documents/tools/to-markdown.js.map +1 -0
- package/lib/documents/types.js +12 -0
- package/lib/documents/types.js.map +1 -0
- package/lib/index.js +225 -20
- package/lib/index.js.map +1 -1
- package/lib/integration-principals.js +22 -0
- package/lib/integration-principals.js.map +1 -0
- package/lib/lockdown-policy.js +15 -3
- package/lib/lockdown-policy.js.map +1 -1
- package/lib/personal-skills/errors.js +9 -0
- package/lib/personal-skills/errors.js.map +1 -0
- package/lib/personal-skills/host.js +80 -0
- package/lib/personal-skills/host.js.map +1 -0
- package/lib/personal-skills/index.js +10 -0
- package/lib/personal-skills/index.js.map +1 -0
- package/lib/personal-skills/paths.js +127 -0
- package/lib/personal-skills/paths.js.map +1 -0
- package/lib/personal-skills/provider.js +109 -0
- package/lib/personal-skills/provider.js.map +1 -0
- package/lib/personal-skills/remotes.js +40 -0
- package/lib/personal-skills/remotes.js.map +1 -0
- package/lib/personal-skills/service.js +686 -0
- package/lib/personal-skills/service.js.map +1 -0
- package/lib/personal-skills/skill-file.js +278 -0
- package/lib/personal-skills/skill-file.js.map +1 -0
- package/lib/personal-skills/skill-format.js +202 -0
- package/lib/personal-skills/skill-format.js.map +1 -0
- package/lib/personal-skills/watcher.js +96 -0
- package/lib/personal-skills/watcher.js.map +1 -0
- package/lib/profile.js +6 -4
- package/lib/profile.js.map +1 -1
- package/lib/prompt-notes.js +19 -0
- package/lib/prompt-notes.js.map +1 -1
- package/lib/provenance/file-preview.js +68 -21
- package/lib/provenance/file-preview.js.map +1 -1
- package/lib/provenance/host-store.js +44 -11
- package/lib/provenance/host-store.js.map +1 -1
- package/lib/provenance/index.js +1 -0
- package/lib/provenance/index.js.map +1 -1
- package/lib/provenance/normalize.js +3 -1
- package/lib/provenance/normalize.js.map +1 -1
- package/lib/provenance/snapshot-store.js +154 -0
- package/lib/provenance/snapshot-store.js.map +1 -0
- package/lib/qa-tools/activation-detector.js +53 -0
- package/lib/qa-tools/activation-detector.js.map +1 -0
- package/lib/qa-tools/activation-manager.js +111 -0
- package/lib/qa-tools/activation-manager.js.map +1 -0
- package/lib/qa-tools/catalog.js +108 -0
- package/lib/qa-tools/catalog.js.map +1 -0
- package/lib/qa-tools/durable-marker.js +115 -0
- package/lib/qa-tools/durable-marker.js.map +1 -0
- package/lib/qa-tools/index.js +83 -0
- package/lib/qa-tools/index.js.map +1 -0
- package/lib/qa-tools/lifecycle.js +64 -0
- package/lib/qa-tools/lifecycle.js.map +1 -0
- package/lib/qa-tools/types.js +2 -0
- package/lib/qa-tools/types.js.map +1 -0
- package/lib/resolve-config.js +5 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +35 -3
- package/lib/secure-session.js.map +1 -1
- package/lib/starters.js +117 -0
- package/lib/starters.js.map +1 -0
- package/lib/typert.host.js +767 -22
- package/lib/typert.remote-client.d.ts +17 -1
- package/lib/typert.remote-client.js +609 -17
- package/lib/types/account-remotes.d.ts +3 -1
- package/lib/types/accounts/errors.d.ts +1 -1
- package/lib/types/accounts/file.d.ts +10 -0
- package/lib/types/accounts/store.d.ts +7 -1
- package/lib/types/client/QaAccountsController.d.ts +7 -1
- package/lib/types/client/QaSessionController.d.ts +12 -0
- package/lib/types/client/QaSurface.d.ts +14 -4
- package/lib/types/client/QaSurfaceGuard.d.ts +27 -0
- package/lib/types/client/QaTranscriptAdapter.d.ts +7 -0
- package/lib/types/client/components/QaComposer.d.ts +3 -1
- package/lib/types/client/components/QaHeader.d.ts +3 -1
- package/lib/types/client/components/QaModal.d.ts +5 -4
- package/lib/types/client/components/QaSidebar.d.ts +8 -11
- package/lib/types/client/components/QaWidthHandle.d.ts +13 -0
- package/lib/types/client/index.d.ts +1 -0
- package/lib/types/client/panels/PanelHost.d.ts +18 -0
- package/lib/types/client/panels/PanelLauncher.d.ts +5 -0
- package/lib/types/client/panels/contract.d.ts +83 -0
- package/lib/types/client/panels/index.d.ts +3 -0
- package/lib/types/client/panels/registry.d.ts +40 -0
- package/lib/types/client/project-session-state.d.ts +5 -0
- package/lib/types/client/settings/sections/documents.d.ts +13 -0
- package/lib/types/client/settings/sections.d.ts +1 -0
- package/lib/types/client/settings-extensions/contract.d.ts +32 -0
- package/lib/types/client/settings-extensions/index.d.ts +3 -0
- package/lib/types/client/settings-extensions/registry.d.ts +15 -0
- package/lib/types/client/settlement.d.ts +41 -5
- package/lib/types/client/source-preview.d.ts +8 -0
- package/lib/types/client/styles.d.ts +2 -0
- package/lib/types/client/subagent-codenames.d.ts +18 -0
- package/lib/types/client/types.d.ts +35 -3
- package/lib/types/client/user-settings/GeneralSettingsPage.d.ts +14 -0
- package/lib/types/client/user-settings/ProfileSettingsPage.d.ts +18 -0
- package/lib/types/client/user-settings/SkillCatalog.d.ts +16 -0
- package/lib/types/client/user-settings/SkillEditor.d.ts +42 -0
- package/lib/types/client/user-settings/SkillToolPicker.d.ts +17 -0
- package/lib/types/client/user-settings/SkillsSettingsPage.d.ts +15 -0
- package/lib/types/client/user-settings/StartersSettingsPage.d.ts +14 -0
- package/lib/types/client/user-settings/UserSettingsDialog.d.ts +43 -0
- package/lib/types/client/user-settings/copy.d.ts +25 -0
- package/lib/types/client/user-settings/draft.d.ts +51 -0
- package/lib/types/client/user-settings/fields.d.ts +43 -0
- package/lib/types/config-resolvers/tools.d.ts +6 -0
- package/lib/types/documents/artifacts/ids.d.ts +14 -0
- package/lib/types/documents/artifacts/manifest.d.ts +32 -0
- package/lib/types/documents/artifacts/store.d.ts +67 -0
- package/lib/types/documents/capabilities.d.ts +32 -0
- package/lib/types/documents/config.d.ts +27 -0
- package/lib/types/documents/defaults.d.ts +161 -0
- package/lib/types/documents/errors.d.ts +42 -0
- package/lib/types/documents/index.d.ts +63 -0
- package/lib/types/documents/inspect/facts.d.ts +43 -0
- package/lib/types/documents/inspect/zip.d.ts +28 -0
- package/lib/types/documents/markdown/directives.d.ts +39 -0
- package/lib/types/documents/markdown/frontmatter.d.ts +15 -0
- package/lib/types/documents/markdown/normalize.d.ts +30 -0
- package/lib/types/documents/orchestrator/assets.d.ts +55 -0
- package/lib/types/documents/orchestrator/convert-document.d.ts +25 -0
- package/lib/types/documents/orchestrator/create-document.d.ts +18 -0
- package/lib/types/documents/orchestrator/extract-document.d.ts +24 -0
- package/lib/types/documents/orchestrator/inspect-document.d.ts +12 -0
- package/lib/types/documents/orchestrator/runtime-deps.d.ts +43 -0
- package/lib/types/documents/orchestrator/scope.d.ts +52 -0
- package/lib/types/documents/providers/docling.d.ts +54 -0
- package/lib/types/documents/providers/libreoffice.d.ts +40 -0
- package/lib/types/documents/providers/markitdown.d.ts +28 -0
- package/lib/types/documents/providers/pandoc.d.ts +42 -0
- package/lib/types/documents/providers/process.d.ts +54 -0
- package/lib/types/documents/providers/registry.d.ts +68 -0
- package/lib/types/documents/providers/shared.d.ts +27 -0
- package/lib/types/documents/runtime.d.ts +59 -0
- package/lib/types/documents/security/file-types.d.ts +39 -0
- package/lib/types/documents/security/limits.d.ts +24 -0
- package/lib/types/documents/security/mime.d.ts +13 -0
- package/lib/types/documents/security/paths.d.ts +38 -0
- package/lib/types/documents/templates/registry.d.ts +50 -0
- package/lib/types/documents/templates/resolver.d.ts +30 -0
- package/lib/types/documents/tools/convert.d.ts +9 -0
- package/lib/types/documents/tools/create.d.ts +14 -0
- package/lib/types/documents/tools/index.d.ts +33 -0
- package/lib/types/documents/tools/inspect.d.ts +9 -0
- package/lib/types/documents/tools/shared.d.ts +77 -0
- package/lib/types/documents/tools/to-markdown.d.ts +12 -0
- package/lib/types/documents/types.d.ts +294 -0
- package/lib/types/index.d.ts +75 -3
- package/lib/types/integration-principals.d.ts +9 -0
- package/lib/types/lockdown-policy.d.ts +12 -2
- package/lib/types/personal-skills/errors.d.ts +11 -0
- package/lib/types/personal-skills/host.d.ts +42 -0
- package/lib/types/personal-skills/index.d.ts +10 -0
- package/lib/types/personal-skills/paths.d.ts +39 -0
- package/lib/types/personal-skills/provider.d.ts +33 -0
- package/lib/types/personal-skills/remotes.d.ts +35 -0
- package/lib/types/personal-skills/service.d.ts +131 -0
- package/lib/types/personal-skills/skill-file.d.ts +64 -0
- package/lib/types/personal-skills/skill-format.d.ts +100 -0
- package/lib/types/personal-skills/watcher.d.ts +39 -0
- package/lib/types/profile.d.ts +13 -0
- package/lib/types/prompt-notes.d.ts +9 -0
- package/lib/types/provenance/file-preview.d.ts +47 -4
- package/lib/types/provenance/host-store.d.ts +7 -1
- package/lib/types/provenance/index.d.ts +1 -0
- package/lib/types/provenance/snapshot-store.d.ts +23 -0
- package/lib/types/qa-tools/activation-detector.d.ts +29 -0
- package/lib/types/qa-tools/activation-manager.d.ts +47 -0
- package/lib/types/qa-tools/catalog.d.ts +40 -0
- package/lib/types/qa-tools/durable-marker.d.ts +16 -0
- package/lib/types/qa-tools/index.d.ts +40 -0
- package/lib/types/qa-tools/lifecycle.d.ts +44 -0
- package/lib/types/qa-tools/types.d.ts +45 -0
- package/lib/types/secure-session.d.ts +24 -2
- package/lib/types/starters.d.ts +45 -0
- package/lib/types/types.d.ts +202 -3
- package/package.json +24 -11
- package/scripts/repair-session-events.mjs +260 -0
- package/lib/client/components/QaProfile.js +0 -64
- package/lib/client/components/QaProfile.js.map +0 -1
- package/lib/types/client/components/QaProfile.d.ts +0 -25
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controlled document directives (§36).
|
|
3
|
+
*
|
|
4
|
+
* Markdown stays the canonical source, so the few structures Markdown cannot
|
|
5
|
+
* express — a page break, a callout — are written as fences the orchestrator
|
|
6
|
+
* rewrites into the target backend's own representation before the renderer
|
|
7
|
+
* sees the text:
|
|
8
|
+
*
|
|
9
|
+
* ```md
|
|
10
|
+
* :::pagebreak
|
|
11
|
+
* :::
|
|
12
|
+
*
|
|
13
|
+
* :::note
|
|
14
|
+
* Important information.
|
|
15
|
+
* :::
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Anything else is refused rather than passed through: an unknown `:::`
|
|
19
|
+
* directive would otherwise reach pandoc as literal text, and raw markup
|
|
20
|
+
* (HTML, LaTeX, Typst escapes) is only accepted when a deployment explicitly
|
|
21
|
+
* opts in with `documents.create.allowRawMarkup`.
|
|
22
|
+
*/
|
|
23
|
+
import { DocumentError } from "../errors.js";
|
|
24
|
+
const DIRECTIVE_OPEN = /^[ \t]*:::[ \t]*([A-Za-z][A-Za-z0-9_-]*)[ \t]*$/u;
|
|
25
|
+
const DIRECTIVE_CLOSE = /^[ \t]*:::[ \t]*$/u;
|
|
26
|
+
const KNOWN_DIRECTIVES = new Set(["pagebreak", "note", "warning", "info"]);
|
|
27
|
+
const PAGEBREAK_OPENXML = '```{=openxml}\n<w:p><w:r><w:br w:type="page"/></w:r></w:p>\n```';
|
|
28
|
+
const RAW_MARKUP_PATTERNS = [
|
|
29
|
+
{
|
|
30
|
+
pattern: /<\s*(?:script|style|iframe|object|embed|applet|form|link|meta|base)\b/iu,
|
|
31
|
+
label: "HTML element",
|
|
32
|
+
},
|
|
33
|
+
{ pattern: /<\?|<!ENTITY/iu, label: "processing instruction" },
|
|
34
|
+
{
|
|
35
|
+
pattern: /\\(?:input|include|write18|directlua|usepackage)\s*[{[]/iu,
|
|
36
|
+
label: "LaTeX command",
|
|
37
|
+
},
|
|
38
|
+
{ pattern: /#(?:import|include|read)\s*[( "]/iu, label: "Typst command" },
|
|
39
|
+
{ pattern: /\{\{|\{%/u, label: "template placeholder" },
|
|
40
|
+
];
|
|
41
|
+
function assertNoRawMarkup(markdown, allowRawMarkup) {
|
|
42
|
+
if (allowRawMarkup)
|
|
43
|
+
return;
|
|
44
|
+
for (const { pattern, label } of RAW_MARKUP_PATTERNS) {
|
|
45
|
+
if (pattern.test(markdown)) {
|
|
46
|
+
throw new DocumentError("INVALID_INPUT", `the content carries raw markup (${label}); raw markup is disabled in this deployment`, { details: { kind: label } });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function renderPageBreak(backend) {
|
|
51
|
+
if (backend === "typst")
|
|
52
|
+
return "#pagebreak()";
|
|
53
|
+
// Pandoc's openxml raw block is understood for DOCX output; for the PDF path
|
|
54
|
+
// the document is rendered through DOCX first, so the same spelling applies.
|
|
55
|
+
return PAGEBREAK_OPENXML;
|
|
56
|
+
}
|
|
57
|
+
function renderNote(kind, body, backend) {
|
|
58
|
+
const label = kind === "note" ? "Note" : kind === "warning" ? "Warning" : "Info";
|
|
59
|
+
const text = body.trim();
|
|
60
|
+
const header = backend === "typst" ? `*${label}.* ` : `> **${label}.** `;
|
|
61
|
+
if (text === "")
|
|
62
|
+
return header.trimEnd();
|
|
63
|
+
if (backend === "typst") {
|
|
64
|
+
return header + text.replace(/\n{2,}/gu, "\n\n");
|
|
65
|
+
}
|
|
66
|
+
return header + text.split(/\r?\n/u).join("\n> ");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Rewrite directives for one backend. Line-oriented on purpose: a fence that
|
|
70
|
+
* appears inside a code block is content, not a directive.
|
|
71
|
+
*/
|
|
72
|
+
export function applyDirectives(markdown, options) {
|
|
73
|
+
assertNoRawMarkup(markdown, options.allowRawMarkup);
|
|
74
|
+
const lines = markdown.split(/\r?\n/u);
|
|
75
|
+
const output = [];
|
|
76
|
+
let index = 0;
|
|
77
|
+
while (index < lines.length) {
|
|
78
|
+
const line = lines[index] ?? "";
|
|
79
|
+
const fence = /^[ \t]*(`{3,}|~{3,})/u.exec(line);
|
|
80
|
+
if (fence !== null) {
|
|
81
|
+
const marker = fence[1] ?? "```";
|
|
82
|
+
output.push(line);
|
|
83
|
+
index += 1;
|
|
84
|
+
while (index < lines.length) {
|
|
85
|
+
const inner = lines[index] ?? "";
|
|
86
|
+
output.push(inner);
|
|
87
|
+
index += 1;
|
|
88
|
+
if (inner.trimStart().startsWith(marker))
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const directive = DIRECTIVE_OPEN.exec(line);
|
|
94
|
+
if (directive === null) {
|
|
95
|
+
output.push(line);
|
|
96
|
+
index += 1;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const rawName = (directive[1] ?? "").toLowerCase();
|
|
100
|
+
const directiveName = rawName === "page-break" ? "pagebreak" : rawName;
|
|
101
|
+
const openedAt = index + 1;
|
|
102
|
+
if (!KNOWN_DIRECTIVES.has(directiveName)) {
|
|
103
|
+
throw new DocumentError("INVALID_INPUT", `unsupported document directive ":::${rawName}" (supported: pagebreak, note, warning, info)`, { details: { directive: rawName, line: openedAt } });
|
|
104
|
+
}
|
|
105
|
+
index += 1;
|
|
106
|
+
const body = [];
|
|
107
|
+
let closed = false;
|
|
108
|
+
while (index < lines.length) {
|
|
109
|
+
const inner = lines[index] ?? "";
|
|
110
|
+
if (DIRECTIVE_CLOSE.test(inner)) {
|
|
111
|
+
closed = true;
|
|
112
|
+
index += 1;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
if (DIRECTIVE_OPEN.test(inner)) {
|
|
116
|
+
throw new DocumentError("INVALID_INPUT", `document directive ":::${directiveName}" on line ${openedAt} contains a nested directive`, { details: { directive: directiveName, line: openedAt } });
|
|
117
|
+
}
|
|
118
|
+
body.push(inner);
|
|
119
|
+
index += 1;
|
|
120
|
+
}
|
|
121
|
+
if (directiveName === "pagebreak") {
|
|
122
|
+
if (body.some((entry) => entry.trim() !== "")) {
|
|
123
|
+
throw new DocumentError("INVALID_INPUT", `":::pagebreak" on line ${openedAt} takes no body`, { details: { directive: directiveName, line: openedAt } });
|
|
124
|
+
}
|
|
125
|
+
output.push(renderPageBreak(options.backend));
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (!closed) {
|
|
129
|
+
throw new DocumentError("INVALID_INPUT", `document directive ":::${directiveName}" opened on line ${openedAt} is never closed`, { details: { directive: directiveName, line: openedAt } });
|
|
130
|
+
}
|
|
131
|
+
output.push(renderNote(directiveName, body.join("\n"), options.backend));
|
|
132
|
+
}
|
|
133
|
+
return { markdown: output.join("\n"), warnings: [] };
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=directives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directives.js","sourceRoot":"","sources":["../../../src/documents/markdown/directives.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Front-matter handling (§35).
|
|
3
|
+
*
|
|
4
|
+
* A generated document may carry a leading `---` block with scalar metadata.
|
|
5
|
+
* Only scalars are read: the block feeds document properties and the manifest,
|
|
6
|
+
* never a nested configuration surface, so there is nothing here an author
|
|
7
|
+
* could use to reach a backend option.
|
|
8
|
+
*/
|
|
9
|
+
const FRONT_MATTER_PATTERN = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?:\r?\n|$)/u;
|
|
10
|
+
function unquote(value) {
|
|
11
|
+
const trimmed = value.trim();
|
|
12
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length >= 2) ||
|
|
13
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'") && trimmed.length >= 2)) {
|
|
14
|
+
return trimmed.slice(1, -1);
|
|
15
|
+
}
|
|
16
|
+
return trimmed;
|
|
17
|
+
}
|
|
18
|
+
/** Split leading front matter from the body. Malformed lines are ignored. */
|
|
19
|
+
export function parseFrontMatter(markdown) {
|
|
20
|
+
const match = FRONT_MATTER_PATTERN.exec(markdown);
|
|
21
|
+
if (match === null)
|
|
22
|
+
return { attributes: {}, body: markdown };
|
|
23
|
+
const attributes = {};
|
|
24
|
+
for (const line of (match[1] ?? "").split(/\r?\n/u)) {
|
|
25
|
+
const separator = line.indexOf(":");
|
|
26
|
+
if (separator <= 0)
|
|
27
|
+
continue;
|
|
28
|
+
const key = line.slice(0, separator).trim().toLowerCase();
|
|
29
|
+
if (key === "" || key.startsWith("-"))
|
|
30
|
+
continue;
|
|
31
|
+
attributes[key] = unquote(line.slice(separator + 1));
|
|
32
|
+
}
|
|
33
|
+
return { attributes, body: markdown.slice(match[0].length) };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/documents/markdown/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,oBAAoB,GACxB,4DAA4D,CAAC;AAE/D,SAAS,OAAO,CAAC,KAAa;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;QACzE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,EACzE,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9D,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,IAAI,CAAC;YAAE,SAAS;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC1D,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAChD,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown normalization for extracted documents (§16).
|
|
3
|
+
*
|
|
4
|
+
* The layer is deliberately conservative: it removes artifacts a converter
|
|
5
|
+
* reliably produces (platform line endings, non-breaking spaces, page-number
|
|
6
|
+
* lines, a running head repeated on every page) and never touches meaning.
|
|
7
|
+
* Guessing missing content is explicitly out of scope, and an LLM pass is not
|
|
8
|
+
* part of this stage at all — a document is never sent to a model to make its
|
|
9
|
+
* Markdown nicer.
|
|
10
|
+
*/
|
|
11
|
+
const PAGE_NUMBER_LINE = /^[ \t]*(?:[-–—|]\s*)?(?:page|стр\.?|страница)?\s*\d{1,4}\s*(?:[-–—|])?[ \t]*$/iu;
|
|
12
|
+
const BULLET_SUBSTITUTES = /^([ \t]*)[•▪◦‣·]([ \t]+)/u;
|
|
13
|
+
const RUNNING_HEAD_MAX_CHARS = 80;
|
|
14
|
+
const RUNNING_HEAD_MIN_REPEATS = 3;
|
|
15
|
+
function collapseBlankRuns(lines) {
|
|
16
|
+
const output = [];
|
|
17
|
+
let blanks = 0;
|
|
18
|
+
for (const line of lines) {
|
|
19
|
+
if (line.trim() === "") {
|
|
20
|
+
blanks += 1;
|
|
21
|
+
if (blanks > 1)
|
|
22
|
+
continue;
|
|
23
|
+
output.push("");
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
blanks = 0;
|
|
27
|
+
output.push(line);
|
|
28
|
+
}
|
|
29
|
+
while (output.length > 0 && output[output.length - 1] === "")
|
|
30
|
+
output.pop();
|
|
31
|
+
return output;
|
|
32
|
+
}
|
|
33
|
+
function stripRunningHeads(lines) {
|
|
34
|
+
const counts = new Map();
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
if (trimmed === "" || trimmed.length > RUNNING_HEAD_MAX_CHARS)
|
|
38
|
+
continue;
|
|
39
|
+
if (trimmed.startsWith("#") ||
|
|
40
|
+
trimmed.startsWith("|") ||
|
|
41
|
+
trimmed.startsWith(">"))
|
|
42
|
+
continue;
|
|
43
|
+
counts.set(trimmed, (counts.get(trimmed) ?? 0) + 1);
|
|
44
|
+
}
|
|
45
|
+
const repeated = new Set([...counts.entries()]
|
|
46
|
+
.filter(([, count]) => count >= RUNNING_HEAD_MIN_REPEATS)
|
|
47
|
+
.map(([line]) => line));
|
|
48
|
+
if (repeated.size === 0)
|
|
49
|
+
return [...lines];
|
|
50
|
+
return lines.filter((line) => {
|
|
51
|
+
const trimmed = line.trim();
|
|
52
|
+
if (trimmed === "" || trimmed.length > RUNNING_HEAD_MAX_CHARS)
|
|
53
|
+
return true;
|
|
54
|
+
return !repeated.has(trimmed);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** Normalize extracted Markdown; returns the text and what was changed. */
|
|
58
|
+
export function normalizeExtractedMarkdown(markdown, options = {}) {
|
|
59
|
+
const warnings = [];
|
|
60
|
+
let text = markdown
|
|
61
|
+
.replace(/^\uFEFF/u, "")
|
|
62
|
+
.replace(/\r\n?/gu, "\n")
|
|
63
|
+
.replace(/\u00A0/gu, " ")
|
|
64
|
+
.replace(/[\u200B-\u200D\u2060]/gu, "");
|
|
65
|
+
const rawLines = text.split("\n");
|
|
66
|
+
let lines = rawLines.map((line) => line.replace(/\s+$/u, ""));
|
|
67
|
+
const bulletFix = lines.map((line) => line.replace(BULLET_SUBSTITUTES, "$1- "));
|
|
68
|
+
if (bulletFix.some((line, index) => line !== lines[index])) {
|
|
69
|
+
lines = bulletFix;
|
|
70
|
+
}
|
|
71
|
+
const beforeHeadStrip = lines.length;
|
|
72
|
+
if (options.stripRunningHeads ?? true) {
|
|
73
|
+
lines = stripRunningHeads(lines);
|
|
74
|
+
if (lines.length < beforeHeadStrip) {
|
|
75
|
+
warnings.push({
|
|
76
|
+
code: "TABLE_EXTRACTION_DEGRADED",
|
|
77
|
+
message: "lines repeated across pages were removed as running heads or footers",
|
|
78
|
+
details: { removed: beforeHeadStrip - lines.length },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (options.stripPageNumbers ?? true) {
|
|
83
|
+
const filtered = lines.filter((line, index) => !(PAGE_NUMBER_LINE.test(line) &&
|
|
84
|
+
(lines[index - 1] ?? "").trim() === "" &&
|
|
85
|
+
(lines[index + 1] ?? "").trim() === ""));
|
|
86
|
+
if (filtered.length < lines.length) {
|
|
87
|
+
warnings.push({
|
|
88
|
+
code: "TABLE_EXTRACTION_DEGRADED",
|
|
89
|
+
message: "standalone page-number lines were removed",
|
|
90
|
+
details: { removed: lines.length - filtered.length },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
lines = filtered;
|
|
94
|
+
}
|
|
95
|
+
lines = collapseBlankRuns(lines);
|
|
96
|
+
text = `${lines.join("\n")}\n`;
|
|
97
|
+
return { markdown: text, warnings };
|
|
98
|
+
}
|
|
99
|
+
/** Count Markdown structure for `document_inspect` on Markdown inputs. */
|
|
100
|
+
export function markdownStructure(markdown) {
|
|
101
|
+
const headings = markdown
|
|
102
|
+
.split("\n")
|
|
103
|
+
.filter((line) => /^#{1,6}\s+\S/u.test(line)).length;
|
|
104
|
+
return {
|
|
105
|
+
headings,
|
|
106
|
+
images: (markdown.match(/!\[[^\]]*\]\([^)]*\)/gu) ?? []).length,
|
|
107
|
+
tables: markdown
|
|
108
|
+
.split(/\n{2,}/u)
|
|
109
|
+
.filter((block) => /^\|.*\|$/mu.test(block) && /\|\s*-{2,}/u.test(block))
|
|
110
|
+
.length,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/documents/markdown/normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset preparation and reference auditing (§17.1).
|
|
3
|
+
*
|
|
4
|
+
* Assets reach a document two ways: the caller names a file in the workspace,
|
|
5
|
+
* or it inlines bytes as a data URI. Both are copied into the bundle's
|
|
6
|
+
* `assets/` directory under a name the pipeline chooses, so the rendered
|
|
7
|
+
* document never depends on a path outside the artifact, and the Markdown
|
|
8
|
+
* references are rewritten to match.
|
|
9
|
+
*
|
|
10
|
+
* Before a renderer runs, every image reference in the source is accounted
|
|
11
|
+
* for: a missing local file, a reference that leaves the assets directory, or
|
|
12
|
+
* a remote URL (which the renderer would fetch from the network) is an error,
|
|
13
|
+
* not a silent drop.
|
|
14
|
+
*/
|
|
15
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { DocumentError, asDocumentError } from "../errors.js";
|
|
18
|
+
import { assertBytesWithinBudget } from "../security/limits.js";
|
|
19
|
+
import { assertRelativeAssetReference, resolveInsideRoot, sanitizeFilename, } from "../security/paths.js";
|
|
20
|
+
import { describeBytes, isAllowedAssetMimeType, mimeTypeForFilename, mimeTypeOfBytes, } from "../security/file-types.js";
|
|
21
|
+
import { allowedInputRoots } from "./scope.js";
|
|
22
|
+
const DATA_URI = /^data:([A-Za-z0-9.+/-]+);base64,([\s\S]*)$/u;
|
|
23
|
+
const EXTENSION_BY_MIME = {
|
|
24
|
+
"image/png": "png",
|
|
25
|
+
"image/jpeg": "jpg",
|
|
26
|
+
"image/gif": "gif",
|
|
27
|
+
"image/webp": "webp",
|
|
28
|
+
"image/bmp": "bmp",
|
|
29
|
+
"image/tiff": "tif",
|
|
30
|
+
};
|
|
31
|
+
function extensionFor(mediaType, fallbackName) {
|
|
32
|
+
const mapped = EXTENSION_BY_MIME[mediaType];
|
|
33
|
+
if (mapped !== undefined)
|
|
34
|
+
return mapped;
|
|
35
|
+
const fromName = fallbackName === undefined ? undefined : path.extname(fallbackName);
|
|
36
|
+
return fromName === undefined || fromName === "" ? "bin" : fromName.slice(1);
|
|
37
|
+
}
|
|
38
|
+
function decodeBase64(payload, id) {
|
|
39
|
+
const compact = payload.replace(/\s+/gu, "");
|
|
40
|
+
try {
|
|
41
|
+
const buffer = Buffer.from(compact, "base64");
|
|
42
|
+
if (buffer.length === 0)
|
|
43
|
+
throw new Error("empty payload");
|
|
44
|
+
return buffer;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" is not valid base64`, {
|
|
48
|
+
cause: error,
|
|
49
|
+
details: { asset: id },
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function prepareAssets(assets, options) {
|
|
54
|
+
if (assets === undefined || assets.length === 0) {
|
|
55
|
+
return { assets: [], warnings: [] };
|
|
56
|
+
}
|
|
57
|
+
await mkdir(options.assetsDir, { recursive: true });
|
|
58
|
+
const seenIds = new Set();
|
|
59
|
+
const prepared = [];
|
|
60
|
+
const warnings = [];
|
|
61
|
+
const maxBytes = options.config.limits.maxAssetBytes;
|
|
62
|
+
for (const asset of assets) {
|
|
63
|
+
const id = asset.id?.trim() ?? "";
|
|
64
|
+
if (id === "") {
|
|
65
|
+
throw new DocumentError("INVALID_ASSET", "every asset needs a non-empty id");
|
|
66
|
+
}
|
|
67
|
+
if (seenIds.has(id)) {
|
|
68
|
+
throw new DocumentError("INVALID_ASSET", `asset id "${id}" is used twice`, {
|
|
69
|
+
details: { asset: id },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
seenIds.add(id);
|
|
73
|
+
if ((asset.path === undefined) === (asset.dataRef === undefined)) {
|
|
74
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" must carry exactly one of path or dataRef`, { details: { asset: id } });
|
|
75
|
+
}
|
|
76
|
+
let bytes;
|
|
77
|
+
let references = [];
|
|
78
|
+
if (asset.path !== undefined) {
|
|
79
|
+
const declared = asset.path.trim();
|
|
80
|
+
let resolved;
|
|
81
|
+
for (const root of allowedInputRoots(options.config, options.scope)) {
|
|
82
|
+
try {
|
|
83
|
+
resolved = await resolveInsideRoot(root, declared, `asset "${id}"`);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
if (error instanceof DocumentError &&
|
|
88
|
+
error.code === "PATH_NOT_ALLOWED")
|
|
89
|
+
continue;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (resolved === undefined) {
|
|
94
|
+
throw new DocumentError("PATH_NOT_ALLOWED", `asset "${id}" is outside the session workspace and configured document roots`, { details: { asset: id } });
|
|
95
|
+
}
|
|
96
|
+
const details = await stat(resolved).catch(() => undefined);
|
|
97
|
+
if (details === undefined || !details.isFile()) {
|
|
98
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" does not exist`, {
|
|
99
|
+
details: { asset: id },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
assertBytesWithinBudget(details.size, maxBytes, `asset "${id}"`);
|
|
103
|
+
bytes = await readFile(resolved).catch((error) => {
|
|
104
|
+
throw asDocumentError(error, "INVALID_ASSET", id);
|
|
105
|
+
});
|
|
106
|
+
// Both separators: a source authored on one platform may spell the path
|
|
107
|
+
// the other way, and the rewrite has to catch it either way.
|
|
108
|
+
references = [declared, resolved, resolved.replace(/\\/gu, "/")];
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const match = DATA_URI.exec((asset.dataRef ?? "").trim());
|
|
112
|
+
if (match === null) {
|
|
113
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" must be a base64 data URI`, { details: { asset: id } });
|
|
114
|
+
}
|
|
115
|
+
bytes = decodeBase64(match[2] ?? "", id);
|
|
116
|
+
assertBytesWithinBudget(bytes.length, maxBytes, `asset "${id}"`);
|
|
117
|
+
if (asset.mimeType === undefined) {
|
|
118
|
+
const declaredMime = match[1] ?? "";
|
|
119
|
+
if (declaredMime.startsWith("image/")) {
|
|
120
|
+
warnings.push({
|
|
121
|
+
code: "METADATA_PARTIALLY_EXTRACTED",
|
|
122
|
+
message: `asset "${id}" carries no mimeType; the data URI's type was used`,
|
|
123
|
+
details: { asset: id },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
assertBytesWithinBudget(bytes.length, maxBytes, `asset "${id}"`);
|
|
129
|
+
const declaredMime = asset.mimeType?.trim();
|
|
130
|
+
const dataUriMime = asset.dataRef === undefined
|
|
131
|
+
? undefined
|
|
132
|
+
: DATA_URI.exec(asset.dataRef.trim())?.[1];
|
|
133
|
+
const mediaType = (declaredMime === undefined || declaredMime === ""
|
|
134
|
+
? undefined
|
|
135
|
+
: declaredMime) ??
|
|
136
|
+
(dataUriMime === undefined || dataUriMime === ""
|
|
137
|
+
? undefined
|
|
138
|
+
: dataUriMime) ??
|
|
139
|
+
mimeTypeOfBytes(bytes) ??
|
|
140
|
+
(asset.filename === undefined
|
|
141
|
+
? undefined
|
|
142
|
+
: mimeTypeForFilename(asset.filename)) ??
|
|
143
|
+
"";
|
|
144
|
+
if (mediaType === "") {
|
|
145
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" has no recognizable media type`, { details: { asset: id, bytes: describeBytes(bytes) } });
|
|
146
|
+
}
|
|
147
|
+
if (!isAllowedAssetMimeType(mediaType, options.config.limits.allowedAssetMimeTypes)) {
|
|
148
|
+
throw new DocumentError("INVALID_ASSET", `asset "${id}" has media type ${mediaType}, which this deployment does not accept`, { details: { asset: id, mediaType } });
|
|
149
|
+
}
|
|
150
|
+
const fileName = sanitizeFilename(asset.filename ??
|
|
151
|
+
(asset.path === undefined ? id : path.basename(asset.path)), id, `.${extensionFor(mediaType, asset.filename)}`);
|
|
152
|
+
await writeFile(path.join(options.assetsDir, fileName), bytes);
|
|
153
|
+
// Two spellings reach the stored file: the declared path (rewritten to the
|
|
154
|
+
// stored name) and the asset id, so a source that references
|
|
155
|
+
// `assets/<id>.<ext>` lands on the same file as one that references the
|
|
156
|
+
// final name.
|
|
157
|
+
const idReference = `assets/${id}${path.extname(fileName)}`;
|
|
158
|
+
if (!references.includes(idReference))
|
|
159
|
+
references.push(idReference);
|
|
160
|
+
prepared.push({ id, fileName, mediaType, bytes: bytes.length, references });
|
|
161
|
+
}
|
|
162
|
+
return { assets: prepared, warnings };
|
|
163
|
+
}
|
|
164
|
+
const IMAGE_REFERENCE = /!\[[^\]]*\]\(\s*([^)\s]+)(?:\s+"[^"]*")?\s*\)/gu;
|
|
165
|
+
function normalizeReference(value) {
|
|
166
|
+
return value.trim().replace(/\\/gu, "/").replace(/^\.\//u, "");
|
|
167
|
+
}
|
|
168
|
+
/** Any spelling of a provided asset's location, mapped to its stored name. */
|
|
169
|
+
function referenceIndex(assets, roots) {
|
|
170
|
+
const index = new Map();
|
|
171
|
+
const remember = (raw, fileName) => {
|
|
172
|
+
const candidates = [normalizeReference(raw)];
|
|
173
|
+
for (const root of roots) {
|
|
174
|
+
candidates.push(normalizeReference(path.isAbsolute(raw) ? path.resolve(raw) : path.resolve(root, raw)));
|
|
175
|
+
}
|
|
176
|
+
for (const candidate of candidates) {
|
|
177
|
+
if (candidate !== "" && !index.has(candidate))
|
|
178
|
+
index.set(candidate, fileName);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
for (const asset of assets) {
|
|
182
|
+
for (const reference of asset.references)
|
|
183
|
+
remember(reference, asset.fileName);
|
|
184
|
+
}
|
|
185
|
+
return index;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Rewrite the image references that point at a provided asset to the bundle's
|
|
189
|
+
* own `assets/<name>`, keeping every other reference untouched. Matching is
|
|
190
|
+
* whole-reference (never a substring) and resolves relative spellings against
|
|
191
|
+
* the workspace, so an absolute path and a workspace-relative path to the same
|
|
192
|
+
* file both land on the same asset.
|
|
193
|
+
*/
|
|
194
|
+
export function rewriteAssetReferences(markdown, assets, options) {
|
|
195
|
+
if (assets.length === 0)
|
|
196
|
+
return markdown;
|
|
197
|
+
const index = referenceIndex(assets, options.roots);
|
|
198
|
+
return markdown.replace(IMAGE_REFERENCE, (full, reference) => {
|
|
199
|
+
const direct = index.get(normalizeReference(reference));
|
|
200
|
+
if (direct !== undefined)
|
|
201
|
+
return full.replace(reference, `assets/${direct}`);
|
|
202
|
+
for (const root of options.roots) {
|
|
203
|
+
const resolved = index.get(normalizeReference(path.resolve(root, reference)));
|
|
204
|
+
if (resolved !== undefined)
|
|
205
|
+
return full.replace(reference, `assets/${resolved}`);
|
|
206
|
+
}
|
|
207
|
+
return full;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Verify every image reference in the Markdown before a renderer can act on
|
|
212
|
+
* it: local files must exist inside the assets directory, and remote URLs are
|
|
213
|
+
* refused because the renderer would fetch them (§26.5).
|
|
214
|
+
*/
|
|
215
|
+
export async function auditAssetReferences(markdown, options) {
|
|
216
|
+
const warnings = [];
|
|
217
|
+
const prepared = new Set(options.assets.map((asset) => asset.fileName));
|
|
218
|
+
for (const match of markdown.matchAll(IMAGE_REFERENCE)) {
|
|
219
|
+
const rawReference = match[1] ?? "";
|
|
220
|
+
// A scheme with an authority is a remote fetch; an absolute path (which on
|
|
221
|
+
// Windows starts with a drive letter and therefore looks like a scheme) is
|
|
222
|
+
// not, and is caught by the containment check below.
|
|
223
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(rawReference) ||
|
|
224
|
+
rawReference.startsWith("//")) {
|
|
225
|
+
throw new DocumentError("INVALID_ASSET", `the source references the remote image "${rawReference}"; remote images are never fetched — add it through assets instead`, { details: { reference: rawReference } });
|
|
226
|
+
}
|
|
227
|
+
const reference = assertRelativeAssetReference(rawReference.replace(/^\.\//u, ""));
|
|
228
|
+
const fileName = path.basename(reference);
|
|
229
|
+
const target = path.resolve(options.assetsDir, reference);
|
|
230
|
+
const insideAssets = path.relative(options.assetsDir, target).split(path.sep)[0] !== "..";
|
|
231
|
+
if (!insideAssets) {
|
|
232
|
+
throw new DocumentError("INVALID_ASSET", `the source references "${rawReference}", which leaves the assets directory`, { details: { reference: rawReference } });
|
|
233
|
+
}
|
|
234
|
+
if (prepared.has(fileName))
|
|
235
|
+
continue;
|
|
236
|
+
const details = await stat(target).catch(() => undefined);
|
|
237
|
+
if (details?.isFile() === true)
|
|
238
|
+
continue;
|
|
239
|
+
throw new DocumentError("INVALID_ASSET", `the source references "${rawReference}", but no such asset was provided`, { details: { reference: rawReference } });
|
|
240
|
+
}
|
|
241
|
+
return warnings;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/documents/orchestrator/assets.ts"],"names":[],"mappings":"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"}
|