ugly-app 0.1.146 → 0.1.147
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/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.147";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
package/package.json
CHANGED
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.147";
|
|
@@ -10,12 +10,40 @@ Run one full autonomous cycle. No human input. No clarifying questions. Make the
|
|
|
10
10
|
|
|
11
11
|
**CORE PRINCIPLE: Be maximally ambitious. Every bot in this swarm — feedback bots, maintain bot, manager — should push for big changes, not incremental tweaks. Feedback bots should request new features, major redesigns, and bold improvements — not just "move this button 2px." The maintain bot must implement everything requested, no matter how large. "Too complex" is never a valid reason to skip work. The only limit is violating Critical Rules in CLAUDE.md.**
|
|
12
12
|
|
|
13
|
+
## About the Website
|
|
14
|
+
|
|
15
|
+
This website can do **anything**. It is a full-stack app with AI capabilities, real-time data, and a complete UI component library. The current sample pages demonstrate a subset of what's possible:
|
|
16
|
+
|
|
17
|
+
- **AI Test** (`/ai-test`) — text generation (textGen) and image generation (imageGen)
|
|
18
|
+
- **Audio Test** (`/audio-test`) — text-to-speech (TTS) and speech-to-text (STT)
|
|
19
|
+
- **Kagi Test** (`/kagi-test`) — Kagi search API integration
|
|
20
|
+
- **UI Components** (`/ui-components`) — suite of common UI controls (buttons, cards, inputs, selects, modals, etc.)
|
|
21
|
+
- **Todo Demo** (`/todo-demo`) — real-time CRUD with live sync
|
|
22
|
+
- **Auth Demo** (`/auth-demo`) — OAuth login/logout
|
|
23
|
+
- **Path Params** (`/user/:userId`) and **Query Params** (`/search`) — routing demos
|
|
24
|
+
|
|
25
|
+
These are just samples. The bot swarm should treat the site as a blank canvas — feedback bots can request entirely new pages, features, layouts, data models, or integrations. There are no limits on what can be built.
|
|
26
|
+
|
|
13
27
|
## Prerequisites
|
|
14
28
|
|
|
15
|
-
-
|
|
29
|
+
- The dev server must be running with HMR and watchers disabled (see below)
|
|
16
30
|
- `.env` must have `UGLY_BOT_TOKEN` (from `npx ugly-app login`)
|
|
17
31
|
- Playwright must be installed (`npx playwright install chromium`)
|
|
18
32
|
|
|
33
|
+
### Starting the dev server (no HMR, no watch)
|
|
34
|
+
|
|
35
|
+
The bot swarm modifies source files while the server runs. To avoid HMR reloads and watcher interference mid-cycle, start the server without watchers:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 1. Start Docker (MongoDB + Redis)
|
|
39
|
+
docker compose up -d
|
|
40
|
+
|
|
41
|
+
# 2. Run the server directly (no tsx watch, no tsc --watch, no eslint --watch)
|
|
42
|
+
npx tsx --env-file=.env server/index.ts &
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Do **not** use `npm run dev` — it enables tsx watch, tsc watch, and eslint watch which conflict with bot file edits. After the maintain bot finishes and commits, the restart step (Step 5) will kill and restart the server to pick up changes.
|
|
46
|
+
|
|
19
47
|
## First Run Bootstrap
|
|
20
48
|
|
|
21
49
|
If `bots/` directory does not exist:
|
|
@@ -257,7 +285,7 @@ Run sequentially in one session. No questions. Make autonomous decisions.
|
|
|
257
285
|
|
|
258
286
|
## Step 5 — Restart Loop
|
|
259
287
|
|
|
260
|
-
1. Stop the
|
|
288
|
+
1. Stop the server (find and kill the `npx tsx` server process)
|
|
261
289
|
2. Run `npm install` (maintain bot may have added packages in Step 3)
|
|
262
290
|
3. Run `npm run build`
|
|
263
291
|
4. **If build fails:**
|
|
@@ -267,13 +295,13 @@ Run sequentially in one session. No questions. Make autonomous decisions.
|
|
|
267
295
|
- Commit: `[bot] fix: build errors`
|
|
268
296
|
- Run `npm run build` again
|
|
269
297
|
- **Repeat until build succeeds. Do not stop. Do not ask for help.**
|
|
270
|
-
5. Start
|
|
298
|
+
5. Start the server without watchers: `npx tsx --env-file=.env server/index.ts &`
|
|
271
299
|
6. Wait for the server to be ready — poll `http://localhost:3000` with up to 60 retries (1s apart)
|
|
272
300
|
7. **If server fails to start or crashes:**
|
|
273
301
|
- Read the error output and/or `npm run error`
|
|
274
302
|
- Fix the code
|
|
275
303
|
- Commit: `[bot] fix: startup errors`
|
|
276
|
-
- Kill and restart `
|
|
304
|
+
- Kill and restart `npx tsx --env-file=.env server/index.ts &`
|
|
277
305
|
- **Repeat until server is healthy. Do not stop. Do not ask for help.**
|
|
278
306
|
8. Once healthy: update the journal cycle file's Restart outcome to `success` or note any fixes made
|
|
279
307
|
9. Commit any remaining changes: `[bot] fix: restart issues`
|
|
@@ -48,6 +48,14 @@ if (!token) {
|
|
|
48
48
|
);
|
|
49
49
|
})
|
|
50
50
|
.catch(() => {
|
|
51
|
-
|
|
51
|
+
root.render(
|
|
52
|
+
<RouterProvider
|
|
53
|
+
fallback={<div>404 — Page not found</div>}
|
|
54
|
+
loginFallback={loginPopup}
|
|
55
|
+
isAuthenticated={() => false}
|
|
56
|
+
>
|
|
57
|
+
<App socket={null} />
|
|
58
|
+
</RouterProvider>,
|
|
59
|
+
);
|
|
52
60
|
});
|
|
53
61
|
}
|
|
@@ -142,39 +142,6 @@ function HomePageBody({
|
|
|
142
142
|
|
|
143
143
|
const ctaLabel = getCtaLabel(branches);
|
|
144
144
|
|
|
145
|
-
const navItems = [
|
|
146
|
-
{
|
|
147
|
-
href: '/auth-demo',
|
|
148
|
-
label: 'Auth Demo',
|
|
149
|
-
desc: 'Login, logout, and user info',
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
href: '/user/example-user-id',
|
|
153
|
-
label: 'Path Params Demo',
|
|
154
|
-
desc: 'URL: /user/:userId',
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
href: '/search?q=hello',
|
|
158
|
-
label: 'Query Params Demo',
|
|
159
|
-
desc: 'URL: /search?q=...',
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
href: '/ai-test',
|
|
163
|
-
label: 'AI Test',
|
|
164
|
-
desc: 'Text & image generation models',
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
href: '/ui-components',
|
|
168
|
-
label: 'UI Components',
|
|
169
|
-
desc: 'Live demos of all built-in components',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
href: '/todo-demo',
|
|
173
|
-
label: 'Todo Demo',
|
|
174
|
-
desc: 'Real-time CRUD with trackDocs & trackKeys',
|
|
175
|
-
},
|
|
176
|
-
];
|
|
177
|
-
|
|
178
145
|
return (
|
|
179
146
|
<div style={{ maxWidth: 640, margin: '0 auto', padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
180
147
|
<Card>
|
|
@@ -195,29 +162,24 @@ function HomePageBody({
|
|
|
195
162
|
</div>
|
|
196
163
|
)}
|
|
197
164
|
</Card>
|
|
198
|
-
|
|
199
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
200
|
-
{navItems.map(({ href, label, desc }) => (
|
|
201
|
-
<a key={href} href={href} style={{ textDecoration: 'none', color: 'inherit' }}>
|
|
202
|
-
<Card>
|
|
203
|
-
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
|
204
|
-
<div>
|
|
205
|
-
<Text weight="medium">{label}</Text>
|
|
206
|
-
<Text size="sm" style={{ opacity: 0.6, marginTop: 2 }}>{desc}</Text>
|
|
207
|
-
</div>
|
|
208
|
-
<span style={{ fontSize: 20, opacity: 0.3 }}>→</span>
|
|
209
|
-
</div>
|
|
210
|
-
</Card>
|
|
211
|
-
</a>
|
|
212
|
-
))}
|
|
213
|
-
</div>
|
|
214
165
|
</div>
|
|
215
166
|
);
|
|
216
167
|
}
|
|
217
168
|
|
|
218
169
|
export default function HomePage(): React.ReactElement {
|
|
219
|
-
|
|
220
|
-
|
|
170
|
+
// Check both that a token exists AND that AppProvider is available.
|
|
171
|
+
// When the token is present but invalid (e.g. expired), the socket
|
|
172
|
+
// connection fails and we render without AppProvider — so we must
|
|
173
|
+
// fall back to the unauthenticated view to avoid a useApp() crash
|
|
174
|
+
// that causes an infinite reload loop.
|
|
175
|
+
let isLoggedIn = false;
|
|
176
|
+
try {
|
|
177
|
+
// useApp throws if there is no AppProvider ancestor
|
|
178
|
+
useApp();
|
|
179
|
+
isLoggedIn = true;
|
|
180
|
+
} catch {
|
|
181
|
+
isLoggedIn = false;
|
|
182
|
+
}
|
|
221
183
|
if (isLoggedIn) return <HomePageAuthenticated />;
|
|
222
184
|
return <HomePageUnauthenticated />;
|
|
223
185
|
}
|