opencodekit 0.15.9 → 0.15.11

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 (62) hide show
  1. package/dist/index.js +9 -7
  2. package/dist/template/.opencode/AGENTS.md +7 -2
  3. package/dist/template/.opencode/agent/build.md +390 -0
  4. package/dist/template/.opencode/agent/general.md +1 -0
  5. package/dist/template/.opencode/agent/looker.md +1 -0
  6. package/dist/template/.opencode/agent/painter.md +218 -0
  7. package/dist/template/.opencode/agent/plan.md +3 -0
  8. package/dist/template/.opencode/agent/vision.md +1 -0
  9. package/dist/template/.opencode/command/edit-image.md +1 -2
  10. package/dist/template/.opencode/command/generate-icon.md +1 -2
  11. package/dist/template/.opencode/command/generate-image.md +1 -2
  12. package/dist/template/.opencode/command/generate-pattern.md +1 -2
  13. package/dist/template/.opencode/command/generate-storyboard.md +1 -2
  14. package/dist/template/.opencode/command/implement.md +136 -10
  15. package/dist/template/.opencode/command/restore-image.md +1 -2
  16. package/dist/template/.opencode/dcp.jsonc +1 -15
  17. package/dist/template/.opencode/memory/observations/2026-01-25-decision-agent-roles-build-orchestrates-general-e.md +14 -0
  18. package/dist/template/.opencode/memory/observations/2026-01-25-decision-simplified-swarm-helper-tool-to-fix-type.md +20 -0
  19. package/dist/template/.opencode/memory/observations/2026-01-25-decision-use-beads-as-swarm-board-source-of-truth.md +14 -0
  20. package/dist/template/.opencode/memory/observations/2026-01-25-learning-user-wants-real-swarm-coordination-guida.md +15 -0
  21. package/dist/template/.opencode/memory/research/opencode-mcp-bug-report.md +126 -0
  22. package/dist/template/.opencode/opencode.json +812 -704
  23. package/dist/template/.opencode/package.json +1 -1
  24. package/dist/template/.opencode/plans/swarm-protocol.md +123 -0
  25. package/dist/template/.opencode/plugin/README.md +10 -0
  26. package/dist/template/.opencode/plugin/swarm-enforcer.ts +297 -0
  27. package/dist/template/.opencode/skill/supabase-postgres-best-practices/AGENTS.md +1490 -0
  28. package/dist/template/.opencode/skill/supabase-postgres-best-practices/SKILL.md +57 -0
  29. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
  30. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
  31. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
  32. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
  33. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
  34. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
  35. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
  36. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
  37. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
  38. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
  39. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
  40. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
  41. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
  42. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
  43. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
  44. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
  45. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
  46. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
  47. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
  48. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
  49. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
  50. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
  51. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
  52. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
  53. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
  54. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
  55. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
  56. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
  57. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
  58. package/dist/template/.opencode/skill/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
  59. package/dist/template/.opencode/skill/swarm-coordination/SKILL.md +405 -0
  60. package/dist/template/.opencode/tool/swarm-delegate.ts +175 -0
  61. package/dist/template/.opencode/tool/swarm-helper.ts +164 -0
  62. package/package.json +1 -1
@@ -0,0 +1,175 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { tool } from "@opencode-ai/plugin";
4
+
5
+ function isSafePathSegment(value: string): boolean {
6
+ if (!value) return false;
7
+ if (value.includes("..")) return false;
8
+ if (value.includes("/")) return false;
9
+ if (value.includes("\\")) return false;
10
+ return true;
11
+ }
12
+
13
+ function sanitizeFilename(value: string): string {
14
+ const trimmed = value.trim();
15
+ if (!trimmed) return "delegation.md";
16
+ if (!isSafePathSegment(trimmed)) return "delegation.md";
17
+ return trimmed;
18
+ }
19
+
20
+ function splitList(input?: string): string[] {
21
+ if (!input) return [];
22
+ const parts = input
23
+ .split(/\r?\n|,/g)
24
+ .map((s) => s.trim())
25
+ .filter(Boolean);
26
+ return [...new Set(parts)];
27
+ }
28
+
29
+ function formatBullets(items: string[]): string {
30
+ if (items.length === 0) return "- (none)";
31
+ return items.map((i) => `- ${i}`).join("\n");
32
+ }
33
+
34
+ async function fileExists(filePath: string): Promise<boolean> {
35
+ try {
36
+ await fs.access(filePath);
37
+ return true;
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ export default tool({
44
+ description: `Generate a Swarm delegation packet (Beads-as-board).
45
+
46
+ Purpose:
47
+ - Creates a consistent delegation envelope for a specific Beads task
48
+ - Optionally appends it to .beads/artifacts/<id>/delegation.md
49
+
50
+ Example:
51
+ swarm-delegate({
52
+ bead_id: "opencodekit-template-xyz",
53
+ title: "Add feature X",
54
+ expected_outcome: "Feature X works and tests pass",
55
+ required_tools: "read, grep, lsp, bash",
56
+ must_do: "LSP before edits, run project verification commands",
57
+ must_not_do: "no new deps, don't edit dist/",
58
+ acceptance_checks: "typecheck: <command>, lint: <command>, test: <command>",
59
+ context: "See .beads/artifacts/<id>/spec.md",
60
+ write: true
61
+ })`,
62
+ args: {
63
+ bead_id: tool.schema
64
+ .string()
65
+ .describe("Beads issue id (e.g., opencodekit-template-abc)"),
66
+ title: tool.schema
67
+ .string()
68
+ .optional()
69
+ .describe("Optional title (defaults to Beads id only)"),
70
+ expected_outcome: tool.schema
71
+ .string()
72
+ .describe("Measurable end state for this task"),
73
+ required_tools: tool.schema
74
+ .string()
75
+ .optional()
76
+ .describe("Comma/newline-separated list of tools"),
77
+ must_do: tool.schema
78
+ .string()
79
+ .optional()
80
+ .describe("Comma/newline-separated MUST DO list"),
81
+ must_not_do: tool.schema
82
+ .string()
83
+ .optional()
84
+ .describe("Comma/newline-separated MUST NOT DO list"),
85
+ acceptance_checks: tool.schema
86
+ .string()
87
+ .optional()
88
+ .describe(
89
+ "Comma/newline-separated checks (prefer 'typecheck: <command>', 'lint: <command>', 'test: <command>')",
90
+ ),
91
+ context: tool.schema
92
+ .string()
93
+ .optional()
94
+ .describe("Extra context pointers (files/links/notes)"),
95
+ write: tool.schema
96
+ .boolean()
97
+ .optional()
98
+ .describe("When true, append packet to task artifact file"),
99
+ output_file: tool.schema
100
+ .string()
101
+ .optional()
102
+ .describe(
103
+ "Artifact filename under .beads/artifacts/<id>/ (default: delegation.md)",
104
+ ),
105
+ },
106
+ execute: async (args: {
107
+ bead_id: string;
108
+ title?: string;
109
+ expected_outcome: string;
110
+ required_tools?: string;
111
+ must_do?: string;
112
+ must_not_do?: string;
113
+ acceptance_checks?: string;
114
+ context?: string;
115
+ write?: boolean;
116
+ output_file?: string;
117
+ }) => {
118
+ const beadId = args.bead_id.trim();
119
+ if (!beadId) return "Error: bead_id is required.";
120
+ if (!isSafePathSegment(beadId)) {
121
+ return "Error: bead_id must be a single path segment (no slashes or '..').";
122
+ }
123
+
124
+ const title = args.title?.trim();
125
+ const taskLine = title ? `${beadId} - ${title}` : beadId;
126
+
127
+ const requiredTools = splitList(args.required_tools);
128
+ const mustDo = splitList(args.must_do);
129
+ const mustNotDo = splitList(args.must_not_do);
130
+ const acceptanceChecks = splitList(args.acceptance_checks);
131
+ const context = args.context?.trim();
132
+
133
+ const now = new Date();
134
+ const stamp = now.toISOString();
135
+
136
+ const packet = [
137
+ "# Delegation Packet",
138
+ "",
139
+ `- TASK: ${taskLine}`,
140
+ `- EXPECTED OUTCOME: ${args.expected_outcome.trim()}`,
141
+ "- REQUIRED TOOLS:",
142
+ formatBullets(requiredTools),
143
+ "- MUST DO:",
144
+ formatBullets(mustDo),
145
+ "- MUST NOT DO:",
146
+ formatBullets(mustNotDo),
147
+ "- ACCEPTANCE CHECKS:",
148
+ formatBullets(acceptanceChecks),
149
+ "- CONTEXT:",
150
+ context ? context : "(none)",
151
+ ].join("\n");
152
+
153
+ if (!args.write) {
154
+ return `${packet}\n`;
155
+ }
156
+
157
+ const artifactDir = path.join(process.cwd(), ".beads", "artifacts", beadId);
158
+ const outName = sanitizeFilename(args.output_file || "delegation.md");
159
+ const outPath = path.join(artifactDir, outName);
160
+
161
+ const specPath = path.join(artifactDir, "spec.md");
162
+ const hasSpec = await fileExists(specPath);
163
+
164
+ await fs.mkdir(artifactDir, { recursive: true });
165
+
166
+ const header = `\n\n---\nGenerated: ${stamp}\n---\n\n`;
167
+ await fs.appendFile(outPath, `${header}${packet}\n`, "utf-8");
168
+
169
+ const specNote = hasSpec
170
+ ? ""
171
+ : `\nWarning: spec.md not found at ${specPath}`;
172
+
173
+ return `✓ Delegation packet appended to ${outPath}${specNote}\n\n${packet}\n`;
174
+ },
175
+ });
@@ -0,0 +1,164 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { tool } from "@opencode-ai/plugin";
4
+
5
+ export const SWARM_MAIL_FILE = ".beads/swarm-mail.jsonl";
6
+
7
+ type BaseArgs = {
8
+ team_name: string;
9
+ };
10
+
11
+ type GetTeamStatusArgs = BaseArgs & {
12
+ limit?: number;
13
+ };
14
+
15
+ type SendTeamMessageArgs = BaseArgs & {
16
+ from_worker?: string;
17
+ to_worker?: string;
18
+ message: string;
19
+ };
20
+
21
+ export default tool({
22
+ description: `Swarm coordination helper.
23
+
24
+ Operations:
25
+ - getTeamStatus: Read swarm mailbox for worker reports and progress
26
+ - sendTeamMessage: Write to swarm mailbox for coordination
27
+
28
+ Pattern:
29
+ - Build agent orchestrates: parses plan → spawns team → monitors → synthesizes
30
+ - General agent executes: reads delegation packet → makes changes → reports back
31
+ - Coordination via mailbox: .beads/swarm-mail.jsonl (append-only log)
32
+
33
+ Example:
34
+ getTeamStatus({ team_name: "plan-implementation" })
35
+ → Returns: worker_status for each worker (pending/working/done/error)
36
+
37
+ sendTeamMessage({
38
+ team_name: "plan-implementation",
39
+ from_worker: "worker-1",
40
+ to_worker: "worker-2",
41
+ message: "Need help with file locking",
42
+ })
43
+ → Appends JSONL line: { timestamp, from, to, message }
44
+
45
+ `,
46
+ args: {
47
+ team_name: tool.schema
48
+ .string()
49
+ .describe("Team identifier (e.g., plan-implementation, auth-feature)"),
50
+ operation: tool.schema
51
+ .enum(["getTeamStatus", "sendTeamMessage"])
52
+ .describe("Which swarm coordination operation to perform"),
53
+ from_worker: tool.schema
54
+ .string()
55
+ .optional()
56
+ .describe("Sending worker name (sendTeamMessage)"),
57
+ to_worker: tool.schema
58
+ .string()
59
+ .optional()
60
+ .describe("Target worker name (sendTeamMessage)"),
61
+ message: tool.schema
62
+ .string()
63
+ .optional()
64
+ .describe("Message content (sendTeamMessage)"),
65
+ limit: tool.schema
66
+ .number()
67
+ .optional()
68
+ .describe("Limit mailbox entries (getTeamStatus)"),
69
+ },
70
+ execute: async (args) => {
71
+ const operation = args.operation as string;
72
+
73
+ if (operation === "getTeamStatus") {
74
+ const result = await getTeamStatus(args as any);
75
+ return result;
76
+ }
77
+
78
+ if (operation === "sendTeamMessage") {
79
+ const result = await sendTeamMessage(args as any);
80
+ return result;
81
+ }
82
+
83
+ return `Error: Unknown operation: ${operation}. Valid: getTeamStatus, sendTeamMessage`;
84
+ },
85
+ });
86
+
87
+ async function getTeamStatus(args: GetTeamStatusArgs) {
88
+ const { team_name, limit } = args;
89
+
90
+ if (!team_name) {
91
+ return "Error: team_name is required.";
92
+ }
93
+
94
+ const mailPath = path.join(process.cwd(), SWARM_MAIL_FILE);
95
+ let lines: string[];
96
+
97
+ try {
98
+ const content = await fs.readFile(mailPath, "utf-8");
99
+ lines = content.trim().split("\n").filter(Boolean);
100
+ } catch {
101
+ return `Error: Failed to read ${SWARM_MAIL_FILE}.`;
102
+ }
103
+
104
+ const team_messages = lines
105
+ .map((line) => {
106
+ try {
107
+ return JSON.parse(line) as {
108
+ timestamp: string;
109
+ team_name: string;
110
+ from_worker?: string;
111
+ to_worker?: string;
112
+ message?: string;
113
+ status?: string;
114
+ };
115
+ } catch {
116
+ return null;
117
+ }
118
+ })
119
+ .filter(Boolean);
120
+
121
+ const relevant = team_messages.filter((m) => m.team_name === team_name);
122
+
123
+ if (limit && limit > 0) {
124
+ return JSON.stringify(relevant.slice(-limit), null, 2);
125
+ }
126
+
127
+ return JSON.stringify(relevant, null, 2);
128
+ }
129
+
130
+ async function sendTeamMessage(args: SendTeamMessageArgs) {
131
+ const { team_name, from_worker, to_worker, message } = args;
132
+
133
+ if (!team_name || !message) {
134
+ return "Error: team_name and message are required.";
135
+ }
136
+
137
+ const mailPath = path.join(process.cwd(), SWARM_MAIL_FILE);
138
+ const entry = {
139
+ timestamp: new Date().toISOString(),
140
+ team_name,
141
+ from_worker: from_worker || "system",
142
+ to_worker: to_worker || "all",
143
+ message,
144
+ status: "unread",
145
+ };
146
+
147
+ try {
148
+ await fs.appendFile(mailPath, `${JSON.stringify(entry)}\n`, "utf-8");
149
+ return JSON.stringify(
150
+ {
151
+ success: true,
152
+ team_name,
153
+ from_worker,
154
+ to_worker,
155
+ message,
156
+ mail_file: SWARM_MAIL_FILE,
157
+ },
158
+ null,
159
+ 2,
160
+ );
161
+ } catch (error: any) {
162
+ return `Error: Failed to write to ${SWARM_MAIL_FILE}: ${error}`;
163
+ }
164
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.15.9",
3
+ "version": "0.15.11",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
6
6
  "license": "MIT",