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,91 @@
|
|
|
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 desktop_exports = {};
|
|
29
|
+
__export(desktop_exports, {
|
|
30
|
+
DESKTOP_PLATFORMS: () => DESKTOP_PLATFORMS,
|
|
31
|
+
DesktopUsageError: () => DesktopUsageError,
|
|
32
|
+
desktop: () => desktop
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(desktop_exports);
|
|
35
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
36
|
+
var import_node_path = __toESM(require("node:path"));
|
|
37
|
+
var import_args = require("./args");
|
|
38
|
+
class DesktopUsageError extends Error {
|
|
39
|
+
}
|
|
40
|
+
const DESKTOP_PLATFORMS = ["darwin-arm64", "darwin-x64", "win32-x64", "win32-arm64", "linux-x64", "linux-arm64"];
|
|
41
|
+
async function desktop(p, deps) {
|
|
42
|
+
const sub = p.rest[0];
|
|
43
|
+
if (sub !== "install" && sub !== "url") {
|
|
44
|
+
throw new DesktopUsageError("desktop needs install or url: codetrellis desktop install [--version <v>] [--platform <p>] [--dir <d>] [--no-open]");
|
|
45
|
+
}
|
|
46
|
+
const platform = (0, import_args.flag)(p, "platform") ?? deps.platform;
|
|
47
|
+
if (!DESKTOP_PLATFORMS.includes(platform)) {
|
|
48
|
+
throw new DesktopUsageError(`--platform must be one of ${DESKTOP_PLATFORMS.join(", ")}${(0, import_args.flag)(p, "platform") ? "" : ` (this computer is ${platform})`}`);
|
|
49
|
+
}
|
|
50
|
+
const json = p.flags.json === true;
|
|
51
|
+
const release = await deps.findRelease(platform, (0, import_args.flag)(p, "version"));
|
|
52
|
+
const asset = release.download;
|
|
53
|
+
if (!asset) {
|
|
54
|
+
const says = `CodeTrellis ${release.version} has no installer for ${platform}.`;
|
|
55
|
+
return { out: json ? JSON.stringify({ version: release.version, platform, error: says }) : says, code: 1 };
|
|
56
|
+
}
|
|
57
|
+
if (sub === "url") {
|
|
58
|
+
return {
|
|
59
|
+
out: json ? JSON.stringify({ version: release.version, platform, filename: asset.filename, url: asset.url, size: asset.size ?? null }) : asset.url,
|
|
60
|
+
code: 0
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const dir = import_node_path.default.resolve((0, import_args.flag)(p, "dir") ?? deps.downloadsDir);
|
|
64
|
+
import_node_fs.default.mkdirSync(dir, { recursive: true });
|
|
65
|
+
const state = await deps.download(release.version, asset);
|
|
66
|
+
if (state.phase !== "ready") {
|
|
67
|
+
const says = `CodeTrellis ${release.version} was not downloaded: ${state.error ?? "the download did not finish"}`;
|
|
68
|
+
return { out: json ? JSON.stringify({ version: release.version, platform, error: says }) : says, code: 1 };
|
|
69
|
+
}
|
|
70
|
+
const saved = await deps.saveCopy(import_node_path.default.join(dir, import_node_path.default.basename(state.filename ?? asset.filename)));
|
|
71
|
+
const appImage = /\.AppImage$/i.test(saved);
|
|
72
|
+
if (appImage) import_node_fs.default.chmodSync(saved, 493);
|
|
73
|
+
const open = p.flags["no-open"] !== true && platform === deps.platform && !appImage;
|
|
74
|
+
if (open) deps.open(saved);
|
|
75
|
+
if (json) {
|
|
76
|
+
return { out: JSON.stringify({ version: release.version, platform, path: saved, sha256: state.sha256, opened: open }), code: 0 };
|
|
77
|
+
}
|
|
78
|
+
const lines = [
|
|
79
|
+
`Downloaded CodeTrellis ${release.version} for ${platform}, checked against the release's signed checksums:`,
|
|
80
|
+
` ${saved}`
|
|
81
|
+
];
|
|
82
|
+
if (open) lines.push(platform.startsWith("darwin") ? "Opened it: drag CodeTrellis to Applications." : "Opened the installer.");
|
|
83
|
+
else if (appImage && platform === deps.platform) lines.push(`Run it with: ${saved}`);
|
|
84
|
+
return { out: lines.join("\n"), code: 0 };
|
|
85
|
+
}
|
|
86
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
87
|
+
0 && (module.exports = {
|
|
88
|
+
DESKTOP_PLATFORMS,
|
|
89
|
+
DesktopUsageError,
|
|
90
|
+
desktop
|
|
91
|
+
});
|
package/src/cli/main.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
16
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
17
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
18
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
19
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
20
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
|
+
mod
|
|
22
|
+
));
|
|
23
|
+
var import_node_child_process = require("node:child_process");
|
|
24
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
25
|
+
var import_node_os = __toESM(require("node:os"));
|
|
26
|
+
var import_node_path = __toESM(require("node:path"));
|
|
27
|
+
var import_args = require("./args");
|
|
28
|
+
var import_verbs = require("./verbs");
|
|
29
|
+
var import_plan_verbs = require("./plan-verbs");
|
|
30
|
+
var import_package = require("../../package.json");
|
|
31
|
+
const out = (s) => process.stdout.write(s.endsWith("\n") ? s : `${s}
|
|
32
|
+
`);
|
|
33
|
+
const fail = (s, code = 2) => {
|
|
34
|
+
process.stderr.write(`codetrellis: ${s}
|
|
35
|
+
`);
|
|
36
|
+
process.exit(code);
|
|
37
|
+
};
|
|
38
|
+
async function shareTaskState(project) {
|
|
39
|
+
const { setSharedTaskState, startRecordWatcher } = await Promise.resolve().then(() => __toESM(require("../backend/services/task-records/shared-state")));
|
|
40
|
+
setSharedTaskState(project, true, "the command line (--share-task-state)");
|
|
41
|
+
await startRecordWatcher(project);
|
|
42
|
+
}
|
|
43
|
+
function backendLogToStderr() {
|
|
44
|
+
const toErr = (...args) => console.error(...args);
|
|
45
|
+
console.log = toErr;
|
|
46
|
+
console.info = toErr;
|
|
47
|
+
console.debug = toErr;
|
|
48
|
+
}
|
|
49
|
+
function projectOf(p) {
|
|
50
|
+
const dir = import_node_path.default.resolve((0, import_args.flag)(p, "project") ?? process.cwd());
|
|
51
|
+
let st;
|
|
52
|
+
try {
|
|
53
|
+
st = import_node_fs.default.statSync(dir);
|
|
54
|
+
} catch {
|
|
55
|
+
return fail(`no such folder: ${dir}`);
|
|
56
|
+
}
|
|
57
|
+
if (!st.isDirectory()) fail(`not a folder: ${dir}`);
|
|
58
|
+
return import_node_fs.default.realpathSync(dir);
|
|
59
|
+
}
|
|
60
|
+
function portOf(p, name) {
|
|
61
|
+
const v = (0, import_args.flag)(p, name);
|
|
62
|
+
if (v === void 0) return void 0;
|
|
63
|
+
const n = Number(v);
|
|
64
|
+
if (!Number.isInteger(n) || n < 0 || n > 65535) fail(`--${name} must be a port number`);
|
|
65
|
+
return String(n);
|
|
66
|
+
}
|
|
67
|
+
async function boot(p, project, dataDir) {
|
|
68
|
+
if (p.flags["share-task-state"]) {
|
|
69
|
+
const { defaultDataDir } = await Promise.resolve().then(() => __toESM(require("../backend/mcp/connector/files")));
|
|
70
|
+
if (import_node_path.default.resolve(dataDir) === import_node_path.default.resolve(defaultDataDir({}))) {
|
|
71
|
+
fail("--share-task-state is for a headless backend; in the app, turn it on in Settings \u2192 Shared task state.", 2);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
process.env.CODETRELLIS_DATA_DIR = dataDir;
|
|
75
|
+
process.env.CODETRELLIS_HEADLESS = "1";
|
|
76
|
+
const port = portOf(p, "port");
|
|
77
|
+
const mcpPort = portOf(p, "mcp-port");
|
|
78
|
+
if (port !== void 0) process.env.CODETRELLIS_BACKEND_PORT = port;
|
|
79
|
+
if (mcpPort !== void 0) process.env.CODETRELLIS_MCP_PORT = mcpPort;
|
|
80
|
+
import_node_fs.default.mkdirSync(dataDir, { recursive: true });
|
|
81
|
+
backendLogToStderr();
|
|
82
|
+
const { startServer, getBoundBackendPort } = await Promise.resolve().then(() => __toESM(require("../backend/server")));
|
|
83
|
+
const { installProcessHandlers } = await Promise.resolve().then(() => __toESM(require("../backend/lifecycle")));
|
|
84
|
+
const { getCapabilityToken } = await Promise.resolve().then(() => __toESM(require("../backend/services/capability-token")));
|
|
85
|
+
installProcessHandlers();
|
|
86
|
+
await startServer(void 0, "127.0.0.1");
|
|
87
|
+
const base = `http://127.0.0.1:${getBoundBackendPort()}`;
|
|
88
|
+
const res = await fetch(`${base}/api/project/scan`, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: { "Content-Type": "application/json", "x-codetrellis-token": getCapabilityToken() },
|
|
91
|
+
body: JSON.stringify({ projectPath: project })
|
|
92
|
+
});
|
|
93
|
+
const scan = await res.json().catch(() => ({}));
|
|
94
|
+
if (!res.ok) fail(`could not open ${project}: ${scan.error ?? res.status}`, 1);
|
|
95
|
+
if (p.flags["share-task-state"]) await shareTaskState(project);
|
|
96
|
+
const { readConnectTarget } = await Promise.resolve().then(() => __toESM(require("../backend/mcp/connector/files")));
|
|
97
|
+
const target = readConnectTarget(dataDir);
|
|
98
|
+
return { base, scan, mcp: target.ok ? target.url : null };
|
|
99
|
+
}
|
|
100
|
+
function counts(scan) {
|
|
101
|
+
const a = scan.astStats ?? {};
|
|
102
|
+
return {
|
|
103
|
+
files: scan.fileCount ?? 0,
|
|
104
|
+
parsed: a.fileCount ?? 0,
|
|
105
|
+
symbols: a.symbolCount ?? 0,
|
|
106
|
+
imports: a.importCount ?? 0,
|
|
107
|
+
resolvedImports: a.resolvedImports ?? 0
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
async function serve(p) {
|
|
111
|
+
const project = projectOf(p);
|
|
112
|
+
const dataDir = import_node_path.default.resolve((0, import_args.flag)(p, "data-dir") ?? (0, import_args.headlessDataDir)(project, process.env, import_node_os.default.homedir()));
|
|
113
|
+
const { base, scan, mcp: mcp2 } = await boot(p, project, dataDir);
|
|
114
|
+
const line = (0, import_args.connectorLine)(process.execPath, binPath(), dataDir);
|
|
115
|
+
const c = counts(scan);
|
|
116
|
+
markReady(dataDir, project);
|
|
117
|
+
if (p.flags.json) {
|
|
118
|
+
out(JSON.stringify({ project, dataDir, api: base, mcp: mcp2, connector: { command: line.command, args: line.args }, counts: c }));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
out([
|
|
122
|
+
`CodeTrellis is serving ${project}`,
|
|
123
|
+
` headless, on loopback only; every request needs the token in ${import_node_path.default.join(dataDir, "capability-token")}`,
|
|
124
|
+
` ${c.files} files, ${c.symbols} symbols, ${c.resolvedImports} of ${c.imports} imports resolved`,
|
|
125
|
+
` data: ${dataDir}`,
|
|
126
|
+
"",
|
|
127
|
+
"Connect an agent (the token is read on every connect, so this survives a restart):",
|
|
128
|
+
` ${line.claude}`,
|
|
129
|
+
` ${line.json}`,
|
|
130
|
+
"",
|
|
131
|
+
"Stop with Ctrl-C."
|
|
132
|
+
].join("\n"));
|
|
133
|
+
}
|
|
134
|
+
async function scanOnce(p) {
|
|
135
|
+
const project = projectOf(p);
|
|
136
|
+
const dataDir = import_node_path.default.resolve((0, import_args.flag)(p, "data-dir") ?? (0, import_args.headlessDataDir)(project, process.env, import_node_os.default.homedir()));
|
|
137
|
+
const { scan } = await boot(p, project, dataDir);
|
|
138
|
+
const c = counts(scan);
|
|
139
|
+
if (p.flags.json) out(JSON.stringify({ project, ...c }));
|
|
140
|
+
else out(`${project}: ${c.files} files (${c.parsed} parsed), ${c.symbols} symbols, ${c.resolvedImports} of ${c.imports} imports resolved`);
|
|
141
|
+
const { gracefulShutdown } = await Promise.resolve().then(() => __toESM(require("../backend/lifecycle")));
|
|
142
|
+
await gracefulShutdown("scan finished");
|
|
143
|
+
}
|
|
144
|
+
async function mcp(p) {
|
|
145
|
+
if (!(0, import_args.flag)(p, "data-dir")) {
|
|
146
|
+
const here = (0, import_args.headlessDataDir)(process.cwd(), process.env, import_node_os.default.homedir());
|
|
147
|
+
if (import_node_fs.default.existsSync(import_node_path.default.join(here, "mcp-endpoint.json"))) process.argv.push("--data-dir", here);
|
|
148
|
+
}
|
|
149
|
+
await Promise.resolve().then(() => __toESM(require("../backend/mcp/connector/main")));
|
|
150
|
+
}
|
|
151
|
+
const READY_FILE = "serve-ready.json";
|
|
152
|
+
function markReady(dataDir, project) {
|
|
153
|
+
const file = import_node_path.default.join(dataDir, READY_FILE);
|
|
154
|
+
import_node_fs.default.writeFileSync(file, JSON.stringify({ pid: process.pid, project }), { mode: 384 });
|
|
155
|
+
process.on("exit", () => {
|
|
156
|
+
try {
|
|
157
|
+
if (JSON.parse(import_node_fs.default.readFileSync(file, "utf8")).pid === process.pid) import_node_fs.default.unlinkSync(file);
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async function runningIn(dataDir) {
|
|
163
|
+
const { readConnectTarget, readEndpoint } = await Promise.resolve().then(() => __toESM(require("../backend/mcp/connector/files")));
|
|
164
|
+
const endpoint = readEndpoint(dataDir);
|
|
165
|
+
const target = readConnectTarget(dataDir);
|
|
166
|
+
if (!endpoint || !target.ok) return null;
|
|
167
|
+
try {
|
|
168
|
+
process.kill(endpoint.pid, 0);
|
|
169
|
+
} catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
if (JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(dataDir, READY_FILE), "utf8")).pid !== endpoint.pid) return null;
|
|
174
|
+
} catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
return { pid: endpoint.pid, url: target.url };
|
|
178
|
+
}
|
|
179
|
+
async function start(p) {
|
|
180
|
+
const project = projectOf(p);
|
|
181
|
+
const dataDir = import_node_path.default.resolve((0, import_args.flag)(p, "data-dir") ?? (0, import_args.headlessDataDir)(project, process.env, import_node_os.default.homedir()));
|
|
182
|
+
const line = (0, import_args.connectorLine)(process.execPath, binPath(), dataDir);
|
|
183
|
+
const say = (state, pid) => {
|
|
184
|
+
if (p.flags.quiet) return;
|
|
185
|
+
if (p.flags.json) out(JSON.stringify({ state, pid, project, dataDir, connector: { command: line.command, args: line.args } }));
|
|
186
|
+
else out(`CodeTrellis ${state === "running" ? "is already running" : "started"} for ${project} (pid ${pid}).
|
|
187
|
+
Connect an agent with:
|
|
188
|
+
${line.claude}`);
|
|
189
|
+
};
|
|
190
|
+
const up = await runningIn(dataDir);
|
|
191
|
+
if (up) return say("running", up.pid);
|
|
192
|
+
import_node_fs.default.mkdirSync(dataDir, { recursive: true });
|
|
193
|
+
const log = import_node_fs.default.openSync(import_node_path.default.join(dataDir, "serve.log"), "a");
|
|
194
|
+
const args = [binPath(), "serve", "--project", project, "--data-dir", dataDir];
|
|
195
|
+
for (const k of ["port", "mcp-port"]) {
|
|
196
|
+
const v = portOf(p, k);
|
|
197
|
+
if (v !== void 0) args.push(`--${k}`, v);
|
|
198
|
+
}
|
|
199
|
+
if (p.flags["share-task-state"]) args.push("--share-task-state");
|
|
200
|
+
const child = (0, import_node_child_process.spawn)(process.execPath, args, { detached: true, stdio: ["ignore", log, log], cwd: project, env: process.env });
|
|
201
|
+
child.unref();
|
|
202
|
+
import_node_fs.default.closeSync(log);
|
|
203
|
+
let exited = null;
|
|
204
|
+
child.on("exit", (code) => {
|
|
205
|
+
exited = code ?? 1;
|
|
206
|
+
});
|
|
207
|
+
const limit = Number((0, import_args.flag)(p, "timeout") ?? 120) * 1e3;
|
|
208
|
+
const until = Date.now() + (Number.isFinite(limit) && limit > 0 ? limit : 12e4);
|
|
209
|
+
while (Date.now() < until) {
|
|
210
|
+
const now = await runningIn(dataDir);
|
|
211
|
+
if (now) return say("started", now.pid);
|
|
212
|
+
if (exited !== null) fail(`codetrellis serve stopped (exit ${exited}); see ${import_node_path.default.join(dataDir, "serve.log")}`, 1);
|
|
213
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
214
|
+
}
|
|
215
|
+
fail(`codetrellis serve did not come up in time; see ${import_node_path.default.join(dataDir, "serve.log")}`, 1);
|
|
216
|
+
}
|
|
217
|
+
async function stop(p) {
|
|
218
|
+
const project = projectOf(p);
|
|
219
|
+
const dataDir = import_node_path.default.resolve((0, import_args.flag)(p, "data-dir") ?? (0, import_args.headlessDataDir)(project, process.env, import_node_os.default.homedir()));
|
|
220
|
+
const up = await runningIn(dataDir);
|
|
221
|
+
if (!up) {
|
|
222
|
+
out(`CodeTrellis is not running for ${project}.`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
process.kill(up.pid, "SIGTERM");
|
|
226
|
+
const until = Date.now() + 15e3;
|
|
227
|
+
while (Date.now() < until) {
|
|
228
|
+
try {
|
|
229
|
+
process.kill(up.pid, 0);
|
|
230
|
+
} catch {
|
|
231
|
+
out(`Stopped CodeTrellis for ${project}.`);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
235
|
+
}
|
|
236
|
+
fail(`CodeTrellis (pid ${up.pid}) did not stop within 15 s`, 1);
|
|
237
|
+
}
|
|
238
|
+
async function verb(name, p) {
|
|
239
|
+
const { agentName, connectAgent, dataDirFor, NotRunningError } = await Promise.resolve().then(() => __toESM(require("./agent")));
|
|
240
|
+
const { runVerb, UsageError } = await Promise.resolve().then(() => __toESM(require("./verbs")));
|
|
241
|
+
const cwd = process.cwd();
|
|
242
|
+
let agent;
|
|
243
|
+
try {
|
|
244
|
+
agent = await connectAgent({ dataDir: dataDirFor((0, import_args.flag)(p, "data-dir"), cwd, process.env), name: agentName((0, import_args.flag)(p, "as"), process.env), cwd });
|
|
245
|
+
} catch (err) {
|
|
246
|
+
if (err instanceof NotRunningError) fail(err.message, 1);
|
|
247
|
+
throw err;
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const { runPlanVerb } = await Promise.resolve().then(() => __toESM(require("./plan-verbs")));
|
|
251
|
+
const { out: text, code } = import_plan_verbs.PLAN_VERBS.has(name) ? await runPlanVerb(name, agent, p, cwd) : await runVerb(name, agent, p, cwd);
|
|
252
|
+
if (text) out(text);
|
|
253
|
+
process.exitCode = code;
|
|
254
|
+
} catch (err) {
|
|
255
|
+
if (err instanceof UsageError) {
|
|
256
|
+
process.stderr.write(`codetrellis: ${err.message}
|
|
257
|
+
`);
|
|
258
|
+
process.exitCode = 2;
|
|
259
|
+
} else throw err;
|
|
260
|
+
} finally {
|
|
261
|
+
await agent.close();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function reviewCmd(p) {
|
|
265
|
+
if (p.rest[0] === "verify" || p.rest[0] === "publish") {
|
|
266
|
+
const { verifyCmd, publishCmd, VerifyUsageError } = await Promise.resolve().then(() => __toESM(require("./review-verify")));
|
|
267
|
+
try {
|
|
268
|
+
const r = p.rest[0] === "verify" ? verifyCmd(p, process.cwd(), process.env, import_package.version) : publishCmd(p, process.cwd());
|
|
269
|
+
out(r.out);
|
|
270
|
+
process.exitCode = r.code;
|
|
271
|
+
} catch (err) {
|
|
272
|
+
if (err instanceof VerifyUsageError) fail(err.message);
|
|
273
|
+
throw err;
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const { agentName, connectAgent, dataDirFor, NotRunningError } = await Promise.resolve().then(() => __toESM(require("./agent")));
|
|
278
|
+
const { review, reviewOptions, ReviewUsageError } = await Promise.resolve().then(() => __toESM(require("./review")));
|
|
279
|
+
const cwd = process.cwd();
|
|
280
|
+
let opts;
|
|
281
|
+
try {
|
|
282
|
+
opts = reviewOptions(p, cwd, process.env);
|
|
283
|
+
} catch (err) {
|
|
284
|
+
if (err instanceof ReviewUsageError) fail(err.message);
|
|
285
|
+
throw err;
|
|
286
|
+
}
|
|
287
|
+
let agent;
|
|
288
|
+
try {
|
|
289
|
+
agent = await connectAgent({ dataDir: dataDirFor((0, import_args.flag)(p, "data-dir"), cwd, process.env), name: agentName((0, import_args.flag)(p, "as"), process.env), cwd });
|
|
290
|
+
} catch (err) {
|
|
291
|
+
if (err instanceof NotRunningError) fail(err.message, 1);
|
|
292
|
+
throw err;
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
const sinkFor = (dir) => ({ command: process.execPath, args: [binPath(), "review-sink", "--pass", dir] });
|
|
296
|
+
const post = opts.post ? await reviewPoster(opts.post, cwd) : void 0;
|
|
297
|
+
const { out: text, code, note } = await review(agent, opts, cwd, process.env, sinkFor, { post, version: import_package.version });
|
|
298
|
+
out(text);
|
|
299
|
+
if (note) process.stderr.write(`codetrellis review: ${note}
|
|
300
|
+
`);
|
|
301
|
+
process.exitCode = code;
|
|
302
|
+
} finally {
|
|
303
|
+
await agent.close();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function reviewPoster(post, cwd) {
|
|
307
|
+
const { detectProjectHost } = await Promise.resolve().then(() => __toESM(require("../backend/services/review-host/detect")));
|
|
308
|
+
const { DEFAULT_TOKEN, postComment, pullNumber } = await Promise.resolve().then(() => __toESM(require("./review-post")));
|
|
309
|
+
const host = detectProjectHost(cwd);
|
|
310
|
+
const pr = post.pr ?? pullNumber(process.env);
|
|
311
|
+
return async (markdown) => {
|
|
312
|
+
if (!host?.kind) return { ok: false, says: "origin is not on GitHub, GitLab or Bitbucket; the review was not posted" };
|
|
313
|
+
if (!pr) return { ok: false, says: "no pull request to post to (not a pull request job; --pr names one)" };
|
|
314
|
+
const tokenVar = post.tokenVar ?? DEFAULT_TOKEN[host.kind];
|
|
315
|
+
const token = process.env[tokenVar];
|
|
316
|
+
if (!token) return { ok: false, says: `${tokenVar} is not set; the review was not posted` };
|
|
317
|
+
return postComment(host, pr, token, markdown);
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async function reviewSink(p) {
|
|
321
|
+
const dir = (0, import_args.flag)(p, "pass");
|
|
322
|
+
if (!dir) fail("review-sink needs --pass <dir>");
|
|
323
|
+
backendLogToStderr();
|
|
324
|
+
const { runReviewSink } = await Promise.resolve().then(() => __toESM(require("./review-sink")));
|
|
325
|
+
await runReviewSink(dir);
|
|
326
|
+
}
|
|
327
|
+
async function desktopCmd(p) {
|
|
328
|
+
const { desktop, DesktopUsageError } = await Promise.resolve().then(() => __toESM(require("./desktop")));
|
|
329
|
+
const work = import_node_fs.default.mkdtempSync(import_node_path.default.join(import_node_os.default.tmpdir(), "codetrellis-desktop-"));
|
|
330
|
+
process.env.CODETRELLIS_DATA_DIR = work;
|
|
331
|
+
const { findDesktopRelease, detectPlatform } = await Promise.resolve().then(() => __toESM(require("../backend/services/update-service")));
|
|
332
|
+
const { startUpdateDownload, saveVerifiedUpdateCopy, getUpdateDownloadState } = await Promise.resolve().then(() => __toESM(require("../backend/services/update-download-service")));
|
|
333
|
+
const downloads = import_node_path.default.join(import_node_os.default.homedir(), "Downloads");
|
|
334
|
+
const tty = process.stderr.isTTY && p.flags.json !== true;
|
|
335
|
+
let ticker;
|
|
336
|
+
let error;
|
|
337
|
+
try {
|
|
338
|
+
const r = await desktop(p, {
|
|
339
|
+
platform: detectPlatform(),
|
|
340
|
+
findRelease: findDesktopRelease,
|
|
341
|
+
download: (version, info) => {
|
|
342
|
+
if (tty) {
|
|
343
|
+
ticker = setInterval(() => {
|
|
344
|
+
const s = getUpdateDownloadState();
|
|
345
|
+
const pct = s.totalBytes ? Math.floor(s.bytesDownloaded / s.totalBytes * 100) : null;
|
|
346
|
+
process.stderr.write(`\r${s.phase === "preparing" ? "Checking the signed checksums\u2026" : `Downloading ${s.filename ?? ""} ${pct === null ? "" : `${pct}%`}`} `);
|
|
347
|
+
}, 500);
|
|
348
|
+
}
|
|
349
|
+
return startUpdateDownload(version, info).finally(() => {
|
|
350
|
+
if (ticker) {
|
|
351
|
+
clearInterval(ticker);
|
|
352
|
+
process.stderr.write("\r\x1B[K");
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
},
|
|
356
|
+
saveCopy: saveVerifiedUpdateCopy,
|
|
357
|
+
// A DMG mounts; a Windows installer is itself the program to start.
|
|
358
|
+
open: (file) => {
|
|
359
|
+
const child = process.platform === "darwin" ? (0, import_node_child_process.spawn)("open", [file], { detached: true, stdio: "ignore" }) : process.platform === "win32" ? (0, import_node_child_process.spawn)(file, [], { detached: true, stdio: "ignore" }) : (0, import_node_child_process.spawn)("xdg-open", [file], { detached: true, stdio: "ignore" });
|
|
360
|
+
child.unref();
|
|
361
|
+
},
|
|
362
|
+
downloadsDir: import_node_fs.default.existsSync(downloads) ? downloads : process.cwd()
|
|
363
|
+
});
|
|
364
|
+
out(r.out);
|
|
365
|
+
process.exitCode = r.code;
|
|
366
|
+
} catch (err) {
|
|
367
|
+
error = err;
|
|
368
|
+
} finally {
|
|
369
|
+
import_node_fs.default.rmSync(work, { recursive: true, force: true });
|
|
370
|
+
}
|
|
371
|
+
if (error instanceof DesktopUsageError) fail(error.message);
|
|
372
|
+
if (error) fail(error instanceof Error ? error.message : String(error), 1);
|
|
373
|
+
}
|
|
374
|
+
function binPath() {
|
|
375
|
+
return import_node_path.default.resolve(__dirname, "..", "..", "bin", "codetrellis.mjs");
|
|
376
|
+
}
|
|
377
|
+
async function main() {
|
|
378
|
+
const p = (0, import_args.parseArgs)(process.argv.slice(2));
|
|
379
|
+
if (p.flags.version === true && !p.command) {
|
|
380
|
+
out(import_package.version);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (p.flags.help || !p.command || p.command === "help") {
|
|
384
|
+
out(import_args.USAGE);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
switch (p.command) {
|
|
388
|
+
case "serve":
|
|
389
|
+
return serve(p);
|
|
390
|
+
case "scan":
|
|
391
|
+
return scanOnce(p);
|
|
392
|
+
case "mcp":
|
|
393
|
+
return mcp(p);
|
|
394
|
+
case "start":
|
|
395
|
+
return start(p);
|
|
396
|
+
case "stop":
|
|
397
|
+
return stop(p);
|
|
398
|
+
case "review":
|
|
399
|
+
return reviewCmd(p);
|
|
400
|
+
case "review-sink":
|
|
401
|
+
return reviewSink(p);
|
|
402
|
+
case "desktop":
|
|
403
|
+
return desktopCmd(p);
|
|
404
|
+
default:
|
|
405
|
+
if (import_verbs.VERBS.has(p.command) || import_plan_verbs.PLAN_VERBS.has(p.command)) return verb(p.command, p);
|
|
406
|
+
fail(`unknown command "${p.command}". Run codetrellis --help.`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
main().catch((err) => fail(err instanceof Error ? err.message : String(err), 1));
|
|
@@ -0,0 +1,109 @@
|
|
|
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 pipeline_exports = {};
|
|
19
|
+
__export(pipeline_exports, {
|
|
20
|
+
pipelineWords: () => pipelineWords,
|
|
21
|
+
runPipeline: () => runPipeline
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(pipeline_exports);
|
|
24
|
+
var import_pipeline = require("../backend/services/pipeline");
|
|
25
|
+
var import_check_words = require("../shared/lib/check-words");
|
|
26
|
+
const agentOnly = (s) => !!s.rules.engine && s.rules.engine.every((e) => e === "agent");
|
|
27
|
+
const wantsReview = (s) => !!s.rules.engine?.includes("agent");
|
|
28
|
+
function gateFindings(stage, g) {
|
|
29
|
+
return g.rules.map((r) => ({
|
|
30
|
+
stage,
|
|
31
|
+
path: r.path,
|
|
32
|
+
says: `${r.path} ${(0, import_check_words.reachWords)(r.imports)}, which ${r.words ?? r.rule} forbids`,
|
|
33
|
+
rule: r.rule,
|
|
34
|
+
...r.strength ? { strength: r.strength } : {}
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
async function runPipeline(p, run, only) {
|
|
38
|
+
const notes = [];
|
|
39
|
+
const results = /* @__PURE__ */ new Map();
|
|
40
|
+
let first = true;
|
|
41
|
+
const chosen = only ? p.stages.filter((s) => s.id === only) : null;
|
|
42
|
+
if (only && !chosen.length) return { ok: false, stages: [], notes: [`The pipeline has no stage ${only}: its stages are ${p.stages.map((s) => s.id).join(", ")}.`] };
|
|
43
|
+
const one = async (s, judgesPipeline) => {
|
|
44
|
+
const base = { id: s.id, words: (0, import_pipeline.stageWords)(s), advisory: !!s.advisory, findings: [] };
|
|
45
|
+
if (s.when && !only) {
|
|
46
|
+
const unmet = Object.entries(s.when).filter(([id, want]) => {
|
|
47
|
+
const r = results.get(id);
|
|
48
|
+
return !r || !r.ran || (want === "passed" ? !r.ok : r.ok);
|
|
49
|
+
});
|
|
50
|
+
if (unmet.length) return { ...base, ran: false, ok: true, skipped: `it runs when ${unmet.map(([id, want]) => `${id} ${want}`).join(" and ")}, and ${unmet.length === 1 ? "that" : "those"} did not happen` };
|
|
51
|
+
}
|
|
52
|
+
const scope = { ...(0, import_pipeline.stageScope)(s), stage: s.id };
|
|
53
|
+
let ok = true;
|
|
54
|
+
const out = { ...base, ran: true, ok: true };
|
|
55
|
+
if (!agentOnly(s) || judgesPipeline) {
|
|
56
|
+
const g = await run.gate({ ...scope, ...judgesPipeline ? { pipeline: true } : {} });
|
|
57
|
+
out.gate = g;
|
|
58
|
+
if ("error" in g) ok = false;
|
|
59
|
+
else {
|
|
60
|
+
ok = g.ok;
|
|
61
|
+
out.findings.push(...gateFindings(s.id, g));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (wantsReview(s)) {
|
|
65
|
+
if (!run.review) {
|
|
66
|
+
if (agentOnly(s) && !judgesPipeline) return { ...base, ran: false, ok: true, skipped: "no reviewer was given (--agent), so its agent rules are guides" };
|
|
67
|
+
notes.push(`The stage ${s.id}'s agent rules were not reviewed: no reviewer was given (--agent).`);
|
|
68
|
+
} else {
|
|
69
|
+
const grounding = only ? [] : (s.grounding ?? []).flatMap((id) => results.get(id)?.findings ?? []);
|
|
70
|
+
const r = await run.review(s, { ...scope, engine: "agent" }, grounding);
|
|
71
|
+
out.review = r;
|
|
72
|
+
if ("error" in r) ok = false;
|
|
73
|
+
else {
|
|
74
|
+
ok = ok && r.ok;
|
|
75
|
+
out.findings.push(...r.findings);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
out.ok = ok;
|
|
80
|
+
return out;
|
|
81
|
+
};
|
|
82
|
+
for (const wave of (0, import_pipeline.waves)(p)) {
|
|
83
|
+
const stages2 = chosen ? wave.filter((s) => chosen.includes(s)) : wave;
|
|
84
|
+
if (!stages2.length) continue;
|
|
85
|
+
const done = await Promise.all(stages2.map((s, i) => one(s, first && i === 0)));
|
|
86
|
+
first = false;
|
|
87
|
+
for (const r of done) results.set(r.id, r);
|
|
88
|
+
}
|
|
89
|
+
const stages = [...results.values()];
|
|
90
|
+
return { ok: stages.every((s) => s.ok || s.advisory), stages, notes };
|
|
91
|
+
}
|
|
92
|
+
function pipelineWords(r, render) {
|
|
93
|
+
const lines = [];
|
|
94
|
+
for (const s of r.stages) {
|
|
95
|
+
const mark = !s.ran ? "\xB7" : s.ok ? "\u2713" : s.advisory ? "\u26A0" : "\u2717";
|
|
96
|
+
lines.push(`${mark} stage ${s.words}${s.skipped ? ` \u2014 skipped: ${s.skipped}` : ""}`);
|
|
97
|
+
if (s.gate) lines.push("error" in s.gate ? ` ${s.gate.error}` : render(s.gate).split("\n").map((l) => l ? ` ${l}` : l).join("\n"));
|
|
98
|
+
if (s.review) lines.push("error" in s.review ? ` review: ${s.review.error}` : s.review.out.split("\n").map((l) => l ? ` ${l}` : l).join("\n"));
|
|
99
|
+
}
|
|
100
|
+
for (const n of r.notes) lines.push(`\u26A0 ${n}`);
|
|
101
|
+
const failing = r.stages.filter((s) => !s.ok && !s.advisory).map((s) => s.id);
|
|
102
|
+
lines.push(r.ok ? `\u2713 The pipeline passes (${r.stages.filter((s) => s.ran).length} of ${r.stages.length} stages ran).` : `\u2717 The pipeline fails: ${failing.join(", ")}.`);
|
|
103
|
+
return lines.join("\n");
|
|
104
|
+
}
|
|
105
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
106
|
+
0 && (module.exports = {
|
|
107
|
+
pipelineWords,
|
|
108
|
+
runPipeline
|
|
109
|
+
});
|