@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.17
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/README.md +21 -1
- package/bin/aiwg.mjs +349 -0
- package/dist/src/a2a/agent-card.js +145 -0
- package/dist/src/a2a/client.js +411 -0
- package/dist/src/a2a/hitl-cli.js +171 -0
- package/dist/src/a2a/hitl-driver.js +370 -0
- package/dist/src/a2a/hitl.js +181 -0
- package/dist/src/a2a/http.js +193 -0
- package/dist/src/a2a/jcs.js +128 -0
- package/dist/src/a2a/jws.js +187 -0
- package/dist/src/a2a/types.js +24 -0
- package/dist/src/a2a/webhook.js +240 -0
- package/dist/src/activity-log/cli.js +348 -0
- package/dist/src/activity-log/parser.js +81 -0
- package/dist/src/activity-log/types.js +50 -0
- package/dist/src/agents/agent-deployer.js +367 -0
- package/dist/src/agents/agent-packager.js +271 -0
- package/dist/src/agents/agent-validator.js +271 -0
- package/dist/src/agents/grounding/knowledge-base.js +161 -0
- package/dist/src/agents/grounding/types.js +12 -0
- package/dist/src/agents/index.js +10 -0
- package/dist/src/agents/packaged-agent-inventory.js +75 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/api/index.d.ts +10 -0
- package/dist/src/api/index.js +10 -0
- package/dist/src/artifacts/address-parser.js +73 -0
- package/dist/src/artifacts/audit/cli.js +183 -0
- package/dist/src/artifacts/audit/drift.js +122 -0
- package/dist/src/artifacts/audit/types.js +12 -0
- package/dist/src/artifacts/backends/graphology-backend.js +160 -0
- package/dist/src/artifacts/backends/json-backend.js +129 -0
- package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
- package/dist/src/artifacts/browser-export.js +622 -0
- package/dist/src/artifacts/capability-resolver.js +94 -0
- package/dist/src/artifacts/checksum-manifest.js +91 -0
- package/dist/src/artifacts/citation-parser.js +162 -0
- package/dist/src/artifacts/cli.js +1462 -0
- package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
- package/dist/src/artifacts/corpus-tools/cli.js +393 -0
- package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
- package/dist/src/artifacts/corpus-tools/curator.js +186 -0
- package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
- package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
- package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
- package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
- package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
- package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
- package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
- package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
- package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
- package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
- package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
- package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
- package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
- package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
- package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
- package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
- package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
- package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
- package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
- package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
- package/dist/src/artifacts/corpus-views/build.js +126 -0
- package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
- package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
- package/dist/src/artifacts/corpus-views/renderers.js +353 -0
- package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
- package/dist/src/artifacts/dep-graph.js +173 -0
- package/dist/src/artifacts/discover-facets.js +375 -0
- package/dist/src/artifacts/embedding-index.js +354 -0
- package/dist/src/artifacts/enrichment/cli.js +240 -0
- package/dist/src/artifacts/enrichment/prompt.js +47 -0
- package/dist/src/artifacts/enrichment/store.js +90 -0
- package/dist/src/artifacts/enrichment/types.js +12 -0
- package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
- package/dist/src/artifacts/fortemi-core-sync.js +251 -0
- package/dist/src/artifacts/fortemi-shard-export.js +44 -0
- package/dist/src/artifacts/fulltext.js +108 -0
- package/dist/src/artifacts/graph-backend.js +51 -0
- package/dist/src/artifacts/graph-query.js +247 -0
- package/dist/src/artifacts/hybrid-query.js +225 -0
- package/dist/src/artifacts/index-builder.js +1089 -0
- package/dist/src/artifacts/index-reader.js +112 -0
- package/dist/src/artifacts/index-status.js +193 -0
- package/dist/src/artifacts/legacy-index-migration.js +169 -0
- package/dist/src/artifacts/move.js +154 -0
- package/dist/src/artifacts/operational-state.js +239 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
- package/dist/src/artifacts/query-engine.js +1955 -0
- package/dist/src/artifacts/source-graph.js +529 -0
- package/dist/src/artifacts/stats.js +169 -0
- package/dist/src/artifacts/types.js +606 -0
- package/dist/src/artifacts/views/cli.js +293 -0
- package/dist/src/artifacts/views/definition.js +170 -0
- package/dist/src/artifacts/views/store.js +149 -0
- package/dist/src/artifacts/views/types.js +8 -0
- package/dist/src/artifacts/watcher.js +255 -0
- package/dist/src/catalog/builtin-models.json +636 -0
- package/dist/src/catalog/cli.js +228 -0
- package/dist/src/catalog/cli.mjs +289 -0
- package/dist/src/catalog/index.js +15 -0
- package/dist/src/catalog/loader.js +217 -0
- package/dist/src/catalog/loader.mjs +251 -0
- package/dist/src/catalog/sources.json +41 -0
- package/dist/src/catalog/types.js +8 -0
- package/dist/src/channel/manager.mjs +504 -0
- package/dist/src/cli/agent-spawn.js +178 -0
- package/dist/src/cli/cli-extension-loader.js +245 -0
- package/dist/src/cli/command-log.js +275 -0
- package/dist/src/cli/config-loader.js +232 -0
- package/dist/src/cli/env.js +82 -0
- package/dist/src/cli/errors.js +150 -0
- package/dist/src/cli/find-package-root.js +40 -0
- package/dist/src/cli/git-hooks.js +250 -0
- package/dist/src/cli/handlers/agentcard.js +206 -0
- package/dist/src/cli/handlers/artifacts.js +76 -0
- package/dist/src/cli/handlers/best-practices-audit.js +280 -0
- package/dist/src/cli/handlers/cockpit.js +137 -0
- package/dist/src/cli/handlers/command-log.js +37 -0
- package/dist/src/cli/handlers/daemon.js +59 -0
- package/dist/src/cli/handlers/diagnose.js +300 -0
- package/dist/src/cli/handlers/execution-mode.js +105 -0
- package/dist/src/cli/handlers/feedback.js +341 -0
- package/dist/src/cli/handlers/help.js +147 -0
- package/dist/src/cli/handlers/index.js +302 -0
- package/dist/src/cli/handlers/init.js +179 -0
- package/dist/src/cli/handlers/install.js +129 -0
- package/dist/src/cli/handlers/issues.js +46 -0
- package/dist/src/cli/handlers/lint.js +42 -0
- package/dist/src/cli/handlers/local-executor.js +315 -0
- package/dist/src/cli/handlers/marketplace.js +168 -0
- package/dist/src/cli/handlers/mc.js +1010 -0
- package/dist/src/cli/handlers/models.js +352 -0
- package/dist/src/cli/handlers/packages.js +155 -0
- package/dist/src/cli/handlers/ralph-launcher.js +717 -0
- package/dist/src/cli/handlers/ralph.js +575 -0
- package/dist/src/cli/handlers/refresh.js +432 -0
- package/dist/src/cli/handlers/regenerate.js +336 -0
- package/dist/src/cli/handlers/repo-access.js +109 -0
- package/dist/src/cli/handlers/run.js +165 -0
- package/dist/src/cli/handlers/runtime-info.js +301 -0
- package/dist/src/cli/handlers/sandbox.js +197 -0
- package/dist/src/cli/handlers/scaffolding.js +149 -0
- package/dist/src/cli/handlers/script-runner.js +121 -0
- package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
- package/dist/src/cli/handlers/serve.js +1835 -0
- package/dist/src/cli/handlers/session.js +348 -0
- package/dist/src/cli/handlers/setup.js +440 -0
- package/dist/src/cli/handlers/skill-lint.js +367 -0
- package/dist/src/cli/handlers/skill-usage.js +74 -0
- package/dist/src/cli/handlers/steward.js +567 -0
- package/dist/src/cli/handlers/subcommands.js +1702 -0
- package/dist/src/cli/handlers/team.js +337 -0
- package/dist/src/cli/handlers/types.js +11 -0
- package/dist/src/cli/handlers/use.js +2772 -0
- package/dist/src/cli/handlers/utilities.js +703 -0
- package/dist/src/cli/handlers/version.js +134 -0
- package/dist/src/cli/handlers/workspace-context.js +93 -0
- package/dist/src/cli/handlers/workspace.js +126 -0
- package/dist/src/cli/help-generator.js +178 -0
- package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
- package/dist/src/cli/hooks/executor.js +96 -0
- package/dist/src/cli/hooks/index.js +15 -0
- package/dist/src/cli/hooks/registry.js +143 -0
- package/dist/src/cli/hooks/types.js +13 -0
- package/dist/src/cli/log.js +492 -0
- package/dist/src/cli/project-isolation/detect.js +70 -0
- package/dist/src/cli/project-isolation/index.js +7 -0
- package/dist/src/cli/project-isolation/signals.js +17 -0
- package/dist/src/cli/project-isolation/warning.js +102 -0
- package/dist/src/cli/prompt-utils.js +155 -0
- package/dist/src/cli/provider-deployment-plan.js +126 -0
- package/dist/src/cli/provider-resolution.js +119 -0
- package/dist/src/cli/router.js +305 -0
- package/dist/src/cli/scope-resolver.js +392 -0
- package/dist/src/cli/skill-usage.js +616 -0
- package/dist/src/cli/ui.js +224 -0
- package/dist/src/cli/watch-service.js +203 -0
- package/dist/src/cli/workflow-orchestrator.js +478 -0
- package/dist/src/cli/workspace-signals.js +321 -0
- package/dist/src/community/footer.js +14 -0
- package/dist/src/community/links.js +123 -0
- package/dist/src/community/milestones.js +46 -0
- package/dist/src/community/nudge-policy.js +93 -0
- package/dist/src/config/aiwg-config.js +883 -0
- package/dist/src/config/cli.js +703 -0
- package/dist/src/config/gitignore.js +156 -0
- package/dist/src/config/project-artifacts.js +76 -0
- package/dist/src/config/user-config.js +428 -0
- package/dist/src/config/user-registry.js +127 -0
- package/dist/src/config/workspace.js +276 -0
- package/dist/src/contributors/detect.js +39 -0
- package/dist/src/contributors/discover.js +172 -0
- package/dist/src/contributors/heuristic.js +186 -0
- package/dist/src/contributors/index.js +11 -0
- package/dist/src/contributors/types.js +13 -0
- package/dist/src/contributors/validation.js +116 -0
- package/dist/src/data/community.schema.json +43 -0
- package/dist/src/data/community.yaml +16 -0
- package/dist/src/extensions/capability-index.js +270 -0
- package/dist/src/extensions/claude-hooks-installer.js +268 -0
- package/dist/src/extensions/commands/definitions.js +3485 -0
- package/dist/src/extensions/deployment-registration.js +463 -0
- package/dist/src/extensions/index.js +22 -0
- package/dist/src/extensions/loader.js +132 -0
- package/dist/src/extensions/managed-marker.js +100 -0
- package/dist/src/extensions/manifest.js +196 -0
- package/dist/src/extensions/project-local-activity.js +114 -0
- package/dist/src/extensions/project-local-discovery.js +261 -0
- package/dist/src/extensions/project-local-doctor.js +281 -0
- package/dist/src/extensions/project-local-gitignore.js +176 -0
- package/dist/src/extensions/project-local-paths.js +121 -0
- package/dist/src/extensions/project-local-promote.js +218 -0
- package/dist/src/extensions/project-local-remove.js +373 -0
- package/dist/src/extensions/project-local-scaffold.js +252 -0
- package/dist/src/extensions/project-quickref.js +291 -0
- package/dist/src/extensions/registry.js +368 -0
- package/dist/src/extensions/shadow-resolver.js +271 -0
- package/dist/src/extensions/types.js +86 -0
- package/dist/src/extensions/upstream-registry.js +195 -0
- package/dist/src/extensions/validation.js +631 -0
- package/dist/src/features/catalog.js +88 -0
- package/dist/src/features/cli.js +197 -0
- package/dist/src/features/installer.js +57 -0
- package/dist/src/features/paths.js +14 -0
- package/dist/src/features/runtime.js +21 -0
- package/dist/src/features/status.js +134 -0
- package/dist/src/hooks/laziness-detection.js +532 -0
- package/dist/src/intake/git-history-analyzer.js +486 -0
- package/dist/src/intake/index.js +9 -0
- package/dist/src/issues/cli.js +327 -0
- package/dist/src/issues/index.js +5 -0
- package/dist/src/issues/live.js +154 -0
- package/dist/src/issues/local.js +666 -0
- package/dist/src/issues/sync.js +143 -0
- package/dist/src/issues/types.js +2 -0
- package/dist/src/issues/workflows.js +164 -0
- package/dist/src/kb/cli.js +173 -0
- package/dist/src/lint/cli.js +171 -0
- package/dist/src/lint/loader.js +225 -0
- package/dist/src/lint/reporters.js +141 -0
- package/dist/src/lint/runner.js +364 -0
- package/dist/src/lint/types.js +10 -0
- package/dist/src/marketplace/cache.js +110 -0
- package/dist/src/marketplace/identifier.js +63 -0
- package/dist/src/marketplace/registry.js +36 -0
- package/dist/src/marketplace/sources/clawhub.js +53 -0
- package/dist/src/marketplace/sources/git.js +45 -0
- package/dist/src/marketplace/types.js +9 -0
- package/dist/src/mcp/adapters/codex-runtime.js +224 -0
- package/dist/src/mcp/cli.mjs +1197 -0
- package/dist/src/mcp/elicitation.mjs +149 -0
- package/dist/src/mcp/helpers.mjs +287 -0
- package/dist/src/mcp/index.mjs +11 -0
- package/dist/src/mcp/profiles.js +263 -0
- package/dist/src/mcp/profiles.mjs +360 -0
- package/dist/src/mcp/registry.js +376 -0
- package/dist/src/mcp/registry.mjs +387 -0
- package/dist/src/mcp/server.mjs +633 -0
- package/dist/src/mcp/test-simple.mjs +271 -0
- package/dist/src/mcp/tools/command-run.mjs +101 -0
- package/dist/src/mcp/tools/discovery.mjs +291 -0
- package/dist/src/mcp/tools/interaction.mjs +87 -0
- package/dist/src/mcp/tools/orchestration.mjs +320 -0
- package/dist/src/mcp/tools/subsystems.mjs +640 -0
- package/dist/src/memory/cli.js +166 -0
- package/dist/src/memory/project-registry.js +282 -0
- package/dist/src/metrics/artifact-metrics.js +184 -0
- package/dist/src/metrics/context-budget.js +174 -0
- package/dist/src/metrics/token-counter.js +133 -0
- package/dist/src/models/config-loader.js +228 -0
- package/dist/src/models/index.js +22 -0
- package/dist/src/models/model-capabilities.v1.json +120 -0
- package/dist/src/models/model-catalog.v1.json +96 -0
- package/dist/src/models/model-discovery.js +521 -0
- package/dist/src/models/provider-models.js +73 -0
- package/dist/src/models/provider-policy.js +273 -0
- package/dist/src/models/resolver.js +245 -0
- package/dist/src/models/router.js +70 -0
- package/dist/src/models/types.js +8 -0
- package/dist/src/models/wrapper-deployment.js +178 -0
- package/dist/src/models/wrapper-route.js +54 -0
- package/dist/src/ops/cli.js +268 -0
- package/dist/src/ops/registry.js +623 -0
- package/dist/src/packages/adapters/clawhub.js +113 -0
- package/dist/src/packages/adapters/git.js +153 -0
- package/dist/src/packages/adapters/gitea.js +93 -0
- package/dist/src/packages/adapters/github.js +69 -0
- package/dist/src/packages/adapters/local-cache.js +89 -0
- package/dist/src/packages/package-registry.js +143 -0
- package/dist/src/packages/registry.js +238 -0
- package/dist/src/packages/types.js +11 -0
- package/dist/src/plugin/cross-framework-ops.js +475 -0
- package/dist/src/plugin/framework-config-loader.js +235 -0
- package/dist/src/plugin/framework-detector.js +186 -0
- package/dist/src/plugin/framework-isolator.js +341 -0
- package/dist/src/plugin/framework-migration.js +371 -0
- package/dist/src/plugin/metadata-validator.js +906 -0
- package/dist/src/plugin/plugin-installer.js +436 -0
- package/dist/src/plugin/plugin-status.js +369 -0
- package/dist/src/plugin/plugin-uninstaller.js +473 -0
- package/dist/src/plugin/registry-validator.js +344 -0
- package/dist/src/plugin/skill-command-translator.js +415 -0
- package/dist/src/plugin/workspace-creator.js +189 -0
- package/dist/src/plugin/workspace-migrator.js +821 -0
- package/dist/src/policy/authorization.js +390 -0
- package/dist/src/policy/repo-access.js +215 -0
- package/dist/src/provenance/cli.js +16 -0
- package/dist/src/providers/capability-matrix.js +300 -0
- package/dist/src/providers/capability-matrix.yaml +514 -0
- package/dist/src/providers/provider-definitions.js +977 -0
- package/dist/src/providers/provider-definitions.mjs +159 -0
- package/dist/src/providers/provider-inventory.js +169 -0
- package/dist/src/quality/feedback-ab.js +174 -0
- package/dist/src/quality/feedback-collector.js +176 -0
- package/dist/src/quality/feedback-tracker.js +123 -0
- package/dist/src/quality/patterns/adr.json +24 -0
- package/dist/src/quality/patterns/sad.json +24 -0
- package/dist/src/quality/patterns/test-plan.json +24 -0
- package/dist/src/quality/patterns/use-case.json +24 -0
- package/dist/src/quality/scoring.js +157 -0
- package/dist/src/reflections/cli.js +15 -0
- package/dist/src/release/plan.js +139 -0
- package/dist/src/research/cache/manager.js +227 -0
- package/dist/src/research/clients/arxiv.js +156 -0
- package/dist/src/research/clients/base.js +197 -0
- package/dist/src/research/clients/crossref.js +112 -0
- package/dist/src/research/clients/semantic-scholar.js +126 -0
- package/dist/src/research/clients/unpaywall.js +87 -0
- package/dist/src/research/index.js +14 -0
- package/dist/src/research/query-cli.js +336 -0
- package/dist/src/research/services/acquisition.js +313 -0
- package/dist/src/research/services/archival.js +225 -0
- package/dist/src/research/services/citation.js +279 -0
- package/dist/src/research/services/discovery.js +243 -0
- package/dist/src/research/services/documentation.js +269 -0
- package/dist/src/research/services/index.js +14 -0
- package/dist/src/research/services/provenance.js +279 -0
- package/dist/src/research/services/quality.js +370 -0
- package/dist/src/research/services/types.js +7 -0
- package/dist/src/research/storage-cli.js +20 -0
- package/dist/src/research/types.js +47 -0
- package/dist/src/resources/index.d.ts +2 -0
- package/dist/src/resources/index.js +2 -0
- package/dist/src/resources/web-release.d.ts +89 -0
- package/dist/src/resources/web-release.js +882 -0
- package/dist/src/rlm/cache/cli.js +162 -0
- package/dist/src/rlm/cache/hash.js +35 -0
- package/dist/src/rlm/cache/store.js +170 -0
- package/dist/src/rlm/cache/types.js +8 -0
- package/dist/src/rlm/cli.js +650 -0
- package/dist/src/serve/a2a-terminal-observer.js +120 -0
- package/dist/src/serve/agent-router.js +205 -0
- package/dist/src/serve/dispatch-router.js +171 -0
- package/dist/src/serve/executor-registry.js +715 -0
- package/dist/src/serve/mission-conductor.js +177 -0
- package/dist/src/serve/orchestrator-adapter.js +113 -0
- package/dist/src/serve/orchestrator-override.js +94 -0
- package/dist/src/serve/orchestrator-pty.js +133 -0
- package/dist/src/serve/pty-bridge.js +799 -0
- package/dist/src/serve/sandbox-registry.js +832 -0
- package/dist/src/serve/screen-reader.js +228 -0
- package/dist/src/serve/stack-adapters.js +68 -0
- package/dist/src/serve/telemetry.js +143 -0
- package/dist/src/skills/adapters/clawhub.js +250 -0
- package/dist/src/skills/adapters/local.js +335 -0
- package/dist/src/skills/adapters/openclaw.js +316 -0
- package/dist/src/skills/cli.js +334 -0
- package/dist/src/skills/registry.js +117 -0
- package/dist/src/skills/run.js +259 -0
- package/dist/src/skills/runtime.js +94 -0
- package/dist/src/skills/types.js +10 -0
- package/dist/src/smiths/agentsmith/demo.js +116 -0
- package/dist/src/smiths/agentsmith/examples.js +300 -0
- package/dist/src/smiths/agentsmith/generator.js +503 -0
- package/dist/src/smiths/agentsmith/index.js +11 -0
- package/dist/src/smiths/agentsmith/types.js +8 -0
- package/dist/src/smiths/commandsmith/example.js +220 -0
- package/dist/src/smiths/commandsmith/generator.js +288 -0
- package/dist/src/smiths/commandsmith/index.js +41 -0
- package/dist/src/smiths/commandsmith/templates.js +296 -0
- package/dist/src/smiths/commandsmith/types.js +7 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
- package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
- package/dist/src/smiths/context-pipeline/discovery.js +187 -0
- package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
- package/dist/src/smiths/context-pipeline/finalization.js +147 -0
- package/dist/src/smiths/context-pipeline/generator.js +477 -0
- package/dist/src/smiths/context-pipeline/index.js +30 -0
- package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
- package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
- package/dist/src/smiths/context-pipeline/overflow.js +212 -0
- package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
- package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
- package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
- package/dist/src/smiths/context-pipeline/types.js +23 -0
- package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
- package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
- package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
- package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
- package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
- package/dist/src/smiths/hook-bridge/index.js +79 -0
- package/dist/src/smiths/hook-bridge/loader.js +116 -0
- package/dist/src/smiths/hook-bridge/shim.js +89 -0
- package/dist/src/smiths/hook-bridge/types.js +31 -0
- package/dist/src/smiths/index.js +39 -0
- package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
- package/dist/src/smiths/mcpsmith/example.js +119 -0
- package/dist/src/smiths/mcpsmith/generator.js +236 -0
- package/dist/src/smiths/mcpsmith/index.js +17 -0
- package/dist/src/smiths/mcpsmith/types.js +10 -0
- package/dist/src/smiths/platform-paths.js +101 -0
- package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
- package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
- package/dist/src/smiths/skillsmith/demo.js +83 -0
- package/dist/src/smiths/skillsmith/examples.js +161 -0
- package/dist/src/smiths/skillsmith/generator.js +316 -0
- package/dist/src/smiths/skillsmith/index.js +12 -0
- package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
- package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
- package/dist/src/smiths/skillsmith/types.js +9 -0
- package/dist/src/smiths/toolsmith/index.js +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
- package/dist/src/smiths/toolsmith/types.js +8 -0
- package/dist/src/storage/backends/fortemi.js +227 -0
- package/dist/src/storage/backends/fs.js +134 -0
- package/dist/src/storage/backends/logseq.js +309 -0
- package/dist/src/storage/backends/obsidian.js +233 -0
- package/dist/src/storage/cli.js +468 -0
- package/dist/src/storage/config.js +272 -0
- package/dist/src/storage/index.js +108 -0
- package/dist/src/storage/subsystem-cli.js +201 -0
- package/dist/src/storage/types.js +33 -0
- package/dist/src/testing/corpus/corpus-builder.js +383 -0
- package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
- package/dist/src/testing/corpus/index.js +10 -0
- package/dist/src/testing/fixtures/index.js +9 -0
- package/dist/src/testing/fixtures/test-data-factory.js +472 -0
- package/dist/src/testing/generators/index.js +11 -0
- package/dist/src/testing/generators/test-case-generator.js +393 -0
- package/dist/src/testing/generators/test-code-generator.js +384 -0
- package/dist/src/testing/generators/use-case-parser.js +325 -0
- package/dist/src/testing/index.js +11 -0
- package/dist/src/tracker/capability-protocol.js +118 -0
- package/dist/src/update/checker.mjs +396 -0
- package/dist/src/update/notifier.mjs +235 -0
- package/dist/src/writing/content-diversifier.js +804 -0
- package/dist/src/writing/example-generator.js +959 -0
- package/dist/src/writing/example-templates.js +99 -0
- package/dist/src/writing/pattern-library.js +486 -0
- package/dist/src/writing/patterns/banned-phrases.json +4413 -0
- package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
- package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
- package/dist/src/writing/patterns/hedging-language.json +2096 -0
- package/dist/src/writing/patterns/transition-words.json +1285 -0
- package/dist/src/writing/patterns/weak-verbs.json +1112 -0
- package/dist/src/writing/prompt-optimizer.js +660 -0
- package/dist/src/writing/prompt-templates.js +583 -0
- package/dist/src/writing/scoring-config-loader.js +168 -0
- package/dist/src/writing/validation-engine.js +595 -0
- package/dist/src/writing/validation-rules.js +380 -0
- package/dist/src/writing/voice-analyzer.js +439 -0
- package/dist/src/writing/voice-calibration.js +661 -0
- package/dist/src/writing/voice-profiles.json +588 -0
- package/package.json +64 -9
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writing Validation Engine
|
|
3
|
+
*
|
|
4
|
+
* Core validation engine that scans text for AI detection patterns, banned phrases,
|
|
5
|
+
* and authenticity markers. Provides comprehensive scoring and issue reporting.
|
|
6
|
+
*
|
|
7
|
+
* @implements @.aiwg/requirements/use-cases/UC-001-validate-ai-generated-content.md
|
|
8
|
+
* @architecture @.aiwg/architecture/software-architecture-doc.md - Section 5.1 WritingValidator
|
|
9
|
+
* @nfr @.aiwg/requirements/nfr-modules/performance.md - NFR-PERF-001 (<60s validation)
|
|
10
|
+
* @nfr @.aiwg/requirements/nfr-modules/accuracy.md - NFR-ACC-001 (<5% false positives)
|
|
11
|
+
* @tests @test/unit/writing/validation-engine.test.ts
|
|
12
|
+
* @depends @src/writing/validation-rules.ts
|
|
13
|
+
* @depends @src/writing/pattern-library.ts
|
|
14
|
+
*/
|
|
15
|
+
import { readFile } from 'fs/promises';
|
|
16
|
+
import { existsSync } from 'fs';
|
|
17
|
+
import { ValidationRuleLoader } from './validation-rules.js';
|
|
18
|
+
import { loadScoringConfig, getScoringConfig } from './scoring-config-loader.js';
|
|
19
|
+
/**
|
|
20
|
+
* Core Writing Validation Engine
|
|
21
|
+
*/
|
|
22
|
+
export class WritingValidationEngine {
|
|
23
|
+
ruleLoader;
|
|
24
|
+
ruleSet = null;
|
|
25
|
+
initialized = false;
|
|
26
|
+
constructor(guideBasePath) {
|
|
27
|
+
this.ruleLoader = new ValidationRuleLoader(guideBasePath);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the engine by loading rules
|
|
31
|
+
*/
|
|
32
|
+
async initialize() {
|
|
33
|
+
if (this.initialized) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Load scoring configuration
|
|
37
|
+
await loadScoringConfig();
|
|
38
|
+
try {
|
|
39
|
+
this.ruleSet = await this.ruleLoader.loadRuleSet();
|
|
40
|
+
// If loaded rules are empty (files not found), use defaults
|
|
41
|
+
if (this.ruleSet.bannedPhrases.length === 0 &&
|
|
42
|
+
this.ruleSet.aiPatterns.length === 0 &&
|
|
43
|
+
this.ruleSet.structuralPatterns.length === 0) {
|
|
44
|
+
this.ruleSet = this.ruleLoader.getDefaultRules();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Fall back to default rules if guide is not available
|
|
49
|
+
console.warn('Failed to load AIWG rules, using defaults:', error);
|
|
50
|
+
this.ruleSet = this.ruleLoader.getDefaultRules();
|
|
51
|
+
}
|
|
52
|
+
this.initialized = true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validate content and return comprehensive results
|
|
56
|
+
*/
|
|
57
|
+
async validate(content, context) {
|
|
58
|
+
await this.initialize();
|
|
59
|
+
const issues = [];
|
|
60
|
+
// Run all detections
|
|
61
|
+
issues.push(...this.detectBannedPhrases(content, context));
|
|
62
|
+
issues.push(...this.detectAIPatterns(content, context));
|
|
63
|
+
issues.push(...this.detectFormulicStructures(content));
|
|
64
|
+
// Analyze authenticity
|
|
65
|
+
const authenticityAnalysis = this.analyzeAuthenticity(content);
|
|
66
|
+
// Check for missing authenticity markers
|
|
67
|
+
if (authenticityAnalysis.missingMarkers.length > 0) {
|
|
68
|
+
issues.push({
|
|
69
|
+
type: 'missing_authenticity',
|
|
70
|
+
severity: 'info',
|
|
71
|
+
message: 'Content lacks authenticity markers',
|
|
72
|
+
location: { start: 0, end: 0, line: 1, column: 1 },
|
|
73
|
+
suggestion: `Consider adding: ${authenticityAnalysis.missingMarkers.join(', ')}`,
|
|
74
|
+
context: authenticityAnalysis.missingMarkers.slice(0, 3).join('; ')
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Calculate summary
|
|
78
|
+
const summary = this.calculateSummary(content, issues, authenticityAnalysis);
|
|
79
|
+
// Generate overall score
|
|
80
|
+
const score = this.calculateOverallScore(summary, authenticityAnalysis);
|
|
81
|
+
// Generate actionable suggestions
|
|
82
|
+
const suggestions = this.generateSuggestions(issues, authenticityAnalysis, summary);
|
|
83
|
+
return {
|
|
84
|
+
score,
|
|
85
|
+
issues,
|
|
86
|
+
summary,
|
|
87
|
+
suggestions,
|
|
88
|
+
humanMarkers: authenticityAnalysis.humanMarkers,
|
|
89
|
+
aiTells: authenticityAnalysis.aiTells
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Validate a file
|
|
94
|
+
*/
|
|
95
|
+
async validateFile(filePath, context) {
|
|
96
|
+
if (!existsSync(filePath)) {
|
|
97
|
+
throw new Error(`File not found: ${filePath}`);
|
|
98
|
+
}
|
|
99
|
+
const content = await readFile(filePath, 'utf-8');
|
|
100
|
+
return this.validate(content, context);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Validate multiple files in batch
|
|
104
|
+
*/
|
|
105
|
+
async validateBatch(files, context) {
|
|
106
|
+
const results = new Map();
|
|
107
|
+
// Process in parallel
|
|
108
|
+
await Promise.all(files.map(async (file) => {
|
|
109
|
+
try {
|
|
110
|
+
const result = await this.validateFile(file, context);
|
|
111
|
+
results.set(file, result);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error(`Failed to validate ${file}:`, error);
|
|
115
|
+
}
|
|
116
|
+
}));
|
|
117
|
+
return results;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Detect banned phrases in content
|
|
121
|
+
*/
|
|
122
|
+
detectBannedPhrases(content, context) {
|
|
123
|
+
if (!this.ruleSet) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
const issues = [];
|
|
127
|
+
let rules = this.ruleSet.bannedPhrases;
|
|
128
|
+
if (context) {
|
|
129
|
+
rules = this.ruleLoader.filterByContext(rules, context);
|
|
130
|
+
}
|
|
131
|
+
for (const rule of rules) {
|
|
132
|
+
const matches = this.findPatternMatches(content, rule.pattern);
|
|
133
|
+
for (const match of matches) {
|
|
134
|
+
issues.push({
|
|
135
|
+
type: 'banned_phrase',
|
|
136
|
+
severity: rule.severity,
|
|
137
|
+
message: rule.message,
|
|
138
|
+
location: match.location,
|
|
139
|
+
suggestion: rule.suggestion,
|
|
140
|
+
context: match.context,
|
|
141
|
+
ruleId: rule.id
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return issues;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Detect AI writing patterns
|
|
149
|
+
*/
|
|
150
|
+
detectAIPatterns(content, context) {
|
|
151
|
+
if (!this.ruleSet) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
const issues = [];
|
|
155
|
+
let rules = this.ruleSet.aiPatterns;
|
|
156
|
+
if (context) {
|
|
157
|
+
rules = this.ruleLoader.filterByContext(rules, context);
|
|
158
|
+
}
|
|
159
|
+
for (const rule of rules) {
|
|
160
|
+
const matches = this.findPatternMatches(content, rule.pattern);
|
|
161
|
+
for (const match of matches) {
|
|
162
|
+
issues.push({
|
|
163
|
+
type: 'ai_pattern',
|
|
164
|
+
severity: rule.severity,
|
|
165
|
+
message: rule.message,
|
|
166
|
+
location: match.location,
|
|
167
|
+
suggestion: rule.suggestion,
|
|
168
|
+
context: match.context,
|
|
169
|
+
ruleId: rule.id
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return issues;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Detect formulaic structures
|
|
177
|
+
*/
|
|
178
|
+
detectFormulicStructures(content) {
|
|
179
|
+
if (!this.ruleSet) {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
const issues = [];
|
|
183
|
+
for (const rule of this.ruleSet.structuralPatterns) {
|
|
184
|
+
const matches = this.findPatternMatches(content, rule.pattern);
|
|
185
|
+
for (const match of matches) {
|
|
186
|
+
issues.push({
|
|
187
|
+
type: 'formulaic_structure',
|
|
188
|
+
severity: rule.severity,
|
|
189
|
+
message: rule.message,
|
|
190
|
+
location: match.location,
|
|
191
|
+
suggestion: rule.suggestion,
|
|
192
|
+
context: match.context,
|
|
193
|
+
ruleId: rule.id
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return issues;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Analyze content for authenticity markers
|
|
201
|
+
*/
|
|
202
|
+
analyzeAuthenticity(content) {
|
|
203
|
+
const humanMarkers = [];
|
|
204
|
+
const aiTells = [];
|
|
205
|
+
const missingMarkers = [];
|
|
206
|
+
// Detect human markers
|
|
207
|
+
const humanPatterns = [
|
|
208
|
+
{ pattern: /\b(I think|in my experience|we found|we chose|we decided)\b/gi, name: 'personal statements' },
|
|
209
|
+
{ pattern: /\bwhile .+, .+ (must|should|need|have to)/gi, name: 'trade-off acknowledgments' },
|
|
210
|
+
{ pattern: /\b(reduced|increased|improved) .+ by \d+(%|ms|s|KB|MB)/gi, name: 'specific metrics' },
|
|
211
|
+
{ pattern: /\b(p\d{2}|99\.9%|version \d+\.\d+)/gi, name: 'technical specifics' },
|
|
212
|
+
{ pattern: /\b(bug|issue|problem|challenge|failed|broke|difficult)\b/gi, name: 'problem mentions' },
|
|
213
|
+
{ pattern: /\b(\w+DB|Redis|Kubernetes|Docker|React|Vue|Angular)\b/g, name: 'specific technologies' }
|
|
214
|
+
];
|
|
215
|
+
for (const { pattern, name } of humanPatterns) {
|
|
216
|
+
const matches = content.match(pattern);
|
|
217
|
+
if (matches && matches.length > 0) {
|
|
218
|
+
humanMarkers.push(`${name} (${matches.length})`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Detect AI tells
|
|
222
|
+
const aiTellPatterns = [
|
|
223
|
+
{ pattern: /\b(seamlessly|cutting-edge|revolutionary|transformative|groundbreaking)\b/gi, name: 'marketing buzzwords' },
|
|
224
|
+
{ pattern: /^(Moreover|Furthermore|Additionally|Consequently),/gm, name: 'formulaic transitions' },
|
|
225
|
+
{ pattern: /\b(comprehensive|robust|innovative|optimal|best-in-class)\b/gi, name: 'vague intensifiers' },
|
|
226
|
+
{ pattern: /\b(it is important to note|it is worth noting|it should be mentioned)\b/gi, name: 'throat-clearing phrases' },
|
|
227
|
+
{ pattern: /\b(may help to|can serve to|has the potential to)\b/gi, name: 'excessive hedging' },
|
|
228
|
+
{ pattern: /\b(\w+, \w+, and \w+)\b/g, name: 'three-item lists' }
|
|
229
|
+
];
|
|
230
|
+
for (const { pattern, name } of aiTellPatterns) {
|
|
231
|
+
const matches = content.match(pattern);
|
|
232
|
+
if (matches && matches.length > 0) {
|
|
233
|
+
aiTells.push(`${name} (${matches.length})`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Check for missing markers
|
|
237
|
+
const contentLower = content.toLowerCase();
|
|
238
|
+
if (!contentLower.includes('i think') && !contentLower.includes('we found') && !contentLower.includes('we chose')) {
|
|
239
|
+
missingMarkers.push('personal statements or opinions');
|
|
240
|
+
}
|
|
241
|
+
if (!/\d+(%|ms|s|KB|MB|GB)/.test(content)) {
|
|
242
|
+
missingMarkers.push('specific metrics or measurements');
|
|
243
|
+
}
|
|
244
|
+
if (!/(bug|issue|problem|challenge|failed|broke|difficult)/i.test(content)) {
|
|
245
|
+
missingMarkers.push('acknowledgment of challenges or problems');
|
|
246
|
+
}
|
|
247
|
+
// Calculate authenticity score using configured weights
|
|
248
|
+
const config = getScoringConfig();
|
|
249
|
+
const humanScore = humanMarkers.length * config.authenticity.humanMarkerWeight;
|
|
250
|
+
const aiPenalty = aiTells.length * config.authenticity.aiTellPenalty;
|
|
251
|
+
const score = Math.max(0, Math.min(100, humanScore - aiPenalty + config.authenticity.baseScore));
|
|
252
|
+
return {
|
|
253
|
+
score,
|
|
254
|
+
humanMarkers,
|
|
255
|
+
missingMarkers,
|
|
256
|
+
aiTells
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Validate content for specific context
|
|
261
|
+
*/
|
|
262
|
+
async validateForContext(content, context) {
|
|
263
|
+
const result = await this.validate(content, context);
|
|
264
|
+
// Apply context-specific adjustments
|
|
265
|
+
const contextAdjustments = this.getContextAdjustments(content, context);
|
|
266
|
+
// Modify score based on context
|
|
267
|
+
result.score = Math.max(0, Math.min(100, result.score + contextAdjustments.scoreModifier));
|
|
268
|
+
// Add context-specific suggestions
|
|
269
|
+
result.suggestions.push(...contextAdjustments.suggestions);
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Load rules from AIWG
|
|
274
|
+
*/
|
|
275
|
+
loadRulesFromGuide(guidePath) {
|
|
276
|
+
this.ruleLoader = new ValidationRuleLoader(guidePath);
|
|
277
|
+
this.initialized = false;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Update rules with custom rule set
|
|
281
|
+
*/
|
|
282
|
+
updateRules(rules) {
|
|
283
|
+
if (!this.ruleSet) {
|
|
284
|
+
this.ruleSet = this.ruleLoader.getDefaultRules();
|
|
285
|
+
}
|
|
286
|
+
if (rules.bannedPhrases) {
|
|
287
|
+
this.ruleSet.bannedPhrases = this.ruleLoader.mergeRules(this.ruleSet.bannedPhrases, rules.bannedPhrases);
|
|
288
|
+
}
|
|
289
|
+
if (rules.aiPatterns) {
|
|
290
|
+
this.ruleSet.aiPatterns = this.ruleLoader.mergeRules(this.ruleSet.aiPatterns, rules.aiPatterns);
|
|
291
|
+
}
|
|
292
|
+
if (rules.authenticityMarkers) {
|
|
293
|
+
this.ruleSet.authenticityMarkers = this.ruleLoader.mergeRules(this.ruleSet.authenticityMarkers, rules.authenticityMarkers);
|
|
294
|
+
}
|
|
295
|
+
if (rules.structuralPatterns) {
|
|
296
|
+
this.ruleSet.structuralPatterns = this.ruleLoader.mergeRules(this.ruleSet.structuralPatterns, rules.structuralPatterns);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Generate report from validation results
|
|
301
|
+
*/
|
|
302
|
+
generateReport(results, format) {
|
|
303
|
+
if (results instanceof Map) {
|
|
304
|
+
return this.generateBatchReport(results, format);
|
|
305
|
+
}
|
|
306
|
+
switch (format) {
|
|
307
|
+
case 'json':
|
|
308
|
+
return JSON.stringify(results, null, 2);
|
|
309
|
+
case 'html':
|
|
310
|
+
return this.generateHtmlReport(results);
|
|
311
|
+
case 'text':
|
|
312
|
+
default:
|
|
313
|
+
return this.generateTextReport(results);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Private helper methods
|
|
317
|
+
findPatternMatches(content, pattern) {
|
|
318
|
+
const matches = [];
|
|
319
|
+
const regex = typeof pattern === 'string' ? new RegExp(pattern, 'gi') : pattern;
|
|
320
|
+
const lines = content.split('\n');
|
|
321
|
+
let absolutePos = 0;
|
|
322
|
+
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
323
|
+
const line = lines[lineIdx];
|
|
324
|
+
const lineMatches = Array.from(line.matchAll(new RegExp(regex.source, regex.flags)));
|
|
325
|
+
for (const match of lineMatches) {
|
|
326
|
+
const start = absolutePos + (match.index || 0);
|
|
327
|
+
const end = start + match[0].length;
|
|
328
|
+
// Extract context (surrounding text)
|
|
329
|
+
const contextStart = Math.max(0, (match.index || 0) - 30);
|
|
330
|
+
const contextEnd = Math.min(line.length, (match.index || 0) + match[0].length + 30);
|
|
331
|
+
const context = line.substring(contextStart, contextEnd);
|
|
332
|
+
matches.push({
|
|
333
|
+
match: match[0],
|
|
334
|
+
location: {
|
|
335
|
+
start,
|
|
336
|
+
end,
|
|
337
|
+
line: lineIdx + 1,
|
|
338
|
+
column: (match.index || 0) + 1
|
|
339
|
+
},
|
|
340
|
+
context
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
absolutePos += line.length + 1; // +1 for newline
|
|
344
|
+
}
|
|
345
|
+
return matches;
|
|
346
|
+
}
|
|
347
|
+
calculateSummary(content, issues, authenticityAnalysis) {
|
|
348
|
+
const criticalCount = issues.filter(i => i.severity === 'critical').length;
|
|
349
|
+
const warningCount = issues.filter(i => i.severity === 'warning').length;
|
|
350
|
+
const infoCount = issues.filter(i => i.severity === 'info').length;
|
|
351
|
+
// Count words and sentences
|
|
352
|
+
const words = content.split(/\s+/).filter(w => w.length > 0);
|
|
353
|
+
const sentences = content.split(/[.!?]+/).filter(s => s.trim().length > 0);
|
|
354
|
+
// Calculate AI pattern score (0-100, higher = more AI-like)
|
|
355
|
+
const config = getScoringConfig();
|
|
356
|
+
const aiPatternCount = issues.filter(i => i.type === 'ai_pattern' || i.type === 'banned_phrase').length;
|
|
357
|
+
const aiPatternScore = Math.min(100, (aiPatternCount / Math.max(1, words.length / 100)) * config.issueScoring.aiPatternNormalizer);
|
|
358
|
+
return {
|
|
359
|
+
totalIssues: issues.length,
|
|
360
|
+
criticalCount,
|
|
361
|
+
warningCount,
|
|
362
|
+
infoCount,
|
|
363
|
+
authenticityScore: authenticityAnalysis.score,
|
|
364
|
+
aiPatternScore,
|
|
365
|
+
wordCount: words.length,
|
|
366
|
+
sentenceCount: sentences.length
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
calculateOverallScore(summary, authenticityAnalysis) {
|
|
370
|
+
const config = getScoringConfig();
|
|
371
|
+
// Start with authenticity score
|
|
372
|
+
let score = authenticityAnalysis.score;
|
|
373
|
+
// Deduct for critical issues (heavy penalty)
|
|
374
|
+
score -= summary.criticalCount * config.issueScoring.criticalPenalty;
|
|
375
|
+
// Deduct for warnings (moderate penalty)
|
|
376
|
+
score -= summary.warningCount * config.issueScoring.warningPenalty;
|
|
377
|
+
// Deduct for high AI pattern score
|
|
378
|
+
score -= summary.aiPatternScore * config.issueScoring.aiPatternMultiplier;
|
|
379
|
+
// Clamp to 0-100
|
|
380
|
+
return Math.max(0, Math.min(100, score));
|
|
381
|
+
}
|
|
382
|
+
generateSuggestions(issues, authenticityAnalysis, summary) {
|
|
383
|
+
const suggestions = [];
|
|
384
|
+
// Critical issues first
|
|
385
|
+
if (summary.criticalCount > 0) {
|
|
386
|
+
suggestions.push(`Remove ${summary.criticalCount} banned phrase(s) immediately`);
|
|
387
|
+
}
|
|
388
|
+
// AI patterns
|
|
389
|
+
const config = getScoringConfig();
|
|
390
|
+
if (summary.aiPatternScore > config.thresholds.highAIPatternWarning) {
|
|
391
|
+
suggestions.push('High AI pattern score - review formulaic transitions and vague intensifiers');
|
|
392
|
+
}
|
|
393
|
+
// Missing authenticity
|
|
394
|
+
if (authenticityAnalysis.missingMarkers.length > 0) {
|
|
395
|
+
suggestions.push(`Add authenticity markers: ${authenticityAnalysis.missingMarkers.slice(0, 2).join(', ')}`);
|
|
396
|
+
}
|
|
397
|
+
// Specific improvements
|
|
398
|
+
const hasTransitionIssues = issues.some(i => i.message.includes('transition'));
|
|
399
|
+
if (hasTransitionIssues) {
|
|
400
|
+
suggestions.push('Remove formulaic transitions (Moreover, Furthermore) - just start the next sentence');
|
|
401
|
+
}
|
|
402
|
+
const hasVagueIntensifiers = issues.some(i => i.message.includes('comprehensive') || i.message.includes('robust'));
|
|
403
|
+
if (hasVagueIntensifiers) {
|
|
404
|
+
suggestions.push('Replace vague descriptors with specific details');
|
|
405
|
+
}
|
|
406
|
+
// If score is low, provide general guidance
|
|
407
|
+
const score = this.calculateOverallScore(summary, authenticityAnalysis);
|
|
408
|
+
if (score < config.thresholds.lowScoreWarning) {
|
|
409
|
+
suggestions.push('Consider adding: specific metrics, problem acknowledgments, and technical details');
|
|
410
|
+
}
|
|
411
|
+
return suggestions;
|
|
412
|
+
}
|
|
413
|
+
getContextAdjustments(content, context) {
|
|
414
|
+
const adjustments = { scoreModifier: 0, suggestions: [] };
|
|
415
|
+
switch (context) {
|
|
416
|
+
case 'academic':
|
|
417
|
+
// Allow more formal language
|
|
418
|
+
if (/\bcitation|reference|study|research\b/i.test(content)) {
|
|
419
|
+
adjustments.scoreModifier += 5;
|
|
420
|
+
}
|
|
421
|
+
if (!/\b(cited|et al|figure \d+)\b/i.test(content)) {
|
|
422
|
+
adjustments.suggestions.push('Academic context: Consider adding citations or references');
|
|
423
|
+
}
|
|
424
|
+
break;
|
|
425
|
+
case 'technical':
|
|
426
|
+
// Require technical specificity
|
|
427
|
+
if (/\b(algorithm|O\(|API|protocol|architecture)\b/i.test(content)) {
|
|
428
|
+
adjustments.scoreModifier += 10;
|
|
429
|
+
}
|
|
430
|
+
if (!/\b\d+(%|ms|MB|GB)\b/.test(content)) {
|
|
431
|
+
adjustments.suggestions.push('Technical context: Include specific metrics and performance numbers');
|
|
432
|
+
}
|
|
433
|
+
break;
|
|
434
|
+
case 'executive':
|
|
435
|
+
// Penalize hedging heavily
|
|
436
|
+
const hedgeCount = (content.match(/\b(may|might|could|perhaps)\b/gi) || []).length;
|
|
437
|
+
if (hedgeCount > 3) {
|
|
438
|
+
adjustments.scoreModifier -= 10;
|
|
439
|
+
adjustments.suggestions.push('Executive context: Reduce hedging - make direct assertions');
|
|
440
|
+
}
|
|
441
|
+
break;
|
|
442
|
+
case 'casual':
|
|
443
|
+
// Allow contractions and informal language
|
|
444
|
+
if (/\b(don't|won't|can't|it's)\b/.test(content)) {
|
|
445
|
+
adjustments.scoreModifier += 5;
|
|
446
|
+
}
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
return adjustments;
|
|
450
|
+
}
|
|
451
|
+
generateTextReport(result) {
|
|
452
|
+
const lines = [];
|
|
453
|
+
lines.push('=== Writing Validation Report ===\n');
|
|
454
|
+
lines.push(`Overall Score: ${result.score}/100`);
|
|
455
|
+
lines.push(`Authenticity Score: ${result.summary.authenticityScore}/100`);
|
|
456
|
+
lines.push(`AI Pattern Score: ${result.summary.aiPatternScore}/100 (lower is better)\n`);
|
|
457
|
+
lines.push(`Total Issues: ${result.summary.totalIssues}`);
|
|
458
|
+
lines.push(` Critical: ${result.summary.criticalCount}`);
|
|
459
|
+
lines.push(` Warnings: ${result.summary.warningCount}`);
|
|
460
|
+
lines.push(` Info: ${result.summary.infoCount}\n`);
|
|
461
|
+
lines.push(`Word Count: ${result.summary.wordCount}`);
|
|
462
|
+
lines.push(`Sentence Count: ${result.summary.sentenceCount}\n`);
|
|
463
|
+
if (result.issues.length > 0) {
|
|
464
|
+
lines.push('=== Issues ===\n');
|
|
465
|
+
for (const issue of result.issues.slice(0, 20)) {
|
|
466
|
+
lines.push(`[${issue.severity.toUpperCase()}] Line ${issue.location.line}: ${issue.message}`);
|
|
467
|
+
if (issue.context) {
|
|
468
|
+
lines.push(` Context: ...${issue.context}...`);
|
|
469
|
+
}
|
|
470
|
+
if (issue.suggestion) {
|
|
471
|
+
lines.push(` Suggestion: ${issue.suggestion}`);
|
|
472
|
+
}
|
|
473
|
+
lines.push('');
|
|
474
|
+
}
|
|
475
|
+
if (result.issues.length > 20) {
|
|
476
|
+
lines.push(`... and ${result.issues.length - 20} more issues\n`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (result.suggestions.length > 0) {
|
|
480
|
+
lines.push('=== Suggestions ===\n');
|
|
481
|
+
result.suggestions.forEach((s, i) => {
|
|
482
|
+
lines.push(`${i + 1}. ${s}`);
|
|
483
|
+
});
|
|
484
|
+
lines.push('');
|
|
485
|
+
}
|
|
486
|
+
if (result.humanMarkers.length > 0) {
|
|
487
|
+
lines.push('=== Human Markers Found ===');
|
|
488
|
+
result.humanMarkers.forEach(m => lines.push(` ✓ ${m}`));
|
|
489
|
+
lines.push('');
|
|
490
|
+
}
|
|
491
|
+
if (result.aiTells.length > 0) {
|
|
492
|
+
lines.push('=== AI Tells Found ===');
|
|
493
|
+
result.aiTells.forEach(t => lines.push(` ✗ ${t}`));
|
|
494
|
+
lines.push('');
|
|
495
|
+
}
|
|
496
|
+
return lines.join('\n');
|
|
497
|
+
}
|
|
498
|
+
generateBatchReport(results, format) {
|
|
499
|
+
if (format === 'json') {
|
|
500
|
+
const obj = {};
|
|
501
|
+
results.forEach((result, filePath) => {
|
|
502
|
+
obj[filePath] = result;
|
|
503
|
+
});
|
|
504
|
+
return JSON.stringify(obj, null, 2);
|
|
505
|
+
}
|
|
506
|
+
const lines = [];
|
|
507
|
+
lines.push('=== Batch Validation Report ===\n');
|
|
508
|
+
lines.push(`Total Files: ${results.size}\n`);
|
|
509
|
+
let totalScore = 0;
|
|
510
|
+
let passed = 0;
|
|
511
|
+
let failed = 0;
|
|
512
|
+
const config = getScoringConfig();
|
|
513
|
+
const passThreshold = config.thresholds.passScore;
|
|
514
|
+
results.forEach((result) => {
|
|
515
|
+
totalScore += result.score;
|
|
516
|
+
if (result.score >= passThreshold) {
|
|
517
|
+
passed++;
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
failed++;
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
const avgScore = results.size > 0 ? totalScore / results.size : 0;
|
|
524
|
+
lines.push(`Average Score: ${avgScore.toFixed(1)}/100`);
|
|
525
|
+
lines.push(`Passed (>=${passThreshold}): ${passed}`);
|
|
526
|
+
lines.push(`Failed (<${passThreshold}): ${failed}\n`);
|
|
527
|
+
lines.push('=== File Results ===\n');
|
|
528
|
+
results.forEach((result, filePath) => {
|
|
529
|
+
const status = result.score >= passThreshold ? 'PASS' : 'FAIL';
|
|
530
|
+
lines.push(`[${status}] ${filePath}: ${result.score}/100`);
|
|
531
|
+
if (result.summary.criticalCount > 0) {
|
|
532
|
+
lines.push(` ${result.summary.criticalCount} critical issue(s)`);
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
return lines.join('\n');
|
|
536
|
+
}
|
|
537
|
+
generateHtmlReport(result) {
|
|
538
|
+
const config = getScoringConfig();
|
|
539
|
+
const statusColor = result.score >= config.thresholds.passScore ? '#22c55e' : result.score >= config.thresholds.lowScoreWarning ? '#eab308' : '#ef4444';
|
|
540
|
+
return `<!DOCTYPE html>
|
|
541
|
+
<html>
|
|
542
|
+
<head>
|
|
543
|
+
<title>Writing Validation Report</title>
|
|
544
|
+
<style>
|
|
545
|
+
body { font-family: system-ui, sans-serif; max-width: 1200px; margin: 0 auto; padding: 2rem; }
|
|
546
|
+
.score { font-size: 3rem; font-weight: bold; color: ${statusColor}; }
|
|
547
|
+
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin: 2rem 0; }
|
|
548
|
+
.metric { background: #f3f4f6; padding: 1rem; border-radius: 0.5rem; }
|
|
549
|
+
.metric-value { font-size: 1.5rem; font-weight: bold; }
|
|
550
|
+
.issue { border-left: 3px solid #ef4444; padding: 0.5rem 1rem; margin: 0.5rem 0; background: #fef2f2; }
|
|
551
|
+
.issue.warning { border-color: #eab308; background: #fefce8; }
|
|
552
|
+
.issue.info { border-color: #3b82f6; background: #eff6ff; }
|
|
553
|
+
.suggestion { padding: 0.5rem 1rem; margin: 0.5rem 0; background: #f0fdf4; border-left: 3px solid #22c55e; }
|
|
554
|
+
</style>
|
|
555
|
+
</head>
|
|
556
|
+
<body>
|
|
557
|
+
<h1>Writing Validation Report</h1>
|
|
558
|
+
<div class="score">${result.score}/100</div>
|
|
559
|
+
|
|
560
|
+
<div class="summary">
|
|
561
|
+
<div class="metric">
|
|
562
|
+
<div>Authenticity Score</div>
|
|
563
|
+
<div class="metric-value">${result.summary.authenticityScore}/100</div>
|
|
564
|
+
</div>
|
|
565
|
+
<div class="metric">
|
|
566
|
+
<div>AI Pattern Score</div>
|
|
567
|
+
<div class="metric-value">${result.summary.aiPatternScore}/100</div>
|
|
568
|
+
</div>
|
|
569
|
+
<div class="metric">
|
|
570
|
+
<div>Total Issues</div>
|
|
571
|
+
<div class="metric-value">${result.summary.totalIssues}</div>
|
|
572
|
+
</div>
|
|
573
|
+
<div class="metric">
|
|
574
|
+
<div>Word Count</div>
|
|
575
|
+
<div class="metric-value">${result.summary.wordCount}</div>
|
|
576
|
+
</div>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
<h2>Issues (${result.issues.length})</h2>
|
|
580
|
+
${result.issues.slice(0, 50).map(issue => `
|
|
581
|
+
<div class="issue ${issue.severity}">
|
|
582
|
+
<strong>Line ${issue.location.line}:</strong> ${issue.message}
|
|
583
|
+
${issue.suggestion ? `<br><em>Suggestion: ${issue.suggestion}</em>` : ''}
|
|
584
|
+
</div>
|
|
585
|
+
`).join('')}
|
|
586
|
+
|
|
587
|
+
${result.suggestions.length > 0 ? `
|
|
588
|
+
<h2>Suggestions</h2>
|
|
589
|
+
${result.suggestions.map(s => `<div class="suggestion">${s}</div>`).join('')}
|
|
590
|
+
` : ''}
|
|
591
|
+
</body>
|
|
592
|
+
</html>`;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
//# sourceMappingURL=validation-engine.js.map
|