canary-agent 0.1.5 → 0.1.7
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/dist/setup.cjs +98 -54
- package/package.json +1 -1
- package/dist/setup.js +0 -110
package/dist/setup.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
"use strict";
|
|
4
3
|
|
|
5
4
|
// src/setup.ts
|
|
@@ -9,44 +8,40 @@ var import_node_os = require("os");
|
|
|
9
8
|
var import_node_readline = require("readline");
|
|
10
9
|
var import_meta = {};
|
|
11
10
|
var DEFAULT_ENDPOINT = "https://canary-production-89d8.up.railway.app";
|
|
11
|
+
function parseCliArgs() {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
let apiKey = "";
|
|
14
|
+
let endpoint = "";
|
|
15
|
+
let local = false;
|
|
16
|
+
let skipSkill = false;
|
|
17
|
+
for (let i = 0; i < args.length; i++) {
|
|
18
|
+
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
19
|
+
else if (args[i].startsWith("--api-key=")) apiKey = args[i].split("=")[1];
|
|
20
|
+
else if (args[i] === "--endpoint" && args[i + 1]) endpoint = args[++i];
|
|
21
|
+
else if (args[i].startsWith("--endpoint=")) endpoint = args[i].split("=")[1];
|
|
22
|
+
else if (args[i] === "--local") local = true;
|
|
23
|
+
else if (args[i] === "--no-skill") skipSkill = true;
|
|
24
|
+
}
|
|
25
|
+
return { apiKey, endpoint, local, skipSkill, isNonInteractive: !!apiKey };
|
|
26
|
+
}
|
|
12
27
|
function ask(rl, question) {
|
|
13
28
|
return new Promise((resolve) => rl.question(question, resolve));
|
|
14
29
|
}
|
|
15
|
-
|
|
16
|
-
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
17
|
-
console.log("");
|
|
18
|
-
console.log(" Canary Agent Setup");
|
|
19
|
-
console.log(" ==================");
|
|
20
|
-
console.log("");
|
|
21
|
-
const apiKey = await ask(rl, " Enter your Canary API key (cnry_sk_...): ");
|
|
22
|
-
if (!apiKey.trim()) {
|
|
23
|
-
console.log("\n No API key provided. You can set CANARY_API_KEY env var later.");
|
|
24
|
-
}
|
|
25
|
-
const customEndpoint = await ask(
|
|
26
|
-
rl,
|
|
27
|
-
` Backend endpoint [${DEFAULT_ENDPOINT}]: `
|
|
28
|
-
);
|
|
29
|
-
const endpoint = customEndpoint.trim() || DEFAULT_ENDPOINT;
|
|
30
|
-
console.log("");
|
|
31
|
-
console.log(" Where should the MCP config be written?");
|
|
32
|
-
console.log(" 1) ~/.claude/mcp.json (global \u2014 works for all projects)");
|
|
33
|
-
console.log(" 2) .mcp.json (project-local \u2014 current directory only)");
|
|
34
|
-
console.log("");
|
|
35
|
-
const configChoice = await ask(rl, " Choice [1]: ");
|
|
30
|
+
function writeMcpConfig(apiKey, endpoint, local) {
|
|
36
31
|
const mcpConfig = {
|
|
37
32
|
mcpServers: {
|
|
38
33
|
"canary-journal": {
|
|
39
34
|
command: "npx",
|
|
40
35
|
args: ["-y", "canary-agent"],
|
|
41
36
|
env: {
|
|
42
|
-
CANARY_API_KEY: apiKey
|
|
37
|
+
CANARY_API_KEY: apiKey || "YOUR_API_KEY_HERE",
|
|
43
38
|
...endpoint !== DEFAULT_ENDPOINT ? { CANARY_ENDPOINT: endpoint } : {}
|
|
44
39
|
}
|
|
45
40
|
}
|
|
46
41
|
}
|
|
47
42
|
};
|
|
48
43
|
let configPath;
|
|
49
|
-
if (
|
|
44
|
+
if (local) {
|
|
50
45
|
configPath = (0, import_node_path.join)(process.cwd(), ".mcp.json");
|
|
51
46
|
} else {
|
|
52
47
|
const claudeDir = (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude");
|
|
@@ -68,45 +63,94 @@ async function main() {
|
|
|
68
63
|
}
|
|
69
64
|
};
|
|
70
65
|
(0, import_node_fs.writeFileSync)(configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
66
|
+
return configPath;
|
|
67
|
+
}
|
|
68
|
+
function installSkill() {
|
|
69
|
+
try {
|
|
70
|
+
const thisDir = typeof __dirname !== "undefined" ? __dirname : new URL(".", import_meta.url).pathname;
|
|
71
|
+
const pkgRoot = (0, import_node_path.join)(thisDir, "..");
|
|
72
|
+
const skillSrc = (0, import_node_path.join)(pkgRoot, "skills", "canary-feedback");
|
|
73
|
+
const claudeDir = (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude");
|
|
74
|
+
const skillDest = (0, import_node_path.join)(claudeDir, "skills", "canary-feedback");
|
|
75
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.join)(skillSrc, "SKILL.md"))) {
|
|
76
|
+
(0, import_node_fs.mkdirSync)(skillDest, { recursive: true });
|
|
77
|
+
for (const file of ["SKILL.md", "manifest.yaml", "mcp-config.json"]) {
|
|
78
|
+
const src = (0, import_node_path.join)(skillSrc, file);
|
|
79
|
+
if ((0, import_node_fs.existsSync)(src)) {
|
|
80
|
+
(0, import_node_fs.writeFileSync)((0, import_node_path.join)(skillDest, file), (0, import_node_fs.readFileSync)(src, "utf8"));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return skillDest;
|
|
84
|
+
}
|
|
85
|
+
} catch {
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
async function runInteractive() {
|
|
90
|
+
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
|
|
91
|
+
console.log("");
|
|
92
|
+
console.log(" Canary Agent Setup");
|
|
93
|
+
console.log(" ==================");
|
|
94
|
+
console.log("");
|
|
95
|
+
const apiKey = await ask(rl, " Enter your Canary API key (cnry_sk_...): ");
|
|
96
|
+
if (!apiKey.trim()) {
|
|
97
|
+
console.log("\n No API key provided. You can set CANARY_API_KEY env var later.");
|
|
98
|
+
}
|
|
99
|
+
const customEndpoint = await ask(rl, ` Backend endpoint [${DEFAULT_ENDPOINT}]: `);
|
|
100
|
+
const endpoint = customEndpoint.trim() || DEFAULT_ENDPOINT;
|
|
101
|
+
console.log("");
|
|
102
|
+
console.log(" Where should the MCP config be written?");
|
|
103
|
+
console.log(" 1) ~/.claude/mcp.json (global \u2014 works for all projects)");
|
|
104
|
+
console.log(" 2) .mcp.json (project-local \u2014 current directory only)");
|
|
105
|
+
console.log("");
|
|
106
|
+
const configChoice = await ask(rl, " Choice [1]: ");
|
|
107
|
+
const local = configChoice.trim() === "2";
|
|
108
|
+
const configPath = writeMcpConfig(apiKey.trim(), endpoint, local);
|
|
71
109
|
console.log(`
|
|
72
110
|
Wrote MCP config to: ${configPath}`);
|
|
73
111
|
console.log("");
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
console.log(` Could not install skill: ${err.message}`);
|
|
112
|
+
const doSkill = await ask(rl, " Install the canary-feedback skill for Claude Code? (Y/n): ");
|
|
113
|
+
if (doSkill.trim().toLowerCase() !== "n") {
|
|
114
|
+
const dest = installSkill();
|
|
115
|
+
if (dest) {
|
|
116
|
+
console.log(` Installed skill to: ${dest}`);
|
|
117
|
+
} else {
|
|
118
|
+
console.log(" Skill files not found in package. Skipping.");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
rl.close();
|
|
122
|
+
printNextSteps();
|
|
123
|
+
}
|
|
124
|
+
function runNonInteractive(cliArgs2) {
|
|
125
|
+
console.log("");
|
|
126
|
+
console.log(" Canary Agent Setup");
|
|
127
|
+
console.log(" ==================");
|
|
128
|
+
console.log("");
|
|
129
|
+
const endpoint = cliArgs2.endpoint || DEFAULT_ENDPOINT;
|
|
130
|
+
const configPath = writeMcpConfig(cliArgs2.apiKey, endpoint, cliArgs2.local);
|
|
131
|
+
console.log(` Wrote MCP config to: ${configPath}`);
|
|
132
|
+
if (!cliArgs2.skipSkill) {
|
|
133
|
+
const dest = installSkill();
|
|
134
|
+
if (dest) {
|
|
135
|
+
console.log(` Installed skill to: ${dest}`);
|
|
99
136
|
}
|
|
100
137
|
}
|
|
138
|
+
printNextSteps();
|
|
139
|
+
}
|
|
140
|
+
function printNextSteps() {
|
|
101
141
|
console.log("");
|
|
102
142
|
console.log(" Setup complete! Next steps:");
|
|
103
143
|
console.log(" 1. Start Claude Code in any project");
|
|
104
144
|
console.log(" 2. The canary-journal MCP server will auto-start");
|
|
105
145
|
console.log(" 3. Claude will use canary_annotate and canary_report tools automatically");
|
|
106
146
|
console.log("");
|
|
107
|
-
rl.close();
|
|
108
147
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
148
|
+
var cliArgs = parseCliArgs();
|
|
149
|
+
if (cliArgs.isNonInteractive) {
|
|
150
|
+
runNonInteractive(cliArgs);
|
|
151
|
+
} else {
|
|
152
|
+
runInteractive().catch((err) => {
|
|
153
|
+
console.error("Setup failed:", err.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
|
156
|
+
}
|
package/package.json
CHANGED
package/dist/setup.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
|
-
|
|
4
|
-
// src/setup.ts
|
|
5
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
6
|
-
import { join } from "path";
|
|
7
|
-
import { homedir } from "os";
|
|
8
|
-
import { createInterface } from "readline";
|
|
9
|
-
var DEFAULT_ENDPOINT = "https://canary-production-89d8.up.railway.app";
|
|
10
|
-
function ask(rl, question) {
|
|
11
|
-
return new Promise((resolve) => rl.question(question, resolve));
|
|
12
|
-
}
|
|
13
|
-
async function main() {
|
|
14
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
15
|
-
console.log("");
|
|
16
|
-
console.log(" Canary Agent Setup");
|
|
17
|
-
console.log(" ==================");
|
|
18
|
-
console.log("");
|
|
19
|
-
const apiKey = await ask(rl, " Enter your Canary API key (cnry_sk_...): ");
|
|
20
|
-
if (!apiKey.trim()) {
|
|
21
|
-
console.log("\n No API key provided. You can set CANARY_API_KEY env var later.");
|
|
22
|
-
}
|
|
23
|
-
const customEndpoint = await ask(
|
|
24
|
-
rl,
|
|
25
|
-
` Backend endpoint [${DEFAULT_ENDPOINT}]: `
|
|
26
|
-
);
|
|
27
|
-
const endpoint = customEndpoint.trim() || DEFAULT_ENDPOINT;
|
|
28
|
-
console.log("");
|
|
29
|
-
console.log(" Where should the MCP config be written?");
|
|
30
|
-
console.log(" 1) ~/.claude/mcp.json (global \u2014 works for all projects)");
|
|
31
|
-
console.log(" 2) .mcp.json (project-local \u2014 current directory only)");
|
|
32
|
-
console.log("");
|
|
33
|
-
const configChoice = await ask(rl, " Choice [1]: ");
|
|
34
|
-
const mcpConfig = {
|
|
35
|
-
mcpServers: {
|
|
36
|
-
"canary-journal": {
|
|
37
|
-
command: "npx",
|
|
38
|
-
args: ["-y", "canary-agent"],
|
|
39
|
-
env: {
|
|
40
|
-
CANARY_API_KEY: apiKey.trim() || "YOUR_API_KEY_HERE",
|
|
41
|
-
...endpoint !== DEFAULT_ENDPOINT ? { CANARY_ENDPOINT: endpoint } : {}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
let configPath;
|
|
47
|
-
if (configChoice.trim() === "2") {
|
|
48
|
-
configPath = join(process.cwd(), ".mcp.json");
|
|
49
|
-
} else {
|
|
50
|
-
const claudeDir = join(homedir(), ".claude");
|
|
51
|
-
mkdirSync(claudeDir, { recursive: true });
|
|
52
|
-
configPath = join(claudeDir, "mcp.json");
|
|
53
|
-
}
|
|
54
|
-
let existing = {};
|
|
55
|
-
if (existsSync(configPath)) {
|
|
56
|
-
try {
|
|
57
|
-
existing = JSON.parse(readFileSync(configPath, "utf8"));
|
|
58
|
-
} catch {
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
const merged = {
|
|
62
|
-
...existing,
|
|
63
|
-
mcpServers: {
|
|
64
|
-
...existing.mcpServers || {},
|
|
65
|
-
...mcpConfig.mcpServers
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
69
|
-
console.log(`
|
|
70
|
-
Wrote MCP config to: ${configPath}`);
|
|
71
|
-
console.log("");
|
|
72
|
-
const installSkill = await ask(
|
|
73
|
-
rl,
|
|
74
|
-
" Install the canary-feedback skill for Claude Code? (Y/n): "
|
|
75
|
-
);
|
|
76
|
-
if (installSkill.trim().toLowerCase() !== "n") {
|
|
77
|
-
try {
|
|
78
|
-
const thisDir = typeof __dirname !== "undefined" ? __dirname : new URL(".", import.meta.url).pathname;
|
|
79
|
-
const pkgRoot = join(thisDir, "..");
|
|
80
|
-
const skillSrc = join(pkgRoot, "skills", "canary-feedback");
|
|
81
|
-
const claudeDir = join(homedir(), ".claude");
|
|
82
|
-
const skillDest = join(claudeDir, "skills", "canary-feedback");
|
|
83
|
-
if (existsSync(join(skillSrc, "SKILL.md"))) {
|
|
84
|
-
mkdirSync(skillDest, { recursive: true });
|
|
85
|
-
for (const file of ["SKILL.md", "manifest.yaml", "mcp-config.json"]) {
|
|
86
|
-
const src = join(skillSrc, file);
|
|
87
|
-
if (existsSync(src)) {
|
|
88
|
-
writeFileSync(join(skillDest, file), readFileSync(src, "utf8"));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
console.log(` Installed skill to: ${skillDest}`);
|
|
92
|
-
} else {
|
|
93
|
-
console.log(" Skill files not found in package. Skipping.");
|
|
94
|
-
}
|
|
95
|
-
} catch (err) {
|
|
96
|
-
console.log(` Could not install skill: ${err.message}`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
console.log("");
|
|
100
|
-
console.log(" Setup complete! Next steps:");
|
|
101
|
-
console.log(" 1. Start Claude Code in any project");
|
|
102
|
-
console.log(" 2. The canary-journal MCP server will auto-start");
|
|
103
|
-
console.log(" 3. Claude will use canary_annotate and canary_report tools automatically");
|
|
104
|
-
console.log("");
|
|
105
|
-
rl.close();
|
|
106
|
-
}
|
|
107
|
-
main().catch((err) => {
|
|
108
|
-
console.error("Setup failed:", err.message);
|
|
109
|
-
process.exit(1);
|
|
110
|
-
});
|