@alashi/cli 0.1.1 → 0.2.1
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/assets/v1/chat.js +296 -0
- package/assets/v1/system.css +532 -0
- package/dist/cli.mjs +8 -5
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{store-CwgDCAAx.mjs → store-Ckx0oLB6.mjs} +265 -43
- package/dist/store-Ckx0oLB6.mjs.map +1 -0
- package/package.json +3 -2
- package/templates/basic-app/AGENTS.md +95 -0
- package/templates/basic-app/README.md +1 -0
- package/templates/basic-app/ui/index.html +12 -281
- package/dist/store-CwgDCAAx.mjs.map +0 -1
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/* alashi system stylesheet v1
|
|
2
|
+
*
|
|
3
|
+
* The single source of look-and-feel for the host UI and every app.
|
|
4
|
+
* Apps link it (<link rel="stylesheet" href="/assets/v1/system.css">) and
|
|
5
|
+
* may override design tokens (the :root variables below) in a small inline
|
|
6
|
+
* block — e.g. `:root { --accent: #dc2626; }` — but should not restyle
|
|
7
|
+
* components. Breaking changes ship as /assets/v2/. */
|
|
8
|
+
|
|
9
|
+
/* ---- design tokens ---- */
|
|
10
|
+
:root {
|
|
11
|
+
--font-sans: system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
12
|
+
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
13
|
+
--text-size: 15px;
|
|
14
|
+
|
|
15
|
+
--bg: #f6f7fb;
|
|
16
|
+
--panel: #ffffff;
|
|
17
|
+
--border: #e4e6ef;
|
|
18
|
+
--text: #1c1e26;
|
|
19
|
+
--muted: #6b7080;
|
|
20
|
+
|
|
21
|
+
--accent: #6d28d9;
|
|
22
|
+
--accent-soft: #ede9fe;
|
|
23
|
+
--accent-contrast: #ffffff;
|
|
24
|
+
|
|
25
|
+
--sidebar-bg: #17141f;
|
|
26
|
+
--sidebar-text: #b9b3c9;
|
|
27
|
+
--sidebar-dim: #5d5871;
|
|
28
|
+
|
|
29
|
+
--ok: #15803d;
|
|
30
|
+
--ok-soft: #dcfce7;
|
|
31
|
+
--err: #b91c1c;
|
|
32
|
+
--err-soft: #fee2e2;
|
|
33
|
+
--warn: #b45309;
|
|
34
|
+
--warn-soft: #fef3c7;
|
|
35
|
+
--info: #1d4ed8;
|
|
36
|
+
--info-soft: #dbeafe;
|
|
37
|
+
--neutral: #374151;
|
|
38
|
+
--neutral-soft: #e5e7eb;
|
|
39
|
+
|
|
40
|
+
--radius: 10px;
|
|
41
|
+
--radius-sm: 8px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* ---- base ---- */
|
|
45
|
+
* {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
body {
|
|
49
|
+
margin: 0;
|
|
50
|
+
font: var(--text-size) / 1.5 var(--font-sans);
|
|
51
|
+
background: var(--bg);
|
|
52
|
+
color: var(--text);
|
|
53
|
+
min-height: 100vh;
|
|
54
|
+
}
|
|
55
|
+
h1 {
|
|
56
|
+
margin: 0 0 0.25rem;
|
|
57
|
+
font-size: 1.4rem;
|
|
58
|
+
}
|
|
59
|
+
h2 {
|
|
60
|
+
font-size: 1.1rem;
|
|
61
|
+
}
|
|
62
|
+
a {
|
|
63
|
+
color: var(--accent);
|
|
64
|
+
}
|
|
65
|
+
code,
|
|
66
|
+
pre {
|
|
67
|
+
font-family: var(--font-mono);
|
|
68
|
+
}
|
|
69
|
+
pre {
|
|
70
|
+
background: var(--bg);
|
|
71
|
+
border: 1px solid var(--border);
|
|
72
|
+
border-radius: var(--radius-sm);
|
|
73
|
+
padding: 0.85rem 1rem;
|
|
74
|
+
white-space: pre-wrap;
|
|
75
|
+
overflow-wrap: break-word;
|
|
76
|
+
font-size: 0.85rem;
|
|
77
|
+
}
|
|
78
|
+
.subtitle {
|
|
79
|
+
color: var(--muted);
|
|
80
|
+
margin: 0 0 1.5rem;
|
|
81
|
+
font-size: 0.95rem;
|
|
82
|
+
}
|
|
83
|
+
.muted {
|
|
84
|
+
color: var(--muted);
|
|
85
|
+
}
|
|
86
|
+
.row {
|
|
87
|
+
display: flex;
|
|
88
|
+
gap: 0.5rem;
|
|
89
|
+
align-items: center;
|
|
90
|
+
}
|
|
91
|
+
.empty {
|
|
92
|
+
color: var(--muted);
|
|
93
|
+
padding: 1.5rem 0;
|
|
94
|
+
text-align: center;
|
|
95
|
+
}
|
|
96
|
+
dl {
|
|
97
|
+
display: grid;
|
|
98
|
+
grid-template-columns: 9rem 1fr;
|
|
99
|
+
gap: 0.35rem 1rem;
|
|
100
|
+
margin: 0;
|
|
101
|
+
font-size: 0.92rem;
|
|
102
|
+
}
|
|
103
|
+
dt {
|
|
104
|
+
color: var(--muted);
|
|
105
|
+
}
|
|
106
|
+
dd {
|
|
107
|
+
margin: 0;
|
|
108
|
+
overflow-wrap: break-word;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* ---- app shell: dark sidebar + main ---- */
|
|
112
|
+
body.with-sidebar {
|
|
113
|
+
display: flex;
|
|
114
|
+
}
|
|
115
|
+
.sidebar {
|
|
116
|
+
width: 230px;
|
|
117
|
+
flex-shrink: 0;
|
|
118
|
+
background: var(--sidebar-bg);
|
|
119
|
+
color: var(--sidebar-text);
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
padding: 1.25rem 0.75rem;
|
|
123
|
+
position: sticky;
|
|
124
|
+
top: 0;
|
|
125
|
+
height: 100vh;
|
|
126
|
+
}
|
|
127
|
+
.brand {
|
|
128
|
+
color: #fff;
|
|
129
|
+
font-weight: 700;
|
|
130
|
+
font-size: 1.05rem;
|
|
131
|
+
padding: 0 0.75rem 1.25rem;
|
|
132
|
+
letter-spacing: 0.02em;
|
|
133
|
+
overflow: hidden;
|
|
134
|
+
text-overflow: ellipsis;
|
|
135
|
+
white-space: nowrap;
|
|
136
|
+
}
|
|
137
|
+
.brand .dot {
|
|
138
|
+
color: var(--accent);
|
|
139
|
+
}
|
|
140
|
+
.brand a {
|
|
141
|
+
color: inherit;
|
|
142
|
+
text-decoration: none;
|
|
143
|
+
}
|
|
144
|
+
.sidebar nav a {
|
|
145
|
+
display: block;
|
|
146
|
+
color: var(--sidebar-text);
|
|
147
|
+
text-decoration: none;
|
|
148
|
+
padding: 0.55rem 0.75rem;
|
|
149
|
+
border-radius: var(--radius-sm);
|
|
150
|
+
margin-bottom: 2px;
|
|
151
|
+
font-size: 0.95rem;
|
|
152
|
+
}
|
|
153
|
+
.sidebar nav a:hover {
|
|
154
|
+
background: rgba(255, 255, 255, 0.06);
|
|
155
|
+
color: #fff;
|
|
156
|
+
}
|
|
157
|
+
.sidebar nav a.active {
|
|
158
|
+
background: var(--accent);
|
|
159
|
+
color: var(--accent-contrast);
|
|
160
|
+
font-weight: 600;
|
|
161
|
+
}
|
|
162
|
+
.sidebar .sidebar-end {
|
|
163
|
+
margin-top: auto;
|
|
164
|
+
}
|
|
165
|
+
.sidebar footer {
|
|
166
|
+
padding: 0.75rem;
|
|
167
|
+
font-size: 0.75rem;
|
|
168
|
+
color: var(--sidebar-dim);
|
|
169
|
+
}
|
|
170
|
+
body.with-sidebar > main {
|
|
171
|
+
flex: 1;
|
|
172
|
+
min-width: 0;
|
|
173
|
+
padding: 2rem 2.5rem;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* ---- host chrome: top bar + centered main ---- */
|
|
177
|
+
.topbar {
|
|
178
|
+
background: var(--sidebar-bg);
|
|
179
|
+
color: #fff;
|
|
180
|
+
padding: 14px 24px;
|
|
181
|
+
display: flex;
|
|
182
|
+
align-items: center;
|
|
183
|
+
gap: 12px;
|
|
184
|
+
}
|
|
185
|
+
.topbar a {
|
|
186
|
+
color: var(--sidebar-text);
|
|
187
|
+
text-decoration: none;
|
|
188
|
+
}
|
|
189
|
+
.topbar a:hover {
|
|
190
|
+
color: #fff;
|
|
191
|
+
}
|
|
192
|
+
main.narrow {
|
|
193
|
+
max-width: 760px;
|
|
194
|
+
margin: 24px auto;
|
|
195
|
+
padding: 0 16px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* ---- hash-routed pages ---- */
|
|
199
|
+
.page {
|
|
200
|
+
display: none;
|
|
201
|
+
}
|
|
202
|
+
.page.visible {
|
|
203
|
+
display: block;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* ---- cards & panels ---- */
|
|
207
|
+
.cards {
|
|
208
|
+
display: grid;
|
|
209
|
+
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
210
|
+
gap: 1rem;
|
|
211
|
+
margin-bottom: 1.5rem;
|
|
212
|
+
}
|
|
213
|
+
.card {
|
|
214
|
+
background: var(--panel);
|
|
215
|
+
border: 1px solid var(--border);
|
|
216
|
+
border-radius: var(--radius);
|
|
217
|
+
}
|
|
218
|
+
.cards .card {
|
|
219
|
+
padding: 1rem 1.25rem;
|
|
220
|
+
}
|
|
221
|
+
.card .label {
|
|
222
|
+
color: var(--muted);
|
|
223
|
+
font-size: 0.8rem;
|
|
224
|
+
text-transform: uppercase;
|
|
225
|
+
letter-spacing: 0.05em;
|
|
226
|
+
}
|
|
227
|
+
.card .value {
|
|
228
|
+
font-size: 1.6rem;
|
|
229
|
+
font-weight: 700;
|
|
230
|
+
margin-top: 0.25rem;
|
|
231
|
+
}
|
|
232
|
+
.card > h2 {
|
|
233
|
+
margin: 0;
|
|
234
|
+
padding: 12px 16px;
|
|
235
|
+
font-size: 15px;
|
|
236
|
+
border-bottom: 1px solid var(--border);
|
|
237
|
+
display: flex;
|
|
238
|
+
align-items: center;
|
|
239
|
+
justify-content: space-between;
|
|
240
|
+
}
|
|
241
|
+
.card .body {
|
|
242
|
+
padding: 12px 16px 16px;
|
|
243
|
+
}
|
|
244
|
+
.panel {
|
|
245
|
+
background: var(--panel);
|
|
246
|
+
border: 1px solid var(--border);
|
|
247
|
+
border-radius: var(--radius);
|
|
248
|
+
padding: 1.25rem;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* ---- tables ---- */
|
|
252
|
+
table {
|
|
253
|
+
width: 100%;
|
|
254
|
+
border-collapse: collapse;
|
|
255
|
+
font-size: 0.92rem;
|
|
256
|
+
}
|
|
257
|
+
th {
|
|
258
|
+
text-align: left;
|
|
259
|
+
color: var(--muted);
|
|
260
|
+
font-weight: 600;
|
|
261
|
+
font-size: 0.8rem;
|
|
262
|
+
text-transform: uppercase;
|
|
263
|
+
letter-spacing: 0.04em;
|
|
264
|
+
}
|
|
265
|
+
th,
|
|
266
|
+
td {
|
|
267
|
+
padding: 0.6rem 0.75rem;
|
|
268
|
+
border-bottom: 1px solid var(--border);
|
|
269
|
+
}
|
|
270
|
+
tr:last-child td {
|
|
271
|
+
border-bottom: none;
|
|
272
|
+
}
|
|
273
|
+
tbody tr.clickable {
|
|
274
|
+
cursor: pointer;
|
|
275
|
+
}
|
|
276
|
+
tbody tr.clickable:hover td {
|
|
277
|
+
background: var(--bg);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* ---- buttons & inputs ---- */
|
|
281
|
+
button {
|
|
282
|
+
font: inherit;
|
|
283
|
+
border: 1px solid var(--border);
|
|
284
|
+
background: var(--panel);
|
|
285
|
+
color: var(--text);
|
|
286
|
+
border-radius: var(--radius-sm);
|
|
287
|
+
padding: 0.45rem 0.9rem;
|
|
288
|
+
cursor: pointer;
|
|
289
|
+
}
|
|
290
|
+
button:hover {
|
|
291
|
+
border-color: var(--accent);
|
|
292
|
+
color: var(--accent);
|
|
293
|
+
}
|
|
294
|
+
button.primary {
|
|
295
|
+
background: var(--accent);
|
|
296
|
+
border-color: var(--accent);
|
|
297
|
+
color: var(--accent-contrast);
|
|
298
|
+
font-weight: 600;
|
|
299
|
+
}
|
|
300
|
+
button.primary:hover {
|
|
301
|
+
opacity: 0.92;
|
|
302
|
+
color: var(--accent-contrast);
|
|
303
|
+
}
|
|
304
|
+
button:disabled {
|
|
305
|
+
opacity: 0.5;
|
|
306
|
+
cursor: default;
|
|
307
|
+
}
|
|
308
|
+
input[type="text"],
|
|
309
|
+
input[type="password"] {
|
|
310
|
+
font: inherit;
|
|
311
|
+
padding: 0.5rem 0.75rem;
|
|
312
|
+
border: 1px solid var(--border);
|
|
313
|
+
border-radius: var(--radius-sm);
|
|
314
|
+
min-width: 0;
|
|
315
|
+
width: 100%;
|
|
316
|
+
}
|
|
317
|
+
.row > input[type="text"] {
|
|
318
|
+
flex: 1;
|
|
319
|
+
width: auto;
|
|
320
|
+
}
|
|
321
|
+
input:focus {
|
|
322
|
+
outline: 2px solid var(--accent-soft);
|
|
323
|
+
border-color: var(--accent);
|
|
324
|
+
}
|
|
325
|
+
select {
|
|
326
|
+
font: inherit;
|
|
327
|
+
padding: 0.45rem 0.6rem;
|
|
328
|
+
border: 1px solid var(--border);
|
|
329
|
+
border-radius: var(--radius-sm);
|
|
330
|
+
background: var(--panel);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* ---- badges & chips ---- */
|
|
334
|
+
.badge {
|
|
335
|
+
display: inline-block;
|
|
336
|
+
padding: 0.1rem 0.5rem;
|
|
337
|
+
border-radius: 999px;
|
|
338
|
+
font-size: 0.75rem;
|
|
339
|
+
font-weight: 600;
|
|
340
|
+
}
|
|
341
|
+
.badge.ok {
|
|
342
|
+
background: var(--ok-soft);
|
|
343
|
+
color: var(--ok);
|
|
344
|
+
}
|
|
345
|
+
.badge.err {
|
|
346
|
+
background: var(--err-soft);
|
|
347
|
+
color: var(--err);
|
|
348
|
+
}
|
|
349
|
+
.badge.warn {
|
|
350
|
+
background: var(--warn-soft);
|
|
351
|
+
color: var(--warn);
|
|
352
|
+
}
|
|
353
|
+
.badge.info {
|
|
354
|
+
background: var(--info-soft);
|
|
355
|
+
color: var(--info);
|
|
356
|
+
}
|
|
357
|
+
.badge.neutral {
|
|
358
|
+
background: var(--neutral-soft);
|
|
359
|
+
color: var(--neutral);
|
|
360
|
+
}
|
|
361
|
+
.chip {
|
|
362
|
+
font-size: 12px;
|
|
363
|
+
font-weight: 600;
|
|
364
|
+
border-radius: 999px;
|
|
365
|
+
padding: 2px 10px;
|
|
366
|
+
}
|
|
367
|
+
.chip.on {
|
|
368
|
+
background: var(--ok-soft);
|
|
369
|
+
color: var(--ok);
|
|
370
|
+
}
|
|
371
|
+
.chip.off {
|
|
372
|
+
background: var(--accent-soft);
|
|
373
|
+
color: var(--muted);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* ---- forms (settings) ---- */
|
|
377
|
+
.banner {
|
|
378
|
+
border-radius: var(--radius-sm);
|
|
379
|
+
padding: 10px 14px;
|
|
380
|
+
margin-bottom: 16px;
|
|
381
|
+
font-weight: 500;
|
|
382
|
+
}
|
|
383
|
+
.banner.ok {
|
|
384
|
+
background: var(--ok-soft);
|
|
385
|
+
color: var(--ok);
|
|
386
|
+
}
|
|
387
|
+
.banner.warn {
|
|
388
|
+
background: var(--err-soft);
|
|
389
|
+
color: var(--err);
|
|
390
|
+
}
|
|
391
|
+
.field {
|
|
392
|
+
margin-bottom: 12px;
|
|
393
|
+
}
|
|
394
|
+
.field label {
|
|
395
|
+
display: block;
|
|
396
|
+
font-weight: 600;
|
|
397
|
+
font-size: 13px;
|
|
398
|
+
margin-bottom: 2px;
|
|
399
|
+
}
|
|
400
|
+
.field .desc {
|
|
401
|
+
font-size: 12.5px;
|
|
402
|
+
color: var(--muted);
|
|
403
|
+
margin-bottom: 4px;
|
|
404
|
+
}
|
|
405
|
+
.req {
|
|
406
|
+
color: var(--err);
|
|
407
|
+
}
|
|
408
|
+
input[type="checkbox"] {
|
|
409
|
+
width: 16px;
|
|
410
|
+
height: 16px;
|
|
411
|
+
accent-color: var(--accent);
|
|
412
|
+
}
|
|
413
|
+
.field label.check {
|
|
414
|
+
display: flex;
|
|
415
|
+
align-items: center;
|
|
416
|
+
gap: 8px;
|
|
417
|
+
cursor: pointer;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* ---- chat ---- */
|
|
421
|
+
.chat-layout {
|
|
422
|
+
display: flex;
|
|
423
|
+
gap: 1rem;
|
|
424
|
+
height: calc(100vh - 9rem);
|
|
425
|
+
}
|
|
426
|
+
.conversations-panel {
|
|
427
|
+
width: 220px;
|
|
428
|
+
flex-shrink: 0;
|
|
429
|
+
display: flex;
|
|
430
|
+
flex-direction: column;
|
|
431
|
+
}
|
|
432
|
+
.conversations {
|
|
433
|
+
list-style: none;
|
|
434
|
+
margin: 0.75rem 0 0;
|
|
435
|
+
padding: 0;
|
|
436
|
+
overflow-y: auto;
|
|
437
|
+
}
|
|
438
|
+
.conversations li {
|
|
439
|
+
padding: 0.45rem 0.6rem;
|
|
440
|
+
border-radius: var(--radius-sm);
|
|
441
|
+
cursor: pointer;
|
|
442
|
+
font-size: 0.88rem;
|
|
443
|
+
overflow: hidden;
|
|
444
|
+
text-overflow: ellipsis;
|
|
445
|
+
white-space: nowrap;
|
|
446
|
+
}
|
|
447
|
+
.conversations li:hover {
|
|
448
|
+
background: var(--bg);
|
|
449
|
+
}
|
|
450
|
+
.conversations li.active {
|
|
451
|
+
background: var(--accent-soft);
|
|
452
|
+
color: var(--accent);
|
|
453
|
+
font-weight: 600;
|
|
454
|
+
}
|
|
455
|
+
.chat-main {
|
|
456
|
+
flex: 1;
|
|
457
|
+
min-width: 0;
|
|
458
|
+
display: flex;
|
|
459
|
+
flex-direction: column;
|
|
460
|
+
}
|
|
461
|
+
.chat-log {
|
|
462
|
+
flex: 1;
|
|
463
|
+
overflow-y: auto;
|
|
464
|
+
padding-right: 0.5rem;
|
|
465
|
+
}
|
|
466
|
+
.msg {
|
|
467
|
+
max-width: 82%;
|
|
468
|
+
padding: 0.6rem 0.85rem;
|
|
469
|
+
border-radius: 12px;
|
|
470
|
+
margin-bottom: 0.6rem;
|
|
471
|
+
white-space: pre-wrap;
|
|
472
|
+
overflow-wrap: break-word;
|
|
473
|
+
}
|
|
474
|
+
.msg.user {
|
|
475
|
+
background: var(--accent);
|
|
476
|
+
color: var(--accent-contrast);
|
|
477
|
+
margin-left: auto;
|
|
478
|
+
}
|
|
479
|
+
.msg.assistant {
|
|
480
|
+
background: var(--bg);
|
|
481
|
+
border: 1px solid var(--border);
|
|
482
|
+
/* assistant bubbles hold rendered markdown (chat.js), not preformatted text */
|
|
483
|
+
white-space: normal;
|
|
484
|
+
}
|
|
485
|
+
.msg.assistant p,
|
|
486
|
+
.msg.assistant ul,
|
|
487
|
+
.msg.assistant ol,
|
|
488
|
+
.msg.assistant pre,
|
|
489
|
+
.msg.assistant h3,
|
|
490
|
+
.msg.assistant h4,
|
|
491
|
+
.msg.assistant h5,
|
|
492
|
+
.msg.assistant h6 {
|
|
493
|
+
margin: 0 0 0.6rem;
|
|
494
|
+
}
|
|
495
|
+
.msg.assistant > :last-child {
|
|
496
|
+
margin-bottom: 0;
|
|
497
|
+
}
|
|
498
|
+
.msg.assistant ul,
|
|
499
|
+
.msg.assistant ol {
|
|
500
|
+
padding-left: 1.3rem;
|
|
501
|
+
}
|
|
502
|
+
.msg.assistant li {
|
|
503
|
+
margin: 0.15rem 0;
|
|
504
|
+
}
|
|
505
|
+
.msg.assistant img {
|
|
506
|
+
max-width: 100%;
|
|
507
|
+
border-radius: var(--radius-sm);
|
|
508
|
+
border: 1px solid var(--border);
|
|
509
|
+
}
|
|
510
|
+
.msg.assistant pre {
|
|
511
|
+
background: var(--panel);
|
|
512
|
+
padding: 0.6rem 0.75rem;
|
|
513
|
+
}
|
|
514
|
+
.msg.assistant h3 {
|
|
515
|
+
font-size: 1rem;
|
|
516
|
+
}
|
|
517
|
+
.msg.assistant h4,
|
|
518
|
+
.msg.assistant h5,
|
|
519
|
+
.msg.assistant h6 {
|
|
520
|
+
font-size: 0.92rem;
|
|
521
|
+
}
|
|
522
|
+
.chat-form {
|
|
523
|
+
display: flex;
|
|
524
|
+
gap: 0.5rem;
|
|
525
|
+
margin-top: 0.75rem;
|
|
526
|
+
}
|
|
527
|
+
.chat-status {
|
|
528
|
+
min-height: 1.2rem;
|
|
529
|
+
font-size: 0.8rem;
|
|
530
|
+
color: var(--muted);
|
|
531
|
+
margin-top: 0.4rem;
|
|
532
|
+
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as installApp, c as addRegistry, d as removeRegistry, g as loadApp, i as resolveAppConfig, n as createServer, o as removeApp, s as updateApp, t as Store } from "./store-
|
|
2
|
+
import { a as installApp, c as addRegistry, d as removeRegistry, g as loadApp, i as resolveAppConfig, n as createServer, o as removeApp, s as updateApp, t as Store } from "./store-Ckx0oLB6.mjs";
|
|
3
3
|
import { APP_NAME_PATTERN, AppSdkError } from "@alashi/apps-sdk";
|
|
4
4
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { ClaudeCodeProvider } from "@alashi/provider-claude";
|
|
7
8
|
import { serve } from "@hono/node-server";
|
|
8
|
-
import { ClaudeCodeProvider } from "alashi-provider-claude";
|
|
9
9
|
import { Command } from "commander";
|
|
10
10
|
//#region src/create.ts
|
|
11
11
|
const TEMPLATE_DIR = fileURLToPath(new URL("../templates/basic-app", import.meta.url));
|
|
@@ -43,17 +43,20 @@ async function scaffoldApp(name, targetDir) {
|
|
|
43
43
|
const program = new Command();
|
|
44
44
|
const store = new Store();
|
|
45
45
|
program.name("alashi").description("Install, manage, and run Claude Code-powered apps");
|
|
46
|
-
async function serveDashboard(portArg) {
|
|
46
|
+
async function serveDashboard(portArg, hostArg) {
|
|
47
47
|
const config = await store.readGlobalConfig();
|
|
48
48
|
const port = portArg ? Number(portArg) : config.port ?? 4141;
|
|
49
49
|
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new Error(`Invalid port: ${portArg}`);
|
|
50
|
+
const hostname = hostArg ?? config.host ?? "127.0.0.1";
|
|
50
51
|
const server = createServer(store, new ClaudeCodeProvider());
|
|
51
52
|
await server.scheduler.start();
|
|
52
53
|
const httpServer = serve({
|
|
53
54
|
fetch: server.app.fetch,
|
|
54
|
-
port
|
|
55
|
+
port,
|
|
56
|
+
hostname
|
|
55
57
|
}, (info) => {
|
|
56
58
|
console.log(`alashi dashboard at http://localhost:${info.port}`);
|
|
59
|
+
if (hostname !== "127.0.0.1" && hostname !== "localhost") console.log(` WARNING: listening on ${hostname} — the dashboard has no authentication`);
|
|
57
60
|
});
|
|
58
61
|
const shutdown = () => {
|
|
59
62
|
httpServer.close();
|
|
@@ -62,7 +65,7 @@ async function serveDashboard(portArg) {
|
|
|
62
65
|
process.on("SIGINT", shutdown);
|
|
63
66
|
process.on("SIGTERM", shutdown);
|
|
64
67
|
}
|
|
65
|
-
program.command("serve", { isDefault: true }).option("-p, --port <port>", "port to listen on (default: config port or 4141)").description("Serve the web dashboard (the default when no command is given)").action(async (options) => serveDashboard(options.port));
|
|
68
|
+
program.command("serve", { isDefault: true }).option("-p, --port <port>", "port to listen on (default: config port or 4141)").option("--host <host>", "address to bind (default: 127.0.0.1; the dashboard has no auth)").description("Serve the web dashboard (the default when no command is given)").action(async (options) => serveDashboard(options.port, options.host));
|
|
66
69
|
program.command("create").argument("<name>", "app name (lowercase letters, digits, hyphens)").argument("[directory]", "target directory (default: ./<name>)").description("Scaffold a new app from the basic template").action(async (name, directory) => {
|
|
67
70
|
const target = directory ?? name;
|
|
68
71
|
const files = await scaffoldApp(name, resolve(target));
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/create.ts","../src/cli.ts"],"sourcesContent":["import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { APP_NAME_PATTERN, AppSdkError } from '@alashi/apps-sdk';\n\n// Works from both src/ (tests) and dist/ (published build) — the templates\n// dir sits one level up in the package root either way.\nconst TEMPLATE_DIR = fileURLToPath(new URL('../templates/basic-app', import.meta.url));\n\n// npm strips .gitignore from published packages, so it ships unprefixed.\nconst RENAMES: Record<string, string> = { gitignore: '.gitignore' };\n\n/**\n * Scaffolds a new app from the basic-app template into targetDir,\n * substituting the app name. Returns the created files, relative to\n * targetDir. Refuses to write into a non-empty directory.\n */\nexport async function scaffoldApp(name: string, targetDir: string): Promise<string[]> {\n if (!APP_NAME_PATTERN.test(name)) {\n throw new AppSdkError(\n `Invalid app name \"${name}\": use lowercase letters, digits, and hyphens (max 64 chars)`,\n );\n }\n const existing = await readdir(targetDir).catch(() => undefined);\n if (existing && existing.length > 0) {\n throw new AppSdkError(`Directory is not empty: ${targetDir}`);\n }\n\n const written: string[] = [];\n async function copyDir(rel: string): Promise<void> {\n const entries = await readdir(join(TEMPLATE_DIR, rel), { withFileTypes: true });\n await mkdir(join(targetDir, rel), { recursive: true });\n for (const entry of entries) {\n const relPath = join(rel, entry.name);\n if (entry.isDirectory()) {\n await copyDir(relPath);\n continue;\n }\n const content = await readFile(join(TEMPLATE_DIR, relPath), 'utf8');\n const outPath = join(rel, RENAMES[entry.name] ?? entry.name);\n await writeFile(join(targetDir, outPath), content.replaceAll('__APP_NAME__', name), 'utf8');\n written.push(outPath);\n }\n }\n await copyDir('');\n return written.sort();\n}\n","#!/usr/bin/env node\nimport { resolve } from 'node:path';\nimport { serve } from '@hono/node-server';\nimport { ClaudeCodeProvider } from 'alashi-provider-claude';\nimport { Command } from 'commander';\nimport { scaffoldApp } from './create.js';\nimport { installApp, removeApp, updateApp } from './installer.js';\nimport { loadApp } from './loader.js';\nimport { addRegistry, removeRegistry } from './registry.js';\nimport { resolveAppConfig } from './runtime.js';\nimport { createServer } from './server.js';\nimport { Store } from './store.js';\n\nconst program = new Command();\nconst store = new Store();\n\nprogram.name('alashi').description('Install, manage, and run Claude Code-powered apps');\n\nasync function serveDashboard(portArg?: string): Promise<void> {\n const config = await store.readGlobalConfig();\n const port = portArg ? Number(portArg) : (config.port ?? 4141);\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error(`Invalid port: ${portArg}`);\n }\n const server = createServer(store, new ClaudeCodeProvider());\n await server.scheduler.start();\n const httpServer = serve({ fetch: server.app.fetch, port }, (info) => {\n console.log(`alashi dashboard at http://localhost:${info.port}`);\n });\n const shutdown = (): void => {\n httpServer.close();\n void server.close().finally(() => process.exit(0));\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nprogram\n .command('serve', { isDefault: true })\n .option('-p, --port <port>', 'port to listen on (default: config port or 4141)')\n .description('Serve the web dashboard (the default when no command is given)')\n .action(async (options: { port?: string }) => serveDashboard(options.port));\n\nprogram\n .command('create')\n .argument('<name>', 'app name (lowercase letters, digits, hyphens)')\n .argument('[directory]', 'target directory (default: ./<name>)')\n .description('Scaffold a new app from the basic template')\n .action(async (name: string, directory?: string) => {\n const target = directory ?? name;\n const files = await scaffoldApp(name, resolve(target));\n console.log(`Created ${name}/`);\n for (const file of files) console.log(` ${file}`);\n console.log('\\nNext steps:');\n console.log(` cd ${target}`);\n console.log(' npm install');\n console.log(' alashi install .');\n console.log(' alashi # dashboard at http://localhost:4141');\n });\n\nprogram\n .command('install')\n .argument('<source>', 'app name (via registry), git URL, or local path')\n .description('Install an app')\n .action(async (source: string) => {\n const record = await installApp(store, source);\n console.log(`Installed ${record.name}@${record.version} (${record.source.type})`);\n console.log(` data: ${store.appDataDir(record.name)}`);\n console.log(` config: ${store.appConfigPath(record.name)}`);\n await printSetupHints(record.name);\n });\n\n/** After install: what still needs configuring, and which integrations exist. */\nasync function printSetupHints(name: string): Promise<void> {\n let manifest: Awaited<ReturnType<typeof loadApp>>['manifest'];\n try {\n ({ manifest } = await loadApp(store.appRepoDir(name)));\n } catch {\n return; // install already succeeded; hints are best-effort\n }\n const { status } = await resolveAppConfig(store, manifest);\n if (status.missing.length > 0) {\n console.log(` requires: ${status.missing.join(', ')}`);\n }\n const optional = status.integrations.filter((i) => i.optional && !i.configured);\n if (optional.length > 0) {\n const list = optional.map((i) => `${i.name} (needs ${i.missing.join(', ')})`).join(', ');\n console.log(` optional integrations: ${list}`);\n }\n if (status.missing.length > 0 || optional.length > 0) {\n console.log(` configure via the dashboard settings page or the config file above`);\n }\n}\n\nprogram\n .command('update')\n .argument('<name>', 'installed app name')\n .description('Update an installed app')\n .action(async (name: string) => {\n const record = await updateApp(store, name);\n console.log(`Updated ${record.name} to ${record.version}`);\n });\n\nprogram\n .command('remove')\n .argument('<name>', 'installed app name')\n .option('--purge', 'also delete the app data and config')\n .description('Remove an installed app (keeps data unless --purge)')\n .action(async (name: string, options: { purge?: boolean }) => {\n await removeApp(store, name, { purge: options.purge ?? false });\n console.log(options.purge ? `Removed ${name} (purged)` : `Removed ${name} (data kept)`);\n });\n\nprogram\n .command('list')\n .option('--json', 'machine-readable output')\n .description('List installed apps')\n .action(async (options: { json?: boolean }) => {\n const records = await store.listInstalled();\n if (options.json) {\n console.log(JSON.stringify(records, null, 2));\n return;\n }\n if (records.length === 0) {\n console.log('No apps installed. Try: alashi install <name|git-url|path>');\n return;\n }\n for (const record of records) {\n const origin = record.source.type === 'git' ? record.source.url : record.source.path;\n console.log(`${record.name}@${record.version} ${record.source.type} ${origin}`);\n }\n });\n\nconst registry = program.command('registry').description('Manage app registries');\n\nregistry\n .command('add')\n .argument('<name>', 'registry name')\n .argument('<url>', 'index.json URL or git repo URL')\n .action(async (name: string, url: string) => {\n const index = await addRegistry(store, name, url);\n console.log(`Added registry \"${name}\" (${index.apps.length} apps)`);\n });\n\nregistry\n .command('remove')\n .argument('<name>', 'registry name')\n .action(async (name: string) => {\n await removeRegistry(store, name);\n console.log(`Removed registry \"${name}\"`);\n });\n\nregistry.command('list').action(async () => {\n const config = await store.readGlobalConfig();\n if (config.registries.length === 0) {\n console.log('No registries configured.');\n return;\n }\n for (const r of config.registries) console.log(`${r.name} ${r.url}`);\n});\n\nprogram.parseAsync().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : err);\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/create.ts","../src/cli.ts"],"sourcesContent":["import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { APP_NAME_PATTERN, AppSdkError } from '@alashi/apps-sdk';\n\n// Works from both src/ (tests) and dist/ (published build) — the templates\n// dir sits one level up in the package root either way.\nconst TEMPLATE_DIR = fileURLToPath(new URL('../templates/basic-app', import.meta.url));\n\n// npm strips .gitignore from published packages, so it ships unprefixed.\nconst RENAMES: Record<string, string> = { gitignore: '.gitignore' };\n\n/**\n * Scaffolds a new app from the basic-app template into targetDir,\n * substituting the app name. Returns the created files, relative to\n * targetDir. Refuses to write into a non-empty directory.\n */\nexport async function scaffoldApp(name: string, targetDir: string): Promise<string[]> {\n if (!APP_NAME_PATTERN.test(name)) {\n throw new AppSdkError(\n `Invalid app name \"${name}\": use lowercase letters, digits, and hyphens (max 64 chars)`,\n );\n }\n const existing = await readdir(targetDir).catch(() => undefined);\n if (existing && existing.length > 0) {\n throw new AppSdkError(`Directory is not empty: ${targetDir}`);\n }\n\n const written: string[] = [];\n async function copyDir(rel: string): Promise<void> {\n const entries = await readdir(join(TEMPLATE_DIR, rel), { withFileTypes: true });\n await mkdir(join(targetDir, rel), { recursive: true });\n for (const entry of entries) {\n const relPath = join(rel, entry.name);\n if (entry.isDirectory()) {\n await copyDir(relPath);\n continue;\n }\n const content = await readFile(join(TEMPLATE_DIR, relPath), 'utf8');\n const outPath = join(rel, RENAMES[entry.name] ?? entry.name);\n await writeFile(join(targetDir, outPath), content.replaceAll('__APP_NAME__', name), 'utf8');\n written.push(outPath);\n }\n }\n await copyDir('');\n return written.sort();\n}\n","#!/usr/bin/env node\nimport { resolve } from 'node:path';\nimport { ClaudeCodeProvider } from '@alashi/provider-claude';\nimport { serve } from '@hono/node-server';\nimport { Command } from 'commander';\nimport { scaffoldApp } from './create.js';\nimport { installApp, removeApp, updateApp } from './installer.js';\nimport { loadApp } from './loader.js';\nimport { addRegistry, removeRegistry } from './registry.js';\nimport { resolveAppConfig } from './runtime.js';\nimport { createServer } from './server.js';\nimport { Store } from './store.js';\n\nconst program = new Command();\nconst store = new Store();\n\nprogram.name('alashi').description('Install, manage, and run Claude Code-powered apps');\n\nasync function serveDashboard(portArg?: string, hostArg?: string): Promise<void> {\n const config = await store.readGlobalConfig();\n const port = portArg ? Number(portArg) : (config.port ?? 4141);\n if (!Number.isInteger(port) || port < 0 || port > 65535) {\n throw new Error(`Invalid port: ${portArg}`);\n }\n // Loopback by default: the dashboard has no auth, so it must not be\n // LAN-reachable unless the user explicitly opts in with --host.\n const hostname = hostArg ?? config.host ?? '127.0.0.1';\n const server = createServer(store, new ClaudeCodeProvider());\n await server.scheduler.start();\n const httpServer = serve({ fetch: server.app.fetch, port, hostname }, (info) => {\n console.log(`alashi dashboard at http://localhost:${info.port}`);\n if (hostname !== '127.0.0.1' && hostname !== 'localhost') {\n console.log(` WARNING: listening on ${hostname} — the dashboard has no authentication`);\n }\n });\n const shutdown = (): void => {\n httpServer.close();\n void server.close().finally(() => process.exit(0));\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\nprogram\n .command('serve', { isDefault: true })\n .option('-p, --port <port>', 'port to listen on (default: config port or 4141)')\n .option('--host <host>', 'address to bind (default: 127.0.0.1; the dashboard has no auth)')\n .description('Serve the web dashboard (the default when no command is given)')\n .action(async (options: { port?: string; host?: string }) =>\n serveDashboard(options.port, options.host),\n );\n\nprogram\n .command('create')\n .argument('<name>', 'app name (lowercase letters, digits, hyphens)')\n .argument('[directory]', 'target directory (default: ./<name>)')\n .description('Scaffold a new app from the basic template')\n .action(async (name: string, directory?: string) => {\n const target = directory ?? name;\n const files = await scaffoldApp(name, resolve(target));\n console.log(`Created ${name}/`);\n for (const file of files) console.log(` ${file}`);\n console.log('\\nNext steps:');\n console.log(` cd ${target}`);\n console.log(' npm install');\n console.log(' alashi install .');\n console.log(' alashi # dashboard at http://localhost:4141');\n });\n\nprogram\n .command('install')\n .argument('<source>', 'app name (via registry), git URL, or local path')\n .description('Install an app')\n .action(async (source: string) => {\n const record = await installApp(store, source);\n console.log(`Installed ${record.name}@${record.version} (${record.source.type})`);\n console.log(` data: ${store.appDataDir(record.name)}`);\n console.log(` config: ${store.appConfigPath(record.name)}`);\n await printSetupHints(record.name);\n });\n\n/** After install: what still needs configuring, and which integrations exist. */\nasync function printSetupHints(name: string): Promise<void> {\n let manifest: Awaited<ReturnType<typeof loadApp>>['manifest'];\n try {\n ({ manifest } = await loadApp(store.appRepoDir(name)));\n } catch {\n return; // install already succeeded; hints are best-effort\n }\n const { status } = await resolveAppConfig(store, manifest);\n if (status.missing.length > 0) {\n console.log(` requires: ${status.missing.join(', ')}`);\n }\n const optional = status.integrations.filter((i) => i.optional && !i.configured);\n if (optional.length > 0) {\n const list = optional.map((i) => `${i.name} (needs ${i.missing.join(', ')})`).join(', ');\n console.log(` optional integrations: ${list}`);\n }\n if (status.missing.length > 0 || optional.length > 0) {\n console.log(` configure via the dashboard settings page or the config file above`);\n }\n}\n\nprogram\n .command('update')\n .argument('<name>', 'installed app name')\n .description('Update an installed app')\n .action(async (name: string) => {\n const record = await updateApp(store, name);\n console.log(`Updated ${record.name} to ${record.version}`);\n });\n\nprogram\n .command('remove')\n .argument('<name>', 'installed app name')\n .option('--purge', 'also delete the app data and config')\n .description('Remove an installed app (keeps data unless --purge)')\n .action(async (name: string, options: { purge?: boolean }) => {\n await removeApp(store, name, { purge: options.purge ?? false });\n console.log(options.purge ? `Removed ${name} (purged)` : `Removed ${name} (data kept)`);\n });\n\nprogram\n .command('list')\n .option('--json', 'machine-readable output')\n .description('List installed apps')\n .action(async (options: { json?: boolean }) => {\n const records = await store.listInstalled();\n if (options.json) {\n console.log(JSON.stringify(records, null, 2));\n return;\n }\n if (records.length === 0) {\n console.log('No apps installed. Try: alashi install <name|git-url|path>');\n return;\n }\n for (const record of records) {\n const origin = record.source.type === 'git' ? record.source.url : record.source.path;\n console.log(`${record.name}@${record.version} ${record.source.type} ${origin}`);\n }\n });\n\nconst registry = program.command('registry').description('Manage app registries');\n\nregistry\n .command('add')\n .argument('<name>', 'registry name')\n .argument('<url>', 'index.json URL or git repo URL')\n .action(async (name: string, url: string) => {\n const index = await addRegistry(store, name, url);\n console.log(`Added registry \"${name}\" (${index.apps.length} apps)`);\n });\n\nregistry\n .command('remove')\n .argument('<name>', 'registry name')\n .action(async (name: string) => {\n await removeRegistry(store, name);\n console.log(`Removed registry \"${name}\"`);\n });\n\nregistry.command('list').action(async () => {\n const config = await store.readGlobalConfig();\n if (config.registries.length === 0) {\n console.log('No registries configured.');\n return;\n }\n for (const r of config.registries) console.log(`${r.name} ${r.url}`);\n});\n\nprogram.parseAsync().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : err);\n process.exitCode = 1;\n});\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -35,6 +35,8 @@ interface RegistryRef {
|
|
|
35
35
|
interface GlobalConfig {
|
|
36
36
|
registries: RegistryRef[];
|
|
37
37
|
port?: number;
|
|
38
|
+
/** Bind address for `alashi serve`; defaults to loopback (the dashboard has no auth). */
|
|
39
|
+
host?: string;
|
|
38
40
|
/** Per-app global overrides, keyed by app name (middle config layer). */
|
|
39
41
|
apps?: Record<string, ConfigObject>;
|
|
40
42
|
}
|
|
@@ -238,9 +240,15 @@ interface AppServer {
|
|
|
238
240
|
* (omit conversationId to start a new conversation; the
|
|
239
241
|
* id is echoed in the x-conversation-id response header)
|
|
240
242
|
* GET /api/apps/:name/chat/conversations conversations, most recent first
|
|
243
|
+
* POST /api/apps/:name/chat/conversations { sessionId?, title? } -> create a conversation,
|
|
244
|
+
* optionally adopting an existing provider session (e.g. an
|
|
245
|
+
* app-run investigation) so chat continues where it left off
|
|
241
246
|
* GET /api/apps/:name/chat/:conversationId/history past turns from the provider transcript
|
|
242
247
|
* GET /api/apps/:name/jobs manifest-declared jobs with schedule/status
|
|
243
248
|
* POST /api/apps/:name/jobs/:job/run trigger a job now (409 while already running)
|
|
249
|
+
* GET /api/apps/:name/manifest read-only app definition: instructions, agents,
|
|
250
|
+
* skills (with dir contents), allowed tools,
|
|
251
|
+
* MCP servers (with configured state), jobs, model
|
|
244
252
|
* GET /api/apps/:name/config declared config schema + merged values
|
|
245
253
|
* (secrets masked) + readiness/integrations
|
|
246
254
|
* PUT /api/apps/:name/config merge keys into the per-app config layer
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/compat.ts","../src/sources.ts","../src/store.ts","../src/installer.ts","../src/loader.ts","../src/registry.ts","../src/runtime.ts","../src/scheduler.ts","../src/server.ts"],"mappings":";;;;;;;iBAOgB,sBAAsB,UAAU;;;KCCpC;EACN;EAAa;EAAa;;EAC1B;EAAe;;;KAGT,YAAY;EAAkB;EAAkB;;iBAE5C,eAAe,cAAc;;iBAwBvB,YAAY,MAAM,eAAe,kBAAkB;;iBAanD,aAAa,MAAM,eAAe,kBAAkB;;;UC9CzD;EACf;EACA;;UAGe;EACf,YAAY;EACZ;;EAEA,OAAO,eAAe;;UAGP;EACf;;EAEA;EACA;EACA;;;UAIe;EACf,eAAe;;UAGA;EACf;EACA;EACA;EACA;EACA;EACA;;;UAIe;EACf,SAAS;EACT,MAAM;;UAGS;EACf;EACA;;EAEA;EACA,QAAQ;EACR;EACA;;;;;;;cAwBW;WACF;EAET,YAAY;MAIR;MAIA;MAIA;MAIA;;EAKJ,OAAO;EAOP,WAAW;EAIX,WAAW;EAIX,cAAc;EAId,cAAc;EAId,iBAAiB;EAIjB,gBAAgB;EAIhB,kBAAkB;EAOlB,oBAA0B,QAAQ;EAIlC,kBAAwB,QAAQ,eAAe;EAI/C,cAAoB,eAAe,QAAQ;EAI3C,eAAqB,QAAQ,gBAAgB;EAI7C,cAAoB,eAAe,QAAQ;EAI3C,eAAqB,cAAc,QAAQ,eAAe;EAI1D,cAAoB,eAAe,QAAQ;EAK3C,eAAqB,cAAc,OAAO,YAAY;EAItD,aAAmB,eAAe,QAAQ;EAK1C,cAAoB,cAAc,OAAO,WAAW;EAIpD,iBAAuB,QAAQ;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/compat.ts","../src/sources.ts","../src/store.ts","../src/installer.ts","../src/loader.ts","../src/registry.ts","../src/runtime.ts","../src/scheduler.ts","../src/server.ts"],"mappings":";;;;;;;iBAOgB,sBAAsB,UAAU;;;KCCpC;EACN;EAAa;EAAa;;EAC1B;EAAe;;;KAGT,YAAY;EAAkB;EAAkB;;iBAE5C,eAAe,cAAc;;iBAwBvB,YAAY,MAAM,eAAe,kBAAkB;;iBAanD,aAAa,MAAM,eAAe,kBAAkB;;;UC9CzD;EACf;EACA;;UAGe;EACf,YAAY;EACZ;;EAEA;;EAEA,OAAO,eAAe;;UAGP;EACf;;EAEA;EACA;EACA;;;UAIe;EACf,eAAe;;UAGA;EACf;EACA;EACA;EACA;EACA;EACA;;;UAIe;EACf,SAAS;EACT,MAAM;;UAGS;EACf;EACA;;EAEA;EACA,QAAQ;EACR;EACA;;;;;;;cAwBW;WACF;EAET,YAAY;MAIR;MAIA;MAIA;MAIA;;EAKJ,OAAO;EAOP,WAAW;EAIX,WAAW;EAIX,cAAc;EAId,cAAc;EAId,iBAAiB;EAIjB,gBAAgB;EAIhB,kBAAkB;EAOlB,oBAA0B,QAAQ;EAIlC,kBAAwB,QAAQ,eAAe;EAI/C,cAAoB,eAAe,QAAQ;EAI3C,eAAqB,QAAQ,gBAAgB;EAI7C,cAAoB,eAAe,QAAQ;EAI3C,eAAqB,cAAc,QAAQ,eAAe;EAI1D,cAAoB,eAAe,QAAQ;EAK3C,eAAqB,cAAc,OAAO,YAAY;EAItD,aAAmB,eAAe,QAAQ;EAK1C,cAAoB,cAAc,OAAO,WAAW;EAIpD,iBAAuB,QAAQ;;;;UC9IhB;;EAEf;;;;;;;iBAQoB,WACpB,OAAO,OACP,iBAAiB,eACjB,UAAS,iBACR,QAAQ;iBA0EW,UAAU,OAAO,OAAO,eAAe,QAAQ;UAuBpD;;EAEf;;iBAGoB,UACpB,OAAO,OACP,cACA,UAAS,gBACR;;;UCzIc;EACf,YAAY;EACZ,UAAU;EACV;;;;;;;iBAQoB,QAAQ,kBAAkB,QAAQ;;;UC5BvC;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf,MAAM;;;;;;;iBAkCc,gBAAgB,OAAO,OAAO,UAAU,cAAc,QAAQ;iBAuB9D,gBACpB,OAAO,OACP,eACC,QAAQ;iBASW,YAAY,OAAO,OAAO,cAAc,cAAc,QAAQ;iBAW9D,eAAe,OAAO,OAAO,eAAe;UAWjD;EACf;EACA,KAAK;;;iBAIe,WAAW,OAAO,OAAO,kBAAkB,QAAQ;;;;;;;;;;;;;iBCFnD,gBACpB,OAAO,OACP,UAAU,aACV,UAAU,aACT,QAAQ;;;UC/GM;EACf,UAAU;EACV,KAAK;EACL,cAAc,gBAAgB,KAAK,eAAe;;UAGnC;EACf;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA,YAAY;;;;;;;;cAiBD;mBAQT;mBACA;UARM;UACA;UACA;;UAEA;EAER,YACE,OAAwB,OACxB,SAA0B,iBAAiB,QAAQ;EAGrD,SAAe;EAuCf;;;;;EAUA,IACE,iBACA,iBACA,UAAS,oBACR,QAAQ;;EAmCX,OAAa,kBAAkB,QAAQ;UA4B/B;;;;UCrHO;;EAEf,KAAK;;EAEL,WAAW;;EAEX,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8BK,aAAa,OAAO,OAAO,UAAU,aAAa"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as checkSdkCompatibility, a as installApp, c as addRegistry, d as removeRegistry, f as resolveApp, g as loadApp, h as updateSource, l as readCachedIndex, m as parseSourceArg, n as createServer, o as removeApp, p as fetchSource, r as buildAppContext, s as updateApp, t as Store, u as refreshRegistry } from "./store-
|
|
1
|
+
import { _ as checkSdkCompatibility, a as installApp, c as addRegistry, d as removeRegistry, f as resolveApp, g as loadApp, h as updateSource, l as readCachedIndex, m as parseSourceArg, n as createServer, o as removeApp, p as fetchSource, r as buildAppContext, s as updateApp, t as Store, u as refreshRegistry } from "./store-Ckx0oLB6.mjs";
|
|
2
2
|
export { Store, addRegistry, buildAppContext, checkSdkCompatibility, createServer, fetchSource, installApp, loadApp, parseSourceArg, readCachedIndex, refreshRegistry, removeApp, removeRegistry, resolveApp, updateApp, updateSource };
|