From f83095f00102016808a7ffd4131471926ea9ad5f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:27:11 -0500 Subject: [PATCH 1/8] ENG-36 Support Intel build for mac, not just Apple Silicon (#1710) * fix(portal): download relevant device agent per macOS chip on portal * fix(portal): fix portal build issue * fix(portal): add log for testing * fix(portal): add log for testing --------- Co-authored-by: chasprowebdev --- .../src/app/api/download-agent/route.ts | 10 +++++---- .../src/app/api/download-agent/types.ts | 2 +- .../src/app/api/download-agent/utils.ts | 21 ++++++++++++++++--- apps/portal/src/utils/s3.ts | 3 ++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/apps/portal/src/app/api/download-agent/route.ts b/apps/portal/src/app/api/download-agent/route.ts index 8c577eccc..0e0584739 100644 --- a/apps/portal/src/app/api/download-agent/route.ts +++ b/apps/portal/src/app/api/download-agent/route.ts @@ -11,6 +11,7 @@ import { getReadmeContent, getScriptFilename, } from './scripts'; +import type { SupportedOS } from './types'; export const runtime = 'nodejs'; export const dynamic = 'force-dynamic'; @@ -39,9 +40,10 @@ export async function GET(req: NextRequest) { orgId: string; employeeId: string; userId: string; - os: 'macos' | 'windows'; + os: SupportedOS; }; - + console.log(os); + // Hardcoded device marker paths used by the setup scripts const fleetDevicePathMac = '/Users/Shared/.fleet'; const fleetDevicePathWindows = 'C:\\ProgramData\\CompAI\\Fleet'; @@ -52,10 +54,10 @@ export async function GET(req: NextRequest) { } // For macOS, serve the DMG directly. For Windows, create a zip with script and installer. - if (os === 'macos') { + if (os === 'macos' || os === 'macos-intel') { try { // Direct DMG download for macOS - const macosPackageFilename = 'Comp AI Agent-1.0.0-arm64.dmg'; + const macosPackageFilename = os === 'macos' ? 'Comp AI Agent-1.0.0-arm64.dmg' : 'Comp AI Agent-1.0.0.dmg'; const packageKey = `macos/${macosPackageFilename}`; const getObjectCommand = new GetObjectCommand({ diff --git a/apps/portal/src/app/api/download-agent/types.ts b/apps/portal/src/app/api/download-agent/types.ts index c7801acc8..04b7c8a55 100644 --- a/apps/portal/src/app/api/download-agent/types.ts +++ b/apps/portal/src/app/api/download-agent/types.ts @@ -1,4 +1,4 @@ -export type SupportedOS = 'macos' | 'windows'; +export type SupportedOS = 'macos' | 'windows' | 'macos-intel'; export interface ScriptConfig { orgId: string; diff --git a/apps/portal/src/app/api/download-agent/utils.ts b/apps/portal/src/app/api/download-agent/utils.ts index bc14f8c5a..5b7841286 100644 --- a/apps/portal/src/app/api/download-agent/utils.ts +++ b/apps/portal/src/app/api/download-agent/utils.ts @@ -3,11 +3,17 @@ import { db } from '@db'; import type { SupportedOS } from './types'; /** - * Detects the operating system from a User-Agent string + * Detects the operating system (and for macOS, the CPU architecture) from a User-Agent string. + * + * Returns: + * - 'windows' for Windows OS + * - 'macos' for Apple Silicon (ARM-based) Macs + * - 'macos-intel' for Intel-based Macs * * Examples of User-Agent strings: * - Windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" - * - macOS: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" + * - macOS (Intel): "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" + * - macOS (Apple Silicon): "Mozilla/5.0 (Macintosh; ARM Mac OS X 11_2_3) AppleWebKit/537.36" */ export function detectOSFromUserAgent(userAgent: string | null): SupportedOS | null { if (!userAgent) return null; @@ -19,8 +25,17 @@ export function detectOSFromUserAgent(userAgent: string | null): SupportedOS | n return 'windows'; } - // Check for macOS (must check before iOS since iOS UA contains "mac") + // Check for macOS (and further distinguish Apple Silicon vs Intel) if (ua.includes('macintosh') || (ua.includes('mac os') && !ua.includes('like mac'))) { + // User-Agent containing 'arm' or 'apple' usually means Apple Silicon + if (ua.includes('arm') || ua.includes('apple')) { + return 'macos'; + } + // 'intel' in UA indicates Intel-based mac + if (ua.includes('intel')) { + return 'macos-intel'; + } + // Fallback for when arch info is missing, treat as Apple Silicon (modern default) return 'macos'; } diff --git a/apps/portal/src/utils/s3.ts b/apps/portal/src/utils/s3.ts index b31a4e0ba..85ba857d2 100644 --- a/apps/portal/src/utils/s3.ts +++ b/apps/portal/src/utils/s3.ts @@ -1,3 +1,4 @@ +import { SupportedOS } from '@/app/api/download-agent/types'; import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'; import { getSignedUrl } from '@aws-sdk/s3-request-presigner'; @@ -113,7 +114,7 @@ export function extractS3KeyFromUrl(url: string): string { return key; } -export async function getFleetAgent({ os }: { os: 'macos' | 'windows' }) { +export async function getFleetAgent({ os }: { os: SupportedOS }) { const fleetBucketName = process.env.FLEET_AGENT_BUCKET_NAME; if (!fleetBucketName) { From b604b18a5c16db2f9b58be64f2262d70fca66d34 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:04:22 -0500 Subject: [PATCH 2/8] fix(portal): remove Ubuntu support help (#1715) Co-authored-by: chasprowebdev --- .../[orgId]/components/tasks/DeviceAgentAccordionItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/portal/src/app/(app)/(home)/[orgId]/components/tasks/DeviceAgentAccordionItem.tsx b/apps/portal/src/app/(app)/(home)/[orgId]/components/tasks/DeviceAgentAccordionItem.tsx index b28a83abf..afe8c100c 100644 --- a/apps/portal/src/app/(app)/(home)/[orgId]/components/tasks/DeviceAgentAccordionItem.tsx +++ b/apps/portal/src/app/(app)/(home)/[orgId]/components/tasks/DeviceAgentAccordionItem.tsx @@ -248,7 +248,7 @@ export function DeviceAgentAccordionItem({

- Operating Systems: macOS 10.14+, Windows 10+, Ubuntu 18.04+ + Operating Systems: macOS 10.14+, Windows 10+

Memory: 512MB RAM minimum From d1288bbf52dd8f0cfc9bd20471ba651a764822fd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:10:10 -0500 Subject: [PATCH 3/8] [dev] [Marfuen] mariano/tasks-stuff (#1713) * fix: auto enable automation when publishing * fix: show success criteria on first render * fix(TestResultsPanel): use actual evaluation criteria for rendering * fix(TestResultsPanel): use shared chat context for automation ID * feat(automation): add file writing activity component and version handling * feat(automation): enhance publish dialog with post-publish options and version testing * fix(automation): update SWR type for automation runs data --------- Co-authored-by: Mariano Fuentes --- apps/app/package.json | 9 +- .../actions/task-automation-actions.ts | 7 + .../components/PublishDialog.tsx | 137 +++++++++++++----- .../message-part/file-writing-activity.tsx | 80 ++++++++++ .../components/chat/message-part/index.tsx | 10 ++ .../components/chat/message.tsx | 60 ++++++++ .../evaluation/EvaluationCriteriaCard.tsx | 13 +- .../workflow/components/TestResultsPanel.tsx | 15 +- .../components/UnifiedWorkflowCard.tsx | 25 +++- .../workflow/workflow-visualizer-simple.tsx | 16 +- .../hooks/use-task-automation.ts | 20 ++- .../components/AutomationOverview.tsx | 126 ++++++++++++++-- .../overview/hooks/use-automation-runs.ts | 27 ++++ .../automations/[automationId]/runs/route.ts | 39 +++++ bun.lock | 20 +-- 15 files changed, 523 insertions(+), 81 deletions(-) create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/chat/message-part/file-writing-activity.tsx create mode 100644 apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automations/[automationId]/overview/hooks/use-automation-runs.ts create mode 100644 apps/app/src/app/api/automations/[automationId]/runs/route.ts diff --git a/apps/app/package.json b/apps/app/package.json index 5d795da36..a5389f0e1 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -49,8 +49,8 @@ "@tiptap/extension-table-cell": "^3.4.4", "@tiptap/extension-table-header": "^3.4.4", "@tiptap/extension-table-row": "^3.4.4", - "@trigger.dev/react-hooks": "4.0.0", - "@trigger.dev/sdk": "4.0.0", + "@trigger.dev/react-hooks": "4.0.6", + "@trigger.dev/sdk": "4.0.6", "@trycompai/db": "^1.3.7", "@trycompai/email": "workspace:*", "@types/canvas-confetti": "^1.9.0", @@ -117,7 +117,7 @@ "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", - "@trigger.dev/build": "4.0.0", + "@trigger.dev/build": "4.0.6", "@types/d3": "^7.4.3", "@types/jspdf": "^2.0.0", "@types/node": "^24.0.3", @@ -157,7 +157,7 @@ "db:getschema": "node ../../packages/db/scripts/combine-schemas.js && cp ../../packages/db/dist/schema.prisma prisma/schema.prisma", "db:migrate": "cd ../../packages/db && bunx prisma migrate dev && cd ../../apps/app", "deploy:trigger-prod": "npx trigger.dev@4.0.0 deploy", - "dev": "bun i && bunx concurrently --kill-others --names \"next,trigger\" --prefix-colors \"yellow,blue\" \"next dev --turbo -p 3000\" \"bun run trigger:dev\"", + "dev": "bun i && bunx concurrently --kill-others --names \"next,trigger\" --prefix-colors \"yellow,blue\" \"next dev --turbo -p 3000\" \"bunx trigger.dev@4.0.6 dev\"", "lint": "next lint && prettier --check .", "prebuild": "bun run db:generate", "start": "next start", @@ -173,7 +173,6 @@ "test:e2e:ui": "playwright test --ui", "test:ui": "vitest --ui", "test:watch": "vitest --watch", - "trigger:dev": "npx trigger.dev@4.0.0 dev", "typecheck": "tsc --noEmit" } } \ No newline at end of file diff --git a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts index 13a14f103..40100081b 100644 --- a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts +++ b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/actions/task-automation-actions.ts @@ -186,6 +186,7 @@ export async function executeAutomationScript(data: { orgId: string; taskId: string; automationId: string; + version?: number; // Optional: test specific version }) { try { const result = await callEnterpriseApi('/api/tasks-automations/trigger/execute', { @@ -361,6 +362,12 @@ export async function publishAutomation( }, }); + // Enable automation if not already enabled + await db.evidenceAutomation.update({ + where: { id: automationId }, + data: { isEnabled: true }, + }); + return { success: true, version, diff --git a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/PublishDialog.tsx b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/PublishDialog.tsx index 49d98adb1..bda713016 100644 --- a/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/PublishDialog.tsx +++ b/apps/app/src/app/(app)/[orgId]/tasks/[taskId]/automation/[automationId]/components/PublishDialog.tsx @@ -12,10 +12,10 @@ import { import { Label } from '@comp/ui/label'; import { Textarea } from '@comp/ui/textarea'; import { Loader2 } from 'lucide-react'; -import { useParams } from 'next/navigation'; +import { useParams, useRouter } from 'next/navigation'; import { useState } from 'react'; import { toast } from 'sonner'; -import { publishAutomation } from '../actions/task-automation-actions'; +import { executeAutomationScript, publishAutomation } from '../actions/task-automation-actions'; import { useAutomationVersions } from '../hooks/use-automation-versions'; import { useSharedChatContext } from '../lib/chat-context'; @@ -25,6 +25,7 @@ interface PublishDialogProps { } export function PublishDialog({ open, onOpenChange }: PublishDialogProps) { + const router = useRouter(); const { orgId, taskId } = useParams<{ orgId: string; taskId: string; @@ -33,8 +34,20 @@ export function PublishDialog({ open, onOpenChange }: PublishDialogProps) { const { automationIdRef } = useSharedChatContext(); const [changelog, setChangelog] = useState(''); const [isPublishing, setIsPublishing] = useState(false); + const [showPostPublishOptions, setShowPostPublishOptions] = useState(false); + const [publishedVersion, setPublishedVersion] = useState(null); const { mutate } = useAutomationVersions(); + const handleDialogChange = (newOpen: boolean) => { + onOpenChange(newOpen); + // Reset state when dialog closes + if (!newOpen) { + setChangelog(''); + setShowPostPublishOptions(false); + setPublishedVersion(null); + } + }; + const handlePublish = async () => { setIsPublishing(true); @@ -50,12 +63,31 @@ export function PublishDialog({ open, onOpenChange }: PublishDialogProps) { throw new Error(result.error || 'Failed to publish'); } - toast.success(`Version ${result.version?.version} published successfully!`); - setChangelog(''); - onOpenChange(false); + const versionNumber = result.version?.version; + toast.success(`Version ${versionNumber} published successfully!`); + setPublishedVersion(versionNumber || null); // Refresh versions list await mutate(); + + // Trigger a test run with the new version + if (versionNumber) { + const runResult = await executeAutomationScript({ + orgId, + taskId, + automationId: automationIdRef.current, + version: versionNumber, + }); + + if (runResult.success) { + toast.success('Running automation with published version'); + } else { + toast.error(runResult.error || 'Failed to start automation run'); + } + } + + // Show post-publish options instead of closing + setShowPostPublishOptions(true); } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to publish automation'); } finally { @@ -63,38 +95,73 @@ export function PublishDialog({ open, onOpenChange }: PublishDialogProps) { } }; + const handleGoToOverview = () => { + handleDialogChange(false); + router.push(`/${orgId}/tasks/${taskId}/automations/${automationIdRef.current}/overview`); + }; + + const handleStayHere = () => { + handleDialogChange(false); + }; + return ( -

+ - - Publish Automation - - Create a new version of this automation. The current draft will remain editable. - - - -
-
- -