Skip to content

Commit 610cf2a

Browse files
yethikrishnaclaude
andcommitted
feat: swarm enhancements, memory bible, compliance logging, MCP support
Major features added: - Human-vetted "Bible" memory system with pending/approved/rejected entries - Swarm-of-Swarms hierarchical coordinator for parallel epics - MCP Native Support - expose tools via Model Context Protocol - Compliance logging with cryptographic signing (HMAC-SHA256/512, RSA) - Circuit breakers for fault tolerance - Timeout detection and management - Shadow deployments for safe testing - Diff logging for code change tracking - Dependency graph for task visualization - Worktree isolation per agent - Token budget management - Reviewer swarm with adversarial multi-round review - Knowledge primer for agent context - Reflection rituals for post-milestone review - Handoff pack generation for human takeover - Swarm persona presets (security-auditor, style-maintainer, etc.) Also includes: - Provider detection fixes (HTTP 404, API key propagation) - Auto-detect environment improvements - Multiple new CLI commands for bible management - Dashboard and visualization utilities Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 85d43ff commit 610cf2a

169 files changed

Lines changed: 38568 additions & 633 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CUserskkvintest-output.txt

Lines changed: 0 additions & 565 deletions
This file was deleted.

INTEGRATION-PLAN.md

Lines changed: 551 additions & 0 deletions
Large diffs are not rendered by default.

assets/levelcode-readme-banner.png

-118 KB
Binary file not shown.
-335 KB
Binary file not shown.
-21.2 KB
Binary file not shown.

assets/multi-agents.png

-23.8 KB
Binary file not shown.

cli/src/commands/bible.ts

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
import {
2+
approveEntry,
3+
rejectEntry,
4+
deleteEntry,
5+
editEntry,
6+
getApprovedEntries,
7+
getPendingEntries,
8+
findEntry,
9+
getBibleStats,
10+
formatBibleStats,
11+
formatEntryList,
12+
getBibleContext,
13+
toggleAutoResearch,
14+
isAutoResearchEnabled,
15+
createEntry,
16+
type BibleEntryType,
17+
} from '@levelcode/common/utils/memory-bible'
18+
import { resolveActiveTeam } from './command-registry'
19+
20+
// ============================================================================
21+
// Bible:pending — List pending entries
22+
// ============================================================================
23+
24+
export async function handleBiblePending(teamName?: string): Promise<string> {
25+
const team = teamName || resolveActiveTeam()?.name
26+
if (!team) return 'No active team. Use /team:create first.'
27+
28+
const pending = getPendingEntries(team)
29+
if (pending.length === 0) {
30+
return 'No pending bible entries. All caught up!'
31+
}
32+
33+
return `=== Pending Bible Entries (${pending.length}) ===\n\n${formatEntryList(pending)}`
34+
}
35+
36+
// ============================================================================
37+
// Bible:approved — List approved entries
38+
// ============================================================================
39+
40+
export async function handleBibleApproved(
41+
type?: BibleEntryType,
42+
teamName?: string,
43+
): Promise<string> {
44+
const team = teamName || resolveActiveTeam()?.name
45+
if (!team) return 'No active team. Use /team:create first.'
46+
47+
const approved = getApprovedEntries(team, type)
48+
if (approved.length === 0) {
49+
return type
50+
? `No approved bible entries for type: ${type}`
51+
: 'No approved bible entries yet. Approve some pending entries first.'
52+
}
53+
54+
return `=== Approved Bible Entries (${approved.length}) ===\n\n${formatEntryList(approved)}`
55+
}
56+
57+
// ============================================================================
58+
// Bible:approve — Approve a pending entry
59+
// ============================================================================
60+
61+
export async function handleBibleApprove(
62+
entryId: string,
63+
teamName?: string,
64+
): Promise<string> {
65+
const team = teamName || resolveActiveTeam()?.name
66+
if (!team) return 'No active team. Use /team:create first.'
67+
if (!entryId.trim()) return 'Usage: /bible:approve <entryId>'
68+
69+
const result = approveEntry(team, entryId.trim(), 'human')
70+
return result.message
71+
}
72+
73+
// ============================================================================
74+
// Bible:reject — Reject a pending entry
75+
// ============================================================================
76+
77+
export async function handleBibleReject(
78+
entryId: string,
79+
teamName?: string,
80+
): Promise<string> {
81+
const team = teamName || resolveActiveTeam()?.name
82+
if (!team) return 'No active team. Use /team:create first.'
83+
if (!entryId.trim()) return 'Usage: /bible:reject <entryId>'
84+
85+
const result = rejectEntry(team, entryId.trim(), 'human')
86+
return result.message
87+
}
88+
89+
// ============================================================================
90+
// Bible:delete — Delete an entry
91+
// ============================================================================
92+
93+
export async function handleBibleDelete(
94+
entryId: string,
95+
teamName?: string,
96+
): Promise<string> {
97+
const team = teamName || resolveActiveTeam()?.name
98+
if (!team) return 'No active team. Use /team:create first.'
99+
if (!entryId.trim()) return 'Usage: /bible:delete <entryId>'
100+
101+
const result = deleteEntry(team, entryId.trim())
102+
return result.message
103+
}
104+
105+
// ============================================================================
106+
// Bible:edit — Edit an entry
107+
// ============================================================================
108+
109+
export async function handleBibleEdit(
110+
args: string,
111+
teamName?: string,
112+
): Promise<string> {
113+
const team = teamName || resolveActiveTeam()?.name
114+
if (!team) return 'No active team. Use /team:create first.'
115+
116+
// Parse: entryId "new title" "new content"
117+
const parts = args.match(/"[^"]+"|'[^']+'|\S+/g)
118+
if (!parts || parts.length < 2) {
119+
return 'Usage: /bible:edit <entryId> ["title"] ["content"]'
120+
}
121+
122+
const entryId = (parts[0] || '').replace(/^["']|["']$/g, '')
123+
const title = parts[1] ? parts[1].replace(/^["']|["']$/g, '') : undefined
124+
const content = parts[2] ? parts[2].replace(/^["']|["']$/g, '') : undefined
125+
126+
const updates: { title?: string; content?: string } = {}
127+
if (title) updates.title = title
128+
if (content) updates.content = content
129+
130+
if (Object.keys(updates).length === 0) {
131+
return 'Nothing to update. Provide a title or content.'
132+
}
133+
134+
const result = editEntry(team, entryId, updates)
135+
return result.message
136+
}
137+
138+
// ============================================================================
139+
// Bible:stats — Show bible statistics
140+
// ============================================================================
141+
142+
export async function handleBibleStats(teamName?: string): Promise<string> {
143+
const team = teamName || resolveActiveTeam()?.name
144+
if (!team) return 'No active team. Use /team:create first.'
145+
146+
const stats = getBibleStats(team)
147+
return formatBibleStats(stats)
148+
}
149+
150+
// ============================================================================
151+
// Bible:add — Manually add an entry
152+
// ============================================================================
153+
154+
export async function handleBibleAdd(
155+
args: string,
156+
teamName?: string,
157+
): Promise<string> {
158+
const team = teamName || resolveActiveTeam()?.name
159+
if (!team) return 'No active team. Use /team:create first.'
160+
161+
// Parse: type title content
162+
const parts = args.match(/(\S+)\s+"([^"]+)"\s+"([^"]+)"/) ||
163+
args.match(/(\S+)\s+(\S+)\s+(.+)/)
164+
165+
if (!parts || parts.length < 4) {
166+
return `Usage: /bible:add <type> "<title>" "<content>"
167+
Types: document, decision, intelligence, feature, product-context, market-insight`
168+
}
169+
170+
const type = parts[1] as BibleEntryType
171+
const title = parts[2]
172+
const content = parts[3]
173+
174+
const validTypes: BibleEntryType[] = [
175+
'document', 'decision', 'intelligence', 'feature',
176+
'product-context', 'market-insight',
177+
]
178+
179+
if (!validTypes.includes(type)) {
180+
return `Invalid type. Use one of: ${validTypes.join(', ')}`
181+
}
182+
183+
const entry = createEntry(team, type, title, content, 'user', {
184+
autoApprove: false, // always require human review for manual adds
185+
})
186+
187+
return `Entry created: ${entry.id} (pending review)\nTitle: ${title}`
188+
}
189+
190+
// ============================================================================
191+
// Bible:toggle-research — Toggle auto-research
192+
// ============================================================================
193+
194+
export async function handleBibleToggleResearch(teamName?: string): Promise<string> {
195+
const team = teamName || resolveActiveTeam()?.name
196+
if (!team) return 'No active team. Use /team:create first.'
197+
198+
const current = isAutoResearchEnabled(team)
199+
toggleAutoResearch(team, !current)
200+
201+
return `Auto-research ${!current ? 'ENABLED' : 'DISABLED'}.`
202+
}
203+
204+
// ============================================================================
205+
// Bible:context — Show approved bible context (for agents)
206+
// ============================================================================
207+
208+
export async function handleBibleContext(
209+
type?: BibleEntryType,
210+
teamName?: string,
211+
): Promise<string> {
212+
const team = teamName || resolveActiveTeam()?.name
213+
if (!team) return 'No active team. Use /team:create first.'
214+
215+
return getBibleContext(team, type)
216+
}
217+
218+
// ============================================================================
219+
// Bible:show — Show a single entry
220+
// ============================================================================
221+
222+
export async function handleBibleShow(
223+
entryId: string,
224+
teamName?: string,
225+
): Promise<string> {
226+
const team = teamName || resolveActiveTeam()?.name
227+
if (!team) return 'No active team. Use /team:create first.'
228+
if (!entryId.trim()) return 'Usage: /bible:show <entryId>'
229+
230+
const entry = findEntry(team, entryId.trim())
231+
if (!entry) return `Entry ${entryId} not found.`
232+
233+
const lines = [
234+
`=== Entry: ${entry.id} ===`,
235+
``,
236+
`Type: ${entry.type}`,
237+
`Title: ${entry.title}`,
238+
`Status: ${entry.status}`,
239+
`Source: ${entry.source}`,
240+
`Created: ${new Date(entry.createdAt).toLocaleString()}`,
241+
`Updated: ${new Date(entry.updatedAt).toLocaleString()}`,
242+
]
243+
244+
if (entry.reviewedAt) {
245+
lines.push(`Reviewed: ${new Date(entry.reviewedAt).toLocaleString()}`)
246+
}
247+
if (entry.reviewedBy) {
248+
lines.push(`Reviewed by: ${entry.reviewedBy}`)
249+
}
250+
if (entry.confidence !== undefined) {
251+
lines.push(`Confidence: ${Math.round(entry.confidence * 100)}%`)
252+
}
253+
if (entry.tags && entry.tags.length > 0) {
254+
lines.push(`Tags: ${entry.tags.join(', ')}`)
255+
}
256+
257+
lines.push(``, `Content:`, entry.content)
258+
259+
return lines.join('\n')
260+
}

0 commit comments

Comments
 (0)