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,114 @@
|
|
|
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 signoff_rows_exports = {};
|
|
19
|
+
__export(signoff_rows_exports, {
|
|
20
|
+
criteriaWarnings: () => criteriaWarnings,
|
|
21
|
+
renderCriteriaTable: () => renderCriteriaTable,
|
|
22
|
+
rowsForCriterion: () => rowsForCriterion,
|
|
23
|
+
signoffRows: () => signoffRows
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(signoff_rows_exports);
|
|
26
|
+
var import_plan_item_service = require("./plan-item-service");
|
|
27
|
+
var import_criteria_service = require("./criteria-service");
|
|
28
|
+
var import_artefact_service = require("./artefact-service");
|
|
29
|
+
var import_locator = require("../../shared/lib/locator");
|
|
30
|
+
var import_references = require("../../shared/lib/references");
|
|
31
|
+
var import_signoff = require("../../shared/lib/signoff");
|
|
32
|
+
function refOf(item) {
|
|
33
|
+
return (0, import_references.formatReference)(item.kind === "object" ? "page" : "task", item.uid);
|
|
34
|
+
}
|
|
35
|
+
function rowsForCriterion(item, c) {
|
|
36
|
+
const evidence = c.latestSubmission.map((e) => {
|
|
37
|
+
const artefact = e.attachmentUid ? (0, import_artefact_service.getArtefact)(e.attachmentUid) : null;
|
|
38
|
+
return {
|
|
39
|
+
path: artefact?.path ?? null,
|
|
40
|
+
locator: e.locator,
|
|
41
|
+
where: (0, import_locator.describeLocator)(e.locator),
|
|
42
|
+
sha256AtSubmit: e.sha256AtSubmit,
|
|
43
|
+
sha256Now: artefact?.sha256 ?? null,
|
|
44
|
+
attachmentUid: e.attachmentUid
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
const s = c.latestSignoff;
|
|
48
|
+
const recorded = s?.evidenceHashes ?? {};
|
|
49
|
+
const changedFiles = c.state === "stale" ? Object.keys(recorded).filter((uid) => ((0, import_artefact_service.getArtefact)(uid)?.sha256 ?? null) !== recorded[uid]).map((uid) => (0, import_artefact_service.getArtefact)(uid)?.path ?? uid) : [];
|
|
50
|
+
return {
|
|
51
|
+
itemUid: item.uid,
|
|
52
|
+
itemTitle: item.title,
|
|
53
|
+
itemRef: refOf(item),
|
|
54
|
+
criterionUid: c.uid,
|
|
55
|
+
text: c.text,
|
|
56
|
+
kind: c.kind,
|
|
57
|
+
policy: c.policy,
|
|
58
|
+
state: c.state,
|
|
59
|
+
evidence,
|
|
60
|
+
submissionNote: c.latestSubmission.find((e) => e.note)?.note ?? null,
|
|
61
|
+
submittedBy: c.latestSubmission[0]?.submittedBy ?? null,
|
|
62
|
+
decision: s ? {
|
|
63
|
+
decision: s.decision,
|
|
64
|
+
actor: s.actor,
|
|
65
|
+
actorType: s.actorType,
|
|
66
|
+
channel: s.channel,
|
|
67
|
+
note: s.note,
|
|
68
|
+
at: s.createdAt,
|
|
69
|
+
evidenceHashes: recorded,
|
|
70
|
+
device: s.device ?? null
|
|
71
|
+
} : null,
|
|
72
|
+
selfApproved: !!s && s.decision === "approved" && s.actorType !== "human" && s.actorType !== "unverified",
|
|
73
|
+
unverified: !!s && s.actorType === "unverified",
|
|
74
|
+
changedFiles
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function signoffRows(planUid) {
|
|
78
|
+
return (0, import_plan_item_service.listAllItems)(planUid).flatMap((item) => (0, import_criteria_service.listCriteria)(item.uid).map((c) => rowsForCriterion(item, c)));
|
|
79
|
+
}
|
|
80
|
+
function cell(text) {
|
|
81
|
+
return text.replace(/\r?\n+/g, " ").replace(/\|/g, "\\|").replace(/`/g, "'").trim() || "\u2014";
|
|
82
|
+
}
|
|
83
|
+
function renderCriteriaTable(rows) {
|
|
84
|
+
if (rows.length === 0) return "";
|
|
85
|
+
const lines = [
|
|
86
|
+
"## Acceptance criteria",
|
|
87
|
+
"",
|
|
88
|
+
"| Task | Criterion | State | Evidence | Signed |",
|
|
89
|
+
"|---|---|---|---|---|",
|
|
90
|
+
...rows.map((r) => `| ${cell(r.itemTitle)} | ${cell(r.text)} | ${cell((0, import_signoff.stateWords)(r))} | ${cell((0, import_signoff.evidenceWords)(r))} | ${cell((0, import_signoff.decisionWords)(r))} |`)
|
|
91
|
+
];
|
|
92
|
+
const self = rows.filter((r) => r.selfApproved);
|
|
93
|
+
if (self.length > 0) {
|
|
94
|
+
lines.push("", `_${self.length} of these ${self.length === 1 ? "was" : "were"} approved by the agent's own checks (agent policy), not by a person._`);
|
|
95
|
+
}
|
|
96
|
+
const unverified = rows.filter((r) => r.unverified && r.decision?.decision === "approved");
|
|
97
|
+
if (unverified.length > 0) {
|
|
98
|
+
lines.push("", `_${unverified.length} of these ${unverified.length === 1 ? "was" : "were"} approved through the local API, not from the CodeTrellis app or a paired phone, so it is not verified that a person approved ${unverified.length === 1 ? "it" : "them"}._`);
|
|
99
|
+
}
|
|
100
|
+
return lines.join("\n");
|
|
101
|
+
}
|
|
102
|
+
function criteriaWarnings(rows) {
|
|
103
|
+
return rows.filter((r) => r.state !== "met").map((r) => {
|
|
104
|
+
const why = r.state === "stale" && r.changedFiles.length ? `changed since approved (${r.changedFiles.join(", ")})` : (0, import_signoff.stateWords)(r);
|
|
105
|
+
return `"${r.text}" on ${r.itemTitle} is ${why}.`;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
109
|
+
0 && (module.exports = {
|
|
110
|
+
criteriaWarnings,
|
|
111
|
+
renderCriteriaTable,
|
|
112
|
+
rowsForCriterion,
|
|
113
|
+
signoffRows
|
|
114
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
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 skill_arrival_service_exports = {};
|
|
29
|
+
__export(skill_arrival_service_exports, {
|
|
30
|
+
acceptArrival: () => acceptArrival,
|
|
31
|
+
lastCommitOf: () => lastCommitOf,
|
|
32
|
+
noteArrivals: () => noteArrivals,
|
|
33
|
+
pendingArrivals: () => pendingArrivals,
|
|
34
|
+
planArrivals: () => planArrivals
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(skill_arrival_service_exports);
|
|
37
|
+
var import_node_path = __toESM(require("node:path"));
|
|
38
|
+
var import_node_child_process = require("node:child_process");
|
|
39
|
+
var import_database = require("./database");
|
|
40
|
+
function rowsOf(sql, params = []) {
|
|
41
|
+
const res = (0, import_database.getDb)().exec(sql, params);
|
|
42
|
+
if (!res.length) return [];
|
|
43
|
+
const { columns, values } = res[0];
|
|
44
|
+
return values.map((v) => Object.fromEntries(columns.map((c, i) => [c, v[i]])));
|
|
45
|
+
}
|
|
46
|
+
const wanted = (s) => s.required || s.use === "recommended";
|
|
47
|
+
function lastCommitOf(file) {
|
|
48
|
+
const run = (args) => (0, import_node_child_process.execFileSync)("git", ["-C", import_node_path.default.dirname(file), ...args], {
|
|
49
|
+
encoding: "utf-8",
|
|
50
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
51
|
+
timeout: 5e3
|
|
52
|
+
}).trim();
|
|
53
|
+
try {
|
|
54
|
+
const name = import_node_path.default.basename(file);
|
|
55
|
+
if (run(["status", "--porcelain", "--", name])) return { addedBy: null, commit: null };
|
|
56
|
+
const [addedBy, commit] = run(["log", "-1", "--format=%an%x1f%h", "--", name]).split("");
|
|
57
|
+
return commit ? { addedBy: addedBy || null, commit } : { addedBy: null, commit: null };
|
|
58
|
+
} catch {
|
|
59
|
+
return { addedBy: null, commit: null };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function noteArrivals(input) {
|
|
63
|
+
completeArrivals(input.itemUid, input.file);
|
|
64
|
+
const had = new Set(input.before.filter(wanted).map((s) => s.name));
|
|
65
|
+
const arrived = input.after.filter((s) => wanted(s) && !had.has(s.name)).map((s) => s.name);
|
|
66
|
+
if (arrived.length === 0) return [];
|
|
67
|
+
const pending = pendingArrivals(input.itemUid);
|
|
68
|
+
const fresh = arrived.filter((n) => !pending.has(n));
|
|
69
|
+
if (fresh.length === 0) return [];
|
|
70
|
+
const { addedBy, commit } = lastCommitOf(input.file);
|
|
71
|
+
const at = input.now ?? Date.now();
|
|
72
|
+
try {
|
|
73
|
+
for (const skill of fresh) {
|
|
74
|
+
(0, import_database.getDb)().run(
|
|
75
|
+
"INSERT INTO skill_arrivals (item_uid, skill, added_by, commit_sha, arrived_at) VALUES (?, ?, ?, ?, ?)",
|
|
76
|
+
[input.itemUid, skill, addedBy, commit, at]
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
return fresh;
|
|
83
|
+
}
|
|
84
|
+
function completeArrivals(itemUid, file) {
|
|
85
|
+
if (![...pendingArrivals(itemUid).values()].some((a) => !a.commit)) return;
|
|
86
|
+
const { addedBy, commit } = lastCommitOf(file);
|
|
87
|
+
if (!commit) return;
|
|
88
|
+
(0, import_database.getDb)().run(
|
|
89
|
+
"UPDATE skill_arrivals SET added_by = ?, commit_sha = ? WHERE item_uid = ? AND accepted_at IS NULL AND commit_sha IS NULL",
|
|
90
|
+
[addedBy, commit, itemUid]
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function pendingArrivals(itemUid) {
|
|
94
|
+
try {
|
|
95
|
+
const rows = rowsOf(
|
|
96
|
+
"SELECT skill, added_by, commit_sha, arrived_at FROM skill_arrivals WHERE item_uid = ? AND accepted_at IS NULL ORDER BY arrived_at",
|
|
97
|
+
[itemUid]
|
|
98
|
+
);
|
|
99
|
+
return new Map(rows.map((r) => [r.skill, { itemUid, skill: r.skill, addedBy: r.added_by, commit: r.commit_sha, arrivedAt: Number(r.arrived_at) }]));
|
|
100
|
+
} catch {
|
|
101
|
+
return /* @__PURE__ */ new Map();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function planArrivals(planUid) {
|
|
105
|
+
try {
|
|
106
|
+
const rows = rowsOf(
|
|
107
|
+
`SELECT a.item_uid, i.title, i.skills, a.skill, a.added_by, a.commit_sha, a.arrived_at
|
|
108
|
+
FROM skill_arrivals a JOIN plan_items i ON i.uid = a.item_uid
|
|
109
|
+
WHERE i.plan_uid = ? AND a.accepted_at IS NULL ORDER BY a.arrived_at`,
|
|
110
|
+
[planUid]
|
|
111
|
+
);
|
|
112
|
+
return rows.filter((r) => {
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(r.skills ?? "[]").some((s) => s.name === r.skill);
|
|
115
|
+
} catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}).map((r) => ({ itemUid: r.item_uid, itemTitle: r.title, skill: r.skill, addedBy: r.added_by, commit: r.commit_sha, arrivedAt: Number(r.arrived_at) }));
|
|
119
|
+
} catch {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function acceptArrival(input) {
|
|
124
|
+
if (!pendingArrivals(input.itemUid).has(input.skill)) return false;
|
|
125
|
+
(0, import_database.getDb)().run(
|
|
126
|
+
"UPDATE skill_arrivals SET accepted_at = ?, accepted_by = ?, accepted_by_type = ? WHERE item_uid = ? AND skill = ? AND accepted_at IS NULL",
|
|
127
|
+
[input.now ?? Date.now(), input.by, input.byType, input.itemUid, input.skill]
|
|
128
|
+
);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
132
|
+
0 && (module.exports = {
|
|
133
|
+
acceptArrival,
|
|
134
|
+
lastCommitOf,
|
|
135
|
+
noteArrivals,
|
|
136
|
+
pendingArrivals,
|
|
137
|
+
planArrivals
|
|
138
|
+
});
|
|
@@ -0,0 +1,193 @@
|
|
|
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 skill_model_exports = {};
|
|
19
|
+
__export(skill_model_exports, {
|
|
20
|
+
MAX_SKILLS: () => MAX_SKILLS,
|
|
21
|
+
MAX_SKILL_NAME: () => MAX_SKILL_NAME,
|
|
22
|
+
MAX_SKILL_WHY: () => MAX_SKILL_WHY,
|
|
23
|
+
SKILL_SOURCES: () => SKILL_SOURCES,
|
|
24
|
+
agentView: () => agentView,
|
|
25
|
+
normaliseLocation: () => normaliseLocation,
|
|
26
|
+
normaliseRepoPath: () => normaliseRepoPath,
|
|
27
|
+
normaliseSkill: () => normaliseSkill,
|
|
28
|
+
normaliseSkills: () => normaliseSkills,
|
|
29
|
+
withoutLinks: () => withoutLinks
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(skill_model_exports);
|
|
32
|
+
const SKILL_SOURCES = ["mcp", "skill", "lang", "plugin"];
|
|
33
|
+
const MAX_SKILLS = 30;
|
|
34
|
+
const MAX_SKILL_NAME = 80;
|
|
35
|
+
const MAX_SKILL_WHY = 200;
|
|
36
|
+
const MAX_REPO_PATH = 300;
|
|
37
|
+
const MAX_URL = 500;
|
|
38
|
+
const NAME_RE = /^[^\u0000-\u001f\u007f`]+$/;
|
|
39
|
+
const IDENT_RE = /^[A-Za-z0-9][A-Za-z0-9._@/:+-]{0,99}$/;
|
|
40
|
+
const UID_RE = /^[A-Za-z0-9_-]{1,100}$/;
|
|
41
|
+
function oneLine(s) {
|
|
42
|
+
return s.replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
|
|
43
|
+
}
|
|
44
|
+
function normaliseRepoPath(raw) {
|
|
45
|
+
if (typeof raw !== "string") return null;
|
|
46
|
+
let p = raw.trim();
|
|
47
|
+
if (!p || p.length > MAX_REPO_PATH || p.includes("\0") || p.includes("\\")) return null;
|
|
48
|
+
if (p.startsWith("/") || /^[A-Za-z]:/.test(p) || p.startsWith("~")) return null;
|
|
49
|
+
p = p.replace(/^\.\/+/, "").replace(/\/+$/, "").replace(/\/{2,}/g, "/");
|
|
50
|
+
const parts = p.split("/");
|
|
51
|
+
if (parts.some((x) => x === ".." || x === "." || x === "")) return null;
|
|
52
|
+
if (!/\.md$/i.test(p)) p = `${p}/SKILL.md`;
|
|
53
|
+
return p;
|
|
54
|
+
}
|
|
55
|
+
function normaliseLocation(raw) {
|
|
56
|
+
if (raw === void 0 || raw === null) return { where: null, problem: null };
|
|
57
|
+
const r = raw;
|
|
58
|
+
switch (r?.kind) {
|
|
59
|
+
case "repo": {
|
|
60
|
+
const path = normaliseRepoPath(r.path);
|
|
61
|
+
return path ? { where: { kind: "repo", path }, problem: null } : { where: null, problem: "a repo location must be a relative path inside the project" };
|
|
62
|
+
}
|
|
63
|
+
case "plugin":
|
|
64
|
+
return typeof r.name === "string" && IDENT_RE.test(r.name) ? { where: { kind: "plugin", name: r.name }, problem: null } : { where: null, problem: "a plugin location needs a plugin name" };
|
|
65
|
+
case "mcp":
|
|
66
|
+
return typeof r.server === "string" && IDENT_RE.test(r.server) ? { where: { kind: "mcp", server: r.server }, problem: null } : { where: null, problem: "an mcp location needs a server name" };
|
|
67
|
+
case "playbook":
|
|
68
|
+
return typeof r.uid === "string" && UID_RE.test(r.uid) ? { where: { kind: "playbook", uid: r.uid }, problem: null } : { where: null, problem: "a playbook location needs a playbook id" };
|
|
69
|
+
case "link": {
|
|
70
|
+
if (typeof r.url !== "string" || r.url.length > MAX_URL) return { where: null, problem: "a link needs an http(s) URL" };
|
|
71
|
+
try {
|
|
72
|
+
const u = new URL(r.url);
|
|
73
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") throw new Error("protocol");
|
|
74
|
+
return { where: { kind: "link", url: u.toString() }, problem: null };
|
|
75
|
+
} catch {
|
|
76
|
+
return { where: null, problem: "a link needs an http(s) URL" };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
default:
|
|
80
|
+
return { where: null, problem: "a location is one of repo, plugin, mcp, playbook or link" };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function normaliseSkill(raw) {
|
|
84
|
+
const problems = [];
|
|
85
|
+
const r = raw ?? {};
|
|
86
|
+
const name = typeof r.name === "string" ? oneLine(r.name) : "";
|
|
87
|
+
if (!name || name.length > MAX_SKILL_NAME || !NAME_RE.test(name)) {
|
|
88
|
+
return { skill: null, problems: [`a skill needs a name of at most ${MAX_SKILL_NAME} characters, on one line, without backticks`] };
|
|
89
|
+
}
|
|
90
|
+
if (r.source !== void 0 && r.source !== null && !SKILL_SOURCES.includes(r.source)) {
|
|
91
|
+
return { skill: null, problems: [`skill "${name}": source must be one of ${SKILL_SOURCES.join(", ")}`] };
|
|
92
|
+
}
|
|
93
|
+
const source = r.source ?? "skill";
|
|
94
|
+
const skill = { name, source, required: r.required === true };
|
|
95
|
+
if (r.use !== void 0 && r.use !== null) {
|
|
96
|
+
if (r.use === "recommended") skill.use = "recommended";
|
|
97
|
+
else problems.push(`skill "${name}": use can only be "recommended"`);
|
|
98
|
+
}
|
|
99
|
+
if (r.why !== void 0 && r.why !== null) {
|
|
100
|
+
const why = typeof r.why === "string" ? oneLine(r.why) : "";
|
|
101
|
+
if (typeof r.why !== "string") problems.push(`skill "${name}": why must be text`);
|
|
102
|
+
else if (why.length > MAX_SKILL_WHY) problems.push(`skill "${name}": why is at most ${MAX_SKILL_WHY} characters`);
|
|
103
|
+
if (why) skill.why = why.slice(0, MAX_SKILL_WHY);
|
|
104
|
+
}
|
|
105
|
+
const { where, problem } = normaliseLocation(r.where);
|
|
106
|
+
if (problem) problems.push(`skill "${name}": ${problem}`);
|
|
107
|
+
if (where) skill.where = where;
|
|
108
|
+
return { skill, problems };
|
|
109
|
+
}
|
|
110
|
+
function normaliseSkills(raw) {
|
|
111
|
+
if (raw === void 0 || raw === null) return { skills: [], problems: [] };
|
|
112
|
+
if (!Array.isArray(raw)) return { skills: [], problems: ["skills must be a list"] };
|
|
113
|
+
const problems = [];
|
|
114
|
+
const out = [];
|
|
115
|
+
const seen = /* @__PURE__ */ new Set();
|
|
116
|
+
for (const entry of raw) {
|
|
117
|
+
const { skill, problems: p } = normaliseSkill(entry);
|
|
118
|
+
problems.push(...p);
|
|
119
|
+
if (!skill) continue;
|
|
120
|
+
if (seen.has(skill.name)) {
|
|
121
|
+
problems.push(`skill "${skill.name}" is listed twice`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (out.length >= MAX_SKILLS) {
|
|
125
|
+
problems.push(`at most ${MAX_SKILLS} skills`);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
seen.add(skill.name);
|
|
129
|
+
out.push(skill);
|
|
130
|
+
}
|
|
131
|
+
return { skills: out, problems };
|
|
132
|
+
}
|
|
133
|
+
function withoutLinks(value, depth = 0, hide) {
|
|
134
|
+
if (depth > 6 || value === null || typeof value !== "object") return value;
|
|
135
|
+
if (Array.isArray(value)) {
|
|
136
|
+
let changed = false;
|
|
137
|
+
const out = value.map((v) => {
|
|
138
|
+
const w = withoutLinks(v, depth + 1, hide);
|
|
139
|
+
if (w !== v) changed = true;
|
|
140
|
+
return w;
|
|
141
|
+
});
|
|
142
|
+
return changed ? out : value;
|
|
143
|
+
}
|
|
144
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) return value;
|
|
145
|
+
let copy = null;
|
|
146
|
+
const rawUid = value.uid;
|
|
147
|
+
const ownerUid = typeof rawUid === "string" ? rawUid : null;
|
|
148
|
+
for (const [k, v] of Object.entries(value)) {
|
|
149
|
+
let w = v;
|
|
150
|
+
if (k === "skills" && Array.isArray(v)) {
|
|
151
|
+
const shown = hide && ownerUid ? v.filter((s) => !hide(ownerUid, s?.name)) : v;
|
|
152
|
+
w = shown.some((s) => s?.where?.kind === "link") ? shown.map((s) => {
|
|
153
|
+
if (s?.where?.kind !== "link") return s;
|
|
154
|
+
const { where: _link, ...rest } = s;
|
|
155
|
+
return rest;
|
|
156
|
+
}) : shown.length === v.length ? v : shown;
|
|
157
|
+
} else {
|
|
158
|
+
w = withoutLinks(v, depth + 1, hide);
|
|
159
|
+
}
|
|
160
|
+
if (w !== v) {
|
|
161
|
+
copy ??= { ...value };
|
|
162
|
+
copy[k] = w;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return copy ?? value;
|
|
166
|
+
}
|
|
167
|
+
function agentView(mod, hide) {
|
|
168
|
+
const out = {};
|
|
169
|
+
for (const [k, v] of Object.entries(mod)) {
|
|
170
|
+
if (typeof v === "function" && !/^class[\s{]/.test(Function.prototype.toString.call(v))) {
|
|
171
|
+
out[k] = (...args) => {
|
|
172
|
+
const r = v(...args);
|
|
173
|
+
return r instanceof Promise ? r.then((x) => withoutLinks(x, 0, hide)) : withoutLinks(r, 0, hide);
|
|
174
|
+
};
|
|
175
|
+
} else {
|
|
176
|
+
out[k] = v;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
182
|
+
0 && (module.exports = {
|
|
183
|
+
MAX_SKILLS,
|
|
184
|
+
MAX_SKILL_NAME,
|
|
185
|
+
MAX_SKILL_WHY,
|
|
186
|
+
SKILL_SOURCES,
|
|
187
|
+
agentView,
|
|
188
|
+
normaliseLocation,
|
|
189
|
+
normaliseRepoPath,
|
|
190
|
+
normaliseSkill,
|
|
191
|
+
normaliseSkills,
|
|
192
|
+
withoutLinks
|
|
193
|
+
});
|
|
@@ -0,0 +1,140 @@
|
|
|
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 skill_use_service_exports = {};
|
|
19
|
+
__export(skill_use_service_exports, {
|
|
20
|
+
isClaudeCode: () => isClaudeCode,
|
|
21
|
+
recordSkillRead: () => recordSkillRead,
|
|
22
|
+
recordSkillUse: () => recordSkillUse,
|
|
23
|
+
skillProof: () => skillProof,
|
|
24
|
+
skillUseSources: () => skillUseSources,
|
|
25
|
+
skillUsesOf: () => skillUsesOf,
|
|
26
|
+
sourceOf: () => sourceOf
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(skill_use_service_exports);
|
|
29
|
+
var import_database = require("./database");
|
|
30
|
+
const MAX_SKILL = 80;
|
|
31
|
+
function rowsOf(sql, params = []) {
|
|
32
|
+
const res = (0, import_database.getDb)().exec(sql, params);
|
|
33
|
+
if (!res.length) return [];
|
|
34
|
+
const { columns, values } = res[0];
|
|
35
|
+
return values.map((v) => Object.fromEntries(columns.map((c, i) => [c, v[i]])));
|
|
36
|
+
}
|
|
37
|
+
function isClaudeCode(agentType) {
|
|
38
|
+
return !!agentType && /^claude(-code)?\b/i.test(agentType) && !/desktop/i.test(agentType);
|
|
39
|
+
}
|
|
40
|
+
function recordSkillUse(input) {
|
|
41
|
+
const skill = input.skill.replace(/[\u0000-\u001f\u007f]+/g, " ").trim().slice(0, MAX_SKILL);
|
|
42
|
+
if (!skill || !input.workstreamRoot) return [];
|
|
43
|
+
try {
|
|
44
|
+
const items = rowsOf(
|
|
45
|
+
`SELECT i.uid, s.agent_type FROM plan_items i JOIN agent_sessions s ON s.session_id = i.assignee_session
|
|
46
|
+
WHERE s.workstream_root = ? AND i.status IN ('assigned', 'in_progress')`,
|
|
47
|
+
[input.workstreamRoot]
|
|
48
|
+
).filter((r) => isClaudeCode(r.agent_type)).map((r) => r.uid);
|
|
49
|
+
const at = input.at ?? Date.now();
|
|
50
|
+
for (const uid of items) {
|
|
51
|
+
(0, import_database.getDb)().run(
|
|
52
|
+
"INSERT INTO skill_uses (item_uid, skill, session_id, workstream_root, at, source) VALUES (?, ?, ?, ?, ?, ?)",
|
|
53
|
+
[uid, skill, input.sessionId, input.workstreamRoot, at, "session_log"]
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return items;
|
|
57
|
+
} catch {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function recordSkillRead(input) {
|
|
62
|
+
const skill = input.skill.replace(/[\u0000-\u001f\u007f]+/g, " ").trim().slice(0, MAX_SKILL);
|
|
63
|
+
if (!skill) return [];
|
|
64
|
+
try {
|
|
65
|
+
const items = rowsOf(
|
|
66
|
+
`SELECT uid FROM plan_items WHERE assignee_session = ? AND status IN ('assigned', 'in_progress')`,
|
|
67
|
+
[input.sessionId]
|
|
68
|
+
).map((r) => r.uid);
|
|
69
|
+
const at = input.at ?? Date.now();
|
|
70
|
+
for (const uid of items) {
|
|
71
|
+
(0, import_database.getDb)().run(
|
|
72
|
+
"INSERT INTO skill_uses (item_uid, skill, session_id, workstream_root, at, source) VALUES (?, ?, ?, ?, ?, ?)",
|
|
73
|
+
[uid, skill, input.sessionId, input.workstreamRoot, at, "mcp"]
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
return items;
|
|
77
|
+
} catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function sourceOf(sources, name) {
|
|
82
|
+
if (sources.has(name)) return sources.get(name);
|
|
83
|
+
for (const [k, v] of sources) if (k.endsWith(`:${name}`)) return v;
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function skillUseSources(itemUid) {
|
|
87
|
+
try {
|
|
88
|
+
const rows = rowsOf("SELECT skill, source FROM skill_uses WHERE item_uid = ? ORDER BY at", [itemUid]);
|
|
89
|
+
const out = /* @__PURE__ */ new Map();
|
|
90
|
+
for (const r of rows) {
|
|
91
|
+
const src = r.source === "mcp" ? "mcp" : "session_log";
|
|
92
|
+
if (!out.has(r.skill)) out.set(r.skill, src);
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
} catch {
|
|
96
|
+
return /* @__PURE__ */ new Map();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function skillUsesOf(itemUid) {
|
|
100
|
+
try {
|
|
101
|
+
const rows = rowsOf("SELECT skill, MIN(at) AS at FROM skill_uses WHERE item_uid = ? GROUP BY skill", [itemUid]);
|
|
102
|
+
return new Map(rows.map((r) => [r.skill, Number(r.at)]));
|
|
103
|
+
} catch {
|
|
104
|
+
return /* @__PURE__ */ new Map();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function assigneeAgentType(item) {
|
|
108
|
+
try {
|
|
109
|
+
const row = rowsOf(
|
|
110
|
+
`SELECT i.assignee_session AS session, s.agent_type FROM plan_items i LEFT JOIN agent_sessions s ON s.session_id = i.assignee_session WHERE i.uid = ?`,
|
|
111
|
+
[item.uid]
|
|
112
|
+
)[0];
|
|
113
|
+
if (!row?.session) return void 0;
|
|
114
|
+
return row.agent_type;
|
|
115
|
+
} catch {
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function skillProof(item, skills) {
|
|
120
|
+
const uses = skillUsesOf(item.uid);
|
|
121
|
+
const agentType = assigneeAgentType(item);
|
|
122
|
+
if (agentType === void 0 && uses.size === 0) return null;
|
|
123
|
+
const out = /* @__PURE__ */ new Map();
|
|
124
|
+
for (const s of skills) {
|
|
125
|
+
if (!s.required && s.use !== "recommended") continue;
|
|
126
|
+
const used = uses.has(s.name) || [...uses.keys()].some((k) => k.endsWith(`:${s.name}`));
|
|
127
|
+
out.set(s.name, used ? "used" : isClaudeCode(agentType) ? "not_used" : "unknown");
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
132
|
+
0 && (module.exports = {
|
|
133
|
+
isClaudeCode,
|
|
134
|
+
recordSkillRead,
|
|
135
|
+
recordSkillUse,
|
|
136
|
+
skillProof,
|
|
137
|
+
skillUseSources,
|
|
138
|
+
skillUsesOf,
|
|
139
|
+
sourceOf
|
|
140
|
+
});
|