@mushi-mushi/cli 0.36.0 → 0.36.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 +4 -4
- package/dist/{chunk-NHE5JMLQ.js → chunk-2JOEQQOU.js} +2 -2
- package/dist/chunk-76LVDUR5.js +8 -0
- package/dist/{chunk-T2NBO4WL.js → chunk-H6HZNVVT.js} +3 -1
- package/dist/{chunk-YJ5Z6ZDX.js → chunk-OKT53MJ7.js} +97 -13
- package/dist/{chunk-GHG5XKGP.js → chunk-TN2IZOY7.js} +2 -1
- package/dist/chunk-YYDQ3IYE.js +10 -0
- package/dist/{connect-CHLNFDG5.js → connect-W4VHAQIQ.js} +2 -2
- package/dist/{connect-GVDAI3RJ.js → connect-YZMEO7Y5.js} +3 -3
- package/dist/{daemon-ZGSTNMAY.js → daemon-D3BEJ4ZR.js} +3 -3
- package/dist/index.js +21 -6
- package/dist/init.js +3 -3
- package/dist/{version-673M6J44.js → version-TOLAY73N.js} +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-FRVELHB4.js +0 -8
- package/dist/chunk-MV3SEIJM.js +0 -10
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ npm install -g @mushi-mushi/cli # optional: a global `mushi` command
|
|
|
21
21
|
|
|
22
22
|
The wizard detects your framework and package manager, checks your credentials, installs the right SDK, writes framework-prefixed env vars (`NEXT_PUBLIC_`, `VITE_`, `EXPO_PUBLIC_`…) to `.env.local`, prints the snippet to paste, and offers to send a test report. It never overwrites an existing env var or edits your code.
|
|
23
23
|
|
|
24
|
-
**Credentials** come from the [console](https://kensaur.us/mushi-mushi/admin): the **project ID** is on the
|
|
24
|
+
**Credentials** come from the [console](https://kensaur.us/mushi-mushi/admin): the **project ID** is on the **Manage apps** page; the **API key** is under **Set up → Test it → Generate API key** (`report:write`), not the AI keys in Settings. No project yet? The wizard can open the console for you.
|
|
25
25
|
|
|
26
26
|
For your editor, `mushi setup` writes the hosted MCP entry by default: the editor opens a browser sign-in on first use and no key is stored on disk. Add `--stdio` for a local server instead.
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ For your editor, `mushi setup` writes the hosted MCP entry by default: the edito
|
|
|
32
32
|
| Set up | `init`, `login`, `setup`, `connect`, `doctor`, `test` (send a test report), `upgrade`, `nudge`, `completion`, `profile` |
|
|
33
33
|
| Bugs | `reports list/show/search/triage`, `lessons list/show`, `sentry import` |
|
|
34
34
|
| Fixes | `fix <reportId>`, `fixes tail/merge/refresh-ci/review/verify`, `verify workflow` |
|
|
35
|
-
| Local agent | `work` (
|
|
35
|
+
| Local agent | `work` (the Cursor CLI or Claude Code on your own computer fixes a report; `mushi work` pushes and opens the draft PR with your `git` and `gh`), `worker install/status/revoke` (keeps it running, steered from the console) |
|
|
36
36
|
| Ship | `sourcemaps upload`, `deploy check`, `migrate`, `audit`, `releases` |
|
|
37
37
|
| Test and UX | `qa stories/runs/run`, `tdd gen/pending/approve/improve`, `stories map`, `ux` (including `ux fresh-eyes`, the first-time user test) |
|
|
38
38
|
| CI | `runner status/compare/bill`: where your tests run, what they cost, and whether a red check was your code or the machine |
|
|
@@ -45,7 +45,7 @@ For your editor, `mushi setup` writes the hosted MCP entry by default: the edito
|
|
|
45
45
|
```bash
|
|
46
46
|
mushi doctor --fix # check SDK, ingest and dispatch; fix what's safe locally
|
|
47
47
|
mushi reports list --status new --severity critical # what broke
|
|
48
|
-
mushi fix <reportId> --wait #
|
|
48
|
+
mushi fix <reportId> --wait # the built-in fixer opens a draft PR for it
|
|
49
49
|
mushi fixes merge <fixId> # merge it and mark the report Fixed
|
|
50
50
|
mushi upgrade # bump @mushi-mushi/* to the latest stable
|
|
51
51
|
mushi upgrade --check # CI: exit 0 current, 1 outdated, 2 registry down
|
|
@@ -62,7 +62,7 @@ MUSHI_API_KEY=mushi_xxx mushi connect --project-id <uuid> --endpoint <url> --wai
|
|
|
62
62
|
|
|
63
63
|
Other `init` flags: `--framework next`, `--cwd apps/web` (monorepos), `--endpoint <url>` (self-hosted), `--skip-install`, `--audit` (check an existing install instead).
|
|
64
64
|
|
|
65
|
-
**What needs your own key.** Reading reports, diagnoses and fix prompts does not. `mushi fix` hands the report to
|
|
65
|
+
**What needs your own key.** Reading reports, diagnoses and fix prompts does not. `mushi fix` hands the report to the built-in fixer by default (`--agent claude_code`): it uses your own Anthropic or OpenAI key when you have added one, and on hosted Mushi Mushi it falls back to Mushi Mushi's key when you have not. `--agent cursor_cloud` needs your own Cursor key. `mushi work` runs the Cursor CLI or Claude Code (`--agent claude`, CLI 0.36.0 or later) on your own computer instead, on the account that tool is signed in to.
|
|
66
66
|
|
|
67
67
|
## Environment variables
|
|
68
68
|
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
requireUuid,
|
|
10
10
|
saveConfig,
|
|
11
11
|
savedSdkKeyFor
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-H6HZNVVT.js";
|
|
13
13
|
import {
|
|
14
14
|
MUSHI_MCP_PIN_SPEC
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-YYDQ3IYE.js";
|
|
16
16
|
import {
|
|
17
17
|
assertEndpoint,
|
|
18
18
|
normalizeEndpoint
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MUSHI_CLI_VERSION
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YYDQ3IYE.js";
|
|
5
5
|
import {
|
|
6
6
|
CLOUD_API_ENDPOINT,
|
|
7
7
|
normalizeEndpoint
|
|
@@ -14,6 +14,7 @@ var EXIT_CODE_MAP = {
|
|
|
14
14
|
E_PROJECT_MISSING: 2,
|
|
15
15
|
E_ENDPOINT_INVALID: 2,
|
|
16
16
|
E_INVALID_INPUT: 2,
|
|
17
|
+
E_WRONG_REPO: 2,
|
|
17
18
|
E_NOT_INTERACTIVE: 2,
|
|
18
19
|
E_NETWORK: 3,
|
|
19
20
|
E_TIMEOUT: 3,
|
|
@@ -771,6 +772,7 @@ export {
|
|
|
771
772
|
getAbortSignal,
|
|
772
773
|
isKeychainEnabled,
|
|
773
774
|
trySaveKeyToKeychain,
|
|
775
|
+
tryLoadKeyFromKeychain,
|
|
774
776
|
syncKeychainAfterKeyChange,
|
|
775
777
|
trySaveWorkerKey,
|
|
776
778
|
tryLoadWorkerKey,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
requireConfig,
|
|
9
9
|
requireUuid,
|
|
10
10
|
tryLoadWorkerKey
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-H6HZNVVT.js";
|
|
12
12
|
import {
|
|
13
13
|
MUSHI_CLI_VERSION
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YYDQ3IYE.js";
|
|
15
15
|
|
|
16
16
|
// src/worker/daemon.ts
|
|
17
17
|
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
@@ -405,6 +405,43 @@ ${run.stderr}`).trim();
|
|
|
405
405
|
${text.slice(-2e3)}` : text);
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
+
// src/commands/work-repo.ts
|
|
409
|
+
function redactRemote(url) {
|
|
410
|
+
return url.trim().replace(/^([a-z][a-z0-9+.-]*:\/\/)[^@/]*@/i, "$1");
|
|
411
|
+
}
|
|
412
|
+
function normaliseRepoUrl(url) {
|
|
413
|
+
let s = url.trim();
|
|
414
|
+
if (!s) return null;
|
|
415
|
+
const proto = /^[a-z][a-z0-9+.-]*:\/\//i.exec(s);
|
|
416
|
+
if (proto) {
|
|
417
|
+
s = s.slice(proto[0].length).replace(/^[^@/]*@/, "");
|
|
418
|
+
s = s.replace(/^([^/:]+):\d+(?=\/|$)/, "$1");
|
|
419
|
+
} else {
|
|
420
|
+
s = s.replace(/^[^@/]*@/, "");
|
|
421
|
+
s = s.replace(/^([^/:]+):(?!\/)/, "$1/");
|
|
422
|
+
}
|
|
423
|
+
s = s.replace(/\/+$/, "").replace(/\.git$/i, "").replace(/\/+$/, "").toLowerCase();
|
|
424
|
+
if (!s) return null;
|
|
425
|
+
const parts = s.split("/").filter(Boolean);
|
|
426
|
+
if (parts.length === 2 && !parts[0].includes(".")) parts.unshift("github.com");
|
|
427
|
+
return parts.length ? parts.join("/") : null;
|
|
428
|
+
}
|
|
429
|
+
function originMatchesRepos(origin, repoUrls) {
|
|
430
|
+
if (!repoUrls.length) return true;
|
|
431
|
+
const o = origin ? normaliseRepoUrl(origin) : null;
|
|
432
|
+
if (!o) return false;
|
|
433
|
+
return repoUrls.some((u) => normaliseRepoUrl(u) === o);
|
|
434
|
+
}
|
|
435
|
+
function wrongRepoMessage(o) {
|
|
436
|
+
if (!o.repoUrls?.length || originMatchesRepos(o.origin, o.repoUrls)) return null;
|
|
437
|
+
const project = o.projectName ? `${o.projectName}${o.projectId ? ` (${o.projectId})` : ""}` : o.projectId ?? "this key's project";
|
|
438
|
+
const origin = o.origin ? redactRemote(o.origin) : "(no origin remote)";
|
|
439
|
+
return {
|
|
440
|
+
message: `Wrong repo: your Mushi key belongs to ${project}, which is linked to ${o.repoUrls.join(", ")}, but ${o.repoDir} has origin ${origin}. mushi work would apply that project's reports to this repo, so it stopped before claiming anything.`,
|
|
441
|
+
hint: "In this repo, run `mushi login --upgrade-scope --project-id <the project for this repo>`, or pass --repo-dir with a clone of the linked repo. For a monorepo or a fork, pass --any-repo to skip this check."
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
408
445
|
// src/commands/work.ts
|
|
409
446
|
import { spawn } from "child_process";
|
|
410
447
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -452,7 +489,7 @@ function cap(text, max) {
|
|
|
452
489
|
return t.length > max ? `${t.slice(0, max)} [cut]` : t;
|
|
453
490
|
}
|
|
454
491
|
function failureTail(r, max = 600) {
|
|
455
|
-
const t = [r.stdout, r.stderr].map((x) => x.trim()).filter(Boolean).join("\n").replace(/[ \t]+/g, " ");
|
|
492
|
+
const t = stripVTControlCharacters2([r.stdout, r.stderr].map((x) => x.trim()).filter(Boolean).join("\n")).replace(/[ \t]+/g, " ");
|
|
456
493
|
const lines = t.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
457
494
|
const kept = [];
|
|
458
495
|
let size = 0;
|
|
@@ -1020,10 +1057,15 @@ async function installDeps(wt, log) {
|
|
|
1020
1057
|
const cmd = installCommand((f) => existsSync(join2(wt, f)));
|
|
1021
1058
|
if (!cmd) return;
|
|
1022
1059
|
log(` deps: ${cmd[0]} ${cmd[1][0]} (so the agent can run tests and the commit hooks work)`);
|
|
1023
|
-
|
|
1024
|
-
|
|
1060
|
+
const [bin, args] = windowsShim(cmd, process.platform);
|
|
1061
|
+
let r = await runProc(bin, args, { cwd: wt, timeoutMs: 10 * 6e4 });
|
|
1062
|
+
if (r.code !== 0) r = await runProc(bin, args, { cwd: wt, timeoutMs: 10 * 6e4 });
|
|
1025
1063
|
if (r.code !== 0) log(` deps: install failed twice, the agent works without them (${failureTail(r, 300)})`);
|
|
1026
1064
|
}
|
|
1065
|
+
function windowsShim(cmd, platform) {
|
|
1066
|
+
if (platform !== "win32") return cmd;
|
|
1067
|
+
return ["cmd.exe", ["/d", "/s", "/c", cmd[0], ...cmd[1]]];
|
|
1068
|
+
}
|
|
1027
1069
|
function isMissingModuleFailure(message) {
|
|
1028
1070
|
return /ERR_MODULE_NOT_FOUND|Cannot find (package|module)/.test(message);
|
|
1029
1071
|
}
|
|
@@ -1091,10 +1133,29 @@ function missingWriteScope(scopes, projectId) {
|
|
|
1091
1133
|
const have = scopes.length ? scopes.join(", ") : "no scopes";
|
|
1092
1134
|
return `This CLI key has ${have}; mushi work also needs mcp:write to record the fix and queue its review. Run: mushi login --upgrade-scope${projectId ? ` --project-id ${projectId}` : ""}`;
|
|
1093
1135
|
}
|
|
1094
|
-
async function
|
|
1136
|
+
async function readWhoami(cfg) {
|
|
1095
1137
|
const res = await apiCall("/v1/sync/whoami", cfg);
|
|
1096
|
-
|
|
1097
|
-
|
|
1138
|
+
return res.ok ? res.data : void 0;
|
|
1139
|
+
}
|
|
1140
|
+
async function originOf(repoDir) {
|
|
1141
|
+
if (!existsSync(repoDir)) return null;
|
|
1142
|
+
const r = await runProc("git", ["remote", "get-url", "origin"], { cwd: repoDir, timeoutMs: 3e4 });
|
|
1143
|
+
const url = r.code === 0 ? r.stdout.trim() : "";
|
|
1144
|
+
return url || null;
|
|
1145
|
+
}
|
|
1146
|
+
async function requireRightRepo(whoami, repoDir) {
|
|
1147
|
+
if (!whoami?.repo_urls?.length) return;
|
|
1148
|
+
const problem = wrongRepoMessage({
|
|
1149
|
+
projectName: whoami.project_name,
|
|
1150
|
+
projectId: whoami.project_id,
|
|
1151
|
+
repoUrls: whoami.repo_urls,
|
|
1152
|
+
origin: await originOf(repoDir),
|
|
1153
|
+
repoDir
|
|
1154
|
+
});
|
|
1155
|
+
if (problem) throw new MushiCliError("E_WRONG_REPO", problem.message, problem.hint);
|
|
1156
|
+
}
|
|
1157
|
+
function requireWriteScope(cfg, whoami) {
|
|
1158
|
+
const problem = missingWriteScope(whoami?.scopes, cfg.projectId);
|
|
1098
1159
|
if (problem) throw new MushiCliError("E_AUTH_MISSING", problem, `mushi login --upgrade-scope${cfg.projectId ? ` --project-id ${cfg.projectId}` : ""}`);
|
|
1099
1160
|
}
|
|
1100
1161
|
function stopLine(agent, left, what) {
|
|
@@ -1102,14 +1163,14 @@ function stopLine(agent, left, what) {
|
|
|
1102
1163
|
return `Stopped: the ${spec.label} agent could not run (out of usage or signed out). ${left} ${what}${left === 1 ? "" : "s"} left untouched and can be picked up again; the run was closed without a retry cooldown. Check: ${spec.bin} ${spec.status.join(" ")}`;
|
|
1103
1164
|
}
|
|
1104
1165
|
function registerWorkCommands(program) {
|
|
1105
|
-
program.command("work").description("Fix reports with a coding agent on this machine (the Cursor CLI or Claude Code); pushes and opens the draft PR with your git and gh").option("--repo-dir <path>", "A clone of the app repo (only worktrees are created in it); not with --daemon").option("--project <id>", "Project id (overrides MUSHI_PROJECT_ID)").option("--agent <name>", "Local agent: cursor (cursor-agent, default) or claude (Claude Code, claude -p); with --daemon, overrides the worker config's agent").option("--model <id>", "Model for the agent (cursor: cursor-agent --list-models; claude: opus, sonnet, haiku or a claude-\u2026 id)").option("--max <n>", "Reports per run", "3").option("--report <id>", "Work on this report only").option("--followups", 'Instead of new reports: fix the Opus "fix first" findings on PRs mushi work opened, and push to them').option("--keep", "Keep the worktree after the run").option("--dry-run", "Show what would run; change nothing").option("--json", "Machine-readable JSON output").option("--daemon", "Run as a local worker: register this machine, send a heartbeat every 60 s, take the console's lane settings and claim reports (set up with `mushi worker install`)").option("--worker-config <path>", "With --daemon: the lanes file (default ~/.config/mushi/worker.json)").action(async (opts) => {
|
|
1166
|
+
program.command("work").description("Fix reports with a coding agent on this machine (the Cursor CLI or Claude Code); pushes and opens the draft PR with your git and gh").option("--repo-dir <path>", "A clone of the app repo (only worktrees are created in it); not with --daemon").option("--project <id>", "Project id (overrides MUSHI_PROJECT_ID)").option("--agent <name>", "Local agent: cursor (cursor-agent, default) or claude (Claude Code, claude -p); with --daemon, overrides the worker config's agent").option("--model <id>", "Model for the agent (cursor: cursor-agent --list-models; claude: opus, sonnet, haiku or a claude-\u2026 id)").option("--max <n>", "Reports per run", "3").option("--report <id>", "Work on this report only").option("--followups", 'Instead of new reports: fix the Opus "fix first" findings on PRs mushi work opened, and push to them').option("--keep", "Keep the worktree after the run").option("--dry-run", "Show what would run; change nothing").option("--any-repo", "Skip the check that the clone is a repo the key's project is linked to (a monorepo or a fork)").option("--json", "Machine-readable JSON output").option("--daemon", "Run as a local worker: register this machine, send a heartbeat every 60 s, take the console's lane settings and claim reports (set up with `mushi worker install`)").option("--worker-config <path>", "With --daemon: the lanes file (default ~/.config/mushi/worker.json)").action(async (opts) => {
|
|
1106
1167
|
const agent = parseLocalAgent(opts.agent);
|
|
1107
1168
|
if (opts.daemon) {
|
|
1108
1169
|
if (opts.repoDir || opts.report || opts.followups) {
|
|
1109
1170
|
throw new MushiCliError("E_INVALID_INPUT", "--daemon takes its lanes and clones from the worker config, not from --repo-dir, --report or --followups.", "mushi worker install");
|
|
1110
1171
|
}
|
|
1111
|
-
const { runDaemon: runDaemon2 } = await import("./daemon-
|
|
1112
|
-
await runDaemon2({ configPath: opts.workerConfig, ...opts.agent !== void 0 ? { agent } : {} });
|
|
1172
|
+
const { runDaemon: runDaemon2 } = await import("./daemon-D3BEJ4ZR.js");
|
|
1173
|
+
await runDaemon2({ configPath: opts.workerConfig, ...opts.agent !== void 0 ? { agent } : {}, ...opts.anyRepo ? { anyRepo: true } : {} });
|
|
1113
1174
|
return;
|
|
1114
1175
|
}
|
|
1115
1176
|
if (!opts.repoDir) throw new MushiCliError("E_INVALID_INPUT", "mushi work needs --repo-dir <clone>.", "mushi work --repo-dir ~/src/my-app");
|
|
@@ -1125,6 +1186,8 @@ function registerWorkCommands(program) {
|
|
|
1125
1186
|
};
|
|
1126
1187
|
const warn = (l) => process.stderr.write(`${l}
|
|
1127
1188
|
`);
|
|
1189
|
+
const whoami = await readWhoami(cfg);
|
|
1190
|
+
if (!opts.anyRepo) await requireRightRepo(whoami, repoDir);
|
|
1128
1191
|
if (opts.followups) {
|
|
1129
1192
|
const listed = await api(`/v1/admin/projects/${cfg.projectId}/local-followups`);
|
|
1130
1193
|
const due = listed.fixes.slice(0, max);
|
|
@@ -1136,7 +1199,7 @@ function registerWorkCommands(program) {
|
|
|
1136
1199
|
return;
|
|
1137
1200
|
}
|
|
1138
1201
|
await preflight(repoDir, warn, agent);
|
|
1139
|
-
|
|
1202
|
+
requireWriteScope(cfg, whoami);
|
|
1140
1203
|
const results2 = [];
|
|
1141
1204
|
for (const f of due) {
|
|
1142
1205
|
if (interruptedBy()) break;
|
|
@@ -1167,7 +1230,7 @@ function registerWorkCommands(program) {
|
|
|
1167
1230
|
return;
|
|
1168
1231
|
}
|
|
1169
1232
|
await preflight(repoDir, warn, agent);
|
|
1170
|
-
|
|
1233
|
+
requireWriteScope(cfg, whoami);
|
|
1171
1234
|
const results = [];
|
|
1172
1235
|
for (const d of picked) {
|
|
1173
1236
|
if (interruptedBy()) break;
|
|
@@ -2874,6 +2937,7 @@ async function runDaemon(opts = {}) {
|
|
|
2874
2937
|
if (gh.code !== 0) process.stdout.write("worker: gh is not signed in on this machine; lanes take nothing until it is (run: gh auth login).\n");
|
|
2875
2938
|
const repos = /* @__PURE__ */ new Map();
|
|
2876
2939
|
const notReady = /* @__PURE__ */ new Map();
|
|
2940
|
+
const origins = /* @__PURE__ */ new Map();
|
|
2877
2941
|
for (const lane of cfg.lanes) {
|
|
2878
2942
|
const g = await runProc("git", ["rev-parse", "--git-dir"], { cwd: lane.repoDir, timeoutMs: 3e4 });
|
|
2879
2943
|
if (g.code !== 0) {
|
|
@@ -2885,8 +2949,28 @@ async function runDaemon(opts = {}) {
|
|
|
2885
2949
|
const origin = await runProc("git", ["remote", "get-url", "origin"], { cwd: lane.repoDir, timeoutMs: 3e4 });
|
|
2886
2950
|
const repo = origin.code === 0 ? repoOfRemote(origin.stdout) : null;
|
|
2887
2951
|
if (repo) repos.set(lane.name, repo);
|
|
2952
|
+
if (origin.code === 0 && origin.stdout.trim()) origins.set(lane.name, origin.stdout.trim());
|
|
2888
2953
|
}
|
|
2889
2954
|
const conf = { apiKey: key, endpoint };
|
|
2955
|
+
if (!opts.anyRepo) {
|
|
2956
|
+
const who = await apiCall("/v1/sync/whoami", conf, {}, { timeoutMs: 3e4 });
|
|
2957
|
+
if (who.ok) {
|
|
2958
|
+
for (const lane of cfg.lanes) {
|
|
2959
|
+
if (notReady.has(lane.name) || lane.projectId !== who.data.project_id) continue;
|
|
2960
|
+
const problem = wrongRepoMessage({
|
|
2961
|
+
projectName: who.data.project_name,
|
|
2962
|
+
projectId: who.data.project_id,
|
|
2963
|
+
repoUrls: who.data.repo_urls,
|
|
2964
|
+
origin: origins.get(lane.name) ?? null,
|
|
2965
|
+
repoDir: lane.repoDir
|
|
2966
|
+
});
|
|
2967
|
+
if (!problem) continue;
|
|
2968
|
+
process.stdout.write(`worker: lane ${lane.name}: ${problem.message} The lane stays out until it is fixed (or restart with --any-repo).
|
|
2969
|
+
`);
|
|
2970
|
+
notReady.set(lane.name, `Its clone is not a repo ${who.data.project_name || "this project"} is linked to (${who.data.repo_urls.join(", ")}); point the lane at a clone of one, or restart the worker with --any-repo`);
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2890
2974
|
let wake = () => void 0;
|
|
2891
2975
|
const readings = createHostReadings({
|
|
2892
2976
|
...cursorAccount ? { cursorAccount } : {},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MUSHI_CLI_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-76LVDUR5.js";
|
|
4
4
|
import {
|
|
5
5
|
assertEndpoint,
|
|
6
6
|
normalizeEndpoint
|
|
@@ -415,6 +415,7 @@ var EXIT_CODE_MAP = {
|
|
|
415
415
|
E_PROJECT_MISSING: 2,
|
|
416
416
|
E_ENDPOINT_INVALID: 2,
|
|
417
417
|
E_INVALID_INPUT: 2,
|
|
418
|
+
E_WRONG_REPO: 2,
|
|
418
419
|
E_NOT_INTERACTIVE: 2,
|
|
419
420
|
E_NETWORK: 3,
|
|
420
421
|
E_TIMEOUT: 3,
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
saveConfig,
|
|
7
7
|
savedSdkKeyFor,
|
|
8
8
|
waitForIngestReady
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TN2IZOY7.js";
|
|
10
10
|
import {
|
|
11
11
|
MUSHI_MCP_PIN_SPEC
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-76LVDUR5.js";
|
|
13
13
|
import {
|
|
14
14
|
detectFramework,
|
|
15
15
|
envVarsToWrite,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
resolveSdkEnvKey,
|
|
4
4
|
runConnect
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2JOEQQOU.js";
|
|
6
6
|
import "./chunk-KOBEOGNF.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-H6HZNVVT.js";
|
|
8
|
+
import "./chunk-YYDQ3IYE.js";
|
|
9
9
|
import "./chunk-LGGE3LH7.js";
|
|
10
10
|
export {
|
|
11
11
|
resolveSdkEnvKey,
|
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
readWorkerKey,
|
|
11
11
|
runDaemon,
|
|
12
12
|
workerHostId
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-OKT53MJ7.js";
|
|
14
|
+
import "./chunk-H6HZNVVT.js";
|
|
15
|
+
import "./chunk-YYDQ3IYE.js";
|
|
16
16
|
import "./chunk-LGGE3LH7.js";
|
|
17
17
|
export {
|
|
18
18
|
assertWorkerKey,
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
sanitizeEndpoint,
|
|
23
23
|
sanitizeProjectId,
|
|
24
24
|
writeMcpServerEntry
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-2JOEQQOU.js";
|
|
26
26
|
import {
|
|
27
27
|
FRAMEWORKS,
|
|
28
28
|
detectFramework,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
registerUxCommands,
|
|
51
51
|
registerWorkCommands,
|
|
52
52
|
validateWorkerConfig
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-OKT53MJ7.js";
|
|
54
54
|
import {
|
|
55
55
|
CONFIG_PATH,
|
|
56
56
|
MushiCliError,
|
|
@@ -86,13 +86,14 @@ import {
|
|
|
86
86
|
setGlobalOutputFormat,
|
|
87
87
|
syncKeychainAfterKeyChange,
|
|
88
88
|
tryDeleteWorkerKey,
|
|
89
|
+
tryLoadKeyFromKeychain,
|
|
89
90
|
trySaveKeyToKeychain,
|
|
90
91
|
trySaveWorkerKey
|
|
91
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-H6HZNVVT.js";
|
|
92
93
|
import {
|
|
93
94
|
MUSHI_CLI_VERSION,
|
|
94
95
|
MUSHI_MCP_PIN_SPEC
|
|
95
|
-
} from "./chunk-
|
|
96
|
+
} from "./chunk-YYDQ3IYE.js";
|
|
96
97
|
import {
|
|
97
98
|
CLOUD_API_ENDPOINT,
|
|
98
99
|
CLOUD_MCP_OAUTH_URL,
|
|
@@ -427,6 +428,17 @@ function printAuthFailed(reason, detail) {
|
|
|
427
428
|
console.log("");
|
|
428
429
|
}
|
|
429
430
|
|
|
431
|
+
// src/env-key-override.ts
|
|
432
|
+
function envKeyOverrideLines(env, savedKey, platform = process.platform) {
|
|
433
|
+
const envKey = env.MUSHI_API_KEY?.trim();
|
|
434
|
+
if (!envKey || savedKey && envKey === savedKey) return [];
|
|
435
|
+
const where = platform === "win32" ? 'Remove it under Windows Settings \u2192 System \u2192 About \u2192 Advanced system settings \u2192 Environment Variables, or open a new terminal after `[Environment]::SetEnvironmentVariable("MUSHI_API_KEY", $null, "User")` in PowerShell.' : "Remove the `export MUSHI_API_KEY=\u2026` line from your shell profile, or run `unset MUSHI_API_KEY` in this terminal.";
|
|
436
|
+
return [
|
|
437
|
+
`\u26A0 MUSHI_API_KEY is set in your environment (${envKey.slice(0, 12)}\u2026), and it overrides ${savedKey ? `the saved key (${savedKey.slice(0, 12)}\u2026)` : "the saved key"}.`,
|
|
438
|
+
` Commands in this terminal use the environment key. ${where}`
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
|
|
430
442
|
// src/login.ts
|
|
431
443
|
function getPostLoginBannerMessage(opts) {
|
|
432
444
|
if (opts.suppressPostLoginBanner) return null;
|
|
@@ -674,8 +686,10 @@ error: Could not create project: ${err instanceof Error ? err.message : String(e
|
|
|
674
686
|
if (opts.upgradeScope) {
|
|
675
687
|
console.log(` \u2713 Full-scope CLI key saved (${apiKey.slice(0, 12)}\u2026)`);
|
|
676
688
|
console.log(` Scopes: report:write \xB7 mcp:read \xB7 mcp:write \u2014 SDK + MCP + admin CLI (incl. writes) all work with this key`);
|
|
689
|
+
for (const line of envKeyOverrideLines(process.env, apiKey)) console.log(` ${line}`);
|
|
677
690
|
} else {
|
|
678
691
|
console.log(` \u2713 CLI key saved (${apiKey.slice(0, 12)}\u2026)`);
|
|
692
|
+
for (const line of envKeyOverrideLines(process.env, apiKey)) console.log(` ${line}`);
|
|
679
693
|
console.log(` Scopes: report:write \xB7 mcp:read \u2014 SDK ingest + MCP read tools.`);
|
|
680
694
|
console.log(` Admin writes (mushi work, fix merge, billing cap, pipeline start) need: mushi login --upgrade-scope${chosenProjectId ? ` --project-id ${chosenProjectId}` : ""}`);
|
|
681
695
|
}
|
|
@@ -1595,7 +1609,7 @@ async function checkOnboardingStatus(config, _consoleBase, cwd, doFetch = global
|
|
|
1595
1609
|
}
|
|
1596
1610
|
async function checkVersionDrift(cwd, doFetch) {
|
|
1597
1611
|
const checks = [];
|
|
1598
|
-
const { MUSHI_CLI_VERSION: MUSHI_CLI_VERSION2 } = await import("./version-
|
|
1612
|
+
const { MUSHI_CLI_VERSION: MUSHI_CLI_VERSION2 } = await import("./version-TOLAY73N.js");
|
|
1599
1613
|
if (MUSHI_CLI_VERSION2 === "0.0.0-dev") return checks;
|
|
1600
1614
|
const parse2 = (v) => {
|
|
1601
1615
|
const m = v.replace(/^[~^]/, "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
@@ -2568,7 +2582,7 @@ async function maybeOfferConnect(credentials, options, _consoleBase) {
|
|
|
2568
2582
|
if (p.isCancel(answer) || !answer) return;
|
|
2569
2583
|
const endpoint = resolveCloudEndpoint(options.endpoint);
|
|
2570
2584
|
try {
|
|
2571
|
-
const { runConnect: runConnect2 } = await import("./connect-
|
|
2585
|
+
const { runConnect: runConnect2 } = await import("./connect-YZMEO7Y5.js");
|
|
2572
2586
|
const saved = loadConfig();
|
|
2573
2587
|
const result = await runConnect2(
|
|
2574
2588
|
{
|
|
@@ -2915,6 +2929,7 @@ Useful after 'mushi login' to confirm credentials are correct.`).action(async (o
|
|
|
2915
2929
|
console.log(" Mint one on the console MCP page, or run `mushi login`.");
|
|
2916
2930
|
}
|
|
2917
2931
|
}
|
|
2932
|
+
for (const line of envKeyOverrideLines(process.env, tryLoadKeyFromKeychain() ?? void 0)) console.log(` ${line}`);
|
|
2918
2933
|
}
|
|
2919
2934
|
});
|
|
2920
2935
|
program2.command("ping").description("Check connectivity to the Mushi backend").option("--json", "Machine-readable JSON output").action(async (opts) => {
|
package/dist/init.js
CHANGED
|
@@ -25,10 +25,10 @@ import {
|
|
|
25
25
|
saveConfig,
|
|
26
26
|
savedSdkKeyFor,
|
|
27
27
|
trySaveKeyToKeychain
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-TN2IZOY7.js";
|
|
29
29
|
import {
|
|
30
30
|
MUSHI_CLI_VERSION
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-76LVDUR5.js";
|
|
32
32
|
import {
|
|
33
33
|
FRAMEWORKS,
|
|
34
34
|
detectFramework,
|
|
@@ -2127,7 +2127,7 @@ async function maybeOfferConnect(credentials, options, _consoleBase) {
|
|
|
2127
2127
|
if (p.isCancel(answer) || !answer) return;
|
|
2128
2128
|
const endpoint = resolveCloudEndpoint(options.endpoint);
|
|
2129
2129
|
try {
|
|
2130
|
-
const { runConnect } = await import("./connect-
|
|
2130
|
+
const { runConnect } = await import("./connect-W4VHAQIQ.js");
|
|
2131
2131
|
const saved = loadConfig();
|
|
2132
2132
|
const result = await runConnect(
|
|
2133
2133
|
{
|
package/dist/version.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ declare const MUSHI_CLI_VERSION: string;
|
|
|
14
14
|
* setup refreshes the pin. Synced to packages/mcp/package.json by
|
|
15
15
|
* `scripts/sync-mcp-pin.mjs` — never hand-edit the version.
|
|
16
16
|
*/
|
|
17
|
-
declare const MUSHI_MCP_PIN_SPEC = "@mushi-mushi/mcp@0.30.
|
|
17
|
+
declare const MUSHI_MCP_PIN_SPEC = "@mushi-mushi/mcp@0.30.7";
|
|
18
18
|
|
|
19
19
|
export { MUSHI_CLI_VERSION, MUSHI_MCP_PIN_SPEC };
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
package/dist/chunk-FRVELHB4.js
DELETED