@rse/ase 2.0.1 → 2.0.2
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-config.js +2 -1
- package/dst/ase-hook.js +2 -7
- package/dst/ase-lib-server-cli.js +6 -5
- package/dst/ase-task-board-core.js +1 -1
- package/dst/ase-task-board-tui-control.js +10 -10
- package/dst/ase-task-board-tui-model.js +10 -14
- package/dst/ase-task-board-tui-view.js +14 -9
- package/dst/ase-task-board-web-client.css +1 -1
- package/dst/ase-task-board-web-client.js +2 -2
- package/dst/ase-task-board-web-server.js +2 -25
- package/dst/ase-task-store-issues.js +76 -0
- package/dst/ase-task-store-plugin-gitea.js +2 -65
- package/dst/ase-task-store-plugin-github.js +2 -65
- package/dst/ase-task-store-plugin-gitlab.js +2 -65
- package/dst/ase-util-diagram.js +3 -5
- package/dst/man/ase-agent-adhoc.1 +1 -1
- package/dst/man/ase-agent-condenser.1 +1 -1
- package/dst/man/ase-agent-editor.1 +1 -1
- package/dst/man/ase-agent-estimator.1 +1 -1
- package/dst/man/ase-agent-fleet.1 +1 -1
- package/dst/man/ase-agent-implementer.1 +1 -1
- package/dst/man/ase-agent-integrator.1 +1 -1
- package/dst/man/ase-agent-qualifier.1 +1 -1
- package/dst/man/ase-agent-rebooter.1 +1 -1
- package/dst/man/ase-agent-relay.1 +1 -1
- package/dst/man/ase-agent-researcher.1 +1 -1
- package/dst/man/ase-agent.1 +1 -1
- package/dst/man/ase-artifact-list.1 +1 -1
- package/dst/man/ase-artifact-name.1 +1 -1
- package/dst/man/ase-artifact.1 +1 -1
- package/dst/man/ase-config-delete.1 +1 -1
- package/dst/man/ase-config-edit.1 +1 -1
- package/dst/man/ase-config-get.1 +1 -1
- package/dst/man/ase-config-init.1 +1 -1
- package/dst/man/ase-config-list.1 +1 -1
- package/dst/man/ase-config-set.1 +1 -1
- package/dst/man/ase-config.1 +1 -1
- package/dst/man/ase-hook-permission-request.1 +1 -1
- package/dst/man/ase-hook-pre-tool-use.1 +1 -1
- package/dst/man/ase-hook-session-end.1 +1 -1
- package/dst/man/ase-hook-session-persona.1 +1 -1
- package/dst/man/ase-hook-session-start.1 +1 -1
- package/dst/man/ase-hook-stop.1 +1 -1
- package/dst/man/ase-hook-user-prompt-submit.1 +1 -1
- package/dst/man/ase-hook.1 +1 -1
- package/dst/man/ase-man.1 +1 -1
- package/dst/man/ase-mcp.1 +1 -1
- package/dst/man/ase-service-log.1 +1 -1
- package/dst/man/ase-service-send.1 +1 -1
- package/dst/man/ase-service-start.1 +1 -1
- package/dst/man/ase-service-status.1 +1 -1
- package/dst/man/ase-service-stop.1 +1 -1
- package/dst/man/ase-service.1 +1 -1
- package/dst/man/ase-setup-disable.1 +1 -1
- package/dst/man/ase-setup-enable.1 +1 -1
- package/dst/man/ase-setup-install.1 +1 -1
- package/dst/man/ase-setup-mcp.1 +1 -1
- package/dst/man/ase-setup-status.1 +1 -1
- package/dst/man/ase-setup-statusline.1 +1 -1
- package/dst/man/ase-setup-telemetry.1 +1 -1
- package/dst/man/ase-setup-uninstall.1 +1 -1
- package/dst/man/ase-setup-update.1 +1 -1
- package/dst/man/ase-setup.1 +1 -1
- package/dst/man/ase-spec-export.1 +1 -1
- package/dst/man/ase-spec-lint.1 +1 -1
- package/dst/man/ase-spec-preview.1 +1 -1
- package/dst/man/ase-spec.1 +1 -1
- package/dst/man/ase-statusline.1 +1 -1
- package/dst/man/ase-task-assign.1 +1 -1
- package/dst/man/ase-task-board.1 +3 -3
- package/dst/man/ase-task-delete.1 +1 -1
- package/dst/man/ase-task-edit.1 +1 -1
- package/dst/man/ase-task-idscheme.1 +1 -1
- package/dst/man/ase-task-lifecycle.1 +1 -1
- package/dst/man/ase-task-list.1 +1 -1
- package/dst/man/ase-task-load.1 +1 -1
- package/dst/man/ase-task-newid.1 +1 -1
- package/dst/man/ase-task-purge.1 +1 -1
- package/dst/man/ase-task-rename.1 +1 -1
- package/dst/man/ase-task-request.1 +1 -1
- package/dst/man/ase-task-save.1 +1 -1
- package/dst/man/ase-task-status.1 +1 -1
- package/dst/man/ase-task-store.1 +1 -1
- package/dst/man/ase-task-view.1 +1 -1
- package/dst/man/ase-task.1 +1 -1
- package/dst/man/ase-util-compat.1 +1 -1
- package/dst/man/ase-util-diagram.1 +1 -1
- package/dst/man/ase-util-meta.1 +1 -1
- package/dst/man/ase-util-metric.1 +1 -1
- package/dst/man/ase-util-mint.1 +1 -1
- package/dst/man/ase-util-worktree.1 +1 -1
- package/dst/man/ase-util.1 +1 -1
- package/dst/man/ase.1 +1 -1
- package/package.json +1 -1
- 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-resolve.md +2 -2
- package/plugin/mods/ase-mods.ts +6 -5
- package/plugin/skills/ase-arch-analyze/SKILL.md +3 -1
- package/plugin/skills/ase-code-analyze/SKILL.md +8 -0
- package/plugin/skills/ase-code-edit/SKILL.md +5 -4
- package/plugin/skills/ase-code-edit/help.md +1 -1
- package/plugin/skills/ase-code-lint/SKILL.md +15 -4
- package/plugin/skills/ase-help-intent/data.md +36 -18
- package/plugin/skills/ase-help-skill/help.md +3 -4
- package/plugin/skills/ase-meta-quorum/SKILL.md +9 -0
- package/plugin/skills/ase-meta-quorum/help.md +5 -3
- package/plugin/skills/ase-meta-workflow/sample.md +5 -3
- package/plugin/skills/ase-repo-changelog/SKILL.md +8 -9
- package/plugin/skills/ase-repo-changelog/help.md +2 -2
- package/plugin/skills/ase-spec-edit/SKILL.md +2 -1
- package/plugin/skills/ase-spec-edit/help.md +2 -1
- package/plugin/skills/ase-sync-reconcile/help.md +4 -4
- package/plugin/skills/ase-task-dissect/SKILL.md +10 -6
- package/plugin/skills/ase-task-grill/help.md +1 -1
- package/plugin/skills/ase-task-implement/SKILL.md +58 -1
- package/plugin/skills/ase-task-implement/help.md +16 -0
- package/plugin/skills/ase-task-list/help.md +2 -2
package/dst/ase-config.js
CHANGED
|
@@ -191,7 +191,8 @@ export class ConfigMCP {
|
|
|
191
191
|
const cfg = new Config("config", configSchema, this.log, scope);
|
|
192
192
|
cfg.read();
|
|
193
193
|
const val = cfg.get(args.key);
|
|
194
|
-
const text = val === undefined ? "" :
|
|
194
|
+
const text = val === undefined ? "" :
|
|
195
|
+
JSON.stringify(configSecretKeys.includes(cfg.resolveKey(args.key)) ? "***" : val);
|
|
195
196
|
return { content: [{ type: "text", text }] };
|
|
196
197
|
}
|
|
197
198
|
catch (err) {
|
package/dst/ase-hook.js
CHANGED
|
@@ -16,6 +16,7 @@ import { parseScope, userStateDir } from "./ase-config-scope.js";
|
|
|
16
16
|
import { readStdin, writeStdout } from "./ase-lib-stdio.js";
|
|
17
17
|
import { Task } from "./ase-task.js";
|
|
18
18
|
import * as TaskFormat from "./ase-task-format.js";
|
|
19
|
+
import { parseTool } from "./ase-setup-common.js";
|
|
19
20
|
const addonMcpServers = [
|
|
20
21
|
"chat-alibaba-qwen",
|
|
21
22
|
"chat-deepseek",
|
|
@@ -706,12 +707,6 @@ export default class HookCommand {
|
|
|
706
707
|
}
|
|
707
708
|
return 0;
|
|
708
709
|
}
|
|
709
|
-
/* parse and validate the --tool option */
|
|
710
|
-
parseTool(value) {
|
|
711
|
-
if (value !== "claude" && value !== "copilot" && value !== "codex")
|
|
712
|
-
throw new Error(`invalid --tool value: "${value}" (expected "claude", "copilot", or "codex")`);
|
|
713
|
-
return value;
|
|
714
|
-
}
|
|
715
710
|
/* register commands */
|
|
716
711
|
register(program) {
|
|
717
712
|
/* default for --tool derived from ASE_TOOL environment variable
|
|
@@ -743,7 +738,7 @@ export default class HookCommand {
|
|
|
743
738
|
.description(desc)
|
|
744
739
|
.option("-t, --tool <tool>", "target tool (\"claude\", \"copilot\", or \"codex\")", toolDflt)
|
|
745
740
|
.action(async (opts) => {
|
|
746
|
-
process.exitCode = await handler(
|
|
741
|
+
process.exitCode = await handler(parseTool(opts.tool));
|
|
747
742
|
});
|
|
748
743
|
}
|
|
749
744
|
}
|
|
@@ -13,6 +13,7 @@ import { isSeq, isScalar } from "yaml";
|
|
|
13
13
|
import { Config } from "./ase-config-core.js";
|
|
14
14
|
import { parseScope } from "./ase-config-scope.js";
|
|
15
15
|
import { isLogLevel } from "./ase-lib-log.js";
|
|
16
|
+
import { writeStdout } from "./ase-lib-stdio.js";
|
|
16
17
|
import { Service } from "./ase-service.js";
|
|
17
18
|
import { DaemonCommand } from "./ase-lib-daemon-cli.js";
|
|
18
19
|
import { urlHost, isLoopback, serverHeader } from "./ase-lib-server-bind.js";
|
|
@@ -381,26 +382,26 @@ export class ServerCommand extends DaemonCommand {
|
|
|
381
382
|
async doStatus() {
|
|
382
383
|
const ctx = this.loadContext();
|
|
383
384
|
if (ctx.port === null) {
|
|
384
|
-
|
|
385
|
+
await writeStdout(`${this.label}: not running (no port configured)\n`);
|
|
385
386
|
return 1;
|
|
386
387
|
}
|
|
387
388
|
const address = ctx.address ?? DEFAULT_ADDRESS;
|
|
388
389
|
const scheme = ctx.tlsCert !== null ? "https" : "http";
|
|
389
390
|
const state = await this.probe(address, ctx.port, ctx.token, ctx.tlsCert !== null);
|
|
390
391
|
if (state === "running") {
|
|
391
|
-
|
|
392
|
+
await writeStdout(`${this.label}: running on ${scheme}://${urlHost(address)}:${ctx.port}` +
|
|
392
393
|
(ctx.pid !== null ? ` (pid ${ctx.pid})` : "") + this.running(ctx) + "\n");
|
|
393
394
|
return 0;
|
|
394
395
|
}
|
|
395
396
|
if (state === "unauthorized") {
|
|
396
|
-
|
|
397
|
+
await writeStdout(`${this.label}: running on ${scheme}://${urlHost(address)}:${ctx.port}, but the configured token is rejected\n`);
|
|
397
398
|
return 1;
|
|
398
399
|
}
|
|
399
400
|
if (state === "foreign") {
|
|
400
|
-
|
|
401
|
+
await writeStdout(`${this.label}: not running (port ${ctx.port} in use by foreign service)\n`);
|
|
401
402
|
return 1;
|
|
402
403
|
}
|
|
403
|
-
|
|
404
|
+
await writeStdout(`${this.label}: not running (port ${ctx.port} not responding)\n`);
|
|
404
405
|
return 1;
|
|
405
406
|
}
|
|
406
407
|
/* stop flow: terminate the server process and wait until it is gone */
|
|
@@ -187,7 +187,7 @@ export class BoardState {
|
|
|
187
187
|
state[surface][flag] = !state[surface][flag];
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
|
-
/* set the shown view (lanes, graph, stats, or
|
|
190
|
+
/* set the shown view (lanes, graph, stats, agents, or flow) */
|
|
191
191
|
static setView(surface, view) {
|
|
192
192
|
return BoardState.update((state) => {
|
|
193
193
|
state[surface].view = view;
|
|
@@ -310,16 +310,6 @@ const handlePopupKey = (ctx, input, key) => {
|
|
|
310
310
|
setPrompt({ ...prompt, focus: prompt.focus === "request" ? "cancel" : "request" });
|
|
311
311
|
return;
|
|
312
312
|
}
|
|
313
|
-
/* type the prompt of an edit request: RETURN requests the edit, Shift+RETURN
|
|
314
|
-
(under the kitty keyboard protocol only), Alt+RETURN (under the kitty keyboard
|
|
315
|
-
protocol, or where the terminal sends it as ESC+RETURN, e.g. with "Option as Meta"
|
|
316
|
-
on macOS), and Ctrl+J (in every terminal, as a plain linefeed without the kitty
|
|
317
|
-
keyboard protocol) insert a newline,
|
|
318
|
-
the left/right arrows move the cursor by one character, HOME/END move it
|
|
319
|
-
to the start/end, BACKSPACE removes the character before the cursor, DELETE
|
|
320
|
-
removes the character at the cursor, and all other input (also pasted text,
|
|
321
|
-
with its newlines kept and its other control characters turned into spaces)
|
|
322
|
-
is inserted at the cursor */
|
|
323
313
|
if (prompt !== null && prompt.request !== null && prompt.focus === "name") {
|
|
324
314
|
/* type the request name of a request by prompt: RETURN switches to the prompt (resp. to
|
|
325
315
|
the request button if the prompt is ignored), the
|
|
@@ -342,6 +332,16 @@ const handlePopupKey = (ctx, input, key) => {
|
|
|
342
332
|
name(request.name + input.toLowerCase());
|
|
343
333
|
return;
|
|
344
334
|
}
|
|
335
|
+
/* type the prompt of an edit request: RETURN requests the edit, Shift+RETURN
|
|
336
|
+
(under the kitty keyboard protocol only), Alt+RETURN (under the kitty keyboard
|
|
337
|
+
protocol, or where the terminal sends it as ESC+RETURN, e.g. with "Option as Meta"
|
|
338
|
+
on macOS), and Ctrl+J (in every terminal, as a plain linefeed without the kitty
|
|
339
|
+
keyboard protocol) insert a newline,
|
|
340
|
+
the left/right arrows move the cursor by one character, HOME/END move it
|
|
341
|
+
to the start/end, BACKSPACE removes the character before the cursor, DELETE
|
|
342
|
+
removes the character at the cursor, and all other input (also pasted text,
|
|
343
|
+
with its newlines kept and its other control characters turned into spaces)
|
|
344
|
+
is inserted at the cursor */
|
|
345
345
|
if (prompt !== null) {
|
|
346
346
|
const chars = [...prompt.text];
|
|
347
347
|
const pos = Math.max(0, Math.min(prompt.pos, chars.length));
|
|
@@ -161,6 +161,14 @@ const boxAt = (map, mx, my) => {
|
|
|
161
161
|
}
|
|
162
162
|
return undefined;
|
|
163
163
|
};
|
|
164
|
+
/* the box of every node of a laid out graph, for the spatial navigation and the scrolling */
|
|
165
|
+
const placesOf = (graph) => {
|
|
166
|
+
const map = new Map();
|
|
167
|
+
if (graph !== undefined)
|
|
168
|
+
for (const n of graph.nodes.values())
|
|
169
|
+
map.set(n.id, { r: n.y + Math.floor(n.h / 2), c: n.x + Math.floor(n.w / 2), top: n.y, bottom: n.y + n.h - 1, bl: n.x, br: n.x + n.w - 1 });
|
|
170
|
+
return map;
|
|
171
|
+
};
|
|
164
172
|
/* the state of the agents view: the agents of the master list, the selected one (followed by its id,
|
|
165
173
|
else, until explicitly selected again, the one at the index of the previously selected one),
|
|
166
174
|
the lines of its operation pane, and the lines of its recent processing log in the detail view (within its frame), scrolled
|
|
@@ -343,13 +351,7 @@ export const useBoardState = (log, initial, relay) => {
|
|
|
343
351
|
}
|
|
344
352
|
}, [all, prompt]);
|
|
345
353
|
/* remember the box of every graph node for the spatial navigation and the scrolling */
|
|
346
|
-
const places = React.useMemo(() =>
|
|
347
|
-
const map = new Map();
|
|
348
|
-
if (layout !== null)
|
|
349
|
-
for (const n of layout.graph.nodes.values())
|
|
350
|
-
map.set(n.id, { r: n.y + Math.floor(n.h / 2), c: n.x + Math.floor(n.w / 2), top: n.y, bottom: n.y + n.h - 1, bl: n.x, br: n.x + n.w - 1 });
|
|
351
|
-
return map;
|
|
352
|
-
}, [layout]);
|
|
354
|
+
const places = React.useMemo(() => placesOf(layout?.graph), [layout]);
|
|
353
355
|
/* follow changes of the task storage and of the lifecycle mode,
|
|
354
356
|
and the kind and connection state of the task store
|
|
355
357
|
(in the background, i.e. without the busy popup) */
|
|
@@ -416,13 +418,7 @@ export const useBoardState = (log, initial, relay) => {
|
|
|
416
418
|
if (!flow.cards.has(flowSel) && !flow.states.some((s) => flowState(s) === flowSel) && flow.cards.size > 0)
|
|
417
419
|
setFlowSel(flow.cards.keys().next().value);
|
|
418
420
|
}, [flow, flowSel]);
|
|
419
|
-
const flowPlaces = React.useMemo(() =>
|
|
420
|
-
const map = new Map();
|
|
421
|
-
if (flowLayout !== null)
|
|
422
|
-
for (const n of flowLayout.graph.nodes.values())
|
|
423
|
-
map.set(n.id, { r: n.y + Math.floor(n.h / 2), c: n.x + Math.floor(n.w / 2), top: n.y, bottom: n.y + n.h - 1, bl: n.x, br: n.x + n.w - 1 });
|
|
424
|
-
return map;
|
|
425
|
-
}, [flowLayout]);
|
|
421
|
+
const flowPlaces = React.useMemo(() => placesOf(flowLayout?.graph), [flowLayout]);
|
|
426
422
|
/* fetch the AI usage of all tasks whenever the statistics view is shown or the board
|
|
427
423
|
changes, but only while the statistics view is shown (as each fetching loads all
|
|
428
424
|
plans), and once known in the background, i.e. without the busy popup */
|
|
@@ -21,6 +21,10 @@ const GRID_MIN = 30;
|
|
|
21
21
|
const GRID_GAP = 1;
|
|
22
22
|
/* make a text of the agent relay safe for the terminal (strip control characters) */
|
|
23
23
|
const clean = (text) => text.replace(/\p{Cc}/gu, "");
|
|
24
|
+
/* append to the content of an info line (" " if empty) the hint how to show the
|
|
25
|
+
hidden key hints again, so it need not be remembered while the key hints are hidden */
|
|
26
|
+
const keysHint = (surface, info) => surface.keys ? info : info === " " ? "?: show key hints" :
|
|
27
|
+
[...(Array.isArray(info) ? info : [info]), " · ?: show key hints"];
|
|
24
28
|
/* compute the visible group range starting at a first group, with the
|
|
25
29
|
width of each visible group (collapsed groups stay narrow, expanded
|
|
26
30
|
groups share the remaining width but never drop below the minimum) */
|
|
@@ -331,7 +335,8 @@ export const renderLanes = (ctx) => {
|
|
|
331
335
|
const arrows = shown < total && !grown;
|
|
332
336
|
const group = board.groups[sel.g];
|
|
333
337
|
const info = grown ? `lane ${group.lanes[sel.l].status} of group ${group.title} grown · g shrinks` :
|
|
334
|
-
`groups ${fit.first + 1}–${fit.last + 1} of ${total} · ${arrows ? "←/→ scrolls" : "all visible"}
|
|
338
|
+
`groups ${fit.first + 1}–${fit.last + 1} of ${total} · ${arrows ? "←/→ scrolls" : "all visible"}` +
|
|
339
|
+
(surface.keys ? "" : " · ?: show key hints");
|
|
335
340
|
const view = { board, surface, sel, dim, carry, titles: surface.titles, scroll: { left: -1, right: -1 }, pulse, cardRef, laneRef, groupRef, agents, working };
|
|
336
341
|
/* the scroll bar consumes the entire width remaining besides the info */
|
|
337
342
|
const track = Math.max(1, columns - 2 - info.length - 3);
|
|
@@ -390,8 +395,8 @@ export const renderGraph = (ctx) => {
|
|
|
390
395
|
})))))),
|
|
391
396
|
/* overlay the graph statistics centered onto the top border */
|
|
392
397
|
h(Box, { position: "absolute", top: 0, left: 0, width: "100%", justifyContent: "center" }, h(Text, { ...cx("dim", dim && "dimmed"), wrap: "truncate" }, `[ ${board.cards.size} tasks, ${deps} dependencies ]`))),
|
|
393
|
-
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), card === undefined ? " " :
|
|
394
|
-
["task: ", h(Text, { key: "id", ...cx("bold") }, card.id), " · status: ", h(Text, { key: "status", ...cx("bold") }, card.status)])),
|
|
398
|
+
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), keysHint(surface, card === undefined ? " " :
|
|
399
|
+
["task: ", h(Text, { key: "id", ...cx("bold") }, card.id), " · status: ", h(Text, { key: "status", ...cx("bold") }, card.status)]))),
|
|
395
400
|
h(Box, { key: "keys1", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), "↑/↓/←/→/Left-Click: select task · ⏎/Double-Click: view task · e: edit task · T: transition task")),
|
|
396
401
|
h(Box, { key: "keys2", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), `D: delete task · A: assign task · E: edit by prompt · R: request by prompt · N: new task · t: ${graphTitles ? "collapse" : "expand"} titles · ` +
|
|
397
402
|
`s: ${surface.standalone ? "hide" : "show"} standalone tasks`)),
|
|
@@ -434,7 +439,7 @@ export const renderFlow = (ctx) => {
|
|
|
434
439
|
})))))),
|
|
435
440
|
/* overlay the graph statistics centered onto the top border */
|
|
436
441
|
h(Box, { position: "absolute", top: 0, left: 0, width: "100%", justifyContent: "center" }, h(Text, { ...cx("dim", dim && "dimmed"), wrap: "truncate" }, `[ ${agents?.agents.length ?? 0} agents, ${flow.states.length} states ]`))),
|
|
437
|
-
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), rel !== null ? [
|
|
442
|
+
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), keysHint(ctx.surface, rel !== null ? [
|
|
438
443
|
"state: ", h(Text, { key: "state", ...cx("bold") }, rel.state),
|
|
439
444
|
" · observed by: ", h(Text, { key: "in", ...cx("bold") }, names(rel.input)),
|
|
440
445
|
" · written by: ", h(Text, { key: "out", ...cx("bold") }, names(rel.output)),
|
|
@@ -448,7 +453,7 @@ export const renderFlow = (ctx) => {
|
|
|
448
453
|
" · output: ", h(Text, { key: "out", ...cx("bold") }, states.output.join(", ") || "none"),
|
|
449
454
|
...(states.gate !== undefined ? [" · gate: ", h(Text, { key: "gate", ...cx("bold") }, states.gate)] : [])
|
|
450
455
|
])
|
|
451
|
-
])),
|
|
456
|
+
]))),
|
|
452
457
|
h(Box, { key: "keys1", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), "↑/↓/←/→/Left-Click: select agent/state · ⏎/Double-Click: view agent · " +
|
|
453
458
|
"⇈/⇊/⇤/⇥/Wheel: scroll canvas")),
|
|
454
459
|
h(Box, { key: "keys2", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), `v/V: ${viewCycleHint("flow", agents !== null)} · M: ${mouse ? "disable" : "enable"} mouse · ?: hide key hints · q: quit`))
|
|
@@ -554,12 +559,12 @@ export const renderAgents = (ctx) => {
|
|
|
554
559
|
const detail = h(Box, { key: "detail", flexGrow: 1, height: boardH, marginLeft: 1, flexDirection: "column" }, op, info, log);
|
|
555
560
|
return [
|
|
556
561
|
h(Box, { key: "agents", height: boardH, paddingX: 1 }, master, detail),
|
|
557
|
-
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", "truncate", dim && "dimmed"), agent === undefined ? " " : [
|
|
562
|
+
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", "truncate", dim && "dimmed"), keysHint(ctx.surface, agent === undefined ? " " : [
|
|
558
563
|
"agent: ", h(Text, { key: "agent", ...cx("bold") }, clean(agentLabel(agent))),
|
|
559
564
|
...(agentOp.title !== "" ? [
|
|
560
565
|
" · operation: ", h(Text, { key: "op", ...cx("bold") }, agentOp.title)
|
|
561
566
|
] : [])
|
|
562
|
-
])),
|
|
567
|
+
]))),
|
|
563
568
|
h(Box, { key: "keys1", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), "↑/↓/Left-Click: select agent · ⇈/⇊/⇤/⇥: page/top/bottom agent log · Mouse-Wheel: scroll agent log")),
|
|
564
569
|
h(Box, { key: "keys2", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), `v/V: ${viewCycleHint("agents", agents !== null)} · M: ${mouse ? "disable" : "enable"} mouse · ?: hide key hints · q: quit`))
|
|
565
570
|
];
|
|
@@ -839,8 +844,8 @@ export const renderStats = (ctx) => {
|
|
|
839
844
|
const shown = stats.states.reduce((n, s) => n + s.count, 0);
|
|
840
845
|
return [
|
|
841
846
|
h(Box, { key: "stats", height: boardH, paddingX: 1, flexDirection: "column", overflow: "hidden" }, ranges, chart, progress, usages, tops),
|
|
842
|
-
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), ["statistics of ", h(Text, { key: "n", ...cx("bold") }, String(shown)),
|
|
843
|
-
` ${filter !== "" ? "filtered " : ""}tasks`, ...(range !== "total" ? [" ", h(Text, { key: "r", ...cx("bold") }, statsRangeLabels[range])] : [])])),
|
|
847
|
+
h(Box, { key: "info", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), keysHint(ctx.surface, ["statistics of ", h(Text, { key: "n", ...cx("bold") }, String(shown)),
|
|
848
|
+
` ${filter !== "" ? "filtered " : ""}tasks`, ...(range !== "total" ? [" ", h(Text, { key: "r", ...cx("bold") }, statsRangeLabels[range])] : [])]))),
|
|
844
849
|
h(Box, { key: "keys1", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), `←/→: select time range · /: filter tasks · v/V: ${viewCycleHint("stats", agents !== null)}`)),
|
|
845
850
|
h(Box, { key: "keys2", ...cx("bar") }, h(Text, cx("hint", dim && "dimmed"), `M: ${mouse ? "disable" : "enable"} mouse · ?: hide key hints · q: quit`))
|
|
846
851
|
];
|