squads-cli 0.2.1 → 0.2.2
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/dist/{autonomy-PSVZVX7A.js → autonomy-GARI6J2J.js} +4 -4
- package/dist/chunk-NP5BDPE6.js +240 -0
- package/dist/chunk-NP5BDPE6.js.map +1 -0
- package/dist/chunk-O632SBON.js +62 -0
- package/dist/chunk-O632SBON.js.map +1 -0
- package/dist/{chunk-QHNUMM4V.js → chunk-QRNR4GIT.js} +3 -2
- package/dist/chunk-QRNR4GIT.js.map +1 -0
- package/dist/chunk-XTHZT53Y.js +364 -0
- package/dist/chunk-XTHZT53Y.js.map +1 -0
- package/dist/cli.js +1026 -88
- package/dist/cli.js.map +1 -1
- package/dist/{context-GWPF4SEY.js → context-PYTO2UQG.js} +7 -7
- package/dist/{context-feed-AJGVAR6H.js → context-feed-TLVZZ24S.js} +15 -15
- package/dist/{cost-XBCDJ7XC.js → cost-OALPURUQ.js} +7 -7
- package/dist/{dashboard-LGT2B2BL.js → dashboard-HQIEHTZC.js} +14 -14
- package/dist/{doctor-XPUIIBHJ.js → doctor-TWHMR23W.js} +4 -4
- package/dist/{exec-OUXM7JBF.js → exec-DYLI4TXY.js} +2 -2
- package/dist/{feedback-KNAOG5QK.js → feedback-5AEACUX6.js} +8 -8
- package/dist/{goal-BVHV5573.js → goal-XUNV3CKV.js} +8 -8
- package/dist/{health-4UXN44PF.js → health-ZF3HSA4W.js} +4 -4
- package/dist/{history-ILH3SWHB.js → history-WP6R5BNG.js} +5 -5
- package/dist/history-WP6R5BNG.js.map +1 -0
- package/dist/{init-XQZ7BOGT.js → init-BQSCG57S.js} +115 -6
- package/dist/init-BQSCG57S.js.map +1 -0
- package/dist/{kpi-RQIU7WGK.js → kpi-VBGDO4GI.js} +6 -6
- package/dist/{learn-OIFUVZAS.js → learn-C4B2PQ5J.js} +8 -8
- package/dist/{login-DXZANWZY.js → login-F6ITE7PR.js} +7 -7
- package/dist/{memory-T3ACCS7E.js → memory-33HYD6AN.js} +11 -11
- package/dist/observability-CL23L7LD.js +20 -0
- package/dist/observability-CL23L7LD.js.map +1 -0
- package/dist/org-cycle-Q74OT4I4.js +130 -0
- package/dist/org-cycle-Q74OT4I4.js.map +1 -0
- package/dist/{progress-DAUZMT3N.js → progress-P2EIZBKP.js} +5 -5
- package/dist/{providers-3P5D2XL5.js → providers-LE744DM6.js} +2 -2
- package/dist/repo-enforcement-JJQMKDAU.js +75 -0
- package/dist/repo-enforcement-JJQMKDAU.js.map +1 -0
- package/dist/{results-UECWGLTB.js → results-6TH33HPN.js} +6 -6
- package/dist/{run-I6KAXU6U.js → run-DOY5SGF3.js} +3713 -3688
- package/dist/run-DOY5SGF3.js.map +1 -0
- package/dist/run-context-GB6GUCKZ.js +26 -0
- package/dist/run-context-GB6GUCKZ.js.map +1 -0
- package/dist/{status-AQNLDZVN.js → status-PFFB2NV6.js} +16 -16
- package/dist/{sync-ZI3MHA4G.js → sync-FR6LQJ4C.js} +12 -12
- package/dist/templates/seed/config/SYSTEM.md +6 -0
- package/dist/templates/seed/idp/catalog/service.yaml.template +25 -0
- package/dist/templates/seed/memory/_squad/goals.md +23 -0
- package/dist/templates/seed/memory/_squad/priorities.md +25 -0
- package/dist/templates/seed/memory/company/company.md +31 -0
- package/dist/templates/seed/skills/squads-cli/SKILL.md +302 -57
- package/dist/templates/seed/skills/squads-cli/references/commands.md +181 -0
- package/dist/templates/seed/squads/company/company-critic.md +12 -4
- package/dist/templates/seed/squads/company/company-eval.md +12 -4
- package/dist/templates/seed/squads/company/event-dispatcher.md +14 -4
- package/dist/templates/seed/squads/company/goal-tracker.md +12 -4
- package/dist/templates/seed/squads/company/manager.md +17 -11
- package/dist/templates/seed/squads/engineering/code-reviewer.md +14 -2
- package/dist/templates/seed/squads/engineering/issue-solver.md +10 -2
- package/dist/templates/seed/squads/engineering/test-writer.md +15 -5
- package/dist/templates/seed/squads/intelligence/intel-critic.md +19 -2
- package/dist/templates/seed/squads/intelligence/intel-eval.md +18 -1
- package/dist/templates/seed/squads/intelligence/intel-lead.md +12 -4
- package/dist/templates/seed/squads/marketing/content-drafter.md +14 -4
- package/dist/templates/seed/squads/marketing/growth-analyst.md +14 -2
- package/dist/templates/seed/squads/marketing/social-poster.md +15 -3
- package/dist/templates/seed/squads/operations/finance-tracker.md +11 -3
- package/dist/templates/seed/squads/operations/goal-tracker.md +14 -2
- package/dist/templates/seed/squads/operations/ops-lead.md +14 -4
- package/dist/templates/seed/squads/product/lead.md +11 -3
- package/dist/templates/seed/squads/product/scanner.md +12 -4
- package/dist/templates/seed/squads/product/worker.md +12 -4
- package/dist/templates/seed/squads/research/analyst.md +12 -4
- package/dist/templates/seed/squads/research/lead.md +11 -5
- package/dist/templates/seed/squads/research/synthesizer.md +12 -4
- package/dist/tier-detect-YX2HPNNR.js +15 -0
- package/dist/tier-detect-YX2HPNNR.js.map +1 -0
- package/package.json +1 -1
- package/templates/seed/config/SYSTEM.md +6 -0
- package/templates/seed/idp/catalog/service.yaml.template +25 -0
- package/templates/seed/memory/_squad/goals.md +23 -0
- package/templates/seed/memory/_squad/priorities.md +25 -0
- package/templates/seed/memory/company/company.md +31 -0
- package/templates/seed/skills/squads-cli/SKILL.md +302 -57
- package/templates/seed/skills/squads-cli/references/commands.md +181 -0
- package/templates/seed/squads/company/company-critic.md +12 -4
- package/templates/seed/squads/company/company-eval.md +12 -4
- package/templates/seed/squads/company/event-dispatcher.md +14 -4
- package/templates/seed/squads/company/goal-tracker.md +12 -4
- package/templates/seed/squads/company/manager.md +17 -11
- package/templates/seed/squads/engineering/code-reviewer.md +14 -2
- package/templates/seed/squads/engineering/issue-solver.md +10 -2
- package/templates/seed/squads/engineering/test-writer.md +15 -5
- package/templates/seed/squads/intelligence/intel-critic.md +19 -2
- package/templates/seed/squads/intelligence/intel-eval.md +18 -1
- package/templates/seed/squads/intelligence/intel-lead.md +12 -4
- package/templates/seed/squads/marketing/content-drafter.md +14 -4
- package/templates/seed/squads/marketing/growth-analyst.md +14 -2
- package/templates/seed/squads/marketing/social-poster.md +15 -3
- package/templates/seed/squads/operations/finance-tracker.md +11 -3
- package/templates/seed/squads/operations/goal-tracker.md +14 -2
- package/templates/seed/squads/operations/ops-lead.md +14 -4
- package/templates/seed/squads/product/lead.md +11 -3
- package/templates/seed/squads/product/scanner.md +12 -4
- package/templates/seed/squads/product/worker.md +12 -4
- package/templates/seed/squads/research/analyst.md +12 -4
- package/templates/seed/squads/research/lead.md +11 -5
- package/templates/seed/squads/research/synthesizer.md +12 -4
- package/dist/chunk-QHNUMM4V.js.map +0 -1
- package/dist/history-ILH3SWHB.js.map +0 -1
- package/dist/init-XQZ7BOGT.js.map +0 -1
- package/dist/run-I6KAXU6U.js.map +0 -1
- /package/dist/{autonomy-PSVZVX7A.js.map → autonomy-GARI6J2J.js.map} +0 -0
- /package/dist/{context-GWPF4SEY.js.map → context-PYTO2UQG.js.map} +0 -0
- /package/dist/{context-feed-AJGVAR6H.js.map → context-feed-TLVZZ24S.js.map} +0 -0
- /package/dist/{cost-XBCDJ7XC.js.map → cost-OALPURUQ.js.map} +0 -0
- /package/dist/{dashboard-LGT2B2BL.js.map → dashboard-HQIEHTZC.js.map} +0 -0
- /package/dist/{doctor-XPUIIBHJ.js.map → doctor-TWHMR23W.js.map} +0 -0
- /package/dist/{exec-OUXM7JBF.js.map → exec-DYLI4TXY.js.map} +0 -0
- /package/dist/{feedback-KNAOG5QK.js.map → feedback-5AEACUX6.js.map} +0 -0
- /package/dist/{goal-BVHV5573.js.map → goal-XUNV3CKV.js.map} +0 -0
- /package/dist/{health-4UXN44PF.js.map → health-ZF3HSA4W.js.map} +0 -0
- /package/dist/{kpi-RQIU7WGK.js.map → kpi-VBGDO4GI.js.map} +0 -0
- /package/dist/{learn-OIFUVZAS.js.map → learn-C4B2PQ5J.js.map} +0 -0
- /package/dist/{login-DXZANWZY.js.map → login-F6ITE7PR.js.map} +0 -0
- /package/dist/{memory-T3ACCS7E.js.map → memory-33HYD6AN.js.map} +0 -0
- /package/dist/{progress-DAUZMT3N.js.map → progress-P2EIZBKP.js.map} +0 -0
- /package/dist/{providers-3P5D2XL5.js.map → providers-LE744DM6.js.map} +0 -0
- /package/dist/{results-UECWGLTB.js.map → results-6TH33HPN.js.map} +0 -0
- /package/dist/{status-AQNLDZVN.js.map → status-PFFB2NV6.js.map} +0 -0
- /package/dist/{sync-ZI3MHA4G.js.map → sync-FR6LQJ4C.js.map} +0 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
RESET,
|
|
4
|
+
colors,
|
|
5
|
+
writeLine
|
|
6
|
+
} from "./chunk-M5FXNY6Y.js";
|
|
7
|
+
import {
|
|
8
|
+
findMemoryDir
|
|
9
|
+
} from "./chunk-ZTQ7ISUR.js";
|
|
10
|
+
import {
|
|
11
|
+
findSquadsDir
|
|
12
|
+
} from "./chunk-TYFTF53O.js";
|
|
13
|
+
|
|
14
|
+
// src/lib/run-context.ts
|
|
15
|
+
import { join, dirname } from "path";
|
|
16
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
17
|
+
import { execSync } from "child_process";
|
|
18
|
+
var ROLE_BUDGETS = {
|
|
19
|
+
scanner: 4e3,
|
|
20
|
+
// ~1000 tokens — company + priorities + goals + agent + state
|
|
21
|
+
worker: 12e3,
|
|
22
|
+
// ~3000 tokens — + feedback
|
|
23
|
+
lead: 24e3,
|
|
24
|
+
// ~6000 tokens — all layers
|
|
25
|
+
coo: 32e3,
|
|
26
|
+
// ~8000 tokens — all layers + expanded
|
|
27
|
+
verifier: 12e3
|
|
28
|
+
// similar needs to worker
|
|
29
|
+
};
|
|
30
|
+
var ROLE_SECTIONS = {
|
|
31
|
+
scanner: /* @__PURE__ */ new Set([1, 2, 3, 4, 5]),
|
|
32
|
+
// identity + focus + role + memory
|
|
33
|
+
worker: /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6]),
|
|
34
|
+
// + feedback
|
|
35
|
+
lead: /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6, 7, 8]),
|
|
36
|
+
// + daily briefing + cross-squad
|
|
37
|
+
coo: /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6, 7, 8]),
|
|
38
|
+
// all layers + expanded budget
|
|
39
|
+
verifier: /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 6])
|
|
40
|
+
// same as worker
|
|
41
|
+
};
|
|
42
|
+
function parseAgentFrontmatter(agentPath) {
|
|
43
|
+
if (!agentPath || !existsSync(agentPath)) return {};
|
|
44
|
+
let content;
|
|
45
|
+
try {
|
|
46
|
+
content = readFileSync(agentPath, "utf-8");
|
|
47
|
+
} catch {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
if (!content) return {};
|
|
51
|
+
const lines = content.split("\n");
|
|
52
|
+
let inFrontmatter = false;
|
|
53
|
+
const yamlLines = [];
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
if (line.trim() === "---") {
|
|
56
|
+
if (inFrontmatter) break;
|
|
57
|
+
inFrontmatter = true;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (inFrontmatter) {
|
|
61
|
+
yamlLines.push(line);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (yamlLines.length === 0) return {};
|
|
65
|
+
const yaml = yamlLines.join("\n");
|
|
66
|
+
const result = {};
|
|
67
|
+
const contextMatch = yaml.match(/context_from:\s*\[([^\]]+)\]/);
|
|
68
|
+
if (contextMatch) {
|
|
69
|
+
result.context_from = contextMatch[1].split(",").map((s) => s.trim());
|
|
70
|
+
}
|
|
71
|
+
const criteriaMatch = yaml.match(/acceptance_criteria:\s*\|\n((?:\s+.+\n?)*)/);
|
|
72
|
+
if (criteriaMatch) {
|
|
73
|
+
result.acceptance_criteria = criteriaMatch[1].replace(/^ {2}/gm, "").trim();
|
|
74
|
+
}
|
|
75
|
+
const retriesMatch = yaml.match(/max_retries:\s*(\d+)/);
|
|
76
|
+
if (retriesMatch) {
|
|
77
|
+
result.max_retries = parseInt(retriesMatch[1], 10);
|
|
78
|
+
}
|
|
79
|
+
const cooldownMatch = yaml.match(/cooldown:\s*["']?([^"'\n]+)["']?/);
|
|
80
|
+
if (cooldownMatch) {
|
|
81
|
+
result.cooldown = cooldownMatch[1].trim();
|
|
82
|
+
}
|
|
83
|
+
for (const line of yamlLines) {
|
|
84
|
+
const trimmed = line.trim();
|
|
85
|
+
if (!trimmed.startsWith("role:")) continue;
|
|
86
|
+
let value = trimmed.slice("role:".length).trim();
|
|
87
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
88
|
+
value = value.slice(1, -1).trim();
|
|
89
|
+
}
|
|
90
|
+
if (value) {
|
|
91
|
+
result.agent_role = value;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
function extractMcpServersFromDefinition(definition) {
|
|
98
|
+
const servers = /* @__PURE__ */ new Set();
|
|
99
|
+
const knownServers = [
|
|
100
|
+
"chrome-devtools",
|
|
101
|
+
"firecrawl",
|
|
102
|
+
"context7",
|
|
103
|
+
"huggingface"
|
|
104
|
+
];
|
|
105
|
+
for (const server of knownServers) {
|
|
106
|
+
if (definition.toLowerCase().includes(server)) {
|
|
107
|
+
servers.add(server);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const mcpMatch = definition.match(/mcp:\s*\n((?:\s*-\s*\S+\s*\n?)+)/i);
|
|
111
|
+
if (mcpMatch) {
|
|
112
|
+
const lines = mcpMatch[1].split("\n");
|
|
113
|
+
for (const line of lines) {
|
|
114
|
+
const serverMatch = line.match(/^\s*-\s*(\S+)/);
|
|
115
|
+
if (serverMatch) {
|
|
116
|
+
servers.add(serverMatch[1]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return Array.from(servers);
|
|
121
|
+
}
|
|
122
|
+
function readAgentsFile(relativePath, warnLabel) {
|
|
123
|
+
const squadsDir = findSquadsDir();
|
|
124
|
+
if (!squadsDir) return "";
|
|
125
|
+
const filePath = join(dirname(squadsDir), relativePath);
|
|
126
|
+
if (!existsSync(filePath)) return "";
|
|
127
|
+
try {
|
|
128
|
+
return readFileSync(filePath, "utf-8").trim();
|
|
129
|
+
} catch (e) {
|
|
130
|
+
writeLine(` ${colors.dim}warn: failed reading ${warnLabel}: ${e instanceof Error ? e.message : String(e)}${RESET}`);
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function loadSystemProtocol() {
|
|
135
|
+
const systemMd = readAgentsFile("SYSTEM.md", "SYSTEM.md");
|
|
136
|
+
if (systemMd) return systemMd;
|
|
137
|
+
const legacyMd = readAgentsFile("config/SYSTEM.md", "SYSTEM.md (legacy)");
|
|
138
|
+
if (legacyMd) return legacyMd;
|
|
139
|
+
return loadApprovalInstructions();
|
|
140
|
+
}
|
|
141
|
+
function loadCompanyContext() {
|
|
142
|
+
const companyMd = readAgentsFile("company.md", "company.md");
|
|
143
|
+
if (companyMd) return companyMd;
|
|
144
|
+
const memoryDir = findMemoryDir();
|
|
145
|
+
if (memoryDir) {
|
|
146
|
+
const directivesFile = join(memoryDir, "company", "directives.md");
|
|
147
|
+
const content = safeRead(directivesFile);
|
|
148
|
+
if (content) return content;
|
|
149
|
+
}
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
function loadApprovalInstructions() {
|
|
153
|
+
return readAgentsFile("config/approval-instructions.md", "approval instructions");
|
|
154
|
+
}
|
|
155
|
+
function loadPostExecution(squadName, agentName) {
|
|
156
|
+
const template = readAgentsFile("config/post-execution.md", "post-execution template");
|
|
157
|
+
if (template) {
|
|
158
|
+
return template.replace(/\{\{squadName\}\}/g, squadName).replace(/\{\{agentName\}\}/g, agentName);
|
|
159
|
+
}
|
|
160
|
+
return "";
|
|
161
|
+
}
|
|
162
|
+
function safeRead(path) {
|
|
163
|
+
try {
|
|
164
|
+
return existsSync(path) ? readFileSync(path, "utf-8").trim() : "";
|
|
165
|
+
} catch {
|
|
166
|
+
return "";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function stripYamlFrontmatter(markdown) {
|
|
170
|
+
const lines = markdown.split("\n");
|
|
171
|
+
let dashCount = 0;
|
|
172
|
+
let endIdx = -1;
|
|
173
|
+
for (let i = 0; i < lines.length; i++) {
|
|
174
|
+
if (lines[i].trim() === "---") {
|
|
175
|
+
dashCount++;
|
|
176
|
+
if (dashCount === 2) {
|
|
177
|
+
endIdx = i;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (endIdx >= 0) return lines.slice(endIdx + 1).join("\n").trim();
|
|
183
|
+
return markdown.trim();
|
|
184
|
+
}
|
|
185
|
+
function scoreByTokens(text, tokens) {
|
|
186
|
+
const lower = text.toLowerCase();
|
|
187
|
+
let score = 0;
|
|
188
|
+
for (const t of tokens) {
|
|
189
|
+
if (!t) continue;
|
|
190
|
+
if (lower.includes(t)) score += 1;
|
|
191
|
+
}
|
|
192
|
+
return score;
|
|
193
|
+
}
|
|
194
|
+
function resolveContextRoleFromAgent(agentPath, agentName) {
|
|
195
|
+
const fm = parseAgentFrontmatter(agentPath);
|
|
196
|
+
const roleText = fm.agent_role || "";
|
|
197
|
+
const normalized = roleText.trim().toLowerCase();
|
|
198
|
+
const directRoles = ["scanner", "worker", "lead", "verifier"];
|
|
199
|
+
for (const r of directRoles) {
|
|
200
|
+
if (normalized === r) return r;
|
|
201
|
+
}
|
|
202
|
+
if (normalized === "coo") return "coo";
|
|
203
|
+
const scannerTokens = ["scan", "monitor", "detect", "find", "opportun", "scout", "gap", "bottleneck"];
|
|
204
|
+
const workerTokens = ["execute", "implement", "write", "create", "build", "prototype", "file", "issue", "worker"];
|
|
205
|
+
const leadTokens = ["lead", "orchestrate", "own", "strategy", "roadmap", "coordinate", "triage", "review", "mvp"];
|
|
206
|
+
const verifierTokens = ["verify", "validation", "compliance", "audit", "approve", "reject", "check", "test", "critic", "verifier"];
|
|
207
|
+
const scored = [
|
|
208
|
+
["scanner", scoreByTokens(normalized, scannerTokens)],
|
|
209
|
+
["worker", scoreByTokens(normalized, workerTokens)],
|
|
210
|
+
["lead", scoreByTokens(normalized, leadTokens)],
|
|
211
|
+
["verifier", scoreByTokens(normalized, verifierTokens)]
|
|
212
|
+
];
|
|
213
|
+
scored.sort((a, b) => b[1] - a[1]);
|
|
214
|
+
const best = scored[0];
|
|
215
|
+
const second = scored[1];
|
|
216
|
+
const clean = best[1] > 0 && (!second || second[1] === 0);
|
|
217
|
+
if (clean) return best[0];
|
|
218
|
+
const llmEnabled = process.env.SQUADS_CONTEXT_ROLE_LLM === "1";
|
|
219
|
+
if (!llmEnabled) return "worker";
|
|
220
|
+
try {
|
|
221
|
+
const raw = safeRead(agentPath);
|
|
222
|
+
const body = stripYamlFrontmatter(raw);
|
|
223
|
+
const excerpt = body.slice(0, 1600);
|
|
224
|
+
const prompt = [
|
|
225
|
+
"Classify the agent into exactly ONE Agents Squads context role.",
|
|
226
|
+
"Return EXACTLY one token from: scanner, worker, lead, verifier.",
|
|
227
|
+
"",
|
|
228
|
+
`Agent name: ${agentName}`,
|
|
229
|
+
`Agent frontmatter role: ${roleText || "(missing)"}`,
|
|
230
|
+
"",
|
|
231
|
+
"Agent definition excerpt:",
|
|
232
|
+
excerpt
|
|
233
|
+
].join("\n");
|
|
234
|
+
const escapedPrompt = prompt.replace(/'/g, "'\\''");
|
|
235
|
+
const model = process.env.SQUADS_CONTEXT_ROLE_LLM_MODEL || "claude-haiku-4-5";
|
|
236
|
+
const out = execSync(
|
|
237
|
+
`claude --print --dangerously-skip-permissions --disable-slash-commands --model ${model} -- '${escapedPrompt}'`,
|
|
238
|
+
{ encoding: "utf-8", timeout: 6e4, maxBuffer: 2 * 1024 * 1024 }
|
|
239
|
+
).trim().toLowerCase();
|
|
240
|
+
const tokens = ["scanner", "worker", "lead", "verifier"];
|
|
241
|
+
for (const t of tokens) {
|
|
242
|
+
if (out === t || out.includes(t)) return t;
|
|
243
|
+
}
|
|
244
|
+
return "worker";
|
|
245
|
+
} catch {
|
|
246
|
+
return "worker";
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function gatherSquadContext(squadName, agentName, options = {}) {
|
|
250
|
+
const squadsDir = findSquadsDir();
|
|
251
|
+
if (!squadsDir) return "";
|
|
252
|
+
const memoryDir = findMemoryDir();
|
|
253
|
+
const role = options.role || "worker";
|
|
254
|
+
const budget = options.maxTokens ? options.maxTokens * 4 : ROLE_BUDGETS[role] ?? ROLE_BUDGETS.worker;
|
|
255
|
+
const allowedSections = ROLE_SECTIONS[role] ?? ROLE_SECTIONS.worker;
|
|
256
|
+
const sections = [];
|
|
257
|
+
let usedChars = 0;
|
|
258
|
+
function addLayer(layerNum, header, content, maxChars) {
|
|
259
|
+
if (!allowedSections.has(layerNum)) return false;
|
|
260
|
+
if (!content) return false;
|
|
261
|
+
let text = content;
|
|
262
|
+
const remaining = Math.max(0, budget - usedChars);
|
|
263
|
+
const cap = maxChars !== void 0 ? Math.min(maxChars, remaining) : remaining;
|
|
264
|
+
if (text.length > cap) {
|
|
265
|
+
text = text.substring(0, cap) + "\n...";
|
|
266
|
+
}
|
|
267
|
+
if (usedChars + text.length > budget) {
|
|
268
|
+
if (options.verbose) {
|
|
269
|
+
writeLine(` ${colors.dim}Context budget exhausted at layer ${layerNum} (${header})${RESET}`);
|
|
270
|
+
}
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
sections.push(`## ${header}
|
|
274
|
+
${text}`);
|
|
275
|
+
usedChars += text.length;
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
const companyContext = loadCompanyContext();
|
|
279
|
+
if (companyContext) {
|
|
280
|
+
addLayer(1, "Company", stripYamlFrontmatter(companyContext));
|
|
281
|
+
}
|
|
282
|
+
if (memoryDir) {
|
|
283
|
+
const prioritiesFile = join(memoryDir, squadName, "priorities.md");
|
|
284
|
+
const content = safeRead(prioritiesFile);
|
|
285
|
+
if (content) {
|
|
286
|
+
addLayer(2, "Priorities", stripYamlFrontmatter(content));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (memoryDir) {
|
|
290
|
+
const goalsFile = join(memoryDir, squadName, "goals.md");
|
|
291
|
+
const content = safeRead(goalsFile);
|
|
292
|
+
if (content) {
|
|
293
|
+
addLayer(3, "Goals", stripYamlFrontmatter(content));
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (options.agentPath) {
|
|
297
|
+
const agentContent = safeRead(options.agentPath);
|
|
298
|
+
if (agentContent) {
|
|
299
|
+
const body = stripYamlFrontmatter(agentContent);
|
|
300
|
+
addLayer(4, `Agent: ${agentName}`, body);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (memoryDir) {
|
|
304
|
+
const stateFile = join(memoryDir, squadName, agentName, "state.md");
|
|
305
|
+
const content = safeRead(stateFile);
|
|
306
|
+
if (content) {
|
|
307
|
+
const body = stripYamlFrontmatter(content);
|
|
308
|
+
const stateCap = role === "scanner" || role === "verifier" ? 2e3 : void 0;
|
|
309
|
+
addLayer(5, "Previous State", body, stateCap);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (memoryDir) {
|
|
313
|
+
const feedbackFile = join(memoryDir, squadName, "feedback.md");
|
|
314
|
+
const content = safeRead(feedbackFile);
|
|
315
|
+
if (content) {
|
|
316
|
+
addLayer(6, "Feedback", content);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (memoryDir) {
|
|
320
|
+
const dailyFile = join(memoryDir, "daily-briefing.md");
|
|
321
|
+
const content = safeRead(dailyFile);
|
|
322
|
+
if (content) {
|
|
323
|
+
addLayer(7, "Daily Briefing", content);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (memoryDir) {
|
|
327
|
+
const frontmatter = options.agentPath ? parseAgentFrontmatter(options.agentPath) : {};
|
|
328
|
+
const contextSquads = frontmatter.context_from || [];
|
|
329
|
+
const learningParts = [];
|
|
330
|
+
for (const ctx of contextSquads) {
|
|
331
|
+
const learningsFile = join(memoryDir, ctx, "shared", "learnings.md");
|
|
332
|
+
const content = safeRead(learningsFile);
|
|
333
|
+
if (content) {
|
|
334
|
+
learningParts.push(`### ${ctx}
|
|
335
|
+
${content}`);
|
|
336
|
+
} else if (options.verbose) {
|
|
337
|
+
writeLine(` ${colors.dim}context_from: no learnings found for squad '${ctx}'${RESET}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (learningParts.length > 0) {
|
|
341
|
+
addLayer(8, "Cross-Squad Learnings", learningParts.join("\n\n"));
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (sections.length === 0) return "";
|
|
345
|
+
if (options.verbose) {
|
|
346
|
+
writeLine(` ${colors.dim}Context: ${sections.length} layers, ~${Math.ceil(usedChars / 4)} tokens (${role} role, budget: ~${Math.ceil(budget / 4)})${RESET}`);
|
|
347
|
+
}
|
|
348
|
+
return `
|
|
349
|
+
# CONTEXT
|
|
350
|
+
${sections.join("\n\n")}
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export {
|
|
355
|
+
parseAgentFrontmatter,
|
|
356
|
+
extractMcpServersFromDefinition,
|
|
357
|
+
loadSystemProtocol,
|
|
358
|
+
loadCompanyContext,
|
|
359
|
+
loadApprovalInstructions,
|
|
360
|
+
loadPostExecution,
|
|
361
|
+
resolveContextRoleFromAgent,
|
|
362
|
+
gatherSquadContext
|
|
363
|
+
};
|
|
364
|
+
//# sourceMappingURL=chunk-XTHZT53Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/run-context.ts"],"sourcesContent":["/**\n * run-context.ts\n *\n * Squad Context System — context assembly for agent execution.\n *\n * Layers flow from general to particular (no overrides, each answers a different question):\n * L0: SYSTEM.md — How (system, tools, principles — immutable, outside budget)\n * L1: company.md — Why (company identity, alignment)\n * L2: priorities.md — Where (current focus, urgency)\n * L3: goals.md — What (measurable targets)\n * L4: agent.md — You (agent role, specific instructions)\n * L5: state.md — Memory (continuity from last run)\n * L6+: Supporting — feedback, daily-briefing, cross-squad learnings\n *\n * SQUAD.md is metadata only (repo, agents, config) — NOT injected into prompt.\n * Each layer adds a unique dimension. No layer contradicts another.\n * Role determines which layers are included and the total token budget.\n */\n\nimport { join, dirname } from 'path';\nimport { existsSync, readFileSync, readdirSync } from 'fs';\nimport { execSync } from 'child_process';\nimport { findSquadsDir } from './squad-parser.js';\nimport { findMemoryDir } from './memory.js';\nimport { colors, RESET, writeLine } from './terminal.js';\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport type ContextRole = 'scanner' | 'worker' | 'lead' | 'coo' | 'verifier';\n\n// ── Token Budgets (chars, ~4 chars/token) ────────────────────────────\n\nconst ROLE_BUDGETS: Record<ContextRole, number> = {\n scanner: 4000, // ~1000 tokens — company + priorities + goals + agent + state\n worker: 12000, // ~3000 tokens — + feedback\n lead: 24000, // ~6000 tokens — all layers\n coo: 32000, // ~8000 tokens — all layers + expanded\n verifier: 12000, // similar needs to worker\n};\n\n/**\n * Which layers each role gets access to.\n * Numbers correspond to layer order in the Squad Context System:\n * 1=company, 2=priorities, 3=goals, 4=agent, 5=state, 6=feedback, 7=daily-briefing, 8=cross-squad\n */\nconst ROLE_SECTIONS: Record<ContextRole, Set<number>> = {\n scanner: new Set([1, 2, 3, 4, 5]), // identity + focus + role + memory\n worker: new Set([1, 2, 3, 4, 5, 6]), // + feedback\n lead: new Set([1, 2, 3, 4, 5, 6, 7, 8]), // + daily briefing + cross-squad\n coo: new Set([1, 2, 3, 4, 5, 6, 7, 8]), // all layers + expanded budget\n verifier: new Set([1, 2, 3, 4, 5, 6]), // same as worker\n};\n\n// ── Agent Frontmatter ─────────────────────────────────────────────────\n\n/**\n * Parsed fields from an agent definition's YAML frontmatter.\n */\nexport interface AgentFrontmatter {\n context_from?: string[];\n acceptance_criteria?: string;\n max_retries?: number;\n cooldown?: string;\n /**\n * `role:` field from agent YAML frontmatter (free text).\n * Used as the primary signal for context-role selection.\n */\n agent_role?: string;\n}\n\n/**\n * Parse frontmatter fields from an agent definition file.\n * Handles non-standard format where frontmatter appears after a heading.\n */\nexport function parseAgentFrontmatter(agentPath: string): AgentFrontmatter {\n if (!agentPath || !existsSync(agentPath)) return {};\n\n let content: string;\n try {\n content = readFileSync(agentPath, 'utf-8');\n } catch {\n return {};\n }\n if (!content) return {};\n const lines = content.split('\\n');\n let inFrontmatter = false;\n const yamlLines: string[] = [];\n\n for (const line of lines) {\n if (line.trim() === '---') {\n if (inFrontmatter) break;\n inFrontmatter = true;\n continue;\n }\n if (inFrontmatter) {\n yamlLines.push(line);\n }\n }\n\n if (yamlLines.length === 0) return {};\n\n const yaml = yamlLines.join('\\n');\n const result: AgentFrontmatter = {};\n\n // context_from: [operations, finance, product, growth]\n const contextMatch = yaml.match(/context_from:\\s*\\[([^\\]]+)\\]/);\n if (contextMatch) {\n result.context_from = contextMatch[1].split(',').map(s => s.trim());\n }\n\n // acceptance_criteria: |\\n - criteria1\\n - criteria2\n const criteriaMatch = yaml.match(/acceptance_criteria:\\s*\\|\\n((?:\\s+.+\\n?)*)/);\n if (criteriaMatch) {\n result.acceptance_criteria = criteriaMatch[1].replace(/^ {2}/gm, '').trim();\n }\n\n // max_retries: 2\n const retriesMatch = yaml.match(/max_retries:\\s*(\\d+)/);\n if (retriesMatch) {\n result.max_retries = parseInt(retriesMatch[1], 10);\n }\n\n // cooldown: \"30m\" or \"6h\" or \"2 hours\"\n const cooldownMatch = yaml.match(/cooldown:\\s*[\"']?([^\"'\\n]+)[\"']?/);\n if (cooldownMatch) {\n result.cooldown = cooldownMatch[1].trim();\n }\n\n // role: <free-text>\n // Primary signal for mapping to context role (scanner/worker/lead/verifier).\n for (const line of yamlLines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('role:')) continue;\n let value = trimmed.slice('role:'.length).trim();\n // Strip wrapping quotes if present.\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith('\\'') && value.endsWith('\\''))\n ) {\n value = value.slice(1, -1).trim();\n }\n if (value) {\n result.agent_role = value;\n }\n break;\n }\n\n return result;\n}\n\n// ── MCP Server Discovery ──────────────────────────────────────────────\n\n/**\n * Extract MCP servers mentioned in an agent definition.\n * Looks for patterns like: mcp-server-name, chrome-devtools, firecrawl, etc.\n */\nexport function extractMcpServersFromDefinition(definition: string): string[] {\n const servers: Set<string> = new Set();\n\n // Common MCP server patterns\n const knownServers = [\n 'chrome-devtools',\n 'firecrawl',\n 'context7',\n 'huggingface',\n ];\n\n // Check for known servers in the definition\n for (const server of knownServers) {\n if (definition.toLowerCase().includes(server)) {\n servers.add(server);\n }\n }\n\n // Look for mcp: blocks in YAML\n const mcpMatch = definition.match(/mcp:\\s*\\n((?:\\s*-\\s*\\S+\\s*\\n?)+)/i);\n if (mcpMatch) {\n const lines = mcpMatch[1].split('\\n');\n for (const line of lines) {\n const serverMatch = line.match(/^\\s*-\\s*(\\S+)/);\n if (serverMatch) {\n servers.add(serverMatch[1]);\n }\n }\n }\n\n return Array.from(servers);\n}\n\n// ── Shared Config File Reader ─────────────────────────────────────────\n\n/**\n * Read a config file relative to the .agents directory.\n * Returns file content trimmed, or empty string if missing/unreadable.\n */\nfunction readAgentsFile(relativePath: string, warnLabel: string): string {\n const squadsDir = findSquadsDir();\n if (!squadsDir) return '';\n\n const filePath = join(dirname(squadsDir), relativePath);\n if (!existsSync(filePath)) return '';\n\n try {\n return readFileSync(filePath, 'utf-8').trim();\n } catch (e) {\n writeLine(` ${colors.dim}warn: failed reading ${warnLabel}: ${e instanceof Error ? e.message : String(e)}${RESET}`);\n return '';\n }\n}\n\n// ── System Protocol ───────────────────────────────────────────────────\n\n/**\n * Load SYSTEM.md (L0) — the immutable base protocol for all agents.\n * Path: .agents/SYSTEM.md (top-level, next to squads/ and memory/)\n * Falls back to legacy config/SYSTEM.md, then approval-instructions.md.\n */\nexport function loadSystemProtocol(): string {\n // Primary: .agents/SYSTEM.md\n const systemMd = readAgentsFile('SYSTEM.md', 'SYSTEM.md');\n if (systemMd) return systemMd;\n\n // Fallback: legacy path\n const legacyMd = readAgentsFile('config/SYSTEM.md', 'SYSTEM.md (legacy)');\n if (legacyMd) return legacyMd;\n\n return loadApprovalInstructions();\n}\n\n/**\n * Load company.md (L1) — company context and strategic direction.\n * Path: .agents/company.md\n * This is the \"why\" layer — frames everything that follows.\n */\nexport function loadCompanyContext(): string {\n // Primary: .agents/company.md\n const companyMd = readAgentsFile('company.md', 'company.md');\n if (companyMd) return companyMd;\n\n // Fallback: legacy directives.md (for backward compat during migration)\n const memoryDir = findMemoryDir();\n if (memoryDir) {\n const directivesFile = join(memoryDir, 'company', 'directives.md');\n const content = safeRead(directivesFile);\n if (content) return content;\n }\n\n return '';\n}\n\n/**\n * Legacy: load approval instructions. Kept for backward compat — prefer SYSTEM.md.\n * @deprecated Absorbed into SYSTEM.md. Used as fallback when SYSTEM.md absent.\n */\nexport function loadApprovalInstructions(): string {\n return readAgentsFile('config/approval-instructions.md', 'approval instructions');\n}\n\n/**\n * Legacy: load post-execution instructions.\n * @deprecated Absorbed into SYSTEM.md. Used as fallback when SYSTEM.md absent.\n */\nexport function loadPostExecution(squadName: string, agentName: string): string {\n const template = readAgentsFile('config/post-execution.md', 'post-execution template');\n if (template) {\n return template\n .replace(/\\{\\{squadName\\}\\}/g, squadName)\n .replace(/\\{\\{agentName\\}\\}/g, agentName);\n }\n return '';\n}\n\n// ── Helpers ───────────────────────────────────────────────────────────\n\n/** Safely read a file, returning empty string on failure */\nfunction safeRead(path: string): string {\n try {\n return existsSync(path) ? readFileSync(path, 'utf-8').trim() : '';\n } catch {\n return '';\n }\n}\n\nfunction stripYamlFrontmatter(markdown: string): string {\n const lines = markdown.split('\\n');\n let dashCount = 0;\n let endIdx = -1;\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n dashCount++;\n if (dashCount === 2) {\n endIdx = i;\n break;\n }\n }\n }\n if (endIdx >= 0) return lines.slice(endIdx + 1).join('\\n').trim();\n return markdown.trim();\n}\n\nfunction scoreByTokens(text: string, tokens: string[]): number {\n const lower = text.toLowerCase();\n let score = 0;\n for (const t of tokens) {\n if (!t) continue;\n if (lower.includes(t)) score += 1;\n }\n return score;\n}\n\n/**\n * Primary context-role resolver.\n *\n * Uses the agent YAML frontmatter `role:` free-text as the signal.\n * Only when ambiguous and enabled (env var) will it ask an LLM to pick\n * one of: scanner | worker | lead | verifier.\n */\nexport function resolveContextRoleFromAgent(agentPath: string, agentName: string): ContextRole {\n const fm = parseAgentFrontmatter(agentPath);\n const roleText = fm.agent_role || '';\n const normalized = roleText.trim().toLowerCase();\n\n // Direct match — new structured schema uses exact role values\n const directRoles: ContextRole[] = ['scanner', 'worker', 'lead', 'verifier'];\n for (const r of directRoles) {\n if (normalized === r) return r;\n }\n // COO is a lead with expanded budget\n if (normalized === 'coo') return 'coo';\n\n // Deterministic mapping from role text. Avoids brittle regex coupling.\n const scannerTokens = ['scan', 'monitor', 'detect', 'find', 'opportun', 'scout', 'gap', 'bottleneck'];\n const workerTokens = ['execute', 'implement', 'write', 'create', 'build', 'prototype', 'file', 'issue', 'worker'];\n const leadTokens = ['lead', 'orchestrate', 'own', 'strategy', 'roadmap', 'coordinate', 'triage', 'review', 'mvp'];\n const verifierTokens = ['verify', 'validation', 'compliance', 'audit', 'approve', 'reject', 'check', 'test', 'critic', 'verifier'];\n\n const scored: Array<[ContextRole, number]> = [\n ['scanner', scoreByTokens(normalized, scannerTokens)],\n ['worker', scoreByTokens(normalized, workerTokens)],\n ['lead', scoreByTokens(normalized, leadTokens)],\n ['verifier', scoreByTokens(normalized, verifierTokens)],\n ];\n\n scored.sort((a, b) => b[1] - a[1]);\n const best = scored[0];\n const second = scored[1];\n\n // Clean mapping => unique non-zero best score.\n const clean = best[1] > 0 && (!second || second[1] === 0);\n if (clean) return best[0];\n\n const llmEnabled = process.env.SQUADS_CONTEXT_ROLE_LLM === '1';\n if (!llmEnabled) return 'worker';\n\n // LLM fallback: best-effort classification. If it fails, return worker.\n try {\n const raw = safeRead(agentPath);\n const body = stripYamlFrontmatter(raw);\n const excerpt = body.slice(0, 1600);\n\n const prompt = [\n 'Classify the agent into exactly ONE Agents Squads context role.',\n 'Return EXACTLY one token from: scanner, worker, lead, verifier.',\n '',\n `Agent name: ${agentName}`,\n `Agent frontmatter role: ${roleText || '(missing)'}`,\n '',\n 'Agent definition excerpt:',\n excerpt,\n ].join('\\n');\n\n const escapedPrompt = prompt.replace(/'/g, \"'\\\\''\");\n const model = process.env.SQUADS_CONTEXT_ROLE_LLM_MODEL || 'claude-haiku-4-5';\n const out = execSync(\n `claude --print --dangerously-skip-permissions --disable-slash-commands --model ${model} -- '${escapedPrompt}'`,\n { encoding: 'utf-8', timeout: 60_000, maxBuffer: 2 * 1024 * 1024 }\n ).trim().toLowerCase();\n\n const tokens: ContextRole[] = ['scanner', 'worker', 'lead', 'verifier'];\n for (const t of tokens) {\n if (out === t || out.includes(t)) return t;\n }\n\n return 'worker';\n } catch {\n return 'worker';\n }\n}\n\n/** Read all .md files from a directory, concatenated */\nfunction readDirMd(dirPath: string, maxChars: number): string {\n if (!existsSync(dirPath)) return '';\n try {\n const files = readdirSync(dirPath).filter(f => f.endsWith('.md')).sort();\n const parts: string[] = [];\n let totalChars = 0;\n for (const file of files) {\n const content = safeRead(join(dirPath, file));\n if (!content) continue;\n if (totalChars + content.length > maxChars) break;\n parts.push(content);\n totalChars += content.length;\n }\n return parts.join('\\n\\n');\n } catch {\n return '';\n }\n}\n\n// ── Squad Context System Assembly ─────────────────────────────────────\n\n/**\n * Gather context for agent execution.\n *\n * Layers flow general → particular (each adds a unique dimension):\n * 1. company.md — Why (company identity, alignment)\n * 2. priorities.md — Where (current focus, urgency)\n * 3. goals.md — What (measurable targets)\n * 4. agent.md — You (agent role, instructions)\n * 5. state.md — Memory (continuity from last run)\n * 6. feedback.md — Supporting (squad feedback)\n * 7. daily-briefing — Supporting (org pulse, leads+coo only)\n * 8. cross-squad — Supporting (learnings from other squads)\n *\n * SQUAD.md is NOT injected — it's metadata for the CLI (repo, agents, config).\n * Missing files are skipped gracefully — no crashes on first run or new squads.\n */\nexport function gatherSquadContext(\n squadName: string,\n agentName: string,\n options: { verbose?: boolean; maxTokens?: number; agentPath?: string; role?: ContextRole } = {}\n): string {\n const squadsDir = findSquadsDir();\n if (!squadsDir) return '';\n\n const memoryDir = findMemoryDir();\n const role = options.role || 'worker';\n const budget = options.maxTokens ? options.maxTokens * 4 : (ROLE_BUDGETS[role] ?? ROLE_BUDGETS.worker);\n const allowedSections = ROLE_SECTIONS[role] ?? ROLE_SECTIONS.worker;\n const sections: string[] = [];\n let usedChars = 0;\n\n /** Try to add a layer. Returns true if added, false if budget exceeded or not allowed. */\n function addLayer(layerNum: number, header: string, content: string, maxChars?: number): boolean {\n if (!allowedSections.has(layerNum)) return false;\n if (!content) return false;\n\n let text = content;\n const remaining = Math.max(0, budget - usedChars);\n const cap = maxChars !== undefined ? Math.min(maxChars, remaining) : remaining;\n if (text.length > cap) {\n text = text.substring(0, cap) + '\\n...';\n }\n\n if (usedChars + text.length > budget) {\n if (options.verbose) {\n writeLine(` ${colors.dim}Context budget exhausted at layer ${layerNum} (${header})${RESET}`);\n }\n return false;\n }\n\n sections.push(`## ${header}\\n${text}`);\n usedChars += text.length;\n return true;\n }\n\n // ── L1: company.md — Why (company identity, alignment) ──\n const companyContext = loadCompanyContext();\n if (companyContext) {\n addLayer(1, 'Company', stripYamlFrontmatter(companyContext));\n }\n\n // ── L2: priorities.md — Where (current focus, urgency) ──\n if (memoryDir) {\n const prioritiesFile = join(memoryDir, squadName, 'priorities.md');\n const content = safeRead(prioritiesFile);\n if (content) {\n addLayer(2, 'Priorities', stripYamlFrontmatter(content));\n }\n }\n\n // ── L3: goals.md — What (measurable targets) ──\n if (memoryDir) {\n const goalsFile = join(memoryDir, squadName, 'goals.md');\n const content = safeRead(goalsFile);\n if (content) {\n addLayer(3, 'Goals', stripYamlFrontmatter(content));\n }\n }\n\n // ── L4: agent.md — You (agent role, instructions) ──\n if (options.agentPath) {\n const agentContent = safeRead(options.agentPath);\n if (agentContent) {\n // Strip YAML frontmatter — inject the markdown body only\n const body = stripYamlFrontmatter(agentContent);\n addLayer(4, `Agent: ${agentName}`, body);\n }\n }\n\n // ── L5: state.md — Memory (continuity from last run) ──\n if (memoryDir) {\n const stateFile = join(memoryDir, squadName, agentName, 'state.md');\n const content = safeRead(stateFile);\n if (content) {\n // Strip frontmatter — LLM gets the body (Current/Blockers/Carry Forward)\n const body = stripYamlFrontmatter(content);\n const stateCap = (role === 'scanner' || role === 'verifier') ? 2000 : undefined;\n addLayer(5, 'Previous State', body, stateCap);\n }\n }\n\n // ── L6: feedback.md — Supporting (squad-level feedback) ──\n if (memoryDir) {\n const feedbackFile = join(memoryDir, squadName, 'feedback.md');\n const content = safeRead(feedbackFile);\n if (content) {\n addLayer(6, 'Feedback', content);\n }\n }\n\n // ── L7: Daily briefing — Supporting (org pulse, leads+coo only) ──\n if (memoryDir) {\n const dailyFile = join(memoryDir, 'daily-briefing.md');\n const content = safeRead(dailyFile);\n if (content) {\n addLayer(7, 'Daily Briefing', content);\n }\n }\n\n // ── L8: Cross-squad learnings — Supporting (from context_from agents) ──\n if (memoryDir) {\n const frontmatter = options.agentPath ? parseAgentFrontmatter(options.agentPath) : {};\n const contextSquads = frontmatter.context_from || [];\n const learningParts: string[] = [];\n for (const ctx of contextSquads) {\n const learningsFile = join(memoryDir, ctx, 'shared', 'learnings.md');\n const content = safeRead(learningsFile);\n if (content) {\n learningParts.push(`### ${ctx}\\n${content}`);\n } else if (options.verbose) {\n writeLine(` ${colors.dim}context_from: no learnings found for squad '${ctx}'${RESET}`);\n }\n }\n if (learningParts.length > 0) {\n addLayer(8, 'Cross-Squad Learnings', learningParts.join('\\n\\n'));\n }\n }\n\n if (sections.length === 0) return '';\n\n if (options.verbose) {\n writeLine(` ${colors.dim}Context: ${sections.length} layers, ~${Math.ceil(usedChars / 4)} tokens (${role} role, budget: ~${Math.ceil(budget / 4)})${RESET}`);\n }\n\n return `\\n# CONTEXT\\n${sections.join('\\n\\n')}\\n`;\n}\n"],"mappings":"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","names":[]}
|