zozul-cli 0.1.0

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 (139) hide show
  1. package/.env.example +44 -0
  2. package/.github/workflows/publish.yml +26 -0
  3. package/DEVELOPMENT.md +288 -0
  4. package/LICENSE +201 -0
  5. package/README.md +178 -0
  6. package/dist/cli/commands.d.ts +3 -0
  7. package/dist/cli/commands.d.ts.map +1 -0
  8. package/dist/cli/commands.js +307 -0
  9. package/dist/cli/commands.js.map +1 -0
  10. package/dist/cli/format.d.ts +5 -0
  11. package/dist/cli/format.d.ts.map +1 -0
  12. package/dist/cli/format.js +115 -0
  13. package/dist/cli/format.js.map +1 -0
  14. package/dist/context/index.d.ts +8 -0
  15. package/dist/context/index.d.ts.map +1 -0
  16. package/dist/context/index.js +37 -0
  17. package/dist/context/index.js.map +1 -0
  18. package/dist/dashboard/html.d.ts +17 -0
  19. package/dist/dashboard/html.d.ts.map +1 -0
  20. package/dist/dashboard/html.js +79 -0
  21. package/dist/dashboard/html.js.map +1 -0
  22. package/dist/dashboard/index.html +1245 -0
  23. package/dist/hooks/config.d.ts +19 -0
  24. package/dist/hooks/config.d.ts.map +1 -0
  25. package/dist/hooks/config.js +106 -0
  26. package/dist/hooks/config.js.map +1 -0
  27. package/dist/hooks/git.d.ts +6 -0
  28. package/dist/hooks/git.d.ts.map +1 -0
  29. package/dist/hooks/git.js +73 -0
  30. package/dist/hooks/git.js.map +1 -0
  31. package/dist/hooks/index.d.ts +4 -0
  32. package/dist/hooks/index.d.ts.map +1 -0
  33. package/dist/hooks/index.js +3 -0
  34. package/dist/hooks/index.js.map +1 -0
  35. package/dist/hooks/server.d.ts +16 -0
  36. package/dist/hooks/server.d.ts.map +1 -0
  37. package/dist/hooks/server.js +349 -0
  38. package/dist/hooks/server.js.map +1 -0
  39. package/dist/index.d.ts +3 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +6 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/otel/config.d.ts +36 -0
  44. package/dist/otel/config.d.ts.map +1 -0
  45. package/dist/otel/config.js +109 -0
  46. package/dist/otel/config.js.map +1 -0
  47. package/dist/otel/index.d.ts +4 -0
  48. package/dist/otel/index.d.ts.map +1 -0
  49. package/dist/otel/index.js +3 -0
  50. package/dist/otel/index.js.map +1 -0
  51. package/dist/otel/receiver.d.ts +10 -0
  52. package/dist/otel/receiver.d.ts.map +1 -0
  53. package/dist/otel/receiver.js +155 -0
  54. package/dist/otel/receiver.js.map +1 -0
  55. package/dist/parser/index.d.ts +4 -0
  56. package/dist/parser/index.d.ts.map +1 -0
  57. package/dist/parser/index.js +3 -0
  58. package/dist/parser/index.js.map +1 -0
  59. package/dist/parser/ingest.d.ts +20 -0
  60. package/dist/parser/ingest.d.ts.map +1 -0
  61. package/dist/parser/ingest.js +98 -0
  62. package/dist/parser/ingest.js.map +1 -0
  63. package/dist/parser/jsonl.d.ts +14 -0
  64. package/dist/parser/jsonl.d.ts.map +1 -0
  65. package/dist/parser/jsonl.js +202 -0
  66. package/dist/parser/jsonl.js.map +1 -0
  67. package/dist/parser/types.d.ts +81 -0
  68. package/dist/parser/types.d.ts.map +1 -0
  69. package/dist/parser/types.js +9 -0
  70. package/dist/parser/types.js.map +1 -0
  71. package/dist/parser/watcher.d.ts +16 -0
  72. package/dist/parser/watcher.d.ts.map +1 -0
  73. package/dist/parser/watcher.js +103 -0
  74. package/dist/parser/watcher.js.map +1 -0
  75. package/dist/pricing/index.d.ts +2 -0
  76. package/dist/pricing/index.d.ts.map +1 -0
  77. package/dist/pricing/index.js +37 -0
  78. package/dist/pricing/index.js.map +1 -0
  79. package/dist/service/index.d.ts +31 -0
  80. package/dist/service/index.d.ts.map +1 -0
  81. package/dist/service/index.js +252 -0
  82. package/dist/service/index.js.map +1 -0
  83. package/dist/storage/db.d.ts +75 -0
  84. package/dist/storage/db.d.ts.map +1 -0
  85. package/dist/storage/db.js +117 -0
  86. package/dist/storage/db.js.map +1 -0
  87. package/dist/storage/index.d.ts +4 -0
  88. package/dist/storage/index.d.ts.map +1 -0
  89. package/dist/storage/index.js +3 -0
  90. package/dist/storage/index.js.map +1 -0
  91. package/dist/storage/repo.d.ts +162 -0
  92. package/dist/storage/repo.d.ts.map +1 -0
  93. package/dist/storage/repo.js +472 -0
  94. package/dist/storage/repo.js.map +1 -0
  95. package/dist/sync/client.d.ts +24 -0
  96. package/dist/sync/client.d.ts.map +1 -0
  97. package/dist/sync/client.js +41 -0
  98. package/dist/sync/client.js.map +1 -0
  99. package/dist/sync/index.d.ts +18 -0
  100. package/dist/sync/index.d.ts.map +1 -0
  101. package/dist/sync/index.js +135 -0
  102. package/dist/sync/index.js.map +1 -0
  103. package/dist/sync/sync.test.d.ts +2 -0
  104. package/dist/sync/sync.test.d.ts.map +1 -0
  105. package/dist/sync/sync.test.js +412 -0
  106. package/dist/sync/sync.test.js.map +1 -0
  107. package/dist/sync/transform.d.ts +80 -0
  108. package/dist/sync/transform.d.ts.map +1 -0
  109. package/dist/sync/transform.js +90 -0
  110. package/dist/sync/transform.js.map +1 -0
  111. package/package.json +50 -0
  112. package/src/cli/commands.ts +332 -0
  113. package/src/cli/format.ts +133 -0
  114. package/src/context/index.ts +42 -0
  115. package/src/dashboard/html.ts +97 -0
  116. package/src/dashboard/index.html +1245 -0
  117. package/src/hooks/config.ts +119 -0
  118. package/src/hooks/git.ts +77 -0
  119. package/src/hooks/index.ts +7 -0
  120. package/src/hooks/server.ts +397 -0
  121. package/src/index.ts +6 -0
  122. package/src/otel/config.ts +141 -0
  123. package/src/otel/index.ts +8 -0
  124. package/src/otel/receiver.ts +183 -0
  125. package/src/parser/index.ts +3 -0
  126. package/src/parser/ingest.ts +119 -0
  127. package/src/parser/jsonl.ts +241 -0
  128. package/src/parser/types.ts +89 -0
  129. package/src/parser/watcher.ts +116 -0
  130. package/src/pricing/index.ts +51 -0
  131. package/src/service/index.ts +272 -0
  132. package/src/storage/db.ts +198 -0
  133. package/src/storage/index.ts +3 -0
  134. package/src/storage/repo.ts +601 -0
  135. package/src/sync/client.ts +63 -0
  136. package/src/sync/index.ts +207 -0
  137. package/src/sync/sync.test.ts +447 -0
  138. package/src/sync/transform.ts +184 -0
  139. package/tsconfig.json +19 -0
@@ -0,0 +1,97 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+
7
+ function rawHtml(): string {
8
+ return readFileSync(join(__dirname, "index.html"), "utf-8");
9
+ }
10
+
11
+ /** Local-only dashboard (no remote toggle). */
12
+ export function dashboardHtml(): string {
13
+ return rawHtml();
14
+ }
15
+
16
+ /**
17
+ * Dashboard with a Local / Remote toggle.
18
+ * When remote config is provided, the user can switch between local SQLite
19
+ * and the remote backend API via a toggle in the header.
20
+ * `mode` sets the initial active source.
21
+ */
22
+ export function dashboardHtmlWithToggle(remote: { apiUrl: string; apiKey: string }, mode: "local" | "remote" = "local"): string {
23
+ const baseUrl = remote.apiUrl.replace(/\/+$/, "") + "/api/v1";
24
+ let html = rawHtml();
25
+
26
+ const configScript = `
27
+ <script>
28
+ const ZOZUL_CONFIG = {
29
+ remote: { baseUrl: ${JSON.stringify(baseUrl)}, apiKey: ${JSON.stringify(remote.apiKey)} },
30
+ mode: ${JSON.stringify(mode)},
31
+ };
32
+ </script>`;
33
+
34
+ html = html.replace("<script>\nlet chartInstances", configScript + "\n<script>\nlet chartInstances");
35
+
36
+ // Replace fetchJson to route based on active mode
37
+ html = html.replace(
38
+ `async function fetchJson(path) {\n const res = await fetch(path);\n if (!res.ok) throw new Error(res.status + ' ' + path);\n return res.json();\n}`,
39
+ `async function fetchJson(path) {
40
+ if (ZOZUL_CONFIG && ZOZUL_CONFIG.mode === 'remote') {
41
+ const url = ZOZUL_CONFIG.remote.baseUrl + path.replace('/api/', '/');
42
+ const res = await fetch(url, { headers: { 'X-API-Key': ZOZUL_CONFIG.remote.apiKey } });
43
+ if (!res.ok) throw new Error(res.status + ' ' + url);
44
+ return res.json();
45
+ }
46
+ const res = await fetch(path);
47
+ if (!res.ok) throw new Error(res.status + ' ' + path);
48
+ return res.json();
49
+ }`,
50
+ );
51
+
52
+ // Inject toggle button into the header-right div
53
+ const toggleHtml = `
54
+ <div style="display:flex;border:1px solid var(--border);border-radius:6px;overflow:hidden;font-size:12px">
55
+ <button id="src-local" onclick="switchSource('local')"
56
+ style="padding:4px 12px;border:none;cursor:pointer;font-size:12px;font-family:inherit;transition:all 0.15s">Local</button>
57
+ <button id="src-remote" onclick="switchSource('remote')"
58
+ style="padding:4px 12px;border:none;cursor:pointer;font-size:12px;font-family:inherit;transition:all 0.15s">Remote</button>
59
+ </div>`;
60
+
61
+ html = html.replace(
62
+ '<div class="header-right">',
63
+ '<div class="header-right">' + toggleHtml,
64
+ );
65
+
66
+ // Inject switchSource function and initial toggle state
67
+ const switchScript = `
68
+ function switchSource(mode) {
69
+ ZOZUL_CONFIG.mode = mode;
70
+ const local = document.getElementById('src-local');
71
+ const remote = document.getElementById('src-remote');
72
+ const activeStyle = 'background:var(--accent);color:#fff;';
73
+ const inactiveStyle = 'background:var(--surface);color:var(--text-dim);';
74
+ local.style.cssText += (mode === 'local' ? activeStyle : inactiveStyle);
75
+ remote.style.cssText += (mode === 'remote' ? activeStyle : inactiveStyle);
76
+ document.title = 'zozul — ' + (mode === 'local' ? 'Local' : 'Remote') + ' Dashboard';
77
+ loadDashboard();
78
+ }
79
+
80
+ // Set initial toggle state on load
81
+ document.addEventListener('DOMContentLoaded', () => switchSource(ZOZUL_CONFIG.mode));
82
+ `;
83
+
84
+ // Must target the top-level bootstrap call (last occurrence), not the one inside manualRefresh()
85
+ const bootstrapCall = "loadDashboard().then(scheduleAutoRefresh);";
86
+ const lastIdx = html.lastIndexOf(bootstrapCall);
87
+ html = html.slice(0, lastIdx) + switchScript + "\n" + bootstrapCall + html.slice(lastIdx + bootstrapCall.length);
88
+
89
+ return html;
90
+ }
91
+
92
+ /**
93
+ * Remote-only dashboard (no local API available).
94
+ */
95
+ export function remoteDashboardHtml(apiUrl: string, apiKey: string): string {
96
+ return dashboardHtmlWithToggle({ apiUrl, apiKey }, "remote");
97
+ }