@crafts69guy/orchestra 0.5.0 → 0.6.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orch",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Orchestrator workflow: scope, implement, review, ship via specialised subagents and worktrees.",
5
5
  "author": {
6
6
  "name": "crafts69guy"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orch",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Orchestrator workflow: scope, implement, review, ship via specialised subagents and worktrees.",
5
5
  "author": {
6
6
  "name": "crafts69guy",
package/README.md CHANGED
@@ -48,6 +48,7 @@ codex plugin marketplace add crafts69guy/orchestra
48
48
  | `orch doctor` | checks Node, git, `wt`, the harness CLIs and the installed plugins |
49
49
  | `orch claude [--yolo] [args...]` | starts `claude` with `ORCH=1` and `--model opus` (unless you pass `--model`) |
50
50
  | `orch codex [--yolo] [args...]` | starts `codex` with `ORCH=1` and the orchestration context (below) |
51
+ | `orch update` | updates the npm CLI, then the plugin for each harness that has the `orchestra` marketplace (`claude plugin update orch@orchestra`, `codex plugin marketplace upgrade orchestra`); skips npm from a git checkout |
51
52
  | `orch wt new\|merge\|list ...` | worktree helper used by the `dispatch` skill; prints JSON |
52
53
  | `orch eval [args...]` | behaviour evals; only from a git checkout (see [AGENTS.md](AGENTS.md)) |
53
54
  | `orch --help`, `orch --version` | usage and version |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crafts69guy/orchestra",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "description": "Cross-harness (Claude Code + Codex) orchestration workflow plugin",
6
6
  "license": "MIT",
package/scripts/orch.mjs CHANGED
@@ -4,7 +4,7 @@ import { join } from 'node:path';
4
4
  import { pluginRoot, which } from '../hooks/session-start.mjs';
5
5
  import { run as doctor } from './doctor.mjs';
6
6
  import { run as codex, gitCommonDir, spawnExit } from './orch-codex.mjs';
7
- import { run as wt, realDeps as wtDeps } from './orch-wt.mjs';
7
+ import { exec, run as wt, realDeps as wtDeps } from './orch-wt.mjs';
8
8
 
9
9
  export const USAGE = `usage: orch <command> [args]
10
10
 
@@ -13,6 +13,7 @@ commands:
13
13
  codex [--yolo] [args] run codex with the orch workflow
14
14
  wt new|merge|list ... manage task worktrees (prints JSON)
15
15
  doctor check prerequisites
16
+ update update the npm CLI and the installed Claude/Codex plugins
16
17
  eval [args] run the behaviour evals (git checkout only)
17
18
  help, -h, --help show this help
18
19
  -V, --version print the version
@@ -35,6 +36,43 @@ export function claudeArgs(args) {
35
36
  ];
36
37
  }
37
38
 
39
+ /**
40
+ * True when `cmd plugin marketplace list --json` names the `orchestra` marketplace. Claude prints
41
+ * an array, Codex `{ marketplaces: [...] }`. A missing binary or unparsable output is false.
42
+ */
43
+ export function hasOrchestra(io, cmd) {
44
+ const r = io.exec(cmd, ['plugin', 'marketplace', 'list', '--json']);
45
+ if (r.status !== 0) return false;
46
+ try {
47
+ const out = JSON.parse(r.stdout);
48
+ const list = Array.isArray(out) ? out : (out?.marketplaces ?? []);
49
+ return list.some((m) => m?.name === 'orchestra');
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Steps of `orch update` as `[cmd, args]`. The npm step is skipped in a git checkout (update it
57
+ * with `git pull`); a harness step is skipped unless that harness has the `orchestra` marketplace.
58
+ */
59
+ export function updateSteps(io) {
60
+ return [
61
+ ...(io.exists(join(io.root, '.git'))
62
+ ? []
63
+ : [['npm', ['install', '-g', '@crafts69guy/orchestra@latest']]]),
64
+ ...(hasOrchestra(io, 'claude')
65
+ ? [
66
+ ['claude', ['plugin', 'marketplace', 'update', 'orchestra']],
67
+ ['claude', ['plugin', 'update', 'orch@orchestra']],
68
+ ]
69
+ : []),
70
+ ...(hasOrchestra(io, 'codex')
71
+ ? [['codex', ['plugin', 'marketplace', 'upgrade', 'orchestra']]]
72
+ : []),
73
+ ];
74
+ }
75
+
38
76
  /** Each command takes `(args, io)` and returns the exit code. */
39
77
  export const commands = {
40
78
  claude: (args, io) =>
@@ -62,6 +100,20 @@ export const commands = {
62
100
  io.stdout(`${lines.join('\n')}\n`);
63
101
  return code;
64
102
  },
103
+ /** Runs every step even after a failure; returns the first non-zero code. */
104
+ update(_args, io) {
105
+ if (io.exists(join(io.root, '.git'))) {
106
+ io.stderr(`orch: ${io.root} is a git checkout; skipping npm (run git pull there)\n`);
107
+ }
108
+ let code = 0;
109
+ for (const [cmd, args] of updateSteps(io)) {
110
+ io.stdout(`$ ${cmd} ${args.join(' ')}\n`);
111
+ const c = spawnExit(io.spawn(cmd, args, { env: io.env }), cmd, io.stderr, 'skipping.');
112
+ if (c !== 0 && code === 0) code = c;
113
+ }
114
+ if (code === 0) io.stdout('orch: updated; restart Claude Code / Codex sessions to apply\n');
115
+ return code;
116
+ },
65
117
  eval(args, io) {
66
118
  const script = join(io.root, 'evals', '_support', 'run.sh');
67
119
  if (!io.exists(script)) {
@@ -103,6 +155,7 @@ export function realIo(proc, metaUrl) {
103
155
  read: readFileSync,
104
156
  readdir: readdirSync,
105
157
  hasCommand: which,
158
+ exec,
106
159
  gitDir: gitCommonDir,
107
160
  wtDeps,
108
161
  };