@mingchuno/agent-workflows 0.4.0 → 0.5.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.
- package/dist/src/adapters/agents.js +9 -0
- package/dist/src/cli.js +14 -1
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.js +9 -11
- package/dist/src/domain.d.ts +6 -0
- package/dist/src/invocation.d.ts +2 -4
- package/dist/src/invocation.js +204 -107
- package/dist/src/operations.d.ts +1 -2
- package/dist/src/operations.js +18 -33
- package/dist/src/recovery.d.ts +20 -2
- package/dist/src/recovery.js +49 -1
- package/dist/src/runner.d.ts +6 -2
- package/dist/src/runner.js +81 -83
- package/dist/src/runtime/process.d.ts +1 -0
- package/dist/src/runtime/process.js +6 -2
- package/dist/src/store.d.ts +4 -2
- package/dist/src/store.js +69 -51
- package/dist/src/tui/data.d.ts +1 -1
- package/dist/src/tui/dialogs.js +1 -0
- package/dist/src/tui/monitor-navigation.d.ts +76 -0
- package/dist/src/tui/monitor-navigation.js +187 -0
- package/dist/src/tui/monitor.js +70 -183
- package/dist/src/tui/projection.d.ts +22 -0
- package/dist/src/tui/projection.js +49 -0
- package/dist/src/validation-selection.d.ts +6 -0
- package/dist/src/validation-selection.js +29 -0
- package/dist/src/workspace.js +3 -2
- package/docs/api.md +1 -1
- package/docs/configuration.md +33 -0
- package/docs/operations.md +4 -3
- package/package.json +1 -1
- package/dist/src/tui/actions.d.ts +0 -16
- package/dist/src/tui/actions.js +0 -23
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const openingFence = /^ {0,3}```agent-workflows-validation[ \t]*$/;
|
|
2
|
+
const closingFence = /^ {0,3}```[ \t]*$/;
|
|
3
|
+
const profileName = /^[a-zA-Z0-9_-]+$/;
|
|
4
|
+
/** Resolve the one ticket-selected set against project-owned commands. */
|
|
5
|
+
export function selectValidation(body, project) {
|
|
6
|
+
const lines = body.split(/\r?\n/);
|
|
7
|
+
let profile;
|
|
8
|
+
for (let index = 0; index < lines.length; index++) {
|
|
9
|
+
if (!openingFence.test(lines[index]))
|
|
10
|
+
continue;
|
|
11
|
+
if (profile !== undefined)
|
|
12
|
+
throw new Error("Duplicate agent-workflows validation block");
|
|
13
|
+
const selected = lines[++index]?.trim();
|
|
14
|
+
if (!selected || !profileName.test(selected))
|
|
15
|
+
throw new Error("Invalid agent-workflows validation profile name");
|
|
16
|
+
if (!closingFence.test(lines[++index] ?? ""))
|
|
17
|
+
throw new Error("Validation block must contain one profile name and a closing fence");
|
|
18
|
+
if (!Object.hasOwn(project.validationProfiles, selected))
|
|
19
|
+
throw new Error(`Unknown validation profile: ${selected}`);
|
|
20
|
+
profile = selected;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
...(profile === undefined ? {} : { profile }),
|
|
24
|
+
commands: [
|
|
25
|
+
...project.validation,
|
|
26
|
+
...(profile === undefined ? [] : project.validationProfiles[profile]),
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
package/dist/src/workspace.js
CHANGED
|
@@ -86,8 +86,9 @@ export class ExistingCheckout {
|
|
|
86
86
|
const diff = await this.git(project, "diff", "HEAD", "--binary", "--no-ext-diff");
|
|
87
87
|
const tracked = await this.git(project, "diff", "HEAD", "--no-renames", "--name-only", "-z");
|
|
88
88
|
const untracked = await this.git(project, "ls-files", "--others", "--exclude-standard", "-z");
|
|
89
|
+
const untrackedPaths = new Set(untracked.split("\0").filter(Boolean));
|
|
89
90
|
const paths = [
|
|
90
|
-
...new Set([...tracked.split("\0"), ...
|
|
91
|
+
...new Set([...tracked.split("\0"), ...untrackedPaths].filter(Boolean)),
|
|
91
92
|
].sort();
|
|
92
93
|
const hash = createHash("sha256")
|
|
93
94
|
.update(head)
|
|
@@ -105,7 +106,7 @@ export class ExistingCheckout {
|
|
|
105
106
|
const content = await readFile(absolute);
|
|
106
107
|
files[path] = fileStateDigest(content, stat.mode);
|
|
107
108
|
hash.update(path).update(content).update(String(stat.mode));
|
|
108
|
-
if (
|
|
109
|
+
if (untrackedPaths.has(path))
|
|
109
110
|
fullDiff += `\n--- /dev/null\n+++ b/${path}\n${content.toString()}`;
|
|
110
111
|
}
|
|
111
112
|
catch (error) {
|
package/docs/api.md
CHANGED
|
@@ -12,7 +12,7 @@ Omitting it preserves current-working-directory behavior for SDK callers.
|
|
|
12
12
|
`promptBaseDirectory` retains its narrower role and, when both are supplied,
|
|
13
13
|
overrides only relative prompt files.
|
|
14
14
|
|
|
15
|
-
`start()` validates registration, acquires ownership, launches DBOS, registers concurrency-one project queues, and starts polling. `poll(projectId?)` performs an immediate scan. `pause(projectId)` stops new starts while active work continues. `resume(projectId)` refuses blocked checkouts. `stop(runId)` waits for the active invocation/process to end, or cancels queued work. `retry(runId)` requires a terminal failed/blocked/cancelled run and a clean checkout, then returns a new linked run ID. `recover(runId)` returns a new execution ID for publication recovery of the same run. `shutdown()` stops intake, cancels and awaits active work, closes DBOS and releases ownership.
|
|
15
|
+
`start()` validates registration, acquires ownership, launches DBOS, registers concurrency-one project queues, and starts polling. `poll(projectId?)` performs an immediate scan. `pause(projectId)` stops new starts while active work continues. `resume(projectId)` refuses blocked checkouts. `stop(runId)` waits for the active invocation/process to end, or cancels queued work. `retry(runId)` requires a terminal failed/blocked/cancelled run and a clean checkout, then returns a new linked run ID using its saved issue. `retry(runId, commandId, { refreshIssue: true })` fetches and validates the current hosted issue once during admission, saving it on the new run. `recover(runId)` returns a new execution ID for publication recovery of the same run. `shutdown()` stops intake, cancels and awaits active work, closes DBOS and releases ownership.
|
|
16
16
|
|
|
17
17
|
Use `try/finally` to call `shutdown()`, including failed startup. A custom `workflowVersion` must change when its durable step order changes; finish existing work before replacing an incompatible version.
|
|
18
18
|
|
package/docs/configuration.md
CHANGED
|
@@ -28,11 +28,44 @@ part of the public SDK `Configuration` type.
|
|
|
28
28
|
| `pollIntervalMs` | 30000; minimum 100 |
|
|
29
29
|
| `includeAgentCoAuthors` | `true`; append co-author trailers for providers whose writable invocations produced retained changes |
|
|
30
30
|
| `validation` | Array of `{command,args,timeoutMs}`; no shell expansion; timeout defaults to 300000 ms |
|
|
31
|
+
| `validationProfiles` | Named, nonempty arrays of validation commands selectable by a ticket; defaults to `{}` |
|
|
31
32
|
| `agent` | Required default profile |
|
|
32
33
|
| `stages` | `implementation`, `publication`, `review`; each has optional `profile`, `prompt`, `promptFile`, `timeoutMs` |
|
|
33
34
|
|
|
34
35
|
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`.
|
|
35
36
|
|
|
37
|
+
## Ticket-selected validation
|
|
38
|
+
|
|
39
|
+
Define optional checks under a project in `validationProfiles` using the same
|
|
40
|
+
command format as `validation`:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"validation": [{ "command": "pnpm", "args": ["lint"] }],
|
|
45
|
+
"validationProfiles": {
|
|
46
|
+
"migration": [{ "command": "pnpm", "args": ["test:migrations"] }]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An issue description selects one profile with a standalone fenced block:
|
|
52
|
+
|
|
53
|
+
````markdown
|
|
54
|
+
```agent-workflows-validation
|
|
55
|
+
migration
|
|
56
|
+
```
|
|
57
|
+
````
|
|
58
|
+
|
|
59
|
+
The runner executes the project's `validation` commands first, then the selected
|
|
60
|
+
profile's commands. Without the block, only the baseline runs. The block must
|
|
61
|
+
contain exactly one configured profile name (`A-Z`, `a-z`, digits, `_`, or `-`);
|
|
62
|
+
duplicate, malformed, and unknown selections fail the run before checkout
|
|
63
|
+
preparation or agent invocation. The issue body is saved with the run, so edits
|
|
64
|
+
to the hosted issue do not change an existing run. A plain retry creates a new
|
|
65
|
+
run from its recorded issue. Use `retry RUN --refresh-issue` (or `R` in the
|
|
66
|
+
monitor) to snapshot the current hosted issue and its validation selection for
|
|
67
|
+
the new run. Later issue edits do not change that run.
|
|
68
|
+
|
|
36
69
|
Absolute configuration paths remain absolute. Effective state and checkout
|
|
37
70
|
paths are normalized once during startup before safety and ownership checks, so
|
|
38
71
|
a later working-directory change cannot redirect a running process. Validation
|
package/docs/operations.md
CHANGED
|
@@ -10,11 +10,12 @@ All commands accept `--config PATH` before the subcommand.
|
|
|
10
10
|
| `run [--project ID ...]` | Start selected projects in the foreground |
|
|
11
11
|
| `status [--json]` | Projects, runs and command outcomes |
|
|
12
12
|
| `inspect RUN` | Full run and invocation/session records as JSON |
|
|
13
|
-
| `logs RUN [--invocation ID]` | Local agent and validation artifacts
|
|
13
|
+
| `logs RUN [--invocation ID]` | Local stage, agent and validation artifacts |
|
|
14
14
|
| `pause PROJECT` / `resume PROJECT` | Queue an intake control command |
|
|
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
|
+
| `retry RUN --refresh-issue` | Queue a new attempt using the current hosted issue |
|
|
18
19
|
| `monitor [--notify]` | Attach an interactive terminal view; optionally alert on outcomes |
|
|
19
20
|
|
|
20
21
|
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.
|
|
@@ -57,7 +58,7 @@ fallback. An overflowing document shows its visible line range in the heading.
|
|
|
57
58
|
| Context | Keys |
|
|
58
59
|
| --- | --- |
|
|
59
60
|
| Dashboard | Left/Right project; Tab/Shift+Tab pane; Up/Down selection or scroll |
|
|
60
|
-
| Details | Enter opens; Up/Down or PgUp/PgDn scroll; Esc returns; `l` opens the latest current-execution session,
|
|
61
|
+
| Details | Enter opens; Up/Down or PgUp/PgDn scroll; Esc returns; `l` opens the latest current-execution session, or the stage diagnostic before a session exists |
|
|
61
62
|
| Progress | `[`/`]` inspect step history; End follows latest event |
|
|
62
63
|
| Sessions | `a` focuses session list; Up/Down selects invocation; `l` opens log |
|
|
63
64
|
| Validation | `v` opens validation logs |
|
|
@@ -176,7 +177,7 @@ After a blocked/failed task that cannot be recovered:
|
|
|
176
177
|
1. Read `inspect RUN`, logs, session IDs and the local Git diff.
|
|
177
178
|
2. Establish that no worker/process group is still running. If startup reports an old PID or process journal, inspect that exact process and stop it before recovery. Never remove a live owner's lease.
|
|
178
179
|
3. Preserve unfinished work on a developer-owned commit/branch or move it to a safe location. Resolve merge/rebase state yourself. Do not rely on DBOS to restore files.
|
|
179
|
-
4. Once the checkout is clean, request `retry RUN`. This creates a new attempt and branch from the configured base, keeping the old run and files/commits inspectable.
|
|
180
|
+
4. Once the checkout is clean, request `retry RUN`. This creates a new attempt and branch from the configured base, keeping the old run and files/commits inspectable. Use `retry RUN --refresh-issue` to capture the current hosted issue description and validation selection in the new run. The hosted issue must retain its identity, be open, and have the required labels; its selected validation profile must be configured.
|
|
180
181
|
|
|
181
182
|
A failed review after publication remains a failed automation attempt, even if its draft request exists. Explicit retry starts the full workflow as a new attempt; it does not silently modify the old request. Human review/merging remains separate. A stale review never claims coverage of a changed remote head.
|
|
182
183
|
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { RunRecord } from "../domain.js";
|
|
2
|
-
import type { ProjectState } from "../store.js";
|
|
3
|
-
/** Display eligibility only; the runner still validates command admission. */
|
|
4
|
-
export declare function actionAvailability({ run, project, projectRuns, pending, }: {
|
|
5
|
-
run?: RunRecord;
|
|
6
|
-
project?: ProjectState;
|
|
7
|
-
projectRuns: RunRecord[];
|
|
8
|
-
pending: boolean;
|
|
9
|
-
}): {
|
|
10
|
-
recoveryReason: string | undefined;
|
|
11
|
-
available: {
|
|
12
|
-
stop: boolean;
|
|
13
|
-
retry: boolean;
|
|
14
|
-
recover: boolean;
|
|
15
|
-
};
|
|
16
|
-
};
|
package/dist/src/tui/actions.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { recoveryUnavailable } from "../recovery.js";
|
|
2
|
-
/** Display eligibility only; the runner still validates command admission. */
|
|
3
|
-
export function actionAvailability({ run, project, projectRuns, pending, }) {
|
|
4
|
-
const recoveryReason = run
|
|
5
|
-
? (recoveryUnavailable(run) ??
|
|
6
|
-
project?.blocked ??
|
|
7
|
-
(projectRuns.some((item) => item.taskKey === run.taskKey && item.attempt > run.attempt)
|
|
8
|
-
? "A newer attempt has superseded this run"
|
|
9
|
-
: undefined))
|
|
10
|
-
: undefined;
|
|
11
|
-
return {
|
|
12
|
-
recoveryReason,
|
|
13
|
-
available: {
|
|
14
|
-
stop: Boolean(run && !pending && ["queued", "running"].includes(run.outcome)),
|
|
15
|
-
retry: Boolean(run &&
|
|
16
|
-
!pending &&
|
|
17
|
-
["failed", "blocked", "cancelled"].includes(run.outcome) &&
|
|
18
|
-
!projectRuns.some((item) => item.taskKey === run.taskKey &&
|
|
19
|
-
["queued", "running"].includes(item.outcome))),
|
|
20
|
-
recover: Boolean(run && !pending && !recoveryReason),
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|