@grainulation/orchard 1.0.0 → 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.
@@ -0,0 +1,25 @@
1
+ # Code of Conduct
2
+
3
+ ## Our standards
4
+
5
+ We are committed to providing a welcoming and productive environment for everyone. We expect participants to:
6
+
7
+ - Use welcoming and inclusive language
8
+ - Respect differing viewpoints and experiences
9
+ - Accept constructive criticism gracefully
10
+ - Focus on what is best for the community and the project
11
+ - Show empathy toward other participants
12
+
13
+ Unacceptable behavior includes harassment, trolling, personal attacks, and publishing others' private information without permission.
14
+
15
+ ## Scope
16
+
17
+ This code of conduct applies to all project spaces -- issues, pull requests, discussions, and any public channel where someone represents the project.
18
+
19
+ ## Enforcement
20
+
21
+ Instances of unacceptable behavior may be reported to the project maintainers. All complaints will be reviewed and investigated, and will result in a response deemed necessary and appropriate.
22
+
23
+ ## Attribution
24
+
25
+ Adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
@@ -0,0 +1,90 @@
1
+ # Contributing to Orchard
2
+
3
+ Thanks for considering contributing. Orchard is the multi-sprint planner for the grainulation ecosystem -- it tracks dependencies, assignments, and timelines across concurrent sprints.
4
+
5
+ ## Quick setup
6
+
7
+ ```bash
8
+ git clone https://github.com/grainulation/orchard.git
9
+ cd orchard
10
+ node bin/orchard.js --help
11
+ ```
12
+
13
+ No `npm install` needed -- orchard has zero dependencies.
14
+
15
+ ## How to contribute
16
+
17
+ ### Report a bug
18
+ Open an issue with:
19
+ - What you expected
20
+ - What happened instead
21
+ - Your Node version (`node --version`)
22
+ - Steps to reproduce
23
+
24
+ ### Suggest a feature
25
+ Open an issue describing the use case, not just the solution. "I need X because Y" is more useful than "add X."
26
+
27
+ ### Submit a PR
28
+ 1. Fork the repo
29
+ 2. Create a branch (`git checkout -b fix/description`)
30
+ 3. Make your changes
31
+ 4. Run the tests: `node test/basic.test.js`
32
+ 5. Commit with a clear message
33
+ 6. Open a PR
34
+
35
+ ## Architecture
36
+
37
+ ```
38
+ bin/orchard.js CLI entrypoint -- dispatches subcommands
39
+ lib/scanner.js Auto-detects active sprints in a workspace
40
+ lib/planner.js Sprint planning and scheduling logic
41
+ lib/tracker.js Progress tracking across sprints
42
+ lib/dependencies.js Cross-sprint dependency resolution
43
+ lib/conflicts.js Conflict detection between parallel sprints
44
+ lib/assignments.js Work assignment and load balancing
45
+ lib/timeline.js Timeline generation and critical path
46
+ lib/sync.js State synchronization across sprint repos
47
+ lib/export.js Export planner data to various formats
48
+ lib/dashboard.js Dashboard data aggregation
49
+ lib/server.js Local preview server (SSE, zero deps)
50
+ templates/ HTML templates (orchard-dashboard, etc.)
51
+ public/ Web UI -- multi-sprint planning dashboard
52
+ site/ Public website (orchard.grainulation.com)
53
+ test/ Node built-in test runner tests
54
+ ```
55
+
56
+ The key architectural principle: **orchard operates above individual sprints.** It scans for active wheat sprints, detects dependencies and conflicts between them, and provides a unified planning view. It reads sprint data but never modifies it directly.
57
+
58
+ ## Code style
59
+
60
+ - Zero dependencies. If you need something, write it or use Node built-ins.
61
+ - No transpilation. Ship what you write.
62
+ - ESM imports (`import`/`export`). Node 18+ required.
63
+ - Keep functions small. If a function needs a scroll, split it.
64
+ - No emojis in code, CLI output, or dashboards.
65
+
66
+ ## Testing
67
+
68
+ ```bash
69
+ node test/basic.test.js
70
+ ```
71
+
72
+ Tests use Node's built-in test runner. No test framework dependencies.
73
+
74
+ ## Commit messages
75
+
76
+ Follow the existing pattern:
77
+ ```
78
+ orchard: <what changed>
79
+ ```
80
+
81
+ Examples:
82
+ ```
83
+ orchard: add cross-sprint dependency graph
84
+ orchard: fix timeline calculation for overlapping sprints
85
+ orchard: update scanner to detect archived sprints
86
+ ```
87
+
88
+ ## License
89
+
90
+ MIT. See LICENSE for details.
package/README.md CHANGED
@@ -1,28 +1,30 @@
1
- # @grainulation/orchard
1
+ <p align="center">
2
+ <img src="site/wordmark.svg" alt="Orchard" width="400">
3
+ </p>
2
4
 
3
- > 12 sprints running. One command to see them all.
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@grainulation/orchard"><img src="https://img.shields.io/npm/v/@grainulation/orchard" alt="npm version"></a> <a href="https://www.npmjs.com/package/@grainulation/orchard"><img src="https://img.shields.io/npm/dm/@grainulation/orchard" alt="npm downloads"></a> <a href="https://github.com/grainulation/orchard/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@grainulation/orchard" alt="license"></a> <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@grainulation/orchard" alt="node"></a> <a href="https://github.com/grainulation/orchard/actions"><img src="https://github.com/grainulation/orchard/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
7
+ </p>
4
8
 
5
- **Orchard** is the multi-sprint orchestrator for [Wheat](https://github.com/grainulation/wheat) research sprints. It coordinates parallel research across teams with dependency tracking, conflict detection, and unified dashboards.
9
+ <p align="center"><strong>Multi-sprint orchestration and dependency tracking.</strong></p>
10
+
11
+ 12 sprints running. One command to see them all. Orchard coordinates parallel research across teams with dependency graphs, conflict detection, and unified dashboards.
6
12
 
7
13
  ## Install
8
14
 
9
15
  ```bash
10
- npx @grainulation/orchard status
16
+ npm install -g @grainulation/orchard
11
17
  ```
12
18
 
13
- ## What it does
19
+ Or use directly:
14
20
 
15
- - **Run multiple wheat sprints in parallel** with dependency tracking
16
- - **Sprint dependency graphs** -- "sprint B needs sprint A's results first"
17
- - **Team assignment** -- who's running which sprint
18
- - **Resource allocation** -- distribute research bandwidth
19
- - **Cross-sprint conflict detection** -- when two sprints reach opposing conclusions
20
- - **Unified status dashboard** across all active sprints
21
- - **Sprint scheduling and deadline tracking**
21
+ ```bash
22
+ npx @grainulation/orchard status
23
+ ```
22
24
 
23
25
  ## Quick start
24
26
 
25
- Create a `orchard.json` in your project root:
27
+ Create `orchard.json` in your project root:
26
28
 
27
29
  ```json
28
30
  {
@@ -50,68 +52,56 @@ Create a `orchard.json` in your project root:
50
52
  Then:
51
53
 
52
54
  ```bash
53
- # See the dependency graph
54
- orchard plan
55
-
56
- # Check status of all sprints
57
- orchard status
58
-
59
- # Assign someone to a sprint
60
- orchard assign ./sprints/data-migration carol
55
+ orchard plan # Show the dependency graph
56
+ orchard status # Check status of all sprints
57
+ orchard sync # Sync status from sprint directories
58
+ orchard dashboard # Generate unified HTML dashboard
59
+ ```
61
60
 
62
- # Sync status from sprint directories
63
- orchard sync
61
+ ## What it does
64
62
 
65
- # Generate HTML dashboard
66
- orchard dashboard
67
- ```
63
+ - **Sprint dependency graphs** -- "sprint B needs sprint A's results first"
64
+ - **Cross-sprint conflict detection** -- when two sprints reach opposing conclusions
65
+ - **Team assignment** -- who's running which sprint
66
+ - **Unified status dashboard** across all active sprints
67
+ - **Sprint scheduling and deadline tracking**
68
+ - **Topological sort** -- determines execution order, flags cycles
68
69
 
69
- ## Commands
70
+ ## CLI
70
71
 
71
72
  | Command | Description |
72
73
  |---------|-------------|
73
- | `orchard plan` | Show sprint dependency graph as ASCII |
74
+ | `orchard plan` | Show sprint dependency graph |
74
75
  | `orchard status` | Show status of all tracked sprints |
75
76
  | `orchard assign <path> <person>` | Assign a person to a sprint |
76
- | `orchard sync` | Sync sprint states from their directories |
77
+ | `orchard sync` | Sync sprint states from directories |
77
78
  | `orchard dashboard [outfile]` | Generate unified HTML dashboard |
78
- | `orchard init` | Initialize orchard.json in the current directory |
79
+ | `orchard init` | Initialize orchard.json |
79
80
  | `orchard serve` | Start the portfolio dashboard web server |
80
- | `orchard help` | Show help |
81
81
 
82
- ## orchard.json schema
83
-
84
- ```typescript
85
- {
86
- sprints: Array<{
87
- path: string; // Relative path to sprint directory
88
- question: string; // The research question
89
- depends_on: string[]; // Paths of prerequisite sprints
90
- assigned_to: string; // Person responsible
91
- deadline: string; // ISO date string
92
- status: string; // active | done | blocked | not-started
93
- }>
94
- }
95
- ```
96
-
97
- ## How it works
98
-
99
- Orchard reads `orchard.json` for the sprint graph, then scans each sprint directory for `claims.json` and `compilation.json` to determine actual state. It detects conflicts by comparing claims across sprints that share tags.
100
-
101
- ### Conflict detection
82
+ ## Conflict detection
102
83
 
103
84
  Orchard flags two types of cross-sprint conflicts:
104
85
 
105
- 1. **Opposing recommendations** -- two sprints make recommendations on the same topic that may contradict
86
+ 1. **Opposing recommendations** -- two sprints make recommendations on the same topic that contradict
106
87
  2. **Constraint-recommendation tension** -- one sprint's constraints conflict with another's recommendations
107
88
 
108
- ### Dependency tracking
89
+ ## Zero dependencies
109
90
 
110
- Sprints can declare dependencies. Orchard uses topological sorting to determine execution order and flags cycles. The `plan` command renders this as ASCII art.
91
+ Node built-in modules only.
111
92
 
112
- ## Zero dependencies
93
+ ## Part of the grainulation ecosystem
113
94
 
114
- Orchard uses only Node.js built-in modules. No npm install required.
95
+ | Tool | Role |
96
+ |------|------|
97
+ | [wheat](https://github.com/grainulation/wheat) | Research engine -- grow structured evidence |
98
+ | [farmer](https://github.com/grainulation/farmer) | Permission dashboard -- approve AI actions in real time |
99
+ | [barn](https://github.com/grainulation/barn) | Shared tools -- templates, validators, sprint detection |
100
+ | [mill](https://github.com/grainulation/mill) | Format conversion -- export to PDF, CSV, slides, 24 formats |
101
+ | [silo](https://github.com/grainulation/silo) | Knowledge storage -- reusable claim libraries and packs |
102
+ | [harvest](https://github.com/grainulation/harvest) | Analytics -- cross-sprint patterns and prediction scoring |
103
+ | **orchard** | Orchestration -- multi-sprint coordination and dependencies |
104
+ | [grainulation](https://github.com/grainulation/grainulation) | Unified CLI -- single entry point to the ecosystem |
115
105
 
116
106
  ## License
117
107
 
package/lib/server.js CHANGED
@@ -80,7 +80,7 @@ const ROUTES = [
80
80
 
81
81
  // ── Load existing CJS modules via createRequire ──────────────────────────────
82
82
 
83
- const { loadSprints: loadDashboardSprints, buildHtml, claimsPaths } = require('./dashboard.js');
83
+ const { claimsPaths } = require('./dashboard.js');
84
84
 
85
85
  // ── State ─────────────────────────────────────────────────────────────────────
86
86
 
@@ -474,38 +474,6 @@ function readBody(req) {
474
474
  });
475
475
  }
476
476
 
477
- // ── SSE live-reload injection ────────────────────────────────────────────────
478
-
479
- const SSE_SCRIPT = `
480
- <script>
481
- (function() {
482
- var es, retryCount = 0;
483
- var dot = document.getElementById('statusDot');
484
- function connect() {
485
- es = new EventSource('/events');
486
- es.addEventListener('update', function() { location.reload(); });
487
- es.onopen = function() {
488
- retryCount = 0;
489
- if (dot) dot.className = 'status-dot ok';
490
- if (window._grainSetState) window._grainSetState('idle');
491
- };
492
- es.onerror = function() {
493
- es.close();
494
- if (dot) dot.className = 'status-dot';
495
- if (window._grainSetState) window._grainSetState('orbit');
496
- var delay = Math.min(30000, 1000 * Math.pow(2, retryCount)) + Math.random() * 1000;
497
- retryCount++;
498
- setTimeout(connect, delay);
499
- };
500
- }
501
- connect();
502
- })();
503
- </script>`;
504
-
505
- function injectSSE(html) {
506
- return html.replace('</body>', SSE_SCRIPT + '\n</body>');
507
- }
508
-
509
477
  // ── HTTP server ───────────────────────────────────────────────────────────────
510
478
 
511
479
  const server = createServer(async (req, res) => {
@@ -589,21 +557,16 @@ ${ROUTES.map(r => '<tr><td><code>'+r.method+'</code></td><td><code>'+r.path+'</c
589
557
  return;
590
558
  }
591
559
 
592
- // ── Dashboard UI (template-injected) ──
560
+ // ── Dashboard UI (web app from public/) ──
593
561
  if (req.method === 'GET' && (url.pathname === '/' || url.pathname === '/index.html')) {
562
+ const indexPath = join(PUBLIC_DIR, 'index.html');
594
563
  try {
595
- const graphData = loadDashboardSprints(ROOT);
596
- if (graphData.sprints.length === 0) {
597
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
598
- res.end('<html><body style="background:#0a0e1a;color:#e2e8f0;font-family:monospace;padding:40px"><h1>No claims.json files found</h1><p>Watching for changes...</p>' + SSE_SCRIPT + '</body></html>');
599
- return;
600
- }
601
- const html = injectSSE(buildHtml(graphData));
564
+ const html = readFileSync(indexPath, 'utf8');
602
565
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
603
566
  res.end(html);
604
567
  } catch (err) {
605
568
  res.writeHead(500, { 'Content-Type': 'text/plain' });
606
- res.end('Error building dashboard: ' + err.message);
569
+ res.end('Error reading dashboard: ' + err.message);
607
570
  }
608
571
  return;
609
572
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grainulation/orchard",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Multi-sprint research orchestrator \u2014 coordinate parallel research across teams",
5
5
  "main": "lib/planner.js",
6
6
  "exports": {
@@ -20,7 +20,9 @@
20
20
  "public/",
21
21
  "templates/",
22
22
  "README.md",
23
- "LICENSE"
23
+ "LICENSE",
24
+ "CODE_OF_CONDUCT.md",
25
+ "CONTRIBUTING.md"
24
26
  ],
25
27
  "scripts": {
26
28
  "test": "node test/basic.test.js",