opencodekit 0.12.7 → 0.13.0
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 +2 -2
- package/dist/index.js +2753 -508
- package/dist/template/.opencode/AGENTS.md +35 -128
- package/dist/template/.opencode/README.md +4 -3
- package/dist/template/.opencode/command/design.md +1 -0
- package/dist/template/.opencode/command/fix.md +28 -1
- package/dist/template/.opencode/command/research.md +0 -4
- package/dist/template/.opencode/command/start.md +106 -0
- package/dist/template/.opencode/command/triage.md +66 -12
- package/dist/template/.opencode/memory/project/beads-workflow.md +278 -0
- package/dist/template/.opencode/memory/session-context.md +40 -0
- package/dist/template/.opencode/opencode.json +557 -496
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/plugin/compaction.ts +62 -18
- package/dist/template/.opencode/plugin/lib/notify.ts +2 -3
- package/dist/template/.opencode/plugin/sessions.ts +1 -1
- package/dist/template/.opencode/plugin/skill-mcp.ts +11 -12
- package/dist/template/.opencode/skill/beads/SKILL.md +44 -0
- package/dist/template/.opencode/tool/ast-grep.ts +3 -3
- package/dist/template/.opencode/tool/bd-inbox.ts +7 -6
- package/dist/template/.opencode/tool/bd-msg.ts +3 -3
- package/dist/template/.opencode/tool/bd-release.ts +2 -2
- package/dist/template/.opencode/tool/bd-reserve.ts +5 -4
- package/dist/template/.opencode/tool/memory-read.ts +2 -2
- package/dist/template/.opencode/tool/memory-search.ts +2 -2
- package/dist/template/.opencode/tool/memory-update.ts +11 -12
- package/dist/template/.opencode/tool/observation.ts +6 -6
- package/package.json +5 -2
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Memory & Compaction Plugin
|
|
2
|
+
* Memory & Compaction Plugin (Codex-Inspired Continuity)
|
|
3
3
|
*
|
|
4
|
-
* Injects
|
|
5
|
-
* 1. Load
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
4
|
+
* Injects continuity context into session compaction:
|
|
5
|
+
* 1. Load session-context.md (CONTINUITY.md pattern)
|
|
6
|
+
* 2. Load project memory files
|
|
7
|
+
* 3. Inject beads in-progress state
|
|
8
|
+
* 4. Append workflow-specific compaction rules
|
|
9
|
+
*
|
|
10
|
+
* Session context format (agent-maintained via memory-update):
|
|
11
|
+
* - Goal: What we're trying to achieve + success criteria
|
|
12
|
+
* - Constraints: User-specified limits, discovered guardrails
|
|
13
|
+
* - Decisions: Key choices made this session
|
|
14
|
+
* - State: Done/Now/Next
|
|
15
|
+
* - Open Questions: Uncertainties marked UNCONFIRMED
|
|
16
|
+
* - Working Set: Files, bead IDs, branch
|
|
8
17
|
*/
|
|
9
18
|
|
|
10
19
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
@@ -14,7 +23,19 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
14
23
|
|
|
15
24
|
return {
|
|
16
25
|
"experimental.session.compacting": async (input, output) => {
|
|
17
|
-
// Load
|
|
26
|
+
// 1. Load session context (CONTINUITY.md pattern) - HIGHEST PRIORITY
|
|
27
|
+
let sessionContext = "";
|
|
28
|
+
try {
|
|
29
|
+
const sessionFile = `${MEMORY_DIR}/session-context.md`;
|
|
30
|
+
const content = await $`cat ${sessionFile} 2>/dev/null`.text();
|
|
31
|
+
if (content.trim()) {
|
|
32
|
+
sessionContext = `\n## Session Continuity (Compaction-Safe)\n${content}`;
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
// No session context yet
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 2. Load project memory files
|
|
18
39
|
let memoryContext = "";
|
|
19
40
|
try {
|
|
20
41
|
const memoryFiles =
|
|
@@ -33,7 +54,7 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
33
54
|
// Memory dir doesn't exist or other error
|
|
34
55
|
}
|
|
35
56
|
|
|
36
|
-
// Inject beads in-progress state
|
|
57
|
+
// 3. Inject beads in-progress state
|
|
37
58
|
let beadsContext = "";
|
|
38
59
|
try {
|
|
39
60
|
const result =
|
|
@@ -48,12 +69,13 @@ export const CompactionPlugin: Plugin = async ({ $, directory }) => {
|
|
|
48
69
|
// Beads not available, skip
|
|
49
70
|
}
|
|
50
71
|
|
|
51
|
-
// Inject
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
// Inject all context - session context FIRST (most important)
|
|
73
|
+
const allContext = [sessionContext, beadsContext, memoryContext]
|
|
74
|
+
.filter(Boolean)
|
|
75
|
+
.join("\n");
|
|
76
|
+
|
|
77
|
+
if (allContext) {
|
|
78
|
+
output.context.push(`## Session Context\n${allContext}\n`);
|
|
57
79
|
}
|
|
58
80
|
|
|
59
81
|
// Append workflow-specific rules to OpenCode's default prompt
|
|
@@ -61,6 +83,28 @@ ${memoryContext}
|
|
|
61
83
|
|
|
62
84
|
## Additional Rules for This Workflow
|
|
63
85
|
|
|
86
|
+
### Session Continuity
|
|
87
|
+
Maintain session-context.md via memory-update tool. Format:
|
|
88
|
+
\`\`\`
|
|
89
|
+
Goal: [What + success criteria]
|
|
90
|
+
Constraints: [Limits, mark UNCONFIRMED if inferred]
|
|
91
|
+
Decisions: [Key choices this session]
|
|
92
|
+
State:
|
|
93
|
+
Done: [Completed]
|
|
94
|
+
Now: [Current focus - ONE thing]
|
|
95
|
+
Next: [Queued]
|
|
96
|
+
Open Questions: [Uncertainties - mark UNCONFIRMED]
|
|
97
|
+
Working Set: [Files, bead ID, branch]
|
|
98
|
+
\`\`\`
|
|
99
|
+
|
|
100
|
+
Update session-context.md when:
|
|
101
|
+
- Goal changes or clarifies
|
|
102
|
+
- Key decision made
|
|
103
|
+
- State shifts (Done/Now/Next)
|
|
104
|
+
- Uncertainty discovered
|
|
105
|
+
|
|
106
|
+
After compaction: Check session-context.md, ask 1-3 targeted questions if gaps exist.
|
|
107
|
+
|
|
64
108
|
### Beads Workflow
|
|
65
109
|
- PRESERVE: Bead IDs (bd-xxx format), bead states, in-progress task IDs
|
|
66
110
|
- DROP: Closed/completed beads (already tracked in git)
|
|
@@ -71,13 +115,13 @@ ${memoryContext}
|
|
|
71
115
|
|
|
72
116
|
### Memory System
|
|
73
117
|
If you discover:
|
|
74
|
-
- Gotchas/edge cases →
|
|
75
|
-
- Build/test commands →
|
|
76
|
-
- Code patterns/conventions →
|
|
77
|
-
- Architecture insights →
|
|
118
|
+
- Gotchas/edge cases → Save to .opencode/memory/project/gotchas.md
|
|
119
|
+
- Build/test commands → Save to .opencode/memory/project/commands.md
|
|
120
|
+
- Code patterns/conventions → Save to .opencode/memory/project/conventions.md
|
|
121
|
+
- Architecture insights → Save to .opencode/memory/project/architecture.md
|
|
78
122
|
|
|
79
123
|
### Preservation Priorities
|
|
80
|
-
- PRESERVE: File paths
|
|
124
|
+
- PRESERVE: File paths (file:line_number), user constraints, decisions, UNCONFIRMED items
|
|
81
125
|
- DROP: Failed attempts, superseded info, verbose tool outputs, exploration dead-ends
|
|
82
126
|
`;
|
|
83
127
|
},
|
|
@@ -12,7 +12,7 @@ let _isWSL: boolean | null = null;
|
|
|
12
12
|
export function isWSL(): boolean {
|
|
13
13
|
if (_isWSL !== null) return _isWSL;
|
|
14
14
|
try {
|
|
15
|
-
const fs = require("fs");
|
|
15
|
+
const fs = require("node:fs");
|
|
16
16
|
const release = fs.readFileSync("/proc/version", "utf8").toLowerCase();
|
|
17
17
|
_isWSL = release.includes("microsoft") || release.includes("wsl");
|
|
18
18
|
} catch {
|
|
@@ -28,7 +28,6 @@ export function isWSL(): boolean {
|
|
|
28
28
|
* @param message - Notification body
|
|
29
29
|
*/
|
|
30
30
|
export async function notify(
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
31
|
$: any,
|
|
33
32
|
title: string,
|
|
34
33
|
message: string,
|
|
@@ -39,7 +38,7 @@ export async function notify(
|
|
|
39
38
|
|
|
40
39
|
try {
|
|
41
40
|
if (platform === "darwin") {
|
|
42
|
-
await $`osascript -e ${
|
|
41
|
+
await $`osascript -e ${`display notification "${safeMessage}" with title "${safeTitle}"`}`;
|
|
43
42
|
} else if (platform === "linux") {
|
|
44
43
|
if (isWSL()) {
|
|
45
44
|
// WSL: try notify-send, fail silently
|
|
@@ -116,7 +116,7 @@ export const SessionsPlugin: Plugin = async ({ client }) => {
|
|
|
116
116
|
const userMessages = messageData.filter(
|
|
117
117
|
(m) => m.info?.role === "user",
|
|
118
118
|
);
|
|
119
|
-
summary +=
|
|
119
|
+
summary += "## Recent User Messages\n\n";
|
|
120
120
|
for (let i = 0; i < Math.min(userMessages.length, 5); i++) {
|
|
121
121
|
const m = userMessages[i];
|
|
122
122
|
const content = extractContent(m.info);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type ChildProcess, spawn } from "child_process";
|
|
2
|
-
import { existsSync, readFileSync } from "fs";
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
import { join } from "path";
|
|
1
|
+
import { type ChildProcess, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
5
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
6
6
|
import { tool } from "@opencode-ai/plugin/tool";
|
|
7
7
|
|
|
@@ -155,7 +155,7 @@ export const SkillMcpPlugin: Plugin = async ({ directory }) => {
|
|
|
155
155
|
},
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
client.process.stdin?.write(JSON.stringify(request)
|
|
158
|
+
client.process.stdin?.write(`${JSON.stringify(request)}\n`);
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
|
|
@@ -232,10 +232,10 @@ export const SkillMcpPlugin: Plugin = async ({ directory }) => {
|
|
|
232
232
|
|
|
233
233
|
// Send initialized notification
|
|
234
234
|
proc.stdin?.write(
|
|
235
|
-
JSON.stringify({
|
|
235
|
+
`${JSON.stringify({
|
|
236
236
|
jsonrpc: "2.0",
|
|
237
237
|
method: "notifications/initialized",
|
|
238
|
-
})
|
|
238
|
+
})}\n`,
|
|
239
239
|
);
|
|
240
240
|
|
|
241
241
|
// Discover capabilities
|
|
@@ -430,7 +430,7 @@ The skill must be loaded first via the skill() tool to register its MCP config.`
|
|
|
430
430
|
if (args.skill_name) {
|
|
431
431
|
const toDisconnect: string[] = [];
|
|
432
432
|
for (const key of state.clients.keys()) {
|
|
433
|
-
if (key.startsWith(args.skill_name
|
|
433
|
+
if (key.startsWith(`${args.skill_name}:`)) {
|
|
434
434
|
toDisconnect.push(key);
|
|
435
435
|
}
|
|
436
436
|
}
|
|
@@ -440,11 +440,10 @@ The skill must be loaded first via the skill() tool to register its MCP config.`
|
|
|
440
440
|
state.clients.delete(key);
|
|
441
441
|
}
|
|
442
442
|
return JSON.stringify({ disconnected: toDisconnect });
|
|
443
|
-
} else {
|
|
444
|
-
const count = state.clients.size;
|
|
445
|
-
disconnectAll();
|
|
446
|
-
return JSON.stringify({ disconnected: "all", count });
|
|
447
443
|
}
|
|
444
|
+
const count = state.clients.size;
|
|
445
|
+
disconnectAll();
|
|
446
|
+
return JSON.stringify({ disconnected: "all", count });
|
|
448
447
|
},
|
|
449
448
|
}),
|
|
450
449
|
},
|
|
@@ -506,6 +506,50 @@ bd_claim(); // Gets frontend task that was waiting on API
|
|
|
506
506
|
5. **Use `bd_msg(to="all")`** - For team-wide announcements
|
|
507
507
|
6. **Sync regularly** - `bd_sync()` at session end
|
|
508
508
|
|
|
509
|
+
## Best Practices (from Steve Yegge)
|
|
510
|
+
|
|
511
|
+
### Daily/Weekly Maintenance
|
|
512
|
+
|
|
513
|
+
| Task | Frequency | Command | Why |
|
|
514
|
+
| ------------ | -------------- | --------------------- | ---------------------------------------------- |
|
|
515
|
+
| Health check | Weekly | `bd doctor` | Repairs database issues, detects orphaned work |
|
|
516
|
+
| Cleanup | Every few days | `bd cleanup --days 7` | Keep DB under 200-500 issues for performance |
|
|
517
|
+
| Upgrade | Weekly | `bd upgrade` | Get latest features and fixes |
|
|
518
|
+
| Git hooks | Once per repo | `bd hooks install` | Auto-sync on commit/merge/checkout |
|
|
519
|
+
|
|
520
|
+
### Key Principles
|
|
521
|
+
|
|
522
|
+
1. **Plan outside Beads first** - Use planning tools, then import tasks to beads
|
|
523
|
+
2. **One task per session, then restart** - Fresh context prevents confusion
|
|
524
|
+
3. **File lots of issues** - Any work >2 minutes should be tracked
|
|
525
|
+
4. **Use short prefixes** - `bd-`, `vc-`, `wy-` etc.
|
|
526
|
+
5. **"Land the plane" = PUSH** - `bd sync` means git push, not "ready when you are"
|
|
527
|
+
6. **Include issue ID in commits** - `git commit -m "Fix bug (bd-abc)"`
|
|
528
|
+
|
|
529
|
+
### Database Health
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
# Check database size
|
|
533
|
+
bd list --status=all --json | wc -l
|
|
534
|
+
|
|
535
|
+
# Target: under 200-500 issues
|
|
536
|
+
# If over, run cleanup more aggressively:
|
|
537
|
+
bd cleanup --days 3
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Git Hooks (Essential)
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
bd hooks install
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
Installs hooks for:
|
|
547
|
+
|
|
548
|
+
- **pre-commit**: Sync before commit
|
|
549
|
+
- **post-merge**: Import changes after merge
|
|
550
|
+
- **pre-push**: Ensure sync before push
|
|
551
|
+
- **post-checkout**: Refresh after branch switch
|
|
552
|
+
|
|
509
553
|
## Quick Reference
|
|
510
554
|
|
|
511
555
|
```
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* Requires: npm install -g @ast-grep/cli (or brew install ast-grep)
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { exec } from "child_process";
|
|
10
|
-
import { promisify } from "util";
|
|
9
|
+
import { exec } from "node:child_process";
|
|
10
|
+
import { promisify } from "node:util";
|
|
11
11
|
import { tool } from "@opencode-ai/plugin";
|
|
12
12
|
|
|
13
13
|
const execAsync = promisify(exec);
|
|
@@ -224,7 +224,7 @@ Install via:
|
|
|
224
224
|
preview += `... and ${count - 10} more matches\n`;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
preview +=
|
|
227
|
+
preview += "\n**To apply:** Run again with dryRun: false";
|
|
228
228
|
return preview;
|
|
229
229
|
} catch {
|
|
230
230
|
return `Dry run preview:\n${stdout}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { tool } from "@opencode-ai/plugin";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
4
|
|
|
5
5
|
const RESERVATIONS_DIR = ".reservations";
|
|
6
6
|
const MESSAGES_FILE = "messages.jsonl";
|
|
@@ -84,7 +84,7 @@ export default tool({
|
|
|
84
84
|
}
|
|
85
85
|
await fs.writeFile(
|
|
86
86
|
messagesPath,
|
|
87
|
-
allMsgs.map((m) => JSON.stringify(m)).join("\n")
|
|
87
|
+
`${allMsgs.map((m) => JSON.stringify(m)).join("\n")}\n`,
|
|
88
88
|
"utf-8",
|
|
89
89
|
);
|
|
90
90
|
}
|
|
@@ -99,11 +99,12 @@ export default tool({
|
|
|
99
99
|
messages = messages.slice(-limit).reverse();
|
|
100
100
|
|
|
101
101
|
return JSON.stringify({ msgs: messages, count: messages.length });
|
|
102
|
-
} catch (e
|
|
103
|
-
|
|
102
|
+
} catch (e) {
|
|
103
|
+
const err = e as NodeJS.ErrnoException;
|
|
104
|
+
if (err.code === "ENOENT") {
|
|
104
105
|
return JSON.stringify({ msgs: [], count: 0 });
|
|
105
106
|
}
|
|
106
|
-
return JSON.stringify({ error: e.message });
|
|
107
|
+
return JSON.stringify({ error: (e as Error).message });
|
|
107
108
|
}
|
|
108
109
|
},
|
|
109
110
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { tool } from "@opencode-ai/plugin";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
4
|
|
|
5
5
|
const RESERVATIONS_DIR = ".reservations";
|
|
6
6
|
const MESSAGES_FILE = "messages.jsonl";
|
|
@@ -56,7 +56,7 @@ export default tool({
|
|
|
56
56
|
read: false,
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
await fs.appendFile(messagesPath, JSON.stringify(msg)
|
|
59
|
+
await fs.appendFile(messagesPath, `${JSON.stringify(msg)}\n`, "utf-8");
|
|
60
60
|
return JSON.stringify({ ok: 1, id: msg.id });
|
|
61
61
|
},
|
|
62
62
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { tool } from "@opencode-ai/plugin";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
4
|
|
|
5
5
|
const RESERVATIONS_DIR = ".reservations";
|
|
6
6
|
|
|
@@ -69,8 +69,9 @@ export default tool({
|
|
|
69
69
|
};
|
|
70
70
|
await fs.writeFile(metaPath, JSON.stringify(lockData), "utf-8");
|
|
71
71
|
granted.push(filePath);
|
|
72
|
-
} catch (e
|
|
73
|
-
|
|
72
|
+
} catch (e) {
|
|
73
|
+
const err = e as NodeJS.ErrnoException;
|
|
74
|
+
if (err.code === "EEXIST") {
|
|
74
75
|
// Lock exists - check if expired or ours
|
|
75
76
|
try {
|
|
76
77
|
const content = await fs.readFile(metaPath, "utf-8");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { tool } from "@opencode-ai/plugin";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
4
|
|
|
5
5
|
export default tool({
|
|
6
6
|
description:
|
|
@@ -41,21 +41,20 @@ export default tool({
|
|
|
41
41
|
const appendContent = `\n\n---\n**Updated:** ${timestamp}\n\n${args.content}`;
|
|
42
42
|
await fs.appendFile(filePath, appendContent, "utf-8");
|
|
43
43
|
return `Successfully appended to ${normalizedFile}.md\n[Written to: ${filePath}]`;
|
|
44
|
-
} else {
|
|
45
|
-
// Replace mode - update timestamp
|
|
46
|
-
const timestamp = new Date().toISOString();
|
|
47
|
-
const updatedContent = args.content.replace(
|
|
48
|
-
/\*\*Last Updated:\*\* \[Timestamp\]/,
|
|
49
|
-
`**Last Updated:** ${timestamp}`,
|
|
50
|
-
);
|
|
51
|
-
await fs.writeFile(filePath, updatedContent, "utf-8");
|
|
52
|
-
return `Successfully updated ${normalizedFile}.md\n[Written to: ${filePath}]`;
|
|
53
44
|
}
|
|
45
|
+
// Replace mode - update timestamp
|
|
46
|
+
const timestamp = new Date().toISOString();
|
|
47
|
+
const updatedContent = args.content.replace(
|
|
48
|
+
/\*\*Last Updated:\*\* \[Timestamp\]/,
|
|
49
|
+
`**Last Updated:** ${timestamp}`,
|
|
50
|
+
);
|
|
51
|
+
await fs.writeFile(filePath, updatedContent, "utf-8");
|
|
52
|
+
return `Successfully updated ${normalizedFile}.md\n[Written to: ${filePath}]`;
|
|
54
53
|
} catch (error) {
|
|
55
54
|
if (error instanceof Error) {
|
|
56
55
|
return `Error updating memory: ${error.message}`;
|
|
57
56
|
}
|
|
58
|
-
return
|
|
57
|
+
return "Unknown error updating memory file";
|
|
59
58
|
}
|
|
60
59
|
},
|
|
61
60
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { tool } from "@opencode-ai/plugin";
|
|
3
|
-
import fs from "fs/promises";
|
|
4
4
|
|
|
5
5
|
// Observation types following claude-mem patterns
|
|
6
6
|
type ObservationType =
|
|
@@ -112,9 +112,9 @@ export default tool({
|
|
|
112
112
|
observation += `**Files:** ${files.map((f) => `\`${f}\``).join(", ")}\n`;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
observation +=
|
|
115
|
+
observation += "\n---\n\n";
|
|
116
116
|
observation += args.content;
|
|
117
|
-
observation +=
|
|
117
|
+
observation += "\n";
|
|
118
118
|
|
|
119
119
|
try {
|
|
120
120
|
// Ensure directory exists
|
|
@@ -128,7 +128,7 @@ export default tool({
|
|
|
128
128
|
// Update bead notes if bead_id provided
|
|
129
129
|
if (args.bead_id) {
|
|
130
130
|
try {
|
|
131
|
-
const { execSync } = await import("child_process");
|
|
131
|
+
const { execSync } = await import("node:child_process");
|
|
132
132
|
const noteContent = `${icon} ${obsType}: ${args.title}`;
|
|
133
133
|
execSync(
|
|
134
134
|
`bd edit ${args.bead_id} --note "${noteContent.replace(/"/g, '\\"')}"`,
|
|
@@ -149,7 +149,7 @@ export default tool({
|
|
|
149
149
|
if (error instanceof Error) {
|
|
150
150
|
return `Error saving observation: ${error.message}`;
|
|
151
151
|
}
|
|
152
|
-
return
|
|
152
|
+
return "Unknown error saving observation";
|
|
153
153
|
}
|
|
154
154
|
},
|
|
155
155
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencodekit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"files": ["dist", "README.md"],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"dev": "bun run src/index.ts",
|
|
20
|
-
"build": "bun build
|
|
20
|
+
"build": "bun run build.ts && mkdir -p dist/template && rsync -av --exclude=node_modules --exclude=dist --exclude=.git --exclude=coverage --exclude=.next --exclude=.turbo --exclude=logs --exclude=package-lock.json .opencode/ dist/template/.opencode/",
|
|
21
21
|
"compile": "bun build src/index.ts --compile --outfile ock",
|
|
22
22
|
"compile:binary": "bun build src/index.ts --compile --outfile bin/ock",
|
|
23
23
|
"typecheck": "tsc --noEmit",
|
|
@@ -35,11 +35,14 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@clack/prompts": "^0.7.0",
|
|
37
37
|
"@opencode-ai/plugin": "^1.1.2",
|
|
38
|
+
"@opentui/core": "^0.1.69",
|
|
39
|
+
"@opentui/solid": "^0.1.69",
|
|
38
40
|
"beads-village": "^1.3.3",
|
|
39
41
|
"cac": "^6.7.14",
|
|
40
42
|
"cli-table3": "^0.6.5",
|
|
41
43
|
"ora": "^9.0.0",
|
|
42
44
|
"picocolors": "^1.1.1",
|
|
45
|
+
"solid-js": "^1.9.10",
|
|
43
46
|
"zod": "^3.23.8"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|