@swissjs/swite 0.3.0

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.
Files changed (163) hide show
  1. package/.changeset/config.json +11 -0
  2. package/.github/workflows/ci.yml +59 -0
  3. package/.github/workflows/publish.yml +50 -0
  4. package/.github/workflows/release.yml +53 -0
  5. package/BUILD_ANALYSIS.md +89 -0
  6. package/BUILD_STRATEGY.md +75 -0
  7. package/CHANGELOG.md +53 -0
  8. package/DIRECTIVE.md +488 -0
  9. package/__tests__/css-extraction.test.ts +261 -0
  10. package/__tests__/css-injection-integration.test.ts +247 -0
  11. package/__tests__/css-middleware.test.ts +191 -0
  12. package/__tests__/import-rewriter-bug.test.ts +135 -0
  13. package/dist/builder.d.ts +36 -0
  14. package/dist/builder.d.ts.map +1 -0
  15. package/dist/builder.js +772 -0
  16. package/dist/cache/compilation-cache.d.ts +33 -0
  17. package/dist/cache/compilation-cache.d.ts.map +1 -0
  18. package/dist/cache/compilation-cache.js +130 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +85 -0
  22. package/dist/config-loader.d.ts +8 -0
  23. package/dist/config-loader.d.ts.map +1 -0
  24. package/dist/config-loader.js +40 -0
  25. package/dist/config.d.ts +29 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +7 -0
  28. package/dist/dev/pythonDevManager.d.ts +12 -0
  29. package/dist/dev/pythonDevManager.d.ts.map +1 -0
  30. package/dist/dev/pythonDevManager.js +85 -0
  31. package/dist/env.d.ts +19 -0
  32. package/dist/env.d.ts.map +1 -0
  33. package/dist/env.js +112 -0
  34. package/dist/handlers/base-handler.d.ts +21 -0
  35. package/dist/handlers/base-handler.d.ts.map +1 -0
  36. package/dist/handlers/base-handler.js +38 -0
  37. package/dist/handlers/js-handler.d.ts +10 -0
  38. package/dist/handlers/js-handler.d.ts.map +1 -0
  39. package/dist/handlers/js-handler.js +87 -0
  40. package/dist/handlers/mjs-handler.d.ts +8 -0
  41. package/dist/handlers/mjs-handler.d.ts.map +1 -0
  42. package/dist/handlers/mjs-handler.js +44 -0
  43. package/dist/handlers/node-module-handler.d.ts +16 -0
  44. package/dist/handlers/node-module-handler.d.ts.map +1 -0
  45. package/dist/handlers/node-module-handler.js +267 -0
  46. package/dist/handlers/ts-handler.d.ts +11 -0
  47. package/dist/handlers/ts-handler.d.ts.map +1 -0
  48. package/dist/handlers/ts-handler.js +120 -0
  49. package/dist/handlers/ui-handler.d.ts +12 -0
  50. package/dist/handlers/ui-handler.d.ts.map +1 -0
  51. package/dist/handlers/ui-handler.js +182 -0
  52. package/dist/handlers/uix-handler.d.ts +12 -0
  53. package/dist/handlers/uix-handler.d.ts.map +1 -0
  54. package/dist/handlers/uix-handler.js +135 -0
  55. package/dist/hmr.d.ts +20 -0
  56. package/dist/hmr.d.ts.map +1 -0
  57. package/dist/hmr.js +265 -0
  58. package/dist/import-rewriter.d.ts +3 -0
  59. package/dist/import-rewriter.d.ts.map +1 -0
  60. package/dist/import-rewriter.js +351 -0
  61. package/dist/index.d.ts +14 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +13 -0
  64. package/dist/middleware/hmr-routes.d.ts +12 -0
  65. package/dist/middleware/hmr-routes.d.ts.map +1 -0
  66. package/dist/middleware/hmr-routes.js +97 -0
  67. package/dist/middleware/middleware-setup.d.ts +23 -0
  68. package/dist/middleware/middleware-setup.d.ts.map +1 -0
  69. package/dist/middleware/middleware-setup.js +596 -0
  70. package/dist/middleware/static-files.d.ts +15 -0
  71. package/dist/middleware/static-files.d.ts.map +1 -0
  72. package/dist/middleware/static-files.js +585 -0
  73. package/dist/proxy/SwiteProxyError.d.ts +6 -0
  74. package/dist/proxy/SwiteProxyError.d.ts.map +1 -0
  75. package/dist/proxy/SwiteProxyError.js +9 -0
  76. package/dist/proxy/proxyToPython.d.ts +28 -0
  77. package/dist/proxy/proxyToPython.d.ts.map +1 -0
  78. package/dist/proxy/proxyToPython.js +66 -0
  79. package/dist/resolver/bare-import-resolver.d.ts +9 -0
  80. package/dist/resolver/bare-import-resolver.d.ts.map +1 -0
  81. package/dist/resolver/bare-import-resolver.js +363 -0
  82. package/dist/resolver/symlink-registry.d.ts +13 -0
  83. package/dist/resolver/symlink-registry.d.ts.map +1 -0
  84. package/dist/resolver/symlink-registry.js +98 -0
  85. package/dist/resolver/url-resolver.d.ts +11 -0
  86. package/dist/resolver/url-resolver.d.ts.map +1 -0
  87. package/dist/resolver/url-resolver.js +268 -0
  88. package/dist/resolver/workspace-package-resolver.d.ts +10 -0
  89. package/dist/resolver/workspace-package-resolver.d.ts.map +1 -0
  90. package/dist/resolver/workspace-package-resolver.js +185 -0
  91. package/dist/resolver.d.ts +17 -0
  92. package/dist/resolver.d.ts.map +1 -0
  93. package/dist/resolver.js +191 -0
  94. package/dist/router/file-router.d.ts +19 -0
  95. package/dist/router/file-router.d.ts.map +1 -0
  96. package/dist/router/file-router.js +114 -0
  97. package/dist/server.d.ts +22 -0
  98. package/dist/server.d.ts.map +1 -0
  99. package/dist/server.js +122 -0
  100. package/dist/utils/cdn-fallback.d.ts +14 -0
  101. package/dist/utils/cdn-fallback.d.ts.map +1 -0
  102. package/dist/utils/cdn-fallback.js +36 -0
  103. package/dist/utils/file-path-resolver.d.ts +9 -0
  104. package/dist/utils/file-path-resolver.d.ts.map +1 -0
  105. package/dist/utils/file-path-resolver.js +187 -0
  106. package/dist/utils/generate-import-map-cli.d.ts +3 -0
  107. package/dist/utils/generate-import-map-cli.d.ts.map +1 -0
  108. package/dist/utils/generate-import-map-cli.js +32 -0
  109. package/dist/utils/generate-import-map.d.ts +21 -0
  110. package/dist/utils/generate-import-map.d.ts.map +1 -0
  111. package/dist/utils/generate-import-map.js +119 -0
  112. package/dist/utils/package-finder.d.ts +24 -0
  113. package/dist/utils/package-finder.d.ts.map +1 -0
  114. package/dist/utils/package-finder.js +161 -0
  115. package/dist/utils/package-registry.d.ts +36 -0
  116. package/dist/utils/package-registry.d.ts.map +1 -0
  117. package/dist/utils/package-registry.js +159 -0
  118. package/dist/utils/workspace.d.ts +6 -0
  119. package/dist/utils/workspace.d.ts.map +1 -0
  120. package/dist/utils/workspace.js +65 -0
  121. package/docs/IMPORT_REWRITING.md +164 -0
  122. package/docs/IMPORT_REWRITING_TROUBLESHOOTING.md +139 -0
  123. package/docs/PATH_RESOLUTION_GUIDE.md +221 -0
  124. package/package.json +49 -0
  125. package/src/adapters/proxy/SwiteProxyError.ts +12 -0
  126. package/src/adapters/proxy/proxyToPython.ts +88 -0
  127. package/src/build-engine/builder.ts +960 -0
  128. package/src/cli.ts +109 -0
  129. package/src/config/config-loader.ts +46 -0
  130. package/src/config/config.ts +34 -0
  131. package/src/config/env.ts +98 -0
  132. package/src/dev-engine/handlers/base-handler.ts +68 -0
  133. package/src/dev-engine/handlers/js-handler.ts +134 -0
  134. package/src/dev-engine/handlers/mjs-handler.ts +65 -0
  135. package/src/dev-engine/handlers/node-module-handler.ts +339 -0
  136. package/src/dev-engine/handlers/ts-handler.ts +143 -0
  137. package/src/dev-engine/handlers/ui-handler.ts +105 -0
  138. package/src/dev-engine/handlers/uix-handler.ts +90 -0
  139. package/src/dev-engine/hmr/hmr-client-template.ts +122 -0
  140. package/src/dev-engine/hmr/hmr.ts +173 -0
  141. package/src/dev-engine/middleware/hmr-routes.ts +120 -0
  142. package/src/dev-engine/middleware/middleware-setup.ts +351 -0
  143. package/src/dev-engine/middleware/static-files.ts +728 -0
  144. package/src/dev-engine/pythonDevManager.ts +116 -0
  145. package/src/dev-engine/router/file-router.ts +164 -0
  146. package/src/dev-engine/server.ts +152 -0
  147. package/src/index.ts +26 -0
  148. package/src/internal/cache/compilation-cache.ts +182 -0
  149. package/src/internal/generate-import-map-cli.ts +40 -0
  150. package/src/internal/generate-import-map.ts +154 -0
  151. package/src/kernel/package-finder.ts +164 -0
  152. package/src/kernel/package-registry.ts +198 -0
  153. package/src/kernel/workspace.ts +62 -0
  154. package/src/resolution/bare-import-resolver.ts +400 -0
  155. package/src/resolution/cdn/cdn-fallback.ts +37 -0
  156. package/src/resolution/path/file-path-resolver.ts +190 -0
  157. package/src/resolution/path/path-fixup.ts +19 -0
  158. package/src/resolution/resolver.ts +198 -0
  159. package/src/resolution/rewriting/import-rewriter.ts +237 -0
  160. package/src/resolution/symlink-registry.ts +114 -0
  161. package/src/resolution/url-resolver.ts +231 -0
  162. package/src/resolution/workspace-package-resolver.ts +94 -0
  163. package/tsconfig.json +37 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@changesets/config/schema.json",
3
+ "changelog": "@changesets/cli/changelog",
4
+ "commit": false,
5
+ "fixed": [],
6
+ "linked": [],
7
+ "access": "public",
8
+ "baseBranch": "main",
9
+ "updateInternalDependencies": "patch",
10
+ "ignore": []
11
+ }
@@ -0,0 +1,59 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ci-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ build-and-test:
15
+ name: Build & Test
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v4
20
+
21
+ - name: Setup pnpm
22
+ uses: pnpm/action-setup@v4
23
+ with:
24
+ version: 10
25
+
26
+ - name: Setup Node
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 18
30
+ cache: pnpm
31
+
32
+ - name: Install dependencies
33
+ run: pnpm install --frozen-lockfile
34
+
35
+ - name: Build
36
+ run: pnpm build
37
+
38
+ - name: Test
39
+ run: pnpm test
40
+
41
+ changeset-check:
42
+ name: Changeset check
43
+ runs-on: ubuntu-latest
44
+ if: github.event_name == 'pull_request'
45
+ steps:
46
+ - name: Checkout
47
+ uses: actions/checkout@v4
48
+ with:
49
+ fetch-depth: 0
50
+
51
+ - name: Check for changeset
52
+ run: |
53
+ git fetch origin main --quiet
54
+ ADDED=$(git diff --name-only --diff-filter=A origin/main HEAD -- '.changeset/*.md' | grep -v README | wc -l)
55
+ if [ "$ADDED" -eq 0 ]; then
56
+ echo "::warning::No changeset added in this PR. Run 'pnpm changeset' if this PR includes publishable changes."
57
+ else
58
+ echo "Changeset found ($ADDED file(s))."
59
+ fi
@@ -0,0 +1,50 @@
1
+ name: Publish (manual)
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ dry_run:
7
+ description: Dry run (list packages without publishing)
8
+ type: boolean
9
+ default: true
10
+
11
+ permissions:
12
+ contents: write
13
+
14
+ jobs:
15
+ publish:
16
+ name: Publish to npm
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Setup pnpm
23
+ uses: pnpm/action-setup@v4
24
+ with:
25
+ version: 10
26
+
27
+ - name: Setup Node
28
+ uses: actions/setup-node@v4
29
+ with:
30
+ node-version: 18
31
+ cache: pnpm
32
+ registry-url: https://registry.npmjs.org
33
+
34
+ - name: Install dependencies
35
+ run: pnpm install --frozen-lockfile
36
+
37
+ - name: Build
38
+ run: pnpm build
39
+
40
+ - name: Publish
41
+ if: ${{ !inputs.dry_run }}
42
+ run: pnpm publish --access public --no-git-checks
43
+ env:
44
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
45
+
46
+ - name: Dry run (show package info)
47
+ if: ${{ inputs.dry_run }}
48
+ run: |
49
+ echo "=== DRY RUN — package that would be published ==="
50
+ node -e "const p = require('./package.json'); console.log(p.name + '@' + p.version);"
@@ -0,0 +1,53 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ concurrency:
8
+ group: release-${{ github.ref }}
9
+ cancel-in-progress: false
10
+
11
+ permissions:
12
+ contents: write
13
+ pull-requests: write
14
+
15
+ jobs:
16
+ release:
17
+ name: Release
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - name: Checkout
21
+ uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+
25
+ - name: Setup pnpm
26
+ uses: pnpm/action-setup@v4
27
+ with:
28
+ version: 10
29
+
30
+ - name: Setup Node
31
+ uses: actions/setup-node@v4
32
+ with:
33
+ node-version: 18
34
+ cache: pnpm
35
+ registry-url: https://registry.npmjs.org
36
+
37
+ - name: Install dependencies
38
+ run: pnpm install --frozen-lockfile
39
+
40
+ - name: Build
41
+ run: pnpm build
42
+
43
+ - name: Create Release PR or Publish
44
+ uses: changesets/action@v1
45
+ with:
46
+ version: pnpm release:version
47
+ publish: pnpm release:publish
48
+ commit: "chore: version packages"
49
+ title: "chore: version packages"
50
+ createGithubReleases: true
51
+ env:
52
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
53
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,89 @@
1
+ # Build System Analysis
2
+
3
+ > **Note:** Alpine and skltn have been removed from the monorepo. Sections below that reference them are kept for historical context.
4
+
5
+ ## Current State
6
+
7
+ ### Alpine App (removed)
8
+ - **Location**: `SwissEnterpriseRepo/apps/alpine/`
9
+ - **Build**: Uses SWISS CLI (`node ../../../SWISS/packages/cli/dist/index.js build`)
10
+ - **Status**: ✅ Correct - uses SWISS build system
11
+ - **Files**: `.uix`, `.ts`
12
+
13
+ ### skltn Package (removed)
14
+ - **Location**: `SwissEnterpriseRepo/lib/skltn/`
15
+ - **Build**: Uses `tsc` (plain TypeScript compiler) ❌
16
+ - **Status**: ❌ **WRONG** - has `.ui`/`.uix` files but uses plain TypeScript
17
+ - **Files**: `.ui`, `.uix`, `.ts`
18
+ - **Exports**: Point to `dist/` but package is never built
19
+ - **Issue**: `tsc` cannot compile `.ui`/`.uix` files
20
+
21
+ ### cart Package
22
+ - **Location**: `SwissEnterpriseRepo/packages/cart/`
23
+ - **Build**: Uses SWISS CLI ✅
24
+ - **Status**: ✅ Correct - uses SWISS build system
25
+ - **Files**: `.ui`, `.uix`
26
+ - **Exports**: Point to source files (`./src/...`) ✅
27
+
28
+ ## Problems Identified
29
+
30
+ ### 1. skltn Build Configuration
31
+ **Current**:
32
+ ```json
33
+ {
34
+ "scripts": {
35
+ "build": "tsc", // ❌ Wrong - can't handle .ui/.uix
36
+ "dev": "tsc --watch"
37
+ },
38
+ "exports": {
39
+ "./shell": {
40
+ "import": "./dist/shell/index.js" // ❌ Points to dist but never built
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ **Should be**:
47
+ ```json
48
+ {
49
+ "scripts": {
50
+ "build": "node ../../../SWISS/packages/cli/dist/index.js build",
51
+ "dev": "node ../../../SWISS/packages/cli/dist/index.js dev"
52
+ },
53
+ "exports": {
54
+ "./shell": "./src/shell/index.ui" // ✅ Point to source (like cart)
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 2. skltn Source File Imports
60
+ **Current** (`src/index.ui`):
61
+ ```typescript
62
+ export * from './shell/index.js'; // ❌ Points to .js but file is .ui
63
+ ```
64
+
65
+ **Should be**:
66
+ ```typescript
67
+ export * from './shell/index.ui'; // ✅ Point to actual file
68
+ ```
69
+
70
+ ### 3. Missing tsconfig.json
71
+ - skltn has no `tsconfig.json`
72
+ - SWISS CLI build needs it for TypeScript compilation
73
+
74
+ ## Required Fixes
75
+
76
+ 1. **Update skltn package.json**:
77
+ - Change build script to use SWISS CLI
78
+ - Update exports to point to source files (like cart)
79
+
80
+ 2. **Fix skltn source imports**:
81
+ - Change `.js` imports to `.ui`/`.uix` in source files
82
+
83
+ 3. **Add tsconfig.json to skltn**:
84
+ - Create proper TypeScript config for SWISS build
85
+
86
+ 4. **Build skltn**:
87
+ - Run build to generate dist/ if needed
88
+ - OR keep exports pointing to source (recommended for dev)
89
+
@@ -0,0 +1,75 @@
1
+ # SWITE Build Strategy - Unified Builder
2
+
3
+ > **Note:** Alpine and skltn have been removed from the monorepo. References below are historical.
4
+
5
+ ## Goal
6
+ **ONE builder (SWITE) that builds the entire app including all workspace dependencies in a single pass.**
7
+
8
+ ## Current State
9
+
10
+ ### Dev Server (SWITE Server)
11
+ - ✅ Compiles `.ui`/`.uix` files on-the-fly when requested
12
+ - ✅ Resolves workspace packages via ModuleResolver
13
+ - ✅ Works for development
14
+
15
+ ### Production Builder (SWITE Builder)
16
+ - ❌ Only compiles files in app's `src/` directory
17
+ - ❌ Does NOT compile workspace dependencies
18
+ - ❌ Marks dependencies as `external` (not bundled)
19
+ - ❌ Dependencies must be pre-built separately
20
+
21
+ ## Required Strategy
22
+
23
+ ### Single-Pass Build Flow
24
+
25
+ ```
26
+ Build app
27
+
28
+ 1. Discover workspace dependencies
29
+ - @swiss-package/* (e.g. ai-agents, event-bus)
30
+
31
+ 2. Compile ALL .ui/.uix files (app + dependencies)
32
+ - App: src/**/*.{ui,uix}
33
+ - Workspace packages as resolved
34
+
35
+ 3. Bundle everything together
36
+ - OR serve from compiled locations
37
+ ```
38
+
39
+ ## Implementation Plan
40
+
41
+ ### Option A: Bundle Everything (Recommended)
42
+ - Compile all dependencies to temp directory
43
+ - Bundle app + dependencies into single output
44
+ - All workspace packages included in bundle
45
+
46
+ ### Option B: Compile & Link
47
+ - Compile each dependency to its own location
48
+ - Bundle app with references to compiled deps
49
+ - Runtime resolution to compiled files
50
+
51
+ ### Option C: Dev Mode (Current)
52
+ - Compile on-the-fly when requested
53
+ - Works for dev, but not for production
54
+
55
+ ## Key Changes Needed
56
+
57
+ 1. **Discover Dependencies**
58
+ - Parse app's package.json dependencies
59
+ - Filter for workspace packages
60
+ - Resolve their locations
61
+
62
+ 2. **Compile Dependencies**
63
+ - Find all .ui/.uix files in dependency packages
64
+ - Compile them to JavaScript
65
+ - Store in temp or output location
66
+
67
+ 3. **Bundle Strategy**
68
+ - Include dependencies in bundle (Option A)
69
+ - OR reference compiled dependencies (Option B)
70
+
71
+ 4. **Module Resolution**
72
+ - During build, resolve workspace packages
73
+ - Include their compiled files in bundle
74
+ - Handle import rewriting
75
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ ## 0.2.31
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix workspace node_modules static serving for pnpm virtual-store symlinks: replace fs.access+express.static with realpathSync+res.sendFile so CSS and other assets resolve correctly in Railway/pnpm deployments
8
+
9
+ ## 0.2.29 — 2026-04-23
10
+
11
+ ### Fixes
12
+
13
+ - SPA fallback now serves HTML only for requests with `Accept: text/html`.
14
+ This prevents module/script/style fetches from receiving HTML (strict MIME failures) in production.
15
+
16
+ ## 0.2.28 — 2026-04-23
17
+
18
+ ### Fixes
19
+
20
+ - Fix pnpm `node_modules` static serving: avoid `path.join(..., req.path)` resetting the root when `req.path` is absolute.
21
+ This restores serving of CSS assets under `/node_modules/*` in production deploys (e.g. Railway).
22
+
23
+ ## 0.2.27 — 2026-04-23
24
+
25
+ ### Fixes
26
+
27
+ - Disable jsDelivr `+esm` fallback for scoped packages by default to avoid 404s for private registries.
28
+ Use `SWITE_CDN_FALLBACK_SCOPES` to opt in specific public scopes when needed.
29
+
30
+ ## 0.2.0 — 2026-03-26
31
+
32
+ ### Bug Fixes
33
+
34
+ - **CG-01** — CLI entry hardcoded as `.ts`; now resolves `.ui` correctly (`src/cli.ts` line 76)
35
+ - **CG-02** — `@swissjs/*` and `@skltn/*` packages were bundled instead of left as browser imports; added to externals in `src/builder.ts`
36
+ - **CG-03** — `findSwissFiles`/`findFiles` did not follow NTFS junctions; added `isSymbolicLink()` check to directory traversal
37
+ - **CG-04** — Traversal entered `node_modules` via symlinks; `node_modules` now excluded from junction traversal
38
+ - **CG-05** — `UiCompiler` rewrites `.ui` imports to `.js` but emits `.tsx` files; added `jsTsxFallbackPlugin` to resolve `.js` → `.tsx` when `.tsx` exists
39
+ - **CG-06** — Compiler emits named exports only; `export default` now injected post-compile when a named export is detected
40
+
41
+ All fixes were discovered during the alpine-mobile Phase 5 build and initially applied as hotfixes to `dist/`. This release ports them properly to `src/`.
42
+
43
+ ## 0.1.0 — 2026-03-02
44
+
45
+ Initial release. Core dev server functional. Python service integration scaffolded.
46
+
47
+ - `SwiteServer` — Express-based dev server with HMR
48
+ - `SwiteBuilder` — esbuild-based production bundler
49
+ - `swiss.config.ts` — `defineConfig` schema including `services.python` block
50
+ - `proxyToPython<T>()` — typed internal proxy utility
51
+ - `startPythonDevService` / `stopPythonDevService` — CLI dev process manager
52
+ - `swite dev` / `swite build` / `swite start` commands
53
+ - CI/CD pipeline via GitHub Actions (ci.yml, release.yml, publish.yml)