@mushi-mushi/mcp 0.6.0 → 0.9.0

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 (3) hide show
  1. package/README.md +31 -5
  2. package/dist/index.js +168 -37
  3. package/package.json +18 -17
package/README.md CHANGED
@@ -1,18 +1,44 @@
1
- # @mushi-mushi/mcp
1
+ # mushi-mcp
2
2
 
3
- [Model Context Protocol](https://spec.modelcontextprotocol.io/) server that wires Mushi Mushi's closed-loop bug intelligence into your AI coding agent so Cursor, Claude Code, Copilot, and any other MCP-compatible client can read classified reports, query the lesson library, and dispatch AI-generated fixes directly from the editor.
3
+ > **Sentry sees what code throws. Mushi sees what users feel — and closes the loop with AI.**
4
4
 
5
- **The evolutionary angle:** the lesson library (`lessons.query` tool) is the agent's institutional memory. Every bug cluster your team has ever named is available to the agent before it touches a single line of code — so it doesn't repeat the same class of mistake the last agent made. That's the "cumulative selection" loop the [main README](https://www.npmjs.com/package/mushi-mushi) describes, delivered to your IDE.
5
+ [Model Context Protocol](https://spec.modelcontextprotocol.io/) server that wires Mushi's **evolution loop** into your AI coding agent. The loop is already running in your Mushi project:
6
+
7
+ ```
8
+ User feels a bug → Mushi captures it → AI triages → AI opens a PR
9
+ → QA verifies → Judge scores → Lesson library remembers → next agent is smarter
10
+ ```
11
+
12
+ Wire it into Cursor, Claude Code, or any MCP client in one command:
13
+
14
+ ```bash
15
+ npx mushi-mushi setup --ide cursor
16
+ # or: npx mushi-mushi setup --ide claude
17
+ ```
18
+
19
+ That command reads `~/.mushirc`, writes `.cursor/mcp.json` with the `mushi` server block, and prints "Done — restart Cursor and ask: `list mushi tools`". No copy-pasting environment variables.
6
20
 
7
21
  > **What this is, and what it isn't**
8
22
  >
9
- > - **This package** is the MCP **server** — runs locally next to your editor, talks to the Mushi Mushi API, and presents bug reports as MCP tools/resources to your coding agent.
23
+ > - **This package** (`mushi-mcp`) is the MCP **server** — runs locally next to your editor, talks to the Mushi API, and presents bug reports as MCP tools/resources to your coding agent. The npm package name is `mushi-mcp`; the scoped alias `@mushi-mushi/mcp` still works.
10
24
  > - **`@mushi-mushi/agents`** ships the MCP **client adapter** — used by the autofix orchestrator when your project's `autofix_agent = 'mcp'`. See `packages/agents/src/adapters/mcp.ts`.
11
25
  > - The `generic_mcp` adapter shipped before V5.3 was a misnomer (it spoke plain REST). It is now `RestFixWorkerAgent`; the old export is kept as a deprecated alias for one more minor.
12
26
 
13
27
  ## Quick start
14
28
 
15
- ### 1. With Claude Desktop
29
+ ### 0. One-liner (recommended)
30
+
31
+ ```bash
32
+ # First: make sure you've logged in
33
+ npx mushi-mushi login --api-key mushi_xxx --endpoint https://<ref>.supabase.co/functions/v1/api
34
+
35
+ # Then wire your IDE
36
+ npx mushi-mushi setup --ide cursor # Cursor
37
+ npx mushi-mushi setup --ide claude # Claude Code / Claude Desktop
38
+ npx mushi-mushi setup --ide cursor --with-rules # also write .cursorrules
39
+ ```
40
+
41
+ ### 1. With Claude Desktop (manual)
16
42
 
17
43
  Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
18
44
 
package/dist/index.js CHANGED
@@ -5,11 +5,8 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
5
5
  import { createRequire } from "module";
6
6
  import { createLogger } from "@mushi-mushi/core";
7
7
 
8
- // src/server.ts
9
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
10
- import { z } from "zod";
11
-
12
8
  // src/catalog.ts
9
+ var ALL_SCOPES = ["mcp:read", "mcp:write"];
13
10
  var TOOL_CATALOG = [
14
11
  {
15
12
  name: "get_recent_reports",
@@ -132,6 +129,15 @@ var TOOL_CATALOG = [
132
129
  hints: { readOnly: true, idempotent: true, openWorld: true },
133
130
  useCase: "What did Stage 2 say we should try for this report?"
134
131
  },
132
+ // --- Setup / admin -------------------------------------------------------
133
+ {
134
+ name: "setup_check",
135
+ title: "Dispatch preflight check",
136
+ description: "Run the 4 dispatch-readiness checks for a project and return their pass/fail status (GitHub repo connected, codebase indexed, Anthropic BYOK key present, autofix enabled). Also returns the target repo URL when GitHub is connected. Use this before calling dispatch_fix to understand why a dispatch might fail \u2014 or to validate that the onboarding wizard is complete.",
137
+ scope: "mcp:read",
138
+ hints: { readOnly: true, idempotent: true, openWorld: true },
139
+ useCase: "Is this project ready to auto-fix bugs? What is blocking me?"
140
+ },
135
141
  // --- Write / agentic ----------------------------------------------------
136
142
  {
137
143
  name: "submit_fix_result",
@@ -145,10 +151,10 @@ var TOOL_CATALOG = [
145
151
  {
146
152
  name: "dispatch_fix",
147
153
  title: "Dispatch Mushi fix agent",
148
- description: "Dispatch the Mushi agentic fix orchestrator for a classified report. Returns a fix_attempt id; poll get_fix_timeline for progress.",
154
+ description: 'Dispatch the Mushi agentic fix orchestrator for a classified report. Set agent="cursor_cloud" to dispatch a Cursor Cloud Agent that opens a signed draft PR. Returns a fix_attempt id; poll get_fix_timeline for progress.',
149
155
  scope: "mcp:write",
150
156
  hints: { readOnly: false, destructive: false, idempotent: false, openWorld: true },
151
- useCase: "Let the in-repo agent attempt this fix for me."
157
+ useCase: "Let the in-repo agent attempt this fix for me (or: dispatch a Cursor Cloud Agent)."
152
158
  },
153
159
  {
154
160
  name: "trigger_judge",
@@ -201,10 +207,20 @@ var TOOL_CATALOG = [
201
207
  scope: "mcp:write",
202
208
  hints: { readOnly: false, destructive: false, idempotent: true, openWorld: true },
203
209
  useCase: "Manually promote this user to Champion tier as a thank-you."
210
+ },
211
+ {
212
+ name: "setup_repo_for_mushi",
213
+ title: "Bootstrap repo for Mushi",
214
+ description: "Writes the three Mushi bootstrap files into the current repo root: `.cursorrules` (Cursor evolution-loop coding rules), `.mushi/lessons.json` (initial empty lesson cache), and `MUSHI.md` (one-page project contract for agents). Idempotent \u2014 safe to re-run after lessons sync. Requires mcp:write scope. Call this once after connecting the repo; subsequently use `mushi sync-lessons` from CI to keep lessons current.",
215
+ scope: "mcp:write",
216
+ hints: { readOnly: false, destructive: false, idempotent: true, openWorld: false },
217
+ useCase: "Set up this repo for the Mushi evolution loop in one step."
204
218
  }
205
219
  ];
206
220
 
207
221
  // src/server.ts
222
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
223
+ import { z } from "zod";
208
224
  var MushiApiError = class extends Error {
209
225
  constructor(status, code, message) {
210
226
  super(`[${code}] ${message}`);
@@ -218,6 +234,9 @@ var MushiApiError = class extends Error {
218
234
  function createMushiServer(config) {
219
235
  const { version, apiEndpoint, apiKey, projectId } = config;
220
236
  const doFetch = config.fetch ?? globalThis.fetch;
237
+ if (config.scopes !== void 0 && config.scopes.length === 0) {
238
+ return new McpServer({ name: "mushi-mushi", version });
239
+ }
221
240
  async function apiCall(path, options) {
222
241
  const res = await doFetch(`${apiEndpoint}${path}`, {
223
242
  ...options,
@@ -263,6 +282,12 @@ function createMushiServer(config) {
263
282
  content: [{ type: "text", text: JSON.stringify(value, null, 2) }]
264
283
  };
265
284
  }
285
+ function jsonResult(value) {
286
+ return {
287
+ content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
288
+ structuredContent: value
289
+ };
290
+ }
266
291
  const server = new McpServer({
267
292
  name: "mushi-mushi",
268
293
  version
@@ -300,6 +325,10 @@ function createMushiServer(config) {
300
325
  category: z.string().optional().describe("Filter by category: bug, slow, visual, confusing, other"),
301
326
  severity: z.string().optional().describe("Filter by severity: critical, high, medium, low"),
302
327
  limit: z.number().optional().describe("Max reports to return (default 20, max 100)")
328
+ },
329
+ outputSchema: {
330
+ reports: z.array(z.unknown()),
331
+ total: z.number()
303
332
  }
304
333
  },
305
334
  async (args) => {
@@ -309,7 +338,7 @@ function createMushiServer(config) {
309
338
  if (args.severity) params.set("severity", args.severity);
310
339
  params.set("limit", String(Math.min(args.limit ?? 20, 100)));
311
340
  const data = await apiCall(`/v1/admin/reports?${params}`);
312
- return jsonText(data);
341
+ return jsonResult(data);
313
342
  }
314
343
  );
315
344
  server.registerTool(
@@ -332,6 +361,9 @@ function createMushiServer(config) {
332
361
  query: z.string().describe("Natural-language search text or component path"),
333
362
  limit: z.number().optional().describe("Max results (default 10, max 50)"),
334
363
  threshold: z.number().optional().describe("Similarity threshold 0..1, default 0.2")
364
+ },
365
+ outputSchema: {
366
+ results: z.array(z.unknown())
335
367
  }
336
368
  },
337
369
  async (args) => {
@@ -344,7 +376,7 @@ function createMushiServer(config) {
344
376
  ...projectId ? { projectId } : {}
345
377
  })
346
378
  });
347
- return jsonText(data);
379
+ return jsonResult(data);
348
380
  }
349
381
  );
350
382
  server.registerTool(
@@ -552,6 +584,43 @@ function createMushiServer(config) {
552
584
  return jsonText(data);
553
585
  }
554
586
  );
587
+ server.registerTool(
588
+ "setup_check",
589
+ {
590
+ title: titleOf("setup_check"),
591
+ description: descOf("setup_check"),
592
+ annotations: annotationsFor("setup_check"),
593
+ inputSchema: {
594
+ projectId: z.string().optional().describe(
595
+ "Project UUID to check. Falls back to the projectId the server was initialised with."
596
+ )
597
+ }
598
+ },
599
+ async (args) => {
600
+ const resolvedId = args.projectId ?? projectId;
601
+ if (!resolvedId) {
602
+ return jsonText({
603
+ ok: false,
604
+ error: "No projectId provided and none configured on the MCP server. Pass projectId explicitly."
605
+ });
606
+ }
607
+ const data = await apiCall(`/v1/admin/projects/${resolvedId}/preflight`);
608
+ const summary = data.checks.map((c) => ({
609
+ check: c.key,
610
+ label: c.label,
611
+ passed: c.ready,
612
+ hint: c.hint,
613
+ fixPath: c.fixHref
614
+ }));
615
+ return jsonText({
616
+ ready: data.ready,
617
+ repoUrl: data.repoUrl ?? null,
618
+ checks: summary,
619
+ // Human-readable summary for agents that paste the result into a prompt
620
+ summary: data.ready ? `Project ${resolvedId} is ready to dispatch auto-fixes${data.repoUrl ? ` (target: ${data.repoUrl})` : ""}.` : `Project ${resolvedId} cannot dispatch yet \u2014 ${summary.filter((c) => !c.passed).map((c) => c.label).join(", ")}.`
621
+ });
622
+ }
623
+ );
555
624
  server.registerTool(
556
625
  "submit_fix_result",
557
626
  {
@@ -598,6 +667,10 @@ function createMushiServer(config) {
598
667
  agent: z.enum(["claude_code", "codex", "rest_worker", "mcp"]).optional().describe("Override the agent adapter"),
599
668
  idempotencyKey: z.string().uuid().optional().describe("Optional RFC 4122 UUID. Resend the same key to safely retry without dispatching a duplicate fix job (Idempotency-Key IETF draft)."),
600
669
  inventoryActionNodeId: z.string().uuid().optional().describe("Optional inventory Action node UUID for spec-traceability (\xA72.10). When provided, the fix-worker embeds the expected_outcome contract in the LLM prompt and runs validateAgainstSpec before opening the PR.")
670
+ },
671
+ outputSchema: {
672
+ fixId: z.string(),
673
+ status: z.string()
601
674
  }
602
675
  },
603
676
  async (args, extra) => {
@@ -625,7 +698,7 @@ function createMushiServer(config) {
625
698
  ...projectId ? { projectId } : {}
626
699
  })
627
700
  });
628
- return jsonText(data);
701
+ return jsonResult(data);
629
702
  }
630
703
  );
631
704
  server.registerTool(
@@ -691,6 +764,26 @@ function createMushiServer(config) {
691
764
  return jsonText(data);
692
765
  }
693
766
  );
767
+ server.registerTool(
768
+ "setup_repo_for_mushi",
769
+ {
770
+ title: titleOf("setup_repo_for_mushi"),
771
+ description: descOf("setup_repo_for_mushi"),
772
+ annotations: annotationsFor("setup_repo_for_mushi"),
773
+ inputSchema: {
774
+ projectId: z.string().optional().describe("Project UUID \u2014 defaults to configured project")
775
+ }
776
+ },
777
+ async (args) => {
778
+ const pid = args.projectId ?? projectId;
779
+ if (!pid) throw new MushiApiError(400, "MISSING_PROJECT", "projectId is required for setup_repo_for_mushi");
780
+ const data = await apiCall(`/v1/admin/projects/${pid}/repo/bootstrap`, {
781
+ method: "POST",
782
+ body: JSON.stringify({})
783
+ });
784
+ return jsonText(data);
785
+ }
786
+ );
694
787
  server.resource(
695
788
  "project_stats",
696
789
  "project://stats",
@@ -715,17 +808,15 @@ function createMushiServer(config) {
715
808
  contents: [{ uri: "project://dashboard", mimeType: "application/json", text: JSON.stringify(await apiCall("/v1/admin/dashboard"), null, 2) }]
716
809
  })
717
810
  );
718
- server.registerTool(
811
+ const rewardsMeta = (name) => annotationsFor(name);
812
+ server.tool(
719
813
  "list_top_contributors",
814
+ rewardsMeta("list_top_contributors").title,
720
815
  {
721
- title: titleOf("list_top_contributors"),
722
- description: descOf("list_top_contributors"),
723
- inputSchema: {
724
- limit: z.number().int().min(1).max(100).optional().default(10).describe("Max rows to return (default 10, max 100)"),
725
- range: z.enum(["30d", "90d", "all"]).optional().default("30d").describe("Time window for points calculation")
726
- },
727
- annotations: annotationsFor("list_top_contributors")
816
+ limit: z.number().int().min(1).max(100).optional().default(10).describe("Max rows to return (default 10, max 100)"),
817
+ range: z.enum(["30d", "90d", "all"]).optional().default("30d").describe("Time window for points calculation")
728
818
  },
819
+ rewardsMeta("list_top_contributors"),
729
820
  async ({ limit, range }) => ({
730
821
  content: [{
731
822
  type: "text",
@@ -737,18 +828,15 @@ function createMushiServer(config) {
737
828
  }]
738
829
  })
739
830
  );
740
- server.registerTool(
831
+ server.tool(
741
832
  "award_bonus_points",
833
+ rewardsMeta("award_bonus_points").title,
742
834
  {
743
- title: titleOf("award_bonus_points"),
744
- description: descOf("award_bonus_points"),
745
- inputSchema: {
746
- external_user_id: z.string().describe("The host-app user id as passed to Mushi.identify()"),
747
- points: z.number().int().min(1).max(5e4).describe("Bonus points to award (max 50,000 per call)"),
748
- reason: z.string().max(200).describe("Human-readable reason, logged to end_user_activity")
749
- },
750
- annotations: annotationsFor("award_bonus_points")
835
+ external_user_id: z.string().describe("The host-app user id as passed to Mushi.identify()"),
836
+ points: z.number().int().min(1).max(5e4).describe("Bonus points to award (max 50,000 per call)"),
837
+ reason: z.string().max(200).describe("Human-readable reason, logged to end_user_activity")
751
838
  },
839
+ rewardsMeta("award_bonus_points"),
752
840
  async ({ external_user_id, points, reason }) => ({
753
841
  content: [{
754
842
  type: "text",
@@ -764,18 +852,15 @@ function createMushiServer(config) {
764
852
  }]
765
853
  })
766
854
  );
767
- server.registerTool(
855
+ server.tool(
768
856
  "set_tier",
857
+ rewardsMeta("set_tier").title,
769
858
  {
770
- title: titleOf("set_tier"),
771
- description: descOf("set_tier"),
772
- inputSchema: {
773
- external_user_id: z.string().describe("The host-app user id as passed to Mushi.identify()"),
774
- tier_slug: z.string().describe('Tier slug to assign, e.g. "champion", "contributor", "explorer"'),
775
- reason: z.string().max(200).optional().describe("Optional reason for manual override")
776
- },
777
- annotations: annotationsFor("set_tier")
859
+ external_user_id: z.string().describe("The host-app user id as passed to Mushi.identify()"),
860
+ tier_slug: z.string().describe('Tier slug to assign, e.g. "champion", "contributor", "explorer"'),
861
+ reason: z.string().max(200).optional().describe("Optional reason for manual override")
778
862
  },
863
+ rewardsMeta("set_tier"),
779
864
  async ({ external_user_id, tier_slug, reason }) => ({
780
865
  content: [{
781
866
  type: "text",
@@ -791,6 +876,34 @@ function createMushiServer(config) {
791
876
  }]
792
877
  })
793
878
  );
879
+ server.resource(
880
+ "privacy_status",
881
+ "privacy://status",
882
+ {
883
+ description: "Returns the privacy posture for this project: storage region, LLM provider, whether BYOK is configured, data retention window, and last audit timestamp."
884
+ },
885
+ async () => ({
886
+ contents: [{
887
+ uri: "privacy://status",
888
+ mimeType: "application/json",
889
+ text: JSON.stringify(await apiCall("/v1/admin/privacy/status"), null, 2)
890
+ }]
891
+ })
892
+ );
893
+ server.resource(
894
+ "evolution_history",
895
+ "evolution://history",
896
+ {
897
+ description: "Returns the project's last 30 days of judge scores, prompt promotions, fixed-bug count, and lesson inductions. Agents can read this to see whether the loop is converging (rising judge scores, falling recurrence) or stalling."
898
+ },
899
+ async () => ({
900
+ contents: [{
901
+ uri: "evolution://history",
902
+ mimeType: "application/json",
903
+ text: JSON.stringify(await apiCall("/v1/admin/evolution/history"), null, 2)
904
+ }]
905
+ })
906
+ );
794
907
  server.resource(
795
908
  "project_integration_health",
796
909
  "project://integration-health",
@@ -891,6 +1004,15 @@ Prefer items that are bottlenecks or critical severity. Skip filler.`
891
1004
  }]
892
1005
  })
893
1006
  );
1007
+ const grantedScopes = config.scopes;
1008
+ if (grantedScopes !== void 0) {
1009
+ const toolRegistry = server._registeredTools;
1010
+ for (const spec of TOOL_CATALOG) {
1011
+ if (!grantedScopes.includes(spec.scope)) {
1012
+ toolRegistry[spec.name]?.remove();
1013
+ }
1014
+ }
1015
+ }
894
1016
  return server;
895
1017
  }
896
1018
 
@@ -901,6 +1023,9 @@ var log = createLogger({ scope: "mushi:mcp", level: "info" });
901
1023
  var API_ENDPOINT = process.env.MUSHI_API_ENDPOINT ?? "";
902
1024
  var API_KEY = process.env.MUSHI_API_KEY ?? "";
903
1025
  var PROJECT_ID = process.env.MUSHI_PROJECT_ID ?? "";
1026
+ var SCOPES_RAW = process.env.MUSHI_SCOPES ?? "";
1027
+ var parsedScopes = SCOPES_RAW ? SCOPES_RAW.split(",").map((s) => s.trim()).filter((s) => s === "mcp:read" || s === "mcp:write") : ALL_SCOPES;
1028
+ var SCOPES = SCOPES_RAW && parsedScopes.length === 0 ? ALL_SCOPES : parsedScopes;
904
1029
  async function main() {
905
1030
  if (!API_KEY) {
906
1031
  log.fatal("MUSHI_API_KEY environment variable is required");
@@ -916,12 +1041,18 @@ async function main() {
916
1041
  "[mushi-mcp] MUSHI_PROJECT_ID is not set.\n\nTools that scope to a project (get_recent_reports, get_report_detail,\nsearch_reports, etc.) will require you to pass projectId explicitly on\nevery call. To set it once and never pass it again:\n\n 1. Open the Mushi admin console \u2192 Projects\n https://kensaur.us/mushi-mushi/projects\n 2. Click your project \u2014 copy the UUID below the project name.\n 3. Add it to your MCP env config:\n MUSHI_PROJECT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\nOr visit Admin \u2192 MCP for a pre-filled config snippet with your actual UUID."
917
1042
  );
918
1043
  }
919
- log.info("Starting Mushi MCP server", { version: VERSION, endpoint: API_ENDPOINT || "(unset)", hasProjectId: !!PROJECT_ID });
1044
+ log.info("Starting Mushi MCP server", {
1045
+ version: VERSION,
1046
+ endpoint: API_ENDPOINT || "(unset)",
1047
+ hasProjectId: !!PROJECT_ID,
1048
+ scopes: SCOPES.join(",")
1049
+ });
920
1050
  const server = createMushiServer({
921
1051
  version: VERSION,
922
1052
  apiEndpoint: API_ENDPOINT,
923
1053
  apiKey: API_KEY,
924
- projectId: PROJECT_ID || void 0
1054
+ projectId: PROJECT_ID || void 0,
1055
+ scopes: SCOPES
925
1056
  });
926
1057
  const transport = new StdioServerTransport();
927
1058
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mushi-mushi/mcp",
3
- "version": "0.6.0",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "description": "MCP server exposing Mushi Mushi reports to coding agents",
6
6
  "type": "module",
@@ -23,18 +23,30 @@
23
23
  "CODE_OF_CONDUCT.md",
24
24
  "SECURITY.md"
25
25
  ],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "clean:types": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
29
+ "dev": "tsup --watch",
30
+ "lint": "eslint src/",
31
+ "test": "vitest run",
32
+ "test:smoke": "node scripts/smoke-stdio.mjs",
33
+ "test:localhost": "node scripts/localhost-e2e.mjs",
34
+ "demo": "node scripts/demo-terminal-config.mjs",
35
+ "inspector": "npx --yes @modelcontextprotocol/inspector@latest node ./dist/index.js",
36
+ "typecheck": "tsc --noEmit"
37
+ },
26
38
  "dependencies": {
27
39
  "@modelcontextprotocol/sdk": "^1.29.0",
28
- "zod": "^4.4.2",
29
- "@mushi-mushi/core": "^1.2.0"
40
+ "@mushi-mushi/core": "workspace:^",
41
+ "zod": "^4.4.2"
30
42
  },
31
43
  "devDependencies": {
44
+ "@mushi-mushi/eslint-config": "workspace:*",
32
45
  "@types/node": "^22.19.17",
33
46
  "eslint": "^10.3.0",
34
47
  "tsup": "^8.5.1",
35
48
  "typescript": "^6.0.3",
36
- "vitest": "^4.1.5",
37
- "@mushi-mushi/eslint-config": "0.0.0"
49
+ "vitest": "^4.1.5"
38
50
  },
39
51
  "repository": {
40
52
  "type": "git",
@@ -73,16 +85,5 @@
73
85
  ],
74
86
  "engines": {
75
87
  "node": ">=20"
76
- },
77
- "scripts": {
78
- "build": "tsup",
79
- "clean:types": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
80
- "dev": "tsup --watch",
81
- "lint": "eslint src/",
82
- "test": "vitest run",
83
- "test:smoke": "node scripts/smoke-stdio.mjs",
84
- "test:localhost": "node scripts/localhost-e2e.mjs",
85
- "demo": "node scripts/demo-terminal-config.mjs",
86
- "typecheck": "tsc --noEmit"
87
88
  }
88
- }
89
+ }