@jskit-ai/agent-docs 0.1.27 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/DISTR_AGENT.md +1 -0
  2. package/guide/agent/app-extras/assistant.md +2 -2
  3. package/guide/agent/app-extras/mobile-capacitor.md +10 -3
  4. package/guide/agent/app-extras/realtime.md +11 -11
  5. package/guide/agent/app-setup/a-more-interesting-shell.md +52 -44
  6. package/guide/agent/app-setup/authentication.md +40 -22
  7. package/guide/agent/app-setup/console.md +5 -5
  8. package/guide/agent/app-setup/database-layer.md +15 -15
  9. package/guide/agent/app-setup/initial-scaffolding.md +37 -5
  10. package/guide/agent/app-setup/multi-homing.md +28 -28
  11. package/guide/agent/app-setup/users.md +22 -22
  12. package/guide/agent/app-setup/working-with-the-jskit-cli.md +13 -6
  13. package/guide/agent/generators/advanced-cruds.md +111 -68
  14. package/guide/agent/generators/crud-generators.md +5 -5
  15. package/guide/agent/generators/ui-generators.md +15 -13
  16. package/guide/agent/index.md +1 -1
  17. package/package.json +1 -1
  18. package/patterns/INDEX.md +4 -1
  19. package/patterns/client-requests.md +23 -6
  20. package/patterns/crud-repository-mapping.md +1 -1
  21. package/patterns/crud-scaffolding.md +10 -1
  22. package/patterns/filters.md +28 -10
  23. package/patterns/generated-ui-contract-tracking.md +62 -0
  24. package/patterns/page-scaffolding.md +17 -0
  25. package/patterns/placements.md +60 -0
  26. package/patterns/surfaces.md +5 -1
  27. package/patterns/ui-testing.md +3 -0
  28. package/reference/autogen/KERNEL_MAP.md +30 -1
  29. package/reference/autogen/packages/assistant.md +1 -1
  30. package/reference/autogen/packages/crud-ui-generator.md +19 -8
  31. package/reference/autogen/packages/kernel.md +38 -6
  32. package/reference/autogen/packages/realtime.md +1 -0
  33. package/reference/autogen/packages/shell-web.md +35 -3
  34. package/reference/autogen/packages/ui-generator.md +26 -5
  35. package/reference/autogen/packages/users-core.md +2 -0
  36. package/reference/autogen/packages/users-web.md +92 -3
  37. package/reference/autogen/packages/workspaces-web.md +3 -1
  38. package/reference/autogen/tooling/jskit-cli.md +24 -8
  39. package/templates/app/AGENTS.md +1 -0
  40. package/workflow/bootstrap.md +1 -0
@@ -17,6 +17,10 @@ Use this on demand; do not load the full index at startup.
17
17
  ### `src/server/buildTemplateContext.js`
18
18
  Exports
19
19
  - `buildUiPageTemplateContext({ appRoot, targetFile = "", options = {} } = {})`
20
+ - `normalizeNavigationRole`
21
+ - `resolveNavigationInferenceRoutePath(pageTarget = {})`
22
+ - `resolveNavigationRoleLinkPlacement(options = {}, inferenceContext = {})`
23
+ - `shouldCreateNavigationLink(options = {}, inferenceContext = {})`
20
24
  Local functions
21
25
  - `resolveLinkToPropLine(linkTo = "")`
22
26
  - `resolveOwnerLine(owner = "")`
@@ -44,14 +48,23 @@ Local functions
44
48
  - `applyScriptImports(source = "")`
45
49
  - `createOutletBlock({ target = "" } = {})`
46
50
  - `resolveOutletOwner(target = "")`
47
- - `resolveSemanticPlacementOption(options = {})`
48
- - `resolveSemanticPlacementOwner({ placementId = "", targetId = "", owner = "" } = {})`
51
+ - `resolveSemanticPlacementOption(options = {}, { context = "ui-generator outlet" } = {})`
52
+ - `resolveOptionalSemanticPlacementOption(options = {}, { context = "ui-generator outlet" } = {})`
53
+ - `resolveVariantOwners(variantTargets = {})`
54
+ - `resolveSemanticPlacementOwner({ placementId = "", targetId = "", variantTargets = null, owner = "", context = "ui-generator outlet" } = {})`
55
+ - `resolveTopologyKind(options = {}, { context = "ui-generator outlet", defaultKind = "", required = false } = {})`
56
+ - `resolveTopologyVariantTargets(options = {}, { context = "ui-generator topology", fallbackTarget = "" } = {})`
57
+ - `hasTopologyOptions(options = {})`
49
58
  - `resolveTopologySurfaces(options = {})`
50
59
  - `renderTopologyOwnerLine(owner = "")`
51
60
  - `renderLinkRendererBlock(rendererToken = "")`
52
- - `renderOutletTopologyBlock({ marker = "", placementId = "", owner = "", surfaces = ["*"], description = "", target = "", rendererToken = "" } = {})`
61
+ - `renderTopologyVariantBlock({ layoutClass = "", target = "", kind = "", rendererToken = "" } = {})`
62
+ - `renderOutletTopologyBlock({ marker = "", placementId = "", owner = "", surfaces = ["*"], description = "", target = "", variantTargets = null, kind = "link", rendererToken = "" } = {})`
53
63
  - `findLastTemplateCloseTag(source = "")`
54
64
  - `applyOutletTemplateBlock(source = "", { target = "" } = {})`
65
+ - `prepareTopologyBlock({ appRoot, topologyPath = null, context = "ui-generator topology", placementId = "", owner = "", surfaces = ["*"], description = "", target = "", variantTargets = null, kind = "", rendererToken = "" } = {})`
66
+ - `applyTopologyBlock(options = {})`
67
+ - `runTopologySubcommand({ appRoot, options = {}, dryRun = false } = {})`
55
68
 
56
69
  ### `src/server/subcommands/page.js`
57
70
  Exports
@@ -69,11 +82,12 @@ Exports
69
82
  - `resolvePageTargetDetails`
70
83
  - `resolveNearestParentSubpagesHost`
71
84
  - `deriveDefaultSubpagesHost`
72
- - `renderPlainPageSource(pageTitle = "")`
85
+ - `renderPlainPageSource(pageTitle = "", { surfaceId = "", routePath = "" } = {})`
73
86
  - `ensureSubpagesSupportScaffold({ appRoot, componentDirectory = DEFAULT_COMPONENT_DIRECTORY, dryRun = false } = {})`
74
87
  - `applySubpagesUpgradeToPageSource(source = "", { target = "", title = "", subtitle = "", sectionContainerComponentImportPath = "/src/components/SectionContainerShell.vue", preserveExistingContent = true } = {})`
75
88
  - `upgradePageFileToSubpages({ appRoot, targetFile, target = "", title = "", subtitle = "", componentDirectory = DEFAULT_COMPONENT_DIRECTORY, preserveExistingContent = true, dryRun = false } = {})`
76
89
  Local functions
90
+ - `resolveGeneratedPageSurfaceProfile({ surfaceId = "", routePath = "" } = {})`
77
91
  - `trimEdgeBlankLines(source = "")`
78
92
  - `renderSectionContainerShellSource()`
79
93
  - `findTemplateBlock(source = "")`
@@ -101,9 +115,16 @@ Exports
101
115
  - `appendBlockIfMarkerMissing(source = "", marker = "", block = "")`
102
116
  - `insertImportIfMissing(source = "", importLine = "")`
103
117
  - `insertBeforeClassDeclaration(source = "", line = "", { className = "", contextFile = "" } = {})`
104
- - `findScriptBlock(source = "")`
118
+ - `findScriptSetupBlock(source = "")`
119
+ - `insertScriptSetupBlock(source = "", content = "")`
120
+ - `appendTopologyBlockIfPlacementMissing({ topologyPath = {}, source = "", marker = "", block = "", placementId = "", owner = "", variantTargets = null, context = "ui-generator topology" } = {})`
105
121
  - `parseTagAttributes(attributesSource = "")`
106
122
  - `indentBlock(source = "", indent = "")`
123
+ Local functions
124
+ - `loadPlacementTopologyDefinitionFromPath(topologyPath = {}, { context = "ui-generator topology" } = {})`
125
+ - `normalizeExpectedTopologyVariantTargets(variantTargets = null)`
126
+ - `describeTopologyVariantTargets(variantTargets = {})`
127
+ - `placementMatchesExpectedVariantTargets(placement = {}, expectedVariantTargets = null)`
107
128
 
108
129
  ### root
109
130
 
@@ -289,6 +289,8 @@ Exports
289
289
  ### `templates/packages/users-workspace/src/server/actions.js`
290
290
  Exports
291
291
  - `createActions({ surface } = {})`
292
+ Local functions
293
+ - `buildListQuery(input = {})`
292
294
 
293
295
  ### `templates/packages/users-workspace/src/server/registerRoutes.js`
294
296
  Exports
@@ -28,6 +28,12 @@ Exports
28
28
  - `createUsersBootstrapUserHandler()`
29
29
  - `registerUsersBootstrapPayloadHandlers(app)`
30
30
 
31
+ ### `src/client/bulkActions.js`
32
+ Exports
33
+ - `defineCrudListBulkActions(actions = [])`
34
+ Local functions
35
+ - `normalizeCrudListBulkAction(rawAction = {}, index = 0)`
36
+
31
37
  ### `src/client/components/AccountSettingsClientElement.vue`
32
38
  Exports
33
39
  - None
@@ -35,6 +41,44 @@ Local functions
35
41
  - `normalizeSection(value)`
36
42
  - `readRouteSection()`
37
43
 
44
+ ### `src/client/components/CrudAddEditScreen.vue`
45
+ Exports
46
+ - None
47
+ Local functions
48
+ - `resolveFieldErrors(fieldKey)`
49
+ - `resolveCancelTo(target = cancelTo.value)`
50
+
51
+ ### `src/client/components/CrudListBulkActionSurface.vue`
52
+ Exports
53
+ - None
54
+ Local functions
55
+ - `clearSelection()`
56
+ - `execute(action = {})`
57
+ - `isActionDisabled(action = {})`
58
+ - `isActionExecuting(action = {})`
59
+
60
+ ### `src/client/components/CrudListFilterSurface.vue`
61
+ Exports
62
+ - None
63
+ Local functions
64
+ - `optionItems(filter = {})`
65
+ - `placeholder(filter = {}, fallback = "")`
66
+ - `clearChip(chip = {})`
67
+ - `clearFilters()`
68
+
69
+ ### `src/client/components/CrudListScreen.vue`
70
+ Exports
71
+ - None
72
+ Local functions
73
+ - `resolveListRecordTitle(record)`
74
+ - `formatListCardValue(value)`
75
+ - `resolveViewLocation(record)`
76
+ - `resolveEditLocation(record)`
77
+
78
+ ### `src/client/components/CrudViewScreen.vue`
79
+ Exports
80
+ - None
81
+
38
82
  ### `src/client/components/ProfileClientElement.vue`
39
83
  Exports
40
84
  - None
@@ -226,7 +270,7 @@ Exports
226
270
  ### `src/client/composables/runtime/operationUiHelpers.js`
227
271
  Exports
228
272
  - `setupRouteChangeCleanup({ enabled = true, route = null, feedback = null, fieldBag = null } = {})`
229
- - `setupOperationErrorReporting({ enabled = true, source = "users-web.operation", loadError = null, notFoundError = null, loadActionFactory = null, notFoundActionFactory = null, loadChannel = "banner", notFoundChannel = "banner", loadSeverity = "error", notFoundSeverity = "warning", dedupeWindowMs = 2000 } = {})`
273
+ - `setupOperationErrorReporting({ enabled = true, source = "users-web.operation", loadError = null, notFoundError = null, loadActionFactory = null, notFoundActionFactory = null, loadChannel = "", notFoundChannel = "", loadSeverity = "error", notFoundSeverity = "warning", dedupeWindowMs = 2000 } = {})`
230
274
  Local functions
231
275
  - `normalizeMessage(value)`
232
276
 
@@ -246,7 +290,7 @@ Exports
246
290
  Exports
247
291
  - `buildEndpointReadRequestOptions({ method = "GET", query = null, transport = null } = {})`
248
292
  - `buildEndpointWriteRequestOptions({ method = "PATCH", body = undefined, options = null, transport = null } = {})`
249
- - `useEndpointResource({ queryKey, path = "", enabled = true, client = usersWebHttpClient, readMethod = "GET", writeMethod = "PATCH", readQuery = null, transport = null, queryOptions = null, mutationOptions = null, fallbackLoadError = "Unable to load resource.", fallbackSaveError = "Unable to save resource." } = {})`
293
+ - `useEndpointResource({ queryKey, path = "", enabled = true, client = usersWebHttpClient, readMethod = "GET", writeMethod = "PATCH", readQuery = null, transport = null, refreshOnPull = false, queryOptions = null, mutationOptions = null, fallbackLoadError = "Unable to load resource.", fallbackSaveError = "Unable to save resource." } = {})`
250
294
  Local functions
251
295
  - `resolveRequestQuery(value = null)`
252
296
 
@@ -265,7 +309,7 @@ Local functions
265
309
 
266
310
  ### `src/client/composables/runtime/useUiFeedback.js`
267
311
  Exports
268
- - `useUiFeedback({ initialType = "success", source = "users-web.ui-feedback", successChannel = "snackbar", errorChannel = "banner", dedupeWindowMs = 2000 } = {})`
312
+ - `useUiFeedback({ initialType = "success", source = "users-web.ui-feedback", successChannel = "", errorChannel = "", dedupeWindowMs = 2000 } = {})`
269
313
 
270
314
  ### `src/client/composables/runtime/useViewCore.js`
271
315
  Exports
@@ -337,6 +381,7 @@ Exports
337
381
  ### `src/client/composables/support/resourceLoadStateHelpers.js`
338
382
  Exports
339
383
  - `hasResolvedQueryData({ query = null, data = null } = {})`
384
+ - `mergeQueryMeta(queryOptions = null, meta = {})`
340
385
 
341
386
  ### `src/client/composables/support/routeTemplateHelpers.js`
342
387
  Exports
@@ -388,6 +433,19 @@ Exports
388
433
  Exports
389
434
  - `useCommand({ ownershipFilter = ROUTE_VISIBILITY_WORKSPACE, surfaceId = "", access = "auto", apiSuffix = "", runPermissions = [], writeMethod = "POST", transport = null, placementSource = "users-web.command", fallbackRunError = "Unable to complete action.", fieldErrorKeys = [], clearOnRouteChange = true, model, input, buildRawPayload, buildCommandPayload, buildCommandOptions, onRunSuccess, onRunError, suppressSuccessMessage = false, messages = {}, realtime = null } = {})`
390
435
 
436
+ ### `src/client/composables/useCrudAddEditScreen.js`
437
+ Exports
438
+ - `useCrudAddEditScreen({ screen = null, mode = "new", title = "", subtitle = "", saveLabel = "Save", cancelTo = "", resource = null, operationName = "", formFields = [], addEditOptions = {}, saveSuccess = {}, fieldBinding = null, createModel = null, buildPayload = null, mapPayloadToModel = null, input = null, preserveCancelQuery = false } = {})`
439
+ Local functions
440
+ - `normalizeProvidedScreen(screen = null)`
441
+
442
+ ### `src/client/composables/useCrudListBulkActions.js`
443
+ Exports
444
+ - `useCrudListBulkActions(actions = [], { resolveRecordId = null, resolveContext = null } = {})`
445
+ Local functions
446
+ - `normalizeSelectedId(value = "")`
447
+ - `resolveActionKey(actionOrKey = "")`
448
+
391
449
  ### `src/client/composables/useCrudListFilterLookups.js`
392
450
  Exports
393
451
  - `useCrudListFilterLookups(definitions = {}, { values = {}, adapter = null, recordIdParam = "recordId", queryKeyPrefix = [], placementSourcePrefix = "", requestQueryParams = {}, labelResolvers = {} } = {})`
@@ -412,6 +470,16 @@ Exports
412
470
  Local functions
413
471
  - `normalizeQueryKeyPrefix(value = [])`
414
472
 
473
+ ### `src/client/composables/useCrudListScreen.js`
474
+ Exports
475
+ - `useCrudListScreen({ adapter = null, resource = null, resourceNamespace = "resource", apiSuffix = "", recordIdParam = "recordId", recordIdSelector = null, titleFallbackFieldKey = "", viewUrlTemplate = "", editUrlTemplate = "", newUrlTemplate = "", recordChangedEvents = [], listFilters = {}, listBulkActions = [], routeQueryBlacklist = Object.freeze(["include", "cursor", "limit"]), fallbackLoadError = "Unable to load records." } = {})`
476
+ Local functions
477
+ - `formatCrudListCardValue(value)`
478
+
479
+ ### `src/client/composables/useCrudViewScreen.js`
480
+ Exports
481
+ - `useCrudViewScreen({ adapter = null, resource = null, resourceNamespace = "resource", apiUrlTemplate = "", recordIdParam = "recordId", titleFallbackFieldKey = "", listUrlTemplate = "", editUrlTemplate = "", recordChangedEvent = "", fallbackLoadError = "Unable to load record.", notFoundMessage = "Record not found." } = {})`
482
+
415
483
  ### `src/client/composables/usePagedCollection.js`
416
484
  Exports
417
485
  - `usePagedCollection({ queryKey, enabled = true, initialPageParam = null, queryFn, getNextPageParam = defaultGetNextPageParam, selectItems = defaultSelectItems, dedupeBy = null, queryOptions = null, fallbackLoadError = "Unable to load list." } = {})`
@@ -450,10 +518,31 @@ Local functions
450
518
  Exports
451
519
  - `useSurfaceRouteContext()`
452
520
 
521
+ ### `src/client/filters.js`
522
+ Exports
523
+ - `CRUD_LIST_FILTER_TYPE_FLAG`
524
+ - `CRUD_LIST_FILTER_TYPE_ENUM`
525
+ - `CRUD_LIST_FILTER_TYPE_ENUM_MANY`
526
+ - `CRUD_LIST_FILTER_TYPE_RECORD_ID`
527
+ - `CRUD_LIST_FILTER_TYPE_RECORD_ID_MANY`
528
+ - `CRUD_LIST_FILTER_TYPE_DATE`
529
+ - `CRUD_LIST_FILTER_TYPE_DATE_RANGE`
530
+ - `CRUD_LIST_FILTER_TYPE_NUMBER_RANGE`
531
+ - `CRUD_LIST_FILTER_TYPE_PRESENCE`
532
+ - `CRUD_LIST_FILTER_PRESENCE_PRESENT`
533
+ - `CRUD_LIST_FILTER_PRESENCE_MISSING`
534
+ - `CRUD_LIST_FILTER_PRESENCE_OPTIONS`
535
+ - `defineCrudListFilters`
536
+
453
537
  ### `src/client/index.js`
454
538
  Exports
455
539
  - `UsersWebClientProvider`
456
540
  - `AccountSettingsClientElement`
541
+ - `CrudAddEditScreen`
542
+ - `CrudListBulkActionSurface`
543
+ - `CrudListFilterSurface`
544
+ - `CrudListScreen`
545
+ - `CrudViewScreen`
457
546
  - `clientProviders`
458
547
 
459
548
  ### `src/client/lib/bootstrap.js`
@@ -89,6 +89,7 @@ Local functions
89
89
  - `normalizeInvites(entries)`
90
90
  - `latestPage(pages)`
91
91
  - `applyWorkspaceSettingsPolicy(payload = {})`
92
+ - `refreshLoad()`
92
93
  - `submitInvite()`
93
94
  - `submitRevokeInvite(inviteId)`
94
95
  - `submitMemberRoleUpdate(member, roleSid)`
@@ -103,7 +104,7 @@ Exports
103
104
  - None
104
105
  Local functions
105
106
  - `normalizePendingInvite(entry)`
106
- - `reportFeedback({ message, severity = "error", channel = "banner", dedupeKey = "" } = {})`
107
+ - `reportFeedback({ message, severity = "error", channel = "", dedupeKey = "" } = {})`
107
108
  - `workspaceInitials(workspace)`
108
109
  - `workspaceAvatarStyle(workspace)`
109
110
  - `workspaceHomePath(workspaceSlug)`
@@ -112,6 +113,7 @@ Local functions
112
113
  - `acceptInvite(invite)`
113
114
  - `refuseInvite(invite)`
114
115
  - `createWorkspace()`
116
+ - `refreshBootstrap()`
115
117
 
116
118
  ### `src/client/components/WorkspaceSettingsClientElement.vue`
117
119
  Exports
@@ -440,16 +440,29 @@ Local functions
440
440
  - `resolveGeneratorDescription(packageEntry = {})`
441
441
  - `resolveGeneratorQuickStartRows(packageEntry = {}, { limit = 3 } = {})`
442
442
  - `isLinkItemToken(token = "")`
443
+ - `collectPlacementRendererKinds(placementTarget = {})`
444
+ - `collectPlacementConcreteOutlets(placementTarget = {})`
445
+ - `classifyPlacementTarget(placementTarget = {})`
446
+ - `createConcreteTargetSourcePathMap(concreteTargets = [])`
447
+ - `resolveChildPagePatternFromHostSourcePath(sourcePath = "")`
448
+ - `resolveOwnerScopedChildPagePattern(placementTarget = {}, concreteSourcePathByTarget = new Map())`
449
+ - `createPlacementTargetSummary(placementTarget = {}, color, { concreteSourcePathByTarget = new Map() } = {})`
450
+ - `appendPlacementLayoutDetails(lines, placementTarget = {}, color)`
451
+ - `collectMappedConcreteOutletIds(semanticPlacements = [])`
452
+ - `resolveUnmappedConcreteTargets({ semanticPlacements = [], concreteTargets = [] } = {})`
453
+ - `formatPlacementGuidanceLine(line = "", color)`
454
+ - `appendPlacementGroup(lines, { color, title = "", description = "", guidance = [], targets = [], concreteSourcePathByTarget = new Map(), showLayoutDetails = false } = {})`
455
+ - `appendUnmappedConcreteTargetWarnings(lines, { color, concreteTargets = [] } = {})`
456
+ - `appendSemanticPlacementGroups(lines, { color, semanticPlacements = [], concreteTargets = [], showLayoutDetails = false } = {})`
443
457
  - `readFileIfExists(filePath = "")`
444
458
  - `resolveDescriptorFromLockEntry({ appRoot = "", packageId = "", installedPackageEntry = {} } = {})`
445
459
  - `collectProviderSourceFiles(rootPath = "")`
446
460
 
447
461
  ### `src/server/commandHandlers/mobile.js`
448
462
  Exports
449
- - `createMobileCommands(ctx = {}, { commandAdd } = {})`
463
+ - `createMobileCommands(ctx = {})`
450
464
  Local functions
451
465
  - `collectManagedMobileFileDriftIssues({ ctx, appRoot, issues = [] } = {})`
452
- - `collectMissingInstalledDependencyNames(ctx, appRoot = "", packageJson = {})`
453
466
  - `renderAndroidMobileCommandList(lines, color)`
454
467
  - `renderMobileHelp(stream, definition = null, platform = "")`
455
468
  - `isValidHttpOrHttpsUrl(value = "")`
@@ -462,17 +475,19 @@ Local functions
462
475
  - `resolveAndroidDeviceTarget({ ctx, appRoot, explicitTarget = "", commandLabel = "this mobile command" } = {})`
463
476
  - `resolveInstalledMobileConfigForCommand({ appRoot, createCliError } = {})`
464
477
  - `runLocalBinary(binaryName, args = [], { appRoot, cwd = appRoot, env = {}, stderr, stdout, pathModule, createCliError, dryRun = false } = {})`
465
- - `runMobileAppInstall({ ctx, appRoot, stdout, stderr, dryRun = false, devlinks = false } = {})`
466
- - `refreshManagedMobileFiles({ ctx, commandAdd, appRoot, options = {}, stdout, stderr } = {})`
467
- - `runMobileSyncAndroidCommand({ ctx, commandAdd, appRoot, options = {}, stdout, stderr })`
468
- - `runMobileRunAndroidCommand({ ctx, commandAdd, appRoot, options = {}, stdout, stderr })`
478
+ - `hasPackageDependency(packageJson = {}, packageId = "")`
479
+ - `readJsonFileForMobileCommand(filePath = "", label = "", createCliError)`
480
+ - `assertMobileRuntimePackageInstalled({ ctx, appRoot } = {})`
481
+ - `refreshManagedMobileFiles({ ctx, appRoot, options = {}, stdout } = {})`
482
+ - `runMobileSyncAndroidCommand({ ctx, appRoot, options = {}, stdout, stderr })`
483
+ - `runMobileRunAndroidCommand({ ctx, appRoot, options = {}, stdout, stderr })`
469
484
  - `runCapRunAndroidCommand({ ctx, appRoot, pathModule, target = "", stdout, stderr, dryRun = false } = {})`
470
- - `runMobileBuildAndroidCommand({ ctx, commandAdd, appRoot, options = {}, stdout, stderr })`
485
+ - `runMobileBuildAndroidCommand({ ctx, appRoot, options = {}, stdout, stderr })`
471
486
  - `runMobileDoctorCommand({ ctx, appRoot, stdout })`
472
487
  - `runMobileDevicesAndroidCommand({ ctx, appRoot, stdout })`
473
488
  - `runMobileTunnelAndroidCommand({ ctx, appRoot, options = {}, stdout })`
474
489
  - `runMobileRestartAndroidCommand({ ctx, appRoot, options = {}, stdout })`
475
- - `runMobileDevAndroidCommand({ ctx, commandAdd, appRoot, options = {}, stdout, stderr })`
490
+ - `runMobileDevAndroidCommand({ ctx, appRoot, options = {}, stdout, stderr })`
476
491
 
477
492
  ### `src/server/commandHandlers/mobileCommandCatalog.js`
478
493
  Exports
@@ -487,6 +502,7 @@ Exports
487
502
  - `ANDROID_DIRECTORY_NAME`
488
503
  - `ANDROID_MANIFEST_RELATIVE_PATH`
489
504
  - `buildManagedMobileConfigStub({ packageJson = {} } = {})`
505
+ - `isEmptyDisabledMobileConfigPlaceholder(mobileConfig = {})`
490
506
  - `resolveInstalledMobileConfig(appRoot = "")`
491
507
  - `resolveAndroidSdkDetails({ appRoot = "" } = {})`
492
508
  - `collectAndroidSdkComponentIssues({ appRoot = "", sdkRoot = "" } = {})`
@@ -63,6 +63,7 @@ Core rules:
63
63
  - `Not doing: ...`
64
64
  - Keep that checkpoint compact. Do not expand it into a long preamble unless the developer asks for detail.
65
65
  - Reuse existing JSKIT helpers and runtime seams before adding new local helpers.
66
+ - If `npm install` is run while the app is using local JSKIT checkout links, run `npm run devlinks` immediately afterward.
66
67
  - A freshly scaffolded JSKIT app can still be in Stage 1. If the app was just created and platform decisions are not settled yet, continue with the initialize workflow before adding runtime packages.
67
68
  - Do not treat a missing `config.tenancyMode` line or an untouched minimal scaffold as a final tenancy decision.
68
69
  - Do not install tenancy-sensitive packages until Stage 1 decisions are complete and the chosen tenancy is written into `config/public.js`.
@@ -54,6 +54,7 @@ Baseline expectations after initialization:
54
54
  - create the app scaffold
55
55
  - install the baseline runtime packages in the documented order
56
56
  - install dependencies
57
+ - run `npm run devlinks` immediately after `npm install` when the app is using local JSKIT checkout links
57
58
  - run database migrations when the chosen package set requires them
58
59
  - use the standard packaged workflows that come with those packages unless the blueprint records an override
59
60
  - leave the app in a reproducible, verified baseline state