spine-framework 0.1.61 → 0.2.1

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.
@@ -67,13 +67,17 @@ function AuthenticatedRouter() {
67
67
  return (b.route_prefix?.length || 0) - (a.route_prefix?.length || 0)
68
68
  })
69
69
 
70
+ // When an app is mounted at root it owns all routes — suppress the
71
+ // framework's own /dashboard and catch-all 404 to avoid conflicts.
72
+ const hasRootApp = sorted.some(app => app.route_prefix === '/')
73
+
70
74
  return (
71
75
  <Suspense fallback={<div className="min-h-screen flex items-center justify-center"><LoadingSpinner /></div>}>
72
76
  <Routes>
73
- {/* Default redirect */}
74
- <Route path="/" element={<Navigate to="/dashboard" replace />} />
75
- <Route path="/dashboard" element={<DashboardPage />} />
76
-
77
+ {/* Default redirect — suppressed when a root app is installed */}
78
+ {!hasRootApp && <Route path="/" element={<Navigate to="/dashboard" replace />} />}
79
+ {!hasRootApp && <Route path="/dashboard" element={<DashboardPage />} />}
80
+
77
81
  {/* Login route for authenticated users (redirects to qualified app) */}
78
82
  <Route path="/login" element={<LoginPage />} />
79
83
 
@@ -85,12 +89,14 @@ function AuthenticatedRouter() {
85
89
  {/* Dynamic app routes */}
86
90
  {sorted.map(app => {
87
91
  const prefix = app.route_prefix!
92
+ // React Router v6: path="/*" does NOT work for root — must use path="*"
93
+ const routePath = prefix === '/' ? '*' : `${prefix}/*`
88
94
 
89
95
  if (app.renderer === 'custom') {
90
96
  return (
91
97
  <Route
92
98
  key={app.slug}
93
- path={`${prefix}/*`}
99
+ path={routePath}
94
100
  element={
95
101
  <AppWrapper app={app}>
96
102
  <CustomAppLoader slug={app.slug} />
@@ -104,7 +110,7 @@ function AuthenticatedRouter() {
104
110
  return (
105
111
  <Route
106
112
  key={app.slug}
107
- path={`${prefix}/*`}
113
+ path={routePath}
108
114
  element={
109
115
  <AppWrapper app={app}>
110
116
  <GenericAppShell app={app} />
@@ -117,7 +123,8 @@ function AuthenticatedRouter() {
117
123
  return null
118
124
  })}
119
125
 
120
- <Route path="*" element={<NotFoundPage />} />
126
+ {/* 404 — suppressed when a root app is installed (it handles its own not-found) */}
127
+ {!hasRootApp && <Route path="*" element={<NotFoundPage />} />}
121
128
  </Routes>
122
129
  </Suspense>
123
130
  )
@@ -57,7 +57,7 @@ class AppErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState>
57
57
  // Static glob maps — Vite analyzes these at build time and builds a complete
58
58
  // module map. Runtime lookup is just a map key lookup, no dynamic string eval.
59
59
  // Custom apps take precedence over core apps with the same slug.
60
- const customAppModules = import.meta.glob('../../../custom/apps/*/index.tsx')
60
+ const customAppModules = import.meta.glob('../../custom/apps/*/index.tsx')
61
61
  const coreAppModules = import.meta.glob('../apps/*/index.tsx')
62
62
 
63
63
  // Module-level cache for lazy components to avoid re-creating on each render
@@ -66,7 +66,7 @@ const appModuleCache = new Map<string, React.LazyExoticComponent<React.Component
66
66
  // Resolve the glob key for a given slug from the custom or core map.
67
67
  function resolveAppLoader(slug: string): (() => Promise<{ default: React.ComponentType }>) | null {
68
68
  // Check custom first (custom/apps/{slug}/index.tsx)
69
- const customKey = `../../../custom/apps/${slug}/index.tsx`
69
+ const customKey = `../../custom/apps/${slug}/index.tsx`
70
70
  if (customAppModules[customKey]) {
71
71
  return customAppModules[customKey] as () => Promise<{ default: React.ComponentType }>
72
72
  }
package/LICENSE.md ADDED
@@ -0,0 +1,18 @@
1
+ # Spine Framework Internal Use License 1.0.0
2
+
3
+ **Source-available. Free for internal use. Commercial rights reserved.**
4
+
5
+ Copyright © 2026 Dahl Ventures Inc. All rights reserved.
6
+
7
+ This license is based on the PolyForm Internal Use License 1.0.0, modified for Spine Framework.
8
+
9
+ ## Quick Summary
10
+
11
+ **You CAN:** Use Spine Framework inside your company for internal business operations.
12
+ **You CANNOT:** Sell it, offer it as SaaS, white-label it, distribute it, or use it to build competing products without a Commercial License.
13
+
14
+ ## Full Terms
15
+
16
+ See the complete license text at: https://spine-framework.com/license
17
+
18
+ For Commercial Licensing inquiries: webmaster@spine-framework.com
@@ -21,7 +21,6 @@ export default defineConfig({
21
21
  'vendor-react': ['react', 'react-dom', 'react-router-dom'],
22
22
  'vendor-supabase': ['@supabase/supabase-js'],
23
23
  'vendor-ui': ['lucide-react', 'clsx', 'tailwind-merge', 'class-variance-authority'],
24
- 'vendor-markdown': ['marked'],
25
24
  },
26
25
  },
27
26
  },
@@ -5,12 +5,17 @@
5
5
  "scripts": {
6
6
  "assemble": "bash node_modules/spine-framework/scripts/assemble.sh",
7
7
  "dev": "netlify dev",
8
- "build": "npm run assemble && netlify build",
8
+ "build": "npm run assemble && vite build --config node_modules/spine-framework/config/vite.config.ts",
9
9
  "preview": "netlify dev"
10
10
  },
11
11
  "dependencies": {
12
- "spine-framework": "^0.1.0",
12
+ "spine-framework": "^0.2.0",
13
13
  "@tanstack/react-query": "^5.0.0",
14
+ "react": "^18.3.0",
15
+ "react-dom": "^18.3.0",
16
+ "react-router-dom": "^6.28.0",
17
+ "@netlify/functions": "^2.0.0",
18
+ "react-is": "^18.3.0",
14
19
  "lucide-react": "^0.400.0",
15
20
  "clsx": "^2.0.0",
16
21
  "tailwind-merge": "^2.0.0",
@@ -54,6 +59,8 @@
54
59
  "highlight.js": "^11.11.1"
55
60
  },
56
61
  "devDependencies": {
62
+ "@types/react": "^18.3.0",
63
+ "@types/react-dom": "^18.3.0",
57
64
  "vite": "^6.4.3",
58
65
  "@vitejs/plugin-react": "^4.0.0",
59
66
  "tailwindcss": "^3.4.0",
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "spine-framework",
3
- "version": "0.1.61",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "description": "Spine — enterprise application framework built on Supabase + Netlify + React",
6
6
  "type": "module",
7
- "license": "MIT",
7
+ "license": "SEE LICENSE IN LICENSE.md",
8
8
  "keywords": [
9
9
  "spine",
10
10
  "framework",
@@ -14,13 +14,13 @@
14
14
  "enterprise",
15
15
  "agentic"
16
16
  ],
17
- "homepage": "https://github.com/art-mojo-admin/spine#readme",
17
+ "homepage": "https://github.com/spine-framework/spine-framework#readme",
18
18
  "bugs": {
19
- "url": "https://github.com/art-mojo-admin/spine/issues"
19
+ "url": "https://github.com/spine-framework/spine-framework/issues"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/art-mojo-admin/spine"
23
+ "url": "https://github.com/spine-framework/spine-framework"
24
24
  },
25
25
  "engines": {
26
26
  "node": ">=18.0.0"
@@ -61,7 +61,8 @@
61
61
  "index.html",
62
62
  "package-project.json",
63
63
  "STRUCTURE.md",
64
- "README.md"
64
+ "README.md",
65
+ "LICENSE.md"
65
66
  ],
66
67
  "scripts": {
67
68
  "spine-framework": "tsx .framework/cli/index.ts",
@@ -61,14 +61,11 @@ if [ -f "$PROJECT_ROOT/.framework/public/_redirects" ]; then
61
61
  echo " ✓ Core: _redirects copied to Vite-served directory for Netlify dev"
62
62
  fi
63
63
 
64
- # 6. Overlay custom src (overrides + additions)
64
+ # 6. Copy custom/apps/ → .assembled/custom/apps/ (preserves path for CustomAppLoader glob)
65
+ ASSEMBLED_CUSTOM_DIR="$PROJECT_ROOT/.assembled/custom/apps"
65
66
  if [ -d "$CUSTOM_SRC_DIR" ]; then
66
- # Copy files and subdirectories
67
- cp -r "$CUSTOM_SRC_DIR"/* "$TARGET_SRC_DIR"/ 2>/dev/null || true
68
-
69
- # Handle subdirectories properly
70
- find "$CUSTOM_SRC_DIR" -mindepth 1 -type d -exec sh -c 'dir="$1"; base=$(basename "$dir"); mkdir -p "'"$TARGET_SRC_DIR"'/$base" && cp -r "$dir"/* "'"$TARGET_SRC_DIR"'/$base/"' _ {} \; 2>/dev/null || true
71
-
67
+ mkdir -p "$ASSEMBLED_CUSTOM_DIR"
68
+ cp -r "$CUSTOM_SRC_DIR"/* "$ASSEMBLED_CUSTOM_DIR"/ 2>/dev/null || true
72
69
  CUSTOM_COUNT=$(find "$CUSTOM_SRC_DIR" -name '*.tsx' -o -name '*.ts' -o -name '*.css' 2>/dev/null | wc -l | tr -d ' ')
73
70
  echo " ✓ Custom: $CUSTOM_COUNT files"
74
71
  else