@axiomantic/garden 0.1.1 → 0.1.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.
- package/README.md +50 -0
- package/SKILL.md +12 -0
- package/bin/run.js +119 -14
- package/package.json +2 -5
- package/skills/garden/SKILL.md +12 -0
- package/bin/garden +0 -0
- package/scripts/postinstall.js +0 -141
package/README.md
CHANGED
|
@@ -67,6 +67,56 @@ Garden is organized into a clean, batteries-included catalog of self-explanatory
|
|
|
67
67
|
| **[`plan-implementation`](skills/plan-implementation/SKILL.md)** | **Master Scheduling** | Authors `implementation_plan.md` defining task assignment matrices, `rhizo` distributed fencing locks, `vine` strand workflows, dynamic markdown checkboxes, harness To-Do integration, and emergent design addenda. |
|
|
68
68
|
| **[`orchestrate-swarm`](skills/orchestrate-swarm/SKILL.md)** | **Main-Chat Governor** | Governs execution from the primary chat session: dispatches tasks over Redis, tracks heartbeats, ratifies emergent design addenda, verifies Two-Key gate passes, and triggers `vine weave`. |
|
|
69
69
|
|
|
70
|
+
## Standalone Yet Designed for the Axiomantic Triad
|
|
71
|
+
|
|
72
|
+
Garden is completely standalone and can direct multi-agent dialectics, persona selection, and tmux worker swarms on any codebase.
|
|
73
|
+
|
|
74
|
+
However, Garden is designed from the ground up to pair seamlessly with **Rhizo** and **Vine**:
|
|
75
|
+
- [**Rhizo**](https://github.com/axiomantic/rhizo) (Transport & Concurrency): Inter-agent messaging bus, monotonic fencing locks, and task queues over Redis.
|
|
76
|
+
- [**Vine**](https://github.com/axiomantic/vine) (Workspaces & Verification): Sub-second APFS Copy-on-Write strands, polyglot build-cache normalization, and the Two-Key integration gate (`git merge-tree` mechanical + compiler/test suite semantic checks).
|
|
77
|
+
- **Garden** (Swarm Ceremonies): Tmux worker fleet provisioning, 3-stage empirical dialectical pump (research, architecture, audit), and master ceremonial implementation planning.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
### 1. For AI Coding Assistants (Recommended)
|
|
84
|
+
|
|
85
|
+
Install the skills globally (`-g`) across all your coding assistants (Claude Code, Antigravity, Cursor, Codex, OpenCode, etc.):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Recommended: Install the complete multi-agent triad globally
|
|
89
|
+
npx skills add -g axiomantic/rhizo
|
|
90
|
+
npx skills add -g axiomantic/vine
|
|
91
|
+
npx skills add -g axiomantic/garden
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
*(Each skill automatically self-bootstraps its native CLI binary if it is not already installed on your system).*
|
|
95
|
+
|
|
96
|
+
To install only Garden (includes the 6 Garden skills):
|
|
97
|
+
```bash
|
|
98
|
+
npx skills add -g axiomantic/garden
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 2. Standalone CLI Installation
|
|
102
|
+
|
|
103
|
+
Install the compiled CLI tools directly onto your `$PATH`:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Install all three tools:
|
|
107
|
+
npm install -g @axiomantic/rhizo @axiomantic/vine @axiomantic/garden
|
|
108
|
+
|
|
109
|
+
# Or install Garden alone:
|
|
110
|
+
npm install -g @axiomantic/garden
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 3. Repository Coordination Guide
|
|
114
|
+
|
|
115
|
+
Install the Garden multi-agent swarm coordination protocol directly into any project's `AGENTS.md`:
|
|
116
|
+
```bash
|
|
117
|
+
garden guide install
|
|
118
|
+
```
|
|
119
|
+
|
|
70
120
|
---
|
|
71
121
|
|
|
72
122
|
## System Prerequisites
|
package/SKILL.md
CHANGED
|
@@ -8,6 +8,18 @@ description: "Master entrypoint and end-to-end ceremony director for multi-agent
|
|
|
8
8
|
> **The Sovereign Orchestration Layer for Autonomous AI Swarms**
|
|
9
9
|
> *Where `rhizo` is the transport nervous system and `vine` is the workspace integrator, `garden` is the institutional intellect, deliberation crucible, and master ceremony conductor.*
|
|
10
10
|
|
|
11
|
+
## 0. Prerequisite & Automatic Bootstrapping
|
|
12
|
+
|
|
13
|
+
All swarm ceremonies require the native `garden` CLI. If `command -v garden` fails, immediately install it:
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @axiomantic/garden
|
|
16
|
+
```
|
|
17
|
+
Or install the full coordination triad:
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @axiomantic/rhizo @axiomantic/vine @axiomantic/garden
|
|
20
|
+
```
|
|
21
|
+
Once installed, `garden` is available on `$PATH` and provisions architecture-appropriate binaries automatically.
|
|
22
|
+
|
|
11
23
|
---
|
|
12
24
|
|
|
13
25
|
## 1. Architectural Architecture & Layering
|
package/bin/run.js
CHANGED
|
@@ -1,31 +1,136 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { spawnSync, execSync } = require('child_process');
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
const PKG_NAME = 'garden';
|
|
8
|
+
const REPO = `axiomantic/${PKG_NAME}`;
|
|
9
|
+
const VERSION = require('../package.json').version;
|
|
10
|
+
|
|
11
|
+
function isCompatibleBinary(filePath) {
|
|
12
|
+
try {
|
|
13
|
+
if (!fs.existsSync(filePath)) return false;
|
|
14
|
+
const stat = fs.statSync(filePath);
|
|
15
|
+
if (!stat.isFile() || stat.size < 64) return false;
|
|
16
|
+
|
|
17
|
+
const fd = fs.openSync(filePath, 'r');
|
|
18
|
+
const buf = Buffer.alloc(64);
|
|
19
|
+
fs.readSync(fd, buf, 0, 64, 0);
|
|
20
|
+
fs.closeSync(fd);
|
|
21
|
+
|
|
22
|
+
const platform = process.platform;
|
|
23
|
+
const arch = process.arch;
|
|
24
|
+
|
|
25
|
+
if (platform === 'darwin') {
|
|
26
|
+
const isMachO64 = (buf[0] === 0xcf && buf[1] === 0xfa && buf[2] === 0xed && buf[3] === 0xfe);
|
|
27
|
+
const isFatMachO = (buf[0] === 0xca && buf[1] === 0xfe && buf[2] === 0xba && buf[3] === 0xbe);
|
|
28
|
+
if (isFatMachO) return true;
|
|
29
|
+
if (!isMachO64) return false;
|
|
30
|
+
const cpuType = buf.readInt32LE(4);
|
|
31
|
+
if (arch === 'arm64' && cpuType === 0x0100000c) return true;
|
|
32
|
+
if (arch === 'x64' && cpuType === 0x01000007) return true;
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (platform === 'linux') {
|
|
37
|
+
const isELF = buf[0] === 0x7f && buf[1] === 0x45 && buf[2] === 0x4c && buf[3] === 0x46;
|
|
38
|
+
if (!isELF) return false;
|
|
39
|
+
const is64Bit = buf[4] === 2;
|
|
40
|
+
if (!is64Bit) return false;
|
|
41
|
+
const machine = buf.readUInt16LE(18);
|
|
42
|
+
if (arch === 'x64' && machine === 62) return true; // EM_X86_64
|
|
43
|
+
if (arch === 'arm64' && machine === 183) return true; // EM_AARCH64
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (platform === 'win32') {
|
|
48
|
+
return buf[0] === 0x4d && buf[1] === 0x5a;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return false;
|
|
52
|
+
} catch (_) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function resolveBinary() {
|
|
7
58
|
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
8
|
-
const arch = process.arch;
|
|
9
|
-
const platform = process.platform;
|
|
59
|
+
const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
|
|
60
|
+
const platform = process.platform === 'darwin' ? 'darwin' : (process.platform === 'linux' ? 'linux' : 'windows');
|
|
10
61
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
62
|
+
// 1. Check local/bundled locations
|
|
63
|
+
const candidates = [
|
|
64
|
+
path.join(__dirname, `${PKG_NAME}-${process.platform}-${process.arch}${ext}`),
|
|
65
|
+
path.join(__dirname, `${PKG_NAME}${ext}`),
|
|
66
|
+
path.join(__dirname, '..', 'vendor', 'bin', `${PKG_NAME}${ext}`),
|
|
67
|
+
];
|
|
14
68
|
|
|
15
|
-
|
|
16
|
-
if (
|
|
69
|
+
for (const cand of candidates) {
|
|
70
|
+
if (isCompatibleBinary(cand)) {
|
|
71
|
+
return cand;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 2. Check user cache directory (~/.cache/<pkg>/bin/<pkg>)
|
|
76
|
+
const cacheBase = process.env.XDG_CACHE_HOME || (
|
|
77
|
+
process.platform === 'win32'
|
|
78
|
+
? (process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'))
|
|
79
|
+
: path.join(os.homedir(), '.cache')
|
|
80
|
+
);
|
|
81
|
+
const cacheBinDir = path.join(cacheBase, PKG_NAME, 'bin');
|
|
82
|
+
const cachedBin = path.join(cacheBinDir, `${PKG_NAME}${ext}`);
|
|
83
|
+
|
|
84
|
+
if (isCompatibleBinary(cachedBin)) {
|
|
85
|
+
return cachedBin;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 3. Auto-download from GitHub releases
|
|
89
|
+
const assetExt = process.platform === 'win32' ? '.zip' : '.tar.gz';
|
|
90
|
+
const assetName = `${PKG_NAME}-${platform}-${arch}${assetExt}`;
|
|
91
|
+
const downloadUrl = `https://github.com/${REPO}/releases/download/v${VERSION}/${assetName}`;
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
fs.mkdirSync(cacheBinDir, { recursive: true });
|
|
95
|
+
process.stderr.write(`[@axiomantic/${PKG_NAME}] Downloading native binary for ${platform}-${arch} from GitHub Releases...\n`);
|
|
96
|
+
|
|
97
|
+
if (process.platform === 'win32') {
|
|
98
|
+
const zipPath = path.join(cacheBinDir, assetName);
|
|
99
|
+
execSync(`powershell -Command "Invoke-WebRequest -Uri '${downloadUrl}' -OutFile '${zipPath}'; Expand-Archive -Path '${zipPath}' -DestinationPath '${cacheBinDir}' -Force; Remove-Item '${zipPath}'"`, { stdio: 'inherit' });
|
|
100
|
+
} else {
|
|
101
|
+
execSync(`curl -fsSL "${downloadUrl}" | tar -xzf - -C "${cacheBinDir}"`, { stdio: 'inherit' });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (isCompatibleBinary(cachedBin)) {
|
|
105
|
+
try { fs.chmodSync(cachedBin, 0o755); } catch (_) {}
|
|
106
|
+
return cachedBin;
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
process.stderr.write(`[@axiomantic/${PKG_NAME}] Automatic download failed: ${err.message}\n`);
|
|
110
|
+
}
|
|
17
111
|
|
|
18
|
-
|
|
19
|
-
|
|
112
|
+
// 4. Fallback: compile from local source if nim is available
|
|
113
|
+
const srcFile = path.join(__dirname, '..', 'src', `${PKG_NAME}.nim`);
|
|
114
|
+
if (fs.existsSync(srcFile)) {
|
|
115
|
+
try {
|
|
116
|
+
execSync('which nim', { stdio: 'ignore' });
|
|
117
|
+
process.stderr.write(`[@axiomantic/${PKG_NAME}] Building from source via Nim compiler...\n`);
|
|
118
|
+
fs.mkdirSync(cacheBinDir, { recursive: true });
|
|
119
|
+
execSync(`nim c -d:release --opt:speed -o:"${cachedBin}" "${srcFile}"`, { stdio: 'inherit' });
|
|
120
|
+
if (isCompatibleBinary(cachedBin)) {
|
|
121
|
+
try { fs.chmodSync(cachedBin, 0o755); } catch (_) {}
|
|
122
|
+
return cachedBin;
|
|
123
|
+
}
|
|
124
|
+
} catch (_) {}
|
|
20
125
|
}
|
|
21
126
|
|
|
22
127
|
return null;
|
|
23
128
|
}
|
|
24
129
|
|
|
25
|
-
const binPath =
|
|
130
|
+
const binPath = resolveBinary();
|
|
26
131
|
if (!binPath) {
|
|
27
|
-
console.error(
|
|
28
|
-
console.error(`Please visit https://github.com/
|
|
132
|
+
console.error(`\nError: @axiomantic/${PKG_NAME} native binary not found or incompatible with ${process.platform}-${process.arch}.`);
|
|
133
|
+
console.error(`Please visit https://github.com/${REPO}/releases to download, or install Nim (https://nim-lang.org) to compile from source.`);
|
|
29
134
|
process.exit(1);
|
|
30
135
|
}
|
|
31
136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomantic/garden",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Multi-Agent Swarm Orchestration, Empirical Dialectics & Ceremonies on top of Rhizo & Vine",
|
|
5
5
|
"main": "bin/run.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,16 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"skills": "./skills",
|
|
10
10
|
"files": [
|
|
11
|
-
"bin/",
|
|
11
|
+
"bin/run.js",
|
|
12
12
|
"scripts/",
|
|
13
13
|
"skills/",
|
|
14
14
|
"SKILL.md",
|
|
15
15
|
"README.md",
|
|
16
16
|
"LICENSE"
|
|
17
17
|
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"postinstall": "node scripts/postinstall.js"
|
|
20
|
-
},
|
|
21
18
|
"publishConfig": {
|
|
22
19
|
"access": "public"
|
|
23
20
|
},
|
package/skills/garden/SKILL.md
CHANGED
|
@@ -8,6 +8,18 @@ description: "Master entrypoint and end-to-end ceremony director for multi-agent
|
|
|
8
8
|
> **The Sovereign Orchestration Layer for Autonomous AI Swarms**
|
|
9
9
|
> *Where `rhizo` is the transport nervous system and `vine` is the workspace integrator, `garden` is the institutional intellect, deliberation crucible, and master ceremony conductor.*
|
|
10
10
|
|
|
11
|
+
## 0. Prerequisite & Automatic Bootstrapping
|
|
12
|
+
|
|
13
|
+
All swarm ceremonies require the native `garden` CLI. If `command -v garden` fails, immediately install it:
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @axiomantic/garden
|
|
16
|
+
```
|
|
17
|
+
Or install the full coordination triad:
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @axiomantic/rhizo @axiomantic/vine @axiomantic/garden
|
|
20
|
+
```
|
|
21
|
+
Once installed, `garden` is available on `$PATH` and provisions architecture-appropriate binaries automatically.
|
|
22
|
+
|
|
11
23
|
---
|
|
12
24
|
|
|
13
25
|
## 1. Architectural Architecture & Layering
|
package/bin/garden
DELETED
|
Binary file
|
package/scripts/postinstall.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
const { execSync } = require('child_process');
|
|
6
|
-
|
|
7
|
-
const REPO = 'axiomantic/garden';
|
|
8
|
-
const PKG_NAME = '@axiomantic/garden';
|
|
9
|
-
const BIN_NAME = 'garden';
|
|
10
|
-
|
|
11
|
-
// 1. Ensure binary permissions and provision if missing
|
|
12
|
-
const binDir = path.join(__dirname, '..', 'bin');
|
|
13
|
-
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
14
|
-
const targetBinary = path.join(binDir, `${BIN_NAME}${ext}`);
|
|
15
|
-
|
|
16
|
-
function ensureBinary() {
|
|
17
|
-
if (fs.existsSync(targetBinary)) {
|
|
18
|
-
try {
|
|
19
|
-
fs.chmodSync(targetBinary, 0o755);
|
|
20
|
-
} catch (_) {}
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Attempt to download pre-built release binary
|
|
25
|
-
const pkgVersion = require('../package.json').version;
|
|
26
|
-
const platform = process.platform === 'darwin' ? 'darwin' : (process.platform === 'win32' ? 'windows' : 'linux');
|
|
27
|
-
const arch = process.arch === 'arm64' ? 'arm64' : 'amd64';
|
|
28
|
-
const assetName = `${BIN_NAME}-${platform}-${arch}${platform === 'windows' ? '.zip' : '.tar.gz'}`;
|
|
29
|
-
const downloadUrl = `https://github.com/${REPO}/releases/download/v${pkgVersion}/${assetName}`;
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
console.log(`[${PKG_NAME}] Downloading native binary from ${downloadUrl}...`);
|
|
33
|
-
const tempArchive = path.join(os.tmpdir(), assetName);
|
|
34
|
-
execSync(`curl -fsSL -o "${tempArchive}" "${downloadUrl}"`, { stdio: 'pipe' });
|
|
35
|
-
|
|
36
|
-
if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true });
|
|
37
|
-
|
|
38
|
-
if (platform === 'windows') {
|
|
39
|
-
execSync(`tar -xf "${tempArchive}" -C "${binDir}"`, { stdio: 'pipe' });
|
|
40
|
-
} else {
|
|
41
|
-
execSync(`tar -xzf "${tempArchive}" -C "${binDir}"`, { stdio: 'pipe' });
|
|
42
|
-
}
|
|
43
|
-
try { fs.unlinkSync(tempArchive); } catch (_) {}
|
|
44
|
-
if (fs.existsSync(targetBinary)) {
|
|
45
|
-
fs.chmodSync(targetBinary, 0o755);
|
|
46
|
-
console.log(`[${PKG_NAME}] Native binary installed successfully.`);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
} catch (_) {
|
|
50
|
-
// Release download failed or offline; check if nim is available to compile locally
|
|
51
|
-
const srcNim = path.join(__dirname, '..', 'src', `${BIN_NAME}.nim`);
|
|
52
|
-
if (fs.existsSync(srcNim)) {
|
|
53
|
-
try {
|
|
54
|
-
console.log(`[${PKG_NAME}] Compiling from source via nim...`);
|
|
55
|
-
execSync(`nim c -d:release --opt:speed -o:"${targetBinary}" "${srcNim}"`, { stdio: 'pipe' });
|
|
56
|
-
fs.chmodSync(targetBinary, 0o755);
|
|
57
|
-
console.log(`[${PKG_NAME}] Native binary compiled successfully.`);
|
|
58
|
-
return;
|
|
59
|
-
} catch (_) {}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.warn(`[${PKG_NAME}] Note: Native binary could not be downloaded or compiled automatically.`);
|
|
64
|
-
console.warn(`[${PKG_NAME}] Run 'nimble build' or visit https://github.com/${REPO}/releases to install manually.`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
ensureBinary();
|
|
68
|
-
|
|
69
|
-
// 2. Auto-equip detected coding assistants with Garden rules
|
|
70
|
-
const home = os.homedir();
|
|
71
|
-
const guideContent = `# Garden Multi-Agent Swarm & Ceremony Guide
|
|
72
|
-
|
|
73
|
-
Garden directs high-level methodology, persona deliberations, and synchronized task execution on top of Rhizo (transport) and Vine (workspace integrator).
|
|
74
|
-
|
|
75
|
-
### 0. Self-Bootstrapping Prerequisite
|
|
76
|
-
This project requires \`rhizo\`, \`vine\`, and \`garden\`. If missing, install via npm:
|
|
77
|
-
\`\`\`bash
|
|
78
|
-
npm install -g @axiomantic/rhizo @axiomantic/vine @axiomantic/garden
|
|
79
|
-
\`\`\`
|
|
80
|
-
|
|
81
|
-
### 1. Invariants & Epistemic Protocol
|
|
82
|
-
* **Zero Theatrical Dialogue**:
|
|
83
|
-
Every dialectical exchange must cite empirical evidence obtained from tool execution (file line citations, test suite runs, AST analysis, compiler output). Theatrical roleplay without tool grounding is strictly prohibited.
|
|
84
|
-
* **Single-Source Planning**:
|
|
85
|
-
All tasks, locks, and strands must be coordinated via \`implementation_plan.md\`. Dynamic progress must be tracked in lockstep with plan checkboxes (\`- [ ]\` to \`- [x]\`) and harness To-Do tracking.
|
|
86
|
-
* **Emergent Design Addendum Protocol**:
|
|
87
|
-
Workers discovering architectural discrepancies cannot unilaterally deviate from \`design.md\`. They must submit a formal \`addendum_<topic>.md\` with rationale, await Orchestrator ratification, update \`design.md\`, and refresh \`implementation_plan.md\`.
|
|
88
|
-
|
|
89
|
-
### 2. Fleet Lifecycle & Multiplexer Discipline
|
|
90
|
-
* **Tmux Multiplexing**:
|
|
91
|
-
All swarm workers run inside managed tmux panes created via \`garden launch\` or \`scripts/launch_tmux_swarm.sh\`. Never detach unmanaged background processes with \`&\` or redirect output.
|
|
92
|
-
* **Continuous Listening**:
|
|
93
|
-
Workers must keep their Rhizo listener active (\`rhizo listen <agent>\`) with zero-timeout infinite wait to prevent token thrashing.
|
|
94
|
-
|
|
95
|
-
### 3. The Two-Key Gate & Strand Weaving
|
|
96
|
-
Never weave a strand into the canonical trunk without passing both keys:
|
|
97
|
-
* **Key 1 (Mechanical)**: In-memory conflict pre-check (\`git merge-tree --write-tree\`).
|
|
98
|
-
* **Key 2 (Semantic)**: Automated compiler and test suite run inside the strand.
|
|
99
|
-
* **Weave**: \`vine weave && rhizo ack queue:<project>:tasks <task_id>\`
|
|
100
|
-
`;
|
|
101
|
-
|
|
102
|
-
function safeWrite(destDir, fileName, content) {
|
|
103
|
-
try {
|
|
104
|
-
if (!fs.existsSync(destDir)) {
|
|
105
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
106
|
-
}
|
|
107
|
-
const target = path.join(destDir, fileName);
|
|
108
|
-
fs.writeFileSync(target, content, 'utf8');
|
|
109
|
-
console.log(`[${PKG_NAME}] Provisioned rules to: ${target}`);
|
|
110
|
-
} catch (err) {
|
|
111
|
-
// Non-fatal if permissions or sandbox prevent writing
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function cleanAndInstall(destDir, oldName, newName) {
|
|
116
|
-
try {
|
|
117
|
-
const oldPath = path.join(destDir, oldName);
|
|
118
|
-
if (fs.existsSync(oldPath)) {
|
|
119
|
-
try { fs.unlinkSync(oldPath); } catch (_) {}
|
|
120
|
-
}
|
|
121
|
-
safeWrite(destDir, newName, guideContent);
|
|
122
|
-
} catch (_) {}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Claude Code
|
|
126
|
-
const claudeDir = path.join(home, '.claude');
|
|
127
|
-
if (fs.existsSync(claudeDir)) {
|
|
128
|
-
cleanAndInstall(path.join(claudeDir, 'rules'), 'agora.md', 'garden.md');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// OpenCode
|
|
132
|
-
const opencodeDir = path.join(home, '.config', 'opencode');
|
|
133
|
-
if (fs.existsSync(opencodeDir)) {
|
|
134
|
-
cleanAndInstall(path.join(opencodeDir, 'instructions'), 'agora.md', 'garden.md');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Antigravity
|
|
138
|
-
const antigravityDir = path.join(home, '.gemini', 'antigravity');
|
|
139
|
-
if (fs.existsSync(antigravityDir)) {
|
|
140
|
-
cleanAndInstall(path.join(antigravityDir, 'rules'), 'agora.md', 'garden.md');
|
|
141
|
-
}
|