swarmdo 1.58.18 → 1.58.24
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/.claude/agents/base-template-generator.md +1 -1
- package/.claude/agents/goal/code-goal-planner.md +1 -1
- package/.claude/helpers/hook-handler.cjs +11 -7
- package/README.md +1 -1
- package/package.json +1 -1
- package/v3/@swarmdo/cli/.claude/helpers/agent-bridge-hook.cjs +174 -0
- package/v3/@swarmdo/cli/.claude/helpers/auto-memory-hook.mjs +274 -27
- package/v3/@swarmdo/cli/.claude/helpers/hook-handler.cjs +150 -107
- package/v3/@swarmdo/cli/.claude/helpers/intelligence.cjs +196 -989
- package/v3/@swarmdo/cli/.claude/helpers/{memory.js → memory.cjs} +10 -9
- package/v3/@swarmdo/cli/.claude/helpers/router.cjs +88 -0
- package/v3/@swarmdo/cli/.claude/helpers/session.cjs +125 -0
- package/v3/@swarmdo/cli/dist/src/commands/config.js +5 -4
- package/v3/@swarmdo/cli/dist/src/init/executor.d.ts +15 -0
- package/v3/@swarmdo/cli/dist/src/init/executor.js +24 -1
- package/v3/@swarmdo/cli/dist/src/mcp-tools/agent-tools.js +1 -1
- package/v3/@swarmdo/cli/dist/src/mcp-tools/neural-tools.d.ts +1 -0
- package/v3/@swarmdo/cli/dist/src/mcp-tools/neural-tools.js +132 -78
- package/v3/@swarmdo/cli/package.json +1 -1
- package/v3/@swarmdo/cli-core/dist/src/index.js +1 -1
- package/v3/@swarmdo/codex/dist/cli.js +0 -0
- package/v3/@swarmdo/hooks/dist/cli/guidance-cli.js +0 -0
- package/v3/@swarmdo/hooks/dist/statusline/index.d.ts +3 -3
- package/v3/@swarmdo/hooks/dist/statusline/index.js +3 -3
- package/v3/@swarmdo/integration/dist/__tests__/agentic-flow-agent.test.js +4 -1
- package/v3/@swarmdo/neural/dist/flash-attention.d.ts +1 -1
- package/v3/@swarmdo/neural/dist/flash-attention.js +1 -1
- package/v3/@swarmdo/plugin-agent-federation/dist/plugin.js +1 -1
- package/v3/@swarmdo/plugin-agent-federation/dist/transport/midstream-aware-loader.js +2 -2
- package/v3/@swarmdo/providers/dist/swarmvector-provider.d.ts +1 -1
- package/v3/@swarmdo/providers/dist/swarmvector-provider.js +1 -1
- package/v3/@swarmdo/security/dist/input-validator.d.ts +6 -6
- package/v3/@swarmdo/shared/dist/hooks/safety/git-commit.js +1 -1
- package/v3/@swarmdo/shared/dist/mcp/transport/http.js +8 -1
- package/.claude/settings.local.json +0 -7
- package/v3/@swarmdo/cli/.claude/helpers/router.js +0 -105
- package/v3/@swarmdo/cli/.claude/helpers/session.js +0 -157
- package/v3/@swarmdo/cli/.claude/helpers/statusline.js +0 -352
- package/v3/@swarmdo/plugin-iot-cognitum/dist/application/index.d.ts +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/application/index.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/application/iot-coordinator.d.ts +0 -138
- package/v3/@swarmdo/plugin-iot-cognitum/dist/application/iot-coordinator.js +0 -418
- package/v3/@swarmdo/plugin-iot-cognitum/dist/bin.d.ts +0 -15
- package/v3/@swarmdo/plugin-iot-cognitum/dist/bin.js +0 -240
- package/v3/@swarmdo/plugin-iot-cognitum/dist/cli-commands.d.ts +0 -7
- package/v3/@swarmdo/plugin-iot-cognitum/dist/cli-commands.js +0 -508
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-agent.d.ts +0 -54
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-agent.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-fleet.d.ts +0 -46
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-fleet.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-trust-level.d.ts +0 -18
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/device-trust-level.js +0 -28
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/index.d.ts +0 -5
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/index.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/telemetry.d.ts +0 -35
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/entities/telemetry.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/device-repository.d.ts +0 -11
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/device-repository.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/fleet-repository.d.ts +0 -9
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/fleet-repository.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/index.d.ts +0 -5
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/index.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/telemetry-repository.d.ts +0 -12
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/telemetry-repository.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/trust-history-repository.d.ts +0 -19
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/repositories/trust-history-repository.js +0 -2
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/anomaly-detection-service.d.ts +0 -44
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/anomaly-detection-service.js +0 -117
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/device-lifecycle-service.d.ts +0 -70
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/device-lifecycle-service.js +0 -194
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/firmware-orchestration-service.d.ts +0 -69
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/firmware-orchestration-service.js +0 -139
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/fleet-topology-service.d.ts +0 -34
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/fleet-topology-service.js +0 -101
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/index.d.ts +0 -10
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/index.js +0 -10
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/mesh-service.d.ts +0 -64
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/mesh-service.js +0 -70
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/sona-integration-service.d.ts +0 -44
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/sona-integration-service.js +0 -79
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/telemetry-ingestion-service.d.ts +0 -37
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/telemetry-ingestion-service.js +0 -39
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/telemetry-service.d.ts +0 -67
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/telemetry-service.js +0 -58
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/witness-verification-service.d.ts +0 -45
- package/v3/@swarmdo/plugin-iot-cognitum/dist/domain/services/witness-verification-service.js +0 -63
- package/v3/@swarmdo/plugin-iot-cognitum/dist/index.d.ts +0 -26
- package/v3/@swarmdo/plugin-iot-cognitum/dist/index.js +0 -17
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/agentdb-telemetry-repository.d.ts +0 -51
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/agentdb-telemetry-repository.js +0 -110
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-device-repository.d.ts +0 -13
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-device-repository.js +0 -25
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-fleet-repository.d.ts +0 -11
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-fleet-repository.js +0 -19
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-trust-history-repository.d.ts +0 -11
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/in-memory-trust-history-repository.js +0 -27
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/index.d.ts +0 -6
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/index.js +0 -6
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/seed-client-factory.d.ts +0 -41
- package/v3/@swarmdo/plugin-iot-cognitum/dist/infrastructure/seed-client-factory.js +0 -64
- package/v3/@swarmdo/plugin-iot-cognitum/dist/mcp-tools.d.ts +0 -8
- package/v3/@swarmdo/plugin-iot-cognitum/dist/mcp-tools.js +0 -703
- package/v3/@swarmdo/plugin-iot-cognitum/dist/plugin.d.ts +0 -23
- package/v3/@swarmdo/plugin-iot-cognitum/dist/plugin.js +0 -239
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/anomaly-scan-worker.d.ts +0 -17
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/anomaly-scan-worker.js +0 -42
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/firmware-watch-worker.d.ts +0 -18
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/firmware-watch-worker.js +0 -45
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/health-probe-worker.d.ts +0 -19
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/health-probe-worker.js +0 -50
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/mesh-sync-worker.d.ts +0 -19
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/mesh-sync-worker.js +0 -47
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/telemetry-ingest-worker.d.ts +0 -17
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/telemetry-ingest-worker.js +0 -40
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/witness-audit-worker.d.ts +0 -18
- package/v3/@swarmdo/plugin-iot-cognitum/dist/workers/witness-audit-worker.js +0 -51
- package/v3/@swarmdo/testing/dist/fixtures/agent-fixtures.d.ts +0 -214
- package/v3/@swarmdo/testing/dist/fixtures/agent-fixtures.js +0 -595
- package/v3/@swarmdo/testing/dist/fixtures/agents.d.ts +0 -76
- package/v3/@swarmdo/testing/dist/fixtures/agents.js +0 -158
- package/v3/@swarmdo/testing/dist/fixtures/configurations.d.ts +0 -157
- package/v3/@swarmdo/testing/dist/fixtures/configurations.js +0 -337
- package/v3/@swarmdo/testing/dist/fixtures/index.d.ts +0 -10
- package/v3/@swarmdo/testing/dist/fixtures/index.js +0 -17
- package/v3/@swarmdo/testing/dist/fixtures/mcp-fixtures.d.ts +0 -329
- package/v3/@swarmdo/testing/dist/fixtures/mcp-fixtures.js +0 -714
- package/v3/@swarmdo/testing/dist/fixtures/memory-entries.d.ts +0 -159
- package/v3/@swarmdo/testing/dist/fixtures/memory-entries.js +0 -262
- package/v3/@swarmdo/testing/dist/fixtures/memory-fixtures.d.ts +0 -290
- package/v3/@swarmdo/testing/dist/fixtures/memory-fixtures.js +0 -547
- package/v3/@swarmdo/testing/dist/fixtures/swarm-fixtures.d.ts +0 -289
- package/v3/@swarmdo/testing/dist/fixtures/swarm-fixtures.js +0 -534
- package/v3/@swarmdo/testing/dist/fixtures/tasks.d.ts +0 -106
- package/v3/@swarmdo/testing/dist/fixtures/tasks.js +0 -229
- package/v3/@swarmdo/testing/dist/helpers/assertion-helpers.d.ts +0 -213
- package/v3/@swarmdo/testing/dist/helpers/assertion-helpers.js +0 -435
- package/v3/@swarmdo/testing/dist/helpers/assertions.d.ts +0 -135
- package/v3/@swarmdo/testing/dist/helpers/assertions.js +0 -217
- package/v3/@swarmdo/testing/dist/helpers/create-mock.d.ts +0 -96
- package/v3/@swarmdo/testing/dist/helpers/create-mock.js +0 -164
- package/v3/@swarmdo/testing/dist/helpers/index.d.ts +0 -14
- package/v3/@swarmdo/testing/dist/helpers/index.js +0 -22
- package/v3/@swarmdo/testing/dist/helpers/mock-factory.d.ts +0 -323
- package/v3/@swarmdo/testing/dist/helpers/mock-factory.js +0 -350
- package/v3/@swarmdo/testing/dist/helpers/setup-teardown.d.ts +0 -271
- package/v3/@swarmdo/testing/dist/helpers/setup-teardown.js +0 -446
- package/v3/@swarmdo/testing/dist/helpers/swarm-instance.d.ts +0 -142
- package/v3/@swarmdo/testing/dist/helpers/swarm-instance.js +0 -205
- package/v3/@swarmdo/testing/dist/helpers/test-application.d.ts +0 -190
- package/v3/@swarmdo/testing/dist/helpers/test-application.js +0 -138
- package/v3/@swarmdo/testing/dist/helpers/test-utils.d.ts +0 -274
- package/v3/@swarmdo/testing/dist/helpers/test-utils.js +0 -456
- package/v3/@swarmdo/testing/dist/index.d.ts +0 -42
- package/v3/@swarmdo/testing/dist/index.js +0 -66
- package/v3/@swarmdo/testing/dist/mocks/index.d.ts +0 -8
- package/v3/@swarmdo/testing/dist/mocks/index.js +0 -10
- package/v3/@swarmdo/testing/dist/mocks/mock-mcp-client.d.ts +0 -206
- package/v3/@swarmdo/testing/dist/mocks/mock-mcp-client.js +0 -575
- package/v3/@swarmdo/testing/dist/mocks/mock-services.d.ts +0 -287
- package/v3/@swarmdo/testing/dist/mocks/mock-services.js +0 -563
- package/v3/@swarmdo/testing/dist/regression/api-contract.d.ts +0 -109
- package/v3/@swarmdo/testing/dist/regression/api-contract.js +0 -374
- package/v3/@swarmdo/testing/dist/regression/index.d.ts +0 -18
- package/v3/@swarmdo/testing/dist/regression/index.js +0 -18
- package/v3/@swarmdo/testing/dist/regression/integration-regression.d.ts +0 -67
- package/v3/@swarmdo/testing/dist/regression/integration-regression.js +0 -334
- package/v3/@swarmdo/testing/dist/regression/performance-baseline.d.ts +0 -106
- package/v3/@swarmdo/testing/dist/regression/performance-baseline.js +0 -268
- package/v3/@swarmdo/testing/dist/regression/regression-runner.d.ts +0 -124
- package/v3/@swarmdo/testing/dist/regression/regression-runner.js +0 -227
- package/v3/@swarmdo/testing/dist/regression/security-regression.d.ts +0 -73
- package/v3/@swarmdo/testing/dist/regression/security-regression.js +0 -258
- package/v3/@swarmdo/testing/dist/setup.d.ts +0 -43
- package/v3/@swarmdo/testing/dist/setup.js +0 -91
- package/v3/@swarmdo/testing/dist/v2-compat/api-compat.test.d.ts +0 -10
- package/v3/@swarmdo/testing/dist/v2-compat/api-compat.test.js +0 -433
- package/v3/@swarmdo/testing/dist/v2-compat/cli-compat.test.d.ts +0 -10
- package/v3/@swarmdo/testing/dist/v2-compat/cli-compat.test.js +0 -352
- package/v3/@swarmdo/testing/dist/v2-compat/compatibility-validator.d.ts +0 -206
- package/v3/@swarmdo/testing/dist/v2-compat/compatibility-validator.js +0 -839
- package/v3/@swarmdo/testing/dist/v2-compat/hooks-compat.test.d.ts +0 -10
- package/v3/@swarmdo/testing/dist/v2-compat/hooks-compat.test.js +0 -428
- package/v3/@swarmdo/testing/dist/v2-compat/index.d.ts +0 -38
- package/v3/@swarmdo/testing/dist/v2-compat/index.js +0 -41
- package/v3/@swarmdo/testing/dist/v2-compat/mcp-compat.test.d.ts +0 -10
- package/v3/@swarmdo/testing/dist/v2-compat/mcp-compat.test.js +0 -419
- package/v3/@swarmdo/testing/dist/v2-compat/report-generator.d.ts +0 -34
- package/v3/@swarmdo/testing/dist/v2-compat/report-generator.js +0 -372
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: base-template-generator
|
|
3
|
-
description: Use this agent when you need to create foundational templates, boilerplate code, or starter configurations for new projects, components, or features. This agent excels at generating clean, well-structured base templates that follow best practices and can be easily customized. Examples: <example>Context: User needs to start a new React component and wants a solid foundation. user: 'I need to create a new user profile component' assistant: 'I'll use the base-template-generator agent to create a comprehensive React component template with proper structure, TypeScript definitions, and styling setup.' <commentary>Since the user needs a foundational template for a new component, use the base-template-generator agent to create a well-structured starting point.</commentary></example> <example>Context: User is setting up a new API endpoint and needs a template. user: 'Can you help me set up a new REST API endpoint for user management?' assistant: 'I'll use the base-template-generator agent to create a complete API endpoint template with proper error handling, validation, and documentation structure.' <commentary>The user needs a foundational template for an API endpoint, so use the base-template-generator agent to provide a comprehensive starting point.</commentary></example>
|
|
3
|
+
description: "Use this agent when you need to create foundational templates, boilerplate code, or starter configurations for new projects, components, or features. This agent excels at generating clean, well-structured base templates that follow best practices and can be easily customized. Examples: <example>Context: User needs to start a new React component and wants a solid foundation. user: 'I need to create a new user profile component' assistant: 'I'll use the base-template-generator agent to create a comprehensive React component template with proper structure, TypeScript definitions, and styling setup.' <commentary>Since the user needs a foundational template for a new component, use the base-template-generator agent to create a well-structured starting point.</commentary></example> <example>Context: User is setting up a new API endpoint and needs a template. user: 'Can you help me set up a new REST API endpoint for user management?' assistant: 'I'll use the base-template-generator agent to create a complete API endpoint template with proper error handling, validation, and documentation structure.' <commentary>The user needs a foundational template for an API endpoint, so use the base-template-generator agent to provide a comprehensive starting point.</commentary></example>"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Base Template Generator, an expert architect specializing in creating clean, well-structured foundational templates and boilerplate code. Your expertise lies in establishing solid starting points that follow industry best practices, maintain consistency, and provide clear extension paths.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-goal-planner
|
|
3
|
-
description: Code-centric Goal-Oriented Action Planning specialist that creates intelligent plans for software development objectives. Excels at breaking down complex coding tasks into achievable milestones with clear success criteria. Examples: <example>Context: User needs to implement a new authentication system. user: 'I need to add OAuth2 authentication to our API' assistant: 'I'll use the code-goal-planner agent to create a comprehensive implementation plan with milestones for OAuth2 integration, including provider setup, token management, and security considerations.' <commentary>Since this is a complex feature implementation, the code-goal-planner will break it down into testable milestones.</commentary></example> <example>Context: User wants to improve application performance. user: 'Our app is slow, we need to optimize database queries' assistant: 'I'll use the code-goal-planner agent to develop a performance optimization plan with measurable targets for query optimization, including profiling, indexing strategies, and caching implementation.' <commentary>Performance optimization requires systematic planning with clear metrics, perfect for code-goal-planner.</commentary></example>
|
|
3
|
+
description: "Code-centric Goal-Oriented Action Planning specialist that creates intelligent plans for software development objectives. Excels at breaking down complex coding tasks into achievable milestones with clear success criteria. Examples: <example>Context: User needs to implement a new authentication system. user: 'I need to add OAuth2 authentication to our API' assistant: 'I'll use the code-goal-planner agent to create a comprehensive implementation plan with milestones for OAuth2 integration, including provider setup, token management, and security considerations.' <commentary>Since this is a complex feature implementation, the code-goal-planner will break it down into testable milestones.</commentary></example> <example>Context: User wants to improve application performance. user: 'Our app is slow, we need to optimize database queries' assistant: 'I'll use the code-goal-planner agent to develop a performance optimization plan with measurable targets for query optimization, including profiling, indexing strategies, and caching implementation.' <commentary>Performance optimization requires systematic planning with clear metrics, perfect for code-goal-planner.</commentary></example>"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Code-Centric Goal-Oriented Action Planning (GOAP) specialist integrated with SPARC methodology, focused exclusively on software development objectives. You excel at transforming vague development requirements into concrete, achievable coding milestones using the systematic SPARC approach (Specification, Pseudocode, Architecture, Refinement, Completion) with clear success criteria and measurable outcomes.
|
|
@@ -144,19 +144,23 @@ const handlers = {
|
|
|
144
144
|
} else {
|
|
145
145
|
console.log('[INFO] Router not available, using default routing');
|
|
146
146
|
}
|
|
147
|
-
// Agentic prompts →
|
|
148
|
-
// Claude Code
|
|
149
|
-
//
|
|
147
|
+
// Agentic prompts → suggest spawning a swarm, and which roles. Swarmdo
|
|
148
|
+
// cannot call Claude Code's Agent tool itself, so this advisory is the only
|
|
149
|
+
// way it can ask. Fully guarded — never breaks the prompt.
|
|
150
|
+
//
|
|
151
|
+
// Deliberately does NOT mention `agent bridge register` (#108): the
|
|
152
|
+
// SubagentStart hook registers every subagent on spawn, so telling the main
|
|
153
|
+
// agent to register by hand is both wrong and redundant work. This fires on
|
|
154
|
+
// every agentic prompt, so it is kept to one line — the three lines of
|
|
155
|
+
// manual-registration instructions it replaced were pure token cost.
|
|
150
156
|
try {
|
|
151
157
|
if (router && router.classifyAgentic) {
|
|
152
158
|
const intent = router.classifyAgentic(prompt);
|
|
153
159
|
if (intent.requiresAgents) {
|
|
154
160
|
const roles = intent.roles.join(', ');
|
|
155
161
|
console.log('');
|
|
156
|
-
console.log('[SWARMDO] Agentic task —
|
|
157
|
-
|
|
158
|
-
console.log(' swarmdo agent bridge register -n <agent-name> -t <role> -s <session>');
|
|
159
|
-
console.log(' suggested roles: ' + roles + ' · then: swarmdo agent bridge list / swarm status');
|
|
162
|
+
console.log('[SWARMDO] Agentic task — consider spawning agents: ' + roles
|
|
163
|
+
+ ' (auto-registered on spawn; see `swarmdo swarm status`)');
|
|
160
164
|
}
|
|
161
165
|
}
|
|
162
166
|
} catch (e) { /* advisory only — never break the prompt */ }
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://swarmdo.com)
|
|
4
4
|
|
|
5
|
-
[](https://img.shields.io/npm/v/swarmdo?style=for-the-badge&logo=npm&logoColor=white&label=npx%20swarmdo&color=cb3837)](https://github.com/SwarmDo/swarmdo/releases)
|
|
6
6
|
[](https://github.com/SwarmDo/swarmdo/blob/main/LICENSE)
|
|
7
7
|
[](https://swarmdo.com)
|
|
8
8
|
[](https://github.com/SwarmDo/swarmdo)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swarmdo",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.24",
|
|
4
4
|
"description": "Swarmdo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-bridge-hook.cjs — bind real Claude Code subagents into Swarmdo's
|
|
3
|
+
* canonical agent registry, automatically.
|
|
4
|
+
*
|
|
5
|
+
* #108. `src/agent-bridge/bridge.ts` was written to solve "a session can run
|
|
6
|
+
* four Claude Code agents while `swarmdo agent list` stays empty", and is pure
|
|
7
|
+
* by design because "All fs / MCP / spawning lives in the command + hook
|
|
8
|
+
* layers". The command layer got built (`swarmdo agent bridge register`); the
|
|
9
|
+
* hook layer never did. So nothing ever registered a Task/Agent-tool subagent,
|
|
10
|
+
* `.swarmdo/agents/store.json` stayed `{"agents":{}}`, and the statusline's
|
|
11
|
+
* `🐝 Swarms N 🤖 Agents M` sat at 0/0 forever. This file is that missing
|
|
12
|
+
* hook layer.
|
|
13
|
+
*
|
|
14
|
+
* Why shell out to the CLI instead of writing the store here: registering is
|
|
15
|
+
* not just a store write — `agent_bridge_register` also auto-forms a swarm from
|
|
16
|
+
* config and enrolls the agent (agent-tools.ts:462), which is what makes the
|
|
17
|
+
* Swarms counter move too. bridge.ts's own rule is to go through the canonical
|
|
18
|
+
* registerAgent path — "NO parallel store". Reimplementing that in CJS would
|
|
19
|
+
* fork the registry. The CLI costs ~850ms to boot (it loads ONNX), far too slow
|
|
20
|
+
* to block every subagent spawn, so calls are fired detached and unref'd: the
|
|
21
|
+
* hook returns immediately and the registry lands ~1s later. The statusline
|
|
22
|
+
* polls every 5s, so eventual consistency is invisible here.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const fs = require('fs');
|
|
26
|
+
const os = require('os');
|
|
27
|
+
const path = require('path');
|
|
28
|
+
const { spawn } = require('child_process');
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Mirror of src/agent-bridge/bridge.ts `bridgeAgentId` — kept in sync by hand,
|
|
32
|
+
* because this hook is standalone CommonJS and cannot import the ESM engine
|
|
33
|
+
* (the same constraint router.cjs already works under for classifyPrompt).
|
|
34
|
+
* __tests__/agent-bridge-hook.test.ts asserts the two implementations agree.
|
|
35
|
+
*
|
|
36
|
+
* Deterministic, so SubagentStart and SubagentStop derive the SAME id from the
|
|
37
|
+
* same agent_id and the stop reliably terminates the record the start created.
|
|
38
|
+
*/
|
|
39
|
+
function bridgeAgentId(d) {
|
|
40
|
+
const sess = d.sessionId
|
|
41
|
+
? d.sessionId.replace(/[^A-Za-z0-9]/g, '').slice(0, 8) || 'nosess'
|
|
42
|
+
: 'nosess';
|
|
43
|
+
const safe = String(d.name || '').replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '') || 'agent';
|
|
44
|
+
return `cc-${sess}-${safe}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Locate an installed CLI bin. Mirror of statusline.cjs resolveCliBin() — same
|
|
49
|
+
* candidate order, same reason (#2337): never `npx @latest` from a hook.
|
|
50
|
+
* Returns null when nothing is installed, in which case we no-op rather than
|
|
51
|
+
* pay a registry round-trip on every subagent spawn.
|
|
52
|
+
*/
|
|
53
|
+
function resolveCliBin(cwd) {
|
|
54
|
+
try {
|
|
55
|
+
const home = os.homedir();
|
|
56
|
+
const base = cwd || process.cwd();
|
|
57
|
+
const candidates = [
|
|
58
|
+
path.join(home, '.claude', 'plugins', 'marketplaces', 'swarmdo', 'bin', 'cli.js'),
|
|
59
|
+
path.join(base, 'node_modules', '@swarmdo', 'cli', 'bin', 'cli.js'),
|
|
60
|
+
path.join(base, 'node_modules', 'swarmdo', 'bin', 'cli.js'),
|
|
61
|
+
path.join(base, 'v3', '@swarmdo', 'cli', 'bin', 'cli.js'),
|
|
62
|
+
];
|
|
63
|
+
try {
|
|
64
|
+
const binDir = path.dirname(process.execPath);
|
|
65
|
+
const globalModuleDirs = [
|
|
66
|
+
path.join(binDir, '..', 'lib', 'node_modules'),
|
|
67
|
+
path.join(binDir, 'node_modules'),
|
|
68
|
+
'/opt/homebrew/lib/node_modules',
|
|
69
|
+
'/usr/local/lib/node_modules',
|
|
70
|
+
];
|
|
71
|
+
for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
|
|
72
|
+
if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
|
|
73
|
+
}
|
|
74
|
+
for (const gm of globalModuleDirs) {
|
|
75
|
+
candidates.push(
|
|
76
|
+
path.join(gm, 'swarmdo', 'bin', 'cli.js'),
|
|
77
|
+
path.join(gm, '@swarmdo', 'cli', 'bin', 'cli.js'),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
} catch { /* ignore */ }
|
|
81
|
+
for (const p of candidates) {
|
|
82
|
+
if (fs.existsSync(p)) return p;
|
|
83
|
+
}
|
|
84
|
+
} catch { /* ignore */ }
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Is this hook payload a real subagent event we should act on? `agent_id` is
|
|
90
|
+
* present ONLY when the hook fires for a subagent, so it doubles as the guard
|
|
91
|
+
* against main-thread invocations. Pure.
|
|
92
|
+
*/
|
|
93
|
+
function isSubagentEvent(hookInput) {
|
|
94
|
+
const id = hookInput && (hookInput.agent_id || hookInput.agentId);
|
|
95
|
+
return typeof id === 'string' && id.length > 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Build the `agent bridge register` argv for a SubagentStart payload, or null
|
|
100
|
+
* when the payload is not a subagent event. Pure — the spawn happens in
|
|
101
|
+
* register(). Registering is idempotent on name+session, so a duplicate
|
|
102
|
+
* SubagentStart updates the bound record rather than forking a second one.
|
|
103
|
+
*/
|
|
104
|
+
function buildRegisterArgs(hookInput) {
|
|
105
|
+
if (!isSubagentEvent(hookInput)) return null;
|
|
106
|
+
const agentId = hookInput.agent_id || hookInput.agentId;
|
|
107
|
+
const sessionId = hookInput.session_id || hookInput.sessionId || '';
|
|
108
|
+
const agentType = hookInput.agent_type || hookInput.agentType || 'general-purpose';
|
|
109
|
+
const args = ['agent', 'bridge', 'register', '-n', agentId, '-t', agentType];
|
|
110
|
+
if (sessionId) args.push('-s', sessionId);
|
|
111
|
+
return args;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Build the `agent stop` argv for a SubagentStop payload, or null when the
|
|
116
|
+
* payload is not a subagent event. `agent stop` sets status='terminated'
|
|
117
|
+
* (agent-tools.ts:721), which is precisely what computeSwarmStatus filters on,
|
|
118
|
+
* so the Agents count decrements when a subagent finishes. `-f` because a hook
|
|
119
|
+
* has no TTY and must not hit the interactive confirm. Pure.
|
|
120
|
+
*/
|
|
121
|
+
function buildTerminateArgs(hookInput) {
|
|
122
|
+
if (!isSubagentEvent(hookInput)) return null;
|
|
123
|
+
const id = bridgeAgentId({
|
|
124
|
+
name: hookInput.agent_id || hookInput.agentId,
|
|
125
|
+
sessionId: hookInput.session_id || hookInput.sessionId,
|
|
126
|
+
});
|
|
127
|
+
return ['agent', 'stop', id, '-f'];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Fire a CLI subcommand and forget it. Detached + unref'd + stdio ignored so
|
|
132
|
+
* the hook process can exit immediately without waiting on the CLI's ~850ms
|
|
133
|
+
* boot, and without the child dying alongside it.
|
|
134
|
+
*/
|
|
135
|
+
function spawnDetached(args, cwd) {
|
|
136
|
+
const cliBin = resolveCliBin(cwd);
|
|
137
|
+
if (!cliBin) return false;
|
|
138
|
+
try {
|
|
139
|
+
const child = spawn(process.execPath, [cliBin, ...args], {
|
|
140
|
+
cwd: cwd || process.cwd(),
|
|
141
|
+
detached: true,
|
|
142
|
+
stdio: 'ignore',
|
|
143
|
+
});
|
|
144
|
+
child.unref();
|
|
145
|
+
return true;
|
|
146
|
+
} catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** SubagentStart → bind the subagent (and auto-form its swarm). */
|
|
152
|
+
function register(hookInput, cwd) {
|
|
153
|
+
const args = buildRegisterArgs(hookInput);
|
|
154
|
+
if (!args) return false;
|
|
155
|
+
return spawnDetached(args, cwd || (hookInput && hookInput.cwd));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** SubagentStop → mark the bound record terminated. */
|
|
159
|
+
function terminate(hookInput, cwd) {
|
|
160
|
+
const args = buildTerminateArgs(hookInput);
|
|
161
|
+
if (!args) return false;
|
|
162
|
+
return spawnDetached(args, cwd || (hookInput && hookInput.cwd));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = {
|
|
166
|
+
bridgeAgentId,
|
|
167
|
+
resolveCliBin,
|
|
168
|
+
isSubagentEvent,
|
|
169
|
+
buildRegisterArgs,
|
|
170
|
+
buildTerminateArgs,
|
|
171
|
+
spawnDetached,
|
|
172
|
+
register,
|
|
173
|
+
terminate,
|
|
174
|
+
};
|
|
@@ -34,9 +34,9 @@ const dim = (msg) => console.log(` ${DIM}${msg}${RESET}`);
|
|
|
34
34
|
const DEBUG = !!(process.env.SWARMDO_DEBUG || process.env.DEBUG);
|
|
35
35
|
|
|
36
36
|
// ── Graceful shutdown (FIX 3) ───────────────────────────────────────────────
|
|
37
|
-
// Track the backend in use so a SIGTERM/SIGINT mid-run can still
|
|
38
|
-
// (the JSON backend persists
|
|
39
|
-
// of leaving a half-written store or a stale lock behind.
|
|
37
|
+
// Track the backend currently in use so a SIGTERM/SIGINT mid-run can still
|
|
38
|
+
// flush it (the JSON backend persists, a SQLite-backed one closes/flushes WAL)
|
|
39
|
+
// instead of leaving a half-written store or a stale lock behind.
|
|
40
40
|
let activeBackend = null;
|
|
41
41
|
let shuttingDown = false;
|
|
42
42
|
function trackBackend(b) { activeBackend = b; return b; }
|
|
@@ -177,16 +177,77 @@ class JsonFileBackend {
|
|
|
177
177
|
// Resolve memory package path (local dev or npm installed)
|
|
178
178
|
// ============================================================================
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Resolve a bundled package file (`<pkg>/<relativeFile>`) by trying, in order:
|
|
182
|
+
* 1. PROJECT_ROOT/v3/<pkg>/<relativeFile> (monorepo dev layout)
|
|
183
|
+
* 2. CWD/node_modules/<pkg>/<relativeFile> (user's project deps)
|
|
184
|
+
* 3. node_modules walk-up from PROJECT_ROOT
|
|
185
|
+
* 4. node_modules walk-up from CWD
|
|
186
|
+
* 5. Global npm prefix — checks the swarmdo / swarmdo / @swarmdo/cli
|
|
187
|
+
* bundles, AND the package installed globally on its own
|
|
188
|
+
*
|
|
189
|
+
* Returns the resolved absolute path, or null. See issue #2285.
|
|
190
|
+
*/
|
|
191
|
+
async function resolveBundledFile(pkg, relativeFile) {
|
|
192
|
+
const monorepo = join(PROJECT_ROOT, 'v3', pkg, relativeFile);
|
|
193
|
+
if (existsSync(monorepo)) return monorepo;
|
|
194
|
+
|
|
195
|
+
const cwd = process.env.SWARMDO_CWD || process.cwd();
|
|
196
|
+
const inCwd = join(cwd, 'node_modules', pkg, relativeFile);
|
|
197
|
+
if (existsSync(inCwd)) return inCwd;
|
|
198
|
+
|
|
199
|
+
const walkUp = (start) => {
|
|
200
|
+
let dir = start;
|
|
201
|
+
while (dir && dir !== dirname(dir)) {
|
|
202
|
+
const candidate = join(dir, 'node_modules', pkg, relativeFile);
|
|
203
|
+
if (existsSync(candidate)) return candidate;
|
|
204
|
+
dir = dirname(dir);
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const fromProject = walkUp(PROJECT_ROOT);
|
|
210
|
+
if (fromProject) return fromProject;
|
|
211
|
+
|
|
212
|
+
const fromCwd = walkUp(cwd);
|
|
213
|
+
if (fromCwd) return fromCwd;
|
|
214
|
+
|
|
215
|
+
// Global npm prefix fallback — handles `npm i -g swarmdo` and friends, where
|
|
216
|
+
// the marketplace clone (PROJECT_ROOT) has no access to the bundled deps.
|
|
217
|
+
try {
|
|
218
|
+
const { execSync } = await import('child_process');
|
|
219
|
+
const npmPrefix = execSync('npm prefix -g', {
|
|
220
|
+
encoding: 'utf-8',
|
|
221
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
222
|
+
}).trim();
|
|
223
|
+
if (npmPrefix) {
|
|
224
|
+
// Both Unix (<prefix>/lib/node_modules) and Windows (<prefix>/node_modules)
|
|
225
|
+
const roots = [join(npmPrefix, 'lib', 'node_modules'), join(npmPrefix, 'node_modules')];
|
|
226
|
+
const wrappers = ['swarmdo', 'swarmdo', join('@swarmdo', 'cli')];
|
|
227
|
+
for (const root of roots) {
|
|
228
|
+
for (const wrapper of wrappers) {
|
|
229
|
+
const candidate = join(root, wrapper, 'node_modules', pkg, relativeFile);
|
|
230
|
+
if (existsSync(candidate)) return candidate;
|
|
231
|
+
}
|
|
232
|
+
const direct = join(root, pkg, relativeFile);
|
|
233
|
+
if (existsSync(direct)) return direct;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} catch { /* npm not on PATH or no global install */ }
|
|
237
|
+
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
|
|
180
241
|
async function loadMemoryPackage() {
|
|
181
|
-
// Strategy 1:
|
|
182
|
-
const
|
|
183
|
-
if (
|
|
242
|
+
// Strategy 1-5: locate dist/index.js across dev/installed/global layouts
|
|
243
|
+
const resolved = await resolveBundledFile('@swarmdo/memory', 'dist/index.js');
|
|
244
|
+
if (resolved) {
|
|
184
245
|
try {
|
|
185
|
-
return await import(`file://${
|
|
246
|
+
return await import(`file://${resolved}`);
|
|
186
247
|
} catch { /* fall through */ }
|
|
187
248
|
}
|
|
188
249
|
|
|
189
|
-
// Strategy
|
|
250
|
+
// Strategy 6: Use createRequire for CJS-style resolution (handles nested node_modules
|
|
190
251
|
// when installed as a transitive dependency via npx swarmdo / npx swarmdo)
|
|
191
252
|
try {
|
|
192
253
|
const { createRequire } = await import('module');
|
|
@@ -194,24 +255,11 @@ async function loadMemoryPackage() {
|
|
|
194
255
|
return require('@swarmdo/memory');
|
|
195
256
|
} catch { /* fall through */ }
|
|
196
257
|
|
|
197
|
-
// Strategy
|
|
258
|
+
// Strategy 7: ESM import (works when @swarmdo/memory is a direct dependency)
|
|
198
259
|
try {
|
|
199
260
|
return await import('@swarmdo/memory');
|
|
200
261
|
} catch { /* fall through */ }
|
|
201
262
|
|
|
202
|
-
// Strategy 4: Walk up from PROJECT_ROOT looking for @swarmdo/memory in any node_modules
|
|
203
|
-
let searchDir = PROJECT_ROOT;
|
|
204
|
-
const { parse } = await import('path');
|
|
205
|
-
while (searchDir !== parse(searchDir).root) {
|
|
206
|
-
const candidate = join(searchDir, 'node_modules', '@swarmdo', 'memory', 'dist', 'index.js');
|
|
207
|
-
if (existsSync(candidate)) {
|
|
208
|
-
try {
|
|
209
|
-
return await import(`file://${candidate}`);
|
|
210
|
-
} catch { /* fall through */ }
|
|
211
|
-
}
|
|
212
|
-
searchDir = dirname(searchDir);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
263
|
return null;
|
|
216
264
|
}
|
|
217
265
|
|
|
@@ -270,7 +318,10 @@ async function doImport() {
|
|
|
270
318
|
await backend.initialize();
|
|
271
319
|
|
|
272
320
|
const bridgeConfig = {
|
|
273
|
-
|
|
321
|
+
// Use Claude Code's invocation cwd (the user's project), not PROJECT_ROOT
|
|
322
|
+
// — PROJECT_ROOT resolves to the plugin clone when this hook runs from
|
|
323
|
+
// ~/.claude/plugins/marketplaces/swarmdo/. See issue #2284.
|
|
324
|
+
workingDir: process.env.SWARMDO_CWD || process.cwd(),
|
|
274
325
|
syncMode: 'on-session-end',
|
|
275
326
|
};
|
|
276
327
|
|
|
@@ -302,6 +353,36 @@ async function doImport() {
|
|
|
302
353
|
dim(`├─ Learning: ${config.learningBridge.enabled ? 'active' : 'disabled'}`);
|
|
303
354
|
dim(`├─ Graph: ${config.memoryGraph.enabled ? 'active' : 'disabled'}`);
|
|
304
355
|
dim(`└─ Agent scopes: ${config.agentScopes.enabled ? 'active' : 'disabled'}`);
|
|
356
|
+
|
|
357
|
+
// Bridge to AgentDB: store entries with ONNX vector embeddings for semantic search
|
|
358
|
+
let vectorized = 0;
|
|
359
|
+
try {
|
|
360
|
+
const cliDistPath = await resolveBundledFile('@swarmdo/cli', 'dist/src/memory/memory-initializer.js');
|
|
361
|
+
if (cliDistPath) {
|
|
362
|
+
const memInit = await import(`file://${cliDistPath}`);
|
|
363
|
+
await memInit.initializeMemoryDatabase({ force: false, verbose: false });
|
|
364
|
+
|
|
365
|
+
const entries = await backend.query({});
|
|
366
|
+
for (const entry of entries) {
|
|
367
|
+
if (!entry.content || entry.content.length < 10) continue;
|
|
368
|
+
try {
|
|
369
|
+
await memInit.storeEntry({
|
|
370
|
+
key: entry.key || entry.id,
|
|
371
|
+
value: entry.content,
|
|
372
|
+
namespace: entry.namespace || 'auto-memory',
|
|
373
|
+
generateEmbeddingFlag: true,
|
|
374
|
+
});
|
|
375
|
+
vectorized++;
|
|
376
|
+
} catch { /* skip entries that fail to embed */ }
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (vectorized > 0) {
|
|
380
|
+
success(`Vectorized ${vectorized} entries into AgentDB (ONNX 384-dim)`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} catch (vecErr) {
|
|
384
|
+
dim(`AgentDB vectorization skipped: ${vecErr.message?.slice(0, 60)}`);
|
|
385
|
+
}
|
|
305
386
|
} catch (err) {
|
|
306
387
|
dim(`Import failed (non-critical): ${err.message}`);
|
|
307
388
|
}
|
|
@@ -330,7 +411,8 @@ async function doSync() {
|
|
|
330
411
|
}
|
|
331
412
|
|
|
332
413
|
const bridgeConfig = {
|
|
333
|
-
|
|
414
|
+
// See doImport — must reflect the user's project, not PROJECT_ROOT (#2284)
|
|
415
|
+
workingDir: process.env.SWARMDO_CWD || process.cwd(),
|
|
334
416
|
syncMode: 'on-session-end',
|
|
335
417
|
};
|
|
336
418
|
|
|
@@ -360,6 +442,21 @@ async function doSync() {
|
|
|
360
442
|
// Curate MEMORY.md index with graph-aware ordering
|
|
361
443
|
await bridge.curateIndex();
|
|
362
444
|
success('Curated MEMORY.md index');
|
|
445
|
+
|
|
446
|
+
// Flush intelligence patterns to disk (SONA + ReasoningBank)
|
|
447
|
+
try {
|
|
448
|
+
const intPath = await resolveBundledFile('@swarmdo/cli', 'dist/src/memory/intelligence.js');
|
|
449
|
+
if (intPath) {
|
|
450
|
+
const intelligence = await import(`file://${intPath}`);
|
|
451
|
+
if (intelligence.flushPatterns) {
|
|
452
|
+
intelligence.flushPatterns();
|
|
453
|
+
const stats = intelligence.getIntelligenceStats?.();
|
|
454
|
+
if (stats && stats.patternsLearned > 0) {
|
|
455
|
+
success(`Flushed ${stats.patternsLearned} learned patterns to disk`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
} catch { /* non-critical */ }
|
|
363
460
|
} catch (err) {
|
|
364
461
|
dim(`Sync failed (non-critical): ${err.message}`);
|
|
365
462
|
}
|
|
@@ -386,9 +483,158 @@ async function doStatus() {
|
|
|
386
483
|
} catch { /* ignore */ }
|
|
387
484
|
}
|
|
388
485
|
|
|
486
|
+
// AgentDB vector status
|
|
487
|
+
try {
|
|
488
|
+
const dbPath = join(PROJECT_ROOT, '.swarmdo', 'memory', 'memory.db');
|
|
489
|
+
const swarmDbPath = join(PROJECT_ROOT, '.swarm', 'memory.db');
|
|
490
|
+
const hasDb = existsSync(dbPath) || existsSync(swarmDbPath);
|
|
491
|
+
console.log(` AgentDB: ${hasDb ? '✅ sql.js database exists' : '⏸ Not initialized'}`);
|
|
492
|
+
|
|
493
|
+
const intPath = await resolveBundledFile('@swarmdo/cli', 'dist/src/memory/intelligence.js');
|
|
494
|
+
if (intPath) {
|
|
495
|
+
const intelligence = await import(`file://${intPath}`);
|
|
496
|
+
const stats = intelligence.getIntelligenceStats?.();
|
|
497
|
+
if (stats) {
|
|
498
|
+
console.log(` SONA: ${stats.sonaEnabled ? '✅ Active' : '⏸ Not initialized'}`);
|
|
499
|
+
console.log(` Patterns: ${stats.patternsLearned} learned`);
|
|
500
|
+
console.log(` Trajectories: ${stats.trajectoriesRecorded} recorded`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
} catch { /* ignore */ }
|
|
504
|
+
|
|
389
505
|
console.log('');
|
|
390
506
|
}
|
|
391
507
|
|
|
508
|
+
// ============================================================================
|
|
509
|
+
// Import ALL Claude Code memories from all projects into AgentDB
|
|
510
|
+
// ============================================================================
|
|
511
|
+
|
|
512
|
+
async function doImportAll() {
|
|
513
|
+
log('Importing ALL Claude Code memories into AgentDB...');
|
|
514
|
+
|
|
515
|
+
const { homedir } = await import('os');
|
|
516
|
+
const { readdirSync } = await import('fs');
|
|
517
|
+
const claudeProjectsDir = join(homedir(), '.claude', 'projects');
|
|
518
|
+
|
|
519
|
+
if (!existsSync(claudeProjectsDir)) {
|
|
520
|
+
dim('No Claude Code projects found at ' + claudeProjectsDir);
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Find all memory files across all projects
|
|
525
|
+
const memoryFiles = [];
|
|
526
|
+
try {
|
|
527
|
+
const projects = readdirSync(claudeProjectsDir, { withFileTypes: true });
|
|
528
|
+
for (const project of projects) {
|
|
529
|
+
if (!project.isDirectory()) continue;
|
|
530
|
+
const memDir = join(claudeProjectsDir, project.name, 'memory');
|
|
531
|
+
if (!existsSync(memDir)) continue;
|
|
532
|
+
const files = readdirSync(memDir).filter(f => f.endsWith('.md'));
|
|
533
|
+
for (const file of files) {
|
|
534
|
+
memoryFiles.push({
|
|
535
|
+
path: join(memDir, file),
|
|
536
|
+
project: project.name,
|
|
537
|
+
file,
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (err) {
|
|
542
|
+
dim('Error scanning projects: ' + err.message);
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
if (memoryFiles.length === 0) {
|
|
547
|
+
dim('No memory files found');
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
log(`Found ${memoryFiles.length} memory files across ${new Set(memoryFiles.map(f => f.project)).size} projects`);
|
|
552
|
+
|
|
553
|
+
// Load memory-initializer for vectorized storage
|
|
554
|
+
let memInit = null;
|
|
555
|
+
try {
|
|
556
|
+
const cliDistPath = await resolveBundledFile('@swarmdo/cli', 'dist/src/memory/memory-initializer.js');
|
|
557
|
+
if (cliDistPath) {
|
|
558
|
+
memInit = await import(`file://${cliDistPath}`);
|
|
559
|
+
await memInit.initializeMemoryDatabase({ force: false, verbose: false });
|
|
560
|
+
}
|
|
561
|
+
} catch (err) {
|
|
562
|
+
dim('Memory initializer not available: ' + err.message?.slice(0, 60));
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (!memInit) {
|
|
566
|
+
dim('Cannot vectorize without memory-initializer. Run: cd v3/@swarmdo/cli && npm run build');
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
let imported = 0;
|
|
571
|
+
let skipped = 0;
|
|
572
|
+
|
|
573
|
+
for (const memFile of memoryFiles) {
|
|
574
|
+
try {
|
|
575
|
+
const content = readFileSync(memFile.path, 'utf-8');
|
|
576
|
+
|
|
577
|
+
// Parse YAML frontmatter + body
|
|
578
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
579
|
+
let name = memFile.file.replace('.md', '');
|
|
580
|
+
let description = '';
|
|
581
|
+
let type = 'auto-memory';
|
|
582
|
+
let body = content;
|
|
583
|
+
|
|
584
|
+
if (frontmatterMatch) {
|
|
585
|
+
const yaml = frontmatterMatch[1];
|
|
586
|
+
body = frontmatterMatch[2].trim();
|
|
587
|
+
const nameMatch = yaml.match(/^name:\s*(.+)$/m);
|
|
588
|
+
const descMatch = yaml.match(/^description:\s*(.+)$/m);
|
|
589
|
+
const typeMatch = yaml.match(/^type:\s*(.+)$/m);
|
|
590
|
+
if (nameMatch) name = nameMatch[1].trim();
|
|
591
|
+
if (descMatch) description = descMatch[1].trim();
|
|
592
|
+
if (typeMatch) type = typeMatch[1].trim();
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Split body into sections (## headers) for granular entries
|
|
596
|
+
const sections = body.split(/^(?=## )/m).filter(s => s.trim().length > 20);
|
|
597
|
+
|
|
598
|
+
if (sections.length === 0) {
|
|
599
|
+
// Store whole file as one entry
|
|
600
|
+
if (body.length > 10) {
|
|
601
|
+
await memInit.storeEntry({
|
|
602
|
+
key: `claude-memory:${memFile.project}:${name}`,
|
|
603
|
+
value: body.slice(0, 4096),
|
|
604
|
+
namespace: 'claude-memories',
|
|
605
|
+
generateEmbeddingFlag: true,
|
|
606
|
+
});
|
|
607
|
+
imported++;
|
|
608
|
+
}
|
|
609
|
+
} else {
|
|
610
|
+
// Store each section separately for better search granularity
|
|
611
|
+
for (const section of sections) {
|
|
612
|
+
const titleMatch = section.match(/^##\s+(.+)/);
|
|
613
|
+
const sectionTitle = titleMatch ? titleMatch[1].trim() : name;
|
|
614
|
+
const sectionBody = section.replace(/^##\s+.+\n/, '').trim();
|
|
615
|
+
if (sectionBody.length < 10) continue;
|
|
616
|
+
|
|
617
|
+
await memInit.storeEntry({
|
|
618
|
+
key: `claude-memory:${memFile.project}:${name}:${sectionTitle.slice(0, 50)}`,
|
|
619
|
+
value: sectionBody.slice(0, 4096),
|
|
620
|
+
namespace: 'claude-memories',
|
|
621
|
+
generateEmbeddingFlag: true,
|
|
622
|
+
});
|
|
623
|
+
imported++;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
dim(` ✓ ${memFile.project}/${memFile.file} (${sections.length || 1} entries)`);
|
|
628
|
+
} catch (err) {
|
|
629
|
+
dim(` ✗ ${memFile.project}/${memFile.file}: ${err.message?.slice(0, 60)}`);
|
|
630
|
+
skipped++;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
success(`Imported ${imported} entries from ${memoryFiles.length} files (${skipped} skipped)`);
|
|
635
|
+
success('All Claude Code memories now searchable via AgentDB vector search');
|
|
636
|
+
}
|
|
637
|
+
|
|
392
638
|
// ============================================================================
|
|
393
639
|
// Main
|
|
394
640
|
// ============================================================================
|
|
@@ -417,17 +663,18 @@ if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
|
|
|
417
663
|
try {
|
|
418
664
|
switch (command) {
|
|
419
665
|
case 'import': await doImport(); break;
|
|
666
|
+
case 'import-all': await doImportAll(); break;
|
|
420
667
|
case 'sync': await doSync(); break;
|
|
421
668
|
case 'status': await doStatus(); break;
|
|
422
669
|
default:
|
|
423
670
|
console.log('Usage: auto-memory-hook.mjs <import|sync|status>');
|
|
424
|
-
|
|
671
|
+
process.exit(1);
|
|
425
672
|
}
|
|
426
673
|
} catch (err) {
|
|
427
674
|
// Hooks must never crash Claude Code - fail silently
|
|
428
|
-
|
|
675
|
+
dim(`Error (non-critical): ${err.message}`);
|
|
429
676
|
}
|
|
430
|
-
//
|
|
677
|
+
// Ensure clean exit for Claude Code hooks (exit 0 = success, no stderr = no error)
|
|
431
678
|
process.exit(0);
|
|
432
679
|
}
|
|
433
680
|
|