@astrale-domains/shell 0.1.0-beta.34 → 0.1.0-beta.36

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 (34) hide show
  1. package/README.md +16 -2
  2. package/dist/application.d.ts +15 -3
  3. package/dist/application.js +9 -0
  4. package/dist/functions/application/index.js +1 -0
  5. package/dist/functions/application/list-applications.js +19 -0
  6. package/dist/queries/application/index.js +1 -0
  7. package/dist/queries/application/read-installed-domain-origins.js +22 -0
  8. package/dist/runtime.d.ts +133 -10
  9. package/dist/runtime.js +2 -1
  10. package/dist/schema/index.d.ts +2 -1
  11. package/dist/schema/index.js +2 -1
  12. package/dist/schema/modules/application/functions/index.d.ts +1 -0
  13. package/dist/schema/modules/application/functions/index.js +1 -0
  14. package/dist/schema/modules/application/functions/list-applications.d.ts +13 -0
  15. package/dist/schema/modules/application/functions/list-applications.js +16 -0
  16. package/dist/schema/modules/application/index.d.ts +2 -0
  17. package/dist/schema/modules/application/index.js +2 -0
  18. package/dist/schema/modules/application/types/application-entry.d.ts +5 -0
  19. package/dist/schema/modules/application/types/application-entry.js +2 -0
  20. package/dist/schema/modules/application/types/index.d.ts +1 -0
  21. package/dist/schema/modules/application/types/index.js +1 -0
  22. package/dist/schema/modules/group/classes/group.d.ts +2 -2
  23. package/dist/schema/modules/group/core/applications-group.d.ts +1 -0
  24. package/dist/schema/modules/group/core/applications-group.js +6 -0
  25. package/dist/schema/modules/group/core/index.d.ts +1 -0
  26. package/dist/schema/modules/group/core/index.js +1 -0
  27. package/dist/schema/modules/group/index.d.ts +1 -1
  28. package/dist/schema/modules/group/index.js +1 -1
  29. package/dist/schema/modules/user/classes/user.d.ts +1 -1
  30. package/dist/schema/policies/index.js +1 -0
  31. package/dist/schema/policies/uses-function.js +5 -0
  32. package/dist/schema/schema.d.ts +48 -12
  33. package/dist/schema/schema.js +9 -4
  34. package/package.json +3 -3
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Shell Domain
2
2
 
3
3
  Shell owns two concrete Identity classes, User and Group, the member_of_group relation,
4
- the admin/member Core groups, three static methods, and one application View. There is
5
- no Space, setup function, personal home, application catalogue, or public repair method.
4
+ the admin/member/applications Core groups, three static methods, one Domain function, and one
5
+ application View. There is no Space, setup function, personal home, or public repair method.
6
6
 
7
7
  ## Contracts
8
8
 
@@ -12,6 +12,20 @@ no Space, setup function, personal home, application catalogue, or public repair
12
12
  | Group.assignMember | `{ member: UserPath \| GroupPath, group: GroupPath }` | `{}` |
13
13
  | Group.unassignMember | Same | `{}` |
14
14
 
15
+ | Domain function | Input | Output |
16
+ | --- | --- | --- |
17
+ | listApplications | `{}` | `{ applications: { origin }[] }` |
18
+
19
+ listApplications reads every installed Domain with Shell's own authority (Shell requires `read` on
20
+ Kernel `Domain`), then resolves each Domain's View catalogue with the caller's authority and keeps
21
+ only the Domains that expose at least one View to that caller. Its Policy (`usesFunction`) admits any
22
+ caller whose composed profile holds `can_use` on it, so holding the capability is enough.
23
+
24
+ The Core `applications` Group carries `can_use` on listApplications and View.resolve. Administrators
25
+ hold listApplications directly (a Core Edge cannot author Kernel `extends_with`); members do not.
26
+ Share it dynamically with `Group.assignMember({ member: user, group: applications })`, which composes
27
+ the profile through `extends_with`; `unassignMember` withdraws it.
28
+
15
29
  User extends Kernel.Identity and owns only optional creationKey correlation.
16
30
  Concrete business classes may declare their own displayName/email; Shell never reads or writes them.
17
31
  Group extends Kernel.Identity, Named and Descriptable. Authentication remains the
@@ -20,7 +20,7 @@ declare const frontend: import("@astrale-os/sdk/view").Frontend<import("@astrale
20
20
  user: string;
21
21
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
22
22
  };
23
- }, "authorized", true, false>>;
23
+ }, "authorized", true, false, undefined>>;
24
24
  };
25
25
  }>;
26
26
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -33,14 +33,14 @@ declare const frontend: import("@astrale-os/sdk/view").Frontend<import("@astrale
33
33
  }, {
34
34
  readonly mode: 'value';
35
35
  readonly value: Record<string, never>;
36
- }, "authorized", true, false>>;
36
+ }, "authorized", true, false, undefined>>;
37
37
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
38
38
  member: string;
39
39
  group: string;
40
40
  }, {
41
41
  readonly mode: 'value';
42
42
  readonly value: Record<string, never>;
43
- }, "authorized", true, false>>;
43
+ }, "authorized", true, false, undefined>>;
44
44
  };
45
45
  }>;
46
46
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -60,10 +60,21 @@ declare const frontend: import("@astrale-os/sdk/view").Frontend<import("@astrale
60
60
  readonly effectiveProperties: never;
61
61
  }>;
62
62
  };
63
+ readonly functions: {
64
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
65
+ readonly mode: 'value';
66
+ readonly value: {
67
+ applications: {
68
+ origin: string;
69
+ }[];
70
+ };
71
+ }, "authorized", false, false, undefined>>;
72
+ };
63
73
  readonly policies: {
64
74
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
65
75
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
66
76
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
77
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
67
78
  };
68
79
  readonly views: {
69
80
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -71,6 +82,7 @@ declare const frontend: import("@astrale-os/sdk/view").Frontend<import("@astrale
71
82
  readonly core: {
72
83
  readonly nodes: {
73
84
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
85
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
74
86
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
75
87
  };
76
88
  };
@@ -13,6 +13,8 @@ const applicationRequirements = requirements({
13
13
  functions: KernelRootFunctions,
14
14
  classes: [
15
15
  { class: K.classes.extends_with, operations: ['create', 'read', 'traverse', 'delete'] },
16
+ // listApplications reads the installed Domain catalogue as Shell.
17
+ { class: K.classes.Domain, operations: ['read'] },
16
18
  ],
17
19
  authority: {
18
20
  grant: ['create', 'read', 'update', 'delete', 'traverse', 'use', 'revoke'],
@@ -27,6 +29,8 @@ const applicationRequirements = requirements({
27
29
  S.classes.User.static.methods.invite,
28
30
  S.classes.Group.static.methods.assignMember,
29
31
  S.classes.Group.static.methods.unassignMember,
32
+ // Core Edges cannot author Kernel extends_with, so administrators hold it directly.
33
+ S.functions.listApplications,
30
34
  ],
31
35
  classes: [
32
36
  { class: S.classes.User, operations: ['create', 'read', 'traverse', 'update', 'delete'] },
@@ -54,6 +58,11 @@ const applicationRequirements = requirements({
54
58
  K.classes.View.static.methods.resolve,
55
59
  ],
56
60
  },
61
+ {
62
+ // Shared dynamically: Group.assignMember(user, applications) composes this profile.
63
+ subject: S.core.nodes.applications,
64
+ functions: [S.functions.listApplications, K.classes.View.static.methods.resolve],
65
+ },
57
66
  ],
58
67
  });
59
68
  export const application = defineApplication({
@@ -0,0 +1 @@
1
+ export { listApplications } from './list-applications.js';
@@ -0,0 +1,19 @@
1
+ import { defineAction } from '@astrale-os/sdk/action';
2
+ import { Path } from '@astrale-os/sdk/graph/path';
3
+ import { readInstalledDomainOrigins } from '../../queries/application/index.js';
4
+ /** Catalogues resolved together, so a large instance does not flood the Kernel. */
5
+ const RESOLVE_BATCH = 16;
6
+ export const listApplications = defineAction()('listApplications', async ({ query, kernel }) => {
7
+ const origins = await query(readInstalledDomainOrigins, {});
8
+ const applications = [];
9
+ for (let offset = 0; offset < origins.length; offset += RESOLVE_BATCH) {
10
+ const batch = origins.slice(offset, offset + RESOLVE_BATCH);
11
+ // The caller's authority decides which Views it can open.
12
+ const catalogues = await Promise.all(batch.map((origin) => kernel.caller.viewsFor(Path.domain(origin))));
13
+ for (const [index, origin] of batch.entries()) {
14
+ if (catalogues[index].views.length > 0)
15
+ applications.push({ origin });
16
+ }
17
+ }
18
+ return { applications };
19
+ });
@@ -0,0 +1 @@
1
+ export { readInstalledDomainOrigins } from './read-installed-domain-origins.js';
@@ -0,0 +1,22 @@
1
+ import { defineQuery, Query, queryResult, } from '@astrale-os/sdk/query';
2
+ /** Every installed Domain origin this authority can read, in origin order. */
3
+ export const readInstalledDomainOrigins = defineQuery()((domain) => ({
4
+ id: 'shell.application.domain-origins',
5
+ page: { size: 200 },
6
+ pagination: { maximumPages: 50 },
7
+ build: () => Query.from({ nodes: [domain.dependencies.kernel.classes.Domain] }).select({
8
+ kind: 'nodes',
9
+ projection: { kind: 'value' },
10
+ }),
11
+ project(pages) {
12
+ return queryResult
13
+ .completeNodeValues(pages, 'Installed Domains')
14
+ .map((installed) => {
15
+ const value = installed.props[domain.dependencies.kernel.classes.Domain.properties.origin.key];
16
+ if (typeof value !== 'string')
17
+ throw new TypeError('Installed Domain has no origin.');
18
+ return value;
19
+ })
20
+ .sort((left, right) => left.localeCompare(right));
21
+ },
22
+ }));
package/dist/runtime.d.ts CHANGED
@@ -31,7 +31,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
31
31
  user: string;
32
32
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
33
33
  };
34
- }, "authorized", true, false>>;
34
+ }, "authorized", true, false, undefined>>;
35
35
  };
36
36
  }>;
37
37
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -44,14 +44,14 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
44
44
  }, {
45
45
  readonly mode: 'value';
46
46
  readonly value: Record<string, never>;
47
- }, "authorized", true, false>>;
47
+ }, "authorized", true, false, undefined>>;
48
48
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
49
49
  member: string;
50
50
  group: string;
51
51
  }, {
52
52
  readonly mode: 'value';
53
53
  readonly value: Record<string, never>;
54
- }, "authorized", true, false>>;
54
+ }, "authorized", true, false, undefined>>;
55
55
  };
56
56
  }>;
57
57
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -71,10 +71,21 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
71
71
  readonly effectiveProperties: never;
72
72
  }>;
73
73
  };
74
+ readonly functions: {
75
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
76
+ readonly mode: 'value';
77
+ readonly value: {
78
+ applications: {
79
+ origin: string;
80
+ }[];
81
+ };
82
+ }, "authorized", false, false, undefined>>;
83
+ };
74
84
  readonly policies: {
75
85
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
76
86
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
77
87
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
88
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
78
89
  };
79
90
  readonly views: {
80
91
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -82,6 +93,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
82
93
  readonly core: {
83
94
  readonly nodes: {
84
95
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
96
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
85
97
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
86
98
  };
87
99
  };
@@ -134,7 +146,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
134
146
  user: string;
135
147
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
136
148
  };
137
- }, "authorized", true, false>>;
149
+ }, "authorized", true, false, undefined>>;
138
150
  };
139
151
  }>;
140
152
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -147,14 +159,14 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
147
159
  }, {
148
160
  readonly mode: 'value';
149
161
  readonly value: Record<string, never>;
150
- }, "authorized", true, false>>;
162
+ }, "authorized", true, false, undefined>>;
151
163
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
152
164
  member: string;
153
165
  group: string;
154
166
  }, {
155
167
  readonly mode: 'value';
156
168
  readonly value: Record<string, never>;
157
- }, "authorized", true, false>>;
169
+ }, "authorized", true, false, undefined>>;
158
170
  };
159
171
  }>;
160
172
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -174,10 +186,21 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
174
186
  readonly effectiveProperties: never;
175
187
  }>;
176
188
  };
189
+ readonly functions: {
190
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
191
+ readonly mode: 'value';
192
+ readonly value: {
193
+ applications: {
194
+ origin: string;
195
+ }[];
196
+ };
197
+ }, "authorized", false, false, undefined>>;
198
+ };
177
199
  readonly policies: {
178
200
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
179
201
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
180
202
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
203
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
181
204
  };
182
205
  readonly views: {
183
206
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -185,6 +208,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
185
208
  readonly core: {
186
209
  readonly nodes: {
187
210
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
211
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
188
212
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
189
213
  };
190
214
  };
@@ -235,7 +259,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
235
259
  user: string;
236
260
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
237
261
  };
238
- }, "authorized", true, false>>;
262
+ }, "authorized", true, false, undefined>>;
239
263
  };
240
264
  }>;
241
265
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -248,14 +272,14 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
248
272
  }, {
249
273
  readonly mode: 'value';
250
274
  readonly value: Record<string, never>;
251
- }, "authorized", true, false>>;
275
+ }, "authorized", true, false, undefined>>;
252
276
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
253
277
  member: string;
254
278
  group: string;
255
279
  }, {
256
280
  readonly mode: 'value';
257
281
  readonly value: Record<string, never>;
258
- }, "authorized", true, false>>;
282
+ }, "authorized", true, false, undefined>>;
259
283
  };
260
284
  }>;
261
285
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -275,10 +299,21 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
275
299
  readonly effectiveProperties: never;
276
300
  }>;
277
301
  };
302
+ readonly functions: {
303
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
304
+ readonly mode: 'value';
305
+ readonly value: {
306
+ applications: {
307
+ origin: string;
308
+ }[];
309
+ };
310
+ }, "authorized", false, false, undefined>>;
311
+ };
278
312
  readonly policies: {
279
313
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
280
314
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
281
315
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
316
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
282
317
  };
283
318
  readonly views: {
284
319
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -286,6 +321,7 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
286
321
  readonly core: {
287
322
  readonly nodes: {
288
323
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
324
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
289
325
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
290
326
  };
291
327
  };
@@ -317,7 +353,94 @@ declare const functions: readonly [import("@astrale-os/sdk/workflow").WorkflowDe
317
353
  outcomeKnown: import("zod").ZodLiteral<false>;
318
354
  }, import("zod/v4/core").$strict>;
319
355
  };
320
- }>];
356
+ }>, import("@astrale-os/sdk/action").ActionDefinition<import("@astrale-os/sdk/schema").AuthoredSchema<"shell.astrale.ai", readonly ["kernel.astrale.ai", import("@astrale-os/sdk/schema").KernelSchema] | readonly ["shell.astrale.ai", {
357
+ readonly classes: {
358
+ readonly User: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
359
+ readonly icon: import("@astrale-os/sdk/schema").ClassIcon;
360
+ readonly extends: readonly [import("@astrale-os/sdk/schema").KernelClass<"Identity">];
361
+ readonly properties: {
362
+ readonly creationKey: import("zod").ZodOptional<import("zod").ZodString>;
363
+ };
364
+ readonly methods: {
365
+ readonly invite: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
366
+ user: string;
367
+ email: string;
368
+ }, {
369
+ readonly mode: 'value';
370
+ readonly value: {
371
+ invitationId: string;
372
+ user: string;
373
+ state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
374
+ };
375
+ }, "authorized", true, false, undefined>>;
376
+ };
377
+ }>;
378
+ readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
379
+ readonly icon: import("@astrale-os/sdk/schema").ClassIcon;
380
+ readonly extends: readonly [import("@astrale-os/sdk/schema").KernelClass<"Identity">, import("@astrale-os/sdk/schema").KernelClass<"Named">, import("@astrale-os/sdk/schema").KernelClass<"Descriptable">];
381
+ readonly methods: {
382
+ readonly assignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
383
+ member: string;
384
+ group: string;
385
+ }, {
386
+ readonly mode: 'value';
387
+ readonly value: Record<string, never>;
388
+ }, "authorized", true, false, undefined>>;
389
+ readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
390
+ member: string;
391
+ group: string;
392
+ }, {
393
+ readonly mode: 'value';
394
+ readonly value: Record<string, never>;
395
+ }, "authorized", true, false, undefined>>;
396
+ };
397
+ }>;
398
+ readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
399
+ readonly depth: 0;
400
+ readonly abstract: false;
401
+ readonly extends: readonly [];
402
+ readonly properties: never;
403
+ readonly source: {
404
+ readonly as: "member";
405
+ readonly outgoing: "0..*";
406
+ };
407
+ readonly target: {
408
+ readonly as: "group";
409
+ readonly incoming: "0..*";
410
+ };
411
+ readonly constraints: Record<never, never>;
412
+ readonly effectiveProperties: never;
413
+ }>;
414
+ };
415
+ readonly functions: {
416
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
417
+ readonly mode: 'value';
418
+ readonly value: {
419
+ applications: {
420
+ origin: string;
421
+ }[];
422
+ };
423
+ }, "authorized", false, false, undefined>>;
424
+ };
425
+ readonly policies: {
426
+ readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
427
+ readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
428
+ readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
429
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
430
+ };
431
+ readonly views: {
432
+ readonly application: import("@astrale-os/sdk/schema").View;
433
+ };
434
+ readonly core: {
435
+ readonly nodes: {
436
+ readonly admin: import("@astrale-os/sdk/schema").CoreNode;
437
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
438
+ readonly member: import("@astrale-os/sdk/schema").CoreNode;
439
+ };
440
+ };
441
+ }, {
442
+ readonly kernel: "kernel.astrale.ai";
443
+ }]>, "listApplications", Readonly<Record<never, never>>, Readonly<Record<never, never>>>];
321
444
  export type ShellRuntime = Runtime<ShellSchema, typeof integrations, typeof initialize, typeof functions>;
322
445
  declare const runtime: ShellRuntime;
323
446
  export default runtime;
package/dist/runtime.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { defineRuntime } from '@astrale-os/sdk/runtime';
2
+ import { listApplications } from './functions/application/index.js';
2
3
  import { assignMember, unassignMember } from './functions/group/index.js';
3
4
  import { invite } from './functions/user/index.js';
4
5
  import { integrations } from './integrations/index.js';
@@ -6,7 +7,7 @@ import { enrollmentProvider } from './providers/admin-enrollment/index.js';
6
7
  const initialize = (environment) => ({
7
8
  providers: { enrollment: enrollmentProvider(environment) },
8
9
  });
9
- const functions = [invite, assignMember, unassignMember];
10
+ const functions = [invite, assignMember, unassignMember, listApplications];
10
11
  const runtime = defineRuntime()({
11
12
  integrations,
12
13
  initialize,
@@ -1,4 +1,5 @@
1
1
  export { ShellSchema, S, type Shell, type ShellClasses, type ShellSchemaInput } from './schema.js';
2
2
  export { User } from './modules/user/index.js';
3
3
  export type { InvitationSummary } from './modules/user/index.js';
4
- export { Group, member_of_group, adminGroup, memberGroup } from './modules/group/index.js';
4
+ export { Group, member_of_group, adminGroup, applicationsGroup, memberGroup, } from './modules/group/index.js';
5
+ export { listApplications, type ApplicationEntry } from './modules/application/index.js';
@@ -1,3 +1,4 @@
1
1
  export { ShellSchema, S } from './schema.js';
2
2
  export { User } from './modules/user/index.js';
3
- export { Group, member_of_group, adminGroup, memberGroup } from './modules/group/index.js';
3
+ export { Group, member_of_group, adminGroup, applicationsGroup, memberGroup, } from './modules/group/index.js';
4
+ export { listApplications } from './modules/application/index.js';
@@ -0,0 +1 @@
1
+ export { listApplications } from './list-applications.js';
@@ -0,0 +1 @@
1
+ export { listApplications } from './list-applications.js';
@@ -0,0 +1,13 @@
1
+ import { type Function as SchemaFunction } from '@astrale-os/sdk/schema';
2
+ /**
3
+ * Installed Domains that expose at least one View to the caller. Shell reads the Domain catalogue
4
+ * with its own authority; each catalogue of Views is resolved with the caller's.
5
+ */
6
+ export declare const listApplications: SchemaFunction<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
7
+ readonly mode: 'value';
8
+ readonly value: {
9
+ applications: {
10
+ origin: string;
11
+ }[];
12
+ };
13
+ }, "authorized", false, false, undefined>>;
@@ -0,0 +1,16 @@
1
+ import { func } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { usesFunction } from '../../../policies/index.js';
4
+ import { applicationEntry } from '../types/index.js';
5
+ /**
6
+ * Installed Domains that expose at least one View to the caller. Shell reads the Domain catalogue
7
+ * with its own authority; each catalogue of Views is resolved with the caller's.
8
+ */
9
+ export const listApplications = func({
10
+ description: 'List the installed Domains whose Views the caller can open.',
11
+ auth: 'authorized',
12
+ input: z.strictObject({}),
13
+ output: z.object({ applications: z.array(applicationEntry) }),
14
+ // Holding can_use is enough: membership of the Applications Group shares it dynamically.
15
+ policy: ({ check, ref }) => check(usesFunction, ref(() => listApplications)),
16
+ });
@@ -0,0 +1,2 @@
1
+ export { listApplications } from './functions/index.js';
2
+ export { applicationEntry, type ApplicationEntry } from './types/index.js';
@@ -0,0 +1,2 @@
1
+ export { listApplications } from './functions/index.js';
2
+ export { applicationEntry } from './types/index.js';
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ export declare const applicationEntry: z.ZodObject<{
3
+ origin: z.ZodString;
4
+ }, z.core.$strip>;
5
+ export type ApplicationEntry = z.infer<typeof applicationEntry>;
@@ -0,0 +1,2 @@
1
+ import { z } from 'zod';
2
+ export const applicationEntry = z.object({ origin: z.string().min(1) });
@@ -0,0 +1 @@
1
+ export { applicationEntry, type ApplicationEntry } from './application-entry.js';
@@ -0,0 +1 @@
1
+ export { applicationEntry } from './application-entry.js';
@@ -8,13 +8,13 @@ export declare const Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
8
8
  }, {
9
9
  readonly mode: 'value';
10
10
  readonly value: Record<string, never>;
11
- }, "authorized", true, false>>;
11
+ }, "authorized", true, false, undefined>>;
12
12
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
13
13
  member: string;
14
14
  group: string;
15
15
  }, {
16
16
  readonly mode: 'value';
17
17
  readonly value: Record<string, never>;
18
- }, "authorized", true, false>>;
18
+ }, "authorized", true, false, undefined>>;
19
19
  };
20
20
  }>;
@@ -0,0 +1 @@
1
+ export declare const applicationsGroup: import("@astrale-os/sdk/schema").CoreNode;
@@ -0,0 +1,6 @@
1
+ import { K, core } from '@astrale-os/sdk/schema';
2
+ import { Group } from '../classes/group.js';
3
+ export const applicationsGroup = core.node(() => Group, {
4
+ [K.classes.Named.properties.name.key]: 'Applications',
5
+ [K.classes.Descriptable.properties.description.key]: 'May list the installed applications they can open.',
6
+ });
@@ -1,2 +1,3 @@
1
1
  export { adminGroup } from './administrators-group.js';
2
+ export { applicationsGroup } from './applications-group.js';
2
3
  export { memberGroup } from './members-group.js';
@@ -1,2 +1,3 @@
1
1
  export { adminGroup } from './administrators-group.js';
2
+ export { applicationsGroup } from './applications-group.js';
2
3
  export { memberGroup } from './members-group.js';
@@ -1,3 +1,3 @@
1
1
  export { Group, member_of_group } from './classes/index.js';
2
- export { adminGroup, memberGroup } from './core/index.js';
2
+ export { adminGroup, applicationsGroup, memberGroup } from './core/index.js';
3
3
  export { belongsToGroup } from './policies/index.js';
@@ -1,3 +1,3 @@
1
1
  export { Group, member_of_group } from './classes/index.js';
2
- export { adminGroup, memberGroup } from './core/index.js';
2
+ export { adminGroup, applicationsGroup, memberGroup } from './core/index.js';
3
3
  export { belongsToGroup } from './policies/index.js';
@@ -16,6 +16,6 @@ export declare const User: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
16
16
  user: string;
17
17
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
18
18
  };
19
- }, "authorized", true, false>>;
19
+ }, "authorized", true, false, undefined>>;
20
20
  };
21
21
  }>;
@@ -1,2 +1,3 @@
1
1
  export { ownsClass } from './owns-class.js';
2
2
  export { administersShellClass } from './administers-shell-class.js';
3
+ export { usesFunction } from './uses-function.js';
@@ -0,0 +1,5 @@
1
+ import { K, policy } from '@astrale-os/sdk/schema';
2
+ /** The subject may use the object Function: its own or a composed Identity holds can_use on it. */
3
+ export const usesFunction = policy({
4
+ match: ({ edge, subject, object }) => edge({ source: subject, class: () => K.classes.can_use, target: object }),
5
+ });
@@ -18,7 +18,7 @@ declare const classes: {
18
18
  user: string;
19
19
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
20
20
  };
21
- }, "authorized", true, false>>;
21
+ }, "authorized", true, false, undefined>>;
22
22
  };
23
23
  }>;
24
24
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -31,14 +31,14 @@ declare const classes: {
31
31
  }, {
32
32
  readonly mode: 'value';
33
33
  readonly value: Record<string, never>;
34
- }, "authorized", true, false>>;
34
+ }, "authorized", true, false, undefined>>;
35
35
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
36
36
  member: string;
37
37
  group: string;
38
38
  }, {
39
39
  readonly mode: 'value';
40
40
  readonly value: Record<string, never>;
41
- }, "authorized", true, false>>;
41
+ }, "authorized", true, false, undefined>>;
42
42
  };
43
43
  }>;
44
44
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -81,7 +81,7 @@ declare const input: {
81
81
  user: string;
82
82
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
83
83
  };
84
- }, "authorized", true, false>>;
84
+ }, "authorized", true, false, undefined>>;
85
85
  };
86
86
  }>;
87
87
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -94,14 +94,14 @@ declare const input: {
94
94
  }, {
95
95
  readonly mode: 'value';
96
96
  readonly value: Record<string, never>;
97
- }, "authorized", true, false>>;
97
+ }, "authorized", true, false, undefined>>;
98
98
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
99
99
  member: string;
100
100
  group: string;
101
101
  }, {
102
102
  readonly mode: 'value';
103
103
  readonly value: Record<string, never>;
104
- }, "authorized", true, false>>;
104
+ }, "authorized", true, false, undefined>>;
105
105
  };
106
106
  }>;
107
107
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -121,10 +121,21 @@ declare const input: {
121
121
  readonly effectiveProperties: never;
122
122
  }>;
123
123
  };
124
+ readonly functions: {
125
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
126
+ readonly mode: 'value';
127
+ readonly value: {
128
+ applications: {
129
+ origin: string;
130
+ }[];
131
+ };
132
+ }, "authorized", false, false, undefined>>;
133
+ };
124
134
  readonly policies: {
125
135
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
126
136
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
127
137
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
138
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
128
139
  };
129
140
  readonly views: {
130
141
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -132,6 +143,7 @@ declare const input: {
132
143
  readonly core: {
133
144
  readonly nodes: {
134
145
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
146
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
135
147
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
136
148
  };
137
149
  };
@@ -156,7 +168,7 @@ export declare const ShellSchema: import("@astrale-os/sdk/schema").AuthoredSchem
156
168
  user: string;
157
169
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
158
170
  };
159
- }, "authorized", true, false>>;
171
+ }, "authorized", true, false, undefined>>;
160
172
  };
161
173
  }>;
162
174
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -169,14 +181,14 @@ export declare const ShellSchema: import("@astrale-os/sdk/schema").AuthoredSchem
169
181
  }, {
170
182
  readonly mode: 'value';
171
183
  readonly value: Record<string, never>;
172
- }, "authorized", true, false>>;
184
+ }, "authorized", true, false, undefined>>;
173
185
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
174
186
  member: string;
175
187
  group: string;
176
188
  }, {
177
189
  readonly mode: 'value';
178
190
  readonly value: Record<string, never>;
179
- }, "authorized", true, false>>;
191
+ }, "authorized", true, false, undefined>>;
180
192
  };
181
193
  }>;
182
194
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -196,10 +208,21 @@ export declare const ShellSchema: import("@astrale-os/sdk/schema").AuthoredSchem
196
208
  readonly effectiveProperties: never;
197
209
  }>;
198
210
  };
211
+ readonly functions: {
212
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
213
+ readonly mode: 'value';
214
+ readonly value: {
215
+ applications: {
216
+ origin: string;
217
+ }[];
218
+ };
219
+ }, "authorized", false, false, undefined>>;
220
+ };
199
221
  readonly policies: {
200
222
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
201
223
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
202
224
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
225
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
203
226
  };
204
227
  readonly views: {
205
228
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -207,6 +230,7 @@ export declare const ShellSchema: import("@astrale-os/sdk/schema").AuthoredSchem
207
230
  readonly core: {
208
231
  readonly nodes: {
209
232
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
233
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
210
234
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
211
235
  };
212
236
  };
@@ -233,7 +257,7 @@ export declare const S: schema.ResolvedDomainOf<import("@astrale-os/sdk/schema")
233
257
  user: string;
234
258
  state: "accepted" | "cancelled" | "completed" | "expired" | "failed" | "pending" | "registered" | "registering";
235
259
  };
236
- }, "authorized", true, false>>;
260
+ }, "authorized", true, false, undefined>>;
237
261
  };
238
262
  }>;
239
263
  readonly Group: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
@@ -246,14 +270,14 @@ export declare const S: schema.ResolvedDomainOf<import("@astrale-os/sdk/schema")
246
270
  }, {
247
271
  readonly mode: 'value';
248
272
  readonly value: Record<string, never>;
249
- }, "authorized", true, false>>;
273
+ }, "authorized", true, false, undefined>>;
250
274
  readonly unassignMember: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
251
275
  member: string;
252
276
  group: string;
253
277
  }, {
254
278
  readonly mode: 'value';
255
279
  readonly value: Record<string, never>;
256
- }, "authorized", true, false>>;
280
+ }, "authorized", true, false, undefined>>;
257
281
  };
258
282
  }>;
259
283
  readonly member_of_group: import("@astrale-os/sdk/schema").DirectedEdgeClass<{
@@ -273,10 +297,21 @@ export declare const S: schema.ResolvedDomainOf<import("@astrale-os/sdk/schema")
273
297
  readonly effectiveProperties: never;
274
298
  }>;
275
299
  };
300
+ readonly functions: {
301
+ readonly listApplications: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
302
+ readonly mode: 'value';
303
+ readonly value: {
304
+ applications: {
305
+ origin: string;
306
+ }[];
307
+ };
308
+ }, "authorized", false, false, undefined>>;
309
+ };
276
310
  readonly policies: {
277
311
  readonly belongsToGroup: import("@astrale-os/sdk/schema").Policy;
278
312
  readonly ownsClass: import("@astrale-os/sdk/schema").Policy;
279
313
  readonly administersShellClass: import("@astrale-os/sdk/schema").Policy;
314
+ readonly usesFunction: import("@astrale-os/sdk/schema").Policy;
280
315
  };
281
316
  readonly views: {
282
317
  readonly application: import("@astrale-os/sdk/schema").View;
@@ -284,6 +319,7 @@ export declare const S: schema.ResolvedDomainOf<import("@astrale-os/sdk/schema")
284
319
  readonly core: {
285
320
  readonly nodes: {
286
321
  readonly admin: import("@astrale-os/sdk/schema").CoreNode;
322
+ readonly applications: import("@astrale-os/sdk/schema").CoreNode;
287
323
  readonly member: import("@astrale-os/sdk/schema").CoreNode;
288
324
  };
289
325
  };
@@ -1,17 +1,22 @@
1
1
  import { defineSchema, KernelSchema, schema } from '@astrale-os/sdk/schema';
2
- import { Group, member_of_group, adminGroup, memberGroup, belongsToGroup, } from './modules/group/index.js';
2
+ import { listApplications } from './modules/application/index.js';
3
+ import { Group, member_of_group, adminGroup, applicationsGroup, memberGroup, belongsToGroup, } from './modules/group/index.js';
3
4
  import { User } from './modules/user/index.js';
4
- import { ownsClass, administersShellClass } from './policies/index.js';
5
+ import { ownsClass, administersShellClass, usesFunction } from './policies/index.js';
5
6
  import { applicationView } from './views/index.js';
6
7
  export const ORIGIN = 'shell.astrale.ai';
7
8
  const dependencies = { kernel: KernelSchema };
8
9
  const classes = { User, Group, member_of_group };
9
- const policies = { belongsToGroup, ownsClass, administersShellClass };
10
+ const functions = { listApplications };
11
+ const policies = { belongsToGroup, ownsClass, administersShellClass, usesFunction };
10
12
  const views = { application: applicationView };
11
- const core = { nodes: { admin: adminGroup, member: memberGroup } };
13
+ const core = {
14
+ nodes: { admin: adminGroup, applications: applicationsGroup, member: memberGroup },
15
+ };
12
16
  const input = {
13
17
  dependencies,
14
18
  classes,
19
+ functions,
15
20
  policies,
16
21
  views,
17
22
  core,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-domains/shell",
3
- "version": "0.1.0-beta.34",
3
+ "version": "0.1.0-beta.36",
4
4
  "description": "Astrale Shell Domain schema and remote product implementation",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "devDependencies": {
60
60
  "@astrale-os/ox": "0.1.4",
61
- "@astrale-os/sdk": "0.6.0-beta.0",
61
+ "@astrale-os/sdk": "0.6.0-beta.4",
62
62
  "@astrale/typescript-config": "npm:@jsr/astrale__typescript-config@~2.0.0",
63
63
  "@types/node": "26.2.0",
64
64
  "happy-dom": "20.11.2",
@@ -67,7 +67,7 @@
67
67
  "vitest": "5.0.1"
68
68
  },
69
69
  "peerDependencies": {
70
- "@astrale-os/sdk": ">=0.6.0-beta.0 <1.0.0"
70
+ "@astrale-os/sdk": ">=0.6.0-beta.4 <1.0.0"
71
71
  },
72
72
  "devEngines": {
73
73
  "runtime": {