ouro.bot 0.1.0-alpha.78 → 0.1.0-alpha.80

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 (2) hide show
  1. package/index.js +160 -11
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,12 +1,161 @@
1
1
  #!/usr/bin/env node
2
- // Thin wrapper: always delegates to the latest @ouro.bot/cli@alpha.
3
- // This avoids stale npx caching every invocation resolves the newest CLI.
4
- const { spawn } = require("child_process");
5
- const child = spawn(
6
- "npx",
7
- ["--yes", "@ouro.bot/cli@alpha"].concat(process.argv.slice(2)),
8
- { stdio: "inherit", shell: true }
9
- );
10
- child.on("close", (code) => {
11
- process.exitCode = code ?? 1;
12
- });
2
+ // Bootstrap installer for @ouro.bot/cli.
3
+ // Installs into ~/.ouro-cli/ versioned layout, creates wrapper, adds to PATH.
4
+ // After first run, the wrapper at ~/.ouro-cli/bin/ouro handles everything.
5
+ "use strict";
6
+
7
+ const { execSync, execFileSync } = require("child_process");
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+ const os = require("os");
11
+
12
+ const OURO_HOME = path.join(os.homedir(), ".ouro-cli");
13
+ const VERSIONS_DIR = path.join(OURO_HOME, "versions");
14
+ const BIN_DIR = path.join(OURO_HOME, "bin");
15
+ const CURRENT_LINK = path.join(OURO_HOME, "CurrentVersion");
16
+ const WRAPPER_PATH = path.join(BIN_DIR, "ouro");
17
+ const ENTRY_RELPATH = "node_modules/@ouro.bot/cli/dist/heart/daemon/ouro-entry.js";
18
+
19
+ const WRAPPER_SCRIPT = `#!/bin/sh
20
+ ENTRY="$HOME/.ouro-cli/CurrentVersion/${ENTRY_RELPATH}"
21
+ if [ ! -e "$ENTRY" ]; then
22
+ echo "ouro not installed. Run: npx ouro.bot" >&2
23
+ exit 1
24
+ fi
25
+ exec node "$ENTRY" "$@"
26
+ `;
27
+
28
+ function resolveLatestVersion() {
29
+ try {
30
+ const raw = execSync("npm view @ouro.bot/cli@alpha version", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] });
31
+ return raw.trim();
32
+ } catch {
33
+ console.error("failed to resolve latest @ouro.bot/cli version from npm registry.");
34
+ process.exit(1);
35
+ }
36
+ }
37
+
38
+ function getCurrentVersion() {
39
+ try {
40
+ const target = fs.readlinkSync(CURRENT_LINK);
41
+ return path.basename(target);
42
+ } catch {
43
+ return null;
44
+ }
45
+ }
46
+
47
+ function ensureLayout() {
48
+ fs.mkdirSync(OURO_HOME, { recursive: true });
49
+ fs.mkdirSync(BIN_DIR, { recursive: true });
50
+ fs.mkdirSync(VERSIONS_DIR, { recursive: true });
51
+ }
52
+
53
+ function installVersion(version) {
54
+ const versionDir = path.join(VERSIONS_DIR, version);
55
+ if (fs.existsSync(path.join(versionDir, ENTRY_RELPATH))) {
56
+ return; // Already installed
57
+ }
58
+ console.error(`installing @ouro.bot/cli@${version}...`);
59
+ fs.mkdirSync(versionDir, { recursive: true });
60
+ execSync(`npm install --prefix "${versionDir}" @ouro.bot/cli@${version}`, { stdio: "pipe" });
61
+ }
62
+
63
+ function activateVersion(version) {
64
+ const previousVersion = getCurrentVersion();
65
+ const newTarget = path.join(VERSIONS_DIR, version);
66
+ const previousLink = path.join(OURO_HOME, "previous");
67
+
68
+ // Update previous symlink
69
+ if (previousVersion) {
70
+ try { fs.unlinkSync(previousLink); } catch { /* may not exist */ }
71
+ fs.symlinkSync(path.join(VERSIONS_DIR, previousVersion), previousLink);
72
+ }
73
+
74
+ // Update CurrentVersion symlink
75
+ try { fs.unlinkSync(CURRENT_LINK); } catch { /* may not exist */ }
76
+ fs.symlinkSync(newTarget, CURRENT_LINK);
77
+ }
78
+
79
+ function installWrapper() {
80
+ const existing = fs.existsSync(WRAPPER_PATH) ? fs.readFileSync(WRAPPER_PATH, "utf-8") : "";
81
+ if (existing === WRAPPER_SCRIPT) return;
82
+ fs.writeFileSync(WRAPPER_PATH, WRAPPER_SCRIPT, { mode: 0o755 });
83
+ }
84
+
85
+ function addToPath() {
86
+ const shell = process.env.SHELL;
87
+ if (!shell) return;
88
+ const base = path.basename(shell);
89
+ let profilePath;
90
+ if (base === "zsh") profilePath = path.join(os.homedir(), ".zshrc");
91
+ else if (base === "bash") profilePath = path.join(os.homedir(), ".bash_profile");
92
+ else if (base === "fish") profilePath = path.join(os.homedir(), ".config", "fish", "config.fish");
93
+ else return;
94
+
95
+ try {
96
+ const content = fs.existsSync(profilePath) ? fs.readFileSync(profilePath, "utf-8") : "";
97
+ if (content.includes(BIN_DIR)) return; // Already in PATH
98
+ const line = base === "fish"
99
+ ? `\n# Added by ouro\nset -gx PATH ${BIN_DIR} $PATH\n`
100
+ : `\n# Added by ouro\nexport PATH="${BIN_DIR}:$PATH"\n`;
101
+ fs.appendFileSync(profilePath, line);
102
+ } catch {
103
+ // Best effort
104
+ }
105
+ }
106
+
107
+ function cleanupOldWrapper() {
108
+ const oldWrapper = path.join(os.homedir(), ".local", "bin", "ouro");
109
+ const oldBinDir = path.join(os.homedir(), ".local", "bin");
110
+ try {
111
+ if (fs.existsSync(oldWrapper)) {
112
+ fs.unlinkSync(oldWrapper);
113
+ // Remove directory if empty
114
+ try {
115
+ const entries = fs.readdirSync(oldBinDir);
116
+ if (entries.length === 0) fs.rmdirSync(oldBinDir);
117
+ } catch { /* best effort */ }
118
+ }
119
+ } catch { /* best effort */ }
120
+ }
121
+
122
+ // ── Main ──
123
+
124
+ const previousVersion = getCurrentVersion();
125
+ const latestVersion = resolveLatestVersion();
126
+
127
+ ensureLayout();
128
+ installVersion(latestVersion);
129
+
130
+ if (previousVersion !== latestVersion) {
131
+ activateVersion(latestVersion);
132
+ if (previousVersion) {
133
+ console.error(`ouro updated to ${latestVersion} (was ${previousVersion})`);
134
+ } else {
135
+ console.error(`ouro installed ${latestVersion}`);
136
+ }
137
+ }
138
+
139
+ installWrapper();
140
+ addToPath();
141
+ cleanupOldWrapper();
142
+
143
+ // Run the CLI with the original args
144
+ const entry = path.join(CURRENT_LINK, ENTRY_RELPATH);
145
+ if (!fs.existsSync(entry)) {
146
+ console.error(`installation failed: ${entry} not found`);
147
+ process.exit(1);
148
+ }
149
+
150
+ if (previousVersion === null) {
151
+ // First install — tell user about PATH
152
+ console.error(`\nouro is ready! Open a new terminal or run: source ~/.zshrc`);
153
+ console.error(`Then run: ouro`);
154
+ } else {
155
+ // Pass through to CLI
156
+ try {
157
+ execFileSync("node", [entry, ...process.argv.slice(2)], { stdio: "inherit" });
158
+ } catch (err) {
159
+ process.exitCode = err.status ?? 1;
160
+ }
161
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ouro.bot",
3
- "version": "0.1.0-alpha.78",
3
+ "version": "0.1.0-alpha.80",
4
4
  "description": "npx-friendly wrapper for @ouro.bot/cli",
5
5
  "bin": {
6
6
  "ouro.bot": "index.js"