oh-my-opencode 5.1.47 → 5.1.51
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/dist/agents/refusal-rule.d.ts +7 -0
- package/dist/cli/index.js +1194 -752
- package/dist/cli/service-auth/accounts-gate.d.ts +11 -0
- package/dist/cli/service-auth/commands.d.ts +2 -4
- package/dist/cli/service-auth/index.d.ts +1 -1
- package/dist/cli/service-auth/keystore.d.ts +26 -2
- package/dist/cli/service-auth/protocol.d.ts +7 -1
- package/dist/cli/service-auth/session.d.ts +6 -0
- package/dist/cli/service-auth/signed-out-marker.d.ts +11 -0
- package/dist/cli-node/index.js +1194 -752
- package/dist/config/schema/hooks.d.ts +1 -0
- package/dist/create-hooks.d.ts +1 -0
- package/dist/features/boulder-state/storage.d.ts +1 -1
- package/dist/features/boulder-state/types.d.ts +1 -1
- package/dist/hooks/atlas/idle-continuation.d.ts +2 -1
- package/dist/hooks/atlas/types.d.ts +9 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/momus-review-persistence/hook.d.ts +19 -0
- package/dist/hooks/momus-review-persistence/index.d.ts +1 -0
- package/dist/hooks/momus-review-persistence/review-resolution.d.ts +20 -0
- package/dist/hooks/prometheus-md-only/constants.d.ts +2 -0
- package/dist/hooks/prometheus-md-only/fixtures/denial-log.d.ts +1 -0
- package/dist/hooks/prometheus-md-only/fixtures/guarded-hashline.d.ts +1 -0
- package/dist/hooks/prometheus-md-only/fixtures/invoke-before.d.ts +7 -0
- package/dist/hooks/prometheus-md-only/fixtures/opencode-patch-parser.d.ts +2 -0
- package/dist/hooks/prometheus-md-only/hook.d.ts +5 -1
- package/dist/hooks/prometheus-md-only/path-policy.d.ts +2 -9
- package/dist/hooks/prometheus-md-only/vendor/opencode-patch-parser.d.ts +22 -0
- package/dist/index.js +2322 -1045
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
- package/dist/shared/posthog-activity-state.d.ts +1 -0
- package/dist/shared/posthog.d.ts +1 -2
- package/dist/shared/resolve-file-write-path.d.ts +6 -0
- package/dist/skills/ast-grep/README.md +1 -1
- package/dist/skills/ast-grep/install.ps1 +5 -3
- package/dist/skills/ast-grep/install.sh +4 -5
- package/dist/skills/ast-grep/references/install.md +2 -2
- package/dist/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
- package/dist/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/dist/skills/coding-agent-sessions/SKILL.md +11 -11
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/dist/skills/coding-agent-sessions/references/codex.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/dist/skills/frontend/ATTRIBUTION.md +1 -1
- package/dist/skills/frontend/SKILL.md +34 -12
- package/dist/skills/frontend/references/design/README.md +2 -2
- package/dist/skills/frontend/references/design/_INDEX.md +2 -1
- package/dist/skills/frontend/references/design/component-catalogs.md +14 -10
- package/dist/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/dist/skills/frontend/references/design/grounding.md +29 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/dist/skills/ultimate-browsing/SKILL.md +5 -4
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/dist/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/dist/skills/ultimate-browsing/engine/summary.py +1 -1
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/dist/skills/ulw-research/AGENTS.md +8 -4
- package/dist/skills/ulw-research/SKILL.md +7 -259
- package/dist/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/dist/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/dist/skills/ulw-research/references/fact-ledger.md +42 -8
- package/dist/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/dist/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/dist/skills/ulw-research/references/report-gates.md +14 -6
- package/dist/skills/ulw-research/references/research-collection.md +195 -0
- package/dist/skills/ulw-research/references/research-delivery.md +123 -0
- package/dist/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/dist/skills/ulw-research/scripts/claim-kinds.test.ts +37 -2
- package/dist/skills/ulw-research/scripts/claim-prefix.test.ts +76 -0
- package/dist/skills/ulw-research/scripts/contracts-validation.test.ts +83 -0
- package/dist/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/dist/skills/ulw-research/scripts/contracts.test.ts +6 -109
- package/dist/skills/ulw-research/scripts/conversion-altered.test.ts +154 -0
- package/dist/skills/ulw-research/scripts/conversion-originals.test.ts +297 -0
- package/dist/skills/ulw-research/scripts/conversion-probe-classes.test.ts +361 -0
- package/dist/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/dist/skills/ulw-research/scripts/conversion-probe.test.ts +218 -0
- package/dist/skills/ulw-research/scripts/copy-returns-fidelity-policy.test.ts +156 -0
- package/dist/skills/ulw-research/scripts/copy-returns-polish.test.ts +10 -9
- package/dist/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/dist/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/dist/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
- package/dist/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
- package/dist/skills/ulw-research/scripts/entities.mjs +13 -4
- package/dist/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/dist/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/dist/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/dist/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/dist/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/dist/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
- package/dist/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/dist/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
- package/dist/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/dist/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/dist/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
- package/dist/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
- package/dist/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/dist/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
- package/dist/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
- package/dist/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
- package/dist/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/dist/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/dist/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/dist/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/dist/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/dist/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/dist/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/dist/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/dist/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/dist/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/dist/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/dist/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
- package/dist/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/dist/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
- package/dist/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/dist/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/dist/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/dist/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/dist/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
- package/dist/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/dist/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
- package/dist/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/dist/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/dist/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
- package/dist/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/dist/skills/ulw-research/scripts/numerals.test.ts +3 -0
- package/dist/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/dist/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
- package/dist/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/dist/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
- package/dist/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/dist/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/dist/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
- package/dist/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
- package/dist/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/dist/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/dist/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
- package/dist/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
- package/dist/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
- package/dist/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
- package/dist/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
- package/dist/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/dist/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/dist/skills/ulw-research/scripts/report-tools.test.ts +6 -560
- package/dist/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
- package/dist/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/dist/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
- package/dist/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/dist/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/dist/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
- package/dist/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/dist/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/dist/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
- package/dist/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
- package/dist/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
- package/dist/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
- package/dist/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
- package/dist/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
- package/dist/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
- package/dist/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
- package/dist/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
- package/dist/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
- package/dist/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
- package/dist/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
- package/dist/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
- package/dist/skills/ulw-research/scripts/units.mjs +14 -3
- package/dist/skills/ulw-research/scripts/units.test.ts +10 -0
- package/dist/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
- package/dist/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
- package/dist/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
- package/dist/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
- package/dist/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
- package/dist/tools/delegate-task/executor-types.d.ts +1 -0
- package/dist/tools/delegate-task/sync-session-existence.d.ts +4 -0
- package/dist/tools/delegate-task/types.d.ts +1 -0
- package/dist/tools/skill/description-formatter.d.ts +2 -1
- package/dist/tools/skill/types.d.ts +6 -0
- package/dist/tui.js +131 -33
- package/package.json +18 -15
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/SKILL.md +7 -7
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +2 -2
- package/packages/omo-codex/plugin/components/telemetry/README.md +2 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +52 -15
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +52 -19
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +2 -9
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -13
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +0 -2
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook-diagnostics.test.ts +0 -3
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +3 -8
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +3 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +16 -16
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/shared/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/README.md +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +5 -3
- package/packages/omo-codex/plugin/skills/ast-grep/install.sh +4 -5
- package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
- package/packages/omo-codex/plugin/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +11 -11
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +34 -12
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +2 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/component-catalogs.md +14 -10
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/packages/omo-codex/plugin/skills/frontend/references/design/grounding.md +29 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +7 -7
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +5 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +3 -0
- package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +8 -4
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +7 -259
- package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger.md +42 -8
- package/packages/omo-codex/plugin/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +14 -6
- package/packages/omo-codex/plugin/skills/ulw-research/references/research-collection.md +195 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/research-delivery.md +123 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/entities.mjs +13 -4
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/units.mjs +14 -3
- package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +6 -4
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +4 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +338 -237
- package/packages/prompts-core/prompts/ultrawork/codex.md +3 -0
- package/packages/shared-skills/skill-source-filter.mjs +6 -2
- package/packages/shared-skills/skills/ast-grep/README.md +1 -1
- package/packages/shared-skills/skills/ast-grep/install.ps1 +5 -3
- package/packages/shared-skills/skills/ast-grep/install.sh +4 -5
- package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
- package/packages/shared-skills/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +11 -11
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +1 -1
- package/packages/shared-skills/skills/frontend/SKILL.md +34 -12
- package/packages/shared-skills/skills/frontend/references/design/README.md +2 -2
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -1
- package/packages/shared-skills/skills/frontend/references/design/component-catalogs.md +14 -10
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/packages/shared-skills/skills/frontend/references/design/grounding.md +29 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +5 -4
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/packages/shared-skills/skills/ulw-research/AGENTS.md +8 -4
- package/packages/shared-skills/skills/ulw-research/SKILL.md +7 -259
- package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/packages/shared-skills/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/packages/shared-skills/skills/ulw-research/references/fact-ledger.md +42 -8
- package/packages/shared-skills/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/packages/shared-skills/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/packages/shared-skills/skills/ulw-research/references/report-gates.md +14 -6
- package/packages/shared-skills/skills/ulw-research/references/research-collection.md +195 -0
- package/packages/shared-skills/skills/ulw-research/references/research-delivery.md +123 -0
- package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.test.ts +37 -2
- package/packages/shared-skills/skills/ulw-research/scripts/claim-prefix.test.ts +76 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts-validation.test.ts +83 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +6 -109
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-altered.test.ts +154 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-originals.test.ts +297 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe-classes.test.ts +361 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.test.ts +218 -0
- package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-fidelity-policy.test.ts +156 -0
- package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-polish.test.ts +10 -9
- package/packages/shared-skills/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/packages/shared-skills/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
- package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
- package/packages/shared-skills/skills/ulw-research/scripts/entities.mjs +13 -4
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
- package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
- package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/packages/shared-skills/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
- package/packages/shared-skills/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/packages/shared-skills/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
- package/packages/shared-skills/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
- package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +3 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/packages/shared-skills/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
- package/packages/shared-skills/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/packages/shared-skills/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
- package/packages/shared-skills/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +6 -560
- package/packages/shared-skills/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
- package/packages/shared-skills/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
- package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +14 -3
- package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +10 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +0 -7
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +0 -19
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +0 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +0 -1128
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +0 -77
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +0 -86
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +0 -279
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +0 -252
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +0 -78
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
// entities.mjs - HTML character reference decoding for html-lite.mjs.
|
|
2
2
|
//
|
|
3
|
-
// Supports a fixed set of named entities plus decimal and hex numeric references.
|
|
4
|
-
// malformed references stay verbatim. Single indexOf scan; plain Node ESM, no dependencies.
|
|
3
|
+
// Supports a fixed set of named entities (NAMED_ENTITIES) plus decimal and hex numeric references.
|
|
4
|
+
// Unknown or malformed references stay verbatim. Single indexOf scan; plain Node ESM, no dependencies.
|
|
5
5
|
|
|
6
|
+
// Beyond the common set, every named reference whose character a number reader treats specially is
|
|
7
|
+
// listed (signs, dashes, the space separators that group digits, and Markdown punctuation), so the
|
|
8
|
+
// conversion probe reads `−5` and `1 234` as a converter does.
|
|
6
9
|
const NAMED_ENTITIES = {
|
|
7
10
|
amp: "&", lt: "<", gt: ">", quot: '"', apos: "'", nbsp: "\u00a0", mdash: "\u2014", ndash: "\u2013",
|
|
8
11
|
hellip: "\u2026", copy: "\u00a9", reg: "\u00ae", times: "\u00d7", middot: "\u00b7",
|
|
12
|
+
minus: "\u2212", hyphen: "\u2010", dash: "\u2010", NonBreakingSpace: "\u00a0", thinsp: "\u2009",
|
|
13
|
+
ThinSpace: "\u2009", numsp: "\u2007", puncsp: "\u2008", hairsp: "\u200a", VeryThinSpace: "\u200a",
|
|
14
|
+
ensp: "\u2002", emsp: "\u2003", emsp13: "\u2004", emsp14: "\u2005", MediumSpace: "\u205f",
|
|
15
|
+
comma: ",", period: ".", plus: "+", lowbar: "_", UnderBar: "_", ast: "*", midast: "*", grave: "`",
|
|
16
|
+
DiacriticalGrave: "`", lpar: "(", rpar: ")", lsqb: "[", lbrack: "[", rsqb: "]", rbrack: "]",
|
|
9
17
|
}
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
/** One reference body (between `&` and `;`), or null when unsupported. */
|
|
20
|
+
export function decodeOne(body) {
|
|
12
21
|
if (Object.hasOwn(NAMED_ENTITIES, body)) return NAMED_ENTITIES[body]
|
|
13
22
|
if (body[0] !== "#") return null
|
|
14
23
|
const hex = body[1] === "x" || body[1] === "X"
|
|
@@ -26,7 +35,7 @@ export function decodeEntities(text) {
|
|
|
26
35
|
let at = source.indexOf("&")
|
|
27
36
|
while (at !== -1) {
|
|
28
37
|
const semi = source.indexOf(";", at + 1)
|
|
29
|
-
const decoded = semi !== -1 && semi - at <=
|
|
38
|
+
const decoded = semi !== -1 && semi - at <= 32 ? decodeOne(source.slice(at + 1, semi)) : null
|
|
30
39
|
if (decoded !== null) {
|
|
31
40
|
out += source.slice(last, at) + decoded
|
|
32
41
|
last = semi + 1
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// fact-commands-fill.mjs - `fact fill`, the reader-facing fill of a placeholder source.
|
|
2
|
+
//
|
|
3
|
+
// It refuses an unlocked brief (fidelity_interview_incomplete) and applies the locked `## Fidelity`
|
|
4
|
+
// fields: `derived numbers: none` and the source floor refuse rows (derived_not_allowed,
|
|
5
|
+
// source_outside_floor, evaluated at every fill), `languages` decides whether a translation after a
|
|
6
|
+
// quote binds to it, and `fallback` picks the block quote or omission for --replace-failed. Any
|
|
7
|
+
// error writes no edition, fill map, or state; the one write that survives a refusal is the
|
|
8
|
+
// ledger's cached outside_floor per row (skipped under --view). The fill map records brief_sha256,
|
|
9
|
+
// the locked block fact verify checks it against. node: builtins and sibling imports only.
|
|
10
|
+
|
|
11
|
+
import { readFileSync, writeFileSync } from "node:fs"
|
|
12
|
+
import { dirname, extname, resolve } from "node:path"
|
|
13
|
+
|
|
14
|
+
import { CliError, sha256Of, writeJsonAtomic } from "./cli-support.mjs"
|
|
15
|
+
import { DEFECT_CODES } from "./contracts.mjs"
|
|
16
|
+
import { markdownAsHtml } from "./fact-commands-verify.mjs"
|
|
17
|
+
import { FILL_FORMATS, fill } from "./fact-fill.mjs"
|
|
18
|
+
import { readLedger, writeLedger } from "./fact-ledger.mjs"
|
|
19
|
+
import { briefHashOf, fillPolicy, lockedBrief, policyErrors } from "./fidelity-policy.mjs"
|
|
20
|
+
import { readState, writeState } from "./fidelity-state.mjs"
|
|
21
|
+
import { withBoundUnits } from "./fidelity-value-unit.mjs"
|
|
22
|
+
import { parseMarkdown } from "./md-lite.mjs"
|
|
23
|
+
import { findPlaceholders } from "./placeholder.mjs"
|
|
24
|
+
import { sessionDirOf } from "./source-commands.mjs"
|
|
25
|
+
|
|
26
|
+
/** The CLI's input vocabulary: fill's output formats plus aliases (tex is filled as md), and the extension defaults. */
|
|
27
|
+
export const FILL_INPUT_FORMAT_RULES = Object.freeze({
|
|
28
|
+
aliases: Object.freeze({ tex: "md" }),
|
|
29
|
+
extensions: Object.freeze({ ".md": "md", ".tex": "tex" }),
|
|
30
|
+
})
|
|
31
|
+
export const FILL_INPUT_FORMATS = Object.freeze([...FILL_FORMATS, ...Object.keys(FILL_INPUT_FORMAT_RULES.aliases)])
|
|
32
|
+
const fillFormatOf = (format) => FILL_INPUT_FORMAT_RULES.aliases[format] ?? format
|
|
33
|
+
|
|
34
|
+
/** Value-mode entries carry the unit fill saw bound to them (unit_bound), read off the edition verify will check. */
|
|
35
|
+
function boundUnits(out, entries, ledger, format) {
|
|
36
|
+
if (!entries.some((entry) => entry.mode === "value")) return entries
|
|
37
|
+
const html = fillFormatOf(format) === "html" ? out : parseMarkdown(out).problems.length === 0 ? markdownAsHtml(out, entries, ledger).html : null
|
|
38
|
+
return html === null ? entries : withBoundUnits(html, entries, new Map(ledger.rows.map((row) => [row.fact_id, row])))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function readText(path) {
|
|
42
|
+
try {
|
|
43
|
+
return readFileSync(path, "utf8")
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw new CliError(`cannot read ${path}: ${error.code ?? error.message}`)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The inline edition: local stylesheets and scripts inlined, relative image paths made absolute. */
|
|
50
|
+
function inlineAssets(html, baseDir) {
|
|
51
|
+
const local = (ref) => !/^[a-z][a-z0-9+.-]*:|^\/\//i.test(ref)
|
|
52
|
+
return html
|
|
53
|
+
.replace(/<link\b[^>]*\brel=["']stylesheet["'][^>]*>/gi, (tag) => {
|
|
54
|
+
const href = /\bhref=["']([^"']+)["']/i.exec(tag)?.[1]
|
|
55
|
+
return href && local(href) ? `<style>${readText(resolve(baseDir, href))}</style>` : tag
|
|
56
|
+
})
|
|
57
|
+
.replace(/<script\b([^>]*)\bsrc=["']([^"']+)["']([^>]*)><\/script>/gi, (tag, pre, src, post) => (local(src) ? `<script${pre}${post}>${readText(resolve(baseDir, src))}</script>` : tag))
|
|
58
|
+
.replace(/(<img\b[^>]*\bsrc=["'])([^"']+)(["'])/gi, (tag, pre, src, post) => (local(src) && !src.startsWith("/") ? `${pre}${resolve(baseDir, src)}${post}` : tag))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** @param {{ positionals: string[], flags: Record<string, any> }} args parsed by runFact */
|
|
62
|
+
export function runFactFill(args) {
|
|
63
|
+
const [source] = args.positionals
|
|
64
|
+
const { flags } = args
|
|
65
|
+
if (!source || (flags.out === undefined && !flags.view)) throw new CliError("usage: fact fill <src> (--out <path> | --view) [--format html|md|tex] [--inline] [--replace-failed] [--brief brief.md]")
|
|
66
|
+
const format = flags.format ?? FILL_INPUT_FORMAT_RULES.extensions[extname(source).toLowerCase()] ?? "html"
|
|
67
|
+
if (!FILL_INPUT_FORMATS.includes(format)) throw new CliError(`--format must be ${FILL_INPUT_FORMATS.slice(0, -1).join(", ")}, or ${FILL_INPUT_FORMATS.at(-1)}`)
|
|
68
|
+
if (flags.inline && format !== "html") throw new CliError("--inline applies to the html edition only")
|
|
69
|
+
const sessionDir = sessionDirOf(flags)
|
|
70
|
+
const { parsed, refusal } = lockedBrief("fact fill", flags)
|
|
71
|
+
if (refusal) return refusal
|
|
72
|
+
const policy = fillPolicy(parsed)
|
|
73
|
+
const text = readText(source)
|
|
74
|
+
const ledger = readLedger(sessionDir)
|
|
75
|
+
const refused = policyErrors(text, findPlaceholders(text), ledger, sessionDir, policy)
|
|
76
|
+
if (refused.cacheChanged && !flags.view) writeLedger(sessionDir, ledger)
|
|
77
|
+
const state = flags["replace-failed"] ? readState(sessionDir) : null
|
|
78
|
+
const result = fill(text, ledger, { format: fillFormatOf(format), view: flags.view === true, fallback: policy.fallback, ...(state ? { replaceFailed: state } : {}) })
|
|
79
|
+
const warnings = result.warnings
|
|
80
|
+
if (result.out === null || refused.errors.length > 0) {
|
|
81
|
+
const filled = result.errors.map((error) => ({ ...error, severity: DEFECT_CODES[error.code]?.severity ?? "blocker", hint: DEFECT_CODES[error.code]?.hint ?? null }))
|
|
82
|
+
const defects = [...refused.errors, ...filled]
|
|
83
|
+
return { json: { command: "fact fill", status: "fail", exitCode: 1, defects, warnings }, summary: `fact fill: FAIL - ${defects.length} error(s), nothing written`, exitCode: 1 }
|
|
84
|
+
}
|
|
85
|
+
const entries = policy.translations ? result.fillMap : result.fillMap.filter((entry) => entry.translates === undefined)
|
|
86
|
+
const out = flags.inline ? inlineAssets(result.out, dirname(resolve(source))) : result.out
|
|
87
|
+
if (flags.view) return { text: out, summary: `fact fill --view: ${entries.length} pointer(s), ${warnings.length} warning(s)`, exitCode: 0 }
|
|
88
|
+
writeFileSync(flags.out, out)
|
|
89
|
+
if (state) writeState(sessionDir, state)
|
|
90
|
+
const artifact = sha256Of(out)
|
|
91
|
+
const map = `${resolve(flags.out)}.fill-map.json`
|
|
92
|
+
const brief = briefHashOf(parsed)
|
|
93
|
+
writeJsonAtomic(map, { schemaVersion: 1, format, artifact: resolve(flags.out), artifact_sha256: artifact, brief_sha256: brief, entries: boundUnits(out, entries, ledger, format) })
|
|
94
|
+
const data = { out: resolve(flags.out), map, artifact_sha256: artifact, brief_sha256: brief, occurrences: entries.length, warnings }
|
|
95
|
+
return { json: { command: "fact fill", status: "pass", exitCode: 0, defects: [], data }, summary: `fact fill: wrote ${flags.out} (${entries.length} pointer(s))`, exitCode: 0 }
|
|
96
|
+
}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
// fact-commands-meaning.mjs - `fact pairs` and `fact meaning-check`, the script half of the
|
|
2
2
|
// separate-session meaning verifier. fact pairs writes the (source, report sentence) pairs a
|
|
3
|
-
// reader lane gets and nothing else (with --changed-since, only the pairs whose sentence
|
|
4
|
-
//
|
|
3
|
+
// reader lane gets and nothing else (with --changed-since, only the pairs whose sentence changed
|
|
4
|
+
// since the pre-polish fill map's artifact, or all when those bytes are gone); it honours the brief's `meaning check` field and writes
|
|
5
5
|
// `{ skipped: true }` when it is off. fact meaning-check ingests the readers' verdict files
|
|
6
|
-
// (meaning-check.mjs), writes
|
|
6
|
+
// (meaning-check.mjs), writes the meaning record of one edition (fidelity-meaning-defects.<format>.json
|
|
7
|
+
// with --edition, else the legacy fidelity-meaning-defects.json; a fidelity record bound to the pairs'
|
|
7
8
|
// artifact_sha256 and report, through writeFidelityRecord), and records the run in
|
|
8
9
|
// fidelity-calibration.jsonl: a header with the promotion criterion on first write, then per run
|
|
9
10
|
// one run line plus one line per flagged pair. The run id hashes the inputs only, so a rerun or a
|
|
10
11
|
// --dispute rerun of the same inputs replaces that run's lines in place (disputes carry forward)
|
|
11
|
-
// instead of counting a second run.
|
|
12
|
+
// instead of counting a second run. Both refuse an unlocked brief (fidelity_interview_incomplete) before
|
|
13
|
+
// reading anything else. Neither command calls a model or the network.
|
|
12
14
|
|
|
13
15
|
import { existsSync, readFileSync } from "node:fs"
|
|
14
16
|
import { dirname, join, resolve } from "node:path"
|
|
15
17
|
|
|
16
18
|
import { CliError, parseArgs, readJsonFile, sha256Of, writeJsonAtomic, writeTextAtomic } from "./cli-support.mjs"
|
|
17
|
-
import { countDefects } from "./contracts.mjs"
|
|
19
|
+
import { countDefects, DELIVERABLE_FORMATS } from "./contracts.mjs"
|
|
18
20
|
import { ledgerFrom, markdownAsHtml, readEdition, sessionOf } from "./fact-commands-verify.mjs"
|
|
19
21
|
import { pairsChangedSince } from "./fact-commands-polish.mjs"
|
|
20
22
|
import { extractPairs, PAIR_KINDS } from "./fact-pairs.mjs"
|
|
21
|
-
import { FIDELITY_INCOMPLETE
|
|
22
|
-
import {
|
|
23
|
+
import { FIDELITY_INCOMPLETE } from "./fidelity-brief.mjs"
|
|
24
|
+
import { briefPathOf, lockedBrief, meaningCheckEnabled } from "./fidelity-policy.mjs"
|
|
25
|
+
import { MEANING_RECORD, meaningRecordName, writeFidelityRecord } from "./fidelity-records.mjs"
|
|
23
26
|
import { blocksDelivery } from "./gates-fidelity.mjs"
|
|
24
27
|
import { ingestVerdicts, unverifiedDefects, VERDICT_SCHEMA } from "./meaning-check.mjs"
|
|
25
28
|
|
|
@@ -36,25 +39,15 @@ const inSession = (session, name, flag) => {
|
|
|
36
39
|
return join(session, name)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
|
-
function briefState(flags, session) {
|
|
40
|
-
const path = flags.brief ?? inSession(session, "brief.md", "--brief")
|
|
41
|
-
const lock = requireLockedBrief(path)
|
|
42
|
-
if (lock.exitCode === 2) throw new CliError(`${path}: malformed ## Fidelity block: ${lock.errors.join("; ")}`)
|
|
43
|
-
return { path, locked: lock.locked, off: !meaningCheckEnabled(lock.parsed) }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
42
|
function runPairs(args) {
|
|
47
43
|
const [report] = args.positionals
|
|
48
44
|
const { flags } = args
|
|
49
45
|
if (!report) throw new CliError("usage: fact pairs <report> [--format html|md] [--ledger F] [--claims claims.json] [--changed-since <fill-map.json>] [--brief brief.md] [--out pairs.json]")
|
|
50
46
|
const session = sessionOf(flags)
|
|
51
47
|
const out = resolve(flags.out ?? inSession(session, PAIRS_FILE, "--out"))
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
return { json, summary: `fact pairs: ${json.message}`, exitCode: 1 }
|
|
56
|
-
}
|
|
57
|
-
if (brief.off) {
|
|
48
|
+
const { parsed, refusal } = lockedBrief("fact pairs", flags)
|
|
49
|
+
if (refusal) return refusal
|
|
50
|
+
if (!meaningCheckEnabled(parsed)) {
|
|
58
51
|
const record = { schemaVersion: 1, skipped: true, reason: "meaning check: off", pairs: [] }
|
|
59
52
|
writeJsonAtomic(out, record)
|
|
60
53
|
return { json: { command: "fact pairs", status: "skipped", exitCode: 0, data: { out, ...record } }, summary: "fact pairs: skipped (meaning check: off)", exitCode: 0 }
|
|
@@ -65,10 +58,12 @@ function runPairs(args) {
|
|
|
65
58
|
const ledger = ledgerFrom(flags, session)
|
|
66
59
|
const html = edition.format === "md" ? markdownAsHtml(edition.text, edition.entries, ledger).html : edition.text
|
|
67
60
|
const all = extractPairs(html, ledger, claims)
|
|
68
|
-
const
|
|
61
|
+
const since = flags["changed-since"] === undefined ? null : pairsChangedSince(all, flags["changed-since"], ledger, claims)
|
|
62
|
+
const pairs = since?.pairs ?? all
|
|
69
63
|
const counts = { total: pairs.length, force_strong: pairs.filter((pair) => pair.force_strong).length }
|
|
70
64
|
for (const kind of PAIR_KINDS) counts[kind] = pairs.filter((pair) => pair.kind === kind).length
|
|
71
|
-
const
|
|
65
|
+
const changed = since === null ? {} : { changed_since: { fill_map: since.fill_map, narrowed: since.narrowed } }
|
|
66
|
+
const record = { schemaVersion: 1, skipped: false, report: resolve(report), format: edition.format, artifact_sha256: sha256Of(edition.text), pairs_sha256: sha256Of(JSON.stringify(pairs)), counts, ...changed, verdict_schema: VERDICT_SCHEMA, pairs }
|
|
72
67
|
writeJsonAtomic(out, record)
|
|
73
68
|
const summary = `fact pairs: ${counts.total} pair(s), ${counts.force_strong} routed to the strong reader`
|
|
74
69
|
return { json: { command: "fact pairs", status: "pass", exitCode: 0, data: { out, ...record, pairs: undefined } }, summary, exitCode: 0 }
|
|
@@ -125,23 +120,24 @@ function recordCalibration(path, lines, runId, pairsSha) {
|
|
|
125
120
|
}
|
|
126
121
|
|
|
127
122
|
/** A `{ skipped: true }` pairs file is accepted only when the locked brief turns the meaning check off. */
|
|
128
|
-
function skippedRefusal(flags,
|
|
129
|
-
|
|
130
|
-
if (!brief.locked) return { error: FIDELITY_INCOMPLETE, message: `${brief.path} has no locked ## Fidelity block, so a skipped meaning check cannot be accepted` }
|
|
131
|
-
if (!brief.off) return { error: "meaning_check_required", message: `${flags.pairs} says skipped but ${brief.path} has meaning check on; rerun fact pairs` }
|
|
123
|
+
function skippedRefusal(flags, parsed) {
|
|
124
|
+
if (meaningCheckEnabled(parsed)) return { error: "meaning_check_required", message: `${flags.pairs} says skipped but ${briefPathOf(flags)} has meaning check on; rerun fact pairs` }
|
|
132
125
|
return null
|
|
133
126
|
}
|
|
134
127
|
|
|
135
128
|
function runMeaningCheck(args) {
|
|
136
129
|
const { flags } = args
|
|
137
|
-
const usage = "usage: fact meaning-check --pairs pairs.json --verdicts cheap.json [--verdicts strong.json] [--dispute P<n> --reason TEXT] [--run-id ID] [--calibration F] [--out F]"
|
|
130
|
+
const usage = "usage: fact meaning-check --pairs pairs.json --verdicts cheap.json [--verdicts strong.json] [--dispute P<n> --reason TEXT] [--run-id ID] [--calibration F] [--brief brief.md] [--edition FORMAT] [--out F]"
|
|
138
131
|
if (flags.pairs === undefined || !Array.isArray(flags.verdicts)) throw new CliError(usage)
|
|
132
|
+
if (flags.edition !== undefined && !DELIVERABLE_FORMATS.includes(flags.edition)) throw new CliError(`--edition must be a deliverable format (${DELIVERABLE_FORMATS.join(", ")}), got ${flags.edition}`)
|
|
139
133
|
const session = sessionOf(flags)
|
|
134
|
+
const { parsed, refusal } = lockedBrief("fact meaning-check", flags)
|
|
135
|
+
if (refusal) return { ...refusal, json: { ...refusal.json, error: FIDELITY_INCOMPLETE } }
|
|
140
136
|
const pairsText = readFileSync(flags.pairs, "utf8")
|
|
141
137
|
const pairsDoc = readJsonFile(flags.pairs)
|
|
142
138
|
if (pairsDoc?.skipped === true) {
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
139
|
+
const skipped = skippedRefusal(flags, parsed)
|
|
140
|
+
if (skipped !== null) return { json: { command: "fact meaning-check", status: "fail", exitCode: 1, ...skipped }, summary: `fact meaning-check: ${skipped.message}`, exitCode: 1 }
|
|
145
141
|
return { json: { command: "fact meaning-check", status: "skipped", exitCode: 0, defects: [] }, summary: JSON.stringify({ command: "fact meaning-check", status: "skipped" }), exitCode: 0 }
|
|
146
142
|
}
|
|
147
143
|
if (typeof pairsDoc?.artifact_sha256 !== "string" || typeof pairsDoc.report !== "string") throw new CliError(`${flags.pairs} names no artifact_sha256 and report, so the meaning record cannot be bound to an edition; rerun fact pairs`)
|
|
@@ -154,7 +150,7 @@ function runMeaningCheck(args) {
|
|
|
154
150
|
} catch (error) {
|
|
155
151
|
throw new CliError(`invalid verdict input: ${error.message}`)
|
|
156
152
|
}
|
|
157
|
-
const out = resolve(flags.out ?? inSession(session, MEANING_RECORD, "--out"))
|
|
153
|
+
const out = resolve(flags.out ?? inSession(session, flags.edition === undefined ? MEANING_RECORD : meaningRecordName(flags.edition), "--out"))
|
|
158
154
|
const calibration = resolve(flags.calibration ?? join(session ?? dirname(out), CALIBRATION_FILE))
|
|
159
155
|
const runId = flags["run-id"] ?? sha256Of([pairsText, ...verdictTexts].join("\0")).slice(0, 16)
|
|
160
156
|
const pairsSha = pairsDoc.pairs_sha256 ?? sha256Of(pairsText)
|
|
@@ -6,19 +6,26 @@
|
|
|
6
6
|
// rejected (major) or unlocated (minor) edit leaves its region unchanged and is listed with its
|
|
7
7
|
// index and reason so the orchestrator can re-send it; every rejection reason is printed verbatim, one
|
|
8
8
|
// line per rejected edit (index and the first 60 characters of its before), in the summary and in
|
|
9
|
-
// data.rejected_reasons. It exits 0 whenever it wrote the output.
|
|
9
|
+
// data.rejected_reasons. It exits 0 whenever it wrote the output; json.applied is false when
|
|
10
|
+
// any edit was rejected or unlocated, independently of data.applied's accepted-edit count.
|
|
11
|
+
// polish-apply never rewrites a fill map: it checks that the edition's map (fillMapOf) records the
|
|
12
|
+
// input's bytes, refusing otherwise, and writes `<out>.polished.fill-map.json` beside the output
|
|
13
|
+
// (artifact = the polished file, its hash, and polishedFrom = the fill map's path and sha256).
|
|
10
14
|
// polish-diff is the whole-document backstop (polish-diff.mjs) between the pre-polish artifact
|
|
11
|
-
// and any later copy; it exits 1 on a blocker. pairsChangedSince
|
|
12
|
-
//
|
|
13
|
-
// meaning readers re-check exactly what
|
|
15
|
+
// and any later copy; it exits 1 on a blocker. pairsChangedSince always reads the pre-polish fill
|
|
16
|
+
// map (following a polished map's polishedFrom) and keeps only the pairs whose sentence text
|
|
17
|
+
// (normalized) is not in the artifact it names, so the meaning readers re-check exactly what
|
|
18
|
+
// changed; when that artifact no longer hashes to the map (polished in place, or edited) nothing
|
|
19
|
+
// can be ruled out and every pair is kept. No model, no network.
|
|
14
20
|
|
|
15
21
|
import { existsSync, readFileSync } from "node:fs"
|
|
16
22
|
import { join, resolve } from "node:path"
|
|
17
23
|
|
|
18
24
|
import { CliError, parseArgs, readJsonFile, sha256Of, writeJsonAtomic, writeTextAtomic } from "./cli-support.mjs"
|
|
19
25
|
import { countDefects, DEFECT_CODES } from "./contracts.mjs"
|
|
20
|
-
import { editionFormatOf, ledgerFrom, markdownAsHtml, sessionOf } from "./fact-commands-verify.mjs"
|
|
26
|
+
import { editionFormatOf, fillMapOf, ledgerFrom, markdownAsHtml, sessionOf } from "./fact-commands-verify.mjs"
|
|
21
27
|
import { extractPairs } from "./fact-pairs.mjs"
|
|
28
|
+
import { lockedBrief } from "./fidelity-policy.mjs"
|
|
22
29
|
import { applyEdits, POLISH_EDIT_FIELDS, validatePolishEdits } from "./polish-apply.mjs"
|
|
23
30
|
import { diffPolish } from "./polish-diff.mjs"
|
|
24
31
|
import { normalizeText } from "./text-normalize.mjs"
|
|
@@ -57,8 +64,10 @@ const rejectionLine = (entry, edit) => ` rejected edit ${entry.index} ("${befor
|
|
|
57
64
|
function runPolishApply(args) {
|
|
58
65
|
const [report] = args.positionals
|
|
59
66
|
const { flags } = args
|
|
60
|
-
if (!report || flags.edits === undefined || flags.out === undefined) throw new CliError("usage: fact polish-apply <report.html> --edits polish-edits.json --out <report.polished.html> [--ledger F] [--session-dir D]")
|
|
67
|
+
if (!report || flags.edits === undefined || flags.out === undefined) throw new CliError("usage: fact polish-apply <report.html> --edits polish-edits.json --out <report.polished.html> [--fill-map F] [--ledger F] [--brief brief.md] [--session-dir D]")
|
|
61
68
|
if (editionFormatOf(report, flags.format) === "md") throw new CliError("fact polish-apply takes the filled HTML edition; polish a Markdown edition through its HTML source")
|
|
69
|
+
const { refusal } = lockedBrief("fact polish-apply", flags)
|
|
70
|
+
if (refusal) return refusal
|
|
62
71
|
const html = readText(report)
|
|
63
72
|
const editsText = readText(flags.edits)
|
|
64
73
|
const edits = readJsonFile(flags.edits)
|
|
@@ -68,18 +77,25 @@ function runPolishApply(args) {
|
|
|
68
77
|
throw new CliError(`${flags.edits} must be an array of {${Object.keys(POLISH_EDIT_FIELDS).join(", ")}} objects: ${error.message}`)
|
|
69
78
|
}
|
|
70
79
|
const result = applyEdits(html, edits, ledgerFrom(flags))
|
|
80
|
+
const mapPath = fillMapOf(report, html, flags["fill-map"])
|
|
81
|
+
const map = mapPath === null ? null : readJsonFile(mapPath)
|
|
82
|
+
if (map !== null && map.artifact_sha256 !== sha256Of(html)) throw new CliError(`${mapPath} does not record the bytes of ${report} (artifact_sha256 differs); refusing to carry its brief binding to the polished edition`)
|
|
83
|
+
const polishedFrom = map?.polishedFrom ?? (map && { map: resolve(mapPath), sha256: sha256Of(readText(mapPath)) })
|
|
71
84
|
writeTextAtomic(flags.out, result.out)
|
|
85
|
+
if (map) writeJsonAtomic(`${resolve(flags.out)}.polished.fill-map.json`, { ...map, artifact: resolve(flags.out), artifact_sha256: sha256Of(result.out), polishedFrom })
|
|
72
86
|
const defects = [...result.rejected, ...result.unlocated].sort((a, b) => a.index - b.index).map(withSeverity)
|
|
73
87
|
const counts = { applied: result.applied.length, rejected: result.rejected.length, unlocated: result.unlocated.length }
|
|
74
88
|
const data = { out: resolve(flags.out), ...counts, applied_indexes: result.applied, input_sha256: sha256Of(html), edits_sha256: sha256Of(editsText), out_sha256: sha256Of(result.out) }
|
|
75
89
|
const rejected_reasons = result.rejected.map((entry) => rejectionLine(entry, edits[entry.index]))
|
|
76
90
|
const summary = [`fact polish-apply: ${counts.applied} applied, ${counts.rejected} rejected, ${counts.unlocated} unlocated of ${edits.length} edit(s)`, ...rejected_reasons].join("\n")
|
|
77
|
-
return { json: { command: "fact polish-apply", status: "pass", exitCode: 0, defects, data: { ...data, rejected_reasons } }, summary, exitCode: 0 }
|
|
91
|
+
return { json: { command: "fact polish-apply", status: "pass", exitCode: 0, applied: counts.rejected === 0 && counts.unlocated === 0, defects, data: { ...data, rejected_reasons } }, summary, exitCode: 0 }
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
function runPolishDiff(args) {
|
|
81
95
|
const { flags } = args
|
|
82
|
-
if (flags.before === undefined || flags.after === undefined) throw new CliError("usage: fact polish-diff --before <pre-polish.html> --after <polished.html> [--ledger F] [--out polish-defects.json] [--session-dir D]")
|
|
96
|
+
if (flags.before === undefined || flags.after === undefined) throw new CliError("usage: fact polish-diff --before <pre-polish.html> --after <polished.html> [--ledger F] [--out polish-defects.json] [--brief brief.md] [--session-dir D]")
|
|
97
|
+
const { refusal } = lockedBrief("fact polish-diff", flags)
|
|
98
|
+
if (refusal) return refusal
|
|
83
99
|
const after = readText(flags.after)
|
|
84
100
|
const defects = diffPolish(readText(flags.before), after, ledgerFrom(flags)).map((defect) => ({ ...defect, hint: DEFECT_CODES[defect.code]?.hint ?? null }))
|
|
85
101
|
const counts = countDefects(defects)
|
|
@@ -95,29 +111,40 @@ function runPolishDiff(args) {
|
|
|
95
111
|
|
|
96
112
|
const pairKey = (pair) => [pair.kind, pair.sentence_key, pair.claim_id ?? "", normalizeText(pair.sentence)].join("\u0000")
|
|
97
113
|
|
|
114
|
+
/** The pre-polish fill map behind --changed-since: a polished map leads to it through polishedFrom, whose sha256 it must still match. */
|
|
115
|
+
function prePolishMap(mapPath) {
|
|
116
|
+
const given = readJsonFile(mapPath)
|
|
117
|
+
if (given.polishedFrom === undefined) return { path: resolve(mapPath), map: given }
|
|
118
|
+
const { map: path, sha256 } = given.polishedFrom
|
|
119
|
+
if (typeof path !== "string" || sha256Of(readText(path)) !== sha256) throw new CliError(`${path} changed after polish wrote ${mapPath}; --changed-since needs the pre-polish fill map it names`)
|
|
120
|
+
return { path, map: readJsonFile(path) }
|
|
121
|
+
}
|
|
122
|
+
|
|
98
123
|
/**
|
|
99
|
-
* The pairs whose sentence text changed since the pre-polish artifact
|
|
100
|
-
* kept unless the same (kind, sentence key, normalized sentence) occurs in that artifact.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
124
|
+
* The pairs whose sentence text changed since the pre-polish artifact the fill map names: a pair is
|
|
125
|
+
* kept unless the same (kind, sentence key, normalized sentence) occurs in that artifact. Only bytes
|
|
126
|
+
* that still hash to the map's `artifact_sha256` narrow the set; otherwise (the report was polished
|
|
127
|
+
* in place, or edited) every pair is kept, so nothing changed escapes the meaning re-check.
|
|
103
128
|
* @param {object[]} pairs extractPairs output on the polished edition
|
|
104
|
-
* @param {string} mapPath
|
|
129
|
+
* @param {string} mapPath fact fill's `<out>.fill-map.json`, or polish-apply's `<out>.polished.fill-map.json`
|
|
130
|
+
* @returns {{ pairs: object[], fill_map: string, narrowed: boolean }}
|
|
105
131
|
*/
|
|
106
132
|
export function pairsChangedSince(pairs, mapPath, ledger, claims) {
|
|
107
|
-
const map =
|
|
108
|
-
if (typeof map.artifact !== "string"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (sha256Of(text) !== map.artifact_sha256)
|
|
133
|
+
const { path, map } = prePolishMap(mapPath)
|
|
134
|
+
if (typeof map.artifact !== "string") throw new CliError(`${path} names no pre-polish artifact`)
|
|
135
|
+
if (typeof map.artifact_sha256 !== "string") throw new CliError(`${path} fill map has no artifact_sha256; --changed-since needs the pre-polish hash`)
|
|
136
|
+
const text = existsSync(map.artifact) ? readText(map.artifact) : null
|
|
137
|
+
if (text === null || sha256Of(text) !== map.artifact_sha256) return { pairs, fill_map: path, narrowed: false }
|
|
112
138
|
const html = map.format === "md" ? markdownAsHtml(text, map.entries, ledger).html : text
|
|
113
139
|
const before = new Map()
|
|
114
140
|
for (const pair of extractPairs(html, ledger, claims)) before.set(pairKey(pair), (before.get(pairKey(pair)) ?? 0) + 1)
|
|
115
|
-
|
|
141
|
+
const kept = pairs.filter((pair) => {
|
|
116
142
|
const left = before.get(pairKey(pair)) ?? 0
|
|
117
143
|
if (left === 0) return true
|
|
118
144
|
before.set(pairKey(pair), left - 1)
|
|
119
145
|
return false
|
|
120
146
|
})
|
|
147
|
+
return { pairs: kept, fill_map: path, narrowed: true }
|
|
121
148
|
}
|
|
122
149
|
|
|
123
150
|
/** @param {string[]} argv the arguments after `fact polish-apply` or `fact polish-diff` */
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
// escaped HTML projection (same line numbers) and checked with its fill map, which is the only
|
|
9
9
|
// record of where its values sit; LaTeX is verified through its Markdown source.
|
|
10
10
|
//
|
|
11
|
+
// The locked brief is re-judged here, not only at fill: every edition (HTML or Markdown) needs its
|
|
12
|
+
// fill map (fillMapOf: --fill-map, else whichever of `<report>.fill-map.json` and the
|
|
13
|
+
// `<report>.polished.fill-map.json` polish-apply writes records the edition's bytes), and that map
|
|
14
|
+
// must carry the current brief's brief_sha256; no map, or another hash, is brief_changed. policyErrors
|
|
15
|
+
// re-runs over every data-fact the edition carries, so an edition that violates the current
|
|
16
|
+
// derived-numbers or source-floor rule fails here too.
|
|
17
|
+
//
|
|
11
18
|
// The delivery barrier that reads these records (and every other fidelity record) is
|
|
12
19
|
// fidelity-records.mjs.
|
|
13
20
|
|
|
@@ -19,6 +26,7 @@ import { countDefects } from "./contracts.mjs"
|
|
|
19
26
|
import { recompute } from "./fact-derive.mjs"
|
|
20
27
|
import { readLedger } from "./fact-ledger.mjs"
|
|
21
28
|
import { validateLedger } from "./fact-ledger-schema.mjs"
|
|
29
|
+
import { briefBindingErrors, fillPolicy, lockedBrief, policyErrors } from "./fidelity-policy.mjs"
|
|
22
30
|
import { FIDELITY_RECORD, writeFidelityRecord } from "./fidelity-records.mjs"
|
|
23
31
|
import { blocksDelivery, checkFidelity } from "./gates-fidelity.mjs"
|
|
24
32
|
import { parseMarkdown } from "./md-lite.mjs"
|
|
@@ -60,8 +68,8 @@ function entryHtml(text, entry, rows) {
|
|
|
60
68
|
if (entry.translates) return `<span data-translates="${escapeHtml(entry.translates)}">${projectMarkdownInline(body.replace(/^<!--[\s\S]*?-->\s*/u, ""))}</span>`
|
|
61
69
|
if (!row) return `<data data-fact="${escapeHtml(entry.fact_id)}">${escapeHtml(body)}</data>`
|
|
62
70
|
const quoted = row.kind === "quote" ? parseRenderedQuote(body) : null
|
|
63
|
-
if (quoted) return renderQuote(row, entry.selector ?? "full", quoted.text, "html")
|
|
64
|
-
return row.kind === "quote" ? null : renderValueHtml(row, body)
|
|
71
|
+
if (quoted) return renderQuote(row, entry.selector ?? "full", quoted.text, "html", entry.claimKind)
|
|
72
|
+
return row.kind === "quote" ? null : renderValueHtml(row, body, { mode: entry.mode, claimKind: entry.claimKind ?? null })
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
/** [from, to) of the filled text as HTML, each intact fill-map entry rebuilt as its fill element. */
|
|
@@ -143,6 +151,17 @@ const MARKDOWN_EXTENSION = /\.(md|markdown)$/iu
|
|
|
143
151
|
/** The edition format: the explicit flag, else md for a .md or .markdown path (any case), else html. */
|
|
144
152
|
export const editionFormatOf = (path, flag) => flag ?? (MARKDOWN_EXTENSION.test(path) ? "md" : "html")
|
|
145
153
|
|
|
154
|
+
/**
|
|
155
|
+
* An edition's fill map path: --fill-map, else whichever of fact fill's `<report>.fill-map.json` and
|
|
156
|
+
* polish-apply's `<report>.polished.fill-map.json` records these bytes as its artifact_sha256, else the
|
|
157
|
+
* first of them that exists; null when neither exists.
|
|
158
|
+
*/
|
|
159
|
+
export function fillMapOf(report, text, flag) {
|
|
160
|
+
if (flag !== undefined) return flag
|
|
161
|
+
const found = [`${report}.fill-map.json`, `${report}.polished.fill-map.json`].filter((path) => existsSync(path))
|
|
162
|
+
return found.find((path) => readJsonFile(path).artifact_sha256 === sha256Of(text)) ?? found[0] ?? null
|
|
163
|
+
}
|
|
164
|
+
|
|
146
165
|
/** The report's format (from --format or its extension) and, for Markdown, its fill map entries. */
|
|
147
166
|
export function readEdition(report, flags) {
|
|
148
167
|
const format = editionFormatOf(report, flags.format)
|
|
@@ -159,25 +178,37 @@ export function runFactVerify(args) {
|
|
|
159
178
|
const [report] = args.positionals
|
|
160
179
|
const { flags } = args
|
|
161
180
|
if (!report) throw new CliError("usage: fact verify <report> [--format html|md] [--sources D] [--claims claims.json] [--fill-map F] [--brief brief.md] [--out fidelity-defects.json]")
|
|
162
|
-
const edition = readEdition(report, flags)
|
|
163
181
|
const sessionDir = sessionDirOf(flags)
|
|
182
|
+
const { parsed, refusal } = lockedBrief("fact verify", flags)
|
|
183
|
+
if (refusal) return refusal
|
|
184
|
+
const policy = fillPolicy(parsed)
|
|
185
|
+
const edition = readEdition(report, flags)
|
|
164
186
|
const claimsPath = flags.claims ?? join(sessionDir, "claims.json")
|
|
165
187
|
const briefPath = flags.brief ?? join(sessionDir, "brief.md")
|
|
166
188
|
const ledger = readLedger(sessionDir)
|
|
167
189
|
const projected = edition.format === "md" ? markdownAsHtml(edition.text, edition.entries, ledger) : null
|
|
190
|
+
// The entries whose element is in the checked HTML: an HTML edition's own map, or the projection's intact entries.
|
|
191
|
+
const ownMap = flags["fill-map"] ?? `${report}.fill-map.json`
|
|
192
|
+
const fillEntries = projected ? edition.entries.filter((entry) => !projected.stale.includes(entry)) : existsSync(ownMap) ? readJsonFile(ownMap).entries : null
|
|
168
193
|
const result = checkFidelity(projected?.html ?? edition.text, {
|
|
169
194
|
ledger,
|
|
170
195
|
sourcesDir: resolve(flags.sources ?? join(sessionDir, "sources")),
|
|
171
196
|
claims: flags.claims !== undefined || existsSync(claimsPath) ? readJsonFile(claimsPath) : null,
|
|
172
197
|
fillMap: projected?.stale ?? edition.entries,
|
|
198
|
+
fillEntries,
|
|
173
199
|
brief: existsSync(briefPath) ? readText(briefPath) : "",
|
|
174
200
|
baseDir: dirname(resolve(report)),
|
|
175
201
|
recompute,
|
|
176
202
|
})
|
|
177
|
-
const
|
|
178
|
-
const
|
|
203
|
+
const checked = projected?.html ?? edition.text
|
|
204
|
+
const pointers = [...checked.matchAll(/\bdata-fact="([^"]+)"/gu)].map((match) => ({ token: match[0], start: match.index, parsed: { id: match[1] } }))
|
|
205
|
+
const mapPath = fillMapOf(report, edition.text, flags["fill-map"])
|
|
206
|
+
const bound = briefBindingErrors(mapPath === null ? null : readJsonFile(mapPath), mapPath ?? `${report}.fill-map.json`, parsed)
|
|
207
|
+
const defects = [...bound, ...policyErrors(checked, pointers, ledger, sessionDir, policy).errors, ...result.defects]
|
|
208
|
+
const counts = countDefects(defects)
|
|
209
|
+
const status = defects.some(blocksDelivery) ? "fail" : "pass"
|
|
179
210
|
const exitCode = status === "fail" ? 1 : 0
|
|
180
211
|
const out = resolve(flags.out ?? join(sessionDir, FIDELITY_RECORD))
|
|
181
|
-
const record = writeFidelityRecord(out, "fidelity", { command: "fact verify", status, exitCode, format: edition.format, report: resolve(report), artifact_sha256: sha256Of(edition.text), defects
|
|
212
|
+
const record = writeFidelityRecord(out, "fidelity", { command: "fact verify", status, exitCode, format: edition.format, report: resolve(report), artifact_sha256: sha256Of(edition.text), defects, counts, gatesRun: result.gatesRun })
|
|
182
213
|
return { json: { ...record, out }, summary: `fact verify: ${status.toUpperCase()} - ${counts.blocker} blocker, ${counts.major} major, ${counts.minor} minor`, exitCode }
|
|
183
214
|
}
|