codetrellis 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +27 -2
- package/bin/codetrellis.mjs +4 -0
- package/package.json +43 -4
- package/reader/material-reader.mjs +130346 -0
- package/resources/tree-sitter/README.md +150 -0
- package/resources/tree-sitter/tree-sitter-c-sharp.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-go.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-java.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-javascript.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-kotlin.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-php.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-python.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-ruby.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-rust.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-swift.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-tsx.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-typescript.wasm +0 -0
- package/resources/tree-sitter/tree-sitter.wasm +0 -0
- package/src/backend/agent/claude-code-watcher.js +270 -0
- package/src/backend/index.js +8 -0
- package/src/backend/lib/sha256-file.js +39 -0
- package/src/backend/lib/zip-entries.js +98 -0
- package/src/backend/lifecycle.js +102 -0
- package/src/backend/mcp/binding-headers.js +54 -0
- package/src/backend/mcp/client-identity.js +44 -0
- package/src/backend/mcp/connector/command.js +110 -0
- package/src/backend/mcp/connector/core.js +278 -0
- package/src/backend/mcp/connector/files.js +121 -0
- package/src/backend/mcp/connector/hook.js +284 -0
- package/src/backend/mcp/connector/main.js +126 -0
- package/src/backend/mcp/connector/sse-upstream.js +152 -0
- package/src/backend/mcp/helpers.js +43 -0
- package/src/backend/mcp/prompt-builders.js +104 -0
- package/src/backend/mcp/resources.js +197 -0
- package/src/backend/mcp/server.js +813 -0
- package/src/backend/mcp/skill-guide.js +1528 -0
- package/src/backend/mcp/tools/architecture-tools.js +273 -0
- package/src/backend/mcp/tools/audio-tools.js +117 -0
- package/src/backend/mcp/tools/awareness-tools.js +623 -0
- package/src/backend/mcp/tools/budget-tools.js +185 -0
- package/src/backend/mcp/tools/channel-tools.js +205 -0
- package/src/backend/mcp/tools/contribution-tools.js +181 -0
- package/src/backend/mcp/tools/drift-tools.js +252 -0
- package/src/backend/mcp/tools/git-tools.js +316 -0
- package/src/backend/mcp/tools/governance-tools.js +175 -0
- package/src/backend/mcp/tools/graph-tools.js +181 -0
- package/src/backend/mcp/tools/intake-tools.js +244 -0
- package/src/backend/mcp/tools/mobile-tools.js +118 -0
- package/src/backend/mcp/tools/peer-tools.js +330 -0
- package/src/backend/mcp/tools/plan-item-tools.js +1601 -0
- package/src/backend/mcp/tools/plan-tools.js +680 -0
- package/src/backend/mcp/tools/presence-tools.js +185 -0
- package/src/backend/mcp/tools/project-config-tools.js +150 -0
- package/src/backend/mcp/tools/review-tools.js +172 -0
- package/src/backend/mcp/tools/session-tools.js +554 -0
- package/src/backend/mcp/tools/system-docs-tools.js +168 -0
- package/src/backend/mcp/tools/terminal-tools.js +186 -0
- package/src/backend/mcp/tools/test-tools.js +117 -0
- package/src/backend/mcp/tools/ui-tools.js +356 -0
- package/src/backend/mcp/types.js +15 -0
- package/src/backend/middleware/local-auth.js +116 -0
- package/src/backend/server.js +5951 -0
- package/src/backend/services/agent-event-log.js +350 -0
- package/src/backend/services/architecture-rule.js +584 -0
- package/src/backend/services/architecture-rules.js +275 -0
- package/src/backend/services/artefact-content-service.js +181 -0
- package/src/backend/services/artefact-service.js +305 -0
- package/src/backend/services/artefact-watcher.js +167 -0
- package/src/backend/services/ast-parser.js +327 -0
- package/src/backend/services/audio-buffer-service.js +152 -0
- package/src/backend/services/awareness-notices.js +139 -0
- package/src/backend/services/awareness-replies.js +194 -0
- package/src/backend/services/awareness-service.js +344 -0
- package/src/backend/services/awareness-signals.js +267 -0
- package/src/backend/services/baseline-store.js +83 -0
- package/src/backend/services/branch-workstreams.js +341 -0
- package/src/backend/services/breakpoint-service.js +584 -0
- package/src/backend/services/brief-service.js +299 -0
- package/src/backend/services/budget-service.js +528 -0
- package/src/backend/services/callsites/base.js +15 -0
- package/src/backend/services/callsites/csharp.js +148 -0
- package/src/backend/services/callsites/go.js +163 -0
- package/src/backend/services/callsites/index.js +53 -0
- package/src/backend/services/callsites/kotlin.js +123 -0
- package/src/backend/services/callsites/process-env.js +125 -0
- package/src/backend/services/callsites/python.js +91 -0
- package/src/backend/services/callsites/ruby.js +164 -0
- package/src/backend/services/callsites/shared.js +198 -0
- package/src/backend/services/callsites/swift.js +115 -0
- package/src/backend/services/callsites/typescript.js +87 -0
- package/src/backend/services/capability-token.js +108 -0
- package/src/backend/services/change-check.js +156 -0
- package/src/backend/services/channel-dispatcher-service.js +235 -0
- package/src/backend/services/channel-event-file-service.js +125 -0
- package/src/backend/services/channel-event-service.js +297 -0
- package/src/backend/services/check-runs.js +177 -0
- package/src/backend/services/checkout-identity.js +73 -0
- package/src/backend/services/claude-code-parallel.js +221 -0
- package/src/backend/services/claude-desktop-config.js +186 -0
- package/src/backend/services/clock.js +57 -0
- package/src/backend/services/cloud-files.js +191 -0
- package/src/backend/services/coalesce.js +50 -0
- package/src/backend/services/code-breakpoints.js +291 -0
- package/src/backend/services/comment-service.js +168 -0
- package/src/backend/services/commit-attribution.js +134 -0
- package/src/backend/services/commit-edges.js +99 -0
- package/src/backend/services/confined-fs.js +241 -0
- package/src/backend/services/conformity-gate.js +132 -0
- package/src/backend/services/contribution-service.js +409 -0
- package/src/backend/services/coverage-service.js +173 -0
- package/src/backend/services/criteria-service.js +721 -0
- package/src/backend/services/criterion-checks.js +387 -0
- package/src/backend/services/criterion-loop-service.js +411 -0
- package/src/backend/services/cross-system-service.js +231 -0
- package/src/backend/services/database.js +916 -0
- package/src/backend/services/db-schema.js +1358 -0
- package/src/backend/services/deviation-service.js +344 -0
- package/src/backend/services/diff-engine.js +168 -0
- package/src/backend/services/evidence.js +363 -0
- package/src/backend/services/external-intake-service.js +269 -0
- package/src/backend/services/external-pointer-service.js +195 -0
- package/src/backend/services/external-refs-service.js +214 -0
- package/src/backend/services/file-history.js +158 -0
- package/src/backend/services/file-watcher.js +193 -0
- package/src/backend/services/folder-requests.js +118 -0
- package/src/backend/services/freeze-service.js +189 -0
- package/src/backend/services/gemini-cli-hook.js +172 -0
- package/src/backend/services/git-activity-service.js +325 -0
- package/src/backend/services/git-blobs.js +70 -0
- package/src/backend/services/git-branches.js +357 -0
- package/src/backend/services/git-checkout.js +153 -0
- package/src/backend/services/git-commit-service.js +91 -0
- package/src/backend/services/git-env.js +121 -0
- package/src/backend/services/git-identity.js +84 -0
- package/src/backend/services/git-refs.js +386 -0
- package/src/backend/services/git-safety.js +58 -0
- package/src/backend/services/grant-guard.js +67 -0
- package/src/backend/services/html-view-policy.js +135 -0
- package/src/backend/services/human-decision.js +55 -0
- package/src/backend/services/importers.js +159 -0
- package/src/backend/services/intent-service.js +105 -0
- package/src/backend/services/ipc-dispatcher.js +164 -0
- package/src/backend/services/item-git-state.js +208 -0
- package/src/backend/services/line-changes.js +232 -0
- package/src/backend/services/line-history.js +174 -0
- package/src/backend/services/local-api-changes.js +40 -0
- package/src/backend/services/logger.js +217 -0
- package/src/backend/services/material-footprints.js +203 -0
- package/src/backend/services/material-place.js +82 -0
- package/src/backend/services/material-reader/child.js +4 -0
- package/src/backend/services/material-reader/docx-markdown.js +198 -0
- package/src/backend/services/material-reader/fixtures.test-helper.js +169 -0
- package/src/backend/services/material-reader/quote.js +44 -0
- package/src/backend/services/material-reader/read.js +430 -0
- package/src/backend/services/material-reader/reader-host.js +202 -0
- package/src/backend/services/material-signals.js +141 -0
- package/src/backend/services/mcp-capabilities.js +390 -0
- package/src/backend/services/mdns-service.js +304 -0
- package/src/backend/services/mobile-api-server.js +281 -0
- package/src/backend/services/mobile-approvals.js +306 -0
- package/src/backend/services/mobile-awareness.js +180 -0
- package/src/backend/services/mobile-breakpoints.js +115 -0
- package/src/backend/services/mobile-budget.js +98 -0
- package/src/backend/services/mobile-freeze.js +106 -0
- package/src/backend/services/mobile-proposals.js +100 -0
- package/src/backend/services/mobile-rpc-service.js +1289 -0
- package/src/backend/services/mobile-workstreams.js +160 -0
- package/src/backend/services/monorepo-detector.js +131 -0
- package/src/backend/services/other-work.js +45 -0
- package/src/backend/services/pack-seal.js +129 -0
- package/src/backend/services/paired-device-service.js +192 -0
- package/src/backend/services/pairing-server.js +323 -0
- package/src/backend/services/pairing-service.js +200 -0
- package/src/backend/services/pantry-resolution-service.js +166 -0
- package/src/backend/services/parsers/base.js +124 -0
- package/src/backend/services/parsers/csharp.js +224 -0
- package/src/backend/services/parsers/go.js +180 -0
- package/src/backend/services/parsers/index.js +101 -0
- package/src/backend/services/parsers/java.js +103 -0
- package/src/backend/services/parsers/kotlin.js +252 -0
- package/src/backend/services/parsers/php.js +113 -0
- package/src/backend/services/parsers/python.js +189 -0
- package/src/backend/services/parsers/ruby.js +212 -0
- package/src/backend/services/parsers/rust.js +97 -0
- package/src/backend/services/parsers/swift.js +221 -0
- package/src/backend/services/parsers/typescript.js +235 -0
- package/src/backend/services/pattern-scan.js +65 -0
- package/src/backend/services/patterns.js +281 -0
- package/src/backend/services/peer-audit-service.js +123 -0
- package/src/backend/services/peer-auth.js +153 -0
- package/src/backend/services/peer-capabilities.js +209 -0
- package/src/backend/services/peer-connection-service.js +450 -0
- package/src/backend/services/peer-grants.js +33 -0
- package/src/backend/services/persistence.js +116 -0
- package/src/backend/services/personal-sync-service.js +232 -0
- package/src/backend/services/pipeline-approvals.js +72 -0
- package/src/backend/services/pipeline.js +232 -0
- package/src/backend/services/plan-arrivals.js +68 -0
- package/src/backend/services/plan-changes-service.js +273 -0
- package/src/backend/services/plan-conflict-service.js +288 -0
- package/src/backend/services/plan-dependencies.js +91 -0
- package/src/backend/services/plan-doc-guard.js +90 -0
- package/src/backend/services/plan-documents-service.js +275 -0
- package/src/backend/services/plan-event-service.js +154 -0
- package/src/backend/services/plan-file-refs.js +106 -0
- package/src/backend/services/plan-file-service.js +1564 -0
- package/src/backend/services/plan-history-service.js +156 -0
- package/src/backend/services/plan-import-service.js +261 -0
- package/src/backend/services/plan-item-service.js +1223 -0
- package/src/backend/services/plan-migrate-service.js +395 -0
- package/src/backend/services/plan-overlay-service.js +173 -0
- package/src/backend/services/plan-phases-service.js +182 -0
- package/src/backend/services/plan-progress-service.js +134 -0
- package/src/backend/services/plan-review-service.js +262 -0
- package/src/backend/services/plan-service.js +682 -0
- package/src/backend/services/plan-status.js +113 -0
- package/src/backend/services/plan-template-publish-service.js +217 -0
- package/src/backend/services/plan-templates-service.js +242 -0
- package/src/backend/services/plan-templates.js +1164 -0
- package/src/backend/services/planned-overlap-actions.js +200 -0
- package/src/backend/services/plans-home.js +224 -0
- package/src/backend/services/play-forward.js +256 -0
- package/src/backend/services/playback-service.js +117 -0
- package/src/backend/services/power-service.js +167 -0
- package/src/backend/services/power-signals.js +81 -0
- package/src/backend/services/pr-draft-service.js +142 -0
- package/src/backend/services/presence-service.js +122 -0
- package/src/backend/services/pricing.js +60 -0
- package/src/backend/services/project-config-service.js +474 -0
- package/src/backend/services/project-scanner.js +184 -0
- package/src/backend/services/projection-service.js +69 -0
- package/src/backend/services/push-notification-service.js +288 -0
- package/src/backend/services/recent-projects-service.js +204 -0
- package/src/backend/services/record-chain.js +162 -0
- package/src/backend/services/recurrence-rule.js +63 -0
- package/src/backend/services/recurring-agent.js +89 -0
- package/src/backend/services/recurring-scheduler.js +77 -0
- package/src/backend/services/recurring-service.js +276 -0
- package/src/backend/services/reference-service.js +169 -0
- package/src/backend/services/release-public-key.js +30 -0
- package/src/backend/services/release-signature.js +64 -0
- package/src/backend/services/remote-audio-service.js +224 -0
- package/src/backend/services/remote-interaction-service.js +275 -0
- package/src/backend/services/remote-terminal-service.js +324 -0
- package/src/backend/services/rendition/child/main.js +76 -0
- package/src/backend/services/rendition/engine-host.js +249 -0
- package/src/backend/services/rendition/engine-lock.js +39 -0
- package/src/backend/services/rendition/engine-lock.json +14 -0
- package/src/backend/services/rendition/engine-manifest.js +97 -0
- package/src/backend/services/rendition/network-proof.js +73 -0
- package/src/backend/services/rendition/rendition-service.js +175 -0
- package/src/backend/services/replay-frames.js +387 -0
- package/src/backend/services/replay-state.js +201 -0
- package/src/backend/services/resolvers/base.js +108 -0
- package/src/backend/services/resolvers/csharp.js +109 -0
- package/src/backend/services/resolvers/go.js +105 -0
- package/src/backend/services/resolvers/index.js +60 -0
- package/src/backend/services/resolvers/java.js +63 -0
- package/src/backend/services/resolvers/kotlin.js +109 -0
- package/src/backend/services/resolvers/php.js +89 -0
- package/src/backend/services/resolvers/python.js +154 -0
- package/src/backend/services/resolvers/ruby.js +103 -0
- package/src/backend/services/resolvers/rust.js +77 -0
- package/src/backend/services/resolvers/swift.js +98 -0
- package/src/backend/services/resolvers/typescript.js +71 -0
- package/src/backend/services/retention.js +54 -0
- package/src/backend/services/review-architecture.js +236 -0
- package/src/backend/services/review-attest.js +68 -0
- package/src/backend/services/review-bundle.js +226 -0
- package/src/backend/services/review-graduation.js +93 -0
- package/src/backend/services/review-host/bitbucket.js +79 -0
- package/src/backend/services/review-host/detect.js +80 -0
- package/src/backend/services/review-host/github.js +97 -0
- package/src/backend/services/review-host/gitlab.js +77 -0
- package/src/backend/services/review-host/host-state.js +103 -0
- package/src/backend/services/review-host/http.js +58 -0
- package/src/backend/services/review-host/switch.js +120 -0
- package/src/backend/services/review-marks.js +72 -0
- package/src/backend/services/review-notes.js +169 -0
- package/src/backend/services/review-other-work.js +90 -0
- package/src/backend/services/review-queue-service.js +147 -0
- package/src/backend/services/review-risk.js +127 -0
- package/src/backend/services/review-task.js +121 -0
- package/src/backend/services/rule-approvals.js +268 -0
- package/src/backend/services/rule-baseline.js +134 -0
- package/src/backend/services/rule-changes.js +162 -0
- package/src/backend/services/rule-preview.js +47 -0
- package/src/backend/services/rule-proposals.js +104 -0
- package/src/backend/services/rule-scope.js +76 -0
- package/src/backend/services/rulebook.js +286 -0
- package/src/backend/services/rules-at.js +56 -0
- package/src/backend/services/rules-overview.js +88 -0
- package/src/backend/services/schema-reconciler.js +250 -0
- package/src/backend/services/secret-store.js +119 -0
- package/src/backend/services/section-workstreams.js +95 -0
- package/src/backend/services/self-write-tracker.js +75 -0
- package/src/backend/services/sensor-bridge-service.js +285 -0
- package/src/backend/services/session-service.js +192 -0
- package/src/backend/services/settings-service.js +324 -0
- package/src/backend/services/signal-breakpoints.js +172 -0
- package/src/backend/services/signed-approval-record.js +86 -0
- package/src/backend/services/signed-approvals.js +244 -0
- package/src/backend/services/signoff-pack.js +328 -0
- package/src/backend/services/signoff-rows.js +114 -0
- package/src/backend/services/skill-arrival-service.js +138 -0
- package/src/backend/services/skill-model.js +193 -0
- package/src/backend/services/skill-use-service.js +140 -0
- package/src/backend/services/skills-service.js +150 -0
- package/src/backend/services/snapshot-compare-service.js +397 -0
- package/src/backend/services/source-control.js +189 -0
- package/src/backend/services/spec-links-service.js +123 -0
- package/src/backend/services/spec-proposal-withdraw.js +50 -0
- package/src/backend/services/spec-proposals-service.js +470 -0
- package/src/backend/services/sql/embedded.js +95 -0
- package/src/backend/services/sql/index.js +63 -0
- package/src/backend/services/sql/refs.js +357 -0
- package/src/backend/services/sql/schema.js +312 -0
- package/src/backend/services/sql/tokenizer.js +195 -0
- package/src/backend/services/stack-overlaps.js +117 -0
- package/src/backend/services/stack-service.js +225 -0
- package/src/backend/services/state-sync-service.js +384 -0
- package/src/backend/services/stuck-sensor-service.js +200 -0
- package/src/backend/services/system-discovery.js +481 -0
- package/src/backend/services/system-docs-service.js +701 -0
- package/src/backend/services/task-attachments-service.js +340 -0
- package/src/backend/services/task-grounding.js +60 -0
- package/src/backend/services/task-records/check-run-record.js +146 -0
- package/src/backend/services/task-records/check-runs.js +115 -0
- package/src/backend/services/task-records/heads.js +88 -0
- package/src/backend/services/task-records/material-reads.js +225 -0
- package/src/backend/services/task-records/read-record.js +100 -0
- package/src/backend/services/task-records/record.js +173 -0
- package/src/backend/services/task-records/run-record.js +136 -0
- package/src/backend/services/task-records/shared-state.js +548 -0
- package/src/backend/services/task-records/signing.js +140 -0
- package/src/backend/services/task-records/split-signals.js +52 -0
- package/src/backend/services/task-records/test-runs.js +164 -0
- package/src/backend/services/task-records/trust.js +243 -0
- package/src/backend/services/task-rules.js +81 -0
- package/src/backend/services/task-workstreams.js +90 -0
- package/src/backend/services/terminal-history-service.js +266 -0
- package/src/backend/services/terminal-service.js +267 -0
- package/src/backend/services/test-clock.js +53 -0
- package/src/backend/services/tests/grounding.js +266 -0
- package/src/backend/services/tests/junit.js +104 -0
- package/src/backend/services/tests/teammate-runs.js +134 -0
- package/src/backend/services/tests/test-results.js +234 -0
- package/src/backend/services/tree-watcher.js +204 -0
- package/src/backend/services/trellis-service.js +204 -0
- package/src/backend/services/trusted-roots.js +186 -0
- package/src/backend/services/update-download-service.js +342 -0
- package/src/backend/services/update-service.js +266 -0
- package/src/backend/services/watch-ignore.js +76 -0
- package/src/backend/services/webhook-egress.js +206 -0
- package/src/backend/services/webrtc-service.js +413 -0
- package/src/backend/services/work-changes.js +59 -0
- package/src/backend/services/workstream-binding.js +82 -0
- package/src/backend/services/workstream-commits.js +116 -0
- package/src/backend/services/workstream-imports.js +177 -0
- package/src/backend/services/workstream-service.js +335 -0
- package/src/backend/services/workstream-symbols.js +223 -0
- package/src/backend/services/workstream-watch-service.js +391 -0
- package/src/backend/services/worktree-service.js +235 -0
- package/src/cli/agent.js +100 -0
- package/src/cli/args.js +201 -0
- package/src/cli/conformity.js +106 -0
- package/src/cli/desktop.js +91 -0
- package/src/cli/main.js +409 -0
- package/src/cli/pipeline.js +109 -0
- package/src/cli/plan-verbs.js +259 -0
- package/src/cli/review-adapters.js +218 -0
- package/src/cli/review-output.js +93 -0
- package/src/cli/review-post.js +89 -0
- package/src/cli/review-sink.js +183 -0
- package/src/cli/review-skill.js +44 -0
- package/src/cli/review-verify.js +104 -0
- package/src/cli/review.js +386 -0
- package/src/cli/sarif.js +148 -0
- package/src/cli/verbs.js +359 -0
- package/src/shared/build-info.js +39 -0
- package/src/shared/lib/agent-review.js +199 -0
- package/src/shared/lib/agent-turns.js +140 -0
- package/src/shared/lib/awareness-digest.js +120 -0
- package/src/shared/lib/branch-name.js +45 -0
- package/src/shared/lib/breakpoint-words.js +118 -0
- package/src/shared/lib/budget-words.js +56 -0
- package/src/shared/lib/burst.js +69 -0
- package/src/shared/lib/call-entry.js +105 -0
- package/src/shared/lib/check-compare.js +42 -0
- package/src/shared/lib/check-words.js +216 -0
- package/src/shared/lib/csv.js +62 -0
- package/src/shared/lib/folder-entry.js +87 -0
- package/src/shared/lib/freeze-words.js +60 -0
- package/src/shared/lib/fuzzy.js +84 -0
- package/src/shared/lib/git-state-words.js +80 -0
- package/src/shared/lib/grep-entry.js +86 -0
- package/src/shared/lib/grounding-line.js +61 -0
- package/src/shared/lib/import-line.js +71 -0
- package/src/shared/lib/item-status.js +249 -0
- package/src/shared/lib/line-changes.js +53 -0
- package/src/shared/lib/locator.js +71 -0
- package/src/shared/lib/matcher.js +120 -0
- package/src/shared/lib/merge-order.js +65 -0
- package/src/shared/lib/open-findings.js +68 -0
- package/src/shared/lib/other-work.js +108 -0
- package/src/shared/lib/package-entry.js +142 -0
- package/src/shared/lib/plan-vocab.js +40 -0
- package/src/shared/lib/pptx-xml.js +86 -0
- package/src/shared/lib/proposal-words.js +61 -0
- package/src/shared/lib/recurrence.js +183 -0
- package/src/shared/lib/references.js +72 -0
- package/src/shared/lib/rule-pattern.js +56 -0
- package/src/shared/lib/sdp-fingerprint.js +115 -0
- package/src/shared/lib/sdp-minimal.js +123 -0
- package/src/shared/lib/secret-paths.js +34 -0
- package/src/shared/lib/signal-words.js +172 -0
- package/src/shared/lib/signoff.js +56 -0
- package/src/shared/lib/skills-note.js +60 -0
- package/src/shared/lib/spec-sections.js +78 -0
- package/src/shared/lib/symbol-entry.js +60 -0
- package/src/shared/lib/tool-phrasing.js +338 -0
- package/src/shared/lib/turn-gap.js +27 -0
- package/src/shared/lib/workstream-words.js +38 -0
- package/src/shared/lib/xlsx-xml.js +144 -0
- package/src/shared/lib/zip-reader.js +99 -0
- package/src/shared/types/agent.js +27 -0
- package/src/shared/types/architecture-rules.js +30 -0
- package/src/shared/types/ast.js +15 -0
- package/src/shared/types/breakpoint.js +33 -0
- package/src/shared/types/channel.js +41 -0
- package/src/shared/types/criteria.js +15 -0
- package/src/shared/types/graph.js +15 -0
- package/src/shared/types/index.js +53 -0
- package/src/shared/types/peer.js +36 -0
- package/src/shared/types/pipeline.js +15 -0
- package/src/shared/types/plan.js +15 -0
- package/src/shared/types/play-forward.js +15 -0
- package/src/shared/types/power.js +15 -0
- package/src/shared/types/presence.js +15 -0
- package/src/shared/types/project-config.js +35 -0
- package/src/shared/types/project.js +15 -0
- package/src/shared/types/record.js +15 -0
- package/src/shared/types/recurring.js +15 -0
- package/src/shared/types/review.js +15 -0
- package/src/shared/types/settings.js +114 -0
- package/src/shared/types/stack.js +15 -0
- package/src/shared/types/system-doc.js +15 -0
- package/src/shared/types/system.js +15 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var engine_host_exports = {};
|
|
19
|
+
__export(engine_host_exports, {
|
|
20
|
+
ConversionFailed: () => ConversionFailed,
|
|
21
|
+
ConversionTimedOut: () => ConversionTimedOut,
|
|
22
|
+
EngineHost: () => EngineHost,
|
|
23
|
+
EngineUnavailable: () => EngineUnavailable,
|
|
24
|
+
runtimeIsolation: () => runtimeIsolation
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(engine_host_exports);
|
|
27
|
+
var import_node_child_process = require("node:child_process");
|
|
28
|
+
var import_engine_manifest = require("./engine-manifest");
|
|
29
|
+
var import_confined_fs = require("../confined-fs");
|
|
30
|
+
class EngineUnavailable extends Error {
|
|
31
|
+
}
|
|
32
|
+
class ConversionFailed extends Error {
|
|
33
|
+
}
|
|
34
|
+
class ConversionTimedOut extends ConversionFailed {
|
|
35
|
+
}
|
|
36
|
+
function runtimeIsolation() {
|
|
37
|
+
const flags = process.allowedNodeEnvironmentFlags;
|
|
38
|
+
return { fs: flags.has("--permission"), net: flags.has("--allow-net") };
|
|
39
|
+
}
|
|
40
|
+
const WARM_UP = new TextEncoder().encode("{\\rtf1\\ansi CodeTrellis warm-up.\\par}");
|
|
41
|
+
class EngineHost {
|
|
42
|
+
constructor(opts) {
|
|
43
|
+
this.opts = opts;
|
|
44
|
+
}
|
|
45
|
+
opts;
|
|
46
|
+
child = null;
|
|
47
|
+
starting = null;
|
|
48
|
+
version = null;
|
|
49
|
+
seq = 0;
|
|
50
|
+
pending = /* @__PURE__ */ new Map();
|
|
51
|
+
queue = Promise.resolve();
|
|
52
|
+
idleTimer = null;
|
|
53
|
+
stderrTail = "";
|
|
54
|
+
get running() {
|
|
55
|
+
return this.child !== null;
|
|
56
|
+
}
|
|
57
|
+
/** The running engine's version, once it has started. */
|
|
58
|
+
get engineVersion() {
|
|
59
|
+
return this.version;
|
|
60
|
+
}
|
|
61
|
+
/** The engine's check, without starting it — its version keys the cache. */
|
|
62
|
+
async check() {
|
|
63
|
+
return (0, import_engine_manifest.verifyEngine)(this.opts.engineDir, this.opts.pinned ?? void 0);
|
|
64
|
+
}
|
|
65
|
+
convert(bytes, ext) {
|
|
66
|
+
const run = this.queue.then(() => this.convertNow(bytes, ext));
|
|
67
|
+
this.queue = run.catch(() => void 0);
|
|
68
|
+
return run;
|
|
69
|
+
}
|
|
70
|
+
stop() {
|
|
71
|
+
this.clearIdle();
|
|
72
|
+
const child = this.child;
|
|
73
|
+
this.child = null;
|
|
74
|
+
if (child && child.exitCode === null) child.kill("SIGKILL");
|
|
75
|
+
}
|
|
76
|
+
async convertNow(bytes, ext) {
|
|
77
|
+
this.clearIdle();
|
|
78
|
+
const child = await this.start();
|
|
79
|
+
const id = ++this.seq;
|
|
80
|
+
const timeoutMs = this.opts.timeoutMs ?? 3e4;
|
|
81
|
+
try {
|
|
82
|
+
return await new Promise((resolve, reject) => {
|
|
83
|
+
const timer = setTimeout(() => {
|
|
84
|
+
console.warn(`[rendition] a .${ext} conversion ran past ${timeoutMs}ms; stopping the engine`);
|
|
85
|
+
this.pending.delete(id);
|
|
86
|
+
reject(new ConversionTimedOut(`The conversion took longer than ${Math.round(timeoutMs / 1e3)}s, so it was stopped`));
|
|
87
|
+
this.stop();
|
|
88
|
+
}, timeoutMs);
|
|
89
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
90
|
+
child.send({ type: "convert", id, bytes, ext });
|
|
91
|
+
});
|
|
92
|
+
} finally {
|
|
93
|
+
this.armIdle();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
start() {
|
|
97
|
+
if (this.child) return Promise.resolve(this.child);
|
|
98
|
+
if (!this.starting) this.starting = this.spawn().finally(() => {
|
|
99
|
+
this.starting = null;
|
|
100
|
+
});
|
|
101
|
+
return this.starting;
|
|
102
|
+
}
|
|
103
|
+
/** Start an engine and warm it; one that hangs on the warm-up is replaced, once. */
|
|
104
|
+
async spawn() {
|
|
105
|
+
for (let attempt = 1; ; attempt++) {
|
|
106
|
+
const child = await this.spawnOnce();
|
|
107
|
+
if (await this.warmUp(child)) {
|
|
108
|
+
child.on("message", (msg) => this.onMessage(msg));
|
|
109
|
+
child.on("exit", () => this.onExit(child));
|
|
110
|
+
this.child = child;
|
|
111
|
+
return child;
|
|
112
|
+
}
|
|
113
|
+
if (child.exitCode === null) child.kill("SIGKILL");
|
|
114
|
+
if (attempt >= 2) throw new EngineUnavailable("the conversion engine did not settle after starting");
|
|
115
|
+
console.warn("[rendition] the engine hung on its warm-up; starting a fresh one");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** True when the engine answered the warm-up — with a PDF or an error — in time. */
|
|
119
|
+
warmUp(child) {
|
|
120
|
+
const ms = this.opts.warmUpMs ?? 2e4;
|
|
121
|
+
if (ms <= 0) return Promise.resolve(true);
|
|
122
|
+
const startedAt = Date.now();
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
const done = (ok) => {
|
|
125
|
+
clearTimeout(timer);
|
|
126
|
+
child.off("message", onMessage);
|
|
127
|
+
child.off("exit", onExit);
|
|
128
|
+
if (ok) console.log(`[rendition] engine warmed in ${Date.now() - startedAt}ms`);
|
|
129
|
+
resolve(ok);
|
|
130
|
+
};
|
|
131
|
+
const onMessage = (msg) => {
|
|
132
|
+
if (msg?.id === 0) done(true);
|
|
133
|
+
};
|
|
134
|
+
const onExit = () => done(false);
|
|
135
|
+
const timer = setTimeout(() => done(false), ms);
|
|
136
|
+
child.on("message", onMessage);
|
|
137
|
+
child.once("exit", onExit);
|
|
138
|
+
child.send({ type: "convert", id: 0, bytes: WARM_UP, ext: "rtf" });
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async spawnOnce() {
|
|
142
|
+
const isolation = runtimeIsolation();
|
|
143
|
+
if (!isolation.fs) throw new EngineUnavailable("this runtime cannot confine the conversion engine");
|
|
144
|
+
const checked = await this.check();
|
|
145
|
+
if (!checked.ok) throw new EngineUnavailable(checked.reason);
|
|
146
|
+
if (!isolation.net && checked.manifest.networkFree !== true && this.opts.requireNetworkDenial !== false) {
|
|
147
|
+
throw new EngineUnavailable("this runtime cannot keep the conversion engine off the network, and this engine is not proven network-free");
|
|
148
|
+
}
|
|
149
|
+
const startedAt = Date.now();
|
|
150
|
+
let engineDir;
|
|
151
|
+
let childScript;
|
|
152
|
+
let read;
|
|
153
|
+
try {
|
|
154
|
+
engineDir = (0, import_confined_fs.canonicalRoot)(this.opts.engineDir);
|
|
155
|
+
childScript = (0, import_confined_fs.canonicalRoot)(this.opts.childScript);
|
|
156
|
+
read = [engineDir, childScript, ...(this.opts.allowRead ?? []).map((p) => (0, import_confined_fs.canonicalRoot)(p))];
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.warn(`[rendition] engine did not start: ${err.message}`);
|
|
159
|
+
throw new EngineUnavailable("the conversion engine could not start");
|
|
160
|
+
}
|
|
161
|
+
const child = (0, import_node_child_process.fork)(childScript, [engineDir], {
|
|
162
|
+
execPath: process.execPath,
|
|
163
|
+
// Its own directory — never the directory the app was started from.
|
|
164
|
+
cwd: engineDir,
|
|
165
|
+
// Omitting --allow-net, --allow-child-process, --allow-addons and every
|
|
166
|
+
// --allow-fs-write is the point.
|
|
167
|
+
execArgv: ["--permission", ...read.map((p) => `--allow-fs-read=${p}`), "--allow-worker"],
|
|
168
|
+
// Nothing of ours — no capability token, no data dir, no paths.
|
|
169
|
+
env: process.versions.electron ? { ELECTRON_RUN_AS_NODE: "1" } : {},
|
|
170
|
+
stdio: ["ignore", "ignore", "pipe", "ipc"],
|
|
171
|
+
serialization: "advanced"
|
|
172
|
+
});
|
|
173
|
+
this.stderrTail = "";
|
|
174
|
+
child.stderr?.on("data", (d) => {
|
|
175
|
+
this.stderrTail = (this.stderrTail + d.toString()).slice(-2e3);
|
|
176
|
+
});
|
|
177
|
+
await new Promise((resolve, reject) => {
|
|
178
|
+
const fail = (why) => {
|
|
179
|
+
clearTimeout(timer);
|
|
180
|
+
if (child.exitCode === null) child.kill("SIGKILL");
|
|
181
|
+
console.warn(`[rendition] engine did not start: ${why}
|
|
182
|
+
${this.stderrTail}`);
|
|
183
|
+
reject(new EngineUnavailable("the conversion engine could not start"));
|
|
184
|
+
};
|
|
185
|
+
const timer = setTimeout(() => fail("timed out"), this.opts.startTimeoutMs ?? 6e4);
|
|
186
|
+
child.once("error", (err) => fail(err.message));
|
|
187
|
+
child.once("exit", (code) => fail(`exited with ${code}`));
|
|
188
|
+
child.on("message", function ready(msg) {
|
|
189
|
+
if (msg?.type !== "ready") return;
|
|
190
|
+
child.off("message", ready);
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
child.removeAllListeners("exit");
|
|
193
|
+
child.removeAllListeners("error");
|
|
194
|
+
resolve();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
this.version = checked.manifest.version;
|
|
198
|
+
console.log(`[rendition] engine ${checked.manifest.version} started in ${Date.now() - startedAt}ms`);
|
|
199
|
+
return child;
|
|
200
|
+
}
|
|
201
|
+
onMessage(msg) {
|
|
202
|
+
const p = this.pending.get(msg.id);
|
|
203
|
+
if (!p) return;
|
|
204
|
+
this.pending.delete(msg.id);
|
|
205
|
+
clearTimeout(p.timer);
|
|
206
|
+
if (msg.type === "result" && msg.pdf) {
|
|
207
|
+
const pdf = new Uint8Array(msg.pdf.buffer, msg.pdf.byteOffset, msg.pdf.byteLength);
|
|
208
|
+
if (pdf.byteLength > (this.opts.maxOutputBytes ?? 200 * 1024 * 1024)) {
|
|
209
|
+
p.reject(new ConversionFailed("The converted document is larger than the viewer will show"));
|
|
210
|
+
} else if (!startsWithPdf(pdf)) {
|
|
211
|
+
p.reject(new ConversionFailed("The engine did not produce a PDF"));
|
|
212
|
+
} else {
|
|
213
|
+
p.resolve(pdf);
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
console.warn(`[rendition] conversion failed: ${msg.message ?? "unknown"}`);
|
|
217
|
+
p.reject(new ConversionFailed("The document could not be converted"));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
onExit(child) {
|
|
221
|
+
if (this.child === child) this.child = null;
|
|
222
|
+
for (const [id, p] of this.pending) {
|
|
223
|
+
clearTimeout(p.timer);
|
|
224
|
+
p.reject(new ConversionFailed("The conversion engine stopped unexpectedly"));
|
|
225
|
+
this.pending.delete(id);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
armIdle() {
|
|
229
|
+
this.clearIdle();
|
|
230
|
+
if (!this.child || this.pending.size > 0) return;
|
|
231
|
+
this.idleTimer = setTimeout(() => this.stop(), this.opts.idleMs ?? 3 * 6e4);
|
|
232
|
+
this.idleTimer.unref();
|
|
233
|
+
}
|
|
234
|
+
clearIdle() {
|
|
235
|
+
if (this.idleTimer) clearTimeout(this.idleTimer);
|
|
236
|
+
this.idleTimer = null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function startsWithPdf(bytes) {
|
|
240
|
+
return bytes.byteLength > 5 && String.fromCharCode(...bytes.subarray(0, 5)) === "%PDF-";
|
|
241
|
+
}
|
|
242
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
243
|
+
0 && (module.exports = {
|
|
244
|
+
ConversionFailed,
|
|
245
|
+
ConversionTimedOut,
|
|
246
|
+
EngineHost,
|
|
247
|
+
EngineUnavailable,
|
|
248
|
+
runtimeIsolation
|
|
249
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var engine_lock_exports = {};
|
|
29
|
+
__export(engine_lock_exports, {
|
|
30
|
+
ENGINE_PIN: () => ENGINE_PIN
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(engine_lock_exports);
|
|
33
|
+
var import_engine_lock = __toESM(require("./engine-lock.json"));
|
|
34
|
+
const pinned = import_engine_lock.default;
|
|
35
|
+
const ENGINE_PIN = pinned.version ? { version: pinned.version, files: pinned.files, networkFree: pinned.networkFree === true } : null;
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
ENGINE_PIN
|
|
39
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "24.8-d1c9e0e4e1-fb2575f33e82",
|
|
3
|
+
"networkFree": true,
|
|
4
|
+
"archive": {
|
|
5
|
+
"url": "https://github.com/lionroseway/codetrellis/releases/download/rendition-engine-24.8-d1c9e0e4e1-fb2575f33e82/rendition-engine-24.8-d1c9e0e4e1-fb2575f33e82.tar.gz",
|
|
6
|
+
"sha256": "b751353127f71c75f605e180963eff9fae52351c02994d8c4d45732fde18aa14"
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"adapter.cjs": "3385951f56a3c5b1ad8a689eac16d66cf631a0b70da9f1c41853e74a7afde831",
|
|
10
|
+
"soffice.data": "5fa78496011c4c2392e736a4cb869a3964e62b8138e3e70f4149bdb8945554d9",
|
|
11
|
+
"soffice.mjs": "22c4c073474ee2029dd55f32ee46ce0e40ccbc8eb0f078abd48a63233456e395",
|
|
12
|
+
"soffice.wasm": "d6b4f176a73925db14ea53bec8525e4fc3b92def1e0cb73b0ed84cf698349222"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var engine_manifest_exports = {};
|
|
29
|
+
__export(engine_manifest_exports, {
|
|
30
|
+
verifyEngine: () => verifyEngine
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(engine_manifest_exports);
|
|
33
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
34
|
+
var import_node_path = __toESM(require("node:path"));
|
|
35
|
+
var import_node_crypto = require("node:crypto");
|
|
36
|
+
const verified = /* @__PURE__ */ new Map();
|
|
37
|
+
function hashFile(file) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
40
|
+
import_node_fs.default.createReadStream(file).on("data", (chunk) => hash.update(chunk)).on("error", reject).on("end", () => resolve(hash.digest("hex")));
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function readManifest(dir) {
|
|
44
|
+
let raw;
|
|
45
|
+
try {
|
|
46
|
+
raw = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(dir, "engine.json"), "utf-8"));
|
|
47
|
+
} catch {
|
|
48
|
+
return "no engine is installed";
|
|
49
|
+
}
|
|
50
|
+
const m = raw;
|
|
51
|
+
if (typeof m.name !== "string" || typeof m.version !== "string" || typeof m.adapter !== "string" || !m.files || typeof m.files !== "object") {
|
|
52
|
+
return "the engine manifest is malformed";
|
|
53
|
+
}
|
|
54
|
+
if (!(m.adapter in m.files)) return "the engine manifest does not cover its adapter";
|
|
55
|
+
for (const [rel, sha] of Object.entries(m.files)) {
|
|
56
|
+
if (typeof sha !== "string" || !/^[0-9a-f]{64}$/.test(sha)) return "the engine manifest is malformed";
|
|
57
|
+
if (import_node_path.default.isAbsolute(rel) || rel.split(/[\\/]/).includes("..")) return "the engine manifest names a file outside the engine";
|
|
58
|
+
}
|
|
59
|
+
return m;
|
|
60
|
+
}
|
|
61
|
+
async function verifyEngine(dir, pin) {
|
|
62
|
+
const read = readManifest(dir);
|
|
63
|
+
if (typeof read === "string") return { ok: false, reason: read };
|
|
64
|
+
let manifest = read;
|
|
65
|
+
if (pin) {
|
|
66
|
+
if (read.version !== pin.version) return { ok: false, reason: `the engine is ${read.version}; this build expects ${pin.version}` };
|
|
67
|
+
if (!(read.adapter in pin.files)) return { ok: false, reason: "the engine's adapter is not one this build pinned" };
|
|
68
|
+
manifest = { ...read, files: pin.files, networkFree: pin.networkFree === true };
|
|
69
|
+
}
|
|
70
|
+
const stats = [];
|
|
71
|
+
for (const rel of Object.keys(manifest.files)) {
|
|
72
|
+
let st;
|
|
73
|
+
try {
|
|
74
|
+
st = import_node_fs.default.lstatSync(import_node_path.default.join(dir, rel));
|
|
75
|
+
} catch {
|
|
76
|
+
return { ok: false, reason: `the engine is missing ${rel}` };
|
|
77
|
+
}
|
|
78
|
+
if (!st.isFile()) return { ok: false, reason: `the engine's ${rel} is not a regular file` };
|
|
79
|
+
stats.push(`${rel}:${st.size}:${st.mtimeMs}`);
|
|
80
|
+
}
|
|
81
|
+
const stamp = `${JSON.stringify(manifest.files)}|${manifest.version}|${manifest.networkFree === true}|${stats.join("|")}`;
|
|
82
|
+
const cached = verified.get(dir);
|
|
83
|
+
if (cached && cached.stamp === stamp) return cached.result;
|
|
84
|
+
let result = { ok: true, manifest };
|
|
85
|
+
for (const [rel, expected] of Object.entries(manifest.files)) {
|
|
86
|
+
if (await hashFile(import_node_path.default.join(dir, rel)) !== expected) {
|
|
87
|
+
result = { ok: false, reason: `the engine's ${rel} does not match the hash it was built with` };
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
verified.set(dir, { stamp, result });
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
95
|
+
0 && (module.exports = {
|
|
96
|
+
verifyEngine
|
|
97
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var network_proof_exports = {};
|
|
19
|
+
__export(network_proof_exports, {
|
|
20
|
+
proveNetworkFree: () => proveNetworkFree,
|
|
21
|
+
removedGlobals: () => removedGlobals,
|
|
22
|
+
withoutSymbolLists: () => withoutSymbolLists
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(network_proof_exports);
|
|
25
|
+
const NETWORK_IMPORT = /^(__syscall_(socket|socketpair|connect|bind|listen|accept4?|getsockname|getpeername|getsockopt|setsockopt|sendto|recvfrom|sendmsg|recvmsg|shutdown)|getaddrinfo|getnameinfo|gethostbyname2?|gethostbyaddr|_emscripten_lookup_name)$|fetch|websocket|xhr/i;
|
|
26
|
+
const FORBIDDEN_IN_GLUE = [
|
|
27
|
+
["SOCKFS", /\bSOCKFS\b/, null],
|
|
28
|
+
["WebSocket", /\bWebSocket\b/, "WebSocket"],
|
|
29
|
+
["XMLHttpRequest", /\bXMLHttpRequest\b/, "XMLHttpRequest"],
|
|
30
|
+
["a network module", /require\(\s*["'](?:node:)?(?:net|tls|http|https|http2|dgram|dns|ws)["']\s*\)/, null],
|
|
31
|
+
["fetch()", /\bfetch\s*\(/, "fetch"]
|
|
32
|
+
];
|
|
33
|
+
function withoutSymbolLists(glue) {
|
|
34
|
+
return glue.replace(/\bvar\s+(?:unexportedSymbols|missingLibrarySymbols)\s*=\s*\[(?:\s*"[\w$]+"\s*,?)*\s*\]\s*;?/g, "");
|
|
35
|
+
}
|
|
36
|
+
function removedGlobals(adapter) {
|
|
37
|
+
const list = adapter?.match(/const\s+NETWORK_GLOBALS\s*=\s*\[([^\]]*)\]/)?.[1];
|
|
38
|
+
if (!list || !/async function load\([^)]*\)\s*\{\s*withoutNetworkGlobals\(\);/.test(adapter ?? "")) return /* @__PURE__ */ new Set();
|
|
39
|
+
return new Set(Array.from(list.matchAll(/['"]([A-Za-z]+)['"]/g), (m) => m[1]));
|
|
40
|
+
}
|
|
41
|
+
function stubValue(glue, importName) {
|
|
42
|
+
const js = `_${importName}`.replace(/\$/g, "\\$");
|
|
43
|
+
const arrow = new RegExp(`(?:var|let|const)\\s+${js}\\s*=\\s*\\([^)]*\\)\\s*=>\\s*(-?\\d+)\\s*[;,\\n]`);
|
|
44
|
+
const ident = "[A-Za-z_$][\\w$]*";
|
|
45
|
+
const proxy = `if\\s*\\(\\s*ENVIRONMENT_IS_PTHREAD\\s*\\)\\s*return\\s+proxyToMainThread\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*[01]\\s*(?:,\\s*${ident}\\s*)*\\)\\s*;\\s*`;
|
|
46
|
+
const unsigned = `(?:${ident}\\s*>>>=\\s*0\\s*;\\s*)*`;
|
|
47
|
+
const fn = new RegExp(`function\\s+${js}\\s*\\([^)]*\\)\\s*\\{\\s*(?:${proxy})?${unsigned}return\\s+(-?\\d+)\\s*;?\\s*\\}`);
|
|
48
|
+
const m = glue.match(arrow) ?? glue.match(fn);
|
|
49
|
+
return m ? Number(m[1]) : null;
|
|
50
|
+
}
|
|
51
|
+
function proveNetworkFree(wasm, glue, adapter) {
|
|
52
|
+
const imports = WebAssembly.Module.imports(new WebAssembly.Module(wasm)).filter((i) => i.kind === "function");
|
|
53
|
+
const networkImports = imports.filter((i) => NETWORK_IMPORT.test(i.name)).map((i) => i.name);
|
|
54
|
+
const failures = [];
|
|
55
|
+
const stubs = {};
|
|
56
|
+
for (const name of networkImports) {
|
|
57
|
+
const value = stubValue(glue, name);
|
|
58
|
+
if (value === null) failures.push(`${name} is imported and is not a no-network stub`);
|
|
59
|
+
else stubs[name] = value;
|
|
60
|
+
}
|
|
61
|
+
const removed = removedGlobals(adapter);
|
|
62
|
+
const code = withoutSymbolLists(glue);
|
|
63
|
+
for (const [what, re, global] of FORBIDDEN_IN_GLUE) {
|
|
64
|
+
if (re.test(code) && !(global && removed.has(global))) failures.push(`the glue contains ${what}`);
|
|
65
|
+
}
|
|
66
|
+
return { imports: imports.length, networkImports, stubs, networkFree: failures.length === 0, failures };
|
|
67
|
+
}
|
|
68
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
69
|
+
0 && (module.exports = {
|
|
70
|
+
proveNetworkFree,
|
|
71
|
+
removedGlobals,
|
|
72
|
+
withoutSymbolLists
|
|
73
|
+
});
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var rendition_service_exports = {};
|
|
29
|
+
__export(rendition_service_exports, {
|
|
30
|
+
CONVERTIBLE: () => CONVERTIBLE,
|
|
31
|
+
existingRendition: () => existingRendition,
|
|
32
|
+
getEngineHost: () => getEngineHost,
|
|
33
|
+
renditionOf: () => renditionOf,
|
|
34
|
+
stopEngine: () => stopEngine
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(rendition_service_exports);
|
|
37
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
38
|
+
var import_node_path = __toESM(require("node:path"));
|
|
39
|
+
var import_node_crypto = require("node:crypto");
|
|
40
|
+
var import_persistence = require("../persistence");
|
|
41
|
+
var import_confined_fs = require("../confined-fs");
|
|
42
|
+
var import_artefact_content_service = require("../artefact-content-service");
|
|
43
|
+
var import_command = require("../../mcp/connector/command");
|
|
44
|
+
var import_engine_lock = require("./engine-lock");
|
|
45
|
+
var import_engine_host = require("./engine-host");
|
|
46
|
+
const CONVERTIBLE = {
|
|
47
|
+
docx: 25 * 1024 * 1024,
|
|
48
|
+
pptx: 100 * 1024 * 1024,
|
|
49
|
+
xlsx: 25 * 1024 * 1024,
|
|
50
|
+
xls: 25 * 1024 * 1024
|
|
51
|
+
};
|
|
52
|
+
const CACHE_CAP_BYTES = 500 * 1024 * 1024;
|
|
53
|
+
let sharedHost;
|
|
54
|
+
function getEngineHost() {
|
|
55
|
+
if (sharedHost !== void 0) return sharedHost;
|
|
56
|
+
const resourcesPath = process.resourcesPath;
|
|
57
|
+
const packaged = (0, import_command.isPackagedElectron)({ execPath: process.execPath, electronVersion: process.versions.electron });
|
|
58
|
+
if (packaged) {
|
|
59
|
+
sharedHost = import_engine_lock.ENGINE_PIN && resourcesPath ? new import_engine_host.EngineHost({
|
|
60
|
+
engineDir: import_node_path.default.join(resourcesPath, "rendition", "engine"),
|
|
61
|
+
childScript: import_node_path.default.join(resourcesPath, "rendition", "engine-child.cjs"),
|
|
62
|
+
pinned: import_engine_lock.ENGINE_PIN
|
|
63
|
+
}) : null;
|
|
64
|
+
} else {
|
|
65
|
+
sharedHost = new import_engine_host.EngineHost({
|
|
66
|
+
engineDir: process.env.CODETRELLIS_RENDITION_ENGINE || import_node_path.default.join(process.cwd(), "resources", "rendition", "engine"),
|
|
67
|
+
childScript: import_node_path.default.join(process.cwd(), "out", "rendition", "engine-child.cjs"),
|
|
68
|
+
pinned: import_engine_lock.ENGINE_PIN
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return sharedHost;
|
|
72
|
+
}
|
|
73
|
+
function stopEngine() {
|
|
74
|
+
sharedHost?.stop();
|
|
75
|
+
}
|
|
76
|
+
function cacheRoot() {
|
|
77
|
+
const root = import_node_path.default.join((0, import_persistence.getDataDir)(), "renditions");
|
|
78
|
+
import_node_fs.default.mkdirSync(root, { recursive: true });
|
|
79
|
+
return root;
|
|
80
|
+
}
|
|
81
|
+
function prune(root) {
|
|
82
|
+
const entries = import_node_fs.default.readdirSync(root, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".pdf")).map((e) => {
|
|
83
|
+
const st = import_node_fs.default.statSync(import_node_path.default.join(root, e.name));
|
|
84
|
+
return { name: e.name, size: st.size, mtimeMs: st.mtimeMs };
|
|
85
|
+
}).sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
86
|
+
let total = entries.reduce((n, e) => n + e.size, 0);
|
|
87
|
+
for (const e of entries) {
|
|
88
|
+
if (total <= CACHE_CAP_BYTES) break;
|
|
89
|
+
try {
|
|
90
|
+
(0, import_confined_fs.removeWithin)(root, e.name, {}, "rendition");
|
|
91
|
+
total -= e.size;
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function renditionName(bytes, version) {
|
|
97
|
+
const sha = (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
|
|
98
|
+
return `${sha}-${version.replace(/[^A-Za-z0-9._-]/g, "_")}.pdf`;
|
|
99
|
+
}
|
|
100
|
+
const RENDITION_READ_CAP = 100 * 1024 * 1024;
|
|
101
|
+
async function existingRendition(bytes, ext, host = getEngineHost()) {
|
|
102
|
+
if (!host || !CONVERTIBLE[ext]) return null;
|
|
103
|
+
try {
|
|
104
|
+
const checked = await host.check();
|
|
105
|
+
if (!checked.ok) return null;
|
|
106
|
+
const rel = renditionName(bytes, checked.manifest.version);
|
|
107
|
+
return await (0, import_artefact_content_service.readServableCapped)({ root: cacheRoot(), rel, contentType: "application/pdf", itemUid: "" }, RENDITION_READ_CAP);
|
|
108
|
+
} catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
113
|
+
async function renditionOf(uid, host = getEngineHost()) {
|
|
114
|
+
const file = await (0, import_artefact_content_service.resolveServable)(uid);
|
|
115
|
+
if (!file) return { ok: false, status: 404, reason: "This attachment is not a file that can be shown" };
|
|
116
|
+
const ext = import_node_path.default.extname(file.rel).slice(1).toLowerCase();
|
|
117
|
+
const cap = CONVERTIBLE[ext];
|
|
118
|
+
if (!cap) return { ok: false, status: 415, reason: `.${ext} files are not converted` };
|
|
119
|
+
if (!host) return { ok: false, status: 503, reason: "this build carries no conversion engine" };
|
|
120
|
+
const checked = await host.check();
|
|
121
|
+
if (!checked.ok) return { ok: false, status: 503, reason: checked.reason };
|
|
122
|
+
let bytes;
|
|
123
|
+
try {
|
|
124
|
+
bytes = await (0, import_artefact_content_service.readServableCapped)(file, cap);
|
|
125
|
+
} catch {
|
|
126
|
+
return { ok: false, status: 404, reason: "The file is not there, or is not a regular file in the project" };
|
|
127
|
+
}
|
|
128
|
+
if (!bytes) return { ok: false, status: 413, reason: "This file is larger than the viewer will convert" };
|
|
129
|
+
const name = renditionName(bytes, checked.manifest.version);
|
|
130
|
+
const root = cacheRoot();
|
|
131
|
+
const served = () => ({ ok: true, file: { root, rel: name, contentType: "application/pdf", itemUid: file.itemUid } });
|
|
132
|
+
try {
|
|
133
|
+
const cached = (0, import_confined_fs.resolveWithin)(root, name, "rendition");
|
|
134
|
+
if (import_node_fs.default.lstatSync(cached).isFile()) {
|
|
135
|
+
const now = /* @__PURE__ */ new Date();
|
|
136
|
+
import_node_fs.default.utimesSync(cached, now, now);
|
|
137
|
+
return served();
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
const running = inFlight.get(name);
|
|
142
|
+
if (running) return running;
|
|
143
|
+
const job = (async () => {
|
|
144
|
+
try {
|
|
145
|
+
let pdf;
|
|
146
|
+
try {
|
|
147
|
+
pdf = await host.convert(bytes, ext);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
if (!(err instanceof import_engine_host.ConversionTimedOut)) throw err;
|
|
150
|
+
pdf = await host.convert(bytes, ext);
|
|
151
|
+
}
|
|
152
|
+
(0, import_confined_fs.writeFileWithin)(root, name, Buffer.from(pdf.buffer, pdf.byteOffset, pdf.byteLength), "rendition");
|
|
153
|
+
prune(root);
|
|
154
|
+
return served();
|
|
155
|
+
} catch (err) {
|
|
156
|
+
if (err instanceof import_engine_host.EngineUnavailable || err instanceof import_engine_host.ConversionFailed) {
|
|
157
|
+
return { ok: false, status: 503, reason: err.message };
|
|
158
|
+
}
|
|
159
|
+
console.warn("[rendition] unexpected failure", err);
|
|
160
|
+
return { ok: false, status: 503, reason: "The document could not be converted" };
|
|
161
|
+
} finally {
|
|
162
|
+
inFlight.delete(name);
|
|
163
|
+
}
|
|
164
|
+
})();
|
|
165
|
+
inFlight.set(name, job);
|
|
166
|
+
return job;
|
|
167
|
+
}
|
|
168
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
169
|
+
0 && (module.exports = {
|
|
170
|
+
CONVERTIBLE,
|
|
171
|
+
existingRendition,
|
|
172
|
+
getEngineHost,
|
|
173
|
+
renditionOf,
|
|
174
|
+
stopEngine
|
|
175
|
+
});
|