Unify workforce cloud auth session#234
Conversation
Co-Authored-By: OpenAI <codex@openai.com>
|
Warning Review limit reached
More reviews will be available in 42 minutes and 5 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughThis PR upgrades ChangesCloud session auth migration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Code Review
This pull request migrates workspace and authentication management from a custom local active.json and legacy keychain files to the canonical @agent-relay/cloud SDK session and active workspace store. It updates dependencies, refactors CLI commands (login, logout, destroy), and updates the deployment orchestrator's token resolution logic. Feedback on the changes suggests awaiting setWorkspaceKey before exiting the process to prevent premature termination, safely catching potential JSON parsing errors when resolving workspace descriptors, and ensuring the key field is validated in normalizeWorkspaceDescriptor to avoid silent authentication failures.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| deployCommandDeps.setWorkspaceKey(workspaceName, descriptor.key); | ||
| process.stdout.write(`\nlogged in: ${workspaceName}\n`); | ||
| process.exit(0); |
There was a problem hiding this comment.
If setWorkspaceKey performs asynchronous I/O (such as writing to a configuration file or keychain) and returns a Promise, calling process.exit(0) immediately afterward without awaiting it can terminate the Node.js process prematurely. This can result in incomplete writes or silent persistence failures. We should await the call to ensure the workspace key is fully persisted before exiting.
| deployCommandDeps.setWorkspaceKey(workspaceName, descriptor.key); | |
| process.stdout.write(`\nlogged in: ${workspaceName}\n`); | |
| process.exit(0); | |
| await deployCommandDeps.setWorkspaceKey(workspaceName, descriptor.key); | |
| process.stdout.write("\nlogged in: " + workspaceName + "\n"); | |
| process.exit(0); |
| const text = await response.text().catch(() => ''); | ||
| throw new Error(`workspace resolve failed for ${workspace}: ${response.status} ${text}`.trim()); | ||
| } | ||
| return normalizeWorkspaceDescriptor(await response.json(), session.auth.apiUrl || args.apiUrl); |
There was a problem hiding this comment.
If the server returns a non-JSON response or an empty body, calling response.json() directly will throw a raw SyntaxError. We should safely parse the JSON with a .catch(() => null) and let normalizeWorkspaceDescriptor handle the invalid payload gracefully, similar to how it is done in resolveWorkspaceForLogin in packages/cli/src/deploy-command.ts.
const payload = await response.json().catch(() => null);
return normalizeWorkspaceDescriptor(payload, session.auth.apiUrl || args.apiUrl);| if (!relaycastWorkspaceId || !relayfileWorkspaceId || !relayauthWorkspaceId) { | ||
| throw new Error('workspace resolve returned an incomplete descriptor'); | ||
| } |
There was a problem hiding this comment.
The validation check for an incomplete workspace descriptor does not verify if key is present, unlike the corresponding check in resolveWorkspaceForLogin within packages/cli/src/deploy-command.ts. If key is missing or empty, it will be silently set to an empty string, which could lead to authentication failures later. We should ensure key is validated as well.
| if (!relaycastWorkspaceId || !relayfileWorkspaceId || !relayauthWorkspaceId) { | |
| throw new Error('workspace resolve returned an incomplete descriptor'); | |
| } | |
| if (!key || !relaycastWorkspaceId || !relayfileWorkspaceId || !relayauthWorkspaceId) { | |
| throw new Error('workspace resolve returned an incomplete descriptor'); | |
| } |
Co-Authored-By: OpenAI <codex@openai.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/cli/src/deploy-command.ts (2)
163-175:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHonor
WORKFORCE_WORKSPACE_IDbefore listing workspaces.
LOGIN_USAGEdocuments the env var as the default, but this branch only checksopts.workspace. On accounts that cannot list/api/v1/workspaces,agentworkforce loginwill still take the 403 failure path instead of resolving the preconfigured workspace.Suggested fix
- if (opts.workspace) { - chosen = opts.workspace; + const requestedWorkspace = opts.workspace ?? process.env.WORKFORCE_WORKSPACE_ID?.trim(); + if (requestedWorkspace) { + chosen = requestedWorkspace; } else { workspaces = await listWorkspacesForLogin(auth, apiUrl); if (workspaces.length === 0) { throw new Error( 'no workspaces are accessible from this account. Create one at https://agentrelay.com/cloud, '🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/src/deploy-command.ts` around lines 163 - 175, The code only checks opts.workspace before calling listWorkspacesForLogin; change the branch logic in the deploy flow (the block that assigns chosen using opts.workspace, listWorkspacesForLogin, and pickWorkspaceInteractive) to first honor the WORKFORCE_WORKSPACE_ID environment variable (process.env.WORKFORCE_WORKSPACE_ID) as the default workspace if present, then fallback to opts.workspace, and only if neither is set call listWorkspacesForLogin(auth, apiUrl) and possibly pickWorkspaceInteractive(workspaces, io); this avoids calling the workspace list API when a preconfigured WORKFORCE_WORKSPACE_ID is available.
197-207:⚠️ Potential issue | 🟠 MajorFix
runLogoutso it actually clears the canonical workspace selection written byrunLogin
runLoginpersists the active workspace viadeployCommandDeps.setWorkspaceKey(...)(packages/cli/src/deploy-command.ts). ButrunLogoutonly callsclearActiveWorkspace()andclearStoredWorkspaceToken(...)—both are explicit no-ops inpackages/deploy/src/login.tsbecause workspace selection now lives in@agent-relay/cloud’s canonical workspace store. As a result,agentworkforce logoutcan printworkspace login clearedwithout clearing the canonical workspace pin (unless--cloud-authhappens to clear stored cloud auth).
packages/cli/src/deploy-command.ts#L190-L207: updaterunLogoutto call the appropriate@agent-relay/cloudAPI to clear the workspace key/pointer written bysetWorkspaceKey(or adjust messaging/flags if no such clearing exists).packages/cli/src/deploy-command.test.ts#L262-L285,#L287-L310,#L312-L335: update these tests to assert the canonical workspace-clearing behavior (they currently only verify the CLI-level deps are invoked, but the real implementations are no-ops).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/cli/src/deploy-command.ts` around lines 197 - 207, Update runLogout so it clears the canonical workspace pointer in `@agent-relay/cloud` (the same canonical key that runLogin writes via setWorkspaceKey). In packages/cli/src/deploy-command.ts (lines 197-207) import and invoke the cloud workspace-clearing API (e.g., cloud.clearWorkspaceKey(...) or cloud.setWorkspaceKey(null) — whichever the cloud package exposes) in addition to the existing deployCommandDeps.clearActiveWorkspace() and clearStoredWorkspaceToken(opts.workspace), and adjust the final message if needed; keep references to deployCommandDeps.clearActiveWorkspace and deployCommandDeps.clearStoredWorkspaceToken. In packages/cli/src/deploy-command.test.ts (lines 262-285, 287-310, 312-335) update the tests to mock/spy the `@agent-relay/cloud` workspace API and assert that the canonical workspace-clearing call is invoked when running logout (replace or augment the existing assertions that only check the CLI-level deps).
🧹 Nitpick comments (1)
packages/deploy/src/login.ts (1)
160-163: ⚡ Quick winRedundant session initialization.
ensureCloudSessionis called here insideresolveWorkspaceDescriptor, but the parent functionresolveWorkspaceTokenalready calls it on line 129. Consider passing the existing session as a parameter to avoid the redundant initialization.♻️ Refactor to reuse the session
Update the function signature to accept a session parameter:
async function resolveWorkspaceDescriptor(args: { requestedWorkspace?: string; apiUrl: string; + session: { auth: StoredAuth; client: { fetch: (path: string, init?: RequestInit) => Promise<Response> } }; }): Promise<ActiveWorkspaceDescriptor> { const workspace = args.requestedWorkspace?.trim(); if (!workspace) { return resolveActiveWorkspace({ apiUrl: args.apiUrl, interactive: false }); } - const session = await ensureCloudSession({ - apiUrl: args.apiUrl, - interactive: false - }); - const response = await session.client.fetch( + const response = await args.session.client.fetch( `/api/v1/workspaces/${encodeURIComponent(workspace)}/resolve`, { method: 'GET' } ); if (!response.ok) { const text = await response.text().catch(() => ''); throw new Error(`workspace resolve failed for ${workspace}: ${response.status} ${text}`.trim()); } - return normalizeWorkspaceDescriptor(await response.json(), session.auth.apiUrl || args.apiUrl); + return normalizeWorkspaceDescriptor(await response.json(), args.session.auth.apiUrl || args.apiUrl); }Then update the call site on line 135:
const descriptor = await resolveWorkspaceDescriptor({ requestedWorkspace: requestedWorkspace || envWorkspace, - apiUrl: session.auth.apiUrl || cloudUrl + apiUrl: session.auth.apiUrl || cloudUrl, + session });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/deploy/src/login.ts` around lines 160 - 163, resolveWorkspaceDescriptor currently calls ensureCloudSession redundantly; change its signature to accept an existing Session (e.g., add a parameter named session), remove the internal call to ensureCloudSession inside resolveWorkspaceDescriptor, and use the passed session where needed. Then update the caller resolveWorkspaceToken to pass the session it already obtains (from its ensureCloudSession call) into resolveWorkspaceDescriptor. Ensure function/method names referenced are resolveWorkspaceDescriptor, resolveWorkspaceToken, and ensureCloudSession and update all call sites accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli/src/deploy-command.ts`:
- Around line 501-529: The resolveWorkspaceForLogin function currently only
validates key and relaycastWorkspaceId but must match the deploy contract by
also requiring relayfileWorkspaceId and relayauthWorkspaceId; update
resolveWorkspaceForLogin to read these fields from the parsed record (use
readString(record, 'relayfileWorkspaceId') and readString(record,
'relayauthWorkspaceId')), include them in the returned LoginWorkspaceDescriptor
(when present) and throw the same "incomplete descriptor" error if either is
missing so partially provisioned workspaces are rejected upfront.
- Around line 123-133: The recovery path in createDeployAuthRecovery().recover()
logs the active workspace but never persists it, which can leave subsequent
deploy/destroy flows without a pinned workspace; after obtaining session and
computing activeWorkspace (the same value logged), call the same
workspace-persistence used in runLogin() (setWorkspaceKey) via
deployCommandDeps.setWorkspaceKey(activeWorkspace) before returning the token;
additionally, update parseLoginArgs() to treat
process.env.WORKFORCE_WORKSPACE_ID as the default when --workspace is not
provided, and ensure resolveWorkspaceForLogin() returns/normalizes both
relayfileWorkspaceId and relayauthWorkspaceId (not just key +
relaycastWorkspaceId) so its payload matches `@agentworkforce/deploy`’s expected
descriptor contract.
---
Outside diff comments:
In `@packages/cli/src/deploy-command.ts`:
- Around line 163-175: The code only checks opts.workspace before calling
listWorkspacesForLogin; change the branch logic in the deploy flow (the block
that assigns chosen using opts.workspace, listWorkspacesForLogin, and
pickWorkspaceInteractive) to first honor the WORKFORCE_WORKSPACE_ID environment
variable (process.env.WORKFORCE_WORKSPACE_ID) as the default workspace if
present, then fallback to opts.workspace, and only if neither is set call
listWorkspacesForLogin(auth, apiUrl) and possibly
pickWorkspaceInteractive(workspaces, io); this avoids calling the workspace list
API when a preconfigured WORKFORCE_WORKSPACE_ID is available.
- Around line 197-207: Update runLogout so it clears the canonical workspace
pointer in `@agent-relay/cloud` (the same canonical key that runLogin writes via
setWorkspaceKey). In packages/cli/src/deploy-command.ts (lines 197-207) import
and invoke the cloud workspace-clearing API (e.g., cloud.clearWorkspaceKey(...)
or cloud.setWorkspaceKey(null) — whichever the cloud package exposes) in
addition to the existing deployCommandDeps.clearActiveWorkspace() and
clearStoredWorkspaceToken(opts.workspace), and adjust the final message if
needed; keep references to deployCommandDeps.clearActiveWorkspace and
deployCommandDeps.clearStoredWorkspaceToken. In
packages/cli/src/deploy-command.test.ts (lines 262-285, 287-310, 312-335) update
the tests to mock/spy the `@agent-relay/cloud` workspace API and assert that the
canonical workspace-clearing call is invoked when running logout (replace or
augment the existing assertions that only check the CLI-level deps).
---
Nitpick comments:
In `@packages/deploy/src/login.ts`:
- Around line 160-163: resolveWorkspaceDescriptor currently calls
ensureCloudSession redundantly; change its signature to accept an existing
Session (e.g., add a parameter named session), remove the internal call to
ensureCloudSession inside resolveWorkspaceDescriptor, and use the passed session
where needed. Then update the caller resolveWorkspaceToken to pass the session
it already obtains (from its ensureCloudSession call) into
resolveWorkspaceDescriptor. Ensure function/method names referenced are
resolveWorkspaceDescriptor, resolveWorkspaceToken, and ensureCloudSession and
update all call sites accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6d6a7a20-c199-4b70-a7c3-80537a3afccb
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
packages/cli/package.jsonpackages/cli/src/deploy-command.test.tspackages/cli/src/deploy-command.tspackages/cli/src/destroy-command.test.tspackages/cli/src/destroy-command.tspackages/deploy/package.jsonpackages/deploy/src/deploy.test.tspackages/deploy/src/deploy.tspackages/deploy/src/login.test.tspackages/deploy/src/login.ts
| io.info(`cloud: starting login because integration auth failed (${reason})`); | ||
| const auth = await deployCommandDeps.ensureAuthenticated(cloudUrl, { force: true }); | ||
| const apiUrl = normalizeCloudUrl(auth.apiUrl || cloudUrl); | ||
| const activeWorkspace = opts.workspace ?? workspace; | ||
| await deployCommandDeps.writeActiveWorkspace({ | ||
| workspace: activeWorkspace, | ||
| cloudUrl: apiUrl | ||
| const session = await deployCommandDeps.ensureCloudSession({ | ||
| apiUrl: cloudUrl, | ||
| force: true, | ||
| interactive: true | ||
| }); | ||
| const activeWorkspace = opts.workspace ?? workspace; | ||
| io.info(`cloud: logged in for workspace ${activeWorkspace}; retrying integration check`); | ||
| return { | ||
| token: auth.accessToken | ||
| token: session.auth.accessToken | ||
| }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and display relevant sections in the CLI deploy command
file="packages/cli/src/deploy-command.ts"
echo "=== $file (context around 100-220) ==="
sed -n '80,240p' "$file" | cat -n
# Find and show createDeployAuthRecovery / recover() region
echo
echo "=== $file (search: createDeployAuthRecovery, recover, runLogin, setWorkspaceKey) ==="
rg -n "createDeployAuthRecovery|recover\(|runLogin|setWorkspaceKey|resolveWorkspaceForLogin|runLogout|clearActiveWorkspace|LOGIN_USAGE|workspace" "$file"
# Inspect deploy-layer login implementation for resolve/persist behavior
depfile="packages/deploy/src/login.ts"
echo
echo "=== $depfile (context around workspace resolve/persist) ==="
ls -la "$depfile" 2>/dev/null || true
if [ -f "$depfile" ]; then
rg -n "resolve.*workspace|setWorkspaceKey|clearActiveWorkspace|workspace.*key|resolveWorkspaceForLogin|/resolve" "$depfile"
sed -n '1,260p' "$depfile" | cat -n
fi
# Inspect any helper implementations for resolveWorkspaceForLogin and workspace pinning
echo
echo "=== Search for resolveWorkspaceForLogin and setWorkspaceKey definitions in repo ==="
rg -n "function resolveWorkspaceForLogin|resolveWorkspaceForLogin\s*=\s*|setWorkspaceKey\s*\(" packages | head -n 50
# Show where setWorkspaceKey is imported/used in CLI
echo
echo "=== $file imports (top of file) ==="
sed -n '1,120p' "$file" | cat -nRepository: AgentWorkforce/workforce
Length of output: 30778
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/cli/src/deploy-command.ts"
echo "=== $file (context around LOGIN_USAGE workspace default text) ==="
sed -n '220,290p' "$file" | cat -n
echo
echo "=== $file (context around parseLoginArgs env handling) ==="
sed -n '290,380p' "$file" | cat -n
echo
echo "=== $file (context around resolveWorkspaceForLogin implementation) ==="
sed -n '470,560p' "$file" | cat -n
echo
echo "=== $file (context around LOGIN_USAGE full section for --workspace default) ==="
rg -n "LOGIN_USAGE|--workspace <name>.*WORKFORCE_WORKSPACE_ID|--workspace <name>\\s+Workforce workspace" "$file"Repository: AgentWorkforce/workforce
Length of output: 13043
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/cli/src/deploy-command.ts"
echo "=== Search WORKFORCE_WORKSPACE_ID/WORKFORCE_WORKSPACE_TOKEN usage in $file ==="
rg -n "WORKFORCE_WORKSPACE_ID|WORKFORCE_WORKSPACE_TOKEN" "$file" || true
echo
echo "=== Show parseLoginArgs implementation ==="
rg -n "function parseLoginArgs" "$file"
start=$(rg -n "function parseLoginArgs" "$file" | cut -d: -f1 | head -n1)
sed -n "$((start-10)),$((start+80))p" "$file" | cat -n
echo
echo "=== Show any env-based workspace default used before listWorkspacesForLogin ==="
rg -n "listWorkspacesForLogin|WORKFORCE_WORKSPACE_ID|resolveWorkspaceForLogin|opts\\.workspace" "$file" | head -n 100Repository: AgentWorkforce/workforce
Length of output: 4693
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/cli/src/deploy-command.ts"
echo "=== Search normalizeCloudUrl in $file ==="
rg -n "normalizeCloudUrl" "$file"Repository: AgentWorkforce/workforce
Length of output: 345
Pin the workspace during deploy auth recovery.
createDeployAuthRecovery().recover() re-authenticates and logs activeWorkspace, but it never resolves/persists the canonical workspace key (unlike runLogin() which calls setWorkspaceKey). This can leave the next default deploy/destroy path without an active workspace pin.
- Also,
loginhelp claims--workspacedefaults toWORKFORCE_WORKSPACE_ID or prompt, butparseLoginArgs()reads only argv—env won’t bypass the/api/v1/workspaces403 flow. resolveWorkspaceForLogin()accepts/resolvepayloads with onlykey+relaycastWorkspaceId, while@agentworkforce/deploy’s normalization requiresrelayfileWorkspaceIdandrelayauthWorkspaceId, so descriptor contract drift can slip through and fail later.
Suggested fix
const session = await deployCommandDeps.ensureCloudSession({
apiUrl: cloudUrl,
force: true,
interactive: true
});
const activeWorkspace = opts.workspace ?? workspace;
+ if (activeWorkspace) {
+ const apiUrl = canonicalizeCloudUrl(normalizeCloudUrl(session.auth.apiUrl || cloudUrl));
+ const descriptor = await resolveWorkspaceForLogin(session.auth, apiUrl, activeWorkspace);
+ deployCommandDeps.setWorkspaceKey(
+ descriptor.name ?? descriptor.slug ?? activeWorkspace,
+ descriptor.key
+ );
+ }
io.info(`cloud: logged in for workspace ${activeWorkspace}; retrying integration check`);
return {
token: session.auth.accessToken
};🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/cli/src/deploy-command.ts` around lines 123 - 133, The recovery path
in createDeployAuthRecovery().recover() logs the active workspace but never
persists it, which can leave subsequent deploy/destroy flows without a pinned
workspace; after obtaining session and computing activeWorkspace (the same value
logged), call the same workspace-persistence used in runLogin()
(setWorkspaceKey) via deployCommandDeps.setWorkspaceKey(activeWorkspace) before
returning the token; additionally, update parseLoginArgs() to treat
process.env.WORKFORCE_WORKSPACE_ID as the default when --workspace is not
provided, and ensure resolveWorkspaceForLogin() returns/normalizes both
relayfileWorkspaceId and relayauthWorkspaceId (not just key +
relaycastWorkspaceId) so its payload matches `@agentworkforce/deploy`’s expected
descriptor contract.
|
I reviewed the checked-out PR artifacts for No code changes are left in the working tree from my review. I validated Gemini’s finding and attempted the minimal fix, but dependency installation was repeatedly terminated before I could run CI-style verification, so I reverted the unverified edits per your instruction. Findings
Addressed comments
Advisory NotesMinimal proposed fix, once CI can run: export function liveNangoInitialSyncSucceeded(
schedules: {
ok?: boolean;
syncs?: readonly ({ status?: string | null } | null | undefined)[];
} | null,
): boolean {
return (
schedules?.ok === true &&
Array.isArray(schedules.syncs) &&
schedules.syncs.length > 0 &&
schedules.syncs.every((sync) => sync?.status === "SUCCESS")
);
}Add tests for Verification was not completed: local dependency installation was killed during package extraction, so I could not run the focused Vitest files, typecheck, or canonical CI commands. |
Co-Authored-By: OpenAI <codex@openai.com>
|
Implemented the PR-scoped fixes for the auth/workspace changes and verified the current checkout with the repo’s build/test path. I used Addressed comments
Advisory Notes
VerificationPassed locally:
I also updated two affected expectations to match the current cloud-session-first auth contract without weakening assertions: deploy.test.ts and destroy-command.test.ts. |
|
Implemented a scoped fix for the PR’s workspace-resolve path. The issue I found: explicit workspace resolution used custom payload normalization that only accepted flat Fixed in: Added/updated coverage: Addressed comments
Advisory NotesNone. Local validation run in CI workflow order:
All passed locally. Note: the sandbox Node version is |
|
Implemented one PR-scoped fix: Addressed comments
Advisory NotesNone. Validation run locally:
All completed successfully. |
|
Implemented PR-scoped fixes for the auth/workspace migration. Addressed comments
Advisory Notes
VerificationPassed locally on the current checkout:
|
|
Implemented PR-scoped fixes for #234 and revalidated locally. Changes made:
Addressed comments
Advisory Notes
VerificationPassed locally with
|
Summary
@agent-relay/cloudto^8.7.0and uses the canonical Agent Relay cloud session/workspace contract for workforce login and deploy auth.agentworkforce logina thin wrapper around the shared cloud session and canonical relay workspace key pin instead of writingactive.json/login.jsonshadow state.WORKFORCE_WORKSPACE_ID+WORKFORCE_WORKSPACE_TOKENas the explicit CI override.active.jsonno longer selects cloud URL/workspace state.References AgentWorkforce/cloud#2108 and the agreed design in cloud
docs/design/auth-unification-2108.md.Validation
npm view @agent-relay/cloud@8.7.0 version=>8.7.0pnpm installpnpm --filter @agentworkforce/deploy test✅ (197/197)pnpm --filter @agentworkforce/cli build✅pnpm --filter @agentworkforce/cli exec node --test dist/deploy-command.test.js dist/destroy-command.test.js✅ (19/19)git diff --check✅file:/Users/...package refs, noagent-relay workspace use, no.agent-relay/cloud-auth.jsoncredential path in touched CLI/deploy package sources.Known local validation caveat: full
pnpm --filter @agentworkforce/cli teststill fails inlocal-personas.testonly. I reproduced the same local-personas failure class on the untouched base branch in/tmp/workforce-auth-base-checkat74c045d, so this PR did not introduce it. CI at this PR head remains the merge gate per the cloud#2108 process.