taskplane 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -156,7 +156,7 @@ Orchestrator lanes execute tasks through task-runner under the hood, so `/task`
156
156
  | `/orch-abort [--hard]` | Abort batch (graceful or immediate) |
157
157
  | `/orch-deps <areas\|paths\|all>` | Show dependency graph |
158
158
  | `/orch-sessions` | List active worker sessions |
159
- | `/settings` | View and edit taskplane configuration interactively |
159
+ | `/taskplane-settings` | View and edit taskplane configuration interactively |
160
160
 
161
161
  ### CLI Commands
162
162
 
package/bin/taskplane.mjs CHANGED
@@ -2565,7 +2565,7 @@ function cmdDoctor() {
2565
2565
 
2566
2566
  if ((hasYamlRunner || hasYamlOrchestrator) && !hasJsonConfig) {
2567
2567
  console.log(` ${WARN} legacy YAML config detected in ${configLocation.label}`);
2568
- console.log(` ${c.dim}→ Run /settings to migrate to taskplane-config.json${c.reset}`);
2568
+ console.log(` ${c.dim}→ Run /taskplane-settings to migrate to taskplane-config.json${c.reset}`);
2569
2569
  }
2570
2570
  }
2571
2571
 
@@ -649,7 +649,7 @@ export default function (pi: ExtensionAPI) {
649
649
 
650
650
  // ── Settings TUI ─────────────────────────────────────────────────
651
651
 
652
- pi.registerCommand("settings", {
652
+ pi.registerCommand("taskplane-settings", {
653
653
  description: "View and edit taskplane configuration",
654
654
  handler: async (_args, ctx) => {
655
655
  if (!requireExecCtx(ctx)) return;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Settings TUI — interactive configuration viewer and editor.
3
3
  *
4
- * Provides a `/settings` command that renders a two-level navigation:
4
+ * Provides a `/taskplane-settings` command that renders a two-level navigation:
5
5
  * 1. Section selector (12 sections)
6
6
  * 2. Per-section SettingsList with field display, source badges,
7
7
  * and inline editing for enum/boolean/string/number fields
@@ -911,7 +911,7 @@ function summarizeArray(arr: any[]): string {
911
911
  /**
912
912
  * Open the settings TUI.
913
913
  *
914
- * This is the main entry point called from the /settings command handler.
914
+ * This is the main entry point called from the /taskplane-settings command handler.
915
915
  * Uses a two-level navigation:
916
916
  * 1. SelectList for section navigation
917
917
  * 2. SettingsList for per-section field display and editing
@@ -1109,6 +1109,30 @@ async function showSectionSettingsLoop(
1109
1109
  const field = section.fields.find((f) => f.configPath === result.fieldId);
1110
1110
  if (!field) continue; // Safety: field not found
1111
1111
 
1112
+ // Input fields: the submenu returned a sentinel — use ctx.ui.input() for actual editing
1113
+ if (result.rawValue === "__EDIT_REQUESTED__" && field.control === "input") {
1114
+ const state = loadConfigState(configRoot, pointerConfigRoot);
1115
+ const currentDisplay = getFieldDisplayValue(field, state.mergedConfig, state.prefs);
1116
+ const currentClean = String(currentDisplay).replace(/\s+\((?:default|project|user)\)$/, "");
1117
+ const placeholder = currentClean === "(not set)" || currentClean === "(inherit)" ? "" : currentClean;
1118
+
1119
+ const newValue = await ctx.ui.input(
1120
+ `${field.label}${field.description ? ` — ${field.description}` : ""}`,
1121
+ placeholder,
1122
+ );
1123
+
1124
+ if (newValue === null || newValue === undefined) continue; // Cancelled
1125
+
1126
+ // Validate
1127
+ const validation = validateFieldInput(field, newValue);
1128
+ if (!validation.valid) {
1129
+ ctx.ui.notify(`❌ Invalid value: ${validation.error}`, "error");
1130
+ continue;
1131
+ }
1132
+
1133
+ result.rawValue = newValue;
1134
+ }
1135
+
1112
1136
  const typedValue = coerceValueForWrite(field, result.rawValue);
1113
1137
 
1114
1138
  // Collect UI answers for the write-decision contract
@@ -1199,11 +1223,12 @@ async function showSectionSettingsOnce(
1199
1223
  item.values = field.values.map((v) => `${v} ${sourceBadge}`);
1200
1224
  }
1201
1225
 
1202
- // Input fields get a submenu for inline editing
1226
+ // Input fields: use a single-value cycling pattern instead of a submenu.
1227
+ // The inline submenu approach freezes on Windows/tmux (issue #57).
1228
+ // We set a single sentinel value so pressing Enter/Space triggers onChange,
1229
+ // which exits the TUI. The caller then uses ctx.ui.input() for actual editing.
1203
1230
  if (field.control === "input") {
1204
- item.submenu = (currentValue: string, submenuDone: (selectedValue?: string) => void) => {
1205
- return createInputSubmenu(field, currentValue, submenuDone);
1206
- };
1231
+ item.values = [`__EDIT_REQUESTED__`];
1207
1232
  }
1208
1233
 
1209
1234
  return item;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskplane",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "AI agent orchestration for pi — parallel task execution with checkpoint discipline",
5
5
  "keywords": [
6
6
  "pi-package",