universal-agent-protocol 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +462 -0
- package/dist/analyzers/index.d.ts +3 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +656 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/bin/cli.d.ts +3 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +506 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bin/tool-calls.d.ts +3 -0
- package/dist/bin/tool-calls.d.ts.map +1 -0
- package/dist/bin/tool-calls.js +4 -0
- package/dist/bin/tool-calls.js.map +1 -0
- package/dist/cli/agent.d.ts +20 -0
- package/dist/cli/agent.d.ts.map +1 -0
- package/dist/cli/agent.js +434 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/analyze.d.ts +7 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +103 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/cli/coord.d.ts +7 -0
- package/dist/cli/coord.d.ts.map +1 -0
- package/dist/cli/coord.js +138 -0
- package/dist/cli/coord.js.map +1 -0
- package/dist/cli/dashboard.d.ts +8 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +704 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/deploy.d.ts +19 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +267 -0
- package/dist/cli/deploy.js.map +1 -0
- package/dist/cli/droids.d.ts +9 -0
- package/dist/cli/droids.d.ts.map +1 -0
- package/dist/cli/droids.js +227 -0
- package/dist/cli/droids.js.map +1 -0
- package/dist/cli/generate.d.ts +17 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +432 -0
- package/dist/cli/generate.js.map +1 -0
- package/dist/cli/hooks.d.ts +9 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +374 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/init.d.ts +11 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +316 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp-router.d.ts +16 -0
- package/dist/cli/mcp-router.d.ts.map +1 -0
- package/dist/cli/mcp-router.js +143 -0
- package/dist/cli/mcp-router.js.map +1 -0
- package/dist/cli/memory.d.ts +24 -0
- package/dist/cli/memory.d.ts.map +1 -0
- package/dist/cli/memory.js +877 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/model.d.ts +15 -0
- package/dist/cli/model.d.ts.map +1 -0
- package/dist/cli/model.js +270 -0
- package/dist/cli/model.js.map +1 -0
- package/dist/cli/patterns.d.ts +26 -0
- package/dist/cli/patterns.d.ts.map +1 -0
- package/dist/cli/patterns.js +587 -0
- package/dist/cli/patterns.js.map +1 -0
- package/dist/cli/setup-mcp-router.d.ts +8 -0
- package/dist/cli/setup-mcp-router.d.ts.map +1 -0
- package/dist/cli/setup-mcp-router.js +163 -0
- package/dist/cli/setup-mcp-router.js.map +1 -0
- package/dist/cli/setup.d.ts +13 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +146 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/sync.d.ts +7 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +26 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/task.d.ts +33 -0
- package/dist/cli/task.d.ts.map +1 -0
- package/dist/cli/task.js +616 -0
- package/dist/cli/task.js.map +1 -0
- package/dist/cli/tool-calls.d.ts +8 -0
- package/dist/cli/tool-calls.d.ts.map +1 -0
- package/dist/cli/tool-calls.js +239 -0
- package/dist/cli/tool-calls.js.map +1 -0
- package/dist/cli/update.d.ts +10 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/cli/update.js +300 -0
- package/dist/cli/update.js.map +1 -0
- package/dist/cli/visualize.d.ts +77 -0
- package/dist/cli/visualize.d.ts.map +1 -0
- package/dist/cli/visualize.js +287 -0
- package/dist/cli/visualize.js.map +1 -0
- package/dist/cli/worktree.d.ts +9 -0
- package/dist/cli/worktree.d.ts.map +1 -0
- package/dist/cli/worktree.js +175 -0
- package/dist/cli/worktree.js.map +1 -0
- package/dist/coordination/capability-router.d.ts +79 -0
- package/dist/coordination/capability-router.d.ts.map +1 -0
- package/dist/coordination/capability-router.js +324 -0
- package/dist/coordination/capability-router.js.map +1 -0
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -0
- package/dist/coordination/database.js +131 -0
- package/dist/coordination/database.js.map +1 -0
- package/dist/coordination/deploy-batcher.d.ts +101 -0
- package/dist/coordination/deploy-batcher.d.ts.map +1 -0
- package/dist/coordination/deploy-batcher.js +565 -0
- package/dist/coordination/deploy-batcher.js.map +1 -0
- package/dist/coordination/index.d.ts +5 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +5 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/service.d.ts +81 -0
- package/dist/coordination/service.d.ts.map +1 -0
- package/dist/coordination/service.js +603 -0
- package/dist/coordination/service.js.map +1 -0
- package/dist/generators/claude-md.d.ts +3 -0
- package/dist/generators/claude-md.d.ts.map +1 -0
- package/dist/generators/claude-md.js +977 -0
- package/dist/generators/claude-md.js.map +1 -0
- package/dist/generators/template-loader.d.ts +105 -0
- package/dist/generators/template-loader.d.ts.map +1 -0
- package/dist/generators/template-loader.js +291 -0
- package/dist/generators/template-loader.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-router/config/parser.d.ts +9 -0
- package/dist/mcp-router/config/parser.d.ts.map +1 -0
- package/dist/mcp-router/config/parser.js +174 -0
- package/dist/mcp-router/config/parser.js.map +1 -0
- package/dist/mcp-router/executor/client.d.ts +31 -0
- package/dist/mcp-router/executor/client.d.ts.map +1 -0
- package/dist/mcp-router/executor/client.js +187 -0
- package/dist/mcp-router/executor/client.js.map +1 -0
- package/dist/mcp-router/index.d.ts +22 -0
- package/dist/mcp-router/index.d.ts.map +1 -0
- package/dist/mcp-router/index.js +18 -0
- package/dist/mcp-router/index.js.map +1 -0
- package/dist/mcp-router/output-compressor.d.ts +26 -0
- package/dist/mcp-router/output-compressor.d.ts.map +1 -0
- package/dist/mcp-router/output-compressor.js +236 -0
- package/dist/mcp-router/output-compressor.js.map +1 -0
- package/dist/mcp-router/search/fuzzy.d.ts +26 -0
- package/dist/mcp-router/search/fuzzy.d.ts.map +1 -0
- package/dist/mcp-router/search/fuzzy.js +94 -0
- package/dist/mcp-router/search/fuzzy.js.map +1 -0
- package/dist/mcp-router/server.d.ts +50 -0
- package/dist/mcp-router/server.d.ts.map +1 -0
- package/dist/mcp-router/server.js +229 -0
- package/dist/mcp-router/server.js.map +1 -0
- package/dist/mcp-router/session-stats.d.ts +37 -0
- package/dist/mcp-router/session-stats.d.ts.map +1 -0
- package/dist/mcp-router/session-stats.js +56 -0
- package/dist/mcp-router/session-stats.js.map +1 -0
- package/dist/mcp-router/tools/discover.d.ts +37 -0
- package/dist/mcp-router/tools/discover.d.ts.map +1 -0
- package/dist/mcp-router/tools/discover.js +65 -0
- package/dist/mcp-router/tools/discover.js.map +1 -0
- package/dist/mcp-router/tools/execute.d.ts +43 -0
- package/dist/mcp-router/tools/execute.d.ts.map +1 -0
- package/dist/mcp-router/tools/execute.js +103 -0
- package/dist/mcp-router/tools/execute.js.map +1 -0
- package/dist/mcp-router/types.d.ts +62 -0
- package/dist/mcp-router/types.d.ts.map +1 -0
- package/dist/mcp-router/types.js +6 -0
- package/dist/mcp-router/types.js.map +1 -0
- package/dist/memory/adaptive-context.d.ts +146 -0
- package/dist/memory/adaptive-context.d.ts.map +1 -0
- package/dist/memory/adaptive-context.js +1022 -0
- package/dist/memory/adaptive-context.js.map +1 -0
- package/dist/memory/agent-scoped-memory.d.ts +67 -0
- package/dist/memory/agent-scoped-memory.d.ts.map +1 -0
- package/dist/memory/agent-scoped-memory.js +126 -0
- package/dist/memory/agent-scoped-memory.js.map +1 -0
- package/dist/memory/backends/base.d.ts +18 -0
- package/dist/memory/backends/base.d.ts.map +1 -0
- package/dist/memory/backends/base.js +2 -0
- package/dist/memory/backends/base.js.map +1 -0
- package/dist/memory/backends/factory.d.ts +4 -0
- package/dist/memory/backends/factory.d.ts.map +1 -0
- package/dist/memory/backends/factory.js +53 -0
- package/dist/memory/backends/factory.js.map +1 -0
- package/dist/memory/backends/github.d.ts +22 -0
- package/dist/memory/backends/github.d.ts.map +1 -0
- package/dist/memory/backends/github.js +118 -0
- package/dist/memory/backends/github.js.map +1 -0
- package/dist/memory/backends/qdrant-cloud.d.ts +32 -0
- package/dist/memory/backends/qdrant-cloud.d.ts.map +1 -0
- package/dist/memory/backends/qdrant-cloud.js +168 -0
- package/dist/memory/backends/qdrant-cloud.js.map +1 -0
- package/dist/memory/context-compressor.d.ts +74 -0
- package/dist/memory/context-compressor.d.ts.map +1 -0
- package/dist/memory/context-compressor.js +289 -0
- package/dist/memory/context-compressor.js.map +1 -0
- package/dist/memory/correction-propagator.d.ts +44 -0
- package/dist/memory/correction-propagator.d.ts.map +1 -0
- package/dist/memory/correction-propagator.js +156 -0
- package/dist/memory/correction-propagator.js.map +1 -0
- package/dist/memory/daily-log.d.ts +67 -0
- package/dist/memory/daily-log.d.ts.map +1 -0
- package/dist/memory/daily-log.js +143 -0
- package/dist/memory/daily-log.js.map +1 -0
- package/dist/memory/dynamic-retrieval.d.ts +110 -0
- package/dist/memory/dynamic-retrieval.d.ts.map +1 -0
- package/dist/memory/dynamic-retrieval.js +688 -0
- package/dist/memory/dynamic-retrieval.js.map +1 -0
- package/dist/memory/embeddings.d.ts +116 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +461 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/hierarchical-memory.d.ts +141 -0
- package/dist/memory/hierarchical-memory.d.ts.map +1 -0
- package/dist/memory/hierarchical-memory.js +477 -0
- package/dist/memory/hierarchical-memory.js.map +1 -0
- package/dist/memory/memory-consolidator.d.ts +124 -0
- package/dist/memory/memory-consolidator.d.ts.map +1 -0
- package/dist/memory/memory-consolidator.js +514 -0
- package/dist/memory/memory-consolidator.js.map +1 -0
- package/dist/memory/memory-maintenance.d.ts +39 -0
- package/dist/memory/memory-maintenance.d.ts.map +1 -0
- package/dist/memory/memory-maintenance.js +305 -0
- package/dist/memory/memory-maintenance.js.map +1 -0
- package/dist/memory/model-router.d.ts +102 -0
- package/dist/memory/model-router.d.ts.map +1 -0
- package/dist/memory/model-router.js +448 -0
- package/dist/memory/model-router.js.map +1 -0
- package/dist/memory/multi-view-memory.d.ts +134 -0
- package/dist/memory/multi-view-memory.d.ts.map +1 -0
- package/dist/memory/multi-view-memory.js +420 -0
- package/dist/memory/multi-view-memory.js.map +1 -0
- package/dist/memory/prepopulate.d.ts +76 -0
- package/dist/memory/prepopulate.d.ts.map +1 -0
- package/dist/memory/prepopulate.js +815 -0
- package/dist/memory/prepopulate.js.map +1 -0
- package/dist/memory/semantic-compression.d.ts +77 -0
- package/dist/memory/semantic-compression.d.ts.map +1 -0
- package/dist/memory/semantic-compression.js +348 -0
- package/dist/memory/semantic-compression.js.map +1 -0
- package/dist/memory/serverless-qdrant.d.ts +102 -0
- package/dist/memory/serverless-qdrant.d.ts.map +1 -0
- package/dist/memory/serverless-qdrant.js +369 -0
- package/dist/memory/serverless-qdrant.js.map +1 -0
- package/dist/memory/short-term/factory.d.ts +26 -0
- package/dist/memory/short-term/factory.d.ts.map +1 -0
- package/dist/memory/short-term/factory.js +28 -0
- package/dist/memory/short-term/factory.js.map +1 -0
- package/dist/memory/short-term/indexeddb.d.ts +25 -0
- package/dist/memory/short-term/indexeddb.d.ts.map +1 -0
- package/dist/memory/short-term/indexeddb.js +64 -0
- package/dist/memory/short-term/indexeddb.js.map +1 -0
- package/dist/memory/short-term/schema.d.ts +6 -0
- package/dist/memory/short-term/schema.d.ts.map +1 -0
- package/dist/memory/short-term/schema.js +119 -0
- package/dist/memory/short-term/schema.js.map +1 -0
- package/dist/memory/short-term/sqlite.d.ts +50 -0
- package/dist/memory/short-term/sqlite.d.ts.map +1 -0
- package/dist/memory/short-term/sqlite.js +221 -0
- package/dist/memory/short-term/sqlite.js.map +1 -0
- package/dist/memory/speculative-cache.d.ts +111 -0
- package/dist/memory/speculative-cache.d.ts.map +1 -0
- package/dist/memory/speculative-cache.js +409 -0
- package/dist/memory/speculative-cache.js.map +1 -0
- package/dist/memory/task-classifier.d.ts +34 -0
- package/dist/memory/task-classifier.d.ts.map +1 -0
- package/dist/memory/task-classifier.js +300 -0
- package/dist/memory/task-classifier.js.map +1 -0
- package/dist/memory/terminal-bench-knowledge.d.ts +48 -0
- package/dist/memory/terminal-bench-knowledge.d.ts.map +1 -0
- package/dist/memory/terminal-bench-knowledge.js +399 -0
- package/dist/memory/terminal-bench-knowledge.js.map +1 -0
- package/dist/memory/write-gate.d.ts +39 -0
- package/dist/memory/write-gate.d.ts.map +1 -0
- package/dist/memory/write-gate.js +190 -0
- package/dist/memory/write-gate.js.map +1 -0
- package/dist/models/executor.d.ts +130 -0
- package/dist/models/executor.d.ts.map +1 -0
- package/dist/models/executor.js +383 -0
- package/dist/models/executor.js.map +1 -0
- package/dist/models/index.d.ts +15 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +17 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/planner.d.ts +71 -0
- package/dist/models/planner.d.ts.map +1 -0
- package/dist/models/planner.js +344 -0
- package/dist/models/planner.js.map +1 -0
- package/dist/models/router.d.ts +75 -0
- package/dist/models/router.d.ts.map +1 -0
- package/dist/models/router.js +344 -0
- package/dist/models/router.js.map +1 -0
- package/dist/models/types.d.ts +370 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +181 -0
- package/dist/models/types.js.map +1 -0
- package/dist/tasks/coordination.d.ts +74 -0
- package/dist/tasks/coordination.d.ts.map +1 -0
- package/dist/tasks/coordination.js +237 -0
- package/dist/tasks/coordination.js.map +1 -0
- package/dist/tasks/database.d.ts +14 -0
- package/dist/tasks/database.d.ts.map +1 -0
- package/dist/tasks/database.js +128 -0
- package/dist/tasks/database.js.map +1 -0
- package/dist/tasks/index.d.ts +5 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +5 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/service.d.ts +39 -0
- package/dist/tasks/service.d.ts.map +1 -0
- package/dist/tasks/service.js +582 -0
- package/dist/tasks/service.js.map +1 -0
- package/dist/tasks/types.d.ts +224 -0
- package/dist/tasks/types.d.ts.map +1 -0
- package/dist/tasks/types.js +64 -0
- package/dist/tasks/types.js.map +1 -0
- package/dist/types/analysis.d.ts +82 -0
- package/dist/types/analysis.d.ts.map +1 -0
- package/dist/types/analysis.js +2 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/config.d.ts +3023 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +292 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/coordination.d.ts +240 -0
- package/dist/types/coordination.d.ts.map +1 -0
- package/dist/types/coordination.js +43 -0
- package/dist/types/coordination.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/calculate-average.d.ts +15 -0
- package/dist/utils/calculate-average.d.ts.map +1 -0
- package/dist/utils/calculate-average.js +21 -0
- package/dist/utils/calculate-average.js.map +1 -0
- package/dist/utils/config-manager.d.ts +30 -0
- package/dist/utils/config-manager.d.ts.map +1 -0
- package/dist/utils/config-manager.js +41 -0
- package/dist/utils/config-manager.js.map +1 -0
- package/dist/utils/dijkstra.d.ts +17 -0
- package/dist/utils/dijkstra.d.ts.map +1 -0
- package/dist/utils/dijkstra.js +91 -0
- package/dist/utils/dijkstra.js.map +1 -0
- package/dist/utils/fetch-with-retry.d.ts +5 -0
- package/dist/utils/fetch-with-retry.d.ts.map +1 -0
- package/dist/utils/fetch-with-retry.js +61 -0
- package/dist/utils/fetch-with-retry.js.map +1 -0
- package/dist/utils/merge-claude-md.d.ts +28 -0
- package/dist/utils/merge-claude-md.d.ts.map +1 -0
- package/dist/utils/merge-claude-md.js +342 -0
- package/dist/utils/merge-claude-md.js.map +1 -0
- package/dist/utils/order-processor-refactored.d.ts +126 -0
- package/dist/utils/order-processor-refactored.d.ts.map +1 -0
- package/dist/utils/order-processor-refactored.js +165 -0
- package/dist/utils/order-processor-refactored.js.map +1 -0
- package/dist/utils/order-processor-strategy.d.ts +72 -0
- package/dist/utils/order-processor-strategy.d.ts.map +1 -0
- package/dist/utils/order-processor-strategy.js +158 -0
- package/dist/utils/order-processor-strategy.js.map +1 -0
- package/dist/utils/order-processor.d.ts +242 -0
- package/dist/utils/order-processor.d.ts.map +1 -0
- package/dist/utils/order-processor.js +370 -0
- package/dist/utils/order-processor.js.map +1 -0
- package/dist/utils/rate-limiter-simple.d.ts +58 -0
- package/dist/utils/rate-limiter-simple.d.ts.map +1 -0
- package/dist/utils/rate-limiter-simple.js +100 -0
- package/dist/utils/rate-limiter-simple.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +62 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +150 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/string-similarity.d.ts +37 -0
- package/dist/utils/string-similarity.d.ts.map +1 -0
- package/dist/utils/string-similarity.js +114 -0
- package/dist/utils/string-similarity.js.map +1 -0
- package/dist/utils/validate-json.d.ts +51 -0
- package/dist/utils/validate-json.d.ts.map +1 -0
- package/dist/utils/validate-json.js +99 -0
- package/dist/utils/validate-json.js.map +1 -0
- package/package.json +96 -0
- package/templates/CLAUDE.template.md +11 -0
- package/templates/CLAUDE_ARCHITECTURE.template.md +103 -0
- package/templates/CLAUDE_CODING.template.md +125 -0
- package/templates/CLAUDE_DROIDS.template.md +109 -0
- package/templates/CLAUDE_MEMORY.template.md +130 -0
- package/templates/CLAUDE_WORKFLOWS.template.md +136 -0
- package/templates/PROJECT.template.md +209 -0
- package/templates/SCHEMA.md +57 -0
- package/templates/archive/CLAUDE.template.root-v6.md +762 -0
- package/templates/archive/CLAUDE.template.v6.md +762 -0
- package/templates/hooks/pre-compact.sh +68 -0
- package/templates/hooks/session-start.sh +106 -0
- package/tools/agents/README.md +224 -0
- package/tools/agents/UAP/README.md +351 -0
- package/tools/agents/UAP/__init__.py +9 -0
- package/tools/agents/UAP/cli.py +675 -0
- package/tools/agents/UAP/version.py +2 -0
- package/tools/agents/benchmarks/benchmark_memory_systems.py +637 -0
- package/tools/agents/benchmarks/results/benchmark_20260106_064817.json +170 -0
- package/tools/agents/benchmarks/results/benchmark_20260106_064817.md +51 -0
- package/tools/agents/config/chat_template.jinja +172 -0
- package/tools/agents/docker-compose.qdrant.yml +24 -0
- package/tools/agents/migrations/apply.py +256 -0
- package/tools/agents/scripts/fix_qwen_chat_template.py +314 -0
- package/tools/agents/scripts/init_qdrant.py +151 -0
- package/tools/agents/scripts/memory_migration.py +518 -0
- package/tools/agents/scripts/migrate_memory_to_qdrant.py +113 -0
- package/tools/agents/scripts/query_memory.py +189 -0
- package/tools/agents/scripts/qwen_tool_call_test.py +419 -0
- package/tools/agents/scripts/qwen_tool_call_wrapper.py +517 -0
- package/tools/agents/scripts/start-services.sh +96 -0
- package/tools/agents/tests/test_uap_compliance.py +257 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
UAM CLI - Unified Agent Memory Protocol Command Line Interface
|
|
4
|
+
|
|
5
|
+
This is the core CLI tool for managing agent memory systems.
|
|
6
|
+
All agent hooks and workflows MUST use these commands for compliance.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
UAP task ready # Check task readiness
|
|
10
|
+
UAP memory query "<topic>" # Query memory by topic
|
|
11
|
+
UAP worktree create <slug> # Create new worktree
|
|
12
|
+
UAP worktree cleanup <id> # Clean up merged worktree
|
|
13
|
+
UAP session start # Start new session
|
|
14
|
+
UAP session end # End current session
|
|
15
|
+
UAP compliance check # Check UAM protocol compliance
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import sqlite3
|
|
20
|
+
import subprocess
|
|
21
|
+
import sys
|
|
22
|
+
import uuid
|
|
23
|
+
from datetime import datetime, timedelta
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import Optional
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class UAMCLI:
|
|
29
|
+
"""Unified Agent Memory Protocol CLI."""
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self.project_root = Path(__file__).parent.parent.parent
|
|
33
|
+
self.db_path = self.project_root / "agents/data/memory/short_term.db"
|
|
34
|
+
self.coord_db_path = (
|
|
35
|
+
self.project_root / "agents/data/coordination/coordination.db"
|
|
36
|
+
)
|
|
37
|
+
self.worktrees_dir = self.project_root / ".worktrees"
|
|
38
|
+
|
|
39
|
+
def get_connection(self, db_path: Optional[Path] = None) -> sqlite3.Connection:
|
|
40
|
+
"""Get database connection."""
|
|
41
|
+
path = db_path or self.db_path
|
|
42
|
+
if not path.exists():
|
|
43
|
+
raise FileNotFoundError(f"Database not found: {path}")
|
|
44
|
+
conn = sqlite3.connect(str(path))
|
|
45
|
+
conn.row_factory = sqlite3.Row
|
|
46
|
+
return conn
|
|
47
|
+
|
|
48
|
+
def get_coordination_connection(self) -> Optional[sqlite3.Connection]:
|
|
49
|
+
"""Get coordination database connection."""
|
|
50
|
+
if not self.coord_db_path.exists():
|
|
51
|
+
return None
|
|
52
|
+
conn = sqlite3.connect(str(self.coord_db_path))
|
|
53
|
+
conn.row_factory = sqlite3.Row
|
|
54
|
+
return conn
|
|
55
|
+
|
|
56
|
+
# ============================================================
|
|
57
|
+
# TASK COMMANDS
|
|
58
|
+
# ============================================================
|
|
59
|
+
|
|
60
|
+
def task_ready(self) -> int:
|
|
61
|
+
"""Check if agent is ready to work."""
|
|
62
|
+
print("=== UAM Task Readiness Check ===\n")
|
|
63
|
+
|
|
64
|
+
# Check memory database
|
|
65
|
+
if not self.db_path.exists():
|
|
66
|
+
print("❌ Memory database not initialized")
|
|
67
|
+
return 1
|
|
68
|
+
print(f"✅ Memory database: {self.db_path}")
|
|
69
|
+
|
|
70
|
+
# Check recent activity
|
|
71
|
+
conn = self.get_connection()
|
|
72
|
+
cursor = conn.cursor()
|
|
73
|
+
|
|
74
|
+
# Get last 5 actions
|
|
75
|
+
cursor.execute("""
|
|
76
|
+
SELECT timestamp, type, substr(content, 1, 60) as content
|
|
77
|
+
FROM memories
|
|
78
|
+
ORDER BY id DESC
|
|
79
|
+
LIMIT 5
|
|
80
|
+
""")
|
|
81
|
+
rows = cursor.fetchall()
|
|
82
|
+
|
|
83
|
+
if rows:
|
|
84
|
+
print(f"\n📝 Recent activity (last {len(rows)} entries):")
|
|
85
|
+
for row in rows:
|
|
86
|
+
print(f" [{row['timestamp']}] {row['type']}: {row['content']}...")
|
|
87
|
+
else:
|
|
88
|
+
print("\n⚠️ No recent memory entries found")
|
|
89
|
+
|
|
90
|
+
# Check coordination database
|
|
91
|
+
if self.coord_db_path.exists():
|
|
92
|
+
print(f"\n✅ Coordination DB: {self.coord_db_path}")
|
|
93
|
+
|
|
94
|
+
# Check for stale agents
|
|
95
|
+
coord_conn = self.get_coordination_connection()
|
|
96
|
+
if coord_conn:
|
|
97
|
+
cursor = coord_conn.cursor()
|
|
98
|
+
cursor.execute("""
|
|
99
|
+
SELECT COUNT(*) as count FROM agent_registry
|
|
100
|
+
WHERE status IN ('active', 'idle')
|
|
101
|
+
AND last_heartbeat < datetime('now', '-24 hours')
|
|
102
|
+
""")
|
|
103
|
+
stale = cursor.fetchone()["count"]
|
|
104
|
+
|
|
105
|
+
if stale > 0:
|
|
106
|
+
print(f"⚠️ {stale} stale agents detected (not heartbeat in 24h)")
|
|
107
|
+
else:
|
|
108
|
+
print("✅ No stale agents detected")
|
|
109
|
+
else:
|
|
110
|
+
print("\n⚠️ Coordination DB not initialized (multi-agent mode disabled)")
|
|
111
|
+
|
|
112
|
+
# Check worktrees
|
|
113
|
+
if self.worktrees_dir.exists():
|
|
114
|
+
worktree_count = len(
|
|
115
|
+
[
|
|
116
|
+
d
|
|
117
|
+
for d in self.worktrees_dir.iterdir()
|
|
118
|
+
if d.is_dir() and d.name.startswith(".")
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
print(f"\n📁 Worktrees: {worktree_count} active")
|
|
122
|
+
|
|
123
|
+
conn.close()
|
|
124
|
+
|
|
125
|
+
print("\n✅ UAM Protocol Ready - You can proceed with work")
|
|
126
|
+
return 0
|
|
127
|
+
|
|
128
|
+
def task_create(self, task_type: str, title: str) -> int:
|
|
129
|
+
"""Create new task entry in memory."""
|
|
130
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
131
|
+
|
|
132
|
+
conn = self.get_connection()
|
|
133
|
+
cursor = conn.cursor()
|
|
134
|
+
|
|
135
|
+
content = f"[{task_type.upper()}] {title}"
|
|
136
|
+
cursor.execute(
|
|
137
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
138
|
+
(timestamp, task_type, content),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
conn.commit()
|
|
142
|
+
print(f"✅ Created {task_type} task: {title}")
|
|
143
|
+
print(f" ID: {cursor.lastrowid}")
|
|
144
|
+
print(f" Timestamp: {timestamp}")
|
|
145
|
+
|
|
146
|
+
conn.close()
|
|
147
|
+
return 0
|
|
148
|
+
|
|
149
|
+
# ============================================================
|
|
150
|
+
# MEMORY COMMANDS
|
|
151
|
+
# ============================================================
|
|
152
|
+
|
|
153
|
+
def memory_query(self, query: str, limit: int = 10) -> int:
|
|
154
|
+
"""Query memory by topic."""
|
|
155
|
+
print(f"=== Memory Query: '{query}' ===\n")
|
|
156
|
+
|
|
157
|
+
if not self.db_path.exists():
|
|
158
|
+
print("❌ Memory database not initialized")
|
|
159
|
+
return 1
|
|
160
|
+
|
|
161
|
+
conn = self.get_connection()
|
|
162
|
+
cursor = conn.cursor()
|
|
163
|
+
|
|
164
|
+
# Try full-text search first
|
|
165
|
+
try:
|
|
166
|
+
cursor.execute(
|
|
167
|
+
"""
|
|
168
|
+
SELECT m.id, m.timestamp, m.type, m.content
|
|
169
|
+
FROM memories_fts f
|
|
170
|
+
JOIN memories m ON f.rowid = m.id
|
|
171
|
+
WHERE memories_fts MATCH ?
|
|
172
|
+
ORDER BY rank
|
|
173
|
+
LIMIT ?
|
|
174
|
+
""",
|
|
175
|
+
(query, limit),
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
rows = cursor.fetchall()
|
|
179
|
+
if rows:
|
|
180
|
+
print(f"Found {len(rows)} matches via FTS search\n")
|
|
181
|
+
for row in rows:
|
|
182
|
+
self._print_memory_row(row)
|
|
183
|
+
conn.close()
|
|
184
|
+
return 0
|
|
185
|
+
except sqlite3.OperationalError:
|
|
186
|
+
# FTS index doesn't exist, fall back to LIKE search
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
# Fall back to LIKE search
|
|
190
|
+
search_pattern = f"%{query}%"
|
|
191
|
+
cursor.execute(
|
|
192
|
+
"""
|
|
193
|
+
SELECT id, timestamp, type, content
|
|
194
|
+
FROM memories
|
|
195
|
+
WHERE content LIKE ?
|
|
196
|
+
ORDER BY timestamp DESC
|
|
197
|
+
LIMIT ?
|
|
198
|
+
""",
|
|
199
|
+
(search_pattern, limit),
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
rows = cursor.fetchall()
|
|
203
|
+
|
|
204
|
+
if not rows:
|
|
205
|
+
print("No matches found")
|
|
206
|
+
conn.close()
|
|
207
|
+
return 1
|
|
208
|
+
|
|
209
|
+
print(f"Found {len(rows)} matches\n")
|
|
210
|
+
for row in rows:
|
|
211
|
+
self._print_memory_row(row)
|
|
212
|
+
|
|
213
|
+
conn.close()
|
|
214
|
+
return 0
|
|
215
|
+
|
|
216
|
+
def _print_memory_row(self, row):
|
|
217
|
+
"""Print formatted memory row."""
|
|
218
|
+
print(f"[{row['id']:3d}] {row['timestamp']} [{row['type']:11s}]")
|
|
219
|
+
content = row["content"]
|
|
220
|
+
if len(content) > 200:
|
|
221
|
+
content = content[:200] + "..."
|
|
222
|
+
print(f" {content}")
|
|
223
|
+
print()
|
|
224
|
+
|
|
225
|
+
def memory_store(self, mem_type: str, content: str, importance: int = 5) -> int:
|
|
226
|
+
"""Store memory entry."""
|
|
227
|
+
if mem_type not in ["action", "observation", "thought", "goal"]:
|
|
228
|
+
print("❌ Invalid type. Must be: action, observation, thought, goal")
|
|
229
|
+
return 1
|
|
230
|
+
|
|
231
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
232
|
+
|
|
233
|
+
conn = self.get_connection()
|
|
234
|
+
cursor = conn.cursor()
|
|
235
|
+
cursor.execute(
|
|
236
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
237
|
+
(timestamp, mem_type, content),
|
|
238
|
+
)
|
|
239
|
+
conn.commit()
|
|
240
|
+
conn.close()
|
|
241
|
+
|
|
242
|
+
print(f"✅ Stored memory [{mem_type}]: {content[:50]}...")
|
|
243
|
+
return 0
|
|
244
|
+
|
|
245
|
+
def session_memories_add(
|
|
246
|
+
self, session_id: str, mem_type: str, content: str, importance: int
|
|
247
|
+
) -> int:
|
|
248
|
+
"""Add to session memories (high-importance decisions)."""
|
|
249
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
250
|
+
|
|
251
|
+
conn = self.get_connection()
|
|
252
|
+
cursor = conn.cursor()
|
|
253
|
+
|
|
254
|
+
try:
|
|
255
|
+
cursor.execute(
|
|
256
|
+
"""
|
|
257
|
+
INSERT OR IGNORE INTO session_memories
|
|
258
|
+
(session_id, timestamp, type, content, importance)
|
|
259
|
+
VALUES (?, ?, ?, ?, ?)
|
|
260
|
+
""",
|
|
261
|
+
(session_id, timestamp, mem_type, content, importance),
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
if cursor.rowcount == 0:
|
|
265
|
+
print("⚠️ Session memory already exists")
|
|
266
|
+
else:
|
|
267
|
+
print(f"✅ Stored session memory [{mem_type}] importance={importance}")
|
|
268
|
+
print(f" Content: {content[:100]}...")
|
|
269
|
+
|
|
270
|
+
conn.commit()
|
|
271
|
+
except sqlite3.OperationalError as e:
|
|
272
|
+
print(f"❌ Error: {e}")
|
|
273
|
+
print(
|
|
274
|
+
" Hint: Run database migration first (tools/agents/migrations/apply.py)"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
conn.close()
|
|
278
|
+
return 0
|
|
279
|
+
|
|
280
|
+
# ============================================================
|
|
281
|
+
# WORKTREE COMMANDS
|
|
282
|
+
# ============================================================
|
|
283
|
+
|
|
284
|
+
def worktree_create(self, slug: str) -> int:
|
|
285
|
+
"""Create new git worktree."""
|
|
286
|
+
import os
|
|
287
|
+
|
|
288
|
+
if not slug:
|
|
289
|
+
print("❌ Worktree slug required")
|
|
290
|
+
return 1
|
|
291
|
+
|
|
292
|
+
# Create worktree using factory script or git directly
|
|
293
|
+
worktree_script = (
|
|
294
|
+
self.project_root / ".factory" / "scripts" / "worktree-manager.sh"
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if worktree_script.exists():
|
|
298
|
+
print(f"📝 Creating worktree: {slug}")
|
|
299
|
+
result = subprocess.run(
|
|
300
|
+
[str(worktree_script), "create", slug],
|
|
301
|
+
cwd=str(self.project_root),
|
|
302
|
+
capture_output=True,
|
|
303
|
+
text=True,
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
if result.returncode == 0:
|
|
307
|
+
print("✅ Worktree created successfully")
|
|
308
|
+
print(result.stdout)
|
|
309
|
+
|
|
310
|
+
# Record in memory
|
|
311
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
312
|
+
conn = self.get_connection()
|
|
313
|
+
cursor = conn.cursor()
|
|
314
|
+
cursor.execute(
|
|
315
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
316
|
+
(timestamp, "action", f"Created worktree: {slug}"),
|
|
317
|
+
)
|
|
318
|
+
conn.commit()
|
|
319
|
+
conn.close()
|
|
320
|
+
|
|
321
|
+
return 0
|
|
322
|
+
else:
|
|
323
|
+
print(f"❌ Error creating worktree:\n{result.stderr}")
|
|
324
|
+
return 1
|
|
325
|
+
else:
|
|
326
|
+
# Fall back to git worktree command
|
|
327
|
+
print(f"📝 Creating worktree via git: {slug}")
|
|
328
|
+
result = subprocess.run(
|
|
329
|
+
["git", "worktree", "add", f".worktrees/{slug}", "-b", slug],
|
|
330
|
+
cwd=str(self.project_root),
|
|
331
|
+
capture_output=True,
|
|
332
|
+
text=True,
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
if result.returncode == 0:
|
|
336
|
+
print("✅ Worktree created successfully")
|
|
337
|
+
|
|
338
|
+
# Record in memory
|
|
339
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
340
|
+
conn = self.get_connection()
|
|
341
|
+
cursor = conn.cursor()
|
|
342
|
+
cursor.execute(
|
|
343
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
344
|
+
(timestamp, "action", f"Created worktree: {slug}"),
|
|
345
|
+
)
|
|
346
|
+
conn.commit()
|
|
347
|
+
conn.close()
|
|
348
|
+
|
|
349
|
+
return 0
|
|
350
|
+
else:
|
|
351
|
+
print(f"❌ Error creating worktree:\n{result.stderr}")
|
|
352
|
+
return 1
|
|
353
|
+
|
|
354
|
+
def worktree_cleanup(self, id_or_slug: str) -> int:
|
|
355
|
+
"""Clean up merged worktree."""
|
|
356
|
+
import os
|
|
357
|
+
|
|
358
|
+
# Find worktree by ID or slug
|
|
359
|
+
if self.worktrees_dir.exists():
|
|
360
|
+
for entry in self.worktrees_dir.iterdir():
|
|
361
|
+
if entry.is_dir() and (
|
|
362
|
+
entry.name == id_or_slug or str(id_or_slug) in entry.name
|
|
363
|
+
):
|
|
364
|
+
print(f"🗑️ Removing worktree: {entry.name}")
|
|
365
|
+
|
|
366
|
+
# Remove directory
|
|
367
|
+
import shutil
|
|
368
|
+
|
|
369
|
+
try:
|
|
370
|
+
shutil.rmtree(entry)
|
|
371
|
+
print("✅ Worktree removed")
|
|
372
|
+
|
|
373
|
+
# Record in memory
|
|
374
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
375
|
+
conn = self.get_connection()
|
|
376
|
+
cursor = conn.cursor()
|
|
377
|
+
cursor.execute(
|
|
378
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
379
|
+
(timestamp, "action", f"Cleaned up worktree: {entry.name}"),
|
|
380
|
+
)
|
|
381
|
+
conn.commit()
|
|
382
|
+
conn.close()
|
|
383
|
+
|
|
384
|
+
return 0
|
|
385
|
+
except Exception as e:
|
|
386
|
+
print(f"❌ Error removing worktree: {e}")
|
|
387
|
+
return 1
|
|
388
|
+
|
|
389
|
+
print(f"❌ Worktree not found: {id_or_slug}")
|
|
390
|
+
return 1
|
|
391
|
+
|
|
392
|
+
def worktree_list(self) -> int:
|
|
393
|
+
"""List all active worktrees."""
|
|
394
|
+
if not self.worktrees_dir.exists():
|
|
395
|
+
print("No worktrees directory found")
|
|
396
|
+
return 0
|
|
397
|
+
|
|
398
|
+
worktrees = [d.name for d in self.worktrees_dir.iterdir() if d.is_dir()]
|
|
399
|
+
|
|
400
|
+
if not worktrees:
|
|
401
|
+
print("No active worktrees")
|
|
402
|
+
return 0
|
|
403
|
+
|
|
404
|
+
print("=== Active Worktrees ===\n")
|
|
405
|
+
for wt in worktrees:
|
|
406
|
+
print(f"📁 {wt}")
|
|
407
|
+
|
|
408
|
+
return 0
|
|
409
|
+
|
|
410
|
+
# ============================================================
|
|
411
|
+
# SESSION COMMANDS
|
|
412
|
+
# ============================================================
|
|
413
|
+
|
|
414
|
+
def session_start(self) -> int:
|
|
415
|
+
"""Start new agent session."""
|
|
416
|
+
import os
|
|
417
|
+
|
|
418
|
+
session_id = str(uuid.uuid4())[:8]
|
|
419
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
420
|
+
|
|
421
|
+
# Store session in coordination DB if available
|
|
422
|
+
coord_conn = self.get_coordination_connection()
|
|
423
|
+
if coord_conn:
|
|
424
|
+
cursor = coord_conn.cursor()
|
|
425
|
+
cursor.execute(
|
|
426
|
+
"""
|
|
427
|
+
INSERT OR REPLACE INTO agent_registry
|
|
428
|
+
(agent_id, status, last_heartbeat)
|
|
429
|
+
VALUES (?, 'active', ?)
|
|
430
|
+
""",
|
|
431
|
+
(session_id, timestamp),
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
# Update any stale agents to failed
|
|
435
|
+
cursor.execute("""
|
|
436
|
+
UPDATE agent_registry SET status='failed'
|
|
437
|
+
WHERE status IN ('active','idle')
|
|
438
|
+
AND last_heartbeat < datetime('now','-24 hours')
|
|
439
|
+
""")
|
|
440
|
+
|
|
441
|
+
coord_conn.commit()
|
|
442
|
+
|
|
443
|
+
# Record in memory
|
|
444
|
+
conn = self.get_connection()
|
|
445
|
+
cursor = conn.cursor()
|
|
446
|
+
cursor.execute(
|
|
447
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
448
|
+
(timestamp, "thought", f"Session started: {session_id}"),
|
|
449
|
+
)
|
|
450
|
+
conn.commit()
|
|
451
|
+
conn.close()
|
|
452
|
+
|
|
453
|
+
print(f"✅ Session started: {session_id}")
|
|
454
|
+
print(f" Timestamp: {timestamp}")
|
|
455
|
+
print(f"\n📝 Remember to run 'UAP session end' when done")
|
|
456
|
+
|
|
457
|
+
return 0
|
|
458
|
+
|
|
459
|
+
def session_end(self) -> int:
|
|
460
|
+
"""End current agent session."""
|
|
461
|
+
import os
|
|
462
|
+
|
|
463
|
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
|
464
|
+
|
|
465
|
+
# Update coordination DB if available
|
|
466
|
+
coord_conn = self.get_coordination_connection()
|
|
467
|
+
if coord_conn:
|
|
468
|
+
cursor = coord_conn.cursor()
|
|
469
|
+
cursor.execute(
|
|
470
|
+
"""
|
|
471
|
+
UPDATE agent_registry SET status='completed', last_heartbeat=?
|
|
472
|
+
WHERE status='active'
|
|
473
|
+
""",
|
|
474
|
+
(timestamp,),
|
|
475
|
+
)
|
|
476
|
+
coord_conn.commit()
|
|
477
|
+
|
|
478
|
+
# Record in memory
|
|
479
|
+
conn = self.get_connection()
|
|
480
|
+
cursor = conn.cursor()
|
|
481
|
+
cursor.execute(
|
|
482
|
+
"INSERT INTO memories (timestamp, type, content) VALUES (?, ?, ?)",
|
|
483
|
+
(timestamp, "thought", "Session ended"),
|
|
484
|
+
)
|
|
485
|
+
conn.commit()
|
|
486
|
+
conn.close()
|
|
487
|
+
|
|
488
|
+
print(f"✅ Session ended: {timestamp}")
|
|
489
|
+
return 0
|
|
490
|
+
|
|
491
|
+
# ============================================================
|
|
492
|
+
# COMPLIANCE COMMANDS
|
|
493
|
+
# ============================================================
|
|
494
|
+
|
|
495
|
+
def compliance_check(self) -> int:
|
|
496
|
+
"""Check UAM protocol compliance."""
|
|
497
|
+
print("=== UAM Protocol Compliance Check ===\n")
|
|
498
|
+
|
|
499
|
+
all_passed = True
|
|
500
|
+
|
|
501
|
+
# Check 1: Memory database exists
|
|
502
|
+
if self.db_path.exists():
|
|
503
|
+
print("✅ Memory database initialized")
|
|
504
|
+
else:
|
|
505
|
+
print("❌ Memory database not initialized")
|
|
506
|
+
all_passed = False
|
|
507
|
+
|
|
508
|
+
# Check 2: Required tables exist
|
|
509
|
+
conn = self.get_connection()
|
|
510
|
+
cursor = conn.cursor()
|
|
511
|
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
|
512
|
+
tables = [row[0] for row in cursor.fetchall()]
|
|
513
|
+
|
|
514
|
+
required_tables = ["memories", "session_memories", "entities", "relationships"]
|
|
515
|
+
for table in required_tables:
|
|
516
|
+
if table in tables:
|
|
517
|
+
print(f"✅ Table '{table}' exists")
|
|
518
|
+
else:
|
|
519
|
+
print(f"❌ Table '{table}' missing (run migration)")
|
|
520
|
+
all_passed = False
|
|
521
|
+
|
|
522
|
+
conn.close()
|
|
523
|
+
|
|
524
|
+
# Check 3: FTS index exists
|
|
525
|
+
if "memories_fts" in tables:
|
|
526
|
+
print("✅ Full-text search index exists")
|
|
527
|
+
else:
|
|
528
|
+
print("❌ FTS5 index missing (run migration)")
|
|
529
|
+
all_passed = False
|
|
530
|
+
|
|
531
|
+
# Check 4: Coordination DB
|
|
532
|
+
if self.coord_db_path.exists():
|
|
533
|
+
print("✅ Coordination database initialized")
|
|
534
|
+
else:
|
|
535
|
+
print("⚠️ Coordination DB not initialized (multi-agent mode disabled)")
|
|
536
|
+
|
|
537
|
+
# Check 5: Worktrees directory
|
|
538
|
+
if self.worktrees_dir.exists():
|
|
539
|
+
wt_count = len([d for d in self.worktrees_dir.iterdir() if d.is_dir()])
|
|
540
|
+
print(f"✅ Worktrees directory exists ({wt_count} worktrees)")
|
|
541
|
+
else:
|
|
542
|
+
print("⚠️ No worktrees directory (single-agent mode)")
|
|
543
|
+
|
|
544
|
+
print("\n" + "=" * 40)
|
|
545
|
+
if all_passed:
|
|
546
|
+
print("✅ UAM Protocol COMPLIANT - All checks passed")
|
|
547
|
+
return 0
|
|
548
|
+
else:
|
|
549
|
+
print("❌ UAM Protocol NON-COMPLIANT - Run migrations first")
|
|
550
|
+
print("\nTo fix:")
|
|
551
|
+
print(" 1. Run database migration: tools/agents/migrations/apply.py")
|
|
552
|
+
print(
|
|
553
|
+
" 2. Initialize coordination DB: tools/agents/scripts/init_coordination_db.sh"
|
|
554
|
+
)
|
|
555
|
+
return 1
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def main():
|
|
559
|
+
parser = argparse.ArgumentParser(
|
|
560
|
+
description="Unified Agent Memory Protocol CLI",
|
|
561
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
562
|
+
epilog="""
|
|
563
|
+
Examples:
|
|
564
|
+
UAP task ready # Check task readiness
|
|
565
|
+
UAP memory query "Redis caching" # Search memory by topic
|
|
566
|
+
UAP worktree create fix-bug # Create new worktree
|
|
567
|
+
UAP session start # Start agent session
|
|
568
|
+
UAP compliance check # Verify protocol compliance
|
|
569
|
+
""",
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
subparsers = parser.add_subparsers(dest="command", help="Command")
|
|
573
|
+
|
|
574
|
+
# Task commands
|
|
575
|
+
task_parser = subparsers.add_parser("task", help="Task management")
|
|
576
|
+
task_sub = task_parser.add_subparsers(dest="subcommand")
|
|
577
|
+
|
|
578
|
+
task_ready = task_sub.add_parser("ready", help="Check task readiness")
|
|
579
|
+
task_create = task_sub.add_parser("create", help="Create new task")
|
|
580
|
+
task_create.add_argument(
|
|
581
|
+
"type", choices=["action", "observation", "thought", "goal"]
|
|
582
|
+
)
|
|
583
|
+
task_create.add_argument("title", help="Task title")
|
|
584
|
+
|
|
585
|
+
# Memory commands
|
|
586
|
+
memory_parser = subparsers.add_parser("memory", help="Memory operations")
|
|
587
|
+
memory_sub = memory_parser.add_subparsers(dest="subcommand")
|
|
588
|
+
|
|
589
|
+
memory_query = memory_sub.add_parser("query", help="Query memory by topic")
|
|
590
|
+
memory_query.add_argument("query", help="Search query")
|
|
591
|
+
memory_query.add_argument("-n", "--limit", type=int, default=10, help="Max results")
|
|
592
|
+
|
|
593
|
+
# Worktree commands
|
|
594
|
+
wt_parser = subparsers.add_parser("worktree", help="Worktree management")
|
|
595
|
+
wt_sub = wt_parser.add_subparsers(dest="subcommand")
|
|
596
|
+
|
|
597
|
+
wt_create = wt_sub.add_parser("create", help="Create new worktree")
|
|
598
|
+
wt_create.add_argument("slug", help="Worktree slug")
|
|
599
|
+
|
|
600
|
+
wt_cleanup = wt_sub.add_parser("cleanup", help="Clean up worktree")
|
|
601
|
+
wt_cleanup.add_argument("id_or_slug", help="Worktree ID or slug")
|
|
602
|
+
|
|
603
|
+
wt_list = wt_sub.add_parser("list", help="List active worktrees")
|
|
604
|
+
|
|
605
|
+
# Session commands
|
|
606
|
+
session_parser = subparsers.add_parser("session", help="Session management")
|
|
607
|
+
session_sub = session_parser.add_subparsers(dest="subcommand")
|
|
608
|
+
|
|
609
|
+
session_start = session_sub.add_parser("start", help="Start new session")
|
|
610
|
+
session_end = session_sub.add_parser("end", help="End current session")
|
|
611
|
+
|
|
612
|
+
# Compliance command
|
|
613
|
+
subparsers.add_parser("compliance", help="Check UAM protocol compliance")
|
|
614
|
+
|
|
615
|
+
args = parser.parse_args()
|
|
616
|
+
|
|
617
|
+
if not args.command:
|
|
618
|
+
parser.print_help()
|
|
619
|
+
return 1
|
|
620
|
+
|
|
621
|
+
cli = UAMCLI()
|
|
622
|
+
|
|
623
|
+
try:
|
|
624
|
+
if args.command == "task":
|
|
625
|
+
if args.subcommand == "ready":
|
|
626
|
+
return cli.task_ready()
|
|
627
|
+
elif args.subcommand == "create":
|
|
628
|
+
return cli.task_create(args.type, args.title)
|
|
629
|
+
else:
|
|
630
|
+
task_parser.print_help()
|
|
631
|
+
return 1
|
|
632
|
+
|
|
633
|
+
elif args.command == "memory":
|
|
634
|
+
if args.subcommand == "query":
|
|
635
|
+
return cli.memory_query(args.query, args.limit)
|
|
636
|
+
else:
|
|
637
|
+
memory_parser.print_help()
|
|
638
|
+
return 1
|
|
639
|
+
|
|
640
|
+
elif args.command == "worktree":
|
|
641
|
+
if args.subcommand == "create":
|
|
642
|
+
return cli.worktree_create(args.slug)
|
|
643
|
+
elif args.subcommand == "cleanup":
|
|
644
|
+
return cli.worktree_cleanup(args.id_or_slug)
|
|
645
|
+
elif args.subcommand == "list":
|
|
646
|
+
return cli.worktree_list()
|
|
647
|
+
else:
|
|
648
|
+
wt_parser.print_help()
|
|
649
|
+
return 1
|
|
650
|
+
|
|
651
|
+
elif args.command == "session":
|
|
652
|
+
if args.subcommand == "start":
|
|
653
|
+
return cli.session_start()
|
|
654
|
+
elif args.subcommand == "end":
|
|
655
|
+
return cli.session_end()
|
|
656
|
+
else:
|
|
657
|
+
session_parser.print_help()
|
|
658
|
+
return 1
|
|
659
|
+
|
|
660
|
+
elif args.command == "compliance":
|
|
661
|
+
return cli.compliance_check()
|
|
662
|
+
|
|
663
|
+
except FileNotFoundError as e:
|
|
664
|
+
print(f"❌ Error: {e}")
|
|
665
|
+
return 1
|
|
666
|
+
except Exception as e:
|
|
667
|
+
print(f"❌ Unexpected error: {e}")
|
|
668
|
+
import traceback
|
|
669
|
+
|
|
670
|
+
traceback.print_exc()
|
|
671
|
+
return 1
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
if __name__ == "__main__":
|
|
675
|
+
sys.exit(main())
|