@tanstack/intent 0.0.14 → 0.0.20

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 (36) hide show
  1. package/README.md +42 -5
  2. package/dist/cli.d.mts +6 -1
  3. package/dist/cli.mjs +253 -170
  4. package/dist/display-CuCDLPP_.mjs +3 -0
  5. package/dist/index.d.mts +10 -11
  6. package/dist/index.mjs +37 -14
  7. package/dist/install-prompt-C0M-U3WZ.mjs +59 -0
  8. package/dist/intent-library.mjs +5 -49
  9. package/dist/{library-scanner-B1tmOzwf.mjs → library-scanner-DBOEhfm8.mjs} +4 -5
  10. package/dist/library-scanner.d.mts +5 -5
  11. package/dist/library-scanner.mjs +2 -2
  12. package/dist/scanner-BHPl60jH.mjs +5 -0
  13. package/dist/scanner-DVepyEwz.mjs +365 -0
  14. package/dist/setup-B-zdCBu4.d.mts +36 -0
  15. package/dist/setup-mGV2dZrq.mjs +367 -0
  16. package/dist/setup.d.mts +2 -2
  17. package/dist/setup.mjs +3 -2
  18. package/dist/{staleness-DJfMKH62.mjs → staleness-DZKvsLVq.mjs} +24 -3
  19. package/dist/staleness-Dr5-5wj5.mjs +4 -0
  20. package/dist/{types-BmnI8kFB.d.mts → types-ddLtccfV.d.mts} +30 -7
  21. package/dist/utils-BfjM1mQe.mjs +152 -0
  22. package/dist/utils-D7OKi0Rn.mjs +3 -0
  23. package/meta/domain-discovery/SKILL.md +95 -20
  24. package/meta/feedback-collection/SKILL.md +20 -1
  25. package/meta/generate-skill/SKILL.md +56 -5
  26. package/meta/templates/workflows/check-skills.yml +4 -4
  27. package/meta/templates/workflows/{notify-playbooks.yml → notify-intent.yml} +4 -4
  28. package/meta/tree-generator/SKILL.md +2 -2
  29. package/package.json +9 -5
  30. package/dist/scanner-CECGXgox.mjs +0 -4
  31. package/dist/scanner-CY40iozO.mjs +0 -218
  32. package/dist/setup-CANkTz55.d.mts +0 -18
  33. package/dist/setup-Nif1-nhS.mjs +0 -211
  34. package/dist/staleness-C1h7RuZ9.mjs +0 -4
  35. package/dist/utils-CDJzAdjD.mjs +0 -79
  36. /package/dist/{display-D_XzuGnu.mjs → display-DhsUxNJW.mjs} +0 -0
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as IntentProjectConfig, c as ScanResult, d as StalenessReport, i as IntentPackage, l as SkillEntry, n as FeedbackPayload, o as MetaFeedbackPayload, r as IntentConfig, s as MetaSkillName, t as AgentName, u as SkillStaleness } from "./types-BmnI8kFB.mjs";
2
- import { a as runEditPackageJson, i as runAddLibraryBin, n as EditPackageJsonResult, o as runSetupGithubActions, r as SetupGithubActionsResult, t as AddLibraryBinResult } from "./setup-CANkTz55.mjs";
1
+ import { a as IntentProjectConfig, c as ScanResult, d as StalenessReport, i as IntentPackage, l as SkillEntry, n as FeedbackPayload, o as MetaFeedbackPayload, r as IntentConfig, s as MetaSkillName, t as AgentName, u as SkillStaleness } from "./types-ddLtccfV.mjs";
2
+ import { d as runEditPackageJson, i as SetupGithubActionsResult, l as runAddLibraryBin, n as EditPackageJsonResult, p as runSetupGithubActions, t as AddLibraryBinResult } from "./setup-B-zdCBu4.mjs";
3
3
 
4
4
  //#region src/scanner.d.ts
5
5
  declare function scanForIntents(root?: string): Promise<ScanResult>;
@@ -13,11 +13,11 @@ declare function hasGhCli(): boolean;
13
13
  declare function resolveFrequency(root: string): string;
14
14
  declare function validatePayload(payload: unknown): {
15
15
  valid: boolean;
16
- errors: string[];
16
+ errors: Array<string>;
17
17
  };
18
18
  declare function validateMetaPayload(payload: unknown): {
19
19
  valid: boolean;
20
- errors: string[];
20
+ errors: Array<string>;
21
21
  };
22
22
  declare function metaToMarkdown(payload: MetaFeedbackPayload): string;
23
23
  declare function toMarkdown(payload: FeedbackPayload): string;
@@ -38,19 +38,18 @@ declare function submitMetaFeedback(payload: MetaFeedbackPayload, opts: {
38
38
  /**
39
39
  * Recursively find all SKILL.md files under a directory.
40
40
  */
41
- declare function findSkillFiles(dir: string): string[];
41
+ declare function findSkillFiles(dir: string): Array<string>;
42
42
  /**
43
43
  * Read dependencies and peerDependencies (and optionally devDependencies) from
44
44
  * a parsed package.json object.
45
45
  */
46
- declare function getDeps(pkgJson: Record<string, unknown>, includeDevDeps?: boolean): string[];
46
+ declare function getDeps(pkgJson: Record<string, unknown>, includeDevDeps?: boolean): Array<string>;
47
47
  /**
48
- * Resolve the directory of a dependency by name. First checks the top-level
49
- * node_modules (hoisted layout — npm, yarn, bun), then resolves through the
50
- * parent package's real path to handle pnpm's virtual store layout where
51
- * transitive deps are siblings in the .pnpm virtual store node_modules.
48
+ * Resolve the directory of a dependency by name. Tries createRequire first
49
+ * (handles pnpm symlinks), then falls back to walking up node_modules
50
+ * directories (handles packages with export maps that block ./package.json).
52
51
  */
53
- declare function resolveDepDir(depName: string, parentDir: string, parentName: string, nodeModulesDir: string): string | null;
52
+ declare function resolveDepDir(depName: string, parentDir: string): string | null;
54
53
  /**
55
54
  * Parse YAML frontmatter from a file. Returns null if no frontmatter or on error.
56
55
  */
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { i as resolveDepDir, n as getDeps, r as parseFrontmatter, t as findSkillFiles } from "./utils-CDJzAdjD.mjs";
2
- import { t as scanForIntents } from "./scanner-CY40iozO.mjs";
3
- import { t as checkStaleness } from "./staleness-DJfMKH62.mjs";
4
- import { n as runEditPackageJson, r as runSetupGithubActions, t as runAddLibraryBin } from "./setup-Nif1-nhS.mjs";
1
+ import { a as parseFrontmatter, n as findSkillFiles, o as resolveDepDir, r as getDeps } from "./utils-BfjM1mQe.mjs";
2
+ import { a as runAddLibraryBin, l as runSetupGithubActions, s as runEditPackageJson } from "./setup-mGV2dZrq.mjs";
3
+ import { t as scanForIntents } from "./scanner-DVepyEwz.mjs";
4
+ import { t as checkStaleness } from "./staleness-DZKvsLVq.mjs";
5
5
  import { readFileSync, writeFileSync } from "node:fs";
6
6
  import { join } from "node:path";
7
7
  import { execFileSync, execSync } from "node:child_process";
@@ -31,17 +31,26 @@ function hasGhCli() {
31
31
  function getHomeConfigDir() {
32
32
  return process.env.XDG_CONFIG_HOME ?? join(process.env.HOME ?? process.env.USERPROFILE ?? "", ".config");
33
33
  }
34
- function resolveFrequency(root) {
35
- const userConfigPath = join(getHomeConfigDir(), "intent", "config.json");
36
- try {
37
- const userCfg = JSON.parse(readFileSync(userConfigPath, "utf8"));
38
- if (userCfg.feedback?.frequency) return userCfg.feedback.frequency;
39
- } catch {}
40
- const projectConfigPath = join(root, "intent.config.json");
34
+ function parseFrequency(value) {
35
+ if (value === "always" || value === "never") return value;
36
+ if (typeof value !== "string") return null;
37
+ const match = /^every-(\d+)$/.exec(value);
38
+ if (!match) return null;
39
+ const count = Number(match[1]);
40
+ return Number.isInteger(count) && count > 0 ? `every-${count}` : null;
41
+ }
42
+ function readFrequency(filePath) {
41
43
  try {
42
- const projCfg = JSON.parse(readFileSync(projectConfigPath, "utf8"));
43
- if (projCfg.feedback?.frequency) return projCfg.feedback.frequency;
44
- } catch {}
44
+ return parseFrequency(JSON.parse(readFileSync(filePath, "utf8")).feedback?.frequency);
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+ function resolveFrequency(root) {
50
+ const userFrequency = readFrequency(join(getHomeConfigDir(), "intent", "config.json"));
51
+ if (userFrequency) return userFrequency;
52
+ const projectFrequency = readFrequency(join(root, "intent.config.json"));
53
+ if (projectFrequency) return projectFrequency;
45
54
  return "every-5";
46
55
  }
47
56
  const REQUIRED_FIELDS = [
@@ -102,6 +111,18 @@ const VALID_QUALITY_RATINGS = [
102
111
  "mixed",
103
112
  "bad"
104
113
  ];
114
+ const VALID_INTERVIEW_QUALITY_RATINGS = [
115
+ "good",
116
+ "mixed",
117
+ "bad",
118
+ "skipped"
119
+ ];
120
+ const VALID_FAILURE_MODE_QUALITY_RATINGS = [
121
+ "good",
122
+ "mixed",
123
+ "bad",
124
+ "not-applicable"
125
+ ];
105
126
  function validateMetaPayload(payload) {
106
127
  const errors = [];
107
128
  if (!payload || typeof payload !== "object") return {
@@ -114,6 +135,8 @@ function validateMetaPayload(payload) {
114
135
  if (obj.agentUsed && !VALID_AGENTS.includes(obj.agentUsed)) errors.push(`agentUsed must be one of: ${VALID_AGENTS.join(", ")}`);
115
136
  if (obj.artifactQuality && !VALID_QUALITY_RATINGS.includes(obj.artifactQuality)) errors.push("artifactQuality must be one of: good, mixed, bad");
116
137
  if (obj.userRating && !VALID_QUALITY_RATINGS.includes(obj.userRating)) errors.push("userRating must be one of: good, mixed, bad");
138
+ if (obj.interviewQuality && !VALID_INTERVIEW_QUALITY_RATINGS.includes(obj.interviewQuality)) errors.push("interviewQuality must be one of: good, mixed, bad, skipped");
139
+ if (obj.failureModeQuality && !VALID_FAILURE_MODE_QUALITY_RATINGS.includes(obj.failureModeQuality)) errors.push("failureModeQuality must be one of: good, mixed, bad, not-applicable");
117
140
  if (containsSecrets(Object.values(obj).filter((v) => typeof v === "string").join("\n"))) errors.push("Payload appears to contain secrets or tokens — submission rejected");
118
141
  return {
119
142
  valid: errors.length === 0,
@@ -0,0 +1,59 @@
1
+ //#region src/install-prompt.ts
2
+ const INSTALL_PROMPT = `You are an AI assistant helping a developer set up skill-to-task mappings for their project.
3
+
4
+ Follow these steps in order:
5
+
6
+ 1. CHECK FOR EXISTING MAPPINGS
7
+ Search the project's agent config files (AGENTS.md, CLAUDE.md, .cursorrules,
8
+ .github/copilot-instructions.md) for a block delimited by:
9
+ <!-- intent-skills:start -->
10
+ <!-- intent-skills:end -->
11
+ - If found: show the user the current mappings, keep that file as the source of truth,
12
+ and ask "What would you like to update?" Then skip to step 4 with their requested changes.
13
+ - If not found: continue to step 2.
14
+
15
+ 2. DISCOVER AVAILABLE SKILLS
16
+ Run: \`npx @tanstack/intent@latest list\`
17
+ This outputs each skill's name, description, full path, and whether it was found in
18
+ project-local node_modules or accessible global node_modules.
19
+ This works best in Node-compatible environments (npm, pnpm, Bun, or Deno npm interop
20
+ with node_modules enabled).
21
+
22
+ 3. SCAN THE REPOSITORY
23
+ Build a picture of the project's structure and patterns:
24
+ - Read package.json for library dependencies
25
+ - Survey the directory layout (src/, app/, routes/, components/, api/, etc.)
26
+ - Note recurring patterns (routing, data fetching, auth, UI components, etc.)
27
+
28
+ Based on this, propose 3-5 skill-to-task mappings. For each one explain:
29
+ - The task or code area (in plain language the user would recognise)
30
+ - Which skill applies and why
31
+
32
+ Then ask: "What other tasks do you commonly use AI coding agents for?
33
+ I'll create mappings for those too."
34
+ Also ask: "I'll default to AGENTS.md unless you want another supported config file.
35
+ Do you have a preference?"
36
+
37
+ 4. WRITE THE MAPPINGS BLOCK
38
+ Once you have the full set of mappings, write or update the agent config file.
39
+ - If you found an existing intent-skills block, update that file in place.
40
+ - Otherwise prefer AGENTS.md by default, unless the user asked for another supported file.
41
+
42
+ Use this exact block:
43
+
44
+ <!-- intent-skills:start -->
45
+ # Skill mappings - when working in these areas, load the linked skill file into context.
46
+ skills:
47
+ - task: "describe the task or code area here"
48
+ load: "node_modules/package-name/skills/skill-name/SKILL.md"
49
+ <!-- intent-skills:end -->
50
+
51
+ Rules:
52
+ - Use the user's own words for task descriptions
53
+ - Include the exact path from \`npx @tanstack/intent@latest list\` output so agents can load it directly
54
+ - Keep entries concise - this block is read on every agent task
55
+ - Preserve all content outside the block tags unchanged
56
+ - If the user is on Deno, note that this setup is best-effort today and relies on npm interop`;
57
+
58
+ //#endregion
59
+ export { INSTALL_PROMPT as t };
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import "./utils-CDJzAdjD.mjs";
3
- import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-D_XzuGnu.mjs";
4
- import { t as scanLibrary } from "./library-scanner-B1tmOzwf.mjs";
2
+ import "./utils-BfjM1mQe.mjs";
3
+ import { t as INSTALL_PROMPT } from "./install-prompt-C0M-U3WZ.mjs";
4
+ import { n as printSkillTree, r as printTable, t as computeSkillNameWidth } from "./display-DhsUxNJW.mjs";
5
+ import { t as scanLibrary } from "./library-scanner-DBOEhfm8.mjs";
5
6
 
6
7
  //#region src/intent-library.ts
7
8
  async function cmdList() {
@@ -52,52 +53,7 @@ async function cmdList() {
52
53
  }
53
54
  }
54
55
  function cmdInstall() {
55
- console.log(`You are an AI assistant helping a developer set up skill-to-task mappings for their project.
56
-
57
- Follow these steps in order:
58
-
59
- 1. CHECK FOR EXISTING MAPPINGS
60
- Search the project's agent config files (CLAUDE.md, AGENTS.md, .cursorrules,
61
- .github/copilot-instructions.md) for a block delimited by:
62
- <!-- intent-skills:start -->
63
- <!-- intent-skills:end -->
64
- - If found: show the user the current mappings and ask "What would you like to update?"
65
- Then skip to step 4 with their requested changes.
66
- - If not found: continue to step 2.
67
-
68
- 2. DISCOVER AVAILABLE SKILLS
69
- Run: intent list
70
- This outputs each skill's name, description, and full path — grouped by package.
71
-
72
- 3. SCAN THE REPOSITORY
73
- Build a picture of the project's structure and patterns:
74
- - Read package.json for library dependencies
75
- - Survey the directory layout (src/, app/, routes/, components/, api/, etc.)
76
- - Note recurring patterns (routing, data fetching, auth, UI components, etc.)
77
-
78
- Based on this, propose 3–5 skill-to-task mappings. For each one explain:
79
- - The task or code area (in plain language the user would recognise)
80
- - Which skill applies and why
81
-
82
- Then ask: "What other tasks do you commonly use AI coding agents for?
83
- I'll create mappings for those too."
84
-
85
- 4. WRITE THE MAPPINGS BLOCK
86
- Once you have the full set of mappings, write or update the agent config file
87
- (prefer CLAUDE.md; create it if none exists) with this exact block:
88
-
89
- <!-- intent-skills:start -->
90
- # Skill mappings — when working in these areas, load the linked skill file into context.
91
- skills:
92
- - task: "describe the task or code area here"
93
- load: "node_modules/package-name/skills/skill-name/SKILL.md"
94
- <!-- intent-skills:end -->
95
-
96
- Rules:
97
- - Use the user's own words for task descriptions
98
- - Include the exact path from \`intent list\` output so agents can load it directly
99
- - Keep entries concise — this block is read on every agent task
100
- - Preserve all content outside the block tags unchanged`);
56
+ console.log(INSTALL_PROMPT);
101
57
  }
102
58
  const USAGE = `TanStack Intent
103
59
 
@@ -1,4 +1,4 @@
1
- import { i as resolveDepDir, n as getDeps, r as parseFrontmatter } from "./utils-CDJzAdjD.mjs";
1
+ import { a as parseFrontmatter, o as resolveDepDir, r as getDeps } from "./utils-BfjM1mQe.mjs";
2
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
3
  import { dirname, join, relative, sep } from "node:path";
4
4
 
@@ -12,7 +12,7 @@ function readPkgJson(dir) {
12
12
  }
13
13
  function findHomeDir(scriptPath) {
14
14
  let dir = dirname(scriptPath);
15
- while (true) {
15
+ for (;;) {
16
16
  if (existsSync(join(dir, "package.json"))) return dir;
17
17
  const parent = dirname(dir);
18
18
  if (parent === dir) return null;
@@ -57,8 +57,7 @@ function discoverSkills(skillsDir) {
57
57
  walk(skillsDir);
58
58
  return skills;
59
59
  }
60
- async function scanLibrary(scriptPath, projectRoot) {
61
- const nodeModulesDir = join(projectRoot ?? process.cwd(), "node_modules");
60
+ async function scanLibrary(scriptPath, _projectRoot) {
62
61
  const packages = [];
63
62
  const warnings = [];
64
63
  const visited = /* @__PURE__ */ new Set();
@@ -89,7 +88,7 @@ async function scanLibrary(scriptPath, projectRoot) {
89
88
  skills: existsSync(skillsDir) ? discoverSkills(skillsDir) : []
90
89
  });
91
90
  for (const depName of getDeps(pkg)) {
92
- const depDir = resolveDepDir(depName, dir, name, nodeModulesDir);
91
+ const depDir = resolveDepDir(depName, dir);
93
92
  if (!depDir) continue;
94
93
  const depPkg = readPkgJson(depDir);
95
94
  if (depPkg && hasIntentBin(depPkg)) processPackage(depName, depDir);
@@ -1,16 +1,16 @@
1
- import { l as SkillEntry } from "./types-BmnI8kFB.mjs";
1
+ import { l as SkillEntry } from "./types-ddLtccfV.mjs";
2
2
 
3
3
  //#region src/library-scanner.d.ts
4
4
  interface LibraryPackage {
5
5
  name: string;
6
6
  version: string;
7
7
  description: string;
8
- skills: SkillEntry[];
8
+ skills: Array<SkillEntry>;
9
9
  }
10
10
  interface LibraryScanResult {
11
- packages: LibraryPackage[];
12
- warnings: string[];
11
+ packages: Array<LibraryPackage>;
12
+ warnings: Array<string>;
13
13
  }
14
- declare function scanLibrary(scriptPath: string, projectRoot?: string): Promise<LibraryScanResult>;
14
+ declare function scanLibrary(scriptPath: string, _projectRoot?: string): Promise<LibraryScanResult>;
15
15
  //#endregion
16
16
  export { LibraryPackage, LibraryScanResult, scanLibrary };
@@ -1,4 +1,4 @@
1
- import "./utils-CDJzAdjD.mjs";
2
- import { t as scanLibrary } from "./library-scanner-B1tmOzwf.mjs";
1
+ import "./utils-BfjM1mQe.mjs";
2
+ import { t as scanLibrary } from "./library-scanner-DBOEhfm8.mjs";
3
3
 
4
4
  export { scanLibrary };
@@ -0,0 +1,5 @@
1
+ import "./utils-BfjM1mQe.mjs";
2
+ import "./setup-mGV2dZrq.mjs";
3
+ import { t as scanForIntents } from "./scanner-DVepyEwz.mjs";
4
+
5
+ export { scanForIntents };