2026-03-02 14:59:16 +01:00
|
|
|
output:
|
|
|
|
|
- meta
|
|
|
|
|
- summary
|
|
|
|
|
- success
|
|
|
|
|
- failure
|
|
|
|
|
- execution
|
|
|
|
|
- execution_out
|
|
|
|
|
- execution_info
|
|
|
|
|
- skips
|
|
|
|
|
|
2026-02-24 15:17:21 +01:00
|
|
|
pre-commit:
|
2026-03-02 16:41:23 +01:00
|
|
|
parallel: true
|
2026-02-24 15:17:21 +01:00
|
|
|
commands:
|
2026-03-06 09:14:21 -08:00
|
|
|
check-binaries:
|
|
|
|
|
tags: binaries
|
2026-04-17 12:55:00 +02:00
|
|
|
run: bash scripts/hooks/check-binaries.sh
|
feat(showcase): self-maintaining promote service dropdown generator
Add showcase/scripts/sync-promote-service-options.ts: generates the
promote workflow's service `choice` options from the SSOT
(railway-envs.ts), spliced between BEGIN/END markers in
showcase_promote.yml. Fail-loud throughout — every emitted token must
resolve to exactly one service under the resolve-step predicate
(name|dispatchName match AND probe.prod), tokens are YAML-safe, args are
strict (a typo'd flag cannot trigger a destructive write), and markers
are validated before any rewrite.
Wire it into a lefthook pre-commit hook (regenerate + restage; set -e so
a failed regen blocks the commit) and an advisory (never-failing) drift
check in showcase_validate.yml. Vitest coverage for ordering, exclusion,
collision/ambiguity guards, marker errors, exit codes, idempotency, and
the import-side-effect guard.
2026-06-02 12:50:07 -07:00
|
|
|
sync-promote-dropdown:
|
|
|
|
|
tags: promote-dropdown
|
|
|
|
|
# Regenerate the showcase_promote.yml `service` dropdown from the
|
|
|
|
|
# railway-envs.ts SSOT and re-stage it so the option list can never
|
|
|
|
|
# drift from the set of promotable services. Plain regenerate + git add
|
|
|
|
|
# (no stash) — keep this hook worktree-safe; lefthook's shared
|
|
|
|
|
# refs/stash is not safe across concurrent worktree commits.
|
2026-06-02 19:51:29 +00:00
|
|
|
glob: "{showcase/scripts/railway-envs.ts,showcase/scripts/sync-promote-service-options.ts,.github/workflows/showcase_promote.yml}"
|
feat(showcase): self-maintaining promote service dropdown generator
Add showcase/scripts/sync-promote-service-options.ts: generates the
promote workflow's service `choice` options from the SSOT
(railway-envs.ts), spliced between BEGIN/END markers in
showcase_promote.yml. Fail-loud throughout — every emitted token must
resolve to exactly one service under the resolve-step predicate
(name|dispatchName match AND probe.prod), tokens are YAML-safe, args are
strict (a typo'd flag cannot trigger a destructive write), and markers
are validated before any rewrite.
Wire it into a lefthook pre-commit hook (regenerate + restage; set -e so
a failed regen blocks the commit) and an advisory (never-failing) drift
check in showcase_validate.yml. Vitest coverage for ordering, exclusion,
collision/ambiguity guards, marker errors, exit codes, idempotency, and
the import-side-effect guard.
2026-06-02 12:50:07 -07:00
|
|
|
run: |
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
pnpm exec tsx showcase/scripts/sync-promote-service-options.ts \
|
|
|
|
|
&& git add .github/workflows/showcase_promote.yml
|
2026-03-02 16:24:48 +01:00
|
|
|
sync-lockfile:
|
|
|
|
|
tags: lockfile
|
2026-04-24 21:24:26 -07:00
|
|
|
glob: "{packages,examples,showcase/scripts}/**/package.json"
|
2026-03-02 16:24:48 +01:00
|
|
|
run: pnpm i --lockfile-only
|
|
|
|
|
stage_fixed: true
|
2026-02-24 15:17:21 +01:00
|
|
|
lint-fix:
|
2026-03-02 15:56:37 +01:00
|
|
|
tags: lint
|
2026-04-22 10:09:51 -07:00
|
|
|
# Scope oxlint and oxfmt to just the files staged for commit — running
|
|
|
|
|
# `--fix .` / `--write .` across the whole monorepo on every commit is
|
|
|
|
|
# both slow and blurs the hook's purpose (touch files that aren't part
|
|
|
|
|
# of this change). Guard against empty `{staged_files}` expansion: when
|
|
|
|
|
# a commit touches only non-matching files (markdown, YAML), lefthook
|
|
|
|
|
# still invokes this hook with an empty expansion, and oxlint/oxfmt
|
|
|
|
|
# would default to operating on the current directory, defeating the
|
|
|
|
|
# scoping entirely. stage_fixed re-stages whatever the hooks modify.
|
2026-05-27 13:49:31 -07:00
|
|
|
# Intentionally excludes json/jsonc/json5: oxfmt --write rewrites JSON
|
|
|
|
|
# files into JSON5 syntax (4-space indent, trailing commas, compact
|
|
|
|
|
# objects) when invoked via lefthook with staged file paths. The result
|
|
|
|
|
# is invalid strict JSON that pnpm rejects with ERR_PNPM_JSON_PARSE,
|
|
|
|
|
# blocking every commit that touches a package.json (see PRs #5054,
|
|
|
|
|
# #5055). JSON formatting is owned by pnpm/manual editing; oxfmt has
|
|
|
|
|
# no per-file knobs to keep package.json valid, so the only safe fix
|
|
|
|
|
# is to keep .json* out of this hook entirely.
|
|
|
|
|
glob: "*.{js,jsx,ts,tsx,mjs,cjs,md,css,yml,yaml,html,vue,py}"
|
2026-06-18 10:54:16 -07:00
|
|
|
# Mirror the generated-data ignorePatterns in .oxlintrc.json /
|
|
|
|
|
# .oxfmtrc.json at the hook layer.
|
2026-04-22 17:31:03 -07:00
|
|
|
exclude:
|
2026-05-26 11:26:45 -07:00
|
|
|
- "showcase/aimock/shared/**"
|
|
|
|
|
- "showcase/aimock/d4/**"
|
|
|
|
|
- "showcase/aimock/d6/**"
|
2026-05-19 15:28:07 +00:00
|
|
|
# Use `set --` so the staged files become positional args; this is the
|
|
|
|
|
# only shell-portable way to test "are there any" without breaking on
|
|
|
|
|
# multi-file expansion. The old `[ -n "{staged_files}" ]` form failed
|
|
|
|
|
# with `sh: 1: [: <path>: unexpected operator` because lefthook
|
|
|
|
|
# interpolates the file list as space-separated words, not a single
|
|
|
|
|
# quoted string, so [ saw 3+ args and tried to parse a binary op.
|
2026-06-15 15:37:03 +02:00
|
|
|
# IMPORTANT: keep this script DOUBLE-QUOTE-FREE. lefthook invokes a
|
|
|
|
|
# multi-line `run` as `sh -c "<script>"` and (in some versions / on
|
|
|
|
|
# Windows git-sh) does not escape embedded double quotes, so any `"$@"`
|
|
|
|
|
# / `[ "$#" ]` / `x=""` prematurely closes the `-c "…"` string and the
|
|
|
|
|
# shell aborts with `unexpected EOF`. Use unquoted `$@`/`$#` — staged
|
|
|
|
|
# paths in this monorepo never contain spaces. JSON is excluded from the
|
|
|
|
|
# glob above, so oxfmt never receives package.json (the old explicit
|
|
|
|
|
# package.json filter is unnecessary). ruff is scoped to .py via `case`.
|
2026-04-22 10:09:51 -07:00
|
|
|
run: |
|
2026-06-18 10:54:16 -07:00
|
|
|
files=
|
|
|
|
|
for f in {staged_files}; do
|
|
|
|
|
[ -f $f ] && files=$files' '$f
|
|
|
|
|
done
|
|
|
|
|
set -- $files
|
2026-06-15 15:37:03 +02:00
|
|
|
if [ $# -gt 0 ]; then
|
|
|
|
|
pnpm exec oxlint --fix $@
|
|
|
|
|
pnpm exec oxfmt --write $@
|
|
|
|
|
for f in $@; do
|
|
|
|
|
case $f in *.py) ruff format $f 2>/dev/null || true ;; esac
|
|
|
|
|
done
|
2026-04-22 10:09:51 -07:00
|
|
|
fi
|
2026-02-24 15:17:21 +01:00
|
|
|
stage_fixed: true
|
2026-03-02 16:09:55 +01:00
|
|
|
test-and-check-packages:
|
|
|
|
|
tags: test-packages
|
2026-02-24 15:17:21 +01:00
|
|
|
env:
|
|
|
|
|
NX_TUI: "false"
|
2026-06-01 16:28:19 +02:00
|
|
|
run: |
|
2026-06-18 10:54:16 -07:00
|
|
|
files=
|
|
|
|
|
for f in {staged_files}; do
|
|
|
|
|
case $f in
|
|
|
|
|
packages/*|package.json|pnpm-lock.yaml|pnpm-workspace.yaml|nx.json|tsconfig*.json) files=$files' '$f ;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
set -- $files
|
2026-06-01 16:28:19 +02:00
|
|
|
if [ "$#" -gt 0 ]; then
|
|
|
|
|
projects=$(printf '%s\n' "$@" | pnpm nx show projects --affected --projects 'packages/*' --stdin --sep=,)
|
|
|
|
|
if [ -n "$projects" ]; then
|
|
|
|
|
pnpm nx run-many -t test,publint,attw --projects="$projects" --outputStyle=static
|
|
|
|
|
fi
|
|
|
|
|
fi
|
2026-02-24 15:17:21 +01:00
|
|
|
|
fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881)
Three names for one value were live in CopilotKit's own documentation, and
following the wrong one with a CLI-provisioned project yields an undefined
key:
- `INTELLIGENCE_API_KEY` — what `copilotkit project select` writes, used by
all 34 integration examples and the docs site.
- `COPILOTKIT_INTELLIGENCE_API_KEY` — the seven Channels package READMEs and
the packaged skills. Nothing ever read it.
- `COPILOTKIT_API_KEY` — the Slack and Teams examples, and the TSDoc on
`CopilotKitIntelligence` itself, which is what an IDE shows on hover.
`INTELLIGENCE_API_KEY` wins, because it is the name the CLI provisions and
changing it would break every scaffolded project in the wild.
`COPILOTKIT_INTELLIGENCE_API_KEY` is retired outright — no code read it.
`COPILOTKIT_API_KEY` stays readable as a deprecated alias in the two
examples that consume it, so an existing `.env` keeps working, and is
documented as deprecated everywhere it appears.
The skills reference also documented `organizationId`, sourced from a fourth
and fifth env name, as a `CopilotKitIntelligence` option. It is not one:
`CopilotKitIntelligenceConfig` has no such field, so the copy-pasteable
sample it appeared in would not compile. Removed from the samples, and the
prose that told readers to fetch a value for it corrected.
The Intelligence wiring itself was published only inside
`node_modules/@copilotkit/runtime/skills/`, and the only docs pages showing
`CopilotKitIntelligence` were the two Channels frontends — so a developer on
the plain web path had no page to reach it from. Adds
`/premium/connect-your-runtime`, which covers the wiring, how to confirm the
credential is actually consumed, and the self-hosted two-URL rule.
`scripts/validate-intelligence-env-names.ts` keeps this from drifting back.
It runs unfiltered in CI on purpose: the two workflows that would otherwise
cover it filter paths, and static/quality ignores `examples/**` — exactly
where the deprecated alias lives.
2026-08-19 17:50:09 -05:00
|
|
|
check-intelligence-env-names:
|
|
|
|
|
tags: intelligence-env-names
|
fix(docs): stop shipping stale Intelligence config claims, and gate the dead hosts (refs OSS-961)
The packaged runtime skill up to v1.62.2 prescribed `api.copilotkit.ai` /
`realtime.copilotkit.ai`. The first host is a CNAME onto the legacy Copilot
Cloud ALB, where no listener rule matches it, so every request gets the ALB
default action: a 404 with an empty body. The second has no DNS record at all.
A reader who followed that page converted a working OSS install into a 502.
The hosts themselves were corrected in v1.64.0, but two shipped surfaces still
carried stale claims about the same step, and nothing stopped the hosts from
coming back a third time:
- The debug skill said Intelligence "requires ... `apiUrl`, `wsUrl`, `apiKey`,
`tenantId`". Three errors in one line: `apiUrl`/`wsUrl` have been optional
with managed defaults since v1.64.0, and `tenantId` has never existed on
`CopilotKitIntelligenceConfig` — the API key carries the project (its token
format is `cpk-{projectId}_...`) and the platform resolves the organization
server-side, so there is no org or tenant field for a caller to pass.
- `CopilotKitIntelligence`'s own TSDoc showed only `*.internal` placeholders,
so the class's hover docs never named the pair that actually serves prod.
`validate-intelligence-env-names` — already the unfiltered guard for this same
config surface (OSS-881) — now also fails on either dead host. The
channels-intelligence realtime test is allowlisted: it needs a hostname that
genuinely does not resolve, since `getaddrinfo ENOTFOUND` is the condition
under test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 15:35:55 -05:00
|
|
|
# No glob: a retired name or a dead host can reappear in any doc, README,
|
|
|
|
|
# example, or skill, so this runs on every commit rather than a path subset.
|
fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881)
Three names for one value were live in CopilotKit's own documentation, and
following the wrong one with a CLI-provisioned project yields an undefined
key:
- `INTELLIGENCE_API_KEY` — what `copilotkit project select` writes, used by
all 34 integration examples and the docs site.
- `COPILOTKIT_INTELLIGENCE_API_KEY` — the seven Channels package READMEs and
the packaged skills. Nothing ever read it.
- `COPILOTKIT_API_KEY` — the Slack and Teams examples, and the TSDoc on
`CopilotKitIntelligence` itself, which is what an IDE shows on hover.
`INTELLIGENCE_API_KEY` wins, because it is the name the CLI provisions and
changing it would break every scaffolded project in the wild.
`COPILOTKIT_INTELLIGENCE_API_KEY` is retired outright — no code read it.
`COPILOTKIT_API_KEY` stays readable as a deprecated alias in the two
examples that consume it, so an existing `.env` keeps working, and is
documented as deprecated everywhere it appears.
The skills reference also documented `organizationId`, sourced from a fourth
and fifth env name, as a `CopilotKitIntelligence` option. It is not one:
`CopilotKitIntelligenceConfig` has no such field, so the copy-pasteable
sample it appeared in would not compile. Removed from the samples, and the
prose that told readers to fetch a value for it corrected.
The Intelligence wiring itself was published only inside
`node_modules/@copilotkit/runtime/skills/`, and the only docs pages showing
`CopilotKitIntelligence` were the two Channels frontends — so a developer on
the plain web path had no page to reach it from. Adds
`/premium/connect-your-runtime`, which covers the wiring, how to confirm the
credential is actually consumed, and the self-hosted two-URL rule.
`scripts/validate-intelligence-env-names.ts` keeps this from drifting back.
It runs unfiltered in CI on purpose: the two workflows that would otherwise
cover it filter paths, and static/quality ignores `examples/**` — exactly
where the deprecated alias lives.
2026-08-19 17:50:09 -05:00
|
|
|
run: pnpm check:intelligence-env-names
|
|
|
|
|
fail_text: |
|
fix(docs): stop shipping stale Intelligence config claims, and gate the dead hosts (refs OSS-961)
The packaged runtime skill up to v1.62.2 prescribed `api.copilotkit.ai` /
`realtime.copilotkit.ai`. The first host is a CNAME onto the legacy Copilot
Cloud ALB, where no listener rule matches it, so every request gets the ALB
default action: a 404 with an empty body. The second has no DNS record at all.
A reader who followed that page converted a working OSS install into a 502.
The hosts themselves were corrected in v1.64.0, but two shipped surfaces still
carried stale claims about the same step, and nothing stopped the hosts from
coming back a third time:
- The debug skill said Intelligence "requires ... `apiUrl`, `wsUrl`, `apiKey`,
`tenantId`". Three errors in one line: `apiUrl`/`wsUrl` have been optional
with managed defaults since v1.64.0, and `tenantId` has never existed on
`CopilotKitIntelligenceConfig` — the API key carries the project (its token
format is `cpk-{projectId}_...`) and the platform resolves the organization
server-side, so there is no org or tenant field for a caller to pass.
- `CopilotKitIntelligence`'s own TSDoc showed only `*.internal` placeholders,
so the class's hover docs never named the pair that actually serves prod.
`validate-intelligence-env-names` — already the unfiltered guard for this same
config surface (OSS-881) — now also fails on either dead host. The
channels-intelligence realtime test is allowlisted: it needs a hostname that
genuinely does not resolve, since `getaddrinfo ENOTFOUND` is the condition
under test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 15:35:55 -05:00
|
|
|
A non-canonical Intelligence env var name or hostname was found.
|
2026-08-27 10:44:51 -07:00
|
|
|
The canonical name is CPK_INTELLIGENCE_API_KEY; the canonical hosts are
|
fix(docs): stop shipping stale Intelligence config claims, and gate the dead hosts (refs OSS-961)
The packaged runtime skill up to v1.62.2 prescribed `api.copilotkit.ai` /
`realtime.copilotkit.ai`. The first host is a CNAME onto the legacy Copilot
Cloud ALB, where no listener rule matches it, so every request gets the ALB
default action: a 404 with an empty body. The second has no DNS record at all.
A reader who followed that page converted a working OSS install into a 502.
The hosts themselves were corrected in v1.64.0, but two shipped surfaces still
carried stale claims about the same step, and nothing stopped the hosts from
coming back a third time:
- The debug skill said Intelligence "requires ... `apiUrl`, `wsUrl`, `apiKey`,
`tenantId`". Three errors in one line: `apiUrl`/`wsUrl` have been optional
with managed defaults since v1.64.0, and `tenantId` has never existed on
`CopilotKitIntelligenceConfig` — the API key carries the project (its token
format is `cpk-{projectId}_...`) and the platform resolves the organization
server-side, so there is no org or tenant field for a caller to pass.
- `CopilotKitIntelligence`'s own TSDoc showed only `*.internal` placeholders,
so the class's hover docs never named the pair that actually serves prod.
`validate-intelligence-env-names` — already the unfiltered guard for this same
config surface (OSS-881) — now also fails on either dead host. The
channels-intelligence realtime test is allowlisted: it needs a hostname that
genuinely does not resolve, since `getaddrinfo ENOTFOUND` is the condition
under test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 15:35:55 -05:00
|
|
|
api.intelligence.copilotkit.ai and realtime.intelligence.copilotkit.ai.
|
|
|
|
|
See scripts/validate-intelligence-env-names.ts for the allowlists.
|
fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881)
Three names for one value were live in CopilotKit's own documentation, and
following the wrong one with a CLI-provisioned project yields an undefined
key:
- `INTELLIGENCE_API_KEY` — what `copilotkit project select` writes, used by
all 34 integration examples and the docs site.
- `COPILOTKIT_INTELLIGENCE_API_KEY` — the seven Channels package READMEs and
the packaged skills. Nothing ever read it.
- `COPILOTKIT_API_KEY` — the Slack and Teams examples, and the TSDoc on
`CopilotKitIntelligence` itself, which is what an IDE shows on hover.
`INTELLIGENCE_API_KEY` wins, because it is the name the CLI provisions and
changing it would break every scaffolded project in the wild.
`COPILOTKIT_INTELLIGENCE_API_KEY` is retired outright — no code read it.
`COPILOTKIT_API_KEY` stays readable as a deprecated alias in the two
examples that consume it, so an existing `.env` keeps working, and is
documented as deprecated everywhere it appears.
The skills reference also documented `organizationId`, sourced from a fourth
and fifth env name, as a `CopilotKitIntelligence` option. It is not one:
`CopilotKitIntelligenceConfig` has no such field, so the copy-pasteable
sample it appeared in would not compile. Removed from the samples, and the
prose that told readers to fetch a value for it corrected.
The Intelligence wiring itself was published only inside
`node_modules/@copilotkit/runtime/skills/`, and the only docs pages showing
`CopilotKitIntelligence` were the two Channels frontends — so a developer on
the plain web path had no page to reach it from. Adds
`/premium/connect-your-runtime`, which covers the wiring, how to confirm the
credential is actually consumed, and the self-hosted two-URL rule.
`scripts/validate-intelligence-env-names.ts` keeps this from drifting back.
It runs unfiltered in CI on purpose: the two workflows that would otherwise
cover it filter paths, and static/quality ignores `examples/**` — exactly
where the deprecated alias lives.
2026-08-19 17:50:09 -05:00
|
|
|
|
2026-04-22 14:50:58 +02:00
|
|
|
check-plugin-skills:
|
|
|
|
|
tags: plugin-skills
|
fix(skills): correct claims the audit found wrong in the two entry points
Verified every factual claim in both new skills against the current source
rather than against my own draft. Six were wrong or incomplete.
`copilotkit`:
- The MCP server does not arrive with the skills. `.mcp.json` lives at the
repository root, outside `skills/`, so a `npx skills add` install — which is
what /build-with-agents tells a reader to run — registered no server, and the
skill said "Nothing to do". It now gives the `claude mcp add` and
`codex mcp add` commands, which is what the docs' own MCP page does.
- The Codex block named a project-local `.codex/config.toml` and a `type` key
that the documented configuration does not use.
- "eleven things" was the ceiling, not the count. `frontendAssetChecks`,
`corsChecks` and `packageVersionChecks` each return an empty list when
nothing could be read, so an Intelligence-mode run settles eight to eleven,
and `--expect-runtime oss` is a smaller set again.
- Dropped the claim that a v1/v2 import mismatch "shows up as routes that 404".
The subpaths and the still-resolving package root are verified in the exports;
that specific symptom was not, and this skill's whole premise is not to state
unverified API detail.
`copilotkit-cli`:
- `login --json` was missing. It is the flag that streams agent-readable JSON
without launching a browser, so it is the one a coding agent needs, and this
skill exists for coding agents.
- `create` was described as the canonical command with `init` as its alias. The
CLI's own help has it the other way round.
- Added the provenance verdict rule, which is the actionable half of the feature
the skill already praised: nothing answering at a URL the project named is a
FAIL, nothing answering at an assumed default is UNKNOWN.
- Added `--runtime-url`, `--header` and `--timeout`, the `--expect-runtime oss`
exit-zero condition, and a `skills install` row — the command the README tells
readers to run.
- Replaced "it does not detect or convert an app you already have" with what is
supported, since I never proved that absence.
Claims that checked out and are unchanged: the four corpora and their
boundaries (the tool descriptions state "library/package source only — NOT
example or showcase apps"), the round trip sending `tools: []` and `context: []`
("Deliberately trivial and answerable without tools or context"), `whoami`
printing the organization, `project select` writing `CPK_INTELLIGENCE_API_KEY`
to `.env`, `import --dry-run`, both telemetry opt-out variables, and all 21
docs links, each of which returns 200 live.
Also fixes the `check-plugin-skills` glob in `lefthook.yml`, which still
enumerated `skills/runtime/**`, `skills/react-core/**` and
`skills/a2ui-renderer/**`. All three are deleted, so editing either new skill
triggered no local mirror check. `plugin-skills-check.yml` already uses
`skills/**` and carries a comment about this exact mistake.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 11:34:39 -05:00
|
|
|
glob: "{packages/*/skills/**,skills/**,scripts/sync-plugin-skills.ts,.claude-plugin/**,packages/runtime/package.json}"
|
2026-04-22 14:50:58 +02:00
|
|
|
run: pnpm check:plugin-skills
|
|
|
|
|
fail_text: |
|
|
|
|
|
Plugin skill mirror is out of sync with the Intent source.
|
|
|
|
|
Run: pnpm sync:plugin-skills
|
|
|
|
|
Then stage the changes and re-commit.
|
|
|
|
|
|
2026-02-24 15:17:21 +01:00
|
|
|
commit-msg:
|
|
|
|
|
commands:
|
|
|
|
|
commitlint:
|
2026-03-02 15:56:37 +01:00
|
|
|
tags: commitlint
|
2026-02-24 15:17:21 +01:00
|
|
|
run: pnpm commitlint --edit {1}
|