@tanstack/intent 0.0.1 → 0.0.3
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 +10 -10
- package/dist/cli.mjs +74 -11
- package/dist/index.mjs +3 -3
- package/dist/intent-library.mjs +6 -23
- package/dist/{library-scanner-BrznE00j.mjs → library-scanner-D0aP7is_.mjs} +5 -2
- package/dist/library-scanner.mjs +2 -2
- package/dist/{scanner-CpsJAHXT.mjs → scanner-BwCyu1Jq.mjs} +15 -6
- package/dist/scanner-fAWJUn6Q.mjs +4 -0
- package/dist/staleness-B5gUj7FR.mjs +4 -0
- package/dist/{staleness-CnomT9Hm.mjs → staleness-lP6B0O4z.mjs} +1 -1
- package/dist/{utils-DjkEPBxu.mjs → utils-DH3jY3CI.mjs} +1 -1
- package/meta/domain-discovery/SKILL.md +1 -1
- package/package.json +3 -2
- package/dist/scanner-BuWPDJ4P.mjs +0 -4
- package/dist/staleness-DyhsrqQ5.mjs +0 -4
package/README.md
CHANGED
|
@@ -50,16 +50,16 @@ npx intent setup
|
|
|
50
50
|
|
|
51
51
|
## CLI Commands
|
|
52
52
|
|
|
53
|
-
| Command
|
|
54
|
-
|
|
|
55
|
-
| `intent init`
|
|
56
|
-
| `intent list [--json]`
|
|
57
|
-
| `intent meta`
|
|
58
|
-
| `intent scaffold`
|
|
59
|
-
| `intent validate [dir]`
|
|
60
|
-
| `intent setup`
|
|
61
|
-
| `intent stale [--json]`
|
|
62
|
-
| `intent feedback`
|
|
53
|
+
| Command | Description |
|
|
54
|
+
| ----------------------- | ----------------------------------------------- |
|
|
55
|
+
| `intent init` | Inject intent discovery into agent config files |
|
|
56
|
+
| `intent list [--json]` | Discover intent-enabled packages |
|
|
57
|
+
| `intent meta` | List meta-skills for library maintainers |
|
|
58
|
+
| `intent scaffold` | Print the guided skill generation prompt |
|
|
59
|
+
| `intent validate [dir]` | Validate SKILL.md files |
|
|
60
|
+
| `intent setup` | Copy CI/Oz workflow templates |
|
|
61
|
+
| `intent stale [--json]` | Check skills for version drift |
|
|
62
|
+
| `intent feedback` | Submit skill feedback |
|
|
63
63
|
|
|
64
64
|
## License
|
|
65
65
|
|
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-DH3jY3CI.mjs";
|
|
3
|
+
import { t as scanForIntents } from "./scanner-BwCyu1Jq.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";
|
|
@@ -12,6 +12,55 @@ import { fileURLToPath } from "node:url";
|
|
|
12
12
|
function getMetaDir() {
|
|
13
13
|
return join(dirname(fileURLToPath(import.meta.url)), "..", "meta");
|
|
14
14
|
}
|
|
15
|
+
function padColumn(text, width) {
|
|
16
|
+
return text.length >= width ? text + " " : text.padEnd(width);
|
|
17
|
+
}
|
|
18
|
+
function printTable(headers, rows) {
|
|
19
|
+
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? "").length)) + 2);
|
|
20
|
+
const headerLine = headers.map((h, i) => padColumn(h, widths[i])).join("");
|
|
21
|
+
const separator = widths.map((w) => "─".repeat(w)).join("");
|
|
22
|
+
console.log(headerLine);
|
|
23
|
+
console.log(separator);
|
|
24
|
+
for (const row of rows) console.log(row.map((cell, i) => padColumn(cell, widths[i])).join(""));
|
|
25
|
+
}
|
|
26
|
+
function printSkillTree(skills, opts) {
|
|
27
|
+
const roots = [];
|
|
28
|
+
const children = /* @__PURE__ */ new Map();
|
|
29
|
+
for (const skill of skills) {
|
|
30
|
+
const slashIdx = skill.name.indexOf("/");
|
|
31
|
+
if (slashIdx === -1) roots.push(skill.name);
|
|
32
|
+
else {
|
|
33
|
+
const parent = skill.name.slice(0, slashIdx);
|
|
34
|
+
if (!children.has(parent)) children.set(parent, []);
|
|
35
|
+
children.get(parent).push(skill);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (roots.length === 0) {
|
|
39
|
+
for (const skill of skills) if (!roots.includes(skill.name)) roots.push(skill.name);
|
|
40
|
+
}
|
|
41
|
+
for (const rootName of roots) {
|
|
42
|
+
const rootSkill = skills.find((s) => s.name === rootName);
|
|
43
|
+
if (!rootSkill) continue;
|
|
44
|
+
printSkillLine(rootName, rootSkill, 4, opts);
|
|
45
|
+
for (const sub of children.get(rootName) ?? []) printSkillLine(sub.name.slice(sub.name.indexOf("/") + 1), sub, 6, opts);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function printSkillLine(displayName, skill, indent, opts) {
|
|
49
|
+
const nameStr = " ".repeat(indent) + displayName;
|
|
50
|
+
const padding = " ".repeat(Math.max(2, opts.nameWidth - nameStr.length));
|
|
51
|
+
const typeCol = opts.showTypes ? (skill.type ? `[${skill.type}]` : "").padEnd(14) : "";
|
|
52
|
+
console.log(`${nameStr}${padding}${typeCol}${skill.description}`);
|
|
53
|
+
}
|
|
54
|
+
function computeSkillNameWidth(allPackageSkills) {
|
|
55
|
+
let max = 0;
|
|
56
|
+
for (const skills of allPackageSkills) for (const s of skills) {
|
|
57
|
+
const slashIdx = s.name.indexOf("/");
|
|
58
|
+
const displayName = slashIdx === -1 ? s.name : s.name.slice(slashIdx + 1);
|
|
59
|
+
const indent = slashIdx === -1 ? 4 : 6;
|
|
60
|
+
max = Math.max(max, indent + displayName.length);
|
|
61
|
+
}
|
|
62
|
+
return max + 2;
|
|
63
|
+
}
|
|
15
64
|
async function cmdList(args) {
|
|
16
65
|
const jsonOutput = args.includes("--json");
|
|
17
66
|
let result;
|
|
@@ -33,14 +82,28 @@ async function cmdList(args) {
|
|
|
33
82
|
}
|
|
34
83
|
return;
|
|
35
84
|
}
|
|
36
|
-
|
|
85
|
+
const totalSkills = result.packages.reduce((sum, p) => sum + p.skills.length, 0);
|
|
86
|
+
console.log(`\n${result.packages.length} intent-enabled packages, ${totalSkills} skills (${result.packageManager})\n`);
|
|
87
|
+
printTable([
|
|
88
|
+
"PACKAGE",
|
|
89
|
+
"VERSION",
|
|
90
|
+
"SKILLS",
|
|
91
|
+
"REQUIRES"
|
|
92
|
+
], result.packages.map((pkg) => [
|
|
93
|
+
pkg.name,
|
|
94
|
+
pkg.version,
|
|
95
|
+
String(pkg.skills.length),
|
|
96
|
+
pkg.intent.requires?.join(", ") || "–"
|
|
97
|
+
]));
|
|
98
|
+
const nameWidth = computeSkillNameWidth(result.packages.map((p) => p.skills));
|
|
99
|
+
const showTypes = result.packages.some((p) => p.skills.some((s) => s.type));
|
|
100
|
+
console.log(`\nSkills:\n`);
|
|
37
101
|
for (const pkg of result.packages) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
102
|
+
console.log(` ${pkg.name}`);
|
|
103
|
+
printSkillTree(pkg.skills, {
|
|
104
|
+
nameWidth,
|
|
105
|
+
showTypes
|
|
106
|
+
});
|
|
44
107
|
console.log();
|
|
45
108
|
}
|
|
46
109
|
if (result.warnings.length > 0) {
|
|
@@ -276,8 +339,8 @@ switch (command) {
|
|
|
276
339
|
cmdScaffold();
|
|
277
340
|
break;
|
|
278
341
|
case "stale": {
|
|
279
|
-
const { checkStaleness } = await import("./staleness-
|
|
280
|
-
const { scanForIntents: scanStale } = await import("./scanner-
|
|
342
|
+
const { checkStaleness } = await import("./staleness-B5gUj7FR.mjs");
|
|
343
|
+
const { scanForIntents: scanStale } = await import("./scanner-fAWJUn6Q.mjs");
|
|
281
344
|
let staleResult;
|
|
282
345
|
try {
|
|
283
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-DH3jY3CI.mjs";
|
|
2
|
+
import { t as scanForIntents } from "./scanner-BwCyu1Jq.mjs";
|
|
3
|
+
import { t as checkStaleness } from "./staleness-lP6B0O4z.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,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./utils-
|
|
3
|
-
import { t as scanLibrary } from "./library-scanner-
|
|
4
|
-
import { spawnSync } from "node:child_process";
|
|
5
|
-
import { release } from "node:os";
|
|
2
|
+
import "./utils-DH3jY3CI.mjs";
|
|
3
|
+
import { t as scanLibrary } from "./library-scanner-D0aP7is_.mjs";
|
|
6
4
|
|
|
7
5
|
//#region src/intent-library.ts
|
|
8
6
|
async function cmdList() {
|
|
@@ -37,18 +35,7 @@ async function cmdList() {
|
|
|
37
35
|
}
|
|
38
36
|
}
|
|
39
37
|
function cmdInstall() {
|
|
40
|
-
|
|
41
|
-
const platform = process.platform;
|
|
42
|
-
const isWsl = platform === "linux" && (Boolean(process.env.WSL_DISTRO_NAME) || Boolean(process.env.WSL_INTEROP) || release().toLowerCase().includes("microsoft"));
|
|
43
|
-
const tryCommand = (command$1, args = []) => {
|
|
44
|
-
return spawnSync(command$1, args, { input: text }).status === 0;
|
|
45
|
-
};
|
|
46
|
-
if (platform === "darwin") return tryCommand("pbcopy");
|
|
47
|
-
if (platform === "win32") return tryCommand("clip");
|
|
48
|
-
if (isWsl) return tryCommand("clip.exe");
|
|
49
|
-
return tryCommand("wl-copy") || tryCommand("xclip", ["-selection", "clipboard"]) || tryCommand("xsel", ["--clipboard", "--input"]);
|
|
50
|
-
}
|
|
51
|
-
const prompt = `You are an AI assistant helping a developer set up skill-to-task mappings for their project.
|
|
38
|
+
console.log(`You are an AI assistant helping a developer set up skill-to-task mappings for their project.
|
|
52
39
|
|
|
53
40
|
Follow these steps in order:
|
|
54
41
|
|
|
@@ -93,18 +80,14 @@ skills:
|
|
|
93
80
|
- Use the user's own words for task descriptions
|
|
94
81
|
- Include the exact path from \`intent list\` output so agents can load it directly
|
|
95
82
|
- Keep entries concise — this block is read on every agent task
|
|
96
|
-
- Preserve all content outside the block tags unchanged
|
|
97
|
-
console.log("🚀 Intent Install");
|
|
98
|
-
console.log("✨ Copy the prompt below into your AI agent:\n");
|
|
99
|
-
console.log(prompt);
|
|
100
|
-
if (tryCopyToClipboard(prompt)) console.log("\n✅ Copied prompt to clipboard");
|
|
101
|
-
else console.log("\n⚠ Tip: Manually copy the prompt above into your agent");
|
|
83
|
+
- Preserve all content outside the block tags unchanged`);
|
|
102
84
|
}
|
|
103
85
|
const USAGE = `TanStack Intent
|
|
104
86
|
|
|
105
87
|
Usage:
|
|
106
88
|
intent list List all available skills from this library and its dependencies
|
|
107
|
-
intent install
|
|
89
|
+
intent install Print a skill that guides your coding agent to scan the project
|
|
90
|
+
and set up skill-to-task mappings in your agent config`;
|
|
108
91
|
const command = process.argv[2];
|
|
109
92
|
switch (command) {
|
|
110
93
|
case "list":
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as parseFrontmatter } from "./utils-
|
|
1
|
+
import { n as parseFrontmatter } from "./utils-DH3jY3CI.mjs";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join, relative, sep } from "node:path";
|
|
4
4
|
|
|
@@ -37,7 +37,10 @@ function discoverSkills(skillsDir) {
|
|
|
37
37
|
function walk(dir) {
|
|
38
38
|
let entries;
|
|
39
39
|
try {
|
|
40
|
-
entries = readdirSync(dir, {
|
|
40
|
+
entries = readdirSync(dir, {
|
|
41
|
+
withFileTypes: true,
|
|
42
|
+
encoding: "utf8"
|
|
43
|
+
});
|
|
41
44
|
} catch {
|
|
42
45
|
return;
|
|
43
46
|
}
|
package/dist/library-scanner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as parseFrontmatter } from "./utils-
|
|
1
|
+
import { n as parseFrontmatter } from "./utils-DH3jY3CI.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,12 +26,15 @@ 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, {
|
|
34
|
+
entries = readdirSync(dir, {
|
|
35
|
+
withFileTypes: true,
|
|
36
|
+
encoding: "utf8"
|
|
37
|
+
});
|
|
35
38
|
} catch {
|
|
36
39
|
return;
|
|
37
40
|
}
|
|
@@ -86,7 +89,10 @@ async function scanForIntents(root) {
|
|
|
86
89
|
const packageDirs = [];
|
|
87
90
|
let topEntries;
|
|
88
91
|
try {
|
|
89
|
-
topEntries = readdirSync(nodeModulesDir, {
|
|
92
|
+
topEntries = readdirSync(nodeModulesDir, {
|
|
93
|
+
withFileTypes: true,
|
|
94
|
+
encoding: "utf8"
|
|
95
|
+
});
|
|
90
96
|
} catch {
|
|
91
97
|
return {
|
|
92
98
|
packageManager,
|
|
@@ -100,7 +106,10 @@ async function scanForIntents(root) {
|
|
|
100
106
|
if (entry.name.startsWith("@")) {
|
|
101
107
|
let scopedEntries;
|
|
102
108
|
try {
|
|
103
|
-
scopedEntries = readdirSync(dirPath, {
|
|
109
|
+
scopedEntries = readdirSync(dirPath, {
|
|
110
|
+
withFileTypes: true,
|
|
111
|
+
encoding: "utf8"
|
|
112
|
+
});
|
|
104
113
|
} catch {
|
|
105
114
|
continue;
|
|
106
115
|
}
|
|
@@ -64,7 +64,7 @@ Log (but do not group yet):
|
|
|
64
64
|
- What the library does in one sentence
|
|
65
65
|
- The core abstractions a developer interacts with
|
|
66
66
|
- Which frameworks it supports
|
|
67
|
-
- Any existing skill files, agent configs, or
|
|
67
|
+
- Any existing skill files, agent configs, or intents
|
|
68
68
|
- Whether the library is a monorepo and which packages matter
|
|
69
69
|
|
|
70
70
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/intent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Ship compositional knowledge for AI coding agents alongside your npm packages",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts",
|
|
36
|
-
"test:lib": "vitest run"
|
|
36
|
+
"test:lib": "vitest run",
|
|
37
|
+
"test:types": "tsc --noEmit"
|
|
37
38
|
}
|
|
38
39
|
}
|