Skip to content

Conversation

@purpleskulll
Copy link

@purpleskulll purpleskulll commented Jan 21, 2026

Summary by CodeRabbit

  • New Features

    • Sprite management client (create/list/delete, run commands, checkpoints, lifecycle events, console URL) and server environment-driven configuration with sensible defaults.
  • Documentation

    • Added comprehensive Genesis Specification (12 sections) and Git Worktree skill/workflow for isolated development.
  • Tests

    • Unit tests covering sprite client behavior and lifecycle.
  • Chores

    • CI/workflow and QA tool configs added; new dev/runtime dependencies and minor config formatting.

✏️ Tip: You can customize this high-level summary in your review settings.

Anansitrading and others added 3 commits January 20, 2026 23:32
12-section enterprise-grade documentation generated through forensic
codebase analysis covering architecture, requirements, security,
testing, deployment, and operations.

Sections included:
- Introduction & Executive Summary
- Product Requirements (50+ functional/non-functional)
- Technology Stack (all dependencies with versions)
- Process Flowcharts (ASCII diagrams)
- Architecture Design (modules, patterns, ADRs)
- Data Models (TypeScript interfaces, storage schemas)
- Security & Compliance (STRIDE threat model)
- Testing Strategy (Vitest, Playwright)
- Monitoring & Observability (logging, metrics)
- Deployment & Operations (Docker, Electron)
- Documentation standards
- Reference Collections & Glossary

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @purpleskulll, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the project's foundational documentation and development configurations. It establishes a comprehensive 'Genesis Specification' that details various aspects of the Automaker project, from architecture to testing and deployment. Complementary to this, new configuration files are introduced to streamline development workflows, enforce code quality, and guide AI-assisted code reviews, ensuring consistency and clarity across the codebase.

Highlights

  • Comprehensive Documentation Suite: Introduction of a detailed 'Automaker Genesis Specification' across 12 sections, covering architecture, requirements, testing, security, and more, serving as a single source of truth for the project.
  • Git Worktree Guidance: New skill and workflow documentation for managing Git Worktrees, promoting isolated development environments and outlining best practices for their use within the Automaker repository.
  • Centralized Configuration: Addition of sprites.ts for centralizing environment variable definitions and .qodo.toml for project quality and testing configurations, streamlining development setup and consistency.
  • AI Review Configuration: Integration of greptile.json to guide AI-powered code reviews, focusing on architectural patterns, monorepo structure, Claude Agent SDK integration, and adherence to specific project guidelines.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link

coderabbitai bot commented Jan 21, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds Git worktree docs and workflows, CI/review config (Qodo, Greptile, PR agent), a sprites runtime config, a new SpriteApiClient service with unit tests and axios dependency, minor tsconfig formatting, and a comprehensive 12-section genesis specification documentation set.

Changes

Cohort / File(s) Summary
Agent Skills & Workflows
​.agent/skills/git-worktrees/SKILL.md, ​.agent/workflows/git-worktree.md
New Git worktree skill and workflow documentation with safe-create/list/remove steps, naming convention, repo-root execution, and example shell commands.
CI / Review Config
​.qodo.toml, greptile.json, ​.pr_agent.toml, .github/workflows/pr_agent.yml
Adds Qodo/Greptile config files and a GitHub Actions PR agent workflow for automated PR review and testing.
Repository / Dependencies
package.json, apps/server/package.json
Adds dev deps @qodo/command, greptile; adds runtime dependency axios@^1.13.2 to server package.
Server config constant
apps/server/src/config/sprites.ts
New exported spritesConfig aggregating environment variables with defaults and integer parsing for OTEL port.
Sprites service + tests
apps/server/src/services/sprite-api-client.ts, apps/server/tests/unit/services/sprite-api-client.test.ts
New SpriteApiClient (extends EventEmitter) and interfaces (Sprite, Checkpoint, ExecResult, SpriteConfig) implementing list/get/create/delete, exec with timeout, checkpoint/restore, shutdown/wake, status cache, event emissions; comprehensive unit tests with mocked HTTP client.
TypeScript project formatting
apps/server/tsconfig.json
Non-functional formatting changes to arrays (lib, include, exclude) only.
Genesis specification (documentation)
genesis_spec/README.md, genesis_spec/section_guides/... (01–12)
Adds a 12-section Genesis Specification suite covering intro, requirements, tech stack, flowcharts, architecture, data models, security, testing, observability, deployment, documentation, and references.

Sequence Diagram(s)

sequenceDiagram
  rect rgba(200,230,255,0.5)
    participant Client as Server (SpriteApiClient)
    participant API as Sprites_API
    participant Consumer as Event_Consumer
    participant Cache as Local_Cache
  end

  Client->>API: POST /sprites (create) with config
  API-->>Client: 201 Created (sprite)
  Client->>Cache: store sprite status
  Client->>Consumer: emit "spriteCreated"

  Client->>API: POST /sprites/:id/exec (command)
  API-->>Client: 200 ExecResult
  Client->>Consumer: emit "execResult"

  Client->>API: POST /sprites/:id/shutdown
  API-->>Client: 200 OK (status changed)
  Client->>Cache: update sprite status
  Client->>Consumer: emit "spriteStatusChanged"
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

Enhancement

Poem

🐇
I hopped through branches, light and spry,
Wove specs and configs, gave docs a try.
Worktrees cradle each new feat,
Sprites hum softly — tests complete.
Cheers from a rabbit, tail held high.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague and generic. 'Feature/tool configurations' uses non-descriptive terms that don't convey meaningful information about the specific changes in the changeset. Replace the generic title with a specific description of the main changes, e.g., 'Add Git Worktrees skill, Sprites API client, and genesis specifications' or 'Initialize Automaker genesis specification and tool configurations'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive set of documentation for the Automaker project, covering skills, workflows, configuration, and detailed Genesis Specification sections. The new documentation is well-structured and provides valuable insights into the project's architecture, requirements, and operational aspects. Additionally, new configuration files for Qodo and Greptile are added, which appear to be correctly formatted. The sprites.ts file correctly loads environment variables with sensible defaults.

git branch -d feature/<name>
```

// turbo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The // turbo comment on this line is not standard Markdown syntax. If this is intended as a comment for a specific tool, it should be documented or formatted in a way that doesn't interfere with standard Markdown rendering. Consider using HTML comments (<!-- comment -->) if it needs to be hidden from rendered output, or remove it if it's not serving a clear purpose.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🤖 Fix all issues with AI agents
In @.agent/skills/git-worktrees/SKILL.md:
- Around line 7-11: Update the skill instructions to explicitly require using
the `@automaker/git-utils` library for creating and removing worktrees instead of
invoking git directly: modify the lines that reference `git worktree list`,
creating worktrees (prefix `../automaker-worktree-`), and the `git-worktree`
workflow so they instruct callers to call the corresponding `@automaker/git-utils`
functions (create/remove/list worktrees) while still advising to run a
repository-root check and to prefer the `../automaker-worktree-` naming; make
sure the SKILL.md text references `@automaker/git-utils` by name and ties this
requirement to the CLAUDE.md safety guidance.

In @.agent/workflows/git-worktree.md:
- Around line 28-30: Remove the stray comment "// turbo" from the workflow steps
so the list flows correctly; locate the line containing the exact text "//
turbo" and delete it, leaving the numbered step "5. **Verify current setup**:
git status" as the first item in that section.
- Around line 14-26: Update the git-worktree examples to align with the
CLAUDE.md/@automaker/git-utils flow by changing the worktree name prefix from
../automaker-feature-<name> to ../automaker-worktree-<name> in the creation, cd,
and removal steps and add a short note that the preferred method is to use
`@automaker/git-utils` (with the shown git commands as a manual fallback); update
the three occurrences in .agent/workflows/git-worktree.md so the commands and
navigation use ../automaker-worktree-<name> and mention `@automaker/git-utils` as
the preferred flow.

In @.qodo.toml:
- Around line 4-12: The .qodo.toml uses non-standard sections/keys: replace the
[tests] section with the official [pr_test] section, rename the key framework to
testing_framework, and remove unsupported keys (directory, test_pattern, and any
keys like enabled, check_types, scripts); also delete the entire [quality]
section so only schema-recognized keys (e.g., testing_framework and any other
official pr_test options) remain in the file.

In `@apps/server/src/config/sprites.ts`:
- Around line 1-12: The OTEL_RECEIVER_PORT value in spritesConfig may become NaN
when parsing unexpected env values; update the OTEL_RECEIVER_PORT assignment in
spritesConfig to call parseInt with an explicit radix (e.g., 10) and add a
fallback to the default port (4317) if the parsed value is not a finite number
(use Number.isFinite or Number.isNaN to detect failure), so OTEL_RECEIVER_PORT
always resolves to a valid integer.

In `@genesis_spec/README.md`:
- Around line 1-4: Replace the emphasized title line "**Comprehensive technical
documentation for the Automaker autonomous AI development studio**" with a
proper Markdown heading (use a top-level heading for the title or a subheading
for the description) so the README uses a heading instead of bold text; update
the line containing the emphasized description and ensure the title "Automaker
Genesis Specification" remains as the main heading.

In `@genesis_spec/section_guides/Automaker_Section_03_Technology_Stack.md`:
- Around line 97-102: The fenced code block showing the package layout lacks a
language identifier; update the opening backticks for that block from ``` to
```text so the block is explicitly marked as plain text (e.g., the block
containing "Root package.json (npm workspaces) ├── apps/server/ ..." should use
```text as the fence) to satisfy MD040 and improve rendering.

In `@genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md`:
- Around line 11-50: The ASCII diagram code fences in
genesis_spec/section_guides/Automaker_Section_04_Process_Flowcharts.md are
missing language identifiers; update each triple-backtick fence that contains
the ASCII art (e.g., the diagram beginning with "+------------------+    
+------------------+     +------------------+" and the other similar diagram
blocks) to use ```text (or ```plaintext) instead of a bare ``` so the fences
become language-tagged and resolve MD040/editor rendering issues; apply this
change to every diagram block mentioned in the review.

In `@genesis_spec/section_guides/Automaker_Section_05_Architecture_Design.md`:
- Around line 186-211: The table rows like the lone "| **Sessions** |" break
Markdown because every row must have three cells to match the header; update
each section header row (e.g., Sessions, Agent, Auto-Mode, Terminal, Settings)
to include three pipe-separated cells (for example: put the section name in the
first cell and add two empty or placeholder cells such as "-" or "") so each row
has three columns and the endpoints rows (e.g., POST /api/sessions, GET
/api/agent/history, POST /api/auto-mode/run-feature, POST
/api/terminal/sessions, GET /api/settings/global) continue to align under the
Method, Endpoint, and Purpose columns.

In `@genesis_spec/section_guides/Automaker_Section_06_Data_Models.md`:
- Around line 203-231: The code fence in the storage layout block of
Automaker_Section_06_Data_Models.md lacks a language identifier; update the
opening fence from ``` to ```text so the block begins with a text language tag
(i.e., change the fenced block around the directory listing to use "text") to
ensure proper rendering and syntax highlighting.
- Around line 86-90: The spec mixes two type names for MCP server configuration:
use a single consistent casing (either MCPServerConfig or McpServerConfig)
across the document; update the declaration for GlobalSettings.mcpServers and
any other references (for example ExecuteOptions and any sections that define
the server schema) to the chosen identifier so all occurrences
(GlobalSettings.mcpServers, the type definition, and ExecuteOptions) match
exactly.
- Around line 152-193: The fenced ASCII diagram block that begins with the
Session/Feature diagram lacks a language identifier; update the opening
triple-backtick that wraps the ASCII art to include a language tag such as
"text" (i.e., change ``` to ```text) so renderers treat it as a preformatted
text block containing the Session, Feature, Message, Worktree, GlobalSettings,
ProjectSettings, and Credentials diagram.

In `@genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md`:
- Around line 13-33: The fenced ASCII security diagram block currently starts
with ```; update that opening fence to include the language identifier by
changing it to ```text so the diagram is marked as plain text; locate the
triple-backtick fence surrounding the "Security Layers" ASCII art (the block
containing the ASCII boxes and headers like "Authentication", "Authorization",
"Data Protection") and replace the opening ``` with ```text, leaving the closing
``` unchanged.

In
`@genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md`:
- Around line 287-298: The fenced console dashboard block showing the ASCII box
(the lines with "Automaker Backend Server", "Listening", "HTTP API", etc.) is
missing a language identifier; update the opening fence from ``` to ```text so
the block is marked as plain text (look for the fenced block containing the
ASCII dashboard header "Automaker Backend Server" and change its opening fence
to include "text").
- Around line 13-30: The fenced observability diagram block is missing a
language identifier; update the opening fence for the ASCII diagram (the
triple-backtick that currently starts the diagram) to include the "text"
language identifier (i.e., change ``` to ```text) so the block is properly
highlighted/rendered while leaving the closing triple-backtick unchanged; locate
the ASCII observability diagram block in the file and modify its opening fence
accordingly.
🧹 Nitpick comments (1)
genesis_spec/section_guides/Automaker_Section_12_Reference_Collections.md (1)

13-180: Consider wrapping bare URLs in markdown link syntax.

The documentation contains many bare URLs in tables. While functional, wrapping them in proper markdown link syntax (angle brackets or [text](url) format) improves readability and ensures better compatibility with markdown processors.

Example improvement for a few entries
 | Resource | URL |
 |----------|-----|
-| GitHub Repository | https://github.com/AutoMaker-Org/automaker |
-| Issue Tracker | https://github.com/AutoMaker-Org/automaker/issues |
+| GitHub Repository | <https://github.com/AutoMaker-Org/automaker> |
+| Issue Tracker | <https://github.com/AutoMaker-Org/automaker/issues> |

Or alternatively:

-| GitHub Repository | https://github.com/AutoMaker-Org/automaker |
+| GitHub Repository | [AutoMaker-Org/automaker](https://github.com/AutoMaker-Org/automaker) |

Comment on lines +7 to +11
## Instructions
- Always use `git worktree list` before creating new ones to avoid path conflicts.
- Prefer naming worktrees with the prefix `../automaker-worktree-`.
- Ensure you are in the root of the repository before running worktree commands.
- Use the `git-worktree` workflow for step-by-step execution.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Call out required @automaker/git-utils usage in the skill instructions.

The skill currently only mentions raw git worktree usage. Please explicitly require creating/removing worktrees via @automaker/git-utils to match repository safety guidance.

✏️ Proposed update
 ## Instructions
 - Always use `git worktree list` before creating new ones to avoid path conflicts.
 - Prefer naming worktrees with the prefix `../automaker-worktree-`.
 - Ensure you are in the root of the repository before running worktree commands.
 - Use the `git-worktree` workflow for step-by-step execution.
+- Create and manage worktrees via `@automaker/git-utils` (avoid direct `git worktree add/remove`).

Based on learnings, please align this with the CLAUDE.md requirement.

🤖 Prompt for AI Agents
In @.agent/skills/git-worktrees/SKILL.md around lines 7 - 11, Update the skill
instructions to explicitly require using the `@automaker/git-utils` library for
creating and removing worktrees instead of invoking git directly: modify the
lines that reference `git worktree list`, creating worktrees (prefix
`../automaker-worktree-`), and the `git-worktree` workflow so they instruct
callers to call the corresponding `@automaker/git-utils` functions
(create/remove/list worktrees) while still advising to run a repository-root
check and to prefer the `../automaker-worktree-` naming; make sure the SKILL.md
text references `@automaker/git-utils` by name and ties this requirement to the
CLAUDE.md safety guidance.

Comment on lines 14 to 26
2. **Create a new worktree for a feature**:
```bash
git worktree add ../automaker-feature-<name> -b feature/<name>
```

3. **Navigate to the worktree**:
- `cd ../automaker-feature-<name>`

4. **Remove worktree after completion**:
```bash
git worktree remove ../automaker-feature-<name>
git branch -d feature/<name>
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Align worktree naming and creation guidance with the required @automaker/git-utils flow.

The workflow uses ../automaker-feature-<name> and only shows raw git commands. This conflicts with the skill doc’s ../automaker-worktree- prefix and the requirement to use @automaker/git-utils. Please align both.

✏️ Suggested adjustment
-2. **Create a new worktree for a feature**:
+2. **Create a new worktree for a feature (prefer `@automaker/git-utils`)**:
   ```bash
-  git worktree add ../automaker-feature-<name> -b feature/<name>
+  # Prefer `@automaker/git-utils`; manual fallback shown:
+  git worktree add ../automaker-worktree-<name> -b feature/<name>
  1. Navigate to the worktree:
    • cd ../automaker-feature-<name>
    • cd ../automaker-worktree-<name>
  1. Remove worktree after completion:
-  git worktree remove ../automaker-feature-<name>
+  git worktree remove ../automaker-worktree-<name>
git branch -d feature/<name>
</details>


Based on learnings, please align this with the CLAUDE.md requirement.

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @.agent/workflows/git-worktree.md around lines 14 - 26, Update the
git-worktree examples to align with the CLAUDE.md/@automaker/git-utils flow by
changing the worktree name prefix from ../automaker-feature- to
../automaker-worktree- in the creation, cd, and removal steps and add a
short note that the preferred method is to use @automaker/git-utils (with the
shown git commands as a manual fallback); update the three occurrences in
.agent/workflows/git-worktree.md so the commands and navigation use
../automaker-worktree- and mention @automaker/git-utils as the preferred
flow.


</details>

<!-- fingerprinting:phantom:poseidon:eagle -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +1 to +12
export const spritesConfig = {
SPRITES_TOKEN: process.env.SPRITES_TOKEN,
SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1",
GITHUB_TOKEN: process.env.GITHUB_TOKEN,
LINEAR_API_KEY: process.env.LINEAR_API_KEY,
CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN,
DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL,
DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main",
GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent",
GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev",
OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || "4317"),
OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard OTEL port parsing to avoid NaN configs.
parseInt can yield NaN for unexpected env values; add radix + finite fallback to prevent runtime misconfig.

🛠️ Proposed fix
+const otelReceiverPort = Number.parseInt(process.env.OTEL_RECEIVER_PORT ?? "4317", 10);
+
 export const spritesConfig = {
     SPRITES_TOKEN: process.env.SPRITES_TOKEN,
     SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1",
     GITHUB_TOKEN: process.env.GITHUB_TOKEN,
     LINEAR_API_KEY: process.env.LINEAR_API_KEY,
     CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN,
     DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL,
     DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main",
     GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent",
     GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev",
-    OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || "4317"),
+    OTEL_RECEIVER_PORT: Number.isFinite(otelReceiverPort) ? otelReceiverPort : 4317,
     OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0",
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const spritesConfig = {
SPRITES_TOKEN: process.env.SPRITES_TOKEN,
SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1",
GITHUB_TOKEN: process.env.GITHUB_TOKEN,
LINEAR_API_KEY: process.env.LINEAR_API_KEY,
CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN,
DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL,
DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main",
GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent",
GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev",
OTEL_RECEIVER_PORT: parseInt(process.env.OTEL_RECEIVER_PORT || "4317"),
OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0",
const otelReceiverPort = Number.parseInt(process.env.OTEL_RECEIVER_PORT ?? "4317", 10);
export const spritesConfig = {
SPRITES_TOKEN: process.env.SPRITES_TOKEN,
SPRITES_API_BASE: process.env.SPRITES_API_BASE || "https://api.sprites.dev/v1",
GITHUB_TOKEN: process.env.GITHUB_TOKEN,
LINEAR_API_KEY: process.env.LINEAR_API_KEY,
CLAUDE_OAUTH_TOKEN: process.env.CLAUDE_OAUTH_TOKEN,
DEFAULT_REPO_URL: process.env.DEFAULT_REPO_URL,
DEFAULT_BRANCH: process.env.DEFAULT_BRANCH || "main",
GIT_USER_NAME: process.env.GIT_USER_NAME || "Automaker Agent",
GIT_USER_EMAIL: process.env.GIT_USER_EMAIL || "agent@automaker.dev",
OTEL_RECEIVER_PORT: Number.isFinite(otelReceiverPort) ? otelReceiverPort : 4317,
OTEL_RECEIVER_HOST: process.env.OTEL_RECEIVER_HOST || "0.0.0.0",
🤖 Prompt for AI Agents
In `@apps/server/src/config/sprites.ts` around lines 1 - 12, The
OTEL_RECEIVER_PORT value in spritesConfig may become NaN when parsing unexpected
env values; update the OTEL_RECEIVER_PORT assignment in spritesConfig to call
parseInt with an explicit radix (e.g., 10) and add a fallback to the default
port (4317) if the parsed value is not a finite number (use Number.isFinite or
Number.isNaN to detect failure), so OTEL_RECEIVER_PORT always resolves to a
valid integer.

Comment on lines +152 to +193
```
+----------------+ +----------------+
| Session | | Feature |
+----------------+ +----------------+
| id | | id |
| name | | name |
| projectPath | | description |
| messages[] +------>+ status |
| model | | priority |
+-------+--------+ | dependencies[] |
| +--------+-------+
| |
v v
+----------------+ +----------------+
| Message | | Worktree |
+----------------+ +----------------+
| id | | path |
| role | | branch |
| content | | featureId |
| images[] | +----------------+
| timestamp |
+----------------+

+----------------+ +----------------+
| GlobalSettings | |ProjectSettings |
+----------------+ +----------------+
| theme | | name |
| defaultModel | | model |
| eventHooks[] | | planningMode |
| mcpServers{} | | gitWorkflow{} |
+-------+--------+ +--------+-------+
| |
+------------+------------+
|
v
+--------------+
| Credentials |
+--------------+
| anthropicKey |
| githubToken |
+--------------+
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the ASCII diagram fence.

✏️ Suggested fix
-```
+```text
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
+----------------+ +----------------+
| Session | | Feature |
+----------------+ +----------------+
| id | | id |
| name | | name |
| projectPath | | description |
| messages[] +------>+ status |
| model | | priority |
+-------+--------+ | dependencies[] |
| +--------+-------+
| |
v v
+----------------+ +----------------+
| Message | | Worktree |
+----------------+ +----------------+
| id | | path |
| role | | branch |
| content | | featureId |
| images[] | +----------------+
| timestamp |
+----------------+
+----------------+ +----------------+
| GlobalSettings | |ProjectSettings |
+----------------+ +----------------+
| theme | | name |
| defaultModel | | model |
| eventHooks[] | | planningMode |
| mcpServers{} | | gitWorkflow{} |
+-------+--------+ +--------+-------+
| |
+------------+------------+
|
v
+--------------+
| Credentials |
+--------------+
| anthropicKey |
| githubToken |
+--------------+
```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

152-152: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@genesis_spec/section_guides/Automaker_Section_06_Data_Models.md` around lines
152 - 193, The fenced ASCII diagram block that begins with the Session/Feature
diagram lacks a language identifier; update the opening triple-backtick that
wraps the ASCII art to include a language tag such as "text" (i.e., change ```
to ```text) so renderers treat it as a preformatted text block containing the
Session, Feature, Message, Worktree, GlobalSettings, ProjectSettings, and
Credentials diagram.

Comment on lines +203 to +231
```
~/.automaker/ # Global config directory
+-- settings.json # GlobalSettings
+-- credentials.json # Credentials (encrypted)
+-- usage/ # Usage tracking
|
+-- data/ # Server data directory
+-- sessions-metadata.json # Session index
+-- agent-sessions/ # Session data
| +-- {sessionId}.json # Messages array
| +-- {sessionId}-queue.json # Prompt queue
|
+-- notifications/ # Notification storage
+-- notifications.json

{project}/.automaker/ # Per-project config
+-- settings.json # ProjectSettings
+-- features/ # Feature data
| +-- {featureId}/
| +-- spec.md # Feature specification
| +-- plan.json # Implementation plan
| +-- progress.json # Status tracking
|
+-- agent-sessions/ # Project-scoped sessions
+-- {sessionId}/
+-- messages.json
+-- events.json
+-- state.json
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the storage layout fence.

✏️ Suggested fix
-```
+```text
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

203-203: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@genesis_spec/section_guides/Automaker_Section_06_Data_Models.md` around lines
203 - 231, The code fence in the storage layout block of
Automaker_Section_06_Data_Models.md lacks a language identifier; update the
opening fence from ``` to ```text so the block begins with a text language tag
(i.e., change the fenced block around the directory listing to use "text") to
ensure proper rendering and syntax highlighting.

Comment on lines +13 to +33
```
+-------------------------------------------------------------------+
| Security Layers |
+-------------------------------------------------------------------+
| |
| +--------------------+ +--------------------+ +---------------+|
| | Authentication | | Authorization | | Data Protection|
| | - API Key auth | | - Path validation | | - Encrypted ||
| | - Session tokens | | - Tool restrictions| | credentials ||
| | - WS tokens | | - CORS policy | | - Secure FS ||
| +--------------------+ +--------------------+ +---------------+|
| |
| +--------------------+ +--------------------+ +---------------+|
| | Input Validation | | Network Security | | Audit Logging ||
| | - JSON schema | | - TLS termination | | - Request logs||
| | - Path traversal | | - Rate limiting | | - Event history|
| | - Size limits | | - Origin checks | | - Error logs ||
| +--------------------+ +--------------------+ +---------------+|
| |
+-------------------------------------------------------------------+
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the security diagram fence.

✏️ Suggested fix
-```
+```text
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@genesis_spec/section_guides/Automaker_Section_07_Security_Compliance.md`
around lines 13 - 33, The fenced ASCII security diagram block currently starts
with ```; update that opening fence to include the language identifier by
changing it to ```text so the diagram is marked as plain text; locate the
triple-backtick fence surrounding the "Security Layers" ASCII art (the block
containing the ASCII boxes and headers like "Authentication", "Authorization",
"Data Protection") and replace the opening ``` with ```text, leaving the closing
``` unchanged.

Comment on lines +13 to +30
```
+-------------------------------------------------------------------------+
| Observability Stack |
+-------------------------------------------------------------------------+
| |
| +---------------------+ +---------------------+ +------------------+ |
| | LOGS | | METRICS | | TRACES | |
| | | | | | | |
| | - Request logs | | - HTTP status codes | | - WebSocket | |
| | - Error logs | | - Session counts | | connections | |
| | - Event history | | - Agent usage | | - API latency | |
| | - Agent activity | | - Terminal sessions | | - Event flow | |
| | | | | | | |
| | Morgan + Custom | | Event-based | | Event History | |
| +---------------------+ +---------------------+ +------------------+ |
| |
+-------------------------------------------------------------------------+
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the observability diagram fence.

✏️ Suggested fix
-```
+```text
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
+-------------------------------------------------------------------------+
| Observability Stack |
+-------------------------------------------------------------------------+
| |
| +---------------------+ +---------------------+ +------------------+ |
| | LOGS | | METRICS | | TRACES | |
| | | | | | | |
| | - Request logs | | - HTTP status codes | | - WebSocket | |
| | - Error logs | | - Session counts | | connections | |
| | - Event history | | - Agent usage | | - API latency | |
| | - Agent activity | | - Terminal sessions | | - Event flow | |
| | | | | | | |
| | Morgan + Custom | | Event-based | | Event History | |
| +---------------------+ +---------------------+ +------------------+ |
| |
+-------------------------------------------------------------------------+
```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

13-13: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md`
around lines 13 - 30, The fenced observability diagram block is missing a
language identifier; update the opening fence for the ASCII diagram (the
triple-backtick that currently starts the diagram) to include the "text"
language identifier (i.e., change ``` to ```text) so the block is properly
highlighted/rendered while leaving the closing triple-backtick unchanged; locate
the ASCII observability diagram block in the file and modify its opening fence
accordingly.

Comment on lines +287 to +298
```
+===========================================================+
| Automaker Backend Server |
+===========================================================+
| Listening: 0.0.0.0:3008 |
| HTTP API: http://localhost:3008 |
| WebSocket: ws://localhost:3008/api/events |
| Terminal: ws://localhost:3008/api/terminal/ws |
| Health: http://localhost:3008/api/health |
| Terminal: enabled (password protected) |
+===========================================================+
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language identifier to the console dashboard fence.

✏️ Suggested fix
-```
+```text
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
+===========================================================+
| Automaker Backend Server |
+===========================================================+
| Listening: 0.0.0.0:3008 |
| HTTP API: http://localhost:3008 |
| WebSocket: ws://localhost:3008/api/events |
| Terminal: ws://localhost:3008/api/terminal/ws |
| Health: http://localhost:3008/api/health |
| Terminal: enabled (password protected) |
+===========================================================+
```
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

287-287: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
In `@genesis_spec/section_guides/Automaker_Section_09_Monitoring_Observability.md`
around lines 287 - 298, The fenced console dashboard block showing the ASCII box
(the lines with "Automaker Backend Server", "Listening", "HTTP API", etc.) is
missing a language identifier; update the opening fence from ``` to ```text so
the block is marked as plain text (look for the fenced block containing the
ASCII dashboard header "Automaker Backend Server" and change its opening fence
to include "text").

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @.agent/workflows/git-worktree.md:
- Around line 28-29: In the "Verify current setup" step the git status line is
not in a code block; update that occurrence of "git status" so it is wrapped in
a fenced code block (use triple backticks with language identifier like bash) to
match the formatting of other commands in the document.

In `@apps/server/src/services/sprite-api-client.ts`:
- Around line 190-212: shutdownSprite and wakeSprite only emit
spriteStatusChanged when statusCache has the sprite, which leaves listeners
uninformed after cache clears; after the POST request in shutdownSprite and
wakeSprite, ensure you always emit the event by either fetching the full sprite
or creating a minimal payload: check statusCache.get(spriteId) and if missing
construct a minimal sprite object with id: spriteId and status: 'hibernating' or
'running', store it in statusCache (so clearCache() consumers still get
consistent state) and then emit('spriteStatusChanged', sprite); apply these
changes in both shutdownSprite and wakeSprite.
♻️ Duplicate comments (1)
.agent/workflows/git-worktree.md (1)

14-17: Add guidance to prefer @automaker/git-utils for worktree creation.

The manual git worktree add command is shown, but the documented requirement to use @automaker/git-utils for worktree creation is not mentioned. Per the retrieved learnings, features must execute in isolated git worktrees created via @automaker/git-utils to protect the main branch. The manual git command should be presented as a fallback option.

📝 Suggested addition
 2. **Create a new worktree for a feature**:
+   > **Note**: Prefer using `@automaker/git-utils` to create worktrees. The command below is a manual fallback.
+   
    ```bash
    git worktree add ../automaker-worktree-<name> -b feature/<name>
    ```

Based on learnings, @automaker/git-utils should be the primary method for worktree creation.

🧹 Nitpick comments (4)
apps/server/src/services/sprite-api-client.ts (2)

60-85: Add a timeout/abort guard for network hangs.

Native fetch has no default timeout; a stalled request could block workflows.

♻️ Suggested timeout guard
-    private async request<T>(path: string, options: RequestInit = {}): Promise<T> {
+    private async request<T>(
+        path: string,
+        options: RequestInit & { timeoutMs?: number } = {}
+    ): Promise<T> {
         const url = `${this.apiBase}${path.startsWith('/') ? path : `/${path}`}`;
-        const headers = {
+        const { timeoutMs = 30000, ...fetchOptions } = options;
+        const controller = new AbortController();
+        const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
+        const headers = {
             'Authorization': `Bearer ${this.token}`,
             'Content-Type': 'application/json',
-            ...options.headers,
+            ...options.headers,
         };
 
         try {
-            const response = await fetch(url, { ...options, headers });
+            const response = await fetch(url, { ...fetchOptions, headers, signal: controller.signal });
             if (!response.ok) {
                 const errorText = await response.text();
                 throw new Error(`Sprites API Error (${response.status}): ${errorText || response.statusText}`);
             }
@@
             return (await response.json()) as T;
         } catch (error) {
             logger.error(`Request to ${url} failed:`, error);
             throw error;
+        } finally {
+            clearTimeout(timeoutId);
         }
     }

145-151: Consider redacting command text in logs.

Commands may contain secrets; logging the full string risks leakage.

🔒 Log-friendly alternative
-        logger.debug(`Executing on sprite ${spriteId}: ${command}`);
+        logger.debug(`Executing on sprite ${spriteId} (command length: ${command.length})`);
apps/server/tests/unit/services/sprite-api-client.test.ts (1)

123-137: Consider priming the cache to assert status-change events.

Right now the test doesn’t validate event emission because the cache isn’t seeded; a small setup step would strengthen lifecycle coverage.

apps/server/package.json (1)

37-37: Remove unused axios dependency.

Verified that axios is not imported or used anywhere in the codebase. Since the server uses Express and the client uses native fetch, this dependency adds unnecessary surface area and should be removed from package.json.

Comment on lines +28 to +29
5. **Verify current setup**:
git status
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Wrap the command in a code block for consistency.

The git status command should be formatted in a code block like all other commands in this workflow document.

✏️ Proposed fix
 5. **Verify current setup**:
-   git status
+   ```bash
+   git status
+   ```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
5. **Verify current setup**:
git status
5. **Verify current setup**:
🤖 Prompt for AI Agents
In @.agent/workflows/git-worktree.md around lines 28 - 29, In the "Verify
current setup" step the git status line is not in a code block; update that
occurrence of "git status" so it is wrapped in a fenced code block (use triple
backticks with language identifier like bash) to match the formatting of other
commands in the document.

Comment on lines +190 to +212
async shutdownSprite(spriteId: string): Promise<void> {
logger.info(`Shutting down sprite ${spriteId}`);
await this.request(`/sprites/${spriteId}/shutdown`, { method: 'POST' });

const sprite = this.statusCache.get(spriteId);
if (sprite) {
sprite.status = 'hibernating';
this.emit('spriteStatusChanged', sprite);
}
}

/**
* Wake up a hibernating sprite
*/
async wakeSprite(spriteId: string): Promise<void> {
logger.info(`Waking up sprite ${spriteId}`);
await this.request(`/sprites/${spriteId}/wake`, { method: 'POST' });

const sprite = this.statusCache.get(spriteId);
if (sprite) {
sprite.status = 'running';
this.emit('spriteStatusChanged', sprite);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n apps/server/src/services/sprite-api-client.ts | head -250

Repository: AutoMaker-Org/automaker

Length of output: 9048


🏁 Script executed:

rg -t ts -t tsx "shutdownSprite|wakeSprite" --no-heading -B 3 -A 3

Repository: AutoMaker-Org/automaker

Length of output: 94


🏁 Script executed:

rg "shutdownSprite|wakeSprite" -B 3 -A 3 --type ts

Repository: AutoMaker-Org/automaker

Length of output: 2563


🏁 Script executed:

cat -n apps/server/tests/unit/services/sprite-api-client.test.ts

Repository: AutoMaker-Org/automaker

Length of output: 6636


🏁 Script executed:

rg "spriteStatusChanged" --type ts -B 5 -A 2

Repository: AutoMaker-Org/automaker

Length of output: 2023


🏁 Script executed:

rg "getSprite|listSprites" --type ts -B 2 -A 2 | head -100

Repository: AutoMaker-Org/automaker

Length of output: 2573


🏁 Script executed:

find apps/server/src -type f -name "*.ts" | xargs rg "shutdownSprite|wakeSprite" -l

Repository: AutoMaker-Org/automaker

Length of output: 112


🏁 Script executed:

find apps/server/src -type f -name "*.ts" | xargs rg "\.shutdownSprite|\.wakeSprite" -B 3 -A 3

Repository: AutoMaker-Org/automaker

Length of output: 51


🏁 Script executed:

fd "\.ts$" apps/server/src --type f | xargs grep -l "SpriteApiClient\|spriteClient" | head -10

Repository: AutoMaker-Org/automaker

Length of output: 112


🏁 Script executed:

rg "new SpriteApiClient|SpriteApiClient\(\)" --type ts -B 2 -A 5

Repository: AutoMaker-Org/automaker

Length of output: 701


🏁 Script executed:

rg "import.*SpriteApiClient" --type ts -B 2 -A 5

Repository: AutoMaker-Org/automaker

Length of output: 753


Status-change events depend on cache presence, which is problematic for listeners.

The shutdownSprite and wakeSprite methods only emit spriteStatusChanged if the sprite exists in statusCache. If the sprite is not cached (e.g., after a client restart or clearCache() call), listeners won't receive the event despite the operation succeeding on the server. This breaks the event contract for consumers relying on these notifications.

Consider always emitting the event with a minimal status payload, or fetch the sprite first to populate the cache before updating status.

🤖 Prompt for AI Agents
In `@apps/server/src/services/sprite-api-client.ts` around lines 190 - 212,
shutdownSprite and wakeSprite only emit spriteStatusChanged when statusCache has
the sprite, which leaves listeners uninformed after cache clears; after the POST
request in shutdownSprite and wakeSprite, ensure you always emit the event by
either fetching the full sprite or creating a minimal payload: check
statusCache.get(spriteId) and if missing construct a minimal sprite object with
id: spriteId and status: 'hibernating' or 'running', store it in statusCache (so
clearCache() consumers still get consistent state) and then
emit('spriteStatusChanged', sprite); apply these changes in both shutdownSprite
and wakeSprite.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@apps/server/src/services/sprite-api-client.ts`:
- Around line 109-123: In createSprite (async createSprite(config:
SpriteConfig)) remove JSON.stringify around the payload passed to this.request
so that data is an object (spread config with repoUrl: config.repoUrl ||
spritesConfig.DEFAULT_REPO_URL and branch: config.branch ||
spritesConfig.DEFAULT_BRANCH) instead of a pre-stringified string; keep the rest
of the flow (calling this.request with method 'POST', then
this.statusCache.set(sprite.id, sprite) and this.emit('spriteCreated', sprite))
unchanged and rely on axios to serialize the object to JSON.
- Around line 160-178: Both createCheckpoint and restoreCheckpoint are passing
JSON.stringify(...) as the request payload; change them to pass the plain object
(e.g., { name } and { checkpointId }) so the underlying request helper can set
headers/serialize correctly. Update the payload in createCheckpoint (function
createCheckpoint) and restoreCheckpoint (method restoreCheckpoint) to send the
object directly rather than a JSON string, leaving content-type/serialization to
the shared request(...) implementation.
- Around line 216-223: getConsoleUrl is brittle because it mutates
axiosInstance.defaults.baseURL with blind string replaces; instead parse the
base URL using the URL API (or accept a configured dashboard base) and build the
console URL robustly: read the origin from axiosInstance.defaults.baseURL (fall
back to a provided spriteDashboardBaseUrl config), remove a trailing version
segment like "/v1" only if present, strip an "api." subdomain only if it exists,
then return `${origin}/dashboard/sprites/${spriteName}`; also validate the final
URL and throw or fallback if parsing fails. Reference: getConsoleUrl and
axiosInstance.defaults.baseURL.
- Around line 142-151: The execCommand method is JSON.stringifying the POST body
which causes double-encoding; update execCommand to pass the plain object {
command, timeout } to this.request (same pattern as other calls) instead of
JSON.stringify({ command, timeout }), ensuring the request call (request<T>)
sends the object directly and lets the HTTP client serialize it.
♻️ Duplicate comments (1)
apps/server/src/services/sprite-api-client.ts (1)

187-210: Status-change events depend on cache presence.

The shutdownSprite and wakeSprite methods only emit spriteStatusChanged if the sprite exists in statusCache. If the cache was cleared or the sprite was never fetched, listeners won't receive the event despite the operation succeeding.

Comment on lines +109 to +123
async createSprite(config: SpriteConfig): Promise<Sprite> {
logger.info(`Creating sprite: ${config.name}`);
const sprite = await this.request<Sprite>('/sprites', {
method: 'POST',
data: JSON.stringify({
...config,
repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL,
branch: config.branch || spritesConfig.DEFAULT_BRANCH,
}),
});

this.statusCache.set(sprite.id, sprite);
this.emit('spriteCreated', sprite);
return sprite;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove JSON.stringify - axios handles JSON serialization automatically.

Axios automatically serializes objects to JSON when Content-Type: application/json is set. Wrapping data in JSON.stringify sends a pre-stringified string as the request body, resulting in double-encoding (e.g., "{\"name\":\"test\"}" instead of {"name":"test"}). This will cause API parsing errors.

🐛 Proposed fix
     async createSprite(config: SpriteConfig): Promise<Sprite> {
         logger.info(`Creating sprite: ${config.name}`);
         const sprite = await this.request<Sprite>('/sprites', {
             method: 'POST',
-            data: JSON.stringify({
+            data: {
                 ...config,
                 repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL,
                 branch: config.branch || spritesConfig.DEFAULT_BRANCH,
-            }),
+            },
         });
 
         this.statusCache.set(sprite.id, sprite);
         this.emit('spriteCreated', sprite);
         return sprite;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async createSprite(config: SpriteConfig): Promise<Sprite> {
logger.info(`Creating sprite: ${config.name}`);
const sprite = await this.request<Sprite>('/sprites', {
method: 'POST',
data: JSON.stringify({
...config,
repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL,
branch: config.branch || spritesConfig.DEFAULT_BRANCH,
}),
});
this.statusCache.set(sprite.id, sprite);
this.emit('spriteCreated', sprite);
return sprite;
}
async createSprite(config: SpriteConfig): Promise<Sprite> {
logger.info(`Creating sprite: ${config.name}`);
const sprite = await this.request<Sprite>('/sprites', {
method: 'POST',
data: {
...config,
repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL,
branch: config.branch || spritesConfig.DEFAULT_BRANCH,
},
});
this.statusCache.set(sprite.id, sprite);
this.emit('spriteCreated', sprite);
return sprite;
}
🤖 Prompt for AI Agents
In `@apps/server/src/services/sprite-api-client.ts` around lines 109 - 123, In
createSprite (async createSprite(config: SpriteConfig)) remove JSON.stringify
around the payload passed to this.request so that data is an object (spread
config with repoUrl: config.repoUrl || spritesConfig.DEFAULT_REPO_URL and
branch: config.branch || spritesConfig.DEFAULT_BRANCH) instead of a
pre-stringified string; keep the rest of the flow (calling this.request with
method 'POST', then this.statusCache.set(sprite.id, sprite) and
this.emit('spriteCreated', sprite)) unchanged and rely on axios to serialize the
object to JSON.

Comment on lines +142 to +151
async execCommand(spriteId: string, command: string, timeout: number = 60000): Promise<ExecResult> {
logger.debug(`Executing on sprite ${spriteId}: ${command}`);

const result = await this.request<ExecResult>(`/sprites/${spriteId}/exec`, {
method: 'POST',
data: JSON.stringify({ command, timeout }),
});

return result;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Same JSON.stringify issue - remove it here as well.

🐛 Proposed fix
     async execCommand(spriteId: string, command: string, timeout: number = 60000): Promise<ExecResult> {
         logger.debug(`Executing on sprite ${spriteId}: ${command}`);
 
         const result = await this.request<ExecResult>(`/sprites/${spriteId}/exec`, {
             method: 'POST',
-            data: JSON.stringify({ command, timeout }),
+            data: { command, timeout },
         });
 
         return result;
     }
🤖 Prompt for AI Agents
In `@apps/server/src/services/sprite-api-client.ts` around lines 142 - 151, The
execCommand method is JSON.stringifying the POST body which causes
double-encoding; update execCommand to pass the plain object { command, timeout
} to this.request (same pattern as other calls) instead of JSON.stringify({
command, timeout }), ensuring the request call (request<T>) sends the object
directly and lets the HTTP client serialize it.

Comment on lines +160 to +178
async createCheckpoint(spriteId: string, name: string): Promise<Checkpoint> {
logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`);
return this.request<Checkpoint>(`/sprites/${spriteId}/checkpoints`, {
method: 'POST',
data: JSON.stringify({ name }),
});
}

/**
* Restore a sprite to a specified checkpoint
*/
async restoreCheckpoint(spriteId: string, checkpointId: string): Promise<void> {
logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`);
await this.request(`/sprites/${spriteId}/restore`, {
method: 'POST',
data: JSON.stringify({ checkpointId }),
});
this.emit('spriteRestored', { spriteId, checkpointId });
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Same JSON.stringify issue in both checkpointing methods.

🐛 Proposed fix
     async createCheckpoint(spriteId: string, name: string): Promise<Checkpoint> {
         logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`);
         return this.request<Checkpoint>(`/sprites/${spriteId}/checkpoints`, {
             method: 'POST',
-            data: JSON.stringify({ name }),
+            data: { name },
         });
     }
 
     async restoreCheckpoint(spriteId: string, checkpointId: string): Promise<void> {
         logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`);
         await this.request(`/sprites/${spriteId}/restore`, {
             method: 'POST',
-            data: JSON.stringify({ checkpointId }),
+            data: { checkpointId },
         });
         this.emit('spriteRestored', { spriteId, checkpointId });
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async createCheckpoint(spriteId: string, name: string): Promise<Checkpoint> {
logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`);
return this.request<Checkpoint>(`/sprites/${spriteId}/checkpoints`, {
method: 'POST',
data: JSON.stringify({ name }),
});
}
/**
* Restore a sprite to a specified checkpoint
*/
async restoreCheckpoint(spriteId: string, checkpointId: string): Promise<void> {
logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`);
await this.request(`/sprites/${spriteId}/restore`, {
method: 'POST',
data: JSON.stringify({ checkpointId }),
});
this.emit('spriteRestored', { spriteId, checkpointId });
}
async createCheckpoint(spriteId: string, name: string): Promise<Checkpoint> {
logger.info(`Creating checkpoint '${name}' for sprite ${spriteId}`);
return this.request<Checkpoint>(`/sprites/${spriteId}/checkpoints`, {
method: 'POST',
data: { name },
});
}
/**
* Restore a sprite to a specified checkpoint
*/
async restoreCheckpoint(spriteId: string, checkpointId: string): Promise<void> {
logger.info(`Restoring sprite ${spriteId} to checkpoint ${checkpointId}`);
await this.request(`/sprites/${spriteId}/restore`, {
method: 'POST',
data: { checkpointId },
});
this.emit('spriteRestored', { spriteId, checkpointId });
}
🤖 Prompt for AI Agents
In `@apps/server/src/services/sprite-api-client.ts` around lines 160 - 178, Both
createCheckpoint and restoreCheckpoint are passing JSON.stringify(...) as the
request payload; change them to pass the plain object (e.g., { name } and {
checkpointId }) so the underlying request helper can set headers/serialize
correctly. Update the payload in createCheckpoint (function createCheckpoint)
and restoreCheckpoint (method restoreCheckpoint) to send the object directly
rather than a JSON string, leaving content-type/serialization to the shared
request(...) implementation.

Comment on lines +216 to +223
/**
* Get the console URL for a sprite in the Sprites dashboard
*/
getConsoleUrl(spriteName: string): string {
const apiBase = this.axiosInstance.defaults.baseURL || '';
const baseUrl = apiBase.replace('/v1', '').replace('api.', '');
return `${baseUrl}/dashboard/sprites/${spriteName}`;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fragile URL construction for console URL.

The string replacements assume the API base URL follows a specific pattern (api.sprites.dev/v1). If the URL differs (e.g., custom domain, different version path, or no api. prefix), the resulting console URL will be malformed.

Consider making this configurable or adding validation.

💡 Suggested improvement
+    // Consider adding a separate config value for the dashboard base URL
+    // Example in spritesConfig: SPRITES_DASHBOARD_URL: 'https://sprites.dev'
     getConsoleUrl(spriteName: string): string {
-        const apiBase = this.axiosInstance.defaults.baseURL || '';
-        const baseUrl = apiBase.replace('/v1', '').replace('api.', '');
+        const dashboardBase = spritesConfig.SPRITES_DASHBOARD_URL || 'https://sprites.dev';
-        return `${baseUrl}/dashboard/sprites/${spriteName}`;
+        return `${dashboardBase}/dashboard/sprites/${spriteName}`;
     }
🤖 Prompt for AI Agents
In `@apps/server/src/services/sprite-api-client.ts` around lines 216 - 223,
getConsoleUrl is brittle because it mutates axiosInstance.defaults.baseURL with
blind string replaces; instead parse the base URL using the URL API (or accept a
configured dashboard base) and build the console URL robustly: read the origin
from axiosInstance.defaults.baseURL (fall back to a provided
spriteDashboardBaseUrl config), remove a trailing version segment like "/v1"
only if present, strip an "api." subdomain only if it exists, then return
`${origin}/dashboard/sprites/${spriteName}`; also validate the final URL and
throw or fallback if parsing fails. Reference: getConsoleUrl and
axiosInstance.defaults.baseURL.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.github/workflows/pr_agent.yml:
- Around line 20-21: Replace the floating, outdated action reference used by the
job with a pinned, trusted release: update the `uses: Codium-ai/pr-agent@main`
entry (job id `pr-agent`) to the new organization `qodo-ai/pr-agent` and pin it
to a specific release tag or commit SHA (for example `qodo-ai/pr-agent@vX.Y.Z`
or `qodo-ai/pr-agent@<commit-sha>`), ensuring the workflow now references the
new org and a fixed, auditable ref.
🧹 Nitpick comments (1)
package.json (1)

73-75: Pin new dev tool versions for consistency.

All other devDependencies use exact versions (9.1.7, 16.2.7, 3.7.4, 4.0.16), but @qodo/command and greptile use caret ranges. Caret ranges can pull in breaking updates and undermine reproducibility. Pin these to exact versions to match the rest of the devDependencies:

-    "@qodo/command": "^0.36.0",
-    "greptile": "^1.0.6"
+    "@qodo/command": "0.36.0",
+    "greptile": "1.0.6"

Both packages support Node ≥22 (or have no explicit Node restriction).

Comment on lines +20 to +21
- id: pr-agent
uses: Codium-ai/pr-agent@main
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

latest release tag Codium-ai/pr-agent GitHub Actions

💡 Result:

Latest release tag: v0.31 — docker/GitHub Actions tag codiumai/pr-agent:0.31-github_action (release listed "06 Nov 09:25"). [1]

Sources:
[1] qodo-ai/pr-agent releases (GitHub).


🌐 Web query:

Codium-ai/pr-agent GitHub releases latest tag GitHub Actions

💡 Result:

Latest published release for the repository (qodo-ai / formerly codium-ai) is v0.31 — Docker/GitHub Action image tag codiumai/pr-agent:0.31 (including codiumai/pr-agent:0.31-github_action). [1]

If you need this tag inside a GitHub Actions workflow, you can:

  • Read the repo’s latest release via the Releases API (GET /repos/{owner}/{repo}/releases/latest) and parse tag_name. [2]
  • Or use an existing action such as actions-ecosystem/action-get-latest-tag to obtain the latest Git tag in a workflow. [3]

Sources:
[1] Releases page showing v0.31 and Docker/GHA tags.
[2] GitHub Releases API (GET /repos/{owner}/{repo}/releases/latest).
[3] actions-ecosystem/action-get-latest-tag (GitHub Action to get latest tag).


🌐 Web query:

site:github.com Codium-ai/pr-agent releases v0.31 commit SHA

💡 Result:

v0.31 commit SHA: d36ad31. [1] (github.com) [2] (sourceforge.net)

Citations:


🌐 Web query:

"qodo-ai/pr-agent" GitHub Actions marketplace action reference

💡 Result:

The GitHub Action for PR-Agent is provided in the qodo-ai/pr-agent repository — use it in workflows with uses: qodo-ai/pr-agent@<ref> (example: uses: qodo-ai/pr-agent@main). See the repo and the GitHub Action / GitHub integration docs for the official action reference and environment/config variables. [1][2][3]

Sources:

  • qodo-ai/pr-agent (GitHub repo — README, Action usage). [1]
  • Qodo documentation — GitHub Action installation/usage and env config. [2][3]

Update action reference and pin to a specific release.

The action uses outdated organization reference Codium-ai/pr-agent (now qodo-ai/pr-agent) and a floating @main ref, creating supply-chain risk. Pin to a vetted release tag or commit SHA.

🔒 Suggested change
-        uses: Codium-ai/pr-agent@main
+        uses: qodo-ai/pr-agent@v0.31

or pin to commit:

-        uses: Codium-ai/pr-agent@main
+        uses: qodo-ai/pr-agent@d36ad31
🤖 Prompt for AI Agents
In @.github/workflows/pr_agent.yml around lines 20 - 21, Replace the floating,
outdated action reference used by the job with a pinned, trusted release: update
the `uses: Codium-ai/pr-agent@main` entry (job id `pr-agent`) to the new
organization `qodo-ai/pr-agent` and pin it to a specific release tag or commit
SHA (for example `qodo-ai/pr-agent@vX.Y.Z` or `qodo-ai/pr-agent@<commit-sha>`),
ensuring the workflow now references the new org and a fixed, auditable ref.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants