[WIP] feat: add --all flag to agent preview end (W-22203669)#406
[WIP] feat: add --all flag to agent preview end (W-22203669)#406franciscoperezsammartino wants to merge 4 commits intomainfrom
Conversation
jshackell-sfdc
left a comment
There was a problem hiding this comment.
see my small suggestions.
| : await Agent.init({ connection: conn as Connection, project: this.project!, apiNameOrId: flags['api-name']! }); | ||
| } catch (error) { | ||
| const wrapped = SfError.wrap(error); | ||
| await Lifecycle.getInstance().emitTelemetry({ eventName: 'agent_preview_end_agent_not_found' }); |
There was a problem hiding this comment.
We don't need this explicit telemetry call because a similar event will be sent as part of the CLI telemetry framework that sends command execution events; both success and error.
| eventName: 'agent_preview_end_all_partial_failure', | ||
| failedCount: failed.length, | ||
| succeededCount: ended.length, | ||
| }); |
There was a problem hiding this comment.
I would remove this specific event and instead set a different exit code for the command when partial success happens. This allows the CLI framework telemetry events to handle it. @WillieRuemmele - can you suggest a good exit code for this?
There was a problem hiding this comment.
I think 4 would work, it's PreviewEndFailed, if we want a more fine-grained approach, we could use 6 as a PreviewEndPartialFailure
| await Lifecycle.getInstance().emitTelemetry({ | ||
| eventName: 'agent_preview_end_all_success', | ||
| sessionCount: ended.length, | ||
| }); |
There was a problem hiding this comment.
This telemetry event is not needed. The CLI framework handles it already.
| await callPreviewEnd(agent); | ||
| } catch (error) { | ||
| const wrapped = SfError.wrap(error); | ||
| await Lifecycle.getInstance().emitTelemetry({ eventName: 'agent_preview_end_failed' }); |
There was a problem hiding this comment.
This isn't needed. The CLI framework telemetry handles this already.
| publishedAgent!.DeveloperName | ||
| } --target-org ${targetOrg} --json` | ||
| ).jsonOutput?.result; | ||
| ).jsonOutput?.result as import('../../src/commands/agent/preview/end.js').EndedSession | undefined; |
There was a problem hiding this comment.
we shouldn't need this type import, you can cast with execCmd<AgentPreviewEndResult>
- Adds --all to end multiple preview sessions at once - When combined with --api-name or --authoring-bundle, ends only sessions for that specific agent; when used alone, ends all sessions in the project - Adds --no-prompt (-p) to skip the confirmation prompt shown by --all - Makes --target-org optional (no org needed for client-side session cleanup); raises a clear error when --api-name is used without --target-org - Restores inline previewSessionStore implementation (the @salesforce/agents shim was broken against the installed 1.1.1 version); adds getSessionDir and removeCacheById helpers needed by the --all code path - Adds 13 unit tests for the new end command behaviour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: address review findings for --all flag on agent preview end - Add try/catch in endAll serial loop with structured PreviewEndPartialFailure error listing which sessions failed vs succeeded - Restore timestamp/sessionType columns on agent preview sessions (W-22203667 regression introduced by the shim revert in the previous commit) - Add three missing tests: --all+--api-name happy path, missing --target-org guard, and mid-loop failure with partial results assertions - Document --no-prompt only has effect when used with --all Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> chore: regenerate schemas and fix NUT type assertions for EndedSession union Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: restore SessionType named import in start.ts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: restore pre-shim inline session store; scope to W-22203669 only Replace the bloated inline rewrite with the correct base (commit 57fb5f7, the last working inline implementation before the broken shim). Only the two helpers needed by --all are added on top: getSessionDir and removeCacheById. sessions.ts and start.ts are restored to their main state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: remove agentId from EndedSession public result type agentId was not in the original result type and is not needed by callers. Kept as an internal SessionTask type for routing within endAll. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: enforce --target-org dependency on --api-name at flag level Use oclif dependsOn instead of a manual guard in run(). authoring-bundle does not need target-org since it works client-side only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: extract callPreviewEnd to remove instanceof duplication The ScriptAgent/ProductionAgent branching was identical in the single-session path and the endAll loop. Extracted to a module-level function. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> chore: restore atomic-write comment on updateSessionIndex Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: eliminate getSessionDir/removeCacheById in favor of duck-typed removeCache removeCache only needs getHistoryDir(), so the no-agent path in --all can pass a plain object instead of requiring a separate removeCacheById helper. Loosened removeCache/validatePreviewSession signatures to structural types. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> chore: restore previewSessionStore.ts to main shim and upgrade @salesforce/agents to 1.2.0 The shim was inadvertently replaced with a full inline implementation. Restoring it to the re-export shim from main. Bumping agents to 1.2.0 which now exports the session store functions the shim references. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> chore: restore yarn.lock to main state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Apply suggestion from @jshackell-sfdc Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> Apply suggestion from @jshackell-sfdc Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com> refactor: use Interfaces.InferredFlags for private method flag types Replaces manual inline object types with Pick<CommandFlags, ...> so the method signatures stay in sync with the flag definitions automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: require --api-name or --authoring-bundle when using --all --all alone was only doing client-side cleanup for ProductionAgent sessions, which was inconsistent. Now --all must be combined with an agent identifier so every session is properly ended server-side. Also simplifies endAll: SessionTask reduced to {sessionId}, tracesPath resolved via agent.getHistoryDir() inside the loop, prompt updated to name the specific agent rather than a generic count. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: enforce --all agent identifier requirement at flag definition level Moves the --all + agent identifier constraint from a runtime guard to oclif's atLeastOne flag metadata. Removing 'all' from all three atLeastOne arrays means oclif itself rejects --all alone with a single clean error message, rather than a custom SfError with duplicated validation logic in run(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> refactor: use exactlyOne instead of exclusive+atLeastOne for agent identifier flags Matches the pattern already used in start.ts. exactlyOne is cleaner and expresses the intent in a single declaration — exactly one of --api-name or --authoring-bundle must be provided. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> feat: allow --all alone to end sessions across all cached agents When --all is used without --api-name or --authoring-bundle, reads all active sessions from the local cache via listCachedSessions, determines agent type from the cached sessionType, and ends each session properly (server-side for ProductionAgent, local for ScriptAgent). --target-org is required with --all since it may be needed for server-side calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: address PR review feedback and improve --all end-all-agents path - Remove all explicit Lifecycle.emitTelemetry() calls (CLI framework handles it) - Change PreviewEndPartialFailure exit code from 4 to 6 - Use sessionType as discriminator for agent type (published vs local) - Re-set sessionId after ProductionAgent.endSession() clears it before removeCache - Clean local cache on server error for --all paths to prevent stale buildup - Show per-agent breakdown with local/published label in confirmation prompt - Use displayName in prompt breakdown, falling back to agentId Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: apply Slack feedback — exit code 68, bot/bundle labels, no cache cleanup on failure - PreviewEndPartialFailure exit code 6 → 68 (matches deploy-retrieve SucceededPartial) - Label published sessions as 'bot', AAB sessions as 'bundle' in --all prompt breakdown - Remove cleanOnServerError: failed sessions no longer remove local cache - Narrow endAllAgents noPrompt param from boolean | undefined to boolean - Fix finishEndAll JSDoc to mention both callers - Add tests: exitCode 68 assertion, all-agents prompt confirm/decline, Agent.init failure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> fix: show user-supplied flag value in --all prompt instead of internal bot ID --all --api-name was showing the internal Salesforce Bot record ID (e.g. 0Xxg8000000QnQ5CAK) in the confirmation prompt instead of the API name passed by the user. Use flags['api-name'] ?? flags['authoring-bundle'] as the prompt label in endAllForAgent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
00d8681 to
85bc9ee
Compare
…ndling --target-org is now required globally. Remove dependsOn constraints on --api-name and --all (no longer needed), drop all Connection | undefined type guards and casts, and update tests to pass --target-org everywhere. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…al loop Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| @@ -120,16 +146,10 @@ export default class AgentPreviewEnd extends SfCommand<AgentPreviewEndResult> { | |||
| const tracesPath = await agent.getHistoryDir(); | |||
| await removeCache(agent); | |||
There was a problem hiding this comment.
swap lines 147 and 149-157 so callPreviewEnd runs first, consistent with the multi-session loop, and same behavior if error occurs during removing cache / ending preview
There was a problem hiding this comment.
Thanks also updated an import you mentioned before and fixed it, but claude decided to change it back again 😅
…gle-session path Swaps the order to match the multi-session loop: end the session first, then re-set sessionId (ProductionAgent clears it internally), then remove the local cache entry. Also replaces inline import casts in the NUT file with a proper top-level EndedSession import. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
--allflag toagent preview endto terminate multiple sessions at once--api-nameor--authoring-bundle: ends only sessions for that specific agent--no-prompt/-pflag to skip confirmation prompt (with--allonly)--target-orgoptional; guard throws when--api-nameis used without itPreviewEndPartialFailureerror listing succeeded/failed sessions on mid-loop failuretimestamp/sessionTypecolumns onagent preview sessions(W-22203667 regression from shim revert)Test plan
yarn test)agent preview end --allends all sessions and shows confirmation promptagent preview end --all --no-promptskips confirmationagent preview end --all --authoring-bundle <name>ends only sessions for that agentagent preview end --all --api-name <name> --target-org <org>ends only sessions for that agentagent preview end --all --api-name <name>(no org) throwsMissingTargetOrgForApiNameagent preview sessionsshows timestamp and sessionType columns🤖 Generated with Claude Code