Conversation
…and artifacts (#1015) The WorkflowResultCard showed a hardcoded green checkmark regardless of actual outcome, with no duration, node count, or artifact links. Changes: - Fetch terminal run data via TanStack Query (staleTime: Infinity) - Merge Zustand live state with API fallback for offline/CLI workflows - Render StatusIcon for completed/failed/cancelled status awareness - Display node count and duration pill in the header - Show ArtifactSummary (PRs, commits, branches, files) above text content - Derive node counts and artifacts from events when live state unavailable Fixes #1015 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…#1014) Loop nodes in DAG workflows appeared as flat nodes with no iteration visibility. The backend already emitted loop_iteration_* events but the frontend dropped them. Changes: - Add nodeId to workflow_step SSE events in workflow-bridge - Add LoopIterationEvent/LoopIterationInfo types and extend DagNodeState - Handle workflow_step events in useSSE and route to store - Add handleLoopIteration action to workflow store - Extract loop_iteration_* events for historical REST view - Add expandable iteration sub-list in DagNodeProgress sidebar - Add iteration count badge on graph nodes (ExecutionDagNode) - Add loop type color/label to graph node type maps Fixes #1014 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…omments and docs - Fix MEDIUM: totalCount in dagNodes live-state path now counts only terminal nodes (completed/failed/skipped), matching the semantics of the events fallback path. Previously included pending/running nodes, producing a misleading denominator during page-refresh mid-execution. - Fix LOW: Duration badge background changed from bg-surface-elevated to bg-surface for visual contrast against the bg-surface-elevated parent header. - Fix LOW: Expanded staleTime: Infinity comment to explain the immutability invariant. - Fix LOW: Expanded node count comment to describe that the events-path totalCount is an approximation (nodes that reached terminal state, not workflow's full node count). - Fix LOW: Added Workflow Result Card subsection to web adapter docs describing the post-completion card's status icon, header, node count, duration, and artifacts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simplify verbose onClick handlers in WorkflowResultCard — remove unnecessary block body and explicit void return type for the navigate call; collapse the setExpanded handler to a single-line block per ESLint no-confusing-void-expression. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n, guard, tests - Preserve accumulated iteration state in handleDagNode by spreading existing node before overwriting with event fields (HIGH: iteration badge/list vanished on node completion) - Replace nested <button> with <span role="button"> + onKeyDown in DagNodeProgress to fix HTML spec violation and broken stopPropagation (HIGH: accessibility + mis-navigation) - Fix falsy guard `if (!iteration)` → `if (iteration === undefined)` in WorkflowExecution REST enrichment (MEDIUM: would silently drop iteration 0 in future) - Fix dead file reference in workflow-bridge comments: `useWorkflowStatus.ts` → `workflow-store.ts handleLoopIteration` (MEDIUM: misleading comment) - Add 7 unit tests for handleLoopIteration in workflow-store.test.ts covering all branches: no-nodeId no-op, ghost-node no-op, first append, upsert, total:0 preservation, accumulation, and iteration state survival across dag_node completion (MEDIUM: zero coverage for core PR logic) - Clarify two LOW comment gaps in WorkflowExecution.tsx and workflow-store.ts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ve element - Add missing `workflow_step` case in useDashboardSSE switch so loop iteration events are routed to the store instead of silently dropped - Restructure DagNodeItem: replace outer <button> with <div role="row"> and change the expand toggle from <span role="button"> to a proper <button>, eliminating the interactive-element-in-interactive-element violation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: make artifact file paths clickable in chat messages (#1016) Artifact paths in AI responses (e.g. `artifacts/runs/{uuid}/report.md`) were rendered as plain inline code. Now they render as clickable buttons (.md opens ArtifactViewerModal) or links (other types open in new tab). Changes: - Add artifact path detection via regex in MessageBubble code renderer - Convert MARKDOWN_COMPONENTS to factory function for modal state access - Add ArtifactViewerModal integration in chat view - Add 'workflow_artifact' to WORKFLOW_EVENT_TYPES in store.ts Fixes #1016 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(web): improve MessageBubble type clarity and code comments - Replace opaque `ComponentPropsWithoutRef<never>` return type on `makeMarkdownComponents` with the idiomatic `Components` type from react-markdown, which is the actual contract the prop expects - Add explanatory comment on `ARTIFACT_PATH_RE` describing group semantics and cross-platform path handling intent - Add comment on `useMemo` empty dep array explaining that `setArtifactViewer` is a stable React state setter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * simplify: merge duplicate lucide-react imports in MessageBubble Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(web): harden extractArtifactInfo UUID regex and path traversal check Make ARTIFACT_PATH_RE case-insensitive for hex digits ([a-fA-F0-9-]+) so uppercase UUID characters are matched correctly. Also reject filenames containing '..' path segments to prevent path traversal. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(web): add artifact path detection to WorkflowResultCard markdown The artifact-aware code component was only in MessageBubble.tsx but WorkflowResultCard in MessageList.tsx used its own static markdown components without artifact detection. Artifact paths in workflow results were rendering as plain code spans instead of clickable links. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(server,web): artifact route uses codebase name for owner/repo + bright link styling The artifact route derived owner/repo from the working_path, which fails for worktree-based runs (worktrees use local filesystem username, not GitHub username). Now looks up the codebase record by codebase_id to get the correct owner/repo from the codebase name. Also fixes artifact link styling in WorkflowResultCard — uses text-accent-bright instead of text-[inherit] which was inheriting the dim text-text-secondary color from the parent container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve merge conflict markers in api.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style(web): brighter artifact link color in workflow result cards Bumped artifact link color from accent-bright (0.72) to a brighter oklch(0.78 0.18 250) with font-medium for better readability against the dark text-text-secondary card background. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * style(web): use inline styles for artifact links to guarantee visibility Tailwind classes were being overridden by parent text-text-secondary. Inline styles ensure the bright blue color and pointer cursor always apply regardless of CSS cascade. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web): use <a> tags for all artifact links with !text-accent-bright Replaced <button> with <a> for .md artifacts (pointer cursor by default), unified styling using !text-accent-bright to override parent text-text-secondary, hover brightens to oklch(0.85). All artifact links now consistently bright and clickable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web,server): restore missing import, fix artifact link colors and cursor - Restore getArchonWorkspacesPath import removed by prior commit (still used in 3 other places in api.ts, breaking the build) - Use text-accent-bright instead of dark text-accent for artifact links in MessageBubble (was nearly invisible on dark background) - Add cursor-pointer to .md artifact buttons in MessageBubble - Replace arbitrary oklch hover value with hover:!text-primary in MessageList artifact links Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix(server): use BUNDLED_VERSION for app version in binary mode
- Fix unsafe `e.data` cast: use runtime type narrowing instead of `as Record<string, string | undefined>` for event artifact extraction - Fix invalid ArtifactType fallback: change 'file' to 'file_created' (a valid member of the ArtifactType union) - Handle useQuery error state: destructure `isError` and render a degraded card (no node count, duration, or artifacts) when the API fetch fails, preventing a misleading "Workflow complete" display - Emit workflowResult metadata on failure/cancel: the orchestrator now attaches workflowResult to failed workflow messages so the chat renders a result card with status icon and "View full logs" link - Add 'workflowRun' to invalidateWorkflowQueries() so singular run cache entries are invalidated alongside the plural list caches Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve merge conflict in MessageList.tsx by combining: - PR #1025: status/duration/nodes/artifacts enrichment for WorkflowResultCard - PR #1023: ArtifactViewerModal clickable file paths in result card content Both features now work together — the result card shows status-aware headers, node counts, duration, and artifact summaries while also supporting clickable artifact file paths in the markdown content. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three fixes for message duplication during live workflow execution: 1. dag-executor: Add missing `tool_call_formatted` category to loop iteration tool messages. Without this, the web adapter sent tool text as both a regular SSE text event AND a structured tool_call event, causing each tool to appear twice (raw text + rendered card). Regular DAG nodes already had this metadata. 2. WorkflowLogs: Add text content dedup in SSE/DB merge. During live execution, the same text (e.g. "Starting workflow...") can appear in both DB (REST fetch) and SSE (event buffer replay). Collects DB text into a Set and skips matching SSE text messages. 3. orchestrator-agent: Suppress remainingMessage re-send in stream mode. The routing AI streams text chunks before /invoke-workflow is detected, then retracts them. Without suppression, remainingMessage re-sends the same text. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WorkflowLogs' onText handler was blindly concatenating all SSE text into a single streaming message, unlike ChatInterface which splits on workflow status text (🚀/✅). This caused the "Starting workflow" text to merge with subsequent text into one giant message, breaking text dedup against DB messages (which are stored as separate segments). The SSE message content never matched any single DB message exactly, so both appeared. Add the same workflow status boundary detection from ChatInterface: close the current streaming message and start a new one when a workflow status message arrives or when regular text follows a status message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The suppression broke the "sends remaining message before dispatching workflow" test — when the AI response contains both text and a command in a single chunk, the text was never streamed, so suppressing remainingMessage loses it entirely. The actual duplicate was in the WorkflowLogs execution view, not the routing AI path, and is already fixed by the onText message splitting and text content dedup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat(web): loop node iteration visibility in workflow execution view
…t timeout (#1067, #1030, #1098, #1070) * fix: strip CWD .env leak, enable platform adapters in serve, add first-event timeout (#1067) Three bugs fixed: (1) Bun auto-loads CWD .env files before user code, leaking non-overlapping keys into the Archon process — new stripCwdEnv() boot import removes them before any module reads env. (2) archon serve hardcoded skipPlatformAdapters:true, preventing Slack/Telegram/Discord from starting. (3) Claude SDK query had no first-event timeout, causing silent 30-min hangs when the subprocess wedges — new withFirstMessageTimeout wrapper races the first event against a configurable deadline (default 60s). Changes: - Add @archon/paths/strip-cwd-env and strip-cwd-env-boot modules - Import boot module as first import in CLI entry point - Remove skipPlatformAdapters: true from serve.ts - Add withFirstMessageTimeout + diagnostics to ClaudeClient - Add CLAUDECODE=1 nested-session warning to CLI - Add 9 unit tests (6 strip-cwd-env + 3 timeout) Fixes #1067 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address review findings for PR #1092 Fixed: - Clear setTimeout timer in withFirstMessageTimeout finally block (HIGH-1) - Add strip-cwd-env-boot to server/src/index.ts for direct dev:server path (MEDIUM-1) - Warn to stderr on non-ENOENT errors in stripCwdEnv (MEDIUM-2) - Update stale configuration.md docs for new env-loading mechanism (HIGH-2) - Add ARCHON_CLAUDE_FIRST_EVENT_TIMEOUT_MS and ARCHON_SUPPRESS_NESTED_CLAUDE_WARNING env vars to docs - Add nested Claude Code hang troubleshooting entry - Fix boot module JSDoc: "CLI and server" → "CLI" only - Fix stripCwdEnv JSDoc: remove stale "override: true" reference - Update .claude/rules/cli.md startup behavior section - Update CLAUDE.md @archon/paths description with new exports Tests added: - Assert controller.signal.aborted on timeout - Handle generator that completes immediately without yielding - Strip distinct keys from different .env files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * simplify: replace string sentinel with typed error class in withFirstMessageTimeout Replace the '__timeout__' string sentinel used to identify timeout rejections with a dedicated FirstEventTimeoutError class. instanceof checks are more explicit and robust than string comparison on error messages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: address review findings — dotenv version, docs, server warning, marker strip, tests 1. Align dotenv to ^17 (was ^16, rest of monorepo uses ^17.2.3) 2. Remove incorrect SUBPROCESS_ENV_ALLOWLIST claim from docs — the SDK bypasses the env option and uses process.env directly (#1097) 3. Add CLAUDECODE=1 warning to server entry point (was only in CLI) 4. Add diagnostic payload content test for withFirstMessageTimeout 5. Integrate #1097's finding: strip CLAUDECODE + CLAUDE_CODE_* session markers (except auth vars) + NODE_OPTIONS + VSCODE_INSPECTOR_OPTIONS from process.env at entry point. Pattern-matched on CLAUDE_CODE_* prefix rather than hardcoding 6 names, so future Claude Code markers are handled automatically. Auth vars (CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX) are preserved. Root cause per #1097: the Claude Agent SDK leaks process.env into the spawned child regardless of the explicit env option, so the only way to prevent the nested-session deadlock is to delete the markers from process.env at the entry point. Validation: bun run validate passes, 125 paths tests (6 new marker tests), 60 claude tests (1 new diagnostic test), DATABASE_URL leak verified stripped (target repo .env DATABASE_URL does not affect Archon DB selection). * refactor: remove SUBPROCESS_ENV_ALLOWLIST — trust user config, strip only CWD The allowlist was wrong for a single-developer tool: - It blocked keys the user intentionally set in ~/.archon/.env (ANTHROPIC_API_KEY, AWS_*, CLAUDE_CONFIG_DIR, MiniMax vars, etc.) - It was bypassed by the SDK anyway (process.env leaks to subprocess regardless of the env option — see #1097) - It attracted a constant stream of PRs adding keys (#1060, #1093, #1099) New model: CWD .env keys are the only untrusted source. stripCwdEnv() at entry point handles that. Everything in ~/.archon/.env + shell env passes through to the subprocess. No filtering, no second-guessing. Changes: - Delete env-allowlist.ts and env-allowlist.test.ts - Simplify buildSubprocessEnv() to return { ...process.env } with auth-mode logging (no token stripping — user controls their config) - Replace 4 allowlist-based tests with 1 pass-through test - Remove env-allowlist.test.ts from core test batch - Update security.md and cli.md docs to reflect the new model The CLAUDECODE + CLAUDE_CODE_* marker strip and NODE_OPTIONS strip remain in stripCwdEnv() at entry point — those are process-level safety (not per-subprocess filtering) and are needed regardless. * fix: restore override:true for archon env, add integration tests The integration tests caught a real issue: without override:true, the ~/.archon/.env load doesn't win over shell-inherited env vars. If the user's shell profile exports PORT=9999 and ~/.archon/.env has PORT=3000, the user expects Archon to use 3000. stripCwdEnv() handles CWD .env files (untrusted). override:true handles shell-inherited vars (trusted but less specific than ~/.archon/.env). Different concerns, both needed. Also adds 6 integration tests covering the full entry-point flow: 1. Global auth user with ANTHROPIC_API_KEY in CWD .env — stripped 2. OAuth token in archon env + random key in CWD — CWD stripped, archon kept 3. General leak test — nothing from CWD reaches subprocess 4. Same key in both CWD and archon — archon value wins 5. CLAUDECODE markers stripped even when not from CWD .env 6. CLAUDE_CODE_OAUTH_TOKEN survives marker strip * test: add DATABASE_URL leak scenarios to env integration tests * fix: move CLAUDECODE warning into stripCwdEnv, remove dead useGlobalAuth logic Review findings addressed: 1. CLAUDECODE warning was dead code — the boot import deleted CLAUDECODE from process.env before the warning check in cli.ts/server/index.ts could fire. Moved the warning into stripCwdEnv() itself, emitted BEFORE the deletion. Removed duplicate warning code from both entry points. 2. useGlobalAuth token stripping removed (intentional, not regression) — the old code stripped CLAUDE_CODE_OAUTH_TOKEN and CLAUDE_API_KEY when useGlobalAuth=true. Per design discussion: the user controls ~/.archon/.env and all keys they set are intentional. If they want global auth, they just don't set tokens. Simplified buildSubprocessEnv to log auth mode for diagnostics only, no filtering. 3. Docs "no override needed" corrected — cli.md and configuration.md now reflect the actual code (override: true). --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Tyone88
pushed a commit
to Tyone88/Archon
that referenced
this pull request
Apr 16, 2026
Release 0.3.6
joaobmonteiro
pushed a commit
to joaobmonteiro/Archon
that referenced
this pull request
Apr 26, 2026
Release 0.3.6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release 0.3.6
Web UI workflow experience improvements, CWD environment leak protection, and bug fixes.
Added
Changed
.envvariables are now stripped from AI subprocess environments at the@archon/pathslayer, replacing the oldSUBPROCESS_ENV_ALLOWLISTapproach. Prevents accidental credential leaks from target repo.envfiles (2 issues: v0.3.5: CLI workflow run silently hangs — dotenv loads .env from CWD instead of ~/.archon/.env,, + rchon serve hardcodes skipPlatformAdapters:true — Telegram/Discord/Slack adapters are unreachable #1067, bug: Claude Agent SDK subprocess hangs when Archon launched from inside Claude Code session #1030, CLAUDE_CONFIG_DIR not passed to subprocess env, breaking non-default config locations #1098, Add MiniMax M2 API and additional environment variables to subprocess allowlist #1070)Fixed
workflow_stepSSE events not handled correctly, causing missing progress updatesremainingMessagesuppression in stream mode causing lost outputBUNDLED_VERSIONfor the app version instead of readingpackage.jsonMerging this PR releases 0.3.6 to main.