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,340 @@
|
|
|
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 task_attachments_service_exports = {};
|
|
29
|
+
__export(task_attachments_service_exports, {
|
|
30
|
+
addAttachment: () => addAttachment,
|
|
31
|
+
deleteAttachment: () => deleteAttachment,
|
|
32
|
+
listItemAttachments: () => listItemAttachments,
|
|
33
|
+
listPlanDocAttachments: () => listPlanDocAttachments,
|
|
34
|
+
listTaskAttachments: () => listTaskAttachments,
|
|
35
|
+
resolveAttachmentLocation: () => resolveAttachmentLocation,
|
|
36
|
+
servedContentType: () => servedContentType,
|
|
37
|
+
upsertAttachment: () => upsertAttachment,
|
|
38
|
+
validateImportedAttachment: () => validateImportedAttachment
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(task_attachments_service_exports);
|
|
41
|
+
var import_node_crypto = require("node:crypto");
|
|
42
|
+
var import_confined_fs = require("./confined-fs");
|
|
43
|
+
var import_trusted_roots = require("./trusted-roots");
|
|
44
|
+
var import_node_os = __toESM(require("node:os"));
|
|
45
|
+
var import_node_path = __toESM(require("node:path"));
|
|
46
|
+
var import_database = require("./database");
|
|
47
|
+
var import_persistence = require("./persistence");
|
|
48
|
+
var import_settings_service = require("./settings-service");
|
|
49
|
+
var import_project_config_service = require("./project-config-service");
|
|
50
|
+
var import_material_place = require("./material-place");
|
|
51
|
+
const MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;
|
|
52
|
+
const ALLOWED_ATTACHMENT_TYPES = /* @__PURE__ */ new Set([
|
|
53
|
+
"image/png",
|
|
54
|
+
"image/jpeg",
|
|
55
|
+
"image/gif",
|
|
56
|
+
"image/webp",
|
|
57
|
+
"image/svg+xml",
|
|
58
|
+
"video/mp4",
|
|
59
|
+
"video/webm",
|
|
60
|
+
"video/quicktime"
|
|
61
|
+
]);
|
|
62
|
+
function resolveAttachmentDir(targetUid, projectRoot) {
|
|
63
|
+
const location = projectRoot ? (0, import_project_config_service.getEffectiveAttachmentLocation)(projectRoot) : (0, import_settings_service.getSettings)().plans.attachmentLocation ?? "project";
|
|
64
|
+
if (location === "user" || !projectRoot) {
|
|
65
|
+
const userDataDir = process.env.CODETRELLIS_DATA_DIR ?? import_node_path.default.join(import_node_os.default.homedir(), ".codetrellis");
|
|
66
|
+
const absDir2 = import_node_path.default.join(userDataDir, "attachments", targetUid);
|
|
67
|
+
return {
|
|
68
|
+
absDir: absDir2,
|
|
69
|
+
storedValuePrefix: `userdata://attachments/${targetUid}/`
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const absDir = import_node_path.default.join(projectRoot, ".codetrellis", "attachments", targetUid);
|
|
73
|
+
return {
|
|
74
|
+
absDir,
|
|
75
|
+
storedValuePrefix: import_node_path.default.join(".codetrellis", "attachments", targetUid) + import_node_path.default.sep
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function resolveAttachmentLocation(value, targetUid, trustedProjectRoot) {
|
|
79
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
80
|
+
if (value.startsWith("userdata://")) {
|
|
81
|
+
const prefix = `userdata://attachments/${targetUid}/`;
|
|
82
|
+
if (!value.startsWith(prefix)) return null;
|
|
83
|
+
const userDataDir = process.env.CODETRELLIS_DATA_DIR ?? import_node_path.default.join(import_node_os.default.homedir(), ".codetrellis");
|
|
84
|
+
return { root: import_node_path.default.join(userDataDir, "attachments", targetUid), rel: value.slice(prefix.length) };
|
|
85
|
+
}
|
|
86
|
+
if ((0, import_material_place.isPlacePath)(value)) return trustedProjectRoot ? (0, import_material_place.locateStored)(value, trustedProjectRoot) : null;
|
|
87
|
+
if (import_node_path.default.isAbsolute(value) || /^[a-z][a-z0-9+.-]*:/i.test(value)) return null;
|
|
88
|
+
if (!trustedProjectRoot) return null;
|
|
89
|
+
return { root: trustedProjectRoot, rel: value };
|
|
90
|
+
}
|
|
91
|
+
const SERVED_TYPES = {
|
|
92
|
+
png: "image/png",
|
|
93
|
+
jpg: "image/jpeg",
|
|
94
|
+
jpeg: "image/jpeg",
|
|
95
|
+
gif: "image/gif",
|
|
96
|
+
webp: "image/webp",
|
|
97
|
+
svg: "image/svg+xml",
|
|
98
|
+
mp4: "video/mp4",
|
|
99
|
+
webm: "video/webm",
|
|
100
|
+
mov: "video/quicktime"
|
|
101
|
+
};
|
|
102
|
+
function servedContentType(rel) {
|
|
103
|
+
return SERVED_TYPES[import_node_path.default.extname(rel).slice(1).toLowerCase()] ?? null;
|
|
104
|
+
}
|
|
105
|
+
function addAttachment(input) {
|
|
106
|
+
const uid = (0, import_node_crypto.randomUUID)();
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
let value = input.value;
|
|
109
|
+
const isInlineByteUpload = (input.kind === "image" || input.kind === "video") && input.dataBase64;
|
|
110
|
+
if (isInlineByteUpload) {
|
|
111
|
+
if (input.contentType && !ALLOWED_ATTACHMENT_TYPES.has(input.contentType.toLowerCase())) {
|
|
112
|
+
throw new Error(`Unsupported attachment content type: ${input.contentType}`);
|
|
113
|
+
}
|
|
114
|
+
const approxBytes = Math.floor(input.dataBase64.length * 3 / 4);
|
|
115
|
+
if (approxBytes > MAX_ATTACHMENT_BYTES) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Attachment exceeds the ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB limit`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const buf = Buffer.from(input.dataBase64, "base64");
|
|
121
|
+
if (buf.length > MAX_ATTACHMENT_BYTES) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`Attachment exceeds the ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB limit`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const trustedRoot = input.projectRoot ? (0, import_trusted_roots.resolveTrustedProjectRoot)(input.projectRoot, "addAttachment(projectRoot)") : void 0;
|
|
127
|
+
const ext = guessExtensionFromContentType(input.contentType) || guessExtensionFromValue(input.value) || (input.kind === "video" ? "mp4" : "png");
|
|
128
|
+
const { absDir, storedValuePrefix } = resolveAttachmentDir(input.targetUid, trustedRoot);
|
|
129
|
+
const filename = `${uid}.${ext}`;
|
|
130
|
+
const containmentRoot = trustedRoot ? import_node_path.default.join(trustedRoot, ".codetrellis", "attachments") : import_node_path.default.dirname(absDir);
|
|
131
|
+
(0, import_confined_fs.writeFileWithin)(containmentRoot, import_node_path.default.join(absDir, filename), buf, "attachment");
|
|
132
|
+
value = storedValuePrefix + filename;
|
|
133
|
+
}
|
|
134
|
+
(0, import_database.getDb)().run(
|
|
135
|
+
`INSERT INTO attachments (uid, target_type, target_uid, kind, value, label, content_type, author, author_type, created_at)
|
|
136
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
137
|
+
[
|
|
138
|
+
uid,
|
|
139
|
+
input.targetType,
|
|
140
|
+
input.targetUid,
|
|
141
|
+
input.kind,
|
|
142
|
+
value,
|
|
143
|
+
input.label ?? null,
|
|
144
|
+
input.contentType ?? null,
|
|
145
|
+
input.author,
|
|
146
|
+
input.authorType,
|
|
147
|
+
now
|
|
148
|
+
]
|
|
149
|
+
);
|
|
150
|
+
(0, import_persistence.markDirty)();
|
|
151
|
+
if (input.targetType === "task" || input.targetType === "item") {
|
|
152
|
+
return {
|
|
153
|
+
uid,
|
|
154
|
+
taskUid: input.targetUid,
|
|
155
|
+
kind: input.kind,
|
|
156
|
+
value,
|
|
157
|
+
label: input.label,
|
|
158
|
+
contentType: input.contentType,
|
|
159
|
+
author: input.author,
|
|
160
|
+
authorType: input.authorType,
|
|
161
|
+
createdAt: now
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
uid,
|
|
166
|
+
docUid: input.targetUid,
|
|
167
|
+
kind: input.kind,
|
|
168
|
+
value,
|
|
169
|
+
label: input.label,
|
|
170
|
+
contentType: input.contentType,
|
|
171
|
+
author: input.author,
|
|
172
|
+
authorType: input.authorType,
|
|
173
|
+
createdAt: now
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function listTaskAttachments(taskUid) {
|
|
177
|
+
const result = (0, import_database.getDb)().exec(
|
|
178
|
+
`SELECT uid, target_uid, kind, value, label, content_type, author, author_type, created_at
|
|
179
|
+
FROM attachments WHERE target_type = 'task' AND target_uid = ? ORDER BY created_at ASC`,
|
|
180
|
+
[taskUid]
|
|
181
|
+
);
|
|
182
|
+
if (!result[0]) return [];
|
|
183
|
+
return result[0].values.map((r) => ({
|
|
184
|
+
uid: r[0],
|
|
185
|
+
taskUid: r[1],
|
|
186
|
+
kind: r[2],
|
|
187
|
+
value: r[3],
|
|
188
|
+
label: r[4] ?? void 0,
|
|
189
|
+
contentType: r[5] ?? void 0,
|
|
190
|
+
author: r[6],
|
|
191
|
+
authorType: r[7],
|
|
192
|
+
createdAt: r[8]
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
function listItemAttachments(itemUid) {
|
|
196
|
+
const result = (0, import_database.getDb)().exec(
|
|
197
|
+
`SELECT uid, target_uid, kind, value, label, content_type, author, author_type, created_at, role, sha256
|
|
198
|
+
FROM attachments
|
|
199
|
+
WHERE target_uid = ? AND target_type IN ('item', 'task', 'plan_doc')
|
|
200
|
+
ORDER BY created_at ASC`,
|
|
201
|
+
[itemUid]
|
|
202
|
+
);
|
|
203
|
+
if (!result[0]) return [];
|
|
204
|
+
return result[0].values.map((r) => ({
|
|
205
|
+
uid: r[0],
|
|
206
|
+
taskUid: r[1],
|
|
207
|
+
kind: r[2],
|
|
208
|
+
value: r[3],
|
|
209
|
+
label: r[4] ?? void 0,
|
|
210
|
+
contentType: r[5] ?? void 0,
|
|
211
|
+
author: r[6],
|
|
212
|
+
authorType: r[7],
|
|
213
|
+
createdAt: r[8],
|
|
214
|
+
role: r[9] ?? null,
|
|
215
|
+
sha256: r[10] ?? null
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
function listPlanDocAttachments(docUid) {
|
|
219
|
+
const result = (0, import_database.getDb)().exec(
|
|
220
|
+
`SELECT uid, target_uid, kind, value, label, content_type, author, author_type, created_at
|
|
221
|
+
FROM attachments WHERE target_type = 'plan_doc' AND target_uid = ? ORDER BY created_at ASC`,
|
|
222
|
+
[docUid]
|
|
223
|
+
);
|
|
224
|
+
if (!result[0]) return [];
|
|
225
|
+
return result[0].values.map((r) => ({
|
|
226
|
+
uid: r[0],
|
|
227
|
+
docUid: r[1],
|
|
228
|
+
kind: r[2],
|
|
229
|
+
value: r[3],
|
|
230
|
+
label: r[4] ?? void 0,
|
|
231
|
+
contentType: r[5] ?? void 0,
|
|
232
|
+
author: r[6],
|
|
233
|
+
authorType: r[7],
|
|
234
|
+
createdAt: r[8]
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
function deleteAttachment(uid) {
|
|
238
|
+
const db = (0, import_database.getDb)();
|
|
239
|
+
const before = db.exec(`SELECT uid FROM attachments WHERE uid = ?`, [uid]);
|
|
240
|
+
if (!before[0]?.values[0]) return false;
|
|
241
|
+
db.run(`DELETE FROM attachments WHERE uid = ?`, [uid]);
|
|
242
|
+
(0, import_persistence.markDirty)();
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
const ATTACHMENT_KINDS = ["url", "image", "video", "file_ref", "code_block", "transcript"];
|
|
246
|
+
function validateImportedAttachment(raw, targetUid) {
|
|
247
|
+
const kind = raw.kind;
|
|
248
|
+
if (!ATTACHMENT_KINDS.includes(kind)) return { refused: `unknown kind ${String(raw.kind)}` };
|
|
249
|
+
if (typeof raw.value !== "string" || raw.value.length === 0) return { refused: "no value" };
|
|
250
|
+
const value = raw.value;
|
|
251
|
+
if (value.includes("\0")) return { refused: "value contains a NUL byte" };
|
|
252
|
+
if (kind === "url") {
|
|
253
|
+
if (!/^https?:\/\//i.test(value)) return { refused: "a url must be http(s)" };
|
|
254
|
+
} else if (kind === "image" || kind === "video" || kind === "file_ref") {
|
|
255
|
+
if (value.startsWith("userdata://")) {
|
|
256
|
+
if (!value.startsWith(`userdata://attachments/${targetUid}/`) || value.includes("..")) {
|
|
257
|
+
return { refused: "points into the data directory outside this item's uploads" };
|
|
258
|
+
}
|
|
259
|
+
} else if ((0, import_material_place.isPlacePath)(value)) {
|
|
260
|
+
if (value.slice("plans://".length).split(/[\\/]/).some((seg) => seg === ".." || seg === "")) {
|
|
261
|
+
return { refused: "path leaves the plans folder" };
|
|
262
|
+
}
|
|
263
|
+
} else if (import_node_path.default.isAbsolute(value) || /^[a-z][a-z0-9+.-]*:/i.test(value)) {
|
|
264
|
+
return { refused: "absolute paths and URLs are not file references; use a path inside the project" };
|
|
265
|
+
} else if (import_node_path.default.normalize(value).split(/[\\/]/).includes("..")) {
|
|
266
|
+
return { refused: "path leaves the project" };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const ct = typeof raw.contentType === "string" ? raw.contentType.toLowerCase() : null;
|
|
270
|
+
return { kind, value, contentType: ct && ALLOWED_ATTACHMENT_TYPES.has(ct) ? ct : null };
|
|
271
|
+
}
|
|
272
|
+
function upsertAttachment(input) {
|
|
273
|
+
const db = (0, import_database.getDb)();
|
|
274
|
+
const role = input.kind === "file_ref" && input.role && ["material", "output", "evidence"].includes(input.role) ? input.role : null;
|
|
275
|
+
const exists = db.exec(`SELECT target_type, target_uid FROM attachments WHERE uid = ?`, [input.uid])[0]?.values[0];
|
|
276
|
+
if (exists) {
|
|
277
|
+
if (exists[0] !== input.targetType || exists[1] !== input.targetUid) return false;
|
|
278
|
+
db.run(
|
|
279
|
+
`UPDATE attachments SET kind = ?, value = ?, label = ?, content_type = ?, author = ?, author_type = ?, created_at = ? WHERE uid = ?`,
|
|
280
|
+
[
|
|
281
|
+
input.kind,
|
|
282
|
+
input.value,
|
|
283
|
+
input.label ?? null,
|
|
284
|
+
input.contentType ?? null,
|
|
285
|
+
input.author,
|
|
286
|
+
input.authorType,
|
|
287
|
+
input.createdAt,
|
|
288
|
+
input.uid
|
|
289
|
+
]
|
|
290
|
+
);
|
|
291
|
+
if (role) db.run(`UPDATE attachments SET role = ? WHERE uid = ?`, [role, input.uid]);
|
|
292
|
+
} else {
|
|
293
|
+
db.run(
|
|
294
|
+
`INSERT INTO attachments (uid, target_type, target_uid, kind, value, label, content_type, author, author_type, created_at, role)
|
|
295
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
296
|
+
[
|
|
297
|
+
input.uid,
|
|
298
|
+
input.targetType,
|
|
299
|
+
input.targetUid,
|
|
300
|
+
input.kind,
|
|
301
|
+
input.value,
|
|
302
|
+
input.label ?? null,
|
|
303
|
+
input.contentType ?? null,
|
|
304
|
+
input.author,
|
|
305
|
+
input.authorType,
|
|
306
|
+
input.createdAt,
|
|
307
|
+
role
|
|
308
|
+
]
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
(0, import_persistence.markDirty)();
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
function guessExtensionFromContentType(contentType) {
|
|
315
|
+
if (!contentType) return null;
|
|
316
|
+
const m = contentType.match(/^(?:image|video)\/([a-z0-9+.-]+)/i);
|
|
317
|
+
if (!m) return null;
|
|
318
|
+
const sub = m[1].toLowerCase();
|
|
319
|
+
if (sub === "jpeg") return "jpg";
|
|
320
|
+
if (sub === "svg+xml") return "svg";
|
|
321
|
+
if (sub === "quicktime") return "mov";
|
|
322
|
+
if (sub === "x-matroska") return "mkv";
|
|
323
|
+
return sub;
|
|
324
|
+
}
|
|
325
|
+
function guessExtensionFromValue(value) {
|
|
326
|
+
const m = value.match(/\.([a-z0-9]{2,5})$/i);
|
|
327
|
+
return m ? m[1].toLowerCase() : null;
|
|
328
|
+
}
|
|
329
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
330
|
+
0 && (module.exports = {
|
|
331
|
+
addAttachment,
|
|
332
|
+
deleteAttachment,
|
|
333
|
+
listItemAttachments,
|
|
334
|
+
listPlanDocAttachments,
|
|
335
|
+
listTaskAttachments,
|
|
336
|
+
resolveAttachmentLocation,
|
|
337
|
+
servedContentType,
|
|
338
|
+
upsertAttachment,
|
|
339
|
+
validateImportedAttachment
|
|
340
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
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 task_grounding_exports = {};
|
|
19
|
+
__export(task_grounding_exports, {
|
|
20
|
+
gradeCriterion: () => gradeCriterion,
|
|
21
|
+
taskGrounding: () => taskGrounding
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(task_grounding_exports);
|
|
24
|
+
var import_criteria_service = require("./criteria-service");
|
|
25
|
+
var import_criterion_loop_service = require("./criterion-loop-service");
|
|
26
|
+
var import_plan_item_service = require("./plan-item-service");
|
|
27
|
+
var import_artefact_service = require("./artefact-service");
|
|
28
|
+
var import_grounding_line = require("../../shared/lib/grounding-line");
|
|
29
|
+
function gradeCriterion(c, check) {
|
|
30
|
+
if (c.state === "stale") return { grade: "changed", why: "a file it was approved on has changed since" };
|
|
31
|
+
if (c.state === "sent_back") return { grade: "sent_back", why: "a person sent it back" };
|
|
32
|
+
const failures = check ? check.findings.filter((f) => f.status === "fail").map((f) => f.message) : [];
|
|
33
|
+
if (check && !check.ok) {
|
|
34
|
+
const older = check.findings.find((f) => f.status === "fail" && f.reason === "tests_older");
|
|
35
|
+
if (older) return { grade: "tests_older", why: older.message };
|
|
36
|
+
if (!c.submitted && c.state === "open") return { grade: "no_evidence", why: failures[0] ?? "nothing offered yet" };
|
|
37
|
+
return { grade: "failing", why: failures[0] ?? "its checks fail" };
|
|
38
|
+
}
|
|
39
|
+
if (c.state === "met") return { grade: "grounded", why: check ? "met, and its checks still pass" : "met" };
|
|
40
|
+
if (!check) return c.submitted ? { grade: "waiting", why: "submitted; its checks could not run here" } : { grade: "no_evidence", why: "nothing offered yet" };
|
|
41
|
+
if (c.kind === "manual") return { grade: "waiting", why: c.submitted ? "submitted; only a person can judge it" : "only a person can judge it" };
|
|
42
|
+
if (c.state === "submitted") return { grade: "waiting", why: "its checks pass; a person decides" };
|
|
43
|
+
return { grade: "grounded", why: "its checks pass on the evidence there" };
|
|
44
|
+
}
|
|
45
|
+
async function taskGrounding(itemUid) {
|
|
46
|
+
if (!(0, import_plan_item_service.getItem)(itemUid)) return null;
|
|
47
|
+
await (0, import_artefact_service.refreshArtefactHashes)(itemUid).catch(() => []);
|
|
48
|
+
const graded = [];
|
|
49
|
+
for (const c of (0, import_criteria_service.listCriteria)(itemUid)) {
|
|
50
|
+
const check = await (0, import_criterion_loop_service.checkCriterion)(c.uid).catch(() => null);
|
|
51
|
+
const { grade, why } = gradeCriterion({ ...c, submitted: (c.latestSubmission?.length ?? 0) > 0 }, check);
|
|
52
|
+
graded.push({ uid: c.uid, text: c.text, grade, why });
|
|
53
|
+
}
|
|
54
|
+
return { itemUid, ...(0, import_grounding_line.groundingLine)(graded.map((g) => g.grade)), criteria: graded };
|
|
55
|
+
}
|
|
56
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
57
|
+
0 && (module.exports = {
|
|
58
|
+
gradeCriterion,
|
|
59
|
+
taskGrounding
|
|
60
|
+
});
|
|
@@ -0,0 +1,146 @@
|
|
|
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 check_run_record_exports = {};
|
|
19
|
+
__export(check_run_record_exports, {
|
|
20
|
+
CHECK_RUN_LIMITS: () => CHECK_RUN_LIMITS,
|
|
21
|
+
MAX_CHECK_RUN_BYTES: () => MAX_CHECK_RUN_BYTES,
|
|
22
|
+
checkRunBytes: () => checkRunBytes,
|
|
23
|
+
outcomeWords: () => outcomeWords,
|
|
24
|
+
parseCheckRun: () => parseCheckRun,
|
|
25
|
+
serializeCheckRun: () => serializeCheckRun
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(check_run_record_exports);
|
|
28
|
+
var import_yaml = require("yaml");
|
|
29
|
+
var import_signing = require("./signing");
|
|
30
|
+
var import_run_record = require("./run-record");
|
|
31
|
+
var import_agent_review = require("../../../shared/lib/agent-review");
|
|
32
|
+
const KIND = "check-run";
|
|
33
|
+
const MAX_CHECK_RUN_BYTES = 512 * 1024;
|
|
34
|
+
const MAX_SAYS = 200;
|
|
35
|
+
const MAX_FINDINGS = 1e3;
|
|
36
|
+
const MAX_DIRTY = 500;
|
|
37
|
+
const WRITER = /^[a-f0-9]{8,32}$/;
|
|
38
|
+
const SHA = /^[a-f0-9]{40}$/;
|
|
39
|
+
const text = (v, max) => typeof v === "string" && v.length > 0 ? v.slice(0, max) : null;
|
|
40
|
+
const count = (v) => Number.isSafeInteger(v) && v >= 0 ? v : 0;
|
|
41
|
+
function bodyOf(r) {
|
|
42
|
+
return {
|
|
43
|
+
kind: KIND,
|
|
44
|
+
writer: r.writer,
|
|
45
|
+
name: r.name,
|
|
46
|
+
counter: r.counter,
|
|
47
|
+
at: new Date(r.at).toISOString(),
|
|
48
|
+
by: r.by,
|
|
49
|
+
ranIn: r.ranIn,
|
|
50
|
+
commit: r.commit,
|
|
51
|
+
dirty: r.dirty,
|
|
52
|
+
base: r.base,
|
|
53
|
+
rulebook: r.rulebook,
|
|
54
|
+
scope: r.scope,
|
|
55
|
+
strict: r.strict,
|
|
56
|
+
outcome: r.outcome,
|
|
57
|
+
says: r.says,
|
|
58
|
+
findings: r.findings.map((f) => ({ rule: f.rule, suite: f.suite, path: f.path, imports: f.imports, strength: f.strength, failing: f.failing, words: f.words, fix: f.fix })),
|
|
59
|
+
// Only when present, so a rule check's record (and its signature) is as before.
|
|
60
|
+
...r.review ? { review: r.review } : {}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function checkRunBytes(r) {
|
|
64
|
+
return (0, import_signing.canonicalJson)(bodyOf(r));
|
|
65
|
+
}
|
|
66
|
+
function serializeCheckRun(r, signature) {
|
|
67
|
+
const body = signature ? { ...bodyOf(r), signature } : bodyOf(r);
|
|
68
|
+
return `# CodeTrellis: one device's latest check run, where it ran, and what it said.
|
|
69
|
+
${(0, import_yaml.stringify)(body, { lineWidth: 0 })}`;
|
|
70
|
+
}
|
|
71
|
+
function parseCheckRun(source) {
|
|
72
|
+
if (Buffer.byteLength(source, "utf8") > MAX_CHECK_RUN_BYTES) return { error: "larger than a check-run record can be" };
|
|
73
|
+
let raw;
|
|
74
|
+
try {
|
|
75
|
+
raw = (0, import_yaml.parse)(source, { maxAliasCount: 0 });
|
|
76
|
+
} catch {
|
|
77
|
+
return { error: "not YAML" };
|
|
78
|
+
}
|
|
79
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return { error: "not a record" };
|
|
80
|
+
const { signature: rawSignature, ...r } = raw;
|
|
81
|
+
if (r.kind !== KIND) return { error: "not a check-run record" };
|
|
82
|
+
const writer = typeof r.writer === "string" && WRITER.test(r.writer) ? r.writer : null;
|
|
83
|
+
if (!writer) return { error: "no writer" };
|
|
84
|
+
const counter = Number.isSafeInteger(r.counter) && r.counter > 0 ? r.counter : null;
|
|
85
|
+
if (!counter) return { error: "no counter" };
|
|
86
|
+
const at = typeof r.at === "string" ? Date.parse(r.at) : NaN;
|
|
87
|
+
if (!Number.isFinite(at)) return { error: "no time" };
|
|
88
|
+
const by = r.by && typeof r.by === "object" ? r.by : {};
|
|
89
|
+
const o = r.outcome && typeof r.outcome === "object" ? r.outcome : {};
|
|
90
|
+
const findings = [];
|
|
91
|
+
for (const f of Array.isArray(r.findings) ? r.findings.slice(0, MAX_FINDINGS) : []) {
|
|
92
|
+
const ff = f && typeof f === "object" ? f : {};
|
|
93
|
+
const rule = text(ff.rule, 63);
|
|
94
|
+
const imports = text(ff.imports, 300);
|
|
95
|
+
if (!rule || !imports || !(0, import_run_record.isRunPath)(ff.path)) continue;
|
|
96
|
+
findings.push({
|
|
97
|
+
rule,
|
|
98
|
+
suite: text(ff.suite, 63) ?? "architecture",
|
|
99
|
+
path: ff.path,
|
|
100
|
+
imports,
|
|
101
|
+
strength: ff.strength === "warn" ? "warn" : "block",
|
|
102
|
+
failing: ff.failing === true,
|
|
103
|
+
words: text(ff.words, 500) ?? rule,
|
|
104
|
+
fix: text(ff.fix, 500)
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
signed: { bytes: (0, import_signing.canonicalJson)(r), signature: (0, import_signing.parseSignature)(rawSignature) },
|
|
109
|
+
record: {
|
|
110
|
+
writer,
|
|
111
|
+
name: text(r.name, 120) ?? "someone",
|
|
112
|
+
counter,
|
|
113
|
+
at,
|
|
114
|
+
by: { author: text(by.author, 120) ?? "someone", authorType: text(by.authorType, 40) ?? "unknown" },
|
|
115
|
+
ranIn: text(r.ranIn, 80) ?? "somewhere",
|
|
116
|
+
commit: typeof r.commit === "string" && SHA.test(r.commit) ? r.commit : null,
|
|
117
|
+
dirty: (Array.isArray(r.dirty) ? r.dirty : []).filter(import_run_record.isRunPath).slice(0, MAX_DIRTY),
|
|
118
|
+
base: text(r.base, 200),
|
|
119
|
+
rulebook: typeof r.rulebook === "string" && SHA.test(r.rulebook) ? r.rulebook : null,
|
|
120
|
+
scope: text(r.scope, 300),
|
|
121
|
+
strict: r.strict === true,
|
|
122
|
+
outcome: { ok: o.ok === true, files: count(o.files), blocks: count(o.blocks), warns: count(o.warns) },
|
|
123
|
+
says: (Array.isArray(r.says) ? r.says : []).map((s) => text(s, 1e3)).filter((s) => !!s).slice(0, MAX_SAYS),
|
|
124
|
+
findings,
|
|
125
|
+
...(0, import_agent_review.parseAgentReview)(r.review) ? { review: (0, import_agent_review.parseAgentReview)(r.review) } : {}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function outcomeWords(o) {
|
|
130
|
+
if (o.ok && o.warns === 0) return "\u2713 conforms";
|
|
131
|
+
const parts = [
|
|
132
|
+
o.blocks ? `\u2717 ${o.blocks} ${o.blocks === 1 ? "blocks" : "block"}` : null,
|
|
133
|
+
o.warns ? `\u26A0 ${o.warns} ${o.warns === 1 ? "warns" : "warn"}` : null
|
|
134
|
+
].filter(Boolean);
|
|
135
|
+
return o.ok ? `\u2713 conforms \xB7 ${parts.join(" \xB7 ")}` : parts.join(" \xB7 ");
|
|
136
|
+
}
|
|
137
|
+
const CHECK_RUN_LIMITS = { MAX_SAYS, MAX_FINDINGS, MAX_DIRTY };
|
|
138
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
139
|
+
0 && (module.exports = {
|
|
140
|
+
CHECK_RUN_LIMITS,
|
|
141
|
+
MAX_CHECK_RUN_BYTES,
|
|
142
|
+
checkRunBytes,
|
|
143
|
+
outcomeWords,
|
|
144
|
+
parseCheckRun,
|
|
145
|
+
serializeCheckRun
|
|
146
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
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 check_runs_exports = {};
|
|
29
|
+
__export(check_runs_exports, {
|
|
30
|
+
CHECK_RUNS_DIR: () => CHECK_RUNS_DIR,
|
|
31
|
+
myCheckRunCount: () => myCheckRunCount,
|
|
32
|
+
readTeammateCheckRuns: () => readTeammateCheckRuns,
|
|
33
|
+
writeCheckRunRecord: () => writeCheckRunRecord
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(check_runs_exports);
|
|
36
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
37
|
+
var import_node_path = __toESM(require("node:path"));
|
|
38
|
+
var import_confined_fs = require("../confined-fs");
|
|
39
|
+
var import_cloud_files = require("../cloud-files");
|
|
40
|
+
var import_check_runs = require("../check-runs");
|
|
41
|
+
var import_check_run_record = require("./check-run-record");
|
|
42
|
+
var import_test_runs = require("./test-runs");
|
|
43
|
+
var import_trust = require("./trust");
|
|
44
|
+
const CHECK_RUNS_DIR = import_node_path.default.join(import_test_runs.RUNS_DIR, "checks");
|
|
45
|
+
const FILE = /^([a-f0-9]{8,32})-(\d{1,9})\.yaml$/;
|
|
46
|
+
const MAX_FILES = 2e3;
|
|
47
|
+
function filesIn(dir) {
|
|
48
|
+
try {
|
|
49
|
+
return import_node_fs.default.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && FILE.test(e.name)).slice(0, MAX_FILES).map((e) => {
|
|
50
|
+
const m = FILE.exec(e.name);
|
|
51
|
+
return { name: e.name, writer: m[1], counter: Number(m[2]) };
|
|
52
|
+
});
|
|
53
|
+
} catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function writeCheckRunRecord(where, run) {
|
|
58
|
+
const dir = import_node_path.default.join(where.home, CHECK_RUNS_DIR);
|
|
59
|
+
const mine = filesIn(dir).filter((f) => f.writer === where.me);
|
|
60
|
+
let counter = Math.max(0, ...mine.map((f) => f.counter)) + 1;
|
|
61
|
+
while (import_node_fs.default.existsSync(import_node_path.default.join(dir, `${where.me}-${counter}.yaml`))) counter++;
|
|
62
|
+
const { projectRoot: _root, ...rest } = run;
|
|
63
|
+
const record = { ...rest, writer: where.me, name: where.name, counter };
|
|
64
|
+
const signature = (0, import_trust.signRecord)(where.projectRoot, where.home, record, (0, import_check_run_record.checkRunBytes)(record));
|
|
65
|
+
const file = (0, import_confined_fs.writeFileWithin)(where.home, import_node_path.default.join(dir, `${where.me}-${counter}.yaml`), (0, import_check_run_record.serializeCheckRun)(record, signature), "check-run record");
|
|
66
|
+
for (const f of mine) {
|
|
67
|
+
try {
|
|
68
|
+
(0, import_confined_fs.removeWithin)(where.home, import_node_path.default.join(dir, f.name), {}, "check-run record");
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return file;
|
|
73
|
+
}
|
|
74
|
+
function readTeammateCheckRuns(projectRoot, home, me) {
|
|
75
|
+
const dir = import_node_path.default.join(home, CHECK_RUNS_DIR);
|
|
76
|
+
const known = (0, import_check_runs.knownCheckRunCounters)(projectRoot);
|
|
77
|
+
const newest = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const f of filesIn(dir)) {
|
|
79
|
+
if (f.writer === me) continue;
|
|
80
|
+
const at = newest.get(f.writer);
|
|
81
|
+
if (!at || f.counter > at.counter) newest.set(f.writer, f);
|
|
82
|
+
}
|
|
83
|
+
let added = 0;
|
|
84
|
+
let ctx = null;
|
|
85
|
+
for (const [writer, f] of newest) {
|
|
86
|
+
if ((known.get(writer) ?? 0) >= f.counter) continue;
|
|
87
|
+
const file = import_node_path.default.join(dir, f.name);
|
|
88
|
+
if ((0, import_cloud_files.isPlaceholder)(file)) continue;
|
|
89
|
+
let text;
|
|
90
|
+
try {
|
|
91
|
+
text = (0, import_confined_fs.readTextWithin)(home, file, "check-run record");
|
|
92
|
+
} catch {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const parsed = (0, import_check_run_record.parseCheckRun)(text);
|
|
96
|
+
if (!("record" in parsed)) continue;
|
|
97
|
+
const r = parsed.record;
|
|
98
|
+
if (r.writer !== writer || r.counter !== f.counter) continue;
|
|
99
|
+
ctx ??= (0, import_trust.checkContext)(projectRoot);
|
|
100
|
+
const v = (0, import_trust.verifyTaskRecord)(r, parsed.signed, ctx);
|
|
101
|
+
(0, import_check_runs.putTeammateCheckRun)(projectRoot, r, v.verified ? { verified: true, how: v.how, who: v.who } : { verified: false, why: v.why });
|
|
102
|
+
added++;
|
|
103
|
+
}
|
|
104
|
+
return added;
|
|
105
|
+
}
|
|
106
|
+
function myCheckRunCount(home, me) {
|
|
107
|
+
return home ? filesIn(import_node_path.default.join(home, CHECK_RUNS_DIR)).filter((f) => f.writer === me).length : 0;
|
|
108
|
+
}
|
|
109
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
110
|
+
0 && (module.exports = {
|
|
111
|
+
CHECK_RUNS_DIR,
|
|
112
|
+
myCheckRunCount,
|
|
113
|
+
readTeammateCheckRuns,
|
|
114
|
+
writeCheckRunRecord
|
|
115
|
+
});
|