@chemx/starter-kit 26.10.8-344 → 26.10.10-75
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/AGENTS.md +135 -32
- package/README.md +253 -199
- package/blueprints/atoms/a-button.svelte +11 -9
- package/blueprints/atoms/a-button.vue +2 -1
- package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.svelte +8 -4
- package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.tsx +8 -4
- package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.vue +8 -4
- package/blueprints/molecule-capsule/m-sample-card.svelte +2 -1
- package/blueprints/molecule-capsule/m-sample-card.tsx +2 -1
- package/blueprints/molecule-capsule/m-sample-card.vue +4 -2
- package/blueprints/workflows/chemx-audit.yml +15 -46
- package/cli/agent-json.js +40 -0
- package/cli/apply-edits.js +195 -0
- package/cli/audit/ai-slop-detector.js +62 -35
- package/cli/audit/ast-passes.js +52 -0
- package/cli/audit/ast-visitors.js +142 -83
- package/cli/audit/audit-plain.js +26 -0
- package/cli/audit/audit-summary.js +16 -3
- package/cli/audit/autofix-content.js +122 -0
- package/cli/audit/autofix.js +74 -159
- package/cli/audit/budget-rules.js +84 -0
- package/cli/audit/catch-predicates.js +51 -0
- package/cli/audit/chemx-dir.js +76 -0
- package/cli/audit/clone-detector.js +4 -2
- package/cli/audit/comment-regions.js +83 -0
- package/cli/audit/coverage.js +48 -0
- package/cli/audit/csharp-analyzer.js +47 -22
- package/cli/audit/discussion-store.js +9 -4
- package/cli/audit/extended-text-patterns.js +104 -54
- package/cli/audit/extended-visitors.js +26 -12
- package/cli/audit/feed.d.ts +77 -0
- package/cli/audit/feed.js +146 -0
- package/cli/audit/gate-delta.js +91 -0
- package/cli/audit/gate-verdict.js +25 -3
- package/cli/audit/history.d.ts +14 -2
- package/cli/audit/history.js +89 -101
- package/cli/audit/hook-shape-validator.js +18 -9
- package/cli/audit/lexicon-predicates.js +125 -0
- package/cli/audit/lifecycle-predicates.js +106 -0
- package/cli/audit/line-budgets.js +154 -0
- package/cli/audit/metrics.js +56 -37
- package/cli/audit/mutable-ref-predicate.js +54 -0
- package/cli/audit/parseable-code.js +11 -0
- package/cli/audit/pattern-detector.js +56 -28
- package/cli/audit/project-figures.js +28 -0
- package/cli/audit/prompt-rule-lines.js +46 -0
- package/cli/audit/prompts.js +74 -46
- package/cli/audit/prop-surface.js +74 -0
- package/cli/audit/ratchet.js +112 -23
- package/cli/audit/render-depth.js +79 -0
- package/cli/audit/reporter-banner.js +7 -4
- package/cli/audit/reporter-grades.js +52 -34
- package/cli/audit/reporter-grouping.js +10 -5
- package/cli/audit/reporter-markdown.js +16 -8
- package/cli/audit/reporter-sections.js +31 -16
- package/cli/audit/reporter-summary.js +28 -16
- package/cli/audit/reporter-utils.js +54 -30
- package/cli/audit/roadmap.js +20 -15
- package/cli/audit/rule-overrides.js +78 -0
- package/cli/audit/rule-pillars.js +43 -0
- package/cli/audit/rule-revisions.js +42 -0
- package/cli/audit/rules-helpers.js +13 -63
- package/cli/audit/rules-predicates.d.ts +1 -0
- package/cli/audit/rules-predicates.js +84 -64
- package/cli/audit/rules-registry.js +94 -10
- package/cli/audit/rules.js +92 -171
- package/cli/audit/shallow-catch-csharp.js +49 -0
- package/cli/audit/shallow-catch-escalation.js +157 -0
- package/cli/audit/shallow-catch-reads.js +116 -0
- package/cli/audit/social-gh.js +18 -9
- package/cli/audit/social-git.js +82 -40
- package/cli/audit/social-http.js +17 -9
- package/cli/audit/social-publisher.js +14 -7
- package/cli/audit/social.js +39 -30
- package/cli/audit/staged-delta.js +67 -0
- package/cli/audit/status-file.js +67 -0
- package/cli/audit/structural-weight-evaluator.js +17 -29
- package/cli/audit/structural-weight.js +30 -13
- package/cli/audit/suppressions.js +130 -0
- package/cli/audit/template-rules.js +82 -0
- package/cli/audit/types.d.ts +24 -1
- package/cli/audit-engine.js +128 -0
- package/cli/audit-preflight-git.js +15 -1
- package/cli/audit-preflight.js +6 -4
- package/cli/audit-scan.js +180 -0
- package/cli/audit-scope.js +31 -14
- package/cli/audit.js +6 -201
- package/cli/babel-lazy.js +41 -0
- package/cli/badge.js +9 -6
- package/cli/banner.js +37 -0
- package/cli/build/child-registry.js +57 -0
- package/cli/build/executor.js +122 -48
- package/cli/build.js +75 -25
- package/cli/cli-args.js +107 -0
- package/cli/columnar.js +6 -3
- package/cli/commands/cmd-audit-each.js +164 -0
- package/cli/commands/cmd-audit-feed.js +78 -0
- package/cli/commands/cmd-audit.js +136 -57
- package/cli/commands/cmd-batch.js +60 -0
- package/cli/commands/cmd-check.js +74 -0
- package/cli/commands/cmd-project.js +18 -9
- package/cli/commands/cmd-router.js +148 -32
- package/cli/commands/cmd-show.js +56 -0
- package/cli/commands/cmd-staged-delta.js +27 -0
- package/cli/commands/cmd-wrappers-files.js +77 -0
- package/cli/commands/cmd-wrappers-git.js +122 -0
- package/cli/commands/cmd-wrappers-json.js +101 -0
- package/cli/commands/cmd-wrappers.js +7 -322
- package/cli/commands/unknown-flags.js +228 -0
- package/cli/commands-schema-badge.js +73 -0
- package/cli/commands-schema-commit.js +21 -0
- package/cli/commands-schema-edit.js +106 -0
- package/cli/commands-schema-host.js +65 -0
- package/cli/commands-schema-ops.js +127 -0
- package/cli/commands-schema-patterns.js +69 -0
- package/cli/commands-schema-report.js +18 -0
- package/cli/commands-schema-search.js +121 -0
- package/cli/commands-schema-setup.js +30 -0
- package/cli/commands-schema-verify.js +89 -0
- package/cli/commands-schema-wrappers.js +131 -0
- package/cli/commands-schema.js +26 -408
- package/cli/comment-ranges.js +108 -0
- package/cli/commit/commit-args.js +73 -0
- package/cli/commit/commit-cli.js +25 -0
- package/cli/commit/commit-facts.js +49 -0
- package/cli/commit/commit-git.js +98 -0
- package/cli/commit/commit-index.js +35 -0
- package/cli/commit/commit-message.js +52 -0
- package/cli/commit/commit-record.js +68 -0
- package/cli/commit/commit-run.js +160 -0
- package/cli/commit/commit-validate.js +62 -0
- package/cli/config/index.js +54 -8
- package/cli/config/loader.js +77 -8
- package/cli/config/profiles.js +7 -0
- package/cli/conflicts-cli.js +118 -0
- package/cli/conflicts.js +104 -0
- package/cli/create.js +11 -6
- package/cli/db-project-stamp.js +124 -0
- package/cli/docs-check/command-tree.js +27 -0
- package/cli/docs-check/extract.js +151 -0
- package/cli/docs-check/resolve.js +85 -0
- package/cli/docs-check/run.js +88 -0
- package/cli/doctor/check-env.js +43 -0
- package/cli/doctor/check-host.js +115 -0
- package/cli/doctor/check-index.js +93 -0
- package/cli/doctor/check-mcp.js +78 -0
- package/cli/doctor/doctor-cli.js +60 -0
- package/cli/doctor/kit-locate.js +40 -0
- package/cli/doctor/proc-scan.js +66 -0
- package/cli/edit-atomic.js +75 -0
- package/cli/edit-diff.js +98 -0
- package/cli/edit-guardrails.js +77 -0
- package/cli/edit-locks.js +128 -0
- package/cli/embeddings/vectorizer.js +9 -5
- package/cli/errors/catcher.js +45 -52
- package/cli/errors/formatter.js +14 -10
- package/cli/errors/policy.js +26 -0
- package/cli/errors/publisher.js +5 -1
- package/cli/errors/report-output.js +67 -0
- package/cli/errors/sanitizer.js +52 -3
- package/cli/errors/storage.js +17 -5
- package/cli/explode-importers.js +102 -0
- package/cli/explode-path-args.js +115 -0
- package/cli/explode-plan.js +153 -0
- package/cli/explode-prologue.js +43 -0
- package/cli/explode-relocate.js +73 -0
- package/cli/exploder.js +205 -193
- package/cli/forge/anchors.js +50 -0
- package/cli/forge/audit-forge.js +58 -0
- package/cli/forge/binding-walk.js +84 -0
- package/cli/forge/bindings.js +238 -0
- package/cli/forge/blueprint-cli.js +153 -0
- package/cli/forge/blueprint-context.js +69 -0
- package/cli/forge/blueprint-members.js +82 -0
- package/cli/forge/blueprint-store.js +106 -0
- package/cli/forge/blueprint-target.js +44 -0
- package/cli/forge/blueprint.js +276 -0
- package/cli/forge/body-end-cache.js +34 -0
- package/cli/forge/body-ends.js +86 -0
- package/cli/forge/canon-inline.js +342 -0
- package/cli/forge/canon-logic.js +106 -0
- package/cli/forge/canon-nodes.js +270 -0
- package/cli/forge/canon-print.js +120 -0
- package/cli/forge/canonicalize.js +49 -0
- package/cli/forge/conventions.js +51 -0
- package/cli/forge/drift.js +120 -0
- package/cli/forge/exclusions.js +21 -0
- package/cli/forge/exits.js +76 -0
- package/cli/forge/facets.js +86 -0
- package/cli/forge/file-units.js +53 -0
- package/cli/forge/fingerprint-file.js +52 -0
- package/cli/forge/fingerprint-session.js +215 -0
- package/cli/forge/fingerprint-sync.js +74 -0
- package/cli/forge/fingerprint-visitors.js +66 -0
- package/cli/forge/fixtures/heal/a7-dry-run.diff.txt +179 -0
- package/cli/forge/fixtures/heal/cli/commit/commit-facts.js.txt +49 -0
- package/cli/forge/fixtures/heal/cli/doctor/check-host.js.txt +117 -0
- package/cli/forge/fixtures/heal/cli/doctor/kit-locate.js.txt +42 -0
- package/cli/forge/fixtures/heal/cli/hooks/guard-paths.js.txt +80 -0
- package/cli/forge/fixtures/heal/cli/hooks/project-status.js.txt +62 -0
- package/cli/forge/fixtures/heal/cli/main.js.txt +169 -0
- package/cli/forge/fixtures/heal/cli/mcp/context.js.txt +81 -0
- package/cli/forge/fixtures/heal/cli/mcp/installer-report.js.txt +47 -0
- package/cli/forge/fixtures/heal/cli/path-scope.js.txt +169 -0
- package/cli/forge/fixtures/heal/cli/project-detector.js.txt +364 -0
- package/cli/forge/fixtures/heal/cli/project-markers.js.txt +42 -0
- package/cli/forge/fixtures/heal/cli/team/coordination-root.js.txt +161 -0
- package/cli/forge/fixtures/heal/cli/team/usage-reader.js.txt +109 -0
- package/cli/forge/fixtures/heal/cli/test-slots.js.txt +129 -0
- package/cli/forge/fixtures/social-gh.js.txt +131 -0
- package/cli/forge/fixtures/team-flags.js.txt +214 -0
- package/cli/forge/fold.js +199 -0
- package/cli/forge/forge-groups.js +200 -0
- package/cli/forge/forge-report.js +73 -0
- package/cli/forge/fuzz/binding-hook.js +36 -0
- package/cli/forge/fuzz/choices.js +40 -0
- package/cli/forge/fuzz/classes.js +41 -0
- package/cli/forge/fuzz/coverage.js +26 -0
- package/cli/forge/fuzz/gen-alias.js +61 -0
- package/cli/forge/fuzz/gen-control.js +73 -0
- package/cli/forge/fuzz/gen-kit.js +75 -0
- package/cli/forge/fuzz/gen-logic.js +77 -0
- package/cli/forge/fuzz/gen-mixed.js +204 -0
- package/cli/forge/fuzz/gen-modules.js +80 -0
- package/cli/forge/fuzz/gen-objects.js +92 -0
- package/cli/forge/fuzz/gen-scope.js +131 -0
- package/cli/forge/fuzz/gen-templates.js +87 -0
- package/cli/forge/fuzz/harness.js +314 -0
- package/cli/forge/fuzz/pair-check.js +115 -0
- package/cli/forge/fuzz/resolve.js +32 -0
- package/cli/forge/fuzz/run.js +121 -0
- package/cli/forge/fuzz/sandbox.js +108 -0
- package/cli/forge/fuzz/seeds.js +119 -0
- package/cli/forge/fuzz/slow-shard.js +60 -0
- package/cli/forge/fuzz/template-oracle.js +148 -0
- package/cli/forge/fuzz/transpile.js +61 -0
- package/cli/forge/gates.js +115 -0
- package/cli/forge/group-shape.js +137 -0
- package/cli/forge/group-store.js +160 -0
- package/cli/forge/group.js +280 -0
- package/cli/forge/gt-sandbox.js +83 -0
- package/cli/forge/gt-scaffold.js +110 -0
- package/cli/forge/hash-labels.js +117 -0
- package/cli/forge/hash.js +119 -0
- package/cli/forge/heal-apply.js +170 -0
- package/cli/forge/heal-cli.js +132 -0
- package/cli/forge/heal-leases.js +52 -0
- package/cli/forge/heal-locate.js +70 -0
- package/cli/forge/heal-match.js +208 -0
- package/cli/forge/heal-ops.js +197 -0
- package/cli/forge/heal-plan.js +143 -0
- package/cli/forge/heal-sandbox.js +126 -0
- package/cli/forge/heal-specs.js +80 -0
- package/cli/forge/heal-store.js +80 -0
- package/cli/forge/heal-text.js +60 -0
- package/cli/forge/heal-typecheck.js +108 -0
- package/cli/forge/heal-undo.js +74 -0
- package/cli/forge/heal-verify.js +148 -0
- package/cli/forge/hole-kinds.js +126 -0
- package/cli/forge/inline-mode.js +6 -0
- package/cli/forge/inline-on.setup.js +4 -0
- package/cli/forge/lgg-stage.js +125 -0
- package/cli/forge/lgg.js +197 -0
- package/cli/forge/library-match.js +74 -0
- package/cli/forge/murmur.js +86 -0
- package/cli/forge/naming.js +101 -0
- package/cli/forge/pattern-schema-ddl.js +157 -0
- package/cli/forge/placement.js +165 -0
- package/cli/forge/rank.js +174 -0
- package/cli/forge/refine.js +93 -0
- package/cli/forge/rejected-members.js +92 -0
- package/cli/forge/rejects.js +77 -0
- package/cli/forge/root-shapes.js +84 -0
- package/cli/forge/run-cache.js +145 -0
- package/cli/forge/sibling-blocks.js +41 -0
- package/cli/forge/siblings.js +140 -0
- package/cli/forge/store.js +180 -0
- package/cli/forge/template-normalize.js +209 -0
- package/cli/forge/template-roles.js +86 -0
- package/cli/forge/template-units.js +148 -0
- package/cli/forge/templates.js +42 -0
- package/cli/forge/unify-step.js +65 -0
- package/cli/forge/unit-floor.js +74 -0
- package/cli/forge/unit-hash.js +229 -0
- package/cli/forge/unit-trees.js +153 -0
- package/cli/forge/units.js +261 -0
- package/cli/forge/windows.js +129 -0
- package/cli/friction/friction-cli.js +71 -0
- package/cli/friction/friction-export.js +54 -0
- package/cli/friction/friction-log.js +54 -0
- package/cli/friction/usage-classify.js +56 -0
- package/cli/friction/usage-report.js +86 -0
- package/cli/friction/wrong-call.js +12 -0
- package/cli/fs-json.js +17 -0
- package/cli/generator-compact.js +55 -0
- package/cli/generator-help.js +16 -15
- package/cli/generator-indexer.js +2 -1
- package/cli/generator-jig-cli.js +11 -7
- package/cli/generator-jig.js +38 -33
- package/cli/generator-templates/archetypes/index.js +30 -13
- package/cli/generator-templates/archetypes/vector-matcher.js +8 -4
- package/cli/generator-templates/compact.js +4 -2
- package/cli/generator-templates/controller-converters.js +23 -14
- package/cli/generator-templates/controller.js +10 -5
- package/cli/generator-templates/hooks.js +4 -2
- package/cli/generator-templates/naming.js +2 -1
- package/cli/generator-templates/react.js +2 -1
- package/cli/generator-templates/specs.js +4 -2
- package/cli/generator-templates/svelte.js +4 -2
- package/cli/generator-templates/types.js +6 -3
- package/cli/generator-templates/views.js +4 -2
- package/cli/generator-templates/vue.js +4 -2
- package/cli/generator-writes.js +24 -0
- package/cli/generator.d.ts +1 -1
- package/cli/generator.js +86 -127
- package/cli/git-file-listing.js +69 -0
- package/cli/help-args.js +18 -0
- package/cli/help.d.ts +7 -3
- package/cli/help.js +94 -149
- package/cli/hooks/bypass-log.js +44 -0
- package/cli/hooks/claude-post-edit.js +79 -0
- package/cli/hooks/claude-pre-tool.js +178 -0
- package/cli/hooks/claude-settings-merge.js +101 -0
- package/cli/hooks/dispatch-identity.js +125 -0
- package/cli/hooks/entry.js +181 -0
- package/cli/hooks/foreign-identity.js +60 -0
- package/cli/hooks/guard-args.js +55 -0
- package/cli/hooks/guard-cases.js +94 -0
- package/cli/hooks/guard-config.js +43 -0
- package/cli/hooks/guard-invocation.js +106 -0
- package/cli/hooks/guard-paths.js +80 -0
- package/cli/hooks/guard-route.js +211 -0
- package/cli/hooks/guard-rules-nudge.js +37 -0
- package/cli/hooks/guard-rules-reads.js +66 -0
- package/cli/hooks/guard-rules-shell.js +239 -0
- package/cli/hooks/guard-rules.js +114 -0
- package/cli/hooks/hook-commands.js +21 -0
- package/cli/hooks/install-hooks-apply.js +36 -0
- package/cli/hooks/install-hooks-cli.js +100 -0
- package/cli/hooks/install-hooks-config.js +48 -0
- package/cli/hooks/install-hooks-pins.js +66 -0
- package/cli/hooks/install-hooks-plan.js +56 -0
- package/cli/hooks/install-hooks-status.js +7 -0
- package/cli/hooks/interpreter-writes.js +195 -0
- package/cli/hooks/launcher.js +60 -0
- package/cli/hooks/mcp-json-merge.js +39 -0
- package/cli/hooks/native-edit-lock.js +40 -0
- package/cli/hooks/native-tool-policy.js +152 -0
- package/cli/hooks/out-of-band-edits.js +141 -0
- package/cli/hooks/post-edit-scope.js +43 -0
- package/cli/hooks/project-status.js +59 -0
- package/cli/hooks/repo-membership.js +32 -0
- package/cli/hooks/run-hook.js +79 -0
- package/cli/hooks/session-identity.js +153 -0
- package/cli/hooks/session-start.js +50 -0
- package/cli/hooks/shell-lexer-readers.js +76 -0
- package/cli/hooks/shell-lexer-state.js +59 -0
- package/cli/hooks/shell-lexer.js +110 -0
- package/cli/hooks/shell-parse.js +232 -0
- package/cli/hooks/statusline.js +27 -0
- package/cli/hooks/xatoms-hints.js +38 -0
- package/cli/host-protocol.js +109 -0
- package/cli/host-shims.js +9 -8
- package/cli/index-admission.js +41 -0
- package/cli/index-freshness.js +83 -0
- package/cli/index-row-check.js +58 -0
- package/cli/index.js +52 -150
- package/cli/installer-templates.js +67 -75
- package/cli/installer.d.ts +16 -1
- package/cli/installer.js +159 -58
- package/cli/languages.js +8 -4
- package/cli/lattice-directives.js +24 -0
- package/cli/lattice-payload.js +34 -0
- package/cli/{tesseract-state.js → lattice-state.js} +8 -4
- package/cli/lease-view.js +48 -0
- package/cli/library/entry-fp.js +42 -0
- package/cli/library/entry-schema.js +90 -0
- package/cli/library/library-tasks.js +25 -0
- package/cli/library/registry.js +56 -0
- package/cli/library/reverify.js +56 -0
- package/cli/library/verify-checks.js +89 -0
- package/cli/library/verify.js +81 -0
- package/cli/license-config.js +124 -0
- package/cli/license.js +168 -135
- package/cli/line-count.js +23 -0
- package/cli/literal-replace.js +107 -0
- package/cli/main.js +166 -0
- package/cli/mcp/antigravity.js +11 -9
- package/cli/mcp/batch.js +59 -0
- package/cli/mcp/call-args.js +75 -0
- package/cli/mcp/call-effects.js +57 -0
- package/cli/mcp/call-scope.js +70 -62
- package/cli/mcp/context.js +81 -0
- package/cli/mcp/envelope.js +62 -0
- package/cli/mcp/fingerprint.js +26 -0
- package/cli/mcp/fresh-entry.js +34 -0
- package/cli/mcp/fresh-protocol.js +37 -0
- package/cli/mcp/fresh-runner.js +40 -0
- package/cli/mcp/help.js +53 -0
- package/cli/mcp/index.js +9 -5
- package/cli/mcp/inflight.js +47 -0
- package/cli/mcp/installer-jsonc.js +64 -0
- package/cli/mcp/installer-package.js +54 -0
- package/cli/mcp/installer-report.js +47 -0
- package/cli/mcp/installer-write.js +117 -0
- package/cli/mcp/installer.js +88 -187
- package/cli/mcp/manifests-analysis.js +156 -0
- package/cli/mcp/manifests-runners.js +48 -0
- package/cli/mcp/manifests-team.js +100 -0
- package/cli/mcp/manifests.js +69 -309
- package/cli/mcp/offload-worker.js +11 -0
- package/cli/mcp/offload.js +18 -0
- package/cli/mcp/patterns-cli.js +76 -0
- package/cli/mcp/patterns-forge-cli.js +120 -0
- package/cli/mcp/prompts.js +13 -10
- package/cli/mcp/resources.js +8 -35
- package/cli/mcp/roots.js +46 -0
- package/cli/mcp/scorecard-worker.js +7 -0
- package/cli/mcp/scorecard.js +42 -0
- package/cli/mcp/server-info.js +28 -0
- package/cli/mcp/server.js +91 -291
- package/cli/mcp/spec-harness.js +62 -0
- package/cli/mcp/stale-exec.js +48 -0
- package/cli/mcp/staleness.js +26 -0
- package/cli/mcp/stdio.js +141 -0
- package/cli/mcp/tool-call.js +73 -0
- package/cli/mcp/tools-audit-feed.js +33 -0
- package/cli/mcp/tools-audit.js +13 -7
- package/cli/mcp/tools-generate.js +3 -3
- package/cli/mcp/tools-lazy.js +39 -0
- package/cli/mcp/tools-patch.js +93 -21
- package/cli/mcp/tools-patterns.js +6 -3
- package/cli/mcp/tools-project.js +8 -4
- package/cli/mcp/tools-q-modes.js +15 -14
- package/cli/mcp/tools-q.js +94 -33
- package/cli/mcp/tools-read.js +30 -80
- package/cli/mcp/tools-team-feed.js +10 -8
- package/cli/mcp/tools-team-locks.js +22 -10
- package/cli/mcp/tools-team-mailbox.js +8 -7
- package/cli/mcp/tools-team-tasks.js +125 -38
- package/cli/mcp/tools-team.js +14 -7
- package/cli/mcp/tools-verify.js +44 -15
- package/cli/mcp/tools-write.js +11 -16
- package/cli/mcp/tools.js +202 -68
- package/cli/mcp/worker-run.js +24 -0
- package/cli/missing-imports.js +52 -0
- package/cli/mutation-args.js +96 -0
- package/cli/mutators.js +164 -61
- package/cli/navigator-actions.js +19 -13
- package/cli/navigator-banner-helpers.js +1 -26
- package/cli/navigator-banner.js +5 -3
- package/cli/navigator-conversion.js +23 -12
- package/cli/navigator-grades.js +70 -35
- package/cli/navigator-guide.js +13 -11
- package/cli/navigator-menu.js +80 -166
- package/cli/navigator-paged.js +15 -8
- package/cli/navigator-sections.js +32 -0
- package/cli/navigator-share.js +53 -39
- package/cli/navigator.d.ts +25 -5
- package/cli/navigator.js +14 -41
- package/cli/network-policy.js +72 -0
- package/cli/network-recorder.fixture.mjs +35 -0
- package/cli/outline/ast-outline.js +120 -0
- package/cli/outline/style-outline.js +42 -0
- package/cli/outline/vue-outline.js +88 -0
- package/cli/patcher-cli.js +255 -0
- package/cli/patcher.d.ts +55 -24
- package/cli/patcher.js +167 -358
- package/cli/path-scope.js +78 -22
- package/cli/patterns/fixtures/gt/A1.txt +109 -0
- package/cli/patterns/fixtures/gt/A10.txt +13 -0
- package/cli/patterns/fixtures/gt/A11.txt +10 -0
- package/cli/patterns/fixtures/gt/A12.txt +29 -0
- package/cli/patterns/fixtures/gt/A13.txt +39 -0
- package/cli/patterns/fixtures/gt/A14.txt +45 -0
- package/cli/patterns/fixtures/gt/A15.txt +70 -0
- package/cli/patterns/fixtures/gt/A16.txt +59 -0
- package/cli/patterns/fixtures/gt/A17.txt +29 -0
- package/cli/patterns/fixtures/gt/A18.txt +9 -0
- package/cli/patterns/fixtures/gt/A19.txt +29 -0
- package/cli/patterns/fixtures/gt/A2.txt +28 -0
- package/cli/patterns/fixtures/gt/A20.txt +83 -0
- package/cli/patterns/fixtures/gt/A21.txt +138 -0
- package/cli/patterns/fixtures/gt/A22.txt +32 -0
- package/cli/patterns/fixtures/gt/A23.txt +37 -0
- package/cli/patterns/fixtures/gt/A24.txt +67 -0
- package/cli/patterns/fixtures/gt/A25.txt +41 -0
- package/cli/patterns/fixtures/gt/A26.txt +29 -0
- package/cli/patterns/fixtures/gt/A3.txt +17 -0
- package/cli/patterns/fixtures/gt/A4.txt +44 -0
- package/cli/patterns/fixtures/gt/A5.txt +32 -0
- package/cli/patterns/fixtures/gt/A6.txt +15 -0
- package/cli/patterns/fixtures/gt/A7.txt +79 -0
- package/cli/patterns/fixtures/gt/A8.txt +41 -0
- package/cli/patterns/fixtures/gt/A9.txt +42 -0
- package/cli/patterns/fixtures/gt/B1.txt +11 -0
- package/cli/patterns/fixtures/gt/B10.txt +41 -0
- package/cli/patterns/fixtures/gt/B11.txt +7 -0
- package/cli/patterns/fixtures/gt/B2.txt +19 -0
- package/cli/patterns/fixtures/gt/B3.txt +70 -0
- package/cli/patterns/fixtures/gt/B4.txt +55 -0
- package/cli/patterns/fixtures/gt/B5.txt +21 -0
- package/cli/patterns/fixtures/gt/B6.txt +15 -0
- package/cli/patterns/fixtures/gt/B7.txt +24 -0
- package/cli/patterns/fixtures/gt/B8.txt +40 -0
- package/cli/patterns/fixtures/gt/B9.txt +18 -0
- package/cli/patterns/fixtures/gt/C1.txt +26 -0
- package/cli/patterns/fixtures/gt/C2.txt +33 -0
- package/cli/patterns/fixtures/gt/C3.txt +26 -0
- package/cli/patterns/fixtures/gt/C4.txt +7 -0
- package/cli/patterns/fixtures/gt/C5.txt +29 -0
- package/cli/patterns/fixtures/gt/C6.txt +7 -0
- package/cli/patterns/fixtures/gt/C7.txt +18 -0
- package/cli/patterns/fixtures/gt/labels.json +1837 -0
- package/cli/patterns/gt-build.js +55 -0
- package/cli/patterns/gt-locations.js +76 -0
- package/cli/patterns/gt-resolve.js +66 -0
- package/cli/patterns/gt-score-cli.js +80 -0
- package/cli/patterns/gt-score.js +188 -0
- package/cli/patterns/gt-text.js +79 -0
- package/cli/pillars-wizard.js +53 -24
- package/cli/pillars-write-guard.js +4 -1
- package/cli/postinstall.js +22 -19
- package/cli/project-detector.js +60 -35
- package/cli/project-markers.js +42 -0
- package/cli/project-scope.js +20 -0
- package/cli/read-revision.js +70 -0
- package/cli/reader-cards-gate.js +29 -0
- package/cli/reader-cards.js +153 -0
- package/cli/reader-cli.js +45 -18
- package/cli/reader-format.js +48 -0
- package/cli/reader-logic.js +128 -250
- package/cli/reader.js +210 -221
- package/cli/request-context.js +9 -0
- package/cli/result-status.js +23 -0
- package/cli/rules.js +81 -0
- package/cli/scaffold.js +80 -51
- package/cli/scan-ignore.js +12 -0
- package/cli/search-args.js +102 -0
- package/cli/search-ast-module.js +103 -0
- package/cli/search-ast.js +75 -112
- package/cli/search-commands-blast.js +70 -0
- package/cli/search-commands-graph.js +57 -105
- package/cli/search-commands-hazards.js +105 -0
- package/cli/search-commands-literal.js +102 -0
- package/cli/search-commands-semantic.js +39 -27
- package/cli/search-commands.js +93 -186
- package/cli/search-db.js +52 -252
- package/cli/search-debug.js +13 -0
- package/cli/search-graph-edges.js +112 -0
- package/cli/search-index-meta.js +66 -0
- package/cli/search-index-write.js +153 -0
- package/cli/search-literal-files.js +64 -0
- package/cli/search-literal.js +150 -0
- package/cli/search-output.js +88 -0
- package/cli/search-queries-graph.js +120 -193
- package/cli/search-queries-semantic.js +41 -14
- package/cli/search-queries-similar.js +2 -1
- package/cli/search-queries.js +46 -21
- package/cli/search-query-view.js +67 -0
- package/cli/search-rank.js +54 -0
- package/cli/search-replace-blocks.js +120 -0
- package/cli/search-resolve.js +52 -0
- package/cli/search-root.js +78 -0
- package/cli/search-scan.js +102 -0
- package/cli/search-schema-ddl.js +172 -0
- package/cli/search-schema.js +135 -220
- package/cli/search-session.js +11 -0
- package/cli/search-sync-paths.js +78 -0
- package/cli/search-sync-plan.js +63 -0
- package/cli/search-sync-rows.js +96 -0
- package/cli/search-sync.js +128 -0
- package/cli/search-tokenizer.js +8 -4
- package/cli/search.d.ts +26 -5
- package/cli/search.js +156 -410
- package/cli/sfc/component-resolver.js +96 -0
- package/cli/sfc/import-coverage.js +24 -0
- package/cli/sfc/module-aliases.js +102 -0
- package/cli/sfc/script-asts.js +51 -0
- package/cli/sfc/sfc-metadata.js +104 -0
- package/cli/sfc/sfc-parse.js +101 -0
- package/cli/sfc/svelte-parse.js +46 -0
- package/cli/sfc/template-walk.js +78 -0
- package/cli/sfc-scripts.js +60 -0
- package/cli/share-consent.js +49 -0
- package/cli/share-outcome.js +57 -0
- package/cli/silence-warnings.js +2 -1
- package/cli/source-parse.js +130 -0
- package/cli/spec-isolated-home.js +17 -0
- package/cli/spec-support/import-trace.mjs +22 -0
- package/cli/spec-support/run-cli.js +58 -0
- package/cli/sqlite-memory.js +47 -0
- package/cli/status-command.js +107 -0
- package/cli/symbol-locator.js +121 -0
- package/cli/team/agent-identity.js +58 -0
- package/cli/team/audit-run-adoption.js +117 -0
- package/cli/team/audit-run-bypass.js +177 -0
- package/cli/team/audit-run-calls.js +108 -0
- package/cli/team/audit-run-db.js +181 -0
- package/cli/team/audit-run-identity.js +80 -0
- package/cli/team/audit-run-invocations.js +130 -0
- package/cli/team/audit-run-protocol.js +258 -0
- package/cli/team/audit-run-render.js +107 -0
- package/cli/team/audit-run-shas.js +179 -0
- package/cli/team/audit-run.js +203 -0
- package/cli/team/claim-ignore-deps.js +16 -0
- package/cli/team/coordination-busy.js +164 -0
- package/cli/team/coordination-db.js +85 -0
- package/cli/team/coordination-fixture.js +53 -0
- package/cli/team/coordination-repos.js +72 -0
- package/cli/team/coordination-root.js +161 -0
- package/cli/team/coordination-target.js +114 -0
- package/cli/team/dispatch-templates/dispatch-v1.js +228 -0
- package/cli/team/edit-shas.js +45 -0
- package/cli/team/lease-activity.js +130 -0
- package/cli/team/lease-cap.js +67 -0
- package/cli/team/lease-contention.js +30 -0
- package/cli/team/lease-key.js +46 -0
- package/cli/team/lease-lapse.js +83 -0
- package/cli/team/lease-reacquire.js +99 -0
- package/cli/team/lease-renew.js +97 -0
- package/cli/team/lease-roots.js +30 -0
- package/cli/team/lease-waiter-notice.js +48 -0
- package/cli/team/staged-leases.js +64 -0
- package/cli/team/task-completion-output.js +78 -0
- package/cli/team/task-detail-sections.js +86 -0
- package/cli/team/task-list-view.js +10 -1
- package/cli/team/task-ref.js +73 -0
- package/cli/team/task-target.js +53 -0
- package/cli/team/task-tier.js +17 -0
- package/cli/team/team-brief.js +78 -0
- package/cli/team/team-commands-board.js +118 -0
- package/cli/team/team-commands-dispatch.js +85 -0
- package/cli/team/team-commands-lock-staged.js +87 -0
- package/cli/team/team-commands-lock-views.js +144 -0
- package/cli/team/team-commands-lock.js +115 -26
- package/cli/team/team-commands-migrate.js +171 -0
- package/cli/team/team-commands-profile.js +44 -0
- package/cli/team/team-commands-repo.js +114 -0
- package/cli/team/team-commands-task.js +312 -0
- package/cli/team/team-commands-tokens.js +57 -0
- package/cli/team/team-commands-triage.js +43 -0
- package/cli/team/team-commands-vds.js +2 -1
- package/cli/team/team-commands.js +108 -463
- package/cli/team/team-db-agents.js +12 -6
- package/cli/team/team-db-feed.js +25 -13
- package/cli/team/team-db-lock-promotion.js +95 -51
- package/cli/team/team-db-locks.js +167 -35
- package/cli/team/team-db-mailbox.js +15 -8
- package/cli/team/team-db-readonly.js +76 -0
- package/cli/team/team-db-task-helpers.js +68 -19
- package/cli/team/team-db-tasks.js +21 -9
- package/cli/team/team-db-transaction.js +20 -5
- package/cli/team/team-db.js +11 -4
- package/cli/team/team-dispatch-batches.js +271 -0
- package/cli/team/team-dispatch-prompts.js +152 -0
- package/cli/team/team-dispatch-render.js +154 -0
- package/cli/team/team-dispatch-run-cli.js +154 -0
- package/cli/team/team-dispatch-runs.js +155 -0
- package/cli/team/team-dispatch-script.js +67 -0
- package/cli/team/team-dispatch-select.js +220 -0
- package/cli/team/team-dispatch-v2-fixture.js +62 -0
- package/cli/team/team-dispatch-v2.js +207 -0
- package/cli/team/team-dispatch.js +229 -0
- package/cli/team/team-dispatcher-authority.js +43 -0
- package/cli/team/team-flags.js +222 -48
- package/cli/team/team-format.js +80 -26
- package/cli/team/team-handoff-hint.js +9 -0
- package/cli/team/team-migrate-agents.js +52 -0
- package/cli/team/team-migrate-apply.js +178 -0
- package/cli/team/team-migrate-junk.js +55 -0
- package/cli/team/team-migrate-metadata.js +80 -0
- package/cli/team/team-migrate-paths.js +50 -0
- package/cli/team/team-migrate-plan.js +85 -0
- package/cli/team/team-migrate-report.js +89 -0
- package/cli/team/team-migrate-tables.js +85 -0
- package/cli/team/team-migrate.js +193 -0
- package/cli/team/team-needs.js +99 -0
- package/cli/team/team-profile-format.js +126 -0
- package/cli/team/team-profile.js +144 -0
- package/cli/team/team-projects-coordinator.js +54 -33
- package/cli/team/team-projects-format.js +8 -4
- package/cli/team/team-projects-memory.js +6 -3
- package/cli/team/team-projects.js +2 -1
- package/cli/team/team-release-train.js +2 -1
- package/cli/team/team-route.js +132 -0
- package/cli/team/team-schema-repo.js +48 -0
- package/cli/team/team-schema-usage.js +25 -0
- package/cli/team/team-schema-vds.js +7 -3
- package/cli/team/team-schema.js +24 -4
- package/cli/team/team-task-close.js +132 -0
- package/cli/team/team-task-guard.js +24 -0
- package/cli/team/team-task-handoff.js +122 -0
- package/cli/team/team-task-ownership.js +74 -0
- package/cli/team/team-task-rules.js +21 -0
- package/cli/team/team-task-uncommitted.js +49 -0
- package/cli/team/team-telemetry.js +44 -32
- package/cli/team/team-tokens.js +4 -1
- package/cli/team/team-triage-generate.js +212 -0
- package/cli/team/team-triage-log.js +11 -0
- package/cli/team/team-triage-verify.js +153 -0
- package/cli/team/team-triage.js +92 -339
- package/cli/team/team-vds.js +2 -1
- package/cli/team/usage-compute.js +70 -0
- package/cli/team/usage-pricing.js +62 -0
- package/cli/team/usage-reader.js +106 -0
- package/cli/team/usage-render.js +72 -0
- package/cli/team/usage-store.js +56 -0
- package/cli/team/usage-transcript.js +127 -0
- package/cli/team/write-lock-guard.js +48 -0
- package/cli/telemetry/call-ledger.js +264 -0
- package/cli/telemetry/call-schema.js +53 -0
- package/cli/telemetry/savings-dbs.js +111 -0
- package/cli/telemetry/savings-render.js +68 -0
- package/cli/telemetry/savings-report.js +101 -0
- package/cli/telemetry/savings-routing.js +66 -0
- package/cli/telemetry/savings-tooling.js +140 -0
- package/cli/terminal.js +38 -40
- package/cli/tesseract-manifesto.js +2 -17
- package/cli/tesseract.js +8 -21
- package/cli/test-audit.js +218 -0
- package/cli/test-changes.js +60 -0
- package/cli/test-command.js +201 -0
- package/cli/test-depth.js +43 -0
- package/cli/test-failures.js +170 -0
- package/cli/test-graph-open.js +150 -0
- package/cli/test-graph.js +188 -0
- package/cli/test-lanes.js +117 -0
- package/cli/test-output.js +155 -0
- package/cli/test-paths.js +51 -0
- package/cli/test-profile.js +64 -0
- package/cli/test-report.js +112 -0
- package/cli/test-run.js +53 -0
- package/cli/test-scope.js +55 -0
- package/cli/test-select.js +107 -0
- package/cli/test-slots.js +276 -0
- package/cli/test-workers.js +45 -0
- package/cli/test-workspace.js +83 -0
- package/cli/theme.js +6 -3
- package/cli/timers.js +6 -0
- package/cli/trend.js +10 -5
- package/cli/tsconfig-shape.js +20 -0
- package/cli/tty-banner.js +11 -0
- package/cli/typecheck-audit.js +146 -0
- package/cli/typecheck-command.js +94 -0
- package/cli/typecheck-sandbox.js +93 -0
- package/cli/ui-actions-codebase.js +20 -7
- package/cli/ui-actions-helpers.js +9 -0
- package/cli/ui-actions-studio.js +11 -7
- package/cli/ui-actions-tasks.js +3 -2
- package/cli/ui-actions-vds.js +2 -1
- package/cli/ui-actions.js +4 -2
- package/cli/ui-attention.js +28 -12
- package/cli/ui-auth-hosts.js +46 -0
- package/cli/ui-auth.js +89 -0
- package/cli/ui-client-cert.js +2 -1
- package/cli/ui-client-filetree.js +2 -2
- package/cli/ui-db-studio.js +23 -33
- package/cli/ui-dev-watcher.js +2 -1
- package/cli/ui-forum-data.js +45 -46
- package/cli/ui-forum-topics.js +6 -3
- package/cli/ui-fresh-index.js +11 -0
- package/cli/ui-handlers.js +6 -6
- package/cli/ui-html.js +6 -12
- package/cli/ui-index.html +3 -3
- package/cli/ui-route-helpers.js +10 -0
- package/cli/ui-server-routes.js +15 -17
- package/cli/ui-server.js +49 -50
- package/cli/ui-sql-guard.js +76 -0
- package/cli/ui-sql-mask.js +61 -0
- package/cli/ui-sse.js +5 -4
- package/cli/ui-template-filetree.js +4 -4
- package/cli/ui-template-kanban.js +4 -7
- package/cli/verify-changed.js +43 -0
- package/cli/verify-helpers.js +21 -207
- package/cli/verify-lint.js +54 -20
- package/cli/verify-report.js +117 -0
- package/cli/verify-steps.js +71 -0
- package/cli/verify.js +111 -372
- package/cli/wait-command.js +147 -0
- package/cli/workspace-run.js +153 -0
- package/cli/workspace.js +147 -0
- package/cli/write-append.js +28 -0
- package/library/node-js/is-path-inside/entry.json +57 -0
- package/library/node-js/is-path-inside/negative/path-scope.js.txt +13 -0
- package/library/node-js/is-path-inside/piece.js +15 -0
- package/library/node-js/is-path-inside/piece.spec.js +38 -0
- package/library/node-js/read-json-or/entry.json +70 -0
- package/library/node-js/read-json-or/negative/ratchet.js.txt +14 -0
- package/library/node-js/read-json-or/negative/workspace.js.txt +8 -0
- package/library/node-js/read-json-or/piece.js +17 -0
- package/library/node-js/read-json-or/piece.spec.js +36 -0
- package/library/vue-ts/nullable-timer-handle/ambient.d.ts +5 -0
- package/library/vue-ts/nullable-timer-handle/entry.json +84 -0
- package/library/vue-ts/nullable-timer-handle/negative/const-alias.ts.txt +17 -0
- package/library/vue-ts/nullable-timer-handle/negative/inline-guard.ts.txt +15 -0
- package/library/vue-ts/nullable-timer-handle/piece.spec.js +48 -0
- package/library/vue-ts/nullable-timer-handle/piece.ts +41 -0
- package/package.json +9 -3
- package/scripts/check-framework-generation.mjs +32 -12
- package/scripts/direct-run.mjs +9 -0
- package/scripts/pre-commit.sh +48 -74
- package/scripts/publish-both.mjs +24 -16
- package/scripts/publish-summary.mjs +14 -0
- package/scripts/postinstall.mjs +0 -27
package/cli/ui-index.html
CHANGED
|
@@ -795,7 +795,7 @@ const App = {
|
|
|
795
795
|
<div class="xo-kpi__value" style="color:var(--xo-cyan);">{{ codebase.length }}</div>
|
|
796
796
|
</div>
|
|
797
797
|
<div class="xo-kpi">
|
|
798
|
-
<div class="xo-kpi__label">
|
|
798
|
+
<div class="xo-kpi__label">Within line budget</div>
|
|
799
799
|
<div class="xo-kpi__value" style="color:var(--xo-lime);">{{ compliantCount }}</div>
|
|
800
800
|
</div>
|
|
801
801
|
<div class="xo-kpi">
|
|
@@ -817,7 +817,7 @@ const App = {
|
|
|
817
817
|
<div v-for="f in filteredCodebase" :key="f.path" class="xo-file-card">
|
|
818
818
|
<div class="d-flex align-center gap-2 mb-1">
|
|
819
819
|
<v-chip v-if="f.tier" size="x-small" :class="'tier-'+f.tier">{{ f.tier }}</v-chip>
|
|
820
|
-
<v-chip v-if="f.
|
|
820
|
+
<v-chip v-if="f.isOverBudget" size="x-small" class="xo-hazard">{{ f.lines }}L ⚠</v-chip>
|
|
821
821
|
<v-chip v-else-if="f.lines" size="x-small" variant="outlined" style="border-color:rgba(255,255,255,.12);color:rgba(255,255,255,.4);">{{ f.lines }}L</v-chip>
|
|
822
822
|
<v-chip v-if="f.coverage!=null" size="x-small" color="success" variant="tonal">{{ f.coverage }}%</v-chip>
|
|
823
823
|
</div>
|
|
@@ -1009,7 +1009,7 @@ const App = {
|
|
|
1009
1009
|
});
|
|
1010
1010
|
};
|
|
1011
1011
|
|
|
1012
|
-
const compliantCount = computed(() => codebase.value.filter(f => !f.
|
|
1012
|
+
const compliantCount = computed(() => codebase.value.filter(f => !f.isOverBudget).length);
|
|
1013
1013
|
const compliancePct = computed(() => !codebase.value.length ? 0 : Math.round(compliantCount.value / codebase.value.length * 100));
|
|
1014
1014
|
|
|
1015
1015
|
const filteredCodebase = computed(() => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const sendJson = (res, status, payload, extraHeaders = {}, afterSend = null) => {
|
|
2
|
+
res.writeHead(status, { 'Content-Type': 'application/json', ...extraHeaders });
|
|
3
|
+
res.end(JSON.stringify(payload));
|
|
4
|
+
if (afterSend) afterSend();
|
|
5
|
+
return res;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const runRoute = (handler) => {
|
|
9
|
+
try { return [handler(), null]; } catch (err) { return [null, err]; }
|
|
10
|
+
};
|
package/cli/ui-server-routes.js
CHANGED
|
@@ -17,27 +17,29 @@ import {
|
|
|
17
17
|
} from './ui-actions.js';
|
|
18
18
|
import { getDatabaseMetrics, executeSqlQuery } from './ui-db-studio.js';
|
|
19
19
|
import { scanAttentionItems, confirmAttentionItem } from './ui-attention.js';
|
|
20
|
+
import { withFreshIndex } from './ui-fresh-index.js';
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
// db: team rows (coordination db, #2581); indexDb (default db): code index for codebase, metrics, db studio.
|
|
23
|
+
export const routeGet = (pathname, db, cwd = process.cwd(), queryParams = {}, { indexDb = db } = {}) => {
|
|
22
24
|
const [cleanPath, search] = (pathname || '').split('?');
|
|
23
25
|
const parsedParams = search ? Object.fromEntries(new URLSearchParams(search)) : queryParams;
|
|
24
26
|
const normPath = cleanPath.replace(/^\/api\/swarm\//, '/api/');
|
|
25
27
|
|
|
26
28
|
const routes = {
|
|
27
|
-
'/api/status': () => handleSwarmStatus(db, cwd),
|
|
29
|
+
'/api/status': () => handleSwarmStatus(db, cwd, indexDb),
|
|
28
30
|
'/api/feed': () => ({ success: true, feed: queryFeed(db, parsedParams) }),
|
|
29
31
|
'/api/tasks': () => ({ success: true, tasks: listTasks(db, parsedParams) }),
|
|
30
32
|
'/api/categories': () => ({ success: true, categories: getForumCategories(db) }),
|
|
31
|
-
'/api/agents': () => ({ success: true, agents: handleSwarmStatus(db, cwd).agents }),
|
|
32
|
-
'/api/codebase': () => handleCodebaseIndex(
|
|
33
|
-
'/api/codebase/tree': () => handleCodebaseTree(
|
|
34
|
-
'/api/codebase/file': () => handleCodebaseFile(
|
|
35
|
-
'/api/database/metrics': () => getDatabaseMetrics(
|
|
33
|
+
'/api/agents': () => ({ success: true, agents: handleSwarmStatus(db, cwd, indexDb).agents }),
|
|
34
|
+
'/api/codebase': () => withFreshIndex(cwd, {}, () => handleCodebaseIndex(indexDb, cwd)),
|
|
35
|
+
'/api/codebase/tree': () => withFreshIndex(cwd, {}, () => handleCodebaseTree(indexDb, cwd)),
|
|
36
|
+
'/api/codebase/file': () => withFreshIndex(cwd, { paths: [parsedParams.path], scope: false }, () => handleCodebaseFile(indexDb, parsedParams.path, cwd)),
|
|
37
|
+
'/api/database/metrics': () => getDatabaseMetrics(indexDb, cwd),
|
|
36
38
|
'/api/topics': () => handleGetTopics(db, parsedParams.category),
|
|
37
39
|
'/api/topics/posts': () => handleGetTopicPosts(db, parsedParams.topicId || parsedParams.topic_id),
|
|
38
40
|
'/api/attention': () => scanAttentionItems(db, cwd),
|
|
39
|
-
'/api/db/tables': () => handleDbTables(
|
|
40
|
-
'/api/db/browse': () => handleDbBrowse(
|
|
41
|
+
'/api/db/tables': () => handleDbTables(indexDb, cwd),
|
|
42
|
+
'/api/db/browse': () => handleDbBrowse(indexDb, parsedParams), '/api/db/structure': () => handleDbStructure(indexDb, parsedParams)
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
const hasRoute = Object.prototype.hasOwnProperty.call(routes, normPath);
|
|
@@ -53,7 +55,7 @@ export const routeGet = (pathname, db, cwd = process.cwd(), queryParams = {}) =>
|
|
|
53
55
|
return null;
|
|
54
56
|
};
|
|
55
57
|
|
|
56
|
-
export const routePost = (pathname, db, body, cwd = process.cwd()) => {
|
|
58
|
+
export const routePost = (pathname, db, body, cwd = process.cwd(), { consoleDb = null } = {}) => {
|
|
57
59
|
const [cleanPath] = (pathname || '').split('?');
|
|
58
60
|
const postFeedHandler = handleCreateFeedPost || handlePostFeed;
|
|
59
61
|
const normPath = cleanPath.replace(/^\/api\/swarm\//, '/api/');
|
|
@@ -72,10 +74,10 @@ export const routePost = (pathname, db, body, cwd = process.cwd()) => {
|
|
|
72
74
|
'/api/agents/signature': () => handleUpdateSignature(db, body),
|
|
73
75
|
'/api/topics': () => handleCreateTopic(db, body),
|
|
74
76
|
'/api/settings/action': () => handleSettingsAction(db, body),
|
|
75
|
-
'/api/database/query': () => executeSqlQuery(
|
|
77
|
+
'/api/database/query': () => executeSqlQuery(consoleDb, body.query),
|
|
76
78
|
'/api/attention/action': () => confirmAttentionItem(db, body.itemId, body.action),
|
|
77
79
|
'/api/prompts/generate': () => handleGeneratePrompt(db, body, cwd),
|
|
78
|
-
'/api/db/query': () => handleDbQuery(
|
|
80
|
+
'/api/db/query': () => handleDbQuery(consoleDb, body)
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
const hasRoute = Object.prototype.hasOwnProperty.call(routes, normPath);
|
|
@@ -88,11 +90,7 @@ export const parseJsonBody = (req) => {
|
|
|
88
90
|
let raw = '';
|
|
89
91
|
req.on('data', (chunk) => { raw += chunk; });
|
|
90
92
|
req.on('end', () => {
|
|
91
|
-
|
|
92
|
-
resolve(JSON.parse(raw || '{}'));
|
|
93
|
-
} catch (err) {
|
|
94
|
-
reject(err);
|
|
95
|
-
}
|
|
93
|
+
Promise.resolve(raw || '{}').then(JSON.parse).then(resolve, reject);
|
|
96
94
|
});
|
|
97
95
|
req.on('error', reject);
|
|
98
96
|
});
|
package/cli/ui-server.js
CHANGED
|
@@ -1,77 +1,74 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
2
|
import { openIndexDb } from './search-db.js';
|
|
3
|
+
import { openTeamContext, describeTeamDbFailure } from './team/coordination-db.js';
|
|
3
4
|
import { handleSwarmStatus } from './ui-handlers.js';
|
|
4
5
|
import { generateSwarmHtml } from './ui-html.js';
|
|
5
6
|
import { routeGet, routePost, parseJsonBody } from './ui-server-routes.js';
|
|
6
7
|
import { handleSseConnection, broadcastSseUpdate, broadcastSseReload, closeSseHub } from './ui-sse.js';
|
|
8
|
+
import { createUiAuth, checkUiRequest, createUiFetch, isLoopbackHost, resolveUiUrlHost, DEFAULT_UI_HOST } from './ui-auth.js';
|
|
9
|
+
import { openConsoleDb } from './ui-sql-guard.js';
|
|
10
|
+
import { sendJson, runRoute } from './ui-route-helpers.js';
|
|
7
11
|
|
|
8
|
-
export const createUiServer = (cwd = process.cwd()) => {
|
|
9
|
-
const
|
|
12
|
+
export const createUiServer = (cwd = process.cwd(), options = {}) => {
|
|
13
|
+
const indexDb = openIndexDb(cwd);
|
|
14
|
+
const teamContext = openTeamContext(cwd);
|
|
15
|
+
const db = teamContext.db; // team rows: coordination db only (#2581), null when refused; code index, studio, console: indexDb
|
|
16
|
+
const auth = options.auth || createUiAuth();
|
|
17
|
+
const consoleDb = openConsoleDb(cwd);
|
|
10
18
|
const server = http.createServer(async (req, res) => {
|
|
11
|
-
const url = new URL(req.url || '/',
|
|
19
|
+
const url = new URL(req.url || '/', 'http://chemx-ui.invalid');
|
|
12
20
|
const { pathname } = url;
|
|
13
21
|
const isGet = req.method === 'GET', isPost = req.method === 'POST';
|
|
14
|
-
const isApi = pathname.startsWith('/api/'),
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
22
|
+
const isApi = pathname.startsWith('/api/'), isFaviconRequest = isGet && pathname === '/favicon.ico';
|
|
23
|
+
if (isFaviconRequest) return res.writeHead(204).end();
|
|
24
|
+
const gate = checkUiRequest(req, auth, url);
|
|
25
|
+
const isDenied = !gate.allowed;
|
|
26
|
+
if (isDenied) return sendJson(res, gate.status, { success: false, error: gate.error });
|
|
27
|
+
const hasSetCookie = Boolean(gate.setCookie);
|
|
28
|
+
const cookieHeaders = hasSetCookie ? { 'Set-Cookie': gate.setCookie } : {};
|
|
29
|
+
const isTeamUnavailable = !db;
|
|
30
|
+
if (isTeamUnavailable) return sendJson(res, 503, { success: false, error: describeTeamDbFailure(teamContext) }, cookieHeaders);
|
|
31
|
+
const shouldServeHtml = isGet && !isApi;
|
|
18
32
|
if (shouldServeHtml) {
|
|
19
|
-
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
20
|
-
res.end(generateSwarmHtml(handleSwarmStatus(db)));
|
|
21
|
-
return;
|
|
33
|
+
return res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', ...cookieHeaders }).end(generateSwarmHtml(handleSwarmStatus(db, cwd, indexDb)));
|
|
22
34
|
}
|
|
23
|
-
if (shouldServeFavicon) { res.writeHead(204); res.end(); return; }
|
|
24
|
-
|
|
25
35
|
if (isGet) {
|
|
26
36
|
const isSse = pathname === '/api/swarm/events' || pathname === '/api/events';
|
|
27
|
-
if (isSse)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const result = routeGet(req.url, db, cwd);
|
|
32
|
-
if (result) {
|
|
33
|
-
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
34
|
-
res.end(JSON.stringify(result));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
+
if (isSse) return handleSseConnection(req, res, db);
|
|
38
|
+
const [result, getError] = runRoute(() => routeGet(req.url, db, cwd, {}, { indexDb }));
|
|
39
|
+
if (getError) return sendJson(res, 500, { success: false, error: getError.message }, cookieHeaders);
|
|
40
|
+
if (result) return sendJson(res, 200, result, cookieHeaders);
|
|
37
41
|
}
|
|
38
|
-
|
|
39
42
|
if (isPost) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
res.end(JSON.stringify(result));
|
|
46
|
-
broadcastSseUpdate(db);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
} catch (err) {
|
|
50
|
-
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
51
|
-
res.end(JSON.stringify({ error: 'Invalid JSON payload' }));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
43
|
+
const [body, parseError] = await parseJsonBody(req).then((value) => [value, null], (err) => [null, err]);
|
|
44
|
+
if (parseError) return sendJson(res, 400, { error: 'Invalid JSON payload' });
|
|
45
|
+
const [result, routeError] = runRoute(() => routePost(req.url, db, body, cwd, { consoleDb }));
|
|
46
|
+
if (routeError) return sendJson(res, 500, { success: false, error: routeError.message });
|
|
47
|
+
if (result) return sendJson(res, 200, result, {}, () => broadcastSseUpdate(db));
|
|
54
48
|
}
|
|
55
|
-
res
|
|
56
|
-
res.end(JSON.stringify({ error: 'Not found' }));
|
|
49
|
+
return sendJson(res, 404, { error: 'Not found' });
|
|
57
50
|
});
|
|
58
51
|
|
|
59
|
-
server.on('close', closeSseHub);
|
|
60
|
-
return { server, db };
|
|
52
|
+
server.on('close', () => { closeSseHub(); consoleDb?.close(); });
|
|
53
|
+
return { server, db, indexDb, auth };
|
|
61
54
|
};
|
|
62
55
|
|
|
56
|
+
const warnPublicBind = (host) => process.stderr.write(
|
|
57
|
+
`\x1b[33m⚠ chemx ui is bound to ${host}, reachable beyond this machine. Anyone with the token URL can drive the swarm.\x1b[0m\n`);
|
|
58
|
+
|
|
63
59
|
export const startUiServer = async (options = {}) => {
|
|
64
60
|
const port = options.port !== undefined ? options.port : 4173;
|
|
65
|
-
const host = options.host ||
|
|
61
|
+
const host = options.host || DEFAULT_UI_HOST;
|
|
66
62
|
const cwd = options.cwd || process.cwd();
|
|
67
|
-
const {
|
|
63
|
+
const auth = createUiAuth({ bindHost: host, token: options.token, allowHosts: options.allowHosts });
|
|
64
|
+
const { server, db } = createUiServer(cwd, { auth });
|
|
68
65
|
|
|
69
|
-
|
|
66
|
+
const isDevMode = Boolean(options.dev);
|
|
67
|
+
if (isDevMode) {
|
|
70
68
|
const { startUiDevWatcher } = await import('./ui-dev-watcher.js');
|
|
71
69
|
const watcher = startUiDevWatcher(cwd, () => broadcastSseReload());
|
|
72
70
|
server.on('close', () => watcher.close());
|
|
73
71
|
}
|
|
74
|
-
|
|
75
72
|
return new Promise((resolve, reject) => {
|
|
76
73
|
server.on('error', (err) => {
|
|
77
74
|
if (options.isCli) process.stderr.write(`\x1b[31m✖ UI error: ${err.message}\x1b[0m\n`);
|
|
@@ -81,13 +78,15 @@ export const startUiServer = async (options = {}) => {
|
|
|
81
78
|
server.listen(port, host, () => {
|
|
82
79
|
const addr = server.address();
|
|
83
80
|
const actualPort = typeof addr === 'object' && addr ? addr.port : port;
|
|
84
|
-
|
|
85
|
-
const
|
|
81
|
+
auth.cookieName = `chemx_ui_${actualPort}`;
|
|
82
|
+
const urlHost = resolveUiUrlHost(host);
|
|
83
|
+
const url = `http://${urlHost}:${actualPort}/?token=${auth.token}`;
|
|
86
84
|
if (options.isCli) {
|
|
87
|
-
|
|
88
|
-
|
|
85
|
+
if (!isLoopbackHost(host)) warnPublicBind(host);
|
|
86
|
+
process.stdout.write(`\x1b[32m✔ Chemical X Live Swarm Web UI listening on ${host}:${actualPort}:\x1b[0m \x1b[36m${url}\x1b[0m\n`);
|
|
87
|
+
if (isDevMode) process.stdout.write(`\x1b[35m🔥 Dev Hot Reload: ENABLED (watching UI files for instant updates)\x1b[0m\n`);
|
|
89
88
|
}
|
|
90
|
-
resolve({ server, port: actualPort, url, db });
|
|
89
|
+
resolve({ server, port: actualPort, url, db, token: auth.token, fetch: createUiFetch(auth.token) });
|
|
91
90
|
});
|
|
92
91
|
});
|
|
93
92
|
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chemical X UI SQL console guard.
|
|
3
|
+
* The DB Studio console is read-only: one SELECT/WITH/VALUES/EXPLAIN statement
|
|
4
|
+
* or a read-only PRAGMA. Everything else (ATTACH, DDL, DML, PRAGMA writes) is refused.
|
|
5
|
+
* The server also runs console SQL on a readOnly, query_only connection as a second wall.
|
|
6
|
+
*/
|
|
7
|
+
import { createRequire } from 'node:module';
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { resolveIndexDbPath } from './search-schema.js';
|
|
10
|
+
import { maskSqlLiteralsAndComments } from './ui-sql-mask.js';
|
|
11
|
+
|
|
12
|
+
const READ_STATEMENT_START = /^(SELECT|WITH|VALUES|EXPLAIN|PRAGMA)\b/i;
|
|
13
|
+
const WRITE_KEYWORDS = /\b(ATTACH|DETACH|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|VACUUM|REINDEX|ANALYZE)\b|\bREPLACE\s+INTO\b/i;
|
|
14
|
+
const INTROSPECTION_PRAGMAS = new Set([
|
|
15
|
+
'table_info', 'table_xinfo', 'index_list', 'index_info', 'index_xinfo',
|
|
16
|
+
'foreign_key_list', 'foreign_key_check', 'integrity_check', 'quick_check'
|
|
17
|
+
]);
|
|
18
|
+
const QUERY_ONLY_PRAGMAS = new Set([
|
|
19
|
+
...INTROSPECTION_PRAGMAS, 'table_list', 'database_list', 'collation_list', 'function_list',
|
|
20
|
+
'pragma_list', 'compile_options', 'page_size', 'page_count', 'freelist_count', 'journal_mode',
|
|
21
|
+
'busy_timeout', 'user_version', 'schema_version', 'application_id', 'encoding', 'auto_vacuum',
|
|
22
|
+
'cache_size', 'synchronous', 'foreign_keys', 'wal_autocheckpoint'
|
|
23
|
+
]);
|
|
24
|
+
const PRAGMA_SHAPE = /^PRAGMA\s+(?:\w+\.)?(\w+)\s*(\(\s*[\w"'.]+\s*\))?\s*$/i;
|
|
25
|
+
|
|
26
|
+
export const CONSOLE_READ_ONLY_ERROR =
|
|
27
|
+
'Only SELECT, WITH, VALUES, EXPLAIN or read-only PRAGMA statements are permitted, one per request: the SQL console is read-only.';
|
|
28
|
+
|
|
29
|
+
const isSingleStatement = (code) => {
|
|
30
|
+
const withoutTrailing = code.trim().replace(/;\s*$/, '');
|
|
31
|
+
return !withoutTrailing.includes(';');
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const isReadOnlyPragma = (code) => {
|
|
35
|
+
const shape = code.trim().replace(/;\s*$/, '').match(PRAGMA_SHAPE);
|
|
36
|
+
if (!shape) return false;
|
|
37
|
+
const name = shape[1].toLowerCase();
|
|
38
|
+
const hasArgument = Boolean(shape[2]);
|
|
39
|
+
if (hasArgument) return INTROSPECTION_PRAGMAS.has(name);
|
|
40
|
+
return QUERY_ONLY_PRAGMAS.has(name);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Returns { allowed, reason } for a console statement. */
|
|
44
|
+
export const classifyConsoleSql = (sql = '') => {
|
|
45
|
+
const masked = maskSqlLiteralsAndComments(sql);
|
|
46
|
+
const code = masked.code.trim();
|
|
47
|
+
if (!masked.isWellFormed) return { allowed: false, reason: CONSOLE_READ_ONLY_ERROR };
|
|
48
|
+
if (!code) return { allowed: false, reason: 'Empty SQL statement' };
|
|
49
|
+
const startsAsRead = READ_STATEMENT_START.test(code);
|
|
50
|
+
const isPragma = /^PRAGMA\b/i.test(code);
|
|
51
|
+
const hasWriteKeyword = WRITE_KEYWORDS.test(code);
|
|
52
|
+
const isAllowed = startsAsRead && isSingleStatement(code) && !hasWriteKeyword && (!isPragma || isReadOnlyPragma(code));
|
|
53
|
+
return isAllowed ? { allowed: true } : { allowed: false, reason: CONSOLE_READ_ONLY_ERROR };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const CONSOLE_UNAVAILABLE_ERROR =
|
|
57
|
+
'SQL console unavailable: the read-only index connection could not be opened.';
|
|
58
|
+
|
|
59
|
+
const loadDatabaseSync = () => {
|
|
60
|
+
try { return createRequire(import.meta.url)('node:sqlite').DatabaseSync; } catch { return null; }
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const openReadOnly = (DatabaseSync, dbPath) => {
|
|
64
|
+
const connection = new DatabaseSync(dbPath, { readOnly: true });
|
|
65
|
+
connection.exec('PRAGMA query_only = 1');
|
|
66
|
+
return connection;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Opens a readOnly, query_only connection to the project index for the SQL console, or null. */
|
|
70
|
+
export const openConsoleDb = (cwd = process.cwd()) => {
|
|
71
|
+
const DatabaseSync = loadDatabaseSync();
|
|
72
|
+
const dbPath = resolveIndexDbPath(cwd);
|
|
73
|
+
const hasIndex = Boolean(DatabaseSync) && fs.existsSync(dbPath);
|
|
74
|
+
if (!hasIndex) return null;
|
|
75
|
+
try { return openReadOnly(DatabaseSync, dbPath); } catch { return null; }
|
|
76
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-pass SQL masker for the UI console guard.
|
|
3
|
+
* Walks the input left to right the way the SQLite tokenizer does, so the guard
|
|
4
|
+
* sees the same statement boundaries SQLite sees. Comments become a space,
|
|
5
|
+
* quoted strings and identifiers become an empty placeholder of the same quote.
|
|
6
|
+
* Returns { code, isWellFormed }: unterminated quotes or a NUL byte are not well formed.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const QUOTE_CLOSERS = { "'": "'", '"': '"', '`': '`', '[': ']' };
|
|
10
|
+
|
|
11
|
+
const findQuoteEnd = (sql, start, closer) => {
|
|
12
|
+
const allowsDoubling = closer !== ']';
|
|
13
|
+
let i = start + 1;
|
|
14
|
+
while (i < sql.length) {
|
|
15
|
+
const isCloser = sql[i] === closer;
|
|
16
|
+
const isDoubled = isCloser && allowsDoubling && sql[i + 1] === closer;
|
|
17
|
+
if (isDoubled) { i += 2; continue; }
|
|
18
|
+
if (isCloser) return i;
|
|
19
|
+
i += 1;
|
|
20
|
+
}
|
|
21
|
+
return -1;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const findLineCommentEnd = (sql, start) => {
|
|
25
|
+
const newline = sql.indexOf('\n', start);
|
|
26
|
+
return newline === -1 ? sql.length : newline;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const findBlockCommentEnd = (sql, start) => {
|
|
30
|
+
const close = sql.indexOf('*/', start + 2);
|
|
31
|
+
return close === -1 ? sql.length : close + 2;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const maskSqlLiteralsAndComments = (sql = '') => {
|
|
35
|
+
const text = String(sql);
|
|
36
|
+
const hasNul = text.includes('\u0000');
|
|
37
|
+
if (hasNul) return { code: '', isWellFormed: false };
|
|
38
|
+
let code = '';
|
|
39
|
+
let i = 0;
|
|
40
|
+
while (i < text.length) {
|
|
41
|
+
const ch = text[i];
|
|
42
|
+
const pair = text.slice(i, i + 2);
|
|
43
|
+
const isLineComment = pair === '--';
|
|
44
|
+
const isBlockComment = pair === '/*';
|
|
45
|
+
const closer = QUOTE_CLOSERS[ch];
|
|
46
|
+
const isQuoteStart = Boolean(closer);
|
|
47
|
+
if (isLineComment) { code += ' '; i = findLineCommentEnd(text, i); continue; }
|
|
48
|
+
if (isBlockComment) { code += ' '; i = findBlockCommentEnd(text, i); continue; }
|
|
49
|
+
if (isQuoteStart) {
|
|
50
|
+
const end = findQuoteEnd(text, i, closer);
|
|
51
|
+
const isUnterminated = end === -1;
|
|
52
|
+
if (isUnterminated) return { code, isWellFormed: false };
|
|
53
|
+
code += ch + closer;
|
|
54
|
+
i = end + 1;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
code += ch;
|
|
58
|
+
i += 1;
|
|
59
|
+
}
|
|
60
|
+
return { code, isWellFormed: true };
|
|
61
|
+
};
|
package/cli/ui-sse.js
CHANGED
|
@@ -6,8 +6,7 @@ export const handleSseConnection = (req, res, db) => {
|
|
|
6
6
|
res.writeHead(200, {
|
|
7
7
|
'Content-Type': 'text/event-stream',
|
|
8
8
|
'Cache-Control': 'no-cache, no-transform',
|
|
9
|
-
'Connection': 'keep-alive'
|
|
10
|
-
'Access-Control-Allow-Origin': '*'
|
|
9
|
+
'Connection': 'keep-alive'
|
|
11
10
|
});
|
|
12
11
|
|
|
13
12
|
try {
|
|
@@ -28,7 +27,8 @@ export const handleSseConnection = (req, res, db) => {
|
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
export const broadcastSseUpdate = (db) => {
|
|
31
|
-
|
|
30
|
+
const isNotReady = clients.size === 0 || !db;
|
|
31
|
+
if (isNotReady) return;
|
|
32
32
|
try {
|
|
33
33
|
const state = handleSwarmStatus(db);
|
|
34
34
|
const payload = `data: ${JSON.stringify(state)}\n\n`;
|
|
@@ -45,7 +45,8 @@ export const broadcastSseUpdate = (db) => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
export const broadcastSseReload = () => {
|
|
48
|
-
|
|
48
|
+
const hasNoClients = clients.size === 0;
|
|
49
|
+
if (hasNoClients) return;
|
|
49
50
|
const payload = `event: reload\ndata: ${JSON.stringify({ timestamp: Date.now() })}\n\n`;
|
|
50
51
|
for (const client of clients) {
|
|
51
52
|
try {
|
|
@@ -8,8 +8,8 @@ export const VIEW_FILETREE_TEMPLATE = `
|
|
|
8
8
|
<div style="display:flex; gap:8px; align-items:center; flex-wrap:wrap;">
|
|
9
9
|
<strong>🧬 Codebase AST Explorer & Inspector</strong>
|
|
10
10
|
<span class="a-badge badge-primary">{{ codebaseFiles.length }} Files</span>
|
|
11
|
-
<span class="a-badge badge-lime">{{ cleanFileCount }}
|
|
12
|
-
<span class="a-badge badge-pink">{{ monolithFileCount }}
|
|
11
|
+
<span class="a-badge badge-lime">{{ cleanFileCount }} within line budget</span>
|
|
12
|
+
<span class="a-badge badge-pink">{{ monolithFileCount }} over line budget</span>
|
|
13
13
|
<span v-if="codebaseHazardCount > 0" class="badge-hazard">⚠️ {{ codebaseHazardCount }} Hazards</span>
|
|
14
14
|
</div>
|
|
15
15
|
<div style="display:flex; gap:6px; align-items:center;">
|
|
@@ -30,7 +30,7 @@ export const VIEW_FILETREE_TEMPLATE = `
|
|
|
30
30
|
</div>
|
|
31
31
|
<div v-else class="filetree-file" :class="{ 'filetree-file--selected': selectedFilePath === node.path }" @click="selectFile(node.path)">
|
|
32
32
|
<span>📄</span><span style="flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:11px;" :title="node.path">{{ node.name }}</span>
|
|
33
|
-
<span class="a-badge" :class="node.
|
|
33
|
+
<span class="a-badge" :class="node.isOverBudget ? 'badge-pink' : 'badge-lime'">{{ node.lines }}L</span>
|
|
34
34
|
<span class="a-badge badge-primary" style="font-size:9px;">{{ node.tier }}</span>
|
|
35
35
|
<span class="a-badge" :class="node.healthScore < 80 ? 'badge-warning' : 'badge-lime'" style="font-size:9px;">{{ node.healthScore }}%</span>
|
|
36
36
|
<span v-if="node.hazardCount > 0" class="badge-hazard" style="font-size:9px;">⚠️{{ node.hazardCount }}</span>
|
|
@@ -46,7 +46,7 @@ export const VIEW_FILETREE_TEMPLATE = `
|
|
|
46
46
|
<div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:6px;">
|
|
47
47
|
<strong style="color:#62c9ff; font-size:12px; word-break:break-all;">{{ selectedFileDetail.file.path }}</strong>
|
|
48
48
|
<div style="display:flex; gap:6px; align-items:center;">
|
|
49
|
-
<span class="a-badge" :class="selectedFileDetail.file.
|
|
49
|
+
<span class="a-badge" :class="selectedFileDetail.file.isOverBudget ? 'badge-pink' : 'badge-lime'">{{ selectedFileDetail.file.lines }} Lines</span>
|
|
50
50
|
<span class="a-badge badge-primary">{{ selectedFileDetail.file.tier }}</span>
|
|
51
51
|
<span class="a-badge badge-lime">Health: {{ selectedFileDetail.file.healthScore }}%</span>
|
|
52
52
|
<span v-if="selectedFileDetail.file.hazardCount > 0" class="badge-hazard">⚠️ {{ selectedFileDetail.file.hazardCount }} Hazards</span>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatTaskTokenStamp } from './team/team-telemetry.js';
|
|
1
2
|
import { TASK_DETAILS_SHEET_TEMPLATE } from './ui-template-task-sheet.js';
|
|
2
3
|
|
|
3
4
|
export const KANBAN_COLUMNS = [
|
|
@@ -14,12 +15,8 @@ export const groupTasksByColumn = (tasks = []) => ({
|
|
|
14
15
|
blocked: tasks.filter((t) => t.status === 'blocked' || t.status === 'failed')
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const c = Number(t.completion_tokens || 45);
|
|
20
|
-
const cost = t.cost_usd != null ? Number(t.cost_usd) : ((p * 0.000003) + (c * 0.000015));
|
|
21
|
-
return `[P: ${p} | C: ${c} | Cost: $${cost.toFixed(4)}]`;
|
|
22
|
-
};
|
|
18
|
+
// Never invent tokens for an unmeasured task; the stamp says unknown.
|
|
19
|
+
export const formatKanbanTokenStamp = (t = {}) => formatTaskTokenStamp(t);
|
|
23
20
|
|
|
24
21
|
export const VIEW_KANBAN_TEMPLATE = `
|
|
25
22
|
<!-- 5-Column Kanban: Queued, In Progress, Review, Completed, Blocked -->
|
|
@@ -67,7 +64,7 @@ export const VIEW_KANBAN_TEMPLATE = `
|
|
|
67
64
|
<span class="a-badge badge-warning" style="font-size:9px;">{{ (t.vds_priority || 'medium').toUpperCase() }}</span>
|
|
68
65
|
<span class="a-badge badge-primary" style="cursor:pointer;" title="Click to view agent profile" @click="openAgentProfile(t.assigned_agent_id || t.assignedAgentId)">{{ t.assigned_agent_id || t.assignedAgentId || '@unassigned' }}</span>
|
|
69
66
|
</div>
|
|
70
|
-
<span class="vb-token-stamp">{{ t.tokenStamp ||
|
|
67
|
+
<span class="vb-token-stamp">{{ t.tokenStamp || '[tokens: unknown]' }}</span>
|
|
71
68
|
|
|
72
69
|
<div v-if="taskRefusals && taskRefusals[t.id]" style="background:#450a0a; border:1px solid #dc2626; color:#fca5a5; padding:5px 6px; border-radius:3px; margin:4px 0; font-size:10px;">
|
|
73
70
|
<strong>⛔ Verification Refused:</strong> {{ taskRefusals[t.id].message }}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// `chemx verify --changed`: the audit covers only the changed source files and the tests only
|
|
2
|
+
// the affected specs; typecheck stays whole-project (types cross every file) and says so.
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { listChangedFiles } from './test-changes.js';
|
|
5
|
+
import { isSourceFilePath } from './audit-preflight-git.js';
|
|
6
|
+
import { ANSI } from './theme.js';
|
|
7
|
+
import { STATUS } from './result-status.js';
|
|
8
|
+
import { changedPackages, runPerPackage, changeNotes, rootOrAllPackages } from './workspace-run.js';
|
|
9
|
+
|
|
10
|
+
// Returns { ok, base, files } (root-relative source files that still exist) or { ok: false, error }.
|
|
11
|
+
export const resolveVerifyChanges = (root, base = null) => {
|
|
12
|
+
const listing = listChangedFiles(root, { base });
|
|
13
|
+
const isListingFailed = !listing.ok;
|
|
14
|
+
if (isListingFailed) return { ok: false, error: listing.error };
|
|
15
|
+
const files = listing.files.filter((f) => f.status !== 'D' && isSourceFilePath(f.path)).map((f) => f.path);
|
|
16
|
+
return { ok: true, base: listing.base, files };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const changedAuditOptions = (root, changes) => ({ fileList: changes.files.map((file) => path.join(root, file)) });
|
|
20
|
+
|
|
21
|
+
export const testArgsFor = (changes, base) => (changes ? ['--changed', ...(base ? [`--base=${base}`] : [])] : []);
|
|
22
|
+
|
|
23
|
+
// verify at a monorepo root: --changed verifies each package that owns a changed file,
|
|
24
|
+
// --all-packages verifies every package, anything else is refused with the package list.
|
|
25
|
+
// runInPackage(pkg, args) resolves to that package's own verify summary.
|
|
26
|
+
export const verifyWorkspace = async (workspace, { changed, base, allPackages }, runInPackage) => {
|
|
27
|
+
if (!changed) return rootOrAllPackages(workspace, 'verify', allPackages, (pkg) => runInPackage(pkg, []));
|
|
28
|
+
const changes = changedPackages(workspace, base);
|
|
29
|
+
const isChangesFailed = !changes.ok;
|
|
30
|
+
if (isChangesFailed) return { status: STATUS.INCONCLUSIVE, success: false, reason: 'NO_CHANGES', error: `cannot list changed files: ${changes.error}`, packages: [] };
|
|
31
|
+
const args = testArgsFor(changes, base);
|
|
32
|
+
const extraStatuses = changes.rootManifests.length > 0 || changes.packages.length === 0 ? [STATUS.INCONCLUSIVE] : [];
|
|
33
|
+
const units = changes.packages.map((pkg) => ({ pkg, args }));
|
|
34
|
+
return runPerPackage(units, (unit) => runInPackage(unit.pkg, unit.args), { base: changes.base, dependents: changes.dependents, rootFiles: changes.rootFiles, notes: changeNotes(changes), extraStatuses });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const formatVerifyLine = (entry) => {
|
|
38
|
+
const steps = ['audit', 'typecheck', 'tests'].map((step) => `${step} ${entry[step]?.status ?? '-'}`).join(', ');
|
|
39
|
+
const icon = entry.status === STATUS.PASS ? `${ANSI.LIME}✔` : `${ANSI.RED}✖`;
|
|
40
|
+
const excluded = Array.isArray(entry.scope?.excluded) ? entry.scope.excluded : [];
|
|
41
|
+
const scopeLine = excluded.length > 0 ? ` ${ANSI.DIM}audited ${entry.scope.dir}/; not audited: ${excluded.join(", ")} (--all-packages runs their own audits)${ANSI.RESET}\n` : "";
|
|
42
|
+
return ` ${icon}${ANSI.RESET} ${entry.status} ${ANSI.DIM}(${steps})${ANSI.RESET}\n${scopeLine}`;
|
|
43
|
+
};
|