@cognite/cli 0.5.2 → 0.6.0-alpha.26
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/README.md +94 -33
- package/_templates/app/new/config/eslint.config.mjs.ejs.t +99 -0
- package/_templates/app/new/config/tsconfig.json.ejs.t +35 -0
- package/_templates/app/new/config/tsconfig.node.json.ejs.t +27 -0
- package/_templates/app/new/config/vite.config.ts.ejs.t +28 -0
- package/_templates/app/new/config/vitest.config.ts.ejs.t +14 -0
- package/_templates/app/new/config/vitest.setup.ts.ejs.t +4 -0
- package/_templates/app/new/github/ci.yml.ejs.t +36 -0
- package/_templates/app/new/prompt.js +49 -0
- package/_templates/app/new/root/.npmrc.ejs.t +4 -0
- package/_templates/app/new/root/AGENTS.md.ejs.t +215 -0
- package/_templates/app/new/root/SPEC.md.ejs.t +77 -0
- package/_templates/app/new/root/app.json.ejs.t +20 -0
- package/_templates/app/new/root/gitignore.ejs.t +21 -0
- package/_templates/app/new/root/index.html.ejs.t +36 -0
- package/_templates/app/new/root/manifest.json.ejs.t +9 -0
- package/_templates/app/new/root/package.json.ejs.t +65 -0
- package/_templates/app/new/src/App.test.tsx.ejs.t +45 -0
- package/_templates/app/new/src/App.tsx.ejs.t +234 -0
- package/_templates/app/new/src/lib/utils.ts.ejs.t +9 -0
- package/_templates/app/new/src/main.tsx.ejs.t +27 -0
- package/_templates/app/new/src/styles.css.ejs.t +12 -0
- package/_vendor/spec-kit/.version +4 -0
- package/_vendor/spec-kit/README.md +39 -0
- package/_vendor/spec-kit/commands/speckit.analyze.md +249 -0
- package/_vendor/spec-kit/commands/speckit.checklist.md +361 -0
- package/_vendor/spec-kit/commands/speckit.clarify.md +247 -0
- package/_vendor/spec-kit/commands/speckit.implement.md +198 -0
- package/_vendor/spec-kit/commands/speckit.plan.md +149 -0
- package/_vendor/spec-kit/commands/speckit.specify.md +327 -0
- package/_vendor/spec-kit/commands/speckit.tasks.md +200 -0
- package/_vendor/spec-kit/scripts/bash/check-prerequisites.sh +190 -0
- package/_vendor/spec-kit/scripts/bash/common.sh +645 -0
- package/_vendor/spec-kit/scripts/bash/setup-plan.sh +75 -0
- package/_vendor/spec-kit/templates/checklist-template.md +40 -0
- package/_vendor/spec-kit/templates/plan-template.md +104 -0
- package/_vendor/spec-kit/templates/spec-template.md +128 -0
- package/_vendor/spec-kit/templates/tasks-template.md +251 -0
- package/dist/chunk-6IFTGM5Y.js +6 -0
- package/dist/chunk-6JBK3X6U.js +2 -0
- package/dist/chunk-7BIIU2MQ.js +8 -0
- package/dist/chunk-CQ5OFVL5.js +2 -0
- package/dist/chunk-F3TJC2SP.js +2 -0
- package/dist/cli/cli.js +350 -0
- package/dist/esm-OFTP7G2W.js +34 -0
- package/dist/getMachineId-bsd-3GB6MPGO.js +2 -0
- package/dist/getMachineId-darwin-4AJ74CH4.js +3 -0
- package/dist/getMachineId-linux-IEUC3AW3.js +2 -0
- package/dist/getMachineId-unsupported-YOCUE26C.js +2 -0
- package/dist/getMachineId-win-DDKCA2D6.js +2 -0
- package/dist/skills-R7PLBJFQ.js +2 -0
- package/package.json +26 -17
- package/index.js +0 -116
- package/operations.js +0 -113
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useSpecKit ? null : (useCurrentDir ? "" : ((directoryName || name) + "/")) + "SPEC.md" %>'
|
|
3
|
+
---
|
|
4
|
+
# Feature Specification: <%= displayName || name %>
|
|
5
|
+
|
|
6
|
+
<!--
|
|
7
|
+
This is your app's living product spec. Edit it directly or ask your coding
|
|
8
|
+
agent to collaborate with you on it.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## User Scenarios & Testing
|
|
12
|
+
|
|
13
|
+
### User Stories
|
|
14
|
+
|
|
15
|
+
<!-- 1. As a [persona], I want [capability], so that [benefit]. -->
|
|
16
|
+
|
|
17
|
+
### Acceptance Scenarios
|
|
18
|
+
|
|
19
|
+
<!-- - Given [state], when [action], then [outcome]. -->
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
### Functional Requirements
|
|
24
|
+
|
|
25
|
+
<!--
|
|
26
|
+
List numbered functional requirements (FR-001, FR-002, …) so plans and tasks
|
|
27
|
+
can reference them.
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
<!-- - FR-001: System MUST … -->
|
|
31
|
+
|
|
32
|
+
## Success Criteria
|
|
33
|
+
|
|
34
|
+
<!--
|
|
35
|
+
Measurable outcomes that signal the feature is working. Prefer user-visible
|
|
36
|
+
criteria over implementation details.
|
|
37
|
+
-->
|
|
38
|
+
|
|
39
|
+
<!-- - SC-001: Users complete X in under N seconds 95% of the time. -->
|
|
40
|
+
|
|
41
|
+
## Clarifications
|
|
42
|
+
|
|
43
|
+
<!--
|
|
44
|
+
Open questions or ambiguities that need to be resolved before planning.
|
|
45
|
+
`/speckit.clarify` can help surface these.
|
|
46
|
+
-->
|
|
47
|
+
|
|
48
|
+
## Assumptions
|
|
49
|
+
|
|
50
|
+
<!-- - [Mobile support is out of scope for v1] -->
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Data Models & CDF Integration *(Dune-specific, mandatory)*
|
|
55
|
+
|
|
56
|
+
<!--
|
|
57
|
+
Dune-specific section. Capture how this app integrates with Cognite Data
|
|
58
|
+
Fusion data models. Every Dune app should fill this in.
|
|
59
|
+
-->
|
|
60
|
+
|
|
61
|
+
### Existing views
|
|
62
|
+
|
|
63
|
+
<!--
|
|
64
|
+
CDF views this app reads from. Format: `<space>.<view>:<version>`.
|
|
65
|
+
-->
|
|
66
|
+
|
|
67
|
+
### New views
|
|
68
|
+
|
|
69
|
+
<!--
|
|
70
|
+
Views this app needs that don't yet exist. Describe properties and relationships.
|
|
71
|
+
-->
|
|
72
|
+
|
|
73
|
+
### Spaces
|
|
74
|
+
|
|
75
|
+
<!--
|
|
76
|
+
CDF spaces this app uses, and what each contains.
|
|
77
|
+
-->
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>app.json'
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"name": <%- JSON.stringify(displayName) %>,
|
|
6
|
+
"description": <%- JSON.stringify(description) %>,
|
|
7
|
+
"externalId": "<%= name %>",
|
|
8
|
+
"versionTag": "0.0.1",
|
|
9
|
+
"infra": "appsApi",
|
|
10
|
+
"deployments": [
|
|
11
|
+
{
|
|
12
|
+
"org": "<%= org %>",
|
|
13
|
+
"project": "<%= project %>",
|
|
14
|
+
"baseUrl": "<%= baseUrl %>",
|
|
15
|
+
"published": false,
|
|
16
|
+
"deployClientId": "",
|
|
17
|
+
"deploySecretName": "<%= (org + '_' + project + '_' + cluster).replace(/-/g, '_').toUpperCase() %>"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>.gitignore'
|
|
3
|
+
---
|
|
4
|
+
# Dependencies
|
|
5
|
+
node_modules
|
|
6
|
+
|
|
7
|
+
# Build output
|
|
8
|
+
dist
|
|
9
|
+
|
|
10
|
+
# Environment variables
|
|
11
|
+
.env
|
|
12
|
+
.env.local
|
|
13
|
+
|
|
14
|
+
# Editor directories
|
|
15
|
+
.vscode
|
|
16
|
+
.idea
|
|
17
|
+
|
|
18
|
+
# OS files
|
|
19
|
+
.DS_Store
|
|
20
|
+
Thumbs.db
|
|
21
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>index.html'
|
|
3
|
+
---
|
|
4
|
+
<!DOCTYPE html>
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="UTF-8" />
|
|
8
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
9
|
+
<meta
|
|
10
|
+
name="viewport"
|
|
11
|
+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
12
|
+
/>
|
|
13
|
+
<meta name="theme-color" content="#000000" />
|
|
14
|
+
<meta name="description" content="Cognite Data Fusion Application" />
|
|
15
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
16
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
17
|
+
<meta name="apple-mobile-web-app-title" content="CDF Application" />
|
|
18
|
+
<title><%= displayName %></title>
|
|
19
|
+
|
|
20
|
+
<!-- PWA Manifest -->
|
|
21
|
+
<link rel="manifest" href="/manifest.json" />
|
|
22
|
+
|
|
23
|
+
<!-- Aura typography compatibility -->
|
|
24
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
25
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
26
|
+
<link
|
|
27
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Space+Grotesk:wght@300..700&family=Source+Code+Pro:wght@200..900&display=swap"
|
|
28
|
+
rel="stylesheet"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<div id="root"></div>
|
|
34
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
35
|
+
</body>
|
|
36
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"name": "<%= name %>",
|
|
6
|
+
"version": "0.0.0",
|
|
7
|
+
"private": true,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=20",
|
|
11
|
+
"npm": ">=11.10.0"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "vite",
|
|
15
|
+
"dev": "vite",
|
|
16
|
+
"build": "tsc && vite build",
|
|
17
|
+
"preview": "vite preview",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"test:ui": "vitest --ui",
|
|
21
|
+
"lint": "eslint . --ext .js,.mjs,.cjs,.ts,.tsx",
|
|
22
|
+
"lint:fix": "eslint . --fix --ext .js,.mjs,.cjs,.ts,.tsx",
|
|
23
|
+
"deploy": "npx @cognite/dune@latest apps deploy --interactive --published",
|
|
24
|
+
"deploy-preview": "npx @cognite/dune@latest apps deploy --interactive"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@cognite/aura": "^0.1.7",
|
|
28
|
+
"@cognite/sdk": "^10.3.0",
|
|
29
|
+
"@cognite/dune": "^4.0.0",
|
|
30
|
+
"@cognite/app-sdk": "^0.4.0",
|
|
31
|
+
"@tabler/icons-react": "^3.35.0",
|
|
32
|
+
"@tanstack/react-query": "^5.90.10",
|
|
33
|
+
"clsx": "^2.1.1",
|
|
34
|
+
"react": "^18.3.1",
|
|
35
|
+
"react-dom": "^18.3.1",
|
|
36
|
+
"tailwind-merge": "^3.4.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@eslint/js": "9.39.4",
|
|
40
|
+
"@tailwindcss/vite": "^4.1.17",
|
|
41
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
42
|
+
"@testing-library/react": "^16.1.0",
|
|
43
|
+
"@testing-library/user-event": "^14.5.2",
|
|
44
|
+
"@types/node": "^24.10.1",
|
|
45
|
+
"@types/react": "^18.3.1",
|
|
46
|
+
"@types/react-dom": "^18.3.1",
|
|
47
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
48
|
+
"@vitest/ui": "^2.1.8",
|
|
49
|
+
"autoprefixer": "^10.4.22",
|
|
50
|
+
"eslint": "9.39.4",
|
|
51
|
+
"eslint-plugin-import": "^2.32.0",
|
|
52
|
+
"eslint-plugin-no-only-tests": "^3.3.0",
|
|
53
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
54
|
+
"eslint-plugin-react-refresh": "^0.5.2",
|
|
55
|
+
"globals": "^16.5.0",
|
|
56
|
+
"happy-dom": "^20.9.0",
|
|
57
|
+
"postcss": "^8.5.6",
|
|
58
|
+
"tailwindcss": "^4.1.17",
|
|
59
|
+
"typescript": "^5.0.0",
|
|
60
|
+
"typescript-eslint": "^8.46.4",
|
|
61
|
+
"vite": "7.3.2",
|
|
62
|
+
"vite-plugin-mkcert": "^1.17.9",
|
|
63
|
+
"vitest": "^2.1.8"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/App.test.tsx'
|
|
3
|
+
---
|
|
4
|
+
import * as appSdk from '@cognite/app-sdk';
|
|
5
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import App from './App';
|
|
9
|
+
|
|
10
|
+
vi.mock(import('@cognite/app-sdk'));
|
|
11
|
+
|
|
12
|
+
describe('App', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.clearAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders loading state', () => {
|
|
18
|
+
vi.mocked(appSdk.connectToHostApp).mockReturnValue(new Promise(() => {}));
|
|
19
|
+
|
|
20
|
+
render(<App />);
|
|
21
|
+
expect(screen.getByText('Loading project...')).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('renders splash with deployment targets and checklist copy', async () => {
|
|
25
|
+
vi.mocked(appSdk.connectToHostApp).mockResolvedValue({
|
|
26
|
+
api: { getProject: vi.fn().mockResolvedValue('my-test-project') } as Partial<appSdk.HostAppAPI> as appSdk.HostAppAPI,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
render(<App />);
|
|
30
|
+
await waitFor(() => expect(screen.getByText('Welcome to Dune')).toBeInTheDocument());
|
|
31
|
+
expect(screen.getByText('App deployment checklist')).toBeInTheDocument();
|
|
32
|
+
expect(screen.getByText('Plan')).toBeInTheDocument();
|
|
33
|
+
expect(screen.getByText('Explore')).toBeInTheDocument();
|
|
34
|
+
expect(screen.getByText('Deploy')).toBeInTheDocument();
|
|
35
|
+
expect(screen.getByText('Support')).toBeInTheDocument();
|
|
36
|
+
expect(screen.getByText('Help & feedback')).toBeInTheDocument();
|
|
37
|
+
expect(screen.getByText('Your app will deploy to')).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText('org')).toBeInTheDocument();
|
|
39
|
+
expect(screen.getByText('and project')).toBeInTheDocument();
|
|
40
|
+
expect(screen.getByText('<%= org %>')).toBeInTheDocument();
|
|
41
|
+
expect(screen.getByText('<%= project %>')).toBeInTheDocument();
|
|
42
|
+
expect(screen.getAllByText(/SPEC\.md/).length).toBeGreaterThan(0);
|
|
43
|
+
expect(screen.getByText(/apps deploy --interactive/)).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/App.tsx'
|
|
3
|
+
---
|
|
4
|
+
import { connectToHostApp } from '@cognite/app-sdk';
|
|
5
|
+
import {
|
|
6
|
+
Alert,
|
|
7
|
+
AlertDescription,
|
|
8
|
+
Badge,
|
|
9
|
+
Card,
|
|
10
|
+
CardContent,
|
|
11
|
+
CardDescription,
|
|
12
|
+
CardHeader,
|
|
13
|
+
CardTitle,
|
|
14
|
+
Collapsible,
|
|
15
|
+
CollapsibleContent,
|
|
16
|
+
CollapsibleTrigger,
|
|
17
|
+
Loader,
|
|
18
|
+
Separator,
|
|
19
|
+
} from '@cognite/aura/components';
|
|
20
|
+
import { IconCaretUpDown, IconRocket } from '@tabler/icons-react';
|
|
21
|
+
import { useEffect, useState } from 'react';
|
|
22
|
+
|
|
23
|
+
import appConfig from '../app.json';
|
|
24
|
+
|
|
25
|
+
const DUNE_DOCUMENTATION_HREF = 'https://laughing-adventure-r6kwpyy.pages.github.io/';
|
|
26
|
+
|
|
27
|
+
const INTRO_COPY =
|
|
28
|
+
"Build and deploy React apps to Cognite Data Fusion in minutes. Aura, Cognite's AI-native design system, comes pre-configured so your app looks and feels at home from day one. Follow the checklist below to get started.";
|
|
29
|
+
|
|
30
|
+
const CHECKLIST_STEPS = [
|
|
31
|
+
{
|
|
32
|
+
label: 'Plan',
|
|
33
|
+
badge: 'Step 1',
|
|
34
|
+
body: (
|
|
35
|
+
<>
|
|
36
|
+
Open <code>SPEC.md</code> at the repo root and describe what you want to build. If <code>.specify/</code> is
|
|
37
|
+
present, run <code>/speckit.specify</code> in Claude Code or Cursor to fill it in interactively. Otherwise, ask
|
|
38
|
+
your agent to collaborate on <code>SPEC.md</code> directly. Keep it simple and clear, then move on to building
|
|
39
|
+
when ready.
|
|
40
|
+
</>
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: 'Explore',
|
|
45
|
+
badge: 'Step 2',
|
|
46
|
+
body: (
|
|
47
|
+
<>
|
|
48
|
+
Ask Cursor to review and understand your data model, then answer any follow-up questions it raises. Continue
|
|
49
|
+
refining the app by providing additional input as needed.
|
|
50
|
+
</>
|
|
51
|
+
),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: 'Deploy',
|
|
55
|
+
badge: 'Step 3',
|
|
56
|
+
body: (
|
|
57
|
+
<>
|
|
58
|
+
When ready to deploy, run <code>npx @cognite/dune apps deploy --interactive</code> in the terminal. Your app will
|
|
59
|
+
appear in the Fusion portal under Custom apps. Run the command again to redeploy new changes.
|
|
60
|
+
</>
|
|
61
|
+
),
|
|
62
|
+
},
|
|
63
|
+
] as const;
|
|
64
|
+
|
|
65
|
+
function App() {
|
|
66
|
+
// Connect to the Fusion host via @cognite/app-sdk. The handshake is
|
|
67
|
+
// asynchronous — `project` is only populated after Comlink finishes
|
|
68
|
+
// exposing the host API, so we render a loader until then.
|
|
69
|
+
const [project, setProject] = useState<string | null>(null);
|
|
70
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
71
|
+
const [error, setError] = useState<string | undefined>();
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
let cancelled = false;
|
|
75
|
+
connectToHostApp({ applicationName: '<%= name %>' })
|
|
76
|
+
.then(async ({ api }) => {
|
|
77
|
+
if (cancelled) return;
|
|
78
|
+
const proj = await api.getProject();
|
|
79
|
+
if (cancelled) return;
|
|
80
|
+
setProject(proj);
|
|
81
|
+
})
|
|
82
|
+
.catch((err: unknown) => {
|
|
83
|
+
if (cancelled) return;
|
|
84
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
85
|
+
})
|
|
86
|
+
.finally(() => {
|
|
87
|
+
if (!cancelled) setIsLoading(false);
|
|
88
|
+
});
|
|
89
|
+
return () => {
|
|
90
|
+
cancelled = true;
|
|
91
|
+
};
|
|
92
|
+
}, []);
|
|
93
|
+
|
|
94
|
+
if (isLoading) {
|
|
95
|
+
return (
|
|
96
|
+
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
97
|
+
<section className="mx-auto flex min-h-screen w-full max-w-lg flex-col justify-center p-4 sm:p-8">
|
|
98
|
+
<div className="mx-auto w-full max-w-sm">
|
|
99
|
+
<Card aria-label="Loading project" aria-live="polite">
|
|
100
|
+
<CardContent>
|
|
101
|
+
<div className="inline-flex items-center gap-3 text-muted-foreground">
|
|
102
|
+
<Loader size={20} />
|
|
103
|
+
<span>Loading project...</span>
|
|
104
|
+
</div>
|
|
105
|
+
</CardContent>
|
|
106
|
+
</Card>
|
|
107
|
+
</div>
|
|
108
|
+
</section>
|
|
109
|
+
</main>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (error) {
|
|
114
|
+
return (
|
|
115
|
+
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
116
|
+
<section className="mx-auto flex min-h-screen w-full max-w-lg flex-col justify-center p-4 sm:p-8">
|
|
117
|
+
<div className="mx-auto w-full max-w-sm">
|
|
118
|
+
<Alert>
|
|
119
|
+
<AlertDescription>Failed to connect to Fusion host: {error}</AlertDescription>
|
|
120
|
+
</Alert>
|
|
121
|
+
</div>
|
|
122
|
+
</section>
|
|
123
|
+
</main>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const deployment = appConfig.deployments?.[0];
|
|
128
|
+
const orgLabel = deployment?.org ?? '';
|
|
129
|
+
const projectLabel = deployment?.project ?? project ?? '';
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
133
|
+
<section className="mx-auto flex min-h-screen w-full max-w-3xl flex-col justify-center p-4 sm:p-8">
|
|
134
|
+
<Card>
|
|
135
|
+
<div className="p-15 gap-16">
|
|
136
|
+
<CardHeader>
|
|
137
|
+
<CardTitle as="h1">Welcome to Dune</CardTitle>
|
|
138
|
+
<CardDescription>{INTRO_COPY}</CardDescription>
|
|
139
|
+
</CardHeader>
|
|
140
|
+
|
|
141
|
+
<CardContent>
|
|
142
|
+
<Separator />
|
|
143
|
+
|
|
144
|
+
<div className="flex flex-col gap-6 pt-16">
|
|
145
|
+
<div className="flex items-center gap-2 pt-4">
|
|
146
|
+
<IconRocket aria-hidden />
|
|
147
|
+
<span className="text-2xl font-medium">App deployment checklist</span>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<div className="flex flex-col gap-4 px-4">
|
|
151
|
+
{CHECKLIST_STEPS.map((step, index) => (
|
|
152
|
+
<Collapsible key={step.label} defaultOpen={index === 0}>
|
|
153
|
+
<CollapsibleTrigger className="w-full">
|
|
154
|
+
<div className="flex w-full min-w-0 items-center justify-between gap-3 text-left">
|
|
155
|
+
<span className="text-lg">{step.label}</span>
|
|
156
|
+
<span className="inline-flex shrink-0 items-center gap-2">
|
|
157
|
+
<Badge variant="mountain" background>
|
|
158
|
+
{step.badge}
|
|
159
|
+
</Badge>
|
|
160
|
+
<IconCaretUpDown aria-hidden className="size-4 text-muted-foreground" />
|
|
161
|
+
</span>
|
|
162
|
+
</div>
|
|
163
|
+
</CollapsibleTrigger>
|
|
164
|
+
<CollapsibleContent>
|
|
165
|
+
<div className="py-2">{step.body}</div>
|
|
166
|
+
</CollapsibleContent>
|
|
167
|
+
</Collapsible>
|
|
168
|
+
))}
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div className="mb-10">
|
|
172
|
+
<Alert variant="secondary">
|
|
173
|
+
<AlertDescription>
|
|
174
|
+
<div className="flex flex-wrap items-center gap-2 text-lg">
|
|
175
|
+
<span>Your app will deploy to</span>
|
|
176
|
+
{orgLabel ? (
|
|
177
|
+
<>
|
|
178
|
+
<span>org</span>
|
|
179
|
+
<Badge variant="nordic" background>
|
|
180
|
+
{orgLabel}
|
|
181
|
+
</Badge>
|
|
182
|
+
<span>and project</span>
|
|
183
|
+
</>
|
|
184
|
+
) : (
|
|
185
|
+
<span>project</span>
|
|
186
|
+
)}
|
|
187
|
+
<Badge variant="nordic" background>
|
|
188
|
+
{projectLabel}
|
|
189
|
+
</Badge>
|
|
190
|
+
</div>
|
|
191
|
+
</AlertDescription>
|
|
192
|
+
</Alert>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<Collapsible>
|
|
196
|
+
<CollapsibleTrigger className="w-full">
|
|
197
|
+
<div className="flex w-full min-w-0 items-center justify-between gap-3 text-left">
|
|
198
|
+
<span className="text-lg">Support</span>
|
|
199
|
+
<span className="inline-flex shrink-0 items-center gap-2">
|
|
200
|
+
<Badge variant="mountain">
|
|
201
|
+
Help & feedback
|
|
202
|
+
</Badge>
|
|
203
|
+
<IconCaretUpDown aria-hidden className="size-4 text-muted-foreground" />
|
|
204
|
+
</span>
|
|
205
|
+
</div>
|
|
206
|
+
</CollapsibleTrigger>
|
|
207
|
+
<CollapsibleContent>
|
|
208
|
+
<div className="py-2">
|
|
209
|
+
<p>
|
|
210
|
+
For additional support and feedback, please head to{' '}
|
|
211
|
+
<a
|
|
212
|
+
href={DUNE_DOCUMENTATION_HREF}
|
|
213
|
+
rel="noreferrer"
|
|
214
|
+
style={{ color: '#486AED' }}
|
|
215
|
+
target="_blank"
|
|
216
|
+
>
|
|
217
|
+
Dune documentation
|
|
218
|
+
</a>{' '}
|
|
219
|
+
or the{' '}
|
|
220
|
+
<span style={{ color: '#486AED' }}>#Dune Slack channel</span>.
|
|
221
|
+
</p>
|
|
222
|
+
</div>
|
|
223
|
+
</CollapsibleContent>
|
|
224
|
+
</Collapsible>
|
|
225
|
+
</div>
|
|
226
|
+
</CardContent>
|
|
227
|
+
</div>
|
|
228
|
+
</Card>
|
|
229
|
+
</section>
|
|
230
|
+
</main>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export default App;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/lib/utils.ts'
|
|
3
|
+
---
|
|
4
|
+
import { type ClassValue, clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
|
|
7
|
+
export function cn(...inputs: ClassValue[]) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/main.tsx'
|
|
3
|
+
---
|
|
4
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import ReactDOM from 'react-dom/client';
|
|
7
|
+
|
|
8
|
+
import App from './App.tsx';
|
|
9
|
+
|
|
10
|
+
import './styles.css';
|
|
11
|
+
|
|
12
|
+
const queryClient = new QueryClient({
|
|
13
|
+
defaultOptions: {
|
|
14
|
+
queries: {
|
|
15
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
16
|
+
gcTime: 10 * 60 * 1000, // 10 minutes
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
22
|
+
<React.StrictMode>
|
|
23
|
+
<QueryClientProvider client={queryClient}>
|
|
24
|
+
<App />
|
|
25
|
+
</QueryClientProvider>
|
|
26
|
+
</React.StrictMode>
|
|
27
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/styles.css'
|
|
3
|
+
---
|
|
4
|
+
@import '@cognite/aura/styles.source.css';
|
|
5
|
+
|
|
6
|
+
@source '../node_modules/@cognite/aura/dist/components';
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
--font-inter: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
10
|
+
--font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
11
|
+
"Liberation Mono", "Courier New", monospace;
|
|
12
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Vendored: github/spec-kit
|
|
2
|
+
|
|
3
|
+
Selected, generated files from [github/spec-kit](https://github.com/github/spec-kit). Pinned version is in [`.version`](./.version).
|
|
4
|
+
|
|
5
|
+
## Why this exists
|
|
6
|
+
|
|
7
|
+
Dune app authors should not need Python, `uv`, or network access just because they pass `dune create --spec-kit`.
|
|
8
|
+
|
|
9
|
+
Instead, Dune maintainers refresh spec-kit inside this monorepo, commit the selected generated files here, and let `dune create` copy them into new apps. That keeps end-user scaffolding fast and JS/TS-only while still letting us track upstream spec-kit intentionally.
|
|
10
|
+
|
|
11
|
+
## Maintainer-only refresh
|
|
12
|
+
|
|
13
|
+
The refresh script is for Dune monorepo maintainers only:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
pnpm --filter @cognite/dune refresh-spec-kit <tag>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
It requires `uv` locally, which provides `uvx`. That is acceptable for maintainers; it must not become a requirement for generated Dune apps.
|
|
20
|
+
|
|
21
|
+
The script runs spec-kit's own `specify init` for the requested tag, stages the selected output in a temporary directory, and swaps it into `_vendor/spec-kit` only after all copies succeed.
|
|
22
|
+
|
|
23
|
+
## What we vendor
|
|
24
|
+
|
|
25
|
+
We vendor the parts Dune uses:
|
|
26
|
+
|
|
27
|
+
- generated `commands/speckit.{specify,clarify,plan,tasks,implement,analyze,checklist}.md`
|
|
28
|
+
- `templates/{spec,plan,tasks,checklist}-template.md`
|
|
29
|
+
- `scripts/bash/{check-prerequisites,common,setup-plan}.sh`
|
|
30
|
+
|
|
31
|
+
Deliberately excluded:
|
|
32
|
+
|
|
33
|
+
- spec-kit's `AGENTS.md`, constitution command, and constitution template, because Dune uses the app's `AGENTS.md` as the constitution
|
|
34
|
+
- integration metadata/workflows generated by `specify init`
|
|
35
|
+
- optional commands such as taskstoissues
|
|
36
|
+
- PowerShell scripts, until Dune chooses to support a PowerShell command set
|
|
37
|
+
- spec-kit's Python CLI, tests, and docs
|
|
38
|
+
|
|
39
|
+
**Cadence:** refresh at least once per Dune CLI minor release, sooner if upstream ships a fix we depend on.
|