@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.
Files changed (3) hide show
  1. package/README.md +14 -5
  2. package/dist/main.js +50 -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
@@ -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: "space toggles \xB7 enter confirms \xB7 empty selection lifts the restriction",
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 items = state.runners.map((r) => ({
4193
- id: r.id,
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("Toggle runner", items, { kind: "toggle-runner" }, {
4201
- hint: "Changes apply immediately.",
4202
- footer: "enter toggles \xB7 esc closes \xB7 type to filter"
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. Space toggles, enter saves.",
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.footer ?? (picker2.multi ? "space toggles \xB7 enter confirms \xB7 esc cancels" : "enter selects \xB7 esc cancels \xB7 type to filter")));
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.0",
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.0",
52
- "@ordewell/web": "^0.4.0",
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
  },