@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +22 -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 +1486 -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 +886 -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 +65 -9
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Checker
|
|
3
|
+
*
|
|
4
|
+
* Checks for available updates and prompts the user to update.
|
|
5
|
+
* - Stable channel: Checks npm registry for newer version
|
|
6
|
+
* - Edge channel: Checks git remote for new commits
|
|
7
|
+
*
|
|
8
|
+
* @module src/update/checker
|
|
9
|
+
* @version 2024.12.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from 'fs/promises';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import https from 'https';
|
|
15
|
+
import { execSync } from 'child_process';
|
|
16
|
+
import { createInterface } from 'readline';
|
|
17
|
+
import { loadConfig, saveConfig, getChannel, getPackageRoot } from '../channel/manager.mjs';
|
|
18
|
+
|
|
19
|
+
const NPM_REGISTRY = 'https://registry.npmjs.org/aiwg';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fetch latest version for a given npm dist-tag
|
|
23
|
+
* @param {string} distTag - npm dist-tag to resolve (latest, next, nightly)
|
|
24
|
+
* @returns {Promise<string|null>} Resolved version or null on error
|
|
25
|
+
*/
|
|
26
|
+
async function fetchNpmDistTag(distTag = 'latest') {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const request = https.get(NPM_REGISTRY, { timeout: 5000 }, (res) => {
|
|
29
|
+
if (res.statusCode !== 200) {
|
|
30
|
+
resolve(null);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let data = '';
|
|
35
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
36
|
+
res.on('end', () => {
|
|
37
|
+
try {
|
|
38
|
+
const pkg = JSON.parse(data);
|
|
39
|
+
resolve(pkg['dist-tags']?.[distTag] || null);
|
|
40
|
+
} catch {
|
|
41
|
+
resolve(null);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
request.on('error', () => resolve(null));
|
|
47
|
+
request.on('timeout', () => {
|
|
48
|
+
request.destroy();
|
|
49
|
+
resolve(null);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fetch latest version from npm registry (stable)
|
|
56
|
+
* @returns {Promise<string|null>} Latest version or null on error
|
|
57
|
+
*/
|
|
58
|
+
async function fetchLatestNpmVersion() {
|
|
59
|
+
return fetchNpmDistTag('latest');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if there are new commits in the git remote (edge channel)
|
|
64
|
+
* @param {string} edgePath - Path to edge installation
|
|
65
|
+
* @returns {Promise<boolean>} True if updates available
|
|
66
|
+
*/
|
|
67
|
+
async function checkGitUpdates(edgePath) {
|
|
68
|
+
try {
|
|
69
|
+
// Fetch latest without merging
|
|
70
|
+
execSync('git fetch --quiet', { cwd: edgePath, timeout: 10000 });
|
|
71
|
+
|
|
72
|
+
// Check if local is behind remote
|
|
73
|
+
const localHash = execSync('git rev-parse HEAD', {
|
|
74
|
+
cwd: edgePath,
|
|
75
|
+
encoding: 'utf8',
|
|
76
|
+
}).trim();
|
|
77
|
+
|
|
78
|
+
const remoteHash = execSync('git rev-parse origin/main', {
|
|
79
|
+
cwd: edgePath,
|
|
80
|
+
encoding: 'utf8',
|
|
81
|
+
}).trim();
|
|
82
|
+
|
|
83
|
+
return localHash !== remoteHash;
|
|
84
|
+
} catch {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Compare CalVer versions
|
|
91
|
+
* @param {string} current - Current version (e.g., "2024.12.0")
|
|
92
|
+
* @param {string} latest - Latest version
|
|
93
|
+
* @returns {boolean} True if latest is newer
|
|
94
|
+
*/
|
|
95
|
+
function isNewerVersion(current, latest) {
|
|
96
|
+
if (!current || !latest) return false;
|
|
97
|
+
|
|
98
|
+
const parseVersion = (v) => {
|
|
99
|
+
const match = v.match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
100
|
+
if (!match) return [0, 0, 0];
|
|
101
|
+
return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10)];
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const [cy, cm, cp] = parseVersion(current);
|
|
105
|
+
const [ly, lm, lp] = parseVersion(latest);
|
|
106
|
+
|
|
107
|
+
if (ly > cy) return true;
|
|
108
|
+
if (ly === cy && lm > cm) return true;
|
|
109
|
+
if (ly === cy && lm === cm && lp > cp) return true;
|
|
110
|
+
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Prompt user for update confirmation
|
|
116
|
+
* @param {string} message - Prompt message
|
|
117
|
+
* @returns {Promise<boolean>} True if user confirms
|
|
118
|
+
*/
|
|
119
|
+
async function promptUpdate(message) {
|
|
120
|
+
// Skip prompt if not interactive terminal
|
|
121
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const rl = createInterface({
|
|
126
|
+
input: process.stdin,
|
|
127
|
+
output: process.stdout,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Hard timeout so the update prompt cannot hang the CLI. The update check
|
|
131
|
+
// runs as a background fire-and-forget from bin/aiwg.mjs; if the user isn't
|
|
132
|
+
// watching the terminal, we silently decline instead of blocking forever.
|
|
133
|
+
// Override via AIWG_PROMPT_TIMEOUT_MS.
|
|
134
|
+
const timeoutMs = (() => {
|
|
135
|
+
const raw = process.env['AIWG_PROMPT_TIMEOUT_MS'];
|
|
136
|
+
const n = raw ? parseInt(raw, 10) : NaN;
|
|
137
|
+
return Number.isFinite(n) && n > 0 ? n : 10_000;
|
|
138
|
+
})();
|
|
139
|
+
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
let settled = false;
|
|
142
|
+
const timer = setTimeout(() => {
|
|
143
|
+
if (settled) return;
|
|
144
|
+
settled = true;
|
|
145
|
+
rl.close();
|
|
146
|
+
resolve(false);
|
|
147
|
+
}, timeoutMs);
|
|
148
|
+
timer.unref?.();
|
|
149
|
+
rl.question(`${message} [y/N]: `, (answer) => {
|
|
150
|
+
if (settled) return;
|
|
151
|
+
settled = true;
|
|
152
|
+
clearTimeout(timer);
|
|
153
|
+
rl.close();
|
|
154
|
+
const normalized = answer.toLowerCase().trim();
|
|
155
|
+
resolve(normalized === 'y' || normalized === 'yes');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Check for updates (background, non-blocking)
|
|
162
|
+
* This is called on every CLI invocation but only checks periodically
|
|
163
|
+
*/
|
|
164
|
+
export async function checkForUpdates() {
|
|
165
|
+
const config = await loadConfig();
|
|
166
|
+
|
|
167
|
+
// Check if enough time has passed since last check
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
const lastCheck = config.lastUpdateCheck || 0;
|
|
170
|
+
const interval = config.updateCheckInterval || 86400000; // 24 hours
|
|
171
|
+
|
|
172
|
+
if (now - lastCheck < interval) {
|
|
173
|
+
// Too soon to check again
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Update last check time
|
|
178
|
+
config.lastUpdateCheck = now;
|
|
179
|
+
await saveConfig(config);
|
|
180
|
+
|
|
181
|
+
if (config.channel === 'next') {
|
|
182
|
+
await checkNextUpdates(config);
|
|
183
|
+
} else if (config.channel === 'nightly') {
|
|
184
|
+
await checkNightlyUpdates(config);
|
|
185
|
+
} else if (config.channel === 'edge') {
|
|
186
|
+
await checkEdgeUpdates(config);
|
|
187
|
+
} else {
|
|
188
|
+
// stable (or unrecognised — treat as stable)
|
|
189
|
+
await checkStableUpdates(config);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Check for stable (npm) channel updates
|
|
195
|
+
*/
|
|
196
|
+
async function checkStableUpdates(config) {
|
|
197
|
+
const packageRoot = getPackageRoot();
|
|
198
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
202
|
+
const currentVersion = packageJson.version;
|
|
203
|
+
const latestVersion = await fetchLatestNpmVersion();
|
|
204
|
+
|
|
205
|
+
if (latestVersion && isNewerVersion(currentVersion, latestVersion)) {
|
|
206
|
+
console.log('');
|
|
207
|
+
console.log(`A new version of aiwg is available: ${currentVersion} → ${latestVersion}`);
|
|
208
|
+
|
|
209
|
+
const shouldUpdate = await promptUpdate('Would you like to update now?');
|
|
210
|
+
|
|
211
|
+
if (shouldUpdate) {
|
|
212
|
+
console.log('');
|
|
213
|
+
console.log('Updating aiwg...');
|
|
214
|
+
try {
|
|
215
|
+
execSync('npm install -g aiwg@latest', { stdio: 'inherit' });
|
|
216
|
+
console.log('Update complete! Please restart your terminal.');
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error('Update failed. Run manually: npm install -g aiwg@latest');
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
console.log('Update skipped. Run `npm install -g aiwg@latest` when ready.');
|
|
222
|
+
}
|
|
223
|
+
console.log('');
|
|
224
|
+
}
|
|
225
|
+
} catch {
|
|
226
|
+
// Silently ignore errors during update check
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Check for next (alpha/beta/RC) channel updates
|
|
232
|
+
*/
|
|
233
|
+
async function checkNextUpdates(config) {
|
|
234
|
+
const packageRoot = getPackageRoot();
|
|
235
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
236
|
+
|
|
237
|
+
try {
|
|
238
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
239
|
+
const currentVersion = packageJson.version;
|
|
240
|
+
const latestVersion = await fetchNpmDistTag('next');
|
|
241
|
+
|
|
242
|
+
if (!latestVersion) return;
|
|
243
|
+
|
|
244
|
+
if (currentVersion !== latestVersion) {
|
|
245
|
+
console.log('');
|
|
246
|
+
console.log(`A new next release is available: ${currentVersion} → ${latestVersion}`);
|
|
247
|
+
|
|
248
|
+
const shouldUpdate = await promptUpdate('Would you like to update now?');
|
|
249
|
+
|
|
250
|
+
if (shouldUpdate) {
|
|
251
|
+
console.log('');
|
|
252
|
+
console.log('Updating aiwg@next...');
|
|
253
|
+
try {
|
|
254
|
+
execSync('npm install -g aiwg@next', { stdio: 'inherit' });
|
|
255
|
+
console.log('Update complete! Please restart your terminal.');
|
|
256
|
+
} catch {
|
|
257
|
+
console.error('Update failed. Run manually: npm install -g aiwg@next');
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
console.log('Update skipped. Run `npm install -g aiwg@next` when ready.');
|
|
261
|
+
}
|
|
262
|
+
console.log('');
|
|
263
|
+
}
|
|
264
|
+
} catch {
|
|
265
|
+
// Silently ignore errors during update check
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Check for nightly channel updates
|
|
271
|
+
*/
|
|
272
|
+
async function checkNightlyUpdates(config) {
|
|
273
|
+
const packageRoot = getPackageRoot();
|
|
274
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
275
|
+
|
|
276
|
+
try {
|
|
277
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
278
|
+
const currentVersion = packageJson.version;
|
|
279
|
+
const latestVersion = await fetchNpmDistTag('nightly');
|
|
280
|
+
|
|
281
|
+
if (!latestVersion) return;
|
|
282
|
+
|
|
283
|
+
if (currentVersion !== latestVersion) {
|
|
284
|
+
console.log('');
|
|
285
|
+
console.log(`A new nightly snapshot is available: ${currentVersion} → ${latestVersion}`);
|
|
286
|
+
|
|
287
|
+
const shouldUpdate = await promptUpdate('Would you like to update now?');
|
|
288
|
+
|
|
289
|
+
if (shouldUpdate) {
|
|
290
|
+
console.log('');
|
|
291
|
+
console.log('Updating aiwg@nightly...');
|
|
292
|
+
try {
|
|
293
|
+
execSync('npm install -g aiwg@nightly', { stdio: 'inherit' });
|
|
294
|
+
console.log('Update complete! Please restart your terminal.');
|
|
295
|
+
} catch {
|
|
296
|
+
console.error('Update failed. Run manually: npm install -g aiwg@nightly');
|
|
297
|
+
}
|
|
298
|
+
} else {
|
|
299
|
+
console.log('Update skipped. Run `npm install -g aiwg@nightly` when ready.');
|
|
300
|
+
}
|
|
301
|
+
console.log('');
|
|
302
|
+
}
|
|
303
|
+
} catch {
|
|
304
|
+
// Silently ignore errors during update check
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Check for edge (git) channel updates
|
|
310
|
+
*/
|
|
311
|
+
async function checkEdgeUpdates(config) {
|
|
312
|
+
const hasUpdates = await checkGitUpdates(config.edgePath);
|
|
313
|
+
|
|
314
|
+
if (hasUpdates) {
|
|
315
|
+
console.log('');
|
|
316
|
+
console.log('New commits available in the main branch.');
|
|
317
|
+
|
|
318
|
+
const shouldUpdate = await promptUpdate('Would you like to update now?');
|
|
319
|
+
|
|
320
|
+
if (shouldUpdate) {
|
|
321
|
+
console.log('');
|
|
322
|
+
console.log('Updating edge installation...');
|
|
323
|
+
try {
|
|
324
|
+
execSync('git pull --ff-only', { cwd: config.edgePath, stdio: 'inherit' });
|
|
325
|
+
console.log('Update complete!');
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error('Update failed. Run manually:');
|
|
328
|
+
console.error(` cd ${config.edgePath} && git pull`);
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
console.log('Update skipped. Run `aiwg -update` when ready.');
|
|
332
|
+
}
|
|
333
|
+
console.log('');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Force an update check (called by aiwg -update)
|
|
339
|
+
*/
|
|
340
|
+
export async function forceUpdateCheck() {
|
|
341
|
+
const config = await loadConfig();
|
|
342
|
+
const packageRoot = getPackageRoot();
|
|
343
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
344
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
345
|
+
const currentVersion = packageJson.version;
|
|
346
|
+
|
|
347
|
+
if (config.channel === 'next') {
|
|
348
|
+
console.log('Checking for updates on next channel...');
|
|
349
|
+
const latestVersion = await fetchNpmDistTag('next');
|
|
350
|
+
if (!latestVersion) {
|
|
351
|
+
console.log('Could not check npm registry. Try: npm install -g aiwg@next');
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (currentVersion !== latestVersion) {
|
|
355
|
+
console.log(`Update available: ${currentVersion} → ${latestVersion}`);
|
|
356
|
+
console.log('');
|
|
357
|
+
console.log('Run: npm install -g aiwg@next');
|
|
358
|
+
} else {
|
|
359
|
+
console.log(`You are on the latest next release: ${currentVersion}`);
|
|
360
|
+
}
|
|
361
|
+
} else if (config.channel === 'nightly') {
|
|
362
|
+
console.log('Checking for updates on nightly channel...');
|
|
363
|
+
const latestVersion = await fetchNpmDistTag('nightly');
|
|
364
|
+
if (!latestVersion) {
|
|
365
|
+
console.log('Could not check npm registry. Try: npm install -g aiwg@nightly');
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (currentVersion !== latestVersion) {
|
|
369
|
+
console.log(`Update available: ${currentVersion} → ${latestVersion}`);
|
|
370
|
+
console.log('');
|
|
371
|
+
console.log('Run: npm install -g aiwg@nightly');
|
|
372
|
+
} else {
|
|
373
|
+
console.log(`You are on the latest nightly snapshot: ${currentVersion}`);
|
|
374
|
+
}
|
|
375
|
+
} else if (config.channel === 'edge') {
|
|
376
|
+
const { updateEdge } = await import('../channel/manager.mjs');
|
|
377
|
+
await updateEdge();
|
|
378
|
+
} else {
|
|
379
|
+
// stable
|
|
380
|
+
console.log('Checking for updates...');
|
|
381
|
+
const latestVersion = await fetchLatestNpmVersion();
|
|
382
|
+
|
|
383
|
+
if (!latestVersion) {
|
|
384
|
+
console.log('Could not check npm registry. Try: npm install -g aiwg@latest');
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (isNewerVersion(currentVersion, latestVersion)) {
|
|
389
|
+
console.log(`Update available: ${currentVersion} → ${latestVersion}`);
|
|
390
|
+
console.log('');
|
|
391
|
+
console.log('Run: npm install -g aiwg@latest');
|
|
392
|
+
} else {
|
|
393
|
+
console.log(`You are on the latest version: ${currentVersion}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIWG Update Notifier
|
|
3
|
+
*
|
|
4
|
+
* Non-blocking update check for the AIWG CLI. Follows the
|
|
5
|
+
* `update-notifier` / `simple-update-notifier` pattern:
|
|
6
|
+
*
|
|
7
|
+
* 1. On CLI invocation, `scheduleBackgroundCheck()` is called from
|
|
8
|
+
* `bin/aiwg.mjs`. It spawns a **detached, unref()'d** child Node
|
|
9
|
+
* process that runs this file with `--check` and writes the result
|
|
10
|
+
* to `~/.aiwg/update-notifier.json`. The child exits immediately
|
|
11
|
+
* after writing; the parent never waits on it.
|
|
12
|
+
*
|
|
13
|
+
* 2. On the *next* invocation, `maybePrintNotice()` reads the cache
|
|
14
|
+
* and prints a single-line "update available" message to stderr.
|
|
15
|
+
* The user's current command is never delayed by a network call.
|
|
16
|
+
*
|
|
17
|
+
* The update check honours `NO_UPDATE_NOTIFIER`, `CI`, the isInteractive()
|
|
18
|
+
* helper, and `--no-update-check`. In all of those cases the check is
|
|
19
|
+
* skipped entirely.
|
|
20
|
+
*
|
|
21
|
+
* Phase 3 of the CLI Stabilization Epic (#920). Replaces the synchronous
|
|
22
|
+
* `checkForUpdates()` + hand-rolled prompt in `checker.mjs` that held the
|
|
23
|
+
* event loop open after the command completed.
|
|
24
|
+
*
|
|
25
|
+
* @module src/update/notifier
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import https from 'https';
|
|
29
|
+
import path from 'path';
|
|
30
|
+
import os from 'os';
|
|
31
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
32
|
+
import { spawn } from 'child_process';
|
|
33
|
+
import { fileURLToPath } from 'url';
|
|
34
|
+
|
|
35
|
+
const CACHE_DIR = path.join(os.homedir(), '.aiwg');
|
|
36
|
+
const CACHE_FILE = path.join(CACHE_DIR, 'update-notifier.json');
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Minimum time between update checks (24 hours). Checked via the
|
|
40
|
+
* `lastCheckAt` timestamp in the cache file.
|
|
41
|
+
*/
|
|
42
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Hard timeout for the npm registry HTTPS request. Keeps the spawned
|
|
46
|
+
* background child from lingering on slow networks.
|
|
47
|
+
*/
|
|
48
|
+
const NETWORK_TIMEOUT_MS = 10_000;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Read an env var and return true iff it's set to a truthy value.
|
|
52
|
+
*/
|
|
53
|
+
function envFlag(name) {
|
|
54
|
+
const v = process.env[name];
|
|
55
|
+
if (!v) return false;
|
|
56
|
+
return v !== '0' && v.toLowerCase() !== 'false';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* True iff update checking is currently disabled by env / CI conventions.
|
|
61
|
+
*/
|
|
62
|
+
function isDisabled() {
|
|
63
|
+
if (envFlag('NO_UPDATE_NOTIFIER')) return true;
|
|
64
|
+
if (envFlag('AIWG_NO_UPDATE_CHECK')) return true;
|
|
65
|
+
if (envFlag('CI')) return true;
|
|
66
|
+
if (envFlag('GITHUB_ACTIONS')) return true;
|
|
67
|
+
if (envFlag('GITLAB_CI')) return true;
|
|
68
|
+
// Non-interactive terminals shouldn't get a notice they can't act on.
|
|
69
|
+
if (!process.stdout.isTTY) return true;
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Read the update-notifier cache. Returns null if absent or malformed.
|
|
75
|
+
*/
|
|
76
|
+
function readCache() {
|
|
77
|
+
if (!existsSync(CACHE_FILE)) return null;
|
|
78
|
+
try {
|
|
79
|
+
return JSON.parse(readFileSync(CACHE_FILE, 'utf-8'));
|
|
80
|
+
} catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function writeCache(data) {
|
|
86
|
+
try {
|
|
87
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
88
|
+
writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
89
|
+
} catch {
|
|
90
|
+
// Best-effort — update-notifier failures are never fatal.
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Compare two CalVer/semver-style versions. Returns true iff `latest` is
|
|
96
|
+
* newer than `current`. Cheap, no full semver parsing.
|
|
97
|
+
*/
|
|
98
|
+
function isNewer(current, latest) {
|
|
99
|
+
if (!current || !latest || current === latest) return false;
|
|
100
|
+
const parse = (v) => {
|
|
101
|
+
const match = String(v).match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
102
|
+
if (!match) return [0, 0, 0];
|
|
103
|
+
return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10)];
|
|
104
|
+
};
|
|
105
|
+
const [cy, cm, cp] = parse(current);
|
|
106
|
+
const [ly, lm, lp] = parse(latest);
|
|
107
|
+
if (ly > cy) return true;
|
|
108
|
+
if (ly === cy && lm > cm) return true;
|
|
109
|
+
if (ly === cy && lm === cm && lp > cp) return true;
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Fetch the latest published version for the `latest` dist-tag from npm.
|
|
115
|
+
* Resolves to `null` on error or timeout.
|
|
116
|
+
*/
|
|
117
|
+
function fetchLatestVersion() {
|
|
118
|
+
return new Promise((resolve) => {
|
|
119
|
+
const req = https.get(
|
|
120
|
+
'https://registry.npmjs.org/aiwg',
|
|
121
|
+
{ timeout: NETWORK_TIMEOUT_MS },
|
|
122
|
+
(res) => {
|
|
123
|
+
if (res.statusCode !== 200) {
|
|
124
|
+
resolve(null);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
let data = '';
|
|
128
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
129
|
+
res.on('end', () => {
|
|
130
|
+
try {
|
|
131
|
+
const pkg = JSON.parse(data);
|
|
132
|
+
resolve(pkg['dist-tags']?.latest ?? null);
|
|
133
|
+
} catch {
|
|
134
|
+
resolve(null);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
req.on('error', () => resolve(null));
|
|
140
|
+
req.on('timeout', () => {
|
|
141
|
+
req.destroy();
|
|
142
|
+
resolve(null);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Read current CLI version from the package.json at `packageRoot`.
|
|
149
|
+
*/
|
|
150
|
+
function readCurrentVersion(packageRoot) {
|
|
151
|
+
try {
|
|
152
|
+
const pkgPath = path.join(packageRoot, 'package.json');
|
|
153
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
154
|
+
return pkg.version;
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Run the actual update check and write the cache file. Invoked by the
|
|
162
|
+
* spawned background child via `node src/update/notifier.mjs --check`.
|
|
163
|
+
*/
|
|
164
|
+
async function runCheck(packageRoot) {
|
|
165
|
+
const currentVersion = readCurrentVersion(packageRoot);
|
|
166
|
+
const latestVersion = await fetchLatestVersion();
|
|
167
|
+
writeCache({
|
|
168
|
+
lastCheckAt: new Date().toISOString(),
|
|
169
|
+
current: currentVersion,
|
|
170
|
+
latest: latestVersion,
|
|
171
|
+
hasUpdate: !!(currentVersion && latestVersion && isNewer(currentVersion, latestVersion)),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Schedule a background update check if one hasn't run in the last
|
|
177
|
+
* CHECK_INTERVAL_MS. Non-blocking: spawns a detached child process and
|
|
178
|
+
* returns immediately. The parent must not wait on the child.
|
|
179
|
+
*
|
|
180
|
+
* Called exactly once per CLI invocation from `bin/aiwg.mjs`.
|
|
181
|
+
*/
|
|
182
|
+
export function scheduleBackgroundCheck(packageRoot) {
|
|
183
|
+
if (isDisabled()) return;
|
|
184
|
+
|
|
185
|
+
const cache = readCache();
|
|
186
|
+
if (cache?.lastCheckAt) {
|
|
187
|
+
const age = Date.now() - new Date(cache.lastCheckAt).getTime();
|
|
188
|
+
if (age < CHECK_INTERVAL_MS) return; // recent enough — skip
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
const entry = fileURLToPath(import.meta.url);
|
|
193
|
+
const child = spawn(
|
|
194
|
+
process.execPath,
|
|
195
|
+
[entry, '--check', '--package-root', packageRoot],
|
|
196
|
+
{
|
|
197
|
+
detached: true,
|
|
198
|
+
stdio: 'ignore',
|
|
199
|
+
env: { ...process.env, AIWG_UPDATE_NOTIFIER_CHILD: '1' },
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
// Unref so the parent can exit without waiting for the child. This is
|
|
203
|
+
// the crucial detail that prevents the "command hangs for 5 minutes"
|
|
204
|
+
// symptom we had before #918.
|
|
205
|
+
child.unref();
|
|
206
|
+
} catch {
|
|
207
|
+
// Spawn failures are non-fatal; the next invocation will retry.
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* If the cache indicates an update is available AND the current terminal
|
|
213
|
+
* is interactive, print a single-line notice to stderr. Never prompts.
|
|
214
|
+
* Safe to call unconditionally from `bin/aiwg.mjs` — gated by isDisabled().
|
|
215
|
+
*/
|
|
216
|
+
export function maybePrintNotice() {
|
|
217
|
+
if (isDisabled()) return;
|
|
218
|
+
const cache = readCache();
|
|
219
|
+
if (!cache?.hasUpdate || !cache.current || !cache.latest) return;
|
|
220
|
+
// One-line, non-intrusive. Users who want to update run `aiwg update`.
|
|
221
|
+
const msg = `aiwg: update available ${cache.current} → ${cache.latest} (run: npm install -g aiwg)`;
|
|
222
|
+
process.stderr.write(`\n${msg}\n`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── Child-process entry ────────────────────────────────────────────────
|
|
226
|
+
|
|
227
|
+
// If invoked with `--check`, act as the background-child worker.
|
|
228
|
+
if (process.argv.includes('--check')) {
|
|
229
|
+
const rootIdx = process.argv.indexOf('--package-root');
|
|
230
|
+
const packageRoot = rootIdx >= 0 ? process.argv[rootIdx + 1] : process.cwd();
|
|
231
|
+
runCheck(packageRoot).catch(() => {
|
|
232
|
+
// Swallow all errors — the background child must never write to stderr.
|
|
233
|
+
process.exit(0);
|
|
234
|
+
});
|
|
235
|
+
}
|