@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.
- package/_templates/app/new/config/eslint.config.mjs.ejs.t +96 -0
- package/_templates/app/new/config/tailwind.config.js.ejs.t +1 -5
- package/_templates/app/new/config/vite.config.ts.ejs.t +9 -10
- package/_templates/app/new/config/vitest.config.ts.ejs.t +4 -5
- package/_templates/app/new/config/vitest.setup.ts.ejs.t +1 -2
- package/_templates/app/new/cursor/mcp.json.ejs.t +0 -5
- package/_templates/app/new/cursor/rules.mdc.ejs.t +1 -2
- package/_templates/app/new/prompt.js +29 -29
- package/_templates/app/new/root/index.html.ejs.t +3 -3
- package/_templates/app/new/root/package.json.ejs.t +11 -5
- package/_templates/app/new/src/App.test.tsx.ejs.t +32 -20
- package/_templates/app/new/src/App.tsx.ejs.t +118 -7
- package/_templates/app/new/src/lib/utils.ts.ejs.t +2 -3
- package/_templates/app/new/src/main.tsx.ejs.t +8 -8
- package/_templates/app/new/src/styles.css.ejs.t +5 -19
- package/bin/auth/authentication-flow.js +16 -14
- package/bin/auth/callback-server.js +23 -23
- package/bin/auth/certificate-manager.js +13 -13
- package/bin/auth/client-credentials.js +31 -32
- package/bin/auth/oauth-client.js +7 -7
- package/bin/cli.js +31 -30
- package/bin/deploy-command.js +32 -32
- package/bin/deploy-interactive-command.js +73 -73
- package/bin/skills-command.js +28 -28
- package/bin/utils/crypto.js +7 -8
- package/dist/auth/index.d.ts +10 -13
- package/dist/auth/index.js +1 -1
- package/dist/{chunk-VIBN7U5H.js ā chunk-53VTKDSC.js} +1 -2
- package/dist/deploy/index.d.ts +9 -1
- package/dist/deploy/index.js +89 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +5 -2
- package/package.json +1 -1
- package/src/auth/dune-auth-provider.tsx +17 -16
- package/src/auth/index.ts +5 -5
- package/src/auth/use-dune.ts +5 -4
- package/src/auth/utils.ts +18 -18
- package/src/deploy/application-deployer.ts +12 -11
- package/src/deploy/application-packager.ts +11 -10
- package/src/deploy/deploy.ts +7 -6
- package/src/deploy/get-sdk.ts +5 -4
- package/src/deploy/index.ts +6 -6
- package/src/deploy/login.test.ts +49 -0
- package/src/deploy/login.ts +134 -11
- package/src/deploy/types.ts +4 -0
- package/src/index.ts +1 -1
- package/src/vite/fusion-open-plugin.ts +17 -15
- package/src/vite/index.ts +1 -1
- package/_templates/app/new/config/biome.json.ejs.t +0 -54
- package/_templates/app/new/config/components.json.ejs.t +0 -28
package/bin/deploy-command.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { execSync } from
|
|
2
|
-
import { existsSync, readFileSync
|
|
3
|
-
import { resolve } from
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
43
|
-
envContent.split(
|
|
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,
|
|
63
|
-
if (existsSync(resolve(appDir,
|
|
64
|
-
if (existsSync(resolve(appDir,
|
|
65
|
-
return
|
|
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 ?
|
|
77
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
console.log(
|
|
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(
|
|
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(
|
|
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(
|
|
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 ===
|
|
145
|
+
if (arg === '--deployment' || arg === '-d') {
|
|
146
146
|
const value = args[++i];
|
|
147
147
|
if (value === undefined) {
|
|
148
|
-
console.error(
|
|
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(
|
|
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 ===
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
226
|
+
console.log('š App is published and available to all users');
|
|
227
227
|
} else {
|
|
228
|
-
console.log(
|
|
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(
|
|
240
|
-
if (error.message.includes(
|
|
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
|
|
8
|
-
import { existsSync, readFileSync, unlinkSync } from
|
|
9
|
-
import os from
|
|
10
|
-
import path from
|
|
11
|
-
|
|
12
|
-
import { AuthenticationFlow } from
|
|
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(
|
|
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:
|
|
31
|
-
clientId:
|
|
32
|
-
redirectUri:
|
|
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(),
|
|
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,
|
|
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,
|
|
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,
|
|
59
|
-
if (existsSync(resolve(appDir,
|
|
60
|
-
if (existsSync(resolve(appDir,
|
|
61
|
-
return
|
|
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 ?
|
|
73
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
console.log(
|
|
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(
|
|
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(
|
|
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 ===
|
|
143
|
+
if (arg === '--base-url') {
|
|
144
144
|
baseUrl = args[++i];
|
|
145
|
-
} else if (arg ===
|
|
145
|
+
} else if (arg === '--project') {
|
|
146
146
|
project = args[++i];
|
|
147
|
-
} else if (arg ===
|
|
147
|
+
} else if (arg === '--org') {
|
|
148
148
|
organization = args[++i];
|
|
149
|
-
} else if (arg ===
|
|
149
|
+
} else if (arg === '--deployment' || arg === '-d') {
|
|
150
150
|
const value = args[++i];
|
|
151
151
|
if (value === undefined) {
|
|
152
|
-
console.error(
|
|
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(
|
|
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 ===
|
|
172
|
+
} else if (arg === '--skip-build') {
|
|
173
173
|
skipBuild = true;
|
|
174
|
-
} else if (arg ===
|
|
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(
|
|
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 ||
|
|
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
|
-
|
|
212
|
+
'Enter custom target...',
|
|
213
213
|
];
|
|
214
214
|
|
|
215
215
|
const { selected } = await enquirer.default.prompt({
|
|
216
|
-
type:
|
|
217
|
-
name:
|
|
218
|
-
message:
|
|
216
|
+
type: 'select',
|
|
217
|
+
name: 'selected',
|
|
218
|
+
message: 'Select deployment target',
|
|
219
219
|
choices,
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
-
if (selected ===
|
|
222
|
+
if (selected === 'Enter custom target...') {
|
|
223
223
|
const answers = await enquirer.default.prompt([
|
|
224
224
|
{
|
|
225
|
-
type:
|
|
226
|
-
name:
|
|
227
|
-
message:
|
|
228
|
-
initial:
|
|
225
|
+
type: 'input',
|
|
226
|
+
name: 'baseUrl',
|
|
227
|
+
message: 'CDF Base URL',
|
|
228
|
+
initial: 'https://api.cognitedata.com',
|
|
229
229
|
},
|
|
230
230
|
{
|
|
231
|
-
type:
|
|
232
|
-
name:
|
|
233
|
-
message:
|
|
231
|
+
type: 'input',
|
|
232
|
+
name: 'project',
|
|
233
|
+
message: 'CDF Project',
|
|
234
234
|
},
|
|
235
235
|
{
|
|
236
|
-
type:
|
|
237
|
-
name:
|
|
238
|
-
message:
|
|
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(
|
|
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:
|
|
262
|
-
name:
|
|
263
|
-
message:
|
|
264
|
-
initial:
|
|
261
|
+
type: 'input',
|
|
262
|
+
name: 'baseUrl',
|
|
263
|
+
message: 'CDF Base URL',
|
|
264
|
+
initial: 'https://api.cognitedata.com',
|
|
265
265
|
},
|
|
266
266
|
{
|
|
267
|
-
type:
|
|
268
|
-
name:
|
|
269
|
-
message:
|
|
270
|
-
validate: (v) => (v ? true :
|
|
267
|
+
type: 'input',
|
|
268
|
+
name: 'project',
|
|
269
|
+
message: 'CDF Project',
|
|
270
|
+
validate: (v) => (v ? true : 'Project is required'),
|
|
271
271
|
},
|
|
272
272
|
{
|
|
273
|
-
type:
|
|
274
|
-
name:
|
|
275
|
-
message:
|
|
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(
|
|
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(
|
|
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(
|
|
316
|
-
console.log(
|
|
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(
|
|
321
|
+
throw new Error('No access token received from authentication');
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
console.log(
|
|
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(
|
|
329
|
-
const { CdfApplicationDeployer, ApplicationPackager } = await import(
|
|
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(
|
|
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(
|
|
366
|
+
console.log('š App is published and available to all users');
|
|
367
367
|
} else {
|
|
368
|
-
console.log(
|
|
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(
|
|
379
|
+
console.error('\nā Deployment failed:', error.message);
|
|
380
380
|
process.exit(1);
|
|
381
381
|
}
|
|
382
382
|
}
|
package/bin/skills-command.js
CHANGED
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* dependency) for pull/list operations.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { execFileSync } from
|
|
9
|
-
import { createRequire } from
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
10
|
|
|
11
|
-
const SKILL_SOURCE =
|
|
12
|
-
const SUPPORTED_AGENTS = [
|
|
13
|
-
const AGENT_FLAGS = SUPPORTED_AGENTS.flatMap((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(
|
|
23
|
+
const bin = require.resolve('skills/bin/cli.mjs');
|
|
24
24
|
execFileSync(process.execPath, [bin, ...args], {
|
|
25
|
-
stdio:
|
|
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 [
|
|
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(
|
|
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 ===
|
|
104
|
+
if (arg === '--source') {
|
|
105
105
|
source = args[++i];
|
|
106
106
|
if (!source) {
|
|
107
|
-
console.error(
|
|
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 ===
|
|
111
|
+
} else if (arg === '--skill') {
|
|
112
112
|
skill_name = args[++i];
|
|
113
113
|
if (!skill_name) {
|
|
114
|
-
console.error(
|
|
114
|
+
console.error('ā --skill requires a name');
|
|
115
115
|
process.exit(1);
|
|
116
116
|
}
|
|
117
|
-
} else if (arg ===
|
|
117
|
+
} else if (arg === '--interactive' || arg === '-i') {
|
|
118
118
|
interactive = true;
|
|
119
|
-
} else if (arg ===
|
|
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 = [
|
|
130
|
+
const cliArgs = ['add', source, ...AGENT_FLAGS];
|
|
131
131
|
if (skill_name) {
|
|
132
|
-
cliArgs.push(
|
|
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(
|
|
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(
|
|
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([
|
|
150
|
+
runSkillsCli(['list']);
|
|
151
151
|
} catch (error) {
|
|
152
|
-
console.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
|
|
169
|
-
case
|
|
170
|
-
case
|
|
168
|
+
case 'help':
|
|
169
|
+
case '--help':
|
|
170
|
+
case '-h':
|
|
171
171
|
printHelp();
|
|
172
172
|
break;
|
|
173
|
-
case
|
|
173
|
+
case 'pull':
|
|
174
174
|
handlePull(subArgs);
|
|
175
175
|
break;
|
|
176
|
-
case
|
|
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(
|
|
185
|
+
console.error('ā Skills command failed:', error.message);
|
|
186
186
|
process.exit(1);
|
|
187
187
|
}
|
|
188
188
|
}
|