@ordewell/cli 0.4.0 → 0.4.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/README.md +14 -5
- package/dist/main.js +32 -22
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
The command line and terminal UI for **[Ordewell](https://ordewell.ai)** — turn one
|
|
4
4
|
goal into an ordered plan of coding-agent tasks, each with its own runner, model
|
|
5
|
-
and mode, then execute
|
|
5
|
+
and mode, then execute and verify it.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -g @ordewell/cli
|
|
8
|
+
npm install -g @ordewell/cli # or: npm install -g ordewell
|
|
9
9
|
|
|
10
|
-
export OPENROUTER_API_KEY="sk-or-..." #
|
|
10
|
+
export OPENROUTER_API_KEY="sk-or-..." # any one provider key — auto-detected
|
|
11
11
|
|
|
12
|
+
ordewell # the TUI
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Bare `ordewell` opens the full-screen terminal UI. On first run it tells you
|
|
16
|
+
what it still needs — a planner and at least one runner — both settable from
|
|
17
|
+
inside it with `/planner`, `/runners` and `/key`. Or drive it as a CLI:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
12
20
|
ordewell plan --goal "Add rate limiting to the public API"
|
|
13
21
|
ordewell run
|
|
14
22
|
```
|
|
@@ -32,8 +40,9 @@ ordewell --help # every slash command is also a subcommand
|
|
|
32
40
|
|
|
33
41
|
## Requirements
|
|
34
42
|
|
|
35
|
-
Node.js ≥ 20
|
|
36
|
-
|
|
43
|
+
Node.js ≥ 20, and **tmux** for the TUI on every platform — it is what backs each
|
|
44
|
+
task's live terminal (`apt install tmux`, `brew install tmux`). Linux, macOS and
|
|
45
|
+
Windows are all supported; on Windows, run the TUI under WSL.
|
|
37
46
|
|
|
38
47
|
Installing this package also installs `@ordewell/web`, the local API server the
|
|
39
48
|
CLI and TUI drive over `127.0.0.1`. It starts on demand — you don't need to run
|
package/dist/main.js
CHANGED
|
@@ -3480,6 +3480,9 @@ function pickerItemsFor(state, action) {
|
|
|
3480
3480
|
detail: [m.provider, m.pricing].filter(Boolean).join(" \xB7 ") || void 0
|
|
3481
3481
|
}));
|
|
3482
3482
|
}
|
|
3483
|
+
if (action.kind === "set-runners") {
|
|
3484
|
+
return state.runners.map((runner) => ({ id: runner.id, label: runner.name }));
|
|
3485
|
+
}
|
|
3483
3486
|
if (action.kind === "set-task-runner") {
|
|
3484
3487
|
const task = state.tasks.find((candidate) => candidate.id === action.taskId);
|
|
3485
3488
|
if (!task) return [];
|
|
@@ -3769,6 +3772,16 @@ function choose(state, picker2, item) {
|
|
|
3769
3772
|
if (picker2.action.kind === "set-allowlist") {
|
|
3770
3773
|
return step(closed, [{ type: "setAllowlist", runner: picker2.action.runner, modelIds: picker2.chosen }]);
|
|
3771
3774
|
}
|
|
3775
|
+
if (picker2.action.kind === "set-runners") {
|
|
3776
|
+
const changes = state.runners.filter((runner) => runner.enabled !== picker2.chosen.includes(runner.id)).map((runner) => ({ runner: runner.id, enabled: !runner.enabled }));
|
|
3777
|
+
if (changes.length === 0) return step(closed);
|
|
3778
|
+
const names = state.runners.filter((r) => picker2.chosen.includes(r.id)).map((r) => r.name);
|
|
3779
|
+
return step(closed, [{
|
|
3780
|
+
type: "setRunners",
|
|
3781
|
+
changes,
|
|
3782
|
+
message: names.length > 0 ? `Runners enabled: ${names.join(", ")}.` : "No runners enabled \u2014 the planner has nothing to assign work to."
|
|
3783
|
+
}]);
|
|
3784
|
+
}
|
|
3772
3785
|
if (picker2.action.kind === "set-task-deps") {
|
|
3773
3786
|
const taskId = picker2.action.taskId;
|
|
3774
3787
|
const task = state.tasks.find((candidate) => candidate.id === taskId);
|
|
@@ -3801,14 +3814,6 @@ function choose(state, picker2, item) {
|
|
|
3801
3814
|
return step(closed, [{ type: "deleteSession", sessionId: item.id }]);
|
|
3802
3815
|
case "set-key":
|
|
3803
3816
|
return step({ ...state, overlay: keyPrompt(item.id) });
|
|
3804
|
-
case "toggle-runner": {
|
|
3805
|
-
const enabled = !(state.runners.find((r) => r.id === item.id)?.enabled ?? item.selected ?? false);
|
|
3806
|
-
const items = picker2.items.map((i) => i.id === item.id ? { ...i, selected: enabled, detail: enabled ? "enabled" : "disabled" } : i);
|
|
3807
|
-
return step(
|
|
3808
|
-
{ ...state, overlay: { kind: "picker", picker: { ...picker2, items } } },
|
|
3809
|
-
[{ type: "setRunnerEnabled", runner: item.id, enabled }]
|
|
3810
|
-
);
|
|
3811
|
-
}
|
|
3812
3817
|
case "choose-allowlist-runner": {
|
|
3813
3818
|
const action = { kind: "set-allowlist", runner: item.id };
|
|
3814
3819
|
const items = pickerItemsFor(state, action);
|
|
@@ -3821,7 +3826,7 @@ function choose(state, picker2, item) {
|
|
|
3821
3826
|
kind: "picker",
|
|
3822
3827
|
picker: {
|
|
3823
3828
|
title: `Models allowed for ${item.label}`,
|
|
3824
|
-
hint: "
|
|
3829
|
+
hint: "An empty selection lifts the restriction.",
|
|
3825
3830
|
items,
|
|
3826
3831
|
filter: "",
|
|
3827
3832
|
index: 0,
|
|
@@ -4189,17 +4194,14 @@ function runners(state, args) {
|
|
|
4189
4194
|
if (enabled === null) return fail2(state, "Usage: /runners [<runner-id> on|off]");
|
|
4190
4195
|
return step(state, [{ type: "setRunnerEnabled", runner, enabled }]);
|
|
4191
4196
|
}
|
|
4192
|
-
const
|
|
4193
|
-
|
|
4194
|
-
label: r.name,
|
|
4195
|
-
detail: r.enabled ? "enabled" : "disabled",
|
|
4196
|
-
selected: r.enabled
|
|
4197
|
-
}));
|
|
4197
|
+
const action = { kind: "set-runners" };
|
|
4198
|
+
const items = pickerItemsFor(state, action);
|
|
4198
4199
|
return step({ ...state, overlay: {
|
|
4199
4200
|
kind: "picker",
|
|
4200
|
-
picker: picker("
|
|
4201
|
-
hint: "
|
|
4202
|
-
|
|
4201
|
+
picker: picker("Runners", items, action, {
|
|
4202
|
+
hint: "Enabled runners are the ones the planner may assign work to.",
|
|
4203
|
+
multi: true,
|
|
4204
|
+
chosen: state.runners.filter((r) => r.enabled).map((r) => r.id)
|
|
4203
4205
|
})
|
|
4204
4206
|
} });
|
|
4205
4207
|
}
|
|
@@ -4245,7 +4247,7 @@ function openTaskDepsPicker(state, task) {
|
|
|
4245
4247
|
overlay: {
|
|
4246
4248
|
kind: "picker",
|
|
4247
4249
|
picker: picker(`Depends on \xB7 #${task.order} ${task.title}`, items, action, {
|
|
4248
|
-
hint: "Only tasks earlier in the plan can be dependencies.
|
|
4250
|
+
hint: "Only tasks earlier in the plan can be dependencies.",
|
|
4249
4251
|
multi: true,
|
|
4250
4252
|
chosen: task.dependencies.filter((id) => items.some((i) => i.id === id))
|
|
4251
4253
|
})
|
|
@@ -4879,14 +4881,14 @@ function renderPicker(picker2, rows, cols) {
|
|
|
4879
4881
|
const start = Math.max(0, Math.min(picker2.index - Math.floor(room / 2), items.length - room));
|
|
4880
4882
|
for (const [offset, item] of items.slice(start, start + room).entries()) {
|
|
4881
4883
|
const active = start + offset === picker2.index;
|
|
4882
|
-
const mark = picker2.multi ? picker2.chosen.includes(item.id) ? style.green("[\u2713]") : style.grey("[ ]") : item.selected ? style.green("\u25CF
|
|
4884
|
+
const mark = picker2.multi ? picker2.chosen.includes(item.id) ? style.green("[\u2713]") : style.grey("[ ]") : item.selected ? style.green("\u25CF") : " ";
|
|
4883
4885
|
const caret = active ? style.cyan("\u276F") : " ";
|
|
4884
4886
|
const label = truncate(item.label, Math.max(1, cols - 12));
|
|
4885
4887
|
const detail = item.detail ? style.grey(` \u2014 ${item.detail}`) : "";
|
|
4886
|
-
const line = item.disabled ? `${caret}${mark} ${style.grey(label)}${detail}` : `${caret}${mark} ${active ? style.bold(label) : label}${detail}`;
|
|
4888
|
+
const line = item.disabled ? `${caret} ${mark} ${style.grey(label)}${detail}` : `${caret} ${mark} ${active ? style.bold(label) : label}${detail}`;
|
|
4887
4889
|
body.push(truncate(line, cols - 2));
|
|
4888
4890
|
}
|
|
4889
|
-
body.push("", style.grey(picker2.
|
|
4891
|
+
body.push("", style.grey(picker2.multi ? "space toggles \xB7 enter confirms \xB7 esc cancels \xB7 type to filter" : "enter selects \xB7 esc cancels \xB7 type to filter"));
|
|
4890
4892
|
return frame(picker2.title, body, rows, cols);
|
|
4891
4893
|
}
|
|
4892
4894
|
var CATEGORY_TITLE = {
|
|
@@ -5176,6 +5178,14 @@ async function perform(effect, deps) {
|
|
|
5176
5178
|
await loadRunners(deps);
|
|
5177
5179
|
dispatch({ type: "notice", message: `${effect.runner} ${effect.enabled ? "enabled" : "disabled"}.` });
|
|
5178
5180
|
return;
|
|
5181
|
+
case "setRunners": {
|
|
5182
|
+
for (const change of effect.changes) {
|
|
5183
|
+
await api.setRunnerEnabled(change.runner, change.enabled);
|
|
5184
|
+
}
|
|
5185
|
+
await loadRunners(deps);
|
|
5186
|
+
dispatch({ type: "notice", message: effect.message });
|
|
5187
|
+
return;
|
|
5188
|
+
}
|
|
5179
5189
|
case "setAutonomous":
|
|
5180
5190
|
deps.setEnvVar("ORDEWELL_AUTONOMOUS_MODE", String(effect.enabled));
|
|
5181
5191
|
dispatch({ type: "notice", message: `Autonomous mode ${effect.enabled ? "on" : "off"}.` });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ordewell/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Ordewell CLI and TUI — plan, run and verify coding-agent tasks from the terminal.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Alessandro Costanzo Ciano",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"typecheck": "tsc --noEmit"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@ordewell/core": "^0.4.
|
|
52
|
-
"@ordewell/web": "^0.4.
|
|
51
|
+
"@ordewell/core": "^0.4.2",
|
|
52
|
+
"@ordewell/web": "^0.4.2",
|
|
53
53
|
"string-width": "^7.2.0",
|
|
54
54
|
"ws": "^8.18.0"
|
|
55
55
|
},
|