feat(KB-503): add multi-project CLI support with project subcommands

- Add project subcommands: list, add, remove, show, set-default, detect
- Add --project flag support for all task commands
- Create project-context.ts utilities for project resolution
- Add defaultProjectId to GlobalSettings type
- Implement project auto-detection from cwd
- Update CLI argument parsing for global --project flag
- Add multi-project CLI documentation to AGENTS.md
This commit is contained in:
gsxdsm
2026-04-01 07:02:15 -07:00
parent dc3b711ba5
commit c671beae96
81 changed files with 4130 additions and 2320 deletions

View File

@@ -163,6 +163,36 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, tasks, initi
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
}, [isOpen, view]);
const handleCancel = useCallback(async () => {
// Show confirmation if user has made progress
if (hasProgress) {
if (!confirm("Are you sure you want to close? Your planning progress will be lost.")) {
return;
}
}
// Always close the stream connection
streamConnectionRef.current?.close();
streamConnectionRef.current = null;
if (view.type === "question" || view.type === "summary") {
try {
await cancelPlanning(view.session.sessionId);
} catch {
// Ignore errors on cancel
}
}
setInitialPlan("");
setView({ type: "initial" });
setError(null);
setResponseHistory([]);
setEditedSummary(null);
setStreamingOutput("");
setHasProgress(false);
currentSessionIdRef.current = null;
onClose();
}, [hasProgress, view, onClose]);
// Handle escape key to close
useEffect(() => {
if (!isOpen) return;
@@ -214,36 +244,6 @@ export function PlanningModeModal({ isOpen, onClose, onTaskCreated, tasks, initi
[view]
);
const handleCancel = useCallback(async () => {
// Show confirmation if user has made progress
if (hasProgress) {
if (!confirm("Are you sure you want to close? Your planning progress will be lost.")) {
return;
}
}
// Always close the stream connection
streamConnectionRef.current?.close();
streamConnectionRef.current = null;
if (view.type === "question" || view.type === "summary") {
try {
await cancelPlanning(view.session.sessionId);
} catch {
// Ignore errors on cancel
}
}
setInitialPlan("");
setView({ type: "initial" });
setError(null);
setResponseHistory([]);
setEditedSummary(null);
setStreamingOutput("");
setHasProgress(false);
currentSessionIdRef.current = null;
onClose();
}, [hasProgress, view, onClose]);
const handleCreateTask = useCallback(async () => {
if (view.type !== "summary") return;