codetrellis 0.0.0-stage → 0.3.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 +41 -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/cli-install.js +249 -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/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/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 +275 -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 +209 -0
- package/src/cli/conformity.js +106 -0
- package/src/cli/desktop.js +91 -0
- package/src/cli/main.js +411 -0
- package/src/cli/pipeline.js +109 -0
- package/src/cli/plan-verbs.js +259 -0
- package/src/cli/review-adapters.js +220 -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 +360 -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,323 @@
|
|
|
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 pairing_server_exports = {};
|
|
29
|
+
__export(pairing_server_exports, {
|
|
30
|
+
deriveConfirmationCode: () => import_peer_auth.deriveConfirmationCode,
|
|
31
|
+
getAllAddresses: () => getAllAddresses,
|
|
32
|
+
isPairingServerActive: () => isPairingServerActive,
|
|
33
|
+
startPairingServer: () => startPairingServer,
|
|
34
|
+
stopPairingServer: () => stopPairingServer
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(pairing_server_exports);
|
|
37
|
+
var import_node_http = __toESM(require("node:http"));
|
|
38
|
+
var import_node_os = __toESM(require("node:os"));
|
|
39
|
+
var import_node_crypto = require("node:crypto");
|
|
40
|
+
var import_peer_auth = require("./peer-auth");
|
|
41
|
+
var import_sdp_fingerprint = require("../../shared/lib/sdp-fingerprint");
|
|
42
|
+
var import_sdp_minimal = require("../../shared/lib/sdp-minimal");
|
|
43
|
+
var import_peer_auth2 = require("./peer-auth");
|
|
44
|
+
const PAIRING_TIMEOUT_MS = 6e4;
|
|
45
|
+
const CODE_LENGTH = 6;
|
|
46
|
+
const NONCE_BYTES = 16;
|
|
47
|
+
const MAX_BODY_BYTES = 256 * 1024;
|
|
48
|
+
const SOCKET_TIMEOUT_MS = 15e3;
|
|
49
|
+
const MAX_CODE_ATTEMPTS = 5;
|
|
50
|
+
let activeServer = null;
|
|
51
|
+
let activeTimeout = null;
|
|
52
|
+
function startPairingServer(opts) {
|
|
53
|
+
stopPairingServer();
|
|
54
|
+
const code = generateCode();
|
|
55
|
+
const nonce = (0, import_node_crypto.randomBytes)(NONCE_BYTES).toString("hex");
|
|
56
|
+
const pairingId = (0, import_node_crypto.randomUUID)();
|
|
57
|
+
const sharedSecret = (0, import_peer_auth.generateSharedSecret)();
|
|
58
|
+
const sdpParams = (0, import_sdp_minimal.extractSdpParams)(opts.offerSdp, opts.iceCandidates);
|
|
59
|
+
return new Promise((resolveStart, rejectStart) => {
|
|
60
|
+
let answerResolve = null;
|
|
61
|
+
let answerReject = null;
|
|
62
|
+
let answered = false;
|
|
63
|
+
let codeAttempts = 0;
|
|
64
|
+
let offerClaimedBy = null;
|
|
65
|
+
const answerPromise = new Promise((res, rej) => {
|
|
66
|
+
answerResolve = res;
|
|
67
|
+
answerReject = rej;
|
|
68
|
+
});
|
|
69
|
+
const noteBadCode = () => {
|
|
70
|
+
codeAttempts += 1;
|
|
71
|
+
if (codeAttempts >= MAX_CODE_ATTEMPTS) {
|
|
72
|
+
console.warn(`[PairingServer] ${codeAttempts} wrong pairing codes \u2014 closing the window`);
|
|
73
|
+
answerReject?.(new Error("Too many incorrect pairing codes"));
|
|
74
|
+
stopThis();
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const readBody = (req) => new Promise((resolve, reject) => {
|
|
78
|
+
let body = "";
|
|
79
|
+
let size = 0;
|
|
80
|
+
req.on("data", (chunk) => {
|
|
81
|
+
size += Buffer.byteLength(chunk);
|
|
82
|
+
if (size > MAX_BODY_BYTES) {
|
|
83
|
+
reject(new Error("Request body too large"));
|
|
84
|
+
req.destroy();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
body += chunk;
|
|
88
|
+
});
|
|
89
|
+
req.on("end", () => resolve(body));
|
|
90
|
+
req.on("error", reject);
|
|
91
|
+
});
|
|
92
|
+
const stopThis = () => {
|
|
93
|
+
if (activeServer === server) {
|
|
94
|
+
stopPairingServer();
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
server.closeAllConnections?.();
|
|
99
|
+
server.close();
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const server = import_node_http.default.createServer((req, res) => {
|
|
104
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
105
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
106
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
107
|
+
if (req.method === "OPTIONS") {
|
|
108
|
+
res.writeHead(204);
|
|
109
|
+
res.end();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
|
|
113
|
+
if (req.method === "POST" && url.pathname === "/offer") {
|
|
114
|
+
readBody(req).then((body) => {
|
|
115
|
+
let data;
|
|
116
|
+
try {
|
|
117
|
+
data = JSON.parse(body);
|
|
118
|
+
} catch {
|
|
119
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
120
|
+
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (data.c !== code) {
|
|
124
|
+
noteBadCode();
|
|
125
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
126
|
+
res.end(JSON.stringify({ error: "Invalid pairing code" }));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const source = req.socket.remoteAddress ?? "unknown";
|
|
130
|
+
if (offerClaimedBy !== null && offerClaimedBy !== source) {
|
|
131
|
+
res.writeHead(409, { "Content-Type": "application/json" });
|
|
132
|
+
res.end(JSON.stringify({ error: "Offer already claimed" }));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
offerClaimedBy = source;
|
|
136
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
137
|
+
res.end(JSON.stringify({
|
|
138
|
+
offer: opts.offerSdp,
|
|
139
|
+
ice: opts.iceCandidates,
|
|
140
|
+
fingerprint: opts.fingerprint,
|
|
141
|
+
nonce,
|
|
142
|
+
pairingId
|
|
143
|
+
}));
|
|
144
|
+
}).catch((err) => {
|
|
145
|
+
console.warn(`[PairingServer] Rejected offer request: ${err.message}`);
|
|
146
|
+
if (!res.headersSent) {
|
|
147
|
+
res.writeHead(413, { "Content-Type": "application/json" });
|
|
148
|
+
res.end(JSON.stringify({ error: "Request body too large" }));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (req.method === "POST" && url.pathname === "/answer") {
|
|
154
|
+
readBody(req).then((body) => {
|
|
155
|
+
let data;
|
|
156
|
+
try {
|
|
157
|
+
data = JSON.parse(body);
|
|
158
|
+
} catch {
|
|
159
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
160
|
+
res.end(JSON.stringify({ error: "Invalid JSON" }));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (typeof data.fingerprint !== "string" || typeof data.mac !== "string") {
|
|
164
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
165
|
+
res.end(JSON.stringify({ error: "Missing fingerprint or mac" }));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (!(0, import_peer_auth2.macsEqual)((0, import_peer_auth2.computeAnswerMac)(code, nonce, data.fingerprint), data.mac)) {
|
|
169
|
+
noteBadCode();
|
|
170
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
171
|
+
res.end(JSON.stringify({ error: "Invalid pairing code" }));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (data.nonce !== nonce) {
|
|
175
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
176
|
+
res.end(JSON.stringify({ error: "Nonce mismatch" }));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (typeof data.answer !== "string" || typeof data.fingerprint !== "string") {
|
|
180
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
181
|
+
res.end(JSON.stringify({ error: "Missing answer or fingerprint" }));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (answered) {
|
|
185
|
+
res.writeHead(409, { "Content-Type": "application/json" });
|
|
186
|
+
res.end(JSON.stringify({ error: "Already answered" }));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const source = req.socket.remoteAddress ?? "unknown";
|
|
190
|
+
if (offerClaimedBy !== null && source !== offerClaimedBy) {
|
|
191
|
+
console.warn(`[PairingServer] Rejected answer from ${source} \u2014 the offer was claimed by another client`);
|
|
192
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
193
|
+
res.end(JSON.stringify({ error: "Not the client that requested the offer" }));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
let sdpFingerprint;
|
|
197
|
+
try {
|
|
198
|
+
sdpFingerprint = (0, import_sdp_fingerprint.extractSingleFingerprint)(data.answer);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
console.warn(`[PairingServer] Rejected answer \u2014 unusable SDP: ${err.message}`);
|
|
201
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
202
|
+
res.end(JSON.stringify({ error: "Answer SDP does not commit to a single certificate" }));
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (!(0, import_sdp_fingerprint.fingerprintsEqual)(sdpFingerprint, data.fingerprint)) {
|
|
206
|
+
console.warn("[PairingServer] Rejected answer \u2014 claimed fingerprint disagrees with the SDP");
|
|
207
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
208
|
+
res.end(JSON.stringify({ error: "Claimed fingerprint does not match the answer SDP" }));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
answered = true;
|
|
212
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
213
|
+
res.end(JSON.stringify({ accepted: true, pairingId }));
|
|
214
|
+
if (activeTimeout) {
|
|
215
|
+
clearTimeout(activeTimeout);
|
|
216
|
+
activeTimeout = null;
|
|
217
|
+
}
|
|
218
|
+
const answer = {
|
|
219
|
+
answerSdp: data.answer,
|
|
220
|
+
iceCandidates: Array.isArray(data.ice) ? data.ice : [],
|
|
221
|
+
fingerprint: sdpFingerprint,
|
|
222
|
+
nonce: String(data.nonce),
|
|
223
|
+
pairingId
|
|
224
|
+
};
|
|
225
|
+
answerResolve?.(answer);
|
|
226
|
+
setTimeout(stopThis, 500);
|
|
227
|
+
}).catch((err) => {
|
|
228
|
+
console.warn(`[PairingServer] Rejected answer body: ${err.message}`);
|
|
229
|
+
if (!res.headersSent) {
|
|
230
|
+
res.writeHead(413, { "Content-Type": "application/json" });
|
|
231
|
+
res.end(JSON.stringify({ error: "Request body too large" }));
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
237
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
238
|
+
});
|
|
239
|
+
server.setTimeout(SOCKET_TIMEOUT_MS, (socket) => socket.destroy());
|
|
240
|
+
server.headersTimeout = SOCKET_TIMEOUT_MS;
|
|
241
|
+
server.requestTimeout = SOCKET_TIMEOUT_MS;
|
|
242
|
+
server.on("error", (err) => {
|
|
243
|
+
console.error("[PairingServer] Error:", err);
|
|
244
|
+
rejectStart(err);
|
|
245
|
+
});
|
|
246
|
+
server.listen(0, "0.0.0.0", () => {
|
|
247
|
+
const addr = server.address();
|
|
248
|
+
if (!addr || typeof addr === "string") {
|
|
249
|
+
rejectStart(new Error("Failed to get server address"));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
activeServer = server;
|
|
253
|
+
const port = addr.port;
|
|
254
|
+
const addresses = getAllAddresses();
|
|
255
|
+
const lanAddress = addresses[0] ?? "127.0.0.1";
|
|
256
|
+
console.log(`[PairingServer] Listening on ${addresses.join(", ") || lanAddress}:${port} (code=${code})`);
|
|
257
|
+
activeTimeout = setTimeout(() => {
|
|
258
|
+
if (!answered) {
|
|
259
|
+
console.log("[PairingServer] Timed out after 60s");
|
|
260
|
+
answerReject?.(new Error("Pairing timed out"));
|
|
261
|
+
}
|
|
262
|
+
stopPairingServer();
|
|
263
|
+
}, PAIRING_TIMEOUT_MS);
|
|
264
|
+
resolveStart({
|
|
265
|
+
code,
|
|
266
|
+
address: lanAddress,
|
|
267
|
+
addresses,
|
|
268
|
+
port,
|
|
269
|
+
nonce,
|
|
270
|
+
pairingId,
|
|
271
|
+
sdpParams,
|
|
272
|
+
sharedSecret,
|
|
273
|
+
waitForAnswer: () => answerPromise,
|
|
274
|
+
stop: stopThis
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function stopPairingServer() {
|
|
280
|
+
if (activeTimeout) {
|
|
281
|
+
clearTimeout(activeTimeout);
|
|
282
|
+
activeTimeout = null;
|
|
283
|
+
}
|
|
284
|
+
if (activeServer) {
|
|
285
|
+
try {
|
|
286
|
+
activeServer.closeAllConnections?.();
|
|
287
|
+
activeServer.close();
|
|
288
|
+
} catch {
|
|
289
|
+
}
|
|
290
|
+
activeServer = null;
|
|
291
|
+
console.log("[PairingServer] Stopped");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function isPairingServerActive() {
|
|
295
|
+
return activeServer !== null;
|
|
296
|
+
}
|
|
297
|
+
function generateCode() {
|
|
298
|
+
const num = (0, import_node_crypto.randomBytes)(4).readUInt32BE(0) % 1e6;
|
|
299
|
+
return num.toString().padStart(CODE_LENGTH, "0");
|
|
300
|
+
}
|
|
301
|
+
function getAllAddresses() {
|
|
302
|
+
const out = [];
|
|
303
|
+
const interfaces = import_node_os.default.networkInterfaces();
|
|
304
|
+
for (const name of Object.keys(interfaces)) {
|
|
305
|
+
for (const addr of interfaces[name] ?? []) {
|
|
306
|
+
if (addr.family === "IPv4" && !addr.internal) out.push(addr.address);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const rank = (ip) => {
|
|
310
|
+
if (/^(192\.168\.|10\.|172\.(1[6-9]|2\d|3[01])\.)/.test(ip)) return 0;
|
|
311
|
+
if (/^100\.(6[4-9]|[7-9]\d|1[01]\d|12[0-7])\./.test(ip)) return 1;
|
|
312
|
+
return 2;
|
|
313
|
+
};
|
|
314
|
+
return out.sort((a, b) => rank(a) - rank(b));
|
|
315
|
+
}
|
|
316
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
317
|
+
0 && (module.exports = {
|
|
318
|
+
deriveConfirmationCode,
|
|
319
|
+
getAllAddresses,
|
|
320
|
+
isPairingServerActive,
|
|
321
|
+
startPairingServer,
|
|
322
|
+
stopPairingServer
|
|
323
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
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 pairing_service_exports = {};
|
|
19
|
+
__export(pairing_service_exports, {
|
|
20
|
+
cancelPairing: () => cancelPairing,
|
|
21
|
+
confirmPairing: () => confirmPairing,
|
|
22
|
+
getConfirmationCode: () => getConfirmationCode,
|
|
23
|
+
getDesktopFingerprint: () => getDesktopFingerprint,
|
|
24
|
+
getPairingId: () => getPairingId,
|
|
25
|
+
getPairingNonce: () => getPairingNonce,
|
|
26
|
+
getStoredAnswer: () => getStoredAnswer,
|
|
27
|
+
getStoredOfferSdp: () => getStoredOfferSdp,
|
|
28
|
+
initiatePairing: () => initiatePairing,
|
|
29
|
+
isPairingActive: () => isPairingActive
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(pairing_service_exports);
|
|
32
|
+
var import_pairing_server = require("./pairing-server");
|
|
33
|
+
var import_paired_device_service = require("./paired-device-service");
|
|
34
|
+
var import_sdp_minimal = require("../../shared/lib/sdp-minimal");
|
|
35
|
+
var import_webrtc_service = require("./webrtc-service");
|
|
36
|
+
var import_types = require("../../shared/types");
|
|
37
|
+
var import_peer_capabilities = require("./peer-capabilities");
|
|
38
|
+
let activePairing = null;
|
|
39
|
+
async function initiatePairing(offerSdp, iceCandidates, fingerprint) {
|
|
40
|
+
cancelPairing();
|
|
41
|
+
const server = await (0, import_pairing_server.startPairingServer)({
|
|
42
|
+
offerSdp,
|
|
43
|
+
iceCandidates,
|
|
44
|
+
fingerprint
|
|
45
|
+
});
|
|
46
|
+
const qrPayload = {
|
|
47
|
+
v: 5,
|
|
48
|
+
hs: server.addresses,
|
|
49
|
+
// every reachable host — LAN and VPN alike
|
|
50
|
+
p: server.port,
|
|
51
|
+
c: server.code,
|
|
52
|
+
iu: server.sdpParams.iu,
|
|
53
|
+
ip: server.sdpParams.ip,
|
|
54
|
+
fp: (0, import_sdp_minimal.stripColonFingerprint)(server.sdpParams.fp),
|
|
55
|
+
cp: server.sdpParams.candidatePort,
|
|
56
|
+
mms: server.sdpParams.maxMessageSize,
|
|
57
|
+
n: server.nonce
|
|
58
|
+
};
|
|
59
|
+
console.log(
|
|
60
|
+
`[Pairing] v5 initiated \u2014 code=${server.code} addr=${server.address}:${server.port} qr=${JSON.stringify(qrPayload).length}B`
|
|
61
|
+
);
|
|
62
|
+
activePairing = {
|
|
63
|
+
server,
|
|
64
|
+
desktopFingerprint: fingerprint,
|
|
65
|
+
offerSdp,
|
|
66
|
+
answer: null,
|
|
67
|
+
confirmCode: null,
|
|
68
|
+
sharedSecret: server.sharedSecret
|
|
69
|
+
};
|
|
70
|
+
const wrappedWait = async () => {
|
|
71
|
+
const answer = await server.waitForAnswer();
|
|
72
|
+
if (activePairing) {
|
|
73
|
+
activePairing.answer = answer;
|
|
74
|
+
activePairing.confirmCode = (0, import_pairing_server.deriveConfirmationCode)(
|
|
75
|
+
server.nonce,
|
|
76
|
+
fingerprint,
|
|
77
|
+
answer.fingerprint
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return answer;
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
qrPayload,
|
|
84
|
+
offerSdp,
|
|
85
|
+
waitForAnswer: wrappedWait
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function getConfirmationCode() {
|
|
89
|
+
return activePairing?.confirmCode ?? null;
|
|
90
|
+
}
|
|
91
|
+
function getStoredOfferSdp() {
|
|
92
|
+
return activePairing?.offerSdp ?? null;
|
|
93
|
+
}
|
|
94
|
+
function getStoredAnswer() {
|
|
95
|
+
return activePairing?.answer ?? null;
|
|
96
|
+
}
|
|
97
|
+
function getDesktopFingerprint() {
|
|
98
|
+
return activePairing?.desktopFingerprint ?? null;
|
|
99
|
+
}
|
|
100
|
+
function getPairingNonce() {
|
|
101
|
+
return activePairing?.server.nonce ?? null;
|
|
102
|
+
}
|
|
103
|
+
function getPairingId() {
|
|
104
|
+
return activePairing?.server.pairingId ?? null;
|
|
105
|
+
}
|
|
106
|
+
function confirmPairing(userCode, deviceAlias, deviceType) {
|
|
107
|
+
if (!activePairing?.answer || !activePairing.confirmCode) {
|
|
108
|
+
console.warn("[Pairing] No answer received yet \u2014 cannot confirm");
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
if (userCode !== activePairing.confirmCode) {
|
|
112
|
+
console.warn("[Pairing] Confirmation code mismatch");
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
116
|
+
const device = {
|
|
117
|
+
fingerprint: activePairing.answer.fingerprint,
|
|
118
|
+
pairingId: activePairing.server.pairingId,
|
|
119
|
+
alias: deviceAlias,
|
|
120
|
+
deviceType,
|
|
121
|
+
pairedAt: now,
|
|
122
|
+
lastConnected: null,
|
|
123
|
+
// A REAL SECRET, not the `''` with a `// TODO` beside it that every record
|
|
124
|
+
// used to carry (Phase 19, finding 1.2). Reconnect now requires a proof
|
|
125
|
+
// computed with this; a `pairingId` on its own no longer gets in.
|
|
126
|
+
sharedSecret: activePairing.sharedSecret,
|
|
127
|
+
instanceId: null,
|
|
128
|
+
// Pairing a phone does not hand it a shell or the settings that control
|
|
129
|
+
// network exposure — those are granted per device, afterwards (finding 17).
|
|
130
|
+
capabilities: [...import_peer_capabilities.DEFAULT_GRANTS],
|
|
131
|
+
confirmedAt: now
|
|
132
|
+
};
|
|
133
|
+
(0, import_paired_device_service.upsertPairedDevice)(device);
|
|
134
|
+
console.log(`[Pairing] Confirmed \u2014 device "${deviceAlias}" (${device.fingerprint.slice(0, 12)}\u2026)`);
|
|
135
|
+
deliverPairingSecret(device);
|
|
136
|
+
activePairing = null;
|
|
137
|
+
return device;
|
|
138
|
+
}
|
|
139
|
+
const SECRET_DELIVERY_WINDOW_MS = 6e4;
|
|
140
|
+
function deliverPairingSecret(device) {
|
|
141
|
+
const payload = JSON.stringify({
|
|
142
|
+
type: "pairing.secret",
|
|
143
|
+
pairingId: device.pairingId,
|
|
144
|
+
secret: device.sharedSecret
|
|
145
|
+
});
|
|
146
|
+
if ((0, import_webrtc_service.sendToPeer)(device.fingerprint, import_types.DATA_CHANNELS.CONTROL, payload)) {
|
|
147
|
+
console.log(`[Pairing] Delivered the reconnect secret to "${device.alias}"`);
|
|
148
|
+
(0, import_paired_device_service.touchPairedDevice)(device.fingerprint);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
console.log(`[Pairing] Control channel not open yet \u2014 will hand "${device.alias}" its secret when it is`);
|
|
152
|
+
let settled = false;
|
|
153
|
+
const finish = (ok) => {
|
|
154
|
+
if (settled) return;
|
|
155
|
+
settled = true;
|
|
156
|
+
unsubscribe();
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
if (ok) {
|
|
159
|
+
console.log(`[Pairing] Delivered the reconnect secret to "${device.alias}"`);
|
|
160
|
+
(0, import_paired_device_service.touchPairedDevice)(device.fingerprint);
|
|
161
|
+
} else {
|
|
162
|
+
console.warn(
|
|
163
|
+
`[Pairing] Never managed to deliver the reconnect secret to "${device.alias}" \u2014 that device will have to pair again.`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const unsubscribe = (0, import_webrtc_service.onConnectionStateChange)((fingerprint, state) => {
|
|
168
|
+
if (fingerprint !== device.fingerprint || state !== "connected") return;
|
|
169
|
+
if ((0, import_webrtc_service.sendToPeer)(device.fingerprint, import_types.DATA_CHANNELS.CONTROL, payload)) finish(true);
|
|
170
|
+
});
|
|
171
|
+
const timer = setTimeout(() => finish(false), SECRET_DELIVERY_WINDOW_MS);
|
|
172
|
+
if (typeof timer === "object" && timer && "unref" in timer) {
|
|
173
|
+
timer.unref();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function cancelPairing() {
|
|
177
|
+
if (activePairing) {
|
|
178
|
+
activePairing.server.stop();
|
|
179
|
+
activePairing = null;
|
|
180
|
+
console.log("[Pairing] Cancelled");
|
|
181
|
+
} else {
|
|
182
|
+
(0, import_pairing_server.stopPairingServer)();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function isPairingActive() {
|
|
186
|
+
return activePairing !== null;
|
|
187
|
+
}
|
|
188
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
189
|
+
0 && (module.exports = {
|
|
190
|
+
cancelPairing,
|
|
191
|
+
confirmPairing,
|
|
192
|
+
getConfirmationCode,
|
|
193
|
+
getDesktopFingerprint,
|
|
194
|
+
getPairingId,
|
|
195
|
+
getPairingNonce,
|
|
196
|
+
getStoredAnswer,
|
|
197
|
+
getStoredOfferSdp,
|
|
198
|
+
initiatePairing,
|
|
199
|
+
isPairingActive
|
|
200
|
+
});
|
|
@@ -0,0 +1,166 @@
|
|
|
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 pantry_resolution_service_exports = {};
|
|
29
|
+
__export(pantry_resolution_service_exports, {
|
|
30
|
+
resolveReference: () => resolveReference,
|
|
31
|
+
resolveReferences: () => resolveReferences,
|
|
32
|
+
scanPlanReferences: () => scanPlanReferences
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(pantry_resolution_service_exports);
|
|
35
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
36
|
+
var import_confined_fs = require("./confined-fs");
|
|
37
|
+
var import_trusted_roots = require("./trusted-roots");
|
|
38
|
+
var import_node_os = __toESM(require("node:os"));
|
|
39
|
+
var import_node_path = __toESM(require("node:path"));
|
|
40
|
+
var import_plans_home = require("./plans-home");
|
|
41
|
+
function resolveReferences(references, projectRoot) {
|
|
42
|
+
return references.map((ref) => resolveReference(ref, projectRoot));
|
|
43
|
+
}
|
|
44
|
+
function resolveReference(reference, projectRoot) {
|
|
45
|
+
if (!reference || typeof reference !== "string") {
|
|
46
|
+
return { reference, status: "external", reason: "Invalid reference" };
|
|
47
|
+
}
|
|
48
|
+
if (reference.startsWith("http://") || reference.startsWith("https://")) {
|
|
49
|
+
return { reference, status: "resolved" };
|
|
50
|
+
}
|
|
51
|
+
if (reference.startsWith("userdata://")) {
|
|
52
|
+
const userDataDir = process.env.CODETRELLIS_DATA_DIR ?? import_node_path.default.join(import_node_os.default.homedir(), ".codetrellis");
|
|
53
|
+
const rel = reference.replace(/^userdata:\/\//, "");
|
|
54
|
+
const absPath = import_node_path.default.resolve(userDataDir, rel);
|
|
55
|
+
if (!absPath.startsWith(import_node_path.default.resolve(userDataDir) + import_node_path.default.sep)) {
|
|
56
|
+
return { reference, status: "external", reason: "Invalid path traversal" };
|
|
57
|
+
}
|
|
58
|
+
if (import_node_fs.default.existsSync(absPath)) {
|
|
59
|
+
return { reference, status: "resolved", absolutePath: absPath };
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
reference,
|
|
63
|
+
status: "external",
|
|
64
|
+
reason: "User-local content \u2014 not available outside the original workspace"
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (!import_node_path.default.isAbsolute(reference)) {
|
|
68
|
+
const absPath = import_node_path.default.resolve(projectRoot, reference);
|
|
69
|
+
const normRoot = import_node_path.default.resolve(projectRoot);
|
|
70
|
+
if (!absPath.startsWith(normRoot + import_node_path.default.sep) && absPath !== normRoot) {
|
|
71
|
+
return { reference, status: "external", reason: "Invalid path traversal" };
|
|
72
|
+
}
|
|
73
|
+
if (import_node_fs.default.existsSync(absPath)) {
|
|
74
|
+
return { reference, status: "resolved", absolutePath: absPath };
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
reference,
|
|
78
|
+
status: "external",
|
|
79
|
+
reason: "Team-only content \u2014 request access from the item author"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const owningRoot = (0, import_trusted_roots.listTrustedRoots)().find((r) => (0, import_confined_fs.isWithin)(r, reference));
|
|
83
|
+
if (owningRoot) {
|
|
84
|
+
if (import_node_fs.default.existsSync(reference)) {
|
|
85
|
+
return { reference, status: "resolved", absolutePath: reference };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
reference,
|
|
90
|
+
status: "external",
|
|
91
|
+
reason: "Referenced file is not part of an open project on this machine"
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function scanPlanReferences(projectRoot, planSlug) {
|
|
95
|
+
projectRoot = (0, import_plans_home.plansHome)(projectRoot) ?? projectRoot;
|
|
96
|
+
const planDir = import_node_path.default.join(projectRoot, ".codetrellis", "plans", planSlug);
|
|
97
|
+
if (!import_node_fs.default.existsSync(planDir)) {
|
|
98
|
+
return { total: 0, resolved: 0, external: 0, externals: [] };
|
|
99
|
+
}
|
|
100
|
+
const references = extractReferencesFromDir(planDir);
|
|
101
|
+
const resolutions = resolveReferences(references, projectRoot);
|
|
102
|
+
const externals = resolutions.filter((r) => r.status === "external");
|
|
103
|
+
return {
|
|
104
|
+
total: resolutions.length,
|
|
105
|
+
resolved: resolutions.length - externals.length,
|
|
106
|
+
external: externals.length,
|
|
107
|
+
externals
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function extractReferencesFromDir(dir) {
|
|
111
|
+
const refs = [];
|
|
112
|
+
let entries;
|
|
113
|
+
try {
|
|
114
|
+
entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
115
|
+
} catch {
|
|
116
|
+
return refs;
|
|
117
|
+
}
|
|
118
|
+
for (const entry of entries) {
|
|
119
|
+
const fullPath = import_node_path.default.join(dir, entry.name);
|
|
120
|
+
if (entry.isDirectory()) {
|
|
121
|
+
refs.push(...extractReferencesFromDir(fullPath));
|
|
122
|
+
} else if (entry.name.endsWith(".yaml") || entry.name.endsWith(".yml")) {
|
|
123
|
+
refs.push(...extractReferencesFromYaml(fullPath));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return refs;
|
|
127
|
+
}
|
|
128
|
+
function extractReferencesFromYaml(filePath) {
|
|
129
|
+
const refs = [];
|
|
130
|
+
let content;
|
|
131
|
+
try {
|
|
132
|
+
content = import_node_fs.default.readFileSync(filePath, "utf-8");
|
|
133
|
+
} catch {
|
|
134
|
+
return refs;
|
|
135
|
+
}
|
|
136
|
+
const lines = content.split("\n");
|
|
137
|
+
let inAttachments = false;
|
|
138
|
+
let attachmentsIndent = -1;
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
const attMatch = line.match(/^(\s*)attachments:\s*$/);
|
|
141
|
+
if (attMatch) {
|
|
142
|
+
inAttachments = true;
|
|
143
|
+
attachmentsIndent = attMatch[1].length;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (inAttachments) {
|
|
147
|
+
if (line.trim() && !line.startsWith(" ".repeat(attachmentsIndent + 1))) {
|
|
148
|
+
inAttachments = false;
|
|
149
|
+
attachmentsIndent = -1;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const valMatch = line.match(/^\s+value:\s*["']?([^"'\n]+)["']?\s*$/);
|
|
153
|
+
if (valMatch) {
|
|
154
|
+
const val = valMatch[1].trim();
|
|
155
|
+
if (val) refs.push(val);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return refs;
|
|
160
|
+
}
|
|
161
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
162
|
+
0 && (module.exports = {
|
|
163
|
+
resolveReference,
|
|
164
|
+
resolveReferences,
|
|
165
|
+
scanPlanReferences
|
|
166
|
+
});
|