@mndrk/agx 2.4.5 → 2.4.6
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/cloud-runtime/standalone/apps/local/.next/BUILD_ID +1 -1
- package/cloud-runtime/standalone/apps/local/.next/build-manifest.json +2 -2
- package/cloud-runtime/standalone/apps/local/.next/prerender-manifest.json +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/[id]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github/select-repos/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github/select-repos.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/notifications/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/notifications/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/prs/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/prs/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__23838f87._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__a61463b8._.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/_0ecd68e8._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/_5c140c38._.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_30d021de._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_988d29c0._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_app_projects_[slug]_teams_[teamId]_page_tsx_6dcfdd52._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_PromptJobBoard_tsx_281b2873._.js +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_projects_ProjectObjectivesWorkspace_tsx_751ab3d3._.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/middleware-manifest.json +5 -5
- package/cloud-runtime/standalone/apps/local/.next/server/pages/404.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/pages/500.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/692103d55fcd0328.js +5 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{8b5d6f5bade8c4ea.js → 8d8fe711583a59f0.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/92467c495ad08a85.js +5 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/add53c2fe147af75.css +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/d662272e49df1950.js +20 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/e0d68c6af17c8c87.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{93b2b6aa0c9593f6.js → e6d4118b7c32d11c.js} +1 -1
- package/cloud-runtime/standalone/apps/local/app/projects/[slug]/teams/[teamId]/page.tsx +58 -2
- package/cloud-runtime/standalone/apps/local/components/PromptJobBoard.tsx +73 -33
- package/cloud-runtime/standalone/apps/local/components/projects/ObjectiveScheduledTasksPanel.tsx +78 -239
- package/cloud-runtime/standalone/apps/local/components/thread/WorkspaceSidebar.tsx +2 -2
- package/cloud-runtime/standalone/apps/local/worker/index.js +2 -2
- package/package.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__7e3c2ea1._.js +0 -7
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__dbda910b._.js +0 -7
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/_917d90b4._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_a2835b49._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/55a31773f8c2833f.js +0 -20
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/7c8515a24aeea102.js +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/80446e085a3aad56.css +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/9c29ef447bef1576.js +0 -5
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/a9111ccc979d4933.js +0 -5
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/d2b34ade19d9d8da.js +0 -1
- /package/cloud-runtime/standalone/apps/local/.next/static/{C3-tP4djbU34_g7VoIFac → fipnHmd6JPn9sTuFdYS0y}/_buildManifest.js +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{C3-tP4djbU34_g7VoIFac → fipnHmd6JPn9sTuFdYS0y}/_clientMiddlewareManifest.json +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{C3-tP4djbU34_g7VoIFac → fipnHmd6JPn9sTuFdYS0y}/_ssgManifest.js +0 -0
|
@@ -66,7 +66,7 @@ export default function TeamDetailPage({
|
|
|
66
66
|
|
|
67
67
|
// Add agent
|
|
68
68
|
const [showAddAgent, setShowAddAgent] = useState(false);
|
|
69
|
-
const [addMode, setAddMode] = useState<"existing" | "preset">("existing");
|
|
69
|
+
const [addMode, setAddMode] = useState<"existing" | "preset" | "scratch">("existing");
|
|
70
70
|
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(null);
|
|
71
71
|
const [selectedExistingId, setSelectedExistingId] = useState<string | null>(null);
|
|
72
72
|
const [addingAgent, setAddingAgent] = useState(false);
|
|
@@ -444,9 +444,65 @@ export default function TeamDetailPage({
|
|
|
444
444
|
>
|
|
445
445
|
From Preset
|
|
446
446
|
</button>
|
|
447
|
+
<button
|
|
448
|
+
onClick={() => setAddMode("scratch")}
|
|
449
|
+
className={`text-xs font-medium px-3 py-1.5 rounded-lg transition-colors ${
|
|
450
|
+
addMode === "scratch"
|
|
451
|
+
? "bg-[var(--primary)] text-white"
|
|
452
|
+
: "bg-[var(--card-bg)] border border-[var(--border)] text-[var(--muted-foreground)]"
|
|
453
|
+
}`}
|
|
454
|
+
>
|
|
455
|
+
From Scratch
|
|
456
|
+
</button>
|
|
447
457
|
</div>
|
|
448
458
|
|
|
449
|
-
{addMode === "
|
|
459
|
+
{addMode === "scratch" ? (
|
|
460
|
+
<AgentForm
|
|
461
|
+
title="Create agent"
|
|
462
|
+
initial={{ name: "", role: "", provider: "claude", model: "", identity: "", skills: [], skillBindings: [] }}
|
|
463
|
+
submitLabel="Create & Add"
|
|
464
|
+
onSubmit={async (data) => {
|
|
465
|
+
if (!project) return;
|
|
466
|
+
setAddingAgent(true);
|
|
467
|
+
try {
|
|
468
|
+
const createRes = await fetch("/api/participants", {
|
|
469
|
+
method: "POST",
|
|
470
|
+
headers: { "Content-Type": "application/json" },
|
|
471
|
+
body: JSON.stringify({
|
|
472
|
+
name: data.name,
|
|
473
|
+
role: data.role || null,
|
|
474
|
+
provider: data.provider,
|
|
475
|
+
model: data.model || null,
|
|
476
|
+
color: data.color,
|
|
477
|
+
...(data.identity ? { identity: data.identity } : {}),
|
|
478
|
+
skills: data.skills ?? [],
|
|
479
|
+
skillBindings: data.skillBindings ?? [],
|
|
480
|
+
}),
|
|
481
|
+
});
|
|
482
|
+
if (!createRes.ok) throw new Error("Failed to create agent");
|
|
483
|
+
const created = await createRes.json();
|
|
484
|
+
const agentId = created.id ?? created.participant?.id;
|
|
485
|
+
await fetch(`/api/projects/${project.id}/agents`, {
|
|
486
|
+
method: "POST",
|
|
487
|
+
headers: { "Content-Type": "application/json" },
|
|
488
|
+
body: JSON.stringify({ agentId }),
|
|
489
|
+
});
|
|
490
|
+
await fetch(`/api/projects/${project.id}/teams/${teamId}/agents`, {
|
|
491
|
+
method: "POST",
|
|
492
|
+
headers: { "Content-Type": "application/json" },
|
|
493
|
+
body: JSON.stringify({ agentId, roleKey: "member" }),
|
|
494
|
+
});
|
|
495
|
+
setShowAddAgent(false);
|
|
496
|
+
await Promise.all([fetchTeam(), fetchParticipants()]);
|
|
497
|
+
} catch {
|
|
498
|
+
/* silent */
|
|
499
|
+
} finally {
|
|
500
|
+
setAddingAgent(false);
|
|
501
|
+
}
|
|
502
|
+
}}
|
|
503
|
+
onCancel={() => setShowAddAgent(false)}
|
|
504
|
+
/>
|
|
505
|
+
) : addMode === "existing" ? (
|
|
450
506
|
<div className="space-y-3">
|
|
451
507
|
{existingAgentOptions.length === 0 ? (
|
|
452
508
|
<p className="text-xs text-[var(--muted-foreground)]">
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
Pencil,
|
|
17
17
|
User,
|
|
18
18
|
Sparkles,
|
|
19
|
+
Search,
|
|
19
20
|
} from "lucide-react";
|
|
20
21
|
import { useUrlSelection } from "@/hooks/useUrlSelection";
|
|
21
22
|
import { usePromptJobs } from "@/hooks/usePromptJobs";
|
|
@@ -133,7 +134,7 @@ function SectionLabel({ children }: { children: React.ReactNode }) {
|
|
|
133
134
|
|
|
134
135
|
// ── Create/Edit Modal ────────────────────────────────────────────────────────
|
|
135
136
|
|
|
136
|
-
interface AgentOption {
|
|
137
|
+
export interface AgentOption {
|
|
137
138
|
id: string;
|
|
138
139
|
name: string;
|
|
139
140
|
provider: string;
|
|
@@ -163,12 +164,12 @@ function Label({ children }: { children: React.ReactNode }) {
|
|
|
163
164
|
);
|
|
164
165
|
}
|
|
165
166
|
|
|
166
|
-
function agentAvatar(id: string, color: string, size = 24) {
|
|
167
|
+
export function agentAvatar(id: string, color: string, size = 24) {
|
|
167
168
|
const bg = color ? color.replace("#", "") : "e2e8f0";
|
|
168
169
|
return `https://api.dicebear.com/9.x/bottts-neutral/svg?seed=${encodeURIComponent(id)}&size=${size}&backgroundColor=${bg}`;
|
|
169
170
|
}
|
|
170
171
|
|
|
171
|
-
function AgentDropdown({
|
|
172
|
+
export function AgentDropdown({
|
|
172
173
|
agents,
|
|
173
174
|
value,
|
|
174
175
|
onChange,
|
|
@@ -178,8 +179,23 @@ function AgentDropdown({
|
|
|
178
179
|
onChange: (id: string) => void;
|
|
179
180
|
}) {
|
|
180
181
|
const [open, setOpen] = useState(false);
|
|
182
|
+
const [query, setQuery] = useState("");
|
|
181
183
|
const selected = agents.find((a) => a.id === value);
|
|
182
184
|
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (!open) setQuery("");
|
|
187
|
+
}, [open]);
|
|
188
|
+
|
|
189
|
+
const q = query.trim().toLowerCase();
|
|
190
|
+
const filteredAgents = q
|
|
191
|
+
? agents.filter(
|
|
192
|
+
(a) =>
|
|
193
|
+
a.name.toLowerCase().includes(q) ||
|
|
194
|
+
a.provider.toLowerCase().includes(q) ||
|
|
195
|
+
(a.model ?? "").toLowerCase().includes(q)
|
|
196
|
+
)
|
|
197
|
+
: agents;
|
|
198
|
+
|
|
183
199
|
return (
|
|
184
200
|
<div className="relative">
|
|
185
201
|
<Label>Agent</Label>
|
|
@@ -217,38 +233,62 @@ function AgentDropdown({
|
|
|
217
233
|
</button>
|
|
218
234
|
|
|
219
235
|
{open && (
|
|
220
|
-
<div className="absolute z-20 mt-1 w-full rounded-lg border border-[var(--card-border)] bg-[var(--card-bg)] shadow-lg max-h-[
|
|
221
|
-
|
|
222
|
-
<
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
onChange(a.id);
|
|
227
|
-
setOpen(false);
|
|
228
|
-
}}
|
|
229
|
-
className={`w-full flex items-center gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-[var(--muted)] ${value === a.id ? "bg-[var(--muted)]" : ""}`}
|
|
230
|
-
>
|
|
231
|
-
<img
|
|
232
|
-
src={agentAvatar(a.id, a.color)}
|
|
233
|
-
alt=""
|
|
234
|
-
className="size-6 rounded-full shrink-0"
|
|
236
|
+
<div className="absolute z-20 mt-1 w-full rounded-lg border border-[var(--card-border)] bg-[var(--card-bg)] shadow-lg flex flex-col max-h-[320px]">
|
|
237
|
+
<div className="sticky top-0 shrink-0 border-b border-[var(--card-border)] bg-[var(--card-bg)] px-2 py-2">
|
|
238
|
+
<div className="relative">
|
|
239
|
+
<Search
|
|
240
|
+
size={12}
|
|
241
|
+
className="absolute left-2.5 top-1/2 -translate-y-1/2 text-[var(--muted-foreground)]"
|
|
235
242
|
/>
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
243
|
+
<input
|
|
244
|
+
type="text"
|
|
245
|
+
value={query}
|
|
246
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
247
|
+
autoFocus
|
|
248
|
+
placeholder="Search agents..."
|
|
249
|
+
className="w-full rounded-md border border-[var(--card-border)] bg-[var(--muted)] pl-7 pr-2 py-1.5 text-xs text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus:outline-none focus:border-[var(--foreground)]"
|
|
250
|
+
/>
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
<div className="min-h-0 flex-1 overflow-y-auto">
|
|
254
|
+
{filteredAgents.length === 0 ? (
|
|
255
|
+
<div className="px-3 py-4 text-center text-[11px] text-[var(--muted-foreground)]">
|
|
256
|
+
No agents match "{query}"
|
|
244
257
|
</div>
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
258
|
+
) : (
|
|
259
|
+
filteredAgents.map((a) => (
|
|
260
|
+
<button
|
|
261
|
+
key={a.id}
|
|
262
|
+
type="button"
|
|
263
|
+
onClick={() => {
|
|
264
|
+
onChange(a.id);
|
|
265
|
+
setOpen(false);
|
|
266
|
+
}}
|
|
267
|
+
className={`w-full flex items-center gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-[var(--muted)] ${value === a.id ? "bg-[var(--muted)]" : ""}`}
|
|
268
|
+
>
|
|
269
|
+
<img
|
|
270
|
+
src={agentAvatar(a.id, a.color)}
|
|
271
|
+
alt=""
|
|
272
|
+
className="size-6 rounded-full shrink-0"
|
|
273
|
+
/>
|
|
274
|
+
<div className="min-w-0 flex-1">
|
|
275
|
+
<div className="text-xs font-medium text-[var(--foreground)] truncate">
|
|
276
|
+
{a.name}
|
|
277
|
+
</div>
|
|
278
|
+
<div className="text-[10px] text-[var(--muted-foreground)]">
|
|
279
|
+
{a.provider}
|
|
280
|
+
{a.model ? ` / ${a.model}` : ""}
|
|
281
|
+
</div>
|
|
282
|
+
</div>
|
|
283
|
+
{value === a.id && (
|
|
284
|
+
<span className="text-xs text-[var(--foreground)]">
|
|
285
|
+
✓
|
|
286
|
+
</span>
|
|
287
|
+
)}
|
|
288
|
+
</button>
|
|
289
|
+
))
|
|
290
|
+
)}
|
|
291
|
+
</div>
|
|
252
292
|
</div>
|
|
253
293
|
)}
|
|
254
294
|
</div>
|
package/cloud-runtime/standalone/apps/local/components/projects/ObjectiveScheduledTasksPanel.tsx
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
4
|
-
import { Check, Clock, Pause, Play, Plus,
|
|
4
|
+
import { Check, Clock, Pause, Pencil, Play, Plus, Terminal, Trash2, XCircle } from "lucide-react";
|
|
5
5
|
import { usePromptJobs } from "@/hooks/usePromptJobs";
|
|
6
6
|
import { cronToHuman } from "@/src/graph/nl-schedule";
|
|
7
7
|
import type { PromptJob, PromptRun } from "@/src/prompt-scheduler/types";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
CreateJobModal,
|
|
10
|
+
agentAvatar,
|
|
11
|
+
type AgentOption,
|
|
12
|
+
type CreateJobData,
|
|
13
|
+
} from "@/components/PromptJobBoard";
|
|
9
14
|
import ConfirmDialog from "@/components/ConfirmDialog";
|
|
10
|
-
import RichTextEditor from "@/components/RichTextEditor";
|
|
11
|
-
import { ScheduleConditionPicker } from "@/components/scheduling/ScheduleConditionPicker";
|
|
12
15
|
|
|
13
16
|
export type ObjectiveScheduledTaskDraft = CreateJobData;
|
|
14
17
|
|
|
@@ -51,14 +54,6 @@ function formatNextRun(epochMs: number | null, state: PromptJob["state"]): strin
|
|
|
51
54
|
return `in ${Math.round(diff / 86_400_000)}d`;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
function promptSummary(prompt: string): string {
|
|
55
|
-
const firstLine = prompt
|
|
56
|
-
.split("\n")
|
|
57
|
-
.map((line) => line.trim())
|
|
58
|
-
.find(Boolean);
|
|
59
|
-
return firstLine || "No instructions yet";
|
|
60
|
-
}
|
|
61
|
-
|
|
62
57
|
function formatDateTime(value: string): string {
|
|
63
58
|
const date = new Date(value);
|
|
64
59
|
return date.toLocaleString(undefined, {
|
|
@@ -69,186 +64,6 @@ function formatDateTime(value: string): string {
|
|
|
69
64
|
});
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
function ScheduleEditModal({
|
|
73
|
-
job,
|
|
74
|
-
onClose,
|
|
75
|
-
onUpdate,
|
|
76
|
-
}: {
|
|
77
|
-
job: PromptJob;
|
|
78
|
-
onClose: () => void;
|
|
79
|
-
onUpdate: (updates: Partial<PromptJob>) => Promise<boolean>;
|
|
80
|
-
}) {
|
|
81
|
-
const [scheduleValue, setScheduleValue] = useState({
|
|
82
|
-
cadence: job.cronExpr || job.cadence || "",
|
|
83
|
-
condition: job.condition || "",
|
|
84
|
-
});
|
|
85
|
-
const [isValid, setIsValid] = useState(true);
|
|
86
|
-
const [saving, setSaving] = useState(false);
|
|
87
|
-
|
|
88
|
-
const handleSave = async () => {
|
|
89
|
-
if (!isValid) return;
|
|
90
|
-
setSaving(true);
|
|
91
|
-
const ok = await onUpdate({
|
|
92
|
-
cadence: scheduleValue.cadence,
|
|
93
|
-
condition: scheduleValue.condition,
|
|
94
|
-
} as Partial<PromptJob>);
|
|
95
|
-
setSaving(false);
|
|
96
|
-
if (ok) {
|
|
97
|
-
onClose();
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4 py-6">
|
|
103
|
-
<div className="flex w-full max-w-md max-h-[85vh] flex-col rounded-[28px] border border-[var(--border)] bg-[var(--card-bg)] shadow-2xl">
|
|
104
|
-
<div className="flex shrink-0 items-center justify-between border-b border-[var(--border)] px-6 py-4">
|
|
105
|
-
<div className="flex items-center gap-2.5">
|
|
106
|
-
<Clock className="h-4 w-4 text-[var(--muted-foreground)]" />
|
|
107
|
-
<p className="text-sm font-semibold text-[var(--foreground)]">{job.name}</p>
|
|
108
|
-
</div>
|
|
109
|
-
<button
|
|
110
|
-
type="button"
|
|
111
|
-
onClick={onClose}
|
|
112
|
-
className="rounded-lg border border-[var(--border)] p-2 text-[var(--muted-foreground)] transition-colors hover:border-[var(--card-hover-border)] hover:text-[var(--foreground)]"
|
|
113
|
-
>
|
|
114
|
-
<X className="h-4 w-4" />
|
|
115
|
-
</button>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div className="min-h-0 flex-1 overflow-y-auto px-6 py-5">
|
|
119
|
-
<ScheduleConditionPicker
|
|
120
|
-
value={scheduleValue}
|
|
121
|
-
onChange={(next, meta) => {
|
|
122
|
-
setScheduleValue(next);
|
|
123
|
-
setIsValid(meta.isScheduleValid);
|
|
124
|
-
}}
|
|
125
|
-
scheduleLabel="Schedule"
|
|
126
|
-
conditionLabel="Condition"
|
|
127
|
-
conditionHelpText="Scheduled runs and Run now will check this condition before executing."
|
|
128
|
-
/>
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div className="flex shrink-0 items-center justify-end gap-3 border-t border-[var(--border)] px-6 py-4">
|
|
132
|
-
<button
|
|
133
|
-
type="button"
|
|
134
|
-
onClick={onClose}
|
|
135
|
-
className="rounded-xl border border-[var(--border)] px-4 py-2.5 text-sm text-[var(--foreground)] transition-colors hover:border-[var(--card-hover-border)]"
|
|
136
|
-
>
|
|
137
|
-
Cancel
|
|
138
|
-
</button>
|
|
139
|
-
<button
|
|
140
|
-
type="button"
|
|
141
|
-
onClick={() => void handleSave()}
|
|
142
|
-
disabled={saving || !isValid}
|
|
143
|
-
className="rounded-xl border border-emerald-500/30 bg-emerald-500/10 px-4 py-2.5 text-sm text-emerald-400 transition-colors hover:bg-emerald-500/20 disabled:opacity-50"
|
|
144
|
-
>
|
|
145
|
-
{saving ? "Saving..." : "Save"}
|
|
146
|
-
</button>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function ObjectiveScheduledTaskDetailModal({
|
|
154
|
-
job,
|
|
155
|
-
onClose,
|
|
156
|
-
onUpdate,
|
|
157
|
-
}: {
|
|
158
|
-
job: PromptJob;
|
|
159
|
-
onClose: () => void;
|
|
160
|
-
onUpdate: (updates: Partial<PromptJob>) => Promise<boolean>;
|
|
161
|
-
}) {
|
|
162
|
-
const [promptDraft, setPromptDraft] = useState(job.prompt || "");
|
|
163
|
-
const [saving, setSaving] = useState(false);
|
|
164
|
-
|
|
165
|
-
const savePrompt = async () => {
|
|
166
|
-
if (promptDraft === job.prompt) return;
|
|
167
|
-
setSaving(true);
|
|
168
|
-
await onUpdate({ prompt: promptDraft } as Partial<PromptJob>);
|
|
169
|
-
setSaving(false);
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
return (
|
|
173
|
-
<div className="fixed inset-0 z-40 flex items-center justify-center bg-black/50 px-4 py-6">
|
|
174
|
-
<div className="flex w-full max-w-6xl max-h-[85vh] flex-col rounded-[28px] border border-[var(--border)] bg-[var(--card-bg)] shadow-2xl">
|
|
175
|
-
{/* Header */}
|
|
176
|
-
<div className="flex shrink-0 items-start justify-between gap-4 border-b border-[var(--border)] px-6 py-5">
|
|
177
|
-
<div className="min-w-0">
|
|
178
|
-
<div className="flex flex-wrap items-center gap-2.5">
|
|
179
|
-
<p className="truncate text-lg font-semibold text-[var(--foreground)]">
|
|
180
|
-
{job.name}
|
|
181
|
-
</p>
|
|
182
|
-
<span
|
|
183
|
-
className={`rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.16em] ${stateClasses(job.state)}`}
|
|
184
|
-
>
|
|
185
|
-
{formatState(job.state)}
|
|
186
|
-
</span>
|
|
187
|
-
{job.condition ? (
|
|
188
|
-
<span className="rounded-md border border-blue-400/20 bg-blue-500/10 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-blue-400">
|
|
189
|
-
gated
|
|
190
|
-
</span>
|
|
191
|
-
) : null}
|
|
192
|
-
</div>
|
|
193
|
-
<div className="mt-2 flex flex-wrap items-center gap-3 text-xs text-[var(--muted-foreground)]">
|
|
194
|
-
<span className="inline-flex items-center gap-1.5">
|
|
195
|
-
<Clock className="h-3.5 w-3.5" />
|
|
196
|
-
{formatCadence(job)}
|
|
197
|
-
</span>
|
|
198
|
-
<span>Next run {formatNextRun(job.nextRunAt, job.state)}</span>
|
|
199
|
-
<span>Updated {formatDateTime(job.updatedAt)}</span>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
<button
|
|
203
|
-
type="button"
|
|
204
|
-
onClick={onClose}
|
|
205
|
-
className="rounded-lg border border-[var(--border)] p-2 text-[var(--muted-foreground)] transition-colors hover:border-[var(--card-hover-border)] hover:text-[var(--foreground)]"
|
|
206
|
-
aria-label="Close scheduled task details"
|
|
207
|
-
>
|
|
208
|
-
<X className="h-4 w-4" />
|
|
209
|
-
</button>
|
|
210
|
-
</div>
|
|
211
|
-
|
|
212
|
-
{/* Scrollable editor area */}
|
|
213
|
-
<div className="min-h-0 flex-1 overflow-y-auto px-6 py-6 space-y-5">
|
|
214
|
-
<div>
|
|
215
|
-
<p className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-[var(--muted-foreground)]">
|
|
216
|
-
Instructions
|
|
217
|
-
</p>
|
|
218
|
-
<div className="rounded-2xl border border-[var(--card-hover-border)] bg-[var(--overlay-panel-muted)] px-1 py-1 text-sm leading-6 text-[var(--foreground)]">
|
|
219
|
-
<RichTextEditor
|
|
220
|
-
content={promptDraft}
|
|
221
|
-
editable
|
|
222
|
-
onChange={setPromptDraft}
|
|
223
|
-
placeholder="Write instructions in markdown…"
|
|
224
|
-
/>
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
|
|
229
|
-
{/* Sticky footer */}
|
|
230
|
-
<div className="flex shrink-0 items-center justify-end gap-3 border-t border-[var(--border)] px-6 py-4">
|
|
231
|
-
<button
|
|
232
|
-
type="button"
|
|
233
|
-
onClick={onClose}
|
|
234
|
-
className="rounded-xl border border-[var(--border)] px-4 py-2.5 text-sm text-[var(--foreground)] transition-colors hover:border-[var(--card-hover-border)]"
|
|
235
|
-
>
|
|
236
|
-
Cancel
|
|
237
|
-
</button>
|
|
238
|
-
<button
|
|
239
|
-
type="button"
|
|
240
|
-
onClick={() => void savePrompt()}
|
|
241
|
-
disabled={saving}
|
|
242
|
-
className="rounded-xl border border-emerald-500/30 bg-emerald-500/10 px-4 py-2.5 text-sm text-emerald-400 transition-colors hover:bg-emerald-500/20 disabled:opacity-50"
|
|
243
|
-
>
|
|
244
|
-
{saving ? "Saving..." : "Save"}
|
|
245
|
-
</button>
|
|
246
|
-
</div>
|
|
247
|
-
</div>
|
|
248
|
-
</div>
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
67
|
function formatState(state: PromptJob["state"]): string {
|
|
253
68
|
if (state === "active") return "Active";
|
|
254
69
|
if (state === "paused") return "Paused";
|
|
@@ -280,10 +95,21 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
280
95
|
const [showCreate, setShowCreate] = useState(false);
|
|
281
96
|
const [busyId, setBusyId] = useState<string | null>(null);
|
|
282
97
|
const [error, setError] = useState<string | null>(null);
|
|
283
|
-
const [
|
|
98
|
+
const [editingJobId, setEditingJobId] = useState<string | null>(null);
|
|
284
99
|
const [deleteTarget, setDeleteTarget] = useState<PromptJob | null>(null);
|
|
285
|
-
const [scheduleEditJobId, setScheduleEditJobId] = useState<string | null>(null);
|
|
286
100
|
const [recentRuns, setRecentRuns] = useState<(PromptRun & { jobName: string })[]>([]);
|
|
101
|
+
const [agentMap, setAgentMap] = useState<Record<string, AgentOption>>({});
|
|
102
|
+
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
fetch("/api/prompt-jobs/agents")
|
|
105
|
+
.then((r) => r.json())
|
|
106
|
+
.then((d) => {
|
|
107
|
+
const map: Record<string, AgentOption> = {};
|
|
108
|
+
for (const a of (d.agents ?? []) as AgentOption[]) map[a.id] = a;
|
|
109
|
+
setAgentMap(map);
|
|
110
|
+
})
|
|
111
|
+
.catch((err) => console.warn("[ObjectiveScheduledTasksPanel] fetch agents failed:", err));
|
|
112
|
+
}, []);
|
|
287
113
|
|
|
288
114
|
const visibleJobs = useMemo(() => {
|
|
289
115
|
const filtered = jobs.filter((job) => job.objectiveId === objectiveId);
|
|
@@ -294,9 +120,10 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
294
120
|
return aPin - bPin;
|
|
295
121
|
});
|
|
296
122
|
}, [jobs, objectiveId]);
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
123
|
+
|
|
124
|
+
const editingJob = useMemo(
|
|
125
|
+
() => visibleJobs.find((job) => job.id === editingJobId) ?? null,
|
|
126
|
+
[editingJobId, visibleJobs]
|
|
300
127
|
);
|
|
301
128
|
|
|
302
129
|
const loadRecentRuns = useCallback(async () => {
|
|
@@ -334,9 +161,6 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
334
161
|
setError(result.error ?? `Failed to hide "${job.name}".`);
|
|
335
162
|
return;
|
|
336
163
|
}
|
|
337
|
-
if (selectedJobId === job.id) {
|
|
338
|
-
setSelectedJobId(null);
|
|
339
|
-
}
|
|
340
164
|
await refresh();
|
|
341
165
|
};
|
|
342
166
|
|
|
@@ -349,16 +173,10 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
349
173
|
return ok;
|
|
350
174
|
};
|
|
351
175
|
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
const handleJobUpdate = useCallback(
|
|
358
|
-
async (jobId: string, updates: Partial<PromptJob>) => {
|
|
359
|
-
const ok = await updateJob(jobId, updates);
|
|
176
|
+
const handleEditSubmit = useCallback(
|
|
177
|
+
async (jobId: string, data: CreateJobData) => {
|
|
178
|
+
const ok = await updateJob(jobId, data as Partial<PromptJob>);
|
|
360
179
|
if (ok) {
|
|
361
|
-
setSelectedJobId(jobId);
|
|
362
180
|
await refresh();
|
|
363
181
|
}
|
|
364
182
|
return ok;
|
|
@@ -369,28 +187,32 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
369
187
|
return (
|
|
370
188
|
<>
|
|
371
189
|
{showCreate ? (
|
|
372
|
-
<
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
onClose={() => setSelectedJobId(null)}
|
|
385
|
-
onUpdate={(updates) => handleJobUpdate(selectedJob.id, updates)}
|
|
386
|
-
/>
|
|
190
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4 py-6">
|
|
191
|
+
<div className="w-full max-w-5xl h-[85vh] overflow-hidden rounded-[28px] border border-[var(--border)] bg-[var(--card-bg)] shadow-2xl">
|
|
192
|
+
<CreateJobModal
|
|
193
|
+
onClose={() => setShowCreate(false)}
|
|
194
|
+
onSubmit={async (data) => {
|
|
195
|
+
await handleCreate(data);
|
|
196
|
+
}}
|
|
197
|
+
createDefaults={createDefaults}
|
|
198
|
+
contextLabel={objectiveKey}
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
387
202
|
) : null}
|
|
388
|
-
{
|
|
389
|
-
<
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
203
|
+
{editingJob ? (
|
|
204
|
+
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4 py-6">
|
|
205
|
+
<div className="w-full max-w-5xl h-[85vh] overflow-hidden rounded-[28px] border border-[var(--border)] bg-[var(--card-bg)] shadow-2xl">
|
|
206
|
+
<CreateJobModal
|
|
207
|
+
onClose={() => setEditingJobId(null)}
|
|
208
|
+
onSubmit={async (data) => {
|
|
209
|
+
await handleEditSubmit(editingJob.id, data);
|
|
210
|
+
}}
|
|
211
|
+
editingJob={editingJob}
|
|
212
|
+
contextLabel={objectiveKey}
|
|
213
|
+
/>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
394
216
|
) : null}
|
|
395
217
|
|
|
396
218
|
<div className="px-1">
|
|
@@ -431,11 +253,11 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
431
253
|
visibleJobs.map((job) => (
|
|
432
254
|
<div
|
|
433
255
|
key={job.id}
|
|
434
|
-
onClick={() =>
|
|
256
|
+
onClick={() => setEditingJobId(job.id)}
|
|
435
257
|
onKeyDown={(event) => {
|
|
436
258
|
if (event.key === "Enter" || event.key === " ") {
|
|
437
259
|
event.preventDefault();
|
|
438
|
-
|
|
260
|
+
setEditingJobId(job.id);
|
|
439
261
|
}
|
|
440
262
|
}}
|
|
441
263
|
role="button"
|
|
@@ -488,9 +310,27 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
488
310
|
</span>
|
|
489
311
|
) : null}
|
|
490
312
|
</div>
|
|
491
|
-
<
|
|
492
|
-
{
|
|
493
|
-
|
|
313
|
+
<div className="mt-3 flex items-center gap-2 min-w-0 text-xs text-[var(--muted-foreground)]">
|
|
314
|
+
{job.agentId && agentMap[job.agentId] ? (
|
|
315
|
+
<img
|
|
316
|
+
src={agentAvatar(job.agentId, agentMap[job.agentId].color, 20)}
|
|
317
|
+
alt=""
|
|
318
|
+
className="size-5 rounded-full shrink-0"
|
|
319
|
+
/>
|
|
320
|
+
) : (
|
|
321
|
+
<Terminal className="h-3.5 w-3.5 shrink-0" />
|
|
322
|
+
)}
|
|
323
|
+
<span className="truncate font-medium text-[var(--foreground)]">
|
|
324
|
+
{job.agentId && agentMap[job.agentId]
|
|
325
|
+
? agentMap[job.agentId].name
|
|
326
|
+
: job.provider}
|
|
327
|
+
</span>
|
|
328
|
+
{job.model ? (
|
|
329
|
+
<span className="truncate font-mono text-[11px]">
|
|
330
|
+
{job.model}
|
|
331
|
+
</span>
|
|
332
|
+
) : null}
|
|
333
|
+
</div>
|
|
494
334
|
{job.condition ? (
|
|
495
335
|
<p className="mt-2 text-xs text-[var(--muted-foreground)]">
|
|
496
336
|
Condition: {job.condition}
|
|
@@ -504,7 +344,6 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
504
344
|
title="Run now"
|
|
505
345
|
onClick={async (event) => {
|
|
506
346
|
event.stopPropagation();
|
|
507
|
-
setSelectedJobId(job.id);
|
|
508
347
|
setBusyId(job.id);
|
|
509
348
|
await runNow(job.id);
|
|
510
349
|
setBusyId(null);
|
|
@@ -518,14 +357,14 @@ export function ObjectiveScheduledTasksPanel({
|
|
|
518
357
|
</button>
|
|
519
358
|
<button
|
|
520
359
|
type="button"
|
|
521
|
-
title="Edit
|
|
360
|
+
title="Edit"
|
|
522
361
|
onClick={(event) => {
|
|
523
362
|
event.stopPropagation();
|
|
524
|
-
|
|
363
|
+
setEditingJobId(job.id);
|
|
525
364
|
}}
|
|
526
365
|
className="rounded-lg border border-[var(--border)] p-2 text-[var(--muted-foreground)] transition-colors hover:border-sky-400/40 hover:text-sky-300"
|
|
527
366
|
>
|
|
528
|
-
<
|
|
367
|
+
<Pencil className="h-3.5 w-3.5" />
|
|
529
368
|
</button>
|
|
530
369
|
<button
|
|
531
370
|
type="button"
|
|
@@ -981,11 +981,11 @@ export function WorkspaceSidebar({
|
|
|
981
981
|
</div>
|
|
982
982
|
</div>
|
|
983
983
|
|
|
984
|
-
{/*
|
|
984
|
+
{/* Automation group — visible from stage 2+ */}
|
|
985
985
|
{showWorkGroup && (
|
|
986
986
|
<div className="mb-3">
|
|
987
987
|
<div className="workspace-sidebar__section-header">
|
|
988
|
-
<p className="workspace-sidebar__section-label">
|
|
988
|
+
<p className="workspace-sidebar__section-label">Automation</p>
|
|
989
989
|
</div>
|
|
990
990
|
<div className="px-2 flex flex-col gap-0.5">
|
|
991
991
|
{stageShow.objectives && (
|