squads-cli 0.4.11 → 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/README.md +24 -4
- package/dist/{chunk-HIQ2APYR.js → chunk-7PRYDHZW.js} +2 -2
- package/dist/chunk-BV6S5AWZ.js +419 -0
- package/dist/chunk-BV6S5AWZ.js.map +1 -0
- package/dist/chunk-QPH5OR7J.js +474 -0
- package/dist/chunk-QPH5OR7J.js.map +1 -0
- package/dist/cli.js +8031 -3620
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +54 -0
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/{memory-4PVUKIDK.js → memory-ZXDXF6KF.js} +8 -4
- package/dist/{sessions-R4VWIGFR.js → sessions-F6LRY7EN.js} +2 -2
- package/dist/squad-parser-MSYE4PXL.js +31 -0
- package/dist/squad-parser-MSYE4PXL.js.map +1 -0
- package/dist/templates/core/AGENTS.md.template +64 -0
- package/dist/templates/core/BUSINESS_BRIEF.md.template +29 -0
- package/dist/templates/core/CLAUDE.md.template +50 -0
- package/dist/templates/core/provider.yaml.template +5 -0
- package/dist/templates/first-squad/SQUAD.md.template +23 -0
- package/dist/templates/first-squad/lead.md.template +44 -0
- package/dist/templates/memory/getting-started/state.md.template +19 -0
- package/dist/templates/skills/squads-learn/SKILL.md +86 -0
- package/dist/templates/skills/squads-workflow/instruction.md +70 -0
- package/docker/docker-compose.engram.yml +26 -0
- package/docker/docker-compose.yml +132 -76
- package/docker/squads-bridge/squads_bridge.py +534 -8
- package/package.json +15 -9
- package/templates/core/AGENTS.md.template +64 -0
- package/templates/core/BUSINESS_BRIEF.md.template +29 -0
- package/templates/core/CLAUDE.md.template +50 -0
- package/templates/core/provider.yaml.template +5 -0
- package/templates/first-squad/SQUAD.md.template +23 -0
- package/templates/first-squad/lead.md.template +44 -0
- package/templates/memory/getting-started/state.md.template +19 -0
- package/templates/skills/squads-learn/SKILL.md +86 -0
- package/templates/skills/squads-workflow/instruction.md +70 -0
- package/dist/chunk-FUHBEL3L.js +0 -203
- package/dist/chunk-FUHBEL3L.js.map +0 -1
- /package/dist/{chunk-HIQ2APYR.js.map → chunk-7PRYDHZW.js.map} +0 -0
- /package/dist/{memory-4PVUKIDK.js.map → memory-ZXDXF6KF.js.map} +0 -0
- /package/dist/{sessions-R4VWIGFR.js.map → sessions-F6LRY7EN.js.map} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
# Project guidance for AI coding agents (vendor-neutral)
|
|
3
|
+
|
|
4
|
+
This project uses AI agent squads for development and operations.
|
|
5
|
+
|
|
6
|
+
## Getting Started
|
|
7
|
+
|
|
8
|
+
If this project is not yet set up, run:
|
|
9
|
+
```bash
|
|
10
|
+
squads setup # Guided onboarding (recommended)
|
|
11
|
+
squads init # Quick init (non-interactive)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Provider: {{PROVIDER_NAME}}
|
|
15
|
+
|
|
16
|
+
Configure in: `.agents/config/provider.yaml`
|
|
17
|
+
|
|
18
|
+
## Repository Structure
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
.agents/
|
|
22
|
+
├── squads/ # Agent team definitions
|
|
23
|
+
│ └── <squad>/
|
|
24
|
+
│ ├── SQUAD.md # Squad definition
|
|
25
|
+
│ └── *.md # Agent files
|
|
26
|
+
├── memory/ # Persistent context
|
|
27
|
+
├── config/ # Provider and model configuration
|
|
28
|
+
└── outputs/ # Agent outputs
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Agent Guidelines
|
|
32
|
+
|
|
33
|
+
### Before Starting Work
|
|
34
|
+
1. Run `squads status` to understand current state
|
|
35
|
+
2. Check `squads memory query "<topic>"` for existing knowledge
|
|
36
|
+
3. Read relevant SQUAD.md files
|
|
37
|
+
|
|
38
|
+
### During Work
|
|
39
|
+
- Update todo list frequently for visibility
|
|
40
|
+
- Prefer editing existing files over creating new ones
|
|
41
|
+
- Keep changes focused - one task per commit/PR
|
|
42
|
+
|
|
43
|
+
### After Work
|
|
44
|
+
- Update memory in `.agents/memory/<squad>/<agent>/state.md`
|
|
45
|
+
- Create GitHub issues for follow-up work
|
|
46
|
+
|
|
47
|
+
## Quick Reference
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
squads setup # Guided onboarding (new projects)
|
|
51
|
+
squads status # Overview
|
|
52
|
+
squads dash # Full dashboard
|
|
53
|
+
squads run <squad> # Run a squad
|
|
54
|
+
squads list # All agents
|
|
55
|
+
squads memory query X # Search memory
|
|
56
|
+
squads goal list # View goals
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Model Aliases
|
|
60
|
+
|
|
61
|
+
Agents can use semantic model names that resolve per provider:
|
|
62
|
+
- `leader` - Most capable (complex tasks)
|
|
63
|
+
- `worker` - Balanced (standard tasks)
|
|
64
|
+
- `simple` - Fast (simple tasks)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Business Brief
|
|
2
|
+
|
|
3
|
+
## #1 Priority
|
|
4
|
+
|
|
5
|
+
**[Define your top priority here]**
|
|
6
|
+
|
|
7
|
+
## Runway
|
|
8
|
+
|
|
9
|
+
**Pressure**: LOW | MEDIUM | HIGH
|
|
10
|
+
|
|
11
|
+
## Current Focus
|
|
12
|
+
|
|
13
|
+
1. **[Focus area 1]** - Description
|
|
14
|
+
2. **[Focus area 2]** - Description
|
|
15
|
+
3. **[Focus area 3]** - Description
|
|
16
|
+
|
|
17
|
+
## Blockers
|
|
18
|
+
|
|
19
|
+
- None currently (or list blockers)
|
|
20
|
+
|
|
21
|
+
## Decision Framework
|
|
22
|
+
|
|
23
|
+
1. Does this drive the #1 priority?
|
|
24
|
+
2. Is there a simpler approach?
|
|
25
|
+
3. What's the opportunity cost?
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
*This file is read by `squads context` to provide business alignment.*
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Claude-Specific Instructions
|
|
2
|
+
|
|
3
|
+
Extends AGENTS.md with Claude Code specific features.
|
|
4
|
+
|
|
5
|
+
## New Project Setup
|
|
6
|
+
|
|
7
|
+
If this project needs squads setup, run:
|
|
8
|
+
```bash
|
|
9
|
+
squads setup # Guided 6-step onboarding with prereq checks
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
This validates Docker, GitHub CLI, Claude CLI, then helps create first squad.
|
|
13
|
+
|
|
14
|
+
## Skill Available
|
|
15
|
+
|
|
16
|
+
Use `/squads-workflow` for detailed workflow guidance.
|
|
17
|
+
|
|
18
|
+
## Session Hooks
|
|
19
|
+
|
|
20
|
+
Claude Code hooks are configured in `.claude/settings.json`:
|
|
21
|
+
- **SessionStart**: Runs `squads status` automatically
|
|
22
|
+
- **Stop**: Syncs memory and prompts for learnings
|
|
23
|
+
|
|
24
|
+
## Creating Agents
|
|
25
|
+
|
|
26
|
+
Agents live in `.agents/squads/<squad-name>/<agent-name>.md`:
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
# Agent Name
|
|
30
|
+
|
|
31
|
+
## Purpose
|
|
32
|
+
One sentence: what this agent does.
|
|
33
|
+
|
|
34
|
+
## Model
|
|
35
|
+
simple # or: worker, leader
|
|
36
|
+
|
|
37
|
+
## Instructions
|
|
38
|
+
1. Specific step
|
|
39
|
+
2. Another step
|
|
40
|
+
3. Output location
|
|
41
|
+
|
|
42
|
+
## Output
|
|
43
|
+
What it produces and where it goes.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Commit Signature
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Co-Authored-By: Claude <model> <noreply@anthropic.com>
|
|
50
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# {{SQUAD_NAME}}
|
|
2
|
+
|
|
3
|
+
{{SQUAD_DESCRIPTION}}
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
|
|
7
|
+
- [ ] {{GOAL}}
|
|
8
|
+
|
|
9
|
+
## Agents
|
|
10
|
+
|
|
11
|
+
| Agent | Purpose |
|
|
12
|
+
|-------|---------|
|
|
13
|
+
| lead | Orchestrates the squad and coordinates work |
|
|
14
|
+
|
|
15
|
+
## Pipeline
|
|
16
|
+
|
|
17
|
+
`lead` (orchestrates all work)
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
squads run {{SQUAD_ID}} --execute
|
|
23
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Lead Agent
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Orchestrate the {{SQUAD_NAME}} squad to achieve its goals.
|
|
5
|
+
|
|
6
|
+
## Model
|
|
7
|
+
leader
|
|
8
|
+
|
|
9
|
+
## Tools
|
|
10
|
+
- Read
|
|
11
|
+
- Write
|
|
12
|
+
- Edit
|
|
13
|
+
- Bash
|
|
14
|
+
- WebSearch
|
|
15
|
+
- WebFetch
|
|
16
|
+
- Task
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
You are the lead agent for the {{SQUAD_NAME}} squad.
|
|
21
|
+
|
|
22
|
+
**Goal**: {{GOAL}}
|
|
23
|
+
|
|
24
|
+
### Approach
|
|
25
|
+
|
|
26
|
+
1. **Understand the goal** - Break down what needs to be accomplished
|
|
27
|
+
2. **Plan the work** - Create a clear execution plan
|
|
28
|
+
3. **Execute** - Work through the plan step by step
|
|
29
|
+
4. **Verify** - Confirm the goal is achieved
|
|
30
|
+
5. **Document** - Update memory with learnings
|
|
31
|
+
|
|
32
|
+
### Guidelines
|
|
33
|
+
|
|
34
|
+
- Use the Task tool to spawn sub-agents for complex, parallelizable work
|
|
35
|
+
- Check existing memory before researching: `squads memory query "<topic>"`
|
|
36
|
+
- Create GitHub issues for follow-up work
|
|
37
|
+
- Update `.agents/memory/{{SQUAD_ID}}/lead/state.md` with progress
|
|
38
|
+
|
|
39
|
+
## Output
|
|
40
|
+
Progress updates and work artifacts as appropriate.
|
|
41
|
+
|
|
42
|
+
## Labels
|
|
43
|
+
- lead
|
|
44
|
+
- orchestration
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Getting Started with Squads
|
|
2
|
+
|
|
3
|
+
## What You've Set Up
|
|
4
|
+
|
|
5
|
+
- **Your first squad** ready to run (`squads run {{SQUAD_ID}}`)
|
|
6
|
+
- **Memory system** for persistent context
|
|
7
|
+
- **Hooks** that sync status and memory automatically
|
|
8
|
+
|
|
9
|
+
## Next Steps
|
|
10
|
+
|
|
11
|
+
1. Run your squad: `squads run {{SQUAD_ID}} --execute`
|
|
12
|
+
2. Check the dashboard: `squads dash`
|
|
13
|
+
3. Create more squads in `.agents/squads/`
|
|
14
|
+
|
|
15
|
+
## Tips
|
|
16
|
+
|
|
17
|
+
- Check memory before researching: `squads memory query "<topic>"`
|
|
18
|
+
- Use `squads context` for business alignment on complex tasks
|
|
19
|
+
- Agents are reusable - if you do something twice, make it an agent
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: squads-learn
|
|
3
|
+
description: Capture learnings after completing work. Use when finishing a task, fixing a bug, discovering a pattern, or learning something worth remembering for future sessions. Helps build institutional memory.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Capture Learnings
|
|
7
|
+
|
|
8
|
+
After completing work, capture what you learned so future sessions can benefit.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- **After fixing a bug** - What was the root cause? How did you find it?
|
|
13
|
+
- **After completing a feature** - What approach worked? What didn't?
|
|
14
|
+
- **After research** - What did you discover? What's the key insight?
|
|
15
|
+
- **When you notice a pattern** - Something that works consistently
|
|
16
|
+
|
|
17
|
+
## How to Capture
|
|
18
|
+
|
|
19
|
+
### Quick Learning (one-liner)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
squads learn "The auth token needs to be refreshed after 1 hour, not when the API returns 401"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### With Context
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
squads learn "Always check memory before researching to avoid duplicate work" \
|
|
29
|
+
--squad engineering \
|
|
30
|
+
--category pattern \
|
|
31
|
+
--tags "memory,research,efficiency"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Categories
|
|
35
|
+
|
|
36
|
+
- `success` - Something that worked well
|
|
37
|
+
- `failure` - Something that didn't work (learn from mistakes)
|
|
38
|
+
- `pattern` - A reusable approach
|
|
39
|
+
- `tip` - General advice
|
|
40
|
+
|
|
41
|
+
## Workflow Integration
|
|
42
|
+
|
|
43
|
+
### End of Task
|
|
44
|
+
|
|
45
|
+
Before marking a task complete, ask yourself:
|
|
46
|
+
1. What worked that I should remember?
|
|
47
|
+
2. What didn't work that I should avoid?
|
|
48
|
+
3. Is there a pattern here worth capturing?
|
|
49
|
+
|
|
50
|
+
If yes to any → `squads learn "<insight>"`
|
|
51
|
+
|
|
52
|
+
### Before Similar Tasks
|
|
53
|
+
|
|
54
|
+
Check existing learnings:
|
|
55
|
+
```bash
|
|
56
|
+
squads learnings search "auth"
|
|
57
|
+
squads learnings show engineering --tag auth
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# After fixing a bug
|
|
64
|
+
squads learn "PostgreSQL connection pool exhaustion was caused by unclosed transactions in error paths" --category failure --tags db,postgres,connection
|
|
65
|
+
|
|
66
|
+
# After successful implementation
|
|
67
|
+
squads learn "Using TypeScript strict mode caught 3 type errors before runtime" --category success --tags typescript,types
|
|
68
|
+
|
|
69
|
+
# Noticing a pattern
|
|
70
|
+
squads learn "When context exceeds 70%, always run squads memory sync before continuing" --category pattern --tags context,memory
|
|
71
|
+
|
|
72
|
+
# General tip
|
|
73
|
+
squads learn "The gh CLI is faster than the GitHub API for simple operations" --category tip --tags github,cli
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## View Learnings
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
squads learnings show <squad> # Squad's learnings
|
|
80
|
+
squads learnings search "<query>" # Search all learnings
|
|
81
|
+
squads learnings show engineering -n 5 # Last 5 for engineering
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Key Principle
|
|
85
|
+
|
|
86
|
+
**Learnings compound.** Each captured insight makes future sessions smarter. A 30-second `squads learn` call can save hours of re-discovery.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Squads Workflow
|
|
2
|
+
|
|
3
|
+
Use this skill when working with squads-cli to maintain persistent memory, track goals, and coordinate work.
|
|
4
|
+
|
|
5
|
+
## Session Start
|
|
6
|
+
|
|
7
|
+
At session start, you'll see `squads status` output automatically. For complex tasks, run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
squads context # Get business context, goals, decisions
|
|
11
|
+
squads memory query "<topic>" # Check what we already know
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Skip context loading for simple tasks** (typo fixes, quick questions).
|
|
15
|
+
|
|
16
|
+
## Core Commands
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Context & Status
|
|
20
|
+
squads context # Business context for alignment
|
|
21
|
+
squads status # Squad overview
|
|
22
|
+
squads dash # Full dashboard
|
|
23
|
+
|
|
24
|
+
# Memory
|
|
25
|
+
squads memory query "<topic>" # Search memory
|
|
26
|
+
squads memory show <squad> # Squad's full memory
|
|
27
|
+
|
|
28
|
+
# Goals
|
|
29
|
+
squads goal list # All active goals
|
|
30
|
+
squads goal set <squad> "X" # Add a goal
|
|
31
|
+
|
|
32
|
+
# Running Agents
|
|
33
|
+
squads run <squad> # Run all agents in squad
|
|
34
|
+
squads run <squad>/<agent> # Run specific agent
|
|
35
|
+
squads list # List all agents
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Workflow
|
|
39
|
+
|
|
40
|
+
### Before Research
|
|
41
|
+
Always check memory first to avoid re-researching:
|
|
42
|
+
```bash
|
|
43
|
+
squads memory query "topic"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### After Work
|
|
47
|
+
Update memory with what you learned by editing:
|
|
48
|
+
`.agents/memory/<squad>/<agent>/state.md`
|
|
49
|
+
|
|
50
|
+
### Commits
|
|
51
|
+
Include goal attribution when relevant:
|
|
52
|
+
```
|
|
53
|
+
feat: add user auth [goal:engineering/1]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Agent Execution
|
|
57
|
+
|
|
58
|
+
When a task could be automated:
|
|
59
|
+
1. Check if agent exists: `squads list | grep <keyword>`
|
|
60
|
+
2. If yes: `squads run <squad>/<agent>`
|
|
61
|
+
3. If no: Create agent in `.agents/squads/<squad>/<name>.md`
|
|
62
|
+
|
|
63
|
+
## Memory Locations
|
|
64
|
+
|
|
65
|
+
- `.agents/memory/<squad>/<agent>/state.md` - Current knowledge
|
|
66
|
+
- `.agents/memory/<squad>/<agent>/learnings.md` - Insights over time
|
|
67
|
+
|
|
68
|
+
## Key Principle
|
|
69
|
+
|
|
70
|
+
**Memory is your cross-session brain.** Without it, every session starts fresh. With it, you build on previous work.
|
package/dist/chunk-FUHBEL3L.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
__require
|
|
4
|
-
} from "./chunk-7OCVIDC7.js";
|
|
5
|
-
|
|
6
|
-
// src/lib/memory.ts
|
|
7
|
-
import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "fs";
|
|
8
|
-
import { join, dirname } from "path";
|
|
9
|
-
function findMemoryDir() {
|
|
10
|
-
let dir = process.cwd();
|
|
11
|
-
for (let i = 0; i < 5; i++) {
|
|
12
|
-
const memoryPath = join(dir, ".agents", "memory");
|
|
13
|
-
if (existsSync(memoryPath)) {
|
|
14
|
-
return memoryPath;
|
|
15
|
-
}
|
|
16
|
-
const parent = join(dir, "..");
|
|
17
|
-
if (parent === dir) break;
|
|
18
|
-
dir = parent;
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
function listMemoryEntries(memoryDir) {
|
|
23
|
-
const entries = [];
|
|
24
|
-
const squads = readdirSync(memoryDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
25
|
-
for (const squad of squads) {
|
|
26
|
-
const squadPath = join(memoryDir, squad);
|
|
27
|
-
const agents = readdirSync(squadPath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
28
|
-
for (const agent of agents) {
|
|
29
|
-
const agentPath = join(squadPath, agent);
|
|
30
|
-
const files = readdirSync(agentPath).filter((f) => f.endsWith(".md"));
|
|
31
|
-
for (const file of files) {
|
|
32
|
-
const filePath = join(agentPath, file);
|
|
33
|
-
const type = file.replace(".md", "");
|
|
34
|
-
entries.push({
|
|
35
|
-
squad,
|
|
36
|
-
agent,
|
|
37
|
-
type,
|
|
38
|
-
content: readFileSync(filePath, "utf-8"),
|
|
39
|
-
path: filePath
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return entries;
|
|
45
|
-
}
|
|
46
|
-
var SEMANTIC_EXPANSIONS = {
|
|
47
|
-
"pricing": ["price", "cost", "$", "revenue", "fee", "rate"],
|
|
48
|
-
"price": ["pricing", "cost", "$", "fee"],
|
|
49
|
-
"revenue": ["income", "sales", "mrr", "arr", "$"],
|
|
50
|
-
"cost": ["expense", "spend", "budget", "$", "price"],
|
|
51
|
-
"customer": ["client", "lead", "prospect", "user"],
|
|
52
|
-
"client": ["customer", "lead", "prospect"],
|
|
53
|
-
"lead": ["prospect", "customer", "client", "pipeline"],
|
|
54
|
-
"agent": ["squad", "bot", "ai"],
|
|
55
|
-
"squad": ["team", "agent", "group"],
|
|
56
|
-
"status": ["state", "progress", "health"],
|
|
57
|
-
"bug": ["issue", "error", "problem", "fix"],
|
|
58
|
-
"feature": ["capability", "function", "ability"]
|
|
59
|
-
};
|
|
60
|
-
function expandQuery(query) {
|
|
61
|
-
const words = query.toLowerCase().split(/\s+/);
|
|
62
|
-
const expanded = new Set(words);
|
|
63
|
-
for (const word of words) {
|
|
64
|
-
if (SEMANTIC_EXPANSIONS[word]) {
|
|
65
|
-
SEMANTIC_EXPANSIONS[word].forEach((syn) => expanded.add(syn));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return Array.from(expanded);
|
|
69
|
-
}
|
|
70
|
-
function getFileAge(filePath) {
|
|
71
|
-
try {
|
|
72
|
-
const { statSync } = __require("fs");
|
|
73
|
-
const stats = statSync(filePath);
|
|
74
|
-
const ageMs = Date.now() - stats.mtimeMs;
|
|
75
|
-
const ageDays = ageMs / (1e3 * 60 * 60 * 24);
|
|
76
|
-
return ageDays;
|
|
77
|
-
} catch {
|
|
78
|
-
return 999;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function searchMemory(query, memoryDir) {
|
|
82
|
-
const dir = memoryDir || findMemoryDir();
|
|
83
|
-
if (!dir) return [];
|
|
84
|
-
const entries = listMemoryEntries(dir);
|
|
85
|
-
const results = [];
|
|
86
|
-
const queryLower = query.toLowerCase();
|
|
87
|
-
const expandedTerms = expandQuery(queryLower);
|
|
88
|
-
for (const entry of entries) {
|
|
89
|
-
const contentLower = entry.content.toLowerCase();
|
|
90
|
-
const lines = entry.content.split("\n");
|
|
91
|
-
const matches = [];
|
|
92
|
-
let score = 0;
|
|
93
|
-
let directHits = 0;
|
|
94
|
-
let expandedHits = 0;
|
|
95
|
-
const directWords = queryLower.split(/\s+/);
|
|
96
|
-
for (const word of directWords) {
|
|
97
|
-
if (contentLower.includes(word)) {
|
|
98
|
-
directHits += 1;
|
|
99
|
-
score += 2;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
for (const term of expandedTerms) {
|
|
103
|
-
if (contentLower.includes(term)) {
|
|
104
|
-
expandedHits += 1;
|
|
105
|
-
score += 0.5;
|
|
106
|
-
for (let i = 0; i < lines.length; i++) {
|
|
107
|
-
const line = lines[i];
|
|
108
|
-
if (line.toLowerCase().includes(term) && line.trim() && !matches.includes(line.trim())) {
|
|
109
|
-
matches.push(line.trim());
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (contentLower.includes(queryLower)) {
|
|
115
|
-
score += 5;
|
|
116
|
-
}
|
|
117
|
-
const ageDays = getFileAge(entry.path);
|
|
118
|
-
if (ageDays < 1) {
|
|
119
|
-
score *= 1.5;
|
|
120
|
-
} else if (ageDays < 7) {
|
|
121
|
-
score *= 1.2;
|
|
122
|
-
} else if (ageDays > 30) {
|
|
123
|
-
score *= 0.8;
|
|
124
|
-
}
|
|
125
|
-
const typeWeights = {
|
|
126
|
-
"state": 1.2,
|
|
127
|
-
// Current state slightly preferred
|
|
128
|
-
"learnings": 1.1,
|
|
129
|
-
// Learnings are valuable
|
|
130
|
-
"output": 1,
|
|
131
|
-
// Recent outputs
|
|
132
|
-
"feedback": 0.9
|
|
133
|
-
// Feedback less commonly needed
|
|
134
|
-
};
|
|
135
|
-
score *= typeWeights[entry.type] || 1;
|
|
136
|
-
if (score > 0 && (directHits > 0 || expandedHits > 1)) {
|
|
137
|
-
results.push({ entry, matches: matches.slice(0, 7), score });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return results.sort((a, b) => b.score - a.score);
|
|
141
|
-
}
|
|
142
|
-
function getSquadState(squadName) {
|
|
143
|
-
const memoryDir = findMemoryDir();
|
|
144
|
-
if (!memoryDir) return [];
|
|
145
|
-
const squadPath = join(memoryDir, squadName);
|
|
146
|
-
if (!existsSync(squadPath)) return [];
|
|
147
|
-
const entries = [];
|
|
148
|
-
const agents = readdirSync(squadPath, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
149
|
-
for (const agent of agents) {
|
|
150
|
-
const statePath = join(squadPath, agent, "state.md");
|
|
151
|
-
if (existsSync(statePath)) {
|
|
152
|
-
entries.push({
|
|
153
|
-
squad: squadName,
|
|
154
|
-
agent,
|
|
155
|
-
type: "state",
|
|
156
|
-
content: readFileSync(statePath, "utf-8"),
|
|
157
|
-
path: statePath
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return entries;
|
|
162
|
-
}
|
|
163
|
-
function updateMemory(squadName, agentName, type, content) {
|
|
164
|
-
const memoryDir = findMemoryDir();
|
|
165
|
-
if (!memoryDir) {
|
|
166
|
-
throw new Error("No .agents/memory directory found");
|
|
167
|
-
}
|
|
168
|
-
const filePath = join(memoryDir, squadName, agentName, `${type}.md`);
|
|
169
|
-
const dir = dirname(filePath);
|
|
170
|
-
if (!existsSync(dir)) {
|
|
171
|
-
mkdirSync(dir, { recursive: true });
|
|
172
|
-
}
|
|
173
|
-
writeFileSync(filePath, content);
|
|
174
|
-
}
|
|
175
|
-
function appendToMemory(squadName, agentName, type, addition) {
|
|
176
|
-
const memoryDir = findMemoryDir();
|
|
177
|
-
if (!memoryDir) {
|
|
178
|
-
throw new Error("No .agents/memory directory found");
|
|
179
|
-
}
|
|
180
|
-
const filePath = join(memoryDir, squadName, agentName, `${type}.md`);
|
|
181
|
-
let existing = "";
|
|
182
|
-
if (existsSync(filePath)) {
|
|
183
|
-
existing = readFileSync(filePath, "utf-8");
|
|
184
|
-
}
|
|
185
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
186
|
-
const newContent = existing + `
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
_Added: ${timestamp}_
|
|
190
|
-
|
|
191
|
-
${addition}`;
|
|
192
|
-
updateMemory(squadName, agentName, type, newContent.trim());
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export {
|
|
196
|
-
findMemoryDir,
|
|
197
|
-
listMemoryEntries,
|
|
198
|
-
searchMemory,
|
|
199
|
-
getSquadState,
|
|
200
|
-
updateMemory,
|
|
201
|
-
appendToMemory
|
|
202
|
-
};
|
|
203
|
-
//# sourceMappingURL=chunk-FUHBEL3L.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/memory.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from 'fs';\nimport { join, dirname } from 'path';\n\nexport interface MemoryEntry {\n squad: string;\n agent: string;\n type: 'state' | 'output' | 'learnings' | 'feedback';\n content: string;\n path: string;\n lastUpdated?: string;\n}\n\nexport interface SearchResult {\n entry: MemoryEntry;\n matches: string[];\n score: number;\n}\n\nexport function findMemoryDir(): string | null {\n let dir = process.cwd();\n\n for (let i = 0; i < 5; i++) {\n const memoryPath = join(dir, '.agents', 'memory');\n if (existsSync(memoryPath)) {\n return memoryPath;\n }\n const parent = join(dir, '..');\n if (parent === dir) break;\n dir = parent;\n }\n\n return null;\n}\n\nexport function listMemoryEntries(memoryDir: string): MemoryEntry[] {\n const entries: MemoryEntry[] = [];\n\n const squads = readdirSync(memoryDir, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const squad of squads) {\n const squadPath = join(memoryDir, squad);\n const agents = readdirSync(squadPath, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const agent of agents) {\n const agentPath = join(squadPath, agent);\n const files = readdirSync(agentPath).filter(f => f.endsWith('.md'));\n\n for (const file of files) {\n const filePath = join(agentPath, file);\n const type = file.replace('.md', '') as MemoryEntry['type'];\n\n entries.push({\n squad,\n agent,\n type,\n content: readFileSync(filePath, 'utf-8'),\n path: filePath\n });\n }\n }\n }\n\n return entries;\n}\n\n// Semantic expansions for common business terms\nconst SEMANTIC_EXPANSIONS: Record<string, string[]> = {\n 'pricing': ['price', 'cost', '$', 'revenue', 'fee', 'rate'],\n 'price': ['pricing', 'cost', '$', 'fee'],\n 'revenue': ['income', 'sales', 'mrr', 'arr', '$'],\n 'cost': ['expense', 'spend', 'budget', '$', 'price'],\n 'customer': ['client', 'lead', 'prospect', 'user'],\n 'client': ['customer', 'lead', 'prospect'],\n 'lead': ['prospect', 'customer', 'client', 'pipeline'],\n 'agent': ['squad', 'bot', 'ai'],\n 'squad': ['team', 'agent', 'group'],\n 'status': ['state', 'progress', 'health'],\n 'bug': ['issue', 'error', 'problem', 'fix'],\n 'feature': ['capability', 'function', 'ability'],\n};\n\nfunction expandQuery(query: string): string[] {\n const words = query.toLowerCase().split(/\\s+/);\n const expanded = new Set(words);\n\n for (const word of words) {\n if (SEMANTIC_EXPANSIONS[word]) {\n SEMANTIC_EXPANSIONS[word].forEach(syn => expanded.add(syn));\n }\n }\n\n return Array.from(expanded);\n}\n\nfunction getFileAge(filePath: string): number {\n try {\n const { statSync } = require('fs');\n const stats = statSync(filePath);\n const ageMs = Date.now() - stats.mtimeMs;\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n return ageDays;\n } catch {\n return 999;\n }\n}\n\nexport function searchMemory(query: string, memoryDir?: string): SearchResult[] {\n const dir = memoryDir || findMemoryDir();\n if (!dir) return [];\n\n const entries = listMemoryEntries(dir);\n const results: SearchResult[] = [];\n const queryLower = query.toLowerCase();\n const expandedTerms = expandQuery(queryLower);\n\n for (const entry of entries) {\n const contentLower = entry.content.toLowerCase();\n const lines = entry.content.split('\\n');\n const matches: string[] = [];\n let score = 0;\n let directHits = 0;\n let expandedHits = 0;\n\n // Check direct query words first\n const directWords = queryLower.split(/\\s+/);\n for (const word of directWords) {\n if (contentLower.includes(word)) {\n directHits += 1;\n score += 2; // Direct matches worth more\n }\n }\n\n // Check expanded terms\n for (const term of expandedTerms) {\n if (contentLower.includes(term)) {\n expandedHits += 1;\n score += 0.5; // Expanded matches worth less but still count\n\n // Find matching lines with context\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.toLowerCase().includes(term) && line.trim() && !matches.includes(line.trim())) {\n matches.push(line.trim());\n }\n }\n }\n }\n\n // Boost score for exact phrase match\n if (contentLower.includes(queryLower)) {\n score += 5;\n }\n\n // Recency boost - files updated recently are more relevant\n const ageDays = getFileAge(entry.path);\n if (ageDays < 1) {\n score *= 1.5; // Updated today\n } else if (ageDays < 7) {\n score *= 1.2; // Updated this week\n } else if (ageDays > 30) {\n score *= 0.8; // Stale data penalty\n }\n\n // Type weighting - balanced across types\n const typeWeights: Record<string, number> = {\n 'state': 1.2, // Current state slightly preferred\n 'learnings': 1.1, // Learnings are valuable\n 'output': 1.0, // Recent outputs\n 'feedback': 0.9, // Feedback less commonly needed\n };\n score *= typeWeights[entry.type] || 1.0;\n\n if (score > 0 && (directHits > 0 || expandedHits > 1)) {\n results.push({ entry, matches: matches.slice(0, 7), score });\n }\n }\n\n // Sort by score descending\n return results.sort((a, b) => b.score - a.score);\n}\n\nexport function getSquadState(squadName: string): MemoryEntry[] {\n const memoryDir = findMemoryDir();\n if (!memoryDir) return [];\n\n const squadPath = join(memoryDir, squadName);\n if (!existsSync(squadPath)) return [];\n\n const entries: MemoryEntry[] = [];\n const agents = readdirSync(squadPath, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .map(e => e.name);\n\n for (const agent of agents) {\n const statePath = join(squadPath, agent, 'state.md');\n if (existsSync(statePath)) {\n entries.push({\n squad: squadName,\n agent,\n type: 'state',\n content: readFileSync(statePath, 'utf-8'),\n path: statePath\n });\n }\n }\n\n return entries;\n}\n\nexport function updateMemory(\n squadName: string,\n agentName: string,\n type: MemoryEntry['type'],\n content: string\n): void {\n const memoryDir = findMemoryDir();\n if (!memoryDir) {\n throw new Error('No .agents/memory directory found');\n }\n\n const filePath = join(memoryDir, squadName, agentName, `${type}.md`);\n const dir = dirname(filePath);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n writeFileSync(filePath, content);\n}\n\nexport function appendToMemory(\n squadName: string,\n agentName: string,\n type: MemoryEntry['type'],\n addition: string\n): void {\n const memoryDir = findMemoryDir();\n if (!memoryDir) {\n throw new Error('No .agents/memory directory found');\n }\n\n const filePath = join(memoryDir, squadName, agentName, `${type}.md`);\n\n let existing = '';\n if (existsSync(filePath)) {\n existing = readFileSync(filePath, 'utf-8');\n }\n\n const timestamp = new Date().toISOString().split('T')[0];\n const newContent = existing + `\\n\\n---\\n_Added: ${timestamp}_\\n\\n${addition}`;\n\n updateMemory(squadName, agentName, type, newContent.trim());\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|