@wirecat/cli-template 0.8.0 → 0.10.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 (125) hide show
  1. package/.github/workflows/ci.yml +3 -3
  2. package/.github/workflows/release.yml +63 -0
  3. package/.gitleaks.toml +18 -0
  4. package/AGENTS.md +9 -15
  5. package/CHANGELOG.md +87 -1
  6. package/README.md +4 -3
  7. package/bin/release +5 -3
  8. package/contracts/plan.json +2 -2
  9. package/dist/bin/clidev.js +34 -12
  10. package/dist/bundle/all-profiles-XHC7BG3P.js +24 -0
  11. package/dist/bundle/anthropic-N6B3ZZHQ.js +70 -0
  12. package/dist/bundle/bun-HUJLS7KP.js +169 -0
  13. package/dist/bundle/bun-sqlite-OWFO2TVR.js +69 -0
  14. package/dist/bundle/chunk-222FANS2.js +161 -0
  15. package/dist/bundle/chunk-2CFBHYFA.js +884 -0
  16. package/dist/bundle/chunk-2KQZ24GI.js +82 -0
  17. package/dist/bundle/chunk-2TBVT4SZ.js +31 -0
  18. package/dist/bundle/chunk-437W3Z2M.js +76 -0
  19. package/dist/bundle/chunk-4QRLPOJ7.js +18 -0
  20. package/dist/bundle/chunk-54AJONOM.js +54 -0
  21. package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
  22. package/dist/bundle/chunk-6CBWO7OF.js +73 -0
  23. package/dist/bundle/chunk-75LVQQEK.js +35782 -0
  24. package/dist/bundle/chunk-7RB76E2L.js +264 -0
  25. package/dist/bundle/chunk-7RXBN7HP.js +63 -0
  26. package/dist/bundle/chunk-ABP7FDMJ.js +122 -0
  27. package/dist/bundle/chunk-ADLS6FVG.js +24600 -0
  28. package/dist/bundle/chunk-AP7QKYBG.js +3531 -0
  29. package/dist/bundle/chunk-ASMH7JWZ.js +288 -0
  30. package/dist/bundle/chunk-B4EED2RF.js +100 -0
  31. package/dist/bundle/chunk-B4LM2B6F.js +1900 -0
  32. package/dist/bundle/chunk-BDSDQCV4.js +281 -0
  33. package/dist/bundle/chunk-DFDN6AUB.js +21 -0
  34. package/dist/bundle/chunk-DMCN22H6.js +35 -0
  35. package/dist/bundle/chunk-E42W72PQ.js +151 -0
  36. package/dist/bundle/chunk-EFHLQXG6.js +5104 -0
  37. package/dist/bundle/chunk-FIHDGZIB.js +34352 -0
  38. package/dist/bundle/chunk-FWVKHD2L.js +48 -0
  39. package/dist/bundle/chunk-FXS3X76A.js +193 -0
  40. package/dist/bundle/chunk-HTQTIKWP.js +928 -0
  41. package/dist/bundle/chunk-IJ3IA7EK.js +24 -0
  42. package/dist/bundle/chunk-JEBSORH7.js +3379 -0
  43. package/dist/bundle/chunk-JTTW5ZKF.js +45 -0
  44. package/dist/bundle/chunk-LSEF4QC3.js +3075 -0
  45. package/dist/bundle/chunk-LY7GS2YI.js +58 -0
  46. package/dist/bundle/chunk-MFS52LTZ.js +570 -0
  47. package/dist/bundle/chunk-MNSD5BX2.js +78 -0
  48. package/dist/bundle/chunk-MTGLJCAZ.js +24 -0
  49. package/dist/bundle/chunk-MZVV2JZT.js +744 -0
  50. package/dist/bundle/chunk-NE3NSB5O.js +8341 -0
  51. package/dist/bundle/chunk-NTLPDH76.js +440 -0
  52. package/dist/bundle/chunk-O3PBQVAB.js +447 -0
  53. package/dist/bundle/chunk-O5EHUB2V.js +2 -0
  54. package/dist/bundle/chunk-O5LMDQTO.js +82 -0
  55. package/dist/bundle/chunk-OPJ24VGH.js +1028 -0
  56. package/dist/bundle/chunk-OPPMGPFW.js +164 -0
  57. package/dist/bundle/chunk-QGNNMPUB.js +158 -0
  58. package/dist/bundle/chunk-QVJLOUQB.js +2 -0
  59. package/dist/bundle/chunk-S57AMKLX.js +6848 -0
  60. package/dist/bundle/chunk-TARN7CHN.js +215 -0
  61. package/dist/bundle/chunk-TJLGI3N6.js +1095 -0
  62. package/dist/bundle/chunk-VMTM46FH.js +7532 -0
  63. package/dist/bundle/chunk-W2IDKBNB.js +2315 -0
  64. package/dist/bundle/chunk-XFXBXQBS.js +630 -0
  65. package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
  66. package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
  67. package/dist/bundle/clidev.js +22 -0
  68. package/dist/bundle/command-contract-PEM3S634.js +29 -0
  69. package/dist/bundle/dist-ESHIQU4M.js +7577 -0
  70. package/dist/bundle/echarts-2QGL2JP5.js +42501 -0
  71. package/dist/bundle/embed-HHAAGHA6.js +35 -0
  72. package/dist/bundle/embedder-W2OGVVYH.js +108 -0
  73. package/dist/bundle/first-run-WCJUDUBU.js +23 -0
  74. package/dist/bundle/first-screen-U4DFUKUC.js +27 -0
  75. package/dist/bundle/instructions-OTZHT6NV.js +9 -0
  76. package/dist/bundle/mcp-OQBZXELQ.js +165 -0
  77. package/dist/bundle/mcp-VVF6J7SQ.js +151 -0
  78. package/dist/bundle/mcp-Y7VCIZ2J.js +78 -0
  79. package/dist/bundle/node-P4E63KXA.js +2340 -0
  80. package/dist/bundle/node-SYD4GX5O.js +176 -0
  81. package/dist/bundle/node-TLZSIHIJ.js +21 -0
  82. package/dist/bundle/node-sqlite-X2DGRFOZ.js +45 -0
  83. package/dist/bundle/oauth-42M34GQ5.js +17 -0
  84. package/dist/bundle/open-SWXRCDLN.js +19 -0
  85. package/dist/bundle/process-KAFGXZ7Q.js +91 -0
  86. package/dist/bundle/program-EHR4G7VN.js +16967 -0
  87. package/dist/bundle/prompt-ZQTMHRGX.js +12 -0
  88. package/dist/bundle/recognize-TTED4SE3.js +190 -0
  89. package/dist/bundle/remote-C37XJ4BP.js +26 -0
  90. package/dist/bundle/rerank-APFZAMQL.js +49 -0
  91. package/dist/bundle/serve-DDPIHDVZ.js +19 -0
  92. package/dist/bundle/server-L5GNG7KC.js +793 -0
  93. package/dist/bundle/server-LKVYA2AE.js +39 -0
  94. package/dist/bundle/state-WWPPHERF.js +33 -0
  95. package/dist/bundle/store-H6UIA4PK.js +120 -0
  96. package/dist/bundle/store-maintenance-command-EYBT64A2.js +40 -0
  97. package/dist/commands/mcp.d.ts.map +1 -1
  98. package/dist/commands/mcp.js +45 -30
  99. package/dist/commands/mcp.js.map +1 -1
  100. package/dist/version.d.ts +1 -1
  101. package/dist/version.d.ts.map +1 -1
  102. package/dist/version.js +1 -1
  103. package/dist/version.js.map +1 -1
  104. package/docs/commands.md +38 -22
  105. package/docs/dev/TESTING.md +14 -3
  106. package/docs/dev/reference-clis.md +17 -9
  107. package/docs/dev/skills/release/SKILL.md +9 -6
  108. package/docs/dev/skills/release/fresh-audit.md +4 -0
  109. package/docs/dev/test-matrix.md +10 -11
  110. package/docs/security.md +4 -0
  111. package/docs/usage.md +7 -6
  112. package/kit/dist/new.js +17 -2
  113. package/package.json +7 -5
  114. package/scripts/audit.sh +5 -3
  115. package/scripts/smoke-bundle.ts +63 -0
  116. package/scripts/test-matrix-untested.ts +4 -10
  117. package/scripts/version-level.test.ts +17 -1
  118. package/scripts/version-level.ts +35 -7
  119. package/skills/clidev-cli/SKILL.md +8 -0
  120. package/src/commands/mcp.ts +54 -33
  121. package/src/mcp-http.test.ts +20 -13
  122. package/src/mcp.test.ts +3 -3
  123. package/src/program.test.ts +8 -2
  124. package/src/roots.test.ts +2 -7
  125. package/src/version.ts +1 -1
@@ -95,7 +95,10 @@ it("serves the three tools behind the browser login, and shows the server in mcp
95
95
  const port = await freePort()
96
96
  const base = new URL(`http://127.0.0.1:${port}`)
97
97
  const stop = new AbortController()
98
- const serving = started(["personal", "mcp", "--http", "--public-url", base.href, "--port", String(port)], stop.signal)
98
+ const serving = started(
99
+ ["personal", "mcp", "serve", "--http", "--public-url", base.href, "--port", String(port)],
100
+ stop.signal,
101
+ )
99
102
  await vi.waitFor(() => expect(serving.err.join("\n")).toContain("serving on"))
100
103
  const codes = () => [...serving.err.join("\n").matchAll(/login code for a new browser app: (\S+)/g)].map((m) => m[1])
101
104
  const client = await loggedInClient(base, () => codes()[0] ?? "")
@@ -121,30 +124,34 @@ it("serves the three tools behind the browser login, and shows the server in mcp
121
124
  expect(await answer(["personal", "mcp", "server", "status", "--json"])).toMatchObject({ running: false })
122
125
  })
123
126
 
124
- it("refuses mcp --http without the tunnel's address", async () => {
125
- const one = started(["personal", "mcp", "--http", "--json"])
127
+ it("refuses mcp serve --http without the tunnel's address", async () => {
128
+ const one = started(["personal", "mcp", "serve", "--http", "--json"])
126
129
  expect(await one.code).not.toBe(0)
127
130
  expect(one.err.join("\n")).toContain("--public-url")
128
131
  })
129
132
 
130
- it("forgets every browser login on --revoke", async () => {
131
- expect(await answer(["personal", "mcp", "--revoke", "--json"])).toEqual({ revoked: true, profile: "personal" })
133
+ it("forgets every browser login on mcp revoke", async () => {
134
+ expect(await answer(["personal", "mcp", "revoke", "--json"])).toEqual({ revoked: true, profile: "personal" })
132
135
  })
133
136
 
134
137
  it("keeps the login code out of a background server's log, and refuses a port in use", async () => {
135
138
  const port = await freePort()
136
139
  const url = `http://127.0.0.1:${port}`
137
140
  const stop = new AbortController()
138
- const background = started(["personal", "mcp", "--http", "--public-url", url, "--port", String(port)], stop.signal, {
139
- ...process.env,
140
- CLIDEV_MCP_HTTP: "personal",
141
- })
141
+ const background = started(
142
+ ["personal", "mcp", "serve", "--http", "--public-url", url, "--port", String(port)],
143
+ stop.signal,
144
+ {
145
+ ...process.env,
146
+ CLIDEV_MCP_HTTP: "personal",
147
+ },
148
+ )
142
149
  try {
143
150
  await vi.waitFor(() => expect(background.err.join("\n")).toContain("serving on"))
144
151
  expect(background.err.join("\n")).toContain(
145
152
  "a new login code for a browser app: `clidev personal mcp server status`",
146
153
  )
147
- const second = started(["work", "mcp", "--http", "--public-url", url, "--port", String(port), "--json"])
154
+ const second = started(["work", "mcp", "serve", "--http", "--public-url", url, "--port", String(port), "--json"])
148
155
  expect(await second.code).not.toBe(0)
149
156
  expect(second.err.join("\n")).toContain(`port ${port} is in use`)
150
157
  } finally {
@@ -154,12 +161,12 @@ it("keeps the login code out of a background server's log, and refuses a port in
154
161
  })
155
162
 
156
163
  it("refuses --json for MCP over stdio", async () => {
157
- const one = started(["personal", "mcp", "--json"])
164
+ const one = started(["personal", "mcp", "serve", "--json"])
158
165
  expect(await one.code).toBe(2)
159
166
  expect(one.err.join("\n")).toContain("MCP over stdio controls its own output")
160
167
  })
161
168
 
162
- it("refuses --revoke under the read-only lock", async () => {
163
- const one = started(["personal", "mcp", "--revoke", "--json"], undefined, { ...process.env, CLIDEV_READ_ONLY: "1" })
169
+ it("refuses mcp revoke under the read-only lock", async () => {
170
+ const one = started(["personal", "mcp", "revoke", "--json"], undefined, { ...process.env, CLIDEV_READ_ONLY: "1" })
164
171
  expect(await one.code).toBe(5)
165
172
  })
package/src/mcp.test.ts CHANGED
@@ -47,7 +47,7 @@ it("finds writes as well as reads", async () => {
47
47
  const client = await connect()
48
48
  const found = structured(await client.callTool({ name: "clidev_tools_search", arguments: {} }))
49
49
  expect(found.items).toContainEqual(expect.objectContaining({ writes: true }))
50
- expect(found.items).not.toContainEqual(expect.objectContaining({ command: "mcp" }))
50
+ expect(found.items).not.toContainEqual(expect.objectContaining({ command: expect.stringMatching(/^mcp\b/) }))
51
51
  })
52
52
 
53
53
  it("runs a command through the CLI and answers with its result", async () => {
@@ -76,9 +76,9 @@ it("serves until the command is stopped", async () => {
76
76
  await expect(serving).resolves.toBeUndefined()
77
77
  })
78
78
 
79
- it("clidev <profile> mcp starts the server and ends on a signal", async () => {
79
+ it("clidev <profile> mcp serve starts the server and ends on a signal", async () => {
80
80
  const stop = new AbortController()
81
- const serving = run(["personal", "mcp"], {
81
+ const serving = run(["personal", "mcp", "serve"], {
82
82
  signal: stop.signal,
83
83
  tty: false,
84
84
  streams: { data: () => {}, diagnostic: () => {} },
@@ -127,12 +127,18 @@ it("skill show prints the packaged skill", async () => {
127
127
  expect(out).toContain(readFileSync(new URL("../skills/clidev-cli/SKILL.md", import.meta.url), "utf8").split("\n")[0])
128
128
  })
129
129
 
130
- it("mcp without a profile stops and says so", async () => {
131
- const { code, err } = await ran(["mcp", "--json"])
130
+ it("mcp serve without a profile stops and says so", async () => {
131
+ const { code, err } = await ran(["mcp", "serve", "--json"])
132
132
  expect(code).toBe(2)
133
133
  expect(err).toContain("validation_error")
134
134
  })
135
135
 
136
+ it("mcp alone only names its commands", async () => {
137
+ const { code, err } = await ran(["personal", "mcp", "--json"])
138
+ expect(code).toBe(2)
139
+ expect(err).toContain("--help")
140
+ })
141
+
136
142
  it("upgrade --check installs nothing when npm cannot be reached", async () => {
137
143
  const { code, out } = await ran(["upgrade", "--check", "--json"])
138
144
  expect(code).toBe(0)
package/src/roots.test.ts CHANGED
@@ -77,18 +77,13 @@ it("skill status and skill show --for read what skill install wrote", async () =
77
77
  expect((await ran(["skill", "install", "--for", "claude", "--json"])).code).toBe(0)
78
78
  const status = await ran(["skill", "status", "--json"])
79
79
  expect(status.code).toBe(0)
80
- // cli-core #2059 wraps skill answers in `{ item, meta }`; accept both until this CLI pins the release that ships it.
81
- const answer = (out: string) => {
82
- const body = JSON.parse(out)
83
- return body.item ?? body
84
- }
85
- expect(answer(status.out).targets).toEqual([
80
+ expect(JSON.parse(status.out).item.targets).toEqual([
86
81
  expect.objectContaining({ target: "claude", state: "current" }),
87
82
  expect.objectContaining({ target: "agents", installed: null, state: "missing" }),
88
83
  ])
89
84
  const shown = await ran(["skill", "show", "--for", "claude", "--json"])
90
85
  expect(shown.code).toBe(0)
91
- expect(answer(shown.out)).toMatchObject({
86
+ expect(JSON.parse(shown.out).item).toMatchObject({
92
87
  target: "claude",
93
88
  content: expect.stringContaining("name: clidev-cli"),
94
89
  })
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.8.0"
1
+ export const VERSION = "0.10.0"