Fix(workflow): normalize SDK init phase flags (#3389)
* fix: normalize sdk init phase flags * chore: add changeset for sdk init phase flags * test: cover sdk phase equals flag variants
This commit is contained in:
5
.changeset/sdk-init-phase-flags.md
Normal file
5
.changeset/sdk-init-phase-flags.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 3389
|
||||
---
|
||||
**`gsd-sdk query init.*` phase-scoped handlers now accept `--phase <N>` and `--phase=N`** - flag-style init queries no longer search for a phase literally named `--phase`.
|
||||
@@ -325,6 +325,20 @@ describe('initExecutePhase', () => {
|
||||
expect(data.milestone_version).toBeDefined();
|
||||
});
|
||||
|
||||
it('accepts --phase flag form for existing phase (#3387)', async () => {
|
||||
const result = await initExecutePhase(['--phase', '9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('accepts --phase=value flag form for existing phase (#3387)', async () => {
|
||||
const result = await initExecutePhase(['--phase=9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('returns error when phase arg missing', async () => {
|
||||
const result = await initExecutePhase([], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
@@ -360,6 +374,20 @@ describe('initPlanPhase', () => {
|
||||
expect(data.project_root).toBe(tmpDir);
|
||||
});
|
||||
|
||||
it('accepts --phase flag form for existing phase (#3387)', async () => {
|
||||
const result = await initPlanPhase(['--phase', '9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('accepts --phase=value flag form for existing phase (#3387)', async () => {
|
||||
const result = await initPlanPhase(['--phase=9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('returns error when phase arg missing', async () => {
|
||||
const result = await initPlanPhase([], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
@@ -448,6 +476,20 @@ describe('initVerifyWork', () => {
|
||||
expect(data.project_root).toBe(tmpDir);
|
||||
});
|
||||
|
||||
it('accepts --phase flag form for existing phase (#3387)', async () => {
|
||||
const result = await initVerifyWork(['--phase', '9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('accepts --phase=value flag form for existing phase (#3387)', async () => {
|
||||
const result = await initVerifyWork(['--phase=9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('resolves workstream-scoped phases when workstream is provided', async () => {
|
||||
const wsDir = join(tmpDir, '.planning', 'workstreams', 'delivery');
|
||||
await mkdir(join(wsDir, 'phases', '32-shipment-creation-tracking-numbers-print-forms'), { recursive: true });
|
||||
@@ -490,6 +532,20 @@ describe('initPhaseOp', () => {
|
||||
expect(data.plan_count).toBeGreaterThanOrEqual(1);
|
||||
expect(data.project_root).toBe(tmpDir);
|
||||
});
|
||||
|
||||
it('accepts --phase flag form for existing phase (#3387)', async () => {
|
||||
const result = await initPhaseOp(['--phase', '9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
|
||||
it('accepts --phase=value flag form for existing phase (#3387)', async () => {
|
||||
const result = await initPhaseOp(['--phase=9'], tmpDir);
|
||||
const data = result.data as Record<string, unknown>;
|
||||
expect(data.phase_found).toBe(true);
|
||||
expect(data.phase_number).toBe('09');
|
||||
});
|
||||
});
|
||||
|
||||
describe('initTodos', () => {
|
||||
|
||||
@@ -54,6 +54,23 @@ function generateSlugInternal(text: string): string {
|
||||
.substring(0, 60);
|
||||
}
|
||||
|
||||
function extractPhaseArg(args: string[]): string | undefined {
|
||||
const equalsArg = args.find((arg) => arg.startsWith('--phase='));
|
||||
if (equalsArg) {
|
||||
const value = equalsArg.slice('--phase='.length).trim();
|
||||
return value || undefined;
|
||||
}
|
||||
|
||||
const flagIndex = args.indexOf('--phase');
|
||||
if (flagIndex !== -1) {
|
||||
const value = args[flagIndex + 1];
|
||||
return value && !value.startsWith('--') ? value : undefined;
|
||||
}
|
||||
|
||||
const first = args[0];
|
||||
return first && !first.startsWith('--') ? first : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path exists on disk.
|
||||
*/
|
||||
@@ -293,7 +310,7 @@ export function withProjectRoot(
|
||||
* Port of cmdInitExecutePhase from init.cjs lines 50-171.
|
||||
*/
|
||||
export const initExecutePhase: QueryHandler = async (args, projectDir, workstream) => {
|
||||
const phase = args[0];
|
||||
const phase = extractPhaseArg(args);
|
||||
if (!phase) {
|
||||
return { data: { error: 'phase required for init execute-phase' } };
|
||||
}
|
||||
@@ -376,7 +393,7 @@ export const initExecutePhase: QueryHandler = async (args, projectDir, workstrea
|
||||
* Port of cmdInitPlanPhase from init.cjs lines 173-293.
|
||||
*/
|
||||
export const initPlanPhase: QueryHandler = async (args, projectDir, workstream) => {
|
||||
const phase = args[0];
|
||||
const phase = extractPhaseArg(args);
|
||||
if (!phase) {
|
||||
return { data: { error: 'phase required for init plan-phase' } };
|
||||
}
|
||||
@@ -623,7 +640,7 @@ export const initResume: QueryHandler = async (_args, projectDir) => {
|
||||
* Port of cmdInitVerifyWork from init.cjs lines 538-586.
|
||||
*/
|
||||
export const initVerifyWork: QueryHandler = async (args, projectDir, workstream) => {
|
||||
const phase = args[0];
|
||||
const phase = extractPhaseArg(args);
|
||||
if (!phase) {
|
||||
return { data: { error: 'phase required for init verify-work' } };
|
||||
}
|
||||
@@ -660,7 +677,7 @@ export const initVerifyWork: QueryHandler = async (args, projectDir, workstream)
|
||||
* Port of cmdInitPhaseOp from init.cjs lines 588-697.
|
||||
*/
|
||||
export const initPhaseOp: QueryHandler = async (args, projectDir, workstream) => {
|
||||
const phase = args[0];
|
||||
const phase = extractPhaseArg(args);
|
||||
if (!phase) {
|
||||
return { data: { error: 'phase required for init phase-op' } };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user