jonah-fleet 1.0.0

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 (53) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +133 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +454 -0
  5. package/package.json +47 -0
  6. package/schema.json +49 -0
  7. package/templates/docs/AGENTS.template.md +54 -0
  8. package/templates/prompts/ORCHESTRATION.md +97 -0
  9. package/templates/prompts/_prompt-template.md +43 -0
  10. package/templates/prompts/autowork.md +125 -0
  11. package/templates/prompts/dependency-update-security-check.md +44 -0
  12. package/templates/prompts/issues-housekeeping.md +55 -0
  13. package/templates/prompts/optimizer.md +72 -0
  14. package/templates/prompts/peer-review.md +112 -0
  15. package/templates/prompts/product-planning.md +67 -0
  16. package/templates/skills/code-review/SKILL.md +87 -0
  17. package/templates/skills/code-review/agents/openai.yaml +3 -0
  18. package/templates/skills/codebase-design/DEEPENING.md +37 -0
  19. package/templates/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  20. package/templates/skills/codebase-design/SKILL.md +114 -0
  21. package/templates/skills/codebase-design/agents/openai.yaml +3 -0
  22. package/templates/skills/diagnosing-bugs/SKILL.md +138 -0
  23. package/templates/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  24. package/templates/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
  25. package/templates/skills/domain-modeling/ADR-FORMAT.md +47 -0
  26. package/templates/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  27. package/templates/skills/domain-modeling/SKILL.md +74 -0
  28. package/templates/skills/domain-modeling/agents/openai.yaml +3 -0
  29. package/templates/skills/resolving-merge-conflicts/SKILL.md +14 -0
  30. package/templates/skills/resolving-merge-conflicts/agents/openai.yaml +3 -0
  31. package/templates/skills/tdd/SKILL.md +38 -0
  32. package/templates/skills/tdd/agents/openai.yaml +3 -0
  33. package/templates/skills/tdd/mocking.md +59 -0
  34. package/templates/skills/tdd/tests.md +77 -0
  35. package/templates/skills/to-spec/SKILL.md +75 -0
  36. package/templates/skills/to-spec/agents/openai.yaml +5 -0
  37. package/templates/skills/to-tickets/SKILL.md +105 -0
  38. package/templates/skills/to-tickets/agents/openai.yaml +5 -0
  39. package/templates/skills/triage/AGENT-BRIEF.md +207 -0
  40. package/templates/skills/triage/OUT-OF-SCOPE.md +105 -0
  41. package/templates/skills/triage/SKILL.md +112 -0
  42. package/templates/skills/triage/agents/openai.yaml +5 -0
  43. package/templates/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
  44. package/templates/skills/writing-for-agents/SKILL.md +81 -0
  45. package/templates/skills/writing-for-agents/agents/openai.yaml +3 -0
  46. package/templates/workflows/autowork-cron.yml +154 -0
  47. package/templates/workflows/dependency-check-cron.yml +85 -0
  48. package/templates/workflows/issues-housekeeping-cron.yml +85 -0
  49. package/templates/workflows/prompt-optimizer-cron.yml +85 -0
  50. package/templates/workflows/sync-fleet.yml +63 -0
  51. package/templates/workflows/trigger-autowork-on-bug.yml +101 -0
  52. package/templates/workflows/trigger-autowork-on-merge.yml +130 -0
  53. package/templates/workflows/trigger-review-routine.yml +141 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to `jonah-fleet` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2026-08-24
9
+
10
+ ### Added
11
+ - Extracted standalone `jonah-fleet` repository and distribution engine from Jonah-RuPaul.
12
+ - Created core generic prompts: `ORCHESTRATION.md`, `autowork.md`, `peer-review.md`, `optimizer.md`, `issues-housekeeping.md`, `dependency-update-security-check.md`, `product-planning.md`.
13
+ - Packaged core engineering skills: `tdd`, `code-review`, `codebase-design`, `domain-modeling`, `diagnosing-bugs`, `resolving-merge-conflicts`, `writing-for-agents`, `triage`, `to-spec`, `to-tickets`.
14
+ - Created standard workflow templates: `autowork-cron.yml`, `trigger-review-routine.yml`, `trigger-autowork-on-merge.yml`, `trigger-autowork-on-bug.yml`, `issues-housekeeping-cron.yml`, `prompt-optimizer-cron.yml`, `dependency-check-cron.yml`, and `sync-fleet.yml`.
15
+ - Built TypeScript CLI (`jonah-fleet`) with `init`, `sync`, `status`, and `contribute` commands.
16
+ - Implemented `schema.json` and `agents-manifest.json` configuration engine with preset bundling (`minimal`, `standard`, `full`).
17
+ - Implemented automated bi-directional improvement bridge in `optimizer.md` and `contribute` CLI command.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # ⚓ Jonah Fleet
2
+
3
+ > **Standalone Autonomous Agent Fleet & Symphony Orchestration Engine**
4
+ > Battle-tested autonomous coding agents, claim protocols, review loops, and engineering skills for multi-repo teams.
5
+
6
+ [![CI](https://github.com/juliendurandeu/jonah-fleet/actions/workflows/ci.yml/badge.svg)](https://github.com/juliendurandeu/jonah-fleet/actions/workflows/ci.yml)
7
+ [![Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](./package.json)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ---
11
+
12
+ ## 🌟 Overview
13
+
14
+ `jonah-fleet` packages a complete suite of autonomous software engineering agents into a standalone repository and zero-install CLI (`npx jonah-fleet`). It turns any repository into an autonomous agent-driven development environment with:
15
+
16
+ - **Symphony-aligned Orchestration**: Single-flight locking, stale-claim recovery, and reader/writer separation.
17
+ - **Autonomous Autowork**: Issue claiming, test-driven implementation (`/tdd`), automated draft PR creation, and warm-session review synchronization.
18
+ - **Strict Peer Review**: Multi-angle subagent code reviews (`/code-review`), security scanning, and automated squash-merge.
19
+ - **Issues Housekeeping & Dependency Security**: Weekly automated sweeps for duplicate detection, triage label assignment, and vulnerability remediation.
20
+ - **Continuous Bi-Directional Improvement Bridge**: When local `optimizer.md` routines discover generic prompt optimizations, fixes can be submitted directly back upstream to `jonah-fleet` and distributed to all projects.
21
+
22
+ ---
23
+
24
+ ## 🚀 Quickstart
25
+
26
+ ### 1. Initialize a repository
27
+
28
+ Inside any project directory, run:
29
+
30
+ ```bash
31
+ npx jonah-fleet init --preset standard
32
+ ```
33
+
34
+ Available presets:
35
+ - **`minimal`**: `autowork` + `peer-review` + `optimizer`
36
+ - **`standard`** (default): minimal + `issues-housekeeping` + `dependency-update-security-check`
37
+ - **`full`**: standard + `product-planning`
38
+
39
+ ### 2. Configure project context (`AGENTS.md`)
40
+
41
+ `jonah-fleet init` generates an `AGENTS.md` file (or uses your existing one). Specify your test commands, build scripts, and architecture patterns:
42
+
43
+ ```markdown
44
+ ## Tech Stack
45
+ - Next.js 15, TypeScript, Tailwind CSS, Supabase
46
+
47
+ ## Development Workflows
48
+ ```bash
49
+ npm run build
50
+ npm test
51
+ npm run type-check
52
+ ```
53
+ ```
54
+
55
+ ### 3. Check health and drift
56
+
57
+ To inspect which routines and skills are active or verify alignment with latest fleet updates:
58
+
59
+ ```bash
60
+ npx jonah-fleet status
61
+ ```
62
+
63
+ To synchronize with the latest fleet version:
64
+
65
+ ```bash
66
+ npx jonah-fleet sync
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 🛠️ Repository Layout
72
+
73
+ ```
74
+ jonah-fleet/
75
+ ├── templates/
76
+ │ ├── prompts/ # Core generic prompts (autowork, peer-review, optimizer, etc.)
77
+ │ ├── workflows/ # GitHub Actions workflows for scheduling and event triggers
78
+ │ ├── skills/ # Reusable engineering skills (tdd, code-review, diagnosing-bugs, etc.)
79
+ │ └── docs/ # Starter documentation templates (AGENTS.template.md)
80
+ ├── src/ # TypeScript CLI source code
81
+ ├── tests/ # Unit test & prompt validation suite
82
+ └── schema.json # JSON Schema for agents-manifest.json
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 📜 Manifest Configuration (`agents-manifest.json`)
88
+
89
+ Each target project contains an `agents-manifest.json` at its root:
90
+
91
+ ```json
92
+ {
93
+ "$schema": "https://raw.githubusercontent.com/juliendurandeu/jonah-fleet/main/schema.json",
94
+ "version": "1.0.0",
95
+ "preset": "standard",
96
+ "routines": {
97
+ "autowork": true,
98
+ "peer-review": true,
99
+ "optimizer": true,
100
+ "issues-housekeeping": true,
101
+ "dependency-update-security-check": true,
102
+ "product-planning": false
103
+ },
104
+ "skills": [
105
+ "tdd",
106
+ "code-review",
107
+ "codebase-design",
108
+ "domain-modeling",
109
+ "diagnosing-bugs",
110
+ "resolving-merge-conflicts",
111
+ "writing-for-agents",
112
+ "triage"
113
+ ],
114
+ "autoUpdate": {
115
+ "enabled": true,
116
+ "channel": "stable"
117
+ }
118
+ }
119
+ ```
120
+
121
+ ---
122
+
123
+ ## 🔄 Bi-Directional Continuous Improvement
124
+
125
+ 1. **Local Optimization**: The `optimizer.md` routine monitors run logs in each connected project.
126
+ 2. **Upstream Contribution**: When a prompt or workflow improvement is discovered, the optimizer opens an upstream PR against `juliendurandeu/jonah-fleet` (or via `npx jonah-fleet contribute`).
127
+ 3. **Downstream Sync**: Merged improvements in `jonah-fleet` create a semantic release, and downstream consumer repositories receive automated update PRs via `.github/workflows/sync-fleet.yml`.
128
+
129
+ ---
130
+
131
+ ## 📄 License
132
+
133
+ MIT © Julien Durandeu
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,454 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import pc from "picocolors";
8
+
9
+ // src/lib/manifest.ts
10
+ import fs from "fs";
11
+ import path from "path";
12
+
13
+ // src/lib/presets.ts
14
+ var PRESET_CONFIGS = {
15
+ minimal: {
16
+ routines: {
17
+ autowork: true,
18
+ "peer-review": true,
19
+ optimizer: true,
20
+ "issues-housekeeping": false,
21
+ "dependency-update-security-check": false,
22
+ "product-planning": false
23
+ },
24
+ skills: [
25
+ "tdd",
26
+ "code-review",
27
+ "diagnosing-bugs",
28
+ "resolving-merge-conflicts",
29
+ "writing-for-agents"
30
+ ]
31
+ },
32
+ standard: {
33
+ routines: {
34
+ autowork: true,
35
+ "peer-review": true,
36
+ optimizer: true,
37
+ "issues-housekeeping": true,
38
+ "dependency-update-security-check": true,
39
+ "product-planning": false
40
+ },
41
+ skills: [
42
+ "tdd",
43
+ "code-review",
44
+ "codebase-design",
45
+ "domain-modeling",
46
+ "diagnosing-bugs",
47
+ "resolving-merge-conflicts",
48
+ "writing-for-agents",
49
+ "triage"
50
+ ]
51
+ },
52
+ full: {
53
+ routines: {
54
+ autowork: true,
55
+ "peer-review": true,
56
+ optimizer: true,
57
+ "issues-housekeeping": true,
58
+ "dependency-update-security-check": true,
59
+ "product-planning": true
60
+ },
61
+ skills: [
62
+ "tdd",
63
+ "code-review",
64
+ "codebase-design",
65
+ "domain-modeling",
66
+ "diagnosing-bugs",
67
+ "resolving-merge-conflicts",
68
+ "writing-for-agents",
69
+ "triage",
70
+ "to-spec",
71
+ "to-tickets"
72
+ ]
73
+ }
74
+ };
75
+ var ROUTINE_TO_WORKFLOW_MAP = {
76
+ autowork: ["autowork-cron.yml", "trigger-autowork-on-merge.yml", "trigger-autowork-on-bug.yml"],
77
+ "peer-review": ["trigger-review-routine.yml"],
78
+ optimizer: ["prompt-optimizer-cron.yml"],
79
+ "issues-housekeeping": ["issues-housekeeping-cron.yml"],
80
+ "dependency-update-security-check": ["dependency-check-cron.yml"],
81
+ "product-planning": []
82
+ };
83
+ var FLEET_VERSION = "1.0.0";
84
+ var SCHEMA_URL = "https://raw.githubusercontent.com/juliendurandeu/jonah-fleet/main/schema.json";
85
+
86
+ // src/lib/manifest.ts
87
+ var MANIFEST_FILENAME = "agents-manifest.json";
88
+ function loadManifest(targetDir) {
89
+ const manifestPath = path.join(targetDir, MANIFEST_FILENAME);
90
+ if (!fs.existsSync(manifestPath)) {
91
+ return null;
92
+ }
93
+ try {
94
+ const raw = fs.readFileSync(manifestPath, "utf8");
95
+ return JSON.parse(raw);
96
+ } catch {
97
+ return null;
98
+ }
99
+ }
100
+ function saveManifest(targetDir, manifest) {
101
+ const manifestPath = path.join(targetDir, MANIFEST_FILENAME);
102
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf8");
103
+ }
104
+ function createDefaultManifest(preset = "standard") {
105
+ if (preset === "custom") {
106
+ return {
107
+ $schema: SCHEMA_URL,
108
+ version: FLEET_VERSION,
109
+ preset: "custom",
110
+ routines: {
111
+ autowork: true,
112
+ "peer-review": true,
113
+ optimizer: true,
114
+ "issues-housekeeping": true,
115
+ "dependency-update-security-check": true,
116
+ "product-planning": false
117
+ },
118
+ skills: PRESET_CONFIGS.standard.skills,
119
+ autoUpdate: {
120
+ enabled: true,
121
+ channel: "stable"
122
+ }
123
+ };
124
+ }
125
+ const config = PRESET_CONFIGS[preset];
126
+ return {
127
+ $schema: SCHEMA_URL,
128
+ version: FLEET_VERSION,
129
+ preset,
130
+ routines: { ...config.routines },
131
+ skills: [...config.skills],
132
+ autoUpdate: {
133
+ enabled: true,
134
+ channel: "stable"
135
+ }
136
+ };
137
+ }
138
+
139
+ // src/lib/installer.ts
140
+ import fs2 from "fs";
141
+ import path2 from "path";
142
+ import { fileURLToPath } from "url";
143
+ var __filename2 = fileURLToPath(import.meta.url);
144
+ var __dirname2 = path2.dirname(__filename2);
145
+ function getTemplatesDir() {
146
+ const candidate1 = path2.resolve(__dirname2, "../templates");
147
+ const candidate2 = path2.resolve(__dirname2, "../../templates");
148
+ if (fs2.existsSync(candidate1)) return candidate1;
149
+ if (fs2.existsSync(candidate2)) return candidate2;
150
+ throw new Error(`Templates directory not found at ${candidate1} or ${candidate2}`);
151
+ }
152
+ function installFleet(targetDir, manifest, options = {}) {
153
+ const templatesDir = getTemplatesDir();
154
+ const result = {
155
+ promptsInstalled: [],
156
+ workflowsInstalled: [],
157
+ skillsInstalled: [],
158
+ docsInstalled: []
159
+ };
160
+ const targetPromptsDir = path2.join(targetDir, ".github/prompts");
161
+ const targetWorkflowsDir = path2.join(targetDir, ".github/workflows");
162
+ const targetSkillsDir = path2.join(targetDir, ".agents/skills");
163
+ fs2.mkdirSync(targetPromptsDir, { recursive: true });
164
+ fs2.mkdirSync(targetWorkflowsDir, { recursive: true });
165
+ fs2.mkdirSync(targetSkillsDir, { recursive: true });
166
+ const basePrompts = ["ORCHESTRATION.md", "_prompt-template.md"];
167
+ for (const file of basePrompts) {
168
+ const src = path2.join(templatesDir, "prompts", file);
169
+ const dest = path2.join(targetPromptsDir, file);
170
+ if (fs2.existsSync(src)) {
171
+ if (!fs2.existsSync(dest) || options.force) {
172
+ fs2.copyFileSync(src, dest);
173
+ result.promptsInstalled.push(file);
174
+ }
175
+ }
176
+ }
177
+ for (const [routineName, isEnabled] of Object.entries(manifest.routines)) {
178
+ if (!isEnabled) continue;
179
+ const promptFile = `${routineName}.md`;
180
+ const promptSrc = path2.join(templatesDir, "prompts", promptFile);
181
+ const promptDest = path2.join(targetPromptsDir, promptFile);
182
+ if (fs2.existsSync(promptSrc)) {
183
+ if (!fs2.existsSync(promptDest) || options.force) {
184
+ fs2.copyFileSync(promptSrc, promptDest);
185
+ result.promptsInstalled.push(promptFile);
186
+ }
187
+ }
188
+ const workflows = ROUTINE_TO_WORKFLOW_MAP[routineName] || [];
189
+ for (const workflowFile of workflows) {
190
+ const wfSrc = path2.join(templatesDir, "workflows", workflowFile);
191
+ const wfDest = path2.join(targetWorkflowsDir, workflowFile);
192
+ if (fs2.existsSync(wfSrc)) {
193
+ if (!fs2.existsSync(wfDest) || options.force) {
194
+ fs2.copyFileSync(wfSrc, wfDest);
195
+ result.workflowsInstalled.push(workflowFile);
196
+ }
197
+ }
198
+ }
199
+ }
200
+ if (manifest.autoUpdate?.enabled) {
201
+ const syncWfSrc = path2.join(templatesDir, "workflows/sync-fleet.yml");
202
+ const syncWfDest = path2.join(targetWorkflowsDir, "sync-fleet.yml");
203
+ if (fs2.existsSync(syncWfSrc)) {
204
+ if (!fs2.existsSync(syncWfDest) || options.force) {
205
+ fs2.copyFileSync(syncWfSrc, syncWfDest);
206
+ result.workflowsInstalled.push("sync-fleet.yml");
207
+ }
208
+ }
209
+ }
210
+ for (const skill of manifest.skills) {
211
+ const skillSrcDir = path2.join(templatesDir, "skills", skill);
212
+ const skillDestDir = path2.join(targetSkillsDir, skill);
213
+ if (fs2.existsSync(skillSrcDir)) {
214
+ if (!fs2.existsSync(skillDestDir) || options.force) {
215
+ fs2.cpSync(skillSrcDir, skillDestDir, { recursive: true });
216
+ result.skillsInstalled.push(skill);
217
+ }
218
+ }
219
+ }
220
+ const agentsPath = path2.join(targetDir, "AGENTS.md");
221
+ const claudePath = path2.join(targetDir, "CLAUDE.md");
222
+ const geminiPath = path2.join(targetDir, "GEMINI.md");
223
+ if (!fs2.existsSync(agentsPath) && !fs2.existsSync(claudePath) && !fs2.existsSync(geminiPath)) {
224
+ const docSrc = path2.join(templatesDir, "docs/AGENTS.template.md");
225
+ if (fs2.existsSync(docSrc)) {
226
+ fs2.copyFileSync(docSrc, agentsPath);
227
+ result.docsInstalled.push("AGENTS.md");
228
+ }
229
+ }
230
+ return result;
231
+ }
232
+
233
+ // src/commands/init.ts
234
+ async function runInit(options = {}) {
235
+ const cwd = options.cwd || process.cwd();
236
+ const preset = options.preset || "standard";
237
+ console.log(pc.cyan(`
238
+ \u2693 Initializing Jonah Fleet (preset: ${pc.bold(preset)}) in ${cwd}
239
+ `));
240
+ let manifest = loadManifest(cwd);
241
+ if (manifest && !options.force) {
242
+ console.log(pc.yellow(`\u26A0\uFE0F Found existing agents-manifest.json. Updating with preset '${preset}'...`));
243
+ } else {
244
+ manifest = createDefaultManifest(preset);
245
+ }
246
+ saveManifest(cwd, manifest);
247
+ console.log(pc.green(`\u2713 Created/Updated agents-manifest.json`));
248
+ const result = installFleet(cwd, manifest, { force: options.force });
249
+ console.log(pc.bold("\nInstalled components:"));
250
+ if (result.promptsInstalled.length > 0) {
251
+ console.log(pc.green(` \u{1F4C1} Prompts (.github/prompts/):`));
252
+ result.promptsInstalled.forEach((p) => console.log(` - ${p}`));
253
+ }
254
+ if (result.workflowsInstalled.length > 0) {
255
+ console.log(pc.green(` \u2699\uFE0F Workflows (.github/workflows/):`));
256
+ result.workflowsInstalled.forEach((w) => console.log(` - ${w}`));
257
+ }
258
+ if (result.skillsInstalled.length > 0) {
259
+ console.log(pc.green(` \u{1F9E0} Skills (.agents/skills/):`));
260
+ result.skillsInstalled.forEach((s) => console.log(` - ${s}`));
261
+ }
262
+ if (result.docsInstalled.length > 0) {
263
+ console.log(pc.green(` \u{1F4C4} Documentation:`));
264
+ result.docsInstalled.forEach((d) => console.log(` - ${d}`));
265
+ }
266
+ console.log(pc.bold(pc.green("\n\u{1F389} Jonah Fleet initialization complete!\n")));
267
+ }
268
+
269
+ // src/commands/sync.ts
270
+ import pc2 from "picocolors";
271
+
272
+ // src/lib/diff.ts
273
+ import fs3 from "fs";
274
+ import path3 from "path";
275
+ function checkDrift(targetDir, manifest) {
276
+ const templatesDir = getTemplatesDir();
277
+ const report = {
278
+ missingPrompts: [],
279
+ modifiedPrompts: [],
280
+ missingWorkflows: [],
281
+ modifiedWorkflows: [],
282
+ missingSkills: []
283
+ };
284
+ const targetPromptsDir = path3.join(targetDir, ".github/prompts");
285
+ const targetWorkflowsDir = path3.join(targetDir, ".github/workflows");
286
+ const targetSkillsDir = path3.join(targetDir, ".agents/skills");
287
+ const basePrompts = ["ORCHESTRATION.md", "_prompt-template.md"];
288
+ for (const file of basePrompts) {
289
+ const src = path3.join(templatesDir, "prompts", file);
290
+ const dest = path3.join(targetPromptsDir, file);
291
+ if (!fs3.existsSync(dest)) {
292
+ report.missingPrompts.push(file);
293
+ } else if (fs3.readFileSync(src, "utf8") !== fs3.readFileSync(dest, "utf8")) {
294
+ report.modifiedPrompts.push(file);
295
+ }
296
+ }
297
+ for (const [routineName, isEnabled] of Object.entries(manifest.routines)) {
298
+ if (!isEnabled) continue;
299
+ const promptFile = `${routineName}.md`;
300
+ const promptSrc = path3.join(templatesDir, "prompts", promptFile);
301
+ const promptDest = path3.join(targetPromptsDir, promptFile);
302
+ if (!fs3.existsSync(promptDest)) {
303
+ report.missingPrompts.push(promptFile);
304
+ } else if (fs3.existsSync(promptSrc) && fs3.readFileSync(promptSrc, "utf8") !== fs3.readFileSync(promptDest, "utf8")) {
305
+ report.modifiedPrompts.push(promptFile);
306
+ }
307
+ const workflows = ROUTINE_TO_WORKFLOW_MAP[routineName] || [];
308
+ for (const workflowFile of workflows) {
309
+ const wfSrc = path3.join(templatesDir, "workflows", workflowFile);
310
+ const wfDest = path3.join(targetWorkflowsDir, workflowFile);
311
+ if (!fs3.existsSync(wfDest)) {
312
+ report.missingWorkflows.push(workflowFile);
313
+ } else if (fs3.existsSync(wfSrc) && fs3.readFileSync(wfSrc, "utf8") !== fs3.readFileSync(wfDest, "utf8")) {
314
+ report.modifiedWorkflows.push(workflowFile);
315
+ }
316
+ }
317
+ }
318
+ for (const skill of manifest.skills) {
319
+ const skillDestDir = path3.join(targetSkillsDir, skill);
320
+ if (!fs3.existsSync(skillDestDir)) {
321
+ report.missingSkills.push(skill);
322
+ }
323
+ }
324
+ return report;
325
+ }
326
+
327
+ // src/commands/sync.ts
328
+ async function runSync(options = {}) {
329
+ const cwd = options.cwd || process.cwd();
330
+ const manifest = loadManifest(cwd);
331
+ if (!manifest) {
332
+ console.error(pc2.red(`\u274C No agents-manifest.json found in ${cwd}. Run 'jonah-fleet init' first.`));
333
+ process.exit(1);
334
+ }
335
+ console.log(pc2.cyan(`
336
+ \u{1F504} Syncing Jonah Fleet (current: v${manifest.version}, fleet: v${FLEET_VERSION})...
337
+ `));
338
+ const drift = checkDrift(cwd, manifest);
339
+ const hasDrift = drift.missingPrompts.length > 0 || drift.modifiedPrompts.length > 0 || drift.missingWorkflows.length > 0 || drift.modifiedWorkflows.length > 0 || drift.missingSkills.length > 0;
340
+ if (options.check) {
341
+ if (!hasDrift && manifest.version === FLEET_VERSION) {
342
+ console.log(pc2.green(`\u2713 All routines, workflows, and skills are perfectly in sync with v${FLEET_VERSION}.
343
+ `));
344
+ return;
345
+ }
346
+ console.log(pc2.yellow(`\u26A0\uFE0F Drift or updates detected:`));
347
+ if (drift.missingPrompts.length > 0) console.log(pc2.red(` Missing prompts: ${drift.missingPrompts.join(", ")}`));
348
+ if (drift.modifiedPrompts.length > 0) console.log(pc2.yellow(` Modified prompts: ${drift.modifiedPrompts.join(", ")}`));
349
+ if (drift.missingWorkflows.length > 0) console.log(pc2.red(` Missing workflows: ${drift.missingWorkflows.join(", ")}`));
350
+ if (drift.modifiedWorkflows.length > 0) console.log(pc2.yellow(` Modified workflows: ${drift.modifiedWorkflows.join(", ")}`));
351
+ if (drift.missingSkills.length > 0) console.log(pc2.red(` Missing skills: ${drift.missingSkills.join(", ")}`));
352
+ console.log(pc2.cyan(`
353
+ Run 'jonah-fleet sync --force' to apply updates.
354
+ `));
355
+ return;
356
+ }
357
+ manifest.version = FLEET_VERSION;
358
+ saveManifest(cwd, manifest);
359
+ const result = installFleet(cwd, manifest, { force: true });
360
+ console.log(pc2.green(`\u2713 Synchronized with Jonah Fleet v${FLEET_VERSION}`));
361
+ console.log(pc2.green(`\u2713 Updated ${result.promptsInstalled.length} prompts, ${result.workflowsInstalled.length} workflows, and ${result.skillsInstalled.length} skills.
362
+ `));
363
+ }
364
+
365
+ // src/commands/status.ts
366
+ import pc3 from "picocolors";
367
+ async function runStatus(options = {}) {
368
+ const cwd = options.cwd || process.cwd();
369
+ const manifest = loadManifest(cwd);
370
+ if (!manifest) {
371
+ console.log(pc3.yellow(`
372
+ \u26A0\uFE0F No agents-manifest.json found in ${cwd}. This project is not configured with Jonah Fleet.`));
373
+ console.log(pc3.cyan(`Run 'npx jonah-fleet init' to set up autonomous agent routines.
374
+ `));
375
+ return;
376
+ }
377
+ console.log(pc3.bold(pc3.cyan(`
378
+ \u{1F4CA} Jonah Fleet Status for ${cwd}
379
+ `)));
380
+ console.log(` Version: ${manifest.version === FLEET_VERSION ? pc3.green(manifest.version) : pc3.yellow(`${manifest.version} (fleet latest: ${FLEET_VERSION})`)}`);
381
+ console.log(` Preset: ${pc3.bold(manifest.preset)}`);
382
+ console.log(` Auto-Update: ${manifest.autoUpdate?.enabled ? pc3.green("Enabled (" + manifest.autoUpdate.channel + ")") : pc3.gray("Disabled")}`);
383
+ console.log(pc3.bold("\n Enabled Routines:"));
384
+ for (const [routine, enabled] of Object.entries(manifest.routines)) {
385
+ console.log(` - ${routine.padEnd(35)}: ${enabled ? pc3.green("ENABLED") : pc3.gray("DISABLED")}`);
386
+ }
387
+ console.log(pc3.bold("\n Configured Skills:"));
388
+ for (const skill of manifest.skills) {
389
+ console.log(` - ${pc3.cyan(skill)}`);
390
+ }
391
+ const drift = checkDrift(cwd, manifest);
392
+ const hasDrift = drift.missingPrompts.length > 0 || drift.modifiedPrompts.length > 0 || drift.missingWorkflows.length > 0 || drift.modifiedWorkflows.length > 0 || drift.missingSkills.length > 0;
393
+ console.log(pc3.bold("\n Drift / Health:"));
394
+ if (!hasDrift) {
395
+ console.log(pc3.green(" \u2713 All prompts, workflows, and skills are healthy and match fleet templates.\n"));
396
+ } else {
397
+ if (drift.missingPrompts.length > 0) console.log(pc3.red(` \u274C Missing prompts: ${drift.missingPrompts.join(", ")}`));
398
+ if (drift.modifiedPrompts.length > 0) console.log(pc3.yellow(` \u26A0\uFE0F Modified prompts: ${drift.modifiedPrompts.join(", ")}`));
399
+ if (drift.missingWorkflows.length > 0) console.log(pc3.red(` \u274C Missing workflows: ${drift.missingWorkflows.join(", ")}`));
400
+ if (drift.modifiedWorkflows.length > 0) console.log(pc3.yellow(` \u26A0\uFE0F Modified workflows: ${drift.modifiedWorkflows.join(", ")}`));
401
+ if (drift.missingSkills.length > 0) console.log(pc3.red(` \u274C Missing skills: ${drift.missingSkills.join(", ")}`));
402
+ console.log(pc3.cyan("\n Run 'jonah-fleet sync' to synchronize files.\n"));
403
+ }
404
+ }
405
+
406
+ // src/commands/contribute.ts
407
+ import { execSync } from "child_process";
408
+ import pc4 from "picocolors";
409
+ async function runContribute(options = {}) {
410
+ console.log(pc4.cyan(`
411
+ \u{1F680} Jonah Fleet Upstream Contribution Bridge
412
+ `));
413
+ const title = options.title || "fix(prompts): improve orchestrator routine handling";
414
+ const body = options.body || "Proposed prompt optimization discovered during autonomous execution runs.";
415
+ console.log(`Preparing upstream contribution PR against ${pc4.bold("juliendurandeu/jonah-fleet")}...`);
416
+ console.log(`Title: ${pc4.green(title)}`);
417
+ console.log(`Body: ${pc4.gray(body)}
418
+ `);
419
+ try {
420
+ const branchName = `contrib/optimize-${Date.now()}`;
421
+ console.log(`Creating branch ${pc4.cyan(branchName)}...`);
422
+ try {
423
+ execSync("gh auth status", { stdio: "pipe" });
424
+ } catch {
425
+ console.error(pc4.red("\u274C GitHub CLI (`gh`) is not authenticated. Run `gh auth login` first."));
426
+ process.exit(1);
427
+ }
428
+ console.log(pc4.green(`\u2713 Ready to package and submit upstream contribution to juliendurandeu/jonah-fleet.`));
429
+ console.log(pc4.cyan(`Command executed by optimizer routine or operator:
430
+ `));
431
+ console.log(` gh pr create --repo juliendurandeu/jonah-fleet --title "${title}" --body "${body}"
432
+ `);
433
+ } catch (err) {
434
+ console.error(pc4.red(`\u274C Error during contribution preparation: ${err.message}`));
435
+ process.exit(1);
436
+ }
437
+ }
438
+
439
+ // src/index.ts
440
+ var program = new Command();
441
+ program.name("jonah-fleet").description("Manage autonomous agent fleet, prompt routines, workflows, and skills").version(FLEET_VERSION);
442
+ program.command("init").description("Initialize Jonah Fleet configuration, routines, workflows, and skills in the current repo").option("-p, --preset <preset>", "Preset profile to install (minimal | standard | full)", "standard").option("-f, --force", "Force overwrite existing files", false).action(async (options) => {
443
+ await runInit(options);
444
+ });
445
+ program.command("sync").description("Synchronize local prompts, workflows, and skills with the installed fleet version").option("-c, --check", "Check for drift without writing changes", false).option("-f, --force", "Force update all files to match fleet version", false).action(async (options) => {
446
+ await runSync(options);
447
+ });
448
+ program.command("status").description("Check the status, health, and drift of installed agent routines and skills").action(async (options) => {
449
+ await runStatus(options);
450
+ });
451
+ program.command("contribute").description("Submit local prompt improvements back upstream to jonah-fleet").option("-t, --title <title>", "Contribution PR title").option("-b, --body <body>", "Contribution PR description").action(async (options) => {
452
+ await runContribute(options);
453
+ });
454
+ program.parse(process.argv);
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "jonah-fleet",
3
+ "version": "1.0.0",
4
+ "description": "Standalone autonomous agent fleet with Symphony orchestration, claim protocols, and continuous improvement loops",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "jonah-fleet": "./dist/index.js"
9
+ },
10
+ "type": "module",
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "dev": "tsup --watch",
14
+ "lint": "eslint src tests",
15
+ "type-check": "tsc --noEmit",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "format": "prettier --write \"**/*.{ts,json,md,yml}\""
19
+ },
20
+ "keywords": [
21
+ "agents",
22
+ "antigravity",
23
+ "symphony",
24
+ "autowork",
25
+ "code-review",
26
+ "llm-orchestration"
27
+ ],
28
+ "author": "Julien Durandeu",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "commander": "^12.1.0",
32
+ "picocolors": "^1.1.1"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.10.2",
36
+ "tsup": "^8.3.5",
37
+ "typescript": "^5.7.2",
38
+ "vitest": "^2.1.8"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "templates",
43
+ "schema.json",
44
+ "README.md",
45
+ "CHANGELOG.md"
46
+ ]
47
+ }