@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,623 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ops Workspace Registry
|
|
3
|
+
*
|
|
4
|
+
* Manages the ops.yaml file in the user config directory.
|
|
5
|
+
* Tracks workspace definitions, repo locations, and cross-repo wiring.
|
|
6
|
+
*
|
|
7
|
+
* @implements #544
|
|
8
|
+
*/
|
|
9
|
+
import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
|
|
10
|
+
import { resolve, dirname, basename, sep } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
13
|
+
import { execSync } from 'child_process';
|
|
14
|
+
import { resolveConfigDir } from '../config/user-config.js';
|
|
15
|
+
import { resolveWorkspace } from '../config/workspace.js';
|
|
16
|
+
import { projectAiwgPath } from '../config/project-artifacts.js';
|
|
17
|
+
/**
|
|
18
|
+
* Extension type abbreviations
|
|
19
|
+
*/
|
|
20
|
+
const EXTENSION_NAMES = {
|
|
21
|
+
sys: 'sysops',
|
|
22
|
+
it: 'itops',
|
|
23
|
+
dev: 'devops',
|
|
24
|
+
stream: 'streamops',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Adapt an existing ops workspace to the canonical general workspace shape.
|
|
28
|
+
*
|
|
29
|
+
* The adapter is intentionally side-effect free: `.aiwg/aiwg.config` is the
|
|
30
|
+
* canonical persisted manifest, while the user-level ops registry remains a
|
|
31
|
+
* specialization/compatibility source rather than a second authorization
|
|
32
|
+
* format.
|
|
33
|
+
*
|
|
34
|
+
* @implements #1764
|
|
35
|
+
*/
|
|
36
|
+
export function opsWorkspaceToWorkspaceConfig(name, workspace, allowed = ['read', 'write', 'commit', 'push', 'issue-comment']) {
|
|
37
|
+
return {
|
|
38
|
+
workspace: {
|
|
39
|
+
name,
|
|
40
|
+
root: workspace.home,
|
|
41
|
+
},
|
|
42
|
+
repos: Object.entries(workspace.repos).map(([repoName, repo]) => ({
|
|
43
|
+
name: repoName,
|
|
44
|
+
path: repo.path,
|
|
45
|
+
allowed: [...allowed],
|
|
46
|
+
})),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Default empty registry
|
|
51
|
+
*/
|
|
52
|
+
const DEFAULT_REGISTRY = {
|
|
53
|
+
apiVersion: 'aiwg.io/v1',
|
|
54
|
+
kind: 'OpsRegistry',
|
|
55
|
+
defaultWorkspace: 'default',
|
|
56
|
+
workspaces: {},
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Ops workspace registry manager
|
|
60
|
+
*/
|
|
61
|
+
export class OpsRegistry {
|
|
62
|
+
configDir;
|
|
63
|
+
registryPath;
|
|
64
|
+
constructor(configDirOverride) {
|
|
65
|
+
this.configDir = resolveConfigDir(configDirOverride);
|
|
66
|
+
this.registryPath = resolve(this.configDir, 'ops.json');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Load the ops registry, creating defaults if missing
|
|
70
|
+
*/
|
|
71
|
+
async load() {
|
|
72
|
+
if (!existsSync(this.registryPath)) {
|
|
73
|
+
return { ...DEFAULT_REGISTRY, workspaces: {} };
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const content = await readFile(this.registryPath, 'utf-8');
|
|
77
|
+
const parsed = JSON.parse(content);
|
|
78
|
+
return {
|
|
79
|
+
...DEFAULT_REGISTRY,
|
|
80
|
+
...parsed,
|
|
81
|
+
workspaces: parsed.workspaces ? { ...parsed.workspaces } : {},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return { ...DEFAULT_REGISTRY, workspaces: {} };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Save the ops registry
|
|
90
|
+
*/
|
|
91
|
+
async save(data) {
|
|
92
|
+
await mkdir(this.configDir, { recursive: true });
|
|
93
|
+
await writeFile(this.registryPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Initialize a new ops workspace
|
|
97
|
+
*/
|
|
98
|
+
async initWorkspace(opts) {
|
|
99
|
+
const data = await this.load();
|
|
100
|
+
// Check for existing workspace
|
|
101
|
+
if (data.workspaces[opts.name]) {
|
|
102
|
+
throw new Error(`Workspace "${opts.name}" already exists. Use a different name or remove the existing workspace.`);
|
|
103
|
+
}
|
|
104
|
+
// Resolve home directory
|
|
105
|
+
const opsHome = opts.home || resolve(homedir(), 'ops', opts.name);
|
|
106
|
+
// Refuse to create nested ops workspaces — walk up from the parent of
|
|
107
|
+
// opsHome looking for OpsInventory.yaml. Sibling layout is required.
|
|
108
|
+
const enclosing = findEnclosingOpsWorkspace(opsHome);
|
|
109
|
+
if (enclosing) {
|
|
110
|
+
const suggested = resolve(dirname(enclosing), opts.name);
|
|
111
|
+
throw new Error(`${enclosing} is already an ops workspace.\n` +
|
|
112
|
+
`Ops workspaces must be siblings of one another, not nested.\n` +
|
|
113
|
+
`Suggested location: ${suggested}`);
|
|
114
|
+
}
|
|
115
|
+
// Build workspace
|
|
116
|
+
const workspace = {
|
|
117
|
+
home: opsHome,
|
|
118
|
+
mode: opts.mode,
|
|
119
|
+
repos: {},
|
|
120
|
+
};
|
|
121
|
+
if (opts.from && opts.mode === 'multi-repo' && opts.extensions.length > 1) {
|
|
122
|
+
throw new Error('--from <url> requires single-repo mode or exactly one extension. ' +
|
|
123
|
+
'Use --mode single-repo, or pass --ext with a single value.');
|
|
124
|
+
}
|
|
125
|
+
if (opts.mode === 'multi-repo') {
|
|
126
|
+
// Create separate repo for each extension
|
|
127
|
+
for (const ext of opts.extensions) {
|
|
128
|
+
const fullName = EXTENSION_NAMES[ext] || ext;
|
|
129
|
+
const repoName = opts.prefix ? `${opts.prefix}-${fullName}` : fullName;
|
|
130
|
+
const repoPath = resolve(opsHome, repoName);
|
|
131
|
+
const provisioned = await provisionRepo(repoPath, opts.from, !!opts.silent);
|
|
132
|
+
workspace.repos[repoName] = {
|
|
133
|
+
path: repoPath,
|
|
134
|
+
remote: provisioned.remote,
|
|
135
|
+
extensions: [ext],
|
|
136
|
+
};
|
|
137
|
+
// Seed OpsInventory stub (only if missing — never overwrite)
|
|
138
|
+
await seedInventory(repoPath, repoName, ext);
|
|
139
|
+
if (!opts.silent)
|
|
140
|
+
console.log(` ${provisioned.action} ${repoName} at ${repoPath}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
// Single-repo mode: one repo, subdirectories per domain
|
|
145
|
+
const repoName = opts.prefix ? `${opts.prefix}-ops` : 'ops';
|
|
146
|
+
const repoPath = resolve(opsHome, repoName);
|
|
147
|
+
const provisioned = await provisionRepo(repoPath, opts.from, !!opts.silent);
|
|
148
|
+
// Create subdirectories for each extension
|
|
149
|
+
for (const ext of opts.extensions) {
|
|
150
|
+
const fullName = EXTENSION_NAMES[ext] || ext;
|
|
151
|
+
const subDir = resolve(repoPath, fullName);
|
|
152
|
+
await mkdir(subDir, { recursive: true });
|
|
153
|
+
await seedInventory(subDir, fullName, ext);
|
|
154
|
+
}
|
|
155
|
+
workspace.repos[repoName] = {
|
|
156
|
+
path: repoPath,
|
|
157
|
+
remote: provisioned.remote,
|
|
158
|
+
extensions: opts.extensions,
|
|
159
|
+
};
|
|
160
|
+
if (!opts.silent)
|
|
161
|
+
console.log(` ${provisioned.action} ${repoName} at ${repoPath}`);
|
|
162
|
+
}
|
|
163
|
+
// Register workspace
|
|
164
|
+
data.workspaces[opts.name] = workspace;
|
|
165
|
+
if (Object.keys(data.workspaces).length === 1) {
|
|
166
|
+
data.defaultWorkspace = opts.name;
|
|
167
|
+
}
|
|
168
|
+
await this.save(data);
|
|
169
|
+
// Post-init summary
|
|
170
|
+
console.log('');
|
|
171
|
+
console.log(`Workspace "${opts.name}" initialized`);
|
|
172
|
+
console.log(` Mode: ${opts.mode}`);
|
|
173
|
+
console.log(` Home: ${opsHome}`);
|
|
174
|
+
console.log(` Extensions: ${opts.extensions.join(', ')}`);
|
|
175
|
+
console.log(` Repos: ${Object.keys(workspace.repos).join(', ')}`);
|
|
176
|
+
console.log(` Registry: ${this.registryPath}`);
|
|
177
|
+
if (opts.provider) {
|
|
178
|
+
console.log('');
|
|
179
|
+
console.log(`Remote push to ${opts.provider} requested — use 'aiwg ops push' to push repos.`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Show workspace status
|
|
184
|
+
*/
|
|
185
|
+
async showStatus(showAll) {
|
|
186
|
+
const data = await this.load();
|
|
187
|
+
if (Object.keys(data.workspaces).length === 0) {
|
|
188
|
+
console.log('No ops workspaces registered.');
|
|
189
|
+
console.log('Run "aiwg ops init" to create one.');
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const workspaces = showAll
|
|
193
|
+
? Object.entries(data.workspaces)
|
|
194
|
+
: [[data.defaultWorkspace, data.workspaces[data.defaultWorkspace]]].filter(([, ws]) => ws !== undefined);
|
|
195
|
+
for (const [name, ws] of workspaces) {
|
|
196
|
+
const workspace = ws;
|
|
197
|
+
const isDefault = name === data.defaultWorkspace;
|
|
198
|
+
console.log(`${isDefault ? '* ' : ' '}${name} (${workspace.mode})`);
|
|
199
|
+
console.log(` Home: ${workspace.home}`);
|
|
200
|
+
for (const [repoName, repo] of Object.entries(workspace.repos)) {
|
|
201
|
+
const exists = existsSync(repo.path);
|
|
202
|
+
const hasGit = exists && existsSync(resolve(repo.path, '.git'));
|
|
203
|
+
const status = !exists ? 'MISSING' : !hasGit ? 'NO GIT' : 'OK';
|
|
204
|
+
console.log(` ${repoName}: ${status} — ${repo.path}`);
|
|
205
|
+
}
|
|
206
|
+
console.log('');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Switch active workspace
|
|
211
|
+
*/
|
|
212
|
+
async switchWorkspace(name) {
|
|
213
|
+
const data = await this.load();
|
|
214
|
+
if (!data.workspaces[name]) {
|
|
215
|
+
const available = Object.keys(data.workspaces).join(', ') || '(none)';
|
|
216
|
+
throw new Error(`Workspace "${name}" not found. Available: ${available}`);
|
|
217
|
+
}
|
|
218
|
+
data.defaultWorkspace = name;
|
|
219
|
+
await this.save(data);
|
|
220
|
+
console.log(`Active workspace: ${name}`);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* List all registered workspaces
|
|
224
|
+
*/
|
|
225
|
+
async listWorkspaces() {
|
|
226
|
+
const data = await this.load();
|
|
227
|
+
if (Object.keys(data.workspaces).length === 0) {
|
|
228
|
+
console.log('No ops workspaces registered.');
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
console.log('Registered workspaces:\n');
|
|
232
|
+
for (const [name, ws] of Object.entries(data.workspaces)) {
|
|
233
|
+
const isDefault = name === data.defaultWorkspace;
|
|
234
|
+
const repoCount = Object.keys(ws.repos).length;
|
|
235
|
+
console.log(` ${isDefault ? '*' : ' '} ${name} — ${ws.mode}, ${repoCount} repo(s), ${ws.home}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Adopt an existing local clone as a repo entry under a workspace.
|
|
240
|
+
*
|
|
241
|
+
* Detects the git remote, seeds OpsInventory.yaml only if missing
|
|
242
|
+
* (never overwrites an existing inventory), and registers the repo.
|
|
243
|
+
* Refuses to register a path nested inside another registered repo.
|
|
244
|
+
*/
|
|
245
|
+
async adoptRepo(repoPath, opts = {}) {
|
|
246
|
+
const absPath = resolve(repoPath);
|
|
247
|
+
if (!existsSync(absPath)) {
|
|
248
|
+
throw new Error(`Path does not exist: ${absPath}`);
|
|
249
|
+
}
|
|
250
|
+
if (!statSync(absPath).isDirectory()) {
|
|
251
|
+
throw new Error(`Path is not a directory: ${absPath}`);
|
|
252
|
+
}
|
|
253
|
+
const data = await this.load();
|
|
254
|
+
// Refuse if this path is nested inside another registered repo
|
|
255
|
+
for (const ws of Object.values(data.workspaces)) {
|
|
256
|
+
for (const repo of Object.values(ws.repos)) {
|
|
257
|
+
const registered = resolve(repo.path);
|
|
258
|
+
if (registered !== absPath && absPath.startsWith(registered + sep)) {
|
|
259
|
+
throw new Error(`Refusing to adopt: ${absPath} is nested inside registered repo ${registered}.`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const workspaceName = opts.workspace ?? 'default';
|
|
264
|
+
if (!data.workspaces[workspaceName]) {
|
|
265
|
+
data.workspaces[workspaceName] = {
|
|
266
|
+
home: dirname(absPath),
|
|
267
|
+
mode: 'multi-repo',
|
|
268
|
+
repos: {},
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
const ws = data.workspaces[workspaceName];
|
|
272
|
+
const remote = readGitRemote(absPath);
|
|
273
|
+
let repoName = opts.name ?? basename(absPath);
|
|
274
|
+
let suffix = 2;
|
|
275
|
+
while (ws.repos[repoName]) {
|
|
276
|
+
// Same path already registered? Treat as idempotent.
|
|
277
|
+
if (resolve(ws.repos[repoName].path) === absPath) {
|
|
278
|
+
if (!opts.silent)
|
|
279
|
+
console.log(` Already registered: ${repoName} -> ${absPath}`);
|
|
280
|
+
return { workspace: workspaceName, repoName };
|
|
281
|
+
}
|
|
282
|
+
repoName = `${opts.name ?? basename(absPath)}-${suffix++}`;
|
|
283
|
+
}
|
|
284
|
+
// Seed OpsInventory.yaml only if missing — never overwrite existing.
|
|
285
|
+
const inventoryPath = resolve(absPath, 'OpsInventory.yaml');
|
|
286
|
+
if (!existsSync(inventoryPath)) {
|
|
287
|
+
const ext = (opts.extensions && opts.extensions[0]) ?? 'sys';
|
|
288
|
+
await seedInventory(absPath, repoName, ext);
|
|
289
|
+
}
|
|
290
|
+
ws.repos[repoName] = {
|
|
291
|
+
path: absPath,
|
|
292
|
+
remote,
|
|
293
|
+
extensions: opts.extensions ?? [],
|
|
294
|
+
};
|
|
295
|
+
if (Object.keys(data.workspaces).length === 1) {
|
|
296
|
+
data.defaultWorkspace = workspaceName;
|
|
297
|
+
}
|
|
298
|
+
await this.save(data);
|
|
299
|
+
if (!opts.silent) {
|
|
300
|
+
console.log(`Adopted ${repoName} at ${absPath} into workspace "${workspaceName}".`);
|
|
301
|
+
if (remote)
|
|
302
|
+
console.log(` Remote: ${remote}`);
|
|
303
|
+
}
|
|
304
|
+
return { workspace: workspaceName, repoName };
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Walk the given roots looking for ops-workspace candidates.
|
|
308
|
+
*
|
|
309
|
+
* A candidate is any directory containing `OpsInventory.yaml`. Skips
|
|
310
|
+
* `node_modules`, `.git`, and other obvious noise. Candidates nested
|
|
311
|
+
* inside another candidate are dropped (siblings-only by design — see
|
|
312
|
+
* #935).
|
|
313
|
+
*/
|
|
314
|
+
async discoverWorkspaces(opts = {}) {
|
|
315
|
+
const roots = (opts.roots && opts.roots.length > 0 ? opts.roots : [homedir()]).map((r) => resolve(r));
|
|
316
|
+
const maxDepth = opts.maxDepth ?? 3;
|
|
317
|
+
const data = await this.load();
|
|
318
|
+
const registeredPaths = new Set();
|
|
319
|
+
for (const ws of Object.values(data.workspaces)) {
|
|
320
|
+
for (const repo of Object.values(ws.repos)) {
|
|
321
|
+
registeredPaths.add(resolve(repo.path));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
const found = [];
|
|
325
|
+
const seen = new Set();
|
|
326
|
+
const skipNames = new Set([
|
|
327
|
+
'node_modules',
|
|
328
|
+
'.git',
|
|
329
|
+
'.aiwg', // walk past, never into
|
|
330
|
+
'.cache',
|
|
331
|
+
'.npm',
|
|
332
|
+
'.yarn',
|
|
333
|
+
'.pnpm-store',
|
|
334
|
+
'.venv',
|
|
335
|
+
'venv',
|
|
336
|
+
'dist',
|
|
337
|
+
'build',
|
|
338
|
+
'target',
|
|
339
|
+
]);
|
|
340
|
+
const walk = async (dir, depth) => {
|
|
341
|
+
if (depth > maxDepth)
|
|
342
|
+
return;
|
|
343
|
+
if (seen.has(dir))
|
|
344
|
+
return;
|
|
345
|
+
seen.add(dir);
|
|
346
|
+
// Marker check at this level
|
|
347
|
+
if (existsSync(resolve(dir, 'OpsInventory.yaml'))) {
|
|
348
|
+
found.push({
|
|
349
|
+
path: dir,
|
|
350
|
+
name: basename(dir),
|
|
351
|
+
remote: readGitRemote(dir),
|
|
352
|
+
alreadyRegistered: registeredPaths.has(dir),
|
|
353
|
+
marker: 'OpsInventory.yaml',
|
|
354
|
+
});
|
|
355
|
+
// Don't descend further — workspaces shouldn't nest.
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
let entries;
|
|
359
|
+
try {
|
|
360
|
+
entries = await readdir(dir);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
for (const entry of entries) {
|
|
366
|
+
if (entry.startsWith('.') && entry !== '.aiwg') {
|
|
367
|
+
// Allow hidden roots only in narrow cases; skip the rest.
|
|
368
|
+
if (skipNames.has(entry))
|
|
369
|
+
continue;
|
|
370
|
+
if (entry === '.git')
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (skipNames.has(entry))
|
|
374
|
+
continue;
|
|
375
|
+
const child = resolve(dir, entry);
|
|
376
|
+
let isDir = false;
|
|
377
|
+
try {
|
|
378
|
+
isDir = statSync(child).isDirectory();
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
if (!isDir)
|
|
384
|
+
continue;
|
|
385
|
+
await walk(child, depth + 1);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
for (const root of roots) {
|
|
389
|
+
if (!existsSync(root))
|
|
390
|
+
continue;
|
|
391
|
+
await walk(root, 0);
|
|
392
|
+
}
|
|
393
|
+
// Drop nested candidates (deeper paths whose ancestor is also a candidate)
|
|
394
|
+
found.sort((a, b) => a.path.length - b.path.length);
|
|
395
|
+
const kept = [];
|
|
396
|
+
for (const cand of found) {
|
|
397
|
+
const nested = kept.some((k) => cand.path !== k.path && cand.path.startsWith(k.path + sep));
|
|
398
|
+
if (!nested)
|
|
399
|
+
kept.push(cand);
|
|
400
|
+
}
|
|
401
|
+
return kept;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Register discovered candidates as a workspace in the registry.
|
|
405
|
+
*
|
|
406
|
+
* Creates a single multi-repo workspace and adds each candidate as a
|
|
407
|
+
* repo entry. Skips candidates whose path is already registered.
|
|
408
|
+
*/
|
|
409
|
+
async registerDiscovered(workspaceName, candidates) {
|
|
410
|
+
if (candidates.length === 0)
|
|
411
|
+
return { added: 0, skipped: 0 };
|
|
412
|
+
const data = await this.load();
|
|
413
|
+
if (!data.workspaces[workspaceName]) {
|
|
414
|
+
data.workspaces[workspaceName] = {
|
|
415
|
+
home: dirname(candidates[0].path),
|
|
416
|
+
mode: 'multi-repo',
|
|
417
|
+
repos: {},
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
const ws = data.workspaces[workspaceName];
|
|
421
|
+
let added = 0;
|
|
422
|
+
let skipped = 0;
|
|
423
|
+
for (const cand of candidates) {
|
|
424
|
+
if (cand.alreadyRegistered) {
|
|
425
|
+
skipped++;
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
// Avoid clobbering an existing repo entry of the same name
|
|
429
|
+
let repoName = cand.name;
|
|
430
|
+
let suffix = 2;
|
|
431
|
+
while (ws.repos[repoName]) {
|
|
432
|
+
repoName = `${cand.name}-${suffix++}`;
|
|
433
|
+
}
|
|
434
|
+
ws.repos[repoName] = {
|
|
435
|
+
path: cand.path,
|
|
436
|
+
remote: cand.remote,
|
|
437
|
+
extensions: [],
|
|
438
|
+
};
|
|
439
|
+
added++;
|
|
440
|
+
}
|
|
441
|
+
if (Object.keys(data.workspaces).length === 1) {
|
|
442
|
+
data.defaultWorkspace = workspaceName;
|
|
443
|
+
}
|
|
444
|
+
await this.save(data);
|
|
445
|
+
return { added, skipped };
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Push workspace repos to remote (always private)
|
|
449
|
+
*/
|
|
450
|
+
async pushWorkspace(workspaceName) {
|
|
451
|
+
const data = await this.load();
|
|
452
|
+
const name = workspaceName || data.defaultWorkspace;
|
|
453
|
+
const workspace = data.workspaces[name];
|
|
454
|
+
if (!workspace) {
|
|
455
|
+
throw new Error(`Workspace "${name}" not found`);
|
|
456
|
+
}
|
|
457
|
+
let canonical = null;
|
|
458
|
+
const canonicalConfigPath = projectAiwgPath(workspace.home, 'aiwg.config');
|
|
459
|
+
let canonicalDeclared = false;
|
|
460
|
+
if (existsSync(canonicalConfigPath)) {
|
|
461
|
+
try {
|
|
462
|
+
const raw = JSON.parse(readFileSync(canonicalConfigPath, 'utf8'));
|
|
463
|
+
canonicalDeclared = Array.isArray(raw.repos);
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
console.log(` Refusing workspace push — invalid canonical config: ${error instanceof Error ? error.message : String(error)}`);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (canonicalDeclared) {
|
|
471
|
+
try {
|
|
472
|
+
canonical = await resolveWorkspace(workspace.home, workspace.home);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
console.log(` Refusing workspace push — canonical workspace resolution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
for (const [repoName, repo] of Object.entries(workspace.repos)) {
|
|
480
|
+
if (!existsSync(repo.path)) {
|
|
481
|
+
console.log(` Skipping ${repoName} — path does not exist`);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
const member = canonical?.members.find((candidate) => resolve(candidate.path) === resolve(repo.path));
|
|
485
|
+
if (canonical && !member) {
|
|
486
|
+
console.log(` Skipping ${repoName} — denied: path is not listed in workspace config`);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
if (member && !member.allowed.includes('push')) {
|
|
490
|
+
console.log(` Skipping ${repoName} — denied: workspace member does not allow push`);
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
const remote = member?.remotes.primary ?? (repo.remote ? 'origin' : undefined);
|
|
494
|
+
const branch = member?.delivery.default_branch ?? 'main';
|
|
495
|
+
if (remote) {
|
|
496
|
+
console.log(` Pushing ${repoName} to ${remote}/${branch}...`);
|
|
497
|
+
try {
|
|
498
|
+
execSync(`git push ${shellEscape(remote)} ${shellEscape(branch)}`, {
|
|
499
|
+
cwd: repo.path,
|
|
500
|
+
stdio: 'pipe',
|
|
501
|
+
});
|
|
502
|
+
console.log(` ${repoName}: pushed`);
|
|
503
|
+
}
|
|
504
|
+
catch (err) {
|
|
505
|
+
console.log(` ${repoName}: push failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
console.log(` ${repoName}: no remote configured`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Provision a repo at `repoPath`. Order of preference:
|
|
516
|
+
* 1. Pre-existing `.git` at the path → adopt (read remote, no init/clone).
|
|
517
|
+
* 2. `--from <url>` provided and target is empty → `git clone`.
|
|
518
|
+
* 3. Fallback → `mkdir` + `git init`.
|
|
519
|
+
*
|
|
520
|
+
* Returns the action taken and the resolved remote URL (if any).
|
|
521
|
+
*/
|
|
522
|
+
async function provisionRepo(repoPath, fromUrl, silent) {
|
|
523
|
+
// Case 1: existing .git at the path → adopt in place.
|
|
524
|
+
if (existsSync(resolve(repoPath, '.git'))) {
|
|
525
|
+
return { action: 'Adopted', remote: readGitRemote(repoPath) };
|
|
526
|
+
}
|
|
527
|
+
// Case 2: --from URL → clone (only if target is empty or doesn't exist).
|
|
528
|
+
if (fromUrl) {
|
|
529
|
+
const exists = existsSync(repoPath);
|
|
530
|
+
if (exists) {
|
|
531
|
+
// Refuse to clone over a non-empty existing dir to avoid surprise overwrites.
|
|
532
|
+
let entries = [];
|
|
533
|
+
try {
|
|
534
|
+
entries = readdirSync(repoPath);
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// ignore
|
|
538
|
+
}
|
|
539
|
+
if (entries.filter((e) => !e.startsWith('.')).length > 0) {
|
|
540
|
+
throw new Error(`Refusing to clone into non-empty directory: ${repoPath}. Move or remove it first.`);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
await mkdir(dirname(repoPath), { recursive: true });
|
|
544
|
+
execSync(`git clone ${shellEscape(fromUrl)} ${shellEscape(repoPath)}`, { stdio: silent ? 'pipe' : 'inherit' });
|
|
545
|
+
return { action: 'Cloned', remote: readGitRemote(repoPath) };
|
|
546
|
+
}
|
|
547
|
+
// Case 3: fresh init.
|
|
548
|
+
await mkdir(repoPath, { recursive: true });
|
|
549
|
+
execSync('git init', { cwd: repoPath, stdio: 'pipe' });
|
|
550
|
+
return { action: 'Created', remote: undefined };
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Minimal shell escaping for git URLs and paths passed via execSync.
|
|
554
|
+
* URLs are URL-encoded already, but paths may contain spaces.
|
|
555
|
+
*/
|
|
556
|
+
function shellEscape(s) {
|
|
557
|
+
if (/^[A-Za-z0-9_@:./~+,=-]+$/.test(s))
|
|
558
|
+
return s;
|
|
559
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Return the `origin` remote URL for a git repo rooted at `dirPath`, or
|
|
563
|
+
* undefined if not a git repo or no origin configured.
|
|
564
|
+
*/
|
|
565
|
+
function readGitRemote(dirPath) {
|
|
566
|
+
if (!existsSync(resolve(dirPath, '.git')))
|
|
567
|
+
return undefined;
|
|
568
|
+
try {
|
|
569
|
+
const out = execSync('git config --get remote.origin.url', {
|
|
570
|
+
cwd: dirPath,
|
|
571
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
572
|
+
})
|
|
573
|
+
.toString()
|
|
574
|
+
.trim();
|
|
575
|
+
return out || undefined;
|
|
576
|
+
}
|
|
577
|
+
catch {
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Walk up from targetPath's parent looking for an enclosing ops workspace.
|
|
583
|
+
* Returns the path of the enclosing workspace, or null if none found.
|
|
584
|
+
*
|
|
585
|
+
* Marker: OpsInventory.yaml (the file the ops scaffolder seeds at workspace
|
|
586
|
+
* root). `.aiwg/` is intentionally not used as a marker since AIWG project
|
|
587
|
+
* roots routinely contain `.aiwg/aiwg.config` without being ops workspaces.
|
|
588
|
+
*/
|
|
589
|
+
function findEnclosingOpsWorkspace(targetPath) {
|
|
590
|
+
const resolved = resolve(targetPath);
|
|
591
|
+
let current = dirname(resolved);
|
|
592
|
+
// Stop walking when dirname() no longer advances (filesystem root).
|
|
593
|
+
while (true) {
|
|
594
|
+
if (existsSync(resolve(current, 'OpsInventory.yaml'))) {
|
|
595
|
+
return current;
|
|
596
|
+
}
|
|
597
|
+
const parent = dirname(current);
|
|
598
|
+
if (parent === current)
|
|
599
|
+
return null;
|
|
600
|
+
current = parent;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Seed an OpsInventory.yaml stub in a repo or subdirectory
|
|
605
|
+
*/
|
|
606
|
+
async function seedInventory(dirPath, name, extension) {
|
|
607
|
+
const inventoryPath = resolve(dirPath, 'OpsInventory.yaml');
|
|
608
|
+
if (existsSync(inventoryPath))
|
|
609
|
+
return;
|
|
610
|
+
const fullName = EXTENSION_NAMES[extension] || extension;
|
|
611
|
+
const content = `apiVersion: aiwg.io/v1
|
|
612
|
+
kind: OpsInventory
|
|
613
|
+
metadata:
|
|
614
|
+
name: ${name}
|
|
615
|
+
domain: ${fullName}
|
|
616
|
+
created: ${new Date().toISOString().split('T')[0]}
|
|
617
|
+
|
|
618
|
+
# Add hosts, services, and resources below
|
|
619
|
+
inventory: []
|
|
620
|
+
`;
|
|
621
|
+
await writeFile(inventoryPath, content, 'utf-8');
|
|
622
|
+
}
|
|
623
|
+
//# sourceMappingURL=registry.js.map
|