Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions dashboard/src/v2/ProjectsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/ho
import gsap from "gsap";
import { useNavigate } from "@tanstack/react-router";
import {
BookOpen,
Bot,
Check,
Circle,
Expand All @@ -18,7 +19,7 @@ import {
Sparkles,
Trash2,
} from "lucide-preact";
import type { Source, SourceStatus } from "./types.js";
import type { ProjectSetupOptions, Source, SourceStatus } from "./types.js";
import { AddProjectModal, type AddProjectModalSubmission, type SourceType as AddProjectModalSourceType } from "./components/ui/AddProjectModal.js";
import { buildProjectCreationSettingsOverride } from "../lib/settings-updaters.js";
import { DEFAULT_DASHBOARD_SETTINGS } from "../lib/settings.js";
Expand All @@ -37,6 +38,14 @@ import { buildProjectCardViewModel } from "./lib/project-card-view-model.js";

const EMBER_HEX = '#FFB800';

const createDefaultSetupOptions = (): ProjectSetupOptions => ({
agents: true,
quicksprints: true,
previewScript: true,
ci: true,
techstack: true,
docs: false,
});

type Filter = 'All' | 'Running' | 'Idle' | 'Failed';

Expand Down Expand Up @@ -453,13 +462,7 @@ export const ProjectsPage: FunctionComponent = () => {
const [runningSetupProjectIds, setRunningSetupProjectIds] = useState<Set<string>>(() => new Set());
const [setupInvocationByProjectId, setSetupInvocationByProjectId] = useState<Record<string, string>>({});
const [setupError, setSetupError] = useState<string | null>(null);
const [setupOptions, setSetupOptions] = useState({
agents: true,
quicksprints: true,
previewScript: true,
ci: true,
techstack: true,
});
const [setupOptions, setSetupOptions] = useState<ProjectSetupOptions>(() => createDefaultSetupOptions());
const [activeFilter, setActiveFilter] = useState<Filter>('All');
const {
projects: sources,
Expand Down Expand Up @@ -542,13 +545,7 @@ export const ProjectsPage: FunctionComponent = () => {
const launchProjectSetup = (
projectId: string,
projectName: string,
options: {
agents: boolean;
quicksprints: boolean;
previewScript: boolean;
ci: boolean;
techstack: boolean;
},
options: ProjectSetupOptions,
) => {
setRunningSetupProjectIds(prev => new Set(prev).add(projectId));
addToast({
Expand Down Expand Up @@ -810,7 +807,7 @@ export const ProjectsPage: FunctionComponent = () => {
onDelete={() => { void deleteProject(source.id); }}
onSetup={() => {
setSetupProjectId(source.id);
setSetupOptions({ agents: true, quicksprints: true, previewScript: true, ci: true, techstack: true });
setSetupOptions(createDefaultSetupOptions());
setSetupError(null);
}}
onOpenInvocation={() => {
Expand Down Expand Up @@ -872,21 +869,29 @@ export const ProjectsPage: FunctionComponent = () => {
{ key: "previewScript", label: "Preview Script", description: "Container startup." },
{ key: "ci", label: "CI", description: "Basic checks." },
{ key: "techstack", label: "Techstack", description: "Detect and assign from manifests." },
{ key: "docs", label: "Docs", description: "Embed repository docs into Knowledge docs.", icon: BookOpen },
] as const).map((option) => (
<button
key={option.key}
type="button"
onClick={() => setSetupOptions(prev => ({ ...prev, [option.key]: !prev[option.key] }))}
disabled={isActiveSetupRunning}
className={`rounded-2xl border p-4 text-left transition-all disabled:cursor-not-allowed disabled:opacity-60 ${
className={`flex min-w-0 items-start gap-3 rounded-2xl border p-4 text-left transition-all disabled:cursor-not-allowed disabled:opacity-60 ${
setupOptions[option.key]
? "border-ember-500/35 bg-ember-500/[0.08] text-slate-900 dark:text-white"
: "border-black/[0.06] bg-black/[0.025] text-slate-500 dark:border-white/[0.08] dark:bg-white/[0.035] dark:text-slate-400"
}`}
aria-pressed={setupOptions[option.key]}
>
<span className="block text-xs font-black uppercase tracking-[0.14em]">{option.label}</span>
<span className="mt-1 block text-xs font-medium opacity-75">{option.description}</span>
{"icon" in option ? (
<span className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-xl ${setupOptions[option.key] ? "bg-ember-500 text-void-900" : "bg-black/[0.04] text-slate-400 dark:bg-white/[0.06]"}`}>
<option.icon className="h-4 w-4" aria-hidden="true" />
</span>
) : null}
<span className="min-w-0 flex-1">
<span className="block text-xs font-black uppercase tracking-[0.14em]">{option.label}</span>
<span className="mt-1 block text-xs font-medium opacity-75">{option.description}</span>
</span>
</button>
))}
</div>
Expand Down
18 changes: 6 additions & 12 deletions dashboard/src/v2/components/ui/AddProjectModal.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
import type { FunctionComponent } from "preact";
import { useRef, useState, useMemo } from "preact/hooks";
import gsap from "gsap";
import { AlertCircle, Bot, Check, ChevronUp, Cloud, FolderOpen, GitBranch, FolderInput, Globe, Home, Info, Layers3, Link2, Loader2, Lock, PlaySquare, Plus, RefreshCw, ShieldCheck, Sparkles, Workflow, X } from "lucide-preact";
import { AlertCircle, BookOpen, Bot, Check, ChevronUp, Cloud, FolderOpen, GitBranch, FolderInput, Globe, Home, Info, Layers3, Link2, Loader2, Lock, PlaySquare, Plus, RefreshCw, ShieldCheck, Sparkles, Workflow, X } from "lucide-preact";
import { FormError } from "../forms/FormError.js";
import { Modal } from "./Modal.js";
import { ActionFeedbackRegion } from "./ActionFeedbackRegion.js";
import { fetchLocalDirectories } from "../../lib/project-api.js";
import type { LocalDirectoryBrowserResponse } from "../../types.js";
import type { LocalDirectoryBrowserResponse, ProjectSetupOptions } from "../../types.js";
import type { ApplicationKind } from "../../../types.js";
import { DEFAULT_DASHBOARD_SETTINGS } from "../../../lib/settings.js";

export type SourceType = 'local' | 'git' | 'new_project';

type ProjectSetupOptions = {
agents: boolean;
quicksprints: boolean;
previewScript: boolean;
ci: boolean;
techstack: boolean;
};

type ExistingProjectSubmission = {
name: string;
type: 'local' | 'git';
Expand Down Expand Up @@ -102,12 +94,13 @@ export const AddProjectModal: FunctionComponent<AddProjectModalProps> = ({ onClo
const [newIsPrivate, setNewIsPrivate] = useState(true);
const [initializeProject, setInitializeProject] = useState(true);
const [showSetupOptions, setShowSetupOptions] = useState(false);
const [setupOptions, setSetupOptions] = useState({
const [setupOptions, setSetupOptions] = useState<ProjectSetupOptions>({
agents: true,
quicksprints: true,
previewScript: false,
ci: true,
techstack: true,
docs: false,
});
const [submitError, setSubmitError] = useState<string | null>(null);
const [activeDirectoryPickerTarget, setActiveDirectoryPickerTarget] = useState<DirectoryPickerTarget | null>(null);
Expand Down Expand Up @@ -379,6 +372,7 @@ export const AddProjectModal: FunctionComponent<AddProjectModalProps> = ({ onClo
{ key: "previewScript", label: "Preview Script", description: "Container startup script for browser previews.", icon: PlaySquare },
{ key: "ci", label: "CI", description: "Basic GitHub/GitLab error-checking pipelines.", icon: ShieldCheck },
{ key: "techstack", label: "Techstack", description: "Detect and assign a project stack from manifests.", icon: Layers3 },
{ key: "docs", label: "Docs", description: "Embed repository docs into Knowledge docs.", icon: BookOpen },
] as const;

return (
Expand Down Expand Up @@ -659,7 +653,7 @@ export const AddProjectModal: FunctionComponent<AddProjectModalProps> = ({ onClo
</div>
<button
type="button"
onClick={() => setSetupOptions({ agents: true, quicksprints: true, previewScript: true, ci: true, techstack: true })}
onClick={() => setSetupOptions({ agents: true, quicksprints: true, previewScript: true, ci: true, techstack: true, docs: true })}
className="rounded-xl bg-white px-3 py-2 text-[10px] font-black uppercase tracking-[0.14em] text-slate-600 shadow-sm transition-colors hover:text-slate-900 dark:bg-white/[0.08] dark:text-slate-300 dark:hover:text-white"
>
All
Expand Down
2 changes: 2 additions & 0 deletions dashboard/src/v2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import type {
PlanningOverrides,
PlanSprintOptions,
ProjectCollectionResponse,
ProjectSetupOptions,
ProjectSetupRequestInput,
ProjectSetupResult,
ProjectSetupStartResult,
Expand Down Expand Up @@ -317,6 +318,7 @@ export type {
PostListenReplyInput,
PullInboxInput,
ProjectCollectionResponse,
ProjectSetupOptions,
ProjectSetupRequestInput,
ProjectSetupResult,
ProjectSetupStartResult,
Expand Down
4 changes: 2 additions & 2 deletions docs-web/content/docs/user-dashboard-projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The form collects:
| Repository URL | Yes for Git URL imports | Remote repository to clone and track. |
| Git URL slug | Yes for new remote apps | Repository slug for backend remote initialization. It auto-fills from the project name until edited. |
| Init mode | Yes for new projects | `Local Repo` creates a local repository; `Remote Repo` initializes a remote repository and clone. |
| Setup scope | Optional for imports | Runs the Project Setup Agent for imported local or Git projects. Setup can generate agents, quicksprints, preview startup, CI, and a detected techstack from repository evidence. Backend and MCP setup requests can also explicitly enable docs embedding into Knowledge. New app initialization hides setup scope controls. |
| Setup scope | Optional for imports | Runs the Project Setup Agent for imported local or Git projects. Setup can generate agents, quicksprints, preview startup, CI, a detected techstack, and opt-in docs embedding from repository evidence. New app initialization hides setup scope controls. |

On save, Code UX:

Expand All @@ -39,7 +39,7 @@ On save, Code UX:

For imported projects, setup techstack detection inspects dependency manifests, especially `package.json`, plus lockfiles and framework config files. When the detection is valid, Code UX adds the stack to the system catalog if needed and writes the project selection to `techstack.selectedTechstackId`. Invalid or empty detections are ignored without blocking other selected setup artifacts, so imported projects are not classified until evidence or an operator assigns them.

Docs setup is opt-in through setup request payloads. When `docs` is true, Code UX discovers repository documentation and embeds it through the Knowledge docs library, returning embedded document IDs plus per-file errors without failing the rest of setup for a single document failure.
Docs setup is opt-in from the dashboard setup scope or setup request payloads. When `docs` is true, Code UX discovers repository documentation and embeds it through the Knowledge docs library, returning embedded document IDs plus per-file errors without failing the rest of setup for a single document failure.

## Selecting the active project

Expand Down
4 changes: 2 additions & 2 deletions docs-web/user/dashboard/projects.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The form collects:
| Repository URL | Yes for Git URL imports | Remote repository to clone and track. |
| Git URL slug | Yes for new remote apps | Repository slug for backend remote initialization. It auto-fills from the project name until edited. |
| Init mode | Yes for new projects | `Local Repo` creates a local repository; `Remote Repo` initializes a remote repository and clone. |
| Setup scope | Optional for imports | Runs the Project Setup Agent for imported local or Git projects. Setup can generate agents, quicksprints, preview startup, CI, and a detected techstack from repository evidence. Backend and MCP setup requests can also explicitly enable docs embedding into Knowledge. New app initialization hides setup scope controls. |
| Setup scope | Optional for imports | Runs the Project Setup Agent for imported local or Git projects. Setup can generate agents, quicksprints, preview startup, CI, a detected techstack, and opt-in docs embedding from repository evidence. New app initialization hides setup scope controls. |

On save, Code UX:

Expand All @@ -39,7 +39,7 @@ On save, Code UX:

For imported projects, setup techstack detection inspects dependency manifests, especially `package.json`, plus lockfiles and framework config files. When the detection is valid, Code UX adds the stack to the system catalog if needed and writes the project selection to `techstack.selectedTechstackId`. Invalid or empty detections are ignored without blocking other selected setup artifacts, so imported projects are not classified until evidence or an operator assigns them.

Docs setup is opt-in through setup request payloads. When `docs` is true, Code UX discovers repository documentation and embeds it through the Knowledge docs library, returning embedded document IDs plus per-file errors without failing the rest of setup for a single document failure.
Docs setup is opt-in from the dashboard setup scope or setup request payloads. When `docs` is true, Code UX discovers repository documentation and embeds it through the Knowledge docs library, returning embedded document IDs plus per-file errors without failing the rest of setup for a single document failure.

## Selecting the active project

Expand Down
2 changes: 1 addition & 1 deletion docs/dashboard/dashboard-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ Legacy runtime:
- The Projects page `Add Project` placeholder card uses the same full-height card footprint and internal padding as project cards, and the add dialog fields use rounded field surfaces with amber focus states instead of bare underline inputs; the dialog also constrains itself to the viewport on shorter screens
- The `Add Project` dialog now has a wider desktop layout, keeps a stable Git-form-height floor while switching source types, and exposes the inline directory browser on both local project paths and optional Git clone destination paths, with home, refresh, parent-directory navigation, child-directory traversal, and an explicit use-current-folder action
- The `Add Project` dialog now also includes a `New Project` source type. That branch keeps creation inside the same modal, preselects `Local Repo` or `Remote Repo` init modes, shows provider and visibility toggles for remote initialization, and skips the Project Setup Agent controls entirely.
- The `Add Project` dialog preselects Project Setup Agent initialization. When enabled, creation advances to a setup scope step where operators choose Agents, Quicksprint Templates, Preview Container Script, CI, and Techstack before the backend creates repository-specific artifacts. Backend and MCP setup requests can also enable opt-in Docs embedding.
- The `Add Project` dialog preselects Project Setup Agent initialization. When enabled, creation advances to a setup scope step where operators choose Agents, Quicksprint Templates, Preview Container Script, CI, Techstack, and opt-in Docs embedding before the backend creates repository-specific artifacts. Backend and MCP setup requests can also enable Docs embedding.
- Existing project cards expose a Project Setup Agent action that opens the same setup scope for later initialization or regeneration. See [Project Initialization](./project-initialization.md).
- Project setup runs display immediate toast feedback, an `Initializing` project-card state, and direct `Open invocation` actions while the background setup invocation is running and after it finishes.
- Git URL projects are cloned into a local checkout before the project record is created. When the optional clone directory is left empty, Code UX uses `~/.code-ux/projects/<repo-name>` so Docker workspaces always seed from a real repository root instead of a relative placeholder path.
Expand Down
4 changes: 2 additions & 2 deletions docs/dashboard/project-initialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ Project Initialization runs a repository-specific setup pass through the `Projec
- New remote init clones into the selected clone directory, or `~/.code-ux/projects` when the field is blank, and stores the project base directory as the single checkout root `~/.code-ux/projects/<repo-name>`.
- Existing projects expose a `Setup Project` action from the project card agent button.

Imported-project setup lets the operator choose which generated artifacts to create. Backend and MCP setup requests can also explicitly enable docs embedding:
Imported-project setup lets the operator choose which generated artifacts to create. The dashboard keeps Docs disabled by default; selecting it embeds discovered repository documentation into Knowledge docs. Backend and MCP setup requests can also explicitly enable docs embedding:

- `Agents`
- `Quicksprints`
- `Preview Script`
- `CI`
- `Techstack`
- `Docs` (opt-in via setup request payload)
- `Docs` (opt-in)

## Backend Flow

Expand Down
Loading