@akanjs/devkit 3.0.0-alpha.0 → 3.0.0-alpha.10
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/agentsIndex.ts +26 -0
- package/akanContext.ts +43 -31
- package/applicationBuildRunner.ts +1 -1
- package/biome.base.json +301 -0
- package/biomeBase.ts +9 -0
- package/capacitorApp.test.ts +8 -0
- package/capacitorApp.ts +112 -18
- package/executors.test.ts +3 -1
- package/executors.ts +2 -1
- package/frontendBuild/allRoutesBuilder.ts +27 -8
- package/frontendBuild/cssCandidateCache.test.ts +38 -0
- package/frontendBuild/cssCandidateCache.ts +15 -3
- package/frontendBuild/precompressArtifacts.ts +35 -7
- package/frontendBuild/routeClientBuilder.ts +14 -2
- package/integration/devResourceProbe.ts +7 -2
- package/integration/ssrMemoryProbe.ts +542 -0
- package/lint/no-bang-comment-in-client.grit +20 -0
- package/lint/no-import-client-in-server.grit +48 -0
- package/lint/no-import-server-in-client.grit +45 -0
- package/lint/no-return-in-store-action.grit +35 -0
- package/package.json +3 -2
- package/qualityScanner.test.ts +154 -1
- package/qualityScanner.ts +46 -46
- package/repoIdentity.ts +42 -0
- package/routeSourceValidator.test.ts +41 -0
- package/routeSourceValidator.ts +2 -44
- package/scanInfo.ts +2 -43
- package/spinner.test.ts +81 -0
- package/spinner.ts +22 -2
- package/ssrScanner.ts +409 -0
- package/workspaceLayout.test.ts +26 -0
- package/workspaceLayout.ts +60 -0
package/agentsIndex.ts
CHANGED
|
@@ -19,6 +19,32 @@ const loadRecipeScanner = () => (recipeScannerLoad ??= import("./recipeScanner")
|
|
|
19
19
|
export const AGENT_BLOCK_START = "<!-- akan:agent:start -->";
|
|
20
20
|
export const AGENT_BLOCK_END = "<!-- akan:agent:end -->";
|
|
21
21
|
|
|
22
|
+
const AGENT_VERSION_PREFIX = "<!-- akan:agent:version ";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The generating release, stamped into the workspace block. Nothing re-runs `akan agent install` on its own, so
|
|
26
|
+
* without a stamp a workspace carrying conventions from four releases ago is indistinguishable from a current one —
|
|
27
|
+
* `akan doctor` compares this against the installed devkit and says so.
|
|
28
|
+
*/
|
|
29
|
+
export const stampBlockVersion = (block: string, version: string): string =>
|
|
30
|
+
`${AGENT_VERSION_PREFIX}${version} -->\n\n${block}`;
|
|
31
|
+
|
|
32
|
+
/** The stamped version of a committed AGENTS.md, or null when it predates stamping or carries no block. */
|
|
33
|
+
export const extractBlockVersion = (content: string): string | null =>
|
|
34
|
+
content.match(/<!-- akan:agent:version ([^\s]+) -->/)?.[1] ?? null;
|
|
35
|
+
|
|
36
|
+
/** The running `@akanjs/devkit` version; null when its package.json is unreadable, which must not fail a doctor run. */
|
|
37
|
+
export const readDevkitVersion = async (): Promise<string | null> => {
|
|
38
|
+
const { readFile } = await import("node:fs/promises");
|
|
39
|
+
const { getDirname } = await import("./getDirname");
|
|
40
|
+
try {
|
|
41
|
+
const raw = await readFile(`${getDirname(import.meta.url)}/package.json`, "utf-8");
|
|
42
|
+
return (JSON.parse(raw) as { version?: string }).version ?? null;
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
22
48
|
export interface AgentsIndexScope {
|
|
23
49
|
type: "app" | "lib";
|
|
24
50
|
name: string;
|
package/akanContext.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdir } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { capitalize } from "akanjs/common";
|
|
4
|
+
import { extractBlockVersion, readDevkitVersion } from "./agentsIndex";
|
|
4
5
|
import { AppExecutor, LibExecutor, type SysExecutor, type WorkspaceExecutor } from "./executors";
|
|
5
6
|
import { FileSys } from "./fileSys";
|
|
6
7
|
import { collectRecipeSources, findInlineRecipeDuplicates, scanRecipes } from "./recipeScanner";
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
workflowRunArtifactPath,
|
|
15
16
|
workflowSyncDir,
|
|
16
17
|
} from "./workflow";
|
|
18
|
+
import { appRootAllowedDirs, appRootAllowedFiles, isScannedAppRootEntry } from "./workspaceLayout";
|
|
17
19
|
|
|
18
20
|
export type AkanContextFormat = "json" | "markdown";
|
|
19
21
|
export type AkanModuleKind = "domain" | "service" | "scalar";
|
|
@@ -275,6 +277,8 @@ const validationCommands = [
|
|
|
275
277
|
"akan test <app-or-lib-or-pkg>",
|
|
276
278
|
"akan build <app-name>",
|
|
277
279
|
"akan doctor --strict --format json",
|
|
280
|
+
"akan quality scan [--format json]",
|
|
281
|
+
"akan quality ssr [--format json]",
|
|
278
282
|
];
|
|
279
283
|
|
|
280
284
|
const unknownGeneratedFilesFreshness: GeneratedFilesFreshness = {
|
|
@@ -313,36 +317,6 @@ const moduleShapeFiles = (module: AkanModuleContext) => {
|
|
|
313
317
|
const constantFieldNames = (content: string) =>
|
|
314
318
|
[...content.matchAll(/\b([A-Za-z_$][\w$]*)\s*:\s*field\(/g)].map((match) => match[1]).filter(Boolean);
|
|
315
319
|
|
|
316
|
-
const appRootAllowFiles = new Set([
|
|
317
|
-
// 스코프 에이전트 가이드 — scan(write) 이 유지 (agentsIndex.ts); scanInfo.ts 의 appRootAllowedFiles 와 동기
|
|
318
|
-
"AGENTS.md",
|
|
319
|
-
"CLAUDE.md",
|
|
320
|
-
"akan.app.json",
|
|
321
|
-
"akan.config.ts",
|
|
322
|
-
"capacitor.config.ts",
|
|
323
|
-
"client.ts",
|
|
324
|
-
"main.ts",
|
|
325
|
-
"package.json",
|
|
326
|
-
"server.ts",
|
|
327
|
-
"tsconfig.json",
|
|
328
|
-
]);
|
|
329
|
-
|
|
330
|
-
const appRootAllowDirs = new Set([
|
|
331
|
-
".akan",
|
|
332
|
-
"android",
|
|
333
|
-
"common",
|
|
334
|
-
"env",
|
|
335
|
-
"ios",
|
|
336
|
-
"lib",
|
|
337
|
-
"page",
|
|
338
|
-
"private",
|
|
339
|
-
"public",
|
|
340
|
-
"script",
|
|
341
|
-
"srvkit",
|
|
342
|
-
"ui",
|
|
343
|
-
"webkit",
|
|
344
|
-
]);
|
|
345
|
-
|
|
346
320
|
const safeReadDir = async (dirPath: string) => {
|
|
347
321
|
try {
|
|
348
322
|
return (await readdir(dirPath, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -647,6 +621,30 @@ export class AkanContextAnalyzer {
|
|
|
647
621
|
};
|
|
648
622
|
}
|
|
649
623
|
|
|
624
|
+
// The conventions in AGENTS.md ship with the package, but nothing re-renders them on `bun update` — a workspace
|
|
625
|
+
// keeps whichever release wrote its block until someone re-runs the install. Comparing the stamp against the
|
|
626
|
+
// running devkit is the only signal that the guide an agent is reading is older than the framework it describes.
|
|
627
|
+
static async #agentGuideDrift(workspace: WorkspaceExecutor) {
|
|
628
|
+
const installed = await readDevkitVersion();
|
|
629
|
+
if (!installed) return null;
|
|
630
|
+
const content = await safeReadText(path.join(workspace.workspaceRoot, "AGENTS.md"));
|
|
631
|
+
if (content === null) return null;
|
|
632
|
+
const stamped = extractBlockVersion(content);
|
|
633
|
+
if (stamped === installed) return null;
|
|
634
|
+
const hint = "Re-render the AGENTS.md managed block from the installed framework release.";
|
|
635
|
+
if (!stamped)
|
|
636
|
+
return {
|
|
637
|
+
code: "agent-guide-unstamped",
|
|
638
|
+
message: `AGENTS.md carries no generated-version stamp, so its conventions may predate @akanjs/devkit ${installed}`,
|
|
639
|
+
hint,
|
|
640
|
+
};
|
|
641
|
+
return {
|
|
642
|
+
code: "agent-guide-stale",
|
|
643
|
+
message: `AGENTS.md was generated by @akanjs/devkit ${stamped}, but ${installed} is installed`,
|
|
644
|
+
hint,
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
650
648
|
static async doctor(
|
|
651
649
|
workspace: WorkspaceExecutor,
|
|
652
650
|
{
|
|
@@ -671,7 +669,8 @@ export class AkanContextAnalyzer {
|
|
|
671
669
|
for (const app of context.apps) {
|
|
672
670
|
const appPath = path.join(workspace.workspaceRoot, app.path);
|
|
673
671
|
for (const entry of await safeReadDir(appPath)) {
|
|
674
|
-
|
|
672
|
+
if (!isScannedAppRootEntry(entry.name)) continue;
|
|
673
|
+
const allowed = entry.isDirectory() ? appRootAllowedDirs.has(entry.name) : appRootAllowedFiles.has(entry.name);
|
|
675
674
|
if (!allowed) {
|
|
676
675
|
const action = repairAction(
|
|
677
676
|
"module-shape",
|
|
@@ -691,6 +690,19 @@ export class AkanContextAnalyzer {
|
|
|
691
690
|
}
|
|
692
691
|
}
|
|
693
692
|
|
|
693
|
+
const agentDrift = await AkanContextAnalyzer.#agentGuideDrift(workspace);
|
|
694
|
+
if (agentDrift) {
|
|
695
|
+
const action = repairAction("generated", "akan agent install agents-md", agentDrift.hint, true);
|
|
696
|
+
diagnostics.push({
|
|
697
|
+
severity: "warning",
|
|
698
|
+
code: agentDrift.code,
|
|
699
|
+
path: "AGENTS.md",
|
|
700
|
+
message: agentDrift.message,
|
|
701
|
+
repairActions: [action],
|
|
702
|
+
});
|
|
703
|
+
repairActions.push(action);
|
|
704
|
+
}
|
|
705
|
+
|
|
694
706
|
for (const sys of [...context.apps, ...context.libs]) {
|
|
695
707
|
for (const module of sys.modules) {
|
|
696
708
|
if (!module.abstract.exists) {
|
|
@@ -112,7 +112,7 @@ export class ApplicationBuildRunner {
|
|
|
112
112
|
() => precompressArtifacts(this.#app),
|
|
113
113
|
(result) =>
|
|
114
114
|
result.files > 0
|
|
115
|
-
? `${result.files} files, ${ApplicationBuildRunner.formatBytes(result.inputBytes)} -> ${ApplicationBuildRunner.formatBytes(result.outputBytes)}`
|
|
115
|
+
? `${result.files} files, ${ApplicationBuildRunner.formatBytes(result.inputBytes)} -> gzip ${ApplicationBuildRunner.formatBytes(result.outputBytes)} / br ${ApplicationBuildRunner.formatBytes(result.brotliBytes)}`
|
|
116
116
|
: "no files",
|
|
117
117
|
phaseOptions,
|
|
118
118
|
);
|
package/biome.base.json
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.5.8/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": false
|
|
7
|
+
},
|
|
8
|
+
"formatter": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"indentStyle": "space",
|
|
11
|
+
"indentWidth": 2,
|
|
12
|
+
"lineWidth": 120
|
|
13
|
+
},
|
|
14
|
+
"linter": {
|
|
15
|
+
"enabled": true,
|
|
16
|
+
"rules": {
|
|
17
|
+
"preset": "recommended",
|
|
18
|
+
"suspicious": {
|
|
19
|
+
"noConsole": {
|
|
20
|
+
"level": "error",
|
|
21
|
+
"options": {
|
|
22
|
+
"allow": ["assert", "error", "info", "warn"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"noArrayIndexKey": "off",
|
|
26
|
+
"noShadowRestrictedNames": "off",
|
|
27
|
+
"noUnnecessaryConditions": {
|
|
28
|
+
"level": "error"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"correctness": {
|
|
32
|
+
"noUnusedFunctionParameters": "off",
|
|
33
|
+
"noUnusedImports": {
|
|
34
|
+
"level": "error",
|
|
35
|
+
"fix": "safe"
|
|
36
|
+
},
|
|
37
|
+
"useParseIntRadix": "off",
|
|
38
|
+
"useExhaustiveDependencies": "off",
|
|
39
|
+
"useHookAtTopLevel": "off"
|
|
40
|
+
},
|
|
41
|
+
"nursery": {
|
|
42
|
+
"useSortedClasses": {
|
|
43
|
+
"level": "error",
|
|
44
|
+
"fix": "safe",
|
|
45
|
+
"options": {
|
|
46
|
+
"attributes": ["classList"],
|
|
47
|
+
"functions": ["cn"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"a11y": "off",
|
|
52
|
+
"complexity": {
|
|
53
|
+
"noStaticOnlyClass": "off"
|
|
54
|
+
},
|
|
55
|
+
"style": {
|
|
56
|
+
"useTemplate": {
|
|
57
|
+
"level": "warn",
|
|
58
|
+
"fix": "safe"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"domains": {
|
|
63
|
+
"project": "recommended",
|
|
64
|
+
"react": "recommended",
|
|
65
|
+
"test": "recommended",
|
|
66
|
+
"types": "all"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"javascript": {
|
|
70
|
+
"parser": {
|
|
71
|
+
"unsafeParameterDecoratorsEnabled": true
|
|
72
|
+
},
|
|
73
|
+
"formatter": {
|
|
74
|
+
"quoteStyle": "double"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"assist": {
|
|
78
|
+
"enabled": true,
|
|
79
|
+
"actions": {
|
|
80
|
+
"source": {
|
|
81
|
+
"organizeImports": "on"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"overrides": [
|
|
86
|
+
{
|
|
87
|
+
"includes": [
|
|
88
|
+
"**/env.client.local.ts",
|
|
89
|
+
"**/env.client.debug.ts",
|
|
90
|
+
"**/env.client.develop.ts",
|
|
91
|
+
"**/env.client.main.ts",
|
|
92
|
+
"**/env.client.testing.ts",
|
|
93
|
+
"**/env.server.local.ts",
|
|
94
|
+
"**/env.server.develop.ts",
|
|
95
|
+
"**/env.server.main.ts",
|
|
96
|
+
"**/env.server.testing.ts",
|
|
97
|
+
"**/env.server.type.ts",
|
|
98
|
+
"apps/*/lib/cnst.ts",
|
|
99
|
+
"apps/*/lib/dict.ts",
|
|
100
|
+
"apps/*/lib/db.ts",
|
|
101
|
+
"apps/*/lib/srv.ts",
|
|
102
|
+
"apps/*/lib/st.ts",
|
|
103
|
+
"apps/*/lib/sig.ts",
|
|
104
|
+
"apps/*/lib/useClient.ts",
|
|
105
|
+
"apps/*/lib/useServer.ts",
|
|
106
|
+
"apps/*/client.ts",
|
|
107
|
+
"apps/*/server.ts",
|
|
108
|
+
"apps/*/lib/*/index.tsx",
|
|
109
|
+
"libs/*/lib/cnst.ts",
|
|
110
|
+
"libs/*/lib/dict.ts",
|
|
111
|
+
"libs/*/lib/db.ts",
|
|
112
|
+
"libs/*/lib/srv.ts",
|
|
113
|
+
"libs/*/lib/st.ts",
|
|
114
|
+
"libs/*/lib/sig.ts",
|
|
115
|
+
"libs/*/lib/useClient.ts",
|
|
116
|
+
"libs/*/lib/useServer.ts",
|
|
117
|
+
"libs/*/client.ts",
|
|
118
|
+
"libs/*/server.ts",
|
|
119
|
+
"libs/*/index.ts",
|
|
120
|
+
"libs/*/lib/*/index.tsx"
|
|
121
|
+
],
|
|
122
|
+
"linter": { "enabled": false },
|
|
123
|
+
"formatter": { "enabled": false },
|
|
124
|
+
"assist": { "enabled": false }
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"includes": [
|
|
128
|
+
"apps/**/*.ts",
|
|
129
|
+
"apps/**/*.tsx",
|
|
130
|
+
"libs/**/*.ts",
|
|
131
|
+
"libs/**/*.tsx",
|
|
132
|
+
"!**/*.test.ts",
|
|
133
|
+
"!**/*.test.tsx",
|
|
134
|
+
"!**/*.spec.ts",
|
|
135
|
+
"!**/*.spec.tsx",
|
|
136
|
+
"!**/*.constant.ts",
|
|
137
|
+
"!**/common/**",
|
|
138
|
+
"!**/env/**"
|
|
139
|
+
],
|
|
140
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-throw-raw-error.grit"]
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"includes": ["**/page/**/*.ts", "**/page/**/*.tsx", "**/*.Unit.tsx", "**/*.View.tsx"],
|
|
144
|
+
"plugins": [
|
|
145
|
+
"./node_modules/@akanjs/devkit/lint/no-import-client-functions.grit",
|
|
146
|
+
"./node_modules/@akanjs/devkit/lint/no-use-client-in-server.grit"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"includes": ["**/page/**/*.ts", "**/page/**/*.tsx"],
|
|
151
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/non-scalar-props-restricted.grit"]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"includes": ["**/*.constant.ts", "**/*.document.ts", "**/*.service.ts", "**/*.store.ts"],
|
|
155
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-js-private-class-method.grit"]
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"includes": ["**/*.store.ts"],
|
|
159
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-return-in-store-action.grit"]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"includes": ["**/*.signal.ts"],
|
|
163
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-redeclare-predefined-endpoint.grit"]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"includes": [
|
|
167
|
+
"**/ui/**/*.ts",
|
|
168
|
+
"**/ui/**/*.tsx",
|
|
169
|
+
"**/webkit/**/*.ts",
|
|
170
|
+
"**/webkit/**/*.tsx",
|
|
171
|
+
"**/common/**/*.ts",
|
|
172
|
+
"**/page/**/*.tsx",
|
|
173
|
+
"**/*.constant.ts",
|
|
174
|
+
"**/*.store.ts",
|
|
175
|
+
"**/*.Template.tsx",
|
|
176
|
+
"**/*.Unit.tsx",
|
|
177
|
+
"**/*.Util.tsx",
|
|
178
|
+
"**/*.View.tsx",
|
|
179
|
+
"**/*.Zone.tsx",
|
|
180
|
+
"!**/*.test.ts",
|
|
181
|
+
"!**/*.test.tsx",
|
|
182
|
+
"!**/*.spec.ts",
|
|
183
|
+
"!**/*.spec.tsx"
|
|
184
|
+
],
|
|
185
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-bang-comment-in-client.grit"]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"includes": [
|
|
189
|
+
"**/*.constant.ts",
|
|
190
|
+
"**/*.dictionary.ts",
|
|
191
|
+
"**/*.document.ts",
|
|
192
|
+
"**/*.service.ts",
|
|
193
|
+
"**/*.signal.ts",
|
|
194
|
+
"**/*.store.ts",
|
|
195
|
+
"**/*.Template.tsx",
|
|
196
|
+
"**/*.Unit.tsx",
|
|
197
|
+
"**/*.Util.tsx",
|
|
198
|
+
"**/*.View.tsx",
|
|
199
|
+
"**/*.Zone.tsx"
|
|
200
|
+
],
|
|
201
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-deep-internal-import.grit"]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"includes": [
|
|
205
|
+
"**/page/**/*.ts",
|
|
206
|
+
"**/page/**/*.tsx",
|
|
207
|
+
"**/index.ts",
|
|
208
|
+
"**/index.tsx",
|
|
209
|
+
"**/cnst.ts",
|
|
210
|
+
"**/db.ts",
|
|
211
|
+
"**/dict.ts",
|
|
212
|
+
"**/option.ts",
|
|
213
|
+
"**/sig.ts",
|
|
214
|
+
"**/srv.ts",
|
|
215
|
+
"**/st.ts",
|
|
216
|
+
"**/*.constant.ts",
|
|
217
|
+
"**/*.dictionary.ts",
|
|
218
|
+
"**/*.document.ts",
|
|
219
|
+
"**/*.service.ts",
|
|
220
|
+
"**/*.signal.ts",
|
|
221
|
+
"**/*.signal.test.ts",
|
|
222
|
+
"**/*.service.test.ts",
|
|
223
|
+
"**/*.store.ts",
|
|
224
|
+
"**/*.Template.tsx",
|
|
225
|
+
"**/*.Unit.tsx",
|
|
226
|
+
"**/*.Util.tsx",
|
|
227
|
+
"**/*.View.tsx",
|
|
228
|
+
"**/*.Zone.tsx"
|
|
229
|
+
],
|
|
230
|
+
"plugins": [
|
|
231
|
+
"./node_modules/@akanjs/devkit/lint/no-import-external-library.grit",
|
|
232
|
+
"./node_modules/@akanjs/devkit/lint/no-deep-internal-import.grit"
|
|
233
|
+
]
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"includes": [
|
|
237
|
+
"apps/**/*.tsx",
|
|
238
|
+
"libs/**/*.tsx",
|
|
239
|
+
"apps/**/ui/**/*.ts",
|
|
240
|
+
"libs/**/ui/**/*.ts",
|
|
241
|
+
"apps/**/webkit/**/*.ts",
|
|
242
|
+
"libs/**/webkit/**/*.ts",
|
|
243
|
+
"apps/**/page/**/*.ts",
|
|
244
|
+
"libs/**/page/**/*.ts",
|
|
245
|
+
"apps/**/common/**/*.ts",
|
|
246
|
+
"libs/**/common/**/*.ts",
|
|
247
|
+
"apps/**/*.store.ts",
|
|
248
|
+
"libs/**/*.store.ts",
|
|
249
|
+
"apps/**/*.constant.ts",
|
|
250
|
+
"libs/**/*.constant.ts",
|
|
251
|
+
"!**/*.test.ts",
|
|
252
|
+
"!**/*.test.tsx",
|
|
253
|
+
"!**/*.spec.ts",
|
|
254
|
+
"!**/*.spec.tsx"
|
|
255
|
+
],
|
|
256
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-import-server-in-client.grit"]
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"includes": [
|
|
260
|
+
"apps/**/*.document.ts",
|
|
261
|
+
"libs/**/*.document.ts",
|
|
262
|
+
"apps/**/*.dictionary.ts",
|
|
263
|
+
"libs/**/*.dictionary.ts",
|
|
264
|
+
"apps/**/*.service.ts",
|
|
265
|
+
"libs/**/*.service.ts",
|
|
266
|
+
"apps/**/*.signal.ts",
|
|
267
|
+
"libs/**/*.signal.ts",
|
|
268
|
+
"apps/**/srvkit/**/*.ts",
|
|
269
|
+
"libs/**/srvkit/**/*.ts",
|
|
270
|
+
"apps/**/common/**/*.ts",
|
|
271
|
+
"libs/**/common/**/*.ts",
|
|
272
|
+
"apps/**/*.constant.ts",
|
|
273
|
+
"libs/**/*.constant.ts",
|
|
274
|
+
"!**/*.test.ts",
|
|
275
|
+
"!**/*.test.tsx",
|
|
276
|
+
"!**/*.spec.ts",
|
|
277
|
+
"!**/*.spec.tsx"
|
|
278
|
+
],
|
|
279
|
+
"plugins": ["./node_modules/@akanjs/devkit/lint/no-import-client-in-server.grit"]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"includes": [
|
|
283
|
+
"apps/**/*.ts",
|
|
284
|
+
"apps/**/*.tsx",
|
|
285
|
+
"libs/**/*.ts",
|
|
286
|
+
"libs/**/*.tsx",
|
|
287
|
+
"!**/*.test.ts",
|
|
288
|
+
"!**/*.test.tsx",
|
|
289
|
+
"!**/*.spec.ts",
|
|
290
|
+
"!**/*.spec.tsx"
|
|
291
|
+
],
|
|
292
|
+
"plugins": [
|
|
293
|
+
"./node_modules/@akanjs/devkit/lint/no-raw-palette-class.grit",
|
|
294
|
+
"./node_modules/@akanjs/devkit/lint/no-arbitrary-color.grit",
|
|
295
|
+
"./node_modules/@akanjs/devkit/lint/no-daisyui-legacy-class.grit",
|
|
296
|
+
"./node_modules/@akanjs/devkit/lint/no-inline-color.grit",
|
|
297
|
+
"./node_modules/@akanjs/devkit/lint/no-interpolated-arbitrary-class.grit"
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
}
|
package/biomeBase.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `extends` target for a workspace `biome.json`; Biome resolves it through node_modules. */
|
|
2
|
+
export const biomeBaseConfig = "@akanjs/devkit/biome.base.json";
|
|
3
|
+
|
|
4
|
+
// Biome moves rules between groups across minors — `noUnnecessaryConditions` sat in `nursery` at 2.4 and moved to
|
|
5
|
+
// `suspicious` at 2.5 — and the stale position is a hard "unknown key" error, not a warning. A workspace whose
|
|
6
|
+
// Biome disagrees with the shipped base config therefore fails to load it at all, which is why the version is
|
|
7
|
+
// pinned here instead of resolved to latest at create time. Bump this and `biome.base.json` in one commit, and run
|
|
8
|
+
// `biome migrate --write` in the workspace root and in `pkgs/@akanjs/devkit` so both configs move together.
|
|
9
|
+
export const biomeVersion = "2.5.8";
|
package/capacitorApp.test.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
clearRootCapacitorConfigs,
|
|
12
12
|
formatAndroidReleaseSigningError,
|
|
13
13
|
getAdbDeviceStateIssues,
|
|
14
|
+
getAndroidLocalServerHost,
|
|
14
15
|
getMissingAndroidReleaseSigningKeys,
|
|
15
16
|
isPlaceholderAppId,
|
|
16
17
|
materializeCapacitorConfig,
|
|
@@ -339,6 +340,13 @@ describe("Android signing diagnostics", () => {
|
|
|
339
340
|
"Android device abc123 is unauthorized. Confirm USB debugging authorization on the device.",
|
|
340
341
|
"Android device xyz is offline. Reconnect the device or restart adb.",
|
|
341
342
|
]);
|
|
343
|
+
expect(getAndroidLocalServerHost("List of devices attached\nemulator-5554 device\n", "192.168.0.5")).toBe(
|
|
344
|
+
"10.0.2.2",
|
|
345
|
+
);
|
|
346
|
+
expect(getAndroidLocalServerHost("List of devices attached\nabc123 device\n", "192.168.0.5")).toBe("192.168.0.5");
|
|
347
|
+
expect(
|
|
348
|
+
getAndroidLocalServerHost("List of devices attached\nemulator-5554 device\nabc123 device\n", "192.168.0.5"),
|
|
349
|
+
).toBe("192.168.0.5");
|
|
342
350
|
});
|
|
343
351
|
});
|
|
344
352
|
|