opencodekit 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.0",
753
+ version: "0.2.0",
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
- const action = await ie({
2021
- message: "What do you want to configure?",
2022
- options: [
2023
- { value: "model", label: "Model - change default model" },
2024
- {
2025
- value: "small_model",
2026
- label: "Small Model - change small model"
2027
- },
2028
- { value: "agent", label: "Agents - configure agent models" },
2029
- { value: "theme", label: "Theme - change UI theme" },
2030
- { value: "mcp", label: "MCP - manage MCP servers" },
2031
- {
2032
- value: "permission",
2033
- label: "Permissions - bash/edit permissions"
2034
- },
2035
- { value: "keybinds", label: "Keybinds - keyboard shortcuts" },
2036
- { value: "show", label: "Show - view current config" },
2037
- { value: "exit", label: "Exit" }
2038
- ]
2039
- });
2040
- if (lD(action) || action === "exit") {
2041
- $e("Done");
2042
- return;
2043
- }
2044
- switch (action) {
2045
- case "model":
2046
- await editModel(configPath);
2047
- break;
2048
- case "small_model":
2049
- await editModel(configPath, "small_model");
2050
- break;
2051
- case "agent":
2052
- await editAgentModel(configPath);
2053
- break;
2054
- case "theme":
2055
- await editTheme(configPath);
2056
- break;
2057
- case "mcp":
2058
- await editMCP(configPath);
2059
- break;
2060
- case "permission":
2061
- await editPermissions(configPath);
2062
- break;
2063
- case "keybinds":
2064
- await editKeybinds(configPath);
2065
- break;
2066
- case "show":
2067
- showConfig(configPath);
2068
- break;
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 = getModelsForProvider(modelsDevProvider);
2261
+ modelOptions = [
2262
+ modelOptions[0],
2263
+ ...getModelsForProvider(modelsDevProvider)
2264
+ ];
2191
2265
  } else if (localProviderConfig?.models && Object.keys(localProviderConfig.models).length > 0) {
2192
- modelOptions = getModelsFromLocalConfig(localProviderConfig.models);
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 selectedAgent = await ie({
2291
- message: "Select agent to configure",
2292
- options: agentNames.map((name) => {
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";
@@ -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": ["ai-analysis"],
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": "github-copilot/claude-opus-4.5"
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
- "npx",
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
- "npx",
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
  }
@@ -15,9 +15,9 @@
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/better-sqlite3": "^7.6.13",
18
- "@types/node": "^20.0.0",
18
+ "@types/node": "^20.19.27",
19
19
  "fs": "^0.0.1-security",
20
20
  "path": "^0.12.7",
21
- "typescript": "^5.0.0"
21
+ "typescript": "^5.9.3"
22
22
  }
23
23
  }
@@ -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
- - Write the validated design to `docs/plans/YYYY-MM-DD-<topic>-design.md`
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
- ```markdown
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 `docs/plans/<filename>.md`. Two execution options:**
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
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "type": "module",
6
6
  "repository": {