@akanjs/cli 2.1.1-rc.1 → 2.1.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.
@@ -1,328 +1,6 @@
1
1
  // @bun
2
- var __create = Object.create;
3
- var __getProtoOf = Object.getPrototypeOf;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- function __accessProp(key) {
8
- return this[key];
9
- }
10
- var __toESMCache_node;
11
- var __toESMCache_esm;
12
- var __toESM = (mod, isNodeMode, target) => {
13
- var canCache = mod != null && typeof mod === "object";
14
- if (canCache) {
15
- var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
- var cached = cache.get(mod);
17
- if (cached)
18
- return cached;
19
- }
20
- target = mod != null ? __create(__getProtoOf(mod)) : {};
21
- const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
28
- if (canCache)
29
- cache.set(mod, to);
30
- return to;
31
- };
32
- var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
2
  var __require = import.meta.require;
34
3
 
35
- // node_modules/dayjs/dayjs.min.js
36
- var require_dayjs_min = __commonJS((exports, module) => {
37
- (function(t, e) {
38
- 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();
39
- })(exports, function() {
40
- 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) {
41
- var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
42
- return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
43
- } }, m = function(t2, e2, n2) {
44
- var r2 = String(t2);
45
- return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
46
- }, v = { s: m, z: function(t2) {
47
- var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
48
- return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
49
- }, m: function t2(e2, n2) {
50
- if (e2.date() < n2.date())
51
- return -t2(n2, e2);
52
- 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);
53
- return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
54
- }, a: function(t2) {
55
- return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
56
- }, p: function(t2) {
57
- 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$/, "");
58
- }, u: function(t2) {
59
- return t2 === undefined;
60
- } }, g = "en", D = {};
61
- D[g] = M;
62
- var p = "$isDayjsObject", S = function(t2) {
63
- return t2 instanceof _ || !(!t2 || !t2[p]);
64
- }, w = function t2(e2, n2, r2) {
65
- var i2;
66
- if (!e2)
67
- return g;
68
- if (typeof e2 == "string") {
69
- var s2 = e2.toLowerCase();
70
- D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
71
- var u2 = e2.split("-");
72
- if (!i2 && u2.length > 1)
73
- return t2(u2[0]);
74
- } else {
75
- var a2 = e2.name;
76
- D[a2] = e2, i2 = a2;
77
- }
78
- return !r2 && i2 && (g = i2), i2 || !r2 && g;
79
- }, O = function(t2, e2) {
80
- if (S(t2))
81
- return t2.clone();
82
- var n2 = typeof e2 == "object" ? e2 : {};
83
- return n2.date = t2, n2.args = arguments, new _(n2);
84
- }, b = v;
85
- b.l = w, b.i = S, b.w = function(t2, e2) {
86
- return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
87
- };
88
- var _ = function() {
89
- function M2(t2) {
90
- this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
91
- }
92
- var m2 = M2.prototype;
93
- return m2.parse = function(t2) {
94
- this.$d = function(t3) {
95
- var { date: e2, utc: n2 } = t3;
96
- if (e2 === null)
97
- return new Date(NaN);
98
- if (b.u(e2))
99
- return new Date;
100
- if (e2 instanceof Date)
101
- return new Date(e2);
102
- if (typeof e2 == "string" && !/Z$/i.test(e2)) {
103
- var r2 = e2.match($2);
104
- if (r2) {
105
- var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
106
- 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);
107
- }
108
- }
109
- return new Date(e2);
110
- }(t2), this.init();
111
- }, m2.init = function() {
112
- var t2 = this.$d;
113
- 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();
114
- }, m2.$utils = function() {
115
- return b;
116
- }, m2.isValid = function() {
117
- return !(this.$d.toString() === l);
118
- }, m2.isSame = function(t2, e2) {
119
- var n2 = O(t2);
120
- return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
121
- }, m2.isAfter = function(t2, e2) {
122
- return O(t2) < this.startOf(e2);
123
- }, m2.isBefore = function(t2, e2) {
124
- return this.endOf(e2) < O(t2);
125
- }, m2.$g = function(t2, e2, n2) {
126
- return b.u(t2) ? this[e2] : this.set(n2, t2);
127
- }, m2.unix = function() {
128
- return Math.floor(this.valueOf() / 1000);
129
- }, m2.valueOf = function() {
130
- return this.$d.getTime();
131
- }, m2.startOf = function(t2, e2) {
132
- var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = function(t3, e3) {
133
- var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
134
- return r2 ? i2 : i2.endOf(a);
135
- }, $3 = function(t3, e3) {
136
- return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
137
- }, y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
138
- switch (f2) {
139
- case h:
140
- return r2 ? l2(1, 0) : l2(31, 11);
141
- case c:
142
- return r2 ? l2(1, M3) : l2(0, M3 + 1);
143
- case o:
144
- var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
145
- return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
146
- case a:
147
- case d:
148
- return $3(v2 + "Hours", 0);
149
- case u:
150
- return $3(v2 + "Minutes", 1);
151
- case s:
152
- return $3(v2 + "Seconds", 2);
153
- case i:
154
- return $3(v2 + "Milliseconds", 3);
155
- default:
156
- return this.clone();
157
- }
158
- }, m2.endOf = function(t2) {
159
- return this.startOf(t2, false);
160
- }, m2.$set = function(t2, e2) {
161
- 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;
162
- if (o2 === c || o2 === h) {
163
- var y2 = this.clone().set(d, 1);
164
- y2.$d[l2]($3), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
165
- } else
166
- l2 && this.$d[l2]($3);
167
- return this.init(), this;
168
- }, m2.set = function(t2, e2) {
169
- return this.clone().$set(t2, e2);
170
- }, m2.get = function(t2) {
171
- return this[b.p(t2)]();
172
- }, m2.add = function(r2, f2) {
173
- var d2, l2 = this;
174
- r2 = Number(r2);
175
- var $3 = b.p(f2), y2 = function(t2) {
176
- var e2 = O(l2);
177
- return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
178
- };
179
- if ($3 === c)
180
- return this.set(c, this.$M + r2);
181
- if ($3 === h)
182
- return this.set(h, this.$y + r2);
183
- if ($3 === a)
184
- return y2(1);
185
- if ($3 === o)
186
- return y2(7);
187
- var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$3] || 1, m3 = this.$d.getTime() + r2 * M3;
188
- return b.w(m3, this);
189
- }, m2.subtract = function(t2, e2) {
190
- return this.add(-1 * t2, e2);
191
- }, m2.format = function(t2) {
192
- var e2 = this, n2 = this.$locale();
193
- if (!this.isValid())
194
- return n2.invalidDate || l;
195
- 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) {
196
- return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
197
- }, d2 = function(t3) {
198
- return b.s(s2 % 12 || 12, t3, "0");
199
- }, $3 = f2 || function(t3, e3, n3) {
200
- var r3 = t3 < 12 ? "AM" : "PM";
201
- return n3 ? r3.toLowerCase() : r3;
202
- };
203
- return r2.replace(y, function(t3, r3) {
204
- return r3 || function(t4) {
205
- switch (t4) {
206
- case "YY":
207
- return String(e2.$y).slice(-2);
208
- case "YYYY":
209
- return b.s(e2.$y, 4, "0");
210
- case "M":
211
- return a2 + 1;
212
- case "MM":
213
- return b.s(a2 + 1, 2, "0");
214
- case "MMM":
215
- return h2(n2.monthsShort, a2, c2, 3);
216
- case "MMMM":
217
- return h2(c2, a2);
218
- case "D":
219
- return e2.$D;
220
- case "DD":
221
- return b.s(e2.$D, 2, "0");
222
- case "d":
223
- return String(e2.$W);
224
- case "dd":
225
- return h2(n2.weekdaysMin, e2.$W, o2, 2);
226
- case "ddd":
227
- return h2(n2.weekdaysShort, e2.$W, o2, 3);
228
- case "dddd":
229
- return o2[e2.$W];
230
- case "H":
231
- return String(s2);
232
- case "HH":
233
- return b.s(s2, 2, "0");
234
- case "h":
235
- return d2(1);
236
- case "hh":
237
- return d2(2);
238
- case "a":
239
- return $3(s2, u2, true);
240
- case "A":
241
- return $3(s2, u2, false);
242
- case "m":
243
- return String(u2);
244
- case "mm":
245
- return b.s(u2, 2, "0");
246
- case "s":
247
- return String(e2.$s);
248
- case "ss":
249
- return b.s(e2.$s, 2, "0");
250
- case "SSS":
251
- return b.s(e2.$ms, 3, "0");
252
- case "Z":
253
- return i2;
254
- }
255
- return null;
256
- }(t3) || i2.replace(":", "");
257
- });
258
- }, m2.utcOffset = function() {
259
- return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
260
- }, m2.diff = function(r2, d2, l2) {
261
- var $3, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = function() {
262
- return b.m(y2, m3);
263
- };
264
- switch (M3) {
265
- case h:
266
- $3 = D2() / 12;
267
- break;
268
- case c:
269
- $3 = D2();
270
- break;
271
- case f:
272
- $3 = D2() / 3;
273
- break;
274
- case o:
275
- $3 = (g2 - v2) / 604800000;
276
- break;
277
- case a:
278
- $3 = (g2 - v2) / 86400000;
279
- break;
280
- case u:
281
- $3 = g2 / n;
282
- break;
283
- case s:
284
- $3 = g2 / e;
285
- break;
286
- case i:
287
- $3 = g2 / t;
288
- break;
289
- default:
290
- $3 = g2;
291
- }
292
- return l2 ? $3 : b.a($3);
293
- }, m2.daysInMonth = function() {
294
- return this.endOf(c).$D;
295
- }, m2.$locale = function() {
296
- return D[this.$L];
297
- }, m2.locale = function(t2, e2) {
298
- if (!t2)
299
- return this.$L;
300
- var n2 = this.clone(), r2 = w(t2, e2, true);
301
- return r2 && (n2.$L = r2), n2;
302
- }, m2.clone = function() {
303
- return b.w(this.$d, this);
304
- }, m2.toDate = function() {
305
- return new Date(this.valueOf());
306
- }, m2.toJSON = function() {
307
- return this.isValid() ? this.toISOString() : null;
308
- }, m2.toISOString = function() {
309
- return this.$d.toISOString();
310
- }, m2.toString = function() {
311
- return this.$d.toUTCString();
312
- }, M2;
313
- }(), Y = _.prototype;
314
- return O.prototype = Y, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
315
- Y[t2[1]] = function(e2) {
316
- return this.$g(e2, t2[0], t2[1]);
317
- };
318
- }), O.extend = function(t2, e2) {
319
- return t2.$i || (t2(e2, _, O), t2.$i = true), O;
320
- }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
321
- return O(1000 * t2);
322
- }, O.en = D[g], O.Ls = D, O.p = {}, O;
323
- });
324
- });
325
-
326
4
  // pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
327
5
  import path37 from "path";
328
6
 
@@ -339,10 +17,7 @@ import { ChatOpenAI } from "@langchain/openai";
339
17
  import { Logger as Logger2 } from "akanjs/common";
340
18
  import chalk from "chalk";
341
19
 
342
- // pkgs/@akanjs/devkit/auth.ts
343
- import { mkdir } from "fs/promises";
344
-
345
- // pkgs/@akanjs/devkit/constants.ts
20
+ // pkgs/@akanjs/devkit/cloud/constants.ts
346
21
  var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
347
22
  var configPath = `${basePath}/config.json`;
348
23
  var akanCloudHost = process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
@@ -350,9 +25,14 @@ var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE ===
350
25
  var defaultHostConfig = {};
351
26
  var defaultAkanGlobalConfig = {
352
27
  cloudHost: {},
28
+ remoteEnvServers: {},
353
29
  llm: null
354
30
  };
355
31
 
32
+ // pkgs/@akanjs/devkit/cloud/globalConfig.ts
33
+ import { mkdir } from "fs/promises";
34
+ import dayjs from "dayjs";
35
+
356
36
  // pkgs/@akanjs/devkit/fileSys.ts
357
37
  import { stat } from "fs/promises";
358
38
  import { Logger } from "akanjs/common";
@@ -391,35 +71,198 @@ class FileSys {
391
71
  }
392
72
  }
393
73
 
394
- // pkgs/@akanjs/devkit/auth.ts
395
- var getAkanGlobalConfig = async () => {
396
- const exists = await FileSys.fileExists(configPath);
397
- const akanConfig = exists ? await FileSys.readJson(configPath) : defaultAkanGlobalConfig;
398
- return akanConfig;
399
- };
400
- var setAkanGlobalConfig = async (akanConfig) => {
401
- await mkdir(basePath, { recursive: true });
402
- await Bun.write(configPath, JSON.stringify(akanConfig, null, 2));
403
- };
404
- var getHostConfig = async (host = akanCloudHost) => {
405
- const akanConfig = await getAkanGlobalConfig();
406
- return akanConfig.cloudHost[host] ?? defaultHostConfig;
407
- };
408
- var setHostConfig = async (host = akanCloudHost, config = {}) => {
409
- const akanConfig = await getAkanGlobalConfig();
410
- akanConfig.cloudHost[host] = config;
411
- await setAkanGlobalConfig(akanConfig);
412
- };
413
- var getSelf = async (token) => {
414
- try {
415
- const res = await fetch(`${akanCloudUrl}/user/getSelf`, { headers: { Authorization: `Bearer ${token}` } });
416
- const user = await res.json();
417
- return user;
418
- } catch (e) {
419
- return null;
74
+ // pkgs/@akanjs/devkit/cloud/globalConfig.ts
75
+ class GlobalConfig {
76
+ static async#getAkanGlobalConfig() {
77
+ const exists = await FileSys.fileExists(configPath);
78
+ const akanConfig = exists ? await FileSys.readJson(configPath) : {};
79
+ return {
80
+ ...defaultAkanGlobalConfig,
81
+ ...akanConfig,
82
+ cloudHost: akanConfig.cloudHost ?? defaultAkanGlobalConfig.cloudHost,
83
+ remoteEnvServers: akanConfig.remoteEnvServers ?? defaultAkanGlobalConfig.remoteEnvServers
84
+ };
420
85
  }
421
- };
86
+ static async#setAkanGlobalConfig(akanConfig) {
87
+ await mkdir(basePath, { recursive: true });
88
+ await Bun.write(configPath, JSON.stringify(akanConfig, null, 2));
89
+ }
90
+ static async getHostConfig(host = akanCloudHost) {
91
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
92
+ return GlobalConfig.toHostConfig(akanConfig.cloudHost[host] ?? defaultHostConfig);
93
+ }
94
+ static async setHostConfig(host = akanCloudHost, config = {}) {
95
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
96
+ akanConfig.cloudHost[host] = GlobalConfig.toHostConfigDto(config);
97
+ await GlobalConfig.#setAkanGlobalConfig(akanConfig);
98
+ }
99
+ static async getLlmConfig() {
100
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
101
+ return akanConfig.llm ?? null;
102
+ }
103
+ static async setLlmConfig(llmConfig) {
104
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
105
+ await GlobalConfig.#setAkanGlobalConfig({ ...akanConfig, llm: llmConfig });
106
+ }
107
+ static async getRemoteEnvServers() {
108
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
109
+ return akanConfig.remoteEnvServers;
110
+ }
111
+ static async setRemoteEnvServer(name, config) {
112
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
113
+ await GlobalConfig.#setAkanGlobalConfig({
114
+ ...akanConfig,
115
+ remoteEnvServers: {
116
+ ...akanConfig.remoteEnvServers,
117
+ [name]: config
118
+ }
119
+ });
120
+ }
121
+ static async removeRemoteEnvServer(name) {
122
+ const akanConfig = await GlobalConfig.#getAkanGlobalConfig();
123
+ const { [name]: _, ...remoteEnvServers } = akanConfig.remoteEnvServers;
124
+ await GlobalConfig.#setAkanGlobalConfig({
125
+ ...akanConfig,
126
+ remoteEnvServers
127
+ });
128
+ }
129
+ static needRefreshToken(accessToken) {
130
+ return !!accessToken?.expiresAt?.isBefore(dayjs().add(1, "hour"));
131
+ }
132
+ static toAccessToken(accessToken) {
133
+ return {
134
+ jwt: accessToken.jwt,
135
+ refreshToken: accessToken.refreshToken ?? null,
136
+ expiresAt: accessToken.expiresAt ? dayjs(accessToken.expiresAt) : null
137
+ };
138
+ }
139
+ static toAccessTokenDto(accessToken) {
140
+ return {
141
+ jwt: accessToken.jwt,
142
+ refreshToken: accessToken.refreshToken ?? null,
143
+ expiresAt: accessToken.expiresAt?.toString() ?? null
144
+ };
145
+ }
146
+ static toHostConfigDto(hostConfig) {
147
+ return {
148
+ auth: {
149
+ accessToken: hostConfig.auth?.accessToken ? GlobalConfig.toAccessTokenDto(hostConfig.auth.accessToken) : undefined,
150
+ self: hostConfig.auth?.self
151
+ }
152
+ };
153
+ }
154
+ static toHostConfig(hostConfigDto) {
155
+ return {
156
+ auth: {
157
+ accessToken: hostConfigDto.auth?.accessToken ? GlobalConfig.toAccessToken(hostConfigDto.auth.accessToken) : undefined,
158
+ self: hostConfigDto.auth?.self
159
+ }
160
+ };
161
+ }
162
+ }
422
163
 
164
+ // pkgs/@akanjs/devkit/cloud/cloudApi.ts
165
+ class HttpClient {
166
+ baseUrl;
167
+ headers = {};
168
+ constructor(baseUrl, headers = {}) {
169
+ this.baseUrl = baseUrl;
170
+ this.headers = headers;
171
+ }
172
+ async get(url, { headers } = {}) {
173
+ const response = await fetch(`${this.baseUrl}${url}`, {
174
+ headers: {
175
+ "Content-Type": "application/json",
176
+ ...this.headers,
177
+ ...headers
178
+ }
179
+ });
180
+ return response.json();
181
+ }
182
+ async getFile(url, localPath, headers) {
183
+ const response = await fetch(`${this.baseUrl}${url}`, {
184
+ headers: { ...this.headers, ...headers }
185
+ });
186
+ if (!response.ok)
187
+ throw new Error(`Failed to download file: ${response.status} ${response.statusText}`);
188
+ await Bun.write(localPath, response);
189
+ }
190
+ async post(url, data, { headers } = {}) {
191
+ const isFormData = data instanceof FormData;
192
+ const response = await fetch(`${this.baseUrl}${url}`, {
193
+ method: "POST",
194
+ body: isFormData ? data : JSON.stringify(data),
195
+ headers: isFormData ? { ...this.headers, ...headers } : { "Content-Type": "application/json", ...this.headers, ...headers }
196
+ });
197
+ return response.json();
198
+ }
199
+ setHeaders(headers) {
200
+ Object.assign(this.headers, headers);
201
+ return this;
202
+ }
203
+ }
204
+
205
+ class CloudApi {
206
+ #api;
207
+ #accessToken = null;
208
+ static async fromHost(host) {
209
+ const hostConfig = await GlobalConfig.getHostConfig(host);
210
+ return new CloudApi(hostConfig);
211
+ }
212
+ constructor(hostConfig) {
213
+ const host = akanCloudHost;
214
+ this.#api = new HttpClient(`${host}/api`);
215
+ this.#accessToken = hostConfig.auth?.accessToken ?? null;
216
+ if (this.#accessToken && !GlobalConfig.needRefreshToken(this.#accessToken))
217
+ this.#api.setHeaders({
218
+ Authorization: `Bearer ${this.#accessToken.jwt}`
219
+ });
220
+ }
221
+ async uploadEnv(devProjectId, file) {
222
+ const formData = new FormData;
223
+ formData.append("devProjectId", devProjectId);
224
+ formData.append("file", file);
225
+ const data = await this.#api.post(`/uploadEnv/${devProjectId}`, formData);
226
+ return data;
227
+ }
228
+ async downloadEnv(devProjectId, localPath) {
229
+ await this.#api.getFile(`/downloadEnv/${devProjectId}`, localPath);
230
+ }
231
+ async getRemoteAuthToken(remoteId) {
232
+ try {
233
+ if (this.#accessToken) {
234
+ if (GlobalConfig.needRefreshToken(this.#accessToken))
235
+ return await this.refreshAuthToken();
236
+ else
237
+ return await this.refreshAuthToken();
238
+ }
239
+ const accessToken = await this.#api.get(`/getRemoteAuthToken/${remoteId}`);
240
+ this.#accessToken = GlobalConfig.toAccessToken(accessToken);
241
+ this.#api.setHeaders({
242
+ Authorization: `Bearer ${this.#accessToken.jwt}`
243
+ });
244
+ return this.#accessToken;
245
+ } catch (_) {
246
+ return null;
247
+ }
248
+ }
249
+ async refreshAuthToken() {
250
+ const response = await this.#api.post(`/refreshRemoteAuthToken`, {
251
+ refreshToken: this.#accessToken?.refreshToken
252
+ });
253
+ this.#accessToken = GlobalConfig.toAccessToken(response);
254
+ this.#api.setHeaders({ Authorization: `Bearer ${this.#accessToken.jwt}` });
255
+ return this.#accessToken;
256
+ }
257
+ async getRemoteSelf() {
258
+ try {
259
+ const data = await this.#api.get(`/getRemoteSelf`);
260
+ return data;
261
+ } catch {
262
+ return null;
263
+ }
264
+ }
265
+ }
423
266
  // pkgs/@akanjs/devkit/spinner.ts
424
267
  import ora from "ora";
425
268
 
@@ -482,12 +325,43 @@ class Spinner {
482
325
 
483
326
  // pkgs/@akanjs/devkit/aiEditor.ts
484
327
  var MAX_ASK_TRY = 300;
485
- var supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
328
+ var supportedLlmModels = [
329
+ "deepseek-chat",
330
+ "deepseek-reasoner"
331
+ ];
332
+ var parseTypescriptFileBlocks = (text) => {
333
+ const fileBlocks = [];
334
+ const codeBlockRegex = /```(?:typescript|ts|tsx)\s*\n([\s\S]*?)```/gi;
335
+ const filePathRegex = /^\s*\/\/\s*File:\s*(.+?)\s*$/im;
336
+ for (const codeBlock of text.matchAll(codeBlockRegex)) {
337
+ const content = codeBlock[1]?.trim();
338
+ if (!content)
339
+ continue;
340
+ const filePath = filePathRegex.exec(content)?.[1]?.trim();
341
+ if (!filePath)
342
+ continue;
343
+ fileBlocks.push({
344
+ filePath,
345
+ content: content.replace(filePathRegex, "").trim()
346
+ });
347
+ }
348
+ return fileBlocks;
349
+ };
350
+ var preserveTypescriptResponseContent = (previousContent, nextContent) => {
351
+ const previousWrites = parseTypescriptFileBlocks(previousContent);
352
+ const nextWrites = parseTypescriptFileBlocks(nextContent);
353
+ if (previousWrites.length > 0 && nextWrites.length === 0)
354
+ return previousContent;
355
+ return nextContent;
356
+ };
486
357
 
487
358
  class AiSession {
488
359
  static #cacheDir = "node_modules/.cache/akan/aiSession";
489
360
  static #chat = null;
490
- static async init({ temperature = 0, useExisting = true } = {}) {
361
+ static async init({
362
+ temperature = 0,
363
+ useExisting = true
364
+ } = {}) {
491
365
  if (useExisting) {
492
366
  const llmConfig2 = await AiSession.getLlmConfig();
493
367
  if (llmConfig2) {
@@ -514,22 +388,24 @@ class AiSession {
514
388
  return AiSession;
515
389
  }
516
390
  static async getLlmConfig() {
517
- const akanConfig = await getAkanGlobalConfig();
518
- return akanConfig.llm ?? null;
391
+ return await GlobalConfig.getLlmConfig();
519
392
  }
520
393
  static async setLlmConfig(llmConfig) {
521
- const akanConfig = await getAkanGlobalConfig();
522
- akanConfig.llm = llmConfig;
523
- await setAkanGlobalConfig(akanConfig);
394
+ await GlobalConfig.setLlmConfig(llmConfig);
524
395
  return AiSession;
525
396
  }
526
397
  static async#requestLlmConfig() {
527
- const model = await select({ message: "Select a LLM model", choices: supportedLlmModels });
398
+ const model = await select({
399
+ message: "Select a LLM model",
400
+ choices: supportedLlmModels
401
+ });
528
402
  const apiKey = await input({ message: "Enter your API key" });
529
403
  return { model, apiKey };
530
404
  }
531
405
  static async#validateApiKey(modelName, apiKey) {
532
- const spinner = new Spinner("Validating LLM API key...", { prefix: `\uD83E\uDD16akan-editor` }).start();
406
+ const spinner = new Spinner("Validating LLM API key...", {
407
+ prefix: `\uD83E\uDD16akan-editor`
408
+ }).start();
533
409
  const chat = new ChatOpenAI({
534
410
  modelName,
535
411
  temperature: 0,
@@ -552,7 +428,11 @@ class AiSession {
552
428
  sessionKey;
553
429
  isCacheLoaded = false;
554
430
  workspace;
555
- constructor(type, { workspace, cacheKey, isContinued }) {
431
+ constructor(type, {
432
+ workspace,
433
+ cacheKey,
434
+ isContinued
435
+ }) {
556
436
  this.workspace = workspace;
557
437
  this.sessionKey = `${type}${cacheKey ? `-${cacheKey}` : ""}`;
558
438
  if (isContinued)
@@ -593,7 +473,7 @@ class AiSession {
593
473
  const humanMessage = new HumanMessage(question);
594
474
  this.messageHistory.push(humanMessage);
595
475
  const stream = await AiSession.#chat.stream(this.messageHistory);
596
- let reasoningResponse = "", fullResponse = "", tokenIdx = 0;
476
+ let reasoningResponse = "", fullResponse = "";
597
477
  for await (const chunk of stream) {
598
478
  if (loader.isSpinning())
599
479
  loader.succeed(`${AiSession.#chat.model} responded`);
@@ -614,7 +494,6 @@ class AiSession {
614
494
  fullResponse += content;
615
495
  onChunk(content);
616
496
  }
617
- tokenIdx++;
618
497
  }
619
498
  fullResponse += `
620
499
  `;
@@ -622,19 +501,33 @@ class AiSession {
622
501
  `);
623
502
  this.messageHistory.push(new AIMessage(fullResponse));
624
503
  return { content: fullResponse, messageHistory: this.messageHistory };
625
- } catch (error) {
504
+ } catch {
626
505
  loader.fail(`${AiSession.#chat.model} failed to respond`);
627
506
  throw new Error("Failed to stream response");
628
507
  }
629
508
  }
630
- async edit(question, { onChunk, onReasoning, maxTry = MAX_ASK_TRY, validate, approve } = {}) {
509
+ async edit(question, {
510
+ onChunk,
511
+ onReasoning,
512
+ maxTry = MAX_ASK_TRY,
513
+ validate,
514
+ approve,
515
+ fallbackToPreviousTypescript
516
+ } = {}) {
631
517
  for (let tryCount = 0;tryCount < maxTry; tryCount++) {
632
518
  let response = await this.ask(question, { onChunk, onReasoning });
633
519
  if (validate?.length && tryCount === 0) {
634
520
  const validateQuestion = `Double check if the response meets the requirements and conditions, and follow the instructions. If not, rewrite it.
635
521
  ${validate.map((v) => `- ${v}`).join(`
636
522
  `)}`;
637
- response = await this.ask(validateQuestion, { onChunk, onReasoning });
523
+ const validateResponse = await this.ask(validateQuestion, {
524
+ onChunk,
525
+ onReasoning
526
+ });
527
+ response = {
528
+ ...validateResponse,
529
+ content: fallbackToPreviousTypescript ? preserveTypescriptResponseContent(response.content, validateResponse.content) : validateResponse.content
530
+ };
638
531
  }
639
532
  const isConfirmed = approve ? true : await select({
640
533
  message: "Do you want to edit the response?",
@@ -667,28 +560,45 @@ ${validate.map((v) => `- ${v}`).join(`
667
560
  return this;
668
561
  }
669
562
  async writeTypescripts(question, executor, options = {}) {
670
- const content = await this.edit(question, options);
563
+ const content = await this.edit(question, {
564
+ ...options,
565
+ fallbackToPreviousTypescript: true
566
+ });
671
567
  const writes = this.#getTypescriptCodes(content);
568
+ if (!writes.length)
569
+ throw new Error("No parseable TypeScript file blocks were found in the AI response. Include `// File: <path>` in each code block.");
672
570
  for (const write of writes)
673
571
  await executor.writeFile(write.filePath, write.content);
674
572
  return await this.#tryFixTypescripts(writes, executor, options);
675
573
  }
676
- async#editTypescripts(question, options = {}) {
677
- const content = await this.edit(question, options);
678
- return this.#getTypescriptCodes(content);
574
+ async#editTypescripts(question, options = {}, fallbackWrites) {
575
+ const content = await this.edit(question, {
576
+ ...options,
577
+ fallbackToPreviousTypescript: true
578
+ });
579
+ const writes = this.#getTypescriptCodes(content);
580
+ if (!writes.length && fallbackWrites?.length)
581
+ return fallbackWrites;
582
+ if (!writes.length)
583
+ throw new Error("No parseable TypeScript file blocks were found in the AI response. Include `// File: <path>` in each code block.");
584
+ return writes;
679
585
  }
680
586
  async#tryFixTypescripts(writes, executor, options = {}) {
681
587
  const MAX_EDIT_TRY = 5;
682
588
  for (let tryCount = 0;tryCount < MAX_EDIT_TRY; tryCount++) {
683
- const loader = new Spinner(`Type checking and linting...`, { prefix: `\uD83E\uDD16akan-editor` }).start();
589
+ const loader = new Spinner(`Type checking and linting...`, {
590
+ prefix: `\uD83E\uDD16akan-editor`
591
+ }).start();
684
592
  const fileChecks = await Promise.all(writes.map(async ({ filePath }) => {
685
- const typeCheckResult = executor.typeCheck(filePath);
686
- const lintResult = await executor.lint(filePath);
687
- const needFix2 = !!typeCheckResult.fileErrors.length || !!lintResult.errors.length;
688
- return { filePath, typeCheckResult, lintResult, needFix: needFix2 };
593
+ const lintResult = await executor.lint(filePath, { fix: true });
594
+ const typeCheckResult = await executor.typeCheckAsync(filePath);
595
+ const hasTypeErrors = typeCheckResult.fileErrors.length > 0;
596
+ const hasLintErrors = lintResult.errors.length > 0;
597
+ const needFix = hasTypeErrors || hasLintErrors;
598
+ return { filePath, typeCheckResult, lintResult, needFix };
689
599
  }));
690
- const needFix = fileChecks.some((fileCheck) => fileCheck.needFix);
691
- if (needFix) {
600
+ const hasAnyFix = fileChecks.some((fileCheck) => fileCheck.needFix);
601
+ if (hasAnyFix) {
692
602
  loader.fail("Type checking and linting has some errors, try to fix them");
693
603
  fileChecks.forEach((fileCheck) => {
694
604
  Logger2.rawLog(`TypeCheck Result
@@ -704,7 +614,7 @@ ${fileCheck.lintResult.message}`);
704
614
  ...options,
705
615
  validate: undefined,
706
616
  approve: true
707
- });
617
+ }, writes);
708
618
  for (const write of writes)
709
619
  await executor.writeFile(write.filePath, write.content);
710
620
  } else {
@@ -715,21 +625,7 @@ ${fileCheck.lintResult.message}`);
715
625
  throw new Error("Failed to create scalar");
716
626
  }
717
627
  #getTypescriptCodes(text) {
718
- const codes = text.match(/```(typescript|tsx)([\s\S]*?)```/g);
719
- if (!codes)
720
- return [];
721
- const result = codes.map((code) => {
722
- const content = /```(typescript|tsx)([\s\S]*?)```/.exec(code)?.[2];
723
- if (!content)
724
- return null;
725
- const filePath = /\/\/ File: (.*?)(?:\n|$)/.exec(content)?.[1]?.trim();
726
- if (!filePath)
727
- return null;
728
- const contentWithoutFilepath = content.replace(`// File: ${filePath}
729
- `, "").trim();
730
- return { filePath, content: contentWithoutFilepath };
731
- });
732
- return result.filter((code) => code !== null);
628
+ return parseTypescriptFileBlocks(text);
733
629
  }
734
630
  async editMarkdown(request, options = {}) {
735
631
  const content = await this.edit(request, options);
@@ -747,21 +643,26 @@ ${fileCheck.lintResult.message}`);
747
643
  }
748
644
  // pkgs/@akanjs/devkit/akanApp/akanApp.host.ts
749
645
  import path9 from "path";
750
- import { Logger as Logger6 } from "akanjs/common";
646
+ import { Logger as Logger5 } from "akanjs/common";
751
647
 
752
648
  // pkgs/@akanjs/devkit/executors.ts
753
649
  import {
754
650
  exec,
755
651
  fork,
756
- spawn
652
+ spawn as spawn2
757
653
  } from "child_process";
758
654
  import { readFileSync as readFileSync3 } from "fs";
759
- import { copyFile, mkdir as mkdir2, readdir as readDirEntries, stat as stat2 } from "fs/promises";
655
+ import {
656
+ copyFile,
657
+ mkdir as mkdir2,
658
+ readdir as readDirEntries,
659
+ stat as stat2
660
+ } from "fs/promises";
760
661
  import path7 from "path";
761
662
  import {
762
663
  capitalize,
763
664
  isRouteSourceFile,
764
- Logger as Logger4,
665
+ Logger as Logger3,
765
666
  parseRouteModuleKey,
766
667
  validatePageSourceFile,
767
668
  validateSubRoutePageKey
@@ -1124,23 +1025,146 @@ import path2 from "path";
1124
1025
  var getDirname = (url) => path2.dirname(new URL(url).pathname);
1125
1026
 
1126
1027
  // pkgs/@akanjs/devkit/linter.ts
1028
+ import { spawn } from "child_process";
1127
1029
  import { existsSync, readFileSync } from "fs";
1128
- import * as path3 from "path";
1129
- import { Logger as Logger3 } from "akanjs/common";
1030
+ import path3 from "path";
1130
1031
  import chalk2 from "chalk";
1131
1032
 
1132
1033
  class Linter {
1133
- #logger = new Logger3("Linter");
1134
1034
  lintRoot;
1035
+ #biomeBin;
1135
1036
  constructor(cwdPath) {
1136
- this.lintRoot = this.#findEslintRootPath(cwdPath);
1037
+ this.lintRoot = this.#findBiomeRootPath(cwdPath);
1038
+ const localBiomeBin = path3.join(this.lintRoot, "node_modules/.bin/biome");
1039
+ this.#biomeBin = existsSync(localBiomeBin) ? localBiomeBin : "biome";
1137
1040
  }
1138
- #findEslintRootPath(dir) {
1139
- const configPath2 = path3.join(dir, "eslint.config.ts");
1041
+ #findBiomeRootPath(dir) {
1042
+ const configPath2 = path3.join(dir, "biome.json");
1140
1043
  if (existsSync(configPath2))
1141
1044
  return dir;
1142
1045
  const parentDir = path3.dirname(dir);
1143
- return this.#findEslintRootPath(parentDir);
1046
+ if (parentDir === dir)
1047
+ throw new Error(`biome.json not found from ${dir}`);
1048
+ return this.#findBiomeRootPath(parentDir);
1049
+ }
1050
+ #toBiomePath(filePath) {
1051
+ const relativePath = path3.relative(this.lintRoot, filePath);
1052
+ if (!relativePath.startsWith("..") && !path3.isAbsolute(relativePath))
1053
+ return relativePath;
1054
+ return filePath;
1055
+ }
1056
+ #resolveFilePath(filePath) {
1057
+ return path3.isAbsolute(filePath) ? filePath : path3.join(this.lintRoot, filePath);
1058
+ }
1059
+ async#runBiome(args, input2) {
1060
+ return await new Promise((resolve, reject) => {
1061
+ const proc = spawn(this.#biomeBin, args, {
1062
+ cwd: this.lintRoot,
1063
+ stdio: ["pipe", "pipe", "pipe"]
1064
+ });
1065
+ let stdout = "";
1066
+ let stderr = "";
1067
+ proc.stdout.on("data", (data) => {
1068
+ stdout += data.toString();
1069
+ });
1070
+ proc.stderr.on("data", (data) => {
1071
+ stderr += data.toString();
1072
+ });
1073
+ proc.on("error", reject);
1074
+ proc.on("close", (code) => resolve({ stdout, stderr, code }));
1075
+ proc.stdin.end(input2);
1076
+ });
1077
+ }
1078
+ #parseBiomeReport(output) {
1079
+ const jsonStart = output.indexOf("{");
1080
+ const jsonEnd = output.lastIndexOf("}");
1081
+ if (jsonStart === -1 || jsonEnd === -1 || jsonEnd < jsonStart)
1082
+ throw new Error(output.trim() || "No Biome JSON output");
1083
+ return JSON.parse(output.slice(jsonStart, jsonEnd + 1));
1084
+ }
1085
+ #diagnosticFilePath(diagnostic, fallbackFilePath) {
1086
+ const diagnosticPath = diagnostic.location?.path;
1087
+ if (!diagnosticPath)
1088
+ return fallbackFilePath;
1089
+ return path3.isAbsolute(diagnosticPath) ? diagnosticPath : path3.join(this.lintRoot, diagnosticPath);
1090
+ }
1091
+ #createLintMessage(diagnostic) {
1092
+ const start = diagnostic.location?.start;
1093
+ const end = diagnostic.location?.end;
1094
+ return {
1095
+ line: Math.max(1, start?.line ?? 1),
1096
+ column: Math.max(1, start?.column ?? 1),
1097
+ endLine: end?.line,
1098
+ endColumn: end?.column,
1099
+ message: diagnostic.message,
1100
+ ruleId: diagnostic.category ?? null,
1101
+ severity: diagnostic.severity === "error" ? 2 : 1
1102
+ };
1103
+ }
1104
+ #toLintResults(report, filePath) {
1105
+ const resultsByPath = new Map;
1106
+ for (const diagnostic of report.diagnostics ?? []) {
1107
+ if (diagnostic.severity !== "error" && diagnostic.severity !== "warning")
1108
+ continue;
1109
+ const diagnosticFilePath = this.#diagnosticFilePath(diagnostic, filePath);
1110
+ const result = resultsByPath.get(diagnosticFilePath) ?? {
1111
+ filePath: diagnosticFilePath,
1112
+ messages: [],
1113
+ errorCount: 0,
1114
+ warningCount: 0,
1115
+ fixableErrorCount: 0,
1116
+ fixableWarningCount: 0
1117
+ };
1118
+ const message = this.#createLintMessage(diagnostic);
1119
+ result.messages.push(message);
1120
+ if (message.severity === 2)
1121
+ result.errorCount += 1;
1122
+ else
1123
+ result.warningCount += 1;
1124
+ resultsByPath.set(diagnosticFilePath, result);
1125
+ }
1126
+ return [
1127
+ resultsByPath.get(filePath) ?? {
1128
+ filePath,
1129
+ messages: [],
1130
+ errorCount: 0,
1131
+ warningCount: 0,
1132
+ fixableErrorCount: 0,
1133
+ fixableWarningCount: 0
1134
+ },
1135
+ ...[...resultsByPath.entries()].filter(([resultPath]) => resultPath !== filePath).map(([, result]) => result)
1136
+ ];
1137
+ }
1138
+ #splitMessages(results) {
1139
+ const messages = results.flatMap((result) => result.messages);
1140
+ return {
1141
+ errors: messages.filter((message) => message.severity === 2),
1142
+ warnings: messages.filter((message) => message.severity === 1)
1143
+ };
1144
+ }
1145
+ async#checkFile(filePath, { write = false } = {}) {
1146
+ const originalContent = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
1147
+ const { stdout, stderr } = await this.#runBiome([
1148
+ "check",
1149
+ ...write ? ["--write"] : [],
1150
+ "--reporter=json",
1151
+ "--max-diagnostics=none",
1152
+ "--no-errors-on-unmatched",
1153
+ "--config-path",
1154
+ path3.join(this.lintRoot, "biome.json"),
1155
+ this.#toBiomePath(filePath)
1156
+ ]);
1157
+ const report = this.#parseBiomeReport(stdout || stderr);
1158
+ const results = this.#toLintResults(report, filePath);
1159
+ const { errors, warnings } = this.#splitMessages(results);
1160
+ const output = write && existsSync(filePath) ? readFileSync(filePath, "utf8") : undefined;
1161
+ return {
1162
+ fixed: write && output !== originalContent,
1163
+ output,
1164
+ results,
1165
+ errors,
1166
+ warnings
1167
+ };
1144
1168
  }
1145
1169
  async lint(filePath, { fix = false, dryRun = false } = {}) {
1146
1170
  if (fix)
@@ -1148,9 +1172,10 @@ class Linter {
1148
1172
  return await this.lintFile(filePath);
1149
1173
  }
1150
1174
  async lintFile(filePath) {
1151
- if (!existsSync(filePath))
1175
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1176
+ if (!existsSync(resolvedFilePath))
1152
1177
  throw new Error(`File not found: ${filePath}`);
1153
- return { fixed: false, results: [], errors: [], warnings: [] };
1178
+ return await this.#checkFile(resolvedFilePath);
1154
1179
  }
1155
1180
  formatLintResults(results) {
1156
1181
  if (results.length === 0)
@@ -1170,12 +1195,12 @@ ${chalk2.cyan(result.filePath)}`);
1170
1195
  const sourceContent = readFileSync(result.filePath, "utf8");
1171
1196
  sourceLines = sourceContent.split(`
1172
1197
  `);
1173
- } catch (error) {}
1198
+ } catch {}
1174
1199
  }
1175
1200
  result.messages.forEach((message) => {
1176
1201
  const type = message.severity === 2 ? "error" : "warning";
1177
1202
  const typeColor = message.severity === 2 ? chalk2.red : chalk2.yellow;
1178
- const icon = message.severity === 2 ? "\u274C" : "\u26A0\uFE0F";
1203
+ const icon = message.severity === 2 ? "x" : "!";
1179
1204
  const ruleInfo = message.ruleId ? chalk2.dim(` (${message.ruleId})`) : "";
1180
1205
  output.push(`
1181
1206
  ${icon} ${typeColor(type)}: ${message.message}${ruleInfo}`);
@@ -1194,7 +1219,7 @@ ${chalk2.dim(`${lineNumber} |`)} ${sourceLine}`);
1194
1219
  }
1195
1220
  });
1196
1221
  if (totalErrors === 0 && totalWarnings === 0)
1197
- return chalk2.bold("\u2705 No ESLint errors or warnings found");
1222
+ return chalk2.bold("No Biome errors or warnings found");
1198
1223
  const errorText = totalErrors > 0 ? chalk2.red(`${totalErrors} error(s)`) : "0 errors";
1199
1224
  const warningText = totalWarnings > 0 ? chalk2.yellow(`${totalWarnings} warning(s)`) : "0 warnings";
1200
1225
  const summary = [`
@@ -1209,23 +1234,26 @@ ${errorText}, ${warningText} found`];
1209
1234
  column: message.column,
1210
1235
  message: message.message,
1211
1236
  ruleId: message.ruleId,
1212
- severity: message.severity === 2 ? "error" : "warning",
1213
- fix: message.fix,
1214
- suggestions: message.suggestions
1237
+ severity: message.severity === 2 ? "error" : "warning"
1215
1238
  })));
1216
1239
  const stats = results.reduce((acc, result) => ({
1217
1240
  errorCount: acc.errorCount + result.errorCount,
1218
1241
  warningCount: acc.warningCount + result.warningCount,
1219
1242
  fixableErrorCount: acc.fixableErrorCount + result.fixableErrorCount,
1220
1243
  fixableWarningCount: acc.fixableWarningCount + result.fixableWarningCount
1221
- }), { errorCount: 0, warningCount: 0, fixableErrorCount: 0, fixableWarningCount: 0 });
1244
+ }), {
1245
+ errorCount: 0,
1246
+ warningCount: 0,
1247
+ fixableErrorCount: 0,
1248
+ fixableWarningCount: 0
1249
+ });
1222
1250
  return { results, details, stats };
1223
1251
  }
1224
1252
  async hasNoLintErrors(filePath) {
1225
1253
  try {
1226
1254
  const { results } = await this.lintFile(filePath);
1227
1255
  return results.every((result) => result.errorCount === 0);
1228
- } catch (error) {
1256
+ } catch {
1229
1257
  return false;
1230
1258
  }
1231
1259
  }
@@ -1238,12 +1266,28 @@ ${errorText}, ${warningText} found`];
1238
1266
  return results.flatMap((result) => result.messages.filter((message) => message.severity === 1));
1239
1267
  }
1240
1268
  async fixFile(filePath, dryRun = false) {
1241
- if (!existsSync(filePath))
1269
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1270
+ if (!existsSync(resolvedFilePath))
1242
1271
  throw new Error(`File not found: ${filePath}`);
1243
- return { fixed: false, output: undefined, results: [], errors: [], warnings: [] };
1272
+ if (!dryRun)
1273
+ return await this.#checkFile(resolvedFilePath, { write: true });
1274
+ const source = readFileSync(resolvedFilePath, "utf8");
1275
+ const { stdout } = await this.#runBiome([
1276
+ "check",
1277
+ "--write",
1278
+ "--config-path",
1279
+ path3.join(this.lintRoot, "biome.json"),
1280
+ "--stdin-file-path",
1281
+ this.#toBiomePath(resolvedFilePath)
1282
+ ], source);
1283
+ const lintResult = await this.lintFile(resolvedFilePath);
1284
+ return { ...lintResult, fixed: stdout !== source, output: stdout };
1244
1285
  }
1245
1286
  async getConfigForFile(filePath) {
1246
- return {};
1287
+ const resolvedFilePath = this.#resolveFilePath(filePath);
1288
+ if (!existsSync(resolvedFilePath))
1289
+ throw new Error(`File not found: ${filePath}`);
1290
+ return JSON.parse(readFileSync(path3.join(this.lintRoot, "biome.json"), "utf8"));
1247
1291
  }
1248
1292
  async getProblematicRules(filePath) {
1249
1293
  const { results } = await this.lintFile(filePath);
@@ -1633,23 +1677,23 @@ async function assertScanConvention(exec, libRoot) {
1633
1677
  files.filter((filename) => !appRootAllowedFiles.has(filename)).forEach((filename) => {
1634
1678
  addViolation(filename, "unsupported app root file");
1635
1679
  });
1636
- dirs.filter((dirname2) => !appRootAllowedDirs.has(dirname2)).forEach((dirname2) => {
1637
- addViolation(dirname2, "unsupported app root folder");
1680
+ dirs.filter((dirname) => !appRootAllowedDirs.has(dirname)).forEach((dirname) => {
1681
+ addViolation(dirname, "unsupported app root folder");
1638
1682
  });
1639
1683
  }
1640
1684
  libRoot.files.filter((filename) => !isAllowedLibRootFile(filename)).forEach((filename) => {
1641
1685
  addViolation(path5.join("lib", filename), "unsupported lib root file");
1642
1686
  });
1643
- libRoot.dirs.filter((dirname2) => dirname2.startsWith("__") && !internalLibDirs.has(dirname2)).forEach((dirname2) => {
1644
- addViolation(path5.join("lib", dirname2), "unsupported internal lib folder");
1687
+ libRoot.dirs.filter((dirname) => dirname.startsWith("__") && !internalLibDirs.has(dirname)).forEach((dirname) => {
1688
+ addViolation(path5.join("lib", dirname), "unsupported internal lib folder");
1645
1689
  });
1646
- const databaseDirs = libRoot.dirs.filter((dirname2) => !dirname2.startsWith("_"));
1647
- const serviceDirs = libRoot.dirs.filter((dirname2) => dirname2.startsWith("_") && !dirname2.startsWith("__"));
1690
+ const databaseDirs = libRoot.dirs.filter((dirname) => !dirname.startsWith("_"));
1691
+ const serviceDirs = libRoot.dirs.filter((dirname) => dirname.startsWith("_") && !dirname.startsWith("__"));
1648
1692
  const scalarDirs = await exec.readdir("lib/__scalar");
1649
1693
  await Promise.all([
1650
- ...databaseDirs.map((dirname2) => validateModuleFiles(exec, violations, "database", path5.join("lib", dirname2))),
1651
- ...serviceDirs.map((dirname2) => validateModuleFiles(exec, violations, "service", path5.join("lib", dirname2))),
1652
- ...scalarDirs.map((dirname2) => validateModuleFiles(exec, violations, "scalar", path5.join("lib/__scalar", dirname2)))
1694
+ ...databaseDirs.map((dirname) => validateModuleFiles(exec, violations, "database", path5.join("lib", dirname))),
1695
+ ...serviceDirs.map((dirname) => validateModuleFiles(exec, violations, "service", path5.join("lib", dirname))),
1696
+ ...scalarDirs.map((dirname) => validateModuleFiles(exec, violations, "scalar", path5.join("lib/__scalar", dirname)))
1653
1697
  ]);
1654
1698
  if (violations.length > 0) {
1655
1699
  throw new Error(`[scan-convention]
@@ -1659,8 +1703,8 @@ ${violations.sort().map((violation) => `- ${violation}`).join(`
1659
1703
  }
1660
1704
  async function validateModuleFiles(exec, violations, kind, modulePath) {
1661
1705
  const { files, dirs } = await exec.getFilesAndDirs(modulePath);
1662
- dirs.forEach((dirname2) => {
1663
- violations.push(`${getScanPath(exec, path5.join(modulePath, dirname2))}: unsupported module folder`);
1706
+ dirs.forEach((dirname) => {
1707
+ violations.push(`${getScanPath(exec, path5.join(modulePath, dirname))}: unsupported module folder`);
1664
1708
  });
1665
1709
  files.forEach((filename) => {
1666
1710
  const filePath = path5.join(modulePath, filename);
@@ -1759,9 +1803,9 @@ class ScanInfo {
1759
1803
  files.zone.databases.push(name);
1760
1804
  });
1761
1805
  }),
1762
- ...serviceDirs.map(async (dirname2) => {
1763
- const name = dirname2.slice(1);
1764
- const filenames = await exec.readdir(path5.join("lib", dirname2));
1806
+ ...serviceDirs.map(async (dirname) => {
1807
+ const name = dirname.slice(1);
1808
+ const filenames = await exec.readdir(path5.join("lib", dirname));
1765
1809
  filenames.forEach((filename) => {
1766
1810
  if (filename.endsWith(".dictionary.ts"))
1767
1811
  files.dictionary.services.push(name);
@@ -2330,8 +2374,13 @@ class CommandExecutionError extends Error {
2330
2374
  const displayCommand = formatCommandForDisplay(command, args);
2331
2375
  const status = signal ? `signal: ${signal}` : `exit code: ${code ?? "unknown"}`;
2332
2376
  const output = (stderr || stdout).trim();
2333
- super([`Command failed: ${displayCommand}`, `cwd: ${cwd}`, status, output ? `
2334
- ${output}` : ""].join(`
2377
+ super([
2378
+ `Command failed: ${displayCommand}`,
2379
+ `cwd: ${cwd}`,
2380
+ status,
2381
+ output ? `
2382
+ ${output}` : ""
2383
+ ].join(`
2335
2384
  `), {
2336
2385
  cause
2337
2386
  });
@@ -2380,7 +2429,13 @@ var parseEnvFile = (envPath) => {
2380
2429
  }
2381
2430
  return env;
2382
2431
  };
2383
- var PAGE_ROUTE_EXPORTS = new Set(["default", "pageConfig", "head", "generateHead", "Loading"]);
2432
+ var PAGE_ROUTE_EXPORTS = new Set([
2433
+ "default",
2434
+ "pageConfig",
2435
+ "head",
2436
+ "generateHead",
2437
+ "Loading"
2438
+ ]);
2384
2439
  var ROOT_LAYOUT_EXPORTS = new Set([
2385
2440
  "default",
2386
2441
  "head",
@@ -2393,7 +2448,12 @@ var ROOT_LAYOUT_EXPORTS = new Set([
2393
2448
  "gaTrackingId",
2394
2449
  "Loading"
2395
2450
  ]);
2396
- var LAYOUT_ROUTE_EXPORTS = new Set(["default", "head", "generateHead", "Loading"]);
2451
+ var LAYOUT_ROUTE_EXPORTS = new Set([
2452
+ "default",
2453
+ "head",
2454
+ "generateHead",
2455
+ "Loading"
2456
+ ]);
2397
2457
  function validateRouteSourceExports(source, filePath, kind, options = {}) {
2398
2458
  const sourceFile = ts3.createSourceFile(filePath, source, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TSX);
2399
2459
  const allowed = kind === "page" ? PAGE_ROUTE_EXPORTS : options.rootLayout ? ROOT_LAYOUT_EXPORTS : LAYOUT_ROUTE_EXPORTS;
@@ -2462,16 +2522,16 @@ class Executor {
2462
2522
  linter = null;
2463
2523
  constructor(name, cwdPath) {
2464
2524
  this.name = name;
2465
- this.logger = new Logger4(name);
2525
+ this.logger = new Logger3(name);
2466
2526
  this.logs = [];
2467
2527
  this.cwdPath = cwdPath;
2468
2528
  }
2469
2529
  #stdout(data) {
2470
2530
  if (Executor.verbose)
2471
- Logger4.raw(chalk4.dim(data.toString()));
2531
+ Logger3.raw(chalk4.dim(data.toString()));
2472
2532
  }
2473
2533
  #stderr(data) {
2474
- Logger4.raw(chalk4.red(data.toString()));
2534
+ Logger3.raw(chalk4.red(data.toString()));
2475
2535
  }
2476
2536
  exec(command, options = {}) {
2477
2537
  const cwd = options.cwd?.toString() ?? this.cwdPath;
@@ -2488,11 +2548,26 @@ class Executor {
2488
2548
  });
2489
2549
  return new Promise((resolve, reject) => {
2490
2550
  proc.on("error", (error) => {
2491
- reject(new CommandExecutionError({ command, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2551
+ reject(new CommandExecutionError({
2552
+ command,
2553
+ cwd,
2554
+ code: null,
2555
+ signal: null,
2556
+ stdout,
2557
+ stderr,
2558
+ cause: error
2559
+ }));
2492
2560
  });
2493
2561
  proc.on("exit", (code, signal) => {
2494
2562
  if (!!code || signal)
2495
- reject(new CommandExecutionError({ command, cwd, code, signal, stdout, stderr }));
2563
+ reject(new CommandExecutionError({
2564
+ command,
2565
+ cwd,
2566
+ code,
2567
+ signal,
2568
+ stdout,
2569
+ stderr
2570
+ }));
2496
2571
  else
2497
2572
  resolve({ code, signal });
2498
2573
  });
@@ -2500,7 +2575,7 @@ class Executor {
2500
2575
  }
2501
2576
  spawn(command, args = [], options = {}) {
2502
2577
  const cwd = options.cwd?.toString() ?? this.cwdPath;
2503
- const proc = spawn(command, args, {
2578
+ const proc = spawn2(command, args, {
2504
2579
  cwd: this.cwdPath,
2505
2580
  ...options
2506
2581
  });
@@ -2518,18 +2593,35 @@ class Executor {
2518
2593
  });
2519
2594
  return new Promise((resolve, reject) => {
2520
2595
  proc.on("error", (error) => {
2521
- reject(new CommandExecutionError({ command, args, cwd, code: null, signal: null, stdout, stderr, cause: error }));
2596
+ reject(new CommandExecutionError({
2597
+ command,
2598
+ args,
2599
+ cwd,
2600
+ code: null,
2601
+ signal: null,
2602
+ stdout,
2603
+ stderr,
2604
+ cause: error
2605
+ }));
2522
2606
  });
2523
2607
  proc.on("close", (code, signal) => {
2524
2608
  if (code !== 0 || signal)
2525
- reject(new CommandExecutionError({ command, args, cwd, code, signal, stdout, stderr }));
2609
+ reject(new CommandExecutionError({
2610
+ command,
2611
+ args,
2612
+ cwd,
2613
+ code,
2614
+ signal,
2615
+ stdout,
2616
+ stderr
2617
+ }));
2526
2618
  else
2527
2619
  resolve(stdout);
2528
2620
  });
2529
2621
  });
2530
2622
  }
2531
2623
  spawnSync(command, args = [], options = {}) {
2532
- const proc = spawn(command, args, {
2624
+ const proc = spawn2(command, args, {
2533
2625
  cwd: this.cwdPath,
2534
2626
  ...options
2535
2627
  });
@@ -2566,7 +2658,15 @@ class Executor {
2566
2658
  });
2567
2659
  proc.on("exit", (code, signal) => {
2568
2660
  if (!!code || signal)
2569
- reject(new CommandExecutionError({ command: modulePath, args, cwd, code, signal, stdout, stderr }));
2661
+ reject(new CommandExecutionError({
2662
+ command: modulePath,
2663
+ args,
2664
+ cwd,
2665
+ code,
2666
+ signal,
2667
+ stdout,
2668
+ stderr
2669
+ }));
2570
2670
  else
2571
2671
  resolve({ code, signal });
2572
2672
  });
@@ -2653,7 +2753,7 @@ class Executor {
2653
2753
  contentStr = currentContent;
2654
2754
  } else {
2655
2755
  await FileSys.writeText(writePath, contentStr);
2656
- if (Logger4.isVerbose())
2756
+ if (Logger3.isVerbose())
2657
2757
  this.logger.rawLog(chalk4.yellow(`File Update: ${filePath}`));
2658
2758
  }
2659
2759
  } else {
@@ -2700,7 +2800,11 @@ class Executor {
2700
2800
  this.logger.debug(msg);
2701
2801
  return this;
2702
2802
  }
2703
- spinning(msg, { prefix = `${this.emoji}${this.name}`, indent = 0, enableSpin = !Executor.verbose } = {}) {
2803
+ spinning(msg, {
2804
+ prefix = `${this.emoji}${this.name}`,
2805
+ indent = 0,
2806
+ enableSpin = !Executor.verbose
2807
+ } = {}) {
2704
2808
  return new Spinner(msg, { prefix, indent, enableSpin }).start();
2705
2809
  }
2706
2810
  #tsconfig = null;
@@ -2713,7 +2817,10 @@ class Executor {
2713
2817
  const result = {
2714
2818
  ...extendsTsconfig,
2715
2819
  ...tsconfig,
2716
- compilerOptions: { ...extendsTsconfig.compilerOptions, ...tsconfig.compilerOptions }
2820
+ compilerOptions: {
2821
+ ...extendsTsconfig.compilerOptions,
2822
+ ...tsconfig.compilerOptions
2823
+ }
2717
2824
  };
2718
2825
  this.#tsconfig = result;
2719
2826
  return result;
@@ -2726,7 +2833,9 @@ class Executor {
2726
2833
  this.#tsconfig = tsconfig;
2727
2834
  }
2728
2835
  #packageJson = null;
2729
- async getPackageJson({ refresh } = {}) {
2836
+ async getPackageJson({
2837
+ refresh
2838
+ } = {}) {
2730
2839
  if (this.#packageJson && !refresh)
2731
2840
  return this.#packageJson;
2732
2841
  const packageJson = await this.readJson("package.json");
@@ -2759,8 +2868,8 @@ class Executor {
2759
2868
  return null;
2760
2869
  const filename = typeof result === "object" ? result.filename : path7.basename(targetPath).replace(".js", ".ts");
2761
2870
  const content = typeof result === "object" ? result.content : result;
2762
- const dirname3 = path7.dirname(targetPath);
2763
- const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), `${dirname3}/${filename}`);
2871
+ const dirname2 = path7.dirname(targetPath);
2872
+ const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), `${dirname2}/${filename}`);
2764
2873
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2765
2874
  return this.writeFile(convertedTargetPath, content, { overwrite });
2766
2875
  } else if (targetPath.endsWith(".template")) {
@@ -2768,13 +2877,15 @@ class Executor {
2768
2877
  const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), targetPath.slice(0, -9));
2769
2878
  const convertedContent = Object.entries(dict).reduce((data, [key, value]) => data.replace(new RegExp(`<%= ${key} %>`, "g"), value), content);
2770
2879
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2771
- return this.writeFile(convertedTargetPath, convertedContent, { overwrite });
2880
+ return this.writeFile(convertedTargetPath, convertedContent, {
2881
+ overwrite
2882
+ });
2772
2883
  } else if (staticTemplateFileExtensions.has(path7.extname(targetPath).toLowerCase())) {
2773
2884
  const convertedTargetPath = Object.entries(dict).reduce((path8, [key, value]) => path8.replace(new RegExp(`__${key}__`, "g"), value), targetPath);
2774
2885
  const writePath = this.getPath(convertedTargetPath);
2775
- const dirname3 = path7.dirname(writePath);
2776
- if (!await FileSys.dirExists(dirname3))
2777
- await mkdir2(dirname3, { recursive: true });
2886
+ const dirname2 = path7.dirname(writePath);
2887
+ if (!await FileSys.dirExists(dirname2))
2888
+ await mkdir2(dirname2, { recursive: true });
2778
2889
  await copyFile(templatePath, writePath);
2779
2890
  this.logger.verbose(`Apply template ${templatePath} to ${convertedTargetPath}`);
2780
2891
  return { filePath: writePath, content: "" };
@@ -2794,14 +2905,24 @@ class Executor {
2794
2905
  const prefixTemplatePath = templatePath;
2795
2906
  if ((await stat2(prefixTemplatePath)).isFile()) {
2796
2907
  const filename = path7.basename(prefixTemplatePath);
2797
- const fileContent = await this.#applyTemplateFile({ templatePath: prefixTemplatePath, targetPath: path7.join(basePath2, filename), scanInfo, overwrite }, dict, options);
2908
+ const fileContent = await this.#applyTemplateFile({
2909
+ templatePath: prefixTemplatePath,
2910
+ targetPath: path7.join(basePath2, filename),
2911
+ scanInfo,
2912
+ overwrite
2913
+ }, dict, options);
2798
2914
  return fileContent ? [fileContent] : [];
2799
2915
  } else {
2800
2916
  const subdirs = await readDirEntries(templatePath);
2801
2917
  const fileContents = (await Promise.all(subdirs.map(async (subdir) => {
2802
2918
  const subpath = path7.join(templatePath, subdir);
2803
2919
  if ((await stat2(subpath)).isFile()) {
2804
- const fileContent = await this.#applyTemplateFile({ templatePath: subpath, targetPath: path7.join(basePath2, subdir), scanInfo, overwrite }, dict, options);
2920
+ const fileContent = await this.#applyTemplateFile({
2921
+ templatePath: subpath,
2922
+ targetPath: path7.join(basePath2, subdir),
2923
+ scanInfo,
2924
+ overwrite
2925
+ }, dict, options);
2805
2926
  return fileContent ? [fileContent] : [];
2806
2927
  } else
2807
2928
  return await this._applyTemplate({
@@ -2830,7 +2951,10 @@ class Executor {
2830
2951
  async applyTemplate(options) {
2831
2952
  const dict = {
2832
2953
  ...options.dict ?? {},
2833
- ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [capitalize(key), capitalize(value)]))
2954
+ ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [
2955
+ capitalize(key),
2956
+ capitalize(value)
2957
+ ]))
2834
2958
  };
2835
2959
  return this._applyTemplate({ ...options, dict });
2836
2960
  }
@@ -2845,6 +2969,48 @@ class Executor {
2845
2969
  const message = typeChecker.formatDiagnostics(fileDiagnostics);
2846
2970
  return { fileDiagnostics, fileErrors, fileWarnings, message };
2847
2971
  }
2972
+ async typeCheckAsync(filePath) {
2973
+ const path8 = this.getPath(filePath);
2974
+ const entry = await this.#resolveTypecheckWorkerEntry();
2975
+ const proc = Bun.spawn([process.execPath, entry], {
2976
+ cwd: this.cwdPath,
2977
+ env: {
2978
+ ...process.env,
2979
+ AKAN_TYPECHECK_CWD: this.cwdPath,
2980
+ AKAN_TYPECHECK_FILE: path8
2981
+ },
2982
+ stdout: "pipe",
2983
+ stderr: "pipe"
2984
+ });
2985
+ const [stdout, stderr, exitCode] = await Promise.all([
2986
+ new Response(proc.stdout).text(),
2987
+ new Response(proc.stderr).text(),
2988
+ proc.exited
2989
+ ]);
2990
+ if (exitCode !== 0)
2991
+ throw new Error((stderr || stdout).trim() || `Typecheck failed with exit code ${exitCode}`);
2992
+ const result = JSON.parse(stdout);
2993
+ return {
2994
+ fileDiagnostics: Array.from({ length: result.fileDiagnosticsCount }),
2995
+ fileErrors: Array.from({ length: result.fileErrorsCount }),
2996
+ fileWarnings: Array.from({ length: result.fileWarningsCount }),
2997
+ message: result.message
2998
+ };
2999
+ }
3000
+ async#resolveTypecheckWorkerEntry() {
3001
+ const dirname2 = getDirname(import.meta.url);
3002
+ const candidates = [
3003
+ path7.join(process.cwd(), "pkgs/@akanjs/devkit/typecheck/typecheck.proc.ts"),
3004
+ path7.join(process.cwd(), "node_modules/@akanjs/devkit/typecheck/typecheck.proc.ts"),
3005
+ path7.join(dirname2, "typecheck/typecheck.proc.ts"),
3006
+ path7.join(dirname2, "typecheck.proc.js"),
3007
+ path7.join(dirname2, "typecheck.proc.ts")
3008
+ ];
3009
+ for (const candidate of candidates)
3010
+ if (await Bun.file(candidate).exists())
3011
+ return candidate;
3012
+ throw new Error(`[devkit] typecheck worker entry not found; looked in: ${candidates.join(", ")}`);
3013
+ }
2848
3014
  getLinter() {
2849
3015
  this.linter ??= new Linter(this.cwdPath);
2850
3016
  return this.linter;
@@ -2852,7 +3018,10 @@ class Executor {
2852
3018
  async lint(filePath, { fix = false, dryRun = false } = {}) {
2853
3019
  const path8 = this.getPath(filePath);
2854
3020
  const linter = this.getLinter();
2855
- const { results, errors, warnings } = await linter.lint(path8, { fix, dryRun });
3021
+ const { results, errors, warnings } = await linter.lint(path8, {
3022
+ fix,
3023
+ dryRun
3024
+ });
2856
3025
  const message = linter.formatLintResults(results);
2857
3026
  return { results, message, errors, warnings };
2858
3027
  }
@@ -2878,6 +3047,7 @@ class WorkspaceExecutor extends Executor {
2878
3047
  const sourceEnv = envPath ? { ...process.env, ...parseEnvFile(envPath) } : process.env;
2879
3048
  const appName = sourceEnv.AKAN_PUBLIC_APP_NAME;
2880
3049
  const workspaceRoot = sourceEnv.AKAN_WORKSPACE_ROOT;
3050
+ const workspaceId = sourceEnv.AKAN_WORKSPACE_ID;
2881
3051
  const repoName = sourceEnv.AKAN_PUBLIC_REPO_NAME;
2882
3052
  if (!repoName)
2883
3053
  throw new Error("AKAN_PUBLIC_REPO_NAME is not set");
@@ -2888,7 +3058,23 @@ class WorkspaceExecutor extends Executor {
2888
3058
  const env = sourceEnv.AKAN_PUBLIC_ENV ?? "debug";
2889
3059
  if (!env)
2890
3060
  throw new Error("AKAN_PUBLIC_ENV is not set");
2891
- return { ...appName ? { appName } : {}, workspaceRoot, repoName, serveDomain, env, portOffset };
3061
+ return {
3062
+ ...appName ? { appName } : {},
3063
+ workspaceRoot,
3064
+ repoName,
3065
+ serveDomain,
3066
+ env,
3067
+ portOffset,
3068
+ workspaceId
3069
+ };
3070
+ }
3071
+ getWorkspaceId({
3072
+ allowEmpty
3073
+ } = {}) {
3074
+ const { workspaceId } = WorkspaceExecutor.getBaseDevEnv();
3075
+ if (!workspaceId && !allowEmpty)
3076
+ throw new Error("Workspace ID is not found");
3077
+ return workspaceId;
2892
3078
  }
2893
3079
  async scan() {
2894
3080
  return await WorkspaceInfo.fromExecutor(this);
@@ -2904,7 +3090,10 @@ class WorkspaceExecutor extends Executor {
2904
3090
  return await this.#getDirHasFile(`${this.workspaceRoot}/libs`, "akan.config.ts");
2905
3091
  }
2906
3092
  async getSyss() {
2907
- const [appNames, libNames] = await Promise.all([this.getApps(), this.getLibs()]);
3093
+ const [appNames, libNames] = await Promise.all([
3094
+ this.getApps(),
3095
+ this.getLibs()
3096
+ ]);
2908
3097
  return [appNames, libNames];
2909
3098
  }
2910
3099
  async getPkgs() {
@@ -2913,7 +3102,11 @@ class WorkspaceExecutor extends Executor {
2913
3102
  return await this.#getDirHasFile(`${this.workspaceRoot}/pkgs`, "package.json");
2914
3103
  }
2915
3104
  async getExecs() {
2916
- const [appNames, libNames, pkgNames] = await Promise.all([this.getApps(), this.getLibs(), this.getPkgs()]);
3105
+ const [appNames, libNames, pkgNames] = await Promise.all([
3106
+ this.getApps(),
3107
+ this.getLibs(),
3108
+ this.getPkgs()
3109
+ ]);
2917
3110
  return [appNames, libNames, pkgNames];
2918
3111
  }
2919
3112
  async setPkgTsPaths(name) {
@@ -2931,7 +3124,10 @@ class WorkspaceExecutor extends Executor {
2931
3124
  async unsetPkgTsPaths(name) {
2932
3125
  const rootTsConfig = await this.readJson("tsconfig.json");
2933
3126
  const filteredKeys = Object.keys(rootTsConfig.compilerOptions.paths ?? {}).filter((key) => key !== name && key !== `${name}/*`);
2934
- rootTsConfig.compilerOptions.paths = Object.fromEntries(filteredKeys.map((key) => [key, rootTsConfig.compilerOptions.paths?.[key] ?? []]));
3127
+ rootTsConfig.compilerOptions.paths = Object.fromEntries(filteredKeys.map((key) => [
3128
+ key,
3129
+ rootTsConfig.compilerOptions.paths?.[key] ?? []
3130
+ ]));
2935
3131
  if (rootTsConfig.references) {
2936
3132
  rootTsConfig.references = rootTsConfig.references.filter((ref) => ref.path !== `./pkgs/${name}/tsconfig.json`);
2937
3133
  }
@@ -2940,12 +3136,12 @@ class WorkspaceExecutor extends Executor {
2940
3136
  }
2941
3137
  async getDirInModule(basePath2, name) {
2942
3138
  const AVOID_DIRS = ["__lib", "__scalar", `_`, `_${name}`];
2943
- const getDirs = async (dirname3, maxDepth = 3, results = [], prefix = "") => {
2944
- const dirs = await this.readdir(dirname3);
3139
+ const getDirs = async (dirname2, maxDepth = 3, results = [], prefix = "") => {
3140
+ const dirs = await this.readdir(dirname2);
2945
3141
  await Promise.all(dirs.map(async (dir) => {
2946
3142
  if (dir.includes("_") || AVOID_DIRS.includes(dir))
2947
3143
  return;
2948
- const dirPath = path7.join(dirname3, dir);
3144
+ const dirPath = path7.join(dirname2, dir);
2949
3145
  if ((await stat2(dirPath)).isDirectory()) {
2950
3146
  results.push(`${prefix}${dir}`);
2951
3147
  if (maxDepth > 0)
@@ -2965,12 +3161,12 @@ class WorkspaceExecutor extends Executor {
2965
3161
  }
2966
3162
  async#getDirHasFile(basePath2, targetFilename) {
2967
3163
  const AVOID_DIRS = ["node_modules", "dist", "public", "webkit"];
2968
- const getDirs = async (dirname3, maxDepth = 3, results = [], prefix = "") => {
2969
- const dirs = await this.readdir(dirname3);
3164
+ const getDirs = async (dirname2, maxDepth = 3, results = [], prefix = "") => {
3165
+ const dirs = await this.readdir(dirname2);
2970
3166
  await Promise.all(dirs.map(async (dir) => {
2971
3167
  if (AVOID_DIRS.includes(dir))
2972
3168
  return;
2973
- const dirPath = path7.join(dirname3, dir);
3169
+ const dirPath = path7.join(dirname2, dir);
2974
3170
  if ((await stat2(dirPath)).isDirectory()) {
2975
3171
  const hasTargetFile = await FileSys.fileExists(path7.join(dirPath, targetFilename));
2976
3172
  if (hasTargetFile)
@@ -3023,7 +3219,11 @@ class SysExecutor extends Executor {
3023
3219
  name;
3024
3220
  type;
3025
3221
  emoji;
3026
- constructor({ workspace = WorkspaceExecutor.fromRoot(), name, type }) {
3222
+ constructor({
3223
+ workspace = WorkspaceExecutor.fromRoot(),
3224
+ name,
3225
+ type
3226
+ }) {
3027
3227
  super(name, `${workspace.workspaceRoot}/${type}s/${name}`);
3028
3228
  this.workspace = workspace;
3029
3229
  this.name = name;
@@ -3092,7 +3292,11 @@ class SysExecutor extends Executor {
3092
3292
  } = {}) {
3093
3293
  if (this.#scanInfo && !refresh)
3094
3294
  return this.#scanInfo;
3095
- const scanInfo = this.type === "app" ? await AppInfo.fromExecutor(this, { refresh }) : await LibInfo.fromExecutor(this, { refresh });
3295
+ const scanInfo = this.type === "app" ? await AppInfo.fromExecutor(this, {
3296
+ refresh
3297
+ }) : await LibInfo.fromExecutor(this, {
3298
+ refresh
3299
+ });
3096
3300
  if (write) {
3097
3301
  await Promise.all(this.#getScanTemplateTasks(scanInfo));
3098
3302
  await this.writeJson(`akan.${this.type}.json`, scanInfo.getScanResult());
@@ -3122,7 +3326,10 @@ class SysExecutor extends Executor {
3122
3326
  },
3123
3327
  devDependencies: {
3124
3328
  ...Object.fromEntries(Object.entries(libPackageJson.devDependencies ?? {}).filter(([dep]) => !dependencySet.has(dep))),
3125
- ...Object.fromEntries(devDependencies.filter((dep) => rootPackageJson.dependencies?.[dep] || rootPackageJson.devDependencies?.[dep]).sort().map((dep) => [dep, rootPackageJson.devDependencies?.[dep] ?? rootPackageJson.dependencies?.[dep]]))
3329
+ ...Object.fromEntries(devDependencies.filter((dep) => rootPackageJson.dependencies?.[dep] || rootPackageJson.devDependencies?.[dep]).sort().map((dep) => [
3330
+ dep,
3331
+ rootPackageJson.devDependencies?.[dep] ?? rootPackageJson.dependencies?.[dep]
3332
+ ]))
3126
3333
  }
3127
3334
  };
3128
3335
  await this.setPackageJson(libPkgJsonWithDeps);
@@ -3189,7 +3396,11 @@ class SysExecutor extends Executor {
3189
3396
  ...await LibExecutor.from(this, lib).getConstantFiles(),
3190
3397
  ...await LibExecutor.from(this, lib).getScalarConstantFiles()
3191
3398
  ]));
3192
- return [...sysContantFiles, ...sysScalarConstantFiles, ...libConstantFiles.flat()];
3399
+ return [
3400
+ ...sysContantFiles,
3401
+ ...sysScalarConstantFiles,
3402
+ ...libConstantFiles.flat()
3403
+ ];
3193
3404
  }
3194
3405
  async getDictionaryFiles() {
3195
3406
  const modules = await this.getModules();
@@ -3198,10 +3409,17 @@ class SysExecutor extends Executor {
3198
3409
  async applyTemplate(options) {
3199
3410
  const dict = {
3200
3411
  ...options.dict ?? {},
3201
- ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [capitalize(key), capitalize(value)]))
3412
+ ...Object.fromEntries(Object.entries(options.dict ?? {}).map(([key, value]) => [
3413
+ capitalize(key),
3414
+ capitalize(value)
3415
+ ]))
3202
3416
  };
3203
3417
  const scanInfo = await this.scan();
3204
- const fileContents = await this._applyTemplate({ ...options, scanInfo, dict });
3418
+ const fileContents = await this._applyTemplate({
3419
+ ...options,
3420
+ scanInfo,
3421
+ dict
3422
+ });
3205
3423
  await this.scan();
3206
3424
  return fileContents;
3207
3425
  }
@@ -3253,7 +3471,10 @@ class AppExecutor extends SysExecutor {
3253
3471
  if (type === "build") {
3254
3472
  if (await this.exists(this.dist.cwdPath))
3255
3473
  await this.dist.exec(`rm -rf ${this.dist.cwdPath}`);
3256
- await Promise.all([this.dist.mkdir("private"), this.dist.mkdir("public")]);
3474
+ await Promise.all([
3475
+ this.dist.mkdir("private"),
3476
+ this.dist.mkdir("public")
3477
+ ]);
3257
3478
  await Promise.all([
3258
3479
  this.cp("private", `${this.dist.cwdPath}/private`),
3259
3480
  this.cp("public", `${this.dist.cwdPath}/public`)
@@ -3296,7 +3517,9 @@ class AppExecutor extends SysExecutor {
3296
3517
  return this.#akanConfig;
3297
3518
  }
3298
3519
  #pageKeys = null;
3299
- async getPageKeys({ refresh } = {}) {
3520
+ async getPageKeys({
3521
+ refresh
3522
+ } = {}) {
3300
3523
  if (this.#pageKeys && !refresh)
3301
3524
  return this.#pageKeys;
3302
3525
  const akanConfig2 = await this.getConfig();
@@ -3307,7 +3530,11 @@ class AppExecutor extends SysExecutor {
3307
3530
  this.#pageKeys = [];
3308
3531
  return this.#pageKeys;
3309
3532
  }
3310
- for await (const rel of glob.scan({ cwd: pageDir, absolute: false, onlyFiles: true })) {
3533
+ for await (const rel of glob.scan({
3534
+ cwd: pageDir,
3535
+ absolute: false,
3536
+ onlyFiles: true
3537
+ })) {
3311
3538
  const segments = rel.split(path7.sep);
3312
3539
  if (segments.some((s) => s === "node_modules"))
3313
3540
  continue;
@@ -3317,7 +3544,10 @@ class AppExecutor extends SysExecutor {
3317
3544
  if (!isRouteSourceFile(posix))
3318
3545
  continue;
3319
3546
  const key = `./${posix}`;
3320
- validateSubRoutePageKey(key, akanConfig2.basePaths, { appName: this.name, filePath: absPath });
3547
+ validateSubRoutePageKey(key, akanConfig2.basePaths, {
3548
+ appName: this.name,
3549
+ filePath: absPath
3550
+ });
3321
3551
  const parsed = parseRouteModuleKey(key);
3322
3552
  if (parsed.isInternalRootLayout) {
3323
3553
  throw new Error(`[route-convention] __root_layout is reserved for Akan.js generated root layout: ${absPath}`);
@@ -3338,7 +3568,10 @@ class AppExecutor extends SysExecutor {
3338
3568
  const projectAssetsPath = `${this.cwdPath}/private`;
3339
3569
  const projectPublicLibPath = `${projectPublicPath}/libs`;
3340
3570
  const projectAssetsLibPath = `${projectAssetsPath}/libs`;
3341
- await Promise.all([this.removeDir(projectPublicLibPath), this.removeDir(projectAssetsLibPath)]);
3571
+ await Promise.all([
3572
+ this.removeDir(projectPublicLibPath),
3573
+ this.removeDir(projectAssetsLibPath)
3574
+ ]);
3342
3575
  const targetPublicDeps = [];
3343
3576
  for (const dep of libDeps) {
3344
3577
  if (await this.exists(`${this.workspace.workspaceRoot}/libs/${dep}/public`))
@@ -3356,8 +3589,15 @@ class AppExecutor extends SysExecutor {
3356
3589
  ...targetAssetsDeps.map((dep) => this.cp(`${this.workspace.workspaceRoot}/libs/${dep}/private`, `${projectAssetsLibPath}/${dep}`))
3357
3590
  ]);
3358
3591
  }
3359
- async scanSync({ refresh = false, write = true } = {}) {
3360
- const scanInfo = await this.scan({ refresh, write, writeLib: write });
3592
+ async scanSync({
3593
+ refresh = false,
3594
+ write = true
3595
+ } = {}) {
3596
+ const scanInfo = await this.scan({
3597
+ refresh,
3598
+ write,
3599
+ writeLib: write
3600
+ });
3361
3601
  if (write)
3362
3602
  await this.syncAssets(scanInfo.getScanResult().libDeps);
3363
3603
  return scanInfo;
@@ -3401,7 +3641,10 @@ class PkgExecutor extends Executor {
3401
3641
  name;
3402
3642
  dist;
3403
3643
  emoji = execEmoji.pkg;
3404
- constructor({ workspace = WorkspaceExecutor.fromRoot(), name }) {
3644
+ constructor({
3645
+ workspace = WorkspaceExecutor.fromRoot(),
3646
+ name
3647
+ }) {
3405
3648
  super(name, `${workspace.workspaceRoot}/pkgs/${name}`);
3406
3649
  this.workspace = workspace;
3407
3650
  this.name = name;
@@ -3421,7 +3664,10 @@ class PkgExecutor extends Executor {
3421
3664
  return scanInfo;
3422
3665
  }
3423
3666
  async#getDependencyVersion(rootPackageJson, dep) {
3424
- const rootDeps = { ...rootPackageJson.dependencies, ...rootPackageJson.devDependencies };
3667
+ const rootDeps = {
3668
+ ...rootPackageJson.dependencies,
3669
+ ...rootPackageJson.devDependencies
3670
+ };
3425
3671
  const rootVersion = rootDeps[dep];
3426
3672
  if (rootVersion)
3427
3673
  return rootVersion;
@@ -3462,7 +3708,10 @@ class PkgExecutor extends Executor {
3462
3708
  };
3463
3709
  }
3464
3710
  async updatePackageJsonDependencies(dependencies = [], devDependencies = []) {
3465
- const [rootPackageJson, pkgJson] = await Promise.all([this.workspace.getPackageJson(), this.getPackageJson()]);
3711
+ const [rootPackageJson, pkgJson] = await Promise.all([
3712
+ this.workspace.getPackageJson(),
3713
+ this.getPackageJson()
3714
+ ]);
3466
3715
  const dependencyMaps = await this.#toDependencyMap(rootPackageJson, dependencies, devDependencies);
3467
3716
  const newPkgJson = {
3468
3717
  ...pkgJson,
@@ -3472,16 +3721,29 @@ class PkgExecutor extends Executor {
3472
3721
  return newPkgJson;
3473
3722
  }
3474
3723
  async generateDistPackageJson(dependencies = [], devDependencies = []) {
3475
- const [rootPackageJson, pkgJson] = await Promise.all([this.workspace.getPackageJson(), this.getPackageJson()]);
3724
+ const [rootPackageJson, pkgJson] = await Promise.all([
3725
+ this.workspace.getPackageJson(),
3726
+ this.getPackageJson()
3727
+ ]);
3476
3728
  const dependencyMaps = await this.#toDependencyMap(rootPackageJson, dependencies, devDependencies);
3477
3729
  const distPkgJson = {
3478
3730
  ...pkgJson,
3479
3731
  type: "module",
3480
- exports: { ...pkgJson.exports, ".": { import: "./index.ts", types: "./index.ts", default: "./index.ts" } },
3732
+ exports: {
3733
+ ...pkgJson.exports,
3734
+ ".": {
3735
+ import: "./index.ts",
3736
+ types: "./index.ts",
3737
+ default: "./index.ts"
3738
+ }
3739
+ },
3481
3740
  engines: { bun: ">=1.3.13" },
3482
3741
  ...dependencyMaps
3483
3742
  };
3484
- await Promise.all([this.dist.writeJson("package.json", distPkgJson), this.writeJson("package.json", distPkgJson)]);
3743
+ await Promise.all([
3744
+ this.dist.writeJson("package.json", distPkgJson),
3745
+ this.writeJson("package.json", distPkgJson)
3746
+ ]);
3485
3747
  return distPkgJson;
3486
3748
  }
3487
3749
  async build() {
@@ -3494,7 +3756,10 @@ class PkgExecutor extends Executor {
3494
3756
  await this.cp(`${this.cwdPath}/dist`, this.dist.cwdPath);
3495
3757
  }
3496
3758
  async generateTsconfigJson() {
3497
- const [rootTsconfig, pkgTsconfig] = await Promise.all([this.workspace.getTsConfig(), this.getTsConfig()]);
3759
+ const [rootTsconfig, pkgTsconfig] = await Promise.all([
3760
+ this.workspace.getTsConfig(),
3761
+ this.getTsConfig()
3762
+ ]);
3498
3763
  const tsconfig = {
3499
3764
  ...rootTsconfig,
3500
3765
  ...pkgTsconfig,
@@ -3658,7 +3923,7 @@ var createTunnel = async (service, { app, environment, port = service === "postg
3658
3923
 
3659
3924
  // pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.host.ts
3660
3925
  import path8 from "path";
3661
- import { Logger as Logger5 } from "akanjs/common";
3926
+ import { Logger as Logger4 } from "akanjs/common";
3662
3927
  var builderMsgTypeSet = new Set([
3663
3928
  "build-route-res",
3664
3929
  "builder-ready",
@@ -3670,7 +3935,7 @@ var builderMsgTypeSet = new Set([
3670
3935
  class IncrementalBuilderHost {
3671
3936
  static #restartBaseDelayMs = 1000;
3672
3937
  static #restartMaxDelayMs = 30000;
3673
- logger = new Logger5("IncrementalBuilderHost");
3938
+ logger = new Logger4("IncrementalBuilderHost");
3674
3939
  entry;
3675
3940
  env;
3676
3941
  app;
@@ -3918,7 +4183,7 @@ class BackendImportGraph {
3918
4183
 
3919
4184
  class AkanAppHost {
3920
4185
  app;
3921
- logger = new Logger6("AkanAppHost");
4186
+ logger = new Logger5("AkanAppHost");
3922
4187
  withInk;
3923
4188
  env;
3924
4189
  #backend = null;
@@ -4201,19 +4466,19 @@ class AkanAppHost {
4201
4466
  }
4202
4467
  }
4203
4468
  // pkgs/@akanjs/devkit/applicationBuildReporter.ts
4204
- import { Logger as Logger7 } from "akanjs/common";
4469
+ import { Logger as Logger6 } from "akanjs/common";
4205
4470
 
4206
4471
  class ApplicationBuildReporter {
4207
4472
  static create() {
4208
4473
  return {
4209
- phaseDone: (phase) => Logger7.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
4474
+ phaseDone: (phase) => Logger6.rawLog(ApplicationBuildReporter.formatPhaseLine(phase))
4210
4475
  };
4211
4476
  }
4212
4477
  static printSummary(result) {
4213
- Logger7.rawLog("");
4214
- Logger7.rawLog(`Route artifacts: ${result.artifactDir}`);
4215
- Logger7.rawLog(`Server output: ${result.outputDir}`);
4216
- Logger7.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
4478
+ Logger6.rawLog("");
4479
+ Logger6.rawLog(`Route artifacts: ${result.artifactDir}`);
4480
+ Logger6.rawLog(`Server output: ${result.outputDir}`);
4481
+ Logger6.rawLog(`Done in ${ApplicationBuildReporter.formatDuration(result.durationMs)}`);
4217
4482
  }
4218
4483
  static formatError(error) {
4219
4484
  if (error instanceof AggregateError) {
@@ -4512,13 +4777,13 @@ import path14 from "path";
4512
4777
 
4513
4778
  // pkgs/@akanjs/devkit/transforms/barrelAnalyzer.ts
4514
4779
  import path12 from "path";
4515
- import { Logger as Logger8 } from "akanjs/common";
4780
+ import { Logger as Logger7 } from "akanjs/common";
4516
4781
  var REEXPORT_RE = /(?:^|\n)\s*export\s+(?:type\s+)?(?:(\*)(?:\s+as\s+(\w+))?|\{\s*([^}]*?)\s*\})\s+from\s+(["'])([^"']+)\4;?/g;
4517
4782
  var LOCAL_NAMED_RE = /(?:^|\n)\s*export\s+\{\s*([^}]*?)\s*\}(?!\s*from)/g;
4518
4783
  var CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
4519
4784
 
4520
4785
  class BarrelAnalyzer {
4521
- #logger = new Logger8("BarrelAnalyzer");
4786
+ #logger = new Logger7("BarrelAnalyzer");
4522
4787
  #opts;
4523
4788
  #cache = new Map;
4524
4789
  #tsTranspiler = new Bun.Transpiler({ loader: "ts" });
@@ -6218,7 +6483,7 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
6218
6483
  }
6219
6484
  // pkgs/@akanjs/devkit/frontendBuild/cssCompiler.ts
6220
6485
  import path23 from "path";
6221
- import { Logger as Logger9 } from "akanjs/common";
6486
+ import { Logger as Logger8 } from "akanjs/common";
6222
6487
  import { compile } from "tailwindcss";
6223
6488
 
6224
6489
  // pkgs/@akanjs/devkit/frontendBuild/cssImportResolver.ts
@@ -6363,7 +6628,7 @@ var NODE_MODULES_RE3 = /[\\/]node_modules[\\/]/;
6363
6628
  var AKANJS_NODE_MODULE_RE3 = /[\\/]node_modules[\\/]akanjs[\\/]/;
6364
6629
 
6365
6630
  class CssCompiler {
6366
- #logger = new Logger9("CssCompiler");
6631
+ #logger = new Logger8("CssCompiler");
6367
6632
  #transpiler = new Bun.Transpiler({ loader: "tsx" });
6368
6633
  #app;
6369
6634
  #cssImportResolver = null;
@@ -7771,7 +8036,7 @@ class ApplicationBuildRunner {
7771
8036
  import { cp, mkdir as mkdir8, rm as rm3 } from "fs/promises";
7772
8037
 
7773
8038
  // pkgs/@akanjs/devkit/uploadRelease.ts
7774
- import { HttpClient, Logger as Logger10 } from "akanjs/common";
8039
+ import { HttpClient as HttpClient2, Logger as Logger9 } from "akanjs/common";
7775
8040
  var spinning = (message) => {
7776
8041
  const spinner = new Spinner(message, { prefix: message, enableSpin: true }).start();
7777
8042
  return spinner;
@@ -7784,9 +8049,9 @@ var uploadRelease = async (appName, {
7784
8049
  os,
7785
8050
  local
7786
8051
  }) => {
7787
- const logger = new Logger10("uploadRelease");
8052
+ const logger = new Logger9("uploadRelease");
7788
8053
  const basePath2 = local ? "http://localhost:8282/backend" : "https://cloud.akanjs.com/backend";
7789
- const httpClient = new HttpClient(basePath2);
8054
+ const httpClient = new HttpClient2(basePath2);
7790
8055
  const buildPath = `${workspaceRoot}/releases/builds/${appName}-release.tar.gz`;
7791
8056
  const appBuildPath = `${workspaceRoot}/releases/builds/${appName}-appBuild.zip`;
7792
8057
  const sourcePath = `${workspaceRoot}/releases/sources/${appName}-source.tar.gz`;
@@ -8770,7 +9035,7 @@ var Workspace = createInternalArgToken("Workspace");
8770
9035
  // pkgs/@akanjs/devkit/commandDecorators/command.ts
8771
9036
  import path36 from "path";
8772
9037
  import { confirm, input as input2, select as select2 } from "@inquirer/prompts";
8773
- import { Logger as Logger11 } from "akanjs/common";
9038
+ import { Logger as Logger10 } from "akanjs/common";
8774
9039
  import chalk6 from "chalk";
8775
9040
  import { program } from "commander";
8776
9041
 
@@ -9055,7 +9320,7 @@ var printCliError = (error) => {
9055
9320
  if (loggedCliErrorMessages.has(message))
9056
9321
  return;
9057
9322
  loggedCliErrorMessages.add(message);
9058
- Logger11.rawLog(`
9323
+ Logger10.rawLog(`
9059
9324
  ${chalk6.red(message)}`);
9060
9325
  };
9061
9326
  var handleOption = (programCommand, argMeta) => {
@@ -9284,7 +9549,7 @@ var runCommands = async (...commands) => {
9284
9549
  const hasCommand = process.argv.length > 2 && !process.argv[2]?.startsWith("-");
9285
9550
  if (hasHelpFlag || !hasCommand) {
9286
9551
  if (process.argv.length === 2 || process.argv.length === 3 && hasHelpFlag) {
9287
- Logger11.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
9552
+ Logger10.rawLog(formatHelp(commands, process.env.AKAN_VERSION));
9288
9553
  process.exit(0);
9289
9554
  }
9290
9555
  }
@@ -9293,7 +9558,7 @@ var runCommands = async (...commands) => {
9293
9558
  });
9294
9559
  const installedAkanPackageJson = await FileSys.fileExists("./node_modules/akanjs/package.json") ? await FileSys.readJson("./node_modules/akanjs/package.json") : null;
9295
9560
  if (installedAkanPackageJson && installedAkanPackageJson.version !== process.env.AKAN_VERSION) {
9296
- Logger11.rawLog(chalk6.yellow(`
9561
+ Logger10.rawLog(chalk6.yellow(`
9297
9562
  Akan CLI version is mismatch with installed package. ${process.env.AKAN_VERSION} (global) vs ${installedAkanPackageJson.version} (akanjs)
9298
9563
  It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`));
9299
9564
  }
@@ -9329,7 +9594,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
9329
9594
  return formatCommandHelp(command, targetMeta.key);
9330
9595
  };
9331
9596
  programCommand.action(async (...args) => {
9332
- Logger11.rawLog();
9597
+ Logger10.rawLog();
9333
9598
  const cmdArgs = args.slice(0, args.length - 2);
9334
9599
  const opt = args[args.length - 2];
9335
9600
  const commandArgs = [];
@@ -9353,7 +9618,7 @@ It may cause unexpected behavior. Run \`akan update\` to update latest akanjs.`)
9353
9618
  const cmd = CommandContainer.get(command);
9354
9619
  try {
9355
9620
  await targetMeta.handler.call(cmd, ...commandArgs);
9356
- Logger11.rawLog();
9621
+ Logger10.rawLog();
9357
9622
  } catch (e) {
9358
9623
  printCliError(e);
9359
9624
  throw e;
@@ -9693,8 +9958,11 @@ import fsPromise from "fs/promises";
9693
9958
  import { input as input3, select as select3 } from "@inquirer/prompts";
9694
9959
  class Prompter {
9695
9960
  static async#getGuidelineRoot() {
9696
- const dirname3 = getDirname(import.meta.url);
9697
- const candidates = [`${dirname3}/guidelines`, `${dirname3}/../cli/guidelines`];
9961
+ const dirname2 = getDirname(import.meta.url);
9962
+ const candidates = [
9963
+ `${dirname2}/guidelines`,
9964
+ `${dirname2}/../cli/guidelines`
9965
+ ];
9698
9966
  for (const candidate of candidates) {
9699
9967
  try {
9700
9968
  await fsPromise.access(candidate);
@@ -9706,7 +9974,10 @@ class Prompter {
9706
9974
  static async selectGuideline() {
9707
9975
  const guidelineRoot = await Prompter.#getGuidelineRoot();
9708
9976
  const guideNames = (await fsPromise.readdir(guidelineRoot)).filter((name) => !name.startsWith("_"));
9709
- return await select3({ message: "Select a guideline", choices: guideNames.map((name) => ({ name, value: name })) });
9977
+ return await select3({
9978
+ message: "Select a guideline",
9979
+ choices: guideNames.map((name) => ({ name, value: name }))
9980
+ });
9710
9981
  }
9711
9982
  static async getGuideJson(guideName) {
9712
9983
  const guidelineRoot = await Prompter.#getGuidelineRoot();
@@ -9721,13 +9992,18 @@ class Prompter {
9721
9992
  return content;
9722
9993
  }
9723
9994
  static async getUpdateRequest(guideName) {
9724
- return await input3({ message: `What do you want to update in ${guideName}?` });
9995
+ return await input3({
9996
+ message: `What do you want to update in ${guideName}?`
9997
+ });
9725
9998
  }
9726
9999
  async makeTsFileUpdatePrompt({ context, request }) {
9727
10000
  return `You are a senior developer writing TypeScript-based programs using Akan.js, an in-house framework. Here's an overview of the Akan.js framework:
9728
10001
  ${await this.getDocumentation("framework")}
9729
10002
  Please understand the following background information, write code that meets the requirements, verify that it satisfies the validation conditions, and return the result.
9730
10003
 
10004
+ # Code Style
10005
+ - Use double quotes for all string literals in TypeScript/TSX code. Do not use single quotes.
10006
+
9731
10007
  # Background Information
9732
10008
  \`\`\`markdown
9733
10009
  ${context}
@@ -9773,82 +10049,11 @@ import { Box as Box2, Newline, Text as Text2, useInput as useInput2 } from "ink"
9773
10049
  import { useEffect as useEffect3, useState as useState3 } from "react";
9774
10050
  import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
9775
10051
  "use client";
9776
- // pkgs/@akanjs/devkit/cloud/cloudApi.ts
9777
- var import_dayjs = __toESM(require_dayjs_min(), 1);
9778
-
9779
- class HttpClient2 {
9780
- baseUrl;
9781
- constructor(baseUrl) {
9782
- this.baseUrl = baseUrl;
9783
- }
9784
- async get(url, { headers } = {}) {
9785
- const response = await fetch(`${this.baseUrl}${url}`, {
9786
- headers: { "Content-Type": "application/json", ...headers }
9787
- });
9788
- return response.json();
9789
- }
9790
- async post(url, data, { headers } = {}) {
9791
- const isFormData = data instanceof FormData;
9792
- const response = await fetch(`${this.baseUrl}${url}`, {
9793
- method: "POST",
9794
- body: isFormData ? data : JSON.stringify(data),
9795
- headers: isFormData ? headers : { "Content-Type": "application/json", ...headers }
9796
- });
9797
- return response.json();
9798
- }
9799
- }
9800
-
9801
- class CloudApi {
9802
- api;
9803
- #accessToken = null;
9804
- constructor(host, { accessToken } = {}) {
9805
- this.api = new HttpClient2(`${host}/api`);
9806
- this.#accessToken = accessToken ?? null;
9807
- }
9808
- async uploadEnv(devProjectId, file) {
9809
- const formData = new FormData;
9810
- formData.append("devProjectId", devProjectId);
9811
- formData.append("file", file);
9812
- const response = await this.api.post(`/uploadEnv/${devProjectId}`, formData);
9813
- return response.success;
9814
- }
9815
- async downloadEnv(devProjectId) {
9816
- const response = await this.api.get(`/downloadEnv/${devProjectId}`);
9817
- return response.success;
9818
- }
9819
- async getRemoteAuthToken(remoteId) {
9820
- if (this.#needRefreshToken())
9821
- return await this.refreshAuthToken();
9822
- else if (this.#accessToken)
9823
- return this.#accessToken;
9824
- const accessToken = await this.api.get(`/getRemoteAuthToken/${remoteId}`);
9825
- this.#accessToken = {
9826
- jwt: accessToken.jwt,
9827
- refreshToken: accessToken.refreshToken,
9828
- expiresAt: accessToken.expiresAt ? import_dayjs.default(accessToken.expiresAt) : null
9829
- };
9830
- return this.#accessToken;
9831
- }
9832
- async refreshAuthToken() {
9833
- const response = await this.api.post(`/refreshRemoteAuthToken`, {
9834
- refreshToken: this.#accessToken?.refreshToken
9835
- });
9836
- this.#accessToken = {
9837
- jwt: response.jwt,
9838
- refreshToken: response.refreshToken,
9839
- expiresAt: response.expiresAt ? import_dayjs.default(response.expiresAt) : null
9840
- };
9841
- return this.#accessToken;
9842
- }
9843
- #needRefreshToken() {
9844
- return !!this.#accessToken?.expiresAt?.isBefore(import_dayjs.default().add(1, "hour"));
9845
- }
9846
- }
9847
10052
  // pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
9848
- import { Logger as Logger12 } from "akanjs/common";
10053
+ import { Logger as Logger11 } from "akanjs/common";
9849
10054
 
9850
10055
  class IncrementalBuilder {
9851
- #logger = new Logger12("IncrementalBuilder");
10056
+ #logger = new Logger11("IncrementalBuilder");
9852
10057
  #app;
9853
10058
  #artifact;
9854
10059
  #watch;