@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 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.2.7",
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",