@kokimoki/kit 1.6.7 → 1.7.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.
- package/README.md +76 -0
- package/dist/api.d.ts +63 -0
- package/dist/api.js +95 -0
- package/dist/credentials.d.ts +25 -0
- package/dist/credentials.js +44 -0
- package/dist/dev-app.d.ts +57 -0
- package/dist/dev-app.js +271 -0
- package/dist/dev-frame/index.d.ts +5 -0
- package/dist/dev-frame/index.js +9 -0
- package/dist/dev-frame/render-dev-frame.d.ts +30 -0
- package/dist/dev-frame/render-dev-frame.js +160 -0
- package/dist/dev-frame/styles.d.ts +4 -0
- package/dist/dev-frame/styles.js +191 -0
- package/dist/dev-i18n.d.ts +56 -0
- package/dist/dev-i18n.js +164 -0
- package/dist/dev-overlays.d.ts +19 -0
- package/dist/dev-overlays.js +300 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/kokimoki-kit-plugin.d.ts +47 -4
- package/dist/kokimoki-kit-plugin.js +383 -71
- package/dist/production-loading-screen.d.ts +20 -0
- package/dist/production-loading-screen.js +123 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/kokimoki-kit.instructions.md +341 -0
- package/llms.txt +46 -0
- package/package.json +10 -3
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Development overlay HTML templates for kokimoki-kit plugin
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderLoadingPage = renderLoadingPage;
|
|
7
|
+
exports.renderErrorPage = renderErrorPage;
|
|
8
|
+
exports.renderStoresChangedPage = renderStoresChangedPage;
|
|
9
|
+
const pageBaseStyles = `
|
|
10
|
+
color: white;
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
15
|
+
`;
|
|
16
|
+
/**
|
|
17
|
+
* Generate a full loading page HTML that polls for initialization completion
|
|
18
|
+
*/
|
|
19
|
+
function renderLoadingPage() {
|
|
20
|
+
return `<!DOCTYPE html>
|
|
21
|
+
<html lang="en">
|
|
22
|
+
<head>
|
|
23
|
+
<meta charset="UTF-8">
|
|
24
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
25
|
+
<title>Loading...</title>
|
|
26
|
+
<style>
|
|
27
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
28
|
+
body {
|
|
29
|
+
${pageBaseStyles}
|
|
30
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
|
31
|
+
min-height: 100vh;
|
|
32
|
+
}
|
|
33
|
+
.container {
|
|
34
|
+
text-align: center;
|
|
35
|
+
}
|
|
36
|
+
.logo {
|
|
37
|
+
width: 80px;
|
|
38
|
+
height: 80px;
|
|
39
|
+
margin-bottom: 24px;
|
|
40
|
+
animation: pulse 2s ease-in-out infinite;
|
|
41
|
+
}
|
|
42
|
+
@keyframes pulse {
|
|
43
|
+
0%, 100% { transform: scale(1); opacity: 1; }
|
|
44
|
+
50% { transform: scale(1.05); opacity: 0.8; }
|
|
45
|
+
}
|
|
46
|
+
h1 {
|
|
47
|
+
font-size: 24px;
|
|
48
|
+
font-weight: 600;
|
|
49
|
+
margin-bottom: 12px;
|
|
50
|
+
color: #fff;
|
|
51
|
+
}
|
|
52
|
+
p {
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
color: #888;
|
|
55
|
+
}
|
|
56
|
+
.spinner {
|
|
57
|
+
width: 40px;
|
|
58
|
+
height: 40px;
|
|
59
|
+
border: 3px solid #333;
|
|
60
|
+
border-top-color: #6366f1;
|
|
61
|
+
border-radius: 50%;
|
|
62
|
+
animation: spin 1s linear infinite;
|
|
63
|
+
margin: 24px auto 0;
|
|
64
|
+
}
|
|
65
|
+
@keyframes spin {
|
|
66
|
+
to { transform: rotate(360deg); }
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
69
|
+
</head>
|
|
70
|
+
<body>
|
|
71
|
+
<div class="container">
|
|
72
|
+
<svg class="logo" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
73
|
+
<circle cx="50" cy="50" r="45" stroke="#6366f1" stroke-width="4" fill="none" opacity="0.3"/>
|
|
74
|
+
<circle cx="50" cy="50" r="30" stroke="#6366f1" stroke-width="4" fill="none" opacity="0.5"/>
|
|
75
|
+
<circle cx="50" cy="50" r="15" fill="#6366f1"/>
|
|
76
|
+
</svg>
|
|
77
|
+
<h1>Initializing Kokimoki</h1>
|
|
78
|
+
<p>Setting up development environment...</p>
|
|
79
|
+
<div class="spinner"></div>
|
|
80
|
+
</div>
|
|
81
|
+
<script>
|
|
82
|
+
(function() {
|
|
83
|
+
let attempts = 0;
|
|
84
|
+
const maxAttempts = 60; // 30 seconds max
|
|
85
|
+
|
|
86
|
+
async function checkReady() {
|
|
87
|
+
attempts++;
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetch('/__kokimoki/ready');
|
|
90
|
+
const data = await res.json();
|
|
91
|
+
if (data.ready) {
|
|
92
|
+
window.location.reload();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// Ignore errors, keep polling
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (attempts < maxAttempts) {
|
|
100
|
+
setTimeout(checkReady, 500);
|
|
101
|
+
} else {
|
|
102
|
+
document.querySelector('h1').textContent = 'Initialization timeout';
|
|
103
|
+
document.querySelector('p').textContent = 'Please refresh the page or check the console for errors.';
|
|
104
|
+
document.querySelector('.spinner').style.display = 'none';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setTimeout(checkReady, 500);
|
|
109
|
+
})();
|
|
110
|
+
</script>
|
|
111
|
+
</body>
|
|
112
|
+
</html>`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate error page HTML for dev app errors (full page)
|
|
116
|
+
*/
|
|
117
|
+
function renderErrorPage(error) {
|
|
118
|
+
return `<!DOCTYPE html>
|
|
119
|
+
<html lang="en">
|
|
120
|
+
<head>
|
|
121
|
+
<meta charset="UTF-8">
|
|
122
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
123
|
+
<title>Error - Kokimoki Kit</title>
|
|
124
|
+
<style>
|
|
125
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
126
|
+
body {
|
|
127
|
+
${pageBaseStyles}
|
|
128
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
|
129
|
+
min-height: 100vh;
|
|
130
|
+
}
|
|
131
|
+
.container {
|
|
132
|
+
max-width: 550px;
|
|
133
|
+
padding: 40px;
|
|
134
|
+
background: rgba(255, 255, 255, 0.05);
|
|
135
|
+
border-radius: 16px;
|
|
136
|
+
border: 1px solid rgba(255, 68, 68, 0.3);
|
|
137
|
+
text-align: center;
|
|
138
|
+
}
|
|
139
|
+
.icon {
|
|
140
|
+
width: 64px;
|
|
141
|
+
height: 64px;
|
|
142
|
+
margin-bottom: 20px;
|
|
143
|
+
}
|
|
144
|
+
h1 {
|
|
145
|
+
font-size: 24px;
|
|
146
|
+
font-weight: 600;
|
|
147
|
+
margin-bottom: 16px;
|
|
148
|
+
color: #ff4444;
|
|
149
|
+
}
|
|
150
|
+
p {
|
|
151
|
+
font-size: 15px;
|
|
152
|
+
color: #aaa;
|
|
153
|
+
line-height: 1.6;
|
|
154
|
+
margin-bottom: 20px;
|
|
155
|
+
}
|
|
156
|
+
code {
|
|
157
|
+
display: block;
|
|
158
|
+
background: rgba(0, 0, 0, 0.3);
|
|
159
|
+
padding: 12px 16px;
|
|
160
|
+
border-radius: 8px;
|
|
161
|
+
font-size: 13px;
|
|
162
|
+
color: #888;
|
|
163
|
+
}
|
|
164
|
+
</style>
|
|
165
|
+
</head>
|
|
166
|
+
<body>
|
|
167
|
+
<div class="container">
|
|
168
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
169
|
+
<circle cx="12" cy="12" r="9" stroke="#ff4444" stroke-width="2"/>
|
|
170
|
+
<path d="M15 9L9 15M9 9L15 15" stroke="#ff4444" stroke-width="2" stroke-linecap="round"/>
|
|
171
|
+
</svg>
|
|
172
|
+
<h1>Kokimoki Kit Error</h1>
|
|
173
|
+
<p>${error.message.replace(/"/g, """)}</p>
|
|
174
|
+
<code>Error code: ${error.code}</code>
|
|
175
|
+
</div>
|
|
176
|
+
</body>
|
|
177
|
+
</html>`;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generate stores changed warning page HTML (full page, not overlay)
|
|
181
|
+
*/
|
|
182
|
+
function renderStoresChangedPage(canReset) {
|
|
183
|
+
const resetButton = canReset
|
|
184
|
+
? `<button id="km-stores-reset-btn" class="btn btn-primary">Reset State</button>`
|
|
185
|
+
: "";
|
|
186
|
+
return `<!DOCTYPE html>
|
|
187
|
+
<html lang="en">
|
|
188
|
+
<head>
|
|
189
|
+
<meta charset="UTF-8">
|
|
190
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
191
|
+
<title>Stores Changed</title>
|
|
192
|
+
<style>
|
|
193
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
194
|
+
body {
|
|
195
|
+
${pageBaseStyles}
|
|
196
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
|
197
|
+
min-height: 100vh;
|
|
198
|
+
}
|
|
199
|
+
.container {
|
|
200
|
+
max-width: 500px;
|
|
201
|
+
padding: 40px;
|
|
202
|
+
background: rgba(255, 255, 255, 0.05);
|
|
203
|
+
border-radius: 16px;
|
|
204
|
+
border: 1px solid rgba(255, 170, 0, 0.3);
|
|
205
|
+
text-align: center;
|
|
206
|
+
}
|
|
207
|
+
.icon {
|
|
208
|
+
width: 64px;
|
|
209
|
+
height: 64px;
|
|
210
|
+
margin-bottom: 20px;
|
|
211
|
+
}
|
|
212
|
+
h1 {
|
|
213
|
+
font-size: 24px;
|
|
214
|
+
font-weight: 600;
|
|
215
|
+
margin-bottom: 16px;
|
|
216
|
+
color: #ffaa00;
|
|
217
|
+
}
|
|
218
|
+
p {
|
|
219
|
+
font-size: 15px;
|
|
220
|
+
color: #aaa;
|
|
221
|
+
line-height: 1.6;
|
|
222
|
+
margin-bottom: 28px;
|
|
223
|
+
}
|
|
224
|
+
.buttons {
|
|
225
|
+
display: flex;
|
|
226
|
+
gap: 12px;
|
|
227
|
+
justify-content: center;
|
|
228
|
+
flex-wrap: wrap;
|
|
229
|
+
}
|
|
230
|
+
.btn {
|
|
231
|
+
padding: 12px 24px;
|
|
232
|
+
border: none;
|
|
233
|
+
border-radius: 8px;
|
|
234
|
+
cursor: pointer;
|
|
235
|
+
font-size: 14px;
|
|
236
|
+
font-weight: 500;
|
|
237
|
+
transition: all 0.2s;
|
|
238
|
+
}
|
|
239
|
+
.btn:disabled {
|
|
240
|
+
opacity: 0.6;
|
|
241
|
+
cursor: not-allowed;
|
|
242
|
+
}
|
|
243
|
+
.btn-secondary {
|
|
244
|
+
background: rgba(255, 255, 255, 0.1);
|
|
245
|
+
color: #ccc;
|
|
246
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
247
|
+
}
|
|
248
|
+
.btn-secondary:hover:not(:disabled) {
|
|
249
|
+
background: rgba(255, 255, 255, 0.15);
|
|
250
|
+
}
|
|
251
|
+
.btn-primary {
|
|
252
|
+
background: linear-gradient(135deg, #ff8800 0%, #ff6600 100%);
|
|
253
|
+
color: white;
|
|
254
|
+
}
|
|
255
|
+
.btn-primary:hover:not(:disabled) {
|
|
256
|
+
background: linear-gradient(135deg, #ff9922 0%, #ff7711 100%);
|
|
257
|
+
transform: translateY(-1px);
|
|
258
|
+
}
|
|
259
|
+
</style>
|
|
260
|
+
</head>
|
|
261
|
+
<body>
|
|
262
|
+
<div class="container">
|
|
263
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
264
|
+
<path d="M12 9V13M12 17H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="#ffaa00" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
265
|
+
</svg>
|
|
266
|
+
<h1>Stores Configuration Changed</h1>
|
|
267
|
+
<p>Your stores configuration has changed. You may want to reset the development app state to avoid data inconsistencies.</p>
|
|
268
|
+
<div class="buttons">
|
|
269
|
+
<button id="km-stores-dismiss-btn" class="btn btn-secondary">Keep Current State</button>
|
|
270
|
+
${resetButton}
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
<script>
|
|
274
|
+
(function() {
|
|
275
|
+
const dismissBtn = document.getElementById('km-stores-dismiss-btn');
|
|
276
|
+
const resetBtn = document.getElementById('km-stores-reset-btn');
|
|
277
|
+
|
|
278
|
+
dismissBtn.addEventListener('click', async function() {
|
|
279
|
+
dismissBtn.disabled = true;
|
|
280
|
+
dismissBtn.textContent = 'Loading...';
|
|
281
|
+
await fetch('/__kokimoki/stores-hash/acknowledge', { method: 'POST' });
|
|
282
|
+
window.location.reload();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (resetBtn) {
|
|
286
|
+
resetBtn.addEventListener('click', async function() {
|
|
287
|
+
resetBtn.disabled = true;
|
|
288
|
+
resetBtn.textContent = 'Resetting...';
|
|
289
|
+
await fetch('/__kokimoki/dev-app/reset', { method: 'POST' });
|
|
290
|
+
|
|
291
|
+
// Clear localStorage to reset local stores for all dev views
|
|
292
|
+
localStorage.clear();
|
|
293
|
+
window.location.reload();
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
})();
|
|
297
|
+
</script>
|
|
298
|
+
</body>
|
|
299
|
+
</html>`;
|
|
300
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,7 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./dev-app"), exports);
|
|
18
|
+
__exportStar(require("./dev-frame"), exports);
|
|
17
19
|
__exportStar(require("./kokimoki-kit-plugin"), exports);
|
|
18
20
|
__exportStar(require("./preprocess-style"), exports);
|
|
19
21
|
// Re-export Zod utilities for schema definition
|
|
20
22
|
__exportStar(require("./zod"), exports);
|
|
23
|
+
// Shared utilities (used by both kit and cli)
|
|
24
|
+
__exportStar(require("./api"), exports);
|
|
25
|
+
__exportStar(require("./credentials"), exports);
|
|
@@ -1,14 +1,57 @@
|
|
|
1
1
|
import type { PluginOption } from "vite";
|
|
2
2
|
import { ZodType } from "zod/v4";
|
|
3
|
+
import type { DevFrameCell } from "./dev-frame";
|
|
4
|
+
export { getI18nMeta, type I18nMeta } from "./dev-i18n";
|
|
3
5
|
export interface KokimokiKitConfig {
|
|
4
6
|
conceptId: string;
|
|
5
|
-
|
|
6
|
-
deployCodes: {
|
|
7
|
+
deployCodes: readonly {
|
|
7
8
|
name: string;
|
|
8
9
|
description: string;
|
|
9
|
-
clientContext:
|
|
10
|
+
clientContext: unknown;
|
|
10
11
|
}[];
|
|
11
|
-
|
|
12
|
+
schema?: ZodType;
|
|
13
|
+
defaultProjectConfigPath?: string;
|
|
12
14
|
defaultProjectStylePath?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Path to i18n folder with structure: `{lng}/{namespace}.json`
|
|
17
|
+
* Example: `./src/i18n` containing `en/ui.json`, `en/game.json`, `et/ui.json`, etc.
|
|
18
|
+
*/
|
|
19
|
+
i18nPath?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Source language code for translations. This is the language that AI will translate FROM.
|
|
22
|
+
* Defaults to 'en' if not specified.
|
|
23
|
+
* Example: 'en'
|
|
24
|
+
*/
|
|
25
|
+
i18nPrimaryLng?: string;
|
|
26
|
+
stores?: readonly {
|
|
27
|
+
pattern: string;
|
|
28
|
+
schema: ZodType;
|
|
29
|
+
local?: boolean;
|
|
30
|
+
}[];
|
|
31
|
+
/** API endpoint for kokimoki services. Defaults to https://api.kokimoki.com */
|
|
32
|
+
endpoint?: string;
|
|
33
|
+
/** WebSocket host for real-time sync. Defaults to y-wss.kokimoki.com */
|
|
34
|
+
host?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Configuration for the dev view multi-window layout.
|
|
37
|
+
* Each inner array represents a row, and each item in the row is a frame.
|
|
38
|
+
* Set to false to disable the dev view entirely.
|
|
39
|
+
*
|
|
40
|
+
* Example:
|
|
41
|
+
* ```
|
|
42
|
+
* devView: [
|
|
43
|
+
* [
|
|
44
|
+
* { label: 'host', clientContext: { mode: 'host', playerCode: 'player' } },
|
|
45
|
+
* { label: 'presenter', clientContext: { mode: 'presenter' } }
|
|
46
|
+
* ],
|
|
47
|
+
* [
|
|
48
|
+
* { label: 'player1', clientContext: { mode: 'player' } },
|
|
49
|
+
* { label: 'player2', clientContext: { mode: 'player' } },
|
|
50
|
+
* { label: 'player3', clientContext: { mode: 'player' } }
|
|
51
|
+
* ]
|
|
52
|
+
* ]
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
devView?: readonly (readonly DevFrameCell[])[] | false;
|
|
13
56
|
}
|
|
14
57
|
export declare function kokimokiKitPlugin(config: KokimokiKitConfig): PluginOption;
|