Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 89 additions & 16 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,116 @@

## Project scope

Codex CLI Launcher is an unofficial VS Code extension. It creates a side terminal and launches a user-configured Codex CLI command. Keep the extension small, cross-platform, and explicit about its unofficial status.
Codex CLI Launcher is an unofficial VS Code extension published to the Visual Studio Marketplace and Open VSX as `mikesoft.vscode-codex-cli-launcher`. It creates a side terminal and launches a user-configured Codex CLI command. Keep the extension small, cross-platform, and explicit about its unofficial status.

The repository is public and MIT licensed. Assume every change, comment, and commit message is world-readable.

## Stack and runtime

- TypeScript compiled with the repository-local `typescript` compiler to CommonJS-compatible `NodeNext` output under `out/`.
- `npm` with the committed `package-lock.json` is the only supported package manager. Do not introduce a second lockfile or package manager.
- Node.js 22 or newer. CI runs Node 22 on `windows-latest` and `ubuntu-latest`.
- Minimum supported editor is VS Code `^1.103.0`. `@types/vscode` is pinned to exactly `1.103.0` so the compiler cannot accept APIs that do not exist on the declared floor.
- There is no linter or formatter. `.editorconfig` (LF, UTF-8, two-space indent, final newline) plus `tsc` in `strict` mode with `noUnusedLocals` and `noUnusedParameters` are the only static checks.

## Architecture

- `src/extension.ts` owns VS Code API integration, terminal lifecycle, workspace-trust checks, settings, and user messages.
- `src/command-utils.ts` contains pure command, naming, output-buffer, and workspace-resolution helpers. Put testable logic here instead of embedding it in activation handlers.
- `test/*.test.js` contains unit, metadata, packaging, and security-invariant tests.
- `test/integration/` runs the extension in the minimum supported VS Code release by default.
- `out/`, `.vscode-test/`, and `*.vsix` are generated locally and must not be committed.
- `src/command-utils.ts` contains pure command, naming, output-buffer, launch-session, and workspace-resolution helpers. Put testable logic here instead of embedding it in activation handlers.
- `test/*.test.js` contains unit, metadata, packaging, lifecycle, and security-invariant tests. They run against compiled `out/`, so compile before running them directly.
- `test/integration/` runs the extension in the minimum supported VS Code release by default. Override with `VSCODE_TEST_VERSION`.
- `docs/` holds maintainer documentation and is excluded from the VSIX.
- `media/` holds the packaged Marketplace and toolbar artwork.

## Repository structure

```
.github/ workflows, issue forms, PR template, CODEOWNERS, funding
docs/ architecture and release documentation (not packaged)
media/ icon.png (Marketplace) and launcher-mark.svg (toolbar)
src/ extension.ts and command-utils.ts
test/ unit and metadata tests plus the VS Code integration suite
out/ generated compiler output (never edit, never commit)
```

## Commands

## Setup and verification
| Purpose | Command |
| --- | --- |
| Install | `npm ci` |
| Compile and type-check | `npm run compile` |
| Watch | `npm run watch` |
| Unit tests | `npm run test:unit` |
| Integration smoke test | `npm run test:integration` |
| All tests | `npm test` |
| Full validation (compile, tests, integration, packaged file list) | `npm run check` |
| Dependency audit | `npm run audit` |
| Build the VSIX | `npm run package` |

- Use Node.js 22 or newer and npm with the committed `package-lock.json`.
- Install reproducibly with `npm ci`.
- Run `npm run check` after source, manifest, workflow, documentation, or packaging changes.
- Run `npm run audit` after changing dependencies or the lockfile.
- Run `npm run package` for release-facing changes and inspect the packaged file list.
There is no dev server, no deploy step, and no publish script. Publishing is a manual maintainer action through `vsce` and `ovsx`; see `docs/releasing.md`.

## Launch lifecycle

Only `activate` may register on `context.subscriptions`: the two commands and the terminal-close listener. VS Code releases that array on deactivation only, so anything pushed per launch would accumulate for the whole session.

Every launch instead creates a disposal scope with `createLaunchSession`. Register launch-scoped listeners and timers on that scope. A scope ends when the command finishes, when the fallback `sendText` path runs, or when its terminal closes; `deactivate` drains whatever is left.

## Security invariants

- Never download or install Codex CLI, generate installer scripts, or invoke Node child-process APIs. A missing default CLI may only offer the official documentation link.
- Never execute a command sourced from workspace settings. `cliCommand` must remain machine-scoped and resolved from user-level configuration.
- Require a trusted workspace before creating a terminal or sending a command.
- Treat `cliCommand` as an intentional shell command, preserve quoted executable paths, and do not silently rewrite it.
- Keep shell-output capture bounded and limited to the missing-Codex detection path. Do not log terminal output or add telemetry.
- Keep shell-output capture bounded and limited to the missing-Codex detection path. Custom commands must not have their output read at all. Do not log terminal output or add telemetry.
- `src/extension.ts` must contain exactly one external URL, the official Codex CLI documentation link. Tests enforce this.
- Do not add official OpenAI or Codex logos or imply endorsement.

## Environment variables and secrets

The extension reads no environment variables at runtime. `VSCODE_TEST_VERSION` only selects the VS Code build used by the integration test.

Marketplace and Open VSX tokens (`VSCE_PAT`, `OVSX_PAT`) belong to the maintainer's local environment. Never commit them, never echo them, never add them to workflows, issue comments, or release notes. No repository secret is required by any workflow in this repository.

## Generated and protected files

- `out/`, `.vscode-test/`, and `*.vsix` are generated locally and must not be committed or edited.
- `package-lock.json` is maintained by npm. Change it only through npm commands.
- `media/icon.png` and `media/launcher-mark.svg` are hand-authored published artwork. Do not regenerate, redraw, recolor, resize, rename, or move them, and do not add a script that writes to `media/`. Optimizing byte size is acceptable only when the rendered result, dimensions, transparency, format, and paths are preserved exactly.

## Compatibility rules

- No breaking changes. Setting ids, command ids, the publisher, and the extension name are part of the installed user's configuration and must stay stable.
- Do not raise `engines.vscode` without a real API requirement, and keep `@types/vscode` equal to that floor.
- Verify behavior on both Windows and POSIX shells when command parsing or terminal execution changes.
- Keep the version synchronized across `package.json`, `package-lock.json`, `CITATION.cff`, `README.md`, `CHANGELOG.md`, and `test/metadata.test.js`.

## Change conventions

- Keep changes focused and add regression tests for behavior changes.
- Update `README.md` for user-visible behavior and `CHANGELOG.md` under `Unreleased` for notable changes.
- Keep the version synchronized across `package.json`, `package-lock.json`, `CITATION.cff`, and release-facing documentation when preparing a release.
- Pin GitHub Actions to full commit SHAs and grant only the permissions each workflow needs.
- Use concise conventional commit subjects. Do not publish, tag, push, or create a release unless the maintainer explicitly requests it.
- Use concise conventional commit subjects.

## Validation criteria

Before proposing a change:

1. `npm ci`
2. `npm run check` after any source, manifest, workflow, documentation, or packaging change
3. `npm run audit` after any dependency or lockfile change
4. `npm run package` for release-facing changes, then inspect the file list and confirm that sources, tests, workflows, `AGENTS.md`, source maps, and local artifacts stay out of the VSIX

Do not disable, skip, or weaken a test to make validation pass.

## Code review rules

- Flag any path that can bypass workspace trust, accept repository-controlled commands, execute installers, or expose terminal output.
- Verify behavior on Windows and POSIX shells when command parsing or terminal execution changes.
- Treat packaged-file changes as release changes: confirm that sources, tests, agent instructions, and local artifacts stay out of the VSIX.
- Flag any disposable registered on `context.subscriptions` outside `activate`.
- Treat packaged-file changes as release changes.

## Instructions for AI agents

- `main` is protected: it requires a pull request, one approving review, passing `validate (ubuntu-latest)` and `validate (windows-latest)` checks, and linear history. Never push to `main` directly, never force push, never rewrite history, and never approve or merge your own pull request.
- Do not publish, tag, or create a release unless the maintainer explicitly requests it. The published Marketplace and Open VSX versions must always match the tag, `package.json`, and `CHANGELOG.md`.
- Do not delete files under `media/`, `docs/`, or `.github/` without an explicit request.
- Report what you actually ran and what actually happened. Do not claim a published release you did not perform.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

## [Unreleased]

## 0.1.9 - 2026-08-01

### Fixed

- Scoped every launch to its own disposal unit, so launch-scoped listeners and the shell-integration fallback timer are released when the launch completes or its terminal closes. They were previously appended to the extension subscription list on every launch and only released on deactivation, so repeated launches grew that list without bound.
- Stopped reading terminal shell output for custom CLI commands. Output was still buffered for every launch even though only the Codex missing-CLI check consumes it, which did not match the documented invariant.

### Added

- Unit tests for the launch disposal scope and source-level regression tests for the extension activation lifecycle.

### Changed

- Moved the launch disposal scope into `src/command-utils.ts` so it is covered by unit tests instead of only by the integration smoke test.
- Documented the launch lifecycle in `docs/architecture.md` and `AGENTS.md`.

### Removed

- Removed the unused `scripts/generate-icon.js` placeholder generator and its `generate:icon` script. It had no callers and overwrote the published `media/icon.png` with a different placeholder image. The published artwork is unchanged.

## 0.1.8

### Changed
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ authors:
- family-names: Gasperini
given-names: Michael
url: "https://github.com/TheStreamCode/codex-cli-launcher"
version: "0.1.8"
version: "0.1.9"
license: MIT
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Codex CLI Launcher is an unofficial VS Code extension that opens OpenAI Codex CL

Works on Windows, macOS, and Linux where Codex CLI is available to the integrated terminal.

Current release: `0.1.8`.
Current release: `0.1.9`.

> **Disclaimer**
> This extension is unofficial and is not affiliated with, endorsed by, sponsored by, or approved by OpenAI. "OpenAI", "Codex", and related names are trademarks of their respective owners.
Expand Down
10 changes: 9 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ Codex CLI Launcher is intentionally a small extension with two production module
4. The extension creates a side terminal and executes the command through terminal shell integration when available, falling back to `sendText` after a short wait.
5. For Codex executables only, the extension inspects a bounded window of shell output. If the executable is missing, it offers the official documentation link.

## Launch lifecycle

Each launch owns a disposal scope created by `createLaunchSession`. The scope holds the shell-integration listener, the fallback timer, and the shell-execution listener for that launch only.

A scope ends when its command finishes, when the fallback path sends the command without shell integration, or when its terminal closes. `deactivate` drains any scope that is still open.

Only `activate` registers on `context.subscriptions`: the two commands and the terminal-close listener. VS Code releases that array on deactivation only, so per-launch resources must never be added to it.

## Trust boundaries

- Workspace files are untrusted input. They must not control `cliCommand` or bypass the workspace-trust gate.
- The configured CLI command is trusted user intent and is sent to the integrated shell. The launcher does not parse arguments into a child process.
- Terminal output can contain sensitive data. It is never logged or transmitted, is not collected for custom commands, and is bounded while checking for a missing Codex executable.
- Terminal output can contain sensitive data. It is never logged or transmitted, is never read for custom commands, and is bounded while checking for a missing Codex executable.
- Network access is limited to opening the official Codex CLI documentation at the user's request. The extension does not make background requests.

## Packaging
Expand Down
2 changes: 1 addition & 1 deletion docs/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Releases are maintainer-only and should start from a clean, up-to-date `main` br
## Prepare

1. Choose a semantic version and move relevant entries from `Unreleased` into that version in `CHANGELOG.md`.
2. Synchronize the version in `package.json`, `package-lock.json`, `CITATION.cff`, `README.md`, and any other release-facing documentation.
2. Synchronize the version in `package.json` and `package-lock.json` with `npm version <x.y.z> --no-git-tag-version`, then update `CITATION.cff`, `README.md`, the version assertion in `test/metadata.test.js`, and any other release-facing documentation.
3. Run `npm ci`, `npm run check`, and `npm run audit`.
4. Run `npm run package` and inspect the VSIX file list. Confirm that source, tests, workflows, `AGENTS.md`, and local artifacts are absent.
5. Install the generated VSIX in a clean VS Code profile and smoke-test launching, settings, workspace trust, and the missing-CLI documentation prompt.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"displayName": "Codex CLI Launcher — Run OpenAI Codex in a Side Terminal",
"description": "Launch the OpenAI Codex AI coding agent in a side terminal from your editor toolbar. Unofficial; works in VS Code, Cursor & Windsurf on Windows, macOS & Linux.",
"publisher": "mikesoft",
"version": "0.1.8",
"version": "0.1.9",
"repository": {
"type": "git",
"url": "https://github.com/TheStreamCode/codex-cli-launcher.git"
Expand Down Expand Up @@ -113,8 +113,7 @@
"vscode:prepublish": "node ./node_modules/typescript/bin/tsc -p . --pretty false",
"package": "node ./node_modules/@vscode/vsce/vsce package",
"audit": "npm audit --audit-level=high",
"check": "node ./node_modules/typescript/bin/tsc -p . --pretty false && node --test test/*.test.js && node ./test/integration/runTest.js && node ./node_modules/@vscode/vsce/vsce ls",
"generate:icon": "node ./scripts/generate-icon.js"
"check": "node ./node_modules/typescript/bin/tsc -p . --pretty false && node --test test/*.test.js && node ./test/integration/runTest.js && node ./node_modules/@vscode/vsce/vsce ls"
},
"devDependencies": {
"@types/node": "^22.20.1",
Expand Down
97 changes: 0 additions & 97 deletions scripts/generate-icon.js

This file was deleted.

Loading
Loading