@wirecat/cli-template 0.0.0-stage → 0.1.1

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 (132) hide show
  1. package/.github/dependabot.yml +23 -0
  2. package/.github/workflows/changelog-guard.yml +12 -0
  3. package/.github/workflows/ci.yml +88 -0
  4. package/.github/workflows/main.yml +17 -0
  5. package/.github/workflows/monthly.yml +28 -0
  6. package/.github/workflows/pr.yml +19 -0
  7. package/.github/workflows/release.yml +191 -0
  8. package/.github/workflows/standards.yml +51 -0
  9. package/.gitleaks.toml +5 -0
  10. package/.markdownlint-cli2.jsonc +7 -0
  11. package/.vale.ini +5 -0
  12. package/AGENTS.md +27 -0
  13. package/CHANGELOG.md +31 -0
  14. package/CLAUDE.md +17 -0
  15. package/LICENSE +204 -0
  16. package/README.md +52 -2
  17. package/SECURITY.md +15 -0
  18. package/bin/release +139 -0
  19. package/biome.json +6 -0
  20. package/config/wirecat/LICENSE +204 -0
  21. package/config/wirecat/biome.base.json +157 -0
  22. package/config/wirecat/check.mjs +41 -0
  23. package/config/wirecat/cspell.json +80 -0
  24. package/config/wirecat/lefthook.yml +26 -0
  25. package/config/wirecat/manifest.json +37 -0
  26. package/config/wirecat/markdownlint.json +10 -0
  27. package/config/wirecat/no-deep-wirecat-import.grit +15 -0
  28. package/config/wirecat/no-exec-interpolation.grit +17 -0
  29. package/config/wirecat/no-new-function.grit +8 -0
  30. package/config/wirecat/no-shell-true.grit +8 -0
  31. package/config/wirecat/no-sqlite-driver.grit +15 -0
  32. package/config/wirecat/no-unbounded-spread.grit +10 -0
  33. package/config/wirecat/release-lock-info.mjs +71 -0
  34. package/config/wirecat/release-lock.sh +34 -0
  35. package/config/wirecat/rumdl.toml +9 -0
  36. package/contracts/help.snap +16 -0
  37. package/contracts/mcp-tools.json +922 -0
  38. package/contracts/no-leak.json +3 -0
  39. package/contracts/plan.json +50 -0
  40. package/cspell.json +10 -0
  41. package/dist/bin/app.d.ts +3 -0
  42. package/dist/bin/app.d.ts.map +1 -0
  43. package/dist/bin/app.js +14 -0
  44. package/dist/bin/app.js.map +1 -0
  45. package/dist/commands/doctor.d.ts +23 -0
  46. package/dist/commands/doctor.d.ts.map +1 -0
  47. package/dist/commands/doctor.js +44 -0
  48. package/dist/commands/doctor.js.map +1 -0
  49. package/dist/commands/mcp.d.ts +3 -0
  50. package/dist/commands/mcp.d.ts.map +1 -0
  51. package/dist/commands/mcp.js +36 -0
  52. package/dist/commands/mcp.js.map +1 -0
  53. package/dist/config.d.ts +3 -0
  54. package/dist/config.d.ts.map +1 -0
  55. package/dist/config.js +4 -0
  56. package/dist/config.js.map +1 -0
  57. package/dist/identity.d.ts +5 -0
  58. package/dist/identity.d.ts.map +1 -0
  59. package/dist/identity.js +12 -0
  60. package/dist/identity.js.map +1 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +3 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/mcp.d.ts +19 -0
  66. package/dist/mcp.d.ts.map +1 -0
  67. package/dist/mcp.js +62 -0
  68. package/dist/mcp.js.map +1 -0
  69. package/dist/program.d.ts +6 -0
  70. package/dist/program.d.ts.map +1 -0
  71. package/dist/program.js +37 -0
  72. package/dist/program.js.map +1 -0
  73. package/dist/version.d.ts +2 -0
  74. package/dist/version.d.ts.map +1 -0
  75. package/dist/version.js +2 -0
  76. package/dist/version.js.map +1 -0
  77. package/docs/commands.md +227 -0
  78. package/docs/configuration.md +18 -0
  79. package/docs/dev/DESIGN.md +13 -0
  80. package/docs/dev/TESTING.md +16 -0
  81. package/docs/dev/design-questions.md +24 -0
  82. package/docs/dev/reference-clis.md +15 -0
  83. package/docs/dev/skills/design-interview/SKILL.md +34 -0
  84. package/docs/dev/skills/release/SKILL.md +24 -0
  85. package/docs/dev/test-matrix.md +52 -0
  86. package/docs/index.md +7 -0
  87. package/docs/installation.md +17 -0
  88. package/docs/meta.json +18 -0
  89. package/docs/security.md +8 -0
  90. package/docs/troubleshooting.md +14 -0
  91. package/docs/usage.md +31 -0
  92. package/gitignore +44 -0
  93. package/kit/README.md +127 -0
  94. package/kit/dist/interview.js +170 -0
  95. package/kit/dist/main.js +70 -0
  96. package/kit/dist/manifest.js +111 -0
  97. package/kit/dist/new.js +256 -0
  98. package/kit/dist/rename.js +36 -0
  99. package/kit/dist/source.js +98 -0
  100. package/kit/dist/upgrade.js +230 -0
  101. package/kit/tsconfig.json +17 -0
  102. package/kit/tsconfig.test.json +5 -0
  103. package/lefthook.yml +2 -0
  104. package/lint/baseline/.gitkeep +0 -0
  105. package/lint/overrides.json +1 -0
  106. package/package.json +106 -4
  107. package/pnpm-workspace.yaml +6 -0
  108. package/scripts/audit.sh +22 -0
  109. package/scripts/command-program.ts +1 -0
  110. package/scripts/commands.ts +39 -0
  111. package/scripts/smoke.ts +56 -0
  112. package/scripts/test-matrix-untested.ts +12 -0
  113. package/skills/app-cli/SKILL.md +21 -0
  114. package/src/bin/app.ts +13 -0
  115. package/src/commands/doctor.ts +45 -0
  116. package/src/commands/mcp.ts +38 -0
  117. package/src/config.ts +4 -0
  118. package/src/identity.ts +15 -0
  119. package/src/index.ts +2 -0
  120. package/src/mcp.test.ts +84 -0
  121. package/src/mcp.ts +82 -0
  122. package/src/program.test.ts +66 -0
  123. package/src/program.ts +53 -0
  124. package/src/roots.test.ts +80 -0
  125. package/src/testing/argv-log.ts +1 -0
  126. package/src/testing/sandbox.ts +25 -0
  127. package/src/version.ts +1 -0
  128. package/template.json +40 -0
  129. package/tsconfig.json +9 -0
  130. package/tsconfig.scripts.json +1 -0
  131. package/tsconfig.test.json +1 -0
  132. package/vitest.config.ts +19 -0
@@ -0,0 +1,23 @@
1
+ version: 2
2
+ updates:
3
+ # Actions are pinned by commit; this is what moves the pins forward.
4
+ - package-ecosystem: github-actions
5
+ directory: /
6
+ schedule:
7
+ interval: weekly
8
+ # The shared packages, at most a day after they ship, so `new` always copies a template on the latest ones.
9
+ - package-ecosystem: npm
10
+ directory: /
11
+ # Looks redundant, but it is what keeps `allow` off security updates: with target-branch set,
12
+ # GitHub stops applying this entry's options to them, so every vulnerable package gets a PR.
13
+ target-branch: main
14
+ schedule:
15
+ interval: daily
16
+ allow:
17
+ - dependency-name: "@wirecat/*"
18
+ groups:
19
+ shared:
20
+ patterns:
21
+ - "@wirecat/*"
22
+ commit-message:
23
+ prefix: "chore(deps)"
@@ -0,0 +1,12 @@
1
+ name: Changelog guard
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, edited, synchronize, reopened]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ changelog:
12
+ uses: WireCatLabs/cli-base/.github/workflows/changelog-guard.yml@70449547973dd113806a6829f4591dce713b5b78 # v0.51.1
@@ -0,0 +1,88 @@
1
+ name: Full validation
2
+
3
+ on:
4
+ workflow_call:
5
+ inputs:
6
+ pack:
7
+ type: boolean
8
+ default: false
9
+ platforms:
10
+ type: boolean
11
+ default: false
12
+ outputs:
13
+ package-sha256:
14
+ value: ${{ jobs.ci.outputs.package-sha256 }}
15
+ workflow_dispatch:
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ ci:
22
+ uses: WireCatLabs/cli-base/.github/workflows/node-ci.yml@70449547973dd113806a6829f4591dce713b5b78 # v0.51.1
23
+ with:
24
+ pack: ${{ inputs.pack || false }}
25
+ bun-run: pnpm build && pnpm smoke:bun
26
+ cli: true
27
+ bin: app
28
+ platforms: ${{ inputs.pack || inputs.platforms || github.event_name == 'workflow_dispatch' }}
29
+ platform-run: |
30
+ node dist/bin/app.js commands --json >/dev/null
31
+ node dist/bin/app.js doctor --json >/dev/null
32
+ # No version is on npm before the first release, so there is no earlier package to upgrade from.
33
+ skip: |
34
+ contracts:upgrade
35
+ checks: |
36
+ bash scripts/audit.sh
37
+
38
+ version:
39
+ if: github.event_name == 'pull_request'
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
43
+ with:
44
+ persist-credentials: false
45
+ - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
46
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
47
+ with:
48
+ node-version: 24
49
+ cache: pnpm
50
+ - run: pnpm install --frozen-lockfile --ignore-scripts
51
+ # A warning, never a failure: a version npm already has is refused by bin/release, not here.
52
+ - name: version above main and npm
53
+ continue-on-error: true
54
+ run: |
55
+ pr=$(node -p 'require("./package.json").version')
56
+ git fetch -q --depth=1 origin main
57
+ main=$(git show FETCH_HEAD:package.json | node -p 'JSON.parse(require("fs").readFileSync(0)).version')
58
+ [ "$pr" != "$main" ] || exit 0
59
+ name=$(node -p 'require("./package.json").name')
60
+ latest=$(npm view "$name" version 2>/dev/null || true)
61
+ versions=$(npm view "$name" versions --json 2>/dev/null) || versions=""
62
+ next=$(pnpm exec cli-dev next-version "$pr" "$latest" "$versions")
63
+ [ "$next" != "$pr" ] || exit 0
64
+ echo "::warning file=package.json::version $pr is not above npm's latest ($latest); the next free one is $next"
65
+
66
+ prose:
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
70
+ with:
71
+ persist-credentials: false
72
+ - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
73
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
74
+ with:
75
+ node-version: 24
76
+ cache: pnpm
77
+ - run: pnpm install --frozen-lockfile --ignore-scripts
78
+ - name: install vale
79
+ env:
80
+ VALE_VERSION: 3.23.0
81
+ VALE_SHA256: cc35445a45186b8f0b01e11c01359694cf941e72cf6ab0fc44774f0e54c9d5fc
82
+ run: |
83
+ curl -sSfLo vale.tar.gz "https://github.com/vale-cli/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz"
84
+ echo "${VALE_SHA256} vale.tar.gz" | sha256sum -c -
85
+ tar -xzf vale.tar.gz vale
86
+ # Style findings are annotations until the rules are tuned; the tone rule (an error) fails.
87
+ - run: ./vale --output line README.md docs/*.md | sed 's/^/::warning::/' || true
88
+ - run: ./vale --minAlertLevel error README.md docs/*.md
@@ -0,0 +1,17 @@
1
+ name: Main validation
2
+
3
+ # Nothing here publishes or tags: release.yml alone does that.
4
+ on:
5
+ push:
6
+ branches: [main]
7
+
8
+ concurrency:
9
+ group: main-validation-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ validation:
17
+ uses: ./.github/workflows/ci.yml
@@ -0,0 +1,28 @@
1
+ name: Monthly validation
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "41 3 1 * *"
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: monthly-${{ github.ref }}
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ validation:
17
+ uses: ./.github/workflows/ci.yml
18
+ with:
19
+ platforms: true
20
+ security:
21
+ permissions:
22
+ contents: read
23
+ actions: read
24
+ security-events: write
25
+ uses: WireCatLabs/cli-base/.github/workflows/release-checks.yml@70449547973dd113806a6829f4591dce713b5b78 # v0.51.1
26
+ with:
27
+ dependencies: true
28
+ languages: '["actions","javascript-typescript"]'
@@ -0,0 +1,19 @@
1
+ name: PR validation
2
+
3
+ # The whole Linux validation main.yml runs, on every pull request, so a change that breaks the coverage floor or a
4
+ # check fails here and never reaches main (WC-CI-5).
5
+ on:
6
+ pull_request:
7
+ types: [opened, synchronize, reopened, ready_for_review]
8
+
9
+ concurrency:
10
+ group: pr-validation-${{ github.event.pull_request.number }}
11
+ cancel-in-progress: true
12
+
13
+ permissions: {}
14
+
15
+ jobs:
16
+ validation:
17
+ permissions:
18
+ contents: read
19
+ uses: ./.github/workflows/ci.yml
@@ -0,0 +1,191 @@
1
+ name: Release
2
+
3
+ # Started by bin/release. npm trusts this file by name (trusted publishing), so there is no npm
4
+ # token anywhere in this repository and renaming the file breaks publishing until npm is told.
5
+ #
6
+ # Full validation builds, checks and packs once; `build` verifies the immutable tarball.
7
+ # The job able to publish runs no code from our dependencies; `publish` holds the OIDC permission and only
8
+ # runs `npm publish` on that file; `tag` is the only one that may write to the repository.
9
+ on:
10
+ workflow_dispatch:
11
+ inputs:
12
+ dry_run:
13
+ description: "Build and pack, run npm publish --dry-run, do not tag"
14
+ type: boolean
15
+ default: false
16
+ commit:
17
+ description: "The commit bin/release checked; the run refuses any other"
18
+ type: string
19
+ default: ""
20
+
21
+ permissions: {}
22
+
23
+ concurrency:
24
+ group: release
25
+ cancel-in-progress: false
26
+
27
+ jobs:
28
+ # Every job builds github.sha, the tip of main when the run started — which a merge can move past the commit
29
+ # bin/release checked.
30
+ checked-commit:
31
+ runs-on: ubuntu-latest
32
+ permissions: {}
33
+ steps:
34
+ - env:
35
+ COMMIT: ${{ inputs.commit }}
36
+ DRY_RUN: ${{ inputs.dry_run }}
37
+ run: |
38
+ [ "$COMMIT" = "$GITHUB_SHA" ] && exit 0
39
+ [ "$DRY_RUN" = "true" ] && [ -z "$COMMIT" ] && exit 0
40
+ echo "::error::this run is at $GITHUB_SHA, but bin/release checked '${COMMIT}' — nothing is published"
41
+ exit 1
42
+
43
+ validation:
44
+ needs: checked-commit
45
+ if: github.ref == 'refs/heads/main' || inputs.dry_run
46
+ permissions:
47
+ contents: read
48
+ uses: ./.github/workflows/ci.yml
49
+ with:
50
+ pack: true
51
+
52
+ checks:
53
+ needs: checked-commit
54
+ if: github.ref == 'refs/heads/main' || inputs.dry_run
55
+ permissions:
56
+ contents: read
57
+ actions: read
58
+ security-events: write
59
+ uses: WireCatLabs/cli-base/.github/workflows/release-checks.yml@70449547973dd113806a6829f4591dce713b5b78 # v0.51.1
60
+
61
+ build:
62
+ needs: [checks, validation]
63
+ if: github.ref == 'refs/heads/main' || inputs.dry_run
64
+ runs-on: ubuntu-latest
65
+ permissions:
66
+ contents: read
67
+ outputs:
68
+ version: ${{ steps.version.outputs.version }}
69
+ name: ${{ steps.version.outputs.name }}
70
+ steps:
71
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
72
+ with:
73
+ persist-credentials: false
74
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
75
+ with:
76
+ node-version: 24
77
+ package-manager-cache: false
78
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
79
+ with:
80
+ name: validated-package
81
+ path: validated
82
+ - name: Verify validated package integrity
83
+ env:
84
+ EXPECTED_SHA256: ${{ needs.validation.outputs.package-sha256 }}
85
+ run: |
86
+ set -- ./validated/*.tgz
87
+ [ "$#" -eq 1 ] && [ -f "$1" ] || { echo "Expected exactly one package tarball"; exit 1; }
88
+ [ -n "$EXPECTED_SHA256" ] || { echo "Missing validation digest"; exit 1; }
89
+ printf '%s %s\n' "$EXPECTED_SHA256" "$1" | sha256sum --check -
90
+
91
+ # A 404 for a package npm has never seen means "not published yet", the same as a missing version.
92
+ - name: version not yet on npm
93
+ id: version
94
+ env:
95
+ DRY_RUN: ${{ inputs.dry_run }}
96
+ run: |
97
+ version=$(node -p 'require("./package.json").version')
98
+ name=$(node -p 'require("./package.json").name')
99
+ echo "version=$version" >> "$GITHUB_OUTPUT"
100
+ echo "name=$name" >> "$GITHUB_OUTPUT"
101
+ if [ "$DRY_RUN" != "true" ] && npm view "$name@$version" version --prefer-online >/dev/null 2>&1; then
102
+ echo "::error::$version is already on npm — raise the version first"
103
+ exit 1
104
+ fi
105
+
106
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
107
+ with:
108
+ name: package
109
+ path: validated/*.tgz
110
+ if-no-files-found: error
111
+ retention-days: 7
112
+
113
+ package-dry-run:
114
+ needs: build
115
+ if: inputs.dry_run
116
+ runs-on: ubuntu-latest
117
+ permissions:
118
+ contents: read
119
+ steps:
120
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
121
+ with:
122
+ node-version: 24
123
+ package-manager-cache: false
124
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
125
+ with:
126
+ name: package
127
+ # Permit checking an already published version; this job has no publishing permissions.
128
+ - run: npm publish ./*.tgz --access public --dry-run --force
129
+
130
+ publish:
131
+ needs: build
132
+ if: ${{ !inputs.dry_run }}
133
+ runs-on: ubuntu-latest
134
+ environment: npm
135
+ permissions:
136
+ id-token: write
137
+ env:
138
+ VERSION: ${{ needs.build.outputs.version }}
139
+ NAME: ${{ needs.build.outputs.name }}
140
+ steps:
141
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
142
+ with:
143
+ node-version: 24
144
+ registry-url: https://registry.npmjs.org
145
+ package-manager-cache: false
146
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
147
+ with:
148
+ name: package
149
+
150
+ # npm, not pnpm: npm's trusted publishing is the documented path. A tarball runs no
151
+ # lifecycle scripts, and nothing is installed here. A tarball path needs its ./.
152
+ - run: |
153
+ set -- ./*.tgz
154
+ npm publish "$1" --access public
155
+
156
+ - name: wait for npm to show the version
157
+ run: |
158
+ # The version's own document, not `npm view`: on 2026-10-01 the document answered while the
159
+ # version list `npm view` reads was still stale for minutes.
160
+ encoded=$(node -p 'encodeURIComponent(process.argv[1]).replace("%40", "@")' "$NAME")
161
+ for _ in $(seq 90); do
162
+ curl -sfo /dev/null "https://registry.npmjs.org/$encoded/$VERSION" && exit 0
163
+ sleep 10
164
+ done
165
+ echo "::error::npm does not show $VERSION after fifteen minutes — not tagging; tag v$VERSION by hand once it does"
166
+ exit 1
167
+
168
+ tag:
169
+ needs: [build, publish]
170
+ if: ${{ !inputs.dry_run }}
171
+ runs-on: ubuntu-latest
172
+ permissions:
173
+ contents: write
174
+ env:
175
+ VERSION: ${{ needs.build.outputs.version }}
176
+ steps:
177
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
178
+
179
+ - name: tag
180
+ run: |
181
+ git config user.name "github-actions[bot]"
182
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
183
+ git tag -a "v$VERSION" -m "$VERSION"
184
+ git push origin "v$VERSION"
185
+
186
+ - name: GitHub release from the changelog
187
+ env:
188
+ GH_TOKEN: ${{ github.token }}
189
+ run: |
190
+ awk -v v="$VERSION" '$0 ~ "^## "v" " {on=1; next} /^## / && on {exit} on' CHANGELOG.md |
191
+ gh release create "v$VERSION" --title "$VERSION" --notes-file -
@@ -0,0 +1,51 @@
1
+ name: Shared standards
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: fast-${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ standards:
17
+ runs-on: ubuntu-latest
18
+ timeout-minutes: 5
19
+ steps:
20
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ fetch-depth: 0
23
+ persist-credentials: false
24
+ - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
25
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
26
+ with:
27
+ node-version: 24
28
+ cache: pnpm
29
+ - run: pnpm install --frozen-lockfile --ignore-scripts
30
+ - run: pnpm standards:check
31
+ - run: pnpm lint
32
+ - run: pnpm docs:lint
33
+ - name: Early bug checks
34
+ timeout-minutes: 2
35
+ run: pnpm run --if-present ci:quick
36
+ - name: Scan new commits for secrets
37
+ env:
38
+ BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
39
+ HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
40
+ GITLEAKS_VERSION: 8.30.1
41
+ GITLEAKS_SHA256: 551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb
42
+ run: |
43
+ curl -sSfLo gitleaks.tar.gz "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
44
+ echo "${GITLEAKS_SHA256} gitleaks.tar.gz" | sha256sum -c -
45
+ tar -xzf gitleaks.tar.gz gitleaks
46
+ if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then
47
+ range="$HEAD_SHA^!"
48
+ else
49
+ range="$BASE_SHA..$HEAD_SHA"
50
+ fi
51
+ ./gitleaks git --log-opts="$range" --no-banner --redact --exit-code 1 .
package/.gitleaks.toml ADDED
@@ -0,0 +1,5 @@
1
+ [extend]
2
+ useDefault = true
3
+
4
+ [allowlist]
5
+ paths = ['''pnpm-lock\.yaml''']
@@ -0,0 +1,7 @@
1
+ {
2
+ "globs": ["README.md", "SECURITY.md", "AGENTS.md", "CLAUDE.md", "docs/*.md", "docs/dev/**/*.md", "skills/**/*.md"],
3
+ "ignores": ["node_modules", "dist", ".worktrees", "config/wirecat", "docs/commands.md", "docs/dev/test-matrix.md"],
4
+ "config": {
5
+ "extends": "./config/wirecat/markdownlint.json"
6
+ }
7
+ }
package/.vale.ini ADDED
@@ -0,0 +1,5 @@
1
+ StylesPath = node_modules/@wirecat/cli-base/config/vale
2
+ MinAlertLevel = warning
3
+
4
+ [*.md]
5
+ BasedOnStyles = CliDocs
package/AGENTS.md ADDED
@@ -0,0 +1,27 @@
1
+ # Working rules for agents
2
+
3
+ The [WireCat CLI standards](node_modules/@wirecat/cli-base/docs/standards/README.md) apply here and win over this
4
+ file and over every other document in this repository. The handbook ships inside `@wirecat/cli-base`; run
5
+ `pnpm install` first. Read the page for the area you change before changing it, and cite the rule ids the change
6
+ touches (`WC-<AREA>-<n>`) in the commit message and the pull request. The rules of this CLI alone are in
7
+ [CLAUDE.md](CLAUDE.md).
8
+
9
+ ## Before building anything
10
+
11
+ This CLI was made from [cli-template](https://github.com/WireCatLabs/cli-template). Its first task is the design:
12
+
13
+ 1. Read [docs/dev/DESIGN.md](docs/dev/DESIGN.md). If the seven answers are not there, ask the owner the
14
+ [design interview](docs/dev/skills/design-interview/SKILL.md) and write them down.
15
+ 2. Learn from the reference CLI below. Copy its patterns for the provider, the store and the commands; the
16
+ template has no sample code on purpose.
17
+ 3. Ask the further questions in the interview that the reference CLI does not answer. Build only after the owner
18
+ has read `DESIGN.md`.
19
+
20
+ <!-- cli-template:reference-cli:start -->
21
+ The reference CLI is not chosen yet; see [Reference CLIs](docs/dev/reference-clis.md).
22
+ <!-- cli-template:reference-cli:end -->
23
+
24
+ ## Template-owned files
25
+
26
+ `template.json` names the files `npx @wirecat/cli-template upgrade` keeps in step with the template. Change one of
27
+ them here only when this CLI needs to differ; `upgrade` asks before it touches your change.
package/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ Notable changes to `@wirecat/cli-template`. One section per version, newest first; versions follow
4
+ [semantic versioning](https://semver.org), so before `1.0.0` the skeleton may still change.
5
+
6
+ ## 0.1.1 — 25.10.2026
7
+
8
+ ### Fixed
9
+
10
+ - **`npx @wirecat/cli-template new` works.** It stopped with `template.json lists ".gitignore", but the package has
11
+ no such file`, because npm renames `.gitignore` when it installs a package. The package now ships the file under
12
+ another name, and `new` and `upgrade` write it as `.gitignore`.
13
+ - **`new` and `upgrade` work on Windows.** `new` now marks `bin/release` and the other scripts as executable in
14
+ git, so a CLI made on Windows can still run them on Linux and macOS. `upgrade` no longer reads every file as
15
+ edited when git checked it out with Windows line endings, and it downloads the earlier template version without
16
+ needing a shell for `npm`.
17
+
18
+ ## 0.1.0 — 25.10.2026
19
+
20
+ ### Added
21
+
22
+ - **A working skeleton for a new WireCat CLI.** The shared root commands `commands`, `doctor`, `skill`, `mcp` and
23
+ `upgrade`, and `config`, on cli-base and cli-core. Every example names its profile; the MCP server offers every
24
+ command, writes included, and the profile's permissions decide what runs.
25
+ - **The checks of the WireCat standards, from the first commit.** CI runs lint, the type check, tests with coverage,
26
+ the command lint and audit, the contracts, the test matrix, the docs checks and the changelog guard.
27
+ - **`npx @wirecat/cli-template new` and `upgrade`.** `new` copies the template into a new folder, renames it, asks
28
+ the seven design questions (or takes them as flags) and prints the four steps that need a person. `upgrade` brings
29
+ later template changes into a CLI made from it, file by file: apply, replace, skip or diff.
30
+ - **A design interview for the agent that builds the new CLI**, and a page that names the CLI to learn from for each
31
+ kind of tool.
package/CLAUDE.md ADDED
@@ -0,0 +1,17 @@
1
+ # app — working rules
2
+
3
+ The [WireCat CLI standards](node_modules/@wirecat/cli-base/docs/standards/README.md) apply here and win over this
4
+ file; it keeps only the rules of `app` itself. Start with [AGENTS.md](AGENTS.md).
5
+
6
+ **What cli-core already does, this repository does not do again** — commands, the store, search, MCP and the
7
+ permissions. A gap in cli-core is fixed in cli-core.
8
+
9
+ ## Local rules
10
+
11
+ None yet. Add a rule here only when it holds for `app` alone, and link the handbook rule it narrows.
12
+
13
+ ## Private working folder
14
+
15
+ Plans, research and journals do not go into this repository. For WireCat's own CLIs they live in the private
16
+ repository `WireCatLabs/cli-private`, linked or cloned into `docs_ai/`, which git ignores. Elsewhere, keep them in a
17
+ folder of your own outside the repository.