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,156 @@
|
|
|
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 change_check_exports = {};
|
|
19
|
+
__export(change_check_exports, {
|
|
20
|
+
checkTheChange: () => checkTheChange
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(change_check_exports);
|
|
23
|
+
var import_node_child_process = require("node:child_process");
|
|
24
|
+
var import_conformity_gate = require("./conformity-gate");
|
|
25
|
+
var import_workstream_imports = require("./workstream-imports");
|
|
26
|
+
var import_rules_at = require("./rules-at");
|
|
27
|
+
var import_rule_changes = require("./rule-changes");
|
|
28
|
+
var import_rule_approvals = require("./rule-approvals");
|
|
29
|
+
var import_rule_scope = require("./rule-scope");
|
|
30
|
+
var import_rule_baseline = require("./rule-baseline");
|
|
31
|
+
var import_architecture_rules = require("./architecture-rules");
|
|
32
|
+
var import_pipeline = require("./pipeline");
|
|
33
|
+
var import_database = require("./database");
|
|
34
|
+
var import_git_safety = require("./git-safety");
|
|
35
|
+
var import_check_runs = require("./check-runs");
|
|
36
|
+
var import_test_runs = require("./task-records/test-runs");
|
|
37
|
+
var import_shared_state = require("./task-records/shared-state");
|
|
38
|
+
var import_check_words = require("../../shared/lib/check-words");
|
|
39
|
+
async function checkTheChange(input) {
|
|
40
|
+
const { root, paths, base, strict, by, ranIn } = input;
|
|
41
|
+
const scope = (0, import_rule_scope.parseScope)(input.scope);
|
|
42
|
+
const ref = base ?? "HEAD";
|
|
43
|
+
let since = null;
|
|
44
|
+
if ((0, import_git_safety.isSafeGitRef)(ref)) {
|
|
45
|
+
try {
|
|
46
|
+
since = (0, import_node_child_process.execFileSync)("git", ["-C", root, "rev-parse", "--verify", "--quiet", `${ref}^{commit}`], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
47
|
+
} catch {
|
|
48
|
+
since = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (base !== void 0 && !since) {
|
|
52
|
+
return { error: `${base} is not a commit in this repository (a shallow clone? fetch the base first).` };
|
|
53
|
+
}
|
|
54
|
+
let judgeBy;
|
|
55
|
+
let rulebook = [];
|
|
56
|
+
const notes = [];
|
|
57
|
+
if (since) {
|
|
58
|
+
const atBase = await (0, import_rules_at.rulesAt)(root, since);
|
|
59
|
+
if (atBase) {
|
|
60
|
+
judgeBy = (0, import_rule_scope.scopeRules)(atBase.rules, scope);
|
|
61
|
+
rulebook = (0, import_rule_changes.diffRules)(atBase.rules, (0, import_architecture_rules.rulesOf)(root), (0, import_architecture_rules.edgesIfLoaded)(root, input.activeProject, import_database.getDependencyEdges, void 0, atBase.rules) ?? []).filter((c2) => !scope || c2.before && (0, import_rule_scope.inScope)(c2.before, scope) || c2.after && (0, import_rule_scope.inScope)(c2.after, scope));
|
|
62
|
+
if (rulebook.some((c2) => c2.effect === "loosens")) {
|
|
63
|
+
const approvals = (0, import_rule_approvals.approvalsHere)(root);
|
|
64
|
+
const keys = (0, import_rule_approvals.keysAt)(root, since);
|
|
65
|
+
try {
|
|
66
|
+
for (const c2 of rulebook) if (c2.effect === "loosens") c2.approval = (0, import_rule_approvals.approvalFor)(root, c2, approvals, keys, since);
|
|
67
|
+
} finally {
|
|
68
|
+
keys.done();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
notes.push(`\u26A0 The rules at ${since.slice(0, 7)} could not be read, so this change was judged by its own rules. Fetch the base with its history.`);
|
|
73
|
+
}
|
|
74
|
+
if (!scope || input.pipeline) {
|
|
75
|
+
const was = await (0, import_pipeline.pipelineAt)(root, since);
|
|
76
|
+
const now = (0, import_pipeline.readPipeline)(root);
|
|
77
|
+
if (now?.problems.length) notes.push(`\u26A0 ${now.problems.join("; ")}`);
|
|
78
|
+
const changes = (0, import_pipeline.diffPipeline)(was?.pipeline ?? null, now?.pipeline ?? null);
|
|
79
|
+
if (changes.some((c2) => c2.effect === "loosens")) {
|
|
80
|
+
const approvals = (0, import_rule_approvals.approvalsHere)(root);
|
|
81
|
+
const keys = (0, import_rule_approvals.keysAt)(root, since);
|
|
82
|
+
try {
|
|
83
|
+
for (const c2 of changes) if (c2.effect === "loosens") c2.approval = (0, import_rule_approvals.approvalFor)(root, c2, approvals, keys, since);
|
|
84
|
+
} finally {
|
|
85
|
+
keys.done();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
rulebook = [...rulebook, ...changes];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
let ratchetFound = [];
|
|
92
|
+
const baseBaseline = since ? (0, import_rule_baseline.baselineAt)(root, since) : null;
|
|
93
|
+
const headBaseline = (0, import_rule_baseline.readBaseline)(root);
|
|
94
|
+
if (baseBaseline || headBaseline) {
|
|
95
|
+
const judged = judgeBy ?? (0, import_rule_scope.scopeRules)((0, import_architecture_rules.rulesOf)(root), scope);
|
|
96
|
+
const edges = (0, import_architecture_rules.edgesIfLoaded)(root, input.activeProject, import_database.getDependencyEdges);
|
|
97
|
+
if (edges) {
|
|
98
|
+
const strengthOf = new Map(judged.map((r) => [r.id, r.strength]));
|
|
99
|
+
const ids = new Set(judged.map((r) => r.id));
|
|
100
|
+
ratchetFound = (0, import_rule_baseline.ratchet)(baseBaseline, headBaseline, judged, edges).filter((f) => ids.has(f.rule) || f.kind === "grew").map((f) => ({ ...f, strength: strengthOf.get(f.rule) ?? "block" }));
|
|
101
|
+
} else {
|
|
102
|
+
notes.push("\u26A0 The rules' baseline was not checked: this project's imports are not loaded here.");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const c = await (0, import_conformity_gate.checkChanges)(root, paths, input.checkCriterion, (files) => (0, import_workstream_imports.ruleImports)(root, files, since, judgeBy ?? (scope ? (0, import_rule_scope.scopeRules)((0, import_architecture_rules.rulesOf)(root), scope) : void 0)), rulebook, notes, strict === true, scope !== null, ratchetFound);
|
|
106
|
+
const failing = new Set(c.says);
|
|
107
|
+
const code = (0, import_test_runs.codeAt)(root);
|
|
108
|
+
const findings = c.rules.map((r) => ({
|
|
109
|
+
rule: r.rule,
|
|
110
|
+
suite: r.suite ?? "architecture",
|
|
111
|
+
path: r.path,
|
|
112
|
+
imports: r.imports,
|
|
113
|
+
strength: r.strength,
|
|
114
|
+
failing: failing.has(`\u2717 ${(0, import_check_words.findingLine)(r)}`),
|
|
115
|
+
words: r.words,
|
|
116
|
+
fix: r.fix ?? null
|
|
117
|
+
}));
|
|
118
|
+
const runId = (0, import_check_runs.recordCheckRun)({
|
|
119
|
+
projectRoot: root,
|
|
120
|
+
at: Date.now(),
|
|
121
|
+
by,
|
|
122
|
+
ranIn,
|
|
123
|
+
commit: code.commit,
|
|
124
|
+
dirty: code.dirty,
|
|
125
|
+
base: base ?? null,
|
|
126
|
+
rulebook: judgeBy ? since : null,
|
|
127
|
+
scope: scope ? (0, import_rule_scope.scopeWords)(scope) : null,
|
|
128
|
+
strict: strict === true,
|
|
129
|
+
outcome: { ok: c.ok, files: c.files.length, blocks: c.says.length, warns: findings.filter((f) => !f.failing).length },
|
|
130
|
+
says: c.says.slice(0, 200),
|
|
131
|
+
findings: findings.slice(0, 1e3)
|
|
132
|
+
}, { writer: (0, import_shared_state.writerId)(), name: (0, import_shared_state.writerName)(root) });
|
|
133
|
+
return { result: {
|
|
134
|
+
ok: c.ok,
|
|
135
|
+
says: c.says,
|
|
136
|
+
files: c.files.length,
|
|
137
|
+
run: runId,
|
|
138
|
+
breakpoints: c.breakpoints,
|
|
139
|
+
tests: c.tests,
|
|
140
|
+
criteria: c.criteria.map((x) => ({ item_uid: x.itemUid, task: x.task, criterion: x.criterion, findings: x.findings })),
|
|
141
|
+
docs: c.docs.map((d) => ({ uid: d.uid, title: d.title, slug: d.slug, verified_at: d.verifiedAt, files: d.files })),
|
|
142
|
+
rules: c.rules.map((r) => ({ path: r.path, imports: r.imports, rule: r.rule, words: r.words, because: r.because, strength: r.strength, suite: r.suite ?? "architecture", fix: r.fix ?? null, ...r.line ? { line_found: r.line } : {} })),
|
|
143
|
+
// C8: the rules judged by, so a suite can say how many hold.
|
|
144
|
+
// B5: an agent rule is a review's to judge, not this check's: it is not said to hold.
|
|
145
|
+
checked: (judgeBy ?? (0, import_rule_scope.scopeRules)((0, import_architecture_rules.rulesOf)(root), scope)).filter((r) => r.kind !== "agent").map((r) => ({ rule: r.id, suite: r.suite ?? "architecture", strength: r.strength })),
|
|
146
|
+
rulebook: c.rulebook.map((r) => ({ rule: r.rule, change: r.change, effect: r.effect, allowed: r.allowed, forbidden: r.forbidden, words: (0, import_rule_changes.changeWords)(r), ...r.approval ? { approval: r.approval } : {} })),
|
|
147
|
+
notes: c.notes,
|
|
148
|
+
...c.ratchet.length ? { ratchet: c.ratchet } : {},
|
|
149
|
+
...scope ? { scope: (0, import_rule_scope.scopeWords)(scope) } : {},
|
|
150
|
+
...c.rulesChecked ? {} : { rules_note: "The architecture rules were not checked: this project's imports are not loaded here. Open the project, or run `codetrellis start` in it." }
|
|
151
|
+
} };
|
|
152
|
+
}
|
|
153
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
154
|
+
0 && (module.exports = {
|
|
155
|
+
checkTheChange
|
|
156
|
+
});
|
|
@@ -0,0 +1,235 @@
|
|
|
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 channel_dispatcher_service_exports = {};
|
|
29
|
+
__export(channel_dispatcher_service_exports, {
|
|
30
|
+
dispatchChannelEvent: () => dispatchChannelEvent,
|
|
31
|
+
startChannelDispatcher: () => startChannelDispatcher,
|
|
32
|
+
stopChannelDispatcher: () => stopChannelDispatcher
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(channel_dispatcher_service_exports);
|
|
35
|
+
var _lazy___plan_service = __toESM(require("./plan-service"));
|
|
36
|
+
var import_channel_event_service = require("./channel-event-service");
|
|
37
|
+
var import_settings_service = require("./settings-service");
|
|
38
|
+
var import_webhook_egress = require("./webhook-egress");
|
|
39
|
+
var import_project_config_service = require("./project-config-service");
|
|
40
|
+
var import_plan_service = require("./plan-service");
|
|
41
|
+
var import_push_notification_service = require("./push-notification-service");
|
|
42
|
+
let broadcastFn = null;
|
|
43
|
+
let staleSweepTimer = null;
|
|
44
|
+
const firedNotifications = /* @__PURE__ */ new Set();
|
|
45
|
+
function startChannelDispatcher(broadcast) {
|
|
46
|
+
broadcastFn = broadcast;
|
|
47
|
+
if (staleSweepTimer) return;
|
|
48
|
+
staleSweepTimer = setInterval(() => {
|
|
49
|
+
sweepStaleEvents().catch((err) => console.warn("[ChannelDispatcher] stale sweep failed:", err));
|
|
50
|
+
}, 3e4);
|
|
51
|
+
if (typeof staleSweepTimer.unref === "function") staleSweepTimer.unref();
|
|
52
|
+
}
|
|
53
|
+
function stopChannelDispatcher() {
|
|
54
|
+
if (staleSweepTimer) {
|
|
55
|
+
clearInterval(staleSweepTimer);
|
|
56
|
+
staleSweepTimer = null;
|
|
57
|
+
}
|
|
58
|
+
firedNotifications.clear();
|
|
59
|
+
}
|
|
60
|
+
async function dispatchChannelEvent(event) {
|
|
61
|
+
(0, import_push_notification_service.pushForChannelEvent)(event).catch(
|
|
62
|
+
(err) => console.warn("[ChannelDispatcher] push notification failed:", err)
|
|
63
|
+
);
|
|
64
|
+
const projectRoot = projectRootForEvent(event);
|
|
65
|
+
if (!projectRoot) return;
|
|
66
|
+
const rules = (0, import_project_config_service.matchChannelRoutingRules)(projectRoot, event);
|
|
67
|
+
await Promise.all(
|
|
68
|
+
rules.filter((r) => r.when.minAgeMs === void 0).map((r) => fireRule(r, event))
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
async function sweepStaleEvents() {
|
|
72
|
+
const eligiblePlans = listEligiblePlansForSweep();
|
|
73
|
+
if (eligiblePlans.length === 0) return;
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
for (const { planUid, projectRoot, rules } of eligiblePlans) {
|
|
76
|
+
const openEvents = (0, import_channel_event_service.listChannelEvents)(planUid, { status: "open", limit: 500 });
|
|
77
|
+
for (const event of openEvents) {
|
|
78
|
+
for (const rule of rules) {
|
|
79
|
+
if (rule.when.minAgeMs === void 0) continue;
|
|
80
|
+
if (!matchesWithoutAge(rule, event)) continue;
|
|
81
|
+
const age = now - event.createdAt;
|
|
82
|
+
if (age < rule.when.minAgeMs) continue;
|
|
83
|
+
const key = notificationKey(rule, event);
|
|
84
|
+
if (firedNotifications.has(key)) continue;
|
|
85
|
+
firedNotifications.add(key);
|
|
86
|
+
await fireRule(rule, event, projectRoot);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function fireRule(rule, event, projectRootHint) {
|
|
92
|
+
try {
|
|
93
|
+
if (rule.notify.target === "webhook") {
|
|
94
|
+
await fireWebhook(rule, event);
|
|
95
|
+
} else if (rule.notify.target === "in-app-toast") {
|
|
96
|
+
fireToast(rule, event, projectRootHint);
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
console.warn(`[ChannelDispatcher] rule ${rule.id ?? "(unnamed)"} failed:`, err);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function fireWebhook(rule, event) {
|
|
103
|
+
if (rule.notify.target !== "webhook") return;
|
|
104
|
+
const url = rule.notify.url;
|
|
105
|
+
let target;
|
|
106
|
+
try {
|
|
107
|
+
const webhookSettings = (0, import_settings_service.getSettings)().webhooks;
|
|
108
|
+
target = await (0, import_webhook_egress.resolveWebhookTarget)(url, webhookSettings.allowedHosts, {
|
|
109
|
+
allowLoopback: webhookSettings.allowLoopback
|
|
110
|
+
});
|
|
111
|
+
} catch (err) {
|
|
112
|
+
if (err instanceof import_webhook_egress.WebhookBlocked) {
|
|
113
|
+
console.warn(`[ChannelDispatcher] webhook blocked \u2014 ${err.message}`);
|
|
114
|
+
broadcastFn?.("channel-webhook-blocked", {
|
|
115
|
+
ruleId: rule.id ?? null,
|
|
116
|
+
url,
|
|
117
|
+
reason: err.message
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
const payload = {
|
|
124
|
+
rule: { id: rule.id, description: rule.description },
|
|
125
|
+
event: {
|
|
126
|
+
uid: event.uid,
|
|
127
|
+
planUid: event.planUid,
|
|
128
|
+
itemUid: event.itemUid,
|
|
129
|
+
eventType: event.eventType,
|
|
130
|
+
status: event.status,
|
|
131
|
+
author: event.author,
|
|
132
|
+
authorType: event.authorType,
|
|
133
|
+
agentModel: event.agentModel,
|
|
134
|
+
respondsTo: event.respondsTo,
|
|
135
|
+
payload: event.payload,
|
|
136
|
+
createdAt: event.createdAt,
|
|
137
|
+
updatedAt: event.updatedAt
|
|
138
|
+
},
|
|
139
|
+
firedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
140
|
+
};
|
|
141
|
+
const headers = {
|
|
142
|
+
"content-type": "application/json",
|
|
143
|
+
...rule.notify.headers ?? {}
|
|
144
|
+
};
|
|
145
|
+
const body = JSON.stringify(payload);
|
|
146
|
+
const maxAttempts = 2;
|
|
147
|
+
let lastErr = null;
|
|
148
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
149
|
+
try {
|
|
150
|
+
const res = await (0, import_webhook_egress.postWebhookJson)(target, headers, body, 5e3);
|
|
151
|
+
if (res.redirected) {
|
|
152
|
+
console.warn(`[ChannelDispatcher] webhook ${url} redirected (${res.status}) \u2014 refusing to follow`);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (res.status >= 200 && res.status < 300) return;
|
|
156
|
+
if (res.status < 500) {
|
|
157
|
+
console.warn(`[ChannelDispatcher] webhook ${url} returned ${res.status} (no retry)`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
lastErr = new Error(`HTTP ${res.status}`);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
lastErr = err;
|
|
163
|
+
}
|
|
164
|
+
if (attempt < maxAttempts) {
|
|
165
|
+
await new Promise((r) => setTimeout(r, 500 * attempt));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
console.warn(`[ChannelDispatcher] webhook ${url} failed after ${maxAttempts} attempts:`, lastErr);
|
|
169
|
+
}
|
|
170
|
+
function fireToast(rule, event, projectRootHint) {
|
|
171
|
+
if (!broadcastFn) return;
|
|
172
|
+
if (rule.notify.target !== "in-app-toast") return;
|
|
173
|
+
broadcastFn("channel-toast-elevated", {
|
|
174
|
+
ruleId: rule.id ?? null,
|
|
175
|
+
description: rule.description ?? null,
|
|
176
|
+
tone: rule.notify.tone ?? "info",
|
|
177
|
+
sticky: !!rule.notify.sticky,
|
|
178
|
+
projectRoot: projectRootHint ?? projectRootForEvent(event),
|
|
179
|
+
event: {
|
|
180
|
+
uid: event.uid,
|
|
181
|
+
planUid: event.planUid,
|
|
182
|
+
itemUid: event.itemUid,
|
|
183
|
+
eventType: event.eventType,
|
|
184
|
+
status: event.status,
|
|
185
|
+
// Attribution must travel with the toast payload — the frontend
|
|
186
|
+
// composes the fallback title as "<eventType> · <author>" when
|
|
187
|
+
// the rule has no description. Without these the title falls
|
|
188
|
+
// back to the bland "Channel: stuck" every time.
|
|
189
|
+
author: event.author,
|
|
190
|
+
authorType: event.authorType,
|
|
191
|
+
agentModel: event.agentModel,
|
|
192
|
+
payload: event.payload
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function projectRootForEvent(event) {
|
|
197
|
+
const plan = (0, import_plan_service.getPlan)(event.planUid);
|
|
198
|
+
if (!plan) return null;
|
|
199
|
+
return plan.projectPath || null;
|
|
200
|
+
}
|
|
201
|
+
function matchesWithoutAge(rule, event) {
|
|
202
|
+
const w = rule.when;
|
|
203
|
+
if (w.eventType && w.eventType !== event.eventType) return false;
|
|
204
|
+
if (w.status && w.status !== event.status) return false;
|
|
205
|
+
if (w.planUid && w.planUid !== event.planUid) return false;
|
|
206
|
+
if (w.itemUid && w.itemUid !== event.itemUid) return false;
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
function notificationKey(rule, event) {
|
|
210
|
+
return `${rule.id ?? "_"}:${event.uid}`;
|
|
211
|
+
}
|
|
212
|
+
function listEligiblePlansForSweep() {
|
|
213
|
+
const { listPlans } = _lazy___plan_service;
|
|
214
|
+
const plans = listPlans();
|
|
215
|
+
const result = [];
|
|
216
|
+
const cache = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const plan of plans) {
|
|
218
|
+
if (!plan.projectPath) continue;
|
|
219
|
+
let rules = cache.get(plan.projectPath);
|
|
220
|
+
if (!rules) {
|
|
221
|
+
rules = (0, import_project_config_service.listChannelRoutingRules)(plan.projectPath).filter((r) => r.when.minAgeMs !== void 0);
|
|
222
|
+
cache.set(plan.projectPath, rules);
|
|
223
|
+
}
|
|
224
|
+
if (rules.length > 0) {
|
|
225
|
+
result.push({ planUid: plan.uid, projectRoot: plan.projectPath, rules });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
231
|
+
0 && (module.exports = {
|
|
232
|
+
dispatchChannelEvent,
|
|
233
|
+
startChannelDispatcher,
|
|
234
|
+
stopChannelDispatcher
|
|
235
|
+
});
|
|
@@ -0,0 +1,125 @@
|
|
|
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 channel_event_file_service_exports = {};
|
|
29
|
+
__export(channel_event_file_service_exports, {
|
|
30
|
+
channelsDirFor: () => channelsDirFor,
|
|
31
|
+
discoverChannelEventFiles: () => discoverChannelEventFiles,
|
|
32
|
+
exportChannelEvent: () => exportChannelEvent,
|
|
33
|
+
importChannelEvent: () => importChannelEvent,
|
|
34
|
+
isChannelEventFile: () => isChannelEventFile,
|
|
35
|
+
removeChannelEventFile: () => removeChannelEventFile
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(channel_event_file_service_exports);
|
|
38
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
39
|
+
var import_node_path = __toESM(require("node:path"));
|
|
40
|
+
var import_yaml = require("yaml");
|
|
41
|
+
var import_self_write_tracker = require("./self-write-tracker");
|
|
42
|
+
var import_plan_service = require("./plan-service");
|
|
43
|
+
var import_plan_file_service = require("./plan-file-service");
|
|
44
|
+
var import_channel_event_service = require("./channel-event-service");
|
|
45
|
+
var import_plans_home = require("./plans-home");
|
|
46
|
+
const CHANNELS_DIR_NAME = "channels";
|
|
47
|
+
function channelsDirFor(planUid, projectRoot) {
|
|
48
|
+
const linked = (0, import_plan_file_service.getLinkedPlanDir)(planUid, projectRoot);
|
|
49
|
+
if (linked) return import_node_path.default.join(linked, CHANNELS_DIR_NAME);
|
|
50
|
+
const plan = (0, import_plan_service.getPlan)(planUid);
|
|
51
|
+
const slug = plan ? (0, import_plan_file_service.makePlanSlug)(plan) : planUid;
|
|
52
|
+
return import_node_path.default.join((0, import_plans_home.plansHome)(projectRoot) ?? projectRoot, ".codetrellis", "plans", slug, CHANNELS_DIR_NAME);
|
|
53
|
+
}
|
|
54
|
+
function exportChannelEvent(event, projectRoot) {
|
|
55
|
+
const dir = channelsDirFor(event.planUid, projectRoot);
|
|
56
|
+
ensureDir(dir);
|
|
57
|
+
const filePath = import_node_path.default.join(dir, `${event.uid}.yaml`);
|
|
58
|
+
const record = (0, import_channel_event_service.eventToManifest)(event);
|
|
59
|
+
writeAtomic(filePath, (0, import_yaml.stringify)(record));
|
|
60
|
+
return filePath;
|
|
61
|
+
}
|
|
62
|
+
function removeChannelEventFile(eventUid, planUid, projectRoot) {
|
|
63
|
+
const filePath = import_node_path.default.join(channelsDirFor(planUid, projectRoot), `${eventUid}.yaml`);
|
|
64
|
+
if (!import_node_fs.default.existsSync(filePath)) return false;
|
|
65
|
+
(0, import_self_write_tracker.stampSelfWrite)(filePath);
|
|
66
|
+
import_node_fs.default.unlinkSync(filePath);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
function importChannelEvent(filePath, planDir) {
|
|
70
|
+
if (!import_node_fs.default.existsSync(filePath)) return null;
|
|
71
|
+
const planUid = readPlanUidFromDir(planDir);
|
|
72
|
+
if (!planUid) {
|
|
73
|
+
console.warn(`[ChannelEvents] Could not resolve plan UID from ${planDir} \u2014 skipping import.`);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const raw = (0, import_yaml.parse)(import_node_fs.default.readFileSync(filePath, "utf-8"));
|
|
78
|
+
if (!raw || typeof raw !== "object") return null;
|
|
79
|
+
const record = raw;
|
|
80
|
+
if (!record.uid || !record.eventType || !record.payload) return null;
|
|
81
|
+
const input = (0, import_channel_event_service.manifestToEventInput)(planUid, record);
|
|
82
|
+
return (0, import_channel_event_service.postChannelEvent)(input);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.warn(`[ChannelEvents] Failed to import ${filePath}:`, err);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function readPlanUidFromDir(planDir) {
|
|
89
|
+
const planYaml = import_node_path.default.join(planDir, "plan.yaml");
|
|
90
|
+
if (!import_node_fs.default.existsSync(planYaml)) return null;
|
|
91
|
+
try {
|
|
92
|
+
const raw = (0, import_yaml.parse)(import_node_fs.default.readFileSync(planYaml, "utf-8"));
|
|
93
|
+
if (raw && typeof raw === "object" && typeof raw.uid === "string") {
|
|
94
|
+
return raw.uid;
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function discoverChannelEventFiles(planDir) {
|
|
101
|
+
const dir = import_node_path.default.join(planDir, CHANNELS_DIR_NAME);
|
|
102
|
+
if (!import_node_fs.default.existsSync(dir)) return [];
|
|
103
|
+
return import_node_fs.default.readdirSync(dir).filter((f) => f.endsWith(".yaml")).map((f) => import_node_path.default.join(dir, f));
|
|
104
|
+
}
|
|
105
|
+
function isChannelEventFile(filePath) {
|
|
106
|
+
return import_node_path.default.basename(import_node_path.default.dirname(filePath)) === CHANNELS_DIR_NAME && filePath.endsWith(".yaml");
|
|
107
|
+
}
|
|
108
|
+
function ensureDir(dir) {
|
|
109
|
+
if (!import_node_fs.default.existsSync(dir)) import_node_fs.default.mkdirSync(dir, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
function writeAtomic(filePath, content) {
|
|
112
|
+
const tmp = `${filePath}.tmp`;
|
|
113
|
+
import_node_fs.default.writeFileSync(tmp, content, "utf-8");
|
|
114
|
+
import_node_fs.default.renameSync(tmp, filePath);
|
|
115
|
+
(0, import_self_write_tracker.stampSelfWrite)(filePath);
|
|
116
|
+
}
|
|
117
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
118
|
+
0 && (module.exports = {
|
|
119
|
+
channelsDirFor,
|
|
120
|
+
discoverChannelEventFiles,
|
|
121
|
+
exportChannelEvent,
|
|
122
|
+
importChannelEvent,
|
|
123
|
+
isChannelEventFile,
|
|
124
|
+
removeChannelEventFile
|
|
125
|
+
});
|