@ordewell/cli 0.4.0 → 0.4.3
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 +50 -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
|
@@ -133,6 +133,7 @@ Other:
|
|
|
133
133
|
ordewell setup Interactive first-run setup wizard
|
|
134
134
|
ordewell plugins list|install|remove|create Manage runner plugins
|
|
135
135
|
ordewell --help Show this help
|
|
136
|
+
ordewell --version Print the installed version (alias: version, -v)
|
|
136
137
|
|
|
137
138
|
TUI options:
|
|
138
139
|
--workspace /path Workspace directory (default: cwd)
|
|
@@ -3480,6 +3481,9 @@ function pickerItemsFor(state, action) {
|
|
|
3480
3481
|
detail: [m.provider, m.pricing].filter(Boolean).join(" \xB7 ") || void 0
|
|
3481
3482
|
}));
|
|
3482
3483
|
}
|
|
3484
|
+
if (action.kind === "set-runners") {
|
|
3485
|
+
return state.runners.map((runner) => ({ id: runner.id, label: runner.name }));
|
|
3486
|
+
}
|
|
3483
3487
|
if (action.kind === "set-task-runner") {
|
|
3484
3488
|
const task = state.tasks.find((candidate) => candidate.id === action.taskId);
|
|
3485
3489
|
if (!task) return [];
|
|
@@ -3769,6 +3773,16 @@ function choose(state, picker2, item) {
|
|
|
3769
3773
|
if (picker2.action.kind === "set-allowlist") {
|
|
3770
3774
|
return step(closed, [{ type: "setAllowlist", runner: picker2.action.runner, modelIds: picker2.chosen }]);
|
|
3771
3775
|
}
|
|
3776
|
+
if (picker2.action.kind === "set-runners") {
|
|
3777
|
+
const changes = state.runners.filter((runner) => runner.enabled !== picker2.chosen.includes(runner.id)).map((runner) => ({ runner: runner.id, enabled: !runner.enabled }));
|
|
3778
|
+
if (changes.length === 0) return step(closed);
|
|
3779
|
+
const names = state.runners.filter((r) => picker2.chosen.includes(r.id)).map((r) => r.name);
|
|
3780
|
+
return step(closed, [{
|
|
3781
|
+
type: "setRunners",
|
|
3782
|
+
changes,
|
|
3783
|
+
message: names.length > 0 ? `Runners enabled: ${names.join(", ")}.` : "No runners enabled \u2014 the planner has nothing to assign work to."
|
|
3784
|
+
}]);
|
|
3785
|
+
}
|
|
3772
3786
|
if (picker2.action.kind === "set-task-deps") {
|
|
3773
3787
|
const taskId = picker2.action.taskId;
|
|
3774
3788
|
const task = state.tasks.find((candidate) => candidate.id === taskId);
|
|
@@ -3801,14 +3815,6 @@ function choose(state, picker2, item) {
|
|
|
3801
3815
|
return step(closed, [{ type: "deleteSession", sessionId: item.id }]);
|
|
3802
3816
|
case "set-key":
|
|
3803
3817
|
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
3818
|
case "choose-allowlist-runner": {
|
|
3813
3819
|
const action = { kind: "set-allowlist", runner: item.id };
|
|
3814
3820
|
const items = pickerItemsFor(state, action);
|
|
@@ -3821,7 +3827,7 @@ function choose(state, picker2, item) {
|
|
|
3821
3827
|
kind: "picker",
|
|
3822
3828
|
picker: {
|
|
3823
3829
|
title: `Models allowed for ${item.label}`,
|
|
3824
|
-
hint: "
|
|
3830
|
+
hint: "An empty selection lifts the restriction.",
|
|
3825
3831
|
items,
|
|
3826
3832
|
filter: "",
|
|
3827
3833
|
index: 0,
|
|
@@ -4189,17 +4195,14 @@ function runners(state, args) {
|
|
|
4189
4195
|
if (enabled === null) return fail2(state, "Usage: /runners [<runner-id> on|off]");
|
|
4190
4196
|
return step(state, [{ type: "setRunnerEnabled", runner, enabled }]);
|
|
4191
4197
|
}
|
|
4192
|
-
const
|
|
4193
|
-
|
|
4194
|
-
label: r.name,
|
|
4195
|
-
detail: r.enabled ? "enabled" : "disabled",
|
|
4196
|
-
selected: r.enabled
|
|
4197
|
-
}));
|
|
4198
|
+
const action = { kind: "set-runners" };
|
|
4199
|
+
const items = pickerItemsFor(state, action);
|
|
4198
4200
|
return step({ ...state, overlay: {
|
|
4199
4201
|
kind: "picker",
|
|
4200
|
-
picker: picker("
|
|
4201
|
-
hint: "
|
|
4202
|
-
|
|
4202
|
+
picker: picker("Runners", items, action, {
|
|
4203
|
+
hint: "Enabled runners are the ones the planner may assign work to.",
|
|
4204
|
+
multi: true,
|
|
4205
|
+
chosen: state.runners.filter((r) => r.enabled).map((r) => r.id)
|
|
4203
4206
|
})
|
|
4204
4207
|
} });
|
|
4205
4208
|
}
|
|
@@ -4245,7 +4248,7 @@ function openTaskDepsPicker(state, task) {
|
|
|
4245
4248
|
overlay: {
|
|
4246
4249
|
kind: "picker",
|
|
4247
4250
|
picker: picker(`Depends on \xB7 #${task.order} ${task.title}`, items, action, {
|
|
4248
|
-
hint: "Only tasks earlier in the plan can be dependencies.
|
|
4251
|
+
hint: "Only tasks earlier in the plan can be dependencies.",
|
|
4249
4252
|
multi: true,
|
|
4250
4253
|
chosen: task.dependencies.filter((id) => items.some((i) => i.id === id))
|
|
4251
4254
|
})
|
|
@@ -4879,14 +4882,14 @@ function renderPicker(picker2, rows, cols) {
|
|
|
4879
4882
|
const start = Math.max(0, Math.min(picker2.index - Math.floor(room / 2), items.length - room));
|
|
4880
4883
|
for (const [offset, item] of items.slice(start, start + room).entries()) {
|
|
4881
4884
|
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
|
|
4885
|
+
const mark = picker2.multi ? picker2.chosen.includes(item.id) ? style.green("[\u2713]") : style.grey("[ ]") : item.selected ? style.green("\u25CF") : " ";
|
|
4883
4886
|
const caret = active ? style.cyan("\u276F") : " ";
|
|
4884
4887
|
const label = truncate(item.label, Math.max(1, cols - 12));
|
|
4885
4888
|
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}`;
|
|
4889
|
+
const line = item.disabled ? `${caret} ${mark} ${style.grey(label)}${detail}` : `${caret} ${mark} ${active ? style.bold(label) : label}${detail}`;
|
|
4887
4890
|
body.push(truncate(line, cols - 2));
|
|
4888
4891
|
}
|
|
4889
|
-
body.push("", style.grey(picker2.
|
|
4892
|
+
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
4893
|
return frame(picker2.title, body, rows, cols);
|
|
4891
4894
|
}
|
|
4892
4895
|
var CATEGORY_TITLE = {
|
|
@@ -5176,6 +5179,14 @@ async function perform(effect, deps) {
|
|
|
5176
5179
|
await loadRunners(deps);
|
|
5177
5180
|
dispatch({ type: "notice", message: `${effect.runner} ${effect.enabled ? "enabled" : "disabled"}.` });
|
|
5178
5181
|
return;
|
|
5182
|
+
case "setRunners": {
|
|
5183
|
+
for (const change of effect.changes) {
|
|
5184
|
+
await api.setRunnerEnabled(change.runner, change.enabled);
|
|
5185
|
+
}
|
|
5186
|
+
await loadRunners(deps);
|
|
5187
|
+
dispatch({ type: "notice", message: effect.message });
|
|
5188
|
+
return;
|
|
5189
|
+
}
|
|
5179
5190
|
case "setAutonomous":
|
|
5180
5191
|
deps.setEnvVar("ORDEWELL_AUTONOMOUS_MODE", String(effect.enabled));
|
|
5181
5192
|
dispatch({ type: "notice", message: `Autonomous mode ${effect.enabled ? "on" : "off"}.` });
|
|
@@ -5694,6 +5705,19 @@ var COMMANDS = {
|
|
|
5694
5705
|
tui: handleTui
|
|
5695
5706
|
};
|
|
5696
5707
|
|
|
5708
|
+
// src/version.ts
|
|
5709
|
+
var import_fs7 = require("fs");
|
|
5710
|
+
var import_path5 = require("path");
|
|
5711
|
+
function cliVersion() {
|
|
5712
|
+
try {
|
|
5713
|
+
const pkg = JSON.parse((0, import_fs7.readFileSync)((0, import_path5.join)(__dirname, "..", "package.json"), "utf8"));
|
|
5714
|
+
const version = pkg.version;
|
|
5715
|
+
return typeof version === "string" && version ? version : "unknown";
|
|
5716
|
+
} catch {
|
|
5717
|
+
return "unknown";
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5720
|
+
|
|
5697
5721
|
// src/main.ts
|
|
5698
5722
|
async function main() {
|
|
5699
5723
|
loadEnvFile();
|
|
@@ -5703,6 +5727,10 @@ async function main() {
|
|
|
5703
5727
|
printHelp();
|
|
5704
5728
|
return;
|
|
5705
5729
|
}
|
|
5730
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
5731
|
+
console.log(cliVersion());
|
|
5732
|
+
return;
|
|
5733
|
+
}
|
|
5706
5734
|
const handler = COMMANDS[command];
|
|
5707
5735
|
if (!handler) {
|
|
5708
5736
|
console.error(`Unknown command: ${command}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ordewell/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
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.3",
|
|
52
|
+
"@ordewell/web": "^0.4.3",
|
|
53
53
|
"string-width": "^7.2.0",
|
|
54
54
|
"ws": "^8.18.0"
|
|
55
55
|
},
|