@akanjs/cli 2.1.0 → 2.1.1-rc.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.
Files changed (33) hide show
  1. package/README.ko.md +63 -0
  2. package/README.md +62 -0
  3. package/guidelines/componentRule/componentRule.generate.json +4 -10
  4. package/guidelines/cssRule/cssRule.generate.json +4 -10
  5. package/guidelines/docPageRule/docPageRule.generate.json +4 -10
  6. package/guidelines/docPageRule/docPageRule.instruction.md +1 -1
  7. package/guidelines/docSyncRule/docSyncRule.generate.json +4 -10
  8. package/guidelines/enumConstant/enumConstant.generate.json +4 -10
  9. package/guidelines/fieldRule/fieldRule.generate.json +4 -10
  10. package/guidelines/framework/framework.generate.json +4 -10
  11. package/guidelines/modelConstant/modelConstant.generate.json +4 -10
  12. package/guidelines/modelDictionary/modelDictionary.generate.json +4 -10
  13. package/guidelines/modelDocument/modelDocument.generate.json +4 -10
  14. package/guidelines/modelService/modelService.generate.json +4 -10
  15. package/guidelines/modelSignal/modelSignal.generate.json +4 -10
  16. package/guidelines/modelStore/modelStore.generate.json +4 -10
  17. package/guidelines/modelTemplate/modelTemplate.generate.json +4 -10
  18. package/guidelines/modelUnit/modelUnit.generate.json +4 -10
  19. package/guidelines/modelUtil/modelUtil.generate.json +4 -10
  20. package/guidelines/modelView/modelView.generate.json +4 -10
  21. package/guidelines/modelZone/modelZone.generate.json +4 -10
  22. package/guidelines/moduleCodegen/moduleCodegen.generate.json +4 -10
  23. package/guidelines/moduleOverview/moduleOverview.generate.json +4 -10
  24. package/guidelines/scalarConstant/scalarConstant.generate.json +4 -10
  25. package/guidelines/scalarDictionary/scalarDictionary.generate.json +4 -10
  26. package/guidelines/scalarModule/scalarModule.generate.json +4 -10
  27. package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +4 -10
  28. package/guidelines/utilUiUsage/utilUiUsage.generate.json +4 -10
  29. package/incrementalBuilder.proc.js +455 -18
  30. package/index.js +532 -33
  31. package/package.json +3 -2
  32. package/templates/libRoot/lib/___libName__/__libName__.signal.ts +15 -0
  33. package/typecheck.proc.js +31 -0
package/index.js CHANGED
@@ -1,7 +1,329 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
13
+ var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
21
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
22
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ if (canCache)
30
+ cache.set(mod, to);
31
+ return to;
32
+ };
33
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
34
  var __require = import.meta.require;
4
35
 
36
+ // node_modules/dayjs/dayjs.min.js
37
+ var require_dayjs_min = __commonJS((exports, module) => {
38
+ (function(t, e) {
39
+ typeof exports == "object" && typeof module != "undefined" ? module.exports = e() : typeof define == "function" && define.amd ? define(e) : (t = typeof globalThis != "undefined" ? globalThis : t || self).dayjs = e();
40
+ })(exports, function() {
41
+ var t = 1000, e = 60000, n = 3600000, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $2 = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) {
42
+ var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
43
+ return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
44
+ } }, m = function(t2, e2, n2) {
45
+ var r2 = String(t2);
46
+ return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
47
+ }, v = { s: m, z: function(t2) {
48
+ var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
49
+ return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
50
+ }, m: function t2(e2, n2) {
51
+ if (e2.date() < n2.date())
52
+ return -t2(n2, e2);
53
+ var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c);
54
+ return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
55
+ }, a: function(t2) {
56
+ return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
57
+ }, p: function(t2) {
58
+ return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
59
+ }, u: function(t2) {
60
+ return t2 === undefined;
61
+ } }, g = "en", D = {};
62
+ D[g] = M;
63
+ var p = "$isDayjsObject", S = function(t2) {
64
+ return t2 instanceof _ || !(!t2 || !t2[p]);
65
+ }, w = function t2(e2, n2, r2) {
66
+ var i2;
67
+ if (!e2)
68
+ return g;
69
+ if (typeof e2 == "string") {
70
+ var s2 = e2.toLowerCase();
71
+ D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
72
+ var u2 = e2.split("-");
73
+ if (!i2 && u2.length > 1)
74
+ return t2(u2[0]);
75
+ } else {
76
+ var a2 = e2.name;
77
+ D[a2] = e2, i2 = a2;
78
+ }
79
+ return !r2 && i2 && (g = i2), i2 || !r2 && g;
80
+ }, O = function(t2, e2) {
81
+ if (S(t2))
82
+ return t2.clone();
83
+ var n2 = typeof e2 == "object" ? e2 : {};
84
+ return n2.date = t2, n2.args = arguments, new _(n2);
85
+ }, b = v;
86
+ b.l = w, b.i = S, b.w = function(t2, e2) {
87
+ return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
88
+ };
89
+ var _ = function() {
90
+ function M2(t2) {
91
+ this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
92
+ }
93
+ var m2 = M2.prototype;
94
+ return m2.parse = function(t2) {
95
+ this.$d = function(t3) {
96
+ var { date: e2, utc: n2 } = t3;
97
+ if (e2 === null)
98
+ return new Date(NaN);
99
+ if (b.u(e2))
100
+ return new Date;
101
+ if (e2 instanceof Date)
102
+ return new Date(e2);
103
+ if (typeof e2 == "string" && !/Z$/i.test(e2)) {
104
+ var r2 = e2.match($2);
105
+ if (r2) {
106
+ var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
107
+ return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
108
+ }
109
+ }
110
+ return new Date(e2);
111
+ }(t2), this.init();
112
+ }, m2.init = function() {
113
+ var t2 = this.$d;
114
+ this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
115
+ }, m2.$utils = function() {
116
+ return b;
117
+ }, m2.isValid = function() {
118
+ return !(this.$d.toString() === l);
119
+ }, m2.isSame = function(t2, e2) {
120
+ var n2 = O(t2);
121
+ return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
122
+ }, m2.isAfter = function(t2, e2) {
123
+ return O(t2) < this.startOf(e2);
124
+ }, m2.isBefore = function(t2, e2) {
125
+ return this.endOf(e2) < O(t2);
126
+ }, m2.$g = function(t2, e2, n2) {
127
+ return b.u(t2) ? this[e2] : this.set(n2, t2);
128
+ }, m2.unix = function() {
129
+ return Math.floor(this.valueOf() / 1000);
130
+ }, m2.valueOf = function() {
131
+ return this.$d.getTime();
132
+ }, m2.startOf = function(t2, e2) {
133
+ var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
134
+ var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
135
+ return r2 ? i2 : i2.endOf(a);
136
+ }, $3 = function(t3, e3) {
137
+ return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
138
+ }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
139
+ switch (f2) {
140
+ case h:
141
+ return r2 ? l2(1, 0) : l2(31, 11);
142
+ case c:
143
+ return r2 ? l2(1, M3) : l2(0, M3 + 1);
144
+ case o:
145
+ var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
146
+ return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
147
+ case a:
148
+ case d:
149
+ return $3(v2 + "Hours", 0);
150
+ case u:
151
+ return $3(v2 + "Minutes", 1);
152
+ case s:
153
+ return $3(v2 + "Seconds", 2);
154
+ case i:
155
+ return $3(v2 + "Milliseconds", 3);
156
+ default:
157
+ return this.clone();
158
+ }
159
+ }, m2.endOf = function(t2) {
160
+ return this.startOf(t2, false);
161
+ }, m2.$set = function(t2, e2) {
162
+ var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $3 = o2 === a ? this.$D + (e2 - this.$W) : e2;
163
+ if (o2 === c || o2 === h) {
164
+ var y2 = this.clone().set(d, 1);
165
+ y2.$d[l2]($3), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
166
+ } else
167
+ l2 && this.$d[l2]($3);
168
+ return this.init(), this;
169
+ }, m2.set = function(t2, e2) {
170
+ return this.clone().$set(t2, e2);
171
+ }, m2.get = function(t2) {
172
+ return this[b.p(t2)]();
173
+ }, m2.add = function(r2, f2) {
174
+ var d2, l2 = this;
175
+ r2 = Number(r2);
176
+ var $3 = b.p(f2), y2 = function(t2) {
177
+ var e2 = O(l2);
178
+ return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
179
+ };
180
+ if ($3 === c)
181
+ return this.set(c, this.$M + r2);
182
+ if ($3 === h)
183
+ return this.set(h, this.$y + r2);
184
+ if ($3 === a)
185
+ return y2(1);
186
+ if ($3 === o)
187
+ return y2(7);
188
+ var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$3] || 1, m3 = this.$d.getTime() + r2 * M3;
189
+ return b.w(m3, this);
190
+ }, m2.subtract = function(t2, e2) {
191
+ return this.add(-1 * t2, e2);
192
+ }, m2.format = function(t2) {
193
+ var e2 = this, n2 = this.$locale();
194
+ if (!this.isValid())
195
+ return n2.invalidDate || l;
196
+ var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = function(t3, n3, i3, s3) {
197
+ return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
198
+ }, d2 = function(t3) {
199
+ return b.s(s2 % 12 || 12, t3, "0");
200
+ }, $3 = f2 || function(t3, e3, n3) {
201
+ var r3 = t3 < 12 ? "AM" : "PM";
202
+ return n3 ? r3.toLowerCase() : r3;
203
+ };
204
+ return r2.replace(y, function(t3, r3) {
205
+ return r3 || function(t4) {
206
+ switch (t4) {
207
+ case "YY":
208
+ return String(e2.$y).slice(-2);
209
+ case "YYYY":
210
+ return b.s(e2.$y, 4, "0");
211
+ case "M":
212
+ return a2 + 1;
213
+ case "MM":
214
+ return b.s(a2 + 1, 2, "0");
215
+ case "MMM":
216
+ return h2(n2.monthsShort, a2, c2, 3);
217
+ case "MMMM":
218
+ return h2(c2, a2);
219
+ case "D":
220
+ return e2.$D;
221
+ case "DD":
222
+ return b.s(e2.$D, 2, "0");
223
+ case "d":
224
+ return String(e2.$W);
225
+ case "dd":
226
+ return h2(n2.weekdaysMin, e2.$W, o2, 2);
227
+ case "ddd":
228
+ return h2(n2.weekdaysShort, e2.$W, o2, 3);
229
+ case "dddd":
230
+ return o2[e2.$W];
231
+ case "H":
232
+ return String(s2);
233
+ case "HH":
234
+ return b.s(s2, 2, "0");
235
+ case "h":
236
+ return d2(1);
237
+ case "hh":
238
+ return d2(2);
239
+ case "a":
240
+ return $3(s2, u2, true);
241
+ case "A":
242
+ return $3(s2, u2, false);
243
+ case "m":
244
+ return String(u2);
245
+ case "mm":
246
+ return b.s(u2, 2, "0");
247
+ case "s":
248
+ return String(e2.$s);
249
+ case "ss":
250
+ return b.s(e2.$s, 2, "0");
251
+ case "SSS":
252
+ return b.s(e2.$ms, 3, "0");
253
+ case "Z":
254
+ return i2;
255
+ }
256
+ return null;
257
+ }(t3) || i2.replace(":", "");
258
+ });
259
+ }, m2.utcOffset = function() {
260
+ return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
261
+ }, m2.diff = function(r2, d2, l2) {
262
+ var $3, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
263
+ return b.m(y2, m3);
264
+ };
265
+ switch (M3) {
266
+ case h:
267
+ $3 = D2() / 12;
268
+ break;
269
+ case c:
270
+ $3 = D2();
271
+ break;
272
+ case f:
273
+ $3 = D2() / 3;
274
+ break;
275
+ case o:
276
+ $3 = (g2 - v2) / 604800000;
277
+ break;
278
+ case a:
279
+ $3 = (g2 - v2) / 86400000;
280
+ break;
281
+ case u:
282
+ $3 = g2 / n;
283
+ break;
284
+ case s:
285
+ $3 = g2 / e;
286
+ break;
287
+ case i:
288
+ $3 = g2 / t;
289
+ break;
290
+ default:
291
+ $3 = g2;
292
+ }
293
+ return l2 ? $3 : b.a($3);
294
+ }, m2.daysInMonth = function() {
295
+ return this.endOf(c).$D;
296
+ }, m2.$locale = function() {
297
+ return D[this.$L];
298
+ }, m2.locale = function(t2, e2) {
299
+ if (!t2)
300
+ return this.$L;
301
+ var n2 = this.clone(), r2 = w(t2, e2, true);
302
+ return r2 && (n2.$L = r2), n2;
303
+ }, m2.clone = function() {
304
+ return b.w(this.$d, this);
305
+ }, m2.toDate = function() {
306
+ return new Date(this.valueOf());
307
+ }, m2.toJSON = function() {
308
+ return this.isValid() ? this.toISOString() : null;
309
+ }, m2.toISOString = function() {
310
+ return this.$d.toISOString();
311
+ }, m2.toString = function() {
312
+ return this.$d.toUTCString();
313
+ }, M2;
314
+ }(), Y = _.prototype;
315
+ return O.prototype = Y, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
316
+ Y[t2[1]] = function(e2) {
317
+ return this.$g(e2, t2[0], t2[1]);
318
+ };
319
+ }), O.extend = function(t2, e2) {
320
+ return t2.$i || (t2(e2, _, O), t2.$i = true), O;
321
+ }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
322
+ return O(1000 * t2);
323
+ }, O.en = D[g], O.Ls = D, O.p = {}, O;
324
+ });
325
+ });
326
+
5
327
  // pkgs/@akanjs/devkit/aiEditor.ts
6
328
  import { input, select } from "@inquirer/prompts";
7
329
  import {
@@ -22,9 +344,12 @@ import { mkdir } from "fs/promises";
22
344
  var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
23
345
  var configPath = `${basePath}/config.json`;
24
346
  var akanCloudHost = process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
25
- var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/\uBA54\u3151`;
347
+ var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/api`;
26
348
  var defaultHostConfig = {};
27
- var defaultAkanGlobalConfig = { cloudHost: {}, llm: null };
349
+ var defaultAkanGlobalConfig = {
350
+ cloudHost: {},
351
+ llm: null
352
+ };
28
353
 
29
354
  // pkgs/@akanjs/devkit/fileSys.ts
30
355
  import { stat } from "fs/promises";
@@ -2138,7 +2463,6 @@ class Executor {
2138
2463
  this.logger = new Logger4(name);
2139
2464
  this.logs = [];
2140
2465
  this.cwdPath = cwdPath;
2141
- //! TODO: 테스트 확인 필요
2142
2466
  }
2143
2467
  #stdout(data) {
2144
2468
  if (Executor.verbose)
@@ -3980,6 +4304,16 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
3980
4304
  }
3981
4305
  return [...boundaries.values()].sort((a, b) => a.segments.join("/").localeCompare(b.segments.join("/")));
3982
4306
  }
4307
+ function hasAncestorRootBoundary(boundary, boundaries) {
4308
+ return boundaries.some((candidate) => candidate !== boundary && candidate.segments.length < boundary.segments.length && candidate.segments.every((segment, index) => boundary.segments[index] === segment));
4309
+ }
4310
+ function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
4311
+ const rootLayoutKey = pageKeys.find((key) => {
4312
+ const segments = getRootBoundarySegments(key);
4313
+ return segments !== null && segments.length === 0;
4314
+ });
4315
+ return rootLayoutKey ? path10.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
4316
+ }
3983
4317
  function routePrefixForSegments(segments) {
3984
4318
  const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
3985
4319
  return visible[0] ?? null;
@@ -3996,21 +4330,27 @@ async function writeGeneratedRootLayoutFile(opts) {
3996
4330
  await mkdir3(path10.dirname(absPath), { recursive: true });
3997
4331
  const sourceRel = opts.boundary.sourceAbsPath ? path10.relative(path10.dirname(absPath), opts.boundary.sourceAbsPath).split(path10.sep).join("/") : null;
3998
4332
  const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
4333
+ const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
4334
+ const inheritedSourceRel = inheritedSourceAbsPath ? path10.relative(path10.dirname(absPath), inheritedSourceAbsPath).split(path10.sep).join("/") : null;
4335
+ const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
3999
4336
  const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
4000
4337
  void st;
4001
4338
  ` : `import "@apps/${opts.appName}/client";
4339
+ `;
4340
+ const inheritedImport = inheritedSourceSpecifier ? `import * as inheritedLayout from ${JSON.stringify(inheritedSourceSpecifier)};
4341
+ ` : `const inheritedLayout = {};
4002
4342
  `;
4003
4343
  const prefix = routePrefixForSegments(opts.boundary.segments);
4004
4344
  const userImport = sourceSpecifier ? `import UserLayout, * as userLayout from ${JSON.stringify(sourceSpecifier)};
4005
4345
  ` : `const UserLayout = ({ children }) => children;
4006
4346
  const userLayout = {};
4007
4347
  `;
4008
- const source = `import type { LayoutProps, PageProps } from "akanjs/client";
4348
+ const source = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
4009
4349
  import { loadFonts } from "akanjs/client";
4010
4350
  import { System } from "akanjs/ui";
4011
4351
  import { env } from "@apps/${opts.appName}/env/env.client";
4012
- ${clientImport}${userImport}
4013
- const userFonts = userLayout.fonts ?? [];
4352
+ ${clientImport}${inheritedImport}${userImport}
4353
+ const userFonts = userLayout.fonts ?? inheritedLayout.fonts ?? [];
4014
4354
  const defaultFonts = userFonts.filter((font) => font.default);
4015
4355
  if (defaultFonts.length > 1) throw new Error("[route-convention] only one default font is allowed per root layout");
4016
4356
  const defaultFont = defaultFonts[0];
@@ -4018,7 +4358,9 @@ const defaultFontClassName = defaultFont ? (defaultFont.className ?? \`font-\${d
4018
4358
 
4019
4359
  export async function generateHead(props: PageProps) {
4020
4360
  if (userLayout.generateHead) return userLayout.generateHead(props);
4021
- return userLayout.head;
4361
+ if (userLayout.head !== undefined) return userLayout.head;
4362
+ if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
4363
+ return inheritedLayout.head;
4022
4364
  }
4023
4365
 
4024
4366
  export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
@@ -4028,19 +4370,31 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
4028
4370
  appName=${JSON.stringify(opts.appName)}
4029
4371
  ${prefix ? `prefix=${JSON.stringify(prefix)}
4030
4372
  ` : ""}params={params}
4031
- manifest={userLayout.manifest}
4373
+ manifest={userLayout.manifest ?? inheritedLayout.manifest}
4032
4374
  env={env}
4033
- theme={userLayout.theme}
4375
+ theme={userLayout.theme ?? inheritedLayout.theme}
4034
4376
  fonts={loadFonts(userFonts)}
4035
4377
  className={defaultFontClassName}
4036
- gaTrackingId={userLayout.gaTrackingId}
4037
- layoutStyle={userLayout.layoutStyle}
4038
- reconnect={userLayout.reconnect ?? false}
4378
+ gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
4379
+ layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
4380
+ reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
4039
4381
  >
4040
4382
  <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>
4041
4383
  </System.Provider>
4042
4384
  );
4043
4385
  }
4386
+ ` : `import type { LayoutProps, PageProps } from "akanjs/client";
4387
+ ${inheritedImport}${userImport}
4388
+ export async function generateHead(props: PageProps) {
4389
+ if (userLayout.generateHead) return userLayout.generateHead(props);
4390
+ if (userLayout.head !== undefined) return userLayout.head;
4391
+ if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
4392
+ return inheritedLayout.head;
4393
+ }
4394
+
4395
+ export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
4396
+ return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
4397
+ }
4044
4398
  `;
4045
4399
  await Bun.write(absPath, source);
4046
4400
  return absPath;
@@ -4049,6 +4403,8 @@ async function resolveSsrPageEntries(opts) {
4049
4403
  const absPageDir = path10.resolve(opts.appCwdPath, "page");
4050
4404
  const hasSt = await appHasStModule(opts.appCwdPath);
4051
4405
  const basePaths = opts.basePaths ?? [];
4406
+ const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
4407
+ const rootBoundaries = findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths);
4052
4408
  const rootLayoutKeys = new Set(opts.pageKeys.filter((key) => {
4053
4409
  const segments = getRootBoundarySegments(key);
4054
4410
  return segments !== null && isRootBoundarySegments(segments, basePaths);
@@ -4057,15 +4413,17 @@ async function resolveSsrPageEntries(opts) {
4057
4413
  key,
4058
4414
  moduleAbsPath: path10.resolve(absPageDir, key)
4059
4415
  }));
4060
- const generated = await Promise.all(findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths).map(async (boundary) => ({
4416
+ const generated = await Promise.all(rootBoundaries.map(async (boundary) => ({
4061
4417
  key: implicitRootLayoutKey(boundary.segments),
4062
4418
  moduleAbsPath: await writeGeneratedRootLayoutFile({
4063
4419
  appCwdPath: opts.appCwdPath,
4064
4420
  appName: opts.appName,
4065
4421
  boundary,
4066
- includeStInit: hasSt && boundary.segments.length === 0
4422
+ rootSourceAbsPath,
4423
+ includeStInit: hasSt && boundary.segments.length === 0,
4424
+ includeSystemProvider: !hasAncestorRootBoundary(boundary, rootBoundaries)
4067
4425
  }),
4068
- seedAbsPaths: boundary.sourceAbsPath ? [boundary.sourceAbsPath] : []
4426
+ seedAbsPaths: [...new Set([boundary.sourceAbsPath, rootSourceAbsPath].filter((absPath) => absPath !== null))]
4069
4427
  })));
4070
4428
  const entries = [...base, ...generated];
4071
4429
  entries.sort((a, b) => a.key.localeCompare(b.key));
@@ -7040,6 +7398,13 @@ function formatBytes(bytes) {
7040
7398
  }
7041
7399
  // pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
7042
7400
  import path30 from "path";
7401
+ import { optimize } from "@tailwindcss/node";
7402
+ function prepareCssAsset(command, basePath2, cssText) {
7403
+ if (command !== "build")
7404
+ return cssText;
7405
+ return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
7406
+ }
7407
+
7043
7408
  class SsrBaseArtifactBuilder {
7044
7409
  #app;
7045
7410
  #command;
@@ -7131,14 +7496,15 @@ class SsrBaseArtifactBuilder {
7131
7496
  }
7132
7497
  async#writeCssAsset(basePath2, cssText) {
7133
7498
  const cssAssetName = basePath2 || "root";
7499
+ const preparedCssText = await prepareCssAsset(this.#command, basePath2, cssText);
7134
7500
  const cssHash = Bun.hash(`${basePath2}
7135
- ${cssText}`).toString(36);
7501
+ ${preparedCssText}`).toString(36);
7136
7502
  const [cssRelPath, cssUrl] = [
7137
7503
  `styles/${cssAssetName}-${cssHash}.css`,
7138
7504
  `/_akan/styles/${cssAssetName}-${cssHash}.css`
7139
7505
  ];
7140
- await Bun.write(path30.join(this.#absArtifactDir, cssRelPath), cssText);
7141
- this.#app.verbose(`[base-artifact] wrote ${cssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
7506
+ await Bun.write(path30.join(this.#absArtifactDir, cssRelPath), preparedCssText);
7507
+ this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
7142
7508
  return [basePath2, { cssUrl, cssRelPath }];
7143
7509
  }
7144
7510
  }
@@ -9405,6 +9771,77 @@ import { Box as Box2, Newline, Text as Text2, useInput as useInput2 } from "ink"
9405
9771
  import { useEffect as useEffect3, useState as useState3 } from "react";
9406
9772
  import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
9407
9773
  "use client";
9774
+ // pkgs/@akanjs/devkit/cloud/cloudApi.ts
9775
+ var import_dayjs = __toESM(require_dayjs_min(), 1);
9776
+
9777
+ class HttpClient2 {
9778
+ baseUrl;
9779
+ constructor(baseUrl) {
9780
+ this.baseUrl = baseUrl;
9781
+ }
9782
+ async get(url, { headers } = {}) {
9783
+ const response = await fetch(`${this.baseUrl}${url}`, {
9784
+ headers: { "Content-Type": "application/json", ...headers }
9785
+ });
9786
+ return response.json();
9787
+ }
9788
+ async post(url, data, { headers } = {}) {
9789
+ const isFormData = data instanceof FormData;
9790
+ const response = await fetch(`${this.baseUrl}${url}`, {
9791
+ method: "POST",
9792
+ body: isFormData ? data : JSON.stringify(data),
9793
+ headers: isFormData ? headers : { "Content-Type": "application/json", ...headers }
9794
+ });
9795
+ return response.json();
9796
+ }
9797
+ }
9798
+
9799
+ class CloudApi {
9800
+ api;
9801
+ #accessToken = null;
9802
+ constructor(host, { accessToken } = {}) {
9803
+ this.api = new HttpClient2(`${host}/api`);
9804
+ this.#accessToken = accessToken ?? null;
9805
+ }
9806
+ async uploadEnv(devProjectId, file) {
9807
+ const formData = new FormData;
9808
+ formData.append("devProjectId", devProjectId);
9809
+ formData.append("file", file);
9810
+ const response = await this.api.post(`/uploadEnv/${devProjectId}`, formData);
9811
+ return response.success;
9812
+ }
9813
+ async downloadEnv(devProjectId) {
9814
+ const response = await this.api.get(`/downloadEnv/${devProjectId}`);
9815
+ return response.success;
9816
+ }
9817
+ async getRemoteAuthToken(remoteId) {
9818
+ if (this.#needRefreshToken())
9819
+ return await this.refreshAuthToken();
9820
+ else if (this.#accessToken)
9821
+ return this.#accessToken;
9822
+ const accessToken = await this.api.get(`/getRemoteAuthToken/${remoteId}`);
9823
+ this.#accessToken = {
9824
+ jwt: accessToken.jwt,
9825
+ refreshToken: accessToken.refreshToken,
9826
+ expiresAt: accessToken.expiresAt ? import_dayjs.default(accessToken.expiresAt) : null
9827
+ };
9828
+ return this.#accessToken;
9829
+ }
9830
+ async refreshAuthToken() {
9831
+ const response = await this.api.post(`/refreshRemoteAuthToken`, {
9832
+ refreshToken: this.#accessToken?.refreshToken
9833
+ });
9834
+ this.#accessToken = {
9835
+ jwt: response.jwt,
9836
+ refreshToken: response.refreshToken,
9837
+ expiresAt: response.expiresAt ? import_dayjs.default(response.expiresAt) : null
9838
+ };
9839
+ return this.#accessToken;
9840
+ }
9841
+ #needRefreshToken() {
9842
+ return !!this.#accessToken?.expiresAt?.isBefore(import_dayjs.default().add(1, "hour"));
9843
+ }
9844
+ }
9408
9845
  // pkgs/@akanjs/cli/application/application.command.ts
9409
9846
  import { select as select6 } from "@inquirer/prompts";
9410
9847
 
@@ -10238,6 +10675,10 @@ class PackageRunner extends runner("package") {
10238
10675
  pkg.generateTsconfigJson()
10239
10676
  ]);
10240
10677
  }
10678
+ await this.#copyPackageReadmes(pkg);
10679
+ }
10680
+ async#copyPackageReadmes(pkg) {
10681
+ await Promise.all(["README.md", "README.ko.md"].map((fileName) => pkg.cp(fileName, `${pkg.dist.cwdPath}/${fileName}`)));
10241
10682
  }
10242
10683
  async updateWorskpaceRootPackageJson(workspace, rootPackageJson) {
10243
10684
  const templatePath = "pkgs/@akanjs/cli/templates/workspaceRoot/package.json.template";
@@ -10310,7 +10751,12 @@ async function getLatestPackageVersion(packageName, tag = "latest", registryUrl)
10310
10751
 
10311
10752
  // pkgs/@akanjs/cli/cloud/cloud.runner.ts
10312
10753
  class CloudRunner extends runner("cloud") {
10313
- #akanFrameworkPackages = new Set(["akanjs", "@akanjs/devkit", "@akanjs/cli", "create-akan-workspace"]);
10754
+ #akanFrameworkPackages = new Set([
10755
+ "akanjs",
10756
+ "@akanjs/devkit",
10757
+ "@akanjs/cli",
10758
+ "create-akan-workspace"
10759
+ ]);
10314
10760
  #getRegistryArgs(registryUrl) {
10315
10761
  return registryUrl ? ["--registry", getNpmRegistryUrl(registryUrl)] : [];
10316
10762
  }
@@ -10330,10 +10776,10 @@ class CloudRunner extends runner("cloud") {
10330
10776
  }
10331
10777
  async login() {
10332
10778
  const config = await getHostConfig();
10333
- const self = config.auth ? await getSelf(config.auth.token) : null;
10334
- if (self) {
10779
+ const self2 = config.auth ? await getSelf(config.auth.token) : null;
10780
+ if (self2) {
10335
10781
  Logger15.rawLog(chalk7.green(`
10336
- \u2713 Already logged in akan cloud as ${self.nickname}
10782
+ \u2713 Already logged in akan cloud as ${self2.nickname}
10337
10783
  `));
10338
10784
  return true;
10339
10785
  }
@@ -10363,12 +10809,12 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10363
10809
  for (let i = 0;i < MAX_RETRY; i++) {
10364
10810
  const res = await fetch(`${akanCloudUrl}/user/getRemoteAuthToken/${remoteId}`);
10365
10811
  const { jwt } = await res.json();
10366
- const self2 = jwt ? await getSelf(jwt) : null;
10367
- if (jwt && self2) {
10368
- setHostConfig(akanCloudHost, { auth: { token: jwt, self: self2 } });
10812
+ const self3 = jwt ? await getSelf(jwt) : null;
10813
+ if (jwt && self3) {
10814
+ setHostConfig(akanCloudHost, { auth: { token: jwt, self: self3 } });
10369
10815
  Logger15.rawLog(chalk7.green(`\r\u2713 Authentication successful!`));
10370
10816
  Logger15.rawLog(chalk7.green.bold(`
10371
- \u2728 Welcome aboard, ${self2.nickname}!`));
10817
+ \u2728 Welcome aboard, ${self3.nickname}!`));
10372
10818
  Logger15.rawLog(chalk7.dim(`You're now ready to use Akan CLI!
10373
10819
  `));
10374
10820
  return true;
@@ -10445,7 +10891,13 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10445
10891
  }
10446
10892
  await Promise.all(akanPkgs.map(async (library) => {
10447
10893
  Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
10448
- await workspace.spawn("npm", ["publish", "--tag", tag, ...this.#getRegistryArgs(registry), ...this.#getLocalRegistryAuthArgs(registry)], {
10894
+ await workspace.spawn("npm", [
10895
+ "publish",
10896
+ "--tag",
10897
+ tag,
10898
+ ...this.#getRegistryArgs(registry),
10899
+ ...this.#getLocalRegistryAuthArgs(registry)
10900
+ ], {
10449
10901
  cwd: path38.join(workspace.workspaceRoot, "dist/pkgs", library),
10450
10902
  env: this.#getRegistryEnv(registry),
10451
10903
  stdio: "inherit"
@@ -10462,7 +10914,14 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10462
10914
  await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env });
10463
10915
  else
10464
10916
  await Promise.all([
10465
- workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env }),
10917
+ workspace.spawn("bun", [
10918
+ "update",
10919
+ "-g",
10920
+ "akanjs",
10921
+ "--latest",
10922
+ `--tag=${tag}`,
10923
+ ...registryArgs
10924
+ ], { env }),
10466
10925
  this.#updateAkanPkgs(workspace, tag, registry)
10467
10926
  ]);
10468
10927
  }
@@ -10486,7 +10945,12 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10486
10945
  }
10487
10946
  #normalizeAkanPackageJson(packageJson, packageName, version) {
10488
10947
  const normalized = { ...packageJson, version };
10489
- for (const field of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
10948
+ for (const field of [
10949
+ "dependencies",
10950
+ "devDependencies",
10951
+ "peerDependencies",
10952
+ "optionalDependencies"
10953
+ ]) {
10490
10954
  const dependencies = normalized[field];
10491
10955
  if (!dependencies)
10492
10956
  continue;
@@ -10497,10 +10961,28 @@ ${chalk7.green("\u27A4")} Authentication Required`));
10497
10961
  }
10498
10962
  return normalized;
10499
10963
  }
10964
+ async downloadEnv(workspace) {
10965
+ const repoName = workspace.repoName;
10966
+ const config = await getHostConfig();
10967
+ const self2 = config.auth ? await getSelf(config.auth.token) : null;
10968
+ if (!self2)
10969
+ throw new Error("Not logged in");
10970
+ const res = await fetch(`${akanCloudUrl}/api/akasys/akasys/${repoName}`, {
10971
+ headers: { Authorization: `Bearer ${config.auth?.token}` }
10972
+ });
10973
+ const env = await res.json();
10974
+ Logger15.info(`Downloading environment variables from cloud...`);
10975
+ Logger15.info(`Environment variables: ${JSON.stringify(env.env, null, 2)}`);
10976
+ }
10977
+ async uploadEnv(workspace) {}
10500
10978
  }
10501
10979
 
10502
10980
  // pkgs/@akanjs/cli/cloud/cloud.script.ts
10503
- class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, PackageScript]) {
10981
+ class CloudScript extends script("cloud", [
10982
+ CloudRunner,
10983
+ ApplicationScript,
10984
+ PackageScript
10985
+ ]) {
10504
10986
  async login(workspace) {
10505
10987
  await this.cloudRunner.login();
10506
10988
  }
@@ -10517,6 +10999,12 @@ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, Packa
10517
10999
  const session = new AiSession("general", { workspace, isContinued: true });
10518
11000
  await session.ask(question);
10519
11001
  }
11002
+ async downloadEnv(workspace) {
11003
+ await this.cloudRunner.downloadEnv(workspace);
11004
+ }
11005
+ async uploadEnv(workspace) {
11006
+ await this.cloudRunner.uploadEnv(workspace);
11007
+ }
10520
11008
  async deployAkan(workspace, { test = true, registryUrl } = {}) {
10521
11009
  const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
10522
11010
  await this.packageScript.updateWorskpaceRootPackageJson(workspace);
@@ -10557,7 +11045,10 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
10557
11045
  ask: target({ desc: "Ask AI assistant a question about your project" }).option("question", String, { ask: "question to ask" }).with(Workspace).exec(async function(question, workspace) {
10558
11046
  await this.cloudScript.ask(question, workspace);
10559
11047
  }),
10560
- deployAkan: target({ devOnly: true, desc: "Deploy Akan.js framework to cloud (internal use)" }).option("test", Boolean, { desc: "test the deployment", default: true }).option("registry", String, {
11048
+ deployAkan: target({
11049
+ devOnly: true,
11050
+ desc: "Deploy Akan.js framework to cloud (internal use)"
11051
+ }).option("test", Boolean, { desc: "test the deployment", default: true }).option("registry", String, {
10561
11052
  desc: "registry target for publishing Akan packages",
10562
11053
  ask: "Select a registry target",
10563
11054
  enum: [
@@ -10582,7 +11073,15 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
10582
11073
  { label: "local", value: "local" }
10583
11074
  ]
10584
11075
  }).exec(async function(workspace, tag, registry) {
10585
- await this.cloudScript.update(workspace, tag, { registryUrl: resolveRegistryUrl(registry) });
11076
+ await this.cloudScript.update(workspace, tag, {
11077
+ registryUrl: resolveRegistryUrl(registry)
11078
+ });
11079
+ }),
11080
+ downloadEnv: target({ desc: "Download environment variables from cloud" }).with(Workspace).exec(async function(workspace) {
11081
+ await this.cloudScript.downloadEnv(workspace);
11082
+ }),
11083
+ uploadEnv: target({ desc: "Upload environment variables to cloud" }).with(Workspace).exec(async function(workspace) {
11084
+ await this.cloudScript.uploadEnv(workspace);
10586
11085
  })
10587
11086
  })) {
10588
11087
  }
@@ -10603,7 +11102,7 @@ class GuidelinePrompt extends Prompter {
10603
11102
  return page;
10604
11103
  if (page.endsWith(".tsx"))
10605
11104
  return page;
10606
- return `apps/angelo/page${page}`;
11105
+ return `apps/akan/page${page}`;
10607
11106
  }
10608
11107
  async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
10609
11108
  const glob = new Bun.Glob(matchPattern);