squads-cli 0.2.0 → 0.2.1
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 +521 -288
- package/dist/auth-YW3UPFSB.js +23 -0
- package/dist/auth-YW3UPFSB.js.map +1 -0
- package/dist/autonomy-PSVZVX7A.js +105 -0
- package/dist/autonomy-PSVZVX7A.js.map +1 -0
- package/dist/chunk-67RO2HKR.js +174 -0
- package/dist/chunk-67RO2HKR.js.map +1 -0
- package/dist/chunk-7OCVIDC7.js +12 -0
- package/dist/chunk-7OCVIDC7.js.map +1 -0
- package/dist/chunk-BODLDQY7.js +452 -0
- package/dist/chunk-BODLDQY7.js.map +1 -0
- package/dist/chunk-EHQJHRIW.js +103 -0
- package/dist/chunk-EHQJHRIW.js.map +1 -0
- package/dist/chunk-FFFCFZ6A.js +121 -0
- package/dist/chunk-FFFCFZ6A.js.map +1 -0
- package/dist/chunk-FIWT2NMM.js +165 -0
- package/dist/chunk-FIWT2NMM.js.map +1 -0
- package/dist/chunk-HF4WR7RA.js +154 -0
- package/dist/chunk-HF4WR7RA.js.map +1 -0
- package/dist/chunk-J6QF4ZQX.js +230 -0
- package/dist/chunk-J6QF4ZQX.js.map +1 -0
- package/dist/chunk-LOA3KWYJ.js +294 -0
- package/dist/chunk-LOA3KWYJ.js.map +1 -0
- package/dist/chunk-M5FXNY6Y.js +384 -0
- package/dist/chunk-M5FXNY6Y.js.map +1 -0
- package/dist/chunk-QHNUMM4V.js +87 -0
- package/dist/chunk-QHNUMM4V.js.map +1 -0
- package/dist/chunk-QJ7C7CMB.js +223 -0
- package/dist/chunk-QJ7C7CMB.js.map +1 -0
- package/dist/chunk-RM6BWILN.js +74 -0
- package/dist/chunk-RM6BWILN.js.map +1 -0
- package/dist/chunk-TYFTF53O.js +613 -0
- package/dist/chunk-TYFTF53O.js.map +1 -0
- package/dist/chunk-TZXD6WFN.js +420 -0
- package/dist/chunk-TZXD6WFN.js.map +1 -0
- package/dist/chunk-WVOIY5GW.js +621 -0
- package/dist/chunk-WVOIY5GW.js.map +1 -0
- package/dist/chunk-Z2UKDBNL.js +162 -0
- package/dist/chunk-Z2UKDBNL.js.map +1 -0
- package/dist/chunk-ZTQ7ISUR.js +338 -0
- package/dist/chunk-ZTQ7ISUR.js.map +1 -0
- package/dist/cli.js +2483 -5902
- package/dist/cli.js.map +1 -1
- package/dist/context-GWPF4SEY.js +291 -0
- package/dist/context-GWPF4SEY.js.map +1 -0
- package/dist/context-feed-AJGVAR6H.js +394 -0
- package/dist/context-feed-AJGVAR6H.js.map +1 -0
- package/dist/cost-XBCDJ7XC.js +275 -0
- package/dist/cost-XBCDJ7XC.js.map +1 -0
- package/dist/create-BLFGG6PF.js +286 -0
- package/dist/create-BLFGG6PF.js.map +1 -0
- package/dist/dashboard-LGT2B2BL.js +951 -0
- package/dist/dashboard-LGT2B2BL.js.map +1 -0
- package/dist/dashboard-RMK2BOD2.js +794 -0
- package/dist/dashboard-RMK2BOD2.js.map +1 -0
- package/dist/doctor-XPUIIBHJ.js +374 -0
- package/dist/doctor-XPUIIBHJ.js.map +1 -0
- package/dist/env-config-SQEI3Y7Y.js +21 -0
- package/dist/env-config-SQEI3Y7Y.js.map +1 -0
- package/dist/exec-OUXM7JBF.js +223 -0
- package/dist/exec-OUXM7JBF.js.map +1 -0
- package/dist/feedback-KNAOG5QK.js +229 -0
- package/dist/feedback-KNAOG5QK.js.map +1 -0
- package/dist/github-UQTM5KMS.js +23 -0
- package/dist/github-UQTM5KMS.js.map +1 -0
- package/dist/goal-BVHV5573.js +168 -0
- package/dist/goal-BVHV5573.js.map +1 -0
- package/dist/health-4UXN44PF.js +218 -0
- package/dist/health-4UXN44PF.js.map +1 -0
- package/dist/history-ILH3SWHB.js +232 -0
- package/dist/history-ILH3SWHB.js.map +1 -0
- package/dist/index.d.ts +736 -8
- package/dist/index.js +1312 -6
- package/dist/index.js.map +1 -1
- package/dist/init-XQZ7BOGT.js +812 -0
- package/dist/init-XQZ7BOGT.js.map +1 -0
- package/dist/kpi-RQIU7WGK.js +413 -0
- package/dist/kpi-RQIU7WGK.js.map +1 -0
- package/dist/learn-OIFUVZAS.js +269 -0
- package/dist/learn-OIFUVZAS.js.map +1 -0
- package/dist/login-DXZANWZY.js +155 -0
- package/dist/login-DXZANWZY.js.map +1 -0
- package/dist/memory-T3ACCS7E.js +560 -0
- package/dist/memory-T3ACCS7E.js.map +1 -0
- package/dist/memory-VNF2VFRB.js +23 -0
- package/dist/memory-VNF2VFRB.js.map +1 -0
- package/dist/progress-DAUZMT3N.js +202 -0
- package/dist/progress-DAUZMT3N.js.map +1 -0
- package/dist/providers-3P5D2XL5.js +65 -0
- package/dist/providers-3P5D2XL5.js.map +1 -0
- package/dist/results-UECWGLTB.js +224 -0
- package/dist/results-UECWGLTB.js.map +1 -0
- package/dist/run-I6KAXU6U.js +4049 -0
- package/dist/run-I6KAXU6U.js.map +1 -0
- package/dist/session-HBU6KZOD.js +64 -0
- package/dist/session-HBU6KZOD.js.map +1 -0
- package/dist/sessions-CK25VGPL.js +333 -0
- package/dist/sessions-CK25VGPL.js.map +1 -0
- package/dist/squad-parser-DCG65BJS.js +35 -0
- package/dist/squad-parser-DCG65BJS.js.map +1 -0
- package/dist/stats-G6NAU5BD.js +334 -0
- package/dist/stats-G6NAU5BD.js.map +1 -0
- package/dist/status-AQNLDZVN.js +352 -0
- package/dist/status-AQNLDZVN.js.map +1 -0
- package/dist/sync-ZI3MHA4G.js +836 -0
- package/dist/sync-ZI3MHA4G.js.map +1 -0
- package/dist/templates/core/AGENTS.md.template +51 -0
- package/dist/templates/core/BUSINESS_BRIEF.md.template +29 -0
- package/dist/templates/core/CLAUDE.md.template +48 -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/seed/BUSINESS_BRIEF.md.template +27 -0
- package/dist/templates/seed/CLAUDE.md.template +119 -0
- package/dist/templates/seed/README.md.template +42 -0
- package/dist/templates/seed/config/SYSTEM.md +52 -0
- package/dist/templates/seed/config/provider.yaml +4 -0
- package/dist/templates/seed/hooks/settings.json.template +31 -0
- package/dist/templates/seed/memory/company/directives.md +37 -0
- package/dist/templates/seed/memory/company/manager/state.md +16 -0
- package/dist/templates/seed/memory/engineering/issue-solver/state.md +12 -0
- package/dist/templates/seed/memory/intelligence/intel-lead/state.md +9 -0
- package/dist/templates/seed/memory/marketing/content-drafter/state.md +12 -0
- package/dist/templates/seed/memory/operations/ops-lead/state.md +12 -0
- package/dist/templates/seed/memory/product/lead/state.md +14 -0
- package/dist/templates/seed/memory/research/lead/state.md +14 -0
- package/dist/templates/seed/skills/gh/SKILL.md +57 -0
- package/dist/templates/seed/skills/squads-cli/SKILL.md +84 -0
- package/dist/templates/seed/squads/company/SQUAD.md +51 -0
- package/dist/templates/seed/squads/company/company-critic.md +49 -0
- package/dist/templates/seed/squads/company/company-eval.md +49 -0
- package/dist/templates/seed/squads/company/event-dispatcher.md +43 -0
- package/dist/templates/seed/squads/company/goal-tracker.md +43 -0
- package/dist/templates/seed/squads/company/manager.md +54 -0
- package/dist/templates/seed/squads/engineering/SQUAD.md +48 -0
- package/dist/templates/seed/squads/engineering/code-reviewer.md +57 -0
- package/dist/templates/seed/squads/engineering/issue-solver.md +58 -0
- package/dist/templates/seed/squads/engineering/test-writer.md +50 -0
- package/dist/templates/seed/squads/intelligence/SQUAD.md +38 -0
- package/dist/templates/seed/squads/intelligence/intel-critic.md +36 -0
- package/dist/templates/seed/squads/intelligence/intel-eval.md +31 -0
- package/dist/templates/seed/squads/intelligence/intel-lead.md +71 -0
- package/dist/templates/seed/squads/marketing/SQUAD.md +47 -0
- package/dist/templates/seed/squads/marketing/content-drafter.md +71 -0
- package/dist/templates/seed/squads/marketing/growth-analyst.md +49 -0
- package/dist/templates/seed/squads/marketing/social-poster.md +44 -0
- package/dist/templates/seed/squads/operations/SQUAD.md +45 -0
- package/dist/templates/seed/squads/operations/finance-tracker.md +47 -0
- package/dist/templates/seed/squads/operations/goal-tracker.md +48 -0
- package/dist/templates/seed/squads/operations/ops-lead.md +58 -0
- package/dist/templates/seed/squads/product/SQUAD.md +41 -0
- package/dist/templates/seed/squads/product/lead.md +56 -0
- package/dist/templates/seed/squads/product/scanner.md +50 -0
- package/dist/templates/seed/squads/product/worker.md +55 -0
- package/dist/templates/seed/squads/research/SQUAD.md +38 -0
- package/dist/templates/seed/squads/research/analyst.md +50 -0
- package/dist/templates/seed/squads/research/lead.md +52 -0
- package/dist/templates/seed/squads/research/synthesizer.md +59 -0
- package/dist/templates/skills/squads-learn/SKILL.md +86 -0
- package/dist/templates/skills/squads-workflow/instruction.md +70 -0
- package/dist/terminal-FBQFQTKZ.js +55 -0
- package/dist/terminal-FBQFQTKZ.js.map +1 -0
- package/dist/update-D7CGIZ3M.js +18 -0
- package/dist/update-D7CGIZ3M.js.map +1 -0
- package/dist/update-STU276HR.js +83 -0
- package/dist/update-STU276HR.js.map +1 -0
- package/package.json +31 -13
- package/templates/core/AGENTS.md.template +51 -0
- package/templates/core/BUSINESS_BRIEF.md.template +29 -0
- package/templates/core/CLAUDE.md.template +48 -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/seed/BUSINESS_BRIEF.md.template +27 -0
- package/templates/seed/CLAUDE.md.template +119 -0
- package/templates/seed/README.md.template +42 -0
- package/templates/seed/config/SYSTEM.md +52 -0
- package/templates/seed/config/provider.yaml +4 -0
- package/templates/seed/hooks/settings.json.template +31 -0
- package/templates/seed/memory/company/directives.md +37 -0
- package/templates/seed/memory/company/manager/state.md +16 -0
- package/templates/seed/memory/engineering/issue-solver/state.md +12 -0
- package/templates/seed/memory/intelligence/intel-lead/state.md +9 -0
- package/templates/seed/memory/marketing/content-drafter/state.md +12 -0
- package/templates/seed/memory/operations/ops-lead/state.md +12 -0
- package/templates/seed/memory/product/lead/state.md +14 -0
- package/templates/seed/memory/research/lead/state.md +14 -0
- package/templates/seed/skills/gh/SKILL.md +57 -0
- package/templates/seed/skills/squads-cli/SKILL.md +84 -0
- package/templates/seed/squads/company/SQUAD.md +51 -0
- package/templates/seed/squads/company/company-critic.md +49 -0
- package/templates/seed/squads/company/company-eval.md +49 -0
- package/templates/seed/squads/company/event-dispatcher.md +43 -0
- package/templates/seed/squads/company/goal-tracker.md +43 -0
- package/templates/seed/squads/company/manager.md +54 -0
- package/templates/seed/squads/engineering/SQUAD.md +48 -0
- package/templates/seed/squads/engineering/code-reviewer.md +57 -0
- package/templates/seed/squads/engineering/issue-solver.md +58 -0
- package/templates/seed/squads/engineering/test-writer.md +50 -0
- package/templates/seed/squads/intelligence/SQUAD.md +38 -0
- package/templates/seed/squads/intelligence/intel-critic.md +36 -0
- package/templates/seed/squads/intelligence/intel-eval.md +31 -0
- package/templates/seed/squads/intelligence/intel-lead.md +71 -0
- package/templates/seed/squads/marketing/SQUAD.md +47 -0
- package/templates/seed/squads/marketing/content-drafter.md +71 -0
- package/templates/seed/squads/marketing/growth-analyst.md +49 -0
- package/templates/seed/squads/marketing/social-poster.md +44 -0
- package/templates/seed/squads/operations/SQUAD.md +45 -0
- package/templates/seed/squads/operations/finance-tracker.md +47 -0
- package/templates/seed/squads/operations/goal-tracker.md +48 -0
- package/templates/seed/squads/operations/ops-lead.md +58 -0
- package/templates/seed/squads/product/SQUAD.md +41 -0
- package/templates/seed/squads/product/lead.md +56 -0
- package/templates/seed/squads/product/scanner.md +50 -0
- package/templates/seed/squads/product/worker.md +55 -0
- package/templates/seed/squads/research/SQUAD.md +38 -0
- package/templates/seed/squads/research/analyst.md +50 -0
- package/templates/seed/squads/research/lead.md +52 -0
- package/templates/seed/squads/research/synthesizer.md +59 -0
- package/templates/skills/squads-learn/SKILL.md +86 -0
- package/templates/skills/squads-workflow/instruction.md +70 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getEnv
|
|
4
|
+
} from "./chunk-EHQJHRIW.js";
|
|
5
|
+
import {
|
|
6
|
+
Events,
|
|
7
|
+
track
|
|
8
|
+
} from "./chunk-QJ7C7CMB.js";
|
|
9
|
+
import {
|
|
10
|
+
appendToMemory,
|
|
11
|
+
findMemoryDir,
|
|
12
|
+
getSquadState,
|
|
13
|
+
listMemoryEntries,
|
|
14
|
+
searchMemory
|
|
15
|
+
} from "./chunk-ZTQ7ISUR.js";
|
|
16
|
+
import {
|
|
17
|
+
RESET,
|
|
18
|
+
bold,
|
|
19
|
+
box,
|
|
20
|
+
colors,
|
|
21
|
+
gradient,
|
|
22
|
+
icons,
|
|
23
|
+
padEnd,
|
|
24
|
+
truncate,
|
|
25
|
+
writeLine
|
|
26
|
+
} from "./chunk-M5FXNY6Y.js";
|
|
27
|
+
import "./chunk-7OCVIDC7.js";
|
|
28
|
+
|
|
29
|
+
// src/lib/services.ts
|
|
30
|
+
function buildServices() {
|
|
31
|
+
const env = getEnv();
|
|
32
|
+
return {
|
|
33
|
+
bridge: {
|
|
34
|
+
name: "API",
|
|
35
|
+
description: "Optional: captures conversations and telemetry",
|
|
36
|
+
required: false,
|
|
37
|
+
getHealthUrl: () => env.bridge_url ? `${env.bridge_url}/health` : "",
|
|
38
|
+
envVars: ["SQUADS_BRIDGE_URL"],
|
|
39
|
+
setupGuide: [
|
|
40
|
+
"Not required for basic usage (init, run, status, eval).",
|
|
41
|
+
"To enable telemetry, authenticate:",
|
|
42
|
+
" squads login"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
postgres: {
|
|
46
|
+
name: "Database",
|
|
47
|
+
description: "Optional: enables scheduling, telemetry, and persistent storage",
|
|
48
|
+
required: false,
|
|
49
|
+
getHealthUrl: () => "",
|
|
50
|
+
envVars: ["SQUADS_DATABASE_URL"],
|
|
51
|
+
setupGuide: [
|
|
52
|
+
"Not required for basic usage (init, run, status, eval).",
|
|
53
|
+
"Available with a Squads account:",
|
|
54
|
+
" squads login"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
mem0: {
|
|
58
|
+
name: "Memory Service",
|
|
59
|
+
description: "Memory extraction and search",
|
|
60
|
+
required: false,
|
|
61
|
+
getHealthUrl: () => {
|
|
62
|
+
const url = process.env.MEM0_API_URL;
|
|
63
|
+
return url ? `${url}/health` : "";
|
|
64
|
+
},
|
|
65
|
+
envVars: ["MEM0_API_URL"],
|
|
66
|
+
setupGuide: [
|
|
67
|
+
"Memory extraction requires the memory service.",
|
|
68
|
+
"Authenticate to enable:",
|
|
69
|
+
" squads login"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
scheduler: {
|
|
73
|
+
name: "Scheduler",
|
|
74
|
+
description: "Trigger evaluation and agent execution",
|
|
75
|
+
required: false,
|
|
76
|
+
getHealthUrl: () => env.api_url ? `${env.api_url}/health` : "",
|
|
77
|
+
envVars: [],
|
|
78
|
+
setupGuide: [
|
|
79
|
+
"Scheduling requires authentication.",
|
|
80
|
+
" squads login"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
langfuse: {
|
|
84
|
+
name: "Traces",
|
|
85
|
+
description: "Telemetry dashboard and cost tracking",
|
|
86
|
+
required: false,
|
|
87
|
+
getHealthUrl: () => {
|
|
88
|
+
const host = process.env.LANGFUSE_HOST;
|
|
89
|
+
return host ? `${host}/api/public/health` : "";
|
|
90
|
+
},
|
|
91
|
+
envVars: ["LANGFUSE_HOST", "LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY"],
|
|
92
|
+
setupGuide: [
|
|
93
|
+
"Traces are available with a Squads account.",
|
|
94
|
+
" squads login"
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
redis: {
|
|
98
|
+
name: "Cache",
|
|
99
|
+
description: "Caching and rate limiting",
|
|
100
|
+
required: false,
|
|
101
|
+
getHealthUrl: () => "",
|
|
102
|
+
envVars: ["REDIS_URL"],
|
|
103
|
+
setupGuide: [
|
|
104
|
+
"Caching is available with a Squads account.",
|
|
105
|
+
" squads login"
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
async function checkService(url, timeout = 2e3) {
|
|
111
|
+
if (!url) return false;
|
|
112
|
+
try {
|
|
113
|
+
const controller = new AbortController();
|
|
114
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
115
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
116
|
+
clearTimeout(timeoutId);
|
|
117
|
+
return response.ok;
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function checkServiceAvailable(serviceName, showGuidance = true) {
|
|
123
|
+
const services = buildServices();
|
|
124
|
+
const service = services[serviceName];
|
|
125
|
+
if (!service) return false;
|
|
126
|
+
const healthUrl = service.getHealthUrl();
|
|
127
|
+
if (!healthUrl) {
|
|
128
|
+
if (showGuidance) {
|
|
129
|
+
showServiceSetupGuide(serviceName, "not configured");
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
const healthy = await checkService(healthUrl);
|
|
134
|
+
if (!healthy) {
|
|
135
|
+
if (showGuidance) {
|
|
136
|
+
showServiceSetupGuide(serviceName, "not responding");
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
function showServiceSetupGuide(serviceName, issue) {
|
|
143
|
+
const services = buildServices();
|
|
144
|
+
const service = services[serviceName];
|
|
145
|
+
if (!service) return;
|
|
146
|
+
writeLine();
|
|
147
|
+
writeLine(` ${colors.yellow}${icons.warning}${RESET} ${bold}${service.name}${RESET} is ${issue}`);
|
|
148
|
+
writeLine(` ${colors.dim}${service.description}${RESET}`);
|
|
149
|
+
writeLine();
|
|
150
|
+
writeLine(` ${bold}To fix:${RESET}`);
|
|
151
|
+
for (const step of service.setupGuide) {
|
|
152
|
+
if (step === "") {
|
|
153
|
+
writeLine();
|
|
154
|
+
} else {
|
|
155
|
+
writeLine(` ${colors.dim}${step}${RESET}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (service.envVars.length > 0) {
|
|
159
|
+
writeLine();
|
|
160
|
+
writeLine(` ${bold}Environment variables:${RESET}`);
|
|
161
|
+
for (const envVar of service.envVars) {
|
|
162
|
+
const value = process.env[envVar];
|
|
163
|
+
const status = value ? `${colors.green}\u2713${RESET}` : `${colors.red}\u2717${RESET}`;
|
|
164
|
+
writeLine(` ${status} ${colors.cyan}${envVar}${RESET}${value ? ` = ${colors.dim}${value}${RESET}` : ""}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
writeLine();
|
|
168
|
+
writeLine(` ${colors.dim}Full setup: squads health${RESET}`);
|
|
169
|
+
writeLine();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// src/commands/memory.ts
|
|
173
|
+
function getBridgeUrl() {
|
|
174
|
+
return getEnv().bridge_url;
|
|
175
|
+
}
|
|
176
|
+
function getMem0Url() {
|
|
177
|
+
return process.env.MEM0_API_URL || "";
|
|
178
|
+
}
|
|
179
|
+
async function memoryQueryCommand(query, options) {
|
|
180
|
+
await track(Events.CLI_MEMORY_QUERY, { squad: options.squad, agent: options.agent });
|
|
181
|
+
const memoryDir = findMemoryDir();
|
|
182
|
+
if (!memoryDir) {
|
|
183
|
+
writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);
|
|
184
|
+
writeLine(` ${colors.dim}Run \`squads init\` to create one.${RESET}`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
writeLine();
|
|
188
|
+
writeLine(` ${gradient("squads")} ${colors.dim}memory query${RESET} "${colors.cyan}${query}${RESET}"`);
|
|
189
|
+
writeLine();
|
|
190
|
+
const results = searchMemory(query, memoryDir);
|
|
191
|
+
if (results.length === 0) {
|
|
192
|
+
writeLine(` ${colors.yellow}No results found.${RESET}`);
|
|
193
|
+
writeLine();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
let filtered = results;
|
|
197
|
+
if (options.squad) {
|
|
198
|
+
filtered = filtered.filter((r) => r.entry.squad === options.squad);
|
|
199
|
+
}
|
|
200
|
+
if (options.agent) {
|
|
201
|
+
filtered = filtered.filter((r) => r.entry.agent === options.agent);
|
|
202
|
+
}
|
|
203
|
+
writeLine(` ${colors.green}${filtered.length}${RESET} results found`);
|
|
204
|
+
writeLine();
|
|
205
|
+
const w = { location: 28, type: 10, score: 8 };
|
|
206
|
+
const tableWidth = w.location + w.type + w.score + 4;
|
|
207
|
+
writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);
|
|
208
|
+
const header = ` ${colors.purple}${box.vertical}${RESET} ${bold}${padEnd("LOCATION", w.location)}${RESET}${bold}${padEnd("TYPE", w.type)}${RESET}${bold}SCORE${RESET} ${colors.purple}${box.vertical}${RESET}`;
|
|
209
|
+
writeLine(header);
|
|
210
|
+
writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);
|
|
211
|
+
for (const result of filtered.slice(0, 8)) {
|
|
212
|
+
const { entry, score } = result;
|
|
213
|
+
const location = `${entry.squad}/${entry.agent}`;
|
|
214
|
+
const scoreColor = score > 5 ? colors.green : score > 2 ? colors.yellow : colors.dim;
|
|
215
|
+
const row = ` ${colors.purple}${box.vertical}${RESET} ${colors.cyan}${padEnd(location, w.location)}${RESET}${colors.dim}${padEnd(entry.type, w.type)}${RESET}${scoreColor}${padEnd(score.toFixed(1), w.score)}${RESET}${colors.purple}${box.vertical}${RESET}`;
|
|
216
|
+
writeLine(row);
|
|
217
|
+
}
|
|
218
|
+
writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);
|
|
219
|
+
writeLine();
|
|
220
|
+
writeLine(` ${bold}Matches${RESET}`);
|
|
221
|
+
writeLine();
|
|
222
|
+
for (const result of filtered.slice(0, 5)) {
|
|
223
|
+
const { entry, matches } = result;
|
|
224
|
+
for (const match of matches.slice(0, 2)) {
|
|
225
|
+
const highlighted = match.replace(
|
|
226
|
+
new RegExp(query, "gi"),
|
|
227
|
+
(m) => `${colors.yellow}${m}${RESET}`
|
|
228
|
+
);
|
|
229
|
+
writeLine(` ${icons.empty} ${truncate(highlighted, 60)}`);
|
|
230
|
+
writeLine(` ${colors.dim}\u2514 ${entry.squad}/${entry.agent}${RESET}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (filtered.length > 5) {
|
|
234
|
+
writeLine(` ${colors.dim} +${filtered.length - 5} more results${RESET}`);
|
|
235
|
+
}
|
|
236
|
+
writeLine();
|
|
237
|
+
writeLine(` ${colors.dim}$${RESET} squads memory show ${colors.cyan}<squad>${RESET} ${colors.dim}View full memory${RESET}`);
|
|
238
|
+
writeLine();
|
|
239
|
+
}
|
|
240
|
+
async function memoryShowCommand(squadName, _options) {
|
|
241
|
+
await track(Events.CLI_MEMORY_SHOW, { squad: squadName });
|
|
242
|
+
const memoryDir = findMemoryDir();
|
|
243
|
+
if (!memoryDir) {
|
|
244
|
+
writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
const states = getSquadState(squadName);
|
|
248
|
+
if (states.length === 0) {
|
|
249
|
+
writeLine(` ${colors.yellow}No memory found for squad: ${squadName}${RESET}`);
|
|
250
|
+
const entries = listMemoryEntries(memoryDir);
|
|
251
|
+
const squads = [...new Set(entries.map((e) => e.squad))].sort();
|
|
252
|
+
if (squads.length > 0) {
|
|
253
|
+
writeLine(` ${colors.dim}Available squads: ${squads.join(", ")}${RESET}`);
|
|
254
|
+
}
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
writeLine();
|
|
258
|
+
writeLine(` ${gradient("squads")} ${colors.dim}memory${RESET} ${colors.cyan}${squadName}${RESET}`);
|
|
259
|
+
writeLine();
|
|
260
|
+
writeLine(` ${colors.dim}${states.length} entries${RESET}`);
|
|
261
|
+
writeLine();
|
|
262
|
+
for (const state of states) {
|
|
263
|
+
writeLine(` ${icons.progress} ${colors.white}${state.agent}${RESET} ${colors.dim}(${state.type || "state"})${RESET}`);
|
|
264
|
+
writeLine(` ${colors.dim}${box.horizontal.repeat(40)}${RESET}`);
|
|
265
|
+
const lines = state.content.split("\n").slice(0, 12);
|
|
266
|
+
for (const line of lines) {
|
|
267
|
+
writeLine(` ${colors.dim}${truncate(line, 70)}${RESET}`);
|
|
268
|
+
}
|
|
269
|
+
if (state.content.split("\n").length > 12) {
|
|
270
|
+
writeLine(` ${colors.dim}... (more content)${RESET}`);
|
|
271
|
+
}
|
|
272
|
+
writeLine();
|
|
273
|
+
}
|
|
274
|
+
writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}"<term>"${RESET} ${colors.dim}Search memory${RESET}`);
|
|
275
|
+
writeLine();
|
|
276
|
+
}
|
|
277
|
+
async function memoryUpdateCommand(squadName, content, options) {
|
|
278
|
+
await track(Events.CLI_MEMORY_UPDATE, { squad: squadName, agent: options.agent, type: options.type });
|
|
279
|
+
const agentName = options.agent || `${squadName}-lead`;
|
|
280
|
+
const type = options.type || "learnings";
|
|
281
|
+
writeLine();
|
|
282
|
+
try {
|
|
283
|
+
await appendToMemory(squadName, agentName, type, content);
|
|
284
|
+
writeLine(` ${icons.success} Updated ${colors.cyan}${type}${RESET} for ${colors.white}${squadName}/${agentName}${RESET}`);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
writeLine(` ${icons.error} ${colors.red}Failed to update memory: ${error}${RESET}`);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
writeLine();
|
|
290
|
+
}
|
|
291
|
+
async function memoryListCommand() {
|
|
292
|
+
await track(Events.CLI_MEMORY_LIST);
|
|
293
|
+
const memoryDir = findMemoryDir();
|
|
294
|
+
if (!memoryDir) {
|
|
295
|
+
writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
const entries = listMemoryEntries(memoryDir);
|
|
299
|
+
const bySquad = {};
|
|
300
|
+
for (const entry of entries) {
|
|
301
|
+
if (!bySquad[entry.squad]) {
|
|
302
|
+
bySquad[entry.squad] = [];
|
|
303
|
+
}
|
|
304
|
+
bySquad[entry.squad].push(entry);
|
|
305
|
+
}
|
|
306
|
+
writeLine();
|
|
307
|
+
writeLine(` ${gradient("squads")} ${colors.dim}memory list${RESET}`);
|
|
308
|
+
writeLine();
|
|
309
|
+
const squadNames = Object.keys(bySquad);
|
|
310
|
+
writeLine(` ${colors.cyan}${entries.length}${RESET} entries across ${squadNames.length} squads`);
|
|
311
|
+
writeLine();
|
|
312
|
+
const w = { squad: 16, agents: 8, types: 28 };
|
|
313
|
+
const tableWidth = w.squad + w.agents + w.types + 4;
|
|
314
|
+
writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);
|
|
315
|
+
const header = ` ${colors.purple}${box.vertical}${RESET} ${bold}${padEnd("SQUAD", w.squad)}${RESET}${bold}${padEnd("AGENTS", w.agents)}${RESET}${bold}TYPES${RESET} ${colors.purple}${box.vertical}${RESET}`;
|
|
316
|
+
writeLine(header);
|
|
317
|
+
writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);
|
|
318
|
+
for (const [squad, squadEntries] of Object.entries(bySquad)) {
|
|
319
|
+
const agents = new Set(squadEntries.map((e) => e.agent));
|
|
320
|
+
const types = [...new Set(squadEntries.map((e) => e.type))].join(", ");
|
|
321
|
+
const typesDisplay = truncate(types, w.types - 2);
|
|
322
|
+
const row = ` ${colors.purple}${box.vertical}${RESET} ${colors.cyan}${padEnd(squad, w.squad)}${RESET}${padEnd(String(agents.size), w.agents)}${colors.dim}${padEnd(typesDisplay, w.types)}${RESET}${colors.purple}${box.vertical}${RESET}`;
|
|
323
|
+
writeLine(row);
|
|
324
|
+
}
|
|
325
|
+
writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);
|
|
326
|
+
writeLine();
|
|
327
|
+
writeLine(` ${colors.dim}$${RESET} squads memory show ${colors.cyan}<squad>${RESET} ${colors.dim}View squad memory${RESET}`);
|
|
328
|
+
writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}"<term>"${RESET} ${colors.dim}Search all memory${RESET}`);
|
|
329
|
+
writeLine();
|
|
330
|
+
}
|
|
331
|
+
async function memorySearchCommand(query, options = {}) {
|
|
332
|
+
writeLine();
|
|
333
|
+
writeLine(` ${gradient("squads")} ${colors.dim}memory search${RESET} "${colors.cyan}${query}${RESET}"`);
|
|
334
|
+
writeLine();
|
|
335
|
+
const limit = options.limit || 10;
|
|
336
|
+
const params = new URLSearchParams({ q: query, limit: String(limit) });
|
|
337
|
+
if (options.role) {
|
|
338
|
+
params.append("role", options.role);
|
|
339
|
+
}
|
|
340
|
+
if (options.importance) {
|
|
341
|
+
params.append("importance", options.importance);
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
const bridgeUrl = getBridgeUrl();
|
|
345
|
+
if (!bridgeUrl) {
|
|
346
|
+
writeLine(` ${colors.yellow}API service unavailable${RESET}`);
|
|
347
|
+
writeLine(` ${colors.dim}Conversation search requires authentication. Run \`squads login\` to connect.${RESET}`);
|
|
348
|
+
writeLine(` ${colors.dim}For local memory search, use: squads memory query "${query}"${RESET}`);
|
|
349
|
+
writeLine();
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const response = await fetch(`${bridgeUrl}/api/conversations/search?${params}`, {
|
|
353
|
+
signal: AbortSignal.timeout(5e3)
|
|
354
|
+
});
|
|
355
|
+
if (!response.ok) {
|
|
356
|
+
if (response.status === 503) {
|
|
357
|
+
writeLine(` ${colors.yellow}API service unavailable. Run \`squads login\` to connect.${RESET}`);
|
|
358
|
+
writeLine(` ${colors.dim}For local memory search, use: squads memory query "${query}"${RESET}`);
|
|
359
|
+
writeLine();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
throw new Error(`HTTP ${response.status}`);
|
|
363
|
+
}
|
|
364
|
+
const data = await response.json();
|
|
365
|
+
const conversations = data.results;
|
|
366
|
+
const total = data.count;
|
|
367
|
+
if (conversations.length === 0) {
|
|
368
|
+
writeLine(` ${colors.yellow}No conversations found for "${query}"${RESET}`);
|
|
369
|
+
writeLine();
|
|
370
|
+
writeLine(` ${colors.dim}Conversations are captured via hooks. Make sure:${RESET}`);
|
|
371
|
+
writeLine(` ${colors.dim} 1. You are authenticated (squads login)${RESET}`);
|
|
372
|
+
writeLine(` ${colors.dim} 2. Telemetry hooks are configured in Claude settings${RESET}`);
|
|
373
|
+
writeLine();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
writeLine(` ${colors.green}${conversations.length}${RESET} of ${total} results`);
|
|
377
|
+
writeLine();
|
|
378
|
+
const w = { time: 12, role: 10, type: 10, content: 50 };
|
|
379
|
+
const tableWidth = w.time + w.role + w.type + w.content + 6;
|
|
380
|
+
writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);
|
|
381
|
+
const header = ` ${colors.purple}${box.vertical}${RESET} ${bold}${padEnd("TIME", w.time)}${RESET}${bold}${padEnd("ROLE", w.role)}${RESET}${bold}${padEnd("TYPE", w.type)}${RESET}${bold}${padEnd("CONTENT", w.content)}${RESET} ${colors.purple}${box.vertical}${RESET}`;
|
|
382
|
+
writeLine(header);
|
|
383
|
+
writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);
|
|
384
|
+
for (const conv of conversations) {
|
|
385
|
+
const time = new Date(conv.created_at).toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
|
|
386
|
+
const roleColor = conv.role === "user" ? colors.cyan : conv.role === "thinking" ? colors.yellow : colors.green;
|
|
387
|
+
const importanceIcon = conv.importance === "high" ? icons.success : "";
|
|
388
|
+
const contentPreview = truncate((conv.content || "").replace(/\n/g, " "), w.content - 2);
|
|
389
|
+
const highlighted = contentPreview.replace(
|
|
390
|
+
new RegExp(query, "gi"),
|
|
391
|
+
(m) => `${colors.yellow}${m}${RESET}${colors.dim}`
|
|
392
|
+
);
|
|
393
|
+
const row = ` ${colors.purple}${box.vertical}${RESET} ${colors.dim}${padEnd(time, w.time)}${RESET}${roleColor}${padEnd(conv.role || "", w.role)}${RESET}${colors.dim}${padEnd(conv.type || "message", w.type)}${RESET}${colors.dim}${padEnd(highlighted + importanceIcon, w.content)}${RESET} ${colors.purple}${box.vertical}${RESET}`;
|
|
394
|
+
writeLine(row);
|
|
395
|
+
}
|
|
396
|
+
writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);
|
|
397
|
+
writeLine();
|
|
398
|
+
writeLine(` ${bold}Top Matches${RESET}`);
|
|
399
|
+
writeLine();
|
|
400
|
+
for (const conv of conversations.slice(0, 3)) {
|
|
401
|
+
const time = new Date(conv.created_at).toLocaleString("en-US", {
|
|
402
|
+
month: "short",
|
|
403
|
+
day: "numeric",
|
|
404
|
+
hour: "2-digit",
|
|
405
|
+
minute: "2-digit"
|
|
406
|
+
});
|
|
407
|
+
const roleIcon = conv.role === "user" ? "\u{1F464}" : conv.role === "thinking" ? "\u{1F4AD}" : "\u{1F916}";
|
|
408
|
+
writeLine(` ${roleIcon} ${colors.dim}${time}${RESET} ${conv.importance === "high" ? colors.yellow + "[high]" + RESET : ""}`);
|
|
409
|
+
const content = conv.content || "";
|
|
410
|
+
const preview = content.substring(0, 200).replace(/\n/g, " ");
|
|
411
|
+
const highlighted = preview.replace(
|
|
412
|
+
new RegExp(query, "gi"),
|
|
413
|
+
(m) => `${colors.yellow}${m}${RESET}`
|
|
414
|
+
);
|
|
415
|
+
writeLine(` ${highlighted}${content.length > 200 ? "..." : ""}`);
|
|
416
|
+
writeLine();
|
|
417
|
+
}
|
|
418
|
+
writeLine(` ${colors.dim}$${RESET} squads memory search ${colors.cyan}"<term>"${RESET} --role user ${colors.dim}Filter by role${RESET}`);
|
|
419
|
+
writeLine(` ${colors.dim}$${RESET} squads memory search ${colors.cyan}"<term>"${RESET} --importance high ${colors.dim}Filter by importance${RESET}`);
|
|
420
|
+
writeLine();
|
|
421
|
+
} catch (error) {
|
|
422
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
423
|
+
if (errorMessage.includes("ECONNREFUSED") || errorMessage.includes("fetch failed")) {
|
|
424
|
+
showServiceSetupGuide("bridge", "not responding");
|
|
425
|
+
} else {
|
|
426
|
+
writeLine(` ${colors.red}Error searching conversations: ${errorMessage}${RESET}`);
|
|
427
|
+
writeLine();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
async function memoryExtractCommand(options = {}) {
|
|
432
|
+
writeLine();
|
|
433
|
+
writeLine(` ${gradient("squads")} ${colors.dim}memory extract${RESET}`);
|
|
434
|
+
writeLine();
|
|
435
|
+
const hours = options.hours || 24;
|
|
436
|
+
try {
|
|
437
|
+
writeLine(` ${colors.dim}Fetching conversations from last ${hours}h...${RESET}`);
|
|
438
|
+
const bridgeUrl = getBridgeUrl();
|
|
439
|
+
if (!bridgeUrl) {
|
|
440
|
+
writeLine(` ${colors.yellow}API service unavailable. Run \`squads login\` to connect.${RESET}`);
|
|
441
|
+
writeLine();
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
const bridgeResponse = await fetch(`${bridgeUrl}/api/conversations/recent`, {
|
|
445
|
+
signal: AbortSignal.timeout(5e3)
|
|
446
|
+
});
|
|
447
|
+
if (!bridgeResponse.ok) {
|
|
448
|
+
throw new Error(`API error: ${bridgeResponse.status}`);
|
|
449
|
+
}
|
|
450
|
+
const { conversations, count } = await bridgeResponse.json();
|
|
451
|
+
if (count === 0) {
|
|
452
|
+
writeLine(` ${colors.yellow}No recent conversations to extract${RESET}`);
|
|
453
|
+
writeLine();
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
writeLine(` ${colors.green}${count}${RESET} conversations found`);
|
|
457
|
+
writeLine();
|
|
458
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
459
|
+
for (const conv of conversations) {
|
|
460
|
+
const sessionId = conv.session_id || "unknown";
|
|
461
|
+
if (!sessions.has(sessionId)) {
|
|
462
|
+
sessions.set(sessionId, []);
|
|
463
|
+
}
|
|
464
|
+
sessions.get(sessionId).push(conv);
|
|
465
|
+
}
|
|
466
|
+
writeLine(` ${colors.cyan}${sessions.size}${RESET} sessions to process`);
|
|
467
|
+
writeLine();
|
|
468
|
+
if (options.dryRun) {
|
|
469
|
+
writeLine(` ${colors.yellow}Dry run - not sending to Engram${RESET}`);
|
|
470
|
+
writeLine();
|
|
471
|
+
for (const [sessionId, convs] of sessions) {
|
|
472
|
+
const squad = convs[0]?.squad || "unknown";
|
|
473
|
+
const agent = convs[0]?.agent || "unknown";
|
|
474
|
+
writeLine(` ${icons.progress} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.cyan}${squad}/${agent}${RESET} ${colors.dim}(${convs.length} messages)${RESET}`);
|
|
475
|
+
}
|
|
476
|
+
writeLine();
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
let extracted = 0;
|
|
480
|
+
let failed = 0;
|
|
481
|
+
for (const [sessionId, convs] of sessions) {
|
|
482
|
+
const squad = convs[0]?.squad || "hq";
|
|
483
|
+
const agent = convs[0]?.agent || "unknown";
|
|
484
|
+
const messages = convs.map((c) => ({
|
|
485
|
+
role: c.role === "assistant" ? "assistant" : c.role === "user" ? "user" : "system",
|
|
486
|
+
content: c.content
|
|
487
|
+
}));
|
|
488
|
+
try {
|
|
489
|
+
const mem0Url = getMem0Url();
|
|
490
|
+
if (!mem0Url) {
|
|
491
|
+
writeLine(` ${colors.yellow}Memory service not configured. Run \`squads login\` to connect.${RESET}`);
|
|
492
|
+
writeLine();
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const mem0Response = await fetch(`${mem0Url}/memories`, {
|
|
496
|
+
method: "POST",
|
|
497
|
+
headers: { "Content-Type": "application/json" },
|
|
498
|
+
body: JSON.stringify({
|
|
499
|
+
messages,
|
|
500
|
+
user_id: squad,
|
|
501
|
+
agent_id: agent,
|
|
502
|
+
run_id: sessionId,
|
|
503
|
+
metadata: {
|
|
504
|
+
source: "squads-cli",
|
|
505
|
+
extracted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
506
|
+
}
|
|
507
|
+
}),
|
|
508
|
+
signal: AbortSignal.timeout(1e4)
|
|
509
|
+
});
|
|
510
|
+
if (mem0Response.ok) {
|
|
511
|
+
const result = await mem0Response.json();
|
|
512
|
+
const memCount = result.results?.length || 0;
|
|
513
|
+
writeLine(` ${colors.green}${icons.success}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.cyan}${squad}/${agent}${RESET} \u2192 ${colors.green}${memCount}${RESET} memories`);
|
|
514
|
+
extracted++;
|
|
515
|
+
} else {
|
|
516
|
+
writeLine(` ${colors.red}${icons.error}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.red}Failed: ${mem0Response.status}${RESET}`);
|
|
517
|
+
failed++;
|
|
518
|
+
}
|
|
519
|
+
} catch (err) {
|
|
520
|
+
writeLine(` ${colors.red}${icons.error}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.red}Error: ${err}${RESET}`);
|
|
521
|
+
failed++;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
writeLine();
|
|
525
|
+
if (failed === 0) {
|
|
526
|
+
writeLine(` ${colors.green}${icons.success}${RESET} Extracted memories from ${extracted} sessions`);
|
|
527
|
+
} else {
|
|
528
|
+
writeLine(` ${colors.yellow}${icons.warning}${RESET} Extracted: ${extracted}, Failed: ${failed}`);
|
|
529
|
+
}
|
|
530
|
+
writeLine();
|
|
531
|
+
writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}"<term>"${RESET} ${colors.dim}Search extracted memories${RESET}`);
|
|
532
|
+
writeLine();
|
|
533
|
+
} catch (error) {
|
|
534
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
535
|
+
if (errorMessage.includes("ECONNREFUSED") || errorMessage.includes("fetch failed")) {
|
|
536
|
+
const bridgeOk = await checkServiceAvailable("bridge", false);
|
|
537
|
+
const mem0Ok = await checkServiceAvailable("mem0", false);
|
|
538
|
+
if (!bridgeOk) {
|
|
539
|
+
showServiceSetupGuide("bridge", "not responding");
|
|
540
|
+
} else if (!mem0Ok) {
|
|
541
|
+
showServiceSetupGuide("mem0", "not responding");
|
|
542
|
+
} else {
|
|
543
|
+
writeLine(` ${colors.red}Error: ${errorMessage}${RESET}`);
|
|
544
|
+
writeLine();
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
writeLine(` ${colors.red}Error: ${errorMessage}${RESET}`);
|
|
548
|
+
writeLine();
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
export {
|
|
553
|
+
memoryExtractCommand,
|
|
554
|
+
memoryListCommand,
|
|
555
|
+
memoryQueryCommand,
|
|
556
|
+
memorySearchCommand,
|
|
557
|
+
memoryShowCommand,
|
|
558
|
+
memoryUpdateCommand
|
|
559
|
+
};
|
|
560
|
+
//# sourceMappingURL=memory-T3ACCS7E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/services.ts","../src/commands/memory.ts"],"sourcesContent":["/**\n * Service availability checking utilities\n * Checks API reachability for optional cloud features\n */\n\nimport {\n colors,\n bold,\n RESET,\n icons,\n writeLine,\n} from './terminal.js';\nimport { getEnv } from './env-config.js';\n\ninterface ServiceInfo {\n name: string;\n description: string;\n required: boolean;\n getHealthUrl: () => string;\n envVars: string[];\n setupGuide: string[];\n}\n\nfunction buildServices(): Record<string, ServiceInfo> {\n const env = getEnv();\n\n return {\n bridge: {\n name: 'API',\n description: 'Optional: captures conversations and telemetry',\n required: false,\n getHealthUrl: () => env.bridge_url ? `${env.bridge_url}/health` : '',\n envVars: ['SQUADS_BRIDGE_URL'],\n setupGuide: [\n 'Not required for basic usage (init, run, status, eval).',\n 'To enable telemetry, authenticate:',\n ' squads login',\n ],\n },\n postgres: {\n name: 'Database',\n description: 'Optional: enables scheduling, telemetry, and persistent storage',\n required: false,\n getHealthUrl: () => '',\n envVars: ['SQUADS_DATABASE_URL'],\n setupGuide: [\n 'Not required for basic usage (init, run, status, eval).',\n 'Available with a Squads account:',\n ' squads login',\n ],\n },\n mem0: {\n name: 'Memory Service',\n description: 'Memory extraction and search',\n required: false,\n getHealthUrl: () => {\n const url = process.env.MEM0_API_URL;\n return url ? `${url}/health` : '';\n },\n envVars: ['MEM0_API_URL'],\n setupGuide: [\n 'Memory extraction requires the memory service.',\n 'Authenticate to enable:',\n ' squads login',\n ],\n },\n scheduler: {\n name: 'Scheduler',\n description: 'Trigger evaluation and agent execution',\n required: false,\n getHealthUrl: () => env.api_url ? `${env.api_url}/health` : '',\n envVars: [],\n setupGuide: [\n 'Scheduling requires authentication.',\n ' squads login',\n ],\n },\n langfuse: {\n name: 'Traces',\n description: 'Telemetry dashboard and cost tracking',\n required: false,\n getHealthUrl: () => {\n const host = process.env.LANGFUSE_HOST;\n return host ? `${host}/api/public/health` : '';\n },\n envVars: ['LANGFUSE_HOST', 'LANGFUSE_PUBLIC_KEY', 'LANGFUSE_SECRET_KEY'],\n setupGuide: [\n 'Traces are available with a Squads account.',\n ' squads login',\n ],\n },\n redis: {\n name: 'Cache',\n description: 'Caching and rate limiting',\n required: false,\n getHealthUrl: () => '',\n envVars: ['REDIS_URL'],\n setupGuide: [\n 'Caching is available with a Squads account.',\n ' squads login',\n ],\n },\n };\n}\n\nasync function checkService(url: string, timeout = 2000): Promise<boolean> {\n if (!url) return false;\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(url, { signal: controller.signal });\n clearTimeout(timeoutId);\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a service is available and show guidance if not\n */\nexport async function checkServiceAvailable(\n serviceName: string,\n showGuidance = true\n): Promise<boolean> {\n const services = buildServices();\n const service = services[serviceName];\n if (!service) return false;\n\n const healthUrl = service.getHealthUrl();\n if (!healthUrl) {\n if (showGuidance) {\n showServiceSetupGuide(serviceName, 'not configured');\n }\n return false;\n }\n\n const healthy = await checkService(healthUrl);\n if (!healthy) {\n if (showGuidance) {\n showServiceSetupGuide(serviceName, 'not responding');\n }\n return false;\n }\n\n return true;\n}\n\n/**\n * Show setup guide for a service\n */\nexport function showServiceSetupGuide(\n serviceName: string,\n issue: string\n): void {\n const services = buildServices();\n const service = services[serviceName];\n if (!service) return;\n\n writeLine();\n writeLine(` ${colors.yellow}${icons.warning}${RESET} ${bold}${service.name}${RESET} is ${issue}`);\n writeLine(` ${colors.dim}${service.description}${RESET}`);\n writeLine();\n\n writeLine(` ${bold}To fix:${RESET}`);\n for (const step of service.setupGuide) {\n if (step === '') {\n writeLine();\n } else {\n writeLine(` ${colors.dim}${step}${RESET}`);\n }\n }\n\n if (service.envVars.length > 0) {\n writeLine();\n writeLine(` ${bold}Environment variables:${RESET}`);\n for (const envVar of service.envVars) {\n const value = process.env[envVar];\n const status = value ? `${colors.green}✓${RESET}` : `${colors.red}✗${RESET}`;\n writeLine(` ${status} ${colors.cyan}${envVar}${RESET}${value ? ` = ${colors.dim}${value}${RESET}` : ''}`);\n }\n }\n\n writeLine();\n writeLine(` ${colors.dim}Full setup: squads health${RESET}`);\n writeLine();\n}\n","import {\n findMemoryDir,\n searchMemory,\n getSquadState,\n appendToMemory,\n listMemoryEntries\n} from '../lib/memory.js';\nimport {\n colors,\n bold,\n RESET,\n gradient,\n box,\n padEnd,\n truncate,\n icons,\n writeLine,\n} from '../lib/terminal.js';\nimport { checkServiceAvailable, showServiceSetupGuide } from '../lib/services.js';\nimport { track, Events } from '../lib/telemetry.js';\nimport { getEnv } from '../lib/env-config.js';\n\nfunction getBridgeUrl(): string {\n return getEnv().bridge_url;\n}\n\nfunction getMem0Url(): string {\n return process.env.MEM0_API_URL || '';\n}\n\ninterface MemoryOptions {\n squad?: string;\n agent?: string;\n type?: string;\n}\n\nexport async function memoryQueryCommand(\n query: string,\n options: MemoryOptions\n): Promise<void> {\n await track(Events.CLI_MEMORY_QUERY, { squad: options.squad, agent: options.agent });\n const memoryDir = findMemoryDir();\n\n if (!memoryDir) {\n writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);\n writeLine(` ${colors.dim}Run \\`squads init\\` to create one.${RESET}`);\n process.exit(1);\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}memory query${RESET} \"${colors.cyan}${query}${RESET}\"`);\n writeLine();\n\n const results = searchMemory(query, memoryDir);\n\n if (results.length === 0) {\n writeLine(` ${colors.yellow}No results found.${RESET}`);\n writeLine();\n return;\n }\n\n // Filter by squad/agent if specified\n let filtered = results;\n if (options.squad) {\n filtered = filtered.filter(r => r.entry.squad === options.squad);\n }\n if (options.agent) {\n filtered = filtered.filter(r => r.entry.agent === options.agent);\n }\n\n writeLine(` ${colors.green}${filtered.length}${RESET} results found`);\n writeLine();\n\n // Table\n const w = { location: 28, type: 10, score: 8 };\n const tableWidth = w.location + w.type + w.score + 4;\n\n writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);\n\n const header = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${bold}${padEnd('LOCATION', w.location)}${RESET}` +\n `${bold}${padEnd('TYPE', w.type)}${RESET}` +\n `${bold}SCORE${RESET}` +\n ` ${colors.purple}${box.vertical}${RESET}`;\n writeLine(header);\n\n writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);\n\n for (const result of filtered.slice(0, 8)) {\n const { entry, score } = result;\n const location = `${entry.squad}/${entry.agent}`;\n const scoreColor = score > 5 ? colors.green : score > 2 ? colors.yellow : colors.dim;\n\n const row = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${colors.cyan}${padEnd(location, w.location)}${RESET}` +\n `${colors.dim}${padEnd(entry.type, w.type)}${RESET}` +\n `${scoreColor}${padEnd(score.toFixed(1), w.score)}${RESET}` +\n `${colors.purple}${box.vertical}${RESET}`;\n\n writeLine(row);\n }\n\n writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);\n writeLine();\n\n // Show matches\n writeLine(` ${bold}Matches${RESET}`);\n writeLine();\n\n for (const result of filtered.slice(0, 5)) {\n const { entry, matches } = result;\n\n for (const match of matches.slice(0, 2)) {\n const highlighted = match.replace(\n new RegExp(query, 'gi'),\n (m) => `${colors.yellow}${m}${RESET}`\n );\n writeLine(` ${icons.empty} ${truncate(highlighted, 60)}`);\n writeLine(` ${colors.dim}└ ${entry.squad}/${entry.agent}${RESET}`);\n }\n }\n\n if (filtered.length > 5) {\n writeLine(` ${colors.dim} +${filtered.length - 5} more results${RESET}`);\n }\n writeLine();\n\n // Commands\n writeLine(` ${colors.dim}$${RESET} squads memory show ${colors.cyan}<squad>${RESET} ${colors.dim}View full memory${RESET}`);\n writeLine();\n}\n\nexport async function memoryShowCommand(\n squadName: string,\n _options: MemoryOptions\n): Promise<void> {\n await track(Events.CLI_MEMORY_SHOW, { squad: squadName });\n const memoryDir = findMemoryDir();\n\n if (!memoryDir) {\n writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);\n process.exit(1);\n }\n\n const states = getSquadState(squadName);\n\n if (states.length === 0) {\n writeLine(` ${colors.yellow}No memory found for squad: ${squadName}${RESET}`);\n const entries = listMemoryEntries(memoryDir!);\n const squads = [...new Set(entries.map(e => e.squad))].sort();\n if (squads.length > 0) {\n writeLine(` ${colors.dim}Available squads: ${squads.join(', ')}${RESET}`);\n }\n process.exit(1);\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}memory${RESET} ${colors.cyan}${squadName}${RESET}`);\n writeLine();\n\n writeLine(` ${colors.dim}${states.length} entries${RESET}`);\n writeLine();\n\n for (const state of states) {\n writeLine(` ${icons.progress} ${colors.white}${state.agent}${RESET} ${colors.dim}(${state.type || 'state'})${RESET}`);\n writeLine(` ${colors.dim}${box.horizontal.repeat(40)}${RESET}`);\n\n // Show preview\n const lines = state.content.split('\\n').slice(0, 12);\n for (const line of lines) {\n writeLine(` ${colors.dim}${truncate(line, 70)}${RESET}`);\n }\n\n if (state.content.split('\\n').length > 12) {\n writeLine(` ${colors.dim}... (more content)${RESET}`);\n }\n writeLine();\n }\n\n // Commands\n writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}\"<term>\"${RESET} ${colors.dim}Search memory${RESET}`);\n writeLine();\n}\n\nexport async function memoryUpdateCommand(\n squadName: string,\n content: string,\n options: MemoryOptions\n): Promise<void> {\n await track(Events.CLI_MEMORY_UPDATE, { squad: squadName, agent: options.agent, type: options.type });\n const agentName = options.agent || `${squadName}-lead`;\n const type = (options.type || 'learnings') as 'state' | 'output' | 'learnings' | 'feedback';\n\n writeLine();\n\n try {\n await appendToMemory(squadName, agentName, type, content);\n writeLine(` ${icons.success} Updated ${colors.cyan}${type}${RESET} for ${colors.white}${squadName}/${agentName}${RESET}`);\n } catch (error) {\n writeLine(` ${icons.error} ${colors.red}Failed to update memory: ${error}${RESET}`);\n process.exit(1);\n }\n\n writeLine();\n}\n\nexport async function memoryListCommand(): Promise<void> {\n await track(Events.CLI_MEMORY_LIST);\n const memoryDir = findMemoryDir();\n\n if (!memoryDir) {\n writeLine(` ${colors.red}No .agents/memory directory found${RESET}`);\n process.exit(1);\n }\n\n const entries = listMemoryEntries(memoryDir);\n\n // Group by squad\n const bySquad: Record<string, typeof entries> = {};\n for (const entry of entries) {\n if (!bySquad[entry.squad]) {\n bySquad[entry.squad] = [];\n }\n bySquad[entry.squad].push(entry);\n }\n\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}memory list${RESET}`);\n writeLine();\n\n const squadNames = Object.keys(bySquad);\n writeLine(` ${colors.cyan}${entries.length}${RESET} entries across ${squadNames.length} squads`);\n writeLine();\n\n // Table\n const w = { squad: 16, agents: 8, types: 28 };\n const tableWidth = w.squad + w.agents + w.types + 4;\n\n writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);\n\n const header = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${bold}${padEnd('SQUAD', w.squad)}${RESET}` +\n `${bold}${padEnd('AGENTS', w.agents)}${RESET}` +\n `${bold}TYPES${RESET}` +\n ` ${colors.purple}${box.vertical}${RESET}`;\n writeLine(header);\n\n writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);\n\n for (const [squad, squadEntries] of Object.entries(bySquad)) {\n const agents = new Set(squadEntries.map(e => e.agent));\n const types = [...new Set(squadEntries.map(e => e.type))].join(', ');\n const typesDisplay = truncate(types, w.types - 2);\n\n const row = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${colors.cyan}${padEnd(squad, w.squad)}${RESET}` +\n `${padEnd(String(agents.size), w.agents)}` +\n `${colors.dim}${padEnd(typesDisplay, w.types)}${RESET}` +\n `${colors.purple}${box.vertical}${RESET}`;\n\n writeLine(row);\n }\n\n writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);\n writeLine();\n\n // Commands\n writeLine(` ${colors.dim}$${RESET} squads memory show ${colors.cyan}<squad>${RESET} ${colors.dim}View squad memory${RESET}`);\n writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}\"<term>\"${RESET} ${colors.dim}Search all memory${RESET}`);\n writeLine();\n}\n\ninterface ConversationResult {\n id: number;\n session_id: string;\n role: string;\n content: string;\n type: string; // message_type in the API response\n importance: string;\n created_at: string;\n rank: number;\n}\n\nexport async function memorySearchCommand(\n query: string,\n options: { limit?: number; role?: string; importance?: string } = {}\n): Promise<void> {\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}memory search${RESET} \"${colors.cyan}${query}${RESET}\"`);\n writeLine();\n\n const limit = options.limit || 10;\n const params = new URLSearchParams({ q: query, limit: String(limit) });\n\n if (options.role) {\n params.append('role', options.role);\n }\n if (options.importance) {\n params.append('importance', options.importance);\n }\n\n try {\n const bridgeUrl = getBridgeUrl();\n if (!bridgeUrl) {\n writeLine(` ${colors.yellow}API service unavailable${RESET}`);\n writeLine(` ${colors.dim}Conversation search requires authentication. Run \\`squads login\\` to connect.${RESET}`);\n writeLine(` ${colors.dim}For local memory search, use: squads memory query \"${query}\"${RESET}`);\n writeLine();\n return;\n }\n\n const response = await fetch(`${bridgeUrl}/api/conversations/search?${params}`, {\n signal: AbortSignal.timeout(5000),\n });\n\n if (!response.ok) {\n if (response.status === 503) {\n writeLine(` ${colors.yellow}API service unavailable. Run \\`squads login\\` to connect.${RESET}`);\n writeLine(` ${colors.dim}For local memory search, use: squads memory query \"${query}\"${RESET}`);\n writeLine();\n return;\n }\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json() as { results: ConversationResult[]; count: number };\n const conversations = data.results;\n const total = data.count;\n\n if (conversations.length === 0) {\n writeLine(` ${colors.yellow}No conversations found for \"${query}\"${RESET}`);\n writeLine();\n writeLine(` ${colors.dim}Conversations are captured via hooks. Make sure:${RESET}`);\n writeLine(` ${colors.dim} 1. You are authenticated (squads login)${RESET}`);\n writeLine(` ${colors.dim} 2. Telemetry hooks are configured in Claude settings${RESET}`);\n writeLine();\n return;\n }\n\n writeLine(` ${colors.green}${conversations.length}${RESET} of ${total} results`);\n writeLine();\n\n // Table\n const w = { time: 12, role: 10, type: 10, content: 50 };\n const tableWidth = w.time + w.role + w.type + w.content + 6;\n\n writeLine(` ${colors.purple}${box.topLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.topRight}${RESET}`);\n\n const header = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${bold}${padEnd('TIME', w.time)}${RESET}` +\n `${bold}${padEnd('ROLE', w.role)}${RESET}` +\n `${bold}${padEnd('TYPE', w.type)}${RESET}` +\n `${bold}${padEnd('CONTENT', w.content)}${RESET}` +\n ` ${colors.purple}${box.vertical}${RESET}`;\n writeLine(header);\n\n writeLine(` ${colors.purple}${box.teeRight}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.teeLeft}${RESET}`);\n\n for (const conv of conversations) {\n const time = new Date(conv.created_at).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });\n const roleColor = conv.role === 'user' ? colors.cyan : conv.role === 'thinking' ? colors.yellow : colors.green;\n const importanceIcon = conv.importance === 'high' ? icons.success : '';\n\n // Highlight search term in content\n const contentPreview = truncate((conv.content || '').replace(/\\n/g, ' '), w.content - 2);\n const highlighted = contentPreview.replace(\n new RegExp(query, 'gi'),\n (m) => `${colors.yellow}${m}${RESET}${colors.dim}`\n );\n\n const row = ` ${colors.purple}${box.vertical}${RESET} ` +\n `${colors.dim}${padEnd(time, w.time)}${RESET}` +\n `${roleColor}${padEnd(conv.role || '', w.role)}${RESET}` +\n `${colors.dim}${padEnd(conv.type || 'message', w.type)}${RESET}` +\n `${colors.dim}${padEnd(highlighted + importanceIcon, w.content)}${RESET}` +\n ` ${colors.purple}${box.vertical}${RESET}`;\n\n writeLine(row);\n }\n\n writeLine(` ${colors.purple}${box.bottomLeft}${colors.dim}${box.horizontal.repeat(tableWidth)}${colors.purple}${box.bottomRight}${RESET}`);\n writeLine();\n\n // Expanded view of top results\n writeLine(` ${bold}Top Matches${RESET}`);\n writeLine();\n\n for (const conv of conversations.slice(0, 3)) {\n const time = new Date(conv.created_at).toLocaleString('en-US', {\n month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit'\n });\n const roleIcon = conv.role === 'user' ? '👤' : conv.role === 'thinking' ? '💭' : '🤖';\n\n writeLine(` ${roleIcon} ${colors.dim}${time}${RESET} ${conv.importance === 'high' ? colors.yellow + '[high]' + RESET : ''}`);\n\n // Show first 200 chars with highlighted search term\n const content = conv.content || '';\n const preview = content.substring(0, 200).replace(/\\n/g, ' ');\n const highlighted = preview.replace(\n new RegExp(query, 'gi'),\n (m) => `${colors.yellow}${m}${RESET}`\n );\n writeLine(` ${highlighted}${content.length > 200 ? '...' : ''}`);\n writeLine();\n }\n\n // Commands\n writeLine(` ${colors.dim}$${RESET} squads memory search ${colors.cyan}\"<term>\"${RESET} --role user ${colors.dim}Filter by role${RESET}`);\n writeLine(` ${colors.dim}$${RESET} squads memory search ${colors.cyan}\"<term>\"${RESET} --importance high ${colors.dim}Filter by importance${RESET}`);\n writeLine();\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('fetch failed')) {\n showServiceSetupGuide('bridge', 'not responding');\n } else {\n writeLine(` ${colors.red}Error searching conversations: ${errorMessage}${RESET}`);\n writeLine();\n }\n }\n}\n\ninterface ExtractOptions {\n session?: string;\n hours?: number;\n dryRun?: boolean;\n}\n\n/**\n * Extract memories from recent conversations and store in Engram\n */\nexport async function memoryExtractCommand(\n options: ExtractOptions = {}\n): Promise<void> {\n writeLine();\n writeLine(` ${gradient('squads')} ${colors.dim}memory extract${RESET}`);\n writeLine();\n\n const hours = options.hours || 24;\n\n try {\n // 1. Fetch recent conversations from API\n writeLine(` ${colors.dim}Fetching conversations from last ${hours}h...${RESET}`);\n\n const bridgeUrl = getBridgeUrl();\n if (!bridgeUrl) {\n writeLine(` ${colors.yellow}API service unavailable. Run \\`squads login\\` to connect.${RESET}`);\n writeLine();\n return;\n }\n\n const bridgeResponse = await fetch(`${bridgeUrl}/api/conversations/recent`, {\n signal: AbortSignal.timeout(5000),\n });\n if (!bridgeResponse.ok) {\n throw new Error(`API error: ${bridgeResponse.status}`);\n }\n\n const { conversations, count } = await bridgeResponse.json() as {\n conversations: Array<{\n id: number;\n session_id: string;\n role: string;\n content: string;\n squad?: string;\n agent?: string;\n created_at: string;\n }>;\n count: number;\n };\n\n if (count === 0) {\n writeLine(` ${colors.yellow}No recent conversations to extract${RESET}`);\n writeLine();\n return;\n }\n\n writeLine(` ${colors.green}${count}${RESET} conversations found`);\n writeLine();\n\n // 2. Group conversations by session\n const sessions = new Map<string, typeof conversations>();\n for (const conv of conversations) {\n const sessionId = conv.session_id || 'unknown';\n if (!sessions.has(sessionId)) {\n sessions.set(sessionId, []);\n }\n sessions.get(sessionId)!.push(conv);\n }\n\n writeLine(` ${colors.cyan}${sessions.size}${RESET} sessions to process`);\n writeLine();\n\n if (options.dryRun) {\n writeLine(` ${colors.yellow}Dry run - not sending to Engram${RESET}`);\n writeLine();\n for (const [sessionId, convs] of sessions) {\n const squad = convs[0]?.squad || 'unknown';\n const agent = convs[0]?.agent || 'unknown';\n writeLine(` ${icons.progress} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.cyan}${squad}/${agent}${RESET} ${colors.dim}(${convs.length} messages)${RESET}`);\n }\n writeLine();\n return;\n }\n\n // 3. Send each session to mem0 for extraction\n let extracted = 0;\n let failed = 0;\n\n for (const [sessionId, convs] of sessions) {\n const squad = convs[0]?.squad || 'hq';\n const agent = convs[0]?.agent || 'unknown';\n\n // Format messages for mem0\n const messages = convs.map(c => ({\n role: c.role === 'assistant' ? 'assistant' : c.role === 'user' ? 'user' : 'system',\n content: c.content\n }));\n\n try {\n const mem0Url = getMem0Url();\n if (!mem0Url) {\n writeLine(` ${colors.yellow}Memory service not configured. Run \\`squads login\\` to connect.${RESET}`);\n writeLine();\n return;\n }\n const mem0Response = await fetch(`${mem0Url}/memories`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages,\n user_id: squad,\n agent_id: agent,\n run_id: sessionId,\n metadata: {\n source: 'squads-cli',\n extracted_at: new Date().toISOString()\n }\n }),\n signal: AbortSignal.timeout(10000),\n });\n\n if (mem0Response.ok) {\n const result = await mem0Response.json() as { results?: Array<unknown> };\n const memCount = result.results?.length || 0;\n writeLine(` ${colors.green}${icons.success}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.cyan}${squad}/${agent}${RESET} → ${colors.green}${memCount}${RESET} memories`);\n extracted++;\n } else {\n writeLine(` ${colors.red}${icons.error}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.red}Failed: ${mem0Response.status}${RESET}`);\n failed++;\n }\n } catch (err) {\n writeLine(` ${colors.red}${icons.error}${RESET} ${colors.dim}${sessionId.slice(0, 8)}${RESET} ${colors.red}Error: ${err}${RESET}`);\n failed++;\n }\n }\n\n writeLine();\n if (failed === 0) {\n writeLine(` ${colors.green}${icons.success}${RESET} Extracted memories from ${extracted} sessions`);\n } else {\n writeLine(` ${colors.yellow}${icons.warning}${RESET} Extracted: ${extracted}, Failed: ${failed}`);\n }\n writeLine();\n\n // Show next steps\n writeLine(` ${colors.dim}$${RESET} squads memory query ${colors.cyan}\"<term>\"${RESET} ${colors.dim}Search extracted memories${RESET}`);\n writeLine();\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('fetch failed')) {\n // Check which service is down\n const bridgeOk = await checkServiceAvailable('bridge', false);\n const mem0Ok = await checkServiceAvailable('mem0', false);\n\n if (!bridgeOk) {\n showServiceSetupGuide('bridge', 'not responding');\n } else if (!mem0Ok) {\n showServiceSetupGuide('mem0', 'not responding');\n } else {\n writeLine(` ${colors.red}Error: ${errorMessage}${RESET}`);\n writeLine();\n }\n } else {\n writeLine(` ${colors.red}Error: ${errorMessage}${RESET}`);\n writeLine();\n }\n }\n}\n"],"mappings":"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","names":[]}
|