codetrellis 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +27 -2
- package/bin/codetrellis.mjs +4 -0
- package/package.json +43 -4
- package/reader/material-reader.mjs +130346 -0
- package/resources/tree-sitter/README.md +150 -0
- package/resources/tree-sitter/tree-sitter-c-sharp.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-go.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-java.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-javascript.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-kotlin.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-php.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-python.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-ruby.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-rust.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-swift.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-tsx.wasm +0 -0
- package/resources/tree-sitter/tree-sitter-typescript.wasm +0 -0
- package/resources/tree-sitter/tree-sitter.wasm +0 -0
- package/src/backend/agent/claude-code-watcher.js +270 -0
- package/src/backend/index.js +8 -0
- package/src/backend/lib/sha256-file.js +39 -0
- package/src/backend/lib/zip-entries.js +98 -0
- package/src/backend/lifecycle.js +102 -0
- package/src/backend/mcp/binding-headers.js +54 -0
- package/src/backend/mcp/client-identity.js +44 -0
- package/src/backend/mcp/connector/command.js +110 -0
- package/src/backend/mcp/connector/core.js +278 -0
- package/src/backend/mcp/connector/files.js +121 -0
- package/src/backend/mcp/connector/hook.js +284 -0
- package/src/backend/mcp/connector/main.js +126 -0
- package/src/backend/mcp/connector/sse-upstream.js +152 -0
- package/src/backend/mcp/helpers.js +43 -0
- package/src/backend/mcp/prompt-builders.js +104 -0
- package/src/backend/mcp/resources.js +197 -0
- package/src/backend/mcp/server.js +813 -0
- package/src/backend/mcp/skill-guide.js +1528 -0
- package/src/backend/mcp/tools/architecture-tools.js +273 -0
- package/src/backend/mcp/tools/audio-tools.js +117 -0
- package/src/backend/mcp/tools/awareness-tools.js +623 -0
- package/src/backend/mcp/tools/budget-tools.js +185 -0
- package/src/backend/mcp/tools/channel-tools.js +205 -0
- package/src/backend/mcp/tools/contribution-tools.js +181 -0
- package/src/backend/mcp/tools/drift-tools.js +252 -0
- package/src/backend/mcp/tools/git-tools.js +316 -0
- package/src/backend/mcp/tools/governance-tools.js +175 -0
- package/src/backend/mcp/tools/graph-tools.js +181 -0
- package/src/backend/mcp/tools/intake-tools.js +244 -0
- package/src/backend/mcp/tools/mobile-tools.js +118 -0
- package/src/backend/mcp/tools/peer-tools.js +330 -0
- package/src/backend/mcp/tools/plan-item-tools.js +1601 -0
- package/src/backend/mcp/tools/plan-tools.js +680 -0
- package/src/backend/mcp/tools/presence-tools.js +185 -0
- package/src/backend/mcp/tools/project-config-tools.js +150 -0
- package/src/backend/mcp/tools/review-tools.js +172 -0
- package/src/backend/mcp/tools/session-tools.js +554 -0
- package/src/backend/mcp/tools/system-docs-tools.js +168 -0
- package/src/backend/mcp/tools/terminal-tools.js +186 -0
- package/src/backend/mcp/tools/test-tools.js +117 -0
- package/src/backend/mcp/tools/ui-tools.js +356 -0
- package/src/backend/mcp/types.js +15 -0
- package/src/backend/middleware/local-auth.js +116 -0
- package/src/backend/server.js +5951 -0
- package/src/backend/services/agent-event-log.js +350 -0
- package/src/backend/services/architecture-rule.js +584 -0
- package/src/backend/services/architecture-rules.js +275 -0
- package/src/backend/services/artefact-content-service.js +181 -0
- package/src/backend/services/artefact-service.js +305 -0
- package/src/backend/services/artefact-watcher.js +167 -0
- package/src/backend/services/ast-parser.js +327 -0
- package/src/backend/services/audio-buffer-service.js +152 -0
- package/src/backend/services/awareness-notices.js +139 -0
- package/src/backend/services/awareness-replies.js +194 -0
- package/src/backend/services/awareness-service.js +344 -0
- package/src/backend/services/awareness-signals.js +267 -0
- package/src/backend/services/baseline-store.js +83 -0
- package/src/backend/services/branch-workstreams.js +341 -0
- package/src/backend/services/breakpoint-service.js +584 -0
- package/src/backend/services/brief-service.js +299 -0
- package/src/backend/services/budget-service.js +528 -0
- package/src/backend/services/callsites/base.js +15 -0
- package/src/backend/services/callsites/csharp.js +148 -0
- package/src/backend/services/callsites/go.js +163 -0
- package/src/backend/services/callsites/index.js +53 -0
- package/src/backend/services/callsites/kotlin.js +123 -0
- package/src/backend/services/callsites/process-env.js +125 -0
- package/src/backend/services/callsites/python.js +91 -0
- package/src/backend/services/callsites/ruby.js +164 -0
- package/src/backend/services/callsites/shared.js +198 -0
- package/src/backend/services/callsites/swift.js +115 -0
- package/src/backend/services/callsites/typescript.js +87 -0
- package/src/backend/services/capability-token.js +108 -0
- package/src/backend/services/change-check.js +156 -0
- package/src/backend/services/channel-dispatcher-service.js +235 -0
- package/src/backend/services/channel-event-file-service.js +125 -0
- package/src/backend/services/channel-event-service.js +297 -0
- package/src/backend/services/check-runs.js +177 -0
- package/src/backend/services/checkout-identity.js +73 -0
- package/src/backend/services/claude-code-parallel.js +221 -0
- package/src/backend/services/claude-desktop-config.js +186 -0
- package/src/backend/services/clock.js +57 -0
- package/src/backend/services/cloud-files.js +191 -0
- package/src/backend/services/coalesce.js +50 -0
- package/src/backend/services/code-breakpoints.js +291 -0
- package/src/backend/services/comment-service.js +168 -0
- package/src/backend/services/commit-attribution.js +134 -0
- package/src/backend/services/commit-edges.js +99 -0
- package/src/backend/services/confined-fs.js +241 -0
- package/src/backend/services/conformity-gate.js +132 -0
- package/src/backend/services/contribution-service.js +409 -0
- package/src/backend/services/coverage-service.js +173 -0
- package/src/backend/services/criteria-service.js +721 -0
- package/src/backend/services/criterion-checks.js +387 -0
- package/src/backend/services/criterion-loop-service.js +411 -0
- package/src/backend/services/cross-system-service.js +231 -0
- package/src/backend/services/database.js +916 -0
- package/src/backend/services/db-schema.js +1358 -0
- package/src/backend/services/deviation-service.js +344 -0
- package/src/backend/services/diff-engine.js +168 -0
- package/src/backend/services/evidence.js +363 -0
- package/src/backend/services/external-intake-service.js +269 -0
- package/src/backend/services/external-pointer-service.js +195 -0
- package/src/backend/services/external-refs-service.js +214 -0
- package/src/backend/services/file-history.js +158 -0
- package/src/backend/services/file-watcher.js +193 -0
- package/src/backend/services/folder-requests.js +118 -0
- package/src/backend/services/freeze-service.js +189 -0
- package/src/backend/services/gemini-cli-hook.js +172 -0
- package/src/backend/services/git-activity-service.js +325 -0
- package/src/backend/services/git-blobs.js +70 -0
- package/src/backend/services/git-branches.js +357 -0
- package/src/backend/services/git-checkout.js +153 -0
- package/src/backend/services/git-commit-service.js +91 -0
- package/src/backend/services/git-env.js +121 -0
- package/src/backend/services/git-identity.js +84 -0
- package/src/backend/services/git-refs.js +386 -0
- package/src/backend/services/git-safety.js +58 -0
- package/src/backend/services/grant-guard.js +67 -0
- package/src/backend/services/html-view-policy.js +135 -0
- package/src/backend/services/human-decision.js +55 -0
- package/src/backend/services/importers.js +159 -0
- package/src/backend/services/intent-service.js +105 -0
- package/src/backend/services/ipc-dispatcher.js +164 -0
- package/src/backend/services/item-git-state.js +208 -0
- package/src/backend/services/line-changes.js +232 -0
- package/src/backend/services/line-history.js +174 -0
- package/src/backend/services/local-api-changes.js +40 -0
- package/src/backend/services/logger.js +217 -0
- package/src/backend/services/material-footprints.js +203 -0
- package/src/backend/services/material-place.js +82 -0
- package/src/backend/services/material-reader/child.js +4 -0
- package/src/backend/services/material-reader/docx-markdown.js +198 -0
- package/src/backend/services/material-reader/fixtures.test-helper.js +169 -0
- package/src/backend/services/material-reader/quote.js +44 -0
- package/src/backend/services/material-reader/read.js +430 -0
- package/src/backend/services/material-reader/reader-host.js +202 -0
- package/src/backend/services/material-signals.js +141 -0
- package/src/backend/services/mcp-capabilities.js +390 -0
- package/src/backend/services/mdns-service.js +304 -0
- package/src/backend/services/mobile-api-server.js +281 -0
- package/src/backend/services/mobile-approvals.js +306 -0
- package/src/backend/services/mobile-awareness.js +180 -0
- package/src/backend/services/mobile-breakpoints.js +115 -0
- package/src/backend/services/mobile-budget.js +98 -0
- package/src/backend/services/mobile-freeze.js +106 -0
- package/src/backend/services/mobile-proposals.js +100 -0
- package/src/backend/services/mobile-rpc-service.js +1289 -0
- package/src/backend/services/mobile-workstreams.js +160 -0
- package/src/backend/services/monorepo-detector.js +131 -0
- package/src/backend/services/other-work.js +45 -0
- package/src/backend/services/pack-seal.js +129 -0
- package/src/backend/services/paired-device-service.js +192 -0
- package/src/backend/services/pairing-server.js +323 -0
- package/src/backend/services/pairing-service.js +200 -0
- package/src/backend/services/pantry-resolution-service.js +166 -0
- package/src/backend/services/parsers/base.js +124 -0
- package/src/backend/services/parsers/csharp.js +224 -0
- package/src/backend/services/parsers/go.js +180 -0
- package/src/backend/services/parsers/index.js +101 -0
- package/src/backend/services/parsers/java.js +103 -0
- package/src/backend/services/parsers/kotlin.js +252 -0
- package/src/backend/services/parsers/php.js +113 -0
- package/src/backend/services/parsers/python.js +189 -0
- package/src/backend/services/parsers/ruby.js +212 -0
- package/src/backend/services/parsers/rust.js +97 -0
- package/src/backend/services/parsers/swift.js +221 -0
- package/src/backend/services/parsers/typescript.js +235 -0
- package/src/backend/services/pattern-scan.js +65 -0
- package/src/backend/services/patterns.js +281 -0
- package/src/backend/services/peer-audit-service.js +123 -0
- package/src/backend/services/peer-auth.js +153 -0
- package/src/backend/services/peer-capabilities.js +209 -0
- package/src/backend/services/peer-connection-service.js +450 -0
- package/src/backend/services/peer-grants.js +33 -0
- package/src/backend/services/persistence.js +116 -0
- package/src/backend/services/personal-sync-service.js +232 -0
- package/src/backend/services/pipeline-approvals.js +72 -0
- package/src/backend/services/pipeline.js +232 -0
- package/src/backend/services/plan-arrivals.js +68 -0
- package/src/backend/services/plan-changes-service.js +273 -0
- package/src/backend/services/plan-conflict-service.js +288 -0
- package/src/backend/services/plan-dependencies.js +91 -0
- package/src/backend/services/plan-doc-guard.js +90 -0
- package/src/backend/services/plan-documents-service.js +275 -0
- package/src/backend/services/plan-event-service.js +154 -0
- package/src/backend/services/plan-file-refs.js +106 -0
- package/src/backend/services/plan-file-service.js +1564 -0
- package/src/backend/services/plan-history-service.js +156 -0
- package/src/backend/services/plan-import-service.js +261 -0
- package/src/backend/services/plan-item-service.js +1223 -0
- package/src/backend/services/plan-migrate-service.js +395 -0
- package/src/backend/services/plan-overlay-service.js +173 -0
- package/src/backend/services/plan-phases-service.js +182 -0
- package/src/backend/services/plan-progress-service.js +134 -0
- package/src/backend/services/plan-review-service.js +262 -0
- package/src/backend/services/plan-service.js +682 -0
- package/src/backend/services/plan-status.js +113 -0
- package/src/backend/services/plan-template-publish-service.js +217 -0
- package/src/backend/services/plan-templates-service.js +242 -0
- package/src/backend/services/plan-templates.js +1164 -0
- package/src/backend/services/planned-overlap-actions.js +200 -0
- package/src/backend/services/plans-home.js +224 -0
- package/src/backend/services/play-forward.js +256 -0
- package/src/backend/services/playback-service.js +117 -0
- package/src/backend/services/power-service.js +167 -0
- package/src/backend/services/power-signals.js +81 -0
- package/src/backend/services/pr-draft-service.js +142 -0
- package/src/backend/services/presence-service.js +122 -0
- package/src/backend/services/pricing.js +60 -0
- package/src/backend/services/project-config-service.js +474 -0
- package/src/backend/services/project-scanner.js +184 -0
- package/src/backend/services/projection-service.js +69 -0
- package/src/backend/services/push-notification-service.js +288 -0
- package/src/backend/services/recent-projects-service.js +204 -0
- package/src/backend/services/record-chain.js +162 -0
- package/src/backend/services/recurrence-rule.js +63 -0
- package/src/backend/services/recurring-agent.js +89 -0
- package/src/backend/services/recurring-scheduler.js +77 -0
- package/src/backend/services/recurring-service.js +276 -0
- package/src/backend/services/reference-service.js +169 -0
- package/src/backend/services/release-public-key.js +30 -0
- package/src/backend/services/release-signature.js +64 -0
- package/src/backend/services/remote-audio-service.js +224 -0
- package/src/backend/services/remote-interaction-service.js +275 -0
- package/src/backend/services/remote-terminal-service.js +324 -0
- package/src/backend/services/rendition/child/main.js +76 -0
- package/src/backend/services/rendition/engine-host.js +249 -0
- package/src/backend/services/rendition/engine-lock.js +39 -0
- package/src/backend/services/rendition/engine-lock.json +14 -0
- package/src/backend/services/rendition/engine-manifest.js +97 -0
- package/src/backend/services/rendition/network-proof.js +73 -0
- package/src/backend/services/rendition/rendition-service.js +175 -0
- package/src/backend/services/replay-frames.js +387 -0
- package/src/backend/services/replay-state.js +201 -0
- package/src/backend/services/resolvers/base.js +108 -0
- package/src/backend/services/resolvers/csharp.js +109 -0
- package/src/backend/services/resolvers/go.js +105 -0
- package/src/backend/services/resolvers/index.js +60 -0
- package/src/backend/services/resolvers/java.js +63 -0
- package/src/backend/services/resolvers/kotlin.js +109 -0
- package/src/backend/services/resolvers/php.js +89 -0
- package/src/backend/services/resolvers/python.js +154 -0
- package/src/backend/services/resolvers/ruby.js +103 -0
- package/src/backend/services/resolvers/rust.js +77 -0
- package/src/backend/services/resolvers/swift.js +98 -0
- package/src/backend/services/resolvers/typescript.js +71 -0
- package/src/backend/services/retention.js +54 -0
- package/src/backend/services/review-architecture.js +236 -0
- package/src/backend/services/review-attest.js +68 -0
- package/src/backend/services/review-bundle.js +226 -0
- package/src/backend/services/review-graduation.js +93 -0
- package/src/backend/services/review-host/bitbucket.js +79 -0
- package/src/backend/services/review-host/detect.js +80 -0
- package/src/backend/services/review-host/github.js +97 -0
- package/src/backend/services/review-host/gitlab.js +77 -0
- package/src/backend/services/review-host/host-state.js +103 -0
- package/src/backend/services/review-host/http.js +58 -0
- package/src/backend/services/review-host/switch.js +120 -0
- package/src/backend/services/review-marks.js +72 -0
- package/src/backend/services/review-notes.js +169 -0
- package/src/backend/services/review-other-work.js +90 -0
- package/src/backend/services/review-queue-service.js +147 -0
- package/src/backend/services/review-risk.js +127 -0
- package/src/backend/services/review-task.js +121 -0
- package/src/backend/services/rule-approvals.js +268 -0
- package/src/backend/services/rule-baseline.js +134 -0
- package/src/backend/services/rule-changes.js +162 -0
- package/src/backend/services/rule-preview.js +47 -0
- package/src/backend/services/rule-proposals.js +104 -0
- package/src/backend/services/rule-scope.js +76 -0
- package/src/backend/services/rulebook.js +286 -0
- package/src/backend/services/rules-at.js +56 -0
- package/src/backend/services/rules-overview.js +88 -0
- package/src/backend/services/schema-reconciler.js +250 -0
- package/src/backend/services/secret-store.js +119 -0
- package/src/backend/services/section-workstreams.js +95 -0
- package/src/backend/services/self-write-tracker.js +75 -0
- package/src/backend/services/sensor-bridge-service.js +285 -0
- package/src/backend/services/session-service.js +192 -0
- package/src/backend/services/settings-service.js +324 -0
- package/src/backend/services/signal-breakpoints.js +172 -0
- package/src/backend/services/signed-approval-record.js +86 -0
- package/src/backend/services/signed-approvals.js +244 -0
- package/src/backend/services/signoff-pack.js +328 -0
- package/src/backend/services/signoff-rows.js +114 -0
- package/src/backend/services/skill-arrival-service.js +138 -0
- package/src/backend/services/skill-model.js +193 -0
- package/src/backend/services/skill-use-service.js +140 -0
- package/src/backend/services/skills-service.js +150 -0
- package/src/backend/services/snapshot-compare-service.js +397 -0
- package/src/backend/services/source-control.js +189 -0
- package/src/backend/services/spec-links-service.js +123 -0
- package/src/backend/services/spec-proposal-withdraw.js +50 -0
- package/src/backend/services/spec-proposals-service.js +470 -0
- package/src/backend/services/sql/embedded.js +95 -0
- package/src/backend/services/sql/index.js +63 -0
- package/src/backend/services/sql/refs.js +357 -0
- package/src/backend/services/sql/schema.js +312 -0
- package/src/backend/services/sql/tokenizer.js +195 -0
- package/src/backend/services/stack-overlaps.js +117 -0
- package/src/backend/services/stack-service.js +225 -0
- package/src/backend/services/state-sync-service.js +384 -0
- package/src/backend/services/stuck-sensor-service.js +200 -0
- package/src/backend/services/system-discovery.js +481 -0
- package/src/backend/services/system-docs-service.js +701 -0
- package/src/backend/services/task-attachments-service.js +340 -0
- package/src/backend/services/task-grounding.js +60 -0
- package/src/backend/services/task-records/check-run-record.js +146 -0
- package/src/backend/services/task-records/check-runs.js +115 -0
- package/src/backend/services/task-records/heads.js +88 -0
- package/src/backend/services/task-records/material-reads.js +225 -0
- package/src/backend/services/task-records/read-record.js +100 -0
- package/src/backend/services/task-records/record.js +173 -0
- package/src/backend/services/task-records/run-record.js +136 -0
- package/src/backend/services/task-records/shared-state.js +548 -0
- package/src/backend/services/task-records/signing.js +140 -0
- package/src/backend/services/task-records/split-signals.js +52 -0
- package/src/backend/services/task-records/test-runs.js +164 -0
- package/src/backend/services/task-records/trust.js +243 -0
- package/src/backend/services/task-rules.js +81 -0
- package/src/backend/services/task-workstreams.js +90 -0
- package/src/backend/services/terminal-history-service.js +266 -0
- package/src/backend/services/terminal-service.js +267 -0
- package/src/backend/services/test-clock.js +53 -0
- package/src/backend/services/tests/grounding.js +266 -0
- package/src/backend/services/tests/junit.js +104 -0
- package/src/backend/services/tests/teammate-runs.js +134 -0
- package/src/backend/services/tests/test-results.js +234 -0
- package/src/backend/services/tree-watcher.js +204 -0
- package/src/backend/services/trellis-service.js +204 -0
- package/src/backend/services/trusted-roots.js +186 -0
- package/src/backend/services/update-download-service.js +342 -0
- package/src/backend/services/update-service.js +266 -0
- package/src/backend/services/watch-ignore.js +76 -0
- package/src/backend/services/webhook-egress.js +206 -0
- package/src/backend/services/webrtc-service.js +413 -0
- package/src/backend/services/work-changes.js +59 -0
- package/src/backend/services/workstream-binding.js +82 -0
- package/src/backend/services/workstream-commits.js +116 -0
- package/src/backend/services/workstream-imports.js +177 -0
- package/src/backend/services/workstream-service.js +335 -0
- package/src/backend/services/workstream-symbols.js +223 -0
- package/src/backend/services/workstream-watch-service.js +391 -0
- package/src/backend/services/worktree-service.js +235 -0
- package/src/cli/agent.js +100 -0
- package/src/cli/args.js +201 -0
- package/src/cli/conformity.js +106 -0
- package/src/cli/desktop.js +91 -0
- package/src/cli/main.js +409 -0
- package/src/cli/pipeline.js +109 -0
- package/src/cli/plan-verbs.js +259 -0
- package/src/cli/review-adapters.js +218 -0
- package/src/cli/review-output.js +93 -0
- package/src/cli/review-post.js +89 -0
- package/src/cli/review-sink.js +183 -0
- package/src/cli/review-skill.js +44 -0
- package/src/cli/review-verify.js +104 -0
- package/src/cli/review.js +386 -0
- package/src/cli/sarif.js +148 -0
- package/src/cli/verbs.js +359 -0
- package/src/shared/build-info.js +39 -0
- package/src/shared/lib/agent-review.js +199 -0
- package/src/shared/lib/agent-turns.js +140 -0
- package/src/shared/lib/awareness-digest.js +120 -0
- package/src/shared/lib/branch-name.js +45 -0
- package/src/shared/lib/breakpoint-words.js +118 -0
- package/src/shared/lib/budget-words.js +56 -0
- package/src/shared/lib/burst.js +69 -0
- package/src/shared/lib/call-entry.js +105 -0
- package/src/shared/lib/check-compare.js +42 -0
- package/src/shared/lib/check-words.js +216 -0
- package/src/shared/lib/csv.js +62 -0
- package/src/shared/lib/folder-entry.js +87 -0
- package/src/shared/lib/freeze-words.js +60 -0
- package/src/shared/lib/fuzzy.js +84 -0
- package/src/shared/lib/git-state-words.js +80 -0
- package/src/shared/lib/grep-entry.js +86 -0
- package/src/shared/lib/grounding-line.js +61 -0
- package/src/shared/lib/import-line.js +71 -0
- package/src/shared/lib/item-status.js +249 -0
- package/src/shared/lib/line-changes.js +53 -0
- package/src/shared/lib/locator.js +71 -0
- package/src/shared/lib/matcher.js +120 -0
- package/src/shared/lib/merge-order.js +65 -0
- package/src/shared/lib/open-findings.js +68 -0
- package/src/shared/lib/other-work.js +108 -0
- package/src/shared/lib/package-entry.js +142 -0
- package/src/shared/lib/plan-vocab.js +40 -0
- package/src/shared/lib/pptx-xml.js +86 -0
- package/src/shared/lib/proposal-words.js +61 -0
- package/src/shared/lib/recurrence.js +183 -0
- package/src/shared/lib/references.js +72 -0
- package/src/shared/lib/rule-pattern.js +56 -0
- package/src/shared/lib/sdp-fingerprint.js +115 -0
- package/src/shared/lib/sdp-minimal.js +123 -0
- package/src/shared/lib/secret-paths.js +34 -0
- package/src/shared/lib/signal-words.js +172 -0
- package/src/shared/lib/signoff.js +56 -0
- package/src/shared/lib/skills-note.js +60 -0
- package/src/shared/lib/spec-sections.js +78 -0
- package/src/shared/lib/symbol-entry.js +60 -0
- package/src/shared/lib/tool-phrasing.js +338 -0
- package/src/shared/lib/turn-gap.js +27 -0
- package/src/shared/lib/workstream-words.js +38 -0
- package/src/shared/lib/xlsx-xml.js +144 -0
- package/src/shared/lib/zip-reader.js +99 -0
- package/src/shared/types/agent.js +27 -0
- package/src/shared/types/architecture-rules.js +30 -0
- package/src/shared/types/ast.js +15 -0
- package/src/shared/types/breakpoint.js +33 -0
- package/src/shared/types/channel.js +41 -0
- package/src/shared/types/criteria.js +15 -0
- package/src/shared/types/graph.js +15 -0
- package/src/shared/types/index.js +53 -0
- package/src/shared/types/peer.js +36 -0
- package/src/shared/types/pipeline.js +15 -0
- package/src/shared/types/plan.js +15 -0
- package/src/shared/types/play-forward.js +15 -0
- package/src/shared/types/power.js +15 -0
- package/src/shared/types/presence.js +15 -0
- package/src/shared/types/project-config.js +35 -0
- package/src/shared/types/project.js +15 -0
- package/src/shared/types/record.js +15 -0
- package/src/shared/types/recurring.js +15 -0
- package/src/shared/types/review.js +15 -0
- package/src/shared/types/settings.js +114 -0
- package/src/shared/types/stack.js +15 -0
- package/src/shared/types/system-doc.js +15 -0
- package/src/shared/types/system.js +15 -0
|
@@ -0,0 +1,194 @@
|
|
|
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 awareness_replies_exports = {};
|
|
29
|
+
__export(awareness_replies_exports, {
|
|
30
|
+
MAX_REPLY: () => MAX_REPLY,
|
|
31
|
+
cleanReply: () => cleanReply,
|
|
32
|
+
recordReply: () => recordReply,
|
|
33
|
+
repliesFor: () => repliesFor,
|
|
34
|
+
replyNoticeFor: () => replyNoticeFor,
|
|
35
|
+
replyText: () => replyText,
|
|
36
|
+
setReplyReadListener: () => setReplyReadListener,
|
|
37
|
+
tasksHeldIn: () => tasksHeldIn,
|
|
38
|
+
withReplies: () => withReplies
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(awareness_replies_exports);
|
|
41
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
42
|
+
var import_database = require("./database");
|
|
43
|
+
var import_persistence = require("./persistence");
|
|
44
|
+
var import_awareness_service = require("./awareness-service");
|
|
45
|
+
var import_session_service = require("./session-service");
|
|
46
|
+
const MAX_REPLY = 1e3;
|
|
47
|
+
function cleanReply(message) {
|
|
48
|
+
if (typeof message !== "string") return null;
|
|
49
|
+
const m = message.trim();
|
|
50
|
+
return m && m.length <= MAX_REPLY ? m : null;
|
|
51
|
+
}
|
|
52
|
+
function canon(p) {
|
|
53
|
+
try {
|
|
54
|
+
return import_node_fs.default.realpathSync.native(p);
|
|
55
|
+
} catch {
|
|
56
|
+
return p;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function sessionsIn(workstreams) {
|
|
60
|
+
const roots = new Set(workstreams.map(canon));
|
|
61
|
+
return (0, import_session_service.getActiveSessions)().filter((s) => s.workstreamRoot && roots.has(canon(s.workstreamRoot))).map((s) => ({ sessionId: s.sessionId, agentType: s.agentType }));
|
|
62
|
+
}
|
|
63
|
+
function recordReply(projectRoot, signalId, message, by, now = Date.now()) {
|
|
64
|
+
const signal = (0, import_awareness_service.loadSignals)(projectRoot).find((s) => s.id === signalId && s.state !== "resolved");
|
|
65
|
+
if (!signal) return null;
|
|
66
|
+
const db = (0, import_database.getDb)();
|
|
67
|
+
db.run(
|
|
68
|
+
`INSERT INTO awareness_signal_replies (signal_id, project_root, message, actor, actor_type, channel, created_at)
|
|
69
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
70
|
+
[signalId, projectRoot, message, by.actor, by.actorType, by.channel, now]
|
|
71
|
+
);
|
|
72
|
+
const id = Number(db.exec("SELECT last_insert_rowid()")[0]?.values[0]?.[0] ?? 0);
|
|
73
|
+
(0, import_persistence.markDirty)();
|
|
74
|
+
return { signal, reply: { id, message, by, at: now, readBy: [] }, tasks: tasksHeldIn(signal.workstreams) };
|
|
75
|
+
}
|
|
76
|
+
function tasksHeldIn(workstreams) {
|
|
77
|
+
const sessions = sessionsIn(workstreams).map((s) => s.sessionId);
|
|
78
|
+
if (sessions.length === 0) return [];
|
|
79
|
+
const res = (0, import_database.getDb)().exec(
|
|
80
|
+
`SELECT plan_uid, uid FROM plan_items
|
|
81
|
+
WHERE assignee_session IN (${sessions.map(() => "?").join(",")})
|
|
82
|
+
AND status IN ('assigned', 'in_progress')
|
|
83
|
+
ORDER BY plan_uid, uid`,
|
|
84
|
+
sessions
|
|
85
|
+
);
|
|
86
|
+
return (res[0]?.values ?? []).map(([planUid, itemUid]) => ({ planUid, itemUid }));
|
|
87
|
+
}
|
|
88
|
+
function repliesFor(signalIds) {
|
|
89
|
+
const out = /* @__PURE__ */ new Map();
|
|
90
|
+
if (signalIds.length === 0) return out;
|
|
91
|
+
const db = (0, import_database.getDb)();
|
|
92
|
+
const res = db.exec(
|
|
93
|
+
`SELECT id, signal_id, message, actor, actor_type, channel, created_at FROM awareness_signal_replies
|
|
94
|
+
WHERE signal_id IN (${signalIds.map(() => "?").join(",")}) ORDER BY created_at, id`,
|
|
95
|
+
[...signalIds]
|
|
96
|
+
);
|
|
97
|
+
const byId = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const [id, signalId, message, actor, actorType, channel, at] of res[0]?.values ?? []) {
|
|
99
|
+
const reply = {
|
|
100
|
+
id,
|
|
101
|
+
message,
|
|
102
|
+
by: { actor, actorType, channel },
|
|
103
|
+
at,
|
|
104
|
+
readBy: []
|
|
105
|
+
};
|
|
106
|
+
byId.set(reply.id, reply);
|
|
107
|
+
const list = out.get(signalId) ?? [];
|
|
108
|
+
list.push(reply);
|
|
109
|
+
out.set(signalId, list);
|
|
110
|
+
}
|
|
111
|
+
if (byId.size > 0) {
|
|
112
|
+
const reads = db.exec(
|
|
113
|
+
`SELECT reply_id, session_id, agent_type, read_at FROM awareness_signal_reply_reads
|
|
114
|
+
WHERE reply_id IN (${[...byId.keys()].map(() => "?").join(",")}) ORDER BY read_at`,
|
|
115
|
+
[...byId.keys()]
|
|
116
|
+
);
|
|
117
|
+
for (const [replyId, sessionId, agentType, readAt] of reads[0]?.values ?? []) {
|
|
118
|
+
byId.get(replyId)?.readBy.push({ sessionId, agentType, readAt });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
function withReplies(signals) {
|
|
124
|
+
const replies = repliesFor(signals.map((s) => s.id));
|
|
125
|
+
return signals.map((s) => replies.has(s.id) ? { ...s, replies: replies.get(s.id) } : s);
|
|
126
|
+
}
|
|
127
|
+
function sender(by) {
|
|
128
|
+
if (by.actorType === "unverified") return "sent through the local API, not verified as the person";
|
|
129
|
+
return by.channel === "phone" ? "the person, from their phone" : "the person, from the CodeTrellis window";
|
|
130
|
+
}
|
|
131
|
+
function replyText(items) {
|
|
132
|
+
const lines = ["\u2500\u2500 CodeTrellis: a message about other work \u2500\u2500"];
|
|
133
|
+
for (const { signal, reply } of items) {
|
|
134
|
+
lines.push(`About ${signal.severity} ${signal.kind} ${signal.id}: ${signal.summary}`);
|
|
135
|
+
lines.push(`From ${sender(reply.by)}:`);
|
|
136
|
+
lines.push(...reply.message.split("\n").map((l) => `> ${l}`));
|
|
137
|
+
}
|
|
138
|
+
lines.push("Answer with acknowledge_signal(id, note) to say what you will do.");
|
|
139
|
+
return lines.join("\n");
|
|
140
|
+
}
|
|
141
|
+
function replyNoticeFor(sessionId, projectRoot, now = Date.now()) {
|
|
142
|
+
if (!projectRoot) return null;
|
|
143
|
+
try {
|
|
144
|
+
const session = (0, import_session_service.getActiveSessions)().find((s) => s.sessionId === sessionId);
|
|
145
|
+
if (!session?.workstreamRoot) return null;
|
|
146
|
+
const mine = canon(session.workstreamRoot);
|
|
147
|
+
const signals = (0, import_awareness_service.loadSignals)(projectRoot).filter((s) => s.workstreams.some((w) => canon(w) === mine));
|
|
148
|
+
if (signals.length === 0) return null;
|
|
149
|
+
const db = (0, import_database.getDb)();
|
|
150
|
+
const res = db.exec(
|
|
151
|
+
`SELECT r.id, r.signal_id, r.message, r.actor, r.actor_type, r.channel FROM awareness_signal_replies r
|
|
152
|
+
WHERE r.project_root = ? AND r.signal_id IN (${signals.map(() => "?").join(",")})
|
|
153
|
+
AND NOT EXISTS (SELECT 1 FROM awareness_signal_reply_reads d WHERE d.reply_id = r.id AND d.session_id = ?)
|
|
154
|
+
ORDER BY r.created_at, r.id`,
|
|
155
|
+
[projectRoot, ...signals.map((s) => s.id), sessionId]
|
|
156
|
+
);
|
|
157
|
+
const rows = res[0]?.values ?? [];
|
|
158
|
+
if (rows.length === 0) return null;
|
|
159
|
+
const byId = new Map(signals.map((s) => [s.id, s]));
|
|
160
|
+
const items = rows.map(([, signalId, message, actor, actorType, channel]) => ({
|
|
161
|
+
signal: byId.get(signalId),
|
|
162
|
+
reply: { message, by: { actor, actorType, channel } }
|
|
163
|
+
}));
|
|
164
|
+
for (const [id] of rows) {
|
|
165
|
+
db.run(
|
|
166
|
+
"INSERT OR IGNORE INTO awareness_signal_reply_reads (reply_id, session_id, agent_type, read_at) VALUES (?, ?, ?, ?)",
|
|
167
|
+
[id, sessionId, session.agentType, now]
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
(0, import_persistence.markDirty)();
|
|
171
|
+
onRead(projectRoot);
|
|
172
|
+
return replyText(items);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.warn("[Awareness] reply delivery failed:", err instanceof Error ? err.message : err);
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
let onRead = () => {
|
|
179
|
+
};
|
|
180
|
+
function setReplyReadListener(listener) {
|
|
181
|
+
onRead = listener;
|
|
182
|
+
}
|
|
183
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
184
|
+
0 && (module.exports = {
|
|
185
|
+
MAX_REPLY,
|
|
186
|
+
cleanReply,
|
|
187
|
+
recordReply,
|
|
188
|
+
repliesFor,
|
|
189
|
+
replyNoticeFor,
|
|
190
|
+
replyText,
|
|
191
|
+
setReplyReadListener,
|
|
192
|
+
tasksHeldIn,
|
|
193
|
+
withReplies
|
|
194
|
+
});
|
|
@@ -0,0 +1,344 @@
|
|
|
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 awareness_service_exports = {};
|
|
29
|
+
__export(awareness_service_exports, {
|
|
30
|
+
contractsOf: () => contractsOf,
|
|
31
|
+
countNeedsYou: () => countNeedsYou,
|
|
32
|
+
declaredFiles: () => declaredFiles,
|
|
33
|
+
filesDefining: () => filesDefining,
|
|
34
|
+
footprintsOf: () => footprintsOf,
|
|
35
|
+
listSignals: () => listSignals,
|
|
36
|
+
loadSignals: () => loadSignals,
|
|
37
|
+
mainChangesSince: () => mainChangesSince,
|
|
38
|
+
refreshSignals: () => refreshSignals,
|
|
39
|
+
refreshSignalsSoon: () => refreshSignalsSoon,
|
|
40
|
+
scopeOf: () => scopeOf,
|
|
41
|
+
setAwarenessListener: () => setAwarenessListener,
|
|
42
|
+
setSignalState: () => setSignalState
|
|
43
|
+
});
|
|
44
|
+
module.exports = __toCommonJS(awareness_service_exports);
|
|
45
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
46
|
+
var import_node_path = __toESM(require("node:path"));
|
|
47
|
+
var import_database = require("./database");
|
|
48
|
+
var import_agent_event_log = require("./agent-event-log");
|
|
49
|
+
var import_persistence = require("./persistence");
|
|
50
|
+
var import_git_safety = require("./git-safety");
|
|
51
|
+
var import_git_env = require("./git-env");
|
|
52
|
+
var import_coalesce = require("./coalesce");
|
|
53
|
+
var import_workstream_service = require("./workstream-service");
|
|
54
|
+
var import_importers = require("./importers");
|
|
55
|
+
var import_intent_service = require("./intent-service");
|
|
56
|
+
var import_awareness_signals = require("./awareness-signals");
|
|
57
|
+
var import_push_notification_service = require("./push-notification-service");
|
|
58
|
+
var import_material_signals = require("./material-signals");
|
|
59
|
+
var import_material_footprints = require("./material-footprints");
|
|
60
|
+
var import_split_signals = require("./task-records/split-signals");
|
|
61
|
+
var import_architecture_rules = require("./architecture-rules");
|
|
62
|
+
var import_architecture_rule = require("./architecture-rule");
|
|
63
|
+
var import_workstream_imports = require("./workstream-imports");
|
|
64
|
+
const SHA = /^[0-9a-f]{40}$/;
|
|
65
|
+
async function mainChangesSince(folder, base, mainRef) {
|
|
66
|
+
if (!base || !SHA.test(base) || !mainRef || !(0, import_git_safety.isSafeGitRef)(mainRef)) return [];
|
|
67
|
+
try {
|
|
68
|
+
return (await (0, import_git_env.gitAsync)(folder, ["diff", "--name-only", "-z", base, mainRef, "--"])).split("\0").filter(Boolean);
|
|
69
|
+
} catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function rowToSignal(r) {
|
|
74
|
+
return {
|
|
75
|
+
id: r[0],
|
|
76
|
+
kind: r[1],
|
|
77
|
+
severity: r[2],
|
|
78
|
+
subject: JSON.parse(r[3]),
|
|
79
|
+
workstreams: JSON.parse(r[4]),
|
|
80
|
+
summary: r[5],
|
|
81
|
+
firstSeen: r[6],
|
|
82
|
+
lastSeen: r[7],
|
|
83
|
+
state: r[8],
|
|
84
|
+
...r[9] ? { stateBy: JSON.parse(r[9]) } : {},
|
|
85
|
+
...r[10] != null ? { stateAt: r[10] } : {},
|
|
86
|
+
...r[11] ? { shape: r[11] } : {},
|
|
87
|
+
...r[12] ? { reopened: { from: r[12], at: r[13] } } : {}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const COLUMNS = "id, kind, severity, subject, workstreams, summary, first_seen, last_seen, state";
|
|
91
|
+
const READ_COLUMNS = `${COLUMNS}, state_by, state_at, shape, reopened_from, reopened_at`;
|
|
92
|
+
function loadSignals(projectRoot) {
|
|
93
|
+
const res = (0, import_database.getDb)().exec(`SELECT ${READ_COLUMNS} FROM awareness_signals WHERE project_root = ?`, [projectRoot]);
|
|
94
|
+
return (res[0]?.values ?? []).map(rowToSignal);
|
|
95
|
+
}
|
|
96
|
+
let onChanged = () => {
|
|
97
|
+
};
|
|
98
|
+
function setAwarenessListener(listener) {
|
|
99
|
+
onChanged = listener;
|
|
100
|
+
}
|
|
101
|
+
function contractsOf(projectRoot, w) {
|
|
102
|
+
return (0, import_awareness_signals.contractCandidates)(w.changes.files).map((c) => ({
|
|
103
|
+
...c,
|
|
104
|
+
importers: (0, import_importers.importersOf)(import_node_path.default.join(projectRoot, c.file), [(0, import_awareness_signals.importableName)(c.symbol)]).map((i) => ({ path: i.relativePath, possibly: i.possibly }))
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
async function footprintsOf(all, projectRoot) {
|
|
108
|
+
const main = all.find((w) => w.main);
|
|
109
|
+
const mainRef = main?.branch ?? main?.head ?? null;
|
|
110
|
+
const out = [];
|
|
111
|
+
for (const w of all.filter((x) => !x.idle)) {
|
|
112
|
+
out.push({
|
|
113
|
+
root: w.root,
|
|
114
|
+
branch: w.branch,
|
|
115
|
+
main: w.main,
|
|
116
|
+
files: w.changes.files,
|
|
117
|
+
// A branch workstream has no folder of its own: git runs in the main checkout.
|
|
118
|
+
mainSinceBase: w.main ? [] : await mainChangesSince(w.shape === "branch" && main ? main.root : w.root, w.changes.base, mainRef),
|
|
119
|
+
...projectRoot ? { contracts: contractsOf(projectRoot, w) } : {},
|
|
120
|
+
...w.intents?.length ? { intended: declaredFiles(w.intents) } : {},
|
|
121
|
+
...scopeEntry(scopeOf(w)),
|
|
122
|
+
...projectRoot ? await ruleEntry(projectRoot, w, main?.root ?? null) : {},
|
|
123
|
+
...projectRoot && scopeOf(w) ? rulesAboutEntry(projectRoot) : {}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
async function ruleEntry(projectRoot, w, mainRoot) {
|
|
129
|
+
const rules = (0, import_architecture_rules.rulesOf)(projectRoot);
|
|
130
|
+
if (rules.length === 0 || w.changes.files.length === 0) return {};
|
|
131
|
+
if (!(0, import_workstream_imports.importsReadableFor)(projectRoot)) return {};
|
|
132
|
+
const breaches = (0, import_architecture_rules.checkEdges)(rules, await (0, import_workstream_imports.importsAdded)(projectRoot, w, mainRoot, { packages: true, symbols: rules.some((r) => r.kind === "symbol"), calls: rules.some((r) => r.kind === "calls"), files: rules.some((r) => r.kind === "folder"), grep: rules.filter((r) => r.kind === "grep" && r.strength !== "guide") }));
|
|
133
|
+
if (breaches.length === 0) return {};
|
|
134
|
+
return {
|
|
135
|
+
ruleBreaches: rules.map((rule) => ({ rule, edges: breaches.filter((b) => b.rule === rule.id).map((b) => ({ from: b.from, to: b.to })) })).filter((r) => r.edges.length > 0)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const scopeEntry = (scope) => scope ? { scope } : {};
|
|
139
|
+
function rulesAboutEntry(projectRoot) {
|
|
140
|
+
const rules = (0, import_architecture_rules.rulesOf)(projectRoot);
|
|
141
|
+
if (rules.length === 0) return {};
|
|
142
|
+
return { rules: rules.map((r) => ({ id: r.id, suite: r.suite, words: (0, import_architecture_rule.ruleStatement)(r), strength: r.strength, kind: r.kind, from: r.from, mayNotImport: r.mayNotImport, only: r.only, ...r.in ? { in: r.in, except: r.except } : {} })) };
|
|
143
|
+
}
|
|
144
|
+
function scopeOf(w) {
|
|
145
|
+
const sessions = w.agents.map((a) => a.sessionId);
|
|
146
|
+
const paths = /* @__PURE__ */ new Set();
|
|
147
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
148
|
+
const items = [];
|
|
149
|
+
if (sessions.length) {
|
|
150
|
+
const res = (0, import_database.getDb)().exec(
|
|
151
|
+
`SELECT uid, file_specs, scope_path FROM plan_items
|
|
152
|
+
WHERE assignee_session IN (${sessions.map(() => "?").join(",")})
|
|
153
|
+
AND COALESCE(status, '') NOT IN ('done', 'skipped')`,
|
|
154
|
+
sessions
|
|
155
|
+
);
|
|
156
|
+
for (const [uid, specsJson, scopePath] of res[0]?.values ?? []) {
|
|
157
|
+
let specs = [];
|
|
158
|
+
try {
|
|
159
|
+
specs = JSON.parse(specsJson || "[]");
|
|
160
|
+
} catch {
|
|
161
|
+
}
|
|
162
|
+
const before = paths.size + dirs.size;
|
|
163
|
+
for (const s of specs) {
|
|
164
|
+
const clean = (p) => p.replace(/^\.\//, "");
|
|
165
|
+
(s.isDir ? dirs : paths).add(clean(s.path));
|
|
166
|
+
if (s.moveTo) paths.add(clean(s.moveTo));
|
|
167
|
+
}
|
|
168
|
+
if (typeof scopePath === "string" && scopePath.trim()) dirs.add(scopePath.trim().replace(/^\.\//, ""));
|
|
169
|
+
if (paths.size + dirs.size > before) items.push(uid);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const declared = declaredFiles(w.intents ?? []);
|
|
173
|
+
for (const f of declared) paths.add(f.path);
|
|
174
|
+
if (paths.size === 0 && dirs.size === 0) return null;
|
|
175
|
+
return { paths: [...paths].sort(), dirs: [...dirs].sort(), items, declared: declared.length > 0 };
|
|
176
|
+
}
|
|
177
|
+
function filesDefining(projectRoot, name, limit = 5) {
|
|
178
|
+
const root = projectRoot.endsWith(import_node_path.default.sep) ? projectRoot : projectRoot + import_node_path.default.sep;
|
|
179
|
+
const res = (0, import_database.getDb)().exec(
|
|
180
|
+
`SELECT DISTINCT f.relative_path FROM symbols s JOIN files f ON s.file_id = f.id
|
|
181
|
+
WHERE s.name = ? AND substr(f.path, 1, ?) = ? ORDER BY f.relative_path LIMIT ?`,
|
|
182
|
+
[name, root.length, root, limit]
|
|
183
|
+
);
|
|
184
|
+
return (res[0]?.values ?? []).map((r) => r[0]);
|
|
185
|
+
}
|
|
186
|
+
function declaredFiles(intents) {
|
|
187
|
+
const merged = /* @__PURE__ */ new Map();
|
|
188
|
+
for (const i of intents) {
|
|
189
|
+
for (const f of (0, import_intent_service.intentFiles)(i)) {
|
|
190
|
+
const set = merged.get(f.path) ?? /* @__PURE__ */ new Set();
|
|
191
|
+
f.symbols.forEach((s) => set.add(s));
|
|
192
|
+
merged.set(f.path, set);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return [...merged].map(([p, s]) => ({ path: p, symbols: [...s].sort() })).sort((a, b) => a.path.localeCompare(b.path));
|
|
196
|
+
}
|
|
197
|
+
function recordSignalSpans(projectRoot, previous, upserts, resolved, now) {
|
|
198
|
+
const db = (0, import_database.getDb)();
|
|
199
|
+
const before = new Map(previous.map((s) => [s.id, s]));
|
|
200
|
+
for (const s of upserts) {
|
|
201
|
+
const open = db.exec("SELECT opened_at FROM awareness_signal_spans WHERE signal_id = ? AND closed_at IS NULL", [s.id])[0]?.values[0];
|
|
202
|
+
if (open) {
|
|
203
|
+
db.run(
|
|
204
|
+
"UPDATE awareness_signal_spans SET severity = ?, summary = ?, workstreams = ? WHERE signal_id = ? AND opened_at = ?",
|
|
205
|
+
[s.severity, s.summary, JSON.stringify(s.workstreams), s.id, open[0]]
|
|
206
|
+
);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const cameBack = before.get(s.id)?.state === "resolved";
|
|
210
|
+
db.run(
|
|
211
|
+
`INSERT OR IGNORE INTO awareness_signal_spans (signal_id, project_root, kind, severity, summary, workstreams, opened_at, closed_at)
|
|
212
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, NULL)`,
|
|
213
|
+
[s.id, projectRoot, s.kind, s.severity, s.summary, JSON.stringify(s.workstreams), cameBack ? now : s.firstSeen]
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
for (const id of resolved) {
|
|
217
|
+
db.run("UPDATE awareness_signal_spans SET closed_at = ? WHERE signal_id = ? AND closed_at IS NULL", [now, id]);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const refreshes = (0, import_coalesce.coalesced)((projectRoot) => runRefresh(projectRoot));
|
|
221
|
+
function refreshSignals(projectRoot) {
|
|
222
|
+
return refreshes(projectRoot);
|
|
223
|
+
}
|
|
224
|
+
function refreshSignalsSoon(projectRoot) {
|
|
225
|
+
(refreshes.running(projectRoot) ?? refreshes(projectRoot)).catch((err) => console.warn("[Awareness] refresh failed:", err));
|
|
226
|
+
}
|
|
227
|
+
async function runRefresh(projectRoot) {
|
|
228
|
+
const footprints = await footprintsOf(await (0, import_workstream_service.listWorkstreams)(projectRoot, { includeIdle: true, fresh: true }), projectRoot);
|
|
229
|
+
const materials = (0, import_material_footprints.materialInputsOf)(projectRoot);
|
|
230
|
+
const drafts = [
|
|
231
|
+
...(0, import_awareness_signals.computeSignals)(footprints),
|
|
232
|
+
...(0, import_material_signals.computeMaterialSignals)(materials.tasks, materials.current),
|
|
233
|
+
// Teammates' records that set a task two ways at once (C3.2).
|
|
234
|
+
...(0, import_split_signals.stateSplitDrafts)(projectRoot)
|
|
235
|
+
];
|
|
236
|
+
const now = Date.now();
|
|
237
|
+
const previous = loadSignals(projectRoot);
|
|
238
|
+
const { upserts, resolved, reopened } = (0, import_awareness_signals.reconcileSignals)(previous, drafts, now);
|
|
239
|
+
if (upserts.length === 0 && resolved.length === 0) return false;
|
|
240
|
+
const db = (0, import_database.getDb)();
|
|
241
|
+
for (const s of upserts) {
|
|
242
|
+
db.run(
|
|
243
|
+
`INSERT INTO awareness_signals (${COLUMNS}, project_root, resolved_at, shape, reopened_from, reopened_at)
|
|
244
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?)
|
|
245
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
246
|
+
severity = excluded.severity, subject = excluded.subject, workstreams = excluded.workstreams,
|
|
247
|
+
summary = excluded.summary, last_seen = excluded.last_seen, resolved_at = NULL, shape = excluded.shape,
|
|
248
|
+
-- Set when it reopens (A3.2); kept until the person answers again.
|
|
249
|
+
reopened_from = COALESCE(excluded.reopened_from, awareness_signals.reopened_from),
|
|
250
|
+
reopened_at = COALESCE(excluded.reopened_at, awareness_signals.reopened_at),
|
|
251
|
+
-- A signal that resolved and came back is open again: whoever
|
|
252
|
+
-- answered it before answered a different occurrence.
|
|
253
|
+
state_by = CASE WHEN awareness_signals.state = excluded.state THEN awareness_signals.state_by END,
|
|
254
|
+
state_at = CASE WHEN awareness_signals.state = excluded.state THEN awareness_signals.state_at END,
|
|
255
|
+
state = excluded.state`,
|
|
256
|
+
[
|
|
257
|
+
s.id,
|
|
258
|
+
s.kind,
|
|
259
|
+
s.severity,
|
|
260
|
+
JSON.stringify(s.subject),
|
|
261
|
+
JSON.stringify(s.workstreams),
|
|
262
|
+
s.summary,
|
|
263
|
+
s.firstSeen,
|
|
264
|
+
s.lastSeen,
|
|
265
|
+
s.state,
|
|
266
|
+
projectRoot,
|
|
267
|
+
s.shape ?? null,
|
|
268
|
+
s.reopened?.from ?? null,
|
|
269
|
+
s.reopened?.at ?? null
|
|
270
|
+
]
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
for (const id of reopened) {
|
|
274
|
+
db.run("UPDATE awareness_signal_notes SET told_at = NULL WHERE signal_id = ?", [id]);
|
|
275
|
+
}
|
|
276
|
+
for (const id of resolved) {
|
|
277
|
+
db.run(`UPDATE awareness_signals SET state = 'resolved', resolved_at = ?, last_seen = ? WHERE id = ?`, [now, now, id]);
|
|
278
|
+
}
|
|
279
|
+
recordSignalSpans(projectRoot, previous, upserts, resolved, now);
|
|
280
|
+
(0, import_persistence.markDirty)();
|
|
281
|
+
onChanged(projectRoot);
|
|
282
|
+
for (const s of (0, import_awareness_signals.newlySerious)(previous, upserts, reopened)) void (0, import_push_notification_service.pushForSignal)(s).catch(() => {
|
|
283
|
+
});
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
function countNeedsYou(projectRoot) {
|
|
287
|
+
const res = (0, import_database.getDb)().exec(
|
|
288
|
+
`SELECT COUNT(*) FROM awareness_signals WHERE project_root = ? AND state = 'open' AND severity IN ('high', 'medium')`,
|
|
289
|
+
[projectRoot]
|
|
290
|
+
);
|
|
291
|
+
return Number(res[0]?.values[0]?.[0] ?? 0);
|
|
292
|
+
}
|
|
293
|
+
const RANK = { high: 0, medium: 1, low: 2 };
|
|
294
|
+
function listSignals(projectRoot, opts = {}) {
|
|
295
|
+
const canon = (p) => {
|
|
296
|
+
try {
|
|
297
|
+
return import_node_fs.default.realpathSync.native(p);
|
|
298
|
+
} catch {
|
|
299
|
+
return p;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
const mine = opts.workstream ? canon(opts.workstream) : null;
|
|
303
|
+
return loadSignals(projectRoot).filter((s) => s.state !== "resolved").filter((s) => !mine || s.workstreams.some((w) => canon(w) === mine)).sort((a, b) => RANK[a.severity] - RANK[b.severity] || b.lastSeen - a.lastSeen);
|
|
304
|
+
}
|
|
305
|
+
function setSignalState(projectRoot, id, state, by, now = Date.now()) {
|
|
306
|
+
const signal = loadSignals(projectRoot).find((s) => s.id === id && s.state !== "resolved");
|
|
307
|
+
if (!signal) return null;
|
|
308
|
+
(0, import_database.getDb)().run(
|
|
309
|
+
"UPDATE awareness_signals SET state = ?, state_by = ?, state_at = ?, reopened_from = NULL, reopened_at = NULL WHERE id = ? AND project_root = ?",
|
|
310
|
+
[state, JSON.stringify(by), now, id, projectRoot]
|
|
311
|
+
);
|
|
312
|
+
(0, import_persistence.markDirty)();
|
|
313
|
+
(0, import_agent_event_log.recordDecision)("signal_answered", {
|
|
314
|
+
signalId: id,
|
|
315
|
+
kind: signal.kind,
|
|
316
|
+
severity: signal.severity,
|
|
317
|
+
state,
|
|
318
|
+
projectRoot,
|
|
319
|
+
workstreams: signal.workstreams,
|
|
320
|
+
summary: signal.summary.slice(0, 200),
|
|
321
|
+
actor: by.actor,
|
|
322
|
+
actorType: by.actorType,
|
|
323
|
+
channel: by.channel
|
|
324
|
+
}, by.actorType);
|
|
325
|
+
onChanged(projectRoot);
|
|
326
|
+
const { reopened: _was, ...rest } = signal;
|
|
327
|
+
return { ...rest, state, stateBy: by, stateAt: now };
|
|
328
|
+
}
|
|
329
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
330
|
+
0 && (module.exports = {
|
|
331
|
+
contractsOf,
|
|
332
|
+
countNeedsYou,
|
|
333
|
+
declaredFiles,
|
|
334
|
+
filesDefining,
|
|
335
|
+
footprintsOf,
|
|
336
|
+
listSignals,
|
|
337
|
+
loadSignals,
|
|
338
|
+
mainChangesSince,
|
|
339
|
+
refreshSignals,
|
|
340
|
+
refreshSignalsSoon,
|
|
341
|
+
scopeOf,
|
|
342
|
+
setAwarenessListener,
|
|
343
|
+
setSignalState
|
|
344
|
+
});
|