diff --git a/apps/web/e2e/channel.spec.ts b/apps/web/e2e/channel.spec.ts index 25006fbf6..ace4eb68b 100644 --- a/apps/web/e2e/channel.spec.ts +++ b/apps/web/e2e/channel.spec.ts @@ -6837,6 +6837,23 @@ test("workflow context inspect details stay out of main feed expansion", async ( }, ]; state.executionActions = [ + { + id: "execution_action_workflow_read", + workspaceId: "workspace_default", + runId: contextRun.id, + actionType: "read", + risk: "low", + status: "succeeded", + title: "Read workflow evidence projection", + summary: "Inspect the current workflow evidence projection.", + targetRefs: [{ type: "file", path: "apps/web/src/lib/workflow-progress.ts" }], + previewArtifactIds: [], + resultArtifactIds: [], + scopeSummary: "read_only", + createdAt: "2026-05-25T00:50:20.000Z", + updatedAt: "2026-05-25T00:50:25.000Z", + executedAt: "2026-05-25T00:50:20.000Z", + }, { id: "execution_action_workflow_edit", workspaceId: "workspace_default", @@ -6849,6 +6866,7 @@ test("workflow context inspect details stay out of main feed expansion", async ( targetRefs: [{ type: "file", path: "apps/web/src/lib/workflow-progress.ts" }], previewArtifactIds: [], resultArtifactIds: ["artifact_context_inspect_file"], + scopeSummary: "workspace_write", createdAt: "2026-05-25T00:50:30.000Z", updatedAt: "2026-05-25T00:51:10.000Z", executedAt: "2026-05-25T00:50:35.000Z", @@ -6865,6 +6883,7 @@ test("workflow context inspect details stay out of main feed expansion", async ( targetRefs: [{ type: "command", label: "pnpm --filter @ling-stack/web exec playwright test e2e/channel.spec.ts -g workflow" }], previewArtifactIds: [], resultArtifactIds: [], + scopeSummary: "workspace_write", createdAt: "2026-05-25T00:51:20.000Z", updatedAt: "2026-05-25T00:51:50.000Z", executedAt: "2026-05-25T00:51:20.000Z", @@ -6905,7 +6924,10 @@ test("workflow context inspect details stay out of main feed expansion", async ( await expect(operationBubble).toHaveClass(/expanded/); await expect(workCell.locator(".conversation-work-cell-agent-span")).toHaveCount(0); const activeStream = workCell.locator(".conversation-work-cell-active-stream"); + await expect(activeStream).toContainText("Read workflow-progress.ts"); await expect(activeStream).toContainText("Ran command"); + await expect(activeStream).not.toContainText("read_only"); + await expect(activeStream).not.toContainText("workspace_write"); await expect(activeStream).not.toContainText("$ pnpm --filter @ling-stack/web exec playwright test e2e/channel.spec.ts -g workflow"); const engineerShellRow = activeStream.locator(".conversation-work-cell-row.shell").filter({ hasText: "Ran command" }); await expect(engineerShellRow.locator(".conversation-work-cell-shell-card")).toHaveCount(0); @@ -6934,8 +6956,11 @@ test("workflow context inspect details stay out of main feed expansion", async ( await expect(workCell).not.toContainText("tokens"); await expect(workCell).not.toContainText("Workflow step runtime boundary:"); const evidenceRegion = workCell.getByRole("region", { name: "Evidence" }); + await expect(evidenceRegion).toContainText("Read workflow-progress.ts"); await expect(evidenceRegion).toContainText("Edited workflow-progress.ts"); await expect(evidenceRegion).toContainText("Ran command"); + await expect(evidenceRegion).not.toContainText("read_only"); + await expect(evidenceRegion).not.toContainText("workspace_write"); await expect(evidenceRegion).toContainText("Handoff: Engineer -> Reviewer"); await expect(evidenceRegion).not.toContainText("Approval checkpoint: Resume workflow execution"); await expect(evidenceRegion).not.toContainText("Resume workflow execution"); diff --git a/apps/web/src/lib/conversation-work-cell.ts b/apps/web/src/lib/conversation-work-cell.ts index 4d774e1d7..df18e9145 100644 --- a/apps/web/src/lib/conversation-work-cell.ts +++ b/apps/web/src/lib/conversation-work-cell.ts @@ -1331,7 +1331,7 @@ function executionActionTranscriptRows( const rows: ConversationWorkCellRow[] = []; const operationExecution = executionActionExecutionView(action, context); const scopeSummary = action.scopeSummary?.trim(); - if (scopeSummary) { + if (scopeSummary && !isInternalExecutionScopeSummary(scopeSummary)) { rows.push({ id: `action-note:${action.id}`, kind: "plan", @@ -1345,6 +1345,26 @@ function executionActionTranscriptRows( return rows; } +const INTERNAL_EXECUTION_SCOPES = new Set([ + "read_only", + "workspace_read", + "workspace_write", + "git_history", + "network", + "credential", + "provider_config", + "deployment", + "external_system", +]); + +function isInternalExecutionScopeSummary(summary: string): boolean { + const scopes = summary + .split(",") + .map((scope) => scope.trim()) + .filter(Boolean); + return scopes.length > 0 && scopes.every((scope) => INTERNAL_EXECUTION_SCOPES.has(scope)); +} + function executionActionExecutionView( action: ExecutionAction, context: {