@jay-framework/jay-stack-cli 0.23.0 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-kit-template/plugin/add-menu-guide.md +17 -17
- package/dist/index.js +109 -215
- package/package.json +10 -10
|
@@ -44,10 +44,10 @@ Use `reference` for data sources (contracts, categories). Use `stage-place` for
|
|
|
44
44
|
Controls card size in the browse grid:
|
|
45
45
|
|
|
46
46
|
```yaml
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
browse:
|
|
48
|
+
size: small # 4 per row — color swatches, small tokens
|
|
49
|
+
size: medium # 2 per row — default
|
|
50
|
+
size: large # 1 per row — full-width previews
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
## Presentation (preview)
|
|
@@ -55,19 +55,19 @@ Controls card size in the browse grid:
|
|
|
55
55
|
Optional visual preview in the browse grid:
|
|
56
56
|
|
|
57
57
|
```yaml
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
# Static image
|
|
59
|
+
presentation:
|
|
60
|
+
type: image
|
|
61
|
+
src: thumbnails/my-plugin/feature.png
|
|
62
|
+
|
|
63
|
+
# HTML fragment — must use @scope for CSS isolation
|
|
64
|
+
presentation:
|
|
65
|
+
type: html-fragment
|
|
66
|
+
html: |
|
|
67
|
+
<div>
|
|
68
|
+
<style>@scope { .demo { color: blue; } }</style>
|
|
69
|
+
<div class="demo">Preview content</div>
|
|
70
|
+
</div>
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Html-fragment rules:
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ import path from "path";
|
|
|
7
7
|
import fs, { promises } from "fs";
|
|
8
8
|
import YAML from "yaml";
|
|
9
9
|
import { getLogger, setDevLogger, createDevLogger } from "@jay-framework/logger";
|
|
10
|
-
import {
|
|
11
|
-
import { scanPlugins, listContracts, materializeContracts, SetupNeedsAnswerError, discoverPluginsWithSetup,
|
|
10
|
+
import { parseJayFile, JAY_IMPORT_RESOLVER, generateElementDefinitionFile, parseContract, generateElementFile, generateServerElementFile, htmlElementTagNameMap, loadLinkedContract, getLinkedContractDir } from "@jay-framework/compiler-jay-html";
|
|
11
|
+
import { scanPlugins, listContracts, materializeContracts, SetupNeedsAnswerError, discoverPluginsWithSetup, sortPluginsByDependencies, discoverPluginsWithInit, executePluginSetup, executePluginServerInits, runInitCallbacks } from "@jay-framework/stack-server-runtime";
|
|
12
12
|
import { listContracts as listContracts2, materializeContracts as materializeContracts2 } from "@jay-framework/stack-server-runtime";
|
|
13
13
|
import { Command } from "commander";
|
|
14
14
|
import chalk from "chalk";
|
|
@@ -19,7 +19,7 @@ import { createRequire } from "module";
|
|
|
19
19
|
import { glob } from "glob";
|
|
20
20
|
import fsSync from "node:fs";
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
|
-
import {
|
|
22
|
+
import { select, confirm, input } from "@inquirer/prompts";
|
|
23
23
|
const DEFAULT_CONFIG = {
|
|
24
24
|
devServer: {
|
|
25
25
|
portRange: [3e3, 3100],
|
|
@@ -464,17 +464,13 @@ function collectLocalInterfaces(sourceFile) {
|
|
|
464
464
|
function collectContractImportedTypes(sourceFile) {
|
|
465
465
|
const contractTypes = /* @__PURE__ */ new Set();
|
|
466
466
|
for (const statement of sourceFile.statements) {
|
|
467
|
-
if (!u.isImportDeclaration(statement))
|
|
468
|
-
continue;
|
|
467
|
+
if (!u.isImportDeclaration(statement)) continue;
|
|
469
468
|
const moduleSpecifier = statement.moduleSpecifier;
|
|
470
|
-
if (!u.isStringLiteral(moduleSpecifier))
|
|
471
|
-
continue;
|
|
469
|
+
if (!u.isStringLiteral(moduleSpecifier)) continue;
|
|
472
470
|
const modulePath = moduleSpecifier.text;
|
|
473
|
-
if (!modulePath.includes(".jay-contract"))
|
|
474
|
-
continue;
|
|
471
|
+
if (!modulePath.includes(".jay-contract")) continue;
|
|
475
472
|
const importClause = statement.importClause;
|
|
476
|
-
if (!importClause)
|
|
477
|
-
continue;
|
|
473
|
+
if (!importClause) continue;
|
|
478
474
|
const namedBindings = importClause.namedBindings;
|
|
479
475
|
if (namedBindings && u.isNamedImports(namedBindings)) {
|
|
480
476
|
for (const element of namedBindings.elements) {
|
|
@@ -510,8 +506,7 @@ function visitNode(node, result) {
|
|
|
510
506
|
}
|
|
511
507
|
if (node.arguments.length > 0) {
|
|
512
508
|
const arg = node.arguments[0];
|
|
513
|
-
if (u.isIdentifier(arg))
|
|
514
|
-
;
|
|
509
|
+
if (u.isIdentifier(arg)) ;
|
|
515
510
|
}
|
|
516
511
|
}
|
|
517
512
|
}
|
|
@@ -533,10 +528,8 @@ function extractTypeNames(typeNode) {
|
|
|
533
528
|
return [];
|
|
534
529
|
}
|
|
535
530
|
function checkPropsConsistency(propsTypeName, localInterfaces, contractImportedTypes, contract, contractName, contractPath, sourcePath, errors, warnings) {
|
|
536
|
-
if (FRAMEWORK_PROP_TYPES.has(propsTypeName))
|
|
537
|
-
|
|
538
|
-
if (contractImportedTypes.has(propsTypeName))
|
|
539
|
-
return;
|
|
531
|
+
if (FRAMEWORK_PROP_TYPES.has(propsTypeName)) return;
|
|
532
|
+
if (contractImportedTypes.has(propsTypeName)) return;
|
|
540
533
|
const prefix = `[${contractName}]`;
|
|
541
534
|
const iface = localInterfaces.get(propsTypeName);
|
|
542
535
|
if (!iface) {
|
|
@@ -551,8 +544,7 @@ function checkPropsConsistency(propsTypeName, localInterfaces, contractImportedT
|
|
|
551
544
|
return;
|
|
552
545
|
}
|
|
553
546
|
const ownProperties = iface.properties;
|
|
554
|
-
if (ownProperties.length === 0)
|
|
555
|
-
return;
|
|
547
|
+
if (ownProperties.length === 0) return;
|
|
556
548
|
if (!contract.props || contract.props.length === 0) {
|
|
557
549
|
errors.push({
|
|
558
550
|
type: "contract-invalid",
|
|
@@ -596,10 +588,8 @@ function checkParamsConsistency(paramsTypeNames, localInterfaces, contractImport
|
|
|
596
588
|
suggestion: `Add a params section to the contract (e.g., params: { slug: string })`
|
|
597
589
|
});
|
|
598
590
|
for (const typeName of paramsTypeNames) {
|
|
599
|
-
if (FRAMEWORK_PROP_TYPES.has(typeName))
|
|
600
|
-
|
|
601
|
-
if (contractImportedTypes.has(typeName))
|
|
602
|
-
continue;
|
|
591
|
+
if (FRAMEWORK_PROP_TYPES.has(typeName)) continue;
|
|
592
|
+
if (contractImportedTypes.has(typeName)) continue;
|
|
603
593
|
const iface = localInterfaces.get(typeName);
|
|
604
594
|
if (iface) {
|
|
605
595
|
const ownProps = iface.properties;
|
|
@@ -612,13 +602,10 @@ function checkParamsConsistency(paramsTypeNames, localInterfaces, contractImport
|
|
|
612
602
|
return;
|
|
613
603
|
}
|
|
614
604
|
for (const typeName of paramsTypeNames) {
|
|
615
|
-
if (FRAMEWORK_PROP_TYPES.has(typeName))
|
|
616
|
-
|
|
617
|
-
if (contractImportedTypes.has(typeName))
|
|
618
|
-
continue;
|
|
605
|
+
if (FRAMEWORK_PROP_TYPES.has(typeName)) continue;
|
|
606
|
+
if (contractImportedTypes.has(typeName)) continue;
|
|
619
607
|
const iface = localInterfaces.get(typeName);
|
|
620
|
-
if (!iface)
|
|
621
|
-
continue;
|
|
608
|
+
if (!iface) continue;
|
|
622
609
|
const ownProperties = iface.properties;
|
|
623
610
|
const contractParamNames = new Set(contract.params.map((p) => p.name));
|
|
624
611
|
for (const prop of ownProperties) {
|
|
@@ -710,16 +697,13 @@ function requiredString(obj, field, itemPath, errors, code) {
|
|
|
710
697
|
}
|
|
711
698
|
function optionalString(obj, field) {
|
|
712
699
|
const value = obj[field];
|
|
713
|
-
if (value === void 0)
|
|
714
|
-
|
|
715
|
-
if (typeof value !== "string")
|
|
716
|
-
return void 0;
|
|
700
|
+
if (value === void 0) return void 0;
|
|
701
|
+
if (typeof value !== "string") return void 0;
|
|
717
702
|
const trimmed = value.trim();
|
|
718
703
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
719
704
|
}
|
|
720
705
|
function validateInteraction(raw, itemPath, errors) {
|
|
721
|
-
if (raw === void 0)
|
|
722
|
-
return void 0;
|
|
706
|
+
if (raw === void 0) return void 0;
|
|
723
707
|
if (!isRecord$1(raw)) {
|
|
724
708
|
errors.push({
|
|
725
709
|
path: itemPath,
|
|
@@ -743,8 +727,7 @@ function validateInteraction(raw, itemPath, errors) {
|
|
|
743
727
|
};
|
|
744
728
|
}
|
|
745
729
|
function validatePresentation(raw, itemPath, errors) {
|
|
746
|
-
if (raw === void 0)
|
|
747
|
-
return void 0;
|
|
730
|
+
if (raw === void 0) return void 0;
|
|
748
731
|
if (!isRecord$1(raw)) {
|
|
749
732
|
errors.push({
|
|
750
733
|
path: itemPath,
|
|
@@ -764,14 +747,12 @@ function validatePresentation(raw, itemPath, errors) {
|
|
|
764
747
|
}
|
|
765
748
|
if (type === "image") {
|
|
766
749
|
const src = requiredString(raw, "src", itemPath, errors, "presentation-missing-src");
|
|
767
|
-
if (!src)
|
|
768
|
-
return void 0;
|
|
750
|
+
if (!src) return void 0;
|
|
769
751
|
return { type: "image", src };
|
|
770
752
|
}
|
|
771
753
|
if (type === "gif") {
|
|
772
754
|
const src = requiredString(raw, "src", itemPath, errors, "presentation-missing-src");
|
|
773
|
-
if (!src)
|
|
774
|
-
return void 0;
|
|
755
|
+
if (!src) return void 0;
|
|
775
756
|
return {
|
|
776
757
|
type: "gif",
|
|
777
758
|
src,
|
|
@@ -816,8 +797,7 @@ function validatePresentation(raw, itemPath, errors) {
|
|
|
816
797
|
}
|
|
817
798
|
const BROWSE_SIZES = /* @__PURE__ */ new Set(["large", "medium", "small"]);
|
|
818
799
|
function validateBrowse(raw, itemPath, errors) {
|
|
819
|
-
if (raw === void 0)
|
|
820
|
-
return void 0;
|
|
800
|
+
if (raw === void 0) return void 0;
|
|
821
801
|
if (!isRecord$1(raw)) {
|
|
822
802
|
errors.push({
|
|
823
803
|
path: itemPath,
|
|
@@ -841,8 +821,7 @@ function validateBrowse(raw, itemPath, errors) {
|
|
|
841
821
|
return { size: sizeRaw };
|
|
842
822
|
}
|
|
843
823
|
function validateFolderPath(raw, itemPath, errors) {
|
|
844
|
-
if (raw === void 0)
|
|
845
|
-
return void 0;
|
|
824
|
+
if (raw === void 0) return void 0;
|
|
846
825
|
if (!Array.isArray(raw)) {
|
|
847
826
|
errors.push({
|
|
848
827
|
path: `${itemPath}.folderPath`,
|
|
@@ -980,8 +959,7 @@ function validateAddMenuCatalogFile(raw, sourcePath) {
|
|
|
980
959
|
raw.items.forEach((entry, index) => {
|
|
981
960
|
const result = validateAddMenuItem(entry, `${sourcePath}.items[${index}]`);
|
|
982
961
|
errors.push(...result.errors);
|
|
983
|
-
if (result.item)
|
|
984
|
-
items.push(result.item);
|
|
962
|
+
if (result.item) items.push(result.item);
|
|
985
963
|
});
|
|
986
964
|
if (items.length === 0 && errors.length > 0) {
|
|
987
965
|
return { file: null, errors };
|
|
@@ -989,11 +967,9 @@ function validateAddMenuCatalogFile(raw, sourcePath) {
|
|
|
989
967
|
return { file: { items }, errors };
|
|
990
968
|
}
|
|
991
969
|
function normalizeAddMenuPresentation(item) {
|
|
992
|
-
if (item.presentation)
|
|
993
|
-
return item.presentation;
|
|
970
|
+
if (item.presentation) return item.presentation;
|
|
994
971
|
const thumbnail = item.thumbnail?.trim();
|
|
995
|
-
if (!thumbnail)
|
|
996
|
-
return void 0;
|
|
972
|
+
if (!thumbnail) return void 0;
|
|
997
973
|
if (/\.gif$/i.test(thumbnail)) {
|
|
998
974
|
return { type: "gif", src: thumbnail };
|
|
999
975
|
}
|
|
@@ -1004,15 +980,12 @@ function normalizeAddMenuBrowseSize(item) {
|
|
|
1004
980
|
}
|
|
1005
981
|
function hasSingleRootDiv(html) {
|
|
1006
982
|
const trimmed = html.trim();
|
|
1007
|
-
if (!trimmed.startsWith("<div"))
|
|
1008
|
-
return false;
|
|
983
|
+
if (!trimmed.startsWith("<div")) return false;
|
|
1009
984
|
const openMatch = trimmed.match(/^<div\b[^>]*>/i);
|
|
1010
|
-
if (!openMatch)
|
|
1011
|
-
return false;
|
|
985
|
+
if (!openMatch) return false;
|
|
1012
986
|
const afterOpen = trimmed.slice(openMatch[0].length);
|
|
1013
987
|
const closeIdx = afterOpen.lastIndexOf("</div>");
|
|
1014
|
-
if (closeIdx < 0)
|
|
1015
|
-
return false;
|
|
988
|
+
if (closeIdx < 0) return false;
|
|
1016
989
|
const tail = afterOpen.slice(closeIdx + "</div>".length).trim();
|
|
1017
990
|
return tail.length === 0;
|
|
1018
991
|
}
|
|
@@ -1088,8 +1061,7 @@ function lintHtmlFragment(item, sourcePath) {
|
|
|
1088
1061
|
}
|
|
1089
1062
|
function lintGifPoster(item, sourcePath) {
|
|
1090
1063
|
const presentation = normalizeAddMenuPresentation(item);
|
|
1091
|
-
if (presentation?.type !== "gif" || presentation.poster?.trim())
|
|
1092
|
-
return [];
|
|
1064
|
+
if (presentation?.type !== "gif" || presentation.poster?.trim()) return [];
|
|
1093
1065
|
return [
|
|
1094
1066
|
catalogWarning(
|
|
1095
1067
|
"gif-missing-poster",
|
|
@@ -1100,10 +1072,8 @@ function lintGifPoster(item, sourcePath) {
|
|
|
1100
1072
|
];
|
|
1101
1073
|
}
|
|
1102
1074
|
function lintBrowseLargeWithoutPresentation(item, sourcePath) {
|
|
1103
|
-
if (normalizeAddMenuBrowseSize(item) !== "large")
|
|
1104
|
-
|
|
1105
|
-
if (normalizeAddMenuPresentation(item))
|
|
1106
|
-
return [];
|
|
1075
|
+
if (normalizeAddMenuBrowseSize(item) !== "large") return [];
|
|
1076
|
+
if (normalizeAddMenuPresentation(item)) return [];
|
|
1107
1077
|
return [
|
|
1108
1078
|
catalogWarning(
|
|
1109
1079
|
"browse-large-without-presentation",
|
|
@@ -1176,8 +1146,7 @@ function resolveModulePath$1(basePath) {
|
|
|
1176
1146
|
return void 0;
|
|
1177
1147
|
}
|
|
1178
1148
|
function collectTypeScriptFiles(dir, depth = 0) {
|
|
1179
|
-
if (depth > 4)
|
|
1180
|
-
return [];
|
|
1149
|
+
if (depth > 4) return [];
|
|
1181
1150
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
1182
1151
|
const files = [];
|
|
1183
1152
|
for (const entry of entries) {
|
|
@@ -1196,8 +1165,7 @@ function resolveHandlerSourceFile(pluginPath, handlerRef, isNpmPackage) {
|
|
|
1196
1165
|
}
|
|
1197
1166
|
const searchRoots = isNpmPackage ? [path.join(pluginPath, "lib"), path.join(pluginPath, "dist")] : [pluginPath];
|
|
1198
1167
|
for (const root of searchRoots) {
|
|
1199
|
-
if (!fs.existsSync(root))
|
|
1200
|
-
continue;
|
|
1168
|
+
if (!fs.existsSync(root)) continue;
|
|
1201
1169
|
for (const file of collectTypeScriptFiles(root)) {
|
|
1202
1170
|
const content = fs.readFileSync(file, "utf-8");
|
|
1203
1171
|
const definesHandler = new RegExp(
|
|
@@ -1217,8 +1185,7 @@ function resolveHandlerSourceFile(pluginPath, handlerRef, isNpmPackage) {
|
|
|
1217
1185
|
if (reExportMatch) {
|
|
1218
1186
|
const importSpec = reExportMatch[1].replace(/\.js$/, "");
|
|
1219
1187
|
const resolved = resolveModulePath$1(path.resolve(path.dirname(file), importSpec));
|
|
1220
|
-
if (resolved)
|
|
1221
|
-
return resolved;
|
|
1188
|
+
if (resolved) return resolved;
|
|
1222
1189
|
}
|
|
1223
1190
|
}
|
|
1224
1191
|
}
|
|
@@ -1228,8 +1195,7 @@ function extractBalancedBlock(source, openBraceIndex) {
|
|
|
1228
1195
|
let depth = 0;
|
|
1229
1196
|
for (let index = openBraceIndex; index < source.length; index++) {
|
|
1230
1197
|
const char = source[index];
|
|
1231
|
-
if (char === "{")
|
|
1232
|
-
depth++;
|
|
1198
|
+
if (char === "{") depth++;
|
|
1233
1199
|
else if (char === "}") {
|
|
1234
1200
|
depth--;
|
|
1235
1201
|
if (depth === 0) {
|
|
@@ -1249,8 +1215,7 @@ function findFunctionBodyOpenBrace(source, searchFrom) {
|
|
|
1249
1215
|
if (parenMatch?.index !== void 0) {
|
|
1250
1216
|
candidates.push(searchFrom + parenMatch.index + parenMatch[0].length - 1);
|
|
1251
1217
|
}
|
|
1252
|
-
if (candidates.length === 0)
|
|
1253
|
-
return -1;
|
|
1218
|
+
if (candidates.length === 0) return -1;
|
|
1254
1219
|
return Math.min(...candidates);
|
|
1255
1220
|
}
|
|
1256
1221
|
function extractFunctionBody(source, functionName) {
|
|
@@ -1267,11 +1232,9 @@ function extractFunctionBody(source, functionName) {
|
|
|
1267
1232
|
];
|
|
1268
1233
|
for (const pattern of patterns) {
|
|
1269
1234
|
const match = pattern.exec(source);
|
|
1270
|
-
if (!match)
|
|
1271
|
-
continue;
|
|
1235
|
+
if (!match) continue;
|
|
1272
1236
|
const braceIndex = findFunctionBodyOpenBrace(source, match.index);
|
|
1273
|
-
if (braceIndex === -1)
|
|
1274
|
-
continue;
|
|
1237
|
+
if (braceIndex === -1) continue;
|
|
1275
1238
|
return extractBalancedBlock(source, braceIndex);
|
|
1276
1239
|
}
|
|
1277
1240
|
return null;
|
|
@@ -1284,11 +1247,9 @@ function extractDefaultExportFunctionBody(source) {
|
|
|
1284
1247
|
];
|
|
1285
1248
|
for (const pattern of patterns) {
|
|
1286
1249
|
const match = pattern.exec(source);
|
|
1287
|
-
if (!match)
|
|
1288
|
-
continue;
|
|
1250
|
+
if (!match) continue;
|
|
1289
1251
|
const braceIndex = findFunctionBodyOpenBrace(source, match.index);
|
|
1290
|
-
if (braceIndex === -1)
|
|
1291
|
-
continue;
|
|
1252
|
+
if (braceIndex === -1) continue;
|
|
1292
1253
|
return extractBalancedBlock(source, braceIndex);
|
|
1293
1254
|
}
|
|
1294
1255
|
return null;
|
|
@@ -1298,8 +1259,7 @@ function handlerBodyWritesAddMenuCatalog(body) {
|
|
|
1298
1259
|
}
|
|
1299
1260
|
function resolveSetupHandlerFunctionBody(pluginPath, handlerRef, isNpmPackage) {
|
|
1300
1261
|
const sourceFile = resolveHandlerSourceFile(pluginPath, handlerRef, isNpmPackage);
|
|
1301
|
-
if (!sourceFile)
|
|
1302
|
-
return null;
|
|
1262
|
+
if (!sourceFile) return null;
|
|
1303
1263
|
const source = fs.readFileSync(sourceFile, "utf-8");
|
|
1304
1264
|
if (isRelativeHandlerRef(handlerRef)) {
|
|
1305
1265
|
return extractDefaultExportFunctionBody(source) ?? extractFunctionBody(source, "setup") ?? extractFunctionBody(source, handlerRef);
|
|
@@ -1307,8 +1267,7 @@ function resolveSetupHandlerFunctionBody(pluginPath, handlerRef, isNpmPackage) {
|
|
|
1307
1267
|
return extractFunctionBody(source, handlerRef);
|
|
1308
1268
|
}
|
|
1309
1269
|
function suggestionForCode(code) {
|
|
1310
|
-
if (!code)
|
|
1311
|
-
return `See ${CONTRIBUTOR_GUIDE} for schema and validation rules`;
|
|
1270
|
+
if (!code) return `See ${CONTRIBUTOR_GUIDE} for schema and validation rules`;
|
|
1312
1271
|
return ADD_MENU_VALIDATION_SUGGESTIONS[code] ?? `See ${CONTRIBUTOR_GUIDE} for schema and validation rules`;
|
|
1313
1272
|
}
|
|
1314
1273
|
function mapSchemaError$1(error, catalogPath) {
|
|
@@ -1338,8 +1297,7 @@ function pluginShipsAddMenuCatalog(context) {
|
|
|
1338
1297
|
);
|
|
1339
1298
|
}
|
|
1340
1299
|
function validateAddMenuAgentKitHandler(context, result) {
|
|
1341
|
-
if (!pluginShipsAddMenuCatalog(context))
|
|
1342
|
-
return;
|
|
1300
|
+
if (!pluginShipsAddMenuCatalog(context)) return;
|
|
1343
1301
|
const agentKitHandler = context.manifest.agentkit;
|
|
1344
1302
|
if (!agentKitHandler) {
|
|
1345
1303
|
result.warnings.push({
|
|
@@ -1351,15 +1309,13 @@ function validateAddMenuAgentKitHandler(context, result) {
|
|
|
1351
1309
|
});
|
|
1352
1310
|
}
|
|
1353
1311
|
const setupHandler = typeof context.manifest.setup === "string" ? context.manifest.setup : void 0;
|
|
1354
|
-
if (!setupHandler)
|
|
1355
|
-
return;
|
|
1312
|
+
if (!setupHandler) return;
|
|
1356
1313
|
const setupBody = resolveSetupHandlerFunctionBody(
|
|
1357
1314
|
context.pluginPath,
|
|
1358
1315
|
setupHandler,
|
|
1359
1316
|
context.isNpmPackage
|
|
1360
1317
|
);
|
|
1361
|
-
if (!setupBody || !handlerBodyWritesAddMenuCatalog(setupBody))
|
|
1362
|
-
return;
|
|
1318
|
+
if (!setupBody || !handlerBodyWritesAddMenuCatalog(setupBody)) return;
|
|
1363
1319
|
result.warnings.push({
|
|
1364
1320
|
type: "add-menu-catalog",
|
|
1365
1321
|
code: "add-menu-legacy-setup-handler",
|
|
@@ -1401,8 +1357,7 @@ async function validateAddMenuCatalog(context, result) {
|
|
|
1401
1357
|
validateAddMenuAgentKitHandler(context, result);
|
|
1402
1358
|
for (const relPath of ADD_MENU_CATALOG_REL_PATHS) {
|
|
1403
1359
|
const catalogPath = path.join(context.pluginPath, relPath);
|
|
1404
|
-
if (!fs.existsSync(catalogPath))
|
|
1405
|
-
continue;
|
|
1360
|
+
if (!fs.existsSync(catalogPath)) continue;
|
|
1406
1361
|
await validateAddMenuCatalogFileAtPath(catalogPath, relPath, result);
|
|
1407
1362
|
}
|
|
1408
1363
|
}
|
|
@@ -2026,16 +1981,14 @@ async function validateSchema(context, result) {
|
|
|
2026
1981
|
}
|
|
2027
1982
|
function checkExportExists(exportName, context) {
|
|
2028
1983
|
const packageJsonPath = path.join(context.pluginPath, "package.json");
|
|
2029
|
-
if (!fs.existsSync(packageJsonPath))
|
|
2030
|
-
return true;
|
|
1984
|
+
if (!fs.existsSync(packageJsonPath)) return true;
|
|
2031
1985
|
let mainPath;
|
|
2032
1986
|
try {
|
|
2033
1987
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
2034
1988
|
if (packageJson.exports?.["."]) {
|
|
2035
1989
|
const entry = packageJson.exports["."];
|
|
2036
1990
|
const entryPath = typeof entry === "string" ? entry : entry.default || entry.import;
|
|
2037
|
-
if (entryPath)
|
|
2038
|
-
mainPath = path.join(context.pluginPath, entryPath);
|
|
1991
|
+
if (entryPath) mainPath = path.join(context.pluginPath, entryPath);
|
|
2039
1992
|
}
|
|
2040
1993
|
if (!mainPath && packageJson.main) {
|
|
2041
1994
|
mainPath = path.join(context.pluginPath, packageJson.main);
|
|
@@ -2043,8 +1996,7 @@ function checkExportExists(exportName, context) {
|
|
|
2043
1996
|
} catch {
|
|
2044
1997
|
return true;
|
|
2045
1998
|
}
|
|
2046
|
-
if (!mainPath || !fs.existsSync(mainPath))
|
|
2047
|
-
return true;
|
|
1999
|
+
if (!mainPath || !fs.existsSync(mainPath)) return true;
|
|
2048
2000
|
try {
|
|
2049
2001
|
const content = fs.readFileSync(mainPath, "utf-8");
|
|
2050
2002
|
const patterns = [
|
|
@@ -2104,8 +2056,7 @@ function resolveContractFile(contractSpec, context) {
|
|
|
2104
2056
|
const resolvedPath = typeof exportValue === "string" ? exportValue : exportValue.default || exportValue.import || exportValue.require;
|
|
2105
2057
|
if (resolvedPath) {
|
|
2106
2058
|
const fullPath = path.join(context.pluginPath, resolvedPath);
|
|
2107
|
-
if (fs.existsSync(fullPath))
|
|
2108
|
-
return fullPath;
|
|
2059
|
+
if (fs.existsSync(fullPath)) return fullPath;
|
|
2109
2060
|
}
|
|
2110
2061
|
}
|
|
2111
2062
|
}
|
|
@@ -2114,8 +2065,7 @@ function resolveContractFile(contractSpec, context) {
|
|
|
2114
2065
|
}
|
|
2115
2066
|
for (const dir of ["dist", "lib", ""]) {
|
|
2116
2067
|
const candidate = path.join(context.pluginPath, dir, contractSpec);
|
|
2117
|
-
if (fs.existsSync(candidate))
|
|
2118
|
-
return candidate;
|
|
2068
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
2119
2069
|
}
|
|
2120
2070
|
return void 0;
|
|
2121
2071
|
} else {
|
|
@@ -2203,8 +2153,7 @@ function hasExportModifier(node) {
|
|
|
2203
2153
|
function resolveModulePath(basePath) {
|
|
2204
2154
|
for (const ext of ["", ".ts", ".js", "/index.ts", "/index.js"]) {
|
|
2205
2155
|
const candidate = basePath + ext;
|
|
2206
|
-
if (fs.existsSync(candidate))
|
|
2207
|
-
return candidate;
|
|
2156
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
2208
2157
|
}
|
|
2209
2158
|
return void 0;
|
|
2210
2159
|
}
|
|
@@ -2214,10 +2163,8 @@ function resolveComponentSourcePath(componentName, context) {
|
|
|
2214
2163
|
const entryFile = resolveModulePath(entryBase);
|
|
2215
2164
|
const libEntryFile = !entryFile ? resolveModulePath(path.join(context.pluginPath, "lib", modulePath)) : void 0;
|
|
2216
2165
|
const sourceEntry = entryFile || libEntryFile;
|
|
2217
|
-
if (!sourceEntry)
|
|
2218
|
-
|
|
2219
|
-
if (!sourceEntry.endsWith(".ts"))
|
|
2220
|
-
return void 0;
|
|
2166
|
+
if (!sourceEntry) return void 0;
|
|
2167
|
+
if (!sourceEntry.endsWith(".ts")) return void 0;
|
|
2221
2168
|
let sourceCode;
|
|
2222
2169
|
try {
|
|
2223
2170
|
sourceCode = fs.readFileSync(sourceEntry, "utf-8");
|
|
@@ -2233,12 +2180,9 @@ function resolveComponentSourcePath(componentName, context) {
|
|
|
2233
2180
|
);
|
|
2234
2181
|
const starReexportModules = [];
|
|
2235
2182
|
for (const statement of sourceFile.statements) {
|
|
2236
|
-
if (!u.isExportDeclaration(statement))
|
|
2237
|
-
|
|
2238
|
-
if (!statement.moduleSpecifier)
|
|
2239
|
-
continue;
|
|
2240
|
-
if (!u.isStringLiteral(statement.moduleSpecifier))
|
|
2241
|
-
continue;
|
|
2183
|
+
if (!u.isExportDeclaration(statement)) continue;
|
|
2184
|
+
if (!statement.moduleSpecifier) continue;
|
|
2185
|
+
if (!u.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
2242
2186
|
const moduleSpec = statement.moduleSpecifier.text;
|
|
2243
2187
|
const exportClause = statement.exportClause;
|
|
2244
2188
|
if (!exportClause) {
|
|
@@ -2256,12 +2200,10 @@ function resolveComponentSourcePath(componentName, context) {
|
|
|
2256
2200
|
}
|
|
2257
2201
|
}
|
|
2258
2202
|
for (const moduleSpec of starReexportModules) {
|
|
2259
|
-
if (!moduleSpec.startsWith("."))
|
|
2260
|
-
continue;
|
|
2203
|
+
if (!moduleSpec.startsWith(".")) continue;
|
|
2261
2204
|
const resolvedBase = path.resolve(path.dirname(sourceEntry), moduleSpec);
|
|
2262
2205
|
const resolvedPath = resolveModulePath(resolvedBase);
|
|
2263
|
-
if (!resolvedPath || !resolvedPath.endsWith(".ts"))
|
|
2264
|
-
continue;
|
|
2206
|
+
if (!resolvedPath || !resolvedPath.endsWith(".ts")) continue;
|
|
2265
2207
|
try {
|
|
2266
2208
|
const modSource = fs.readFileSync(resolvedPath, "utf-8");
|
|
2267
2209
|
const modFile = u.createSourceFile(
|
|
@@ -2294,16 +2236,12 @@ function resolveContractPath(contract, context) {
|
|
|
2294
2236
|
}
|
|
2295
2237
|
async function checkComponentContractConsistency(contract, context, result) {
|
|
2296
2238
|
const componentName = contract.component;
|
|
2297
|
-
if (!componentName)
|
|
2298
|
-
return;
|
|
2239
|
+
if (!componentName) return;
|
|
2299
2240
|
const sourcePath = resolveComponentSourcePath(componentName, context);
|
|
2300
|
-
if (!sourcePath)
|
|
2301
|
-
|
|
2302
|
-
if (!sourcePath.endsWith(".ts"))
|
|
2303
|
-
return;
|
|
2241
|
+
if (!sourcePath) return;
|
|
2242
|
+
if (!sourcePath.endsWith(".ts")) return;
|
|
2304
2243
|
const contractPath = resolveContractPath(contract, context);
|
|
2305
|
-
if (!contractPath)
|
|
2306
|
-
return;
|
|
2244
|
+
if (!contractPath) return;
|
|
2307
2245
|
let contractContent;
|
|
2308
2246
|
try {
|
|
2309
2247
|
contractContent = await fs.promises.readFile(contractPath, "utf-8");
|
|
@@ -2311,8 +2249,7 @@ async function checkComponentContractConsistency(contract, context, result) {
|
|
|
2311
2249
|
return;
|
|
2312
2250
|
}
|
|
2313
2251
|
const parsed = parseContract(contractContent, path.basename(contractPath));
|
|
2314
|
-
if (parsed.validations.length > 0)
|
|
2315
|
-
return;
|
|
2252
|
+
if (parsed.validations.length > 0) return;
|
|
2316
2253
|
let sourceCode;
|
|
2317
2254
|
try {
|
|
2318
2255
|
sourceCode = await fs.promises.readFile(sourcePath, "utf-8");
|
|
@@ -2431,8 +2368,7 @@ async function validatePackageJson(context, result) {
|
|
|
2431
2368
|
}
|
|
2432
2369
|
async function validateDynamicContracts(context, result) {
|
|
2433
2370
|
const { dynamic_contracts } = context.manifest;
|
|
2434
|
-
if (!dynamic_contracts)
|
|
2435
|
-
return;
|
|
2371
|
+
if (!dynamic_contracts) return;
|
|
2436
2372
|
const dynamicConfigs = Array.isArray(dynamic_contracts) ? dynamic_contracts : [dynamic_contracts];
|
|
2437
2373
|
for (const config of dynamicConfigs) {
|
|
2438
2374
|
const prefix = config.prefix || "(unknown)";
|
|
@@ -2511,8 +2447,7 @@ function extractExpressions(text) {
|
|
|
2511
2447
|
function extractTagPath(expr) {
|
|
2512
2448
|
let cleaned = expr.replace(/^!/, "").trim();
|
|
2513
2449
|
cleaned = cleaned.split(/\s*[!=]==?\s*/)[0].trim();
|
|
2514
|
-
if (cleaned === "." || cleaned === "")
|
|
2515
|
-
return null;
|
|
2450
|
+
if (cleaned === "." || cleaned === "") return null;
|
|
2516
2451
|
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*(\.[a-zA-Z_$][a-zA-Z0-9_$]*)*$/.test(cleaned)) {
|
|
2517
2452
|
return cleaned;
|
|
2518
2453
|
}
|
|
@@ -2611,8 +2546,7 @@ function collectUsedTags(jayHtml) {
|
|
|
2611
2546
|
const ifVal = element.getAttribute?.("if");
|
|
2612
2547
|
if (ifVal) {
|
|
2613
2548
|
const ifPath = extractTagPath(ifVal);
|
|
2614
|
-
if (ifPath)
|
|
2615
|
-
resolvePath(ifPath, scopes);
|
|
2549
|
+
if (ifPath) resolvePath(ifPath, scopes);
|
|
2616
2550
|
}
|
|
2617
2551
|
const refVal = element.getAttribute?.("ref");
|
|
2618
2552
|
if (refVal) {
|
|
@@ -2620,12 +2554,10 @@ function collectUsedTags(jayHtml) {
|
|
|
2620
2554
|
}
|
|
2621
2555
|
const attrs = element.attributes ?? {};
|
|
2622
2556
|
for (const [name, value] of Object.entries(attrs)) {
|
|
2623
|
-
if (SKIP_ATTRS.has(name))
|
|
2624
|
-
continue;
|
|
2557
|
+
if (SKIP_ATTRS.has(name)) continue;
|
|
2625
2558
|
for (const expr of extractExpressions(value)) {
|
|
2626
2559
|
const p = extractTagPath(expr);
|
|
2627
|
-
if (p)
|
|
2628
|
-
resolvePath(p, scopes);
|
|
2560
|
+
if (p) resolvePath(p, scopes);
|
|
2629
2561
|
}
|
|
2630
2562
|
}
|
|
2631
2563
|
for (const child of element.childNodes ?? []) {
|
|
@@ -2633,8 +2565,7 @@ function collectUsedTags(jayHtml) {
|
|
|
2633
2565
|
const text = child.rawText ?? child.text ?? "";
|
|
2634
2566
|
for (const expr of extractExpressions(text)) {
|
|
2635
2567
|
const p = extractTagPath(expr);
|
|
2636
|
-
if (p)
|
|
2637
|
-
resolvePath(p, childScopes);
|
|
2568
|
+
if (p) resolvePath(p, childScopes);
|
|
2638
2569
|
}
|
|
2639
2570
|
} else if (child.nodeType === 1) {
|
|
2640
2571
|
walkElement(child, childScopes);
|
|
@@ -2647,14 +2578,12 @@ function collectUsedTags(jayHtml) {
|
|
|
2647
2578
|
function analyzeTagCoverage(jayHtml, file) {
|
|
2648
2579
|
const imports = jayHtml.headlessImports;
|
|
2649
2580
|
const withContracts = imports.filter((imp) => imp.contract);
|
|
2650
|
-
if (withContracts.length === 0)
|
|
2651
|
-
return null;
|
|
2581
|
+
if (withContracts.length === 0) return null;
|
|
2652
2582
|
const usedTagsMap = collectUsedTags(jayHtml);
|
|
2653
2583
|
const contracts = [];
|
|
2654
2584
|
for (let i = 0; i < imports.length; i++) {
|
|
2655
2585
|
const imp = imports[i];
|
|
2656
|
-
if (!imp.contract)
|
|
2657
|
-
continue;
|
|
2586
|
+
if (!imp.contract) continue;
|
|
2658
2587
|
const allTags = flattenContractTags(imp.contract.tags);
|
|
2659
2588
|
const usedSet = usedTagsMap.get(i) ?? /* @__PURE__ */ new Set();
|
|
2660
2589
|
const expanded = new Set(usedSet);
|
|
@@ -2683,12 +2612,9 @@ function resolveContractTag(contract, tagPath) {
|
|
|
2683
2612
|
let tags = contract.tags;
|
|
2684
2613
|
for (let i = 0; i < segments.length; i++) {
|
|
2685
2614
|
const tag = tags.find((t) => t.tag === segments[i]);
|
|
2686
|
-
if (!tag)
|
|
2687
|
-
|
|
2688
|
-
if (
|
|
2689
|
-
return tag;
|
|
2690
|
-
if (!tag.tags)
|
|
2691
|
-
return void 0;
|
|
2615
|
+
if (!tag) return void 0;
|
|
2616
|
+
if (i === segments.length - 1) return tag;
|
|
2617
|
+
if (!tag.tags) return void 0;
|
|
2692
2618
|
tags = tag.tags;
|
|
2693
2619
|
}
|
|
2694
2620
|
return void 0;
|
|
@@ -2720,17 +2646,13 @@ function checkRefElementTypes(jayHtml, file) {
|
|
|
2720
2646
|
importIndex = scope.importIndex;
|
|
2721
2647
|
tagPath = scope.prefix ? `${scope.prefix}.${refPath}` : refPath;
|
|
2722
2648
|
}
|
|
2723
|
-
if (importIndex === void 0)
|
|
2724
|
-
return;
|
|
2649
|
+
if (importIndex === void 0) return;
|
|
2725
2650
|
const imp = imports[importIndex];
|
|
2726
|
-
if (!imp.contract)
|
|
2727
|
-
return;
|
|
2651
|
+
if (!imp.contract) return;
|
|
2728
2652
|
const contractTag = resolveContractTag(imp.contract, tagPath);
|
|
2729
|
-
if (!contractTag || !contractTag.elementType)
|
|
2730
|
-
return;
|
|
2653
|
+
if (!contractTag || !contractTag.elementType) return;
|
|
2731
2654
|
const contractTypes = contractTag.elementType;
|
|
2732
|
-
if (contractTypes.includes("HTMLElement"))
|
|
2733
|
-
return;
|
|
2655
|
+
if (contractTypes.includes("HTMLElement")) return;
|
|
2734
2656
|
if (!contractTypes.includes(ref.actualType)) {
|
|
2735
2657
|
const label = imp.key ? `${imp.key}.${tagPath}` : tagPath;
|
|
2736
2658
|
warnings.push(
|
|
@@ -2840,8 +2762,7 @@ function checkRouteParams(parsedFile, filePath, pagesBase) {
|
|
|
2840
2762
|
collectParams(imp.contract.params);
|
|
2841
2763
|
}
|
|
2842
2764
|
}
|
|
2843
|
-
if (requiredParams.size === 0)
|
|
2844
|
-
return [];
|
|
2765
|
+
if (requiredParams.size === 0) return [];
|
|
2845
2766
|
const routeParams = extractRouteParams(filePath, pagesBase);
|
|
2846
2767
|
const headlessProps = extractHeadlessPropsParamNames(parsedFile);
|
|
2847
2768
|
const availableParams = /* @__PURE__ */ new Set([...routeParams, ...headlessProps]);
|
|
@@ -2857,11 +2778,9 @@ function checkRouteParams(parsedFile, filePath, pagesBase) {
|
|
|
2857
2778
|
}
|
|
2858
2779
|
function checkRouteToContractParams(parsedFile, filePath, pagesBase) {
|
|
2859
2780
|
const routeParams = extractRouteParams(filePath, pagesBase);
|
|
2860
|
-
if (routeParams.size === 0)
|
|
2861
|
-
return [];
|
|
2781
|
+
if (routeParams.size === 0) return [];
|
|
2862
2782
|
const hasAnyContract = !!parsedFile.contract || parsedFile.headlessImports.some((imp) => !!imp.contract);
|
|
2863
|
-
if (!hasAnyContract)
|
|
2864
|
-
return [];
|
|
2783
|
+
if (!hasAnyContract) return [];
|
|
2865
2784
|
const declaredParams = /* @__PURE__ */ new Set();
|
|
2866
2785
|
if (parsedFile.contract?.params) {
|
|
2867
2786
|
for (const p of parsedFile.contract.params) {
|
|
@@ -2913,17 +2832,14 @@ function resolveBindingPhase(bindingPath, jayHtml) {
|
|
|
2913
2832
|
const keyedImport = jayHtml.headlessImports.find((i) => i.key === root && i.contract);
|
|
2914
2833
|
if (keyedImport?.contract) {
|
|
2915
2834
|
const tagPath = segments.slice(1).join(".");
|
|
2916
|
-
if (!tagPath)
|
|
2917
|
-
return void 0;
|
|
2835
|
+
if (!tagPath) return void 0;
|
|
2918
2836
|
const tag = resolveContractTag(keyedImport.contract, tagPath);
|
|
2919
|
-
if (!tag)
|
|
2920
|
-
return void 0;
|
|
2837
|
+
if (!tag) return void 0;
|
|
2921
2838
|
return tag.phase || "slow";
|
|
2922
2839
|
}
|
|
2923
2840
|
if (jayHtml.contract) {
|
|
2924
2841
|
const tag = resolveContractTag(jayHtml.contract, bindingPath);
|
|
2925
|
-
if (!tag)
|
|
2926
|
-
return void 0;
|
|
2842
|
+
if (!tag) return void 0;
|
|
2927
2843
|
return tag.phase || "slow";
|
|
2928
2844
|
}
|
|
2929
2845
|
return void 0;
|
|
@@ -2974,15 +2890,12 @@ function checkHeadlessInstanceProps(jayHtml, file) {
|
|
|
2974
2890
|
}
|
|
2975
2891
|
for (const contractProp of contract.props) {
|
|
2976
2892
|
const attrValue = lowerAttrs[contractProp.name.toLowerCase()];
|
|
2977
|
-
if (!attrValue)
|
|
2978
|
-
continue;
|
|
2893
|
+
if (!attrValue) continue;
|
|
2979
2894
|
const bindingMatch = attrValue.match(/^\{(.+)\}$/);
|
|
2980
|
-
if (!bindingMatch)
|
|
2981
|
-
continue;
|
|
2895
|
+
if (!bindingMatch) continue;
|
|
2982
2896
|
const bindingPath = bindingMatch[1];
|
|
2983
2897
|
const sourcePhase = resolveBindingPhase(bindingPath, jayHtml);
|
|
2984
|
-
if (!sourcePhase)
|
|
2985
|
-
continue;
|
|
2898
|
+
if (!sourcePhase) continue;
|
|
2986
2899
|
const propPhase = contractProp.phase ?? "slow";
|
|
2987
2900
|
const sourceOrder = PHASE_ORDER[sourcePhase] ?? 0;
|
|
2988
2901
|
const propOrder = PHASE_ORDER[propPhase] ?? 0;
|
|
@@ -3020,8 +2933,7 @@ function resolveLinkedTags(tags, contractDir) {
|
|
|
3020
2933
|
});
|
|
3021
2934
|
}
|
|
3022
2935
|
function resolveContractLinks(contract, contractPath) {
|
|
3023
|
-
if (!contractPath)
|
|
3024
|
-
return contract;
|
|
2936
|
+
if (!contractPath) return contract;
|
|
3025
2937
|
const contractDir = path.dirname(contractPath);
|
|
3026
2938
|
return { ...contract, tags: resolveLinkedTags(contract.tags, contractDir) };
|
|
3027
2939
|
}
|
|
@@ -3029,8 +2941,7 @@ async function runPluginValidators(projectRoot, parsedFiles, errors, warnings) {
|
|
|
3029
2941
|
const scannedPlugins = await scanPlugins({ projectRoot, includeDevDeps: true });
|
|
3030
2942
|
const loadedValidators = [];
|
|
3031
2943
|
for (const [, plugin] of scannedPlugins) {
|
|
3032
|
-
if (!plugin.manifest.validators)
|
|
3033
|
-
continue;
|
|
2944
|
+
if (!plugin.manifest.validators) continue;
|
|
3034
2945
|
for (const validatorDef of plugin.manifest.validators) {
|
|
3035
2946
|
const source = `${plugin.name}/${validatorDef.name}`;
|
|
3036
2947
|
let validatorFn;
|
|
@@ -3609,8 +3520,7 @@ async function ensureAgentKitDocs(projectRoot, _force, mode) {
|
|
|
3609
3520
|
const sharedDirs = ["contracts"];
|
|
3610
3521
|
for (const dir of sharedDirs) {
|
|
3611
3522
|
const srcDir = path$1.join(templateDir, dir);
|
|
3612
|
-
if (!fsSync.existsSync(srcDir))
|
|
3613
|
-
continue;
|
|
3523
|
+
if (!fsSync.existsSync(srcDir)) continue;
|
|
3614
3524
|
await copyDirRecursive(srcDir, path$1.join(agentKitDir, dir));
|
|
3615
3525
|
getLogger().info(chalk.gray(` Created agent-kit/${dir}/`));
|
|
3616
3526
|
}
|
|
@@ -3635,8 +3545,7 @@ async function mergePluginAgentKitGuides(projectRoot, mode) {
|
|
|
3635
3545
|
const copiedPerRole = /* @__PURE__ */ new Map();
|
|
3636
3546
|
for (const [, plugin] of plugins) {
|
|
3637
3547
|
const pluginAgentKitDir = path$1.join(plugin.pluginPath, "agent-kit");
|
|
3638
|
-
if (!fsSync.existsSync(pluginAgentKitDir))
|
|
3639
|
-
continue;
|
|
3548
|
+
if (!fsSync.existsSync(pluginAgentKitDir)) continue;
|
|
3640
3549
|
for (const role of roles) {
|
|
3641
3550
|
const roleSourceDir = path$1.join(pluginAgentKitDir, role);
|
|
3642
3551
|
let files;
|
|
@@ -3647,8 +3556,7 @@ async function mergePluginAgentKitGuides(projectRoot, mode) {
|
|
|
3647
3556
|
} catch {
|
|
3648
3557
|
continue;
|
|
3649
3558
|
}
|
|
3650
|
-
if (files.length === 0)
|
|
3651
|
-
continue;
|
|
3559
|
+
if (files.length === 0) continue;
|
|
3652
3560
|
const roleOutputDir = path$1.join(agentKitDir, role);
|
|
3653
3561
|
await fs$1.mkdir(roleOutputDir, { recursive: true });
|
|
3654
3562
|
for (const filename of files) {
|
|
@@ -3671,8 +3579,7 @@ async function mergePluginAgentKitGuides(projectRoot, mode) {
|
|
|
3671
3579
|
}
|
|
3672
3580
|
} catch {
|
|
3673
3581
|
}
|
|
3674
|
-
if (!copiedPerRole.has(role))
|
|
3675
|
-
copiedPerRole.set(role, []);
|
|
3582
|
+
if (!copiedPerRole.has(role)) copiedPerRole.set(role, []);
|
|
3676
3583
|
copiedPerRole.get(role).push({ filename, pluginName: plugin.name, description });
|
|
3677
3584
|
getLogger().info(
|
|
3678
3585
|
chalk.gray(
|
|
@@ -3684,8 +3591,7 @@ async function mergePluginAgentKitGuides(projectRoot, mode) {
|
|
|
3684
3591
|
}
|
|
3685
3592
|
for (const [role, entries] of copiedPerRole) {
|
|
3686
3593
|
const instructionsPath = path$1.join(agentKitDir, role, "INSTRUCTIONS.md");
|
|
3687
|
-
if (!fsSync.existsSync(instructionsPath))
|
|
3688
|
-
continue;
|
|
3594
|
+
if (!fsSync.existsSync(instructionsPath)) continue;
|
|
3689
3595
|
const lines = [
|
|
3690
3596
|
"",
|
|
3691
3597
|
"## Plugin-Contributed Guides",
|
|
@@ -3707,8 +3613,7 @@ async function generatePluginAgentKit(projectRoot, options, initErrors, viteServ
|
|
|
3707
3613
|
verbose: options.verbose,
|
|
3708
3614
|
pluginFilter: options.plugin
|
|
3709
3615
|
});
|
|
3710
|
-
if (plugins.length === 0)
|
|
3711
|
-
return;
|
|
3616
|
+
if (plugins.length === 0) return;
|
|
3712
3617
|
const logger = getLogger();
|
|
3713
3618
|
logger.important("");
|
|
3714
3619
|
logger.important(chalk.bold("Generating plugin agent-kit data..."));
|
|
@@ -3937,20 +3842,17 @@ function createAnswersFilePrompt(answers, pluginName) {
|
|
|
3937
3842
|
return {
|
|
3938
3843
|
async input(options) {
|
|
3939
3844
|
const value = answers[options.key];
|
|
3940
|
-
if (value !== void 0)
|
|
3941
|
-
return value;
|
|
3845
|
+
if (value !== void 0) return value;
|
|
3942
3846
|
throw new SetupNeedsAnswerError(pluginName, options.key, "input", options.message);
|
|
3943
3847
|
},
|
|
3944
3848
|
async confirm(options) {
|
|
3945
3849
|
const value = answers[options.key];
|
|
3946
|
-
if (value !== void 0)
|
|
3947
|
-
return value === "true" || value === "yes";
|
|
3850
|
+
if (value !== void 0) return value === "true" || value === "yes";
|
|
3948
3851
|
throw new SetupNeedsAnswerError(pluginName, options.key, "confirm", options.message);
|
|
3949
3852
|
},
|
|
3950
3853
|
async select(options) {
|
|
3951
3854
|
const value = answers[options.key];
|
|
3952
|
-
if (value !== void 0)
|
|
3953
|
-
return value;
|
|
3855
|
+
if (value !== void 0) return value;
|
|
3954
3856
|
throw new SetupNeedsAnswerError(
|
|
3955
3857
|
pluginName,
|
|
3956
3858
|
options.key,
|
|
@@ -4111,12 +4013,9 @@ async function runSetup(pluginFilter, options, projectRoot) {
|
|
|
4111
4013
|
}
|
|
4112
4014
|
await runProjectInit(projectRoot, viteServer);
|
|
4113
4015
|
const parts = [];
|
|
4114
|
-
if (configured > 0)
|
|
4115
|
-
|
|
4116
|
-
if (
|
|
4117
|
-
parts.push(`${needsConfig} needs config`);
|
|
4118
|
-
if (errors > 0)
|
|
4119
|
-
parts.push(`${errors} error(s)`);
|
|
4016
|
+
if (configured > 0) parts.push(`${configured} configured`);
|
|
4017
|
+
if (needsConfig > 0) parts.push(`${needsConfig} needs config`);
|
|
4018
|
+
if (errors > 0) parts.push(`${errors} error(s)`);
|
|
4120
4019
|
logger.important(`Setup complete: ${parts.join(", ")}`);
|
|
4121
4020
|
if (errors > 0) {
|
|
4122
4021
|
process.exit(1);
|
|
@@ -4135,8 +4034,7 @@ async function runSetup(pluginFilter, options, projectRoot) {
|
|
|
4135
4034
|
}
|
|
4136
4035
|
async function initPlugin(pluginName, allPluginsWithInit, viteServer, logger) {
|
|
4137
4036
|
const pluginInit = allPluginsWithInit.filter((p) => p.name === pluginName);
|
|
4138
|
-
if (pluginInit.length === 0)
|
|
4139
|
-
return;
|
|
4037
|
+
if (pluginInit.length === 0) return;
|
|
4140
4038
|
const initErrors = await executePluginServerInits(pluginInit, viteServer, false, true);
|
|
4141
4039
|
if (initErrors.size > 0) {
|
|
4142
4040
|
for (const [, err] of initErrors) {
|
|
@@ -4276,8 +4174,7 @@ function printCommandList(commands) {
|
|
|
4276
4174
|
logger.important("\nAvailable plugin commands:\n");
|
|
4277
4175
|
const byPlugin = /* @__PURE__ */ new Map();
|
|
4278
4176
|
for (const cmd of commands) {
|
|
4279
|
-
if (!byPlugin.has(cmd.pluginName))
|
|
4280
|
-
byPlugin.set(cmd.pluginName, []);
|
|
4177
|
+
if (!byPlugin.has(cmd.pluginName)) byPlugin.set(cmd.pluginName, []);
|
|
4281
4178
|
byPlugin.get(cmd.pluginName).push(cmd);
|
|
4282
4179
|
}
|
|
4283
4180
|
for (const [pluginName, cmds] of byPlugin) {
|
|
@@ -4333,8 +4230,7 @@ program.command("build").description("Build production artifacts").option("-p, -
|
|
|
4333
4230
|
await runBuild(options.path, options);
|
|
4334
4231
|
} catch (error) {
|
|
4335
4232
|
getLogger().error(chalk.red("Build failed:") + " " + error.message);
|
|
4336
|
-
if (error.stack)
|
|
4337
|
-
getLogger().error(error.stack);
|
|
4233
|
+
if (error.stack) getLogger().error(error.stack);
|
|
4338
4234
|
process.exit(1);
|
|
4339
4235
|
}
|
|
4340
4236
|
});
|
|
@@ -4343,8 +4239,7 @@ program.command("serve").description("Start production server").option("-p, --pa
|
|
|
4343
4239
|
await runServe(options.path, options);
|
|
4344
4240
|
} catch (error) {
|
|
4345
4241
|
getLogger().error(chalk.red("Server failed:") + " " + error.message);
|
|
4346
|
-
if (error.stack)
|
|
4347
|
-
getLogger().error(error.stack);
|
|
4242
|
+
if (error.stack) getLogger().error(error.stack);
|
|
4348
4243
|
process.exit(1);
|
|
4349
4244
|
}
|
|
4350
4245
|
});
|
|
@@ -4353,8 +4248,7 @@ program.command("rebuild").description("Rebuild instances by contract, route, or
|
|
|
4353
4248
|
await runRebuild(options.path, options);
|
|
4354
4249
|
} catch (error) {
|
|
4355
4250
|
getLogger().error(chalk.red("Rebuild failed:") + " " + error.message);
|
|
4356
|
-
if (error.stack)
|
|
4357
|
-
getLogger().error(error.stack);
|
|
4251
|
+
if (error.stack) getLogger().error(error.stack);
|
|
4358
4252
|
process.exit(1);
|
|
4359
4253
|
}
|
|
4360
4254
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/jay-stack-cli",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@inquirer/prompts": "^8.5.2",
|
|
28
|
-
"@jay-framework/compiler-jay-html": "^0.23.
|
|
29
|
-
"@jay-framework/compiler-shared": "^0.23.
|
|
30
|
-
"@jay-framework/dev-server": "^0.23.
|
|
31
|
-
"@jay-framework/fullstack-component": "^0.23.
|
|
32
|
-
"@jay-framework/logger": "^0.23.
|
|
33
|
-
"@jay-framework/plugin-validator": "^0.23.
|
|
34
|
-
"@jay-framework/production-server": "^0.23.
|
|
35
|
-
"@jay-framework/stack-server-runtime": "^0.23.
|
|
28
|
+
"@jay-framework/compiler-jay-html": "^0.23.1",
|
|
29
|
+
"@jay-framework/compiler-shared": "^0.23.1",
|
|
30
|
+
"@jay-framework/dev-server": "^0.23.1",
|
|
31
|
+
"@jay-framework/fullstack-component": "^0.23.1",
|
|
32
|
+
"@jay-framework/logger": "^0.23.1",
|
|
33
|
+
"@jay-framework/plugin-validator": "^0.23.1",
|
|
34
|
+
"@jay-framework/production-server": "^0.23.1",
|
|
35
|
+
"@jay-framework/stack-server-runtime": "^0.23.1",
|
|
36
36
|
"chalk": "^4.1.2",
|
|
37
37
|
"commander": "^14.0.0",
|
|
38
38
|
"express": "^5.0.1",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"yaml": "^2.3.4"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@jay-framework/dev-environment": "^0.23.
|
|
46
|
+
"@jay-framework/dev-environment": "^0.23.1",
|
|
47
47
|
"@types/express": "^5.0.2",
|
|
48
48
|
"@types/node": "^22.15.21",
|
|
49
49
|
"nodemon": "^3.0.3",
|