model-orchestrator 0.1.35 → 1.0.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.
Files changed (124) hide show
  1. package/AGENTS.md +31 -21
  2. package/CHANGELOG.md +58 -1
  3. package/README.md +129 -110
  4. package/SECURITY.md +7 -3
  5. package/bin/README.md +57 -6
  6. package/bin/aunx.js +7 -0
  7. package/bin/cli-run.mjs +21 -15
  8. package/bin/cli.js +376 -257
  9. package/docs/README.md +15 -18
  10. package/docs/catalog.md +236 -44
  11. package/docs/companions.md +28 -10
  12. package/docs/guarantees.md +21 -12
  13. package/docs/how-it-routes.md +49 -42
  14. package/docs/install.md +141 -33
  15. package/docs/part-1-beginner.md +37 -45
  16. package/docs/part-2-intermediate.md +34 -52
  17. package/docs/part-3-advanced.md +36 -26
  18. package/docs/security-review-history.md +39 -0
  19. package/llms.txt +24 -25
  20. package/package.json +15 -8
  21. package/proof/README.md +100 -0
  22. package/proof/gate-demo.cast +9 -0
  23. package/proof/gate-demo.gif +0 -0
  24. package/proof/results.json +198 -0
  25. package/proof/scripts/check-gate.js +26 -0
  26. package/proof/scripts/install-time.js +16 -0
  27. package/proof/scripts/lib.js +73 -0
  28. package/proof/scripts/measure.js +15 -0
  29. package/proof/scripts/missing-results.js +30 -0
  30. package/proof/scripts/record-gate.js +38 -0
  31. package/proof/scripts/render.js +18 -0
  32. package/proof/scripts/runner-overhead.js +21 -0
  33. package/src/README.md +10 -3
  34. package/src/activation-ownership.js +19 -0
  35. package/src/apply-companions.js +104 -0
  36. package/src/apply-snippets.js +60 -28
  37. package/src/aunx.js +272 -0
  38. package/src/bounded-file.js +31 -0
  39. package/src/catalog.js +257 -121
  40. package/src/install.js +483 -212
  41. package/src/plugin.js +13 -4
  42. package/src/postinstall.js +57 -0
  43. package/src/roles.js +184 -0
  44. package/src/uninstall.js +128 -10
  45. package/templates/README.md +19 -2
  46. package/templates/advanced/README.md +2 -2
  47. package/templates/advanced/vm/ENVIRONMENT.md +8 -0
  48. package/templates/advanced/vm/PRIVACY_GATES.md +17 -19
  49. package/templates/advanced/vm/README.md +25 -20
  50. package/templates/advanced/vm/box-CLAUDE.md +19 -18
  51. package/templates/advanced/vm/docker-compose.yml +2 -1
  52. package/templates/advanced/vm/jobs/README.md +31 -2
  53. package/templates/advanced/vm/jobs/weekly-audit.service +7 -2
  54. package/templates/advanced/vm/jobs/weekly-audit.sh +24 -17
  55. package/templates/advanced/vm/setup-vm.sh +49 -2
  56. package/templates/agents/README.md +2 -2
  57. package/templates/agents/agy/README.md +20 -3
  58. package/templates/agents/agy/builder.md +11 -7
  59. package/templates/agents/agy/bulk-worker.md +9 -7
  60. package/templates/agents/agy/code-reviewer.md +13 -7
  61. package/templates/agents/agy/deep-planner.md +10 -7
  62. package/templates/agents/agy/done-verifier.md +13 -22
  63. package/templates/agents/agy/finding-verifier.md +14 -22
  64. package/templates/agents/agy/live-researcher.md +10 -7
  65. package/templates/agents/agy/reader.md +10 -12
  66. package/templates/agents/claude-code/README.md +18 -14
  67. package/templates/agents/claude-code/builder.md +10 -15
  68. package/templates/agents/claude-code/bulk-worker.md +8 -10
  69. package/templates/agents/claude-code/code-reviewer.md +11 -17
  70. package/templates/agents/claude-code/deep-planner.md +9 -11
  71. package/templates/agents/claude-code/done-verifier.md +12 -33
  72. package/templates/agents/claude-code/finding-verifier.md +13 -39
  73. package/templates/agents/claude-code/live-researcher.md +9 -11
  74. package/templates/agents/claude-code/reader.md +9 -18
  75. package/templates/agents/snippets/chat.md +9 -10
  76. package/templates/agents/snippets/claude-code.md +17 -18
  77. package/templates/agents/snippets/generic.md +9 -11
  78. package/templates/agents/snippets/route-gate.mjs +2 -2
  79. package/templates/agents/snippets/route-metrics.mjs +1 -1
  80. package/templates/agents/snippets/subagent-context.mjs +4 -4
  81. package/templates/beginner/ORCHESTRATOR.md +31 -36
  82. package/templates/beginner/README.md +1 -1
  83. package/templates/common/ACCEPTANCE_CHECKS.json +12 -0
  84. package/templates/common/CONTEXT.md +37 -0
  85. package/templates/common/DECISIONS.md +11 -0
  86. package/templates/common/README.md +24 -11
  87. package/templates/common/TASK_BRIEF.md +84 -0
  88. package/templates/common/protocols/README.md +14 -11
  89. package/templates/common/protocols/acceptance-checks.md +15 -0
  90. package/templates/common/protocols/build-protocol.md +91 -106
  91. package/templates/common/protocols/context-file.md +10 -0
  92. package/templates/common/protocols/decision-log.md +9 -0
  93. package/templates/common/protocols/deep-research.md +20 -34
  94. package/templates/common/protocols/docs-then-prove.md +13 -18
  95. package/templates/common/protocols/gap-analysis.md +15 -21
  96. package/templates/common/protocols/memory-and-record.md +21 -20
  97. package/templates/common/protocols/numbers-and-logic.md +20 -26
  98. package/templates/common/protocols/propagate.md +18 -27
  99. package/templates/intermediate/CLI-RUN.md +83 -113
  100. package/templates/intermediate/DELEGATION_MATRIX.md +9 -3
  101. package/templates/intermediate/README.md +3 -3
  102. package/templates/intermediate/RESEARCH_TRIAGE.md +23 -15
  103. package/templates/intermediate/ROUTING.md +54 -51
  104. package/templates/intermediate/TIERS.md +37 -76
  105. package/templates/tools/README.md +1 -1
  106. package/templates/tools/codecalc/CODECALC.md +4 -4
  107. package/templates/tools/codecalc/mcp/agy.mcp_config.json +1 -1
  108. package/templates/tools/codecalc/mcp/codex.config.toml +1 -1
  109. package/templates/tools/codecalc/mcp/mcpServers.json +1 -1
  110. package/templates/tools/codecalc/mcp/vscode.mcp.json +1 -1
  111. package/templates/tools/codecalc/mcp/zed.settings.json +1 -1
  112. package/templates/tools/context7/CONTEXT7.md +6 -10
  113. package/templates/tools/obsidian-tc/OBSIDIAN-TC.md +3 -3
  114. package/templates/tools/obsidian-tc/mcp/obsidian-tc.agy.mcp_config.json +1 -1
  115. package/templates/tools/obsidian-tc/mcp/obsidian-tc.codex.config.toml +1 -1
  116. package/templates/tools/obsidian-tc/mcp/obsidian-tc.mcpServers.json +1 -1
  117. package/templates/tools/obsidian-tc/mcp/obsidian-tc.vscode.mcp.json +1 -1
  118. package/templates/tools/obsidian-tc/mcp/obsidian-tc.zed.settings.json +1 -1
  119. package/docs/audit-brief.md +0 -148
  120. package/scripts/README.md +0 -7
  121. package/scripts/gen-catalog.js +0 -81
  122. package/scripts/gen-plugin.js +0 -16
  123. package/scripts/record-demo.sh +0 -45
  124. package/templates/common/TASK_BUNDLE.md +0 -56
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env node
2
- // Regenerates docs/catalog.md and the README's vendor compatibility table from
3
- // src/catalog.js. The test suite checks they agree, so neither can drift (#23).
4
- import { writeFileSync, readFileSync } from 'node:fs';
5
- import { AIS, LEVELS, TOOLS, IMAGES, npmSpec } from '../src/catalog.js';
6
- import { readdirSync } from 'node:fs';
7
-
8
- export function protocolCount() {
9
- return readdirSync(new URL('../templates/common/protocols/', import.meta.url)).filter((f) => f.endsWith('.md') && f !== 'README.md').length;
10
- }
11
-
12
- export function catalogMarkdown() {
13
- let md = '# Catalog\n\nGenerated from `src/catalog.js`. Do not hand-edit; `npm run gen:catalog` rewrites it. Protocols shipped at every level: ' + protocolCount() + ' (counted from `templates/common/protocols/`).\n\n## Levels\n\n| Level | Name | Tagline | Gives |\n|---|---|---|---|\n';
14
- for (const l of LEVELS) md += `| ${l.id} | ${l.name} | ${l.tagline} | ${l.gives} |\n`;
15
- md += '\n## AIs\n\n';
16
- for (const a of AIS) {
17
- const how = a.install.npm
18
- ? '`npm install -g ' + npmSpec(a) + '`'
19
- : a.install.script
20
- ? 'vendor script (read it first): `' + a.install.script + '`'
21
- : a.install.url + (a.install.brew ? ' (or `brew install ' + a.install.brew + '`)' : '');
22
- md += `### \`${a.id}\` · ${a.name}\n\n- **Kind:** ${a.kind} · **Access:** ${a.access} · **Lane:** ${a.lane} · **Level:** ${a.minLevel}+\n- **Wins at:** ${a.role}\n- **Install:** ${how}\n- **Sign in:** ${a.auth}\n`;
23
- if (a.rulesFile) md += `- **Reads rules from:** \`${a.rulesFile}\`` + (a.agentsDir ? ` · subagents in \`${a.agentsDir}/\`` : '') + '\n';
24
- if (a.cliRun) md += '- **cli-run lane:** yes\n';
25
- if (a.plans) {
26
- md += '- **Plans:**\n';
27
- for (const p of a.plans) md += ` - ${p.name} (${p.headroom} headroom, checked ${p.checked}): ${p.source}\n`;
28
- }
29
- if (a.builtAgainst) md += `- **Built against:** ${a.builtAgainst}` + (a.install.npm ? ' (the same number the npm pin uses)' : '') + '\n';
30
- if (a.note) md += `- **Note:** ${a.note}\n`;
31
- md += '\n';
32
- }
33
- md += '## Companion tools\n\n';
34
- for (const t of TOOLS) {
35
- md += `### \`${t.id}\` · ${t.name}\n\n- **Repo:** ${t.repo}\n- **Gives:** ${t.role}\n- **Install:** \`${t.install}\` (needs ${t.requires})\n- **Registers itself with:** ${t.autoClients.join(', ')}; snippets for the rest are written to \`mcp/\`\n- **Default:** ${t.recommended ? 'selected' : 'not selected'}\n\n`;
36
- }
37
- return md;
38
- }
39
-
40
- export const VENDOR_TABLE_START = '<!-- vendor-table:start -->';
41
- export const VENDOR_TABLE_END = '<!-- vendor-table:end -->';
42
-
43
- export function fixtureManifest() {
44
- return JSON.parse(readFileSync(new URL('../test/fixtures/manifest.json', import.meta.url), 'utf8'));
45
- }
46
-
47
- // The compatibility table in README.md. Every number comes from `builtAgainst`
48
- // in src/catalog.js, which is also the npm pin where there is one, so "built
49
- // against" and "pinned to" are the same number by construction (#23).
50
- export function vendorTableMarkdown() {
51
- const fx = fixtureManifest();
52
- const byLane = Object.fromEntries(fx.fixtures.map((f) => [f.lane, f]));
53
- let md = VENDOR_TABLE_START + '\n\n| Lane | Vendor | Version this release was built against | Where that number is proved |\n|---|---|---|---|\n';
54
- for (const a of AIS) {
55
- if (!a.bin || !a.builtAgainst) continue;
56
- const proof = byLane[a.id]
57
- ? '`test/fixtures/' + byLane[a.id].file + '`, a recorded run'
58
- : a.install.npm
59
- ? 'the npm pin the installer writes, `' + npmSpec(a) + '`'
60
- : a.id === 'ollama'
61
- ? 'the pinned image the level 3 box runs, `' + IMAGES.ollama + '`'
62
- : "the maintainer's own install";
63
- md += `| \`${a.bin}\` | ${a.vendor} | ${a.builtAgainst} | ${proof} |\n`;
64
- }
65
- md += `\nGenerated from \`src/catalog.js\` by \`npm run gen:catalog\`; \`npm test\` fails if this table and the catalog disagree. Fixtures were captured ${fx.capturedAt}.\n\n` + VENDOR_TABLE_END;
66
- return md;
67
- }
68
-
69
- export function readmeWithVendorTable(current) {
70
- const a = current.indexOf(VENDOR_TABLE_START);
71
- const b = current.indexOf(VENDOR_TABLE_END);
72
- if (a === -1 || b === -1) throw new Error('README.md has no vendor-table markers');
73
- return current.slice(0, a) + vendorTableMarkdown() + current.slice(b + VENDOR_TABLE_END.length);
74
- }
75
-
76
- if (process.argv[1] && process.argv[1].endsWith('gen-catalog.js')) {
77
- writeFileSync(new URL('../docs/catalog.md', import.meta.url), catalogMarkdown());
78
- const readmeUrl = new URL('../README.md', import.meta.url);
79
- writeFileSync(readmeUrl, readmeWithVendorTable(readFileSync(readmeUrl, 'utf8')));
80
- console.log('docs/catalog.md and the README vendor table regenerated');
81
- }
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env node
2
- // Regenerates the Claude Code plugin bundle under plugin/ from the installer's
3
- // templates (src/plugin.js has the plan). The test suite checks the committed
4
- // bundle matches, so an agent or hook edited in templates/ cannot ship to npm
5
- // users and silently not to plugin users.
6
- import { writeFileSync, mkdirSync } from 'node:fs';
7
- import { join, dirname } from 'node:path';
8
- import { planPluginFiles, PLUGIN_DIR } from '../src/plugin.js';
9
-
10
- const files = planPluginFiles();
11
- for (const f of files) {
12
- const abs = join(PLUGIN_DIR, ...f.rel.split('/'));
13
- mkdirSync(dirname(abs), { recursive: true });
14
- writeFileSync(abs, f.content);
15
- }
16
- console.log('plugin/ regenerated: ' + files.length + ' files');
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Re-records docs/demo.gif from the PUBLISHED package, so the frames are the
3
- # program's own output and anyone can reproduce them.
4
- #
5
- # bash scripts/record-demo.sh # records the current published version
6
- # bash scripts/record-demo.sh 0.1.27 # pins a version
7
- #
8
- # Needs asciinema (the recorder) and agg (cast to GIF), both from the asciinema
9
- # project: brew install asciinema agg
10
- set -euo pipefail
11
-
12
- VERSION="${1:-latest}"
13
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
14
- OUT="$REPO_ROOT/docs/demo.gif"
15
- WORK="$(mktemp -d)"
16
- trap 'rm -rf "$WORK"' EXIT
17
-
18
- for tool in asciinema agg npm; do
19
- command -v "$tool" >/dev/null || { echo "missing: $tool (brew install asciinema agg)" >&2; exit 1; }
20
- done
21
-
22
- # Installed locally first, so the recorded npx call resolves from node_modules
23
- # and never stops on npx's own "Ok to proceed?" prompt mid-take.
24
- cd "$WORK"
25
- npm install --silent "model-orchestrator@$VERSION" >/dev/null
26
-
27
- cat > "$WORK/take.sh" <<'TAKE'
28
- #!/bin/bash
29
- cd "$(dirname "$0")"
30
- printf '~/my-app $ '
31
- sleep 0.8
32
- cmd='npx model-orchestrator --yes --level 2 --ais claude-code,codex,grok --primary claude-code --dry'
33
- for (( i=0; i<${#cmd}; i++ )); do printf '%s' "${cmd:$i:1}"; sleep 0.022; done
34
- sleep 0.6; printf '\n'
35
- npx model-orchestrator --yes --level 2 --ais claude-code,codex,grok --primary claude-code --dry
36
- printf '~/my-app $ '
37
- sleep 2.5
38
- TAKE
39
- chmod +x "$WORK/take.sh"
40
-
41
- asciinema rec --cols 108 --rows 34 --overwrite --command "$WORK/take.sh" "$WORK/demo.cast"
42
- agg --theme monokai --font-size 16 --speed 1.3 --idle-time-limit 1.2 --last-frame-duration 3 \
43
- "$WORK/demo.cast" "$OUT"
44
-
45
- echo "wrote $OUT ($(wc -c < "$OUT") bytes)"
@@ -1,56 +0,0 @@
1
- # Task Bundle: the brief every delegation carries
2
-
3
- A subagent, a second CLI, or a fresh chat window may hold none of the rules your main session is holding, and that is the default to assume. One exception: a Claude Code subagent loads the project's CLAUDE.md hierarchy at start, so it already carries the standing rules, just not this task's scope. Either way, it cannot see this task's conventions and will read an unspecified edge as an open one.
4
-
5
- > A delegate gets an approved, bounded brief. Absence is not permission.
6
-
7
- A brief is under-specified if it is missing **purpose**, **denied actions**, **report contract**, or **exit parameters**.
8
-
9
- ## Template
10
-
11
- Copy this into the delegate's prompt. Delete nothing; write `none` where a field is genuinely empty, so a reader can tell "nothing denied" from "nobody thought about it".
12
-
13
- ```markdown
14
- ## Task bundle
15
-
16
- **Purpose.** <one sentence: what this task is for, and why>
17
- **Task class.** <read_only | draft_only | mutating> (draft_only = produce, do not apply)
18
-
19
- **Granted scope.**
20
- - <paths, globs, topics, or record sets this brief covers>
21
- - Anything outside this list is out of scope. Do not widen it on your own judgment.
22
-
23
- **Capabilities.** <the actions you MAY take: read, search, write to <path>, run <cmd>>
24
-
25
- **Denied actions.** <explicit list: do not commit, push, deploy, delete, send, publish, close a ticket...>
26
- - Anything absent from Capabilities is denied. Absence is not permission.
27
-
28
- **Conventions you do not have.** <restate every house rule this task needs; even a delegate that loaded the standing rules still needs this task's scope, and a second CLI or a fresh chat window may hold none of it>
29
-
30
- **Report contract.** Return: <exactly what to hand back>. State plainly what you did NOT do
31
- and anything you could not verify. "Unverified" is an acceptable answer; a confident guess is not.
32
-
33
- **Exit parameters.** <at least one bound: a wall-clock ceiling, a work ceiling ("at most 20 files"),
34
- or a stop condition. Plus the partial-result clause: if you hit a bound, report what you have and
35
- name what you did not cover. Never keep going past a bound, never return nothing.>
36
- ```
37
-
38
- ## When to skip it
39
-
40
- A one-line read-only lookup can say so outright:
41
-
42
- ```
43
- Task bundle: none (one-line lookup, read-only, no artifact)
44
- ```
45
-
46
- The reason is required. A bare `none` is indistinguishable from "forgot".
47
-
48
- Never skip it for anything touching secrets, deletion, bulk mutation, deploys, or someone else's data. Better: do not delegate those at all.
49
-
50
- ## Field notes
51
-
52
- - **Purpose** is what makes the rest checkable. "Fix the thing" has no edge to exceed.
53
- - **Task class** is the cheapest safety win. Most delegation wants `read_only` or `draft_only`.
54
- - **Denied actions** must be written even when they feel obvious. Nothing is obvious to a delegate with no context.
55
- - **Report contract** is what turns a result into evidence rather than a claim.
56
- - **Exit parameters** exist because a delegate that never returns is more expensive than one that returns wrong. A wrong answer is corrected next turn; a hang burns the session while looking like progress. Bound your own shell calls the same way (pass a timeout; scope recursive searches away from `.git`, `node_modules`, build output).