add temporal service to builds. (#2842)
This commit is contained in:
@@ -7,3 +7,4 @@ src/bin/goose-npm/
|
||||
/src/bin/*.cmd
|
||||
/playwright-report/
|
||||
/test-results/
|
||||
/src/bin/temporal-service
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"license": {
|
||||
"name": "Apache-2.0"
|
||||
},
|
||||
"version": "1.0.24"
|
||||
"version": "1.0.26"
|
||||
},
|
||||
"paths": {
|
||||
"/agent/tools": {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22.6666" cy="21.3333" r="21.3333" fill="#101010"/>
|
||||
<path d="M15.9289 14.9289C19.8342 11.0237 26.1663 11.0237 30.0715 14.9289C33.9768 18.8342 33.9768 25.1663 30.0715 29.0715C26.1663 32.9768 19.8342 32.9768 15.9289 29.0715C12.0237 25.1663 12.0237 18.8342 15.9289 14.9289ZM28.6574 16.343C25.5333 13.2188 20.4672 13.2188 17.343 16.343C14.2188 19.4672 14.2188 24.5333 17.343 27.6574C20.4672 30.7816 25.5333 30.7816 28.6574 27.6574C31.7816 24.5333 31.7816 19.4672 28.6574 16.343ZM24.0002 22.0002H26.5002V24.0002H23.0002C22.4479 24.0002 22.0002 23.5525 22.0002 23.0002V18.5002H24.0002V22.0002Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 718 B |
@@ -336,7 +336,7 @@ export default function RecipeEditor({ config }: RecipeEditorProps) {
|
||||
<button
|
||||
onClick={() => setIsScheduleModalOpen(true)}
|
||||
disabled={!requiredFieldsAreFilled()}
|
||||
className="w-full p-3 bg-green-500 text-white rounded-lg hover:bg-green-600 disabled:opacity-50 disabled:hover:bg-green-500"
|
||||
className="w-full h-[60px] rounded-none border-t text-gray-900 dark:text-white hover:bg-gray-50 dark:border-gray-600 text-lg font-medium"
|
||||
>
|
||||
Create Schedule from Recipe
|
||||
</button>
|
||||
|
||||
@@ -7,6 +7,7 @@ import cronstrue from 'cronstrue';
|
||||
import * as yaml from 'yaml';
|
||||
import { Buffer } from 'buffer';
|
||||
import { Recipe } from '../../recipe';
|
||||
import ClockIcon from '../../assets/clock-icon.svg';
|
||||
|
||||
type FrequencyValue = 'once' | 'hourly' | 'daily' | 'weekly' | 'monthly';
|
||||
|
||||
@@ -499,17 +500,24 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/20 backdrop-blur-sm z-40 flex items-center justify-center p-4">
|
||||
<Card className="w-full max-w-md bg-bgApp shadow-xl rounded-lg z-50 flex flex-col max-h-[90vh] overflow-hidden">
|
||||
<div className="px-6 pt-6 pb-4 flex-shrink-0">
|
||||
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
|
||||
Create New Schedule
|
||||
</h2>
|
||||
<Card className="w-full max-w-md bg-bgApp shadow-xl rounded-3xl z-50 flex flex-col max-h-[90vh] overflow-hidden">
|
||||
<div className="px-8 pt-8 pb-4 flex-shrink-0 text-center">
|
||||
<div className="flex flex-col items-center">
|
||||
<img src={ClockIcon} alt="Clock" className="w-11 h-11 mb-2" />
|
||||
<h2 className="text-base font-semibold text-gray-900 dark:text-white">
|
||||
Create New Schedule
|
||||
</h2>
|
||||
<p className="text-base text-gray-500 dark:text-gray-400 mt-2 max-w-sm">
|
||||
Create a new schedule using the settings below to do things like automatically run
|
||||
tasks or create files
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="new-schedule-form"
|
||||
onSubmit={handleLocalSubmit}
|
||||
className="px-6 py-4 space-y-4 flex-grow overflow-y-auto"
|
||||
className="px-8 py-4 space-y-4 flex-grow overflow-y-auto"
|
||||
>
|
||||
{apiErrorExternally && (
|
||||
<p className="text-red-500 text-sm mb-3 p-2 bg-red-100 dark:bg-red-900/30 rounded-md border border-red-500/50">
|
||||
@@ -524,7 +532,7 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
|
||||
<div>
|
||||
<label htmlFor="scheduleId-modal" className={modalLabelClassName}>
|
||||
Schedule ID:
|
||||
Name:
|
||||
</label>
|
||||
<Input
|
||||
type="text"
|
||||
@@ -537,30 +545,30 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className={modalLabelClassName}>Recipe Source:</label>
|
||||
<label className={modalLabelClassName}>Source:</label>
|
||||
<div className="space-y-2">
|
||||
<div className="flex gap-2">
|
||||
<div className="flex bg-gray-100 dark:bg-gray-700 rounded-full p-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSourceType('file')}
|
||||
className={`px-3 py-2 text-sm rounded-md border ${
|
||||
className={`flex-1 px-4 py-2 text-sm font-medium rounded-full transition-all ${
|
||||
sourceType === 'file'
|
||||
? 'bg-blue-500 text-white border-blue-500'
|
||||
: 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600'
|
||||
? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-white shadow-sm'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white'
|
||||
}`}
|
||||
>
|
||||
YAML File
|
||||
YAML
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSourceType('deeplink')}
|
||||
className={`px-3 py-2 text-sm rounded-md border ${
|
||||
className={`flex-1 px-4 py-2 text-sm font-medium rounded-full transition-all ${
|
||||
sourceType === 'deeplink'
|
||||
? 'bg-blue-500 text-white border-blue-500'
|
||||
: 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600'
|
||||
? 'bg-white dark:bg-gray-800 text-gray-900 dark:text-white shadow-sm'
|
||||
: 'text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white'
|
||||
}`}
|
||||
>
|
||||
Deep Link
|
||||
Deep link
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -570,7 +578,7 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={handleBrowseFile}
|
||||
className="w-full justify-center"
|
||||
className="w-full justify-center rounded-full"
|
||||
>
|
||||
Browse for YAML file...
|
||||
</Button>
|
||||
@@ -589,6 +597,7 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
value={deepLinkInput}
|
||||
onChange={(e) => handleDeepLinkChange(e.target.value)}
|
||||
placeholder="Paste goose://bot or goose://recipe link here..."
|
||||
className="rounded-full"
|
||||
/>
|
||||
{parsedRecipe && (
|
||||
<div className="mt-2 p-2 bg-green-100 dark:bg-green-900/30 rounded-md border border-green-500/50">
|
||||
@@ -739,6 +748,15 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
|
||||
{/* Actions */}
|
||||
<div className="mt-[8px] ml-[-24px] mr-[-24px] pt-[16px]">
|
||||
<Button
|
||||
type="submit"
|
||||
form="new-schedule-form"
|
||||
variant="ghost"
|
||||
disabled={isLoadingExternally}
|
||||
className="w-full h-[60px] rounded-none border-t text-gray-900 dark:text-white hover:bg-gray-50 dark:border-gray-600 text-lg font-medium"
|
||||
>
|
||||
{isLoadingExternally ? 'Creating...' : 'Create Schedule'}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
@@ -748,15 +766,6 @@ export const CreateScheduleModal: React.FC<CreateScheduleModalProps> = ({
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
form="new-schedule-form"
|
||||
variant="default"
|
||||
disabled={isLoadingExternally}
|
||||
className="w-full h-[60px] rounded-none border-t dark:border-gray-600 text-lg dark:text-white dark:border-gray-600 font-regular"
|
||||
>
|
||||
{isLoadingExternally ? 'Creating...' : 'Create Schedule'}
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@@ -86,12 +86,8 @@ export const ScheduleFromRecipeModal: React.FC<ScheduleFromRecipeModalProps> = (
|
||||
Recipe Details:
|
||||
</h3>
|
||||
<div className="bg-gray-50 dark:bg-gray-800 p-3 rounded-md">
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">
|
||||
{recipe.title}
|
||||
</p>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-400 mt-1">
|
||||
{recipe.description}
|
||||
</p>
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-white">{recipe.title}</p>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-400 mt-1">{recipe.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,22 +96,13 @@ export const ScheduleFromRecipeModal: React.FC<ScheduleFromRecipeModalProps> = (
|
||||
Recipe Deep Link:
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
<Input
|
||||
type="text"
|
||||
value={deepLink}
|
||||
readOnly
|
||||
className="flex-1 text-xs font-mono"
|
||||
/>
|
||||
<Input type="text" value={deepLink} readOnly className="flex-1 text-xs font-mono" />
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleCopy}
|
||||
className="ml-2 px-3 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 flex items-center"
|
||||
>
|
||||
{copied ? (
|
||||
<Check className="w-4 h-4" />
|
||||
) : (
|
||||
<Copy className="w-4 h-4" />
|
||||
)}
|
||||
{copied ? <Check className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
@@ -129,14 +116,14 @@ export const ScheduleFromRecipeModal: React.FC<ScheduleFromRecipeModalProps> = (
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={handleClose}
|
||||
className="flex-1"
|
||||
className="flex-1 rounded-xl hover:bg-bgSubtle text-textSubtle"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleCreateSchedule}
|
||||
className="flex-1 bg-green-500 hover:bg-green-600 text-white"
|
||||
className="flex-1 bg-bgAppInverse text-sm text-textProminentInverse rounded-xl hover:bg-bgStandardInverse transition-colors"
|
||||
>
|
||||
Create Schedule
|
||||
</Button>
|
||||
|
||||
@@ -16,11 +16,12 @@ import MoreMenuLayout from '../more_menu/MoreMenuLayout';
|
||||
import { Card } from '../ui/card';
|
||||
import { Button } from '../ui/button';
|
||||
import { TrashIcon } from '../icons/TrashIcon';
|
||||
import { Plus, RefreshCw, Pause, Play, Edit, Square, Eye } from 'lucide-react';
|
||||
import { Plus, RefreshCw, Pause, Play, Edit, Square, Eye, MoreHorizontal } from 'lucide-react';
|
||||
import { CreateScheduleModal, NewSchedulePayload } from './CreateScheduleModal';
|
||||
import { EditScheduleModal } from './EditScheduleModal';
|
||||
import ScheduleDetailView from './ScheduleDetailView';
|
||||
import { toastError, toastSuccess } from '../../toasts';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
|
||||
import cronstrue from 'cronstrue';
|
||||
|
||||
interface SchedulesViewProps {
|
||||
@@ -67,7 +68,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose }) => {
|
||||
useEffect(() => {
|
||||
if (viewingScheduleId === null) {
|
||||
fetchSchedules();
|
||||
|
||||
|
||||
// Check for pending deep link from recipe editor
|
||||
const pendingDeepLink = localStorage.getItem('pendingScheduleDeepLink');
|
||||
if (pendingDeepLink) {
|
||||
@@ -382,7 +383,7 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose }) => {
|
||||
onClick={handleRefresh}
|
||||
disabled={isRefreshing || isLoading}
|
||||
variant="outline"
|
||||
className="w-full md:w-auto flex items-center gap-2 justify-center"
|
||||
className="w-full md:w-auto flex items-center gap-2 justify-center rounded-full [&>svg]:!size-4"
|
||||
>
|
||||
<RefreshCw className={`h-4 w-4 ${isRefreshing ? 'animate-spin' : ''}`} />
|
||||
{isRefreshing ? 'Refreshing...' : 'Refresh'}
|
||||
@@ -453,111 +454,118 @@ const SchedulesView: React.FC<SchedulesViewProps> = ({ onClose }) => {
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-shrink-0 flex items-center gap-1">
|
||||
{!job.currently_running && (
|
||||
<>
|
||||
<div className="flex-shrink-0">
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOpenEditModal(job);
|
||||
}}
|
||||
className="text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-blue-100/50 dark:hover:bg-blue-900/30"
|
||||
title={`Edit schedule ${job.id}`}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) ||
|
||||
deletingScheduleIds.has(job.id) ||
|
||||
isSubmitting
|
||||
}
|
||||
className="text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:bg-gray-100/50 dark:hover:bg-gray-800/50"
|
||||
>
|
||||
<Edit className="w-4 h-4" />
|
||||
<MoreHorizontal className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (job.paused) {
|
||||
handleUnpauseSchedule(job.id);
|
||||
} else {
|
||||
handlePauseSchedule(job.id);
|
||||
}
|
||||
}}
|
||||
className={`${
|
||||
job.paused
|
||||
? 'text-green-500 dark:text-green-400 hover:text-green-600 dark:hover:text-green-300 hover:bg-green-100/50 dark:hover:bg-green-900/30'
|
||||
: 'text-orange-500 dark:text-orange-400 hover:text-orange-600 dark:hover:text-orange-300 hover:bg-orange-100/50 dark:hover:bg-orange-900/30'
|
||||
}`}
|
||||
title={
|
||||
job.paused
|
||||
? `Unpause schedule ${job.id}`
|
||||
: `Pause schedule ${job.id}`
|
||||
}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) || deletingScheduleIds.has(job.id)
|
||||
}
|
||||
>
|
||||
{job.paused ? (
|
||||
<Play className="w-4 h-4" />
|
||||
) : (
|
||||
<Pause className="w-4 h-4" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="w-48 p-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 shadow-lg"
|
||||
align="end"
|
||||
>
|
||||
<div className="space-y-1">
|
||||
{!job.currently_running && (
|
||||
<>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleOpenEditModal(job);
|
||||
}}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) ||
|
||||
deletingScheduleIds.has(job.id) ||
|
||||
isSubmitting
|
||||
}
|
||||
className="w-full flex items-center justify-between px-3 py-2 text-sm text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span>Edit</span>
|
||||
<Edit className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (job.paused) {
|
||||
handleUnpauseSchedule(job.id);
|
||||
} else {
|
||||
handlePauseSchedule(job.id);
|
||||
}
|
||||
}}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) ||
|
||||
deletingScheduleIds.has(job.id)
|
||||
}
|
||||
className="w-full flex items-center justify-between px-3 py-2 text-sm text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span>{job.paused ? 'Resume schedule' : 'Stop schedule'}</span>
|
||||
{job.paused ? (
|
||||
<Play className="w-4 h-4" />
|
||||
) : (
|
||||
<Pause className="w-4 h-4" />
|
||||
)}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{job.currently_running && (
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleInspectRunningJob(job.id);
|
||||
}}
|
||||
className="text-blue-500 dark:text-blue-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-blue-100/50 dark:hover:bg-blue-900/30"
|
||||
title={`Inspect running job ${job.id}`}
|
||||
disabled={
|
||||
inspectingScheduleIds.has(job.id) || killingScheduleIds.has(job.id)
|
||||
}
|
||||
>
|
||||
<Eye className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleKillRunningJob(job.id);
|
||||
}}
|
||||
className="text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300 hover:bg-red-100/50 dark:hover:bg-red-900/30"
|
||||
title={`Kill running job ${job.id}`}
|
||||
disabled={
|
||||
killingScheduleIds.has(job.id) || inspectingScheduleIds.has(job.id)
|
||||
}
|
||||
>
|
||||
<Square className="w-4 h-4" />
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteSchedule(job.id);
|
||||
}}
|
||||
className="text-gray-500 dark:text-gray-400 hover:text-red-500 dark:hover:text-red-400 hover:bg-red-100/50 dark:hover:bg-red-900/30"
|
||||
title={`Delete schedule ${job.id}`}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) ||
|
||||
deletingScheduleIds.has(job.id) ||
|
||||
killingScheduleIds.has(job.id) ||
|
||||
inspectingScheduleIds.has(job.id)
|
||||
}
|
||||
>
|
||||
<TrashIcon className="w-5 h-5" />
|
||||
</Button>
|
||||
{job.currently_running && (
|
||||
<>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleInspectRunningJob(job.id);
|
||||
}}
|
||||
disabled={
|
||||
inspectingScheduleIds.has(job.id) ||
|
||||
killingScheduleIds.has(job.id)
|
||||
}
|
||||
className="w-full flex items-center justify-between px-3 py-2 text-sm text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span>Inspect</span>
|
||||
<Eye className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleKillRunningJob(job.id);
|
||||
}}
|
||||
disabled={
|
||||
killingScheduleIds.has(job.id) ||
|
||||
inspectingScheduleIds.has(job.id)
|
||||
}
|
||||
className="w-full flex items-center justify-between px-3 py-2 text-sm text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span>Kill job</span>
|
||||
<Square className="w-4 h-4" />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<hr className="border-gray-200 dark:border-gray-600 my-1" />
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteSchedule(job.id);
|
||||
}}
|
||||
disabled={
|
||||
pausingScheduleIds.has(job.id) ||
|
||||
deletingScheduleIds.has(job.id) ||
|
||||
killingScheduleIds.has(job.id) ||
|
||||
inspectingScheduleIds.has(job.id)
|
||||
}
|
||||
className="w-full flex items-center justify-between px-3 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<span>Delete</span>
|
||||
<TrashIcon className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user