@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.
Files changed (3) hide show
  1. package/README.md +14 -5
  2. package/dist/main.js +32 -22
  3. 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 it and verify the result from evidence.
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-..." # or GEMINI_API_KEY — auto-detected
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. Linux, macOS and Windows are all supported; the TUI is
36
- tmux-backed, so on Windows run it under WSL.
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: "space toggles \xB7 enter confirms \xB7 empty selection lifts the restriction",
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 items = state.runners.map((r) => ({
4193
- id: r.id,
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("Toggle runner", items, { kind: "toggle-runner" }, {
4201
- hint: "Changes apply immediately.",
4202
- footer: "enter toggles \xB7 esc closes \xB7 type to filter"
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. Space toggles, enter saves.",
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.footer ?? (picker2.multi ? "space toggles \xB7 enter confirms \xB7 esc cancels" : "enter selects \xB7 esc cancels \xB7 type to filter")));
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.0",
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.0",
52
- "@ordewell/web": "^0.4.0",
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
  },