diff --git a/packages/app/src/app/app.tsx b/packages/app/src/app/app.tsx index 37b43511..cf3c201b 100644 --- a/packages/app/src/app/app.tsx +++ b/packages/app/src/app/app.tsx @@ -723,12 +723,14 @@ export default function App() { setTemplateDraftPrompt, templateDraftScope, setTemplateDraftScope, + templateDraftAutoRun, + setTemplateDraftAutoRun, workspaceTemplates, globalTemplates, openTemplateModal, saveTemplate, deleteTemplate, - runTemplate, + applyTemplate, loadWorkspaceTemplates, } = templateState; @@ -1474,8 +1476,15 @@ export default function App() { applyThemeMode(isDark ? "dark" : "light"); }); + // Listen for setPrompt events from template system (when autoRun is disabled) + const handleSetPrompt = (e: CustomEvent) => { + setPrompt(e.detail); + }; + window.addEventListener("openwork:setPrompt", handleSetPrompt as EventListener); + onCleanup(() => { unsubscribeTheme(); + window.removeEventListener("openwork:setPrompt", handleSetPrompt as EventListener); }); createEffect(() => { @@ -2090,7 +2099,7 @@ export default function App() { setTemplateDraftScope(scope); }, openTemplateModal, - runTemplate, + applyTemplate, deleteTemplate, refreshSkills: (options?: { force?: boolean }) => refreshSkills(options).catch(() => undefined), refreshPlugins: (scopeOverride?: PluginScope) => @@ -2263,6 +2272,8 @@ export default function App() { sessionStatus={selectedSessionStatus()} renameSession={renameSessionTitle} error={error()} + workspaceTemplates={workspaceTemplates()} + applyTemplate={applyTemplate} /> @@ -2332,12 +2343,14 @@ export default function App() { description={templateDraftDescription()} prompt={templateDraftPrompt()} scope={templateDraftScope()} + autoRun={templateDraftAutoRun()} onClose={() => setTemplateModalOpen(false)} onSave={saveTemplate} onTitleChange={setTemplateDraftTitle} onDescriptionChange={setTemplateDraftDescription} onPromptChange={setTemplateDraftPrompt} onScopeChange={setTemplateDraftScope} + onAutoRunChange={setTemplateDraftAutoRun} /> void; onSave: () => void; onTitleChange: (value: string) => void; onDescriptionChange: (value: string) => void; onPromptChange: (value: string) => void; onScopeChange: (value: "workspace" | "global") => void; + onAutoRunChange: (value: boolean) => void; }; export default function TemplateModal(props: TemplateModalProps) { @@ -88,6 +90,25 @@ export default function TemplateModal(props: TemplateModalProps) { />
{translate("templates.prompt_hint")}
+ + {/* Auto-run Toggle */} +
+
+
{translate("templates.auto_run_label")}
+
{translate("templates.auto_run_hint")}
+
+ +
diff --git a/packages/app/src/app/pages/dashboard.tsx b/packages/app/src/app/pages/dashboard.tsx index a20d4c1a..69ae6593 100644 --- a/packages/app/src/app/pages/dashboard.tsx +++ b/packages/app/src/app/pages/dashboard.tsx @@ -78,7 +78,7 @@ export type DashboardViewProps = { setTemplateDraftScope: (value: "workspace" | "global") => void; openTemplateModal: () => void; resetTemplateDraft?: (scope?: "workspace" | "global") => void; - runTemplate: (template: WorkspaceTemplate) => void; + applyTemplate: (template: WorkspaceTemplate) => void; deleteTemplate: (templateId: string) => void; refreshSkills: (options?: { force?: boolean }) => void; refreshPlugins: (scopeOverride?: PluginScope) => void; @@ -537,7 +537,7 @@ export default function DashboardView(props: DashboardViewProps) { {(t) => ( )} @@ -698,7 +698,7 @@ export default function DashboardView(props: DashboardViewProps) { setTemplateDraftScope={props.setTemplateDraftScope} openTemplateModal={props.openTemplateModal} resetTemplateDraft={props.resetTemplateDraft} - runTemplate={props.runTemplate} + applyTemplate={props.applyTemplate} deleteTemplate={props.deleteTemplate} /> diff --git a/packages/app/src/app/pages/session.tsx b/packages/app/src/app/pages/session.tsx index 048a5d00..c051f878 100644 --- a/packages/app/src/app/pages/session.tsx +++ b/packages/app/src/app/pages/session.tsx @@ -9,11 +9,13 @@ import type { TodoItem, View, WorkspaceDisplay, + WorkspaceTemplate, } from "../types"; import { AlertTriangle, ArrowRight, + FileText, ChevronDown, HardDrive, Shield, @@ -94,6 +96,8 @@ export type SessionViewProps = { setSessionAgent: (sessionId: string, agent: string | null) => void; saveSession: (sessionId: string) => Promise; sessionStatusById: Record; + workspaceTemplates: WorkspaceTemplate[]; + applyTemplate: (template: WorkspaceTemplate) => void; }; export default function SessionView(props: SessionViewProps) { @@ -429,7 +433,7 @@ export default function SessionView(props: SessionViewProps) { } setPrevArtifactCount(count); }); - + createEffect(() => { const files = props.workingFiles; const count = files.length; @@ -824,87 +828,132 @@ export default function SessionView(props: SessionViewProps) { } `} - + -
-
- +
+
+
+ +
+

Ready to work

+

+ Describe a task. I'll show progress and ask for permissions when needed. +

-

Ready to work

-

- Describe a task. I'll show progress and ask for permissions when needed. -

-
- - -
- -
+ {/* Spacer */} +
+ + {/* Quick Start Templates */} + 0}> +
+
+

+ Quick Start Templates +

+ +
+
+ + {(t) => ( - - {(detail) => ( -
-
{detail().title}
- -
{detail().detail}
-
+ )} + +
+
+ +
+
+ + 0}> + +
+ +
+
-
-
-
- } - > - - - {runLine()} + + + + {(detail) => ( +
+
{detail().title}
+ +
{detail().detail}
+
+
+ )} +
+
+ +
+
+ } + > + + + {runLine()} +
+ {runElapsedLabel()}
- {runElapsedLabel()}
-
- ) : undefined - } - /> + ) : undefined + } + /> +
(messagesEndEl = el)} />
- + chatContainerEl} messages={props.messages} /> @@ -914,7 +963,7 @@ export default function SessionView(props: SessionViewProps) {
- void; openTemplateModal: () => void; resetTemplateDraft?: (scope?: "workspace" | "global") => void; - runTemplate: (template: WorkspaceTemplate) => void; + applyTemplate: (template: WorkspaceTemplate) => void; deleteTemplate: (templateId: string) => void; }; @@ -68,9 +68,9 @@ export default function TemplatesView(props: TemplatesViewProps) {
{formatRelativeTime(t.createdAt)}
-
-