@hienlh/ppm 0.6.3 → 0.6.5

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 (78) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/web/assets/api-client-4Ni0i4Hl.js +1 -0
  3. package/dist/web/assets/{chat-tab-DjE_8Csw.js → chat-tab-DkgRZpbj.js} +3 -3
  4. package/dist/web/assets/{code-editor-witrClmz.js → code-editor-CVMeIylx.js} +1 -1
  5. package/dist/web/assets/database-viewer-BX0F2yv0.js +1 -0
  6. package/dist/web/assets/{diff-viewer-DSU--yFW.js → diff-viewer-B1vnegRS.js} +1 -1
  7. package/dist/web/assets/dist-Jb3Tnkpc.js +16 -0
  8. package/dist/web/assets/{git-graph-HpcOYt3G.js → git-graph-Bi4PM-z2.js} +1 -1
  9. package/dist/web/assets/index-DSg2VjxL.css +2 -0
  10. package/dist/web/assets/{index-CcXQ5iQw.js → index-DUb5kwfL.js} +6 -6
  11. package/dist/web/assets/{input-CCCPR1s4.js → input-nI4xe1Y9.js} +1 -1
  12. package/dist/web/assets/keybindings-store-BVTJScRw.js +1 -0
  13. package/dist/web/assets/{markdown-renderer-DSw-4oxk.js → markdown-renderer-ChvoCZNm.js} +1 -1
  14. package/dist/web/assets/postgres-viewer-DPsoDR4y.js +1 -0
  15. package/dist/web/assets/settings-store-CfB0vCtQ.js +1 -0
  16. package/dist/web/assets/settings-tab-D7pNWvVE.js +1 -0
  17. package/dist/web/assets/sqlite-viewer-CTPkNEEe.js +1 -0
  18. package/dist/web/assets/{tab-store-DhXold0e.js → tab-store-DIyJSjtr.js} +1 -1
  19. package/dist/web/assets/table-DCVKGOr2.js +1 -0
  20. package/dist/web/assets/{terminal-tab-CAQvs2wj.js → terminal-tab-B_75oJaQ.js} +1 -1
  21. package/dist/web/assets/{use-monaco-theme-GX0lrqac.js → use-monaco-theme-Dexl3s3E.js} +1 -1
  22. package/dist/web/index.html +8 -8
  23. package/dist/web/sw.js +1 -1
  24. package/docs/codebase-summary.md +41 -14
  25. package/docs/project-roadmap.md +31 -6
  26. package/docs/system-architecture.md +222 -7
  27. package/package.json +1 -1
  28. package/src/cli/commands/db-cmd.ts +21 -4
  29. package/src/server/index.ts +6 -0
  30. package/src/server/routes/chat.ts +2 -2
  31. package/src/server/routes/database.ts +261 -0
  32. package/src/services/database/adapter-registry.ts +13 -0
  33. package/src/services/database/init-adapters.ts +9 -0
  34. package/src/services/database/postgres-adapter.ts +42 -0
  35. package/src/services/database/readonly-check.ts +17 -0
  36. package/src/services/database/sqlite-adapter.ts +55 -0
  37. package/src/services/db.service.ts +77 -4
  38. package/src/services/table-cache.service.ts +75 -0
  39. package/src/types/config.ts +10 -2
  40. package/src/types/database.ts +50 -0
  41. package/src/web/app.tsx +9 -4
  42. package/src/web/components/chat/tool-cards.tsx +2 -2
  43. package/src/web/components/database/connection-color-picker.tsx +67 -0
  44. package/src/web/components/database/connection-form-dialog.tsx +234 -0
  45. package/src/web/components/database/connection-list.tsx +257 -0
  46. package/src/web/components/database/database-sidebar.tsx +89 -0
  47. package/src/web/components/database/database-viewer.tsx +228 -0
  48. package/src/web/components/database/use-connections.ts +92 -0
  49. package/src/web/components/database/use-database.ts +117 -0
  50. package/src/web/components/layout/command-palette.tsx +56 -6
  51. package/src/web/components/layout/draggable-tab.tsx +13 -2
  52. package/src/web/components/layout/editor-panel.tsx +1 -0
  53. package/src/web/components/layout/mobile-drawer.tsx +7 -2
  54. package/src/web/components/layout/mobile-nav.tsx +1 -1
  55. package/src/web/components/layout/sidebar.tsx +7 -3
  56. package/src/web/components/layout/tab-bar.tsx +1 -0
  57. package/src/web/components/layout/tab-content.tsx +5 -0
  58. package/src/web/components/postgres/postgres-viewer.tsx +42 -25
  59. package/src/web/components/postgres/use-postgres.ts +54 -21
  60. package/src/web/components/settings/ai-settings-section.tsx +0 -1
  61. package/src/web/components/sqlite/sqlite-viewer.tsx +43 -13
  62. package/src/web/components/sqlite/use-sqlite.ts +24 -15
  63. package/src/web/hooks/use-chat.ts +1 -1
  64. package/src/web/hooks/use-usage.ts +1 -1
  65. package/src/web/lib/api-client.ts +7 -1
  66. package/src/web/lib/color-utils.ts +23 -0
  67. package/src/web/stores/settings-store.ts +2 -2
  68. package/src/web/stores/tab-store.ts +1 -0
  69. package/dist/web/assets/api-client-D0pZeYY8.js +0 -1
  70. package/dist/web/assets/dist-PpKqMvyx.js +0 -16
  71. package/dist/web/assets/index-DyEgsogR.css +0 -2
  72. package/dist/web/assets/keybindings-store-C_KQKrsc.js +0 -1
  73. package/dist/web/assets/postgres-viewer-BnkGPi0L.js +0 -1
  74. package/dist/web/assets/settings-store-B5g1Gis-.js +0 -1
  75. package/dist/web/assets/settings-tab-DpQdg9OW.js +0 -1
  76. package/dist/web/assets/sqlite-viewer-JZvegGV-.js +0 -1
  77. /package/dist/web/assets/{react-l9v2XLcs.js → react-DHSo28we.js} +0 -0
  78. /package/dist/web/assets/{utils-CAPYyGV3.js → utils-siJJ3uG0.js} +0 -0
@@ -0,0 +1,23 @@
1
+ /** Parse hex color to RGB components */
2
+ function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
3
+ const m = /^#([0-9a-fA-F]{6})$/.exec(hex.trim());
4
+ if (!m) return null;
5
+ const n = parseInt(m[1]!, 16);
6
+ return { r: (n >> 16) & 0xff, g: (n >> 8) & 0xff, b: n & 0xff };
7
+ }
8
+
9
+ /** Relative luminance per WCAG 2.0 */
10
+ function getLuminance(r: number, g: number, b: number): number {
11
+ const [rs, gs, bs] = [r, g, b].map((c) => {
12
+ const s = c / 255;
13
+ return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
14
+ }) as [number, number, number];
15
+ return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
16
+ }
17
+
18
+ /** Returns true if the color is dark enough to need white text */
19
+ export function isDarkColor(hex: string): boolean {
20
+ const rgb = hexToRgb(hex);
21
+ if (!rgb) return false;
22
+ return getLuminance(rgb.r, rgb.g, rgb.b) < 0.4;
23
+ }
@@ -2,7 +2,7 @@ import { create } from "zustand";
2
2
 
3
3
  export type Theme = "light" | "dark" | "system";
4
4
  export type GitStatusViewMode = "flat" | "tree";
5
- export type SidebarActiveTab = "explorer" | "git" | "settings";
5
+ export type SidebarActiveTab = "explorer" | "git" | "settings" | "database";
6
6
 
7
7
  const STORAGE_KEY = "ppm-settings";
8
8
 
@@ -78,7 +78,7 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({
78
78
  sidebarWidth: _initial.sidebarWidth ?? 280,
79
79
  gitStatusViewMode: _initial.gitStatusViewMode === "flat" ? "flat" : "tree",
80
80
  wordWrap: _initial.wordWrap ?? false,
81
- sidebarActiveTab: (_initial.sidebarActiveTab === "git" || _initial.sidebarActiveTab === "settings") ? _initial.sidebarActiveTab : "explorer",
81
+ sidebarActiveTab: (["git", "settings", "database"] as SidebarActiveTab[]).includes(_initial.sidebarActiveTab as SidebarActiveTab) ? _initial.sidebarActiveTab! : "explorer",
82
82
  deviceName: null,
83
83
  version: null,
84
84
 
@@ -5,6 +5,7 @@ export type TabType =
5
5
  | "terminal"
6
6
  | "chat"
7
7
  | "editor"
8
+ | "database"
8
9
  | "sqlite"
9
10
  | "postgres"
10
11
  | "git-graph"
@@ -1 +0,0 @@
1
- import{r as e}from"./react-CYzKIDNi.js";var t=e({api:()=>r,getAuthToken:()=>o,projectUrl:()=>i,setAuthToken:()=>a}),n=`ppm-auth-token`,r=new class{baseUrl;constructor(e=``){this.baseUrl=e}getToken(){return localStorage.getItem(n)}headers(){let e={"Content-Type":`application/json`},t=this.getToken();return t&&(e.Authorization=`Bearer ${t}`),e}async get(e){let t=await fetch(`${this.baseUrl}${e}`,{headers:this.headers()});return this.handleResponse(t)}async post(e,t){let n=await fetch(`${this.baseUrl}${e}`,{method:`POST`,headers:this.headers(),body:t==null?void 0:JSON.stringify(t)});return this.handleResponse(n)}async put(e,t){let n=await fetch(`${this.baseUrl}${e}`,{method:`PUT`,headers:this.headers(),body:t==null?void 0:JSON.stringify(t)});return this.handleResponse(n)}async patch(e,t){let n=await fetch(`${this.baseUrl}${e}`,{method:`PATCH`,headers:this.headers(),body:t==null?void 0:JSON.stringify(t)});return this.handleResponse(n)}async del(e,t){let n=await fetch(`${this.baseUrl}${e}`,{method:`DELETE`,headers:this.headers(),body:t==null?void 0:JSON.stringify(t)});await this.handleResponse(n)}async handleResponse(e){if(e.status===401)throw localStorage.removeItem(n),window.location.reload(),Error(`Unauthorized`);let t=await e.json();if(t.ok===!1)throw Error(t.error??`HTTP ${e.status}`);return t.data}};function i(e){return`/api/project/${encodeURIComponent(e)}`}function a(e){localStorage.setItem(n,e)}function o(){return localStorage.getItem(n)}export{a,i,t as n,o as r,r as t};