@rse/ase 2.0.6 → 2.0.8
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/dst/ase-agent-definition-api.d.ts +2 -0
- package/dst/ase-agent-definition-core.js +24 -3
- package/dst/ase-agent-fleet.js +2 -1
- package/dst/ase-agent-relay-client.js +3 -4
- package/dst/ase-agent-runtime-engine.js +22 -4
- package/dst/ase-agent-runtime-tool.js +10 -8
- package/dst/ase-agent-runtime.js +8 -4
- package/dst/ase-config-schema.js +4 -1
- package/dst/ase-lib-fetch.js +12 -0
- package/dst/ase-lib-server-cli.js +8 -5
- package/dst/ase-man-catalog.js +1 -1
- package/dst/ase-task-board-diff.js +120 -0
- package/dst/ase-task-board-tui-control.js +8 -5
- package/dst/ase-task-board-tui-model.js +54 -14
- package/dst/ase-task-board-tui-popup.js +41 -8
- package/dst/ase-task-board-tui.js +42 -27
- package/dst/ase-task-board-web-client.css +1 -1
- package/dst/ase-task-board-web-client.html +16 -0
- package/dst/ase-task-board-web-client.js +33 -33
- package/dst/ase-task-board-web-server.js +44 -9
- package/dst/ase-task-board.js +12 -4
- package/dst/ase-task-store-client.js +4 -5
- package/dst/ase-task-store-plugin-gitea.js +3 -3
- package/dst/man/ase-agent-adhoc.md +25 -6
- package/dst/man/ase-agent-condenser.md +7 -0
- package/dst/man/ase-agent-editor.md +7 -0
- package/dst/man/ase-agent-estimator.md +7 -0
- package/dst/man/ase-agent-fleet.md +7 -4
- package/dst/man/ase-agent-implementer.md +7 -0
- package/dst/man/ase-agent-integrator.md +7 -0
- package/dst/man/ase-agent-qualifier.md +7 -0
- package/dst/man/ase-agent-rebooter.md +7 -0
- package/dst/man/ase-agent-researcher.md +7 -0
- package/dst/man/ase-config-init.md +2 -1
- package/dst/man/ase-config.md +5 -0
- package/dst/man/ase-task-board.md +44 -2
- package/package.json +11 -10
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.github/plugin/plugin.json +1 -1
- package/plugin/meta/ase-common-task.md +33 -1
- package/plugin/meta/ase-control.md +14 -0
- package/plugin/meta/ase-format-specbook.yaml +9 -9
- package/plugin/meta/ase-skill.md +7 -0
- package/plugin/mods/ase-mods-common.ts +73 -42
- package/plugin/mods/ase-mods-help-hint.ts +1 -1
- package/plugin/mods/ase-mods-task-edit.ts +427 -0
- package/plugin/mods/ase-mods.ts +45 -14
- package/plugin/skills/ase-code-edit/SKILL.md +53 -16
- package/plugin/skills/ase-code-edit/help.md +26 -13
- package/plugin/skills/ase-code-lint/SKILL.md +7 -3
- package/plugin/skills/ase-help-intent/data.md +248 -36
- package/plugin/skills/ase-help-skill/catalog.md +1 -0
- package/plugin/skills/ase-meta-workflow/workflow.txt +2 -0
- package/plugin/skills/ase-repo-changelog/SKILL.md +29 -10
- package/plugin/skills/ase-repo-changelog/help.md +5 -1
- package/plugin/skills/ase-repo-commit/SKILL.md +4 -1
- package/plugin/skills/ase-repo-dissect/help.md +2 -1
- package/plugin/skills/ase-repo-stage/SKILL.md +459 -0
- package/plugin/skills/ase-repo-stage/help.md +120 -0
- package/plugin/skills/ase-spec-edit/SKILL.md +20 -12
- package/plugin/skills/ase-spec-edit/help.md +22 -14
- package/plugin/skills/ase-task-edit/SKILL.md +114 -9
- package/plugin/skills/ase-task-edit/help.md +60 -0
- package/plugin/skills/ase-task-grill/SKILL.md +35 -20
- package/plugin/skills/ase-task-grill/help.md +18 -8
- /package/plugin/mods/{ase-mods-evaluate.ts → ase-mods-meta-evaluate.ts} +0 -0
- /package/plugin/mods/{ase-mods-grill.ts → ase-mods-task-grill.ts} +0 -0
|
@@ -13,6 +13,7 @@ import { userId } from "./ase-service-otel.js";
|
|
|
13
13
|
import { Config } from "./ase-config-core.js";
|
|
14
14
|
import { configSchema, webColorDefaults, webColorNames } from "./ase-config-schema.js";
|
|
15
15
|
import { buildBoard, watchTasks, toneOf, laneMoves, cardMoves, BoardState, attachmentTabs, isDiff, diffTones, dataLang, dataLoad, dataSpans, newTaskText, createTask, saveTask, TaskConflict, watchAgents } from "./ase-task-board-core.js";
|
|
16
|
+
import { diffHunks, diffMarkdown, diffMarksToHTML } from "./ase-task-board-diff.js";
|
|
16
17
|
import { layoutGraph, drawGraphSVG } from "./ase-task-board-graph.js";
|
|
17
18
|
import { flowOf, layoutFlow, drawFlowSVG } from "./ase-task-board-flow.js";
|
|
18
19
|
import { filterBoard, dropStandalone } from "./ase-task-board-filter.js";
|
|
@@ -94,9 +95,9 @@ const markedLoad = async (remote) => {
|
|
|
94
95
|
(title ? ` title="${escapeHTML(title)}"` : "") + ">" : escapeHTML(text);
|
|
95
96
|
},
|
|
96
97
|
code({ text, lang }) {
|
|
97
|
-
if (lang === "mermaid") {
|
|
98
|
+
if (lang === "mermaid" && !text.includes("⟦chg:")) {
|
|
98
99
|
try {
|
|
99
|
-
return `<div class="diagram">${renderMermaidSVG(text)}</div>`;
|
|
100
|
+
return `<div class="diagram">${renderMermaidSVG(text, { bg: "var(--c-paper)", fg: "var(--c-text)" })}</div>`;
|
|
100
101
|
}
|
|
101
102
|
catch {
|
|
102
103
|
/* fall through to the plain rendering of the source */
|
|
@@ -119,12 +120,12 @@ const renderPlan = async (body, remote = false) => {
|
|
|
119
120
|
const outside = fence === "";
|
|
120
121
|
fence = TaskFormat.fenceTrack(fence, line);
|
|
121
122
|
return !outside || fence !== "" ? line : line
|
|
122
|
-
.replace(/^(\s*(?:[-*]|\d+[.)])\s+)\[([ x/?\->])\]/, (_m, lead, box) => `${lead}⟦box:${boxes[box]}⟧`);
|
|
123
|
+
.replace(/^(\s*(?:[-*]|\d+[.)])\s+(?:⟦chg:[a-z-]+⟧)?)\[([ x/?\->])\]/, (_m, lead, box) => `${lead}⟦box:${boxes[box]}⟧`);
|
|
123
124
|
}).join("\n");
|
|
124
125
|
if (!marked.has(remote))
|
|
125
126
|
marked.set(remote, markedLoad(remote));
|
|
126
127
|
const html = (await marked.get(remote)).parse(prepared, { async: false });
|
|
127
|
-
return html.replace(/⟦box:([a-z]+)⟧/g, (_m, state) => `<span class="box ${state}" title="[${escapeHTML(boxChars[state] ?? " ")}]"></span>`);
|
|
128
|
+
return diffMarksToHTML(html.replace(/⟦box:([a-z]+)⟧/g, (_m, state) => `<span class="box ${state}" title="[${escapeHTML(boxChars[state] ?? " ")}]"></span>`));
|
|
128
129
|
};
|
|
129
130
|
const colorRoles = Object.keys(webColorDefaults);
|
|
130
131
|
const colorBases = (log) => {
|
|
@@ -154,10 +155,18 @@ const editorKeymap = (log) => {
|
|
|
154
155
|
const value = cfg.get("board.web.editor.keymap");
|
|
155
156
|
return value === "vim" || value === "emacs" ? value : "default";
|
|
156
157
|
};
|
|
157
|
-
/*
|
|
158
|
-
|
|
158
|
+
/* the color theme of the web board, resolved from the
|
|
159
|
+
"board.web.theme" configuration (on each page load) */
|
|
160
|
+
const boardTheme = (log) => {
|
|
161
|
+
const cfg = new Config("config", configSchema, log);
|
|
162
|
+
cfg.read();
|
|
163
|
+
const value = cfg.get("board.web.theme");
|
|
164
|
+
return value === "light" || value === "dark" ? value : "auto";
|
|
165
|
+
};
|
|
166
|
+
/* render a standalone document (styled by the client stylesheet) out of key/value
|
|
167
|
+
fields (optionally marked as added or removed), separated by a line from the content */
|
|
159
168
|
const fieldsDocument = (fields, content) => {
|
|
160
|
-
const rows = fields.map(([k, v]) => `<tr><td class="k">${escapeHTML(k)}</td><td>${escapeHTML(v)}</td></tr>`).join("");
|
|
169
|
+
const rows = fields.map(([k, v, mark]) => `<tr${mark !== undefined ? ` class="${mark}"` : ""}><td class="k">${escapeHTML(k)}</td><td>${escapeHTML(v)}</td></tr>`).join("");
|
|
161
170
|
return "<!DOCTYPE html><html><head><meta charset=\"utf-8\">" +
|
|
162
171
|
"<link rel=\"stylesheet\" href=\"/task-board/colors.css\">" +
|
|
163
172
|
"<link rel=\"stylesheet\" href=\"/task-board/ase-task-board-web-client.css\"></head><body class=\"plan\"><article>" +
|
|
@@ -166,6 +175,16 @@ const fieldsDocument = (fields, content) => {
|
|
|
166
175
|
};
|
|
167
176
|
/* render a task plan as a standalone document: frontmatter fields and the numbered plan sections */
|
|
168
177
|
const taskDocument = async (keys, body) => fieldsDocument([...keys].filter(([k]) => k !== "Type"), await renderPlan(body));
|
|
178
|
+
const isPlanText = (value) => {
|
|
179
|
+
const plan = value;
|
|
180
|
+
return typeof plan?.body === "string" && Array.isArray(plan.keys) && plan.keys.every((field) => Array.isArray(field) && field.length === 2 && field.every((text) => typeof text === "string"));
|
|
181
|
+
};
|
|
182
|
+
/* render the diff of two task plans as a standalone document, in the look of a task plan */
|
|
183
|
+
const diffDocument = async (before, after) => fieldsDocument(diffHunks(before.keys, after.keys, (field) => JSON.stringify(field)).flatMap(({ kept, removed, added }) => [
|
|
184
|
+
...kept,
|
|
185
|
+
...removed.map(([k, v]) => [k, v, "del"]),
|
|
186
|
+
...added.map(([k, v]) => [k, v, "add"])
|
|
187
|
+
]), await renderPlan(diffMarkdown(before.body, after.body)));
|
|
169
188
|
/* render a task plan attachment as a standalone document: its fields and
|
|
170
189
|
its content, with images embedded, Markdown rendered, YAML or JSON data syntax-highlighted, a diff
|
|
171
190
|
colored per line, binary content as a placeholder, and else verbatim text */
|
|
@@ -335,11 +354,13 @@ const guarded = (handler) => async (request, h) => {
|
|
|
335
354
|
};
|
|
336
355
|
/* register the page routes of the web board: its client assets and its colors */
|
|
337
356
|
const registerPageRoutes = (server, log) => {
|
|
338
|
-
/* the single page of the web board, with its stylesheet and browser-side code
|
|
357
|
+
/* the single page of the web board, with its stylesheet and browser-side code,
|
|
358
|
+
and with its color theme (resolved on each page load) on its root element */
|
|
339
359
|
server.route({
|
|
340
360
|
method: "GET",
|
|
341
361
|
path: "/task-board",
|
|
342
|
-
handler: (_request, h) => h.response(clientAsset("html")
|
|
362
|
+
handler: (_request, h) => h.response(clientAsset("html")
|
|
363
|
+
.replace(/<html\b/, `<html data-theme="${boardTheme(log)}"`)).type("text/html; charset=utf-8")
|
|
343
364
|
});
|
|
344
365
|
server.route({
|
|
345
366
|
method: "GET",
|
|
@@ -439,12 +460,26 @@ const registerViewRoutes = (server, log) => {
|
|
|
439
460
|
group: board.groups.find((g) => g.lanes.some((l) => l.status === card.status))?.title ?? "",
|
|
440
461
|
epic: card.group,
|
|
441
462
|
doc: await taskDocument(parts.keys, parts.body),
|
|
463
|
+
plan: { keys: [...parts.keys].filter(([k]) => k !== "Type"), body: parts.body },
|
|
442
464
|
tabs: attachmentTabs(await Task.attachments(log, id), parts.keys.get("Modified") ?? ""),
|
|
443
465
|
pred: ref(board.pred.get(id) ?? []),
|
|
444
466
|
succ: ref(board.succ.get(id) ?? [])
|
|
445
467
|
});
|
|
446
468
|
})
|
|
447
469
|
});
|
|
470
|
+
/* the diff of two states of a task plan, rendered statelessly out of the states
|
|
471
|
+
kept by the client, as the changes are followed per task dialog */
|
|
472
|
+
server.route({
|
|
473
|
+
method: "POST",
|
|
474
|
+
path: "/task-board/api/diff",
|
|
475
|
+
options: { payload: { parse: true, allow: "application/json" } },
|
|
476
|
+
handler: guarded(async (request, h) => {
|
|
477
|
+
const p = request.payload;
|
|
478
|
+
if (!isPlanText(p?.before) || !isPlanText(p.after))
|
|
479
|
+
return h.response({ error: "invalid diff request" }).code(400);
|
|
480
|
+
return h.response({ doc: await diffDocument(p.before, p.after) });
|
|
481
|
+
})
|
|
482
|
+
});
|
|
448
483
|
/* one task plan as text for editing, with the entity tag it is based on and the editor key bindings */
|
|
449
484
|
server.route({
|
|
450
485
|
method: "GET",
|
package/dst/ase-task-board.js
CHANGED
|
@@ -108,27 +108,35 @@ export default class TaskBoardCommand {
|
|
|
108
108
|
.option("--agent-relay <url>", "agent relay to receive the live presence of the agents from, " +
|
|
109
109
|
"as \"ase[s]://<addr>:<port>[/<token>]\" (default: the configured \"project.relay.url\", else none; " +
|
|
110
110
|
"the web board always follows the configured one)")
|
|
111
|
+
.option("-T, --task <id>", "show only the task dialog of the given task as a task viewer, " +
|
|
112
|
+
"following all its changes live (with --text or without a terminal: print its plan and exit)")
|
|
111
113
|
.action(async (opts) => {
|
|
114
|
+
/* refuse the task viewer on an unknown task */
|
|
115
|
+
const plan = opts.task !== undefined ? await Task.load(this.log, opts.task) : "";
|
|
116
|
+
if (opts.task !== undefined && plan === "")
|
|
117
|
+
throw new Error(`board: no task "${opts.task}"`);
|
|
112
118
|
/* serve and open the web board */
|
|
113
119
|
if (opts.web === true) {
|
|
114
120
|
if (opts.agentRelay !== undefined)
|
|
115
121
|
this.log.write("warning", "board: \"--agent-relay\" is ignored by the web board, " +
|
|
116
122
|
"which follows the configured \"project.relay.url\"");
|
|
117
|
-
const url = `http://${SERVICE_HOST}:${await this.servicePort()}/task-board
|
|
123
|
+
const url = `http://${SERVICE_HOST}:${await this.servicePort()}/task-board` +
|
|
124
|
+
(opts.task !== undefined ? `?task=${encodeURIComponent(opts.task)}` : "");
|
|
118
125
|
await writeStdout(`${url}\n`);
|
|
119
126
|
await this.openBrowser(url);
|
|
120
127
|
return;
|
|
121
128
|
}
|
|
122
|
-
/* print the plain text overview
|
|
129
|
+
/* print the plain text overview (resp. the plan of the task
|
|
130
|
+
of the task viewer) if requested or without a terminal */
|
|
123
131
|
if (opts.text === true || !process.stdout.isTTY || !process.stdin.isTTY) {
|
|
124
|
-
await writeStdout(await textOverview(this.log, opts.agentRelay));
|
|
132
|
+
await writeStdout(opts.task !== undefined ? plan : await textOverview(this.log, opts.agentRelay));
|
|
125
133
|
return;
|
|
126
134
|
}
|
|
127
135
|
/* run the interactive terminal board, with the production build of React
|
|
128
136
|
(its development build records a never cleared performance measure per render) */
|
|
129
137
|
process.env.NODE_ENV ??= "production";
|
|
130
138
|
const { runTUI } = await import("./ase-task-board-tui.js");
|
|
131
|
-
await runTUI(this.log, opts.agentRelay);
|
|
139
|
+
await runTUI(this.log, opts.agentRelay, opts.task);
|
|
132
140
|
});
|
|
133
141
|
}
|
|
134
142
|
}
|
|
@@ -5,10 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import fs from "node:fs";
|
|
8
|
-
import { ofetch } from "ofetch";
|
|
9
|
-
import { Agent } from "undici";
|
|
10
8
|
import { WebSocket } from "ws";
|
|
11
9
|
import { LRUCache } from "lru-cache";
|
|
10
|
+
import { dispatchFetch, insecureAgent } from "./ase-lib-fetch.js";
|
|
12
11
|
import { Config } from "./ase-config-core.js";
|
|
13
12
|
import { configSchema } from "./ase-config-schema.js";
|
|
14
13
|
import { parseScope, userStateDir } from "./ase-config-scope.js";
|
|
@@ -217,7 +216,7 @@ export class RemoteTaskStoreClient {
|
|
|
217
216
|
this.insecure = insecure;
|
|
218
217
|
this.lifecycle = configured;
|
|
219
218
|
this.idscheme = configuredIdScheme;
|
|
220
|
-
this.dispatcher = insecure ?
|
|
219
|
+
this.dispatcher = insecure ? insecureAgent() : undefined;
|
|
221
220
|
}
|
|
222
221
|
/* raise a failed connection as an unreachable store error,
|
|
223
222
|
reporting the innermost cause (like "connect ECONNREFUSED") */
|
|
@@ -232,7 +231,7 @@ export class RemoteTaskStoreClient {
|
|
|
232
231
|
a null result, any other error response is raised as a problem carrying
|
|
233
232
|
its status, and a failed connection is raised as an unreachable store error */
|
|
234
233
|
async request(method, url, body, headers = {}, tolerated = []) {
|
|
235
|
-
const r = await
|
|
234
|
+
const r = await dispatchFetch.raw(`${this.base}${url}`, {
|
|
236
235
|
method,
|
|
237
236
|
headers: {
|
|
238
237
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -408,7 +407,7 @@ export class RemoteTaskStoreClient {
|
|
|
408
407
|
return await this.task(await this.request("POST", `${this.tasks}/${encodeURIComponent(id)}/attachment${append ? "?append=true" : ""}`, attachment)) !== null;
|
|
409
408
|
}
|
|
410
409
|
async content(id, index) {
|
|
411
|
-
const r = await
|
|
410
|
+
const r = await dispatchFetch.raw(`${this.base}${this.tasks}/${encodeURIComponent(id)}/attachment/${index}/content`, {
|
|
412
411
|
headers: { Authorization: `Bearer ${this.token}` },
|
|
413
412
|
responseType: "arrayBuffer",
|
|
414
413
|
dispatcher: this.dispatcher,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
4
|
** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
|
|
5
5
|
*/
|
|
6
|
-
import { giteaApi } from "gitea-js";
|
|
6
|
+
import { giteaApi, ContentType } from "gitea-js";
|
|
7
7
|
import { LRUCache } from "lru-cache";
|
|
8
8
|
import * as TaskFormat from "./ase-task-format.js";
|
|
9
9
|
import * as TaskIssues from "./ase-task-store-issues.js";
|
|
@@ -396,7 +396,7 @@ class GiteaTaskStoragePlugin extends TaskIssues.IssueTaskStoragePlugin {
|
|
|
396
396
|
for (const blocker of after) {
|
|
397
397
|
if (have.has(blocker.number))
|
|
398
398
|
continue;
|
|
399
|
-
await this.call(loc, this.gt.repos.issueCreateIssueDependencies(loc.owner, loc.repo, String(issue.number), meta(blocker)))
|
|
399
|
+
await this.call(loc, this.gt.repos.issueCreateIssueDependencies(loc.owner, loc.repo, String(issue.number), meta(blocker), { type: ContentType.Json }))
|
|
400
400
|
.catch((err) => {
|
|
401
401
|
if (statusOf(err) === 404)
|
|
402
402
|
throw new Error(`Gitea rejected the dependency of issue #${issue.number} on issue #${blocker.number} ` +
|
|
@@ -406,7 +406,7 @@ class GiteaTaskStoragePlugin extends TaskIssues.IssueTaskStoragePlugin {
|
|
|
406
406
|
}
|
|
407
407
|
for (const blocker of current)
|
|
408
408
|
if (!want.has(blocker.number))
|
|
409
|
-
await found(this.call(loc, this.gt.repos.issueRemoveIssueDependencies(loc.owner, loc.repo, String(issue.number), meta(blocker))));
|
|
409
|
+
await found(this.call(loc, this.gt.repos.issueRemoveIssueDependencies(loc.owner, loc.repo, String(issue.number), meta(blocker), { type: ContentType.Json })));
|
|
410
410
|
}
|
|
411
411
|
/* synchronize the comments with the attachments, touching changed ones only
|
|
412
412
|
(see the common issue tracker parts) */
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
\[`--lifecycle` *model*\]
|
|
20
20
|
\[`--serial`\]
|
|
21
21
|
\[`--unclaimed`\]
|
|
22
|
+
\[`-M`|`--model` *model*\]
|
|
22
23
|
\[`--params` *name*`=`*value*\]
|
|
23
24
|
\[`--state-`*item* *state*\]
|
|
24
25
|
\[`--tag-`*item* *tag*\]
|
|
@@ -169,12 +170,12 @@ tags (except the request state tag) and, by default, gets its previous
|
|
|
169
170
|
assignee back. An agent consumes the request prompts if its prompt
|
|
170
171
|
template references `{prompt}` (except within the conditional
|
|
171
172
|
`{?prompt:`*text*`}` only, which makes the prompt *optional*) or it
|
|
172
|
-
has a hook `prepare`, `prompt`, or `finish` (which receive
|
|
173
|
-
prompt in their *job*), where it then refuses a request
|
|
174
|
-
prompt as failed, else it accepts requests with an empty
|
|
175
|
-
an agent with an optional prompt still passes on if
|
|
176
|
-
announces this to the agent relay, so the task boards
|
|
177
|
-
prompt for its requests, too.
|
|
173
|
+
has a hook `prepare`, `prompt`, `model`, or `finish` (which receive
|
|
174
|
+
the request prompt in their *job*), where it then refuses a request
|
|
175
|
+
with an empty prompt as failed, else it accepts requests with an empty
|
|
176
|
+
prompt (which an agent with an optional prompt still passes on if
|
|
177
|
+
non-empty), and announces this to the agent relay, so the task boards
|
|
178
|
+
accept an empty prompt for its requests, too.
|
|
178
179
|
|
|
179
180
|
Only the prompt (and `--state-incoming` for `--type phase`) is
|
|
180
181
|
mandatory, while all other options default to the safe *annotate*
|
|
@@ -431,6 +432,16 @@ and `--prompt-skill` with `--prompt-args`, and `--tag-retry` and
|
|
|
431
432
|
`passes`, and `--workdir changeset` resp. `target` (as the task can
|
|
432
433
|
be claimed by another agent meanwhile).
|
|
433
434
|
|
|
435
|
+
- \[`-M`|`--model` *model*\]:
|
|
436
|
+
The model of the agent tool, passed to it as `--model` *model*
|
|
437
|
+
verbatim (e.g., an alias like `sonnet` or a full model name), either a
|
|
438
|
+
*model* for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
439
|
+
`Effort:` size of the task (`XS`, `S`, `M`, `L`, `XL`, or `*` for all
|
|
440
|
+
other tasks, e.g., `XS=haiku,S=haiku,M=sonnet,*=opus`), where a task
|
|
441
|
+
without a matching pair gets the default model of the agent tool (the
|
|
442
|
+
default for all tasks). The hook `model` can override it per task (see
|
|
443
|
+
**HOOKS**).
|
|
444
|
+
|
|
434
445
|
- \[`--params` *name*`=`*value*\]:
|
|
435
446
|
(repeatable) The value of the parameter *name* declared by the
|
|
436
447
|
definition (see **PARAMETERS**), where a later value of the same
|
|
@@ -986,6 +997,14 @@ invocation:
|
|
|
986
997
|
`{ text }`, a plain prompt text, or `undefined` to keep the
|
|
987
998
|
configured one, where a thrown error fails the processing.
|
|
988
999
|
|
|
1000
|
+
- `model(task, model, job, ctx)`:
|
|
1001
|
+
The model of the agent tool for the job, given the configured *model*
|
|
1002
|
+
of `--model` for the `Effort:` size of the task (empty for the default
|
|
1003
|
+
model of the agent tool): a model (empty for the default one), or
|
|
1004
|
+
`undefined` to keep the configured one, where a thrown error fails the
|
|
1005
|
+
processing. This allows choosing the model per task by any means,
|
|
1006
|
+
e.g., by asking a cheap model via `ctx.exec`.
|
|
1007
|
+
|
|
989
1008
|
- `verdict(task, result, ctx)`:
|
|
990
1009
|
(after a successful agent tool only) The verdict of the result (an
|
|
991
1010
|
upper-case word, accepted only if listed by `--verdict-allow`), an
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
\[`-T`|`--timeout` *duration*\]
|
|
10
10
|
\[`-o`|`--one-shot`\]
|
|
11
11
|
\[`--agent-relay` *url*\]
|
|
12
|
+
\[`-M`|`--model` *model*\]
|
|
12
13
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
13
14
|
\[`-f`|`--foreground`\]
|
|
14
15
|
|
|
@@ -145,6 +146,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
145
146
|
(`phase` only). Built-in: not set. Not allowed, as the condenser
|
|
146
147
|
claims the tasks into its activity state.
|
|
147
148
|
|
|
149
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
150
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
151
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
152
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
153
|
+
model of the agent tool. Built-in: none.
|
|
154
|
+
|
|
148
155
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
149
156
|
declared by the definition (repeatable). Built-in: none declared.
|
|
150
157
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
\[`--agent-relay` *url*\]
|
|
12
12
|
\[`-r`|`--repo` *url*\]
|
|
13
13
|
\[`-d`|`--tempdir` *dir*\]
|
|
14
|
+
\[`-M`|`--model` *model*\]
|
|
14
15
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
15
16
|
\[`-f`|`--foreground`\]
|
|
16
17
|
|
|
@@ -192,6 +193,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
192
193
|
(`phase` only). Built-in: not set. Not allowed, as the editor is
|
|
193
194
|
of type `request`.
|
|
194
195
|
|
|
196
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
197
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
198
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
199
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
200
|
+
model of the agent tool. Built-in: none.
|
|
201
|
+
|
|
195
202
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
196
203
|
declared by the definition (repeatable). Built-in: none declared.
|
|
197
204
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
\[`-o`|`--one-shot`\]
|
|
11
11
|
\[`--agent-relay` *url*\]
|
|
12
12
|
\[`-m`|`--mode` `phase`|`request`\]
|
|
13
|
+
\[`-M`|`--model` *model*\]
|
|
13
14
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
14
15
|
\[`-f`|`--foreground`\]
|
|
15
16
|
|
|
@@ -204,6 +205,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
204
205
|
(`phase` only). Built-in: enabled (mode `phase`) resp. not set
|
|
205
206
|
(mode `request`).
|
|
206
207
|
|
|
208
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
209
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
210
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
211
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
212
|
+
model of the agent tool. Built-in: none.
|
|
213
|
+
|
|
207
214
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
208
215
|
declared by the definition (repeatable). Built-in: none declared.
|
|
209
216
|
|
|
@@ -79,7 +79,7 @@ members) or `ase agent fleet stop`.
|
|
|
79
79
|
(with all its options commented out, so they fall back to
|
|
80
80
|
`project.relay.url`, `project.relay.crt`, and `project.relay.key`),
|
|
81
81
|
the section `default` (with `tool`, `parallel: 1`, and `timeout: 60m`,
|
|
82
|
-
plus `repo
|
|
82
|
+
plus `model`, `repo`, and `tempdir` commented out), the edit request agent
|
|
83
83
|
`editor`, the effort estimation agent `estimator` (mode `phase`,
|
|
84
84
|
estimating the planned tasks, i.e., the `OPEN` tasks for `solo`, the
|
|
85
85
|
`PLANNING` tasks for `team`, and the `PLANNED` tasks for `enterprise`,
|
|
@@ -201,8 +201,9 @@ value omits an option, and a list repeats an option:
|
|
|
201
201
|
`project.relay.url` selecting HTTPS requires both.
|
|
202
202
|
|
|
203
203
|
- `default`:
|
|
204
|
-
(optional) The default options of all agents: `tool`, `
|
|
205
|
-
`timeout`, `repo`, `tempdir`, and `agent-relay` (see
|
|
204
|
+
(optional) The default options of all agents: `tool`, `model`,
|
|
205
|
+
`parallel`, `timeout`, `repo`, `tempdir`, and `agent-relay` (see
|
|
206
|
+
`ase-agent`(1) and `ase-agent-adhoc`(1)),
|
|
206
207
|
each one applied only to the agents supporting it (e.g., `repo` not to
|
|
207
208
|
`rebooter`), and overridden by the section of an agent. The option
|
|
208
209
|
`agent-relay` is not allowed together with the section `relay`.
|
|
@@ -315,7 +316,8 @@ $ ase agent fleet stop
|
|
|
315
316
|
```
|
|
316
317
|
|
|
317
318
|
A configuration `.ase/fleet.yaml` with the agent relay, the built-in
|
|
318
|
-
agents
|
|
319
|
+
agents (with an implementer using cheaper models for smaller tasks),
|
|
320
|
+
two editors of different agent tools, an agent of the
|
|
319
321
|
definition file `.ase/agents/reviewer.mts`, and an ad-hoc request
|
|
320
322
|
agent:
|
|
321
323
|
|
|
@@ -329,6 +331,7 @@ default:
|
|
|
329
331
|
rebooter:
|
|
330
332
|
implementer:
|
|
331
333
|
parallel: 2
|
|
334
|
+
model: XS=haiku,S=haiku,*=sonnet
|
|
332
335
|
editor-claude:
|
|
333
336
|
kind: editor
|
|
334
337
|
editor-codex:
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
\[`-r`|`--repo` *url*\]
|
|
13
13
|
\[`-d`|`--tempdir` *dir*\]
|
|
14
14
|
\[`-m`|`--mode` `implement`|`draft`\]
|
|
15
|
+
\[`-M`|`--model` *model*\]
|
|
15
16
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
16
17
|
\[`-f`|`--foreground`\]
|
|
17
18
|
|
|
@@ -260,6 +261,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
260
261
|
(`phase` only). Built-in: not set. Not allowed, as the implementer
|
|
261
262
|
claims the tasks into its activity state.
|
|
262
263
|
|
|
264
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
265
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
266
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
267
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
268
|
+
model of the agent tool. Built-in: none.
|
|
269
|
+
|
|
263
270
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
264
271
|
declared by the definition (repeatable). Built-in: `effort-wait`
|
|
265
272
|
(`true` or `false`, default: `true`), whether to wait for the
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
\[`-r`|`--repo` *url*\]
|
|
13
13
|
\[`-d`|`--tempdir` *dir*\]
|
|
14
14
|
\[`-m`|`--mode` `merge`|`rebase`|`squash`\]
|
|
15
|
+
\[`-M`|`--model` *model*\]
|
|
15
16
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
16
17
|
\[`-f`|`--foreground`\]
|
|
17
18
|
|
|
@@ -206,6 +207,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
206
207
|
(`phase` only). Built-in: not set. Not allowed, as the integrator
|
|
207
208
|
claims the tasks into its activity state.
|
|
208
209
|
|
|
210
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
211
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
212
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
213
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
214
|
+
model of the agent tool. Built-in: none.
|
|
215
|
+
|
|
209
216
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
210
217
|
declared by the definition (repeatable). Built-in: none declared.
|
|
211
218
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
\[`-r`|`--repo` *url*\]
|
|
13
13
|
\[`-d`|`--tempdir` *dir*\]
|
|
14
14
|
\[`-m`|`--mode` `judge`|`qualify`\]
|
|
15
|
+
\[`-M`|`--model` *model*\]
|
|
15
16
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
16
17
|
\[`-f`|`--foreground`\]
|
|
17
18
|
|
|
@@ -187,6 +188,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
187
188
|
(`phase` only). Built-in: not set. Not allowed, as the qualifier
|
|
188
189
|
claims the tasks into its activity state.
|
|
189
190
|
|
|
191
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
192
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
193
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
194
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
195
|
+
model of the agent tool. Built-in: none.
|
|
196
|
+
|
|
190
197
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
191
198
|
declared by the definition (repeatable). Built-in: none declared.
|
|
192
199
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
\[`-T`|`--timeout` *duration*\]
|
|
10
10
|
\[`-o`|`--one-shot`\]
|
|
11
11
|
\[`--agent-relay` *url*\]
|
|
12
|
+
\[`-M`|`--model` *model*\]
|
|
12
13
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
13
14
|
\[`-f`|`--foreground`\]
|
|
14
15
|
|
|
@@ -145,6 +146,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
145
146
|
(`phase` only). Built-in: not set. Not allowed, as the rebooter
|
|
146
147
|
claims the tasks into its activity state.
|
|
147
148
|
|
|
149
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
150
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
151
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
152
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
153
|
+
model of the agent tool. Built-in: none.
|
|
154
|
+
|
|
148
155
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
149
156
|
declared by the definition (repeatable). Built-in: none declared.
|
|
150
157
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
\[`-r`|`--repo` *url*\]
|
|
13
13
|
\[`-d`|`--tempdir` *dir*\]
|
|
14
14
|
\[`-m`|`--mode` `phase`|`request`\]
|
|
15
|
+
\[`-M`|`--model` *model*\]
|
|
15
16
|
\[`--`*group*`-`*item* *value* \[...\]\]
|
|
16
17
|
\[`-f`|`--foreground`\]
|
|
17
18
|
|
|
@@ -246,6 +247,12 @@ All other options belong to the sub-commands (see **COMMANDS**).
|
|
|
246
247
|
- \[`--unclaimed`\]: Process the tasks of the incoming states
|
|
247
248
|
without claiming them (`phase` only). Built-in: not set.
|
|
248
249
|
|
|
250
|
+
- \[`-M`|`--model` *model*\]: The model of the agent tool: a model
|
|
251
|
+
for all tasks, or comma-separated *size*`=`*model* pairs per
|
|
252
|
+
`Effort:` size (`XS`, `S`, `M`, `L`, `XL`, or `*` for all other
|
|
253
|
+
tasks), see `ase-agent-adhoc`(1). Generic default: the default
|
|
254
|
+
model of the agent tool. Built-in: none.
|
|
255
|
+
|
|
249
256
|
- \[`--params` *name*`=`*value*\]: The value of a parameter
|
|
250
257
|
declared by the definition (repeatable). Built-in: none declared.
|
|
251
258
|
|
|
@@ -63,7 +63,8 @@ file lock and atomically.
|
|
|
63
63
|
`project.task.effort.line` `0.025`,
|
|
64
64
|
`project.task.effort.iteration` `2.5`, the full set of
|
|
65
65
|
`project.artifact.*` globs, the `board.tui.color.*`,
|
|
66
|
-
`board.web.color.*`,
|
|
66
|
+
`board.web.color.*`, `board.web.editor.keymap`, and
|
|
67
|
+
`board.web.theme` defaults, and
|
|
67
68
|
`telemetry.enabled` `false`, `telemetry.prices.ai`
|
|
68
69
|
`*=4.00/20.00/0.20/5.00`, and `telemetry.prices.hr` `*=110`.
|
|
69
70
|
- `vibe`:
|
package/dst/man/ase-config.md
CHANGED
|
@@ -361,6 +361,11 @@ Task board (all writable on the `user` and `project` scopes only, see
|
|
|
361
361
|
The key bindings of the task plan editor of the web board (default:
|
|
362
362
|
`default`).
|
|
363
363
|
|
|
364
|
+
- `board.web.theme` (`auto`, `light`, or `dark`):
|
|
365
|
+
The color theme of the web board, where `auto` follows the light or
|
|
366
|
+
dark preference of the operating system resp. browser (default:
|
|
367
|
+
`auto`).
|
|
368
|
+
|
|
364
369
|
## ENVIRONMENT
|
|
365
370
|
|
|
366
371
|
- `EDITOR`, `VISUAL`:
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
\[`-w`|`--web`\]
|
|
8
8
|
\[`-t`|`--text`\]
|
|
9
9
|
\[`--agent-relay` *url*\]
|
|
10
|
+
\[`-T`|`--task` *id*\]
|
|
10
11
|
|
|
11
12
|
## DESCRIPTION
|
|
12
13
|
|
|
@@ -89,6 +90,11 @@ set snapshot `kind="changeset"` of the `implementer` and `integrator`
|
|
|
89
90
|
agents) is colored per line, YAML and JSON data are syntax-highlighted,
|
|
90
91
|
and a change set snapshot older than the plan is marked `(stale)`.
|
|
91
92
|
|
|
93
|
+
While the task dialog is open, the last change of the shown plan is displayed
|
|
94
|
+
as a diff in the plan tab, with the removed and added lines colored (in the
|
|
95
|
+
terminal board also signed) and their changed words shown inverse, until `#` clears it or a next change
|
|
96
|
+
replaces it. Closing the task dialog or switching to another task drops it.
|
|
97
|
+
|
|
92
98
|
A task is moved into another state (changing its `Status:`) either by
|
|
93
99
|
picking it up with `SPACE` and dropping it with a second `SPACE` onto
|
|
94
100
|
the selected lane (only lanes whose state is reachable from the current
|
|
@@ -214,6 +220,26 @@ waiting) with their status and their last processing log line, and
|
|
|
214
220
|
finally all warnings of the board (behind `⚠`, e.g. on dependency
|
|
215
221
|
cycles).
|
|
216
222
|
|
|
223
|
+
### Task Viewer
|
|
224
|
+
|
|
225
|
+
With `--task`, the terminal and the web board act as a *task viewer*:
|
|
226
|
+
instead of the board, they show only the task dialog of the given task,
|
|
227
|
+
spanning the entire window and following all changes of the task live.
|
|
228
|
+
All actions of the task dialog stay available, and a click onto a
|
|
229
|
+
predecessor or successor shows that task instead. The shown view of the
|
|
230
|
+
board stays untouched. An unknown task is refused with an error.
|
|
231
|
+
|
|
232
|
+
The terminal board quits on `q` or `Ctrl`+`C` only, and with a warning
|
|
233
|
+
once the shown task no longer exists (e.g. as it was deleted or renamed
|
|
234
|
+
elsewhere).
|
|
235
|
+
|
|
236
|
+
The web board has no closing keys, as a page cannot close its browser
|
|
237
|
+
tab. Once the shown task no longer exists, it shows only a notice, and
|
|
238
|
+
shows the task again as soon as it exists again.
|
|
239
|
+
|
|
240
|
+
With `--text`, and also without an interactive terminal, the plan of the
|
|
241
|
+
task is printed as plain text and the command exits.
|
|
242
|
+
|
|
217
243
|
### Statistics View
|
|
218
244
|
|
|
219
245
|
The third view *statistics* shows the statistics of the tasks matching the
|
|
@@ -410,6 +436,10 @@ relay, the agent graph view is skipped.
|
|
|
410
436
|
board always follows the configured `project.relay.url` (and hence
|
|
411
437
|
warns about the option).
|
|
412
438
|
|
|
439
|
+
- \[`-T`|`--task` *id*\]:
|
|
440
|
+
Show only the task dialog of the task *id* instead of the board, as a
|
|
441
|
+
viewer and watcher of the task (see **Task Viewer**).
|
|
442
|
+
|
|
413
443
|
## KEYS
|
|
414
444
|
|
|
415
445
|
The following keys are supported by the terminal board (and, unless
|
|
@@ -426,6 +456,9 @@ letter under the kitty keyboard protocol.
|
|
|
426
456
|
views).
|
|
427
457
|
- `?`: Hide or show the key hint lines (persisted); while hidden, the
|
|
428
458
|
information line ends with `?: show key hints`.
|
|
459
|
+
- `L`: Cycle the color theme through `auto`, `light`, and `dark`,
|
|
460
|
+
overriding `board.web.theme` in the current browser until cycled back
|
|
461
|
+
to its value (web board only).
|
|
429
462
|
- `D`: Delete the selected task, after a confirmation (not in the
|
|
430
463
|
agent logs and statistics views).
|
|
431
464
|
- `T`: Transfer the selected task to another state via the transfer
|
|
@@ -515,7 +548,8 @@ letter under the kitty keyboard protocol.
|
|
|
515
548
|
- `↑`/`↓`: Scroll the content.
|
|
516
549
|
- `PgUp`/`PgDn`: Scroll the content by one page.
|
|
517
550
|
- `e`: Edit the task plan.
|
|
518
|
-
-
|
|
551
|
+
- `#`: Clear the diff of the last change of the task plan.
|
|
552
|
+
- `D`, `T`, `A`, `E`, `R`, `M`, `L`: As in every view.
|
|
519
553
|
- `⏎`, `ESC`: Close the task dialog.
|
|
520
554
|
|
|
521
555
|
### Filter Field
|
|
@@ -594,6 +628,11 @@ The following configuration keys (on scope `user` or `project`, see
|
|
|
594
628
|
The key bindings of the task plan editor of the web board: `default`,
|
|
595
629
|
`vim`, or `emacs` (default: `default`).
|
|
596
630
|
|
|
631
|
+
- `board.web.theme`:
|
|
632
|
+
The color theme of the web board: `light`, `dark`, or `auto`, which
|
|
633
|
+
follows the light or dark preference of the operating system resp.
|
|
634
|
+
browser (default: `auto`).
|
|
635
|
+
|
|
597
636
|
- `project.relay.url`:
|
|
598
637
|
The default agent relay of the boards (see `--agent-relay`).
|
|
599
638
|
|
|
@@ -625,7 +664,7 @@ The following configuration keys (on scope `user` or `project`, see
|
|
|
625
664
|
The command exits with status `0` once the terminal board is quit, the
|
|
626
665
|
text overview is printed, resp. the web board is opened, and with
|
|
627
666
|
status `1` on any error (e.g. an *ASE* service without web board on
|
|
628
|
-
`--web`).
|
|
667
|
+
`--web`, or an unknown task on `--task`).
|
|
629
668
|
|
|
630
669
|
## EXAMPLES
|
|
631
670
|
|
|
@@ -636,6 +675,9 @@ $ ase task board
|
|
|
636
675
|
# show the web board in the browser
|
|
637
676
|
$ ase task board --web
|
|
638
677
|
|
|
678
|
+
# view and watch a single task in the terminal
|
|
679
|
+
$ ase task board --task T1
|
|
680
|
+
|
|
639
681
|
# print the lane overview, including the agents of a remote agent relay
|
|
640
682
|
$ ase task board --text --agent-relay ase://relay.example.com:42043
|
|
641
683
|
```
|