@cognite/dune 0.2.7 ā 0.3.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.
- package/bin/cli.js +22 -1
- package/bin/skills-command.js +188 -0
- package/package.json +4 -3
package/bin/cli.js
CHANGED
|
@@ -73,6 +73,7 @@ async function main() {
|
|
|
73
73
|
|
|
74
74
|
// Handle different commands
|
|
75
75
|
if (command === "create" || command === "new" || !command || command === ".") {
|
|
76
|
+
// TODO(DUNE-362): simplify directory resolution logic
|
|
76
77
|
// Parse directory argument
|
|
77
78
|
// Support: npx @cognite/dune create . or npx @cognite/dune .
|
|
78
79
|
let dirArg;
|
|
@@ -132,7 +133,7 @@ ${deployLabel}
|
|
|
132
133
|
${deployCommand}
|
|
133
134
|
`);
|
|
134
135
|
} else {
|
|
135
|
-
const appDir = appName || "your-app";
|
|
136
|
+
const appDir = dirName || appName || "your-app";
|
|
136
137
|
console.log(`
|
|
137
138
|
ā
App created successfully!
|
|
138
139
|
|
|
@@ -147,6 +148,21 @@ ${deployLabel}
|
|
|
147
148
|
${deployCommand}
|
|
148
149
|
`);
|
|
149
150
|
}
|
|
151
|
+
|
|
152
|
+
// Pull AI skills into the new app
|
|
153
|
+
try {
|
|
154
|
+
const { runSkillsCli, defaultPullArgs } = await import("./skills-command.js");
|
|
155
|
+
const skillsCwd = isCurrentDir ? process.cwd() : resolve(process.cwd(), dirName || appName);
|
|
156
|
+
console.log("š§ Pulling Dune skills...");
|
|
157
|
+
runSkillsCli(defaultPullArgs(), {
|
|
158
|
+
cwd: skillsCwd,
|
|
159
|
+
timeout: 30_000,
|
|
160
|
+
});
|
|
161
|
+
console.log("ā
Skills installed successfully");
|
|
162
|
+
} catch (error) {
|
|
163
|
+
// Skills pull failure should never block app creation
|
|
164
|
+
console.warn("ā ļø Could not pull Dune skills:", error.message);
|
|
165
|
+
}
|
|
150
166
|
} catch (error) {
|
|
151
167
|
console.error("Error:", error.message);
|
|
152
168
|
process.exit(1);
|
|
@@ -157,6 +173,9 @@ ${deployLabel}
|
|
|
157
173
|
} else if (command === "deploy:interactive") {
|
|
158
174
|
const { handleDeployInteractive } = await import("./deploy-interactive-command.js");
|
|
159
175
|
await handleDeployInteractive(args.slice(1));
|
|
176
|
+
} else if (command === "skills") {
|
|
177
|
+
const { handleSkillsCommand } = await import("./skills-command.js");
|
|
178
|
+
handleSkillsCommand(args.slice(1));
|
|
160
179
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
161
180
|
console.log(`
|
|
162
181
|
@cognite/dune - Build and deploy React apps to Cognite Data Fusion
|
|
@@ -168,6 +187,7 @@ Commands:
|
|
|
168
187
|
create, new Create a new Dune application (default)
|
|
169
188
|
deploy Build and deploy using environment credentials
|
|
170
189
|
deploy:interactive Build and deploy with browser-based login
|
|
190
|
+
skills Manage AI agent skills (pull, push, list)
|
|
171
191
|
help Show this help message
|
|
172
192
|
|
|
173
193
|
Examples:
|
|
@@ -177,6 +197,7 @@ Examples:
|
|
|
177
197
|
npx @cognite/dune create . # Create app in current directory (. is special)
|
|
178
198
|
npx @cognite/dune deploy # Deploy with env credentials
|
|
179
199
|
npx @cognite/dune deploy:interactive # Deploy with browser login
|
|
200
|
+
npx @cognite/dune skills pull # Pull AI skills into your project
|
|
180
201
|
|
|
181
202
|
For programmatic usage:
|
|
182
203
|
import { DuneAuthProvider, useDune } from "@cognite/dune/auth"
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Command
|
|
3
|
+
*
|
|
4
|
+
* Manages AI agent skills for Dune apps. Uses the `skills` package (bundled
|
|
5
|
+
* dependency) for pull/list operations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
|
|
11
|
+
const SKILL_SOURCE = "cognitedata/dune-skills";
|
|
12
|
+
const SUPPORTED_AGENTS = ["claude-code", "cursor"];
|
|
13
|
+
const AGENT_FLAGS = SUPPORTED_AGENTS.flatMap((a) => ["-a", a]);
|
|
14
|
+
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Run the bundled `skills` CLI with the given arguments.
|
|
19
|
+
* @param {string[]} args
|
|
20
|
+
* @param {import('child_process').ExecFileSyncOptions} [options]
|
|
21
|
+
*/
|
|
22
|
+
export function runSkillsCli(args, options = {}) {
|
|
23
|
+
const bin = require.resolve("skills/bin/cli.mjs");
|
|
24
|
+
execFileSync(process.execPath, [bin, ...args], {
|
|
25
|
+
stdio: "inherit",
|
|
26
|
+
cwd: process.cwd(),
|
|
27
|
+
...options,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Print help message
|
|
33
|
+
*/
|
|
34
|
+
function printHelp() {
|
|
35
|
+
console.log(`
|
|
36
|
+
š§ Dune Skills ā Manage AI agent skills for your Dune app
|
|
37
|
+
|
|
38
|
+
Installs skills for: ${SUPPORTED_AGENTS.join(", ")}
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
npx @cognite/dune skills <command> [options]
|
|
42
|
+
|
|
43
|
+
Commands:
|
|
44
|
+
pull Pull all skills into your project
|
|
45
|
+
list List installed skills
|
|
46
|
+
help Show this help message
|
|
47
|
+
|
|
48
|
+
Options for pull:
|
|
49
|
+
--source <owner/repo> Skills repository (default: ${SKILL_SOURCE})
|
|
50
|
+
--skill <name> Pull a specific skill by name
|
|
51
|
+
--interactive, -i Interactively select which skills to install
|
|
52
|
+
--global Install skills globally
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
npx @cognite/dune skills pull # Pull all skills
|
|
56
|
+
npx @cognite/dune skills pull --skill create-client-tool
|
|
57
|
+
npx @cognite/dune skills list # List installed skills
|
|
58
|
+
`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Build the default CLI args for pulling all skills.
|
|
63
|
+
*
|
|
64
|
+
* Invokes: skills add <source> -a claude-code -a cursor --skill '*' -y
|
|
65
|
+
* - "add" : skills CLI subcommand that fetches and installs skills
|
|
66
|
+
* - SKILL_SOURCE : GitHub owner/repo hosting the skill definitions
|
|
67
|
+
* - AGENT_FLAGS : install for every supported AI agent (-a claude-code -a cursor)
|
|
68
|
+
* - --skill '*' : wildcard ā pull every available skill
|
|
69
|
+
* - -y : auto-confirm all prompts (non-interactive / --yes)
|
|
70
|
+
*
|
|
71
|
+
* See: https://github.com/vercel-labs/skills
|
|
72
|
+
* @returns {string[]}
|
|
73
|
+
*/
|
|
74
|
+
export function defaultPullArgs() {
|
|
75
|
+
return ["add", SKILL_SOURCE, ...AGENT_FLAGS, "--skill", "*", "-y"];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Validate that a source string matches owner/repo format.
|
|
80
|
+
* @param {string} source
|
|
81
|
+
*/
|
|
82
|
+
function validateSource(source) {
|
|
83
|
+
if (!/^[\w.-]+\/[\w.-]+$/.test(source)) {
|
|
84
|
+
console.error(`ā Invalid source format: ${source}`);
|
|
85
|
+
console.error("Expected: owner/repo (e.g., cognitedata/dune-skills)");
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Handle `dune skills pull`
|
|
92
|
+
* @param {string[]} args
|
|
93
|
+
*/
|
|
94
|
+
// TODO(DUNE-362): replace manual arg parsing with node:util parseArgs
|
|
95
|
+
function handlePull(args) {
|
|
96
|
+
let source = SKILL_SOURCE;
|
|
97
|
+
let skill_name = null;
|
|
98
|
+
let interactive = false;
|
|
99
|
+
// Flags forwarded verbatim to the skills CLI (e.g. --global)
|
|
100
|
+
const passthrough = [];
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < args.length; i++) {
|
|
103
|
+
const arg = args[i];
|
|
104
|
+
if (arg === "--source") {
|
|
105
|
+
source = args[++i];
|
|
106
|
+
if (!source) {
|
|
107
|
+
console.error("ā --source requires a value (e.g., cognitedata/dune-skills)");
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
validateSource(source);
|
|
111
|
+
} else if (arg === "--skill") {
|
|
112
|
+
skill_name = args[++i];
|
|
113
|
+
if (!skill_name) {
|
|
114
|
+
console.error("ā --skill requires a name");
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
} else if (arg === "--interactive" || arg === "-i") {
|
|
118
|
+
interactive = true;
|
|
119
|
+
} else if (arg === "--global") {
|
|
120
|
+
// --global installs skills into ~/.claude/skills (user-wide) instead of project-local
|
|
121
|
+
passthrough.push(arg);
|
|
122
|
+
} else {
|
|
123
|
+
console.warn(`ā ļø Unknown option: ${arg}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Build the skills CLI invocation:
|
|
128
|
+
// skills add <source> -a claude-code -a cursor [--skill <name> | --skill * -y]
|
|
129
|
+
// See: https://github.com/vercel-labs/skills
|
|
130
|
+
const cliArgs = ["add", source, ...AGENT_FLAGS];
|
|
131
|
+
if (skill_name) {
|
|
132
|
+
cliArgs.push("--skill", skill_name);
|
|
133
|
+
} else if (!interactive) {
|
|
134
|
+
// Pull all skills and auto-confirm (-y / --yes) without interactive prompts
|
|
135
|
+
cliArgs.push("--skill", "*", "-y");
|
|
136
|
+
}
|
|
137
|
+
cliArgs.push(...passthrough);
|
|
138
|
+
|
|
139
|
+
console.log(`š Pulling skills from ${source}...`);
|
|
140
|
+
|
|
141
|
+
runSkillsCli(cliArgs);
|
|
142
|
+
console.log("\nā
Skills pulled successfully");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Handle `dune skills list`
|
|
147
|
+
*/
|
|
148
|
+
function handleList() {
|
|
149
|
+
try {
|
|
150
|
+
runSkillsCli(["list"]);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error("ā Failed to list skills:", error instanceof Error ? error.message : String(error));
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Skills command handler
|
|
159
|
+
* @param {string[]} args
|
|
160
|
+
*/
|
|
161
|
+
export function handleSkillsCommand(args) {
|
|
162
|
+
const subcommand = args[0];
|
|
163
|
+
const subArgs = args.slice(1);
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
switch (subcommand) {
|
|
167
|
+
case undefined:
|
|
168
|
+
case "help":
|
|
169
|
+
case "--help":
|
|
170
|
+
case "-h":
|
|
171
|
+
printHelp();
|
|
172
|
+
break;
|
|
173
|
+
case "pull":
|
|
174
|
+
handlePull(subArgs);
|
|
175
|
+
break;
|
|
176
|
+
case "list":
|
|
177
|
+
handleList();
|
|
178
|
+
break;
|
|
179
|
+
default:
|
|
180
|
+
console.error(`ā Unknown skills command: ${subcommand}`);
|
|
181
|
+
printHelp();
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error("ā Skills command failed:", error.message);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cognite/dune",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Build and deploy React apps to Cognite Data Fusion",
|
|
5
5
|
"keywords": ["cognite", "dune", "cdf", "fusion", "react", "scaffold", "deploy"],
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"bin": {
|
|
42
42
|
"dune": "./bin/cli.js"
|
|
43
43
|
},
|
|
44
|
-
"files": ["bin/cli.js", "bin/deploy-command.js", "bin/deploy-interactive-command.js", "bin/auth", "bin/utils", "dist", "src", "_templates"],
|
|
44
|
+
"files": ["bin/cli.js", "bin/deploy-command.js", "bin/deploy-interactive-command.js", "bin/skills-command.js", "bin/auth", "bin/utils", "dist", "src", "_templates"],
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsup",
|
|
47
47
|
"prepare": "tsup",
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
"enquirer": "^2.4.1",
|
|
56
56
|
"execa": "^5.1.1",
|
|
57
57
|
"hygen": "^6.2.11",
|
|
58
|
-
"open": "^10.1.0"
|
|
58
|
+
"open": "^10.1.0",
|
|
59
|
+
"skills": "^1.4.3"
|
|
59
60
|
},
|
|
60
61
|
"peerDependencies": {
|
|
61
62
|
"@cognite/sdk": ">=9.0.0",
|