@mingchuno/agent-workflows 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,39 +1,62 @@
1
1
  # Configuration
2
2
 
3
- The CLI reads `agent-workflows.json`, or `--config PATH`. Unknown properties are rejected by Zod. Paths are local filesystem paths; checkout paths are canonicalized before ownership is acquired. Use absolute paths when launching from different working directories.
3
+ The CLI reads `agent-workflows.json`, or `--config PATH`. Both paths resolve from
4
+ the launch directory. Unknown properties are rejected by Zod. Relative
5
+ configuration-owned paths resolve from the directory containing the resolved
6
+ configuration file, independently of where the CLI is launched. Use
7
+ `--config-base-directory DIRECTORY` to select another base; a relative option
8
+ value resolves from the launch directory. The base must be an existing directory
9
+ and is canonicalized before startup.
4
10
 
5
11
  | Runner field | Default / meaning |
6
12
  | ---------------- | --------------------------------------------------------------------------------------------------------- |
7
13
  | `id` | Required stable letters/digits/underscore/hyphen identity; scopes records and queues |
8
14
  | `databaseUrlEnv` | `AGENT_WORKFLOWS_DATABASE_URL`; environment variable containing a PostgreSQL connection URL with username |
9
- | `stateDirectory` | `.agent-workflows`; must resolve outside every managed checkout |
15
+ | `stateDirectory` | `.agent-workflows`; relative to the configuration base and outside every managed checkout |
10
16
  | `projects` | Nonempty array; duplicate IDs or canonical checkout roots are rejected |
11
17
 
18
+ The JSON file also accepts optional CLI-only `envFile`; it is intentionally not
19
+ part of the public SDK `Configuration` type.
20
+
12
21
  | Project field | Default / meaning |
13
22
  | ---------------------- | --------------------------------------------------------------------------------------------------- |
14
- | `id`, `checkout` | Required stable identity and existing Git repository root |
23
+ | `id`, `checkout` | Required stable identity and existing Git repository root; relative to the configuration base |
15
24
  | `hosting` | `provider` (`github`/`gitlab`), web `origin`, `repository`, and `tokenEnv`; no serialized tokens |
16
25
  | `labels` | `['ready-for-agent']`; all labels must match |
17
26
  | `baseBranch`, `remote` | `main`, `origin`; Git remote is independent of hosting API origin |
18
27
  | `branchTemplate` | `agent/{issue}-{attempt}`; `{issue}` required; `{attempt}` and `{run}` supported |
19
28
  | `pollIntervalMs` | 30000; minimum 100 |
20
- | `gitIdentity` | Required `name` and `email`; used by application commits |
29
+ | `includeAgentCoAuthors` | `true`; append co-author trailers for providers whose writable invocations produced retained changes |
21
30
  | `validation` | Array of `{command,args,timeoutMs}`; no shell expansion; timeout defaults to 300000 ms |
22
31
  | `agent` | Required default profile |
23
32
  | `stages` | `implementation`, `publication`, `review`; each has optional `profile`, `prompt`, `promptFile`, `timeoutMs` |
24
33
 
25
34
  Issues are selected in ascending issue-number order within each intake scan. Deduplication persists across restarts. An explicit retry is a new numbered attempt linked through `retryOf`.
26
35
 
36
+ Absolute configuration paths remain absolute. Effective state and checkout
37
+ paths are normalized once during startup before safety and ownership checks, so
38
+ a later working-directory change cannot redirect a running process. Validation
39
+ commands still execute in the canonical checkout; command names and arguments
40
+ are passed unchanged and are not rebased to the configuration directory.
41
+
42
+ `init` writes relative checkout and external sibling-state paths from the
43
+ effective configuration base. It still refuses to overwrite an existing file.
44
+ When the configuration is in the checkout root, the checkout is `.` and state
45
+ is the relative sibling `<checkout-name>.agent-workflows`.
46
+
27
47
  ## CLI environment files
28
48
 
29
- Select one file explicitly for any CLI command:
49
+ Set the optional top-level `envFile` property to load one file for every CLI
50
+ command that reads the configuration:
30
51
 
31
- ```sh
32
- agent-workflows --env-file ./runner.env run
33
- agent-workflows --env-file ./runner.env status --json
34
- agent-workflows --env-file /absolute/path/runner.env monitor
52
+ ```json
53
+ "envFile": "./runner.env"
35
54
  ```
36
55
 
56
+ Add this alongside the other top-level properties in `agent-workflows.json`.
57
+ `envFile` is a CLI-file setting, not part of the public SDK `Configuration`.
58
+ SDK callers continue to prepare their own process environment.
59
+
37
60
  Example `runner.env` (replace placeholders locally):
38
61
 
39
62
  ```dotenv
@@ -48,16 +71,19 @@ APP_REFERENCE='${APP_MODE}'
48
71
  or hosting values still fail existing validation. Missing keys are filled from
49
72
  the file; arbitrary application variable names are supported. `databaseUrlEnv`
50
73
  and `hosting.tokenEnv` still select which names the runner uses.
51
- - Relative paths resolve from the CLI launch directory, independently of
52
- `--config` and project checkouts. Absolute paths work too. No `.env` discovery
53
- or multiple-file layering is performed.
74
+ - Relative paths resolve from the effective configuration base: the directory
75
+ containing the resolved configuration file, or `--config-base-directory`
76
+ when supplied. Absolute paths work too. Omitting `envFile` performs no `.env`
77
+ discovery. Multiple-file layering is not supported.
54
78
  - Parsing uses Node's literal dotenv syntax: quotes and comments are supported;
55
79
  `$NAME`, `${NAME}`, backticks and `$(command)` in values are not expanded or
56
80
  executed. This is not shell sourcing.
57
- - The file is read once before the command action, database access, hosting
58
- adapters or runner creation. Missing or unreadable files stop the command with
59
- a nonzero exit and a path/error code, without printing file contents. Restart
60
- the runner to pick up edits. Help only displays usage and does not load files.
81
+ - The configuration is validated before its environment file can be discovered.
82
+ The file is then read once before database access, hosting adapters or runner
83
+ creation. Missing, unreadable or invalid files stop the command with a nonzero
84
+ exit without printing file contents. Restart the runner to pick up edits.
85
+ `init` creates a configuration without `envFile`; help and `init` do not load
86
+ an environment file.
61
87
  - The merged environment is shared across all projects in the runner. Validation,
62
88
  Git and agent worker subprocesses inherit it. Provider runtimes may apply their
63
89
  own environment policies to tools they launch; see [providers](providers.md).
@@ -71,12 +97,13 @@ redaction remains in effect; arbitrary variable support does not classify every
71
97
  application value as a secret. A GitHub API token does not configure Git push
72
98
  credentials.
73
99
 
74
- The flag belongs to `agent-workflows`, not the separate `pnpm db:migrate` command.
75
- SDK callers load their own process environment before creating a runner and
76
- continue passing `databaseUrl` explicitly. Node startup-only settings, such as
77
- `NODE_EXTRA_CA_CERTS`, must be set before launching Node to affect the CLI process.
78
- When invoking the script directly through Node, separate Node arguments from
79
- application arguments: `node -- dist/src/cli.js --env-file ./runner.env status`.
100
+ The setting belongs to the CLI configuration file, not the separate
101
+ `pnpm db:migrate` command. SDK callers load their own process environment before
102
+ creating a runner and continue passing `databaseUrl` explicitly. The setting's
103
+ path and contents are not part of publication-recovery fingerprints, so
104
+ credential rotation does not invalidate recovery. Node startup-only settings,
105
+ such as `NODE_EXTRA_CA_CERTS`, must be set before launching Node to affect the
106
+ CLI process.
80
107
 
81
108
  ## Profiles
82
109
 
@@ -128,11 +155,12 @@ in inspection explicitly; do not present an incomplete review as a clean review.
128
155
  These exact defaults are checked against the runtime source.
129
156
 
130
157
  Use either nonblank literal `prompt` text or a `promptFile` path, never both.
131
- Files must contain nonblank UTF-8 text. Relative paths resolve from the CLI
132
- configuration file's directory, independently of the launch directory; absolute
133
- paths are allowed. Files load once when the runner is constructed. Restart to
134
- apply edits. No templating, interpolation, or includes are supported. SDK callers
135
- supply `promptBaseDirectory` for relative paths.
158
+ Files must contain nonblank UTF-8 text. Relative paths use the same configuration
159
+ base as state and checkout paths; absolute paths are allowed. Files load once
160
+ when the runner is constructed. Restart to apply edits. No templating,
161
+ interpolation, or includes are supported. SDK callers use `pathBaseDirectory` as
162
+ the general base. `promptBaseDirectory`, when supplied, overrides it for prompt
163
+ files only.
136
164
 
137
165
  ```json
138
166
  "stages": {
@@ -146,6 +174,29 @@ supply `promptBaseDirectory` for relative paths.
146
174
  without aliases. Configure skills in the selected agent runtime and request them
147
175
  in task text. Old invocation records and skill snapshots remain readable.
148
176
 
177
+ ## Git identity and agent attribution
178
+
179
+ Commits use Git's native author and committer selection. The application does
180
+ not configure, validate, snapshot, or override identity. Repository, worktree,
181
+ global, system, and identity environment settings therefore behave as they do
182
+ for `git commit`, including distinct author and committer identities. Missing or
183
+ invalid identity fails at the commit operation with Git's error. The removed
184
+ `gitIdentity` property is rejected as unknown input.
185
+
186
+ Agent assistance is represented separately. With `includeAgentCoAuthors: true`,
187
+ the finalized commit message includes each provider once, ordered by its first
188
+ successful writable invocation that produced a retained change:
189
+
190
+ - `Codex <noreply@openai.com>` (OpenAI's published implementation convention)
191
+ - `Copilot <223556219+Copilot@users.noreply.github.com>` (GitHub's current
192
+ first-party convention, not a stable product API guarantee)
193
+
194
+ Read-only publication/review invocations and writable invocations with no
195
+ accepted retained change are not attributed. Existing trailers are preserved,
196
+ matching agent trailers are deduplicated, and exactly one
197
+ `Agent-Workflows-Run` trailer remains. Set `includeAgentCoAuthors: false` per
198
+ project to disable injection; existing publication trailers are not removed.
199
+
149
200
  Stage timeout defaults to 30 minutes, including profile validation and at most
150
201
  one format-correction attempt. Correction uses a fresh inspection-only session
151
202
  and only the remaining deadline. Provider failures, cancellation, timeout and
package/docs/database.md CHANGED
@@ -15,21 +15,5 @@ Do not edit applied migration files or use schema push against existing data. Ad
15
15
 
16
16
  The initial migration adopts the original application's identical tables using `IF NOT EXISTS`, preserving records and constraints. This supports the original schema, not arbitrary manually altered schemas; inspect and reconcile any local schema changes first.
17
17
 
18
- ## Query boundary
19
-
20
- `Store` uses typed Drizzle inserts, updates and selects. Concurrent JSON record patches use a transaction and row lock to preserve unrelated fields. Full-scope run and invocation queries sort their JSON fields in memory; introduce typed indexed columns if history size requires database pagination.
21
-
22
- Retry admission locks the project row before checking task history, then commits
23
- the new run, project unblocking and admission events in one transaction. The
24
- project lock serializes requests even when they target different historical
25
- attempts. Runner's checkout/process safety check runs while that lock is held;
26
- command replay skips it and does not write new events.
27
-
28
- `src/db/locks.ts` contains the only application driver SQL: fixed, parameterized PostgreSQL session-lock calls, which have no Drizzle query-builder equivalent. Generated migration SQL and the frozen legacy-schema test fixture are intentional SQL artifacts. No interpolated SQL template strings are used for record access.
29
-
30
- Execution history is stored in the existing run JSON record. Publication recovery
31
- adds optional fields without changing SQL tables; no migration or backfill is
32
- required. Legacy records remain readable, but lack the evidence needed for
33
- recovery. Recovery admission atomically appends an execution, queues the same
34
- run and writes an event under the project/task locks used by retry admission.
35
- The persisted execution ID lets dispatch reconcile a DBOS fork across crashes.
18
+ The persistence and locking rationale is recorded in
19
+ [ADR 0005](adr/0005-postgresql-persistence-boundary.md).
@@ -15,7 +15,7 @@ All commands accept `--config PATH` before the subcommand.
15
15
  | `stop RUN` | Queue cancellation; success means active local work has stopped |
16
16
  | `recover RUN` | Continue a failed publication step using completed checkpoints |
17
17
  | `retry RUN` | Queue an explicit new attempt after checkout validation |
18
- | `monitor` | Attach an interactive terminal view |
18
+ | `monitor [--notify]` | Attach an interactive terminal view; optionally alert on outcomes |
19
19
 
20
20
  Control commands return a command ID and `pending`; inspect `status --json` or the monitor for success/failure. With no runner, commands stay pending. Run and monitor are separate processes. Closing the monitor never cancels work. Ctrl-C on the runner stops intake, cancels active work, waits for process termination and releases ownership. Queued issues remain durable for the next start.
21
21
 
@@ -27,10 +27,37 @@ prove that a runner is alive. Requires an interactive terminal of at least
27
27
  compact terminals show the focused pane. Titles and identifiers are available
28
28
  in full in scrollable details. `NO_COLOR=1` disables semantic colors.
29
29
 
30
+ `monitor --notify` emits one desktop notification when an Execution first
31
+ reaches `completed`, `failed`, `blocked`, `cancelled`, `no-change` or
32
+ `ineligible` during that monitor session. The initial snapshot is silent;
33
+ later terminal Executions are detected across every visible project, including
34
+ Executions first seen after a database reconnection. Delivery uses OSC 9 and is
35
+ best-effort: notifications are not persisted, retried or acknowledged, and a
36
+ terminal write failure does not affect monitoring or workflow state. Current
37
+ iTerm2, Kitty, WezTerm and Ghostty releases are supported; other OSC 9
38
+ implementations may work, while Windows Terminal is not supported in this
39
+ version. Terminal permissions and settings determine whether an alert appears,
40
+ including whether foreground alerts are suppressed.
41
+
42
+ The notification payload is display-only and contains only
43
+ `agent-workflows: <project> · <issue reference> · <outcome>`. It excludes issue
44
+ titles, diagnostics, paths and internal Run, Execution and session identifiers.
45
+ Under tmux, the monitor emits one layer of DCS passthrough wrapping. tmux 3.3
46
+ and later requires `set -g allow-passthrough on`; the CLI does not change tmux
47
+ configuration.
48
+
49
+ Run details is one responsive, vertically scrollable document. It leads with
50
+ the issue, outcome, phase, attempt, total elapsed time and branch, and adds an
51
+ attention summary only when operator action may be required. At 140 columns
52
+ and above, execution history appears beside validation and agent-session
53
+ evidence; narrower terminals stack those sections in the same reading order.
54
+ The primary design target is 160×48, with 80×24 retained as the functional
55
+ fallback. An overflowing document shows its visible line range in the heading.
56
+
30
57
  | Context | Keys |
31
58
  | --- | --- |
32
59
  | Dashboard | Left/Right project; Tab/Shift+Tab pane; Up/Down selection or scroll |
33
- | Details | Enter opens; Up/Down or PgUp/PgDn scroll; Esc returns |
60
+ | Details | Enter opens; Up/Down or PgUp/PgDn scroll; Esc returns; `l` opens the latest current-execution session, preferring a running session |
34
61
  | Progress | `[`/`]` inspect step history; End follows latest event |
35
62
  | Sessions | `a` focuses session list; Up/Down selects invocation; `l` opens log |
36
63
  | Validation | `v` opens validation logs |
@@ -61,10 +88,12 @@ Execution duration includes eligibility, preparation and waits within one
61
88
  execution. It excludes queue waiting and gaps before publication recovery.
62
89
  Details show each execution, its queue wait and the run's total elapsed time.
63
90
  Completed execution durations freeze at their first terminal outcome. Records
64
- without timing evidence show an em dash. Noninteractive tools use `status --json`
65
- and `inspect`. See [TUI design](tui-redesign.md) for implementation boundaries.
91
+ without timing evidence use factual labels such as `not started`, `not recorded`
92
+ or `unavailable`. Noninteractive tools use `status --json` and `inspect`. Run
93
+ details keeps complete errors under Diagnostics and exact identifiers, paths,
94
+ profiles and ISO timestamps under Technical details.
66
95
 
67
- ## Observability Landscape
96
+ ## Observability landscape
68
97
 
69
98
  This section includes only options that run locally without a license key.
70
99
  Cloud services and tools requiring a license key are excluded. These boundaries
@@ -92,31 +121,30 @@ Conductor service or cloud login. See the [DBOS CLI reference](https://docs.dbos
92
121
  The initial DBOS workflow ID equals the run ID. Publication recovery keeps the
93
122
  run ID and adds a new DBOS execution ID; `inspect RUN` includes execution history
94
123
  and a persisted recovery eligibility assessment. Admission performs live checks.
95
- Inspect both layers: the
96
- runner catches execution errors and persists application outcomes, so a DBOS
97
- `SUCCESS` can accompany an application `failed` or `blocked` outcome. DBOS step
98
- history does not replace the local agent/validation artifacts.
99
-
100
- A browser dashboard is an extension path, not a bundled feature. A local server
101
- could combine the [Store query/event API](api.md#query-and-event-interface) with
102
- `DBOSClient.create({ systemDatabaseUrl: databaseUrl })`, joining records by run ID.
103
- Neither inspector needs to launch another DBOS runtime. Keep database access on
104
- the server and bind a local-only dashboard to loopback. See the
105
- [inspection example](../examples/observe.ts) for Store lifecycle handling.
106
-
107
- Route dashboard controls through `Store.request` or the runner's public controls.
108
- Direct DBOS cancellation, resumption or forking bypasses application coordination
109
- for process termination, checkout safety and retry admission.
124
+ Inspect both layers: the runner catches execution errors and persists application
125
+ outcomes, so DBOS `SUCCESS` can accompany an application `failed` or `blocked`
126
+ outcome. DBOS step history does not replace local agent or validation artifacts.
127
+ See [ADR 0003](adr/0003-run-and-execution-identity.md) for the identity model.
110
128
 
111
129
  ## Ownership and recovery
112
130
 
113
- Only the runner may edit or switch managed checkouts while it is active. PostgreSQL advisory locks protect runner/configuration and checkout identities. A local Git-directory lease also prevents runners using different databases from owning the same checkout. Worker/validation process-group journals prevent reuse while old work may still run.
131
+ Only the runner may edit or switch managed checkouts while it is active.
132
+ PostgreSQL advisory locks, a local Git-directory lease, and worker/validation
133
+ process journals prevent concurrent ownership and reuse while old work may still
134
+ run. See [ADR 0002](adr/0002-existing-checkouts-and-exclusive-ownership.md) for
135
+ the checkout and concurrency tradeoff.
114
136
 
115
137
  Git process journals live in `<git-directory>/agent-workflows-processes/`, independently of the configured state directory. A surviving Git process blocks ownership acquisition after a crash. Stop requests propagate to active fetch, staging, commit and push commands; interrupted effects still require reconciliation.
116
138
 
117
139
  Startup and phase boundaries check ownership assumptions, branch/head and actual changes. Unfinished files are never reset, cleaned, stashed or discarded automatically. Dirty files, unresolved Git operations, branch collisions, unexpected mutations and ambiguous agent recovery become inspectable blocked states. Other eligible projects continue.
118
140
 
119
- Publication effects have independent DBOS checkpoints. A task commit carries `Agent-Workflows-Run`; commit recovery checks parent and marker, push recovery checks the remote ref, request creation checks the source branch, and review publication checks stable markers. Transient publication failures use bounded retries and reconciliation. Interrupted agent stages block rather than starting another writer.
141
+ Publication effects have independent DBOS checkpoints. A task commit carries
142
+ exactly one `Agent-Workflows-Run` marker and, by default, co-author trailers for
143
+ providers with retained writable contributions. Commit, push, request creation,
144
+ and review publication reconcile their durable identities before retrying an
145
+ ambiguous effect. Interrupted agent stages block rather than starting another
146
+ writer. See [ADR 0003](adr/0003-run-and-execution-identity.md) for the recovery
147
+ boundary.
120
148
 
121
149
  ## Publication recovery
122
150
 
@@ -156,6 +184,10 @@ A failed review after publication remains a failed automation attempt, even if i
156
184
 
157
185
  Git hooks are disabled for application-authored task commits; configure required checks as validation commands. Changed symlinks and submodules require manual handling. Checkout checks detect boundary changes but do not sandbox custom adapters or prevent unrelated local tools from writing.
158
186
 
187
+ Git chooses author and committer through its normal configuration and environment
188
+ rules. Runner startup performs no identity preflight; missing identity fails at
189
+ the commit step before push or hosting publication.
190
+
159
191
  Validation records say exactly which command ran, when, its exit code and artifact path. No-change work skips publication. Generated commit/request text is validated and saved before Git/API writes. Logs, prompts and errors redact configured credentials and recognized secret environment values; this does not sanitize arbitrary repository content or secrets unknown to the runner.
160
192
 
161
193
  Back up both PostgreSQL and the state directory if history/artifacts matter. The checkout and runtime session stores are separate local state. Losing them cannot be repaired from DBOS checkpoints alone. Do not change a custom workflow's step order or rename projects while its runs are pending; use a new workflow version and finish or explicitly resolve existing runs first.
package/docs/providers.md CHANGED
@@ -21,7 +21,7 @@ The runner deliberately does not automatically resume interrupted agent work. Ru
21
21
 
22
22
  ## Environment inheritance
23
23
 
24
- CLI `--env-file` values reach validation commands, Git subprocesses and agent
24
+ CLI `envFile` values reach validation commands, Git subprocesses and agent
25
25
  workers through the runner's process environment. SDK callers get the same
26
26
  inheritance from their own process environment. The installed Codex SDK forwards
27
27
  that environment to its executable; Copilot uses it for its local runtime, with
@@ -58,7 +58,7 @@ In GitHub **Settings → Developer settings → Personal access tokens → Fine-
58
58
 
59
59
  Git push uses the checkout's configured remote and Git credentials independently of this API token. The API adapter does not require **Contents** permission. If you also use this PAT for HTTPS Git pushes, grant **Contents: Read and write**; pushing changes to `.github/workflows/` additionally requires **Workflows: Read and write**. Do not embed credentials in remote URLs.
60
60
 
61
- If access is denied, check the selected owner/repository, PR write permission, token expiration, organization approval, and the token owner's repository access. If you replace the token value, restart the runner with the updated environment; existing environment variables override `--env-file` values. An already failed run requires explicit [recovery](operations.md#ownership-and-recovery); updating permissions does not restart it.
61
+ If access is denied, check the selected owner/repository, PR write permission, token expiration, organization approval, and the token owner's repository access. If you replace the token value, restart the runner with the updated environment; existing environment variables override configured `envFile` values. An already failed run requires explicit [recovery](operations.md#ownership-and-recovery); updating permissions does not restart it.
62
62
 
63
63
  References: GitHub's [PAT creation guide](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens), [issue permissions](https://docs.github.com/en/rest/issues/issues#list-repository-issues), [PR creation permissions](https://docs.github.com/en/rest/pulls/pulls#create-a-pull-request), and [review permissions](https://docs.github.com/en/rest/pulls/reviews#create-a-review-for-a-pull-request).
64
64
 
@@ -1,13 +1,13 @@
1
1
  import { configSchema } from "@mingchuno/agent-workflows";
2
2
 
3
- /** Replace paths, repository, identity and model IDs with locally available values. */
3
+ /** Replace paths, repository and model IDs with locally available values. */
4
4
  export const configuration = configSchema.parse({
5
5
  id: "local",
6
- stateDirectory: "/absolute/path/outside-the-checkout/agent-workflows-state",
6
+ stateDirectory: "../application.agent-workflows",
7
7
  projects: [
8
8
  {
9
9
  id: "application",
10
- checkout: "/absolute/path/to/existing-checkout",
10
+ checkout: ".",
11
11
  hosting: {
12
12
  provider: "gitlab",
13
13
  origin: "https://git.example.com/gitlab",
@@ -17,7 +17,7 @@ export const configuration = configSchema.parse({
17
17
  labels: ["ready-for-agent"],
18
18
  baseBranch: "main",
19
19
  branchTemplate: "agent/{issue}-{attempt}",
20
- gitIdentity: { name: "Workflow Agent", email: "agent@example.com" },
20
+ includeAgentCoAuthors: true,
21
21
  agent: { provider: "codex" },
22
22
  stages: {
23
23
  implementation: {
package/examples/run.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { readFile } from "node:fs/promises";
2
+ import { dirname, resolve } from "node:path";
2
3
  import {
3
4
  configSchema,
4
5
  createAgents,
@@ -7,13 +8,15 @@ import {
7
8
  } from "@mingchuno/agent-workflows";
8
9
  import { reportingWorkflow } from "./custom-workflow.js";
9
10
 
11
+ const configPath = resolve(process.argv[2] ?? "agent-workflows.json");
10
12
  const config = configSchema.parse(
11
- JSON.parse(await readFile(process.argv[2] ?? "agent-workflows.json", "utf8")),
13
+ JSON.parse(await readFile(configPath, "utf8")),
12
14
  );
13
15
  const databaseUrl = process.env[config.databaseUrlEnv];
14
16
  if (!databaseUrl) throw new Error(`Set ${config.databaseUrlEnv}`);
15
17
  const runner = new Runner({
16
18
  config,
19
+ pathBaseDirectory: dirname(configPath),
17
20
  databaseUrl,
18
21
  hosting: createHosting,
19
22
  agents: createAgents(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingchuno/agent-workflows",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Local durable coding workflows on DBOS",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,41 +0,0 @@
1
- # Architecture
2
-
3
- DBOS owns workflow execution, durable steps and concurrency-one project queues. The runner only discovers candidates, dispatches durable identities and handles local operator commands. It does not introduce a workflow language or an interchangeable scheduler.
4
-
5
- - `config.ts` / `domain.ts`: validated configuration, vocabulary and adapter contracts.
6
- - `runner.ts`: local ownership, intake/deduplication, DBOS lifecycle and operator controls.
7
- - `operations.ts`: reusable durable coding operations and the default workflow.
8
- - `prompts.ts` / `invocation.ts`: resolved task text, output contracts and bounded format correction.
9
- - `evidence.ts`: indexed, hashed change artifacts and capture limits.
10
- - `recovery.ts`: publication recovery eligibility, input fingerprints and live safety checks.
11
- - `workspace.ts`: existing-checkout Git operations and change verification.
12
- - `store.ts`: typed Drizzle queries for run, invocation, project, command and event records; `db/schema.ts` and `drizzle/` own the application schema and migrations.
13
- - `adapters/`: provider clients and isolated SDK workers.
14
- - `runtime/`: process groups, ownership journals and redacted logging.
15
- - `cli.ts` / `tui/`: shared command/query interfaces.
16
-
17
- Application records live in `agent_workflows`; DBOS maintains its own execution schema in the same PostgreSQL database. Large streamed agent/validation logs live under the configured state directory, referenced by records. Interrupted or failed agent calls are never automatically retried. A returned response that fails its output contract may receive one fresh inspection-only format-correction attempt within the same stage deadline. Publication retries and explicit recovery reconcile external state first. Clean terminal state and terminal workflow outcome are deliberately separate.
18
-
19
- Node/PostgreSQL/Git are the only runtime infrastructure; providers require their normal local authentication. Zod, Commander, Ink/React, Drizzle/node-postgres, Pino, Octokit and Gitbeaker handle standard infrastructure. Drizzle ORM and Codex SDK are Apache-2.0; the other listed runtime libraries and Copilot SDK are MIT-licensed. Exact dependency versions are pinned by the lockfile. No custom HTTP client, CLI parser or terminal renderer is introduced.
20
-
21
- The test boundary is the public runner/workflow API using real PostgreSQL, real temporary Git repositories and controlled adapters. Separate adapter contracts exercise SDK argument/event mapping and HTTP behavior. Process-level recovery tests terminate a runner after external effects and restart it against the same state. Runtime/provider smoke calls are intentionally separate from deterministic acceptance tests.
22
-
23
- The runner supports existing checkouts only. Higher per-project concurrency requires isolated workspaces and lifecycle design; changing the DBOS queue limit alone is unsafe.
24
-
25
- ## Package boundary
26
-
27
- Keep one package while the SDK, CLI and TUI share a runtime, schema and release cycle. `src/adapters`, `src/runtime`, `src/db` and `src/tui` provide internal boundaries without workspace packages. Split into a monorepo when a separately deployed app or independently versioned package needs its own dependencies and build. `pnpm-workspace.yaml` currently configures installation policy only.
28
-
29
- ## Run and execution identity
30
-
31
- A run owns the branch, commit and publication markers. Its initial DBOS execution
32
- uses the run ID; publication recovery forks the failed execution at its failed
33
- step under a new execution ID, preserving completed checkpoints and the original
34
- run input. Execution history stays in the run record. Fresh retry creates a new
35
- run and branch.
36
-
37
- Recovery admission and retry share a project lock. Admission persists the fork ID
38
- before dispatch so a restarted runner can adopt an existing fork. Recovery gates
39
- run inside the first operation that actually executes, avoiding copied pause and
40
- safety decisions. Recovery is limited to the default workflow's publication
41
- steps; interrupted agents still require manual inspection.