@horizon-ai-dev/shokunin 0.1.0-alpha.1
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/LICENSE +9 -0
- package/README.md +236 -0
- package/dist/agents/sn-code-reviewer.d.ts +13 -0
- package/dist/agents/sn-code-reviewer.d.ts.map +1 -0
- package/dist/agents/sn-code-reviewer.js +75 -0
- package/dist/agents/sn-code-reviewer.js.map +1 -0
- package/dist/agents/sn-code-simplifier.d.ts +13 -0
- package/dist/agents/sn-code-simplifier.d.ts.map +1 -0
- package/dist/agents/sn-code-simplifier.js +70 -0
- package/dist/agents/sn-code-simplifier.js.map +1 -0
- package/dist/agents/sn-comment-analyzer.d.ts +12 -0
- package/dist/agents/sn-comment-analyzer.d.ts.map +1 -0
- package/dist/agents/sn-comment-analyzer.js +65 -0
- package/dist/agents/sn-comment-analyzer.js.map +1 -0
- package/dist/agents/sn-pr-test-analyzer.d.ts +12 -0
- package/dist/agents/sn-pr-test-analyzer.d.ts.map +1 -0
- package/dist/agents/sn-pr-test-analyzer.js +78 -0
- package/dist/agents/sn-pr-test-analyzer.js.map +1 -0
- package/dist/agents/sn-silent-failure-hunter.d.ts +12 -0
- package/dist/agents/sn-silent-failure-hunter.d.ts.map +1 -0
- package/dist/agents/sn-silent-failure-hunter.js +84 -0
- package/dist/agents/sn-silent-failure-hunter.js.map +1 -0
- package/dist/agents/sn-skill-reviewer.d.ts +12 -0
- package/dist/agents/sn-skill-reviewer.d.ts.map +1 -0
- package/dist/agents/sn-skill-reviewer.js +93 -0
- package/dist/agents/sn-skill-reviewer.js.map +1 -0
- package/dist/agents/sn-type-design-analyzer.d.ts +12 -0
- package/dist/agents/sn-type-design-analyzer.d.ts.map +1 -0
- package/dist/agents/sn-type-design-analyzer.js +109 -0
- package/dist/agents/sn-type-design-analyzer.js.map +1 -0
- package/dist/commands/sn-check-config.d.ts +23 -0
- package/dist/commands/sn-check-config.d.ts.map +1 -0
- package/dist/commands/sn-check-config.js +230 -0
- package/dist/commands/sn-check-config.js.map +1 -0
- package/dist/commands/sn-configure.d.ts +27 -0
- package/dist/commands/sn-configure.d.ts.map +1 -0
- package/dist/commands/sn-configure.js +273 -0
- package/dist/commands/sn-configure.js.map +1 -0
- package/dist/commands/sn-review-pr.d.ts +16 -0
- package/dist/commands/sn-review-pr.d.ts.map +1 -0
- package/dist/commands/sn-review-pr.js +113 -0
- package/dist/commands/sn-review-pr.js.map +1 -0
- package/dist/commands/sn-update.d.ts +23 -0
- package/dist/commands/sn-update.d.ts.map +1 -0
- package/dist/commands/sn-update.js +202 -0
- package/dist/commands/sn-update.js.map +1 -0
- package/dist/context/shokunin-rules.d.ts +26 -0
- package/dist/context/shokunin-rules.d.ts.map +1 -0
- package/dist/context/shokunin-rules.js +59 -0
- package/dist/context/shokunin-rules.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/logger.d.ts +50 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +52 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/smart-merge.d.ts +130 -0
- package/dist/lib/smart-merge.d.ts.map +1 -0
- package/dist/lib/smart-merge.js +368 -0
- package/dist/lib/smart-merge.js.map +1 -0
- package/dist/plugin.d.ts +30 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +133 -0
- package/dist/plugin.js.map +1 -0
- package/dist/tools/emergency-stop.d.ts +15 -0
- package/dist/tools/emergency-stop.d.ts.map +1 -0
- package/dist/tools/emergency-stop.js +97 -0
- package/dist/tools/emergency-stop.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart-merge utilities for config files.
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for merging plugin configuration into user's
|
|
5
|
+
* opencode.json without overwriting existing settings.
|
|
6
|
+
*
|
|
7
|
+
* Used by /sn-configure and /sn-update commands.
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Internal helpers
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Check if a value is a plain object (not array, null, etc.)
|
|
14
|
+
*/
|
|
15
|
+
function isPlainObject(value) {
|
|
16
|
+
return (typeof value === "object" &&
|
|
17
|
+
value !== null &&
|
|
18
|
+
!Array.isArray(value) &&
|
|
19
|
+
Object.prototype.toString.call(value) === "[object Object]");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Stringify a value for comparison purposes.
|
|
23
|
+
*/
|
|
24
|
+
function stringify(value) {
|
|
25
|
+
if (value === null || value === undefined) {
|
|
26
|
+
return JSON.stringify(value);
|
|
27
|
+
}
|
|
28
|
+
if (typeof value !== "object") {
|
|
29
|
+
return JSON.stringify(value);
|
|
30
|
+
}
|
|
31
|
+
return JSON.stringify(value, Object.keys(value).sort());
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Deep equality check for two values.
|
|
35
|
+
*/
|
|
36
|
+
function deepEqual(a, b) {
|
|
37
|
+
return stringify(a) === stringify(b);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Deep clone a value using JSON serialization.
|
|
41
|
+
*/
|
|
42
|
+
function deepClone(value) {
|
|
43
|
+
return JSON.parse(JSON.stringify(value));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build a path string from parent and key.
|
|
47
|
+
*/
|
|
48
|
+
function buildPath(parentPath, key) {
|
|
49
|
+
return parentPath ? `${parentPath}.${key}` : key;
|
|
50
|
+
}
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Array merge
|
|
53
|
+
// ============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Merge arrays, adding only unique items from additions.
|
|
56
|
+
*
|
|
57
|
+
* Uses JSON.stringify for deep equality comparison of objects.
|
|
58
|
+
*
|
|
59
|
+
* @param existing - The existing array
|
|
60
|
+
* @param additions - Items to potentially add
|
|
61
|
+
* @returns New array with unique items from both
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* mergeArrayUnique([1, 2, 3], [2, 3, 4]);
|
|
66
|
+
* // => [1, 2, 3, 4]
|
|
67
|
+
*
|
|
68
|
+
* mergeArrayUnique([{ a: 1 }], [{ a: 1 }, { b: 2 }]);
|
|
69
|
+
* // => [{ a: 1 }, { b: 2 }]
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function mergeArrayUnique(existing, additions) {
|
|
73
|
+
const result = [...existing];
|
|
74
|
+
const existingSet = new Set(existing.map((item) => stringify(item)));
|
|
75
|
+
for (const item of additions) {
|
|
76
|
+
const key = stringify(item);
|
|
77
|
+
if (!existingSet.has(key)) {
|
|
78
|
+
result.push(item);
|
|
79
|
+
existingSet.add(key);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Handle the case when a key doesn't exist in existing object.
|
|
86
|
+
*/
|
|
87
|
+
function handleNewKey(ctx, key, newValue) {
|
|
88
|
+
ctx.merged[key] = deepClone(newValue);
|
|
89
|
+
ctx.hasChanges = true;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Handle merging two arrays.
|
|
93
|
+
*/
|
|
94
|
+
function handleArrayMerge(ctx, key, existingArray, newArray) {
|
|
95
|
+
const mergedArray = mergeArrayUnique(existingArray, newArray);
|
|
96
|
+
if (mergedArray.length !== existingArray.length) {
|
|
97
|
+
ctx.hasChanges = true;
|
|
98
|
+
}
|
|
99
|
+
ctx.merged[key] = mergedArray;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handle merging two nested objects.
|
|
103
|
+
*/
|
|
104
|
+
function handleNestedObjectMerge(params) {
|
|
105
|
+
const { ctx, key, path, existingObj, newObj } = params;
|
|
106
|
+
const nestedResult = mergeObjectInternal(existingObj, newObj, path);
|
|
107
|
+
ctx.merged[key] = nestedResult.merged;
|
|
108
|
+
ctx.conflicts.push(...nestedResult.conflicts);
|
|
109
|
+
if (nestedResult.hasChanges) {
|
|
110
|
+
ctx.hasChanges = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Handle value conflicts (different primitive values).
|
|
115
|
+
*/
|
|
116
|
+
function handleConflict(ctx, path, existingValue, newValue) {
|
|
117
|
+
ctx.conflicts.push({
|
|
118
|
+
path,
|
|
119
|
+
existingValue,
|
|
120
|
+
newValue,
|
|
121
|
+
});
|
|
122
|
+
// Keep existing value on conflict
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Internal merge implementation with lower complexity.
|
|
126
|
+
*/
|
|
127
|
+
function mergeObjectInternal(existing, additions, parentPath) {
|
|
128
|
+
const ctx = {
|
|
129
|
+
merged: { ...existing },
|
|
130
|
+
conflicts: [],
|
|
131
|
+
hasChanges: false,
|
|
132
|
+
};
|
|
133
|
+
for (const key of Object.keys(additions)) {
|
|
134
|
+
const path = buildPath(parentPath, key);
|
|
135
|
+
const existingValue = existing[key];
|
|
136
|
+
const newValue = additions[key];
|
|
137
|
+
if (!(key in existing)) {
|
|
138
|
+
handleNewKey(ctx, key, newValue);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
142
|
+
handleArrayMerge(ctx, key, existingValue, newValue);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const bothObjects = isPlainObject(existingValue) && isPlainObject(newValue);
|
|
146
|
+
if (bothObjects) {
|
|
147
|
+
handleNestedObjectMerge({
|
|
148
|
+
ctx,
|
|
149
|
+
key,
|
|
150
|
+
path,
|
|
151
|
+
existingObj: existingValue,
|
|
152
|
+
newObj: newValue,
|
|
153
|
+
});
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (!deepEqual(existingValue, newValue)) {
|
|
157
|
+
handleConflict(ctx, path, existingValue, newValue);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return ctx;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Deep merge two objects, detecting value conflicts.
|
|
164
|
+
*
|
|
165
|
+
* - For arrays: merges using mergeArrayUnique
|
|
166
|
+
* - For objects: recursively merges nested objects
|
|
167
|
+
* - For primitives: detects conflicts when values differ
|
|
168
|
+
*
|
|
169
|
+
* @param existing - The existing object
|
|
170
|
+
* @param additions - Object with values to merge in
|
|
171
|
+
* @returns Merged object and any conflicts detected
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* mergeObject(
|
|
176
|
+
* { a: 1, b: { c: 2 } },
|
|
177
|
+
* { b: { d: 3 }, e: 4 }
|
|
178
|
+
* );
|
|
179
|
+
* // => { merged: { a: 1, b: { c: 2, d: 3 }, e: 4 }, conflicts: [] }
|
|
180
|
+
*
|
|
181
|
+
* mergeObject({ a: 1 }, { a: 2 });
|
|
182
|
+
* // => { merged: { a: 1 }, conflicts: [{ path: 'a', existingValue: 1, newValue: 2 }] }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export function mergeObject(existing, additions) {
|
|
186
|
+
return mergeObjectInternal(existing, additions, "");
|
|
187
|
+
}
|
|
188
|
+
// ============================================================================
|
|
189
|
+
// Change collection - helpers for reduced complexity
|
|
190
|
+
// ============================================================================
|
|
191
|
+
/**
|
|
192
|
+
* Handle new key addition in change collection.
|
|
193
|
+
*/
|
|
194
|
+
function recordAddition(changes, path, newValue) {
|
|
195
|
+
changes.push({ type: "added", path, value: newValue });
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Handle array modification in change collection.
|
|
199
|
+
*/
|
|
200
|
+
function recordArrayChange(changes, path, existingArray, newArray) {
|
|
201
|
+
const existingSet = new Set(existingArray.map((item) => stringify(item)));
|
|
202
|
+
const newItems = newArray.filter((item) => !existingSet.has(stringify(item)));
|
|
203
|
+
if (newItems.length > 0) {
|
|
204
|
+
changes.push({
|
|
205
|
+
type: "modified",
|
|
206
|
+
path,
|
|
207
|
+
value: newItems,
|
|
208
|
+
previousValue: `(array with ${existingArray.length} items)`,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Record a value conflict in change collection.
|
|
214
|
+
*/
|
|
215
|
+
function recordConflict(changes, path, existingValue, newValue) {
|
|
216
|
+
changes.push({
|
|
217
|
+
type: "conflict",
|
|
218
|
+
path,
|
|
219
|
+
value: newValue,
|
|
220
|
+
previousValue: existingValue,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Recursively collect changes between original and additions.
|
|
225
|
+
*/
|
|
226
|
+
function collectChanges(original, additions, parentPath, changes) {
|
|
227
|
+
for (const key of Object.keys(additions)) {
|
|
228
|
+
const path = buildPath(parentPath, key);
|
|
229
|
+
const existingValue = original[key];
|
|
230
|
+
const newValue = additions[key];
|
|
231
|
+
if (!(key in original)) {
|
|
232
|
+
recordAddition(changes, path, newValue);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
236
|
+
recordArrayChange(changes, path, existingValue, newValue);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const bothObjects = isPlainObject(existingValue) && isPlainObject(newValue);
|
|
240
|
+
if (bothObjects) {
|
|
241
|
+
collectChanges(existingValue, newValue, path, changes);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (!deepEqual(existingValue, newValue)) {
|
|
245
|
+
recordConflict(changes, path, existingValue, newValue);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// ============================================================================
|
|
250
|
+
// Summary formatting - helpers for reduced complexity
|
|
251
|
+
// ============================================================================
|
|
252
|
+
/**
|
|
253
|
+
* Format added changes for summary.
|
|
254
|
+
*/
|
|
255
|
+
function formatAddedChanges(added) {
|
|
256
|
+
if (added.length === 0) {
|
|
257
|
+
return "";
|
|
258
|
+
}
|
|
259
|
+
let result = "Added:\n";
|
|
260
|
+
for (const change of added) {
|
|
261
|
+
result += ` + ${change.path}\n`;
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Format modified changes for summary.
|
|
267
|
+
*/
|
|
268
|
+
function formatModifiedChanges(modified) {
|
|
269
|
+
if (modified.length === 0) {
|
|
270
|
+
return "";
|
|
271
|
+
}
|
|
272
|
+
let result = "Modified:\n";
|
|
273
|
+
for (const change of modified) {
|
|
274
|
+
result += ` ~ ${change.path}\n`;
|
|
275
|
+
}
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Format conflict changes for summary.
|
|
280
|
+
*/
|
|
281
|
+
function formatConflictChanges(conflicts) {
|
|
282
|
+
if (conflicts.length === 0) {
|
|
283
|
+
return "";
|
|
284
|
+
}
|
|
285
|
+
let result = "Conflicts (existing value kept):\n";
|
|
286
|
+
for (const change of conflicts) {
|
|
287
|
+
const existing = JSON.stringify(change.previousValue);
|
|
288
|
+
const newVal = JSON.stringify(change.value);
|
|
289
|
+
result += ` ! ${change.path}: existing=${existing}, new=${newVal}\n`;
|
|
290
|
+
}
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Build summary header with counts.
|
|
295
|
+
*/
|
|
296
|
+
function buildSummaryHeader(added, modified, conflicts) {
|
|
297
|
+
const parts = [];
|
|
298
|
+
if (added.length > 0) {
|
|
299
|
+
parts.push(`${added.length} addition${added.length > 1 ? "s" : ""}`);
|
|
300
|
+
}
|
|
301
|
+
if (modified.length > 0) {
|
|
302
|
+
parts.push(`${modified.length} modification${modified.length > 1 ? "s" : ""}`);
|
|
303
|
+
}
|
|
304
|
+
if (conflicts.length > 0) {
|
|
305
|
+
parts.push(`${conflicts.length} conflict${conflicts.length > 1 ? "s" : ""}`);
|
|
306
|
+
}
|
|
307
|
+
return `Changes: ${parts.join(", ")}.\n\n`;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Format changes into a human-readable summary.
|
|
311
|
+
*/
|
|
312
|
+
function formatChangesSummary(changes) {
|
|
313
|
+
if (changes.length === 0) {
|
|
314
|
+
return "No changes needed.";
|
|
315
|
+
}
|
|
316
|
+
const added = changes.filter((c) => c.type === "added");
|
|
317
|
+
const modified = changes.filter((c) => c.type === "modified");
|
|
318
|
+
const conflicts = changes.filter((c) => c.type === "conflict");
|
|
319
|
+
let summary = buildSummaryHeader(added, modified, conflicts);
|
|
320
|
+
summary += formatAddedChanges(added);
|
|
321
|
+
summary += formatModifiedChanges(modified);
|
|
322
|
+
summary += formatConflictChanges(conflicts);
|
|
323
|
+
return summary.trim();
|
|
324
|
+
}
|
|
325
|
+
// ============================================================================
|
|
326
|
+
// Public API - preview and dry run
|
|
327
|
+
// ============================================================================
|
|
328
|
+
/**
|
|
329
|
+
* Preview the changes that would be made by merging additions into existing.
|
|
330
|
+
*
|
|
331
|
+
* @param original - The original object
|
|
332
|
+
* @param additions - Object with values to merge in
|
|
333
|
+
* @returns Preview with list of changes and human-readable summary
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```ts
|
|
337
|
+
* const preview = previewChanges(
|
|
338
|
+
* { a: 1, b: 2 },
|
|
339
|
+
* { b: 3, c: 4 }
|
|
340
|
+
* );
|
|
341
|
+
* // preview.changes = [
|
|
342
|
+
* // { type: 'conflict', path: 'b', value: 3, previousValue: 2 },
|
|
343
|
+
* // { type: 'added', path: 'c', value: 4 }
|
|
344
|
+
* // ]
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
export function previewChanges(original, additions) {
|
|
348
|
+
const changes = [];
|
|
349
|
+
collectChanges(original, additions, "", changes);
|
|
350
|
+
const summary = formatChangesSummary(changes);
|
|
351
|
+
return { changes, summary };
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Perform a merge operation in dry-run mode.
|
|
355
|
+
*
|
|
356
|
+
* Returns the merge result without modifying anything,
|
|
357
|
+
* along with a preview of what would change.
|
|
358
|
+
*
|
|
359
|
+
* @param original - The original object
|
|
360
|
+
* @param additions - Object with values to merge in
|
|
361
|
+
* @returns Merge result and preview
|
|
362
|
+
*/
|
|
363
|
+
export function dryRunMerge(original, additions) {
|
|
364
|
+
const result = mergeObject(original, additions);
|
|
365
|
+
const preview = previewChanges(original, additions);
|
|
366
|
+
return { result, preview };
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=smart-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-merge.js","sourceRoot":"","sources":["../../src/lib/smart-merge.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shokunin Plugin
|
|
3
|
+
*
|
|
4
|
+
* Wraps and extends the opencode-beads plugin with additional
|
|
5
|
+
* Shokunin-specific functionality.
|
|
6
|
+
*
|
|
7
|
+
* Inherited from opencode-beads:
|
|
8
|
+
* - Context injection via `bd prime` on session start and after compaction
|
|
9
|
+
* - Commands parsed from beads command definitions
|
|
10
|
+
* - beads-task-agent for autonomous issue completion
|
|
11
|
+
*
|
|
12
|
+
* Shokunin agents (sn- prefix):
|
|
13
|
+
* - sn-code-reviewer (primary) - Comprehensive code review
|
|
14
|
+
* - sn-code-simplifier (subagent) - Code simplification
|
|
15
|
+
* - sn-comment-analyzer (subagent) - Comment quality analysis
|
|
16
|
+
* - sn-pr-test-analyzer (subagent) - Test coverage analysis
|
|
17
|
+
* - sn-silent-failure-hunter (subagent) - Error handling analysis
|
|
18
|
+
* - sn-type-design-analyzer (subagent) - TypeScript type design
|
|
19
|
+
* - sn-skill-reviewer (subagent) - OpenCode skill review
|
|
20
|
+
*/
|
|
21
|
+
import type { Plugin } from "@opencode-ai/plugin";
|
|
22
|
+
/**
|
|
23
|
+
* The main Shokunin plugin export.
|
|
24
|
+
*
|
|
25
|
+
* Wraps BeadsPlugin and merges any additional Shokunin-specific hooks.
|
|
26
|
+
* This allows extending the plugin functionality while maintaining
|
|
27
|
+
* full compatibility with opencode-beads.
|
|
28
|
+
*/
|
|
29
|
+
export declare const ShokuninPlugin: Plugin;
|
|
30
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAS,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAkDzD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,MA4E5B,CAAC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shokunin Plugin
|
|
3
|
+
*
|
|
4
|
+
* Wraps and extends the opencode-beads plugin with additional
|
|
5
|
+
* Shokunin-specific functionality.
|
|
6
|
+
*
|
|
7
|
+
* Inherited from opencode-beads:
|
|
8
|
+
* - Context injection via `bd prime` on session start and after compaction
|
|
9
|
+
* - Commands parsed from beads command definitions
|
|
10
|
+
* - beads-task-agent for autonomous issue completion
|
|
11
|
+
*
|
|
12
|
+
* Shokunin agents (sn- prefix):
|
|
13
|
+
* - sn-code-reviewer (primary) - Comprehensive code review
|
|
14
|
+
* - sn-code-simplifier (subagent) - Code simplification
|
|
15
|
+
* - sn-comment-analyzer (subagent) - Comment quality analysis
|
|
16
|
+
* - sn-pr-test-analyzer (subagent) - Test coverage analysis
|
|
17
|
+
* - sn-silent-failure-hunter (subagent) - Error handling analysis
|
|
18
|
+
* - sn-type-design-analyzer (subagent) - TypeScript type design
|
|
19
|
+
* - sn-skill-reviewer (subagent) - OpenCode skill review
|
|
20
|
+
*/
|
|
21
|
+
import { BeadsPlugin } from "opencode-beads";
|
|
22
|
+
// Shokunin agents
|
|
23
|
+
import { snCodeReviewerAgent } from "./agents/sn-code-reviewer.js";
|
|
24
|
+
import { snCodeSimplifierAgent } from "./agents/sn-code-simplifier.js";
|
|
25
|
+
import { snCommentAnalyzerAgent } from "./agents/sn-comment-analyzer.js";
|
|
26
|
+
import { snPrTestAnalyzerAgent } from "./agents/sn-pr-test-analyzer.js";
|
|
27
|
+
import { snSilentFailureHunterAgent } from "./agents/sn-silent-failure-hunter.js";
|
|
28
|
+
import { snSkillReviewerAgent } from "./agents/sn-skill-reviewer.js";
|
|
29
|
+
import { snTypeDesignAnalyzerAgent } from "./agents/sn-type-design-analyzer.js";
|
|
30
|
+
// Shokunin commands
|
|
31
|
+
import { snCheckConfigCommand } from "./commands/sn-check-config.js";
|
|
32
|
+
import { snConfigureCommand } from "./commands/sn-configure.js";
|
|
33
|
+
import { snReviewPrCommand } from "./commands/sn-review-pr.js";
|
|
34
|
+
import { snUpdateCommand } from "./commands/sn-update.js";
|
|
35
|
+
// Shokunin context
|
|
36
|
+
import { looksLikeCompaction, SHOKUNIN_RULES, } from "./context/shokunin-rules.js";
|
|
37
|
+
// Shokunin tools
|
|
38
|
+
import { shokuninTools } from "./tools/emergency-stop.js";
|
|
39
|
+
/**
|
|
40
|
+
* All Shokunin commands merged together.
|
|
41
|
+
*/
|
|
42
|
+
const shokuninCommands = {
|
|
43
|
+
...snCheckConfigCommand,
|
|
44
|
+
...snConfigureCommand,
|
|
45
|
+
...snReviewPrCommand,
|
|
46
|
+
...snUpdateCommand,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* All Shokunin agents merged together.
|
|
50
|
+
*/
|
|
51
|
+
const shokuninAgents = {
|
|
52
|
+
...snCodeReviewerAgent,
|
|
53
|
+
...snCodeSimplifierAgent,
|
|
54
|
+
...snCommentAnalyzerAgent,
|
|
55
|
+
...snPrTestAnalyzerAgent,
|
|
56
|
+
...snSilentFailureHunterAgent,
|
|
57
|
+
...snTypeDesignAnalyzerAgent,
|
|
58
|
+
...snSkillReviewerAgent,
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The main Shokunin plugin export.
|
|
62
|
+
*
|
|
63
|
+
* Wraps BeadsPlugin and merges any additional Shokunin-specific hooks.
|
|
64
|
+
* This allows extending the plugin functionality while maintaining
|
|
65
|
+
* full compatibility with opencode-beads.
|
|
66
|
+
*/
|
|
67
|
+
export const ShokuninPlugin = async (input) => {
|
|
68
|
+
const { client } = input;
|
|
69
|
+
// Get hooks from BeadsPlugin
|
|
70
|
+
const beadsHooks = await BeadsPlugin(input);
|
|
71
|
+
// Track sessions that have received shokunin-rules context
|
|
72
|
+
const injectedSessions = new Set();
|
|
73
|
+
// Shokunin-specific hooks
|
|
74
|
+
const shokuninHooks = {
|
|
75
|
+
config: async (config) => {
|
|
76
|
+
// Inject Shokunin agents
|
|
77
|
+
config.agent = {
|
|
78
|
+
...config.agent,
|
|
79
|
+
...shokuninAgents,
|
|
80
|
+
};
|
|
81
|
+
// Inject Shokunin commands
|
|
82
|
+
config.command = {
|
|
83
|
+
...config.command,
|
|
84
|
+
...shokuninCommands,
|
|
85
|
+
};
|
|
86
|
+
// Call beads config hook if it exists
|
|
87
|
+
if (beadsHooks.config) {
|
|
88
|
+
await beadsHooks.config(config);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
// Register Shokunin tools
|
|
92
|
+
tool: shokuninTools,
|
|
93
|
+
// Inject shokunin-rules context on first message and after compaction
|
|
94
|
+
"chat.message": async (hookInput, output) => {
|
|
95
|
+
const sessionID = hookInput.sessionID;
|
|
96
|
+
// Get the first text part from the message
|
|
97
|
+
const textPart = output.parts.find((p) => p.type === "text");
|
|
98
|
+
const messageText = textPart?.type === "text" ? textPart.text : "";
|
|
99
|
+
// Check if this is a new session or post-compaction
|
|
100
|
+
const isNewSession = !injectedSessions.has(sessionID);
|
|
101
|
+
const isPostCompaction = looksLikeCompaction(messageText);
|
|
102
|
+
// Inject context if needed
|
|
103
|
+
if (isNewSession || isPostCompaction) {
|
|
104
|
+
try {
|
|
105
|
+
await client.session.prompt({
|
|
106
|
+
path: { id: sessionID },
|
|
107
|
+
body: {
|
|
108
|
+
noReply: true,
|
|
109
|
+
model: hookInput.model,
|
|
110
|
+
agent: hookInput.agent,
|
|
111
|
+
parts: [{ type: "text", text: SHOKUNIN_RULES, synthetic: true }],
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
injectedSessions.add(sessionID);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Silent skip if injection fails
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Call beads chat.message hook if it exists
|
|
121
|
+
if (beadsHooks["chat.message"]) {
|
|
122
|
+
await beadsHooks["chat.message"](hookInput, output);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
// Merge hooks - shokunin hooks override beads hooks when both exist
|
|
127
|
+
// This ensures our config hook runs and then calls beads' config hook
|
|
128
|
+
return {
|
|
129
|
+
...beadsHooks,
|
|
130
|
+
...shokuninHooks,
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emergency Stop Tool
|
|
3
|
+
*
|
|
4
|
+
* Plays terminal bell to alert users when the LLM needs human input.
|
|
5
|
+
* Works through SSH and VS Code Remote by using the terminal bell character.
|
|
6
|
+
*/
|
|
7
|
+
import type { Hooks } from "@opencode-ai/plugin";
|
|
8
|
+
/**
|
|
9
|
+
* Emergency stop tool for the Shokunin plugin.
|
|
10
|
+
*
|
|
11
|
+
* Plays terminal bell to alert users when human input is required.
|
|
12
|
+
* Returns the tool definition directly - TypeScript will infer the Hooks["tool"] type.
|
|
13
|
+
*/
|
|
14
|
+
export declare const shokuninTools: Hooks["tool"];
|
|
15
|
+
//# sourceMappingURL=emergency-stop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emergency-stop.d.ts","sourceRoot":"","sources":["../../src/tools/emergency-stop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AA2DjD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,MAAM,CAkDvC,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emergency Stop Tool
|
|
3
|
+
*
|
|
4
|
+
* Plays terminal bell to alert users when the LLM needs human input.
|
|
5
|
+
* Works through SSH and VS Code Remote by using the terminal bell character.
|
|
6
|
+
*/
|
|
7
|
+
import { tool } from "@opencode-ai/plugin";
|
|
8
|
+
/**
|
|
9
|
+
* Number of bells to play based on urgency level.
|
|
10
|
+
*/
|
|
11
|
+
const URGENCY_BELLS = {
|
|
12
|
+
low: 1,
|
|
13
|
+
medium: 3,
|
|
14
|
+
high: 5,
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Plays the terminal bell character the specified number of times.
|
|
18
|
+
* The bell character (\x07) works through SSH and VS Code Remote.
|
|
19
|
+
*/
|
|
20
|
+
function playBells(count) {
|
|
21
|
+
for (let i = 0; i < count; i++) {
|
|
22
|
+
process.stdout.write("\x07");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Formats the alert message for the LLM context window.
|
|
27
|
+
*/
|
|
28
|
+
function formatAlertMessage(reason, urgency, context) {
|
|
29
|
+
const timestamp = new Date().toISOString();
|
|
30
|
+
const urgencyLabel = urgency.toUpperCase();
|
|
31
|
+
const bellCount = URGENCY_BELLS[urgency];
|
|
32
|
+
let message = `
|
|
33
|
+
## EMERGENCY STOP ALERT
|
|
34
|
+
|
|
35
|
+
**Timestamp:** ${timestamp}
|
|
36
|
+
**Urgency:** ${urgencyLabel} (${bellCount} bell${bellCount > 1 ? "s" : ""})
|
|
37
|
+
**Reason:** ${reason}
|
|
38
|
+
`;
|
|
39
|
+
if (context) {
|
|
40
|
+
message += `
|
|
41
|
+
**Context:**
|
|
42
|
+
${context}
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
message += `
|
|
46
|
+
---
|
|
47
|
+
*Alert sound played. Waiting for human input.*
|
|
48
|
+
`;
|
|
49
|
+
return message.trim();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Emergency stop tool for the Shokunin plugin.
|
|
53
|
+
*
|
|
54
|
+
* Plays terminal bell to alert users when human input is required.
|
|
55
|
+
* Returns the tool definition directly - TypeScript will infer the Hooks["tool"] type.
|
|
56
|
+
*/
|
|
57
|
+
export const shokuninTools = {
|
|
58
|
+
emergency_stop: tool({
|
|
59
|
+
description: "Play an alert sound (terminal bell) to notify the user that their attention is required. " +
|
|
60
|
+
"Use when: (1) you encounter a critical decision that requires human judgment, " +
|
|
61
|
+
"(2) you find a potential security issue that needs review, " +
|
|
62
|
+
"(3) you're blocked and cannot proceed without clarification, " +
|
|
63
|
+
"(4) you've completed a significant milestone and need review, or " +
|
|
64
|
+
"(5) you encounter an error you cannot resolve autonomously.",
|
|
65
|
+
args: {
|
|
66
|
+
reason: tool.schema
|
|
67
|
+
.string()
|
|
68
|
+
.describe("The reason why human input is needed"),
|
|
69
|
+
urgency: tool.schema
|
|
70
|
+
.enum(["low", "medium", "high"])
|
|
71
|
+
.optional()
|
|
72
|
+
.default("medium")
|
|
73
|
+
.describe("Urgency level: low (1 bell), medium (3 bells), high (5 bells). Defaults to medium."),
|
|
74
|
+
context: tool.schema
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe("Additional context about the situation"),
|
|
78
|
+
repeat_interval_seconds: tool.schema
|
|
79
|
+
.number()
|
|
80
|
+
.optional()
|
|
81
|
+
.describe("If provided, repeat the alert at this interval until user responds (not implemented in initial version)"),
|
|
82
|
+
max_repeats: tool.schema
|
|
83
|
+
.number()
|
|
84
|
+
.optional()
|
|
85
|
+
.describe("Maximum number of times to repeat the alert (not implemented in initial version)"),
|
|
86
|
+
},
|
|
87
|
+
execute(args, _context) {
|
|
88
|
+
const urgency = (args.urgency ?? "medium");
|
|
89
|
+
const bellCount = URGENCY_BELLS[urgency];
|
|
90
|
+
// Play terminal bells
|
|
91
|
+
playBells(bellCount);
|
|
92
|
+
// Return formatted message for LLM context
|
|
93
|
+
return Promise.resolve(formatAlertMessage(args.reason, urgency, args.context));
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=emergency-stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emergency-stop.js","sourceRoot":"","sources":["../../src/tools/emergency-stop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,MAAM,aAAa,GAAG;IACpB,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;CACC,CAAC;AAIX;;;GAGG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,MAAc,EACd,OAAqB,EACrB,OAAgB;IAEhB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,OAAO,GAAG;;;iBAGC,SAAS;eACX,YAAY,KAAK,SAAS,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;cAC3D,MAAM;CACnB,CAAC;IAEA,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,IAAI;;EAEb,OAAO;CACR,CAAC;IACA,CAAC;IAED,OAAO,IAAI;;;CAGZ,CAAC;IAEA,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,cAAc,EAAE,IAAI,CAAC;QACnB,WAAW,EACT,2FAA2F;YAC3F,gFAAgF;YAChF,6DAA6D;YAC7D,+DAA+D;YAC/D,mEAAmE;YACnE,6DAA6D;QAC/D,IAAI,EAAE;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;iBAChB,MAAM,EAAE;iBACR,QAAQ,CAAC,sCAAsC,CAAC;YACnD,OAAO,EAAE,IAAI,CAAC,MAAM;iBACjB,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;iBAC/B,QAAQ,EAAE;iBACV,OAAO,CAAC,QAAQ,CAAC;iBACjB,QAAQ,CACP,oFAAoF,CACrF;YACH,OAAO,EAAE,IAAI,CAAC,MAAM;iBACjB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,wCAAwC,CAAC;YACrD,uBAAuB,EAAE,IAAI,CAAC,MAAM;iBACjC,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,yGAAyG,CAC1G;YACH,WAAW,EAAE,IAAI,CAAC,MAAM;iBACrB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,kFAAkF,CACnF;SACJ;QACD,OAAO,CAAC,IAAI,EAAE,QAAQ;YACpB,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAiB,CAAC;YAC3D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YAEzC,sBAAsB;YACtB,SAAS,CAAC,SAAS,CAAC,CAAC;YAErB,2CAA2C;YAC3C,OAAO,OAAO,CAAC,OAAO,CACpB,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CACvD,CAAC;QACJ,CAAC;KACF,CAAC;CACH,CAAC"}
|