opencodekit 0.16.20 → 0.16.21

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/index.js CHANGED
@@ -759,7 +759,7 @@ var cac = (name = "") => new CAC(name);
759
759
  // package.json
760
760
  var package_default = {
761
761
  name: "opencodekit",
762
- version: "0.16.20",
762
+ version: "0.16.21",
763
763
  description: "CLI tool for bootstrapping and managing OpenCodeKit projects",
764
764
  keywords: ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
765
765
  license: "MIT",
@@ -10,14 +10,11 @@
10
10
  * - Inject large free-form manuals into the prompt.
11
11
  */
12
12
 
13
- import { execFile } from "node:child_process";
13
+ import { Database } from "bun:sqlite";
14
14
  import { readFile, readdir, stat } from "node:fs/promises";
15
15
  import path from "node:path";
16
- import { promisify } from "node:util";
17
16
  import type { Plugin } from "@opencode-ai/plugin";
18
17
 
19
- const execFileAsync = promisify(execFile);
20
-
21
18
  const MAX_SESSION_CONTEXT_CHARS = 3000;
22
19
  const MAX_PROJECT_FILES = 3;
23
20
  const MAX_PROJECT_FILE_CHARS = 900;
@@ -25,6 +22,11 @@ const MAX_HANDOFF_CHARS = 2500;
25
22
  const MAX_BEADS = 8;
26
23
  const MAX_COMBINED_CONTEXT_CHARS = 9000;
27
24
 
25
+ interface BeadRow {
26
+ id: string;
27
+ title: string;
28
+ }
29
+
28
30
  function truncate(text: string, maxChars: number): string {
29
31
  if (text.length <= maxChars) return text;
30
32
  return `${text.slice(0, maxChars)}\n...[truncated]`;
@@ -98,30 +100,32 @@ async function readLatestHandoff(handoffDir: string): Promise<string> {
98
100
  return `Source: ${latest.name}\n${truncate(content, MAX_HANDOFF_CHARS)}`;
99
101
  }
100
102
 
101
- async function readInProgressBeads(directory: string): Promise<string> {
103
+ /**
104
+ * Read in-progress beads directly from SQLite database.
105
+ * Cross-platform alternative to shell command execution.
106
+ */
107
+ function readInProgressBeads(directory: string): string {
108
+ const dbPath = path.join(directory, ".beads", "beads.db");
109
+ let db: Database | undefined;
110
+
102
111
  try {
103
- const { stdout } = await execFileAsync(
104
- "br",
105
- ["list", "--status", "in_progress", "--json"],
106
- {
107
- cwd: directory,
108
- timeout: 10000,
109
- },
110
- );
112
+ db = new Database(dbPath, { readonly: true });
111
113
 
112
- const parsed = JSON.parse(stdout as string) as Array<{
113
- id: string;
114
- title: string;
115
- }>;
114
+ const rows = db
115
+ .query<BeadRow, [number]>(
116
+ "SELECT id, title FROM issues WHERE status = 'in_progress' ORDER BY updated_at DESC LIMIT ?",
117
+ )
118
+ .all(MAX_BEADS);
116
119
 
117
- if (!Array.isArray(parsed) || parsed.length === 0) return "";
120
+ if (rows.length === 0) return "";
118
121
 
119
- return parsed
120
- .slice(0, MAX_BEADS)
121
- .map((item) => `- ${item.id}: ${item.title}`)
122
- .join("\n");
122
+ return rows.map((row) => `- ${row.id}: ${row.title}`).join("\n");
123
123
  } catch {
124
+ // Database may not exist, be locked, or have different schema
125
+ // Return empty string to allow graceful degradation
124
126
  return "";
127
+ } finally {
128
+ db?.close();
125
129
  }
126
130
  }
127
131
 
@@ -136,12 +140,14 @@ export const CompactionPlugin: Plugin = async ({ directory }) => {
136
140
  MAX_SESSION_CONTEXT_CHARS,
137
141
  );
138
142
 
139
- const [projectContext, beadsContext, handoffContext] = await Promise.all([
143
+ const [projectContext, handoffContext] = await Promise.all([
140
144
  readProjectMemoryContext(memoryDir),
141
- readInProgressBeads(directory),
142
145
  readLatestHandoff(handoffDir),
143
146
  ]);
144
147
 
148
+ // Synchronous SQLite query - no async/await needed
149
+ const beadsContext = readInProgressBeads(directory);
150
+
145
151
  const combined = [
146
152
  renderSection("Session Continuity", sessionContext),
147
153
  renderSection("Active Beads", beadsContext),
@@ -1,16 +1,16 @@
1
1
  {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "nodenext",
6
- "allowSyntheticDefaultImports": true,
7
- "esModuleInterop": true,
8
- "strict": true,
9
- "noImplicitAny": false,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "types": ["node"]
13
- },
14
- "include": ["**/*.ts"],
15
- "exclude": ["node_modules"]
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "nodenext",
6
+ "allowSyntheticDefaultImports": true,
7
+ "esModuleInterop": true,
8
+ "strict": true,
9
+ "noImplicitAny": false,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "types": ["node", "bun"]
13
+ },
14
+ "include": ["**/*.ts"],
15
+ "exclude": ["node_modules"]
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.16.20",
3
+ "version": "0.16.21",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
6
6
  "license": "MIT",