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.
Files changed (42) hide show
  1. package/README.md +24 -4
  2. package/dist/{chunk-HIQ2APYR.js → chunk-7PRYDHZW.js} +2 -2
  3. package/dist/chunk-BV6S5AWZ.js +419 -0
  4. package/dist/chunk-BV6S5AWZ.js.map +1 -0
  5. package/dist/chunk-QPH5OR7J.js +474 -0
  6. package/dist/chunk-QPH5OR7J.js.map +1 -0
  7. package/dist/cli.js +8031 -3620
  8. package/dist/cli.js.map +1 -1
  9. package/dist/index.d.ts +54 -0
  10. package/dist/index.js +8 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/{memory-4PVUKIDK.js → memory-ZXDXF6KF.js} +8 -4
  13. package/dist/{sessions-R4VWIGFR.js → sessions-F6LRY7EN.js} +2 -2
  14. package/dist/squad-parser-MSYE4PXL.js +31 -0
  15. package/dist/squad-parser-MSYE4PXL.js.map +1 -0
  16. package/dist/templates/core/AGENTS.md.template +64 -0
  17. package/dist/templates/core/BUSINESS_BRIEF.md.template +29 -0
  18. package/dist/templates/core/CLAUDE.md.template +50 -0
  19. package/dist/templates/core/provider.yaml.template +5 -0
  20. package/dist/templates/first-squad/SQUAD.md.template +23 -0
  21. package/dist/templates/first-squad/lead.md.template +44 -0
  22. package/dist/templates/memory/getting-started/state.md.template +19 -0
  23. package/dist/templates/skills/squads-learn/SKILL.md +86 -0
  24. package/dist/templates/skills/squads-workflow/instruction.md +70 -0
  25. package/docker/docker-compose.engram.yml +26 -0
  26. package/docker/docker-compose.yml +132 -76
  27. package/docker/squads-bridge/squads_bridge.py +534 -8
  28. package/package.json +15 -9
  29. package/templates/core/AGENTS.md.template +64 -0
  30. package/templates/core/BUSINESS_BRIEF.md.template +29 -0
  31. package/templates/core/CLAUDE.md.template +50 -0
  32. package/templates/core/provider.yaml.template +5 -0
  33. package/templates/first-squad/SQUAD.md.template +23 -0
  34. package/templates/first-squad/lead.md.template +44 -0
  35. package/templates/memory/getting-started/state.md.template +19 -0
  36. package/templates/skills/squads-learn/SKILL.md +86 -0
  37. package/templates/skills/squads-workflow/instruction.md +70 -0
  38. package/dist/chunk-FUHBEL3L.js +0 -203
  39. package/dist/chunk-FUHBEL3L.js.map +0 -1
  40. /package/dist/{chunk-HIQ2APYR.js.map → chunk-7PRYDHZW.js.map} +0 -0
  41. /package/dist/{memory-4PVUKIDK.js.map → memory-ZXDXF6KF.js.map} +0 -0
  42. /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,5 @@
1
+ # Squads Provider Configuration
2
+ # Selected during: squads init
3
+ # Change with: squads init --provider <name>
4
+
5
+ provider: {{PROVIDER}}
@@ -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.
@@ -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":[]}