@cognite/dune 0.2.3 → 0.3.0

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.
@@ -17,12 +17,12 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
17
17
  "test:ui": "vitest --ui",
18
18
  "lint": "biome check .",
19
19
  "lint:fix": "biome check --write .",
20
- "deploy": "pnpm run build && echo 'Deploying...' && echo 'Deployed!'",
21
- "deploy-preview": "pnpm run build && echo 'Deploying preview...' && echo 'Deployed preview!'"
20
+ "deploy": "dune deploy:interactive --published",
21
+ "deploy-preview": "dune deploy:interactive"
22
22
  },
23
23
  "dependencies": {
24
24
  "@cognite/sdk": "^10.3.0",
25
- "@cognite/dune": "^0.2.2",
25
+ "@cognite/dune": "^0.2.4",
26
26
  "@tanstack/react-query": "^5.90.10",
27
27
  "clsx": "^2.1.1",
28
28
  "react": "^19.2.0",
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,171 @@
1
+ /**
2
+ * Skills Command
3
+ *
4
+ * Manages AI agent skills for Dune apps. Uses the `skills` package (bundled
5
+ * dependency) for pull 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
+ help Show this help message
46
+
47
+ Options for pull:
48
+ --source <owner/repo> Skills repository (default: ${SKILL_SOURCE})
49
+ --skill <name> Pull a specific skill by name
50
+ --interactive, -i Interactively select which skills to install
51
+ --global Install skills globally
52
+
53
+ Examples:
54
+ npx @cognite/dune skills pull # Pull all skills
55
+ npx @cognite/dune skills pull --skill create-client-tool
56
+ `);
57
+ }
58
+
59
+ /**
60
+ * Build the default CLI args for pulling all skills.
61
+ *
62
+ * Invokes: skills add <source> -a claude-code -a cursor --skill '*' -y
63
+ * - "add" : skills CLI subcommand that fetches and installs skills
64
+ * - SKILL_SOURCE : GitHub owner/repo hosting the skill definitions
65
+ * - AGENT_FLAGS : install for every supported AI agent (-a claude-code -a cursor)
66
+ * - --skill '*' : wildcard — pull every available skill
67
+ * - -y : auto-confirm all prompts (non-interactive / --yes)
68
+ *
69
+ * See: https://github.com/vercel-labs/skills
70
+ * @returns {string[]}
71
+ */
72
+ export function defaultPullArgs() {
73
+ return ["add", SKILL_SOURCE, ...AGENT_FLAGS, "--skill", "*", "-y"];
74
+ }
75
+
76
+ /**
77
+ * Validate that a source string matches owner/repo format.
78
+ * @param {string} source
79
+ */
80
+ function validateSource(source) {
81
+ if (!/^[\w.-]+\/[\w.-]+$/.test(source)) {
82
+ console.error(`āŒ Invalid source format: ${source}`);
83
+ console.error("Expected: owner/repo (e.g., cognitedata/dune-skills)");
84
+ process.exit(1);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Handle `dune skills pull`
90
+ * @param {string[]} args
91
+ */
92
+ // TODO(DUNE-362): replace manual arg parsing with node:util parseArgs
93
+ function handlePull(args) {
94
+ let source = SKILL_SOURCE;
95
+ let skill_name = null;
96
+ let interactive = false;
97
+ // Flags forwarded verbatim to the skills CLI (e.g. --global)
98
+ const passthrough = [];
99
+
100
+ for (let i = 0; i < args.length; i++) {
101
+ const arg = args[i];
102
+ if (arg === "--source") {
103
+ source = args[++i];
104
+ if (!source) {
105
+ console.error("āŒ --source requires a value (e.g., cognitedata/dune-skills)");
106
+ process.exit(1);
107
+ }
108
+ validateSource(source);
109
+ } else if (arg === "--skill") {
110
+ skill_name = args[++i];
111
+ if (!skill_name) {
112
+ console.error("āŒ --skill requires a name");
113
+ process.exit(1);
114
+ }
115
+ } else if (arg === "--interactive" || arg === "-i") {
116
+ interactive = true;
117
+ } else if (arg === "--global") {
118
+ // --global installs skills into ~/.claude/skills (user-wide) instead of project-local
119
+ passthrough.push(arg);
120
+ } else {
121
+ console.warn(`āš ļø Unknown option: ${arg}`);
122
+ }
123
+ }
124
+
125
+ // Build the skills CLI invocation:
126
+ // skills add <source> -a claude-code -a cursor [--skill <name> | --skill * -y]
127
+ // See: https://github.com/vercel-labs/skills
128
+ const cliArgs = ["add", source, ...AGENT_FLAGS];
129
+ if (skill_name) {
130
+ cliArgs.push("--skill", skill_name);
131
+ } else if (!interactive) {
132
+ // Pull all skills and auto-confirm (-y / --yes) without interactive prompts
133
+ cliArgs.push("--skill", "*", "-y");
134
+ }
135
+ cliArgs.push(...passthrough);
136
+
137
+ console.log(`šŸ”„ Pulling skills from ${source}...`);
138
+
139
+ runSkillsCli(cliArgs);
140
+ console.log("\nāœ… Skills pulled successfully");
141
+ }
142
+
143
+ /**
144
+ * Skills command handler
145
+ * @param {string[]} args
146
+ */
147
+ export function handleSkillsCommand(args) {
148
+ const subcommand = args[0];
149
+ const subArgs = args.slice(1);
150
+
151
+ try {
152
+ switch (subcommand) {
153
+ case undefined:
154
+ case "help":
155
+ case "--help":
156
+ case "-h":
157
+ printHelp();
158
+ break;
159
+ case "pull":
160
+ handlePull(subArgs);
161
+ break;
162
+ default:
163
+ console.error(`āŒ Unknown skills command: ${subcommand}`);
164
+ printHelp();
165
+ process.exit(1);
166
+ }
167
+ } catch (error) {
168
+ console.error("āŒ Skills command failed:", error.message);
169
+ process.exit(1);
170
+ }
171
+ }
package/package.json CHANGED
@@ -1,16 +1,8 @@
1
1
  {
2
2
  "name": "@cognite/dune",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Build and deploy React apps to Cognite Data Fusion",
5
- "keywords": [
6
- "cognite",
7
- "dune",
8
- "cdf",
9
- "fusion",
10
- "react",
11
- "scaffold",
12
- "deploy"
13
- ],
5
+ "keywords": ["cognite", "dune", "cdf", "fusion", "react", "scaffold", "deploy"],
14
6
  "license": "Apache-2.0",
15
7
  "author": "Cognite",
16
8
  "repository": {
@@ -49,22 +41,22 @@
49
41
  "bin": {
50
42
  "dune": "./bin/cli.js"
51
43
  },
52
- "files": [
53
- "bin/cli.js",
54
- "bin/deploy-command.js",
55
- "bin/deploy-interactive-command.js",
56
- "bin/auth",
57
- "bin/utils",
58
- "dist",
59
- "src",
60
- "_templates"
61
- ],
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
+ "scripts": {
46
+ "build": "tsup",
47
+ "prepare": "tsup",
48
+ "prepack": "pnpm run build",
49
+ "prepublishOnly": "pnpm run build",
50
+ "test": "vitest run",
51
+ "test:watch": "vitest"
52
+ },
62
53
  "dependencies": {
63
54
  "archiver": "^7.0.1",
64
55
  "enquirer": "^2.4.1",
65
56
  "execa": "^5.1.1",
66
57
  "hygen": "^6.2.11",
67
- "open": "^10.1.0"
58
+ "open": "^10.1.0",
59
+ "skills": "^1.4.3"
68
60
  },
69
61
  "peerDependencies": {
70
62
  "@cognite/sdk": ">=9.0.0",
@@ -96,10 +88,5 @@
96
88
  },
97
89
  "engines": {
98
90
  "node": ">=18"
99
- },
100
- "scripts": {
101
- "build": "tsup",
102
- "test": "vitest run",
103
- "test:watch": "vitest"
104
91
  }
105
- }
92
+ }