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
|
|
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.
|
|
1205
|
-
return createInputSubmenu(field, currentValue, submenuDone);
|
|
1206
|
-
};
|
|
1231
|
+
item.values = [`__EDIT_REQUESTED__`];
|
|
1207
1232
|
}
|
|
1208
1233
|
|
|
1209
1234
|
return item;
|