fix(workstream): require name arg for set, add --clear flag (#1527)

workstream set with no argument silently cleared the active workstream,
a footgun for users who forgot the name. Now requires a name arg and
errors with usage hint. Explicit clearing via --clear flag, which also
reports the previous workstream in its output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox
2026-04-01 14:35:00 -07:00
parent 5eed6973b8
commit 89f82d5483
2 changed files with 24 additions and 2 deletions

View File

@@ -339,9 +339,13 @@ function cmdWorkstreamComplete(cwd, name, options, raw) {
// ─── Active Workstream Commands ──────────────────────────────────────────────
function cmdWorkstreamSet(cwd, name, raw) {
if (!name) {
if (!name || name === '--clear') {
if (name !== '--clear') {
error('Workstream name required. Usage: workstream set <name> (or workstream set --clear to unset)');
}
const previous = getActiveWorkstream(cwd);
setActiveWorkstream(cwd, null);
output({ active: null, cleared: true }, raw);
output({ active: null, cleared: true, previous: previous || null }, raw);
return;
}

View File

@@ -268,6 +268,24 @@ describe('workstream set/get', () => {
assert.ok(result.success);
assert.strictEqual(result.output, 'ws-a');
});
test('errors when set called with no name (#1527)', () => {
const result = runGsdTools(['workstream', 'set', '--raw'], tmpDir);
assert.ok(!result.success, 'should fail when no name provided');
assert.ok(result.error.includes('name required'), 'error should mention name required');
});
test('--clear explicitly unsets active workstream', () => {
// First set one
runGsdTools(['workstream', 'set', 'ws-b', '--raw'], tmpDir);
// Then clear
const result = runGsdTools(['workstream', 'set', '--clear', '--raw'], tmpDir);
assert.ok(result.success);
const data = JSON.parse(result.output);
assert.strictEqual(data.active, null);
assert.strictEqual(data.cleared, true);
assert.strictEqual(data.previous, 'ws-b');
});
});
// ─── Collision Detection ────────────────────────────────────────────────────