create-caspian-app 0.4.0-rc.5 → 0.4.0-rc.7
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/.github/copilot-instructions.md +2 -2
- package/dist/AGENTS.md +143 -0
- package/dist/settings/bs-config.ts +29 -14
- package/package.json +1 -1
|
@@ -35,7 +35,7 @@ This is the top architectural requirement for this workspace. Treat it as a hard
|
|
|
35
35
|
- For current repo behavior, trust `main.py`, `src/lib/**`, `public/js/**`, `prisma/**`, and `src/app/**` over generic Caspian docs.
|
|
36
36
|
- For framework internals, trust `.venv/Lib/site-packages/casp/**` over generic or older upstream guidance.
|
|
37
37
|
- When packaged docs conflict with project code or installed runtime, the project code, `caspian.config.json`, and installed runtime win. Keep the packaged docs feature-oriented and point AI back to the project files that decide actual enablement and behavior.
|
|
38
|
-
- When `prisma/schema.prisma` changes, follow this order: run `npx prisma migrate dev`; if the change affects seed flow or `prisma/seed.ts`, run `npx prisma generate` and then `npx prisma db seed`; then run `npx ppy generate` so the Python ORM stays aligned with the schema.
|
|
38
|
+
- When `prisma/schema.prisma` changes, follow this order: run `npx prisma migrate dev`; if the change affects seed flow or `prisma/seed.ts`, run `npx prisma generate` and then consider `npx prisma db seed`; then run `npx ppy generate` so the Python ORM stays aligned with the schema. Treat `npx prisma db seed` as a destructive data operation: it may clean tables and replace existing records, including production data if pointed at the wrong database. Before running it, tell the user exactly which command you intend to run, explain that it can delete or overwrite database data, confirm the current datasource when practical, and wait for the user's explicit approval.
|
|
39
39
|
- Reuse the existing Python database layer in `src/lib/prisma/**`; do not create a second app-owned database abstraction unless the user explicitly asks for one.
|
|
40
40
|
- When `caspian.config.json` has `prisma: true`, all Python-side database reads and writes must go through the generated Prisma Python ORM exposed from `src/lib/prisma/**`. Do not bypass it with ad hoc sqlite/postgres drivers, hand-written fetch helpers, JSON files as active stores, browser-side database fetches, or custom HTTP endpoints that reinvent the ORM. Use raw SQL only through Prisma as a narrow fallback when the generated ORM cannot express the query clearly.
|
|
41
41
|
- Treat `src/lib/prisma/__init__.py`, `src/lib/prisma/db.py`, `src/lib/prisma/models.py`, and `settings/prisma-schema.json` as generated outputs owned by `npx ppy generate`; do not create or hand-edit them manually.
|
|
@@ -161,7 +161,7 @@ This is the top architectural requirement for this workspace. Treat it as a hard
|
|
|
161
161
|
- Treat `prisma/schema.prisma` as the data-model source of truth.
|
|
162
162
|
- Treat `prisma.config.ts` as the datasource and migration or seed configuration source of truth.
|
|
163
163
|
- After changing `prisma/schema.prisma`, run `npx prisma migrate dev` first so migrations and the development database stay aligned.
|
|
164
|
-
- If the schema change affects seed data or `prisma/seed.ts`, run `npx prisma generate
|
|
164
|
+
- If the schema change affects seed data or `prisma/seed.ts`, run `npx prisma generate`, then ask for explicit user approval before running `npx prisma db seed` because the seed script may delete or replace table data.
|
|
165
165
|
- Run `npx ppy generate` after every schema change so the Python ORM files and `settings/prisma-schema.json` stay aligned with Prisma.
|
|
166
166
|
- Keep Node-side generation and seeding aligned with `npx prisma generate` and `prisma/seed.ts`.
|
|
167
167
|
- Keep Python-side database access aligned with `src/lib/prisma/**`, and treat that directory as generated output rather than a manual editing surface.
|
package/dist/AGENTS.md
CHANGED
|
@@ -67,6 +67,7 @@ Use `.github/copilot-instructions.md` for the repo-wide implementation rules. Th
|
|
|
67
67
|
- Use `node_modules/caspian-utils/dist/docs/websockets.md` when the task names WebSockets, live bidirectional channels, socket origin checks, socket auth/session behavior, broadcast managers, or native browser `WebSocket` clients.
|
|
68
68
|
- Use `node_modules/caspian-utils/dist/docs/file-conventions.md` when the task asks what belongs in `index.html`, `index.py`, `layout.html`, `layout.py`, `loading.html`, `not-found.html`, or `error.html`.
|
|
69
69
|
- When `caspian.config.json` has `prisma: true`, database reads and writes from Python routes, layouts, RPC actions, upload flows, auth flows, and helpers must use the generated Prisma Python ORM in `src/lib/prisma/**`. Do not create a separate database fetch layer with raw drivers, hand-written SQL helpers, JSON manifests, app-specific HTTP fetches, or browser-side data fetches to replace the ORM. Use raw SQL only as a narrow Prisma ORM fallback when the generated client cannot express a query clearly.
|
|
70
|
+
- Treat `npx prisma db seed` as a delicate, potentially destructive operation. In this workspace, seed scripts may clear tables before inserting fresh records. Before running that command, an AI agent must propose the exact command, warn that it can delete or overwrite database data including production data if the datasource is wrong, confirm the datasource when practical, and wait for explicit user approval.
|
|
70
71
|
- Component-first page composition is the highest-priority authoring rule for this workspace (see `.github/copilot-instructions.md`). Build pages as a short assembly of `x-*` chunk components (top menu, sidebar, header, content sections, cards, forms, footer) and keep each chunk's long markup inside its own single-file `html(...)` component, so `src/app/**/index.html` stays small instead of holding a wall of HTML. Plan the chunk breakdown before writing the route, not as a later cleanup pass.
|
|
71
72
|
- Components may be authored as a single Python file. Import `html` from `casp.component_decorator` and return `html("""...""", **context)` to keep markup, server interpolation, and a PulsePoint `<script>` inline, instead of pairing the `.py` with a same-name `.html` through `render_html(...)`. Inside `html(...)`, `{{ ... }}` is server-side Jinja and `{ ... }` stays for PulsePoint; do not use a Python f-string for the markup. Prefer single-file `html(...)` for small and medium components and keep `render_html(...)` plus a `.html` file for large markup or long scripts. Both forms render identically through `transform_components(...)` then `transform_scripts(...)`. See `node_modules/caspian-utils/dist/docs/components.md`.
|
|
72
73
|
- For component-to-component composition, prefer real Python imports over `<!-- @import ... -->` comments inside single-file components. A component's own `x-*` tags resolve from the components imported into its Python module, which disambiguates same-name components across directories. Resolution precedence inside a component's output is inherited ancestor components, then the component's own Python imports, then a local `@import` in that same template. Slot content (children) resolves in the scope where it was authored, so the component that writes an `x-*` tag in markup must import that component.
|
|
@@ -132,3 +133,145 @@ Before merging doc or runtime changes:
|
|
|
132
133
|
2. Update the matching packaged doc in `node_modules/caspian-utils/dist/docs/` if the running behavior changed.
|
|
133
134
|
3. Update `.github/copilot-instructions.md` if the repo-wide implementation rules changed.
|
|
134
135
|
4. Update this file if the decision order, task routing, workspace clarifications, or packaged-doc maintenance rules changed.
|
|
136
|
+
|
|
137
|
+
<!-- maddex:start -->
|
|
138
|
+
# Maddex AI Context
|
|
139
|
+
|
|
140
|
+
This project uses `maddex` to generate reusable Python UI component modules.
|
|
141
|
+
|
|
142
|
+
- Config file: maddex.json
|
|
143
|
+
- Maddex instructions file: .github/instructions/maddex.instructions.md
|
|
144
|
+
- Components directory: src/lib/maddex
|
|
145
|
+
- Configured Python source path: src/lib/maddex
|
|
146
|
+
- Suggested module path: src.lib.maddex
|
|
147
|
+
- Tailwind CSS file: src/app/globals.css
|
|
148
|
+
- Icon library: ppicons
|
|
149
|
+
- Installed component count: 57
|
|
150
|
+
- Installed component inventory and project metadata: `maddex.json` (under `manifest`)
|
|
151
|
+
|
|
152
|
+
## Installing Components
|
|
153
|
+
|
|
154
|
+
When a requested UI component does not exist yet, install it with `maddex` instead of hand-writing generated component modules.
|
|
155
|
+
|
|
156
|
+
- Add one component: `npx maddex add <component-name>`
|
|
157
|
+
- Add multiple components: `npx maddex add <component-a> <component-b>`
|
|
158
|
+
- Add the full catalogue: `npx maddex add --all`
|
|
159
|
+
- Refresh installed components: `npx maddex update`
|
|
160
|
+
|
|
161
|
+
## Discovering Available Components
|
|
162
|
+
|
|
163
|
+
Use the Maddex catalogue API to find component names before installing them.
|
|
164
|
+
|
|
165
|
+
- Fetch all available components: `GET https://maddex.tsnc.tech/cli?component=all`
|
|
166
|
+
- Fetch one component by name: `GET https://maddex.tsnc.tech/cli?component=Button`
|
|
167
|
+
- The `component=all` endpoint returns a JSON array of component names.
|
|
168
|
+
- The single-component endpoint may return a `files` array for multi-file components or a legacy `content` string for a single Python module.
|
|
169
|
+
|
|
170
|
+
Single component response example:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"name": "Button",
|
|
175
|
+
"files": [
|
|
176
|
+
{
|
|
177
|
+
"name": "Button.py",
|
|
178
|
+
"content": "class Button:\n ...generated Python source..."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "Button.html",
|
|
182
|
+
"content": "<button>...generated template...</button>"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Importing and Using Components
|
|
189
|
+
|
|
190
|
+
Use the installed Python module as the source for template `@import` comments, then copy the live docs example for the component you are rendering.
|
|
191
|
+
|
|
192
|
+
- Adjust the relative `@import` path to match the current file location.
|
|
193
|
+
- Maddex docs URLs use kebab-case component names such as `https://maddex.tsnc.tech/docs/button` and `https://maddex.tsnc.tech/docs/alert-dialog`.
|
|
194
|
+
- For any installed component, derive the docs page as `https://maddex.tsnc.tech/docs/<component-kebab-name>`.
|
|
195
|
+
|
|
196
|
+
Button example:
|
|
197
|
+
|
|
198
|
+
```html
|
|
199
|
+
<!-- @import { Button } from ../../../../lib/maddex/Button.py -->
|
|
200
|
+
|
|
201
|
+
<div class="flex w-full flex-wrap items-center justify-center gap-3">
|
|
202
|
+
<x-button>Default</x-button>
|
|
203
|
+
<x-button variant="secondary">Secondary</x-button>
|
|
204
|
+
<x-button variant="destructive">Destructive</x-button>
|
|
205
|
+
<x-button variant="outline">Outline</x-button>
|
|
206
|
+
<x-button variant="ghost">Ghost</x-button>
|
|
207
|
+
<x-button variant="link">Link</x-button>
|
|
208
|
+
</div>
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Installed Components
|
|
212
|
+
|
|
213
|
+
- Accordion: `src/lib/maddex/Accordion.py` (docs: `https://maddex.tsnc.tech/docs/accordion`)
|
|
214
|
+
- Alert: `src/lib/maddex/Alert.py` (docs: `https://maddex.tsnc.tech/docs/alert`)
|
|
215
|
+
- AlertDialog: `src/lib/maddex/AlertDialog.py` (docs: `https://maddex.tsnc.tech/docs/alert-dialog`)
|
|
216
|
+
- AspectRatio: `src/lib/maddex/AspectRatio.py` (docs: `https://maddex.tsnc.tech/docs/aspect-ratio`)
|
|
217
|
+
- Avatar: `src/lib/maddex/Avatar.py` (docs: `https://maddex.tsnc.tech/docs/avatar`)
|
|
218
|
+
- Badge: `src/lib/maddex/Badge.py` (docs: `https://maddex.tsnc.tech/docs/badge`)
|
|
219
|
+
- Breadcrumb: `src/lib/maddex/Breadcrumb.py` (docs: `https://maddex.tsnc.tech/docs/breadcrumb`)
|
|
220
|
+
- Button: `src/lib/maddex/Button.py` (docs: `https://maddex.tsnc.tech/docs/button`)
|
|
221
|
+
- ButtonGroup: `src/lib/maddex/ButtonGroup.py` (docs: `https://maddex.tsnc.tech/docs/button-group`)
|
|
222
|
+
- Calendar: `src/lib/maddex/Calendar.py` (docs: `https://maddex.tsnc.tech/docs/calendar`)
|
|
223
|
+
- Card: `src/lib/maddex/Card.py` (docs: `https://maddex.tsnc.tech/docs/card`)
|
|
224
|
+
- Carousel: `src/lib/maddex/Carousel.py` (docs: `https://maddex.tsnc.tech/docs/carousel`)
|
|
225
|
+
- Chart: `src/lib/maddex/Chart.py` (docs: `https://maddex.tsnc.tech/docs/chart`)
|
|
226
|
+
- Checkbox: `src/lib/maddex/Checkbox.py` (docs: `https://maddex.tsnc.tech/docs/checkbox`)
|
|
227
|
+
- Collapsible: `src/lib/maddex/Collapsible.py` (docs: `https://maddex.tsnc.tech/docs/collapsible`)
|
|
228
|
+
- Combobox: `src/lib/maddex/Combobox.py` (docs: `https://maddex.tsnc.tech/docs/combobox`)
|
|
229
|
+
- Command: `src/lib/maddex/Command.py` (docs: `https://maddex.tsnc.tech/docs/command`)
|
|
230
|
+
- ContextMenu: `src/lib/maddex/ContextMenu.py` (docs: `https://maddex.tsnc.tech/docs/context-menu`)
|
|
231
|
+
- DataTable: `src/lib/maddex/DataTable.py` (docs: `https://maddex.tsnc.tech/docs/data-table`)
|
|
232
|
+
- DatePicker: `src/lib/maddex/DatePicker.py` (docs: `https://maddex.tsnc.tech/docs/date-picker`)
|
|
233
|
+
- Dialog: `src/lib/maddex/Dialog.py` (docs: `https://maddex.tsnc.tech/docs/dialog`)
|
|
234
|
+
- Drawer: `src/lib/maddex/Drawer.py` (docs: `https://maddex.tsnc.tech/docs/drawer`)
|
|
235
|
+
- DropdownMenu: `src/lib/maddex/DropdownMenu.py` (docs: `https://maddex.tsnc.tech/docs/dropdown-menu`)
|
|
236
|
+
- Editor: `src/lib/maddex/Editor.py` (docs: `https://maddex.tsnc.tech/docs/editor`)
|
|
237
|
+
- Empty: `src/lib/maddex/Empty.py` (docs: `https://maddex.tsnc.tech/docs/empty`)
|
|
238
|
+
- Field: `src/lib/maddex/Field.py` (docs: `https://maddex.tsnc.tech/docs/field`)
|
|
239
|
+
- HoverCard: `src/lib/maddex/HoverCard.py` (docs: `https://maddex.tsnc.tech/docs/hover-card`)
|
|
240
|
+
- Input: `src/lib/maddex/Input.py` (docs: `https://maddex.tsnc.tech/docs/input`)
|
|
241
|
+
- InputGroup: `src/lib/maddex/InputGroup.py` (docs: `https://maddex.tsnc.tech/docs/input-group`)
|
|
242
|
+
- InputOTP: `src/lib/maddex/InputOTP.py` (docs: `https://maddex.tsnc.tech/docs/input-otp`)
|
|
243
|
+
- Item: `src/lib/maddex/Item.py` (docs: `https://maddex.tsnc.tech/docs/item`)
|
|
244
|
+
- Kbd: `src/lib/maddex/Kbd.py` (docs: `https://maddex.tsnc.tech/docs/kbd`)
|
|
245
|
+
- Label: `src/lib/maddex/Label.py` (docs: `https://maddex.tsnc.tech/docs/label`)
|
|
246
|
+
- Menubar: `src/lib/maddex/Menubar.py` (docs: `https://maddex.tsnc.tech/docs/menubar`)
|
|
247
|
+
- NavigationMenu: `src/lib/maddex/NavigationMenu.py` (docs: `https://maddex.tsnc.tech/docs/navigation-menu`)
|
|
248
|
+
- Popover: `src/lib/maddex/Popover.py` (docs: `https://maddex.tsnc.tech/docs/popover`)
|
|
249
|
+
- Portal: `src/lib/maddex/Portal.py` (docs: `https://maddex.tsnc.tech/docs/portal`)
|
|
250
|
+
- Radio: `src/lib/maddex/Radio.py` (docs: `https://maddex.tsnc.tech/docs/radio`)
|
|
251
|
+
- RadioGroup: `src/lib/maddex/RadioGroup.py` (docs: `https://maddex.tsnc.tech/docs/radio-group`)
|
|
252
|
+
- Resizable: `src/lib/maddex/Resizable.py` (docs: `https://maddex.tsnc.tech/docs/resizable`)
|
|
253
|
+
- ScrollArea: `src/lib/maddex/ScrollArea.py` (docs: `https://maddex.tsnc.tech/docs/scroll-area`)
|
|
254
|
+
- Select: `src/lib/maddex/Select.py` (docs: `https://maddex.tsnc.tech/docs/select`)
|
|
255
|
+
- Separator: `src/lib/maddex/Separator.py` (docs: `https://maddex.tsnc.tech/docs/separator`)
|
|
256
|
+
- Sheet: `src/lib/maddex/Sheet.py` (docs: `https://maddex.tsnc.tech/docs/sheet`)
|
|
257
|
+
- Sidebar: `src/lib/maddex/Sidebar.py` (docs: `https://maddex.tsnc.tech/docs/sidebar`)
|
|
258
|
+
- Skeleton: `src/lib/maddex/Skeleton.py` (docs: `https://maddex.tsnc.tech/docs/skeleton`)
|
|
259
|
+
- Slider: `src/lib/maddex/Slider.py` (docs: `https://maddex.tsnc.tech/docs/slider`)
|
|
260
|
+
- Slot: `src/lib/maddex/Slot.py` (docs: `https://maddex.tsnc.tech/docs/slot`)
|
|
261
|
+
- Switch: `src/lib/maddex/Switch.py` (docs: `https://maddex.tsnc.tech/docs/switch`)
|
|
262
|
+
- Table: `src/lib/maddex/Table.py` (docs: `https://maddex.tsnc.tech/docs/table`)
|
|
263
|
+
- Tabs: `src/lib/maddex/Tabs.py` (docs: `https://maddex.tsnc.tech/docs/tabs`)
|
|
264
|
+
- Textarea: `src/lib/maddex/Textarea.py` (docs: `https://maddex.tsnc.tech/docs/textarea`)
|
|
265
|
+
- Toast: `src/lib/maddex/Toast.py` (docs: `https://maddex.tsnc.tech/docs/toast`)
|
|
266
|
+
- Toggle: `src/lib/maddex/Toggle.py` (docs: `https://maddex.tsnc.tech/docs/toggle`)
|
|
267
|
+
- ToggleGroup: `src/lib/maddex/ToggleGroup.py` (docs: `https://maddex.tsnc.tech/docs/toggle-group`)
|
|
268
|
+
- Tooltip: `src/lib/maddex/Tooltip.py` (docs: `https://maddex.tsnc.tech/docs/tooltip`)
|
|
269
|
+
- utils: `src/lib/maddex/utils.py` (docs: `https://maddex.tsnc.tech/docs/utils`)
|
|
270
|
+
|
|
271
|
+
## Usage Notes
|
|
272
|
+
|
|
273
|
+
- Generated Python files follow this pattern: `src/lib/maddex/<ComponentName>.py`
|
|
274
|
+
- Prefer the configured module path `src.lib.maddex` when the host project exposes that package path for imports.
|
|
275
|
+
- Some components may include sidecar template or asset files next to the main Python module.
|
|
276
|
+
- Manual content outside this managed block is preserved.
|
|
277
|
+
<!-- maddex:end -->
|
|
@@ -154,6 +154,21 @@ function getExternalIP(): string | null {
|
|
|
154
154
|
return null;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
// All reload triggers funnel through this single debounced worker so that a
|
|
158
|
+
// multi-file save (or several watchers firing for one edit) collapses into a
|
|
159
|
+
// single browser reload instead of a cascade of reloads.
|
|
160
|
+
const reloader = new DebouncedWorker(
|
|
161
|
+
() => {
|
|
162
|
+
if (bs.active) bs.reload();
|
|
163
|
+
},
|
|
164
|
+
500,
|
|
165
|
+
"bs-reload",
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
function requestReload(reason?: string) {
|
|
169
|
+
reloader.schedule(reason);
|
|
170
|
+
}
|
|
171
|
+
|
|
157
172
|
const pipeline = new DebouncedWorker(
|
|
158
173
|
async () => {
|
|
159
174
|
const changedFile = lastChangedFile;
|
|
@@ -172,8 +187,8 @@ const pipeline = new DebouncedWorker(
|
|
|
172
187
|
updateRouteFilesCache();
|
|
173
188
|
|
|
174
189
|
const isReady = await waitForPort(pythonPort);
|
|
175
|
-
if (isReady
|
|
176
|
-
|
|
190
|
+
if (isReady) {
|
|
191
|
+
requestReload("python restart");
|
|
177
192
|
} else {
|
|
178
193
|
console.error(
|
|
179
194
|
chalk.red("Warning: Server failed to start or timed out."),
|
|
@@ -208,16 +223,16 @@ const pipeline = new DebouncedWorker(
|
|
|
208
223
|
);
|
|
209
224
|
await restartPythonServer(pythonPort, bsPort);
|
|
210
225
|
const isReady = await waitForPort(pythonPort);
|
|
211
|
-
if (isReady
|
|
212
|
-
} else
|
|
213
|
-
|
|
226
|
+
if (isReady) requestReload("structure change");
|
|
227
|
+
} else {
|
|
228
|
+
requestReload("src change");
|
|
214
229
|
}
|
|
215
230
|
previousRouteFiles = routeFiles;
|
|
216
|
-
} else
|
|
217
|
-
|
|
231
|
+
} else {
|
|
232
|
+
requestReload("src change");
|
|
218
233
|
}
|
|
219
234
|
},
|
|
220
|
-
|
|
235
|
+
1200,
|
|
221
236
|
"bs-pipeline",
|
|
222
237
|
);
|
|
223
238
|
|
|
@@ -245,9 +260,9 @@ const publicPipeline = new DebouncedWorker(
|
|
|
245
260
|
console.log(
|
|
246
261
|
chalk.cyan("-> Public directory changed, reloading browser..."),
|
|
247
262
|
);
|
|
248
|
-
|
|
263
|
+
requestReload("public change");
|
|
249
264
|
},
|
|
250
|
-
|
|
265
|
+
1200,
|
|
251
266
|
"bs-public-pipeline",
|
|
252
267
|
);
|
|
253
268
|
|
|
@@ -327,8 +342,8 @@ async function shutdown(exitCode: number): Promise<void> {
|
|
|
327
342
|
sourceWatchers.push(
|
|
328
343
|
createSrcWatcher(viteFlagFile, {
|
|
329
344
|
onEvent: (ev) => {
|
|
330
|
-
if (ev === "change"
|
|
331
|
-
|
|
345
|
+
if (ev === "change") {
|
|
346
|
+
requestReload("vite build complete");
|
|
332
347
|
}
|
|
333
348
|
},
|
|
334
349
|
awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
|
|
@@ -344,7 +359,7 @@ async function shutdown(exitCode: number): Promise<void> {
|
|
|
344
359
|
if (_abs.includes("__pycache__")) return;
|
|
345
360
|
await restartPythonServer(pythonPort, bsPort);
|
|
346
361
|
const isReady = await waitForPort(pythonPort);
|
|
347
|
-
if (isReady
|
|
362
|
+
if (isReady) requestReload("utils change");
|
|
348
363
|
},
|
|
349
364
|
awaitWriteFinish: DEFAULT_AWF,
|
|
350
365
|
logPrefix: "watch-utils",
|
|
@@ -359,7 +374,7 @@ async function shutdown(exitCode: number): Promise<void> {
|
|
|
359
374
|
if (_abs.includes("__pycache__")) return;
|
|
360
375
|
await restartPythonServer(pythonPort, bsPort);
|
|
361
376
|
const isReady = await waitForPort(pythonPort);
|
|
362
|
-
if (isReady
|
|
377
|
+
if (isReady) requestReload("main.py change");
|
|
363
378
|
},
|
|
364
379
|
awaitWriteFinish: DEFAULT_AWF,
|
|
365
380
|
logPrefix: "watch-main",
|