@minnai/create-aura-app 0.0.10 → 0.0.12
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/dist/scaffold.js +8 -32
- package/package.json +1 -1
- package/templates/starter/package.json +3 -0
- package/templates/starter/src/src/App.css +32 -0
- package/templates/starter/src/src/App.tsx +82 -0
- package/templates/starter/src/src/ambiance/currency-air/index.tsx +25 -0
- package/templates/starter/src/src/ambiance/currency-air/logic.ts +49 -0
- package/templates/starter/src/src/ambiance/currency-air/manifest.ts +15 -0
- package/templates/starter/src/src/ambiance/currency-air/resources.ts +16 -0
- package/templates/starter/src/src/ambiance/currency-air/ui/index.tsx +42 -0
- package/templates/starter/src/src/ambiance/index.ts +48 -0
- package/templates/starter/src/src/ambiance/stocks-air/index.ts +3 -0
- package/templates/starter/src/src/ambiance/stocks-air/index.tsx +28 -0
- package/templates/starter/src/src/ambiance/stocks-air/logic.ts +87 -0
- package/templates/starter/src/src/ambiance/stocks-air/manifest.ts +15 -0
- package/templates/starter/src/src/ambiance/stocks-air/resources.ts +23 -0
- package/templates/starter/src/src/ambiance/stocks-air/ui/index.tsx +67 -0
- package/templates/starter/src/src/assets/react.svg +1 -0
- package/templates/starter/src/src/components/AnalyticsTracker.tsx +13 -0
- package/templates/starter/src/src/components/Playground/CodeEditor.tsx +121 -0
- package/templates/starter/src/src/components/Playground/Debugger.tsx +71 -0
- package/templates/starter/src/src/components/Playground/Playground.tsx +221 -0
- package/templates/starter/src/src/components/Playground/Sidebar.tsx +68 -0
- package/templates/starter/src/src/components/ProjectSidebar/ProjectSidebar.tsx +219 -0
- package/templates/starter/src/src/components/TourGuide/TourGuide.tsx +16 -0
- package/templates/starter/src/src/components/TourGuide/index.ts +1 -0
- package/templates/starter/src/src/components/TourGuide/tour-flow.yaml +137 -0
- package/templates/starter/src/src/components/TourGuide/useTourEngine.ts +376 -0
- package/templates/starter/src/src/index.css +68 -0
- package/templates/starter/src/src/main.tsx +10 -0
- package/templates/starter/src/src/services/AnalyticsService.ts +181 -0
- package/templates/starter/src/src/types/ContextHandler.ts +13 -0
- package/templates/starter/vite.config.ts +0 -9
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { getStorage } from '@minnai/aura';
|
|
3
|
+
|
|
4
|
+
interface ProjectSidebarProps {
|
|
5
|
+
currentProjectId: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const ProjectSidebar: React.FC<ProjectSidebarProps> = ({ currentProjectId }) => {
|
|
9
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
10
|
+
|
|
11
|
+
// Simple local history (could be more robust)
|
|
12
|
+
const [recentProjects, setRecentProjects] = useState<string[]>(() => {
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(localStorage.getItem('aura_projects') || '[]');
|
|
15
|
+
} catch {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const addProject = (id: string) => {
|
|
21
|
+
const next = [id, ...recentProjects.filter(p => p !== id)].slice(0, 5); // Keep last 5
|
|
22
|
+
setRecentProjects(next);
|
|
23
|
+
localStorage.setItem('aura_projects', JSON.stringify(next));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const handleNewChat = () => {
|
|
27
|
+
const newId = 'proj_' + Math.random().toString(36).substr(2, 6);
|
|
28
|
+
addProject(newId);
|
|
29
|
+
window.location.href = `/?project=${newId}`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleRestart = async () => {
|
|
33
|
+
if (confirm('Are you sure you want to reset the Tour Demo? This will clear all data.')) {
|
|
34
|
+
try {
|
|
35
|
+
const storage = getStorage();
|
|
36
|
+
console.log("[ProjectSidebar] Clearing all tour demo data...");
|
|
37
|
+
|
|
38
|
+
// Delete the main project document
|
|
39
|
+
await storage.documents.delete('projects', 'aura-tour-demo');
|
|
40
|
+
|
|
41
|
+
// Clear any task collections that might have been created
|
|
42
|
+
// The session ID is dynamic, so we can't target specific collections
|
|
43
|
+
// Instead, we rely on the project state being the source of truth
|
|
44
|
+
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error("Failed to reset storage", e);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Navigate to (or reload) the demo project
|
|
50
|
+
window.location.href = `/?project=aura-tour-demo`;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleSwitch = (id: string) => {
|
|
55
|
+
window.location.href = `/?project=${id}`;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const isTourDemo = currentProjectId === 'aura-tour-demo';
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
63
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
64
|
+
style={{
|
|
65
|
+
width: isHovered ? '240px' : '68px',
|
|
66
|
+
height: '100%',
|
|
67
|
+
background: '#1a1a1b',
|
|
68
|
+
display: 'flex',
|
|
69
|
+
flexDirection: 'column',
|
|
70
|
+
transition: 'width 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
71
|
+
overflow: 'hidden',
|
|
72
|
+
zIndex: 100,
|
|
73
|
+
borderRight: '1px solid #2d2d2f'
|
|
74
|
+
}}>
|
|
75
|
+
|
|
76
|
+
{/* Logo Section */}
|
|
77
|
+
<div style={{ padding: '20px 16px', display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
78
|
+
<div style={{ fontSize: '24px', lineHeight: '1' }}>🌌</div>
|
|
79
|
+
{isHovered && <span style={{ color: 'white', fontWeight: 'bold', whiteSpace: 'nowrap' }}>Aura Starter</span>}
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div style={{ height: '1px', background: '#2d2d2f', margin: '0 12px 20px' }} />
|
|
83
|
+
|
|
84
|
+
{/* New Chat Button */}
|
|
85
|
+
<div style={{
|
|
86
|
+
padding: '0 12px',
|
|
87
|
+
marginBottom: '15px',
|
|
88
|
+
display: 'flex',
|
|
89
|
+
alignItems: 'center',
|
|
90
|
+
gap: '12px',
|
|
91
|
+
cursor: 'pointer',
|
|
92
|
+
opacity: 0.9
|
|
93
|
+
}}
|
|
94
|
+
onClick={handleNewChat}
|
|
95
|
+
title="Start New Chat"
|
|
96
|
+
>
|
|
97
|
+
<div style={{
|
|
98
|
+
minWidth: '44px',
|
|
99
|
+
height: '44px',
|
|
100
|
+
borderRadius: '12px',
|
|
101
|
+
background: '#2d2d2f',
|
|
102
|
+
display: 'flex',
|
|
103
|
+
alignItems: 'center',
|
|
104
|
+
justifyContent: 'center',
|
|
105
|
+
fontSize: '1.2rem',
|
|
106
|
+
color: '#fff',
|
|
107
|
+
transition: 'background 0.2s',
|
|
108
|
+
border: '1px dashed #555'
|
|
109
|
+
}}>
|
|
110
|
+
+
|
|
111
|
+
</div>
|
|
112
|
+
{isHovered && (
|
|
113
|
+
<span style={{ color: 'white', fontSize: '0.9rem', fontWeight: '500', whiteSpace: 'nowrap' }}>New Chat</span>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{/* Restart Button (Only visible/relevant for Tour Demo? Or always to reset Tour?) */}
|
|
118
|
+
{/* User asked for "Restart button should start the tourer logic but from a clean slate" */}
|
|
119
|
+
<div style={{
|
|
120
|
+
padding: '0 12px',
|
|
121
|
+
marginBottom: '15px',
|
|
122
|
+
display: 'flex',
|
|
123
|
+
alignItems: 'center',
|
|
124
|
+
gap: '12px',
|
|
125
|
+
cursor: 'pointer',
|
|
126
|
+
opacity: 0.9
|
|
127
|
+
}}
|
|
128
|
+
onClick={handleRestart}
|
|
129
|
+
title="Reset & Start Tour"
|
|
130
|
+
>
|
|
131
|
+
<div style={{
|
|
132
|
+
minWidth: '44px',
|
|
133
|
+
height: '44px',
|
|
134
|
+
borderRadius: '12px',
|
|
135
|
+
background: 'rgba(255, 68, 68, 0.1)',
|
|
136
|
+
border: '1px solid rgba(255, 68, 68, 0.3)',
|
|
137
|
+
display: 'flex',
|
|
138
|
+
alignItems: 'center',
|
|
139
|
+
justifyContent: 'center',
|
|
140
|
+
fontSize: '1.2rem',
|
|
141
|
+
color: '#ff4444',
|
|
142
|
+
transition: 'background 0.2s',
|
|
143
|
+
}}>
|
|
144
|
+
↻
|
|
145
|
+
</div>
|
|
146
|
+
{isHovered && (
|
|
147
|
+
<span style={{ color: '#ff4444', fontSize: '0.9rem', fontWeight: '500', whiteSpace: 'nowrap' }}>Restart Tour</span>
|
|
148
|
+
)}
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
{/* Tour Demo Item */}
|
|
152
|
+
<div style={{
|
|
153
|
+
padding: '0 12px',
|
|
154
|
+
marginBottom: '5px',
|
|
155
|
+
display: 'flex',
|
|
156
|
+
alignItems: 'center',
|
|
157
|
+
gap: '12px',
|
|
158
|
+
cursor: 'pointer',
|
|
159
|
+
opacity: isTourDemo ? 1 : 0.6,
|
|
160
|
+
background: isTourDemo ? 'rgba(255,255,255,0.05)' : 'transparent',
|
|
161
|
+
borderRadius: '8px'
|
|
162
|
+
}}
|
|
163
|
+
onClick={() => handleSwitch('aura-tour-demo')}>
|
|
164
|
+
<div style={{
|
|
165
|
+
minWidth: '44px',
|
|
166
|
+
height: '44px',
|
|
167
|
+
display: 'flex',
|
|
168
|
+
alignItems: 'center',
|
|
169
|
+
justifyContent: 'center',
|
|
170
|
+
fontSize: '1.2rem',
|
|
171
|
+
}}>
|
|
172
|
+
🚀
|
|
173
|
+
</div>
|
|
174
|
+
{isHovered && (
|
|
175
|
+
<div style={{ display: 'flex', flexDirection: 'column', whiteSpace: 'nowrap' }}>
|
|
176
|
+
<span style={{ color: 'white', fontSize: '0.9rem', fontWeight: '600' }}>Tour Demo</span>
|
|
177
|
+
{isTourDemo && <span style={{ color: '#888', fontSize: '0.7rem' }}>Active</span>}
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
{/* Recent Projects */}
|
|
183
|
+
{recentProjects.map(pid => (
|
|
184
|
+
<div key={pid} style={{
|
|
185
|
+
padding: '0 12px',
|
|
186
|
+
marginBottom: '5px',
|
|
187
|
+
display: 'flex',
|
|
188
|
+
alignItems: 'center',
|
|
189
|
+
gap: '12px',
|
|
190
|
+
cursor: 'pointer',
|
|
191
|
+
opacity: currentProjectId === pid ? 1 : 0.6,
|
|
192
|
+
background: currentProjectId === pid ? 'rgba(255,255,255,0.05)' : 'transparent',
|
|
193
|
+
borderRadius: '8px'
|
|
194
|
+
}}
|
|
195
|
+
onClick={() => handleSwitch(pid)}>
|
|
196
|
+
<div style={{
|
|
197
|
+
minWidth: '44px',
|
|
198
|
+
height: '44px',
|
|
199
|
+
display: 'flex',
|
|
200
|
+
alignItems: 'center',
|
|
201
|
+
justifyContent: 'center',
|
|
202
|
+
fontSize: '1.2rem',
|
|
203
|
+
color: '#aaa'
|
|
204
|
+
}}>
|
|
205
|
+
💬
|
|
206
|
+
</div>
|
|
207
|
+
{isHovered && (
|
|
208
|
+
<div style={{ display: 'flex', flexDirection: 'column', whiteSpace: 'nowrap' }}>
|
|
209
|
+
<span style={{ color: 'white', fontSize: '0.9rem', fontWeight: '500' }}>Chat {pid.substr(-4)}</span>
|
|
210
|
+
</div>
|
|
211
|
+
)}
|
|
212
|
+
</div>
|
|
213
|
+
))}
|
|
214
|
+
|
|
215
|
+
<div style={{ flex: 1 }} />
|
|
216
|
+
|
|
217
|
+
</div>
|
|
218
|
+
);
|
|
219
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useTourEngine } from './useTourEngine';
|
|
2
|
+
import tourFlowYaml from './tour-flow.yaml?raw';
|
|
3
|
+
import YAML from 'yaml';
|
|
4
|
+
|
|
5
|
+
// Parse the YAML config
|
|
6
|
+
const tourFlow = YAML.parse(tourFlowYaml);
|
|
7
|
+
|
|
8
|
+
export function TourGuide({ projectId }: { projectId: string }) {
|
|
9
|
+
// The engine handles everything
|
|
10
|
+
const state = useTourEngine(tourFlow, projectId);
|
|
11
|
+
|
|
12
|
+
// Debug logging
|
|
13
|
+
console.log('[TourGuide] State:', state);
|
|
14
|
+
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TourGuide } from './TourGuide';
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
name: Aura Starter Tour
|
|
2
|
+
projectId: aura-tour-demo
|
|
3
|
+
|
|
4
|
+
steps:
|
|
5
|
+
- step: INIT
|
|
6
|
+
run:
|
|
7
|
+
- say: "Loading brain. 🧠"
|
|
8
|
+
- say: "Loading UIs. 🎨"
|
|
9
|
+
- say: "Hello world, am I alive? 🤖"
|
|
10
|
+
- say: "Loading sense of humor..."
|
|
11
|
+
- say: "404 Not Found !!"
|
|
12
|
+
- say: "Just kidding 😅"
|
|
13
|
+
- say: "All systems nominal. Ready to go. 🚀"
|
|
14
|
+
- say: "Hi!"
|
|
15
|
+
- say: "I'm Aura 🌌."
|
|
16
|
+
- say: "I've been assigned to show you around."
|
|
17
|
+
- say: "But we should work together."
|
|
18
|
+
- say: "Loading starter tasks.."
|
|
19
|
+
- spawn: tasks-air
|
|
20
|
+
props:
|
|
21
|
+
title: "Aura Starter Tasks"
|
|
22
|
+
initialTasks:
|
|
23
|
+
- { id: init-1, label: "loading Aura", completed: false }
|
|
24
|
+
- { id: move-1, label: "move tasks to space", completed: false }
|
|
25
|
+
- { id: apple-1, label: "check Apple stock price", completed: false }
|
|
26
|
+
- say: "There we go."
|
|
27
|
+
- say: "Now, let's use the chat to close our first task."
|
|
28
|
+
- say: 'Tell me to "complete loading".'
|
|
29
|
+
- wait: task_toggled
|
|
30
|
+
match: "loading"
|
|
31
|
+
- goto: POPOUT_GUIDE
|
|
32
|
+
|
|
33
|
+
- step: POPOUT_GUIDE
|
|
34
|
+
run:
|
|
35
|
+
- say: "Perfect!"
|
|
36
|
+
- say: "Let's keep the chat tidy."
|
|
37
|
+
- say: "You can press the 'Pop Out' button to move the Tasks to the space on the right if you'd like."
|
|
38
|
+
- say: "Or you can keep it here in the chat. Both work fine!"
|
|
39
|
+
- goto: MANUAL_CHECK
|
|
40
|
+
|
|
41
|
+
- step: MANUAL_CHECK
|
|
42
|
+
run:
|
|
43
|
+
- say: "Great! Now, you try the next one manually."
|
|
44
|
+
- say: 'Click the checkbox next to "move tasks to space" to mark it as done.'
|
|
45
|
+
- wait: task_toggled
|
|
46
|
+
match: "move tasks"
|
|
47
|
+
- goto: CHAT_ADD
|
|
48
|
+
|
|
49
|
+
- step: CHAT_ADD
|
|
50
|
+
run:
|
|
51
|
+
- say: "Yes, you do, or tell me to do. Both works with Aura."
|
|
52
|
+
- say: "Now, let me show you how to add tasks via chat."
|
|
53
|
+
- say: 'Tell me: "Add task: convert stocks to Euro".'
|
|
54
|
+
- say: "We will need it later."
|
|
55
|
+
- wait: task_added
|
|
56
|
+
match: "convert"
|
|
57
|
+
- goto: APPLE_STOCK
|
|
58
|
+
|
|
59
|
+
- step: APPLE_STOCK
|
|
60
|
+
run:
|
|
61
|
+
# - say: "Excellent. Efficiency is key. 🚀"
|
|
62
|
+
# - say: "You got it, I leave updating the tasks to you now."
|
|
63
|
+
# - say: 'You can ask me contextual questions about your tasks like "how many tasks do i have open".'
|
|
64
|
+
# - say: "Now, let's cook up some fun stuff!"
|
|
65
|
+
# - say: "I'm also a financial expert (in training) 📈."
|
|
66
|
+
- say: "Ask me: `What is the Apple stock price?`."
|
|
67
|
+
- say: "Let's see what happens..."
|
|
68
|
+
- wait: air_success
|
|
69
|
+
air: stocks-air
|
|
70
|
+
onError: API_KEY_MISSING
|
|
71
|
+
- goto: STOCKS_INFO
|
|
72
|
+
|
|
73
|
+
- step: STOCKS_INFO
|
|
74
|
+
run:
|
|
75
|
+
- say: "Nice! The stock data is showing."
|
|
76
|
+
- say: "Real-time market data powered by AlphaVantage API. 📈"
|
|
77
|
+
- do: toggle_task
|
|
78
|
+
label: "check Apple stock price"
|
|
79
|
+
- goto: CONVERT
|
|
80
|
+
|
|
81
|
+
- step: API_KEY_MISSING
|
|
82
|
+
run:
|
|
83
|
+
- say: "⚠️ **WARNING: API KEY MISSING!** ⚠️"
|
|
84
|
+
- say: "I can't fetch market data without a `STOCKS_API_KEY`."
|
|
85
|
+
- say: "You can get a free API key from AlphaVantage. [Get Key Here](https://www.alphavantage.co/support/#api-key)."
|
|
86
|
+
- say: "Just put a random email and they give you the key instantly! 📧"
|
|
87
|
+
- say: "Then put the key in keys section at the bottom of [src/ambiance/stocks-air/resources.ts](file://src/ambiance/stocks-air/resources.ts)."
|
|
88
|
+
- say: "Just refresh the screen when you're done, I'll wait here (like I have a choice)! ⏳"
|
|
89
|
+
- wait: air_success
|
|
90
|
+
air: stocks-air
|
|
91
|
+
- do: toggle_task
|
|
92
|
+
label: "check Apple stock price"
|
|
93
|
+
- goto: CONVERT
|
|
94
|
+
|
|
95
|
+
- step: CONVERT
|
|
96
|
+
run:
|
|
97
|
+
- say: "Impressive numbers! Now let's fulfill that conversion task."
|
|
98
|
+
- say: 'Tell me: "Convert Apple stock price to Euro".'
|
|
99
|
+
- wait: air_success
|
|
100
|
+
air: currency-air
|
|
101
|
+
onError: FIX_BUG
|
|
102
|
+
- goto: FINAL_MANUAL
|
|
103
|
+
|
|
104
|
+
- step: FIX_BUG
|
|
105
|
+
run:
|
|
106
|
+
- say: "❌ **ERROR: REFUSED CONNECTION!** ❌"
|
|
107
|
+
- say: "Something is wrong with the currency service..."
|
|
108
|
+
- say: "I found a bug in the source code! Open [src/ambiance/currency-air/logic.ts](file://src/ambiance/currency-air/logic.ts) immediately."
|
|
109
|
+
- say: "You'll see I'm hardcoding `dollar.json` instead of using the proper URL from resources!"
|
|
110
|
+
- say: "**Fix it:** Replace the hardcoded path with `resources.api.currency.rates.config.url` and save!"
|
|
111
|
+
- wait: air_success
|
|
112
|
+
air: currency-air
|
|
113
|
+
- goto: FINAL_MANUAL
|
|
114
|
+
|
|
115
|
+
- step: FINAL_MANUAL
|
|
116
|
+
run:
|
|
117
|
+
- say: "Great job! Working together makes the dream work."
|
|
118
|
+
- say: "Let me help you wrap up the starter tasks."
|
|
119
|
+
- do: toggle_task
|
|
120
|
+
label: "loading Aura"
|
|
121
|
+
- do: toggle_task
|
|
122
|
+
label: "move tasks to space"
|
|
123
|
+
- do: toggle_task
|
|
124
|
+
label: "check Apple stock price"
|
|
125
|
+
- say: "All tasks completed! 🎉"
|
|
126
|
+
- do: confetti
|
|
127
|
+
- goto: COMPLETION
|
|
128
|
+
|
|
129
|
+
- step: COMPLETION
|
|
130
|
+
run:
|
|
131
|
+
- say: "Success! You fixed the code. You're a pro now."
|
|
132
|
+
- say: "Aura developer training is complete. 🎓"
|
|
133
|
+
- say: "Go build something amazing. 🎉"
|
|
134
|
+
- goto: DONE
|
|
135
|
+
|
|
136
|
+
- step: DONE
|
|
137
|
+
run: []
|