@akanjs/cli 3.0.0-alpha.5 → 3.0.0-alpha.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build-stamp +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/{abstractCompactor-e5yq60qz.js → abstractCompactor-20e0cwbs.js} +2 -2
- package/{agent.command-b0fcx3r2.js → agent.command-nqs3bw0g.js} +8 -7
- package/{application.command-cgmy00gd.js → application.command-k2v46pxf.js} +7 -6
- package/{applicationBuildRunner-n1svrwgt.js → applicationBuildRunner-t5v6tcrm.js} +6 -7
- package/{applicationReleasePackager-gg8ccbeh.js → applicationReleasePackager-93nzdfsy.js} +1 -1
- package/buildBatch.proc.js +6 -5
- package/{capacitorApp-yyw35vg4.js → capacitorApp-927ahhz2.js} +29 -26
- package/{cloud.command-1m7hfdpk.js → cloud.command-7jwmxtez.js} +11 -10
- package/{context.command-b5heat2a.js → context.command-6kn3tady.js} +16 -15
- package/{dependencyScanner-f6grrep3.js → dependencyScanner-rbs2407b.js} +1 -1
- package/getDirname-ka11hm7e.js +8 -0
- package/{guideline.command-9ew6aqhm.js → guideline.command-pjdrndqk.js} +7 -6
- package/guidelines/agentRule/agentRule.generate.json +31 -0
- package/guidelines/agentRule/agentRule.instruction.md +457 -0
- package/guidelines/conventions/conventions.generate.json +25 -0
- package/guidelines/conventions/conventions.instruction.md +773 -0
- package/guidelines/cssRule/cssRule.instruction.md +7 -0
- package/guidelines/framework/framework.instruction.md +1 -0
- package/guidelines/mcpRule/mcpRule.generate.json +25 -0
- package/guidelines/mcpRule/mcpRule.instruction.md +176 -0
- package/guidelines/workspaceOnboarding/workspaceOnboarding.generate.json +24 -0
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +638 -0
- package/incrementalBuilder.proc.js +7 -6
- package/index-1577bej2.js +7 -0
- package/{index-jn9vfpwz.js → index-24h5bqpj.js} +54 -15
- package/{index-hrwzz2wf.js → index-4z05haak.js} +1 -1
- package/{index-m4kpmmtj.js → index-5em412h5.js} +1 -1
- package/{index-6npsfpxr.js → index-5fe016p2.js} +3 -3
- package/{index-bjpxzr6s.js → index-5vy2jzar.js} +1 -1
- package/{index-exhpp31y.js → index-6bs24rb4.js} +15 -7
- package/{index-nx1vbtsc.js → index-7etegaht.js} +14 -14
- package/{index-wrrb8rxk.js → index-7w5vv8jk.js} +4 -4
- package/{index-meh7mmz9.js → index-7zd96bng.js} +8 -4
- package/{index-p69fcwe1.js → index-866yqz3y.js} +13 -13
- package/{index-jkynkyfk.js → index-8rr621r2.js} +5 -3
- package/{index-47qxw1tz.js → index-90zyjrby.js} +170 -65
- package/{index-pfrt7qwh.js → index-97cw8sg1.js} +4 -4
- package/{index-p6txr1ss.js → index-bwt525ne.js} +9 -11
- package/{index-qp089jp0.js → index-j37qq1f2.js} +1 -1
- package/{index-c94nq3c1.js → index-k7sm38v6.js} +3 -3
- package/{index-j9cxndc0.js → index-qnv0aqmm.js} +9 -6
- package/{index-0cj2zxbm.js → index-sh01r3pm.js} +1 -1
- package/{index-0fj4yg7k.js → index-wr999y03.js} +105 -227
- package/{index-nfxq39kj.js → index-xe3ychw5.js} +37 -6
- package/{index-60a3jfcz.js → index-xrdrttjb.js} +8 -8
- package/{index-mn96y1nk.js → index-y59x51f1.js} +6 -6
- package/{index-mterpj70.js → index-zgkey4d0.js} +86 -17
- package/index.js +20 -19
- package/{library.command-aa1g8nsa.js → library.command-7h3yezwc.js} +5 -4
- package/{localRegistry.command-kshva1ck.js → localRegistry.command-vnkc41gj.js} +10 -9
- package/{module.command-b1zzgqde.js → module.command-4g11k3xd.js} +9 -8
- package/{package.command-9qv6vr9s.js → package.command-z7dd6vy2.js} +5 -4
- package/package.json +3 -4
- package/{page.command-k16pw244.js → page.command-y996708m.js} +5 -4
- package/{primitive.command-s60dn1ae.js → primitive.command-4fcn8k83.js} +10 -9
- package/{quality.command-p3vaze52.js → quality.command-hx5af2yn.js} +193 -112
- package/{recipeScanner-tghkzrrt.js → recipeScanner-zrzev25x.js} +3 -3
- package/{repair.command-mfv749ha.js → repair.command-ysxd8pef.js} +7 -6
- package/{routeSourceValidator-cncd92fv.js → routeSourceValidator-7fycdqyv.js} +3 -39
- package/{scalar.command-hs3nwzv1.js → scalar.command-3chgxybs.js} +8 -7
- package/templates/app/env/env.server.debug.ts.template +1 -5
- package/templates/app/env/env.server.develop.ts.template +1 -5
- package/templates/app/env/env.server.local.ts.template +1 -5
- package/templates/app/env/env.server.main.ts.template +1 -5
- package/templates/app/page/styles.css.template +3 -3
- package/templates/appSample/srvkit/AuthGuard.ts +9 -5
- package/templates/appSample/srvkit/SessionInternalArg.ts +4 -3
- package/templates/crudPages/[__model__Id]/edit/page.tsx +1 -1
- package/templates/crudPages/new/page.tsx +1 -1
- package/templates/crudSinglePage/page.tsx +1 -1
- package/templates/env/_env.server.type.ts +7 -5
- package/templates/lib/db.ts +1 -1
- package/templates/lib/dict.ts +1 -1
- package/templates/lib/sig.ts +1 -1
- package/templates/lib/srv.ts +6 -2
- package/templates/module/__Model__.Util.tsx +1 -1
- package/templates/module/__Model__.Zone.tsx +3 -5
- package/templates/workspaceRoot/AGENTS.md.template +0 -967
- package/templates/workspaceRoot/CLAUDE.md.template +19 -0
- package/templates/workspaceRoot/biome.json.template +4 -220
- package/templates/workspaceRoot/docs/AI-DEVELOPMENT.md.template +15 -16
- package/templates/workspaceRoot/docs/GENERATED.md.template +12 -10
- package/{typeChecker-kravn7ns.js → typeChecker-g6bh0xfv.js} +1 -1
- package/typecheck.proc.js +1 -1
- package/{workflow.command-z0e0fk0z.js → workflow.command-endxfzv5.js} +15 -14
- package/{workspace.command-3q1d6kk4.js → workspace.command-5f2nmmd5.js} +70 -52
- package/templates/workspaceRoot/.cursor/rules/akan-page-routing.mdc.template +0 -43
- package/templates/workspaceRoot/.cursor/rules/akan-sync-conventions.mdc.template +0 -34
- package/templates/workspaceRoot/.cursor/rules/application-test-commands.mdc.template +0 -16
- package/templates/workspaceRoot/.cursor/rules/change-scope.mdc.template +0 -12
- package/templates/workspaceRoot/.cursor/rules/client-server-boundaries.mdc.template +0 -18
- package/templates/workspaceRoot/.cursor/rules/coding-comments.mdc.template +0 -25
- package/templates/workspaceRoot/.cursor/rules/coding-style.mdc.template +0 -44
- package/templates/workspaceRoot/.cursor/rules/domain-module-conventions.mdc.template +0 -17
- package/templates/workspaceRoot/.cursor/rules/format-lint.mdc.template +0 -12
- package/templates/workspaceRoot/.cursor/rules/lint-enforced-rules.mdc.template +0 -18
- package/templates/workspaceRoot/.cursor/rules/module-file-playbook.mdc.template +0 -61
- package/templates/workspaceRoot/.cursor/rules/naming-conventions.mdc.template +0 -15
- package/templates/workspaceRoot/.cursor/rules/react-component-style.mdc.template +0 -21
- package/templates/workspaceRoot/.cursor/rules/repo-overview.mdc.template +0 -17
- package/templates/workspaceRoot/.cursor/rules/scalar-modeling.mdc.template +0 -58
- package/templates/workspaceRoot/.cursor/rules/secrets-and-env.mdc.template +0 -13
- package/templates/workspaceRoot/.cursor/rules/service-signal-conventions.mdc.template +0 -83
- package/templates/workspaceRoot/.cursor/rules/srvkit-adapters-and-guards.mdc.template +0 -50
- package/templates/workspaceRoot/.cursor/rules/ssr-first.mdc.template +0 -59
- package/templates/workspaceRoot/.cursor/rules/typescript-imports.mdc.template +0 -16
- /package/{index-r24hmh0q.js → index-yb2wsc7f.js} +0 -0
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
createTsconfigPackageResolver,
|
|
10
10
|
rewriteBarrelImports,
|
|
11
11
|
transformUseClient
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-qnv0aqmm.js";
|
|
13
13
|
import {
|
|
14
14
|
__require
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-yb2wsc7f.js";
|
|
16
16
|
|
|
17
17
|
// pkgs/@akanjs/devkit/frontendBuild/allRoutesBuilder.ts
|
|
18
18
|
import path4 from "path";
|
|
@@ -810,10 +810,10 @@ import { compile } from "tailwindcss";
|
|
|
810
810
|
|
|
811
811
|
// pkgs/@akanjs/devkit/frontendBuild/cssCandidateCache.ts
|
|
812
812
|
import { stat } from "fs/promises";
|
|
813
|
-
var CANDIDATE_RE = /-?[\w@][\w:/.-]*(?:\[[^\]]+\][\w:/.-]*)*/g;
|
|
813
|
+
var CANDIDATE_RE = /-?(?:[\w@]|\[[^\]\s]+\])[\w:/.-]*(?:\[[^\]\s]+\][\w:/.-]*)*/g;
|
|
814
814
|
|
|
815
815
|
class CssCandidateCache {
|
|
816
|
-
static #version =
|
|
816
|
+
static #version = 3;
|
|
817
817
|
#path;
|
|
818
818
|
#entries = new Map;
|
|
819
819
|
#dirty = false;
|
|
@@ -973,8 +973,12 @@ class CssImportResolver {
|
|
|
973
973
|
const pkg = await Bun.file(pkgPath).json();
|
|
974
974
|
const subpath = id === pkgName ? "." : `.${id.slice(pkgName.length)}`;
|
|
975
975
|
const exportValue = pkg.exports?.[subpath];
|
|
976
|
-
const
|
|
977
|
-
|
|
976
|
+
const exportedEntry = typeof exportValue === "string" ? exportValue : exportValue?.style || exportValue?.import || exportValue?.default;
|
|
977
|
+
if (exportedEntry)
|
|
978
|
+
return await this.#firstExisting(path7.resolve(pkgDir, exportedEntry));
|
|
979
|
+
if (subpath !== ".")
|
|
980
|
+
return await this.#firstExisting(path7.resolve(pkgDir, subpath));
|
|
981
|
+
return await this.#firstExisting(path7.resolve(pkgDir, pkg.exports?.["."]?.style || pkg.style || "index.css"));
|
|
978
982
|
} catch {
|
|
979
983
|
return null;
|
|
980
984
|
}
|
|
@@ -1031,6 +1035,8 @@ class CssCompiler {
|
|
|
1031
1035
|
#fileExistsCache = new Map;
|
|
1032
1036
|
#resolvedFileCache = new Map;
|
|
1033
1037
|
#resolvedSpecifierCache = new Map;
|
|
1038
|
+
#discoveredCssPaths = new Set;
|
|
1039
|
+
importedStylesheetsByBasePath = {};
|
|
1034
1040
|
#fileExists(absPath) {
|
|
1035
1041
|
let cached = this.#fileExistsCache.get(absPath);
|
|
1036
1042
|
if (!cached) {
|
|
@@ -1064,13 +1070,20 @@ class CssCompiler {
|
|
|
1064
1070
|
async getCss({ refresh } = {}) {
|
|
1065
1071
|
if (this.#cssText !== null && !refresh)
|
|
1066
1072
|
return this.#cssText;
|
|
1073
|
+
this.#discoveredCssPaths.clear();
|
|
1074
|
+
this.importedStylesheetsByBasePath = {};
|
|
1067
1075
|
const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh });
|
|
1068
|
-
|
|
1076
|
+
const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
|
|
1077
|
+
this.#cssText = css;
|
|
1078
|
+
this.importedStylesheetsByBasePath = { "": imported };
|
|
1079
|
+
await this.#warnUnreachableStylesheets();
|
|
1069
1080
|
return this.#cssText;
|
|
1070
1081
|
}
|
|
1071
1082
|
async getCssByBasePath({ refresh } = {}) {
|
|
1072
1083
|
if (this.#cssTextByBasePath !== null && !refresh)
|
|
1073
1084
|
return this.#cssTextByBasePath;
|
|
1085
|
+
this.#discoveredCssPaths.clear();
|
|
1086
|
+
this.importedStylesheetsByBasePath = {};
|
|
1074
1087
|
const akanConfig = await this.#app.getConfig({ refresh });
|
|
1075
1088
|
const pageKeys = await this.#app.getPageKeys({ refresh });
|
|
1076
1089
|
const basePaths = [...akanConfig.basePaths];
|
|
@@ -1081,7 +1094,8 @@ class CssCompiler {
|
|
|
1081
1094
|
return ["", ""];
|
|
1082
1095
|
const started = Date.now();
|
|
1083
1096
|
const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh, pageKeys: rootPageKeys });
|
|
1084
|
-
const css = await this
|
|
1097
|
+
const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
|
|
1098
|
+
this.importedStylesheetsByBasePath[""] = imported;
|
|
1085
1099
|
this.#logger.verbose(`css base=root paths=${cssPaths.length} sources=${sourcePaths.length} in ${Date.now() - started}ms`);
|
|
1086
1100
|
return ["", css];
|
|
1087
1101
|
})(),
|
|
@@ -1091,14 +1105,27 @@ class CssCompiler {
|
|
|
1091
1105
|
return [basePath, ""];
|
|
1092
1106
|
const started = Date.now();
|
|
1093
1107
|
const { cssPaths, sourcePaths } = await this.discoverCssAndSources({ refresh, pageKeys: basePathPageKeys });
|
|
1094
|
-
const css = await this
|
|
1108
|
+
const { css, imported } = await this.#compileWithImports(cssPaths, sourcePaths);
|
|
1109
|
+
this.importedStylesheetsByBasePath[basePath] = imported;
|
|
1095
1110
|
this.#logger.verbose(`css base=${basePath} paths=${cssPaths.length} sources=${sourcePaths.length} in ${Date.now() - started}ms`);
|
|
1096
1111
|
return [basePath, css];
|
|
1097
1112
|
})
|
|
1098
1113
|
]);
|
|
1099
1114
|
this.#cssTextByBasePath = Object.fromEntries(cssEntries);
|
|
1115
|
+
await this.#warnUnreachableStylesheets();
|
|
1100
1116
|
return this.#cssTextByBasePath;
|
|
1101
1117
|
}
|
|
1118
|
+
async#warnUnreachableStylesheets() {
|
|
1119
|
+
const pageDir = path8.join(this.#app.cwdPath, "page");
|
|
1120
|
+
const glob = new Bun.Glob("**/*.css");
|
|
1121
|
+
for await (const cssPath of glob.scan({ cwd: pageDir, absolute: true })) {
|
|
1122
|
+
if (cssPath.includes(`${path8.sep}(libs)${path8.sep}`))
|
|
1123
|
+
continue;
|
|
1124
|
+
if (this.#discoveredCssPaths.has(cssPath))
|
|
1125
|
+
continue;
|
|
1126
|
+
this.#logger.warn(`css ${path8.relative(this.#app.cwdPath, cssPath)} is imported by no route and never compiled`);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1102
1129
|
async discoverCss({ refresh } = {}) {
|
|
1103
1130
|
const { cssPaths } = await this.discoverCssAndSources({ refresh });
|
|
1104
1131
|
return cssPaths;
|
|
@@ -1158,21 +1185,47 @@ class CssCompiler {
|
|
|
1158
1185
|
queue.push(resolved);
|
|
1159
1186
|
}
|
|
1160
1187
|
}
|
|
1161
|
-
|
|
1188
|
+
const tokenPaths = await this.#libTokenStylesheets(sourceFiles);
|
|
1189
|
+
const cssPaths = [...new Set([...tokenPaths, ...cssFiles])];
|
|
1190
|
+
for (const cssPath of cssPaths)
|
|
1191
|
+
this.#discoveredCssPaths.add(cssPath);
|
|
1192
|
+
return { cssPaths, sourcePaths: [...sourceFiles] };
|
|
1193
|
+
}
|
|
1194
|
+
async#libTokenStylesheets(sourceFiles) {
|
|
1195
|
+
const libsRoot = path8.join(this.#app.workspace.workspaceRoot, "libs");
|
|
1196
|
+
const libNames = new Set;
|
|
1197
|
+
for (const filePath of sourceFiles) {
|
|
1198
|
+
const relPath = path8.relative(libsRoot, filePath);
|
|
1199
|
+
if (relPath.startsWith("..") || path8.isAbsolute(relPath))
|
|
1200
|
+
continue;
|
|
1201
|
+
const [libName] = relPath.split(path8.sep);
|
|
1202
|
+
if (libName)
|
|
1203
|
+
libNames.add(libName);
|
|
1204
|
+
}
|
|
1205
|
+
const tokenPaths = await Promise.all([...libNames].sort().map(async (libName) => {
|
|
1206
|
+
const tokensPath = path8.join(libsRoot, libName, "ui/tokens.css");
|
|
1207
|
+
return await this.#fileExists(tokensPath) ? tokensPath : null;
|
|
1208
|
+
}));
|
|
1209
|
+
return tokenPaths.filter((tokensPath) => !!tokensPath);
|
|
1162
1210
|
}
|
|
1163
1211
|
async compileCss(cssPaths, sourcePaths) {
|
|
1212
|
+
const { css } = await this.#compileWithImports(cssPaths, sourcePaths);
|
|
1213
|
+
return css;
|
|
1214
|
+
}
|
|
1215
|
+
async#compileWithImports(cssPaths, sourcePaths) {
|
|
1164
1216
|
if (cssPaths.length === 0)
|
|
1165
|
-
return "";
|
|
1217
|
+
return { css: "", imported: [] };
|
|
1166
1218
|
const compileStarted = Date.now();
|
|
1167
1219
|
const compilers = await Promise.all(cssPaths.map(async (cssPath) => {
|
|
1168
1220
|
const css = await Bun.file(cssPath).text();
|
|
1169
1221
|
const base = path8.dirname(cssPath);
|
|
1222
|
+
const imported2 = new Map;
|
|
1170
1223
|
const compiler = await compile(css, {
|
|
1171
1224
|
base,
|
|
1172
|
-
loadStylesheet: (id, fromBase) => this.#loadStylesheet(id, fromBase),
|
|
1225
|
+
loadStylesheet: (id, fromBase) => this.#loadStylesheet(id, fromBase, imported2),
|
|
1173
1226
|
loadModule: (id, fromBase) => this.#loadModule(id, fromBase)
|
|
1174
1227
|
});
|
|
1175
|
-
return { cssPath, compiler };
|
|
1228
|
+
return { cssPath, compiler, imported: imported2 };
|
|
1176
1229
|
}));
|
|
1177
1230
|
const sourceDirs = new Set;
|
|
1178
1231
|
for (const entry of compilers) {
|
|
@@ -1185,23 +1238,39 @@ class CssCompiler {
|
|
|
1185
1238
|
const candidates = await this.#scanCandidates(sourcePaths, [...sourceDirs]);
|
|
1186
1239
|
this.#logger.verbose(`css candidates scanned count=${candidates.length} sources=${sourcePaths.length} dirs=${sourceDirs.size} in ${Date.now() - scanStarted}ms`);
|
|
1187
1240
|
const parts = [];
|
|
1241
|
+
const imported = [];
|
|
1188
1242
|
for (const entry of compilers) {
|
|
1189
1243
|
if (!entry)
|
|
1190
1244
|
continue;
|
|
1191
|
-
|
|
1245
|
+
const part = entry.compiler.build(candidates);
|
|
1246
|
+
parts.push(part);
|
|
1247
|
+
for (const [cssPath, content] of entry.imported) {
|
|
1248
|
+
const declaredNames = declaredCustomProperties(content);
|
|
1249
|
+
imported.push({ cssPath, declaredNames });
|
|
1250
|
+
if (declaredNames.length === 0 || declaredNames.some((name) => part.includes(`${name}:`)))
|
|
1251
|
+
continue;
|
|
1252
|
+
this.#logger.warn(`css @import ${cssPath} was loaded by ${entry.cssPath} but none of its ${declaredNames.length} declaration(s) reached the compiled CSS`);
|
|
1253
|
+
}
|
|
1192
1254
|
}
|
|
1193
1255
|
this.#logger.verbose(`css compiled paths=${cssPaths.length} candidates=${candidates.length} in ${Date.now() - compileStarted}ms`);
|
|
1194
|
-
return parts.join(`
|
|
1195
|
-
`);
|
|
1256
|
+
return { css: parts.join(`
|
|
1257
|
+
`), imported };
|
|
1196
1258
|
}
|
|
1197
|
-
async#loadStylesheet(id, fromBase) {
|
|
1259
|
+
async#loadStylesheet(id, fromBase, imported) {
|
|
1198
1260
|
const p = await this.#resolveCssImport(id, fromBase);
|
|
1261
|
+
this.#discoveredCssPaths.add(p);
|
|
1199
1262
|
const content = await Bun.file(p).text();
|
|
1263
|
+
imported?.set(p, content);
|
|
1264
|
+
this.#logger.verbose(`css import "${id}" from ${fromBase} -> ${p} (${content.length} bytes)`);
|
|
1200
1265
|
return { path: p, base: path8.dirname(p), content };
|
|
1201
1266
|
}
|
|
1202
1267
|
async#resolveCssImport(id, fromBase) {
|
|
1203
|
-
if (id.startsWith(".") || id.startsWith("/"))
|
|
1204
|
-
|
|
1268
|
+
if (id.startsWith(".") || id.startsWith("/")) {
|
|
1269
|
+
const filePath = path8.resolve(fromBase, id);
|
|
1270
|
+
if (await this.#fileExists(filePath))
|
|
1271
|
+
return filePath;
|
|
1272
|
+
throw new Error(`[css] failed to resolve stylesheet import "${id}" from ${fromBase} (no file at ${filePath})`);
|
|
1273
|
+
}
|
|
1205
1274
|
const resolver = await this.#getCssImportResolver();
|
|
1206
1275
|
const resolved = await resolver.resolve(id, fromBase);
|
|
1207
1276
|
if (resolved)
|
|
@@ -1286,6 +1355,10 @@ function isSourceFile(filePath) {
|
|
|
1286
1355
|
function isIgnoredNodeModuleSource(filePath) {
|
|
1287
1356
|
return NODE_MODULES_RE.test(filePath) && !AKANJS_NODE_MODULE_RE.test(filePath);
|
|
1288
1357
|
}
|
|
1358
|
+
function declaredCustomProperties(css) {
|
|
1359
|
+
const withoutThemeBlocks = css.replace(/@theme[^{]*\{[^}]*\}/g, "");
|
|
1360
|
+
return [...new Set([...withoutThemeBlocks.matchAll(/(?:^|[\s;{])(--[\w-]+)\s*:/g)].map(([, name]) => name))].filter((name) => !!name);
|
|
1361
|
+
}
|
|
1289
1362
|
function getPageKeyBasePath(pageKey, basePaths) {
|
|
1290
1363
|
const normalized = pageKey.split(path8.sep).join("/").replace(/^\.\//, "");
|
|
1291
1364
|
const segments = normalized.split("/");
|
|
@@ -1763,7 +1836,6 @@ var DEFAULT_EXCLUDE_PREFIX = ["@akanjs/cli/", "@akanjs/devkit/"];
|
|
|
1763
1836
|
var OPTIONAL_BACKEND_EXTERNAL_EXACT = new Set([
|
|
1764
1837
|
"@libsql/client",
|
|
1765
1838
|
"bullmq",
|
|
1766
|
-
"croner",
|
|
1767
1839
|
"ioredis",
|
|
1768
1840
|
"postgres",
|
|
1769
1841
|
"protobufjs"
|
|
@@ -2180,7 +2252,7 @@ class SsrBaseArtifactBuilder {
|
|
|
2180
2252
|
const ssrBundle = await new ClientEntriesBundler({
|
|
2181
2253
|
app: this.#app,
|
|
2182
2254
|
entries: [rscSegmentOutletEntry],
|
|
2183
|
-
...RouteClientBuilder.
|
|
2255
|
+
...RouteClientBuilder.resolveSsrClientBundleOptions(this.#command),
|
|
2184
2256
|
outputSubdir: "client-ssr",
|
|
2185
2257
|
command: this.#command
|
|
2186
2258
|
}).bundle();
|
|
@@ -2232,13 +2304,13 @@ class SsrBaseArtifactBuilder {
|
|
|
2232
2304
|
`);
|
|
2233
2305
|
if (!cssText)
|
|
2234
2306
|
return [];
|
|
2235
|
-
return [this.#writeCssAsset(basePath, cssText)];
|
|
2307
|
+
return [this.#writeCssAsset(basePath, cssText, cssCompiler.importedStylesheetsByBasePath[basePath] ?? [])];
|
|
2236
2308
|
})));
|
|
2237
2309
|
if (optimizedFonts.files.length > 0)
|
|
2238
2310
|
this.#app.verbose(`[base-artifact] optimized ${optimizedFonts.files.length} font files`);
|
|
2239
2311
|
return { cssCompiler, optimizedFonts, cssAssets };
|
|
2240
2312
|
}
|
|
2241
|
-
async#writeCssAsset(basePath, cssText) {
|
|
2313
|
+
async#writeCssAsset(basePath, cssText, imported) {
|
|
2242
2314
|
const cssAssetName = basePath || "root";
|
|
2243
2315
|
const preparedCssText = await prepareCssAsset(this.#command, basePath, cssText);
|
|
2244
2316
|
const cssHash = Bun.hash(`${basePath}
|
|
@@ -2248,9 +2320,17 @@ ${preparedCssText}`).toString(36);
|
|
|
2248
2320
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
2249
2321
|
];
|
|
2250
2322
|
await Bun.write(path13.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
2323
|
+
SsrBaseArtifactBuilder.#warnDroppedImports(this.#app, cssRelPath, preparedCssText, imported);
|
|
2251
2324
|
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath} -> ${cssRelPath}`);
|
|
2252
2325
|
return [basePath, { cssUrl, cssRelPath }];
|
|
2253
2326
|
}
|
|
2327
|
+
static #warnDroppedImports(app, cssRelPath, css, imported) {
|
|
2328
|
+
for (const { cssPath, declaredNames } of imported) {
|
|
2329
|
+
if (declaredNames.length === 0 || declaredNames.some((name) => css.includes(`${name}:`)))
|
|
2330
|
+
continue;
|
|
2331
|
+
app.logger.warn(`[base-artifact] @import ${cssPath} declares ${declaredNames.length} custom propert${declaredNames.length === 1 ? "y" : "ies"} and none of them are in ${cssRelPath}`);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2254
2334
|
}
|
|
2255
2335
|
// pkgs/@akanjs/devkit/frontendBuild/styleGuard.ts
|
|
2256
2336
|
var PREFIX = "(?:bg|text|border(?:-[tblrxy])?(?:-[se])?|ring(?:-offset)?|fill|stroke|shadow|from|to|via|divide|outline|decoration|placeholder|caret|accent)";
|
|
@@ -2258,210 +2338,8 @@ var PALETTE = "(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|gre
|
|
|
2258
2338
|
var LEAD = "(^|[\\s\"'`{(\\[:!])";
|
|
2259
2339
|
var TAIL = "(?=[\\s\"'`})\\]:/!,]|$)";
|
|
2260
2340
|
var RAW_PALETTE_RE = new RegExp(`${LEAD}((?:${PREFIX})-)${PALETTE}-\\d{2,3}${TAIL}`, "g");
|
|
2261
|
-
var ARBITRARY_COLOR_RE = /\[(#[0-9a-fA-F]{3,8}|(?:rgb|rgba|hsl|hsla|oklch|oklab|lab|lch|hwb|color)\([^\]]*\))\]/g;
|
|
2262
2341
|
var INTERPOLATED_ARBITRARY_RE = new RegExp(`${LEAD}[a-z][a-z0-9-]*-\\[[^\\]\`]*\\$\\{`, "g");
|
|
2263
|
-
var STYLE_OBJECT_RE = /style=\{\{([\s\S]*?)\}\}/g;
|
|
2264
|
-
var STYLE_TAG_RE = /<style[^>]*>([\s\S]*?)<\/style>/g;
|
|
2265
|
-
var INLINE_COLOR_LITERAL_RE = /#[0-9a-fA-F]{3,8}\b|(?:rgb|rgba|hsl|hsla|oklch|oklab|lab|lch|hwb)\(/g;
|
|
2266
2342
|
var DAISYUI_LEGACY_RE = new RegExp(`${LEAD}(?:` + "btn-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|link|outline|square|circle|wide|block|xs|sm|md|lg)|" + "badge-(?:primary|secondary|accent|neutral|info|success|warning|error|ghost|outline)|" + "alert-(?:info|success|warning|error)|" + "input-(?:bordered|primary|secondary|accent|ghost|error)|" + "select-(?:bordered|primary|ghost)|textarea-(?:bordered|primary|ghost)|" + "checkbox-(?:primary|secondary|accent)|toggle-(?:primary|secondary|accent)|" + "loading-(?:spinner|dots|ring|ball|bars|infinity)|" + "card-(?:body|title|actions)|modal-(?:box|action|backdrop)|" + "collapse-(?:title|content|arrow|plus)|dropdown-(?:content|end|start|hover)|" + "stat-(?:title|value|desc)|tabs-(?:boxed|lifted|bordered)|tab-active|" + "menu-(?:title|dropdown)|steps-(?:horizontal|vertical)|join-item|" + "mockup-(?:code|phone|browser|window)|drawer-(?:side|content|toggle)" + `)${TAIL}`, "g");
|
|
2267
|
-
var
|
|
2268
|
-
|
|
2269
|
-
"arbitrary-color",
|
|
2270
|
-
"inline-color",
|
|
2271
|
-
"daisyui-legacy",
|
|
2272
|
-
"interpolated-arbitrary"
|
|
2273
|
-
];
|
|
2274
|
-
|
|
2275
|
-
class StyleGuard {
|
|
2276
|
-
run(files) {
|
|
2277
|
-
const out = [];
|
|
2278
|
-
for (const file of files) {
|
|
2279
|
-
const directives = this.#parseDirectives(file.content);
|
|
2280
|
-
const scan = this.#stripComments(file.content);
|
|
2281
|
-
const local = [];
|
|
2282
|
-
this.#scanClassLiterals(file, scan, local);
|
|
2283
|
-
this.#scanInlineColors(file, scan, local);
|
|
2284
|
-
for (const v of local)
|
|
2285
|
-
if (!this.#isSuppressed(v, directives))
|
|
2286
|
-
out.push(v);
|
|
2287
|
-
}
|
|
2288
|
-
return out;
|
|
2289
|
-
}
|
|
2290
|
-
#stripComments(src) {
|
|
2291
|
-
const out = src.split("");
|
|
2292
|
-
const blank = (i2) => {
|
|
2293
|
-
if (src[i2] !== `
|
|
2294
|
-
`)
|
|
2295
|
-
out[i2] = " ";
|
|
2296
|
-
};
|
|
2297
|
-
let state = "code";
|
|
2298
|
-
let i = 0;
|
|
2299
|
-
while (i < src.length) {
|
|
2300
|
-
const c = src[i];
|
|
2301
|
-
const d = src[i + 1];
|
|
2302
|
-
if (state === "code") {
|
|
2303
|
-
if (c === "/" && d === "/") {
|
|
2304
|
-
blank(i);
|
|
2305
|
-
blank(i + 1);
|
|
2306
|
-
state = "line";
|
|
2307
|
-
i += 2;
|
|
2308
|
-
} else if (c === "/" && d === "*") {
|
|
2309
|
-
blank(i);
|
|
2310
|
-
blank(i + 1);
|
|
2311
|
-
state = "block";
|
|
2312
|
-
i += 2;
|
|
2313
|
-
} else {
|
|
2314
|
-
if (c === "'")
|
|
2315
|
-
state = "squote";
|
|
2316
|
-
else if (c === '"')
|
|
2317
|
-
state = "dquote";
|
|
2318
|
-
else if (c === "`")
|
|
2319
|
-
state = "template";
|
|
2320
|
-
i++;
|
|
2321
|
-
}
|
|
2322
|
-
} else if (state === "line") {
|
|
2323
|
-
if (c === `
|
|
2324
|
-
`)
|
|
2325
|
-
state = "code";
|
|
2326
|
-
else
|
|
2327
|
-
blank(i);
|
|
2328
|
-
i++;
|
|
2329
|
-
} else if (state === "block") {
|
|
2330
|
-
if (c === "*" && d === "/") {
|
|
2331
|
-
blank(i);
|
|
2332
|
-
blank(i + 1);
|
|
2333
|
-
state = "code";
|
|
2334
|
-
i += 2;
|
|
2335
|
-
} else {
|
|
2336
|
-
blank(i);
|
|
2337
|
-
i++;
|
|
2338
|
-
}
|
|
2339
|
-
} else {
|
|
2340
|
-
const close = state === "squote" ? "'" : state === "dquote" ? '"' : "`";
|
|
2341
|
-
if (c === "\\")
|
|
2342
|
-
i += 2;
|
|
2343
|
-
else {
|
|
2344
|
-
if (c === close)
|
|
2345
|
-
state = "code";
|
|
2346
|
-
i++;
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
return out.join("");
|
|
2351
|
-
}
|
|
2352
|
-
#parseDirectives(content) {
|
|
2353
|
-
const directives = { file: null, nextLine: new Map };
|
|
2354
|
-
const lines = content.split(`
|
|
2355
|
-
`);
|
|
2356
|
-
for (let i = 0;i < lines.length; i++) {
|
|
2357
|
-
const line = lines[i];
|
|
2358
|
-
const nextLineMatch = line.match(/styleguard-disable-next-line\b(.*)$/);
|
|
2359
|
-
if (nextLineMatch) {
|
|
2360
|
-
directives.nextLine.set(i + 2, this.#extractRules(nextLineMatch[1]));
|
|
2361
|
-
continue;
|
|
2362
|
-
}
|
|
2363
|
-
const fileMatch = line.match(/styleguard-disable\b(.*)$/);
|
|
2364
|
-
if (fileMatch)
|
|
2365
|
-
directives.file = this.#mergeFileScope(directives.file, this.#extractRules(fileMatch[1]));
|
|
2366
|
-
}
|
|
2367
|
-
return directives;
|
|
2368
|
-
}
|
|
2369
|
-
#extractRules(tail) {
|
|
2370
|
-
const found = ALL_RULES.filter((rule) => tail.includes(rule));
|
|
2371
|
-
return found.length === 0 ? "all" : new Set(found);
|
|
2372
|
-
}
|
|
2373
|
-
#mergeFileScope(prev, next) {
|
|
2374
|
-
if (prev === "all" || next === "all")
|
|
2375
|
-
return "all";
|
|
2376
|
-
return new Set([...prev ?? [], ...next]);
|
|
2377
|
-
}
|
|
2378
|
-
#isSuppressed(v, directives) {
|
|
2379
|
-
if (directives.file === "all" || directives.file?.has(v.rule))
|
|
2380
|
-
return true;
|
|
2381
|
-
const nextLine = directives.nextLine.get(v.line);
|
|
2382
|
-
return nextLine === "all" || (nextLine?.has(v.rule) ?? false);
|
|
2383
|
-
}
|
|
2384
|
-
#scanClassLiterals(file, scan, out) {
|
|
2385
|
-
for (const m of scan.matchAll(RAW_PALETTE_RE)) {
|
|
2386
|
-
out.push(this.#violation(file, m.index ?? 0, {
|
|
2387
|
-
rule: "raw-palette",
|
|
2388
|
-
severity: "error",
|
|
2389
|
-
suggestion: "\uC2DC\uB9E8\uD2F1 \uD1A0\uD070\uC73C\uB85C \uAD50\uCCB4\uD558\uC138\uC694 \u2014 \uC608: text-gray-500\u2192text-muted-foreground, bg-red-500\u2192bg-destructive, bg-blue-500\u2192bg-info. \uBE0C\uB79C\uB4DC \uC0C9\uC740 page/styles.css \uD1A0\uD070\uC5D0\uC11C \uC870\uC815\uD569\uB2C8\uB2E4."
|
|
2390
|
-
}));
|
|
2391
|
-
}
|
|
2392
|
-
for (const m of scan.matchAll(ARBITRARY_COLOR_RE)) {
|
|
2393
|
-
out.push(this.#violation(file, m.index ?? 0, {
|
|
2394
|
-
rule: "arbitrary-color",
|
|
2395
|
-
severity: "error",
|
|
2396
|
-
suggestion: "\uC784\uC758 \uC0C9 \uB9AC\uD130\uB7F4 \uB300\uC2E0 \uD1A0\uD070\uC744 \uC4F0\uC138\uC694 \u2014 bg-[#3b82f6]\u2192bg-info, text-[rgb(...)]\u2192\uC2DC\uB9E8\uD2F1 \uD1A0\uD070. \uAF2D \uD544\uC694\uD558\uBA74 \uC2A4\uCF54\uD504 \uD1A0\uD070(.campaign-x { --primary: \u2026 })\uC744 \uC815\uC758\uD558\uC138\uC694."
|
|
2397
|
-
}));
|
|
2398
|
-
}
|
|
2399
|
-
for (const m of scan.matchAll(DAISYUI_LEGACY_RE)) {
|
|
2400
|
-
out.push(this.#violation(file, m.index ?? 0, {
|
|
2401
|
-
rule: "daisyui-legacy",
|
|
2402
|
-
severity: "error",
|
|
2403
|
-
suggestion: "daisyUI \uD074\uB798\uC2A4\uB294 \uC81C\uAC70\uB410\uC2B5\uB2C8\uB2E4. akanjs/ui \uD504\uB9AC\uBBF8\uD2F0\uBE0C(Button/Badge \uB4F1)\uB098 buttonRecipe()/badgeRecipe() + \uC2DC\uB9E8\uD2F1 \uD1A0\uD070\uC73C\uB85C \uAD50\uCCB4\uD558\uC138\uC694."
|
|
2404
|
-
}));
|
|
2405
|
-
}
|
|
2406
|
-
for (const m of scan.matchAll(INTERPOLATED_ARBITRARY_RE)) {
|
|
2407
|
-
out.push(this.#violation(file, m.index ?? 0, {
|
|
2408
|
-
rule: "interpolated-arbitrary",
|
|
2409
|
-
severity: "error",
|
|
2410
|
-
suggestion: "\uB7F0\uD0C0\uC784 \uAC12\uC73C\uB85C \uC784\uC758\uAC12 \uD074\uB798\uC2A4\uB97C \uC870\uB9BD\uD558\uBA74 CSS \uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC2A4\uCE90\uB108\uB294 \uC18C\uC2A4 \uD14D\uC2A4\uD2B8\uB97C \uC77D\uC2B5\uB2C8\uB2E4). \uD06C\uAE30/\uC704\uCE58\uB294 style prop \uC73C\uB85C \uB118\uAE30\uC138\uC694 \u2014 style={{ minHeight }}. \uAC12\uC774 enum \uC774\uBA74 \uB9AC\uD130\uB7F4 \uD074\uB798\uC2A4 \uB9F5\uC73C\uB85C \uB450\uC138\uC694."
|
|
2411
|
-
}));
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
#scanInlineColors(file, scan, out) {
|
|
2415
|
-
const push = (index) => out.push(this.#violation(file, index, {
|
|
2416
|
-
rule: "inline-color",
|
|
2417
|
-
severity: "error",
|
|
2418
|
-
suggestion: "\uC778\uB77C\uC778 \uC0C9 \uB9AC\uD130\uB7F4 \uB300\uC2E0 CSS \uBCC0\uC218/\uD1A0\uD070\uC744 \uCC38\uC870\uD558\uC138\uC694 \u2014 style={{ color: 'var(--primary)' }} \uB610\uB294 \uC2DC\uB9E8\uD2F1 \uD074\uB798\uC2A4(text-primary). \uD558\uB4DC\uCF54\uB529 hex/rgb \uB294 \uD14C\uB9C8 \uC804\uD658\uC744 \uAE68\uB728\uB9BD\uB2C8\uB2E4."
|
|
2419
|
-
}));
|
|
2420
|
-
for (const region of [STYLE_OBJECT_RE, STYLE_TAG_RE]) {
|
|
2421
|
-
for (const m of scan.matchAll(region)) {
|
|
2422
|
-
const inner = m[1] ?? "";
|
|
2423
|
-
const innerStart = (m.index ?? 0) + m[0].indexOf(inner);
|
|
2424
|
-
for (const lit of inner.matchAll(INLINE_COLOR_LITERAL_RE)) {
|
|
2425
|
-
push(innerStart + (lit.index ?? 0));
|
|
2426
|
-
}
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
}
|
|
2430
|
-
#violation(file, index, base) {
|
|
2431
|
-
const before = file.content.slice(0, index);
|
|
2432
|
-
const line = before.length === 0 ? 1 : before.split(`
|
|
2433
|
-
`).length;
|
|
2434
|
-
const lineStart = before.lastIndexOf(`
|
|
2435
|
-
`) + 1;
|
|
2436
|
-
const lineEnd = file.content.indexOf(`
|
|
2437
|
-
`, index);
|
|
2438
|
-
const snippet = file.content.slice(lineStart, lineEnd === -1 ? undefined : lineEnd).trim();
|
|
2439
|
-
return { ...base, path: file.path, line, snippet };
|
|
2440
|
-
}
|
|
2441
|
-
static countNamedComponentClasses(css) {
|
|
2442
|
-
const names = new Set;
|
|
2443
|
-
const layerRe = /@layer\s+components\s*\{/g;
|
|
2444
|
-
for (const layer of css.matchAll(layerRe)) {
|
|
2445
|
-
const bodyStart = (layer.index ?? 0) + layer[0].length;
|
|
2446
|
-
const body = StyleGuard.#extractBalanced(css, bodyStart);
|
|
2447
|
-
for (const sel of body.matchAll(/(^|[\s}])\.(-?[a-zA-Z_][\w-]*)/g))
|
|
2448
|
-
names.add(sel[2]);
|
|
2449
|
-
}
|
|
2450
|
-
return { count: names.size, names: [...names].sort() };
|
|
2451
|
-
}
|
|
2452
|
-
static #extractBalanced(css, start) {
|
|
2453
|
-
let depth = 1;
|
|
2454
|
-
for (let i = start;i < css.length; i++) {
|
|
2455
|
-
const ch = css[i];
|
|
2456
|
-
if (ch === "{")
|
|
2457
|
-
depth++;
|
|
2458
|
-
else if (ch === "}") {
|
|
2459
|
-
depth--;
|
|
2460
|
-
if (depth === 0)
|
|
2461
|
-
return css.slice(start, i);
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
return css.slice(start);
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2343
|
+
var DAISYUI_TOKEN = "(?:base-(?:100|200|300|content)|(?:primary|secondary|accent|neutral|info|success|warning|error)-content|error)";
|
|
2344
|
+
var DAISYUI_TOKEN_RE = new RegExp(`${LEAD}(?:${PREFIX})-${DAISYUI_TOKEN}${TAIL}`, "g");
|
|
2467
2345
|
export { AllRoutesBuilder, CsrArtifactBuilder, CssCompiler, FontOptimizer, PagesBundleBuilder, precompressArtifacts, SsrBaseArtifactBuilder };
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
AkanContextAnalyzer
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-24h5bqpj.js";
|
|
5
5
|
import {
|
|
6
6
|
Prompter
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-j37qq1f2.js";
|
|
8
8
|
import {
|
|
9
9
|
runner,
|
|
10
10
|
script
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-8rr621r2.js";
|
|
12
12
|
import {
|
|
13
13
|
AGENT_BLOCK_END,
|
|
14
14
|
AGENT_BLOCK_START,
|
|
15
15
|
AppExecutor,
|
|
16
|
+
CLAUDE_COMMENT_RULE,
|
|
16
17
|
LibExecutor,
|
|
18
|
+
readDevkitVersion,
|
|
17
19
|
renderRecipeEntries,
|
|
20
|
+
stampBlockVersion,
|
|
18
21
|
upsertAgentBlock
|
|
19
|
-
} from "./index-
|
|
22
|
+
} from "./index-90zyjrby.js";
|
|
20
23
|
import {
|
|
21
24
|
collectRecipeSources,
|
|
22
25
|
scanRecipes
|
|
@@ -103,19 +106,33 @@ ${scopeIndexPointer}
|
|
|
103
106
|
|
|
104
107
|
`;
|
|
105
108
|
};
|
|
109
|
+
var renderGuides = async (context) => {
|
|
110
|
+
const conventions = (await Prompter.getInstruction("conventions")).trim();
|
|
111
|
+
if (context.pkgs.some((pkg) => pkg.name === "akanjs"))
|
|
112
|
+
return conventions;
|
|
113
|
+
const onboarding = (await Prompter.getInstruction("workspaceOnboarding")).trim();
|
|
114
|
+
const appName = context.apps[0]?.name ?? "app";
|
|
115
|
+
return `${conventions}
|
|
116
|
+
|
|
117
|
+
${onboarding.replaceAll("<%= appName %>", appName)}`;
|
|
118
|
+
};
|
|
106
119
|
var renderManagedBlock = async (workspace) => {
|
|
107
120
|
const context = await AkanContextAnalyzer.analyze(workspace);
|
|
108
121
|
const frameworkGuide = await Prompter.getInstruction("framework");
|
|
109
122
|
const appNames = context.apps.map((app) => app.name);
|
|
110
123
|
const sampleCleanup = await renderSampleCleanup(workspace, appNames);
|
|
111
124
|
const recipeIndex = await renderRecipeIndex(workspace);
|
|
112
|
-
|
|
125
|
+
const guides = await renderGuides(context);
|
|
126
|
+
const version = await readDevkitVersion();
|
|
127
|
+
const block = `## Workspace
|
|
113
128
|
|
|
114
129
|
- Repo: ${context.repoName}
|
|
115
130
|
- Apps: ${context.apps.map((app) => app.name).join(", ") || "none"}
|
|
116
131
|
- Libraries: ${context.libs.map((lib) => lib.name).join(", ") || "none"}
|
|
117
132
|
- Packages: ${context.pkgs.map((pkg) => pkg.name).join(", ") || "none"}
|
|
118
133
|
|
|
134
|
+
${guides}
|
|
135
|
+
|
|
119
136
|
${sampleCleanup}## Akan Module Abstracts
|
|
120
137
|
|
|
121
138
|
- Before changing a domain, service, or scalar module, read its \`*.abstract.md\` file first.
|
|
@@ -148,7 +165,19 @@ ${context.validationCommands.map((command) => `- \`${command}\``).join(`
|
|
|
148
165
|
|
|
149
166
|
## Framework Guide
|
|
150
167
|
|
|
151
|
-
${frameworkGuide.trim()}
|
|
168
|
+
${frameworkGuide.trim()}
|
|
169
|
+
|
|
170
|
+
## Before You Finish
|
|
171
|
+
|
|
172
|
+
1. \`bun run akan lint <appName>\` \u2014 Tailwind class order, \`Err\`, \`console\`, \`#private\` scope, unused imports.
|
|
173
|
+
2. \`bun run akan typecheck <appName>\` \u2014 server/client boundary violations.
|
|
174
|
+
3. \`bun run akan sync <appName>\` if you added, renamed, or deleted any file.
|
|
175
|
+
4. Did you write or change a \`.tsx\` file? \`bun run akan quality ssr\` \u2014 did the server share hold, and did you add
|
|
176
|
+
a \`"use client"\` you cannot justify?
|
|
177
|
+
5. Re-read the file you wrote against its section above.
|
|
178
|
+
6. Did you add a comment? Delete it unless it documents an external constraint or a security decision.
|
|
179
|
+
7. Did behavior or an invariant change? Update the module's \`*.abstract.md\`.`;
|
|
180
|
+
return version ? stampBlockVersion(block, version) : block;
|
|
152
181
|
};
|
|
153
182
|
var renderAgentsMd = async (workspace, existing) => {
|
|
154
183
|
const block = await renderManagedBlock(workspace);
|
|
@@ -171,6 +200,8 @@ var renderClaudeMd = async (workspace) => {
|
|
|
171
200
|
return `# ${context.repoName} \u2014 Claude Code Guide
|
|
172
201
|
|
|
173
202
|
@AGENTS.md
|
|
203
|
+
|
|
204
|
+
${CLAUDE_COMMENT_RULE}
|
|
174
205
|
`;
|
|
175
206
|
};
|
|
176
207
|
var renderCursorRule = () => `---
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import {
|
|
3
|
-
PageScript
|
|
4
|
-
} from "./index-hrwzz2wf.js";
|
|
5
2
|
import {
|
|
6
3
|
pluralizeName
|
|
7
4
|
} from "./index-ss469dec.js";
|
|
5
|
+
import {
|
|
6
|
+
PageScript
|
|
7
|
+
} from "./index-4z05haak.js";
|
|
8
8
|
import {
|
|
9
9
|
AiSession
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-sh01r3pm.js";
|
|
11
11
|
import {
|
|
12
12
|
bilingualDescriptionForField,
|
|
13
13
|
bilingualLabelForField,
|
|
@@ -15,17 +15,17 @@ import {
|
|
|
15
15
|
generatedFilesForSync,
|
|
16
16
|
moduleSourcePaths,
|
|
17
17
|
sourceFile
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-5em412h5.js";
|
|
19
19
|
import {
|
|
20
20
|
Prompter
|
|
21
|
-
} from "./index-
|
|
21
|
+
} from "./index-j37qq1f2.js";
|
|
22
22
|
import {
|
|
23
23
|
runner,
|
|
24
24
|
script
|
|
25
|
-
} from "./index-
|
|
25
|
+
} from "./index-8rr621r2.js";
|
|
26
26
|
import {
|
|
27
27
|
ModuleExecutor
|
|
28
|
-
} from "./index-
|
|
28
|
+
} from "./index-90zyjrby.js";
|
|
29
29
|
import {
|
|
30
30
|
FileSys
|
|
31
31
|
} from "./index-67546d0j.js";
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
CloudRunner
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-bwt525ne.js";
|
|
5
5
|
import {
|
|
6
6
|
PackageScript
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-7zd96bng.js";
|
|
8
8
|
import {
|
|
9
9
|
AiSession,
|
|
10
10
|
CloudApi,
|
|
11
11
|
GlobalConfig
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-sh01r3pm.js";
|
|
13
13
|
import {
|
|
14
14
|
ApplicationScript
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-7etegaht.js";
|
|
16
16
|
import {
|
|
17
17
|
script
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-8rr621r2.js";
|
|
19
19
|
import {
|
|
20
20
|
PkgExecutor
|
|
21
|
-
} from "./index-
|
|
21
|
+
} from "./index-90zyjrby.js";
|
|
22
22
|
|
|
23
23
|
// pkgs/@akanjs/cli/cloud/cloud.script.ts
|
|
24
24
|
import { Logger } from "akanjs/common";
|