test: CLI integration test suite with JWT agent support (TC-001–TC-028)#334
Closed
m-golovchin wants to merge 80 commits into
Closed
test: CLI integration test suite with JWT agent support (TC-001–TC-028)#334m-golovchin wants to merge 80 commits into
m-golovchin wants to merge 80 commits into
Conversation
Dark-Sun
reviewed
Jun 5, 2026
Dark-Sun
approved these changes
Jun 8, 2026
15f80e0 to
4a9cd33
Compare
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Guard against missing env vars and bad HTTP status in fetchJwtToken; fix waitForOutput race condition (always reject on close), add stdout null guard, and wrap SIGTERM/SIGKILL in try/catch for already-dead processes. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ture Adds a dedicated Vitest config for agent integration tests with a globalSetup that builds dist/ once per session, plus two new npm scripts for targeted test runs. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Replace deprecated `poolOptions.threads.maxThreads/minThreads` with top-level `maxWorkers: 4` as required by Vitest 4. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…file) Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Refactor TC-003 describe block to call spawnSync once in beforeAll and reuse the cached result in both it blocks, eliminating duplicate CLI invocations. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Replace the 2-test stub with a comprehensive suite covering profile list, switch, delete (inactive + active), rename, status with no profiles, and negative paths (switch/rename to non-existent/conflicting names). Key implementation notes: - runCLI sets cwd=codemieHome so no local .codemie/ config interferes - NODE_ENV=test disables CLI auto-update during subprocess invocations - CODEMIE_DEBUG=true surfaces logger.error() messages to stderr for negative-path assertions - TC-006 uses 'profile' list (not 'profile status') to avoid auth prompts in non-TTY environments - TC-008 assertions updated to match actual CLI behaviour: deleting the active profile succeeds with "No profiles remaining" rather than erroring Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Refactored TC-006, TC-007, and TC-009 describe blocks so that the profile switch, delete, and rename CLI calls are executed once in beforeAll and their results stored, eliminating inter-it side-effect dependencies. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Extends skills.test.ts with two JWT-gated describe blocks: - TC-012: full add/list/remove/list lifecycle against a real marketplace source - TC-013: error-path validation for a nonexistent skill source Both suites are skipped unless INCLUDE_JWT_TESTS=true is set. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Adds integration test for 'codemie models list' guarded behind INCLUDE_JWT_TESTS, caching the spawnSync result in beforeAll to avoid double invocation. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Add agent-jwt-basic.test.ts covering JWT token auth flows, invalid token negative cases, missing profile/token negative case, and agent health check. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Replace the credential-leaking cleanEnv() implementation (which copied full process.env and deleted 2 keys) with a minimal allowlist that only passes through PATH and NODE_PATH, preventing accidental credential exposure in child processes. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…rge TC-015 its Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…tderr guards Add ?? '' fallbacks to PATH/NODE_PATH in cleanEnv() and guard all result.stdout + result.stderr concatenations with nullish coalescing. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Implements TC-020 (session model matches profile model for sonnet and haiku) and TC-021 (all three tier models populated and distinct) under describe.runIf(INCLUDE_JWT_TESTS). Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Implements interactive agent session tests: /model slash-command switch (TC-024), skill slash-command invocation in a running session (TC-025), and non-interactive assistant chat PONG assertion (TC-026). All gated under INCLUDE_JWT_TESTS=true and skip cleanly without credentials. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Add combined stdout+stderr as the Vitest failure message on the exit-code assertion in TC-028 so CI shows what the agent printed when the test fails. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Add a beforeAll guard that throws a clear error when CI_CODEMIE_ASSISTANT_ID is absent, preventing the empty-regex assertion from silently passing. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Add an early-exit guard in TC-026's beforeAll that throws a descriptive error when assistantId is empty, preventing a confusing CLI failure and ensuring a clean skip when INCLUDE_JWT_TESTS=true but the env var is absent. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
4a9cd33 to
0669d4c
Compare
- Add agent JWT integration tests (TC-001–TC-028) for basic, budget, models, and interactive flows - Add PTY session helper, metrics helper, and JWT auth helper for integration test infrastructure - Add JWTModelProxy to bearer-auth provider for `models list` support - Add --jwt-token option to assistants chat command - Add load-test-env setup and env.test.local.example for local test configuration - Exclude agent/JWT integration tests from lint-staged pre-commit vitest run - Skip egress-shim exit-code tests on Windows (NODE_OPTIONS --require causes access violation) - Increase error-handling test beforeAll timeout to 30s for concurrent load - Fix TC-014, TC-022, TC-024, TC-026 guards for missing CI env vars Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Documents the test tier strategy, authentication approach, and TC-001–TC-028 test case catalogue for the JWT/agent integration tests. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The waitFor timeout already includes last 20 PTY lines in the error message; the pty-debug.txt write was redundant and deleted by afterAll. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…lifecycle Extract TC-025 into agent-skills.test.ts with SSO/JWT dual-mode auth. Dynamically create and delete the test skill via SDK (createSkill/deleteSkill) instead of relying on a static CI_CODEMIE_SKILL_NAME env var. TC-024 is now standalone in agent-interactive-session.test.ts. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Rename reflects the file's actual scope (TC-024 /model switch test only). Update header comment, outer describe label, temp dir prefix, and vitest config. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ent-model-switch Rename agent-model-switch.test.ts to agent-model.test.ts and absorb TC-020 and TC-021 from agent-jwt-models.test.ts. Both tests converted from JWT-only (INCLUDE_JWT_TESTS gate) to SSO/JWT dual-mode via CI_IS_LOCAL_RUN. Adds writeProfileWithModel() helper for model-specific SSO/JWT profiles. Also fixes TC-020's missing haikuHome cleanup in afterAll. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Remove INCLUDE_JWT_TESTS gate, add CI_IS_LOCAL_RUN dual-mode support. Fix __dirname to use fileURLToPath. Add stdout/stderr to exit-code failure message for easier debugging. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Move codemie-claude health check out of the JWT-only agent-jwt-basic gate into a standalone cli-commands/health.test.ts file. The health subcommand requires no auth, so the test runs unconditionally without any SSO/JWT setup. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ofile test - agent-task.test.ts: converts TC-016 to SSO/JWT dual-mode; asserts --task exits 0 and agent response appears in stdout (non-interactive output path not covered by PTY tests) - agent-jwt-token.test.ts: new TC-027, JWT-only; tests --jwt-token with no pre-written profile and empty CODEMIE_HOME; skipped label in describe name makes the reason visible in test output - agent-jwt-basic.test.ts: remove TC-016 (now in agent-task.test.ts) - vitest.agent.config.ts: update file list comment with TC references Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Move negative agent test cases out of the INCLUDE_JWT_TESTS gate into a dedicated file. TC-018 (invalid JWT token) stays JWT-only with a skip label; TC-019 (no profile/no auth) is converted to dual-mode since an empty CODEMIE_HOME fails the same way in both SSO and JWT modes. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…verride Replace the simple profile+token run in TC-017 with a more meaningful test: write a config with an SSO profile as active and a JWT profile as non-active, then run with --profile <jwt> --jwt-token <token> to verify that both the active profile and the auth method are overridden by the CLI flags. TC-017 and TC-027 are now both in agent-jwt-token.test.ts. agent-jwt-basic is deleted — all its tests have moved to purpose-specific files. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
The provider field in the session comes from the profile config, not from the --jwt-token flag at runtime. Restoring bearer-auth on profile-jwt-override makes the session provider the observable proof that both --profile and --jwt-token overrides worked: bearer-auth confirms the non-active profile was selected and SSO was not used. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Remove the original May 2026 spec files (2026-05-19 and 2026-05-27) and replace with a current design document that reflects the dual-mode auth model (CI_IS_LOCAL_RUN), the updated file layout, the full TC map, and the SSO/PTY helper layer added during this branch. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
codemie has no 'health' subcommand and codemie-claude health requires the claude binary to be installed, which fails in CI. TC-031 is retired; existing doctor, list, and version tests cover no-auth CLI smoke checks. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
cli-commands/models.test.ts used hybrid auth (SSO + JWT) which doesn't belong in the no-auth cli-commands suite. Move TC-022 into agent-model.test.ts alongside the other dual-mode model tests (TC-020/021/024). Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
- Replace vitest.config.ts + vitest.agent.config.ts with a single defineConfig/defineProject workspace (unit, cli, agent projects) - Add test:run (unit+cli), test:all (unit+cli+agent sequential) scripts - Remove test:e2e (no e2e tests exist), deduplicate test:all entry - Fix TC-019: add cwd:testHome to spawnSync so ConfigLoader does not pick up .codemie/codemie-cli.config.json from the repo root - Remove agent test steps from CI pipeline (unit+cli only in pipeline) - Update agent-task-session.test.ts run comment to use npm script Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
- TC-029 (agent-setup): SSO setup wizard PTY test — walks the full interactive wizard, creates a profile, and verifies the written config - TC-030 (self-update): verify --check exits 0 and reports current version - pty-session: waitFor and onData now also check the incomplete tail line so input prompts (which never emit a trailing \n) are detectable - spec: add TC-030 row and self-update.test.ts to directory layout Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
… in agent integration tests Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Remove per-file setupSsoAutotestProfile/teardownSsoAutotestProfile calls from agent-model.test.ts outer beforeAll/afterAll. The global setup in agent-build-setup.ts already owns the full SSO profile lifecycle; the per-file calls write to ~/.codemie/codemie-cli.config.json concurrently with other workers that use ~/.codemie directly, causing a race condition that prevents TC-020/TC-021 from writing metrics in parallel runs. Also quote the engine binary path in validate-secrets.js to handle paths with spaces on Windows. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
When -y/--yes is supplied the action computed interactive=false but did not forward it to runSkillsCli, which defaulted to interactive=true. In interactive mode the close handler calls process.stderr.write on the buffered stderr, which raises EPIPE when the parent process has a piped stderr (e.g. integration test spawnSync). The uncaught write error caused Node to exit with code 1 instead of propagating the real upstream exit code. Fix: pass interactive to runSkillsCli so non-interactive runs use piped stdio and avoid the write. Also forward result.stderr explicitly in non-interactive failure paths so egress-blocked and other markers are still visible to the caller's stderr stream. Generated with AI Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Owner
|
[AUTO_CLOSE_WARNING] 🔒 This pull request was automatically closed after being older than 30 days with no activity. Contact maintainers to reopen if needed. |
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.
Summary
This PR introduces a comprehensive integration test suite for the CodeMie Code CLI, covering CLI management commands, SSO/JWT-authenticated agent sessions, interactive PTY sessions, and budget/model queries (TC-014 through TC-028). It also includes the minimal production code changes required to make those test scenarios work end-to-end.
Production Source Code Changes
1.
src/utils/auth.ts— JWT branch ingetAuthenticatedClientWhat: Added a JWT-specific code path at the top of
getAuthenticatedClient. Whenconfig.authMethod === 'jwt', the function reads the token from the configured env var (defaulting toCODEMIE_JWT_TOKEN) or fromconfig.jwtConfig.token, constructs anAuthConfigwithtokenGetter: async () => token, and instantiates all SDK services, composing them into aCodeMieClient-shaped object.Why:
getAuthenticatedClientwas SSO-only. Any CLI command that called it would attempt a browser-session cookie flow and fail in CI environments that only carry a JWT token.Why this approach: The
tokenGetterpattern was already in use insrc/cli/commands/assistants/chat/index.ts. Adopting it inauth.tsfollows established codebase precedent. The JWT branch only executes whenauthMethod === 'jwt', leaving the entire SSO path untouched.2.
src/cli/commands/assistants/chat/index.ts+types.ts—--jwt-tokenflag onassistants chatWhat: Added
--jwt-token <token>as a Commander option. When the flag (orCODEMIE_JWT_TOKENenv var) is present, the command builds a minimalAssistantService-only client inline withtokenGetter, bypassinggetAuthenticatedCliententirely.3.
src/providers/plugins/jwt/jwt.models.ts+index.ts—JWTModelProxyWhat: New class
JWTModelProxyimplementingProviderModelFetcher. Registers itself against thebearer-authprovider socodemie models listworks for JWT users (TC-022).4.
src/cli/commands/models.ts— Removebearer-authfromUNSUPPORTED_PROVIDERSWhat: Removed
'bearer-auth'from theUNSUPPORTED_PROVIDERSset. Required alongsideJWTModelProxyso the guard no longer exits early for JWT profiles.5.
src/providers/plugins/jwt/jwt.template.ts—agentHooksfor extension install and--plugin-dirWhat: Added
agentHooksblock with*.beforeRun(installs CodeMie extension) andclaude.enrichArgs(injects--plugin-dir). JWT profiles were missing the extension-install wiring the SSO template already had.6.
src/utils/config.ts—CODEMIE_HOMErespected inloadAssistantsByScopeWhat: Changed global-scope base directory from
os.homedir()toprocess.env.CODEMIE_HOME ?? os.homedir()so integration tests using isolated temp dirs see test-injected assistant configs instead of the developer's real ones.7.
src/utils/errors.ts— Guard against emptywrapTextresult informatErrorForUserWhat: Added a guard so an empty
wrapTextresult falls back tocontext.error.message || '(unknown error)'instead of printingundefined.8.
src/env/types.ts—authServerUrlandauthRealmonProviderProfileWhat: Added two optional fields to
ProviderProfilefor potential future use.Test Infrastructure
Auth model —
CI_IS_LOCAL_RUNdual-modeTests gate on the
CI_IS_LOCAL_RUNenv flag:true(default)sso-autotestprofile in~/.codemiefalseCI_CODEMIE_AUTH_URLIntegration test files
agent-task.test.ts--taskexit code and stdoutagent-task-session.test.tsagent-model.test.tsmodels list,/modelPTYagent-skills.test.tsagent-assistant.test.tsagent-jwt-token.test.ts--profile+--jwt-tokenoverride [JWT-only]agent-jwt-budget.test.tsagent-negative.test.tsagent-shortcuts.test.tscli-commands/*.test.tsTest helpers
tests/helpers/jwt-auth.tsfetchJwtToken(),writeJwtProfile(),jwtCleanEnv()tests/helpers/sso-auth.tswriteSsoProfile(),ssoCleanEnv(),copySsoCredentials(), setup/teardowntests/helpers/pty-session.tsnode-ptyfor interactive session testingtests/helpers/metrics.tsgetLatestMetricsRecord()helpertests/helpers/test-env.tsgetTestEnvFlagOrDefault()tests/helpers/session-poll.tspollForSession()with timeoutTest setup / config
tests/setup/load-test-env.ts.env.test.localbefore each test filetests/setup/agent-build-setup.tsnpm run build, claude install, SSO credential validation with auto-loginenv.test.local.exampleVitest workspace config
vitest.config.tsusesdefineConfig+defineProjectto define three named projects in a single file:unitsrc/**/*.test.tsclitests/integration/**/*.test.ts(excl.agent-*)agenttests/integration/agent-*.test.tsagent-build-setup.ts(build + SSO auth)npm scripts
npm run test:unitnpm run test:integrationnpm run test:integration:clinpm run test:integration:agentnpm run test:runnpm run test:allTest Plan
npm run test:unit— all unit tests pass (no credential requirement)npm run test:integration:cli— CLI management tests pass (no credential requirement)sso-autotestprofile in~/.codemieor run — credentials are auto-validated and browser login is triggered if expired.env.test.localperenv.test.local.examplewithCI_IS_LOCAL_RUN=falseand JWT credentialsnpm run test:integration:agent— agent tests pass against a live CodeMie environment