@antelopejs/dms 0.16.0 → 0.16.2

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 (36) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +14 -14
  3. package/dist/store/cache.d.ts +5 -1
  4. package/dist/store/cache.js +23 -14
  5. package/dist/store/cache.js.map +1 -1
  6. package/dist/store/frontend-compatibility.d.ts +3 -1
  7. package/dist/store/frontend-compatibility.js +6 -8
  8. package/dist/store/frontend-compatibility.js.map +1 -1
  9. package/dist/store/index.d.ts +1 -0
  10. package/dist/store/index.js +1 -0
  11. package/dist/store/index.js.map +1 -1
  12. package/dist/store/interfaces.d.ts +3 -2
  13. package/dist/store/interfaces.js +16 -14
  14. package/dist/store/interfaces.js.map +1 -1
  15. package/dist/store/listing.js +6 -4
  16. package/dist/store/listing.js.map +1 -1
  17. package/dist/store/operations.js +1 -1
  18. package/dist/store/operations.js.map +1 -1
  19. package/dist/store/registry.d.ts +2 -1
  20. package/dist/store/registry.js +7 -26
  21. package/dist/store/registry.js.map +1 -1
  22. package/dist/store/requirements.js +3 -3
  23. package/dist/store/requirements.js.map +1 -1
  24. package/frontend-vue/layers/dms-core/app/build/utils/storedAccounts.ts +62 -0
  25. package/frontend-vue/layers/dms-core/app/composables/auth/useMultiAccount.ts +12 -9
  26. package/frontend-vue/layers/dms-layout/app/build/components/layout/DashboardHeader.vue +30 -3
  27. package/frontend-vue/layers/dms-layout/app/build/components/layout/HeaderActionIcon.vue +75 -0
  28. package/frontend-vue/layers/dms-layout/app/composables/useHeaderActions.ts +9 -0
  29. package/frontend-vue/layers/dms-layout/app/plugins/seo.ts +7 -0
  30. package/frontend-vue/layers/dms-layout/app/theme/surfaces.ts +10 -0
  31. package/frontend-vue/package.json +1 -1
  32. package/package.json +5 -5
  33. package/skills/dms-project/DEV-SERVERS.md +30 -4
  34. package/skills/dms-project/SKILL.md +8 -1
  35. package/skills/dms-project/scripts/dms-dev-usage.sh +5 -2
  36. package/skills/dms-project/scripts/dms-dev.sh +82 -69
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/store/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/store/registry.ts"],"names":[],"mappings":";;;AAyBA,0BAiBC;AA4BD,sCAQC;AA9ED,2DAA8C;AAC9C,yCAAsC;AACtC,mCAA4D;AAG5D,MAAM,aAAa,GAAG,IAAA,qBAAS,EAAC,6BAAQ,CAAC,CAAC;AAE1C,MAAM,iBAAiB,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;AAC3E,MAAM,mBAAmB,GAAG,MAAM,CAAC;AACnC,MAAM,UAAU,GAAG,QAAQ,CAAC;AACf,QAAA,iBAAiB,GAAG,2BAA2B,CAAC;AAQ7D,MAAM,QAAQ,GAAG,IAAA,yBAAiB,EAAiB,iBAAiB,CAAC,CAAC;AAO/D,KAAK,UAAU,OAAO,CAC3B,IAAY,EACZ,MAAyB,EACzB,WAAmB;IAGnB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,KAAK,EACL,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,QAAQ,CAAC,EACnC,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,mBAAmB,EAAE,CACnD,CAAC;QACF,MAAM,IAAI,GAAY,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,WAAmB,EACnB,WAAmB;IAGnB,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CACzB,GAAG,WAAW,IAAI,UAAU,EAAE,EAC9B,CAAC,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,EACzC,WAAW,CACZ,CAA8B,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,OAAO;QAAE,OAAO,SAAS,CAAC;IACrC,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,cAAc,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,yBAAiB,CAAC;QACtD,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;QACrC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;YACxC,CAAC,CAAC,EAAE;KACP,CAAC;AACJ,CAAC;AAOD,SAAgB,aAAa,CAC3B,WAAmB,EACnB,WAAmB,EACnB,SAAoB;IAEpB,OAAO,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE;QAC3E,SAAS;KACV,CAAC,CAAC;AACL,CAAC"}
@@ -19,7 +19,7 @@ function caretRange(release) {
19
19
  }
20
20
  async function assertFrontendSupports(context, release) {
21
21
  const { package: packageName } = context.catalogEntry;
22
- const range = await (0, frontend_compatibility_1.releaseFrontendRange)(packageName, release.version, context.projectPath);
22
+ const range = await (0, frontend_compatibility_1.releaseFrontendRange)(packageName, release.version, context.projectPath, "cached");
23
23
  const running = (0, frontend_compatibility_1.runningFrontend)(context.projectPath);
24
24
  if (!range || !running || (0, frontend_compatibility_1.supportsFrontend)(range, running.version))
25
25
  return;
@@ -30,7 +30,7 @@ async function runningModules() {
30
30
  }
31
31
  async function pickDependencies(context, release, label) {
32
32
  const implemented = await (0, interfaces_1.implementedInterfaces)(await runningModules());
33
- const missing = await (0, interfaces_1.findMissingInterfaces)(release, implemented, context.projectPath);
33
+ const missing = await (0, interfaces_1.findMissingInterfaces)(release, implemented, context.projectPath, "cached");
34
34
  const picked = new Map();
35
35
  const unpicked = [];
36
36
  for (const { interfacePackage } of missing) {
@@ -50,7 +50,7 @@ async function installDependency(context, interfacePackage, choice) {
50
50
  if (await (0, declarations_1.hasDeclaration)(key)) {
51
51
  throw new Error(`${key} is already in antelope.config.ts but does not run: start it from there`);
52
52
  }
53
- const release = await (0, registry_1.latestRelease)(key, context.projectPath, true);
53
+ const release = await (0, registry_1.latestRelease)(key, context.projectPath, "fresh");
54
54
  if (!release) {
55
55
  throw new Error(`The npm registry has no release of ${key}`);
56
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/store/requirements.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/store/requirements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { StoredAccount } from "../../types/auth";
2
+
3
+ function lastUsedTime(account: StoredAccount): number {
4
+ return new Date(account.lastUsed).getTime();
5
+ }
6
+
7
+ function isRefused(account: StoredAccount): boolean {
8
+ return account.isExpired === true;
9
+ }
10
+
11
+ /** Whether `account` is the better of two entries: live first, then newest. */
12
+ function isPreferred(account: StoredAccount, other: StoredAccount): boolean {
13
+ if (isRefused(account) !== isRefused(other)) return isRefused(other);
14
+ return lastUsedTime(account) > lastUsedTime(other);
15
+ }
16
+
17
+ /**
18
+ * Whether `stale` is an entry a recreated user record left behind: it can no
19
+ * longer sign in from this browser (marked expired), and a better entry holds
20
+ * its email under another user id. A live entry is never one, since a stored
21
+ * email can be out of date and name another person.
22
+ */
23
+ function isRecreatedAs(stale: StoredAccount, current: StoredAccount): boolean {
24
+ return (
25
+ stale.userId !== current.userId &&
26
+ stale.email === current.email &&
27
+ isRefused(stale) &&
28
+ isPreferred(current, stale)
29
+ );
30
+ }
31
+
32
+ function isReplacedBy(stored: StoredAccount, account: StoredAccount): boolean {
33
+ return stored.userId === account.userId || isRecreatedAs(stored, account);
34
+ }
35
+
36
+ /** `accounts` with `account` in place of every entry it replaces. */
37
+ export function withAccount(
38
+ accounts: StoredAccount[],
39
+ account: StoredAccount,
40
+ ): StoredAccount[] {
41
+ const index = accounts.findIndex((stored) => isReplacedBy(stored, account));
42
+ const others = accounts.filter((stored) => !isReplacedBy(stored, account));
43
+ if (index < 0) return [...others, account];
44
+ return [...others.slice(0, index), account, ...others.slice(index)];
45
+ }
46
+
47
+ /**
48
+ * One entry per user, the preferred one, without the refused entries of user
49
+ * records recreated under the same email.
50
+ */
51
+ export function uniqueAccounts(accounts: StoredAccount[]): StoredAccount[] {
52
+ const byUser = new Map<string, StoredAccount>();
53
+ for (const account of accounts) {
54
+ const kept = byUser.get(account.userId);
55
+ if (!kept || isPreferred(account, kept))
56
+ byUser.set(account.userId, account);
57
+ }
58
+ const perUser = [...byUser.values()];
59
+ return perUser.filter(
60
+ (account) => !perUser.some((other) => isRecreatedAs(account, other)),
61
+ );
62
+ }
@@ -4,6 +4,7 @@ import type {
4
4
  SwitchAccountResponse,
5
5
  ValidateAccountResponse,
6
6
  } from "../../types/auth";
7
+ import { uniqueAccounts, withAccount } from "../../build/utils/storedAccounts";
7
8
 
8
9
  const STORAGE_KEY = "antelopejs-accounts";
9
10
  const SWITCH_ACCOUNT_ENDPOINT = "/auth/switch-account";
@@ -14,6 +15,12 @@ type AccountsRef = ReturnType<typeof useStorage<StoredAccount[]>>;
14
15
 
15
16
  const accountsStorageByApp = new WeakMap<object, AccountsRef>();
16
17
 
18
+ function dropDuplicates(accounts: AccountsRef) {
19
+ if (!Array.isArray(accounts.value)) return;
20
+ const unique = uniqueAccounts(accounts.value);
21
+ if (unique.length < accounts.value.length) accounts.value = unique;
22
+ }
23
+
17
24
  /**
18
25
  * The stored accounts, on a ref whose persistence outlives any component.
19
26
  *
@@ -34,6 +41,7 @@ function useAccountsStorage(): AccountsRef {
34
41
  const storage = effectScope(true).run(() =>
35
42
  useStorage<StoredAccount[]>(STORAGE_KEY, [], undefined),
36
43
  ) as AccountsRef;
44
+ dropDuplicates(storage);
37
45
  accountsStorageByApp.set(dmsApp, storage);
38
46
  return storage;
39
47
  }
@@ -88,20 +96,13 @@ function upsertAccount(
88
96
  user: MinimalUser,
89
97
  accountId: string,
90
98
  ) {
91
- const existingIndex = accounts.value.findIndex((a) => a.userId === user._id);
92
- const account: StoredAccount = {
99
+ accounts.value = withAccount(accounts.value, {
93
100
  accountId,
94
101
  userId: user._id,
95
102
  email: user.email,
96
103
  name: user.name,
97
104
  lastUsed: new Date(),
98
- };
99
-
100
- if (existingIndex >= 0) {
101
- accounts.value[existingIndex] = account;
102
- } else {
103
- accounts.value.push(account);
104
- }
105
+ });
105
106
  }
106
107
 
107
108
  async function requestAccountSwitch(account: StoredAccount) {
@@ -168,6 +169,7 @@ function createSwitchAccount(
168
169
  } catch (error) {
169
170
  if (isTokenRejection(error)) {
170
171
  account.isExpired = true;
172
+ dropDuplicates(accounts);
171
173
  }
172
174
  throw error;
173
175
  }
@@ -187,6 +189,7 @@ function createValidateAllAccounts(
187
189
  .filter((a) => a.userId !== currentUserId)
188
190
  .map((account) => validateAccount(account)),
189
191
  );
192
+ dropDuplicates(accounts);
190
193
  };
191
194
  }
192
195
 
@@ -2,6 +2,7 @@
2
2
  import type { BreadcrumbItem, DropdownMenuItem } from "@nuxt/ui";
3
3
  import { onMounted, ref } from "vue";
4
4
  import NotificationPopover from "../notification/NotificationPopover.vue";
5
+ import HeaderActionIcon from "./HeaderActionIcon.vue";
5
6
  import QuickActionsPopover from "./QuickActionsPopover.vue";
6
7
  import { useSidebarState } from "./sidebarState";
7
8
  import {
@@ -24,6 +25,7 @@ const MOBILE_ELLIPSIS_SLOT = "ellipsis";
24
25
  /** v2 toolbar buttons: muted until hovered or open. */
25
26
  const TOOLBAR_BUTTON_CLASS =
26
27
  "text-muted hover:text-highlighted data-[state=open]:text-highlighted";
28
+ const BUILDER_FALLBACK_ICON = "i-ph-hammer-light";
27
29
  /** The crumb naming a row keeps the row's own case (crumbs capitalize). */
28
30
  const RECORD_CRUMB_LABEL_CLASS = "first-letter:normal-case";
29
31
 
@@ -50,6 +52,17 @@ const registeredActions = computed(() =>
50
52
  : visibleActions.value.filter(isPlainDataHeaderAction),
51
53
  );
52
54
 
55
+ /** The component of each action whose `iconComponent` resolves, by action id. */
56
+ const iconComponents = computed(
57
+ () =>
58
+ new Map(
59
+ registeredActions.value.flatMap((action) => {
60
+ const component = resolveDmsComponent(action.iconComponent);
61
+ return component ? [[action.id, component] as const] : [];
62
+ }),
63
+ ),
64
+ );
65
+
53
66
  const builderAction = computed(() =>
54
67
  registeredActions.value.find((action) => action.id === BUILDER_ACTION_ID),
55
68
  );
@@ -290,7 +303,7 @@ const mobileBreadcrumb = computed(
290
303
  :content="TOOLTIP_CONTENT"
291
304
  >
292
305
  <UButton
293
- :icon="builderAction.icon || 'i-ph-hammer-light'"
306
+ :icon="builderAction.icon || BUILDER_FALLBACK_ICON"
294
307
  variant="ghost"
295
308
  :color="isActionActive(builderAction) ? 'primary' : 'neutral'"
296
309
  :class="
@@ -304,7 +317,14 @@ const mobileBreadcrumb = computed(
304
317
  "
305
318
  :ui="{ leadingIcon: 'size-[18px]' }"
306
319
  @click="selectAction(builderAction)"
307
- />
320
+ >
321
+ <template v-if="iconComponents.has(builderAction.id)" #leading>
322
+ <HeaderActionIcon
323
+ :component="iconComponents.get(builderAction.id)"
324
+ :icon="builderAction.icon || BUILDER_FALLBACK_ICON"
325
+ />
326
+ </template>
327
+ </UButton>
308
328
  </UTooltip>
309
329
 
310
330
  <UTooltip
@@ -324,7 +344,14 @@ const mobileBreadcrumb = computed(
324
344
  "
325
345
  :ui="{ leadingIcon: 'size-[18px]' }"
326
346
  @click="selectAction(action)"
327
- />
347
+ >
348
+ <template v-if="iconComponents.has(action.id)" #leading>
349
+ <HeaderActionIcon
350
+ :component="iconComponents.get(action.id)"
351
+ :icon="action.icon"
352
+ />
353
+ </template>
354
+ </UButton>
328
355
  </UTooltip>
329
356
 
330
357
  <QuickActionsPopover />
@@ -0,0 +1,75 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ getCurrentInstance,
4
+ onErrorCaptured,
5
+ onMounted,
6
+ ref,
7
+ watch,
8
+ type Component,
9
+ type ComponentInternalInstance,
10
+ } from "vue";
11
+
12
+ /**
13
+ * Draws a header action's `iconComponent` in the leading slot of its button.
14
+ * `icon` stands in, at the size of the button's own leading icon, while there
15
+ * is no component, on the server and the hydration pass, until the component
16
+ * has rendered, and when it fails to load. A new `component` gets its own
17
+ * attempt after a failed one.
18
+ */
19
+ const props = defineProps<{
20
+ component?: Component;
21
+ icon: string;
22
+ }>();
23
+
24
+ /** The box of the `leadingIcon` this replaces, whichever of the two draws. */
25
+ const ICON_CLASS = "size-[18px] shrink-0";
26
+
27
+ const mounted = ref(false);
28
+ onMounted(() => {
29
+ mounted.value = true;
30
+ });
31
+
32
+ const failed = ref(false);
33
+ watch(
34
+ () => props.component,
35
+ () => {
36
+ failed.value = false;
37
+ },
38
+ );
39
+ const self = getCurrentInstance();
40
+
41
+ /** The component drawn here that `source` belongs to: its ancestor whose parent is this one. */
42
+ function drawnComponentOf(
43
+ source: ComponentInternalInstance | null,
44
+ ): ComponentInternalInstance | null {
45
+ let current = source;
46
+ while (current && current.parent !== self) current = current.parent;
47
+ return current;
48
+ }
49
+
50
+ onErrorCaptured((error, instance) => {
51
+ if (drawnComponentOf(instance?.$ ?? null)?.type !== props.component)
52
+ return false;
53
+ failed.value = true;
54
+ if (import.meta.env.DEV)
55
+ console.warn(
56
+ "[dms] header action icon component failed to load; drawing icon instead",
57
+ error,
58
+ );
59
+ return false;
60
+ });
61
+ </script>
62
+
63
+ <template>
64
+ <UIcon
65
+ v-if="!mounted || failed || !component"
66
+ :name="icon"
67
+ :class="ICON_CLASS"
68
+ />
69
+ <Suspense v-else>
70
+ <component :is="component" :class="ICON_CLASS" />
71
+ <template #fallback>
72
+ <UIcon :name="icon" :class="ICON_CLASS" />
73
+ </template>
74
+ </Suspense>
75
+ </template>
@@ -9,6 +9,15 @@ import { isFunction, isString } from "#dms-core/app/utils/type-check";
9
9
  export interface HeaderAction {
10
10
  id: string;
11
11
  icon: string;
12
+ /**
13
+ * A component drawn in place of `icon`, by the name `registerComponent` gave
14
+ * it (resolved as a side panel's `component` is), for an icon that animates
15
+ * or follows a state. The component is drawn once the app is mounted. `icon`
16
+ * stays required: it is drawn on the server's first paint, while the name
17
+ * does not resolve, while an async component loads, and when it fails to
18
+ * load. The name is plain data, so a server still renders the action.
19
+ */
20
+ iconComponent?: string;
12
21
  /** Tooltip and accessible name: a plain literal, or an i18n key when prefixed with "$". */
13
22
  label: string;
14
23
  /** Run on click. Required unless `sidePanelId` is set, which it overrides. */
@@ -1,3 +1,5 @@
1
+ import { watch } from "vue";
2
+
1
3
  export default defineDmsPlugin(async () => {
2
4
  const { metaTitle, metaDescription, refresh } = useSystemState();
3
5
 
@@ -25,5 +27,10 @@ export default defineDmsPlugin(async () => {
25
27
  ],
26
28
  });
27
29
 
30
+ if (typeof window !== "undefined")
31
+ watch(metaTitle, (title) => {
32
+ if (!title) void refresh();
33
+ });
34
+
28
35
  if (!metaTitle.value) await refresh();
29
36
  });
@@ -191,10 +191,20 @@ const toastTheme = {
191
191
  * floating bar, a drawer's footer band): the bar sets how far it reaches
192
192
  * (`--dms-toaster-clearance`, see `toasterClearance.ts`), so a toast never
193
193
  * covers its buttons, and the stack drops back once the bar hides.
194
+ *
195
+ * reka-ui 2.11 writes its own `data-expanded` on each toast over Nuxt UI's
196
+ * `true`/`false`, from its own hover and focus state, so Nuxt UI's collapsed
197
+ * rules on the toast (`data-[expanded=false]`) never match. The viewport keeps
198
+ * Nuxt UI's attribute, and `in-data-[expanded=false]` restates those rules from
199
+ * it: a toast behind the front one takes the front one's height and hides its
200
+ * content, and when it closes it fades out where it sits. Without that, it ran
201
+ * the expanded exit, which moves it to its expanded slot, well above the
202
+ * collapsed stack.
194
203
  */
195
204
  const toasterTheme = {
196
205
  slots: {
197
206
  viewport: "w-[calc(100%-2.5rem)] sm:w-[380px]",
207
+ base: "in-data-[expanded=false]:data-[front=false]:h-(--front-height) in-data-[expanded=false]:data-[front=false]:*:opacity-0 data-[state=closed]:in-data-[expanded=false]:data-[front=false]:animate-[fade-out_200ms_ease-in-out]",
198
208
  },
199
209
  variants: {
200
210
  position: {
@@ -76,7 +76,7 @@
76
76
  "zod": "^3.24.2"
77
77
  },
78
78
  "devDependencies": {
79
- "@antelopejs/core": ">=1.16.0 <2",
79
+ "@antelopejs/core": ">=1.20.0 <2",
80
80
  "@antelopejs/dms-frontend": ">=0.10.0 <0.11.0",
81
81
  "@eslint/js": "^8.57.0",
82
82
  "@inertiajs/vue3": "^3.7.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "AntelopeJS DMS. Plug in your PostgreSQL, MongoDB or RethinkDB database and your coding agent builds a back office and analytics dashboard as typed TypeScript. Real-time updates on the data the DMS manages.",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -93,7 +93,7 @@
93
93
  "zod": "~3.24.2"
94
94
  },
95
95
  "devDependencies": {
96
- "@antelopejs/core": ">=1.17.0 <2",
96
+ "@antelopejs/core": ">=1.20.0 <2",
97
97
  "@antelopejs/tooling-configs": "0.2.18",
98
98
  "@types/archiver": "^6.0.4",
99
99
  "@types/chai": "^4.3.20",
@@ -118,7 +118,7 @@
118
118
  "tsc-alias": "^1.9.1",
119
119
  "typescript": "^6.0.3",
120
120
  "vue": "^3.5.18",
121
- "@antelopejs/api": "file:../../.campaign/tgz/antelopejs-api-6afe3e2.tgz"
121
+ "@antelopejs/api": "^1.7.0"
122
122
  },
123
123
  "exports": {
124
124
  ".": {
@@ -138,11 +138,11 @@
138
138
  "registry": "https://registry.npmjs.org/"
139
139
  },
140
140
  "optionalDependencies": {
141
- "@antelopejs/interface-dms-automation": "file:../../.campaign/tgz/antelopejs-interface-dms-automation-b4bc5d2.tgz",
141
+ "@antelopejs/interface-dms-automation": ">=0.6.0 <1.0.0",
142
142
  "@antelopejs/interface-redis": ">=0.0.9 <1.0.0"
143
143
  },
144
144
  "peerDependencies": {
145
- "@antelopejs/core": ">=1.17.0 <2"
145
+ "@antelopejs/core": ">=1.20.0 <2"
146
146
  },
147
147
  "peerDependenciesMeta": {
148
148
  "@antelopejs/core": {
@@ -36,10 +36,7 @@ overwrite the memory.
36
36
 
37
37
  ## Choose the process manager
38
38
 
39
- The script is for local shells. In an Amp orb, use the repository's `.amp/services.yaml` with
40
- `amp orb services ensure`, or `amp orb service start` for a one-off service; check readiness with
41
- service logs and HTTP checks and share the returned portal URL. Processes the script detaches do
42
- not survive orb updates.
39
+ The script is for local shells.
43
40
 
44
41
  ## What `stop` and `restart` touch
45
42
 
@@ -55,6 +52,35 @@ the processes of that server alone that the scan below finds. The other server k
55
52
 
56
53
  Run one `start` or `restart` at a time: a second concurrent call hits a port or lock conflict.
57
54
 
55
+ ## Several worktrees side by side
56
+
57
+ Each project keeps its own pid file and logs, so projects only collide on ports, MongoDB and
58
+ temporary files. `antelopejs-lease` (in the project's tooling-configs) hands a command its own set
59
+ of those. Prefix the script with it:
60
+
61
+ ```sh
62
+ DMS_BACK_DIR=<resolved-path> pnpm exec antelopejs-lease run -- bash "<skill-base-dir>/scripts/dms-dev.sh" start
63
+ ```
64
+
65
+ The lease sets `DMS_BACK_PORT` and `DMS_FRONT_PORT`, never `PORT`. The script turns each into
66
+ `PORT` for its own process only, because `ajs dms dev` and the DMS playground's
67
+ `antelope.config.ts` read `PORT` and would otherwise share one port. Without the variables nothing
68
+ changes: no `PORT` is set and the reported URLs default to `5010` and `3001`; with them, to those
69
+ ports.
70
+
71
+ Pass `DMS_BACK_CMD` / `DMS_FRONT_CMD` overrides through the environment, not as arguments of a wrapper command (`antelopejs-lease run -- env DMS_BACK_CMD=… bash dms-dev.sh start`): the script's process search can otherwise match the wrapper's command line.
72
+
73
+ After the backend's ready line, `start` also waits (within `DMS_DEV_TIMEOUT`) until `GET /dms/frontend?renderer=vue&rendererVersion=3`, the request the dashboard makes first, answers 200, 401 or 403. The ready line can print before the modules have loaded, and the manifest answers 503 until they have, which made the dashboard exit when several backends started at once. The wait is skipped without `curl`, without a `.antelope/dev.json`, or when nothing accepts connections on the recorded port.
74
+
75
+ A config that hard-codes the api port (most DMS repos pin `5010`) ignores `PORT`. Two such projects
76
+ still start side by side: in dev mode the second backend listens on the next free port and logs
77
+ `Port <n> in use, listening on <url> instead.`, and the script treats that line as ready. The
78
+ backend URL it reports comes from `.antelope/dev.json`, which records the port actually bound, and
79
+ the dashboard finds the backend through that same file.
80
+
81
+ Logs default to `<DMS_BACK_DIR>/.antelope/logs/back.log` and `front.log` (ignored by git with the
82
+ rest of `.antelope`); `status` prints both paths. `DMS_BACK_LOG` / `DMS_FRONT_LOG` override them.
83
+
58
84
  ## Windows
59
85
 
60
86
  The script runs in Git Bash, MSYS2 or Cygwin. Their `ps` lists only their own processes and takes
@@ -205,7 +205,7 @@ DMS_BACK_DIR=<resolved-path> bash "<skill-base-dir>/scripts/dms-dev.sh" restart
205
205
  | `start` | Nothing is running (fresh shell, after `stop`). |
206
206
  | `stop` | Before walking away, before destructive operations, on session cleanup. |
207
207
  | `status` | The user asks whether the DMS is running. |
208
- | `back-log [N]` / `front-log [N]` | A boot fails: read the last N (default 60) lines of `/tmp/dms-back.log` / `/tmp/dms-front.log`. |
208
+ | `back-log [N]` / `front-log [N]` | A boot fails: read the last N (default 60) lines of `<DMS_BACK_DIR>/.antelope/logs/back.log` / `front.log`. |
209
209
 
210
210
  The call returns once both servers print their ready line and reports the URLs they listen on; it
211
211
  fails fast when a server exits early, otherwise after 180 s per server (`DMS_DEV_TIMEOUT`). The
@@ -214,6 +214,13 @@ servers keep running detached. By default the script runs the project's `pnpm de
214
214
  override them with `DMS_BACK_CMD` / `DMS_FRONT_CMD`. It runs in bash on Linux and macOS, and in
215
215
  Git Bash, MSYS2 or Cygwin on Windows ([DEV-SERVERS.md](DEV-SERVERS.md#windows)).
216
216
 
217
+ Several worktrees or repos run side by side when each call gets its own ports: prefix the script
218
+ with `pnpm exec antelopejs-lease run --` where the project's tooling-configs has it. The script
219
+ hands `DMS_BACK_PORT` / `DMS_FRONT_PORT` to the backend / frontend process as its `PORT`, and
220
+ logs under the project's own `.antelope/logs/`. A backend whose config pins the api port still
221
+ starts: it falls back to the next free port and the script reports that one
222
+ ([DEV-SERVERS.md](DEV-SERVERS.md#several-worktrees-side-by-side)).
223
+
217
224
  When you hand off for manual testing, run `restart` yourself, wait for both ready lines, then tell
218
225
  the user what to click. Boot failures, stale frontends, a refused credential (401), stop scope and
219
226
  managed environments (Amp orbs): [DEV-SERVERS.md](DEV-SERVERS.md).
@@ -22,8 +22,11 @@ Environment:
22
22
  the playground convention for "ajs project dev -w" / legacy "run -w").
23
23
  DMS_FRONT_CMD Command to start the frontend, run in DMS_BACK_DIR (default:
24
24
  "pnpm frontend:dev", the playground convention for "ajs dms dev").
25
- DMS_BACK_LOG (default: /tmp/dms-back.log)
26
- DMS_FRONT_LOG (default: /tmp/dms-front.log)
25
+ DMS_BACK_PORT Port of the backend: it becomes PORT for the backend process only, and the
26
+ default of the URL reported when the backend gives none (default: unset).
27
+ DMS_FRONT_PORT The same for the frontend (default: unset).
28
+ DMS_BACK_LOG (default: <DMS_BACK_DIR>/.antelope/logs/back.log)
29
+ DMS_FRONT_LOG (default: <DMS_BACK_DIR>/.antelope/logs/front.log)
27
30
  DMS_DEV_TIMEOUT (default: 180 seconds per server)
28
31
  DMS_DEV_STOP_GRACE (default: 10 seconds between SIGTERM and SIGKILL; unused on Windows)
29
32
  EOF