@tuan_son.dinh/gsd 2.6.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/LICENSE +21 -0
- package/README.md +453 -0
- package/dist/app-paths.d.ts +4 -0
- package/dist/app-paths.js +6 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +269 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +70 -0
- package/dist/logo.d.ts +16 -0
- package/dist/logo.js +25 -0
- package/dist/onboarding.d.ts +43 -0
- package/dist/onboarding.js +418 -0
- package/dist/pi-migration.d.ts +14 -0
- package/dist/pi-migration.js +57 -0
- package/dist/resource-loader.d.ts +22 -0
- package/dist/resource-loader.js +60 -0
- package/dist/tool-bootstrap.d.ts +4 -0
- package/dist/tool-bootstrap.js +74 -0
- package/dist/wizard.d.ts +7 -0
- package/dist/wizard.js +25 -0
- package/package.json +60 -0
- package/patches/@mariozechner+pi-coding-agent+0.57.1.patch +108 -0
- package/patches/@mariozechner+pi-tui+0.57.1.patch +47 -0
- package/pkg/dist/modes/interactive/theme/dark.json +85 -0
- package/pkg/dist/modes/interactive/theme/light.json +84 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts +78 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.js +949 -0
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -0
- package/pkg/package.json +8 -0
- package/scripts/postinstall.js +127 -0
- package/src/resources/GSD-WORKFLOW.md +661 -0
- package/src/resources/agents/researcher.md +29 -0
- package/src/resources/agents/scout.md +56 -0
- package/src/resources/agents/worker.md +31 -0
- package/src/resources/extensions/ask-user-questions.ts +249 -0
- package/src/resources/extensions/bg-shell/index.ts +2808 -0
- package/src/resources/extensions/browser-tools/BROWSER-TOOLS-V2-PROPOSAL.md +1277 -0
- package/src/resources/extensions/browser-tools/core.js +1057 -0
- package/src/resources/extensions/browser-tools/index.ts +4989 -0
- package/src/resources/extensions/browser-tools/package.json +20 -0
- package/src/resources/extensions/context7/index.ts +428 -0
- package/src/resources/extensions/context7/package.json +11 -0
- package/src/resources/extensions/get-secrets-from-user.ts +352 -0
- package/src/resources/extensions/google-search/index.ts +323 -0
- package/src/resources/extensions/google-search/package.json +9 -0
- package/src/resources/extensions/gsd/activity-log.ts +69 -0
- package/src/resources/extensions/gsd/auto.ts +2744 -0
- package/src/resources/extensions/gsd/commands.ts +313 -0
- package/src/resources/extensions/gsd/crash-recovery.ts +85 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +521 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +176 -0
- package/src/resources/extensions/gsd/doctor.ts +690 -0
- package/src/resources/extensions/gsd/files.ts +732 -0
- package/src/resources/extensions/gsd/git-service.ts +597 -0
- package/src/resources/extensions/gsd/gitignore.ts +168 -0
- package/src/resources/extensions/gsd/guided-flow.ts +817 -0
- package/src/resources/extensions/gsd/index.ts +558 -0
- package/src/resources/extensions/gsd/metrics.ts +374 -0
- package/src/resources/extensions/gsd/migrate/command.ts +218 -0
- package/src/resources/extensions/gsd/migrate/index.ts +42 -0
- package/src/resources/extensions/gsd/migrate/parser.ts +323 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +624 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +48 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +346 -0
- package/src/resources/extensions/gsd/migrate/types.ts +370 -0
- package/src/resources/extensions/gsd/migrate/validator.ts +55 -0
- package/src/resources/extensions/gsd/migrate/writer.ts +539 -0
- package/src/resources/extensions/gsd/observability-validator.ts +408 -0
- package/src/resources/extensions/gsd/package.json +11 -0
- package/src/resources/extensions/gsd/paths.ts +308 -0
- package/src/resources/extensions/gsd/preferences.ts +757 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +50 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +25 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +29 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +189 -0
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +29 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +61 -0
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +59 -0
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -0
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +23 -0
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +11 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -0
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +65 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +51 -0
- package/src/resources/extensions/gsd/prompts/queue.md +85 -0
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +48 -0
- package/src/resources/extensions/gsd/prompts/replan-slice.md +39 -0
- package/src/resources/extensions/gsd/prompts/research-milestone.md +37 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +28 -0
- package/src/resources/extensions/gsd/prompts/review-migration.md +66 -0
- package/src/resources/extensions/gsd/prompts/run-uat.md +109 -0
- package/src/resources/extensions/gsd/prompts/system.md +187 -0
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +123 -0
- package/src/resources/extensions/gsd/session-forensics.ts +487 -0
- package/src/resources/extensions/gsd/skill-discovery.ts +137 -0
- package/src/resources/extensions/gsd/state.ts +460 -0
- package/src/resources/extensions/gsd/templates/context.md +76 -0
- package/src/resources/extensions/gsd/templates/decisions.md +8 -0
- package/src/resources/extensions/gsd/templates/milestone-summary.md +73 -0
- package/src/resources/extensions/gsd/templates/plan.md +131 -0
- package/src/resources/extensions/gsd/templates/preferences.md +24 -0
- package/src/resources/extensions/gsd/templates/project.md +31 -0
- package/src/resources/extensions/gsd/templates/reassessment.md +28 -0
- package/src/resources/extensions/gsd/templates/requirements.md +81 -0
- package/src/resources/extensions/gsd/templates/research.md +46 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +118 -0
- package/src/resources/extensions/gsd/templates/slice-context.md +58 -0
- package/src/resources/extensions/gsd/templates/slice-summary.md +99 -0
- package/src/resources/extensions/gsd/templates/state.md +19 -0
- package/src/resources/extensions/gsd/templates/task-plan.md +52 -0
- package/src/resources/extensions/gsd/templates/task-summary.md +57 -0
- package/src/resources/extensions/gsd/templates/uat.md +54 -0
- package/src/resources/extensions/gsd/tests/activity-log-prune.test.ts +327 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +225 -0
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +160 -0
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +689 -0
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/doctor.test.ts +505 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +1313 -0
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +308 -0
- package/src/resources/extensions/gsd/tests/metrics-io.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +217 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +390 -0
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +786 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +657 -0
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +443 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +318 -0
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +420 -0
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +309 -0
- package/src/resources/extensions/gsd/tests/parsers.test.ts +1351 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +386 -0
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/remote-status.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +521 -0
- package/src/resources/extensions/gsd/tests/requirements.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +34 -0
- package/src/resources/extensions/gsd/tests/resolve-ts.mjs +11 -0
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +247 -0
- package/src/resources/extensions/gsd/tests/workflow-config.test.mjs +53 -0
- package/src/resources/extensions/gsd/tests/workspace-index.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +253 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +160 -0
- package/src/resources/extensions/gsd/tests/worktree.test.ts +264 -0
- package/src/resources/extensions/gsd/types.ts +159 -0
- package/src/resources/extensions/gsd/unit-runtime.ts +184 -0
- package/src/resources/extensions/gsd/workspace-index.ts +203 -0
- package/src/resources/extensions/gsd/worktree-command.ts +845 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +392 -0
- package/src/resources/extensions/gsd/worktree.ts +183 -0
- package/src/resources/extensions/mac-tools/index.ts +852 -0
- package/src/resources/extensions/mac-tools/swift-cli/Package.swift +22 -0
- package/src/resources/extensions/mac-tools/swift-cli/Sources/main.swift +1318 -0
- package/src/resources/extensions/mcporter/index.ts +429 -0
- package/src/resources/extensions/remote-questions/config.ts +81 -0
- package/src/resources/extensions/remote-questions/discord-adapter.ts +128 -0
- package/src/resources/extensions/remote-questions/format.ts +163 -0
- package/src/resources/extensions/remote-questions/manager.ts +192 -0
- package/src/resources/extensions/remote-questions/remote-command.ts +307 -0
- package/src/resources/extensions/remote-questions/slack-adapter.ts +92 -0
- package/src/resources/extensions/remote-questions/status.ts +31 -0
- package/src/resources/extensions/remote-questions/store.ts +77 -0
- package/src/resources/extensions/remote-questions/types.ts +75 -0
- package/src/resources/extensions/search-the-web/cache.ts +78 -0
- package/src/resources/extensions/search-the-web/command-search-provider.ts +95 -0
- package/src/resources/extensions/search-the-web/format.ts +258 -0
- package/src/resources/extensions/search-the-web/http.ts +238 -0
- package/src/resources/extensions/search-the-web/index.ts +65 -0
- package/src/resources/extensions/search-the-web/native-search.ts +157 -0
- package/src/resources/extensions/search-the-web/provider.ts +118 -0
- package/src/resources/extensions/search-the-web/tavily.ts +116 -0
- package/src/resources/extensions/search-the-web/tool-fetch-page.ts +519 -0
- package/src/resources/extensions/search-the-web/tool-llm-context.ts +561 -0
- package/src/resources/extensions/search-the-web/tool-search.ts +576 -0
- package/src/resources/extensions/search-the-web/url-utils.ts +91 -0
- package/src/resources/extensions/shared/confirm-ui.ts +126 -0
- package/src/resources/extensions/shared/interview-ui.ts +613 -0
- package/src/resources/extensions/shared/next-action-ui.ts +197 -0
- package/src/resources/extensions/shared/progress-widget.ts +282 -0
- package/src/resources/extensions/shared/terminal.ts +23 -0
- package/src/resources/extensions/shared/thinking-widget.ts +107 -0
- package/src/resources/extensions/shared/ui.ts +400 -0
- package/src/resources/extensions/shared/wizard-ui.ts +551 -0
- package/src/resources/extensions/slash-commands/audit.ts +88 -0
- package/src/resources/extensions/slash-commands/clear.ts +10 -0
- package/src/resources/extensions/slash-commands/create-extension.ts +297 -0
- package/src/resources/extensions/slash-commands/create-slash-command.ts +234 -0
- package/src/resources/extensions/slash-commands/index.ts +12 -0
- package/src/resources/extensions/subagent/agents.ts +126 -0
- package/src/resources/extensions/subagent/index.ts +1020 -0
- package/src/resources/extensions/voice/index.ts +195 -0
- package/src/resources/extensions/voice/speech-recognizer.swift +154 -0
- package/src/resources/skills/debug-like-expert/SKILL.md +231 -0
- package/src/resources/skills/debug-like-expert/references/debugging-mindset.md +253 -0
- package/src/resources/skills/debug-like-expert/references/hypothesis-testing.md +373 -0
- package/src/resources/skills/debug-like-expert/references/investigation-techniques.md +337 -0
- package/src/resources/skills/debug-like-expert/references/verification-patterns.md +425 -0
- package/src/resources/skills/debug-like-expert/references/when-to-research.md +361 -0
- package/src/resources/skills/frontend-design/SKILL.md +45 -0
- package/src/resources/skills/swiftui/SKILL.md +208 -0
- package/src/resources/skills/swiftui/references/animations.md +921 -0
- package/src/resources/skills/swiftui/references/architecture.md +1561 -0
- package/src/resources/skills/swiftui/references/layout-system.md +1186 -0
- package/src/resources/skills/swiftui/references/navigation.md +1492 -0
- package/src/resources/skills/swiftui/references/networking-async.md +214 -0
- package/src/resources/skills/swiftui/references/performance.md +1706 -0
- package/src/resources/skills/swiftui/references/platform-integration.md +204 -0
- package/src/resources/skills/swiftui/references/state-management.md +1443 -0
- package/src/resources/skills/swiftui/references/swiftdata.md +297 -0
- package/src/resources/skills/swiftui/references/testing-debugging.md +247 -0
- package/src/resources/skills/swiftui/references/uikit-appkit-interop.md +218 -0
- package/src/resources/skills/swiftui/workflows/add-feature.md +191 -0
- package/src/resources/skills/swiftui/workflows/build-new-app.md +311 -0
- package/src/resources/skills/swiftui/workflows/debug-swiftui.md +192 -0
- package/src/resources/skills/swiftui/workflows/optimize-performance.md +197 -0
- package/src/resources/skills/swiftui/workflows/ship-app.md +203 -0
- package/src/resources/skills/swiftui/workflows/write-tests.md +235 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { loadFile, parsePlan, parseRoadmap } from "./files.ts";
|
|
5
|
+
import {
|
|
6
|
+
milestonesDir,
|
|
7
|
+
resolveMilestoneFile,
|
|
8
|
+
resolveSliceFile,
|
|
9
|
+
resolveSlicePath,
|
|
10
|
+
resolveTaskFile,
|
|
11
|
+
resolveTasksDir,
|
|
12
|
+
} from "./paths.ts";
|
|
13
|
+
import { deriveState } from "./state.ts";
|
|
14
|
+
import { type ValidationIssue, validateCompleteBoundary, validatePlanBoundary } from "./observability-validator.ts";
|
|
15
|
+
import { getSliceBranchName, detectWorktreeName } from "./worktree.ts";
|
|
16
|
+
|
|
17
|
+
export interface WorkspaceTaskTarget {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
done: boolean;
|
|
21
|
+
planPath?: string;
|
|
22
|
+
summaryPath?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface WorkspaceSliceTarget {
|
|
26
|
+
id: string;
|
|
27
|
+
title: string;
|
|
28
|
+
done: boolean;
|
|
29
|
+
planPath?: string;
|
|
30
|
+
summaryPath?: string;
|
|
31
|
+
uatPath?: string;
|
|
32
|
+
tasksDir?: string;
|
|
33
|
+
branch?: string;
|
|
34
|
+
tasks: WorkspaceTaskTarget[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface WorkspaceMilestoneTarget {
|
|
38
|
+
id: string;
|
|
39
|
+
title: string;
|
|
40
|
+
roadmapPath?: string;
|
|
41
|
+
slices: WorkspaceSliceTarget[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface WorkspaceScopeTarget {
|
|
45
|
+
scope: string;
|
|
46
|
+
label: string;
|
|
47
|
+
kind: "project" | "milestone" | "slice" | "task";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface GSDWorkspaceIndex {
|
|
51
|
+
milestones: WorkspaceMilestoneTarget[];
|
|
52
|
+
active: {
|
|
53
|
+
milestoneId?: string;
|
|
54
|
+
sliceId?: string;
|
|
55
|
+
taskId?: string;
|
|
56
|
+
phase: string;
|
|
57
|
+
};
|
|
58
|
+
scopes: WorkspaceScopeTarget[];
|
|
59
|
+
validationIssues: ValidationIssue[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function findMilestoneIds(basePath: string): string[] {
|
|
63
|
+
try {
|
|
64
|
+
return readdirSync(milestonesDir(basePath), { withFileTypes: true })
|
|
65
|
+
.filter(entry => entry.isDirectory())
|
|
66
|
+
.map(entry => {
|
|
67
|
+
const match = entry.name.match(/^(M\d+)/);
|
|
68
|
+
return match ? match[1] : entry.name;
|
|
69
|
+
})
|
|
70
|
+
.sort();
|
|
71
|
+
} catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function titleFromRoadmapHeader(content: string, fallbackId: string): string {
|
|
77
|
+
const roadmap = parseRoadmap(content);
|
|
78
|
+
return roadmap.title.replace(/^M\d+[^:]*:\s*/, "") || fallbackId;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function indexSlice(basePath: string, milestoneId: string, sliceId: string, fallbackTitle: string, done: boolean): Promise<WorkspaceSliceTarget> {
|
|
82
|
+
const planPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN") ?? undefined;
|
|
83
|
+
const summaryPath = resolveSliceFile(basePath, milestoneId, sliceId, "SUMMARY") ?? undefined;
|
|
84
|
+
const uatPath = resolveSliceFile(basePath, milestoneId, sliceId, "UAT") ?? undefined;
|
|
85
|
+
const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? undefined;
|
|
86
|
+
|
|
87
|
+
const tasks: WorkspaceTaskTarget[] = [];
|
|
88
|
+
let title = fallbackTitle;
|
|
89
|
+
|
|
90
|
+
if (planPath) {
|
|
91
|
+
const content = await loadFile(planPath);
|
|
92
|
+
if (content) {
|
|
93
|
+
const plan = parsePlan(content);
|
|
94
|
+
title = plan.title || fallbackTitle;
|
|
95
|
+
for (const task of plan.tasks) {
|
|
96
|
+
tasks.push({
|
|
97
|
+
id: task.id,
|
|
98
|
+
title: task.title,
|
|
99
|
+
done: task.done,
|
|
100
|
+
planPath: resolveTaskFile(basePath, milestoneId, sliceId, task.id, "PLAN") ?? undefined,
|
|
101
|
+
summaryPath: resolveTaskFile(basePath, milestoneId, sliceId, task.id, "SUMMARY") ?? undefined,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
id: sliceId,
|
|
109
|
+
title,
|
|
110
|
+
done,
|
|
111
|
+
planPath,
|
|
112
|
+
summaryPath,
|
|
113
|
+
uatPath,
|
|
114
|
+
tasksDir,
|
|
115
|
+
branch: getSliceBranchName(milestoneId, sliceId, detectWorktreeName(basePath)),
|
|
116
|
+
tasks,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function indexWorkspace(basePath: string): Promise<GSDWorkspaceIndex> {
|
|
121
|
+
const milestoneIds = findMilestoneIds(basePath);
|
|
122
|
+
const milestones: WorkspaceMilestoneTarget[] = [];
|
|
123
|
+
const validationIssues: ValidationIssue[] = [];
|
|
124
|
+
|
|
125
|
+
for (const milestoneId of milestoneIds) {
|
|
126
|
+
const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP") ?? undefined;
|
|
127
|
+
let title = milestoneId;
|
|
128
|
+
const slices: WorkspaceSliceTarget[] = [];
|
|
129
|
+
|
|
130
|
+
if (roadmapPath) {
|
|
131
|
+
const roadmapContent = await loadFile(roadmapPath);
|
|
132
|
+
if (roadmapContent) {
|
|
133
|
+
const roadmap = parseRoadmap(roadmapContent);
|
|
134
|
+
title = titleFromRoadmapHeader(roadmapContent, milestoneId);
|
|
135
|
+
for (const slice of roadmap.slices) {
|
|
136
|
+
const indexedSlice = await indexSlice(basePath, milestoneId, slice.id, slice.title, slice.done);
|
|
137
|
+
slices.push(indexedSlice);
|
|
138
|
+
validationIssues.push(...await validatePlanBoundary(basePath, milestoneId, slice.id));
|
|
139
|
+
validationIssues.push(...await validateCompleteBoundary(basePath, milestoneId, slice.id));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
milestones.push({ id: milestoneId, title, roadmapPath, slices });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const state = await deriveState(basePath);
|
|
148
|
+
const active = {
|
|
149
|
+
milestoneId: state.activeMilestone?.id,
|
|
150
|
+
sliceId: state.activeSlice?.id,
|
|
151
|
+
taskId: state.activeTask?.id,
|
|
152
|
+
phase: state.phase,
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const scopes: WorkspaceScopeTarget[] = [{ scope: "project", label: "project", kind: "project" }];
|
|
156
|
+
for (const milestone of milestones) {
|
|
157
|
+
scopes.push({ scope: milestone.id, label: `${milestone.id}: ${milestone.title}`, kind: "milestone" });
|
|
158
|
+
for (const slice of milestone.slices) {
|
|
159
|
+
scopes.push({ scope: `${milestone.id}/${slice.id}`, label: `${milestone.id}/${slice.id}: ${slice.title}`, kind: "slice" });
|
|
160
|
+
for (const task of slice.tasks) {
|
|
161
|
+
scopes.push({
|
|
162
|
+
scope: `${milestone.id}/${slice.id}/${task.id}`,
|
|
163
|
+
label: `${milestone.id}/${slice.id}/${task.id}: ${task.title}`,
|
|
164
|
+
kind: "task",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { milestones, active, scopes, validationIssues };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function listDoctorScopeSuggestions(basePath: string): Promise<Array<{ value: string; label: string }>> {
|
|
174
|
+
const index = await indexWorkspace(basePath);
|
|
175
|
+
const activeSliceScope = index.active.milestoneId && index.active.sliceId
|
|
176
|
+
? `${index.active.milestoneId}/${index.active.sliceId}`
|
|
177
|
+
: null;
|
|
178
|
+
|
|
179
|
+
const ordered = [...index.scopes].filter(scope => scope.kind !== "project");
|
|
180
|
+
ordered.sort((a, b) => {
|
|
181
|
+
if (activeSliceScope && a.scope === activeSliceScope) return -1;
|
|
182
|
+
if (activeSliceScope && b.scope === activeSliceScope) return 1;
|
|
183
|
+
return a.scope.localeCompare(b.scope);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
return ordered.map(scope => ({ value: scope.scope, label: scope.label }));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export async function getSuggestedNextCommands(basePath: string): Promise<string[]> {
|
|
190
|
+
const index = await indexWorkspace(basePath);
|
|
191
|
+
const scope = index.active.milestoneId && index.active.sliceId
|
|
192
|
+
? `${index.active.milestoneId}/${index.active.sliceId}`
|
|
193
|
+
: index.active.milestoneId;
|
|
194
|
+
|
|
195
|
+
const commands = new Set<string>();
|
|
196
|
+
if (index.active.phase === "planning") commands.add("/gsd");
|
|
197
|
+
if (index.active.phase === "executing" || index.active.phase === "summarizing") commands.add("/gsd auto");
|
|
198
|
+
if (scope) commands.add(`/gsd doctor ${scope}`);
|
|
199
|
+
if (scope) commands.add(`/gsd doctor fix ${scope}`);
|
|
200
|
+
if (index.validationIssues.length > 0 && scope) commands.add(`/gsd doctor audit ${scope}`);
|
|
201
|
+
commands.add("/gsd status");
|
|
202
|
+
return [...commands];
|
|
203
|
+
}
|