opencodekit 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/template/.opencode/AGENTS.md +40 -417
  3. package/dist/template/.opencode/agent/build.md +119 -9
  4. package/dist/template/.opencode/agent/planner.md +0 -1
  5. package/dist/template/.opencode/agent/rush.md +81 -19
  6. package/dist/template/.opencode/command/accessibility-check.md +1 -1
  7. package/dist/template/.opencode/command/commit.md +1 -1
  8. package/dist/template/.opencode/command/create.md +68 -441
  9. package/dist/template/.opencode/command/finish.md +82 -252
  10. package/dist/template/.opencode/command/fix-ci.md +52 -247
  11. package/dist/template/.opencode/command/fix-types.md +32 -292
  12. package/dist/template/.opencode/command/fix-ui.md +49 -234
  13. package/dist/template/.opencode/command/fix.md +57 -194
  14. package/dist/template/.opencode/command/handoff.md +66 -243
  15. package/dist/template/.opencode/command/implement.md +67 -231
  16. package/dist/template/.opencode/command/issue.md +42 -190
  17. package/dist/template/.opencode/command/plan.md +86 -442
  18. package/dist/template/.opencode/command/pr.md +3 -1
  19. package/dist/template/.opencode/command/research-and-implement.md +69 -370
  20. package/dist/template/.opencode/command/research.md +72 -197
  21. package/dist/template/.opencode/command/resume.md +70 -438
  22. package/dist/template/.opencode/command/status.md +11 -11
  23. package/dist/template/.opencode/command/triage.md +23 -18
  24. package/dist/template/.opencode/memory/project/commands.md +139 -7
  25. package/dist/template/.opencode/memory/project/gotchas.md +85 -0
  26. package/dist/template/.opencode/opencode.json +556 -510
  27. package/dist/template/.opencode/plugin/beads.ts +181 -16
  28. package/dist/template/.opencode/skill/beads/SKILL.md +15 -0
  29. package/dist/template/.opencode/skill/context-engineering/SKILL.md +94 -0
  30. package/dist/template/.opencode/skill/memory-system/SKILL.md +107 -0
  31. package/dist/template/.opencode/skill/session-management/SKILL.md +111 -0
  32. package/dist/template/.opencode/skill/tool-priority/SKILL.md +115 -0
  33. package/package.json +1 -1
@@ -366,10 +366,12 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
366
366
  filePath: string,
367
367
  reason?: string,
368
368
  ttlSeconds = 600,
369
+ overrideAgent?: string,
369
370
  ): Promise<{ acquired: boolean; holder?: string }> {
370
371
  const lockPath = lockDir(filePath);
371
372
  const now = Date.now();
372
373
  const expires = now + ttlSeconds * 1000;
374
+ const agentToUse = overrideAgent || state.agentId;
373
375
 
374
376
  // Atomic: mkdir fails if dir exists
375
377
  try {
@@ -384,10 +386,10 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
384
386
  if (lock.expires < now) {
385
387
  // Expired - remove and retry
386
388
  await $`rm -rf ${lockPath}`.cwd(directory).quiet();
387
- return acquireLock(filePath, reason, ttlSeconds);
389
+ return acquireLock(filePath, reason, ttlSeconds, overrideAgent);
388
390
  }
389
391
 
390
- if (lock.agent === state.agentId) {
392
+ if (lock.agent === agentToUse) {
391
393
  // We already hold this lock - refresh it
392
394
  lock.expires = expires;
393
395
  await $`echo ${JSON.stringify(lock)} > ${metaPath}`
@@ -400,14 +402,14 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
400
402
  } catch {
401
403
  // Corrupted lock - remove and retry
402
404
  await $`rm -rf ${lockPath}`.cwd(directory).quiet();
403
- return acquireLock(filePath, reason, ttlSeconds);
405
+ return acquireLock(filePath, reason, ttlSeconds, overrideAgent);
404
406
  }
405
407
  }
406
408
 
407
409
  // Lock acquired - write metadata
408
410
  const lockData: LockData = {
409
411
  path: filePath,
410
- agent: state.agentId,
412
+ agent: agentToUse,
411
413
  reason,
412
414
  created: now,
413
415
  expires,
@@ -597,7 +599,7 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
597
599
  role: tool.schema
598
600
  .string()
599
601
  .optional()
600
- .describe("Role: fe|be|mobile|devops|qa"),
602
+ .describe("Role: build|rush|explore|planner|review|scout|vision"),
601
603
  },
602
604
  async execute(args) {
603
605
  await $`bd init`
@@ -670,11 +672,17 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
670
672
  .default("completed")
671
673
  .describe("Completion message"),
672
674
  },
673
- async execute(args) {
675
+ async execute(args, context) {
674
676
  const taskId = args.id || state.currentTask;
675
677
  if (!taskId) return json({ error: "No task ID" });
676
678
 
677
- const closeResult = await bdClose(taskId, args.msg);
679
+ // Audit trail
680
+ const auditAgent = context?.agent || state.agentId;
681
+
682
+ const closeResult = await bdClose(
683
+ taskId,
684
+ `${args.msg} [by ${auditAgent}]`,
685
+ );
678
686
  if (closeResult.error) return json({ error: closeResult.error });
679
687
 
680
688
  // Release all locks
@@ -708,7 +716,9 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
708
716
  tags: tool.schema
709
717
  .array(tool.schema.string())
710
718
  .optional()
711
- .describe("Role tags: fe,be,mobile,devops,qa"),
719
+ .describe(
720
+ "Agent tags: build,rush,explore,planner,review,scout,vision",
721
+ ),
712
722
  parent: tool.schema.string().optional().describe("Parent issue ID"),
713
723
  deps: tool.schema
714
724
  .array(tool.schema.string())
@@ -754,7 +764,9 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
754
764
  "Assign task to role (leader only). Adds tag and notifies.",
755
765
  args: {
756
766
  id: tool.schema.string().describe("Issue ID"),
757
- role: tool.schema.string().describe("Role: fe|be|mobile|devops|qa"),
767
+ role: tool.schema
768
+ .string()
769
+ .describe("Role: build|rush|explore|planner|review|scout|vision"),
758
770
  notify: tool.schema
759
771
  .boolean()
760
772
  .default(true)
@@ -882,16 +894,24 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
882
894
  .default(600)
883
895
  .describe("Seconds until expiry"),
884
896
  },
885
- async execute(args) {
897
+ async execute(args, context) {
886
898
  if (!args.paths?.length) return json({ error: "paths required" });
887
899
 
900
+ // Log who is reserving for audit
901
+ const reservingAgent = context?.agent || state.agentId;
902
+
888
903
  await ensureReservationsDir();
889
904
 
890
905
  const granted: string[] = [];
891
906
  const conflicts: { path: string; holder?: string }[] = [];
892
907
 
893
908
  for (const path of args.paths) {
894
- const result = await acquireLock(path, args.reason, args.ttl);
909
+ const result = await acquireLock(
910
+ path,
911
+ args.reason,
912
+ args.ttl,
913
+ reservingAgent,
914
+ );
895
915
  if (result.acquired) {
896
916
  granted.push(path);
897
917
  } else {
@@ -963,12 +983,15 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
963
983
  .default(false)
964
984
  .describe("Send to all workspaces"),
965
985
  },
966
- async execute(args) {
986
+ async execute(args, context) {
967
987
  if (!args.subj) return json({ error: "subj required" });
968
988
 
989
+ // Use context agent if available for audit trail
990
+ const senderAgent = context?.agent || state.agentId;
991
+
969
992
  const msg: Message = {
970
993
  id: `msg-${Date.now().toString(36)}`,
971
- from: state.agentId,
994
+ from: senderAgent,
972
995
  to: args.to || "all",
973
996
  subj: args.subj,
974
997
  body: args.body,
@@ -1000,6 +1023,117 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
1000
1023
  },
1001
1024
  }),
1002
1025
 
1026
+ bd_ack: tool({
1027
+ description: "Acknowledge message(s). Marks as read.",
1028
+ args: {
1029
+ ids: tool.schema
1030
+ .array(tool.schema.string())
1031
+ .describe("Message IDs to acknowledge"),
1032
+ },
1033
+ async execute(args) {
1034
+ if (!args.ids?.length) return json({ error: "ids required" });
1035
+
1036
+ try {
1037
+ const content =
1038
+ await $`cat ${RESERVATIONS_DIR}/messages.jsonl 2>/dev/null`
1039
+ .cwd(directory)
1040
+ .text();
1041
+
1042
+ if (!content.trim()) return json({ acked: 0 });
1043
+
1044
+ const idsToAck = new Set(args.ids);
1045
+ let acked = 0;
1046
+
1047
+ const msgs = content
1048
+ .trim()
1049
+ .split("\n")
1050
+ .map((line) => {
1051
+ try {
1052
+ const msg = JSON.parse(line) as Message;
1053
+ if (idsToAck.has(msg.id) && !msg.read) {
1054
+ msg.read = true;
1055
+ acked++;
1056
+ }
1057
+ return msg;
1058
+ } catch {
1059
+ return null;
1060
+ }
1061
+ })
1062
+ .filter((m): m is Message => m !== null);
1063
+
1064
+ const newContent = msgs.map((m) => JSON.stringify(m)).join("\n");
1065
+ await $`echo ${newContent} > ${RESERVATIONS_DIR}/messages.jsonl`
1066
+ .cwd(directory)
1067
+ .quiet();
1068
+
1069
+ return json({ ok: 1, acked });
1070
+ } catch {
1071
+ return json({ acked: 0 });
1072
+ }
1073
+ },
1074
+ }),
1075
+
1076
+ bd_whois: tool({
1077
+ description: "Agent directory lookup. See who's working on what.",
1078
+ args: {
1079
+ agent: tool.schema
1080
+ .string()
1081
+ .optional()
1082
+ .describe("Agent ID to lookup (empty=all)"),
1083
+ },
1084
+ async execute(args) {
1085
+ const locks = await getAllLocks();
1086
+ const { tasks: inProgressTasks } = await bdList({
1087
+ status: "in_progress",
1088
+ });
1089
+
1090
+ // Build agent activity map
1091
+ const agentMap: Record<
1092
+ string,
1093
+ {
1094
+ files: string[];
1095
+ task?: string;
1096
+ role?: string;
1097
+ }
1098
+ > = {};
1099
+
1100
+ // Add locks info
1101
+ for (const lock of locks) {
1102
+ if (!agentMap[lock.agent]) {
1103
+ agentMap[lock.agent] = { files: [] };
1104
+ }
1105
+ agentMap[lock.agent].files.push(lock.path);
1106
+ if (lock.task) {
1107
+ agentMap[lock.agent].task = lock.task;
1108
+ }
1109
+ }
1110
+
1111
+ // Add current agent info
1112
+ if (!agentMap[state.agentId]) {
1113
+ agentMap[state.agentId] = { files: [] };
1114
+ }
1115
+ agentMap[state.agentId].role = state.role || undefined;
1116
+ if (state.currentTask) {
1117
+ agentMap[state.agentId].task = state.currentTask;
1118
+ }
1119
+
1120
+ // Filter if specific agent requested
1121
+ if (args.agent) {
1122
+ const agent = agentMap[args.agent];
1123
+ if (!agent) return json({ error: "agent not found" });
1124
+ return json({ agent: args.agent, ...agent });
1125
+ }
1126
+
1127
+ return json({
1128
+ agents: Object.entries(agentMap).map(([id, info]) => ({
1129
+ id,
1130
+ ...info,
1131
+ })),
1132
+ in_progress_tasks: inProgressTasks.length,
1133
+ });
1134
+ },
1135
+ }),
1136
+
1003
1137
  bd_status: tool({
1004
1138
  description: "Workspace overview. Shows agents, tasks, locks.",
1005
1139
  args: {
@@ -1038,10 +1172,22 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
1038
1172
 
1039
1173
  bd_sync: tool({
1040
1174
  description: "Sync with git. Pull/push changes.",
1041
- args: {},
1042
- async execute() {
1175
+ args: {
1176
+ reason: tool.schema
1177
+ .string()
1178
+ .optional()
1179
+ .describe("Audit trail reason for sync"),
1180
+ },
1181
+ async execute(args, context) {
1043
1182
  const result = await bdSync();
1044
- return json({ ok: 1, output: result.output });
1183
+ // Log sync with context for audit trail
1184
+ const syncAgent = context?.agent || state.agentId;
1185
+ return json({
1186
+ ok: 1,
1187
+ output: result.output,
1188
+ by: syncAgent,
1189
+ reason: args.reason,
1190
+ });
1045
1191
  },
1046
1192
  }),
1047
1193
 
@@ -1249,6 +1395,25 @@ export const BeadsCorePlugin: Plugin = async ({ $, directory }) => {
1249
1395
  if (event.type === "session.idle" && state.currentTask) {
1250
1396
  await bdSync();
1251
1397
  }
1398
+
1399
+ // Cleanup expired locks on compaction
1400
+ if (event.type === "session.compacted") {
1401
+ await cleanupExpiredLocks();
1402
+ }
1403
+
1404
+ // Log errors to audit trail
1405
+ if (event.type === "session.error" && state.currentTask) {
1406
+ await appendMessage({
1407
+ id: `err-${Date.now().toString(36)}`,
1408
+ from: state.agentId,
1409
+ to: "all",
1410
+ subj: `Session error on task ${state.currentTask}`,
1411
+ body: `Error occurred during task execution`,
1412
+ importance: "high",
1413
+ at: Date.now(),
1414
+ read: false,
1415
+ });
1416
+ }
1252
1417
  },
1253
1418
  };
1254
1419
  };
@@ -340,6 +340,21 @@ bd_msg({
340
340
  bd_inbox({ unread: true, n: 10 });
341
341
  ```
342
342
 
343
+ ### Acknowledge Messages
344
+
345
+ ```typescript
346
+ bd_ack({ ids: ["msg-abc", "msg-def"] }); // Mark as read
347
+ ```
348
+
349
+ ## Agent Coordination
350
+
351
+ ### Who's Working on What
352
+
353
+ ```typescript
354
+ bd_whois(); // All agents with their files and tasks
355
+ bd_whois({ agent: "build-abc" }); // Specific agent lookup
356
+ ```
357
+
343
358
  ## Status and Analysis
344
359
 
345
360
  ### Workspace Overview
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: Use when managing context window, deciding what to load/prune, or understanding AI adoption stages - covers constraint awareness and intent layer principles
3
+ ---
4
+
5
+ # Context Engineering Skill
6
+
7
+ ## AI Adoption Stages
8
+
9
+ OpenCode operates at **Stage 5-6**:
10
+
11
+ - **Stage 5** (Agentic Verification): Agents run tests and iterate autonomously
12
+ - **Stage 6** (Multi-Agent Orchestration): Parallel workstreams with coordination
13
+
14
+ **Current constraint**: Planning and specification quality. Implementation capacity is not the bottleneck—how well you specify requirements is.
15
+
16
+ ## Autonomous Duration
17
+
18
+ The key metric: **How long can an agent work before losing the plot?**
19
+
20
+ Extend autonomous duration by:
21
+
22
+ - Binding tighter to intent (clear specs, constraints, invariants)
23
+ - Providing systematic context (AGENTS.md hierarchy, memory files)
24
+ - Verification loops (test → iterate → verify)
25
+
26
+ ## Greenfield vs Legacy
27
+
28
+ | Type | Context | Agent Performance |
29
+ | -------------- | -------------------------- | ----------------------------- |
30
+ | **Greenfield** | Simple, fast prototypes | Works well immediately |
31
+ | **Legacy** | Complex, hidden invariants | Needs careful context loading |
32
+
33
+ Codebase complexity is a primary difficulty knob. Context is how you pay it down.
34
+
35
+ ## Three Context Constraints
36
+
37
+ 1. **Blind spots cause hallucinations** - If agent doesn't see specific context, it fills gaps with generic training priors. You only get the behavior you load.
38
+
39
+ 2. **Everything influences everything** - Noise-to-signal ratio matters. Irrelevant files degrade ALL output quality.
40
+
41
+ 3. **Window is finite** - Performance degrades BEFORE hitting hard token limits. Curate the smallest, highest-signal slice.
42
+
43
+ ## Practical Implications
44
+
45
+ | Instead of | Do This |
46
+ | ----------------------- | ----------------------------------------------------- |
47
+ | Reading entire files | Use `lsp_lsp_document_symbols` for outline |
48
+ | Loading whole documents | Read specific line ranges |
49
+ | Flat file loading | Navigate AGENTS.md hierarchy (progressive disclosure) |
50
+ | Keeping completed work | Prune context aggressively |
51
+
52
+ ## Intent Layer Principles
53
+
54
+ ### What Belongs in Each AGENTS.md
55
+
56
+ - **Purpose & Scope** - What this area does. What it explicitly DOESN'T do.
57
+ - **Entry Points & Contracts** - Main APIs, invariants, "all X goes through Y"
58
+ - **Usage Patterns** - Canonical examples: "To add a rule, follow this pattern..."
59
+ - **Anti-patterns** - Negative examples: "Never call X directly; go through Y"
60
+ - **Dependencies & Downlinks** - What it connects to, pointers to child AGENTS.md
61
+ - **Pitfalls** - Things that repeatedly confused agents/humans
62
+
63
+ ### Key Mechanics
64
+
65
+ | Principle | Meaning |
66
+ | ------------------------------- | ------------------------------------------------------------- |
67
+ | **Hierarchical loading** | When a node loads, all ancestors load too (T-shaped view) |
68
+ | **Compression, not bloat** | Good nodes compress code; 10k tokens for 20k code adds weight |
69
+ | **Least Common Ancestor (LCA)** | Place shared knowledge at shallowest node covering all paths |
70
+ | **Downlinks for discovery** | Point to related context without loading everything upfront |
71
+
72
+ ## Context Budget Guidelines
73
+
74
+ | Phase | Target Context | Action |
75
+ | ----------------- | -------------- | ----------------------------------------- |
76
+ | Starting work | <50k tokens | Load only essential AGENTS.md + task spec |
77
+ | Mid-task | 50-100k tokens | Prune completed reads, keep active files |
78
+ | Approaching limit | >100k tokens | Aggressive pruning, extract key findings |
79
+ | Near capacity | >150k tokens | Consider session restart with handoff |
80
+
81
+ ## Anti-Patterns
82
+
83
+ ❌ Loading "everything that might be relevant"
84
+ ❌ Keeping old file reads after editing complete
85
+ ❌ Reading entire files when you only need a function
86
+ ❌ Ignoring AGENTS.md hierarchy (loading leaf without ancestors)
87
+
88
+ ## Best Practices
89
+
90
+ ✅ Start with minimum viable context
91
+ ✅ Use LSP tools for targeted information
92
+ ✅ Prune after each completed sub-task
93
+ ✅ Trust AGENTS.md hierarchy for discovery
94
+ ✅ Extract findings before pruning valuable reads
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: memory-system
3
+ description: Use when persisting learnings, loading previous context, or searching past decisions - covers memory file structure, tools, and when to update each file
4
+ ---
5
+
6
+ # Memory System
7
+
8
+ Persistent context that survives across sessions.
9
+
10
+ ## Directory Structure
11
+
12
+ ```
13
+ .opencode/memory/
14
+ _templates/ # Task templates (prd, observation, session-summary)
15
+ handoffs/ # Phase transitions
16
+ research/ # Research findings
17
+ observations/ # Structured observations
18
+ project/ # Persistent project knowledge
19
+ commands.md # Build, test, lint, deploy commands
20
+ conventions.md # Code patterns, commit style, PR process
21
+ gotchas.md # Footguns, edge cases, "don't forget this"
22
+ architecture.md # Key modules, directory structure
23
+ user.md # Identity, preferences, communication style
24
+ ```
25
+
26
+ ## Standard Memory Blocks
27
+
28
+ | File | Purpose | Update When |
29
+ | ------------------------- | ------------------------ | --------------------------- |
30
+ | `project/commands.md` | Build/test/lint commands | Discovering new command |
31
+ | `project/conventions.md` | Code patterns, style | Learning team pattern |
32
+ | `project/gotchas.md` | Footguns, warnings | Hitting unexpected behavior |
33
+ | `project/architecture.md` | Key modules, structure | Mapping new area |
34
+ | `user.md` | Preferences, workflow | Learning user preference |
35
+
36
+ ## Explicit Memory Updates
37
+
38
+ Don't rely on implicit learning. Explicitly persist:
39
+
40
+ - Non-obvious project behavior → `project/gotchas.md`
41
+ - User preferences discovered → `user.md`
42
+ - New build/test commands → `project/commands.md`
43
+ - Code patterns to follow → `project/conventions.md`
44
+
45
+ ## Memory Tools
46
+
47
+ ### memory-read
48
+
49
+ Load previous context or templates:
50
+
51
+ ```typescript
52
+ memory - read({ file: "project/commands" }); // Load commands
53
+ memory - read({ file: "_templates/prd" }); // Load PRD template
54
+ memory - read({ file: "handoffs/bd-abc123" }); // Load specific handoff
55
+ ```
56
+
57
+ ### memory-update
58
+
59
+ Save learnings or handoffs:
60
+
61
+ ```typescript
62
+ memory -
63
+ update({
64
+ file: "project/gotchas",
65
+ content: "### New Gotcha\n\nDescription...",
66
+ mode: "append", // or "replace"
67
+ });
68
+ ```
69
+
70
+ ### memory-search
71
+
72
+ Find past decisions, research, or handoffs:
73
+
74
+ ```typescript
75
+ memory - search({ query: "authentication" });
76
+ memory - search({ query: "bugfix", type: "observations" });
77
+ memory - search({ query: "session", type: "handoffs" });
78
+ ```
79
+
80
+ ## Observations
81
+
82
+ Record important findings with structured metadata:
83
+
84
+ ```typescript
85
+ observation({
86
+ type: "decision", // decision, bugfix, feature, pattern, discovery, learning, warning
87
+ title: "Use JWT auth",
88
+ content: "Decided to use JWT because...",
89
+ concepts: "auth, security",
90
+ files: "src/auth.ts",
91
+ bead_id: "bd-abc123",
92
+ });
93
+ ```
94
+
95
+ **When to create observations:**
96
+
97
+ - Major architectural decisions
98
+ - Bug root causes discovered
99
+ - Patterns worth reusing
100
+ - Gotchas and warnings for future
101
+
102
+ ## Best Practices
103
+
104
+ 1. **Read before work** - Check relevant memory files at session start
105
+ 2. **Update during work** - Don't wait until end; persist incrementally
106
+ 3. **Be specific** - Include file paths, function names, concrete examples
107
+ 4. **Keep it actionable** - Future agents should know what to do with the info
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: session-management
3
+ description: Use when context is growing large, switching tasks, or needing previous session context - covers thresholds, session tools, and workflow patterns
4
+ ---
5
+
6
+ # Session Management
7
+
8
+ **Philosophy**: Short sessions (<150k tokens) beat long bloated ones. Agents get worse with too much context. Cost is exponential.
9
+
10
+ ## Context Thresholds
11
+
12
+ The environment monitors context usage and warns at these thresholds:
13
+
14
+ | Threshold | Action |
15
+ | --------- | ---------------------------------------------------------- |
16
+ | **70%** | Consolidate work; consider pruning irrelevant tool outputs |
17
+ | **85%** | Summarize findings and consider starting a new session |
18
+ | **95%** | Critical: prune context immediately or restart session |
19
+
20
+ ## Session Tools
21
+
22
+ ### list_sessions
23
+
24
+ Discover available sessions before reading:
25
+
26
+ ```typescript
27
+ list_sessions({ limit: 10, project: "current" }); // Current project
28
+ list_sessions({ since: "today" }); // Today's sessions
29
+ list_sessions({ project: "all", since: "yesterday" }); // Cross-project
30
+ ```
31
+
32
+ ### read_session
33
+
34
+ Pull context from previous session:
35
+
36
+ ```typescript
37
+ read_session("last"); // Most recent
38
+ read_session("2 ago", { project: "current" }); // 2nd most recent
39
+ read_session("today"); // Today's first session
40
+ read_session("ses_abc123", { focus: "file changes" }); // Specific aspect
41
+ ```
42
+
43
+ ### search_session
44
+
45
+ Full-text search across sessions:
46
+
47
+ ```typescript
48
+ search_session({ query: "auth bug" }); // Search all sessions
49
+ search_session({ query: "OAuth", session_id: "ses_abc" }); // Specific session
50
+ search_session({ query: "error", limit: 10 }); // Limit results
51
+ ```
52
+
53
+ Use to find past discussions, decisions, or work on a topic before starting new work.
54
+
55
+ ### summarize_session
56
+
57
+ Generate AI summary of a session:
58
+
59
+ ```typescript
60
+ summarize_session("ses_abc123"); // Trigger AI summarization
61
+ ```
62
+
63
+ Use before `read_session` to get a quick overview of what happened in a past session without loading full context.
64
+
65
+ ## When to Start New Session
66
+
67
+ - Completing distinct task from `bd ready`
68
+ - Token usage approaching 150k
69
+ - Switching phases (implementation → review → testing)
70
+ - After handoff (`/handoff <bead-id>`)
71
+
72
+ ## Session Workflow Pattern
73
+
74
+ ```
75
+ Session 1: Implement feature X (80k tokens)
76
+ ↓ close, update memory
77
+ Session 2: list_sessions() → read_session("last") → Refactor (60k tokens)
78
+
79
+ Session 3: read_session("previous") → Add tests (90k tokens)
80
+
81
+ Session 4: read_session refs → Final review (100k tokens)
82
+ ```
83
+
84
+ **Result**: 4 fresh contexts vs 1 degraded 330k context. Better performance, lower cost.
85
+
86
+ ## Context Transfer
87
+
88
+ Use all available sources:
89
+
90
+ 1. `read_session("last")` - Previous session work
91
+ 2. Git state - `git diff`, `git log` - Code changes
92
+ 3. Memory files - `.opencode/memory/*` - Persistent context
93
+ 4. Beads - `bd show <id>` - Task specs
94
+
95
+ **Don't**: Carry everything forward. Extract what's needed, discard the rest.
96
+
97
+ ## Pruning Strategy
98
+
99
+ When context grows large:
100
+
101
+ 1. **Discard** completed task outputs (read files you won't edit again)
102
+ 2. **Extract** key findings before discarding research
103
+ 3. **Summarize** complex investigations into memory files
104
+ 4. **Restart** session if above 85% and work is at a natural break
105
+
106
+ ## Anti-Patterns
107
+
108
+ - ❌ Running until context limit forces restart
109
+ - ❌ Carrying all previous reads forward "just in case"
110
+ - ❌ Not using memory files for cross-session persistence
111
+ - ❌ Re-reading the same files every session instead of extracting key info