Skip to content

feat: add execution runner#1

Merged
adelrodriguez merged 1 commit intomainfrom
02-22-feat_add_execution_runner
Feb 22, 2026
Merged

feat: add execution runner#1
adelrodriguez merged 1 commit intomainfrom
02-22-feat_add_execution_runner

Conversation

@adelrodriguez
Copy link
Copy Markdown
Owner

@adelrodriguez adelrodriguez commented Feb 22, 2026

Summary by CodeRabbit

Release Notes

  • New Features
    • Introduced core run() function for executing code with configurable retry and timeout policies
    • Added fluent builder API with retry(), timeout(), signal(), and wrap() methods for fine-grained control flow
    • Implemented structured error types: CancellationError, TimeoutError, RetryExhaustedError, UnhandledException, and Panic
    • Foundation for parallel task orchestration and generator-based workflows (coming in future releases)

Greptile Summary

Implements Phase 0 and Phase 1 of the hardtry execution runner library, establishing foundation types, error classes, and synchronous run() execution. The PR adds a fluent builder API (retry, timeout, signal, wrap) and core execution logic with proper error handling for UnhandledException and Panic cases.

Key Changes:

  • Core type system with TryCtx, RunOptions, and BuilderConfig
  • Five custom error classes with stable error codes and cause preservation
  • Immutable TryBuilder with chainable configuration methods
  • executeRun function supporting both function and object forms
  • Context creation with retry metadata
  • Comprehensive test coverage for synchronous execution paths
  • Placeholder stubs for future features (gen, dispose, all, allSettled, flow)

Issues Found:

  • Logic issue in src/lib/retry.ts:12-16 where spread operator placement allows undefined values to override defaults

Confidence Score: 4/5

  • Safe to merge with one logic fix needed in retry policy normalization
  • Strong foundation with clean architecture, comprehensive tests, and well-documented design. One logic bug in retry.ts prevents a perfect score - the spread operator placement could allow undefined values to override defaults. The implementation correctly follows the phased plan and matches the design spec.
  • Fix src/lib/retry.ts before merging to prevent potential undefined override issues

Important Files Changed

Filename Overview
src/lib/builder.ts Fluent builder implementation with immutable config pattern, all methods correctly return new instances
src/lib/runner.ts Core execution engine with proper error handling for sync paths, correctly implements function and object forms
src/lib/retry.ts Retry policy normalization with defaults; spread operator placement may allow undefined to override defaults
src/lib/errors.ts Well-structured error hierarchy with stable codes and cause preservation
src/lib/types.ts Comprehensive type definitions for all core abstractions
src/index.ts Clean public API surface using bound methods from root builder instance

Last reviewed commit: bb72fd6

@adelrodriguez adelrodriguez marked this pull request as ready for review February 22, 2026 21:49
Copy link
Copy Markdown
Owner Author

adelrodriguez commented Feb 22, 2026

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 22, 2026

Warning

Rate limit exceeded

@adelrodriguez has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

This PR introduces the foundational architecture for hardtry, a TypeScript-based retry/timeout/abort-control flow library. It includes design and implementation documentation, core type definitions, an error hierarchy, an immutable fluent builder API (TryBuilder) for configuring operations, and synchronous execution logic with structured error handling and context management.

Changes

Cohort / File(s) Summary
Documentation
.context/api-proposal.md, .context/design.md, .context/plan.md
Comprehensive design documentation, API proposals, and phase-by-phase implementation plan for the hardtry v1 library, including architecture overview, error handling model, and module responsibilities.
Type Definitions
src/lib/types.ts
Core types for retry policies, execution context, builder configuration, error codes, and function signatures (RunTryFn, RunCatchFn, WrapFn, TimeoutOptions, RetryPolicy).
Error Handling
src/lib/errors.ts
Structured error hierarchy with abstract ExecutionError base class and concrete error types (CancellationError, TimeoutError, RetryExhaustedError, UnhandledException, Panic), each with unique error codes and default messages.
Builder API
src/lib/builder.ts
TryBuilder class implementing a fluent, immutable builder pattern with methods to configure retry policies, timeouts, abort signals, and middleware wrapping, delegating execution to executeRun.
Execution Layer
src/lib/runner.ts, src/lib/context.ts
executeRun function handling synchronous execution with error mapping to UnhandledException/Panic; createContext utility normalizing builder configuration into a TryCtx runtime context.
Retry Utilities
src/lib/retry.ts
normalizeRetryPolicy and retryOptions functions to normalize retry configurations, applying defaults for backoff strategy and delay.
Placeholders
src/lib/dispose.ts, src/lib/gen.ts
Stub implementations for createDisposer and executeGen, throwing "not implemented yet" errors to mark future work.
Module Exports & Tests
src/index.ts, src/__tests__/index.test.ts, src/lib/__tests__/runner.test.ts
Root module exports binding builder methods to a singleton TryBuilder instance and re-exporting error classes and utilities; test suites validating run execution, error handling, and context normalization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add execution runner' accurately describes the main addition to the codebase: introducing the executeRun function and supporting infrastructure (TryBuilder, context creation, error classes) that form the core execution runner system.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 02-22-feat_add_execution_runner

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
Copy Markdown

@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

🧹 Nitpick comments (8)
src/__tests__/index.test.ts (1)

1-42: LGTM — integration tests correctly cover the sync contract.

Side note: TryBuilder.run in src/lib/builder.ts (lines 56–62) has a redundant if (typeof input === "function") — both branches call executeRun(this.#config, input) identically. The branch adds no runtime behavior and can be removed.

♻️ Suggested simplification in builder.ts
-  run<T, E>(input: RunTryFn<T> | RunWithCatchOptions<T, E>) {
-    if (typeof input === "function") {
-      return executeRun(this.#config, input)
-    }
-
-    return executeRun(this.#config, input)
-  }
+  run<T, E>(input: RunTryFn<T> | RunWithCatchOptions<T, E>) {
+    return executeRun(this.#config, input)
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/index.test.ts` around lines 1 - 42, Remove the redundant branch
in TryBuilder.run: the if (typeof input === "function") check is unnecessary
because both branches call executeRun(this.#config, input) identically; simplify
the method by calling executeRun(this.#config, input) unconditionally and
removing the conditional and its duplicate call, keeping the method signature
and preserving use of this.#config and the executeRun helper.
src/lib/__tests__/runner.test.ts (1)

20-32: Optional: add a happy-path test for object form where try succeeds.

The current object-form tests only cover the try-throws path. The success path (no throw from try) is not exercised — it falls through to return input.try(ctx) in executeRun without any assertion.

✅ Suggested additional test
+  it("returns success value in object form", () => {
+    const result = executeRun(
+      {},
+      {
+        try: () => "ok" as const,
+        catch: () => "mapped",
+      }
+    )
+
+    expect(result).toBe("ok")
+  })
+
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/runner.test.ts` around lines 20 - 32, Add a happy-path test
for the object form to assert executeRun returns the value from the provided try
function when it does not throw; specifically, in
src/lib/__tests__/runner.test.ts add a test that calls executeRun with an object
having try: () => "ok" and catch: () => "mapped" (or a spy) and assert the
result is "ok" (and optionally that catch was not invoked), targeting the
executeRun function behavior.
src/lib/retry.ts (1)

19-21: retryOptions has no dedicated tests and normalizeRetryPolicy is untested for its object branch.

The runner tests exercise context building with { limit: 3 }, but there are no tests directly covering normalizeRetryPolicy with a full policy object (non-number path), including default application for backoff / delayMs.

✅ Suggested tests for retry.ts
import { describe, expect, it } from "bun:test"
import { normalizeRetryPolicy, retryOptions } from "../retry"

describe("normalizeRetryPolicy", () => {
  it("converts a number to a RetryPolicy with linear defaults", () => {
    expect(normalizeRetryPolicy(3)).toEqual({
      backoff: "linear",
      delayMs: 0,
      limit: 3,
    })
  })

  it("applies defaults for missing backoff and delayMs in object form", () => {
    expect(normalizeRetryPolicy({ limit: 5 })).toEqual({
      backoff: "linear",
      delayMs: 0,
      limit: 5,
    })
  })

  it("preserves explicit backoff and delayMs in object form", () => {
    expect(normalizeRetryPolicy({ limit: 3, backoff: "exponential", delayMs: 500 })).toEqual({
      backoff: "exponential",
      delayMs: 500,
      limit: 3,
    })
  })
})

describe("retryOptions", () => {
  it("delegates to normalizeRetryPolicy", () => {
    expect(retryOptions({ limit: 2 })).toEqual(normalizeRetryPolicy({ limit: 2 }))
  })
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/retry.ts` around lines 19 - 21, Add unit tests covering
normalizeRetryPolicy's object branch and retryOptions delegation: create tests
that assert numeric input (e.g., 3) returns { backoff: "linear", delayMs: 0,
limit: 3 }, that an object with only limit (e.g., { limit: 5 }) applies defaults
for backoff and delayMs, and that an object with explicit backoff and delayMs
(e.g., { limit: 3, backoff: "exponential", delayMs: 500 }) is preserved; also
add a test that retryOptions({ limit: 2 }) simply returns the same value as
normalizeRetryPolicy({ limit: 2 }). Ensure tests import normalizeRetryPolicy and
retryOptions and use assertions for equality to cover the previously untested
branches.
src/lib/builder.ts (2)

57-63: Redundant runtime branch — both arms call the same code.

The if/else exists solely to narrow types for overload resolution. Since both branches are identical at runtime, consider collapsing them with a type assertion, or adding a brief comment so future readers don't wonder about the duplication.

Option: collapse with a comment
   run<T, E>(input: RunTryFn<T> | RunWithCatchOptions<T, E>) {
-    if (typeof input === "function") {
-      return executeRun(this.#config, input)
-    }
-
-    return executeRun(this.#config, input)
+    // Branch narrows `input` so TS selects the correct executeRun overload.
+    if (typeof input === "function") {
+      return executeRun(this.#config, input)
+    }
+    return executeRun(this.#config, input)
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/builder.ts` around lines 57 - 63, The run method in class Builder
redundantly branches even though both branches call executeRun(this.#config,
input); simplify by removing the if/else and calling executeRun once, using a
type assertion to satisfy overloads (e.g., assert input as RunTryFn<T> |
RunWithCatchOptions<T,E>) or add an inline comment explaining the runtime
duplication is deliberate for type narrowing; update the run<T,E>(input: ...)
implementation around the run method to either collapse to a single return
executeRun(this.#config, input as any) with a clarifying comment or keep the
current signature but eliminate the duplicate branch while preserving type
correctness for executeRun and `#config` references.

14-20: normalizeTimeoutOptions mirrors normalizeRetryPolicy — consider co-locating or keeping the pattern consistent.

normalizeRetryPolicy lives in retry.ts and is exported, while normalizeTimeoutOptions is a file-private function in builder.ts. When timeout.ts is implemented (step 5 in the implementation order), this helper will likely need to move there. Not blocking, just a heads-up.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/builder.ts` around lines 14 - 20, normalizeTimeoutOptions is
currently a private helper in builder.ts but mirrors normalizeRetryPolicy's
exported pattern; move and export normalizeTimeoutOptions to the new timeout
module (e.g., timeout.ts) so it follows the same public helper pattern as
normalizeRetryPolicy, then update builder.ts to import { normalizeTimeoutOptions
} from timeout.ts (or export it from a central index) to keep helper placement
and visibility consistent when the timeout feature is implemented.
.context/design.md (2)

302-303: Minor naming drift between design doc and implementation.

The design doc references RunOptions<T, E> here, but the actual type in src/lib/types.ts is RunWithCatchOptions<T, E> (with a separate RunTryFn<T> for the function form). Worth aligning the doc to avoid confusion as the team grows.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.context/design.md around lines 302 - 303, The doc refers to RunOptions<T,
E> but the code defines RunWithCatchOptions<T, E> (and a separate RunTryFn<T>
for the try-function form); update the design document to use the actual type
names (replace RunOptions<T, E> with RunWithCatchOptions<T, E> and mention
RunTryFn<T> where the function form is described) so the doc matches the
implementation and avoids naming drift.

65-93: Add a language identifier to the fenced code block.

The directory tree block at line 65 is missing a language specifier, which triggers the MD040 lint warning. Use ```text or ```plaintext to silence it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.context/design.md around lines 65 - 93, The fenced code block that shows
the project directory tree (the triple-backtick block containing the "src/"
tree) lacks a language identifier and triggers MD040; update the opening fence
from ``` to a specific specifier such as ```text or ```plaintext so the block is
treated as plain text and the lint warning is silenced.
src/lib/errors.ts (1)

14-24: Consider exporting ExecutionError for catch-all instanceof checks.

ExecutionError is not exported, so consumers cannot write a single instanceof ExecutionError guard to match any framework error. If the intent is to keep it internal and have users rely on the code discriminant instead, that's a valid choice — just worth making explicit in the public docs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/errors.ts` around lines 14 - 24, ExecutionError is currently declared
as an internal abstract class and not exported, preventing consumers from using
instanceof ExecutionError to catch any framework error; change its declaration
to export abstract class ExecutionError so it becomes part of the public API,
update any local imports/usages that relied on the non-exported symbol, and add
it to your library's public exports/barrel (or relevant export list) so
consumers can import it for catch-all instanceof checks (if you prefer to keep
it internal instead, explicitly document that consumers should use the error
code discriminant instead).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.context/api-proposal.md:
- Around line 10-13: The example passed to .run has a syntax error: the object
literal with properties try and catch is missing a comma; update the .run
invocation (the object containing try: () => myFn() and catch: (e) => new
MyErr()) to include a comma after the try property so the code becomes a valid
object literal and the .run({ try: () => myFn(), catch: (e) => new MyErr() })
form is correct.
- Around line 104-116: The examples for try$.all / try$.allSettled have trailing
commas after return expressions (e.g., in the async functions a, b, c and the
b(conn) functions) which are syntax errors; edit the example function bodies
(the async a(), async b(), async c(), and their counterparts) to remove the
trailing commas after the return expressions so each return line ends with the
expression only (e.g., return getA() not return getA(),) and ensure dependent
uses like getC(await this.$result.a) remain unchanged.

In `@src/index.ts`:
- Around line 25-26: Replace the direct constant assignments for gen and dispose
with re-exports to avoid the need for explicit type annotations: instead of
"export const gen = executeGen" and "export const dispose = createDisposer",
re-export the existing symbols so that executeGen is exported as gen and
createDisposer is exported as dispose; this removes the declaration-emit typing
requirement while preserving the public API.

In `@src/lib/retry.ts`:
- Around line 12-16: The return object currently spreads ...policy after setting
backoff and delayMs which allows undefined values in policy to clobber the
defaults; change the order so ...policy is spread first and then set the
defaults using policy.backoff ?? "linear" and policy.delayMs ?? 0 (i.e., put the
spread before the explicit backoff and delayMs assignments) so the defaults
always apply even when policy.backoff or policy.delayMs are undefined; target
the function that returns this object and the local variable policy and the
properties backoff/delayMs.

---

Nitpick comments:
In @.context/design.md:
- Around line 302-303: The doc refers to RunOptions<T, E> but the code defines
RunWithCatchOptions<T, E> (and a separate RunTryFn<T> for the try-function
form); update the design document to use the actual type names (replace
RunOptions<T, E> with RunWithCatchOptions<T, E> and mention RunTryFn<T> where
the function form is described) so the doc matches the implementation and avoids
naming drift.
- Around line 65-93: The fenced code block that shows the project directory tree
(the triple-backtick block containing the "src/" tree) lacks a language
identifier and triggers MD040; update the opening fence from ``` to a specific
specifier such as ```text or ```plaintext so the block is treated as plain text
and the lint warning is silenced.

In `@src/__tests__/index.test.ts`:
- Around line 1-42: Remove the redundant branch in TryBuilder.run: the if
(typeof input === "function") check is unnecessary because both branches call
executeRun(this.#config, input) identically; simplify the method by calling
executeRun(this.#config, input) unconditionally and removing the conditional and
its duplicate call, keeping the method signature and preserving use of
this.#config and the executeRun helper.

In `@src/lib/__tests__/runner.test.ts`:
- Around line 20-32: Add a happy-path test for the object form to assert
executeRun returns the value from the provided try function when it does not
throw; specifically, in src/lib/__tests__/runner.test.ts add a test that calls
executeRun with an object having try: () => "ok" and catch: () => "mapped" (or a
spy) and assert the result is "ok" (and optionally that catch was not invoked),
targeting the executeRun function behavior.

In `@src/lib/builder.ts`:
- Around line 57-63: The run method in class Builder redundantly branches even
though both branches call executeRun(this.#config, input); simplify by removing
the if/else and calling executeRun once, using a type assertion to satisfy
overloads (e.g., assert input as RunTryFn<T> | RunWithCatchOptions<T,E>) or add
an inline comment explaining the runtime duplication is deliberate for type
narrowing; update the run<T,E>(input: ...) implementation around the run method
to either collapse to a single return executeRun(this.#config, input as any)
with a clarifying comment or keep the current signature but eliminate the
duplicate branch while preserving type correctness for executeRun and `#config`
references.
- Around line 14-20: normalizeTimeoutOptions is currently a private helper in
builder.ts but mirrors normalizeRetryPolicy's exported pattern; move and export
normalizeTimeoutOptions to the new timeout module (e.g., timeout.ts) so it
follows the same public helper pattern as normalizeRetryPolicy, then update
builder.ts to import { normalizeTimeoutOptions } from timeout.ts (or export it
from a central index) to keep helper placement and visibility consistent when
the timeout feature is implemented.

In `@src/lib/errors.ts`:
- Around line 14-24: ExecutionError is currently declared as an internal
abstract class and not exported, preventing consumers from using instanceof
ExecutionError to catch any framework error; change its declaration to export
abstract class ExecutionError so it becomes part of the public API, update any
local imports/usages that relied on the non-exported symbol, and add it to your
library's public exports/barrel (or relevant export list) so consumers can
import it for catch-all instanceof checks (if you prefer to keep it internal
instead, explicitly document that consumers should use the error code
discriminant instead).

In `@src/lib/retry.ts`:
- Around line 19-21: Add unit tests covering normalizeRetryPolicy's object
branch and retryOptions delegation: create tests that assert numeric input
(e.g., 3) returns { backoff: "linear", delayMs: 0, limit: 3 }, that an object
with only limit (e.g., { limit: 5 }) applies defaults for backoff and delayMs,
and that an object with explicit backoff and delayMs (e.g., { limit: 3, backoff:
"exponential", delayMs: 500 }) is preserved; also add a test that retryOptions({
limit: 2 }) simply returns the same value as normalizeRetryPolicy({ limit: 2 }).
Ensure tests import normalizeRetryPolicy and retryOptions and use assertions for
equality to cover the previously untested branches.

Comment on lines +12 to +16
return {
backoff: policy.backoff ?? "linear",
delayMs: policy.delayMs ?? 0,
...policy,
}
Copy link
Copy Markdown

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

🏁 Script executed:

#!/bin/bash
# Check for tsconfig files and search for exactOptionalPropertyTypes
find . -name "tsconfig*.json" -type f | head -20

Repository: adelrodriguez/hardtry

Length of output: 80


🏁 Script executed:

#!/bin/bash
# Read the retry.ts file to see the current code
wc -l src/lib/retry.ts

Repository: adelrodriguez/hardtry

Length of output: 84


🏁 Script executed:

#!/bin/bash
# Read the retry.ts file around lines 12-16
sed -n '1,25p' src/lib/retry.ts

Repository: adelrodriguez/hardtry

Length of output: 527


🏁 Script executed:

#!/bin/bash
# Check tsconfig.json for exactOptionalPropertyTypes
cat tsconfig.json

Repository: adelrodriguez/hardtry

Length of output: 420


🏁 Script executed:

#!/bin/bash
# Find and read the types file to understand RetryPolicy
find . -name "types.ts" -o -name "types.d.ts" | head -5

Repository: adelrodriguez/hardtry

Length of output: 83


🏁 Script executed:

#!/bin/bash
# Read the types.ts file to see RetryPolicy definition
cat src/lib/types.ts

Repository: adelrodriguez/hardtry

Length of output: 1178


Move spread operator before defaults to prevent undefined clobber.

When spreading two objects with the same properties, the last assignment wins—even if it's undefined. The current code places ...policy after the ?? defaults:

return {
  backoff: policy.backoff ?? "linear",
  delayMs: policy.delayMs ?? 0,
  ...policy,
}

Since exactOptionalPropertyTypes is not enabled in tsconfig, callers can pass { limit: 3, backoff: undefined } (valid RetryPolicy), which would clobber the defaults and return backoff: undefined instead of "linear".

Move the spread before the defaults so defaults always apply:

🐛 Proposed fix
  return {
-   backoff: policy.backoff ?? "linear",
-   delayMs: policy.delayMs ?? 0,
    ...policy,
+   backoff: policy.backoff ?? "linear",
+   delayMs: policy.delayMs ?? 0,
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/retry.ts` around lines 12 - 16, The return object currently spreads
...policy after setting backoff and delayMs which allows undefined values in
policy to clobber the defaults; change the order so ...policy is spread first
and then set the defaults using policy.backoff ?? "linear" and policy.delayMs ??
0 (i.e., put the spread before the explicit backoff and delayMs assignments) so
the defaults always apply even when policy.backoff or policy.delayMs are
undefined; target the function that returns this object and the local variable
policy and the properties backoff/delayMs.

@adelrodriguez adelrodriguez force-pushed the 02-22-feat_add_execution_runner branch 2 times, most recently from cdedcdd to fe74bbf Compare February 22, 2026 21:59
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

14 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@adelrodriguez adelrodriguez force-pushed the 02-22-feat_add_execution_runner branch from fe74bbf to d03bd39 Compare February 22, 2026 22:04
@adelrodriguez adelrodriguez force-pushed the 02-22-feat_add_execution_runner branch from d03bd39 to bb72fd6 Compare February 22, 2026 22:08
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

14 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

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.

1 participant