@cognite/dune 0.3.1 → 0.3.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.
Files changed (52) hide show
  1. package/_templates/app/new/config/eslint.config.mjs.ejs.t +96 -0
  2. package/_templates/app/new/config/tailwind.config.js.ejs.t +1 -5
  3. package/_templates/app/new/config/vite.config.ts.ejs.t +9 -10
  4. package/_templates/app/new/config/vitest.config.ts.ejs.t +4 -5
  5. package/_templates/app/new/config/vitest.setup.ts.ejs.t +1 -2
  6. package/_templates/app/new/cursor/mcp.json.ejs.t +0 -5
  7. package/_templates/app/new/cursor/rules.mdc.ejs.t +1 -2
  8. package/_templates/app/new/prompt.js +29 -29
  9. package/_templates/app/new/root/index.html.ejs.t +3 -3
  10. package/_templates/app/new/root/package.json.ejs.t +11 -5
  11. package/_templates/app/new/src/App.test.tsx.ejs.t +32 -20
  12. package/_templates/app/new/src/App.tsx.ejs.t +118 -7
  13. package/_templates/app/new/src/lib/utils.ts.ejs.t +2 -3
  14. package/_templates/app/new/src/main.tsx.ejs.t +8 -8
  15. package/_templates/app/new/src/styles.css.ejs.t +5 -19
  16. package/bin/auth/authentication-flow.js +16 -14
  17. package/bin/auth/callback-server.js +23 -23
  18. package/bin/auth/certificate-manager.js +13 -13
  19. package/bin/auth/client-credentials.js +31 -32
  20. package/bin/auth/oauth-client.js +7 -7
  21. package/bin/cli.js +31 -30
  22. package/bin/deploy-command.js +32 -32
  23. package/bin/deploy-interactive-command.js +73 -73
  24. package/bin/skills-command.js +28 -28
  25. package/bin/utils/crypto.js +7 -8
  26. package/dist/auth/index.d.ts +10 -13
  27. package/dist/auth/index.js +1 -1
  28. package/dist/{chunk-VIBN7U5H.js → chunk-53VTKDSC.js} +1 -2
  29. package/dist/deploy/index.d.ts +9 -1
  30. package/dist/deploy/index.js +89 -7
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +1 -1
  33. package/dist/vite/index.d.ts +1 -0
  34. package/dist/vite/index.js +5 -2
  35. package/package.json +1 -1
  36. package/src/auth/dune-auth-provider.tsx +17 -16
  37. package/src/auth/index.ts +5 -5
  38. package/src/auth/use-dune.ts +5 -4
  39. package/src/auth/utils.ts +18 -18
  40. package/src/deploy/application-deployer.ts +12 -11
  41. package/src/deploy/application-packager.ts +11 -10
  42. package/src/deploy/deploy.ts +7 -6
  43. package/src/deploy/get-sdk.ts +5 -4
  44. package/src/deploy/index.ts +6 -6
  45. package/src/deploy/login.test.ts +49 -0
  46. package/src/deploy/login.ts +134 -11
  47. package/src/deploy/types.ts +4 -0
  48. package/src/index.ts +1 -1
  49. package/src/vite/fusion-open-plugin.ts +17 -15
  50. package/src/vite/index.ts +1 -1
  51. package/_templates/app/new/config/biome.json.ejs.t +0 -54
  52. package/_templates/app/new/config/components.json.ejs.t +0 -28
@@ -1,13 +1,13 @@
1
- import { execSync } from "node:child_process";
2
- import { existsSync, readFileSync, unlinkSync } from "node:fs";
3
- import { resolve } from "node:path";
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { resolve } from 'node:path';
4
4
 
5
5
  /**
6
6
  * Generate Fusion app URL
7
7
  */
8
8
  function generateFusionUrl(deployment, appExternalId, versionTag) {
9
9
  const { org, project, baseUrl } = deployment;
10
- const cluster = baseUrl?.split("//")[1];
10
+ const cluster = baseUrl?.split('//')[1];
11
11
 
12
12
  if (!org || !project || !cluster) {
13
13
  return null;
@@ -20,12 +20,12 @@ function generateFusionUrl(deployment, appExternalId, versionTag) {
20
20
  * Load app.json from a directory
21
21
  */
22
22
  function loadAppConfig(appDir) {
23
- const configPath = resolve(appDir, "app.json");
23
+ const configPath = resolve(appDir, 'app.json');
24
24
  if (!existsSync(configPath)) {
25
25
  return null;
26
26
  }
27
27
  try {
28
- return JSON.parse(readFileSync(configPath, "utf-8"));
28
+ return JSON.parse(readFileSync(configPath, 'utf-8'));
29
29
  } catch (error) {
30
30
  console.error(`Error parsing app.json: ${error.message}`);
31
31
  return null;
@@ -36,19 +36,19 @@ function loadAppConfig(appDir) {
36
36
  * Load .env file from a directory
37
37
  */
38
38
  function loadEnvFile(dir) {
39
- const envPath = resolve(dir, ".env");
39
+ const envPath = resolve(dir, '.env');
40
40
  if (existsSync(envPath)) {
41
41
  console.log(`Loading environment variables from ${envPath}`);
42
- const envContent = readFileSync(envPath, "utf-8");
43
- envContent.split("\n").forEach((line) => {
42
+ const envContent = readFileSync(envPath, 'utf-8');
43
+ envContent.split('\n').forEach((line) => {
44
44
  const trimmedLine = line.trim();
45
- if (!trimmedLine || trimmedLine.startsWith("#")) {
45
+ if (!trimmedLine || trimmedLine.startsWith('#')) {
46
46
  return;
47
47
  }
48
48
  const match = trimmedLine.match(/^([^=]+)=(.*)$/);
49
49
  if (match) {
50
50
  const key = match[1].trim();
51
- const value = match[2].trim().replace(/^["']|["']$/g, "");
51
+ const value = match[2].trim().replace(/^["']|["']$/g, '');
52
52
  process.env[key] = value;
53
53
  }
54
54
  });
@@ -59,10 +59,10 @@ function loadEnvFile(dir) {
59
59
  * Detect the package manager being used
60
60
  */
61
61
  function detectPackageManager(appDir) {
62
- if (existsSync(resolve(appDir, "pnpm-lock.yaml"))) return "pnpm";
63
- if (existsSync(resolve(appDir, "yarn.lock"))) return "yarn";
64
- if (existsSync(resolve(appDir, "bun.lockb"))) return "bun";
65
- return "npm";
62
+ if (existsSync(resolve(appDir, 'pnpm-lock.yaml'))) return 'pnpm';
63
+ if (existsSync(resolve(appDir, 'yarn.lock'))) return 'yarn';
64
+ if (existsSync(resolve(appDir, 'bun.lockb'))) return 'bun';
65
+ return 'npm';
66
66
  }
67
67
 
68
68
  /**
@@ -74,10 +74,10 @@ function buildApp(appDir, verbose = true) {
74
74
 
75
75
  execSync(`${pm} run build`, {
76
76
  cwd: appDir,
77
- stdio: verbose ? "inherit" : "pipe",
77
+ stdio: verbose ? 'inherit' : 'pipe',
78
78
  });
79
79
 
80
- console.log("āœ… Build successful");
80
+ console.log('āœ… Build successful');
81
81
  }
82
82
 
83
83
  /**
@@ -113,7 +113,7 @@ Examples:
113
113
  */
114
114
  export async function handleDeploy(args) {
115
115
  // Check for help first, before any other operations
116
- if (args.includes("--help") || args.includes("-h")) {
116
+ if (args.includes('--help') || args.includes('-h')) {
117
117
  printHelp();
118
118
  process.exit(0);
119
119
  }
@@ -126,13 +126,13 @@ export async function handleDeploy(args) {
126
126
  // Load app.json
127
127
  const appConfig = loadAppConfig(cwd);
128
128
  if (!appConfig) {
129
- console.error("āŒ No app.json found in current directory");
129
+ console.error('āŒ No app.json found in current directory');
130
130
  console.error("Make sure you're running this command from your app's root directory.");
131
131
  process.exit(1);
132
132
  }
133
133
 
134
134
  if (!appConfig.deployments || appConfig.deployments.length === 0) {
135
- console.error("āŒ No deployments configured in app.json");
135
+ console.error('āŒ No deployments configured in app.json');
136
136
  process.exit(1);
137
137
  }
138
138
 
@@ -142,10 +142,10 @@ export async function handleDeploy(args) {
142
142
 
143
143
  for (let i = 0; i < args.length; i++) {
144
144
  const arg = args[i];
145
- if (arg === "--deployment" || arg === "-d") {
145
+ if (arg === '--deployment' || arg === '-d') {
146
146
  const value = args[++i];
147
147
  if (value === undefined) {
148
- console.error("āŒ --deployment requires a value (index or project name)");
148
+ console.error('āŒ --deployment requires a value (index or project name)');
149
149
  process.exit(1);
150
150
  }
151
151
  // Try to parse as index first
@@ -159,7 +159,7 @@ export async function handleDeploy(args) {
159
159
  );
160
160
  if (found === -1) {
161
161
  console.error(`āŒ No deployment found for project: ${value}`);
162
- console.log("Available deployments:");
162
+ console.log('Available deployments:');
163
163
  appConfig.deployments.forEach((d, i) => {
164
164
  console.log(` ${i}: ${d.org}/${d.project}`);
165
165
  });
@@ -167,7 +167,7 @@ export async function handleDeploy(args) {
167
167
  }
168
168
  deploymentIndex = found;
169
169
  }
170
- } else if (arg === "--skip-build") {
170
+ } else if (arg === '--skip-build') {
171
171
  skipBuild = true;
172
172
  }
173
173
  }
@@ -184,8 +184,8 @@ export async function handleDeploy(args) {
184
184
 
185
185
  const deployment = appConfig.deployments[deploymentIndex];
186
186
 
187
- console.log("\nšŸš€ Dune Deploy");
188
- console.log("================");
187
+ console.log('\nšŸš€ Dune Deploy');
188
+ console.log('================');
189
189
  console.log(`App: ${appConfig.name} (${appConfig.externalId})`);
190
190
  console.log(`Version: ${appConfig.versionTag}`);
191
191
  console.log(`Target: ${deployment.org}/${deployment.project}`);
@@ -196,14 +196,14 @@ export async function handleDeploy(args) {
196
196
  try {
197
197
  buildApp(cwd);
198
198
  } catch (error) {
199
- console.error("āŒ Build failed:", error.message);
199
+ console.error('āŒ Build failed:', error.message);
200
200
  process.exit(1);
201
201
  }
202
202
  }
203
203
 
204
204
  // Import deploy function and deploy
205
205
  try {
206
- const { deploy } = await import("../dist/deploy/index.js");
206
+ const { deploy } = await import('../dist/deploy/index.js');
207
207
 
208
208
  console.log(`\nšŸ“¤ Deploying to ${deployment.org}/${deployment.project}...`);
209
209
 
@@ -223,9 +223,9 @@ export async function handleDeploy(args) {
223
223
  );
224
224
 
225
225
  if (deployment.published) {
226
- console.log("🌐 App is published and available to all users");
226
+ console.log('🌐 App is published and available to all users');
227
227
  } else {
228
- console.log("šŸ”’ App is deployed in draft mode");
228
+ console.log('šŸ”’ App is deployed in draft mode');
229
229
  }
230
230
 
231
231
  // Generate and display the app URL
@@ -236,8 +236,8 @@ export async function handleDeploy(args) {
236
236
 
237
237
  process.exit(0);
238
238
  } catch (error) {
239
- console.error("\nāŒ Deployment failed:", error.message);
240
- if (error.message.includes("secret not found")) {
239
+ console.error('\nāŒ Deployment failed:', error.message);
240
+ if (error.message.includes('secret not found')) {
241
241
  console.log(`\nMake sure the environment variable "${deployment.deploySecretName}" is set.`);
242
242
  console.log("You can set it in a .env file in your app's root directory.");
243
243
  }
@@ -4,19 +4,19 @@
4
4
  * Handles deployment with browser-based OAuth login instead of environment variables.
5
5
  */
6
6
 
7
- import { execSync } from "node:child_process";
8
- import { existsSync, readFileSync, unlinkSync } from "node:fs";
9
- import os from "node:os";
10
- import path from "node:path";
11
- import { resolve } from "node:path";
12
- import { AuthenticationFlow } from "./auth/authentication-flow.js";
7
+ import { execSync } from 'node:child_process';
8
+ import { existsSync, readFileSync, unlinkSync } from 'node:fs';
9
+ import os from 'node:os';
10
+ import path, { resolve } from 'node:path';
11
+
12
+ import { AuthenticationFlow } from './auth/authentication-flow.js';
13
13
 
14
14
  /**
15
15
  * Generate Fusion app URL
16
16
  */
17
17
  function generateFusionUrl(deployment, appExternalId, versionTag) {
18
18
  const { org, project, baseUrl } = deployment;
19
- const cluster = baseUrl?.split("//")[1];
19
+ const cluster = baseUrl?.split('//')[1];
20
20
 
21
21
  if (!org || !project || !cluster) {
22
22
  return null;
@@ -27,24 +27,24 @@ function generateFusionUrl(deployment, appExternalId, versionTag) {
27
27
 
28
28
  // Default OAuth configuration for CDF
29
29
  const DEFAULT_CONFIG = {
30
- authority: "https://auth.cognite.com",
31
- clientId: "c6f97d29-79a5-48ac-85de-1de8229226cb", // CDF CLI public client ID
32
- redirectUri: "https://localhost:3000",
30
+ authority: 'https://auth.cognite.com',
31
+ clientId: 'c6f97d29-79a5-48ac-85de-1de8229226cb', // CDF CLI public client ID
32
+ redirectUri: 'https://localhost:3000',
33
33
  port: 3000,
34
34
  loginTimeout: 5 * 60 * 1000, // 5 minutes
35
- certDir: path.join(os.homedir(), ".cdf-login"),
35
+ certDir: path.join(os.homedir(), '.cdf-login'),
36
36
  };
37
37
 
38
38
  /**
39
39
  * Load app.json from a directory
40
40
  */
41
41
  function loadAppConfig(appDir) {
42
- const configPath = resolve(appDir, "app.json");
42
+ const configPath = resolve(appDir, 'app.json');
43
43
  if (!existsSync(configPath)) {
44
44
  return null;
45
45
  }
46
46
  try {
47
- return JSON.parse(readFileSync(configPath, "utf-8"));
47
+ return JSON.parse(readFileSync(configPath, 'utf-8'));
48
48
  } catch (error) {
49
49
  console.error(`Error parsing app.json: ${error.message}`);
50
50
  return null;
@@ -55,10 +55,10 @@ function loadAppConfig(appDir) {
55
55
  * Detect the package manager being used
56
56
  */
57
57
  function detectPackageManager(appDir) {
58
- if (existsSync(resolve(appDir, "pnpm-lock.yaml"))) return "pnpm";
59
- if (existsSync(resolve(appDir, "yarn.lock"))) return "yarn";
60
- if (existsSync(resolve(appDir, "bun.lockb"))) return "bun";
61
- return "npm";
58
+ if (existsSync(resolve(appDir, 'pnpm-lock.yaml'))) return 'pnpm';
59
+ if (existsSync(resolve(appDir, 'yarn.lock'))) return 'yarn';
60
+ if (existsSync(resolve(appDir, 'bun.lockb'))) return 'bun';
61
+ return 'npm';
62
62
  }
63
63
 
64
64
  /**
@@ -70,10 +70,10 @@ function buildApp(appDir, verbose = true) {
70
70
 
71
71
  execSync(`${pm} run build`, {
72
72
  cwd: appDir,
73
- stdio: verbose ? "inherit" : "pipe",
73
+ stdio: verbose ? 'inherit' : 'pipe',
74
74
  });
75
75
 
76
- console.log("āœ… Build successful");
76
+ console.log('āœ… Build successful');
77
77
  }
78
78
 
79
79
  /**
@@ -115,7 +115,7 @@ Examples:
115
115
  */
116
116
  export async function handleDeployInteractive(args) {
117
117
  // Check for help first
118
- if (args.includes("--help") || args.includes("-h")) {
118
+ if (args.includes('--help') || args.includes('-h')) {
119
119
  printHelp();
120
120
  process.exit(0);
121
121
  }
@@ -125,7 +125,7 @@ export async function handleDeployInteractive(args) {
125
125
  // Load app.json
126
126
  const appConfig = loadAppConfig(cwd);
127
127
  if (!appConfig) {
128
- console.error("āŒ No app.json found in current directory");
128
+ console.error('āŒ No app.json found in current directory');
129
129
  console.error("Make sure you're running this command from your app's root directory.");
130
130
  process.exit(1);
131
131
  }
@@ -140,16 +140,16 @@ export async function handleDeployInteractive(args) {
140
140
 
141
141
  for (let i = 0; i < args.length; i++) {
142
142
  const arg = args[i];
143
- if (arg === "--base-url") {
143
+ if (arg === '--base-url') {
144
144
  baseUrl = args[++i];
145
- } else if (arg === "--project") {
145
+ } else if (arg === '--project') {
146
146
  project = args[++i];
147
- } else if (arg === "--org") {
147
+ } else if (arg === '--org') {
148
148
  organization = args[++i];
149
- } else if (arg === "--deployment" || arg === "-d") {
149
+ } else if (arg === '--deployment' || arg === '-d') {
150
150
  const value = args[++i];
151
151
  if (value === undefined) {
152
- console.error("āŒ --deployment requires a value (index or project name)");
152
+ console.error('āŒ --deployment requires a value (index or project name)');
153
153
  process.exit(1);
154
154
  }
155
155
  const idx = Number.parseInt(value, 10);
@@ -161,7 +161,7 @@ export async function handleDeployInteractive(args) {
161
161
  );
162
162
  if (found === -1) {
163
163
  console.error(`āŒ No deployment found for project: ${value}`);
164
- console.log("Available deployments:");
164
+ console.log('Available deployments:');
165
165
  appConfig.deployments.forEach((d, i) => {
166
166
  console.log(` ${i}: ${d.org}/${d.project}`);
167
167
  });
@@ -169,23 +169,23 @@ export async function handleDeployInteractive(args) {
169
169
  }
170
170
  deploymentIndex = found;
171
171
  }
172
- } else if (arg === "--skip-build") {
172
+ } else if (arg === '--skip-build') {
173
173
  skipBuild = true;
174
- } else if (arg === "--published") {
174
+ } else if (arg === '--published') {
175
175
  published = true;
176
176
  }
177
177
  }
178
178
 
179
179
  // Determine deployment target
180
180
  let deployment;
181
- const enquirer = await import("enquirer");
181
+ const enquirer = await import('enquirer');
182
182
 
183
183
  if (baseUrl && project) {
184
184
  // Use CLI-provided values
185
185
  deployment = {
186
186
  baseUrl,
187
187
  project,
188
- org: organization || "unknown",
188
+ org: organization || 'unknown',
189
189
  published,
190
190
  };
191
191
  } else if (deploymentIndex !== null) {
@@ -209,34 +209,34 @@ export async function handleDeployInteractive(args) {
209
209
  // Prompt user to select from existing deployments or enter custom
210
210
  const choices = [
211
211
  ...appConfig.deployments.map((d) => `${d.org}/${d.project}`),
212
- "Enter custom target...",
212
+ 'Enter custom target...',
213
213
  ];
214
214
 
215
215
  const { selected } = await enquirer.default.prompt({
216
- type: "select",
217
- name: "selected",
218
- message: "Select deployment target",
216
+ type: 'select',
217
+ name: 'selected',
218
+ message: 'Select deployment target',
219
219
  choices,
220
220
  });
221
221
 
222
- if (selected === "Enter custom target...") {
222
+ if (selected === 'Enter custom target...') {
223
223
  const answers = await enquirer.default.prompt([
224
224
  {
225
- type: "input",
226
- name: "baseUrl",
227
- message: "CDF Base URL",
228
- initial: "https://api.cognitedata.com",
225
+ type: 'input',
226
+ name: 'baseUrl',
227
+ message: 'CDF Base URL',
228
+ initial: 'https://api.cognitedata.com',
229
229
  },
230
230
  {
231
- type: "input",
232
- name: "project",
233
- message: "CDF Project",
231
+ type: 'input',
232
+ name: 'project',
233
+ message: 'CDF Project',
234
234
  },
235
235
  {
236
- type: "input",
237
- name: "org",
238
- message: "Organization (for login hint)",
239
- initial: "",
236
+ type: 'input',
237
+ name: 'org',
238
+ message: 'Organization (for login hint)',
239
+ initial: '',
240
240
  },
241
241
  ]);
242
242
  deployment = {
@@ -254,26 +254,26 @@ export async function handleDeployInteractive(args) {
254
254
  }
255
255
  } else {
256
256
  // No deployments in app.json - prompt for values
257
- console.log("No deployments configured in app.json. Enter target details:\n");
257
+ console.log('No deployments configured in app.json. Enter target details:\n');
258
258
 
259
259
  const answers = await enquirer.default.prompt([
260
260
  {
261
- type: "input",
262
- name: "baseUrl",
263
- message: "CDF Base URL",
264
- initial: "https://api.cognitedata.com",
261
+ type: 'input',
262
+ name: 'baseUrl',
263
+ message: 'CDF Base URL',
264
+ initial: 'https://api.cognitedata.com',
265
265
  },
266
266
  {
267
- type: "input",
268
- name: "project",
269
- message: "CDF Project",
270
- validate: (v) => (v ? true : "Project is required"),
267
+ type: 'input',
268
+ name: 'project',
269
+ message: 'CDF Project',
270
+ validate: (v) => (v ? true : 'Project is required'),
271
271
  },
272
272
  {
273
- type: "input",
274
- name: "org",
275
- message: "Organization (for login hint)",
276
- initial: "",
273
+ type: 'input',
274
+ name: 'org',
275
+ message: 'Organization (for login hint)',
276
+ initial: '',
277
277
  },
278
278
  ]);
279
279
 
@@ -288,8 +288,8 @@ export async function handleDeployInteractive(args) {
288
288
  }
289
289
  }
290
290
 
291
- console.log("\nšŸš€ Dune Deploy (Interactive)");
292
- console.log("=============================");
291
+ console.log('\nšŸš€ Dune Deploy (Interactive)');
292
+ console.log('=============================');
293
293
  console.log(`App: ${appConfig.name} (${appConfig.externalId})`);
294
294
  console.log(`Version: ${appConfig.versionTag}`);
295
295
  console.log(`Target: ${deployment.project} @ ${deployment.baseUrl}`);
@@ -300,7 +300,7 @@ export async function handleDeployInteractive(args) {
300
300
  try {
301
301
  buildApp(cwd);
302
302
  } catch (error) {
303
- console.error("āŒ Build failed:", error.message);
303
+ console.error('āŒ Build failed:', error.message);
304
304
  process.exit(1);
305
305
  }
306
306
  }
@@ -312,21 +312,21 @@ export async function handleDeployInteractive(args) {
312
312
  // Use org from CLI, then deployment, then null
313
313
  const orgHint = organization || deployment.org || null;
314
314
 
315
- console.log("\nšŸ” Starting browser authentication...");
316
- console.log("A browser window will open for you to log in.\n");
315
+ console.log('\nšŸ” Starting browser authentication...');
316
+ console.log('A browser window will open for you to log in.\n');
317
317
 
318
318
  const tokens = await authFlow.login(orgHint);
319
319
 
320
320
  if (!tokens || !tokens.access_token) {
321
- throw new Error("No access token received from authentication");
321
+ throw new Error('No access token received from authentication');
322
322
  }
323
323
 
324
- console.log("\nāœ… Authentication successful!");
324
+ console.log('\nāœ… Authentication successful!');
325
325
  console.log(`\nšŸ“¤ Deploying to ${deployment.project}...`);
326
326
 
327
327
  // Import CogniteClient and deployer classes
328
- const { CogniteClient } = await import("@cognite/sdk");
329
- const { CdfApplicationDeployer, ApplicationPackager } = await import("../dist/deploy/index.js");
328
+ const { CogniteClient } = await import('@cognite/sdk');
329
+ const { CdfApplicationDeployer, ApplicationPackager } = await import('../dist/deploy/index.js');
330
330
 
331
331
  // Create SDK with the obtained token
332
332
  const sdk = new CogniteClient({
@@ -340,7 +340,7 @@ export async function handleDeployInteractive(args) {
340
340
  // Package the application
341
341
  const distPath = `${cwd}/dist`;
342
342
  const packager = new ApplicationPackager(distPath);
343
- const zipFilename = await packager.createZip("app.zip", true);
343
+ const zipFilename = await packager.createZip('app.zip', true);
344
344
 
345
345
  // Deploy to CDF
346
346
  const deployer = new CdfApplicationDeployer(sdk);
@@ -363,9 +363,9 @@ export async function handleDeployInteractive(args) {
363
363
  console.log(`\nāœ… Successfully deployed ${appConfig.name} to ${deployment.project}`);
364
364
 
365
365
  if (deployment.published || published) {
366
- console.log("🌐 App is published and available to all users");
366
+ console.log('🌐 App is published and available to all users');
367
367
  } else {
368
- console.log("šŸ”’ App is deployed in draft mode");
368
+ console.log('šŸ”’ App is deployed in draft mode');
369
369
  }
370
370
 
371
371
  // Generate and display the app URL
@@ -376,7 +376,7 @@ export async function handleDeployInteractive(args) {
376
376
 
377
377
  process.exit(0);
378
378
  } catch (error) {
379
- console.error("\nāŒ Deployment failed:", error.message);
379
+ console.error('\nāŒ Deployment failed:', error.message);
380
380
  process.exit(1);
381
381
  }
382
382
  }
@@ -5,12 +5,12 @@
5
5
  * dependency) for pull/list operations.
6
6
  */
7
7
 
8
- import { execFileSync } from "node:child_process";
9
- import { createRequire } from "node:module";
8
+ import { execFileSync } from 'node:child_process';
9
+ import { createRequire } from 'node:module';
10
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]);
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
14
 
15
15
  const require = createRequire(import.meta.url);
16
16
 
@@ -20,9 +20,9 @@ const require = createRequire(import.meta.url);
20
20
  * @param {import('child_process').ExecFileSyncOptions} [options]
21
21
  */
22
22
  export function runSkillsCli(args, options = {}) {
23
- const bin = require.resolve("skills/bin/cli.mjs");
23
+ const bin = require.resolve('skills/bin/cli.mjs');
24
24
  execFileSync(process.execPath, [bin, ...args], {
25
- stdio: "inherit",
25
+ stdio: 'inherit',
26
26
  cwd: process.cwd(),
27
27
  ...options,
28
28
  });
@@ -35,7 +35,7 @@ function printHelp() {
35
35
  console.log(`
36
36
  🧠 Dune Skills — Manage AI agent skills for your Dune app
37
37
 
38
- Installs skills for: ${SUPPORTED_AGENTS.join(", ")}
38
+ Installs skills for: ${SUPPORTED_AGENTS.join(', ')}
39
39
 
40
40
  Usage:
41
41
  npx @cognite/dune skills <command> [options]
@@ -72,7 +72,7 @@ Examples:
72
72
  * @returns {string[]}
73
73
  */
74
74
  export function defaultPullArgs() {
75
- return ["add", SKILL_SOURCE, ...AGENT_FLAGS, "--skill", "*", "-y"];
75
+ return ['add', SKILL_SOURCE, ...AGENT_FLAGS, '--skill', '*', '-y'];
76
76
  }
77
77
 
78
78
  /**
@@ -82,7 +82,7 @@ export function defaultPullArgs() {
82
82
  function validateSource(source) {
83
83
  if (!/^[\w.-]+\/[\w.-]+$/.test(source)) {
84
84
  console.error(`āŒ Invalid source format: ${source}`);
85
- console.error("Expected: owner/repo (e.g., cognitedata/dune-skills)");
85
+ console.error('Expected: owner/repo (e.g., cognitedata/dune-skills)');
86
86
  process.exit(1);
87
87
  }
88
88
  }
@@ -101,22 +101,22 @@ function handlePull(args) {
101
101
 
102
102
  for (let i = 0; i < args.length; i++) {
103
103
  const arg = args[i];
104
- if (arg === "--source") {
104
+ if (arg === '--source') {
105
105
  source = args[++i];
106
106
  if (!source) {
107
- console.error("āŒ --source requires a value (e.g., cognitedata/dune-skills)");
107
+ console.error('āŒ --source requires a value (e.g., cognitedata/dune-skills)');
108
108
  process.exit(1);
109
109
  }
110
110
  validateSource(source);
111
- } else if (arg === "--skill") {
111
+ } else if (arg === '--skill') {
112
112
  skill_name = args[++i];
113
113
  if (!skill_name) {
114
- console.error("āŒ --skill requires a name");
114
+ console.error('āŒ --skill requires a name');
115
115
  process.exit(1);
116
116
  }
117
- } else if (arg === "--interactive" || arg === "-i") {
117
+ } else if (arg === '--interactive' || arg === '-i') {
118
118
  interactive = true;
119
- } else if (arg === "--global") {
119
+ } else if (arg === '--global') {
120
120
  // --global installs skills into ~/.claude/skills (user-wide) instead of project-local
121
121
  passthrough.push(arg);
122
122
  } else {
@@ -127,19 +127,19 @@ function handlePull(args) {
127
127
  // Build the skills CLI invocation:
128
128
  // skills add <source> -a claude-code -a cursor [--skill <name> | --skill * -y]
129
129
  // See: https://github.com/vercel-labs/skills
130
- const cliArgs = ["add", source, ...AGENT_FLAGS];
130
+ const cliArgs = ['add', source, ...AGENT_FLAGS];
131
131
  if (skill_name) {
132
- cliArgs.push("--skill", skill_name);
132
+ cliArgs.push('--skill', skill_name);
133
133
  } else if (!interactive) {
134
134
  // Pull all skills and auto-confirm (-y / --yes) without interactive prompts
135
- cliArgs.push("--skill", "*", "-y");
135
+ cliArgs.push('--skill', '*', '-y');
136
136
  }
137
137
  cliArgs.push(...passthrough);
138
138
 
139
139
  console.log(`šŸ”„ Pulling skills from ${source}...`);
140
140
 
141
141
  runSkillsCli(cliArgs);
142
- console.log("\nāœ… Skills pulled successfully");
142
+ console.log('\nāœ… Skills pulled successfully');
143
143
  }
144
144
 
145
145
  /**
@@ -147,9 +147,9 @@ function handlePull(args) {
147
147
  */
148
148
  function handleList() {
149
149
  try {
150
- runSkillsCli(["list"]);
150
+ runSkillsCli(['list']);
151
151
  } catch (error) {
152
- console.error("āŒ Failed to list skills:", error instanceof Error ? error.message : String(error));
152
+ console.error('āŒ Failed to list skills:', error instanceof Error ? error.message : String(error));
153
153
  process.exit(1);
154
154
  }
155
155
  }
@@ -165,15 +165,15 @@ export function handleSkillsCommand(args) {
165
165
  try {
166
166
  switch (subcommand) {
167
167
  case undefined:
168
- case "help":
169
- case "--help":
170
- case "-h":
168
+ case 'help':
169
+ case '--help':
170
+ case '-h':
171
171
  printHelp();
172
172
  break;
173
- case "pull":
173
+ case 'pull':
174
174
  handlePull(subArgs);
175
175
  break;
176
- case "list":
176
+ case 'list':
177
177
  handleList();
178
178
  break;
179
179
  default:
@@ -182,7 +182,7 @@ export function handleSkillsCommand(args) {
182
182
  process.exit(1);
183
183
  }
184
184
  } catch (error) {
185
- console.error("āŒ Skills command failed:", error.message);
185
+ console.error('āŒ Skills command failed:', error.message);
186
186
  process.exit(1);
187
187
  }
188
188
  }