@tanstack/intent 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/artifact-coverage-CXX6wav1.mjs +2 -0
  2. package/dist/{artifact-coverage-nGwun1tt.mjs → artifact-coverage-DFtI6V_H.mjs} +1 -3
  3. package/dist/{cli-error-BrMXlbtx.mjs → cli-error-DDAO6DIL.mjs} +1 -2
  4. package/dist/{cli-support-BADtMg6z.mjs → cli-support-BANzHEBM.mjs} +2 -6
  5. package/dist/{cli-support-C8SKYTA4.mjs → cli-support-z64kSJOO.mjs} +8 -11
  6. package/dist/cli.d.mts +0 -1
  7. package/dist/cli.mjs +14 -16
  8. package/dist/{command-runner-fstUIUhe.mjs → command-runner-B5OofX0E.mjs} +1 -2
  9. package/dist/{core-hEMP5GMV.mjs → core-DaAr5MBD.mjs} +11 -15
  10. package/dist/core.d.mts +3 -4
  11. package/dist/core.mjs +2 -11
  12. package/dist/{display-CFnFnrtx.mjs → display-CnpA7XuV.mjs} +3 -7
  13. package/dist/{edit-package-json-DKyJ04t1.mjs → edit-package-json-D8xfcy2X.mjs} +1 -2
  14. package/dist/{exclude-CBxkyK3Q.mjs → exclude-DbHwcgQQ.mjs} +6 -11
  15. package/dist/{excludes-DDMe-4iu.mjs → excludes-ByvSbmmj.mjs} +3 -6
  16. package/dist/index.d.mts +2 -3
  17. package/dist/index.mjs +9 -14
  18. package/dist/{install-BE7gVoNT.mjs → install-Bv2qdHwd.mjs} +18 -24
  19. package/dist/{list-UqYivAcV.mjs → list-C-eGocZP.mjs} +5 -15
  20. package/dist/{load-Dgw151E3.mjs → load-DDNrmeBz.mjs} +4 -14
  21. package/dist/{meta-BZMVgIzJ.mjs → meta-CF4XIYOo.mjs} +3 -5
  22. package/dist/{package-manager-BUgTjW9Q.mjs → package-manager-Dw7lYcI0.mjs} +1 -3
  23. package/dist/{project-context-DDCie6Ro.mjs → project-context-oi_m7paK.mjs} +2 -4
  24. package/dist/{resolver-CZXZ0rft.mjs → resolver-Uwx8B5jv.mjs} +4 -6
  25. package/dist/{scaffold-D2vwv9ls.mjs → scaffold-D8TAMXvs.mjs} +1 -3
  26. package/dist/{scanner-2XDBAsbm.mjs → scanner-C5bzzri5.mjs} +21 -14
  27. package/dist/{setup-DW3pn0QW.d.mts → setup-CdfBc7Oe.d.mts} +0 -1
  28. package/dist/{setup-CMec7fht.mjs → setup-Cx1r2y-1.mjs} +3 -5
  29. package/dist/{setup-github-actions-emXSyGy3.mjs → setup-github-actions-IxZTZihi.mjs} +1 -2
  30. package/dist/setup.d.mts +1 -1
  31. package/dist/setup.mjs +3 -6
  32. package/dist/{skill-paths-Cr74uFk4.mjs → skill-paths-Bm1P6IYe.mjs} +2 -4
  33. package/dist/{skill-use-CUrNHf-u.mjs → skill-use-B2xRF1i9.mjs} +1 -2
  34. package/dist/source-policy-CTeI29oF.mjs +2 -0
  35. package/dist/{source-policy-rGOtjQSM.mjs → source-policy-D__bcpoU.mjs} +4 -7
  36. package/dist/{stale-DxZyYibt.mjs → stale-DhjSTIt-.mjs} +3 -5
  37. package/dist/staleness-B5Cqe77_.mjs +2 -0
  38. package/dist/{staleness-B8IvDS_9.mjs → staleness-DoZU3lzy.mjs} +9 -16
  39. package/dist/{types-oEflMSso.d.mts → types-ByXUTBJ2.d.mts} +2 -1
  40. package/dist/{utils-Dj49bkF_.mjs → utils-6FtqhOYf.mjs} +1 -3
  41. package/dist/{utils-BuNMwKct.mjs → utils-BKBDYbCx.mjs} +2 -3
  42. package/dist/{validate-B3pkTIZl.mjs → validate-BAU0uzvQ.mjs} +133 -46
  43. package/dist/{workflow-review-wL1Iu2Sf.mjs → workflow-review-B4AfwtHH.mjs} +1 -3
  44. package/dist/{workflow-review-CtOR1bgh.mjs → workflow-review-Bo2kPVXV.mjs} +2 -3
  45. package/dist/{workspace-patterns-Cz_lNhwz.mjs → workspace-patterns-BDoJIWk-.mjs} +2 -4
  46. package/dist/workspace-patterns-CrL8hAbd.mjs +2 -0
  47. package/meta/generate-skill/SKILL.md +34 -20
  48. package/meta/tree-generator/SKILL.md +42 -38
  49. package/package.json +5 -6
  50. package/dist/artifact-coverage-BfJ7f-S9.mjs +0 -3
  51. package/dist/source-policy-D4slvwwI.mjs +0 -9
  52. package/dist/staleness-Ctzy2Zac.mjs +0 -5
  53. package/dist/workspace-patterns-BBW4c1gr.mjs +0 -4
@@ -1,13 +1,29 @@
1
- import "./utils-Dj49bkF_.mjs";
2
- import { n as findWorkspacePackages } from "./workspace-patterns-Cz_lNhwz.mjs";
3
- import { t as resolveProjectContext } from "./project-context-DDCie6Ro.mjs";
4
- import { n as isCliFailure, t as fail } from "./cli-error-BrMXlbtx.mjs";
5
- import { u as printWarnings } from "./cli-support-C8SKYTA4.mjs";
6
- import { appendFileSync, existsSync, readFileSync } from "node:fs";
7
- import { basename, dirname, join, relative, resolve, sep } from "node:path";
8
-
1
+ import { n as findWorkspacePackages } from "./workspace-patterns-BDoJIWk-.mjs";
2
+ import { t as resolveProjectContext } from "./project-context-oi_m7paK.mjs";
3
+ import { n as isCliFailure, t as fail } from "./cli-error-DDAO6DIL.mjs";
4
+ import { u as printWarnings } from "./cli-support-z64kSJOO.mjs";
5
+ import { appendFileSync, existsSync, readFileSync, writeFileSync } from "node:fs";
6
+ import { basename, dirname, join, relative, resolve } from "node:path";
9
7
  //#region src/commands/validate.ts
10
8
  const agentSkillNamePattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
9
+ const specTopLevelKeys = new Set([
10
+ "name",
11
+ "description",
12
+ "license",
13
+ "compatibility",
14
+ "metadata",
15
+ "allowed-tools"
16
+ ]);
17
+ const intentArrayKeys = new Set(["sources", "requires"]);
18
+ const metadataScalarKeys = [
19
+ "type",
20
+ "library",
21
+ "library_version",
22
+ "framework"
23
+ ];
24
+ function isScalarValue(value) {
25
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
26
+ }
11
27
  function buildValidationFailure(errors, warnings) {
12
28
  const lines = [
13
29
  "",
@@ -48,26 +64,60 @@ function formatWarning({ file, message }) {
48
64
  function isRecord(value) {
49
65
  return !!value && typeof value === "object" && !Array.isArray(value);
50
66
  }
51
- function collectAgentSkillSpecWarnings({ filePath, fm, rel }) {
52
- const warnings = [];
53
- if (typeof fm.name === "string") {
54
- if (fm.name.length > 64) warnings.push({
55
- file: rel,
56
- message: `Agent Skills spec warning: name exceeds 64 characters (${fm.name.length} chars)`
57
- });
58
- for (const segment of fm.name.split("/")) if (!agentSkillNamePattern.test(segment)) {
59
- warnings.push({
60
- file: rel,
61
- message: "Agent Skills spec warning: each name segment should use lowercase letters, numbers, and single hyphens only"
62
- });
63
- break;
67
+ function collectFrontmatterFixPlan({ filePath, fm, rel }) {
68
+ const changes = [];
69
+ const parentDir = basename(dirname(filePath));
70
+ if (typeof fm.name === "string" && (fm.name.includes("/") || fm.name !== parentDir) && agentSkillNamePattern.test(parentDir)) changes.push(`rewrite name to "${parentDir}"`);
71
+ const metadata = fm.metadata;
72
+ if (metadata === void 0 || isRecord(metadata)) {
73
+ const metadataRecord = isRecord(metadata) ? metadata : void 0;
74
+ for (const key of metadataScalarKeys) {
75
+ if (typeof fm[key] !== "string") continue;
76
+ if (metadataRecord && key in metadataRecord) changes.push(`remove top-level "${key}"; metadata.${key} already exists`);
77
+ else changes.push(`move top-level "${key}" under metadata.${key}`);
64
78
  }
65
- const parentDir = basename(dirname(filePath));
66
- if (!fm.name.includes("/") && fm.name !== parentDir) warnings.push({
67
- file: rel,
68
- message: "Agent Skills spec warning: name should match the parent directory name"
69
- });
70
79
  }
80
+ return changes.length > 0 ? {
81
+ file: rel,
82
+ filePath,
83
+ changes
84
+ } : null;
85
+ }
86
+ function normalizeLineEndings(value, lineEnding) {
87
+ return lineEnding === "\r\n" ? value.replace(/\r?\n/g, "\r\n") : value;
88
+ }
89
+ async function applyFrontmatterFixes(fixPlans) {
90
+ const { parseDocument } = await import("yaml");
91
+ for (const plan of fixPlans) {
92
+ const match = readFileSync(plan.filePath, "utf8").match(/^---(\r?\n)([\s\S]*?)(\r?\n)---(\r?\n?)([\s\S]*)/);
93
+ if (!match) continue;
94
+ const openingLineEnding = match[1];
95
+ const frontmatter = match[2];
96
+ const closingLineEnding = match[3];
97
+ const afterClose = match[4];
98
+ const body = match[5];
99
+ if (openingLineEnding === void 0 || frontmatter === void 0 || closingLineEnding === void 0 || afterClose === void 0 || body === void 0) continue;
100
+ const doc = parseDocument(frontmatter);
101
+ if (doc.errors.length > 0) continue;
102
+ const fm = doc.toJS();
103
+ const parentDir = basename(dirname(plan.filePath));
104
+ if (typeof fm.name === "string" && (fm.name.includes("/") || fm.name !== parentDir) && agentSkillNamePattern.test(parentDir)) doc.set("name", parentDir);
105
+ const metadata = fm.metadata;
106
+ if (metadata === void 0 || isRecord(metadata)) for (const key of metadataScalarKeys) {
107
+ const value = fm[key];
108
+ if (typeof value !== "string") continue;
109
+ if (!doc.hasIn(["metadata", key])) {
110
+ const valueNode = doc.get(key, true);
111
+ doc.setIn(["metadata", key], valueNode ?? value);
112
+ }
113
+ doc.delete(key);
114
+ }
115
+ const nextContent = `---${openingLineEnding}${normalizeLineEndings(doc.toString().replace(/\r?\n$/, ""), openingLineEnding)}${closingLineEnding}---${afterClose}${body}`;
116
+ writeFileSync(plan.filePath, nextContent);
117
+ }
118
+ }
119
+ function collectAgentSkillSpecWarnings({ fm, rel }) {
120
+ const warnings = [];
71
121
  if (fm.license !== void 0 && (typeof fm.license !== "string" || fm.license.trim().length === 0)) warnings.push({
72
122
  file: rel,
73
123
  message: "Agent Skills spec warning: license should be a non-empty string"
@@ -82,16 +132,6 @@ function collectAgentSkillSpecWarnings({ filePath, fm, rel }) {
82
132
  message: `Agent Skills spec warning: compatibility exceeds 500 characters (${fm.compatibility.length} chars)`
83
133
  });
84
134
  }
85
- if (fm.metadata !== void 0) {
86
- if (!isRecord(fm.metadata)) warnings.push({
87
- file: rel,
88
- message: "Agent Skills spec warning: metadata should be a mapping"
89
- });
90
- else if (Object.values(fm.metadata).some((value) => typeof value !== "string")) warnings.push({
91
- file: rel,
92
- message: "Agent Skills spec warning: metadata values should be strings"
93
- });
94
- }
95
135
  if (fm["allowed-tools"] !== void 0 && typeof fm["allowed-tools"] !== "string") warnings.push({
96
136
  file: rel,
97
137
  message: "Agent Skills spec warning: allowed-tools should be a space-separated string"
@@ -99,12 +139,13 @@ function collectAgentSkillSpecWarnings({ filePath, fm, rel }) {
99
139
  return warnings;
100
140
  }
101
141
  async function runValidateCommand(dir, options = {}) {
142
+ if (options.fix && options.check) fail("Cannot combine --fix and --check");
102
143
  if (!options.githubSummary) {
103
- await runValidateCommandInternal(dir);
144
+ await runValidateCommandInternal(dir, options);
104
145
  return;
105
146
  }
106
147
  try {
107
- await runValidateCommandInternal(dir);
148
+ await runValidateCommandInternal(dir, options);
108
149
  writeGithubValidationSummary({ ok: true });
109
150
  } catch (err) {
110
151
  writeGithubValidationSummary({
@@ -114,8 +155,8 @@ async function runValidateCommand(dir, options = {}) {
114
155
  throw err;
115
156
  }
116
157
  }
117
- async function runValidateCommandInternal(dir) {
118
- const [{ parse: parseYaml }, { findSkillFiles, readScalarField }] = await Promise.all([import("yaml"), import("./utils-BuNMwKct.mjs")]);
158
+ async function runValidateCommandInternal(dir, options = {}) {
159
+ const [{ parse: parseYaml }, { findSkillFiles, readScalarField }] = await Promise.all([import("yaml"), import("./utils-BKBDYbCx.mjs")]);
119
160
  const context = resolveProjectContext({
120
161
  cwd: process.cwd(),
121
162
  targetPath: dir
@@ -125,6 +166,7 @@ async function runValidateCommandInternal(dir) {
125
166
  if (explicitDir && !existsSync(skillsDirs[0])) fail(`Skills directory not found: ${skillsDirs[0]}`);
126
167
  const errors = [];
127
168
  const warnings = [];
169
+ const fixPlans = [];
128
170
  let validatedCount = 0;
129
171
  if (explicitDir && findSkillFiles(skillsDirs[0]).length === 0) fail("No SKILL.md files found");
130
172
  if (skillsDirs.length === 0) {
@@ -166,6 +208,12 @@ async function runValidateCommandInternal(dir) {
166
208
  });
167
209
  continue;
168
210
  }
211
+ const fixPlan = collectFrontmatterFixPlan({
212
+ filePath,
213
+ fm,
214
+ rel
215
+ });
216
+ if (fixPlan) fixPlans.push(fixPlan);
169
217
  if (!fm.name) errors.push({
170
218
  file: rel,
171
219
  message: "Missing required field: name"
@@ -175,10 +223,38 @@ async function runValidateCommandInternal(dir) {
175
223
  message: "Missing required field: description"
176
224
  });
177
225
  if (typeof fm.name === "string") {
178
- const expectedPath = relative(skillsDir, filePath).replace(/[/\\]SKILL\.md$/, "").split(sep).join("/");
179
- if (fm.name !== expectedPath) errors.push({
226
+ const parentDir = basename(dirname(filePath));
227
+ if (fm.name.length > 64) errors.push({
180
228
  file: rel,
181
- message: `name "${fm.name}" does not match directory path "${expectedPath}"`
229
+ message: `name exceeds 64 characters (${fm.name.length} chars)`
230
+ });
231
+ if (fm.name.includes("/")) errors.push({
232
+ file: rel,
233
+ message: `name "${fm.name}" must be a single leaf segment matching its parent directory "${parentDir}" — the namespace is carried by the directory path, not the name`
234
+ });
235
+ else {
236
+ if (fm.name !== parentDir) errors.push({
237
+ file: rel,
238
+ message: `name "${fm.name}" does not match parent directory "${parentDir}"`
239
+ });
240
+ if (!agentSkillNamePattern.test(fm.name)) errors.push({
241
+ file: rel,
242
+ message: `name "${fm.name}" must use only lowercase letters, numbers, and hyphens`
243
+ });
244
+ }
245
+ }
246
+ for (const [key, value] of Object.entries(fm)) if (!specTopLevelKeys.has(key) && !intentArrayKeys.has(key) && isScalarValue(value)) errors.push({
247
+ file: rel,
248
+ message: `non-spec top-level key "${key}" — move client-specific scalar fields under "metadata"`
249
+ });
250
+ if (fm.metadata !== void 0) {
251
+ if (!isRecord(fm.metadata)) errors.push({
252
+ file: rel,
253
+ message: "metadata must be a mapping"
254
+ });
255
+ else if (Object.values(fm.metadata).some((value) => typeof value !== "string")) errors.push({
256
+ file: rel,
257
+ message: "metadata values must be strings"
182
258
  });
183
259
  }
184
260
  if (typeof fm.description === "string" && fm.description.length > 1024) errors.push({
@@ -190,7 +266,6 @@ async function runValidateCommandInternal(dir) {
190
266
  message: "Framework skills must have a \"requires\" field"
191
267
  });
192
268
  warnings.push(...collectAgentSkillSpecWarnings({
193
- filePath,
194
269
  fm,
195
270
  rel
196
271
  }).map(formatWarning));
@@ -235,6 +310,19 @@ async function runValidateCommandInternal(dir) {
235
310
  validatedCount += skillFiles.length;
236
311
  warnings.push(...collectPackagingWarnings(validateContext));
237
312
  }
313
+ if (options.check) for (const plan of fixPlans) errors.push({
314
+ file: plan.file,
315
+ message: `fixable frontmatter migration pending: ${plan.changes.join("; ")}`
316
+ });
317
+ if (options.fix && fixPlans.length > 0) {
318
+ await applyFrontmatterFixes(fixPlans);
319
+ console.log(`✅ Fixed ${fixPlans.length} skill files`);
320
+ await runValidateCommandInternal(dir, {
321
+ ...options,
322
+ fix: false
323
+ });
324
+ return;
325
+ }
238
326
  if (errors.length > 0) fail(buildValidationFailure(errors, warnings));
239
327
  console.log(`✅ Validated ${validatedCount} skill files — all passed`);
240
328
  if (warnings.length > 0) console.log();
@@ -266,6 +354,5 @@ function collectDefaultSkillsDirs(context, findSkillFiles) {
266
354
  addSkillsDir(context.targetSkillsDir ?? (context.packageRoot ? join(context.packageRoot, "skills") : resolve(context.cwd, "skills")));
267
355
  return skillsDirs;
268
356
  }
269
-
270
357
  //#endregion
271
- export { runValidateCommand };
358
+ export { runValidateCommand };
@@ -1,5 +1,4 @@
1
1
  import { appendFileSync, writeFileSync } from "node:fs";
2
-
3
2
  //#region src/workflow-review.ts
4
3
  function collectStaleReviewItems(reports) {
5
4
  const items = [];
@@ -148,6 +147,5 @@ function writeStaleReviewWorkflowFiles(items, options = {}) {
148
147
  if (hasReview) writeFileSync(prBodyPath, summary);
149
148
  if (summaryPath) appendFileSync(summaryPath, summary);
150
149
  }
151
-
152
150
  //#endregion
153
- export { writeStaleReviewWorkflowFiles as a, createWorkflowAdvisoryReviewItems as i, collectStaleReviewItems as n, createFailedStaleReviewItem as r, buildStaleReviewBody as t };
151
+ export { writeStaleReviewWorkflowFiles as a, createWorkflowAdvisoryReviewItems as i, collectStaleReviewItems as n, createFailedStaleReviewItem as r, buildStaleReviewBody as t };
@@ -1,3 +1,2 @@
1
- import { a as writeStaleReviewWorkflowFiles, i as createWorkflowAdvisoryReviewItems, n as collectStaleReviewItems, r as createFailedStaleReviewItem, t as buildStaleReviewBody } from "./workflow-review-wL1Iu2Sf.mjs";
2
-
3
- export { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles };
1
+ import { a as writeStaleReviewWorkflowFiles, i as createWorkflowAdvisoryReviewItems, n as collectStaleReviewItems, r as createFailedStaleReviewItem } from "./workflow-review-B4AfwtHH.mjs";
2
+ export { collectStaleReviewItems, createFailedStaleReviewItem, createWorkflowAdvisoryReviewItems, writeStaleReviewWorkflowFiles };
@@ -1,9 +1,8 @@
1
- import { r as findSkillFiles } from "./utils-Dj49bkF_.mjs";
1
+ import { r as findSkillFiles } from "./utils-6FtqhOYf.mjs";
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { dirname, join } from "node:path";
4
4
  import { parse } from "yaml";
5
5
  import { parse as parse$1 } from "jsonc-parser";
6
-
7
6
  //#region src/workspace-patterns.ts
8
7
  function normalizeWorkspacePattern(pattern) {
9
8
  return pattern.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
@@ -189,6 +188,5 @@ function findPackagesWithSkills(root) {
189
188
  function findWorkspacePackages(root) {
190
189
  return readWorkspacePackageDirs(root) ?? [];
191
190
  }
192
-
193
191
  //#endregion
194
- export { readWorkspacePatterns as a, getWorkspaceInfo as i, findWorkspacePackages as n, resolveWorkspacePackages as o, findWorkspaceRoot as r, findPackagesWithSkills as t };
192
+ export { readWorkspacePatterns as a, getWorkspaceInfo as i, findWorkspacePackages as n, resolveWorkspacePackages as o, findWorkspaceRoot as r, findPackagesWithSkills as t };
@@ -0,0 +1,2 @@
1
+ import { i as getWorkspaceInfo, r as findWorkspaceRoot } from "./workspace-patterns-BDoJIWk-.mjs";
2
+ export { findWorkspaceRoot, getWorkspaceInfo };
@@ -52,7 +52,9 @@ SKILL.md into that package's skills directory (e.g.
52
52
  `packages/client/skills/core/SKILL.md`), not a shared root.
53
53
 
54
54
  1. **Skill name** — format `library-group/skill-name` (e.g. `tanstack-query/core`,
55
- `tanstack-router/loaders`, `db/core/live-queries`)
55
+ `tanstack-router/loaders`, `db/core/live-queries`). This is the skill's
56
+ directory path: its **last segment** becomes the frontmatter `name` (a
57
+ spec-legal leaf), and the full path is where the `SKILL.md` lives.
56
58
  2. **Skill description** — what the skill covers and when an agent should load it
57
59
  3. **Source documentation** — the docs, guides, API references, and/or source
58
60
  files to distill from
@@ -170,17 +172,18 @@ domain-discovery — use those directly.
170
172
 
171
173
  ```yaml
172
174
  ---
173
- name: [library]/[skill-name]
175
+ name: '[skill-name]'
174
176
  description: >
175
177
  [1–3 sentences. What this skill covers and exactly when an agent should
176
178
  load it. Written for the agent — include the keywords an agent would
177
179
  encounter when it needs this skill. Dense routing key.]
178
- type: core
179
- library: [library]
180
- library_version: "[version this targets]"
180
+ metadata:
181
+ type: core
182
+ library: '[library]'
183
+ library_version: '[version this targets]'
181
184
  sources:
182
- - "[Owner/repo]:docs/[path].md"
183
- - "[Owner/repo]:src/[path].ts"
185
+ - '[Owner/repo]:docs/[path].md'
186
+ - '[Owner/repo]:src/[path].ts'
184
187
  ---
185
188
  ```
186
189
 
@@ -188,14 +191,15 @@ sources:
188
191
 
189
192
  ```yaml
190
193
  ---
191
- name: [library]/[parent]/[skill-name]
194
+ name: '[skill-name]'
192
195
  description: >
193
196
  [1–3 sentences. What this sub-topic covers and when to load it.]
194
- type: sub-skill
195
- library: [library]
196
- library_version: "[version]"
197
+ metadata:
198
+ type: sub-skill
199
+ library: '[library]'
200
+ library_version: '[version]'
197
201
  sources:
198
- - "[Owner/repo]:docs/[path].md"
202
+ - '[Owner/repo]:docs/[path].md'
199
203
  ---
200
204
  ```
201
205
 
@@ -203,29 +207,39 @@ sources:
203
207
 
204
208
  ```yaml
205
209
  ---
206
- name: [library]/[framework]
210
+ name: '[framework]'
207
211
  description: >
208
212
  [1–3 sentences. Framework-specific bindings. Name the hooks, components,
209
213
  providers.]
210
- type: framework
211
- library: [library]
212
- framework: [react | vue | solid | svelte | angular]
213
- library_version: "[version]"
214
+ metadata:
215
+ type: framework
216
+ library: '[library]'
217
+ framework: '[react | vue | solid | svelte | angular]'
218
+ library_version: '[version]'
214
219
  requires:
215
- - [library]/core
220
+ - '[library]/core'
216
221
  sources:
217
- - "[Owner/repo]:docs/framework/[framework]/[path].md"
222
+ - '[Owner/repo]:docs/framework/[framework]/[path].md'
218
223
  ---
219
224
  ```
220
225
 
221
226
  ### Frontmatter rules
222
227
 
228
+ - `name` is the spec-legal leaf segment — lowercase letters, numbers, and
229
+ hyphens only — and matches the skill's parent directory. It carries no
230
+ slashes; the namespace lives in the skill's directory path instead.
231
+ - Intent-specific scalars (`type`, `library`, `library_version`, `framework`)
232
+ live under the `metadata` map. The Agent Skills spec permits only `name`,
233
+ `description`, `license`, `compatibility`, `metadata`, and `allowed-tools`
234
+ at the top level, so emitting these scalars at the top level fails
235
+ validation.
223
236
  - `description` must be written so the agent loads this skill at the right
224
237
  time — not too broad (triggers on everything) and not too narrow (never
225
238
  triggers). Pack with function names, option names, concept keywords.
226
239
  - `sources` uses the format `Owner/repo:relative-path`. Glob patterns are
227
240
  supported (e.g. `TanStack/query:docs/framework/react/guides/*.md`).
228
- - `library_version` is the version of the source library this skill targets.
241
+ - `metadata.library_version` is the version of the source library this skill
242
+ targets.
229
243
  - `requires` lists skills that must be loaded before this one.
230
244
 
231
245
  ---
@@ -287,14 +287,15 @@ framework-agnostic concepts and contains the sub-skill registry.
287
287
 
288
288
  ```yaml
289
289
  ---
290
- name: [lib]-core
290
+ name: '[lib]-core'
291
291
  description: >
292
292
  [1–3 sentences. What this library does and the framework-agnostic
293
293
  concepts it provides. Pack with keywords: function names, config
294
294
  options, concepts. This is a routing key, not a human summary.]
295
- type: core
296
- library: [lib]
297
- library_version: "[version this targets]"
295
+ metadata:
296
+ type: core
297
+ library: '[lib]'
298
+ library_version: '[version this targets]'
298
299
  ---
299
300
  ```
300
301
 
@@ -332,16 +333,17 @@ One SKILL.md per domain. Follow this structure exactly.
332
333
 
333
334
  ```yaml
334
335
  ---
335
- name: [lib]-core/[domain-slug]
336
+ name: '[domain-slug]'
336
337
  description: >
337
338
  [1–3 sentences. What this domain covers AND when to load it. Name
338
339
  specific functions, options, or APIs. Dense routing key.]
339
- type: sub-skill
340
- library: [lib]
341
- library_version: "[version]"
340
+ metadata:
341
+ type: sub-skill
342
+ library: '[lib]'
343
+ library_version: '[version]'
342
344
  sources:
343
- - "[repo]:docs/[path].md"
344
- - "[repo]:src/[path].ts"
345
+ - '[repo]:docs/[path].md'
346
+ - '[repo]:src/[path].ts'
345
347
  ---
346
348
  ```
347
349
 
@@ -452,17 +454,18 @@ framework-specific patterns and mistakes.
452
454
 
453
455
  ```yaml
454
456
  ---
455
- name: react-[lib]
457
+ name: 'react-[lib]'
456
458
  description: >
457
459
  [1–3 sentences. React-specific bindings for [library]. Name the hooks,
458
460
  components, and providers. Mention React-specific patterns like SSR
459
461
  hydration if applicable.]
460
- type: framework
461
- library: [lib]
462
- framework: react
463
- library_version: "[version]"
462
+ metadata:
463
+ type: framework
464
+ library: '[lib]'
465
+ framework: react
466
+ library_version: '[version]'
464
467
  requires:
465
- - [lib]-core
468
+ - '[lib]-core'
466
469
  ---
467
470
  ```
468
471
 
@@ -499,18 +502,18 @@ with the framework frontmatter:
499
502
 
500
503
  ```yaml
501
504
  ---
502
- name: react-[lib]/[domain-slug]
505
+ name: '[domain-slug]'
503
506
  description: >
504
507
  [React-specific description for this domain.]
505
- type: sub-skill
506
- library: [lib]
507
- framework: react
508
- library_version: "[version]"
508
+ metadata:
509
+ type: sub-skill
510
+ library: '[lib]'
511
+ framework: react
512
+ library_version: '[version]'
509
513
  requires:
510
- - [lib]-core
511
- - [lib]-core/[domain-slug]
514
+ - '[lib]-core'
515
+ - '[lib]-core/[domain-slug]'
512
516
  ---
513
-
514
517
  This skill builds on [lib]-core/[domain-slug]. Read the core skill first.
515
518
  ```
516
519
 
@@ -556,19 +559,19 @@ framework hooks and providers).
556
559
 
557
560
  ```yaml
558
561
  ---
559
- name: compositions/[lib-a]-[lib-b]
562
+ name: '[lib-a]-[lib-b]'
560
563
  description: >
561
564
  [How lib-a and lib-b wire together. Name the specific integration
562
565
  points: functions, hooks, patterns.]
563
- type: composition
564
- library_version: "[version of primary lib]"
566
+ metadata:
567
+ type: composition
568
+ library_version: '[version of primary lib]'
565
569
  requires:
566
- - [lib-a]-core
567
- - react-[lib-a]
568
- - [lib-b]-core
569
- - react-[lib-b]
570
+ - '[lib-a]-core'
571
+ - 'react-[lib-a]'
572
+ - '[lib-b]-core'
573
+ - 'react-[lib-b]'
570
574
  ---
571
-
572
575
  This skill requires familiarity with both [lib-a] and [lib-b].
573
576
  Read their core and framework skills first.
574
577
  ```
@@ -601,15 +604,16 @@ for these skill types.
601
604
 
602
605
  ```yaml
603
606
  ---
604
- name: react-[lib]/security
607
+ name: security
605
608
  description: >
606
609
  Go-live security validation for [library]. Checks [specific concerns].
607
- type: security
608
- library: [lib]
609
- framework: react
610
- library_version: '[version]'
610
+ metadata:
611
+ type: security
612
+ library: '[lib]'
613
+ framework: react
614
+ library_version: '[version]'
611
615
  requires:
612
- - react-[lib]
616
+ - 'react-[lib]'
613
617
  ---
614
618
  ```
615
619
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/intent",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,14 +28,13 @@
28
28
  "dependencies": {
29
29
  "cac": "^6.7.14",
30
30
  "jsonc-parser": "^3.3.1",
31
- "semver": "^7.7.4",
32
- "yaml": "2.8.3"
31
+ "semver": "^7.8.4",
32
+ "yaml": "2.9.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/semver": "^7.7.1",
36
- "@verdaccio/node-api": "6.0.0-6-next.76",
37
- "tsdown": "^0.19.0",
38
- "verdaccio": "^6.3.2"
36
+ "tsdown": "^0.22.2",
37
+ "verdaccio": "^6.7.2"
39
38
  },
40
39
  "scripts": {
41
40
  "build": "tsdown src/index.ts src/cli.ts src/setup.ts src/core.ts --format esm --dts",
@@ -1,3 +0,0 @@
1
- import { t as readIntentArtifacts } from "./artifact-coverage-nGwun1tt.mjs";
2
-
3
- export { readIntentArtifacts };
@@ -1,9 +0,0 @@
1
- import "./utils-Dj49bkF_.mjs";
2
- import "./skill-paths-Cr74uFk4.mjs";
3
- import "./scanner-2XDBAsbm.mjs";
4
- import "./workspace-patterns-Cz_lNhwz.mjs";
5
- import "./project-context-DDCie6Ro.mjs";
6
- import "./excludes-DDMe-4iu.mjs";
7
- import { a as checkLoadAllowed, i as applySourcePolicy, n as EMPTY_NOTE, o as readSkillSourcesConfig, r as MIGRATION_NOTICE, s as scanForPolicedIntents, t as ALLOW_ALL_NOTICE } from "./source-policy-rGOtjQSM.mjs";
8
-
9
- export { scanForPolicedIntents };
@@ -1,5 +0,0 @@
1
- import "./utils-Dj49bkF_.mjs";
2
- import "./artifact-coverage-nGwun1tt.mjs";
3
- import { n as checkStaleness, r as readPackageName, t as buildWorkspaceCoverageSignals } from "./staleness-B8IvDS_9.mjs";
4
-
5
- export { buildWorkspaceCoverageSignals, checkStaleness, readPackageName };
@@ -1,4 +0,0 @@
1
- import "./utils-Dj49bkF_.mjs";
2
- import { a as readWorkspacePatterns, i as getWorkspaceInfo, n as findWorkspacePackages, o as resolveWorkspacePackages, r as findWorkspaceRoot, t as findPackagesWithSkills } from "./workspace-patterns-Cz_lNhwz.mjs";
3
-
4
- export { findWorkspaceRoot, getWorkspaceInfo };