@tanstack/intent 0.0.3 → 0.0.5
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 +2 -2
- package/dist/cli.mjs +4 -4
- package/dist/index.mjs +3 -3
- package/dist/intent-library.mjs +71 -10
- package/dist/{library-scanner-D0aP7is_.mjs → library-scanner-BrznE00j.mjs} +2 -5
- package/dist/library-scanner.mjs +2 -2
- package/dist/scanner-BuWPDJ4P.mjs +4 -0
- package/dist/{scanner-BwCyu1Jq.mjs → scanner-CpsJAHXT.mjs} +6 -15
- package/dist/{staleness-lP6B0O4z.mjs → staleness-CnomT9Hm.mjs} +1 -1
- package/dist/staleness-DyhsrqQ5.mjs +4 -0
- package/dist/{utils-DH3jY3CI.mjs → utils-DjkEPBxu.mjs} +1 -1
- package/meta/feedback-collection/SKILL.md +156 -0
- package/meta/skill-staleness-check/SKILL.md +9 -9
- package/meta/templates/workflows/check-skills.yml +143 -0
- package/package.json +1 -1
- package/dist/scanner-fAWJUn6Q.mjs +0 -4
- package/dist/staleness-B5gUj7FR.mjs +0 -4
- package/meta/templates/oz/domain-discovery.md +0 -53
- package/meta/templates/oz/feedback-collection.md +0 -69
- package/meta/templates/oz/skill-update.md +0 -47
- package/meta/templates/oz/tree-generation.md +0 -48
- package/meta/templates/workflows/generate-skills-oz.yml +0 -86
- package/meta/templates/workflows/update-skills-oz.yml +0 -98
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ Validate your skill files:
|
|
|
42
42
|
npx intent validate
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Copy CI
|
|
45
|
+
Copy CI workflow templates into your repo:
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
npx intent setup
|
|
@@ -57,7 +57,7 @@ npx intent setup
|
|
|
57
57
|
| `intent meta` | List meta-skills for library maintainers |
|
|
58
58
|
| `intent scaffold` | Print the guided skill generation prompt |
|
|
59
59
|
| `intent validate [dir]` | Validate SKILL.md files |
|
|
60
|
-
| `intent setup` | Copy CI
|
|
60
|
+
| `intent setup` | Copy CI workflow templates |
|
|
61
61
|
| `intent stale [--json]` | Check skills for version drift |
|
|
62
62
|
| `intent feedback` | Submit skill feedback |
|
|
63
63
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-
|
|
3
|
-
import { t as scanForIntents } from "./scanner-
|
|
2
|
+
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-DjkEPBxu.mjs";
|
|
3
|
+
import { t as scanForIntents } from "./scanner-CpsJAHXT.mjs";
|
|
4
4
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
5
5
|
import { dirname, join, relative, sep } from "node:path";
|
|
6
6
|
import { parse } from "yaml";
|
|
@@ -339,8 +339,8 @@ switch (command) {
|
|
|
339
339
|
cmdScaffold();
|
|
340
340
|
break;
|
|
341
341
|
case "stale": {
|
|
342
|
-
const { checkStaleness } = await import("./staleness-
|
|
343
|
-
const { scanForIntents: scanStale } = await import("./scanner-
|
|
342
|
+
const { checkStaleness } = await import("./staleness-DyhsrqQ5.mjs");
|
|
343
|
+
const { scanForIntents: scanStale } = await import("./scanner-BuWPDJ4P.mjs");
|
|
344
344
|
let staleResult;
|
|
345
345
|
try {
|
|
346
346
|
staleResult = await scanStale();
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-
|
|
2
|
-
import { t as scanForIntents } from "./scanner-
|
|
3
|
-
import { t as checkStaleness } from "./staleness-
|
|
1
|
+
import { n as parseFrontmatter, t as findSkillFiles } from "./utils-DjkEPBxu.mjs";
|
|
2
|
+
import { t as scanForIntents } from "./scanner-CpsJAHXT.mjs";
|
|
3
|
+
import { t as checkStaleness } from "./staleness-CnomT9Hm.mjs";
|
|
4
4
|
import { c as toMarkdown, i as resolveFrequency, l as validateMetaPayload, n as hasGhCli, o as submitFeedback, r as metaToMarkdown, s as submitMetaFeedback, t as containsSecrets, u as validatePayload } from "./feedback-DKreHfB1.mjs";
|
|
5
5
|
import { a as runInit, i as readProjectConfig, n as hasIntentBlock, o as writeProjectConfig, r as injectIntentBlock, t as detectAgentConfigs } from "./init-DNxmjQfU.mjs";
|
|
6
6
|
import { t as runSetup } from "./setup-CNGz26qL.mjs";
|
package/dist/intent-library.mjs
CHANGED
|
@@ -1,8 +1,57 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./utils-
|
|
3
|
-
import { t as scanLibrary } from "./library-scanner-
|
|
2
|
+
import "./utils-DjkEPBxu.mjs";
|
|
3
|
+
import { t as scanLibrary } from "./library-scanner-BrznE00j.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/intent-library.ts
|
|
6
|
+
function padColumn(text, width) {
|
|
7
|
+
return text.length >= width ? text + " " : text.padEnd(width);
|
|
8
|
+
}
|
|
9
|
+
function printTable(headers, rows) {
|
|
10
|
+
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)) + 2);
|
|
11
|
+
const headerLine = headers.map((h, i) => padColumn(h, widths[i])).join("");
|
|
12
|
+
const separator = widths.map((w) => "─".repeat(w)).join("");
|
|
13
|
+
console.log(headerLine);
|
|
14
|
+
console.log(separator);
|
|
15
|
+
for (const row of rows) console.log(row.map((cell, i) => padColumn(cell, widths[i])).join(""));
|
|
16
|
+
}
|
|
17
|
+
function printSkillTree(skills, opts) {
|
|
18
|
+
const roots = [];
|
|
19
|
+
const children = /* @__PURE__ */ new Map();
|
|
20
|
+
for (const skill of skills) {
|
|
21
|
+
const slashIdx = skill.name.indexOf("/");
|
|
22
|
+
if (slashIdx === -1) roots.push(skill.name);
|
|
23
|
+
else {
|
|
24
|
+
const parent = skill.name.slice(0, slashIdx);
|
|
25
|
+
if (!children.has(parent)) children.set(parent, []);
|
|
26
|
+
children.get(parent).push(skill);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (roots.length === 0) {
|
|
30
|
+
for (const skill of skills) if (!roots.includes(skill.name)) roots.push(skill.name);
|
|
31
|
+
}
|
|
32
|
+
for (const rootName of roots) {
|
|
33
|
+
const rootSkill = skills.find((s) => s.name === rootName);
|
|
34
|
+
if (!rootSkill) continue;
|
|
35
|
+
printSkillLine(rootName, rootSkill, 4, opts);
|
|
36
|
+
for (const sub of children.get(rootName) ?? []) printSkillLine(sub.name.slice(sub.name.indexOf("/") + 1), sub, 6, opts);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function printSkillLine(displayName, skill, indent, opts) {
|
|
40
|
+
const nameStr = " ".repeat(indent) + displayName;
|
|
41
|
+
const padding = " ".repeat(Math.max(2, opts.nameWidth - nameStr.length));
|
|
42
|
+
const typeCol = opts.showTypes ? (skill.type ? `[${skill.type}]` : "").padEnd(14) : "";
|
|
43
|
+
console.log(`${nameStr}${padding}${typeCol}${skill.description}`);
|
|
44
|
+
}
|
|
45
|
+
function computeSkillNameWidth(allPackageSkills) {
|
|
46
|
+
let max = 0;
|
|
47
|
+
for (const skills of allPackageSkills) for (const s of skills) {
|
|
48
|
+
const slashIdx = s.name.indexOf("/");
|
|
49
|
+
const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1);
|
|
50
|
+
const indent = slashIdx === -1 ? 4 : 6;
|
|
51
|
+
max = Math.max(max, indent + displayName.length);
|
|
52
|
+
}
|
|
53
|
+
return max + 2;
|
|
54
|
+
}
|
|
6
55
|
async function cmdList() {
|
|
7
56
|
let result;
|
|
8
57
|
try {
|
|
@@ -19,18 +68,30 @@ async function cmdList() {
|
|
|
19
68
|
}
|
|
20
69
|
return;
|
|
21
70
|
}
|
|
71
|
+
const totalSkills = result.packages.reduce((sum, p) => sum + p.skills.length, 0);
|
|
72
|
+
console.log(`\n${result.packages.length} intent-enabled packages, ${totalSkills} skills\n`);
|
|
73
|
+
printTable([
|
|
74
|
+
"PACKAGE",
|
|
75
|
+
"VERSION",
|
|
76
|
+
"SKILLS"
|
|
77
|
+
], result.packages.map((pkg) => [
|
|
78
|
+
pkg.name,
|
|
79
|
+
pkg.version,
|
|
80
|
+
String(pkg.skills.length)
|
|
81
|
+
]));
|
|
82
|
+
const nameWidth = computeSkillNameWidth(result.packages.map((p) => p.skills));
|
|
83
|
+
const showTypes = result.packages.some((p) => p.skills.some((s) => s.type));
|
|
84
|
+
console.log(`\nSkills:\n`);
|
|
22
85
|
for (const pkg of result.packages) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log(` ${name}${desc}${skill.path}`);
|
|
29
|
-
}
|
|
86
|
+
console.log(` ${pkg.name}`);
|
|
87
|
+
printSkillTree(pkg.skills, {
|
|
88
|
+
nameWidth,
|
|
89
|
+
showTypes
|
|
90
|
+
});
|
|
30
91
|
console.log();
|
|
31
92
|
}
|
|
32
93
|
if (result.warnings.length > 0) {
|
|
33
|
-
console.log(
|
|
94
|
+
console.log(`Warnings:`);
|
|
34
95
|
for (const w of result.warnings) console.log(` ⚠ ${w}`);
|
|
35
96
|
}
|
|
36
97
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as parseFrontmatter } from "./utils-
|
|
1
|
+
import { n as parseFrontmatter } from "./utils-DjkEPBxu.mjs";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join, relative, sep } from "node:path";
|
|
4
4
|
|
|
@@ -37,10 +37,7 @@ function discoverSkills(skillsDir) {
|
|
|
37
37
|
function walk(dir) {
|
|
38
38
|
let entries;
|
|
39
39
|
try {
|
|
40
|
-
entries = readdirSync(dir, {
|
|
41
|
-
withFileTypes: true,
|
|
42
|
-
encoding: "utf8"
|
|
43
|
-
});
|
|
40
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
44
41
|
} catch {
|
|
45
42
|
return;
|
|
46
43
|
}
|
package/dist/library-scanner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as parseFrontmatter } from "./utils-
|
|
1
|
+
import { n as parseFrontmatter } from "./utils-DjkEPBxu.mjs";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { join, relative, sep } from "node:path";
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ function detectPackageManager(root) {
|
|
|
12
12
|
if (existsSync(join(root, "package-lock.json"))) return "npm";
|
|
13
13
|
return "unknown";
|
|
14
14
|
}
|
|
15
|
-
function validateIntentField(
|
|
15
|
+
function validateIntentField(pkgName, intent) {
|
|
16
16
|
if (!intent || typeof intent !== "object") return null;
|
|
17
17
|
const pb = intent;
|
|
18
18
|
if (pb.version !== 1) return null;
|
|
@@ -26,15 +26,12 @@ function validateIntentField(_pkgName, intent) {
|
|
|
26
26
|
requires
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
function discoverSkills(skillsDir,
|
|
29
|
+
function discoverSkills(skillsDir, baseName) {
|
|
30
30
|
const skills = [];
|
|
31
31
|
function walk(dir) {
|
|
32
32
|
let entries;
|
|
33
33
|
try {
|
|
34
|
-
entries = readdirSync(dir, {
|
|
35
|
-
withFileTypes: true,
|
|
36
|
-
encoding: "utf8"
|
|
37
|
-
});
|
|
34
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
38
35
|
} catch {
|
|
39
36
|
return;
|
|
40
37
|
}
|
|
@@ -89,10 +86,7 @@ async function scanForIntents(root) {
|
|
|
89
86
|
const packageDirs = [];
|
|
90
87
|
let topEntries;
|
|
91
88
|
try {
|
|
92
|
-
topEntries = readdirSync(nodeModulesDir, {
|
|
93
|
-
withFileTypes: true,
|
|
94
|
-
encoding: "utf8"
|
|
95
|
-
});
|
|
89
|
+
topEntries = readdirSync(nodeModulesDir, { withFileTypes: true });
|
|
96
90
|
} catch {
|
|
97
91
|
return {
|
|
98
92
|
packageManager,
|
|
@@ -106,10 +100,7 @@ async function scanForIntents(root) {
|
|
|
106
100
|
if (entry.name.startsWith("@")) {
|
|
107
101
|
let scopedEntries;
|
|
108
102
|
try {
|
|
109
|
-
scopedEntries = readdirSync(dirPath, {
|
|
110
|
-
withFileTypes: true,
|
|
111
|
-
encoding: "utf8"
|
|
112
|
-
});
|
|
103
|
+
scopedEntries = readdirSync(dirPath, { withFileTypes: true });
|
|
113
104
|
} catch {
|
|
114
105
|
continue;
|
|
115
106
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-feedback-collection
|
|
3
|
+
description: >
|
|
4
|
+
Collect structured feedback about skill usage after completing a coding task.
|
|
5
|
+
Activate at the end of any session where one or more SKILL.md files were
|
|
6
|
+
loaded. Captures agent signals (gaps, errors, corrections, human interventions)
|
|
7
|
+
and brief human input, then submits via the intent feedback CLI.
|
|
8
|
+
metadata:
|
|
9
|
+
version: '1.0'
|
|
10
|
+
category: meta-tooling
|
|
11
|
+
output_artifacts:
|
|
12
|
+
- intent-feedback.json
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Skill Feedback Collection
|
|
16
|
+
|
|
17
|
+
Run this at the end of any session where you loaded one or more SKILL.md files.
|
|
18
|
+
The goal is to capture what worked, what didn't, and what was missing — so skill
|
|
19
|
+
maintainers can improve future versions.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Phase 1 — Automated Signal Collection
|
|
24
|
+
|
|
25
|
+
Review your own session transcript. No human interaction needed yet.
|
|
26
|
+
|
|
27
|
+
### 1a: Gap detection
|
|
28
|
+
|
|
29
|
+
Identify moments where the skill was silent and you had to bridge the gap
|
|
30
|
+
yourself — via code reading, search, trial-and-error, or general knowledge.
|
|
31
|
+
|
|
32
|
+
For each gap, note:
|
|
33
|
+
|
|
34
|
+
- What you needed to do
|
|
35
|
+
- What the skill should have told you
|
|
36
|
+
- How you solved it (code reading, web search, guessing)
|
|
37
|
+
|
|
38
|
+
### 1b: Error/correction tracking
|
|
39
|
+
|
|
40
|
+
Identify moments where the skill prescribed an approach that produced an error.
|
|
41
|
+
|
|
42
|
+
For each error, note:
|
|
43
|
+
|
|
44
|
+
- What the skill said to do
|
|
45
|
+
- The error or incorrect behavior that resulted
|
|
46
|
+
- The fix you applied
|
|
47
|
+
|
|
48
|
+
### 1c: Human intervention events
|
|
49
|
+
|
|
50
|
+
Identify moments where the human clarified, corrected, or overrode your approach.
|
|
51
|
+
|
|
52
|
+
For each intervention, note:
|
|
53
|
+
|
|
54
|
+
- What you were doing when the human intervened
|
|
55
|
+
- What the human said or changed
|
|
56
|
+
- Whether the skill could have prevented this
|
|
57
|
+
|
|
58
|
+
### 1d: Step duration anomalies
|
|
59
|
+
|
|
60
|
+
Identify steps that consumed disproportionate effort compared to their apparent
|
|
61
|
+
complexity. These signal that the skill should provide a template, snippet, or
|
|
62
|
+
more detailed guidance.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Phase 2 — Human Interview
|
|
67
|
+
|
|
68
|
+
Ask the human up to 4 questions. Keep it brief — skip questions if the session
|
|
69
|
+
already provided clear answers. Respect if they decline.
|
|
70
|
+
|
|
71
|
+
1. "Was anything unclear about what was happening during the task?"
|
|
72
|
+
2. "Did anything feel frustrating or take longer than expected?"
|
|
73
|
+
3. "Were you uncertain about the output quality at any point?"
|
|
74
|
+
4. "Anything you'd want done differently next time?"
|
|
75
|
+
|
|
76
|
+
Derive `userRating` from overall sentiment:
|
|
77
|
+
|
|
78
|
+
- Mostly positive → `good`
|
|
79
|
+
- Mixed signals → `mixed`
|
|
80
|
+
- Mostly negative → `bad`
|
|
81
|
+
|
|
82
|
+
If the human gives an explicit rating, use that instead.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Phase 3 — Build the Payload
|
|
87
|
+
|
|
88
|
+
Construct one JSON payload per skill used. The schema must match exactly:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"skill": "<skill name from SKILL.md frontmatter>",
|
|
93
|
+
"package": "<npm package name that contains the skill>",
|
|
94
|
+
"skillVersion": "<metadata.version from SKILL.md frontmatter, or library_version>",
|
|
95
|
+
"task": "<one-sentence summary of what the human asked you to do>",
|
|
96
|
+
"whatWorked": "<patterns/instructions from the skill that were accurate and helpful>",
|
|
97
|
+
"whatFailed": "<errors from 1b — what the skill got wrong>",
|
|
98
|
+
"missing": "<gaps from 1a — what the skill should have covered>",
|
|
99
|
+
"selfCorrections": "<fixes you applied from 1b + interventions from 1c>",
|
|
100
|
+
"userRating": "good | mixed | bad",
|
|
101
|
+
"userComments": "<optional — direct quotes or paraphrased human input from Phase 2>"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Field derivation guide
|
|
106
|
+
|
|
107
|
+
| Field | Source |
|
|
108
|
+
| ----------------- | ------------------------------------------------------------------ |
|
|
109
|
+
| `skill` | Frontmatter `name` field of the SKILL.md you loaded |
|
|
110
|
+
| `package` | The npm package the skill lives in (e.g. `@tanstack/query-intent`) |
|
|
111
|
+
| `skillVersion` | Frontmatter `metadata.version` or `library_version` |
|
|
112
|
+
| `task` | Summarize the human's original request in one sentence |
|
|
113
|
+
| `whatWorked` | List skill sections/patterns that were correct and useful |
|
|
114
|
+
| `whatFailed` | From 1b — skill instructions that produced errors |
|
|
115
|
+
| `missing` | From 1a — gaps where the skill was silent |
|
|
116
|
+
| `selfCorrections` | From 1b fixes + 1c human interventions, combined |
|
|
117
|
+
| `userRating` | From Phase 2 sentiment analysis or explicit rating |
|
|
118
|
+
| `userComments` | From Phase 2 answers, keep brief |
|
|
119
|
+
|
|
120
|
+
### Example
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"skill": "tanstack-query/core",
|
|
125
|
+
"package": "@anthropic/tanstack-query-intent",
|
|
126
|
+
"skillVersion": "1.0",
|
|
127
|
+
"task": "Add optimistic updates to a mutation with rollback on error",
|
|
128
|
+
"whatWorked": "Setup pattern was correct. onMutate/onError/onSettled lifecycle was accurate.",
|
|
129
|
+
"whatFailed": "Cache key format used array syntax that doesn't match v5 — had to switch to queryOptions pattern.",
|
|
130
|
+
"missing": "No guidance on TypeScript generics for mutation variables. Had to read source.",
|
|
131
|
+
"selfCorrections": "Fixed cache key format. Human corrected the rollback type to include undefined.",
|
|
132
|
+
"userRating": "mixed",
|
|
133
|
+
"userComments": "The optimistic update pattern was helpful but the cache key thing wasted 10 minutes."
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If multiple skills were loaded, produce one payload per skill. Only include
|
|
138
|
+
skills that were actually used during the session — skip any that were loaded
|
|
139
|
+
but never referenced.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Phase 4 — Submit
|
|
144
|
+
|
|
145
|
+
1. Save the payload to `intent-feedback.json` in the project root.
|
|
146
|
+
If multiple skills, save as a JSON array.
|
|
147
|
+
|
|
148
|
+
2. Submit:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx intent feedback --submit --file intent-feedback.json
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
3. If the submission succeeds, delete `intent-feedback.json`.
|
|
155
|
+
|
|
156
|
+
4. If it fails, tell the human and leave the file for manual retry.
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
name: skill-staleness-check
|
|
3
3
|
description: >
|
|
4
4
|
Evaluate intent skills for staleness when source files change in upstream
|
|
5
|
-
TanStack package repos.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
TanStack package repos. Matches changed files against metadata.sources,
|
|
6
|
+
evaluates whether diffs affect documented behavior, rewrites stale skills
|
|
7
|
+
using skill-generate, checks cross-skill references, and opens PRs.
|
|
8
|
+
Silent when nothing needs updating.
|
|
9
9
|
metadata:
|
|
10
10
|
version: '1.0'
|
|
11
11
|
category: meta-tooling
|
|
@@ -21,10 +21,10 @@ metadata:
|
|
|
21
21
|
|
|
22
22
|
# Skill Staleness Check
|
|
23
23
|
|
|
24
|
-
You are
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
You are a coding agent. Your job is to evaluate whether intent skills are
|
|
25
|
+
stale after upstream source changes, and if so, update them and open PRs.
|
|
26
|
+
You act autonomously end-to-end. PRs contain already-updated skill
|
|
27
|
+
content, not suggestions.
|
|
28
28
|
|
|
29
29
|
If nothing needs updating, exit silently. No PR, no notification.
|
|
30
30
|
|
|
@@ -279,4 +279,4 @@ node scripts/sync-skills.mjs db --mark-synced --all
|
|
|
279
279
|
| One cascade level | Cross-skill checks go one level deep, not recursive |
|
|
280
280
|
| PRs scoped to one library | Never mix libraries in a single PR |
|
|
281
281
|
| Version bumps are separate from content updates | A version-only bump doesn't require regeneration |
|
|
282
|
-
| Commit messages include co-author |
|
|
282
|
+
| Commit messages include co-author | Include the coding agent's co-author tag |
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# check-skills.yml — Drop this into your library repo's .github/workflows/
|
|
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.
|
|
6
|
+
#
|
|
7
|
+
# Triggers: new release published, or manual workflow_dispatch.
|
|
8
|
+
#
|
|
9
|
+
# Template variables (replaced by `intent setup`):
|
|
10
|
+
# {{PACKAGE_NAME}} — e.g. @tanstack/query
|
|
11
|
+
|
|
12
|
+
name: Check Skills
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
release:
|
|
16
|
+
types: [published]
|
|
17
|
+
workflow_dispatch: {}
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
pull-requests: write
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
check:
|
|
25
|
+
name: Check for stale skills
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 0
|
|
32
|
+
|
|
33
|
+
- name: Setup Node
|
|
34
|
+
uses: actions/setup-node@v4
|
|
35
|
+
with:
|
|
36
|
+
node-version: 20
|
|
37
|
+
|
|
38
|
+
- name: Install intent
|
|
39
|
+
run: npm install {{PACKAGE_NAME}}
|
|
40
|
+
|
|
41
|
+
- name: Check staleness
|
|
42
|
+
id: stale
|
|
43
|
+
run: |
|
|
44
|
+
OUTPUT=$(npx intent stale --json 2>&1) || true
|
|
45
|
+
echo "$OUTPUT"
|
|
46
|
+
|
|
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
|
|
71
|
+
|
|
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');
|
|
82
|
+
|
|
83
|
+
const prompt = [
|
|
84
|
+
'Review and update the following stale intent skills for {{PACKAGE_NAME}}:',
|
|
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 intent validate\` to verify the updated skill',
|
|
93
|
+
].join('\n');
|
|
94
|
+
|
|
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 }}
|
|
106
|
+
|
|
107
|
+
- name: Open review PR
|
|
108
|
+
if: steps.stale.outputs.has_stale == 'true'
|
|
109
|
+
env:
|
|
110
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
111
|
+
run: |
|
|
112
|
+
VERSION="${{ github.event.release.tag_name || 'manual' }}"
|
|
113
|
+
BRANCH="skills/review-${VERSION}"
|
|
114
|
+
|
|
115
|
+
git config user.name "github-actions[bot]"
|
|
116
|
+
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
|
+
|
|
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
|
+
~~~
|
|
139
|
+
|
|
140
|
+
PREOF
|
|
141
|
+
)" \
|
|
142
|
+
--head "$BRANCH" \
|
|
143
|
+
--base main
|
package/package.json
CHANGED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Oz Prompt: Domain Discovery
|
|
2
|
-
|
|
3
|
-
Use this prompt with `oz agent run` (local) or `warpdotdev/oz-agent-action` (CI)
|
|
4
|
-
to run domain discovery for a library.
|
|
5
|
-
|
|
6
|
-
## Usage
|
|
7
|
-
|
|
8
|
-
### Local (interactive — includes maintainer interview)
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
oz agent run --prompt "$(cat this-file.md)"
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
### CI (compressed — skips interview phases)
|
|
15
|
-
|
|
16
|
-
Use the `generate-skills-oz.yml` workflow template instead.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Prompt
|
|
21
|
-
|
|
22
|
-
Read the meta-skill at `node_modules/@tanstack/intent/meta/domain-discovery/SKILL.md`
|
|
23
|
-
and follow its instructions for the library described below.
|
|
24
|
-
|
|
25
|
-
### Library details
|
|
26
|
-
|
|
27
|
-
- **Package:** [PACKAGE_NAME]
|
|
28
|
-
- **Repository:** [REPO_URL]
|
|
29
|
-
- **Docs path:** [DOCS_PATH]
|
|
30
|
-
- **Primary framework:** [react | vue | solid | svelte | framework-agnostic]
|
|
31
|
-
|
|
32
|
-
### Instructions
|
|
33
|
-
|
|
34
|
-
Run the full 5-phase domain discovery process:
|
|
35
|
-
|
|
36
|
-
1. **Phase 1 — Quick scan:** Orient yourself in the library
|
|
37
|
-
2. **Phase 2 — High-level interview:** Ask the maintainer about developer tasks
|
|
38
|
-
3. **Phase 3 — Deep read:** Read docs and source, build concept inventory
|
|
39
|
-
4. **Phase 4 — Detail interview:** Fill gaps with targeted questions
|
|
40
|
-
5. **Phase 5 — Finalize:** Produce domain_map.yaml and skill_spec.md
|
|
41
|
-
|
|
42
|
-
Write the output artifacts to the repository root:
|
|
43
|
-
|
|
44
|
-
- `domain_map.yaml`
|
|
45
|
-
- `skill_spec.md`
|
|
46
|
-
|
|
47
|
-
### After completion
|
|
48
|
-
|
|
49
|
-
Tell the user:
|
|
50
|
-
|
|
51
|
-
- "Domain discovery complete. Artifacts written to domain_map.yaml and skill_spec.md."
|
|
52
|
-
- "Next step: load the tree-generator meta-skill to generate SKILL.md files."
|
|
53
|
-
- "Run `npx intent feedback --meta --interactive` to share how this went."
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Oz Prompt: Meta-Skill Feedback Collection
|
|
2
|
-
|
|
3
|
-
Use this prompt to collect structured feedback about the meta-skill experience
|
|
4
|
-
and submit it to TanStack/intent.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Prompt
|
|
9
|
-
|
|
10
|
-
You are collecting feedback about the TanStack Intent meta-skill experience.
|
|
11
|
-
The user just ran one or more meta-skills (domain-discovery, tree-generator,
|
|
12
|
-
generate-skill, or skill-staleness-check) and you need to capture what worked
|
|
13
|
-
and what didn't.
|
|
14
|
-
|
|
15
|
-
### Questions to ask
|
|
16
|
-
|
|
17
|
-
Walk through these questions one at a time:
|
|
18
|
-
|
|
19
|
-
1. **Which meta-skill(s) did you use?**
|
|
20
|
-
(domain-discovery, tree-generator, generate-skill, skill-staleness-check)
|
|
21
|
-
|
|
22
|
-
2. **What library were you generating skills for?**
|
|
23
|
-
(package name and version)
|
|
24
|
-
|
|
25
|
-
3. **Which AI agent ran the meta-skill?**
|
|
26
|
-
(oz, claude-code, cursor, copilot, codex, other)
|
|
27
|
-
|
|
28
|
-
4. **How would you rate the generated artifacts?**
|
|
29
|
-
(good / mixed / bad)
|
|
30
|
-
- If domain-discovery: How were the interview questions? Did they surface
|
|
31
|
-
the right failure modes and domain structure?
|
|
32
|
-
- If tree-generator: Were the generated SKILL.md files usable? Did the
|
|
33
|
-
structure match your library?
|
|
34
|
-
- If generate-skill: Was the individual skill accurate and complete?
|
|
35
|
-
|
|
36
|
-
5. **What worked well?**
|
|
37
|
-
(free text — what the meta-skill got right)
|
|
38
|
-
|
|
39
|
-
6. **What failed or was inaccurate?**
|
|
40
|
-
(free text — what the agent got wrong, what needed manual fixing)
|
|
41
|
-
|
|
42
|
-
7. **What's missing?**
|
|
43
|
-
(free text — suggestions for improving the meta-skill instructions)
|
|
44
|
-
|
|
45
|
-
8. **Overall rating:** good / mixed / bad
|
|
46
|
-
|
|
47
|
-
### After collecting answers
|
|
48
|
-
|
|
49
|
-
1. Format the feedback as JSON matching the MetaFeedbackPayload schema:
|
|
50
|
-
|
|
51
|
-
```json
|
|
52
|
-
{
|
|
53
|
-
"metaSkill": "domain-discovery",
|
|
54
|
-
"library": "@tanstack/query",
|
|
55
|
-
"agentUsed": "oz",
|
|
56
|
-
"artifactQuality": "good",
|
|
57
|
-
"interviewQuality": "mixed",
|
|
58
|
-
"failureModeQuality": "good",
|
|
59
|
-
"whatWorked": "...",
|
|
60
|
-
"whatFailed": "...",
|
|
61
|
-
"suggestions": "...",
|
|
62
|
-
"userRating": "mixed"
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
2. Save to `intent-meta-feedback.json`
|
|
67
|
-
3. Run: `npx intent feedback --meta --file intent-meta-feedback.json`
|
|
68
|
-
4. If `gh` CLI is available, this submits directly to TanStack/intent.
|
|
69
|
-
Otherwise, it saves a markdown file the user can paste into a GitHub Discussion.
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# Oz Prompt: Skill Update (Staleness Check)
|
|
2
|
-
|
|
3
|
-
Use this prompt to check existing skills for staleness after a library
|
|
4
|
-
version change and surgically update any that are outdated.
|
|
5
|
-
|
|
6
|
-
## Prerequisites
|
|
7
|
-
|
|
8
|
-
- Existing skills in `skills/` directory
|
|
9
|
-
- `@tanstack/intent` installed
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Prompt
|
|
14
|
-
|
|
15
|
-
Read the meta-skill at `node_modules/@tanstack/intent/meta/skill-staleness-check/SKILL.md`
|
|
16
|
-
and follow its instructions.
|
|
17
|
-
|
|
18
|
-
### Context
|
|
19
|
-
|
|
20
|
-
- **Package:** [PACKAGE_NAME]
|
|
21
|
-
- **Previous version:** [OLD_VERSION] (check skill frontmatter `library_version`)
|
|
22
|
-
- **Current version:** [NEW_VERSION]
|
|
23
|
-
- **Changelog:** [CHANGELOG_PATH or URL]
|
|
24
|
-
|
|
25
|
-
### Task
|
|
26
|
-
|
|
27
|
-
1. Find all SKILL.md files under skills/
|
|
28
|
-
2. Compare each skill's `library_version` against the current version
|
|
29
|
-
3. Read the changelog/migration guide for changes between versions
|
|
30
|
-
4. For each skill, classify the impact: no-impact, version-bump, content-update, breaking
|
|
31
|
-
5. For content updates and breaking changes:
|
|
32
|
-
- Read the generate-skill meta-skill at
|
|
33
|
-
`node_modules/@tanstack/intent/meta/generate-skill/SKILL.md`
|
|
34
|
-
- Use regeneration mode — surgical updates, not full rewrites
|
|
35
|
-
- Add old patterns as new Common Mistake entries for breaking changes
|
|
36
|
-
6. Bump `library_version` in all updated skill frontmatter
|
|
37
|
-
7. Run `npx intent validate skills/` to verify
|
|
38
|
-
|
|
39
|
-
### Output
|
|
40
|
-
|
|
41
|
-
If nothing needs updating, say so and exit.
|
|
42
|
-
|
|
43
|
-
If skills were updated, summarize:
|
|
44
|
-
|
|
45
|
-
- Which skills were updated and why
|
|
46
|
-
- What sections changed
|
|
47
|
-
- Any new Common Mistake entries added
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# Oz Prompt: Tree Generation
|
|
2
|
-
|
|
3
|
-
Use this prompt with `oz agent run` (local) or `warpdotdev/oz-agent-action` (CI)
|
|
4
|
-
to generate a complete skill tree from domain discovery artifacts.
|
|
5
|
-
|
|
6
|
-
## Prerequisites
|
|
7
|
-
|
|
8
|
-
- `domain_map.yaml` and `skill_spec.md` in the repo (from domain discovery)
|
|
9
|
-
- `@tanstack/intent` installed
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Prompt
|
|
14
|
-
|
|
15
|
-
Read the meta-skill at `node_modules/@tanstack/intent/meta/tree-generator/SKILL.md`
|
|
16
|
-
and follow Workflow A (Generate) instructions.
|
|
17
|
-
|
|
18
|
-
### Inputs
|
|
19
|
-
|
|
20
|
-
- `domain_map.yaml` — in the repository root
|
|
21
|
-
- `skill_spec.md` — in the repository root
|
|
22
|
-
- Library source documentation is at [DOCS_PATH]
|
|
23
|
-
|
|
24
|
-
### Task
|
|
25
|
-
|
|
26
|
-
1. Read domain_map.yaml and skill_spec.md
|
|
27
|
-
2. Plan the file tree based on the skill inventory
|
|
28
|
-
3. Generate all SKILL.md files following the tree-generator spec
|
|
29
|
-
4. Write files under `skills/` in the appropriate package directory
|
|
30
|
-
5. Run `npx intent validate skills/` to verify all files pass
|
|
31
|
-
6. Fix any validation errors
|
|
32
|
-
|
|
33
|
-
### Output structure
|
|
34
|
-
|
|
35
|
-
Write skills following the structure recommended in the domain map.
|
|
36
|
-
Ensure every skill from domain_map.yaml has a corresponding SKILL.md file.
|
|
37
|
-
|
|
38
|
-
### After completion
|
|
39
|
-
|
|
40
|
-
Tell the user:
|
|
41
|
-
|
|
42
|
-
- "Skill tree generated. [N] skills written to skills/."
|
|
43
|
-
- "Validation: [PASS/FAIL with details]"
|
|
44
|
-
- "Next steps:"
|
|
45
|
-
- "1. Review the generated skills for accuracy"
|
|
46
|
-
- "2. Add `\"skills\"` to your package.json `files` array"
|
|
47
|
-
- "3. Add the `intent` field to your package.json"
|
|
48
|
-
- "4. Run `npx intent feedback --meta --interactive` to share how this went"
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# generate-skills-oz.yml — Drop this into your library repo's .github/workflows/
|
|
2
|
-
#
|
|
3
|
-
# Manual-trigger workflow that runs domain-discovery + tree-generator via
|
|
4
|
-
# Warp Oz to generate a complete skill tree for your library.
|
|
5
|
-
#
|
|
6
|
-
# Requirements:
|
|
7
|
-
# - WARP_API_KEY repository secret (from Warp Settings > Platform)
|
|
8
|
-
#
|
|
9
|
-
# Template variables (replaced by `intent setup`):
|
|
10
|
-
# {{PACKAGE_NAME}} — e.g. @tanstack/query
|
|
11
|
-
# {{REPO}} — e.g. TanStack/query
|
|
12
|
-
# {{DOCS_PATH}} — e.g. docs/
|
|
13
|
-
|
|
14
|
-
name: Generate Skills (Oz)
|
|
15
|
-
|
|
16
|
-
on:
|
|
17
|
-
workflow_dispatch:
|
|
18
|
-
inputs:
|
|
19
|
-
docs_path:
|
|
20
|
-
description: 'Path to library docs (default from intent config)'
|
|
21
|
-
required: false
|
|
22
|
-
default: '{{DOCS_PATH}}'
|
|
23
|
-
type: string
|
|
24
|
-
skip_interview:
|
|
25
|
-
description: 'Skip maintainer interview (compressed discovery)'
|
|
26
|
-
required: false
|
|
27
|
-
default: false
|
|
28
|
-
type: boolean
|
|
29
|
-
|
|
30
|
-
permissions:
|
|
31
|
-
contents: write
|
|
32
|
-
pull-requests: write
|
|
33
|
-
|
|
34
|
-
jobs:
|
|
35
|
-
generate:
|
|
36
|
-
name: Generate skill tree
|
|
37
|
-
runs-on: ubuntu-latest
|
|
38
|
-
steps:
|
|
39
|
-
- name: Checkout
|
|
40
|
-
uses: actions/checkout@v4
|
|
41
|
-
with:
|
|
42
|
-
fetch-depth: 0
|
|
43
|
-
|
|
44
|
-
- name: Setup Node
|
|
45
|
-
uses: actions/setup-node@v4
|
|
46
|
-
with:
|
|
47
|
-
node-version: 20
|
|
48
|
-
|
|
49
|
-
- name: Install dependencies
|
|
50
|
-
run: npm install @tanstack/intent yaml
|
|
51
|
-
|
|
52
|
-
- name: Run Oz agent
|
|
53
|
-
uses: warpdotdev/oz-agent-action@v1
|
|
54
|
-
with:
|
|
55
|
-
prompt: |
|
|
56
|
-
You are generating AI coding agent skills for {{PACKAGE_NAME}}.
|
|
57
|
-
|
|
58
|
-
## Setup
|
|
59
|
-
|
|
60
|
-
1. Read the meta-skill at node_modules/@tanstack/intent/meta/domain-discovery/SKILL.md
|
|
61
|
-
2. The library source is in this repo at {{DOCS_PATH}}
|
|
62
|
-
3. The package name is {{PACKAGE_NAME}} and the repo is {{REPO}}
|
|
63
|
-
|
|
64
|
-
## Task
|
|
65
|
-
|
|
66
|
-
Run the domain-discovery skill to produce domain_map.yaml and skill_spec.md.
|
|
67
|
-
Since this is a CI run with no interactive maintainer, use compressed
|
|
68
|
-
discovery mode (Phase 1 + Phase 3 only — skip interview phases).
|
|
69
|
-
|
|
70
|
-
After producing the domain map, read the meta-skill at
|
|
71
|
-
node_modules/@tanstack/intent/meta/tree-generator/SKILL.md and
|
|
72
|
-
run Workflow A to generate the complete skill tree under skills/.
|
|
73
|
-
|
|
74
|
-
## Output
|
|
75
|
-
|
|
76
|
-
1. Write domain_map.yaml and skill_spec.md to the repo root
|
|
77
|
-
2. Write generated SKILL.md files under the appropriate skills/ directory
|
|
78
|
-
3. Run `npx intent validate skills/` to verify all files pass
|
|
79
|
-
4. Create a branch `skills/generate-{{PACKAGE_NAME}}` and open a PR with:
|
|
80
|
-
- Title: "feat: generate intent skills for {{PACKAGE_NAME}}"
|
|
81
|
-
- Body summarizing what was generated and any gaps flagged
|
|
82
|
-
- Co-Authored-By: Oz <oz-agent@warp.dev>
|
|
83
|
-
|
|
84
|
-
If validation fails, fix the issues before opening the PR.
|
|
85
|
-
warp_api_key: ${{ secrets.WARP_API_KEY }}
|
|
86
|
-
profile: ${{ vars.WARP_AGENT_PROFILE || '' }}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# update-skills-oz.yml — Drop this into your library repo's .github/workflows/
|
|
2
|
-
#
|
|
3
|
-
# Triggered on new version releases. Oz evaluates whether skills need
|
|
4
|
-
# updating based on changelog/migration guide changes, and opens PRs
|
|
5
|
-
# for any stale skills.
|
|
6
|
-
#
|
|
7
|
-
# Requirements:
|
|
8
|
-
# - WARP_API_KEY repository secret
|
|
9
|
-
# - Skills must already exist in the repo (run generate-skills-oz first)
|
|
10
|
-
#
|
|
11
|
-
# Template variables (replaced by `intent setup`):
|
|
12
|
-
# {{PACKAGE_NAME}} — e.g. @tanstack/query
|
|
13
|
-
# {{REPO}} — e.g. TanStack/query
|
|
14
|
-
|
|
15
|
-
name: Update Skills (Oz)
|
|
16
|
-
|
|
17
|
-
on:
|
|
18
|
-
release:
|
|
19
|
-
types: [published]
|
|
20
|
-
|
|
21
|
-
# Manual trigger for testing
|
|
22
|
-
workflow_dispatch:
|
|
23
|
-
inputs:
|
|
24
|
-
version:
|
|
25
|
-
description: 'Version to check against (e.g. 5.62.0)'
|
|
26
|
-
required: false
|
|
27
|
-
type: string
|
|
28
|
-
|
|
29
|
-
permissions:
|
|
30
|
-
contents: write
|
|
31
|
-
pull-requests: write
|
|
32
|
-
|
|
33
|
-
jobs:
|
|
34
|
-
update:
|
|
35
|
-
name: Check and update skills
|
|
36
|
-
runs-on: ubuntu-latest
|
|
37
|
-
steps:
|
|
38
|
-
- name: Checkout
|
|
39
|
-
uses: actions/checkout@v4
|
|
40
|
-
with:
|
|
41
|
-
fetch-depth: 0
|
|
42
|
-
|
|
43
|
-
- name: Setup Node
|
|
44
|
-
uses: actions/setup-node@v4
|
|
45
|
-
with:
|
|
46
|
-
node-version: 20
|
|
47
|
-
|
|
48
|
-
- name: Install dependencies
|
|
49
|
-
run: npm install @tanstack/intent yaml
|
|
50
|
-
|
|
51
|
-
- name: Determine version
|
|
52
|
-
id: version
|
|
53
|
-
run: |
|
|
54
|
-
if [ -n "${{ inputs.version }}" ]; then
|
|
55
|
-
echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
|
|
56
|
-
else
|
|
57
|
-
echo "version=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
- name: Run Oz agent
|
|
61
|
-
uses: warpdotdev/oz-agent-action@v1
|
|
62
|
-
with:
|
|
63
|
-
prompt: |
|
|
64
|
-
You are checking whether AI coding agent skills for {{PACKAGE_NAME}}
|
|
65
|
-
need updating after a new release.
|
|
66
|
-
|
|
67
|
-
## Setup
|
|
68
|
-
|
|
69
|
-
1. Read the meta-skill at node_modules/@tanstack/intent/meta/skill-staleness-check/SKILL.md
|
|
70
|
-
2. The package is {{PACKAGE_NAME}} in repo {{REPO}}
|
|
71
|
-
3. The new version is ${{ steps.version.outputs.version }}
|
|
72
|
-
|
|
73
|
-
## Task
|
|
74
|
-
|
|
75
|
-
Follow the staleness check skill instructions:
|
|
76
|
-
|
|
77
|
-
1. Find all SKILL.md files under skills/ in this repo
|
|
78
|
-
2. Compare each skill's library_version against the new version
|
|
79
|
-
3. Read the CHANGELOG or migration guide for changes between versions
|
|
80
|
-
4. Classify each skill: no-impact, version-bump-only, content-update, or breaking-change
|
|
81
|
-
5. For skills needing updates, read the generate-skill meta-skill at
|
|
82
|
-
node_modules/@tanstack/intent/meta/generate-skill/SKILL.md and
|
|
83
|
-
use regeneration mode (surgical updates, not full rewrites)
|
|
84
|
-
|
|
85
|
-
## Output
|
|
86
|
-
|
|
87
|
-
If no skills need updating, exit silently — no PR, no noise.
|
|
88
|
-
|
|
89
|
-
If skills need updating:
|
|
90
|
-
1. Update the affected SKILL.md files
|
|
91
|
-
2. Run `npx intent validate skills/` to verify
|
|
92
|
-
3. Create branch `skills/update-${{ steps.version.outputs.version }}`
|
|
93
|
-
4. Open a PR with:
|
|
94
|
-
- Title: "skill: update for {{PACKAGE_NAME}}@${{ steps.version.outputs.version }}"
|
|
95
|
-
- Body with: what changed in the source, what changed in skills, review checklist
|
|
96
|
-
- Co-Authored-By: Oz <oz-agent@warp.dev>
|
|
97
|
-
warp_api_key: ${{ secrets.WARP_API_KEY }}
|
|
98
|
-
profile: ${{ vars.WARP_AGENT_PROFILE || '' }}
|