karnel-termux 4.17.19 → 4.17.20

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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  <p align="center">
10
10
  <a href="https://github.com/israelmarques1024-dotcom/karnel-termux">
11
- <img src="https://img.shields.io/badge/version-4.17.19-0078D4?style=for-the-badge" alt="Version">
11
+ <img src="https://img.shields.io/badge/version-4.17.20-0078D4?style=for-the-badge" alt="Version">
12
12
  </a>
13
13
  <a href="https://www.npmjs.com/package/karnel-termux">
14
14
  <img src="https://img.shields.io/npm/v/karnel-termux?style=for-the-badge&logo=npm&color=cb3837" alt="npm">
@@ -78,7 +78,7 @@ Why it's great:
78
78
  ### Via checksummed GitHub release (recommended)
79
79
 
80
80
  ```bash
81
- version=4.17.19
81
+ version=4.17.20
82
82
  tmpdir=$(mktemp -d) && trap 'rm -rf "$tmpdir"' EXIT
83
83
  base="https://github.com/israelmarques1024-dotcom/karnel-termux/releases/download/v$version"
84
84
  curl -fsSL "$base/karnel-termux-install.sh" -o "$tmpdir/karnel-termux-install.sh"
package/docs/CHANGELOG.md CHANGED
@@ -6,6 +6,23 @@ layout: base
6
6
 
7
7
  # Documentation Changelog
8
8
 
9
+ ## 4.17.20
10
+
11
+ - **PostgreSQL and Supabase (3):**
12
+ - `pg stop` now returns failure when `pg_ctl stop` fails; `pg restart` now stops immediately on either stop or start failure instead of printing a false success.
13
+ - `pg schedule` now returns failure if `crontab` rejects the generated entry instead of returning success after temporary-file cleanup.
14
+ - `supabase remote-status` now preserves a failed Supabase CLI status instead of logging a warning and exiting 0.
15
+ - **Search (1):** `karnel search` now treats user input as literal text in tool and brain searches. Regex metacharacters such as `[` no longer cause grep errors, and option-like input cannot change grep behavior.
16
+ - **Project initializer (7):**
17
+ - `karnel init` now requires explicit confirmation before templates that may overwrite existing files.
18
+ - Next landing pages no longer import a Button component that the initializer never creates.
19
+ - React's generated Button now has its `clsx` and `tailwind-merge` runtime dependencies installed.
20
+ - Express templates no longer import ungenerated entities/routes, and production PostgreSQL TLS now verifies certificates.
21
+ - Go templates derive imports from the actual `go.mod` module name rather than hard-coding `project`.
22
+ - Rust Dockerfiles derive the release binary from `Cargo.toml` instead of assuming `project`.
23
+ - **Regression coverage:** added PostgreSQL/Supabase contracts (5) and init/search contracts (10); the isolated full suite passes.
24
+ - Version references bumped to `4.17.20`.
25
+
9
26
  ## 4.17.19
10
27
 
11
28
  - **Release gate:** `tests/bun-installer.sh` did not mock the integrity helpers required by the hardened Bun native installer (`github_release_asset_sha256`, `verify_sha256`, `safe_extract_zip`). The test exited 1 before printing its result, causing `tests/run-isolated.sh`, CI, npm publishing, and GitHub release creation to fail from 4.17.14 through 4.17.18 despite the preceding suites passing. The test now supplies contract-faithful stubs; the full isolated suite exits 0.
@@ -1 +1 @@
1
- 1eb16a5898d6f323ed664668b96bf8eff18348cd
1
+ 4d6f527bfdc17d468eee7881aca77083528e7961
@@ -80,9 +80,8 @@ EOF
80
80
  log_success "Created .prettierrc"
81
81
 
82
82
  log_info "Creating karnel landing page..."
83
- [[ -f "src/app/page.tsx" ]] && cat >src/app/page.tsx <<'EOF'
83
+ [[ -f "src/app/page.tsx" ]] && cat >src/app/page.tsx <<'EOF'
84
84
  "use client"
85
- import { Button } from "@/components/ui/button"
86
85
  import { motion } from "framer-motion"
87
86
  import { Terminal, Code2, Rocket } from "lucide-react"
88
87
  import { Toaster } from "sonner"
@@ -113,9 +112,9 @@ export default function Home() {
113
112
  <div className="p-6 rounded-xl bg-slate-900/50 border border-slate-800"><Terminal className="w-12 h-12 text-pink-400 mb-4 mx-auto" /><h3 className="text-lg font-semibold text-white mb-2">Comunidad Activa</h3></div>
114
113
  </motion.div>
115
114
  <motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.7 }} className="w-full max-w-sm mx-auto">
116
- <Button size="lg" onClick={() => window.open("mailto:israelmarques1024@gmail.com", "_blank")} className="w-full bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white px-8 py-6 text-lg font-semibold">
117
- <Rocket className="w-5 h-5 mr-2" /> Contato: israelmarques1024@gmail.com
118
- </Button>
115
+ <button type="button" onClick={() => window.open("mailto:israelmarques1024@gmail.com", "_blank")} className="w-full rounded-md bg-gradient-to-r from-blue-500 to-purple-600 px-8 py-6 text-lg font-semibold text-white hover:from-blue-600 hover:to-purple-700">
116
+ <Rocket className="w-5 h-5 mr-2" /> Contato: israelmarques1024@gmail.com
117
+ </button>
119
118
  </motion.div>
120
119
  <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.8 }} className="mt-16 text-sm text-slate-600">Built with ❤️ using karnel tools</motion.p>
121
120
  </motion.div>
@@ -296,7 +295,7 @@ EOF
296
295
  }
297
296
 
298
297
  _install_react_deps() {
299
- npm install axios lucide-react framer-motion sonner zod react-hook-form @hookform/resolvers @tanstack/react-query zustand tailwindcss &>"$LOG_FILE"
298
+ npm install axios lucide-react framer-motion sonner zod react-hook-form @hookform/resolvers @tanstack/react-query zustand tailwindcss clsx tailwind-merge &>"$LOG_FILE"
300
299
  npm install -D prettier prettier-plugin-tailwindcss &>>"$LOG_FILE"
301
300
  }
302
301
 
@@ -431,8 +430,6 @@ EOF
431
430
  import "reflect-metadata";
432
431
  import { DataSource } from "typeorm";
433
432
  import { DATABASE_URL, NODE_ENV } from "@/config/env";
434
- import { ExampleEntity1 } from "@/entities/ExampleEntity1";
435
- import { ExampleEntity2 } from "@/entities/ExampleEntity2";
436
433
 
437
434
  const isDevelopment = NODE_ENV === "development";
438
435
  const isProduction = NODE_ENV === "production";
@@ -440,10 +437,10 @@ const isProduction = NODE_ENV === "production";
440
437
  export const AppDataSource = new DataSource({
441
438
  type: "postgres",
442
439
  url: DATABASE_URL,
443
- ssl: isDevelopment ? false : { rejectUnauthorized: false },
440
+ ssl: isDevelopment ? false : { rejectUnauthorized: true },
444
441
  synchronize: isDevelopment,
445
442
  logging: isDevelopment ? ["query", "error"] : false,
446
- entities: [ExampleEntity1, ExampleEntity2],
443
+ entities: [],
447
444
  migrations: isDevelopment
448
445
  ? [__dirname + "/migrations/*.ts"]
449
446
  : [__dirname + "/migrations/*.js"],
@@ -463,8 +460,6 @@ import morgan from "morgan";
463
460
  import cors from "cors";
464
461
  import cookieParser from "cookie-parser";
465
462
  import { FRONTEND_URL } from "@/config/env";
466
- import exampleRoutes1 from "@/routes/example1.routes";
467
- import exampleRoutes2 from "@/routes/example2.routes";
468
463
 
469
464
  const app = express();
470
465
 
@@ -497,10 +492,6 @@ app.use(express.json());
497
492
  // manejar cookies
498
493
  app.use(cookieParser());
499
494
 
500
- // endpoints
501
- app.use("/api/example1", exampleRoutes1);
502
- app.use("/api/example2", exampleRoutes2);
503
-
504
495
  export default app;
505
496
  EOF
506
497
  log_success "Created src/app.ts"
@@ -854,6 +845,12 @@ configure_go() {
854
845
  go mod init "$mod_name" 2>/dev/null || go mod init project
855
846
  log_success "Created go.mod"
856
847
  fi
848
+ local go_module
849
+ go_module=$(awk '$1 == "module" { print $2; exit }' go.mod)
850
+ if [[ -z "$go_module" ]]; then
851
+ log_error "Unable to determine Go module name from go.mod"
852
+ return 1
853
+ fi
857
854
 
858
855
  log_info "Creating folder structure..."
859
856
  mkdir -p cmd/api internal/config internal/db internal/handlers internal/models scripts 2>/dev/null
@@ -888,14 +885,14 @@ EOF
888
885
 
889
886
  # Create main.go based on framework
890
887
  if [[ "$framework_choice" == "Gin" ]]; then
891
- cat >cmd/api/main.go <<'EOF'
888
+ cat >cmd/api/main.go <<EOF
892
889
  package main
893
890
 
894
891
  import (
895
892
  "fmt"
896
893
  "net/http"
897
- "project/internal/config"
898
- "project/internal/handlers"
894
+ "$go_module/internal/config"
895
+ "$go_module/internal/handlers"
899
896
  "github.com/gin-gonic/gin"
900
897
  )
901
898
 
@@ -917,13 +914,13 @@ func main() {
917
914
  }
918
915
  EOF
919
916
  else
920
- cat >cmd/api/main.go <<'EOF'
917
+ cat >cmd/api/main.go <<EOF
921
918
  package main
922
919
 
923
920
  import (
924
921
  "fmt"
925
- "project/internal/config"
926
- "project/internal/handlers"
922
+ "$go_module/internal/config"
923
+ "$go_module/internal/handlers"
927
924
  "github.com/gofiber/fiber/v2"
928
925
  )
929
926
 
@@ -1107,6 +1104,12 @@ configure_rust() {
1107
1104
  done
1108
1105
  log_success "Configured Cargo.toml"
1109
1106
  fi
1107
+ local rust_binary
1108
+ rust_binary=$(awk -F '"' '/^name[[:space:]]*=/ { print $2; exit }' Cargo.toml)
1109
+ if [[ -z "$rust_binary" ]]; then
1110
+ log_error "Unable to determine Rust package name from Cargo.toml"
1111
+ return 1
1112
+ fi
1110
1113
 
1111
1114
  # Create src/main.rs
1112
1115
  mkdir -p src scripts 2>/dev/null
@@ -1197,7 +1200,7 @@ EOF
1197
1200
  chmod +x scripts/run.sh
1198
1201
 
1199
1202
  # Create Dockerfile
1200
- cat >Dockerfile <<'EOF'
1203
+ cat >Dockerfile <<EOF
1201
1204
  FROM rust:1.70 AS builder
1202
1205
  WORKDIR /app
1203
1206
  COPY . .
@@ -1205,9 +1208,9 @@ RUN cargo build --release
1205
1208
 
1206
1209
  FROM debian:bullseye-slim
1207
1210
  WORKDIR /app
1208
- COPY --from=builder /app/target/release/project .
1211
+ COPY --from=builder /app/target/release/$rust_binary .
1209
1212
  EXPOSE 3000
1210
- CMD ["./project"]
1213
+ CMD ["./$rust_binary"]
1211
1214
  EOF
1212
1215
  log_success "Created Dockerfile"
1213
1216
 
@@ -1230,6 +1233,15 @@ EOF
1230
1233
  echo
1231
1234
  }
1232
1235
 
1236
+ _init_confirm_overwrite() {
1237
+ local confirm
1238
+ read_confirm "Karnel may overwrite existing project files. Continue?" confirm
1239
+ if [[ "$confirm" != "y" ]]; then
1240
+ log_warn "Cancelled"
1241
+ return 1
1242
+ fi
1243
+ }
1244
+
1233
1245
  # ===== MAIN =====
1234
1246
  init_main() {
1235
1247
  local template="$1"
@@ -1239,19 +1251,20 @@ init_main() {
1239
1251
  init_help
1240
1252
  return
1241
1253
  ;;
1242
- next | nextjs) configure_next ;;
1243
- react | vite) configure_react ;;
1244
- nest | nestjs) configure_nest ;;
1245
- express | exp) configure_express ;;
1246
- python | fastapi) configure_python ;;
1247
- go | gin) configure_go ;;
1248
- rust | axum) configure_rust ;;
1254
+ next | nextjs) _init_confirm_overwrite || return 0; configure_next ;;
1255
+ react | vite) _init_confirm_overwrite || return 0; configure_react ;;
1256
+ nest | nestjs) _init_confirm_overwrite || return 0; configure_nest ;;
1257
+ express | exp) _init_confirm_overwrite || return 0; configure_express ;;
1258
+ python | fastapi) _init_confirm_overwrite || return 0; configure_python ;;
1259
+ go | gin) _init_confirm_overwrite || return 0; configure_go ;;
1260
+ rust | axum) _init_confirm_overwrite || return 0; configure_rust ;;
1249
1261
  "")
1250
1262
  local detected
1251
1263
  detected=$(detect_project_type)
1252
1264
  if [[ "$detected" != "unknown" ]]; then
1253
1265
  log_info "Detected project type: $detected"
1254
1266
  echo
1267
+ _init_confirm_overwrite || return 0
1255
1268
  case "$detected" in
1256
1269
  next) configure_next ;;
1257
1270
  react) configure_react ;;
@@ -209,6 +209,7 @@ pg_stop() {
209
209
  log_success "PostgreSQL stopped successfully"
210
210
  else
211
211
  log_warn "PostgreSQL may not be running or failed to stop"
212
+ return 1
212
213
  fi
213
214
 
214
215
  echo
@@ -230,11 +231,11 @@ pg_restart() {
230
231
  pg_init || return 1
231
232
  sleep 1
232
233
  else
233
- pg_stop
234
+ pg_stop || return 1
234
235
  sleep 1
235
236
  fi
236
237
 
237
- pg_start
238
+ pg_start || return 1
238
239
 
239
240
  echo
240
241
  separator
@@ -755,8 +756,10 @@ pg_schedule() {
755
756
  list_item "Ensure cron daemon is running (run: 'crond')"
756
757
  else
757
758
  log_error "Failed to schedule backup for database '$db_name'"
759
+ rm -f "$tmpcron"
760
+ return 1
758
761
  fi
759
762
  rm -f "$tmpcron"
760
763
  fi
761
764
  echo
762
- }
765
+ }
@@ -31,7 +31,7 @@ search_main() {
31
31
  local id name
32
32
  id=$(echo "$line" | cut -d: -f1 | tr -d '"' | xargs)
33
33
  name=$(echo "$line" | cut -d: -f2 | tr -d '"' | xargs)
34
- if echo "$id $name" | grep -qi "$query"; then
34
+ if printf '%s\n' "$id $name" | grep -Fqi -- "$query"; then
35
35
  list_item "${D_CYAN}$mod${NC}: $name ($id)"
36
36
  any_found=true
37
37
  fi
@@ -51,7 +51,7 @@ search_main() {
51
51
  title=$(head -1 "$file" 2>/dev/null | sed 's/^# //')
52
52
  list_item "${D_CYAN}$(basename "$file")${NC}: ${title:-$file}"
53
53
  any_found=true
54
- done < <(grep -ril "$query" "$KARNEL_DATA/brain" 2>/dev/null)
54
+ done < <(grep -rFil -- "$query" "$KARNEL_DATA/brain" 2>/dev/null)
55
55
  if ! $any_found; then
56
56
  log_info "No memories found matching '$query'"
57
57
  fi
@@ -219,7 +219,10 @@ supabase_remote_status() {
219
219
  log_error "Supabase CLI not installed"
220
220
  return 1
221
221
  fi
222
- supabase_safe status 2>/dev/null || log_warn "Unable to check Supabase status"
222
+ supabase_safe status 2>/dev/null || {
223
+ log_warn "Unable to check Supabase status"
224
+ return 1
225
+ }
223
226
  }
224
227
 
225
228
  supabase_link() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karnel-termux",
3
- "version": "4.17.19",
3
+ "version": "4.17.20",
4
4
  "description": "Modular Dev Environment for Termux — install languages, databases, AI agents, editors, and more with one command",
5
5
  "bin": {
6
6
  "karnel": "karnel/bin/karnel"