@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.
- package/.github/dependabot.yml +23 -0
- package/.github/workflows/changelog-guard.yml +12 -0
- package/.github/workflows/ci.yml +88 -0
- package/.github/workflows/main.yml +17 -0
- package/.github/workflows/monthly.yml +28 -0
- package/.github/workflows/pr.yml +19 -0
- package/.github/workflows/release.yml +191 -0
- package/.github/workflows/standards.yml +51 -0
- package/.gitleaks.toml +5 -0
- package/.markdownlint-cli2.jsonc +7 -0
- package/.vale.ini +5 -0
- package/AGENTS.md +27 -0
- package/CHANGELOG.md +31 -0
- package/CLAUDE.md +17 -0
- package/LICENSE +204 -0
- package/README.md +52 -2
- package/SECURITY.md +15 -0
- package/bin/release +139 -0
- package/biome.json +6 -0
- package/config/wirecat/LICENSE +204 -0
- package/config/wirecat/biome.base.json +157 -0
- package/config/wirecat/check.mjs +41 -0
- package/config/wirecat/cspell.json +80 -0
- package/config/wirecat/lefthook.yml +26 -0
- package/config/wirecat/manifest.json +37 -0
- package/config/wirecat/markdownlint.json +10 -0
- package/config/wirecat/no-deep-wirecat-import.grit +15 -0
- package/config/wirecat/no-exec-interpolation.grit +17 -0
- package/config/wirecat/no-new-function.grit +8 -0
- package/config/wirecat/no-shell-true.grit +8 -0
- package/config/wirecat/no-sqlite-driver.grit +15 -0
- package/config/wirecat/no-unbounded-spread.grit +10 -0
- package/config/wirecat/release-lock-info.mjs +71 -0
- package/config/wirecat/release-lock.sh +34 -0
- package/config/wirecat/rumdl.toml +9 -0
- package/contracts/help.snap +16 -0
- package/contracts/mcp-tools.json +922 -0
- package/contracts/no-leak.json +3 -0
- package/contracts/plan.json +50 -0
- package/cspell.json +10 -0
- package/dist/bin/app.d.ts +3 -0
- package/dist/bin/app.d.ts.map +1 -0
- package/dist/bin/app.js +14 -0
- package/dist/bin/app.js.map +1 -0
- package/dist/commands/doctor.d.ts +23 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +44 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +36 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -0
- package/dist/identity.d.ts +5 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +12 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +19 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +62 -0
- package/dist/mcp.js.map +1 -0
- package/dist/program.d.ts +6 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +37 -0
- package/dist/program.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/commands.md +227 -0
- package/docs/configuration.md +18 -0
- package/docs/dev/DESIGN.md +13 -0
- package/docs/dev/TESTING.md +16 -0
- package/docs/dev/design-questions.md +24 -0
- package/docs/dev/reference-clis.md +15 -0
- package/docs/dev/skills/design-interview/SKILL.md +34 -0
- package/docs/dev/skills/release/SKILL.md +24 -0
- package/docs/dev/test-matrix.md +52 -0
- package/docs/index.md +7 -0
- package/docs/installation.md +17 -0
- package/docs/meta.json +18 -0
- package/docs/security.md +8 -0
- package/docs/troubleshooting.md +14 -0
- package/docs/usage.md +31 -0
- package/gitignore +44 -0
- package/kit/README.md +127 -0
- package/kit/dist/interview.js +170 -0
- package/kit/dist/main.js +70 -0
- package/kit/dist/manifest.js +111 -0
- package/kit/dist/new.js +256 -0
- package/kit/dist/rename.js +36 -0
- package/kit/dist/source.js +98 -0
- package/kit/dist/upgrade.js +230 -0
- package/kit/tsconfig.json +17 -0
- package/kit/tsconfig.test.json +5 -0
- package/lefthook.yml +2 -0
- package/lint/baseline/.gitkeep +0 -0
- package/lint/overrides.json +1 -0
- package/package.json +106 -4
- package/pnpm-workspace.yaml +6 -0
- package/scripts/audit.sh +22 -0
- package/scripts/command-program.ts +1 -0
- package/scripts/commands.ts +39 -0
- package/scripts/smoke.ts +56 -0
- package/scripts/test-matrix-untested.ts +12 -0
- package/skills/app-cli/SKILL.md +21 -0
- package/src/bin/app.ts +13 -0
- package/src/commands/doctor.ts +45 -0
- package/src/commands/mcp.ts +38 -0
- package/src/config.ts +4 -0
- package/src/identity.ts +15 -0
- package/src/index.ts +2 -0
- package/src/mcp.test.ts +84 -0
- package/src/mcp.ts +82 -0
- package/src/program.test.ts +66 -0
- package/src/program.ts +53 -0
- package/src/roots.test.ts +80 -0
- package/src/testing/argv-log.ts +1 -0
- package/src/testing/sandbox.ts +25 -0
- package/src/version.ts +1 -0
- package/template.json +40 -0
- package/tsconfig.json +9 -0
- package/tsconfig.scripts.json +1 -0
- package/tsconfig.test.json +1 -0
- 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,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
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.
|