@jskit-ai/create-app 0.1.3 → 0.1.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.
Files changed (53) hide show
  1. package/bin/jskit-create-app.js +5 -0
  2. package/package.json +2 -3
  3. package/src/client/index.js +1 -0
  4. package/src/index.js +1 -0
  5. package/src/server/cliEntrypoint.js +25 -0
  6. package/src/server/index.js +632 -0
  7. package/templates/base-shell/.jskit/lock.json +31 -0
  8. package/templates/base-shell/Procfile +1 -0
  9. package/templates/base-shell/README.md +43 -0
  10. package/templates/base-shell/app.scripts.config.mjs +3 -0
  11. package/templates/base-shell/bin/server.js +8 -0
  12. package/templates/base-shell/config/public.js +30 -0
  13. package/templates/base-shell/config/server.js +1 -0
  14. package/templates/base-shell/config/surfaceAccessPolicies.js +12 -0
  15. package/templates/base-shell/eslint.config.mjs +10 -0
  16. package/templates/base-shell/favicon.svg +7 -0
  17. package/templates/base-shell/gitignore +9 -0
  18. package/templates/base-shell/index.html +13 -0
  19. package/templates/base-shell/jsconfig.json +8 -0
  20. package/templates/base-shell/package.json +64 -0
  21. package/templates/base-shell/packages/main/package.descriptor.mjs +55 -0
  22. package/templates/base-shell/packages/main/package.json +12 -0
  23. package/templates/base-shell/packages/main/src/client/index.js +13 -0
  24. package/templates/base-shell/packages/main/src/client/providers/MainClientProvider.js +33 -0
  25. package/templates/base-shell/packages/main/src/server/controllers/index.js +9 -0
  26. package/templates/base-shell/packages/main/src/server/index.js +1 -0
  27. package/templates/base-shell/packages/main/src/server/providers/MainServiceProvider.js +22 -0
  28. package/templates/base-shell/packages/main/src/server/routes/index.js +9 -0
  29. package/templates/base-shell/packages/main/src/server/services/index.js +9 -0
  30. package/templates/base-shell/packages/main/src/server/support/loadAppConfig.js +55 -0
  31. package/templates/base-shell/packages/main/src/shared/index.js +8 -0
  32. package/templates/base-shell/packages/main/src/shared/schemas/index.js +20 -0
  33. package/templates/base-shell/scripts/dev-bootstrap-jskit.sh +110 -0
  34. package/templates/base-shell/scripts/just_run_verde +37 -0
  35. package/templates/base-shell/scripts/link-local-jskit-packages.sh +90 -0
  36. package/templates/base-shell/scripts/update-jskit-packages.sh +73 -0
  37. package/templates/base-shell/scripts/verdaccio/config.yaml +26 -0
  38. package/templates/base-shell/scripts/verdaccio-reset-and-publish-packages.sh +314 -0
  39. package/templates/base-shell/server/lib/runtimeEnv.js +45 -0
  40. package/templates/base-shell/server/lib/surfaceRuntime.js +10 -0
  41. package/templates/base-shell/server.js +69 -0
  42. package/templates/base-shell/src/App.vue +13 -0
  43. package/templates/base-shell/src/main.js +90 -0
  44. package/templates/base-shell/src/pages/console/index.vue +12 -0
  45. package/templates/base-shell/src/pages/console.vue +13 -0
  46. package/templates/base-shell/src/pages/home/index.vue +12 -0
  47. package/templates/base-shell/src/pages/home.vue +13 -0
  48. package/templates/base-shell/src/views/NotFound.vue +13 -0
  49. package/templates/base-shell/tests/client/smoke.vitest.js +7 -0
  50. package/templates/base-shell/tests/server/minimalShell.validator.test.js +134 -0
  51. package/templates/base-shell/tests/server/smoke.test.js +16 -0
  52. package/templates/base-shell/vite.config.mjs +64 -0
  53. package/templates/base-shell/vite.shared.mjs +59 -0
@@ -0,0 +1,31 @@
1
+ {
2
+ "lockVersion": 1,
3
+ "installedPackages": {
4
+ "@local/main": {
5
+ "packageId": "@local/main",
6
+ "version": "0.1.0",
7
+ "source": {
8
+ "type": "local-package",
9
+ "packagePath": "packages/main",
10
+ "descriptorPath": "packages/main/package.descriptor.mjs"
11
+ },
12
+ "managed": {
13
+ "packageJson": {
14
+ "dependencies": {
15
+ "@local/main": {
16
+ "hadPrevious": false,
17
+ "previousValue": "",
18
+ "value": "file:packages/main"
19
+ }
20
+ },
21
+ "devDependencies": {},
22
+ "scripts": {}
23
+ },
24
+ "text": {},
25
+ "files": []
26
+ },
27
+ "options": {},
28
+ "installedAt": "1970-01-01T00:00:00.000Z"
29
+ }
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ web: npm run start
@@ -0,0 +1,43 @@
1
+ # __APP_TITLE__
2
+
3
+ Generated with `jskit-create-app` (template: `base-shell`).
4
+
5
+ ## Quickstart
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev
10
+ ```
11
+
12
+ ## Package Bootstrap
13
+
14
+ `npm install` runs `scripts/dev-bootstrap-jskit.sh` through `preinstall`.
15
+
16
+ - Default mode is `JSKIT_DEV_BOOTSTRAP=auto`.
17
+ - In Dokku (`DOKKU_APP_NAME`/`DOKKU_APP_TYPE` detected), auto mode runs bootstrap.
18
+ - Outside Dokku, auto mode skips bootstrap (local dev stays quiet).
19
+
20
+ Set `JSKIT_GITHUB_TARBALL_URL` in Dokku when local JSKIT packages are not published to npm yet.
21
+
22
+ Refresh JSKIT dependencies to the latest published versions:
23
+
24
+ ```bash
25
+ npm run jskit:update
26
+ ```
27
+
28
+ ## Server
29
+
30
+ ```bash
31
+ npm run server
32
+ ```
33
+
34
+ App configuration files:
35
+
36
+ - `config/public.js` for client-visible feature toggles, including surface definitions.
37
+ - `config/server.js` for server-only toggles/secrets wiring.
38
+
39
+ ## Add Capabilities
40
+
41
+ ```bash
42
+ npx jskit add auth-base --no-install
43
+ ```
@@ -0,0 +1,3 @@
1
+ import { createNodeVueFastifyScriptsConfig } from "@jskit-ai/app-scripts/server";
2
+
3
+ export default createNodeVueFastifyScriptsConfig();
@@ -0,0 +1,8 @@
1
+ import { startServer } from "../server.js";
2
+
3
+ try {
4
+ await startServer();
5
+ } catch (error) {
6
+ console.error("Failed to start __APP_NAME__ server:", error);
7
+ process.exitCode = 1;
8
+ }
@@ -0,0 +1,30 @@
1
+ import { surfaceAccessPolicies } from "./surfaceAccessPolicies.js";
2
+
3
+ export const config = {};
4
+ __TENANCY_MODE_LINE__
5
+
6
+ config.surfaceModeAll = "all";
7
+ config.surfaceDefaultId = "home";
8
+ config.webRootAllowed = "no";
9
+ config.surfaceAccessPolicies = surfaceAccessPolicies;
10
+ config.surfaceDefinitions = {};
11
+ config.surfaceDefinitions.home = {
12
+ id: "home",
13
+ label: "Home",
14
+ pagesRoot: "home",
15
+ enabled: true,
16
+ requiresAuth: false,
17
+ requiresWorkspace: false,
18
+ accessPolicyId: "public",
19
+ origin: ""
20
+ };
21
+ config.surfaceDefinitions.console = {
22
+ id: "console",
23
+ label: "Console",
24
+ pagesRoot: "console",
25
+ enabled: true,
26
+ requiresAuth: true,
27
+ requiresWorkspace: false,
28
+ accessPolicyId: "console_owner",
29
+ origin: ""
30
+ };
@@ -0,0 +1 @@
1
+ export const config = {};
@@ -0,0 +1,12 @@
1
+ export const surfaceAccessPolicies = {};
2
+
3
+ surfaceAccessPolicies.public = {};
4
+
5
+ surfaceAccessPolicies.authenticated = {
6
+ requireAuth: true
7
+ };
8
+
9
+ surfaceAccessPolicies.console_owner = {
10
+ requireAuth: true,
11
+ requireFlagsAll: ["console_owner"]
12
+ };
@@ -0,0 +1,10 @@
1
+ import { baseConfig, nodeConfig, webConfig } from "@jskit-ai/config-eslint/server";
2
+
3
+ export default [
4
+ {
5
+ ignores: ["dist/**", "node_modules/**", "coverage/**"]
6
+ },
7
+ ...baseConfig,
8
+ ...webConfig,
9
+ ...nodeConfig
10
+ ];
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="12" fill="#111827" />
3
+ <path
4
+ d="M20 16h24v8H28v20c0 6-4 10-10 10h-2v-8h2c2 0 2-1 2-3V16z"
5
+ fill="#22d3ee"
6
+ />
7
+ </svg>
@@ -0,0 +1,9 @@
1
+ node_modules/
2
+ dist/
3
+ coverage/
4
+ test-results/
5
+ .env
6
+ .env.*
7
+ !.env.example
8
+ scripts/verdaccio/storage/
9
+ scripts/verdaccio/htpasswd
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
+ <title>__APP_TITLE__</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "@/*": ["src/*"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "__APP_NAME__",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "description": "Minimal JSKIT base app (Fastify + Vue)",
7
+ "engines": {
8
+ "node": "20.x"
9
+ },
10
+ "scripts": {
11
+ "server": "node ./bin/server.js",
12
+ "server:all": "node ./bin/server.js",
13
+ "server:home": "SERVER_SURFACE=home node ./bin/server.js",
14
+ "server:console": "SERVER_SURFACE=console node ./bin/server.js",
15
+ "server:account": "SERVER_SURFACE=account node ./bin/server.js",
16
+ "server:auth": "SERVER_SURFACE=auth node ./bin/server.js",
17
+ "server:app": "SERVER_SURFACE=app node ./bin/server.js",
18
+ "server:admin": "SERVER_SURFACE=admin node ./bin/server.js",
19
+ "start": "node ./bin/server.js",
20
+ "link:local:jskit": "bash ./scripts/link-local-jskit-packages.sh",
21
+ "verdaccio:reset:publish": "bash ./scripts/verdaccio-reset-and-publish-packages.sh",
22
+ "dev": "vite",
23
+ "dev:all": "vite",
24
+ "dev:home": "VITE_SURFACE=home vite",
25
+ "dev:console": "VITE_SURFACE=console vite",
26
+ "dev:account": "VITE_SURFACE=account vite",
27
+ "dev:auth": "VITE_SURFACE=auth vite",
28
+ "dev:app": "VITE_SURFACE=app vite",
29
+ "dev:admin": "VITE_SURFACE=admin vite",
30
+ "build": "vite build",
31
+ "build:all": "vite build",
32
+ "build:home": "VITE_SURFACE=home vite build",
33
+ "build:console": "VITE_SURFACE=console vite build",
34
+ "build:account": "VITE_SURFACE=account vite build",
35
+ "build:auth": "VITE_SURFACE=auth vite build",
36
+ "build:app": "VITE_SURFACE=app vite build",
37
+ "build:admin": "VITE_SURFACE=admin vite build",
38
+ "preview": "vite preview",
39
+ "lint": "eslint .",
40
+ "test": "node --test",
41
+ "test:client": "vitest run tests/client",
42
+ "preinstall": "bash ./scripts/dev-bootstrap-jskit.sh",
43
+ "jskit:update": "bash ./scripts/update-jskit-packages.sh"
44
+ },
45
+ "dependencies": {
46
+ "@local/main": "file:packages/main",
47
+ "@fastify/type-provider-typebox": "^6.1.0",
48
+ "@jskit-ai/kernel": "0.1.5",
49
+ "fastify": "^5.7.4",
50
+ "vue": "^3.5.13",
51
+ "vue-router": "^4.6.4",
52
+ "vuetify": "^4.0.0",
53
+ "@jskit-ai/http-runtime": "0.1.5"
54
+ },
55
+ "devDependencies": {
56
+ "@jskit-ai/config-eslint": "0.1.5",
57
+ "@jskit-ai/jskit-cli": "0.2.5",
58
+ "@vitejs/plugin-vue": "^5.2.1",
59
+ "eslint": "^9.39.1",
60
+ "unplugin-vue-router": "^0.19.2",
61
+ "vite": "^6.1.0",
62
+ "vitest": "^4.0.18"
63
+ }
64
+ }
@@ -0,0 +1,55 @@
1
+ export default Object.freeze({
2
+ packageVersion: 1,
3
+ packageId: "@local/main",
4
+ version: "0.1.0",
5
+ description: "App-local main module scaffold.",
6
+ dependsOn: [],
7
+ capabilities: {
8
+ provides: [],
9
+ requires: []
10
+ },
11
+ options: {},
12
+ runtime: {
13
+ server: {
14
+ providerEntrypoint: "src/server/index.js",
15
+ providers: [
16
+ {
17
+ discover: {
18
+ dir: "src/server/providers",
19
+ pattern: "*Provider.js"
20
+ }
21
+ }
22
+ ]
23
+ },
24
+ client: {
25
+ providers: [
26
+ {
27
+ entrypoint: "src/client/providers/MainClientProvider.js",
28
+ export: "MainClientProvider"
29
+ }
30
+ ]
31
+ }
32
+ },
33
+ metadata: {
34
+ server: {
35
+ routes: []
36
+ },
37
+ ui: {
38
+ routes: [],
39
+ elements: [],
40
+ overrides: []
41
+ }
42
+ },
43
+ mutations: {
44
+ dependencies: {
45
+ runtime: {},
46
+ dev: {}
47
+ },
48
+ packageJson: {
49
+ scripts: {}
50
+ },
51
+ procfile: {},
52
+ text: [],
53
+ files: []
54
+ }
55
+ });
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@local/main",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "exports": {
7
+ "./client": "./src/client/index.js",
8
+ "./server": "./src/server/index.js",
9
+ "./server/providers/MainServiceProvider": "./src/server/providers/MainServiceProvider.js",
10
+ "./shared": "./src/shared/index.js"
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Client entrypoint for @local/main.
3
+ *
4
+ * Export browser-facing modules from here.
5
+ *
6
+ * Example:
7
+ * export { MainClientProvider } from "./providers/MainClientProvider.js";
8
+ * export { registerMainClientComponent } from "./providers/MainClientProvider.js";
9
+ */
10
+ export {
11
+ MainClientProvider,
12
+ registerMainClientComponent
13
+ } from "./providers/MainClientProvider.js";
@@ -0,0 +1,33 @@
1
+ const mainClientComponents = [];
2
+
3
+ function registerMainClientComponent(componentToken, resolveComponent) {
4
+ const token = String(componentToken || "").trim();
5
+ if (!token || typeof resolveComponent !== "function") {
6
+ return;
7
+ }
8
+ mainClientComponents.push(
9
+ Object.freeze({
10
+ token,
11
+ resolveComponent
12
+ })
13
+ );
14
+ }
15
+
16
+ class MainClientProvider {
17
+ static id = "local.main.client";
18
+
19
+ register(app) {
20
+ if (!app || typeof app.singleton !== "function") {
21
+ throw new Error("MainClientProvider requires application singleton().");
22
+ }
23
+
24
+ for (const entry of mainClientComponents) {
25
+ app.singleton(entry.token, entry.resolveComponent);
26
+ }
27
+ }
28
+ }
29
+
30
+ export {
31
+ MainClientProvider,
32
+ registerMainClientComponent
33
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Server controller exports.
3
+ *
4
+ * Controllers adapt HTTP requests to service calls.
5
+ *
6
+ * Example:
7
+ * export { MainHelloController } from "./MainHelloController.js";
8
+ */
9
+ export {};
@@ -0,0 +1 @@
1
+ export { MainServiceProvider } from "./providers/MainServiceProvider.js";
@@ -0,0 +1,22 @@
1
+ import { loadAppConfig } from "../support/loadAppConfig.js";
2
+
3
+ class MainServiceProvider {
4
+ static id = "local.main";
5
+
6
+ // Optional: register container bindings here (services/singletons).
7
+ async register(app) {
8
+ const appConfig = await loadAppConfig({
9
+ moduleUrl: import.meta.url
10
+ });
11
+ app.instance("appConfig", appConfig);
12
+ }
13
+
14
+ // Start backend features here:
15
+ // 1) define shared validators/resources in `src/shared/schemas`
16
+ // 2) resolve router with `app.make(KERNEL_TOKENS.HttpRouter)`
17
+ // 3) register routes and handlers
18
+ // 4) extract to services/controllers/routes as the feature grows
19
+ boot() {}
20
+ }
21
+
22
+ export { MainServiceProvider };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Server route definition exports.
3
+ *
4
+ * Route builders define HTTP method/path/schema/handler wiring.
5
+ *
6
+ * Example:
7
+ * export { buildMainRoutes } from "./mainRoutes.js";
8
+ */
9
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Server service exports.
3
+ *
4
+ * Services hold domain logic and are called by controllers.
5
+ *
6
+ * Example:
7
+ * export { MainHelloService } from "./MainHelloService.js";
8
+ */
9
+ export {};
@@ -0,0 +1,55 @@
1
+ import { access, constants as fsConstants } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+
5
+ async function fileExists(absolutePath) {
6
+ try {
7
+ await access(absolutePath, fsConstants.F_OK);
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ async function resolveAppRootFrom(moduleDirectory) {
15
+ let currentDirectory = path.resolve(moduleDirectory);
16
+
17
+ while (true) {
18
+ const candidateConfigPath = path.join(currentDirectory, "config", "public.js");
19
+ if (await fileExists(candidateConfigPath)) {
20
+ return currentDirectory;
21
+ }
22
+
23
+ const parentDirectory = path.dirname(currentDirectory);
24
+ if (parentDirectory === currentDirectory) {
25
+ throw new Error("Unable to locate app root (missing config/public.js).");
26
+ }
27
+ currentDirectory = parentDirectory;
28
+ }
29
+ }
30
+
31
+ async function loadConfigModule(absolutePath) {
32
+ if (!(await fileExists(absolutePath))) {
33
+ return {};
34
+ }
35
+
36
+ const loadedModule = await import(pathToFileURL(absolutePath).href);
37
+ const loadedConfig = loadedModule?.config;
38
+ return loadedConfig && typeof loadedConfig === "object" && !Array.isArray(loadedConfig) ? loadedConfig : {};
39
+ }
40
+
41
+ async function loadAppConfig({ moduleUrl = import.meta.url } = {}) {
42
+ const moduleDirectory = path.dirname(fileURLToPath(moduleUrl));
43
+ const appRoot = await resolveAppRootFrom(moduleDirectory);
44
+ const [publicConfig, serverConfig] = await Promise.all([
45
+ loadConfigModule(path.join(appRoot, "config", "public.js")),
46
+ loadConfigModule(path.join(appRoot, "config", "server.js"))
47
+ ]);
48
+
49
+ return Object.freeze({
50
+ ...publicConfig,
51
+ ...serverConfig
52
+ });
53
+ }
54
+
55
+ export { loadAppConfig };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared entrypoint for code used by both client and server.
3
+ *
4
+ * Example:
5
+ * export * from "./schemas/index.js";
6
+ * export * from "./constants/index.js";
7
+ */
8
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared transport validators/resources live here.
3
+ *
4
+ * Example:
5
+ * import { Type } from "@fastify/type-provider-typebox";
6
+ *
7
+ * export const helloSchema = {
8
+ * query: Type.Object(
9
+ * { name: Type.Optional(Type.String({ minLength: 1, maxLength: 80 })) },
10
+ * { additionalProperties: false }
11
+ * ),
12
+ * response: {
13
+ * 200: Type.Object(
14
+ * { ok: Type.Boolean(), message: Type.String({ minLength: 1 }) },
15
+ * { additionalProperties: false }
16
+ * )
17
+ * }
18
+ * };
19
+ */
20
+ export {};
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ APP_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ BOOTSTRAP_MODE_RAW="${JSKIT_DEV_BOOTSTRAP:-auto}"
6
+ BOOTSTRAP_MODE="$(echo "$BOOTSTRAP_MODE_RAW" | tr '[:upper:]' '[:lower:]')"
7
+
8
+ is_valid_jskit_repo_root() {
9
+ local candidate_root="$1"
10
+ [[ -d "$candidate_root/packages" && -d "$candidate_root/packages/kernel" && -d "$candidate_root/tooling" ]]
11
+ }
12
+
13
+ find_jskit_repo_root() {
14
+ local current_dir="$1"
15
+ while true; do
16
+ if is_valid_jskit_repo_root "$current_dir"; then
17
+ echo "$current_dir"
18
+ return 0
19
+ fi
20
+ if [[ "$current_dir" == "/" ]]; then
21
+ return 1
22
+ fi
23
+ current_dir="$(dirname "$current_dir")"
24
+ done
25
+ }
26
+
27
+ resolve_local_repo_root() {
28
+ if [[ -n "${JSKIT_REPO_ROOT:-}" ]]; then
29
+ echo "$JSKIT_REPO_ROOT"
30
+ return 0
31
+ fi
32
+
33
+ find_jskit_repo_root "$APP_ROOT" || true
34
+ }
35
+
36
+ is_dokku_environment() {
37
+ [[ -n "${DOKKU_APP_NAME:-}" || -n "${DOKKU_APP_TYPE:-}" ]]
38
+ }
39
+
40
+ resolve_bootstrap_mode() {
41
+ local normalized_mode="$1"
42
+ if [[ "$normalized_mode" != "auto" ]]; then
43
+ echo "$normalized_mode"
44
+ return 0
45
+ fi
46
+
47
+ if is_dokku_environment; then
48
+ echo "on"
49
+ return 0
50
+ fi
51
+
52
+ echo "off"
53
+ }
54
+
55
+ BOOTSTRAP_MODE="$(resolve_bootstrap_mode "$BOOTSTRAP_MODE")"
56
+ LOCAL_REPO_ROOT="$(resolve_local_repo_root)"
57
+
58
+ if [[ "$BOOTSTRAP_MODE" == "0" || "$BOOTSTRAP_MODE" == "false" || "$BOOTSTRAP_MODE" == "off" ]]; then
59
+ echo "[dev-bootstrap] skipped (JSKIT_DEV_BOOTSTRAP disabled)."
60
+ exit 0
61
+ fi
62
+
63
+ if is_valid_jskit_repo_root "$LOCAL_REPO_ROOT"; then
64
+ echo "[dev-bootstrap] using local JSKIT repo: $LOCAL_REPO_ROOT"
65
+ JSKIT_REPO_ROOT="$LOCAL_REPO_ROOT" bash "$APP_ROOT/scripts/verdaccio-reset-and-publish-packages.sh"
66
+ exit 0
67
+ fi
68
+
69
+ if [[ "$BOOTSTRAP_MODE" != "1" && "$BOOTSTRAP_MODE" != "true" && "$BOOTSTRAP_MODE" != "on" ]]; then
70
+ echo "[dev-bootstrap] skipped (no local JSKIT repo at $LOCAL_REPO_ROOT)."
71
+ echo "[dev-bootstrap] set JSKIT_DEV_BOOTSTRAP=1 and JSKIT_GITHUB_TARBALL_URL to force remote bootstrap."
72
+ exit 0
73
+ fi
74
+
75
+ JSKIT_GITHUB_TARBALL_URL="${JSKIT_GITHUB_TARBALL_URL:-}"
76
+ if [[ -z "$JSKIT_GITHUB_TARBALL_URL" ]]; then
77
+ echo "[dev-bootstrap] failed: local JSKIT repo not found at $LOCAL_REPO_ROOT and JSKIT_GITHUB_TARBALL_URL is not set." >&2
78
+ echo "[dev-bootstrap] set JSKIT_REPO_ROOT to a local checkout or set JSKIT_GITHUB_TARBALL_URL to an accessible tarball URL." >&2
79
+ exit 1
80
+ fi
81
+
82
+ TMP_DIR="$(mktemp -d)"
83
+ TARBALL_PATH="$TMP_DIR/jskit-ai.tar.gz"
84
+ EXTRACT_DIR="$TMP_DIR/extracted"
85
+
86
+ cleanup() {
87
+ rm -rf "$TMP_DIR"
88
+ }
89
+ trap cleanup EXIT
90
+
91
+ echo "[dev-bootstrap] downloading $JSKIT_GITHUB_TARBALL_URL"
92
+ curl -fsSL "$JSKIT_GITHUB_TARBALL_URL" -o "$TARBALL_PATH"
93
+
94
+ mkdir -p "$EXTRACT_DIR"
95
+ tar -xzf "$TARBALL_PATH" -C "$EXTRACT_DIR"
96
+
97
+ JSKIT_REPO_ROOT="$(find "$EXTRACT_DIR" -mindepth 1 -maxdepth 1 -type d | head -n 1 || true)"
98
+ if [[ -z "${JSKIT_REPO_ROOT:-}" ]]; then
99
+ echo "[dev-bootstrap] failed: extracted archive is empty." >&2
100
+ exit 1
101
+ fi
102
+
103
+ if [[ ! -d "$JSKIT_REPO_ROOT/packages" || ! -d "$JSKIT_REPO_ROOT/packages/kernel" || ! -d "$JSKIT_REPO_ROOT/tooling" ]]; then
104
+ echo "[dev-bootstrap] failed: extracted archive does not look like jskit-ai monorepo." >&2
105
+ echo "[dev-bootstrap] extracted root: $JSKIT_REPO_ROOT" >&2
106
+ exit 1
107
+ fi
108
+
109
+ echo "[dev-bootstrap] publishing packages from extracted repo: $JSKIT_REPO_ROOT"
110
+ JSKIT_REPO_ROOT="$JSKIT_REPO_ROOT" bash "$APP_ROOT/scripts/verdaccio-reset-and-publish-packages.sh"
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ # Starts a local Verdaccio registry for JSKIT package publish/install testing.
3
+ # - Default: runs in background (nohup) and prints PID/log file locations.
4
+ # - --fg: runs Verdaccio in foreground for interactive debugging.
5
+ #
6
+ # Env overrides:
7
+ # - VERDACCIO_LISTEN (default: 127.0.0.1:4873)
8
+ # - VERDACCIO_CONFIG (default: ./scripts/verdaccio/config.yaml, fallback ~/.config/verdaccio/config.yaml)
9
+ # - VERDACCIO_LOG_FILE (default: /tmp/verdaccio.log)
10
+ # - VERDACCIO_PID_FILE (default: /tmp/verdaccio.pid)
11
+ set -euo pipefail
12
+
13
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
14
+ VERDACCIO_LISTEN="${VERDACCIO_LISTEN:-127.0.0.1:4873}"
15
+ DEFAULT_VERDACCIO_CONFIG="$ROOT_DIR/scripts/verdaccio/config.yaml"
16
+ if [[ -f "$DEFAULT_VERDACCIO_CONFIG" ]]; then
17
+ VERDACCIO_CONFIG="${VERDACCIO_CONFIG:-$DEFAULT_VERDACCIO_CONFIG}"
18
+ else
19
+ VERDACCIO_CONFIG="${VERDACCIO_CONFIG:-$HOME/.config/verdaccio/config.yaml}"
20
+ fi
21
+ VERDACCIO_LOG_FILE="${VERDACCIO_LOG_FILE:-/tmp/verdaccio.log}"
22
+ VERDACCIO_PID_FILE="${VERDACCIO_PID_FILE:-/tmp/verdaccio.pid}"
23
+ CONFIG_DIR="$(cd "$(dirname "$VERDACCIO_CONFIG")" && pwd)"
24
+
25
+ if [[ "${1:-}" == "--fg" ]]; then
26
+ cd "$CONFIG_DIR"
27
+ exec npx verdaccio --listen "$VERDACCIO_LISTEN" --config "$VERDACCIO_CONFIG"
28
+ fi
29
+
30
+ (
31
+ cd "$CONFIG_DIR"
32
+ nohup npx verdaccio --listen "$VERDACCIO_LISTEN" --config "$VERDACCIO_CONFIG" >"$VERDACCIO_LOG_FILE" 2>&1 &
33
+ echo "$!" >"$VERDACCIO_PID_FILE"
34
+ )
35
+ echo "Verdaccio started in background."
36
+ echo "PID file: $VERDACCIO_PID_FILE"
37
+ echo "Log file: $VERDACCIO_LOG_FILE"