@wirecat/cli-template 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.
Files changed (49) hide show
  1. package/.github/workflows/changelog-guard.yml +1 -1
  2. package/.github/workflows/ci.yml +7 -3
  3. package/.github/workflows/main.yml +2 -1
  4. package/.markdownlint-cli2.jsonc +11 -1
  5. package/AGENTS.md +2 -0
  6. package/CHANGELOG.md +56 -0
  7. package/README.md +26 -6
  8. package/SECURITY.md +1 -1
  9. package/bin/release +24 -3
  10. package/config/parity-groups.json +6 -0
  11. package/contracts/help.snap +2 -2
  12. package/contracts/mcp-tools.json +2 -2
  13. package/cspell.json +1 -1
  14. package/dist/commands/doctor.d.ts +69 -36
  15. package/dist/commands/doctor.d.ts.map +1 -1
  16. package/dist/commands/doctor.js +42 -15
  17. package/dist/commands/doctor.js.map +1 -1
  18. package/dist/mcp.js +1 -1
  19. package/dist/mcp.js.map +1 -1
  20. package/dist/version.d.ts +1 -1
  21. package/dist/version.js +1 -1
  22. package/docs/commands.md +22 -6
  23. package/docs/configuration.md +1 -1
  24. package/docs/dev/TESTING.md +2 -0
  25. package/docs/dev/skills/release/SKILL.md +3 -1
  26. package/docs/dev/test-matrix.md +3 -1
  27. package/docs/index.md +3 -3
  28. package/docs/installation.md +3 -3
  29. package/docs/security.md +6 -2
  30. package/docs/troubleshooting.md +2 -1
  31. package/docs/usage.md +1 -1
  32. package/kit/dist/main.js +1 -1
  33. package/kit/dist/manifest.js +18 -30
  34. package/kit/dist/new.js +14 -6
  35. package/kit/dist/rename.js +1 -0
  36. package/kit/dist/source.js +7 -4
  37. package/package.json +8 -7
  38. package/pnpm-workspace.yaml +2 -0
  39. package/scripts/commands.ts +1 -1
  40. package/scripts/docs-rules.ts +1 -1
  41. package/scripts/smoke.ts +19 -10
  42. package/skills/clidev-cli/SKILL.md +3 -3
  43. package/src/commands/doctor.ts +53 -16
  44. package/src/mcp.ts +1 -1
  45. package/src/program.test.ts +35 -2
  46. package/src/roots.test.ts +16 -0
  47. package/src/testing/sandbox.ts +4 -7
  48. package/src/version.ts +1 -1
  49. package/vitest.config.ts +3 -1
@@ -1,4 +1,4 @@
1
- import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
1
+ import { chmodSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs"
2
2
  import { join } from "node:path"
3
3
  import { expect, it } from "vitest"
4
4
  import { doctorReport } from "./commands/doctor.js"
@@ -58,10 +58,43 @@ it("doctor reports an unknown setting with the command that removes it", async (
58
58
  })
59
59
 
60
60
  it("doctor reports settings an environment variable breaks, and still answers", () => {
61
- const report = doctorReport({ ...process.env, CLIDEV_EMBEDDING_DIMS: "many" })
61
+ const { report } = doctorReport({ ...process.env, CLIDEV_EMBEDDING_DIMS: "many" })
62
62
  expect(report).toMatchObject({ config: { issues: [] }, settings: { error: expect.any(String) }, profiles: null })
63
63
  })
64
64
 
65
+ it.skipIf(process.platform === "win32")(
66
+ "doctor names a config file and folder others can read, with the chmod that fixes each",
67
+ async () => {
68
+ const dir = process.env.CLIDEV_CONFIG_DIR ?? ""
69
+ const file = join(dir, "config.json")
70
+ mkdirSync(dir, { recursive: true })
71
+ writeFileSync(file, "{}")
72
+ chmodSync(file, 0o644)
73
+ chmodSync(dir, 0o775)
74
+ try {
75
+ const { code, out, err } = await ran(["doctor", "--json"])
76
+ expect(code).toBe(0)
77
+ expect(json(out).item.files).toEqual({
78
+ checked: true,
79
+ ok: false,
80
+ problems: [
81
+ { path: file, mode: "0644", want: "0600" },
82
+ { path: dir, mode: "0775", want: "0700" },
83
+ ],
84
+ })
85
+ expect(err).toContain(`to make it private: chmod 600 '${file}'`)
86
+ expect(err).toContain(`to make it private: chmod 700 '${dir}'`)
87
+
88
+ chmodSync(dir, 0o700)
89
+ expect((await ran(["personal", "config", "set", "--defaults", "limit", "5"])).code).toBe(0)
90
+ expect(statSync(file).mode & 0o777).toBe(0o600)
91
+ expect(json((await ran(["doctor", "--json"])).out).item.files).toEqual({ checked: true, ok: true, problems: [] })
92
+ } finally {
93
+ rmSync(file)
94
+ }
95
+ },
96
+ )
97
+
65
98
  it("config show names the profile it was given", async () => {
66
99
  const { code, out } = await ran(["personal", "config", "show", "--json"])
67
100
  expect(code).toBe(0)
package/src/roots.test.ts CHANGED
@@ -73,6 +73,22 @@ it("skill install writes the skill for Claude Code", async () => {
73
73
  expect(existsSync(join(homedir(), ".claude", "skills", "clidev-cli", "SKILL.md"))).toBe(true)
74
74
  })
75
75
 
76
+ it("skill status and skill show --for read what skill install wrote", async () => {
77
+ expect((await ran(["skill", "install", "--for", "claude", "--json"])).code).toBe(0)
78
+ const status = await ran(["skill", "status", "--json"])
79
+ expect(status.code).toBe(0)
80
+ expect(JSON.parse(status.out).targets).toEqual([
81
+ expect.objectContaining({ target: "claude", state: "current" }),
82
+ expect.objectContaining({ target: "agents", installed: null, state: "missing" }),
83
+ ])
84
+ const shown = await ran(["skill", "show", "--for", "claude", "--json"])
85
+ expect(shown.code).toBe(0)
86
+ expect(JSON.parse(shown.out)).toMatchObject({
87
+ target: "claude",
88
+ content: expect.stringContaining("name: clidev-cli"),
89
+ })
90
+ })
91
+
76
92
  it("help prints the first screen", async () => {
77
93
  const { code, out } = await ran(["help"])
78
94
  expect(code).toBe(0)
@@ -5,13 +5,10 @@ import { ARGV_LOG } from "./argv-log.js"
5
5
 
6
6
  const saved = { ...process.env }
7
7
 
8
- // cli-base's setup already gave this file a fresh TMPDIR and HOME, a keyring that throws and no network.
9
- const sandbox = tmpdir()
10
- process.env.CLIDEV_CONFIG_DIR = join(sandbox, "config")
11
- process.env.CLIDEV_STATE_DIR = join(sandbox, "state")
12
- process.env.CLIDEV_CACHE_DIR = join(sandbox, "cache")
13
- process.env.MESSAGING_STORE = join(sandbox, "messages.db")
14
- process.env.WIRECAT_STATE_DIR = join(sandbox, "wirecat")
8
+ // cli-base's setup already gave this file a fresh TMPDIR and HOME, a keyring that throws and no network, and points
9
+ // every folder and store variable at them (WC-TEST-1, WC-STORE-14). The config folder is set only because tests
10
+ // write into it by name.
11
+ process.env.CLIDEV_CONFIG_DIR = join(tmpdir(), "config")
15
12
  process.env.CLIDEV_NO_UPDATE_CHECK = "1"
16
13
  process.env.CLIDEV_TEST_ARGV_LOG = ARGV_LOG
17
14
  delete process.env.CLIDEV_PROFILE
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.1.5"
1
+ export const VERSION = "0.1.7"
package/vitest.config.ts CHANGED
@@ -10,13 +10,15 @@ export default defineConfig({
10
10
  globalSetup: ["src/testing/argv-log.ts"],
11
11
  coverage: {
12
12
  provider: "v8",
13
- include: ["src/**/*.ts"],
13
+ include: ["src/**/*.ts", "kit/src/**/*.ts"],
14
14
  exclude: [
15
15
  "src/**/*.test.ts",
16
16
  // Test setup: the sandbox and the argv log run only under vitest.
17
17
  "src/testing/**",
18
18
  // The entry point: one line handing argv to run(), which the suite drives directly.
19
19
  "src/bin/**",
20
+ // The kit's entry point runs only as a separate process, in kit/test/package.test.ts.
21
+ "kit/src/main.ts",
20
22
  ],
21
23
  reporter: ["text-summary", "json-summary"],
22
24
  thresholds: { lines: 90, statements: 90, functions: 80, branches: 70, perFile: { lines: 50 } },