@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,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Obsidian Storage Adapter
|
|
3
|
+
*
|
|
4
|
+
* Writes and reads markdown files in an Obsidian vault on disk. The
|
|
5
|
+
* adapter is filesystem-shaped — Obsidian vaults are directories of
|
|
6
|
+
* `.md` files plus a hidden `.obsidian/` config dir we never touch.
|
|
7
|
+
*
|
|
8
|
+
* About the official Obsidian CLI: as of Feb 2026 Obsidian ships an
|
|
9
|
+
* official CLI for vault interactions. Its primary surface is opening
|
|
10
|
+
* notes / running commands against a *running* Obsidian instance, not
|
|
11
|
+
* arbitrary external file writes. Obsidian's own file watcher handles
|
|
12
|
+
* picking up external markdown changes within a few seconds, so direct
|
|
13
|
+
* fs writes work cleanly when Obsidian is closed and converge quickly
|
|
14
|
+
* when it's open.
|
|
15
|
+
*
|
|
16
|
+
* What this adapter does:
|
|
17
|
+
* - Reads / writes / lists / deletes markdown files via fs
|
|
18
|
+
* - Optional CLI reachability probe (when `useCli: true`) — emits a
|
|
19
|
+
* one-time warning if the user opted into CLI mode but the
|
|
20
|
+
* `obsidian` binary is missing
|
|
21
|
+
* - Refuses paths that resolve into the vault's `.obsidian/` config
|
|
22
|
+
* - Forwards `WriteMeta.frontmatter` into the markdown's YAML
|
|
23
|
+
* frontmatter when provided
|
|
24
|
+
* - Does NOT implement `query()` — Obsidian's search is not exposed
|
|
25
|
+
* via the CLI as of research date
|
|
26
|
+
*
|
|
27
|
+
* @design @.aiwg/architecture/storage-design.md (§5.2)
|
|
28
|
+
* @issue #934
|
|
29
|
+
* @issue #957
|
|
30
|
+
*/
|
|
31
|
+
import { existsSync } from 'fs';
|
|
32
|
+
import { mkdir, readFile, readdir, rm, stat, writeFile } from 'fs/promises';
|
|
33
|
+
import { dirname, join, relative, resolve, sep } from 'path';
|
|
34
|
+
import { execSync } from 'child_process';
|
|
35
|
+
const OBSIDIAN_CONFIG_DIR = '.obsidian';
|
|
36
|
+
export class ObsidianAdapter {
|
|
37
|
+
/** Absolute path to the root the adapter writes into (vault[/folder]). */
|
|
38
|
+
root;
|
|
39
|
+
/** Absolute path to the vault — used to enforce the .obsidian/ guard. */
|
|
40
|
+
vault;
|
|
41
|
+
useCli;
|
|
42
|
+
/** Cached result of the CLI reachability probe so we only warn once. */
|
|
43
|
+
cliWarned = false;
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this.vault = resolve(expandHome(config.vault));
|
|
46
|
+
this.root = config.folder ? join(this.vault, config.folder) : this.vault;
|
|
47
|
+
this.useCli = config.useCli ?? true;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate a subsystem-relative path. Rejects traversal, absolute
|
|
51
|
+
* paths, backslashes, and any path that resolves into the vault's
|
|
52
|
+
* `.obsidian/` config directory.
|
|
53
|
+
*/
|
|
54
|
+
resolveSafe(relPath) {
|
|
55
|
+
if (typeof relPath !== 'string' || relPath.length === 0) {
|
|
56
|
+
throw new Error('storage(obsidian): path must be a non-empty string');
|
|
57
|
+
}
|
|
58
|
+
if (relPath.includes('\\')) {
|
|
59
|
+
throw new Error(`storage(obsidian): backslash not allowed in path "${relPath}"`);
|
|
60
|
+
}
|
|
61
|
+
if (relPath.startsWith('/') || relPath.startsWith('~')) {
|
|
62
|
+
throw new Error(`storage(obsidian): absolute paths not allowed: "${relPath}"`);
|
|
63
|
+
}
|
|
64
|
+
const segments = relPath.split('/');
|
|
65
|
+
if (segments.some((s) => s === '..')) {
|
|
66
|
+
throw new Error(`storage(obsidian): ".." traversal not allowed in "${relPath}"`);
|
|
67
|
+
}
|
|
68
|
+
const abs = resolve(this.root, relPath);
|
|
69
|
+
// Must stay under root
|
|
70
|
+
if (abs !== this.root && !abs.startsWith(this.root + sep)) {
|
|
71
|
+
throw new Error(`storage(obsidian): resolved path escapes folder root: "${relPath}"`);
|
|
72
|
+
}
|
|
73
|
+
// Must never enter .obsidian/
|
|
74
|
+
const relFromVault = relative(this.vault, abs);
|
|
75
|
+
if (relFromVault === OBSIDIAN_CONFIG_DIR ||
|
|
76
|
+
relFromVault.startsWith(OBSIDIAN_CONFIG_DIR + sep)) {
|
|
77
|
+
throw new Error(`storage(obsidian): refusing to operate on .obsidian/ vault config (${relPath})`);
|
|
78
|
+
}
|
|
79
|
+
return abs;
|
|
80
|
+
}
|
|
81
|
+
async init() {
|
|
82
|
+
if (!existsSync(this.vault)) {
|
|
83
|
+
throw new Error(`storage(obsidian): vault does not exist: ${this.vault}`);
|
|
84
|
+
}
|
|
85
|
+
if (this.useCli)
|
|
86
|
+
this.probeCli();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* One-shot best-effort `obsidian --version` probe. We only warn
|
|
90
|
+
* (never fail) — direct fs writes still work without the CLI.
|
|
91
|
+
*/
|
|
92
|
+
probeCli() {
|
|
93
|
+
if (this.cliWarned)
|
|
94
|
+
return;
|
|
95
|
+
try {
|
|
96
|
+
execSync('obsidian --version', {
|
|
97
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
98
|
+
timeout: 2000,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
this.cliWarned = true;
|
|
103
|
+
process.stderr.write(`storage(obsidian): CLI requested (useCli: true) but the \`obsidian\` binary was not found.\n` +
|
|
104
|
+
` AIWG will continue with direct file writes against the vault.\n` +
|
|
105
|
+
` Set "useCli": false in storage.config to suppress this warning.\n`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async read(path) {
|
|
109
|
+
const abs = this.resolveSafe(path);
|
|
110
|
+
if (!existsSync(abs))
|
|
111
|
+
return null;
|
|
112
|
+
return readFile(abs, 'utf-8');
|
|
113
|
+
}
|
|
114
|
+
async write(path, content, meta) {
|
|
115
|
+
const abs = this.resolveSafe(path);
|
|
116
|
+
await mkdir(dirname(abs), { recursive: true });
|
|
117
|
+
// Merge supplied frontmatter into the markdown payload (only when
|
|
118
|
+
// there isn't already YAML frontmatter at the top — we don't want
|
|
119
|
+
// to overwrite user-written frontmatter inadvertently).
|
|
120
|
+
let body = content;
|
|
121
|
+
if (meta?.frontmatter && Object.keys(meta.frontmatter).length > 0 && !startsWithFrontmatter(content)) {
|
|
122
|
+
body = renderFrontmatter(meta.frontmatter) + content;
|
|
123
|
+
}
|
|
124
|
+
await writeFile(abs, body, 'utf-8');
|
|
125
|
+
}
|
|
126
|
+
async list(prefix) {
|
|
127
|
+
if (typeof prefix !== 'string') {
|
|
128
|
+
throw new Error('storage(obsidian): list prefix must be a string');
|
|
129
|
+
}
|
|
130
|
+
if (prefix.length > 0)
|
|
131
|
+
this.resolveSafe(prefix);
|
|
132
|
+
if (!existsSync(this.root))
|
|
133
|
+
return [];
|
|
134
|
+
const out = [];
|
|
135
|
+
await walkInto(this.root, this.root, this.vault, prefix, out);
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
async delete(path) {
|
|
139
|
+
const abs = this.resolveSafe(path);
|
|
140
|
+
if (!existsSync(abs))
|
|
141
|
+
return;
|
|
142
|
+
await rm(abs, { force: true });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async function walkInto(root, dir, vault, prefix, out) {
|
|
146
|
+
let entries;
|
|
147
|
+
try {
|
|
148
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
for (const e of entries) {
|
|
154
|
+
// Skip the vault config directory anywhere under the walk
|
|
155
|
+
if (e.name === OBSIDIAN_CONFIG_DIR) {
|
|
156
|
+
const fullForCheck = join(dir, e.name);
|
|
157
|
+
// Only skip when this is *the* vault's .obsidian/ — a user-created
|
|
158
|
+
// folder named ".obsidian" inside content would still be skipped
|
|
159
|
+
// out of paranoia, which matches the safety stance.
|
|
160
|
+
if (relative(vault, fullForCheck) === OBSIDIAN_CONFIG_DIR)
|
|
161
|
+
continue;
|
|
162
|
+
continue; // be conservative: skip any .obsidian directory
|
|
163
|
+
}
|
|
164
|
+
const full = join(dir, e.name);
|
|
165
|
+
const rel = relative(root, full).split(sep).join('/');
|
|
166
|
+
if (e.isDirectory()) {
|
|
167
|
+
if (prefix === '' || rel.startsWith(prefix) || prefix.startsWith(rel + '/')) {
|
|
168
|
+
await walkInto(root, full, vault, prefix, out);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (!e.isFile())
|
|
173
|
+
continue;
|
|
174
|
+
if (prefix !== '' && !rel.startsWith(prefix))
|
|
175
|
+
continue;
|
|
176
|
+
let size;
|
|
177
|
+
let modifiedAt;
|
|
178
|
+
try {
|
|
179
|
+
const s = await stat(full);
|
|
180
|
+
size = s.size;
|
|
181
|
+
modifiedAt = s.mtime;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// ignore
|
|
185
|
+
}
|
|
186
|
+
const entry = { path: rel };
|
|
187
|
+
if (size !== undefined)
|
|
188
|
+
entry.size = size;
|
|
189
|
+
if (modifiedAt !== undefined)
|
|
190
|
+
entry.modifiedAt = modifiedAt;
|
|
191
|
+
out.push(entry);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function expandHome(p) {
|
|
195
|
+
if (p.startsWith('~/')) {
|
|
196
|
+
const { homedir } = require('os');
|
|
197
|
+
return join(homedir(), p.slice(2));
|
|
198
|
+
}
|
|
199
|
+
if (p === '~') {
|
|
200
|
+
const { homedir } = require('os');
|
|
201
|
+
return homedir();
|
|
202
|
+
}
|
|
203
|
+
return p;
|
|
204
|
+
}
|
|
205
|
+
function startsWithFrontmatter(content) {
|
|
206
|
+
// Obsidian frontmatter convention: starts with `---` on a line by itself
|
|
207
|
+
return /^---\s*\r?\n/.test(content);
|
|
208
|
+
}
|
|
209
|
+
function renderFrontmatter(fm) {
|
|
210
|
+
const lines = ['---'];
|
|
211
|
+
for (const [k, v] of Object.entries(fm)) {
|
|
212
|
+
lines.push(`${k}: ${formatYamlScalar(v)}`);
|
|
213
|
+
}
|
|
214
|
+
lines.push('---', '');
|
|
215
|
+
return lines.join('\n');
|
|
216
|
+
}
|
|
217
|
+
function formatYamlScalar(v) {
|
|
218
|
+
if (v === null || v === undefined)
|
|
219
|
+
return '';
|
|
220
|
+
if (typeof v === 'boolean' || typeof v === 'number')
|
|
221
|
+
return String(v);
|
|
222
|
+
if (Array.isArray(v))
|
|
223
|
+
return '[' + v.map((x) => formatYamlScalar(x)).join(', ') + ']';
|
|
224
|
+
if (typeof v === 'string') {
|
|
225
|
+
// Quote strings containing YAML special characters
|
|
226
|
+
if (/[:\#\n\r\t&*?{}\[\]|>'"%@`!,]/.test(v) || /^\s|\s$/.test(v) || v.length === 0) {
|
|
227
|
+
return JSON.stringify(v);
|
|
228
|
+
}
|
|
229
|
+
return v;
|
|
230
|
+
}
|
|
231
|
+
return JSON.stringify(v);
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=obsidian.js.map
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage CLI — `aiwg storage <subcommand>`
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* show — print effective config + resolved physical paths
|
|
6
|
+
* list-backends — inventory of compiled-in adapters with status
|
|
7
|
+
* test <subsystem> — round-trip read/write/list/delete through the
|
|
8
|
+
* configured backend
|
|
9
|
+
* migrate <subsystem> — copy entries from one backend to another
|
|
10
|
+
*
|
|
11
|
+
* @design @.aiwg/architecture/storage-design.md (§7)
|
|
12
|
+
* @issue #934
|
|
13
|
+
* @issue #954
|
|
14
|
+
* @issue #955
|
|
15
|
+
*/
|
|
16
|
+
import { randomUUID } from 'crypto';
|
|
17
|
+
import { existsSync } from 'fs';
|
|
18
|
+
import { mkdir, readFile, writeFile, appendFile } from 'fs/promises';
|
|
19
|
+
import { dirname, join, resolve as resolvePath } from 'path';
|
|
20
|
+
import { BACKEND_TYPES, FilesystemAdapter, ObsidianAdapter, LogseqAdapter, FortemiAdapter, SUBSYSTEM_KEYS, getLoadedConfig, initStorage, resolveStorage, resolveSubsystemRoot, storageConfigPath, } from './index.js';
|
|
21
|
+
export async function main(args) {
|
|
22
|
+
const subcommand = args[0];
|
|
23
|
+
const subArgs = args.slice(1);
|
|
24
|
+
const projectRoot = process.cwd();
|
|
25
|
+
switch (subcommand) {
|
|
26
|
+
case 'show':
|
|
27
|
+
await handleShow(projectRoot);
|
|
28
|
+
break;
|
|
29
|
+
case 'list-backends':
|
|
30
|
+
await handleListBackends(subArgs);
|
|
31
|
+
break;
|
|
32
|
+
case 'test':
|
|
33
|
+
await handleTest(projectRoot, subArgs);
|
|
34
|
+
break;
|
|
35
|
+
case 'migrate':
|
|
36
|
+
await handleMigrate(projectRoot, subArgs);
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
printUsage();
|
|
40
|
+
if (subcommand) {
|
|
41
|
+
throw new Error(`Unknown storage subcommand: ${subcommand}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function handleShow(projectRoot) {
|
|
46
|
+
await initStorage(projectRoot);
|
|
47
|
+
const config = await getLoadedConfig(projectRoot);
|
|
48
|
+
const cfgPath = storageConfigPath(projectRoot);
|
|
49
|
+
if (!config) {
|
|
50
|
+
console.log(`No storage.config — every subsystem uses the default fs backend under .aiwg/.\n`);
|
|
51
|
+
console.log(`Expected location (when configured): ${cfgPath}\n`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(`storage.config: ${cfgPath}`);
|
|
55
|
+
console.log(`schema version: ${config.version}`);
|
|
56
|
+
if (config.fallback)
|
|
57
|
+
console.log(`fallback: ${config.fallback}`);
|
|
58
|
+
console.log('');
|
|
59
|
+
}
|
|
60
|
+
console.log(`Subsystem Backend Resolved location`);
|
|
61
|
+
console.log(`───────────── ──────────── ──────────────────────────────────────────`);
|
|
62
|
+
for (const subsystem of SUBSYSTEM_KEYS) {
|
|
63
|
+
const backend = config?.backends?.[subsystem]?.type ?? 'fs';
|
|
64
|
+
const location = backend === 'fs'
|
|
65
|
+
? resolveSubsystemRoot(subsystem, projectRoot, config)
|
|
66
|
+
: describeBackendLocation(subsystem, config);
|
|
67
|
+
const sub = subsystem.padEnd(13);
|
|
68
|
+
const back = backend.padEnd(12);
|
|
69
|
+
console.log(` ${sub} ${back} ${location}`);
|
|
70
|
+
}
|
|
71
|
+
console.log('');
|
|
72
|
+
}
|
|
73
|
+
async function handleListBackends(args = []) {
|
|
74
|
+
const json = args.includes('--json');
|
|
75
|
+
if (json) {
|
|
76
|
+
const out = BACKEND_TYPES.map((t) => {
|
|
77
|
+
const status = backendStatus(t);
|
|
78
|
+
return {
|
|
79
|
+
type: t,
|
|
80
|
+
status: status.implemented ? 'ready' : 'stub',
|
|
81
|
+
note: status.note,
|
|
82
|
+
...(status.trackingIssue ? { tracking_issue: status.trackingIssue } : {}),
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
console.log(JSON.stringify(out, null, 2));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log(`Compiled-in storage backends:\n`);
|
|
89
|
+
console.log(` STATUS TYPE NOTES`);
|
|
90
|
+
console.log(` ────── ──────────── ────────────────────────────────────────`);
|
|
91
|
+
for (const t of BACKEND_TYPES) {
|
|
92
|
+
const status = backendStatus(t);
|
|
93
|
+
const sym = status.implemented ? 'READY ' : 'STUB ';
|
|
94
|
+
console.log(` ${sym} ${t.padEnd(12)} ${status.note}`);
|
|
95
|
+
}
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
98
|
+
async function handleTest(projectRoot, args) {
|
|
99
|
+
const subsystem = args[0];
|
|
100
|
+
if (!subsystem || !SUBSYSTEM_KEYS.includes(subsystem)) {
|
|
101
|
+
throw new Error(`Usage: aiwg storage test <subsystem>\n` +
|
|
102
|
+
` Valid subsystems: ${SUBSYSTEM_KEYS.join(', ')}`);
|
|
103
|
+
}
|
|
104
|
+
await initStorage(projectRoot);
|
|
105
|
+
const adapter = await resolveStorage(subsystem);
|
|
106
|
+
const probePath = `.aiwg-storage-test/${randomUUID()}.txt`;
|
|
107
|
+
const probeContent = `aiwg storage test ${subsystem} ${new Date().toISOString()}\n`;
|
|
108
|
+
let stage = 'init';
|
|
109
|
+
try {
|
|
110
|
+
stage = 'write';
|
|
111
|
+
console.log(` ► write ${probePath}`);
|
|
112
|
+
await adapter.write(probePath, probeContent);
|
|
113
|
+
stage = 'read';
|
|
114
|
+
console.log(` ► read ${probePath}`);
|
|
115
|
+
const got = await adapter.read(probePath);
|
|
116
|
+
if (got !== probeContent) {
|
|
117
|
+
throw new Error(`read mismatch: expected ${JSON.stringify(probeContent)}, got ${JSON.stringify(got)}`);
|
|
118
|
+
}
|
|
119
|
+
stage = 'list';
|
|
120
|
+
console.log(` ► list prefix=.aiwg-storage-test/`);
|
|
121
|
+
const entries = await adapter.list('.aiwg-storage-test/');
|
|
122
|
+
if (!entries.some((e) => e.path === probePath)) {
|
|
123
|
+
throw new Error(`list missing probe path ${probePath}`);
|
|
124
|
+
}
|
|
125
|
+
stage = 'delete';
|
|
126
|
+
console.log(` ► delete ${probePath}`);
|
|
127
|
+
await adapter.delete(probePath);
|
|
128
|
+
const after = await adapter.read(probePath);
|
|
129
|
+
if (after !== null) {
|
|
130
|
+
throw new Error(`delete did not remove ${probePath}`);
|
|
131
|
+
}
|
|
132
|
+
console.log(`\n ✓ all 4 ops succeeded for subsystem "${subsystem}"\n`);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
throw new Error(`storage test failed at ${stage}: ${err.message}\n` +
|
|
136
|
+
` Subsystem: ${subsystem}\n Probe path: ${probePath}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* `aiwg storage migrate <subsystem> --from <spec> --to <spec> [--dry-run]`
|
|
141
|
+
*
|
|
142
|
+
* Spec format: `<type>:<location>` where type is one of fs/obsidian/
|
|
143
|
+
* logseq/fortemi and location is:
|
|
144
|
+
* fs → directory path (relative to projectRoot or absolute)
|
|
145
|
+
* obsidian → vault directory (folder via `--from-folder`/`--to-folder`)
|
|
146
|
+
* logseq → graph directory
|
|
147
|
+
* fortemi → MCP server name (default: 'fortemi')
|
|
148
|
+
*
|
|
149
|
+
* Examples:
|
|
150
|
+
* aiwg storage migrate memory --from fs:.aiwg/memory --to obsidian:~/vault --to-folder AIWG/memory
|
|
151
|
+
* aiwg storage migrate kb --from fs:.aiwg/kb --to fortemi:fortemi --dry-run
|
|
152
|
+
*
|
|
153
|
+
* Walks source.list(''), reads each entry, writes to destination. Tracks
|
|
154
|
+
* progress in `.aiwg/.storage-cache/migrations/<id>.jsonl` so re-running
|
|
155
|
+
* resumes from the last successfully-migrated entry.
|
|
156
|
+
*
|
|
157
|
+
* @issue #955
|
|
158
|
+
*/
|
|
159
|
+
async function handleMigrate(projectRoot, args) {
|
|
160
|
+
const opts = parseMigrateArgs(args);
|
|
161
|
+
const source = buildAdapter(opts.subsystem, opts.from, projectRoot);
|
|
162
|
+
const destination = buildAdapter(opts.subsystem, opts.to, projectRoot);
|
|
163
|
+
if (locationsEqual(opts.from, opts.to, projectRoot)) {
|
|
164
|
+
throw new Error(`Refusing to migrate: source and destination resolve to the same location.\n ${describeSpec(opts.from)}\n ${describeSpec(opts.to)}`);
|
|
165
|
+
}
|
|
166
|
+
if (source.init)
|
|
167
|
+
await source.init();
|
|
168
|
+
if (destination.init)
|
|
169
|
+
await destination.init();
|
|
170
|
+
console.log(`storage migrate (${opts.dryRun ? 'DRY RUN' : 'live'})`);
|
|
171
|
+
console.log(` subsystem: ${opts.subsystem}`);
|
|
172
|
+
console.log(` from: ${describeSpec(opts.from)}`);
|
|
173
|
+
console.log(` to: ${describeSpec(opts.to)}`);
|
|
174
|
+
console.log('');
|
|
175
|
+
const entries = await source.list('');
|
|
176
|
+
if (entries.length === 0) {
|
|
177
|
+
console.log('No entries to migrate.');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Resume support: read the per-migration log; skip already-done paths
|
|
181
|
+
const migrationLogPath = resolvePath(projectRoot, '.aiwg', '.storage-cache', 'migrations', `${opts.subsystem}-${specSlug(opts.from)}-to-${specSlug(opts.to)}.jsonl`);
|
|
182
|
+
const completed = await readCompletedSet(migrationLogPath);
|
|
183
|
+
let copied = 0;
|
|
184
|
+
let skipped = 0;
|
|
185
|
+
let errored = 0;
|
|
186
|
+
for (const entry of entries) {
|
|
187
|
+
if (completed.has(entry.path)) {
|
|
188
|
+
skipped++;
|
|
189
|
+
console.log(` ✓ ${entry.path} (already migrated, skipped)`);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (opts.dryRun) {
|
|
193
|
+
copied++;
|
|
194
|
+
console.log(` → ${entry.path} (would copy)`);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const content = await source.read(entry.path);
|
|
199
|
+
if (content === null) {
|
|
200
|
+
errored++;
|
|
201
|
+
console.log(` ✗ ${entry.path} (read returned null)`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
await destination.write(entry.path, content);
|
|
205
|
+
await recordCompletion(migrationLogPath, entry.path);
|
|
206
|
+
copied++;
|
|
207
|
+
console.log(` ✓ ${entry.path}`);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
errored++;
|
|
211
|
+
console.log(` ✗ ${entry.path} (${err.message})`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (source.close)
|
|
215
|
+
await source.close();
|
|
216
|
+
if (destination.close)
|
|
217
|
+
await destination.close();
|
|
218
|
+
console.log('');
|
|
219
|
+
console.log(`Summary: copied=${copied} skipped=${skipped} errored=${errored} total=${entries.length}`);
|
|
220
|
+
if (!opts.dryRun) {
|
|
221
|
+
console.log(`Migration log: ${migrationLogPath}`);
|
|
222
|
+
}
|
|
223
|
+
if (errored > 0) {
|
|
224
|
+
throw new Error(`${errored} entr${errored === 1 ? 'y' : 'ies'} failed to migrate.`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function parseMigrateArgs(args) {
|
|
228
|
+
let subsystem;
|
|
229
|
+
let from;
|
|
230
|
+
let to;
|
|
231
|
+
let fromFolder;
|
|
232
|
+
let toFolder;
|
|
233
|
+
let dryRun = false;
|
|
234
|
+
for (let i = 0; i < args.length; i++) {
|
|
235
|
+
const a = args[i];
|
|
236
|
+
if (a === '--from')
|
|
237
|
+
from = args[++i];
|
|
238
|
+
else if (a === '--to')
|
|
239
|
+
to = args[++i];
|
|
240
|
+
else if (a === '--from-folder')
|
|
241
|
+
fromFolder = args[++i];
|
|
242
|
+
else if (a === '--to-folder')
|
|
243
|
+
toFolder = args[++i];
|
|
244
|
+
else if (a === '--dry-run')
|
|
245
|
+
dryRun = true;
|
|
246
|
+
else if (!a.startsWith('--') && !subsystem)
|
|
247
|
+
subsystem = a;
|
|
248
|
+
else
|
|
249
|
+
throw new Error(`Unknown migrate flag: ${a}`);
|
|
250
|
+
}
|
|
251
|
+
if (!subsystem || !SUBSYSTEM_KEYS.includes(subsystem)) {
|
|
252
|
+
throw new Error(`Usage: aiwg storage migrate <subsystem> --from <type>:<location> --to <type>:<location> [--dry-run]\n Valid subsystems: ${SUBSYSTEM_KEYS.join(', ')}`);
|
|
253
|
+
}
|
|
254
|
+
if (!from)
|
|
255
|
+
throw new Error('storage migrate: --from <type>:<location> is required');
|
|
256
|
+
if (!to)
|
|
257
|
+
throw new Error('storage migrate: --to <type>:<location> is required');
|
|
258
|
+
return {
|
|
259
|
+
subsystem: subsystem,
|
|
260
|
+
from: { ...parseSpec(from), ...(fromFolder ? { folder: fromFolder } : {}) },
|
|
261
|
+
to: { ...parseSpec(to), ...(toFolder ? { folder: toFolder } : {}) },
|
|
262
|
+
dryRun,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function parseSpec(raw) {
|
|
266
|
+
const idx = raw.indexOf(':');
|
|
267
|
+
if (idx === -1) {
|
|
268
|
+
throw new Error(`Invalid backend spec "${raw}" — expected <type>:<location>`);
|
|
269
|
+
}
|
|
270
|
+
const type = raw.slice(0, idx);
|
|
271
|
+
const location = raw.slice(idx + 1);
|
|
272
|
+
if (!BACKEND_TYPES.includes(type)) {
|
|
273
|
+
throw new Error(`Unknown backend type "${type}" in spec "${raw}". Valid: ${BACKEND_TYPES.join(', ')}`);
|
|
274
|
+
}
|
|
275
|
+
if (location.length === 0) {
|
|
276
|
+
throw new Error(`Empty location in backend spec "${raw}"`);
|
|
277
|
+
}
|
|
278
|
+
return { type: type, location };
|
|
279
|
+
}
|
|
280
|
+
function buildAdapter(subsystem, spec, projectRoot) {
|
|
281
|
+
switch (spec.type) {
|
|
282
|
+
case 'fs': {
|
|
283
|
+
const root = expandFsLocation(spec.location, projectRoot);
|
|
284
|
+
return new FilesystemAdapter(root);
|
|
285
|
+
}
|
|
286
|
+
case 'obsidian':
|
|
287
|
+
return new ObsidianAdapter({
|
|
288
|
+
type: 'obsidian',
|
|
289
|
+
vault: expandFsLocation(spec.location, projectRoot),
|
|
290
|
+
...(spec.folder ? { folder: spec.folder } : {}),
|
|
291
|
+
useCli: false,
|
|
292
|
+
});
|
|
293
|
+
case 'logseq':
|
|
294
|
+
return new LogseqAdapter({
|
|
295
|
+
type: 'logseq',
|
|
296
|
+
graph: expandFsLocation(spec.location, projectRoot),
|
|
297
|
+
useApi: false,
|
|
298
|
+
});
|
|
299
|
+
case 'fortemi':
|
|
300
|
+
return new FortemiAdapter({
|
|
301
|
+
subsystem,
|
|
302
|
+
config: { type: 'fortemi', mcpServer: spec.location },
|
|
303
|
+
});
|
|
304
|
+
case 'notion':
|
|
305
|
+
case 'anythingllm':
|
|
306
|
+
case 's3':
|
|
307
|
+
case 'webdav':
|
|
308
|
+
throw new Error(`storage migrate: backend "${spec.type}" not yet implemented. ` +
|
|
309
|
+
`See issues #959, #960, #962, #963 for tracking.`);
|
|
310
|
+
default: {
|
|
311
|
+
const _exhaustive = spec.type;
|
|
312
|
+
void _exhaustive;
|
|
313
|
+
throw new Error(`Unhandled backend type ${spec.type}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function expandFsLocation(loc, projectRoot) {
|
|
318
|
+
if (loc.startsWith('~/')) {
|
|
319
|
+
const { homedir } = require('os');
|
|
320
|
+
return join(homedir(), loc.slice(2));
|
|
321
|
+
}
|
|
322
|
+
if (loc === '~') {
|
|
323
|
+
const { homedir } = require('os');
|
|
324
|
+
return homedir();
|
|
325
|
+
}
|
|
326
|
+
if (loc.startsWith('/'))
|
|
327
|
+
return loc;
|
|
328
|
+
return resolvePath(projectRoot, loc);
|
|
329
|
+
}
|
|
330
|
+
function locationsEqual(a, b, projectRoot) {
|
|
331
|
+
if (a.type !== b.type)
|
|
332
|
+
return false;
|
|
333
|
+
if (a.type === 'fortemi')
|
|
334
|
+
return a.location === b.location;
|
|
335
|
+
// For file-shaped backends, compare resolved fs paths
|
|
336
|
+
return expandFsLocation(a.location, projectRoot) === expandFsLocation(b.location, projectRoot);
|
|
337
|
+
}
|
|
338
|
+
function describeSpec(spec) {
|
|
339
|
+
return spec.folder ? `${spec.type}:${spec.location} (folder=${spec.folder})` : `${spec.type}:${spec.location}`;
|
|
340
|
+
}
|
|
341
|
+
function specSlug(spec) {
|
|
342
|
+
return `${spec.type}-${spec.location.replace(/[^a-zA-Z0-9]/g, '_').slice(0, 32)}`;
|
|
343
|
+
}
|
|
344
|
+
async function readCompletedSet(logPath) {
|
|
345
|
+
if (!existsSync(logPath))
|
|
346
|
+
return new Set();
|
|
347
|
+
try {
|
|
348
|
+
const content = await readFile(logPath, 'utf-8');
|
|
349
|
+
const out = new Set();
|
|
350
|
+
for (const line of content.split('\n')) {
|
|
351
|
+
if (!line.trim())
|
|
352
|
+
continue;
|
|
353
|
+
try {
|
|
354
|
+
const obj = JSON.parse(line);
|
|
355
|
+
if (obj.path)
|
|
356
|
+
out.add(obj.path);
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
/* ignore malformed line */
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return out;
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
return new Set();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async function recordCompletion(logPath, path) {
|
|
369
|
+
await mkdir(dirname(logPath), { recursive: true });
|
|
370
|
+
const line = JSON.stringify({ path, ts: new Date().toISOString() }) + '\n';
|
|
371
|
+
if (existsSync(logPath)) {
|
|
372
|
+
await appendFile(logPath, line, 'utf-8');
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
await writeFile(logPath, line, 'utf-8');
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
function describeBackendLocation(subsystem, config) {
|
|
379
|
+
const b = config?.backends?.[subsystem];
|
|
380
|
+
if (!b)
|
|
381
|
+
return '(default fs)';
|
|
382
|
+
switch (b.type) {
|
|
383
|
+
case 'obsidian':
|
|
384
|
+
return `obsidian: ${b.vault}${b.folder ? '/' + b.folder : ''}`;
|
|
385
|
+
case 'logseq':
|
|
386
|
+
return `logseq: ${b.graph}${b.useApi === false ? ' (file mode)' : ' (HTTP API)'}`;
|
|
387
|
+
case 'notion':
|
|
388
|
+
return `notion: ${'pageId' in b.parent ? 'page=' + b.parent.pageId : 'database=' + b.parent.databaseId}`;
|
|
389
|
+
case 'anythingllm':
|
|
390
|
+
return `anythingllm: ${b.baseUrl}/${b.workspace}${b.folder ? '/' + b.folder : ''}`;
|
|
391
|
+
case 'fortemi':
|
|
392
|
+
return `fortemi: mcp=${b.mcpServer ?? 'fortemi'}${b.scheme ? ' scheme=' + b.scheme : ''}`;
|
|
393
|
+
case 's3':
|
|
394
|
+
return `s3: ${b.bucket}${b.prefix ? '/' + b.prefix : ''}${b.endpoint ? ' @ ' + b.endpoint : ''}`;
|
|
395
|
+
case 'webdav':
|
|
396
|
+
return `webdav: ${b.url}`;
|
|
397
|
+
default:
|
|
398
|
+
return `(${b.type})`;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
const ISSUE_TRACKER_BASE = 'https://git.integrolabs.net/roctinam/aiwg/issues';
|
|
402
|
+
export function backendStatus(type) {
|
|
403
|
+
switch (type) {
|
|
404
|
+
case 'fs':
|
|
405
|
+
return { implemented: true, note: 'default backend — local filesystem' };
|
|
406
|
+
case 'obsidian':
|
|
407
|
+
return { implemented: true, note: 'fs-shaped vault writes; refuses .obsidian/' };
|
|
408
|
+
case 'logseq':
|
|
409
|
+
return { implemented: true, note: 'fs writes; YAML→property:: transform; refuses logseq/' };
|
|
410
|
+
case 'notion':
|
|
411
|
+
return {
|
|
412
|
+
implemented: false,
|
|
413
|
+
note: 'planned (#959) — REST + external_id upsert',
|
|
414
|
+
trackingIssue: `${ISSUE_TRACKER_BASE}/959`,
|
|
415
|
+
};
|
|
416
|
+
case 'anythingllm':
|
|
417
|
+
return {
|
|
418
|
+
implemented: false,
|
|
419
|
+
note: 'planned (#960) — multipart upload',
|
|
420
|
+
trackingIssue: `${ISSUE_TRACKER_BASE}/960`,
|
|
421
|
+
};
|
|
422
|
+
case 'fortemi':
|
|
423
|
+
return { implemented: true, note: 'MCP-routed via configured Fortemi server (alpha)' };
|
|
424
|
+
case 's3':
|
|
425
|
+
return {
|
|
426
|
+
implemented: false,
|
|
427
|
+
note: 'planned (#962) — phase 3',
|
|
428
|
+
trackingIssue: `${ISSUE_TRACKER_BASE}/962`,
|
|
429
|
+
};
|
|
430
|
+
case 'webdav':
|
|
431
|
+
return {
|
|
432
|
+
implemented: false,
|
|
433
|
+
note: 'planned (#963) — phase 3',
|
|
434
|
+
trackingIssue: `${ISSUE_TRACKER_BASE}/963`,
|
|
435
|
+
};
|
|
436
|
+
default: {
|
|
437
|
+
const _exhaustive = type;
|
|
438
|
+
void _exhaustive;
|
|
439
|
+
return { implemented: false, note: 'unknown' };
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
function printUsage() {
|
|
444
|
+
console.log(`Usage: aiwg storage <subcommand>
|
|
445
|
+
|
|
446
|
+
Subcommands:
|
|
447
|
+
show Print effective config + resolved physical paths
|
|
448
|
+
list-backends [--json] Inventory of compiled-in adapters; --json emits structured output including tracking_issue URL for stubs
|
|
449
|
+
test <subsystem> Round-trip read/write/list/delete through the configured backend
|
|
450
|
+
migrate <subsystem> Copy entries from one backend to another (#955)
|
|
451
|
+
--from <type>:<location> Source spec (fs:./dir, obsidian:~/vault, logseq:./graph, fortemi:server)
|
|
452
|
+
--to <type>:<location> Destination spec (same format)
|
|
453
|
+
--from-folder <folder> Optional Obsidian subfolder for source
|
|
454
|
+
--to-folder <folder> Optional Obsidian subfolder for destination
|
|
455
|
+
--dry-run Preview operations without writing
|
|
456
|
+
|
|
457
|
+
Subsystems: ${SUBSYSTEM_KEYS.join(', ')}
|
|
458
|
+
|
|
459
|
+
Examples:
|
|
460
|
+
aiwg storage show
|
|
461
|
+
aiwg storage list-backends
|
|
462
|
+
aiwg storage test activity_log
|
|
463
|
+
aiwg storage migrate memory --from fs:.aiwg/memory --to obsidian:~/vault --to-folder AIWG/memory --dry-run
|
|
464
|
+
aiwg storage migrate kb --from fs:.aiwg/kb --to fortemi:fortemi
|
|
465
|
+
|
|
466
|
+
See @.aiwg/architecture/storage-design.md for the design.`);
|
|
467
|
+
}
|
|
468
|
+
//# sourceMappingURL=cli.js.map
|