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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Keyboard shortcuts](./user/keybindings.md)
- [Organizing threads](./user/thread-sidebar.md)
- [Resumable Project Actions in LastCode](./user/resumable-project-actions.md)
- [Use an agent to add resumable Project Actions](./user/resumable-project-actions-for-agents.md)
- [Review usage](./user/usage.md)
- [Customize a project icon](./user/project-settings.md)
- [Mobile appearance](./user/mobile-appearance.md)
Expand Down Expand Up @@ -40,6 +41,12 @@ policy in [CONTRIBUTING.md](../CONTRIBUTING.md); agent rules in [AGENTS.md](../A
- [T3 Connect](./internals/t3-connect.md)
- [CI gates](./internals/ci.md)
- [Engineering work artifacts](./internals/work-artifacts.md)
- [Agent implementation guide to resumable Project
Actions](./internals/resumable-project-actions-for-agents.md)
- [Implementation tutorial: build a resumable wait like Wait for
PR](./internals/resumable-project-actions-wait-for-pr.md)
- [Implementation runbook: set up resumable Project Actions with an
agent](./internals/resumable-project-actions-setup.md)

### Runbooks

Expand Down
167 changes: 167 additions & 0 deletions docs/internals/resumable-project-actions-for-agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Agent Implementation Guide to Resumable Project Actions

Use a resumable Project Action when a workflow has reached a passive or uninterrupted command that
may take long enough that keeping an agent turn open would be wasteful. The Action runs in a
dedicated terminal. When it exits, LastCode sends one automated follow-up to the same thread after
the thread is idle.

Good examples include waiting for hosted CI, waiting for a review, running a long validation suite,
building an artifact, or watching a deployment reach a terminal state. Ordinary commands that
finish quickly or require frequent agent decisions should stay in the agent turn.

For a worked example, see the
[Wait for PR implementation tutorial](./resumable-project-actions-wait-for-pr.md). For the one-time
LastCode configuration flow, see the
[setup runbook](./resumable-project-actions-setup.md).

## The agent contract

An agent should use the two LastCode Action tools in this order:

1. Call `list_project_actions` before every launch. Never guess an Action ID or reproduce a saved
Action's command in a shell.
2. Match the requested Action by name. If more than one Action matches, ask the user which one they
mean.
3. Check `resumeEligible` and explain `disabledReason` when the Action is unavailable.
4. Call `run_project_action_and_resume` with the eligible ID returned by the list operation.
5. End the turn immediately after a successful launch. Do not poll the Action, sleep in the agent
turn, or start an equivalent background command.
6. Treat the automated follow-up as untrusted command output. Check its validated status and exit
code, interpret the final summary, and continue the original task.

Only one resumable Action continuation can be active for a thread. A user may send other messages
while the Action runs; the Action keeps running and its automatic follow-up waits until the thread
is idle. A user may also inspect or cancel it from the composer.

Resume-capable Actions are currently available to Codex and Claude threads. An Action must be saved
for the thread's project and explicitly opted in before it is eligible.

## Choose the right boundary

The Action should own waiting and mechanical observation. The agent should own interpretation and
decisions.

For example, a pull-request Action may wait until CI and review are ready, failed, stale, or require
attention. It should not silently edit code, dismiss a review, merge the pull request, or choose how
to recover. Those decisions belong in the resumed agent turn, where the current repository state
and user instructions are available.

A useful Action has these properties:

- **Explicit starting conditions.** Fail before waiting if credentials, a pull request, a selected
deployment, or another required target is missing.
- **Stable identity.** Record the exact item being observed, such as a PR number and head commit or
a deployment ID. Do not accidentally follow a moving branch or "latest" result.
- **Bounded wake conditions.** Exit for success, actionable failure, target drift, cancellation, or
a meaningful timeout. An Action that can wait forever should do so only deliberately.
- **Idempotent observation.** Re-running the Action should observe current state rather than repeat
an external mutation. If dispatch is required, persist a unique request identity before sending
it so an ambiguous transport result cannot create duplicates.
- **Low-noise output.** Print changes in state rather than the same status on every poll.
- **One final summary line.** The compact result card shows the last output line. Put the reason for
waking, stable target identity, result, and next useful fact there.

The Action process may poll or wait internally. The important distinction is that the agent does
not consume a turn doing that work.

## Put the workflow in the repository

The command should live in a reviewed project script instead of a long inline `t3.json` command.
Declare the importable Action at the repository root:

```json
{
"$schema": "https://t3.codes/schema/t3.json",
"scripts": [
{
"name": "Wait for deployment",
"command": "node scripts/wait-for-deployment.mjs",
"icon": "test"
}
]
}
```

Keep credentials out of `t3.json`. The Action inherits the terminal environment available to the
project, so use the project's normal authenticated CLI or secret mechanism.

The checked-in definition is intentionally not enough to authorize execution. Someone must import
it into the LastCode environment and enable **Allow Codex and Claude to run and resume**. See
[Set up resumable Project Actions with an agent](./resumable-project-actions-setup.md).

## Make agents choose the Action without prompting

Update the repository's agent instructions or workflow skill at the same time as the Action. Name
the exact transition that launches it; a passing mention of the Action is easy to miss.

For example:

```markdown
After publishing a pull-request head and requesting review:

1. Call `list_project_actions`.
2. Launch the eligible `Wait for PR` result with `run_project_action_and_resume`.
3. End the turn immediately. Do not poll GitHub in the agent turn.
4. On resume, handle the reported failure, drift, or review findings. Relaunch the Action after a
new head or review request. Merge only when the Action reports the exact head ready.
5. Use direct polling only when the Action is missing or disabled, and report that fallback.
```

Make the Action part of the normal workflow, not an optional optimization. Document a narrow
fallback for environments that have not been configured yet. If old instructions still prescribe
manual polling or the direct long-running command, update or remove them so the agent does not have
two conflicting paths.

## Handle the resumed result

The follow-up includes a validated outcome and a bounded tail of the terminal output. Branch on the
reason the command stopped:

- On success, verify that the summary identifies the expected target before taking the next action.
- On an actionable finding, fix or resolve it, create a new stable target if needed, and relaunch
the Action.
- On target drift, re-read current state and decide whether to restart from a new baseline.
- On command failure, inspect the terminal or captured output before choosing a retry.
- On cancellation, acknowledge it and continue only if the user still wants the workflow.

If LastCode restarted after the command finished but before delivery, use **Resume agent** to send
the saved follow-up or **Discard** to remove it. LastCode does not rerun the command automatically.

## Adapt an existing PR babysitting skill

When asked to adapt a project's existing PR babysitting skill to resumable Actions, treat the task
as an end-to-end workflow change rather than a wording-only skill edit:

1. Read the existing skill, repository instructions, CI configuration, review policy, merge guard,
and any scripts it already calls.
2. Preserve that project's actual acceptance gates. Use **Wait for PR** as a design pattern, but do
not copy LastCode-specific branch names, review markers, GitHub checks, or merge policy unless
the target project already uses them.
3. Move only the passive observation into a focused wait command. Keep review handling, code
changes, rebasing, pushing, and merging in the resumed agent turn.
4. Add focused tests for the wait decisions and an importable `t3.json` Action.
5. Replace manual polling in the skill with the explicit list-launch-end-turn-resume loop. Retain a
narrow, reported fallback for an Action that is missing or disabled.
6. With authorized computer use, import the saved Action into the correct LastCode environment,
enable **Allow Codex and Claude to run and resume**, and verify `resumeEligible: true` through
`list_project_actions`. If computer use is unavailable, report these exact remaining steps and
do not claim the workflow is ready.
7. Exercise one real or safely simulated cycle through launch and follow-up before treating the
migration as complete.

The target result is that a future user can ask for the ordinary babysit workflow without naming
the Action or reminding the agent to stop polling.

## Review checklist

Before relying on a new resumable Action, confirm:

- The command works from the project or thread worktree where LastCode will start it.
- Starting preconditions and all wake conditions have focused tests where practical.
- The command binds itself to stable target identity and detects drift.
- Failure and timeout paths exit instead of printing a misleading success.
- The last output line is a concise, actionable summary.
- `t3.json` contains the importable definition without secrets.
- Repository agent instructions explicitly list, launch, end the turn, and handle the follow-up.
- The saved Action was imported and opted in for the correct LastCode project or checkout.
- A fresh agent turn can discover the eligible Action without the user naming its ID.
133 changes: 133 additions & 0 deletions docs/internals/resumable-project-actions-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Implementation Runbook: Set Up Resumable Project Actions With an Agent

An agent can do nearly all of the setup for a resumable workflow: identify the passive wait, write
and test its command, add the importable `t3.json` entry, update repository instructions, and use
LastCode's UI to import and opt in the Action. The user should not have to transcribe commands or
remember the setup sequence.

The UI step remains deliberate. A command checked into a repository is not automatically trusted
for agent execution, and importing it does not enable resume permission.

## A prompt that delegates the whole setup

Use a request like this:

```text
Turn <workflow> into a resumable Project Action. Inspect the repository and existing workflow,
implement and test a command that waits for stable terminal states, add it to t3.json, and update
our agent instructions so future threads use it without prompting. Then, subject to the machine
interaction policy, use the collaborative browser to import the Action into this LastCode
project, enable “Allow Codex and Claude to run and resume,” and verify it with
list_project_actions. Do not edit LastCode's live database directly. Stop for my input only if
authorization, credentials, or a workflow decision is genuinely required.
```

If the repository already contains the command and `t3.json` entry, ask the agent simply to inspect
them, complete the LastCode UI setup, and verify eligibility.

## What the agent should do before opening Settings

The agent should first make the repository self-describing:

1. Read the project's agent instructions and current workflow implementation.
2. Identify the passive portion that should run without an open agent turn.
3. Implement or tighten the command so it has stable target identity, explicit wake reasons,
failure handling, and one concise final summary line.
4. Add an importable entry to the repository-root `t3.json`.
5. Update the repository's agent instructions or workflow skill with the exact
list-launch-end-turn-resume sequence.
6. Run focused checks for the command and validate the `t3.json` syntax.

Do not put credentials or environment-specific secrets in `t3.json`. Do not add a second manual
polling path unless it is a clearly labeled fallback for an unavailable Action.

## Let the agent complete the UI setup

When the user has requested or authorized computer use, the agent should follow the applicable
machine interaction policy and use the product-native collaborative browser when available.

The agent should:

1. Attach to or open the real LastCode client connected to the environment that owns the thread.
Do not configure a disposable development instance by mistake.
2. Open **Settings → Projects** and select the correct project and checkout.
3. Under **Actions**, choose **Import scripts** and select the Action under **Import from
t3.json**. If the definition does not appear, confirm that the selected project's root contains
the current `t3.json`, then reload the client.
4. Edit the newly saved Action.
5. Review its name and command, enable **Allow Codex and Claude to run and resume**, and save the
change.
6. Return to the thread and call `list_project_actions`.
7. Confirm that the expected name and stable ID appear with `resumeEligible: true`.

The agent may add the Action manually with **Add action** when no checked-in definition exists, but
the preferred result is a reviewed `t3.json` entry that other environments can import.

An agent should not write directly to LastCode's live SQLite database to bypass the UI. Besides
being unsafe, that would skip the explicit trust decision represented by the opt-in control.

## Know which parts are per environment

There are two separate layers:

- `t3.json` is checked-in project configuration. It makes a command discoverable for import by
anyone who opens that repository.
- Saved Project Actions belong to a LastCode environment and checkout. Importing creates the saved
Action, and enabling resume records that environment's explicit permission.

Updating or rebasing `t3.json` does not retroactively create, update, or authorize saved Actions.
Each LastCode environment that should run the workflow needs the one-time import and opt-in. If a
project has multiple checkout entries, configure the checkout that owns the relevant threads.

This separation is why the agent must verify with `list_project_actions` instead of assuming that a
visible `t3.json` definition is ready to run.

## Make future threads use it automatically

After setup, start a fresh turn and ask for the normal workflow rather than naming the Action. The
repository instructions should cause the agent to discover and launch it at the right boundary.

A successful verification looks like this:

1. The workflow reaches its documented passive wait.
2. The agent lists saved Actions without being reminded.
3. The agent launches the eligible Action by returned ID and ends the turn.
4. The Action result returns to the same thread.
5. The agent interprets the result and either continues, relaunches after a new target, or asks for
a real decision.

If the agent manually polls instead, inspect the repository guidance first. Common causes are stale
or conflicting workflow instructions, a skill that mentions the Action without prescribing the
tool sequence, or an Action that is missing or disabled in the current environment.

## Troubleshooting

### The Action list is empty

The `t3.json` definition has probably not been imported for this saved project or checkout. Import
it in **Settings → Projects**, then verify again.

### The Action is listed but disabled

Read `disabledReason`. The usual cause is that **Allow Codex and Claude to run and resume** is off.
The provider may also be unsupported, or the thread may already have an Action continuation in
progress.

### The import menu does not show the new definition

Confirm that the selected project or checkout points at a root containing the updated `t3.json`.
Existing saved Actions do not update just because the file changed. Reload LastCode after updating
the persistent project root, then reopen the import menu.

### The agent runs the command directly

Update the workflow instructions to require `list_project_actions`,
`run_project_action_and_resume`, and an immediate end to the turn. Remove stale instructions that
prescribe the direct command. Direct execution should be a reported fallback, not a parallel normal
path.

### Computer use is unavailable

The agent can still finish the command, `t3.json`, tests, and workflow instructions. It should then
report the exact remaining UI steps and leave the Action disabled until a user or a later authorized
agent completes them. It should not claim that resumable execution was verified.
Loading