@monte3l/groundwork 0.0.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.
- package/README.md +23 -0
- package/bin/m3l-groundwork.mjs +10 -0
- package/dist/assets.d.ts +20 -0
- package/dist/assets.js +79 -0
- package/dist/caps.d.ts +25 -0
- package/dist/caps.js +69 -0
- package/dist/conflicts.d.ts +12 -0
- package/dist/conflicts.js +77 -0
- package/dist/emit.d.ts +7 -0
- package/dist/emit.js +42 -0
- package/dist/git.d.ts +3 -0
- package/dist/git.js +9 -0
- package/dist/harness/conformance.d.ts +20 -0
- package/dist/harness/conformance.js +18 -0
- package/dist/harness/frontmatter.d.ts +38 -0
- package/dist/harness/frontmatter.js +204 -0
- package/dist/harness/grade.d.ts +4 -0
- package/dist/harness/grade.js +105 -0
- package/dist/harness/rules.d.ts +55 -0
- package/dist/harness/rules.js +580 -0
- package/dist/harness/types.d.ts +32 -0
- package/dist/harness/types.js +9 -0
- package/dist/inventory.d.ts +63 -0
- package/dist/inventory.js +66 -0
- package/dist/jsonc.d.ts +14 -0
- package/dist/jsonc.js +83 -0
- package/dist/main.d.ts +24 -0
- package/dist/main.js +297 -0
- package/dist/merge-json.d.ts +74 -0
- package/dist/merge-json.js +135 -0
- package/dist/mode.d.ts +19 -0
- package/dist/mode.js +53 -0
- package/dist/packs.d.ts +61 -0
- package/dist/packs.js +186 -0
- package/dist/plugin.d.ts +23 -0
- package/dist/plugin.js +79 -0
- package/dist/report.d.ts +4 -0
- package/dist/report.js +323 -0
- package/dist/survey/fs-walk.d.ts +14 -0
- package/dist/survey/fs-walk.js +60 -0
- package/dist/survey/survey-docs.d.ts +4 -0
- package/dist/survey/survey-docs.js +69 -0
- package/dist/survey/survey-harness.d.ts +4 -0
- package/dist/survey/survey-harness.js +121 -0
- package/dist/survey/survey-shape.d.ts +4 -0
- package/dist/survey/survey-shape.js +182 -0
- package/dist/survey/survey-toolchain.d.ts +4 -0
- package/dist/survey/survey-toolchain.js +217 -0
- package/dist/survey/survey.d.ts +5 -0
- package/dist/survey/survey.js +21 -0
- package/dist/survey/types.d.ts +117 -0
- package/dist/survey/types.js +8 -0
- package/dist/tokens.d.ts +13 -0
- package/dist/tokens.js +13 -0
- package/dist/toolchain/conformance.d.ts +20 -0
- package/dist/toolchain/conformance.js +30 -0
- package/dist/toolchain/grade.d.ts +4 -0
- package/dist/toolchain/grade.js +244 -0
- package/dist/toolchain/rules.d.ts +118 -0
- package/dist/toolchain/rules.js +706 -0
- package/dist/toolchain/tsconfig-chain.d.ts +36 -0
- package/dist/toolchain/tsconfig-chain.js +116 -0
- package/dist/toolchain/types.d.ts +27 -0
- package/dist/toolchain/types.js +9 -0
- package/package.json +59 -0
- package/plugin/skills/customize/SKILL.md +305 -0
- package/plugin/src/domain-map.ts +134 -0
- package/plugin/src/index.ts +4 -0
- package/plugin/src/kind-facet-map.ts +174 -0
- package/plugin/src/pack-map.ts +65 -0
- package/templates/core/.claude/agents/Explore.md +43 -0
- package/templates/core/.claude/agents/code-implementer.md +258 -0
- package/templates/core/.claude/agents/code-reviewer.md +163 -0
- package/templates/core/.claude/agents/silent-failure-hunter.md +191 -0
- package/templates/core/.claude/agents/test-author.md +211 -0
- package/templates/core/.claude/hooks/guard-branch-isolation.mjs +123 -0
- package/templates/core/.claude/hooks/guard-double-background.mjs +113 -0
- package/templates/core/.claude/hooks/guard-git-push-signed.mjs +90 -0
- package/templates/core/.claude/hooks/guard-hub-src-writes.mjs +88 -0
- package/templates/core/.claude/hooks/guard-js-extension.mjs +66 -0
- package/templates/core/.claude/hooks/guard-no-commonjs.mjs +105 -0
- package/templates/core/.claude/hooks/guard-protected-paths.mjs +45 -0
- package/templates/core/.claude/hooks/guard-secret-writes.mjs +183 -0
- package/templates/core/.claude/hooks/inject-decision-gate.mjs +119 -0
- package/templates/core/.claude/hooks/post-edit-verify.mjs +150 -0
- package/templates/core/.claude/rules/agent-dispatch.md +121 -0
- package/templates/core/.claude/rules/refactoring.md +52 -0
- package/templates/core/.claude/rules/src.md +114 -0
- package/templates/core/.claude/rules/tests.md +129 -0
- package/templates/core/.claude/settings.json +111 -0
- package/templates/core/.claude/skills/creating-prs/SKILL.md +132 -0
- package/templates/core/.claude/skills/finishing-work/SKILL.md +117 -0
- package/templates/core/.claude/skills/harness-guidance/SKILL.md +140 -0
- package/templates/core/.claude/skills/harness-guidance/references/official-sources.md +58 -0
- package/templates/core/.claude/skills/starting-work/SKILL.md +94 -0
- package/templates/core/.claude/skills/triaging-ci/SKILL.md +111 -0
- package/templates/core/.claude/skills/typescript-guidance/SKILL.md +143 -0
- package/templates/core/.claude/skills/typescript-guidance/references/typescript-sources.md +102 -0
- package/templates/core/.claude/skills/writing-commits/SKILL.md +248 -0
- package/templates/core/.github/workflows/ci.yml +123 -0
- package/templates/core/.github/workflows/dependency-review.yml +26 -0
- package/templates/core/.github/workflows/security-audit.yml +54 -0
- package/templates/core/.node-version +1 -0
- package/templates/core/.prettierignore +5 -0
- package/templates/core/.prettierrc.json +4 -0
- package/templates/core/CLAUDE.md +127 -0
- package/templates/core/README.md +24 -0
- package/templates/core/_gitignore +19 -0
- package/templates/core/_npmrc +1 -0
- package/templates/core/bin/check-exports.mjs +92 -0
- package/templates/core/bin/check-harness.mjs +27 -0
- package/templates/core/bin/check-node-version.mjs +51 -0
- package/templates/core/bin/check-toolchain.mjs +20 -0
- package/templates/core/bin/lib/agent-roster.mjs +8 -0
- package/templates/core/bin/lib/frontmatter.mjs +210 -0
- package/templates/core/bin/lib/harness-rules.mjs +916 -0
- package/templates/core/bin/lib/protected-paths.mjs +23 -0
- package/templates/core/bin/lib/report.mjs +56 -0
- package/templates/core/bin/lib/signed-range.mjs +178 -0
- package/templates/core/bin/lib/toolchain-rules.mjs +1264 -0
- package/templates/core/bin/lib/verify-steps.mjs +131 -0
- package/templates/core/bin/lib/verify-steps.packs.json +1 -0
- package/templates/core/bin/lint-commit.mjs +50 -0
- package/templates/core/bin/strip-claude-trailers.mjs +25 -0
- package/templates/core/bin/verify.mjs +64 -0
- package/templates/core/commitlint.config.js +11 -0
- package/templates/core/docs/research/harness-refresh.md +27 -0
- package/templates/core/docs/research/typescript-refresh.md +32 -0
- package/templates/core/eslint.config.js +105 -0
- package/templates/core/knip.json +6 -0
- package/templates/core/lefthook.yml +39 -0
- package/templates/core/package.json +58 -0
- package/templates/core/pnpm-workspace.yaml +13 -0
- package/templates/core/src/index.ts +12 -0
- package/templates/core/tests/index.test.ts +8 -0
- package/templates/core/tsconfig.base.json +36 -0
- package/templates/core/tsconfig.build.json +10 -0
- package/templates/core/tsconfig.json +11 -0
- package/templates/core/vitest.config.ts +32 -0
- package/templates/packs/README.md +81 -0
- package/templates/packs/harness-extras/files/.claude/agents/type-design-analyzer.md +188 -0
- package/templates/packs/harness-extras/files/.claude/hooks/guard-readonly-bash.mjs +324 -0
- package/templates/packs/harness-extras/files/.claude/hooks/reinject-compact-handoff.mjs +197 -0
- package/templates/packs/harness-extras/files/.claude/hooks/write-compact-handoff.mjs +180 -0
- package/templates/packs/harness-extras/files/bin/check-file-budget.mjs +407 -0
- package/templates/packs/harness-extras/files/bin/file-budget-baseline.json +1 -0
- package/templates/packs/harness-extras/pack.json +65 -0
- package/templates/packs/statusline/files/.claude/hooks/statusline-layout.mjs +365 -0
- package/templates/packs/statusline/files/.claude/hooks/statusline.mjs +996 -0
- package/templates/packs/statusline/files/.claude/hooks/subagent-statusline.mjs +203 -0
- package/templates/packs/statusline/pack.json +31 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Official Anthropic sources — the allowlist
|
|
2
|
+
|
|
3
|
+
The single source list consulted by `harness-guidance` in both modes.
|
|
4
|
+
Editing this file is the one edit site when Anthropic moves, renames, or
|
|
5
|
+
adds a domain.
|
|
6
|
+
|
|
7
|
+
## Domain allowlist
|
|
8
|
+
|
|
9
|
+
Pass verbatim as `WebSearch`'s `allowed_domains`:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
anthropic.com, www.anthropic.com, claude.com, www.claude.com,
|
|
13
|
+
platform.claude.com, code.claude.com, docs.claude.com, docs.anthropic.com
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Anthropic's engineering posts, research papers, and news all live under
|
|
17
|
+
`anthropic.com` (including `/engineering`, `/research`, `/news`), so this
|
|
18
|
+
one allowlist covers whitepapers and blog posts as well as docs.
|
|
19
|
+
|
|
20
|
+
## GitHub caveat
|
|
21
|
+
|
|
22
|
+
`allowed_domains` filters by domain, not path, so a bare `github.com`
|
|
23
|
+
allowance would let through any repo. Agents may include `github.com` and
|
|
24
|
+
`raw.githubusercontent.com` in their search domains, but must **only cite or
|
|
25
|
+
fetch URLs under the `anthropics` GitHub org** — `github.com/anthropics/...`
|
|
26
|
+
or `raw.githubusercontent.com/anthropics/...` — and drop any other GitHub
|
|
27
|
+
result, even a highly-ranked one.
|
|
28
|
+
|
|
29
|
+
## First-class sources to enumerate directly
|
|
30
|
+
|
|
31
|
+
Search ranking is not exhaustive — a recent post can be silently missed
|
|
32
|
+
unless an agent is told to check these directly:
|
|
33
|
+
|
|
34
|
+
- **Claude Code CHANGELOG** —
|
|
35
|
+
`https://raw.githubusercontent.com/anthropics/claude-code/main/CHANGELOG.md`.
|
|
36
|
+
The authoritative, version-ordered record of Claude Code feature and
|
|
37
|
+
behavior changes. Because it's version-ordered, it can be read as a
|
|
38
|
+
**delta** from a known prior version — the primary input for refresh
|
|
39
|
+
mode's Step 2.
|
|
40
|
+
- **Blog / news / engineering / research index pages** — enumerate directly:
|
|
41
|
+
- `https://www.anthropic.com/news`
|
|
42
|
+
- `https://www.anthropic.com/engineering`
|
|
43
|
+
- `https://www.anthropic.com/research`
|
|
44
|
+
- `https://claude.com/blog`
|
|
45
|
+
|
|
46
|
+
## Current-date anchor
|
|
47
|
+
|
|
48
|
+
Every agent brief must state today's date explicitly. A `retrieved <date>`
|
|
49
|
+
stamp otherwise depends on the spoke inferring the date itself, which is
|
|
50
|
+
unreliable.
|
|
51
|
+
|
|
52
|
+
## Coverage discipline
|
|
53
|
+
|
|
54
|
+
Reject any non-allowlisted domain outright and say so in the report, rather
|
|
55
|
+
than substituting a community blog, a third-party summary, or a Stack
|
|
56
|
+
Overflow answer for missing official coverage. If a facet turns up no
|
|
57
|
+
official source, that is itself a reportable finding (a coverage gap), not
|
|
58
|
+
a reason to lower the bar.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: starting-work
|
|
3
|
+
description: >-
|
|
4
|
+
The pre-work decision gate for any task that will change code. Invoke it
|
|
5
|
+
FIRST -- before reading, investigating, or editing anything -- for
|
|
6
|
+
"implement", "build", "add", "fix the bug where ...", "refactor", or any
|
|
7
|
+
request to change behavior, even when the change is unnamed or you have not
|
|
8
|
+
seen the code yet. Inspects git state, recommends a branch (feat/fix <slug>)
|
|
9
|
+
and push target, and decides whether a PR is required, all confirmed before
|
|
10
|
+
any write. Skip for research and questions that change nothing.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# starting-work
|
|
14
|
+
|
|
15
|
+
This skill is the single place the project answers "where do I do this
|
|
16
|
+
work?" before touching anything. `guard-branch-isolation.mjs` hard-blocks
|
|
17
|
+
writes to `src/**` and `tests/**` while `HEAD` is `main` — that's a
|
|
18
|
+
backstop, not a plan: if you discover it when a write is rejected, you're
|
|
19
|
+
already mid-task with a dirty tree. This skill is the workflow half — it
|
|
20
|
+
branches _before_ the block can fire.
|
|
21
|
+
|
|
22
|
+
## The contract
|
|
23
|
+
|
|
24
|
+
**Infer and recommend all decisions, then confirm every one with the user in
|
|
25
|
+
a single round. Do not write files or create a branch until the user has
|
|
26
|
+
confirmed.** The user is always free to override a recommendation; your job
|
|
27
|
+
is to make the right default obvious, not to force it.
|
|
28
|
+
|
|
29
|
+
## Steps
|
|
30
|
+
|
|
31
|
+
### 1 — Inspect git state (read-only)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git rev-parse --abbrev-ref HEAD # branch name; "HEAD" means detached
|
|
35
|
+
git status --porcelain # is the tree already dirty?
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
- A detached HEAD sitting on the `main` commit is treated as `main` for
|
|
39
|
+
isolation purposes — it's the same tree state the guard protects.
|
|
40
|
+
- **Re-run this inspection after any conversational gap, not just at the
|
|
41
|
+
start.** The branch is not a stable fact across a long session.
|
|
42
|
+
|
|
43
|
+
### 2 — Infer the change scope
|
|
44
|
+
|
|
45
|
+
From the task in front of you, work out **which paths will be edited** and
|
|
46
|
+
whether any are _guarded_ (under `src/**` or `tests/**`). This drives the PR
|
|
47
|
+
decision and whether isolation is even required. A docs-only or `.claude/`
|
|
48
|
+
-only change touches no guarded path, so the guard won't fire and a PR may
|
|
49
|
+
be optional; a change under `src/` or `tests/` always needs isolation and a
|
|
50
|
+
PR.
|
|
51
|
+
|
|
52
|
+
### 3 — Recommend each decision
|
|
53
|
+
|
|
54
|
+
- **Branch** — recommend `feat/<slug>` (or `fix/<slug>` for a bug fix), with
|
|
55
|
+
the slug derived from the task (kebab-case, short). If the repo is already
|
|
56
|
+
on a suitable non-`main` branch, recommend **staying** on it. Never
|
|
57
|
+
recommend `main` or a detached-on-`main` HEAD for guarded work.
|
|
58
|
+
- **PR required?** — **yes** whenever a guarded path is in scope: land via
|
|
59
|
+
PR, never a direct commit to `main`. For docs/config-only changes, note
|
|
60
|
+
that a PR is optional but still recommended.
|
|
61
|
+
- **Push target** — `origin <the recommended branch>`. Never `origin main`.
|
|
62
|
+
|
|
63
|
+
### 4 — Confirm with the user (blocking)
|
|
64
|
+
|
|
65
|
+
Ask every decision that applies in **one** `AskUserQuestion` call — branch,
|
|
66
|
+
PR-required, and push target — one question per decision, with your inferred
|
|
67
|
+
recommendation listed **first** and labelled "(Recommended)". For the
|
|
68
|
+
branch, offer the inferred `feat/<slug>` plus an "Other" path for a custom
|
|
69
|
+
slug. Make it explicit in your framing that **nothing is written and no
|
|
70
|
+
branch is created until they confirm** — this is the whole point of the
|
|
71
|
+
gate.
|
|
72
|
+
|
|
73
|
+
If the user has _already_ told you the branch to use (e.g. "do it on
|
|
74
|
+
`fix/foo`"), don't re-ask that dimension — treat it as confirmed and only
|
|
75
|
+
surface the decisions still open.
|
|
76
|
+
|
|
77
|
+
### 5 — Act on the confirmed decisions
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git switch -c feat/<slug> # or fix/<slug>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Verify `HEAD` is neither `main` nor detached-on-`main` before handing back;
|
|
84
|
+
if it is, loop back to Step 4 rather than proceeding into a write that the
|
|
85
|
+
guard will reject. When **resuming an existing feature branch** that may
|
|
86
|
+
have fallen behind, resync it with `origin/main` before working (or defer to
|
|
87
|
+
the resync step in `creating-prs`) so the branch does not drift from the
|
|
88
|
+
base over multiple sessions.
|
|
89
|
+
|
|
90
|
+
### 6 — Hand back
|
|
91
|
+
|
|
92
|
+
Report a one-line summary of the confirmed decisions — branch, PR
|
|
93
|
+
(yes/no), push target — so the calling skill or the user proceeds with the
|
|
94
|
+
context recorded.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: triaging-ci
|
|
3
|
+
description: >-
|
|
4
|
+
Diagnose a CI failure via gh CLI: resolve the failing run, fetch logs, map the
|
|
5
|
+
failure to its pipeline step, report root cause plus the exact local repro
|
|
6
|
+
command, and present 3-5 fix options. Use for /triaging-ci, "why did CI fail",
|
|
7
|
+
"CI is failing", "debug the CI run", or a specific run ID/URL. GitHub stance:
|
|
8
|
+
gh CLI.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Diagnose why a GitHub Actions CI run failed by fetching its logs via `gh` and
|
|
12
|
+
mapping the failure back to the specific pipeline step and root cause, then
|
|
13
|
+
present 3–5 solution options for the user to choose from. This skill does not
|
|
14
|
+
apply fixes — it ends with options, not actions.
|
|
15
|
+
|
|
16
|
+
## Steps
|
|
17
|
+
|
|
18
|
+
### 1 — Resolve the run
|
|
19
|
+
|
|
20
|
+
If the user provided an explicit run ID or URL, extract the numeric ID from it.
|
|
21
|
+
|
|
22
|
+
Otherwise, find the most recent failed run on the current branch:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
gh run list --branch $(git rev-parse --abbrev-ref HEAD) \
|
|
26
|
+
--limit 5 \
|
|
27
|
+
--json databaseId,status,conclusion,name,createdAt
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Pick the most recent entry whose `conclusion` is `"failure"`.
|
|
31
|
+
|
|
32
|
+
If no failed run exists on the current branch (empty result or all passing), widen
|
|
33
|
+
the search to the 10 most recent runs across all branches:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
gh run list --limit 10 \
|
|
37
|
+
--json databaseId,status,conclusion,name,headBranch,createdAt
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If a failed run exists in the broader search, proceed with that run and note the
|
|
41
|
+
branch it came from. If no failed run exists anywhere in the recent history, report
|
|
42
|
+
that clearly and stop — there is nothing to triage.
|
|
43
|
+
|
|
44
|
+
**Zero runs at all (not even queued) is a different problem from a failed
|
|
45
|
+
run** — a dropped webhook event, not a code failure. If a push landed but no
|
|
46
|
+
run was ever created for its head SHA, first confirm it isn't isolated to
|
|
47
|
+
this push — check whether a different, unrelated PR pushed around the same
|
|
48
|
+
time shows the identical gap. If so, it's likely a one-off delivery drop,
|
|
49
|
+
not a repo config problem; a safe, reversible fix is an empty-commit push
|
|
50
|
+
(`git commit --allow-empty -m "chore: retrigger CI"`) to fire a fresh event,
|
|
51
|
+
rather than auditing Actions permissions or workflow triggers.
|
|
52
|
+
|
|
53
|
+
### 2 — Fetch the failing job logs
|
|
54
|
+
|
|
55
|
+
Pull only the logs from steps that failed:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
gh run view <id> --log-failed
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
If that command returns nothing (the run was cancelled, or all steps are
|
|
62
|
+
technically "successful" but a post-step failed), fall back to the full log:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
gh run view <id> --log
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Do not reproduce the entire log output — find and keep only the region around
|
|
69
|
+
the first failure, typically the last 50–100 lines before the run aborted.
|
|
70
|
+
|
|
71
|
+
### 3 — Map to the pipeline step
|
|
72
|
+
|
|
73
|
+
`.github/workflows/ci.yml`'s lanes each run `node bin/verify.mjs --step <id>`
|
|
74
|
+
against a step id from `bin/lib/verify-steps.mjs` — that file's `cmd` field
|
|
75
|
+
IS the local reproduction command, so mapping a failing CI step to its local
|
|
76
|
+
command is always: find the `## <step name>` line the log shows, match it to
|
|
77
|
+
the step's `name` in `bin/lib/verify-steps.mjs`, and reproduce with that
|
|
78
|
+
step's `cmd` array joined as a shell command (or just `node bin/verify.mjs
|
|
79
|
+
--step <id>` directly). The step name usually appears verbatim in the log
|
|
80
|
+
lines (e.g. `Run pnpm lint` or `##[error]...`).
|
|
81
|
+
|
|
82
|
+
### 4 — Report the diagnosis
|
|
83
|
+
|
|
84
|
+
Output a concise structured report — no prose padding:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
## CI Triage — Run #<id>
|
|
88
|
+
|
|
89
|
+
**Failed step:** <step name>
|
|
90
|
+
**Reproduce locally:** <exact command, e.g. `node bin/verify.mjs --step lint`>
|
|
91
|
+
**Root cause:** <one sentence>
|
|
92
|
+
**Error excerpt:**
|
|
93
|
+
<quoted lines from the log — enough to identify the file/rule/test>
|
|
94
|
+
**Assessment:** <Real failure | Likely flake — explain why>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
A "likely flake" is a transient runner issue: network timeout downloading
|
|
98
|
+
dependencies, OOM on a large test run, a GitHub-side runner error, or a retry
|
|
99
|
+
that would probably pass. Everything else is a real failure requiring a code fix.
|
|
100
|
+
|
|
101
|
+
### 5 — Present solution options
|
|
102
|
+
|
|
103
|
+
After the diagnosis, present 3–5 solution options in a separate
|
|
104
|
+
`## Solution Options` section so the diagnosis stays readable on its own. For
|
|
105
|
+
each option include: a one-line description, the exact command or change
|
|
106
|
+
needed, and the main tradeoff. Do not apply any fix — leave the choice to the
|
|
107
|
+
user.
|
|
108
|
+
|
|
109
|
+
If triaging several failed runs in one pass, write the per-run reports to a
|
|
110
|
+
file and keep the chat reply to a short summary table — don't paste every
|
|
111
|
+
report inline.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript-guidance
|
|
3
|
+
description: >-
|
|
4
|
+
Dual-mode TypeScript guidance skill. `research` mode answers a single
|
|
5
|
+
TypeScript/toolchain question from owner-normative upstream sources only
|
|
6
|
+
(typescriptlang.org, the devblog, microsoft/TypeScript releases,
|
|
7
|
+
nodejs.org type stripping, typescript-eslint.io, attw, publint). `refresh`
|
|
8
|
+
mode sweeps this project's whole TypeScript-facing surface — tsconfig,
|
|
9
|
+
eslint, packaging, and the test config/approach — against a living
|
|
10
|
+
tracker and produces a remediation plan. Use for /typescript-guidance,
|
|
11
|
+
"what does the TypeScript team say about X", "are we behind on
|
|
12
|
+
TypeScript", "is our tsconfig still current", or before changing a
|
|
13
|
+
compiler flag. Not how this project's config is wired today — that's
|
|
14
|
+
CLAUDE.md and the config files themselves.
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# typescript-guidance
|
|
18
|
+
|
|
19
|
+
One skill, two modes, sharing one allowlist
|
|
20
|
+
(`references/typescript-sources.md`) so they can't drift apart. Pick the
|
|
21
|
+
mode from how you were invoked: a specific question → `research`; a
|
|
22
|
+
periodic or `/customize`-driven sweep → `refresh`.
|
|
23
|
+
|
|
24
|
+
**Must only run in the main (hub) agent, never inside a subagent** — it ends
|
|
25
|
+
in `EnterPlanMode` (refresh) or an `AskUserQuestion` (either mode,
|
|
26
|
+
occasionally), neither of which a subagent can do.
|
|
27
|
+
|
|
28
|
+
**No files are written by this skill itself** in research mode by default;
|
|
29
|
+
refresh mode writes to exactly one file, the tracker, in Step 5.
|
|
30
|
+
|
|
31
|
+
## Authority (read this before either mode)
|
|
32
|
+
|
|
33
|
+
This skill has authority over **every TypeScript-facing file in the
|
|
34
|
+
project** — `tsconfig.base.json`, `tsconfig.json`, `eslint.config.js`,
|
|
35
|
+
`vitest.config.ts` (config **and** the testing approach itself, not just
|
|
36
|
+
its config shape), `package.json`'s TypeScript-toolchain entries, packaging
|
|
37
|
+
(`exports`, `check-exports.mjs`), and the toolchain steps in
|
|
38
|
+
`.github/workflows/*.yml`. An interview-derived emphasis (from
|
|
39
|
+
`/customize`'s kind-to-facet table) tells this skill which facet to research
|
|
40
|
+
**most deeply**, never which facets it may or may not touch. A facet with
|
|
41
|
+
low priority still gets swept; it just gets less dedicated attention per run.
|
|
42
|
+
|
|
43
|
+
## Research mode
|
|
44
|
+
|
|
45
|
+
1. **Scope the topic.** Read the topic from the invocation or the
|
|
46
|
+
surrounding task; at most **one** clarifying question, otherwise infer
|
|
47
|
+
and proceed. Derive **3–5 orthogonal facets** — one per Explore agent.
|
|
48
|
+
Derive a kebab-case slug for the optional Step 5 snapshot.
|
|
49
|
+
2. **Fan out.** Read `references/typescript-sources.md` first, then spawn
|
|
50
|
+
**all agents in a single message**. Each brief carries: one facet; the
|
|
51
|
+
allowlist + GitHub caveat pasted verbatim; today's date; "do not stop at
|
|
52
|
+
the first matching source — fetch every distinct one"; "reject any
|
|
53
|
+
non-allowlisted domain outright and say so"; "you hold no write tool —
|
|
54
|
+
findings travel only in your response"; the findings format below; and a
|
|
55
|
+
~8,000-character (~2,000-token) return cap. Always `subagent_type:
|
|
56
|
+
"Explore"`, breadth `"very thorough"`.
|
|
57
|
+
|
|
58
|
+
Findings format, one block per source:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
SOURCE: <URL>
|
|
62
|
+
TIER: T1 | T2
|
|
63
|
+
CLAIM: <the specific claim, quoted or tightly paraphrased>
|
|
64
|
+
CONFLICT-WITH: <another SOURCE, if this claim contradicts it — omit if none>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
3. **Aggregate & synthesize.** Read every agent's full inline findings —
|
|
68
|
+
digests are for triage, not synthesis. Assign `S1, S2, …` deduping; merge
|
|
69
|
+
agreement into single consensus points tagged with all supporting ids;
|
|
70
|
+
flag contradictions. Precedence when two sources disagree: T1 outranks
|
|
71
|
+
T2; within T1, a devblog release post outranks the Handbook (the Handbook
|
|
72
|
+
lags a release); nodejs.org is co-normative for the runtime boundary — a
|
|
73
|
+
genuine Microsoft/Node disagreement must be surfaced, never silently
|
|
74
|
+
arbitrated.
|
|
75
|
+
4. **Ask a clarifying question only if genuinely needed** — only when two
|
|
76
|
+
current, equally authoritative sources conflict in a way that changes the
|
|
77
|
+
invoking task.
|
|
78
|
+
5. **Offer an optional snapshot.** Default is inline-only. On explicit
|
|
79
|
+
confirmation, write `docs/research/typescript/<topic-slug>.md`, assembled
|
|
80
|
+
from Step 2's findings + Step 3's synthesis (not re-fetched), with a `>
|
|
81
|
+
**Provenance** —` header naming today's date and the sources consulted.
|
|
82
|
+
|
|
83
|
+
## Refresh mode
|
|
84
|
+
|
|
85
|
+
1. **Read the tracker & establish anchors.** Read
|
|
86
|
+
`docs/research/typescript-refresh.md`, its header
|
|
87
|
+
`<!-- typescript-refresh: last-verified=<date> typescript-version=<version> -->`
|
|
88
|
+
— deliberately the newest **upstream** version last verified, distinct
|
|
89
|
+
from `package.json`'s own `typescript` pin, which this tracker exists to
|
|
90
|
+
check against, not restate. Missing tracker/facet → first run, `NEW`
|
|
91
|
+
only. Then read the allowlist file; state today's date; derive a run
|
|
92
|
+
directory `<scratchpad>/ts-refresh-<date>/`.
|
|
93
|
+
2. **Build the delta.** `WebFetch` the devblog index and
|
|
94
|
+
`github.com/microsoft/TypeScript/releases`; extract entries newer than
|
|
95
|
+
the recorded version. An unreachable source is a coverage gap, not a
|
|
96
|
+
blocker. Pass this delta into all five briefs below — it is not a sixth
|
|
97
|
+
facet.
|
|
98
|
+
3. **Fan out five fixed facets in one message** — fixed, not derived per
|
|
99
|
+
run, so sweeps stay comparable and the tracker stays diffable:
|
|
100
|
+
|
|
101
|
+
| Facet id | Emitted surface it validates |
|
|
102
|
+
| ---------------------------- | --------------------------------------------------------------------------------------- |
|
|
103
|
+
| `compiler-config-flags` | `tsconfig.base.json`, `tsconfig.json` |
|
|
104
|
+
| `modules-esm-node-interop` | `guard-js-extension.mjs`, `guard-no-commonjs.mjs`, the `import-x/extensions` rule |
|
|
105
|
+
| `packaging-declaration-emit` | `check-exports.mjs`, the `exports` map, `isolatedDeclarations` |
|
|
106
|
+
| `lint-typing-rules` | `eslint.config.js`'s preset composition |
|
|
107
|
+
| `testing-language-features` | `vitest.config.ts`, the coverage gate, the choice of runner and testing approach itself |
|
|
108
|
+
|
|
109
|
+
Each brief carries: the facet row, Step 2's delta, the tracker's prior
|
|
110
|
+
claims for that facet, the allowlist + GitHub caveat + date anchor, the
|
|
111
|
+
exact filename to write (`<run-dir>/<facet-id>.md`), and this verdict
|
|
112
|
+
format per claim:
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
CLAIM: <the tracker's prior claim, or "NEW" if none existed>
|
|
116
|
+
VERDICT: UNCHANGED | CHANGED | GONE
|
|
117
|
+
NOW: <the current upstream position, with tier>
|
|
118
|
+
REPO-IMPACT: <which emitted file(s) this affects, or "none">
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Return value: **write the full file, return only a compact digest**
|
|
122
|
+
(counts per verdict + every non-"none" REPO-IMPACT line + the file path).
|
|
123
|
+
|
|
124
|
+
4. **Aggregate.** Read every scratchpad file in full. Four buckets:
|
|
125
|
+
confirmed drift with repo impact (verify each against the cited file
|
|
126
|
+
itself before trusting it — an agent can misread a page), guidance
|
|
127
|
+
changes with no impact, dead/moved URLs, coverage gaps.
|
|
128
|
+
5. **Update the tracker in place** (not a new dated file) — this skill's
|
|
129
|
+
only write outside plan mode. Bump the header date + version, update
|
|
130
|
+
every checked claim's text/URL/date, add `NEW` sources, update the
|
|
131
|
+
outstanding-drift table.
|
|
132
|
+
6. **`EnterPlanMode`** with a remediation plan, one section per
|
|
133
|
+
confirmed-drift item. No drift → skip plan mode, report a clean sweep,
|
|
134
|
+
still update the tracker.
|
|
135
|
+
|
|
136
|
+
## Why this exists, separately from "how is our config wired"
|
|
137
|
+
|
|
138
|
+
Research mode answers "what does upstream say about X." Nothing else in the
|
|
139
|
+
baseline asks the inverse — "is what's already configured still what
|
|
140
|
+
upstream recommends" — because every lint/typecheck/test gate is a closed
|
|
141
|
+
loop checking the repo against its own prior decisions. A stale pin one
|
|
142
|
+
major behind upstream passes every one of those gates cleanly; only a live
|
|
143
|
+
sweep against the actual upstream surfaces it.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Upstream TypeScript sources — the allowlist
|
|
2
|
+
|
|
3
|
+
The single source list consulted by `typescript-guidance` in both modes.
|
|
4
|
+
Editing this file is the one edit site when the tiering changes.
|
|
5
|
+
|
|
6
|
+
## Domain allowlist
|
|
7
|
+
|
|
8
|
+
Pass verbatim as `WebSearch`'s `allowed_domains`:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
typescriptlang.org, www.typescriptlang.org, devblogs.microsoft.com,
|
|
12
|
+
nodejs.org, typescript-eslint.io, arethetypeswrong.github.io, publint.dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Plus **the official docs of a tool the project's interview actually
|
|
16
|
+
selected** for testing/bundling (e.g. `vitest.dev`, a chosen bundler's
|
|
17
|
+
docs) — this is what gives the `testing-language-features` facet a source
|
|
18
|
+
family, since none of the domains above owns a test runner's own docs.
|
|
19
|
+
|
|
20
|
+
Two of the fixed domains are **path-scoped within an otherwise broader
|
|
21
|
+
domain**:
|
|
22
|
+
|
|
23
|
+
- `devblogs.microsoft.com` hosts every Microsoft product's blog. Only
|
|
24
|
+
`/typescript/` paths are in scope here.
|
|
25
|
+
- `nodejs.org` hosts the whole Node.js documentation site. Only `/api/`
|
|
26
|
+
paths — principally `/api/typescript.html` — are in scope here.
|
|
27
|
+
|
|
28
|
+
## The two tiers
|
|
29
|
+
|
|
30
|
+
**T1 — owner-normative.** A claim from here can be cited as-is.
|
|
31
|
+
|
|
32
|
+
- `typescriptlang.org` — the Handbook, the tsconfig reference, the Modules
|
|
33
|
+
reference.
|
|
34
|
+
- `devblogs.microsoft.com/typescript` — release announcements, the
|
|
35
|
+
authoritative record of breaking changes.
|
|
36
|
+
- `github.com/microsoft/TypeScript` — releases, milestones, wiki Design
|
|
37
|
+
Notes.
|
|
38
|
+
- `nodejs.org/api/typescript.html` — co-normative T1 for the
|
|
39
|
+
Node↔TypeScript runtime boundary (type stripping, `erasableSyntaxOnly`).
|
|
40
|
+
A disagreement across that seam is a genuine two-owner conflict to
|
|
41
|
+
surface, not a T1-vs-T2 subordination to resolve silently.
|
|
42
|
+
|
|
43
|
+
**T2 — owner-adjacent / executable spec.** Citable, but state the scope
|
|
44
|
+
limit.
|
|
45
|
+
|
|
46
|
+
- `typescript-eslint.io` — rule semantics, and the exact composition of the
|
|
47
|
+
`recommendedTypeChecked`/`strictTypeChecked`/`stylisticTypeChecked`
|
|
48
|
+
presets.
|
|
49
|
+
- `arethetypeswrong.github.io` — packaging correctness rules (dual-format
|
|
50
|
+
resolution, `exports`-map type resolution failure modes).
|
|
51
|
+
- `publint.dev` — package-publishing correctness rules.
|
|
52
|
+
- The selected test/bundler tool's own docs — behavior and current
|
|
53
|
+
recommendation for that tool specifically.
|
|
54
|
+
|
|
55
|
+
**Explicitly out of scope.** Named here so an agent that finds one of these
|
|
56
|
+
drops it and says so, rather than quietly substituting it for missing T1/T2
|
|
57
|
+
coverage:
|
|
58
|
+
|
|
59
|
+
- `github.com/tsconfig/bases` — actively maintained ecosystem consensus,
|
|
60
|
+
but consensus, not the owner's word.
|
|
61
|
+
- Individual authors and their published material — no normative standing.
|
|
62
|
+
|
|
63
|
+
## GitHub caveat
|
|
64
|
+
|
|
65
|
+
`allowed_domains` filters by domain, not path, so a bare `github.com`
|
|
66
|
+
allowance would let through any repo. Agents may include `github.com` and
|
|
67
|
+
`raw.githubusercontent.com` in their search domains, but must **only cite or
|
|
68
|
+
fetch URLs under `microsoft/TypeScript`, `microsoft/TypeScript-Website`, or
|
|
69
|
+
`arethetypeswrong/arethetypeswrong.github.io`** — and drop any other GitHub
|
|
70
|
+
result, however highly ranked.
|
|
71
|
+
|
|
72
|
+
## First-class sources to enumerate directly
|
|
73
|
+
|
|
74
|
+
Search ranking is not exhaustive — a recent devblog post or an individual
|
|
75
|
+
tsconfig option page can rank poorly and simply not surface. Enumerate these
|
|
76
|
+
directly rather than relying on search alone:
|
|
77
|
+
|
|
78
|
+
- `https://devblogs.microsoft.com/typescript/` — the release-announcement
|
|
79
|
+
index; read as a **delta** from a known prior version in refresh mode.
|
|
80
|
+
- `https://github.com/microsoft/TypeScript/releases` — the machine-readable
|
|
81
|
+
version list; cross-check the devblog against it.
|
|
82
|
+
- `https://www.typescriptlang.org/tsconfig/` — the per-option compiler-flag
|
|
83
|
+
reference.
|
|
84
|
+
- `https://www.typescriptlang.org/docs/handbook/modules/reference.html` —
|
|
85
|
+
the Modules reference (`nodenext`/`bundler` resolution modes, ESM/CJS
|
|
86
|
+
interop).
|
|
87
|
+
- `https://nodejs.org/api/typescript.html` — Node's type-stripping page.
|
|
88
|
+
- `https://typescript-eslint.io/users/configs/` — preset composition.
|
|
89
|
+
|
|
90
|
+
## Coverage discipline
|
|
91
|
+
|
|
92
|
+
Reject any non-allowlisted domain outright and say so in the report, rather
|
|
93
|
+
than substituting a community blog, an individual author's material, or a
|
|
94
|
+
Stack Overflow answer for missing T1/T2 coverage. If a facet turns up no
|
|
95
|
+
qualifying source, that is itself a reportable finding (a coverage gap), not
|
|
96
|
+
a reason to lower the bar.
|
|
97
|
+
|
|
98
|
+
## Current-date anchor
|
|
99
|
+
|
|
100
|
+
Every agent brief must state today's date explicitly — a `retrieved <date>`
|
|
101
|
+
stamp otherwise depends on the spoke inferring the date itself, which is
|
|
102
|
+
unreliable.
|