{
  "markdown": "# Eclipse Agent Studio CLI\n\nA fast, minimal-dependency CLI for managing services, workspaces, volumes, and more on the Eclipse Agent Studio platform.\n\n[Claude Code](#claude-code) | [Gemini CLI](#google-gemini-cli) | [Codex](#openai-codex) | [CLI Only](#cli-only-linuxmacos) | [CLI Usage](#quick-start)\n\n## AI Agent Integration\n\nThe `ast` skill uses the [Agent Skills open standard](https://agentskills.io/specification)\nand works across Claude Code, Google Gemini CLI, and OpenAI Codex.\n\n### Claude Code\n\n**Plugin** (recommended — auto-installs binary + skill):\n\n```bash\n# 1. Add the marketplace (one time)\n/plugin marketplace add https://github.com/Eclipse-Space/ast-cli\n\n# 2. Install the plugin\n/plugin install ast\n```\n\nOr use `/plugin` and follow the interactive menu.\n\nThis installs the `ast` plugin, which:\n- Adds the `/ast:ast` skill to Claude Code\n- Adds the `/ast:setup` command for guided onboarding\n\nAfter installing, reload plugins to activate the new commands (no restart needed):\n\n```\n/reload-plugins\n```\n\nThen run `/setup` to get started:\n\n```\n/ast:setup\n```\n\nThis will check if you're logged in, walk you through authentication (or registration), and help you create your first workspace and server.\n\n**Standalone skill** (skill only):\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/Eclipse-Space/ast-cli/main/install-claude-skill.sh | bash\n```\n\nInstalls the binary and skill to `~/.claude/skills/ast/`.\nRun `/reload-plugins` to activate `/ast` without restarting.\n\n---\n\n### Google Gemini CLI\n\n**Extension** (recommended — includes context file + skill):\n\n```bash\ngemini extensions install https://github.com/Eclipse-Space/ast-cli\n```\n\n**Standalone skill** (skill only):\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/Eclipse-Space/ast-cli/main/install-gemini-skill.sh | bash\n```\n\nInstalls the binary and skill to `~/.gemini/skills/ast/`.\nRestart Gemini CLI to activate.\n\n---\n\n### OpenAI Codex\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/Eclipse-Space/ast-cli/main/install-codex-skill.sh | bash\n```\n\nInstalls the binary and skill to `~/.codex/skills/ast/`.\nRestart Codex to activate.\n\n---\n\n## CLI Only (Linux/macOS)\n\nFor terminal users who want the `ast` binary without AI agent integration.\n\n### One-liner (recommended)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/Eclipse-Space/ast-cli/main/install.sh | bash\n```\n\nThis downloads the pre-built binary for your platform, verifies its checksum, and installs it to `~/.local/bin/ast`.\n\nTo install to a custom location:\n\n```bash\nAST_INSTALL_DIR=/usr/local/bin curl -fsSL https://raw.githubusercontent.com/Eclipse-Space/ast-cli/main/install.sh | bash\n```\n\n### Build from source\n\nIf the one-liner doesn't work (e.g., restricted network, unsupported platform), you can build from source.\n\n**Dependencies:**\n- [git](https://git-scm.com/downloads)\n- [Rust/cargo](https://rustup.rs) — install with: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`\n\n```bash\ngit clone https://github.com/Eclipse-Space/ast-cli.git\ncd ast-cli\ncargo build --release\ncp target/release/ast ~/.local/bin/\n```\n\n## Quick Start\n\n### 1. Authenticate\n\nLog in via browser (OAuth2 PKCE flow):\n\n```bash\nast auth login\n```\n\nThis opens your browser to the Keycloak login page, captures the auth token, and stores it securely in your OS keychain.\n\nTo target a specific environment:\n\n```bash\nast auth login --env dev\nast auth login --env test\n```\n\n### 2. Verify Your Identity\n\n```bash\nast auth whoami\n```\n\n### 3. List Workspaces\n\n```bash\n# JSON output (default)\nast workspaces get\n\n# Table output\nast workspaces get --format table\n\n# Filter by organization\nast workspaces get --organization-id <ORG_ID>\n```\n\n### 4. Log Out\n\n```bash\nast auth logout\n```\n\n## Authentication Methods\n\nThe CLI supports multiple auth methods, resolved in this priority order:\n\n| Priority | Method | Usage |\n|----------|--------|-------|\n| 1 | Bearer token | `--bearer-token <TOKEN>` or `AST_BEARER_TOKEN` env var |\n| 2 | API key (CLI) | `--api-key <KEY>` or `AST_API_KEY` env var |\n| 3 | API key (config) | Stored in `~/.ast/config.yaml` |\n| 4 | Keychain token | Stored automatically after `auth login` |\n\nConfig, tokens, and upload checkpoints live under `~/.ast/` by default; set\n`AST_CONFIG_DIR` to relocate all of them (see server mode below).\n\n### Using an API Key\n\n```bash\n# Via flag\nast workspaces get --api-key <YOUR_KEY>\n\n# Via environment variable\nexport AST_API_KEY=<YOUR_KEY>\nast workspaces get\n```\n\n### Server mode — running `ast` inside a service\n\nLong-running services (the MCP gateway, the SimRunner server) subprocess `ast`\nwith injected credentials. Set this environment for every invocation so the\nCLI touches nothing outside the service's own scratch space:\n\n```bash\nAST_BEARER_TOKEN=<token>      # or AST_API_KEY — the injected credential\nAST_NO_DOTENV=1               # ignore any .env in/above the working directory\nAST_CONFIG_DIR=/scratch/ast   # config, token, and upload checkpoints go here, not $HOME\nAST_TELEMETRY_DISABLED=1      # no PostHog events, no ~2 s flush per invocation\nAST_ORGANIZATION_ID=<org>     # pin context explicitly\nAST_WORKSPACE_ID=<ws>         # pin context explicitly\n```\n\nWith this contract in place:\n\n- A stray `.env` in the service working tree cannot override the injected\n  credential (without `AST_NO_DOTENV`, `.env` values take precedence over\n  inherited environment variables by design).\n- No `~/.ast` is created or read — all state follows `AST_CONFIG_DIR`.\n- An explicit `AST_BEARER_TOKEN`/`--bearer-token` or API key never triggers\n  the OAuth refresh path, so an auth failure surfaces immediately instead of\n  reading and rewriting the stored token file. Refresh still works for\n  interactive `auth login` sessions.\n\nThese behaviors are pinned by the `tests/server_mode.rs` integration tests.\n\n## Environments\n\n| Name | Flag | API |\n|------|------|-----|\n| Production (default) | `--env prod` | `api.studio.eclipse.space` |\n| Staging | `--env staging` | `api.studio.staging.eclipse.space` |\n| Dev | `--env dev` | `api.studio.dev.eclipse.space` |\n\n## Commands\n\n```\nast auth login       Log in via browser (OAuth2 PKCE)\nast auth logout      Clear stored credentials\nast auth whoami      Show current user info\nast workspaces get   List workspaces\nast secrets get      List secrets (metadata only)\nast secrets create   Create a secret\nast secrets edit     Change a secret's value or workspace exposure\nast secrets delete   Delete a secret\nast rules get-*      Show platform/organization/workspace/service/user rules\nast rules edit-*     Replace organization/workspace/service/user rules\n```\n\nFurther command groups: `organizations`, `members`, `volumes`, `volume-data`,\n`services`, `skills`, `servers`, `mcp-servers`, `api-keys`, `rules`, `schema`.\nRun `ast <group> --help` for details.\n\n## Volume Data\n\n```bash\n# Upload a file (multipart + resumable above 50 MiB; re-run after an\n# interruption to resume from the last completed part)\nast volume-data upload --volume-id <VOL_ID> --file ./results.zip --key results/results.zip\n\n# Download files — nested keys work, content is streamed to disk. Since\n# 0.1.4 the key's directory structure is preserved under --output-dir\n# (this example writes ./results/sim-runner/jobs/<SIM_ID>/results/out.bin);\n# pass --flat for the pre-0.1.4 layout (./results/out.bin)\nast volume-data download --volume-id <VOL_ID> \\\n  --keys sim-runner/jobs/<SIM_ID>/results/out.bin --output-dir ./results\n\n# Presign for external tools — bare URL(s) on stdout with --format table\n# (URLs expire after 24 h; for multipart sizes the part URLs print one per\n# line with uploadId/partSize on stderr); --format json returns the full\n# contract, including multipart part URLs + uploadId for large presigned\n# uploads\naria2c -x16 \"$(ast volume-data presign --volume-id <VOL_ID> --key results/out.bin --format table)\"\n\n# Register an object uploaded via presigned PUT (uploads via\n# `ast volume-data upload` finalize automatically)\nast volume-data finalize --key results/out.bin\n```\n\n## Skills\n\n```bash\n# Download a skill's package archive\nast skills download --skill-id <SKILL_ID>                    # → ./<name>.zip\nast skills download --skill-id <SKILL_ID> --output pkgs/     # → pkgs/<name>.zip\nast skills download --skill-id <SKILL_ID> --output my.zip    # exact path\n```\n\n**Package-fetch contract** (for consumers mirroring this operation, e.g. the\nMCP gateway's `load_skill`):\n\n- The operation is the `getSkillDownload(skillId)` GraphQL query, returning\n  `{ skillId, name, url }`. The `url` is a presigned HTTPS GET valid for\n  **24 hours** (`X-Amz-Expires=86400`), same TTL as volume-data presigns.\n- The `s3Url` field on `getSkills` is an `s3://` storage locator and **cannot\n  be fetched directly** — always go through `getSkillDownload`.\n- The archive is a **zip** with `SKILL.md` at the root (the Agent Skills\n  package layout used by `skills create`/`replace-package`).\n\n## Persistent Services\n\nPersistent services are long-running solver/tool instances that cache state\nbetween jobs. Jobs queue even when the service is stopped — the platform\nauto-starts a stopped service that has queued jobs.\n\n```bash\n# List services / inspect one (detail shows the tools it exposes)\nast persistent-services get --workspace-id <WS_ID> --format table\n\n# Submit a job — the payload is {\"tool\": ..., \"inputs\": {...}}; volume paths\n# use the volume UUID and each volume is declared with --volumes\nast persistent-services jobs create \\\n  --persistent-service-id <PS_ID> \\\n  --volumes <VOLUME_UUID> \\\n  --payload '{\"tool\": \"no_solve\", \"inputs\": {\"project_file\": \"/workspace/volumes/<VOLUME_UUID>/in.aedt\"}}'\n\n# Poll status (single-shot; JSON output is the job object — check .completedAt;\n# terminal jobs carry presigned log/result URLs, ~24 h expiry — re-run for\n# fresh links)\nast persistent-services jobs status --ps-job-id <PS_JOB_ID>\n\n# Lifecycle + queue management\nast persistent-services start|stop|restart --persistent-service-id <PS_ID>\nast persistent-services jobs cancel --ps-job-id <PS_JOB_ID>\n```\n\n## Secrets\n\nSecrets are environment variables injected into your servers — the place to put\nAPI keys and tokens rather than committing them to a repo.\n\n**Values are write-only.** The platform never returns a secret's value, so\n`ast secrets get` lists names and scope only. There is no command to read a\nvalue back; if you lose it, replace it with `ast secrets edit`.\n\n### Creating a secret\n\nPass the value on stdin, from a file, or let the CLI prompt you:\n\n```bash\n# From stdin (recommended — keeps the value out of shell history)\necho -n 'sk-abc123' | ast secrets create --name OPENAI_API_KEY \\\n  --value-stdin --workspace-id <WORKSPACE_ID>\n\n# From a file — use this for multi-line values such as a PEM key\nast secrets create --name GITHUB_APP_PRIVATE_KEY \\\n  --value-file ./private-key.pem --workspace-id <WORKSPACE_ID>\n\n# Prompt for the value (hidden input)\nast secrets create --name OPENAI_API_KEY --workspace-id <WORKSPACE_ID>\n```\n\n`--value <VALUE>` also works, but the value is then visible in your shell\nhistory and in the process list on shared machines. Prefer the options above.\n\nA trailing newline is stripped from `--value-stdin` and `--value-file`, so\n`echo` without `-n` behaves as expected.\n\n### Where a secret is visible\n\nEvery secret needs somewhere to be exposed — pass one of:\n\n| Flag | Effect |\n|------|--------|\n| `--workspace-id <ID>` | Expose to that workspace. Repeat for several. |\n| `--all-workspaces` | Expose to every workspace in the organization. |\n\nNames are scoped per workspace, not per organization, so the same name can exist\nin two workspaces as two independent secrets. Rotating one does not update the\nother.\n\n### Bulk import\n\n```bash\nast secrets create --env-file .env --workspace-id <WORKSPACE_ID>\n```\n\nOne secret per `KEY=VALUE` line. Blank lines, `#` comments, a leading `export `,\nand quoted values are handled; for unquoted values a trailing ` # comment` is\nstripped, and if a key repeats the last occurrence wins.\n\n**Multi-line values are not supported here** — a PEM key spanning several lines\nis rejected rather than truncated. Create those individually with `--value-file`.\n\n### Editing and deleting\n\n```bash\n# Replace the value\necho -n 'sk-new' | ast secrets edit --secret-id <SECRET_ID> --value-stdin\n\n# Re-scope without touching the value\nast secrets edit --secret-id <SECRET_ID> --workspace-id <WORKSPACE_ID>\n\n# Delete (prompts for confirmation in an interactive terminal)\nast secrets delete --secret-id <SECRET_ID>\nast secrets delete --secret-id <SECRET_ID> --yes   # skip the prompt\n```\n\nEditing cannot rename a secret — delete it and create it again under the new\nname.\n\n## Rules\n\nRules are markdown documents that shape how agents behave. They are compiled\ninto the agent's context when a session starts.\n\n**Hierarchy** (broadest → most specific, more specific overrides broader):\norganization → user → service → workspace.\n\n### Reading rules\n\n```bash\nast rules get-organization --organization-id <ORG_ID>\nast rules get-workspace --workspace-id <WORKSPACE_ID>\nast rules get-service --service-id <SERVICE_ID>\nast rules get-user\nast rules get-platform\n\n# Print the markdown itself rather than the JSON envelope\nast rules get-workspace --workspace-id <WORKSPACE_ID> --format table\n```\n\n### Writing rules\n\nEach `edit-*` subcommand takes the markdown from **either** `--rules` or\n`--rules-file` — exactly one, never both:\n\n```bash\n# From a file (easiest for a whole document)\nast rules edit-organization --organization-id <ORG_ID> --rules-file rules.md\n\n# Inline\nast rules edit-workspace --workspace-id <WORKSPACE_ID> --rules '# Rules\n\nPrefer small commits.'\n```\n\nThe content is sent **literally**. It is not parsed as JSON, so markdown,\nbackticks, and quotes need no escaping — do *not* pre-encode with `jq -Rs .`,\nor the quotes and `\\n` escapes will be stored as literal characters.\n\nA single trailing newline is stripped from `--rules-file`, so\n`--rules-file x.md` and `--rules \"$(cat x.md)\"` send identical content.\n\n**`edit-*` replaces the whole document**, it does not append. Read the current\nrules first if you mean to extend them:\n\n```bash\nast rules get-workspace --workspace-id <WS_ID> --format table > rules.md\n# edit rules.md\nast rules edit-workspace --workspace-id <WS_ID> --rules-file rules.md\n```\n\nEmpty rules are rejected, so a write cannot silently blank out the document\nagents rely on.\n\n## Global Options\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| `--format <json\\|table>` | Output format | `json` |\n| `--env <ENV>` | Target environment | `prod` |\n| `--api-key <KEY>` | API key | — |\n| `--bearer-token <TOKEN>` | Bearer token | — |\n| `-v, --verbose` | Enable verbose logging | off |\n\n## Configuration\n\nConfig is stored at `~/.ast/config.yaml`:\n\n```yaml\napikey: <your-api-key>\nenvironment: <last-used-auth-url>\n```\n\n## License\n\nMIT\n",
  "bytes": 14850,
  "sha": "cab0a5de7ac081b4d3022d2a0feafb7b4a31cb7af8eccaabab35b0067056f87d",
  "repo_slug": "eclipse-space/ast-cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_eclipse_space_ast_cli_f76f5242/readme"
}