@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
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
export interface AtomButtonProps {
|
|
3
|
+
type?: 'button' | 'submit' | 'reset';
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
ariaLabel?: string;
|
|
6
|
+
variant?: 'primary' | 'ghost' | 'glass';
|
|
7
|
+
class?: string;
|
|
8
|
+
onclick?: (e: MouseEvent) => void;
|
|
9
|
+
children?: import('svelte').Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
2
12
|
let {
|
|
3
13
|
type = 'button',
|
|
4
14
|
disabled = false,
|
|
@@ -7,15 +17,7 @@
|
|
|
7
17
|
class: className = '',
|
|
8
18
|
onclick,
|
|
9
19
|
children
|
|
10
|
-
} = $props<
|
|
11
|
-
type?: 'button' | 'submit' | 'reset';
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
ariaLabel?: string;
|
|
14
|
-
variant?: 'primary' | 'ghost' | 'glass';
|
|
15
|
-
class?: string;
|
|
16
|
-
onclick?: (e: MouseEvent) => void;
|
|
17
|
-
children?: import('svelte').Snippet;
|
|
18
|
-
}>();
|
|
20
|
+
} = $props<AtomButtonProps>();
|
|
19
21
|
</script>
|
|
20
22
|
|
|
21
23
|
<button
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
|
|
4
4
|
export const resolveGradeClass = (grade: string): string => {
|
|
5
5
|
const g = grade.toUpperCase();
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
if (
|
|
6
|
+
const isGradeA = Boolean(g.startsWith('A'));
|
|
7
|
+
if (isGradeA) return 'm-chemx-badge__grade--a';
|
|
8
|
+
const isGradeB = Boolean(g.startsWith('B'));
|
|
9
|
+
if (isGradeB) return 'm-chemx-badge__grade--b';
|
|
10
|
+
const isGradeC = Boolean(g.startsWith('C'));
|
|
11
|
+
if (isGradeC) return 'm-chemx-badge__grade--c';
|
|
12
|
+
const isGradeD = Boolean(g.startsWith('D'));
|
|
13
|
+
if (isGradeD) return 'm-chemx-badge__grade--d';
|
|
10
14
|
return 'm-chemx-badge__grade--f';
|
|
11
15
|
};
|
|
12
16
|
|
|
@@ -3,10 +3,14 @@ import type { MChemxBadgeProps } from './types';
|
|
|
3
3
|
|
|
4
4
|
export const resolveGradeClass = (grade: string): string => {
|
|
5
5
|
const g = grade.toUpperCase();
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
if (
|
|
6
|
+
const isGradeA = g.startsWith('A');
|
|
7
|
+
if (isGradeA) return 'm-chemx-badge__grade--a';
|
|
8
|
+
const isGradeB = g.startsWith('B');
|
|
9
|
+
if (isGradeB) return 'm-chemx-badge__grade--b';
|
|
10
|
+
const isGradeC = g.startsWith('C');
|
|
11
|
+
if (isGradeC) return 'm-chemx-badge__grade--c';
|
|
12
|
+
const isGradeD = g.startsWith('D');
|
|
13
|
+
if (isGradeD) return 'm-chemx-badge__grade--d';
|
|
10
14
|
return 'm-chemx-badge__grade--f';
|
|
11
15
|
};
|
|
12
16
|
|
|
@@ -18,10 +18,14 @@ const props = withDefaults(defineProps<MChemxBadgeProps>(), {
|
|
|
18
18
|
const targetHref = computed(() => props.reportUrl || props.href);
|
|
19
19
|
const gradeClass = computed(() => {
|
|
20
20
|
const g = props.grade.toUpperCase();
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
if (
|
|
21
|
+
const isGradeA = g.startsWith('A');
|
|
22
|
+
if (isGradeA) return 'm-chemx-badge__grade--a';
|
|
23
|
+
const isGradeB = g.startsWith('B');
|
|
24
|
+
if (isGradeB) return 'm-chemx-badge__grade--b';
|
|
25
|
+
const isGradeC = g.startsWith('C');
|
|
26
|
+
if (isGradeC) return 'm-chemx-badge__grade--c';
|
|
27
|
+
const isGradeD = g.startsWith('D');
|
|
28
|
+
if (isGradeD) return 'm-chemx-badge__grade--d';
|
|
25
29
|
return 'm-chemx-badge__grade--f';
|
|
26
30
|
});
|
|
27
31
|
</script>
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
const isHighValue = $derived(value > 1000);
|
|
14
14
|
|
|
15
15
|
const badge = $derived.by((): SampleCardBadgeDescriptor => {
|
|
16
|
-
|
|
16
|
+
const isArchived = status !== 'active';
|
|
17
|
+
if (isArchived) {
|
|
17
18
|
return {
|
|
18
19
|
text: status,
|
|
19
20
|
className: 'm-sample-card__badge m-sample-card__badge--archived'
|
|
@@ -6,7 +6,8 @@ export const resolveBadgeDescriptor = (
|
|
|
6
6
|
status: 'active' | 'archived',
|
|
7
7
|
isHighValue: boolean
|
|
8
8
|
): SampleCardBadgeDescriptor => {
|
|
9
|
-
|
|
9
|
+
const isArchived = status !== 'active';
|
|
10
|
+
if (isArchived) {
|
|
10
11
|
return {
|
|
11
12
|
text: status,
|
|
12
13
|
className: 'm-sample-card__badge m-sample-card__badge--archived'
|
|
@@ -12,7 +12,8 @@ const props = withDefaults(defineProps<MSampleCardProps>(), {
|
|
|
12
12
|
const isHighValue = computed(() => props.value > 1000);
|
|
13
13
|
|
|
14
14
|
const badge = computed((): SampleCardBadgeDescriptor => {
|
|
15
|
-
|
|
15
|
+
const isArchived = props.status !== 'active';
|
|
16
|
+
if (isArchived) {
|
|
16
17
|
return {
|
|
17
18
|
text: props.status,
|
|
18
19
|
className: 'm-sample-card__badge m-sample-card__badge--archived'
|
|
@@ -31,7 +32,8 @@ const badge = computed((): SampleCardBadgeDescriptor => {
|
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
const handleActionClick = () => {
|
|
34
|
-
|
|
35
|
+
const onActionHandler = props.onAction;
|
|
36
|
+
if (onActionHandler) onActionHandler();
|
|
35
37
|
};
|
|
36
38
|
</script>
|
|
37
39
|
|
|
@@ -31,13 +31,19 @@ jobs:
|
|
|
31
31
|
npm install
|
|
32
32
|
fi
|
|
33
33
|
|
|
34
|
+
# Gate on the ratchet (chemx-ratchet.json): fail only when a rule rises above its recorded
|
|
35
|
+
# baseline. Without a ratchet file the gate fails on any CRITICAL/HIGH finding; record one with
|
|
36
|
+
# `npx chemx audit --rebaseline` (full scan). Set the CHEMX_MIN_GRADE / CHEMX_MIN_SCORE repo
|
|
37
|
+
# variables to add absolute floors.
|
|
34
38
|
- name: Run Chemical X Architectural Audit
|
|
39
|
+
env:
|
|
40
|
+
CHEMX_MIN_GRADE: ${{ vars.CHEMX_MIN_GRADE }}
|
|
41
|
+
CHEMX_MIN_SCORE: ${{ vars.CHEMX_MIN_SCORE }}
|
|
35
42
|
run: |
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
--output=AUDIT_REPORT.md
|
|
43
|
+
set -- --markdown --output=AUDIT_REPORT.md
|
|
44
|
+
if [ -n "$CHEMX_MIN_GRADE" ]; then set -- "$@" "--min-grade=$CHEMX_MIN_GRADE"; fi
|
|
45
|
+
if [ -n "$CHEMX_MIN_SCORE" ]; then set -- "$@" "--min-score=$CHEMX_MIN_SCORE"; fi
|
|
46
|
+
npx --yes chemx audit "$@"
|
|
41
47
|
|
|
42
48
|
- name: Upload Audit Scorecard Artifact
|
|
43
49
|
if: always()
|
|
@@ -62,53 +68,16 @@ jobs:
|
|
|
62
68
|
{
|
|
63
69
|
echo "<!-- chemical-x-audit-pr-comment -->"
|
|
64
70
|
if [ -n "$DISCUSSION_URL" ]; then
|
|
65
|
-
echo "> 💬 **Architectural Discussion Topic:** [View Discussion & Community Showcase](
|
|
71
|
+
echo "> 💬 **Architectural Discussion Topic:** [View Discussion & Community Showcase]($DISCUSSION_URL)"
|
|
66
72
|
echo ""
|
|
67
73
|
fi
|
|
68
74
|
cat AUDIT_REPORT.md
|
|
69
75
|
} > PR_COMMENT.md
|
|
70
76
|
|
|
71
|
-
EXISTING_COMMENT_ID=$(gh api "repos
|
|
77
|
+
EXISTING_COMMENT_ID=$(gh api "repos/$REPO/issues/$PR_NUMBER/comments" --jq '.[] | select(.body | contains("<!-- chemical-x-audit-pr-comment -->")) | .id' | head -n 1)
|
|
72
78
|
|
|
73
79
|
if [ -n "$EXISTING_COMMENT_ID" ]; then
|
|
74
|
-
gh api --method PATCH "repos
|
|
80
|
+
gh api --method PATCH "repos/$REPO/issues/comments/$EXISTING_COMMENT_ID" -F body=@PR_COMMENT.md
|
|
75
81
|
else
|
|
76
|
-
gh pr comment "
|
|
82
|
+
gh pr comment "$PR_NUMBER" --body-file PR_COMMENT.md
|
|
77
83
|
fi
|
|
78
|
-
|
|
79
|
-
scaffold-smoke-test:
|
|
80
|
-
name: Framework Scaffolding Smoke Test
|
|
81
|
-
runs-on: ubuntu-latest
|
|
82
|
-
steps:
|
|
83
|
-
- name: Checkout Code
|
|
84
|
-
uses: actions/checkout@v4
|
|
85
|
-
- name: Setup Node.js
|
|
86
|
-
uses: actions/setup-node@v4
|
|
87
|
-
with:
|
|
88
|
-
node-version: 22
|
|
89
|
-
- name: Install Dependencies
|
|
90
|
-
run: npm install
|
|
91
|
-
- name: Run Test Suite
|
|
92
|
-
run: npm test
|
|
93
|
-
- name: Multi-Framework Scaffolding Smoke Test
|
|
94
|
-
run: |
|
|
95
|
-
for fw in react vue svelte; do
|
|
96
|
-
echo "Smoke testing scaffolding for framework: $fw"
|
|
97
|
-
node cli/create.js test-app-$fw --framework=$fw --yes --skip-install
|
|
98
|
-
if [ "$fw" = "react" ]; then
|
|
99
|
-
test -f test-app-react/src/components/m-sample-card/m-sample-card.tsx
|
|
100
|
-
! ls test-app-react/src/components/m-sample-card/*.vue 2>/dev/null
|
|
101
|
-
! ls test-app-react/src/components/m-sample-card/*.svelte 2>/dev/null
|
|
102
|
-
elif [ "$fw" = "vue" ]; then
|
|
103
|
-
test -f test-app-vue/src/components/m-sample-card/m-sample-card.vue
|
|
104
|
-
! ls test-app-vue/src/components/m-sample-card/*.tsx 2>/dev/null
|
|
105
|
-
! ls test-app-vue/src/components/m-sample-card/*.svelte 2>/dev/null
|
|
106
|
-
elif [ "$fw" = "svelte" ]; then
|
|
107
|
-
test -f test-app-svelte/src/components/m-sample-card/m-sample-card.svelte
|
|
108
|
-
! ls test-app-svelte/src/components/m-sample-card/*.vue 2>/dev/null
|
|
109
|
-
! ls test-app-svelte/src/components/m-sample-card/*.tsx 2>/dev/null
|
|
110
|
-
fi
|
|
111
|
-
echo "Framework $fw scaffolded cleanly."
|
|
112
|
-
done
|
|
113
|
-
|
|
114
|
-
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { stripAnsi } from './terminal.js';
|
|
2
|
+
|
|
3
|
+
// One serializer for every --json payload an agent reads (CLI and, via G3, MCP):
|
|
4
|
+
// minified, ANSI-free, no null fields. Diagnostic lists stay arrays (so `.errors|length`
|
|
5
|
+
// counts diagnostics whether there are none or many) of "file:line:col CODE message"
|
|
6
|
+
// strings, each shorter than the raw tool line it replaces. A report costs at most the raw
|
|
7
|
+
// output plus a fixed envelope (success, exitCode, command, durationMs, errorCount);
|
|
8
|
+
// cli/agent-json.spec.js pins both bounds.
|
|
9
|
+
|
|
10
|
+
const isDiagnosticRow = (item) =>
|
|
11
|
+
Boolean(item) && typeof item === 'object' && typeof item.file === 'string' && 'line' in item && 'message' in item;
|
|
12
|
+
|
|
13
|
+
const isDiagnosticList = (value) => Array.isArray(value) && value.length > 0 && value.every(isDiagnosticRow);
|
|
14
|
+
|
|
15
|
+
export const formatDiagnosticRow = (row) => {
|
|
16
|
+
const isWarning = String(row.severity ?? '').toUpperCase() === 'WARNING';
|
|
17
|
+
const position = [stripAnsi(row.file), row.line, row.column].filter((part) => part !== undefined && part !== null && part !== '').join(':');
|
|
18
|
+
const code = row.code ?? row.ruleId ?? row.rule ?? null;
|
|
19
|
+
const parts = [position, isWarning ? 'warning' : null, code, stripAnsi(String(row.message))];
|
|
20
|
+
return parts.filter(Boolean).join(' ');
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const compactValue = (value) => {
|
|
24
|
+
const isString = typeof value === 'string';
|
|
25
|
+
if (isString) return stripAnsi(value);
|
|
26
|
+
if (isDiagnosticList(value)) return value.map(formatDiagnosticRow);
|
|
27
|
+
if (Array.isArray(value)) return value.map(compactValue);
|
|
28
|
+
const isPlainObject = Boolean(value) && typeof value === 'object';
|
|
29
|
+
if (!isPlainObject) return value;
|
|
30
|
+
const compacted = {};
|
|
31
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
32
|
+
const isAbsent = entry === null || entry === undefined;
|
|
33
|
+
if (!isAbsent) compacted[key] = compactValue(entry);
|
|
34
|
+
}
|
|
35
|
+
return compacted;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const compactAgentPayload = (payload) => compactValue(payload);
|
|
39
|
+
|
|
40
|
+
export const formatAgentJson = (payload) => JSON.stringify(compactValue(payload));
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* applyEdits: the single mutation gate for write, patch, autofix, explode and add:*.
|
|
3
|
+
*
|
|
4
|
+
* Every edit is validated before anything touches disk:
|
|
5
|
+
* - the path stays inside the workspace (realpath containment, symlinked parents included);
|
|
6
|
+
* - the new text parses (Babel / SFC script blocks / JSON) unless the old text was already broken;
|
|
7
|
+
* - no top-level declaration disappears unless the caller named it in allowRemoved;
|
|
8
|
+
* - no other agent holds a team lock on the file.
|
|
9
|
+
* A dry run returns the same result (with an uncapped unified diff) and writes nothing.
|
|
10
|
+
* A real run writes each file atomically with a backup and rolls back the batch on failure.
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { resolveSafePath } from './path-scope.js';
|
|
17
|
+
import { parseSource } from './source-parse.js';
|
|
18
|
+
import { buildUnifiedDiff } from './edit-diff.js';
|
|
19
|
+
import { writeAtomic, removeWithBackup, restoreFromBackup } from './edit-atomic.js';
|
|
20
|
+
import { findForeignLease } from './edit-locks.js';
|
|
21
|
+
import { syncLeasesAfterEdit } from './team/lease-renew.js';
|
|
22
|
+
import { countLines } from './line-count.js';
|
|
23
|
+
|
|
24
|
+
export class EditRefusedError extends Error {
|
|
25
|
+
constructor(issues) {
|
|
26
|
+
super(issues.map((i) => `${i.file}: ${i.reason}`).join('\n'));
|
|
27
|
+
this.name = 'EditRefusedError';
|
|
28
|
+
this.issues = issues;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Declaration delta between two parses. Every top-level declaration that disappears must be
|
|
34
|
+
* named in allowRemoved (or allowRemoved === true), renames included: a patch that removes A
|
|
35
|
+
* and adds an unrelated B is exactly the wrong-block replace this gate exists to catch.
|
|
36
|
+
*/
|
|
37
|
+
const declarationDelta = (beforeParse, afterParse, allowRemoved) => {
|
|
38
|
+
const isComparable = beforeParse.ok && afterParse.ok && beforeParse.kind === 'babel';
|
|
39
|
+
if (!isComparable) return { removed: [], added: [], blocked: [] };
|
|
40
|
+
const beforeSet = new Set(beforeParse.declarations);
|
|
41
|
+
const afterSet = new Set(afterParse.declarations);
|
|
42
|
+
const removed = beforeParse.declarations.filter((name) => !afterSet.has(name));
|
|
43
|
+
const added = afterParse.declarations.filter((name) => !beforeSet.has(name));
|
|
44
|
+
const isAllAllowed = allowRemoved === true;
|
|
45
|
+
const allowed = new Set(Array.isArray(allowRemoved) ? allowRemoved : []);
|
|
46
|
+
const unallowed = isAllAllowed ? [] : removed.filter((name) => !allowed.has(name));
|
|
47
|
+
return { removed, added, blocked: unallowed };
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const V8_CHECKED_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* V8's own syntax check (node --check on a temp copy). Babel's parse does not report every
|
|
54
|
+
* early error V8 raises at import (redeclarations, duplicate exports, bad regex flags).
|
|
55
|
+
* Returns the first SyntaxError line, or null when V8 accepts the text or the check could not run
|
|
56
|
+
* (a failure to spawn node is not treated as a syntax error).
|
|
57
|
+
*/
|
|
58
|
+
const v8SyntaxError = (text, absPath, parse) => {
|
|
59
|
+
const ext = path.extname(absPath);
|
|
60
|
+
const isCheckedExtension = V8_CHECKED_EXTENSIONS.has(ext);
|
|
61
|
+
if (!isCheckedExtension) return null;
|
|
62
|
+
let dir = null;
|
|
63
|
+
try {
|
|
64
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'chemx-v8check-'));
|
|
65
|
+
// node --check on a .js file holding module syntax skips regex early errors, so the copy
|
|
66
|
+
// gets the extension that matches how Babel read the text.
|
|
67
|
+
const isModule = ext === '.mjs' || parse.programs?.[0]?.sourceType === 'module';
|
|
68
|
+
const isCommonJs = ext === '.cjs' || !isModule;
|
|
69
|
+
const checkExt = isCommonJs ? '.cjs' : '.mjs';
|
|
70
|
+
const tmp = path.join(dir, `check${checkExt}`);
|
|
71
|
+
fs.writeFileSync(tmp, text);
|
|
72
|
+
const res = spawnSync(process.execPath, ['--check', tmp], { encoding: 'utf-8', timeout: 15000 });
|
|
73
|
+
const isAccepted = Boolean(res.error) || res.status === 0;
|
|
74
|
+
if (isAccepted) return null;
|
|
75
|
+
const lines = String(res.stderr).split('\n');
|
|
76
|
+
const found = lines.find((l) => /^\w*Error: /.test(l));
|
|
77
|
+
return found || lines.find((l) => l.trim()) || 'unknown syntax error';
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
} finally {
|
|
81
|
+
if (dir) fs.rmSync(dir, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const lapsedIssue = (file, lease) => {
|
|
86
|
+
const at = new Date(lease.expiresAt).toISOString();
|
|
87
|
+
return `your lease on ${file} lapsed at ${at} and ${lease.queue.join(', ')} ${lease.queue.length > 1 ? 'are' : 'is'} queued for it, so it is theirs next and this edit was not made (queue: ${lease.queue.join(' > ')}; see: chemx team lock status ${file})`;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const lockedIssue = (file, lease) => {
|
|
91
|
+
const isLapsedOwn = Boolean(lease.lapsedOwn);
|
|
92
|
+
if (isLapsedOwn) return lapsedIssue(file, lease);
|
|
93
|
+
const purpose = lease.purpose ? ` (${lease.purpose})` : '';
|
|
94
|
+
const until = new Date(lease.expiresAt).toISOString();
|
|
95
|
+
return `locked by ${lease.lockedBy}${purpose} until ${until}; wait until ${lease.lockedBy} releases it or the lease expires (check: chemx team lock check ${file}; all locks: chemx team lock list)`;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const planEdit = (edit, root, options) => {
|
|
99
|
+
const absPath = resolveSafePath(edit.path, root);
|
|
100
|
+
const file = path.relative(root, absPath);
|
|
101
|
+
const isExisting = fs.existsSync(absPath);
|
|
102
|
+
const isDirectory = isExisting && fs.statSync(absPath).isDirectory();
|
|
103
|
+
if (isDirectory) return { file, absPath, issue: 'path is a directory' };
|
|
104
|
+
|
|
105
|
+
const before = isExisting ? fs.readFileSync(absPath, 'utf-8') : null;
|
|
106
|
+
const isDelete = Boolean(edit.delete);
|
|
107
|
+
const plan = { file, absPath, before, isDelete, created: !isExisting, deleted: isDelete };
|
|
108
|
+
const isDeletingNothing = isDelete && !isExisting;
|
|
109
|
+
if (isDeletingNothing) return { ...plan, issue: 'cannot delete a file that does not exist' };
|
|
110
|
+
const isMissingContent = !isDelete && typeof edit.content !== 'string';
|
|
111
|
+
if (isMissingContent) return { ...plan, issue: 'no content given' };
|
|
112
|
+
|
|
113
|
+
const after = isDelete ? '' : edit.content;
|
|
114
|
+
const lease = findForeignLease(root, absPath, options.agentId);
|
|
115
|
+
const isLocked = Boolean(lease);
|
|
116
|
+
if (isLocked) return { ...plan, issue: lockedIssue(file, lease) };
|
|
117
|
+
if (isDelete) return { ...plan, after, parse: { kind: 'n/a', ok: true }, declarations: { removed: [], added: [] } };
|
|
118
|
+
|
|
119
|
+
const afterParse = parseSource(after, absPath);
|
|
120
|
+
const beforeParse = before === null ? null : parseSource(before, absPath);
|
|
121
|
+
const wasBroken = Boolean(beforeParse) && !beforeParse.ok;
|
|
122
|
+
const isNewlyBroken = !afterParse.ok && !wasBroken;
|
|
123
|
+
if (isNewlyBroken) return { ...plan, after, issue: `result does not parse (${afterParse.error}); nothing was written` };
|
|
124
|
+
|
|
125
|
+
const v8Error = wasBroken ? null : v8SyntaxError(after, absPath, afterParse);
|
|
126
|
+
if (v8Error) return { ...plan, after, issue: `V8 rejects the result (${v8Error}); nothing was written` };
|
|
127
|
+
|
|
128
|
+
const delta = beforeParse ? declarationDelta(beforeParse, afterParse, edit.allowRemoved) : { removed: [], added: [], blocked: [] };
|
|
129
|
+
const hasBlockedRemovals = delta.blocked.length > 0;
|
|
130
|
+
if (hasBlockedRemovals) {
|
|
131
|
+
const hasAdded = delta.added.length > 0;
|
|
132
|
+
const addedNote = hasAdded ? ` (and would add ${delta.added.join(', ')})` : '';
|
|
133
|
+
return { ...plan, after, issue: `would remove top-level declaration(s) ${delta.blocked.join(', ')}${addedNote}; name them in allowRemoved (CLI: --allow-remove=${delta.blocked.join(',')}) if intended` };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const parse = { kind: afterParse.kind, ok: afterParse.ok, ...(wasBroken ? { note: 'file did not parse before this edit either, so the parse and declaration-removal checks could not run' } : {}) };
|
|
137
|
+
return { ...plan, after, parse, declarations: { removed: delta.removed, added: delta.added } };
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const commitPlans = (plans, root) => {
|
|
141
|
+
const done = [];
|
|
142
|
+
try {
|
|
143
|
+
for (const plan of plans) {
|
|
144
|
+
const isUnchanged = !plan.isDelete && plan.before === plan.after;
|
|
145
|
+
if (isUnchanged) continue;
|
|
146
|
+
const { backup } = plan.isDelete ? removeWithBackup(plan.absPath, root) : writeAtomic(plan.absPath, plan.after, root);
|
|
147
|
+
plan.backup = backup;
|
|
148
|
+
done.push(plan);
|
|
149
|
+
}
|
|
150
|
+
} catch (err) {
|
|
151
|
+
for (const plan of done.reverse()) restoreFromBackup(plan.absPath, plan.backup);
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @param {Array<{ path: string, content?: string, delete?: boolean, allowRemoved?: string[]|true }>} edits
|
|
158
|
+
* @param {object} [options] { cwd, dryRun, agentId }
|
|
159
|
+
* @returns {{ dryRun: boolean, files: object[], diff: string }}
|
|
160
|
+
* @throws {EditRefusedError} When any edit is refused (nothing is written).
|
|
161
|
+
*/
|
|
162
|
+
export const applyEdits = (edits, options = {}) => {
|
|
163
|
+
const rawRoot = options.cwd || process.cwd();
|
|
164
|
+
const root = fs.existsSync(rawRoot) ? fs.realpathSync(rawRoot) : path.resolve(rawRoot);
|
|
165
|
+
const dryRun = Boolean(options.dryRun);
|
|
166
|
+
const plans = edits.map((edit) => planEdit(edit, root, options));
|
|
167
|
+
const issues = plans.filter((p) => p.issue).map((p) => ({ file: p.file, reason: p.issue }));
|
|
168
|
+
const hasIssues = issues.length > 0;
|
|
169
|
+
if (hasIssues) throw new EditRefusedError(issues);
|
|
170
|
+
|
|
171
|
+
const isPreview = dryRun;
|
|
172
|
+
let leaseNotes = [];
|
|
173
|
+
if (!isPreview) {
|
|
174
|
+
commitPlans(plans, root);
|
|
175
|
+
// Renew-on-edit: a live lease of the caller's on a written file gets one more TTL; a lapsed,
|
|
176
|
+
// untaken one is re-acquired and the result says so.
|
|
177
|
+
leaseNotes = syncLeasesAfterEdit(root, plans.map((p) => p.absPath), options.agentId).notes;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const files = plans.map((p) => ({
|
|
181
|
+
file: p.file,
|
|
182
|
+
absPath: p.absPath,
|
|
183
|
+
created: p.created,
|
|
184
|
+
deleted: p.deleted,
|
|
185
|
+
changed: p.isDelete || p.before !== p.after,
|
|
186
|
+
originalLines: p.before === null ? 0 : countLines(p.before),
|
|
187
|
+
newLines: p.isDelete ? 0 : countLines(p.after),
|
|
188
|
+
parse: p.parse,
|
|
189
|
+
declarations: p.declarations,
|
|
190
|
+
backup: p.backup ? path.relative(root, p.backup) : null,
|
|
191
|
+
diff: buildUnifiedDiff(p.before ?? '', p.after, { path: p.file, isNew: p.created, isDeleted: p.isDelete })
|
|
192
|
+
}));
|
|
193
|
+
const noteField = leaseNotes.length > 0 ? { leaseNotes } : {};
|
|
194
|
+
return { dryRun, files, diff: files.map((f) => f.diff).filter(Boolean).join('\n'), ...noteField };
|
|
195
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as t from '@babel/types';
|
|
2
|
+
import { ruleTree } from '../rules.js';
|
|
2
3
|
import { RULE_REGISTRY } from './rules-registry.js';
|
|
3
4
|
import {
|
|
4
5
|
isComponentPath,
|
|
@@ -7,12 +8,17 @@ import {
|
|
|
7
8
|
hasAnyTypeAnnotation,
|
|
8
9
|
isRedundantPassthroughReturn
|
|
9
10
|
} from './rules-predicates.js';
|
|
11
|
+
import { resolveCatchEscalation, resolveCatchSpan } from './shallow-catch-escalation.js';
|
|
10
12
|
|
|
11
13
|
const RESIDUE_PATTERNS = [
|
|
12
14
|
['hope this', 'helps'].join(' '),
|
|
13
15
|
['feel free', 'to tweak'].join(' '),
|
|
14
16
|
['let me know', 'if you need'].join(' '),
|
|
15
|
-
|
|
17
|
+
// Assistant framing only (the phrase followed by a pause and "here"/"I"/"below",
|
|
18
|
+
// or addressed to "you"). The bare phrase in a sentence about an API client is
|
|
19
|
+
// ordinary engineering prose.
|
|
20
|
+
['as you', 'requested'].join(' '),
|
|
21
|
+
['as', 'requested[,.!:]\\s*(?:here|i\\b|below)'].join(' '),
|
|
16
22
|
['as an ai', 'language model'].join(' ')
|
|
17
23
|
];
|
|
18
24
|
|
|
@@ -81,19 +87,24 @@ const normalizeWords = (text) => {
|
|
|
81
87
|
const COMMENT_LINE_START = /^\s*(?:\/\/|#|\*|--)/;
|
|
82
88
|
|
|
83
89
|
const isInsideStringLiteral = (lineText, matchIndex) => {
|
|
84
|
-
|
|
85
|
-
if (
|
|
90
|
+
const isAtLineStart = matchIndex <= 0;
|
|
91
|
+
if (isAtLineStart) return false;
|
|
92
|
+
const isCommentLine = COMMENT_LINE_START.test(lineText);
|
|
93
|
+
if (isCommentLine) return false;
|
|
86
94
|
|
|
87
95
|
let quote = null;
|
|
88
96
|
for (let i = 0; i < matchIndex; i += 1) {
|
|
89
97
|
const ch = lineText[i];
|
|
90
|
-
|
|
98
|
+
const isEscape = ch === '\\';
|
|
99
|
+
if (isEscape) {
|
|
91
100
|
i += 1;
|
|
92
101
|
continue;
|
|
93
102
|
}
|
|
103
|
+
const closesQuote = ch === quote;
|
|
104
|
+
const opensQuote = ch === '"' || ch === "'" || ch === '`';
|
|
94
105
|
if (quote) {
|
|
95
|
-
if (
|
|
96
|
-
} else if (
|
|
106
|
+
if (closesQuote) quote = null;
|
|
107
|
+
} else if (opensQuote) {
|
|
97
108
|
quote = ch;
|
|
98
109
|
}
|
|
99
110
|
}
|
|
@@ -104,7 +115,8 @@ export const checkSlopTextPatterns = (content, lines, relativePath, violations)
|
|
|
104
115
|
lines.forEach((lineText, idx) => {
|
|
105
116
|
for (const pat of CONVERSATIONAL_PATTERNS) {
|
|
106
117
|
const hit = pat.regex.exec(lineText);
|
|
107
|
-
|
|
118
|
+
const isRealHit = Boolean(hit && !isInsideStringLiteral(lineText, hit.index));
|
|
119
|
+
if (isRealHit) {
|
|
108
120
|
const meta = RULE_REGISTRY[pat.rule];
|
|
109
121
|
violations.push({
|
|
110
122
|
filePath: relativePath,
|
|
@@ -122,11 +134,13 @@ export const checkSlopTextPatterns = (content, lines, relativePath, violations)
|
|
|
122
134
|
}
|
|
123
135
|
|
|
124
136
|
const trimmed = lineText.trim();
|
|
125
|
-
|
|
137
|
+
const isLineComment = trimmed.startsWith('//') && !trimmed.startsWith('///');
|
|
138
|
+
if (isLineComment) {
|
|
126
139
|
const commentBody = trimmed.replace(/^\/\/\s*/, '');
|
|
127
140
|
const commentWords = normalizeWords(commentBody);
|
|
128
141
|
|
|
129
|
-
|
|
142
|
+
const isShortComment = commentWords.length >= 2 && commentWords.length <= 6;
|
|
143
|
+
if (isShortComment) {
|
|
130
144
|
let nextIdx = idx + 1;
|
|
131
145
|
while (nextIdx < lines.length) {
|
|
132
146
|
const nextTrim = lines[nextIdx].trim();
|
|
@@ -134,10 +148,12 @@ export const checkSlopTextPatterns = (content, lines, relativePath, violations)
|
|
|
134
148
|
const nextWords = new Set(normalizeWords(nextTrim));
|
|
135
149
|
let matchCount = 0;
|
|
136
150
|
for (const cw of commentWords) {
|
|
137
|
-
|
|
151
|
+
const isEchoedWord = nextWords.has(cw);
|
|
152
|
+
if (isEchoedWord) matchCount += 1;
|
|
138
153
|
}
|
|
139
154
|
const matchRatio = matchCount / commentWords.length;
|
|
140
|
-
|
|
155
|
+
const isEcho = matchRatio >= 0.75;
|
|
156
|
+
if (isEcho) {
|
|
141
157
|
const meta = RULE_REGISTRY.AI_SLOP_ECHO_COMMENT;
|
|
142
158
|
violations.push({
|
|
143
159
|
filePath: relativePath,
|
|
@@ -169,15 +185,16 @@ export const createAiSlopVisitors = ({ relativePath, violations }) => {
|
|
|
169
185
|
const isShallowCatch = isShallowCatchBody(body, t);
|
|
170
186
|
|
|
171
187
|
if (isShallowCatch) {
|
|
172
|
-
const line = astPath.node.loc?.start.line || 1;
|
|
173
188
|
const meta = RULE_REGISTRY.AI_SLOP_SHALLOW_CATCH;
|
|
189
|
+
const { severity, binding } = resolveCatchEscalation(astPath);
|
|
174
190
|
violations.push({
|
|
175
191
|
filePath: relativePath,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
...resolveCatchSpan(astPath),
|
|
193
|
+
hazard: binding
|
|
194
|
+
? `Shallow catch leaves "${binding}" unset; it is read after the try (silent undefined propagation)`
|
|
195
|
+
: 'Shallow catch paranoia wrapper (silent suppression without handling)',
|
|
179
196
|
rule: 'AI_SLOP_SHALLOW_CATCH',
|
|
180
|
-
severity
|
|
197
|
+
severity,
|
|
181
198
|
pillar: meta.pillar,
|
|
182
199
|
directive: meta.directive,
|
|
183
200
|
isAiSlop: true
|
|
@@ -203,7 +220,8 @@ export const createAiSlopVisitors = ({ relativePath, violations }) => {
|
|
|
203
220
|
|
|
204
221
|
BlockStatement(astPath) {
|
|
205
222
|
const stmts = astPath.node.body;
|
|
206
|
-
|
|
223
|
+
const hasMultipleStatements = stmts.length >= 2;
|
|
224
|
+
if (hasMultipleStatements) {
|
|
207
225
|
for (let i = 0; i < stmts.length - 1; i++) {
|
|
208
226
|
const curr = stmts[i];
|
|
209
227
|
const next = stmts[i + 1];
|
|
@@ -230,7 +248,8 @@ export const createAiSlopVisitors = ({ relativePath, violations }) => {
|
|
|
230
248
|
FunctionDeclaration(astPath) {
|
|
231
249
|
if (!isComponentFile) return;
|
|
232
250
|
const fnName = astPath.node.id?.name?.toLowerCase();
|
|
233
|
-
|
|
251
|
+
const isReinventedFn = Boolean(fnName && REINVENTED_UTILS.has(fnName));
|
|
252
|
+
if (isReinventedFn) {
|
|
234
253
|
const line = astPath.node.loc?.start.line || 1;
|
|
235
254
|
const meta = RULE_REGISTRY.AI_SLOP_UTILITY_REINVENTION;
|
|
236
255
|
violations.push({
|
|
@@ -248,27 +267,35 @@ export const createAiSlopVisitors = ({ relativePath, violations }) => {
|
|
|
248
267
|
},
|
|
249
268
|
|
|
250
269
|
VariableDeclarator(astPath) {
|
|
251
|
-
if (!isComponentFile) return;
|
|
252
270
|
const idName = astPath.node.id?.name?.toLowerCase();
|
|
253
|
-
|
|
254
|
-
|
|
271
|
+
const isReinventedName = Boolean(idName && REINVENTED_UTILS.has(idName));
|
|
255
272
|
const initNode = astPath.node.init;
|
|
256
|
-
const isFunction = t.isArrowFunctionExpression(initNode) || t.isFunctionExpression(initNode);
|
|
257
|
-
|
|
273
|
+
const isFunction = Boolean(initNode && (t.isArrowFunctionExpression(initNode) || t.isFunctionExpression(initNode)));
|
|
274
|
+
|
|
275
|
+
const gate = ruleTree({
|
|
276
|
+
declarator: {
|
|
277
|
+
notComponent: !isComponentFile,
|
|
278
|
+
notReinvented: !isReinventedName,
|
|
279
|
+
notFunction: !isFunction
|
|
280
|
+
}
|
|
281
|
+
}, { failFast: true });
|
|
282
|
+
|
|
283
|
+
const isReinvented = gate.ok;
|
|
284
|
+
if (!isReinvented) return;
|
|
258
285
|
|
|
259
286
|
const line = astPath.node.loc?.start.line || 1;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
287
|
+
const meta = RULE_REGISTRY.AI_SLOP_UTILITY_REINVENTION;
|
|
288
|
+
violations.push({
|
|
289
|
+
filePath: relativePath,
|
|
290
|
+
line,
|
|
291
|
+
column: astPath.node.loc?.start.column || 1,
|
|
292
|
+
hazard: `Inline utility reinvention "${astPath.node.id.name}" in component capsule`,
|
|
293
|
+
rule: 'AI_SLOP_UTILITY_REINVENTION',
|
|
294
|
+
severity: meta.severity,
|
|
295
|
+
pillar: meta.pillar,
|
|
296
|
+
directive: meta.directive,
|
|
297
|
+
isAiSlop: true
|
|
298
|
+
});
|
|
272
299
|
}
|
|
273
300
|
};
|
|
274
301
|
};
|