@astrale-domains/shell 0.1.0-beta.21 → 0.1.0-beta.23

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/CHANGELOG.md +19 -0
  2. package/README.md +6 -5
  3. package/dist/application.js +4 -0
  4. package/dist/schema/modules/group/classes/group.d.ts +2 -1
  5. package/dist/schema/modules/group/classes/group.js +5 -4
  6. package/dist/schema/modules/group/functions/assign-user.d.ts +2 -1
  7. package/dist/schema/modules/group/functions/assign-user.js +12 -2
  8. package/dist/schema/modules/group/functions/unassign-user.d.ts +2 -1
  9. package/dist/schema/modules/group/functions/unassign-user.js +12 -2
  10. package/dist/schema/modules/group/types/membership.d.ts +276 -0
  11. package/dist/schema/modules/group/types/membership.js +5 -0
  12. package/dist/schema/modules/space/classes/space.d.ts +2 -1
  13. package/dist/schema/modules/space/classes/space.js +5 -4
  14. package/dist/schema/modules/space/functions/add-user.d.ts +2 -1
  15. package/dist/schema/modules/space/functions/add-user.js +3 -2
  16. package/dist/schema/modules/space/functions/remove-user.d.ts +2 -1
  17. package/dist/schema/modules/space/functions/remove-user.js +3 -1
  18. package/dist/schema/modules/space/functions/set-default.d.ts +2 -1
  19. package/dist/schema/modules/space/functions/set-default.js +3 -1
  20. package/dist/schema/modules/space/policies/belongs-to-space.js +1 -1
  21. package/dist/schema/modules/space/policies/may-administer-space.js +1 -1
  22. package/dist/schema/modules/space/policies/owns-space.js +1 -1
  23. package/dist/schema/modules/space/types/access.d.ts +280 -0
  24. package/dist/schema/modules/space/{policies/group-space-branch.js → types/access.js} +5 -0
  25. package/dist/schema/modules/user/classes/user.d.ts +2 -1
  26. package/dist/schema/modules/user/classes/user.js +5 -4
  27. package/dist/schema/modules/user/functions/setup-admin.d.ts +2 -1
  28. package/dist/schema/modules/user/functions/setup-admin.js +11 -2
  29. package/dist/schema/modules/user/functions/setup-member.d.ts +2 -1
  30. package/dist/schema/modules/user/functions/setup-member.js +11 -2
  31. package/dist/schema/modules/user/types/setup-user.d.ts +13 -0
  32. package/dist/schema/modules/user/types/setup-user.js +14 -0
  33. package/package.json +4 -4
  34. package/dist/schema/modules/group/functions/membership.d.ts +0 -7
  35. package/dist/schema/modules/group/functions/membership.js +0 -16
  36. package/dist/schema/modules/space/functions/access.d.ts +0 -10
  37. package/dist/schema/modules/space/functions/access.js +0 -9
  38. package/dist/schema/modules/space/policies/group-space-branch.d.ts +0 -4
  39. package/dist/schema/modules/user/functions/setup-user.d.ts +0 -15
  40. package/dist/schema/modules/user/functions/setup-user.js +0 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.0-beta.23](https://github.com/astrale-os/shell/compare/shell-domain-v0.1.0-beta.22...shell-domain-v0.1.0-beta.23) (2026-09-04)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **deps:** align SDK and Kernel release cohort ([#177](https://github.com/astrale-os/shell/issues/177)) ([294ec8f](https://github.com/astrale-os/shell/commit/294ec8f6f7a908afb608a1078e03a84ff2cc09ca))
9
+
10
+ ## [0.1.0-beta.22](https://github.com/astrale-os/shell/compare/shell-domain-v0.1.0-beta.21...shell-domain-v0.1.0-beta.22) (2026-09-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **core:** declare required node class icons ([#163](https://github.com/astrale-os/shell/issues/163)) ([2114424](https://github.com/astrale-os/shell/commit/2114424dc1295d978e49536aea76ace897917987))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **domain:** authorize installed app discovery ([#164](https://github.com/astrale-os/shell/issues/164)) ([cbcb559](https://github.com/astrale-os/shell/commit/cbcb5594ffa9701ec979333f76f7c5dc3597401e))
21
+
3
22
  ## [0.1.0-beta.21](https://github.com/astrale-os/shell/compare/shell-domain-v0.1.0-beta.20...shell-domain-v0.1.0-beta.21) (2026-09-01)
4
23
 
5
24
 
package/README.md CHANGED
@@ -34,11 +34,12 @@ The Methods are:
34
34
 
35
35
  Installation authors the `admin`, `member`, and `default-space` Core nodes. Shell infers no authority
36
36
  from email, claims, path spelling, creation order, or a successful handler-local boolean.
37
- The signed Publication declares installation-owned authority profiles: the Shell principal and
38
- Core `admin` receive the intended Kernel application-plane surface, excluding only the ability to
39
- grant `grant` or revoke `revoke`; Core `member` receives Kernel Introspection, Query, Mutation, and
40
- View resolution. Kernel install, upgrade, introspection, and uninstall own those authority edges as
41
- one generation.
37
+ The signed Publication declares installation-owned authority profiles: the Shell principal can
38
+ read installed Kernel `Domain` metadata so managed sessions can list applications and resolve their
39
+ domain Views, and the Shell principal plus Core `admin` receive the intended Kernel
40
+ application-plane surface, excluding only the ability to grant `grant` or revoke `revoke`; Core
41
+ `member` receives Kernel Introspection, Query, Mutation, and View resolution. Kernel install,
42
+ upgrade, introspection, and uninstall own those authority edges as one generation.
42
43
 
43
44
  ## Source ownership
44
45
 
@@ -16,6 +16,10 @@ const frontend = defineFrontend({
16
16
  const applicationRequirements = requirements({
17
17
  functions: KernelRootFunctions,
18
18
  classes: [
19
+ {
20
+ class: K.classes.Domain,
21
+ operations: ['read'],
22
+ },
19
23
  {
20
24
  class: K.classes.extends_with,
21
25
  operations: ['create', 'read', 'traverse', 'delete'],
@@ -1,4 +1,4 @@
1
- import { nodeClass, type Kernel } from '@astrale-os/sdk/schema';
1
+ import { nodeClass, type ClassIcon, type Kernel } from '@astrale-os/sdk/schema';
2
2
  import { groupAssignUser } from '../functions/assign-user.js';
3
3
  import { groupUnassignUser } from '../functions/unassign-user.js';
4
4
  export interface GroupConfig {
@@ -8,6 +8,7 @@ export interface GroupConfig {
8
8
  Kernel['classes']['Named'],
9
9
  Kernel['classes']['Descriptable']
10
10
  ];
11
+ readonly icon: ClassIcon;
11
12
  readonly methods: {
12
13
  readonly assignUser: typeof groupAssignUser;
13
14
  readonly unassignUser: typeof groupUnassignUser;
@@ -1,9 +1,10 @@
1
- import { K, nodeClass } from '@astrale-os/sdk/schema';
1
+ import { classIcon, K, nodeClass } from '@astrale-os/sdk/schema';
2
+ import { UsersRound } from '@astrale-os/sdk/schema/icons';
2
3
  import { groupAssignUser } from '../functions/assign-user.js';
3
4
  import { groupUnassignUser } from '../functions/unassign-user.js';
4
- const config = {
5
+ export const Group = nodeClass({
5
6
  description: 'A named compositional Shell Identity.',
6
7
  extends: [K.classes.Identity, K.classes.Named, K.classes.Descriptable],
8
+ icon: classIcon.lucide(UsersRound),
7
9
  methods: { assignUser: groupAssignUser, unassignUser: groupUnassignUser },
8
- };
9
- export const Group = nodeClass(config);
10
+ });
@@ -1,4 +1,5 @@
1
- export declare const groupAssignUser: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const groupAssignUser: builder.Method<builder.CallableProjection<{
2
3
  user: string;
3
4
  }, {
4
5
  readonly mode: 'value';
@@ -1,2 +1,12 @@
1
- import { defineGroupMembership } from './membership.js';
2
- export const groupAssignUser = defineGroupMembership('Assign one User to this Group.');
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { adminGroup } from '../core/admin-group.js';
3
+ import { maySetupUsers } from '../policies/may-setup-users.js';
4
+ import { membershipInput, membershipOutput } from '../types/membership.js';
5
+ const membershipPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
6
+ export const groupAssignUser = method({
7
+ description: 'Assign one User to this Group.',
8
+ input: membershipInput,
9
+ output: membershipOutput,
10
+ auth: 'authorized',
11
+ policy: membershipPolicy,
12
+ });
@@ -1,4 +1,5 @@
1
- export declare const groupUnassignUser: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const groupUnassignUser: builder.Method<builder.CallableProjection<{
2
3
  user: string;
3
4
  }, {
4
5
  readonly mode: 'value';
@@ -1,2 +1,12 @@
1
- import { defineGroupMembership } from './membership.js';
2
- export const groupUnassignUser = defineGroupMembership('Remove one User from this Group.');
1
+ import { method } from '@astrale-os/sdk/schema';
2
+ import { adminGroup } from '../core/admin-group.js';
3
+ import { maySetupUsers } from '../policies/may-setup-users.js';
4
+ import { membershipInput, membershipOutput } from '../types/membership.js';
5
+ const membershipPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
6
+ export const groupUnassignUser = method({
7
+ description: 'Remove one User from this Group.',
8
+ input: membershipInput,
9
+ output: membershipOutput,
10
+ auth: 'authorized',
11
+ policy: membershipPolicy,
12
+ });
@@ -0,0 +1,276 @@
1
+ import { z } from 'zod';
2
+ export declare const membershipInput: z.ZodObject<{
3
+ user: import("@astrale-os/sdk/schema").PathAuthoring<readonly [import("@astrale-os/sdk/schema").NodeClass<{
4
+ readonly depth: 1;
5
+ readonly abstract: false;
6
+ readonly extends: readonly [import("@astrale-os/sdk/schema").ClassProjection<"node", import("@astrale-os/sdk/schema").NodeClassDefinition & {
7
+ readonly ref: import("@astrale-os/sdk/schema").ClassRef<"Identity"> & {
8
+ readonly origin: "kernel.astrale.ai";
9
+ };
10
+ readonly kind: 'node';
11
+ readonly abstract: true;
12
+ }, import("@astrale-os/sdk/schema").ClassRef & import("@astrale-os/sdk/schema").ClassRef<"Identity"> & {
13
+ readonly origin: "kernel.astrale.ai";
14
+ }, "kernel.astrale.ai:class.Identity", readonly [import("@astrale-os/sdk/schema").ClassProjection<"node", import("@astrale-os/sdk/schema").NodeClassDefinition & {
15
+ readonly ref: import("@astrale-os/sdk/schema").ClassRef<"Node"> & {
16
+ readonly origin: "kernel.astrale.ai";
17
+ };
18
+ readonly kind: 'node';
19
+ readonly abstract: true;
20
+ }, import("@astrale-os/sdk/schema").ClassRef & import("@astrale-os/sdk/schema").ClassRef<"Node"> & {
21
+ readonly origin: "kernel.astrale.ai";
22
+ }, "kernel.astrale.ai:class.Node", readonly import("@astrale-os/sdk/schema").AnyResolvedClass[], never, never, never, never, never, never>, ...never[]], import("@astrale-os/sdk/schema").PropertyProjection<({
23
+ claim: string;
24
+ op: "contains";
25
+ value: unknown;
26
+ } | {
27
+ claim: string;
28
+ op: "eq";
29
+ value: unknown;
30
+ } | {
31
+ claim: string;
32
+ op: "exists";
33
+ })[], false, "requiredClaims", "kernel.astrale.ai:class.Identity.property.requiredClaims", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "frozen", "kernel.astrale.ai:class.Identity.property.frozen", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "iss", "kernel.astrale.ai:class.Identity.property.iss", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "sub", "kernel.astrale.ai:class.Identity.property.sub", undefined>, import("@astrale-os/sdk/schema").MethodProjection<{
34
+ audience: string;
35
+ ttlSeconds: number;
36
+ attenuation: unknown;
37
+ }, {
38
+ readonly mode: 'value';
39
+ readonly value: string;
40
+ }, false, "default", "authenticated", "delegate", "kernel.astrale.ai:class.Identity.method.delegate">, import("@astrale-os/sdk/schema").MethodProjection<Record<string, never>, {
41
+ readonly mode: 'value';
42
+ readonly value: {
43
+ id: string;
44
+ iss: string;
45
+ sub: string;
46
+ frozen: boolean;
47
+ requiredClaims: ({
48
+ claim: string;
49
+ op: "contains";
50
+ value: unknown;
51
+ } | {
52
+ claim: string;
53
+ op: "eq";
54
+ value: unknown;
55
+ } | {
56
+ claim: string;
57
+ op: "exists";
58
+ })[];
59
+ };
60
+ }, true, "default", "authenticated", "whoami", "kernel.astrale.ai:class.Identity.method.whoami"> | import("@astrale-os/sdk/schema").MethodProjection<{
61
+ policy: string;
62
+ object: string;
63
+ }, {
64
+ readonly mode: 'value';
65
+ readonly value: {
66
+ allowed: boolean;
67
+ };
68
+ }, true, "default", "authenticated", "can", "kernel.astrale.ai:class.Identity.method.can"> | import("@astrale-os/sdk/schema").MethodProjection<{
69
+ iss: string;
70
+ sub: string;
71
+ }, {
72
+ readonly mode: 'value';
73
+ readonly value: {
74
+ id: string;
75
+ iss: string;
76
+ sub: string;
77
+ frozen: boolean;
78
+ requiredClaims: ({
79
+ claim: string;
80
+ op: "contains";
81
+ value: unknown;
82
+ } | {
83
+ claim: string;
84
+ op: "eq";
85
+ value: unknown;
86
+ } | {
87
+ claim: string;
88
+ op: "exists";
89
+ })[];
90
+ } | null;
91
+ }, true, "default", "authorized", "whois", "kernel.astrale.ai:class.Identity.method.whois"> | import("@astrale-os/sdk/schema").MethodProjection<{
92
+ audience?: string | undefined;
93
+ ttlSeconds: number;
94
+ grant?: unknown;
95
+ }, {
96
+ readonly mode: 'value';
97
+ readonly value: string;
98
+ }, true, "default", "authenticated", "mint", "kernel.astrale.ai:class.Identity.method.mint">, import("@astrale-os/sdk/schema").PropertyProjection<({
99
+ claim: string;
100
+ op: "contains";
101
+ value: unknown;
102
+ } | {
103
+ claim: string;
104
+ op: "eq";
105
+ value: unknown;
106
+ } | {
107
+ claim: string;
108
+ op: "exists";
109
+ })[], false, "requiredClaims", "kernel.astrale.ai:class.Identity.property.requiredClaims", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "frozen", "kernel.astrale.ai:class.Identity.property.frozen", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "iss", "kernel.astrale.ai:class.Identity.property.iss", undefined> | import("@astrale-os/sdk/schema").PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "sub", "kernel.astrale.ai:class.Identity.property.sub", undefined>, import("@astrale-os/sdk/schema").MethodProjection<{
110
+ audience: string;
111
+ ttlSeconds: number;
112
+ attenuation: unknown;
113
+ }, {
114
+ readonly mode: 'value';
115
+ readonly value: string;
116
+ }, false, "default", "authenticated", "delegate", "kernel.astrale.ai:class.Identity.method.delegate">, import("@astrale-os/sdk/schema").MethodProjection<Record<string, never>, {
117
+ readonly mode: 'value';
118
+ readonly value: {
119
+ id: string;
120
+ iss: string;
121
+ sub: string;
122
+ frozen: boolean;
123
+ requiredClaims: ({
124
+ claim: string;
125
+ op: "contains";
126
+ value: unknown;
127
+ } | {
128
+ claim: string;
129
+ op: "eq";
130
+ value: unknown;
131
+ } | {
132
+ claim: string;
133
+ op: "exists";
134
+ })[];
135
+ };
136
+ }, true, "default", "authenticated", "whoami", "kernel.astrale.ai:class.Identity.method.whoami"> | import("@astrale-os/sdk/schema").MethodProjection<{
137
+ policy: string;
138
+ object: string;
139
+ }, {
140
+ readonly mode: 'value';
141
+ readonly value: {
142
+ allowed: boolean;
143
+ };
144
+ }, true, "default", "authenticated", "can", "kernel.astrale.ai:class.Identity.method.can"> | import("@astrale-os/sdk/schema").MethodProjection<{
145
+ iss: string;
146
+ sub: string;
147
+ }, {
148
+ readonly mode: 'value';
149
+ readonly value: {
150
+ id: string;
151
+ iss: string;
152
+ sub: string;
153
+ frozen: boolean;
154
+ requiredClaims: ({
155
+ claim: string;
156
+ op: "contains";
157
+ value: unknown;
158
+ } | {
159
+ claim: string;
160
+ op: "eq";
161
+ value: unknown;
162
+ } | {
163
+ claim: string;
164
+ op: "exists";
165
+ })[];
166
+ } | null;
167
+ }, true, "default", "authorized", "whois", "kernel.astrale.ai:class.Identity.method.whois"> | import("@astrale-os/sdk/schema").MethodProjection<{
168
+ audience?: string | undefined;
169
+ ttlSeconds: number;
170
+ grant?: unknown;
171
+ }, {
172
+ readonly mode: 'value';
173
+ readonly value: string;
174
+ }, true, "default", "authenticated", "mint", "kernel.astrale.ai:class.Identity.method.mint">>];
175
+ readonly properties: {
176
+ readonly displayName: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, false, "displayName", "self", never>;
177
+ };
178
+ readonly methods: {
179
+ readonly resolveHome: typeof import("../../user/index.js").resolveHome;
180
+ };
181
+ readonly effectiveProperties: import("@astrale-os/sdk/schema").AuthoredPropertyProjection<string, string, false, "displayName", "self", never> | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
182
+ readonly name: "frozen";
183
+ readonly key: "kernel.astrale.ai:class.Identity.property.frozen";
184
+ }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
185
+ readonly name: "iss";
186
+ readonly key: "kernel.astrale.ai:class.Identity.property.iss";
187
+ }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
188
+ readonly name: "sub";
189
+ readonly key: "kernel.astrale.ai:class.Identity.property.sub";
190
+ });
191
+ readonly effectiveInstanceMethods: import("@astrale-os/sdk/schema").AuthoredMethodProjection<import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
192
+ readonly mode: 'value';
193
+ readonly value: {
194
+ userId: string;
195
+ personalSpaceId: string | null;
196
+ };
197
+ }, "authenticated", false, "default">>, "resolveHome", "self"> | (import("@astrale-os/sdk/schema").ResolvedMethod<{
198
+ audience: string;
199
+ ttlSeconds: number;
200
+ attenuation: unknown;
201
+ }, {
202
+ readonly mode: 'value';
203
+ readonly value: string;
204
+ }, false, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.delegate"> & {
205
+ readonly name: "delegate";
206
+ });
207
+ readonly effectiveStaticMethods: (import("@astrale-os/sdk/schema").ResolvedMethod<{
208
+ policy: string;
209
+ object: string;
210
+ }, {
211
+ readonly mode: 'value';
212
+ readonly value: {
213
+ allowed: boolean;
214
+ };
215
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.can"> & {
216
+ readonly name: "can";
217
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<{
218
+ audience?: string | undefined;
219
+ ttlSeconds: number;
220
+ grant?: unknown;
221
+ }, {
222
+ readonly mode: 'value';
223
+ readonly value: string;
224
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.mint"> & {
225
+ readonly name: "mint";
226
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<Record<string, never>, {
227
+ readonly mode: 'value';
228
+ readonly value: {
229
+ id: string;
230
+ iss: string;
231
+ sub: string;
232
+ frozen: boolean;
233
+ requiredClaims: ({
234
+ claim: string;
235
+ op: "contains";
236
+ value: unknown;
237
+ } | {
238
+ claim: string;
239
+ op: "eq";
240
+ value: unknown;
241
+ } | {
242
+ claim: string;
243
+ op: "exists";
244
+ })[];
245
+ };
246
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.whoami"> & {
247
+ readonly name: "whoami";
248
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<{
249
+ iss: string;
250
+ sub: string;
251
+ }, {
252
+ readonly mode: 'value';
253
+ readonly value: {
254
+ id: string;
255
+ iss: string;
256
+ sub: string;
257
+ frozen: boolean;
258
+ requiredClaims: ({
259
+ claim: string;
260
+ op: "contains";
261
+ value: unknown;
262
+ } | {
263
+ claim: string;
264
+ op: "eq";
265
+ value: unknown;
266
+ } | {
267
+ claim: string;
268
+ op: "exists";
269
+ })[];
270
+ } | null;
271
+ }, true, "default", "authorized", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.whois"> & {
272
+ readonly name: "whois";
273
+ });
274
+ }>]>;
275
+ }, z.core.$strict>;
276
+ export declare const membershipOutput: z.ZodObject<{}, z.core.$strict>;
@@ -0,0 +1,5 @@
1
+ import { path } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ import { User } from '#schema/modules/user';
4
+ export const membershipInput = z.strictObject({ user: path(User) });
5
+ export const membershipOutput = z.strictObject({});
@@ -1,10 +1,11 @@
1
- import { nodeClass, type Kernel } from '@astrale-os/sdk/schema';
1
+ import { nodeClass, type ClassIcon, type Kernel } from '@astrale-os/sdk/schema';
2
2
  import { spaceAddUser } from '../functions/add-user.js';
3
3
  import { spaceRemoveUser } from '../functions/remove-user.js';
4
4
  import { spaceSetDefault } from '../functions/set-default.js';
5
5
  export interface SpaceConfig {
6
6
  readonly description: string;
7
7
  readonly extends: readonly [Kernel['classes']['Named'], Kernel['classes']['Descriptable']];
8
+ readonly icon: ClassIcon;
8
9
  readonly methods: {
9
10
  readonly addUser: typeof spaceAddUser;
10
11
  readonly removeUser: typeof spaceRemoveUser;
@@ -1,14 +1,15 @@
1
- import { K, nodeClass } from '@astrale-os/sdk/schema';
1
+ import { classIcon, K, nodeClass } from '@astrale-os/sdk/schema';
2
+ import { PanelsTopLeft } from '@astrale-os/sdk/schema/icons';
2
3
  import { spaceAddUser } from '../functions/add-user.js';
3
4
  import { spaceRemoveUser } from '../functions/remove-user.js';
4
5
  import { spaceSetDefault } from '../functions/set-default.js';
5
- const config = {
6
+ export const Space = nodeClass({
6
7
  description: 'A named Shell collaboration boundary.',
7
8
  extends: [K.classes.Named, K.classes.Descriptable],
9
+ icon: classIcon.lucide(PanelsTopLeft),
8
10
  methods: {
9
11
  addUser: spaceAddUser,
10
12
  removeUser: spaceRemoveUser,
11
13
  setDefault: spaceSetDefault,
12
14
  },
13
- };
14
- export const Space = nodeClass(config);
15
+ });
@@ -1,4 +1,5 @@
1
- export declare const spaceAddUser: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const spaceAddUser: builder.Method<builder.CallableProjection<{
2
3
  user: string;
3
4
  access: "admin" | "member";
4
5
  }, {
@@ -1,7 +1,8 @@
1
1
  import { method } from '@astrale-os/sdk/schema';
2
2
  import { z } from 'zod';
3
- import { administerPolicy } from './access.js';
4
- import { spaceUser } from './access.js';
3
+ import { mayAdministerSpace } from '../policies/may-administer-space.js';
4
+ import { spaceUser } from '../types/access.js';
5
+ const administerPolicy = ({ check, self }) => check(mayAdministerSpace, self);
5
6
  export const spaceAddUser = method({
6
7
  description: 'Set one User direct member or admin access.',
7
8
  input: spaceUser.extend({ access: z.enum(['member', 'admin']) }),
@@ -1,4 +1,5 @@
1
- export declare const spaceRemoveUser: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const spaceRemoveUser: builder.Method<builder.CallableProjection<{
2
3
  user: string;
3
4
  }, {
4
5
  readonly mode: 'value';
@@ -1,5 +1,7 @@
1
1
  import { method } from '@astrale-os/sdk/schema';
2
- import { administerPolicy, emptyObject, spaceUser } from './access.js';
2
+ import { mayAdministerSpace } from '../policies/may-administer-space.js';
3
+ import { emptyObject, spaceUser } from '../types/access.js';
4
+ const administerPolicy = ({ check, self }) => check(mayAdministerSpace, self);
3
5
  export const spaceRemoveUser = method({
4
6
  description: 'Remove one User direct access.',
5
7
  input: spaceUser,
@@ -1,4 +1,5 @@
1
- export declare const spaceSetDefault: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const spaceSetDefault: builder.Method<builder.CallableProjection<Record<string, never>, {
2
3
  readonly mode: 'value';
3
4
  readonly value: Record<string, never>;
4
5
  }, "authorized", false, "default">>;
@@ -1,5 +1,7 @@
1
1
  import { method } from '@astrale-os/sdk/schema';
2
- import { emptyObject, membershipPolicy } from './access.js';
2
+ import { belongsToSpace } from '../policies/belongs-to-space.js';
3
+ import { emptyObject } from '../types/access.js';
4
+ const membershipPolicy = ({ check, self }) => check(belongsToSpace, self);
3
5
  export const spaceSetDefault = method({
4
6
  description: 'Set this accessible Space as the granted User fallback.',
5
7
  input: emptyObject,
@@ -2,7 +2,7 @@ import { policy } from '@astrale-os/sdk/schema';
2
2
  import { administers_space } from '../classes/administers-space.js';
3
3
  import { member_of_space } from '../classes/member-of-space.js';
4
4
  import { owns_space } from '../classes/owns-space.js';
5
- import { groupSpaceBranch } from './group-space-branch.js';
5
+ import { groupSpaceBranch } from '../types/access.js';
6
6
  export const belongsToSpace = policy({
7
7
  description: 'The effective User Grant has direct or Group-derived access to this Space.',
8
8
  match: ({ allOf, anyOf, edge, exists, object, subject }) => anyOf(edge({ source: subject, class: owns_space, target: object }), edge({ source: subject, class: administers_space, target: object }), edge({ source: subject, class: member_of_space, target: object }), groupSpaceBranch({ allOf, edge, exists, object, subject }, owns_space), groupSpaceBranch({ allOf, edge, exists, object, subject }, administers_space), groupSpaceBranch({ allOf, edge, exists, object, subject }, member_of_space)),
@@ -1,7 +1,7 @@
1
1
  import { policy } from '@astrale-os/sdk/schema';
2
2
  import { administers_space } from '../classes/administers-space.js';
3
3
  import { owns_space } from '../classes/owns-space.js';
4
- import { groupSpaceBranch } from './group-space-branch.js';
4
+ import { groupSpaceBranch } from '../types/access.js';
5
5
  export const mayAdministerSpace = policy({
6
6
  description: 'The effective User Grant directly or transitively administers this Space.',
7
7
  match: ({ allOf, anyOf, edge, exists, object, subject }) => anyOf(edge({ source: subject, class: owns_space, target: object }), edge({ source: subject, class: administers_space, target: object }), groupSpaceBranch({ allOf, edge, exists, object, subject }, owns_space), groupSpaceBranch({ allOf, edge, exists, object, subject }, administers_space)),
@@ -1,6 +1,6 @@
1
1
  import { policy } from '@astrale-os/sdk/schema';
2
2
  import { owns_space } from '../classes/owns-space.js';
3
- import { groupSpaceBranch } from './group-space-branch.js';
3
+ import { groupSpaceBranch } from '../types/access.js';
4
4
  export const ownsSpace = policy({
5
5
  description: 'The effective User Grant directly or transitively owns this Space.',
6
6
  match: ({ allOf, anyOf, edge, exists, object, subject }) => anyOf(edge({ source: subject, class: owns_space, target: object }), groupSpaceBranch({ allOf, edge, exists, object, subject }, owns_space)),
@@ -0,0 +1,280 @@
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ export declare const emptyObject: z.ZodObject<{}, z.core.$strict>;
4
+ export declare const spaceUser: z.ZodObject<{
5
+ user: builder.PathAuthoring<readonly [builder.NodeClass<{
6
+ readonly depth: 1;
7
+ readonly abstract: false;
8
+ readonly extends: readonly [builder.ClassProjection<"node", import("@astrale-os/sdk/schema").NodeClassDefinition & {
9
+ readonly ref: import("@astrale-os/sdk/schema").ClassRef<"Identity"> & {
10
+ readonly origin: "kernel.astrale.ai";
11
+ };
12
+ readonly kind: 'node';
13
+ readonly abstract: true;
14
+ }, import("@astrale-os/sdk/schema").ClassRef & import("@astrale-os/sdk/schema").ClassRef<"Identity"> & {
15
+ readonly origin: "kernel.astrale.ai";
16
+ }, "kernel.astrale.ai:class.Identity", readonly [builder.ClassProjection<"node", import("@astrale-os/sdk/schema").NodeClassDefinition & {
17
+ readonly ref: import("@astrale-os/sdk/schema").ClassRef<"Node"> & {
18
+ readonly origin: "kernel.astrale.ai";
19
+ };
20
+ readonly kind: 'node';
21
+ readonly abstract: true;
22
+ }, import("@astrale-os/sdk/schema").ClassRef & import("@astrale-os/sdk/schema").ClassRef<"Node"> & {
23
+ readonly origin: "kernel.astrale.ai";
24
+ }, "kernel.astrale.ai:class.Node", readonly import("@astrale-os/sdk/schema").AnyResolvedClass[], never, never, never, never, never, never>, ...never[]], builder.PropertyProjection<({
25
+ claim: string;
26
+ op: "contains";
27
+ value: unknown;
28
+ } | {
29
+ claim: string;
30
+ op: "eq";
31
+ value: unknown;
32
+ } | {
33
+ claim: string;
34
+ op: "exists";
35
+ })[], false, "requiredClaims", "kernel.astrale.ai:class.Identity.property.requiredClaims", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "frozen", "kernel.astrale.ai:class.Identity.property.frozen", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "iss", "kernel.astrale.ai:class.Identity.property.iss", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "sub", "kernel.astrale.ai:class.Identity.property.sub", undefined>, builder.MethodProjection<{
36
+ audience: string;
37
+ ttlSeconds: number;
38
+ attenuation: unknown;
39
+ }, {
40
+ readonly mode: 'value';
41
+ readonly value: string;
42
+ }, false, "default", "authenticated", "delegate", "kernel.astrale.ai:class.Identity.method.delegate">, builder.MethodProjection<Record<string, never>, {
43
+ readonly mode: 'value';
44
+ readonly value: {
45
+ id: string;
46
+ iss: string;
47
+ sub: string;
48
+ frozen: boolean;
49
+ requiredClaims: ({
50
+ claim: string;
51
+ op: "contains";
52
+ value: unknown;
53
+ } | {
54
+ claim: string;
55
+ op: "eq";
56
+ value: unknown;
57
+ } | {
58
+ claim: string;
59
+ op: "exists";
60
+ })[];
61
+ };
62
+ }, true, "default", "authenticated", "whoami", "kernel.astrale.ai:class.Identity.method.whoami"> | builder.MethodProjection<{
63
+ policy: string;
64
+ object: string;
65
+ }, {
66
+ readonly mode: 'value';
67
+ readonly value: {
68
+ allowed: boolean;
69
+ };
70
+ }, true, "default", "authenticated", "can", "kernel.astrale.ai:class.Identity.method.can"> | builder.MethodProjection<{
71
+ iss: string;
72
+ sub: string;
73
+ }, {
74
+ readonly mode: 'value';
75
+ readonly value: {
76
+ id: string;
77
+ iss: string;
78
+ sub: string;
79
+ frozen: boolean;
80
+ requiredClaims: ({
81
+ claim: string;
82
+ op: "contains";
83
+ value: unknown;
84
+ } | {
85
+ claim: string;
86
+ op: "eq";
87
+ value: unknown;
88
+ } | {
89
+ claim: string;
90
+ op: "exists";
91
+ })[];
92
+ } | null;
93
+ }, true, "default", "authorized", "whois", "kernel.astrale.ai:class.Identity.method.whois"> | builder.MethodProjection<{
94
+ audience?: string | undefined;
95
+ ttlSeconds: number;
96
+ grant?: unknown;
97
+ }, {
98
+ readonly mode: 'value';
99
+ readonly value: string;
100
+ }, true, "default", "authenticated", "mint", "kernel.astrale.ai:class.Identity.method.mint">, builder.PropertyProjection<({
101
+ claim: string;
102
+ op: "contains";
103
+ value: unknown;
104
+ } | {
105
+ claim: string;
106
+ op: "eq";
107
+ value: unknown;
108
+ } | {
109
+ claim: string;
110
+ op: "exists";
111
+ })[], false, "requiredClaims", "kernel.astrale.ai:class.Identity.property.requiredClaims", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "frozen", "kernel.astrale.ai:class.Identity.property.frozen", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "iss", "kernel.astrale.ai:class.Identity.property.iss", undefined> | builder.PropertyProjection<string | number | boolean | import("@astrale-os/sdk/schema").Array | import("@astrale-os/sdk/schema").Object | null, false, "sub", "kernel.astrale.ai:class.Identity.property.sub", undefined>, builder.MethodProjection<{
112
+ audience: string;
113
+ ttlSeconds: number;
114
+ attenuation: unknown;
115
+ }, {
116
+ readonly mode: 'value';
117
+ readonly value: string;
118
+ }, false, "default", "authenticated", "delegate", "kernel.astrale.ai:class.Identity.method.delegate">, builder.MethodProjection<Record<string, never>, {
119
+ readonly mode: 'value';
120
+ readonly value: {
121
+ id: string;
122
+ iss: string;
123
+ sub: string;
124
+ frozen: boolean;
125
+ requiredClaims: ({
126
+ claim: string;
127
+ op: "contains";
128
+ value: unknown;
129
+ } | {
130
+ claim: string;
131
+ op: "eq";
132
+ value: unknown;
133
+ } | {
134
+ claim: string;
135
+ op: "exists";
136
+ })[];
137
+ };
138
+ }, true, "default", "authenticated", "whoami", "kernel.astrale.ai:class.Identity.method.whoami"> | builder.MethodProjection<{
139
+ policy: string;
140
+ object: string;
141
+ }, {
142
+ readonly mode: 'value';
143
+ readonly value: {
144
+ allowed: boolean;
145
+ };
146
+ }, true, "default", "authenticated", "can", "kernel.astrale.ai:class.Identity.method.can"> | builder.MethodProjection<{
147
+ iss: string;
148
+ sub: string;
149
+ }, {
150
+ readonly mode: 'value';
151
+ readonly value: {
152
+ id: string;
153
+ iss: string;
154
+ sub: string;
155
+ frozen: boolean;
156
+ requiredClaims: ({
157
+ claim: string;
158
+ op: "contains";
159
+ value: unknown;
160
+ } | {
161
+ claim: string;
162
+ op: "eq";
163
+ value: unknown;
164
+ } | {
165
+ claim: string;
166
+ op: "exists";
167
+ })[];
168
+ } | null;
169
+ }, true, "default", "authorized", "whois", "kernel.astrale.ai:class.Identity.method.whois"> | builder.MethodProjection<{
170
+ audience?: string | undefined;
171
+ ttlSeconds: number;
172
+ grant?: unknown;
173
+ }, {
174
+ readonly mode: 'value';
175
+ readonly value: string;
176
+ }, true, "default", "authenticated", "mint", "kernel.astrale.ai:class.Identity.method.mint">>];
177
+ readonly properties: {
178
+ readonly displayName: builder.AuthoredPropertyProjection<string, string, false, "displayName", "self", never>;
179
+ };
180
+ readonly methods: {
181
+ readonly resolveHome: typeof import("../../user/index.js").resolveHome;
182
+ };
183
+ readonly effectiveProperties: builder.AuthoredPropertyProjection<string, string, false, "displayName", "self", never> | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
184
+ readonly name: "frozen";
185
+ readonly key: "kernel.astrale.ai:class.Identity.property.frozen";
186
+ }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
187
+ readonly name: "iss";
188
+ readonly key: "kernel.astrale.ai:class.Identity.property.iss";
189
+ }) | (import("@astrale-os/sdk/schema").ResolvedProperty<import("@astrale-os/sdk/schema").Value, false, never> & {
190
+ readonly name: "sub";
191
+ readonly key: "kernel.astrale.ai:class.Identity.property.sub";
192
+ });
193
+ readonly effectiveInstanceMethods: builder.AuthoredMethodProjection<builder.Method<builder.CallableProjection<Record<string, never>, {
194
+ readonly mode: 'value';
195
+ readonly value: {
196
+ userId: string;
197
+ personalSpaceId: string | null;
198
+ };
199
+ }, "authenticated", false, "default">>, "resolveHome", "self"> | (import("@astrale-os/sdk/schema").ResolvedMethod<{
200
+ audience: string;
201
+ ttlSeconds: number;
202
+ attenuation: unknown;
203
+ }, {
204
+ readonly mode: 'value';
205
+ readonly value: string;
206
+ }, false, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.delegate"> & {
207
+ readonly name: "delegate";
208
+ });
209
+ readonly effectiveStaticMethods: (import("@astrale-os/sdk/schema").ResolvedMethod<Record<string, never>, {
210
+ readonly mode: 'value';
211
+ readonly value: {
212
+ id: string;
213
+ iss: string;
214
+ sub: string;
215
+ frozen: boolean;
216
+ requiredClaims: ({
217
+ claim: string;
218
+ op: "contains";
219
+ value: unknown;
220
+ } | {
221
+ claim: string;
222
+ op: "eq";
223
+ value: unknown;
224
+ } | {
225
+ claim: string;
226
+ op: "exists";
227
+ })[];
228
+ };
229
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.whoami"> & {
230
+ readonly name: "whoami";
231
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<{
232
+ policy: string;
233
+ object: string;
234
+ }, {
235
+ readonly mode: 'value';
236
+ readonly value: {
237
+ allowed: boolean;
238
+ };
239
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.can"> & {
240
+ readonly name: "can";
241
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<{
242
+ iss: string;
243
+ sub: string;
244
+ }, {
245
+ readonly mode: 'value';
246
+ readonly value: {
247
+ id: string;
248
+ iss: string;
249
+ sub: string;
250
+ frozen: boolean;
251
+ requiredClaims: ({
252
+ claim: string;
253
+ op: "contains";
254
+ value: unknown;
255
+ } | {
256
+ claim: string;
257
+ op: "eq";
258
+ value: unknown;
259
+ } | {
260
+ claim: string;
261
+ op: "exists";
262
+ })[];
263
+ } | null;
264
+ }, true, "default", "authorized", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.whois"> & {
265
+ readonly name: "whois";
266
+ }) | (import("@astrale-os/sdk/schema").ResolvedMethod<{
267
+ audience?: string | undefined;
268
+ ttlSeconds: number;
269
+ grant?: unknown;
270
+ }, {
271
+ readonly mode: 'value';
272
+ readonly value: string;
273
+ }, true, "default", "authenticated", import("@astrale-os/sdk/schema").PolicyCheckExpression<import("@astrale-os/sdk/schema").PolicyRef, import("@astrale-os/sdk/schema").PolicyCheckObject>, "kernel.astrale.ai:class.Identity.method.mint"> & {
274
+ readonly name: "mint";
275
+ });
276
+ }>]>;
277
+ }, z.core.$strict>;
278
+ type PolicyContext = Pick<builder.PolicyPatternContext, 'allOf' | 'edge' | 'exists' | 'object' | 'subject'>;
279
+ export declare function groupSpaceBranch(context: PolicyContext, access: builder.Lazy<builder.EdgeClass>): ReturnType<PolicyContext['edge']>;
280
+ export {};
@@ -1,4 +1,9 @@
1
+ import { path } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
1
3
  import { Group, member_of_group } from '#schema/modules/group';
4
+ import { User } from '#schema/modules/user';
5
+ export const emptyObject = z.strictObject({});
6
+ export const spaceUser = z.strictObject({ user: path(User) });
2
7
  export function groupSpaceBranch(context, access) {
3
8
  return context.exists(({ node }) => {
4
9
  const group = node(Group);
@@ -1,4 +1,4 @@
1
- import { nodeClass, type Kernel } from '@astrale-os/sdk/schema';
1
+ import { nodeClass, type ClassIcon, type Kernel } from '@astrale-os/sdk/schema';
2
2
  import { z } from 'zod';
3
3
  import { resolveHome } from '../functions/resolve-home.js';
4
4
  declare const displayName: import("@astrale-os/sdk/schema").Property<z.ZodString, {
@@ -7,6 +7,7 @@ declare const displayName: import("@astrale-os/sdk/schema").Property<z.ZodString
7
7
  export interface UserConfig {
8
8
  readonly description: string;
9
9
  readonly extends: readonly [Kernel['classes']['Identity']];
10
+ readonly icon: ClassIcon;
10
11
  readonly properties: {
11
12
  readonly displayName: typeof displayName;
12
13
  };
@@ -1,11 +1,12 @@
1
- import { K, nodeClass, property } from '@astrale-os/sdk/schema';
1
+ import { classIcon, K, nodeClass, property, } from '@astrale-os/sdk/schema';
2
+ import { UserRound } from '@astrale-os/sdk/schema/icons';
2
3
  import { z } from 'zod';
3
4
  import { resolveHome } from '../functions/resolve-home.js';
4
5
  const displayName = property(z.string().min(1).max(160), { required: false });
5
- const config = {
6
+ export const User = nodeClass({
6
7
  description: 'One externally identified person using Shell.',
7
8
  extends: [K.classes.Identity],
9
+ icon: classIcon.lucide(UserRound),
8
10
  properties: { displayName },
9
11
  methods: { resolveHome },
10
- };
11
- export const User = nodeClass(config);
12
+ });
@@ -1,4 +1,5 @@
1
- export declare const setupAdmin: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const setupAdmin: builder.Function<builder.CallableProjection<{
2
3
  operationId: string;
3
4
  issuer: string;
4
5
  subject: string;
@@ -1,2 +1,11 @@
1
- import { defineSetupUser } from './setup-user.js';
2
- export const setupAdmin = defineSetupUser('Converge one asserted external identity as a Shell administrator.');
1
+ import { func } from '@astrale-os/sdk/schema';
2
+ import { adminGroup, maySetupUsers } from '#schema/modules/group';
3
+ import { setupInput, setupOutput } from '../types/setup-user.js';
4
+ const setupPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
5
+ export const setupAdmin = func({
6
+ description: 'Converge one asserted external identity as a Shell administrator.',
7
+ auth: 'authorized',
8
+ input: setupInput,
9
+ output: setupOutput,
10
+ policy: setupPolicy,
11
+ });
@@ -1,4 +1,5 @@
1
- export declare const setupMember: import("@astrale-os/sdk/schema").Function<import("@astrale-os/sdk/schema").CallableProjection<{
1
+ import { type builder } from '@astrale-os/sdk/schema';
2
+ export declare const setupMember: builder.Function<builder.CallableProjection<{
2
3
  operationId: string;
3
4
  issuer: string;
4
5
  subject: string;
@@ -1,2 +1,11 @@
1
- import { defineSetupUser } from './setup-user.js';
2
- export const setupMember = defineSetupUser('Converge one asserted external identity as a Shell member.');
1
+ import { func } from '@astrale-os/sdk/schema';
2
+ import { adminGroup, maySetupUsers } from '#schema/modules/group';
3
+ import { setupInput, setupOutput } from '../types/setup-user.js';
4
+ const setupPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
5
+ export const setupMember = func({
6
+ description: 'Converge one asserted external identity as a Shell member.',
7
+ auth: 'authorized',
8
+ input: setupInput,
9
+ output: setupOutput,
10
+ policy: setupPolicy,
11
+ });
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ export declare const setupInput: z.ZodObject<{
3
+ operationId: z.ZodString;
4
+ issuer: z.ZodString;
5
+ subject: z.ZodString;
6
+ displayName: z.ZodString;
7
+ personalSpaceName: z.ZodString;
8
+ }, z.core.$strict>;
9
+ export declare const setupOutput: z.ZodObject<{
10
+ userId: z.ZodString;
11
+ personalSpaceId: z.ZodString;
12
+ changed: z.ZodBoolean;
13
+ }, z.core.$strict>;
@@ -0,0 +1,14 @@
1
+ import { fullMatch } from '@astrale-os/sdk/schema';
2
+ import { z } from 'zod';
3
+ export const setupInput = z.strictObject({
4
+ operationId: z.string().min(1).max(256).check(fullMatch('[A-Za-z0-9][A-Za-z0-9._:-]{0,255}')),
5
+ issuer: z.string().min(1).max(2_048),
6
+ subject: z.string().min(1).max(2_048),
7
+ displayName: z.string().min(1).max(160),
8
+ personalSpaceName: z.string().min(1).max(160),
9
+ });
10
+ export const setupOutput = z.strictObject({
11
+ userId: z.string().min(1),
12
+ personalSpaceId: z.string().min(1),
13
+ changed: z.boolean(),
14
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-domains/shell",
3
- "version": "0.1.0-beta.21",
3
+ "version": "0.1.0-beta.23",
4
4
  "description": "Astrale Shell Domain schema and remote product implementation",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -49,8 +49,8 @@
49
49
  "zod": "4.4.3"
50
50
  },
51
51
  "devDependencies": {
52
- "@astrale-os/ox": "0.1.3",
53
- "@astrale-os/sdk": "0.5.0-beta.99",
52
+ "@astrale-os/ox": "0.1.4",
53
+ "@astrale-os/sdk": "0.5.0-beta.109",
54
54
  "@astrale/typescript-config": "npm:@jsr/astrale__typescript-config@~1.1.3",
55
55
  "@types/node": "^22.0.0",
56
56
  "oxlint": "1.78.0",
@@ -58,7 +58,7 @@
58
58
  "vitest": "4.1.10"
59
59
  },
60
60
  "peerDependencies": {
61
- "@astrale-os/sdk": ">=0.5.0-beta.99 <1.0.0"
61
+ "@astrale-os/sdk": ">=0.5.0-beta.109 <1.0.0"
62
62
  },
63
63
  "devEngines": {
64
64
  "runtime": {
@@ -1,7 +0,0 @@
1
- import { type builder } from '@astrale-os/sdk/schema';
2
- export declare function defineGroupMembership(description: string): builder.Method<builder.CallableProjection<{
3
- user: string;
4
- }, {
5
- readonly mode: 'value';
6
- readonly value: Record<string, never>;
7
- }, "authorized", false, "default">>;
@@ -1,16 +0,0 @@
1
- import { method, path } from '@astrale-os/sdk/schema';
2
- import { z } from 'zod';
3
- import { User } from '#schema/modules/user';
4
- import { adminGroup } from '../core/admin-group.js';
5
- import { maySetupUsers } from '../policies/may-setup-users.js';
6
- const emptyObject = z.strictObject({});
7
- const setupPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
8
- export function defineGroupMembership(description) {
9
- return method({
10
- description,
11
- input: z.strictObject({ user: path(User) }),
12
- output: emptyObject,
13
- auth: 'authorized',
14
- policy: setupPolicy,
15
- });
16
- }
@@ -1,10 +0,0 @@
1
- import { type builder } from '@astrale-os/sdk/schema';
2
- import { z } from 'zod';
3
- import { User } from '../../user/index.js';
4
- export declare const emptyObject: z.ZodObject<{}, z.core.$strict>;
5
- export type SpaceUserSchema = z.ZodObject<{
6
- user: builder.PathAuthoring<readonly [typeof User]>;
7
- }, z.core.$strict>;
8
- export declare const spaceUser: SpaceUserSchema;
9
- export declare const administerPolicy: builder.CallablePolicyBuilder;
10
- export declare const membershipPolicy: builder.CallablePolicyBuilder;
@@ -1,9 +0,0 @@
1
- import { path } from '@astrale-os/sdk/schema';
2
- import { z } from 'zod';
3
- import { User } from '#schema/modules/user';
4
- import { belongsToSpace } from '../policies/belongs-to-space.js';
5
- import { mayAdministerSpace } from '../policies/may-administer-space.js';
6
- export const emptyObject = z.strictObject({});
7
- export const spaceUser = z.strictObject({ user: path(User) });
8
- export const administerPolicy = ({ check, self }) => check(mayAdministerSpace, self);
9
- export const membershipPolicy = ({ check, self }) => check(belongsToSpace, self);
@@ -1,4 +0,0 @@
1
- import type { builder } from '@astrale-os/sdk/schema';
2
- type PolicyContext = Pick<builder.PolicyPatternContext, 'allOf' | 'edge' | 'exists' | 'object' | 'subject'>;
3
- export declare function groupSpaceBranch(context: PolicyContext, access: builder.Lazy<builder.EdgeClass>): ReturnType<PolicyContext['edge']>;
4
- export {};
@@ -1,15 +0,0 @@
1
- import { type builder } from '@astrale-os/sdk/schema';
2
- export declare function defineSetupUser(description: string): builder.Function<builder.CallableProjection<{
3
- operationId: string;
4
- issuer: string;
5
- subject: string;
6
- displayName: string;
7
- personalSpaceName: string;
8
- }, {
9
- readonly mode: 'value';
10
- readonly value: {
11
- userId: string;
12
- personalSpaceId: string;
13
- changed: boolean;
14
- };
15
- }, "authorized", false, "default">>;
@@ -1,20 +0,0 @@
1
- import { func, fullMatch } from '@astrale-os/sdk/schema';
2
- import { z } from 'zod';
3
- import { adminGroup, maySetupUsers } from '#schema/modules/group';
4
- const operationId = z.string().min(1).max(256).check(fullMatch('[A-Za-z0-9][A-Za-z0-9._:-]{0,255}'));
5
- const input = z.strictObject({
6
- operationId,
7
- issuer: z.string().min(1).max(2_048),
8
- subject: z.string().min(1).max(2_048),
9
- displayName: z.string().min(1).max(160),
10
- personalSpaceName: z.string().min(1).max(160),
11
- });
12
- const output = z.strictObject({
13
- userId: z.string().min(1),
14
- personalSpaceId: z.string().min(1),
15
- changed: z.boolean(),
16
- });
17
- const setupPolicy = ({ check, ref }) => check(maySetupUsers, ref(adminGroup));
18
- export function defineSetupUser(description) {
19
- return func({ description, auth: 'authorized', input, output, policy: setupPolicy });
20
- }