@tanstack/intent 0.0.32 → 0.0.34

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 (37) hide show
  1. package/README.md +7 -7
  2. package/dist/artifact-coverage-BAN2W6aH.mjs +3 -0
  3. package/dist/artifact-coverage-wLNVX8yC.mjs +128 -0
  4. package/dist/cli.mjs +248 -99
  5. package/dist/{display-DCRCp4-C.mjs → display-B3vkG99D.mjs} +1 -1
  6. package/dist/index.d.mts +22 -4
  7. package/dist/index.mjs +10 -8
  8. package/dist/{install-BmVqcbEi.mjs → install-QjryhQtg.mjs} +54 -18
  9. package/dist/intent-library.mjs +5 -5
  10. package/dist/library-scanner.d.mts +1 -1
  11. package/dist/library-scanner.mjs +1 -1
  12. package/dist/{project-context-CKG-q4rD.mjs → project-context-alYMNoNa.mjs} +1 -1
  13. package/dist/{resolver-aFigTqXi.mjs → resolver-Whd12ksO.mjs} +1 -1
  14. package/dist/scanner-BAZxWeUk.mjs +6 -0
  15. package/dist/{scanner-DKL8v8is.mjs → scanner-Dav1tzQK.mjs} +79 -4
  16. package/dist/{setup-JJvjiGkM.mjs → setup-Dp-W8y0Y.mjs} +2 -2
  17. package/dist/setup.d.mts +1 -1
  18. package/dist/setup.mjs +3 -3
  19. package/dist/staleness-DpbmYod4.mjs +5 -0
  20. package/dist/staleness-PdgakrCQ.mjs +243 -0
  21. package/dist/{types-CsySN6Vw.d.mts → types-DT7Y6TFz.d.mts} +48 -1
  22. package/dist/workflow-review-CwkPVIQf.mjs +153 -0
  23. package/dist/workflow-review-Dz_ofcYQ.mjs +3 -0
  24. package/dist/{workspace-patterns-U35B5AO-.mjs → workspace-patterns-BN2A_60g.mjs} +6 -1
  25. package/dist/workspace-patterns-x-dLZxx4.mjs +4 -0
  26. package/meta/templates/workflows/check-skills.yml +58 -96
  27. package/package.json +1 -1
  28. package/dist/scanner-CRZITpcY.mjs +0 -6
  29. package/dist/staleness-DorwfGrf.mjs +0 -104
  30. package/dist/staleness-NF-lxfXf.mjs +0 -4
  31. package/dist/workspace-patterns-DbnA0peB.mjs +0 -4
  32. package/meta/templates/workflows/notify-intent.yml +0 -51
  33. package/meta/templates/workflows/validate-skills.yml +0 -52
  34. /package/dist/{display-DUgtRJkt.mjs → display-CAof6doy.mjs} +0 -0
  35. /package/dist/{library-scanner-DFFreLjW.mjs → library-scanner-fexXlPXb.mjs} +0 -0
  36. /package/dist/{setup-DDoOLriA.d.mts → setup-t1i2o2-h.d.mts} +0 -0
  37. /package/dist/{skill-use-CXOnncWK.mjs → skill-use-BzuuvLM7.mjs} +0 -0
@@ -0,0 +1,153 @@
1
+ import { appendFileSync, writeFileSync } from "node:fs";
2
+
3
+ //#region src/workflow-review.ts
4
+ function collectStaleReviewItems(reports) {
5
+ const items = [];
6
+ for (const report of reports) {
7
+ for (const skill of report.skills ?? []) {
8
+ if (!skill?.needsReview) continue;
9
+ items.push({
10
+ type: "stale-skill",
11
+ library: report.library,
12
+ subject: skill.name,
13
+ reasons: skill.reasons ?? []
14
+ });
15
+ }
16
+ for (const signal of report.signals ?? []) {
17
+ if (signal?.needsReview === false) continue;
18
+ items.push({
19
+ type: signal?.type ?? "review-signal",
20
+ library: signal?.library ?? report.library,
21
+ subject: signal?.packageName ?? signal?.packageRoot ?? signal?.skill ?? signal?.artifactPath ?? signal?.subject ?? report.library,
22
+ reasons: signal?.reasons ?? [],
23
+ artifactPath: signal?.artifactPath,
24
+ packageName: signal?.packageName,
25
+ packageRoot: signal?.packageRoot,
26
+ skill: signal?.skill
27
+ });
28
+ }
29
+ }
30
+ return items;
31
+ }
32
+ function createFailedStaleReviewItem(library) {
33
+ return {
34
+ type: "stale-check-failed",
35
+ library,
36
+ subject: "intent stale --json",
37
+ reasons: ["The stale check command failed. Review the workflow logs before updating skills."]
38
+ };
39
+ }
40
+ function createWorkflowAdvisoryReviewItems(library, advisories) {
41
+ return advisories.map((advisory) => ({
42
+ type: "workflow-advisory",
43
+ library,
44
+ subject: "check-skills.yml",
45
+ reasons: [advisory]
46
+ }));
47
+ }
48
+ function buildStaleReviewBody(items) {
49
+ const grouped = /* @__PURE__ */ new Map();
50
+ for (const item of items) grouped.set(item.type, (grouped.get(item.type) ?? 0) + 1);
51
+ const signalRows = [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([type, count]) => `| \`${type}\` | ${count} |`);
52
+ const itemRows = items.map((item) => {
53
+ const subject = item.subject ? `\`${item.subject}\`` : "-";
54
+ const reasons = item.reasons?.length ? item.reasons.join("; ") : "-";
55
+ return `| \`${item.type}\` | ${subject} | \`${item.library}\` | ${reasons} |`;
56
+ });
57
+ const reasonBullets = items.map((item) => {
58
+ const subject = item.subject ? `\`${item.subject}\`` : "`unknown`";
59
+ const reasons = item.reasons?.length ? item.reasons.join("; ") : "Intent did not emit a detailed reason for this signal.";
60
+ return `- \`${item.type}\` for ${subject}: ${reasons}`;
61
+ });
62
+ const prompt = [
63
+ "You are helping maintain Intent skills for this repository.",
64
+ "",
65
+ "Goal:",
66
+ "Resolve the Intent skill review signals below while preserving the existing scope, taxonomy, and maintainer-reviewed artifacts.",
67
+ "",
68
+ "Review signals:",
69
+ JSON.stringify(items, null, 2),
70
+ "",
71
+ "Required workflow:",
72
+ "1. Read the existing `_artifacts/*domain_map.yaml`, `_artifacts/*skill_tree.yaml`, and generated `skills/**/SKILL.md` files.",
73
+ "2. Read each flagged package package.json, public exports, README/docs if present, and source entry points.",
74
+ "3. Compare flagged packages against the existing domains, skills, tasks, packages, covers, sources, tensions, and cross-references in the artifacts.",
75
+ "4. For each signal, decide whether it means existing skill coverage, a missing generated skill, a new skill candidate, out-of-scope coverage, or deferred work.",
76
+ "",
77
+ "Maintainer questions:",
78
+ "Before editing skills or artifacts, ask the maintainer:",
79
+ "1. For each flagged package, is this package user-facing enough to need agent guidance?",
80
+ "2. If yes, should it extend an existing skill or become a new skill?",
81
+ "3. If it extends an existing skill, which current skill should own it?",
82
+ "4. If it is out of scope, what short reason should be recorded in artifact coverage ignores?",
83
+ "5. Are any of these packages experimental or unstable enough to exclude for now?",
84
+ "",
85
+ "Decision rules:",
86
+ "- Do not auto-generate skills.",
87
+ "- Do not create broad new skill areas without maintainer confirmation.",
88
+ "- Prefer adding package coverage to an existing skill when the package is an implementation variant of an existing domain.",
89
+ "- Create a new skill only when the package introduces a distinct developer task or failure mode.",
90
+ "- Preserve current naming, path, and package layout conventions.",
91
+ "- Keep generated skills under the package-local `skills/` directory.",
92
+ "- Keep repo-root `_artifacts` as the reviewed plan.",
93
+ "",
94
+ "If maintainer confirms updates:",
95
+ "1. Update the relevant `_artifacts/*domain_map.yaml` or `_artifacts/*skill_tree.yaml`.",
96
+ "2. Update or create `SKILL.md` files only for confirmed coverage changes.",
97
+ "3. Keep `sources` aligned between artifact skill entries and SKILL frontmatter.",
98
+ "4. Bump `library_version` only for skills whose covered source package version changed.",
99
+ "5. Run `npx @tanstack/intent@latest validate` on touched skill directories.",
100
+ "6. Summarize every package as one of: existing-skill coverage, new skill, ignored, or deferred."
101
+ ].join("\n");
102
+ return [
103
+ "## Intent Skill Review Needed",
104
+ "",
105
+ "Intent found skills, artifact coverage, or workspace package coverage that need maintainer review.",
106
+ "",
107
+ "### Summary",
108
+ "",
109
+ "| Signal | Count |",
110
+ "| --- | ---: |",
111
+ ...signalRows,
112
+ "",
113
+ "### Why This PR Opened",
114
+ "",
115
+ ...reasonBullets,
116
+ "",
117
+ "### Review Items",
118
+ "",
119
+ "| Signal | Subject | Library | Reason |",
120
+ "| --- | --- | --- | --- |",
121
+ ...itemRows,
122
+ "",
123
+ "### Agent Prompt",
124
+ "",
125
+ "Paste this into your coding agent:",
126
+ "",
127
+ "```text",
128
+ prompt,
129
+ "```",
130
+ "",
131
+ "This PR is a review reminder only. It does not update skills automatically."
132
+ ].join("\n");
133
+ }
134
+ function writeStaleReviewWorkflowFiles(items, options = {}) {
135
+ const outputPath = options.outputPath ?? process.env.GITHUB_OUTPUT;
136
+ const summaryPath = options.summaryPath ?? process.env.GITHUB_STEP_SUMMARY;
137
+ const reviewItemsPath = options.reviewItemsPath ?? "review-items.json";
138
+ const prBodyPath = options.prBodyPath ?? "pr-body.md";
139
+ const hasReview = items.length > 0;
140
+ writeFileSync(reviewItemsPath, JSON.stringify(items, null, 2) + "\n");
141
+ if (outputPath) appendFileSync(outputPath, `has_review=${hasReview ? "true" : "false"}\n`);
142
+ const summary = hasReview ? buildStaleReviewBody(items) + "\n" : [
143
+ "### Intent skill review",
144
+ "",
145
+ "No stale skills or coverage gaps found.",
146
+ ""
147
+ ].join("\n");
148
+ if (hasReview) writeFileSync(prBodyPath, summary);
149
+ if (summaryPath) appendFileSync(summaryPath, summary);
150
+ }
151
+
152
+ //#endregion
153
+ export { writeStaleReviewWorkflowFiles as a, createWorkflowAdvisoryReviewItems as i, collectStaleReviewItems as n, createFailedStaleReviewItem as r, buildStaleReviewBody as t };
@@ -0,0 +1,3 @@
1
+ import { a as writeStaleReviewWorkflowFiles, i as createWorkflowAdvisoryReviewItems, n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-CwkPVIQf.mjs";
2
+
3
+ export { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles };
@@ -162,6 +162,11 @@ function findPackagesWithSkills(root) {
162
162
  return existsSync(skillsDir) && findSkillFiles(skillsDir).length > 0;
163
163
  });
164
164
  }
165
+ function findWorkspacePackages(root) {
166
+ const patterns = readWorkspacePatterns(root);
167
+ if (!patterns) return [];
168
+ return resolveWorkspacePackages(root, patterns);
169
+ }
165
170
 
166
171
  //#endregion
167
- export { resolveWorkspacePackages as i, findWorkspaceRoot as n, readWorkspacePatterns as r, findPackagesWithSkills as t };
172
+ export { resolveWorkspacePackages as a, readWorkspacePatterns as i, findWorkspacePackages as n, findWorkspaceRoot as r, findPackagesWithSkills as t };
@@ -0,0 +1,4 @@
1
+ import "./utils-COlDcU72.mjs";
2
+ import { a as resolveWorkspacePackages, i as readWorkspacePatterns, n as findWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-BN2A_60g.mjs";
3
+
4
+ export { findPackagesWithSkills, findWorkspacePackages, findWorkspaceRoot };
@@ -1,10 +1,13 @@
1
1
  # check-skills.yml — Drop this into your library repo's .github/workflows/
2
2
  #
3
- # Checks for stale intent skills after a release and opens a review PR
4
- # if any skills need attention. The PR body includes a prompt you can
5
- # paste into Claude Code, Cursor, or any coding agent to update them.
3
+ # Validates intent skills on PRs. After a release or manual run, opens or
4
+ # updates one review PR when existing skills, artifact coverage, or workspace
5
+ # package coverage need review.
6
6
  #
7
- # Triggers: new release published, or manual workflow_dispatch.
7
+ # Triggers: pull requests touching skills/artifacts, new release published, or
8
+ # manual workflow_dispatch.
9
+ #
10
+ # intent-workflow-version: 3
8
11
  #
9
12
  # Template variables (replaced by `intent setup`):
10
13
  # {{PACKAGE_LABEL}} — e.g. @tanstack/query or my-workspace workspace
@@ -12,6 +15,12 @@
12
15
  name: Check Skills
13
16
 
14
17
  on:
18
+ pull_request:
19
+ paths:
20
+ - 'skills/**'
21
+ - '**/skills/**'
22
+ - '_artifacts/**'
23
+ - '**/_artifacts/**'
15
24
  release:
16
25
  types: [published]
17
26
  workflow_dispatch: {}
@@ -21,14 +30,13 @@ permissions:
21
30
  pull-requests: write
22
31
 
23
32
  jobs:
24
- check:
25
- name: Check for stale skills
33
+ validate:
34
+ name: Validate intent skills
35
+ if: github.event_name == 'pull_request'
26
36
  runs-on: ubuntu-latest
27
37
  steps:
28
38
  - name: Checkout
29
39
  uses: actions/checkout@v4
30
- with:
31
- fetch-depth: 0
32
40
 
33
41
  - name: Setup Node
34
42
  uses: actions/setup-node@v4
@@ -38,106 +46,60 @@ jobs:
38
46
  - name: Install intent
39
47
  run: npm install -g @tanstack/intent
40
48
 
41
- - name: Check staleness
42
- id: stale
43
- run: |
44
- OUTPUT=$(intent stale --json 2>&1) || true
45
- echo "$OUTPUT"
49
+ - name: Validate skills
50
+ run: intent validate --github-summary
46
51
 
47
- # Check if any skills need review
48
- NEEDS_REVIEW=$(echo "$OUTPUT" | node -e "
49
- const input = require('fs').readFileSync('/dev/stdin','utf8');
50
- try {
51
- const reports = JSON.parse(input);
52
- const stale = reports.flatMap(r =>
53
- r.skills.filter(s => s.needsReview).map(s => ({ library: r.library, skill: s.name, reasons: s.reasons }))
54
- );
55
- if (stale.length > 0) {
56
- console.log(JSON.stringify(stale));
57
- }
58
- } catch {}
59
- ")
60
-
61
- if [ -z "$NEEDS_REVIEW" ]; then
62
- echo "has_stale=false" >> "$GITHUB_OUTPUT"
63
- else
64
- echo "has_stale=true" >> "$GITHUB_OUTPUT"
65
- # Escape for multiline GH output
66
- EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
67
- echo "stale_json<<$EOF" >> "$GITHUB_OUTPUT"
68
- echo "$NEEDS_REVIEW" >> "$GITHUB_OUTPUT"
69
- echo "$EOF" >> "$GITHUB_OUTPUT"
70
- fi
52
+ review:
53
+ name: Check intent skill coverage
54
+ if: github.event_name != 'pull_request'
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - name: Checkout
58
+ uses: actions/checkout@v4
59
+ with:
60
+ fetch-depth: 0
71
61
 
72
- - name: Build summary
73
- if: steps.stale.outputs.has_stale == 'true'
74
- id: summary
75
- run: |
76
- node -e "
77
- const stale = JSON.parse(process.env.STALE_JSON);
78
- const lines = stale.map(s =>
79
- '- **' + s.skill + '** (' + s.library + '): ' + s.reasons.join(', ')
80
- );
81
- const summary = lines.join('\n');
62
+ - name: Setup Node
63
+ uses: actions/setup-node@v4
64
+ with:
65
+ node-version: 20
82
66
 
83
- const prompt = [
84
- 'Review and update the following stale intent skills for {{PACKAGE_LABEL}}:',
85
- '',
86
- ...stale.map(s => '- ' + s.skill + ': ' + s.reasons.join(', ')),
87
- '',
88
- 'For each stale skill:',
89
- '1. Read the current SKILL.md file',
90
- '2. Check what changed in the library since the skill was last updated',
91
- '3. Update the skill content to reflect current APIs and behavior',
92
- '4. Run \`npx @tanstack/intent validate\` to verify the updated skill',
93
- ].join('\n');
67
+ - name: Install intent
68
+ run: npm install -g @tanstack/intent
94
69
 
95
- // Write outputs
96
- const fs = require('fs');
97
- const env = fs.readFileSync(process.env.GITHUB_OUTPUT, 'utf8');
98
- const eof = require('crypto').randomBytes(15).toString('base64');
99
- fs.appendFileSync(process.env.GITHUB_OUTPUT,
100
- 'summary<<' + eof + '\n' + summary + '\n' + eof + '\n' +
101
- 'prompt<<' + eof + '\n' + prompt + '\n' + eof + '\n'
102
- );
103
- "
104
- env:
105
- STALE_JSON: ${{ steps.stale.outputs.stale_json }}
70
+ - name: Check skills
71
+ id: stale
72
+ run: |
73
+ intent stale --github-review --package-label "{{PACKAGE_LABEL}}"
106
74
 
107
- - name: Open review PR
108
- if: steps.stale.outputs.has_stale == 'true'
75
+ - name: Open or update review PR
76
+ if: steps.stale.outputs.has_review == 'true'
109
77
  env:
110
78
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
111
79
  run: |
112
80
  VERSION="${{ github.event.release.tag_name || 'manual' }}"
113
81
  BRANCH="skills/review-${VERSION}"
82
+ BASE_BRANCH="${{ github.event.repository.default_branch }}"
114
83
 
115
84
  git config user.name "github-actions[bot]"
116
85
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
117
- git checkout -b "$BRANCH"
118
- git commit --allow-empty -m "chore: review stale skills for ${VERSION}"
119
- git push origin "$BRANCH"
120
-
121
- gh pr create \
122
- --title "Review stale skills (${VERSION})" \
123
- --body "$(cat <<'PREOF'
124
- ## Stale Skills Detected
125
-
126
- The following skills may need updates after the latest release:
127
86
 
128
- ${{ steps.summary.outputs.summary }}
129
-
130
- ---
131
-
132
- ### Update Prompt
133
-
134
- Paste this into your coding agent (Claude Code, Cursor, etc.):
135
-
136
- ~~~
137
- ${{ steps.summary.outputs.prompt }}
138
- ~~~
87
+ git fetch origin "$BRANCH" || true
88
+ if git show-ref --verify --quiet "refs/remotes/origin/$BRANCH"; then
89
+ git checkout -B "$BRANCH" "origin/$BRANCH"
90
+ else
91
+ git checkout -b "$BRANCH"
92
+ git commit --allow-empty -m "chore: review intent skills for ${VERSION}"
93
+ git push origin "$BRANCH"
94
+ fi
139
95
 
140
- PREOF
141
- )" \
142
- --head "$BRANCH" \
143
- --base main
96
+ PR_URL="$(gh pr list --head "$BRANCH" --json url --jq '.[0].url')"
97
+ if [ -n "$PR_URL" ]; then
98
+ gh pr edit "$PR_URL" --body-file pr-body.md
99
+ else
100
+ gh pr create \
101
+ --title "Review intent skills (${VERSION})" \
102
+ --body-file pr-body.md \
103
+ --head "$BRANCH" \
104
+ --base "$BASE_BRANCH"
105
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/intent",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +0,0 @@
1
- import "./utils-COlDcU72.mjs";
2
- import "./skill-paths-8k9K9y26.mjs";
3
- import { t as scanForIntents } from "./scanner-DKL8v8is.mjs";
4
- import "./workspace-patterns-U35B5AO-.mjs";
5
-
6
- export { scanForIntents };
@@ -1,104 +0,0 @@
1
- import { a as parseFrontmatter, n as findSkillFiles } from "./utils-COlDcU72.mjs";
2
- import { readFileSync } from "node:fs";
3
- import { join, relative, sep } from "node:path";
4
-
5
- //#region src/staleness.ts
6
- function classifyVersionDrift(oldVer, newVer) {
7
- if (oldVer === newVer) return null;
8
- const oldParts = oldVer.replace(/[^0-9.]/g, "").split(".").map(Number);
9
- const newParts = newVer.replace(/[^0-9.]/g, "").split(".").map(Number);
10
- if ((newParts[0] ?? 0) > (oldParts[0] ?? 0)) return "major";
11
- if ((newParts[1] ?? 0) > (oldParts[1] ?? 0)) return "minor";
12
- if ((newParts[2] ?? 0) > (oldParts[2] ?? 0)) return "patch";
13
- return null;
14
- }
15
- function readLocalVersion(packageDir) {
16
- try {
17
- const pkgJson = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
18
- return typeof pkgJson.version === "string" ? pkgJson.version : null;
19
- } catch {
20
- return null;
21
- }
22
- }
23
- async function fetchNpmVersion(packageName) {
24
- try {
25
- const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`);
26
- if (!res.ok) return null;
27
- const data = await res.json();
28
- return typeof data.version === "string" ? data.version : null;
29
- } catch {
30
- return null;
31
- }
32
- }
33
- async function fetchCurrentVersion(packageDir, packageName) {
34
- return readLocalVersion(packageDir) ?? await fetchNpmVersion(packageName);
35
- }
36
- function isStringRecord(value) {
37
- return !!value && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
38
- }
39
- function parseSyncState(value) {
40
- if (!value || typeof value !== "object") return null;
41
- const raw = value;
42
- const parsed = {};
43
- if (typeof raw.library_version === "string") parsed.library_version = raw.library_version;
44
- if (raw.skills && typeof raw.skills === "object") {
45
- const skills = {};
46
- for (const [skillName, skillValue] of Object.entries(raw.skills)) {
47
- if (!skillValue || typeof skillValue !== "object") continue;
48
- const sourcesSha = skillValue.sources_sha;
49
- if (sourcesSha !== void 0 && !isStringRecord(sourcesSha)) continue;
50
- skills[skillName] = {};
51
- if (sourcesSha) skills[skillName].sources_sha = sourcesSha;
52
- }
53
- parsed.skills = skills;
54
- }
55
- return parsed;
56
- }
57
- function readSyncState(packageDir) {
58
- const statePath = join(packageDir, "skills", "sync-state.json");
59
- try {
60
- return parseSyncState(JSON.parse(readFileSync(statePath, "utf8")));
61
- } catch {
62
- return null;
63
- }
64
- }
65
- async function checkStaleness(packageDir, packageName) {
66
- const skillsDir = join(packageDir, "skills");
67
- const library = packageName ?? "unknown";
68
- const skillMetas = findSkillFiles(skillsDir).map((filePath) => {
69
- const fm = parseFrontmatter(filePath);
70
- const relName = relative(skillsDir, filePath).replace(/[/\\]SKILL\.md$/, "").split(sep).join("/");
71
- return {
72
- name: typeof fm?.name === "string" ? fm.name : relName,
73
- filePath,
74
- libraryVersion: fm?.library_version,
75
- sources: Array.isArray(fm?.sources) ? fm.sources : void 0
76
- };
77
- });
78
- const skillVersion = skillMetas.find((s) => s.libraryVersion)?.libraryVersion ?? null;
79
- const currentVersion = await fetchCurrentVersion(packageDir, library);
80
- const versionDrift = skillVersion && currentVersion ? classifyVersionDrift(skillVersion, currentVersion) : null;
81
- const syncState = readSyncState(packageDir);
82
- return {
83
- library,
84
- currentVersion,
85
- skillVersion,
86
- versionDrift,
87
- skills: skillMetas.map((skill) => {
88
- const reasons = [];
89
- if (currentVersion && skill.libraryVersion && skill.libraryVersion !== currentVersion) reasons.push(`version drift (${skill.libraryVersion} → ${currentVersion})`);
90
- const storedShas = syncState?.skills?.[skill.name]?.sources_sha ?? {};
91
- if (skill.sources && Object.keys(storedShas).length > 0) {
92
- for (const source of skill.sources) if (!storedShas[source]) reasons.push(`new source (${source})`);
93
- }
94
- return {
95
- name: skill.name,
96
- reasons,
97
- needsReview: reasons.length > 0
98
- };
99
- })
100
- };
101
- }
102
-
103
- //#endregion
104
- export { checkStaleness as t };
@@ -1,4 +0,0 @@
1
- import "./utils-COlDcU72.mjs";
2
- import { t as checkStaleness } from "./staleness-DorwfGrf.mjs";
3
-
4
- export { checkStaleness };
@@ -1,4 +0,0 @@
1
- import "./utils-COlDcU72.mjs";
2
- import { i as resolveWorkspacePackages, n as findWorkspaceRoot, r as readWorkspacePatterns, t as findPackagesWithSkills } from "./workspace-patterns-U35B5AO-.mjs";
3
-
4
- export { findPackagesWithSkills, findWorkspaceRoot };
@@ -1,51 +0,0 @@
1
- # notify-intent.yml — Drop this into your library repo's .github/workflows/
2
- #
3
- # Fires a repository_dispatch event whenever docs or source files change
4
- # on merge to main. This triggers the skill staleness check workflow.
5
- #
6
- # Requirements:
7
- # - A fine-grained PAT with contents:write on this repository stored
8
- # as the INTENT_NOTIFY_TOKEN repository secret.
9
- #
10
- # Template variables (replaced by `intent setup`):
11
- # {{PAYLOAD_PACKAGE}} — e.g. @tanstack/query or my-workspace workspace
12
- # {{DOCS_PATH}} — e.g. docs/**
13
- # {{SRC_PATH}} — e.g. packages/query-core/src/**
14
-
15
- name: Trigger Skill Review
16
-
17
- on:
18
- push:
19
- branches: [main]
20
- paths:
21
- - '{{DOCS_PATH}}'
22
- - '{{SRC_PATH}}'
23
-
24
- jobs:
25
- notify:
26
- name: Trigger Skill Review
27
- runs-on: ubuntu-latest
28
- steps:
29
- - name: Checkout
30
- uses: actions/checkout@v4
31
- with:
32
- fetch-depth: 2
33
-
34
- - name: Collect changed files
35
- id: changes
36
- run: |
37
- FILES=$(git diff --name-only HEAD~1 HEAD | jq -R -s -c 'split("\n") | map(select(length > 0))')
38
- echo "files=$FILES" >> "$GITHUB_OUTPUT"
39
-
40
- - name: Dispatch to intent repo
41
- uses: peter-evans/repository-dispatch@v3
42
- with:
43
- token: ${{ secrets.INTENT_NOTIFY_TOKEN }}
44
- repository: ${{ github.repository }}
45
- event-type: skill-check
46
- client-payload: |
47
- {
48
- "package": "{{PAYLOAD_PACKAGE}}",
49
- "sha": "${{ github.sha }}",
50
- "changed_files": ${{ steps.changes.outputs.files }}
51
- }
@@ -1,52 +0,0 @@
1
- # validate-skills.yml — Drop this into your library repo's .github/workflows/
2
- #
3
- # Validates skill files on PRs that touch the skills/ directory.
4
- # Ensures frontmatter is correct, names match paths, and files stay under
5
- # the 500-line limit.
6
-
7
- name: Validate Skills
8
-
9
- on:
10
- pull_request:
11
- paths:
12
- - 'skills/**'
13
- - '**/skills/**'
14
-
15
- jobs:
16
- validate:
17
- name: Validate skill files
18
- runs-on: ubuntu-latest
19
- steps:
20
- - name: Checkout
21
- uses: actions/checkout@v4
22
-
23
- - name: Setup Node
24
- uses: actions/setup-node@v4
25
- with:
26
- node-version: 20
27
-
28
- - name: Install intent CLI
29
- run: npm install -g @tanstack/intent
30
-
31
- - name: Find and validate skills
32
- run: |
33
- # Find all directories containing SKILL.md files
34
- SKILLS_DIR=""
35
- if [ -d "skills" ]; then
36
- SKILLS_DIR="skills"
37
- elif [ -d "packages" ]; then
38
- # Monorepo — find skills/ under packages
39
- for dir in packages/*/skills; do
40
- if [ -d "$dir" ]; then
41
- echo "Validating $dir..."
42
- intent validate "$dir"
43
- fi
44
- done
45
- exit 0
46
- fi
47
-
48
- if [ -n "$SKILLS_DIR" ]; then
49
- intent validate "$SKILLS_DIR"
50
- else
51
- echo "No skills/ directory found — skipping validation."
52
- fi