@misaka-net/misakanet-setup 0.4.1 → 0.4.2
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 +2 -2
- package/bin/misakanet-setup.mjs +87 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @misaka-net/misakanet-setup
|
|
2
2
|
|
|
3
|
-
One command to teach your **Claude Code**, **Codex**, **Hermes** or **
|
|
4
|
-
MisakaNet's failure lessons before repeating a mistake — and to distil the session's reusable
|
|
3
|
+
One command to teach your **Claude Code**, **Codex**, **Hermes**, **OpenClaw** or **codewhale** to
|
|
4
|
+
check MisakaNet's failure lessons before repeating a mistake — and to distil the session's reusable
|
|
5
5
|
lessons at a checkpoint.
|
|
6
6
|
|
|
7
7
|
```bash
|
package/bin/misakanet-setup.mjs
CHANGED
|
@@ -69,7 +69,7 @@ const valueOf = (flag, dflt) => {
|
|
|
69
69
|
const only = valueOf('--only', '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
70
70
|
const DRY = has('--dry-run');
|
|
71
71
|
const HOME = resolve(valueOf('--home', homedir()));
|
|
72
|
-
const AGENTS = ['claude', 'codex', 'hermes', 'openclaw'];
|
|
72
|
+
const AGENTS = ['claude', 'codex', 'hermes', 'openclaw', 'codewhale'];
|
|
73
73
|
|
|
74
74
|
const done = [];
|
|
75
75
|
const manual = [];
|
|
@@ -103,7 +103,7 @@ function readText(path) {
|
|
|
103
103
|
* meant to prevent is now caught in CI instead, by a test that binds this literal to the
|
|
104
104
|
* manifest — a failing test is a better place for that than a request header.
|
|
105
105
|
*/
|
|
106
|
-
const VERSION = '0.4.
|
|
106
|
+
const VERSION = '0.4.2';
|
|
107
107
|
|
|
108
108
|
function backup(path) {
|
|
109
109
|
if (DRY || !readText(path)) return;
|
|
@@ -352,6 +352,7 @@ function detect(agent) {
|
|
|
352
352
|
codex: ['.codex'],
|
|
353
353
|
hermes: ['.hermes'],
|
|
354
354
|
openclaw: ['.openclaw'],
|
|
355
|
+
codewhale: ['.codewhale'],
|
|
355
356
|
}[agent] || [];
|
|
356
357
|
return paths.some((p) => existsSync(join(HOME, p)));
|
|
357
358
|
}
|
|
@@ -673,6 +674,75 @@ async function installHermes(hookPath, bearer) {
|
|
|
673
674
|
* The manual `openclaw mcp add …` line is still printed for the user to run themselves — as
|
|
674
675
|
* text, never executed.
|
|
675
676
|
*/
|
|
677
|
+
/**
|
|
678
|
+
* codewhale keeps MCP servers in its own JSON file, and reads workspace rules from a
|
|
679
|
+
* plain `AGENTS.md` — but only in a *trusted* project (`config.toml`'s
|
|
680
|
+
* `[projects."<dir>"] trust_level = "trusted"`). So the block goes into the trusted
|
|
681
|
+
* project directories, which are also where the user actually works, rather than into a
|
|
682
|
+
* guessed user-level path (checked on 0.9.7: no user-level AGENTS.md is read).
|
|
683
|
+
*
|
|
684
|
+
* The token is the one thing codewhale will not take inline: `bearer_token_env_var` names
|
|
685
|
+
* an environment variable, so "install once" for this agent ends with the user exporting
|
|
686
|
+
* `MISAKANET_TOKEN` once. That is stated rather than silently half-installed.
|
|
687
|
+
*/
|
|
688
|
+
function codewhaleProjects() {
|
|
689
|
+
const text = readText(join(HOME, '.codewhale', 'config.toml'));
|
|
690
|
+
if (!text) return [];
|
|
691
|
+
const out = [];
|
|
692
|
+
let current = null;
|
|
693
|
+
for (const line of text.split('\n')) {
|
|
694
|
+
const header = line.match(/^\s*\[projects\.(.+?)\]\s*$/);
|
|
695
|
+
if (header) { current = header[1].trim().replace(/^"|"$/g, ''); continue; }
|
|
696
|
+
if (/^\s*\[/.test(line)) { current = null; continue; }
|
|
697
|
+
if (current && /^\s*trust_level\s*=\s*"trusted"/.test(line)) out.push(current);
|
|
698
|
+
}
|
|
699
|
+
return out;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
async function installCodewhale(bearer) {
|
|
703
|
+
const cfg = join(HOME, '.codewhale', 'mcp.json');
|
|
704
|
+
const data = readJson(cfg, null) || {
|
|
705
|
+
timeouts: { connect_timeout: 10, execute_timeout: 60, read_timeout: 120 },
|
|
706
|
+
servers: {},
|
|
707
|
+
};
|
|
708
|
+
const servers = { ...(data.servers || {}) };
|
|
709
|
+
const entry = {
|
|
710
|
+
command: null,
|
|
711
|
+
args: [],
|
|
712
|
+
env: {},
|
|
713
|
+
url: ENDPOINT,
|
|
714
|
+
connect_timeout: null,
|
|
715
|
+
execute_timeout: null,
|
|
716
|
+
read_timeout: null,
|
|
717
|
+
disabled: false,
|
|
718
|
+
enabled: true,
|
|
719
|
+
required: false,
|
|
720
|
+
enabled_tools: [],
|
|
721
|
+
disabled_tools: [],
|
|
722
|
+
bearer_token_env_var: 'MISAKANET_TOKEN',
|
|
723
|
+
};
|
|
724
|
+
if (JSON.stringify(servers.misakanet || null) !== JSON.stringify(entry)) {
|
|
725
|
+
servers.misakanet = entry;
|
|
726
|
+
backup(cfg);
|
|
727
|
+
writeText(cfg, `${JSON.stringify({ ...data, servers }, null, 2)}\n`);
|
|
728
|
+
ok(`codewhale:注册 MCP(streamable-http)→ ${cfg}`);
|
|
729
|
+
} else {
|
|
730
|
+
ok('codewhale:MCP 已注册(无改动)');
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const projects = codewhaleProjects();
|
|
734
|
+
for (const project of projects) {
|
|
735
|
+
if (!existsSync(project)) continue;
|
|
736
|
+
ok(`codewhale:规则块 ${injectBlock(join(project, 'AGENTS.md'), PROMPT_BLOCK)} → ${join(project, 'AGENTS.md')}`);
|
|
737
|
+
}
|
|
738
|
+
if (!projects.length) {
|
|
739
|
+
need('codewhale:没有受信任的项目目录(config.toml 里没有 trust_level = "trusted")→ '
|
|
740
|
+
+ '先在 codewhale 里打开一次你的项目并信任它,再运行本命令,规则块才会写进去');
|
|
741
|
+
}
|
|
742
|
+
need('codewhale:token 只能通过环境变量给 → 在你的 shell 配置里加 `export MISAKANET_TOKEN=<你的 token>`'
|
|
743
|
+
+ '(本机状态:npx @misaka-net/misakanet-setup --verify 会告诉你 token 在哪)');
|
|
744
|
+
}
|
|
745
|
+
|
|
676
746
|
async function installOpenclaw(bearer) {
|
|
677
747
|
const workspace = openclawWorkspaces()[0];
|
|
678
748
|
const rules = join(workspace, 'AGENTS.md');
|
|
@@ -850,6 +920,20 @@ function uninstall() {
|
|
|
850
920
|
const rules = join(workspace, 'AGENTS.md');
|
|
851
921
|
if (stripBlock(rules)) ok(`移除规则块 → ${rules}`);
|
|
852
922
|
}
|
|
923
|
+
|
|
924
|
+
// codewhale: same two surfaces as the install (its own mcp.json + trusted projects).
|
|
925
|
+
for (const project of codewhaleProjects()) {
|
|
926
|
+
const rules = join(project, 'AGENTS.md');
|
|
927
|
+
if (stripBlock(rules)) ok(`移除规则块 → ${rules}`);
|
|
928
|
+
}
|
|
929
|
+
const whaleCfg = join(HOME, '.codewhale', 'mcp.json');
|
|
930
|
+
const whale = readJson(whaleCfg, null);
|
|
931
|
+
if (whale?.servers?.misakanet) {
|
|
932
|
+
delete whale.servers.misakanet;
|
|
933
|
+
backup(whaleCfg);
|
|
934
|
+
writeText(whaleCfg, `${JSON.stringify(whale, null, 2)}\n`);
|
|
935
|
+
ok(`移除 MCP 注册 → ${whaleCfg}`);
|
|
936
|
+
}
|
|
853
937
|
const cfg = join(HOME, '.claude.json');
|
|
854
938
|
const data = readJson(cfg, null);
|
|
855
939
|
if (data && data.mcpServers?.misakanet) {
|
|
@@ -974,6 +1058,7 @@ if (!targets.length) {
|
|
|
974
1058
|
else if (agent === 'codex') await installCodex(hookPath, bearer);
|
|
975
1059
|
else if (agent === 'hermes') await installHermes(hookPath, bearer);
|
|
976
1060
|
else if (agent === 'openclaw') await installOpenclaw(bearer);
|
|
1061
|
+
else if (agent === 'codewhale') await installCodewhale(bearer);
|
|
977
1062
|
}
|
|
978
1063
|
}
|
|
979
1064
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@misaka-net/misakanet-setup",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "One-command setup: teach your Claude Code / Codex / Hermes / OpenClaw to search MisakaNet failure lessons before repeating a mistake, and to distil the session at a checkpoint.",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "One-command setup: teach your Claude Code / Codex / Hermes / OpenClaw / codewhale to search MisakaNet failure lessons before repeating a mistake, and to distil the session at a checkpoint.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"misakanet-setup": "bin/misakanet-setup.mjs"
|
|
7
7
|
},
|