@jskit-ai/create-app 0.1.48 → 0.1.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/create-app",
3
- "version": "0.1.48",
3
+ "version": "0.1.50",
4
4
  "description": "Scaffold minimal JSKIT app shells.",
5
5
  "type": "module",
6
6
  "files": [
@@ -2,6 +2,7 @@ node_modules/
2
2
  dist/
3
3
  coverage/
4
4
  test-results/
5
+ .jskit/WORKBOARD.md
5
6
  .env
6
7
  .env.*
7
8
  !.env.example
@@ -12,7 +12,7 @@
12
12
  "server:all": "node ./bin/server.js",
13
13
  "server:home": "SERVER_SURFACE=home node ./bin/server.js",
14
14
  "start": "node ./bin/server.js",
15
- "devlinks": "bash ./scripts/link-local-jskit-packages.sh",
15
+ "devlinks": "jskit app link-local-packages",
16
16
  "dev": "vite",
17
17
  "dev:all": "vite",
18
18
  "dev:home": "VITE_SURFACE=home vite",
@@ -23,13 +23,13 @@
23
23
  "lint": "eslint .",
24
24
  "test": "node --test",
25
25
  "test:client": "vitest run tests/client",
26
- "verify": "npm run lint && npm run test && npm run test:client && npm run build && npx jskit doctor",
27
- "release": "bash ./scripts/release.sh",
28
- "jskit:update": "bash ./scripts/update-jskit-packages.sh"
26
+ "verify": "jskit app verify && npm run --if-present verify:app",
27
+ "release": "jskit app release",
28
+ "jskit:update": "jskit app update-packages"
29
29
  },
30
30
  "dependencies": {
31
31
  "@local/main": "file:packages/main",
32
- "@fastify/static": "^8.3.0",
32
+ "@fastify/static": "^9.1.1",
33
33
  "@fastify/type-provider-typebox": "^6.1.0",
34
34
  "@jskit-ai/kernel": "0.x",
35
35
  "fastify": "^5.7.4",
@@ -1,206 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Link all local @jskit-ai packages from a jskit-ai monorepo checkout into node_modules.
3
- # Run this AFTER `npm install` when you want live local development without publishing packages.
4
- #
5
- # Usage:
6
- # npm run link:local:jskit
7
- # JSKIT_REPO_ROOT=/abs/path/to/jskit-ai npm run link:local:jskit
8
- set -euo pipefail
9
-
10
- APP_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
11
- SCOPE_DIR="$APP_ROOT/node_modules/@jskit-ai"
12
- VITE_CACHE_DIR="$APP_ROOT/node_modules/.vite"
13
-
14
- is_valid_jskit_repo_root() {
15
- local candidate_root="$1"
16
- [[ -d "$candidate_root/packages" && -d "$candidate_root/packages/kernel" && -d "$candidate_root/tooling" ]]
17
- }
18
-
19
- to_absolute_dir() {
20
- local candidate_dir="$1"
21
- (cd "$candidate_dir" && pwd)
22
- }
23
-
24
- resolve_local_repo_root() {
25
- if [[ -n "${JSKIT_REPO_ROOT:-}" ]]; then
26
- if [[ -d "$JSKIT_REPO_ROOT" ]]; then
27
- to_absolute_dir "$JSKIT_REPO_ROOT"
28
- return 0
29
- fi
30
- echo "$JSKIT_REPO_ROOT"
31
- return 0
32
- fi
33
-
34
- local current_dir
35
- current_dir="$(dirname "$APP_ROOT")"
36
- while true; do
37
- local candidate_root="$current_dir/jskit-ai"
38
- if is_valid_jskit_repo_root "$candidate_root"; then
39
- to_absolute_dir "$candidate_root"
40
- return 0
41
- fi
42
- if [[ "$current_dir" == "/" ]]; then
43
- return 1
44
- fi
45
- current_dir="$(dirname "$current_dir")"
46
- done
47
- }
48
-
49
- JSKIT_REPO_ROOT="$(resolve_local_repo_root || true)"
50
-
51
- if [[ ! -d "$SCOPE_DIR" ]]; then
52
- echo "[link-local] @jskit-ai scope not found at $SCOPE_DIR (run npm install first)." >&2
53
- exit 1
54
- fi
55
-
56
- if [[ -z "$JSKIT_REPO_ROOT" ]]; then
57
- echo "[link-local] no JSKIT repository found." >&2
58
- echo "[link-local] set JSKIT_REPO_ROOT to a local jskit-ai checkout path." >&2
59
- exit 1
60
- fi
61
-
62
- if ! is_valid_jskit_repo_root "$JSKIT_REPO_ROOT"; then
63
- echo "[link-local] JSKIT_REPO_ROOT is not a valid jskit-ai checkout: $JSKIT_REPO_ROOT" >&2
64
- exit 1
65
- fi
66
-
67
- discover_local_package_map() {
68
- node - "$JSKIT_REPO_ROOT" <<'NODE'
69
- const fs = require("node:fs");
70
- const path = require("node:path");
71
-
72
- const repoRoot = process.argv[2];
73
- const parentDirectories = [
74
- path.join(repoRoot, "packages"),
75
- path.join(repoRoot, "tooling")
76
- ];
77
- const packageMap = new Map();
78
-
79
- for (const parentDirectory of parentDirectories) {
80
- if (!fs.existsSync(parentDirectory) || !fs.statSync(parentDirectory).isDirectory()) {
81
- continue;
82
- }
83
-
84
- for (const entry of fs.readdirSync(parentDirectory, { withFileTypes: true })) {
85
- if (!entry.isDirectory() || entry.name.startsWith(".")) {
86
- continue;
87
- }
88
-
89
- const packageRoot = path.join(parentDirectory, entry.name);
90
- const packageJsonPath = path.join(packageRoot, "package.json");
91
- if (!fs.existsSync(packageJsonPath)) {
92
- continue;
93
- }
94
-
95
- let packageJson = {};
96
- try {
97
- packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
98
- } catch {
99
- continue;
100
- }
101
-
102
- const packageId = String(packageJson?.name || "").trim();
103
- if (!packageId.startsWith("@jskit-ai/")) {
104
- continue;
105
- }
106
- const packageDirName = packageId.slice("@jskit-ai/".length);
107
- if (!packageDirName || packageDirName.includes("/")) {
108
- continue;
109
- }
110
-
111
- if (!packageMap.has(packageDirName)) {
112
- packageMap.set(packageDirName, packageRoot);
113
- }
114
- }
115
- }
116
-
117
- for (const [packageDirName, packageRoot] of packageMap.entries()) {
118
- process.stdout.write(`${packageDirName}\t${packageRoot}\n`);
119
- }
120
- NODE
121
- }
122
-
123
- link_package_bin_entries() {
124
- local package_dir_name="$1"
125
- local source_dir="$2"
126
-
127
- node - "$APP_ROOT" "$package_dir_name" "$source_dir" <<'NODE'
128
- const fs = require("node:fs");
129
- const path = require("node:path");
130
-
131
- const appRoot = process.argv[2];
132
- const packageDirName = process.argv[3];
133
- const sourceDir = process.argv[4];
134
-
135
- const packageJsonPath = path.join(sourceDir, "package.json");
136
- if (!fs.existsSync(packageJsonPath)) {
137
- process.exit(0);
138
- }
139
-
140
- let packageJson = {};
141
- try {
142
- packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
143
- } catch {
144
- process.exit(0);
145
- }
146
-
147
- const rawBin = packageJson?.bin;
148
- let binEntries = [];
149
- if (typeof rawBin === "string") {
150
- binEntries = [[packageDirName, rawBin]];
151
- } else if (rawBin && typeof rawBin === "object" && !Array.isArray(rawBin)) {
152
- binEntries = Object.entries(rawBin);
153
- }
154
-
155
- if (binEntries.length < 1) {
156
- process.exit(0);
157
- }
158
-
159
- const binDir = path.join(appRoot, "node_modules", ".bin");
160
- const packageRoot = path.join(appRoot, "node_modules", "@jskit-ai", packageDirName);
161
- fs.mkdirSync(binDir, { recursive: true });
162
-
163
- for (const [rawBinName, rawBinTarget] of binEntries) {
164
- const binName = String(rawBinName || "").trim();
165
- const binTarget = String(rawBinTarget || "").trim();
166
- if (!binName || !binTarget) {
167
- continue;
168
- }
169
-
170
- const absoluteTarget = path.join(packageRoot, binTarget);
171
- if (!fs.existsSync(absoluteTarget)) {
172
- continue;
173
- }
174
-
175
- const binPath = path.join(binDir, binName);
176
- fs.rmSync(binPath, { force: true, recursive: true });
177
-
178
- const relativeTarget = path.relative(binDir, absoluteTarget) || absoluteTarget;
179
- fs.symlinkSync(relativeTarget, binPath);
180
- process.stdout.write(`[link-local] linked bin ${binName} -> ${relativeTarget}\n`);
181
- }
182
- NODE
183
- }
184
-
185
- linked_count=0
186
-
187
- mkdir -p "$SCOPE_DIR"
188
- while IFS=$'\t' read -r package_dir_name source_dir; do
189
- if [[ -z "$package_dir_name" || -z "$source_dir" ]]; then
190
- continue
191
- fi
192
-
193
- target_path="$SCOPE_DIR/$package_dir_name"
194
- rm -rf "$target_path"
195
- ln -s "$source_dir" "$target_path"
196
- echo "[link-local] linked @jskit-ai/$package_dir_name -> $source_dir"
197
- link_package_bin_entries "$package_dir_name" "$source_dir"
198
- linked_count=$((linked_count + 1))
199
- done < <(discover_local_package_map)
200
-
201
- if [[ -d "$VITE_CACHE_DIR" ]]; then
202
- rm -rf "$VITE_CACHE_DIR"
203
- echo "[link-local] cleared Vite cache at $VITE_CACHE_DIR"
204
- fi
205
-
206
- echo "[link-local] done. linked=$linked_count"
@@ -1,95 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- APP_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
-
6
- require_command() {
7
- local name="$1"
8
- if ! command -v "$name" >/dev/null 2>&1; then
9
- echo "[release] required command not found: $name" >&2
10
- exit 1
11
- fi
12
- }
13
-
14
- ensure_clean_worktree() {
15
- if [[ -n "$(git status --porcelain)" ]]; then
16
- echo "[release] worktree is not clean. Commit/stash first." >&2
17
- exit 1
18
- fi
19
- }
20
-
21
- ensure_on_main() {
22
- local current_branch
23
- current_branch="$(git rev-parse --abbrev-ref HEAD)"
24
- if [[ "$current_branch" != "main" ]]; then
25
- echo "[release] current branch is \"$current_branch\". Switch to main first." >&2
26
- exit 1
27
- fi
28
- }
29
-
30
- main() {
31
- require_command git
32
- require_command npm
33
- require_command gh
34
-
35
- cd "$APP_ROOT"
36
-
37
- if ! gh auth status >/dev/null 2>&1; then
38
- echo "[release] gh is not authenticated. Run: gh auth login" >&2
39
- exit 1
40
- fi
41
-
42
- ensure_clean_worktree
43
- ensure_on_main
44
-
45
- echo "[release] syncing local main..."
46
- git fetch origin main
47
- git pull --ff-only origin main
48
-
49
- echo "[release] running package refresh..."
50
- npm run jskit:update
51
-
52
- if [[ -z "$(git status --porcelain)" ]]; then
53
- echo "[release] no changes produced by jskit:update. Nothing to release."
54
- exit 0
55
- fi
56
-
57
- local timestamp
58
- local pretty_time
59
- local branch
60
- local commit_message
61
- local pr_title
62
- local pr_url
63
-
64
- timestamp="$(date -u +%Y%m%d-%H%M%S)"
65
- pretty_time="$(date -u +'%Y-%m-%d %H:%M UTC')"
66
- branch="release/${timestamp}"
67
- commit_message="chore: release ${pretty_time}"
68
- pr_title="Release ${pretty_time}"
69
-
70
- echo "[release] creating branch ${branch}..."
71
- git checkout -b "$branch"
72
-
73
- git add -A
74
- git commit -m "$commit_message"
75
- git push -u origin "$branch"
76
-
77
- pr_url="$(
78
- gh pr create \
79
- --base main \
80
- --head "$branch" \
81
- --title "$pr_title" \
82
- --body "Automated release commit generated by \`npm run release\`."
83
- )"
84
-
85
- echo "[release] created PR: $pr_url"
86
- gh pr merge "$pr_url" --merge --delete-branch
87
-
88
- echo "[release] merged. syncing local main..."
89
- git checkout main
90
- git pull --ff-only origin main
91
-
92
- echo "[release] done."
93
- }
94
-
95
- main "$@"
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- APP_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
- PACKAGE_JSON_PATH="$APP_ROOT/package.json"
6
- JSKIT_REGISTRY="${JSKIT_REGISTRY:-}"
7
- NPM_DRY_RUN="${npm_config_dry_run:-}"
8
-
9
- dry_run_enabled=false
10
- normalized_npm_dry_run="$(printf "%s" "$NPM_DRY_RUN" | tr '[:upper:]' '[:lower:]')"
11
- if [[ "$normalized_npm_dry_run" == "1" || "$normalized_npm_dry_run" == "true" ]]; then
12
- dry_run_enabled=true
13
- fi
14
-
15
- for arg in "$@"; do
16
- if [[ "$arg" == "--dry-run" ]]; then
17
- dry_run_enabled=true
18
- elif [[ "$arg" == "--no-dry-run" ]]; then
19
- dry_run_enabled=false
20
- fi
21
- done
22
-
23
- install_args=()
24
- if [[ "$dry_run_enabled" == "true" ]]; then
25
- install_args+=(--dry-run)
26
- echo "[jskit:update] dry-run mode enabled."
27
- fi
28
-
29
- if [[ ! -f "$PACKAGE_JSON_PATH" ]]; then
30
- echo "[jskit:update] package.json not found: $PACKAGE_JSON_PATH" >&2
31
- exit 1
32
- fi
33
-
34
- readarray -t runtime_packages < <(
35
- node -e '
36
- const fs = require("node:fs");
37
- const packageJson = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
38
- const dependencies = packageJson?.dependencies || {};
39
- const names = Object.keys(dependencies).filter((name) => name.startsWith("@jskit-ai/")).sort();
40
- for (const name of names) {
41
- process.stdout.write(`${name}\n`);
42
- }
43
- ' "$PACKAGE_JSON_PATH"
44
- )
45
-
46
- readarray -t dev_packages < <(
47
- node -e '
48
- const fs = require("node:fs");
49
- const packageJson = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
50
- const dependencies = packageJson?.devDependencies || {};
51
- const names = Object.keys(dependencies).filter((name) => name.startsWith("@jskit-ai/")).sort();
52
- for (const name of names) {
53
- process.stdout.write(`${name}\n`);
54
- }
55
- ' "$PACKAGE_JSON_PATH"
56
- )
57
-
58
- registry_args=()
59
- if [[ -n "$JSKIT_REGISTRY" ]]; then
60
- registry_args+=(--registry "$JSKIT_REGISTRY")
61
- fi
62
-
63
- if (( ${#runtime_packages[@]} == 0 && ${#dev_packages[@]} == 0 )); then
64
- echo "[jskit:update] no @jskit-ai packages found in dependencies."
65
- exit 0
66
- fi
67
-
68
- resolve_major_range() {
69
- local package_name="$1"
70
- local latest_version
71
- if ! latest_version="$(npm view "${registry_args[@]}" "$package_name" version)"; then
72
- echo "[jskit:update] failed to resolve latest version for $package_name." >&2
73
- exit 1
74
- fi
75
- latest_version="$(printf "%s" "$latest_version" | tr -d '[:space:]')"
76
-
77
- if [[ ! "$latest_version" =~ ^([0-9]+)\.[0-9]+\.[0-9]+([.+-][0-9A-Za-z.-]+)?$ ]]; then
78
- echo "[jskit:update] invalid latest version for $package_name: $latest_version" >&2
79
- exit 1
80
- fi
81
-
82
- local major="${BASH_REMATCH[1]}"
83
- printf "%s.x" "$major"
84
- }
85
-
86
- runtime_specs=()
87
- for package_name in "${runtime_packages[@]}"; do
88
- runtime_specs+=("${package_name}@$(resolve_major_range "$package_name")")
89
- done
90
-
91
- dev_specs=()
92
- for package_name in "${dev_packages[@]}"; do
93
- dev_specs+=("${package_name}@$(resolve_major_range "$package_name")")
94
- done
95
-
96
- if (( ${#runtime_specs[@]} > 0 )); then
97
- echo "[jskit:update] updating runtime packages: ${runtime_specs[*]}"
98
- (
99
- cd "$APP_ROOT"
100
- npm install --save-exact "${registry_args[@]}" "${install_args[@]}" "${runtime_specs[@]}"
101
- )
102
- fi
103
-
104
- if (( ${#dev_specs[@]} > 0 )); then
105
- echo "[jskit:update] updating dev packages: ${dev_specs[*]}"
106
- (
107
- cd "$APP_ROOT"
108
- npm install --save-dev --save-exact "${registry_args[@]}" "${install_args[@]}" "${dev_specs[@]}"
109
- )
110
- fi
111
-
112
- if [[ "$dry_run_enabled" != "true" ]]; then
113
- echo "[jskit:update] generating managed migrations for changed packages."
114
- (
115
- cd "$APP_ROOT"
116
- npx jskit migrations changed
117
- )
118
- fi
119
-
120
- echo "[jskit:update] done."