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,150 @@
|
|
|
1
|
+
# Tree-sitter grammars
|
|
2
|
+
|
|
3
|
+
These `.wasm` files are the parser grammars `ast-parser.ts` loads at
|
|
4
|
+
boot, one per `ParserPlugin.grammarFile`. They are committed rather
|
|
5
|
+
than fetched at install time, and copied verbatim into the packaged app
|
|
6
|
+
via `extraResource`.
|
|
7
|
+
|
|
8
|
+
`tree-sitter.wasm` is not a grammar — it is the **runtime**, loaded by
|
|
9
|
+
`Parser.init({ locateFile })`. It must stay ABI-compatible with the
|
|
10
|
+
pinned `web-tree-sitter` version in `package.json`.
|
|
11
|
+
|
|
12
|
+
## Compatibility
|
|
13
|
+
|
|
14
|
+
A grammar built for an older tree-sitter ABI fails at
|
|
15
|
+
`Language.load()` with an opaque emscripten dylink error, and
|
|
16
|
+
`loadGrammars()` catches it, logs a warning and carries on — so an
|
|
17
|
+
incompatible grammar presents as **a language that silently produces no
|
|
18
|
+
symbols and no edges**, not as a crash. That is a slow, confusing
|
|
19
|
+
failure, so:
|
|
20
|
+
|
|
21
|
+
- `src/backend/services/parsers/go.test.ts` loads the Go grammar
|
|
22
|
+
directly under `npm run test:unit` and asserts it parses. It is the
|
|
23
|
+
fastest signal that a grammar swap broke something. Worth copying for
|
|
24
|
+
the other languages.
|
|
25
|
+
- A grammar from a bundle that targets an older runtime will not load.
|
|
26
|
+
During Phase 20 the `tree-sitter-wasms@0.1.13` build of Go failed
|
|
27
|
+
exactly this way against `web-tree-sitter@0.27`; the grammar shipped
|
|
28
|
+
in the official `tree-sitter-go` npm package loaded cleanly.
|
|
29
|
+
|
|
30
|
+
## Provenance
|
|
31
|
+
|
|
32
|
+
| File | sha256 | Source |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `tree-sitter-go.wasm` | `9504573f352b20be7f2f1911754d710622aedc15afff16d5ed8fb5645681aee7` | npm `tree-sitter-go@0.25.0`, the `tree-sitter-go.wasm` shipped in the package (Phase 20) |
|
|
35
|
+
| `tree-sitter-ruby.wasm` | `09a96427d7c72f0613ed470cd9812223fc4a91d6a9c025c0235cc6bd59ff96f4` | npm `tree-sitter-ruby@0.23.1`, the `tree-sitter-ruby.wasm` shipped in the package (Phase 27) |
|
|
36
|
+
| `tree-sitter-c-sharp.wasm` | `6f69e1cae44e1c32c1eccc170dc5a9778fb94ff716f71113fe1f8c4299aa2f40` | npm `tree-sitter-c-sharp@0.23.5`, the `tree-sitter-c_sharp.wasm` shipped in the package (Phase 27). ABI 15. |
|
|
37
|
+
| `tree-sitter-kotlin.wasm` | `7009d69453bc8735e438b2818a633efb21c88f99782769abba60dffedfab73f7` | npm `@tree-sitter-grammars/tree-sitter-kotlin@1.1.0`, the `tree-sitter-kotlin.wasm` shipped in the package (Phase 27). ABI 14. |
|
|
38
|
+
| `tree-sitter-swift.wasm` | `24a6afb13db61ffd7d53dd848bbf684ec1c3aacea685a0857dcd1db673d28c7e` | Built from source — npm `tree-sitter-swift@0.7.1` (tarball sha1 `e7b41402dbc29fc3a8741793513e7a0f3e35cc55`, matching npm's `dist.shasum`), compiled with `tree-sitter-cli@0.27.0`. ABI 14. See "Swift is built from source" below. |
|
|
39
|
+
| `tree-sitter-java.wasm` | `4fdeac4ca6ca089f06c6f7e562abcac1733cd465728cc7031ebb73c2019122c4` | unrecorded — predates this file |
|
|
40
|
+
| `tree-sitter-javascript.wasm` | `5fb488d0cabb4775a594bab85682de5ad6ce83c0d6ac997a9f82dd084d571240` | unrecorded — predates this file |
|
|
41
|
+
| `tree-sitter-php.wasm` | `d4df6a6ff08c87c3ec4f9cbb785fe09998a0cb570e03f57d7b19b3acfb146aa7` | unrecorded — predates this file |
|
|
42
|
+
| `tree-sitter-python.wasm` | `16108b50df4ee9a30168794252ab55e7c93bfc5765d7fa0aa3e335752c515f47` | unrecorded — predates this file |
|
|
43
|
+
| `tree-sitter-rust.wasm` | `f65f354215611fd94ad34134b3427eb3d58cbb745df7b6509ba722184db73d57` | unrecorded — predates this file |
|
|
44
|
+
| `tree-sitter-tsx.wasm` | `79e5da75ea62855a0cd67177685f0164eac87d5f630b3cbe1e0a099751ad30f8` | unrecorded — predates this file |
|
|
45
|
+
| `tree-sitter-typescript.wasm` | `778025db5a8be0e70f8ccc3671e486dfeddd048c25d9e8a70c26de2e1bf6f97d` | unrecorded — predates this file |
|
|
46
|
+
| `tree-sitter.wasm` | `c03bccdc3b448a32848f5ae327e209c982bbb0840d43eec8bc2d5759544a1ed3` | the `web-tree-sitter` runtime (see `package.json` for the pinned version) |
|
|
47
|
+
|
|
48
|
+
## Swift is built from source
|
|
49
|
+
|
|
50
|
+
Swift is the one grammar with no artifact of its own to take: no
|
|
51
|
+
published `tree-sitter-swift` ships a wasm at any version, and there is
|
|
52
|
+
no `@tree-sitter-grammars/tree-sitter-swift`. Until this build it
|
|
53
|
+
shipped a third-party artifact from `@repomix/tree-sitter-wasms`. It is
|
|
54
|
+
now compiled here from the maintainers' own source.
|
|
55
|
+
|
|
56
|
+
Reproduce it:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm pack tree-sitter-swift@0.7.1
|
|
60
|
+
# tarball sha1 must be e7b41402dbc29fc3a8741793513e7a0f3e35cc55 — npm's dist.shasum
|
|
61
|
+
tar -xzf tree-sitter-swift-0.7.1.tgz
|
|
62
|
+
cd package && npx tree-sitter-cli@0.27.0 build --wasm .
|
|
63
|
+
sha256sum tree-sitter-swift.wasm
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**This needs no Emscripten.** tree-sitter-cli 0.27 downloads a pinned
|
|
67
|
+
wasi-sdk and binaryen into `~/.cache/tree-sitter` and builds with those,
|
|
68
|
+
so the toolchain comes from the CLI version rather than from whatever
|
|
69
|
+
the machine happens to have. The CLI's minor is deliberately matched to
|
|
70
|
+
the pinned `web-tree-sitter` (0.27) — the runtime that loads it.
|
|
71
|
+
`src/parser.c` declares ABI 14, the same ABI as the artifact this
|
|
72
|
+
replaced.
|
|
73
|
+
|
|
74
|
+
**The bytes are not reproducible across machines.** A different wasi-sdk
|
|
75
|
+
or wasm-opt will compile the same source to a different sha256. The hash
|
|
76
|
+
in the table pins what is *committed*, so a change to it is visible in a
|
|
77
|
+
diff; the tarball sha1 above is what pins the *source*.
|
|
78
|
+
|
|
79
|
+
What this bought, stated plainly: trust moved from the `@repomix`
|
|
80
|
+
publisher to the `tree-sitter-swift` maintainers — the same people the
|
|
81
|
+
other rows already trust. It was never a large exposure. A grammar runs
|
|
82
|
+
inside the wasm sandbox and imports nothing but the tree-sitter runtime:
|
|
83
|
+
no filesystem, no network, no host calls. The worst a hostile grammar
|
|
84
|
+
can do is return a wrong parse tree or hang the parse loop, which is far
|
|
85
|
+
less than an npm package with an install script.
|
|
86
|
+
|
|
87
|
+
Verified before committing, because a bad grammar swap is silent — it
|
|
88
|
+
presents as a language that produces no symbols, not as a crash:
|
|
89
|
+
|
|
90
|
+
- The new wasm produces **symbol and import extraction identical** to the
|
|
91
|
+
artifact it replaced, over a sample covering class, struct, enum,
|
|
92
|
+
extension, protocol, actor, init, deinit, subscript and computed
|
|
93
|
+
properties. Identical sets, no parse errors, on both.
|
|
94
|
+
- `parsers/jvm-and-apple.test.ts` passes under `npm run test:unit`.
|
|
95
|
+
|
|
96
|
+
The seven "unrecorded" rows are honest: those files were committed
|
|
97
|
+
before provenance was tracked, and guessing a version here would be
|
|
98
|
+
worse than saying so. Their hashes are recorded now, so any future
|
|
99
|
+
change to them is at least visible. Re-deriving their true origin is
|
|
100
|
+
worth doing the next time any of them is touched — this is a public
|
|
101
|
+
repo shipping compiled binaries, and "where did this come from" should
|
|
102
|
+
have an answer.
|
|
103
|
+
|
|
104
|
+
## Adding a grammar
|
|
105
|
+
|
|
106
|
+
1. Obtain the `.wasm`, preferring the grammar's own npm package — those
|
|
107
|
+
are built against a current runtime.
|
|
108
|
+
|
|
109
|
+
**Check every plausible package name before concluding no artifact
|
|
110
|
+
exists.** Phase 27 initially costed Kotlin and Swift as needing an
|
|
111
|
+
Emscripten toolchain because `tree-sitter-kotlin@0.3.8` ships no wasm.
|
|
112
|
+
`@tree-sitter-grammars/tree-sitter-kotlin@1.1.0` — the maintained one,
|
|
113
|
+
under the grammar org's scope — ships it. One `npm pack` of the right
|
|
114
|
+
name replaced a multi-day build story. Names to try, in order:
|
|
115
|
+
`@tree-sitter-grammars/tree-sitter-<lang>`, then
|
|
116
|
+
`tree-sitter-<lang>`, then a reputable prebuilt bundle. Record which
|
|
117
|
+
one you used.
|
|
118
|
+
|
|
119
|
+
An external C scanner (`src/scanner.c`) is a hint that a local build
|
|
120
|
+
will be fiddly, **not** evidence that no prebuilt exists — C#, Kotlin
|
|
121
|
+
and Swift all have one and all three have a usable published wasm.
|
|
122
|
+
See [docs/PHASE-27-LANGUAGE-EXPANSION.md](../../docs/PHASE-27-LANGUAGE-EXPANSION.md).
|
|
123
|
+
2. **Verify it loads and parses before writing any plugin code**, and
|
|
124
|
+
read the grammar's real node shapes off a sample file rather than
|
|
125
|
+
assuming them. Several grammars pack multiple declarations into one
|
|
126
|
+
node type and separate them with an **anonymous** keyword token that
|
|
127
|
+
`namedChildren` cannot see — Kotlin's `class_declaration` is class,
|
|
128
|
+
interface and enum; Swift's is class, struct, enum and extension.
|
|
129
|
+
Guessing there produces a plausible, wrong graph rather than an error.
|
|
130
|
+
A unit test like `parsers/go.test.ts` is the cheapest way.
|
|
131
|
+
3. Commit it here and add a row above with its sha256 and exact source.
|
|
132
|
+
4. Register the plugin in `parsers/index.ts`, and add the extension to
|
|
133
|
+
the scanner's `LANG_MAP` and the tag to `SupportedLanguage`. The
|
|
134
|
+
file-watcher needs nothing — it derives its parseable-extension set
|
|
135
|
+
from the same registry — and `findUnparsedLanguages()` fails the unit
|
|
136
|
+
suite if the scanner tags a language no plugin claims.
|
|
137
|
+
5. Emit a **flat** symbol list with qualified member names
|
|
138
|
+
(`Type.member`). Nested symbols are written to the database and then
|
|
139
|
+
filtered out by every per-file reader — see `flattenSymbols` in
|
|
140
|
+
`parsers/base.ts`.
|
|
141
|
+
6. Add the language to `frontend/lib/prism-lang.ts` and
|
|
142
|
+
`frontend/lib/codemirror-lang.ts`, or deliberately leave it out.
|
|
143
|
+
Both are guarded by `prism-lang.test.ts`; naming a grammar that is not
|
|
144
|
+
installed renders plain text with no error.
|
|
145
|
+
|
|
146
|
+
To re-verify every hash:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cd resources/tree-sitter && sha256sum *.wasm
|
|
150
|
+
```
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,270 @@
|
|
|
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 claude_code_watcher_exports = {};
|
|
29
|
+
__export(claude_code_watcher_exports, {
|
|
30
|
+
getWatcherStatus: () => getWatcherStatus,
|
|
31
|
+
startClaudeCodeWatcher: () => startClaudeCodeWatcher,
|
|
32
|
+
stopClaudeCodeWatcher: () => stopClaudeCodeWatcher
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(claude_code_watcher_exports);
|
|
35
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
36
|
+
var import_node_path = __toESM(require("node:path"));
|
|
37
|
+
var import_node_os = __toESM(require("node:os"));
|
|
38
|
+
var import_server = require("../server");
|
|
39
|
+
var import_budget_service = require("../services/budget-service");
|
|
40
|
+
var import_agent_event_log = require("../services/agent-event-log");
|
|
41
|
+
var import_skill_use_service = require("../services/skill-use-service");
|
|
42
|
+
var import_workstream_binding = require("../services/workstream-binding");
|
|
43
|
+
const claudeDir = () => process.env.CODETRELLIS_CLAUDE_DIR || import_node_path.default.join(import_node_os.default.homedir(), ".claude");
|
|
44
|
+
const sessionsDir = () => import_node_path.default.join(claudeDir(), "sessions");
|
|
45
|
+
const projectsDir = () => import_node_path.default.join(claudeDir(), "projects");
|
|
46
|
+
const pollIntervalMs = () => Number(process.env.CODETRELLIS_WATCHER_POLL_MS) || 2e3;
|
|
47
|
+
let watchInterval = null;
|
|
48
|
+
const watched = /* @__PURE__ */ new Map();
|
|
49
|
+
let lastBound = null;
|
|
50
|
+
function jsonlDirsFor(cwd) {
|
|
51
|
+
const dirs = [cwd.replace(/\//g, "-"), cwd.replace(/[^a-zA-Z0-9]/g, "-")];
|
|
52
|
+
return [...new Set(dirs)].map((d) => import_node_path.default.join(projectsDir(), d));
|
|
53
|
+
}
|
|
54
|
+
function findLiveSessions(folders) {
|
|
55
|
+
if (!folders.length || !import_node_fs.default.existsSync(sessionsDir())) return [];
|
|
56
|
+
const live = [];
|
|
57
|
+
for (const file of import_node_fs.default.readdirSync(sessionsDir()).filter((f) => f.endsWith(".json"))) {
|
|
58
|
+
try {
|
|
59
|
+
const session = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(sessionsDir(), file), "utf-8"));
|
|
60
|
+
if (typeof session.sessionId !== "string" || typeof session.cwd !== "string") continue;
|
|
61
|
+
const workstreamRoot = (0, import_workstream_binding.matchWorkstreamRoot)(session.cwd, folders);
|
|
62
|
+
if (!workstreamRoot) continue;
|
|
63
|
+
try {
|
|
64
|
+
process.kill(session.pid, 0);
|
|
65
|
+
} catch {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const jsonlPath = jsonlDirsFor(session.cwd).map((dir) => import_node_path.default.join(dir, `${session.sessionId}.jsonl`)).find((p) => import_node_fs.default.existsSync(p));
|
|
69
|
+
if (jsonlPath) live.push({ sessionId: session.sessionId, jsonlPath, workstreamRoot });
|
|
70
|
+
} catch {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return live;
|
|
75
|
+
}
|
|
76
|
+
function parseJsonlEntries(line) {
|
|
77
|
+
try {
|
|
78
|
+
const entry = JSON.parse(line);
|
|
79
|
+
return parseEntry(entry).map((e) => ({ ...e, timestamp: entryTime(entry, e.timestamp) }));
|
|
80
|
+
} catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function entryTime(entry, readAt) {
|
|
85
|
+
const t = typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) : NaN;
|
|
86
|
+
return Number.isFinite(t) && t <= readAt + 6e4 ? t : readAt;
|
|
87
|
+
}
|
|
88
|
+
function parseEntry(entry) {
|
|
89
|
+
try {
|
|
90
|
+
const type = entry.type;
|
|
91
|
+
if (type === "assistant") {
|
|
92
|
+
const usage = entry.message?.usage;
|
|
93
|
+
const sessionId = entry.sessionId ?? entry.session_id;
|
|
94
|
+
if (usage && typeof sessionId === "string") {
|
|
95
|
+
try {
|
|
96
|
+
(0, import_budget_service.recordTokens)({
|
|
97
|
+
sessionId,
|
|
98
|
+
model: entry.message?.model ?? null,
|
|
99
|
+
tokens: {
|
|
100
|
+
inputTokens: usage.input_tokens ?? 0,
|
|
101
|
+
outputTokens: usage.output_tokens ?? 0,
|
|
102
|
+
cacheWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
103
|
+
cacheReadTokens: usage.cache_read_input_tokens ?? 0
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const content = entry.message?.content;
|
|
110
|
+
if (!Array.isArray(content)) return [];
|
|
111
|
+
const events = [];
|
|
112
|
+
for (const block of content) {
|
|
113
|
+
if (block.type === "tool_use") {
|
|
114
|
+
events.push(toolUseEvent(block.name, block.input || {}));
|
|
115
|
+
} else if (block.type === "text") {
|
|
116
|
+
const text = block.text || "";
|
|
117
|
+
if (isPlanLike(text)) {
|
|
118
|
+
events.push(makeEvent("plan_reported", {
|
|
119
|
+
text: text.substring(0, 1e3)
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return events;
|
|
125
|
+
}
|
|
126
|
+
if (type === "user") {
|
|
127
|
+
return [makeEvent("session_start", {
|
|
128
|
+
message: (entry.message?.content || "").substring(0, 200),
|
|
129
|
+
timestamp: entry.timestamp
|
|
130
|
+
})];
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
} catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function toolUseEvent(toolName, input) {
|
|
138
|
+
if (toolName === "Read") return makeEvent("file_changed", { action: "read", file: input.file_path, tool: toolName });
|
|
139
|
+
if (toolName === "Write") return makeEvent("file_changed", { action: "write", file: input.file_path, tool: toolName });
|
|
140
|
+
if (toolName === "Edit") return makeEvent("file_changed", { action: "edit", file: input.file_path, tool: toolName });
|
|
141
|
+
if (toolName === "Bash") {
|
|
142
|
+
return makeEvent("file_changed", { action: "bash", command: String(input.command ?? "").substring(0, 200), tool: toolName });
|
|
143
|
+
}
|
|
144
|
+
if (toolName === "Skill") {
|
|
145
|
+
return makeEvent("skill_used", { skill: String(input.skill ?? input.name ?? "").slice(0, 80), tool: toolName });
|
|
146
|
+
}
|
|
147
|
+
if (toolName === "Glob" || toolName === "Grep") {
|
|
148
|
+
return makeEvent("architecture_query", { tool: toolName, pattern: input.pattern || input.query });
|
|
149
|
+
}
|
|
150
|
+
return makeEvent("file_changed", { action: "tool", tool: toolName });
|
|
151
|
+
}
|
|
152
|
+
function isPlanLike(text) {
|
|
153
|
+
const lines = text.split("\n").filter((l) => l.trim());
|
|
154
|
+
const numberedLines = lines.filter((l) => /^\s*\d+[.)]\s/.test(l));
|
|
155
|
+
if (numberedLines.length >= 3) return true;
|
|
156
|
+
const hasHeaders = lines.some((l) => l.startsWith("##") || l.startsWith("**"));
|
|
157
|
+
const hasBullets = lines.filter((l) => /^\s*[-*]\s/.test(l)).length >= 3;
|
|
158
|
+
if (hasHeaders && hasBullets) return true;
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
function makeEvent(type, payload) {
|
|
162
|
+
return {
|
|
163
|
+
id: (0, import_agent_event_log.eventId)("cc"),
|
|
164
|
+
timestamp: Date.now(),
|
|
165
|
+
source: "claude-code-watcher",
|
|
166
|
+
type,
|
|
167
|
+
payload
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function tailSession(sessionId, w) {
|
|
171
|
+
try {
|
|
172
|
+
const stat = import_node_fs.default.statSync(w.jsonlPath);
|
|
173
|
+
if (stat.size <= w.position) return;
|
|
174
|
+
const fd = import_node_fs.default.openSync(w.jsonlPath, "r");
|
|
175
|
+
const buffer = Buffer.alloc(stat.size - w.position);
|
|
176
|
+
import_node_fs.default.readSync(fd, buffer, 0, buffer.length, w.position);
|
|
177
|
+
import_node_fs.default.closeSync(fd);
|
|
178
|
+
const text = buffer.toString("utf-8");
|
|
179
|
+
const complete = text.lastIndexOf("\n") + 1;
|
|
180
|
+
w.position += Buffer.byteLength(text.slice(0, complete), "utf-8");
|
|
181
|
+
for (const line of text.slice(0, complete).split("\n")) {
|
|
182
|
+
if (!line.trim()) continue;
|
|
183
|
+
for (const event of parseJsonlEntries(line)) {
|
|
184
|
+
event.payload = { ...event.payload, sessionId, workstreamRoot: w.workstreamRoot };
|
|
185
|
+
if (event.type === "skill_used" && typeof event.payload.skill === "string") {
|
|
186
|
+
const itemUids = (0, import_skill_use_service.recordSkillUse)({ skill: event.payload.skill, sessionId, workstreamRoot: w.workstreamRoot, at: event.timestamp });
|
|
187
|
+
event.payload = { ...event.payload, itemUids };
|
|
188
|
+
}
|
|
189
|
+
(0, import_server.broadcast)("agent-event", event);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const REBIND_CHECK_TICKS = 5;
|
|
196
|
+
function follow(session) {
|
|
197
|
+
let position = 0;
|
|
198
|
+
try {
|
|
199
|
+
position = import_node_fs.default.statSync(session.jsonlPath).size;
|
|
200
|
+
} catch {
|
|
201
|
+
}
|
|
202
|
+
watched.set(session.sessionId, { jsonlPath: session.jsonlPath, position, workstreamRoot: session.workstreamRoot });
|
|
203
|
+
lastBound = session.sessionId;
|
|
204
|
+
console.log(`[ClaudeWatcher] Following session ${session.sessionId} in ${session.workstreamRoot}`);
|
|
205
|
+
(0, import_server.broadcast)("agent-event", makeEvent("session_start", {
|
|
206
|
+
sessionId: session.sessionId,
|
|
207
|
+
workstreamRoot: session.workstreamRoot
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
function reconcile(live) {
|
|
211
|
+
const liveIds = new Set(live.map((s) => s.sessionId));
|
|
212
|
+
for (const [id, w] of watched) {
|
|
213
|
+
if (liveIds.has(id)) continue;
|
|
214
|
+
tailSession(id, w);
|
|
215
|
+
watched.delete(id);
|
|
216
|
+
if (lastBound === id) lastBound = [...watched.keys()].pop() ?? null;
|
|
217
|
+
}
|
|
218
|
+
for (const s of live) if (!watched.has(s.sessionId)) follow(s);
|
|
219
|
+
}
|
|
220
|
+
const FOLDERS_TTL_MS = 3e4;
|
|
221
|
+
function startClaudeCodeWatcher(projectRoot, folders) {
|
|
222
|
+
stopClaudeCodeWatcher();
|
|
223
|
+
let cached = null;
|
|
224
|
+
const currentFolders = () => {
|
|
225
|
+
if (folders) return folders();
|
|
226
|
+
if (cached && Date.now() - cached.at < FOLDERS_TTL_MS) return cached.list;
|
|
227
|
+
let list;
|
|
228
|
+
try {
|
|
229
|
+
list = [.../* @__PURE__ */ new Set([projectRoot, ...(0, import_workstream_binding.candidateWorkstreamRoots)()])];
|
|
230
|
+
} catch {
|
|
231
|
+
list = [projectRoot];
|
|
232
|
+
}
|
|
233
|
+
cached = { at: Date.now(), list };
|
|
234
|
+
return list;
|
|
235
|
+
};
|
|
236
|
+
reconcile(findLiveSessions(currentFolders()));
|
|
237
|
+
if (!watched.size) console.log("[ClaudeWatcher] No active Claude Code session found, polling...");
|
|
238
|
+
let ticksSinceCheck = 0;
|
|
239
|
+
watchInterval = setInterval(() => {
|
|
240
|
+
if (!watched.size || ++ticksSinceCheck >= REBIND_CHECK_TICKS) {
|
|
241
|
+
ticksSinceCheck = 0;
|
|
242
|
+
reconcile(findLiveSessions(currentFolders()));
|
|
243
|
+
}
|
|
244
|
+
for (const [id, w] of watched) tailSession(id, w);
|
|
245
|
+
}, pollIntervalMs());
|
|
246
|
+
console.log(`[ClaudeWatcher] Watching for Claude Code sessions in ${projectRoot} and its workstreams`);
|
|
247
|
+
}
|
|
248
|
+
function stopClaudeCodeWatcher() {
|
|
249
|
+
if (watchInterval) {
|
|
250
|
+
clearInterval(watchInterval);
|
|
251
|
+
watchInterval = null;
|
|
252
|
+
}
|
|
253
|
+
watched.clear();
|
|
254
|
+
lastBound = null;
|
|
255
|
+
}
|
|
256
|
+
function getWatcherStatus() {
|
|
257
|
+
const latest = lastBound ? watched.get(lastBound) : void 0;
|
|
258
|
+
return {
|
|
259
|
+
watching: watchInterval !== null,
|
|
260
|
+
sessionId: latest ? lastBound : null,
|
|
261
|
+
jsonlPath: latest?.jsonlPath ?? null,
|
|
262
|
+
sessions: [...watched].map(([sessionId, w]) => ({ sessionId, jsonlPath: w.jsonlPath, workstreamRoot: w.workstreamRoot }))
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
266
|
+
0 && (module.exports = {
|
|
267
|
+
getWatcherStatus,
|
|
268
|
+
startClaudeCodeWatcher,
|
|
269
|
+
stopClaudeCodeWatcher
|
|
270
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var import_server = require("./server");
|
|
2
|
+
var import_lifecycle = require("./lifecycle");
|
|
3
|
+
const PORT = parseInt(process.env.PORT || "3001", 10);
|
|
4
|
+
(0, import_lifecycle.installProcessHandlers)();
|
|
5
|
+
(0, import_server.startServer)(PORT).catch((err) => {
|
|
6
|
+
console.error("[Backend] Failed to start:", err);
|
|
7
|
+
process.exit(1);
|
|
8
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
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 sha256_file_exports = {};
|
|
19
|
+
__export(sha256_file_exports, {
|
|
20
|
+
sha256FileWithin: () => sha256FileWithin
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(sha256_file_exports);
|
|
23
|
+
var import_node_crypto = require("node:crypto");
|
|
24
|
+
var import_confined_fs = require("../services/confined-fs");
|
|
25
|
+
var import_cloud_files = require("../services/cloud-files");
|
|
26
|
+
function sha256FileWithin(root, rel) {
|
|
27
|
+
if ((0, import_cloud_files.isPlaceholder)((0, import_confined_fs.resolveWithin)(root, rel, "artefact"))) return Promise.reject(new import_cloud_files.NotOnDeviceError(rel));
|
|
28
|
+
const { stream, size, mtimeMs } = (0, import_confined_fs.openReadStreamWithin)(root, rel, {}, "artefact");
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const hash = (0, import_node_crypto.createHash)("sha256");
|
|
31
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
32
|
+
stream.on("error", reject);
|
|
33
|
+
stream.on("end", () => resolve({ sha256: hash.digest("hex"), size, mtimeMs }));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
sha256FileWithin
|
|
39
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
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 zip_entries_exports = {};
|
|
29
|
+
__export(zip_entries_exports, {
|
|
30
|
+
ZipError: () => ZipError,
|
|
31
|
+
listZipEntries: () => listZipEntries,
|
|
32
|
+
readZipEntry: () => readZipEntry
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(zip_entries_exports);
|
|
35
|
+
var import_node_zlib = __toESM(require("node:zlib"));
|
|
36
|
+
class ZipError extends Error {
|
|
37
|
+
}
|
|
38
|
+
const EOCD_SIG = 101010256;
|
|
39
|
+
const CEN_SIG = 33639248;
|
|
40
|
+
const LOC_SIG = 67324752;
|
|
41
|
+
function listZipEntries(buf) {
|
|
42
|
+
const floor = Math.max(0, buf.length - 22 - 65535);
|
|
43
|
+
let eocd = -1;
|
|
44
|
+
for (let i = buf.length - 22; i >= floor; i--) {
|
|
45
|
+
if (buf.readUInt32LE(i) === EOCD_SIG) {
|
|
46
|
+
eocd = i;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (eocd < 0) throw new ZipError("not a zip archive");
|
|
51
|
+
const count = buf.readUInt16LE(eocd + 10);
|
|
52
|
+
let p = buf.readUInt32LE(eocd + 16);
|
|
53
|
+
const entries = [];
|
|
54
|
+
for (let n = 0; n < count; n++) {
|
|
55
|
+
if (p + 46 > buf.length || buf.readUInt32LE(p) !== CEN_SIG) throw new ZipError("corrupt central directory");
|
|
56
|
+
const method = buf.readUInt16LE(p + 10);
|
|
57
|
+
const compressedSize = buf.readUInt32LE(p + 20);
|
|
58
|
+
const size = buf.readUInt32LE(p + 24);
|
|
59
|
+
const nameLen = buf.readUInt16LE(p + 28);
|
|
60
|
+
const extraLen = buf.readUInt16LE(p + 30);
|
|
61
|
+
const commentLen = buf.readUInt16LE(p + 32);
|
|
62
|
+
const localHeaderOffset = buf.readUInt32LE(p + 42);
|
|
63
|
+
const name = buf.toString("utf8", p + 46, p + 46 + nameLen);
|
|
64
|
+
entries.push({ name, method, compressedSize, size, localHeaderOffset });
|
|
65
|
+
p += 46 + nameLen + extraLen + commentLen;
|
|
66
|
+
}
|
|
67
|
+
return entries;
|
|
68
|
+
}
|
|
69
|
+
function readZipEntry(buf, name, opts = {}) {
|
|
70
|
+
const max = opts.maxEntryBytes ?? 20 * 1024 * 1024;
|
|
71
|
+
const entry = (opts.entries ?? listZipEntries(buf)).find((e) => e.name === name);
|
|
72
|
+
if (!entry) return null;
|
|
73
|
+
const at = entry.localHeaderOffset;
|
|
74
|
+
if (at + 30 > buf.length || buf.readUInt32LE(at) !== LOC_SIG) throw new ZipError("corrupt local header");
|
|
75
|
+
const start = at + 30 + buf.readUInt16LE(at + 26) + buf.readUInt16LE(at + 28);
|
|
76
|
+
const end = start + entry.compressedSize;
|
|
77
|
+
if (end > buf.length) throw new ZipError("entry runs past the end of the archive");
|
|
78
|
+
const raw = buf.subarray(start, end);
|
|
79
|
+
if (entry.method === 0) {
|
|
80
|
+
if (raw.length > max) throw new ZipError(`${name} is larger than ${max} bytes`);
|
|
81
|
+
return Buffer.from(raw);
|
|
82
|
+
}
|
|
83
|
+
if (entry.method !== 8) throw new ZipError(`${name} uses compression method ${entry.method}`);
|
|
84
|
+
try {
|
|
85
|
+
return import_node_zlib.default.inflateRawSync(raw, { maxOutputLength: max });
|
|
86
|
+
} catch (err) {
|
|
87
|
+
if (err.code === "ERR_BUFFER_TOO_LARGE") {
|
|
88
|
+
throw new ZipError(`${name} inflates past ${max} bytes`);
|
|
89
|
+
}
|
|
90
|
+
throw new ZipError(`${name} could not be inflated`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
94
|
+
0 && (module.exports = {
|
|
95
|
+
ZipError,
|
|
96
|
+
listZipEntries,
|
|
97
|
+
readZipEntry
|
|
98
|
+
});
|