clearotron 0.2.1 → 0.2.3
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/.env.example +82 -1
- package/.nvmrc +1 -1
- package/CONTRIBUTING.md +3 -3
- package/INSTALL.md +64 -58
- package/README.md +11 -16
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/bin/brandowner.mjs +1 -1
- package/bin/clearotron.mjs +26 -4
- package/bin/connect.mjs +2 -2
- package/bin/example.mjs +31 -11
- package/bin/grant.mjs +3 -3
- package/bin/key.mjs +1 -1
- package/bin/onboard.mjs +252 -136
- package/bin/start.mjs +176 -33
- package/bin/stop.mjs +65 -3
- package/bin/update.mjs +7 -7
- package/bin/uspto-sync.mjs +1 -1
- package/build-info.json +2 -2
- package/demo/full-country-search/run/_driver/framework.json +1 -1
- package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
- package/demo/knockout-search/run/_driver/framework.json +1 -1
- package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
- package/docs/DELIVERY.md +6 -2
- package/docs/E2E.md +5 -5
- package/docs/PORTAL.md +2 -2
- package/docs/README.md +5 -4
- package/docs/SECURITY.md +17 -0
- package/docs/architecture/01-product-overview.md +2 -2
- package/docs/architecture/02-architecture.md +2 -2
- package/docs/architecture/04-configuration-reference.md +8 -3
- package/docs/architecture/05-config-governance.md +52 -5
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/architecture/06-operations-runbook.md +13 -1
- package/docs/architecture/09-security-and-data.md +1 -1
- package/docs/configuration.md +4 -3
- package/docs/decisions/0004-documentation-structure.md +1 -1
- package/driver/CHANGELOG.md +121 -1
- package/driver/README.md +2 -2
- package/driver/ask-ledger.mjs +3 -3
- package/driver/authority-trees.mjs +1 -1
- package/driver/call-capture.mjs +1 -1
- package/driver/card-frame.mjs +1 -1
- package/driver/case-law-ledger.mjs +1 -1
- package/driver/claim-liveness.mjs +1 -1
- package/driver/common-law-receipts.mjs +2 -2
- package/driver/commonlaw-carry.mjs +1 -1
- package/driver/config-inventory.mjs +1 -1
- package/driver/config-staleness.mjs +1 -1
- package/driver/connotation-search.mjs +12 -12
- package/driver/contract-audit.mjs +5 -5
- package/driver/contract-dictation-registry.mjs +4 -4
- package/driver/contract-dictation.mjs +2 -2
- package/driver/contract-e3-backlog.mjs +6 -6
- package/driver/contract-vocabulary.mjs +3 -3
- package/driver/corrections-feedforward.mjs +1 -1
- package/driver/coverage-form-io.mjs +2 -2
- package/driver/coverage-form.mjs +4 -4
- package/driver/coverage-ledger.mjs +3 -3
- package/driver/coverage-union.mjs +1 -1
- package/driver/declination-call.mjs +35 -3
- package/driver/declination-duty.mjs +1 -1
- package/driver/deliver-trigger.sh +3 -3
- package/driver/deploy-live-run-guard.mjs +6 -2
- package/driver/dev-portal.mjs +3 -3
- package/driver/disposition-call.mjs +4 -4
- package/driver/disposition-tool.mjs +4 -4
- package/driver/disposition-union.mjs +2 -2
- package/driver/doc-constants.mjs +1 -1
- package/driver/door-gates.mjs +2 -2
- package/driver/doubt-selection.mjs +2 -2
- package/driver/drainer-identity.mjs +1 -1
- package/driver/driver.config.mjs +64 -12
- package/driver/e2e-rounds.mjs +2 -2
- package/driver/effort-model.mjs +2 -2
- package/driver/engine/anthropic-agent.mjs +24 -24
- package/driver/engine/auth.mjs +1 -1
- package/driver/engine/cli-version.mjs +103 -0
- package/driver/engine/common.mjs +1 -1
- package/driver/engine/deny-authority-write.mjs +1 -1
- package/driver/engine/jx-turn.mjs +1 -1
- package/driver/engine/mcp/clarivate-server.mjs +1 -1
- package/driver/engine/mcp/corsearch-server.mjs +1 -1
- package/driver/engine/mcp/declination-server.mjs +1 -1
- package/driver/engine/mcp/dispositions-server.mjs +1 -1
- package/driver/engine/mcp/euipo-server.mjs +1 -1
- package/driver/engine/mcp/fetch-server.mjs +1 -1
- package/driver/engine/mcp/free-tier-server.mjs +2 -2
- package/driver/engine/mcp/gather-config.mjs +11 -11
- package/driver/engine/mcp/perplexity-server.mjs +1 -1
- package/driver/engine/mcp/recording-server.mjs +8 -4
- package/driver/engine/mcp/signa-server.mjs +1 -1
- package/driver/engine/mcp/uspto-local-server.mjs +1 -1
- package/driver/engine/openai-agent.mjs +2 -2
- package/driver/engine-build.mjs +2 -2
- package/driver/enqueue-schema.mjs +10 -10
- package/driver/enqueue.mjs +1 -1
- package/driver/envelope-settle.mjs +1 -1
- package/driver/evidence-claim-invariant.mjs +2 -2
- package/driver/feedback-store.mjs +1 -1
- package/driver/findings-model.mjs +60 -10
- package/driver/flag-snapshot.mjs +20 -0
- package/driver/floor-duty.mjs +1 -1
- package/driver/form-neighbourhood.mjs +1 -1
- package/driver/framework.mjs +2 -2
- package/driver/gateway.mjs +45 -23
- package/driver/grounds-grammar.mjs +1 -1
- package/driver/hit-list.mjs +1 -1
- package/driver/jurisdiction-systems.mjs +1 -1
- package/driver/jx-lanes.mjs +1 -1
- package/driver/jx-units.mjs +1 -1
- package/driver/jx.mjs +3 -3
- package/driver/knockout-assess-record.mjs +5 -1
- package/driver/narrative-refutation-record.mjs +3 -3
- package/driver/numeric-setting.mjs +1 -1
- package/driver/owner-use-check.mjs +184 -0
- package/driver/package.json +4 -4
- package/driver/party-facts.mjs +2 -2
- package/driver/phase0.mjs +2 -2
- package/driver/pipeline-knockout.mjs +52 -4
- package/driver/pipeline.mjs +180 -67
- package/driver/placement-diff.mjs +2 -2
- package/driver/placement-form.mjs +4 -4
- package/driver/placement-union.mjs +1 -1
- package/driver/plain-register.mjs +120 -0
- package/driver/portal-access.mjs +1 -1
- package/driver/portal-acks.mjs +1 -1
- package/driver/portal-config-view.mjs +42 -3
- package/driver/portal-families.mjs +1 -1
- package/driver/portal-local-auth.mjs +1 -1
- package/driver/portal-report.mjs +7 -7
- package/driver/portal-service.mjs +41 -22
- package/driver/portal-upstream.mjs +2 -2
- package/driver/predelivery-lint.mjs +149 -11
- package/driver/prelim-variants-record.mjs +2 -2
- package/driver/profile-page.html +11 -3
- package/driver/profile-selection.mjs +1 -1
- package/driver/profile-service.mjs +6 -6
- package/driver/profiles/README.md +3 -3
- package/driver/profiles.mjs +145 -13
- package/driver/progress.mjs +6 -6
- package/driver/provider-usage.mjs +1 -1
- package/driver/publish/demo-marking.mjs +1 -1
- package/driver/publish/index.mjs +49 -8
- package/driver/publish/knockout.mjs +42 -14
- package/driver/publish/parse.mjs +4 -4
- package/driver/publish/publish-inputs.mjs +2 -2
- package/driver/publish/register-presence.mjs +1 -1
- package/driver/publish/render-knockout.mjs +646 -144
- package/driver/publish/render.mjs +2 -2
- package/driver/publish/report-data.mjs +13 -3
- package/driver/queue-watch-probe.mjs +1 -1
- package/driver/queue-watch-verdict.mjs +1 -1
- package/driver/recall-reconciliation.mjs +1 -1
- package/driver/recipe-service.mjs +1 -1
- package/driver/record-carry.mjs +5 -5
- package/driver/recording-agreement.mjs +3 -3
- package/driver/reference-score.mjs +7 -7
- package/driver/reference-strip-signatures.mjs +20 -0
- package/driver/refusal-bound.mjs +3 -3
- package/driver/register-availability.mjs +2 -2
- package/driver/register-count.mjs +1 -1
- package/driver/register-grant-vocabulary.mjs +2 -2
- package/driver/register-plan.mjs +8 -8
- package/driver/register-records.mjs +2 -2
- package/driver/registry-fidelity.mjs +3 -3
- package/driver/remedy-accounting.mjs +1 -1
- package/driver/repair-composers.mjs +2 -2
- package/driver/repair-digest.mjs +3 -3
- package/driver/repairs.mjs +6 -6
- package/driver/replay-archive.mjs +2 -0
- package/driver/report-card-record.mjs +2 -2
- package/driver/result-noun-fields.mjs +10 -3
- package/driver/run-economics.mjs +2 -2
- package/driver/run-integrity.mjs +1 -1
- package/driver/runner.mjs +22 -22
- package/driver/scope-rules.mjs +1 -1
- package/driver/search-policy.mjs +5 -5
- package/driver/skeptic-search.mjs +1 -1
- package/driver/skills/blind-frame/SKILL.md +2 -2
- package/driver/skills/case-law-citation/SKILL.md +2 -2
- package/driver/skills/knockout-assess/SKILL.md +94 -4
- package/driver/skills/matter-frame/SKILL.md +6 -6
- package/driver/skills/matter-frame/watchlist-reference.md +2 -2
- package/driver/skills/prelim-common-law/SKILL.md +1 -1
- package/driver/skills/prelim-search/SKILL.md +3 -3
- package/driver/skills/prelim-search/report-prose.md +82 -0
- package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
- package/driver/skills/prelim-search/synthesis-rules.md +1 -1
- package/driver/skills/prelim-search/template-formatting.md +1 -1
- package/driver/skills/prelim-search/templates/email/generic.md +1 -1
- package/driver/skills/prelim-search/worked-examples.md +1 -1
- package/driver/skills/prelim-variants/SKILL.md +5 -5
- package/driver/stage-context.mjs +1 -1
- package/driver/stages-knockout.mjs +55 -4
- package/driver/stages.mjs +101 -44
- package/driver/stray-artifacts.mjs +2 -2
- package/driver/suite-census.json +275 -65
- package/driver/synthesis-record.mjs +1 -1
- package/driver/systemd/clearotron-client-mcp.service +1 -1
- package/driver/systemd/clearotron-portal.service +1 -1
- package/driver/systemd/render-units.mjs +1 -1
- package/driver/tokens.mjs +1 -1
- package/driver/tool-calls.mjs +1 -1
- package/driver/turnaround-bands.mjs +1 -1
- package/driver/unit-file-drift.mjs +1 -1
- package/driver/unit-inventory.mjs +297 -80
- package/driver/unit-state-verdict.mjs +20 -12
- package/driver/verify-knockout.mjs +10 -2
- package/driver/verify.mjs +13 -13
- package/driver/whatif-memo-run.mjs +72 -9
- package/driver/whatif-memo.mjs +19 -1
- package/driver/whatif-queue.mjs +1 -1
- package/driver/whatif-worker.mjs +1 -1
- package/examples/README.md +2 -2
- package/examples/grants.example.json +6 -7
- package/mcp-server/CHANGELOG.md +6 -0
- package/mcp-server/README.md +3 -3
- package/mcp-server/http-server.mjs +44 -1
- package/mcp-server/key-socket.mjs +184 -0
- package/mcp-server/lib/audit-view.mjs +69 -2
- package/mcp-server/lib/brief.mjs +15 -0
- package/mcp-server/lib/driver.mjs +7 -1
- package/mcp-server/lib/events.mjs +1 -1
- package/mcp-server/lib/http-handler.mjs +1 -1
- package/mcp-server/lib/knockout.mjs +435 -0
- package/mcp-server/lib/ops.mjs +4 -4
- package/mcp-server/lib/options.mjs +1 -1
- package/mcp-server/lib/plan.mjs +1 -1
- package/mcp-server/lib/runs.mjs +1 -1
- package/mcp-server/lib/scrub.mjs +2 -2
- package/mcp-server/lib/whatif.mjs +5 -5
- package/mcp-server/mint-token.mjs +1 -1
- package/mcp-server/package.json +2 -2
- package/mcp-server/packs/ops/EXAMPLES.md +2 -2
- package/mcp-server/server.mjs +77 -12
- package/package.json +30 -12
- package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
- package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-CEYvXdqH.js} +226 -49
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/_shared/enumerate.mjs +1 -1
- package/providers/_shared/ledger-path.mjs +3 -3
- package/providers/_shared/ledger.mjs +1 -1
- package/providers/_shared/result-shape.mjs +3 -3
- package/providers/_shared/term-shape.mjs +2 -2
- package/providers/corsearch/src/core.js +1 -1
- package/providers/jx-subclass/BUILDING.md +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +6 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/oauth-mcp-bridge/stdin-guard.mjs +2 -2
- package/providers/uspto-local/src/index-store.js +2 -2
- package/scripts/README.md +1 -1
- package/scripts/added-reference-check.mjs +29 -1
- package/scripts/authority-boundary-probe.mjs +1 -1
- package/scripts/backfill-started-at.mjs +1 -1
- package/scripts/citation-line-check.mjs +124 -5
- package/scripts/compare.mjs +2 -2
- package/scripts/contract-dictation-scan.mjs +2 -2
- package/scripts/dead-names.mjs +1 -1
- package/scripts/drain-preflight.mjs +5 -5
- package/scripts/e2e-unread-terminals.mjs +1 -1
- package/scripts/e2e.mjs +8 -8
- package/scripts/env-audit.mjs +7 -7
- package/scripts/env-classify.mjs +206 -18
- package/scripts/freeze-example-run.mjs +3 -3
- package/scripts/head-arrived-gated.mjs +1 -1
- package/scripts/headless-page.mjs +51 -2
- package/scripts/live-surface-check.mjs +129 -19
- package/scripts/main-health.mjs +1 -1
- package/scripts/merge-presence-check.mjs +3 -3
- package/scripts/mint-suite-census.mjs +6 -6
- package/scripts/nightly-notice.mjs +1 -3
- package/scripts/preinstall-node-check.mjs +24 -0
- package/scripts/reconcile-runs.mjs +1 -1
- package/scripts/release-await-cut.mjs +6 -4
- package/scripts/release-version-pr-checks.mjs +1 -1
- package/scripts/release-version.mjs +2 -2
- package/scripts/render-check.mjs +66 -7
- package/scripts/report-frame-check.mjs +1 -1
- package/scripts/report-screenshot.mjs +1 -1
- package/scripts/revisit-render-check.mjs +1 -1
- package/scripts/score.mjs +4 -4
- package/scripts/strip-tracker-citations.mjs +139 -0
- package/scripts/test-run.mjs +19 -3
- package/scripts/third-party-notices.mjs +3 -3
- package/scripts/travelling-predicates.mjs +3 -3
- package/scripts/unexecuted-asserts.mjs +2 -2
- package/scripts/verify-publishable.mjs +2 -2
- package/scripts/write-up-form-census.mjs +1 -1
- package/shared/access-audience.mjs +1 -1
- package/shared/anon-overlay.mjs +3 -3
- package/shared/brand.mjs +13 -13
- package/shared/citation-scan.mjs +1 -1
- package/shared/client-door.mjs +7 -7
- package/shared/customer-store.mjs +1 -1
- package/shared/driver-dir.mjs +1 -1
- package/shared/env-aliases.mjs +0 -48
- package/shared/env-local.mjs +1 -1
- package/shared/identifier-scan.mjs +3 -3
- package/shared/invocation.mjs +29 -1
- package/shared/names-in-force.mjs +4 -0
- package/shared/node-floor.mjs +97 -0
- package/shared/product-owned-names.mjs +1 -1
- package/shared/register-selection.mjs +1 -1
- package/shared/scope.mjs +5 -5
- package/shared/server-units.mjs +4 -4
- package/shared/staff-domain.mjs +154 -0
- package/shared/store-in-repo.mjs +25 -4
- package/shared/suite-census.mjs +4 -4
- package/shared/tty-style.mjs +1 -1
- package/shared/uspto-index-size.mjs +1 -1
- package/shared/vacuous-pass.mjs +1 -1
- package/skills/clearotron-account/SKILL.md +42 -13
- package/skills/clearotron-ops/SKILL.md +1 -1
- package/driver/recipes/README.md +0 -49
- package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
- package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
- package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
- package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
- package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
- package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
- package/driver/systemd/prelim-driver.path +0 -69
- package/driver/systemd/prelim-driver.service +0 -86
- package/driver/systemd/prelim-driver.timer +0 -14
- package/driver/systemd/prelim-outbox.path +0 -27
- package/driver/systemd/prelim-outbox.service +0 -37
- package/driver/systemd/prelim-outbox.timer +0 -21
- package/node_modules/exceljs/README_zh.md +0 -2878
- package/node_modules/exceljs/dist/LICENSE +0 -22
- package/node_modules/exceljs/dist/es5/csv/csv.js +0 -182
- package/node_modules/exceljs/dist/es5/csv/csv.js.map +0 -1
- package/node_modules/exceljs/dist/es5/csv/line-buffer.js +0 -68
- package/node_modules/exceljs/dist/es5/csv/line-buffer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/csv/stream-converter.js +0 -110
- package/node_modules/exceljs/dist/es5/csv/stream-converter.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/anchor.js +0 -73
- package/node_modules/exceljs/dist/es5/doc/anchor.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/cell.js +0 -961
- package/node_modules/exceljs/dist/es5/doc/cell.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/column.js +0 -274
- package/node_modules/exceljs/dist/es5/doc/column.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/data-validations.js +0 -18
- package/node_modules/exceljs/dist/es5/doc/data-validations.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/defined-names.js +0 -173
- package/node_modules/exceljs/dist/es5/doc/defined-names.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/enums.js +0 -49
- package/node_modules/exceljs/dist/es5/doc/enums.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/image.js +0 -69
- package/node_modules/exceljs/dist/es5/doc/image.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/modelcontainer.js +0 -16
- package/node_modules/exceljs/dist/es5/doc/modelcontainer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/note.js +0 -64
- package/node_modules/exceljs/dist/es5/doc/note.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/range.js +0 -229
- package/node_modules/exceljs/dist/es5/doc/range.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/row.js +0 -382
- package/node_modules/exceljs/dist/es5/doc/row.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/table.js +0 -443
- package/node_modules/exceljs/dist/es5/doc/table.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/workbook.js +0 -202
- package/node_modules/exceljs/dist/es5/doc/workbook.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/worksheet.js +0 -900
- package/node_modules/exceljs/dist/es5/doc/worksheet.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.bare.js +0 -14
- package/node_modules/exceljs/dist/es5/exceljs.bare.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.browser.js +0 -36
- package/node_modules/exceljs/dist/es5/exceljs.browser.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.nodejs.js +0 -15
- package/node_modules/exceljs/dist/es5/exceljs.nodejs.js.map +0 -1
- package/node_modules/exceljs/dist/es5/index.js +0 -15
- package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js +0 -90
- package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js +0 -94
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js +0 -94
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js +0 -362
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js +0 -347
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js +0 -392
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js +0 -652
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/auto-drain.js +0 -18
- package/node_modules/exceljs/dist/es5/utils/auto-drain.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js +0 -15
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js +0 -18
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/cell-matrix.js +0 -149
- package/node_modules/exceljs/dist/es5/utils/cell-matrix.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/col-cache.js +0 -258
- package/node_modules/exceljs/dist/es5/utils/col-cache.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/copy-style.js +0 -43
- package/node_modules/exceljs/dist/es5/utils/copy-style.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/encryptor.js +0 -58
- package/node_modules/exceljs/dist/es5/utils/encryptor.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/iterate-stream.js +0 -46
- package/node_modules/exceljs/dist/es5/utils/iterate-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/parse-sax.js +0 -47
- package/node_modules/exceljs/dist/es5/utils/parse-sax.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/shared-formula.js +0 -42
- package/node_modules/exceljs/dist/es5/utils/shared-formula.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/shared-strings.js +0 -32
- package/node_modules/exceljs/dist/es5/utils/shared-strings.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stream-base64.js +0 -66
- package/node_modules/exceljs/dist/es5/utils/stream-base64.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stream-buf.js +0 -343
- package/node_modules/exceljs/dist/es5/utils/stream-buf.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/string-buf.js +0 -73
- package/node_modules/exceljs/dist/es5/utils/string-buf.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/string-builder.js +0 -32
- package/node_modules/exceljs/dist/es5/utils/string-builder.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js +0 -61
- package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/typed-stack.js +0 -23
- package/node_modules/exceljs/dist/es5/utils/typed-stack.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/under-dash.js +0 -168
- package/node_modules/exceljs/dist/es5/utils/under-dash.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/utils.js +0 -171
- package/node_modules/exceljs/dist/es5/utils/utils.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/xml-stream.js +0 -151
- package/node_modules/exceljs/dist/es5/utils/xml-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/zip-stream.js +0 -79
- package/node_modules/exceljs/dist/es5/utils/zip-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js +0 -230
- package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/rel-type.js +0 -18
- package/node_modules/exceljs/dist/es5/xlsx/rel-type.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js +0 -139
- package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js +0 -85
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +0 -24
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js +0 -234
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js +0 -103
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js +0 -76
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +0 -97
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js +0 -107
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js +0 -92
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js +0 -93
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js +0 -112
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js +0 -158
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js +0 -23
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js +0 -65
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +0 -62
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js +0 -82
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js +0 -98
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +0 -59
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +0 -63
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js +0 -67
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +0 -62
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js +0 -91
- package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js +0 -451
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +0 -275
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +0 -25
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +0 -45
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +0 -77
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +0 -42
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +0 -71
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +0 -43
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +0 -88
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +0 -52
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +0 -43
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +0 -75
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +0 -66
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js +0 -78
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js +0 -247
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +0 -69
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js +0 -126
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +0 -50
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +0 -26
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js +0 -52
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +0 -24
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js +0 -46
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js +0 -99
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js +0 -45
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +0 -37
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js +0 -128
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +0 -83
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +0 -84
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +0 -190
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js +0 -513
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js +0 -58
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +0 -98
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js +0 -92
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js +0 -99
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js +0 -114
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js +0 -39
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js +0 -139
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js +0 -185
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js +0 -66
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js +0 -106
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js +0 -308
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js +0 -175
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js +0 -59
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js +0 -118
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js +0 -612
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js +0 -46
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js +0 -75
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js +0 -89
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js +0 -42
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js +0 -123
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xlsx.js +0 -697
- package/node_modules/exceljs/dist/es5/xlsx/xlsx.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js +0 -5
- package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js.map +0 -1
- package/node_modules/exceljs/dist/exceljs.bare.js +0 -55253
- package/node_modules/exceljs/dist/exceljs.bare.js.map +0 -761
- package/node_modules/exceljs/dist/exceljs.bare.min.js +0 -45
- package/node_modules/exceljs/dist/exceljs.bare.min.js.map +0 -1
- package/node_modules/exceljs/dist/exceljs.js +0 -59900
- package/node_modules/exceljs/dist/exceljs.js.map +0 -1083
- package/node_modules/exceljs/dist/exceljs.min.js +0 -45
- package/node_modules/exceljs/dist/exceljs.min.js.map +0 -1
- package/scripts/ai-page-render-check.mjs +0 -532
- package/scripts/clearances-render-check.mjs +0 -480
- package/scripts/composer-render-check.mjs +0 -1027
- package/scripts/deploy-test.sh +0 -309
- package/scripts/home-render-check.mjs +0 -526
- package/scripts/portal-lifecycle-check.mjs +0 -639
package/bin/onboard.mjs
CHANGED
|
@@ -64,11 +64,16 @@ import { stdin as input, stdout as output } from "node:process";
|
|
|
64
64
|
import { accessSync, constants, copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, chmodSync } from "node:fs"; // read the process table here; moved that to shared/process-table.mjs
|
|
65
65
|
import { homedir, userInfo } from "node:os";
|
|
66
66
|
import { invocationPrefix } from "../shared/invocation.mjs"; // — one rule for how the reader invokes us
|
|
67
|
+
import { nodeFloorVerdict } from "../shared/node-floor.mjs"; // — the floor is package.json engines, not a constant here
|
|
67
68
|
import { invocationForm } from "../shared/invocation.mjs"; // — and WHY that form
|
|
68
69
|
import { standFrom } from "../shared/invocation.mjs"; // is this tree one npm replaces?
|
|
69
70
|
import { installShim } from "../shared/verb-shim.mjs"; // — the verb goes on PATH
|
|
70
71
|
import { styleFor, banner } from "../shared/tty-style.mjs"; // — weight where the meaning is
|
|
71
|
-
import { bracketAsciiCells } from "../shared/brand.mjs"; // F18 — the mark, from the geometry the SVG already uses
|
|
72
|
+
import { bracketAsciiCells, BRAND } from "../shared/brand.mjs"; // F18 — the mark, from the geometry the SVG already uses
|
|
73
|
+
// ONE CLASSIFIER, shared with `bin/start.mjs`. The wizard asks the question; the launcher enforces the
|
|
74
|
+
// answer. Two copies of "what does this domain admit" is a wizard that consents to one rule and a
|
|
75
|
+
// launcher that builds another.
|
|
76
|
+
import { classifyStaffDomain, domainOfEmail, staffDomainRefusal, staffGrantSentence } from "../shared/staff-domain.mjs";
|
|
72
77
|
import { join, dirname, isAbsolute, resolve } from "node:path";
|
|
73
78
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
74
79
|
import { delimiter } from "node:path";
|
|
@@ -121,7 +126,6 @@ const ENV_PATH = envLocalPath({ repoRoot: REPO }); // resolved, never composed
|
|
|
121
126
|
// command is applying. Writes stay on ENV_PATH: a writer that followed the file backwards would keep an
|
|
122
127
|
// install in the directory npm replaces forever.
|
|
123
128
|
const READ_ENV_PATH = () => activeEnvPath({ repoRoot: REPO });
|
|
124
|
-
const NODE_FLOOR = 22;
|
|
125
129
|
|
|
126
130
|
const argv = process.argv.slice(2);
|
|
127
131
|
const has = (n) => argv.includes(n);
|
|
@@ -133,7 +137,7 @@ const PROBE_ENGINE = has("--probe-engine");
|
|
|
133
137
|
// issue 1871 — the same opt-in shape, for the credentials that had no proof at all. Never implied by
|
|
134
138
|
// a plain --check: this SPENDS, and on two of the register adapters the count IS a billable search.
|
|
135
139
|
const PROBE_PROVIDERS = has("--probe-providers");
|
|
136
|
-
//
|
|
140
|
+
// the same opt-in shape again, and this one WRITES: every registration it gets
|
|
137
141
|
// accepted CREATES an OAuth client on the operator's account. `doctor` promises in INSTALL.md that it
|
|
138
142
|
// writes nothing, and that promise is why a reader runs it on a production box without thinking. So
|
|
139
143
|
// this is never implied, it says what it is about to create before it creates it, and it reports what
|
|
@@ -141,7 +145,7 @@ const PROBE_PROVIDERS = has("--probe-providers");
|
|
|
141
145
|
const PROBE_CONNECTOR = has("--probe-connector");
|
|
142
146
|
|
|
143
147
|
// ── output ───────────────────────────────────────────────────────────────────────────────────────────
|
|
144
|
-
// WEIGHT WHERE THE MEANING IS (
|
|
148
|
+
// WEIGHT WHERE THE MEANING IS (owner ruling 2026-08-31). Every line here used to
|
|
145
149
|
// be the same weight, which is why the passphrase and the coverage reason both disappeared into their
|
|
146
150
|
// surroundings — two defects on that issue that are formatting defects wearing other clothes.
|
|
147
151
|
//
|
|
@@ -587,6 +591,80 @@ export const AMBIENT_KEYS = [
|
|
|
587
591
|
// ── helpers ──────────────────────────────────────────────────────────────────────────────────────────
|
|
588
592
|
const present = (v) => typeof v === "string" && v.trim() !== "";
|
|
589
593
|
|
|
594
|
+
/**
|
|
595
|
+
* Ask who signs in, and take a real yes for the access rule that address implies.
|
|
596
|
+
*
|
|
597
|
+
* ── WHY THIS QUESTION EXISTS AT ALL ─────────────────────────────────────────────────────────────────
|
|
598
|
+
*
|
|
599
|
+
* Setup never asked for an address. `clearotron start` therefore took one from `--user`, from
|
|
600
|
+
* `PORTAL_LOCAL_USER`, or from the local account as `<account>@localhost` — and derived a STAFF RULE
|
|
601
|
+
* from everything after its `@`. On the local-account default that rule is `localhost`: one machine,
|
|
602
|
+
* one identity, nothing granted to anyone. Given a real address it is that address's whole domain, and
|
|
603
|
+
* the settings page then reports it back as "Anyone at <domain> — a rule, not a person".
|
|
604
|
+
*
|
|
605
|
+
* An outside install reached exactly that state. Nobody typed the address into this wizard, because
|
|
606
|
+
* this wizard had no prompt for it; an assistant filled one into the environment file on the operator's
|
|
607
|
+
* behalf, and the install granted a documentation domain. They read their own settings page and
|
|
608
|
+
* reported it as a back door. They were right to: a grant to a group had been made, by nobody.
|
|
609
|
+
*
|
|
610
|
+
* So the address is asked for here, where a person is definitionally present, and the grant it implies
|
|
611
|
+
* is shown in the words the settings page uses BEFORE it is written. `start` no longer guesses: it
|
|
612
|
+
* refuses a rule wider than one machine unless `PORTAL_STAFF_DOMAINS` says so in writing, which is what
|
|
613
|
+
* a yes here writes.
|
|
614
|
+
*
|
|
615
|
+
* THE DEFAULT IS THE LOCAL ACCOUNT AND NOTHING ELSE — not the git author, not the hostname, not a shell
|
|
616
|
+
* variable. An identity that becomes an access rule comes from the person, or from the one source that
|
|
617
|
+
* cannot name a second person.
|
|
618
|
+
*
|
|
619
|
+
* `io` IS INJECTED for the reason `offerUsptoSync`'s is: the branch that matters is the one where a
|
|
620
|
+
* reader pressed Enter at the grant question and NOTHING must be granted, and closed over a terminal
|
|
621
|
+
* that branch is asserted nowhere. Returns the `.env` keys to write and nothing else.
|
|
622
|
+
*/
|
|
623
|
+
export async function askSignIn(io, { localAccount = "user", staffLabel = "Staff", envPath = "" } = {}) {
|
|
624
|
+
const { askValue, confirm, say = () => {}, ok = () => {}, info = () => {},
|
|
625
|
+
warn = () => {}, problem = () => {} } = io;
|
|
626
|
+
const localDefault = `${localAccount}@localhost`;
|
|
627
|
+
prose("The portal admits one address on this install, and that address is also what decides who is an",
|
|
628
|
+
"administrator. Enter accepts the local-account form, which is this machine and nobody else.");
|
|
629
|
+
for (;;) {
|
|
630
|
+
const typed = String(await askValue("Sign-in address:", { def: localDefault })).trim().toLowerCase();
|
|
631
|
+
if (!typed.includes("@") || typed.indexOf("@") !== typed.lastIndexOf("@")) {
|
|
632
|
+
problem(`"${typed}" is not a single email address. The portal refuses a multi-@ identity outright, `
|
|
633
|
+
+ "so this would sign in and then be denied at the door.");
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
const domain = domainOfEmail(typed);
|
|
637
|
+
const verdict = classifyStaffDomain(domain);
|
|
638
|
+
if (verdict === "public" || verdict === "reserved") {
|
|
639
|
+
// The classifier's own sentence, never a second copy: `clearotron start` prints these same words
|
|
640
|
+
// when it meets the same domain, and two wordings of one refusal is how a reader comes to believe
|
|
641
|
+
// they have met two different problems.
|
|
642
|
+
problem(staffDomainRefusal(domain));
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
if (verdict === "narrow") {
|
|
646
|
+
ok(`${typed} — this machine only. No domain rule is written, and nobody else is granted anything.`);
|
|
647
|
+
return { PORTAL_LOCAL_USER: typed };
|
|
648
|
+
}
|
|
649
|
+
// `wide`: a real domain, so the grant is a grant. Stated first, in the settings page's own words,
|
|
650
|
+
// and Enter is NOT a yes — the default is no, because this is the one answer in the wizard that
|
|
651
|
+
// admits people the reader has never met.
|
|
652
|
+
say("");
|
|
653
|
+
warn(`${typed} makes this a rule about ${domain}, not about you.`);
|
|
654
|
+
say(` ${staffGrantSentence(domain, { staffLabel })}`);
|
|
655
|
+
say("");
|
|
656
|
+
say(` Everyone at ${domain} who gets past this install's sign-in door would see every brand owner`);
|
|
657
|
+
say(" on it — every clearance, every report, every configuration. On a laptop that is only you,");
|
|
658
|
+
say(" because only one address can sign in. Behind a company login it is the whole domain.");
|
|
659
|
+
say("");
|
|
660
|
+
if (await confirm(`Grant ${domain} that, and write it down as PORTAL_STAFF_DOMAINS?`, false))
|
|
661
|
+
return { PORTAL_LOCAL_USER: typed, PORTAL_STAFF_DOMAINS: domain };
|
|
662
|
+
info(`nothing granted${envPath ? `, and nothing written to ${envPath}` : ""}. ${typed} would sign in `
|
|
663
|
+
+ "and every page would refuse it, because signing in is not being enrolled — so choose the "
|
|
664
|
+
+ "local-account form, or answer yes above.");
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
590
668
|
/**
|
|
591
669
|
* An engine binary, resolved the way the engine resolves it — and the trap that resolution carries.
|
|
592
670
|
*
|
|
@@ -693,8 +771,8 @@ export async function preflightCandidate(candidate) {
|
|
|
693
771
|
/** Ask EUIPO for a token. This is the check that makes "refuses to persist a bad secret" true. */
|
|
694
772
|
export async function validateEuipo({ clientId, clientSecret, environment }) {
|
|
695
773
|
try {
|
|
696
|
-
const { resolveConfig } = await import(join(REPO, "providers", "euipo", "src", "core.js"));
|
|
697
|
-
const { getAccessToken } = await import(join(REPO, "providers", "euipo", "src", "euipo-client.js"));
|
|
774
|
+
const { resolveConfig } = await import(pathToFileURL(join(REPO, "providers", "euipo", "src", "core.js")).href);
|
|
775
|
+
const { getAccessToken } = await import(pathToFileURL(join(REPO, "providers", "euipo", "src", "euipo-client.js")).href);
|
|
698
776
|
await getAccessToken(resolveConfig({ clientId, clientSecret, environment }), { force: true });
|
|
699
777
|
return { ok: true };
|
|
700
778
|
} catch (e) {
|
|
@@ -705,7 +783,7 @@ export async function validateEuipo({ clientId, clientSecret, environment }) {
|
|
|
705
783
|
/** One minimal Perplexity call. Costs a request, so it is never made without being asked for. */
|
|
706
784
|
export async function validatePerplexity(apiKey) {
|
|
707
785
|
try {
|
|
708
|
-
const { buildRequestBody, callAgentAPI } = await import(join(REPO, "providers", "perplexity", "src", "core.js"));
|
|
786
|
+
const { buildRequestBody, callAgentAPI } = await import(pathToFileURL(join(REPO, "providers", "perplexity", "src", "core.js")).href);
|
|
709
787
|
await callAgentAPI(apiKey, buildRequestBody({ task: "Reply with the single word: ok.", preset: "fast-search" }), { retries: 0 });
|
|
710
788
|
return { ok: true };
|
|
711
789
|
} catch (e) {
|
|
@@ -998,9 +1076,9 @@ export async function runCheck() {
|
|
|
998
1076
|
}
|
|
999
1077
|
|
|
1000
1078
|
say("\n Node");
|
|
1001
|
-
const
|
|
1002
|
-
if (
|
|
1003
|
-
else problem(`node ${
|
|
1079
|
+
const nodeV = nodeFloorVerdict();
|
|
1080
|
+
if (nodeV.ok) ok(`node ${nodeV.current}`);
|
|
1081
|
+
else problem(`node ${nodeV.current} — this engine needs ${nodeV.required} or newer; node:sqlite is not a built-in module before then`);
|
|
1004
1082
|
|
|
1005
1083
|
// Read the file up here rather than at the `.env` heading below: the engine section is the first that
|
|
1006
1084
|
// needs `effective()`, and which ENGINE is configured decides which binary variable to check. Reading
|
|
@@ -1053,7 +1131,7 @@ export async function runCheck() {
|
|
|
1053
1131
|
// deliberate — a second reader would drift from this one exactly as the composer and the checker did
|
|
1054
1132
|
// in F41, and the drift is invisible because both sides keep passing their own arms.
|
|
1055
1133
|
const unitDir = join(homedir(), ".config", "systemd", "user");
|
|
1056
|
-
const { BACKGROUND_UNITS } = await import(join(REPO, "bin", "start.mjs"));
|
|
1134
|
+
const { BACKGROUND_UNITS } = await import(pathToFileURL(join(REPO, "bin", "start.mjs")).href);
|
|
1057
1135
|
const hosted = BACKGROUND_UNITS.some((u) => existsSync(join(unitDir, u)));
|
|
1058
1136
|
const unitEnv = hosted
|
|
1059
1137
|
? unitEnvironment({
|
|
@@ -1166,8 +1244,48 @@ export async function runCheck() {
|
|
|
1166
1244
|
+ "and the MCP connection are live right now; `npm run example` needs no engine.");
|
|
1167
1245
|
info(`To leave demo: install ${engSpec.vendor}'s CLI (\`${engSpec.fallback}\`), then ${engSpec.signIn}.`);
|
|
1168
1246
|
} else {
|
|
1169
|
-
info("
|
|
1170
|
-
+ "
|
|
1247
|
+
info("The engine program is installed. Whether it is signed in cannot be read from disk: run "
|
|
1248
|
+
+ "clearotron doctor --probe-engine to find out.");
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
// AND WHETHER THE ENGINE AGREES, which is a different question from the one above and the reason an
|
|
1252
|
+
// outside user gave up on this product. This command reads its OWN environment; the portal's New
|
|
1253
|
+
// clearance screen reads what the engine recorded when it last started. Both were right and they
|
|
1254
|
+
// said opposite things, so a reader who checked the confident-looking one first was told the engine
|
|
1255
|
+
// was fine while no search would start. Reported here in the same words the configuration page uses,
|
|
1256
|
+
// because a doctor that cannot see a contradiction the product ships with is the wrong doctor.
|
|
1257
|
+
try {
|
|
1258
|
+
const { readFlagSnapshot, postureDisagreement } = await import("../driver/flag-snapshot.mjs");
|
|
1259
|
+
// THE READ-SIDE ACCESSOR, because this is a read: `config.poolRoot` throws on a box with no pool
|
|
1260
|
+
// configured, and `readFlagSnapshot(null)` already answers "no capture" for exactly that case.
|
|
1261
|
+
const snap = readFlagSnapshot(config.poolRootOrNull);
|
|
1262
|
+
const rows = snap
|
|
1263
|
+
? postureDisagreement(snap, { flags: {}, engine: engineInventory(invEnv) })
|
|
1264
|
+
: null;
|
|
1265
|
+
// NULL IS NOT AGREEMENT and neither is an empty pool — a box with no capture has nothing to
|
|
1266
|
+
// disagree with, and saying so beats printing a clean bill nobody measured.
|
|
1267
|
+
const clash = (rows ?? []).find((r) => r.what === "engine program");
|
|
1268
|
+
if (clash) {
|
|
1269
|
+
problem(`The engine that last ran and this machine disagree about the engine program: the last run `
|
|
1270
|
+
+ `recorded it as ${clash.capture}, this machine reads it as ${clash.live}. A NEW search will `
|
|
1271
|
+
+ `refuse while that is true. Restart the engine service so it re-reads its PATH, or install the `
|
|
1272
|
+
+ `CLI where the service can see it.`);
|
|
1273
|
+
}
|
|
1274
|
+
} catch (e) {
|
|
1275
|
+
// WHAT ACTUALLY REACHES THIS CATCH, established by driving it rather than by reading it.
|
|
1276
|
+
//
|
|
1277
|
+
// Not a box with no pool: `poolRootOrNull` answers null and `readFlagSnapshot(null)` answers null,
|
|
1278
|
+
// neither throwing. And NOT an unreadable capture either — `readFlagSnapshot` has its own try and
|
|
1279
|
+
// returns null for a corrupt file, so a damaged capture is already indistinguishable from an absent
|
|
1280
|
+
// one by the time this code sees it. That is worth knowing and is not this change's to fix.
|
|
1281
|
+
//
|
|
1282
|
+
// So this catch covers an import that has broken or an unexpected throw out of the comparison —
|
|
1283
|
+
// the check having stopped running. A doctor silent about its own failure is the defect the rest of
|
|
1284
|
+
// this change is about, an absence rendered as a clean bill, so it says so. A caution rather than a
|
|
1285
|
+
// problem: the engine may be perfectly fine and it is this check that is broken.
|
|
1286
|
+
info(`Could not compare this machine against what the engine last recorded (${e?.message ?? e}). `
|
|
1287
|
+
+ `That comparison is what catches a settings page reading healthy while a search will not start, `
|
|
1288
|
+
+ `so this run has not checked it either way.`);
|
|
1171
1289
|
}
|
|
1172
1290
|
|
|
1173
1291
|
// item 5 — WHICH BILLING LANE, reported rather than left to be inferred from a variable's
|
|
@@ -1188,8 +1306,8 @@ export async function runCheck() {
|
|
|
1188
1306
|
if (e) envForResolve[k] = e.v;
|
|
1189
1307
|
}
|
|
1190
1308
|
const auth = resolveAuthMode({ engineName: engineId, env: envForResolve });
|
|
1191
|
-
if (auth.mode === "unknown") info(`billing
|
|
1192
|
-
else ok(`billing
|
|
1309
|
+
if (auth.mode === "unknown") info(`billing: no policy for ${engineId} — this engine declares no sign-in modes`);
|
|
1310
|
+
else ok(`billing: ${auth.mode}${auth.apiBilled ? ` — charged per token against ${engSpec.apiKeyEnv}` : " — charged to the signed-in subscription, not per token"}`);
|
|
1193
1311
|
} catch (e) {
|
|
1194
1312
|
problem(String(e?.message ?? e));
|
|
1195
1313
|
}
|
|
@@ -1366,7 +1484,7 @@ export async function runCheck() {
|
|
|
1366
1484
|
// Both lines were honest about their own source and neither said what it was. The first reads this
|
|
1367
1485
|
// command's env file; the second reads THIS PROCESS's resolution, and a CLI is started by a login
|
|
1368
1486
|
// shell that carries none of the units' `EnvironmentFile`. The deployment was correct and served
|
|
1369
|
-
//
|
|
1487
|
+
// the configured roster throughout.
|
|
1370
1488
|
//
|
|
1371
1489
|
// THE UNITS' ENV IS NOT PASSED INTO `profileStoreResolution`, deliberately. `PROFILES_OVERLAY_DIR`
|
|
1372
1490
|
// is captured when profiles.mjs LOADS, so handing it the units' value would set `live` with no
|
|
@@ -1418,17 +1536,38 @@ export async function runCheck() {
|
|
|
1418
1536
|
const demo = keys.filter((k) => roster.get(k)?.demoData === true);
|
|
1419
1537
|
// `generic` is the universal fallback the module requires by name, not a brand owner somebody
|
|
1420
1538
|
// onboarded — counting it would tell an operator with an empty store that they have one.
|
|
1421
|
-
|
|
1539
|
+
//
|
|
1540
|
+
// A DEMO ACCOUNT IS NOT AN ONBOARDED OWNER EITHER, and until this line it was counted as one. A
|
|
1541
|
+
// fresh install used to ship the demo account into every roster, so `doctor` reported "1 brand
|
|
1542
|
+
// owner(s) resolve here: demo-brand-owner (DEMO DATA)" on a machine where nobody had onboarded
|
|
1543
|
+
// anything — and never named `generic`, which is the account that actually rates a run there.
|
|
1544
|
+
// The reader is told they have a customer and not told what they are running on. Both halves
|
|
1545
|
+
// wrong from one list.
|
|
1546
|
+
//
|
|
1547
|
+
// SINCE 2026-09-08 A FRESH INSTALL RESOLVES `generic` ALONE (owner ruling): nobody should have to
|
|
1548
|
+
// clean demo material out of an environment they just created. So the demo branch below no longer
|
|
1549
|
+
// fires on a plain install — it fires inside the demo, which asks for its own account. It is kept
|
|
1550
|
+
// rather than deleted because it is still reachable, and a reader who meets the demo account
|
|
1551
|
+
// there is owed the same two facts: it is fiction, and a real clearance under it is refused at
|
|
1552
|
+
// the admission wall.
|
|
1553
|
+
//
|
|
1554
|
+
// Three states, told apart, because they mean three different things to whoever is reading:
|
|
1555
|
+
// an onboarded roster, the house default alone, and the house default beside what the demo
|
|
1556
|
+
// brought with it.
|
|
1557
|
+
const owners = keys.filter((k) => k !== "generic" && !demo.includes(k));
|
|
1422
1558
|
if (!owners.length) {
|
|
1423
|
-
|
|
1424
|
-
+
|
|
1559
|
+
const base = "`generic` is the account this install rates under — the house default, and the "
|
|
1560
|
+
+ "only one a clean install has";
|
|
1561
|
+
if (demo.length) {
|
|
1562
|
+
info(`${base}. The demo brought one with it, marked DEMO DATA: ${demo.join(", ")} — fiction `
|
|
1563
|
+
+ "rather than an account anybody onboarded, and a real clearance under one is refused");
|
|
1564
|
+
} else {
|
|
1565
|
+
info(`${base}. An empty store is a working install on Generic defaults; it is also what a `
|
|
1566
|
+
+ "store pointed at the wrong directory looks like");
|
|
1567
|
+
}
|
|
1425
1568
|
} else {
|
|
1426
|
-
const
|
|
1427
|
-
|
|
1428
|
-
// The demo marker is the member-level half: naming the store is not the
|
|
1429
|
-
// same as saying the accounts in it are fiction, and a real clearance under one is refused at
|
|
1430
|
-
// the admission wall — which an operator should learn here rather than from that refusal.
|
|
1431
|
-
if (demo.length) info(`${line} — accounts marked DEMO DATA cannot start a real clearance`);
|
|
1569
|
+
const line = `${owners.length} brand owner(s) resolve here: ${owners.join(", ")}`;
|
|
1570
|
+
if (demo.length) info(`${line}. The demo brought one with it, marked DEMO DATA: ${demo.join(", ")} — not counted above, and a real clearance under one is refused`);
|
|
1432
1571
|
else ok(line);
|
|
1433
1572
|
}
|
|
1434
1573
|
try {
|
|
@@ -1513,7 +1652,7 @@ export async function runCheck() {
|
|
|
1513
1652
|
//
|
|
1514
1653
|
// REPORTS, NEVER JUDGES: nothing here sets `problem()`. Drift is information for the reader, not a
|
|
1515
1654
|
// fault in their install, and a doctor that called their own overrides broken would be wrong.
|
|
1516
|
-
say("\n
|
|
1655
|
+
say("\n Custom instructions");
|
|
1517
1656
|
try {
|
|
1518
1657
|
const report = overlayReport({ baseRoot: config.skillsBaseDir, overlayRoot: config.skillsOverlayDir });
|
|
1519
1658
|
for (const line of renderOverlayReport(report, { indent: "" })) say(` ${line}`);
|
|
@@ -1528,7 +1667,7 @@ export async function runCheck() {
|
|
|
1528
1667
|
// answer for somebody running the engine by hand. This line is what the services see.
|
|
1529
1668
|
const svcDoctrine = effectiveForService("CLEAROTRON_INSTRUCTIONS_DIR");
|
|
1530
1669
|
if (hosted && serviceKnown && svcDoctrine?.v && svcDoctrine.v !== config.skillsOverlayDir) {
|
|
1531
|
-
info(`the services read
|
|
1670
|
+
info(`the services read custom instructions this process does not: ${svcDoctrine.v} `
|
|
1532
1671
|
+ `(${svcDoctrine.from}). The lines above are this command's own environment — a CLI is not `
|
|
1533
1672
|
+ "started by the units' EnvironmentFile, so \"none configured\" here is not a statement about "
|
|
1534
1673
|
+ "the deployment");
|
|
@@ -1541,7 +1680,7 @@ export async function runCheck() {
|
|
|
1541
1680
|
// An unreadable overlay THROWS by design (config.resolveSkillPath refuses rather than falling back
|
|
1542
1681
|
// to the product's copy). Surfaced here rather than allowed to abort the whole check: the doctor's
|
|
1543
1682
|
// job is to report every section, and a section that kills the run tells the reader least.
|
|
1544
|
-
problem(`the
|
|
1683
|
+
problem(`the custom instructions could not be read — ${e.message}`);
|
|
1545
1684
|
}
|
|
1546
1685
|
|
|
1547
1686
|
say("\n Register provider");
|
|
@@ -1585,7 +1724,7 @@ export async function runCheck() {
|
|
|
1585
1724
|
say("\n Research provider");
|
|
1586
1725
|
const px = effective("PERPLEXITY_API_KEY");
|
|
1587
1726
|
if (px) ok(`PERPLEXITY_API_KEY present (${px.from}) — presence only; add --probe-providers to prove it answers`);
|
|
1588
|
-
else info("PERPLEXITY_API_KEY is not set — the three clearance searches carry the common-law grid and cannot switch it off, so a clearance
|
|
1727
|
+
else info("PERPLEXITY_API_KEY is not set — the three clearance searches carry the common-law grid and cannot switch it off, so a clearance stops before it starts, and names the missing key; a Knockout search still runs and discloses the half it skipped");
|
|
1589
1728
|
|
|
1590
1729
|
// ── — THE LANES A PRODUCT DECLARES IT NEEDS, BEFORE A REPORT NAMES THEM ──
|
|
1591
1730
|
//
|
|
@@ -1663,7 +1802,7 @@ export async function runCheck() {
|
|
|
1663
1802
|
// could print, and the portal's own config view does — is deliberately not printed here: `doctor` goes
|
|
1664
1803
|
// to a terminal, into a paste, into an issue.
|
|
1665
1804
|
// THE ONE CONDITION THAT STOPS THE PORTAL RENDERING, and `doctor` said nothing about it at all
|
|
1666
|
-
// (
|
|
1805
|
+
// (found in review). `portal-ui/dist` is committed, so an absent bundle means a bad checkout on
|
|
1667
1806
|
// a deployment and an unbuilt tree on a source clone; the service already answers 503 and says so in
|
|
1668
1807
|
// its boot log, but a reader who runs `doctor` BEFORE `start` — which is the order every document
|
|
1669
1808
|
// gives — had no way to learn it. The product's OWN predicate decides rather than a second existence
|
|
@@ -1770,7 +1909,7 @@ export async function runCheck() {
|
|
|
1770
1909
|
}
|
|
1771
1910
|
}
|
|
1772
1911
|
|
|
1773
|
-
say("\n Portal
|
|
1912
|
+
say("\n Portal sign-in");
|
|
1774
1913
|
{
|
|
1775
1914
|
const { authView } = await import("../driver/portal-config-view.mjs");
|
|
1776
1915
|
const door = authView({
|
|
@@ -1785,10 +1924,11 @@ export async function runCheck() {
|
|
|
1785
1924
|
// NOT A TICK, AND THAT IS THE POINT. This reads the environment THIS command is
|
|
1786
1925
|
// typed in. `bin/start.mjs` INJECTS `PORTAL_AUTH_MODE: "local"` into the portal's own environment,
|
|
1787
1926
|
// and a systemd unit's EnvironmentFile can name a third thing — so a green tick here was a
|
|
1788
|
-
// confident claim about a door the running service may not be serving. Measured on the test
|
|
1789
|
-
// doctor said `auth-proxy door (PORTAL_AUTH_MODE is
|
|
1790
|
-
// cf-access, and said `local passphrase door` with a
|
|
1791
|
-
// green, neither the door a caller meets.
|
|
1927
|
+
// confident claim about a door the running service may not be serving. Measured on the test
|
|
1928
|
+
// machine, in the wording doctor used at the time: it said `auth-proxy door (PORTAL_AUTH_MODE is
|
|
1929
|
+
// unset)` with a tick while the machine served cf-access, and said `local passphrase door` with a
|
|
1930
|
+
// tick while it still served cf-access. Both green, neither the door a caller meets. Those two
|
|
1931
|
+
// lines read differently now; what they claimed is the point, not how they were worded.
|
|
1792
1932
|
//
|
|
1793
1933
|
// The reading is still worth printing — it is what a hand-run process here would use, and it is
|
|
1794
1934
|
// what `clearotron start` would launch from. It is stated as that, and the sentence below says
|
|
@@ -1808,7 +1948,7 @@ export async function runCheck() {
|
|
|
1808
1948
|
say(` · local passphrase door (${typed}) — one operator, one passphrase, no identity provider`);
|
|
1809
1949
|
info(`a lost passphrase is recoverable: ${invocationPrefix()}clearotron passphrase --reset`);
|
|
1810
1950
|
} else if (door.shape === "fronted") {
|
|
1811
|
-
say(` ·
|
|
1951
|
+
say(` · Sign-in: handled by a proxy in front (${typed}) — identity is proved by whatever sits in front, and this process trusts it`);
|
|
1812
1952
|
for (const v of door.proxyValues) {
|
|
1813
1953
|
if (v.present) ok(` ${v.name} present`);
|
|
1814
1954
|
else info(` ${v.name} not set`);
|
|
@@ -1908,8 +2048,8 @@ export async function runCheck() {
|
|
|
1908
2048
|
say("\n Register lane — proven, not inferred");
|
|
1909
2049
|
try {
|
|
1910
2050
|
const [{ activeProvider }, { makeLaneProbe, probeSpend, DEFAULT_CONTROLS, loadProviderCapabilities }] = await Promise.all([
|
|
1911
|
-
import(join(REPO, "driver", "driver.config.mjs")),
|
|
1912
|
-
import(join(REPO, "providers", "_shared", "lane-probe.mjs")),
|
|
2051
|
+
import(pathToFileURL(join(REPO, "driver", "driver.config.mjs")).href),
|
|
2052
|
+
import(pathToFileURL(join(REPO, "providers", "_shared", "lane-probe.mjs")).href),
|
|
1913
2053
|
]);
|
|
1914
2054
|
const adapter = activeProvider();
|
|
1915
2055
|
// NOT `adapter.capabilities` — that is null on every adapter, and reading it announced a LOCAL
|
|
@@ -1952,7 +2092,7 @@ export async function runCheck() {
|
|
|
1952
2092
|
}
|
|
1953
2093
|
}
|
|
1954
2094
|
|
|
1955
|
-
say("\n
|
|
2095
|
+
say("\n Where files are stored");
|
|
1956
2096
|
// Each entry is a FUNCTION, called only on the branch that prints it, so a getter is read at access
|
|
1957
2097
|
// time and never captured as a constant here. The reader of this command is deciding what to
|
|
1958
2098
|
// provision; a default quoted from memory is the one thing that can send them to the wrong path and
|
|
@@ -1963,7 +2103,7 @@ export async function runCheck() {
|
|
|
1963
2103
|
// whole rather than summarised: a summary is a second copy, and a second copy is what drifted.
|
|
1964
2104
|
["CLEAROTRON_REPORTS_DIR", (name) => {
|
|
1965
2105
|
const d = defaultWith(name, () => config.poolRoot);
|
|
1966
|
-
return d.refusal ?? `${name} is not set — the published-
|
|
2106
|
+
return d.refusal ?? `${name} is not set — the published-reports folder falls back to ${d.value}`;
|
|
1967
2107
|
}],
|
|
1968
2108
|
["CLEAROTRON_WORK_DIR", (name) => {
|
|
1969
2109
|
const d = defaultWith(name, () => config.workspaceRoot);
|
|
@@ -1985,67 +2125,6 @@ export async function runCheck() {
|
|
|
1985
2125
|
// The status surface the ruling names: "status should say whether a key is still valid". Stopping
|
|
1986
2126
|
// the door revokes nothing — a key outlives every teardown until it expires or its id is denylisted —
|
|
1987
2127
|
// so a doctor that reported the unit and stayed silent about the keys would bless exactly the state
|
|
1988
|
-
// the issue was filed about. Judged by the verifier's own pieces (`connectKeyReport` takes the real
|
|
1989
|
-
// `isRevoked`), never by a second opinion written here.
|
|
1990
|
-
// ── THE PROFILE STORE RESOLVES, OR THE PORTAL 500s ────────────────────────
|
|
1991
|
-
//
|
|
1992
|
-
// Asked by RUNNING the engine's own resolution, not by re-deriving it: loadProfiles() layers the
|
|
1993
|
-
// configured store over the bundled base with generic falling through by name, and its refusal text
|
|
1994
|
-
// is the exact line the portal prints on every screen when this is broken. A doctor that stayed
|
|
1995
|
-
// green over that state would bless the owner's fresh-install 500.
|
|
1996
|
-
say("\n Profile store");
|
|
1997
|
-
try {
|
|
1998
|
-
const { loadProfiles } = await import(join(REPO, "driver", "profiles.mjs"));
|
|
1999
|
-
const resolved = loadProfiles({ force: true });
|
|
2000
|
-
const named = [...resolved.keys()];
|
|
2001
|
-
ok(`resolves: ${named.length} profile(s) (${named.slice(0, 6).join(", ")}${named.length > 6 ? ", …" : ""}) — the universal fallback is present`);
|
|
2002
|
-
} catch (e) {
|
|
2003
|
-
problem(`the profile store does NOT resolve — every portal profile screen and every run refuses on this: ${e.message}`);
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
// ── THE SUBMIT LANE, WALKED (the owner's 502, 2026-09-02) ────────────────────────────────────────
|
|
2007
|
-
//
|
|
2008
|
-
// Every surface on that box was green while the portal's Start button had no engine to call. This is
|
|
2009
|
-
// the only check that asks the question the client's own path asks, so it goes before the connector
|
|
2010
|
-
// section: a dead submit lane matters more than a connector nobody has configured yet.
|
|
2011
|
-
// ── SETTINGS THIS BUILD DOES NOT READ ( tracker issue 168) ────────────────────────────────────────
|
|
2012
|
-
//
|
|
2013
|
-
// THE SURFACE AN OPERATOR CHECKS AFTER AN UPGRADE, and until now the surface that told them
|
|
2014
|
-
// everything was fine. Upgrading the production install across the `PRELIM_*` rename left thirteen
|
|
2015
|
-
// configured settings with no reader in the new build; doctor exited 0 and mentioned none of them.
|
|
2016
|
-
//
|
|
2017
|
-
// EVERY ENVIRONMENT THE DEPLOYMENT ACTUALLY READS, not this shell's alone — the F34 lesson one step
|
|
2018
|
-
// on. A hosted box's values live in the file the units load, so checking `process.env` here would
|
|
2019
|
-
// pass a box whose units carry thirteen dead lines. Each source is named in its own row: "it is in
|
|
2020
|
-
// your env file" and "it is in the units' environment" are different fixes.
|
|
2021
|
-
//
|
|
2022
|
-
// A source that could not be read is NOT reported as clean. `unitEnvironment` already distinguishes
|
|
2023
|
-
// that, and an unreadable unit environment is said out loud rather than counted as zero dead names —
|
|
2024
|
-
// an absence of evidence is not evidence of absence, and this whole check exists because something
|
|
2025
|
-
// invisible was being read as fine.
|
|
2026
|
-
{
|
|
2027
|
-
const { retiredSpellingsIn, retiredSpellingLine } = await import(join(REPO, "shared", "env-aliases.mjs"));
|
|
2028
|
-
const sources = [
|
|
2029
|
-
{ label: "your environment file", env: fileEnv, known: true },
|
|
2030
|
-
{ label: "this shell's environment", env: process.env, known: true },
|
|
2031
|
-
];
|
|
2032
|
-
if (hosted) sources.push({ label: "the units' environment", env: unitEnv?.env, known: unitEnv?.known === true });
|
|
2033
|
-
|
|
2034
|
-
const seen = new Set();
|
|
2035
|
-
let anyUnknown = false;
|
|
2036
|
-
for (const src of sources) {
|
|
2037
|
-
if (!src.known || !src.env) { if (src.label === "the units' environment") anyUnknown = true; continue; }
|
|
2038
|
-
for (const row of retiredSpellingsIn(src.env)) {
|
|
2039
|
-
// One row per NAME, not per source: a name set in both the file and the units is one thing to
|
|
2040
|
-
// fix, and two rows would read as two faults.
|
|
2041
|
-
if (seen.has(row.name)) continue;
|
|
2042
|
-
seen.add(row.name);
|
|
2043
|
-
inertSetting(`${retiredSpellingLine(row)} (found in ${src.label})`);
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
if (anyUnknown) warn(couldNotDetermine("retired setting names", unitEnv));
|
|
2047
|
-
if (!seen.size && !anyUnknown) ok("no retired setting names — every configured name is one this build reads");
|
|
2048
|
-
}
|
|
2049
2128
|
|
|
2050
2129
|
// LINGERING, WHICH NOTHING ELSE CHECKS ( — F9). `--background` installs USER units,
|
|
2051
2130
|
// and a user manager without lingering is torn down at logout: the units stop with the session and
|
|
@@ -2075,9 +2154,9 @@ export async function runCheck() {
|
|
|
2075
2154
|
+ "failing to look, not a report that it is off.");
|
|
2076
2155
|
}
|
|
2077
2156
|
|
|
2078
|
-
say("\n
|
|
2157
|
+
say("\n Start-button path");
|
|
2079
2158
|
try {
|
|
2080
|
-
const { triggerLaneVerdict, HOSTED, SUPERVISED } = await import(join(REPO, "shared", "trigger-lane.mjs"));
|
|
2159
|
+
const { triggerLaneVerdict, HOSTED, SUPERVISED } = await import(pathToFileURL(join(REPO, "shared", "trigger-lane.mjs")).href);
|
|
2081
2160
|
// POSTURE FROM THE BOX, NOT FROM A FLAG. Units installed means the units serve, and the units read
|
|
2082
2161
|
// %h/.env — so an absent value there is the incident. No units means `start` supervises and derives
|
|
2083
2162
|
// the value at runtime, where reading this process's environment says nothing either way.
|
|
@@ -2117,7 +2196,7 @@ export async function runCheck() {
|
|
|
2117
2196
|
// Stop control's availability on — one reader, two surfaces.
|
|
2118
2197
|
let verbs = null;
|
|
2119
2198
|
try {
|
|
2120
|
-
const { opsTokenPosture } = await import(join(REPO, "driver", "portal-service.mjs"));
|
|
2199
|
+
const { opsTokenPosture } = await import(pathToFileURL(join(REPO, "driver", "portal-service.mjs")).href);
|
|
2121
2200
|
verbs = opsTokenPosture(opsToken).verbs;
|
|
2122
2201
|
} catch { /* unreadable posture leaves verbs null, which reads as full ops — see the verdict */ }
|
|
2123
2202
|
let probe = null;
|
|
@@ -2153,12 +2232,12 @@ export async function runCheck() {
|
|
|
2153
2232
|
} catch (e) { warn(`the submit lane could not be read: ${e.message}`); }
|
|
2154
2233
|
|
|
2155
2234
|
say("\n Client connector");
|
|
2156
|
-
// THE REVOCATION LIST, REPORTED (
|
|
2235
|
+
// THE REVOCATION LIST, REPORTED (found in review). `isRevoked` treats an unreadable
|
|
2157
2236
|
// denylist as "not revoked", so a named-but-absent file makes every revocation silently ineffective:
|
|
2158
2237
|
// measured on a default install, a revoked key completed a full handshake with nothing logged. Nothing
|
|
2159
2238
|
// surfaced that state anywhere, which is why it survived to be found by hand.
|
|
2160
2239
|
{
|
|
2161
|
-
const { defaultDenylistPath } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
2240
|
+
const { defaultDenylistPath } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
2162
2241
|
const dl = effective("TRADEMARK_MCP_TOKEN_DENYLIST")?.v || defaultDenylistPath(homedir());
|
|
2163
2242
|
try {
|
|
2164
2243
|
const n = readFileSync(dl, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).length;
|
|
@@ -2172,8 +2251,8 @@ export async function runCheck() {
|
|
|
2172
2251
|
}
|
|
2173
2252
|
}
|
|
2174
2253
|
try {
|
|
2175
|
-
const { clientDoorState: doorState, describeDoorState, connectKeyReport, CLIENT_DOOR_UNIT: doorUnit } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
2176
|
-
const { loadGrants: readGrantsFile, isRevoked: revokedCheck } = await import(join(REPO, "shared", "scope.mjs"));
|
|
2254
|
+
const { clientDoorState: doorState, describeDoorState, connectKeyReport, CLIENT_DOOR_UNIT: doorUnit } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
2255
|
+
const { loadGrants: readGrantsFile, isRevoked: revokedCheck } = await import(pathToFileURL(join(REPO, "shared", "scope.mjs")).href);
|
|
2177
2256
|
// ── CONFIGURED IS NOT RUNNING, AND THIS IS THE SURFACE IT WAS MEASURED ON ──
|
|
2178
2257
|
//
|
|
2179
2258
|
// `describeDoorState` was written for exactly this block and then never called from it: the split
|
|
@@ -2242,14 +2321,14 @@ export async function runCheck() {
|
|
|
2242
2321
|
const doorEnvKnown = !hosted || unitEnv?.known === true;
|
|
2243
2322
|
const doorEnv = hosted && unitEnv?.known === true ? unitEnv.env : process.env;
|
|
2244
2323
|
if (!doorEnvKnown) warn(couldNotDetermine("CLIENT_MCP_ACCOUNT_ACCESS", unitEnv));
|
|
2245
|
-
// THE PORT AND ITS ALLOW-LIST ARE ONE SETTING, AND NOTHING SAID SO (
|
|
2246
|
-
//
|
|
2324
|
+
// THE PORT AND ITS ALLOW-LIST ARE ONE SETTING, AND NOTHING SAID SO (found in an operator pass).
|
|
2325
|
+
// `start` derives CLIENT_MCP_ALLOWED_HOSTS from the port it resolved, so moving the
|
|
2247
2326
|
// port THROUGH start works. Moving it in the env file the units load does not: the door binds the
|
|
2248
2327
|
// new port and then answers "403 Invalid Host header" on every request, because the allow-list still
|
|
2249
2328
|
// names the old one. A door that is up, listening, and refuses everything is the worst of the three
|
|
2250
2329
|
// states to debug, and nothing surfaced the mismatch.
|
|
2251
2330
|
{
|
|
2252
|
-
const { clientDoorPort: portOf, allowedHosts: hostsFor } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
2331
|
+
const { clientDoorPort: portOf, allowedHosts: hostsFor } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
2253
2332
|
const declared = String(effective("CLIENT_MCP_ALLOWED_HOSTS")?.v ?? "").trim();
|
|
2254
2333
|
if (declared) {
|
|
2255
2334
|
const port = portOf(doorEnv);
|
|
@@ -2265,14 +2344,14 @@ export async function runCheck() {
|
|
|
2265
2344
|
}
|
|
2266
2345
|
}
|
|
2267
2346
|
|
|
2268
|
-
// IS ANYTHING ANSWERING? (
|
|
2347
|
+
// IS ANYTHING ANSWERING? (found in review) The unit file is evidence about the
|
|
2269
2348
|
// background shape only. A foreground `clearotron start` runs the door as its own child with no unit
|
|
2270
2349
|
// at all, and this section then told a reader whose door was listening that it "is not set up here",
|
|
2271
2350
|
// pointing them at the command they had just run. One loopback connect settles it, and null stays
|
|
2272
2351
|
// null — a probe that could not be made is not a door that is absent.
|
|
2273
2352
|
let doorListening = null;
|
|
2274
2353
|
try {
|
|
2275
|
-
const { clientDoorPort: portOf } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
2354
|
+
const { clientDoorPort: portOf } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
2276
2355
|
const { createConnection } = await import("node:net");
|
|
2277
2356
|
doorListening = await new Promise((resolve) => {
|
|
2278
2357
|
const sock = createConnection({ host: "127.0.0.1", port: portOf(doorEnv), timeout: 700 });
|
|
@@ -2307,10 +2386,10 @@ export async function runCheck() {
|
|
|
2307
2386
|
problem("a valid key is on record but NO revocation list is configured (TRADEMARK_MCP_TOKEN_DENYLIST unset) "
|
|
2308
2387
|
+ `— \`${invoke("disconnect")}\` could not actually revoke it. \`${invoke("connect")}\` arms one; set the variable or reconnect.`);
|
|
2309
2388
|
}
|
|
2310
|
-
// THE PUBLISHED ADDRESS, AND WHETHER IT ANSWERS (
|
|
2389
|
+
// THE PUBLISHED ADDRESS, AND WHETHER IT ANSWERS (acceptance 2). Reported here
|
|
2311
2390
|
// rather than beside the unit, because the unit running and the address being reachable are
|
|
2312
2391
|
// different facts and the second is the one a client depends on.
|
|
2313
|
-
const { clientDoorReachability } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
2392
|
+
const { clientDoorReachability } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
2314
2393
|
// FROM THE FILE THE UNITS LOAD, NOT THE SHELL THIS COMMAND WAS TYPED IN (the tracker issue 226
|
|
2315
2394
|
// family, met again here). On a hosted box the published address lives in the units' environment,
|
|
2316
2395
|
// and reading `process.env` reported "no client connector address is published — that is correct
|
|
@@ -2357,7 +2436,7 @@ export async function runCheck() {
|
|
|
2357
2436
|
// No new credential and no provider API: the audience is in the redirect handed to a caller with
|
|
2358
2437
|
// no session at all, which is the request just made.
|
|
2359
2438
|
{
|
|
2360
|
-
const { readAudience, audienceVerdict } = await import(join(REPO, "shared", "access-audience.mjs"));
|
|
2439
|
+
const { readAudience, audienceVerdict } = await import(pathToFileURL(join(REPO, "shared", "access-audience.mjs")).href);
|
|
2361
2440
|
const configuredAud = effectiveForService("CLEAROTRON_OIDC_AUDIENCE")?.v ?? "";
|
|
2362
2441
|
const read = readAudience(probe ?? { error: "the published address was never asked" });
|
|
2363
2442
|
// NOTHING IS CLAIMED ABOUT A BOX THAT USES NO EDGE. With no audience configured AND no Access
|
|
@@ -2370,6 +2449,27 @@ export async function runCheck() {
|
|
|
2370
2449
|
// unreachable; repeating it as a second failure teaches the reader that this section
|
|
2371
2450
|
// double-counts. It still states what was NOT established, which is the whole job.
|
|
2372
2451
|
else if (v.kind === "could-not-look") info(v.message);
|
|
2452
|
+
// NO ACCESS IN FRONT OF THE CLIENT DOOR IS A POSTURE, NOT A FAULT (owner ruling 2026-09-08).
|
|
2453
|
+
//
|
|
2454
|
+
// This is the CLIENT connector's address, and how a client reaches it is the client's decision:
|
|
2455
|
+
// "client access sitting behind OAuth is totally up to a client — plenty might just run it token
|
|
2456
|
+
// based on their own laptop." A door answering with its own Bearer challenge and no Access front
|
|
2457
|
+
// is a supported shape, not a misconfiguration, so raising it made `doctor` exit 1 on a healthy
|
|
2458
|
+
// deployment and taught its reader to skim the one command that must never be skimmed.
|
|
2459
|
+
//
|
|
2460
|
+
// It is still SAID rather than dropped, and it still states what was not established: an
|
|
2461
|
+
// audience that was never compared is not an audience that agreed. What changed is that the
|
|
2462
|
+
// sentence no longer calls a client's own arrangement a finding about this install.
|
|
2463
|
+
//
|
|
2464
|
+
// Scoped deliberately to `not-fronted` on THIS address. A configured audience that DISAGREES
|
|
2465
|
+
// with the one the edge issues is still a fault, and the portal and ops surfaces are untouched —
|
|
2466
|
+
// they are checked elsewhere and Access in front of them is not optional.
|
|
2467
|
+
else if (v.kind === "not-fronted") {
|
|
2468
|
+
info(`nothing is fronting this hostname with Access — ${read.why}. That is this client door's `
|
|
2469
|
+
+ "posture rather than a fault: a client may reach it with its own token and no Access in "
|
|
2470
|
+
+ "front, which is a supported shape. The configured audience was not compared against this "
|
|
2471
|
+
+ "address, so nothing here says the two agree.");
|
|
2472
|
+
}
|
|
2373
2473
|
else problem(v.message);
|
|
2374
2474
|
}
|
|
2375
2475
|
}
|
|
@@ -2383,7 +2483,7 @@ export async function runCheck() {
|
|
|
2383
2483
|
// announces the side effect first, and its control runs before any vendor.
|
|
2384
2484
|
if (PROBE_CONNECTOR && String(published ?? "").trim()) {
|
|
2385
2485
|
const { registrationEndpointFrom, probeRegistration, describeRegistration } =
|
|
2386
|
-
await import(join(REPO, "shared", "connector-signin-probe.mjs"));
|
|
2486
|
+
await import(pathToFileURL(join(REPO, "shared", "connector-signin-probe.mjs")).href);
|
|
2387
2487
|
say("");
|
|
2388
2488
|
say(" --probe-connector: asking this door's sign-in whether each assistant vendor could register.");
|
|
2389
2489
|
say(" Each attempt that SUCCEEDS creates a throwaway OAuth client on your account, which you may");
|
|
@@ -2571,7 +2671,7 @@ try {
|
|
|
2571
2671
|
// is DERIVED: the engines from ENGINE_BINARIES, the search vendors from the same adapter tables the
|
|
2572
2672
|
// prompts loop over, each wearing its own table row's where-to-get line. A hand-kept copy here would
|
|
2573
2673
|
// be the SERPAPI defect again, one screen earlier. Everything is skippable; the list says so.
|
|
2574
|
-
// THE BANNER — once, on entry, named (
|
|
2674
|
+
// THE BANNER — once, on entry, named (owner ruling 2026-08-31). Not on every
|
|
2575
2675
|
// command: a banner every verb prints is how a product becomes tiresome to use twice. It sits here
|
|
2576
2676
|
// rather than at the top of main() so that `--check`, which writes nothing and is run repeatedly,
|
|
2577
2677
|
// does not wear it either.
|
|
@@ -2581,7 +2681,7 @@ try {
|
|
|
2581
2681
|
say("");
|
|
2582
2682
|
say(` ${style.bold("Before you start")} — what this setup can take, so nothing here surprises you:`);
|
|
2583
2683
|
// `vendor`, not `label`: the labels are engineer sentences carrying flag names, and a question a
|
|
2584
|
-
// lawyer reads may not (
|
|
2684
|
+
// lawyer reads may not (the first rule).
|
|
2585
2685
|
say(` · Which AI runs the searches (${Object.values(ENGINE_BINARIES).map((e) => e.vendor).join(" or ")}),`);
|
|
2586
2686
|
say(" and how it bills — the subscription you already sign in with, or an API key.");
|
|
2587
2687
|
say(" · Your trademark register vendor's credential, if you have one (a register can be chosen later).");
|
|
@@ -2594,13 +2694,13 @@ try {
|
|
|
2594
2694
|
|
|
2595
2695
|
// 1 ── Node
|
|
2596
2696
|
say(" Node");
|
|
2597
|
-
const
|
|
2598
|
-
if (
|
|
2599
|
-
problem(`node ${
|
|
2697
|
+
const nodeV = nodeFloorVerdict();
|
|
2698
|
+
if (!nodeV.ok) {
|
|
2699
|
+
problem(`node ${nodeV.current} — this engine needs ${nodeV.required} or newer. Upgrade Node and run setup again.`);
|
|
2600
2700
|
aborted = "node";
|
|
2601
2701
|
throw new Error("node floor");
|
|
2602
2702
|
}
|
|
2603
|
-
ok(`node ${
|
|
2703
|
+
ok(`node ${nodeV.current}`);
|
|
2604
2704
|
|
|
2605
2705
|
// 2 ── the engine: which one, which binary, and PROOF that it can run a turn
|
|
2606
2706
|
//
|
|
@@ -2855,7 +2955,7 @@ try {
|
|
|
2855
2955
|
}
|
|
2856
2956
|
}
|
|
2857
2957
|
}
|
|
2858
|
-
// —
|
|
2958
|
+
// — found in review, and the same trap closed one prompt over. The default
|
|
2859
2959
|
// was YES, so Enter re-ran a probe that CANNOT succeed until the reader has signed in somewhere
|
|
2860
2960
|
// else — and the wizard's own header tells them Enter is the safe key. Driven with Enter it went
|
|
2861
2961
|
// 19 attempts, no cap and no escape, in a wizard whose header says everything here is skippable.
|
|
@@ -3049,7 +3149,7 @@ try {
|
|
|
3049
3149
|
const baseDefault = join(homedir(), "trademark");
|
|
3050
3150
|
prose("Reports, run workspaces, queues and locks all live under one directory.");
|
|
3051
3151
|
if (poolDefault.refusal) {
|
|
3052
|
-
prose(`Enter accepts ${baseDefault}. There is no built-in default for the
|
|
3152
|
+
prose(`Enter accepts ${baseDefault}. There is no built-in default for the reports folder — left unset a run`,
|
|
3053
3153
|
"refuses and names it rather than guessing — so setup gives it a real path under your home,",
|
|
3054
3154
|
"and this install publishes only where you own the disk.");
|
|
3055
3155
|
} else {
|
|
@@ -3095,7 +3195,7 @@ try {
|
|
|
3095
3195
|
// The escape goes in the BRACKETS and the consequence in `skipped`, matching the two prompts that
|
|
3096
3196
|
// already take this mode — the question no longer carries "(empty for none)" because the bracket now
|
|
3097
3197
|
// says it, and a prompt that says it twice in two different wordings is how the two drift apart.
|
|
3098
|
-
const reportsUrl = await askValue("Public base URL for the
|
|
3198
|
+
const reportsUrl = await askValue("Public base URL for the reports folder:", {
|
|
3099
3199
|
skippable: true,
|
|
3100
3200
|
skipped: "CLEAROTRON_REPORTS_URL left unset — runs will deliver, and their notifications will carry no link",
|
|
3101
3201
|
});
|
|
@@ -3134,7 +3234,7 @@ try {
|
|
|
3134
3234
|
prose("No default — it is your hostname. Skip it and this stays a local install: everything works",
|
|
3135
3235
|
"here, and the Use-your-AI page says so rather than handing out an address that fails.");
|
|
3136
3236
|
prose("The usual shape, and why: mcp-server/CONNECT.md.");
|
|
3137
|
-
const { clientDoorReachability } = await import(join(REPO, "shared", "client-door.mjs"));
|
|
3237
|
+
const { clientDoorReachability } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
|
|
3138
3238
|
for (;;) {
|
|
3139
3239
|
const clientUrl = await askValue("Public connector address:", {
|
|
3140
3240
|
skippable: true,
|
|
@@ -3177,7 +3277,7 @@ try {
|
|
|
3177
3277
|
// making a decision about where their customer data lives without being told they had made it.
|
|
3178
3278
|
const cfgDefault = join(base, "config");
|
|
3179
3279
|
say("\n Where this install keeps its own configuration");
|
|
3180
|
-
prose("Your customers and any
|
|
3280
|
+
prose("Your customers and any instructions you override live here, outside the checkout — which is what",
|
|
3181
3281
|
"lets you take updates with `git pull` instead of merging into files you never meant to own.");
|
|
3182
3282
|
prose(`Enter accepts ${cfgDefault}, and your customers are written there.`);
|
|
3183
3283
|
const cfg = await askValue("Configuration directory:", { def: cfgDefault });
|
|
@@ -3202,7 +3302,7 @@ try {
|
|
|
3202
3302
|
candidate.PROFILE_REPO_ROOT = cfg; // no alias row — this name is current
|
|
3203
3303
|
for (const k of ["CLEAROTRON_CUSTOMERS_DIR", "PROFILE_REPO_ROOT"]) ok(`${k}=${candidate[k]}`);
|
|
3204
3304
|
|
|
3205
|
-
// CLEAROTRON_INSTRUCTIONS_DIR IS DELIBERATELY NOT WRITTEN (
|
|
3305
|
+
// CLEAROTRON_INSTRUCTIONS_DIR IS DELIBERATELY NOT WRITTEN (found in review).
|
|
3206
3306
|
//
|
|
3207
3307
|
// Setup used to point it at `<cfg>/skills` and create that directory empty. `clearotron start` then
|
|
3208
3308
|
// makes `<cfg>` a git repository for saved searches — so the doctrine store ends up INSIDE a checkout
|
|
@@ -3218,7 +3318,7 @@ try {
|
|
|
3218
3318
|
// Note for whoever adds an overlay later: it needs this name set, which is why the line below says so
|
|
3219
3319
|
// rather than leaving a reader to discover that files they dropped in are being ignored.
|
|
3220
3320
|
info(`doctrine: this install overrides nothing, so CLEAROTRON_INSTRUCTIONS_DIR stays unset and the `
|
|
3221
|
-
+ `product's own files are used. To override
|
|
3321
|
+
+ `product's own files are used. To override an instruction file later, put it in ${join(cfg, "skills")}, `
|
|
3222
3322
|
+ `COMMIT it in ${cfg}, and set CLEAROTRON_INSTRUCTIONS_DIR to that directory — an uncommitted store `
|
|
3223
3323
|
+ "cannot be identified, and a run says so rather than guessing.");
|
|
3224
3324
|
|
|
@@ -3231,10 +3331,26 @@ try {
|
|
|
3231
3331
|
// PRECISELY what shows through, because the last wording said "bundled customers" and the loader
|
|
3232
3332
|
// says otherwise: the demo roster never layers into a deployment (a typo'd key must not resolve to
|
|
3233
3333
|
// our fixtures), generic.json falls through BY NAME, and doctrine resolves file-by-file.
|
|
3234
|
-
say(" Left empty. The
|
|
3334
|
+
say(" Left empty. The bundled instructions show through file-by-file, and generic.json — the universal");
|
|
3235
3335
|
say(" fallback — falls through by name, so an empty store is a working install. Your own customers");
|
|
3236
3336
|
say(" are added here by name; the bundled demo customers never show through into your roster.");
|
|
3237
3337
|
|
|
3338
|
+
// 7c ── WHO SIGNS IN, AND WHAT THAT ADDRESS GRANTS
|
|
3339
|
+
//
|
|
3340
|
+
// Setup never asked for an address, so `clearotron start` derived one — and derived a staff-domain
|
|
3341
|
+
// rule from everything after its `@`. The whole reasoning, and the install that granted a
|
|
3342
|
+
// documentation domain to a reader who had never been asked, is on `askSignIn` above.
|
|
3343
|
+
section("Who signs in");
|
|
3344
|
+
const localAccount = (() => {
|
|
3345
|
+
try { return userInfo().username || "user"; } catch { return "user"; }
|
|
3346
|
+
})();
|
|
3347
|
+
// ONE CALL SITE. The loop itself lives in `askSignIn` so that the branch that matters — a reader who
|
|
3348
|
+
// pressed Enter at the grant question, and a staff rule that must therefore NOT be written — is
|
|
3349
|
+
// reachable without a terminal. The same seam and the same reason as `offerUsptoSync`.
|
|
3350
|
+
Object.assign(candidate, await askSignIn(
|
|
3351
|
+
{ askValue, confirm, say, ok, info, warn, problem },
|
|
3352
|
+
{ localAccount, staffLabel: `${BRAND.name} staff`, envPath: ENV_PATH }));
|
|
3353
|
+
|
|
3238
3354
|
// 8 ── the engine's own preflight over the whole candidate
|
|
3239
3355
|
//
|
|
3240
3356
|
// — THIS STEP CHECKS THE REGISTER PROVIDER AND NOTHING ELSE. `preflightCandidate` pins
|
|
@@ -3289,7 +3405,7 @@ try {
|
|
|
3289
3405
|
// rather than fall back, so a permissions fault can never silently swap a customer's framework for the
|
|
3290
3406
|
// Generic default). Nothing is written INTO them — see the note at step 7b.
|
|
3291
3407
|
for (const k of ["CLEAROTRON_CUSTOMERS_DIR"]) mkdirSync(candidate[k], { recursive: true });
|
|
3292
|
-
ok(`configuration directories created under ${cfg} (empty —
|
|
3408
|
+
ok(`configuration directories created under ${cfg} (empty — the bundled instructions and the generic fallback show through; customers are yours to add)`);
|
|
3293
3409
|
|
|
3294
3410
|
// 9a ── PUT THE VERB ON THIS OPERATOR'S PATH
|
|
3295
3411
|
//
|
|
@@ -3329,17 +3445,17 @@ try {
|
|
|
3329
3445
|
// They are `clearotron` verbs now for a second reason as well: from an INSTALLED package there is
|
|
3330
3446
|
// no `npm run example` to type — no package.json, no scripts block — so the old advice was not
|
|
3331
3447
|
// merely misordered there, it was unrunnable.
|
|
3332
|
-
// ONE COMMAND, AND WHAT TO EXPECT FROM IT (
|
|
3448
|
+
// ONE COMMAND, AND WHAT TO EXPECT FROM IT (the owner's point 10). This screen
|
|
3333
3449
|
// offered three, each with a sentence, and a reader who has just answered a page of questions is
|
|
3334
3450
|
// being asked to make one more choice at the moment they most want to be told what to do. Three
|
|
3335
3451
|
// equally-weighted options is not generosity; it is the decision handed back.
|
|
3336
3452
|
//
|
|
3337
3453
|
// `start` is the one, because it is the product — the other two were already ordered behind it for
|
|
3338
|
-
// that reason (
|
|
3454
|
+
// that reason (when this screen offered `npm run example` and a raw pipeline invocation and
|
|
3339
3455
|
// named the product nowhere). They keep their place as an afterthought line rather than an option.
|
|
3340
3456
|
// THE COMMAND LINE STAYS A PLAIN LITERAL, DELIBERATELY. onboard-wizard.test.mjs reads this screen
|
|
3341
3457
|
// STATICALLY — it extracts every say() literal and asserts which command leads — and that guard is
|
|
3342
|
-
// the only thing standing between this screen and
|
|
3458
|
+
// the only thing standing between this screen and the defect coming back. Wrapping the command in
|
|
3343
3459
|
// style.bold() puts a nested template literal inside the say(), the extractor stops matching, and the
|
|
3344
3460
|
// corpus goes empty. Its own comment records the previous generation of exactly this: the arms went
|
|
3345
3461
|
// vacuous the moment these lines became template literals.
|
|
@@ -3360,7 +3476,7 @@ try {
|
|
|
3360
3476
|
say(" What this box has now:");
|
|
3361
3477
|
for (const line of [
|
|
3362
3478
|
stateLine("register", candidate.CLEAROTRON_DATABASE, "no register, so every search refuses until one is chosen"),
|
|
3363
|
-
stateLine("web research", present(candidate.PERPLEXITY_API_KEY) ? "a key" : "", "a clearance
|
|
3479
|
+
stateLine("web research", present(candidate.PERPLEXITY_API_KEY) ? "a key" : "", "a clearance stops before it starts, and names the missing key; a knockout search runs and discloses the half it skipped"),
|
|
3364
3480
|
stateLine("data directory", candidate.CLEAROTRON_REPORTS_DIR, "unset"),
|
|
3365
3481
|
stateLine("configuration store", candidate.CLEAROTRON_CUSTOMERS_DIR, "the bundled demo roster"),
|
|
3366
3482
|
stateLine("notification links", candidate.CLEAROTRON_REPORTS_URL, "notifications carry no link into the report"),
|