setclaw 1.0.1 → 1.0.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # setclaw
4
4
 
5
- **One command. All models. Every OS.**
5
+ **BOA & Quatarly setup for Claude Code & Factory**
6
6
 
7
7
  Connect [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and [Factory AI Droid](https://app.factory.ai) to [Quatarly](https://api.quatarly.cloud) — access Claude, Gemini, and GPT models with a single API key.
8
8
 
@@ -37,20 +37,19 @@ Connect [Claude Code](https://docs.anthropic.com/en/docs/claude-code) and [Facto
37
37
  | 2 | **Quatarly API key** | Format: `qua_trail_...` or `qua_...` |
38
38
  | 3 | **Factory AI** *(optional)* | See [Install Factory](#install-factory-ai-optional) below |
39
39
 
40
- ### Install & Configure — One Command
40
+ ### Install & Configure
41
41
 
42
42
  ```bash
43
43
  npm i -g setclaw
44
+ setclaw <your-quatarly-api-key>
44
45
  ```
45
46
 
46
- That's it. During installation it will:
47
+ That's it. When you run `setclaw`, it will:
47
48
 
48
49
  ```
49
50
  setclaw — Quatarly setup for Claude Code & Factory
50
51
  ─────────────────────────────────────────────────
51
52
 
52
- Enter your Quatarly API key: █
53
-
54
53
  > Adding models to Factory...
55
54
  ✔ Factory: 11 models added, 0 updated (11 total)
56
55
  ✔ Backup saved to ~/.factory/settings.json.backup
@@ -67,10 +66,17 @@ That's it. During installation it will:
67
66
  ✔ All done! Restart your terminal, then launch Claude Code.
68
67
  ```
69
68
 
70
- ### Non-Interactive Install (CI / Scripts)
69
+ You can also run without arguments to get an interactive prompt:
70
+
71
+ ```bash
72
+ setclaw
73
+ # Enter your Quatarly API key: █
74
+ ```
75
+
76
+ ### Non-Interactive (CI / Scripts)
71
77
 
72
78
  ```bash
73
- QUATARLY_API_KEY=qua_trail_your-key npm i -g setclaw
79
+ QUATARLY_API_KEY=qua_trail_your-key setclaw
74
80
  ```
75
81
 
76
82
  ---
@@ -205,7 +211,7 @@ To persist, use `[System.Environment]::SetEnvironmentVariable("VAR", "value", "U
205
211
  <details>
206
212
  <summary><b>Can I run it again with a different API key?</b></summary>
207
213
 
208
- Yes. Re-run `npm i -g setclaw` — it updates existing models and env vars without creating duplicates. A backup of your Factory settings is saved before any changes.
214
+ Yes. Just run `setclaw <new-key>` again — it updates existing models and env vars without creating duplicates. A backup of your Factory settings is saved before any changes.
209
215
 
210
216
  </details>
211
217
 
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * postinstall — If QUATARLY_API_KEY env var is set, run setup automatically.
5
+ * Otherwise, print instructions telling the user to run `setclaw`.
6
+ */
7
+
8
+ import { platform } from "os";
9
+
10
+ const apiKey = process.env.QUATARLY_API_KEY;
11
+
12
+ if (apiKey) {
13
+ // Non-interactive install: run setup directly
14
+ await import("./setup.mjs");
15
+ } else {
16
+ // Interactive install: can't prompt during npm postinstall, so guide the user
17
+ const w = (msg) => process.stderr.write(msg + "\n");
18
+ w("");
19
+ w("\x1b[1m setclaw\x1b[0m — BOA & Quatarly — installed successfully!");
20
+ w("");
21
+ w(" Run this command to configure your Quatarly API key:");
22
+ w("");
23
+ w(" \x1b[36msetclaw \x1b[33m<your-api-key>\x1b[0m");
24
+ w("");
25
+ w(" Or with an env var:");
26
+ w("");
27
+ if (platform() === "win32") {
28
+ w(' \x1b[36m$env:QUATARLY_API_KEY="your-key"; setclaw\x1b[0m');
29
+ } else {
30
+ w(" \x1b[36mQUATARLY_API_KEY=your-key setclaw\x1b[0m");
31
+ }
32
+ w("");
33
+ }
package/bin/setup.mjs CHANGED
@@ -1,55 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * setclaw postinstall runs automatically during `npm i -g setclaw`
4
+ * setclaw — BOA & Quatarly setup for Claude Code & Factory
5
5
  *
6
- * npm suppresses stdin during lifecycle scripts, so we open the
7
- * terminal directly (/dev/tty on unix, CON on windows) to prompt.
6
+ * Usage:
7
+ * setclaw <API_KEY>
8
+ * QUATARLY_API_KEY=<key> setclaw
9
+ * setclaw (prompts interactively)
8
10
  */
9
11
 
10
- import { readFileSync, writeFileSync, copyFileSync, appendFileSync, existsSync, createReadStream } from "fs";
12
+ import { readFileSync, writeFileSync, copyFileSync, appendFileSync, existsSync } from "fs";
11
13
  import { join } from "path";
12
14
  import { homedir, platform } from "os";
13
15
  import { execSync } from "child_process";
14
16
  import { createInterface } from "readline";
15
- import { Socket } from "net";
16
17
 
17
18
  // ─── Helpers ─────────────────────────────────────────────────────────
18
19
 
19
20
  function ask(question) {
20
- if (platform() === "win32") {
21
- // On Windows, npm postinstall has no usable stdin and createReadStream("CON")
22
- // resolves as a relative path. Shell out to PowerShell to read from the console.
23
- process.stderr.write(question);
24
- try {
25
- const result = execSync(
26
- 'powershell -NoProfile -Command "[Console]::In.ReadLine()"',
27
- { stdio: ["inherit", "pipe", "inherit"], encoding: "utf-8" }
28
- );
29
- return Promise.resolve((result || "").trim());
30
- } catch {
31
- return Promise.reject(
32
- new Error("Cannot read from terminal. Pass the key via: QUATARLY_API_KEY=<key> npm i -g setclaw")
33
- );
34
- }
35
- }
36
-
37
- // Unix: open /dev/tty directly to bypass npm's stdin suppression
38
- return new Promise((resolve, reject) => {
39
- let ttyIn;
40
- try {
41
- ttyIn = createReadStream("/dev/tty", { encoding: "utf-8" });
42
- } catch {
43
- reject(new Error("Cannot open terminal for input. Pass the key via: QUATARLY_API_KEY=<key> npm i -g setclaw"));
44
- return;
45
- }
46
- const rl = createInterface({ input: ttyIn, output: process.stderr, terminal: true });
21
+ const rl = createInterface({ input: process.stdin, output: process.stderr, terminal: true });
22
+ return new Promise((resolve) =>
47
23
  rl.question(question, (answer) => {
48
24
  rl.close();
49
- ttyIn.destroy();
50
25
  resolve(answer.trim());
51
- });
52
- });
26
+ })
27
+ );
53
28
  }
54
29
 
55
30
  function log(msg) {
@@ -71,13 +46,13 @@ function fail(msg) {
71
46
  // ─── Banner ──────────────────────────────────────────────────────────
72
47
 
73
48
  process.stderr.write("\n");
74
- process.stderr.write("\x1b[1m setclaw\x1b[0m — Quatarly setup for Claude Code & Factory\n");
49
+ process.stderr.write("\x1b[1m setclaw\x1b[0m — BOA & Quatarly setup for Claude Code & Factory\n");
75
50
  process.stderr.write(" ─────────────────────────────────────────────────\n");
76
51
  process.stderr.write("\n");
77
52
 
78
53
  // ─── Get API key ─────────────────────────────────────────────────────
79
54
 
80
- let apiKey = process.env.QUATARLY_API_KEY;
55
+ let apiKey = process.env.QUATARLY_API_KEY || process.argv[2];
81
56
 
82
57
  if (!apiKey) {
83
58
  try {
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "setclaw",
3
- "version": "1.0.1",
4
- "description": "One-command setup for Quatarly API models in Claude Code and Factory",
3
+ "version": "1.0.3",
4
+ "description": "BOA & Quatarly setup for Claude Code and Factory",
5
5
  "type": "module",
6
+ "bin": {
7
+ "setclaw": "./bin/setup.mjs"
8
+ },
6
9
  "scripts": {
7
- "postinstall": "node bin/setup.mjs"
10
+ "postinstall": "node bin/postinstall.mjs"
8
11
  },
9
12
  "files": [
10
13
  "bin"