opencodekit 0.1.0 → 0.2.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/dist/index.js +369 -63
- package/dist/template/.opencode/command/analyze-project.md +26 -5
- package/dist/template/.opencode/command/commit.md +30 -2
- package/dist/template/.opencode/command/fix-ci.md +33 -6
- package/dist/template/.opencode/command/fix-types.md +28 -3
- package/dist/template/.opencode/command/issue.md +26 -2
- package/dist/template/.opencode/command/pr.md +20 -3
- package/dist/template/.opencode/command/research-ui.md +20 -4
- package/dist/template/.opencode/command/ui-review.md +26 -2
- package/dist/template/.opencode/dcp.jsonc +1 -1
- package/dist/template/.opencode/memory/_templates/task-design.md +59 -0
- package/dist/template/.opencode/opencode.json +10 -53
- package/dist/template/.opencode/package.json +2 -2
- package/dist/template/.opencode/superpowers/skills/brainstorming/SKILL.md +6 -1
- package/dist/template/.opencode/superpowers/skills/writing-plans/SKILL.md +7 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -750,7 +750,7 @@ var cac = (name = "") => new CAC(name);
|
|
|
750
750
|
// package.json
|
|
751
751
|
var package_default = {
|
|
752
752
|
name: "opencodekit",
|
|
753
|
-
version: "0.1
|
|
753
|
+
version: "0.2.1",
|
|
754
754
|
description: "CLI tool for bootstrapping and managing OpenCodeKit projects",
|
|
755
755
|
type: "module",
|
|
756
756
|
repository: {
|
|
@@ -1968,6 +1968,18 @@ async function configCommand(action) {
|
|
|
1968
1968
|
case "theme":
|
|
1969
1969
|
await editTheme(configPath);
|
|
1970
1970
|
break;
|
|
1971
|
+
case "tui":
|
|
1972
|
+
await editTui(configPath);
|
|
1973
|
+
break;
|
|
1974
|
+
case "tools":
|
|
1975
|
+
await editTools(configPath);
|
|
1976
|
+
break;
|
|
1977
|
+
case "share":
|
|
1978
|
+
await editShare(configPath);
|
|
1979
|
+
break;
|
|
1980
|
+
case "autoupdate":
|
|
1981
|
+
await editAutoupdate(configPath);
|
|
1982
|
+
break;
|
|
1971
1983
|
case "show":
|
|
1972
1984
|
showConfig(configPath);
|
|
1973
1985
|
break;
|
|
@@ -1978,6 +1990,10 @@ async function configCommand(action) {
|
|
|
1978
1990
|
"permission",
|
|
1979
1991
|
"keybinds",
|
|
1980
1992
|
"theme",
|
|
1993
|
+
"tui",
|
|
1994
|
+
"tools",
|
|
1995
|
+
"share",
|
|
1996
|
+
"autoupdate",
|
|
1981
1997
|
"show"
|
|
1982
1998
|
]);
|
|
1983
1999
|
}
|
|
@@ -2000,6 +2016,23 @@ function showConfig(configPath) {
|
|
|
2000
2016
|
}
|
|
2001
2017
|
console.log(import_picocolors7.default.bold(" Theme"));
|
|
2002
2018
|
console.log(` ${import_picocolors7.default.cyan(config.theme || "system")}`);
|
|
2019
|
+
console.log(import_picocolors7.default.bold(" Share"));
|
|
2020
|
+
console.log(` ${import_picocolors7.default.cyan(config.share || "manual")}`);
|
|
2021
|
+
const autoupdateDisplay = config.autoupdate === "notify" ? "notify" : config.autoupdate === false ? "disabled" : "enabled";
|
|
2022
|
+
console.log(import_picocolors7.default.bold(" Autoupdate"));
|
|
2023
|
+
console.log(` ${import_picocolors7.default.cyan(autoupdateDisplay)}`);
|
|
2024
|
+
if (config.tui && Object.keys(config.tui).length > 0) {
|
|
2025
|
+
console.log(import_picocolors7.default.bold(" TUI"));
|
|
2026
|
+
if (config.tui.scroll_speed !== undefined) {
|
|
2027
|
+
console.log(` scroll_speed: ${import_picocolors7.default.cyan(String(config.tui.scroll_speed))}`);
|
|
2028
|
+
}
|
|
2029
|
+
if (config.tui.scroll_acceleration !== undefined) {
|
|
2030
|
+
console.log(` scroll_acceleration: ${import_picocolors7.default.cyan(String(config.tui.scroll_acceleration))}`);
|
|
2031
|
+
}
|
|
2032
|
+
if (config.tui.diff_style) {
|
|
2033
|
+
console.log(` diff_style: ${import_picocolors7.default.cyan(config.tui.diff_style)}`);
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2003
2036
|
if (config.mcp && Object.keys(config.mcp).length > 0) {
|
|
2004
2037
|
console.log(import_picocolors7.default.bold(" MCP Servers"));
|
|
2005
2038
|
for (const [name, server] of Object.entries(config.mcp)) {
|
|
@@ -2007,6 +2040,13 @@ function showConfig(configPath) {
|
|
|
2007
2040
|
console.log(` ${status} ${name}`);
|
|
2008
2041
|
}
|
|
2009
2042
|
}
|
|
2043
|
+
if (config.tools && Object.keys(config.tools).length > 0) {
|
|
2044
|
+
console.log(import_picocolors7.default.bold(" Tools"));
|
|
2045
|
+
for (const [tool, enabled] of Object.entries(config.tools)) {
|
|
2046
|
+
const status = enabled === false ? import_picocolors7.default.red("off") : import_picocolors7.default.green("on");
|
|
2047
|
+
console.log(` ${status} ${tool}`);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2010
2050
|
if (config.keybinds && Object.keys(config.keybinds).length > 0) {
|
|
2011
2051
|
console.log(import_picocolors7.default.bold(" Keybinds"));
|
|
2012
2052
|
for (const [action, key] of Object.entries(config.keybinds)) {
|
|
@@ -2017,55 +2057,74 @@ function showConfig(configPath) {
|
|
|
2017
2057
|
}
|
|
2018
2058
|
async function configMenu(configPath) {
|
|
2019
2059
|
oe(import_picocolors7.default.bgCyan(import_picocolors7.default.black(" Configuration ")));
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
value: "
|
|
2033
|
-
label: "
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2060
|
+
while (true) {
|
|
2061
|
+
const action = await ie({
|
|
2062
|
+
message: "What do you want to configure?",
|
|
2063
|
+
options: [
|
|
2064
|
+
{ value: "model", label: "Model - change default model" },
|
|
2065
|
+
{
|
|
2066
|
+
value: "small_model",
|
|
2067
|
+
label: "Small Model - change small model"
|
|
2068
|
+
},
|
|
2069
|
+
{ value: "agent", label: "Agents - configure agent models" },
|
|
2070
|
+
{ value: "theme", label: "Theme - change UI theme" },
|
|
2071
|
+
{ value: "tui", label: "TUI - scroll speed, diff style" },
|
|
2072
|
+
{ value: "mcp", label: "MCP - manage MCP servers" },
|
|
2073
|
+
{ value: "tools", label: "Tools - enable/disable tools" },
|
|
2074
|
+
{
|
|
2075
|
+
value: "permission",
|
|
2076
|
+
label: "Permissions - bash/edit permissions"
|
|
2077
|
+
},
|
|
2078
|
+
{ value: "keybinds", label: "Keybinds - keyboard shortcuts" },
|
|
2079
|
+
{ value: "share", label: "Share - sharing settings" },
|
|
2080
|
+
{ value: "autoupdate", label: "Autoupdate - update behavior" },
|
|
2081
|
+
{ value: "show", label: "Show - view current config" },
|
|
2082
|
+
{ value: "exit", label: "Exit" }
|
|
2083
|
+
]
|
|
2084
|
+
});
|
|
2085
|
+
if (lD(action) || action === "exit") {
|
|
2086
|
+
$e("Done");
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
switch (action) {
|
|
2090
|
+
case "model":
|
|
2091
|
+
await editModel(configPath);
|
|
2092
|
+
break;
|
|
2093
|
+
case "small_model":
|
|
2094
|
+
await editModel(configPath, "small_model");
|
|
2095
|
+
break;
|
|
2096
|
+
case "agent":
|
|
2097
|
+
await editAgentModel(configPath);
|
|
2098
|
+
break;
|
|
2099
|
+
case "theme":
|
|
2100
|
+
await editTheme(configPath);
|
|
2101
|
+
break;
|
|
2102
|
+
case "tui":
|
|
2103
|
+
await editTui(configPath);
|
|
2104
|
+
break;
|
|
2105
|
+
case "mcp":
|
|
2106
|
+
await editMCP(configPath);
|
|
2107
|
+
break;
|
|
2108
|
+
case "tools":
|
|
2109
|
+
await editTools(configPath);
|
|
2110
|
+
break;
|
|
2111
|
+
case "permission":
|
|
2112
|
+
await editPermissions(configPath);
|
|
2113
|
+
break;
|
|
2114
|
+
case "keybinds":
|
|
2115
|
+
await editKeybinds(configPath);
|
|
2116
|
+
break;
|
|
2117
|
+
case "share":
|
|
2118
|
+
await editShare(configPath);
|
|
2119
|
+
break;
|
|
2120
|
+
case "autoupdate":
|
|
2121
|
+
await editAutoupdate(configPath);
|
|
2122
|
+
break;
|
|
2123
|
+
case "show":
|
|
2124
|
+
showConfig(configPath);
|
|
2125
|
+
break;
|
|
2126
|
+
}
|
|
2127
|
+
console.log();
|
|
2069
2128
|
}
|
|
2070
2129
|
}
|
|
2071
2130
|
async function editModel(configPath, modelType = "model") {
|
|
@@ -2102,6 +2161,11 @@ async function editModel(configPath, modelType = "model") {
|
|
|
2102
2161
|
const configuredProviderIds = new Set(Object.keys(localProviders));
|
|
2103
2162
|
const allProviders = Object.values(modelsDevData);
|
|
2104
2163
|
const quickOptions = [];
|
|
2164
|
+
quickOptions.push({
|
|
2165
|
+
value: "__back__",
|
|
2166
|
+
label: "← Back",
|
|
2167
|
+
hint: "return to menu"
|
|
2168
|
+
});
|
|
2105
2169
|
for (const [providerId2, providerConfig] of Object.entries(localProviders)) {
|
|
2106
2170
|
const modelsDevProvider2 = modelsDevData[providerId2];
|
|
2107
2171
|
const localModels = providerConfig.models || {};
|
|
@@ -2129,10 +2193,12 @@ async function editModel(configPath, modelType = "model") {
|
|
|
2129
2193
|
options: quickOptions
|
|
2130
2194
|
});
|
|
2131
2195
|
if (lD(quickPick)) {
|
|
2132
|
-
ue("Cancelled");
|
|
2133
2196
|
return;
|
|
2134
2197
|
}
|
|
2135
2198
|
let providerId = quickPick;
|
|
2199
|
+
if (providerId === "__back__") {
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2136
2202
|
if (providerId === "__custom__") {
|
|
2137
2203
|
const customModel = await te({
|
|
2138
2204
|
message: `Enter ${modelLabel}`,
|
|
@@ -2186,10 +2252,21 @@ async function editModel(configPath, modelType = "model") {
|
|
|
2186
2252
|
const modelsDevProvider = modelsDevData[providerId];
|
|
2187
2253
|
const localProviderConfig = localProviders[providerId];
|
|
2188
2254
|
let modelOptions = [];
|
|
2255
|
+
modelOptions.push({
|
|
2256
|
+
value: "__back__",
|
|
2257
|
+
label: "← Back",
|
|
2258
|
+
hint: "return to provider selection"
|
|
2259
|
+
});
|
|
2189
2260
|
if (modelsDevProvider && Object.keys(modelsDevProvider.models || {}).length > 0) {
|
|
2190
|
-
modelOptions =
|
|
2261
|
+
modelOptions = [
|
|
2262
|
+
modelOptions[0],
|
|
2263
|
+
...getModelsForProvider(modelsDevProvider)
|
|
2264
|
+
];
|
|
2191
2265
|
} else if (localProviderConfig?.models && Object.keys(localProviderConfig.models).length > 0) {
|
|
2192
|
-
modelOptions =
|
|
2266
|
+
modelOptions = [
|
|
2267
|
+
modelOptions[0],
|
|
2268
|
+
...getModelsFromLocalConfig(localProviderConfig.models)
|
|
2269
|
+
];
|
|
2193
2270
|
} else {
|
|
2194
2271
|
f2.warn(`No models found for ${providerId}`);
|
|
2195
2272
|
return;
|
|
@@ -2198,8 +2275,7 @@ async function editModel(configPath, modelType = "model") {
|
|
|
2198
2275
|
message: `Select model from ${providerId}`,
|
|
2199
2276
|
options: modelOptions
|
|
2200
2277
|
});
|
|
2201
|
-
if (lD(selectedModel)) {
|
|
2202
|
-
ue("Cancelled");
|
|
2278
|
+
if (lD(selectedModel) || selectedModel === "__back__") {
|
|
2203
2279
|
return;
|
|
2204
2280
|
}
|
|
2205
2281
|
const fullModelId = `${providerId}/${selectedModel}`;
|
|
@@ -2287,9 +2363,9 @@ async function editAgentModel(configPath) {
|
|
|
2287
2363
|
console.log(` ${import_picocolors7.default.cyan(name)}: ${model}${builtIn}${disabled}`);
|
|
2288
2364
|
}
|
|
2289
2365
|
console.log();
|
|
2290
|
-
const
|
|
2291
|
-
|
|
2292
|
-
|
|
2366
|
+
const agentOptions = [
|
|
2367
|
+
{ value: "__back__", label: "← Back", hint: "return to menu" },
|
|
2368
|
+
...agentNames.map((name) => {
|
|
2293
2369
|
const info = agentInfoMap.get(name);
|
|
2294
2370
|
return {
|
|
2295
2371
|
value: name,
|
|
@@ -2297,8 +2373,12 @@ async function editAgentModel(configPath) {
|
|
|
2297
2373
|
hint: info?.model || "(default)"
|
|
2298
2374
|
};
|
|
2299
2375
|
})
|
|
2376
|
+
];
|
|
2377
|
+
const selectedAgent = await ie({
|
|
2378
|
+
message: "Select agent to configure",
|
|
2379
|
+
options: agentOptions
|
|
2300
2380
|
});
|
|
2301
|
-
if (lD(selectedAgent)) {
|
|
2381
|
+
if (lD(selectedAgent) || selectedAgent === "__back__") {
|
|
2302
2382
|
return;
|
|
2303
2383
|
}
|
|
2304
2384
|
const agentName = selectedAgent;
|
|
@@ -2306,6 +2386,11 @@ async function editAgentModel(configPath) {
|
|
|
2306
2386
|
const action = await ie({
|
|
2307
2387
|
message: `Configure ${agentName}`,
|
|
2308
2388
|
options: [
|
|
2389
|
+
{
|
|
2390
|
+
value: "__back__",
|
|
2391
|
+
label: "← Back",
|
|
2392
|
+
hint: "return to agent list"
|
|
2393
|
+
},
|
|
2309
2394
|
{ value: "model", label: "Change model" },
|
|
2310
2395
|
{
|
|
2311
2396
|
value: "toggle",
|
|
@@ -2314,7 +2399,7 @@ async function editAgentModel(configPath) {
|
|
|
2314
2399
|
{ value: "description", label: "Edit description" }
|
|
2315
2400
|
]
|
|
2316
2401
|
});
|
|
2317
|
-
if (lD(action)) {
|
|
2402
|
+
if (lD(action) || action === "__back__") {
|
|
2318
2403
|
return;
|
|
2319
2404
|
}
|
|
2320
2405
|
if (action === "toggle") {
|
|
@@ -2373,6 +2458,11 @@ async function editAgentModel(configPath) {
|
|
|
2373
2458
|
const localProviders = config.provider || {};
|
|
2374
2459
|
const allProviders = Object.values(modelsDevData);
|
|
2375
2460
|
const quickOptions = [];
|
|
2461
|
+
quickOptions.push({
|
|
2462
|
+
value: "__back__",
|
|
2463
|
+
label: "← Back",
|
|
2464
|
+
hint: "return to agent list"
|
|
2465
|
+
});
|
|
2376
2466
|
quickOptions.push({
|
|
2377
2467
|
value: "__default__",
|
|
2378
2468
|
label: "Default - use session model",
|
|
@@ -2408,6 +2498,9 @@ async function editAgentModel(configPath) {
|
|
|
2408
2498
|
return;
|
|
2409
2499
|
}
|
|
2410
2500
|
let providerId = quickPick;
|
|
2501
|
+
if (providerId === "__back__") {
|
|
2502
|
+
return;
|
|
2503
|
+
}
|
|
2411
2504
|
if (providerId === "__default__") {
|
|
2412
2505
|
if (!config.agent[agentName]) {
|
|
2413
2506
|
config.agent[agentName] = {};
|
|
@@ -2515,12 +2608,13 @@ async function editMCP(configPath) {
|
|
|
2515
2608
|
const action = await ie({
|
|
2516
2609
|
message: "MCP Servers",
|
|
2517
2610
|
options: [
|
|
2611
|
+
{ value: "__back__", label: "← Back", hint: "return to menu" },
|
|
2518
2612
|
{ value: "toggle", label: "Toggle server on/off" },
|
|
2519
2613
|
{ value: "add", label: "Add new server" },
|
|
2520
2614
|
{ value: "remove", label: "Remove server" }
|
|
2521
2615
|
]
|
|
2522
2616
|
});
|
|
2523
|
-
if (lD(action)) {
|
|
2617
|
+
if (lD(action) || action === "__back__") {
|
|
2524
2618
|
return;
|
|
2525
2619
|
}
|
|
2526
2620
|
switch (action) {
|
|
@@ -2663,6 +2757,7 @@ async function editPermissions(configPath) {
|
|
|
2663
2757
|
const action = await ie({
|
|
2664
2758
|
message: "Edit permission",
|
|
2665
2759
|
options: [
|
|
2760
|
+
{ value: "__back__", label: "← Back", hint: "return to menu" },
|
|
2666
2761
|
{ value: "edit", label: "edit - file editing" },
|
|
2667
2762
|
{
|
|
2668
2763
|
value: "external",
|
|
@@ -2671,7 +2766,7 @@ async function editPermissions(configPath) {
|
|
|
2671
2766
|
{ value: "bash", label: "bash - add command pattern" }
|
|
2672
2767
|
]
|
|
2673
2768
|
});
|
|
2674
|
-
if (lD(action)) {
|
|
2769
|
+
if (lD(action) || action === "__back__") {
|
|
2675
2770
|
return;
|
|
2676
2771
|
}
|
|
2677
2772
|
const permValue = await ie({
|
|
@@ -2726,6 +2821,7 @@ async function editKeybinds(configPath) {
|
|
|
2726
2821
|
const action = await ie({
|
|
2727
2822
|
message: "Select keybind to edit",
|
|
2728
2823
|
options: [
|
|
2824
|
+
{ value: "__back__", label: "← Back", hint: "return to menu" },
|
|
2729
2825
|
{ value: "leader", label: "leader - prefix key" },
|
|
2730
2826
|
{
|
|
2731
2827
|
value: "command_list",
|
|
@@ -2742,7 +2838,7 @@ async function editKeybinds(configPath) {
|
|
|
2742
2838
|
{ value: "custom", label: "Custom keybind" }
|
|
2743
2839
|
]
|
|
2744
2840
|
});
|
|
2745
|
-
if (lD(action)) {
|
|
2841
|
+
if (lD(action) || action === "__back__") {
|
|
2746
2842
|
return;
|
|
2747
2843
|
}
|
|
2748
2844
|
let keybindName = action;
|
|
@@ -2829,6 +2925,216 @@ async function editTheme(configPath) {
|
|
|
2829
2925
|
saveConfig(configPath, config);
|
|
2830
2926
|
f2.success(`Theme set to ${import_picocolors7.default.cyan(selectedTheme)}`);
|
|
2831
2927
|
}
|
|
2928
|
+
async function editTui(configPath) {
|
|
2929
|
+
const config = loadConfig(configPath);
|
|
2930
|
+
if (!config.tui) {
|
|
2931
|
+
config.tui = {};
|
|
2932
|
+
}
|
|
2933
|
+
const setting = await ie({
|
|
2934
|
+
message: "TUI Setting",
|
|
2935
|
+
options: [
|
|
2936
|
+
{
|
|
2937
|
+
value: "__back__",
|
|
2938
|
+
label: "← Back",
|
|
2939
|
+
hint: "return to menu"
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
value: "scroll_speed",
|
|
2943
|
+
label: "Scroll Speed",
|
|
2944
|
+
hint: `current: ${config.tui.scroll_speed ?? "default"}`
|
|
2945
|
+
},
|
|
2946
|
+
{
|
|
2947
|
+
value: "scroll_acceleration",
|
|
2948
|
+
label: "Scroll Acceleration",
|
|
2949
|
+
hint: `current: ${config.tui.scroll_acceleration ?? "default"}`
|
|
2950
|
+
},
|
|
2951
|
+
{
|
|
2952
|
+
value: "diff_style",
|
|
2953
|
+
label: "Diff Style",
|
|
2954
|
+
hint: `current: ${config.tui.diff_style ?? "unified"}`
|
|
2955
|
+
}
|
|
2956
|
+
]
|
|
2957
|
+
});
|
|
2958
|
+
if (lD(setting) || setting === "__back__") {
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
if (setting === "diff_style") {
|
|
2962
|
+
const style = await ie({
|
|
2963
|
+
message: "Diff style",
|
|
2964
|
+
options: [
|
|
2965
|
+
{ value: "unified", label: "Unified", hint: "single column" },
|
|
2966
|
+
{ value: "split", label: "Split", hint: "side by side" }
|
|
2967
|
+
]
|
|
2968
|
+
});
|
|
2969
|
+
if (lD(style)) {
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2972
|
+
config.tui.diff_style = style;
|
|
2973
|
+
saveConfig(configPath, config);
|
|
2974
|
+
f2.success(`Diff style set to ${import_picocolors7.default.cyan(style)}`);
|
|
2975
|
+
} else {
|
|
2976
|
+
const settingKey = setting;
|
|
2977
|
+
const value = await te({
|
|
2978
|
+
message: `${settingKey === "scroll_speed" ? "Scroll speed" : "Scroll acceleration"}`,
|
|
2979
|
+
placeholder: "e.g. 1.0, 2.0",
|
|
2980
|
+
initialValue: String(config.tui[settingKey] ?? ""),
|
|
2981
|
+
validate: (v2) => {
|
|
2982
|
+
if (v2 && Number.isNaN(Number(v2)))
|
|
2983
|
+
return "Must be a number";
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2986
|
+
if (lD(value)) {
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2989
|
+
config.tui[settingKey] = value ? Number(value) : undefined;
|
|
2990
|
+
saveConfig(configPath, config);
|
|
2991
|
+
f2.success(`${settingKey} set to ${import_picocolors7.default.cyan(value || "default")}`);
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
async function editTools(configPath) {
|
|
2995
|
+
const config = loadConfig(configPath);
|
|
2996
|
+
if (!config.tools) {
|
|
2997
|
+
config.tools = {};
|
|
2998
|
+
}
|
|
2999
|
+
const commonTools = [
|
|
3000
|
+
"read",
|
|
3001
|
+
"glob",
|
|
3002
|
+
"grep",
|
|
3003
|
+
"edit",
|
|
3004
|
+
"write",
|
|
3005
|
+
"bash",
|
|
3006
|
+
"webfetch",
|
|
3007
|
+
"todowrite",
|
|
3008
|
+
"todoread"
|
|
3009
|
+
];
|
|
3010
|
+
console.log();
|
|
3011
|
+
console.log(import_picocolors7.default.bold(" Tool Status"));
|
|
3012
|
+
for (const tool of commonTools) {
|
|
3013
|
+
const status = config.tools[tool] === false ? import_picocolors7.default.red("off") : import_picocolors7.default.green("on");
|
|
3014
|
+
console.log(` ${status} ${tool}`);
|
|
3015
|
+
}
|
|
3016
|
+
console.log();
|
|
3017
|
+
const action = await ie({
|
|
3018
|
+
message: "Select action",
|
|
3019
|
+
options: [
|
|
3020
|
+
{ value: "__back__", label: "← Back", hint: "return to menu" },
|
|
3021
|
+
{ value: "toggle", label: "Toggle tool on/off" },
|
|
3022
|
+
{ value: "custom", label: "Add custom tool" }
|
|
3023
|
+
]
|
|
3024
|
+
});
|
|
3025
|
+
if (lD(action) || action === "__back__") {
|
|
3026
|
+
return;
|
|
3027
|
+
}
|
|
3028
|
+
if (action === "toggle") {
|
|
3029
|
+
const allTools = [
|
|
3030
|
+
...new Set([...commonTools, ...Object.keys(config.tools)])
|
|
3031
|
+
];
|
|
3032
|
+
const selected = await ie({
|
|
3033
|
+
message: "Select tool to toggle",
|
|
3034
|
+
options: allTools.map((tool) => ({
|
|
3035
|
+
value: tool,
|
|
3036
|
+
label: tool,
|
|
3037
|
+
hint: config.tools?.[tool] === false ? "off" : "on"
|
|
3038
|
+
}))
|
|
3039
|
+
});
|
|
3040
|
+
if (lD(selected)) {
|
|
3041
|
+
return;
|
|
3042
|
+
}
|
|
3043
|
+
const toolName = selected;
|
|
3044
|
+
const wasEnabled = config.tools[toolName] !== false;
|
|
3045
|
+
config.tools[toolName] = !wasEnabled;
|
|
3046
|
+
saveConfig(configPath, config);
|
|
3047
|
+
const status = config.tools[toolName] ? import_picocolors7.default.green("enabled") : import_picocolors7.default.red("disabled");
|
|
3048
|
+
f2.success(`${toolName}: ${status}`);
|
|
3049
|
+
} else {
|
|
3050
|
+
const toolName = await te({
|
|
3051
|
+
message: "Tool name",
|
|
3052
|
+
placeholder: "e.g. my-custom-tool",
|
|
3053
|
+
validate: (v2) => {
|
|
3054
|
+
if (!v2)
|
|
3055
|
+
return "Tool name is required";
|
|
3056
|
+
}
|
|
3057
|
+
});
|
|
3058
|
+
if (lD(toolName)) {
|
|
3059
|
+
return;
|
|
3060
|
+
}
|
|
3061
|
+
const enabled = await se({
|
|
3062
|
+
message: "Enable this tool?",
|
|
3063
|
+
initialValue: true
|
|
3064
|
+
});
|
|
3065
|
+
if (lD(enabled)) {
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
3068
|
+
config.tools[toolName] = enabled;
|
|
3069
|
+
saveConfig(configPath, config);
|
|
3070
|
+
f2.success(`Added ${toolName}: ${enabled ? import_picocolors7.default.green("on") : import_picocolors7.default.red("off")}`);
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
async function editShare(configPath) {
|
|
3074
|
+
const config = loadConfig(configPath);
|
|
3075
|
+
const current = config.share || "manual";
|
|
3076
|
+
f2.info(`Current share setting: ${import_picocolors7.default.cyan(current)}`);
|
|
3077
|
+
const selected = await ie({
|
|
3078
|
+
message: "Share setting",
|
|
3079
|
+
options: [
|
|
3080
|
+
{
|
|
3081
|
+
value: "manual",
|
|
3082
|
+
label: "Manual",
|
|
3083
|
+
hint: "share when requested"
|
|
3084
|
+
},
|
|
3085
|
+
{
|
|
3086
|
+
value: "auto",
|
|
3087
|
+
label: "Auto",
|
|
3088
|
+
hint: "automatically share sessions"
|
|
3089
|
+
},
|
|
3090
|
+
{ value: "disabled", label: "Disabled", hint: "never share" }
|
|
3091
|
+
]
|
|
3092
|
+
});
|
|
3093
|
+
if (lD(selected)) {
|
|
3094
|
+
return;
|
|
3095
|
+
}
|
|
3096
|
+
const shareValue = selected;
|
|
3097
|
+
config.share = shareValue;
|
|
3098
|
+
saveConfig(configPath, config);
|
|
3099
|
+
f2.success(`Share set to ${import_picocolors7.default.cyan(shareValue)}`);
|
|
3100
|
+
}
|
|
3101
|
+
async function editAutoupdate(configPath) {
|
|
3102
|
+
const config = loadConfig(configPath);
|
|
3103
|
+
const current = config.autoupdate ?? true;
|
|
3104
|
+
const display = current === "notify" ? "notify" : current ? "enabled" : "disabled";
|
|
3105
|
+
f2.info(`Current autoupdate: ${import_picocolors7.default.cyan(display)}`);
|
|
3106
|
+
const selected = await ie({
|
|
3107
|
+
message: "Autoupdate behavior",
|
|
3108
|
+
options: [
|
|
3109
|
+
{
|
|
3110
|
+
value: "true",
|
|
3111
|
+
label: "Enabled",
|
|
3112
|
+
hint: "auto-update OpenCode"
|
|
3113
|
+
},
|
|
3114
|
+
{
|
|
3115
|
+
value: "notify",
|
|
3116
|
+
label: "Notify",
|
|
3117
|
+
hint: "notify but don't auto-update"
|
|
3118
|
+
},
|
|
3119
|
+
{
|
|
3120
|
+
value: "false",
|
|
3121
|
+
label: "Disabled",
|
|
3122
|
+
hint: "never update automatically"
|
|
3123
|
+
}
|
|
3124
|
+
]
|
|
3125
|
+
});
|
|
3126
|
+
if (lD(selected)) {
|
|
3127
|
+
return;
|
|
3128
|
+
}
|
|
3129
|
+
const selectedValue = selected;
|
|
3130
|
+
if (selectedValue === "notify") {
|
|
3131
|
+
config.autoupdate = "notify";
|
|
3132
|
+
} else {
|
|
3133
|
+
config.autoupdate = selectedValue === "true";
|
|
3134
|
+
}
|
|
3135
|
+
saveConfig(configPath, config);
|
|
3136
|
+
f2.success(`Autoupdate set to ${import_picocolors7.default.cyan(selectedValue)}`);
|
|
3137
|
+
}
|
|
2832
3138
|
|
|
2833
3139
|
// src/commands/upgrade.ts
|
|
2834
3140
|
import { join as join5, dirname as dirname2 } from "node:path";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Analyze project structure and
|
|
2
|
+
description: Analyze project structure, status, and ready work
|
|
3
3
|
agent: planner
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -12,6 +12,16 @@ agent: planner
|
|
|
12
12
|
3. **CI:** Check build status
|
|
13
13
|
4. **Dependencies:** Check for outdated packages
|
|
14
14
|
|
|
15
|
+
## Ready Work
|
|
16
|
+
|
|
17
|
+
Find actionable tasks with no blockers:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bd ready
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This shows beads that are unblocked and ready to start. Use `/implement <bead-id>` to begin work on any of these.
|
|
24
|
+
|
|
15
25
|
## Detailed Analysis (On Request)
|
|
16
26
|
|
|
17
27
|
### Task Overview
|
|
@@ -23,6 +33,16 @@ bd ready
|
|
|
23
33
|
|
|
24
34
|
For active beads, read spec from `.beads/artifacts/<bead-id>/spec.md`
|
|
25
35
|
|
|
36
|
+
### Blocked Work
|
|
37
|
+
|
|
38
|
+
Check what's blocking progress:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bd list --status blocked
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
For each blocked bead, identify the blocker and either resolve it or escalate.
|
|
45
|
+
|
|
26
46
|
### Project Structure
|
|
27
47
|
|
|
28
48
|
- Key directories
|
|
@@ -33,7 +53,8 @@ For active beads, read spec from `.beads/artifacts/<bead-id>/spec.md`
|
|
|
33
53
|
|
|
34
54
|
### Recommendations
|
|
35
55
|
|
|
36
|
-
- Tasks ready to start
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
56
|
+
- **Immediate:** Tasks from `bd ready` to start now
|
|
57
|
+
- **Blocked:** Dependencies preventing progress
|
|
58
|
+
- **Attention:** Areas needing cleanup or refactoring
|
|
59
|
+
- **Updates:** Dependency updates needed
|
|
60
|
+
- **Patterns:** Code patterns to follow
|
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Commit with verification
|
|
2
|
+
description: Commit with verification and optional bead traceability
|
|
3
|
+
argument-hint: "[bead-id]"
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
# Commit
|
|
6
7
|
|
|
7
8
|
use_skill("verification-before-completion")
|
|
8
9
|
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
9
12
|
1. Run all tests/lints
|
|
10
13
|
2. Verify output shows success
|
|
11
|
-
3.
|
|
14
|
+
3. Commit with conventional message format
|
|
15
|
+
|
|
16
|
+
## Bead Integration (Optional)
|
|
17
|
+
|
|
18
|
+
If a bead ID is provided (`$ARGUMENTS`), include it in the commit message for traceability:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
<type>(<scope>): <description>
|
|
22
|
+
|
|
23
|
+
<bead-id>: <what was done for this bead>
|
|
24
|
+
|
|
25
|
+
[optional body]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Example:**
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
feat(auth): add OAuth2 login flow
|
|
32
|
+
|
|
33
|
+
bd-a1b2c3: implement token refresh mechanism
|
|
34
|
+
|
|
35
|
+
- Added refresh token storage
|
|
36
|
+
- Integrated with session manager
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If no bead ID is provided, proceed with standard conventional commit format.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Analyze Github Actions logs and fix issues
|
|
2
|
+
description: Analyze Github Actions logs and fix issues with bead tracking
|
|
3
3
|
argument-hint: "[github-actions-url]"
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -7,14 +7,41 @@ argument-hint: "[github-actions-url]"
|
|
|
7
7
|
|
|
8
8
|
<url>$ARGUMENTS</url>
|
|
9
9
|
|
|
10
|
+
## Create Bug Bead
|
|
11
|
+
|
|
12
|
+
CI failures are P0 bugs. Create a bead to track:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bd create --title "Fix CI: <failure summary>" --type bug --priority p0 --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Save the bead ID for tracking. Add the CI run reference:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bd edit <bead-id> --note "CI Run: $ARGUMENTS"
|
|
22
|
+
```
|
|
23
|
+
|
|
10
24
|
## Workflow
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
1. **Analyze:** Use `build` agent to read the GitHub Actions logs, analyze and find the root causes of the issues.
|
|
27
|
+
|
|
28
|
+
2. **Plan:** For complex CI/CD problems (≥3 phases), delegate to `planner` agent to create a detailed implementation plan. Save plan to `.beads/artifacts/<bead-id>/spec.md`.
|
|
29
|
+
|
|
30
|
+
3. **Fix:** Use `build` agent to implement the fixes step by step.
|
|
31
|
+
|
|
32
|
+
4. **Verify:** Use `review` agent to run tests, ensure quality and security, then report back.
|
|
33
|
+
|
|
34
|
+
5. **Iterate:** If there are issues or failed tests, `build` agent will fix them and repeat the process until all tests pass.
|
|
35
|
+
|
|
36
|
+
## Close Bead
|
|
37
|
+
|
|
38
|
+
Once CI passes:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bd close <bead-id> --reason "CI fixed: <summary of fix>"
|
|
42
|
+
```
|
|
17
43
|
|
|
18
44
|
## Notes
|
|
19
45
|
|
|
20
46
|
- If `gh` command is not available, instruct the user to install and authorize GitHub CLI first.
|
|
47
|
+
- If the fix reveals systemic issues, create related beads for follow-up work.
|
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Fix type errors
|
|
2
|
+
description: Fix type errors with optional bead tracking
|
|
3
|
+
argument-hint: "[bead-id]"
|
|
3
4
|
---
|
|
4
5
|
|
|
6
|
+
# Fix Type Errors
|
|
7
|
+
|
|
5
8
|
Run `bun run typecheck` and fix all type errors.
|
|
6
9
|
|
|
7
10
|
## Rules
|
|
8
11
|
|
|
9
|
-
- Fix all
|
|
10
|
-
- Do not use `any` just to pass the type check.
|
|
12
|
+
- Fix all type errors and repeat the process until there are no more type errors.
|
|
13
|
+
- Do not use `any` just to pass the type check.
|
|
14
|
+
- Prefer proper typing over type assertions where possible.
|
|
15
|
+
|
|
16
|
+
## Bead Integration (Optional)
|
|
17
|
+
|
|
18
|
+
If a bead ID is provided (`$ARGUMENTS`), track the type fixing work:
|
|
19
|
+
|
|
20
|
+
1. **Before fixing:** Note the initial error count
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
bd edit $ARGUMENTS --note "Type errors found: <count>"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2. **After fixing:** Update with resolution
|
|
27
|
+
```bash
|
|
28
|
+
bd edit $ARGUMENTS --note "Type errors resolved: <summary of fixes>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If type errors reveal deeper issues requiring refactoring, create a follow-up bead:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bd create --title "Refactor: <type issue summary>" --type task --related $ARGUMENTS
|
|
35
|
+
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Analyze GitHub issue and create
|
|
2
|
+
description: Analyze GitHub issue and create bead for tracking
|
|
3
3
|
argument-hint: "[issue-number]"
|
|
4
4
|
agent: build
|
|
5
5
|
---
|
|
@@ -19,8 +19,24 @@ gh issue view $ARGUMENTS
|
|
|
19
19
|
3. **Current:** What happens now?
|
|
20
20
|
4. **Steps:** How to reproduce?
|
|
21
21
|
|
|
22
|
+
## Create Tracking Bead
|
|
23
|
+
|
|
24
|
+
Create a bead to track this work, linking it to the GitHub issue:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bd create --title "<issue title>" --type task --priority <p1|p2|p3> --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Save the bead ID for subsequent commands. Add the GitHub issue reference:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bd edit <bead-id> --note "GitHub issue: #$ARGUMENTS"
|
|
34
|
+
```
|
|
35
|
+
|
|
22
36
|
## Implementation Plan
|
|
23
37
|
|
|
38
|
+
Save to `.beads/artifacts/<bead-id>/spec.md`:
|
|
39
|
+
|
|
24
40
|
1. **Files to change:** Identify affected code
|
|
25
41
|
2. **Testing strategy:** How to verify fix
|
|
26
42
|
3. **Risks/edge cases:** What could go wrong
|
|
@@ -38,4 +54,12 @@ gh issue view $ARGUMENTS
|
|
|
38
54
|
- [ ] Test cases to verify
|
|
39
55
|
- [ ] Performance considerations
|
|
40
56
|
|
|
41
|
-
|
|
57
|
+
## Discovered Work
|
|
58
|
+
|
|
59
|
+
If analysis reveals additional issues, create child beads:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
bd create --title "<discovered issue>" --type discovered --parent <parent-bead-id>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Next:** Use `/implement <bead-id>` to start implementation.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Create and submit pull request with
|
|
2
|
+
description: Create and submit pull request with bead traceability
|
|
3
|
+
argument-hint: "[bead-id]"
|
|
3
4
|
---
|
|
4
5
|
|
|
5
6
|
## Create Pull Request
|
|
@@ -14,13 +15,18 @@ Create a pull request following these steps:
|
|
|
14
15
|
|
|
15
16
|
2. **Push branch**: `!git push -u origin $(git branch --show-current)`
|
|
16
17
|
|
|
17
|
-
3. **
|
|
18
|
+
3. **Check for bead context:**
|
|
19
|
+
- If `$ARGUMENTS` contains a bead ID, fetch bead details: `bd show $ARGUMENTS --json`
|
|
20
|
+
- Use bead title and spec to inform PR content
|
|
21
|
+
- Reference the bead in the PR body for traceability
|
|
22
|
+
|
|
23
|
+
4. **Generate PR content:**
|
|
18
24
|
- Title: Clear, descriptive (under 60 chars)
|
|
19
25
|
- Summary: What and why this change matters
|
|
20
26
|
- Testing: How to verify the changes
|
|
21
27
|
- Breaking changes: Note any API/behavior changes
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
5. **Create PR**: `!gh pr create --title "Generated Title" --body "Generated Description"`
|
|
24
30
|
|
|
25
31
|
**Template format:**
|
|
26
32
|
|
|
@@ -28,9 +34,20 @@ Create a pull request following these steps:
|
|
|
28
34
|
## Summary
|
|
29
35
|
- Brief description of changes
|
|
30
36
|
|
|
37
|
+
## Bead Reference
|
|
38
|
+
Closes: bd-XXXXX (if applicable)
|
|
39
|
+
|
|
31
40
|
## Testing
|
|
32
41
|
- How to test these changes
|
|
33
42
|
|
|
34
43
|
## Breaking Changes
|
|
35
44
|
- None / List any breaking changes
|
|
36
45
|
```
|
|
46
|
+
|
|
47
|
+
## After PR Created
|
|
48
|
+
|
|
49
|
+
If a bead ID was provided, update the bead with PR link:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
bd edit $ARGUMENTS --note "PR created: <pr-url>"
|
|
53
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Large-scale UI/UX research using Gemini CLI
|
|
3
|
-
argument-hint: "[research topic or path]"
|
|
2
|
+
description: Large-scale UI/UX research using Gemini CLI with bead artifact storage
|
|
3
|
+
argument-hint: "[bead-id] [research topic or path]"
|
|
4
4
|
agent: review
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,6 +9,10 @@ agent: review
|
|
|
9
9
|
use_skill("gemini-large-context")
|
|
10
10
|
use_skill("ui-ux-research")
|
|
11
11
|
|
|
12
|
+
## Parse Arguments
|
|
13
|
+
|
|
14
|
+
Extract bead ID (if provided) and research topic from `$ARGUMENTS`. If no bead ID provided, research findings will be saved to memory instead.
|
|
15
|
+
|
|
12
16
|
## When to Use Gemini CLI
|
|
13
17
|
|
|
14
18
|
For a single component, use local tools—they're faster and sufficient. When researching patterns across multiple files or comparing implementations throughout a codebase, switch to Gemini CLI's non-interactive mode to scan entire directories at once. For analyzing images like mockups or screenshots, start Gemini in interactive mode and reference the image directly.
|
|
@@ -19,9 +23,21 @@ Point Gemini at the relevant directories and ask about the topic. Include both c
|
|
|
19
23
|
|
|
20
24
|
For image analysis, start interactive mode and reference the image file, then describe what aspects you want analyzed.
|
|
21
25
|
|
|
22
|
-
##
|
|
26
|
+
## Save Findings
|
|
27
|
+
|
|
28
|
+
### With Bead ID
|
|
29
|
+
|
|
30
|
+
Save research findings to bead artifacts for traceability:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Save to .beads/artifacts/<bead-id>/research-ui.md
|
|
34
|
+
bd edit <bead-id> --note "UI research completed: <key findings summary>"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Without Bead ID
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
Save to memory for general reference:
|
|
40
|
+
`.opencode/memory/research/YYYY-MM-DD-<topic>.md`
|
|
25
41
|
|
|
26
42
|
## Common Research Topics
|
|
27
43
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Review UI/UX design or mockup
|
|
3
|
-
argument-hint: "[path to image or component]"
|
|
2
|
+
description: Review UI/UX design or mockup with optional bead tracking
|
|
3
|
+
argument-hint: "[bead-id] [path to image or component]"
|
|
4
4
|
agent: review
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,6 +9,10 @@ agent: review
|
|
|
9
9
|
use_skill("ui-ux-research")
|
|
10
10
|
use_skill("frontend-aesthetics")
|
|
11
11
|
|
|
12
|
+
## Parse Arguments
|
|
13
|
+
|
|
14
|
+
Extract bead ID (if provided) and path/component from `$ARGUMENTS`. If a bead ID is present, findings will be recorded to the bead.
|
|
15
|
+
|
|
12
16
|
## How to Analyze
|
|
13
17
|
|
|
14
18
|
First, determine what you're reviewing. If it's an image or screenshot, start Gemini in interactive mode and reference the image to analyze it. If it's component code, analyze it directly with local tools. For large codebases spanning many files, use Gemini's non-interactive mode to scan the entire directory.
|
|
@@ -23,6 +27,26 @@ For accessibility, verify color contrast meets WCAG AA minimum, check for ARIA l
|
|
|
23
27
|
|
|
24
28
|
Provide specific, actionable improvements: suggest alternative fonts, propose color palette changes, identify opportunities for subtle animations, and recommend layout enhancements. Include code snippets when they would help clarify the suggestion.
|
|
25
29
|
|
|
30
|
+
## Record Findings
|
|
31
|
+
|
|
32
|
+
### With Bead ID
|
|
33
|
+
|
|
34
|
+
Update the bead with review findings:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bd edit <bead-id> --note "UI Review: <summary of issues found and recommendations>"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If review reveals implementation tasks, create child beads:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
bd create --title "<specific UI fix>" --type task --parent <bead-id>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Without Bead ID
|
|
47
|
+
|
|
48
|
+
Output findings directly to the user.
|
|
49
|
+
|
|
26
50
|
## Output
|
|
27
51
|
|
|
28
52
|
Summarize what issues you found, what specific changes you recommend, and show before/after comparisons for significant improvements.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// AI analysis strategies (deduplication runs automatically on every request)
|
|
13
13
|
"strategies": {
|
|
14
14
|
// Strategies to run when session goes idle
|
|
15
|
-
"onIdle": ["
|
|
15
|
+
"onIdle": [""],
|
|
16
16
|
// Strategies to run when AI calls prune tool
|
|
17
17
|
"onTool": ["ai-analysis"],
|
|
18
18
|
},
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Design Document
|
|
2
|
+
|
|
3
|
+
**Bead ID:** [bead-id]
|
|
4
|
+
**Created:** [date]
|
|
5
|
+
**Status:** Draft | Validated
|
|
6
|
+
|
|
7
|
+
## Problem Statement
|
|
8
|
+
|
|
9
|
+
What we're solving and why it matters:
|
|
10
|
+
|
|
11
|
+
## Approaches Considered
|
|
12
|
+
|
|
13
|
+
### Option A: [Name]
|
|
14
|
+
|
|
15
|
+
- **Pros:** [advantages]
|
|
16
|
+
- **Cons:** [drawbacks]
|
|
17
|
+
|
|
18
|
+
### Option B: [Name]
|
|
19
|
+
|
|
20
|
+
- **Pros:** [advantages]
|
|
21
|
+
- **Cons:** [drawbacks]
|
|
22
|
+
|
|
23
|
+
### Chosen Approach
|
|
24
|
+
|
|
25
|
+
[Which option and why]
|
|
26
|
+
|
|
27
|
+
## Architecture
|
|
28
|
+
|
|
29
|
+
High-level structure and how components fit together:
|
|
30
|
+
|
|
31
|
+
### Components
|
|
32
|
+
|
|
33
|
+
- [Component 1]: [purpose]
|
|
34
|
+
- [Component 2]: [purpose]
|
|
35
|
+
|
|
36
|
+
### Data Flow
|
|
37
|
+
|
|
38
|
+
[How data moves through the system]
|
|
39
|
+
|
|
40
|
+
## Error Handling
|
|
41
|
+
|
|
42
|
+
How the design handles failure cases:
|
|
43
|
+
|
|
44
|
+
- [Error scenario 1]: [handling approach]
|
|
45
|
+
- [Error scenario 2]: [handling approach]
|
|
46
|
+
|
|
47
|
+
## Testing Strategy
|
|
48
|
+
|
|
49
|
+
How we'll validate this design works:
|
|
50
|
+
|
|
51
|
+
- [Testing approach 1]
|
|
52
|
+
- [Testing approach 2]
|
|
53
|
+
|
|
54
|
+
## Open Questions
|
|
55
|
+
|
|
56
|
+
Unresolved items to address during implementation:
|
|
57
|
+
|
|
58
|
+
- [ ] [Question 1]
|
|
59
|
+
- [ ] [Question 2]
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"build": {
|
|
11
11
|
"description": "Primary development agent with full codebase access",
|
|
12
|
-
"model": "
|
|
12
|
+
"model": "proxypal/gemini-claude-opus-4-5-thinking"
|
|
13
13
|
},
|
|
14
14
|
"rush": {
|
|
15
15
|
"description": "Fast primary agent for small, well-defined tasks",
|
|
@@ -35,60 +35,23 @@
|
|
|
35
35
|
"experimental": {
|
|
36
36
|
"batch_tool": true,
|
|
37
37
|
"chatMaxRetries": 2,
|
|
38
|
-
"primary_tools": [
|
|
39
|
-
"edit",
|
|
40
|
-
"write",
|
|
41
|
-
"bash",
|
|
42
|
-
"prune"
|
|
43
|
-
]
|
|
38
|
+
"primary_tools": ["edit", "write", "bash", "prune"]
|
|
44
39
|
},
|
|
45
40
|
"formatter": {
|
|
46
41
|
"biome": {
|
|
47
|
-
"command": [
|
|
48
|
-
|
|
49
|
-
"@biomejs/biome",
|
|
50
|
-
"check",
|
|
51
|
-
"--write",
|
|
52
|
-
"$FILE"
|
|
53
|
-
],
|
|
54
|
-
"extensions": [
|
|
55
|
-
".js",
|
|
56
|
-
".jsx",
|
|
57
|
-
".ts",
|
|
58
|
-
".tsx",
|
|
59
|
-
".json",
|
|
60
|
-
".jsonc"
|
|
61
|
-
]
|
|
42
|
+
"command": ["npx", "@biomejs/biome", "check", "--write", "$FILE"],
|
|
43
|
+
"extensions": [".js", ".jsx", ".ts", ".tsx", ".json", ".jsonc"]
|
|
62
44
|
},
|
|
63
45
|
"java-formatter": {
|
|
64
|
-
"command": [
|
|
65
|
-
"google-java-format",
|
|
66
|
-
"--replace",
|
|
67
|
-
"$FILE"
|
|
68
|
-
],
|
|
46
|
+
"command": ["google-java-format", "--replace", "$FILE"],
|
|
69
47
|
"environment": {
|
|
70
48
|
"JAVA_HOME": "{env:JAVA_HOME}"
|
|
71
49
|
},
|
|
72
|
-
"extensions": [
|
|
73
|
-
".java"
|
|
74
|
-
]
|
|
50
|
+
"extensions": [".java"]
|
|
75
51
|
},
|
|
76
52
|
"prettier": {
|
|
77
|
-
"command": [
|
|
78
|
-
|
|
79
|
-
"prettier",
|
|
80
|
-
"--write",
|
|
81
|
-
"$FILE"
|
|
82
|
-
],
|
|
83
|
-
"extensions": [
|
|
84
|
-
".html",
|
|
85
|
-
".css",
|
|
86
|
-
".scss",
|
|
87
|
-
".sass",
|
|
88
|
-
".md",
|
|
89
|
-
".yaml",
|
|
90
|
-
".yml"
|
|
91
|
-
]
|
|
53
|
+
"command": ["npx", "prettier", "--write", "$FILE"],
|
|
54
|
+
"extensions": [".html", ".css", ".scss", ".sass", ".md", ".yaml", ".yml"]
|
|
92
55
|
}
|
|
93
56
|
},
|
|
94
57
|
"keybinds": {
|
|
@@ -110,10 +73,7 @@
|
|
|
110
73
|
"type": "local"
|
|
111
74
|
},
|
|
112
75
|
"augment-context-engine": {
|
|
113
|
-
"command": [
|
|
114
|
-
"auggie",
|
|
115
|
-
"--mcp"
|
|
116
|
-
],
|
|
76
|
+
"command": ["auggie", "--mcp"],
|
|
117
77
|
"enabled": false,
|
|
118
78
|
"type": "local"
|
|
119
79
|
},
|
|
@@ -136,10 +96,7 @@
|
|
|
136
96
|
"url": "http://localhost:27495/mcp"
|
|
137
97
|
},
|
|
138
98
|
"playwright": {
|
|
139
|
-
"command": [
|
|
140
|
-
"npx",
|
|
141
|
-
"@playwright/mcp@latest"
|
|
142
|
-
],
|
|
99
|
+
"command": ["npx", "@playwright/mcp@latest"],
|
|
143
100
|
"enabled": false,
|
|
144
101
|
"type": "local"
|
|
145
102
|
}
|
|
@@ -14,6 +14,7 @@ Start by understanding the current project context, then ask questions one at a
|
|
|
14
14
|
## The Process
|
|
15
15
|
|
|
16
16
|
**Understanding the idea:**
|
|
17
|
+
|
|
17
18
|
- Check out the current project state first (files, docs, recent commits)
|
|
18
19
|
- Ask questions one at a time to refine the idea
|
|
19
20
|
- Prefer multiple choice questions when possible, but open-ended is fine too
|
|
@@ -21,11 +22,13 @@ Start by understanding the current project context, then ask questions one at a
|
|
|
21
22
|
- Focus on understanding: purpose, constraints, success criteria
|
|
22
23
|
|
|
23
24
|
**Exploring approaches:**
|
|
25
|
+
|
|
24
26
|
- Propose 2-3 different approaches with trade-offs
|
|
25
27
|
- Present options conversationally with your recommendation and reasoning
|
|
26
28
|
- Lead with your recommended option and explain why
|
|
27
29
|
|
|
28
30
|
**Presenting the design:**
|
|
31
|
+
|
|
29
32
|
- Once you believe you understand what you're building, present the design
|
|
30
33
|
- Break it into sections of 200-300 words
|
|
31
34
|
- Ask after each section whether it looks right so far
|
|
@@ -35,11 +38,13 @@ Start by understanding the current project context, then ask questions one at a
|
|
|
35
38
|
## After the Design
|
|
36
39
|
|
|
37
40
|
**Documentation:**
|
|
38
|
-
|
|
41
|
+
|
|
42
|
+
- Write the validated design to `.beads/artifacts/<bead-id>/design.md` using template from `.opencode/memory/_templates/task-design.md`
|
|
39
43
|
- Use elements-of-style:writing-clearly-and-concisely skill if available
|
|
40
44
|
- Commit the design document to git
|
|
41
45
|
|
|
42
46
|
**Implementation (if continuing):**
|
|
47
|
+
|
|
43
48
|
- Ask: "Ready to set up for implementation?"
|
|
44
49
|
- Use superpowers:using-git-worktrees to create isolated workspace
|
|
45
50
|
- Use superpowers:writing-plans to create detailed implementation plan
|
|
@@ -20,6 +20,7 @@ Assume they are a skilled developer, but know almost nothing about our toolset o
|
|
|
20
20
|
## Bite-Sized Task Granularity
|
|
21
21
|
|
|
22
22
|
**Each step is one action (2-5 minutes):**
|
|
23
|
+
|
|
23
24
|
- "Write the failing test" - step
|
|
24
25
|
- "Run it to make sure it fails" - step
|
|
25
26
|
- "Implement the minimal code to make the test pass" - step
|
|
@@ -46,10 +47,11 @@ Assume they are a skilled developer, but know almost nothing about our toolset o
|
|
|
46
47
|
|
|
47
48
|
## Task Structure
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
````markdown
|
|
50
51
|
### Task N: [Component Name]
|
|
51
52
|
|
|
52
53
|
**Files:**
|
|
54
|
+
|
|
53
55
|
- Create: `exact/path/to/file.py`
|
|
54
56
|
- Modify: `exact/path/to/existing.py:123-145`
|
|
55
57
|
- Test: `tests/exact/path/to/test.py`
|
|
@@ -61,6 +63,7 @@ def test_specific_behavior():
|
|
|
61
63
|
result = function(input)
|
|
62
64
|
assert result == expected
|
|
63
65
|
```
|
|
66
|
+
````
|
|
64
67
|
|
|
65
68
|
**Step 2: Run test to verify it fails**
|
|
66
69
|
|
|
@@ -85,6 +88,7 @@ Expected: PASS
|
|
|
85
88
|
git add tests/path/test.py src/path/file.py
|
|
86
89
|
git commit -m "feat: add specific feature"
|
|
87
90
|
```
|
|
91
|
+
|
|
88
92
|
```
|
|
89
93
|
|
|
90
94
|
## Remember
|
|
@@ -98,7 +102,7 @@ git commit -m "feat: add specific feature"
|
|
|
98
102
|
|
|
99
103
|
After saving the plan, offer execution choice:
|
|
100
104
|
|
|
101
|
-
**"Plan complete and saved to
|
|
105
|
+
**"Plan complete and saved to `.beads/artifacts/<bead-id>/plan.md`. Two execution options:**
|
|
102
106
|
|
|
103
107
|
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
|
|
104
108
|
|
|
@@ -114,3 +118,4 @@ After saving the plan, offer execution choice:
|
|
|
114
118
|
**If Parallel Session chosen:**
|
|
115
119
|
- Guide them to open new session in worktree
|
|
116
120
|
- **REQUIRED SUB-SKILL:** New session uses superpowers:executing-plans
|
|
121
|
+
```
|